@shwfed/config 2.2.5 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/actions/buttons/2026-05-21/com.shwfed.actions.button.http.download/config.d.vue.ts +61 -0
  3. package/dist/runtime/components/actions/buttons/2026-05-21/com.shwfed.actions.button.http.download/config.vue +187 -0
  4. package/dist/runtime/components/actions/buttons/2026-05-21/com.shwfed.actions.button.http.download/config.vue.d.ts +61 -0
  5. package/dist/runtime/components/actions/buttons/2026-05-21/com.shwfed.actions.button.http.download/runtime.d.vue.ts +8 -0
  6. package/dist/runtime/components/actions/buttons/2026-05-21/com.shwfed.actions.button.http.download/runtime.vue +62 -0
  7. package/dist/runtime/components/actions/buttons/2026-05-21/com.shwfed.actions.button.http.download/runtime.vue.d.ts +8 -0
  8. package/dist/runtime/components/actions/buttons/2026-05-21/com.shwfed.actions.button.http.download/schema.d.ts +40 -0
  9. package/dist/runtime/components/actions/buttons/2026-05-21/com.shwfed.actions.button.http.download/schema.js +87 -0
  10. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.d.vue.ts +8 -8
  11. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.vue.d.ts +8 -8
  12. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.d.vue.ts +8 -8
  13. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.vue.d.ts +8 -8
  14. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/schema.d.ts +9 -15
  15. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/config.d.vue.ts +2 -2
  16. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/config.vue +32 -52
  17. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/config.vue.d.ts +2 -2
  18. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/runtime.vue +19 -8
  19. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/schema.d.ts +2 -2
  20. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/schema.js +4 -3
  21. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch/config.vue +25 -0
  22. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch/runtime.vue +2 -8
  23. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch/schema.d.ts +4 -0
  24. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch/schema.js +5 -0
  25. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/config.d.vue.ts +133 -0
  26. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/config.vue +533 -0
  27. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/config.vue.d.ts +133 -0
  28. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/runtime.d.vue.ts +9 -0
  29. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/runtime.vue +237 -0
  30. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/runtime.vue.d.ts +9 -0
  31. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/schema.d.ts +124 -0
  32. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/schema.js +96 -0
  33. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/config.d.vue.ts +10 -0
  34. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/config.vue +475 -0
  35. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/config.vue.d.ts +10 -0
  36. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/runtime.d.vue.ts +9 -0
  37. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/runtime.vue +156 -0
  38. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/runtime.vue.d.ts +9 -0
  39. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/schema.d.ts +56 -0
  40. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/schema.js +81 -0
  41. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch/config.d.vue.ts +10 -0
  42. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch/config.vue +310 -0
  43. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch/config.vue.d.ts +10 -0
  44. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch/runtime.d.vue.ts +9 -0
  45. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch/runtime.vue +81 -0
  46. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch/runtime.vue.d.ts +9 -0
  47. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch/schema.d.ts +57 -0
  48. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch/schema.js +59 -0
  49. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/config.d.vue.ts +10 -0
  50. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/config.vue +292 -0
  51. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/config.vue.d.ts +10 -0
  52. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/runtime.d.vue.ts +9 -0
  53. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/runtime.vue +140 -0
  54. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/runtime.vue.d.ts +9 -0
  55. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/schema.d.ts +50 -0
  56. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/schema.js +53 -0
  57. package/dist/runtime/components/table/config.d.vue.ts +2 -0
  58. package/dist/runtime/components/table/config.vue +136 -109
  59. package/dist/runtime/components/table/config.vue.d.ts +2 -0
  60. package/dist/runtime/components/table/index.d.vue.ts +2 -2
  61. package/dist/runtime/components/table/index.vue +46 -53
  62. package/dist/runtime/components/table/index.vue.d.ts +2 -2
  63. package/dist/runtime/components/table/row-provider.d.vue.ts +23 -0
  64. package/dist/runtime/components/table/row-provider.vue +55 -0
  65. package/dist/runtime/components/table/row-provider.vue.d.ts +23 -0
  66. package/dist/runtime/components/table/schema.d.ts +17 -29
  67. package/dist/runtime/components/table/schema.js +22 -18
  68. package/dist/runtime/components/table/utils/shared.d.ts +28 -0
  69. package/dist/runtime/components/table/utils/shared.js +40 -0
  70. package/dist/runtime/components/ui/field/index.js +6 -1
  71. package/dist/runtime/components/ui/input/Input.vue +1 -1
  72. package/package.json +1 -1
@@ -22,6 +22,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
22
22
  import { ExpressionEditor } from "../ui/expression-editor";
23
23
  import { Field, FieldLabel } from "../ui/field";
24
24
  import { Locale } from "../ui/locale";
25
+ import { Switch } from "../ui/switch";
25
26
  import { CommandItem, CommandGroup } from "../ui/command";
26
27
  import {
27
28
  InputGroup,
@@ -131,7 +132,9 @@ const TableActionsCELContext = defineComponent({
131
132
  });
132
133
  const config = defineModel({ type: Object, ...{ required: true } });
133
134
  const props = defineProps({
134
- configure: { type: Function, required: false }
135
+ configure: { type: Function, required: false },
136
+ hideDisplayName: { type: Boolean, required: false },
137
+ hideDataSource: { type: Boolean, required: false }
135
138
  });
136
139
  const configure = props.configure ?? (() => {
137
140
  });
@@ -208,20 +211,17 @@ function commit(w) {
208
211
  function normalizeForEmit(general) {
209
212
  const out = { ...general };
210
213
  const ds = out.dataSource;
211
- const nextDs = { ...ds ?? {} };
212
- if (typeof nextDs.request === "string" && nextDs.request.trim() === "") delete nextDs.request;
213
- if (typeof nextDs.total === "string" && nextDs.total.trim() === "") delete nextDs.total;
214
- out.dataSource = nextDs;
215
- const pagination = out.pagination;
216
- const p = { ...pagination ?? {} };
217
- const hasPageSize = typeof p.pageSize === "number" && Number.isFinite(p.pageSize) && p.pageSize > 0;
218
- const hasPageSizes = Array.isArray(p.pageSizes) && p.pageSizes.length > 0;
219
- const hasTotal = nextDs.total !== void 0;
220
- if (!hasPageSize && !hasPageSizes && !hasTotal) {
221
- delete out.pagination;
222
- } else {
223
- out.pagination = p;
214
+ let emittedDs;
215
+ if (ds) {
216
+ const nextDs = { ...ds };
217
+ if (typeof nextDs.request === "string" && nextDs.request.trim() === "") delete nextDs.request;
218
+ if (typeof nextDs.total === "string" && nextDs.total.trim() === "") delete nextDs.total;
219
+ if (typeof nextDs.data === "string" && nextDs.data.trim().length > 0) {
220
+ emittedDs = nextDs;
221
+ }
224
222
  }
223
+ if (emittedDs) out.dataSource = emittedDs;
224
+ else delete out.dataSource;
225
225
  const query = out.query;
226
226
  if (query && (!Array.isArray(query.fields) || query.fields.length === 0)) {
227
227
  delete out.query;
@@ -231,7 +231,6 @@ function normalizeForEmit(general) {
231
231
  function readGeneral() {
232
232
  const { columns: _c, groups: _g, kind: _k, ...general } = config.value ?? {};
233
233
  const cloned = JSON.parse(JSON.stringify(general));
234
- if (!cloned.pagination) cloned.pagination = {};
235
234
  if (!cloned.dataSource) cloned.dataSource = { data: "" };
236
235
  return cloned;
237
236
  }
@@ -936,25 +935,37 @@ function updateDataSourceOptional(key, value) {
936
935
  const ds = value.trim() === "" ? rest : { ...rest, [key]: value };
937
936
  writeGeneralPatch({ dataSource: ds });
938
937
  }
938
+ function setPaginationEnabled(enabled) {
939
+ if (enabled) {
940
+ if (config.value.pagination !== void 0) return;
941
+ writeGeneralPatch({ pagination: { pageSize: 100 } });
942
+ return;
943
+ }
944
+ const cur = config.value;
945
+ if (!cur || cur.pagination === void 0) return;
946
+ const { pagination: _drop, ...rest } = cur;
947
+ config.value = rest;
948
+ }
939
949
  function setPageSize(value) {
940
950
  const cur = readGeneral();
941
- const p = { ...cur.pagination ?? {} };
951
+ if (!cur.pagination) return;
942
952
  const n = typeof value === "number" ? value : Number(value);
943
- if (!Number.isFinite(n) || n <= 0) delete p.pageSize;
944
- else p.pageSize = n;
945
- writeGeneralPatch({ pagination: p });
953
+ if (!Number.isFinite(n) || n <= 0) return;
954
+ writeGeneralPatch({ pagination: { ...cur.pagination, pageSize: n } });
946
955
  }
947
956
  function setPageSizes(value) {
948
957
  const parsed = parsePageSizes(value);
949
958
  const cur = readGeneral();
950
- const p = { ...cur.pagination ?? {} };
959
+ if (!cur.pagination) return;
960
+ const p = { ...cur.pagination };
951
961
  if (parsed.length === 0) delete p.pageSizes;
952
962
  else p.pageSizes = parsed;
953
963
  writeGeneralPatch({ pagination: p });
954
964
  }
955
965
  function setPaginationLocale(key, value) {
956
966
  const cur = readGeneral();
957
- const p = { ...cur.pagination ?? {} };
967
+ if (!cur.pagination) return;
968
+ const p = { ...cur.pagination };
958
969
  if (value == null) {
959
970
  if (key === "left") delete p.left;
960
971
  else delete p.right;
@@ -1228,7 +1239,10 @@ const tableQueryValue = computed({
1228
1239
  v-if="selectedGeneral"
1229
1240
  class="space-y-5"
1230
1241
  >
1231
- <Field orientation="vertical">
1242
+ <Field
1243
+ v-if="!hideDisplayName"
1244
+ orientation="vertical"
1245
+ >
1232
1246
  <FieldLabel class="text-xs text-zinc-500">
1233
1247
  <template
1234
1248
  v-if="generalFieldDescription('displayName')"
@@ -1255,119 +1269,132 @@ const tableQueryValue = computed({
1255
1269
  field config) injects its own fields into the general pane. -->
1256
1270
  <slot name="general-extra" />
1257
1271
 
1258
- <div class="flex items-center gap-2">
1259
- <h3 class="text-xs font-medium text-zinc-500">
1260
- {{ generalFieldTitle("dataSource") }}
1261
- </h3>
1262
- <TableAiDataSourceButton
1263
- :data-source="editingGeneralConfig.dataSource"
1264
- :columns="editingColumns"
1265
- @apply="applyAiDataSource"
1266
- />
1267
- </div>
1268
-
1269
- <div class="space-y-4">
1270
- <Field orientation="vertical">
1271
- <FieldLabel class="text-xs text-zinc-500">
1272
- <template
1273
- v-if="dataSourceFieldDescription('request')"
1274
- #tooltip
1275
- >
1276
- <Markdown
1277
- :source="dataSourceFieldDescription('request')"
1278
- block
1279
- class="prose prose-sm prose-zinc"
1280
- />
1281
- </template>
1282
- {{ dataSourceFieldTitle("request") }}
1283
- </FieldLabel>
1284
- <RequestCELContext>
1285
- <ExpressionEditor
1286
- :model-value="editingGeneralConfig.dataSource?.request ?? ''"
1287
- placeholder="如 http.get('/api/users').query('page', pageIndex)"
1288
- result-type="HttpRequest"
1289
- multiline
1290
- class="min-h-20"
1291
- @update:model-value="(v) => updateDataSourceOptional('request', v)"
1292
- />
1293
- </RequestCELContext>
1294
- <p
1295
- v-if="getError('dataSource.request')"
1296
- class="text-xs text-red-500"
1297
- >
1298
- {{ getError("dataSource.request") }}
1299
- </p>
1300
- </Field>
1272
+ <template v-if="!hideDataSource">
1273
+ <div class="flex items-center gap-2">
1274
+ <h3 class="text-xs font-medium text-zinc-500">
1275
+ {{ generalFieldTitle("dataSource") }}
1276
+ </h3>
1277
+ <TableAiDataSourceButton
1278
+ :data-source="editingGeneralConfig.dataSource"
1279
+ :columns="editingColumns"
1280
+ @apply="applyAiDataSource"
1281
+ />
1282
+ </div>
1301
1283
 
1302
- <div class="grid grid-cols-2 gap-x-6 gap-y-4">
1284
+ <div class="space-y-4">
1303
1285
  <Field orientation="vertical">
1304
1286
  <FieldLabel class="text-xs text-zinc-500">
1305
1287
  <template
1306
- v-if="dataSourceFieldDescription('data')"
1288
+ v-if="dataSourceFieldDescription('request')"
1307
1289
  #tooltip
1308
1290
  >
1309
1291
  <Markdown
1310
- :source="dataSourceFieldDescription('data')"
1292
+ :source="dataSourceFieldDescription('request')"
1311
1293
  block
1312
1294
  class="prose prose-sm prose-zinc"
1313
1295
  />
1314
1296
  </template>
1315
- {{ dataSourceFieldTitle("data") }}
1297
+ {{ dataSourceFieldTitle("request") }}
1316
1298
  </FieldLabel>
1317
- <JsonCELContext>
1299
+ <RequestCELContext>
1318
1300
  <ExpressionEditor
1319
- :model-value="editingGeneralConfig.dataSource?.data ?? ''"
1320
- placeholder="如 json.?value.items.orValue([])"
1321
- result-type="list"
1322
- @update:model-value="(v) => setDataSourceField('data', v)"
1301
+ :model-value="editingGeneralConfig.dataSource?.request ?? ''"
1302
+ placeholder="如 http.get('/api/users').query('page', pageIndex)"
1303
+ result-type="HttpRequest"
1304
+ multiline
1305
+ class="min-h-20"
1306
+ @update:model-value="(v) => updateDataSourceOptional('request', v)"
1323
1307
  />
1324
- </JsonCELContext>
1308
+ </RequestCELContext>
1325
1309
  <p
1326
- v-if="getError('dataSource.data')"
1310
+ v-if="getError('dataSource.request')"
1327
1311
  class="text-xs text-red-500"
1328
1312
  >
1329
- {{ getError("dataSource.data") }}
1313
+ {{ getError("dataSource.request") }}
1330
1314
  </p>
1331
1315
  </Field>
1332
- <Field orientation="vertical">
1333
- <FieldLabel class="text-xs text-zinc-500">
1334
- <template
1335
- v-if="dataSourceFieldDescription('total')"
1336
- #tooltip
1316
+
1317
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
1318
+ <Field orientation="vertical">
1319
+ <FieldLabel class="text-xs text-zinc-500">
1320
+ <template
1321
+ v-if="dataSourceFieldDescription('data')"
1322
+ #tooltip
1323
+ >
1324
+ <Markdown
1325
+ :source="dataSourceFieldDescription('data')"
1326
+ block
1327
+ class="prose prose-sm prose-zinc"
1328
+ />
1329
+ </template>
1330
+ {{ dataSourceFieldTitle("data") }}
1331
+ </FieldLabel>
1332
+ <JsonCELContext>
1333
+ <ExpressionEditor
1334
+ :model-value="editingGeneralConfig.dataSource?.data ?? ''"
1335
+ placeholder="如 json.?value.items.orValue([])"
1336
+ result-type="list"
1337
+ @update:model-value="(v) => setDataSourceField('data', v)"
1338
+ />
1339
+ </JsonCELContext>
1340
+ <p
1341
+ v-if="getError('dataSource.data')"
1342
+ class="text-xs text-red-500"
1337
1343
  >
1338
- <Markdown
1339
- :source="dataSourceFieldDescription('total')"
1340
- block
1341
- class="prose prose-sm prose-zinc"
1344
+ {{ getError("dataSource.data") }}
1345
+ </p>
1346
+ </Field>
1347
+ <Field orientation="vertical">
1348
+ <FieldLabel class="text-xs text-zinc-500">
1349
+ <template
1350
+ v-if="dataSourceFieldDescription('total')"
1351
+ #tooltip
1352
+ >
1353
+ <Markdown
1354
+ :source="dataSourceFieldDescription('total')"
1355
+ block
1356
+ class="prose prose-sm prose-zinc"
1357
+ />
1358
+ </template>
1359
+ {{ dataSourceFieldTitle("total") }}
1360
+ </FieldLabel>
1361
+ <JsonCELContext>
1362
+ <ExpressionEditor
1363
+ :model-value="editingGeneralConfig.dataSource?.total ?? ''"
1364
+ placeholder="留空使用前端分页;如 json.?value.total.orValue(0)"
1365
+ result-type="number"
1366
+ @update:model-value="(v) => updateDataSourceOptional('total', v)"
1342
1367
  />
1343
- </template>
1344
- {{ dataSourceFieldTitle("total") }}
1345
- </FieldLabel>
1346
- <JsonCELContext>
1347
- <ExpressionEditor
1348
- :model-value="editingGeneralConfig.dataSource?.total ?? ''"
1349
- placeholder="留空使用前端分页;如 json.?value.total.orValue(0)"
1350
- result-type="number"
1351
- @update:model-value="(v) => updateDataSourceOptional('total', v)"
1352
- />
1353
- </JsonCELContext>
1354
- <p
1355
- v-if="getError('dataSource.total')"
1356
- class="text-xs text-red-500"
1357
- >
1358
- {{ getError("dataSource.total") }}
1359
- </p>
1360
- </Field>
1368
+ </JsonCELContext>
1369
+ <p
1370
+ v-if="getError('dataSource.total')"
1371
+ class="text-xs text-red-500"
1372
+ >
1373
+ {{ getError("dataSource.total") }}
1374
+ </p>
1375
+ </Field>
1376
+ </div>
1361
1377
  </div>
1362
- </div>
1378
+ </template>
1363
1379
 
1364
1380
  <Separator />
1365
1381
 
1366
- <h3 class="text-xs font-medium text-zinc-500">
1367
- {{ generalFieldTitle("pagination") }}
1368
- </h3>
1382
+ <div class="flex items-center gap-2">
1383
+ <h3 class="text-xs font-medium text-zinc-500">
1384
+ {{ generalFieldTitle("pagination") }}
1385
+ </h3>
1386
+ <Switch
1387
+ size="sm"
1388
+ :model-value="editingGeneralConfig.pagination !== void 0"
1389
+ aria-label="启用分页"
1390
+ @update:model-value="setPaginationEnabled"
1391
+ />
1392
+ </div>
1369
1393
 
1370
- <div class="grid grid-cols-2 gap-x-6 gap-y-4">
1394
+ <div
1395
+ v-if="editingGeneralConfig.pagination !== void 0"
1396
+ class="grid grid-cols-2 gap-x-6 gap-y-4"
1397
+ >
1371
1398
  <Field orientation="vertical">
1372
1399
  <FieldLabel class="text-xs text-zinc-500">
1373
1400
  <template
@@ -2,6 +2,8 @@ import { Environment } from '../../vendor/cel-js/lib/index.js';
2
2
  type AnyRecord = Record<string, any>;
3
3
  type __VLS_Props = {
4
4
  configure?: (env: Environment) => void;
5
+ hideDisplayName?: boolean;
6
+ hideDataSource?: boolean;
5
7
  };
6
8
  type __VLS_ModelProps = {
7
9
  modelValue: AnyRecord;
@@ -20,7 +20,7 @@ declare const __VLS_export: import("vue").DefineComponent<{
20
20
  displayName?: string;
21
21
  columns: ReadonlyArray<ColumnValue>;
22
22
  groups: ReadonlyArray<ColumnGroupValue>;
23
- dataSource: Readonly<{
23
+ dataSource?: Readonly<{
24
24
  request?: string;
25
25
  data: string;
26
26
  total?: string;
@@ -64,7 +64,7 @@ declare const __VLS_export: import("vue").DefineComponent<{
64
64
  displayName?: string;
65
65
  columns: ReadonlyArray<ColumnValue>;
66
66
  groups: ReadonlyArray<ColumnGroupValue>;
67
- dataSource: Readonly<{
67
+ dataSource?: Readonly<{
68
68
  request?: string;
69
69
  data: string;
70
70
  total?: string;
@@ -13,9 +13,10 @@ import { useVirtualizer } from "@tanstack/vue-virtual";
13
13
  import { Effect, Fiber, Option } from "effect";
14
14
  import { Fetch } from "fx-fetch";
15
15
  import { Pagination } from "reka-ui/namespaced";
16
- import { computed, defineComponent, h, onMounted, ref, toRaw, watch } from "vue";
16
+ import { computed, h, onMounted, ref, toRaw, watch } from "vue";
17
17
  import { useI18n } from "vue-i18n";
18
18
  import { celBindings, provideCELContext, injectCELContext } from "../../utils/cel-context";
19
+ import TableRowProvider from "./row-provider.vue";
19
20
  import { getLocalizedText } from "../../share/locale";
20
21
  import { Button } from "../ui/button";
21
22
  import { Markdown } from "../ui/markdown";
@@ -29,6 +30,7 @@ import { provideTableInstanceId } from "./utils/instance";
29
30
  import { provideEventTarget } from "../../share/event-bus";
30
31
  import { findColumn } from "./utils/resolve";
31
32
  import { interpolateMarkdown } from "./utils/runtime";
33
+ defineOptions({ name: "ShwfedTable" });
32
34
  const config = defineModel("config", { type: Object });
33
35
  const rowData = defineModel("rows", { type: Array, ...{ default: () => [] } });
34
36
  const serverTotal = ref(void 0);
@@ -148,7 +150,7 @@ const isPaginationEnabled = computed(() => config.value?.pagination !== void 0);
148
150
  const isManualPagination = computed(() => isPaginationEnabled.value && config.value?.dataSource?.total !== void 0);
149
151
  const totalItems = computed(() => isManualPagination.value ? serverTotal.value ?? 0 : rowData.value.length);
150
152
  const paginationConfig = computed(() => config.value?.pagination);
151
- const paginationPageSizes = computed(() => paginationConfig.value?.pageSizes ?? [20, 50, 100, 200]);
153
+ const paginationPageSizes = computed(() => paginationConfig.value?.pageSizes ?? []);
152
154
  const paginationLeftSource = computed(() => {
153
155
  const source = getLocaleText(paginationConfig.value?.left);
154
156
  if (!source) return "";
@@ -163,34 +165,17 @@ const paginationRightSource = computed(() => {
163
165
  selected: tableApi.getSelectedRowModel().rows.map((row) => row.original)
164
166
  });
165
167
  });
166
- const TableRowCELContext = defineComponent({
167
- name: "TableRowCELContext",
168
- props: {
169
- row: { type: null, default: void 0 },
170
- index: { type: Number, required: true }
171
- },
172
- setup(props, { slots }) {
173
- provideCELContext({
174
- row: {
175
- type: "dyn",
176
- label: "\u5F53\u524D\u884C",
177
- description: "\u5F53\u524D\u6E32\u67D3\u7684\u6574\u884C\u6570\u636E\uFF0C\u7C7B\u578B\u5728\u914D\u7F6E\u65F6\u672A\u77E5\uFF08`dyn`\uFF09\uFF0C\u5177\u4F53\u5B57\u6BB5\u53D6\u51B3\u4E8E\u63A5\u5165\u6570\u636E\u6E90\u3002",
178
- get value() {
179
- return props.row;
180
- }
181
- },
182
- index: {
183
- type: "number",
184
- label: "\u884C\u5E8F\u53F7",
185
- description: "\u5F53\u524D\u884C\u5728\u6240\u6709\u6570\u636E\u4E2D\u7684\u5E8F\u53F7\uFF0C\u4ECE `0` \u5F00\u59CB\u3002",
186
- get value() {
187
- return props.index;
188
- }
189
- }
190
- });
191
- return () => slots.default?.();
192
- }
193
- });
168
+ function getRowAt(i) {
169
+ return rowData.value[i];
170
+ }
171
+ function setRowAt(i, next) {
172
+ const rows2 = rowData.value;
173
+ if (i < 0 || i >= rows2.length) return;
174
+ rowData.value = rows2.map((r, j) => j === i ? next : r);
175
+ }
176
+ const derivedEditableColumns = computed(
177
+ () => (config.value?.columns ?? []).filter((c) => typeof c.binding === "string" && !!c.derived)
178
+ );
194
179
  const tableApi = useVueTable({
195
180
  get columns() {
196
181
  return columns.value;
@@ -491,8 +476,9 @@ const currentPageSize = computed({
491
476
  });
492
477
  function syncPaginationPageSize() {
493
478
  if (!isPaginationEnabled.value) return;
494
- const currentPageSize2 = tableApi.getState().pagination.pageSize;
495
479
  const pageSizes = paginationPageSizes.value;
480
+ if (pageSizes.length === 0) return;
481
+ const currentPageSize2 = tableApi.getState().pagination.pageSize;
496
482
  if (pageSizes.includes(currentPageSize2)) return;
497
483
  const closest = pageSizes.reduce(
498
484
  (prev, curr) => Math.abs(curr - currentPageSize2) < Math.abs(prev - currentPageSize2) ? curr : prev
@@ -705,41 +691,48 @@ export { TableConfig, createTableConfig, getColumnTechnicalKey } from "./schema"
705
691
  class="grid relative"
706
692
  :style="{ height: `${rowTotalSize}px` }"
707
693
  >
708
- <tr
694
+ <template
709
695
  v-for="r in rowWindow"
710
696
  :key="rows[r.index]?.id ?? r.index"
711
- :ref="measureRow"
712
- class="flex absolute w-full border-b border-zinc-300"
713
- :data-index="rows[r.index]?.index"
714
- :style="{ transform: `translate3d(0, ${r.start}px, 0)` }"
715
697
  >
716
- <td
717
- v-for="cell in rows[r.index]?.getVisibleCells() ?? []"
718
- :key="cell.id"
719
- :class="[
698
+ <TableRowProvider
699
+ v-if="rows[r.index]"
700
+ :source-index="rows[r.index].index"
701
+ :display-index="getDisplayIndex(rows[r.index])"
702
+ :derived-columns="derivedEditableColumns"
703
+ :get-row="getRowAt"
704
+ :set-row="setRowAt"
705
+ >
706
+ <tr
707
+ :ref="measureRow"
708
+ class="flex absolute w-full border-b border-zinc-300"
709
+ :data-index="rows[r.index].index"
710
+ :style="{ transform: `translate3d(0, ${r.start}px, 0)` }"
711
+ >
712
+ <td
713
+ v-for="cell in rows[r.index].getVisibleCells()"
714
+ :key="cell.id"
715
+ :class="[
720
716
  'border-zinc-300',
721
717
  cell.column.columnDef.meta?.grow && 'flex-1',
722
718
  cell.column.getIsPinned() && 'sticky z-15',
723
719
  shouldHaveRightBorder(cell.column) && 'border-r',
724
720
  shouldHaveLeftBorder(cell.column) && 'border-l'
725
721
  ]"
726
- :style="{
722
+ :style="{
727
723
  width: `${cell.column.getSize()}px`,
728
724
  ...pinnedStyle(cell.column),
729
725
  ...getCellStyles(cell.getContext())
730
726
  }"
731
- >
732
- <TableRowCELContext
733
- :row="cell.row.original"
734
- :index="getDisplayIndex(cell.row)"
735
- >
736
- <FlexRender
737
- :render="cell.column.columnDef.cell"
738
- :props="cell.getContext()"
739
- />
740
- </TableRowCELContext>
741
- </td>
742
- </tr>
727
+ >
728
+ <FlexRender
729
+ :render="cell.column.columnDef.cell"
730
+ :props="cell.getContext()"
731
+ />
732
+ </td>
733
+ </tr>
734
+ </TableRowProvider>
735
+ </template>
743
736
  </tbody>
744
737
 
745
738
  <!-- Footer -->
@@ -20,7 +20,7 @@ declare const __VLS_export: import("vue").DefineComponent<{
20
20
  displayName?: string;
21
21
  columns: ReadonlyArray<ColumnValue>;
22
22
  groups: ReadonlyArray<ColumnGroupValue>;
23
- dataSource: Readonly<{
23
+ dataSource?: Readonly<{
24
24
  request?: string;
25
25
  data: string;
26
26
  total?: string;
@@ -64,7 +64,7 @@ declare const __VLS_export: import("vue").DefineComponent<{
64
64
  displayName?: string;
65
65
  columns: ReadonlyArray<ColumnValue>;
66
66
  groups: ReadonlyArray<ColumnGroupValue>;
67
- dataSource: Readonly<{
67
+ dataSource?: Readonly<{
68
68
  request?: string;
69
69
  data: string;
70
70
  total?: string;
@@ -0,0 +1,23 @@
1
+ import type { FieldValue } from '../form/schema.js';
2
+ type __VLS_Props = {
3
+ sourceIndex: number;
4
+ displayIndex: number;
5
+ derivedColumns: ReadonlyArray<FieldValue>;
6
+ getRow: (i: number) => unknown;
7
+ setRow: (i: number, value: unknown) => void;
8
+ };
9
+ declare var __VLS_1: {};
10
+ type __VLS_Slots = {} & {
11
+ default?: (props: typeof __VLS_1) => any;
12
+ };
13
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
14
+ evaluate: (expression: string) => unknown;
15
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
17
+ declare const _default: typeof __VLS_export;
18
+ export default _default;
19
+ type __VLS_WithSlots<T, S> = T & {
20
+ new (): {
21
+ $slots: S;
22
+ };
23
+ };
@@ -0,0 +1,55 @@
1
+ <script setup>
2
+ import { Effect } from "effect";
3
+ import { customRef } from "vue";
4
+ import { cel as _rawCel } from "../../utils/cel";
5
+ import { celBindings, injectCELContext, provideCELContext } from "../../utils/cel-context";
6
+ import { useDerived, useDerivedQuiescence } from "../form/utils/derived";
7
+ import { provideFormState } from "../form/utils/state";
8
+ defineOptions({ name: "ShwfedTableRowProvider" });
9
+ const props = defineProps({
10
+ sourceIndex: { type: Number, required: true },
11
+ displayIndex: { type: Number, required: true },
12
+ derivedColumns: { type: Array, required: true },
13
+ getRow: { type: Function, required: true },
14
+ setRow: { type: Function, required: true }
15
+ });
16
+ const rowRef = customRef((track, trigger) => ({
17
+ get() {
18
+ track();
19
+ return props.getRow(props.sourceIndex);
20
+ },
21
+ set(next) {
22
+ props.setRow(props.sourceIndex, next);
23
+ trigger();
24
+ }
25
+ }));
26
+ provideCELContext({
27
+ row: {
28
+ type: "dyn",
29
+ label: "\u5F53\u524D\u884C",
30
+ description: "\u5F53\u524D\u884C\u7684\u6574\u884C\u6570\u636E\uFF1B\u5199\u5165\u5F0F\u7F16\u8F91\u5217\u53EF\u7ECF `useFormState().setAt` \u89E6\u53D1\u5176\u53D8\u5316\u3002",
31
+ value: () => rowRef.value
32
+ },
33
+ index: {
34
+ type: "number",
35
+ label: "\u884C\u5E8F\u53F7",
36
+ description: "\u5F53\u524D\u884C\u5728\u6240\u6709\u6570\u636E\u4E2D\u7684\u5E8F\u53F7\uFF0C\u4ECE `0` \u5F00\u59CB\u3002",
37
+ value: () => props.displayIndex
38
+ }
39
+ });
40
+ const inherited = injectCELContext();
41
+ const $cel = (expression, context) => _rawCel(expression, { ...celBindings(inherited), ...context });
42
+ const formState = provideFormState(rowRef);
43
+ useDerived({
44
+ fields: () => props.derivedColumns,
45
+ evaluate: (expression) => $cel(expression),
46
+ ready: Promise.resolve(),
47
+ formState,
48
+ quiescence: useDerivedQuiescence()
49
+ });
50
+ defineExpose({ evaluate: (expression) => Effect.runSync($cel(expression)) });
51
+ </script>
52
+
53
+ <template>
54
+ <slot />
55
+ </template>
@@ -0,0 +1,23 @@
1
+ import type { FieldValue } from '../form/schema.js';
2
+ type __VLS_Props = {
3
+ sourceIndex: number;
4
+ displayIndex: number;
5
+ derivedColumns: ReadonlyArray<FieldValue>;
6
+ getRow: (i: number) => unknown;
7
+ setRow: (i: number, value: unknown) => void;
8
+ };
9
+ declare var __VLS_1: {};
10
+ type __VLS_Slots = {} & {
11
+ default?: (props: typeof __VLS_1) => any;
12
+ };
13
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
14
+ evaluate: (expression: string) => unknown;
15
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
17
+ declare const _default: typeof __VLS_export;
18
+ export default _default;
19
+ type __VLS_WithSlots<T, S> = T & {
20
+ new (): {
21
+ $slots: S;
22
+ };
23
+ };