@toolbox-web/grid 3.9.1 → 3.9.2
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.js +1 -1
- package/all.js.map +1 -1
- package/custom-elements.json +2 -2
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/lib/core/grid.d.ts +8 -4
- package/lib/core/plugin/base-plugin.d.ts +7 -0
- package/lib/core/types.d.ts +2 -0
- package/lib/features/registry.js +1 -1
- package/lib/plugins/context-menu/context-menu-plugin.d.ts +9 -4
- package/lib/plugins/context-menu/index.js +1 -1
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/context-menu/types.d.ts +8 -4
- package/lib/plugins/editing/index.js +1 -1
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/editing/internal/dirty-tracking-manager.d.ts +2 -1
- package/lib/plugins/filtering/filter-model.d.ts +2 -1
- package/lib/plugins/filtering/filtering-plugin.d.ts +5 -2
- package/lib/plugins/filtering/index.js +1 -1
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-rows/grouping-rows-plugin.d.ts +7 -14
- package/lib/plugins/grouping-rows/grouping-rows.d.ts +48 -0
- package/lib/plugins/grouping-rows/index.d.ts +1 -1
- package/lib/plugins/grouping-rows/index.js +1 -1
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/grouping-rows/types.d.ts +21 -0
- package/lib/plugins/master-detail/index.d.ts +1 -1
- package/lib/plugins/master-detail/index.js +1 -1
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/master-detail/master-detail-plugin.d.ts +28 -6
- package/lib/plugins/master-detail/master-detail.d.ts +0 -8
- package/lib/plugins/master-detail/types.d.ts +25 -1
- package/lib/plugins/multi-sort/index.js +1 -1
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/selection/index.js +1 -1
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/selection/selection-plugin.d.ts +8 -1
- package/lib/plugins/server-side/datasource-types.d.ts +28 -0
- package/lib/plugins/server-side/datasource.d.ts +7 -0
- package/lib/plugins/server-side/index.js +1 -1
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/server-side/server-side-plugin.d.ts +61 -8
- package/lib/plugins/server-side/types.d.ts +9 -1
- package/lib/plugins/tree/index.js +1 -1
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/tree/tree-plugin.d.ts +5 -11
- package/lib/plugins/tree/types.d.ts +22 -6
- package/lib/plugins/undo-redo/history.d.ts +2 -1
- package/lib/plugins/undo-redo/index.js +1 -1
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/undo-redo/types.d.ts +13 -1
- package/lib/plugins/undo-redo/undo-redo-plugin.d.ts +15 -2
- 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/context-menu.umd.js +1 -1
- package/umd/plugins/context-menu.umd.js.map +1 -1
- package/umd/plugins/editing.umd.js +1 -1
- package/umd/plugins/editing.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/grouping-rows.umd.js +1 -1
- package/umd/plugins/grouping-rows.umd.js.map +1 -1
- package/umd/plugins/master-detail.umd.js +1 -1
- package/umd/plugins/master-detail.umd.js.map +1 -1
- package/umd/plugins/multi-sort.umd.js +1 -1
- package/umd/plugins/multi-sort.umd.js.map +1 -1
- 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
- package/umd/plugins/undo-redo.umd.js +1 -1
- package/umd/plugins/undo-redo.umd.js.map +1 -1
|
@@ -54,6 +54,7 @@ import { ServerSideConfig } from './types';
|
|
|
54
54
|
* @since 0.1.1
|
|
55
55
|
*/
|
|
56
56
|
export declare class ServerSidePlugin extends BaseGridPlugin<ServerSideConfig> {
|
|
57
|
+
#private;
|
|
57
58
|
/**
|
|
58
59
|
* Plugin manifest declaring capabilities, hooks, events, and queries.
|
|
59
60
|
* @internal
|
|
@@ -75,7 +76,15 @@ export declare class ServerSidePlugin extends BaseGridPlugin<ServerSideConfig> {
|
|
|
75
76
|
* can cancel the underlying network call.
|
|
76
77
|
*/
|
|
77
78
|
private blockControllers;
|
|
78
|
-
|
|
79
|
+
/**
|
|
80
|
+
* In-flight `getChildRows` requests. Aborted only on `detach()` or when the
|
|
81
|
+
* requester's `FetchChildrenQuery.signal` fires — NOT on sort/filter/refresh:
|
|
82
|
+
* cancellation is requester-owned (Tree, GroupingRows, MasterDetail each
|
|
83
|
+
* abort their own stale loads). An abort broadcasts only `datasource:loading`
|
|
84
|
+
* `false`, which no requester treats as a release, so an unrequested abort
|
|
85
|
+
* would strand its loading state.
|
|
86
|
+
*/
|
|
87
|
+
private childControllers;
|
|
79
88
|
private scrollDebounceTimer?;
|
|
80
89
|
/**
|
|
81
90
|
* One-shot flag set when a block lands; consumed in `afterRender()` to re-check
|
|
@@ -90,11 +99,28 @@ export declare class ServerSidePlugin extends BaseGridPlugin<ServerSideConfig> {
|
|
|
90
99
|
/** @internal */
|
|
91
100
|
detach(): void;
|
|
92
101
|
/**
|
|
93
|
-
* Abort all in-flight block requests
|
|
94
|
-
* the data source is replaced, the cache is purged,
|
|
95
|
-
* model changes (the previously loaded block coordinates no
|
|
102
|
+
* Abort all in-flight block requests and release their loading slots. Called
|
|
103
|
+
* when the plugin tears down, the data source is replaced, the cache is purged,
|
|
104
|
+
* or the sort/filter model changes (the previously loaded block coordinates no
|
|
105
|
+
* longer apply).
|
|
96
106
|
*/
|
|
97
107
|
private abortAllBlocks;
|
|
108
|
+
/**
|
|
109
|
+
* Release `blockNum`'s in-flight slot when its request settles — but only if
|
|
110
|
+
* `controller` still owns it. An aborted request settles a microtask after the
|
|
111
|
+
* abort, by which time a superseding request (refresh, sort/filter change) may
|
|
112
|
+
* have re-registered the same block; deleting that entry would orphan the new
|
|
113
|
+
* request from `abortAllBlocks()` and let stale rows land in the cache.
|
|
114
|
+
*/
|
|
115
|
+
private releaseBlock;
|
|
116
|
+
/**
|
|
117
|
+
* Effective sort/filter ownership. The `data-src` URL source only slices a cached
|
|
118
|
+
* dataset and ignores `sortModel` / `filterModel`, so it is always `'local'` —
|
|
119
|
+
* otherwise a sort or filter would refetch the unchanged rows and nobody would
|
|
120
|
+
* apply it.
|
|
121
|
+
*/
|
|
122
|
+
private get sortMode();
|
|
123
|
+
private get filterMode();
|
|
98
124
|
/**
|
|
99
125
|
* Build enrichment params by querying sort/filter models from loaded plugins.
|
|
100
126
|
*
|
|
@@ -104,10 +130,29 @@ export declare class ServerSidePlugin extends BaseGridPlugin<ServerSideConfig> {
|
|
|
104
130
|
*/
|
|
105
131
|
private getEnrichmentParams;
|
|
106
132
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
|
|
110
|
-
|
|
133
|
+
* Blocks (ascending) the viewport — expanded by `threshold` rows both ways to
|
|
134
|
+
* prefetch — needs loaded. The viewport is translated through a structural
|
|
135
|
+
* plugin's `datasource:viewport-mapping` when one responds, else 1:1 (flat data).
|
|
136
|
+
*
|
|
137
|
+
* When the displayed rows are not `managedNodes` itself, a later stage may have
|
|
138
|
+
* dropped or reordered rows (local filter or sort), or a structural plugin
|
|
139
|
+
* renumbered the rows it kept (Tree counts the remaining roots from zero). Then a
|
|
140
|
+
* display index is no longer a node index, so the blocks of the placeholders on
|
|
141
|
+
* screen are added: their `__index` is their node index, and loaded rows need no fetch.
|
|
142
|
+
*/
|
|
143
|
+
private getRequiredBlockNumbers;
|
|
144
|
+
/**
|
|
145
|
+
* `totalNodeCount`, or `Infinity` while it is unknown — `0` means "not yet loaded"
|
|
146
|
+
* (just after purgeCache, or before the first fetch resolves), and block 0 must
|
|
147
|
+
* still be fetchable then.
|
|
148
|
+
*/
|
|
149
|
+
private get knownTotal();
|
|
150
|
+
/** Whether the displayed rows are not `managedNodes` itself, so display indices may not be node indices. */
|
|
151
|
+
private get displayDiffers();
|
|
152
|
+
/** A structural plugin's (Tree, GroupingRows) translation of the viewport to node space, if any. */
|
|
153
|
+
private queryViewportMapping;
|
|
154
|
+
/** Add the block of every placeholder displayed in `[displayStart, displayEnd)` (may be fractional). */
|
|
155
|
+
private addPlaceholderBlocks;
|
|
111
156
|
/**
|
|
112
157
|
* Handle sort or filter model changes.
|
|
113
158
|
* Purge cache and refetch current viewport with new enrichment params.
|
|
@@ -125,6 +170,12 @@ export declare class ServerSidePlugin extends BaseGridPlugin<ServerSideConfig> {
|
|
|
125
170
|
* Returns loaded rows + one extra block of placeholders to trigger next fetch.
|
|
126
171
|
*/
|
|
127
172
|
private getInfiniteScrollEstimate;
|
|
173
|
+
/**
|
|
174
|
+
* Length `managedNodes` must have: the infinite-scroll estimate, else
|
|
175
|
+
* `totalNodeCount` (guarded against an invalid value from a malformed
|
|
176
|
+
* datasource response, e.g. `undefined`).
|
|
177
|
+
*/
|
|
178
|
+
private getNodeCount;
|
|
128
179
|
/**
|
|
129
180
|
* Check current viewport and load any missing blocks.
|
|
130
181
|
*/
|
|
@@ -141,6 +192,8 @@ export declare class ServerSidePlugin extends BaseGridPlugin<ServerSideConfig> {
|
|
|
141
192
|
handleQuery(query: PluginQuery): unknown;
|
|
142
193
|
/**
|
|
143
194
|
* Fetch child rows via the datasource and broadcast the result.
|
|
195
|
+
* `requesterSignal` (from `FetchChildrenQuery.signal`) aborts the request;
|
|
196
|
+
* an aborted request broadcasts only `datasource:loading` `false`.
|
|
144
197
|
*/
|
|
145
198
|
private fetchChildren;
|
|
146
199
|
/**
|
|
@@ -76,6 +76,8 @@ export interface ServerSideConfig {
|
|
|
76
76
|
* How sort changes affect the cache.
|
|
77
77
|
* - `'server'` (default): purge cache and refetch via `getRows({ sortModel })`.
|
|
78
78
|
* Use when the backend supports the requested sort shape natively.
|
|
79
|
+
* MultiSortPlugin does not re-sort the returned rows locally — the data
|
|
80
|
+
* source's order (and its loading placeholders' block positions) is shown as-is.
|
|
79
81
|
* - `'local'`: keep the loaded blocks; sort the loaded rows in-place via
|
|
80
82
|
* the active sort plugin (MultiSort or core sort). `sortModel` is **not**
|
|
81
83
|
* sent on subsequent block fetches. Loading placeholder rows
|
|
@@ -83,6 +85,7 @@ export interface ServerSideConfig {
|
|
|
83
85
|
*
|
|
84
86
|
* Use `'local'` when the server cannot sort by every column the user can sort
|
|
85
87
|
* (e.g. APIs that only support a single sort field, or no sort at all).
|
|
88
|
+
* Ignored for the `data-src` URL source, which always sorts locally.
|
|
86
89
|
*
|
|
87
90
|
* @default 'server'
|
|
88
91
|
*/
|
|
@@ -90,9 +93,14 @@ export interface ServerSideConfig {
|
|
|
90
93
|
/**
|
|
91
94
|
* How filter changes affect the cache.
|
|
92
95
|
* - `'server'` (default): purge cache and refetch via `getRows({ filterModel })`.
|
|
96
|
+
* FilteringPlugin does not re-filter the returned rows locally — the data
|
|
97
|
+
* source's result (and its loading placeholders) is shown as-is.
|
|
93
98
|
* - `'local'`: keep the loaded blocks; filter only the rows currently in cache
|
|
94
99
|
* via FilteringPlugin's normal pipeline. `filterModel` is **not** sent on
|
|
95
|
-
* subsequent block fetches.
|
|
100
|
+
* subsequent block fetches. Loading placeholders (see `isLoadingPlaceholder()`)
|
|
101
|
+
* always pass the filter until their block loads.
|
|
102
|
+
*
|
|
103
|
+
* Ignored for the `data-src` URL source, which always filters locally.
|
|
96
104
|
*
|
|
97
105
|
* In `'local'` mode the user only filters the currently loaded subset —
|
|
98
106
|
* scrolling further loads more blocks which then re-enter the local filter.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{BaseGridPlugin as e,builtInSort as t}from"@toolbox-web/grid";import{HierarchyPlugin as r,buildHierarchy as i}from"@toolbox-web/grid/plugins/hierarchy";var n="expanded",s="tree-toggle",o="__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(e=>e.split("").reverse().join("")),a=(new RegExp(`__(proto|defineGetter|defineSetter)|${o.slice(3).join("|")}|this\\b`),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|math".split("|"))),d=/^on\w+$/i,l=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),h=/^\s*(javascript|vbscript|data|blob):/i;function c(e){const t=document.createElement("template");return e&&"string"==typeof e&&(t.innerHTML=e,function(e){const t=[],r=e.querySelectorAll("*");for(const i of r){const e=i.tagName.toLowerCase();if(a.has(e)){t.push(i);continue}if(("svg"===e||"http://www.w3.org/2000/svg"===i.namespaceURI)&&Array.from(i.attributes).some(e=>d.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(i);continue}const r=[];for(const t of i.attributes){const e=t.name.toLowerCase();d.test(e)?r.push(t.name):"is"!==e?(l.has(e)&&h.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&r.push(t.name):r.push(t.name)}r.forEach(e=>i.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content)),t.content}function p(e,t,r){return void 0!==e.id?String(e.id):r?`${r}-${t}`:String(t)}function u(e,t){const r=new Set(e);return r.has(t)?r.delete(t):r.add(t),r}function g(e,t,r=null,i=0){const n=t.childrenField??"children",s=/* @__PURE__ */new Set;for(let o=0;o<e.length;o++){const a=e[o],d=p(a,o,r),l=a[n];if(Array.isArray(l)&&l.length>0){s.add(d);const e=g(l,t,d,i+1);for(const t of e)s.add(t)}}return s}function y(e,t,r,i=null,n=0){const s=r.childrenField??"children";for(let o=0;o<e.length;o++){const a=e[o],d=p(a,o,i);if(d===t)return[d];const l=a[s];if(Array.isArray(l)&&l.length>0){const e=y(l,t,r,d,n+1);if(e)return[d,...e]}}return null}function f(e,t,r,i){const n=y(e,t,r);if(!n)return i;const s=new Set(i);for(let o=0;o<n.length-1;o++)s.add(n[o]);return s}function w(e,t="children",r){if(!Array.isArray(e)||0===e.length)return!1;for(const i of e){if(!i||!0===i.__loading)continue;const e=i[t];if(Array.isArray(e)&&e.length>0)return!0;if(null!=e&&!Array.isArray(e)&&e)return!0;if(r?.(i))return!0}return!1}var m=class extends e{static manifest={modifiesRowStructure:!0,hookPriority:{processRows:10},incompatibleWith:[{name:"pivot",reason:"PivotPlugin replaces the entire row and column structure with aggregated pivot data. Tree hierarchy cannot coexist with pivot aggregation."}],events:[{type:"tree-expand",description:"Emitted when tree expansion state changes (toggle, expand all, collapse all). Broadcast to both DOM consumers and plugin bus."},{type:"tree-load-start",description:"Emitted when lazy child loading starts for a node whose children are not yet loaded."},{type:"tree-load-end",description:"Emitted when lazy child loading completes and children have been merged into the parent row."},{type:"tree-load-error",description:"Emitted when lazy child loading fails. The node leaves its loading state and can be retried."}],queries:[{type:"canMoveRow",description:"Returns false for rows with children (parent nodes cannot be reordered)"},{type:"datasource:viewport-mapping",description:"Translates flat viewport row indices to top-level node indices for ServerSide pagination."}]};static dependencies=[{name:"hierarchy",required:!0,reason:"Builds the hierarchical row model",provide:()=>new r},{name:"multiSort",required:!1,reason:"Queries sort model for coordinated tree sorting"},{name:"serverSide",required:!1,reason:"Consumes datasource events for lazy-loaded tree data"}];name="tree";hierarchyStage="structure";styles='@layer tbw-plugins{tbw-grid .cell[data-field=__tbw_expander]{justify-content:flex-start;align-items:center;padding:0;display:flex;border-inline-end:none!important}tbw-grid .header-row .cell[data-field=__tbw_expander]{display:none}tbw-grid .header-row .cell[data-field=__tbw_expander]+.cell{grid-column:1/3}tbw-grid .tree-cell-wrapper{vertical-align:middle;align-items:center;padding-inline-start:calc(var(--tbw-tree-depth,0) * var(--tbw-tree-indent-width,var(--tbw-tree-toggle-size,1.25em)));display:inline-flex;overflow:visible}tbw-grid .tree-expander{box-sizing:border-box;justify-content:flex-start;align-items:center;width:100%;height:100%;display:flex}tbw-grid .tree-toggle{cursor:pointer;-webkit-user-select:none;user-select:none;width:var(--tbw-tree-toggle-size,1.25em);height:var(--tbw-tree-toggle-size,1.25em);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}tbw-grid .tree-toggle:hover{color:var(--tbw-tree-accent,var(--tbw-color-accent))}tbw-grid .tree-toggle{position:relative}tbw-grid .tree-toggle:after{content:"";inline-size:var(--tbw-touch-target-min,24px);block-size:var(--tbw-touch-target-min,24px);position:absolute;inset-block-start:50%;inset-inline-start:50%;translate:-50% -50%}tbw-grid .tree-spacer{width:var(--tbw-tree-toggle-size,1.25em);height:var(--tbw-tree-toggle-size,1.25em);flex-shrink:0;display:inline-block}@media (pointer:coarse){tbw-grid .tree-toggle,tbw-grid .tree-spacer{min-width:var(--tbw-touch-target-min,24px);min-height:var(--tbw-touch-target-min,24px)}}tbw-grid .tree-loading{--tbw-spinner-size:var(--tbw-tree-toggle-size,1.25em);flex-shrink:0}tbw-grid .data-grid-row.tbw-tree-slide-in{animation:tbw-tree-slide-in var(--tbw-animation-duration,.2s) var(--tbw-animation-easing,ease-out) forwards}tbw-grid .data-grid-row.tbw-tree-fade-in{animation:tbw-tree-fade-in var(--tbw-animation-duration,.2s) var(--tbw-animation-easing,ease-out) forwards}@keyframes tbw-tree-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}@keyframes tbw-tree-fade-in{0%{opacity:0}to{opacity:1}}}';get defaultConfig(){return{childrenField:"children",autoDetect:!0,defaultExpanded:!1,indentWidth:20,showExpandIcons:!0,animation:"slide"}}expandedKeys=/* @__PURE__ */new Set;initialExpansionDone=!1;flattenedRows=[];rowKeyMap=/* @__PURE__ */new Map;previousVisibleKeys=/* @__PURE__ */new Set;keysToAnimate=/* @__PURE__ */new Set;#e=[];#t=0;sortState=null;#r=null;loadingKeys=/* @__PURE__ */new Set;loadedKeys=/* @__PURE__ */new Set;#i=/* @__PURE__ */new Map;#n=/* @__PURE__ */new WeakMap;#s=/* @__PURE__ */new WeakMap;originalTreeColumnRenderer;originalTreeColumnRendererProperty="viewRenderer";wrappedTreeColumnField;#o=!1;#a=!1;detach(){this.expandedKeys.clear(),this.initialExpansionDone=!1,this.flattenedRows=[],this.#e=[],this.#t=0,this.rowKeyMap.clear(),this.previousVisibleKeys.clear(),this.keysToAnimate.clear(),this.sortState=null,this.#r=null,this.loadingKeys.clear(),this.loadedKeys.clear();for(const e of this.#i.values())e.abort();this.#i.clear(),this.originalTreeColumnRenderer=void 0,this.originalTreeColumnRendererProperty="viewRenderer",this.wrappedTreeColumnField=void 0,this.#o=!1}handleQuery(e){if("canMoveRow"===e.type){const t=e.context,r=this.config.childrenField??"children",i=t?.[r];if(Array.isArray(i)&&i.length>0)return!1}if("datasource:viewport-mapping"===e.type){const{viewportStart:t,viewportEnd:r}=e.context;if(0===this.flattenedRows.length)return;return function(e,t,r,i){const n=e.length-1,s=t=>Math.max(0,e[Math.max(0,Math.min(t,n))]??0);return{startNode:s(r),endNode:s(i)+1,totalLoadedNodes:t}}(this.#e,this.#t,t,r)}}attach(e){super.attach(e),this.on("datasource:data",e=>{const t=e;t.claimed||(t.claimed=!0)}),this.on("datasource:children",e=>{const t=e;if("tree"!==t.context?.source)return;t.claimed=!0;const r=t.context.parentNode;if(r){const e=this.#d(r);this.#l(r,t.rows??[]),this.loadingKeys.delete(e),this.broadcast("tree-load-end",{key:e,row:r,depth:this.rowKeyMap.get(e)?.depth??0,childCount:t.rows?.length??0}),this.requestRender()}}),this.on("datasource:error",e=>{const t=e;if("tree"!==t.context?.source)return;const r=t.context.parentNode;if(!r)return;const i=this.#d(r);this.loadingKeys.delete(i)&&(this.broadcast("tree-load-error",{key:i,row:r,depth:this.rowKeyMap.get(i)?.depth??0,error:t.error}),this.requestRender())})}get animationStyle(){return!!this.isAnimationEnabled&&(this.config.animation??"slide")}detect(e){if(!this.config.autoDetect)return!1;const t=e,r=this.config.childrenField??function(e){if(!Array.isArray(e)||0===e.length)return null;const t=["children","items","nodes","subRows","nested"];for(const r of e)if(r&&"object"==typeof r)for(const e of t){const t=r[e];if(Array.isArray(t)&&t.length>0)return e}return null}(t)??"children";return w(t,r)}processRows(e){const t=this.grid?.getPluginByName?.("hierarchy");return t?t.process(e,this):i(e,[this])}beginHierarchy(e){const t=e;return 0!==t.length&&w(t,this.config.childrenField??"children",this.config.hasChildren)?(this.#r=this.resolveEffectiveSortState(),this.config.defaultExpanded&&!this.initialExpansionDone&&(this.expandedKeys=g(t,this.config),this.initialExpansionDone=!0),this.#s=/* @__PURE__ */new WeakMap,!0):(this.flattenedRows=[],this.#e=[],this.#t=0,this.rowKeyMap.clear(),this.previousVisibleKeys.clear(),this.#h(),!1)}processSiblings(e,t){const{parentKey:r,depth:i}=t,n=this.config.childrenField??"children",s=this.config.hasChildren;for(let d=0;d<e.length;d++)this.#c(e[d].row,d,r);const o=this.#r,a=o?this.#p(e,o.field,o.direction):e;for(let d=0;d<a.length;d++){const e=a[d],t=e.row,o=this.#c(t,d,r),l=t[n],h=Array.isArray(l)&&l.length>0,c=h||!0!==t.__loading&&(s?s(t):null!=l&&!Array.isArray(l)&&!!l),p=this.expandedKeys.has(o);this.#s.set(t,{key:o,data:t,depth:i,hasChildren:c,isExpanded:p,parentKey:r,posInSet:d+1,setSize:a.length}),e.key=o,h&&p&&(e.expanded=!0,e.children=l.map(e=>({row:e})))}return a}endHierarchy(e,t){const r=this.#s;this.#s=/* @__PURE__ */new WeakMap,this.flattenedRows=[],this.rowKeyMap.clear(),this.keysToAnimate.clear();const i=/* @__PURE__ */new Set,n=new Array(e.length);let s=-1;for(let o=0;o<e.length;o++){const a=e[o],d=r.get(a);if(null===d?.parentKey&&s++,n[o]=s,!d)continue;const l=t(a)?.level;void 0!==l&&(d.depth=l-1),this.flattenedRows.push(d),this.rowKeyMap.set(d.key,d),this.#s.set(a,d),i.add(d.key),!this.previousVisibleKeys.has(d.key)&&d.depth>0&&this.keysToAnimate.add(d.key)}return this.previousVisibleKeys=i,this.#e=n,this.#t=s+1,this.#h(),!0}#h(){this.#a||(this.#a=!0,queueMicrotask(()=>{this.#a=!1,this.grid&&this.#o!==this.flattenedRows.length>0&&this.requestColumnsRender()}))}#c(e,t,r){if(void 0!==e.id){const t=String(e.id);return this.#n.set(e,t),t}const i=this.#n.get(e);if(void 0!==i)return i;const n=r?`${r}-${t}`:String(t);return this.#n.set(e,n),n}#p(e,t,r){const i=/* @__PURE__ */new Map;for(const n of e)i.set(n.row,n);return this.#u(e.map(e=>e.row),t,r).map(e=>i.get(e)??{row:e})}#u(e,r,i){const n=this.grid,s=n?._columns??[],o={field:r,direction:i},a=[...e],d=(n?.effectiveConfig?.sortHandler??t)(a,o,s);return d&&"function"==typeof d.then?(d.catch(()=>{}),t(a,o,s)):d}#d(e){return this.#n.get(e)??String(e.id??"?")}#l(e,t){e[this.config.childrenField??"children"]=t,this.loadedKeys.add(this.#d(e))}#g(e,t){if(this.loadedKeys.has(t))return!1;const r=e[this.config.childrenField??"children"];if(Array.isArray(r)&&r.length>0)return!1;const i=this.config.hasChildren;return i?i(e):null!=r&&!Array.isArray(r)&&!!r}requestLazyChildren(e){const{key:t,depth:r,data:i}=e;if(this.loadingKeys.has(t))return;if(!this.#g(i,t))return;const n=this.queryBoolean("datasource:is-active"),{loadChildren:s}=this.config;(n||s)&&(this.loadingKeys.add(t),this.broadcast("tree-load-start",{key:t,row:i,depth:r}),n?this.grid.query("datasource:fetch-children",{context:{source:"tree",parentNode:i,nodePath:[t]}}):this.#y(t,i,r))}#y(e,t,r){const i=this.config.loadChildren,n=new AbortController;this.#i.set(e,n);const s=()=>!n.signal.aborted&&(this.#i.delete(e),this.loadingKeys.delete(e),!0),o=i=>{if(!s())return;const n=i??[];this.#l(t,n),this.broadcast("tree-load-end",{key:e,row:t,depth:r,childCount:n.length}),this.requestRender()},a=i=>{s()&&(this.broadcast("tree-load-error",{key:e,row:t,depth:r,error:i}),this.requestRender())};let d;try{d=i({row:t,key:e,depth:r,signal:n.signal})}catch(l){return void a(l)}if(d&&"function"==typeof d.subscribe){let e=!1,t=null;const r=()=>{e=!0,t?.unsubscribe(),t=null},i=d.subscribe({next:e=>{o(e),r()},error:e=>{a(e),r()}});return e?void i.unsubscribe():(t=i,void n.signal.addEventListener("abort",r,{once:!0}))}Promise.resolve(d).then(o,a)}resolveEffectiveSortState(){const e=this.grid?.query?.("sort:get-model",null);if(Array.isArray(e)&&e.length>0){const t=e[0];if(Array.isArray(t)&&t.length>0)return{field:t[0].field,direction:"desc"===t[0].direction?-1:1}}return this.sortState}processColumns(e){if(0===this.flattenedRows.length){const t=[...e];if(this.#o){const e=t.findIndex(e=>e.field===this.wrappedTreeColumnField);e>=0&&(t[e]={...t[e],renderer:"renderer"===this.originalTreeColumnRendererProperty?this.originalTreeColumnRenderer:void 0})}return this.#o=!1,this.originalTreeColumnRenderer=void 0,this.originalTreeColumnRendererProperty="viewRenderer",this.wrappedTreeColumnField=void 0,t}const t=[...e];if(0===t.length)return t;const{treeColumn:r}=this.config;let i=0;if(r){const e=t.findIndex(e=>e.field===r);e>=0&&(i=e)}const o=t[i],a=o.field;this.wrappedTreeColumnField!==a&&(this.originalTreeColumnRenderer=o.renderer||o.viewRenderer,this.originalTreeColumnRendererProperty=o.renderer?"renderer":"viewRenderer",this.wrappedTreeColumnField=a);const d=this.originalTreeColumnRenderer,l=()=>this.config,h=this.setIcon.bind(this);return t[i]={...o,renderer:e=>{const{row:t,value:r}=e,{showExpandIcons:i=!0,indentWidth:o}=l(),a=this.#s.get(t),p=a?.depth??0,u=document.createElement("span");if(u.className="tree-cell-wrapper",u.style.setProperty("--tbw-tree-depth",String(p)),void 0!==o&&u.style.setProperty("--tbw-tree-indent-width",`${o}px`),i)if(a&&this.loadingKeys.has(a.key)){const e=function(e){const t=document.createElement("div");return t.className=`tbw-spinner tbw-spinner--${e}`,t.setAttribute("role","progressbar"),t.setAttribute("aria-label","Loading"),t}("small");e.classList.add("tree-loading"),u.appendChild(e)}else if(a&&a.hasChildren){const e=document.createElement("span");e.className=`${s}${a.isExpanded?` ${n}`:""}`,h(e,a.isExpanded?"collapse":"expand"),e.setAttribute("data-tree-key",a.key),u.appendChild(e)}else{const e=document.createElement("span");e.className="tree-spacer",u.appendChild(e)}const g=document.createElement("span");if(g.className="tree-content",d){const t=d(e);t instanceof Node?g.appendChild(t):"string"==typeof t&&(y=g,(f=t)&&"string"==typeof f?-1!==f.indexOf("<")||-1!==f.indexOf("&")?y.replaceChildren(c(f)):y.textContent=f:y.replaceChildren())}else g.textContent=null!=r?String(r):"";var y,f;return u.appendChild(g),u}},this.#o=!0,t}onCellClick(e){const t=e.originalEvent?.target;if(!t?.classList.contains(s))return!1;const r=t.getAttribute("data-tree-key");if(!r)return!1;const i=this.rowKeyMap.get(r);return!!i&&(this.expandedKeys=u(this.expandedKeys,r),this.expandedKeys.has(r)&&this.requestLazyChildren(i),this.broadcast("tree-expand",{key:r,row:i.data,expanded:this.expandedKeys.has(r),depth:i.depth,expandedKeys:[...this.expandedKeys]}),this.requestRender(),!0)}onKeyDown(e){if(" "!==e.key)return;const t=this.grid._focusRow,r=this.#s.get(this.rows[t]);return r?.hasChildren?(e.preventDefault(),this.expandedKeys=u(this.expandedKeys,r.key),this.expandedKeys.has(r.key)&&this.requestLazyChildren(r),this.broadcast("tree-expand",{key:r.key,row:r.data,expanded:this.expandedKeys.has(r.key),depth:r.depth,expandedKeys:[...this.expandedKeys]}),this.requestRenderWithFocus(),!0):void 0}onHeaderClick(e){if(0===this.flattenedRows.length||!e.column.sortable)return!1;const t=this.grid?.query?.("sort:get-model",null);if(Array.isArray(t)&&t.length>0)return!1;const{field:r}=e.column;this.sortState&&this.sortState.field===r?1===this.sortState.direction?this.sortState={field:r,direction:-1}:this.sortState=null:this.sortState={field:r,direction:1};const i=this.grid;return void 0!==i._sortState&&(i._sortState=this.sortState?{...this.sortState}:null),this.broadcast("sort-change",{field:r,direction:this.sortState?.direction??0}),this.requestRender(),!0}afterRender(){const e=this.gridElement?.querySelector(".rows");if(!e)return;const t=this.animationStyle,r=!1!==t&&this.keysToAnimate.size>0,i="fade"===t?"tbw-tree-fade-in":"tbw-tree-slide-in";for(const n of e.querySelectorAll(".data-grid-row")){const e=this.#s.get(n.__rowDataRef);e&&(e.hasChildren?n.setAttribute("aria-expanded",String(e.isExpanded)):n.hasAttribute("aria-expanded")&&n.removeAttribute("aria-expanded"),n.classList.toggle("tbw-row-expanded",e.hasChildren&&e.isExpanded),this.loadingKeys.has(e.key)?n.setAttribute("aria-busy","true"):n.hasAttribute("aria-busy")&&!n.classList.contains("tbw-row-loading")&&n.removeAttribute("aria-busy"),r&&e.key&&this.keysToAnimate.has(e.key)&&(n.classList.add(i),n.addEventListener("animationend",()=>n.classList.remove(i),{once:!0})))}this.keysToAnimate.clear()}expand(e){this.expandedKeys.add(e);const t=this.rowKeyMap.get(e);t&&this.requestLazyChildren(t),this.requestRender()}collapse(e){this.expandedKeys.delete(e),this.requestRender()}toggle(e){this.expandedKeys=u(this.expandedKeys,e);const t=this.rowKeyMap.get(e);t?(this.expandedKeys.has(e)&&this.requestLazyChildren(t),this.broadcast("tree-expand",{key:e,row:t.data,expanded:this.expandedKeys.has(e),depth:t.depth,expandedKeys:[...this.expandedKeys]})):this.emitPluginEvent("tree-expand",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}expandAll(){this.expandedKeys=g(this.rows,this.config),this.emitPluginEvent("tree-expand",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}collapseAll(){this.expandedKeys=/* @__PURE__ */new Set,this.emitPluginEvent("tree-expand",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}isExpanded(e){return this.expandedKeys.has(e)}getExpandedKeys(){return[...this.expandedKeys]}getFlattenedRows(){return[...this.flattenedRows]}getRowMeta(e){return this.#s.get(e)}getRowByKey(e){return this.rowKeyMap.get(e)?.data}expandToKey(e){this.expandedKeys=f(this.rows,e,this.config,this.expandedKeys),this.requestRender()}};export{m as TreePlugin};
|
|
1
|
+
import{BaseGridPlugin as e,builtInSort as t}from"@toolbox-web/grid";import{HierarchyPlugin as r,buildHierarchy as n}from"@toolbox-web/grid/plugins/hierarchy";var i="expanded",s="tree-toggle",o="__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(e=>e.split("").reverse().join("")),a=(new RegExp(`__(proto|defineGetter|defineSetter)|${o.slice(3).join("|")}|this\\b`),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|math".split("|"))),d=/^on\w+$/i,l=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),h=/^\s*(javascript|vbscript|data|blob):/i;function c(e){const t=document.createElement("template");return e&&"string"==typeof e&&(t.innerHTML=e,function(e){const t=[],r=e.querySelectorAll("*");for(const n of r){const e=n.tagName.toLowerCase();if(a.has(e)){t.push(n);continue}if(("svg"===e||"http://www.w3.org/2000/svg"===n.namespaceURI)&&Array.from(n.attributes).some(e=>d.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(n);continue}const r=[];for(const t of n.attributes){const e=t.name.toLowerCase();d.test(e)?r.push(t.name):"is"!==e?(l.has(e)&&h.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&r.push(t.name):r.push(t.name)}r.forEach(e=>n.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content)),t.content}function u(e,t,r){return void 0!==e.id?String(e.id):r?`${r}-${t}`:String(t)}function p(e,t){const r=new Set(e);return r.has(t)?r.delete(t):r.add(t),r}function g(e,t,r=null,n=0){const i=t.childrenField??"children",s=/* @__PURE__ */new Set;for(let o=0;o<e.length;o++){const a=e[o],d=u(a,o,r),l=a[i];if(Array.isArray(l)&&l.length>0){s.add(d);const e=g(l,t,d,n+1);for(const t of e)s.add(t)}}return s}function w(e,t,r,n=null,i=0){const s=r.childrenField??"children";for(let o=0;o<e.length;o++){const a=e[o],d=u(a,o,n);if(d===t)return[d];const l=a[s];if(Array.isArray(l)&&l.length>0){const e=w(l,t,r,d,i+1);if(e)return[d,...e]}}return null}function y(e,t,r,n){const i=w(e,t,r);if(!i)return n;const s=new Set(n);for(let o=0;o<i.length-1;o++)s.add(i[o]);return s}function f(e,t="children",r){if(!Array.isArray(e)||0===e.length)return!1;for(const n of e){if(!n||!0===n.__loading)continue;const e=n[t];if(Array.isArray(e)&&e.length>0)return!0;if(null!=e&&!Array.isArray(e)&&e)return!0;if(r?.(n))return!0}return!1}var m=class extends e{static manifest={modifiesRowStructure:!0,hookPriority:{processRows:10},incompatibleWith:[{name:"pivot",reason:"PivotPlugin replaces the entire row and column structure with aggregated pivot data. Tree hierarchy cannot coexist with pivot aggregation."}],events:[{type:"tree-expand",description:"Emitted when tree expansion state changes (toggle, expand all, collapse all). Broadcast to both DOM consumers and plugin bus."},{type:"tree-load-start",description:"Emitted when lazy child loading starts for a node whose children are not yet loaded."},{type:"tree-load-end",description:"Emitted when lazy child loading completes and children have been merged into the parent row."},{type:"tree-load-error",description:"Emitted when lazy child loading fails. The node leaves its loading state and can be retried."}],queries:[{type:"canMoveRow",description:"Returns false for rows with children (parent nodes cannot be reordered)"},{type:"datasource:viewport-mapping",description:"Translates flat viewport row indices to top-level node indices for ServerSide pagination."}]};static dependencies=[{name:"hierarchy",required:!0,reason:"Builds the hierarchical row model",provide:()=>new r},{name:"multiSort",required:!1,reason:"Queries sort model for coordinated tree sorting"},{name:"serverSide",required:!1,reason:"Consumes datasource events for lazy-loaded tree data"}];name="tree";hierarchyStage="structure";styles='@layer tbw-plugins{tbw-grid .cell[data-field=__tbw_expander]{justify-content:flex-start;align-items:center;padding:0;display:flex;border-inline-end:none!important}tbw-grid .header-row .cell[data-field=__tbw_expander]{display:none}tbw-grid .header-row .cell[data-field=__tbw_expander]+.cell{grid-column:1/3}tbw-grid .tree-cell-wrapper{vertical-align:middle;align-items:center;padding-inline-start:calc(var(--tbw-tree-depth,0) * var(--tbw-tree-indent-width,var(--tbw-tree-toggle-size,1.25em)));display:inline-flex;overflow:visible}tbw-grid .tree-expander{box-sizing:border-box;justify-content:flex-start;align-items:center;width:100%;height:100%;display:flex}tbw-grid .tree-toggle{cursor:pointer;-webkit-user-select:none;user-select:none;width:var(--tbw-tree-toggle-size,1.25em);height:var(--tbw-tree-toggle-size,1.25em);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}tbw-grid .tree-toggle:hover{color:var(--tbw-tree-accent,var(--tbw-color-accent))}tbw-grid .tree-toggle{position:relative}tbw-grid .tree-toggle:after{content:"";inline-size:var(--tbw-touch-target-min,24px);block-size:var(--tbw-touch-target-min,24px);position:absolute;inset-block-start:50%;inset-inline-start:50%;translate:-50% -50%}tbw-grid .tree-spacer{width:var(--tbw-tree-toggle-size,1.25em);height:var(--tbw-tree-toggle-size,1.25em);flex-shrink:0;display:inline-block}@media (pointer:coarse){tbw-grid .tree-toggle,tbw-grid .tree-spacer{min-width:var(--tbw-touch-target-min,24px);min-height:var(--tbw-touch-target-min,24px)}}tbw-grid .tree-loading{--tbw-spinner-size:var(--tbw-tree-toggle-size,1.25em);flex-shrink:0}tbw-grid .data-grid-row.tbw-tree-slide-in{animation:tbw-tree-slide-in var(--tbw-animation-duration,.2s) var(--tbw-animation-easing,ease-out) forwards}tbw-grid .data-grid-row.tbw-tree-fade-in{animation:tbw-tree-fade-in var(--tbw-animation-duration,.2s) var(--tbw-animation-easing,ease-out) forwards}@keyframes tbw-tree-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}@keyframes tbw-tree-fade-in{0%{opacity:0}to{opacity:1}}}';get defaultConfig(){return{childrenField:"children",autoDetect:!0,defaultExpanded:!1,indentWidth:20,showExpandIcons:!0,animation:"slide"}}expandedKeys=/* @__PURE__ */new Set;initialExpansionDone=!1;flattenedRows=[];rowKeyMap=/* @__PURE__ */new Map;previousVisibleKeys=/* @__PURE__ */new Set;keysToAnimate=/* @__PURE__ */new Set;#e=[];#t=0;sortState=null;#r=null;#n=/* @__PURE__ */new Map;#i=/* @__PURE__ */new WeakSet;#s=/* @__PURE__ */new WeakSet;#o=/* @__PURE__ */new WeakSet;#a=[];#d=/* @__PURE__ */new WeakMap;#l=/* @__PURE__ */new WeakMap;originalTreeColumnRenderer;originalTreeColumnRendererProperty="viewRenderer";wrappedTreeColumnField;#h=!1;#c=!1;detach(){this.expandedKeys.clear(),this.initialExpansionDone=!1,this.flattenedRows=[],this.#e=[],this.#t=0,this.rowKeyMap.clear(),this.previousVisibleKeys.clear(),this.keysToAnimate.clear(),this.sortState=null,this.#r=null,this.#i=/* @__PURE__ */new WeakSet,this.#s=/* @__PURE__ */new WeakSet,this.#o=/* @__PURE__ */new WeakSet,this.#a=[];for(const e of this.#n.values())e.controller.abort();this.#n.clear(),this.originalTreeColumnRenderer=void 0,this.originalTreeColumnRendererProperty="viewRenderer",this.wrappedTreeColumnField=void 0,this.#h=!1}handleQuery(e){if("canMoveRow"===e.type){const t=e.context,r=this.config.childrenField??"children",n=t?.[r];if(Array.isArray(n)&&n.length>0)return!1}if("datasource:viewport-mapping"===e.type){const{viewportStart:t,viewportEnd:r}=e.context;if(0===this.flattenedRows.length)return;return function(e,t,r,n){const i=e.length-1,s=t=>Math.max(0,e[Math.max(0,Math.min(t,i))]??0);return{startNode:s(r),endNode:s(n)+1,totalLoadedNodes:t}}(this.#e,this.#t,t,r)}}attach(e){super.attach(e),this.on("datasource:data",e=>{const t=e;t.claimed||(t.claimed=!0)}),this.on("datasource:children",e=>{const t=e;if("tree"!==t.context?.source)return;t.claimed=!0;const r=t.context.parentNode;if(r){const e=this.#u(r),n=this.#p(e,r);if(!n&&(this.#s.has(r)||this.#o.has(r)))return;this.#g(r,t.rows??[]),this.broadcast("tree-load-end",{key:e,row:r,depth:n?.depth??this.rowKeyMap.get(e)?.depth??0,childCount:t.rows?.length??0}),this.requestRender()}}),this.on("datasource:error",e=>{const t=e;if("tree"!==t.context?.source)return;const r=t.context.parentNode;if(!r)return;const n=this.#u(r),i=this.#p(n,r);i&&(this.broadcast("tree-load-error",{key:n,row:r,depth:i.depth,error:t.error}),this.requestRender())})}get animationStyle(){return!!this.isAnimationEnabled&&(this.config.animation??"slide")}detect(e){if(!this.config.autoDetect)return!1;const t=e,r=this.config.childrenField??function(e){if(!Array.isArray(e)||0===e.length)return null;const t=["children","items","nodes","subRows","nested"];for(const r of e)if(r&&"object"==typeof r)for(const e of t){const t=r[e];if(Array.isArray(t)&&t.length>0)return e}return null}(t)??"children";return f(t,r)}processRows(e){const t=this.grid?.getPluginByName?.("hierarchy");return t?t.process(e,this):n(e,[this])}beginHierarchy(e){const t=e;if(0===t.length||!f(t,this.config.childrenField??"children",this.config.hasChildren))return this.flattenedRows=[],this.#e=[],this.#t=0,this.rowKeyMap.clear(),this.previousVisibleKeys.clear(),this.#w(t),this.#y(),!1;const r="server"===this.grid?.query?.("datasource:sort-mode",null)?.[0];return this.#r=r?null:this.resolveEffectiveSortState(),this.config.defaultExpanded&&!this.initialExpansionDone&&(this.expandedKeys=g(t,this.config),this.initialExpansionDone=!0),this.#l=/* @__PURE__ */new WeakMap,!0}processSiblings(e,t){const{parentKey:r,depth:n}=t,i=this.config.childrenField??"children",s=this.config.hasChildren;for(let d=0;d<e.length;d++)this.#f(e[d].row,d,r);const o=this.#r,a=o?this.#m(e,o.field,o.direction):e;for(let d=0;d<a.length;d++){const e=a[d],t=e.row,o=this.#f(t,d,r),l=t[i],h=Array.isArray(l)&&l.length>0,c=h||!0!==t.__loading&&(s?s(t):null!=l&&!Array.isArray(l)&&!!l),u=this.expandedKeys.has(o);this.#l.set(t,{key:o,data:t,depth:n,hasChildren:c,isExpanded:u,parentKey:r,posInSet:d+1,setSize:a.length}),e.key=o,h&&u&&(e.expanded=!0,e.children=l.map(e=>({row:e})))}return a}endHierarchy(e,t){const r=this.#l;this.#l=/* @__PURE__ */new WeakMap,this.flattenedRows=[],this.rowKeyMap.clear(),this.keysToAnimate.clear();const n=/* @__PURE__ */new Set,i=new Array(e.length);let s=-1;for(let o=0;o<e.length;o++){const a=e[o],d=r.get(a);if(null===d?.parentKey&&s++,i[o]=s,!d)continue;const l=t(a)?.level;void 0!==l&&(d.depth=l-1),this.flattenedRows.push(d),this.rowKeyMap.set(d.key,d),this.#l.set(a,d),n.add(d.key),!this.previousVisibleKeys.has(d.key)&&d.depth>0&&this.keysToAnimate.add(d.key),this.#b(d)&&this.#x(d)}return this.previousVisibleKeys=n,this.#e=i,this.#t=s+1,this.#y(),!0}#y(){this.#c||(this.#c=!0,queueMicrotask(()=>{this.#c=!1,this.grid&&this.#h!==this.flattenedRows.length>0&&this.requestColumnsRender()}))}#f(e,t,r){if(void 0!==e.id){const t=String(e.id);return this.#d.set(e,t),t}const n=this.#d.get(e);if(void 0!==n)return n;const i=r?`${r}-${t}`:String(t);return this.#d.set(e,i),i}#m(e,t,r){const n=/* @__PURE__ */new Map;for(const i of e)n.set(i.row,i);return this.#v(e.map(e=>e.row),t,r).map(e=>n.get(e)??{row:e})}#v(e,r,n){const i=this.grid,s=i?._columns??[],o={field:r,direction:n},a=[...e],d=(i?.effectiveConfig?.sortHandler??t)(a,o,s);return d&&"function"==typeof d.then?(d.catch(()=>{}),t(a,o,s)):d}#u(e){return this.#d.get(e)??String(e.id??"?")}#g(e,t){e[this.config.childrenField??"children"]=t,this.#i.add(e)}#R(e){if(this.#i.has(e))return!1;const t=e[this.config.childrenField??"children"];if(Array.isArray(t)&&t.length>0)return!1;const r=this.config.hasChildren;return r?r(e):null!=t&&!Array.isArray(t)&&!!t}#b(e){if(!0===e.data.__loading)return!1;const t=this.#n.get(e.key);return t?t.row!==e.data:e.isExpanded&&e.hasChildren&&!this.#s.has(e.data)&&this.#R(e.data)}#w(e){if(0===this.#n.size)return;const t=/* @__PURE__ */new Map;for(let r=0;r<e.length;r++){const n=e[r];if(!0===n.__loading)continue;const i=void 0!==n.id?String(n.id):this.#d.get(n)??String(r);this.#n.has(i)&&t.set(i,n)}for(const[r,n]of t)this.#n.get(r)?.row!==n&&this.#x({key:r,data:n,depth:0,hasChildren:!1,isExpanded:!1,parentKey:null,posInSet:0,setSize:0},!0)}#x(e,t=!1){this.#a.push({meta:e,flat:t})>1||queueMicrotask(()=>{const e=this.#a;if(this.#a=[],!this.grid)return;let t=!1;for(const{meta:r,flat:n}of e){if(!n&&this.rowKeyMap.get(r.key)?.data!==r.data)continue;const e=this.#n.get(r.key);e&&e.row!==r.data&&this.#C(r.key),n||!this.expandedKeys.has(r.key)||this.#s.has(r.data)||(this.#s.add(r.data),t=this.requestLazyChildren(r)||t)}t&&this.requestRender()})}requestLazyChildren(e){const{key:t,depth:r,data:n}=e,i=this.#n.get(t);if(i?.row===n)return!1;if(!this.#R(n))return!1;const s=this.queryBoolean("datasource:is-active"),{loadChildren:o}=this.config;if(!s&&!o)return!1;i&&this.#C(t);const a=new AbortController;return this.#n.set(t,{row:n,depth:r,controller:a}),this.#s.add(n),this.#o.delete(n),this.broadcast("tree-load-start",{key:t,row:n,depth:r}),s?(this.grid.query("datasource:fetch-children",{context:{source:"tree",parentNode:n,nodePath:[t]},signal:a.signal}),!0):(this.#k(t,n,r,a),!0)}#S(e){return this.#n.get(e.key)?.row===e.data}#p(e,t){const r=this.#n.get(e);if(r?.row===t)return this.#n.delete(e),r}#C(e){const t=this.#n.get(e);t&&(this.#n.delete(e),this.#s.delete(t.row),this.#o.add(t.row),t.controller.abort(),this.broadcast("tree-load-end",{key:e,row:t.row,depth:t.depth,childCount:0,cancelled:!0}))}#k(e,t,r,n){const i=this.config.loadChildren,s=()=>!n.signal.aborted&&(this.#n.delete(e),!0),o=n=>{if(!s())return;const i=n??[];this.#g(t,i),this.broadcast("tree-load-end",{key:e,row:t,depth:r,childCount:i.length}),this.requestRender()},a=n=>{s()&&(this.broadcast("tree-load-error",{key:e,row:t,depth:r,error:n}),this.requestRender())};let d;try{d=i({row:t,key:e,depth:r,signal:n.signal})}catch(l){return void a(l)}if(d&&"function"==typeof d.subscribe){let e=!1,t=null;const r=()=>{e=!0,t?.unsubscribe(),t=null},i=d.subscribe({next:e=>{o(e),r()},error:e=>{a(e),r()}});return e?void i.unsubscribe():(t=i,void n.signal.addEventListener("abort",r,{once:!0}))}Promise.resolve(d).then(o,a)}resolveEffectiveSortState(){const e=this.grid?.query?.("sort:get-model",null);if(Array.isArray(e)&&e.length>0){const t=e[0];if(Array.isArray(t)&&t.length>0)return{field:t[0].field,direction:"desc"===t[0].direction?-1:1}}return this.sortState}processColumns(e){if(0===this.flattenedRows.length){const t=[...e];if(this.#h){const e=t.findIndex(e=>e.field===this.wrappedTreeColumnField);e>=0&&(t[e]={...t[e],renderer:"renderer"===this.originalTreeColumnRendererProperty?this.originalTreeColumnRenderer:void 0})}return this.#h=!1,this.originalTreeColumnRenderer=void 0,this.originalTreeColumnRendererProperty="viewRenderer",this.wrappedTreeColumnField=void 0,t}const t=[...e];if(0===t.length)return t;const{treeColumn:r}=this.config;let n=0;if(r){const e=t.findIndex(e=>e.field===r);e>=0&&(n=e)}const o=t[n],a=o.field;this.wrappedTreeColumnField!==a&&(this.originalTreeColumnRenderer=o.renderer||o.viewRenderer,this.originalTreeColumnRendererProperty=o.renderer?"renderer":"viewRenderer",this.wrappedTreeColumnField=a);const d=this.originalTreeColumnRenderer,l=()=>this.config,h=this.setIcon.bind(this);return t[n]={...o,renderer:e=>{const{row:t,value:r}=e,{showExpandIcons:n=!0,indentWidth:o}=l(),a=this.#l.get(t),u=a?.depth??0,p=document.createElement("span");if(p.className="tree-cell-wrapper",p.style.setProperty("--tbw-tree-depth",String(u)),void 0!==o&&p.style.setProperty("--tbw-tree-indent-width",`${o}px`),n)if(a&&this.#S(a)){const e=function(e){const t=document.createElement("div");return t.className=`tbw-spinner tbw-spinner--${e}`,t.setAttribute("role","progressbar"),t.setAttribute("aria-label","Loading"),t}("small");e.classList.add("tree-loading"),p.appendChild(e)}else if(a&&a.hasChildren){const e=document.createElement("span");e.className=`${s}${a.isExpanded?` ${i}`:""}`,h(e,a.isExpanded?"collapse":"expand"),e.setAttribute("data-tree-key",a.key),p.appendChild(e)}else{const e=document.createElement("span");e.className="tree-spacer",p.appendChild(e)}const g=document.createElement("span");if(g.className="tree-content",d){const t=d(e);t instanceof Node?g.appendChild(t):"string"==typeof t&&(w=g,(y=t)&&"string"==typeof y?-1!==y.indexOf("<")||-1!==y.indexOf("&")?w.replaceChildren(c(y)):w.textContent=y:w.replaceChildren())}else g.textContent=null!=r?String(r):"";var w,y;return p.appendChild(g),p}},this.#h=!0,t}onCellClick(e){const t=e.originalEvent?.target;if(!t?.classList.contains(s))return!1;const r=t.getAttribute("data-tree-key");if(!r)return!1;const n=this.rowKeyMap.get(r);return!!n&&(this.expandedKeys=p(this.expandedKeys,r),this.expandedKeys.has(r)&&this.requestLazyChildren(n),this.broadcast("tree-expand",{key:r,row:n.data,expanded:this.expandedKeys.has(r),depth:n.depth,expandedKeys:[...this.expandedKeys]}),this.requestRender(),!0)}onKeyDown(e){if(" "!==e.key)return;const t=this.grid._focusRow,r=this.#l.get(this.rows[t]);return r?.hasChildren?(e.preventDefault(),this.expandedKeys=p(this.expandedKeys,r.key),this.expandedKeys.has(r.key)&&this.requestLazyChildren(r),this.broadcast("tree-expand",{key:r.key,row:r.data,expanded:this.expandedKeys.has(r.key),depth:r.depth,expandedKeys:[...this.expandedKeys]}),this.requestRenderWithFocus(),!0):void 0}onHeaderClick(e){if(0===this.flattenedRows.length||!e.column.sortable)return!1;const t=this.grid?.query?.("sort:get-model",null);if(Array.isArray(t)&&t.length>0)return!1;const{field:r}=e.column;this.sortState&&this.sortState.field===r?1===this.sortState.direction?this.sortState={field:r,direction:-1}:this.sortState=null:this.sortState={field:r,direction:1};const n=this.grid;return void 0!==n._sortState&&(n._sortState=this.sortState?{...this.sortState}:null),this.broadcast("sort-change",{field:r,direction:this.sortState?.direction??0}),this.requestRender(),!0}afterRender(){const e=this.gridElement?.querySelector(".rows");if(!e)return;const t=this.animationStyle,r=!1!==t&&this.keysToAnimate.size>0,n="fade"===t?"tbw-tree-fade-in":"tbw-tree-slide-in";for(const i of e.querySelectorAll(".data-grid-row")){const e=this.#l.get(i.__rowDataRef);e&&(e.hasChildren?i.setAttribute("aria-expanded",String(e.isExpanded)):i.hasAttribute("aria-expanded")&&i.removeAttribute("aria-expanded"),i.classList.toggle("tbw-row-expanded",e.hasChildren&&e.isExpanded),this.#S(e)?i.setAttribute("aria-busy","true"):i.hasAttribute("aria-busy")&&!i.classList.contains("tbw-row-loading")&&i.removeAttribute("aria-busy"),r&&e.key&&this.keysToAnimate.has(e.key)&&(i.classList.add(n),i.addEventListener("animationend",()=>i.classList.remove(n),{once:!0})))}this.keysToAnimate.clear()}expand(e){this.expandedKeys.add(e);const t=this.rowKeyMap.get(e);t&&this.requestLazyChildren(t),this.requestRender()}collapse(e){this.expandedKeys.delete(e),this.requestRender()}toggle(e){this.expandedKeys=p(this.expandedKeys,e);const t=this.rowKeyMap.get(e);t?(this.expandedKeys.has(e)&&this.requestLazyChildren(t),this.broadcast("tree-expand",{key:e,row:t.data,expanded:this.expandedKeys.has(e),depth:t.depth,expandedKeys:[...this.expandedKeys]})):this.emitPluginEvent("tree-expand",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}expandAll(){this.expandedKeys=g(this.rows,this.config),this.emitPluginEvent("tree-expand",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}collapseAll(){this.expandedKeys=/* @__PURE__ */new Set,this.emitPluginEvent("tree-expand",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}isExpanded(e){return this.expandedKeys.has(e)}getExpandedKeys(){return[...this.expandedKeys]}getFlattenedRows(){return[...this.flattenedRows]}getRowMeta(e){return this.#l.get(e)}getRowByKey(e){return this.rowKeyMap.get(e)?.data}expandToKey(e){this.expandedKeys=y(this.rows,e,this.config,this.expandedKeys),this.requestRender()}};export{m as TreePlugin};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|