@_tc/template-core 0.2.0-bate.9 → 0.2.1-bate.1

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.
Files changed (90) hide show
  1. package/AGENT_README.md +5 -2
  2. package/README.md +76 -31
  3. package/cjs/app/controller/project.js +1 -1
  4. package/cjs/app/controller/view.js +1 -1
  5. package/cjs/app/extends/db.js +4 -4
  6. package/cjs/app/middleware.js +1 -1
  7. package/cjs/app/middlewares/error-handle.js +1 -1
  8. package/cjs/app/middlewares/project-handler.js +1 -1
  9. package/cjs/app/utils/i18n.js +1 -0
  10. package/cjs/app/view/entry.tpl +1 -0
  11. package/cjs/config/config.default.js +1 -1
  12. package/cjs/packages/common/i18n/default.js +1 -1
  13. package/cjs/packages/common/i18n/en-US.js +1 -1
  14. package/cjs/packages/common/index.js +1 -1
  15. package/esm/app/controller/project.js +12 -11
  16. package/esm/app/controller/view.js +2 -1
  17. package/esm/app/extends/db.js +64 -60
  18. package/esm/app/middleware.js +1 -1
  19. package/esm/app/middlewares/error-handle.js +16 -15
  20. package/esm/app/middlewares/project-handler.js +8 -7
  21. package/esm/app/utils/i18n.js +36 -0
  22. package/esm/app/view/entry.tpl +1 -0
  23. package/esm/config/config.default.js +2 -1
  24. package/esm/packages/common/i18n/default.js +13 -0
  25. package/esm/packages/common/i18n/en-US.js +13 -0
  26. package/esm/packages/common/index.js +9 -9
  27. package/fe/frontend/apps/dash/Dashboard.js +6 -4
  28. package/fe/frontend/apps/dash/dash.entry.js +2 -0
  29. package/fe/frontend/src/common/generateMenuData.d.ts +4 -1
  30. package/fe/frontend/src/common/generateMenuData.js +3 -3
  31. package/fe/frontend/src/common/language.d.ts +1 -2
  32. package/fe/frontend/src/common/language.js +10 -10
  33. package/fe/frontend/src/common/request.js +3 -1
  34. package/fe/frontend/src/components/AsyncSelect/AsyncSelect.js +10 -2
  35. package/fe/frontend/src/components/BasePage/HeaderView.js +2 -2
  36. package/fe/frontend/src/components/LanguageSwitch/LanguageSwitch.js +13 -9
  37. package/fe/frontend/src/components/ThemeSwitch/ThemeSwitch.js +4 -3
  38. package/fe/frontend/src/defaultPages/NotFoundPage/index.js +4 -3
  39. package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/DetailPanel.js +14 -9
  40. package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/PopFrom.js +8 -7
  41. package/fe/frontend/src/defaultPages/SchemaPage/components/SchemaSearch/index.js +6 -12
  42. package/fe/frontend/src/defaultPages/SchemaPage/components/SchemaTable/index.js +25 -18
  43. package/fe/frontend/src/defaultPages/SchemaPage/index.js +5 -3
  44. package/fe/frontend/src/defaultPages/SidebarSlotPageTmp.js +4 -2
  45. package/fe/frontend/src/hooks/useText.d.ts +3 -0
  46. package/fe/frontend/src/hooks/useText.js +14 -0
  47. package/fe/frontend/src/index.d.ts +1 -0
  48. package/fe/frontend/src/index.js +3 -2
  49. package/fe/frontend/src/language/index.d.ts +0 -2
  50. package/fe/frontend/src/language/index.js +1 -7
  51. package/fe/frontend/src/language/resources.d.ts +2 -0
  52. package/fe/frontend/src/language/resources.js +9 -0
  53. package/fe/packages/common/i18n/default.d.ts +15 -0
  54. package/fe/packages/common/i18n/default.js +16 -0
  55. package/fe/packages/common/i18n/en-US.d.ts +15 -0
  56. package/fe/packages/common/i18n/en-US.js +18 -2
  57. package/fe/packages/common/i18n/index.js +13 -0
  58. package/fe/packages/common/i18n/locales.js +7 -0
  59. package/fe/packages/react/ui/components/Date/Calendar.js +9 -5
  60. package/fe/packages/react/ui/components/Date/LocaleContext.d.ts +22 -1
  61. package/fe/packages/react/ui/components/Date/LocaleContext.js +28 -3
  62. package/fe/packages/react/ui/components/Date/LocaleProvider.d.ts +1 -1
  63. package/fe/packages/react/ui/components/Date/LocaleProvider.js +7 -16
  64. package/fe/packages/react/ui/components/Date/index.js +2 -2
  65. package/fe/packages/react/ui/components/Date/locales.d.ts +2 -0
  66. package/fe/packages/react/ui/components/Date/locales.js +29 -13
  67. package/fe/packages/react/ui/components/TableSearch/TableSearch.js +21 -1
  68. package/fe/packages/react/ui/components/TableSearch/lang.d.ts +2 -0
  69. package/fe/packages/react/ui/components/TableSearch/lang.js +18 -7
  70. package/fe/packages/react/ui/components/Textarea/Textarea.d.ts +1 -1
  71. package/fe/packages/react/ui/components/Textarea/Textarea.js +1 -1
  72. package/model/frontend/src/common/language.d.ts +1 -2
  73. package/model/frontend/src/hooks/useText.d.ts +3 -0
  74. package/model/frontend/src/language/index.d.ts +0 -2
  75. package/model/frontend/src/language/resources.d.ts +2 -0
  76. package/model/packages/common/i18n/default.d.ts +15 -0
  77. package/model/packages/common/i18n/en-US.d.ts +15 -0
  78. package/model/packages/react/ui/components/Date/LocaleContext.d.ts +22 -1
  79. package/model/packages/react/ui/components/Date/LocaleProvider.d.ts +1 -1
  80. package/model/packages/react/ui/components/Date/locales.d.ts +2 -0
  81. package/model/packages/react/ui/components/TableSearch/lang.d.ts +2 -0
  82. package/model/packages/react/ui/components/Textarea/Textarea.d.ts +1 -1
  83. package/package.json +1 -1
  84. package/types/app/utils/i18n.d.ts +12 -0
  85. package/types/config/config.default.d.ts +6 -0
  86. package/types/packages/common/i18n/default.d.ts +19 -0
  87. package/types/packages/common/i18n/en-US.d.ts +21 -2
  88. package/types/packages/common/i18n/index.d.ts +21 -0
  89. package/types/packages/common/i18n/locales.d.ts +10 -0
  90. package/types/packages/common/i18n/types.d.ts +40 -0
@@ -2,26 +2,27 @@ import { frontendLangKeys } from "../../language/index.js";
2
2
  import { i18nStore } from "../../../../packages/common/i18n/index.js";
3
3
  import { useI18nStore } from "../../../../packages/react/ui/i18n/useI18n.js";
4
4
  import "../../../../packages/react/ui/i18n/index.js";
5
- import { getSupportedLanguages, getText } from "../../common/language.js";
5
+ import { getSupportedLanguages } from "../../common/language.js";
6
6
  import { cn } from "../../../../packages/react/ui/lib/utils.js";
7
7
  import { Button } from "../../../../packages/react/ui/components/Button/Button.js";
8
8
  import { Dropdown } from "../../../../packages/react/ui/components/Dropdown/Dropdown.js";
9
9
  import "../../../../packages/react/ui/index.js";
10
+ import { useText } from "../../hooks/useText.js";
10
11
  import { useCallback, useMemo, useRef } from "react";
11
12
  import { jsx, jsxs } from "react/jsx-runtime";
12
13
  import { Check, ChevronDown } from "lucide-react";
13
14
  //#region frontend/src/components/LanguageSwitch/LanguageSwitch.tsx
14
- var getDefaultLanguageOptions = () => [{
15
- label: getText(frontendLangKeys.languageSwitchZhCN),
15
+ var getDefaultLanguageOptions = (text) => [{
16
+ label: text(frontendLangKeys.languageSwitchZhCN),
16
17
  value: "zh-CN",
17
18
  searchText: "zh-CN 中文 简体中文"
18
19
  }, {
19
- label: getText(frontendLangKeys.languageSwitchEnUS),
20
+ label: text(frontendLangKeys.languageSwitchEnUS),
20
21
  value: "en-US",
21
22
  searchText: "en-US English"
22
23
  }];
23
- var getLanguageOptions = () => {
24
- const baseOptions = getDefaultLanguageOptions();
24
+ var getLanguageOptions = (text) => {
25
+ const baseOptions = getDefaultLanguageOptions(text);
25
26
  const seen = new Set(baseOptions.map((option) => option.value));
26
27
  return [...baseOptions, ...getSupportedLanguages().filter((language) => !seen.has(language)).map((language) => ({
27
28
  label: language,
@@ -31,15 +32,18 @@ var getLanguageOptions = () => {
31
32
  };
32
33
  var LanguageSwitch = ({ value, defaultValue, options, onChange, className, buttonClassName, placeholder, disabled, loading, clearable: _clearable, searchable: _searchable, placement = "bottom-end", getPopupContainer = "parent", ...props }) => {
33
34
  const rootRef = useRef(null);
35
+ const text = useText();
34
36
  const currentLanguage = useI18nStore((state) => state.language);
35
- const mergedOptions = useMemo(() => options ?? getLanguageOptions(), [
37
+ const mergedOptions = useMemo(() => options ?? getLanguageOptions(text), [
36
38
  currentLanguage,
37
39
  options,
38
- useI18nStore((state) => state.resources)
40
+ useI18nStore((state) => state.resources),
41
+ text
39
42
  ]);
40
43
  const selectedLanguage = value ?? currentLanguage ?? defaultValue;
41
44
  const selectedOption = mergedOptions.find((option) => option.value === selectedLanguage);
42
- const displayText = selectedOption?.label ?? placeholder ?? getText(frontendLangKeys.languageSwitchPlaceholder);
45
+ let displayText = selectedOption?.label ?? (placeholder || frontendLangKeys.languageSwitchPlaceholder);
46
+ if (typeof displayText === "string") displayText = text(displayText);
43
47
  const handleChange = useCallback((language) => {
44
48
  if (!language) return;
45
49
  const nextLanguage = String(language);
@@ -1,17 +1,18 @@
1
1
  import { frontendLangKeys } from "../../language/index.js";
2
2
  import { useI18nStore } from "../../../../packages/react/ui/i18n/useI18n.js";
3
3
  import "../../../../packages/react/ui/i18n/index.js";
4
- import { getText } from "../../common/language.js";
5
4
  import { cn } from "../../../../packages/react/ui/lib/utils.js";
6
5
  import { Switch } from "../../../../packages/react/ui/components/Switch/Switch.js";
7
6
  import { Tooltip } from "../../../../packages/react/ui/components/Tooltip/Tooltip.js";
8
7
  import "../../../../packages/react/ui/index.js";
8
+ import { useText } from "../../hooks/useText.js";
9
9
  import { applyThemeMode, getCurrentThemeMode, persistThemeMode, themeSwitchStorageKey } from "../../common/theme.js";
10
10
  import { useEffect, useState } from "react";
11
11
  import { jsx, jsxs } from "react/jsx-runtime";
12
12
  import { Moon, Sun } from "lucide-react";
13
13
  //#region frontend/src/components/ThemeSwitch/ThemeSwitch.tsx
14
14
  var ThemeSwitch = ({ value, defaultValue, onChange, disabled, className, showLabel = false, persist = true, storageKey = themeSwitchStorageKey }) => {
15
+ const text = useText();
15
16
  useI18nStore((state) => state.language);
16
17
  const [internalMode, setInternalMode] = useState(() => getCurrentThemeMode(defaultValue, storageKey));
17
18
  const isControlled = value !== void 0;
@@ -30,8 +31,8 @@ var ThemeSwitch = ({ value, defaultValue, onChange, disabled, className, showLab
30
31
  if (persist) persistThemeMode(nextMode, storageKey);
31
32
  onChange?.(nextMode);
32
33
  };
33
- const label = mode === "dark" ? getText(frontendLangKeys.themeSwitchDark) : getText(frontendLangKeys.themeSwitchLight);
34
- const tooltip = checked ? getText(frontendLangKeys.themeSwitchToLight) : getText(frontendLangKeys.themeSwitchToDark);
34
+ const label = mode === "dark" ? text(frontendLangKeys.themeSwitchDark) : text(frontendLangKeys.themeSwitchLight);
35
+ const tooltip = checked ? text(frontendLangKeys.themeSwitchToLight) : text(frontendLangKeys.themeSwitchToDark);
35
36
  return /* @__PURE__ */ jsxs("div", {
36
37
  className: cn("inline-flex shrink-0 items-center gap-2 text-foreground", className),
37
38
  children: [
@@ -1,8 +1,9 @@
1
1
  import { frontendLangKeys } from "../../language/index.js";
2
- import { getText } from "../../common/language.js";
2
+ import { useText } from "../../hooks/useText.js";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region frontend/src/defaultPages/NotFoundPage/index.tsx
5
5
  var NotFoundPage = () => {
6
+ const text = useText();
6
7
  return /* @__PURE__ */ jsx("div", {
7
8
  className: "flex h-full min-h-[240px] w-full items-center justify-center bg-theme-bg px-6 text-foreground",
8
9
  children: /* @__PURE__ */ jsxs("div", {
@@ -14,11 +15,11 @@ var NotFoundPage = () => {
14
15
  }),
15
16
  /* @__PURE__ */ jsx("h1", {
16
17
  className: "text-lg font-semibold tracking-normal",
17
- children: getText(frontendLangKeys.notFoundTitle)
18
+ children: text(frontendLangKeys.notFoundTitle)
18
19
  }),
19
20
  /* @__PURE__ */ jsx("p", {
20
21
  className: "mt-2 text-sm leading-6 text-muted-foreground",
21
- children: getText(frontendLangKeys.notFoundDescription)
22
+ children: text(frontendLangKeys.notFoundDescription)
22
23
  })
23
24
  ]
24
25
  })
@@ -1,8 +1,8 @@
1
1
  import { frontendLangKeys } from "../../../../language/index.js";
2
- import { getText } from "../../../../common/language.js";
3
2
  import { Drawer } from "../../../../../../packages/react/ui/components/Drawer/Drawer.js";
4
3
  import "../../../../../../packages/react/ui/components/index.js";
5
4
  import { request } from "../../../../common/request.js";
5
+ import { useText } from "../../../../hooks/useText.js";
6
6
  import { schemaEventBus } from "../../../../stores/schemaEventBus.js";
7
7
  import { handlingRequestErrors } from "../../../../common/fetchErrorShow.js";
8
8
  import useExecuteOnce from "../../../../../../packages/react/hooks/useExecuteOnce.js";
@@ -28,7 +28,7 @@ var getOptionLabel = (options, value) => {
28
28
  if (!matchedOption || typeof matchedOption !== "object") return void 0;
29
29
  return matchedOption.label ?? stringifyValue(value);
30
30
  };
31
- var formatValue = (value, fieldInfo) => {
31
+ var formatValue = (value, fieldInfo, text) => {
32
32
  if (isEmptyValue(value)) return EMPTY_TEXT;
33
33
  const option = fieldInfo.option;
34
34
  const optionLabel = getOptionLabel(option?.options ?? option?.enumList, value);
@@ -39,28 +39,33 @@ var formatValue = (value, fieldInfo) => {
39
39
  return stringifyValue(item);
40
40
  }).join(", ");
41
41
  }
42
- if (typeof value === "boolean") return value ? getText(frontendLangKeys.yes) : getText(frontendLangKeys.no);
42
+ if (typeof value === "boolean") return value ? text(frontendLangKeys.yes) : text(frontendLangKeys.no);
43
43
  return stringifyValue(value);
44
44
  };
45
- var generateFields = (schema, data) => {
45
+ var generateFields = (schema, data, text) => {
46
46
  if (!schema?.properties) return [];
47
47
  return Object.keys(schema.properties).reduce((fields, key) => {
48
48
  const fieldInfo = schema.properties[key];
49
49
  if (!fieldInfo?.option || fieldInfo.option.visible === false) return fields;
50
50
  fields.push({
51
51
  key,
52
- label: getText(fieldInfo.label),
53
- value: formatValue(data?.[key], fieldInfo),
52
+ label: text(fieldInfo.label),
53
+ value: formatValue(data?.[key], fieldInfo, text),
54
54
  level: fieldInfo.level ?? 10
55
55
  });
56
56
  return fields;
57
57
  }, []).sort((a, b) => a.level - b.level);
58
58
  };
59
59
  var DetailPanel = memo((props) => {
60
+ const text = useText();
60
61
  const [open, setOpen] = useState(true);
61
62
  const [data, setData] = useState(props.data);
62
63
  const { config, schema, api } = useComConfig({ comName: props.comName });
63
- const fields = useMemo(() => generateFields(schema, data), [data, schema]);
64
+ const fields = useMemo(() => generateFields(schema, data, text), [
65
+ data,
66
+ schema,
67
+ text
68
+ ]);
64
69
  useExecuteOnce(async () => {
65
70
  const fetchKey = config?.fetchKey;
66
71
  if (fetchKey) {
@@ -73,7 +78,7 @@ var DetailPanel = memo((props) => {
73
78
  return /* @__PURE__ */ jsx("div", {
74
79
  className: "detail-panel",
75
80
  children: /* @__PURE__ */ jsx(Drawer, {
76
- title: getText(config?.title ?? ""),
81
+ title: text(config?.title ?? ""),
77
82
  open,
78
83
  onClose: () => {
79
84
  setOpen(false);
@@ -93,7 +98,7 @@ var DetailPanel = memo((props) => {
93
98
  }, field.key))
94
99
  }) : /* @__PURE__ */ jsx("div", {
95
100
  className: "py-8 text-center text-sm text-muted-foreground",
96
- children: getText(frontendLangKeys.noData)
101
+ children: text(frontendLangKeys.noData)
97
102
  })
98
103
  })
99
104
  });
@@ -1,9 +1,9 @@
1
1
  import { frontendLangKeys } from "../../../../language/index.js";
2
- import { getText } from "../../../../common/language.js";
3
2
  import { Modal } from "../../../../../../packages/react/ui/components/Modal/Modal.js";
4
3
  import { SchemaForm } from "../../../../../../packages/react/ui/components/Form/SchemaForm/index.js";
5
4
  import "../../../../../../packages/react/ui/components/index.js";
6
5
  import { post, put, request } from "../../../../common/request.js";
6
+ import { useText } from "../../../../hooks/useText.js";
7
7
  import { schemaEventBus } from "../../../../stores/schemaEventBus.js";
8
8
  import { handlingRequestErrors } from "../../../../common/fetchErrorShow.js";
9
9
  import useExecuteOnce from "../../../../../../packages/react/hooks/useExecuteOnce.js";
@@ -14,7 +14,7 @@ import { createAjvValidator } from "../../utils/validator.js";
14
14
  import { memo, useCallback, useMemo, useRef, useState } from "react";
15
15
  import { jsx } from "react/jsx-runtime";
16
16
  //#region frontend/src/defaultPages/SchemaPage/components/CallCom/PopFrom.tsx
17
- var generateSchemas = (schema) => {
17
+ var generateSchemas = (schema, text) => {
18
18
  if (!schema?.properties) return [];
19
19
  return Object.keys(schema.properties).reduce((schemas, key) => {
20
20
  const fieldInfo = schema.properties[key];
@@ -23,12 +23,12 @@ var generateSchemas = (schema) => {
23
23
  const { comType = "input", default: _defaultValue, visible: _visible, ...fieldProps } = option;
24
24
  schemas.push({
25
25
  key,
26
- label: getText(fieldInfo.label),
26
+ label: text(fieldInfo.label),
27
27
  type: comType,
28
28
  required: schema.required?.includes(key),
29
29
  rules: [...schema.required?.includes(key) ? [{
30
30
  required: true,
31
- message: getText(frontendLangKeys.requiredInput, { label: getText(fieldInfo.label) })
31
+ message: text(frontendLangKeys.requiredInput, { label: text(fieldInfo.label) })
32
32
  }] : [], { validator: createAjvValidator(fieldInfo, { required: schema.required?.includes(key) }) }],
33
33
  fieldProps: {
34
34
  ...fieldProps,
@@ -48,6 +48,7 @@ var generateDefaultValue = (schema, data) => {
48
48
  return defaultValue;
49
49
  };
50
50
  var PopForm = memo((props) => {
51
+ const text = useText();
51
52
  const [open, setOpen] = useState(true);
52
53
  const [submitting, setSubmitting] = useState(false);
53
54
  const { schema, config, api } = useComConfig({ comName: props.comName });
@@ -64,8 +65,8 @@ var PopForm = memo((props) => {
64
65
  *
65
66
  */
66
67
  const schemas = useMemo(() => {
67
- return generateSchemas(schema);
68
- }, [schema]);
68
+ return generateSchemas(schema, text);
69
+ }, [schema, text]);
69
70
  const closed = submitting ? void 0 : () => {
70
71
  schemaEventBus.getState().emitCom({ type: merge(eventsInfo.closeCom) });
71
72
  setOpen(false);
@@ -98,7 +99,7 @@ var PopForm = memo((props) => {
98
99
  return /* @__PURE__ */ jsx(Modal, {
99
100
  open,
100
101
  onClose: closed,
101
- title: getText(config?.title ?? ""),
102
+ title: text(config?.title ?? ""),
102
103
  width: 640,
103
104
  maskClosable: !submitting,
104
105
  children: /* @__PURE__ */ jsx(SchemaForm, {
@@ -1,14 +1,13 @@
1
- import { getText } from "../../../../common/language.js";
2
1
  import TableSearch from "../../../../../../packages/react/ui/components/TableSearch/TableSearch.js";
3
2
  import "../../../../../../packages/react/ui/components/index.js";
4
- import useInit from "../../../../../../packages/react/hooks/useInit.js";
3
+ import { useText } from "../../../../hooks/useText.js";
5
4
  import { schemaEventBus } from "../../../../stores/schemaEventBus.js";
6
5
  import { filterEmpty } from "../../../../../../packages/common/object/filterEmpty.js";
7
6
  import { useSchemaStore } from "../../../../stores/schemaStore.js";
8
- import { memo, useState } from "react";
7
+ import { memo, useMemo } from "react";
9
8
  import { jsx } from "react/jsx-runtime";
10
9
  //#region frontend/src/defaultPages/SchemaPage/components/SchemaSearch/index.tsx
11
- var generateSchemas = (config) => {
10
+ var generateSchemas = (config, text) => {
12
11
  const keys = Object.keys(config);
13
12
  const schemas = [];
14
13
  let defaultValue = void 0;
@@ -21,7 +20,7 @@ var generateSchemas = (config) => {
21
20
  defaultValue[k] = defaultFieldValue;
22
21
  }
23
22
  schemas.push({
24
- label: getText(fieldInfo.label),
23
+ label: text(fieldInfo.label),
25
24
  key: k,
26
25
  type: comType,
27
26
  fieldProps
@@ -34,14 +33,9 @@ var generateSchemas = (config) => {
34
33
  };
35
34
  };
36
35
  var SchemaSearch = memo(() => {
36
+ const text = useText();
37
37
  const schema = useSchemaStore((s) => s.searchSchema);
38
- const [schemas, setSchemas] = useState([]);
39
- const [defaultValue, setSchemaDefaultValue] = useState(void 0);
40
- useInit(() => {
41
- const { schemas, defaultValue } = generateSchemas(schema.properties);
42
- setSchemas(schemas);
43
- setSchemaDefaultValue(defaultValue);
44
- });
38
+ const { schemas, defaultValue } = useMemo(() => generateSchemas(schema.properties, text), [schema, text]);
45
39
  const tsProps = {
46
40
  schemas,
47
41
  defaultValue,
@@ -1,11 +1,10 @@
1
1
  import { frontendLangKeys } from "../../../../language/index.js";
2
- import { getText } from "../../../../common/language.js";
3
2
  import { Button } from "../../../../../../packages/react/ui/components/Button/Button.js";
4
3
  import { modal } from "../../../../../../packages/react/ui/components/Modal/ModalManager.js";
5
4
  import { DataTable } from "../../../../../../packages/react/ui/components/DataTable/index.js";
6
5
  import "../../../../../../packages/react/ui/components/index.js";
7
6
  import { del, get } from "../../../../common/request.js";
8
- import useInit from "../../../../../../packages/react/hooks/useInit.js";
7
+ import { useText } from "../../../../hooks/useText.js";
9
8
  import { schemaEventBus } from "../../../../stores/schemaEventBus.js";
10
9
  import { useSchemaStore } from "../../../../stores/schemaStore.js";
11
10
  import { handlingRequestErrors } from "../../../../common/fetchErrorShow.js";
@@ -21,7 +20,7 @@ import { useShallow } from "zustand/react/shallow";
21
20
  import { produce } from "immer";
22
21
  //#region frontend/src/defaultPages/SchemaPage/components/SchemaTable/index.tsx
23
22
  var VALUE_KEY = "$schema::";
24
- var generateColumns = (config) => {
23
+ var generateColumns = (config, text) => {
25
24
  const keys = Object.keys(config);
26
25
  const columns = [];
27
26
  keys.forEach((k) => {
@@ -29,7 +28,7 @@ var generateColumns = (config) => {
29
28
  if (fieldInfo?.option) {
30
29
  const { render: customRender, renderComponent, renderComponentProps, ...fieldProps } = fieldInfo.option;
31
30
  columns.push({
32
- title: getText(fieldInfo.label),
31
+ title: text(fieldInfo.label),
33
32
  key: k,
34
33
  ...fieldProps,
35
34
  render(v, d, index) {
@@ -53,7 +52,7 @@ var generateColumns = (config) => {
53
52
  });
54
53
  return columns;
55
54
  };
56
- var generateRowActions = (btnConfigs, rowData, api) => {
55
+ var generateRowActions = (btnConfigs, rowData, text, api) => {
57
56
  const handleRowAction = (btnConfig) => {
58
57
  const { eventKey, eventOption } = btnConfig;
59
58
  switch (eventKey) {
@@ -72,7 +71,7 @@ var generateRowActions = (btnConfigs, rowData, api) => {
72
71
  return o;
73
72
  }, {});
74
73
  modal.confirm({
75
- content: getText(frontendLangKeys.confirmDelete),
74
+ content: text(frontendLangKeys.confirmDelete),
76
75
  async onOk() {
77
76
  await handlingRequestErrors(del(api, apiParams));
78
77
  schemaEventBus.getState().emitCom({ type: merge(eventsInfo.initTable) });
@@ -85,7 +84,7 @@ var generateRowActions = (btnConfigs, rowData, api) => {
85
84
  }
86
85
  };
87
86
  return btnConfigs.map((rb, index) => {
88
- const label = getText(rb.label ?? "");
87
+ const label = text(rb.label ?? "");
89
88
  const bState = rb.eventKey === "remove" ? "danger" : void 0;
90
89
  return { render: (_item, { close }) => /* @__PURE__ */ jsx("div", {
91
90
  className: " p-2.5",
@@ -102,20 +101,19 @@ var generateRowActions = (btnConfigs, rowData, api) => {
102
101
  });
103
102
  };
104
103
  var SchemaTable = memo(({ ref }) => {
104
+ const text = useText();
105
105
  const params = useSchemaStore(useShallow((s) => ({
106
106
  config: s.tableConfig,
107
107
  schema: s.tableSchema,
108
108
  api: s.api
109
109
  })));
110
110
  const [data, uData] = useState([]);
111
- const [columns, uColumns] = useState([]);
112
111
  const [loading, uLoading, loadingRef] = useRefState(false, 25);
113
112
  const [pagination, setPagination, paginationRef] = useRefState({
114
113
  current: 1,
115
114
  pageSize: 10,
116
115
  total: 0
117
116
  });
118
- const [handleBtn, setHandleBtn] = useState([]);
119
117
  const init = useCallback(async (query) => {
120
118
  if (loadingRef.current.data) return;
121
119
  uLoading(true);
@@ -143,29 +141,38 @@ var SchemaTable = memo(({ ref }) => {
143
141
  useImperativeHandle(ref, () => {
144
142
  return { initData: init };
145
143
  }, [init]);
146
- useInit(() => {
147
- const contextColumns = generateColumns(params.schema.properties);
144
+ const { columns, handleBtn } = useMemo(() => {
145
+ const contextColumns = generateColumns(params.schema.properties, text);
148
146
  const actionColumn = [];
147
+ let handleBtn = [];
149
148
  if (params.config) {
150
149
  const { rowButtons, headerButtons } = params.config;
151
150
  if (rowButtons) actionColumn.push({
152
151
  key: "action",
153
- title: getText(frontendLangKeys.operation),
154
- actions: (_value, _record, index) => [...generateRowActions(rowButtons, _record, params.api)]
152
+ title: text(frontendLangKeys.operation),
153
+ actions: (_value, _record, index) => [...generateRowActions(rowButtons, _record, text, params.api)]
155
154
  });
156
- setHandleBtn(headerButtons?.map((c) => {
155
+ handleBtn = headerButtons?.map((c) => {
157
156
  const { label, eventKey, eventOption, ...props } = c;
158
157
  return {
159
- children: getText(label ?? ""),
158
+ children: text(label ?? ""),
160
159
  onClick: () => {
161
160
  if ("comName" in eventOption) schemaEventBus.getState().emitTable(eventOption);
162
161
  },
163
162
  ...props
164
163
  };
165
- }) ?? []);
164
+ }) ?? [];
166
165
  }
167
- uColumns(contextColumns.concat(actionColumn));
168
- });
166
+ return {
167
+ columns: contextColumns.concat(actionColumn),
168
+ handleBtn
169
+ };
170
+ }, [
171
+ params.api,
172
+ params.config,
173
+ params.schema,
174
+ text
175
+ ]);
169
176
  useExecuteOnce(() => {
170
177
  init();
171
178
  }, { executionPhase: "mount" });
@@ -1,6 +1,6 @@
1
1
  import "./index.css";
2
2
  import { frontendLangKeys } from "../../language/index.js";
3
- import { getText } from "../../common/language.js";
3
+ import { useText } from "../../hooks/useText.js";
4
4
  import useInit from "../../../../packages/react/hooks/useInit.js";
5
5
  import { logIllegalComponentCallback } from "../../common/logFn/index.js";
6
6
  import { schemaEventBus } from "../../stores/schemaEventBus.js";
@@ -19,6 +19,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
19
19
  //#region frontend/src/defaultPages/SchemaPage/index.tsx
20
20
  var Schema = memo(() => {
21
21
  const { menu } = useCurrentMenuData();
22
+ const text = useText();
22
23
  const [showCompoentKey, setShowCompoentKey] = useState();
23
24
  const [comProps, setComProps] = useState({});
24
25
  const schemaStoreAvailable = useSchemaStore((s) => s.schemaStoreAvailable);
@@ -77,12 +78,13 @@ var Schema = memo(() => {
77
78
  });
78
79
  } else return /* @__PURE__ */ jsx("div", {
79
80
  className: "flex h-full items-center justify-center text-sm text-muted-foreground",
80
- children: getText(frontendLangKeys.loading)
81
+ children: text(frontendLangKeys.loading)
81
82
  });
82
83
  }, [
83
84
  comProps,
84
85
  schemaStoreAvailable,
85
- showCompoentKey
86
+ showCompoentKey,
87
+ text
86
88
  ]);
87
89
  });
88
90
  Schema.displayName = "SchemaPage";
@@ -1,16 +1,18 @@
1
1
  import { generateMenuItemData } from "../common/generateMenuData.js";
2
2
  import { useModeStore } from "../stores/mode.js";
3
3
  import { leftSidebarBasePath } from "../common/menu.js";
4
+ import { useText } from "../hooks/useText.js";
4
5
  import SidebarSlotContainer from "./SidebarSlotPage/SidebarSlotContainer.js";
5
6
  import { useMemo } from "react";
6
7
  import { jsx } from "react/jsx-runtime";
7
8
  //#region frontend/src/defaultPages/SidebarSlotPageTmp.tsx
8
9
  var SidebarSlotPageTmp = () => {
9
10
  const projInfo = useModeStore((s) => s.projectInfo);
11
+ const text = useText();
10
12
  const [menuItems, rawMenuData] = useMemo(() => {
11
- if (projInfo) return [generateMenuItemData(projInfo.menu), projInfo.menu];
13
+ if (projInfo) return [generateMenuItemData(projInfo.menu, text), projInfo.menu];
12
14
  return [[], []];
13
- }, [projInfo]);
15
+ }, [projInfo, text]);
14
16
  return /* @__PURE__ */ jsx(SidebarSlotContainer, {
15
17
  prefixPath: "/" + leftSidebarBasePath,
16
18
  rawMenuData,
@@ -0,0 +1,3 @@
1
+ import type { I18nInterpolationValues, I18nTranslateOptions } from "../../../packages/react/ui/i18n/index";
2
+ export type TextTranslator = <T = string>(key: string, fillingData?: I18nInterpolationValues, options?: I18nTranslateOptions) => T | string;
3
+ export declare const useText: () => TextTranslator;
@@ -0,0 +1,14 @@
1
+ import { i18nKeyPrefix } from "../language/index.js";
2
+ import { useI18n } from "../../../packages/react/ui/i18n/useI18n.js";
3
+ import "../../../packages/react/ui/i18n/index.js";
4
+ import { useCallback } from "react";
5
+ //#region frontend/src/hooks/useText.ts
6
+ var useText = () => {
7
+ const translate = useI18n();
8
+ return useCallback((key, fillingData, options) => {
9
+ if (key.startsWith("$i18n::")) return translate(key.slice(i18nKeyPrefix.length), fillingData, options);
10
+ return translate(key, fillingData, options);
11
+ }, [translate]);
12
+ };
13
+ //#endregion
14
+ export { useText };
@@ -16,5 +16,6 @@ export { clearAuthToken, getAuthToken, localKeyMap, setAuthToken } from "./commo
16
16
  export * from "./common/language";
17
17
  export * from "./defaultPages/SchemaPage/data/eventInfo";
18
18
  export { merge } from "./defaultPages/SchemaPage/utils/permissions";
19
+ export { useText, type TextTranslator } from "./hooks/useText";
19
20
  export * from "./exportStore";
20
21
  export { i18n, i18nStore } from "../../packages/react/ui/i18n/index";
@@ -1,11 +1,12 @@
1
1
  import { clearAuthToken, getAuthToken, localKeyMap, setAuthToken } from "./common/auth/index.js";
2
2
  import { i18n, i18nStore } from "../../packages/common/i18n/index.js";
3
3
  import "../../packages/react/ui/i18n/index.js";
4
- import { addLanguage, addLanguageResources, addResources, getCurrentLanguage, getFallbackLanguage, getI18nResources, getSupportedLanguages, getText, setFallbackLanguage, setLanguage, setResources, t } from "./common/language.js";
4
+ import { addLanguageResources, getCurrentLanguage, getFallbackLanguage, getI18nResources, getSupportedLanguages, getText, registerFrontendI18nResources, setFallbackLanguage, setLanguage, setResources, t } from "./common/language.js";
5
5
  import { FreezeState, apiFreezerStore, useApiFreezer } from "./stores/apiFreezer.js";
6
6
  import FetchAxios from "../../packages/common/http/index.js";
7
7
  import { api, del, get, patch, post, put, request } from "./common/request.js";
8
8
  import { modeStore, useModeStore } from "./stores/mode.js";
9
+ import { useText } from "./hooks/useText.js";
9
10
  import HeaderView from "./components/BasePage/HeaderView.js";
10
11
  import { renderImportComponent } from "./common/importComponent.js";
11
12
  import { applyThemeMode, getCurrentThemeMode, getStoredThemeMode, initThemeMode, persistThemeMode, themeSwitchStorageKey } from "./common/theme.js";
@@ -21,4 +22,4 @@ import ThemeSwitch_default from "./components/ThemeSwitch/index.js";
21
22
  import "./components/index.js";
22
23
  import { eventsInfo } from "./defaultPages/SchemaPage/data/eventInfo.js";
23
24
  import { merge } from "./defaultPages/SchemaPage/utils/permissions.js";
24
- export { AsyncSelect_default as AsyncSelect, FetchAxios, FreezeState, HeaderView, LanguageSwitch_default as LanguageSwitch, ThemeSwitch_default as ThemeSwitch, addLanguage, addLanguageResources, addResources, api, apiFreezerStore, applyThemeMode, clearAuthToken, clearRafTimer, del, eventsInfo, generateRouter, get, getAuthToken, getCurrentLanguage, getCurrentThemeMode, getFallbackLanguage, getI18nResources, getStoredThemeMode, getSupportedLanguages, getText, i18n, i18nStore, initApp, initThemeMode, localKeyMap, merge, modeStore, patch, persistThemeMode, post, put, rafClearInterval, rafClearTimeout, rafSetInterval, rafSetTimeout, renderImportComponent, request, schemaEventBus, schemaStore, setAuthToken, setFallbackLanguage, setLanguage, setResources, t, themeSwitchStorageKey, useApiFreezer, useModeStore, useSchemaStore };
25
+ export { AsyncSelect_default as AsyncSelect, FetchAxios, FreezeState, HeaderView, LanguageSwitch_default as LanguageSwitch, ThemeSwitch_default as ThemeSwitch, addLanguageResources, api, apiFreezerStore, applyThemeMode, clearAuthToken, clearRafTimer, del, eventsInfo, generateRouter, get, getAuthToken, getCurrentLanguage, getCurrentThemeMode, getFallbackLanguage, getI18nResources, getStoredThemeMode, getSupportedLanguages, getText, i18n, i18nStore, initApp, initThemeMode, localKeyMap, merge, modeStore, patch, persistThemeMode, post, put, rafClearInterval, rafClearTimeout, rafSetInterval, rafSetTimeout, registerFrontendI18nResources, renderImportComponent, request, schemaEventBus, schemaStore, setAuthToken, setFallbackLanguage, setLanguage, setResources, t, themeSwitchStorageKey, useApiFreezer, useModeStore, useSchemaStore, useText };
@@ -1,6 +1,4 @@
1
- import type { I18nResources } from "../../../packages/react/ui/i18n/index";
2
1
  export declare const i18nKeyPrefix = "$i18n::";
3
- export declare const frontendI18nResources: I18nResources;
4
2
  export declare const withI18nKey: (key: string) => string;
5
3
  export declare const frontendLangKeys: {
6
4
  readonly appTitle: string;
@@ -1,11 +1,5 @@
1
- import { frontendEnUSResources } from "./en-US.js";
2
- import { frontendZhCNResources } from "./zh-CN.js";
3
1
  //#region frontend/src/language/index.ts
4
2
  var i18nKeyPrefix = "$i18n::";
5
- var frontendI18nResources = {
6
- "zh-CN": frontendZhCNResources,
7
- "en-US": frontendEnUSResources
8
- };
9
3
  var withI18nKey = (key) => `${i18nKeyPrefix}${key}`;
10
4
  var frontendLangKeys = {
11
5
  appTitle: withI18nKey("frontend.app.title"),
@@ -76,4 +70,4 @@ var frontendLangKeys = {
76
70
  logApiTamperEn: withI18nKey("frontend.log.apiTamperEn")
77
71
  };
78
72
  //#endregion
79
- export { frontendI18nResources, frontendLangKeys, i18nKeyPrefix, withI18nKey };
73
+ export { frontendLangKeys, i18nKeyPrefix, withI18nKey };
@@ -0,0 +1,2 @@
1
+ import type { I18nResources } from "../../../packages/react/ui/i18n/index";
2
+ export declare const frontendI18nResources: I18nResources;
@@ -0,0 +1,9 @@
1
+ import { frontendEnUSResources } from "./en-US.js";
2
+ import { frontendZhCNResources } from "./zh-CN.js";
3
+ //#region frontend/src/language/resources.ts
4
+ var frontendI18nResources = {
5
+ "zh-CN": frontendZhCNResources,
6
+ "en-US": frontendEnUSResources
7
+ };
8
+ //#endregion
9
+ export { frontendI18nResources };
@@ -7,6 +7,21 @@ export declare const defaultLanguageResources: {
7
7
  readonly submit: "提交";
8
8
  readonly reset: "重置";
9
9
  };
10
+ readonly server: {
11
+ readonly errors: {
12
+ readonly network: "网络错误";
13
+ readonly invalidRequest: "请求不合法";
14
+ readonly getProjectFailed: "获取项目异常";
15
+ readonly dbNodeSqliteUnavailable: "[db] 默认数据库依赖 Node.js 内置 {sqliteSpecifier},当前运行环境不可用。请升级 Node.js,或在业务项目覆盖 app/extends/db.ts。{cause}";
16
+ readonly dbDatabaseSyncUnavailable: "[db] {sqliteSpecifier} 未提供 DatabaseSync,无法初始化默认 SQLite 数据库。";
17
+ readonly dbNamespaceRequired: "[db] namespace 不能为空";
18
+ readonly dbKeyRequired: "[db] key 不能为空";
19
+ readonly dbLimitInvalid: "[db] limit 必须是大于 0 的整数";
20
+ readonly dbOffsetInvalid: "[db] offset 必须是大于等于 0 的整数";
21
+ readonly dbValueNotSerializable: "[db] value 必须可以被 JSON.stringify 序列化。{cause}";
22
+ readonly dbClosed: "[db] SQLite 数据库连接已关闭";
23
+ };
24
+ };
10
25
  readonly components: {
11
26
  readonly breadcrumb: {
12
27
  readonly close: "关闭";
@@ -5,6 +5,7 @@
5
5
  * 这里只放组件内置文案,业务项目可以通过 I18nProvider.resources 覆盖或追加。
6
6
  */
7
7
  var defaultLanguageResources = {
8
+ /** 通用操作文案。 */
8
9
  common: {
9
10
  tip: "提示",
10
11
  confirm: "确认",
@@ -13,6 +14,20 @@ var defaultLanguageResources = {
13
14
  submit: "提交",
14
15
  reset: "重置"
15
16
  },
17
+ server: { errors: {
18
+ network: "网络错误",
19
+ invalidRequest: "请求不合法",
20
+ getProjectFailed: "获取项目异常",
21
+ dbNodeSqliteUnavailable: "[db] 默认数据库依赖 Node.js 内置 {sqliteSpecifier},当前运行环境不可用。请升级 Node.js,或在业务项目覆盖 app/extends/db.ts。{cause}",
22
+ dbDatabaseSyncUnavailable: "[db] {sqliteSpecifier} 未提供 DatabaseSync,无法初始化默认 SQLite 数据库。",
23
+ dbNamespaceRequired: "[db] namespace 不能为空",
24
+ dbKeyRequired: "[db] key 不能为空",
25
+ dbLimitInvalid: "[db] limit 必须是大于 0 的整数",
26
+ dbOffsetInvalid: "[db] offset 必须是大于等于 0 的整数",
27
+ dbValueNotSerializable: "[db] value 必须可以被 JSON.stringify 序列化。{cause}",
28
+ dbClosed: "[db] SQLite 数据库连接已关闭"
29
+ } },
30
+ /** UI 组件内置文案,按组件名分组。 */
16
31
  components: {
17
32
  breadcrumb: { close: "关闭" },
18
33
  confirmDialog: {
@@ -64,6 +79,7 @@ var defaultLanguageResources = {
64
79
  rotateRight: "右旋转",
65
80
  flipHorizontal: "左右镜像",
66
81
  flipVertical: "上下镜像",
82
+ /** {index} 会在运行时由调用方传入的插值数据替换。 */
67
83
  previewImage: "预览第{index}张"
68
84
  },
69
85
  modal: {