/home/ivoiecob/email.hirewise-va.com/modules/AdminPanelWebclient/vue/src/pages/Users.vue
<template>
<main-layout>
<q-splitter
:after-class="!showTabs ? 'q-splitter__right-panel' : ''"
class="full-height full-width"
v-model="listSplitterWidth"
:limits="[10, 30]"
>
<template v-slot:before>
<div class="flex column full-height">
<q-toolbar class="col-auto q-py-sm list-border">
<div class="flex">
<q-btn
flat
color="grey-8"
size="mg"
no-wrap
:disable="checkedIds.length === 0"
@click="askDeleteCheckedUsers"
>
<IconTrash />
<span>{{ countLabel }}</span>
<q-tooltip>
{{ $t('COREWEBCLIENT.ACTION_DELETE') }}
</q-tooltip>
</q-btn>
<q-btn flat color="grey-8" size="mg" @click="routeCreateUser" v-if="allowCreateUser">
<IconAdd />
<q-tooltip>
{{ $t('ADMINPANELWEBCLIENT.ACTION_CREATE_ENTITY_USER') }}
</q-tooltip>
</q-btn>
<span v-if="allTenantGroups.length > 0 && isUserSuperAdmin">
<q-btn-dropdown
flat
color="grey-8"
size="mg"
:disable="checkedOrSelectedUsersIds.length === 0 || groups.length === 0"
>
<template v-slot:label>
<IconAddToGroup />
<q-tooltip>
{{ $t('ADMINPANELWEBCLIENT.ACTION_ADD_USER_TO_GROUP') }}
</q-tooltip>
</template>
<q-list>
<q-item
clickable
v-close-popup
v-for="group in groups"
:key="group.id"
@click="addUsersToGroup(group.id)"
>
<q-item-section>
<q-item-label>{{ group.name }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<q-btn flat color="grey-8" size="mg" @click="removeFromGroup" :disable="disableRemoveFromGroup">
<IconRemoveFromGroup />
<q-tooltip>
{{ $t('ADMINPANELWEBCLIENT.ACTION_REMOVE_USER_FROM_GROUP') }}
</q-tooltip>
</q-btn>
</span>
<component
v-for="filter in filters"
:key="filter.name"
v-bind:is="filter"
@filter-selected="routeFilter"
@filter-filled-up="populateFiltersGetParameters"
@allow-create-user="handleAllowCreateUser"
/>
</div>
</q-toolbar>
<StandardList
class="col-grow list-border"
:items="userItems"
:selectedItem="selectedUserId"
:loading="loadingUsers"
:search="search"
:page="page"
:pagesCount="pagesCount"
:noItemsText="'ADMINPANELWEBCLIENT.INFO_NO_ENTITIES_USER'"
:noItemsFoundText="'ADMINPANELWEBCLIENT.INFO_NO_ENTITIES_FOUND_USER'"
ref="userList"
@route="route"
@check="afterCheck"
/>
</div>
</template>
<template v-slot:after>
<q-splitter
after-class="q-splitter__right-panel"
v-if="showTabs"
class="full-height full-width"
v-model="tabsSplitterWidth"
:limits="[10, 30]"
>
<template v-slot:before>
<q-list>
<div>
<q-item clickable @click="route(selectedUserId)" :class="selectedTab === '' ? 'bg-selected-item' : ''">
<q-item-section>
<q-item-label lines="1" v-t="'ADMINPANELWEBCLIENT.LABEL_COMMON_SETTINGS_TAB'"></q-item-label>
</q-item-section>
</q-item>
<q-separator />
</div>
<div v-for="tab in tabs" :key="tab.tabName">
<template v-if="tab.hideTabForSelectedUserRoles.indexOf(selectedUserRole) === -1">
<q-item
clickable
@click="route(selectedUserId, tab.tabName)"
:class="selectedTab === tab.tabName ? 'bg-selected-item' : ''"
>
<q-item-section>
<q-item-label lines="1">{{ $t(tab.tabTitle) }}</q-item-label>
</q-item-section>
</q-item>
<q-separator />
</template>
</div>
<q-inner-loading style="justify-content: flex-start" :showing="deleting">
<q-linear-progress query />
</q-inner-loading>
</q-list>
</template>
<template v-slot:after>
<router-view
@no-user-found="handleNoUserFound"
@user-created="handleCreateUser"
@user-updated="handleUpdateUser"
@cancel-create="route"
@delete-user="askDeleteUser"
:deletingIds="deletingIds"
:createMode="createMode"
></router-view>
</template>
</q-splitter>
<router-view
v-if="!showTabs"
@no-user-found="handleNoUserFound"
@user-created="handleCreateUser"
@user-updated="handleUpdateUser"
@cancel-create="route"
@delete-user="askDeleteUser"
:deletingIds="deletingIds"
:createMode="createMode"
></router-view>
</template>
<ConfirmDialog ref="confirmDialog" />
</q-splitter>
</main-layout>
</template>
<script>
import _ from 'lodash'
import errors from 'src/utils/errors'
import notification from 'src/utils/notification'
import typesUtils from 'src/utils/types'
import webApi from 'src/utils/web-api'
import cache from 'src/cache'
import modulesManager from 'src/modules-manager'
import settings from 'src/settings'
import MainLayout from 'src/layouts/MainLayout'
import ConfirmDialog from 'src/components/ConfirmDialog'
import StandardList from 'src/components/StandardList'
import IconAdd from 'src/assets/icons/Add'
import IconAddToGroup from 'src/assets/icons/AddToGroup'
import IconRemoveFromGroup from 'src/assets/icons/RemoveFromGroup'
import IconTrash from 'src/assets/icons/Trash'
import enums from 'src/enums'
let UserRoles = {}
export default {
name: 'Domains',
components: {
MainLayout,
ConfirmDialog,
StandardList,
IconAdd,
IconAddToGroup,
IconRemoveFromGroup,
IconTrash,
},
data() {
return {
users: [],
selectedUserId: 0,
loadingUsers: false,
totalCount: 0,
search: '',
page: 1,
limit: settings.getEntitiesPerPage(),
userItems: [],
checkedIds: [],
allowCreateUser: true,
justCreatedId: 0,
deletingIds: [],
selectedGroupId: -1,
tabs: [],
selectedTab: '',
listSplitterWidth: typesUtils.pInt(localStorage.getItem('aurora_admin_users_splitter-width'), 20),
tabsSplitterWidth: typesUtils.pInt(localStorage.getItem('aurora_admin_users_tabs_splitter-width'), 20),
filters: [],
currentFiltersRoutes: {},
filtersGetParameters: {},
}
},
computed: {
currentTenantId() {
return this.$store.getters['tenants/getCurrentTenantId']
},
pagesCount() {
return Math.ceil(this.totalCount / this.limit)
},
countLabel() {
const count = this.checkedIds.length
return count > 0 ? count : ''
},
showTabs() {
return this.tabs.length > 0 && this.selectedUserId > 0
},
deleting() {
return this.deletingIds.indexOf(this.selectedUserId) !== -1
},
createMode() {
const createIndex = this.$route.path.indexOf('/create')
return createIndex !== -1 && createIndex === this.$route.path.length - 7
},
allTenantGroups() {
const groups = this.$store.getters['groups/getGroups']
const allTenantGroups = typesUtils.pArray(groups[this.currentTenantId])
return allTenantGroups.filter((group) => !group.isTeam)
},
groups() {
const selectedGroupId = this.selectedGroupId
return this.allTenantGroups.filter((group) => group.id !== selectedGroupId)
},
checkedOrSelectedUsersIds() {
if (this.checkedIds.length > 0) {
return this.checkedIds
}
if (this.selectedUserId !== 0) {
return [this.selectedUserId]
}
return []
},
disableRemoveFromGroup() {
const selectedGroup = this.allTenantGroups.find((group) => group.id === this.selectedGroupId)
return !selectedGroup || this.checkedOrSelectedUsersIds.length <= 0
},
selectedUserRole() {
const selectedUser = this.users.find((user) => user.id === this.selectedUserId),
selectedUserRole = selectedUser && selectedUser.role
return selectedUserRole || UserRoles.NormalUser
},
isUserSuperAdmin() {
return this.$store.getters['user/isUserSuperAdmin']
},
userRole() {
return this.$store.getters['user/getUserRole']
},
},
watch: {
currentTenantId() {
if (this.$route.path !== '/users') {
this.route()
}
this.populate()
},
$route(to, from) {
this.parseRoute()
},
users() {
const userPublicId = this.$store.getters['user/getUserPublicId']
const UserRoles = enums.getUserRoles()
this.userItems = this.users.map((user) => {
const labels = []
if (user.disabled) {
labels.push({
title: this.$t('ADMINPANELWEBCLIENT.LABEL_DISABLED'),
cssClass: 'disabled',
})
}
if (user.publicId === userPublicId) {
labels.push({
title: this.$t('ADMINPANELWEBCLIENT.LABEL_ITS_ME'),
cssClass: 'me',
})
}
if (user.role === UserRoles.TenantAdmin) {
labels.push({
title: this.$t('ADMINPANELWEBCLIENT.LABEL_ITS_ADMIN'),
cssClass: 'admin',
})
}
return {
id: user.id,
title: user.publicId,
checked: false,
labels,
}
})
},
allowCreateUser() {
if (!this.allowCreateUser && this.createMode) {
this.$router.push('/users')
}
},
listSplitterWidth(listSplitterWidth) {
localStorage.setItem('aurora_admin_users_splitter-width', listSplitterWidth)
},
tabsSplitterWidth(tabsSplitterWidth) {
localStorage.setItem('aurora_admin_users_tabs_splitter-width', tabsSplitterWidth)
},
},
mounted() {
UserRoles = enums.getUserRoles()
this.populateFilters()
this.populateTabs()
this.populate()
this.parseRoute()
},
methods: {
parseRoute() {
if (this.createMode) {
this.selectedUserId = 0
} else {
const search = typesUtils.pString(this.$route?.params?.search)
const page = typesUtils.pPositiveInt(this.$route?.params?.page)
if (this.search !== search || this.page !== page || this.justCreatedId !== 0) {
this.search = search
this.page = page
this.populate()
}
const userId = typesUtils.pNonNegativeInt(this.$route?.params?.id)
if (this.selectedUserId !== userId) {
this.selectedUserId = userId
}
this.selectedGroupId = typesUtils.pInt(this.$route?.params?.group)
const pathParts = this.$route.path.split('/')
const lastPart = pathParts.length > 0 ? pathParts[pathParts.length - 1] : ''
const tab = this.tabs.find((tab) => {
return tab.tabName === lastPart
})
this.selectedTab = tab ? tab.tabName : ''
}
},
handleAllowCreateUser(data) {
if (data.tenantId === this.currentTenantId) {
this.allowCreateUser = data.allowCreateUser
}
},
populateFilters() {
this.filters = modulesManager.getFiltersForUsers()
},
populateTabs() {
this.tabs = modulesManager.getAdminEntityTabs('getAdminUserTabs').map((tab) => {
return {
tabName: tab.tabName,
tabTitle: tab.tabTitle,
hideTabForSelectedUserRoles:
tab.hideTabForSelectedUserRoles !== undefined ? tab.hideTabForSelectedUserRoles : [],
}
})
},
populateFiltersGetParameters(filterGetParameter) {
const newFiltersGetParameters = _.extend(_.clone(this.filtersGetParameters), filterGetParameter)
if (!_.isEqual(newFiltersGetParameters, this.filtersGetParameters)) {
this.filtersGetParameters = newFiltersGetParameters
this.populate()
}
},
populate() {
this.loadingUsers = true
cache
.getUsers(this.currentTenantId, this.filtersGetParameters, this.search, this.page, this.limit)
.then(({ users, totalCount, tenantId, filtersGetParameters = {}, page = 1, search = '' }) => {
if (
tenantId === this.currentTenantId &&
_.isEqual(filtersGetParameters, this.filtersGetParameters) &&
page === this.page &&
search === this.search
) {
this.users = users
this.totalCount = totalCount
this.loadingUsers = false
if (this.justCreatedId && users.find(user => user.id === this.justCreatedId)) {
this.route(this.justCreatedId)
this.justCreatedId = 0
}
}
})
},
getFiltersRoute() {
const filterRoutes = _.map(this.currentFiltersRoutes, (routeValue, routeName) => {
return routeValue !== undefined ? routeName + '/' + routeValue : ''
})
const filterRoutesValues = _.filter(filterRoutes, (routeValue) => {
return routeValue !== ''
})
return filterRoutesValues.length > 0 ? '/' + filterRoutesValues.join('/') : ''
},
routeFilter(data) {
if (this.currentFiltersRoutes[data.routeName] !== data.routeValue) {
this.currentFiltersRoutes[data.routeName] = data.routeValue
this.route()
}
},
route(userId = 0, tabName = '') {
const enteredSearch = this.$refs?.userList?.enteredSearch || ''
const searchRoute = enteredSearch !== '' ? `/search/${enteredSearch}` : ''
let selectedPage = this.$refs?.userList?.selectedPage || 1
if (this.search !== enteredSearch) {
selectedPage = 1
}
const pageRoute = selectedPage > 1 ? `/page/${selectedPage}` : ''
const idRoute = userId > 0 ? `/id/${userId}` : ''
const tabRoute = tabName !== '' ? `/${tabName}` : ''
const path = '/users' + this.getFiltersRoute() + searchRoute + pageRoute + idRoute + tabRoute
if (path !== this.$route.path) {
this.$router.push(path)
}
},
routeCreateUser() {
this.$router.push('/users' + this.getFiltersRoute() + '/create')
},
handleCreateUser(id) {
this.justCreatedId = id
this.route()
this.populate()
},
handleUpdateUser(id) {
this.populate()
},
afterCheck(ids) {
this.checkedIds = ids
},
handleNoUserFound() {
notification.showError(this.$t('ADMINPANELWEBCLIENT.ERROR_USER_NOT_FOUND'))
this.route()
this.populate()
},
askDeleteUser(id) {
this.askDeleteUsers([id])
},
askDeleteCheckedUsers() {
this.askDeleteUsers(this.checkedIds)
},
askDeleteUsers(ids) {
if (_.isFunction(this?.$refs?.confirmDialog?.openDialog)) {
const user =
ids.length === 1
? this.users.find((user) => {
return user.id === ids[0]
})
: null
const title = user ? user.publicId : ''
this.$refs.confirmDialog.openDialog({
title,
message: this.$tc('ADMINPANELWEBCLIENT.CONFIRM_DELETE_USER_PLURAL', ids.length),
okHandler: this.deleteUsers.bind(this, ids),
})
}
},
deleteUsers(ids) {
this.deletingIds = ids
this.loadingUsers = true
webApi
.sendRequest({
moduleName: 'Core',
methodName: 'DeleteUsers',
parameters: {
IdList: ids,
},
})
.then(
(result) => {
this.deletingIds = []
this.loadingUsers = false
if (result === true) {
notification.showReport(this.$tc('ADMINPANELWEBCLIENT.REPORT_DELETE_ENTITIES_USER_PLURAL', ids.length))
const isSelectedUserRemoved = ids.indexOf(this.selectedUserId) !== -1
const selectedPage = this.$refs?.userList?.selectedPage || 1
const shouldChangePage = this.users.length === ids.length && selectedPage > 1
if (shouldChangePage && _.isFunction(this.$refs?.userList?.decreasePage)) {
this.$refs.userList.decreasePage()
} else if (isSelectedUserRemoved) {
this.route()
this.populate()
} else {
this.populate()
}
} else {
notification.showError(this.$tc('ADMINPANELWEBCLIENT.ERROR_DELETE_ENTITIES_USER_PLURAL', ids.length))
}
},
(error) => {
this.deletingIds = []
this.loadingUsers = false
notification.showError(
errors.getTextFromResponse(
error,
this.$tc('ADMINPANELWEBCLIENT.ERROR_DELETE_ENTITIES_USER_PLURAL', ids.length)
)
)
}
)
},
addUsersToGroup(groupId) {
if (this.checkedOrSelectedUsersIds.length > 0) {
this.$store.dispatch('groups/addUsersToGroup', {
tenantId: this.currentTenantId,
groupId,
usersIds: this.checkedOrSelectedUsersIds,
})
}
},
async removeFromGroup() {
if (this.checkedOrSelectedUsersIds.length > 0) {
await this.$store.dispatch('groups/removeUsersFromGroup', {
tenantId: this.currentTenantId,
groupId: this.selectedGroupId,
usersIds: this.checkedOrSelectedUsersIds,
callback: this.populate.bind(this),
})
}
},
},
}
</script>
<style lang="scss">
.q-menu.q-position-engine {
z-index: 10000;
}
</style>