|
|
|
@ -1,10 +1,16 @@
|
|
|
|
|
<script lang="ts" setup> |
|
|
|
|
import { iconMap, isEeUI, navigateTo, useUIPermission } from '#imports' |
|
|
|
|
import { iconMap, navigateTo, useUIPermission } from '#imports' |
|
|
|
|
|
|
|
|
|
definePageMeta({ |
|
|
|
|
hideHeader: true, |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
const { isUIAllowed } = useUIPermission() |
|
|
|
|
|
|
|
|
|
const $route = useRoute() |
|
|
|
|
|
|
|
|
|
const { appInfo, signedIn, signOut } = useGlobal() |
|
|
|
|
|
|
|
|
|
const selectedKeys = computed(() => [ |
|
|
|
|
/^\/account\/users\/?$/.test($route.fullPath) |
|
|
|
|
? isUIAllowed('superAdminUserManagement') |
|
|
|
@ -12,86 +18,180 @@ const selectedKeys = computed(() => [
|
|
|
|
|
: 'settings' |
|
|
|
|
: $route.params.nestedPage ?? $route.params.page, |
|
|
|
|
]) |
|
|
|
|
|
|
|
|
|
const openKeys = ref([/^\/account\/users/.test($route.fullPath) && 'users']) |
|
|
|
|
|
|
|
|
|
const logout = async () => { |
|
|
|
|
await signOut(false) |
|
|
|
|
navigateTo('/signin') |
|
|
|
|
} |
|
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
<template> |
|
|
|
|
<div class="mx-auto h-full"> |
|
|
|
|
<a-layout class="h-full overflow-y-auto flex"> |
|
|
|
|
<!-- Side tabs --> |
|
|
|
|
<a-layout-sider> |
|
|
|
|
<NuxtLayout name="empty"> |
|
|
|
|
<div class="mx-auto h-full"> |
|
|
|
|
<div class="h-full overflow-y-auto flex"> |
|
|
|
|
<!-- Side tabs --> |
|
|
|
|
|
|
|
|
|
<div class="h-full bg-white nc-user-sidebar"> |
|
|
|
|
<a-menu |
|
|
|
|
<NcMenu |
|
|
|
|
v-model:openKeys="openKeys" |
|
|
|
|
v-model:selectedKeys="selectedKeys" |
|
|
|
|
:inline-indent="16" |
|
|
|
|
class="tabs-menu h-full" |
|
|
|
|
mode="inline" |
|
|
|
|
> |
|
|
|
|
<div class="text-xs text-gray-500 ml-4 pt-4 pb-2 font-weight-bold">{{ $t('title.accountSettings') }}</div> |
|
|
|
|
<div |
|
|
|
|
v-if="!$route.params.projectType" |
|
|
|
|
v-e="['c:navbar:home']" |
|
|
|
|
data-testid="nc-noco-brand-icon" |
|
|
|
|
class="transition-all duration-200 px-2 mx-2 mt-1.5 cursor-pointer transform hover:bg-gray-100 my-1 nc-noco-brand-icon h-8 rounded-md min-w-60" |
|
|
|
|
@click="navigateTo('/')" |
|
|
|
|
> |
|
|
|
|
<div class="flex flex-row gap-x-2 items-center h-8.5"> |
|
|
|
|
<GeneralIcon icon="arrowLeft" class="-mt-0.1" /> |
|
|
|
|
<div class="flex text-xs text-gray-800">Back to Workspace</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<a-sub-menu key="users" class="!bg-white"> |
|
|
|
|
<div class="text-xs text-gray-600 ml-4 py-1.5 mt-3">{{ $t('labels.account') }}</div> |
|
|
|
|
|
|
|
|
|
<NcMenuItem |
|
|
|
|
key="profile" |
|
|
|
|
class="item" |
|
|
|
|
:class="{ |
|
|
|
|
active: $route.params.page === 'profile', |
|
|
|
|
}" |
|
|
|
|
@click="navigateTo('/account/profile')" |
|
|
|
|
> |
|
|
|
|
<div class="flex items-center space-x-2"> |
|
|
|
|
<GeneralIcon icon="account" /> |
|
|
|
|
|
|
|
|
|
<div class="select-none">{{ $t('labels.profile') }}</div> |
|
|
|
|
</div> |
|
|
|
|
</NcMenuItem> |
|
|
|
|
|
|
|
|
|
<NcMenuItem |
|
|
|
|
key="tokens" |
|
|
|
|
class="item" |
|
|
|
|
:class="{ |
|
|
|
|
active: $route.params.page === 'tokens', |
|
|
|
|
}" |
|
|
|
|
@click="navigateTo('/account/tokens')" |
|
|
|
|
> |
|
|
|
|
<div class="flex items-center space-x-2"> |
|
|
|
|
<MdiShieldKeyOutline /> |
|
|
|
|
|
|
|
|
|
<div class="select-none">{{ $t('title.tokens') }}</div> |
|
|
|
|
</div> |
|
|
|
|
</NcMenuItem> |
|
|
|
|
<NcMenuItem |
|
|
|
|
v-if="isUIAllowed('appStore') && !isEeUI" |
|
|
|
|
key="apps" |
|
|
|
|
class="item" |
|
|
|
|
:class="{ |
|
|
|
|
active: $route.params.page === 'apps', |
|
|
|
|
}" |
|
|
|
|
@click="navigateTo('/account/apps')" |
|
|
|
|
> |
|
|
|
|
<div class="flex items-center space-x-2"> |
|
|
|
|
<component :is="iconMap.appStore" /> |
|
|
|
|
|
|
|
|
|
<div class="select-none text-sm">{{ $t('title.appStore') }}</div> |
|
|
|
|
</div> |
|
|
|
|
</NcMenuItem> |
|
|
|
|
<a-sub-menu key="users" class="!bg-white !my-0"> |
|
|
|
|
<template #icon> |
|
|
|
|
<MdiAccountSupervisorOutline /> |
|
|
|
|
</template> |
|
|
|
|
<template #title>Users</template> |
|
|
|
|
|
|
|
|
|
<a-menu-item |
|
|
|
|
<NcMenuItem |
|
|
|
|
v-if="isUIAllowed('superAdminUserManagement') && !isEeUI" |
|
|
|
|
key="list" |
|
|
|
|
class="text-xs" |
|
|
|
|
class="text-xs item" |
|
|
|
|
:class="{ |
|
|
|
|
active: $route.params.nestedPage === 'list', |
|
|
|
|
}" |
|
|
|
|
@click="navigateTo('/account/users/list')" |
|
|
|
|
> |
|
|
|
|
<span class="ml-4">{{ $t('title.userManagement') }}</span> |
|
|
|
|
</a-menu-item> |
|
|
|
|
<a-menu-item key="password-reset" class="text-xs" @click="navigateTo('/account/users/password-reset')"> |
|
|
|
|
</NcMenuItem> |
|
|
|
|
<NcMenuItem |
|
|
|
|
key="password-reset" |
|
|
|
|
class="text-xs item" |
|
|
|
|
:class="{ |
|
|
|
|
active: $route.params.nestedPage === 'password-reset', |
|
|
|
|
}" |
|
|
|
|
@click="navigateTo('/account/users/password-reset')" |
|
|
|
|
> |
|
|
|
|
<span class="ml-4">{{ $t('title.resetPasswordMenu') }}</span> |
|
|
|
|
</a-menu-item> |
|
|
|
|
<a-menu-item |
|
|
|
|
</NcMenuItem> |
|
|
|
|
<NcMenuItem |
|
|
|
|
v-if="isUIAllowed('superAdminAppSettings') && !isEeUI" |
|
|
|
|
key="settings" |
|
|
|
|
class="text-xs" |
|
|
|
|
class="text-xs item" |
|
|
|
|
:class="{ |
|
|
|
|
active: $route.params.nestedPage === 'settings', |
|
|
|
|
}" |
|
|
|
|
@click="navigateTo('/account/users/settings')" |
|
|
|
|
> |
|
|
|
|
<span class="ml-4">{{ $t('activity.settings') }}</span> |
|
|
|
|
</a-menu-item> |
|
|
|
|
</NcMenuItem> |
|
|
|
|
</a-sub-menu> |
|
|
|
|
</NcMenu> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<a-menu-item |
|
|
|
|
key="tokens" |
|
|
|
|
class="group active:(!ring-0) hover:(!bg-primary !bg-opacity-25)" |
|
|
|
|
@click="navigateTo('/account/tokens')" |
|
|
|
|
> |
|
|
|
|
<div class="flex items-center space-x-2"> |
|
|
|
|
<MdiShieldKeyOutline /> |
|
|
|
|
<!-- Sub Tabs --> |
|
|
|
|
|
|
|
|
|
<div class="select-none">{{ $t('title.tokens') }}</div> |
|
|
|
|
</div> |
|
|
|
|
</a-menu-item> |
|
|
|
|
<a-menu-item |
|
|
|
|
v-if="isUIAllowed('appStore') && !isEeUI" |
|
|
|
|
key="apps" |
|
|
|
|
class="group active:(!ring-0) hover:(!bg-primary !bg-opacity-25)" |
|
|
|
|
@click="navigateTo('/account/apps')" |
|
|
|
|
> |
|
|
|
|
<div class="flex items-center space-x-2"> |
|
|
|
|
<component :is="iconMap.appStore" /> |
|
|
|
|
<div class="flex flex-col w-full"> |
|
|
|
|
<div class="flex flex-row p-3 items-center"> |
|
|
|
|
<div class="flex-1" /> |
|
|
|
|
|
|
|
|
|
<LazyGeneralReleaseInfo /> |
|
|
|
|
|
|
|
|
|
<div class="select-none">{{ $t('title.appStore') }}</div> |
|
|
|
|
<a-tooltip v-if="!appInfo.ee" placement="bottom" :mouse-enter-delay="1"> |
|
|
|
|
<template #title> Switch language</template> |
|
|
|
|
|
|
|
|
|
<div class="flex pr-4 items-center"> |
|
|
|
|
<LazyGeneralLanguage class="cursor-pointer text-2xl hover:text-gray-800" /> |
|
|
|
|
</div> |
|
|
|
|
</a-menu-item> |
|
|
|
|
</a-menu> |
|
|
|
|
</div> |
|
|
|
|
</a-layout-sider> |
|
|
|
|
</a-tooltip> |
|
|
|
|
|
|
|
|
|
<template v-if="signedIn"> |
|
|
|
|
<NcDropdown :trigger="['click']" overlay-class-name="nc-dropdown-user-accounts-menu"> |
|
|
|
|
<NcButton type="text" size="small"> |
|
|
|
|
<component |
|
|
|
|
:is="iconMap.threeDotVertical" |
|
|
|
|
data-testid="nc-menu-accounts" |
|
|
|
|
class="md:text-lg cursor-pointer hover:text-gray-800 nc-menu-accounts" |
|
|
|
|
@click.prevent |
|
|
|
|
/> |
|
|
|
|
</NcButton> |
|
|
|
|
|
|
|
|
|
<template #overlay> |
|
|
|
|
<div class="!py-1 !rounded-md bg-white overflow-hidden"> |
|
|
|
|
<div class="!rounded-b group" data-testid="nc-menu-accounts__sign-out"> |
|
|
|
|
<div v-e="['a:navbar:user:sign-out']" class="nc-account-dropdown-item group" @click="logout"> |
|
|
|
|
<component :is="iconMap.signout" class="group-hover:text-accent" /> |
|
|
|
|
|
|
|
|
|
<!-- Sub Tabs --> |
|
|
|
|
<a-layout-content class="h-auto px-4 scrollbar-thumb-gray-500"> |
|
|
|
|
<div class="container mx-auto"> |
|
|
|
|
<NuxtPage /> |
|
|
|
|
<span class="prose group-hover:text-primary"> |
|
|
|
|
{{ $t('general.signOut') }} |
|
|
|
|
</span> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</template> |
|
|
|
|
</NcDropdown> |
|
|
|
|
</template> |
|
|
|
|
</div> |
|
|
|
|
<div class="flex flex-col container mx-auto mt-2"> |
|
|
|
|
<NuxtPage /> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</a-layout-content> |
|
|
|
|
</a-layout> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</NuxtLayout> |
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped> |
|
|
|
@ -111,4 +211,26 @@ const openKeys = ref([/^\/account\/users/.test($route.fullPath) && 'users'])
|
|
|
|
|
:deep(.ant-menu-submenu-selected .ant-menu-submenu-arrow) { |
|
|
|
|
@apply !text-inherit; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
:deep(.item) { |
|
|
|
|
@apply select-none mx-2 !px-3 !text-sm !rounded-md !mb-1 !hover:(bg-brand-50 text-brand-500); |
|
|
|
|
width: calc(100% - 1rem); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
:deep(.active) { |
|
|
|
|
@apply !bg-brand-50 !text-brand-500; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
:deep(.ant-menu-submenu-title) { |
|
|
|
|
@apply select-none mx-2 !px-3 !text-sm !rounded-md !mb-1 !hover:(bg-brand-50 text-brand-500); |
|
|
|
|
width: calc(100% - 1rem); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
:deep(.ant-menu) { |
|
|
|
|
@apply !pt-0 !rounded-none !border-gray-200; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.nc-account-dropdown-item { |
|
|
|
|
@apply flex flex-row px-4 items-center py-2 gap-x-2 hover:bg-gray-100 cursor-pointer; |
|
|
|
|
} |
|
|
|
|
</style> |
|
|
|
|