@revisium/schema-toolkit-ui 0.6.12 → 0.6.14

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
@@ -2,7 +2,7 @@ import * as mobx from "mobx";
2
2
  import { comparer, computed, makeAutoObservable, observable, reaction, runInAction, untracked } from "mobx";
3
3
  import { FIELD_NAME_ERROR_MESSAGE, SchemaParser, SystemSchemaIds, arr, createRowModel, createSchemaTree, createTableModel, fileSchema, generateDefaultValue, isForeignKeyValueNode, isValidFieldName, jsonPointerToSimplePath, num, obj, rowCreatedAtSchema, rowCreatedIdSchema, rowHashSchema, rowIdSchema, rowPublishedAtSchema, rowSchemaHashSchema, rowUpdatedAtSchema, rowVersionIdSchema, str, validateFormulaAgainstSchema } from "@revisium/schema-toolkit";
4
4
  import { createMobxProvider, setReactivityProvider } from "@revisium/schema-toolkit/core";
5
- import { ActionBar, Badge, Box, Button, Checkbox, Flex, HStack, HoverCard, Icon, IconButton, Image, Input, Kbd, Menu, Popover, Portal, SegmentGroup, Spinner, Text, Textarea, Tooltip as Tooltip$1, VStack, chakra } from "@chakra-ui/react";
5
+ import { ActionBar, Badge, Box, Button, Checkbox, Flex, HStack, HoverCard, Icon, IconButton, Image, Input, Kbd, Menu, Popover, Portal, SegmentGroup, Skeleton, Spinner, Text, Textarea, Tooltip as Tooltip$1, VStack, chakra } from "@chakra-ui/react";
6
6
  import { observer } from "mobx-react-lite";
7
7
  import * as React$1 from "react";
8
8
  import React, { Fragment, createContext, memo, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
@@ -9509,6 +9509,14 @@ var SortModel = class {
9509
9509
  direction: sort.direction
9510
9510
  }));
9511
9511
  }
9512
+ serializeToQuerySorts() {
9513
+ const lookup = this._fieldLookup;
9514
+ return this.sorts.map((sort) => ({
9515
+ field: stripDataFieldPrefix(sort.field),
9516
+ direction: sort.direction,
9517
+ type: lookup.get(sort.field)?.fieldType ?? "String"
9518
+ }));
9519
+ }
9512
9520
  applyViewSorts(viewSorts) {
9513
9521
  const lookup = this._fieldLookup;
9514
9522
  const sorts = [];
@@ -9838,7 +9846,7 @@ const SortingsWidget = observer(({ model, availableFields, onChange }) => {
9838
9846
  children: "Clear all"
9839
9847
  }),
9840
9848
  model.hasSorts && /* @__PURE__ */ jsx(CopyJsonPopover, {
9841
- data: model.serializeToViewSorts(),
9849
+ data: model.serializeToQuerySorts(),
9842
9850
  tooltipContent: "Copy sort JSON",
9843
9851
  testId: "sort-copy-json"
9844
9852
  }),
@@ -13970,10 +13978,7 @@ var TableEditorCore = class {
13970
13978
  _buildQuery(after = null) {
13971
13979
  return {
13972
13980
  where: this.filters.hasActiveFilters ? this.filters.buildCurrentWhereClause() : null,
13973
- orderBy: this.sorts.serializeToViewSorts().map((s) => ({
13974
- field: stripDataFieldPrefix(s.field),
13975
- direction: s.direction
13976
- })),
13981
+ orderBy: this.sorts.serializeToQuerySorts(),
13977
13982
  search: this.search.debouncedQuery,
13978
13983
  first: this._pageSize,
13979
13984
  after
@@ -13986,9 +13991,10 @@ var TableEditorCore = class {
13986
13991
  this._replaceRowVMs(result.rows);
13987
13992
  this._endCursor = result.endCursor;
13988
13993
  this._hasNextPage = result.hasNextPage;
13994
+ const isFiltering = this.filters.hasActiveFilters || this.search.hasActiveSearch;
13989
13995
  this.rowCount.setTotalCount(result.totalCount);
13990
- this.rowCount.setBaseTotalCount(result.totalCount);
13991
- this.rowCount.setIsFiltering(this.filters.hasActiveFilters || this.search.hasActiveSearch);
13996
+ if (!isFiltering) this.rowCount.setBaseTotalCount(result.totalCount);
13997
+ this.rowCount.setIsFiltering(isFiltering);
13992
13998
  this._updateNavigationContext();
13993
13999
  });
13994
14000
  }
@@ -14207,6 +14213,45 @@ var MockDataSource = class {
14207
14213
  }
14208
14214
  };
14209
14215
 
14216
+ //#endregion
14217
+ //#region src/hooks/useDelayedVisibility.ts
14218
+ /**
14219
+ * Controls visibility with a show delay and minimum display time.
14220
+ *
14221
+ * - If `active` becomes false before `delayMs` elapses → never shown.
14222
+ * - If shown, stays visible for at least `minShowMs` after `active` becomes false.
14223
+ */
14224
+ function useDelayedVisibility(active, { delayMs = 150, minShowMs = 300 } = {}) {
14225
+ const [visible, setVisible] = useState(false);
14226
+ const shownAt = useRef(null);
14227
+ useEffect(() => {
14228
+ if (active) {
14229
+ const timer = setTimeout(() => {
14230
+ shownAt.current = Date.now();
14231
+ setVisible(true);
14232
+ }, delayMs);
14233
+ return () => clearTimeout(timer);
14234
+ }
14235
+ if (shownAt.current !== null) {
14236
+ const remaining = minShowMs - (Date.now() - shownAt.current);
14237
+ if (remaining > 0) {
14238
+ const timer = setTimeout(() => {
14239
+ shownAt.current = null;
14240
+ setVisible(false);
14241
+ }, remaining);
14242
+ return () => clearTimeout(timer);
14243
+ }
14244
+ shownAt.current = null;
14245
+ }
14246
+ setVisible(false);
14247
+ }, [
14248
+ active,
14249
+ delayMs,
14250
+ minShowMs
14251
+ ]);
14252
+ return visible;
14253
+ }
14254
+
14210
14255
  //#endregion
14211
14256
  //#region src/table-editor/Status/ui/CellInfoWidget.tsx
14212
14257
  const CellInfoWidget = observer(({ model }) => {
@@ -14349,17 +14394,178 @@ const ViewSettingsBadge = observer(({ model }) => {
14349
14394
  });
14350
14395
  });
14351
14396
 
14397
+ //#endregion
14398
+ //#region src/table-editor/TableEditor/ui/TableEditorSkeleton.tsx
14399
+ const HEADER_ROW_HEIGHT = 40;
14400
+ const DATA_ROW_HEIGHT = 40;
14401
+ const SKELETON_ROW_COUNT = 8;
14402
+ const COLUMN_WIDTHS = [
14403
+ 120,
14404
+ 150,
14405
+ 120,
14406
+ 100,
14407
+ 130
14408
+ ];
14409
+ const CONTENT_WIDTHS = [
14410
+ [
14411
+ 80,
14412
+ 110,
14413
+ 70,
14414
+ 60,
14415
+ 90
14416
+ ],
14417
+ [
14418
+ 100,
14419
+ 90,
14420
+ 100,
14421
+ 80,
14422
+ 110
14423
+ ],
14424
+ [
14425
+ 60,
14426
+ 130,
14427
+ 80,
14428
+ 70,
14429
+ 80
14430
+ ],
14431
+ [
14432
+ 90,
14433
+ 100,
14434
+ 60,
14435
+ 90,
14436
+ 100
14437
+ ],
14438
+ [
14439
+ 75,
14440
+ 120,
14441
+ 90,
14442
+ 55,
14443
+ 70
14444
+ ],
14445
+ [
14446
+ 110,
14447
+ 80,
14448
+ 75,
14449
+ 80,
14450
+ 120
14451
+ ],
14452
+ [
14453
+ 85,
14454
+ 140,
14455
+ 95,
14456
+ 65,
14457
+ 95
14458
+ ],
14459
+ [
14460
+ 95,
14461
+ 70,
14462
+ 110,
14463
+ 85,
14464
+ 80
14465
+ ]
14466
+ ];
14467
+ const TableEditorSkeleton = ({ breadcrumbs, onBreadcrumbClick, showCreateButton, useWindowScroll }) => /* @__PURE__ */ jsxs(Box, {
14468
+ display: "flex",
14469
+ flexDirection: "column",
14470
+ height: useWindowScroll ? void 0 : "100%",
14471
+ flex: useWindowScroll ? 1 : void 0,
14472
+ children: [/* @__PURE__ */ jsxs(Flex, {
14473
+ px: 3,
14474
+ pt: "32px",
14475
+ pb: "48px",
14476
+ alignItems: "flex-start",
14477
+ justifyContent: "space-between",
14478
+ ...useWindowScroll && {
14479
+ position: "sticky",
14480
+ top: 0,
14481
+ zIndex: 3,
14482
+ bg: "white"
14483
+ },
14484
+ children: [breadcrumbs.length > 0 ? /* @__PURE__ */ jsx(Breadcrumbs, {
14485
+ segments: breadcrumbs,
14486
+ highlightLast: false,
14487
+ onSegmentClick: onBreadcrumbClick,
14488
+ action: showCreateButton ? /* @__PURE__ */ jsx(Skeleton, {
14489
+ height: "32px",
14490
+ width: "32px",
14491
+ borderRadius: "6px"
14492
+ }) : void 0
14493
+ }) : /* @__PURE__ */ jsx(Box, {}), /* @__PURE__ */ jsxs(Flex, {
14494
+ alignItems: "center",
14495
+ gap: "8px",
14496
+ children: [
14497
+ /* @__PURE__ */ jsx(Skeleton, {
14498
+ height: "32px",
14499
+ width: "32px",
14500
+ borderRadius: "6px"
14501
+ }),
14502
+ /* @__PURE__ */ jsx(Skeleton, {
14503
+ height: "32px",
14504
+ width: "32px",
14505
+ borderRadius: "6px"
14506
+ }),
14507
+ /* @__PURE__ */ jsx(Skeleton, {
14508
+ height: "32px",
14509
+ width: "32px",
14510
+ borderRadius: "6px"
14511
+ })
14512
+ ]
14513
+ })]
14514
+ }), /* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsx(Flex, {
14515
+ height: `${HEADER_ROW_HEIGHT}px`,
14516
+ alignItems: "center",
14517
+ px: 3,
14518
+ borderBottom: "1px solid",
14519
+ borderColor: "gray.100",
14520
+ children: COLUMN_WIDTHS.map((colWidth, j) => /* @__PURE__ */ jsx(Box, {
14521
+ width: `${colWidth}px`,
14522
+ flexShrink: 0,
14523
+ children: /* @__PURE__ */ jsx(Skeleton, {
14524
+ height: "12px",
14525
+ width: "60px",
14526
+ borderRadius: "4px"
14527
+ })
14528
+ }, `h-${j}`))
14529
+ }), CONTENT_WIDTHS.slice(0, SKELETON_ROW_COUNT).map((contentWidths, i) => /* @__PURE__ */ jsx(Flex, {
14530
+ height: `${DATA_ROW_HEIGHT}px`,
14531
+ alignItems: "center",
14532
+ px: 3,
14533
+ borderBottom: "1px solid",
14534
+ borderColor: "gray.100",
14535
+ children: COLUMN_WIDTHS.map((colWidth, j) => /* @__PURE__ */ jsx(Box, {
14536
+ width: `${colWidth}px`,
14537
+ flexShrink: 0,
14538
+ children: /* @__PURE__ */ jsx(Skeleton, {
14539
+ height: "14px",
14540
+ width: `${contentWidths[j]}px`,
14541
+ borderRadius: "4px"
14542
+ })
14543
+ }, `r-${i}-c-${j}`))
14544
+ }, `r-${i}`))] })]
14545
+ });
14546
+
14352
14547
  //#endregion
14353
14548
  //#region src/table-editor/TableEditor/ui/TableEditor.tsx
14354
14549
  const noop = () => {};
14550
+ function getWriteCallbacks(isReadonly, viewModel, callbacks) {
14551
+ return {
14552
+ onDeleteRow: isReadonly ? void 0 : (id) => viewModel.deleteRows([id]),
14553
+ onDuplicateRow: isReadonly ? void 0 : callbacks.onDuplicateRow,
14554
+ onDeleteSelected: isReadonly ? void 0 : (ids) => viewModel.deleteRows(ids),
14555
+ onUploadFile: isReadonly ? void 0 : callbacks.onUploadFile
14556
+ };
14557
+ }
14355
14558
  const TableEditor = observer(({ viewModel, useWindowScroll }) => {
14356
- if (viewModel.isBootstrapping) return /* @__PURE__ */ jsx(Box, {
14357
- display: "flex",
14358
- alignItems: "center",
14359
- justifyContent: "center",
14360
- height: "100%",
14361
- children: /* @__PURE__ */ jsx(Spinner, {})
14362
- });
14559
+ const showSkeleton = useDelayedVisibility(viewModel.isBootstrapping);
14560
+ if (viewModel.isBootstrapping) {
14561
+ if (!showSkeleton) return null;
14562
+ return /* @__PURE__ */ jsx(TableEditorSkeleton, {
14563
+ breadcrumbs: viewModel.breadcrumbs,
14564
+ onBreadcrumbClick: viewModel.callbacks.onBreadcrumbClick,
14565
+ showCreateButton: !viewModel.readonly && !!viewModel.callbacks.onCreateRow,
14566
+ useWindowScroll
14567
+ });
14568
+ }
14363
14569
  const isReadonly = viewModel.readonly;
14364
14570
  const { breadcrumbs, callbacks } = viewModel;
14365
14571
  return /* @__PURE__ */ jsxs(Box, {
@@ -14420,11 +14626,8 @@ const TableEditor = observer(({ viewModel, useWindowScroll }) => {
14420
14626
  onEndReached: viewModel.loadMore,
14421
14627
  onOpenRow: callbacks.onOpenRow,
14422
14628
  onPickRow: callbacks.onPickRow,
14423
- onDeleteRow: isReadonly ? void 0 : (id) => viewModel.deleteRows([id]),
14424
- onDuplicateRow: isReadonly ? void 0 : callbacks.onDuplicateRow,
14425
- onDeleteSelected: isReadonly ? void 0 : (ids) => viewModel.deleteRows(ids),
14629
+ ...getWriteCallbacks(isReadonly, viewModel, callbacks),
14426
14630
  onSearchForeignKey: callbacks.onSearchForeignKey,
14427
- onUploadFile: isReadonly ? void 0 : callbacks.onUploadFile,
14428
14631
  onOpenFile: callbacks.onOpenFile,
14429
14632
  onCopyPath: callbacks.onCopyPath,
14430
14633
  useWindowScroll
@@ -14457,5 +14660,5 @@ const TableEditor = observer(({ viewModel, useWindowScroll }) => {
14457
14660
  });
14458
14661
 
14459
14662
  //#endregion
14460
- 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 };
14663
+ 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, useDelayedVisibility };
14461
14664
  //# sourceMappingURL=index.mjs.map