Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(projects): multi language buttons support hiding. #677

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/layouts/modules/global-header/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ const { isFullscreen, toggle } = useFullscreen();
<div class="h-full flex-y-center justify-end">
<GlobalSearch />
<FullScreen v-if="!appStore.isMobile" :full="isFullscreen" @click="toggle" />
<LangSwitch :lang="appStore.locale" :lang-options="appStore.localeOptions" @change-lang="appStore.changeLocale" />
<LangSwitch
v-if="themeStore.header.multilingual.visible"
:lang="appStore.locale"
:lang-options="appStore.localeOptions"
@change-lang="appStore.changeLocale"
/>
<ThemeSchemaSwitch
:theme-schema="themeStore.themeScheme"
:is-dark="themeStore.darkMode"
Expand Down
3 changes: 3 additions & 0 deletions src/layouts/modules/theme-drawer/modules/page-fun.vue
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ const isWrapperScrollMode = computed(() => themeStore.layout.scrollMode === 'wra
placeholder="SoybeanAdmin"
/>
</SettingItem>
<SettingItem key="9" :label="$t('theme.header.multilingual.visible')">
<NSwitch v-model:value="themeStore.header.multilingual.visible" />
</SettingItem>
</TransitionGroup>
</template>

Expand Down
3 changes: 3 additions & 0 deletions src/locales/langs/en-us.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ const local: App.I18n.Schema = {
breadcrumb: {
visible: 'Breadcrumb Visible',
showIcon: 'Breadcrumb Icon Visible'
},
multilingual: {
visible: 'Display multilingual button'
}
},
tab: {
Expand Down
3 changes: 3 additions & 0 deletions src/locales/langs/zh-cn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ const local: App.I18n.Schema = {
breadcrumb: {
visible: '显示面包屑',
showIcon: '显示面包屑图标'
},
multilingual: {
visible: '显示多语言按钮'
}
},
tab: {
Expand Down
12 changes: 8 additions & 4 deletions src/store/modules/theme/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,34 @@ import type { GlobalThemeOverrides } from 'naive-ui';
import { addColorAlpha, getColorPalette, getPaletteColorByNumber, getRgb } from '@sa/color';
import { overrideThemeSettings, themeSettings } from '@/theme/settings';
import { themeVars } from '@/theme/vars';
import { toggleHtmlClass } from '@/utils/common';
import { toggleHtmlClass, updateBase } from '@/utils/common';
import { localStg } from '@/utils/storage';

const DARK_CLASS = 'dark';

/** Init theme settings */
export function initThemeSettings() {
const isProd = import.meta.env.PROD;
// const isProd = import.meta.env.PROD;
const isProd = true;

// if it is development mode, the theme settings will not be cached, by update `themeSettings` in `src/theme/settings.ts` to update theme settings
if (!isProd) return themeSettings;

const localSettings = localStg.get('themeSettings') || themeSettings;

// if it is production mode, the theme settings will be cached in localStorage
// if want to update theme settings when publish new version, please update `overrideThemeSettings` in `src/theme/settings.ts`

const settings = localStg.get('themeSettings') || themeSettings;
const settings = updateBase(themeSettings, localSettings);

const isOverride = localStg.get('overrideThemeFlag') === BUILD_TIME;

if (!isOverride) {
Object.assign(settings, overrideThemeSettings);
localStg.set('overrideThemeFlag', BUILD_TIME);
}

localStg.set('themeSettings', settings);

return settings;
}

Expand Down
3 changes: 3 additions & 0 deletions src/theme/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ export const themeSettings: App.Theme.ThemeSetting = {
breadcrumb: {
visible: true,
showIcon: true
},
multilingual: {
visible: true
}
},
tab: {
Expand Down
10 changes: 9 additions & 1 deletion src/typings/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ declare namespace App {
/** Whether to show the breadcrumb icon */
showIcon: boolean;
};
/** Multilingual */
multilingual: {
/** Whether to show the multilingual */
visible: boolean;
};
};
/** Tab */
tab: {
Expand Down Expand Up @@ -98,7 +103,7 @@ declare namespace App {
right: boolean;
};
/** Watermark */
watermark?: {
watermark: {
/** Whether to show the watermark */
visible: boolean;
/** Watermark text */
Expand Down Expand Up @@ -363,6 +368,9 @@ declare namespace App {
visible: string;
showIcon: string;
};
multilingual: {
visible: string;
};
};
tab: {
visible: string;
Expand Down
69 changes: 69 additions & 0 deletions src/utils/common.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isObject } from 'lodash-es';
import { $t } from '@/locales';

/**
Expand Down Expand Up @@ -56,3 +57,71 @@ export function toggleHtmlClass(className: string) {
remove
};
}

type AnyObject = { [key: string]: any };
/** Auxiliary type: recursively make all attributes optional */
type PartialDeep<T> = {
[P in keyof T]?: T[P] extends AnyObject ? PartialDeep<T[P]> : T[P];
};
/**
* Deeply update base objects without adding keys that do not exist in the base.
*
* @example
* const base = {
* a: 1,
* b: {
* c: 2,
* d: 3,
* },
* e: [1, 2, 3],
* };
*
* const updates = {
* a: 10,
* b: {
* c: 20,
* e: 30, // Does not exist in base. b, will be ignored
* },
* f: 40, // Does not exist in base. b, will be ignored
* e: [4, 5], // Array will be replaced
* };
*
* const updatedBase = updateBase(base, updates);
*
* console.log(updatedBase);
* output:
* {
* a: 10,
* b: {
* c: 20,
* d: 3
* },
* e: [4, 5]
* }
*
* @param base - Base object
* @param updates - Update object
* @returns New object, a deep copy of the base object with updates applied
*/
export function updateBase<T extends AnyObject>(base: T, updates: PartialDeep<T>): T {
// Deep copy the base object to avoid modifying the original object
const result: AnyObject = Array.isArray(base) ? [...base] : { ...base };

for (const key in updates) {
if (Object.hasOwn(base, key)) {
const baseValue = base[key];
const updateValue = updates[key];

if (isObject(baseValue) && isObject(updateValue)) {
// Recursively update nested objects
result[key] = updateBase(baseValue, updateValue);
} else {
// Directly assign updates
result[key] = updateValue;
}
}
// If the key in updates does not exist in base, ignore it
}

return result as T;
}
Loading