@arronqzy/vue-view 0.1.0 → 0.1.3

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 (48) hide show
  1. package/package.json +10 -7
  2. package/src/panel/VueViewOnlinePreview.vue +15 -7
  3. package/src/panel/VueViewPanel.vue +81 -55
  4. package/src/panel/components/ConfigHintIcon.vue +4 -2
  5. package/src/panel/components/ElementsLayer.vue +15 -0
  6. package/src/panel/components/MaterialPreview.vue +19 -1
  7. package/src/panel/components/MaterialSidebar.vue +35 -31
  8. package/src/panel/components/MaterialSidebarTreeNode.vue +27 -26
  9. package/src/panel/components/MoveableLayer.vue +7 -4
  10. package/src/panel/components/PanelConfigSidebar.vue +57 -39
  11. package/src/panel/components/ViewElementScopePanel.vue +6 -4
  12. package/src/panel/components/WorkspaceConfigSidebar.vue +7 -1
  13. package/src/panel/components/WorkspaceProjectNav.vue +23 -16
  14. package/src/panel/components/WorkspaceStageSplit.vue +10 -7
  15. package/src/panel/components/config/ConfigColorField.vue +3 -1
  16. package/src/panel/components/config/PanelConfigAudioSection.vue +44 -43
  17. package/src/panel/components/config/PanelConfigChartSection.vue +79 -76
  18. package/src/panel/components/config/PanelConfigGeometrySection.vue +21 -19
  19. package/src/panel/components/config/PanelConfigGridChildSpan.vue +7 -5
  20. package/src/panel/components/config/PanelConfigGridSection.vue +10 -8
  21. package/src/panel/components/config/PanelConfigImageSection.vue +22 -21
  22. package/src/panel/components/config/PanelConfigMultiSelect.vue +42 -40
  23. package/src/panel/components/config/PanelConfigNodeInfo.vue +19 -16
  24. package/src/panel/components/config/PanelConfigReferenceSection.vue +11 -9
  25. package/src/panel/components/config/PanelConfigStyleSections.vue +27 -26
  26. package/src/panel/components/config/PanelConfigTextSection.vue +20 -17
  27. package/src/panel/components/config/PanelConfigVideoSection.vue +15 -14
  28. package/src/panel/components/config/shared.ts +0 -3
  29. package/src/panel/components/elementsLayerNodes.ts +37 -18
  30. package/src/panel/components/materialSidebarData.ts +73 -54
  31. package/src/panel/components/scope-config/ScopeTemplatePreviewHost.vue +7 -2
  32. package/src/panel/components/scope-config/ScopeTemplatePreviewPanel.vue +6 -3
  33. package/src/panel/components/scope-config/ScopeTemplateUsageHint.vue +7 -16
  34. package/src/panel/components/scope-config/ScopeTemplateWarningsPanel.vue +4 -2
  35. package/src/panel/components/table/ConditionEditor.vue +181 -0
  36. package/src/panel/components/table/JsonCodeEditor.vue +148 -0
  37. package/src/panel/components/table/PanelConfigTableSection.vue +2033 -0
  38. package/src/panel/components/table/TableNodeContent.vue +557 -0
  39. package/src/panel/constants/messages.ts +76 -34
  40. package/src/panel/hooks/usePanelElements.ts +54 -41
  41. package/src/panel/hooks/useWorkspaceProjects.ts +8 -5
  42. package/src/panel/types.ts +4 -0
  43. package/src/panel/utils/panelElementDefaults.ts +73 -39
  44. package/src/panel/utils/scope-field-labels.ts +53 -39
  45. package/src/panel/utils/scope-template-spread.ts +57 -24
  46. package/src/panel/utils/scope-template-warnings.ts +23 -22
  47. package/src/panel/utils/scope-template.ts +80 -0
  48. package/src/tailwind.css +18 -10
@@ -1,6 +1,7 @@
1
1
  import { computed, onMounted } from "vue";
2
2
  import { store, type Node, type State } from "@arronqzy/rx-store";
3
3
  import { useStoreRef } from "@arronqzy/vue-rx-store";
4
+ import { useI18nOptional } from "@arronqzy/i18n/vue";
4
5
  import type {
5
6
  PanelActionResult,
6
7
  PanelElement,
@@ -8,6 +9,7 @@ import type {
8
9
  PanelLayer,
9
10
  ReferenceCopyMode,
10
11
  } from "../types";
12
+ import { getPanelMessages } from "../constants/messages";
11
13
  import {
12
14
  DEFAULT_LAYER,
13
15
  DEFAULT_LAYER_ID,
@@ -15,6 +17,7 @@ import {
15
17
  getDefaultGridConfig,
16
18
  getDefaultNodeName,
17
19
  getDefaultSizeByMaterial,
20
+ getDefaultTableConfig,
18
21
  getDefaultTextContent,
19
22
  normalizePrimaryLayer,
20
23
  randomId,
@@ -44,34 +47,39 @@ import {
44
47
 
45
48
  export type { PanelActionResult, PanelHistoryItem, PanelLayer } from "../types";
46
49
 
47
- const HISTORY_LABEL_BY_TYPE: Record<string, string> = {
48
- initial: "初始化",
49
- "node.update": "更新节点",
50
- "node.group-drag": "批量移动节点",
51
- "node.group-resize": "批量缩放节点",
52
- "node.group-rotate": "批量旋转节点",
53
- "node.delete": "删除节点",
54
- "node.batch-delete": "批量删除节点",
55
- "node.z.front": "节点置顶",
56
- "node.z.back": "节点置底",
57
- "node.z.up": "节点上移一层",
58
- "node.z.down": "节点下移一层",
59
- "node.duplicate": "复制节点",
60
- "node.ref-copy-mode": "设置引用拷贝模式",
61
- "node.add": "添加节点",
62
- "layer.activate": "切换图层",
63
- "layer.add": "新增图层",
64
- "layer.rename": "重命名图层",
65
- "layer.toggle-lock": "切换图层锁定",
66
- "layer.open-selected-mapping": "映射图层打开选中节点",
67
- "layer.delete": "删除图层",
68
- "layer.toggle-merge": "勾选合并图层",
69
- "layer.merge": "合并图层",
70
- "layer.set-primary": "设置主图层",
71
- "panel.import": "导入面板",
50
+ const HISTORY_LABEL_KEYS: Record<string, string> = {
51
+ initial: "panel.history.initial",
52
+ "node.update": "panel.history.nodeUpdate",
53
+ "node.group-drag": "panel.history.nodeGroupDrag",
54
+ "node.group-resize": "panel.history.nodeGroupResize",
55
+ "node.group-rotate": "panel.history.nodeGroupRotate",
56
+ "node.delete": "panel.history.nodeDelete",
57
+ "node.batch-delete": "panel.history.nodeBatchDelete",
58
+ "node.z.front": "panel.history.nodeZFront",
59
+ "node.z.back": "panel.history.nodeZBack",
60
+ "node.z.up": "panel.history.nodeZUp",
61
+ "node.z.down": "panel.history.nodeZDown",
62
+ "node.duplicate": "panel.history.nodeDuplicate",
63
+ "node.ref-copy-mode": "panel.history.nodeRefCopyMode",
64
+ "node.add": "panel.history.nodeAdd",
65
+ "layer.activate": "panel.history.layerActivate",
66
+ "layer.add": "panel.history.layerAdd",
67
+ "layer.rename": "panel.history.layerRename",
68
+ "layer.toggle-lock": "panel.history.layerToggleLock",
69
+ "layer.open-selected-mapping": "panel.history.layerOpenSelectedMapping",
70
+ "layer.delete": "panel.history.layerDelete",
71
+ "layer.toggle-merge": "panel.history.layerToggleMerge",
72
+ "layer.merge": "panel.history.layerMerge",
73
+ "layer.set-primary": "panel.history.layerSetPrimary",
74
+ "panel.import": "panel.history.panelImport",
72
75
  };
73
76
 
74
77
  export function usePanelElements() {
78
+ const { t, locale } = useI18nOptional();
79
+ const messages = computed(() => {
80
+ void locale.value;
81
+ return getPanelMessages(t);
82
+ });
75
83
  const stateRef = useStoreRef();
76
84
 
77
85
  onMounted(() => {
@@ -165,7 +173,7 @@ export function usePanelElements() {
165
173
  return {
166
174
  index,
167
175
  timestamp: entry.timestamp,
168
- label: (type && HISTORY_LABEL_BY_TYPE[type]) || "编辑",
176
+ label: (type && HISTORY_LABEL_KEYS[type] ? t(HISTORY_LABEL_KEYS[type]) : t("panel.history.fallback")),
169
177
  active: index === cursor,
170
178
  };
171
179
  });
@@ -596,11 +604,12 @@ export function usePanelElements() {
596
604
  layerId: currentLayerId,
597
605
  zIndex: 1,
598
606
  materialType,
599
- name: getDefaultNodeName(materialType),
600
- ...getDefaultTextContent(materialType),
607
+ name: getDefaultNodeName(materialType, t),
608
+ ...getDefaultTextContent(materialType, t),
601
609
  ...getDefaultGridConfig(materialType),
602
610
  refCopyMode: materialType === "reference" ? "shallow" : undefined,
603
- chart: getDefaultChartConfig(materialType),
611
+ chart: getDefaultChartConfig(materialType, t),
612
+ table: getDefaultTableConfig(materialType, t),
604
613
  geometryShape: materialType === "geometry" ? "rect" : undefined,
605
614
  geometryColor: materialType === "geometry" ? "#3b82f6" : undefined,
606
615
  geometryScript: undefined,
@@ -738,7 +747,7 @@ export function usePanelElements() {
738
747
  const nextId = randomId("layer");
739
748
  const next: PanelLayer = {
740
749
  id: nextId,
741
- name: `图层${list.length + 1}`,
750
+ name: t("panel.defaults.layerN", { n: list.length + 1 }),
742
751
  locked: false,
743
752
  editable: true,
744
753
  isPrimary: false,
@@ -755,7 +764,7 @@ export function usePanelElements() {
755
764
 
756
765
  function openElementsInNewLayer(ids: string[]): PanelActionResult {
757
766
  const filtered = ids.filter(Boolean);
758
- if (filtered.length === 0) return { ok: false, reason: "未选择节点" };
767
+ if (filtered.length === 0) return { ok: false, reason: messages.value.noNodesSelected };
759
768
  const current = store.getState();
760
769
  const currentLayers =
761
770
  (current.variables?.layers as PanelLayer[] | undefined) ?? [DEFAULT_LAYER];
@@ -768,14 +777,14 @@ export function usePanelElements() {
768
777
  const selected = expandedIds
769
778
  .map((id) => nodeById.get(id))
770
779
  .filter((el): el is PanelElement => !!el);
771
- if (selected.length === 0) return { ok: false, reason: "未找到可迁移节点" };
780
+ if (selected.length === 0) return { ok: false, reason: messages.value.noMigratableNodes };
772
781
  const anchorEl = nodeById.get(filtered[0]!) ?? selected[0];
773
782
  const hasLocked = selected.some((el) => {
774
783
  if (el.locked) return true;
775
784
  const layer = currentLayers.find((l) => l.id === el.layerId);
776
785
  return !!layer?.locked;
777
786
  });
778
- if (hasLocked) return { ok: false, reason: "选中节点包含锁定内容,无法在新图层打开" };
787
+ if (hasLocked) return { ok: false, reason: messages.value.lockedCannotOpenMapping };
779
788
 
780
789
  const selectedSet = new Set(selected.map((el) => el.id));
781
790
  const idMap = new Map<string, string>();
@@ -783,7 +792,7 @@ export function usePanelElements() {
783
792
  const nextLayerId = randomId("layer");
784
793
  const nextLayer: PanelLayer = {
785
794
  id: nextLayerId,
786
- name: `映射图层${currentLayers.length + 1}`,
795
+ name: t("panel.defaults.mappingLayerN", { n: currentLayers.length + 1 }),
787
796
  locked: false,
788
797
  editable: true,
789
798
  isPrimary: false,
@@ -872,16 +881,16 @@ export function usePanelElements() {
872
881
  const current = store.getState();
873
882
  const list = (current.variables?.layers as PanelLayer[] | undefined) ?? [];
874
883
  const target = list.find((l) => l.id === layerId);
875
- if (!target) return { ok: false, reason: "图层不存在" };
876
- if (!target.editable) return { ok: false, reason: "默认图层不可删除" };
877
- if (target.locked) return { ok: false, reason: "锁定图层不可删除" };
884
+ if (!target) return { ok: false, reason: messages.value.layerNotFound };
885
+ if (!target.editable) return { ok: false, reason: messages.value.defaultLayerCannotDelete };
886
+ if (target.locked) return { ok: false, reason: messages.value.lockedLayerCannotDelete };
878
887
  if (mode === "move" && !targetLayerId) {
879
- return { ok: false, reason: "请选择目标图层" };
888
+ return { ok: false, reason: messages.value.selectTargetLayer };
880
889
  }
881
890
  const remainingLayers = list.filter((l) => l.id !== layerId);
882
891
  const moveTarget = remainingLayers.find((l) => l.id === targetLayerId);
883
892
  if (mode === "move" && !moveTarget) {
884
- return { ok: false, reason: "目标图层不存在" };
893
+ return { ok: false, reason: messages.value.targetLayerNotFound };
885
894
  }
886
895
  const allPanelElements = (current.root.children ?? [])
887
896
  .filter((n) => isPanelElementNode(n) && n.props)
@@ -895,7 +904,7 @@ export function usePanelElements() {
895
904
  return (el.refCopyMode ?? "shallow") !== "deep";
896
905
  });
897
906
  if (hasBlockingRef) {
898
- return { ok: false, reason: "该图层仍被浅拷贝引用,请先删除引用节点或改为深拷贝" };
907
+ return { ok: false, reason: messages.value.shallowRefBlockingDelete };
899
908
  }
900
909
 
901
910
  store.update(
@@ -959,7 +968,11 @@ export function usePanelElements() {
959
968
  const nextId = randomId("layer");
960
969
  const nextLayer: PanelLayer = {
961
970
  id: nextId,
962
- name: name?.trim() || `图层-${Math.random().toString(36).slice(2, 6)}`,
971
+ name:
972
+ name?.trim() ||
973
+ t("panel.defaults.layerRandom", {
974
+ id: Math.random().toString(36).slice(2, 6),
975
+ }),
963
976
  locked: false,
964
977
  editable: true,
965
978
  isPrimary: false,
@@ -5,6 +5,7 @@ import {
5
5
  type BlueprintMetaDraft,
6
6
  } from "@arronqzy/vue-blueprint";
7
7
  import type { State } from "@arronqzy/rx-store";
8
+ import { useI18nOptional } from "@arronqzy/i18n/vue";
8
9
  import {
9
10
  createWorkspaceProjectId,
10
11
  deleteWorkspaceProject,
@@ -53,13 +54,15 @@ export function buildOnlinePreviewUrl(projectId: string): string {
53
54
  }
54
55
 
55
56
  export function useWorkspaceProjects(options: UseWorkspaceProjectsOptions) {
57
+ const { t, locale } = useI18nOptional();
56
58
  const projects = ref<WorkspaceProjectListItem[]>([]);
57
59
  const activeProjectId = ref<string | null>(null);
58
60
  const activeProjectName = ref<string | null>(null);
59
61
  const syncedSnapshotRef = shallowRef<WorkspaceSnapshot | null>(null);
60
62
 
61
63
  function resolveProjectName() {
62
- return toValue(options.productName).trim() || "未命名产物";
64
+ void locale.value;
65
+ return toValue(options.productName).trim() || t("panel.defaults.unnamedProduct");
63
66
  }
64
67
 
65
68
  function buildCurrentSnapshot(): WorkspaceSnapshot {
@@ -94,7 +97,7 @@ export function useWorkspaceProjects(options: UseWorkspaceProjectsOptions) {
94
97
  const blueprintDocument =
95
98
  record.blueprintDocument ?? BlueprintGraph.empty().document;
96
99
  const blueprintMeta: BlueprintMetaDraft = {
97
- name: record.blueprintMeta?.name ?? "未命名蓝图",
100
+ name: record.blueprintMeta?.name ?? t("panel.defaults.unnamedBlueprint"),
98
101
  remark: record.blueprintMeta?.remark ?? "",
99
102
  };
100
103
 
@@ -176,14 +179,14 @@ export function useWorkspaceProjects(options: UseWorkspaceProjectsOptions) {
176
179
  const record = await getWorkspaceProject(id);
177
180
  if (!record) {
178
181
  await refreshProjects();
179
- throw new Error("工作区不存在或已被删除");
182
+ throw new Error(t("panel.messages.workspaceNotFound"));
180
183
  }
181
184
  applyProjectRecord(record);
182
185
  }
183
186
 
184
187
  async function handleSyncProject() {
185
188
  if (!activeProjectId.value) {
186
- throw new Error("请先保存工作区");
189
+ throw new Error(t("panel.messages.saveWorkspaceFirst"));
187
190
  }
188
191
  const existing = await getWorkspaceProject(activeProjectId.value);
189
192
  if (!existing) {
@@ -191,7 +194,7 @@ export function useWorkspaceProjects(options: UseWorkspaceProjectsOptions) {
191
194
  activeProjectName.value = null;
192
195
  syncedSnapshotRef.value = null;
193
196
  await refreshProjects();
194
- throw new Error("工作区不存在或已被删除");
197
+ throw new Error(t("panel.messages.workspaceNotFound"));
195
198
  }
196
199
  const name = resolveProjectName() || existing.name;
197
200
  await persistProject({
@@ -54,6 +54,9 @@ export type PanelElementStyle = {
54
54
 
55
55
  export type ReferenceCopyMode = "shallow" | "deep";
56
56
 
57
+ export type { PanelTableConfig } from "@arronqzy/view-table";
58
+ import type { PanelTableConfig } from "@arronqzy/view-table";
59
+
57
60
  export type PanelElement = {
58
61
  id: string;
59
62
  layerId: string;
@@ -65,6 +68,7 @@ export type PanelElement = {
65
68
  refCopyMode?: ReferenceCopyMode;
66
69
  refSnapshot?: PanelElement[];
67
70
  chart?: PanelChartConfig;
71
+ table?: PanelTableConfig;
68
72
  textHtml?: string;
69
73
  textAllowInput?: boolean;
70
74
  textFontFamily?: string;
@@ -1,41 +1,54 @@
1
+ import type { TranslateFn } from "@arronqzy/i18n";
2
+ import { tForLocale } from "@arronqzy/i18n";
3
+ import { createDefaultTableConfig, type PanelTableConfig } from "@arronqzy/view-table";
1
4
  import type { PanelChartConfig, PanelLayer } from "../types";
2
5
 
3
- const DEFAULT_NODE_NAME_MAP: Record<string, string> = {
4
- bar: "柱状图",
5
- line: "折线图",
6
- pie: "饼图",
7
- area: "面积图",
8
- scatter: "散点图",
9
- radar: "雷达图",
10
- gauge: "仪表盘",
11
- funnel: "漏斗图",
12
- text: "文本",
13
- grid: "网格布局",
14
- image: "图片",
15
- video: "视频",
16
- audio: "音频",
17
- reference: "引用组件",
18
- geometry: "几何",
6
+ const DEFAULT_NODE_NAME_KEYS: Record<string, string> = {
7
+ bar: "panel.defaults.bar",
8
+ line: "panel.defaults.line",
9
+ pie: "panel.defaults.pie",
10
+ area: "panel.defaults.area",
11
+ scatter: "panel.defaults.scatter",
12
+ radar: "panel.defaults.radar",
13
+ gauge: "panel.defaults.gauge",
14
+ funnel: "panel.defaults.funnel",
15
+ text: "panel.defaults.text",
16
+ grid: "panel.defaults.grid",
17
+ image: "panel.defaults.image",
18
+ video: "panel.defaults.video",
19
+ audio: "panel.defaults.audio",
20
+ reference: "panel.defaults.reference",
21
+ geometry: "panel.defaults.geometry",
22
+ table: "panel.defaults.table",
19
23
  };
20
24
 
21
25
  export const DEFAULT_LAYER_ID = "layer-1";
22
26
 
23
- export function getDefaultNodeName(materialType: string): string {
24
- return DEFAULT_NODE_NAME_MAP[materialType] ?? materialType;
27
+ export function getDefaultNodeName(
28
+ materialType: string,
29
+ t: TranslateFn = tForLocale("zh-CN")
30
+ ): string {
31
+ const key = DEFAULT_NODE_NAME_KEYS[materialType];
32
+ return key ? t(key) : materialType;
25
33
  }
26
34
 
27
- export const DEFAULT_LAYER: PanelLayer = {
28
- id: DEFAULT_LAYER_ID,
29
- name: "图层1",
30
- locked: false,
31
- editable: false,
32
- isPrimary: true,
33
- isMapping: false,
34
- mappingBaseLayerId: undefined,
35
- };
35
+ export function getDefaultLayer(t: TranslateFn = tForLocale("zh-CN")): PanelLayer {
36
+ return {
37
+ id: DEFAULT_LAYER_ID,
38
+ name: t("panel.defaults.layer1"),
39
+ locked: false,
40
+ editable: false,
41
+ isPrimary: true,
42
+ isMapping: false,
43
+ mappingBaseLayerId: undefined,
44
+ };
45
+ }
46
+
47
+ /** @deprecated Prefer getDefaultLayer(t) */
48
+ export const DEFAULT_LAYER: PanelLayer = getDefaultLayer();
36
49
 
37
50
  export function normalizePrimaryLayer(layers: PanelLayer[]): PanelLayer[] {
38
- if (layers.length === 0) return [DEFAULT_LAYER];
51
+ if (layers.length === 0) return [getDefaultLayer()];
39
52
  const explicitPrimary = layers.find((layer) => layer.isPrimary);
40
53
  const primaryId = explicitPrimary?.id ?? layers[0].id;
41
54
  return layers.map((layer) => {
@@ -68,15 +81,20 @@ export function getDefaultSizeByMaterial(materialType: string) {
68
81
  return { width: 280, height: 180 };
69
82
  case "geometry":
70
83
  return { width: 220, height: 220 };
84
+ case "table":
85
+ return { width: 480, height: 280 };
71
86
  default:
72
87
  return { width: 220, height: 130 };
73
88
  }
74
89
  }
75
90
 
76
- export function getDefaultTextContent(materialType: string) {
91
+ export function getDefaultTextContent(
92
+ materialType: string,
93
+ t: TranslateFn = tForLocale("zh-CN")
94
+ ) {
77
95
  if (materialType !== "text") return {};
78
96
  return {
79
- textHtml: "<p>双击输入文本</p>",
97
+ textHtml: `<p>${t("panel.defaults.doubleClickTextHtml")}</p>`,
80
98
  textAllowInput: true,
81
99
  textFontSize: 14,
82
100
  textFontWeight: "400",
@@ -96,7 +114,10 @@ export function getDefaultGridConfig(materialType: string) {
96
114
  } as const;
97
115
  }
98
116
 
99
- export function getDefaultChartConfig(materialType: string): PanelChartConfig | undefined {
117
+ export function getDefaultChartConfig(
118
+ materialType: string,
119
+ t: TranslateFn = tForLocale("zh-CN")
120
+ ): PanelChartConfig | undefined {
100
121
  if (!["bar", "line", "pie", "area", "scatter", "radar", "gauge", "funnel"].includes(materialType))
101
122
  return undefined;
102
123
  const common = {
@@ -107,40 +128,40 @@ export function getDefaultChartConfig(materialType: string): PanelChartConfig |
107
128
  };
108
129
  if (materialType === "bar") {
109
130
  return {
110
- title: "柱状图",
131
+ title: t("panel.defaults.bar"),
111
132
  ...common,
112
133
  barWidth: 24,
113
134
  };
114
135
  }
115
136
  if (materialType === "line") {
116
137
  return {
117
- title: "折线图",
138
+ title: t("panel.defaults.line"),
118
139
  ...common,
119
140
  smooth: true,
120
141
  };
121
142
  }
122
143
  if (materialType === "area") {
123
144
  return {
124
- title: "面积图",
145
+ title: t("panel.defaults.area"),
125
146
  ...common,
126
147
  smooth: true,
127
148
  };
128
149
  }
129
150
  if (materialType === "scatter") {
130
151
  return {
131
- title: "散点图",
152
+ title: t("panel.defaults.scatter"),
132
153
  ...common,
133
154
  };
134
155
  }
135
156
  if (materialType === "radar") {
136
157
  return {
137
- title: "雷达图",
158
+ title: t("panel.defaults.radar"),
138
159
  ...common,
139
160
  };
140
161
  }
141
162
  if (materialType === "gauge") {
142
163
  return {
143
- title: "仪表盘",
164
+ title: t("panel.defaults.gauge"),
144
165
  color: "#3b82f6",
145
166
  renderMode: "canvas",
146
167
  values: [68],
@@ -148,14 +169,27 @@ export function getDefaultChartConfig(materialType: string): PanelChartConfig |
148
169
  }
149
170
  if (materialType === "funnel") {
150
171
  return {
151
- title: "漏斗图",
172
+ title: t("panel.defaults.funnel"),
152
173
  ...common,
153
174
  };
154
175
  }
155
176
  return {
156
- title: "饼图",
177
+ title: t("panel.defaults.pie"),
157
178
  ...common,
158
179
  pieInnerRadius: 30,
159
180
  pieOuterRadius: 65,
160
181
  };
161
182
  }
183
+
184
+ export function getDefaultTableConfig(
185
+ materialType: string,
186
+ t: TranslateFn = tForLocale("zh-CN")
187
+ ): PanelTableConfig | undefined {
188
+ if (materialType !== "table") return undefined;
189
+ const cfg = createDefaultTableConfig();
190
+ cfg.emptyText = t("panel.config.tableEmpty");
191
+ if (cfg.columns?.[0]) cfg.columns[0].title = t("panel.config.tableColName");
192
+ if (cfg.columns?.[1]) cfg.columns[1].title = t("panel.config.tableColStatus");
193
+ if (cfg.columns?.[2]) cfg.columns[2].title = t("panel.config.tableColScore");
194
+ return cfg;
195
+ }
@@ -1,44 +1,58 @@
1
- const LABELS: Record<string, string> = {
2
- name: "节点名称",
3
- textHtml: "文本内容",
4
- textFontFamily: "文本字体",
5
- textFontWeight: "文本字重",
6
- textColor: "文本颜色",
7
- "chart.title": "图表标题",
8
- "chart.color": "图表颜色",
9
- "chart.gradientFrom": "渐变起始色",
10
- "chart.gradientTo": "渐变结束色",
11
- "chart.xAxisName": "X 轴名称",
12
- "chart.yAxisName": "Y 轴名称",
13
- "chart.xAxisTickColor": "X 轴刻度颜色",
14
- "chart.yAxisTickColor": "Y 轴刻度颜色",
15
- "chart.xAxisSplitLineColor": "X 轴分割线颜色",
16
- "chart.yAxisSplitLineColor": "Y 轴分割线颜色",
17
- "chart.xAxisLabelColor": "X 轴标签颜色",
18
- "chart.yAxisLabelColor": "Y 轴标签颜色",
19
- "chart.tooltipBackgroundColor": "Tooltip 背景色",
20
- "chart.tooltipTextColor": "Tooltip 文字色",
21
- "chart.tooltipFormatter": "Tooltip 格式化",
22
- "chart.labelsText": "图表类目",
23
- "chart.valuesText": "图表数值",
24
- "style.backgroundColor": "背景色",
25
- "style.backgroundImage": "背景图",
26
- "style.backgroundImageRemoteUrl": "背景图远程地址",
27
- "style.backgroundSize": "背景尺寸",
28
- "style.backgroundPosition": "背景位置",
29
- "style.borderColor": "边框颜色",
30
- audioSrc: "音频地址",
31
- audioRemoteUrl: "音频远程地址",
32
- videoSrc: "视频地址",
33
- videoRemoteUrl: "视频远程地址",
34
- geometryColor: "几何颜色",
35
- geometryScript: "几何脚本",
1
+ import type { TranslateFn } from "@arronqzy/i18n";
2
+ import { tForLocale } from "@arronqzy/i18n";
3
+
4
+ const FIELD_KEY_MAP: Record<string, string> = {
5
+ name: "panel.scope.fieldName",
6
+ textHtml: "panel.scope.fieldTextHtml",
7
+ textFontFamily: "panel.scope.fieldTextFontFamily",
8
+ textFontWeight: "panel.scope.fieldTextFontWeight",
9
+ textColor: "panel.scope.fieldTextColor",
10
+ "chart.title": "panel.scope.fieldChartTitle",
11
+ "chart.color": "panel.scope.fieldChartColor",
12
+ "chart.gradientFrom": "panel.scope.fieldChartGradientFrom",
13
+ "chart.gradientTo": "panel.scope.fieldChartGradientTo",
14
+ "chart.xAxisName": "panel.scope.fieldChartXAxisName",
15
+ "chart.yAxisName": "panel.scope.fieldChartYAxisName",
16
+ "chart.xAxisTickColor": "panel.scope.fieldChartXAxisTickColor",
17
+ "chart.yAxisTickColor": "panel.scope.fieldChartYAxisTickColor",
18
+ "chart.xAxisSplitLineColor": "panel.scope.fieldChartXAxisSplitLineColor",
19
+ "chart.yAxisSplitLineColor": "panel.scope.fieldChartYAxisSplitLineColor",
20
+ "chart.xAxisLabelColor": "panel.scope.fieldChartXAxisLabelColor",
21
+ "chart.yAxisLabelColor": "panel.scope.fieldChartYAxisLabelColor",
22
+ "chart.tooltipBackgroundColor": "panel.scope.fieldChartTooltipBackgroundColor",
23
+ "chart.tooltipTextColor": "panel.scope.fieldChartTooltipTextColor",
24
+ "chart.tooltipFormatter": "panel.scope.fieldChartTooltipFormatter",
25
+ "chart.labelsText": "panel.scope.fieldChartLabelsText",
26
+ "chart.valuesText": "panel.scope.fieldChartValuesText",
27
+ "style.backgroundColor": "panel.scope.fieldStyleBackgroundColor",
28
+ "style.backgroundImage": "panel.scope.fieldStyleBackgroundImage",
29
+ "style.backgroundImageRemoteUrl": "panel.scope.fieldStyleBackgroundImageRemoteUrl",
30
+ "style.backgroundSize": "panel.scope.fieldStyleBackgroundSize",
31
+ "style.backgroundPosition": "panel.scope.fieldStyleBackgroundPosition",
32
+ "style.borderColor": "panel.scope.fieldStyleBorderColor",
33
+ audioSrc: "panel.scope.fieldAudioSrc",
34
+ audioRemoteUrl: "panel.scope.fieldAudioRemoteUrl",
35
+ videoSrc: "panel.scope.fieldVideoSrc",
36
+ videoRemoteUrl: "panel.scope.fieldVideoRemoteUrl",
37
+ geometryColor: "panel.scope.fieldGeometryColor",
38
+ geometryScript: "panel.scope.fieldGeometryScript",
36
39
  };
37
40
 
38
- export function resolveScopeFieldLabel(fieldId: string): string {
39
- if (LABELS[fieldId]) return LABELS[fieldId];
40
- const leaf = fieldId.split(".").pop() ?? fieldId;
41
- return LABELS[fieldId] ?? leaf;
41
+ export function getScopeFieldLabels(t: TranslateFn): Record<string, string> {
42
+ const labels: Record<string, string> = {};
43
+ for (const [fieldId, key] of Object.entries(FIELD_KEY_MAP)) {
44
+ labels[fieldId] = t(key);
45
+ }
46
+ return labels;
47
+ }
48
+
49
+ export function resolveScopeFieldLabel(
50
+ fieldId: string,
51
+ t: TranslateFn = tForLocale("zh-CN")
52
+ ): string {
53
+ const key = FIELD_KEY_MAP[fieldId];
54
+ if (key) return t(key);
55
+ return fieldId.split(".").pop() ?? fieldId;
42
56
  }
43
57
 
44
58
  export function scopeFieldDomId(fieldId: string): string {