From 71ecbe1819ff8e7ed352abaed6e0fecd0059ddd0 Mon Sep 17 00:00:00 2001 From: mertmit Date: Mon, 29 Aug 2022 17:57:19 +0300 Subject: [PATCH] fix: use injection for useProject Signed-off-by: mertmit --- .../composables/useInjectionState/index.ts | 22 ++++- packages/nc-gui-v2/composables/useProject.ts | 98 +++++++++++-------- .../index/index/{[id].vue => [projectId].vue} | 4 +- 3 files changed, 77 insertions(+), 47 deletions(-) rename packages/nc-gui-v2/pages/index/index/{[id].vue => [projectId].vue} (97%) diff --git a/packages/nc-gui-v2/composables/useInjectionState/index.ts b/packages/nc-gui-v2/composables/useInjectionState/index.ts index d96955c07f..09933498d6 100644 --- a/packages/nc-gui-v2/composables/useInjectionState/index.ts +++ b/packages/nc-gui-v2/composables/useInjectionState/index.ts @@ -1,20 +1,36 @@ -import type { InjectionKey } from 'vue' +import type { EffectScope, InjectionKey } from 'vue' +import { getCurrentScope } from 'vue' + +type ExtendedScope = { [key: symbol]: T } & EffectScope export function useInjectionState( composable: (...args: Arguments) => Return, keyName = 'InjectionState', ): readonly [useInjectionState: (...args: Arguments) => Return, useInjectedState: () => Return | undefined] { - const key: string | InjectionKey = Symbol(keyName) + const keySymbol = Symbol(keyName) + const key: string | InjectionKey = keySymbol const useProvidingState = (...args: Arguments) => { const providedState = composable(...args) + const currentScope = getCurrentScope() as ExtendedScope + currentScope[keySymbol] = providedState + provide(key, providedState) return providedState } - const useInjectedState = () => inject(key, undefined) + const useInjectedState = () => { + let injection = inject(key, undefined) + + if (typeof injection === 'undefined') { + const currentScope = getCurrentScope() as ExtendedScope + injection = currentScope[keySymbol] + } + + return injection + } return [useProvidingState, useInjectedState] } diff --git a/packages/nc-gui-v2/composables/useProject.ts b/packages/nc-gui-v2/composables/useProject.ts index 6af3e9de92..82ae2f709f 100644 --- a/packages/nc-gui-v2/composables/useProject.ts +++ b/packages/nc-gui-v2/composables/useProject.ts @@ -1,34 +1,25 @@ +import type { MaybeRef } from '@vueuse/core' import { SqlUiFactory } from 'nocodb-sdk' import type { OracleUi, ProjectType, TableType } from 'nocodb-sdk' -import type { MaybeRef } from '@vueuse/core' -import { useNuxtApp, useRoute, useState } from '#app' +import { useNuxtApp, useRoute } from '#app' import type { ProjectMetaInfo } from '~/lib' -import { USER_PROJECT_ROLES } from '~/lib' import type { ThemeConfig } from '@/composables/useTheme' +import { useInjectionState } from '#imports' -export function useProject(projectId?: MaybeRef) { - const projectRoles = useState>(USER_PROJECT_ROLES, () => ({})) +const [setup, use] = useInjectionState((_projectId?: MaybeRef) => { const { $api } = useNuxtApp() - let _projectId = $ref('') - - const project = useState('project') - const tables = useState('tables', () => [] as TableType[]) const route = useRoute() const { includeM2M } = useGlobal() const { setTheme } = useTheme() - const projectMetaInfo = useState('projectMetaInfo') + + const projectId = computed(() => (_projectId ? unref(_projectId) : (route.params.projectId as string))) + const project = ref({}) + const tables = ref([]) + const projectRoles = ref>({}) + const projectMetaInfo = ref() + // todo: refactor path param name and variable name const projectType = $computed(() => route.params.projectType as string) - const isLoaded = ref(false) - - const projectBaseType = $computed(() => project.value?.bases?.[0]?.type || '') - const isMysql = computed(() => ['mysql', 'mysql2'].includes(projectBaseType)) - const isMssql = computed(() => projectBaseType === 'mssql') - const isPg = computed(() => projectBaseType === 'pg') - const sqlUi = computed( - () => SqlUiFactory.create({ client: projectBaseType }) as Exclude, typeof OracleUi>, - ) - const isSharedBase = computed(() => projectType === 'base') const projectMeta = computed(() => { try { @@ -38,6 +29,17 @@ export function useProject(projectId?: MaybeRef) { } }) + const projectBaseType = $computed(() => project.value?.bases?.[0]?.type || '') + + const sqlUi = computed( + () => SqlUiFactory.create({ client: projectBaseType }) as Exclude, typeof OracleUi>, + ) + + const isMysql = computed(() => ['mysql', 'mysql2'].includes(projectBaseType)) + const isMssql = computed(() => projectBaseType === 'mssql') + const isPg = computed(() => projectBaseType === 'pg') + const isSharedBase = computed(() => projectType === 'base') + async function loadProjectMetaInfo(force?: boolean) { if (!projectMetaInfo.value || force) { const data = await $api.project.metaGet(project.value.id!, {}, {}) @@ -74,31 +76,21 @@ export function useProject(projectId?: MaybeRef) { } async function loadProject() { - if (unref(projectId)) { - _projectId = unref(projectId)! - } else if (projectType === 'base') { + if (projectType === 'base') { const baseData = await $api.public.sharedBaseGet(route.params.projectId as string) - _projectId = baseData.project_id! + project.value = await $api.project.read(baseData.project_id!) } else { - _projectId = route.params.projectId as string + project.value = await $api.project.read(projectId.value) } - isLoaded.value = true - project.value = await $api.project.read(_projectId!) await loadProjectRoles() await loadTables() - setTheme(projectMeta.value?.theme) } async function updateProject(data: Partial) { - if (unref(projectId)) { - _projectId = unref(projectId)! - } else if (projectType === 'base') { + if (projectType === 'base') { return - } else { - _projectId = route.params.projectId as string } - - await $api.project.update(_projectId, data) + await $api.project.update(projectId.value, data) } async function saveTheme(theme: Partial) { @@ -112,14 +104,24 @@ export function useProject(projectId?: MaybeRef) { setTheme(theme) } + watch(project, () => { + setTheme(projectMeta.value?.theme || {}) + }) + + watch( + () => route.params, + (v) => { + if (!v?.projectId) { + setTheme({}) + } + }, + ) + onScopeDispose(() => { - if (isLoaded.value === true) { - project.value = {} - tables.value = [] - projectMetaInfo.value = undefined - projectRoles.value = {} - setTheme({}) - } + project.value = {} + tables.value = [] + projectMetaInfo.value = undefined + projectRoles.value = {} }) return { @@ -139,4 +141,16 @@ export function useProject(projectId?: MaybeRef) { projectMeta, saveTheme, } +}, 'useProject') + +export const provideProject = setup + +export function useProject(projectId?: MaybeRef) { + const state = use() + + if (!state) { + return setup(projectId) + } + + return state } diff --git a/packages/nc-gui-v2/pages/index/index/[id].vue b/packages/nc-gui-v2/pages/index/index/[projectId].vue similarity index 97% rename from packages/nc-gui-v2/pages/index/index/[id].vue rename to packages/nc-gui-v2/pages/index/index/[projectId].vue index 3e4c977c3b..72ab27d685 100644 --- a/packages/nc-gui-v2/pages/index/index/[id].vue +++ b/packages/nc-gui-v2/pages/index/index/[projectId].vue @@ -21,7 +21,7 @@ useSidebar({ hasSidebar: false }) const route = useRoute() -const { project, loadProject, updateProject } = useProject(route.params.id as string) +const { project, loadProject, updateProject } = useProject(route.params.projectId as string) await loadProject() @@ -43,7 +43,7 @@ const renameProject = async () => { try { await updateProject(formState) - navigateTo(`/nc/${route.params.id}`) + navigateTo(`/nc/${route.params.projectId}`) } catch (e: any) { message.error(await extractSdkResponseErrorMsg(e)) }