@entifix/react-controls 0.18.2 → 0.20.0
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/README.md +13 -5
- package/dist/i18n/catalog/en.d.ts.map +1 -1
- package/dist/i18n/catalog/en.js +68 -10
- package/dist/i18n/catalog/en.js.map +1 -1
- package/dist/i18n/catalog/es.d.ts +76 -5
- package/dist/i18n/catalog/es.d.ts.map +1 -1
- package/dist/i18n/catalog/es.js +74 -10
- package/dist/i18n/catalog/es.js.map +1 -1
- package/dist/i18n/catalog/index.d.ts +126 -10
- package/dist/i18n/catalog/index.d.ts.map +1 -1
- package/dist/i18n/entity-labels.d.ts +14 -0
- package/dist/i18n/entity-labels.d.ts.map +1 -1
- package/dist/i18n/entity-labels.js +15 -0
- package/dist/i18n/entity-labels.js.map +1 -1
- package/dist/i18n/i18n-context.js +2 -2
- package/dist/i18n/i18n-context.js.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -2
- package/dist/index.js.map +1 -1
- package/dist/primitives.d.ts +7 -1
- package/dist/primitives.d.ts.map +1 -1
- package/dist/primitives.js +7 -1
- package/dist/primitives.js.map +1 -1
- package/dist/theme/index.d.ts +1 -0
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +1 -0
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/theme-context.d.ts +35 -7
- package/dist/theme/theme-context.d.ts.map +1 -1
- package/dist/theme/theme-context.js +109 -21
- package/dist/theme/theme-context.js.map +1 -1
- package/dist/theme/theme-cookie.d.ts +9 -0
- package/dist/theme/theme-cookie.d.ts.map +1 -0
- package/dist/theme/theme-cookie.js +8 -0
- package/dist/theme/theme-cookie.js.map +1 -0
- package/dist/theme/theme-script.d.ts +8 -5
- package/dist/theme/theme-script.d.ts.map +1 -1
- package/dist/theme/theme-script.js +24 -10
- package/dist/theme/theme-script.js.map +1 -1
- package/dist/theme/types.d.ts +19 -3
- package/dist/theme/types.d.ts.map +1 -1
- package/dist/theme/types.js.map +1 -1
- package/dist/ui/actions/action-surfaces.d.ts +1 -1
- package/dist/ui/actions/action-surfaces.js +1 -1
- package/dist/ui/actions/action-surfaces.js.map +1 -1
- package/dist/ui/actions/error-actions.d.ts +32 -0
- package/dist/ui/actions/error-actions.d.ts.map +1 -0
- package/dist/ui/actions/error-actions.js +40 -0
- package/dist/ui/actions/error-actions.js.map +1 -0
- package/dist/ui/actions/index.d.ts +2 -0
- package/dist/ui/actions/index.d.ts.map +1 -1
- package/dist/ui/actions/index.js +2 -0
- package/dist/ui/actions/index.js.map +1 -1
- package/dist/ui/actions/shortcut.d.ts +13 -0
- package/dist/ui/actions/shortcut.d.ts.map +1 -0
- package/dist/ui/actions/shortcut.js +18 -0
- package/dist/ui/actions/shortcut.js.map +1 -0
- package/dist/ui/actions/use-verb-invoker.d.ts +50 -0
- package/dist/ui/actions/use-verb-invoker.d.ts.map +1 -0
- package/dist/ui/actions/use-verb-invoker.js +93 -0
- package/dist/ui/actions/use-verb-invoker.js.map +1 -0
- package/dist/ui/atoms/alert/alert-dismiss.d.ts +9 -0
- package/dist/ui/atoms/alert/alert-dismiss.d.ts.map +1 -0
- package/dist/ui/atoms/alert/alert-dismiss.js +28 -0
- package/dist/ui/atoms/alert/alert-dismiss.js.map +1 -0
- package/dist/ui/atoms/alert/alert.d.ts +24 -0
- package/dist/ui/atoms/alert/alert.d.ts.map +1 -0
- package/dist/ui/atoms/alert/alert.js +50 -0
- package/dist/ui/atoms/alert/alert.js.map +1 -0
- package/dist/ui/atoms/alert/index.d.ts +3 -0
- package/dist/ui/atoms/alert/index.d.ts.map +1 -0
- package/dist/ui/atoms/alert/index.js +4 -0
- package/dist/ui/atoms/alert/index.js.map +1 -0
- package/dist/ui/atoms/alert/tone.d.ts +8 -0
- package/dist/ui/atoms/alert/tone.d.ts.map +1 -0
- package/dist/ui/atoms/alert/tone.js +11 -0
- package/dist/ui/atoms/alert/tone.js.map +1 -0
- package/dist/ui/atoms/button/button-recipe.js +1 -1
- package/dist/ui/atoms/button/button-recipe.js.map +1 -1
- package/dist/ui/atoms/button/index.d.ts +1 -0
- package/dist/ui/atoms/button/index.d.ts.map +1 -1
- package/dist/ui/atoms/button/index.js +1 -0
- package/dist/ui/atoms/button/index.js.map +1 -1
- package/dist/ui/atoms/button/submit-button.d.ts +13 -0
- package/dist/ui/atoms/button/submit-button.d.ts.map +1 -0
- package/dist/ui/atoms/button/submit-button.js +29 -0
- package/dist/ui/atoms/button/submit-button.js.map +1 -0
- package/dist/ui/atoms/cell-value/cell-value.d.ts +6 -1
- package/dist/ui/atoms/cell-value/cell-value.d.ts.map +1 -1
- package/dist/ui/atoms/cell-value/cell-value.js +48 -16
- package/dist/ui/atoms/cell-value/cell-value.js.map +1 -1
- package/dist/ui/atoms/field/checkbox.d.ts.map +1 -1
- package/dist/ui/atoms/field/checkbox.js +21 -1
- package/dist/ui/atoms/field/checkbox.js.map +1 -1
- package/dist/ui/atoms/field/field.js +1 -1
- package/dist/ui/atoms/field/field.js.map +1 -1
- package/dist/ui/atoms/field-control/field-control.d.ts +7 -1
- package/dist/ui/atoms/field-control/field-control.d.ts.map +1 -1
- package/dist/ui/atoms/field-control/field-control.js +25 -3
- package/dist/ui/atoms/field-control/field-control.js.map +1 -1
- package/dist/ui/atoms/money/index.d.ts +4 -0
- package/dist/ui/atoms/money/index.d.ts.map +1 -0
- package/dist/ui/atoms/money/index.js +5 -0
- package/dist/ui/atoms/money/index.js.map +1 -0
- package/dist/ui/atoms/money/money-input.d.ts +19 -0
- package/dist/ui/atoms/money/money-input.d.ts.map +1 -0
- package/dist/ui/atoms/money/money-input.js +75 -0
- package/dist/ui/atoms/money/money-input.js.map +1 -0
- package/dist/ui/atoms/money/money-math.d.ts +21 -0
- package/dist/ui/atoms/money/money-math.d.ts.map +1 -0
- package/dist/ui/atoms/money/money-math.js +36 -0
- package/dist/ui/atoms/money/money-math.js.map +1 -0
- package/dist/ui/atoms/money/money.d.ts +19 -0
- package/dist/ui/atoms/money/money.d.ts.map +1 -0
- package/dist/ui/atoms/money/money.js +26 -0
- package/dist/ui/atoms/money/money.js.map +1 -0
- package/dist/ui/atoms/number-input/index.d.ts +3 -0
- package/dist/ui/atoms/number-input/index.d.ts.map +1 -0
- package/dist/ui/atoms/number-input/index.js +4 -0
- package/dist/ui/atoms/number-input/index.js.map +1 -0
- package/dist/ui/atoms/number-input/number-input.d.ts +10 -0
- package/dist/ui/atoms/number-input/number-input.d.ts.map +1 -0
- package/dist/ui/atoms/number-input/number-input.js +23 -0
- package/dist/ui/atoms/number-input/number-input.js.map +1 -0
- package/dist/ui/atoms/number-input/quantity-input.d.ts +29 -0
- package/dist/ui/atoms/number-input/quantity-input.d.ts.map +1 -0
- package/dist/ui/atoms/number-input/quantity-input.js +100 -0
- package/dist/ui/atoms/number-input/quantity-input.js.map +1 -0
- package/dist/ui/atoms/skeleton/skeleton.js +1 -1
- package/dist/ui/atoms/skeleton/skeleton.js.map +1 -1
- package/dist/ui/atoms/status-tag/index.d.ts +2 -0
- package/dist/ui/atoms/status-tag/index.d.ts.map +1 -0
- package/dist/ui/atoms/status-tag/index.js +3 -0
- package/dist/ui/atoms/status-tag/index.js.map +1 -0
- package/dist/ui/atoms/status-tag/status-tag.d.ts +17 -0
- package/dist/ui/atoms/status-tag/status-tag.d.ts.map +1 -0
- package/dist/ui/atoms/status-tag/status-tag.js +37 -0
- package/dist/ui/atoms/status-tag/status-tag.js.map +1 -0
- package/dist/ui/atoms/switch/switch.d.ts.map +1 -1
- package/dist/ui/atoms/switch/switch.js +6 -3
- package/dist/ui/atoms/switch/switch.js.map +1 -1
- package/dist/ui/atoms/table/table.d.ts +12 -3
- package/dist/ui/atoms/table/table.d.ts.map +1 -1
- package/dist/ui/atoms/table/table.js +59 -10
- package/dist/ui/atoms/table/table.js.map +1 -1
- package/dist/ui/atoms/text/text.d.ts +2 -2
- package/dist/ui/atoms/text/text.d.ts.map +1 -1
- package/dist/ui/atoms/text/text.js.map +1 -1
- package/dist/ui/molecules/action-bar/action-bar.d.ts +76 -0
- package/dist/ui/molecules/action-bar/action-bar.d.ts.map +1 -0
- package/dist/ui/molecules/action-bar/action-bar.js +218 -0
- package/dist/ui/molecules/action-bar/action-bar.js.map +1 -0
- package/dist/ui/molecules/action-bar/index.d.ts +2 -0
- package/dist/ui/molecules/action-bar/index.d.ts.map +1 -0
- package/dist/ui/molecules/action-bar/index.js +3 -0
- package/dist/ui/molecules/action-bar/index.js.map +1 -0
- package/dist/ui/molecules/breadcrumbs/breadcrumbs.d.ts +11 -2
- package/dist/ui/molecules/breadcrumbs/breadcrumbs.d.ts.map +1 -1
- package/dist/ui/molecules/breadcrumbs/breadcrumbs.js +9 -7
- package/dist/ui/molecules/breadcrumbs/breadcrumbs.js.map +1 -1
- package/dist/ui/molecules/bulk-action-bar/bulk-action-bar.d.ts.map +1 -1
- package/dist/ui/molecules/bulk-action-bar/bulk-action-bar.js +8 -10
- package/dist/ui/molecules/bulk-action-bar/bulk-action-bar.js.map +1 -1
- package/dist/ui/molecules/bulk-result/bulk-result.d.ts +3 -3
- package/dist/ui/molecules/bulk-result/bulk-result.js +4 -4
- package/dist/ui/molecules/bulk-result/bulk-result.js.map +1 -1
- package/dist/ui/molecules/column-settings/column-settings.js +1 -1
- package/dist/ui/molecules/column-settings/column-settings.js.map +1 -1
- package/dist/ui/molecules/confirm-dialog/confirm-dialog.d.ts +24 -9
- package/dist/ui/molecules/confirm-dialog/confirm-dialog.d.ts.map +1 -1
- package/dist/ui/molecules/confirm-dialog/confirm-dialog.js +38 -13
- package/dist/ui/molecules/confirm-dialog/confirm-dialog.js.map +1 -1
- package/dist/ui/molecules/description-list/description-list.d.ts +17 -0
- package/dist/ui/molecules/description-list/description-list.d.ts.map +1 -0
- package/dist/ui/molecules/description-list/description-list.js +36 -0
- package/dist/ui/molecules/description-list/description-list.js.map +1 -0
- package/dist/ui/molecules/description-list/index.d.ts +2 -0
- package/dist/ui/molecules/description-list/index.d.ts.map +1 -0
- package/dist/ui/molecules/description-list/index.js +3 -0
- package/dist/ui/molecules/description-list/index.js.map +1 -0
- package/dist/ui/molecules/drawer/drawer.js +3 -3
- package/dist/ui/molecules/drawer/drawer.js.map +1 -1
- package/dist/ui/molecules/empty-state/empty-state.d.ts +15 -0
- package/dist/ui/molecules/empty-state/empty-state.d.ts.map +1 -0
- package/dist/ui/molecules/empty-state/empty-state.js +29 -0
- package/dist/ui/molecules/empty-state/empty-state.js.map +1 -0
- package/dist/ui/molecules/empty-state/index.d.ts +2 -0
- package/dist/ui/molecules/empty-state/index.d.ts.map +1 -0
- package/dist/ui/molecules/empty-state/index.js +3 -0
- package/dist/ui/molecules/empty-state/index.js.map +1 -0
- package/dist/ui/molecules/entity-link-input/entity-link-input.d.ts.map +1 -1
- package/dist/ui/molecules/entity-link-input/entity-link-input.js +7 -4
- package/dist/ui/molecules/entity-link-input/entity-link-input.js.map +1 -1
- package/dist/ui/molecules/entity-link-picker/entity-link-picker.js +2 -2
- package/dist/ui/molecules/entity-link-picker/entity-link-picker.js.map +1 -1
- package/dist/ui/molecules/entity-record-card/entity-record-card.d.ts +33 -20
- package/dist/ui/molecules/entity-record-card/entity-record-card.d.ts.map +1 -1
- package/dist/ui/molecules/entity-record-card/entity-record-card.js +53 -20
- package/dist/ui/molecules/entity-record-card/entity-record-card.js.map +1 -1
- package/dist/ui/molecules/filter-builder/filter-builder.d.ts +8 -2
- package/dist/ui/molecules/filter-builder/filter-builder.d.ts.map +1 -1
- package/dist/ui/molecules/filter-builder/filter-builder.js +14 -5
- package/dist/ui/molecules/filter-builder/filter-builder.js.map +1 -1
- package/dist/ui/molecules/filter-chips/filter-chips.d.ts +16 -0
- package/dist/ui/molecules/filter-chips/filter-chips.d.ts.map +1 -0
- package/dist/ui/molecules/filter-chips/filter-chips.js +73 -0
- package/dist/ui/molecules/filter-chips/filter-chips.js.map +1 -0
- package/dist/ui/molecules/filter-chips/index.d.ts +2 -0
- package/dist/ui/molecules/filter-chips/index.d.ts.map +1 -0
- package/dist/ui/molecules/filter-chips/index.js +3 -0
- package/dist/ui/molecules/filter-chips/index.js.map +1 -0
- package/dist/ui/molecules/media-gallery/index.d.ts +2 -0
- package/dist/ui/molecules/media-gallery/index.d.ts.map +1 -0
- package/dist/ui/molecules/media-gallery/index.js +3 -0
- package/dist/ui/molecules/media-gallery/index.js.map +1 -0
- package/dist/ui/molecules/media-gallery/media-gallery.d.ts +31 -0
- package/dist/ui/molecules/media-gallery/media-gallery.d.ts.map +1 -0
- package/dist/ui/molecules/media-gallery/media-gallery.js +64 -0
- package/dist/ui/molecules/media-gallery/media-gallery.js.map +1 -0
- package/dist/ui/molecules/menu/menu.d.ts +11 -1
- package/dist/ui/molecules/menu/menu.d.ts.map +1 -1
- package/dist/ui/molecules/menu/menu.js +68 -6
- package/dist/ui/molecules/menu/menu.js.map +1 -1
- package/dist/ui/molecules/nav-menu/nav-menu.js +4 -4
- package/dist/ui/molecules/nav-menu/nav-menu.js.map +1 -1
- package/dist/ui/molecules/pagination/pagination.d.ts +5 -0
- package/dist/ui/molecules/pagination/pagination.d.ts.map +1 -1
- package/dist/ui/molecules/pagination/pagination.js +35 -18
- package/dist/ui/molecules/pagination/pagination.js.map +1 -1
- package/dist/ui/molecules/region-state/index.d.ts +2 -0
- package/dist/ui/molecules/region-state/index.d.ts.map +1 -0
- package/dist/ui/molecules/region-state/index.js +3 -0
- package/dist/ui/molecules/region-state/index.js.map +1 -0
- package/dist/ui/molecules/region-state/region-state.d.ts +42 -0
- package/dist/ui/molecules/region-state/region-state.d.ts.map +1 -0
- package/dist/ui/molecules/region-state/region-state.js +83 -0
- package/dist/ui/molecules/region-state/region-state.js.map +1 -0
- package/dist/ui/molecules/segmented-nav/segment-classes.d.ts +3 -3
- package/dist/ui/molecules/segmented-nav/segment-classes.d.ts.map +1 -1
- package/dist/ui/molecules/segmented-nav/segment-classes.js +2 -2
- package/dist/ui/molecules/segmented-nav/segment-classes.js.map +1 -1
- package/dist/ui/molecules/segmented-nav/segmented-nav.d.ts +14 -4
- package/dist/ui/molecules/segmented-nav/segmented-nav.d.ts.map +1 -1
- package/dist/ui/molecules/segmented-nav/segmented-nav.js +6 -5
- package/dist/ui/molecules/segmented-nav/segmented-nav.js.map +1 -1
- package/dist/ui/molecules/split-view/split-view.js +3 -3
- package/dist/ui/molecules/split-view/split-view.js.map +1 -1
- package/dist/ui/molecules/tab-strip/tab-strip.d.ts +51 -12
- package/dist/ui/molecules/tab-strip/tab-strip.d.ts.map +1 -1
- package/dist/ui/molecules/tab-strip/tab-strip.js +125 -34
- package/dist/ui/molecules/tab-strip/tab-strip.js.map +1 -1
- package/dist/ui/molecules/table-toolbar/table-toolbar.d.ts +3 -1
- package/dist/ui/molecules/table-toolbar/table-toolbar.d.ts.map +1 -1
- package/dist/ui/molecules/table-toolbar/table-toolbar.js +3 -2
- package/dist/ui/molecules/table-toolbar/table-toolbar.js.map +1 -1
- package/dist/ui/molecules/toast-region/toast-region.d.ts +63 -19
- package/dist/ui/molecules/toast-region/toast-region.d.ts.map +1 -1
- package/dist/ui/molecules/toast-region/toast-region.js +129 -42
- package/dist/ui/molecules/toast-region/toast-region.js.map +1 -1
- package/dist/ui/organisms/command-palette/command-palette.d.ts.map +1 -1
- package/dist/ui/organisms/command-palette/command-palette.js +25 -18
- package/dist/ui/organisms/command-palette/command-palette.js.map +1 -1
- package/dist/ui/organisms/entity-detail-grid/entity-detail-grid.d.ts.map +1 -1
- package/dist/ui/organisms/entity-detail-grid/entity-detail-grid.js +8 -3
- package/dist/ui/organisms/entity-detail-grid/entity-detail-grid.js.map +1 -1
- package/dist/ui/organisms/entity-form/entity-form.d.ts +1 -1
- package/dist/ui/organisms/entity-form/entity-form.d.ts.map +1 -1
- package/dist/ui/organisms/entity-form/entity-form.js +325 -215
- package/dist/ui/organisms/entity-form/entity-form.js.map +1 -1
- package/dist/ui/organisms/entity-form/entity-form.types.d.ts +8 -0
- package/dist/ui/organisms/entity-form/entity-form.types.d.ts.map +1 -1
- package/dist/ui/organisms/entity-form/entity-form.types.js.map +1 -1
- package/dist/ui/organisms/entity-table/entity-table.d.ts +1 -1
- package/dist/ui/organisms/entity-table/entity-table.d.ts.map +1 -1
- package/dist/ui/organisms/entity-table/entity-table.js +334 -198
- package/dist/ui/organisms/entity-table/entity-table.js.map +1 -1
- package/dist/ui/organisms/entity-table/entity-table.types.d.ts +19 -4
- package/dist/ui/organisms/entity-table/entity-table.types.d.ts.map +1 -1
- package/dist/ui/organisms/entity-table/entity-table.types.js.map +1 -1
- package/dist/ui/organisms/entity-table/header-sort.d.ts +18 -0
- package/dist/ui/organisms/entity-table/header-sort.d.ts.map +1 -0
- package/dist/ui/organisms/entity-table/header-sort.js +54 -0
- package/dist/ui/organisms/entity-table/header-sort.js.map +1 -0
- package/dist/ui/organisms/entity-table/pivot.d.ts +25 -0
- package/dist/ui/organisms/entity-table/pivot.d.ts.map +1 -0
- package/dist/ui/organisms/entity-table/pivot.js +106 -0
- package/dist/ui/organisms/entity-table/pivot.js.map +1 -0
- package/dist/ui/organisms/entity-table/use-result-announcement.d.ts +13 -0
- package/dist/ui/organisms/entity-table/use-result-announcement.d.ts.map +1 -0
- package/dist/ui/organisms/entity-table/use-result-announcement.js +31 -0
- package/dist/ui/organisms/entity-table/use-result-announcement.js.map +1 -0
- package/dist/ui/organisms/top-bar/live-indicator.d.ts +11 -0
- package/dist/ui/organisms/top-bar/live-indicator.d.ts.map +1 -0
- package/dist/ui/organisms/top-bar/live-indicator.js +46 -0
- package/dist/ui/organisms/top-bar/live-indicator.js.map +1 -0
- package/dist/ui/organisms/top-bar/top-bar.d.ts +11 -2
- package/dist/ui/organisms/top-bar/top-bar.d.ts.map +1 -1
- package/dist/ui/organisms/top-bar/top-bar.js +14 -5
- package/dist/ui/organisms/top-bar/top-bar.js.map +1 -1
- package/dist/ui/organisms/wizard/wizard.d.ts +1 -1
- package/dist/ui/organisms/wizard/wizard.d.ts.map +1 -1
- package/dist/ui/organisms/wizard/wizard.js +7 -1
- package/dist/ui/organisms/wizard/wizard.js.map +1 -1
- package/dist/ui/organisms/wizard/wizard.types.d.ts +8 -0
- package/dist/ui/organisms/wizard/wizard.types.d.ts.map +1 -1
- package/dist/ui/organisms/wizard/wizard.types.js.map +1 -1
- package/dist/ui/utils/live-updates.d.ts +24 -0
- package/dist/ui/utils/live-updates.d.ts.map +1 -0
- package/dist/ui/utils/live-updates.js +20 -0
- package/dist/ui/utils/live-updates.js.map +1 -0
- package/dist/ui/utils/use-focus-on-arrival.d.ts +14 -0
- package/dist/ui/utils/use-focus-on-arrival.d.ts.map +1 -0
- package/dist/ui/utils/use-focus-on-arrival.js +42 -0
- package/dist/ui/utils/use-focus-on-arrival.js.map +1 -0
- package/dist/ui/utils/use-hotkey.d.ts +44 -25
- package/dist/ui/utils/use-hotkey.d.ts.map +1 -1
- package/dist/ui/utils/use-hotkey.js +80 -48
- package/dist/ui/utils/use-hotkey.js.map +1 -1
- package/package.json +5 -5
- package/dist/ui/molecules/split-button/index.d.ts +0 -2
- package/dist/ui/molecules/split-button/index.d.ts.map +0 -1
- package/dist/ui/molecules/split-button/index.js +0 -3
- package/dist/ui/molecules/split-button/index.js.map +0 -1
- package/dist/ui/molecules/split-button/split-button.d.ts +0 -21
- package/dist/ui/molecules/split-button/split-button.d.ts.map +0 -1
- package/dist/ui/molecules/split-button/split-button.js +0 -35
- package/dist/ui/molecules/split-button/split-button.js.map +0 -1
|
@@ -1,48 +1,34 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { emptySelection, extractMetaEntity, hierarchyOf, isSelected, selectionSize, toggleSelected } from '@entifix/core';
|
|
4
|
-
import { Fragment, useMemo, useRef, useState } from 'react';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
3
|
+
import { emptySelection, extractMetaEntity, hierarchyOf, isSelected, queryPropertyFor, selectionSize, toggleSelected } from '@entifix/core';
|
|
4
|
+
import { Fragment, useId, useMemo, useRef, useState } from 'react';
|
|
5
|
+
import { useEntityNoun, useLocale, useT, useTranslateKey } from '../../../i18n/index.js';
|
|
6
|
+
import { renderAnchor, useCasesForSurface } from '../../actions/index.js';
|
|
7
|
+
import { useVerbInvoker } from '../../actions/use-verb-invoker.js';
|
|
8
|
+
import { Button, button } from '../../atoms/button/index.js';
|
|
8
9
|
import { CellValue } from '../../atoms/cell-value/index.js';
|
|
9
10
|
import { Checkbox } from '../../atoms/field/index.js';
|
|
10
11
|
import { Skeleton } from '../../atoms/skeleton/index.js';
|
|
11
12
|
import { Table, TableBody, TableCell, TableHead, TableHeaderCell, TableMessageRow, TableRow } from '../../atoms/table/index.js';
|
|
12
13
|
import { linkClassName } from '../../atoms/text/index.js';
|
|
14
|
+
import { ActionBar, itemsForUseCases } from '../../molecules/action-bar/index.js';
|
|
13
15
|
import { BulkActionBar } from '../../molecules/bulk-action-bar/index.js';
|
|
14
16
|
import { BulkResult } from '../../molecules/bulk-result/index.js';
|
|
15
17
|
import { ColumnSettings } from '../../molecules/column-settings/index.js';
|
|
16
|
-
import { ConfirmDialog } from '../../molecules/confirm-dialog/index.js';
|
|
17
18
|
import { EntityRecordCard } from '../../molecules/entity-record-card/index.js';
|
|
18
19
|
import { FilterBuilder } from '../../molecules/filter-builder/index.js';
|
|
20
|
+
import { FilterChips } from '../../molecules/filter-chips/index.js';
|
|
19
21
|
import { LoadingBoundary } from '../../molecules/loading-boundary/index.js';
|
|
20
|
-
import { Menu } from '../../molecules/menu/index.js';
|
|
21
22
|
import { Pagination } from '../../molecules/pagination/index.js';
|
|
23
|
+
import { RegionState } from '../../molecules/region-state/index.js';
|
|
22
24
|
import { SortBuilder } from '../../molecules/sort-builder/index.js';
|
|
23
25
|
import { TableToolbar } from '../../molecules/table-toolbar/index.js';
|
|
24
26
|
import { readEntityTableSlots } from './entity-table-slots.js';
|
|
25
27
|
import { shownTreeRows, TreeCell, treeRows } from './entity-table-tree.js';
|
|
28
|
+
import { nextHeaderSorting, sortKeys } from './header-sort.js';
|
|
29
|
+
import { ACTIONS_WIDTH, pivotClasses, pivotWidth, SELECTION_WIDTH } from './pivot.js';
|
|
26
30
|
import { useEntityTableColumns } from './use-entity-table-columns.js';
|
|
27
|
-
|
|
28
|
-
* The grid and the card list are both rendered, and CSS picks one. A JS
|
|
29
|
-
* breakpoint hook would have to guess during SSR and correct after mount —
|
|
30
|
-
* a hydration mismatch on every page load. Classes are written out in full
|
|
31
|
-
* because Tailwind cannot see a class name that is concatenated at runtime.
|
|
32
|
-
*/ const PIVOT_CLASS = {
|
|
33
|
-
sm: {
|
|
34
|
-
grid: 'hidden sm:block',
|
|
35
|
-
cards: 'sm:hidden'
|
|
36
|
-
},
|
|
37
|
-
md: {
|
|
38
|
-
grid: 'hidden md:block',
|
|
39
|
-
cards: 'md:hidden'
|
|
40
|
-
},
|
|
41
|
-
lg: {
|
|
42
|
-
grid: 'hidden lg:block',
|
|
43
|
-
cards: 'lg:hidden'
|
|
44
|
-
}
|
|
45
|
-
};
|
|
31
|
+
import { useResultAnnouncement } from './use-result-announcement.js';
|
|
46
32
|
/**
|
|
47
33
|
* How many placeholder rows the built-in skeleton draws.
|
|
48
34
|
*
|
|
@@ -51,36 +37,18 @@ import { useEntityTableColumns } from './use-entity-table-columns.js';
|
|
|
51
37
|
* a fifty-row page would otherwise paint fifty shimmer rows to stand in for
|
|
52
38
|
* content that arrives below the fold anyway.
|
|
53
39
|
*/ const SKELETON_ROW_CAP = 5;
|
|
54
|
-
|
|
55
|
-
|
|
40
|
+
/** How many members a card shows as meta when none declares a `card` role. */ const UNDECLARED_META_CAP = 3;
|
|
41
|
+
export function EntityTable({ entityConstructor, isLoading, skeleton = true, error, items, totalItems, currentPage, pageSize, onPageChange, onPageSizeChange, hrefFor, newHref, renderLink = renderAnchor, onSelect, preferencesKey, showControls = true, pivotBreakpoint, filtering, sorting, onFilteringChange, onSortingChange, facets, selection, onSelectionChange, metadata, isMetadataLoading = false, onBulkUseCase, onUseCase, onRetry, bulkOutcomes, onBulkDismiss, onBulkRetry, isBulkRunning = false, children }) {
|
|
42
|
+
var _ref, _ref1;
|
|
56
43
|
const t = useT();
|
|
57
44
|
// A descriptor's label is a runtime catalog key — the typed gate cannot see
|
|
58
45
|
// it, which is why a host's catalog check is what catches a typo.
|
|
59
46
|
const translateKey = useTranslateKey();
|
|
60
|
-
const
|
|
47
|
+
const entityNoun = useEntityNoun();
|
|
61
48
|
const metaEntity = extractMetaEntity(entityConstructor);
|
|
62
49
|
const slots = readEntityTableSlots(children);
|
|
63
50
|
const [panel, setPanel] = useState('none');
|
|
64
|
-
/**
|
|
65
|
-
* A verb waiting to be confirmed, and what it will act on.
|
|
66
|
-
*
|
|
67
|
-
* ⚠️ **The table had no confirmation flow at all** until a change moved a
|
|
68
|
-
* destructive verb onto it. It read `confirm.tone` — only to pick a tone for
|
|
69
|
-
* a button or a menu item — and then fired on the first click. `unpublish` is
|
|
70
|
-
* declared `destructive`, so a verb reachable from a row menu without this
|
|
71
|
-
* would have been a one-click unpublish with a red label explaining what had
|
|
72
|
-
* already happened.
|
|
73
|
-
*
|
|
74
|
-
* The state holds the confirmation itself rather than the descriptor, so the
|
|
75
|
-
* dialog cannot open for a verb that never asked for one — the same shape
|
|
76
|
-
* `EntityForm` uses, and for the same reason.
|
|
77
|
-
*
|
|
78
|
-
* It carries the **target** too, which the form's does not need: a form has
|
|
79
|
-
* one record and a table has a row or a selection, and those run through two
|
|
80
|
-
* different handlers with two different payloads.
|
|
81
|
-
*/ const [pending, setPending] = useState(undefined);
|
|
82
51
|
const { columns, visibleColumns, hidden, setPersonalization } = useEntityTableColumns(entityConstructor, slots.columns, items[0], `entity-table:${(_ref = preferencesKey != null ? preferencesKey : metaEntity.key) != null ? _ref : metaEntity.name}`);
|
|
83
|
-
const pivot = PIVOT_CLASS[pivotBreakpoint];
|
|
84
52
|
// A picker's table is choosing *one* value; a multi-selection there would
|
|
85
53
|
// offer a set to a form member that holds a single reference, and the two
|
|
86
54
|
// controls would fight over the same row. This is a wiring mistake rather
|
|
@@ -116,28 +84,90 @@ export function EntityTable({ entityConstructor, isLoading, skeleton = true, err
|
|
|
116
84
|
total: totalItems,
|
|
117
85
|
excluded: new Set()
|
|
118
86
|
};
|
|
119
|
-
|
|
87
|
+
// Opening a record is its title's link, so a row needs an actions column
|
|
88
|
+
// only to pick it or to run a verb on it.
|
|
89
|
+
const hasRowAction = onSelect !== undefined || hasRowMenu;
|
|
120
90
|
const columnCount = visibleColumns.length + (hasRowAction ? 1 : 0) + (selectable ? 1 : 0);
|
|
121
91
|
/**
|
|
92
|
+
* The grid and the cards are both rendered, and a container query on the
|
|
93
|
+
* table's own box picks one — at the width its visible columns need. A
|
|
94
|
+
* viewport breakpoint was wrong inside a split view, a drawer or a wizard
|
|
95
|
+
* step, and a JS measurement would guess during SSR and correct after mount.
|
|
96
|
+
*/ const pivot = pivotClasses(pivotWidth(visibleColumns, (selectable ? SELECTION_WIDTH : 0) + (hasRowAction ? ACTIONS_WIDTH : 0), pivotBreakpoint));
|
|
97
|
+
/**
|
|
122
98
|
* The first load has nothing to show and is held with a skeleton; a refetch
|
|
123
99
|
* already has rows, so it keeps them and only marks the region busy. Splitting
|
|
124
100
|
* the two is what stops every pagination click flashing grey.
|
|
125
101
|
*/ const isFirstLoad = isLoading && items.length === 0;
|
|
126
|
-
const isRefetching = isLoading && items.length > 0;
|
|
127
102
|
/** `true`/omitted → the built-in default; a node → that node; `false` → none. */ const customSkeleton = typeof skeleton === 'boolean' ? undefined : skeleton;
|
|
128
103
|
const showSkeleton = isFirstLoad && skeleton !== false;
|
|
129
104
|
const skeletonRows = Array.from({
|
|
130
105
|
length: Math.min(pageSize, SKELETON_ROW_CAP)
|
|
131
106
|
}, (_, index)=>index);
|
|
132
107
|
/**
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*/ const
|
|
137
|
-
const
|
|
108
|
+
* A refetch keeps its rows at full contrast and marks them `aria-busy`:
|
|
109
|
+
* dimming them through opacity took the text under the contrast a reader
|
|
110
|
+
* needs, on every page change.
|
|
111
|
+
*/ const busy = isLoading || undefined;
|
|
112
|
+
/** The column a row reads *as*: the first non-identifier one it filled in. */ const titleColumn = (item)=>visibleColumns.find((column)=>{
|
|
113
|
+
if (column.type === 'id') return false;
|
|
114
|
+
const value = item[column.name];
|
|
115
|
+
return value != null && String(value) !== '';
|
|
116
|
+
});
|
|
117
|
+
/** The column that links to the record: one declared `card: 'title'`, else the row's title. */ const declaredTitle = visibleColumns.find((column)=>column.card === 'title');
|
|
118
|
+
const linkColumn = (item)=>declaredTitle != null ? declaredTitle : titleColumn(item);
|
|
119
|
+
/**
|
|
120
|
+
* What a record's card shows, by each member's declared `card` role or the
|
|
121
|
+
* default: an id is hidden, the first enum is the badge, and up to
|
|
122
|
+
* {@link UNDECLARED_META_CAP} more members are meta — a card is a summary,
|
|
123
|
+
* and the grid holds the rest.
|
|
124
|
+
*/ const firstEnum = visibleColumns.find((column)=>column.card === undefined && column.type === 'enum');
|
|
125
|
+
const roleOf = (column)=>{
|
|
126
|
+
var _column_card;
|
|
127
|
+
return (_column_card = column.card) != null ? _column_card : column.type === 'id' ? 'hidden' : column === firstEnum ? 'badge' : 'meta';
|
|
128
|
+
};
|
|
129
|
+
const cardParts = (item)=>{
|
|
130
|
+
const title = linkColumn(item);
|
|
131
|
+
const rest = visibleColumns.filter((column)=>column !== title);
|
|
132
|
+
let undeclared = 0;
|
|
133
|
+
return {
|
|
134
|
+
title,
|
|
135
|
+
subtitle: rest.find((column)=>roleOf(column) === 'subtitle'),
|
|
136
|
+
badges: rest.filter((column)=>roleOf(column) === 'badge'),
|
|
137
|
+
meta: rest.filter((column)=>{
|
|
138
|
+
if (roleOf(column) !== 'meta') return false;
|
|
139
|
+
if (column.card !== undefined) return true;
|
|
140
|
+
undeclared += 1;
|
|
141
|
+
return undeclared <= UNDECLARED_META_CAP;
|
|
142
|
+
})
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
const renderValue = (column, item)=>column.render ? column.render(item) : /*#__PURE__*/ _jsx(CellValue, {
|
|
138
146
|
value: item[column.name],
|
|
139
|
-
descriptor: column
|
|
147
|
+
descriptor: column,
|
|
148
|
+
record: item
|
|
149
|
+
});
|
|
150
|
+
/**
|
|
151
|
+
* A cell, and the row's title cell is the record's link
|
|
152
|
+
* ([ADR 0026](../../../../../../../docs/adr/0026-actions-hierarchy-overflow-and-destructive-verbs.md)).
|
|
153
|
+
* A column of identical "Open" links named nothing, and a reader tabbing
|
|
154
|
+
* down it heard "Open" once per row; the title says which record it opens.
|
|
155
|
+
* A picker's rows are chosen, not opened, so they stay plain.
|
|
156
|
+
*/ const renderCell = (column, item)=>{
|
|
157
|
+
var _linkColumn;
|
|
158
|
+
const value = renderValue(column, item);
|
|
159
|
+
if (hrefFor === undefined || onSelect !== undefined) return value;
|
|
160
|
+
if (((_linkColumn = linkColumn(item)) == null ? void 0 : _linkColumn.name) !== column.name) return value;
|
|
161
|
+
return renderLink({
|
|
162
|
+
href: hrefFor(item.id),
|
|
163
|
+
className: linkClassName,
|
|
164
|
+
children: value,
|
|
165
|
+
intent: {
|
|
166
|
+
kind: 'open',
|
|
167
|
+
id: item.id
|
|
168
|
+
}
|
|
140
169
|
});
|
|
170
|
+
};
|
|
141
171
|
/**
|
|
142
172
|
* The row a shift-click ranges *from* — the last box the user actually
|
|
143
173
|
* toggled. Held in a ref rather than state because it changes nothing on
|
|
@@ -219,11 +249,7 @@ export function EntityTable({ entityConstructor, isLoading, skeleton = true, err
|
|
|
219
249
|
//
|
|
220
250
|
// The id remains the last resort, because a row with nothing rendered
|
|
221
251
|
// still has to announce itself.
|
|
222
|
-
const named =
|
|
223
|
-
if (column.type === 'id') return false;
|
|
224
|
-
const value = item[column.name];
|
|
225
|
-
return value != null && String(value) !== '';
|
|
226
|
-
});
|
|
252
|
+
const named = titleColumn(item);
|
|
227
253
|
return named ? String(item[named.name]) : String(item.id);
|
|
228
254
|
};
|
|
229
255
|
const selectionCell = (item, index, // Passed in rather than closed over: this is only ever called under
|
|
@@ -244,113 +270,196 @@ export function EntityTable({ entityConstructor, isLoading, skeleton = true, err
|
|
|
244
270
|
if (target.kind === 'row') onUseCase == null ? void 0 : onUseCase(key, target.item);
|
|
245
271
|
else onBulkUseCase == null ? void 0 : onBulkUseCase(key, target.selection);
|
|
246
272
|
};
|
|
273
|
+
/**
|
|
274
|
+
* Every verb on the table goes through here — the row menu, the bulk bar and
|
|
275
|
+
* the toolbar — so none reaches a destructive verb around its confirmation,
|
|
276
|
+
* its typed check or its Undo.
|
|
277
|
+
*/ const verbs = useVerbInvoker({
|
|
278
|
+
run: runTarget,
|
|
279
|
+
busy: isBulkRunning,
|
|
280
|
+
served: metadata == null ? void 0 : metadata.useCases
|
|
281
|
+
});
|
|
247
282
|
const invoke = (useCase, target)=>{
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
target
|
|
283
|
+
if (target.kind === 'row') {
|
|
284
|
+
verbs.invoke({
|
|
285
|
+
descriptor: useCase,
|
|
286
|
+
target,
|
|
287
|
+
object: rowLabel(target.item),
|
|
288
|
+
count: 1
|
|
255
289
|
});
|
|
256
290
|
return;
|
|
257
291
|
}
|
|
258
|
-
|
|
292
|
+
const count = selectionSize(target.selection);
|
|
293
|
+
verbs.invoke({
|
|
294
|
+
descriptor: useCase,
|
|
295
|
+
target,
|
|
296
|
+
object: t('confirm.selection', {
|
|
297
|
+
count,
|
|
298
|
+
label: entityNoun(metaEntity),
|
|
299
|
+
plural: entityNoun(metaEntity, 'plural')
|
|
300
|
+
}),
|
|
301
|
+
count,
|
|
302
|
+
matching: target.selection.mode === 'matching'
|
|
303
|
+
});
|
|
259
304
|
};
|
|
260
|
-
const rowMenu = (item)=>hasRowMenu ? /*#__PURE__*/
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
return /*#__PURE__*/ _jsx(Menu.Item, {
|
|
270
|
-
tone: ((_useCase_confirm = useCase.confirm) == null ? void 0 : _useCase_confirm.tone) === 'destructive' ? 'destructive' : 'neutral',
|
|
271
|
-
onClick: ()=>invoke(useCase, {
|
|
272
|
-
kind: 'row',
|
|
273
|
-
item
|
|
274
|
-
}),
|
|
275
|
-
children: translateKey(useCase.labelKey)
|
|
276
|
-
}, useCase.key);
|
|
277
|
-
})
|
|
278
|
-
})
|
|
279
|
-
]
|
|
305
|
+
const rowMenu = (item)=>hasRowMenu ? /*#__PURE__*/ _jsx(ActionBar, {
|
|
306
|
+
surface: "row-menu",
|
|
307
|
+
menuLabel: t('actions.forRecord', {
|
|
308
|
+
record: rowLabel(item)
|
|
309
|
+
}),
|
|
310
|
+
items: itemsForUseCases(rowUseCases, translateKey, (useCase)=>invoke(useCase, {
|
|
311
|
+
kind: 'row',
|
|
312
|
+
item
|
|
313
|
+
}))
|
|
280
314
|
}) : undefined;
|
|
281
315
|
/**
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
* The row menu sits *beside* whichever of the two applies rather than
|
|
286
|
-
* replacing it — "open this record" and "run a verb on it" are both true at
|
|
287
|
-
* once, and folding the first into the menu would bury the action every row
|
|
288
|
-
* of a list exists for.
|
|
316
|
+
* A picker's Select, then the row's verbs. Opening the record is not here:
|
|
317
|
+
* it is the title's link.
|
|
289
318
|
*/ const recordAction = (item)=>{
|
|
290
|
-
const
|
|
319
|
+
const pick = onSelect ? /*#__PURE__*/ _jsx(Button, {
|
|
291
320
|
type: "button",
|
|
292
321
|
variant: "secondary",
|
|
293
322
|
size: "sm",
|
|
294
323
|
onClick: ()=>onSelect(item),
|
|
295
324
|
children: t('table.select')
|
|
296
|
-
}) : hrefFor ? renderLink({
|
|
297
|
-
href: hrefFor(item.id),
|
|
298
|
-
className: linkClassName,
|
|
299
|
-
children: t('table.open'),
|
|
300
|
-
intent: {
|
|
301
|
-
kind: 'open',
|
|
302
|
-
id: item.id
|
|
303
|
-
}
|
|
304
325
|
}) : undefined;
|
|
305
326
|
const menu = rowMenu(item);
|
|
306
|
-
if (!menu) return
|
|
327
|
+
if (!menu) return pick;
|
|
307
328
|
return /*#__PURE__*/ _jsxs("span", {
|
|
308
329
|
className: "flex items-center gap-2xs",
|
|
309
330
|
children: [
|
|
310
|
-
|
|
331
|
+
pick,
|
|
311
332
|
menu
|
|
312
333
|
]
|
|
313
334
|
});
|
|
314
335
|
};
|
|
315
336
|
/**
|
|
316
|
-
* "
|
|
317
|
-
*
|
|
318
|
-
*
|
|
319
|
-
|
|
337
|
+
* "New" is the list's primary, and only where something can be created
|
|
338
|
+
* here: the entity is not one only a flow writes (`creatable: false`), and
|
|
339
|
+
* the caller may write it. A list that offered "New" to a reader who could
|
|
340
|
+
* never save opened a form with no Save on it.
|
|
341
|
+
*/ const mayCreate = newHref !== undefined && metaEntity.creatable && (metadata === undefined || metadata.actions.includes('write'));
|
|
342
|
+
const toolbarItems = itemsForUseCases(toolbarUseCases, translateKey, (useCase)=>invoke(useCase, {
|
|
343
|
+
kind: 'selection',
|
|
344
|
+
selection: everythingMatching
|
|
345
|
+
}), isBulkRunning);
|
|
346
|
+
const declaresToolbarPrimary = toolbarItems.some((item)=>item.emphasis === 'primary');
|
|
347
|
+
const toolbarActions = [
|
|
348
|
+
...mayCreate ? [
|
|
349
|
+
{
|
|
350
|
+
key: 'new',
|
|
351
|
+
label: t('table.new'),
|
|
352
|
+
emphasis: declaresToolbarPrimary ? 'default' : 'primary',
|
|
353
|
+
href: newHref,
|
|
354
|
+
intent: {
|
|
355
|
+
kind: 'new'
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
] : [],
|
|
359
|
+
...toolbarItems
|
|
360
|
+
];
|
|
361
|
+
const locale = useLocale();
|
|
362
|
+
const panelId = useId();
|
|
363
|
+
const keys = sortKeys(sorting, columns);
|
|
364
|
+
const activeFilters = (_ref1 = filtering == null ? void 0 : filtering.values.length) != null ? _ref1 : 0;
|
|
365
|
+
const results = t('table.results', {
|
|
366
|
+
count: totalItems
|
|
367
|
+
});
|
|
368
|
+
/**
|
|
369
|
+
* What the status region says once a filter, a sort or a page has settled —
|
|
370
|
+
* debounced, and silent on the first load.
|
|
371
|
+
*/ const announcement = useResultAnnouncement(!isLoading, totalItems === 0 && activeFilters > 0 ? t('table.noResultsFiltered') : results, JSON.stringify([
|
|
372
|
+
filtering,
|
|
373
|
+
sorting,
|
|
374
|
+
currentPage,
|
|
375
|
+
pageSize
|
|
376
|
+
]));
|
|
377
|
+
/** The caption: what the table holds, how many, and in what order. */ const primaryKey = keys[0];
|
|
378
|
+
const primaryColumn = primaryKey === undefined ? undefined : columns.find((column)=>column.name === primaryKey.member);
|
|
379
|
+
const caption = primaryKey === undefined || primaryColumn === undefined ? t('table.caption', {
|
|
380
|
+
entity: entityNoun(metaEntity, 'plural'),
|
|
381
|
+
results
|
|
382
|
+
}) : t('table.captionSorted', {
|
|
383
|
+
entity: entityNoun(metaEntity, 'plural'),
|
|
384
|
+
results,
|
|
385
|
+
column: primaryColumn.label,
|
|
386
|
+
direction: t(primaryKey.type === 'asc' ? 'sort.ascending' : 'sort.descending')
|
|
387
|
+
});
|
|
388
|
+
/**
|
|
389
|
+
* A column's header: its name, and — for a sortable one — a button that
|
|
390
|
+
* cycles it ascending → descending → unsorted, with Shift adding it as the
|
|
391
|
+
* next key. Only the primary key carries `aria-sort`.
|
|
392
|
+
*/ const headerCell = (column)=>{
|
|
393
|
+
var _column_header;
|
|
394
|
+
var _keys_position;
|
|
395
|
+
const label = (_column_header = column.header) != null ? _column_header : column.label;
|
|
396
|
+
if (!column.sortable || onSortingChange === undefined) return /*#__PURE__*/ _jsx(TableHeaderCell, {
|
|
397
|
+
children: label
|
|
398
|
+
}, column.name);
|
|
399
|
+
const position = keys.findIndex((key)=>key.member === column.name);
|
|
400
|
+
const type = (_keys_position = keys[position]) == null ? void 0 : _keys_position.type;
|
|
401
|
+
return /*#__PURE__*/ _jsx(TableHeaderCell, {
|
|
402
|
+
"aria-sort": position === 0 ? type === 'asc' ? 'ascending' : 'descending' : undefined,
|
|
403
|
+
children: /*#__PURE__*/ _jsxs("button", {
|
|
404
|
+
type: "button",
|
|
405
|
+
className: "inline-flex min-h-(--target-min) items-center gap-3xs rounded-sm focus-ring hover:text-content",
|
|
406
|
+
onClick: (event)=>onSortingChange(nextHeaderSorting(keys, {
|
|
407
|
+
member: column.name,
|
|
408
|
+
property: queryPropertyFor(column, locale)
|
|
409
|
+
}, event.shiftKey)),
|
|
410
|
+
children: [
|
|
411
|
+
label,
|
|
412
|
+
/*#__PURE__*/ _jsx("span", {
|
|
413
|
+
"aria-hidden": "true",
|
|
414
|
+
children: type === 'asc' ? '▲' : type === 'desc' ? '▼' : '↕'
|
|
415
|
+
}),
|
|
416
|
+
keys.length > 1 && position >= 0 && /*#__PURE__*/ _jsx("span", {
|
|
417
|
+
"aria-hidden": "true",
|
|
418
|
+
className: "text-step-sm",
|
|
419
|
+
children: position + 1
|
|
420
|
+
})
|
|
421
|
+
]
|
|
422
|
+
})
|
|
423
|
+
}, column.name);
|
|
424
|
+
};
|
|
425
|
+
/** A panel toggle: its state said by `aria-expanded`, and its count shown. */ const panelToggle = (which, count)=>/*#__PURE__*/ _jsxs(Button, {
|
|
426
|
+
type: "button",
|
|
427
|
+
variant: panel === which ? 'primary' : 'secondary',
|
|
428
|
+
size: "sm",
|
|
429
|
+
"aria-expanded": panel === which,
|
|
430
|
+
"aria-controls": panelId,
|
|
431
|
+
onClick: ()=>setPanel((current)=>current === which ? 'none' : which),
|
|
432
|
+
children: [
|
|
433
|
+
t(which === 'filters' ? 'table.filters' : 'table.sorting'),
|
|
434
|
+
count > 0 && // Its name stays "Filters": the chips say which filters, and a count
|
|
435
|
+
// in the name would change it under the reader with every filter.
|
|
436
|
+
/*#__PURE__*/ _jsx("span", {
|
|
437
|
+
"aria-hidden": "true",
|
|
438
|
+
className: "ms-3xs rounded-full bg-surface px-3xs text-step-sm text-content",
|
|
439
|
+
children: count
|
|
440
|
+
})
|
|
441
|
+
]
|
|
442
|
+
});
|
|
320
443
|
return /*#__PURE__*/ _jsxs("div", {
|
|
321
|
-
className: "flex flex-col gap-s",
|
|
444
|
+
className: "@container/entity-table flex flex-col gap-s",
|
|
322
445
|
children: [
|
|
323
446
|
/*#__PURE__*/ _jsx("span", {
|
|
324
447
|
role: "status",
|
|
325
448
|
"aria-live": "polite",
|
|
326
449
|
className: "sr-only",
|
|
327
|
-
children: isFirstLoad ? t('table.loading') :
|
|
450
|
+
children: isFirstLoad ? t('table.loading') : announcement
|
|
328
451
|
}),
|
|
329
452
|
showControls && /*#__PURE__*/ _jsx(TableToolbar, {
|
|
330
453
|
start: /*#__PURE__*/ _jsxs(_Fragment, {
|
|
331
454
|
children: [
|
|
332
|
-
newHref && renderLink({
|
|
333
|
-
href: newHref,
|
|
334
|
-
className: linkClassName,
|
|
335
|
-
children: t('table.new'),
|
|
336
|
-
intent: {
|
|
337
|
-
kind: 'new'
|
|
338
|
-
}
|
|
339
|
-
}),
|
|
340
455
|
/*#__PURE__*/ _jsx(LoadingBoundary, {
|
|
341
456
|
isLoading: isMetadataLoading,
|
|
342
457
|
lines: 0,
|
|
343
458
|
children: /*#__PURE__*/ _jsx(_Fragment, {
|
|
344
|
-
children:
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
variant: ((_useCase_confirm = useCase.confirm) == null ? void 0 : _useCase_confirm.tone) === 'destructive' ? 'destructive' : 'secondary',
|
|
349
|
-
size: "sm",
|
|
350
|
-
disabled: isBulkRunning,
|
|
351
|
-
onClick: ()=>onBulkUseCase == null ? void 0 : onBulkUseCase(useCase.key, everythingMatching),
|
|
352
|
-
children: translateKey(useCase.labelKey)
|
|
353
|
-
}, useCase.key);
|
|
459
|
+
children: toolbarActions.length > 0 && /*#__PURE__*/ _jsx(ActionBar, {
|
|
460
|
+
surface: "table-toolbar",
|
|
461
|
+
items: toolbarActions,
|
|
462
|
+
renderLink: renderLink
|
|
354
463
|
})
|
|
355
464
|
})
|
|
356
465
|
}),
|
|
@@ -359,20 +468,8 @@ export function EntityTable({ entityConstructor, isLoading, skeleton = true, err
|
|
|
359
468
|
}),
|
|
360
469
|
end: /*#__PURE__*/ _jsxs(_Fragment, {
|
|
361
470
|
children: [
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
variant: panel === 'filters' ? 'primary' : 'secondary',
|
|
365
|
-
size: "sm",
|
|
366
|
-
onClick: ()=>setPanel((current)=>current === 'filters' ? 'none' : 'filters'),
|
|
367
|
-
children: t('table.filters')
|
|
368
|
-
}),
|
|
369
|
-
/*#__PURE__*/ _jsx(Button, {
|
|
370
|
-
type: "button",
|
|
371
|
-
variant: panel === 'sorting' ? 'primary' : 'secondary',
|
|
372
|
-
size: "sm",
|
|
373
|
-
onClick: ()=>setPanel((current)=>current === 'sorting' ? 'none' : 'sorting'),
|
|
374
|
-
children: t('table.sorting')
|
|
375
|
-
}),
|
|
471
|
+
panelToggle('filters', activeFilters),
|
|
472
|
+
panelToggle('sorting', keys.length),
|
|
376
473
|
/*#__PURE__*/ _jsx(ColumnSettings, {
|
|
377
474
|
columns: columns,
|
|
378
475
|
hidden: hidden,
|
|
@@ -380,16 +477,23 @@ export function EntityTable({ entityConstructor, isLoading, skeleton = true, err
|
|
|
380
477
|
})
|
|
381
478
|
]
|
|
382
479
|
}),
|
|
480
|
+
panelId: panelId,
|
|
383
481
|
panel: panel === 'filters' ? /*#__PURE__*/ _jsx(FilterBuilder, {
|
|
384
482
|
descriptors: columns.filter((column)=>column.filterable),
|
|
483
|
+
facets: facets,
|
|
385
484
|
value: filtering,
|
|
386
485
|
onChange: (applied)=>onFilteringChange == null ? void 0 : onFilteringChange(applied)
|
|
387
|
-
}) : panel === 'sorting' ? /*#__PURE__*/ _jsx(SortBuilder, {
|
|
486
|
+
}, JSON.stringify(filtering != null ? filtering : null)) : panel === 'sorting' ? /*#__PURE__*/ _jsx(SortBuilder, {
|
|
388
487
|
descriptors: columns.filter((column)=>column.sortable),
|
|
389
488
|
value: sorting,
|
|
390
489
|
onChange: (applied)=>onSortingChange == null ? void 0 : onSortingChange(applied)
|
|
391
490
|
}) : undefined
|
|
392
491
|
}),
|
|
492
|
+
showControls && onFilteringChange !== undefined && /*#__PURE__*/ _jsx(FilterChips, {
|
|
493
|
+
descriptors: columns.filter((column)=>column.filterable),
|
|
494
|
+
value: filtering,
|
|
495
|
+
onChange: onFilteringChange
|
|
496
|
+
}),
|
|
393
497
|
selectionState && selectionSize(selectionState) > 0 && /*#__PURE__*/ _jsx(BulkActionBar, {
|
|
394
498
|
count: selectionSize(selectionState),
|
|
395
499
|
useCases: bulkUseCases,
|
|
@@ -404,19 +508,7 @@ export function EntityTable({ entityConstructor, isLoading, skeleton = true, err
|
|
|
404
508
|
selection: selectionState
|
|
405
509
|
})
|
|
406
510
|
}),
|
|
407
|
-
|
|
408
|
-
open: true,
|
|
409
|
-
tone: pending.confirm.tone,
|
|
410
|
-
title: translateKey(pending.labelKey),
|
|
411
|
-
message: translateKey(pending.confirm.messageKey),
|
|
412
|
-
busy: isBulkRunning,
|
|
413
|
-
onCancel: ()=>setPending(undefined),
|
|
414
|
-
onConfirm: ()=>{
|
|
415
|
-
const { key, target } = pending;
|
|
416
|
-
setPending(undefined);
|
|
417
|
-
runTarget(key, target);
|
|
418
|
-
}
|
|
419
|
-
}),
|
|
511
|
+
verbs.dialog,
|
|
420
512
|
bulkOutcomes && bulkOutcomes.length > 0 && onBulkDismiss && /*#__PURE__*/ _jsx(BulkResult, {
|
|
421
513
|
outcomes: bulkOutcomes,
|
|
422
514
|
busy: isBulkRunning,
|
|
@@ -427,15 +519,37 @@ export function EntityTable({ entityConstructor, isLoading, skeleton = true, err
|
|
|
427
519
|
onRetryFailed: onBulkRetry,
|
|
428
520
|
onDismiss: onBulkDismiss
|
|
429
521
|
}),
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
522
|
+
/*#__PURE__*/ _jsx(RegionState, {
|
|
523
|
+
plural: entityNoun(metaEntity, 'plural'),
|
|
524
|
+
isLoading: isLoading,
|
|
525
|
+
error: error,
|
|
526
|
+
onRetry: onRetry,
|
|
527
|
+
hasStaleData: items.length > 0,
|
|
528
|
+
isEmpty: items.length === 0,
|
|
529
|
+
isFiltered: activeFilters > 0,
|
|
530
|
+
onClearFilters: onFilteringChange === undefined ? undefined : ()=>onFilteringChange({
|
|
531
|
+
// Only offered under a filter, so there is one to keep the
|
|
532
|
+
// logic of.
|
|
533
|
+
operator: filtering.operator,
|
|
534
|
+
values: []
|
|
535
|
+
}),
|
|
536
|
+
emptyAction: mayCreate ? renderLink({
|
|
537
|
+
href: newHref,
|
|
538
|
+
className: button({
|
|
539
|
+
variant: 'primary'
|
|
540
|
+
}),
|
|
541
|
+
children: t('table.new'),
|
|
542
|
+
intent: {
|
|
543
|
+
kind: 'new'
|
|
544
|
+
}
|
|
545
|
+
}) : undefined
|
|
435
546
|
}),
|
|
436
547
|
/*#__PURE__*/ _jsx("div", {
|
|
437
|
-
className:
|
|
548
|
+
className: pivot.grid,
|
|
549
|
+
"aria-busy": busy,
|
|
438
550
|
children: /*#__PURE__*/ _jsxs(Table, {
|
|
551
|
+
caption: caption,
|
|
552
|
+
containerClassName: "max-h-(--table-max-block) scroll-pt-12",
|
|
439
553
|
children: [
|
|
440
554
|
/*#__PURE__*/ _jsx(TableHead, {
|
|
441
555
|
children: slots.header ? slots.header.render(visibleColumns) : /*#__PURE__*/ _jsxs("tr", {
|
|
@@ -449,12 +563,7 @@ export function EntityTable({ entityConstructor, isLoading, skeleton = true, err
|
|
|
449
563
|
onChange: (event)=>toggleAllOnPage(event.currentTarget.checked, selectionState)
|
|
450
564
|
})
|
|
451
565
|
}),
|
|
452
|
-
visibleColumns.map(
|
|
453
|
-
var _column_header;
|
|
454
|
-
return /*#__PURE__*/ _jsx(TableHeaderCell, {
|
|
455
|
-
children: (_column_header = column.header) != null ? _column_header : column.label
|
|
456
|
-
}, column.name);
|
|
457
|
-
}),
|
|
566
|
+
visibleColumns.map(headerCell),
|
|
458
567
|
hasRowAction && /*#__PURE__*/ _jsx(TableHeaderCell, {
|
|
459
568
|
children: t('table.actions')
|
|
460
569
|
})
|
|
@@ -462,7 +571,6 @@ export function EntityTable({ entityConstructor, isLoading, skeleton = true, err
|
|
|
462
571
|
})
|
|
463
572
|
}),
|
|
464
573
|
/*#__PURE__*/ _jsxs(TableBody, {
|
|
465
|
-
"aria-busy": isLoading || undefined,
|
|
466
574
|
children: [
|
|
467
575
|
showSkeleton && (customSkeleton ? /*#__PURE__*/ _jsx(TableMessageRow, {
|
|
468
576
|
colSpan: columnCount,
|
|
@@ -489,10 +597,6 @@ export function EntityTable({ entityConstructor, isLoading, skeleton = true, err
|
|
|
489
597
|
})
|
|
490
598
|
]
|
|
491
599
|
}, row))),
|
|
492
|
-
!isLoading && items.length === 0 && /*#__PURE__*/ _jsx(TableMessageRow, {
|
|
493
|
-
colSpan: columnCount,
|
|
494
|
-
children: emptyMessage
|
|
495
|
-
}),
|
|
496
600
|
shown.map(({ item, depth, hasChildren }, index)=>{
|
|
497
601
|
var _item_id, _item_id1;
|
|
498
602
|
return slots.row ? // A Fragment carries the key without wrapping the custom row in
|
|
@@ -528,30 +632,62 @@ export function EntityTable({ entityConstructor, isLoading, skeleton = true, err
|
|
|
528
632
|
})
|
|
529
633
|
}),
|
|
530
634
|
/*#__PURE__*/ _jsxs("div", {
|
|
531
|
-
className:
|
|
532
|
-
"aria-busy":
|
|
635
|
+
className: pivot.cards,
|
|
636
|
+
"aria-busy": busy,
|
|
533
637
|
children: [
|
|
534
|
-
showSkeleton && (customSkeleton != null ? customSkeleton :
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
638
|
+
showSkeleton && (customSkeleton != null ? customSkeleton : /*#__PURE__*/ _jsx("ul", {
|
|
639
|
+
role: "list",
|
|
640
|
+
className: "m-0 p-0 flex list-none flex-col gap-2xs",
|
|
641
|
+
children: skeletonRows.map((row)=>/*#__PURE__*/ _jsx("li", {
|
|
642
|
+
children: /*#__PURE__*/ _jsx(EntityRecordCard, {
|
|
643
|
+
title: /*#__PURE__*/ _jsx(Skeleton, {
|
|
644
|
+
shape: "line",
|
|
645
|
+
className: "w-32"
|
|
646
|
+
}),
|
|
647
|
+
meta: visibleColumns.slice(1).map((column)=>({
|
|
648
|
+
key: column.name,
|
|
649
|
+
label: column.label,
|
|
650
|
+
value: /*#__PURE__*/ _jsx(Skeleton, {
|
|
651
|
+
shape: "line",
|
|
652
|
+
className: "w-24"
|
|
653
|
+
})
|
|
654
|
+
}))
|
|
539
655
|
})
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
656
|
+
}, row))
|
|
657
|
+
})),
|
|
658
|
+
shown.length > 0 && /*#__PURE__*/ _jsx("ul", {
|
|
659
|
+
role: "list",
|
|
660
|
+
className: "m-0 p-0 flex list-none flex-col gap-2xs",
|
|
661
|
+
children: shown.map(({ item, depth }, index)=>{
|
|
662
|
+
var _item_id;
|
|
663
|
+
const parts = cardParts(item);
|
|
664
|
+
return /*#__PURE__*/ _jsx("li", {
|
|
665
|
+
// A tree's card says how deep it sits, as its row does.
|
|
666
|
+
"aria-level": treeKeys === undefined ? undefined : depth + 1,
|
|
667
|
+
style: treeKeys === undefined ? undefined : {
|
|
668
|
+
marginInlineStart: `${depth * 1.5}rem`
|
|
669
|
+
},
|
|
670
|
+
children: /*#__PURE__*/ _jsx(EntityRecordCard, {
|
|
671
|
+
// The same renderers as the grid, so the two layouts agree.
|
|
672
|
+
title: parts.title === undefined ? rowLabel(item) : renderCell(parts.title, item),
|
|
673
|
+
subtitle: parts.subtitle === undefined ? undefined : renderCell(parts.subtitle, item),
|
|
674
|
+
badges: parts.badges.map((column)=>({
|
|
675
|
+
key: column.name,
|
|
676
|
+
value: renderCell(column, item)
|
|
677
|
+
})),
|
|
678
|
+
meta: parts.meta.map((column)=>{
|
|
679
|
+
var _column_header;
|
|
680
|
+
return {
|
|
681
|
+
key: column.name,
|
|
682
|
+
label: (_column_header = column.header) != null ? _column_header : column.label,
|
|
683
|
+
value: renderCell(column, item)
|
|
684
|
+
};
|
|
685
|
+
}),
|
|
686
|
+
leading: selectionState ? selectionCell(item, index, selectionState) : undefined,
|
|
687
|
+
actions: recordAction(item)
|
|
688
|
+
})
|
|
689
|
+
}, String((_item_id = item.id) != null ? _item_id : index));
|
|
690
|
+
})
|
|
555
691
|
})
|
|
556
692
|
]
|
|
557
693
|
}),
|