@toolbox-web/grid 2.3.0 → 2.4.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.
- package/all.d.ts +1 -0
- package/all.js +2 -2
- package/all.js.map +1 -1
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/lib/core/grid.d.ts +2 -1
- package/lib/core/internal/aria.d.ts +13 -0
- package/lib/core/internal/diagnostics.d.ts +5 -1
- package/lib/core/internal/dom-builder.d.ts +0 -25
- package/lib/core/internal/drag-drop-registry.d.ts +66 -0
- package/lib/core/internal/render-scheduler.d.ts +9 -8
- package/lib/core/plugin/base-plugin.d.ts +23 -0
- package/lib/core/plugin/plugin-manager.d.ts +9 -0
- package/lib/core/types.d.ts +67 -46
- package/lib/features/registry.js.map +1 -1
- package/lib/features/reorder-rows.d.ts +3 -3
- package/lib/features/reorder-rows.js +1 -1
- package/lib/features/reorder-rows.js.map +1 -1
- package/lib/features/row-drag-drop.d.ts +9 -0
- package/lib/features/row-drag-drop.js +2 -0
- package/lib/features/row-drag-drop.js.map +1 -0
- package/lib/features/server-side.js.map +1 -1
- package/lib/plugins/clipboard/index.js +1 -1
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js +1 -1
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/index.js +1 -1
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/editing/index.js +1 -1
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/export/ExportPlugin.d.ts +89 -0
- package/lib/plugins/export/index.d.ts +3 -2
- package/lib/plugins/export/index.js +1 -1
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/export/types.d.ts +30 -0
- package/lib/plugins/filtering/FilteringPlugin.d.ts +15 -0
- package/lib/plugins/filtering/index.js +1 -1
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/index.js +1 -1
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/index.js +2 -2
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/index.js +1 -1
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/multi-sort/index.js +1 -1
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/index.js +1 -1
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/index.js +1 -1
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/index.js +1 -1
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/print/index.js +1 -1
- package/lib/plugins/print/index.js.map +1 -1
- package/lib/plugins/reorder-columns/index.js +1 -1
- package/lib/plugins/reorder-columns/index.js.map +1 -1
- package/lib/plugins/reorder-rows/RowReorderPlugin.d.ts +14 -156
- package/lib/plugins/reorder-rows/index.d.ts +10 -4
- package/lib/plugins/reorder-rows/index.js +1 -1
- package/lib/plugins/reorder-rows/index.js.map +1 -1
- package/lib/plugins/reorder-rows/types.d.ts +9 -86
- package/lib/plugins/responsive/index.js +1 -1
- package/lib/plugins/responsive/index.js.map +1 -1
- package/lib/plugins/row-drag-drop/RowDragDropPlugin.d.ts +146 -0
- package/lib/plugins/row-drag-drop/index.d.ts +9 -0
- package/lib/plugins/row-drag-drop/index.js +2 -0
- package/lib/plugins/row-drag-drop/index.js.map +1 -0
- package/lib/plugins/row-drag-drop/types.d.ts +276 -0
- package/lib/plugins/selection/index.js +1 -1
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/server-side/ServerSidePlugin.d.ts +13 -0
- package/lib/plugins/server-side/datasource-types.d.ts +54 -7
- package/lib/plugins/server-side/datasource.d.ts +10 -2
- package/lib/plugins/server-side/index.d.ts +1 -1
- package/lib/plugins/server-side/index.js +1 -1
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/server-side/types.d.ts +1 -1
- package/lib/plugins/shared/drag-drop-protocol.d.ts +98 -0
- package/lib/plugins/tooltip/index.js +1 -1
- package/lib/plugins/tooltip/index.js.map +1 -1
- package/lib/plugins/tree/TreePlugin.d.ts +19 -6
- package/lib/plugins/tree/index.js +1 -1
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/undo-redo/index.js +1 -1
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js +1 -1
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +1 -1
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +1 -1
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/export.umd.js +1 -1
- package/umd/plugins/export.umd.js.map +1 -1
- package/umd/plugins/filtering.umd.js +1 -1
- package/umd/plugins/filtering.umd.js.map +1 -1
- package/umd/plugins/reorder-rows.umd.js +1 -1
- package/umd/plugins/reorder-rows.umd.js.map +1 -1
- package/umd/plugins/row-drag-drop.umd.js +2 -0
- package/umd/plugins/row-drag-drop.umd.js.map +1 -0
- package/umd/plugins/selection.umd.js +1 -1
- package/umd/plugins/selection.umd.js.map +1 -1
- package/umd/plugins/server-side.umd.js +1 -1
- package/umd/plugins/server-side.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +1 -1
- package/umd/plugins/tree.umd.js.map +1 -1
|
@@ -67,6 +67,13 @@ export declare class ServerSidePlugin extends BaseGridPlugin<ServerSideConfig> {
|
|
|
67
67
|
private infiniteScrollMode;
|
|
68
68
|
private loadedBlocks;
|
|
69
69
|
private loadingBlocks;
|
|
70
|
+
/**
|
|
71
|
+
* Per-block AbortControllers for in-flight requests. Aborted when a block
|
|
72
|
+
* is superseded (sort/filter change, refresh, purgeCache, detach) so data
|
|
73
|
+
* sources that honor `params.signal` (e.g. `fetch`, RxJS via `fromObservable`)
|
|
74
|
+
* can cancel the underlying network call.
|
|
75
|
+
*/
|
|
76
|
+
private blockControllers;
|
|
70
77
|
private lastRequestId;
|
|
71
78
|
private scrollDebounceTimer?;
|
|
72
79
|
/** Persistent node array with stable placeholder references to avoid unnecessary DOM rebuilds. */
|
|
@@ -75,6 +82,12 @@ export declare class ServerSidePlugin extends BaseGridPlugin<ServerSideConfig> {
|
|
|
75
82
|
attach(grid: import('../../core/plugin/base-plugin').GridElement): void;
|
|
76
83
|
/** @internal */
|
|
77
84
|
detach(): void;
|
|
85
|
+
/**
|
|
86
|
+
* Abort all in-flight block requests. Called when the plugin tears down,
|
|
87
|
+
* the data source is replaced, the cache is purged, or the sort/filter
|
|
88
|
+
* model changes (the previously loaded block coordinates no longer apply).
|
|
89
|
+
*/
|
|
90
|
+
private abortAllBlocks;
|
|
78
91
|
/**
|
|
79
92
|
* Build enrichment params by querying sort/filter models from loaded plugins.
|
|
80
93
|
*
|
|
@@ -23,6 +23,17 @@ export interface GetRowsParams extends DataRequestModel {
|
|
|
23
23
|
startNode: number;
|
|
24
24
|
/** Zero-based index of the last node to fetch (exclusive). `endNode - startNode` equals the block size. */
|
|
25
25
|
endNode: number;
|
|
26
|
+
/**
|
|
27
|
+
* Cancellation signal for the request. The grid aborts the signal when:
|
|
28
|
+
* - a newer request supersedes the same block (sort/filter change, refresh, purgeCache)
|
|
29
|
+
* - the plugin detaches or the grid disconnects
|
|
30
|
+
*
|
|
31
|
+
* Pass it to `fetch(url, { signal })` (native), an `AbortController.signal` consumer,
|
|
32
|
+
* or via the `fromObservable` helper in `@toolbox-web/grid-angular/features/server-side`
|
|
33
|
+
* to translate it to RxJS `takeUntil`. Data sources that ignore `signal` keep working
|
|
34
|
+
* — the only consequence is that superseded HTTP requests still complete on the wire.
|
|
35
|
+
*/
|
|
36
|
+
signal: AbortSignal;
|
|
26
37
|
}
|
|
27
38
|
/**
|
|
28
39
|
* Result returned from {@link ServerSideDataSource.getRows}.
|
|
@@ -84,6 +95,27 @@ export interface GetChildRowsParams extends DataRequestModel {
|
|
|
84
95
|
export interface GetChildRowsResult<TRow = unknown> {
|
|
85
96
|
rows: TRow[];
|
|
86
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Minimal Subscribable contract used by {@link ServerSideDataSource.getRows} when
|
|
100
|
+
* an Observable-based data source is preferred over a `Promise`. Matches the
|
|
101
|
+
* shape of RxJS `Observable` and the TC39 Observable proposal — any value that
|
|
102
|
+
* exposes a `.subscribe(observer)` method returning an unsubscribable handle
|
|
103
|
+
* works without a runtime dependency on RxJS.
|
|
104
|
+
*
|
|
105
|
+
* The plugin subscribes once, expects exactly one `next` (the result), and
|
|
106
|
+
* tears the subscription down on `complete`, `error`, or when the request is
|
|
107
|
+
* superseded (`AbortSignal` fires) — which is what causes Angular `HttpClient`
|
|
108
|
+
* to cancel the underlying XHR.
|
|
109
|
+
*/
|
|
110
|
+
export interface Subscribable<T> {
|
|
111
|
+
subscribe(observer: {
|
|
112
|
+
next?(value: T): void;
|
|
113
|
+
error?(err: unknown): void;
|
|
114
|
+
complete?(): void;
|
|
115
|
+
}): {
|
|
116
|
+
unsubscribe(): void;
|
|
117
|
+
};
|
|
118
|
+
}
|
|
87
119
|
/**
|
|
88
120
|
* Unified data source contract for server-side data loading.
|
|
89
121
|
*
|
|
@@ -91,6 +123,11 @@ export interface GetChildRowsResult<TRow = unknown> {
|
|
|
91
123
|
* or any asynchronous provider. The grid calls `getRows()` whenever it needs
|
|
92
124
|
* a new block of rows (on initial load, scroll, sort change, or filter change).
|
|
93
125
|
*
|
|
126
|
+
* `getRows` may return either a `Promise` (e.g. `fetch(url, { signal }).then(...)`)
|
|
127
|
+
* or a {@link Subscribable} (e.g. an Angular `HttpClient` observable). With a
|
|
128
|
+
* Subscribable, the grid unsubscribes on supersede, which natively cancels the
|
|
129
|
+
* underlying request — no need to wire `params.signal` into anything.
|
|
130
|
+
*
|
|
94
131
|
* Optionally implement `getChildRows` for on-demand child data (tree children,
|
|
95
132
|
* group rows, detail panels, etc.). If child data is already embedded in
|
|
96
133
|
* parent rows (e.g. tree nodes with inline `children` arrays), this method
|
|
@@ -98,17 +135,23 @@ export interface GetChildRowsResult<TRow = unknown> {
|
|
|
98
135
|
*
|
|
99
136
|
* @example
|
|
100
137
|
* ```typescript
|
|
138
|
+
* // Promise / fetch
|
|
101
139
|
* const dataSource: ServerSideDataSource = {
|
|
102
140
|
* async getRows(params) {
|
|
103
|
-
* const res = await fetch(`/api/data?start=${params.startNode}&end=${params.endNode}
|
|
141
|
+
* const res = await fetch(`/api/data?start=${params.startNode}&end=${params.endNode}`, {
|
|
142
|
+
* signal: params.signal,
|
|
143
|
+
* });
|
|
104
144
|
* const data = await res.json();
|
|
105
145
|
* return { rows: data.items, totalNodeCount: data.total };
|
|
106
146
|
* },
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
147
|
+
* };
|
|
148
|
+
*
|
|
149
|
+
* // Angular HttpClient (Observable)
|
|
150
|
+
* const dataSource: ServerSideDataSource = {
|
|
151
|
+
* getRows: (params) =>
|
|
152
|
+
* this.http
|
|
153
|
+
* .get<{ items: unknown[]; total: number }>('/api/data', { params: toHttpParams(params) })
|
|
154
|
+
* .pipe(map((d) => ({ rows: d.items, totalNodeCount: d.total }))),
|
|
112
155
|
* };
|
|
113
156
|
* ```
|
|
114
157
|
*/
|
|
@@ -120,8 +163,12 @@ export interface ServerSideDataSource<TRow = unknown> {
|
|
|
120
163
|
* Before calling this, ServerSide queries loaded plugins for their
|
|
121
164
|
* current state (sort model, filter model, etc.) and passes it
|
|
122
165
|
* through in the params.
|
|
166
|
+
*
|
|
167
|
+
* Return either a `Promise<GetRowsResult>` or a {@link Subscribable}
|
|
168
|
+
* (Observable). For Subscribables, unsubscription on supersede is what
|
|
169
|
+
* cancels the underlying request.
|
|
123
170
|
*/
|
|
124
|
-
getRows(params: GetRowsParams): Promise<GetRowsResult<TRow>>;
|
|
171
|
+
getRows(params: GetRowsParams): Promise<GetRowsResult<TRow>> | Subscribable<GetRowsResult<TRow>>;
|
|
125
172
|
/**
|
|
126
173
|
* Fetch child rows for a parent context.
|
|
127
174
|
* Called when a plugin queries `datasource:fetch-children`.
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
import { GetRowsParams, GetRowsResult, ServerSideDataSource } from './datasource-types';
|
|
1
|
+
import { GetRowsParams, GetRowsResult, ServerSideDataSource, Subscribable } from './datasource-types';
|
|
2
2
|
export declare function getBlockNumber(nodeIndex: number, blockSize: number): number;
|
|
3
3
|
export declare function getBlockRange(blockNumber: number, blockSize: number): {
|
|
4
4
|
start: number;
|
|
5
5
|
end: number;
|
|
6
6
|
};
|
|
7
7
|
export declare function getRequiredBlocks(startNode: number, endNode: number, blockSize: number): number[];
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Bridge a `Promise | Subscribable` getRows return value into a single
|
|
10
|
+
* `Promise<GetRowsResult>`. For Subscribables, abort triggers `unsubscribe()`
|
|
11
|
+
* so the underlying request (e.g. Angular `HttpClient` XHR) is cancelled.
|
|
12
|
+
* Promise sources should pass `signal` to `fetch` themselves — we still reject
|
|
13
|
+
* on abort either way so the plugin's abort path is consistent.
|
|
14
|
+
*/
|
|
15
|
+
export declare function toResultPromise<T>(source: Promise<T> | Subscribable<T>, signal: AbortSignal): Promise<T>;
|
|
16
|
+
export declare function loadBlock(dataSource: ServerSideDataSource, blockNumber: number, blockSize: number, params: Partial<GetRowsParams>, signal: AbortSignal): Promise<GetRowsResult>;
|
|
9
17
|
export declare function getRowFromCache(nodeIndex: number, blockSize: number, loadedBlocks: Map<number, unknown[]>): unknown | undefined;
|
|
10
18
|
export declare function isBlockLoaded(blockNumber: number, loadedBlocks: Map<number, unknown[]>): boolean;
|
|
11
19
|
export declare function isBlockLoading(blockNumber: number, loadingBlocks: Set<number>): boolean;
|
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
* @module Plugins/Server-Side
|
|
6
6
|
*/
|
|
7
7
|
export { ServerSidePlugin } from './ServerSidePlugin';
|
|
8
|
-
export type { DataRequestModel, DataSourceChildrenDetail, DataSourceDataDetail, DataSourceErrorDetail, DataSourceLoadingDetail, FetchChildrenQuery, GetChildRowsParams, GetChildRowsResult, GetRowsParams, GetRowsResult, ServerSideConfig, ServerSideDataSource, ViewportMappingQuery, ViewportMappingResponse
|
|
8
|
+
export type { DataRequestModel, DataSourceChildrenDetail, DataSourceDataDetail, DataSourceErrorDetail, DataSourceLoadingDetail, FetchChildrenQuery, GetChildRowsParams, GetChildRowsResult, GetRowsParams, GetRowsResult, ServerSideConfig, ServerSideDataSource, Subscribable, ViewportMappingQuery, ViewportMappingResponse } from './types';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function t(t,e){return`[tbw-grid${t?`#${t}`:""}${e?`:${e}`:""}]`}const e="TBW140";function o(e,o,r,i){return`${t(r,i)} ${e}: ${o}\n\n → More info: ${function(t){return`https://toolboxjs.com/grid/errors#${t.toLowerCase()}`}(e)}`}function r(t,e,r,i){console.debug(o(t,e,r,i))}function i(t,e,r,i){console.error(o(t,e,r,i))}const s='<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>',n={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:s,filterActive:s,print:"🖨️"},a="__otorp__|__retteGenifed__|__retteSenifed__|rotcurtsnoc|wodniw|sihTlabolg|labolg|ssecorp|noitcnuF|tropmi|lave|tcelfeR|yxorP|rorrE|stnemugra|tnemucod|noitacol|eikooc|egarotSlacol|egarotSnoisses|BDdexedni|hctef|tseuqeRpttHLMX|tekcoSbeW|rekroW|rekroWderahS|rekroWecivreS|renepo|tnerap|pot|semarf|fles".split("|").map(t=>t.split("").reverse().join(""));new RegExp(`__(proto|defineGetter|defineSetter)|${a.slice(3).join("|")}|this\\b`);const d=new Set("script|iframe|object|embed|form|input|button|textarea|select|link|meta|base|style|template|slot|portal|frame|frameset|applet|noscript|noembed|plaintext|xmp|listing".split("|")),l=/^on\w+$/i,c=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),u=/^\s*(javascript|vbscript|data|blob):/i;function h(t){if(!t||"string"!=typeof t)return"";if(-1===t.indexOf("<"))return t;const e=document.createElement("template");return e.innerHTML=t,function(t){const e=[],o=t.querySelectorAll("*");for(const r of o){const t=r.tagName.toLowerCase();if(d.has(t)){e.push(r);continue}if("svg"===t||"http://www.w3.org/2000/svg"===r.namespaceURI){if(Array.from(r.attributes).some(t=>l.test(t.name)||"href"===t.name||"xlink:href"===t.name)){e.push(r);continue}}const o=[];for(const e of r.attributes){const t=e.name.toLowerCase();l.test(t)?o.push(e.name):(c.has(t)&&u.test(e.value)||"style"===t&&/expression\s*\(|javascript:|behavior\s*:/i.test(e.value))&&o.push(e.name)}o.forEach(t=>r.removeAttribute(t))}e.forEach(t=>t.remove())}(e.content),e.innerHTML}class g{static dependencies;static manifest;aliases;version="undefined"!=typeof __GRID_VERSION__?__GRID_VERSION__:"dev";styles;cellRenderers;headerRenderers;cellEditors;grid;config;userConfig;#t;get defaultConfig(){return{}}constructor(t={}){this.userConfig=t}attach(t){this.#t?.abort(),this.#t=new AbortController,this.grid=t,this.config={...this.defaultConfig,...this.userConfig}}detach(){this.#t?.abort(),this.#t=void 0}getPlugin(t){return this.grid?.getPlugin(t)}emit(t,e){this.grid?.dispatchEvent?.(new CustomEvent(t,{detail:e,bubbles:!0}))}emitCancelable(t,e){const o=new CustomEvent(t,{detail:e,bubbles:!0,cancelable:!0});return this.grid?.dispatchEvent?.(o),o.defaultPrevented}on(t,e){this.grid?._pluginManager?.subscribe(this,t,e)}off(t){this.grid?._pluginManager?.unsubscribe(this,t)}emitPluginEvent(t,e){this.grid?._pluginManager?.emitPluginEvent(t,e)}broadcast(t,e){this.emitPluginEvent(t,e),this.emit(t,e)}requestRender(){this.grid?.requestRender?.()}requestColumnsRender(){this.grid?.requestColumnsRender?.()}requestRenderWithFocus(){this.grid?.requestRenderWithFocus?.()}requestAfterRender(){this.grid?.requestAfterRender?.()}requestVirtualRefresh(){this.grid?.requestVirtualRefresh?.()}get rows(){return this.grid?.rows??[]}get sourceRows(){return this.grid?.sourceRows??[]}get columns(){return this.grid?.columns??[]}get visibleColumns(){return this.grid?._visibleColumns??[]}get gridElement(){return this.grid?._hostElement}get disconnectSignal(){return this.#t?.signal??this.grid?.disconnectSignal}get gridIcons(){const t=this.grid?.gridConfig?.icons??{};return{...n,...t}}get isAnimationEnabled(){const t=this.grid?.effectiveConfig?.animation?.mode??"reduced-motion";if(!1===t||"off"===t)return!1;if(!0===t||"on"===t)return!0;const e=this.gridElement;if(e){return"0"!==getComputedStyle(e).getPropertyValue("--tbw-animation-enabled").trim()}return!0}get animationDuration(){const t=this.gridElement;if(t){const e=getComputedStyle(t).getPropertyValue("--tbw-animation-duration").trim(),o=parseInt(e,10);if(!isNaN(o))return o}return 200}setIcon(t,e,o){t.dataset.icon=e.replace(/([A-Z])/g,"-$1").toLowerCase(),"collapse"===e?t.dataset.expanded="":"expand"===e&&delete t.dataset.expanded;const r=this.#e(e,o);void 0!==r?"string"==typeof r?t.innerHTML=h(r):r instanceof HTMLElement&&(t.innerHTML="",t.appendChild(r.cloneNode(!0))):t.innerHTML=""}#e(t,e){return void 0!==e?e:this.grid?.gridConfig?.icons?.[t]}updateSortIndicator(t,e){t.querySelector('[part~="sort-indicator"], .sort-indicator')?.remove();const o=document.createElement("span");o.setAttribute("part","sort-indicator"),o.className="sort-indicator",e?(t.setAttribute("aria-sort","asc"===e?"ascending":"descending"),t.setAttribute("data-sort",e),this.setIcon(o,"asc"===e?"sortAsc":"sortDesc")):(t.setAttribute("aria-sort","none"),t.removeAttribute("data-sort"),this.setIcon(o,"sortNone"));const r=t.querySelector(".tbw-filter-btn")??t.querySelector(".resize-handle");return r?t.insertBefore(o,r):t.appendChild(o),o}warn(e,r){void 0!==r?console.warn(o(e,r,this.gridElement.id,this.name)):console.warn(`${t(this.gridElement.id,this.name)} ${e}`)}throwDiagnostic(t,e){throw new Error(o(t,e,this.gridElement.id,this.name))}}const f=/* @__PURE__ */new WeakMap;function m(t,e,o=-1){if(!e.valueAccessor)return t?.[e.field];if("object"!=typeof t||null===t)return e.valueAccessor({row:t,column:e,rowIndex:o});const r=e.field;let i=f.get(t);if(i){if(i.has(r))return i.get(r)}else i=/* @__PURE__ */new Map,f.set(t,i);const s=e.valueAccessor({row:t,column:e,rowIndex:o});return i.set(r,s),s}function p(t,e,o){const r=o.find(t=>t.field===e.field),i=r?.sortComparator,{field:s,direction:n}=e,a=[...t];return i?r?.valueAccessor?a.sort((t,e)=>i(m(t,r),m(e,r),t,e)*n):a.sort((t,e)=>i(t[s],e[s],t,e)*n):r?.valueAccessor?function(t,e,o){t.sort((t,r)=>{const i=b(t,r);if(0!==i)return i;const s=m(t,e),n=m(r,e);return null==s&&null==n?0:null==s?-o:null==n||s>n?o:s<n?-o:0})}(a,r,n):function(t,e,o){t.sort((t,r)=>{const i=b(t,r);if(0!==i)return i;const s=t[e],n=r[e];return null==s&&null==n?0:null==s?-o:null==n||s>n?o:s<n?-o:0})}(a,s,n),a}function b(t,e){const o=!0===t?.__loading;return o===(!0===e?.__loading)?0:o?1:-1}function w(t,e){return Math.floor(t/e)}async function S(t,e,o,r){const i=function(t,e){return{start:t*e,end:(t+1)*e}}(e,o);return t.getRows({startNode:i.start,endNode:i.end,sortModel:r.sortModel,filterModel:r.filterModel})}function C(t,e,o){const r=w(t,e),i=o.get(r);if(!i)return;return i[t%e]}class v extends g{static manifest={modifiesRowStructure:!0,hookPriority:{processRows:-10},incompatibleWith:[{name:"pivot",reason:"PivotPlugin requires the full dataset to compute aggregations. ServerSidePlugin lazy-loads rows in blocks, so pivot aggregation cannot be performed client-side."}],events:[{type:"datasource:data",description:"Root data page/block loaded"},{type:"datasource:children",description:"Child data loaded for a parent context"},{type:"datasource:loading",description:"Loading state changed"},{type:"datasource:error",description:"Fetch operation failed"}],queries:[{type:"datasource:fetch-children",description:"Request child rows for a parent context"},{type:"datasource:is-active",description:"Check if ServerSide plugin has an active data source"}]};name="serverSide";get defaultConfig(){return{pageSize:100,cacheBlockSize:100,maxConcurrentRequests:2}}dataSource=null;totalNodeCount=0;infiniteScrollMode=!1;loadedBlocks=/* @__PURE__ */new Map;loadingBlocks=/* @__PURE__ */new Set;lastRequestId=0;scrollDebounceTimer;managedNodes=[];attach(t){super.attach(t),this.on("sort-change",()=>{"local"===this.config.sortMode?this.requestRender():this.onModelChange()}),this.on("filter-change",()=>{"local"===this.config.filterMode?this.requestRender():this.onModelChange()}),this.config.dataSource&&this.setDataSource(this.config.dataSource)}detach(){this.dataSource=null,this.totalNodeCount=0,this.infiniteScrollMode=!1,this.loadedBlocks.clear(),this.loadingBlocks.clear(),this.managedNodes=[],this.lastRequestId=0,this.scrollDebounceTimer&&(clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=void 0)}getEnrichmentParams(){const t="local"===this.config.sortMode,e="local"===this.config.filterMode,o=t?void 0:this.grid?.query?.("sort:get-model",null),r=e?void 0:this.grid?.query?.("filter:get-model",null);let i=o?.[0];const s=this.grid;if(!t&&!i&&s?._sortState){const{field:t,direction:e}=s._sortState;i=[{field:t,direction:1===e?"asc":"desc"}]}return{sortModel:i,filterModel:r?.[0]}}getViewportMapping(t,e){const o={viewportStart:t,viewportEnd:e},r=this.grid?.query?.("datasource:viewport-mapping",o);return r?.[0]?r[0]:{startNode:t,endNode:e,totalLoadedNodes:this.totalNodeCount}}onModelChange(){this.dataSource&&(this.loadedBlocks.clear(),this.loadingBlocks.clear(),this.managedNodes=[],this.totalNodeCount=0,this.infiniteScrollMode=!1,this.requestRender(),this.loadRequiredBlocks())}applyServerResult(t,e,o){void 0!==t.lastNode?(this.totalNodeCount=t.lastNode+1,this.infiniteScrollMode=!1):-1===t.totalNodeCount?this.infiniteScrollMode=!0:(this.totalNodeCount=t.totalNodeCount,this.infiniteScrollMode=!1),this.infiniteScrollMode&&t.rows.length<o&&(this.totalNodeCount=e*o+t.rows.length,this.infiniteScrollMode=!1)}getInfiniteScrollEstimate(t){let e=0;for(const[o,r]of this.loadedBlocks){const i=o*t+r.length;i>e&&(e=i)}return e+t}loadRequiredBlocks(){if(!this.dataSource)return;const t=this.grid,o=this.config.cacheBlockSize??100,s=this.getViewportMapping(t._virtualization.start,t._virtualization.end),n=Math.max(0,this.config.loadThreshold??0),a=Math.max(0,s.startNode-n),d=this.totalNodeCount>0?this.totalNodeCount:1/0,l=Math.min(d,s.endNode+n);if(l<=a)return;const c=function(t,e,o){const r=w(t,o),i=w(e-1,o),s=[];for(let n=r;n<=i;n++)s.push(n);return s}(a,l,o),u=this.getEnrichmentParams(),h=this.grid?.getAttribute?.("id")??void 0;for(const g of c)if(!this.loadedBlocks.has(g)&&!this.loadingBlocks.has(g)){if(this.loadingBlocks.size>=(this.config.maxConcurrentRequests??2)){r("TBW143","Concurrent request limit reached, deferring block load",h);break}this.loadingBlocks.add(g),this.broadcast("datasource:loading",{loading:!0}),S(this.dataSource,g,o,u).then(t=>{this.loadedBlocks.set(g,t.rows);const e=this.managedNodes.length;this.applyServerResult(t,g,o),this.loadingBlocks.delete(g);const r=g*o;for(let o=0;o<t.rows.length;o++)r+o<this.managedNodes.length&&(this.managedNodes[r+o]=t.rows[o]);const i={rows:t.rows,totalNodeCount:t.totalNodeCount,startNode:r,endNode:r+t.rows.length,claimed:!1};this.broadcast("datasource:data",i),0===this.loadingBlocks.size&&this.broadcast("datasource:loading",{loading:!1});0===e||this.managedNodes.length<(Number.isFinite(this.totalNodeCount)?this.totalNodeCount:0)?this.requestRender():this.requestVirtualRefresh(),this.loadRequiredBlocks()}).catch(t=>{this.loadingBlocks.delete(g);const o=t instanceof Error?t:new Error(String(t));i(e,`getRows() failed: ${o.message}`,h),this.broadcast("datasource:error",{error:o}),0===this.loadingBlocks.size&&this.broadcast("datasource:loading",{loading:!1})})}}processRows(t){if(!this.dataSource)return[...t];const e=this.config.cacheBlockSize??100,o=this.infiniteScrollMode?this.getInfiniteScrollEstimate(e):Number.isFinite(this.totalNodeCount)&&this.totalNodeCount>=0?this.totalNodeCount:0;for(;this.managedNodes.length<o;){const t=this.managedNodes.length;this.managedNodes.push({__loading:!0,__index:t})}this.managedNodes.length=o;for(let i=0;i<o;i++){const t=C(i,e,this.loadedBlocks);t&&(this.managedNodes[i]=t)}const r=this.grid;if("local"===this.config.sortMode&&r?._sortState){const t=r._columns??[];return p(this.managedNodes,r._sortState,t)}return this.managedNodes}onScroll(t){this.dataSource&&(this.loadRequiredBlocks(),this.scrollDebounceTimer&&clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=setTimeout(()=>{this.loadRequiredBlocks()},100))}handleQuery(t){switch(t.type){case"datasource:is-active":return null!=this.dataSource;case"datasource:fetch-children":{const{context:e}=t.context;return void this.fetchChildren(e)}}}fetchChildren(t){if(!this.dataSource)return;const e=this.grid?.getAttribute?.("id")??void 0;if(!this.dataSource.getChildRows)return void function(t,e,r,i){console.warn(o(t,e,r,i))}("TBW142",`Plugin "${t.source}" requested child rows but getChildRows() is not implemented on the dataSource`,e);const r=this.getEnrichmentParams();this.broadcast("datasource:loading",{loading:!0,context:t}),this.dataSource.getChildRows({context:t,sortModel:r.sortModel,filterModel:r.filterModel}).then(e=>{const o={rows:e.rows,context:t,claimed:!1};this.broadcast("datasource:children",o),this.broadcast("datasource:loading",{loading:!1,context:t})}).catch(o=>{const r=o instanceof Error?o:new Error(String(o));i("TBW141",`getChildRows() failed: ${r.message}`,e),this.broadcast("datasource:error",{error:r,context:t}),this.broadcast("datasource:loading",{loading:!1,context:t})})}setDataSource(t){this.dataSource=t,this.loadedBlocks.clear(),this.loadingBlocks.clear(),this.managedNodes=[],this.totalNodeCount=0,this.infiniteScrollMode=!1;const o=this.config.cacheBlockSize??100,r=this.getEnrichmentParams(),s=this.grid?.getAttribute?.("id")??void 0;this.broadcast("datasource:loading",{loading:!0}),S(t,0,o,r).then(t=>{this.loadedBlocks.set(0,t.rows),this.applyServerResult(t,0,o);const e={rows:t.rows,totalNodeCount:t.totalNodeCount,startNode:0,endNode:t.rows.length,claimed:!1};this.broadcast("datasource:data",e),this.broadcast("datasource:loading",{loading:!1}),this.requestRender(),(this.config.loadThreshold??0)>0&&this.loadRequiredBlocks()}).catch(t=>{const o=t instanceof Error?t:new Error(String(t));i(e,`getRows() failed: ${o.message}`,s),this.broadcast("datasource:error",{error:o}),this.broadcast("datasource:loading",{loading:!1})})}refresh(){if(!this.dataSource)return;const t=this.dataSource;this.loadedBlocks.clear(),this.loadingBlocks.clear(),this.managedNodes=[],this.totalNodeCount=0,this.infiniteScrollMode=!1,this.setDataSource(t)}purgeCache(){this.loadedBlocks.clear(),this.managedNodes=[]}getTotalNodeCount(){return this.totalNodeCount}getTotalRowCount(){return this.totalNodeCount}isNodeLoaded(t){const e=w(t,this.config.cacheBlockSize??100);return this.loadedBlocks.has(e)}isRowLoaded(t){return this.isNodeLoaded(t)}getLoadedBlockCount(){return this.loadedBlocks.size}}export{v as ServerSidePlugin};
|
|
1
|
+
function t(t,e){return`[tbw-grid${t?`#${t}`:""}${e?`:${e}`:""}]`}const e="TBW140";function o(e,o,r,s){return`${t(r,s)} ${e}: ${o}\n\n → More info: ${function(t){return`https://toolboxjs.com/grid/errors#${t.toLowerCase()}`}(e)}`}function r(t,e,r,s){console.debug(o(t,e,r,s))}function s(t,e,r,s){console.error(o(t,e,r,s))}const i={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:"",filterActive:"",print:"🖨️"},n="__otorp__|__retteGenifed__|__retteSenifed__|rotcurtsnoc|wodniw|sihTlabolg|labolg|ssecorp|noitcnuF|tropmi|lave|tcelfeR|yxorP|rorrE|stnemugra|tnemucod|noitacol|eikooc|egarotSlacol|egarotSnoisses|BDdexedni|hctef|tseuqeRpttHLMX|tekcoSbeW|rekroW|rekroWderahS|rekroWecivreS|renepo|tnerap|pot|semarf|fles".split("|").map(t=>t.split("").reverse().join(""));new RegExp(`__(proto|defineGetter|defineSetter)|${n.slice(3).join("|")}|this\\b`);const a=new Set("script|iframe|object|embed|form|input|button|textarea|select|link|meta|base|style|template|slot|portal|frame|frameset|applet|noscript|noembed|plaintext|xmp|listing".split("|")),l=/^on\w+$/i,d=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),c=/^\s*(javascript|vbscript|data|blob):/i;function u(t){if(!t||"string"!=typeof t)return"";if(-1===t.indexOf("<"))return t;const e=document.createElement("template");return e.innerHTML=t,function(t){const e=[],o=t.querySelectorAll("*");for(const r of o){const t=r.tagName.toLowerCase();if(a.has(t)){e.push(r);continue}if("svg"===t||"http://www.w3.org/2000/svg"===r.namespaceURI){if(Array.from(r.attributes).some(t=>l.test(t.name)||"href"===t.name||"xlink:href"===t.name)){e.push(r);continue}}const o=[];for(const e of r.attributes){const t=e.name.toLowerCase();l.test(t)?o.push(e.name):(d.has(t)&&c.test(e.value)||"style"===t&&/expression\s*\(|javascript:|behavior\s*:/i.test(e.value))&&o.push(e.name)}o.forEach(t=>r.removeAttribute(t))}e.forEach(t=>t.remove())}(e.content),e.innerHTML}class h{static dependencies;static manifest;aliases;version="undefined"!=typeof __GRID_VERSION__?__GRID_VERSION__:"dev";styles;cellRenderers;headerRenderers;cellEditors;grid;config;userConfig;#t;get defaultConfig(){return{}}constructor(t={}){this.userConfig=t}mergeConfigsFrom(t){if(0===t.length)return;const e={...this.userConfig},r={};for(const o of Object.keys(e))r[o]=this;for(const s of t){const t=s.userConfig;for(const[i,n]of Object.entries(t)){if(void 0===n)continue;if(!(i in e)){e[i]=n,r[i]=s;continue}if(e[i]===n)continue;const t=r[i]?.constructor.name??this.constructor.name,a=s.constructor.name,l=o("TBW025",`Cannot merge plugin configs for "${this.name}": conflicting value for "${i}" supplied by both ${t} and ${a}. Pass the option on a single instance, or remove the duplicate.`,void 0,this.name);throw new Error(l)}}Object.assign(this.userConfig,e)}attach(t){this.#t?.abort(),this.#t=new AbortController,this.grid=t,this.config={...this.defaultConfig,...this.userConfig}}detach(){this.#t?.abort(),this.#t=void 0}getPlugin(t){return this.grid?.getPlugin(t)}emit(t,e){this.grid?.dispatchEvent?.(new CustomEvent(t,{detail:e,bubbles:!0}))}emitCancelable(t,e){const o=new CustomEvent(t,{detail:e,bubbles:!0,cancelable:!0});return this.grid?.dispatchEvent?.(o),o.defaultPrevented}on(t,e){this.grid?._pluginManager?.subscribe(this,t,e)}off(t){this.grid?._pluginManager?.unsubscribe(this,t)}emitPluginEvent(t,e){this.grid?._pluginManager?.emitPluginEvent(t,e)}broadcast(t,e){this.emitPluginEvent(t,e),this.emit(t,e)}requestRender(){this.grid?.requestRender?.()}requestColumnsRender(){this.grid?.requestColumnsRender?.()}requestRenderWithFocus(){this.grid?.requestRenderWithFocus?.()}requestAfterRender(){this.grid?.requestAfterRender?.()}requestVirtualRefresh(){this.grid?.requestVirtualRefresh?.()}get rows(){return this.grid?.rows??[]}get sourceRows(){return this.grid?.sourceRows??[]}get columns(){return this.grid?.columns??[]}get visibleColumns(){return this.grid?._visibleColumns??[]}get gridElement(){return this.grid?._hostElement}get disconnectSignal(){return this.#t?.signal??this.grid?.disconnectSignal}get gridIcons(){const t=this.grid?.gridConfig?.icons??{};return{...i,...t}}get isAnimationEnabled(){const t=this.grid?.effectiveConfig?.animation?.mode??"reduced-motion";if(!1===t||"off"===t)return!1;if(!0===t||"on"===t)return!0;const e=this.gridElement;if(e){return"0"!==getComputedStyle(e).getPropertyValue("--tbw-animation-enabled").trim()}return!0}get animationDuration(){const t=this.gridElement;if(t){const e=getComputedStyle(t).getPropertyValue("--tbw-animation-duration").trim(),o=parseInt(e,10);if(!isNaN(o))return o}return 200}setIcon(t,e,o){t.dataset.icon=e.replace(/([A-Z])/g,"-$1").toLowerCase(),"collapse"===e?t.dataset.expanded="":"expand"===e&&delete t.dataset.expanded;const r=this.#e(e,o);void 0!==r?"string"==typeof r?t.innerHTML=u(r):r instanceof HTMLElement&&(t.innerHTML="",t.appendChild(r.cloneNode(!0))):t.innerHTML=""}#e(t,e){return void 0!==e?e:this.grid?.gridConfig?.icons?.[t]}updateSortIndicator(t,e){t.querySelector('[part~="sort-indicator"], .sort-indicator')?.remove();const o=document.createElement("span");o.setAttribute("part","sort-indicator"),o.className="sort-indicator",e?(t.setAttribute("aria-sort","asc"===e?"ascending":"descending"),t.setAttribute("data-sort",e),this.setIcon(o,"asc"===e?"sortAsc":"sortDesc")):(t.setAttribute("aria-sort","none"),t.removeAttribute("data-sort"),this.setIcon(o,"sortNone"));const r=t.querySelector(".tbw-filter-btn")??t.querySelector(".resize-handle");return r?t.insertBefore(o,r):t.appendChild(o),o}warn(e,r){void 0!==r?console.warn(o(e,r,this.gridElement.id,this.name)):console.warn(`${t(this.gridElement.id,this.name)} ${e}`)}throwDiagnostic(t,e){throw new Error(o(t,e,this.gridElement.id,this.name))}}const g=/* @__PURE__ */new WeakMap;function f(t,e,o=-1){if(!e.valueAccessor)return t?.[e.field];if("object"!=typeof t||null===t)return e.valueAccessor({row:t,column:e,rowIndex:o});const r=e.field;let s=g.get(t);if(s){if(s.has(r))return s.get(r)}else s=/* @__PURE__ */new Map,g.set(t,s);const i=e.valueAccessor({row:t,column:e,rowIndex:o});return s.set(r,i),i}function m(t,e,o){const r=o.find(t=>t.field===e.field),s=r?.sortComparator,{field:i,direction:n}=e,a=[...t];return s?r?.valueAccessor?a.sort((t,e)=>s(f(t,r),f(e,r),t,e)*n):a.sort((t,e)=>s(t[i],e[i],t,e)*n):r?.valueAccessor?function(t,e,o){t.sort((t,r)=>{const s=b(t,r);if(0!==s)return s;const i=f(t,e),n=f(r,e);return null==i&&null==n?0:null==i?-o:null==n||i>n?o:i<n?-o:0})}(a,r,n):function(t,e,o){t.sort((t,r)=>{const s=b(t,r);if(0!==s)return s;const i=t[e],n=r[e];return null==i&&null==n?0:null==i?-o:null==n||i>n?o:i<n?-o:0})}(a,i,n),a}function b(t,e){const o=!0===t?.__loading;return o===(!0===e?.__loading)?0:o?1:-1}function p(t,e){return Math.floor(t/e)}function C(){return new DOMException("Aborted","AbortError")}function w(t,e,o,r,s){const i=function(t,e){return{start:t*e,end:(t+1)*e}}(e,o);return function(t,e){return e.aborted?Promise.reject(C()):"object"!=typeof(o=t)||null===o||"function"!=typeof o.subscribe||"function"==typeof o.then?new Promise((o,r)=>{const s=()=>r(C());e.addEventListener("abort",s,{once:!0}),Promise.resolve(t).then(t=>{e.removeEventListener("abort",s),o(t)},t=>{e.removeEventListener("abort",s),r(t)})}):new Promise((o,r)=>{let s=!1;const i=t.subscribe({next:t=>{s||(s=!0,o(t),i.unsubscribe())},error:t=>{s||(s=!0,r(t))},complete:()=>{s||(s=!0,r(new Error("getRows observable completed without emitting a value")))}});s||e.addEventListener("abort",()=>{s||(s=!0,i.unsubscribe(),r(C()))},{once:!0})});var o}(t.getRows({startNode:i.start,endNode:i.end,sortModel:r.sortModel,filterModel:r.filterModel,signal:s}),s)}function v(t,e,o){const r=p(t,e),s=o.get(r);if(!s)return;return s[t%e]}class S extends h{static manifest={modifiesRowStructure:!0,hookPriority:{processRows:-10},incompatibleWith:[{name:"pivot",reason:"PivotPlugin requires the full dataset to compute aggregations. ServerSidePlugin lazy-loads rows in blocks, so pivot aggregation cannot be performed client-side."}],events:[{type:"datasource:data",description:"Root data page/block loaded"},{type:"datasource:children",description:"Child data loaded for a parent context"},{type:"datasource:loading",description:"Loading state changed"},{type:"datasource:error",description:"Fetch operation failed"}],queries:[{type:"datasource:fetch-children",description:"Request child rows for a parent context"},{type:"datasource:is-active",description:"Check if ServerSide plugin has an active data source"}]};name="serverSide";get defaultConfig(){return{pageSize:100,cacheBlockSize:100,maxConcurrentRequests:2}}dataSource=null;totalNodeCount=0;infiniteScrollMode=!1;loadedBlocks=/* @__PURE__ */new Map;loadingBlocks=/* @__PURE__ */new Set;blockControllers=/* @__PURE__ */new Map;lastRequestId=0;scrollDebounceTimer;managedNodes=[];attach(t){super.attach(t),this.on("sort-change",()=>{"local"===this.config.sortMode?this.requestRender():this.onModelChange()}),this.on("filter-change",()=>{"local"===this.config.filterMode?this.requestRender():this.onModelChange()}),this.config.dataSource&&this.setDataSource(this.config.dataSource)}detach(){this.dataSource=null,this.totalNodeCount=0,this.infiniteScrollMode=!1,this.loadedBlocks.clear(),this.loadingBlocks.clear(),this.abortAllBlocks(),this.managedNodes=[],this.lastRequestId=0,this.scrollDebounceTimer&&(clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=void 0)}abortAllBlocks(){for(const t of this.blockControllers.values())t.abort();this.blockControllers.clear()}getEnrichmentParams(){const t="local"===this.config.sortMode,e="local"===this.config.filterMode,o=t?void 0:this.grid?.query?.("sort:get-model",null),r=e?void 0:this.grid?.query?.("filter:get-model",null);let s=o?.[0];const i=this.grid;if(!t&&!s&&i?._sortState){const{field:t,direction:e}=i._sortState;s=[{field:t,direction:1===e?"asc":"desc"}]}return{sortModel:s,filterModel:r?.[0]}}getViewportMapping(t,e){const o={viewportStart:t,viewportEnd:e},r=this.grid?.query?.("datasource:viewport-mapping",o);return r?.[0]?r[0]:{startNode:t,endNode:e,totalLoadedNodes:this.totalNodeCount}}onModelChange(){this.dataSource&&(this.abortAllBlocks(),this.loadedBlocks.clear(),this.loadingBlocks.clear(),this.managedNodes=[],this.totalNodeCount=0,this.infiniteScrollMode=!1,this.requestRender(),this.loadRequiredBlocks())}applyServerResult(t,e,o){void 0!==t.lastNode?(this.totalNodeCount=t.lastNode+1,this.infiniteScrollMode=!1):-1===t.totalNodeCount?this.infiniteScrollMode=!0:(this.totalNodeCount=t.totalNodeCount,this.infiniteScrollMode=!1),this.infiniteScrollMode&&t.rows.length<o&&(this.totalNodeCount=e*o+t.rows.length,this.infiniteScrollMode=!1)}getInfiniteScrollEstimate(t){let e=0;for(const[o,r]of this.loadedBlocks){const s=o*t+r.length;s>e&&(e=s)}return e+t}loadRequiredBlocks(){if(!this.dataSource)return;const t=this.grid,o=this.config.cacheBlockSize??100,i=this.getViewportMapping(t._virtualization.start,t._virtualization.end),n=Math.max(0,this.config.loadThreshold??0),a=Math.max(0,i.startNode-n),l=this.totalNodeCount>0?this.totalNodeCount:1/0,d=Math.min(l,i.endNode+n);if(d<=a)return;const c=function(t,e,o){const r=p(t,o),s=p(e-1,o),i=[];for(let n=r;n<=s;n++)i.push(n);return i}(a,d,o),u=this.getEnrichmentParams(),h=this.grid?.getAttribute?.("id")??void 0;for(const g of c){if(this.loadedBlocks.has(g)||this.loadingBlocks.has(g))continue;if(this.loadingBlocks.size>=(this.config.maxConcurrentRequests??2)){r("TBW143","Concurrent request limit reached, deferring block load",h);break}this.loadingBlocks.add(g);const t=new AbortController;this.blockControllers.set(g,t),this.broadcast("datasource:loading",{loading:!0}),w(this.dataSource,g,o,u,t.signal).then(e=>{if(this.blockControllers.delete(g),t.signal.aborted)return this.loadingBlocks.delete(g),void(0===this.loadingBlocks.size&&this.broadcast("datasource:loading",{loading:!1}));this.loadedBlocks.set(g,e.rows);const r=this.managedNodes.length;this.applyServerResult(e,g,o),this.loadingBlocks.delete(g);const s=g*o;for(let t=0;t<e.rows.length;t++)s+t<this.managedNodes.length&&(this.managedNodes[s+t]=e.rows[t]);const i={rows:e.rows,totalNodeCount:e.totalNodeCount,startNode:s,endNode:s+e.rows.length,claimed:!1};this.broadcast("datasource:data",i),0===this.loadingBlocks.size&&this.broadcast("datasource:loading",{loading:!1});0===r||this.managedNodes.length<(Number.isFinite(this.totalNodeCount)?this.totalNodeCount:0)?this.requestRender():this.requestVirtualRefresh(),this.loadRequiredBlocks()}).catch(o=>{if(this.blockControllers.delete(g),this.loadingBlocks.delete(g),t.signal.aborted)return void(0===this.loadingBlocks.size&&this.broadcast("datasource:loading",{loading:!1}));const r=o instanceof Error?o:new Error(String(o));s(e,`getRows() failed: ${r.message}`,h),this.broadcast("datasource:error",{error:r}),0===this.loadingBlocks.size&&this.broadcast("datasource:loading",{loading:!1})})}}processRows(t){if(!this.dataSource)return[...t];const e=this.config.cacheBlockSize??100,o=this.infiniteScrollMode?this.getInfiniteScrollEstimate(e):Number.isFinite(this.totalNodeCount)&&this.totalNodeCount>=0?this.totalNodeCount:0;for(;this.managedNodes.length<o;){const t=this.managedNodes.length;this.managedNodes.push({__loading:!0,__index:t})}this.managedNodes.length=o;for(let s=0;s<o;s++){const t=v(s,e,this.loadedBlocks);t&&(this.managedNodes[s]=t)}const r=this.grid;if("local"===this.config.sortMode&&r?._sortState){const t=r._columns??[],e=(r.effectiveConfig?.sortHandler??m)(this.managedNodes,r._sortState,t);return e&&"function"==typeof e.then?(e.catch(()=>{}),this.managedNodes):e}return this.managedNodes}onScroll(t){this.dataSource&&(this.loadRequiredBlocks(),this.scrollDebounceTimer&&clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=setTimeout(()=>{this.loadRequiredBlocks()},100))}handleQuery(t){switch(t.type){case"datasource:is-active":return null!=this.dataSource;case"datasource:fetch-children":{const{context:e}=t.context;return void this.fetchChildren(e)}}}fetchChildren(t){if(!this.dataSource)return;const e=this.grid?.getAttribute?.("id")??void 0;if(!this.dataSource.getChildRows)return void function(t,e,r,s){console.warn(o(t,e,r,s))}("TBW142",`Plugin "${t.source}" requested child rows but getChildRows() is not implemented on the dataSource`,e);const r=this.getEnrichmentParams();this.broadcast("datasource:loading",{loading:!0,context:t}),this.dataSource.getChildRows({context:t,sortModel:r.sortModel,filterModel:r.filterModel}).then(e=>{const o={rows:e.rows,context:t,claimed:!1};this.broadcast("datasource:children",o),this.broadcast("datasource:loading",{loading:!1,context:t})}).catch(o=>{const r=o instanceof Error?o:new Error(String(o));s("TBW141",`getChildRows() failed: ${r.message}`,e),this.broadcast("datasource:error",{error:r,context:t}),this.broadcast("datasource:loading",{loading:!1,context:t})})}setDataSource(t){this.abortAllBlocks(),this.dataSource=t,this.loadedBlocks.clear(),this.loadingBlocks.clear(),this.managedNodes=[],this.totalNodeCount=0,this.infiniteScrollMode=!1;const o=this.config.cacheBlockSize??100,r=this.getEnrichmentParams(),i=this.grid?.getAttribute?.("id")??void 0,n=new AbortController;this.blockControllers.set(0,n),this.loadingBlocks.add(0),this.broadcast("datasource:loading",{loading:!0}),w(t,0,o,r,n.signal).then(t=>{if(this.blockControllers.delete(0),this.loadingBlocks.delete(0),n.signal.aborted)return void this.broadcast("datasource:loading",{loading:!1});this.loadedBlocks.set(0,t.rows),this.applyServerResult(t,0,o);const e={rows:t.rows,totalNodeCount:t.totalNodeCount,startNode:0,endNode:t.rows.length,claimed:!1};this.broadcast("datasource:data",e),this.broadcast("datasource:loading",{loading:!1}),this.requestRender(),(this.config.loadThreshold??0)>0&&this.loadRequiredBlocks()}).catch(t=>{if(this.blockControllers.delete(0),this.loadingBlocks.delete(0),n.signal.aborted)return void this.broadcast("datasource:loading",{loading:!1});const o=t instanceof Error?t:new Error(String(t));s(e,`getRows() failed: ${o.message}`,i),this.broadcast("datasource:error",{error:o}),this.broadcast("datasource:loading",{loading:!1})})}refresh(){if(!this.dataSource)return;const t=this.dataSource;this.abortAllBlocks(),this.loadedBlocks.clear(),this.loadingBlocks.clear(),this.managedNodes=[],this.totalNodeCount=0,this.infiniteScrollMode=!1,this.setDataSource(t)}purgeCache(){this.abortAllBlocks(),this.loadedBlocks.clear(),this.managedNodes=[]}getTotalNodeCount(){return this.totalNodeCount}getTotalRowCount(){return this.totalNodeCount}isNodeLoaded(t){const e=p(t,this.config.cacheBlockSize??100);return this.loadedBlocks.has(e)}isRowLoaded(t){return this.isNodeLoaded(t)}getLoadedBlockCount(){return this.loadedBlocks.size}}export{S as ServerSidePlugin};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|