@trackunit/react-table 2.11.9 → 2.11.11-alpha-7afddbbe4cc.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../../../libs/react/table/migrations/entry.ts"],"names":[],"mappings":"","sourcesContent":["export {};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-table",
3
- "version": "2.11.9",
3
+ "version": "2.11.11-alpha-7afddbbe4cc.0",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -11,15 +11,15 @@
11
11
  "react-dnd": "16.0.1",
12
12
  "react-dnd-html5-backend": "16.0.1",
13
13
  "tailwind-merge": "^2.0.0",
14
- "@trackunit/react-components": "3.8.2",
15
- "@trackunit/react-core-hooks": "1.25.5",
16
- "@trackunit/shared-utils": "1.19.5",
17
- "@trackunit/css-class-variance-utilities": "2.3.5",
18
- "@trackunit/ui-icons": "1.17.5",
19
- "@trackunit/react-table-base-components": "2.12.9",
20
- "@trackunit/react-form-components": "2.10.9",
21
- "@trackunit/i18n-library-translation": "2.8.5",
22
- "@trackunit/iris-app-runtime-core-api": "1.21.5",
14
+ "@trackunit/react-components": "3.8.4-alpha-7afddbbe4cc.0",
15
+ "@trackunit/react-core-hooks": "1.25.7-alpha-7afddbbe4cc.0",
16
+ "@trackunit/shared-utils": "1.19.7-alpha-7afddbbe4cc.0",
17
+ "@trackunit/css-class-variance-utilities": "2.3.7-alpha-7afddbbe4cc.0",
18
+ "@trackunit/ui-icons": "1.17.7-alpha-7afddbbe4cc.0",
19
+ "@trackunit/react-table-base-components": "2.12.11-alpha-7afddbbe4cc.0",
20
+ "@trackunit/react-form-components": "2.10.11-alpha-7afddbbe4cc.0",
21
+ "@trackunit/i18n-library-translation": "2.8.7-alpha-7afddbbe4cc.0",
22
+ "@trackunit/iris-app-runtime-core-api": "1.21.7-alpha-7afddbbe4cc.0",
23
23
  "zod": "^3.25.76"
24
24
  },
25
25
  "peerDependencies": {
@@ -29,29 +29,29 @@ declare const tableStateSchema: z.ZodObject<{
29
29
  expanded: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<true>, z.ZodRecord<z.ZodString, z.ZodBoolean>]>>;
30
30
  }, "strip", z.ZodTypeAny, {
31
31
  columnOrder?: string[] | undefined;
32
- columnVisibility?: Record<string, boolean> | undefined;
33
32
  sorting?: {
34
33
  id: string;
35
34
  desc: boolean;
36
35
  }[] | undefined;
36
+ columnVisibility?: Record<string, boolean> | undefined;
37
+ columnSizing?: Record<string, number> | undefined;
37
38
  columnPinning?: {
38
39
  right?: string[] | undefined;
39
40
  left?: string[] | undefined;
40
41
  } | undefined;
41
- columnSizing?: Record<string, number> | undefined;
42
42
  expanded?: true | Record<string, boolean> | undefined;
43
43
  }, {
44
44
  columnOrder?: string[] | undefined;
45
- columnVisibility?: Record<string, boolean> | undefined;
46
45
  sorting?: {
47
46
  id: string;
48
47
  desc: boolean;
49
48
  }[] | undefined;
49
+ columnVisibility?: Record<string, boolean> | undefined;
50
+ columnSizing?: Record<string, number> | undefined;
50
51
  columnPinning?: {
51
52
  right?: string[] | undefined;
52
53
  left?: string[] | undefined;
53
54
  } | undefined;
54
- columnSizing?: Record<string, number> | undefined;
55
55
  expanded?: true | Record<string, boolean> | undefined;
56
56
  }>;
57
57
  export type TableColumnOptions = z.infer<typeof tableStateSchema>;
@@ -61,58 +61,55 @@ type UseTablePersistenceResult = {
61
61
  };
62
62
  /**
63
63
  * Persists and restores table column state (order, sizing, visibility, sorting, pinning, expanded) using
64
- * the URL **hash fragment** and localStorage.
64
+ * localStorage and the URL **hash fragment**.
65
65
  *
66
66
  * Storage scope:
67
- * - URL hash (shareable): `columnOrder`, `columnVisibility`, `sorting`, `columnPinning`, `columnSizing`.
68
- * - localStorage: everything above plus `expanded`.
67
+ * - localStorage: everything, scoped to the current user.
68
+ * - URL hash (shareable): everything except `expanded`.
69
69
  *
70
70
  * The hash slot is used instead of search params because some deployments
71
71
  * route through AWS WAF, whose `SizeRestrictions_QUERYSTRING` managed rule
72
72
  * caps the query string at ~5000 bytes — easily breached by wide tables.
73
73
  * The fragment is client-only and bypasses that cap entirely (subject to a
74
- * 64 KiB soft limit enforced by `useHashParamSync`).
75
- *
76
- * Legacy compatibility: shared links that still use `?<persistenceKey>Tp=`
77
- * search params from before the hash migration are decoded on first load
78
- * and the search param is stripped via a `replace` navigation so old
79
- * bookmarks and forwarded URLs continue to restore state without polluting
80
- * browser history.
74
+ * 64 KiB soft limit enforced by the URL sync).
81
75
  *
82
- * On mount, state is loaded from the hash (or legacy search param as a
83
- * one-shot fallback) and merged with localStorage so fields omitted from
84
- * the URL, such as `expanded`, still survive reloads. Opening that URL
85
- * saves the merged layout for the account that loaded the page, so a
86
- * pasted link sticks without a further edit. An account that becomes
87
- * current later, while the same URL is still open, does not receive that
88
- * write — their storage changes only when they edit the table. Switching
89
- * back to the opener does not write the hash that is on screen then.
76
+ * On load the hash wins, so a link or bookmark renders the same layout for
77
+ * whoever opens it, and localStorage fills in what the hash omits (`expanded`).
78
+ * Opening a URL that carries a layout saves it for the account that loaded the
79
+ * page, so a pasted link sticks without a further edit. A layout that exists
80
+ * only in localStorage is never copied into the hash on load: doing that put
81
+ * the current layout into every history entry, so a later visit via history,
82
+ * a bookmark, or a login redirect replayed an older layout and saved it over
83
+ * the current one (GLU-2396).
90
84
  *
91
- * A layout that exists only in localStorage is not copied into the hash on
92
- * load. Doing that put the current layout into every history entry, so a
93
- * later visit via history, a bookmark, or a login redirect replayed an
94
- * older layout and saved it over the current one (GLU-2396). The hash is
95
- * written when the user changes the table, replacing the current history
96
- * entry, or when they open a URL that already carries one. A push per edit
97
- * would leave the same replayable entries behind.
85
+ * `onTableStateChange` takes a *partial* state and merges it into whatever was
86
+ * reported earlier in the session, so a consumer can report a single slice
87
+ * (e.g. only `expanded`) without the omitted fields falling back to their
88
+ * mount-time values. A field reported empty is dropped from the stored state,
89
+ * and once every field is empty the entry is removed altogether.
98
90
  *
99
- * `onTableStateChange` takes a *partial* state and merges it into whatever
100
- * was reported earlier in the session, so a consumer can report a single
101
- * slice (e.g. only `expanded`) without the omitted fields falling back to
102
- * their mount-time values. A field reported empty is dropped from the stored
103
- * state, and once every field is empty the entry is removed altogether.
91
+ * Each change is written to localStorage as soon as it is reported, so
92
+ * navigating away right after an edit cannot lose it. The hash is written
93
+ * after a {@link URL_WRITE_DEBOUNCE_MS} quiet period, replacing the current
94
+ * history entry: a drag or a run of toggles leaves one entry, not one per step.
104
95
  *
105
- * Reported state is scoped to the identity that reported it: when the current
106
- * user changes, state reported by the previous user is discarded instead of
107
- * being written to the new user's storage. A layout shared through the URL
108
- * renders for anyone. It is saved for the account that opened the page, and
109
- * only becomes a later account's layout once that account changes the table.
96
+ * Every hash write is stamped with the identity that wrote it. The stamp is
97
+ * read only by the login redirect, which drops a hash left behind by another
98
+ * account that also uses this browser, so accounts sharing a PC do not hand
99
+ * their layouts to each other (GLU-2396).
110
100
  *
111
- * The hash always wins on load so a link or bookmark renders the same layout
112
- * for whoever opens it. Each hash write is stamped with the identity that
113
- * wrote it; the stamp is read only by the login redirect, which drops a hash
114
- * left behind by a *different* account that also uses this browser so
115
- * accounts sharing a PC do not hand their layouts to each other (GLU-2396).
101
+ * Changes reported before `clientSideUserId` resolves are held in React state
102
+ * and written to the user's scoped storage and stamped into the hash once it
103
+ * does. The id can also change while the table is mounted: releasing an
104
+ * impersonated identity renews the token, and the new claims are published
105
+ * before the page navigates away. Reported state is therefore tagged with the
106
+ * identity that produced it and persisted only while that identity is current,
107
+ * and the layout read on load is committed to storage only for the account
108
+ * that opened the page, so a layout never crosses from one account into
109
+ * another's scoped storage or into their hash on its own. An identity that
110
+ * takes over and then edits saves what it sees on screen — the opener's hash
111
+ * over its own stored layout — under its own key, the same as editing an
112
+ * opened link.
116
113
  *
117
114
  * @param persistenceKey - Unique key used to store and retrieve the table state.
118
115
  * Must be camelCase and at most 15 characters (e.g. "userTable", "assetList").
@@ -0,0 +1,27 @@
1
+ import type { TableColumnOptions } from "../useTablePersistence";
2
+ /**
3
+ * The URL projection of table state: everything except `expanded`.
4
+ *
5
+ * Row expansion is per-session, per-user detail and would make a shared link
6
+ * open rows the recipient has no interest in, so it lives only in
7
+ * localStorage. `usePersistedState`'s `mergeWithStorageOnRead` restores it on
8
+ * load. The remaining fields are written as-is; the gzip step in
9
+ * `useCustomEncoding` handles the size, and a value that reads back to the
10
+ * same shape it was written from cannot drift from storage.
11
+ */
12
+ export declare const toTableUrlValue: ({ expanded: _expanded, ...shareable }: TableColumnOptions) => Omit<TableColumnOptions, "expanded">;
13
+ /**
14
+ * Normalises a decoded URL value into the full `TableColumnOptions` shape.
15
+ *
16
+ * A value written by {@link toTableUrlValue} passes through unchanged, except
17
+ * that a `columnPinning` with one side missing gets the other side filled in
18
+ * as `[]`. Values in the legacy compact format are expanded:
19
+ * - short keys (`co`, `cv`, `s`, `cp`, `cs`) become full names;
20
+ * - a `columnVisibility` array of visible column IDs becomes a visible-only
21
+ * map (see `VISIBLE_ONLY_COLUMN_VISIBILITY_KEY`);
22
+ * - a `columnVisibility` `{ v, h }` pair becomes explicit booleans;
23
+ * - `columnPinning` `{ l, r }` becomes `{ left, right }`.
24
+ *
25
+ * Non-object input is returned as-is so validation can reject it.
26
+ */
27
+ export declare const fromTableUrlValue: (decoded: unknown) => unknown;
package/src/useTable.d.ts CHANGED
@@ -22,6 +22,12 @@ export interface TableOptionsProps<TData extends object> extends Omit<TableOptio
22
22
  *
23
23
  * `onTableStateChange` is called with the field that changed, not the whole state, so anything
24
24
  * storing it has to merge each report into what it already holds. `useTablePersistence` does.
25
+ * Within that field only what differs from the column definitions is reported — visibility
26
+ * entries equal to `meta.hiddenByDefault`, sizes equal to `size`, an order equal to the
27
+ * definition order, a pinning equal to `meta.pinned` — and an emptied field is reported empty.
28
+ * Defaults therefore belong on the column definitions; a value in `initialState` is read as
29
+ * saved state, not as a default. Columns without an explicit `id` take no part in the
30
+ * defaults (as before), so they are always reported once they are in the state.
25
31
  *
26
32
  * @template TData - The type representing the data model associated with the table.
27
33
  * @param {TableOptionsProps<TData>} props - The props object containing configuration options.
@@ -1,24 +0,0 @@
1
- import type { TableColumnOptions } from "../useTablePersistence";
2
- type CompactTableUrl = Record<string, unknown>;
3
- type UseCompactTableUrlReturn = {
4
- readonly toUrlValue: (state: TableColumnOptions) => CompactTableUrl;
5
- readonly fromUrlValue: (decoded: unknown) => unknown;
6
- };
7
- /**
8
- * Provides transform functions for compacting table state before URL encoding
9
- * and expanding it back after URL decoding.
10
- *
11
- * The compaction strategy:
12
- * - Short property keys (columnOrder → co, columnVisibility → cv, etc.)
13
- * - columnVisibility stored as an array of visible column names only
14
- * - columnOrder stored as visible-column order when visibility is available
15
- * - columnSizing stored under a short key (`cs`)
16
- * - `expanded` is excluded from the URL and restored from localStorage via
17
- * `usePersistedState`'s `mergeWithStorageOnRead`
18
- * - Empty pinning arrays are excluded
19
- *
20
- * These transforms are designed to plug into {@link usePersistedState}'s
21
- * `toUrlValue` and `fromUrlValue` options.
22
- */
23
- export declare const useCompactTableUrl: () => UseCompactTableUrlReturn;
24
- export {};