@4399ywkf/cli 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/templates/AntdStaticMethods/index.tsx +20 -0
- package/dist/templates/AppTheme.tsx +136 -0
- package/dist/templates/DIRECTORY_STRUCTURE.md +141 -0
- package/dist/templates/GlobalProvider/AppTheme.tsx +136 -0
- package/dist/templates/GlobalProvider/Locale.tsx +84 -0
- package/dist/templates/GlobalProvider/Query.tsx +12 -0
- package/dist/templates/GlobalProvider/StyleRegistry.tsx +9 -0
- package/dist/templates/GlobalProvider/index.tsx +23 -0
- package/dist/templates/Locale.tsx +55 -56
- package/dist/templates/Query.tsx +12 -0
- package/dist/templates/StyleRegistry.tsx +9 -0
- package/dist/templates/analyzeUnusedKeys.ts +506 -0
- package/dist/templates/app/.i18nrc.js +57 -0
- package/dist/templates/app/config/jwt/index.ts +2 -1
- package/dist/templates/app/docs/DIRECTORY_STRUCTURE.md +141 -0
- package/dist/templates/app/docs/glossary.md +11 -0
- package/dist/templates/app/package.json.tpl +7 -15
- package/dist/templates/app/scripts/i18nWorkflow/analyzeUnusedKeys.ts +506 -0
- package/dist/templates/app/scripts/i18nWorkflow/cleanUnusedKeys.ts +344 -0
- package/dist/templates/app/scripts/i18nWorkflow/const.ts +18 -0
- package/dist/templates/app/scripts/i18nWorkflow/flattenLocaleKeys.ts +139 -0
- package/dist/templates/app/scripts/i18nWorkflow/genDefaultLocale.ts +19 -0
- package/dist/templates/app/scripts/i18nWorkflow/genDiff.ts +49 -0
- package/dist/templates/app/scripts/i18nWorkflow/i18nConfig.ts +7 -0
- package/dist/templates/app/scripts/i18nWorkflow/index.ts +11 -0
- package/dist/templates/app/scripts/i18nWorkflow/protectedPatterns.ts +91 -0
- package/dist/templates/app/scripts/i18nWorkflow/utils.ts +76 -0
- package/dist/templates/app/src/components/AntdStaticMethods/index.tsx +20 -0
- package/dist/templates/app/src/index.tsx +0 -4
- package/dist/templates/app/src/layout/GlobalProvider/AppTheme.tsx +136 -0
- package/dist/templates/app/src/layout/GlobalProvider/Locale.tsx +84 -0
- package/dist/templates/app/src/layout/GlobalProvider/Query.tsx +12 -0
- package/dist/templates/app/src/layout/GlobalProvider/StyleRegistry.tsx +9 -0
- package/dist/templates/app/src/layout/GlobalProvider/index.tsx +23 -0
- package/dist/templates/app/src/locales/utils.ts +23 -0
- package/dist/templates/app/src/pages/base/index.tsx +170 -79
- package/dist/templates/app/src/routes.tsx +2 -2
- package/dist/templates/app/tsconfig.json +19 -3
- package/dist/templates/base/index.tsx +170 -79
- package/dist/templates/cleanUnusedKeys.ts +344 -0
- package/dist/templates/components/AntdStaticMethods/index.tsx +20 -0
- package/dist/templates/config/jwt/index.ts +2 -1
- package/dist/templates/const.ts +18 -0
- package/dist/templates/docs/DIRECTORY_STRUCTURE.md +141 -0
- package/dist/templates/docs/glossary.md +11 -0
- package/dist/templates/flattenLocaleKeys.ts +139 -0
- package/dist/templates/genDefaultLocale.ts +19 -0
- package/dist/templates/genDiff.ts +49 -0
- package/dist/templates/glossary.md +11 -0
- package/dist/templates/i18nConfig.ts +7 -0
- package/dist/templates/i18nWorkflow/analyzeUnusedKeys.ts +506 -0
- package/dist/templates/i18nWorkflow/cleanUnusedKeys.ts +344 -0
- package/dist/templates/i18nWorkflow/const.ts +18 -0
- package/dist/templates/i18nWorkflow/flattenLocaleKeys.ts +139 -0
- package/dist/templates/i18nWorkflow/genDefaultLocale.ts +19 -0
- package/dist/templates/i18nWorkflow/genDiff.ts +49 -0
- package/dist/templates/i18nWorkflow/i18nConfig.ts +7 -0
- package/dist/templates/i18nWorkflow/index.ts +11 -0
- package/dist/templates/i18nWorkflow/protectedPatterns.ts +91 -0
- package/dist/templates/i18nWorkflow/utils.ts +76 -0
- package/dist/templates/index.tsx +170 -79
- package/dist/templates/jwt/index.ts +2 -1
- package/dist/templates/layout/GlobalProvider/AppTheme.tsx +136 -0
- package/dist/templates/layout/GlobalProvider/Locale.tsx +84 -0
- package/dist/templates/layout/GlobalProvider/Query.tsx +12 -0
- package/dist/templates/layout/GlobalProvider/StyleRegistry.tsx +9 -0
- package/dist/templates/layout/GlobalProvider/index.tsx +23 -0
- package/dist/templates/locales/utils.ts +23 -0
- package/dist/templates/package.json.tpl +7 -15
- package/dist/templates/pages/base/index.tsx +170 -79
- package/dist/templates/protectedPatterns.ts +91 -0
- package/dist/templates/routes.tsx +2 -2
- package/dist/templates/scripts/i18nWorkflow/analyzeUnusedKeys.ts +506 -0
- package/dist/templates/scripts/i18nWorkflow/cleanUnusedKeys.ts +344 -0
- package/dist/templates/scripts/i18nWorkflow/const.ts +18 -0
- package/dist/templates/scripts/i18nWorkflow/flattenLocaleKeys.ts +139 -0
- package/dist/templates/scripts/i18nWorkflow/genDefaultLocale.ts +19 -0
- package/dist/templates/scripts/i18nWorkflow/genDiff.ts +49 -0
- package/dist/templates/scripts/i18nWorkflow/i18nConfig.ts +7 -0
- package/dist/templates/scripts/i18nWorkflow/index.ts +11 -0
- package/dist/templates/scripts/i18nWorkflow/protectedPatterns.ts +91 -0
- package/dist/templates/scripts/i18nWorkflow/utils.ts +76 -0
- package/dist/templates/src/components/AntdStaticMethods/index.tsx +20 -0
- package/dist/templates/src/index.tsx +0 -4
- package/dist/templates/src/layout/GlobalProvider/AppTheme.tsx +136 -0
- package/dist/templates/src/layout/GlobalProvider/Locale.tsx +84 -0
- package/dist/templates/src/layout/GlobalProvider/Query.tsx +12 -0
- package/dist/templates/src/layout/GlobalProvider/StyleRegistry.tsx +9 -0
- package/dist/templates/src/layout/GlobalProvider/index.tsx +23 -0
- package/dist/templates/src/locales/utils.ts +23 -0
- package/dist/templates/src/pages/base/index.tsx +170 -79
- package/dist/templates/src/routes.tsx +2 -2
- package/dist/templates/tsconfig.json +19 -3
- package/dist/templates/type.ts +23 -24
- package/dist/templates/utils.ts +23 -0
- package/package.json +19 -21
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { consola } from "consola";
|
|
2
|
+
import { colors } from "consola/utils";
|
|
3
|
+
import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
4
|
+
import { resolve, dirname } from "node:path";
|
|
5
|
+
import prettier from "@prettier/sync";
|
|
6
|
+
import i18nConfig from "./i18nConfig";
|
|
7
|
+
|
|
8
|
+
let prettierOptions = prettier.resolveConfig(
|
|
9
|
+
resolve(__dirname, "../../.prettierrc.js"),
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
export const readJSON = (filePath: string) => {
|
|
13
|
+
const data = readFileSync(filePath, "utf8");
|
|
14
|
+
return JSON.parse(data);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const writeJSON = (filePath: string, data: any) => {
|
|
18
|
+
const jsonStr = JSON.stringify(data, null, 2);
|
|
19
|
+
writeFileSync(filePath, jsonStr, "utf8");
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const writeJSONWithPrettier = (filePath: string, data: any) => {
|
|
23
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
24
|
+
const jsonStr = JSON.stringify(data, null, 2);
|
|
25
|
+
const formatted = prettier.format(jsonStr, {
|
|
26
|
+
...prettierOptions,
|
|
27
|
+
parser: "json",
|
|
28
|
+
});
|
|
29
|
+
writeFileSync(filePath, formatted, "utf8");
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const genResourcesContent = (locales: string[]) => {
|
|
33
|
+
let index = "";
|
|
34
|
+
let indexObj = "";
|
|
35
|
+
|
|
36
|
+
for (const locale of locales) {
|
|
37
|
+
index += `import ${locale} from "./${locale}";\n`;
|
|
38
|
+
indexObj += ` "${locale.replace("_", "-")}": ${locale},\n`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return `${index}
|
|
42
|
+
const resources = {
|
|
43
|
+
${indexObj}} as const;
|
|
44
|
+
export default resources;
|
|
45
|
+
export const defaultResources = ${i18nConfig.entryLocale};
|
|
46
|
+
export type Resources = typeof resources;
|
|
47
|
+
export type DefaultResources = typeof defaultResources;
|
|
48
|
+
export type Namespaces = keyof DefaultResources;
|
|
49
|
+
export type Locales = keyof Resources;
|
|
50
|
+
`;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const genNamespaceList = (files: string[], locale: string) => {
|
|
54
|
+
return files.map((file) => ({
|
|
55
|
+
name: file.replace(".json", ""),
|
|
56
|
+
path: resolve(i18nConfig.output, locale, file),
|
|
57
|
+
}));
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const tagBlue = (text: string) =>
|
|
61
|
+
colors.bgBlueBright(colors.black(` ${text} `));
|
|
62
|
+
export const tagYellow = (text: string) =>
|
|
63
|
+
colors.bgYellowBright(colors.black(` ${text} `));
|
|
64
|
+
export const tagGreen = (text: string) =>
|
|
65
|
+
colors.bgGreenBright(colors.black(` ${text} `));
|
|
66
|
+
export const tagWhite = (text: string) =>
|
|
67
|
+
colors.bgWhiteBright(colors.black(` ${text} `));
|
|
68
|
+
|
|
69
|
+
export const split = (name: string) => {
|
|
70
|
+
consola.log("");
|
|
71
|
+
consola.log(
|
|
72
|
+
colors.gray(
|
|
73
|
+
`========================== ${name} ==============================`,
|
|
74
|
+
),
|
|
75
|
+
);
|
|
76
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Entry component
|
|
2
|
+
import { App } from 'antd';
|
|
3
|
+
import type { MessageInstance } from 'antd/es/message/interface';
|
|
4
|
+
import type { ModalStaticFunctions } from 'antd/es/modal/confirm';
|
|
5
|
+
import type { NotificationInstance } from 'antd/es/notification/interface';
|
|
6
|
+
import { memo } from 'react';
|
|
7
|
+
|
|
8
|
+
let message: MessageInstance;
|
|
9
|
+
let notification: NotificationInstance;
|
|
10
|
+
let modal: Omit<ModalStaticFunctions, 'warn'>;
|
|
11
|
+
|
|
12
|
+
export default memo(() => {
|
|
13
|
+
const staticFunction = App.useApp();
|
|
14
|
+
message = staticFunction.message;
|
|
15
|
+
modal = staticFunction.modal;
|
|
16
|
+
notification = staticFunction.notification;
|
|
17
|
+
return null;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export { message, modal, notification };
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import "./index.css";
|
|
2
2
|
import { renderClient } from "@config/router";
|
|
3
|
-
import { bootstrapWithEnv } from "@/bootstrap";
|
|
4
3
|
import { createGarfishProvider, isMicroApp } from "@/micro/garfish";
|
|
5
4
|
import { env } from "@/config/env";
|
|
6
5
|
|
|
7
|
-
// 初始化应用
|
|
8
|
-
bootstrapWithEnv();
|
|
9
|
-
|
|
10
6
|
// 微前端模式:导出 Garfish 生命周期
|
|
11
7
|
export const provider = createGarfishProvider(env.APP_NAME);
|
|
12
8
|
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import ThemeProvider from "@/components/ThemeProvider";
|
|
2
|
+
import { CLOUD_THEME_APPEARANCE } from "@/const/theme";
|
|
3
|
+
import { setCookie } from "@/utils/cookie";
|
|
4
|
+
|
|
5
|
+
// import { useGlobalStore } from "@store/global";
|
|
6
|
+
import React, { memo, useEffect, type ReactNode } from "react";
|
|
7
|
+
|
|
8
|
+
import { SYSTEM_PREFIX } from "@/const/system";
|
|
9
|
+
import { GlobalStyle } from "@/styles";
|
|
10
|
+
import { useUserStore } from "@store/user";
|
|
11
|
+
import { createStaticStyles, cx } from "antd-style";
|
|
12
|
+
import HarmonyOS_Sans_Regular from "@public/fonts/HarmonyOS_Sans_Regular.woff2";
|
|
13
|
+
import AntdStaticMethods from "@/components/AntdStaticMethods";
|
|
14
|
+
|
|
15
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
16
|
+
app: css`
|
|
17
|
+
position: relative;
|
|
18
|
+
|
|
19
|
+
overscroll-behavior: none;
|
|
20
|
+
display: flex;
|
|
21
|
+
flex-direction: column;
|
|
22
|
+
align-items: center;
|
|
23
|
+
|
|
24
|
+
height: 100%;
|
|
25
|
+
min-height: 100dvh;
|
|
26
|
+
max-height: 100dvh;
|
|
27
|
+
|
|
28
|
+
@media (min-device-width: 576px) {
|
|
29
|
+
overflow: hidden;
|
|
30
|
+
}
|
|
31
|
+
`,
|
|
32
|
+
// scrollbar-width and scrollbar-color are supported from Chrome 121
|
|
33
|
+
// https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-color
|
|
34
|
+
scrollbar: css`
|
|
35
|
+
scrollbar-color: ${cssVar.colorFill} transparent;
|
|
36
|
+
scrollbar-width: thin;
|
|
37
|
+
|
|
38
|
+
#lobe-mobile-scroll-container {
|
|
39
|
+
scrollbar-width: none;
|
|
40
|
+
|
|
41
|
+
::-webkit-scrollbar {
|
|
42
|
+
width: 0;
|
|
43
|
+
height: 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
`,
|
|
47
|
+
|
|
48
|
+
// so this is a polyfill for older browsers
|
|
49
|
+
scrollbarPolyfill: css`
|
|
50
|
+
::-webkit-scrollbar {
|
|
51
|
+
width: 0.75em;
|
|
52
|
+
height: 0.75em;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
::-webkit-scrollbar-thumb {
|
|
56
|
+
border-radius: 10px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
:hover::-webkit-scrollbar-thumb {
|
|
60
|
+
border: 3px solid transparent;
|
|
61
|
+
background-color: ${cssVar.colorText};
|
|
62
|
+
background-clip: content-box;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
::-webkit-scrollbar-track {
|
|
66
|
+
background-color: transparent;
|
|
67
|
+
}
|
|
68
|
+
`,
|
|
69
|
+
}));
|
|
70
|
+
|
|
71
|
+
interface AppThemeProps {
|
|
72
|
+
children: ReactNode;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const AppTheme = memo(({ children }: AppThemeProps) => {
|
|
76
|
+
const themeMode = useUserStore((s) => s.themeMode);
|
|
77
|
+
const animationMode = useUserStore((s) => s.animationMode);
|
|
78
|
+
const neutralColor = useUserStore((s) => s.neutralColor);
|
|
79
|
+
const primaryColor = useUserStore((s) => s.primaryColor);
|
|
80
|
+
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
// Update data-theme accordingly if user selects light or dark
|
|
83
|
+
if (themeMode !== "auto") {
|
|
84
|
+
document.documentElement.dataset.theme = themeMode;
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// For auto mode, we need to watch system preferences
|
|
89
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
90
|
+
|
|
91
|
+
// Set initial theme based on system preference
|
|
92
|
+
document.documentElement.dataset.theme = mediaQuery.matches
|
|
93
|
+
? "dark"
|
|
94
|
+
: "light";
|
|
95
|
+
|
|
96
|
+
// Update theme when system preference changes
|
|
97
|
+
function handleChange(e) {
|
|
98
|
+
document.documentElement.dataset.theme = e.matches ? "dark" : "light";
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
102
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
103
|
+
}, [themeMode]);
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<ThemeProvider
|
|
107
|
+
prefixCls={SYSTEM_PREFIX}
|
|
108
|
+
appearance={themeMode !== "auto" ? themeMode : undefined}
|
|
109
|
+
className={cx(styles.app, styles.scrollbar, styles.scrollbarPolyfill)}
|
|
110
|
+
customTheme={{
|
|
111
|
+
neutralColor: neutralColor,
|
|
112
|
+
primaryColor: primaryColor,
|
|
113
|
+
}}
|
|
114
|
+
customFonts={[HarmonyOS_Sans_Regular]}
|
|
115
|
+
theme={{
|
|
116
|
+
cssVar: true,
|
|
117
|
+
token: {
|
|
118
|
+
motion: animationMode !== "disabled",
|
|
119
|
+
motionUnit: animationMode === "agile" ? 0.05 : 0.1,
|
|
120
|
+
},
|
|
121
|
+
}}
|
|
122
|
+
themeMode={themeMode}
|
|
123
|
+
onAppearanceChange={(appearance) => {
|
|
124
|
+
if (themeMode !== "auto") return;
|
|
125
|
+
|
|
126
|
+
setCookie(CLOUD_THEME_APPEARANCE, appearance);
|
|
127
|
+
}}
|
|
128
|
+
>
|
|
129
|
+
{children}
|
|
130
|
+
<AntdStaticMethods />
|
|
131
|
+
<GlobalStyle />
|
|
132
|
+
</ThemeProvider>
|
|
133
|
+
);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
export default AppTheme;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ConfigProvider } from 'antd';
|
|
2
|
+
import dayjs from 'dayjs';
|
|
3
|
+
import { type PropsWithChildren, memo, useEffect, useState } from 'react';
|
|
4
|
+
import { isRtlLang } from 'rtl-detect';
|
|
5
|
+
|
|
6
|
+
import { createI18nNext } from '@/locales/create';
|
|
7
|
+
import { getAntdLocale } from '@/utils/locale';
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
const updateDayjs = async (lang: string) => {
|
|
11
|
+
let dayJSLocale;
|
|
12
|
+
try {
|
|
13
|
+
// dayjs locale is using `en` instead of `en-US`
|
|
14
|
+
// refs: https://github.com/lobehub/lobe-chat/issues/3396
|
|
15
|
+
const locale = lang!.toLowerCase() === 'en-us' ? 'en' : lang!.toLowerCase();
|
|
16
|
+
|
|
17
|
+
dayJSLocale = await import(`dayjs/locale/${locale}.js`);
|
|
18
|
+
} catch {
|
|
19
|
+
console.warn(`dayjs locale for ${lang} not found, fallback to en`);
|
|
20
|
+
dayJSLocale = await import(`dayjs/locale/en.js`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
dayjs.locale(dayJSLocale.default);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
interface LocaleLayoutProps extends PropsWithChildren {
|
|
27
|
+
antdLocale?: any;
|
|
28
|
+
defaultLang?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const Locale = memo<LocaleLayoutProps>(({ children, defaultLang, antdLocale }) => {
|
|
32
|
+
const [i18n] = useState(() => createI18nNext(defaultLang));
|
|
33
|
+
const [lang, setLang] = useState(defaultLang);
|
|
34
|
+
const [locale, setLocale] = useState(antdLocale);
|
|
35
|
+
|
|
36
|
+
if (!i18n.instance.isInitialized)
|
|
37
|
+
i18n.init().then(async () => {
|
|
38
|
+
if (!lang) return;
|
|
39
|
+
|
|
40
|
+
await updateDayjs(lang);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// handle i18n instance language change
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
const handleLang = async (lng: string) => {
|
|
46
|
+
setLang(lng);
|
|
47
|
+
|
|
48
|
+
if (lang === lng) return;
|
|
49
|
+
|
|
50
|
+
const newLocale = await getAntdLocale(lng);
|
|
51
|
+
setLocale(newLocale);
|
|
52
|
+
|
|
53
|
+
await updateDayjs(lng);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
i18n.instance.on('languageChanged', handleLang);
|
|
57
|
+
return () => {
|
|
58
|
+
i18n.instance.off('languageChanged', handleLang);
|
|
59
|
+
};
|
|
60
|
+
}, [i18n, lang]);
|
|
61
|
+
|
|
62
|
+
// detect document direction
|
|
63
|
+
const documentDir = isRtlLang(lang!) ? 'rtl' : 'ltr';
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<ConfigProvider
|
|
67
|
+
direction={documentDir}
|
|
68
|
+
locale={locale}
|
|
69
|
+
theme={{
|
|
70
|
+
components: {
|
|
71
|
+
Button: {
|
|
72
|
+
contentFontSizeSM: 12,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
}}
|
|
76
|
+
>
|
|
77
|
+
{children}
|
|
78
|
+
</ConfigProvider>
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
Locale.displayName = 'Locale';
|
|
83
|
+
|
|
84
|
+
export default Locale;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
2
|
+
import React, { type PropsWithChildren, useEffect, useState } from 'react';
|
|
3
|
+
|
|
4
|
+
const QueryProvider = ({ children }: PropsWithChildren) => {
|
|
5
|
+
const [queryClient] = useState(() => new QueryClient());
|
|
6
|
+
|
|
7
|
+
return (
|
|
8
|
+
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
|
9
|
+
);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default QueryProvider;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import StyleRegistry from "./StyleRegistry";
|
|
2
|
+
import AppTheme from "./AppTheme";
|
|
3
|
+
import QueryProvider from "./Query";
|
|
4
|
+
import Locale from "./Locale";
|
|
5
|
+
import { Outlet } from "react-router";
|
|
6
|
+
|
|
7
|
+
interface GlobalProviderProps {
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default function GlobalProvider({ }: GlobalProviderProps) {
|
|
12
|
+
return (
|
|
13
|
+
<StyleRegistry>
|
|
14
|
+
<Locale>
|
|
15
|
+
<AppTheme>
|
|
16
|
+
<QueryProvider>
|
|
17
|
+
<Outlet />
|
|
18
|
+
</QueryProvider>
|
|
19
|
+
</AppTheme>
|
|
20
|
+
</Locale>
|
|
21
|
+
</StyleRegistry>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const SAFE_KEY = /^[^.[\]]+$/;
|
|
2
|
+
|
|
3
|
+
export const toLodashPath = (segments: Array<number | string>) => {
|
|
4
|
+
let path = '';
|
|
5
|
+
|
|
6
|
+
for (const segment of segments) {
|
|
7
|
+
if (typeof segment === 'number') {
|
|
8
|
+
path += `[${segment}]`;
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const key = segment;
|
|
13
|
+
const safe = SAFE_KEY.test(key);
|
|
14
|
+
if (safe) {
|
|
15
|
+
path += path ? `.${key}` : key;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
path += `[${JSON.stringify(key)}]`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return path;
|
|
23
|
+
};
|