From 7b7a05170a787f3d5557f851a3a8eda99c23e4e7 Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Mon, 18 May 2020 20:07:26 +0300 Subject: [PATCH 01/18] Disable moderation of users that don't have nicknames or IDs --- src/lang/en.js | 3 ++- src/views/reports/components/Report.vue | 5 +++- .../users/components/MultipleUsersMenu.vue | 24 +++++++++---------- src/views/users/index.vue | 20 +++++++++++----- src/views/users/show.vue | 5 ++++ 5 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/lang/en.js b/src/lang/en.js index 2e504315..d25fff70 100644 --- a/src/lang/en.js +++ b/src/lang/en.js @@ -238,7 +238,8 @@ export default { unconfirmedEmail: 'User didn\'t confirm the email', confirmAccount: 'Confirm account', confirmAccounts: 'Confirm accounts', - resendConfirmation: 'Resend confirmation email' + resendConfirmation: 'Resend confirmation email', + invalidUser: 'This user is invalid and can\'t be modified' }, statuses: { statuses: 'Statuses', diff --git a/src/views/reports/components/Report.vue b/src/views/reports/components/Report.vue index 565b3cb0..56a13372 100644 --- a/src/views/reports/components/Report.vue +++ b/src/views/reports/components/Report.vue @@ -24,7 +24,7 @@ {{ $t('reports.close') }} - +
@@ -179,6 +179,9 @@ export default { }, showStatuses(statuses = []) { return statuses.length > 0 + }, + validAccount(account) { + return account.nickname && account.id } } } diff --git a/src/views/users/components/MultipleUsersMenu.vue b/src/views/users/components/MultipleUsersMenu.vue index eaf6d742..f7476c0b 100644 --- a/src/views/users/components/MultipleUsersMenu.vue +++ b/src/views/users/components/MultipleUsersMenu.vue @@ -165,33 +165,33 @@ export default { } return { grantRight: (right) => () => { - const filterUsersFn = user => user.local && !user.roles[right] && this.$store.state.user.id !== user.id + const filterUsersFn = user => user.nickname && user.id && user.local && !user.roles[right] && this.$store.state.user.id !== user.id const addRightFn = async(users) => await this.$store.dispatch('AddRight', { users, right }) const filtered = this.selectedUsers.filter(filterUsersFn) applyAction(filtered, addRightFn) }, revokeRight: (right) => () => { - const filterUsersFn = user => user.local && user.roles[right] && this.$store.state.user.id !== user.id + const filterUsersFn = user => user.nickname && user.id && user.local && user.roles[right] && this.$store.state.user.id !== user.id const deleteRightFn = async(users) => await this.$store.dispatch('DeleteRight', { users, right }) const filtered = this.selectedUsers.filter(filterUsersFn) applyAction(filtered, deleteRightFn) }, activate: () => { - const filtered = this.selectedUsers.filter(user => user.deactivated && this.$store.state.user.id !== user.id) + const filtered = this.selectedUsers.filter(user => user.nickname && user.id && user.deactivated && this.$store.state.user.id !== user.id) const activateUsersFn = async(users) => await this.$store.dispatch('ActivateUsers', { users }) applyAction(filtered, activateUsersFn) }, deactivate: () => { - const filtered = this.selectedUsers.filter(user => !user.deactivated && this.$store.state.user.id !== user.id) + const filtered = this.selectedUsers.filter(user => user.nickname && user.id && !user.deactivated && this.$store.state.user.id !== user.id) const deactivateUsersFn = async(users) => await this.$store.dispatch('DeactivateUsers', { users }) applyAction(filtered, deactivateUsersFn) }, remove: () => { - const filtered = this.selectedUsers.filter(user => this.$store.state.user.id !== user.id) + const filtered = this.selectedUsers.filter(user => user.nickname && user.id && this.$store.state.user.id !== user.id) const deleteAccountFn = async(users) => await this.$store.dispatch('DeleteUsers', { users }) applyAction(filtered, deleteAccountFn) @@ -199,34 +199,34 @@ export default { addTag: (tag) => () => { const filtered = this.selectedUsers.filter(user => tag === 'disable_remote_subscription' || tag === 'disable_any_subscription' - ? user.local && !user.tags.includes(tag) - : !user.tags.includes(tag)) + ? user.nickname && user.id && user.local && !user.tags.includes(tag) + : user.nickname && user.id && !user.tags.includes(tag)) const addTagFn = async(users) => await this.$store.dispatch('AddTag', { users, tag }) applyAction(filtered, addTagFn) }, removeTag: (tag) => async() => { const filtered = this.selectedUsers.filter(user => tag === 'disable_remote_subscription' || tag === 'disable_any_subscription' - ? user.local && user.tags.includes(tag) - : user.tags.includes(tag)) + ? user.nickname && user.id && user.local && user.tags.includes(tag) + : user.nickname && user.id && user.tags.includes(tag)) const removeTagFn = async(users) => await this.$store.dispatch('RemoveTag', { users, tag }) applyAction(filtered, removeTagFn) }, requirePasswordReset: () => { - const filtered = this.selectedUsers.filter(user => user.local) + const filtered = this.selectedUsers.filter(user => user.nickname && user.id && user.local) const requirePasswordResetFn = async(users) => await this.$store.dispatch('RequirePasswordReset', users) applyAction(filtered, requirePasswordResetFn) }, confirmAccounts: () => { - const filtered = this.selectedUsers.filter(user => user.local && user.confirmation_pending) + const filtered = this.selectedUsers.filter(user => user.nickname && user.id && user.local && user.confirmation_pending) const confirmAccountFn = async(users) => await this.$store.dispatch('ConfirmUsersEmail', { users }) applyAction(filtered, confirmAccountFn) }, resendConfirmation: () => { - const filtered = this.selectedUsers.filter(user => user.local && user.confirmation_pending) + const filtered = this.selectedUsers.filter(user => user.nickname && user.id && user.local && user.confirmation_pending) const resendConfirmationFn = async(users) => await this.$store.dispatch('ResendConfirmationEmail', users) applyAction(filtered, resendConfirmationFn) diff --git a/src/views/users/index.vue b/src/views/users/index.vue index 6d6deb47..d3edbf5b 100644 --- a/src/views/users/index.vue +++ b/src/views/users/index.vue @@ -75,9 +75,11 @@ @@ -140,12 +142,6 @@ export default { normalizedUsersCount() { return numeral(this.$store.state.users.totalUsersCount).format('0a') }, - users() { - return this.$store.state.users.fetchedUsers - }, - usersCount() { - return this.$store.state.users.totalUsersCount - }, pageSize() { return this.$store.state.users.pageSize }, @@ -164,6 +160,12 @@ export default { isMobile() { return this.$store.state.app.device === 'mobile' }, + users() { + return this.$store.state.users.fetchedUsers + }, + usersCount() { + return this.$store.state.users.totalUsersCount + }, width() { return this.isMobile ? 55 : false } @@ -211,6 +213,9 @@ export default { }, showDeactivatedButton(id) { return this.$store.state.user.id !== id + }, + validUser(user) { + return user.nickname && user.id } } } @@ -248,6 +253,9 @@ export default { .create-account > .el-icon-plus { margin-right: 5px; } +.invalid-user { + color: gray; +} .users-header-container { display: flex; align-items: center; diff --git a/src/views/users/show.vue b/src/views/users/show.vue index a4ae844a..9ccb530e 100644 --- a/src/views/users/show.vue +++ b/src/views/users/show.vue @@ -7,6 +7,7 @@
@@ -22,6 +23,7 @@ @@ -182,6 +184,9 @@ export default { }, openResetPasswordDialog() { this.resetPasswordDialogOpen = true + }, + validUser(user) { + return user.nickname && user.id } } } From 1c2782a5228a8506e89b23bb7e1d1cb67a5d413b Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Mon, 18 May 2020 20:10:33 +0300 Subject: [PATCH 02/18] Fix sorting users if there are users without nicknames or IDs --- src/store/modules/users.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/store/modules/users.js b/src/store/modules/users.js index 2a1540e3..0b6061cb 100644 --- a/src/store/modules/users.js +++ b/src/store/modules/users.js @@ -51,9 +51,11 @@ const users = { return } - state.fetchedUsers = [...usersWithoutSwapped, ...users].sort((a, b) => - a.nickname.localeCompare(b.nickname) - ) + const updatedUsers = [...usersWithoutSwapped, ...users] + state.fetchedUsers = updatedUsers + .filter(user => user.nickname && user.id) + .sort((a, b) => a.nickname.localeCompare(b.nickname)) + .concat(updatedUsers.filter(user => !user.nickname || !user.id)) }, SET_COUNT: (state, count) => { state.totalUsersCount = count From 20a56bb21f9acc8ae5411130c7985efe28e588bb Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Mon, 18 May 2020 22:50:32 +0300 Subject: [PATCH 03/18] Clear search and filter inputs when vue instance is destroyed --- src/store/modules/users.js | 4 ++++ src/views/users/index.vue | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/store/modules/users.js b/src/store/modules/users.js index 0b6061cb..76a844bb 100644 --- a/src/store/modules/users.js +++ b/src/store/modules/users.js @@ -124,6 +124,10 @@ const users = { dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId }) }, + ClearUsersState({ commit }) { + commit('SET_SEARCH_QUERY', '') + commit('SET_USERS_FILTERS', { local: false, external: false, active: false, deactivated: false }) + }, async ClearFilters({ commit, dispatch, state }) { commit('CLEAR_USERS_FILTERS') dispatch('SearchUsers', { query: state.searchQuery, page: 1 }) diff --git a/src/views/users/index.vue b/src/views/users/index.vue index d3edbf5b..56df8612 100644 --- a/src/views/users/index.vue +++ b/src/views/users/index.vue @@ -179,6 +179,9 @@ export default { this.$store.dispatch('NeedReboot') this.$store.dispatch('FetchUsers', { page: 1 }) }, + destroyed() { + this.$store.dispatch('ClearUsersState') + }, methods: { activationIcon(status) { return status ? 'el-icon-error' : 'el-icon-success' From 8fddbb69d28fe02f31b3ed41d0ab2bbd5dc892b7 Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Mon, 18 May 2020 23:00:23 +0300 Subject: [PATCH 04/18] Update styles for deactivated users --- src/components/Status/index.vue | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/Status/index.vue b/src/components/Status/index.vue index 90058332..25c62d5e 100644 --- a/src/components/Status/index.vue +++ b/src/components/Status/index.vue @@ -229,6 +229,10 @@ export default { line-height: 26px; font-size: 13px; } + .deactivated { + color: gray; + font-size: 15px; + } .image { width: 20%; img { From f4d7ad945386b7292941626e191ecfef10923451 Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Sat, 30 May 2020 21:51:13 +0300 Subject: [PATCH 05/18] Refactoring and unification of function names --- src/views/reports/components/Report.vue | 8 +++--- .../users/components/MultipleUsersMenu.vue | 27 ++++++++++--------- src/views/users/index.vue | 8 +++--- src/views/users/show.vue | 10 +++---- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/views/reports/components/Report.vue b/src/views/reports/components/Report.vue index 56a13372..0df17b10 100644 --- a/src/views/reports/components/Report.vue +++ b/src/views/reports/components/Report.vue @@ -24,7 +24,7 @@ {{ $t('reports.close') }} - +
@@ -174,14 +174,14 @@ export default { handlePageChange(page) { this.$store.dispatch('FetchReports', page) }, + isValid(account) { + return account.nickname && account.id + }, parseTimestamp(timestamp) { return moment(timestamp).format('L HH:mm') }, showStatuses(statuses = []) { return statuses.length > 0 - }, - validAccount(account) { - return account.nickname && account.id } } } diff --git a/src/views/users/components/MultipleUsersMenu.vue b/src/views/users/components/MultipleUsersMenu.vue index f7476c0b..70883598 100644 --- a/src/views/users/components/MultipleUsersMenu.vue +++ b/src/views/users/components/MultipleUsersMenu.vue @@ -165,33 +165,33 @@ export default { } return { grantRight: (right) => () => { - const filterUsersFn = user => user.nickname && user.id && user.local && !user.roles[right] && this.$store.state.user.id !== user.id + const filterUsersFn = user => this.isValid(user) && user.local && !user.roles[right] && this.$store.state.user.id !== user.id const addRightFn = async(users) => await this.$store.dispatch('AddRight', { users, right }) const filtered = this.selectedUsers.filter(filterUsersFn) applyAction(filtered, addRightFn) }, revokeRight: (right) => () => { - const filterUsersFn = user => user.nickname && user.id && user.local && user.roles[right] && this.$store.state.user.id !== user.id + const filterUsersFn = user => this.isValid(user) && user.local && user.roles[right] && this.$store.state.user.id !== user.id const deleteRightFn = async(users) => await this.$store.dispatch('DeleteRight', { users, right }) const filtered = this.selectedUsers.filter(filterUsersFn) applyAction(filtered, deleteRightFn) }, activate: () => { - const filtered = this.selectedUsers.filter(user => user.nickname && user.id && user.deactivated && this.$store.state.user.id !== user.id) + const filtered = this.selectedUsers.filter(user => this.isValid(user) && user.deactivated && this.$store.state.user.id !== user.id) const activateUsersFn = async(users) => await this.$store.dispatch('ActivateUsers', { users }) applyAction(filtered, activateUsersFn) }, deactivate: () => { - const filtered = this.selectedUsers.filter(user => user.nickname && user.id && !user.deactivated && this.$store.state.user.id !== user.id) + const filtered = this.selectedUsers.filter(user => this.isValid(user) && !user.deactivated && this.$store.state.user.id !== user.id) const deactivateUsersFn = async(users) => await this.$store.dispatch('DeactivateUsers', { users }) applyAction(filtered, deactivateUsersFn) }, remove: () => { - const filtered = this.selectedUsers.filter(user => user.nickname && user.id && this.$store.state.user.id !== user.id) + const filtered = this.selectedUsers.filter(user => this.isValid(user) && this.$store.state.user.id !== user.id) const deleteAccountFn = async(users) => await this.$store.dispatch('DeleteUsers', { users }) applyAction(filtered, deleteAccountFn) @@ -199,40 +199,43 @@ export default { addTag: (tag) => () => { const filtered = this.selectedUsers.filter(user => tag === 'disable_remote_subscription' || tag === 'disable_any_subscription' - ? user.nickname && user.id && user.local && !user.tags.includes(tag) - : user.nickname && user.id && !user.tags.includes(tag)) + ? this.isValid(user) && user.local && !user.tags.includes(tag) + : this.isValid(user) && !user.tags.includes(tag)) const addTagFn = async(users) => await this.$store.dispatch('AddTag', { users, tag }) applyAction(filtered, addTagFn) }, removeTag: (tag) => async() => { const filtered = this.selectedUsers.filter(user => tag === 'disable_remote_subscription' || tag === 'disable_any_subscription' - ? user.nickname && user.id && user.local && user.tags.includes(tag) - : user.nickname && user.id && user.tags.includes(tag)) + ? this.isValid(user) && user.local && user.tags.includes(tag) + : this.isValid(user) && user.tags.includes(tag)) const removeTagFn = async(users) => await this.$store.dispatch('RemoveTag', { users, tag }) applyAction(filtered, removeTagFn) }, requirePasswordReset: () => { - const filtered = this.selectedUsers.filter(user => user.nickname && user.id && user.local) + const filtered = this.selectedUsers.filter(user => this.isValid(user) && user.local) const requirePasswordResetFn = async(users) => await this.$store.dispatch('RequirePasswordReset', users) applyAction(filtered, requirePasswordResetFn) }, confirmAccounts: () => { - const filtered = this.selectedUsers.filter(user => user.nickname && user.id && user.local && user.confirmation_pending) + const filtered = this.selectedUsers.filter(user => this.isValid(user) && user.local && user.confirmation_pending) const confirmAccountFn = async(users) => await this.$store.dispatch('ConfirmUsersEmail', { users }) applyAction(filtered, confirmAccountFn) }, resendConfirmation: () => { - const filtered = this.selectedUsers.filter(user => user.nickname && user.id && user.local && user.confirmation_pending) + const filtered = this.selectedUsers.filter(user => this.isValid(user) && user.local && user.confirmation_pending) const resendConfirmationFn = async(users) => await this.$store.dispatch('ResendConfirmationEmail', users) applyAction(filtered, resendConfirmationFn) } } }, + isValid(user) { + return user.nickname && user.id + }, grantRightToMultipleUsers(right) { const { grantRight } = this.mappers() this.confirmMessage( diff --git a/src/views/users/index.vue b/src/views/users/index.vue index 56df8612..474a438e 100644 --- a/src/views/users/index.vue +++ b/src/views/users/index.vue @@ -75,7 +75,7 @@