pne-ui 4.4.0 → 4.5.0-rc.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 (38) hide show
  1. package/README.md +65 -0
  2. package/cjs/component/table/column-settings/PneTableColumnSettingsAction.d.ts +25 -0
  3. package/cjs/component/table/column-settings/PneTableColumnSettingsAction.js +38 -0
  4. package/cjs/component/table/column-settings/PneTableColumnSettingsAction.js.map +1 -0
  5. package/cjs/component/table/column-settings/PneTableColumnSettingsDialog.d.ts +48 -0
  6. package/cjs/component/table/column-settings/PneTableColumnSettingsDialog.js +213 -0
  7. package/cjs/component/table/column-settings/PneTableColumnSettingsDialog.js.map +1 -0
  8. package/cjs/component/table/column-settings/resolveColumnSettings.d.ts +22 -0
  9. package/cjs/component/table/column-settings/resolveColumnSettings.js +84 -0
  10. package/cjs/component/table/column-settings/resolveColumnSettings.js.map +1 -0
  11. package/cjs/component/table/column-settings/types.d.ts +37 -0
  12. package/cjs/component/table/column-settings/types.js +3 -0
  13. package/cjs/component/table/column-settings/types.js.map +1 -0
  14. package/cjs/component/table/column-settings/usePneTableColumnSettings.d.ts +34 -0
  15. package/cjs/component/table/column-settings/usePneTableColumnSettings.js +37 -0
  16. package/cjs/component/table/column-settings/usePneTableColumnSettings.js.map +1 -0
  17. package/cjs/exports/table.d.ts +8 -0
  18. package/cjs/exports/table.js +11 -1
  19. package/cjs/exports/table.js.map +1 -1
  20. package/esm/component/table/column-settings/PneTableColumnSettingsAction.d.ts +25 -0
  21. package/esm/component/table/column-settings/PneTableColumnSettingsAction.js +34 -0
  22. package/esm/component/table/column-settings/PneTableColumnSettingsAction.js.map +1 -0
  23. package/esm/component/table/column-settings/PneTableColumnSettingsDialog.d.ts +48 -0
  24. package/esm/component/table/column-settings/PneTableColumnSettingsDialog.js +209 -0
  25. package/esm/component/table/column-settings/PneTableColumnSettingsDialog.js.map +1 -0
  26. package/esm/component/table/column-settings/resolveColumnSettings.d.ts +22 -0
  27. package/esm/component/table/column-settings/resolveColumnSettings.js +77 -0
  28. package/esm/component/table/column-settings/resolveColumnSettings.js.map +1 -0
  29. package/esm/component/table/column-settings/types.d.ts +37 -0
  30. package/esm/component/table/column-settings/types.js +2 -0
  31. package/esm/component/table/column-settings/types.js.map +1 -0
  32. package/esm/component/table/column-settings/usePneTableColumnSettings.d.ts +34 -0
  33. package/esm/component/table/column-settings/usePneTableColumnSettings.js +35 -0
  34. package/esm/component/table/column-settings/usePneTableColumnSettings.js.map +1 -0
  35. package/esm/exports/table.d.ts +8 -0
  36. package/esm/exports/table.js +4 -0
  37. package/esm/exports/table.js.map +1 -1
  38. package/package.json +1 -1
package/README.md CHANGED
@@ -690,6 +690,66 @@ remount. В controlled-режиме lifetime принадлежит consumer: е
690
690
  экрана, consumer сам должен очистить его при navigation/remount. Строковое представление applied scope остаётся
691
691
  в памяти библиотеки и не выводится в DOM/storage.
692
692
 
693
+ #### Настройка колонок
694
+
695
+ Пользовательский состав колонок для одного view таблицы. Библиотека не знает, где хранится настройка:
696
+ consumer передаёт загруженное значение и колбэк сохранения, а получает упорядоченный список видимых колонок.
697
+
698
+ - Каталог — массив `PneTableColumnOption` (`id`, текстовый `label`, `defaultVisible`) в порядке по умолчанию.
699
+ `id` стабилен и не зависит от языка и позиции; поля consumer-типа (например, `render`) сохраняются
700
+ в `visibleColumns`.
701
+ - Значение `PneTableColumnSettingsValue` — `visibleColumnIds` в порядке отображения и `hiddenColumnIds`.
702
+ Колонки каталога, отсутствующие в обоих списках, считаются новыми и показываются; неизвестные `id`
703
+ отбрасываются; значение без видимых колонок заменяется умолчанием.
704
+ - `usePneTableColumnSettings({columns, value, onSave})` сверяет значение с каталогом и владеет состоянием
705
+ окна. Для нескольких view создавайте по одному хуку на view.
706
+ - `PneTableColumnSettingsAction` — кнопка вызова (`variant='icon'` для слота `actions` селектора view,
707
+ `variant='button'` для широкой панели). `PneTableColumnSettingsDialog` — модальное окно: поиск, один
708
+ чеклист по каталогу, «Reset to default», «Cancel», «Save». Последняя видимая колонка не снимается.
709
+ - Видимые колонки переставляются перетаскиванием за отдельную ручку (мышь, клавиатура: Space, стрелки,
710
+ Space; тач без задержки). Ручки показываются только у видимых колонок и только без активного поиска;
711
+ `reorderable={false}` отключает перестановку. Скрытые колонки идут в конце списка без ручек.
712
+ - `onSave` получает нормализованное значение. Окно закрывается после resolve; при reject остаётся открытым
713
+ с черновиком, сообщение об ошибке показывает consumer.
714
+ - Служебные колонки (выбор строки, действия) в каталог не входят: рендерьте их рядом с `visibleColumns`.
715
+
716
+ ```tsx
717
+ const columns = [
718
+ {id: 'id', label: 'ID'},
719
+ {id: 'name', label: 'Name'},
720
+ {id: 'email', label: 'Email', defaultVisible: false},
721
+ ] as const satisfies readonly PneTableColumnOption[]
722
+
723
+ const settings = usePneTableColumnSettings({
724
+ columns,
725
+ value: storedValue, // PneTableColumnSettingsValue | undefined
726
+ onSave: value => api.save(value),
727
+ })
728
+
729
+ <PneTable<Row>
730
+ autoTestId="items"
731
+ data={rows}
732
+ toolbar={<PneTableToolbar
733
+ aria-label="Items table controls"
734
+ persistent={<PneTableColumnSettingsAction autoTestId="items" onClick={settings.openDialog}/>}
735
+ />}
736
+ createTableHeader={() => <PneTableRow>
737
+ {settings.visibleColumns.map(column => (
738
+ <PneHeaderTableCell key={column.id}>{column.label}</PneHeaderTableCell>
739
+ ))}
740
+ </PneTableRow>}
741
+ createRow={row => <PneTableRow key={row.id}>
742
+ {settings.visibleColumns.map(column => (
743
+ <PneTableCell key={column.id}>{row[column.id]}</PneTableCell>
744
+ ))}
745
+ </PneTableRow>}
746
+ />
747
+ <PneTableColumnSettingsDialog {...settings.dialogProps} autoTestId="items"/>
748
+ ```
749
+
750
+ Ключи локализации задаются в библиотеке с английским `defaultValue`: `pneTable.columnSettings.action`,
751
+ `.title`, `.search`, `.reset`, `.cancel`, `.save`, `.noMatches`, `.lastVisible`, `.reorder` (с `{{name}}`).
752
+
693
753
  ### SearchUI и SearchUIFilters
694
754
 
695
755
  Передавайте стабильный несекретный `autoTestId` как Selenium scope поискового интерфейса. Если prop не задан,
@@ -869,6 +929,11 @@ assertEquals("true", enabled.getAttribute("aria-pressed"));
869
929
  | Пустой результат | `[data-autotest="empty-state"]` | Наличие существующей empty row |
870
930
  | Загрузка | Semantic `table` | `aria-busy="true|false"` |
871
931
  | Активная сортировка | `th[aria-sort="ascending"], th[aria-sort="descending"]` | Значение `aria-sort` |
932
+ | Кнопка настройки колонок | `[data-autotest="column-settings"][data-autotest-value="<scope>"]` | Native button `disabled`; `<scope>` задаёт consumer через `autoTestId` |
933
+ | Окно настройки колонок | `[data-autotest="column-settings-dialog"][data-autotest-value="<scope>"]` | Существование `role="dialog"`; внутри `column-settings-search`, `column-settings-reset`, `column-settings-cancel`, `column-settings-save` |
934
+ | Колонка в окне настройки | `input[data-autotest="column-settings-option"][data-autotest-value="<columnId>"]` | Native `checked`, `disabled`; порядок в DOM = порядок отображения, скрытые в конце |
935
+ | Ручка перестановки колонки | `button[data-autotest="column-settings-reorder"][data-autotest-value="<columnId>"]` | Есть только у видимых колонок без активного поиска; keyboard: Space, ArrowUp/ArrowDown, Space |
936
+ | Пустой поиск по колонкам | `[data-autotest="column-settings-empty"]` | Наличие строки |
872
937
 
873
938
  Внутри каждого `pagination/top|bottom` уже существуют:
874
939
 
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import { SxProps, Theme } from '@mui/material';
3
+ export declare const COLUMN_SETTINGS_ACTION_AUTOTEST_ID = "column-settings";
4
+ export type PneTableColumnSettingsActionProps = {
5
+ /** Opens the column settings dialog. */
6
+ onClick: React.MouseEventHandler<HTMLButtonElement>;
7
+ /**
8
+ * `icon` renders a 40px icon button with a tooltip and fits the
9
+ * `PneTableViewSelector` actions slot. `button` renders an outlined text
10
+ * button with the icon for wide layouts. Defaults to `icon`.
11
+ */
12
+ variant?: 'icon' | 'button';
13
+ /** Accessible name and visible text; defaults to the localized "Table settings". */
14
+ label?: string;
15
+ disabled?: boolean;
16
+ /** Stable, non-secret instance identifier used to scope Selenium locators. */
17
+ autoTestId?: string;
18
+ sx?: SxProps<Theme>;
19
+ };
20
+ /**
21
+ * Entry point to the column settings dialog. Place it in the table toolbar or
22
+ * in the view selector `actions` slot next to the view it configures.
23
+ */
24
+ declare const PneTableColumnSettingsAction: React.ForwardRefExoticComponent<PneTableColumnSettingsActionProps & React.RefAttributes<HTMLButtonElement>>;
25
+ export default PneTableColumnSettingsAction;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.COLUMN_SETTINGS_ACTION_AUTOTEST_ID = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const react_1 = tslib_1.__importStar(require("react"));
6
+ const SettingsOutlined_1 = tslib_1.__importDefault(require("@mui/icons-material/SettingsOutlined"));
7
+ const material_1 = require("@mui/material");
8
+ const react_i18next_1 = require("react-i18next");
9
+ const PneButton_1 = tslib_1.__importDefault(require("../../PneButton"));
10
+ const AutoTestAttribute_1 = require("../../AutoTestAttribute");
11
+ exports.COLUMN_SETTINGS_ACTION_AUTOTEST_ID = 'column-settings';
12
+ const iconButtonSx = {
13
+ borderRadius: '4px',
14
+ height: '40px',
15
+ padding: '8px',
16
+ width: '40px',
17
+ };
18
+ /**
19
+ * Entry point to the column settings dialog. Place it in the table toolbar or
20
+ * in the view selector `actions` slot next to the view it configures.
21
+ */
22
+ const PneTableColumnSettingsAction = (0, react_1.forwardRef)(function PneTableColumnSettingsAction(props, ref) {
23
+ const { autoTestId, disabled = false, label, onClick, sx, variant = 'icon', } = props;
24
+ const { t } = (0, react_i18next_1.useTranslation)();
25
+ const resolvedLabel = label ?? t('pneTable.columnSettings.action', { defaultValue: 'Table settings' });
26
+ if (variant === 'button') {
27
+ return react_1.default.createElement(PneButton_1.default, { ...(0, AutoTestAttribute_1.createAutoTestAttributes)(exports.COLUMN_SETTINGS_ACTION_AUTOTEST_ID, autoTestId), disabled: disabled, onClick: onClick, pneStyle: 'outlined', ref: ref, startIcon: react_1.default.createElement(SettingsOutlined_1.default, null), sx: sx }, resolvedLabel);
28
+ }
29
+ return react_1.default.createElement(material_1.Tooltip, { enterDelay: 300, enterNextDelay: 300, title: resolvedLabel },
30
+ react_1.default.createElement("span", null,
31
+ react_1.default.createElement(material_1.IconButton, { ...(0, AutoTestAttribute_1.createAutoTestAttributes)(exports.COLUMN_SETTINGS_ACTION_AUTOTEST_ID, autoTestId), "aria-label": resolvedLabel, disabled: disabled, onClick: onClick, ref: ref, size: 'small', sx: [
32
+ iconButtonSx,
33
+ ...(Array.isArray(sx) ? sx : [sx]),
34
+ ] },
35
+ react_1.default.createElement(SettingsOutlined_1.default, { sx: { height: '16px', width: '16px' } }))));
36
+ });
37
+ exports.default = PneTableColumnSettingsAction;
38
+ //# sourceMappingURL=PneTableColumnSettingsAction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PneTableColumnSettingsAction.js","sourceRoot":"","sources":["../../../../src/component/table/column-settings/PneTableColumnSettingsAction.tsx"],"names":[],"mappings":";;;;AAAA,uDAAuC;AACvC,oGAAuE;AACvE,4CAAiE;AACjE,iDAA4C;AAC5C,wEAAuC;AACvC,+DAAgE;AAEnD,QAAA,kCAAkC,GAAG,iBAAiB,CAAA;AAmBnE,MAAM,YAAY,GAAmB;IACjC,YAAY,EAAE,KAAK;IACnB,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,KAAK;IACd,KAAK,EAAE,MAAM;CAChB,CAAA;AAED;;;GAGG;AACH,MAAM,4BAA4B,GAAG,IAAA,kBAAU,EAC3C,SAAS,4BAA4B,CAAC,KAAK,EAAE,GAAG;IAC5C,MAAM,EACF,UAAU,EACV,QAAQ,GAAG,KAAK,EAChB,KAAK,EACL,OAAO,EACP,EAAE,EACF,OAAO,GAAG,MAAM,GACnB,GAAG,KAAK,CAAA;IACT,MAAM,EAAC,CAAC,EAAC,GAAG,IAAA,8BAAc,GAAE,CAAA;IAC5B,MAAM,aAAa,GAAG,KAAK,IAAI,CAAC,CAAC,gCAAgC,EAAE,EAAC,YAAY,EAAE,gBAAgB,EAAC,CAAC,CAAA;IAEpG,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACvB,OAAO,8BAAC,mBAAS,OACT,IAAA,4CAAwB,EAAC,0CAAkC,EAAE,UAAU,CAAC,EAC5E,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAC,UAAU,EACnB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,8BAAC,0BAAoB,OAAE,EAClC,EAAE,EAAE,EAAE,IAEL,aAAa,CACN,CAAA;IAChB,CAAC;IAED,OAAO,8BAAC,kBAAO,IACX,UAAU,EAAE,GAAG,EACf,cAAc,EAAE,GAAG,EACnB,KAAK,EAAE,aAAa;QAEpB;YACI,8BAAC,qBAAU,OACH,IAAA,4CAAwB,EAAC,0CAAkC,EAAE,UAAU,CAAC,gBAChE,aAAa,EACzB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,GAAG,EACR,IAAI,EAAC,OAAO,EACZ,EAAE,EAAE;oBACA,YAAY;oBACZ,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;iBACrC;gBAED,8BAAC,0BAAoB,IAAC,EAAE,EAAE,EAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAC,GAAG,CACnD,CACV,CACD,CAAA;AACd,CAAC,CACJ,CAAA;AAED,kBAAe,4BAA4B,CAAA"}
@@ -0,0 +1,48 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { SxProps, Theme } from '@mui/material';
3
+ import type { PneTableColumnOption, PneTableColumnSettingsValue } from './types';
4
+ export declare const COLUMN_SETTINGS_DIALOG_AUTOTEST_ID = "column-settings-dialog";
5
+ export declare const COLUMN_SETTINGS_SEARCH_AUTOTEST_ID = "column-settings-search";
6
+ export declare const COLUMN_SETTINGS_OPTION_AUTOTEST_ID = "column-settings-option";
7
+ export declare const COLUMN_SETTINGS_REORDER_AUTOTEST_ID = "column-settings-reorder";
8
+ export declare const COLUMN_SETTINGS_EMPTY_AUTOTEST_ID = "column-settings-empty";
9
+ export declare const COLUMN_SETTINGS_RESET_AUTOTEST_ID = "column-settings-reset";
10
+ export declare const COLUMN_SETTINGS_CANCEL_AUTOTEST_ID = "column-settings-cancel";
11
+ export declare const COLUMN_SETTINGS_SAVE_AUTOTEST_ID = "column-settings-save";
12
+ export type PneTableColumnSettingsDialogProps<TColumn extends PneTableColumnOption = PneTableColumnOption> = {
13
+ open: boolean;
14
+ /** Called on Cancel, on the close button, on backdrop/Escape, and after a successful save. */
15
+ onClose: () => void;
16
+ /** Column catalog of the configured table view, in default display order. */
17
+ columns: readonly TColumn[];
18
+ /** Stored preference; `undefined` or `null` means the catalog defaults. */
19
+ value?: PneTableColumnSettingsValue | null;
20
+ /**
21
+ * Receives the normalized draft on Save. The dialog closes once the returned
22
+ * promise resolves. A rejected promise keeps the dialog open with the draft
23
+ * intact; reporting that failure to the user is the caller's job.
24
+ */
25
+ onSave: (value: PneTableColumnSettingsValue) => void | Promise<void>;
26
+ /** Stable, non-secret instance identifier used to scope Selenium locators. */
27
+ autoTestId?: string;
28
+ /** Defaults to the localized "Table settings". */
29
+ title?: ReactNode;
30
+ /** Set to false to drop the search field for short catalogs. Defaults to true. */
31
+ searchable?: boolean;
32
+ /**
33
+ * Lets the user drag visible columns into a new display order. Grips are
34
+ * shown only for visible columns and only while the list is not filtered.
35
+ * Defaults to true.
36
+ */
37
+ reorderable?: boolean;
38
+ containerSx?: SxProps<Theme>;
39
+ };
40
+ /**
41
+ * Modal editor for the visible column set of one table view: a searchable
42
+ * checklist over the catalog with drag reordering of visible columns,
43
+ * "Reset to default", "Cancel" and "Save". The draft is created when the
44
+ * dialog opens and discarded when it closes, so a reopened dialog always
45
+ * starts from the current `value`.
46
+ */
47
+ declare const PneTableColumnSettingsDialog: <TColumn extends PneTableColumnOption = PneTableColumnOption>(props: PneTableColumnSettingsDialogProps<TColumn>) => React.JSX.Element | null;
48
+ export default PneTableColumnSettingsDialog;
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.COLUMN_SETTINGS_SAVE_AUTOTEST_ID = exports.COLUMN_SETTINGS_CANCEL_AUTOTEST_ID = exports.COLUMN_SETTINGS_RESET_AUTOTEST_ID = exports.COLUMN_SETTINGS_EMPTY_AUTOTEST_ID = exports.COLUMN_SETTINGS_REORDER_AUTOTEST_ID = exports.COLUMN_SETTINGS_OPTION_AUTOTEST_ID = exports.COLUMN_SETTINGS_SEARCH_AUTOTEST_ID = exports.COLUMN_SETTINGS_DIALOG_AUTOTEST_ID = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const react_1 = tslib_1.__importStar(require("react"));
6
+ const material_1 = require("@mui/material");
7
+ const DragIndicator_1 = tslib_1.__importDefault(require("@mui/icons-material/DragIndicator"));
8
+ const dnd_1 = require("@hello-pangea/dnd");
9
+ const react_i18next_1 = require("react-i18next");
10
+ const PneModal_1 = tslib_1.__importDefault(require("../../PneModal"));
11
+ const PneModalActions_1 = tslib_1.__importDefault(require("../../PneModalActions"));
12
+ const PneButton_1 = tslib_1.__importDefault(require("../../PneButton"));
13
+ const PneCheckbox_1 = require("../../PneCheckbox");
14
+ const PneTextField_1 = tslib_1.__importDefault(require("../../PneTextField"));
15
+ const AutoTestAttribute_1 = require("../../AutoTestAttribute");
16
+ const useImmediateTouchSensor_1 = tslib_1.__importDefault(require("../../non-abstract-entity-selector/useImmediateTouchSensor"));
17
+ const resolveColumnSettings_1 = require("./resolveColumnSettings");
18
+ exports.COLUMN_SETTINGS_DIALOG_AUTOTEST_ID = 'column-settings-dialog';
19
+ exports.COLUMN_SETTINGS_SEARCH_AUTOTEST_ID = 'column-settings-search';
20
+ exports.COLUMN_SETTINGS_OPTION_AUTOTEST_ID = 'column-settings-option';
21
+ exports.COLUMN_SETTINGS_REORDER_AUTOTEST_ID = 'column-settings-reorder';
22
+ exports.COLUMN_SETTINGS_EMPTY_AUTOTEST_ID = 'column-settings-empty';
23
+ exports.COLUMN_SETTINGS_RESET_AUTOTEST_ID = 'column-settings-reset';
24
+ exports.COLUMN_SETTINGS_CANCEL_AUTOTEST_ID = 'column-settings-cancel';
25
+ exports.COLUMN_SETTINGS_SAVE_AUTOTEST_ID = 'column-settings-save';
26
+ const DROPPABLE_ID = 'pne-table-column-settings';
27
+ /** Mouse, keyboard and immediate touch dragging on the dedicated grip. */
28
+ const reorderSensors = [dnd_1.useMouseSensor, dnd_1.useKeyboardSensor, useImmediateTouchSensor_1.default];
29
+ const listSx = {
30
+ maxHeight: '320px',
31
+ overflowY: 'auto',
32
+ padding: 0,
33
+ };
34
+ const itemSx = {
35
+ alignItems: 'stretch',
36
+ display: 'flex',
37
+ padding: 0,
38
+ };
39
+ const itemButtonSx = {
40
+ borderRadius: '4px',
41
+ flex: 1,
42
+ minHeight: '40px',
43
+ minWidth: 0,
44
+ paddingBottom: '2px',
45
+ paddingLeft: '4px',
46
+ paddingRight: '8px',
47
+ paddingTop: '2px',
48
+ };
49
+ const gripSx = {
50
+ borderRadius: '4px',
51
+ cursor: 'grab',
52
+ flexShrink: 0,
53
+ minHeight: '40px',
54
+ padding: 0,
55
+ width: '32px',
56
+ '@media (pointer: coarse)': { width: '44px' },
57
+ '&.Mui-focusVisible': {
58
+ outline: '2px solid',
59
+ outlineColor: 'primary.main',
60
+ outlineOffset: -2,
61
+ },
62
+ };
63
+ const normalizeSearch = (value) => value.trim().toLocaleLowerCase();
64
+ const ColumnSettingsForm = (props) => {
65
+ const { autoTestId, columns, containerSx, onClose, onSave, reorderable = true, searchable = true, title, value, } = props;
66
+ const { t } = (0, react_i18next_1.useTranslation)();
67
+ const initial = (0, react_1.useMemo)(() => (0, resolveColumnSettings_1.resolvePneTableColumnSettings)(columns, value), [columns, value]);
68
+ const [draft, setDraft] = (0, react_1.useState)(initial.value);
69
+ const [search, setSearch] = (0, react_1.useState)('');
70
+ const [saving, setSaving] = (0, react_1.useState)(false);
71
+ const mountedRef = (0, react_1.useRef)(true);
72
+ (0, react_1.useEffect)(() => () => {
73
+ mountedRef.current = false;
74
+ }, []);
75
+ const resolvedDraft = (0, react_1.useMemo)(() => (0, resolveColumnSettings_1.resolvePneTableColumnSettings)(columns, draft), [columns, draft]);
76
+ const items = (0, react_1.useMemo)(() => [
77
+ ...resolvedDraft.visibleColumns.map(column => ({ column, visible: true })),
78
+ ...resolvedDraft.hiddenColumns.map(column => ({ column, visible: false })),
79
+ ], [resolvedDraft]);
80
+ const normalizedSearch = normalizeSearch(search);
81
+ const filtering = normalizedSearch !== '';
82
+ const filteredItems = filtering
83
+ ? items.filter(item => normalizeSearch(item.column.label).includes(normalizedSearch))
84
+ : items;
85
+ const lastVisibleId = resolvedDraft.visibleColumns.length === 1
86
+ ? resolvedDraft.visibleColumns[0].id
87
+ : null;
88
+ const visibleCount = resolvedDraft.visibleColumns.length;
89
+ const dragEnabled = reorderable && !saving && !filtering && visibleCount > 1;
90
+ const toggle = (id) => {
91
+ setDraft(current => {
92
+ const visible = current.visibleColumnIds.includes(id);
93
+ if (visible) {
94
+ if (current.visibleColumnIds.length <= 1) {
95
+ return current;
96
+ }
97
+ return {
98
+ visibleColumnIds: current.visibleColumnIds.filter(columnId => columnId !== id),
99
+ hiddenColumnIds: [...current.hiddenColumnIds, id],
100
+ };
101
+ }
102
+ return {
103
+ visibleColumnIds: [...current.visibleColumnIds, id],
104
+ hiddenColumnIds: current.hiddenColumnIds.filter(columnId => columnId !== id),
105
+ };
106
+ });
107
+ };
108
+ const handleDragEnd = (result) => {
109
+ const { destination, source } = result;
110
+ if (!destination || destination.droppableId !== DROPPABLE_ID) {
111
+ return;
112
+ }
113
+ // Visible columns occupy the leading list slots in draft order, so list
114
+ // indices map onto visibleColumnIds; hidden rows are not a valid target.
115
+ const target = Math.min(destination.index, visibleCount - 1);
116
+ if (source.index >= visibleCount || target === source.index) {
117
+ return;
118
+ }
119
+ setDraft(current => {
120
+ const visible = [...current.visibleColumnIds];
121
+ const [moved] = visible.splice(source.index, 1);
122
+ visible.splice(target, 0, moved);
123
+ return { ...current, visibleColumnIds: visible };
124
+ });
125
+ };
126
+ const handleReset = () => {
127
+ setDraft((0, resolveColumnSettings_1.createDefaultPneTableColumnSettings)(columns));
128
+ };
129
+ const handleSave = async () => {
130
+ if (saving) {
131
+ return;
132
+ }
133
+ setSaving(true);
134
+ try {
135
+ await onSave(resolvedDraft.value);
136
+ if (mountedRef.current) {
137
+ setSaving(false);
138
+ }
139
+ onClose();
140
+ }
141
+ catch {
142
+ // The consumer reports the failure; the draft stays editable.
143
+ if (mountedRef.current) {
144
+ setSaving(false);
145
+ }
146
+ }
147
+ };
148
+ const actionLabel = t('pneTable.columnSettings.title', { defaultValue: 'Table settings' });
149
+ const searchLabel = t('pneTable.columnSettings.search', { defaultValue: 'Search columns' });
150
+ const lastVisibleHint = t('pneTable.columnSettings.lastVisible', {
151
+ defaultValue: 'At least one column stays visible',
152
+ });
153
+ return react_1.default.createElement(PneModal_1.default, { ...(0, AutoTestAttribute_1.createAutoTestAttributes)(exports.COLUMN_SETTINGS_DIALOG_AUTOTEST_ID, autoTestId), actions: react_1.default.createElement(PneModalActions_1.default, { leading: react_1.default.createElement(PneButton_1.default, { ...(0, AutoTestAttribute_1.createAutoTestAttributes)(exports.COLUMN_SETTINGS_RESET_AUTOTEST_ID), disabled: saving || resolvedDraft.isDefault, onClick: handleReset, pneStyle: 'outlined' }, t('pneTable.columnSettings.reset', { defaultValue: 'Reset to default' })), primary: react_1.default.createElement(PneButton_1.default, { ...(0, AutoTestAttribute_1.createAutoTestAttributes)(exports.COLUMN_SETTINGS_SAVE_AUTOTEST_ID), disabled: saving, onClick: () => {
154
+ void handleSave();
155
+ } }, t('pneTable.columnSettings.save', { defaultValue: 'Save' })), secondary: react_1.default.createElement(PneButton_1.default, { ...(0, AutoTestAttribute_1.createAutoTestAttributes)(exports.COLUMN_SETTINGS_CANCEL_AUTOTEST_ID), disabled: saving, onClick: onClose, pneStyle: 'outlined' }, t('pneTable.columnSettings.cancel', { defaultValue: 'Cancel' })) }), containerSx: [
156
+ { maxWidth: '100%', width: '480px' },
157
+ ...(Array.isArray(containerSx) ? containerSx : [containerSx]),
158
+ ], onClose: () => {
159
+ if (!saving) {
160
+ onClose();
161
+ }
162
+ }, open: true, title: title ?? actionLabel },
163
+ react_1.default.createElement(material_1.Box, { sx: { display: 'flex', flexDirection: 'column', gap: '12px' } },
164
+ searchable ? react_1.default.createElement(PneTextField_1.default, { autoComplete: 'off', fullWidth: true, label: searchLabel, onChange: event => setSearch(event.target.value), slotProps: {
165
+ htmlInput: (0, AutoTestAttribute_1.createAutoTestAttributes)(exports.COLUMN_SETTINGS_SEARCH_AUTOTEST_ID),
166
+ }, type: 'search', value: search }) : null,
167
+ react_1.default.createElement(dnd_1.DragDropContext, { enableDefaultSensors: false, onDragEnd: handleDragEnd, sensors: reorderSensors },
168
+ react_1.default.createElement(dnd_1.Droppable, { droppableId: DROPPABLE_ID, isDropDisabled: !dragEnabled }, droppable => react_1.default.createElement(material_1.List, { ...droppable.droppableProps, "aria-label": actionLabel, dense: true, ref: droppable.innerRef, sx: listSx },
169
+ filteredItems.map(({ column, visible }, index) => {
170
+ const locked = visible && column.id === lastVisibleId;
171
+ const labelId = `pne-column-settings-${column.id}`;
172
+ const draggable = dragEnabled && visible;
173
+ const reorderLabel = t('pneTable.columnSettings.reorder', {
174
+ name: column.label,
175
+ defaultValue: 'Reorder {{name}}',
176
+ });
177
+ return react_1.default.createElement(dnd_1.Draggable
178
+ // The grip is a real button; without this the library refuses to lift from it.
179
+ , {
180
+ // The grip is a real button; without this the library refuses to lift from it.
181
+ disableInteractiveElementBlocking: true, draggableId: column.id, index: index, isDragDisabled: !draggable, key: column.id }, provided => react_1.default.createElement(material_1.ListItem, { ...provided.draggableProps, ref: provided.innerRef, style: provided.draggableProps.style, sx: itemSx },
182
+ react_1.default.createElement(material_1.ListItemButton, { dense: true, disabled: saving || locked, onClick: () => toggle(column.id), sx: itemButtonSx, title: locked ? lastVisibleHint : undefined },
183
+ react_1.default.createElement(material_1.ListItemIcon, { sx: { minWidth: '36px' } },
184
+ react_1.default.createElement(PneCheckbox_1.PneCheckbox, { checked: visible, disabled: saving || locked, disableRipple: true, edge: 'start', slotProps: {
185
+ input: {
186
+ ...(0, AutoTestAttribute_1.createAutoTestAttributes)(exports.COLUMN_SETTINGS_OPTION_AUTOTEST_ID, column.id),
187
+ 'aria-labelledby': labelId,
188
+ },
189
+ }, tabIndex: -1 })),
190
+ react_1.default.createElement(material_1.ListItemText, { id: labelId, primary: column.label, slotProps: { primary: { noWrap: true } } })),
191
+ draggable && provided.dragHandleProps ? react_1.default.createElement(material_1.IconButton, { ...provided.dragHandleProps, ...(0, AutoTestAttribute_1.createAutoTestAttributes)(exports.COLUMN_SETTINGS_REORDER_AUTOTEST_ID, column.id), "aria-label": reorderLabel, disableRipple: true, style: { touchAction: 'none' }, sx: gripSx, type: 'button' },
192
+ react_1.default.createElement(DragIndicator_1.default, { fontSize: 'small' })) : null));
193
+ }),
194
+ droppable.placeholder,
195
+ filteredItems.length === 0 ? react_1.default.createElement(material_1.ListItem, { ...(0, AutoTestAttribute_1.createAutoTestAttributes)(exports.COLUMN_SETTINGS_EMPTY_AUTOTEST_ID), sx: { justifyContent: 'center', minHeight: '40px' } },
196
+ react_1.default.createElement(material_1.Typography, { color: 'text.secondary', variant: 'body2' }, t('pneTable.columnSettings.noMatches', { defaultValue: 'No columns match' }))) : null)))));
197
+ };
198
+ /**
199
+ * Modal editor for the visible column set of one table view: a searchable
200
+ * checklist over the catalog with drag reordering of visible columns,
201
+ * "Reset to default", "Cancel" and "Save". The draft is created when the
202
+ * dialog opens and discarded when it closes, so a reopened dialog always
203
+ * starts from the current `value`.
204
+ */
205
+ const PneTableColumnSettingsDialog = (props) => {
206
+ const { open, ...formProps } = props;
207
+ if (!open) {
208
+ return null;
209
+ }
210
+ return react_1.default.createElement(ColumnSettingsForm, { ...formProps });
211
+ };
212
+ exports.default = PneTableColumnSettingsDialog;
213
+ //# sourceMappingURL=PneTableColumnSettingsDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PneTableColumnSettingsDialog.js","sourceRoot":"","sources":["../../../../src/component/table/column-settings/PneTableColumnSettingsDialog.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { PneTableColumnOption, PneTableColumnSettingsValue, PneTableResolvedColumnSettings } from './types';
2
+ /**
3
+ * Throws on a catalog that cannot be configured: empty or with duplicate IDs.
4
+ * Column identity belongs to the consumer, so silent de-duplication would hide a bug.
5
+ */
6
+ export declare const assertPneTableColumnCatalog: (columns: readonly PneTableColumnOption[]) => void;
7
+ /** Default value for a catalog: `defaultVisible !== false` columns in catalog order, the rest hidden. */
8
+ export declare const createDefaultPneTableColumnSettings: (columns: readonly PneTableColumnOption[]) => PneTableColumnSettingsValue;
9
+ /**
10
+ * Applies a stored value to the current catalog:
11
+ *
12
+ * - IDs unknown to the catalog are dropped;
13
+ * - visible columns keep their stored order;
14
+ * - catalog columns absent from both stored lists are new since the save and
15
+ * are appended as visible, in catalog order;
16
+ * - a value that leaves nothing visible falls back to the catalog defaults.
17
+ *
18
+ * `undefined` means "never configured" and yields the defaults.
19
+ */
20
+ export declare const resolvePneTableColumnSettings: <TColumn extends PneTableColumnOption>(columns: readonly TColumn[], value: PneTableColumnSettingsValue | null | undefined) => PneTableResolvedColumnSettings<TColumn>;
21
+ /** Structural equality of two normalized values; hidden order is irrelevant. */
22
+ export declare const isSamePneTableColumnSettings: (left: PneTableColumnSettingsValue, right: PneTableColumnSettingsValue) => boolean;
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isSamePneTableColumnSettings = exports.resolvePneTableColumnSettings = exports.createDefaultPneTableColumnSettings = exports.assertPneTableColumnCatalog = void 0;
4
+ const uniqueIds = (ids) => {
5
+ const seen = new Set();
6
+ const result = [];
7
+ for (const id of ids) {
8
+ if (!seen.has(id)) {
9
+ seen.add(id);
10
+ result.push(id);
11
+ }
12
+ }
13
+ return result;
14
+ };
15
+ const sameIds = (left, right) => left.length === right.length && left.every((id, index) => id === right[index]);
16
+ /**
17
+ * Throws on a catalog that cannot be configured: empty or with duplicate IDs.
18
+ * Column identity belongs to the consumer, so silent de-duplication would hide a bug.
19
+ */
20
+ const assertPneTableColumnCatalog = (columns) => {
21
+ if (columns.length === 0) {
22
+ throw new Error('PneTable column settings: the column catalog must not be empty');
23
+ }
24
+ const seen = new Set();
25
+ for (const column of columns) {
26
+ if (seen.has(column.id)) {
27
+ throw new Error(`PneTable column settings: duplicate column ID "${column.id}"`);
28
+ }
29
+ seen.add(column.id);
30
+ }
31
+ };
32
+ exports.assertPneTableColumnCatalog = assertPneTableColumnCatalog;
33
+ /** Default value for a catalog: `defaultVisible !== false` columns in catalog order, the rest hidden. */
34
+ const createDefaultPneTableColumnSettings = (columns) => ({
35
+ visibleColumnIds: columns.filter(column => column.defaultVisible !== false).map(column => column.id),
36
+ hiddenColumnIds: columns.filter(column => column.defaultVisible === false).map(column => column.id),
37
+ });
38
+ exports.createDefaultPneTableColumnSettings = createDefaultPneTableColumnSettings;
39
+ /**
40
+ * Applies a stored value to the current catalog:
41
+ *
42
+ * - IDs unknown to the catalog are dropped;
43
+ * - visible columns keep their stored order;
44
+ * - catalog columns absent from both stored lists are new since the save and
45
+ * are appended as visible, in catalog order;
46
+ * - a value that leaves nothing visible falls back to the catalog defaults.
47
+ *
48
+ * `undefined` means "never configured" and yields the defaults.
49
+ */
50
+ const resolvePneTableColumnSettings = (columns, value) => {
51
+ (0, exports.assertPneTableColumnCatalog)(columns);
52
+ const byId = new Map(columns.map(column => [column.id, column]));
53
+ const defaults = (0, exports.createDefaultPneTableColumnSettings)(columns);
54
+ const resolveIds = (source) => {
55
+ const visible = uniqueIds(source.visibleColumnIds).filter(id => byId.has(id));
56
+ const visibleSet = new Set(visible);
57
+ const hidden = uniqueIds(source.hiddenColumnIds)
58
+ .filter(id => byId.has(id) && !visibleSet.has(id));
59
+ const known = new Set([...visible, ...hidden]);
60
+ const added = columns.filter(column => !known.has(column.id)).map(column => column.id);
61
+ return {
62
+ visibleColumnIds: [...visible, ...added],
63
+ hiddenColumnIds: hidden,
64
+ };
65
+ };
66
+ let resolved = value ? resolveIds(value) : defaults;
67
+ if (resolved.visibleColumnIds.length === 0) {
68
+ resolved = defaults;
69
+ }
70
+ const hiddenSet = new Set(resolved.hiddenColumnIds);
71
+ return {
72
+ visibleColumns: resolved.visibleColumnIds.map(id => byId.get(id)),
73
+ hiddenColumns: columns.filter(column => hiddenSet.has(column.id)),
74
+ value: resolved,
75
+ isDefault: sameIds(resolved.visibleColumnIds, defaults.visibleColumnIds)
76
+ && sameIds([...resolved.hiddenColumnIds].sort(), [...defaults.hiddenColumnIds].sort()),
77
+ };
78
+ };
79
+ exports.resolvePneTableColumnSettings = resolvePneTableColumnSettings;
80
+ /** Structural equality of two normalized values; hidden order is irrelevant. */
81
+ const isSamePneTableColumnSettings = (left, right) => sameIds(left.visibleColumnIds, right.visibleColumnIds)
82
+ && sameIds([...left.hiddenColumnIds].sort(), [...right.hiddenColumnIds].sort());
83
+ exports.isSamePneTableColumnSettings = isSamePneTableColumnSettings;
84
+ //# sourceMappingURL=resolveColumnSettings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveColumnSettings.js","sourceRoot":"","sources":["../../../../src/component/table/column-settings/resolveColumnSettings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /** Stable, non-secret column identifier owned by the consumer; never an index or a translated label. */
2
+ export type PneTableColumnId = string;
3
+ /**
4
+ * One entry of a table column catalog. The catalog lists every column a
5
+ * consumer can render for a given table view, in the default display order.
6
+ */
7
+ export type PneTableColumnOption = {
8
+ id: PneTableColumnId;
9
+ /** Plain-text label used by the settings dialog for display and search; keep it equal to the header text. */
10
+ label: string;
11
+ /** Whether the column is shown before the user configures anything. Defaults to `true`. */
12
+ defaultVisible?: boolean;
13
+ };
14
+ /**
15
+ * Persisted user preference for one table view. The consumer stores it as-is
16
+ * and passes it back; the library never inspects where it lives.
17
+ */
18
+ export type PneTableColumnSettingsValue = {
19
+ /** Column IDs the user keeps visible, in display order. */
20
+ visibleColumnIds: readonly PneTableColumnId[];
21
+ /**
22
+ * Column IDs the user explicitly hid. Catalog columns absent from both lists
23
+ * are new since the value was saved and are shown by default.
24
+ */
25
+ hiddenColumnIds: readonly PneTableColumnId[];
26
+ };
27
+ /** Catalog-aware result of applying a stored value to the current column catalog. */
28
+ export type PneTableResolvedColumnSettings<TColumn extends PneTableColumnOption> = {
29
+ /** Catalog columns to render, in display order. Never empty for a non-empty catalog. */
30
+ visibleColumns: readonly TColumn[];
31
+ /** Catalog columns currently hidden, in catalog order. */
32
+ hiddenColumns: readonly TColumn[];
33
+ /** Normalized value that references only existing catalog columns. */
34
+ value: PneTableColumnSettingsValue;
35
+ /** True when `value` equals the catalog defaults. */
36
+ isDefault: boolean;
37
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/component/table/column-settings/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
1
+ import type { PneTableColumnId, PneTableColumnOption, PneTableColumnSettingsValue } from './types';
2
+ import type { PneTableColumnSettingsDialogProps } from './PneTableColumnSettingsDialog';
3
+ export type UsePneTableColumnSettingsParams<TColumn extends PneTableColumnOption> = {
4
+ /** Column catalog of the configured table view, in default display order. */
5
+ columns: readonly TColumn[];
6
+ /** Stored preference owned by the consumer; `undefined` or `null` means the catalog defaults. */
7
+ value?: PneTableColumnSettingsValue | null;
8
+ /** Persists the normalized value. Reject to keep the dialog open; report the failure yourself. */
9
+ onSave: (value: PneTableColumnSettingsValue) => void | Promise<void>;
10
+ };
11
+ export type UsePneTableColumnSettingsResult<TColumn extends PneTableColumnOption> = {
12
+ /** Catalog columns to render, in display order. */
13
+ visibleColumns: readonly TColumn[];
14
+ /** Catalog columns currently hidden, in catalog order. */
15
+ hiddenColumns: readonly TColumn[];
16
+ /** Normalized current value after catalog reconciliation. */
17
+ value: PneTableColumnSettingsValue;
18
+ /** True when the current value equals the catalog defaults. */
19
+ isDefault: boolean;
20
+ isVisible: (columnId: PneTableColumnId) => boolean;
21
+ /** Dialog visibility. */
22
+ open: boolean;
23
+ openDialog: () => void;
24
+ closeDialog: () => void;
25
+ /** Spread into `PneTableColumnSettingsDialog`. */
26
+ dialogProps: Pick<PneTableColumnSettingsDialogProps<TColumn>, 'columns' | 'onClose' | 'onSave' | 'open' | 'value'>;
27
+ };
28
+ /**
29
+ * Reconciles a stored column preference with the catalog and owns the dialog
30
+ * open state. Storage stays with the consumer: pass the loaded `value` and an
31
+ * `onSave` that writes it back.
32
+ */
33
+ declare const usePneTableColumnSettings: <TColumn extends PneTableColumnOption>(params: UsePneTableColumnSettingsParams<TColumn>) => UsePneTableColumnSettingsResult<TColumn>;
34
+ export default usePneTableColumnSettings;