fix(theme-editor): "No permission" error when updating default theme of system (#3171)
* fix: fix T-2703 * fix: bug * fix: migration * chore: switch type to radio * fix: collection.sync --------- Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
parent
7166409c75
commit
8c1738db83
@ -28,6 +28,7 @@
|
|||||||
"@nocobase/database": "0.x",
|
"@nocobase/database": "0.x",
|
||||||
"@nocobase/server": "0.x",
|
"@nocobase/server": "0.x",
|
||||||
"@nocobase/test": "0.x",
|
"@nocobase/test": "0.x",
|
||||||
"@nocobase/utils": "0.x"
|
"@nocobase/utils": "0.x",
|
||||||
|
"@nocobase/actions": "0.x"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,28 @@
|
|||||||
import { defaultTheme, useAPIClient, useCurrentUserContext, useGlobalTheme, useSystemSettings } from '@nocobase/client';
|
import { defaultTheme as presetTheme, useAPIClient, useCurrentUserContext, useGlobalTheme } from '@nocobase/client';
|
||||||
import { error } from '@nocobase/utils/client';
|
import { error } from '@nocobase/utils/client';
|
||||||
import { Spin } from 'antd';
|
import { Spin } from 'antd';
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useMemo, useRef } from 'react';
|
||||||
import { changeAlgorithmFromFunctionToString } from '../utils/changeAlgorithmFromFunctionToString';
|
import { changeAlgorithmFromFunctionToString } from '../utils/changeAlgorithmFromFunctionToString';
|
||||||
import { changeAlgorithmFromStringToFunction } from '../utils/changeAlgorithmFromStringToFunction';
|
import { changeAlgorithmFromStringToFunction } from '../utils/changeAlgorithmFromStringToFunction';
|
||||||
import { useThemeListContext } from './ThemeListProvider';
|
import { useThemeListContext } from './ThemeListProvider';
|
||||||
|
|
||||||
const CurrentThemeIdContext = React.createContext<number>(null);
|
const ThemeIdContext = React.createContext<{
|
||||||
|
currentThemeId: number;
|
||||||
|
defaultThemeId: number;
|
||||||
|
}>({} as any);
|
||||||
|
|
||||||
export const useCurrentThemeId = () => {
|
export const useThemeId = () => {
|
||||||
return React.useContext(CurrentThemeIdContext);
|
return React.useContext(ThemeIdContext);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于在页面加载时初始化主题
|
* 用于在页面加载时初始化主题
|
||||||
*/
|
*/
|
||||||
const InitializeTheme: React.FC = ({ children }) => {
|
const InitializeTheme: React.FC = ({ children }) => {
|
||||||
const systemSettings = useSystemSettings();
|
|
||||||
const currentUser = useCurrentUserContext();
|
const currentUser = useCurrentUserContext();
|
||||||
const { setTheme } = useGlobalTheme();
|
const { setTheme } = useGlobalTheme();
|
||||||
const { run, data, loading } = useThemeListContext();
|
const { run, data, loading } = useThemeListContext();
|
||||||
|
const defaultTheme = useMemo(() => data?.find((item) => item.default), [data]);
|
||||||
const themeId = useRef<number>(null);
|
const themeId = useRef<number>(null);
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
|
|
||||||
@ -39,40 +42,44 @@ const InitializeTheme: React.FC = ({ children }) => {
|
|||||||
return run();
|
return run();
|
||||||
}
|
}
|
||||||
|
|
||||||
themeId.current =
|
const currentThemeId = currentUser?.data?.data?.systemSettings?.themeId;
|
||||||
// 这里不要使用 `===` 操作符
|
let theme: any;
|
||||||
currentUser?.data?.data?.systemSettings?.themeId == null
|
if (currentThemeId !== null && currentThemeId !== undefined) {
|
||||||
? systemSettings?.data?.data?.options?.themeId
|
// Use the theme from the current user's system settings
|
||||||
: currentUser?.data?.data?.systemSettings?.themeId;
|
theme = data.find((item) => item.id === currentThemeId);
|
||||||
|
}
|
||||||
// 这里不要使用 `!==` 操作符
|
if (!theme) {
|
||||||
if (themeId.current != null) {
|
// Use the default theme if there is not an available theme in user's system settings
|
||||||
const theme = data?.find((item) => item.id === themeId.current);
|
theme = defaultTheme;
|
||||||
|
}
|
||||||
if (theme) {
|
if (theme) {
|
||||||
|
themeId.current = theme.id;
|
||||||
setTheme(theme.config);
|
setTheme(theme.config);
|
||||||
api.auth.setOption(
|
api.auth.setOption(
|
||||||
'theme',
|
'theme',
|
||||||
JSON.stringify(Object.assign({ ...theme }, { config: changeAlgorithmFromFunctionToString(theme.config) })),
|
JSON.stringify(Object.assign({ ...theme }, { config: changeAlgorithmFromFunctionToString(theme.config) })),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
setTheme(defaultTheme);
|
// Use the preset theme if the theme is not found
|
||||||
|
setTheme(presetTheme);
|
||||||
api.auth.setOption('theme', null);
|
api.auth.setOption('theme', null);
|
||||||
}
|
}
|
||||||
}, [
|
}, [api.auth, currentUser?.data?.data?.systemSettings?.themeId, data, run, setTheme, defaultTheme]);
|
||||||
api.auth,
|
|
||||||
currentUser?.data?.data?.systemSettings?.themeId,
|
|
||||||
data,
|
|
||||||
run,
|
|
||||||
setTheme,
|
|
||||||
systemSettings?.data?.data?.options?.themeId,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (loading && !data) {
|
if (loading && !data) {
|
||||||
return <Spin />;
|
return <Spin />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <CurrentThemeIdContext.Provider value={themeId.current}>{children}</CurrentThemeIdContext.Provider>;
|
return (
|
||||||
|
<ThemeIdContext.Provider
|
||||||
|
value={{
|
||||||
|
currentThemeId: themeId.current,
|
||||||
|
defaultThemeId: defaultTheme?.id,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</ThemeIdContext.Provider>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
InitializeTheme.displayName = 'InitializeTheme';
|
InitializeTheme.displayName = 'InitializeTheme';
|
||||||
|
@ -1,12 +1,5 @@
|
|||||||
import { DeleteOutlined, EditOutlined, EllipsisOutlined } from '@ant-design/icons';
|
import { DeleteOutlined, EditOutlined, EllipsisOutlined } from '@ant-design/icons';
|
||||||
import {
|
import { compatOldTheme, useAPIClient, useCurrentUserContext, useGlobalTheme, useToken } from '@nocobase/client';
|
||||||
compatOldTheme,
|
|
||||||
useAPIClient,
|
|
||||||
useCurrentUserContext,
|
|
||||||
useGlobalTheme,
|
|
||||||
useSystemSettings,
|
|
||||||
useToken,
|
|
||||||
} from '@nocobase/client';
|
|
||||||
import { error } from '@nocobase/utils/client';
|
import { error } from '@nocobase/utils/client';
|
||||||
import { App, Card, ConfigProvider, Dropdown, Space, Switch, Tag, message } from 'antd';
|
import { App, Card, ConfigProvider, Dropdown, Space, Switch, Tag, message } from 'antd';
|
||||||
import React, { useCallback, useMemo } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
@ -14,7 +7,7 @@ import { ThemeConfig, ThemeItem } from '../../types';
|
|||||||
import { Primary } from '../antd-token-previewer';
|
import { Primary } from '../antd-token-previewer';
|
||||||
import { useUpdateThemeSettings } from '../hooks/useUpdateThemeSettings';
|
import { useUpdateThemeSettings } from '../hooks/useUpdateThemeSettings';
|
||||||
import { useTranslation } from '../locale';
|
import { useTranslation } from '../locale';
|
||||||
import { useCurrentThemeId } from './InitializeTheme';
|
import { useThemeId } from './InitializeTheme';
|
||||||
import { useThemeEditorContext } from './ThemeEditorProvider';
|
import { useThemeEditorContext } from './ThemeEditorProvider';
|
||||||
|
|
||||||
enum HandleTypes {
|
enum HandleTypes {
|
||||||
@ -69,17 +62,16 @@ const ThemeCard = (props: Props) => {
|
|||||||
} = useGlobalTheme();
|
} = useGlobalTheme();
|
||||||
const { setOpen } = useThemeEditorContext();
|
const { setOpen } = useThemeEditorContext();
|
||||||
const currentUser = useCurrentUserContext();
|
const currentUser = useCurrentUserContext();
|
||||||
const systemSettings = useSystemSettings();
|
|
||||||
const { item, style = {}, onChange } = props;
|
const { item, style = {}, onChange } = props;
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
const { updateUserThemeSettings, updateSystemThemeSettings } = useUpdateThemeSettings();
|
const { updateUserThemeSettings } = useUpdateThemeSettings();
|
||||||
const { modal } = App.useApp();
|
const { modal } = App.useApp();
|
||||||
const [loading, setLoading] = React.useState(false);
|
const [loading, setLoading] = React.useState(false);
|
||||||
const currentThemeId = useCurrentThemeId();
|
const { currentThemeId, defaultThemeId } = useThemeId();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { token } = useToken();
|
const { token } = useToken();
|
||||||
|
|
||||||
const isDefault = item.id === systemSettings?.data?.data?.options?.themeId;
|
const isDefault = item.id === defaultThemeId;
|
||||||
|
|
||||||
const handleDelete = useCallback(() => {
|
const handleDelete = useCallback(() => {
|
||||||
if (isDefault) {
|
if (isDefault) {
|
||||||
@ -97,9 +89,6 @@ const ThemeCard = (props: Props) => {
|
|||||||
if (item.id === currentUser?.data?.data?.systemSettings?.themeId) {
|
if (item.id === currentUser?.data?.data?.systemSettings?.themeId) {
|
||||||
updateUserThemeSettings(null);
|
updateUserThemeSettings(null);
|
||||||
}
|
}
|
||||||
if (item.id === systemSettings?.data?.data?.options?.themeId) {
|
|
||||||
updateSystemThemeSettings(null);
|
|
||||||
}
|
|
||||||
message.success(t('Deleted successfully'));
|
message.success(t('Deleted successfully'));
|
||||||
onChange?.({ type: HandleTypes.delete, item });
|
onChange?.({ type: HandleTypes.delete, item });
|
||||||
},
|
},
|
||||||
@ -111,9 +100,7 @@ const ThemeCard = (props: Props) => {
|
|||||||
item,
|
item,
|
||||||
modal,
|
modal,
|
||||||
onChange,
|
onChange,
|
||||||
systemSettings?.data?.data?.options?.themeId,
|
|
||||||
t,
|
t,
|
||||||
updateSystemThemeSettings,
|
|
||||||
updateUserThemeSettings,
|
updateUserThemeSettings,
|
||||||
]);
|
]);
|
||||||
const handleSwitchOptional = useCallback(
|
const handleSwitchOptional = useCallback(
|
||||||
@ -127,12 +114,11 @@ const ThemeCard = (props: Props) => {
|
|||||||
method: 'post',
|
method: 'post',
|
||||||
data: {
|
data: {
|
||||||
optional: checked,
|
optional: checked,
|
||||||
|
default: false,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
// 如果用户把当前设置的主题设置为不可选,那么就需要把当前设置的主题设置为默认主题
|
// 如果用户把当前设置的主题设置为不可选,那么就需要把当前设置的主题设置为默认主题
|
||||||
item.id === currentThemeId && updateUserThemeSettings(null),
|
item.id === currentUser?.data?.data?.systemSettings?.themeId && updateUserThemeSettings(null),
|
||||||
// 系统默认主题应该始终是可选的,所以当用户设置为不可选时,应该也同时把系统默认主题设置为空
|
|
||||||
item.id === systemSettings?.data?.data?.options?.themeId && updateSystemThemeSettings(null),
|
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
await api.request({
|
await api.request({
|
||||||
@ -150,16 +136,7 @@ const ThemeCard = (props: Props) => {
|
|||||||
message.success(t('Updated successfully'));
|
message.success(t('Updated successfully'));
|
||||||
onChange?.({ type: HandleTypes.optional, item });
|
onChange?.({ type: HandleTypes.optional, item });
|
||||||
},
|
},
|
||||||
[
|
[api, currentUser?.data?.data?.systemSettings?.themeId, item, onChange, t, updateUserThemeSettings],
|
||||||
api,
|
|
||||||
currentThemeId,
|
|
||||||
item,
|
|
||||||
onChange,
|
|
||||||
systemSettings?.data?.data?.options?.themeId,
|
|
||||||
t,
|
|
||||||
updateSystemThemeSettings,
|
|
||||||
updateUserThemeSettings,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
const handleSwitchDefault = useCallback(
|
const handleSwitchDefault = useCallback(
|
||||||
async (checked: boolean) => {
|
async (checked: boolean) => {
|
||||||
@ -167,18 +144,24 @@ const ThemeCard = (props: Props) => {
|
|||||||
try {
|
try {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
updateSystemThemeSettings(item.id),
|
|
||||||
// 用户在设置该主题为默认主题时,肯定也希望该主题可被用户选择
|
// 用户在设置该主题为默认主题时,肯定也希望该主题可被用户选择
|
||||||
api.request({
|
api.request({
|
||||||
url: `themeConfig:update/${item.id}`,
|
url: `themeConfig:update/${item.id}`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: {
|
data: {
|
||||||
optional: true,
|
optional: true,
|
||||||
|
default: true,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
await updateSystemThemeSettings(null);
|
await api.request({
|
||||||
|
url: `themeConfig:update/${item.id}`,
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
error(err);
|
error(err);
|
||||||
@ -187,7 +170,7 @@ const ThemeCard = (props: Props) => {
|
|||||||
message.success(t('Updated successfully'));
|
message.success(t('Updated successfully'));
|
||||||
onChange?.({ type: HandleTypes.optional, item });
|
onChange?.({ type: HandleTypes.optional, item });
|
||||||
},
|
},
|
||||||
[api, item, onChange, t, updateSystemThemeSettings],
|
[api, item, onChange, t],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleEdit = useCallback(() => {
|
const handleEdit = useCallback(() => {
|
||||||
@ -269,13 +252,13 @@ const ThemeCard = (props: Props) => {
|
|||||||
}, [handleDelete, handleEdit, isDefault, menu, token.colorTextDisabled]);
|
}, [handleDelete, handleEdit, isDefault, menu, token.colorTextDisabled]);
|
||||||
|
|
||||||
const extra = useMemo(() => {
|
const extra = useMemo(() => {
|
||||||
if (item.id !== systemSettings?.data?.data?.options?.themeId && !item.optional) {
|
if (item.id !== defaultThemeId && !item.optional) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const text =
|
const text =
|
||||||
item.id === currentThemeId
|
item.id === currentThemeId
|
||||||
? t('Current')
|
? t('Current')
|
||||||
: item.id === systemSettings?.data?.data?.options?.themeId
|
: item.id === defaultThemeId
|
||||||
? t('Default')
|
? t('Default')
|
||||||
: item.optional
|
: item.optional
|
||||||
? t('Optional')
|
? t('Optional')
|
||||||
@ -283,7 +266,7 @@ const ThemeCard = (props: Props) => {
|
|||||||
const color =
|
const color =
|
||||||
item.id === currentThemeId
|
item.id === currentThemeId
|
||||||
? 'processing'
|
? 'processing'
|
||||||
: item.id === systemSettings?.data?.data?.options?.themeId
|
: item.id === defaultThemeId
|
||||||
? 'default'
|
? 'default'
|
||||||
: item.optional
|
: item.optional
|
||||||
? 'success'
|
? 'success'
|
||||||
@ -294,7 +277,7 @@ const ThemeCard = (props: Props) => {
|
|||||||
{text}
|
{text}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
}, [currentThemeId, item.id, item.optional, systemSettings?.data?.data?.options?.themeId, t]);
|
}, [currentThemeId, defaultThemeId, item.id, item.optional, t]);
|
||||||
|
|
||||||
const cardStyle = useMemo(() => {
|
const cardStyle = useMemo(() => {
|
||||||
if (getCurrentEditingTheme()?.id === item.id) {
|
if (getCurrentEditingTheme()?.id === item.id) {
|
||||||
|
@ -2,7 +2,7 @@ import { SelectWithTitle, useAPIClient, useCurrentUserContext, useSystemSettings
|
|||||||
import { error } from '@nocobase/utils/client';
|
import { error } from '@nocobase/utils/client';
|
||||||
import { MenuProps } from 'antd';
|
import { MenuProps } from 'antd';
|
||||||
import React, { useEffect, useMemo } from 'react';
|
import React, { useEffect, useMemo } from 'react';
|
||||||
import { useCurrentThemeId } from '../components/InitializeTheme';
|
import { useThemeId } from '../components/InitializeTheme';
|
||||||
import { useThemeListContext } from '../components/ThemeListProvider';
|
import { useThemeListContext } from '../components/ThemeListProvider';
|
||||||
import { useTranslation } from '../locale';
|
import { useTranslation } from '../locale';
|
||||||
import { useUpdateThemeSettings } from './useUpdateThemeSettings';
|
import { useUpdateThemeSettings } from './useUpdateThemeSettings';
|
||||||
@ -21,11 +21,9 @@ function Label() {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const currentUser = useCurrentUserContext();
|
const currentUser = useCurrentUserContext();
|
||||||
const systemSettings = useSystemSettings();
|
const systemSettings = useSystemSettings();
|
||||||
const { run, error: err, data, refresh } = useThemeListContext();
|
const { run, error: err, data } = useThemeListContext();
|
||||||
const { updateUserThemeSettings, updateSystemThemeSettings } = useUpdateThemeSettings();
|
const { updateUserThemeSettings } = useUpdateThemeSettings();
|
||||||
const currentThemeId = useCurrentThemeId();
|
const { currentThemeId } = useThemeId();
|
||||||
const themeId = useCurrentThemeId();
|
|
||||||
const api = useAPIClient();
|
|
||||||
|
|
||||||
const options = useMemo(() => {
|
const options = useMemo(() => {
|
||||||
return data
|
return data
|
||||||
@ -44,25 +42,6 @@ function Label() {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const init = async () => {
|
|
||||||
// 当 themeId 为空时表示插件是第一次被启用
|
|
||||||
if (themeId == null && data) {
|
|
||||||
const firstTheme = data[0];
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 避免并发请求,在本地存储中容易出问题
|
|
||||||
await updateSystemThemeSettings(firstTheme.id);
|
|
||||||
await updateUserThemeSettings(firstTheme.id);
|
|
||||||
} catch (err) {
|
|
||||||
error(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
init();
|
|
||||||
}, [themeId, updateSystemThemeSettings, updateUserThemeSettings, data, api, refresh]);
|
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
error(err);
|
error(err);
|
||||||
return null;
|
return null;
|
||||||
|
@ -37,33 +37,5 @@ export function useUpdateThemeSettings() {
|
|||||||
[api, currentUser],
|
[api, currentUser],
|
||||||
);
|
);
|
||||||
|
|
||||||
const updateSystemThemeSettings = useCallback(
|
return { updateUserThemeSettings };
|
||||||
async (themeId: number | null) => {
|
|
||||||
if (themeId === systemSettings.data.data.options?.themeId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await api.request({
|
|
||||||
url: 'systemSettings:update/1',
|
|
||||||
method: 'post',
|
|
||||||
data: {
|
|
||||||
options: {
|
|
||||||
...(systemSettings.data.data.options || {}),
|
|
||||||
themeId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
systemSettings.mutate({
|
|
||||||
data: {
|
|
||||||
...systemSettings.data.data,
|
|
||||||
options: {
|
|
||||||
...(systemSettings.data.data.options || {}),
|
|
||||||
themeId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[api, systemSettings],
|
|
||||||
);
|
|
||||||
|
|
||||||
return { updateUserThemeSettings, updateSystemThemeSettings };
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ export const defaultTheme: Omit<ThemeItem, 'id'> = {
|
|||||||
optional: true,
|
optional: true,
|
||||||
isBuiltIn: true,
|
isBuiltIn: true,
|
||||||
uid: 'default',
|
uid: 'default',
|
||||||
|
default: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const dark: Omit<ThemeItem, 'id'> = {
|
export const dark: Omit<ThemeItem, 'id'> = {
|
||||||
@ -19,6 +20,7 @@ export const dark: Omit<ThemeItem, 'id'> = {
|
|||||||
optional: true,
|
optional: true,
|
||||||
isBuiltIn: true,
|
isBuiltIn: true,
|
||||||
uid: 'dark',
|
uid: 'dark',
|
||||||
|
default: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const compact: Omit<ThemeItem, 'id'> = {
|
export const compact: Omit<ThemeItem, 'id'> = {
|
||||||
@ -30,6 +32,7 @@ export const compact: Omit<ThemeItem, 'id'> = {
|
|||||||
optional: true,
|
optional: true,
|
||||||
isBuiltIn: true,
|
isBuiltIn: true,
|
||||||
uid: 'compact',
|
uid: 'compact',
|
||||||
|
default: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 同时包含 `紧凑` 和 `暗黑` 两种模式 */
|
/** 同时包含 `紧凑` 和 `暗黑` 两种模式 */
|
||||||
@ -42,4 +45,5 @@ export const compactDark: Omit<ThemeItem, 'id'> = {
|
|||||||
optional: true,
|
optional: true,
|
||||||
isBuiltIn: true,
|
isBuiltIn: true,
|
||||||
uid: 'compact_dark',
|
uid: 'compact_dark',
|
||||||
|
default: false,
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
import { Migration } from '@nocobase/server';
|
||||||
|
|
||||||
|
export default class ThemeEditorMigration extends Migration {
|
||||||
|
async up() {
|
||||||
|
const result = await this.app.version.satisfies('<0.17.0-alpha.5');
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const repository = this.db.getRepository('themeConfig');
|
||||||
|
if (!repository) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await repository.collection.sync();
|
||||||
|
|
||||||
|
const systemSettings = await this.db.getRepository('systemSettings').findOne();
|
||||||
|
const defaultThemeId = systemSettings.options?.themeId;
|
||||||
|
if (!defaultThemeId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.db.sequelize.transaction(async (t) => {
|
||||||
|
await repository.update({
|
||||||
|
values: {
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
filter: {
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
transaction: t,
|
||||||
|
});
|
||||||
|
await repository.update({
|
||||||
|
values: {
|
||||||
|
default: true,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
filterByTk: defaultThemeId,
|
||||||
|
transaction: t,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async down() {}
|
||||||
|
}
|
@ -7,15 +7,7 @@ export class ThemeEditorPlugin extends Plugin {
|
|||||||
|
|
||||||
afterAdd() {}
|
afterAdd() {}
|
||||||
|
|
||||||
async beforeLoad() {
|
async beforeLoad() {}
|
||||||
this.db.addMigrations({
|
|
||||||
namespace: 'theme-editor',
|
|
||||||
directory: resolve(__dirname, './migrations'),
|
|
||||||
context: {
|
|
||||||
plugin: this,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
this.db.collection({
|
this.db.collection({
|
||||||
@ -39,8 +31,21 @@ export class ThemeEditorPlugin extends Plugin {
|
|||||||
type: 'uid',
|
type: 'uid',
|
||||||
name: 'uid',
|
name: 'uid',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'radio',
|
||||||
|
name: 'default',
|
||||||
|
defaultValue: false,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
this.db.addMigrations({
|
||||||
|
namespace: 'theme-editor',
|
||||||
|
directory: resolve(__dirname, './migrations'),
|
||||||
|
context: {
|
||||||
|
plugin: this,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
this.app.acl.allow('themeConfig', 'list', 'public');
|
this.app.acl.allow('themeConfig', 'list', 'public');
|
||||||
this.app.acl.registerSnippet({
|
this.app.acl.registerSnippet({
|
||||||
name: `pm.${this.name}.themeConfig`,
|
name: `pm.${this.name}.themeConfig`,
|
||||||
|
@ -10,6 +10,7 @@ export interface ThemeItem {
|
|||||||
optional: boolean;
|
optional: boolean;
|
||||||
isBuiltIn?: boolean;
|
isBuiltIn?: boolean;
|
||||||
uid?: string;
|
uid?: string;
|
||||||
|
default?: boolean; // 当前系统默认主题
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Theme = {
|
export type Theme = {
|
||||||
|
Loading…
Reference in New Issue
Block a user