@shwfed/nuxt 0.7.8 → 0.7.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.
Files changed (174) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/app.d.vue.ts +7 -58
  3. package/dist/runtime/components/app.vue +18 -411
  4. package/dist/runtime/components/app.vue.d.ts +7 -58
  5. package/dist/runtime/components/fields.d.vue.ts +177 -0
  6. package/dist/runtime/components/fields.vue +47 -0
  7. package/dist/runtime/components/fields.vue.d.ts +177 -0
  8. package/dist/runtime/components/table.d.vue.ts +63 -59
  9. package/dist/runtime/components/table.vue +52 -617
  10. package/dist/runtime/components/table.vue.d.ts +63 -59
  11. package/dist/runtime/components/ui/app/App.d.vue.ts +86 -0
  12. package/dist/runtime/components/ui/app/App.vue +414 -0
  13. package/dist/runtime/components/ui/app/App.vue.d.ts +86 -0
  14. package/dist/runtime/components/ui/button-group/ButtonGroupSeparator.vue +1 -1
  15. package/dist/runtime/components/ui/button-group/ButtonGroupText.vue +1 -1
  16. package/dist/runtime/components/ui/calendar/Calendar.d.vue.ts +5 -12
  17. package/dist/runtime/components/ui/calendar/Calendar.vue +77 -92
  18. package/dist/runtime/components/ui/calendar/Calendar.vue.d.ts +5 -12
  19. package/dist/runtime/components/ui/calendar/CalendarCellTrigger.vue +1 -1
  20. package/dist/runtime/components/ui/calendar/index.d.ts +1 -1
  21. package/dist/runtime/components/ui/checkbox/Checkbox.vue +6 -2
  22. package/dist/runtime/components/ui/command/CommandGroup.vue +4 -0
  23. package/dist/runtime/components/ui/dialog/DialogOverlay.vue +1 -1
  24. package/dist/runtime/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +1 -1
  25. package/dist/runtime/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +1 -1
  26. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.d.vue.ts +30 -0
  27. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue +87 -0
  28. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue.d.ts +30 -0
  29. package/dist/runtime/components/ui/expression-editor/index.d.ts +1 -0
  30. package/dist/runtime/components/ui/expression-editor/index.js +1 -0
  31. package/dist/runtime/components/ui/field/FieldContent.vue +1 -1
  32. package/dist/runtime/components/ui/field/FieldDescription.vue +1 -1
  33. package/dist/runtime/components/ui/field/FieldError.vue +2 -2
  34. package/dist/runtime/components/ui/field/FieldLabel.vue +1 -1
  35. package/dist/runtime/components/ui/field/FieldSeparator.vue +1 -1
  36. package/dist/runtime/components/ui/field/index.js +7 -5
  37. package/dist/runtime/components/ui/fields/Fields.d.vue.ts +376 -0
  38. package/dist/runtime/components/ui/fields/Fields.vue +441 -0
  39. package/dist/runtime/components/ui/fields/Fields.vue.d.ts +376 -0
  40. package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.d.vue.ts +163 -0
  41. package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.vue +363 -0
  42. package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.vue.d.ts +163 -0
  43. package/dist/runtime/components/ui/input/Input.d.vue.ts +1 -0
  44. package/dist/runtime/components/ui/input/Input.vue +3 -1
  45. package/dist/runtime/components/ui/input/Input.vue.d.ts +1 -0
  46. package/dist/runtime/components/ui/input-group/InputGroup.vue +3 -0
  47. package/dist/runtime/components/ui/input-group/InputGroupAddon.vue +4 -1
  48. package/dist/runtime/components/ui/input-group/InputGroupCombobox.d.vue.ts +11 -3
  49. package/dist/runtime/components/ui/input-group/InputGroupCombobox.vue +16 -5
  50. package/dist/runtime/components/ui/input-group/InputGroupCombobox.vue.d.ts +11 -3
  51. package/dist/runtime/components/ui/input-group/InputGroupComboboxInput.d.vue.ts +8 -1
  52. package/dist/runtime/components/ui/input-group/InputGroupComboboxInput.vue +12 -1
  53. package/dist/runtime/components/ui/input-group/InputGroupComboboxInput.vue.d.ts +8 -1
  54. package/dist/runtime/components/ui/input-group/InputGroupInput.vue +1 -1
  55. package/dist/runtime/components/ui/input-group/InputGroupNumberField.d.vue.ts +5 -2
  56. package/dist/runtime/components/ui/input-group/InputGroupNumberField.vue +10 -4
  57. package/dist/runtime/components/ui/input-group/InputGroupNumberField.vue.d.ts +5 -2
  58. package/dist/runtime/components/ui/input-group/InputGroupText.vue +1 -1
  59. package/dist/runtime/components/ui/input-group/InputGroupTextarea.vue +1 -1
  60. package/dist/runtime/components/ui/input-group/index.js +2 -2
  61. package/dist/runtime/components/ui/label/Label.vue +1 -1
  62. package/dist/runtime/components/ui/locale/Locale.d.vue.ts +20 -0
  63. package/dist/runtime/components/ui/locale/Locale.vue +291 -0
  64. package/dist/runtime/components/ui/locale/Locale.vue.d.ts +20 -0
  65. package/dist/runtime/components/ui/locale/index.d.ts +1 -0
  66. package/dist/runtime/components/ui/locale/index.js +1 -0
  67. package/dist/runtime/components/ui/native-select/NativeSelect.vue +3 -3
  68. package/dist/runtime/components/ui/native-select/NativeSelectOption.d.vue.ts +1 -0
  69. package/dist/runtime/components/ui/native-select/NativeSelectOption.vue +4 -1
  70. package/dist/runtime/components/ui/native-select/NativeSelectOption.vue.d.ts +1 -0
  71. package/dist/runtime/components/ui/navigation-menu/NavigationMenuLink.vue +1 -1
  72. package/dist/runtime/components/ui/navigation-menu/NavigationMenuViewport.vue +1 -1
  73. package/dist/runtime/components/ui/number-field/NumberFieldInput.vue +1 -1
  74. package/dist/runtime/components/ui/range-calendar/RangeCalendarCell.vue +1 -1
  75. package/dist/runtime/components/ui/range-calendar/RangeCalendarCellTrigger.vue +1 -1
  76. package/dist/runtime/components/ui/sheet/SheetOverlay.vue +1 -1
  77. package/dist/runtime/components/ui/switch/Switch.d.vue.ts +24 -0
  78. package/dist/runtime/components/ui/switch/Switch.vue +46 -0
  79. package/dist/runtime/components/ui/switch/Switch.vue.d.ts +24 -0
  80. package/dist/runtime/components/ui/switch/index.d.ts +1 -0
  81. package/dist/runtime/components/ui/switch/index.js +1 -0
  82. package/dist/runtime/components/ui/table/Table.d.vue.ts +81 -0
  83. package/dist/runtime/components/ui/table/Table.vue +792 -0
  84. package/dist/runtime/components/ui/table/Table.vue.d.ts +81 -0
  85. package/dist/runtime/components/ui/table/schema.d.ts +48 -0
  86. package/dist/runtime/components/ui/table/schema.js +126 -0
  87. package/dist/runtime/components/ui/table-configurator/TableConfiguratorDialog.d.vue.ts +62 -0
  88. package/dist/runtime/components/ui/table-configurator/TableConfiguratorDialog.vue +2233 -0
  89. package/dist/runtime/components/ui/table-configurator/TableConfiguratorDialog.vue.d.ts +62 -0
  90. package/dist/runtime/components/ui/table-configurator/menu.d.ts +37 -0
  91. package/dist/runtime/components/ui/table-configurator/menu.js +227 -0
  92. package/dist/runtime/components/ui/tabs/Tabs.d.vue.ts +24 -0
  93. package/dist/runtime/components/ui/tabs/Tabs.vue +30 -0
  94. package/dist/runtime/components/ui/tabs/Tabs.vue.d.ts +24 -0
  95. package/dist/runtime/components/ui/tabs/TabsContent.d.vue.ts +18 -0
  96. package/dist/runtime/components/ui/tabs/TabsContent.vue +23 -0
  97. package/dist/runtime/components/ui/tabs/TabsContent.vue.d.ts +18 -0
  98. package/dist/runtime/components/ui/tabs/TabsList.d.vue.ts +18 -0
  99. package/dist/runtime/components/ui/tabs/TabsList.vue +25 -0
  100. package/dist/runtime/components/ui/tabs/TabsList.vue.d.ts +18 -0
  101. package/dist/runtime/components/ui/tabs/TabsTrigger.d.vue.ts +18 -0
  102. package/dist/runtime/components/ui/tabs/TabsTrigger.vue +27 -0
  103. package/dist/runtime/components/ui/tabs/TabsTrigger.vue.d.ts +18 -0
  104. package/dist/runtime/components/ui/tabs/index.d.ts +4 -0
  105. package/dist/runtime/components/ui/tabs/index.js +4 -0
  106. package/dist/runtime/components/ui/textarea/Textarea.d.vue.ts +1 -0
  107. package/dist/runtime/components/ui/textarea/Textarea.vue +4 -2
  108. package/dist/runtime/components/ui/textarea/Textarea.vue.d.ts +1 -0
  109. package/dist/runtime/components/ui/toggle/Toggle.d.vue.ts +34 -0
  110. package/dist/runtime/components/ui/toggle/Toggle.vue +32 -0
  111. package/dist/runtime/components/ui/toggle/Toggle.vue.d.ts +34 -0
  112. package/dist/runtime/components/ui/toggle/index.d.ts +7 -0
  113. package/dist/runtime/components/ui/toggle/index.js +22 -0
  114. package/dist/runtime/composables/useTableRenderers.d.ts +2 -1
  115. package/dist/runtime/composables/useTableRenderers.js +2 -1
  116. package/dist/runtime/plugins/cel/env.d.ts +2 -2
  117. package/dist/runtime/plugins/cel/env.js +5 -4
  118. package/dist/runtime/plugins/cel/index.d.ts +3 -3
  119. package/dist/runtime/plugins/cel/index.js +7 -3
  120. package/dist/runtime/plugins/markdown/index.d.ts +1 -1
  121. package/dist/runtime/style.css +1 -1
  122. package/dist/runtime/table-renderers/builtins.js +213 -98
  123. package/dist/runtime/table-renderers/registry.d.ts +1 -0
  124. package/dist/runtime/table-renderers/registry.js +3 -0
  125. package/dist/runtime/utils/coders.d.ts +32 -0
  126. package/dist/runtime/utils/coders.js +64 -0
  127. package/dist/runtime/vendor/cel/index.d.ts +17 -0
  128. package/dist/runtime/vendor/cel/index.js +10 -0
  129. package/dist/runtime/vendor/cel-js/LICENSE +21 -0
  130. package/dist/runtime/vendor/cel-js/UPSTREAM.md +17 -0
  131. package/dist/runtime/vendor/cel-js/lib/errors.d.ts +21 -0
  132. package/dist/runtime/vendor/cel-js/lib/errors.js +97 -0
  133. package/dist/runtime/vendor/cel-js/lib/evaluator.d.ts +4 -0
  134. package/dist/runtime/vendor/cel-js/lib/evaluator.js +192 -0
  135. package/dist/runtime/vendor/cel-js/lib/functions.d.ts +53 -0
  136. package/dist/runtime/vendor/cel-js/lib/functions.js +513 -0
  137. package/dist/runtime/vendor/cel-js/lib/globals.d.ts +27 -0
  138. package/dist/runtime/vendor/cel-js/lib/globals.js +33 -0
  139. package/dist/runtime/vendor/cel-js/lib/index.d.ts +469 -0
  140. package/dist/runtime/vendor/cel-js/lib/index.js +18 -0
  141. package/dist/runtime/vendor/cel-js/lib/macros.d.ts +1 -0
  142. package/dist/runtime/vendor/cel-js/lib/macros.js +230 -0
  143. package/dist/runtime/vendor/cel-js/lib/operators.d.ts +117 -0
  144. package/dist/runtime/vendor/cel-js/lib/operators.js +739 -0
  145. package/dist/runtime/vendor/cel-js/lib/optional.d.ts +14 -0
  146. package/dist/runtime/vendor/cel-js/lib/optional.js +161 -0
  147. package/dist/runtime/vendor/cel-js/lib/options.d.ts +23 -0
  148. package/dist/runtime/vendor/cel-js/lib/options.js +47 -0
  149. package/dist/runtime/vendor/cel-js/lib/overloads.d.ts +1 -0
  150. package/dist/runtime/vendor/cel-js/lib/overloads.js +214 -0
  151. package/dist/runtime/vendor/cel-js/lib/parser.d.ts +56 -0
  152. package/dist/runtime/vendor/cel-js/lib/parser.js +827 -0
  153. package/dist/runtime/vendor/cel-js/lib/registry.d.ts +279 -0
  154. package/dist/runtime/vendor/cel-js/lib/registry.js +1596 -0
  155. package/dist/runtime/vendor/cel-js/lib/serialize.d.ts +1 -0
  156. package/dist/runtime/vendor/cel-js/lib/serialize.js +259 -0
  157. package/dist/runtime/vendor/cel-js/lib/type-checker.d.ts +26 -0
  158. package/dist/runtime/vendor/cel-js/lib/type-checker.js +81 -0
  159. package/package.json +9 -4
  160. package/dist/runtime/components/locale.d.vue.ts +0 -14
  161. package/dist/runtime/components/locale.vue +0 -89
  162. package/dist/runtime/components/locale.vue.d.ts +0 -14
  163. package/dist/runtime/components/query.d.vue.ts +0 -30
  164. package/dist/runtime/components/query.vue +0 -266
  165. package/dist/runtime/components/query.vue.d.ts +0 -30
  166. package/dist/runtime/utilities/query-config/global.d.ts +0 -4
  167. package/dist/runtime/utilities/query-config/global.js +0 -18
  168. package/dist/runtime/utilities/query-config/index.d.ts +0 -3
  169. package/dist/runtime/utilities/query-config/index.js +0 -14
  170. package/dist/runtime/utilities/query-config/schema.d.ts +0 -96
  171. package/dist/runtime/utilities/query-config/schema.js +0 -51
  172. /package/dist/runtime/components/{logo.d.vue.ts → ui/logo/Logo.d.vue.ts} +0 -0
  173. /package/dist/runtime/components/{logo.vue → ui/logo/Logo.vue} +0 -0
  174. /package/dist/runtime/components/{logo.vue.d.ts → ui/logo/Logo.vue.d.ts} +0 -0
@@ -0,0 +1,2233 @@
1
+ <script setup>
2
+ import { useNuxtApp } from "#app";
3
+ import { useSortable } from "@vueuse/integrations/useSortable";
4
+ import { Icon } from "@iconify/vue";
5
+ import z from "zod";
6
+ import { computed, nextTick, ref, watch } from "vue";
7
+ import { useI18n } from "vue-i18n";
8
+ import { useTableRenderers } from "../../../composables/useTableRenderers";
9
+ import { dotPropC, expressionC } from "../../../utils/coders";
10
+ import { cn } from "../../../utils/cn";
11
+ import ExpressionEditor from "../expression-editor/ExpressionEditor.vue";
12
+ import { Button } from "../button";
13
+ import { Checkbox } from "../checkbox";
14
+ import {
15
+ Dialog,
16
+ DialogContent,
17
+ DialogDescription,
18
+ DialogFooter,
19
+ DialogHeader,
20
+ DialogTitle
21
+ } from "../dialog";
22
+ import { Input } from "../input";
23
+ import { InputGroup, InputGroupNumberField } from "../input-group";
24
+ import Locale from "../locale/Locale.vue";
25
+ import { NativeSelect, NativeSelectOption } from "../native-select";
26
+ import { NumberField, NumberFieldInput } from "../number-field";
27
+ import { Switch } from "../switch";
28
+ import { Textarea } from "../textarea";
29
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "../tabs";
30
+ import { Toggle } from "../toggle";
31
+ import {
32
+ getColumnTechnicalKey,
33
+ getLocalizedText,
34
+ TableConfigC,
35
+ TableConfigCellStylesC,
36
+ TableConfigEnableMultiRowSelectionC,
37
+ TableConfigEnableRowSelectionC,
38
+ TableConfigGetRowIdC,
39
+ TableConfigGetSubRowsC
40
+ } from "../table/schema";
41
+ import {
42
+ buildTableConfiguratorColumnTree,
43
+ createTableConfiguratorDraftColumnNode,
44
+ flattenTableConfiguratorColumnTree,
45
+ getTableConfiguratorColumnAncestorItemIds,
46
+ getTableConfiguratorColumnDescendantItemIds,
47
+ getTableConfiguratorColumnNode,
48
+ insertTableConfiguratorRootColumnNode,
49
+ materializeTableConfiguratorColumnTree,
50
+ moveTableConfiguratorColumnNodeAfterItem,
51
+ moveTableConfiguratorColumnNodeToParent,
52
+ moveTableConfiguratorColumnSibling,
53
+ removeTableConfiguratorColumnSubtree,
54
+ updateTableConfiguratorColumnNode
55
+ } from "./menu";
56
+ const GENERATED_COLUMN_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
57
+ const TableConfiguratorColumnAccessorReadC = expressionC(/.+/, { row: "dyn", index: "int" });
58
+ const TableConfiguratorColumnAccessorWriteC = z.string().trim().refine((value) => value.length > 0, { error: "\u5199\u5165\u8868\u8FBE\u5F0F\u4E0D\u80FD\u4E3A\u7A7A" });
59
+ const TOOLTIP_EXPRESSION_EXAMPLE = "{{ expression }}";
60
+ const props = defineProps({
61
+ config: { type: Object, required: true }
62
+ });
63
+ const emit = defineEmits(["confirm"]);
64
+ const open = defineModel("open", { type: Boolean, ...{
65
+ default: false
66
+ } });
67
+ const { $toast } = useNuxtApp();
68
+ const { t, locale } = useI18n();
69
+ const { listTableRenderers, resolveTableRenderer } = useTableRenderers();
70
+ const search = ref("");
71
+ const childSearch = ref("");
72
+ const selectedItemId = ref("general");
73
+ const draftBaseConfig = ref({ columns: [] });
74
+ const draftColumnTree = ref(buildTableConfiguratorColumnTree([]));
75
+ const draftGetRowId = ref();
76
+ const draftGetSubRows = ref();
77
+ const draftEnableRowSelection = ref();
78
+ const draftEnableMultiRowSelection = ref();
79
+ const draftCellStyles = ref();
80
+ const draftPaginationLeft = ref();
81
+ const draftPaginationRight = ref();
82
+ const draftPageSize = ref();
83
+ const leftPinnedSortableListRef = ref(null);
84
+ const leftPinnedSortableItemIds = ref([]);
85
+ const centerSortableListRef = ref(null);
86
+ const centerSortableItemIds = ref([]);
87
+ const rightPinnedSortableListRef = ref(null);
88
+ const rightPinnedSortableItemIds = ref([]);
89
+ const leftPinnedRootItemIds = ref([]);
90
+ const centerRootItemIds = ref([]);
91
+ const rightPinnedRootItemIds = ref([]);
92
+ const selectedChildSortableListRef = ref(null);
93
+ const selectedChildSortableItemIds = ref([]);
94
+ const getRowIdEditor = ref(null);
95
+ const getSubRowsEditor = ref(null);
96
+ const enableRowSelectionEditor = ref(null);
97
+ const enableMultiRowSelectionEditor = ref(null);
98
+ const cellStylesEditor = ref(null);
99
+ const importInputRef = ref(null);
100
+ const accessorPathEditor = ref(null);
101
+ const accessorReadEditor = ref(null);
102
+ const accessorWriteEditor = ref(null);
103
+ const selectedRendererConfigRef = ref(null);
104
+ const selectedColumnAccessorMode = ref("path");
105
+ const generalItem = computed(() => ({
106
+ id: "general",
107
+ label: t("general")
108
+ }));
109
+ const normalizedSearch = computed(() => search.value.trim().toLocaleLowerCase());
110
+ const normalizedChildSearch = computed(() => childSearch.value.trim().toLocaleLowerCase());
111
+ const selectedColumnNode = computed(() => {
112
+ if (selectedItemId.value === "general") {
113
+ return void 0;
114
+ }
115
+ return getTableConfiguratorColumnNode(draftColumnTree.value, selectedItemId.value);
116
+ });
117
+ const selectedColumn = computed(() => selectedColumnNode.value?.column);
118
+ const selectedColumnTechnicalKey = computed(() => selectedColumn.value ? getColumnTechnicalKey(selectedColumn.value) : void 0);
119
+ const selectedColumnAncestorItemIds = computed(() => {
120
+ const node = selectedColumnNode.value;
121
+ if (!node) {
122
+ return [];
123
+ }
124
+ return getTableConfiguratorColumnAncestorItemIds(draftColumnTree.value, node.itemId);
125
+ });
126
+ const selectedColumnDescendantItemIds = computed(() => {
127
+ const node = selectedColumnNode.value;
128
+ if (!node) {
129
+ return [];
130
+ }
131
+ return getTableConfiguratorColumnDescendantItemIds(draftColumnTree.value, node.itemId);
132
+ });
133
+ function looksLikeGeneratedColumnId(value) {
134
+ if (!value) {
135
+ return false;
136
+ }
137
+ return GENERATED_COLUMN_ID_RE.test(value);
138
+ }
139
+ function getColumnSearchMeta(column, hasChildren) {
140
+ if (typeof column.accessor === "string") {
141
+ return column.accessor;
142
+ }
143
+ if (column.accessor) {
144
+ return column.accessor.read;
145
+ }
146
+ if (column.id && (hasChildren || !looksLikeGeneratedColumnId(column.id))) {
147
+ return column.id;
148
+ }
149
+ return void 0;
150
+ }
151
+ function createListItem(itemId, depth) {
152
+ const node = getTableConfiguratorColumnNode(draftColumnTree.value, itemId);
153
+ if (!node) {
154
+ return void 0;
155
+ }
156
+ const hasChildren = node.childItemIds.length > 0;
157
+ const searchMeta = getColumnSearchMeta(node.column, hasChildren);
158
+ return {
159
+ itemId,
160
+ label: getLocalizedText(node.column.title, locale.value) ?? searchMeta ?? t("untitled-column"),
161
+ searchMeta,
162
+ depth,
163
+ hasChildren,
164
+ column: node.column
165
+ };
166
+ }
167
+ const columnListItems = computed(() => flattenTableConfiguratorColumnTree(draftColumnTree.value).flatMap((item) => {
168
+ const listItem = createListItem(item.itemId, item.depth);
169
+ return listItem ? [listItem] : [];
170
+ }));
171
+ const filteredColumnItems = computed(() => {
172
+ if (!normalizedSearch.value) {
173
+ return columnListItems.value;
174
+ }
175
+ return columnListItems.value.filter((item) => matchesSearch(item, normalizedSearch.value));
176
+ });
177
+ const selectedColumnItem = computed(() => columnListItems.value.find((item) => item.itemId === selectedItemId.value));
178
+ const selectedItemLabel = computed(() => selectedColumnItem.value?.label ?? generalItem.value.label);
179
+ const selectedColumnLocaleValue = computed(() => {
180
+ const node = selectedColumnNode.value;
181
+ if (!node) {
182
+ return void 0;
183
+ }
184
+ if (node.column.title) {
185
+ return node.column.title;
186
+ }
187
+ const fallbackLabel = getColumnSearchMeta(node.column, node.childItemIds.length > 0);
188
+ if (!fallbackLabel) {
189
+ return void 0;
190
+ }
191
+ return [
192
+ {
193
+ locale: "zh",
194
+ message: fallbackLabel
195
+ }
196
+ ];
197
+ });
198
+ const selectedColumnTooltipValue = computed(() => {
199
+ const node = selectedColumnNode.value;
200
+ if (!node) {
201
+ return void 0;
202
+ }
203
+ return node.column.tooltip;
204
+ });
205
+ const selectedColumnHasChildren = computed(() => (selectedColumnNode.value?.childItemIds.length ?? 0) > 0);
206
+ const rendererOptions = computed(() => listTableRenderers().map((renderer) => ({
207
+ id: renderer.id,
208
+ label: getTableConfiguratorRendererLabel(renderer.id)
209
+ })));
210
+ function getTableConfiguratorRendererLabel(rendererId) {
211
+ const segments = rendererId.split(".");
212
+ const leaf = segments.at(-1) ?? rendererId;
213
+ if (locale.value.startsWith("ja")) {
214
+ const labels2 = {
215
+ text: "\u30C6\u30AD\u30B9\u30C8",
216
+ selection: "\u9078\u629E",
217
+ expand: "\u5C55\u958B",
218
+ money: "\u91D1\u984D",
219
+ date: "\u65E5\u4ED8",
220
+ markdown: "Markdown"
221
+ };
222
+ const label2 = labels2[leaf];
223
+ if (label2) {
224
+ return label2;
225
+ }
226
+ }
227
+ if (locale.value.startsWith("en")) {
228
+ const labels2 = {
229
+ text: "Text",
230
+ selection: "Selection",
231
+ expand: "Expand",
232
+ money: "Money",
233
+ date: "Date",
234
+ markdown: "Markdown"
235
+ };
236
+ const label2 = labels2[leaf];
237
+ if (label2) {
238
+ return label2;
239
+ }
240
+ }
241
+ const labels = {
242
+ text: "\u6587\u672C",
243
+ selection: "\u9009\u62E9",
244
+ expand: "\u5C55\u5F00",
245
+ money: "\u91D1\u989D",
246
+ date: "\u65E5\u671F",
247
+ markdown: "Markdown"
248
+ };
249
+ const label = labels[leaf];
250
+ if (label) {
251
+ return label;
252
+ }
253
+ return `${leaf.slice(0, 1).toLocaleUpperCase()}${leaf.slice(1)}`;
254
+ }
255
+ function getColumnRendererId(column) {
256
+ if (!column) {
257
+ return "table.renderer.text";
258
+ }
259
+ if (typeof column.renderer === "string") {
260
+ return column.renderer;
261
+ }
262
+ return column.renderer?.id ?? "table.renderer.text";
263
+ }
264
+ function getColumnRendererProps(column) {
265
+ if (!column || !column.renderer || typeof column.renderer === "string") {
266
+ return void 0;
267
+ }
268
+ return column.renderer.props;
269
+ }
270
+ const selectedColumnRendererId = computed(() => getColumnRendererId(selectedColumn.value));
271
+ const selectedColumnRendererModel = computed({
272
+ get() {
273
+ return selectedColumnRendererId.value;
274
+ },
275
+ set(value) {
276
+ updateSelectedColumnRendererId(value);
277
+ }
278
+ });
279
+ const selectedColumnRenderer = computed(() => resolveTableRenderer(selectedColumnRendererId.value));
280
+ const selectedColumnRendererConfigComponent = computed(() => selectedColumnRenderer.value.config);
281
+ const selectedColumnRendererOptions = computed(() => {
282
+ const renderer = selectedColumnRenderer.value;
283
+ try {
284
+ return renderer.parseOptions(getColumnRendererProps(selectedColumn.value));
285
+ } catch (e) {
286
+ console.error(e);
287
+ return renderer.parseOptions(void 0);
288
+ }
289
+ });
290
+ function isDotPropPath(value) {
291
+ if (!value) {
292
+ return false;
293
+ }
294
+ return dotPropC.safeParse(value).success;
295
+ }
296
+ async function copySelectedColumnId() {
297
+ if (!selectedColumnTechnicalKey.value) {
298
+ return;
299
+ }
300
+ try {
301
+ await navigator.clipboard.writeText(selectedColumnTechnicalKey.value);
302
+ } catch (e) {
303
+ console.error(e);
304
+ }
305
+ }
306
+ function getColumnAccessorPath(column) {
307
+ if (!column) {
308
+ return void 0;
309
+ }
310
+ if (typeof column.accessor === "string") {
311
+ return column.accessor;
312
+ }
313
+ if (!column.accessor) {
314
+ return void 0;
315
+ }
316
+ if (isDotPropPath(column.accessor.write)) {
317
+ return column.accessor.write;
318
+ }
319
+ const read = column.accessor.read;
320
+ if (!read.startsWith("row")) {
321
+ return void 0;
322
+ }
323
+ const path = read.slice(3);
324
+ const normalizedPath = path.startsWith(".") ? path.slice(1) : path;
325
+ return isDotPropPath(normalizedPath) ? normalizedPath : void 0;
326
+ }
327
+ function createAccessorReadFromPath(path) {
328
+ if (!path) {
329
+ return "";
330
+ }
331
+ return path.startsWith("[") ? `row${path}` : `row.${path}`;
332
+ }
333
+ function getColumnAccessorExpression(column) {
334
+ if (column?.accessor && typeof column.accessor !== "string") {
335
+ return column.accessor;
336
+ }
337
+ const path = getColumnAccessorPath(column);
338
+ return {
339
+ read: createAccessorReadFromPath(path),
340
+ write: path ?? ""
341
+ };
342
+ }
343
+ function getColumnAccessorMode(column) {
344
+ if (column?.accessor && typeof column.accessor !== "string") {
345
+ return "expression";
346
+ }
347
+ return "path";
348
+ }
349
+ const selectedColumnAccessorPath = computed(() => getColumnAccessorPath(selectedColumn.value));
350
+ const selectedColumnAccessorExpression = computed(() => getColumnAccessorExpression(selectedColumn.value));
351
+ function normalizeOptionalText(value) {
352
+ if (value === void 0 || value.trim().length === 0) {
353
+ return void 0;
354
+ }
355
+ return value;
356
+ }
357
+ function normalizeOptionalNumber(value) {
358
+ if (typeof value === "number") {
359
+ return Number.isFinite(value) ? value : void 0;
360
+ }
361
+ if (value === void 0 || value.trim().length === 0) {
362
+ return void 0;
363
+ }
364
+ const normalized = Number(value);
365
+ return Number.isFinite(normalized) ? normalized : void 0;
366
+ }
367
+ function getInitialPageSize(config) {
368
+ return config.props?.initialState?.pagination?.pageSize;
369
+ }
370
+ function isRendererConfigExposed(value) {
371
+ if (typeof value !== "object" || value === null) {
372
+ return false;
373
+ }
374
+ const clearValidation = Reflect.get(value, "clearValidation");
375
+ const validate = Reflect.get(value, "validate");
376
+ return typeof clearValidation === "function" && typeof validate === "function";
377
+ }
378
+ function areRendererOptionsDefault(rendererId, props2) {
379
+ const renderer = resolveTableRenderer(rendererId);
380
+ const normalizedProps = renderer.parseOptions(props2);
381
+ const defaultProps = renderer.parseOptions(void 0);
382
+ return JSON.stringify(normalizedProps) === JSON.stringify(defaultProps);
383
+ }
384
+ function buildColumnRenderer(rendererId, props2) {
385
+ const renderer = resolveTableRenderer(rendererId);
386
+ const normalizedProps = renderer.parseOptions(props2);
387
+ if (areRendererOptionsDefault(rendererId, normalizedProps)) {
388
+ return rendererId;
389
+ }
390
+ return {
391
+ id: renderer.id,
392
+ props: normalizedProps
393
+ };
394
+ }
395
+ function getLeafColumnTechnicalKeys(itemId) {
396
+ const node = getTableConfiguratorColumnNode(draftColumnTree.value, itemId);
397
+ if (!node) {
398
+ return void 0;
399
+ }
400
+ if (node.childItemIds.length === 0) {
401
+ const technicalKey = getColumnTechnicalKey(node.column);
402
+ return technicalKey ? [technicalKey] : void 0;
403
+ }
404
+ const leafColumnIds = [];
405
+ for (const childItemId of node.childItemIds) {
406
+ const childLeafColumnIds = getLeafColumnTechnicalKeys(childItemId);
407
+ if (!childLeafColumnIds?.length) {
408
+ return void 0;
409
+ }
410
+ leafColumnIds.push(...childLeafColumnIds);
411
+ }
412
+ return leafColumnIds;
413
+ }
414
+ function createRootInitialStateItem(itemId) {
415
+ const listItem = createListItem(itemId, 0);
416
+ if (!listItem) {
417
+ return void 0;
418
+ }
419
+ const leafColumnIds = getLeafColumnTechnicalKeys(itemId) ?? [];
420
+ return {
421
+ itemId,
422
+ label: listItem.label,
423
+ leafColumnIds,
424
+ canManage: leafColumnIds.length > 0
425
+ };
426
+ }
427
+ const rootInitialStateItems = computed(() => draftColumnTree.value.rootItemIds.flatMap((itemId) => {
428
+ const listItem = createRootInitialStateItem(itemId);
429
+ return listItem ? [listItem] : [];
430
+ }));
431
+ function resolveRootInitialStateItems(itemIds) {
432
+ return itemIds.flatMap((itemId) => {
433
+ const item = rootInitialStateItems.value.find((candidate) => candidate.itemId === itemId);
434
+ return item ? [item] : [];
435
+ });
436
+ }
437
+ const leftPinnedInitialStateItems = computed(() => resolveRootInitialStateItems(leftPinnedRootItemIds.value));
438
+ const centerInitialStateItems = computed(() => resolveRootInitialStateItems(centerRootItemIds.value));
439
+ const rightPinnedInitialStateItems = computed(() => resolveRootInitialStateItems(rightPinnedRootItemIds.value));
440
+ const selectedChildItems = computed(() => {
441
+ const node = selectedColumnNode.value;
442
+ if (!node) {
443
+ return [];
444
+ }
445
+ return node.childItemIds.flatMap((itemId) => {
446
+ const listItem = createListItem(itemId, 0);
447
+ return listItem ? [listItem] : [];
448
+ });
449
+ });
450
+ const childCandidateItems = computed(() => {
451
+ const node = selectedColumnNode.value;
452
+ if (!node) {
453
+ return [];
454
+ }
455
+ const excludedItemIds = /* @__PURE__ */ new Set([
456
+ node.itemId,
457
+ ...selectedColumnAncestorItemIds.value,
458
+ ...selectedColumnDescendantItemIds.value
459
+ ]);
460
+ return columnListItems.value.filter((item) => !excludedItemIds.has(item.itemId));
461
+ });
462
+ const filteredChildCandidateItems = computed(() => {
463
+ if (!normalizedChildSearch.value) {
464
+ return childCandidateItems.value;
465
+ }
466
+ return childCandidateItems.value.filter((item) => matchesSearch(item, normalizedChildSearch.value));
467
+ });
468
+ function matchesSearch(item, normalizedValue) {
469
+ const haystack = [item.label, item.searchMeta].filter((value) => value).join(" ").toLocaleLowerCase();
470
+ return haystack.includes(normalizedValue);
471
+ }
472
+ function reorderItemIds(itemIds, oldIndex, newIndex) {
473
+ if (oldIndex < 0 || newIndex < 0 || oldIndex >= itemIds.length || newIndex >= itemIds.length) {
474
+ return itemIds.slice();
475
+ }
476
+ const nextItemIds = itemIds.slice();
477
+ const movedItemId = nextItemIds[oldIndex];
478
+ if (!movedItemId) {
479
+ return itemIds.slice();
480
+ }
481
+ nextItemIds.splice(oldIndex, 1);
482
+ nextItemIds.splice(newIndex, 0, movedItemId);
483
+ return nextItemIds;
484
+ }
485
+ function initializeInitialStateGroups(config) {
486
+ const leafColumnIdToRootItemId = /* @__PURE__ */ new Map();
487
+ for (const item of rootInitialStateItems.value) {
488
+ if (!item.canManage) {
489
+ continue;
490
+ }
491
+ for (const leafColumnId of item.leafColumnIds) {
492
+ if (!leafColumnIdToRootItemId.has(leafColumnId)) {
493
+ leafColumnIdToRootItemId.set(leafColumnId, item.itemId);
494
+ }
495
+ }
496
+ }
497
+ const initialState = config.props?.initialState;
498
+ const leftItemIds = [];
499
+ const rightItemIds = [];
500
+ const centerItemIds = [];
501
+ for (const leafColumnId of initialState?.columnPinning?.left ?? []) {
502
+ const itemId = leafColumnIdToRootItemId.get(leafColumnId);
503
+ if (!itemId || leftItemIds.includes(itemId)) {
504
+ continue;
505
+ }
506
+ leftItemIds.push(itemId);
507
+ }
508
+ for (const leafColumnId of initialState?.columnPinning?.right ?? []) {
509
+ const itemId = leafColumnIdToRootItemId.get(leafColumnId);
510
+ if (!itemId || leftItemIds.includes(itemId) || rightItemIds.includes(itemId)) {
511
+ continue;
512
+ }
513
+ rightItemIds.push(itemId);
514
+ }
515
+ for (const leafColumnId of initialState?.columnOrder ?? []) {
516
+ const itemId = leafColumnIdToRootItemId.get(leafColumnId);
517
+ if (!itemId || leftItemIds.includes(itemId) || rightItemIds.includes(itemId) || centerItemIds.includes(itemId)) {
518
+ continue;
519
+ }
520
+ centerItemIds.push(itemId);
521
+ }
522
+ for (const item of rootInitialStateItems.value) {
523
+ if (leftItemIds.includes(item.itemId) || rightItemIds.includes(item.itemId) || centerItemIds.includes(item.itemId)) {
524
+ continue;
525
+ }
526
+ centerItemIds.push(item.itemId);
527
+ }
528
+ leftPinnedRootItemIds.value = leftItemIds;
529
+ centerRootItemIds.value = centerItemIds;
530
+ rightPinnedRootItemIds.value = rightItemIds;
531
+ }
532
+ function resetDraftState(config) {
533
+ draftBaseConfig.value = config;
534
+ draftColumnTree.value = buildTableConfiguratorColumnTree(config.columns);
535
+ draftGetRowId.value = config.getRowId;
536
+ draftGetSubRows.value = config.getSubRows;
537
+ draftEnableRowSelection.value = config.enableRowSelection;
538
+ draftEnableMultiRowSelection.value = config.enableMultiRowSelection;
539
+ draftCellStyles.value = config.cellStyles;
540
+ draftPaginationLeft.value = config.paginationLeft;
541
+ draftPaginationRight.value = config.paginationRight;
542
+ draftPageSize.value = getInitialPageSize(config);
543
+ initializeInitialStateGroups(config);
544
+ childSearch.value = "";
545
+ selectedItemId.value = "general";
546
+ clearExpressionValidation();
547
+ }
548
+ watch(() => props.config, (config) => {
549
+ if (!open.value) {
550
+ resetDraftState(config);
551
+ }
552
+ }, { immediate: true });
553
+ const leftPinnedSortable = useSortable(leftPinnedSortableListRef, leftPinnedSortableItemIds);
554
+ const centerSortable = useSortable(centerSortableListRef, centerSortableItemIds);
555
+ const rightPinnedSortable = useSortable(rightPinnedSortableListRef, rightPinnedSortableItemIds);
556
+ const childSortable = useSortable(selectedChildSortableListRef, selectedChildSortableItemIds);
557
+ function syncSortableItemIds() {
558
+ leftPinnedSortableItemIds.value = leftPinnedRootItemIds.value.slice();
559
+ centerSortableItemIds.value = centerRootItemIds.value.slice();
560
+ rightPinnedSortableItemIds.value = rightPinnedRootItemIds.value.slice();
561
+ selectedChildSortableItemIds.value = selectedColumnNode.value?.childItemIds.slice() ?? [];
562
+ }
563
+ function normalizeInitialStateGroups() {
564
+ const rootItemIdSet = new Set(rootInitialStateItems.value.map((item) => item.itemId));
565
+ const manageableRootItemIdSet = new Set(
566
+ rootInitialStateItems.value.filter((item) => item.canManage).map((item) => item.itemId)
567
+ );
568
+ const leftItemIds = [];
569
+ const centerItemIds = [];
570
+ const rightItemIds = [];
571
+ for (const itemId of leftPinnedRootItemIds.value) {
572
+ if (!rootItemIdSet.has(itemId) || !manageableRootItemIdSet.has(itemId) || leftItemIds.includes(itemId)) {
573
+ continue;
574
+ }
575
+ leftItemIds.push(itemId);
576
+ }
577
+ for (const itemId of centerRootItemIds.value) {
578
+ if (!rootItemIdSet.has(itemId) || leftItemIds.includes(itemId) || centerItemIds.includes(itemId)) {
579
+ continue;
580
+ }
581
+ centerItemIds.push(itemId);
582
+ }
583
+ for (const itemId of rightPinnedRootItemIds.value) {
584
+ if (!rootItemIdSet.has(itemId) || !manageableRootItemIdSet.has(itemId) || leftItemIds.includes(itemId) || centerItemIds.includes(itemId) || rightItemIds.includes(itemId)) {
585
+ continue;
586
+ }
587
+ rightItemIds.push(itemId);
588
+ }
589
+ for (const item of rootInitialStateItems.value) {
590
+ if (leftItemIds.includes(item.itemId) || centerItemIds.includes(item.itemId) || rightItemIds.includes(item.itemId)) {
591
+ continue;
592
+ }
593
+ centerItemIds.push(item.itemId);
594
+ }
595
+ leftPinnedRootItemIds.value = leftItemIds;
596
+ centerRootItemIds.value = centerItemIds;
597
+ rightPinnedRootItemIds.value = rightItemIds;
598
+ }
599
+ function handleLeftPinnedSortableUpdate(event) {
600
+ const oldIndex = event.oldIndex;
601
+ const newIndex = event.newIndex;
602
+ if (selectedItemId.value !== "general" || oldIndex === void 0 || newIndex === void 0 || oldIndex === newIndex) {
603
+ return;
604
+ }
605
+ leftPinnedRootItemIds.value = reorderItemIds(
606
+ leftPinnedRootItemIds.value,
607
+ oldIndex,
608
+ newIndex
609
+ );
610
+ }
611
+ function handleCenterSortableUpdate(event) {
612
+ const oldIndex = event.oldIndex;
613
+ const newIndex = event.newIndex;
614
+ if (selectedItemId.value !== "general" || oldIndex === void 0 || newIndex === void 0 || oldIndex === newIndex) {
615
+ return;
616
+ }
617
+ centerRootItemIds.value = reorderItemIds(
618
+ centerRootItemIds.value,
619
+ oldIndex,
620
+ newIndex
621
+ );
622
+ }
623
+ function handleRightPinnedSortableUpdate(event) {
624
+ const oldIndex = event.oldIndex;
625
+ const newIndex = event.newIndex;
626
+ if (selectedItemId.value !== "general" || oldIndex === void 0 || newIndex === void 0 || oldIndex === newIndex) {
627
+ return;
628
+ }
629
+ rightPinnedRootItemIds.value = reorderItemIds(
630
+ rightPinnedRootItemIds.value,
631
+ oldIndex,
632
+ newIndex
633
+ );
634
+ }
635
+ function handleChildSortableUpdate(event) {
636
+ const oldIndex = event.oldIndex;
637
+ const newIndex = event.newIndex;
638
+ const node = selectedColumnNode.value;
639
+ if (!node || oldIndex === void 0 || newIndex === void 0 || oldIndex === newIndex) {
640
+ return;
641
+ }
642
+ draftColumnTree.value = moveTableConfiguratorColumnSibling(
643
+ draftColumnTree.value,
644
+ node.itemId,
645
+ oldIndex,
646
+ newIndex
647
+ );
648
+ }
649
+ function configureLeftPinnedSortable() {
650
+ leftPinnedSortable.option("animation", 150);
651
+ leftPinnedSortable.option("handle", '[data-slot="table-configurator-initial-state-left-drag-handle"]');
652
+ leftPinnedSortable.option("onUpdate", handleLeftPinnedSortableUpdate);
653
+ }
654
+ function configureCenterSortable() {
655
+ centerSortable.option("animation", 150);
656
+ centerSortable.option("handle", '[data-slot="table-configurator-initial-state-center-drag-handle"]');
657
+ centerSortable.option("onUpdate", handleCenterSortableUpdate);
658
+ }
659
+ function configureRightPinnedSortable() {
660
+ rightPinnedSortable.option("animation", 150);
661
+ rightPinnedSortable.option("handle", '[data-slot="table-configurator-initial-state-right-drag-handle"]');
662
+ rightPinnedSortable.option("onUpdate", handleRightPinnedSortableUpdate);
663
+ }
664
+ function configureChildSortable() {
665
+ childSortable.option("animation", 150);
666
+ childSortable.option("handle", '[data-slot="table-configurator-child-drag-handle"]');
667
+ childSortable.option("onUpdate", handleChildSortableUpdate);
668
+ }
669
+ async function refreshSortable() {
670
+ leftPinnedSortable.stop();
671
+ centerSortable.stop();
672
+ rightPinnedSortable.stop();
673
+ childSortable.stop();
674
+ if (!open.value) {
675
+ return;
676
+ }
677
+ await nextTick();
678
+ if (selectedItemId.value === "general") {
679
+ leftPinnedSortable.start();
680
+ centerSortable.start();
681
+ rightPinnedSortable.start();
682
+ configureLeftPinnedSortable();
683
+ configureCenterSortable();
684
+ configureRightPinnedSortable();
685
+ return;
686
+ }
687
+ if (selectedColumnNode.value) {
688
+ childSortable.start();
689
+ configureChildSortable();
690
+ }
691
+ }
692
+ watch(rootInitialStateItems, () => {
693
+ normalizeInitialStateGroups();
694
+ }, { immediate: true });
695
+ watch([draftColumnTree, selectedItemId, leftPinnedRootItemIds, centerRootItemIds, rightPinnedRootItemIds], () => {
696
+ syncSortableItemIds();
697
+ }, { immediate: true });
698
+ watch(open, async (value) => {
699
+ if (value) {
700
+ resetDraftState(props.config);
701
+ await refreshSortable();
702
+ return;
703
+ }
704
+ leftPinnedSortable.stop();
705
+ centerSortable.stop();
706
+ rightPinnedSortable.stop();
707
+ childSortable.stop();
708
+ childSearch.value = "";
709
+ search.value = "";
710
+ }, { immediate: true });
711
+ watch(selectedItemId, async () => {
712
+ childSearch.value = "";
713
+ clearAccessorValidation();
714
+ clearRendererValidation();
715
+ selectedColumnAccessorMode.value = getColumnAccessorMode(selectedColumn.value);
716
+ if (!open.value) {
717
+ return;
718
+ }
719
+ await refreshSortable();
720
+ });
721
+ watch(selectedColumnAccessorMode, (value, oldValue) => {
722
+ if (value === oldValue) {
723
+ return;
724
+ }
725
+ updateSelectedColumnAccessorMode(value);
726
+ });
727
+ watch(columnListItems, (items) => {
728
+ if (selectedItemId.value === "general") {
729
+ return;
730
+ }
731
+ if (!items.some((item) => item.itemId === selectedItemId.value)) {
732
+ selectedItemId.value = "general";
733
+ }
734
+ }, { immediate: true });
735
+ watch(filteredColumnItems, (items) => {
736
+ if (!normalizedSearch.value || selectedItemId.value === "general") {
737
+ return;
738
+ }
739
+ if (items.some((item) => item.itemId === selectedItemId.value)) {
740
+ return;
741
+ }
742
+ selectedItemId.value = items[0]?.itemId ?? "general";
743
+ }, { immediate: true });
744
+ watch(selectedColumnRendererId, () => {
745
+ clearRendererValidation();
746
+ });
747
+ function hasVisibleTitle(value) {
748
+ return value?.some((item) => item.message.trim().length > 0) ?? false;
749
+ }
750
+ function normalizeColumn(column) {
751
+ const title = hasVisibleTitle(column.title) ? column.title : void 0;
752
+ const tooltip = hasVisibleTitle(column.tooltip) ? column.tooltip : void 0;
753
+ const normalizedChildren = column.columns?.map(normalizeColumn);
754
+ return {
755
+ ...column,
756
+ title,
757
+ tooltip,
758
+ columns: normalizedChildren?.length ? normalizedChildren : void 0
759
+ };
760
+ }
761
+ function discardChanges() {
762
+ resetDraftState(props.config);
763
+ childSearch.value = "";
764
+ search.value = "";
765
+ open.value = false;
766
+ }
767
+ function handleOpenChange(value) {
768
+ if (value) {
769
+ open.value = true;
770
+ return;
771
+ }
772
+ discardChanges();
773
+ }
774
+ function selectGeneral() {
775
+ selectedItemId.value = "general";
776
+ }
777
+ function selectItem(itemId) {
778
+ selectedItemId.value = itemId;
779
+ }
780
+ function moveRootItemToGroup(itemId, group) {
781
+ const nextLeftItemIds = leftPinnedRootItemIds.value.filter((currentItemId) => currentItemId !== itemId);
782
+ const nextCenterItemIds = centerRootItemIds.value.filter((currentItemId) => currentItemId !== itemId);
783
+ const nextRightItemIds = rightPinnedRootItemIds.value.filter((currentItemId) => currentItemId !== itemId);
784
+ if (group === "left") {
785
+ nextLeftItemIds.push(itemId);
786
+ } else if (group === "center") {
787
+ nextCenterItemIds.push(itemId);
788
+ } else {
789
+ nextRightItemIds.push(itemId);
790
+ }
791
+ leftPinnedRootItemIds.value = nextLeftItemIds;
792
+ centerRootItemIds.value = nextCenterItemIds;
793
+ rightPinnedRootItemIds.value = nextRightItemIds;
794
+ }
795
+ function addColumn() {
796
+ const nextNode = createTableConfiguratorDraftColumnNode({
797
+ id: crypto.randomUUID()
798
+ });
799
+ draftColumnTree.value = insertTableConfiguratorRootColumnNode(draftColumnTree.value, nextNode);
800
+ selectedItemId.value = nextNode.itemId;
801
+ }
802
+ function deleteColumn(itemId) {
803
+ const flattenedItems = flattenTableConfiguratorColumnTree(draftColumnTree.value);
804
+ const deleteIndex = flattenedItems.findIndex((item) => item.itemId === itemId);
805
+ if (deleteIndex < 0) {
806
+ return;
807
+ }
808
+ const removedItemIds = [itemId, ...getTableConfiguratorColumnDescendantItemIds(draftColumnTree.value, itemId)];
809
+ const nextTree = removeTableConfiguratorColumnSubtree(draftColumnTree.value, itemId);
810
+ draftColumnTree.value = nextTree;
811
+ if (!removedItemIds.includes(selectedItemId.value)) {
812
+ return;
813
+ }
814
+ const nextFlattenedItems = flattenTableConfiguratorColumnTree(nextTree);
815
+ const nextSelectedItem = nextFlattenedItems[deleteIndex] ?? nextFlattenedItems[deleteIndex - 1];
816
+ selectedItemId.value = nextSelectedItem?.itemId ?? "general";
817
+ }
818
+ function updateSelectedColumnTitle(value) {
819
+ const node = selectedColumnNode.value;
820
+ if (!node) {
821
+ return;
822
+ }
823
+ draftColumnTree.value = updateTableConfiguratorColumnNode(
824
+ draftColumnTree.value,
825
+ node.itemId,
826
+ (column) => ({
827
+ ...column,
828
+ title: value
829
+ })
830
+ );
831
+ }
832
+ function updateSelectedColumnTooltip(value) {
833
+ const node = selectedColumnNode.value;
834
+ if (!node) {
835
+ return;
836
+ }
837
+ draftColumnTree.value = updateTableConfiguratorColumnNode(
838
+ draftColumnTree.value,
839
+ node.itemId,
840
+ (column) => ({
841
+ ...column,
842
+ tooltip: value
843
+ })
844
+ );
845
+ }
846
+ function updateSelectedColumnAccessor(accessor) {
847
+ const node = selectedColumnNode.value;
848
+ if (!node) {
849
+ return;
850
+ }
851
+ draftColumnTree.value = updateTableConfiguratorColumnNode(
852
+ draftColumnTree.value,
853
+ node.itemId,
854
+ (column) => ({
855
+ ...column,
856
+ accessor
857
+ })
858
+ );
859
+ }
860
+ function updateSelectedColumnSize(value) {
861
+ const node = selectedColumnNode.value;
862
+ if (!node) {
863
+ return;
864
+ }
865
+ draftColumnTree.value = updateTableConfiguratorColumnNode(
866
+ draftColumnTree.value,
867
+ node.itemId,
868
+ (column) => ({
869
+ ...column,
870
+ size: normalizeOptionalNumber(value)
871
+ })
872
+ );
873
+ }
874
+ function updateSelectedColumnGrow(value) {
875
+ const node = selectedColumnNode.value;
876
+ if (!node) {
877
+ return;
878
+ }
879
+ draftColumnTree.value = updateTableConfiguratorColumnNode(
880
+ draftColumnTree.value,
881
+ node.itemId,
882
+ (column) => ({
883
+ ...column,
884
+ grow: value === true
885
+ })
886
+ );
887
+ }
888
+ function updateSelectedColumnEnableSorting(value) {
889
+ const node = selectedColumnNode.value;
890
+ if (!node) {
891
+ return;
892
+ }
893
+ draftColumnTree.value = updateTableConfiguratorColumnNode(
894
+ draftColumnTree.value,
895
+ node.itemId,
896
+ (column) => ({
897
+ ...column,
898
+ enableSorting: value === true
899
+ })
900
+ );
901
+ }
902
+ function updateSelectedColumnAccessorPath(value) {
903
+ updateSelectedColumnAccessor(value);
904
+ }
905
+ function updateSelectedColumnAccessorRead(value) {
906
+ const currentAccessor = selectedColumnAccessorExpression.value;
907
+ const nextRead = value ?? "";
908
+ const nextWrite = currentAccessor.write;
909
+ if (nextRead.length === 0 && nextWrite.length === 0) {
910
+ updateSelectedColumnAccessor(void 0);
911
+ return;
912
+ }
913
+ updateSelectedColumnAccessor({
914
+ read: nextRead,
915
+ write: nextWrite
916
+ });
917
+ }
918
+ function updateSelectedColumnAccessorWrite(value) {
919
+ const currentAccessor = selectedColumnAccessorExpression.value;
920
+ const nextRead = currentAccessor.read;
921
+ const nextWrite = value ?? "";
922
+ if (nextRead.length === 0 && nextWrite.length === 0) {
923
+ updateSelectedColumnAccessor(void 0);
924
+ return;
925
+ }
926
+ updateSelectedColumnAccessor({
927
+ read: nextRead,
928
+ write: nextWrite
929
+ });
930
+ }
931
+ function updateSelectedColumnAccessorMode(value) {
932
+ const column = selectedColumn.value;
933
+ if (!column) {
934
+ return;
935
+ }
936
+ if (value === "path") {
937
+ updateSelectedColumnAccessor(getColumnAccessorPath(column));
938
+ clearAccessorValidation();
939
+ return;
940
+ }
941
+ const accessor = getColumnAccessorExpression(column);
942
+ updateSelectedColumnAccessor({
943
+ read: accessor.read,
944
+ write: accessor.write
945
+ });
946
+ clearAccessorValidation();
947
+ }
948
+ function updateSelectedColumnRendererId(value) {
949
+ const node = selectedColumnNode.value;
950
+ if (!node || typeof value !== "string") {
951
+ return;
952
+ }
953
+ draftColumnTree.value = updateTableConfiguratorColumnNode(
954
+ draftColumnTree.value,
955
+ node.itemId,
956
+ (column) => ({
957
+ ...column,
958
+ renderer: buildColumnRenderer(value, void 0)
959
+ })
960
+ );
961
+ }
962
+ function updateSelectedColumnRendererProps(value) {
963
+ const node = selectedColumnNode.value;
964
+ if (!node) {
965
+ return;
966
+ }
967
+ draftColumnTree.value = updateTableConfiguratorColumnNode(
968
+ draftColumnTree.value,
969
+ node.itemId,
970
+ (column) => ({
971
+ ...column,
972
+ renderer: buildColumnRenderer(selectedColumnRendererId.value, value)
973
+ })
974
+ );
975
+ }
976
+ function toggleChildSelection(itemId, value) {
977
+ const node = selectedColumnNode.value;
978
+ if (!node || value !== true) {
979
+ return;
980
+ }
981
+ draftColumnTree.value = moveTableConfiguratorColumnNodeToParent(
982
+ draftColumnTree.value,
983
+ itemId,
984
+ node.itemId
985
+ );
986
+ }
987
+ function removeSelectedChild(itemId) {
988
+ const node = selectedColumnNode.value;
989
+ if (!node) {
990
+ return;
991
+ }
992
+ draftColumnTree.value = moveTableConfiguratorColumnNodeAfterItem(
993
+ draftColumnTree.value,
994
+ itemId,
995
+ node.itemId
996
+ );
997
+ }
998
+ function clearExpressionValidation() {
999
+ getRowIdEditor.value?.clearValidation();
1000
+ getSubRowsEditor.value?.clearValidation();
1001
+ enableRowSelectionEditor.value?.clearValidation();
1002
+ enableMultiRowSelectionEditor.value?.clearValidation();
1003
+ cellStylesEditor.value?.clearValidation();
1004
+ clearAccessorValidation();
1005
+ clearRendererValidation();
1006
+ }
1007
+ function clearAccessorValidation() {
1008
+ accessorPathEditor.value?.clearValidation();
1009
+ accessorReadEditor.value?.clearValidation();
1010
+ accessorWriteEditor.value?.clearValidation();
1011
+ }
1012
+ function clearRendererValidation() {
1013
+ if (isRendererConfigExposed(selectedRendererConfigRef.value)) {
1014
+ selectedRendererConfigRef.value.clearValidation();
1015
+ }
1016
+ }
1017
+ function validateExpressionEditors() {
1018
+ let isValid = true;
1019
+ if (getRowIdEditor.value && !getRowIdEditor.value.validate()) {
1020
+ isValid = false;
1021
+ }
1022
+ if (getSubRowsEditor.value && !getSubRowsEditor.value.validate()) {
1023
+ isValid = false;
1024
+ }
1025
+ if (enableRowSelectionEditor.value && !enableRowSelectionEditor.value.validate()) {
1026
+ isValid = false;
1027
+ }
1028
+ if (enableMultiRowSelectionEditor.value && !enableMultiRowSelectionEditor.value.validate()) {
1029
+ isValid = false;
1030
+ }
1031
+ if (cellStylesEditor.value && !cellStylesEditor.value.validate()) {
1032
+ isValid = false;
1033
+ }
1034
+ if (selectedColumn.value && selectedColumnAccessorMode.value === "path" && selectedColumnAccessorPath.value !== void 0 && accessorPathEditor.value && !accessorPathEditor.value.validate()) {
1035
+ isValid = false;
1036
+ }
1037
+ if (selectedColumn.value && selectedColumnAccessorMode.value === "expression") {
1038
+ const accessor = selectedColumn.value.accessor;
1039
+ if (!accessor || typeof accessor === "string") {
1040
+ return validateRendererConfig(isValid);
1041
+ }
1042
+ if (accessorReadEditor.value && !accessorReadEditor.value.validate()) {
1043
+ isValid = false;
1044
+ }
1045
+ if (accessorWriteEditor.value && !accessorWriteEditor.value.validate()) {
1046
+ isValid = false;
1047
+ }
1048
+ }
1049
+ return validateRendererConfig(isValid);
1050
+ }
1051
+ function validateRendererConfig(currentIsValid) {
1052
+ if (!selectedColumn.value || selectedColumnHasChildren.value) {
1053
+ return currentIsValid;
1054
+ }
1055
+ if (isRendererConfigExposed(selectedRendererConfigRef.value) && !selectedRendererConfigRef.value.validate()) {
1056
+ return false;
1057
+ }
1058
+ return currentIsValid;
1059
+ }
1060
+ function buildInitialStateLeafColumnIds(itemIds) {
1061
+ const leafColumnIds = [];
1062
+ for (const itemId of itemIds) {
1063
+ const item = rootInitialStateItems.value.find((candidate) => candidate.itemId === itemId);
1064
+ if (!item?.canManage) {
1065
+ continue;
1066
+ }
1067
+ leafColumnIds.push(...item.leafColumnIds);
1068
+ }
1069
+ return leafColumnIds;
1070
+ }
1071
+ function updateDraftPaginationLeft(value) {
1072
+ draftPaginationLeft.value = normalizeOptionalText(String(value));
1073
+ }
1074
+ function updateDraftPaginationRight(value) {
1075
+ draftPaginationRight.value = normalizeOptionalText(String(value));
1076
+ }
1077
+ function updateDraftPageSize(value) {
1078
+ draftPageSize.value = normalizeOptionalNumber(value);
1079
+ }
1080
+ function buildNextPaginationState() {
1081
+ const currentPagination = draftBaseConfig.value.props?.initialState?.pagination;
1082
+ const nextPageSize = draftPageSize.value;
1083
+ if (!currentPagination && nextPageSize === void 0) {
1084
+ return void 0;
1085
+ }
1086
+ return {
1087
+ ...currentPagination,
1088
+ pageSize: nextPageSize
1089
+ };
1090
+ }
1091
+ function buildDraftConfig() {
1092
+ return TableConfigC.safeParse({
1093
+ ...draftBaseConfig.value,
1094
+ getRowId: draftGetRowId.value,
1095
+ getSubRows: draftGetSubRows.value,
1096
+ enableRowSelection: draftEnableRowSelection.value,
1097
+ enableMultiRowSelection: draftEnableMultiRowSelection.value,
1098
+ cellStyles: draftCellStyles.value,
1099
+ paginationLeft: normalizeOptionalText(draftPaginationLeft.value),
1100
+ paginationRight: normalizeOptionalText(draftPaginationRight.value),
1101
+ columns: materializeTableConfiguratorColumnTree(draftColumnTree.value).map(normalizeColumn),
1102
+ props: {
1103
+ ...draftBaseConfig.value.props,
1104
+ initialState: {
1105
+ ...draftBaseConfig.value.props?.initialState,
1106
+ columnPinning: {
1107
+ ...draftBaseConfig.value.props?.initialState?.columnPinning,
1108
+ left: buildInitialStateLeafColumnIds(leftPinnedRootItemIds.value),
1109
+ right: buildInitialStateLeafColumnIds(rightPinnedRootItemIds.value)
1110
+ },
1111
+ columnOrder: buildInitialStateLeafColumnIds(centerRootItemIds.value),
1112
+ pagination: buildNextPaginationState()
1113
+ }
1114
+ }
1115
+ });
1116
+ }
1117
+ function triggerImport() {
1118
+ importInputRef.value?.click();
1119
+ }
1120
+ function showImportError(message) {
1121
+ $toast.error(message);
1122
+ }
1123
+ function showExportError() {
1124
+ $toast.error(t("export-config-failed"));
1125
+ }
1126
+ async function handleImportChange(event) {
1127
+ const target = event.target;
1128
+ if (!(target instanceof HTMLInputElement)) {
1129
+ return;
1130
+ }
1131
+ const file = target.files?.[0];
1132
+ try {
1133
+ if (!file) {
1134
+ return;
1135
+ }
1136
+ const source = await file.text();
1137
+ let parsedValue;
1138
+ try {
1139
+ parsedValue = JSON.parse(source);
1140
+ } catch {
1141
+ showImportError(t("import-config-invalid-json"));
1142
+ return;
1143
+ }
1144
+ const result = TableConfigC.safeParse(parsedValue);
1145
+ if (!result.success) {
1146
+ showImportError(t("import-config-invalid-schema"));
1147
+ return;
1148
+ }
1149
+ resetDraftState(result.data);
1150
+ await nextTick();
1151
+ await refreshSortable();
1152
+ } finally {
1153
+ target.value = "";
1154
+ }
1155
+ }
1156
+ function exportConfig() {
1157
+ if (!validateExpressionEditors()) {
1158
+ showExportError();
1159
+ return;
1160
+ }
1161
+ const result = buildDraftConfig();
1162
+ if (!result.success) {
1163
+ showExportError();
1164
+ return;
1165
+ }
1166
+ try {
1167
+ const blob = new Blob([JSON.stringify(result.data, null, 2)], { type: "application/json" });
1168
+ const url = URL.createObjectURL(blob);
1169
+ const link = document.createElement("a");
1170
+ link.href = url;
1171
+ link.download = "table-config.json";
1172
+ document.body.append(link);
1173
+ link.click();
1174
+ link.remove();
1175
+ URL.revokeObjectURL(url);
1176
+ } catch {
1177
+ showExportError();
1178
+ }
1179
+ }
1180
+ function confirmChanges() {
1181
+ if (!validateExpressionEditors()) {
1182
+ return;
1183
+ }
1184
+ const result = buildDraftConfig();
1185
+ if (!result.success) {
1186
+ return;
1187
+ }
1188
+ emit("confirm", result.data);
1189
+ search.value = "";
1190
+ open.value = false;
1191
+ }
1192
+ </script>
1193
+
1194
+ <template>
1195
+ <Dialog
1196
+ :open="open"
1197
+ @update:open="handleOpenChange"
1198
+ >
1199
+ <DialogContent
1200
+ class="flex h-[min(42rem,calc(100vh-4rem))] w-[calc(100%-2rem)] max-h-[calc(100vh-4rem)] max-w-[calc(100%-2rem)] flex-col overflow-hidden p-0 sm:w-[80vw] sm:max-w-[80vw]"
1201
+ :show-close-button="true"
1202
+ >
1203
+ <DialogHeader class="gap-1 border-b border-zinc-200 px-6 py-5">
1204
+ <div class="flex items-center gap-3">
1205
+ <DialogTitle class="text-xl font-semibold text-zinc-800">
1206
+ {{ t("configure-table") }}
1207
+ </DialogTitle>
1208
+ <Button
1209
+ type="button"
1210
+ variant="ghost"
1211
+ size="sm"
1212
+ data-slot="table-configurator-import"
1213
+ class="shrink-0"
1214
+ @click="triggerImport"
1215
+ >
1216
+ <Icon icon="fluent:arrow-upload-20-regular" />
1217
+ {{ t("import-config") }}
1218
+ </Button>
1219
+ <input
1220
+ ref="importInputRef"
1221
+ data-slot="table-configurator-import-input"
1222
+ class="hidden"
1223
+ type="file"
1224
+ accept="application/json,.json"
1225
+ @change="handleImportChange"
1226
+ >
1227
+ </div>
1228
+ <DialogDescription class="text-sm text-zinc-500">
1229
+ {{ t("configure-table-description") }}
1230
+ </DialogDescription>
1231
+ </DialogHeader>
1232
+
1233
+ <div class="grid min-h-0 flex-1 grid-cols-[19rem_minmax(0,1fr)]">
1234
+ <section class="flex min-h-0 flex-col border-r border-zinc-200 px-4 py-4">
1235
+ <Input
1236
+ v-model="search"
1237
+ data-slot="table-configurator-search"
1238
+ :placeholder="t('search-columns')"
1239
+ />
1240
+
1241
+ <Button
1242
+ type="button"
1243
+ data-slot="table-configurator-add"
1244
+ class="mt-3 w-full justify-center"
1245
+ @click="addColumn"
1246
+ >
1247
+ <Icon icon="fluent:add-20-regular" />
1248
+ {{ t("add-column") }}
1249
+ </Button>
1250
+
1251
+ <div class="mt-4 flex min-h-0 flex-1 flex-col overflow-hidden">
1252
+ <div class="flex min-h-0 flex-1 flex-col gap-1 overflow-y-auto pr-1">
1253
+ <button
1254
+ type="button"
1255
+ data-slot="table-configurator-item"
1256
+ data-item-id="general"
1257
+ :data-selected="selectedItemId === 'general' ? 'true' : 'false'"
1258
+ :class="cn(
1259
+ 'flex w-full items-center rounded-md border p-1 text-left transition-colors',
1260
+ selectedItemId === 'general' ? 'border-(--primary)/25 bg-[color-mix(in_srgb,var(--primary)_10%,white)]' : 'border-transparent hover:border-zinc-200 hover:bg-zinc-50'
1261
+ )"
1262
+ @click="selectGeneral"
1263
+ >
1264
+ <span class="truncate px-2 py-2 text-sm font-medium text-zinc-800">{{ generalItem.label }}</span>
1265
+ </button>
1266
+
1267
+ <div
1268
+ data-slot="table-configurator-column-list"
1269
+ class="flex flex-col gap-1"
1270
+ >
1271
+ <div
1272
+ v-for="item in filteredColumnItems"
1273
+ :key="item.itemId"
1274
+ data-slot="table-configurator-item"
1275
+ :data-item-id="item.itemId"
1276
+ :data-selected="selectedItemId === item.itemId ? 'true' : 'false'"
1277
+ :class="cn(
1278
+ 'flex w-full items-center gap-2 rounded-md border p-1 transition-colors',
1279
+ selectedItemId === item.itemId ? 'border-(--primary)/25 bg-[color-mix(in_srgb,var(--primary)_10%,white)]' : 'border-transparent hover:border-zinc-200 hover:bg-zinc-50'
1280
+ )"
1281
+ @click="selectItem(item.itemId)"
1282
+ >
1283
+ <button
1284
+ type="button"
1285
+ class="min-w-0 flex-1 px-2 py-2 text-left"
1286
+ >
1287
+ <span class="block truncate text-sm font-medium text-zinc-800">{{ item.label }}</span>
1288
+ </button>
1289
+
1290
+ <button
1291
+ type="button"
1292
+ data-slot="table-configurator-delete"
1293
+ class="flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-sm text-zinc-400 transition-colors hover:bg-red-50 hover:text-red-600"
1294
+ :aria-label="t('delete-column', { column: item.label })"
1295
+ @click.stop="deleteColumn(item.itemId)"
1296
+ >
1297
+ <Icon icon="fluent:delete-20-regular" />
1298
+ </button>
1299
+ </div>
1300
+ </div>
1301
+
1302
+ <p
1303
+ v-if="normalizedSearch && filteredColumnItems.length === 0"
1304
+ data-slot="table-configurator-empty"
1305
+ class="px-1 pt-2 text-xs text-zinc-400"
1306
+ >
1307
+ {{ t("no-matches") }}
1308
+ </p>
1309
+ </div>
1310
+ </div>
1311
+ </section>
1312
+
1313
+ <section class="flex min-h-0 flex-col overflow-y-auto px-6 py-6">
1314
+ <div class="flex items-center gap-2">
1315
+ <h3
1316
+ data-slot="table-configurator-detail-title"
1317
+ class="text-lg font-semibold text-zinc-800"
1318
+ >
1319
+ {{ selectedItemLabel }}
1320
+ </h3>
1321
+ <Button
1322
+ v-if="selectedColumnTechnicalKey"
1323
+ type="button"
1324
+ variant="ghost"
1325
+ size="sm"
1326
+ data-slot="table-configurator-copy-id"
1327
+ class="size-7 p-0 text-zinc-400 hover:text-zinc-700"
1328
+ :aria-label="t('copy-column-id', { column: selectedItemLabel })"
1329
+ :title="selectedColumnTechnicalKey"
1330
+ @click="copySelectedColumnId"
1331
+ >
1332
+ <Icon icon="fluent:copy-20-regular" />
1333
+ </Button>
1334
+ </div>
1335
+ <p
1336
+ v-if="selectedItemId === 'general'"
1337
+ data-slot="table-configurator-detail-description"
1338
+ class="mt-2 text-sm text-zinc-500"
1339
+ >
1340
+ {{ t("general-placeholder") }}
1341
+ </p>
1342
+
1343
+ <div
1344
+ v-if="selectedItemId === 'general'"
1345
+ data-slot="table-configurator-general-fields"
1346
+ class="mt-6 flex flex-col gap-4"
1347
+ >
1348
+ <ExpressionEditor
1349
+ ref="getRowIdEditor"
1350
+ v-model="draftGetRowId"
1351
+ data-field-key="getRowId"
1352
+ :label="t('get-row-id')"
1353
+ :description="t('get-row-id-description')"
1354
+ :placeholder="t('expression-placeholder')"
1355
+ :schema="TableConfigGetRowIdC"
1356
+ />
1357
+
1358
+ <ExpressionEditor
1359
+ ref="getSubRowsEditor"
1360
+ v-model="draftGetSubRows"
1361
+ data-field-key="getSubRows"
1362
+ :label="t('get-sub-rows')"
1363
+ :description="t('get-sub-rows-description')"
1364
+ :placeholder="t('expression-placeholder')"
1365
+ :schema="TableConfigGetSubRowsC"
1366
+ />
1367
+
1368
+ <ExpressionEditor
1369
+ ref="enableRowSelectionEditor"
1370
+ v-model="draftEnableRowSelection"
1371
+ data-field-key="enableRowSelection"
1372
+ :label="t('enable-row-selection')"
1373
+ :description="t('enable-row-selection-description')"
1374
+ :placeholder="t('expression-placeholder')"
1375
+ :schema="TableConfigEnableRowSelectionC"
1376
+ />
1377
+
1378
+ <ExpressionEditor
1379
+ ref="enableMultiRowSelectionEditor"
1380
+ v-model="draftEnableMultiRowSelection"
1381
+ data-field-key="enableMultiRowSelection"
1382
+ :label="t('enable-multi-row-selection')"
1383
+ :description="t('enable-multi-row-selection-description')"
1384
+ :placeholder="t('expression-placeholder')"
1385
+ :schema="TableConfigEnableMultiRowSelectionC"
1386
+ />
1387
+
1388
+ <ExpressionEditor
1389
+ ref="cellStylesEditor"
1390
+ v-model="draftCellStyles"
1391
+ data-field-key="cellStyles"
1392
+ :label="t('cell-styles')"
1393
+ :description="t('cell-styles-description')"
1394
+ :placeholder="t('expression-placeholder')"
1395
+ :schema="TableConfigCellStylesC"
1396
+ />
1397
+
1398
+ <section
1399
+ data-slot="table-configurator-pagination"
1400
+ class="rounded-lg border border-zinc-200 p-4"
1401
+ >
1402
+ <h4 class="text-sm font-semibold text-zinc-800">
1403
+ {{ t("pagination") }}
1404
+ </h4>
1405
+
1406
+ <div class="mt-3 flex flex-col gap-4">
1407
+ <label
1408
+ data-field-key="paginationLeft"
1409
+ class="flex flex-col gap-1"
1410
+ >
1411
+ <span class="text-xs font-medium text-zinc-500">{{ t("pagination-left") }}</span>
1412
+ <Textarea
1413
+ class="min-h-20"
1414
+ :model-value="draftPaginationLeft ?? ''"
1415
+ :placeholder="t('pagination-left-placeholder')"
1416
+ @update:model-value="updateDraftPaginationLeft"
1417
+ />
1418
+ </label>
1419
+
1420
+ <label
1421
+ data-field-key="paginationRight"
1422
+ class="flex flex-col gap-1"
1423
+ >
1424
+ <span class="text-xs font-medium text-zinc-500">{{ t("pagination-right") }}</span>
1425
+ <Textarea
1426
+ class="min-h-20"
1427
+ :model-value="draftPaginationRight ?? ''"
1428
+ :placeholder="t('pagination-right-placeholder')"
1429
+ @update:model-value="updateDraftPaginationRight"
1430
+ />
1431
+ </label>
1432
+
1433
+ <label
1434
+ data-field-key="pageSize"
1435
+ class="flex flex-col gap-1"
1436
+ >
1437
+ <span class="text-xs font-medium text-zinc-500">{{ t("pagination-page-size") }}</span>
1438
+ <NumberField
1439
+ :model-value="draftPageSize"
1440
+ :min="1"
1441
+ @update:model-value="updateDraftPageSize"
1442
+ >
1443
+ <NumberFieldInput class="w-full text-left" />
1444
+ </NumberField>
1445
+ </label>
1446
+ </div>
1447
+ </section>
1448
+
1449
+ <section
1450
+ data-slot="table-configurator-initial-state"
1451
+ class="rounded-lg border border-zinc-200 p-4"
1452
+ >
1453
+ <h4 class="text-sm font-semibold text-zinc-800">
1454
+ {{ t("initial-state") }}
1455
+ </h4>
1456
+
1457
+ <div class="mt-3 flex flex-col gap-4">
1458
+ <section
1459
+ data-slot="table-configurator-initial-state-left"
1460
+ class="rounded-md border border-zinc-200/80 p-3"
1461
+ >
1462
+ <p class="text-xs font-medium text-zinc-500">
1463
+ {{ t("pinned-left-group") }}
1464
+ </p>
1465
+
1466
+ <div
1467
+ v-if="leftPinnedInitialStateItems.length > 0"
1468
+ ref="leftPinnedSortableListRef"
1469
+ class="mt-3 flex flex-col gap-1"
1470
+ >
1471
+ <div
1472
+ v-for="item in leftPinnedInitialStateItems"
1473
+ :key="item.itemId"
1474
+ data-slot="table-configurator-initial-state-left-item"
1475
+ class="flex items-center gap-2 rounded-md border border-transparent p-1"
1476
+ >
1477
+ <button
1478
+ type="button"
1479
+ data-slot="table-configurator-initial-state-left-drag-handle"
1480
+ class="flex size-8 shrink-0 cursor-grab items-center justify-center rounded-sm text-zinc-400 active:cursor-grabbing"
1481
+ :aria-label="t('drag-left-column', { column: item.label })"
1482
+ >
1483
+ <Icon icon="fluent:re-order-dots-vertical-20-regular" />
1484
+ </button>
1485
+
1486
+ <span class="min-w-0 flex-1 truncate px-1 text-sm font-medium text-zinc-800">{{ item.label }}</span>
1487
+
1488
+ <button
1489
+ v-if="item.canManage"
1490
+ type="button"
1491
+ data-slot="table-configurator-unpin-from-left"
1492
+ class="flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-sm text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700"
1493
+ :aria-label="t('unpin-left-column', { column: item.label })"
1494
+ @click="moveRootItemToGroup(item.itemId, 'center')"
1495
+ >
1496
+ <Icon icon="fluent:padding-right-20-regular" />
1497
+ </button>
1498
+ </div>
1499
+ </div>
1500
+
1501
+ <p
1502
+ v-else
1503
+ data-slot="table-configurator-initial-state-left-empty"
1504
+ class="mt-3 text-xs text-zinc-400"
1505
+ >
1506
+ {{ t("no-pinned-left-columns") }}
1507
+ </p>
1508
+ </section>
1509
+
1510
+ <section
1511
+ data-slot="table-configurator-initial-state-center"
1512
+ class="rounded-md border border-zinc-200/80 p-3"
1513
+ >
1514
+ <p class="text-xs font-medium text-zinc-500">
1515
+ {{ t("pinned-center-group") }}
1516
+ </p>
1517
+
1518
+ <div
1519
+ v-if="centerInitialStateItems.length > 0"
1520
+ ref="centerSortableListRef"
1521
+ class="mt-3 flex flex-col gap-1"
1522
+ >
1523
+ <div
1524
+ v-for="item in centerInitialStateItems"
1525
+ :key="item.itemId"
1526
+ data-slot="table-configurator-initial-state-center-item"
1527
+ class="flex items-center gap-2 rounded-md border border-transparent p-1"
1528
+ >
1529
+ <button
1530
+ type="button"
1531
+ data-slot="table-configurator-initial-state-center-drag-handle"
1532
+ class="flex size-8 shrink-0 cursor-grab items-center justify-center rounded-sm text-zinc-400 active:cursor-grabbing"
1533
+ :aria-label="t('drag-center-column', { column: item.label })"
1534
+ >
1535
+ <Icon icon="fluent:re-order-dots-vertical-20-regular" />
1536
+ </button>
1537
+
1538
+ <span class="min-w-0 flex-1 truncate px-1 text-sm font-medium text-zinc-800">{{ item.label }}</span>
1539
+
1540
+ <div
1541
+ v-if="item.canManage"
1542
+ class="flex items-center gap-1"
1543
+ >
1544
+ <button
1545
+ type="button"
1546
+ data-slot="table-configurator-pin-left"
1547
+ class="flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-sm text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700"
1548
+ :aria-label="t('pin-left-column', { column: item.label })"
1549
+ @click="moveRootItemToGroup(item.itemId, 'left')"
1550
+ >
1551
+ <Icon icon="fluent:padding-left-20-regular" />
1552
+ </button>
1553
+
1554
+ <button
1555
+ type="button"
1556
+ data-slot="table-configurator-pin-right"
1557
+ class="flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-sm text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700"
1558
+ :aria-label="t('pin-right-column', { column: item.label })"
1559
+ @click="moveRootItemToGroup(item.itemId, 'right')"
1560
+ >
1561
+ <Icon icon="fluent:padding-right-20-regular" />
1562
+ </button>
1563
+ </div>
1564
+ </div>
1565
+ </div>
1566
+
1567
+ <p
1568
+ v-else
1569
+ data-slot="table-configurator-initial-state-center-empty"
1570
+ class="mt-3 text-xs text-zinc-400"
1571
+ >
1572
+ {{ t("no-pinned-center-columns") }}
1573
+ </p>
1574
+ </section>
1575
+
1576
+ <section
1577
+ data-slot="table-configurator-initial-state-right"
1578
+ class="rounded-md border border-zinc-200/80 p-3"
1579
+ >
1580
+ <p class="text-xs font-medium text-zinc-500">
1581
+ {{ t("pinned-right-group") }}
1582
+ </p>
1583
+
1584
+ <div
1585
+ v-if="rightPinnedInitialStateItems.length > 0"
1586
+ ref="rightPinnedSortableListRef"
1587
+ class="mt-3 flex flex-col gap-1"
1588
+ >
1589
+ <div
1590
+ v-for="item in rightPinnedInitialStateItems"
1591
+ :key="item.itemId"
1592
+ data-slot="table-configurator-initial-state-right-item"
1593
+ class="flex items-center gap-2 rounded-md border border-transparent p-1"
1594
+ >
1595
+ <button
1596
+ type="button"
1597
+ data-slot="table-configurator-initial-state-right-drag-handle"
1598
+ class="flex size-8 shrink-0 cursor-grab items-center justify-center rounded-sm text-zinc-400 active:cursor-grabbing"
1599
+ :aria-label="t('drag-right-column', { column: item.label })"
1600
+ >
1601
+ <Icon icon="fluent:re-order-dots-vertical-20-regular" />
1602
+ </button>
1603
+
1604
+ <span class="min-w-0 flex-1 truncate px-1 text-sm font-medium text-zinc-800">{{ item.label }}</span>
1605
+
1606
+ <button
1607
+ v-if="item.canManage"
1608
+ type="button"
1609
+ data-slot="table-configurator-unpin-from-right"
1610
+ class="flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-sm text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700"
1611
+ :aria-label="t('unpin-right-column', { column: item.label })"
1612
+ @click="moveRootItemToGroup(item.itemId, 'center')"
1613
+ >
1614
+ <Icon icon="fluent:padding-left-20-regular" />
1615
+ </button>
1616
+ </div>
1617
+ </div>
1618
+
1619
+ <p
1620
+ v-else
1621
+ data-slot="table-configurator-initial-state-right-empty"
1622
+ class="mt-3 text-xs text-zinc-400"
1623
+ >
1624
+ {{ t("no-pinned-right-columns") }}
1625
+ </p>
1626
+ </section>
1627
+ </div>
1628
+ </section>
1629
+ </div>
1630
+
1631
+ <div
1632
+ v-else-if="selectedColumn"
1633
+ class="mt-6 flex flex-col gap-6"
1634
+ >
1635
+ <section
1636
+ data-slot="table-configurator-column-main"
1637
+ class="flex flex-col gap-6"
1638
+ >
1639
+ <h4 class="text-sm font-semibold text-zinc-800">
1640
+ {{ t("column-main") }}
1641
+ </h4>
1642
+
1643
+ <div
1644
+ data-slot="table-configurator-locale-field"
1645
+ class="flex flex-col gap-2"
1646
+ >
1647
+ <p class="text-xs font-medium text-zinc-500">
1648
+ {{ t("column-title") }}
1649
+ </p>
1650
+
1651
+ <Locale
1652
+ data-slot="table-configurator-locale"
1653
+ :model-value="selectedColumnLocaleValue"
1654
+ @update:model-value="updateSelectedColumnTitle"
1655
+ />
1656
+ </div>
1657
+
1658
+ <div
1659
+ data-slot="table-configurator-column-options"
1660
+ class="flex flex-col gap-3"
1661
+ >
1662
+ <label
1663
+ data-field-key="columnSize"
1664
+ class="flex flex-col gap-1"
1665
+ >
1666
+ <span class="text-xs font-medium text-zinc-500">{{ t("column-size") }}</span>
1667
+ <InputGroup class="overflow-hidden">
1668
+ <InputGroupNumberField
1669
+ class="flex-1"
1670
+ :model-value="selectedColumn.size"
1671
+ :min="1"
1672
+ @update:model-value="updateSelectedColumnSize"
1673
+ />
1674
+
1675
+ <div class="flex h-full items-stretch border-l border-zinc-200">
1676
+ <Toggle
1677
+ class="h-full rounded-none border-0 px-3 text-xs shadow-none"
1678
+ :model-value="selectedColumn.grow ?? false"
1679
+ @update:model-value="updateSelectedColumnGrow"
1680
+ >
1681
+ <Icon icon="fluent:arrow-fit-20-regular" />
1682
+ {{ t("column-grow") }}
1683
+ </Toggle>
1684
+ </div>
1685
+ </InputGroup>
1686
+ </label>
1687
+
1688
+ <label class="flex items-center justify-between gap-3 py-1">
1689
+ <div class="flex flex-col gap-1">
1690
+ <span class="text-sm font-medium text-zinc-800">{{ t("column-enable-sorting") }}</span>
1691
+ <span class="text-xs text-zinc-500">{{ t("column-enable-sorting-description") }}</span>
1692
+ </div>
1693
+ <Switch
1694
+ :model-value="selectedColumn.enableSorting ?? false"
1695
+ @update:model-value="updateSelectedColumnEnableSorting"
1696
+ />
1697
+ </label>
1698
+ </div>
1699
+
1700
+ <div
1701
+ data-slot="table-configurator-accessor"
1702
+ class="flex flex-col gap-3"
1703
+ >
1704
+ <p class="text-xs font-medium text-zinc-500">
1705
+ {{ t("accessor") }}
1706
+ </p>
1707
+
1708
+ <Tabs
1709
+ v-model="selectedColumnAccessorMode"
1710
+ data-slot="table-configurator-accessor-tabs"
1711
+ class="gap-4"
1712
+ >
1713
+ <TabsList>
1714
+ <TabsTrigger value="path">
1715
+ {{ t("accessor-path-tab") }}
1716
+ </TabsTrigger>
1717
+ <TabsTrigger value="expression">
1718
+ {{ t("accessor-expression-tab") }}
1719
+ </TabsTrigger>
1720
+ </TabsList>
1721
+
1722
+ <TabsContent
1723
+ value="path"
1724
+ class="flex flex-col gap-4"
1725
+ >
1726
+ <ExpressionEditor
1727
+ ref="accessorPathEditor"
1728
+ data-field-key="accessorPath"
1729
+ :model-value="selectedColumnAccessorPath"
1730
+ :label="t('accessor-path')"
1731
+ :description="t('accessor-path-description')"
1732
+ :placeholder="t('accessor-path-placeholder')"
1733
+ :schema="dotPropC"
1734
+ @update:model-value="updateSelectedColumnAccessorPath"
1735
+ />
1736
+ </TabsContent>
1737
+
1738
+ <TabsContent
1739
+ value="expression"
1740
+ class="flex flex-col gap-4"
1741
+ >
1742
+ <ExpressionEditor
1743
+ ref="accessorReadEditor"
1744
+ data-field-key="accessorRead"
1745
+ :model-value="selectedColumnAccessorExpression.read"
1746
+ :label="t('accessor-read')"
1747
+ :description="t('accessor-read-description')"
1748
+ :placeholder="t('accessor-read-placeholder')"
1749
+ :schema="TableConfiguratorColumnAccessorReadC"
1750
+ @update:model-value="updateSelectedColumnAccessorRead"
1751
+ />
1752
+
1753
+ <ExpressionEditor
1754
+ ref="accessorWriteEditor"
1755
+ data-field-key="accessorWrite"
1756
+ :model-value="selectedColumnAccessorExpression.write"
1757
+ :label="t('accessor-write')"
1758
+ :description="t('accessor-write-description')"
1759
+ :placeholder="t('accessor-write-placeholder')"
1760
+ :schema="TableConfiguratorColumnAccessorWriteC"
1761
+ @update:model-value="updateSelectedColumnAccessorWrite"
1762
+ />
1763
+ </TabsContent>
1764
+ </Tabs>
1765
+ </div>
1766
+
1767
+ <div
1768
+ v-if="!selectedColumnHasChildren"
1769
+ data-slot="table-configurator-renderer"
1770
+ class="flex flex-col gap-3"
1771
+ >
1772
+ <div class="flex items-center justify-between gap-3">
1773
+ <p class="text-xs font-medium text-zinc-500">
1774
+ {{ t("renderer") }}
1775
+ </p>
1776
+
1777
+ <label
1778
+ data-field-key="rendererId"
1779
+ class="min-w-32 max-w-40"
1780
+ >
1781
+ <NativeSelect
1782
+ v-model="selectedColumnRendererModel"
1783
+ class="w-full"
1784
+ >
1785
+ <NativeSelectOption
1786
+ v-for="item in rendererOptions"
1787
+ :key="item.id"
1788
+ :value="item.id"
1789
+ >
1790
+ {{ item.label }}
1791
+ </NativeSelectOption>
1792
+ </NativeSelect>
1793
+ </label>
1794
+ </div>
1795
+
1796
+ <component
1797
+ :is="selectedColumnRendererConfigComponent"
1798
+ v-if="selectedColumnRendererConfigComponent"
1799
+ ref="selectedRendererConfigRef"
1800
+ data-slot="table-configurator-renderer-config"
1801
+ :model-value="selectedColumnRendererOptions"
1802
+ @update:model-value="updateSelectedColumnRendererProps"
1803
+ />
1804
+ </div>
1805
+
1806
+ <div
1807
+ data-slot="table-configurator-tooltip"
1808
+ class="flex flex-col gap-3"
1809
+ >
1810
+ <div class="flex flex-col gap-1">
1811
+ <p class="text-xs font-medium text-zinc-500">
1812
+ {{ t("tooltip") }}
1813
+ </p>
1814
+
1815
+ <p class="text-sm text-zinc-500">
1816
+ {{ t("tooltip-description", { expression: TOOLTIP_EXPRESSION_EXAMPLE }) }}
1817
+ </p>
1818
+ </div>
1819
+
1820
+ <Locale
1821
+ data-slot="table-configurator-tooltip-locale"
1822
+ :model-value="selectedColumnTooltipValue"
1823
+ :multiline="true"
1824
+ @update:model-value="updateSelectedColumnTooltip"
1825
+ />
1826
+ </div>
1827
+ </section>
1828
+
1829
+ <section
1830
+ data-slot="table-configurator-children"
1831
+ class="flex flex-col gap-3"
1832
+ >
1833
+ <h4 class="text-sm font-semibold text-zinc-800">
1834
+ {{ t("child-columns") }}
1835
+ </h4>
1836
+
1837
+ <div
1838
+ data-slot="table-configurator-selected-children"
1839
+ >
1840
+ <p class="text-xs font-medium text-zinc-500">
1841
+ {{ t("selected-children") }}
1842
+ </p>
1843
+
1844
+ <div
1845
+ v-if="selectedChildItems.length > 0"
1846
+ ref="selectedChildSortableListRef"
1847
+ class="mt-2 flex flex-col gap-1"
1848
+ >
1849
+ <div
1850
+ v-for="item in selectedChildItems"
1851
+ :key="item.itemId"
1852
+ data-slot="table-configurator-child-item"
1853
+ class="flex items-center gap-2 rounded-md border border-transparent p-1"
1854
+ >
1855
+ <button
1856
+ type="button"
1857
+ data-slot="table-configurator-child-drag-handle"
1858
+ class="flex size-8 shrink-0 cursor-grab items-center justify-center rounded-sm text-zinc-400 active:cursor-grabbing"
1859
+ :aria-label="t('drag-child-column', { column: item.label })"
1860
+ >
1861
+ <Icon icon="fluent:re-order-dots-vertical-20-regular" />
1862
+ </button>
1863
+
1864
+ <span class="min-w-0 flex-1 truncate px-1 text-sm font-medium text-zinc-800">{{ item.label }}</span>
1865
+
1866
+ <button
1867
+ type="button"
1868
+ data-slot="table-configurator-child-remove"
1869
+ class="flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-sm text-zinc-400 transition-colors hover:bg-red-50 hover:text-red-600"
1870
+ :aria-label="t('remove-child-column', { column: item.label })"
1871
+ @click="removeSelectedChild(item.itemId)"
1872
+ >
1873
+ <Icon icon="fluent:dismiss-20-regular" />
1874
+ </button>
1875
+ </div>
1876
+ </div>
1877
+
1878
+ <p
1879
+ v-else
1880
+ data-slot="table-configurator-child-empty"
1881
+ class="mt-2 text-xs text-zinc-400"
1882
+ >
1883
+ {{ t("no-selected-children") }}
1884
+ </p>
1885
+ </div>
1886
+
1887
+ <div
1888
+ data-slot="table-configurator-child-candidates"
1889
+ class="border-t border-zinc-200 pt-3"
1890
+ >
1891
+ <p class="text-xs font-medium text-zinc-500">
1892
+ {{ t("available-columns") }}
1893
+ </p>
1894
+
1895
+ <Input
1896
+ v-model="childSearch"
1897
+ data-slot="table-configurator-child-search"
1898
+ class="mt-2"
1899
+ :placeholder="t('search-child-columns')"
1900
+ />
1901
+
1902
+ <div
1903
+ v-if="filteredChildCandidateItems.length > 0"
1904
+ class="mt-3 flex flex-col gap-1"
1905
+ >
1906
+ <label
1907
+ v-for="item in filteredChildCandidateItems"
1908
+ :key="item.itemId"
1909
+ data-slot="table-configurator-child-candidate"
1910
+ class="flex items-center gap-3 rounded-md border border-transparent p-1 text-sm text-zinc-700"
1911
+ >
1912
+ <Checkbox
1913
+ :model-value="false"
1914
+ @update:model-value="(value) => toggleChildSelection(item.itemId, value)"
1915
+ />
1916
+ <span class="min-w-0 truncate font-medium text-zinc-800">{{ item.label }}</span>
1917
+ </label>
1918
+ </div>
1919
+
1920
+ <p
1921
+ v-else-if="normalizedChildSearch"
1922
+ data-slot="table-configurator-candidate-empty"
1923
+ class="mt-3 text-xs text-zinc-400"
1924
+ >
1925
+ {{ t("no-child-matches") }}
1926
+ </p>
1927
+
1928
+ <p
1929
+ v-else
1930
+ data-slot="table-configurator-candidate-empty"
1931
+ class="mt-3 text-xs text-zinc-400"
1932
+ >
1933
+ {{ t("no-available-columns") }}
1934
+ </p>
1935
+ </div>
1936
+ </section>
1937
+ </div>
1938
+ </section>
1939
+ </div>
1940
+
1941
+ <DialogFooter class="border-t border-zinc-200 px-6 py-4">
1942
+ <Button
1943
+ type="button"
1944
+ data-slot="table-configurator-export"
1945
+ variant="ghost"
1946
+ @click="exportConfig"
1947
+ >
1948
+ <Icon icon="fluent:arrow-download-20-regular" />
1949
+ {{ t("export-config") }}
1950
+ </Button>
1951
+ <Button
1952
+ type="button"
1953
+ data-slot="table-configurator-cancel"
1954
+ variant="default"
1955
+ @click="discardChanges"
1956
+ >
1957
+ <Icon icon="fluent:dismiss-20-regular" />
1958
+ {{ t("cancel") }}
1959
+ </Button>
1960
+ <Button
1961
+ type="button"
1962
+ data-slot="table-configurator-confirm"
1963
+ variant="primary"
1964
+ @click="confirmChanges"
1965
+ >
1966
+ <Icon icon="fluent:checkmark-20-regular" />
1967
+ {{ t("confirm") }}
1968
+ </Button>
1969
+ </DialogFooter>
1970
+ </DialogContent>
1971
+ </Dialog>
1972
+ </template>
1973
+
1974
+ <i18n lang="json">
1975
+ {
1976
+ "zh": {
1977
+ "configure-table": "配置表格",
1978
+ "configure-table-description": "在这里浏览表格和列配置项。",
1979
+ "import-config": "导入",
1980
+ "export-config": "导出",
1981
+ "import-config-invalid-json": "导入失败,文件不是有效的 JSON。",
1982
+ "import-config-invalid-schema": "导入失败,配置格式无效。",
1983
+ "export-config-failed": "导出失败,请先修正当前配置中的错误。",
1984
+ "search-columns": "搜索列名称……",
1985
+ "general": "通用",
1986
+ "no-matches": "没有匹配的列。",
1987
+ "general-placeholder": "配置当前表格的通用 CEL 表达式。",
1988
+ "expression-placeholder": "输入 CEL 表达式",
1989
+ "accessor": "取值配置",
1990
+ "accessor-path-tab": "路径",
1991
+ "accessor-expression-tab": "表达式",
1992
+ "accessor-path": "路径",
1993
+ "accessor-path-description": "使用 dot-prop 路径从 row 读取值,如 foo.bar 或 foo[0].bar。",
1994
+ "accessor-path-placeholder": "输入 dot-prop 路径",
1995
+ "accessor-read": "读取表达式",
1996
+ "accessor-read-description": "返回列值的 CEL 表达式,可使用 row、index 变量。",
1997
+ "accessor-read-placeholder": "输入读取用 CEL 表达式",
1998
+ "accessor-write": "写入表达式",
1999
+ "accessor-write-description": "保存列值时使用的表达式。",
2000
+ "accessor-write-placeholder": "输入写入表达式",
2001
+ "tooltip": "提示",
2002
+ "tooltip-description": "列提示支持 Markdown 编辑,并支持在 {expression} 中求值。",
2003
+ "get-row-id": "行 ID",
2004
+ "get-row-id-description": "返回 string 的 CEL 表达式,可使用 row、index、parent 变量。",
2005
+ "get-sub-rows": "子行",
2006
+ "get-sub-rows-description": "返回子行数据的 CEL 表达式,可使用 row、index 变量。",
2007
+ "enable-row-selection": "启用行选择",
2008
+ "enable-row-selection-description": "返回 bool 的 CEL 表达式,可使用 row、index、id 变量。",
2009
+ "enable-multi-row-selection": "启用多选",
2010
+ "enable-multi-row-selection-description": "返回 bool 的 CEL 表达式,可使用 row、index、id 变量。",
2011
+ "cell-styles": "单元格样式",
2012
+ "cell-styles-description": "返回样式对象的 CEL 表达式,可使用 row、index、id、selected、pinned 变量。",
2013
+ "pagination": "分页",
2014
+ "pagination-left": "左侧文案",
2015
+ "pagination-left-placeholder": "输入分页左侧 Markdown",
2016
+ "pagination-right": "右侧文案",
2017
+ "pagination-right-placeholder": "输入分页右侧 Markdown",
2018
+ "pagination-page-size": "每页条数",
2019
+ "initial-state": "初始状态",
2020
+ "column-options": "列配置",
2021
+ "column-main": "基本",
2022
+ "column-title": "标题",
2023
+ "column-size": "列宽",
2024
+ "column-grow": "自适应增长",
2025
+ "column-grow-description": "启用后该列会占据剩余空间。",
2026
+ "column-enable-sorting": "启用排序",
2027
+ "column-enable-sorting-description": "启用后表头会显示排序操作。",
2028
+ "renderer": "渲染器",
2029
+ "renderer-type": "渲染器类型",
2030
+ "renderer-name-text": "文本",
2031
+ "renderer-name-selection": "选择",
2032
+ "renderer-name-expand": "展开",
2033
+ "renderer-name-money": "金额",
2034
+ "renderer-name-date": "日期",
2035
+ "renderer-name-markdown": "Markdown",
2036
+ "pinned-left-group": "左侧组",
2037
+ "pinned-center-group": "中间组",
2038
+ "pinned-right-group": "右侧组",
2039
+ "child-columns": "子列",
2040
+ "selected-children": "已选子列",
2041
+ "available-columns": "可选列",
2042
+ "search-child-columns": "搜索可选列……",
2043
+ "no-child-matches": "没有匹配的可选列。",
2044
+ "no-pinned-left-columns": "左侧组暂无列。",
2045
+ "no-pinned-center-columns": "中间组暂无列。",
2046
+ "no-pinned-right-columns": "右侧组暂无列。",
2047
+ "no-selected-children": "当前列还没有子列。",
2048
+ "no-available-columns": "没有可添加的列。",
2049
+ "add-column": "新增列",
2050
+ "drag-left-column": "拖拽调整左侧组顺序:{column}",
2051
+ "drag-center-column": "拖拽调整中间组顺序:{column}",
2052
+ "drag-right-column": "拖拽调整右侧组顺序:{column}",
2053
+ "pin-left-column": "固定到左侧组:{column}",
2054
+ "pin-right-column": "固定到右侧组:{column}",
2055
+ "unpin-left-column": "从左侧组释放到中间组:{column}",
2056
+ "unpin-right-column": "从右侧组释放到中间组:{column}",
2057
+ "drag-child-column": "拖拽调整子列顺序:{column}",
2058
+ "delete-column": "删除列:{column}",
2059
+ "remove-child-column": "移出子列:{column}",
2060
+ "copy-column-id": "复制列 ID:{column}",
2061
+ "untitled-column": "未命名列",
2062
+ "cancel": "取消",
2063
+ "confirm": "确认"
2064
+ },
2065
+ "ja": {
2066
+ "configure-table": "テーブルを設定",
2067
+ "configure-table-description": "ここではテーブルと列の設定項目を確認できます。",
2068
+ "search-columns": "列名を検索…",
2069
+ "general": "共通",
2070
+ "no-matches": "一致する列がありません。",
2071
+ "general-placeholder": "このテーブルの共通 CEL 式を設定します。",
2072
+ "expression-placeholder": "CEL 式を入力",
2073
+ "accessor": "アクセサ",
2074
+ "accessor-path-tab": "パス",
2075
+ "accessor-expression-tab": "式",
2076
+ "accessor-path": "パス",
2077
+ "accessor-path-description": "foo.bar や foo[0].bar のような dot-prop パスで row から値を読み取ります。",
2078
+ "accessor-path-placeholder": "dot-prop パスを入力",
2079
+ "accessor-read": "読み取り式",
2080
+ "accessor-read-description": "列値を返す CEL 式です。row、index を利用できます。",
2081
+ "accessor-read-placeholder": "読み取り用 CEL 式を入力",
2082
+ "accessor-write": "書き込み式",
2083
+ "accessor-write-description": "列値を書き戻すときに使う式です。",
2084
+ "accessor-write-placeholder": "書き込み式を入力",
2085
+ "tooltip": "ツールチップ",
2086
+ "tooltip-description": "列ツールチップは Markdown で編集でき、{expression} も利用できます。",
2087
+ "get-row-id": "行 ID",
2088
+ "get-row-id-description": "string を返す CEL 式です。row、index、parent を利用できます。",
2089
+ "get-sub-rows": "子行",
2090
+ "get-sub-rows-description": "子行データを返す CEL 式です。row、index を利用できます。",
2091
+ "enable-row-selection": "行選択を有効化",
2092
+ "enable-row-selection-description": "bool を返す CEL 式です。row、index、id を利用できます。",
2093
+ "enable-multi-row-selection": "複数選択を有効化",
2094
+ "enable-multi-row-selection-description": "bool を返す CEL 式です。row、index、id を利用できます。",
2095
+ "cell-styles": "セルスタイル",
2096
+ "cell-styles-description": "スタイルオブジェクトを返す CEL 式です。row、index、id、selected、pinned を利用できます。",
2097
+ "pagination": "ページネーション",
2098
+ "pagination-left": "左側テキスト",
2099
+ "pagination-left-placeholder": "左側の Markdown を入力",
2100
+ "pagination-right": "右側テキスト",
2101
+ "pagination-right-placeholder": "右側の Markdown を入力",
2102
+ "pagination-page-size": "1ページあたりの件数",
2103
+ "initial-state": "初期状態",
2104
+ "column-options": "列設定",
2105
+ "column-main": "基本",
2106
+ "column-title": "タイトル",
2107
+ "column-size": "列幅",
2108
+ "column-grow": "可変幅",
2109
+ "column-grow-description": "有効にすると余白を埋めるように広がります。",
2110
+ "column-enable-sorting": "ソートを有効化",
2111
+ "column-enable-sorting-description": "有効にするとヘッダーにソート操作を表示します。",
2112
+ "renderer": "レンダラー",
2113
+ "renderer-type": "レンダラー種別",
2114
+ "renderer-name-text": "テキスト",
2115
+ "renderer-name-selection": "選択",
2116
+ "renderer-name-expand": "展開",
2117
+ "renderer-name-money": "金額",
2118
+ "renderer-name-date": "日付",
2119
+ "renderer-name-markdown": "Markdown",
2120
+ "pinned-left-group": "左側グループ",
2121
+ "pinned-center-group": "中央グループ",
2122
+ "pinned-right-group": "右側グループ",
2123
+ "child-columns": "子列",
2124
+ "selected-children": "選択済みの子列",
2125
+ "available-columns": "追加可能な列",
2126
+ "search-child-columns": "追加可能な列を検索…",
2127
+ "no-child-matches": "一致する追加可能な列がありません。",
2128
+ "no-pinned-left-columns": "左側グループに列がありません。",
2129
+ "no-pinned-center-columns": "中央グループに列がありません。",
2130
+ "no-pinned-right-columns": "右側グループに列がありません。",
2131
+ "no-selected-children": "この列にはまだ子列がありません。",
2132
+ "no-available-columns": "追加できる列がありません。",
2133
+ "add-column": "列を追加",
2134
+ "drag-left-column": "{column} の左側グループ順をドラッグで変更",
2135
+ "drag-center-column": "{column} の中央グループ順をドラッグで変更",
2136
+ "drag-right-column": "{column} の右側グループ順をドラッグで変更",
2137
+ "pin-left-column": "{column} を左側グループに固定",
2138
+ "pin-right-column": "{column} を右側グループに固定",
2139
+ "unpin-left-column": "{column} を左側グループから中央グループに戻す",
2140
+ "unpin-right-column": "{column} を右側グループから中央グループに戻す",
2141
+ "drag-child-column": "{column} の子列順をドラッグで変更",
2142
+ "delete-column": "{column} を削除",
2143
+ "remove-child-column": "{column} を子列から外す",
2144
+ "copy-column-id": "{column} の列 ID をコピー",
2145
+ "untitled-column": "未設定の列",
2146
+ "cancel": "キャンセル",
2147
+ "confirm": "確認"
2148
+ },
2149
+ "en": {
2150
+ "configure-table": "Configure Table",
2151
+ "configure-table-description": "Browse the table and column settings here.",
2152
+ "search-columns": "Search columns…",
2153
+ "general": "General",
2154
+ "no-matches": "No matching columns.",
2155
+ "general-placeholder": "Configure the shared CEL expressions for this table.",
2156
+ "expression-placeholder": "Enter a CEL expression",
2157
+ "accessor": "Accessor",
2158
+ "accessor-path-tab": "Path",
2159
+ "accessor-expression-tab": "Expression",
2160
+ "accessor-path": "Path",
2161
+ "accessor-path-description": "Read from row with a dot-prop path such as foo.bar or foo[0].bar.",
2162
+ "accessor-path-placeholder": "Enter a dot-prop path",
2163
+ "accessor-read": "Read expression",
2164
+ "accessor-read-description": "CEL expression that returns the column value. Variables: row, index.",
2165
+ "accessor-read-placeholder": "Enter a read CEL expression",
2166
+ "accessor-write": "Write expression",
2167
+ "accessor-write-description": "Expression used when writing the column value back.",
2168
+ "accessor-write-placeholder": "Enter a write expression",
2169
+ "tooltip": "Tooltip",
2170
+ "tooltip-description": "Column tooltips support Markdown and can evaluate {expression}.",
2171
+ "get-row-id": "Row ID",
2172
+ "get-row-id-description": "CEL expression that returns a string. Variables: row, index, parent.",
2173
+ "get-sub-rows": "Sub rows",
2174
+ "get-sub-rows-description": "CEL expression that returns sub-row data. Variables: row, index.",
2175
+ "enable-row-selection": "Enable row selection",
2176
+ "enable-row-selection-description": "CEL expression that returns a bool. Variables: row, index, id.",
2177
+ "enable-multi-row-selection": "Enable multi row selection",
2178
+ "enable-multi-row-selection-description": "CEL expression that returns a bool. Variables: row, index, id.",
2179
+ "cell-styles": "Cell styles",
2180
+ "cell-styles-description": "CEL expression that returns a style map. Variables: row, index, id, selected, pinned.",
2181
+ "pagination": "Pagination",
2182
+ "pagination-left": "Left content",
2183
+ "pagination-left-placeholder": "Enter left pagination markdown",
2184
+ "pagination-right": "Right content",
2185
+ "pagination-right-placeholder": "Enter right pagination markdown",
2186
+ "pagination-page-size": "Page size",
2187
+ "initial-state": "Initial State",
2188
+ "column-options": "Column options",
2189
+ "column-main": "Basics",
2190
+ "column-title": "Title",
2191
+ "column-size": "Column size",
2192
+ "column-grow": "Grow",
2193
+ "column-grow-description": "Allow this column to fill remaining horizontal space.",
2194
+ "column-enable-sorting": "Enable sorting",
2195
+ "column-enable-sorting-description": "Show sorting controls in the header.",
2196
+ "renderer": "Renderer",
2197
+ "renderer-type": "Renderer type",
2198
+ "renderer-name-text": "Text",
2199
+ "renderer-name-selection": "Selection",
2200
+ "renderer-name-expand": "Expand",
2201
+ "renderer-name-money": "Money",
2202
+ "renderer-name-date": "Date",
2203
+ "renderer-name-markdown": "Markdown",
2204
+ "pinned-left-group": "Left group",
2205
+ "pinned-center-group": "Center group",
2206
+ "pinned-right-group": "Right group",
2207
+ "child-columns": "Child columns",
2208
+ "selected-children": "Selected child columns",
2209
+ "available-columns": "Available columns",
2210
+ "search-child-columns": "Search available columns…",
2211
+ "no-child-matches": "No matching available columns.",
2212
+ "no-pinned-left-columns": "No columns in the left group.",
2213
+ "no-pinned-center-columns": "No columns in the center group.",
2214
+ "no-pinned-right-columns": "No columns in the right group.",
2215
+ "no-selected-children": "This column has no child columns yet.",
2216
+ "no-available-columns": "No columns can be added here.",
2217
+ "add-column": "Add column",
2218
+ "drag-left-column": "Drag to reorder left group column {column}",
2219
+ "drag-center-column": "Drag to reorder center group column {column}",
2220
+ "drag-right-column": "Drag to reorder right group column {column}",
2221
+ "pin-left-column": "Pin {column} to the left group",
2222
+ "pin-right-column": "Pin {column} to the right group",
2223
+ "unpin-left-column": "Move {column} from the left group to the center group",
2224
+ "unpin-right-column": "Move {column} from the right group to the center group",
2225
+ "drag-child-column": "Drag to reorder child column {column}",
2226
+ "delete-column": "Delete {column}",
2227
+ "remove-child-column": "Remove child column {column}",
2228
+ "untitled-column": "Untitled column",
2229
+ "cancel": "Cancel",
2230
+ "confirm": "Confirm"
2231
+ }
2232
+ }
2233
+ </i18n>