@evotecit/canopyx 0.3.11 → 0.3.15
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/CanopyX.Html/Assets/canopyx-calendar-edit.js +36 -18
- package/CanopyX.Html/Assets/canopyx-calendar-ics.js +7 -5
- package/CanopyX.Html/Assets/canopyx-calendar.css +124 -116
- package/CanopyX.Html/Assets/canopyx-calendar.js +74 -54
- package/CanopyX.Html/Assets/canopyx-cell-range.css +8 -8
- package/CanopyX.Html/Assets/canopyx-cell-range.js +1 -1
- package/CanopyX.Html/Assets/canopyx-changes.css +113 -113
- package/CanopyX.Html/Assets/canopyx-changes.js +7 -10
- package/CanopyX.Html/Assets/canopyx-column-groups.css +5 -5
- package/CanopyX.Html/Assets/canopyx-column-groups.js +1 -1
- package/CanopyX.Html/Assets/canopyx-data.js +2 -2
- package/CanopyX.Html/Assets/canopyx-detail-rows.css +9 -9
- package/CanopyX.Html/Assets/canopyx-detail-rows.js +2 -2
- package/CanopyX.Html/Assets/canopyx-editing.css +18 -18
- package/CanopyX.Html/Assets/canopyx-editing.js +1 -1
- package/CanopyX.Html/Assets/canopyx-enhance.js +2 -2
- package/CanopyX.Html/Assets/canopyx-export.js +8 -4
- package/CanopyX.Html/Assets/canopyx-facets.css +33 -33
- package/CanopyX.Html/Assets/canopyx-facets.js +10 -11
- package/CanopyX.Html/Assets/canopyx-filter-editor.css +57 -57
- package/CanopyX.Html/Assets/canopyx-filter-editor.js +15 -11
- package/CanopyX.Html/Assets/canopyx-flow-checks.css +11 -11
- package/CanopyX.Html/Assets/canopyx-flow-checks.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-command.css +7 -7
- package/CanopyX.Html/Assets/canopyx-flow-command.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-dialog.css +7 -7
- package/CanopyX.Html/Assets/canopyx-flow-dialog.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-drafts.css +7 -7
- package/CanopyX.Html/Assets/canopyx-flow-drafts.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-entry.css +17 -76
- package/CanopyX.Html/Assets/canopyx-flow-entry.js +9 -3
- package/CanopyX.Html/Assets/canopyx-flow-host.css +4 -4
- package/CanopyX.Html/Assets/canopyx-flow-host.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-module.mjs +9 -3
- package/CanopyX.Html/Assets/canopyx-flow-pick.css +4 -4
- package/CanopyX.Html/Assets/canopyx-flow-pick.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-preview.css +6 -6
- package/CanopyX.Html/Assets/canopyx-flow-preview.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-records.css +3 -3
- package/CanopyX.Html/Assets/canopyx-flow-records.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-tasks.css +17 -17
- package/CanopyX.Html/Assets/canopyx-flow-tasks.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow.css +79 -79
- package/CanopyX.Html/Assets/canopyx-flow.js +1 -1
- package/CanopyX.Html/Assets/canopyx-format-editor.css +23 -23
- package/CanopyX.Html/Assets/canopyx-format-editor.js +2 -3
- package/CanopyX.Html/Assets/canopyx-formatting.css +17 -17
- package/CanopyX.Html/Assets/canopyx-formatting.js +5 -5
- package/CanopyX.Html/Assets/canopyx-forms.css +5 -5
- package/CanopyX.Html/Assets/canopyx-forms.js +1 -1
- package/CanopyX.Html/Assets/canopyx-grid-module.mjs +134 -77
- package/CanopyX.Html/Assets/canopyx-grid-options.css +10 -0
- package/CanopyX.Html/Assets/canopyx-grid-options.js +47 -0
- package/CanopyX.Html/Assets/canopyx-grid.css +199 -261
- package/CanopyX.Html/Assets/canopyx-grid.js +134 -77
- package/CanopyX.Html/Assets/canopyx-grouping.css +17 -17
- package/CanopyX.Html/Assets/canopyx-grouping.js +12 -9
- package/CanopyX.Html/Assets/canopyx-highlight.css +14 -14
- package/CanopyX.Html/Assets/canopyx-highlight.js +2 -2
- package/CanopyX.Html/Assets/canopyx-interactive.css +94 -155
- package/CanopyX.Html/Assets/canopyx-interactive.js +58 -24
- package/CanopyX.Html/Assets/canopyx-labels-de.js +5 -0
- package/CanopyX.Html/Assets/canopyx-labels-es.js +5 -0
- package/CanopyX.Html/Assets/canopyx-labels-fr.js +5 -0
- package/CanopyX.Html/Assets/canopyx-labels-it.js +5 -0
- package/CanopyX.Html/Assets/canopyx-labels-pl.js +5 -0
- package/CanopyX.Html/Assets/canopyx-layouts.css +17 -17
- package/CanopyX.Html/Assets/canopyx-layouts.js +4 -12
- package/CanopyX.Html/Assets/canopyx-link.css +7 -7
- package/CanopyX.Html/Assets/canopyx-link.js +1 -1
- package/CanopyX.Html/Assets/canopyx-live.css +9 -9
- package/CanopyX.Html/Assets/canopyx-live.js +2 -2
- package/CanopyX.Html/Assets/canopyx-matrix.css +74 -74
- package/CanopyX.Html/Assets/canopyx-matrix.js +3 -4
- package/CanopyX.Html/Assets/canopyx-module.mjs +58 -24
- package/CanopyX.Html/Assets/canopyx-pager.css +2 -2
- package/CanopyX.Html/Assets/canopyx-pager.js +1 -1
- package/CanopyX.Html/Assets/canopyx-presenters.js +11 -0
- package/CanopyX.Html/Assets/canopyx-record-panel.css +49 -49
- package/CanopyX.Html/Assets/canopyx-record-panel.js +13 -11
- package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +142 -84
- package/CanopyX.Html/Assets/canopyx-reporting.css +214 -276
- package/CanopyX.Html/Assets/canopyx-reporting.js +142 -84
- package/CanopyX.Html/Assets/canopyx-timeline.css +28 -28
- package/CanopyX.Html/Assets/canopyx-timeline.js +11 -10
- package/CanopyX.Html/Assets/canopyx-tree-tools.css +47 -46
- package/CanopyX.Html/Assets/canopyx-tree-tools.js +5 -4
- package/CanopyX.Html/Assets/canopyx.css +81 -142
- package/CanopyX.Html/Assets/canopyx.js +58 -24
- package/JavaScript/calendar.d.ts +15 -0
- package/JavaScript/grid.d.ts +29 -4
- package/JavaScript/hosts.d.ts +11 -0
- package/JavaScript/locales/de.mjs +5 -0
- package/JavaScript/locales/es.mjs +5 -0
- package/JavaScript/locales/fr.mjs +5 -0
- package/JavaScript/locales/it.mjs +5 -0
- package/JavaScript/locales/pl.mjs +5 -0
- package/JavaScript/plugins.d.ts +4 -0
- package/JavaScript/protocol.d.ts +14 -1
- package/JavaScript/records.d.ts +2 -0
- package/README.md +6 -2
- package/package.json +7 -1
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/* Column groups: header rows above the column headers (canopyx.column-groups.source),and the nested Columns menu. */
|
|
2
|
-
.cx-data-grid .cx-hgroup-row{height:var(--cx-
|
|
2
|
+
.cx-data-grid .cx-hgroup-row{height:var(--hfx-table-header-height,calc(40px - var(--cx-compact,0) * 8px));}
|
|
3
3
|
.cx-data-grid.cx-phone .cx-hgroup-row{height:var(--cx-size-32px);}
|
|
4
|
-
.cx-data-grid .cx-hgroup{overflow:visible;justify-content:flex-start;border-bottom:var(--cx-size-1px) solid var(--
|
|
4
|
+
.cx-data-grid .cx-hgroup{overflow:visible;justify-content:flex-start;border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
|
|
5
5
|
.cx-data-grid .cx-hgroup::after{top:0;bottom:0;}
|
|
6
6
|
.cx-data-grid .cx-hgroup-row .cx-hcell:last-child::after{display:block;}
|
|
7
7
|
.cx-data-grid .cx-hgroup-row .cx-hcell:last-child:not(.cx-hgroup)::after,.cx-data-grid .cx-hgroup-pad::after{display:none;}
|
|
8
|
-
.cx-data-grid .cx-hgroup-title{position:sticky;left:calc(var(--cx-pin-left-w,0px) + var(--
|
|
8
|
+
.cx-data-grid .cx-hgroup-title{position:sticky;left:calc(var(--cx-pin-left-w,0px) + var(--hfx-cell-padding-x,calc(12px - var(--cx-compact,0) * 4px)));min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
|
9
9
|
.cx-data-grid .cx-hgroup[data-cx-pin] .cx-hgroup-title{position:static;}
|
|
10
10
|
.cx-data-grid .cx-hgroup .cx-column-move{flex:none;}
|
|
11
|
-
.cx-data-grid .cx-hgroup.cx-drop-before{box-shadow:inset var(--cx-size-2px) 0 var(--
|
|
12
|
-
.cx-data-grid .cx-hgroup.cx-drop-after{box-shadow:inset var(--cx-size-neg-2px) 0 var(--
|
|
11
|
+
.cx-data-grid .cx-hgroup.cx-drop-before{box-shadow:inset var(--cx-size-2px) 0 var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
|
|
12
|
+
.cx-data-grid .cx-hgroup.cx-drop-after{box-shadow:inset var(--cx-size-neg-2px) 0 var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
|
|
13
13
|
.cx-data-grid.cx-column-groups .cx-hrow:not(.cx-hgroup-row) .cx-hcell::after{top:var(--cx-size-6px);bottom:var(--cx-size-6px);}
|
|
14
14
|
.cx-grid-column-choice{padding-inline-start:calc(var(--cx-level,0) * var(--cx-size-16px));}
|
|
15
15
|
.cx-grid-column-group-choice .cx-grid-column-name{font-weight:600;}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(global){"use strict";const installed=new WeakSet();const part={version:"
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"cd6d93e033719439",install(context){if(installed.has(context.DataGrid.prototype))return;const{DataGrid,h,setText,fill,columnWidth,foldText,gridButton,gridIcon,gridDecorateButton,cellText,cellValue,isCellObject,numberFormat,gridFreeze,requireIdentifier,loadGridFilterEditor,CELL_CONTROLS,reachable}=context;const CG_DEPTH=3,CG_PINS=["left","none","right"];const cgBad=problem=>{throw new Error("CanopyX: column groups "+problem+".")};function cgRead(view){const declared=new Set(view.columns.map(column=>column.id)),owner=new Map(),byId=new Map();if(!Array.isArray(view.columnGroups)||view.columnGroups.length>1000)cgBad("must be an array of at most 1000 groups");const read=(input,parent,depth)=>{if(!input||typeof input!=="object"||Array.isArray(input))cgBad("must be objects");requireIdentifier(input.id,"column group ID");const columns=input.columns??[],groups=input.groups??[];if(byId.has(input.id)||typeof input.title!=="string"||!input.title.trim()||input.title.length>256||depth>CG_DEPTH||
|
|
2
2
|
!Array.isArray(columns)||!Array.isArray(groups)||!columns.length&&!groups.length||
|
|
3
3
|
input.pinned!==undefined&&(parent||![null,"left","right"].includes(input.pinned)))
|
|
4
4
|
cgBad("need unique IDs, titles, members, at most "+CG_DEPTH+" levels, and a pin only on a top-level group");const node={id:input.id,title:input.title,pinned:input.pinned,parent,depth,columns:[],groups:[],leaves:[]};byId.set(node.id,node);for(const id of columns){if(!declared.has(id)||owner.has(id))cgBad("name declared columns, each in one group at most");owner.set(id,node);node.columns.push(id)}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(global){"use strict";const installed=new WeakSet();const part={version:"
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"d74a01c46f1c40cc",install(context){if(installed.has(context.GRID_DATA_IMPL))return;const{GRID_DATA_IMPL,PROTOCOL,validateGridRows,inlineGridSource,loadSidecar,gridIdOrder}=context;const ROW_SCRIPTS=':scope>script[type="application/x-canopyx-rows"]';const nextTask=()=>globalThis.scheduler?.yield?scheduler.yield():new Promise(resolve=>setTimeout(resolve));async function inflateRows(text){if(typeof DecompressionStream!=="function")throw new Error("CanopyX: this browser cannot read compressed row data.");let bytes;if(Uint8Array.fromBase64)bytes=Uint8Array.fromBase64(text);else{const binary=atob(text);bytes=new Uint8Array(binary.length);for(let i=0;i<binary.length;i++)bytes[i]=binary.charCodeAt(i)}
|
|
2
2
|
return new Response(new Blob([bytes]).stream().pipeThrough(new DecompressionStream("gzip"))).text()}
|
|
3
3
|
function rowDataSource(grid,outer){const view=grid.view,data=view.rowData,rows=view.rows,ids=new Set(),declared=new Set(view.columns.map(column=>column.id));const columns=data.columns,chunks=data.chunks,sidecar=data.base!==undefined;if(data.version!==1||!Array.isArray(columns)||!columns.length||new Set(columns).size!==columns.length||columns.some(id=>!declared.has(id))||
|
|
4
4
|
![undefined,"gzip"].includes(data.encoding)||![undefined,true,false].includes(data.ordered)||
|
|
@@ -10,6 +10,6 @@ chunk=JSON.parse(chunk)}
|
|
|
10
10
|
if(!Array.isArray(chunk))throw new Error("CanopyX: a row data chunk is not an array of rows.");const decoded=chunk.map(expand);validateGridRows(decoded,view.columns,ids);if(ordered)for(const row of decoded){if(previous!==null&&gridIdOrder(previous,row.id)>=0){if(!(previous<row.id))throw new Error("CanopyX: row data is not in its declared identity order.");ordered=false;legacyOrder=true;retirePrefix();break}
|
|
11
11
|
previous=row.id}
|
|
12
12
|
for(const row of decoded)rows.push(row);if(rows.length>data.count)break;files[index]=null;advance();waitForChunk();await nextTask()}
|
|
13
|
-
active();if(rows.length!==data.count)throw new Error("CanopyX: row data holds "+rows.length+" rows, not "+data.count+".");finished=true;ids.clear();if(legacyOrder)retirePrefix();if(Array.isArray(chunks))chunks.fill(null);scripts?.forEach(script=>{script.textContent=""});grid.version++;grid.scheduleRender()})();done.catch(()=>outer.reset());done.then(()=>{if(!grid.destroyed){grid.version++;grid.scheduleRender?.()}},()=>{});let complete=null;outer.invalidate=()=>{complete=null};const all=async()=>{await done;return complete||=inlineGridSource(view)};outer.decoded=done;if(!Object.hasOwn(grid,"columnFacetItems"))grid.columnFacetItems=async function(...args){await outer.decoded;return Object.getPrototypeOf(this).columnFacetItems.apply(this,args)};if(view.reporting?.facetColumns?.length)outer.facet=async(request,options)=>(await all()).facet(request,options);return{async query(query,options){if(ordered&&!view.reporting&&!query.search&&!query.filters.length&&!query.filterGroup&&!query.sort.length){const end=Math.min(data.count,query.offset+query.limit);while(rows.length<end&&!finished)await Promise.race([progress,done]);if(options.signal.aborted)throw new DOMException("Grid cancelled.","AbortError");if(!finished&&ordered)return{protocol:PROTOCOL,type:"gridPage",view:view.id,revision:"inline",offset:query.offset,total:data.count,matched:data.count,items:rows.slice(query.offset,end)}}
|
|
13
|
+
active();if(rows.length!==data.count)throw new Error("CanopyX: row data holds "+rows.length+" rows, not "+data.count+".");finished=true;ids.clear();if(legacyOrder)retirePrefix();if(Array.isArray(chunks))chunks.fill(null);scripts?.forEach(script=>{script.textContent=""});grid.version++;grid.scheduleRender()})();done.catch(()=>outer.reset());done.then(()=>{if(!grid.destroyed){grid.version++;grid.scheduleRender?.()}},()=>{});let complete=null;outer.invalidate=()=>{complete=null};const all=async()=>{await done;return complete||=inlineGridSource(view)};outer.decoded=done;if(!Object.hasOwn(grid,"columnFacetItems"))grid.columnFacetItems=async function(...args){await outer.decoded;return Object.getPrototypeOf(this).columnFacetItems.apply(this,args)};if(view.reporting?.facetColumns?.length)outer.facet=async(request,options)=>(await all()).facet(request,options);return{async query(query,options){if(ordered&&!view.reporting&&!view.footers?.length&&!query.search&&!query.filters.length&&!query.filterGroup&&!query.sort.length){const end=Math.min(data.count,query.offset+query.limit);while(rows.length<end&&!finished)await Promise.race([progress,done]);if(options.signal.aborted)throw new DOMException("Grid cancelled.","AbortError");if(!finished&&ordered)return{protocol:PROTOCOL,type:"gridPage",view:view.id,revision:"inline",offset:query.offset,total:data.count,matched:data.count,items:rows.slice(query.offset,end)}}
|
|
14
14
|
return(await all()).query(query,options)}}}
|
|
15
15
|
GRID_DATA_IMPL.source=rowDataSource;installed.add(context.GRID_DATA_IMPL)}};(global.CanopyXParts||=[]).push(["data",part])})(typeof window!=="undefined"?window:globalThis);
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/* ---------- detail rows: the expander,the row and the content inside the visible width ---------- */
|
|
2
|
-
.cx-detail-toggle{flex:none;display:inline-grid;place-items:center;width:var(--cx-size-20px);height:var(--cx-size-20px);margin-inline-end:var(--cx-size-4px);padding:0;border:0;border-radius:var(--
|
|
2
|
+
.cx-detail-toggle{flex:none;display:inline-grid;place-items:center;width:var(--cx-size-20px);height:var(--cx-size-20px);margin-inline-end:var(--cx-size-4px);padding:0;border:0;border-radius:var(--hfx-radius-sm,4px);background:transparent;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));cursor:pointer;}
|
|
3
3
|
.cx-detail-toggle::before{content:"";width:var(--cx-size-6px);height:var(--cx-size-6px);border-right:var(--cx-size-1d6px) solid currentColor;border-bottom:var(--cx-size-1d6px) solid currentColor;transform:translateX(var(--cx-size-neg-1px)) rotate(-45deg);transition:transform .12s;}
|
|
4
4
|
.cx-detail-toggle[aria-expanded="true"]::before{transform:translateY(var(--cx-size-neg-1px)) rotate(45deg);}
|
|
5
|
-
.cx-detail-toggle:hover{color:var(--
|
|
6
|
-
.cx-detail-toggle:focus-visible{outline:var(--
|
|
7
|
-
.cx-detail-toggle[aria-expanded="true"]{color:var(--
|
|
8
|
-
.cx-data-grid .cx-row.cx-detail-row{background:var(--
|
|
9
|
-
.cx-data-grid .cx-row.cx-detail-row:hover{background:var(--
|
|
5
|
+
.cx-detail-toggle:hover{color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));}
|
|
6
|
+
.cx-detail-toggle:focus-visible{outline:var(--hfx-focus-width,2px) solid var(--hfx-color-focus-ring,light-dark(#02726a,#37c9b8));outline-offset:var(--hfx-focus-offset,2px);}
|
|
7
|
+
.cx-detail-toggle[aria-expanded="true"]{color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
|
|
8
|
+
.cx-data-grid .cx-row.cx-detail-row{background:var(--hfx-color-row-alt,light-dark(#fafafa,#1d1f23));border-bottom:var(--cx-size-1px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));}
|
|
9
|
+
.cx-data-grid .cx-row.cx-detail-row:hover{background:var(--hfx-color-row-alt,light-dark(#fafafa,#1d1f23));}
|
|
10
10
|
.cx-data-grid .cx-detail-cell{flex:none;width:100%;padding:0;border-right:0;overflow:visible;}
|
|
11
11
|
.cx-data-grid .cx-detail-row .cx-detail-body{padding:var(--cx-size-10px) var(--cx-size-12px) var(--cx-size-12px);box-sizing:border-box;}
|
|
12
|
-
.cx-detail-pending{color:var(--
|
|
13
|
-
.cx-detail-error{margin:0 0 var(--cx-size-8px);color:var(--
|
|
14
|
-
.cx-detail-view{height:var(--cx-size-320px);border:var(--cx-size-1px) solid var(--
|
|
12
|
+
.cx-detail-pending{color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-style:italic;}
|
|
13
|
+
.cx-detail-error{margin:0 0 var(--cx-size-8px);color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
|
|
14
|
+
.cx-detail-view{height:var(--cx-size-320px);border:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));}
|
|
15
15
|
.cx-detail-view.cx-host{padding:0;}
|
|
16
16
|
.cx-phone .cx-detail-view{height:var(--cx-size-280px);}
|
|
17
17
|
@media (prefers-reduced-motion:reduce){.cx-detail-toggle::before{transition:none;}}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(global){"use strict";const installed=new WeakSet();const part={version:"
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"e4150bb67f40d597",install(context){if(installed.has(context.DataGrid.prototype))return;const{DataGrid,GRID_ROWS,GRID_REPORTING,h,setText,fill,gridButton,gridFreeze,cellText,formatting,labelsFor,requireIdentifier,GridRowOffsets,TreeGrid,createDataGrid,createTreeGrid,disposeRowHostCells,OWN_ARROWS,hostHtml}=context;const ROWS_BASE={};for(const name of["render","renderPass","trimInactiveCache","syncRowOffsets","setFocus","onKey","fillRow","destroy"])
|
|
2
2
|
ROWS_BASE[name]=DataGrid.prototype[name];GRID_ROWS.view=ROWS_BASE;function rowsLowerBound(list,value){let low=0,high=list.length;while(low<high){const middle=(low+high)>>>1;if(list[middle]<value)low=middle+1;else high=middle}
|
|
3
3
|
return low}
|
|
4
4
|
function rowsAtOrBefore(list,value,field){let low=0,high=list.length;while(low<high){const middle=(low+high)>>>1;if(list[middle][field]<=value)low=middle+1;else high=middle}
|
|
@@ -38,7 +38,7 @@ return ROWS_BASE.destroy.call(this)}});const DETAIL_FOCUSABLE="a[href],button:no
|
|
|
38
38
|
body.replaceChildren(fragment)}else if(["grid","tree","source"].some(name=>typeof options[name]==="function")||declared.view){await this.nestedDetail(entry,row,context)}else this.payloadDetail(body,row.detail)}catch(error){if(signal.aborted||this.destroyed)return;body.replaceChildren();const message=h("p","cx-detail-error");setText(message,fill(this.labels.gridDetailFailed,{error:error.message}));body.appendChild(message);body.appendChild(gridButton(this.labels.gridRetry,()=>{entry.controller.abort();entry.controller=new AbortController();entry.api?.destroy();entry.api=null;entry.ready=this.fillDetail(entry,id,record)}));this.emit("error",{error})}finally{body.classList.remove("cx-detail-pending");if(!this.destroyed){this.detailMeasure=true;this.scheduleRender()}}},async nestedDetail(entry,row,context){const options=this.opts.detail||{},declared=this.view.reporting?.detail||{};const factory=typeof options.grid==="function"?options.grid:typeof options.tree==="function"?options.tree:null;const spec=factory?await factory(row,context):null;if(factory&&(!spec||typeof spec!=="object"||!spec.view||typeof spec.view!=="object"))
|
|
39
39
|
throw new Error("CanopyX: a nested detail returns { view, source?, options? }.");if(!spec&&!declared.view)throw new Error("CanopyX: a detail source needs the definition's detail view.");const source=spec?spec.source:typeof options.source==="function"?await options.source(row,context):undefined;const view=JSON.parse(JSON.stringify(spec?spec.view:declared.view)),tree=view?.type==="view",payload=row.detail;if(!view||!["grid","view"].includes(view.type))throw new Error("CanopyX: a nested detail view is a grid or a tree document.");if(!source&&view.source?.kind!=="host"&&(tree?!view.roots?.length:!view.rows?.length)){if(tree?payload?.type!=="tree"||!Array.isArray(payload.roots):payload?.type!=="grid"||!Array.isArray(payload.rows))
|
|
40
40
|
throw new Error("CanopyX: the record has no " +(tree?"tree":"grid")+ " detail payload.");view.source={kind:"inline"};if(tree)view.roots=payload.roots;else view.rows=payload.rows}
|
|
41
|
-
delete view.stateKey;delete view.deepLink;if(context.signal.aborted)return;const host=h("div","cx-detail-view");
|
|
41
|
+
delete view.stateKey;delete view.deepLink;if(context.signal.aborted)return;const host=h("div","cx-detail-view");entry.body.replaceChildren(host);entry.api=(tree?createTreeGrid:createDataGrid)(host,{labels:this.opts.labels,toolbar:false,...(spec?.options||{}),view,...(source?{source}:{})});await entry.api.ready},payloadDetail(body,payload){if(!payload||typeof payload!=="object"||!["table","properties","html"].includes(payload.type)||
|
|
42
42
|
payload.type==="table"&&(!Array.isArray(payload.columns)||!Array.isArray(payload.rows)||payload.rows.some(item=>!Array.isArray(item)))||
|
|
43
43
|
payload.type==="properties"&&!Array.isArray(payload.items)||payload.type==="html"&&typeof payload.html!=="string")
|
|
44
44
|
throw new Error("CanopyX: a detail payload is a table, properties or html; grid and tree payloads need the definition's detail view.");const holder=h("div");TreeGrid.prototype.renderDetail.call({opts:this.opts,fmt:this.fmt},{detail:payload},holder);body.replaceChildren(...holder.firstChild.childNodes)},disposeDetail(id){const entry=this.detailBodies?.get(id);if(!entry)return;this.detailBodies.delete(id);entry.controller.abort();entry.events.abort();try{entry.api?.destroy()}catch(error){console.error(error)}
|
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
/* Editing part: editors in cells,changed and invalid marks,messages,the edit bar and the drawer's edit form. */
|
|
2
|
-
.cx-data-grid .cx-cell.cx-dirty{background-image:linear-gradient(135deg,var(--
|
|
3
|
-
.cx-data-grid .cx-cell.cx-invalid{background-image:linear-gradient(135deg,var(--
|
|
4
|
-
.cx-data-grid .cx-row.cx-row-invalid > .cx-cell:first-child{box-shadow:inset var(--cx-size-3px) 0 0 var(--
|
|
2
|
+
.cx-data-grid .cx-cell.cx-dirty{background-image:linear-gradient(135deg,var(--hfx-color-accent,light-dark(#11776f,#37c9b8)) 0 var(--cx-size-6px),transparent var(--cx-size-6px));background-repeat:no-repeat;}
|
|
3
|
+
.cx-data-grid .cx-cell.cx-invalid{background-image:linear-gradient(135deg,var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171)) 0 var(--cx-size-6px),transparent var(--cx-size-6px));background-repeat:no-repeat;box-shadow:inset 0 0 0 var(--cx-size-1px) var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
|
|
4
|
+
.cx-data-grid .cx-row.cx-row-invalid > .cx-cell:first-child{box-shadow:inset var(--cx-size-3px) 0 0 var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
|
|
5
5
|
.cx-data-grid .cx-cell.cx-editable{cursor:text;}
|
|
6
6
|
.cx-data-grid .cx-cell.cx-editing{padding:0 var(--cx-size-2px);overflow:visible;}
|
|
7
7
|
.cx-data-grid .cx-cell.cx-editing > :not(.cx-editor-host){display:none;}
|
|
8
8
|
.cx-editor-host{flex:1;min-width:0;height:100%;display:flex;align-items:center;}
|
|
9
9
|
.cx-editor-combo{display:flex;flex:1;min-width:0;height:100%;align-items:center;}
|
|
10
|
-
.cx-editor{box-sizing:border-box;width:100%;min-width:0;height:calc(100% - var(--cx-size-4px));margin:0;padding:0 var(--cx-size-6px);font:inherit;color:var(--
|
|
11
|
-
.cx-editor:focus-visible{box-shadow:0 0 0 var(--cx-size-2px) var(--
|
|
12
|
-
.cx-editor[aria-invalid="true"]{border-color:var(--
|
|
10
|
+
.cx-editor{box-sizing:border-box;width:100%;min-width:0;height:calc(100% - var(--cx-size-4px));margin:0;padding:0 var(--cx-size-6px);font:inherit;color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));border:var(--cx-size-1px) solid var(--hfx-color-accent,light-dark(#11776f,#37c9b8));border-radius:var(--hfx-radius-sm,4px);outline:none;color-scheme:inherit;}
|
|
11
|
+
.cx-editor:focus-visible{box-shadow:0 0 0 var(--cx-size-2px) var(--hfx-color-accent-subtle,light-dark(#e7f1f1,#1b3435));}
|
|
12
|
+
.cx-editor[aria-invalid="true"]{border-color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
|
|
13
13
|
.cx-kind-number .cx-editor{text-align:right;font-variant-numeric:tabular-nums;}
|
|
14
|
-
.cx-editor.cx-editor-toggle{flex:none;width:var(--cx-size-18px);height:var(--cx-size-18px);margin:0 auto 0 var(--cx-size-6px);accent-color:var(--
|
|
15
|
-
.cx-edit-tip{position:fixed;inset:auto;margin:0;box-sizing:border-box;background:var(--
|
|
16
|
-
.cx-edit-tip{max-width:var(--cx-size-280px);padding:var(--cx-size-6px) var(--cx-size-10px);border-left:var(--cx-size-3px) solid var(--
|
|
17
|
-
.cx-editbar{display:flex;align-items:center;gap:var(--cx-size-4px);height:var(--
|
|
14
|
+
.cx-editor.cx-editor-toggle{flex:none;width:var(--cx-size-18px);height:var(--cx-size-18px);margin:0 auto 0 var(--cx-size-6px);accent-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
|
|
15
|
+
.cx-edit-tip{position:fixed;inset:auto;margin:0;box-sizing:border-box;background:var(--hfx-color-surface-raised,light-dark(#ffffff,#1e2126));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));border:var(--cx-size-1px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));border-radius:var(--hfx-radius-overlay,var(--hfx-radius-lg,10px));box-shadow:var(--hfx-elevation-2,0 1px 2px rgba(22,24,28,.05),0 6px 18px -10px rgba(22,24,28,.18));font:var(--cx-size-13d5px)/1.4 var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);}
|
|
16
|
+
.cx-edit-tip{max-width:var(--cx-size-280px);padding:var(--cx-size-6px) var(--cx-size-10px);border-left:var(--cx-size-3px) solid var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));white-space:normal;pointer-events:none;}
|
|
17
|
+
.cx-editbar{display:flex;align-items:center;gap:var(--cx-size-4px);height:var(--hfx-control-height-md,calc(36px - var(--cx-compact,0) * 8px));padding:0 var(--cx-size-4px) 0 var(--cx-size-10px);border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));font-size:var(--cx-size-13d5px);}
|
|
18
18
|
.cx-editbar[hidden]{display:none;}
|
|
19
19
|
.cx-editbar-text{margin-right:var(--cx-size-4px);white-space:nowrap;}
|
|
20
|
-
.cx-editbar-errors{color:var(--
|
|
20
|
+
.cx-editbar-errors{color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
|
|
21
21
|
.cx-data-grid .cx-editbar .cx-btn{height:var(--cx-size-28px);min-height:var(--cx-size-28px);font-size:var(--cx-size-13px);padding:0 var(--cx-size-9px);}
|
|
22
22
|
.cx-data-grid .cx-editbar .icon{width:var(--cx-size-28px);padding:0;}
|
|
23
|
-
.cx-host .cx-edit-save,.cx-host .cx-edit-save:hover{background:var(--
|
|
23
|
+
.cx-host .cx-edit-save,.cx-host .cx-edit-save:hover{background:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));border-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));color:var(--hfx-color-accent-contrast,light-dark(#ffffff,#0c0d10));}
|
|
24
24
|
.cx-host .cx-edit-save:disabled{opacity:.45;}
|
|
25
25
|
.cx-phone .cx-editbar{order:10;flex:1 1 100%;flex-wrap:wrap;height:auto;min-height:var(--cx-size-44px);padding-block:var(--cx-size-4px);}
|
|
26
26
|
.cx-phone .cx-editbar-text{flex:1 1 100%;min-width:0;margin-right:0;white-space:normal;overflow-wrap:anywhere;}
|
|
27
|
-
.cx-drawer.cx-edit-form .cx-dl dd .cx-editor{height:var(--cx-size-34px);border-color:var(--
|
|
28
|
-
.cx-drawer.cx-edit-form .cx-dl dd .cx-editor:focus-visible{border-color:var(--
|
|
29
|
-
.cx-drawer.cx-edit-form .cx-dl dd .cx-editor[aria-invalid="true"]{border-color:var(--
|
|
27
|
+
.cx-drawer.cx-edit-form .cx-dl dd .cx-editor{height:var(--cx-size-34px);border-color:var(--hfx-color-border-control,light-dark(#8a8f98,#6e737c));}
|
|
28
|
+
.cx-drawer.cx-edit-form .cx-dl dd .cx-editor:focus-visible{border-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
|
|
29
|
+
.cx-drawer.cx-edit-form .cx-dl dd .cx-editor[aria-invalid="true"]{border-color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
|
|
30
30
|
.cx-drawer.cx-edit-form.cx-phone .cx-dl dd .cx-editor{height:var(--cx-size-44px);}
|
|
31
31
|
.cx-drawer.cx-edit-form .cx-editor-host{height:auto;}
|
|
32
|
-
.cx-edit-message{margin-top:var(--cx-size-4px);font-size:var(--cx-size-13px);color:var(--
|
|
33
|
-
.cx-drawer-f{flex:none;display:flex;align-items:center;justify-content:flex-end;gap:var(--cx-size-8px);padding:var(--cx-size-12px) var(--cx-size-16px);border-top:var(--cx-size-1px) solid var(--
|
|
34
|
-
.cx-drawer-summary{margin:0 auto 0 0;font-size:var(--cx-size-13px);color:var(--
|
|
32
|
+
.cx-edit-message{margin-top:var(--cx-size-4px);font-size:var(--cx-size-13px);color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
|
|
33
|
+
.cx-drawer-f{flex:none;display:flex;align-items:center;justify-content:flex-end;gap:var(--cx-size-8px);padding:var(--cx-size-12px) var(--cx-size-16px);border-top:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
|
|
34
|
+
.cx-drawer-summary{margin:0 auto 0 0;font-size:var(--cx-size-13px);color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
|
|
35
35
|
@media (forced-colors:active){
|
|
36
36
|
.cx-data-grid .cx-cell.cx-dirty{text-decoration:underline dotted;}
|
|
37
37
|
.cx-data-grid .cx-cell.cx-invalid{outline:var(--cx-size-2px) dashed CanvasText;outline-offset:calc(-1 * var(--cx-size-2px));}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(global){"use strict";const installed=new WeakSet();const part={version:"
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"579a74b205923fd5",requires:["filter-editor","forms"],install(context){if(installed.has(context.DataGrid.prototype))return;const{DataGrid,FORMS_IMPL,h,setText,fill,gridButton,gridDecorateButton,GRID_ICONS,cellValue,cellText,isCellObject,gridFreeze,gridMomentFromParts,numberFormat,gridQuery,foldText,requireIdentifier,checkDocument,validateGridRows,inlineGridSource,PROTOCOL,boundedPattern,validateGridFacetPage,RECORD_IMPL}=context;const{EDIT_EDITORS,editOptions,formRuleSpec,formCheck,FORM_LABELS}=FORMS_IMPL;const EDIT_LABELS={...FORM_LABELS,gridEditCell:"Edit {column}",gridEditSave:"Save",gridEditCancel:"Cancel",gridEditDiscard:"Discard",gridEditUndo:"Undo",gridEditRedo:"Redo",gridEditEdited:"Edited",gridEditChanges:"Unsaved changes: {count}",gridEditErrors:"Errors: {count}",gridEditSaving:"Saving…",gridEditSaved:"Saved rows: {count}",gridEditFailed:"Rows not saved: {count}",gridEditConflict:"Someone else changed this row. Reload it and try again.",gridEditRejected:"Not saved: {error}",gridEditNotSaved:"Not saved.",gridEditUndone:"Undone: {column}",gridEditRedone:"Redone: {column}"};const editCopy=value=>gridFreeze(JSON.parse(JSON.stringify(value===undefined?null:value)));const editSame=(left,right)=>left===right||left==null&&right==null;const editScalar=value=>value===null||typeof value==="string"||typeof value==="boolean"||Number.isFinite(value);const editBad=(id,problem)=>{throw new Error("CanopyX: column "+id+" "+problem+".")};function editSpec(column,editors,columns){const id=column.id,raw=column.editor===undefined?{}:typeof column.editor==="string"?{type:column.editor}:column.editor;const rules=column.validation===undefined?{}:column.validation,object=value=>value&&typeof value==="object"&&!Array.isArray(value);if(!object(raw)||!object(rules))editBad(id,"has an invalid editor or validation");const type=raw.type??column.kind;if(typeof type!=="string"||!Object.hasOwn(editors,type))editBad(id,"names an editor nobody registered");const fits={number:["number"],text:["text"],toggle:["text"],date:["datetime","text"],datetime:["datetime","text"],time:["datetime","text"]}[type];if(fits&&!fits.includes(column.kind))editBad(id,"cannot use a "+type+" editor for its kind");const{pattern,rules:checks}=formRuleSpec(raw,rules,problem=>editBad(id,problem));const lookup=raw.lookup??(type==="lookup"?{}:null);if(lookup&&(!object(lookup)||lookup.column!==undefined&&!columns.some(item=>item.id===lookup.column)||
|
|
2
2
|
lookup.limit!==undefined&&!(Number.isInteger(lookup.limit)&&lookup.limit>=1&&lookup.limit<=50)||
|
|
3
3
|
lookup.minLength!==undefined&&!(Number.isInteger(lookup.minLength)&&lookup.minLength>=0&&lookup.minLength<=16)))editBad(id,"has invalid lookup settings");return Object.freeze({id,column,type,editor:gridFreeze({...raw,type}),options:editOptions(raw.options,id),lookup:lookup&&Object.freeze({column:lookup.column??id,limit:lookup.limit??20,minLength:lookup.minLength??1}),pattern,rules:checks})}
|
|
4
4
|
function editCell(original,value,text){if(!isCellObject(original)&&text===undefined)return value;const cell=isCellObject(original)?{...original}:{};delete cell.text;delete cell.searchText;delete cell.sort;delete cell.secondary;cell.value=value;if(text!==undefined)cell.text=text;return cell}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(global){"use strict";const installed=new WeakSet();const part={version:"
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"a101e32b0f8a1644",install(context){if(installed.has(context.GRID_ENHANCE_IMPL))return;const{DataGrid,GRID_ENHANCE_IMPL,PROTOCOL,createDataGrid,h,setText,gridQueryRows,gridCompare,gridResultShape,isIdentifier,GRID_REPORTING,loadPart,GRID_PAGER}=context;const ENHANCE_KINDS={text:"text",number:"number",datetime:"datetime",date:"datetime"};const ENHANCE_DATE=/^(\d{4}-\d\d-\d\d)(?:[T ](\d\d:\d\d(?::\d\d(?:\.\d{1,9})?)?)(Z|[+-]\d\d:?\d\d)?)?$/;
|
|
2
2
|
const ENHANCE_NUMBER=/^([^\p{L}\d\s+\-\u2212.,()]{0,3})\s?([+\-\u2212]?)(\(?)(\d[\d\s'\u2019.,\u00a0\u202f]*?)(\)?)(?:\s?[^\p{L}\d\s()]{1,3}|\s\p{L}{1,3})?$/u;
|
|
3
3
|
let enhanceDecimal=null;function enhanceDecimalMark(){if(enhanceDecimal===null){try{enhanceDecimal=new Intl.NumberFormat(document.documentElement.lang||undefined).formatToParts(1.5).find(part=>part.type==="decimal")?.value||"."}
|
|
4
4
|
catch(_){enhanceDecimal="."}}
|
|
@@ -104,7 +104,7 @@ const ENHANCE_OPTIONS=["id","label","noun","columns","data","url","serverSide","
|
|
|
104
104
|
function enhancePager(settings){const pager={lengths:settings.pageLengths===undefined?[10,25,50,100,"all"]:settings.pageLengths};const numbers=settings.pageNumbers===undefined||settings.pageNumbers===true?7:settings.pageNumbers===false?0:settings.pageNumbers;if(numbers)pager.numbers=numbers;for(const name of["lengthMenu","pageInput","firstLast"])if(settings[name]!==undefined)pager[name]=settings[name];pager.info=settings.info===false?"none":settings.info===undefined||settings.info===true?"sentence":settings.info;return pager}
|
|
105
105
|
function enhanceLabels(settings){const labels={};if(settings.texts&&typeof settings.texts==="object")
|
|
106
106
|
for(const[name,text]of Object.entries(settings.texts))if(Object.hasOwn(ENHANCE_TEXTS,name)&&typeof text==="string")labels[ENHANCE_TEXTS[name]]=text;return Object.assign(labels,settings.labels)}
|
|
107
|
-
const ENHANCE_STYLES={caption:"flex:none;padding:var(--cx-size-10px) var(--cx-size-12px) var(--cx-size-2px);color:var(--
|
|
107
|
+
const ENHANCE_STYLES={caption:"flex:none;padding:var(--cx-size-10px) var(--cx-size-12px) var(--cx-size-2px);color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));font-size:var(--cx-size-14px);font-weight:600;line-height:1.35",foot:"flex:none;display:flex;flex-direction:column;gap:var(--cx-size-4px);padding:var(--cx-size-8px) var(--cx-size-12px);border-top:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-size:var(--cx-size-13px)",row:"display:flex;flex-wrap:wrap;gap:var(--cx-size-4px) var(--cx-size-16px);margin:0",value:"color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));font-weight:600;font-variant-numeric:tabular-nums"};function enhanceStyled(tag,className,style){const element=h(tag,className);element.style.cssText=ENHANCE_STYLES[style];return element}
|
|
108
108
|
function enhanceFooter(rows,columns){const foot=enhanceStyled("div","cx-enhanced-foot","foot");for(const values of rows){const line=enhanceStyled("p","cx-enhanced-foot-row","row");values.forEach((text,index)=>{if(!text)return;const item=h("span"),title=index&&columns[index]?columns[index].grid.title:"",value=enhanceStyled("b","","value");if(title){const name=h("span");setText(name,title+" ");item.appendChild(name)}
|
|
109
109
|
setText(value,text);item.appendChild(value);line.appendChild(item)});if(line.firstChild)foot.appendChild(line)}
|
|
110
110
|
return foot.firstChild?foot:null}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(global){"use strict";const installed=new WeakSet();const part={version:"
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"9203882f58fa0155",install(context){if(installed.has(context.EXPORT_IMPL))return;const{DataGrid,EXPORT_IMPL,h,setText,gridButton,gridOption,fill,numberFormat,gridOperationActive,formatting,gridQuery,validateGridCursorPage,validateGridPage,GRID_REPORTING,gridFreeze,cellValue,cellText,isCellObject,exportTimeout,exportFormat,EXPORT_FORMATS,gridExportField}=context;function saveExport(blob,name){const url=URL.createObjectURL(blob),link=h("a");link.href=url;link.download=String(name).replace(/[\\/:*?"<>|\x00-\x1f\x7f\u200e\u200f\u202a-\u202e\u2066-\u2069]/g, "_").replace(/^[. ]+|[. ]+$/g, "_");
|
|
2
2
|
document.body.appendChild(link);link.click();link.remove();setTimeout(()=>URL.revokeObjectURL(url),30000)}
|
|
3
3
|
Object.assign(EXPORT_IMPL,{async run(grid,id,options,capture,format){if(!format)throw new Error("CanopyX: export format '"+id+"' is not available.");const total=capture.request.recordCount,onProgress=options.onProgress;if(onProgress!==undefined&&typeof onProgress!=="function"||options.download!==undefined&&typeof options.download!=="boolean")
|
|
4
4
|
throw new Error("CanopyX: export progress is a callback and download is a boolean.");const timer=new AbortController(),clock=setTimeout(()=>timer.abort(new DOMException("Export timed out.","TimeoutError")),exportTimeout(grid,options));const signal=AbortSignal.any([grid.lifetime.signal,timer.signal,options.signal].filter(Boolean));const failure=()=>signal.reason?.name==="TimeoutError"?new Error("CanopyX: export timed out."):new DOMException("Export cancelled.","AbortError");const phases=["reading","generating","ready"];let phase=-1,done=0,read=0,stop;const report=(name,completed)=>{const next=phases.indexOf(name),count=total===null?completed:Math.min(completed,total);if(signal.aborted||next<phase||!Number.isSafeInteger(completed)||completed<0||next===phase&&count<=done)return;phase=next;done=Math.max(done,count);onProgress?.(Object.freeze({phase:name,completed:done,total}))};const stopped=new Promise((resolve,reject)=>{stop=()=>reject(failure())});signal.addEventListener("abort",stop,{once:true});try{if(signal.aborted)throw failure();const counted=Object.freeze({request:capture.request,rows:async function*(more){read=0;for await(const row of capture.rows({signal:AbortSignal.any([signal,more?.signal].filter(Boolean))})){yield row;if(++read%100===0)report("reading",read)}
|
|
@@ -11,8 +11,12 @@ throw new Error("CanopyX: incomplete cursor export.");expected.matched=page.matc
|
|
|
11
11
|
offset +=this.cursor?page.items.length:request.query.limit;if(this.cursor){cursor=page.nextCursor;if(cursor===undefined)break;if(tokens.has(cursor))throw new Error("CanopyX: cursor export repeated a token.");tokens.add(cursor)}}
|
|
12
12
|
gridOperationActive(this,signal);if(remaining.size)throw new Error("CanopyX: selected IDs absent from revision.")},async exportText(exported,maxRows=50000,delimiter,signal){if(!Number.isInteger(maxRows)||maxRows<1||maxRows>1000000)throw new Error("CanopyX: export row limit is 1 to 1000000.");const request=exported.request;if(request.recordCount>maxRows)throw new Error("CanopyX: client row limit exceeded.");const lines=[request.columns.map(column=>gridExportField(column.title,delimiter)).join(delimiter)];let count=0;for await(const row of exported.rows()){if(++count>maxRows)throw new Error("CanopyX: client row limit exceeded.");lines.push(request.columns.map(column=>{const value=request.values==="raw"?row.cells[column.id]?.value:row.cells[column.id]?.text;return gridExportField(row.level>1&&column.id===this.columns[0].id?" ".repeat(row.level-1)+(value??""):value,delimiter)}).join(delimiter))}
|
|
13
13
|
gridOperationActive(this,signal);return lines.join("\r\n")+ "\r\n"},toCsv(capture,options){return this.exportText(capture,options.maxRows,",",options.signal)},async copy(capture,options){const text=await this.exportText(capture,options.maxRows===undefined?10000:options.maxRows,"\t",options.signal);await gridWriteClipboard(this,text,options.signal);return text},copyFocused(row,cell){if(this.selected.size)return this.copy({scope:"selected"});const columns=this.visibleColumns(),element=this.rendered.get(row),index=cell&&element?this.rowCells(element).indexOf(cell):-1;const text=index>=0?gridExportField(cellText(row.h.cells[columns[index].id],columns[index],this.fmt),"\t"):
|
|
14
|
-
columns.map(column=>gridExportField(cellText(row.h.cells[column.id],column,this.fmt),"\t")).join("\t");return gridWriteClipboard(this,text)},exportToHost(capture,format,options){if(typeof format!=="string"||!format.trim()||typeof this.opts.onExport!=="function")throw new Error("CanopyX: invalid host export.");return this.runGridHook(signal=>this.opts.onExport({format,request:capture.request,capture,signal}),options.signal,exportTimeout(this,options))}});Object.assign(EXPORT_IMPL,{exportFromMenu(action){const{details,panel}=this.exportControl;this.renderGridExport(panel);details.open=true;if(!this.phone&&this.overflow)this.overflow.details.open=false;panel.cxRun(action)}});const exportMenu=function(panel){if(panel.cxRun)return panel.cxFormats();panel.replaceChildren();const reporting=!!this.view.reporting,scope=h("select"),labels=this.labels;
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
columns.map(column=>gridExportField(cellText(row.h.cells[column.id],column,this.fmt),"\t")).join("\t");return gridWriteClipboard(this,text)},exportToHost(capture,format,options){if(typeof format!=="string"||!format.trim()||typeof this.opts.onExport!=="function")throw new Error("CanopyX: invalid host export.");return this.runGridHook(signal=>this.opts.onExport({format,request:capture.request,capture,signal}),options.signal,exportTimeout(this,options))}});Object.assign(EXPORT_IMPL,{exportFromMenu(action){const{details,panel}=this.exportControl;this.renderGridExport(panel);details.open=true;if(!this.phone&&this.overflow)this.overflow.details.open=false;panel.cxRun(action)}});const exportMenu=function(panel){if(panel.cxRun)return panel.cxFormats();panel.replaceChildren();const reporting=!!this.view.reporting,scope=h("select"),labels=this.labels;const menu=this.opts.exportMenu??{};if(!menu||typeof menu!=="object"||Array.isArray(menu)||
|
|
15
|
+
Object.keys(menu).some(key=>!["csv","copy","values"].includes(key))||
|
|
16
|
+
["csv","copy"].some(key=>menu[key]!==undefined&&typeof menu[key]!=="boolean")||
|
|
17
|
+
menu.values!==undefined&&!["raw","display"].includes(menu.values))
|
|
18
|
+
throw new Error("CanopyX: exportMenu supports csv/copy booleans and raw/display values.");scope.setAttribute("aria-label",labels.gridExport);for(const[value,label]of this.exportScopes||[["filtered","gridFilteredResults"],["selected","gridSelectedRows"],["all","gridAllResults"]])
|
|
19
|
+
scope.appendChild(gridOption(value,labels[label]));const status=h("p","cx-grid-delivery-status");status.setAttribute("role","status");const meter=h("progress");meter.setAttribute("aria-label",labels.gridExport);meter.hidden=true;let operation=null,formats=[];panel.cxExportBusy=()=>operation!==null;const cancel=gridButton(labels.gridCancelExport,()=>operation?.abort());cancel.hidden=true;const progress=value=>{if(this.destroyed||!operation||operation.signal.aborted)return;setText(status,fill(value.total===null?labels.gridExportReading:labels.gridExportProgress,{completed:numberFormat(this.lang).format(value.completed),total:value.total===null?"":numberFormat(this.lang).format(value.total)}));if(value.total===null)meter.removeAttribute("value");else{meter.max=Math.max(1,value.total);meter.value=value.completed}};const canExport=()=>this.view.type!=="grid"||this.defaultExportColumns().length>0;const busy=state=>{scope.disabled=state;cancel.hidden=meter.hidden=!state;for(const button of[csv,...formats,copy,this.printButton])if(button)button.disabled=state||!canExport()};const traced=(options,onProgress)=>reporting?{...options,onProgress}:options;panel.cxRun=action=>{if(operation)return;const controller=operation=new AbortController();busy(true);meter.removeAttribute("value");setText(status,labels.loading);Promise.resolve().then(()=>action({scope:scope.value,signal:controller.signal,...(menu.values?{values:menu.values}:{})},progress)).then(()=>{if(!this.destroyed)setText(status,"")},error=>{if(!this.destroyed)setText(status,error.name==="AbortError"?labels.gridExportCancelled:error.message);if(error.name!=="AbortError")this.emit("error",{error})}).finally(()=>{if(operation===controller)operation=null;if(!this.destroyed){const returnFocus=document.activeElement===cancel;busy(false);if(returnFocus)scope.focus()}})};const csv=gridButton(labels.gridDownloadCsv,()=>panel.cxRun(async(options,onProgress)=>{const exported=this.prepareExport(traced(options,onProgress));const text=await this.exportText(exported,50000,",",options.signal);gridOperationActive(this,options.signal);saveExport(new Blob([text],{type:"text/csv;charset=utf-8"}),(exported.request.fileName||this.view.id.replace(/[^a-z0-9_-]/gi, "_")) + ".csv");
|
|
20
|
+
}));const copy=this.copy?gridButton(labels.gridCopy,()=>panel.cxRun((options,onProgress)=>this.copy(traced(options,onProgress)))):h("span");csv.hidden=menu.csv===false;copy.hidden=menu.copy===false;panel.cxFormats=()=>{if(operation)return;formats.forEach(button=>button.remove());try{formats=EXPORT_IMPL.formatsOf(this).filter(format=>format.showInMenu).map(format=>Object.assign(gridButton(format.label,()=>
|
|
17
21
|
panel.cxRun((options,onProgress)=>this.exportAs(format.id,{...options,onProgress}))),{value:format.id}))}catch(error){formats=[];this.emit("error",{error})}
|
|
18
22
|
copy.before(...formats);busy(false);if(!canExport())setText(status,labels.gridNoExportColumns);else if(status.textContent===labels.gridNoExportColumns)setText(status,"")};panel.append(scope,csv,copy,cancel,meter,status);panel.cxFormats()};DataGrid.prototype.renderGridExport=exportMenu;installed.add(context.EXPORT_IMPL)}};(global.CanopyXParts||=[]).push(["export",part])})(typeof window!=="undefined"?window:globalThis);
|
|
@@ -5,66 +5,66 @@
|
|
|
5
5
|
body.cx-page > .cx-facet-frame,body.cx-page > .cx-main > .cx-facet-frame{box-sizing:border-box;height:100vh;padding:12px 16px;}
|
|
6
6
|
body.cx-page > .cx-facet-frame > .cx-data-grid,body.cx-page > .cx-main > .cx-facet-frame > .cx-data-grid{height:auto;min-height:0;}
|
|
7
7
|
body.cx-page > .cx-facet-frame[data-cx-position="side"] > .cx-data-grid,body.cx-page > .cx-main > .cx-facet-frame[data-cx-position="side"] > .cx-data-grid{align-self:stretch;}
|
|
8
|
-
.cx-facets.cx-host{height:auto;min-height:0;border:var(--cx-size-1px) solid var(--
|
|
8
|
+
.cx-facets.cx-host{height:auto;min-height:0;border:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));overflow:hidden;}
|
|
9
9
|
.cx-facets.cx-host[hidden]{display:none;}
|
|
10
10
|
.cx-facets[data-cx-position="side"]{flex:none;width:var(--cx-facets-w,260px);align-self:flex-start;display:flex;flex-direction:column;}
|
|
11
|
-
.cx-facets-h{display:flex;align-items:center;gap:var(--cx-size-6px);min-height:var(--cx-size-44px);padding:var(--cx-size-6px) var(--cx-size-6px) var(--cx-size-6px) var(--cx-size-12px);border-bottom:var(--cx-size-1px) solid var(--
|
|
11
|
+
.cx-facets-h{display:flex;align-items:center;gap:var(--cx-size-6px);min-height:var(--cx-size-44px);padding:var(--cx-size-6px) var(--cx-size-6px) var(--cx-size-6px) var(--cx-size-12px);border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
|
|
12
12
|
.cx-facets-title{flex:1;min-width:0;margin:0;font-size:var(--cx-size-14px);font-weight:600;line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
|
13
|
-
.cx-facets .cx-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--cx-size-6px);min-height:var(--cx-size-28px);padding:0 var(--cx-size-8px);border:var(--cx-size-1px) solid transparent;border-radius:var(--
|
|
14
|
-
.cx-facets .cx-button:hover{background:var(--
|
|
15
|
-
.cx-facets .cx-button:focus-visible,.cx-facet-toggle:focus-visible,.cx-facet-val input:focus-visible,.cx-facets .cx-input:focus-visible{outline:var(--
|
|
13
|
+
.cx-facets .cx-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--cx-size-6px);min-height:var(--cx-size-28px);padding:0 var(--cx-size-8px);border:var(--cx-size-1px) solid transparent;border-radius:var(--hfx-radius-sm,4px);background:transparent;color:var(--hfx-color-text-secondary,light-dark(#4d525b,#b0b4bc));font:inherit;font-size:var(--cx-size-13px);cursor:pointer;}
|
|
14
|
+
.cx-facets .cx-button:hover{background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));}
|
|
15
|
+
.cx-facets .cx-button:focus-visible,.cx-facet-toggle:focus-visible,.cx-facet-val input:focus-visible,.cx-facets .cx-input:focus-visible{outline:var(--hfx-focus-width,2px) solid var(--hfx-color-focus-ring,light-dark(#02726a,#37c9b8));outline-offset:var(--hfx-focus-offset,2px);}
|
|
16
16
|
.cx-facets-toggle{width:var(--cx-size-28px);padding:0;}
|
|
17
17
|
.cx-facets-toggle .cx-ico,.cx-facets-open .cx-ico{width:var(--cx-size-16px);height:var(--cx-size-16px);}
|
|
18
18
|
.cx-data-grid > .cx-facets-open{flex:none;align-self:flex-start;min-height:var(--cx-size-44px);margin:var(--cx-size-8px) var(--cx-size-12px);}
|
|
19
19
|
.cx-facets-list{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;}
|
|
20
20
|
.cx-facets[data-cx-position="top"] .cx-facets-list{display:flex;flex-wrap:wrap;gap:0;overflow-y:visible;}
|
|
21
|
-
.cx-facets[data-cx-position="top"] .cx-facet{flex:1 1 var(--cx-size-210px);min-width:var(--cx-size-180px);max-width:var(--cx-size-320px);border-inline-end:var(--cx-size-1px) solid var(--
|
|
21
|
+
.cx-facets[data-cx-position="top"] .cx-facet{flex:1 1 var(--cx-size-210px);min-width:var(--cx-size-180px);max-width:var(--cx-size-320px);border-inline-end:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
|
|
22
22
|
.cx-facets.cx-facets-closed[data-cx-position="side"]{width:var(--cx-size-44px);}
|
|
23
23
|
.cx-facets.cx-facets-closed .cx-facets-list,.cx-facets.cx-facets-closed .cx-facets-clear{display:none;}
|
|
24
24
|
.cx-facets.cx-facets-closed[data-cx-position="side"] .cx-facets-title{display:none;}
|
|
25
25
|
.cx-facets.cx-facets-closed[data-cx-position="side"] .cx-facets-h{justify-content:center;padding:var(--cx-size-6px) 0;border-bottom:0;}
|
|
26
|
-
.cx-facet{position:relative;border-bottom:var(--cx-size-1px) solid var(--
|
|
26
|
+
.cx-facet{position:relative;border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
|
|
27
27
|
.cx-facet-h{margin:0;font-size:inherit;font-weight:inherit;}
|
|
28
28
|
.cx-facet-top{position:relative;}
|
|
29
|
-
.cx-facets:not([data-cx-position="top"]) .cx-facet-top,.cx-facets.cx-facets-in-sheet .cx-facet-top{position:sticky;top:0;z-index:1;background:var(--
|
|
29
|
+
.cx-facets:not([data-cx-position="top"]) .cx-facet-top,.cx-facets.cx-facets-in-sheet .cx-facet-top{position:sticky;top:0;z-index:1;background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));}
|
|
30
30
|
.cx-facets:not([data-cx-position="top"]) .cx-facet-b,.cx-facets.cx-facets-in-sheet .cx-facet-b{position:relative;z-index:0;}
|
|
31
|
-
.cx-facet-toggle{display:flex;align-items:center;gap:var(--cx-size-6px);width:100%;min-height:var(--cx-size-36px);padding-block:var(--cx-size-6px);padding-inline:var(--cx-size-12px) var(--cx-size-64px);border:0;background:transparent;color:var(--
|
|
32
|
-
.cx-facet-toggle::after{content:"";flex:none;width:var(--cx-size-7px);height:var(--cx-size-7px);margin-inline-start:auto;border-right:var(--cx-size-1d5px) solid var(--
|
|
31
|
+
.cx-facet-toggle{display:flex;align-items:center;gap:var(--cx-size-6px);width:100%;min-height:var(--cx-size-36px);padding-block:var(--cx-size-6px);padding-inline:var(--cx-size-12px) var(--cx-size-64px);border:0;background:transparent;color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));font:inherit;font-size:var(--cx-size-13d5px);font-weight:600;text-align:start;cursor:pointer;}
|
|
32
|
+
.cx-facet-toggle::after{content:"";flex:none;width:var(--cx-size-7px);height:var(--cx-size-7px);margin-inline-start:auto;border-right:var(--cx-size-1d5px) solid var(--hfx-color-text-muted,light-dark(#626770,#8f949d));border-bottom:var(--cx-size-1d5px) solid var(--hfx-color-text-muted,light-dark(#626770,#8f949d));transform:translateY(-25%) rotate(45deg);}
|
|
33
33
|
.cx-facet-toggle[aria-expanded="false"]::after{transform:rotate(-45deg);}
|
|
34
|
-
.cx-facet-toggle:hover{background:var(--
|
|
34
|
+
.cx-facet-toggle:hover{background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));}
|
|
35
35
|
.cx-facet-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
|
36
|
-
.cx-facet-badge{flex:none;min-width:var(--cx-size-20px);height:var(--cx-size-20px);padding:0 var(--cx-size-6px);border-radius:var(--
|
|
36
|
+
.cx-facet-badge{flex:none;min-width:var(--cx-size-20px);height:var(--cx-size-20px);padding:0 var(--cx-size-6px);border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));background:var(--hfx-color-accent-subtle,light-dark(#e7f1f1,#1b3435));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));font-size:var(--cx-size-12px);font-weight:600;line-height:var(--cx-size-20px);text-align:center;}
|
|
37
37
|
.cx-facet-badge[hidden]{display:none;}
|
|
38
38
|
.cx-facets .cx-facet-clear{position:absolute;top:var(--cx-size-4px);inset-inline-end:var(--cx-size-30px);width:var(--cx-size-28px);min-height:var(--cx-size-28px);padding:0;}
|
|
39
39
|
.cx-facets .cx-facet-clear .cx-ico{width:var(--cx-size-14px);height:var(--cx-size-14px);}
|
|
40
|
-
.cx-facet-empty{color:var(--
|
|
40
|
+
.cx-facet-empty{color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-style:italic;}
|
|
41
41
|
.cx-facet-b{padding:0 var(--cx-size-12px) var(--cx-size-10px);}
|
|
42
42
|
.cx-facet-b[hidden]{display:none;}
|
|
43
|
-
.cx-facets .cx-facet-search{width:100%;height:var(--cx-size-30px);margin:0 0 var(--cx-size-6px);padding:0 var(--cx-size-8px);border:var(--cx-size-1px) solid var(--
|
|
43
|
+
.cx-facets .cx-facet-search{width:100%;height:var(--cx-size-30px);margin:0 0 var(--cx-size-6px);padding:0 var(--cx-size-8px);border:var(--cx-size-1px) solid var(--hfx-color-border-control,light-dark(#8a8f98,#6e737c));border-radius:var(--hfx-radius-sm,4px);background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));font:inherit;font-size:var(--cx-size-13px);}
|
|
44
44
|
.cx-facet-values{margin:0;padding:0;list-style:none;}
|
|
45
|
-
.cx-facet-val{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:var(--cx-size-8px);min-height:var(--cx-size-28px);padding:0 var(--cx-size-4px);border-radius:var(--
|
|
46
|
-
.cx-facet-val:hover{background:var(--
|
|
47
|
-
.cx-facet-val input{width:var(--cx-size-16px);height:var(--cx-size-16px);margin:0;accent-color:var(--
|
|
45
|
+
.cx-facet-val{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:var(--cx-size-8px);min-height:var(--cx-size-28px);padding:0 var(--cx-size-4px);border-radius:var(--hfx-radius-sm,4px);font-size:var(--cx-size-13d5px);cursor:pointer;}
|
|
46
|
+
.cx-facet-val:hover{background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));}
|
|
47
|
+
.cx-facet-val input{width:var(--cx-size-16px);height:var(--cx-size-16px);margin:0;accent-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
|
|
48
48
|
.cx-facet-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
|
49
|
-
.cx-facet-n{color:var(--
|
|
50
|
-
.cx-facet-zero .cx-facet-text,.cx-facet-zero .cx-facet-n{color:var(--
|
|
51
|
-
.cx-facets .cx-facet-more{margin-top:var(--cx-size-2px);padding:0 var(--cx-size-4px);color:var(--
|
|
52
|
-
.cx-facet-note{margin:var(--cx-size-6px) 0 0;color:var(--
|
|
49
|
+
.cx-facet-n{color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-size:var(--cx-size-12d5px);font-variant-numeric:tabular-nums;text-align:end;}
|
|
50
|
+
.cx-facet-zero .cx-facet-text,.cx-facet-zero .cx-facet-n{color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
|
|
51
|
+
.cx-facets .cx-facet-more{margin-top:var(--cx-size-2px);padding:0 var(--cx-size-4px);color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
|
|
52
|
+
.cx-facet-note{margin:var(--cx-size-6px) 0 0;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-size:var(--cx-size-12d5px);}
|
|
53
53
|
.cx-facet-note[hidden],.cx-facets [hidden]{display:none;}
|
|
54
|
-
.cx-facet-hist{display:flex;align-items:flex-end;gap:var(--cx-size-2px);height:var(--cx-size-52px);margin:var(--cx-size-4px) 0 var(--cx-size-2px);padding-bottom:var(--cx-size-1px);border-bottom:var(--cx-size-1px) solid var(--
|
|
55
|
-
.cx-facet-bar{flex:1;min-width:var(--cx-size-2px);border-radius:var(--cx-size-2px) var(--cx-size-2px) 0 0;background:color-mix(in srgb,var(--
|
|
56
|
-
.cx-facet-bar:hover{background:color-mix(in srgb,var(--
|
|
57
|
-
.cx-facet-bar.cx-facet-in{background:var(--
|
|
58
|
-
.cx-facet-axis{display:flex;justify-content:space-between;gap:var(--cx-size-8px);margin:0 0 var(--cx-size-6px);color:var(--
|
|
54
|
+
.cx-facet-hist{display:flex;align-items:flex-end;gap:var(--cx-size-2px);height:var(--cx-size-52px);margin:var(--cx-size-4px) 0 var(--cx-size-2px);padding-bottom:var(--cx-size-1px);border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
|
|
55
|
+
.cx-facet-bar{flex:1;min-width:var(--cx-size-2px);border-radius:var(--cx-size-2px) var(--cx-size-2px) 0 0;background:color-mix(in srgb,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)) 22%,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));cursor:pointer;}
|
|
56
|
+
.cx-facet-bar:hover{background:color-mix(in srgb,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)) 40%,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
|
|
57
|
+
.cx-facet-bar.cx-facet-in{background:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
|
|
58
|
+
.cx-facet-axis{display:flex;justify-content:space-between;gap:var(--cx-size-8px);margin:0 0 var(--cx-size-6px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-size:var(--cx-size-12px);font-variant-numeric:tabular-nums;}
|
|
59
59
|
.cx-facet-range{display:grid;grid-template-columns:1fr 1fr;gap:var(--cx-size-8px);}
|
|
60
|
-
.cx-facet-field{display:flex;flex-direction:column;gap:var(--cx-size-2px);min-width:0;color:var(--
|
|
61
|
-
.cx-facet-field .cx-input{width:100%;min-width:0;height:var(--cx-size-30px);padding:0 var(--cx-size-6px);border:var(--cx-size-1px) solid var(--
|
|
60
|
+
.cx-facet-field{display:flex;flex-direction:column;gap:var(--cx-size-2px);min-width:0;color:var(--hfx-color-text-secondary,light-dark(#4d525b,#b0b4bc));font-size:var(--cx-size-12d5px);}
|
|
61
|
+
.cx-facet-field .cx-input{width:100%;min-width:0;height:var(--cx-size-30px);padding:0 var(--cx-size-6px);border:var(--cx-size-1px) solid var(--hfx-color-border-control,light-dark(#8a8f98,#6e737c));border-radius:var(--hfx-radius-sm,4px);background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));font:inherit;font-size:var(--cx-size-13px);color-scheme:inherit;}
|
|
62
62
|
.cx-data-grid .cx-facets-open[hidden]{display:none;}
|
|
63
|
-
.cx-data-grid .cx-facets-open .badge{min-width:var(--cx-size-18px);height:var(--cx-size-18px);padding:0 var(--cx-size-5px);border-radius:var(--
|
|
63
|
+
.cx-data-grid .cx-facets-open .badge{min-width:var(--cx-size-18px);height:var(--cx-size-18px);padding:0 var(--cx-size-5px);border-radius:var(--hfx-radius-badge,var(--hfx-radius-sm,4px));background:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));color:var(--hfx-color-surface,light-dark(#ffffff,#16181c));font-size:var(--cx-size-11px);line-height:var(--cx-size-18px);}
|
|
64
64
|
.cx-facet-sheet.cx-host{position:fixed;inset:0;width:100%;max-width:none;height:100%;max-height:none;margin:0;padding:0;border:0;border-radius:0;flex-direction:column;}
|
|
65
65
|
.cx-facet-sheet.cx-host[open]{display:flex;}
|
|
66
|
-
.cx-facet-sheet::backdrop{background:color-
|
|
67
|
-
.cx-facet-sheet-h{display:flex;align-items:center;gap:var(--cx-size-8px);min-height:var(--cx-size-56px);padding:var(--cx-size-6px) var(--cx-size-12px) var(--cx-size-6px) var(--cx-size-16px);border-bottom:var(--cx-size-1px) solid var(--
|
|
66
|
+
.cx-facet-sheet::backdrop{background:var(--hfx-color-overlay,light-dark(rgba(22,24,28,0.42),rgba(0,0,0,0.66)));}
|
|
67
|
+
.cx-facet-sheet-h{display:flex;align-items:center;gap:var(--cx-size-8px);min-height:var(--cx-size-56px);padding:var(--cx-size-6px) var(--cx-size-12px) var(--cx-size-6px) var(--cx-size-16px);border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
|
|
68
68
|
.cx-facet-sheet-h h2{flex:1;margin:0;font-size:var(--cx-size-16px);}
|
|
69
69
|
.cx-facet-sheet-h .cx-button{min-height:var(--cx-size-44px);padding:0 var(--cx-size-16px);}
|
|
70
70
|
.cx-facets.cx-facets-in-sheet{flex:1;align-self:stretch;width:auto;min-height:0;border:0;border-radius:0;}
|
|
@@ -72,8 +72,8 @@ body.cx-page > .cx-facet-frame[data-cx-position="side"] > .cx-data-grid,body.cx-
|
|
|
72
72
|
.cx-facets.cx-facets-in-sheet .cx-facet{max-width:none;border-inline-end:0;}
|
|
73
73
|
.cx-facets.cx-facets-in-sheet .cx-facet-values{max-height:none;}
|
|
74
74
|
.cx-facets.cx-facets-in-sheet .cx-facets-h{display:none;}
|
|
75
|
-
.cx-facet-sheet-h .cx-facets-clear{min-height:var(--cx-size-44px);padding:0 var(--cx-size-12px);border:0;background:transparent;color:var(--
|
|
76
|
-
.cx-facet-sheet-h .cx-facets-clear:focus-visible{outline:var(--
|
|
75
|
+
.cx-facet-sheet-h .cx-facets-clear{min-height:var(--cx-size-44px);padding:0 var(--cx-size-12px);border:0;background:transparent;color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));font:inherit;font-size:var(--cx-size-14px);cursor:pointer;}
|
|
76
|
+
.cx-facet-sheet-h .cx-facets-clear:focus-visible{outline:var(--hfx-focus-width,2px) solid var(--hfx-color-focus-ring,light-dark(#02726a,#37c9b8));outline-offset:var(--hfx-focus-offset,2px);}
|
|
77
77
|
.cx-facet-sheet-h .cx-facets-clear[hidden]{display:none;}
|
|
78
78
|
.cx-facets.cx-facets-in-sheet .cx-facet-val,.cx-facets.cx-facets-in-sheet .cx-facet-toggle,.cx-facets.cx-facets-in-sheet .cx-button{min-height:var(--cx-size-44px);}
|
|
79
79
|
.cx-facets.cx-facets-in-sheet .cx-facet-clear{top:0;}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(global){"use strict";const installed=new WeakSet();const part={version:"
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"2ffa91f40c9b9b21",install(context){if(installed.has(context.DataGrid.prototype))return;const{DataGrid,h,setText,fill,gridButton,gridIcon,gridQueryStart,gridQueryRows,gridColumnProjection,gridScalar,gridOrder,gridKeyCompare,gridFacetKey,cellText,foldText,numberFormat,gridCellRenderer,gridFreeze,overlayTheme,watchOverlayTheme}=context;function gridColumnGroup(operator,items){const filters=[],groups=[];for(const item of items){if(typeof item==="boolean"){if(item===(operator==="or"))return item;continue}
|
|
2
2
|
if(item.operator===operator){filters.push(...item.filters);groups.push(...item.groups)}
|
|
3
3
|
else(item.groups?groups:filters).push(item)}
|
|
4
4
|
return!filters.length&&!groups.length?operator==="and":!filters.length&&groups.length===1?groups[0]:{operator,filters,groups}}
|
|
@@ -17,8 +17,8 @@ merged.label!==undefined&&(typeof merged.label!=="string"||!merged.label.trim()|
|
|
|
17
17
|
merged.target!==undefined&&!(merged.target instanceof HTMLElement))
|
|
18
18
|
throw new Error("CanopyX: invalid facet panel options.");const hosted=grid.view.source.kind!=="inline"||!!grid.opts.source;if(hosted&&typeof grid.getFacets!=="function")throw new Error("CanopyX: a hosted grid's facet panel needs the reporting runtime.");if(hosted&&facets.some(facet=>!grid.view.reporting?.facetColumns?.includes(facet.column)))
|
|
19
19
|
throw new Error("CanopyX: a hosted grid's facets must be declared reporting facet columns.");return{facets,hosted,position:merged.position||"side",open:merged.open!==false,collapsible:merged.collapsible!==false,width:merged.width||260,label:merged.label||null,target:merged.target||null}}
|
|
20
|
-
function facetDeclaredOrder(grid,column){const presenter=column.presenter,values=grid.view.reporting?.ordering?.[column.id]?.categories||
|
|
21
|
-
(presenter&&(presenter.kind==="enum"||presenter.kind==="state")&&presenter.tones?Object.keys(presenter.tones):null);return values&&values.length?new Map(values.map((value,index)=>[
|
|
20
|
+
function facetDeclaredOrder(grid,column){const presenter=column.presenter,values=column.valueOrder||grid.view.reporting?.ordering?.[column.id]?.categories||
|
|
21
|
+
(presenter&&(presenter.kind==="enum"||presenter.kind==="state")&&presenter.tones?Object.keys(presenter.tones):null);return values&&values.length?new Map(values.map((value,index)=>[gridFacetKey(value,column),index])):null}
|
|
22
22
|
function facetSelection(query,facet){let clauses;try{({clauses}=gridColumnClauses(query,facet.column))}catch(_){return{custom:true,locked:true}}
|
|
23
23
|
if(!clauses.length)return{none:true};if(facet.kind==="list"){const listed=clause=>["in","eq","isNull"].includes(clause.operator)&&!clause.groups;const items=clauses.length!==1?null:clauses[0].groups?clauses[0].operator==="or"&&!clauses[0].groups.length&&clauses[0].filters.every(listed)?clauses[0].filters:null:listed(clauses[0])?clauses:null;return items?{values:items.flatMap(clause=>clause.operator==="isNull"?[null]:clause.values)}:{custom:true}}
|
|
24
24
|
let low=null,high=null,lowOpen=false,open=false;for(const clause of clauses){if(clause.groups||clauses.length>2)return{custom:true};if((clause.operator==="ge"||clause.operator==="gt")&&low===null){low=clause.values[0];lowOpen=clause.operator==="gt"}
|
|
@@ -27,17 +27,17 @@ else return{custom:true}}
|
|
|
27
27
|
return{low,high,lowOpen,open}}
|
|
28
28
|
function facetQuery(query,facet,choice){const predicate=(operator,values=[])=>({column:facet.column,operator,values});try{if(facet.kind==="range"){const base=gridColumnClauses(query,facet.column).query;const bounds=[choice.low!=null&&predicate(choice.lowOpen?"gt":"ge",[choice.low]),choice.high!=null&&predicate(choice.open?"lt":"le",[choice.high])].filter(Boolean);return gridQueryStart(base,{filters:[...base.filters,...bounds]})}
|
|
29
29
|
const raw=choice.filter(value=>value!==null),empty=raw.length<choice.length;const items=[raw.length&&predicate("in",raw),empty&&predicate("isNull")].filter(Boolean);return gridInstallColumnClause(query,facet.column,!items.length?null:items.length===1?items[0]:{operator:"or",filters:items,groups:[]})}catch(_){return query}}
|
|
30
|
-
const facetShape=query=>query?JSON.stringify([query.search,query.searchMode,query.filters,query.filterGroup,query.revision]):"";const facetKey=
|
|
30
|
+
const facetShape=query=>query?JSON.stringify([query.search,query.searchMode,query.filters,query.filterGroup,query.revision]):"";const facetKey=gridFacetKey;function facetInlineCounts(grid,facet,query){const projection=gridColumnProjection(query,facet.column),columns=new Map(grid.view.columns.map(column=>[column.id,column]));const rows=gridQueryRows(grid.view,projection,columns,false),column=facet.def;if(facet.kind==="range"){const values=[];for(const row of rows){const value=gridScalar(row.cells[column.id],column);if(value!==null)values.push(value)}
|
|
31
31
|
return{matched:rows.length,values,complete:true}}
|
|
32
32
|
const buckets=new Map();for(const row of rows){const raw=gridScalar(row.cells[column.id],column),value=column.kind==="datetime"&&raw!==null?new Date(raw).toISOString():raw,key=facetKey(value,column);const bucket=buckets.get(key);if(bucket){bucket.count++;if(typeof value==="string"&&value<bucket.value)bucket.value=value}else buckets.set(key,{value,count:1})}
|
|
33
33
|
const items=[...buckets.values()];return{matched:rows.length,items,totalValues:items.length,truncated:false}}
|
|
34
34
|
async function facetHostedCounts(grid,facet,search,signal){const page=await grid.getFacets(facet.column,{search:search||"",includeCurrentFilter:false,limit:FACET_VALUES,signal});const column=facet.def;if(facet.kind==="range")
|
|
35
35
|
return{matched:page.matched,buckets:page.items.filter(item=>item.value!==null).map(item=>({value:gridScalar(item.value,column),count:item.count})),complete:!page.truncated};return{matched:page.matched,items:page.items.map(item=>({value:item.value,count:item.count})),totalValues:page.totalValues,truncated:page.truncated}}
|
|
36
|
-
const FACET_SEARCH_FROM=12;function facetListBody(panel,facet,body){const grid=panel.grid,search=h("input","cx-input cx-facet-search"),list=h("ul","cx-facet-values"),more=gridButton("",()=>{state.expanded=!state.expanded;draw()});const note=h("p","cx-facet-note"),state={expanded:false,search:"",counts:null,timer:0};search.type="search";search.placeholder=grid.labels.gridFacetSearch;search.setAttribute("aria-label",fill(grid.labels.gridFacetSearch,{})+ ": "+facet.label);search.hidden=true;more.classList.add("cx-facet-more");more.hidden=true;note.hidden=true;list.setAttribute("aria-label",facet.label);body.append(search,list,more,note);search.addEventListener("input",()=>{state.search=search.value;clearTimeout(state.timer);state.timer=setTimeout(()=>facet.hosted?panel.refresh([facet]):draw(),facet.hosted?250:0)});list.addEventListener("keydown",event=>{const boxes=[...list.querySelectorAll("input")],at=boxes.indexOf(document.activeElement);const next={ArrowDown:at+1,ArrowUp:at-1,Home:0,End:boxes.length-1}[event.key];if(at<0||next===undefined||!boxes[next])return;event.preventDefault();boxes.forEach(box=>{box.tabIndex=-1});boxes[next].tabIndex=0;boxes[next].focus()});const choose=(item,checked)=>{const chosen=new Map((state.chosen||[]).map(value=>[facetKey(value,facet.def),value]));if(checked)chosen.set(facetKey(item.value,facet.def),item.value);else chosen.delete(facetKey(item.value,facet.def));state.chosen=[...chosen.values()];panel.apply(facet,state.chosen)};function draw(){const counts=state.counts,selection=panel.selection(facet);if(!counts)return;state.chosen=selection.values||[];const chosen=new Set(state.chosen.map(value=>facetKey(value,facet.def))),focused=list.contains(document.activeElement)?document.activeElement:null;const focusKey=focused?.getAttribute("data-cx-key"),focusPosition=focused?[...list.querySelectorAll("input")].indexOf(focused):0;const needle=facet.hosted?"":foldText(state.search),locked=!!selection.locked;let items=counts.items.filter(item=>!needle||item.value!==null&&foldText(
|
|
36
|
+
const FACET_SEARCH_FROM=12;function facetListBody(panel,facet,body){const grid=panel.grid,search=h("input","cx-input cx-facet-search"),list=h("ul","cx-facet-values"),more=gridButton("",()=>{state.expanded=!state.expanded;draw()});const note=h("p","cx-facet-note"),state={expanded:false,search:"",counts:null,timer:0};search.type="search";search.placeholder=grid.labels.gridFacetSearch;search.setAttribute("aria-label",fill(grid.labels.gridFacetSearch,{})+ ": "+facet.label);search.hidden=true;more.classList.add("cx-facet-more");more.hidden=true;note.hidden=true;list.setAttribute("aria-label",facet.label);body.append(search,list,more,note);search.addEventListener("input",()=>{state.search=search.value;clearTimeout(state.timer);state.timer=setTimeout(()=>facet.hosted?panel.refresh([facet]):draw(),facet.hosted?250:0)});list.addEventListener("keydown",event=>{const boxes=[...list.querySelectorAll("input")],at=boxes.indexOf(document.activeElement);const next={ArrowDown:at+1,ArrowUp:at-1,Home:0,End:boxes.length-1}[event.key];if(at<0||next===undefined||!boxes[next])return;event.preventDefault();boxes.forEach(box=>{box.tabIndex=-1});boxes[next].tabIndex=0;boxes[next].focus()});const choose=(item,checked)=>{const chosen=new Map((state.chosen||[]).map(value=>[facetKey(value,facet.def),value]));if(checked)chosen.set(facetKey(item.value,facet.def),item.value);else chosen.delete(facetKey(item.value,facet.def));state.chosen=[...chosen.values()];panel.apply(facet,state.chosen)};function draw(){const counts=state.counts,selection=panel.selection(facet);if(!counts)return;state.chosen=selection.values||[];const chosen=new Set(state.chosen.map(value=>facetKey(value,facet.def))),focused=list.contains(document.activeElement)?document.activeElement:null;const focusKey=focused?.getAttribute("data-cx-key"),focusPosition=focused?[...list.querySelectorAll("input")].indexOf(focused):0;const needle=facet.hosted?"":foldText(state.search),locked=!!selection.locked;let items=counts.items.filter(item=>!needle||item.value!==null&&foldText(cellText(item.value,facet.def,grid.fmt)).includes(needle));if(!(facet.hosted&&state.search))for(const value of state.chosen)if(!items.some(item=>facetKey(item.value,facet.def)===facetKey(value,facet.def)))items.push({value,count:0});items.sort(facet.sort==="count"?(a,b)=>b.count-a.count||facetValueOrder(a.value,b.value,facet):(a,b)=>facetValueOrder(a.value,b.value,facet));const shown=state.expanded?items.filter((item,index)=>index<FACET_VALUES||chosen.has(facetKey(item.value,facet.def))):items.filter((item,index)=>index<facet.limit||chosen.has(facetKey(item.value,facet.def)));const retainedIndex=shown.findIndex(item=>facetKey(item.value,facet.def)===focusKey);const focusIndex=retainedIndex>=0?retainedIndex:Math.min(Math.max(0,focusPosition),Math.max(0,shown.length-1));const numbers=numberFormat(grid.lang);list.replaceChildren(...shown.map((item,index)=>{const row=h("li"),label=h("label","cx-facet-val"),box=h("input"),text=h("span","cx-facet-text"),count=h("span","cx-facet-n"),key=facetKey(item.value,facet.def);box.type="checkbox";box.checked=chosen.has(key);box.disabled=locked;box.setAttribute("data-cx-key",key);box.tabIndex=index===focusIndex?0:-1;const empty=item.value===null||item.value==="",display=empty?grid.labels.gridFacetEmptyValue:facetValueText(grid,facet,item.value,text);if(empty){setText(text,display);text.classList.add("cx-facet-empty")}
|
|
37
37
|
box.setAttribute("aria-label",fill(grid.labels.gridFacetValueCount,{value:display,count:numbers.format(item.count)}));setText(count,numbers.format(item.count));count.setAttribute("aria-hidden","true");if(!item.count)label.classList.add("cx-facet-zero");box.addEventListener("change",()=>choose(item,box.checked));label.append(box,text,count);row.appendChild(label);return row}));if(focusKey){const target=!locked&&list.querySelector('input[tabindex="0"]')||body.closest(".cx-facet")?.querySelector(".cx-facet-toggle");target?.focus({preventScroll:!locked&&retainedIndex>=0})}
|
|
38
38
|
const hidden=items.length-shown.length,capped=state.expanded&&hidden>0;more.hidden=!hidden&&!state.expanded||items.length<=facet.limit;setText(more,state.expanded?grid.labels.gridFacetShowFewer:fill(grid.labels.gridFacetShowMore,{count:numbers.format(Math.min(hidden,Math.max(1,FACET_VALUES-shown.length)))}));search.hidden=!state.search&&document.activeElement!==search&&counts.totalValues<=FACET_SEARCH_FROM;search.disabled=locked;note.hidden=!counts.truncated&&!capped;if(!note.hidden)setText(note,fill(grid.labels.gridFacetCounts,{count:numbers.format(counts.matched),shown:numbers.format(counts.truncated?counts.items.length:shown.length),total:numbers.format(counts.totalValues)}))}
|
|
39
39
|
return{draw,search:()=>state.search,update(counts){state.counts=counts;draw()}}}
|
|
40
|
-
function facetValueOrder(a,b,facet){const column=facet.def;if(a===null||b===null)return a===b?0:a===null?1:-1;if(facet.order){const at=facet.order.get(
|
|
40
|
+
function facetValueOrder(a,b,facet){const column=facet.def;if(column.valueOrder?.length)return gridKeyCompare(a,b,column,"asc");if(a===null||b===null)return a===b?0:a===null?1:-1;if(facet.order){const at=facet.order.get(facetKey(a,column))??Infinity,bt=facet.order.get(facetKey(b,column))??Infinity;if(at!==bt)return at<bt?-1:1}
|
|
41
41
|
if(column.kind!=="text")return gridOrder(gridScalar(a,column),gridScalar(b,column));if(typeof a!==typeof b)return typeof a==="boolean"?-1:1;return gridOrder(typeof a==="string"?foldText(a):a,typeof b==="string"?foldText(b):b)}
|
|
42
42
|
function facetValueText(grid,facet,value,element){const column=facet.def,options=column.presenter,text=cellText(value,column,grid.fmt)||String(value);if(options&&!["statusStrip","sparklineBars","sparklineLine","change","identifier","longText","list","tags","structured"].includes(options.kind)){try{gridCellRenderer(grid,column,options)({id:"facet",cells:{[column.id]:value}},element);return text}catch(_){element.replaceChildren()}}
|
|
43
43
|
setText(element,text);return text}
|
|
@@ -54,12 +54,11 @@ const place=value=>Math.min(count-1,Math.floor((value-min)/ width));
|
|
|
54
54
|
for(const value of counts.values||[])tallies[place(value)]++;for(const pair of pairs||[])tallies[place(pair.value)]+=pair.count;const highest=Math.max(1,...tallies);const bins=tallies.map((tally,index)=>({start:min+index*width,end:index===count-1?max:min +(index+1)*width,count:tally}));const sameBins=bins.length===state.bins.length&&bins.every((bin,index)=>bin.start===state.bins[index].start&&bin.end===state.bins[index].end);state.bins=bins;const bars=sameBins?Array.from(chart.children):bins.map(()=>h("span","cx-facet-bar"));bins.forEach((bin,index)=>{const last=index===count-1,bar=bars[index];const inside=(range.low==null||(last&&!range.lowOpen?bin.end>=range.low:bin.end>range.low))&&(range.high==null||(range.open?bin.start<range.high:bin.start<=range.high));bar.setAttribute("data-cx-bin",String(index));bar.style.height=Math.max(bin.count?6:0,Math.round(bin.count / highest * 100)) + "%";
|
|
55
55
|
bar.classList.toggle("cx-facet-in",inside&&(range.low!=null||range.high!=null));bar.title=fill(grid.labels.gridFacetBin,{from:label(bin.start),to:label(bin.end),count:numbers.format(bin.count)})});if(!sameBins)chart.replaceChildren(...bars);setText(low,label(min));setText(high,label(max))}
|
|
56
56
|
return{draw,search:()=>"",update(counts){state.counts=counts;draw()}}}
|
|
57
|
-
let facetSeq=0;const FACET_ICON='<path d="M4 6h16M7 12h10M10 18h4"/>';
|
|
58
|
-
|
|
59
|
-
const sheetButton=this.facetSheetButton=gridButton(this.labels.gridFacetPanel,()=>this.openFacetSheet());sheetButton.classList.add("cx-btn","cx-facets-open");sheetButton.prepend(gridIcon(null,FACET_ICON));sheetButton.hidden=true;sheetButton.setAttribute("aria-haspopup","dialog");const anchor=this.toolbar.querySelector(".cx-grid-filters")||this.toolbar.querySelector(".cx-grid-columns")||this.spacer;if(this.opts.toolbar===false)this.host.prepend(sheetButton);else if(anchor?.parentNode===this.toolbar)anchor.before(sheetButton);else this.toolbar.prepend(sheetButton);this.facetResize=new ResizeObserver(()=>requestAnimationFrame(()=>this.destroyed||this.facetFit()));this.facetResize.observe(this.facetFrame||this.host);if(this.facetFrame)this.facetResize.observe(this.host);this.host.addEventListener("canopyx:query",()=>{if(facetShape(this.acceptedQuery)!==this.facetCounted)this.facetRefresh()},{signal});this.host.addEventListener("canopyx:rowsChanged",()=>{clearTimeout(this.facetLiveTimer);this.facetLiveTimer=setTimeout(()=>this.facetRefresh(),300)},{signal});signal.addEventListener("abort",()=>this.facetDestroy(),{once:true});this.facetSync();this.facetFit();if(this.acceptedQuery)this.facetRefresh()},facetSection(facet,list){const section=h("section","cx-facet"),head=h("h3","cx-facet-h"),toggle=h("button","cx-facet-toggle"),name=h("span","cx-facet-name"),badge=h("span","cx-facet-badge");const clear=gridButton("",()=>this.facetApply(facet,facet.kind==="list"?[]:{low:null,high:null})),body=h("div","cx-facet-b"),custom=h("p","cx-facet-note cx-facet-custom");const failure=h("p","cx-facet-note cx-facet-error"),spoken=h("span","cx-sr-only");const bodyId=this.facetPanel.id+"-"+facet.column;section.setAttribute("data-cx-facet",facet.column);toggle.type="button";toggle.setAttribute("aria-controls",bodyId);body.id=bodyId;badge.setAttribute("aria-hidden","true");setText(name,facet.label);toggle.append(name,badge,spoken);head.appendChild(toggle);clear.classList.add("cx-facet-clear");clear.appendChild(gridIcon("close"));clear.setAttribute("aria-label",fill(this.labels.gridFacetClear,{column:facet.label}));clear.title=clear.getAttribute("aria-label");custom.hidden=true;custom.setAttribute("role","status");failure.hidden=true;failure.setAttribute("role","status");const facetView={grid:this,selection:target=>facetSelection(this.queryForChange(),target),apply:(target,choice)=>this.facetApply(target,choice),refresh:targets=>this.facetRefresh(targets)};const content=facet.kind==="list"?facetListBody(facetView,facet,body):facetRangeBody(facetView,facet,body);body.prepend(custom,failure);const collapsed=()=>{const closed=facet.collapsed;toggle.setAttribute("aria-expanded",String(!closed));body.hidden=closed;toggle.title=fill(this.labels[closed?"gridFacetExpand":"gridFacetCollapse"],{column:facet.label})};toggle.addEventListener("click",()=>{facet.collapsed=!facet.collapsed;collapsed()});collapsed();const top=h("div","cx-facet-top");top.append(head,clear);section.append(top,body);list.appendChild(section);return{facet,section,badge,spoken,clear,custom,failure,content,generation:0,controller:null}},facetApply(facet,choice){this.facetPending||=new Map();this.facetPending.set(facet.column,{facet,choice});clearTimeout(this.facetTimer);this.facetTimer=setTimeout(()=>this.facetFlush(),150)},facetFlush(){clearTimeout(this.facetTimer);this.facetTimer=0;const pending=this.facetPending;this.facetPending=null;if(!pending||this.destroyed)return Promise.resolve();let query=this.queryForChange(true);for(const{facet,choice}of pending.values())query=facetQuery(query,facet,choice);return this.setQuery(query).then(()=>this.facetAnnounce(),()=>{})},facetClearAll(){clearTimeout(this.facetTimer);this.facetPending=null;let query=this.queryForChange(true);for(const facet of this.facetColumns)query=facetQuery(query,facet,facet.kind==="list"?[]:{low:null,high:null});return this.setQuery(query).then(()=>this.facetAnnounce(),()=>{})},facetAnnounce(){const numbers=numberFormat(this.lang);setText(this.facetLive,"");setText(this.facetLive,fill(this.labels.gridFacetResult,{count:numbers.format(this.snapshot?.matched??0)}))},async facetRefresh(targets){if(!this.facetPanel||!this.acceptedQuery||this.destroyed)return;const query=this.acceptedQuery,run=targets?this.facetRun:this.facetRun=(this.facetRun||0)+ 1;if(!targets)this.facetCounted=facetShape(query);for(const section of this.facetSections){if(targets&&!targets.includes(section.facet))continue;section.controller?.abort();const controller=section.controller=new AbortController(),generation=++section.generation;const current=()=>!this.destroyed&&run===this.facetRun&&generation===section.generation;try{const counts=section.facet.hosted?await facetHostedCounts(this,section.facet,section.content.search(),controller.signal):facetInlineCounts(this,section.facet,query);if(current()){section.failure.hidden=true;section.content.update(counts)}}catch(error){if(current()&&error?.name!=="AbortError"){setText(section.failure,fill(this.labels.queryFailed,{error:error.message}));section.failure.hidden=false}}finally{if(section.controller===controller)section.controller=null;controller.abort()}
|
|
57
|
+
let facetSeq=0;const FACET_ICON='<path d="M4 6h16M7 12h10M10 18h4"/>';Object.assign(DataGrid.prototype,{startFacets(){if(this.facetPanel)return;const options=this.facetOptions=facetOptions(this),id=this.id+"-facets-" + ++facetSeq,signal=this.lifetime.signal;this.facetColumns=options.facets.map(facet=>Object.assign(facet,{hosted:options.hosted}));this.facetOpen??=options.open;if(this.defaultState)this.defaultState.facets={open:options.open};const panel=this.facetPanel=h("aside","cx-host cx-chrome cx-facets"),head=h("div","cx-facets-h"),title=h("h2","cx-facets-title");const clear=gridButton(this.labels.gridClearAll,()=>this.facetClearAll()),toggle=gridButton("",()=>this.setFacetPanelOpen(!this.facetOpen));const list=h("div","cx-facets-list"),live=this.facetLive=h("p","cx-sr-only");panel.id=id;panel.setAttribute("aria-labelledby",id+"-title");title.id=id+"-title";setText(title,options.label||this.labels.gridFacetPanel);live.setAttribute("aria-live","polite");toggle.classList.add("cx-facets-toggle");toggle.setAttribute("aria-controls",id+"-list");list.id=id+"-list";toggle.appendChild(gridIcon(null,FACET_ICON));clear.classList.add("cx-facets-clear");this.facetClear=clear;toggle.hidden=!options.collapsible;head.append(title,clear,toggle);panel.append(head,list,live);panel.setAttribute("data-cx-position",options.position);panel.style.setProperty("--cx-facets-w",options.width+"px");this.facetSections=this.facetColumns.map(facet=>this.facetSection(facet,list));if(options.target)options.target.appendChild(panel);else{const frame=this.facetFrame=h("div","cx-facet-frame");frame.setAttribute("data-cx-position",options.position);this.host.before(frame);frame.append(panel,this.host)}
|
|
58
|
+
this.facetTheme=watchOverlayTheme(this.host,panel,signal);const sheetButton=this.facetSheetButton=gridButton(this.labels.gridFacetPanel,()=>this.openFacetSheet());sheetButton.classList.add("cx-btn","cx-facets-open");sheetButton.prepend(gridIcon(null,FACET_ICON));sheetButton.hidden=true;sheetButton.setAttribute("aria-haspopup","dialog");const anchor=this.toolbar.querySelector(".cx-grid-filters")||this.toolbar.querySelector(".cx-grid-columns")||this.spacer;if(this.opts.toolbar===false)this.host.prepend(sheetButton);else if(anchor?.parentNode===this.toolbar)anchor.before(sheetButton);else this.toolbar.prepend(sheetButton);this.facetResize=new ResizeObserver(()=>requestAnimationFrame(()=>this.destroyed||this.facetFit()));this.facetResize.observe(this.facetFrame||this.host);if(this.facetFrame)this.facetResize.observe(this.host);this.host.addEventListener("canopyx:query",()=>{if(facetShape(this.acceptedQuery)!==this.facetCounted)this.facetRefresh()},{signal});this.host.addEventListener("canopyx:rowsChanged",()=>{clearTimeout(this.facetLiveTimer);this.facetLiveTimer=setTimeout(()=>this.facetRefresh(),300)},{signal});signal.addEventListener("abort",()=>this.facetDestroy(),{once:true});this.facetSync();this.facetFit();if(this.acceptedQuery)this.facetRefresh()},facetSection(facet,list){const section=h("section","cx-facet"),head=h("h3","cx-facet-h"),toggle=h("button","cx-facet-toggle"),name=h("span","cx-facet-name"),badge=h("span","cx-facet-badge");const clear=gridButton("",()=>this.facetApply(facet,facet.kind==="list"?[]:{low:null,high:null})),body=h("div","cx-facet-b"),custom=h("p","cx-facet-note cx-facet-custom");const failure=h("p","cx-facet-note cx-facet-error"),spoken=h("span","cx-sr-only");const bodyId=this.facetPanel.id+"-"+facet.column;section.setAttribute("data-cx-facet",facet.column);toggle.type="button";toggle.setAttribute("aria-controls",bodyId);body.id=bodyId;badge.setAttribute("aria-hidden","true");setText(name,facet.label);toggle.append(name,badge,spoken);head.appendChild(toggle);clear.classList.add("cx-facet-clear");clear.appendChild(gridIcon("close"));clear.setAttribute("aria-label",fill(this.labels.gridFacetClear,{column:facet.label}));clear.title=clear.getAttribute("aria-label");custom.hidden=true;custom.setAttribute("role","status");failure.hidden=true;failure.setAttribute("role","status");const facetView={grid:this,selection:target=>facetSelection(this.queryForChange(),target),apply:(target,choice)=>this.facetApply(target,choice),refresh:targets=>this.facetRefresh(targets)};const content=facet.kind==="list"?facetListBody(facetView,facet,body):facetRangeBody(facetView,facet,body);body.prepend(custom,failure);const collapsed=()=>{const closed=facet.collapsed;toggle.setAttribute("aria-expanded",String(!closed));body.hidden=closed;toggle.title=fill(this.labels[closed?"gridFacetExpand":"gridFacetCollapse"],{column:facet.label})};toggle.addEventListener("click",()=>{facet.collapsed=!facet.collapsed;collapsed()});collapsed();const top=h("div","cx-facet-top");top.append(head,clear);section.append(top,body);list.appendChild(section);return{facet,section,badge,spoken,clear,custom,failure,content,generation:0,controller:null}},facetApply(facet,choice){this.facetPending||=new Map();this.facetPending.set(facet.column,{facet,choice});clearTimeout(this.facetTimer);this.facetTimer=setTimeout(()=>this.facetFlush(),150)},facetFlush(){clearTimeout(this.facetTimer);this.facetTimer=0;const pending=this.facetPending;this.facetPending=null;if(!pending||this.destroyed)return Promise.resolve();let query=this.queryForChange(true);for(const{facet,choice}of pending.values())query=facetQuery(query,facet,choice);return this.setQuery(query).then(()=>this.facetAnnounce(),()=>{})},facetClearAll(){clearTimeout(this.facetTimer);this.facetPending=null;let query=this.queryForChange(true);for(const facet of this.facetColumns)query=facetQuery(query,facet,facet.kind==="list"?[]:{low:null,high:null});return this.setQuery(query).then(()=>this.facetAnnounce(),()=>{})},facetAnnounce(){const numbers=numberFormat(this.lang);setText(this.facetLive,"");setText(this.facetLive,fill(this.labels.gridFacetResult,{count:numbers.format(this.snapshot?.matched??0)}))},async facetRefresh(targets){if(!this.facetPanel||!this.acceptedQuery||this.destroyed)return;const query=this.acceptedQuery,run=targets?this.facetRun:this.facetRun=(this.facetRun||0)+ 1;if(!targets)this.facetCounted=facetShape(query);for(const section of this.facetSections){if(targets&&!targets.includes(section.facet))continue;section.controller?.abort();const controller=section.controller=new AbortController(),generation=++section.generation;const current=()=>!this.destroyed&&run===this.facetRun&&generation===section.generation;try{const counts=section.facet.hosted?await facetHostedCounts(this,section.facet,section.content.search(),controller.signal):facetInlineCounts(this,section.facet,query);if(current()){section.failure.hidden=true;section.content.update(counts)}}catch(error){if(current()&&error?.name!=="AbortError"){setText(section.failure,fill(this.labels.queryFailed,{error:error.message}));section.failure.hidden=false}}finally{if(section.controller===controller)section.controller=null;controller.abort()}
|
|
60
59
|
if(!section.facet.hosted)await new Promise(resolve=>setTimeout(resolve,0));if(this.destroyed||run!==this.facetRun)return}},facetSync(){if(!this.facetPanel)return;const query=this.queryForChange(),numbers=numberFormat(this.lang);let active=0;for(const section of this.facetSections||[]){const selection=facetSelection(query,section.facet),count=selection.values?selection.values.length:selection.custom||selection.low!=null||selection.high!=null?1:0;active +=count?1:0;setText(section.badge,selection.values?numbers.format(count):"");section.badge.hidden=!selection.values||!count;setText(section.spoken,section.badge.hidden?"":", "+fill(this.labels.gridFacetSelected,{count:numbers.format(count)}));section.clear.hidden=!count||!!selection.locked;section.section.classList.toggle("cx-facet-active",!!count);if(selection.custom){setText(section.custom,this.labels.gridFacetCustom);section.custom.hidden=false}
|
|
61
60
|
else if(section.custom.textContent===this.labels.gridFacetCustom)section.custom.hidden=true;section.content.draw()}
|
|
62
61
|
this.facetClear.hidden=!active;this.facetActive=active;if(this.facetSheetButton){this.facetSheetButton.querySelector(".badge")?.remove();if(active){const badge=h("span","badge");setText(badge,numbers.format(active));this.facetSheetButton.appendChild(badge)}}},facetFit(){const panel=this.facetPanel,options=this.facetOptions;if(!panel||this.facetSheet)return;const width=(this.facetFrame||this.host).clientWidth,fits=options.target?true:options.position==="side"?width>=options.width+480:width>640;this.facetFits=fits;panel.hidden=!fits;this.facetSheetButton.hidden=fits;this.facetFrame?.toggleAttribute("data-cx-sheet",!fits);panel.classList.toggle("cx-facets-closed",!this.facetOpen);panel.style.height=options.position==="side"&&this.facetFrame&&this.facetOpen?Math.max(360,this.host.offsetHeight)+ "px":"";const toggle=panel.querySelector(".cx-facets-toggle");toggle.setAttribute("aria-expanded",String(!!this.facetOpen));toggle.setAttribute("aria-label",this.labels[this.facetOpen?"gridFacetPanelHide":"gridFacetPanelShow"]);toggle.title=toggle.getAttribute("aria-label")},setFacetPanelOpen(open){if(typeof open!=="boolean")return Promise.reject(new Error("CanopyX: the facet panel's open state is a boolean."));if(open!==this.facetOpen){this.facetOpen=open;this.facetFit();this.stateChanged();this.emit("facetPanel",{open})}
|
|
63
|
-
return Promise.resolve(this.getFacetPanel())},getFacetPanel(){if(!this.facetPanel)return gridFreeze({open:this.facetOpen??null,columns:(this.facetColumns||[]).map(facet=>facet.column)});return gridFreeze({open:!!this.facetOpen,columns:this.facetColumns.map(facet=>facet.column),active:this.facetActive||0})},openFacetSheet(){if(this.facetSheet||!this.facetPanel)return;const sheet=this.facetSheet=h("dialog","cx-host cx-chrome cx-grid-overlay cx-facet-sheet"),head=h("div","cx-facet-sheet-h"),title=h("h2"),done=gridButton(this.labels.gridDone,()=>sheet.close());const panel=this.facetPanel,home=panel.parentNode,next=panel.nextSibling,returnFocus=document.activeElement;
|
|
64
|
-
panel.classList.remove("cx-facets-in-sheet");home?.insertBefore(panel,next);clearHome.insertBefore(clear,clearNext);sheet.remove();this.facetSheet=null;this.facetFit();if(returnFocus?.isConnected)returnFocus.focus({preventScroll:true})},{once:true});sheet.showModal();done.focus()},facetDestroy(){clearTimeout(this.facetTimer);clearTimeout(this.facetLiveTimer);this.facetResize?.disconnect();for(const section of this.facetSections||[])section.controller?.abort();const sheet=this.facetSheet;this.facetSheet=null;this.facetPanel?.remove();this.facetSheetButton?.remove();this.facetPanel=null;if(sheet){sheet.close();sheet.remove()}
|
|
62
|
+
return Promise.resolve(this.getFacetPanel())},getFacetPanel(){if(!this.facetPanel)return gridFreeze({open:this.facetOpen??null,columns:(this.facetColumns||[]).map(facet=>facet.column)});return gridFreeze({open:!!this.facetOpen,columns:this.facetColumns.map(facet=>facet.column),active:this.facetActive||0})},openFacetSheet(){if(this.facetSheet||!this.facetPanel)return;const sheet=this.facetSheet=h("dialog","cx-host cx-chrome cx-grid-overlay cx-facet-sheet"),head=h("div","cx-facet-sheet-h"),title=h("h2"),done=gridButton(this.labels.gridDone,()=>sheet.close());const panel=this.facetPanel,home=panel.parentNode,next=panel.nextSibling,returnFocus=document.activeElement;const disposeTheme=watchOverlayTheme(this.host,sheet,this.lifetime.signal);sheet.addEventListener("close",disposeTheme,{once:true});title.id=this.id+"-facet-sheet";sheet.setAttribute("aria-labelledby",title.id);setText(title,this.facetOptions.label||this.labels.gridFacetPanel);const clear=this.facetClear,clearHome=clear.parentNode,clearNext=clear.nextSibling;done.classList.add("cx-btn");head.append(title,clear,done);sheet.append(head,panel);panel.hidden=false;panel.classList.remove("cx-facets-closed");panel.classList.add("cx-facets-in-sheet");document.body.appendChild(sheet);this.facetTheme.refresh();sheet.addEventListener("close",()=>{if(this.facetPanel!==panel){sheet.remove();return}// The grid was destroyed meanwhile; the panel is gone.
|
|
63
|
+
panel.classList.remove("cx-facets-in-sheet");home?.insertBefore(panel,next);this.facetTheme.refresh();clearHome.insertBefore(clear,clearNext);sheet.remove();this.facetSheet=null;this.facetFit();if(returnFocus?.isConnected)returnFocus.focus({preventScroll:true})},{once:true});sheet.showModal();done.focus()},facetDestroy(){clearTimeout(this.facetTimer);clearTimeout(this.facetLiveTimer);this.facetResize?.disconnect();this.facetTheme?.();this.facetTheme=null;for(const section of this.facetSections||[])section.controller?.abort();const sheet=this.facetSheet;this.facetSheet=null;this.facetPanel?.remove();this.facetSheetButton?.remove();this.facetPanel=null;if(sheet){sheet.close();sheet.remove()}
|
|
65
64
|
if(this.facetFrame){this.facetFrame.replaceWith(this.host);this.facetFrame=null}}});const FACET_SUMMARY=DataGrid.prototype.syncQuerySummary;DataGrid.prototype.syncQuerySummary=function(){FACET_SUMMARY.call(this);if(this.facetPanel)this.facetSync()};const FACET_ZONE=DataGrid.prototype.setTimeZone;DataGrid.prototype.setTimeZone=function(zone){const result=FACET_ZONE.call(this,zone);if(this.facetPanel)this.facetSync();return result};installed.add(context.DataGrid.prototype)}};(global.CanopyXParts||=[]).push(["facets",part])})(typeof window!=="undefined"?window:globalThis);
|