diff --git a/packages/plugins/@hera/plugin-core/src/client/features/assistant/Assistant.provider.tsx b/packages/plugins/@hera/plugin-core/src/client/features/assistant/Assistant.provider.tsx
new file mode 100644
index 000000000..c56863d75
--- /dev/null
+++ b/packages/plugins/@hera/plugin-core/src/client/features/assistant/Assistant.provider.tsx
@@ -0,0 +1,17 @@
+import { CalculatorOutlined, CommentOutlined, HighlightOutlined, ToolOutlined } from '@ant-design/icons';
+import { useDesignable } from '@nocobase/client';
+import { FloatButton } from 'antd';
+import React from 'react';
+export const AssistantProvider = ({ children }) => {
+ const { designable, setDesignable } = useDesignable();
+ return (
+ <>
+ {children}
+ }>
+ } onClick={() => setDesignable(!designable)} />
+ } />
+ } />
+
+ >
+ );
+};
diff --git a/packages/plugins/@hera/plugin-core/src/client/features/assistant/index.ts b/packages/plugins/@hera/plugin-core/src/client/features/assistant/index.ts
new file mode 100644
index 000000000..2947a9a86
--- /dev/null
+++ b/packages/plugins/@hera/plugin-core/src/client/features/assistant/index.ts
@@ -0,0 +1,8 @@
+import { Plugin } from '@nocobase/client';
+import { AssistantProvider } from './Assistant.provider';
+
+export class PluginAssistant extends Plugin {
+ async load() {
+ this.app.use(AssistantProvider);
+ }
+}
diff --git a/packages/plugins/@hera/plugin-core/src/client/features/hera-version/HeraVersion.provider.tsx b/packages/plugins/@hera/plugin-core/src/client/features/hera-version/HeraVersion.provider.tsx
new file mode 100644
index 000000000..1af974969
--- /dev/null
+++ b/packages/plugins/@hera/plugin-core/src/client/features/hera-version/HeraVersion.provider.tsx
@@ -0,0 +1,24 @@
+import React, { useEffect } from 'react';
+import { useCurrentUserSettingsMenu } from '@nocobase/client';
+import { usePluginVersion } from '../../hooks/usePluginVersion';
+import { useTabSettings } from '../page-style/useTabSettings';
+
+const useHeraVersion = () => {
+ const version = usePluginVersion();
+ return {
+ key: 'hera-version',
+ eventKey: 'hera-version',
+ label: 赫拉系统 - {version},
+ };
+};
+
+export const HeraVersionProvider = ({ children }) => {
+ const { addMenuItem } = useCurrentUserSettingsMenu();
+ const heraVersion = useHeraVersion();
+ const tabItem = useTabSettings();
+ useEffect(() => {
+ addMenuItem(heraVersion, { before: 'divider_1' });
+ }, [addMenuItem, tabItem, heraVersion]);
+
+ return <>{children}>;
+};
diff --git a/packages/plugins/@hera/plugin-core/src/client/features/hera-version/index.ts b/packages/plugins/@hera/plugin-core/src/client/features/hera-version/index.ts
new file mode 100644
index 000000000..8dc465589
--- /dev/null
+++ b/packages/plugins/@hera/plugin-core/src/client/features/hera-version/index.ts
@@ -0,0 +1,8 @@
+import { Plugin } from '@nocobase/client';
+import { HeraVersionProvider } from './HeraVersion.provider';
+
+export class PluginHeraVersion extends Plugin {
+ async load() {
+ this.app.use(HeraVersionProvider);
+ }
+}
diff --git a/packages/plugins/@hera/plugin-core/src/client/features/page-style/PageStyle.provider.tsx b/packages/plugins/@hera/plugin-core/src/client/features/page-style/PageStyle.provider.tsx
new file mode 100644
index 000000000..cbf0c10f4
--- /dev/null
+++ b/packages/plugins/@hera/plugin-core/src/client/features/page-style/PageStyle.provider.tsx
@@ -0,0 +1,32 @@
+import { useCurrentUserContext, useCurrentUserSettingsMenu } from '@nocobase/client';
+import React, { createContext, useEffect, useState } from 'react';
+import { useTabSettings } from './useTabSettings';
+import { TabsProps } from 'antd';
+
+export interface PageStyleContextValue {
+ style: string;
+ items: TabsProps['items'];
+ setItems: React.Dispatch>;
+}
+
+export const PageStyleContext = createContext>({
+ style: 'classical',
+});
+
+export const PageStyleProvider = ({ children }) => {
+ const currentUser = useCurrentUserContext();
+ const tabItem = useTabSettings();
+ const [items, setItems] = useState([]);
+ const { addMenuItem } = useCurrentUserSettingsMenu();
+ useEffect(() => {
+ addMenuItem(tabItem, { before: 'divider_3' });
+ }, [addMenuItem, tabItem]);
+
+ return (
+
+ {children}
+
+ );
+};
diff --git a/packages/plugins/@hera/plugin-core/src/client/features/page-style/PageTab.tsx b/packages/plugins/@hera/plugin-core/src/client/features/page-style/PageTab.tsx
new file mode 100644
index 000000000..5759f16ba
--- /dev/null
+++ b/packages/plugins/@hera/plugin-core/src/client/features/page-style/PageTab.tsx
@@ -0,0 +1,62 @@
+import { RemoteSchemaComponent, css, useDocumentTitle } from '@nocobase/client';
+import { Tabs } from 'antd';
+import React, { useContext, useEffect } from 'react';
+import { useNavigate, useParams } from 'react-router-dom';
+import { PageStyleContext } from './PageStyle.provider';
+
+export const PageTab = () => {
+ const params = useParams<{ name?: string }>();
+ const { title, setTitle } = useDocumentTitle();
+ const navigate = useNavigate();
+ const { items, setItems } = useContext(PageStyleContext);
+
+ useEffect(() => {
+ if (params.name && title) {
+ const targetItem = items.find((value) => value.key === params.name);
+ if (!targetItem) {
+ // 现有tab页数组里,不存在之前浏览的tab页面,添加新的tab页进数组
+ setItems([
+ ...items,
+ {
+ key: params.name,
+ label: title,
+ children: ,
+ },
+ ]);
+ } else {
+ // 如果存在之前浏览的tab页面,只用更新页面标题
+ setTitle(targetItem.label);
+ }
+ }
+ }, [params.name, title]);
+
+ const onEdit = (targetKey: React.MouseEvent | React.KeyboardEvent | string, action: 'add' | 'remove') => {
+ if (action === 'remove') {
+ setItems((items) => {
+ return items.filter((item) => item.key !== targetKey);
+ });
+ }
+ };
+ return (
+ {
+ navigate(`/admin/${key}`);
+ }}
+ activeKey={params.name}
+ />
+ );
+};
+
+export function MyRouteSchemaComponent({ name }: { name: string }) {
+ return ;
+}
diff --git a/packages/plugins/@hera/plugin-core/src/client/features/page-style/index.ts b/packages/plugins/@hera/plugin-core/src/client/features/page-style/index.ts
new file mode 100644
index 000000000..ca7b3ae80
--- /dev/null
+++ b/packages/plugins/@hera/plugin-core/src/client/features/page-style/index.ts
@@ -0,0 +1,8 @@
+import { Plugin } from '@nocobase/client';
+import { PageStyleProvider } from './PageStyle.provider';
+
+export class PluginPageStyle extends Plugin {
+ async load() {
+ this.app.use(PageStyleProvider);
+ }
+}
diff --git a/packages/plugins/@hera/plugin-core/src/client/features/page-style/usePageStyle.tsx b/packages/plugins/@hera/plugin-core/src/client/features/page-style/usePageStyle.tsx
new file mode 100644
index 000000000..f0a3f8a3a
--- /dev/null
+++ b/packages/plugins/@hera/plugin-core/src/client/features/page-style/usePageStyle.tsx
@@ -0,0 +1,6 @@
+import { useContext } from 'react';
+import { PageStyleContext } from './PageStyle.provider';
+
+export const usePageStyle = () => {
+ return useContext(PageStyleContext).style;
+};
diff --git a/packages/plugins/@hera/plugin-core/src/client/features/page-style/useTabSettings.tsx b/packages/plugins/@hera/plugin-core/src/client/features/page-style/useTabSettings.tsx
new file mode 100644
index 000000000..5fcfb4ea8
--- /dev/null
+++ b/packages/plugins/@hera/plugin-core/src/client/features/page-style/useTabSettings.tsx
@@ -0,0 +1,73 @@
+import React, { useCallback } from 'react';
+import { SelectWithTitle, useAPIClient, useCurrentUserContext } from '@nocobase/client';
+import { error } from '@nocobase/utils/client';
+import { useTranslation } from '../../locale';
+
+export const useTabSettings = () => {
+ return {
+ key: 'tab',
+ eventKey: 'tab',
+ label: ,
+ };
+};
+
+export function Label() {
+ const { t } = useTranslation();
+ const { updateUserPageStyle } = useUpdatePageStyleSettings();
+ const currentUser = useCurrentUserContext();
+
+ return (
+
+ );
+}
+
+export function useUpdatePageStyleSettings() {
+ const api = useAPIClient();
+ const currentUser = useCurrentUserContext();
+
+ const updateUserPageStyle = useCallback(
+ async (pageStyle: string | null) => {
+ if (pageStyle === currentUser.data.data.systemSettings?.pageStyle) {
+ return;
+ }
+ try {
+ await api.resource('users').updateProfile({
+ values: {
+ systemSettings: {
+ ...(currentUser.data.data.systemSettings || {}),
+ pageStyle,
+ },
+ },
+ });
+ currentUser.mutate({
+ data: {
+ ...currentUser.data.data,
+ systemSettings: {
+ ...(currentUser.data.data.systemSettings || {}),
+ pageStyle,
+ },
+ },
+ });
+ } catch (err) {
+ error(err);
+ }
+ },
+ [api, currentUser],
+ );
+
+ return { updateUserPageStyle };
+}
diff --git a/packages/plugins/@hera/plugin-core/src/client/index.tsx b/packages/plugins/@hera/plugin-core/src/client/index.tsx
index 387b972db..1f239670c 100644
--- a/packages/plugins/@hera/plugin-core/src/client/index.tsx
+++ b/packages/plugins/@hera/plugin-core/src/client/index.tsx
@@ -76,6 +76,9 @@ import {
import { SchemaSettingsSubmitDataType } from './schema-settings/SchemaSettingsSubmitDataType';
import { EmbedPlugin } from './features/embed';
import { DepartmentsPlugin } from './features/departments';
+import { PluginPageStyle } from './features/page-style';
+import { PluginHeraVersion } from './features/hera-version';
+import { PluginAssistant } from './features/assistant';
export { usePDFViewerRef } from './schema-initializer';
export * from './components/custom-components/custom-components';
@@ -86,6 +89,9 @@ export class PluginCoreClient extends Plugin {
await this.app.pm.add(GroupBlockPlugin);
await this.app.pm.add(EmbedPlugin);
await this.app.pm.add(DepartmentsPlugin);
+ await this.app.pm.add(PluginPageStyle);
+ await this.app.pm.add(PluginHeraVersion);
+ await this.app.pm.add(PluginAssistant);
}
async registerSettings() {
diff --git a/packages/plugins/@hera/plugin-core/src/client/pages/AdminLayout.tsx b/packages/plugins/@hera/plugin-core/src/client/pages/AdminLayout.tsx
index 2300e0b7a..18b73f651 100644
--- a/packages/plugins/@hera/plugin-core/src/client/pages/AdminLayout.tsx
+++ b/packages/plugins/@hera/plugin-core/src/client/pages/AdminLayout.tsx
@@ -1,7 +1,6 @@
import { css } from '@emotion/css';
import { useSessionStorageState } from 'ahooks';
-import { App, Layout, Spin, FloatButton } from 'antd';
-import { ToolOutlined, CommentOutlined, CalculatorOutlined, HighlightOutlined } from '@ant-design/icons';
+import { App, Layout } from 'antd';
import React, { createContext, useContext, useEffect, useMemo, useRef, useState } from 'react';
import { Link, Outlet, useMatch, useNavigate, useParams } from 'react-router-dom';
import {
@@ -16,27 +15,13 @@ import {
useRequest,
useSystemSettings,
useToken,
- useApp,
AdminProvider,
- RemoteSchemaComponent,
- useCurrentUserSettingsMenu,
- SelectWithTitle,
- useDesignable,
} from '@nocobase/client';
-import { Tabs } from 'antd';
-import type { TabsProps } from 'antd';
-import { usePluginVersion } from '../hooks/usePluginVersion';
import { OnlineUserDropdown } from '../components/system/OnlineUserProvider';
import { MobileLink } from '../components/system/MobileLink';
import { Notifications } from '../components/system/Notifications';
-import { useTranslation } from '../locale';
-
-export const useAppSpin = () => {
- const app = useApp();
- return {
- render: () => (app ? app?.renderComponent?.('AppSpin') : React.createElement(Spin)),
- };
-};
+import { usePageStyle } from '../features/page-style/usePageStyle';
+import { PageTab } from '../features/page-style/PageTab';
const filterByACL = (schema, options) => {
const { allowAll, allowMenuItemIds = [] } = options;
@@ -90,7 +75,6 @@ const MenuEditor = (props) => {
setCurrent(schema);
navigate(`/admin/${schema['x-uid']}`);
};
- const { render } = useAppSpin();
const adminSchemaUid = useAdminSchemaUid();
const { data, loading } = useRequest<{
data: any;
@@ -204,50 +188,13 @@ const MenuEditor = (props) => {
);
};
-export function MyRouteSchemaComponent({ name }: { name: string }) {
- return ;
-}
-
-export const InternalAdminLayout = (props: any) => {
- const app = useApp();
+export const InternalAdminLayout = () => {
const sideMenuRef = useRef();
const result = useSystemSettings();
const params = useParams<{ name?: string }>();
const { token } = useToken();
- const { render } = useAppSpin();
- const { title, setTitle } = useDocumentTitle();
- const navigate = useNavigate();
- const [items, setItems] = useState([]);
const pageStyle = usePageStyle();
- useEffect(() => {
- if (params.name && title && pageStyle === 'tab') {
- const targetItem = items.find((value) => value.key === params.name);
- if (!targetItem) {
- // 现有tab页数组里,不存在之前浏览的tab页面,添加新的tab页进数组
- setItems([
- ...items,
- {
- key: params.name,
- label: title,
- children: ,
- },
- ]);
- } else {
- // 如果存在之前浏览的tab页面,只用更新页面标题
- setTitle(targetItem.label);
- }
- }
- }, [params.name, title]);
-
- const onEdit = (targetKey: React.MouseEvent | React.KeyboardEvent | string, action: 'add' | 'remove') => {
- if (action === 'remove') {
- setItems((items) => {
- return items.filter((item) => item.key !== targetKey);
- });
- }
- };
-
return (
{
pointer-events: none;
`}
>
- <>
- {params.name && pageStyle === 'tab' ? (
- {
- navigate(`/admin/${key}`);
- }}
- activeKey={params.name}
- />
- ) : (
-
- )}
- >
+ <>{params.name && pageStyle === 'tab' ? : }>
);
};
-export const useTabSettings = (props) => {
- return {
- key: 'tab',
- eventKey: 'tab',
- label: ,
- };
-};
-
-const useHeraVersion = () => {
- const version = usePluginVersion();
- return {
- key: 'hera-version',
- eventKey: 'hera-version',
- label: 赫拉系统 - {version},
- };
-};
-
-const usePageStyle = () => {
- return useContext(PageStyleContext).style;
-};
-
export const AdminLayout = (props) => {
- const { addMenuItem } = useCurrentUserSettingsMenu();
- const [style, setStyle] = useState('classical');
- const tabItem = useTabSettings({ style, setStyle });
- const heraVersion = useHeraVersion();
- const { designable, setDesignable } = useDesignable();
-
- useEffect(() => {
- addMenuItem(tabItem, { before: 'divider_3' });
- }, [addMenuItem, tabItem]);
- useEffect(() => {
- addMenuItem(heraVersion, { before: 'divider_1' });
- }, [addMenuItem, tabItem]);
-
const AdminComponent = (
-
-
-
- }>
- } onClick={() => setDesignable(!designable)} />
- } />
- } />
-
+
);
return AdminComponent;
};
-
-export interface PageStyleContextValue {
- style: string;
-}
-
-const PageStyleContext = createContext({
- style: 'classical',
-});
-
-function Label({ style, setStyle }) {
- const { t } = useTranslation();
- return (
-
- );
-}
diff --git a/packages/plugins/@hera/plugin-core/src/client/pages/Home.tsx b/packages/plugins/@hera/plugin-core/src/client/pages/Home.tsx
index 501292dfc..581faa792 100644
--- a/packages/plugins/@hera/plugin-core/src/client/pages/Home.tsx
+++ b/packages/plugins/@hera/plugin-core/src/client/pages/Home.tsx
@@ -1,8 +1,7 @@
import React from 'react';
import { useStyles } from './style';
import { Carousel, Image } from 'antd';
-import { useRequest } from '@nocobase/client';
-import { useAppSpin } from './AdminLayout';
+import { useAppSpin, useRequest } from '@nocobase/client';
export const HomePage: React.FC<{}> = () => {
const { styles } = useStyles();