Merge branch 'fix/update-pending-status' into 'develop'

Update usage of `need_approval` status

See merge request pleroma/admin-fe!154
This commit is contained in:
Angelina Filippova 2020-08-11 23:04:26 +00:00
commit 51da64c138
6 changed files with 100 additions and 84 deletions

View file

@ -229,13 +229,14 @@ export default {
revokeRightConfirmation: 'Are you sure you want to revoke {right} rights from all selected users?',
activateMultipleUsersConfirmation: 'Are you sure you want to activate accounts of all selected users?',
deactivateMultipleUsersConfirmation: 'Are you sure you want to deactivate accounts of all selected users?',
deleteUsersConfirmation: 'Are you sure you want to delete this account? This action cannot be undone.',
deleteMultipleUsersConfirmation: 'Are you sure you want to delete accounts of all selected users?',
deleteUserConfirmation: 'Are you sure you want to delete this account? This action cannot be undone.',
rejectAccountConfirmation: 'Are you sure you want to reject this account? This account will be deleted and it cannot be undone.',
deleteMultipleUsersConfirmation: 'Are you sure you want to delete accounts of all selected users? This action cannot be undone.',
addTagForMultipleUsersConfirmation: 'Are you sure you want to apply tag to all selected users?',
removeTagFromMultipleUsersConfirmation: 'Are you sure you want to remove tag from all selected users?',
requirePasswordResetConfirmation: 'Are you sure you want to require password reset for all selected users?',
approveAccountsConfirmation: 'Are you sure you want to approve accounts for all selected users?',
rejectAccountsConfirmation: 'Are you sure you want to reject accounts for all selected users?',
rejectAccountsConfirmation: 'Are you sure you want to reject accounts for all selected users? These accounts will be deleted and it cannot be undone.',
confirmAccountsConfirmation: 'Are you sure you want to confirm emails for all selected users?',
resendEmailConfirmation: 'Are you sure you want to resend confirmation email for all selected users?',
mailerMustBeEnabled: 'To require user\'s password reset you must enable mailer.',
@ -268,7 +269,8 @@ export default {
invalidAccount: 'This account has invalid nickname and can\'t be modified',
invalidNickname: 'invalid nickname',
passwordResetTokenGenerated: 'Password reset token was generated:',
linkToResetPassword: 'You can also use this link to reset password:'
linkToResetPassword: 'You can also use this link to reset password:',
registrationReason: 'Registration Reason'
},
statuses: {
statuses: 'Statuses',
@ -323,7 +325,7 @@ export default {
external: 'External',
byStatus: 'By status',
active: 'Active',
pending: 'Pending',
pending: 'Pending Approval',
deactivated: 'Deactivated'
},
reports: {

View file

@ -31,7 +31,7 @@ const users = {
local: false,
external: false,
active: false,
needApproval: false,
need_approval: false,
deactivated: false
},
passwordResetToken: {
@ -126,14 +126,32 @@ const users = {
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId, statusId: _statusId })
},
async ApproveUsersAccount({ dispatch, getters }, { users, _userId, _statusId }) {
const updatedUsers = users.map(user => {
return { ...user, approval_pending: false }
})
const nicknames = users.map(user => user.nickname)
const callApiFn = async() => await approveUserAccount(nicknames, getters.authHost, getters.token)
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId, statusId: _statusId })
},
ClearUsersState({ commit }) {
commit('SET_SEARCH_QUERY', '')
commit('SET_USERS_FILTERS', { local: false, external: false, active: false, needApproval: false, deactivated: false })
commit('SET_USERS_FILTERS', { local: false, external: false, active: false, need_approval: false, deactivated: false })
},
async ClearFilters({ commit, dispatch, state }) {
commit('CLEAR_USERS_FILTERS')
dispatch('SearchUsers', { query: state.searchQuery, page: 1 })
},
async ConfirmUsersEmail({ dispatch, getters }, { users, _userId, _statusId }) {
const updatedUsers = users.map(user => {
return { ...user, confirmation_pending: false }
})
const nicknames = users.map(user => user.nickname)
const callApiFn = async() => await confirmUserEmail(nicknames, getters.authHost, getters.token)
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId, statusId: _statusId })
},
async CreateNewAccount({ dispatch, getters, state }, { nickname, email, password }) {
try {
await createNewAccount(nickname, email, password, getters.authHost, getters.token)
@ -161,33 +179,6 @@ const users = {
}
dispatch('SuccessMessage')
},
async ApproveUsersAccount({ dispatch, getters }, { users, _userId, _statusId }) {
const updatedUsers = users.map(user => {
return { ...user, approval_pending: false }
})
const nicknames = users.map(user => user.nickname)
const callApiFn = async() => await approveUserAccount(nicknames, getters.authHost, getters.token)
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId, statusId: _statusId })
},
async ConfirmUsersEmail({ dispatch, getters }, { users, _userId, _statusId }) {
const updatedUsers = users.map(user => {
return { ...user, confirmation_pending: false }
})
const nicknames = users.map(user => user.nickname)
const callApiFn = async() => await confirmUserEmail(nicknames, getters.authHost, getters.token)
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId, statusId: _statusId })
},
async ResendConfirmationEmail({ dispatch, getters }, users) {
const usersNicknames = users.map(user => user.nickname)
try {
await resendConfirmationEmail(usersNicknames, getters.authHost, getters.token)
} catch (_e) {
return
}
dispatch('SuccessMessage')
},
async DeleteRight({ dispatch, getters }, { users, right, _userId, _statusId }) {
const updatedUsers = users.map(user => {
return user.local ? { ...user, roles: { ...user.roles, [right]: false }} : user
@ -246,6 +237,15 @@ const users = {
}
dispatch('SuccessMessage')
},
async ResendConfirmationEmail({ dispatch, getters }, users) {
const usersNicknames = users.map(user => user.nickname)
try {
await resendConfirmationEmail(usersNicknames, getters.authHost, getters.token)
} catch (_e) {
return
}
dispatch('SuccessMessage')
},
async SearchUsers({ commit, dispatch, state, getters }, { query, page }) {
if (query.length === 0) {
commit('SET_SEARCH_QUERY', query)
@ -271,7 +271,7 @@ const users = {
local: false,
external: false,
active: false,
needApproval: false,
need_approval: false,
deactivated: false
}
const currentFilters = { ...defaultFilters, ...filters }

View file

@ -155,7 +155,7 @@ export default {
},
handleDeletion(user) {
this.$confirm(
this.$t('users.deleteUsersConfirmation'),
this.$t('users.deleteUserConfirmation'),
{
confirmButtonText: 'Delete',
cancelButtonText: 'Cancel',
@ -174,9 +174,9 @@ export default {
},
handleAccountRejection(user) {
this.$confirm(
this.$t('users.deleteUsersConfirmation'),
this.$t('users.rejectAccountConfirmation'),
{
confirmButtonText: 'Delete',
confirmButtonText: 'Reject',
cancelButtonText: 'Cancel',
type: 'warning'
}).then(() => {
@ -184,7 +184,7 @@ export default {
}).catch(() => {
this.$message({
type: 'info',
message: 'Delete canceled'
message: 'Reject canceled'
})
})
},

View file

@ -325,7 +325,7 @@ export default {
rejectAccountsForMultipleUsers() {
const { remove } = this.mappers()
this.confirmMessage(
this.$t('users.deleteMultipleUsersConfirmation'),
this.$t('users.rejectAccountsConfirmation'),
remove
)
},

View file

@ -12,7 +12,7 @@
</el-option-group>
<el-option-group :label="$t('usersFilter.byStatus')">
<el-option value="active" label="Active">{{ $t('usersFilter.active') }}</el-option>
<el-option value="needApproval" label="Need Approval">{{ $t('usersFilter.pending') }}</el-option>
<el-option value="need_approval" label="Need Approval">{{ $t('usersFilter.pending') }}</el-option>
<el-option value="deactivated" label="Deactivated">{{ $t('usersFilter.deactivated') }}</el-option>
</el-option-group>
</el-select>
@ -37,20 +37,25 @@ export default {
methods: {
removeOppositeFilters() {
const filtersQuantity = Object.keys(this.$store.state.users.filters).length
const currentFilters = this.$data.value.slice()
const indexOfLocal = currentFilters.indexOf('local')
const indexOfExternal = currentFilters.indexOf('external')
const indexOfActive = currentFilters.indexOf('active')
const indexOfDeactivated = currentFilters.indexOf('deactivated')
if (currentFilters.length === filtersQuantity) {
const currentFilters = []
const indexOfLocal = this.$data.value.indexOf('local')
const indexOfExternal = this.$data.value.indexOf('external')
const indexOfActive = this.$data.value.indexOf('active')
const indexOfDeactivated = this.$data.value.indexOf('deactivated')
const indexOfPending = this.$data.value.indexOf('need_approval')
if (this.$data.value.length === filtersQuantity) {
return []
} else if (indexOfLocal > -1 && indexOfExternal > -1) {
const filterToRemove = indexOfLocal > indexOfExternal ? indexOfExternal : indexOfLocal
currentFilters.splice(filterToRemove, 1)
} else if (indexOfActive > -1 && indexOfDeactivated > -1) {
const filterToRemove = indexOfActive > indexOfDeactivated ? indexOfDeactivated : indexOfActive
currentFilters.splice(filterToRemove, 1)
}
Math.max(indexOfLocal, indexOfExternal) > -1
? currentFilters.push(this.$data.value[Math.max(indexOfLocal, indexOfExternal)])
: currentFilters
Math.max(indexOfActive, indexOfDeactivated, indexOfPending) > -1
? currentFilters.push(this.$data.value[Math.max(indexOfActive, indexOfDeactivated, indexOfPending)])
: currentFilters
return currentFilters
},
toggleFilters() {

View file

@ -56,10 +56,20 @@
</el-table-column>
<el-table-column :min-width="width" :label="$t('users.status')">
<template slot-scope="scope">
<el-tag :type="scope.row.deactivated ? 'danger' : 'success'">
<span v-if="isDesktop">{{ scope.row.deactivated ? $t('users.deactivated') : $t('users.active') }}</span>
<i v-else :class="activationIcon(scope.row.deactivated)"/>
<el-tag v-if="!scope.row.deactivated & !scope.row.approval_pending" type="success">
<span v-if="isDesktop">{{ $t('users.active') }}</span>
<i v-else class="el-icon-circle-check"/>
</el-tag>
<el-tag v-if="scope.row.deactivated & !scope.row.approval_pending" type="danger">
<span v-if="isDesktop">{{ $t('users.deactivated') }}</span>
<i v-else class="el-icon-circle-close"/>
</el-tag>
<el-tooltip :content="$t('users.unapprovedAccount')" effect="dark">
<el-tag v-if="scope.row.approval_pending" type="info">
<span v-if="isDesktop">{{ $t('users.unapproved') }}</span>
<i v-else class="el-icon-warning-outline"/>
</el-tag>
</el-tooltip>
<el-tag v-if="scope.row.roles.admin">
<span>{{ isDesktop ? $t('users.admin') : getFirstLetter($t('users.admin')) }}</span>
</el-tag>
@ -71,16 +81,20 @@
{{ isDesktop ? $t('users.unconfirmed') : getFirstLetter($t('users.unconfirmed')) }}
</el-tag>
</el-tooltip>
<el-tooltip :content="$t('users.unapprovedAccount')" effect="dark">
<el-tag v-if="scope.row.approval_pending" type="info">
{{ isDesktop ? $t('users.unapproved') : getFirstLetter($t('users.unapproved')) }}
</el-tag>
</el-tooltip>
<div v-if="pendingView && isDesktop" class="reason-text">
"{{ scope.row.registration_reason | truncate(100, '...') }}"
</div>
</template>
</el-table-column>
<el-table-column v-if="pendingView && isDesktop" :label="$t('users.registrationReason')">
<template slot-scope="scope">
<el-tooltip
v-if="regReason(scope.row.registration_reason)"
:content="scope.row.registration_reason"
popper-class="reason-tooltip"
effect="dark">
<span>
"{{ scope.row.registration_reason | truncate(100, '...') }}"
</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column :label="$t('users.actions')" fixed="right">
<template slot-scope="scope">
@ -134,11 +148,7 @@ export default {
},
filters: {
truncate: function(text, length, suffix) {
if (text.length > length) {
return text.substring(0, length) + suffix
} else {
return text
}
return text.length < length ? text : text.substring(0, length) + suffix
}
},
data() {
@ -175,7 +185,7 @@ export default {
return this.$store.state.users.totalUsersCount
},
pendingView() {
return this.$store.state.users.filters['needApproval']
return this.$store.state.users.filters['need_approval']
},
width() {
return this.isMobile ? 55 : false
@ -194,9 +204,6 @@ export default {
this.$store.dispatch('ClearUsersState')
},
methods: {
activationIcon(status) {
return status ? 'el-icon-error' : 'el-icon-success'
},
clearSelection() {
this.$refs.usersTable.clearSelection()
},
@ -233,6 +240,9 @@ export default {
propertyExists(account, property) {
return account[property]
},
regReason(reason) {
return reason && reason.length > 0
},
showDeactivatedButton(id) {
return this.$store.state.user.id !== id
}
@ -278,6 +288,9 @@ export default {
.password-reset-token-dialog {
width: 50%
}
.reason-tooltip {
max-width: 450px;
}
.reset-password-link {
text-decoration: underline;
}
@ -291,6 +304,9 @@ export default {
margin: 10px 0 0 15px;
height: 40px;
}
.cell {
word-break: break-word;
}
.el-table__row:hover {
cursor: pointer;
}
@ -319,9 +335,6 @@ export default {
color: gray;
font-size: 28px;
}
.reason-text {
word-break: normal;
}
}
@media only screen and (max-width:480px) {
@ -355,16 +368,12 @@ export default {
}
.el-table__row {
.el-tag {
display: flex;
align-items: center;
justify-content: center;
width: 30px;
display: inline-block;
margin-bottom: 4px;
font-weight: bold;
&.el-tag--success {
padding-left: 8px;
}
&.el-tag--danger {
padding-left: 8px;
}
}
}
.reboot-button {