@pallasoft/ps-table-components 1.25.0 → 1.27.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.
Files changed (59) hide show
  1. package/dist/components/ps-data-table.d.ts +10 -1
  2. package/dist/components/ps-data-table.js +93 -17
  3. package/dist/components/ps-select-all-matching-banner.d.ts +10 -0
  4. package/dist/components/ps-select-all-matching-banner.js +10 -0
  5. package/dist/components/ps-table-pagination.d.ts +3 -1
  6. package/dist/components/ps-table-pagination.js +11 -3
  7. package/dist/components/ps-table-reorder-frame.d.ts +2 -1
  8. package/dist/components/ps-table-reorder-frame.js +8 -4
  9. package/dist/constants/ps-server-rows-config.d.ts +8 -0
  10. package/dist/constants/ps-server-rows-config.js +11 -0
  11. package/dist/constants/ps-table-drop-classes.js +2 -2
  12. package/dist/constants/ps-table-pagination-position.d.ts +6 -0
  13. package/dist/constants/ps-table-pagination-position.js +8 -0
  14. package/dist/esm/components/ps-data-table.js +94 -18
  15. package/dist/esm/components/ps-select-all-matching-banner.js +6 -0
  16. package/dist/esm/components/ps-table-pagination.js +11 -3
  17. package/dist/esm/components/ps-table-reorder-frame.js +8 -4
  18. package/dist/esm/constants/ps-server-rows-config.js +8 -0
  19. package/dist/esm/constants/ps-table-drop-classes.js +2 -2
  20. package/dist/esm/constants/ps-table-pagination-position.js +5 -0
  21. package/dist/esm/hooks/use-ps-server-rows.js +209 -0
  22. package/dist/esm/hooks/use-ps-table-reorder.js +8 -1
  23. package/dist/esm/index.js +12 -0
  24. package/dist/esm/interfaces/ps-server-entry.js +1 -0
  25. package/dist/esm/interfaces/ps-server-page.js +1 -0
  26. package/dist/esm/interfaces/ps-server-rows-input.js +1 -0
  27. package/dist/esm/interfaces/ps-server-rows-result.js +1 -0
  28. package/dist/esm/interfaces/ps-table-cursor-paging.js +1 -0
  29. package/dist/esm/interfaces/ps-table-select-all-matching.js +1 -0
  30. package/dist/esm/interfaces/table-drag-size.js +1 -0
  31. package/dist/esm/services/ps-server-rows-service.js +36 -0
  32. package/dist/esm/services/ps-table-reorder-service.js +12 -0
  33. package/dist/hooks/use-ps-server-rows.d.ts +3 -0
  34. package/dist/hooks/use-ps-server-rows.js +213 -0
  35. package/dist/hooks/use-ps-table-reorder.d.ts +2 -0
  36. package/dist/hooks/use-ps-table-reorder.js +8 -1
  37. package/dist/index.d.ts +12 -0
  38. package/dist/index.js +12 -0
  39. package/dist/interfaces/ps-server-entry.d.ts +6 -0
  40. package/dist/interfaces/ps-server-entry.js +2 -0
  41. package/dist/interfaces/ps-server-page.d.ts +7 -0
  42. package/dist/interfaces/ps-server-page.js +2 -0
  43. package/dist/interfaces/ps-server-rows-input.d.ts +13 -0
  44. package/dist/interfaces/ps-server-rows-input.js +2 -0
  45. package/dist/interfaces/ps-server-rows-result.d.ts +18 -0
  46. package/dist/interfaces/ps-server-rows-result.js +2 -0
  47. package/dist/interfaces/ps-table-cursor-paging.d.ts +12 -0
  48. package/dist/interfaces/ps-table-cursor-paging.js +2 -0
  49. package/dist/interfaces/ps-table-select-all-matching.d.ts +7 -0
  50. package/dist/interfaces/ps-table-select-all-matching.js +2 -0
  51. package/dist/interfaces/table-drag-size.d.ts +5 -0
  52. package/dist/interfaces/table-drag-size.js +2 -0
  53. package/dist/interfaces/table-reorder-item.d.ts +1 -0
  54. package/dist/interfaces/table-reorder.d.ts +1 -0
  55. package/dist/services/ps-server-rows-service.d.ts +11 -0
  56. package/dist/services/ps-server-rows-service.js +40 -0
  57. package/dist/services/ps-table-reorder-service.d.ts +2 -0
  58. package/dist/services/ps-table-reorder-service.js +12 -0
  59. package/package.json +2 -2
@@ -0,0 +1,36 @@
1
+ import { PsServerRowsConfig } from '../constants/ps-server-rows-config';
2
+ import { PsTableQueryService } from './ps-table-query-service';
3
+ export class PsServerRowsService {
4
+ static queryKey(query, search, pageSize) {
5
+ const filters = Object.entries(query.filters)
6
+ .filter(([, value]) => PsTableQueryService.isActive(value))
7
+ .sort(([left], [right]) => left.localeCompare(right));
8
+ return JSON.stringify([filters, search.trim(), query.sort, pageSize]);
9
+ }
10
+ static cacheKey(queryKey, cursor) {
11
+ return `${queryKey}|${cursor === null ? '' : cursor}`;
12
+ }
13
+ static remember(cache, key, page) {
14
+ cache.delete(key);
15
+ cache.set(key, page);
16
+ for (const oldest of cache.keys()) {
17
+ if (cache.size <= PsServerRowsConfig.cacheSize)
18
+ return;
19
+ cache.delete(oldest);
20
+ }
21
+ }
22
+ static recall(cache, key) {
23
+ const page = cache.get(key);
24
+ if (page === undefined)
25
+ return undefined;
26
+ cache.delete(key);
27
+ cache.set(key, page);
28
+ return page;
29
+ }
30
+ static preview(rows, columns, query, getSearchText) {
31
+ return PsTableQueryService.apply(rows, columns, query.filters, query.search, getSearchText, query.sort);
32
+ }
33
+ static pageCount(total, pageSize) {
34
+ return Math.max(Math.ceil(total / pageSize), 1);
35
+ }
36
+ }
@@ -33,6 +33,18 @@ export class PsTableReorderService {
33
33
  next.splice(to, 0, moved);
34
34
  return next;
35
35
  }
36
+ static measure(activator) {
37
+ const target = activator === null ? null : activator.target;
38
+ const row = target instanceof Element ? target.closest('tr') : null;
39
+ if (row === null)
40
+ return null;
41
+ const rect = row.getBoundingClientRect();
42
+ return {
43
+ columnWidths: Array.from(row.children).map((cell) => cell.getBoundingClientRect().width),
44
+ height: rect.height,
45
+ width: rect.width,
46
+ };
47
+ }
36
48
  static pointerY(event, deltaY) {
37
49
  if (event instanceof MouseEvent)
38
50
  return event.clientY + deltaY;
@@ -0,0 +1,3 @@
1
+ import type { PsServerRowsInput } from '../interfaces/ps-server-rows-input';
2
+ import type { PsServerRowsResult } from '../interfaces/ps-server-rows-result';
3
+ export declare const usePsServerRows: <RowData>({ columns, debounceMs, getSearchText, initialPage, initialQuery, isPrefetching, load, pageSize, }: PsServerRowsInput<RowData>) => PsServerRowsResult<RowData>;
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePsServerRows = void 0;
4
+ const react_1 = require("react");
5
+ const ps_server_rows_config_1 = require("../constants/ps-server-rows-config");
6
+ const ps_server_rows_service_1 = require("../services/ps-server-rows-service");
7
+ const scheduleIdle = (run) => {
8
+ if (typeof window.requestIdleCallback === 'function') {
9
+ const handle = window.requestIdleCallback(run, { timeout: ps_server_rows_config_1.PsServerRowsConfig.idleTimeoutMs });
10
+ return () => window.cancelIdleCallback(handle);
11
+ }
12
+ const timer = window.setTimeout(run, ps_server_rows_config_1.PsServerRowsConfig.idleFallbackMs);
13
+ return () => window.clearTimeout(timer);
14
+ };
15
+ const usePsServerRows = ({ columns, debounceMs = ps_server_rows_config_1.PsServerRowsConfig.debounceMs, getSearchText, initialPage = null, initialQuery, isPrefetching = true, load, pageSize, }) => {
16
+ const [query, setQuery] = (0, react_1.useState)(initialQuery);
17
+ const [search, setSearch] = (0, react_1.useState)(initialQuery.search);
18
+ const [reloadToken, setReloadToken] = (0, react_1.useState)(0);
19
+ const [isLoading, setIsLoading] = (0, react_1.useState)(initialPage === null);
20
+ const [error, setError] = (0, react_1.useState)(null);
21
+ const queryKey = ps_server_rows_service_1.PsServerRowsService.queryKey(query, search, pageSize);
22
+ const [navigation, setNavigation] = (0, react_1.useState)({
23
+ cursor: null,
24
+ pageNumber: 1,
25
+ queryKey,
26
+ });
27
+ const [entry, setEntry] = (0, react_1.useState)(() => initialPage === null
28
+ ? null
29
+ : {
30
+ key: ps_server_rows_service_1.PsServerRowsService.cacheKey(queryKey, null),
31
+ page: initialPage,
32
+ queryKey,
33
+ });
34
+ const cache = (0, react_1.useRef)(new Map());
35
+ const inflight = (0, react_1.useRef)(new Map());
36
+ const loadRef = (0, react_1.useRef)(load);
37
+ const limitRef = (0, react_1.useRef)(pageSize);
38
+ const queryRef = (0, react_1.useRef)(query);
39
+ const searchRef = (0, react_1.useRef)(search);
40
+ const isPrimed = (0, react_1.useRef)(false);
41
+ loadRef.current = load;
42
+ limitRef.current = pageSize;
43
+ queryRef.current = query;
44
+ searchRef.current = search;
45
+ if (initialPage !== null && !isPrimed.current) {
46
+ isPrimed.current = true;
47
+ ps_server_rows_service_1.PsServerRowsService.remember(cache.current, ps_server_rows_service_1.PsServerRowsService.cacheKey(queryKey, null), initialPage);
48
+ }
49
+ if (navigation.queryKey !== queryKey)
50
+ setNavigation({ cursor: null, pageNumber: 1, queryKey });
51
+ (0, react_1.useEffect)(() => {
52
+ if (query.search === search)
53
+ return;
54
+ const timer = window.setTimeout(() => setSearch(query.search), debounceMs);
55
+ return () => window.clearTimeout(timer);
56
+ }, [debounceMs, query.search, search]);
57
+ const fetchPage = (0, react_1.useCallback)((cursor, signal, key) => {
58
+ const pending = inflight.current.get(key);
59
+ if (pending !== undefined)
60
+ return pending;
61
+ const request = loadRef.current({ ...queryRef.current, search: searchRef.current }, cursor, signal, limitRef.current);
62
+ const tracked = request.then((page) => {
63
+ inflight.current.delete(key);
64
+ if (!signal.aborted)
65
+ ps_server_rows_service_1.PsServerRowsService.remember(cache.current, key, page);
66
+ return page;
67
+ }, (failure) => {
68
+ inflight.current.delete(key);
69
+ throw failure;
70
+ });
71
+ inflight.current.set(key, tracked);
72
+ return tracked;
73
+ }, []);
74
+ const generation = (0, react_1.useRef)(null);
75
+ (0, react_1.useEffect)(() => {
76
+ const controller = new AbortController();
77
+ generation.current = controller;
78
+ return () => {
79
+ controller.abort();
80
+ inflight.current.clear();
81
+ };
82
+ }, [queryKey, reloadToken]);
83
+ (0, react_1.useEffect)(() => {
84
+ const controller = generation.current;
85
+ if (controller === null)
86
+ return;
87
+ const key = ps_server_rows_service_1.PsServerRowsService.cacheKey(queryKey, navigation.cursor);
88
+ const cached = ps_server_rows_service_1.PsServerRowsService.recall(cache.current, key);
89
+ let isStale = false;
90
+ if (cached !== undefined) {
91
+ setEntry({ key, page: cached, queryKey });
92
+ setIsLoading(false);
93
+ setError(null);
94
+ return;
95
+ }
96
+ setIsLoading(true);
97
+ setError(null);
98
+ fetchPage(navigation.cursor, controller.signal, key).then((page) => {
99
+ if (isStale || controller.signal.aborted)
100
+ return;
101
+ setEntry({ key, page, queryKey });
102
+ setIsLoading(false);
103
+ }, (failure) => {
104
+ if (isStale || controller.signal.aborted)
105
+ return;
106
+ setError(failure);
107
+ setIsLoading(false);
108
+ });
109
+ return () => {
110
+ isStale = true;
111
+ };
112
+ }, [fetchPage, navigation.cursor, queryKey, reloadToken]);
113
+ const nextCursor = entry !== null && entry.queryKey === queryKey ? entry.page.nextCursor : null;
114
+ const prefetch = (0, react_1.useCallback)(() => {
115
+ const controller = generation.current;
116
+ if (controller === null || controller.signal.aborted || nextCursor === null)
117
+ return;
118
+ const key = ps_server_rows_service_1.PsServerRowsService.cacheKey(queryKey, nextCursor);
119
+ if (cache.current.has(key) || inflight.current.has(key))
120
+ return;
121
+ fetchPage(nextCursor, controller.signal, key).catch(() => undefined);
122
+ }, [fetchPage, nextCursor, queryKey]);
123
+ (0, react_1.useEffect)(() => {
124
+ if (!isPrefetching || isLoading || nextCursor === null)
125
+ return;
126
+ return scheduleIdle(prefetch);
127
+ }, [isLoading, isPrefetching, nextCursor, prefetch]);
128
+ const onQueryChange = (0, react_1.useCallback)((next) => setQuery(next), []);
129
+ const goNext = (0, react_1.useCallback)(() => {
130
+ if (nextCursor === null)
131
+ return;
132
+ setNavigation((current) => ({
133
+ ...current,
134
+ cursor: nextCursor,
135
+ pageNumber: current.pageNumber + 1,
136
+ }));
137
+ }, [nextCursor]);
138
+ const previousCursor = entry !== null && entry.queryKey === queryKey ? entry.page.prevCursor : null;
139
+ const goPrevious = (0, react_1.useCallback)(() => {
140
+ if (previousCursor === null)
141
+ return;
142
+ setNavigation((current) => ({
143
+ ...current,
144
+ cursor: previousCursor,
145
+ pageNumber: Math.max(current.pageNumber - 1, 1),
146
+ }));
147
+ }, [previousCursor]);
148
+ const reload = (0, react_1.useCallback)(() => {
149
+ cache.current.clear();
150
+ setNavigation((current) => ({ ...current, cursor: null, pageNumber: 1 }));
151
+ setReloadToken((current) => current + 1);
152
+ }, []);
153
+ const retry = (0, react_1.useCallback)(() => setReloadToken((current) => current + 1), []);
154
+ const updateRows = (0, react_1.useCallback)((update, totalDelta = 0) => {
155
+ setEntry((current) => {
156
+ if (current === null)
157
+ return current;
158
+ const page = {
159
+ ...current.page,
160
+ rows: update(current.page.rows),
161
+ total: Math.max(current.page.total + totalDelta, 0),
162
+ };
163
+ cache.current.clear();
164
+ ps_server_rows_service_1.PsServerRowsService.remember(cache.current, current.key, page);
165
+ return { ...current, page };
166
+ });
167
+ }, []);
168
+ const isCurrent = entry !== null &&
169
+ entry.queryKey === queryKey &&
170
+ entry.key === ps_server_rows_service_1.PsServerRowsService.cacheKey(queryKey, navigation.cursor);
171
+ const baseRows = (0, react_1.useMemo)(() => (entry === null ? [] : entry.page.rows), [entry]);
172
+ const isSameQuery = entry !== null && entry.queryKey === queryKey;
173
+ const rows = (0, react_1.useMemo)(() => isSameQuery ? baseRows : ps_server_rows_service_1.PsServerRowsService.preview(baseRows, columns, query, getSearchText), [baseRows, columns, getSearchText, isSameQuery, query]);
174
+ const total = entry === null ? 0 : entry.page.total;
175
+ const totalIsEstimate = entry === null ? false : entry.page.totalIsEstimate;
176
+ const isPending = isLoading || query.search !== search || !isCurrent;
177
+ const cursorPaging = (0, react_1.useMemo)(() => ({
178
+ hasNext: nextCursor !== null,
179
+ hasPrevious: previousCursor !== null,
180
+ isEstimate: totalIsEstimate,
181
+ isPending,
182
+ onNext: goNext,
183
+ onNextIntent: prefetch,
184
+ onPrevious: goPrevious,
185
+ pageNumber: navigation.pageNumber,
186
+ }), [
187
+ goNext,
188
+ goPrevious,
189
+ isPending,
190
+ navigation.pageNumber,
191
+ nextCursor,
192
+ prefetch,
193
+ previousCursor,
194
+ totalIsEstimate,
195
+ ]);
196
+ return {
197
+ cursorPaging,
198
+ error,
199
+ hasFailed: error !== null,
200
+ isPending,
201
+ onQueryChange,
202
+ pageCount: ps_server_rows_service_1.PsServerRowsService.pageCount(total, pageSize),
203
+ pageNumber: navigation.pageNumber,
204
+ query,
205
+ reload,
206
+ retry,
207
+ rows,
208
+ total,
209
+ totalIsEstimate,
210
+ updateRows,
211
+ };
212
+ };
213
+ exports.usePsServerRows = usePsServerRows;
@@ -1,4 +1,5 @@
1
1
  import { type DndContextProps } from '@dnd-kit/core';
2
+ import type { PsTableDragSize } from '../interfaces/table-drag-size';
2
3
  import type { PsTableDrop } from '../interfaces/table-drop';
3
4
  import type { PsTableReorderAnnouncements } from '../interfaces/table-reorder-announcements';
4
5
  import type { PsTableReorderItem } from '../interfaces/table-reorder-item';
@@ -15,6 +16,7 @@ export interface UsePsTableReorderInput {
15
16
  export interface PsTableReorderState {
16
17
  activeId: string | null;
17
18
  activeRunId: string | null;
19
+ activeSize: PsTableDragSize | null;
18
20
  contextProps: Omit<DndContextProps, 'children'>;
19
21
  blockedReason: string | null;
20
22
  drop: PsTableDrop | null;
@@ -12,6 +12,7 @@ const pointerThenCenter = (args) => {
12
12
  };
13
13
  const usePsTableReorder = ({ announcements: texts, enabled, instructions, items, nesting, onReorder, }) => {
14
14
  const [activeId, setActiveId] = (0, react_1.useState)(null);
15
+ const [activeSize, setActiveSize] = (0, react_1.useState)(null);
15
16
  const [drop, setDrop] = (0, react_1.useState)(null);
16
17
  const [blockedReason, setBlockedReason] = (0, react_1.useState)(null);
17
18
  const dropRef = (0, react_1.useRef)(null);
@@ -104,6 +105,7 @@ const usePsTableReorder = ({ announcements: texts, enabled, instructions, items,
104
105
  const { active, over } = event;
105
106
  const target = resolveDrop(event);
106
107
  setActiveId(null);
108
+ setActiveSize(null);
107
109
  setDrop(null);
108
110
  setBlockedReason(null);
109
111
  dropRef.current = null;
@@ -125,6 +127,7 @@ const usePsTableReorder = ({ announcements: texts, enabled, instructions, items,
125
127
  };
126
128
  return {
127
129
  activeId,
130
+ activeSize,
128
131
  blockedReason,
129
132
  activeRunId: activePlacement === undefined ? null : activePlacement.runId,
130
133
  contextProps: {
@@ -133,13 +136,17 @@ const usePsTableReorder = ({ announcements: texts, enabled, instructions, items,
133
136
  modifiers: [ps_table_reorder_service_1.PsTableReorderService.lockToVerticalAxis],
134
137
  onDragCancel: () => {
135
138
  setActiveId(null);
139
+ setActiveSize(null);
136
140
  setDrop(null);
137
141
  setBlockedReason(null);
138
142
  dropRef.current = null;
139
143
  },
140
144
  onDragEnd: handleDragEnd,
141
145
  onDragMove: nesting === undefined ? undefined : handleDragMove,
142
- onDragStart: ({ active }) => setActiveId(String(active.id)),
146
+ onDragStart: ({ active, activatorEvent }) => {
147
+ setActiveSize(ps_table_reorder_service_1.PsTableReorderService.measure(activatorEvent));
148
+ setActiveId(String(active.id));
149
+ },
143
150
  sensors,
144
151
  },
145
152
  drop,
package/dist/index.d.ts CHANGED
@@ -47,3 +47,15 @@ export * from './interfaces/table-reorder-nesting';
47
47
  export * from './interfaces/table-nesting-announcements';
48
48
  export * from './constants/ps-table-drop-placement';
49
49
  export * from './services/ps-table-reorder-service';
50
+ export * from './constants/ps-table-pagination-position';
51
+ export * from './interfaces/table-drag-size';
52
+ export * from './components/ps-select-all-matching-banner';
53
+ export * from './constants/ps-server-rows-config';
54
+ export * from './hooks/use-ps-server-rows';
55
+ export * from './interfaces/ps-server-entry';
56
+ export * from './interfaces/ps-server-page';
57
+ export * from './interfaces/ps-server-rows-input';
58
+ export * from './interfaces/ps-server-rows-result';
59
+ export * from './interfaces/ps-table-cursor-paging';
60
+ export * from './interfaces/ps-table-select-all-matching';
61
+ export * from './services/ps-server-rows-service';
package/dist/index.js CHANGED
@@ -63,3 +63,15 @@ __exportStar(require("./interfaces/table-reorder-nesting"), exports);
63
63
  __exportStar(require("./interfaces/table-nesting-announcements"), exports);
64
64
  __exportStar(require("./constants/ps-table-drop-placement"), exports);
65
65
  __exportStar(require("./services/ps-table-reorder-service"), exports);
66
+ __exportStar(require("./constants/ps-table-pagination-position"), exports);
67
+ __exportStar(require("./interfaces/table-drag-size"), exports);
68
+ __exportStar(require("./components/ps-select-all-matching-banner"), exports);
69
+ __exportStar(require("./constants/ps-server-rows-config"), exports);
70
+ __exportStar(require("./hooks/use-ps-server-rows"), exports);
71
+ __exportStar(require("./interfaces/ps-server-entry"), exports);
72
+ __exportStar(require("./interfaces/ps-server-page"), exports);
73
+ __exportStar(require("./interfaces/ps-server-rows-input"), exports);
74
+ __exportStar(require("./interfaces/ps-server-rows-result"), exports);
75
+ __exportStar(require("./interfaces/ps-table-cursor-paging"), exports);
76
+ __exportStar(require("./interfaces/ps-table-select-all-matching"), exports);
77
+ __exportStar(require("./services/ps-server-rows-service"), exports);
@@ -0,0 +1,6 @@
1
+ import type { PsServerPage } from './ps-server-page';
2
+ export interface PsServerEntry<RowData> {
3
+ key: string;
4
+ page: PsServerPage<RowData>;
5
+ queryKey: string;
6
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,7 @@
1
+ export interface PsServerPage<RowData> {
2
+ nextCursor: string | null;
3
+ prevCursor: string | null;
4
+ rows: RowData[];
5
+ total: number;
6
+ totalIsEstimate: boolean;
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,13 @@
1
+ import type { PsServerPage } from './ps-server-page';
2
+ import type { PsTableColumn } from './table-column';
3
+ import type { PsTableQuery } from './table-query';
4
+ export interface PsServerRowsInput<RowData> {
5
+ columns: PsTableColumn<RowData>[];
6
+ debounceMs?: number;
7
+ getSearchText?: (row: RowData) => string;
8
+ initialPage?: PsServerPage<RowData> | null;
9
+ initialQuery: PsTableQuery;
10
+ isPrefetching?: boolean;
11
+ load: (query: PsTableQuery, cursor: string | null, signal: AbortSignal, limit: number) => Promise<PsServerPage<RowData>>;
12
+ pageSize: number;
13
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,18 @@
1
+ import type { PsTableCursorPaging } from './ps-table-cursor-paging';
2
+ import type { PsTableQuery } from './table-query';
3
+ export interface PsServerRowsResult<RowData> {
4
+ cursorPaging: PsTableCursorPaging;
5
+ error: unknown;
6
+ hasFailed: boolean;
7
+ isPending: boolean;
8
+ onQueryChange: (query: PsTableQuery) => void;
9
+ pageCount: number;
10
+ pageNumber: number;
11
+ query: PsTableQuery;
12
+ reload: () => void;
13
+ retry: () => void;
14
+ rows: RowData[];
15
+ total: number;
16
+ totalIsEstimate: boolean;
17
+ updateRows: (update: (rows: RowData[]) => RowData[], totalDelta?: number) => void;
18
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,12 @@
1
+ export interface PsTableCursorPaging {
2
+ hasNext: boolean;
3
+ hasPrevious: boolean;
4
+ isEstimate: boolean;
5
+ isPending?: boolean;
6
+ onNext: () => void;
7
+ onNextIntent?: () => void;
8
+ onPageSizeChange?: (pageSize: number) => void;
9
+ onPrevious: () => void;
10
+ pageNumber: number;
11
+ pageSizeOptions?: number[];
12
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,7 @@
1
+ export interface PsTableSelectAllMatching {
2
+ isActive: boolean;
3
+ noun?: string;
4
+ onActivate: () => void;
5
+ onDeactivate: () => void;
6
+ total: number;
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ export interface PsTableDragSize {
2
+ columnWidths: number[];
3
+ height: number;
4
+ width: number;
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -2,5 +2,6 @@ export interface PsTableReorderItem {
2
2
  groupKey: string;
3
3
  handleLabel: string;
4
4
  id: string;
5
+ isDraggable: boolean;
5
6
  label: string;
6
7
  }
@@ -9,6 +9,7 @@ export interface PsTableReorder<RowData> {
9
9
  getHandleLabel: (rowLabel: string) => string;
10
10
  groupKey?: (row: RowData) => string;
11
11
  instructions: string;
12
+ isRowDraggable?: (row: RowData) => boolean;
12
13
  nesting?: PsTableReorderNesting<RowData>;
13
14
  onReorder?: (groupKey: string, orderedIds: string[]) => void;
14
15
  }
@@ -0,0 +1,11 @@
1
+ import type { PsServerPage } from '../interfaces/ps-server-page';
2
+ import type { PsTableColumn } from '../interfaces/table-column';
3
+ import type { PsTableQuery } from '../interfaces/table-query';
4
+ export declare class PsServerRowsService {
5
+ static queryKey(query: PsTableQuery, search: string, pageSize: number): string;
6
+ static cacheKey(queryKey: string, cursor: string | null): string;
7
+ static remember<RowData>(cache: Map<string, PsServerPage<RowData>>, key: string, page: PsServerPage<RowData>): void;
8
+ static recall<RowData>(cache: Map<string, PsServerPage<RowData>>, key: string): PsServerPage<RowData> | undefined;
9
+ static preview<RowData>(rows: RowData[], columns: PsTableColumn<RowData>[], query: PsTableQuery, getSearchText: ((row: RowData) => string) | undefined): RowData[];
10
+ static pageCount(total: number, pageSize: number): number;
11
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PsServerRowsService = void 0;
4
+ const ps_server_rows_config_1 = require("../constants/ps-server-rows-config");
5
+ const ps_table_query_service_1 = require("./ps-table-query-service");
6
+ class PsServerRowsService {
7
+ static queryKey(query, search, pageSize) {
8
+ const filters = Object.entries(query.filters)
9
+ .filter(([, value]) => ps_table_query_service_1.PsTableQueryService.isActive(value))
10
+ .sort(([left], [right]) => left.localeCompare(right));
11
+ return JSON.stringify([filters, search.trim(), query.sort, pageSize]);
12
+ }
13
+ static cacheKey(queryKey, cursor) {
14
+ return `${queryKey}|${cursor === null ? '' : cursor}`;
15
+ }
16
+ static remember(cache, key, page) {
17
+ cache.delete(key);
18
+ cache.set(key, page);
19
+ for (const oldest of cache.keys()) {
20
+ if (cache.size <= ps_server_rows_config_1.PsServerRowsConfig.cacheSize)
21
+ return;
22
+ cache.delete(oldest);
23
+ }
24
+ }
25
+ static recall(cache, key) {
26
+ const page = cache.get(key);
27
+ if (page === undefined)
28
+ return undefined;
29
+ cache.delete(key);
30
+ cache.set(key, page);
31
+ return page;
32
+ }
33
+ static preview(rows, columns, query, getSearchText) {
34
+ return ps_table_query_service_1.PsTableQueryService.apply(rows, columns, query.filters, query.search, getSearchText, query.sort);
35
+ }
36
+ static pageCount(total, pageSize) {
37
+ return Math.max(Math.ceil(total / pageSize), 1);
38
+ }
39
+ }
40
+ exports.PsServerRowsService = PsServerRowsService;
@@ -1,6 +1,7 @@
1
1
  import type { Modifier } from '@dnd-kit/core';
2
2
  import type { SortingStrategy } from '@dnd-kit/sortable';
3
3
  import { PsTableDropPlacement } from '../constants/ps-table-drop-placement';
4
+ import type { PsTableDragSize } from '../interfaces/table-drag-size';
4
5
  import type { PsTableReorderApi } from '../interfaces/table-reorder-api';
5
6
  import type { PsTableReorderPlacement } from '../interfaces/table-reorder-placement';
6
7
  import type { PsTableReorderRun } from '../interfaces/table-reorder-run';
@@ -11,6 +12,7 @@ export declare class PsTableReorderService {
11
12
  static runs<Item>(items: Item[], getKey: (item: Item) => string, getId: (item: Item) => string): PsTableReorderRun<Item>[];
12
13
  static placements<Item>(runs: PsTableReorderRun<Item>[], getId: (item: Item) => string): Map<string, PsTableReorderPlacement>;
13
14
  static move(ids: string[], activeId: string, overId: string): string[];
15
+ static measure(activator: Event | null): PsTableDragSize | null;
14
16
  static pointerY(event: Event | null, deltaY: number): number | null;
15
17
  static dropPlacement(pointerY: number | null, rect: {
16
18
  height: number;
@@ -36,6 +36,18 @@ class PsTableReorderService {
36
36
  next.splice(to, 0, moved);
37
37
  return next;
38
38
  }
39
+ static measure(activator) {
40
+ const target = activator === null ? null : activator.target;
41
+ const row = target instanceof Element ? target.closest('tr') : null;
42
+ if (row === null)
43
+ return null;
44
+ const rect = row.getBoundingClientRect();
45
+ return {
46
+ columnWidths: Array.from(row.children).map((cell) => cell.getBoundingClientRect().width),
47
+ height: rect.height,
48
+ width: rect.width,
49
+ };
50
+ }
39
51
  static pointerY(event, deltaY) {
40
52
  if (event instanceof MouseEvent)
41
53
  return event.clientY + deltaY;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pallasoft/ps-table-components",
3
- "version": "1.25.0",
3
+ "version": "1.27.0",
4
4
  "private": false,
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -78,7 +78,7 @@
78
78
  "@dnd-kit/core": "^6.3.1",
79
79
  "@dnd-kit/sortable": "^10.0.0",
80
80
  "@dnd-kit/utilities": "^3.2.2",
81
- "@pallasoft/ps-core-components": "^2.23.0",
81
+ "@pallasoft/ps-core-components": "^2.32.0",
82
82
  "@pallasoft/ps-icons": "^1.5.4",
83
83
  "@pallasoft/ps-input-components": "^1.14.0 || ^2.0.0",
84
84
  "@pallasoft/ps-motion-components": "^1.2.0",