diff --git a/packages/nc-gui-v2/composables/useProject.ts b/packages/nc-gui-v2/composables/useProject.ts index b51f9e7320..26ed0f83b0 100644 --- a/packages/nc-gui-v2/composables/useProject.ts +++ b/packages/nc-gui-v2/composables/useProject.ts @@ -88,6 +88,14 @@ export function useProject(projectId?: MaybeRef) { await $api.project.update(_projectId, data) } + function getProjectMeta() { + try { + return typeof project.value.meta === 'string' ? JSON.parse(project.value.meta) : project.value.meta + } catch (e) { + return {} + } + } + return { project, tables, @@ -102,5 +110,6 @@ export function useProject(projectId?: MaybeRef) { isSharedBase, loadProjectMetaInfo, projectMetaInfo, + getProjectMeta, } } diff --git a/packages/nc-gui-v2/composables/useTheme/index.ts b/packages/nc-gui-v2/composables/useTheme/index.ts index ded242762c..1090cb8e20 100644 --- a/packages/nc-gui-v2/composables/useTheme/index.ts +++ b/packages/nc-gui-v2/composables/useTheme/index.ts @@ -1,7 +1,6 @@ import { ConfigProvider } from 'ant-design-vue' import type { Theme as AntTheme } from 'ant-design-vue/es/config-provider' -import { useStorage } from '@vueuse/core' -import { NOCO, hexToRGB, themeV2Colors, useCssVar, useInjectionState } from '#imports' +import { hexToRGB, themeV2Colors, useCssVar, useInjectionState, useProject } from '#imports' interface ThemeConfig extends AntTheme { primaryColor: string @@ -12,17 +11,40 @@ const [setup, use] = useInjectionState((config?: Partial) => { const primaryColor = useCssVar('--color-primary', typeof document !== 'undefined' ? document.documentElement : null) const accentColor = useCssVar('--color-accent', typeof document !== 'undefined' ? document.documentElement : null) - /** current theme config */ - const currentTheme = useStorage( - `${NOCO}db-theme`, - { + const { project, getProjectMeta, updateProject } = useProject() + + const route = useRoute() + + // set theme based on active project + watch(project, () => { + setTheme({ primaryColor: themeV2Colors['royal-blue'].DEFAULT, accentColor: themeV2Colors.pink['500'], + ...getProjectMeta()?.theme, + }) + }) + + // set default theme for routes out of project + watch( + () => route, + (v) => { + if (!v.params?.projectId) { + setTheme({ + primaryColor: themeV2Colors['royal-blue'].DEFAULT, + accentColor: themeV2Colors.pink['500'], + }) + } }, - localStorage, - { mergeDefaults: true }, + { deep: true }, ) + /** current theme config */ + const currentTheme = ref({ + primaryColor: themeV2Colors['royal-blue'].DEFAULT, + accentColor: themeV2Colors.pink['500'], + ...getProjectMeta()?.theme, + }) + /** set initial config */ setTheme(config ?? currentTheme.value) @@ -39,9 +61,23 @@ const [setup, use] = useInjectionState((config?: Partial) => { }) } + async function saveTheme(theme: Partial) { + const meta = getProjectMeta() + await updateProject({ + meta: JSON.stringify({ + ...meta, + theme: { + ...theme, + }, + }), + }) + setTheme(theme) + } + return { theme: currentTheme, setTheme, + saveTheme, } }, 'theme') diff --git a/packages/nc-gui-v2/pages/[projectType]/[projectId]/index.vue b/packages/nc-gui-v2/pages/[projectType]/[projectId]/index.vue index e6d10d35bf..56f7c5d04e 100644 --- a/packages/nc-gui-v2/pages/[projectType]/[projectId]/index.vue +++ b/packages/nc-gui-v2/pages/[projectType]/[projectId]/index.vue @@ -59,11 +59,11 @@ let pickerActive = $ref(false) const email = computed(() => user.value?.email ?? '---') -const { setTheme, theme } = useTheme() +const { saveTheme, theme } = useTheme() watch(pickedColor, (nextColor) => { if (pickerActive && nextColor.hex) { - setTheme({ + saveTheme({ primaryColor: pickerActive === 'primary' ? nextColor.hex : theme.value.primaryColor, accentColor: pickerActive === 'accent' ? nextColor.hex : theme.value.accentColor, }) @@ -348,7 +348,7 @@ const onMenuClose = (visible: boolean) => { - +