Browse Source

fix(nc-gui): refactor issues

pull/3801/head
braks 2 years ago
parent
commit
90b3da67ab
  1. 2
      packages/nc-gui/app.vue
  2. 1
      packages/nc-gui/components.d.ts
  3. 22
      packages/nc-gui/components/tabs/Auth.vue
  4. 28
      packages/nc-gui/composables/useProject.ts
  5. 6
      packages/nc-gui/middleware/auth.global.ts
  6. 6
      packages/nc-gui/pages/[projectType]/[projectId]/index.vue
  7. 2
      packages/nc-gui/pages/[projectType]/[projectId]/index/index/[type]/[title]/[[viewTitle]].vue
  8. 4
      packages/nc-gui/pages/index/index.vue
  9. 4
      packages/nc-gui/pages/index/index/index.vue
  10. 12
      packages/nc-gui/pages/signin.vue

2
packages/nc-gui/app.vue

@ -9,7 +9,7 @@ const disableBaseLayout = computed(() => route.path.startsWith('/nc/view') || ro
<template> <template>
<a-config-provider> <a-config-provider>
<NuxtLayout :name="disableBaseLayout ? false : 'base'"> <NuxtLayout :name="disableBaseLayout ? false : 'base'">
<NuxtPage /> <NuxtPage keepalive :page-key="$route.fullPath.split('?')[0]" />
</NuxtLayout> </NuxtLayout>
</a-config-provider> </a-config-provider>
</template> </template>

1
packages/nc-gui/components.d.ts vendored

@ -142,7 +142,6 @@ declare module '@vue/runtime-core' {
MdiMoonFull: typeof import('~icons/mdi/moon-full')['default'] MdiMoonFull: typeof import('~icons/mdi/moon-full')['default']
MdiNumeric: typeof import('~icons/mdi/numeric')['default'] MdiNumeric: typeof import('~icons/mdi/numeric')['default']
MdiOpenInNew: typeof import('~icons/mdi/open-in-new')['default'] MdiOpenInNew: typeof import('~icons/mdi/open-in-new')['default']
MdiOpenInNewIcon: typeof import('~icons/mdi/open-in-new-icon')['default']
MdiPencil: typeof import('~icons/mdi/pencil')['default'] MdiPencil: typeof import('~icons/mdi/pencil')['default']
MdiPlus: typeof import('~icons/mdi/plus')['default'] MdiPlus: typeof import('~icons/mdi/plus')['default']
MdiPlusOutline: typeof import('~icons/mdi/plus-outline')['default'] MdiPlusOutline: typeof import('~icons/mdi/plus-outline')['default']

22
packages/nc-gui/components/tabs/Auth.vue

@ -1,11 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n, useUIPermission } from '#imports' import type { ComputedRef } from 'vue'
import { computed, useI18n, useUIPermission } from '#imports'
interface Tab { interface Tab {
title: string title: string
label: string label: string
body: any isUIAllowed: ComputedRef<boolean>
isUIAllowed: () => boolean
} }
const { t } = useI18n() const { t } = useI18n()
@ -16,14 +16,12 @@ const tabsInfo: Tab[] = [
{ {
title: 'Users Management', title: 'Users Management',
label: t('title.userMgmt'), label: t('title.userMgmt'),
body: () => import('./auth/UserManagement.vue'), isUIAllowed: computed(() => isUIAllowed('userMgmtTab')),
isUIAllowed: () => isUIAllowed('userMgmtTab'),
}, },
{ {
title: 'API Token Management', title: 'API Token Management',
label: t('title.apiTokenMgmt'), label: t('title.apiTokenMgmt'),
body: () => import('./auth/ApiTokenManagement.vue'), isUIAllowed: computed(() => isUIAllowed('apiTokenTab')),
isUIAllowed: () => isUIAllowed('apiTokenTab'),
}, },
] ]
@ -32,7 +30,7 @@ const selectedTab = $computed(() => tabsInfo[selectedTabKey])
</script> </script>
<template> <template>
<div v-if="selectedTab.isUIAllowed()"> <div v-if="selectedTab.isUIAllowed">
<a-tabs v-model:active-key="selectedTabKey" :open-keys="[]" mode="horizontal" class="nc-auth-tabs !mx-6"> <a-tabs v-model:active-key="selectedTabKey" :open-keys="[]" mode="horizontal" class="nc-auth-tabs !mx-6">
<a-tab-pane v-for="(tab, key) of tabsInfo" :key="key" class="select-none"> <a-tab-pane v-for="(tab, key) of tabsInfo" :key="key" class="select-none">
<template #tab> <template #tab>
@ -44,7 +42,13 @@ const selectedTab = $computed(() => tabsInfo[selectedTabKey])
</a-tabs> </a-tabs>
<div class="mx-4 py-6 mt-2"> <div class="mx-4 py-6 mt-2">
<component :is="selectedTab.body()" /> <template v-if="selectedTabKey === 0">
<LazyTabsAuthUserManagement />
</template>
<template v-else>
<LazyTabsAuthApiTokenManagement />
</template>
</div> </div>
</div> </div>
</template> </template>

28
packages/nc-gui/composables/useProject.ts

@ -6,12 +6,15 @@ import {
computed, computed,
createEventHook, createEventHook,
ref, ref,
tryOnScopeDispose,
unref,
useApi, useApi,
useGlobal, useGlobal,
useInjectionState, useInjectionState,
useNuxtApp, useNuxtApp,
useRoles, useRoles,
useRoute, useRoute,
useRouter,
useTheme, useTheme,
watch, watch,
} from '#imports' } from '#imports'
@ -28,6 +31,8 @@ const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
const { setTheme, theme } = useTheme() const { setTheme, theme } = useTheme()
const router = useRouter()
const { projectRoles, loadProjectRoles } = useRoles() const { projectRoles, loadProjectRoles } = useRoles()
const projectLoadedHook = createEventHook<ProjectType>() const projectLoadedHook = createEventHook<ProjectType>()
@ -62,17 +67,15 @@ const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
const isPg = computed(() => projectBaseType === 'pg') const isPg = computed(() => projectBaseType === 'pg')
const isSharedBase = computed(() => projectType === 'base') const isSharedBase = computed(() => projectType === 'base')
const router = useRouter()
async function loadProjectMetaInfo(force?: boolean) { async function loadProjectMetaInfo(force?: boolean) {
if (!projectMetaInfo.value || force) { if (!projectMetaInfo.value || force) {
projectMetaInfo.value = await api.project.metaGet(project.value.id!, {}, {}) projectMetaInfo.value = await api.project.metaGet(project.value.id!, {}, {})
} }
} }
async function loadTables() { async function loadTables(id?: string) {
if (project.value.id) { if (id || project.value.id) {
const tablesResponse = await api.dbTable.list(project.value.id, { const tablesResponse = await api.dbTable.list((id || project.value.id)!, {
includeM2M: includeM2M.value, includeM2M: includeM2M.value,
}) })
@ -82,7 +85,7 @@ const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
async function loadProject(id?: string) { async function loadProject(id?: string) {
if (id) { if (id) {
project.value = await api.project.read(projectId.value) project.value = await api.project.read(id)
} else if (projectType === 'base') { } else if (projectType === 'base') {
try { try {
const baseData = await api.public.sharedBaseGet(route.params.projectId as string) const baseData = await api.public.sharedBaseGet(route.params.projectId as string)
@ -101,16 +104,15 @@ const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
} }
await loadProjectRoles( await loadProjectRoles(
project.value.id || (route.params.projectId as string), id || project.value.id || (route.params.projectId as string), isSharedBase.value,
isSharedBase.value,
route.params.projectId as string, route.params.projectId as string,
) )
await loadTables() await loadTables(id)
setTheme(projectMeta.value?.theme) setTheme(projectMeta.value?.theme)
projectLoadedHook.trigger(project.value) return projectLoadedHook.trigger(project.value)
} }
async function updateProject(data: Partial<ProjectType>) { async function updateProject(data: Partial<ProjectType>) {
@ -188,7 +190,11 @@ export function useProject(projectId?: MaybeRef<string>) {
const state = use() const state = use()
if (!state) { if (!state) {
return setup(projectId) const setupState = setup(projectId)
tryOnScopeDispose(setupState.reset)
return setupState
} }
return state return state

6
packages/nc-gui/middleware/auth.global.ts

@ -1,5 +1,5 @@
import type { Api } from 'nocodb-sdk' import type { Api } from 'nocodb-sdk'
import type { Actions } from '~/composables' import type { Actions } from '~/composables/useGlobal/types'
import { defineNuxtRouteMiddleware, message, navigateTo, useApi, useGlobal, useRoles } from '#imports' import { defineNuxtRouteMiddleware, message, navigateTo, useApi, useGlobal, useRoles } from '#imports'
/** /**
@ -43,7 +43,7 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
if (to.meta.public) return if (to.meta.public) return
/** if shared base allow without validating */ /** if shared base allow without validating */
if (to.params?.projectType === 'base') return if (to.params.projectType === 'base') return
/** if auth is required or unspecified (same as required) and user is not signed in, redirect to signin page */ /** if auth is required or unspecified (same as required) and user is not signed in, redirect to signin page */
if ((to.meta.requiresAuth || typeof to.meta.requiresAuth === 'undefined') && !state.signedIn.value) { if ((to.meta.requiresAuth || typeof to.meta.requiresAuth === 'undefined') && !state.signedIn.value) {
@ -74,7 +74,7 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
/** if users are accessing the projects without having enough permissions, redirect to My Projects page */ /** if users are accessing the projects without having enough permissions, redirect to My Projects page */
if (to.params.projectId && from.params.projectId !== to.params.projectId) { if (to.params.projectId && from.params.projectId !== to.params.projectId) {
const user = await api.auth.me({ project_id: to?.params?.projectId as string }) const user = await api.auth.me({ project_id: to.params.projectId as string })
if (user?.roles?.user) { if (user?.roles?.user) {
message.error("You don't have enough permission to access the project.") message.error("You don't have enough permission to access the project.")

6
packages/nc-gui/pages/[projectType]/[projectId]/index.vue

@ -150,7 +150,7 @@ onKeyStroke(
clearTabs() clearTabs()
onBeforeMount(async () => { onBeforeMount(async () => {
await loadProject() await loadProject(route.params.projectId as string)
if (!route.params.type && isUIAllowed('teamAndAuth')) { if (!route.params.type && isUIAllowed('teamAndAuth')) {
addTab({ type: TabType.AUTH, title: t('title.teamAndAuth') }) addTab({ type: TabType.AUTH, title: t('title.teamAndAuth') })
@ -486,10 +486,10 @@ onBeforeUnmount(reset)
</a-layout-sider> </a-layout-sider>
</template> </template>
<div :key="$route.fullPath.split('?')[0]"> <div>
<LazyDashboardSettingsModal v-model="dialogOpen" :open-key="openDialogKey" /> <LazyDashboardSettingsModal v-model="dialogOpen" :open-key="openDialogKey" />
<NuxtPage /> <NuxtPage :page-key="project.id" />
<LazyGeneralPreviewAs float /> <LazyGeneralPreviewAs float />
</div> </div>

2
packages/nc-gui/pages/[projectType]/[projectId]/index/index/[type]/[title]/[[viewTitle]].vue

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { TabItem } from '~/lib' import type { TabItem } from '~/lib'
import { TabMetaInj, until, computed, inject, useMetas, useProject, useRoute } from '#imports' import { TabMetaInj, computed, inject, ref, until, useMetas, useProject, useRoute } from '#imports'
const { getMeta } = useMetas() const { getMeta } = useMetas()

4
packages/nc-gui/pages/index/index.vue

@ -1,7 +1,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useRoute } from '#imports' import { useRoute, useSidebar } from '#imports'
const route = useRoute() const route = useRoute()
useSidebar('nc-left-sidebar', { hasSidebar: false })
</script> </script>
<template> <template>

4
packages/nc-gui/pages/index/index/index.vue

@ -14,7 +14,6 @@ import {
themeV2Colors, themeV2Colors,
useApi, useApi,
useNuxtApp, useNuxtApp,
useSidebar,
useUIPermission, useUIPermission,
} from '#imports' } from '#imports'
@ -28,8 +27,6 @@ const { api, isLoading } = useApi()
const { isUIAllowed } = useUIPermission() const { isUIAllowed } = useUIPermission()
useSidebar('nc-left-sidebar', { hasSidebar: false, isOpen: true })
const filterQuery = ref('') const filterQuery = ref('')
const projects = ref<ProjectType[]>() const projects = ref<ProjectType[]>()
@ -243,6 +240,7 @@ onBeforeMount(loadProjects)
Custom Color Custom Color
</div> </div>
</template> </template>
<template #expandIcon></template> <template #expandIcon></template>
<LazyGeneralChromeWrapper @input="handleProjectColor(record.id, $event)" /> <LazyGeneralChromeWrapper @input="handleProjectColor(record.id, $event)" />

12
packages/nc-gui/pages/signin.vue

@ -2,6 +2,11 @@
import type { RuleObject } from 'ant-design-vue/es/form' import type { RuleObject } from 'ant-design-vue/es/form'
import { definePageMeta, isEmail, navigateTo, reactive, ref, useApi, useGlobal, useI18n, useSidebar } from '#imports' import { definePageMeta, isEmail, navigateTo, reactive, ref, useApi, useGlobal, useI18n, useSidebar } from '#imports'
definePageMeta({
requiresAuth: false,
title: 'title.headLogin',
})
const { signIn: _signIn } = useGlobal() const { signIn: _signIn } = useGlobal()
const { api, isLoading, error } = useApi({ useGlobalInstance: true }) const { api, isLoading, error } = useApi({ useGlobalInstance: true })
@ -10,11 +15,6 @@ const { t } = useI18n()
useSidebar('nc-left-sidebar', { hasSidebar: false }) useSidebar('nc-left-sidebar', { hasSidebar: false })
definePageMeta({
requiresAuth: false,
title: 'title.headLogin',
})
const formValidator = ref() const formValidator = ref()
const form = reactive({ const form = reactive({
@ -31,6 +31,7 @@ const formRules: Record<string, RuleObject[]> = {
validator: (_: unknown, v: string) => { validator: (_: unknown, v: string) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (isEmail(v)) return resolve() if (isEmail(v)) return resolve()
reject(new Error(t('msg.error.signUpRules.emailInvalid'))) reject(new Error(t('msg.error.signUpRules.emailInvalid')))
}) })
}, },
@ -50,6 +51,7 @@ async function signIn() {
api.auth.signin(form).then(async ({ token }) => { api.auth.signin(form).then(async ({ token }) => {
_signIn(token!) _signIn(token!)
await navigateTo('/') await navigateTo('/')
}) })
} }

Loading…
Cancel
Save