@revisium/schema-toolkit-ui 0.6.2 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -7041,7 +7041,11 @@ function resolveFileRefColumns(child, fieldPath) {
7041
7041
  if (child.isObject()) for (const subField of child.properties()) {
7042
7042
  const subFieldPath = buildFieldPath(fieldPath, subField.name());
7043
7043
  const fieldType = NODE_TYPE_TO_FIELD_TYPE[subField.nodeType()];
7044
- if (fieldType) result.push(createColumn(subFieldPath, subField, fieldType));
7044
+ if (fieldType) {
7045
+ const subCol = createColumn(subFieldPath, subField, fieldType);
7046
+ subCol.parentFileField = fieldPath;
7047
+ result.push(subCol);
7048
+ }
7045
7049
  }
7046
7050
  return result;
7047
7051
  }
@@ -7130,6 +7134,9 @@ var ColumnsModel = class {
7130
7134
  constructor() {
7131
7135
  makeAutoObservable(this, {}, { autoBind: true });
7132
7136
  }
7137
+ get allColumns() {
7138
+ return this._allColumns;
7139
+ }
7133
7140
  get visibleColumns() {
7134
7141
  const lookup = this._columnLookup;
7135
7142
  const result = [];
@@ -7562,6 +7569,49 @@ var ColumnsModel = class {
7562
7569
  }
7563
7570
  };
7564
7571
 
7572
+ //#endregion
7573
+ //#region src/table-editor/Columns/model/groupFileFields.ts
7574
+ function isFileFieldGroup(item) {
7575
+ return "parent" in item && "children" in item;
7576
+ }
7577
+ function groupFileFields(columns, allColumns) {
7578
+ const allLookup = allColumns ? new Map(allColumns.map((c) => [c.field, c])) : null;
7579
+ const groups = /* @__PURE__ */ new Map();
7580
+ const result = [];
7581
+ for (const col of columns) if (col.fieldType === FilterFieldType.File) {
7582
+ const existing = groups.get(col.field);
7583
+ if (existing) {
7584
+ existing.parent = col;
7585
+ existing.parentVisible = false;
7586
+ } else {
7587
+ const group = {
7588
+ parent: col,
7589
+ children: [],
7590
+ parentVisible: false
7591
+ };
7592
+ groups.set(col.field, group);
7593
+ result.push(group);
7594
+ }
7595
+ } else if (col.parentFileField) {
7596
+ let group = groups.get(col.parentFileField);
7597
+ if (!group) {
7598
+ const parentCol = allLookup?.get(col.parentFileField);
7599
+ if (parentCol) {
7600
+ group = {
7601
+ parent: parentCol,
7602
+ children: [],
7603
+ parentVisible: true
7604
+ };
7605
+ groups.set(col.parentFileField, group);
7606
+ result.push(group);
7607
+ }
7608
+ }
7609
+ if (group) group.children.push(col);
7610
+ else result.push(col);
7611
+ } else result.push(col);
7612
+ return result;
7613
+ }
7614
+
7565
7615
  //#endregion
7566
7616
  //#region src/table-editor/Filters/model/utils/operators.ts
7567
7617
  let FilterOperator = /* @__PURE__ */ function(FilterOperator) {
@@ -8023,15 +8073,15 @@ function parseValue(value, fieldType) {
8023
8073
  }
8024
8074
  return value;
8025
8075
  }
8026
- function buildOperatorClause(operator, value, fieldType) {
8076
+ function buildOperatorClause(operator, value, fieldType, isSystemField) {
8027
8077
  const parsed = parseValue(value, fieldType);
8028
8078
  switch (operator) {
8029
8079
  case FilterOperator.Equals: return { equals: parsed };
8030
8080
  case FilterOperator.NotEquals: return { not: { equals: parsed } };
8031
- case FilterOperator.Contains: return { string_contains: value };
8032
- case FilterOperator.NotContains: return { not: { string_contains: value } };
8033
- case FilterOperator.StartsWith: return { string_starts_with: value };
8034
- case FilterOperator.EndsWith: return { string_ends_with: value };
8081
+ case FilterOperator.Contains: return isSystemField ? { contains: value } : { string_contains: value };
8082
+ case FilterOperator.NotContains: return isSystemField ? { not: { contains: value } } : { not: { string_contains: value } };
8083
+ case FilterOperator.StartsWith: return isSystemField ? { startsWith: value } : { string_starts_with: value };
8084
+ case FilterOperator.EndsWith: return isSystemField ? { endsWith: value } : { string_ends_with: value };
8035
8085
  case FilterOperator.Gt: return { gt: parsed };
8036
8086
  case FilterOperator.Gte: return { gte: parsed };
8037
8087
  case FilterOperator.Lt: return { lt: parsed };
@@ -8058,8 +8108,9 @@ function buildConditionClause(condition) {
8058
8108
  searchType: condition.searchType || "plain"
8059
8109
  } };
8060
8110
  }
8061
- const opClause = buildOperatorClause(condition.operator, condition.value, condition.fieldType);
8062
- if (SYSTEM_FIELD_IDS.has(condition.field)) return { [condition.field]: opClause };
8111
+ const isSystemField = SYSTEM_FIELD_IDS.has(condition.field);
8112
+ const opClause = buildOperatorClause(condition.operator, condition.value, condition.fieldType, isSystemField);
8113
+ if (isSystemField) return { [condition.field]: opClause };
8063
8114
  return { data: {
8064
8115
  path: stripDataFieldPrefix(condition.field),
8065
8116
  ...opClause
@@ -9228,7 +9279,10 @@ const SearchWidget = observer(({ model }) => {
9228
9279
  right: "0",
9229
9280
  top: "50%",
9230
9281
  transform: "translateY(-50%)",
9231
- onClick: () => model.clear(),
9282
+ onClick: () => {
9283
+ model.clear();
9284
+ setExpanded(false);
9285
+ },
9232
9286
  color: "gray.400",
9233
9287
  _hover: { color: "black" },
9234
9288
  children: /* @__PURE__ */ jsx(PiXBold, {})
@@ -12222,10 +12276,69 @@ const FieldMenuItem = memo(({ field, name, fieldType, valuePrefix, onClick }) =>
12222
12276
  });
12223
12277
  });
12224
12278
 
12279
+ //#endregion
12280
+ //#region src/table-editor/Table/ui/Header/FileFieldSubmenu.tsx
12281
+ const FileFieldSubmenu = ({ group, parentVisible, valuePrefix, onClick }) => {
12282
+ if (group.children.length === 0 && !parentVisible) return /* @__PURE__ */ jsx(FieldMenuItem, {
12283
+ field: group.parent.field,
12284
+ name: group.parent.label,
12285
+ fieldType: group.parent.fieldType,
12286
+ valuePrefix,
12287
+ onClick
12288
+ });
12289
+ return /* @__PURE__ */ jsxs(Menu.Root, {
12290
+ positioning: {
12291
+ placement: "right-start",
12292
+ gutter: 2
12293
+ },
12294
+ lazyMount: true,
12295
+ unmountOnExit: true,
12296
+ children: [/* @__PURE__ */ jsxs(Menu.TriggerItem, {
12297
+ "data-testid": `file-group-${group.parent.field}`,
12298
+ children: [/* @__PURE__ */ jsxs(Box, {
12299
+ display: "flex",
12300
+ alignItems: "center",
12301
+ gap: 2,
12302
+ flex: 1,
12303
+ children: [/* @__PURE__ */ jsx(Box, {
12304
+ as: "span",
12305
+ fontSize: "xs",
12306
+ fontWeight: "medium",
12307
+ color: "gray.400",
12308
+ fontFamily: "mono",
12309
+ minWidth: "20px",
12310
+ children: getFieldTypeIcon(group.parent.fieldType)
12311
+ }), /* @__PURE__ */ jsx(Text, {
12312
+ truncate: true,
12313
+ children: group.parent.label
12314
+ })]
12315
+ }), /* @__PURE__ */ jsx(LuChevronRight, {})]
12316
+ }), /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, { children: /* @__PURE__ */ jsxs(Menu.Content, {
12317
+ maxH: "300px",
12318
+ minW: "200px",
12319
+ overflowY: "auto",
12320
+ children: [!parentVisible && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(FieldMenuItem, {
12321
+ field: group.parent.field,
12322
+ name: group.parent.label,
12323
+ fieldType: group.parent.fieldType,
12324
+ valuePrefix,
12325
+ onClick
12326
+ }), /* @__PURE__ */ jsx(Menu.Separator, {})] }), group.children.map((col) => /* @__PURE__ */ jsx(FieldMenuItem, {
12327
+ field: col.field,
12328
+ name: col.label,
12329
+ fieldType: col.fieldType,
12330
+ valuePrefix,
12331
+ onClick
12332
+ }, col.field))]
12333
+ }) }) })]
12334
+ });
12335
+ };
12336
+
12225
12337
  //#endregion
12226
12338
  //#region src/table-editor/Table/ui/Header/InsertColumnSubmenu.tsx
12227
- const InsertColumnSubmenu = ({ label, valuePrefix, availableFields, onSelect }) => {
12339
+ const InsertColumnSubmenu = ({ label, valuePrefix, availableFields, allColumns, onSelect }) => {
12228
12340
  if (availableFields.length === 0) return null;
12341
+ const groupedFields = groupFileFields(availableFields, allColumns);
12229
12342
  return /* @__PURE__ */ jsxs(Menu.Root, {
12230
12343
  positioning: {
12231
12344
  placement: "right-start",
@@ -12240,13 +12353,18 @@ const InsertColumnSubmenu = ({ label, valuePrefix, availableFields, onSelect })
12240
12353
  maxH: "300px",
12241
12354
  minW: "200px",
12242
12355
  overflowY: "auto",
12243
- children: availableFields.map((col) => /* @__PURE__ */ jsx(FieldMenuItem, {
12244
- field: col.field,
12245
- name: col.label,
12246
- fieldType: col.fieldType,
12356
+ children: groupedFields.map((item) => isFileFieldGroup(item) ? /* @__PURE__ */ jsx(FileFieldSubmenu, {
12357
+ group: item,
12358
+ parentVisible: item.parentVisible,
12359
+ valuePrefix,
12360
+ onClick: onSelect
12361
+ }, item.parent.field) : /* @__PURE__ */ jsx(FieldMenuItem, {
12362
+ field: item.field,
12363
+ name: item.label,
12364
+ fieldType: item.fieldType,
12247
12365
  valuePrefix,
12248
12366
  onClick: onSelect
12249
- }, col.field))
12367
+ }, item.field))
12250
12368
  }) }) })]
12251
12369
  });
12252
12370
  };
@@ -12329,12 +12447,14 @@ const ColumnHeaderMenu = observer(({ column, columnsModel, sortModel, filterMode
12329
12447
  label: "Insert before",
12330
12448
  valuePrefix: "before",
12331
12449
  availableFields: insertableFields,
12450
+ allColumns: columnsModel.allColumns,
12332
12451
  onSelect: handleInsertBefore
12333
12452
  }),
12334
12453
  /* @__PURE__ */ jsx(InsertColumnSubmenu, {
12335
12454
  label: "Insert after",
12336
12455
  valuePrefix: "after",
12337
12456
  availableFields: insertableFields,
12457
+ allColumns: columnsModel.allColumns,
12338
12458
  onSelect: handleInsertAfter
12339
12459
  }),
12340
12460
  /* @__PURE__ */ jsx(Menu.Separator, {})
@@ -12483,6 +12603,7 @@ const AddColumnButton = observer(({ columnsModel }) => {
12483
12603
  const availableFields = columnsModel.availableFieldsToAdd;
12484
12604
  const availableSystemFields = columnsModel.availableSystemFieldsToAdd;
12485
12605
  if (!columnsModel.hasHiddenColumns) return null;
12606
+ const groupedFields = groupFileFields(availableFields, columnsModel.allColumns);
12486
12607
  return /* @__PURE__ */ jsx(Flex, {
12487
12608
  alignItems: "center",
12488
12609
  px: "4px",
@@ -12516,17 +12637,21 @@ const AddColumnButton = observer(({ columnsModel }) => {
12516
12637
  onClick: columnsModel.addAll,
12517
12638
  children: [/* @__PURE__ */ jsx(PiListBullets, {}), /* @__PURE__ */ jsx(Text, { children: "Add all columns" })]
12518
12639
  }),
12519
- availableFields.length > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Menu.Separator, {}), /* @__PURE__ */ jsxs(Menu.ItemGroup, { children: [/* @__PURE__ */ jsx(Menu.ItemGroupLabel, {
12640
+ groupedFields.length > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Menu.Separator, {}), /* @__PURE__ */ jsxs(Menu.ItemGroup, { children: [/* @__PURE__ */ jsx(Menu.ItemGroupLabel, {
12520
12641
  fontWeight: "medium",
12521
12642
  color: "gray.500",
12522
12643
  fontSize: "xs",
12523
12644
  children: "Data fields"
12524
- }), availableFields.map((col) => /* @__PURE__ */ jsx(FieldMenuItem, {
12525
- field: col.field,
12526
- name: col.label,
12527
- fieldType: col.fieldType,
12645
+ }), groupedFields.map((item) => isFileFieldGroup(item) ? /* @__PURE__ */ jsx(FileFieldSubmenu, {
12646
+ group: item,
12647
+ parentVisible: item.parentVisible,
12648
+ onClick: columnsModel.showColumn
12649
+ }, item.parent.field) : /* @__PURE__ */ jsx(FieldMenuItem, {
12650
+ field: item.field,
12651
+ name: item.label,
12652
+ fieldType: item.fieldType,
12528
12653
  onClick: columnsModel.showColumn
12529
- }, col.field))] })] }),
12654
+ }, item.field))] })] }),
12530
12655
  availableSystemFields.length > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Menu.Separator, {}), /* @__PURE__ */ jsxs(Menu.ItemGroup, { children: [/* @__PURE__ */ jsx(Menu.ItemGroupLabel, {
12531
12656
  fontWeight: "medium",
12532
12657
  color: "gray.500",
@@ -12901,45 +13026,48 @@ const SelectionToolbar = observer(({ selection, allRowIds, onDuplicate, onDelete
12901
13026
  const isAllSelected = selection.isAllSelected(allRowIds);
12902
13027
  return /* @__PURE__ */ jsx(ActionBar.Root, {
12903
13028
  open: selection.isSelectionMode,
12904
- children: /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(ActionBar.Positioner, { children: /* @__PURE__ */ jsxs(ActionBar.Content, {
12905
- "data-testid": "selection-toolbar",
12906
- children: [
12907
- /* @__PURE__ */ jsxs(ActionBar.SelectionTrigger, { children: [selection.selectedCount, " selected"] }),
12908
- /* @__PURE__ */ jsx(ActionBar.Separator, {}),
12909
- !isAllSelected && /* @__PURE__ */ jsxs(Button, {
12910
- variant: "outline",
12911
- size: "sm",
12912
- onClick: () => selection.selectAll(allRowIds),
12913
- "data-testid": "select-all",
12914
- children: [/* @__PURE__ */ jsx(PiCheckSquare, {}), "Select all"]
12915
- }),
12916
- onDuplicate && /* @__PURE__ */ jsxs(Button, {
12917
- variant: "outline",
12918
- size: "sm",
12919
- onClick: () => onDuplicate(selection.selectedIds),
12920
- "data-testid": "duplicate-selected",
12921
- children: [/* @__PURE__ */ jsx(LuCopy, {}), "Duplicate"]
12922
- }),
12923
- onDelete && /* @__PURE__ */ jsxs(Button, {
12924
- variant: "outline",
12925
- size: "sm",
12926
- onClick: () => onDelete(selection.selectedIds),
12927
- "data-testid": "delete-selected",
12928
- children: [/* @__PURE__ */ jsx(LuTrash2, {}), "Delete"]
12929
- }),
12930
- /* @__PURE__ */ jsx(ActionBar.CloseTrigger, {
12931
- asChild: true,
12932
- children: /* @__PURE__ */ jsx(Button, {
12933
- variant: "ghost",
13029
+ children: /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(ActionBar.Positioner, {
13030
+ zIndex: 5,
13031
+ children: /* @__PURE__ */ jsxs(ActionBar.Content, {
13032
+ "data-testid": "selection-toolbar",
13033
+ children: [
13034
+ /* @__PURE__ */ jsxs(ActionBar.SelectionTrigger, { children: [selection.selectedCount, " selected"] }),
13035
+ /* @__PURE__ */ jsx(ActionBar.Separator, {}),
13036
+ !isAllSelected && /* @__PURE__ */ jsxs(Button, {
13037
+ variant: "outline",
13038
+ size: "sm",
13039
+ onClick: () => selection.selectAll(allRowIds),
13040
+ "data-testid": "select-all",
13041
+ children: [/* @__PURE__ */ jsx(PiCheckSquare, {}), "Select all"]
13042
+ }),
13043
+ onDuplicate && /* @__PURE__ */ jsxs(Button, {
13044
+ variant: "outline",
12934
13045
  size: "sm",
12935
- "aria-label": "Exit selection",
12936
- onClick: () => selection.exitSelectionMode(),
12937
- "data-testid": "exit-selection",
12938
- children: /* @__PURE__ */ jsx(PiX, {})
13046
+ onClick: () => onDuplicate(selection.selectedIds),
13047
+ "data-testid": "duplicate-selected",
13048
+ children: [/* @__PURE__ */ jsx(LuCopy, {}), "Duplicate"]
13049
+ }),
13050
+ onDelete && /* @__PURE__ */ jsxs(Button, {
13051
+ variant: "outline",
13052
+ size: "sm",
13053
+ onClick: () => onDelete(selection.selectedIds),
13054
+ "data-testid": "delete-selected",
13055
+ children: [/* @__PURE__ */ jsx(LuTrash2, {}), "Delete"]
13056
+ }),
13057
+ /* @__PURE__ */ jsx(ActionBar.CloseTrigger, {
13058
+ asChild: true,
13059
+ children: /* @__PURE__ */ jsx(Button, {
13060
+ variant: "ghost",
13061
+ size: "sm",
13062
+ "aria-label": "Exit selection",
13063
+ onClick: () => selection.exitSelectionMode(),
13064
+ "data-testid": "exit-selection",
13065
+ children: /* @__PURE__ */ jsx(PiX, {})
13066
+ })
12939
13067
  })
12940
- })
12941
- ]
12942
- }) }) })
13068
+ ]
13069
+ })
13070
+ }) })
12943
13071
  });
12944
13072
  });
12945
13073
 
@@ -14150,5 +14278,5 @@ const TableEditor = observer(({ viewModel, useWindowScroll }) => {
14150
14278
  });
14151
14279
 
14152
14280
  //#endregion
14153
- export { BackButton, BooleanCell, Breadcrumbs, CellFSM, CellRenderer, CellVM, CellWrapper, CloseButton, ColumnsModel, ContentEditable, CopyButton, CreateButton, CreatingEditorVM, CreatingSchemaEditor, DataRow, DateTimeCell, DeleteConfirmDialog, FieldSelect, FileCell, FilterConditionVM, FilterConditionView, FilterCore, FilterCore as FilterModel, FilterFieldType, FilterGroupVM, FilterGroupView, FilterOperator, FilterValueInput, FilterWidget, ForeignKeyCell, GrayButton, HeaderRow, JsonCard, MockDataSource, NumberCell, OPERATORS_BY_TYPE, OperatorSelect, PlusButton, ReadonlyCell, ResizeHandle, RowActionsMenu, RowCountModel, RowCountWidget, RowEditor, RowEditorVM, RowVM, SEARCH_LANGUAGES, SEARCH_TYPES, SORT_SCHEMA, SYSTEM_FIELDS, SYSTEM_FIELD_BY_REF, SYSTEM_FIELD_IDS, SchemaContext, SchemaEditorCore, SchemaTypeIds, SearchForeignKey, SearchForeignKeyVM, SearchLanguage, SearchModel, SearchType, SearchWidget, SelectionModel, SelectionToolbar, SettingsButton, SortDirectionSelect, SortFieldSelect, SortModel, SortRow, SortingsWidget, StringCell, SystemFieldId, TableEditor, TableEditorCore, TableWidget, Tooltip, UpdatingEditorVM, UpdatingSchemaEditor, ViewSettingsBadge, ViewSettingsBadgeModel, ViewerSwitcher, ViewerSwitcherMode, buildWhereClause, ensureReactivityProvider, extractColumns, getDefaultOperator, getLabelByRef, getOperatorLabel, getOperatorsForType, operatorRequiresValue, selectDefaultColumns, typeMenuGroups, useContentEditable };
14281
+ export { BackButton, BooleanCell, Breadcrumbs, CellFSM, CellRenderer, CellVM, CellWrapper, CloseButton, ColumnsModel, ContentEditable, CopyButton, CreateButton, CreatingEditorVM, CreatingSchemaEditor, DataRow, DateTimeCell, DeleteConfirmDialog, FieldSelect, FileCell, FilterConditionVM, FilterConditionView, FilterCore, FilterCore as FilterModel, FilterFieldType, FilterGroupVM, FilterGroupView, FilterOperator, FilterValueInput, FilterWidget, ForeignKeyCell, GrayButton, HeaderRow, JsonCard, MockDataSource, NumberCell, OPERATORS_BY_TYPE, OperatorSelect, PlusButton, ReadonlyCell, ResizeHandle, RowActionsMenu, RowCountModel, RowCountWidget, RowEditor, RowEditorVM, RowVM, SEARCH_LANGUAGES, SEARCH_TYPES, SORT_SCHEMA, SYSTEM_FIELDS, SYSTEM_FIELD_BY_REF, SYSTEM_FIELD_IDS, SchemaContext, SchemaEditorCore, SchemaTypeIds, SearchForeignKey, SearchForeignKeyVM, SearchLanguage, SearchModel, SearchType, SearchWidget, SelectionModel, SelectionToolbar, SettingsButton, SortDirectionSelect, SortFieldSelect, SortModel, SortRow, SortingsWidget, StringCell, SystemFieldId, TableEditor, TableEditorCore, TableWidget, Tooltip, UpdatingEditorVM, UpdatingSchemaEditor, ViewSettingsBadge, ViewSettingsBadgeModel, ViewerSwitcher, ViewerSwitcherMode, buildWhereClause, ensureReactivityProvider, extractColumns, getDefaultOperator, getLabelByRef, getOperatorLabel, getOperatorsForType, groupFileFields, isFileFieldGroup, operatorRequiresValue, selectDefaultColumns, typeMenuGroups, useContentEditable };
14154
14282
  //# sourceMappingURL=index.mjs.map