diff --git a/packages/studio-components/src/IntlProvider/index.tsx b/packages/studio-components/src/IntlProvider/index.tsx new file mode 100644 index 000000000..eb5ea3517 --- /dev/null +++ b/packages/studio-components/src/IntlProvider/index.tsx @@ -0,0 +1,53 @@ +import React, { useState } from 'react'; +import { IntlProvider } from 'react-intl'; +import { storage } from '../Utils'; +import { IntlContainerProvider } from './useIntlConfigProvider'; + +type IThemeProvider = { + locales: { + 'zh-CN': Record; + 'en-US': Record; + }; + children: React.ReactNode; + locale?: 'zh-CN' | 'en-US'; +}; + +const Provider: React.FC = props => { + const { children, locales } = props; + const [state, setState] = useState<{ locale?: 'zh-CN' | 'en-US' }>(() => { + let { locale = storage.get('locale') } = props; + if (!locale) { + locale = 'en-US'; + } + storage.set('locale', locale); + return { + locale, + }; + }); + + const { locale } = state; + + const messages = locales[locale || 'en-US']; + + const handleLocale = themeConfig => { + const { locale } = themeConfig; + storage.set('locale', locale); + setState(preState => { + return { + ...preState, + locale, + }; + }); + }; + console.log('locale111', locale); + + return ( + + + {children} + + + ); +}; + +export default Provider; diff --git a/packages/studio-components/src/IntlProvider/useIntlConfigProvider.tsx b/packages/studio-components/src/IntlProvider/useIntlConfigProvider.tsx new file mode 100644 index 000000000..07a7fb5f4 --- /dev/null +++ b/packages/studio-components/src/IntlProvider/useIntlConfigProvider.tsx @@ -0,0 +1,23 @@ +import { createContext, useContext } from 'react'; + +export interface ThemeProviderType { + locale?: 'zh-CN' | 'en-US'; +} +export interface IContainerContext extends ThemeProviderType { + handleLocale: (value: ThemeProviderType) => void; +} +export const IntlContainerContext = createContext({ + handleLocale: ({}) => {}, + locale: 'en-US', +}); + +export const IntlContainerProvider = IntlContainerContext.Provider; + +export const useIntlContainer = () => { + const context = useContext(IntlContainerContext); + + if (context === undefined || Object.keys(context).length === 0) { + throw new Error(`useContext must be used within a ContainerProvider`); + } + return context; +}; diff --git a/packages/studio-components/src/Provider/useStore.tsx b/packages/studio-components/src/Provider/getThemeConfig.tsx similarity index 68% rename from packages/studio-components/src/Provider/useStore.tsx rename to packages/studio-components/src/Provider/getThemeConfig.tsx index 5eae469e0..ab91a3329 100644 --- a/packages/studio-components/src/Provider/useStore.tsx +++ b/packages/studio-components/src/Provider/getThemeConfig.tsx @@ -10,7 +10,7 @@ export interface IColorStore { editorForeground?: string; } -export const useStore = (algorithm: ThemeProviderType['algorithm']) => { +export const getThemeConfig = (algorithm: ThemeProviderType['algorithm']) => { const isLight = algorithm === 'defaultAlgorithm'; /** components 基础配置 */ const componentsConfig = { @@ -47,16 +47,5 @@ export const useStore = (algorithm: ThemeProviderType['algorithm']) => { colorBgBase: isLight ? '#fff' : 'rgba(12,12,12,1)', colorBgLayout: isLight ? '#f5f7f9' : 'rgba(43,43,43,1)', }; - /** 特殊颜色配置 */ - const colorConfig = { - sectionBackground: isLight ? '#fff' : '#0D0D0D', - containerBackground: isLight ? '#f5f7f9' : '#020202', - instanceBackground: isLight ? '#FCFCFC' : '', - jobDetailBorder: isLight ? '#efefef' : '#323232', - jobDetailColor: isLight ? '#1F1F1F' : '#808080', - pluginBorder: isLight ? '#efefef' : '#323232', - editorBackground: isLight ? '#fff' : '#151515', - editorForeground: isLight ? '#212121' : '#FFF', - }; - return { componentsConfig, tokenConfig, colorConfig }; + return { componentsConfig, tokenConfig }; }; diff --git a/packages/studio-components/src/Provider/index.tsx b/packages/studio-components/src/Provider/index.tsx index b4705e487..7a00aecbd 100644 --- a/packages/studio-components/src/Provider/index.tsx +++ b/packages/studio-components/src/Provider/index.tsx @@ -1,32 +1,20 @@ -import React, { useEffect, useState } from 'react'; +import React, { useState } from 'react'; import { ConfigProvider, theme } from 'antd'; -import { IntlProvider } from 'react-intl'; import { ContainerProvider } from './useThemeConfigProvider'; import type { ThemeProviderType } from './useThemeConfigProvider'; import { storage } from '../Utils'; -import { useStore } from './useStore'; +import { getThemeConfig } from './getThemeConfig'; type IThemeProvider = { - locales: { - 'zh-CN': Record; - 'en-US': Record; - }; children: React.ReactNode; - locale?: 'zh-CN' | 'en-US'; algorithm?: 'defaultAlgorithm' | 'darkAlgorithm'; }; const Provider: React.FC = props => { - const { children, locales } = props; + const { children } = props; const [state, setState] = useState(() => { - let { algorithm, locale } = props; - if (!locale) { - locale = storage.get('locale'); - if (!locale) { - locale = 'en-US'; - storage.set('locale', locale); - } - } + let { algorithm } = props; + if (!algorithm) { algorithm = storage.get('algorithm'); if (!algorithm) { @@ -38,12 +26,11 @@ const Provider: React.FC = props => { components: storage.get('components'), token: storage.get('token'), algorithm, - locale, }; }); - const { components, token, algorithm, locale } = state; - const { componentsConfig, tokenConfig, colorConfig } = useStore(algorithm); + const { components, token, algorithm } = state; + const { componentsConfig, tokenConfig } = getThemeConfig(algorithm); const isLight = algorithm === 'defaultAlgorithm'; @@ -59,41 +46,34 @@ const Provider: React.FC = props => { components: { ...preState.components, ...components }, token: { ...preState.token, ...token }, algorithm: themeConfig.algorithm || preState.algorithm, - locale: themeConfig.locale, }; }); }; - const messages = locales[locale || 'en-US']; return ( - - - {children} - - + + {children} + ); }; diff --git a/packages/studio-components/src/Provider/useCustomTheme.tsx b/packages/studio-components/src/Provider/useCustomTheme.tsx new file mode 100644 index 000000000..757b643fd --- /dev/null +++ b/packages/studio-components/src/Provider/useCustomTheme.tsx @@ -0,0 +1,29 @@ +import { ThemeProviderType } from './useThemeConfigProvider'; +import { useThemeContainer } from './useThemeConfigProvider'; +export interface IColorStore { + sectionBackground?: string; + containerBackground?: string; + instanceBackground?: string; + jobDetailBorder?: string; + jobDetailColor?: string; + pluginBorder?: string; + editorBackground?: string; + editorForeground?: string; +} + +export const useCustomTheme = () => { + const { algorithm } = useThemeContainer(); + const isLight = algorithm === 'defaultAlgorithm'; + /** 特殊颜色配置 */ + const colorConfig = { + sectionBackground: isLight ? '#fff' : '#0D0D0D', + containerBackground: isLight ? '#f5f7f9' : '#020202', + instanceBackground: isLight ? '#FCFCFC' : '', + jobDetailBorder: isLight ? '#efefef' : '#323232', + jobDetailColor: isLight ? '#1F1F1F' : '#808080', + pluginBorder: isLight ? '#efefef' : '#323232', + editorBackground: isLight ? '#fff' : '#151515', + editorForeground: isLight ? '#212121' : '#FFF', + }; + return colorConfig; +}; diff --git a/packages/studio-components/src/Provider/useThemeConfigProvider.tsx b/packages/studio-components/src/Provider/useThemeConfigProvider.tsx index 8efd69cec..608657cd6 100644 --- a/packages/studio-components/src/Provider/useThemeConfigProvider.tsx +++ b/packages/studio-components/src/Provider/useThemeConfigProvider.tsx @@ -1,5 +1,5 @@ import { createContext, useContext } from 'react'; -import { IColorStore } from './useStore'; +import type { IColorStore } from './getThemeConfig'; export interface ThemeProviderType extends IColorStore { algorithm?: 'defaultAlgorithm' | 'darkAlgorithm'; components?: { [key: string]: { [key: string]: string | number } }; diff --git a/packages/studio-components/src/index.tsx b/packages/studio-components/src/index.tsx index d79d7a0b7..5f7015c53 100644 --- a/packages/studio-components/src/index.tsx +++ b/packages/studio-components/src/index.tsx @@ -12,6 +12,7 @@ export { default as MultipleInstance } from './MultipleInstance'; export { default as SplitSection } from './SplitSection'; export { default as ResultConfig } from './ResultConfig'; export { default as ThemeProvider } from './Provider'; +export { default as IntlProvider } from './IntlProvider'; export { default as ImportFiles } from './ImportFiles'; export { default as SideTabs } from './SideTabs'; export { default as ResizablePanels } from './ResizablePanel'; @@ -28,6 +29,8 @@ export { useContainer } from './Container/useContainer'; export { useSection } from './Section/useSection'; export { useMultipleInstance } from './MultipleInstance/useMultipleInstance'; export { useThemeContainer } from './Provider/useThemeConfigProvider'; +export { useIntlContainer } from './IntlProvider/useIntlConfigProvider'; +export { useCustomTheme } from './Provider/useCustomTheme'; /** export typing */ export type { SegmentedTabsProps } from './SegmentedTabs'; export type { Property } from './PropertiesList/typing'; diff --git a/packages/studio-importor/src/app/index.tsx b/packages/studio-importor/src/app/index.tsx index 06eafa74e..66cda1bcd 100644 --- a/packages/studio-importor/src/app/index.tsx +++ b/packages/studio-importor/src/app/index.tsx @@ -4,7 +4,7 @@ import PropertiesEditor from './properties-editor'; import ImportSchema from './import-schema'; import { ReactFlowProvider } from 'reactflow'; -import { ThemeProvider, Section } from '@graphscope/studio-components'; +import { IntlProvider, Section } from '@graphscope/studio-components'; import 'reactflow/dist/style.css'; import { transformGraphNodes, transformEdges } from './elements/index'; import { IdContext } from './useContext'; @@ -86,7 +86,7 @@ const ImportApp: React.FunctionComponent = props => { const IS_PURE = appMode === 'PURE'; return ( - +
} rightSide={ @@ -115,7 +115,7 @@ const ImportApp: React.FunctionComponent = props => { {children}
-
+ ); }; diff --git a/packages/studio-query/src/app/index.tsx b/packages/studio-query/src/app/index.tsx index 097063aa3..5069331e5 100644 --- a/packages/studio-query/src/app/index.tsx +++ b/packages/studio-query/src/app/index.tsx @@ -14,7 +14,7 @@ import { FormattedMessage } from 'react-intl'; import type { IStudioQueryProps } from './context'; import { v4 as uuidv4 } from 'uuid'; import { formatCypherStatement } from './utils'; -import { Utils, ThemeProvider, Section } from '@graphscope/studio-components'; +import { Utils, IntlProvider, Section } from '@graphscope/studio-components'; const { getSearchParams, setSearchParams } = Utils; import Container from './container'; @@ -156,7 +156,7 @@ const StudioQuery: React.FunctionComponent = props => { }; return ( - +
= props => { enableImmediateQuery={enableImmediateQuery} />
-
+ ); } return null; diff --git a/packages/studio-query/src/sdk/query-statement/index.tsx b/packages/studio-query/src/sdk/query-statement/index.tsx index 6a4054364..26687795a 100644 --- a/packages/studio-query/src/sdk/query-statement/index.tsx +++ b/packages/studio-query/src/sdk/query-statement/index.tsx @@ -3,7 +3,7 @@ import { Statement } from '../..'; import type { IStatement } from '../..'; import { CypherDriver, GremlinDriver } from '@graphscope/studio-driver'; import ConnectEndpoint, { IConnectEndpointProps } from './connect-endpoint'; -import { ThemeProvider } from '@graphscope/studio-components'; +import { IntlProvider } from '@graphscope/studio-components'; import locales from '../../locales'; const driver_config: Record = {}; @@ -63,14 +63,14 @@ const QueryStatement = props => { }; if (!endpoint || !language) { return ( - + - + ); } return ( - + { onQuery={onQuery} onCancel={onCancel} /> - + ); }; diff --git a/packages/studio-website/src/components/section/index.tsx b/packages/studio-website/src/components/section/index.tsx index 0199b836f..f26574082 100644 --- a/packages/studio-website/src/components/section/index.tsx +++ b/packages/studio-website/src/components/section/index.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { Divider, Typography, Tabs, Space } from 'antd'; import { FormattedMessage } from 'react-intl'; import type { TabsProps } from 'antd'; -import { Utils, useThemeContainer } from '@graphscope/studio-components'; +import { Utils, useThemeContainer, useCustomTheme } from '@graphscope/studio-components'; interface IFormattedMessage { id: string; values?: { [key: string]: string }; @@ -18,7 +18,7 @@ interface ISectionProps { const { useEffect } = React; const Section: React.FunctionComponent = props => { const { title, desc, breadcrumb, children, items, style } = props; - const { sectionBackground } = useThemeContainer(); + const { sectionBackground } = useCustomTheme(); useEffect(() => { if (items) { const nav = Utils.getSearchParams('nav') || ''; diff --git a/packages/studio-website/src/layouts/container.tsx b/packages/studio-website/src/layouts/container.tsx index 47a992d07..83593ad50 100644 --- a/packages/studio-website/src/layouts/container.tsx +++ b/packages/studio-website/src/layouts/container.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import { useContext } from './useContext'; import useWidth from './useWidth'; -import { useThemeContainer } from '@graphscope/studio-components'; +import { useCustomTheme } from '@graphscope/studio-components'; import { DeploymentApiFactory } from '@graphscope/studio-server'; import { Skeleton } from 'antd'; @@ -20,7 +20,7 @@ const Container: React.FunctionComponent = props => { const { store } = useContext(); const { collapse } = store; const ContainerWidth = useWidth(); - const { containerBackground } = useThemeContainer(); + const { containerBackground } = useCustomTheme(); const [state, setState] = useState({ isReady: false, engineType: 'interactive', diff --git a/packages/studio-website/src/layouts/index.tsx b/packages/studio-website/src/layouts/index.tsx index 472f20c1e..d68c0f869 100644 --- a/packages/studio-website/src/layouts/index.tsx +++ b/packages/studio-website/src/layouts/index.tsx @@ -9,7 +9,7 @@ import { useContext } from './useContext'; import { TOOLS_MENU } from './const'; import SegmentedSection from './segmented-section'; import { history } from 'umi'; -import { ThemeProvider } from '@graphscope/studio-components'; +import { ThemeProvider, IntlProvider } from '@graphscope/studio-components'; const Content = (props: any) => { const { children, navStyle } = props; const { store } = useContext(); @@ -33,16 +33,18 @@ export default function Layout() { const { locale, navStyle } = store; return ( - - } - content={ - - - - } - footer={