@evotecit/canopyx 0.3.18 → 0.3.20
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-board.css +12 -12
- package/CanopyX.Html/Assets/canopyx-board.js +1 -1
- package/CanopyX.Html/Assets/canopyx-calendar.css +70 -57
- package/CanopyX.Html/Assets/canopyx-calendar.js +14 -14
- package/CanopyX.Html/Assets/canopyx-cell-range.css +4 -4
- package/CanopyX.Html/Assets/canopyx-cell-range.js +1 -1
- package/CanopyX.Html/Assets/canopyx-changes.css +55 -55
- package/CanopyX.Html/Assets/canopyx-changes.js +1 -1
- package/CanopyX.Html/Assets/canopyx-column-groups.css +5 -1
- package/CanopyX.Html/Assets/canopyx-column-groups.js +15 -9
- package/CanopyX.Html/Assets/canopyx-compare.css +4 -4
- package/CanopyX.Html/Assets/canopyx-compare.js +1 -1
- package/CanopyX.Html/Assets/canopyx-detail-rows.css +4 -4
- package/CanopyX.Html/Assets/canopyx-detail-rows.js +1 -1
- package/CanopyX.Html/Assets/canopyx-editing.css +3 -3
- 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 -8
- package/CanopyX.Html/Assets/canopyx-facets.css +19 -18
- package/CanopyX.Html/Assets/canopyx-facets.js +1 -1
- package/CanopyX.Html/Assets/canopyx-filter-editor.css +24 -24
- package/CanopyX.Html/Assets/canopyx-filter-editor.js +3 -3
- package/CanopyX.Html/Assets/canopyx-flow-checks.css +2 -2
- package/CanopyX.Html/Assets/canopyx-flow-checks.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-command.css +3 -3
- package/CanopyX.Html/Assets/canopyx-flow-command.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-dialog.css +2 -2
- package/CanopyX.Html/Assets/canopyx-flow-dialog.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-drafts.css +2 -2
- package/CanopyX.Html/Assets/canopyx-flow-drafts.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-entry.css +24 -23
- package/CanopyX.Html/Assets/canopyx-flow-entry.js +4 -4
- package/CanopyX.Html/Assets/canopyx-flow-host.css +2 -2
- package/CanopyX.Html/Assets/canopyx-flow-host.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-module.mjs +4 -4
- 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 +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-preview.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-records.css +2 -2
- package/CanopyX.Html/Assets/canopyx-flow-records.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-tasks.css +4 -4
- package/CanopyX.Html/Assets/canopyx-flow-tasks.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow.css +41 -41
- package/CanopyX.Html/Assets/canopyx-flow.js +1 -1
- package/CanopyX.Html/Assets/canopyx-format-editor.css +9 -9
- package/CanopyX.Html/Assets/canopyx-format-editor.js +1 -1
- package/CanopyX.Html/Assets/canopyx-formatting.css +13 -13
- package/CanopyX.Html/Assets/canopyx-formatting.js +3 -3
- package/CanopyX.Html/Assets/canopyx-forms.css +3 -3
- package/CanopyX.Html/Assets/canopyx-forms.js +1 -1
- package/CanopyX.Html/Assets/canopyx-grid-module.mjs +53 -42
- package/CanopyX.Html/Assets/canopyx-grid-options.css +8 -8
- package/CanopyX.Html/Assets/canopyx-grid-options.js +9 -2
- package/CanopyX.Html/Assets/canopyx-grid.css +99 -96
- package/CanopyX.Html/Assets/canopyx-grid.js +53 -42
- package/CanopyX.Html/Assets/canopyx-grouping.css +7 -7
- package/CanopyX.Html/Assets/canopyx-grouping.js +1 -1
- package/CanopyX.Html/Assets/canopyx-highlight.css +10 -10
- package/CanopyX.Html/Assets/canopyx-highlight.js +1 -1
- package/CanopyX.Html/Assets/canopyx-interactive.css +50 -49
- package/CanopyX.Html/Assets/canopyx-interactive.js +10 -8
- package/CanopyX.Html/Assets/canopyx-layouts.css +9 -9
- package/CanopyX.Html/Assets/canopyx-layouts.js +2 -2
- package/CanopyX.Html/Assets/canopyx-link.css +3 -3
- package/CanopyX.Html/Assets/canopyx-link.js +3 -3
- package/CanopyX.Html/Assets/canopyx-links.js +2 -2
- package/CanopyX.Html/Assets/canopyx-live.css +2 -2
- package/CanopyX.Html/Assets/canopyx-live.js +1 -1
- package/CanopyX.Html/Assets/canopyx-matrix.css +31 -31
- package/CanopyX.Html/Assets/canopyx-matrix.js +1 -1
- package/CanopyX.Html/Assets/canopyx-module.mjs +10 -8
- package/CanopyX.Html/Assets/canopyx-pager.css +1 -1
- package/CanopyX.Html/Assets/canopyx-pager.js +1 -1
- package/CanopyX.Html/Assets/canopyx-path.css +8 -8
- package/CanopyX.Html/Assets/canopyx-path.js +1 -1
- package/CanopyX.Html/Assets/canopyx-pivot.css +10 -10
- package/CanopyX.Html/Assets/canopyx-pivot.js +3 -3
- package/CanopyX.Html/Assets/canopyx-plan.css +24 -17
- package/CanopyX.Html/Assets/canopyx-plan.js +13 -9
- package/CanopyX.Html/Assets/canopyx-record-panel.css +47 -42
- package/CanopyX.Html/Assets/canopyx-record-panel.js +16 -9
- package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +56 -52
- package/CanopyX.Html/Assets/canopyx-reporting.css +104 -101
- package/CanopyX.Html/Assets/canopyx-reporting.js +56 -52
- package/CanopyX.Html/Assets/canopyx-stack.css +6 -6
- package/CanopyX.Html/Assets/canopyx-stack.js +1 -1
- package/CanopyX.Html/Assets/canopyx-time-slider.css +5 -5
- package/CanopyX.Html/Assets/canopyx-time-slider.js +1 -1
- package/CanopyX.Html/Assets/canopyx-timeline.css +19 -19
- package/CanopyX.Html/Assets/canopyx-timeline.js +2 -2
- package/CanopyX.Html/Assets/canopyx-tree-tools.css +21 -21
- package/CanopyX.Html/Assets/canopyx-tree-tools.js +3 -3
- package/CanopyX.Html/Assets/canopyx-ui-menu.css +7 -7
- package/CanopyX.Html/Assets/canopyx-ui-menu.js +1 -1
- package/CanopyX.Html/Assets/canopyx-ui-navigation.css +5 -5
- package/CanopyX.Html/Assets/canopyx-ui-navigation.js +1 -1
- package/CanopyX.Html/Assets/canopyx-ui-overlays.css +5 -5
- package/CanopyX.Html/Assets/canopyx-ui-overlays.js +5 -2
- package/CanopyX.Html/Assets/canopyx-ui-picker.css +2 -2
- package/CanopyX.Html/Assets/canopyx-ui-picker.js +1 -1
- package/CanopyX.Html/Assets/canopyx-ui-stepper.css +12 -12
- package/CanopyX.Html/Assets/canopyx-ui-stepper.js +1 -1
- package/CanopyX.Html/Assets/canopyx-ui-tabs.css +8 -8
- package/CanopyX.Html/Assets/canopyx-ui-tabs.js +1 -1
- package/CanopyX.Html/Assets/canopyx-view-intents.css +1 -1
- package/CanopyX.Html/Assets/canopyx-view-intents.js +1 -1
- package/CanopyX.Html/Assets/canopyx.css +47 -46
- package/CanopyX.Html/Assets/canopyx.js +10 -8
- package/JavaScript/column-groups.d.ts +24 -4
- package/JavaScript/grid.d.ts +11 -1
- package/JavaScript/hosts.d.ts +2 -0
- package/JavaScript/protocol.d.ts +2 -0
- package/JavaScript/records.d.ts +2 -0
- package/README.md +76 -206
- package/README.nuget.md +63 -87
- package/package.json +1 -1
|
@@ -90,8 +90,8 @@ function trusted(kind,value){if(trustPolicy===undefined){try{trustPolicy=global.
|
|
|
90
90
|
catch(_){trustPolicy=null}}
|
|
91
91
|
return trustPolicy?trustPolicy["create"+kind](value):value}
|
|
92
92
|
function hostHtml(element,html,sanitize,kind){const text=String(html??""),value=sanitize?sanitize(text,{kind}):text;if(value?.nodeType)element.replaceChildren(value);else if(typeof value==="string")element.innerHTML=trusted("HTML",value);else if(global.trustedTypes?.isHTML?.(value))element.innerHTML=value;else throw new Error("CanopyX: invalid sanitizeHtml result.")}
|
|
93
|
-
const STATUS_FALLBACKS={"--hfx-color-status-bad-bg":"light-dark(#f9e4e4,#3c272a)","--hfx-color-status-bad-fg":"light-dark(#b8292a,#f47171)","--hfx-color-status-good-bg":"light-dark(#e2f0e9,#1f362f)","--hfx-color-status-good-fg":"light-dark(#177345,#4cc78a)","--hfx-color-status-info-bg":"light-dark(#e4ecfa,#262f41)","--hfx-color-status-info-fg":"light-dark(#2b5fc0,#74a2f7)","--hfx-color-status-neutral-bg":"light-dark(#eeeff0,#2a2c31)","--hfx-color-status-neutral-fg":"light-dark(#5b6069,#a0a5ae)","--hfx-color-status-warn-bg":"light-dark(#f8efde,#3b3322)","--hfx-color-status-warn-fg":"light-dark(#8c5c05,#eeb640)"};const MODE_ATTRIBUTES=["data-theme","data-cx-theme","data-hfx-mode","data-bs-theme","data-hfx-theme","data-hfx-tokens"];const THEME_ATTRIBUTES=[...MODE_ATTRIBUTES,"data-hfx-style","data-hfx-density","data-cx-fallback-mode","style","class"];function watchTheme(host,signal){const attributes=THEME_ATTRIBUTES;const previous=host.getAttribute("data-cx-fallback-mode");const refresh=()=>{const parent=host.parentElement&&getComputedStyle(host.parentElement);const inherited=parent?.colorScheme;
|
|
94
|
-
if(
|
|
93
|
+
const STATUS_FALLBACKS={"--hfx-color-status-bad-bg":"light-dark(#f9e4e4,#3c272a)","--hfx-color-status-bad-fg":"light-dark(#b8292a,#f47171)","--hfx-color-status-good-bg":"light-dark(#e2f0e9,#1f362f)","--hfx-color-status-good-fg":"light-dark(#177345,#4cc78a)","--hfx-color-status-info-bg":"light-dark(#e4ecfa,#262f41)","--hfx-color-status-info-fg":"light-dark(#2b5fc0,#74a2f7)","--hfx-color-status-neutral-bg":"light-dark(#eeeff0,#2a2c31)","--hfx-color-status-neutral-fg":"light-dark(#5b6069,#a0a5ae)","--hfx-color-status-warn-bg":"light-dark(#f8efde,#3b3322)","--hfx-color-status-warn-fg":"light-dark(#8c5c05,#eeb640)"};const MODE_ATTRIBUTES=["data-theme","data-cx-theme","data-hfx-mode","data-bs-theme","data-hfx-theme","data-hfx-tokens"];const THEME_ATTRIBUTES=[...MODE_ATTRIBUTES,"data-hfx-style","data-hfx-density","data-cx-fallback-mode","style","class"];function watchTheme(host,signal){const attributes=THEME_ATTRIBUTES;const previous=host.getAttribute("data-cx-fallback-mode");const refresh=()=>{const parent=host.parentElement&&getComputedStyle(host.parentElement);const inherited=parent?.colorScheme;const surface=parent&&["--hfx-color-surface-card","--hfx-color-surface"].some(name=>parent.getPropertyValue(name).trim());let mode=null;if(!surface){outer:for(let owner=host;owner;owner=owner.parentElement)for(const attribute of MODE_ATTRIBUTES){const value=owner.getAttribute(attribute);if(value==="light"||value==="dark"){mode=value;break outer}}}
|
|
94
|
+
if(surface||!mode&&inherited&&inherited!=="normal"){if(host.hasAttribute("data-cx-fallback-mode"))host.removeAttribute("data-cx-fallback-mode")}else if(host.getAttribute("data-cx-fallback-mode")!==(mode||"auto"))host.setAttribute("data-cx-fallback-mode",mode||"auto")};const observer=new MutationObserver(refresh);for(let owner=host;owner;owner=owner.parentElement)observer.observe(owner,{attributes:true,attributeFilter:attributes});refresh();const dispose=()=>{observer.disconnect();if(previous===null)host.removeAttribute("data-cx-fallback-mode");else host.setAttribute("data-cx-fallback-mode",previous)};signal?.addEventListener("abort",dispose,{once:true});return dispose}
|
|
95
95
|
function overlayTheme(host,element,inherit=false){for(const name of["data-hfx-style","data-hfx-mode","data-hfx-density"]){const owner=host.closest("["+name+"]");if(owner&&!inherit)element.setAttribute(name,owner.getAttribute(name));else element.removeAttribute(name)}
|
|
96
96
|
const theme=getComputedStyle(host),parent=inherit&&host.parentElement&&getComputedStyle(host.parentElement);element.style.colorScheme=theme.colorScheme;const copied=[];for(const name of theme)if((name.startsWith("--cx-")||name.startsWith("--hfx-"))&&(!parent||theme.getPropertyValue(name)!==parent.getPropertyValue(name))){element.style.setProperty(name,theme.getPropertyValue(name));copied.push(name)}
|
|
97
97
|
return copied}
|
|
@@ -214,8 +214,9 @@ if(kind==="inline"){if(!Array.isArray(view.roots))throw new Error("CanopyX: inli
|
|
|
214
214
|
throw new Error("CanopyX: unknown source kind '"+kind+"'.")}
|
|
215
215
|
async function remoteJson(url,type,timeoutMs,lifetime,signal){const controller=new AbortController();const signals=Array.from(new Set([lifetime,signal].filter(Boolean)));const abort=()=>controller.abort();signals.forEach((item)=>{if(item.aborted)abort();else item.addEventListener("abort",abort,{once:true})});let timedOut=false;const timer=setTimeout(()=>{timedOut=true;abort()},timeoutMs);try{const response=await fetch(url,{headers:{Accept:"application/json"},signal:controller.signal});if(!response.ok){if(response.body)await response.body.cancel().catch(()=>{});throw new Error(response.status+" "+response.statusText)}
|
|
216
216
|
return checkDocument(await response.json(),type)}catch(error){if(timedOut)throw new Error("CanopyX: remote request timed out after "+timeoutMs+" milliseconds.");throw error}finally{abort();clearTimeout(timer);signals.forEach((item)=>item.removeEventListener("abort",abort))}}
|
|
217
|
-
class TreeGrid{constructor(host,options){const view=checkDocument(options.view,"view");
|
|
218
|
-
|
|
217
|
+
class TreeGrid{constructor(host,options){const view=checkDocument(options.view,"view");if(view.recordDrawerModal!==undefined&&typeof view.recordDrawerModal!=="boolean")
|
|
218
|
+
throw new Error("CanopyX: recordDrawerModal must be a Boolean.");requireIdentifier(view.id,"view ID");if(view.columns.some(column=>column.format!==undefined))throw new Error("CanopyX: number formats apply to flat grids only.");this.host=host;this.view=view;this.opts=options;for(const name of["isSelectable","beforeSelect","sanitizeHtml"]){if(options[name]!==undefined&&typeof options[name]!=="function")throw new Error("CanopyX: "+name+" must be a function.")}
|
|
219
|
+
do{this.id="cx" + ++instanceSeq}while(document.getElementById(this.id));this.lifetime=new AbortController();this.source=options.source||sourceFor(view,{signal:this.lifetime.signal,timeoutMs:options.requestTimeoutMs});this.queryAware=this.source.queryAware===true;this.dataLifetime=new AbortController();this.acceptedQuery=Object.freeze({version:1,sort:null,filters:Object.freeze([])});this.datasetRevision=null;this.rowH=view.rowHeight||40;this.pageSize=view.pageSize||100;this.retainedNodeLimit=options.retainedNodeLimit===undefined?1024:options.retainedNodeLimit;if(!validStructuralCount(this.retainedNodeLimit))throw new Error("CanopyX: retainedNodeLimit must be a nonnegative 32-bit integer.");this.inactiveNodeLimit=options.inactiveNodeLimit===undefined?4096:options.inactiveNodeLimit;if(!validStructuralCount(this.inactiveNodeLimit))throw new Error("CanopyX: inactiveNodeLimit must be a nonnegative 32-bit integer.");this.multi=view.selection==="multiple";this.lang=document.documentElement.lang||undefined;this.labels=labelsFor(view.labels,options.labels);this.tools=Object.assign({},view.toolbar,options.toolbar);if(Object.entries(this.tools).some(([name,value])=>!/^(search|filters|columns|views|export|more|matches|layout)$/.test(name) || typeof value !== "boolean"))
|
|
219
220
|
throw new Error("CanopyX: toolbar options are booleans by control name.");this.local=view.timeZone==="local";this.fmt=formatting(this.lang,this.local,this.labels);this.kind="tree";this.plugins=viewPlugins(options,this.kind);const renderers=hostRenderers(options.renderers||{},view.columns,this.plugins);if(!options.formatLink!==!options.parseLink){throw new Error("CanopyX: formatLink and parseLink define one link scheme and are given together.")}
|
|
220
221
|
this.columns=view.columns.map((column,index)=>({...column,hidden:index>0&&!!column.hidden,render:Object.hasOwn(renderers,column.id)?renderers[column.id]:null}));this.columns.forEach(prepareWidth);this.columns.forEach(validateColumnValues);this.keyMap=new Map();this.root={key:null,h:null,parent:null,level:0,idx:0,expanded:true,children:null,total:null,next:null,loading:false,error:null};if(!options.source&&(!view.source||view.source.kind==="inline")){this.root.inlineItems=view.roots||[]}
|
|
221
222
|
this.rows=[];this.tops=[0];this.total=0;this.version=1;this.rendered=new Map();this.pool=[];this.focused=null;this.selected=new Set();this.anchor=null;this.filter=null;this.declaredFilter=null;this.filterExpand=false;this.activeFilters=new Set();this.sortState=null;this.typeBuf="";this.typeAt=0;this.rafId=0;this.iconTemplates=this.buildIcons(view.icons||{});this.initializing=true;this.prepareViewModes();this.build();this.buildToolbar();if(view.deepLink)loadPart(LINKS).catch(()=>{});this.ready=this.modesReady?Promise.all([this.init(),this.modesReady]).then(([result])=>result):this.init()}
|
|
@@ -410,7 +411,7 @@ if(accepted&&deferred&&revision===this.selectionRevision)
|
|
|
410
411
|
this.notifySelection(w,Array.from(this.selected).map((selected)=>selected.h),revision)}},async retryPage(status){const parent=status.parent;await this.loadStatusPage(parent,status,parent.next||null)},typeAhead(e,i){if(e.key.length!==1||e.ctrlKey||e.metaKey||e.altKey){return false}
|
|
411
412
|
const now=performance.now();const letter=e.key.toLowerCase();this.typeBuf=now-this.typeAt>TYPEAHEAD_MS?letter:this.typeBuf+letter;this.typeAt=now;const n=this.rows.length;const start=this.typeBuf.length===1?i+1:i;for(let k=0;k<n;k++){const w=this.rows[(start+k)%n];if(!w.status&&String(w.h.label).toLowerCase().startsWith(this.typeBuf)){this.setFocus(w);break}}
|
|
412
413
|
return true},announce(message){setText(this.live,message)}});const CELL_CONTROLS="a[href],button,input,select,textarea,summary,[tabindex],[contenteditable]:not([contenteditable=false])," +
|
|
413
|
-
"[role=button],[role=checkbox],[role=radio],[role=link],[role=switch],[role=tab],[role=menuitem],[role=textbox],[role=combobox]";const OWN_ARROWS=".cx-detail-body,textarea,select,[contenteditable]:not([contenteditable=false]),[aria-activedescendant]," +
|
|
414
|
+
"[role=button],[role=checkbox],[role=radio],[role=link],[role=switch],[role=tab],[role=menuitem],[role=textbox],[role=combobox]";const OWN_ARROWS=".cx-detail-body,.cx-phone-value,textarea,select,[contenteditable]:not([contenteditable=false]),[aria-activedescendant]," +
|
|
414
415
|
"[role=textbox],[role=combobox],[role=spinbutton],[role=slider],[role=radio],[role=tab],[role=menuitem],[role=listbox],[role=tree],[role=grid]," +
|
|
415
416
|
"input:not([type=button]):not([type=checkbox]):not([type=submit]):not([type=reset]):not([type=image]):not([type=file]):not([type=color])";function reachable(control){return!control.matches(":disabled")&&!control.closest("[inert],[aria-hidden=true]")&&
|
|
416
417
|
(control.checkVisibility?control.checkVisibility({visibilityProperty:true}):control.getClientRects().length>0)}
|
|
@@ -530,11 +531,11 @@ close()}else{return}
|
|
|
530
531
|
e.preventDefault()});input.addEventListener("blur",()=>{cancelNavigation();sequence++;clearTimeout(timer);clearTimeout(blurTimer);blurTimer=setTimeout(close,150)});this.cancelSearch=()=>{cancelNavigation();sequence++;clearTimeout(timer);clearTimeout(blurTimer);hits=[];close()};box.appendChild(input);box.appendChild(list);box.appendChild(status);bar.appendChild(box);this.searchInput=input}});function watchFlyout(anchorElement,panel,isOpen){const lifetime=new AbortController();let flyout=null,pending=null;const ready=()=>flyout?Promise.resolve(flyout):pending||=loadPart(SHARED_PARTS["ui-overlays"]).then(()=>{if(!lifetime.signal.aborted)flyout=UI_TOOLS.toolbarFlyout(anchorElement,panel,isOpen,lifetime.signal);return flyout}).catch(error=>{pending=null;throw error});const invoke=method=>{if(lifetime.signal.aborted||!isOpen())return;if(flyout){flyout[method]();return}
|
|
531
532
|
ready().then(value=>{if(!lifetime.signal.aborted&&isOpen())value?.[method]()}).catch(error=>{if(!lifetime.signal.aborted)(anchorElement.closest(".cx-host")||anchorElement)
|
|
532
533
|
.dispatchEvent(new CustomEvent("canopyx:error",{detail:{error},bubbles:true}))})};return{position:()=>invoke("position"),open:()=>invoke("open"),close:()=>flyout?.close(),dispose:()=>lifetime.abort()}}
|
|
533
|
-
const PART_URL=typeof document!=="undefined"&&document.currentScript?.src;const PARTS={"ui-overlays":["
|
|
534
|
+
const PART_URL=typeof document!=="undefined"&&document.currentScript?.src;const PARTS={"ui-overlays":["8dc12c5deb018c2c","canopyx-ui-overlays.1e39ccf6db0a3df6.js","canopyx-ui-overlays.3668a9a74004ea8e.css"],"ui-menu":["352b1ee391133ff0","canopyx-ui-menu.f9abee36db8f6ad2.js","canopyx-ui-menu.2f3478cc5f5c272f.css"],"ui-picker":["d415103478faf52a","canopyx-ui-picker.13e544bd68aca998.js","canopyx-ui-picker.59c85a1988a287a9.css"],"ui-navigation":["d14b60f4d16a1cf3","canopyx-ui-navigation.02e11de5f457cc64.js","canopyx-ui-navigation.fb8bdcd8dba604c8.css"],"ui-tabs":["96b84956100933e7","canopyx-ui-tabs.f83f7ebb96c86512.js","canopyx-ui-tabs.bb8c7c70a8b5be2c.css"],"ui-stepper":["a31fd5d0b314cdef","canopyx-ui-stepper.dfddf053fc163c73.js","canopyx-ui-stepper.1d4a9db373b8d2f2.css"],"tree-tools":["ef0d06c82135ae2e","canopyx-tree-tools.1c4b9e286dde6065.js","canopyx-tree-tools.350dd0ee46757029.css"],"presenters":["d5f9d61bb730974b","canopyx-presenters.d71f9e12d83969d9.js"],"filter-editor":["b760f978327dbab0","canopyx-filter-editor.4851bd579e7d146c.js","canopyx-filter-editor.2e0cf6850cbd3235.css"],"export":["15abf3205094bda6","canopyx-export.68b90138463329fe.js"],"office-export":["4fb7a4d570390ee9","canopyx-office-export.7e62c385b884e75b.js"],"history":["7d9901d2fe04df72","canopyx-history.9432e724bf14c9ed.js"],"pager":["cc30dd4f6d3feeb0","canopyx-pager.2a6f5da8c93de083.js","canopyx-pager.c1e16027780b7fdd.css"],"enhance":["a3b4be5ec19a43a6","canopyx-enhance.4a189cba27c290de.js"],"data":["bab770170bd2cfdd","canopyx-data.34325d1fd693886e.js"],"forms":["381a3edba481660b","canopyx-forms.fa85aa9e8b62876a.js","canopyx-forms.50a5ddb0fcc98bdf.css"],"flow":["02a915fe174e4710","canopyx-flow.2ec165998fe2950d.js","canopyx-flow.347ecd64183ea3a1.css"],"flow-host":["7169c4283cec8b25","canopyx-flow-host.52ccd1a2b6cd53f7.js","canopyx-flow-host.a7c8d3fc930ad3a9.css"],"flow-checks":["53394e75b7d1b0e2","canopyx-flow-checks.76e58f9d05eaa78f.js","canopyx-flow-checks.88dd9f389b249147.css"],"flow-options":["60450342239ded26","canopyx-flow-options.d31458a54aa4b1e7.js"],"flow-pick":["7e0924c72fdd2f74","canopyx-flow-pick.c2e34da944b0edab.js","canopyx-flow-pick.ce7687598d4703f1.css"],"flow-records":["0b652a9789ce4128","canopyx-flow-records.df8aba0a303019e0.js","canopyx-flow-records.393243243aae9a56.css"],"flow-drafts":["fac75bf905a77d0b","canopyx-flow-drafts.c7db634ab651e9fc.js","canopyx-flow-drafts.2c43cff1ce9be700.css"],"flow-preview":["5e8207eed3801f91","canopyx-flow-preview.3924dc8410f9775d.js","canopyx-flow-preview.069c52c33e87ffb4.css"],"flow-command":["a30245a47f6d4530","canopyx-flow-command.b145a234a6ecc8a2.js","canopyx-flow-command.f98b5333af3a0e17.css"],"flow-tasks":["8a4437f5216ac3ee","canopyx-flow-tasks.569d4c40d317472b.js","canopyx-flow-tasks.54857a9f2732048a.css"],"flow-dialog":["8c45e0a8bb6a8ab9","canopyx-flow-dialog.cb4e85bcb7383fe2.js","canopyx-flow-dialog.58bd5d446415e01a.css"],"flow-links":["2c14b19c9236e90d","canopyx-flow-links.7b6cfe42d28b6067.js"],"flow-endpoint":["f5cddfc9545e0920","canopyx-flow-endpoint.b31146202bd76aac.js"],"flow-facts":["385b5e61ed487e16","canopyx-flow-facts.8dad3bc07a71fdb0.js"],"flow-consent":["22121778bc0d07c5","canopyx-flow-consent.749b97f13039bc71.js","canopyx-flow-consent.9f6580d3673ae8bf.css"],"matrix":["002a6d917bb4d638","canopyx-matrix.17ae2d0e03ad1364.js","canopyx-matrix.59fc6920ae000d49.css"],"changes":["7d9a526aa07a8838","canopyx-changes.75f1a61cbba98a4f.js","canopyx-changes.5f0ae1710b8b081c.css"],"editing":["88e4ca705a7eb0c3","canopyx-editing.6a6df811fb4dde54.js","canopyx-editing.4816f6be6f89d794.css"],"column-groups":["91abd99e8ff95b58","canopyx-column-groups.4c71d23375de727c.js","canopyx-column-groups.4e4131c1e2df40b1.css"],"cell-range":["cb29468954702795","canopyx-cell-range.d4f99a024db5d0f8.js","canopyx-cell-range.c790b8f140b1243b.css"],"links":["c6579c9401f0971d","canopyx-links.b25760079f57e6e1.js"],"search":["521eebd6e1bbbd35","canopyx-search.14c69f4551c69f23.js"],"formatting":["0feff4e3424599e9","canopyx-formatting.94536547a1d35e9b.js","canopyx-formatting.22b2400c566e25d6.css"],"format-editor":["97085e181fbc1cf7","canopyx-format-editor.a6bc57c48173bfc0.js","canopyx-format-editor.d5aaa8e873d92695.css"],"link":["7485f5c9875e9f9b","canopyx-link.9066770aa822fe0f.js","canopyx-link.997fefec6b85f0c5.css"],"detail-rows":["1892f1fd9d035c0f","canopyx-detail-rows.8be98dbc5721170a.js","canopyx-detail-rows.275076ec8bd9144a.css"],"calculations":["f902dc5856fc7bdd","canopyx-calculations.97e438237ba43f99.js","canopyx-calculations.50432e524dd7d8d9.css"],"pivot":["577443c67c7ed719","canopyx-pivot.3abc630122030933.js","canopyx-pivot.5670e62c0bbf114f.css"],"values":["0d7006b0f7bfca10","canopyx-values.ad4c56fcbcd89cbb.js","canopyx-values.446654b98c62ef1d.css"],"buckets":["cc69c8336c15df83","canopyx-buckets.1f59613f13ee292c.js"],"grouping":["c82705991ff01a4c","canopyx-grouping.239f13b0785a2e30.js","canopyx-grouping.a91801c602d752b3.css"],"highlight":["5ebf0042011ba4fd","canopyx-highlight.ff11a0ca8e30102b.js","canopyx-highlight.9c26291cbcd0962b.css"],"layouts":["90267e35e7edf3a4","canopyx-layouts.058b8a396f909a79.js","canopyx-layouts.ca17f42babc4192a.css"],"facets":["e78c2340a96fa802","canopyx-facets.74b2e520a3c04580.js","canopyx-facets.e2970dd7cf0c3da6.css"],"live":["78791b002a111843","canopyx-live.878dc16d683abb72.js","canopyx-live.9881627f352f59da.css"],"record-panel":["cb6bcd1baf644a51","canopyx-record-panel.557c676822e8624f.js","canopyx-record-panel.174846a640de979f.css"],"calendar":["e11aad6b723ddf23","canopyx-calendar.79518c25ddf28dd7.js","canopyx-calendar.47490d57a6e6c1dc.css"],"calendar-recurrence":["64bcc24d785bd1af","canopyx-calendar-recurrence.4b7f430c2a64de23.js"],"calendar-edit":["09747e191820d94c","canopyx-calendar-edit.174f5125d3e75bd9.js"],"calendar-ics":["ac8b2950fccbfb0f","canopyx-calendar-ics.4a18c1c4a1520418.js"],"timeline":["cb9b9dd33154172c","canopyx-timeline.a3dea165914fa7fd.js","canopyx-timeline.44c3156c218531e2.css"],"grid-options":["ee53e6f124b99d5a","canopyx-grid-options.9f8604806c93bf19.js","canopyx-grid-options.e85648a66d70d5b5.css"],"board":["dd02be00df77f53a","canopyx-board.81de43b6e0f4aec3.js","canopyx-board.b62cc3a0348e758a.css"],"plan":["db07c2eb53541d49","canopyx-plan.f3bf394516b627b7.js","canopyx-plan.743201d95414f399.css"],"path":["c6fa2dbab6a0dbaa","canopyx-path.97c3ee2b076b2db6.js","canopyx-path.efba21adc0bfc372.css"],"stack":["e29298edc07edb6d","canopyx-stack.82a5a0c6383519dc.js","canopyx-stack.b867aa57edf9002c.css"],"time-slider":["5516099a165cc345","canopyx-time-slider.ed59a275671c729f.js","canopyx-time-slider.dfc55326f03e1d4a.css"],"view-intents":["dbd26360f2b90a49","canopyx-view-intents.3adcb56dffca0650.js","canopyx-view-intents.29a5c2de68ce3ba0.css"],"compare":["46245b96483e9c30","canopyx-compare.2a8ddc0ce67e903f.js","canopyx-compare.da0a2dff321e782d.css"]},PART_CODE=new Map(),SHARED_PARTS={},partName=name=>typeof name==="string"&&/^[a-z][a-z\d-]{0,31}$/.test(name);
|
|
534
535
|
function registerPart(name,part){if(!partName(name)||!part||typeof part.version!=="string"||typeof part.install!=="function"||
|
|
535
536
|
part.requires!==undefined&&!(Array.isArray(part.requires)&&part.requires.every(partName)))throw new Error("CanopyX: invalid part.");PART_CODE.set(name,part)}
|
|
536
537
|
function definePart(View,name,label,context){const parts=View.prototype.parts||={};return parts[name]={name,label,context,parts}}
|
|
537
|
-
function loadPart(part){return part.ready||=Promise.resolve().then(async()=>{const[version,scriptFile,styleFile]=Object.hasOwn(PARTS,part.name)?PARTS[part.name]:[];part.version=version;if(!version)throw new Error("CanopyX:
|
|
538
|
+
function loadPart(part){return part.ready||=Promise.resolve().then(async()=>{const[version,scriptFile,styleFile]=Object.hasOwn(PARTS,part.name)?PARTS[part.name]:[];part.version=version;if(!version)throw new Error("CanopyX: no "+part.label+".");if(PART_CODE.get(part.name)?.version!==part.version||part.styleReady===null){const find=type=>[...document.querySelectorAll('script[type="application/x-canopyx-'+type+'"][data-cx-version="'+part.version+'"]')].find(item=>!pageNonce||item.nonce===pageNonce);const payload=find(part.name),script=h("script"),embeddedStyle=styleFile&&find(part.name+"-style");if(payload){if(embeddedStyle){const style=h("style");style.nonce=payload.nonce;setText(style,embeddedStyle.textContent);document.head.appendChild(style)}
|
|
538
539
|
script.textContent=trusted("Script",payload.textContent);script.nonce=payload.nonce;document.head.appendChild(script);script.remove()}else{const base=global.CanopyXFilterEditorBase,runtime=PART_URL||typeof base==="string"&&base||document.baseURI,hashed=PART_URL&&/\.[a-f\d]{16}\.js(?:[?#]|$)/.test(PART_URL);
|
|
539
540
|
const load=(element,attribute,file,kind)=>new Promise((resolve,reject)=>{const url=new URL(file,runtime).href;element[attribute]=attribute==="src"?trusted("ScriptURL",url):url;element.onload=resolve;element.onerror=()=>{element.remove();reject(new Error("CanopyX: "+part.label+" "+kind+" unavailable."))};document.head.appendChild(withNonce(element))});const link=h("link");link.rel="stylesheet";const style=styleFile&&(part.styleReady||=load(link,"href",hashed?styleFile:"canopyx-"+part.name+".css","stylesheet")
|
|
540
541
|
.catch(error=>{part.styleReady=null;throw error}));const code=PART_CODE.get(part.name)?.version===part.version||(part.scriptReady||=load(script,"src",hashed?scriptFile:"canopyx-"+part.name+".js","script")
|
|
@@ -704,11 +705,12 @@ function gridNumberFormat(format){const minimum=format?.minimumFractionDigits??0
|
|
|
704
705
|
Object.keys(format).some(key=>!["minimumFractionDigits","maximumFractionDigits","prefix","suffix"].includes(key))||
|
|
705
706
|
[format.prefix,format.suffix].some(text=>text!==undefined&&(typeof text!=="string"||!text||text.length>16)))throw new Error("CanopyX: invalid number format.")}
|
|
706
707
|
function validateGridView(view){checkDocument(view,"grid");requireIdentifier(view.id,"grid ID");if([view.board,view.path,view.stack,view.calendar].filter(value=>value!=null).length>1)
|
|
707
|
-
throw new Error("CanopyX: choose one grid presentation: board, path, stack or calendar (with optional plan).");view=gridColumnDefaults(view);if(view.
|
|
708
|
-
throw new Error("CanopyX:
|
|
709
|
-
throw new Error("CanopyX:
|
|
710
|
-
throw new Error("CanopyX:
|
|
711
|
-
throw new Error("CanopyX: a grid needs a label and columns.");if(view.
|
|
708
|
+
throw new Error("CanopyX: choose one grid presentation: board, path, stack or calendar (with optional plan).");view=gridColumnDefaults(view);if(view.selectOnClick!==undefined&&typeof view.selectOnClick!=="boolean")throw new Error("CanopyX: selectOnClick is a boolean.");if(view.allowRegexSearch!==undefined&&typeof view.allowRegexSearch!=="boolean")throw new Error("CanopyX: allowRegexSearch is a boolean.");const groups=[view.columnBands,view.columnGroups].filter(value=>value!==undefined);if(groups.length>1||groups.some(value=>!Array.isArray(value)))
|
|
709
|
+
throw new Error("CanopyX: choose columnBands or columnGroups as an array.");if(view.rowIdentity!==undefined&&!["stableKey","ordinal"].includes(view.rowIdentity))
|
|
710
|
+
throw new Error("CanopyX: rowIdentity must be stableKey or ordinal.");if(view.rowIdentity==="ordinal"&&(view.live||view.record?.deepLink))
|
|
711
|
+
throw new Error("CanopyX: rowIdentity must be stableKey for live updates or deep links.");if(typeof view.label!=="string"||!view.label.trim()||!Array.isArray(view.columns)||!view.columns.length)
|
|
712
|
+
throw new Error("CanopyX: a grid needs a label and columns.");if(!view.source||typeof view.source!=="object"||!["inline","host"].includes(view.source.kind))
|
|
713
|
+
throw new Error("CanopyX: a grid needs source.kind inline or host.");if(view.reporting!==undefined){if(!GRID_REPORTING.validate)throw new Error("CanopyX: this view needs the reporting runtime.");GRID_REPORTING.validate(view)}
|
|
712
714
|
const ids=new Set();for(const column of view.columns){requireIdentifier(column&&column.id,"grid column ID");if(ids.has(column.id)||typeof column.title!=="string"||!["text","number","datetime"].includes(column.kind)||
|
|
713
715
|
column.headerDescription!==undefined&&typeof column.headerDescription!=="string"||
|
|
714
716
|
column.width!==undefined&&(!Number.isInteger(column.width)||column.width<40)||
|
|
@@ -723,17 +725,18 @@ column.section!==undefined&&(typeof column.section!=="string"||!column.section.t
|
|
|
723
725
|
throw new Error("CanopyX: invalid column aggregate or drawer section.")}
|
|
724
726
|
if(view.columns.every(column=>column.hidden)||view.columns.filter(column=>column.rowHeader).length>1)
|
|
725
727
|
throw new Error("CanopyX: a grid needs a visible column and one row header at most.");if(view.density!==undefined&&!["compact","default","comfortable"].includes(view.density)||
|
|
726
|
-
["zebra","statusBar","autoHeight","rowAccents"].some(name=>view[name]!==undefined&&typeof view[name]!=="boolean")||
|
|
728
|
+
["zebra","statusBar","autoHeight","rowAccents","recordDrawerModal"].some(name=>view[name]!==undefined&&typeof view[name]!=="boolean")||
|
|
727
729
|
view.rowAction!==undefined&&!["none","details","link"].includes(view.rowAction)||
|
|
728
730
|
view.noun!==undefined&&(typeof view.noun!=="string"||!view.noun.trim()||view.noun.length>256)||
|
|
729
731
|
view.emptyReason!==undefined&&(typeof view.emptyReason!=="string"||view.emptyReason.length>4096))throw new Error("CanopyX: invalid grid appearance or state text.");validateGridHighlights(view);if(view.searchDelayMs!==undefined&&(!Number.isInteger(view.searchDelayMs)||view.searchDelayMs<0||view.searchDelayMs>5000))
|
|
730
732
|
throw new Error("CanopyX: search delay must be an integer from 0 to 5000 milliseconds.");if(view.searchColumns!==undefined&&(!Array.isArray(view.searchColumns)||!view.searchColumns.length||
|
|
731
733
|
new Set(view.searchColumns).size!==view.searchColumns.length||view.searchColumns.some(id=>!ids.has(id))))
|
|
732
|
-
throw new Error("CanopyX: search columns must identify unique declared columns.");if(view.exportFormats!==undefined&&!exportFormatIds(view.exportFormats))throw new Error("CanopyX: exportFormats lists unique format IDs.");if(view.
|
|
733
|
-
|
|
734
|
-
view.
|
|
735
|
-
!Number.isInteger(view.
|
|
736
|
-
|
|
734
|
+
throw new Error("CanopyX: search columns must identify unique declared columns.");if(view.exportFormats!==undefined&&!exportFormatIds(view.exportFormats))throw new Error("CanopyX: exportFormats lists unique format IDs.");if(!Number.isInteger(view.pageSize)||view.pageSize<1||view.pageSize>10000)
|
|
735
|
+
throw new Error("CanopyX: pageSize must be 1 to 10000.");if(!["none","single","multiple"].includes(view.selection))
|
|
736
|
+
throw new Error("CanopyX: selection must be none, single or multiple.");if(view.autoRowHeight!==undefined&&typeof view.autoRowHeight!=="boolean")
|
|
737
|
+
throw new Error("CanopyX: autoRowHeight is a boolean.");if(view.rowHeight!==undefined&&view.rowHeight!=="auto"&&(!Number.isInteger(view.rowHeight)||view.rowHeight<20||view.rowHeight>64))
|
|
738
|
+
throw new Error("CanopyX: rowHeight must be auto or 20 to 64.");if(view.estimatedRowHeight!==undefined&&(!Number.isInteger(view.estimatedRowHeight)||view.estimatedRowHeight<20||view.estimatedRowHeight>64))
|
|
739
|
+
throw new Error("CanopyX: estimatedRowHeight must be 20 to 64.");if(view.calculatedColumnsEditable!==undefined&&(typeof view.calculatedColumnsEditable!=="boolean"||view.calculatedColumnsEditable&&view.source.kind!=="inline"))
|
|
737
740
|
throw new Error("CanopyX: the calculated-column editor requires an inline grid.");if(view.source.navigation!==undefined&&!["offset","cursor"].includes(view.source.navigation))
|
|
738
741
|
throw new Error("CanopyX: invalid grid source navigation.");if(view.source.navigation==="cursor"&&(view.source.kind!=="host"||view.presentation!=="paged"))
|
|
739
742
|
throw new Error("CanopyX: cursors need a hosted paged grid.");if(view.presentation!==undefined&&!["continuous","paged"].includes(view.presentation)||
|
|
@@ -807,8 +810,8 @@ throw new Error("CanopyX: facet counts contradict the known accepted dataset cou
|
|
|
807
810
|
throw new Error("CanopyX: invalid facet value/count bucket.");const key=gridFacetKey(item.value,column);if(keys.has(key))throw new Error("CanopyX: duplicate typed facet bucket.");keys.add(key);occurrences +=item.count;return{value:item.value,count:item.count}});if(occurrences>input.matched||!request.search&&!input.truncated&&occurrences!==input.matched)
|
|
808
811
|
throw new Error("CanopyX: facet buckets contradict the matching row count.");return gridFreeze({protocol:PROTOCOL,type:"gridFacetPage",view:input.view,revision:input.revision,column:input.column,search:input.search,includeCurrentFilter:input.includeCurrentFilter,matched:input.matched,totalValues:input.totalValues,truncated:input.truncated,items,...(request.bucket?{bucket:request.bucket}:{})})}
|
|
809
812
|
class DataGrid{constructor(host,options){const{rows,rowData,...definition}=validateGridView(options.view),owned=parsedViews.has(options.view);this.view=JSON.parse(JSON.stringify(definition));if(this.view.rowIdentity==="ordinal"&&options.live)
|
|
810
|
-
throw new Error("CanopyX:
|
|
811
|
-
this.host=host;this.opts=options;this.id="cx" + ++instanceSeq;this.lifetime=new AbortController();this.dataLifetime=new AbortController();this.source=options.source||(this.view.source.kind==="inline"?this.view.rowData?rowDataSource(this):inlineGridSource(this.view):null);if(!this.source||typeof this.source.query!=="function")throw new Error("CanopyX: host grids need a query source.");this.cursor=this.view.source.navigation==="cursor";if(this.source.navigation!==undefined&&this.source.navigation!==(this.cursor?"cursor":"offset"))
|
|
813
|
+
throw new Error("CanopyX: rowIdentity must be stableKey for live updates or deep links.");if(rows)this.view.rows=owned?rows:JSON.parse(JSON.stringify(rows));if(rowData){this.view.rowData=owned?rowData:structuredClone(rowData);this.view.rows=[]}
|
|
814
|
+
this.selectOnClick=this.view.selectOnClick===true;this.host=host;this.opts=options;do{this.id="cx" + ++instanceSeq}while(document.getElementById(this.id));this.lifetime=new AbortController();this.dataLifetime=new AbortController();this.source=options.source||(this.view.source.kind==="inline"?this.view.rowData?rowDataSource(this):inlineGridSource(this.view):null);if(!this.source||typeof this.source.query!=="function")throw new Error("CanopyX: host grids need a query source.");this.cursor=this.view.source.navigation==="cursor";if(this.source.navigation!==undefined&&this.source.navigation!==(this.cursor?"cursor":"offset"))
|
|
812
815
|
throw new Error("CanopyX: source navigation must match the grid definition.");this.pageSize=this.view.pageSize;this.authoredAutoRows=this.view.rowHeight==="auto"||!!this.view.autoRowHeight||
|
|
813
816
|
this.view.autoRowHeight!==false&&this.view.columns.some(column=>column.wrap);this.autoRows=this.authoredAutoRows;this.rowH=this.view.rowHeight==="auto"?this.view.estimatedRowHeight||(this.view.density==="compact"?32:40):this.view.rowHeight;this.rowHeights=new Map();this.paged=this.view.presentation==="paged";this.pageLength=this.view.pageLength||50;this.pageOffset=0;this.searchDelayMs=options.searchDelayMs===undefined?this.view.searchDelayMs===undefined?
|
|
814
817
|
this.view.source.kind==="inline"?0:300:this.view.searchDelayMs:options.searchDelayMs;if(!Number.isInteger(this.searchDelayMs)||this.searchDelayMs<0||this.searchDelayMs>5000)
|
|
@@ -826,12 +829,12 @@ async setQuery(input,paging){if(this.destroyed)throw new DOMException("Grid was
|
|
|
826
829
|
const same=this.acceptedQuery&&gridResultShape(initial)===gridResultShape(this.acceptedQuery)&&initial.revision===this.acceptedQuery.revision;let query=this.paged&&!this.cursor?gridQuery(this.view,{...initial,offset:same?Math.min(desired,Math.max(0,Math.ceil(this.rowCount()/ length) - 1) * length) : 0 }) : initial;
|
|
827
830
|
const epoch=++this.queryEpoch;clearTimeout(this.searchTimer);this.searchTimer=null;this.dataLifetime.abort();this.dataLifetime=new AbortController();const lifetime=this.dataLifetime;this.pendingPages.clear();this.pendingQuery=query;this.pendingPaging=paging?{...paging,pageLength:length}:null;this.setNotice(this.labels.loading,false);this.grid.setAttribute("aria-busy","true");this.syncPager();try{let page=(this.cursor?validateGridCursorPage:validateGridPage)(await this.requestPage(query,lifetime.signal),this.view,query,same?this.snapshot:null);if(this.cursor&&paging&&paging.direction)this.validateCursorTransition(page,paging);if(this.paged&&!this.cursor&&!same&&desired){gridOperationActive(this,lifetime.signal);const offset=Math.min(desired,Math.max(0,Math.ceil(page.matched / length) - 1) * length);
|
|
828
831
|
if(offset){const snapshot={revision:page.revision,total:page.total,matched:page.matched};query=gridQuery(this.view,{...query,offset,revision:page.revision});page=validateGridPage(await this.requestPage(query,lifetime.signal),this.view,query,snapshot)}}
|
|
829
|
-
gridOperationActive(this,lifetime.signal);const hadFocus=this.canvas.contains(document.activeElement),previousId=this.focused&&this.focused.key;const retireSelection=this.view.rowIdentity==="ordinal"&&this.snapshot&&this.snapshot.revision!==page.revision;this.pages.clear();this.rowCache.clear();this.placeholders.clear();this.focused=null;this.acceptedQuery=gridQuery(this.view,{...query,revision:page.revision});this.snapshot={revision:page.revision,total:page.total,matched:page.matched};if(retireSelection)this.clearSnapshotSelection();this.pageLength=length;if(paging)this.pageAll=!!paging.allRows;this.pageOffset=this.cursor?page.offset:this.paged?query.offset:0;if(this.cursor)this.cursorWindow={end:page.offset+page.items.length,next:page.nextCursor,previous:page.previousCursor};if(this.autoRows){if(!same)this.rowHeights.clear();this.rowOffsets=null}
|
|
832
|
+
gridOperationActive(this,lifetime.signal);const hadFocus=this.canvas.contains(document.activeElement),previousId=this.focused&&this.focused.key;const retireSelection=this.view.rowIdentity==="ordinal"&&this.snapshot&&this.snapshot.revision!==page.revision;if(!same||this.snapshot?.revision!==page.revision)this.selectionAnchor=null;this.pages.clear();this.rowCache.clear();this.placeholders.clear();this.focused=null;this.acceptedQuery=gridQuery(this.view,{...query,revision:page.revision});this.snapshot={revision:page.revision,total:page.total,matched:page.matched};if(retireSelection)this.clearSnapshotSelection();this.pageLength=length;if(paging)this.pageAll=!!paging.allRows;this.pageOffset=this.cursor?page.offset:this.paged?query.offset:0;if(this.cursor)this.cursorWindow={end:page.offset+page.items.length,next:page.nextCursor,previous:page.previousCursor};if(this.autoRows){if(!same)this.rowHeights.clear();this.rowOffsets=null}
|
|
830
833
|
this.storePage(page);this.pendingQuery=null;this.pendingPaging=null;this.lastFailedQuery=null;this.lastFailedPaging=null;this.version++;const hasRows=this.cursor?page.items.length:page.matched;this.total=(this.cursor?page.items.length:this.paged?Math.min(length,page.matched-this.pageOffset):page.matched)*this.rowH;this.grid.setAttribute("aria-rowcount",page.matched===null?"-1":String(page.matched+1 +(this.headDepth||0)));this.grid.tabIndex=hasRows?-1:0;this.syncScrollRange(this.paged?0:query.offset*this.rowH);this.buildHeader();this.syncColumnControls();this.setNotice(hasRows?"":this.labels.searchNoResults,false);this.grid.setAttribute("aria-busy","false");if(hadFocus||this.focusOrigin){this.focused=[...this.rowCache.values()].find(row=>row.key===previousId)||this.rowCache.get(this.cursor?page.offset:query.offset)||null}
|
|
831
834
|
this.render();if(hadFocus){const element=this.focused&&this.rendered.get(this.focused);(element||this.grid).focus({preventScroll:true})}
|
|
832
835
|
this.host.setAttribute("data-cx-ready","true");if(this.searchInput&&!this.searchComposing&&this.searchTimer==null)this.searchInput.value=query.search;if(this.searchInput){const label=query.searchMode==="regex"?this.labels.gridRegexSearch:this.view.noun?
|
|
833
836
|
fill(this.labels.gridSearchNoun,{noun:this.noun}):this.labels.searchPlaceholder;this.searchInput.placeholder=label;this.searchInput.setAttribute("aria-label",label);this.searchInput.maxLength=query.searchMode==="regex"?256:524288;this.searchInput.setCustomValidity("")}
|
|
834
|
-
this.syncQuerySummary();this.syncPager();this.emit("query",{query:this.acceptedQuery,revision:page.revision,total:page.total,matched:page.matched});this.stateChanged();return this.getQuery()}catch(error){if(epoch===this.queryEpoch&&!this.destroyed){const cancelled=lifetime.signal.aborted&&error?.name==="AbortError";this.pendingQuery=null;this.pendingPaging=null;this.lastFailedQuery=cancelled?null:initial;this.lastFailedPaging=cancelled?null:{...paging,pageLength:length};this.dataLifetime.abort();this.dataLifetime=new AbortController();this.grid.setAttribute("aria-busy","false");this.setNotice(cancelled?"":fill(this.labels.queryFailed,{error:error.message}),!cancelled);this.syncPager();if(!cancelled)this.emit("error",{error})}
|
|
837
|
+
this.syncQuerySummary();this.syncPager();this.fitHeight();this.emit("query",{query:this.acceptedQuery,revision:page.revision,total:page.total,matched:page.matched});this.stateChanged();return this.getQuery()}catch(error){if(epoch===this.queryEpoch&&!this.destroyed){const cancelled=lifetime.signal.aborted&&error?.name==="AbortError";this.pendingQuery=null;this.pendingPaging=null;this.lastFailedQuery=cancelled?null:initial;this.lastFailedPaging=cancelled?null:{...paging,pageLength:length};this.dataLifetime.abort();this.dataLifetime=new AbortController();this.grid.setAttribute("aria-busy","false");this.setNotice(cancelled?"":fill(this.labels.queryFailed,{error:error.message}),!cancelled);this.syncPager();this.fitHeight();if(!cancelled)this.emit("error",{error})}
|
|
835
838
|
throw error}}
|
|
836
839
|
querySortHeader(id,event){const previous=gridQuery(this.view,this.queryForChange(true)),sorts=previous.sort.slice();const found=sorts.findIndex(sort=>sort.column===id),old=found>=0?sorts[found].direction:null;const authored=this.columns.find(column=>column.id===id).orderSequence;const sequence=authored?.length?authored:["asc","desc","none"];const direction=sequence[(sequence.indexOf(old||"none")+ 1)%sequence.length];const next=direction==="none"?null:direction;const changed=event&&event.shiftKey?sorts.filter(sort=>sort.column!==id):[];if(next)changed.splice(event&&event.shiftKey&&found>=0?Math.min(found,changed.length):changed.length,0,{column:id,direction:next});this.setQuery(gridQueryStart(previous,{sort:changed})).catch(()=>{})}
|
|
837
840
|
sort(sorts){return this.setQuery(gridQueryStart(this.queryForChange(true),{sort:sorts}))}
|
|
@@ -844,12 +847,12 @@ indexOf(row){if(!row||this.paged&&(row._ri<this.pageOffset||row._ri>=this.pageOf
|
|
|
844
847
|
rowItem(index){if(index<0||index>=this.rowCount()||this.paged&&(index<this.pageOffset||index>=this.pageOffset+this.pageLength))return null;if(this.rowCache.has(index))return this.rowCache.get(index);if(!this.placeholders.has(index))this.placeholders.set(index,{_ri:index,hpx:this.rowH,status:"loading",h:{cells:{}}});const row=this.placeholders.get(index),page=this.pages.get(Math.floor(index / this.pageSize) * this.pageSize);
|
|
845
848
|
row.status=page&&page.error?"error":"loading";return row}
|
|
846
849
|
render(){if(this.destroyed||!this.sized)return;let measured=false;if(this.autoRows)this.syncRowOffsets();for(let pass=0;;pass++){this.renderPass();if(!this.autoRows||!this.measureGridRows())break;measured=true;if(pass===3){this.scheduleRender();break}}
|
|
847
|
-
for(const[index,row]of this.placeholders)if(!this.rendered.has(row)&&this.focused!==row)this.placeholders.delete(index);this.loadWindow();const origin=this.focusOrigin;if(origin&&this.hasGridSize()){this.focusOrigin=null;if(document.activeElement===origin)(this.rendered.get(this.focused)||this.grid).focus({preventScroll:true})}
|
|
850
|
+
this.syncGridPhoneValues?.();for(const[index,row]of this.placeholders)if(!this.rendered.has(row)&&this.focused!==row)this.placeholders.delete(index);this.loadWindow();const origin=this.focusOrigin;if(origin&&this.hasGridSize()){this.focusOrigin=null;if(document.activeElement===origin)(this.rendered.get(this.focused)||this.grid).focus({preventScroll:true})}
|
|
848
851
|
return measured}
|
|
849
852
|
observeDetail(){}
|
|
850
853
|
trimInactiveCache(){this.trimPages()}
|
|
851
854
|
clearSnapshotSelection(){const changed=this.selected.size||this.querySelection;this.selectionController?.abort();this.selectionAnchor=null;this.querySelection=null;this.selectionExcluded=null;this.selected.clear();if(changed){this.version++;this.scheduleRender();this.emit("select",{ids:[]});this.syncGridChrome()}}
|
|
852
|
-
setSelection(ids){if(this.destroyed)return;if(!Array.isArray(ids))throw new Error("CanopyX: selection must be an array of row IDs.");ids.forEach(id=>requireIdentifier(id,"selection ID"));const next=new Set(ids);if(this.view.selection==="none"&&next.size||!this.multi&&next.size>1)throw new Error("CanopyX: selection exceeds the view's mode.");this.selected=next;this.version++;this.scheduleRender();this.emit("select",{ids:[...next]});this.syncGridChrome();this.stateChanged()}
|
|
855
|
+
setSelection(ids){if(this.destroyed)return;if(!Array.isArray(ids))throw new Error("CanopyX: selection must be an array of row IDs.");ids.forEach(id=>requireIdentifier(id,"selection ID"));const next=new Set(ids);if(this.view.selection==="none"&&next.size||!this.multi&&next.size>1)throw new Error("CanopyX: selection exceeds the view's mode.");this.selectionController?.abort();this.selectionAnchor=null;this.selected=next;this.version++;this.scheduleRender();this.emit("select",{ids:[...next]});this.syncGridChrome();this.stateChanged()}
|
|
853
856
|
setColumnVisible(id,visible){const column=this.columns.find(item=>item.id===id);if(!column||typeof visible!=="boolean")throw new Error("CanopyX: visibility needs a declared column and boolean.");if(!visible&&this.columns.filter(item=>!item.hidden).length===1&&!column.hidden)throw new Error("CanopyX: keep at least one column visible.");column.hidden=!visible;this.buildHeader();this.version++;this.scheduleRender();this.stateChanged();this.syncColumnControls()}
|
|
854
857
|
destroy(){if(this.destroyed)return;this.writeStoredState(this.getState());this.destroyed=true;this.queryEpoch++;this.lifetime.abort();this.dataLifetime.abort();this.focusOrigin=null;for(const row of[...this.rendered.values(),...this.pool])disposeRowHostCells(row);if(this.rafId)cancelAnimationFrame(this.rafId);clearTimeout(this.searchTimer);this.searchTimer=null;clearTimeout(this.stateTimer);if(this.disposeControls)this.disposeControls();if(this.cancelResize)this.cancelResize();this.resizeObserver.disconnect();this.detailObserver?.disconnect();this.rowHeights?.clear();this.rowOffsets=null;this.restoreHeight();this.host.classList.remove("cx-data-grid","cx-chrome","cx-phone","cx-has-selection","cx-scroll-left","cx-scroll-right","cx-grid-awaiting","cx-pins");this.grid.removeEventListener("wheel",this.onScaledWheel);this.grid.removeEventListener("touchstart",this.onScaledTouchStart);this.grid.removeEventListener("touchmove",this.onScaledTouchMove);this.grid.removeEventListener("touchend",this.onScaledTouchEnd);this.grid.removeEventListener("touchcancel",this.onScaledTouchEnd);this.pages.clear();this.rowCache.clear();this.placeholders.clear();this.pendingPages.clear();this.rendered.clear();this.pool.length=0;this.toolbar.remove();this.grid.remove();this.notice.remove();this.live.remove();this.querySummary?.remove();if(this.pager)this.pager.remove();this.statusBar?.remove();this.groupBar?.remove();this.statusAggregateController?.abort();this.host.removeAttribute("data-cx-ready");this.host.removeAttribute("data-canopyx-mounted")}}
|
|
855
858
|
Object.assign(DataGrid.prototype,ROW_SCROLLING,ROW_DOM_ORDER,ROW_VIEWPORT,ROW_HELPERS);Object.assign(DataGrid.prototype,{requestPage(query,signal){return this.runGridHook(signal=>this.source.query(query,{signal}),signal)},storePage(page){const rows=page.items.map((item,i)=>({key:item.id,h:item,_ri:page.offset+i,hpx:this.rowH}));const incoming=new Map(rows.map(row=>[row.key,row._ri]));for(const cached of this.rowCache.values())if(incoming.has(cached.key)&&incoming.get(cached.key)!==cached._ri)
|
|
@@ -896,9 +899,10 @@ this.canvas.addEventListener("focusin",event=>{const element=event.target.closes
|
|
|
896
899
|
this.pendingNavigation=null;if(element&&element._w&&this.focused!==element._w){this.pendingNavigation=null;this.focused=element._w;this.scheduleRender()}},{signal});document.addEventListener("focusin",event=>{if(this.pendingNavigation&&this.pendingNavigation.focus&&!this.canvas.contains(event.target))this.pendingNavigation=null;if(this.focusOrigin&&event.target!==this.focusOrigin)this.focusOrigin=null},{signal,capture:true});document.addEventListener("focusout",event=>{if(event.target===this.focusOrigin)this.focusOrigin=null},{signal,capture:true});this.canvas.addEventListener("focusout",event=>this.settleCell(event.relatedTarget),{signal});this.sized=this.hasGridSize();grid.style.opacity="0";let resizeFrame;signal.addEventListener("abort",()=>cancelAnimationFrame(resizeFrame),{once:true});this.resizeObserver=new ResizeObserver(entries=>{const size=entries.find(entry=>entry.target===grid);if(size)this.fitContentWidth=size.contentRect.width;if(size&&!size.contentRect.width)grid.style.opacity="0";const resize=()=>{if(this.destroyed)return;if(!grid.clientWidth||!grid.checkVisibility()){if(host.clientWidth&&host.checkVisibility())this.updateGridPhone();this.sized=false;return}
|
|
897
900
|
if(this.fitContentWidth===0)return;if(host.classList.contains("cx-grid-awaiting"))grid.style.setProperty("--cx-empty-head-height",Math.max(this.phone?44:0,this.head.offsetHeight+grid.offsetHeight-grid.clientHeight)+ "px");style.setProperty("--cx-min-h",this.minimumGridHeight()+ "px");this.fitHeight();if(!(this.sized=this.hasGridSize()))return;this.applyWidths();this.updateGridPhone();this.fitHeight();this.viewportHeight=grid.clientHeight-this.head.offsetHeight;if(this.hiddenScrollTop!==undefined){const top=this.hiddenScrollTop;delete this.hiddenScrollTop;this.setLogicalTop(top)}
|
|
898
901
|
if(grid.style.opacity){this.render();grid.style.opacity=""}
|
|
899
|
-
else this.scheduleRender()};cancelAnimationFrame(resizeFrame);resizeFrame=requestAnimationFrame(resize)});this.resizeObserver.observe(grid);this.resizeObserver.observe(this.head);this.resizeObserver.observe(host)},minimumGridHeight(){if(this.toolbar.hidden)return 0;
|
|
900
|
-
parseFloat(css.paddingTop)+ parseFloat(css.paddingBottom)}
|
|
901
|
-
return
|
|
902
|
+
else this.scheduleRender()};cancelAnimationFrame(resizeFrame);resizeFrame=requestAnimationFrame(resize)});this.resizeObserver.observe(grid);this.resizeObserver.observe(this.head);this.resizeObserver.observe(host)},minimumGridHeight(rows=true){if(rows&&this.toolbar.hidden)return 0;const host=getComputedStyle(this.host);let count=0;const height=[...this.host.children].reduce((sum,child)=>{const css=getComputedStyle(child);if(css.display==="none"||css.position==="absolute"||css.position==="fixed")return sum;count++;let block=child===this.grid?0:child.offsetHeight;if(child===this.notice&&child.classList.contains("cx-state")){block=(child.lastElementChild?child.lastElementChild.getBoundingClientRect().bottom-child.firstElementChild.getBoundingClientRect().top:0)+
|
|
903
|
+
parseFloat(css.paddingTop)+ parseFloat(css.paddingBottom)+ child.offsetHeight-child.clientHeight;block=Math.max(block,parseFloat(css.minHeight)||0)}
|
|
904
|
+
return sum+block+parseFloat(css.marginTop)+ parseFloat(css.marginBottom)},rows?Math.max(this.head.offsetHeight,this.rowH*Math.min(4,Math.max(1,this.rowCount())))+ 2:0);return height+this.host.offsetHeight-this.host.clientHeight+parseFloat(host.paddingTop)+ parseFloat(host.paddingBottom)
|
|
905
|
+
+ Math.max(0,count-1)*(parseFloat(host.rowGap)||0)},setLogicalTop(top){if(!this.hasGridSize()){this.hiddenScrollTop=top;return}
|
|
902
906
|
const result=ROW_SCROLLING.setLogicalTop.call(this,top);this.visibleScrollTop=ROW_SCROLLING.logicalTop.call(this);return result},logicalTop(){if(this.hiddenScrollTop!==undefined)return this.hiddenScrollTop;if(!this.grid.checkVisibility())return this.visibleScrollTop??0;return this.visibleScrollTop=ROW_SCROLLING.logicalTop.call(this)},hasGridSize(){return!!(this.grid.clientWidth&&this.grid.clientHeight&&this.grid.checkVisibility())},buildHeader(){const fixed=new Set((this.view.preSort||[]).map(sort=>sort.column));const sorts=(this.acceptedQuery?.sort||[]).filter(sort=>!fixed.has(sort.column));const fixedText=(this.view.preSort||[]).map(sort=>(this.columns.find(column=>column.id===sort.column)?.title||sort.column)+ " "+sort.direction).join(", ");this.sortState=sorts[0]||null;ROW_HELPERS.buildHeader.call(this);for(const cell of this.headCells){const column=this.columns.find(column=>column.id===cell.getAttribute("data-cx-column"));if(column?.className)cell.classList.add(...column.className.split(/ +/));
|
|
903
907
|
if(column?.alignment)cell.style.textAlign=column.alignment;const button=cell.querySelector(".cx-sort");if(fixedText)cell.title +="\nAlways sorted by "+fixedText+" first";if(button){const label=h("span","cx-htext");setText(label,button.textContent);button.replaceChildren(label)}
|
|
904
908
|
const index=sorts.findIndex(sort=>sort.column===cell.getAttribute("data-cx-column"));if(index>=0){cell.setAttribute("aria-sort",sorts.length===1?sorts[index].direction==="asc"?"ascending":"descending":"other");cell.setAttribute("data-cx-sort",sorts[index].direction);cell.setAttribute("data-cx-sort-priority",String(index+1));button.setAttribute("data-cx-sort-priority",String(index+1));if(sorts.length>1){const priority=h("sup","cx-sort-priority");setText(priority,String(index+1));button.appendChild(priority)}
|
|
@@ -929,9 +933,13 @@ this.total=this.rowOffsets.top(count);this.syncScrollRange(this.logicalTop());th
|
|
|
929
933
|
if(changed){this.total=this.rowOffsets.top(this.rowOffsets.count);this.syncScrollRange(rows.rowTop(anchor.index)+ anchor.offset)}
|
|
930
934
|
return changed},revealGridRow(row,index,rows=this){const top=rows.rowTop(index),viewport=Math.max(0,this.grid.clientHeight-this.head.offsetHeight);if(top<this.logicalTop())this.setLogicalTop(top);else if(top+Math.min(row.hpx,viewport)>this.logicalTop()+ viewport)this.setLogicalTop(top+Math.min(row.hpx,viewport)- viewport)},gridPageStep(row,direction,rows=this){const index=this.rowProjection?rows.indexOf(row):row._ri;if(!this.autoRows)return index+direction*Math.max(1,Math.floor((this.grid.clientHeight-this.head.offsetHeight)/ this.rowH));
|
|
931
935
|
const proposed=rows.rowAt(Math.max(0,rows.rowTop(index)+ direction*(this.grid.clientHeight-this.head.offsetHeight)));return direction>0?Math.max(index+1,proposed):Math.min(index-1,proposed)}});const HEIGHT_RENDER=DataGrid.prototype.render;DataGrid.prototype.render=function(){const measured=HEIGHT_RENDER.call(this);if(this.sized&&this.total!==this.fitTotal){this.fitTotal=this.total;this.fitHeight()}
|
|
932
|
-
return measured};DataGrid.prototype.fitHeight=function(){if(this.view.autoHeight===false||this.pendingQuery||!this.grid.clientWidth||!this.host.checkVisibility())return;const grid=this.grid,style=this.host.style
|
|
933
|
-
|
|
934
|
-
const
|
|
936
|
+
return measured};DataGrid.prototype.fitHeight=function(){if(this.view.autoHeight===false||this.pendingQuery||!this.grid.clientWidth||!this.host.checkVisibility())return;const grid=this.grid,style=this.host.style;const content=[...grid.children].reduce((sum,child)=>{const position=getComputedStyle(child).position;return position==="absolute"||position==="fixed"?sum:sum+child.getBoundingClientRect().height},grid.offsetHeight-grid.clientHeight);if(this.fitInline===undefined){this.fitInline=style.maxHeight;global.addEventListener("resize",()=>this.fitHeight(),{signal:this.lifetime.signal})}
|
|
937
|
+
if(/var\(/i.test(this.fitInline) && !this.fitBoundObserver) {
|
|
938
|
+
const observer=this.fitBoundObserver=new MutationObserver(records=>{if(records.some(record=>record.target!==this.host||record.attributeName==="class")||this.fitStyle!==style.cssText)this.fitHeight()});this.lifetime.signal.addEventListener("abort",()=>observer.disconnect(),{once:true})}
|
|
939
|
+
if(this.fitBoundObserver&&this.fitBoundParent!==this.host.parentElement){this.fitBoundObserver.disconnect();for(let parent=this.host;parent;parent=parent.parentElement)
|
|
940
|
+
this.fitBoundObserver.observe(parent,{attributes:true,attributeFilter:["style","class"]});this.fitBoundParent=this.host.parentElement}
|
|
941
|
+
const fitted=style.maxHeight;style.maxHeight=this.fitInline;const resolved=getComputedStyle(this.host).maxHeight;this.fitMax=resolved==="none"||/^(initial|inherit|unset|revert(-layer)?)$/.test(this.fitInline) ? resolved : this.fitInline || resolved;
|
|
942
|
+
style.maxHeight=fitted;const empty=!this.toolbar.hidden&&this.host.classList.contains("cx-grid-awaiting");const height=Math.ceil(Math.max(empty?0:this.host.getBoundingClientRect().height-grid.getBoundingClientRect().height,this.minimumGridHeight(false))+ content),bound=this.fitMax;const value=this.rowCount()||empty?bound==="none"?height+"px":"min("+height+"px, "+bound+")":this.fitInline;if(empty||this.fitEmpty)style.setProperty("--cx-min-h",empty?value:this.minimumGridHeight()+ "px");this.fitEmpty=empty;if(style.maxHeight!==value)style.maxHeight=value;this.fitStyle=style.cssText};function gridPriority(value){return["essential","normal","optional"].includes(value)||Number.isInteger(value)&&value>=0&&value<=MAX_PROTOCOL_INTEGER}
|
|
935
943
|
function gridRank(column){const value=column.priority;return typeof value==="number"?value:value==="optional"?10000:value==="essential"||value===undefined&&column.identity?0:5000}
|
|
936
944
|
function gridLevel(column){const rank=gridRank(column);return rank<2?0:rank<10000?1:2}
|
|
937
945
|
function gridOptions(column){return column.presenter||{}}
|
|
@@ -992,7 +1000,7 @@ return result};function validateGridHighlights(view){if(view.highlightRules===un
|
|
|
992
1000
|
rule.target!==undefined&&!["row","cell"].includes(rule.target)||rule.tone===undefined&&rule.className===undefined)
|
|
993
1001
|
throw new Error("CanopyX: invalid highlight rule.");const{column,operator,values}=rule;if(!Object.hasOwn(GRID_FILTER_LABELS,operator))throw new Error("CanopyX: highlight rules use built-in operators.");gridPredicate({column,operator,values},columns,budget);gridDecoration(rule.tone,rule.className)}}
|
|
994
1002
|
DataGrid.prototype.paintGridHighlights=function(element,row){if(!this.view.highlightRules?.length&&!row.h.tone&&!row.h.className&&!element._cxHighlight)return;const matches=new Map();if(!row.status)for(const rule of this.view.highlightRules||[]){const key=rule.target==="cell"?rule.column:null;if(!matches.has(key)&&gridMatches(row.h,rule,this.columns.find(column=>column.id===rule.column)))matches.set(key,rule)}
|
|
995
|
-
const mark=matches.get(null),name=row.status?null:mark?.tone??row.h.tone;const tone=toneOf(name),classes=row.status?"":[row.h.className,mark?.className].filter(Boolean).join(" ");setClass(element,(element._cls??element.className)+(classes?" "+classes:"")+ tone.cls);toneColors(element,tone);setAttr(element,"data-cx-tone",name||null);if(name)element.style.setProperty("--cx-row-tone",toneVariable(name,false,"var(--hfx-color-text,light-dark(#16181c,#f2f3f5))"));else element.style.removeProperty("--cx-row-tone");element._cxHighlight=!!(name||classes);for(const[id,rule]of matches)if(id!==null){const index=this.cols.findIndex(column=>column.id===id),slot=element._cells[index];if(!slot)continue;const base=rule.tone?slot.cell.className.replace(/(?:^|\s)cx-tone-[a-z0-9-]+|(?:^|\s)cx-toned/g, "") : slot.cell.className;
|
|
1003
|
+
const mark=matches.get(null),name=row.status?null:mark?.tone??row.h.tone;const tone=toneOf(name),classes=row.status?"":[row.h.className,mark?.className].filter(Boolean).join(" ");setClass(element,(element._cls??element.className)+(classes?" "+classes:"")+ tone.cls);toneColors(element,tone);setAttr(element,"data-cx-tone",name||null);if(name)element.style.setProperty("--cx-row-tone",toneVariable(name,false,"var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)))"));else element.style.removeProperty("--cx-row-tone");element._cxHighlight=!!(name||classes);for(const[id,rule]of matches)if(id!==null){const index=this.cols.findIndex(column=>column.id===id),slot=element._cells[index];if(!slot)continue;const base=rule.tone?slot.cell.className.replace(/(?:^|\s)cx-tone-[a-z0-9-]+|(?:^|\s)cx-toned/g, "") : slot.cell.className;
|
|
996
1004
|
slot.cell.className=base +(rule.className?" "+rule.className:"")+(rule.tone?toneOf(rule.tone).cls:"");if(rule.tone)toneColors(slot.cell,toneOf(rule.tone));slot.highlighted=true}};const VALUE_PAINT=DataGrid.prototype.paintSlot;DataGrid.prototype.paintSlot=function(slot,row,column,index,wrapper){VALUE_PAINT.call(this,slot,row,column,index,wrapper);if(!column.render){const cell=row.cells[column.id],rule=columnNumericTone(column,cellValue(cell)),tone=columnValueTone(column,cell);if(tone){applyTone(slot.cell,slot.base,toneOf(tone));slot.cls=slot.cell.className}
|
|
997
1005
|
if(rule){slot.cell.title=rule.label;slot.title=rule.label}
|
|
998
1006
|
setAttr(slot.cell,"aria-description",rule?.label||null)}};DEFAULT_LABELS=Object.freeze(Object.assign({},DEFAULT_LABELS,{gridExpandCell:"{column}: show complete text",gridCloseCell:"Close complete text"}));const GRID_PRESENTERS_BUILD=DataGrid.prototype.build;function gridPresenter(options,column,columns){const kinds=["link","icon","progress","boolean","list","longText","enum","state","change","statusStrip","sparklineBars","sparklineLine","identifier","tags","missing","structured"];const invalid=()=>{throw new Error("CanopyX: invalid grid presenter or raw column binding.")};if(!options||typeof options!=="object"||Array.isArray(options)||!kinds.includes(options.kind))invalid();if((options.kind==="progress"||options.kind==="change"&&!options.beforeAfter)&&column.kind!=="number"||
|
|
@@ -1021,7 +1029,8 @@ row.loadingAt??=performance.now();const wait=150-(performance.now()-row.loadingA
|
|
|
1021
1029
|
const cell=element._cells[0].cell;element._cells[0].text.data="";if(element._skeleton?.isConnected)return;const skeleton=element._skeleton=h("span","cx-skel");skeleton.setAttribute("aria-hidden","true");for(const column of this.cols){const span=h("span"),bar=h("i");span.style.width=column.renderWidth+"px";span.appendChild(bar);skeleton.appendChild(span)}cell.appendChild(skeleton)},buildGridStatus(){if(!this.view.statusBar)return;this.statusBar=h("div","cx-grid-status");this.statusCount=h("span");this.statusAggregates=h("span","agg");this.statusBar.setAttribute("role","status");this.statusBar.append(this.statusCount,this.statusAggregates);this.host.appendChild(this.statusBar)},async syncGridStatus(){if(!this.statusBar)return;const count=this.querySelection?this.querySelection.matched==null?null:Math.max(0,this.querySelection.matched-this.selectionExcluded.size):this.selected.size;const number=numberFormat(this.lang);gridCountLabel(this.statusCount,this.labels.gridStatusCount,{count:this.snapshot?.matched==null?"—":number.format(this.snapshot.matched),noun:this.noun,selected:count==null?"—":number.format(count)});const columns=this.columns.filter(column=>column.aggregatable&&column.exportable!==false),key=JSON.stringify([this.queryEpoch,this.snapshot?.revision,count,[...this.selected],this.querySelection?.query,[...(this.selectionExcluded||[])],columns.map(column=>column.id)]);if(key===this.statusAggregateKey)return;this.statusAggregateKey=key;this.statusAggregateController?.abort();this.statusAggregates.replaceChildren();if(!columns.length||count===0||!this.acceptedQuery)return;try{await loadGridFilterEditor();if(!this.destroyed&&this.statusAggregateKey===key)await this.calculateGridAggregates(columns)}
|
|
1022
1030
|
catch(error){if(!this.destroyed&&this.statusAggregateKey===key)setText(this.statusAggregates,this.labels.gridNoData)}}});Object.assign(DataGrid.prototype,{setFocus(row,focus){this.pendingNavigation=null;if(!row||this.indexOf(row)<0||this.destroyed)return;if(focus)this.focusOrigin=null;this.focused=row;this.revealGridRow(row,row._ri);if(this.render()){this.revealGridRow(row,row._ri);this.render()}
|
|
1023
1031
|
if(focus){const element=this.rendered.get(row);if(this.hasGridSize()&&element)element.focus({preventScroll:true});else{this.focusOrigin=document.activeElement;this.scheduleRender()}}},onClick(event){const element=event.target.closest(".cx-row"),row=element&&element._w,link=event.target.closest("a.p-link");if(row&&link&&!this.emit("link",{id:row.key,row:gridFreeze(JSON.parse(JSON.stringify(row.h))),href:link.href,column:this.visibleColumns()[this.rowCells(element).findIndex(cell=>cell.contains(link))]?.id}))event.preventDefault();if(!row||event.defaultPrevented||event.target.closest("a,button,input,select,textarea,[contenteditable]"))return;this.setFocus(row,true);if(row.status){if(row.status==="error")this.retry().catch(()=>{});return}
|
|
1024
|
-
|
|
1032
|
+
if(this.selectOnClick&&this.view.selection!=="none"){if(event.detail<2)this.selectClickedRow(row,event);return}
|
|
1033
|
+
const action=event.detail<2&&this.clickAction(element);if(action)this.activateRow(row,false,action!==true&&action,event)},selectClickedRow(row,event){if(this.pendingQuery)return;const additive=this.multi&&(event.ctrlKey||event.metaKey);if(this.multi&&event.shiftKey&&this.selectionAnchor!=null){this.selectRowRange(this.selectionAnchor,row._ri,{additive}).catch(error=>{if(error.name!=="AbortError")this.emit("error",{error})})}else{this.selectionController?.abort();const next=additive?new Set(this.selected):new Set();if(next.has(row.key))next.delete(row.key);else next.add(row.key);this.setSelection([...next]);this.selectionAnchor=row._ri}},clickAction(element){return this.view.rowAction==="link"&&element.querySelector("a[href]")||this.phone||this.view.rowAction==="details"},activateRow(row,keyboard,link,event={}){if(this.emit("rowActivate",{id:row.key,row:gridFreeze(JSON.parse(JSON.stringify(row.h))),keyboard}))link?
|
|
1025
1034
|
link.dispatchEvent(new MouseEvent("click",{bubbles:true,cancelable:true,ctrlKey:event.ctrlKey,metaKey:event.metaKey,shiftKey:event.shiftKey})):
|
|
1026
1035
|
Promise.resolve().then(()=>this.openDetails(row.key)).catch(error=>this.emit("error",{error}))},onKey(event){const element=event.target.closest(".cx-row"),row=element&&element._w;if(!row||event.defaultPrevented||event.isComposing||event.altKey)return;const cells=this.rowCells(element),navigation=this.pendingNavigation;const pendingPage=navigation&&navigation.focus&&navigation.epoch===this.queryEpoch&&this.pendingQuery&&
|
|
1027
1036
|
this.pendingPageNavigation&&this.pendingPageNavigation.epoch===this.queryEpoch&&this.focused===row;let column=cells.findIndex(cell=>cell.contains(event.target));if(pendingPage||row.status&&navigation&&navigation.epoch===this.queryEpoch&&navigation.index===row._ri&&navigation.focus)
|
|
@@ -1064,13 +1073,13 @@ const parsed=typeof value==="string"&&/^\d{4}-\d\d-\d\dT\d\d:\d\d/.test(value) ?
|
|
|
1064
1073
|
if(parsed&&Number.isFinite(parsed.getTime()))return calInstantText(parsed,field,allDay);throw new Error("CanopyX: a calendar event's "+field+" is a Date or an ISO date or date and time.")}
|
|
1065
1074
|
function createCalendar(host,options={}){const preset=CAL_PRESETS[options.preset??"basic"];if(!preset)throw new Error("CanopyX: calendar presets are basic, standard and scheduler.");const events=options.events??[];if(!Array.isArray(events)||events.length>100000)throw new Error("CanopyX: calendar events are an array of at most 100,000 events.");const hooks={},own={};for(const[name,value]of Object.entries(options.calendar||{}))(typeof value==="function"?hooks:own)[name]=value;const pick=name=>own[name]!==undefined?own[name]:options[name]!==undefined?options[name]:preset[name];const editable=!!pick("editable"),create=pick("create"),drop=!!pick("drop"),used=new Set(),ids=new Set();const rows=events.map((event,index)=>{if(!event||typeof event!=="object"||typeof event.title!=="string")throw new Error("CanopyX: calendar event " +(index+1)+ " needs a title.");const id=event.id===undefined?"e" +(index+1):String(event.id);if(ids.has(id))throw new Error("CanopyX: calendar event ids are unique; '"+id+"' repeats.");ids.add(id);const allDay=event.allDay??(typeof event.start==="string"&&event.start.length===10);const cells={title:event.title,start:calInstantText(event.start,"start",allDay)};if(event.end!=null)cells.end=calInstantText(event.end,"end",allDay);if(allDay){cells.allDay=true;used.add("allDay")}
|
|
1066
1075
|
for(const field of CAL_FIELDS)if(field!=="allDay"&&event[field]!=null){cells[field]=field==="resourceIds"?JSON.stringify(event[field]):field==="recurrenceId"?calInstantText(event[field],field,false):String(event[field]);used.add(field)}
|
|
1067
|
-
return{id,cells}});if(options.resources)used.add("resource");if(used.has("recurrence"))for(const field of["series","recurrenceId","exceptions"])used.add(field);if(pick("sources"))used.add("source");if(drop||create&&!(typeof create==="object"&&create.allDay===false))used.add("allDay");const writable=editable||!!create||drop;const columns=[{id:"title",title:"Title",kind:"text",rowHeader:true,sortable:true,editable:writable},{id:"start",title:"Start",kind:"datetime",sortable:true,editable:writable},{id:"end",title:"End",kind:"datetime",sortable:true,editable:writable},...CAL_FIELDS.filter(field=>used.has(field)).map(field=>({id:field,title:CAL_TITLES[field],kind:field==="recurrenceId"?"datetime":"text",hidden:field!=="description",editable:writable&&(field==="resource"||field==="resourceIds"||field==="series"||field==="recurrenceId"||field==="allDay"||field==="recurrence"||field==="exceptions")}))];let toolbar=pick("toolbar");if(options.export===true&&toolbar!==true)toolbar=toolbar===false?["export"]:toolbar.includes("export")?toolbar:[...toolbar,"export"];if(options.export===false&&toolbar!==false)toolbar=(toolbar===true?["search","filters","columns","views","more"]:toolbar.filter(item=>item!=="export"));if(Array.isArray(toolbar)&&!toolbar.length)toolbar=false;const calendar={start:"start",end:"end",title:"title",views:pick("views"),toolbar,details:options.drawer===true?"drawer":options.drawer===false?"popover":pick("details")};for(const field of CAL_FIELDS)if(used.has(field))calendar[field]=field;for(const name of["view","date","timeZone","firstDay","sources"])if(options[name]!==undefined)calendar[name]=options[name];if(editable)calendar.editable=typeof pick("editable")==="object"?pick("editable"):true;if(create)calendar.create=create;if(drop)calendar.drop=true;if(pick("print"))calendar.print=true;const ownViews=own.views!==undefined||options.views!==undefined,addTimeline=()=>{if(!ownViews&&!calendar.views.includes("timeline"))calendar.views=[...calendar.views,"timeline"]};if(options.resources){const list=options.resources,tree=Array.isArray(list)?{protocol:PROTOCOL,type:"view",id:"resources",label:"Resources",rowHeight:34,pageSize:200,selection:"single",columns:[{id:"name",title:"Resource",kind:"text",width:200}],source:{kind:"inline"},roots:calResourceRoots(list)}:list;calendar.resources={view:tree};if(options.timeline!==false&&(options.timeline||options.preset==="scheduler"))addTimeline();if(options.preset==="scheduler")calendar.capacity={thresholds:[{at:3,tone:"warning"},{at:5,tone:"danger"}]}}else if(options.timeline)addTimeline();for(const[name,value]of Object.entries(own))if(!["toolbar","editable","create","drop"].includes(name))calendar[name]=value;if(calendar.toolbar===true)delete calendar.toolbar;if(calendar.details==="drawer")delete calendar.details;const search=calendar.toolbar===undefined||calendar.toolbar!==false&&calendar.toolbar.includes("search");const view={protocol:PROTOCOL,type:"grid",id:options.id??"calendar",label:options.label??"Calendar",rowHeight:34,pageSize:200,selection:"single",search,columns,source:{kind:"inline"},rows,calendar};if(options.live)view.live=options.live===true?{}:options.live;if(options.facets)view.facets=Array.isArray(options.facets)?{columns:options.facets}:options.facets;const hostOptions=Object.fromEntries(Object.entries(options).filter(([name])=>!CAL_OWN.has(name)));if(options.links)hostOptions.linkEvents=true;if(Object.keys(hooks).length)hostOptions.calendar=hooks;return createDataGrid(host,{...hostOptions,view})}
|
|
1076
|
+
return{id,cells}});if(options.resources)used.add("resource");if(used.has("recurrence"))for(const field of["series","recurrenceId","exceptions"])used.add(field);if(pick("sources"))used.add("source");if(drop||create&&!(typeof create==="object"&&create.allDay===false))used.add("allDay");const writable=editable||!!create||drop;const columns=[{id:"title",title:"Title",kind:"text",rowHeader:true,sortable:true,editable:writable},{id:"start",title:"Start",kind:"datetime",sortable:true,editable:writable},{id:"end",title:"End",kind:"datetime",sortable:true,editable:writable},...CAL_FIELDS.filter(field=>used.has(field)).map(field=>({id:field,title:CAL_TITLES[field],kind:field==="recurrenceId"?"datetime":"text",hidden:field!=="description",editable:writable&&(field==="resource"||field==="resourceIds"||field==="series"||field==="recurrenceId"||field==="allDay"||field==="recurrence"||field==="exceptions")}))];let toolbar=pick("toolbar");if(options.export===true&&toolbar!==true)toolbar=toolbar===false?["export"]:toolbar.includes("export")?toolbar:[...toolbar,"export"];if(options.export===false&&toolbar!==false)toolbar=(toolbar===true?["search","filters","columns","views","more"]:toolbar.filter(item=>item!=="export"));if(Array.isArray(toolbar)&&!toolbar.length)toolbar=false;const calendar={start:"start",end:"end",title:"title",views:pick("views"),toolbar,details:options.drawer===true?"drawer":options.drawer===false?"popover":pick("details")};for(const field of CAL_FIELDS)if(used.has(field))calendar[field]=field;for(const name of["view","date","timeZone","firstDay","sources"])if(options[name]!==undefined)calendar[name]=options[name];if(editable)calendar.editable=typeof pick("editable")==="object"?pick("editable"):true;if(create)calendar.create=create;if(drop)calendar.drop=true;if(pick("print"))calendar.print=true;const ownViews=own.views!==undefined||options.views!==undefined,addTimeline=()=>{if(!ownViews&&!calendar.views.includes("timeline"))calendar.views=[...calendar.views,"timeline"]};const opensOnTimeline=pick("view")==="timeline";if(opensOnTimeline&&options.timeline===false)throw new Error("CanopyX: a calendar that opens on the timeline cannot set timeline: false.");if(options.resources){const list=options.resources,tree=Array.isArray(list)?{protocol:PROTOCOL,type:"view",id:"resources",label:"Resources",rowHeight:34,pageSize:200,selection:"single",columns:[{id:"name",title:"Resource",kind:"text",width:200}],source:{kind:"inline"},roots:calResourceRoots(list)}:list;calendar.resources={view:tree};if(options.timeline!==false&&(options.timeline||opensOnTimeline||options.preset==="scheduler"))addTimeline();if(options.preset==="scheduler")calendar.capacity={thresholds:[{at:3,tone:"warning"},{at:5,tone:"danger"}]}}else if(options.timeline||opensOnTimeline)addTimeline();for(const[name,value]of Object.entries(own))if(!["toolbar","editable","create","drop"].includes(name))calendar[name]=value;if(calendar.toolbar===true)delete calendar.toolbar;if(calendar.details==="drawer")delete calendar.details;const search=calendar.toolbar===undefined||calendar.toolbar!==false&&calendar.toolbar.includes("search");const view={protocol:PROTOCOL,type:"grid",id:options.id??"calendar",label:options.label??"Calendar",rowHeight:34,pageSize:200,selection:"single",search,columns,source:{kind:"inline"},rows,calendar};if(options.live)view.live=options.live===true?{}:options.live;if(options.facets)view.facets=Array.isArray(options.facets)?{columns:options.facets}:options.facets;const hostOptions=Object.fromEntries(Object.entries(options).filter(([name])=>!CAL_OWN.has(name)));if(options.links)hostOptions.linkEvents=true;if(Object.keys(hooks).length)hostOptions.calendar=hooks;return createDataGrid(host,{...hostOptions,view})}
|
|
1068
1077
|
function calResourceRoots(list){const nodes=new Map(list.map(item=>[String(item.id),{id:String(item.id),label:String(item.label??item.id),cells:{name:String(item.label??item.id)},expanded:true}])),roots=[];for(const item of list){const node=nodes.get(String(item.id)),parent=item.parent==null?null:nodes.get(String(item.parent));if(parent)(parent.children||=[]).push(node);else roots.push(node)}
|
|
1069
1078
|
return roots}
|
|
1070
1079
|
const GRID_EDITING=definePart(DataGrid,"editing","editing",()=>({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}));const GRID_EDIT_INIT=DataGrid.prototype.initializeState;const GRID_EDIT_API=["beginEdit","endEdit","setCellValue","validate","commitRow","commitChanges","insertRow","isEditing","hasChanges","undo","redo","canUndo","canRedo","cancelEdit","revertChanges","getChanges","setReadOnly"];GRID_EDIT_API.forEach((name,index)=>{DataGrid.prototype[name]=index<7?function(...args){return this.loadEditing().then(()=>this[name](...args))}:index<15?()=>false:()=>[]});DataGrid.prototype.setReadOnly=function(value){this.editReadOnly=!!value};DataGrid.prototype.loadEditing=function(){return this.editLoad||=loadPart(GRID_EDITING).then(()=>this.startEditing()).catch(error=>{this.editLoad=null;this.emit("error",{error});throw error})};DataGrid.prototype.initializeState=function(){const ready=GRID_EDIT_INIT.call(this);return this.columns.some(column=>column.editable)?Promise.all([ready,this.loadEditing().catch(()=>{})]).then(([result])=>result):ready};DEFAULT_LABELS=Object.freeze(Object.assign({},DEFAULT_LABELS,{gridFacetPanel:"Refine",gridFacetPanelHide:"Hide the filter panel",gridFacetPanelShow:"Show the filter panel",gridFacetShowMore:"Show {count} more",gridFacetShowFewer:"Show fewer",gridFacetEmptyValue:"(Empty)",gridFacetFrom:"From",gridFacetTo:"To",gridFacetHistogram:"Distribution of {column}",gridFacetBin:"{from} to {to}: {count} rows",gridFacetNoChart:"Too many values to chart",gridFacetClear:"Clear {column}",gridFacetCustom:"Another condition filters this column.",gridFacetResult:"{count} matching rows",gridFacetSelected:"{count} selected",gridFacetValueCount:"{value}, {count} rows",gridFacetCollapse:"Collapse {column}",gridFacetExpand:"Expand {column}",gridFacetInvalid:"Enter a valid value.",gridFacetReversed:"From must not be after To."}));const GRID_FACETS=definePart(DataGrid,"facets","facet panel",()=>({DataGrid,h,setText,fill,gridButton,gridIcon,gridQueryStart,gridQueryRows,gridColumnProjection,gridScalar,gridOrder,gridKeyCompare,gridFacetKey,cellText,foldText,numberFormat,gridCellRenderer,gridFreeze,overlayTheme,watchOverlayTheme,GRID_BUCKETS,gridBucketDefinition}));Object.assign(DataGrid.prototype,{loadFacets(){return this.facetLoad||=Promise.resolve().then(async()=>{if((this.opts.facets?.columns||this.view.facets?.columns)?.some(facet=>facet?.bucket))await loadPart(BUCKETS_PART);await loadPart(GRID_FACETS);if(!this.destroyed)this.startFacets()}).catch(error=>{this.facetLoad=null;throw error})},setFacetPanelOpen(open){return this.loadFacets().then(()=>this.setFacetPanelOpen(open))},getFacetPanel(){return gridFreeze({open:this.facetOpen??null,columns:(this.facetColumns||[]).map(facet=>facet.column)})}});const FACET_STATE={get:DataGrid.prototype.getState,read:DataGrid.prototype.readGridState,apply:DataGrid.prototype.applyStatePresentation,init:DataGrid.prototype.initializeState};Object.assign(DataGrid.prototype,{getState(){const state=FACET_STATE.get.call(this);if((this.view.facets||this.opts.facets)&&this.facetOpen!==undefined)state.facets={open:this.facetOpen};return state},readGridState(input){const state=FACET_STATE.read.call(this,input);if(input.facets!==undefined){const facets=input.facets;if(!facets||typeof facets!=="object"||Array.isArray(facets)||Object.keys(facets).some(key=>key!=="open")||typeof facets.open!=="boolean")
|
|
1071
1080
|
throw new Error("CanopyX: invalid saved facet panel state.");if(this.view.facets||this.opts.facets)state.facets={open:facets.open}}
|
|
1072
1081
|
return state},applyStatePresentation(state){const applied=FACET_STATE.apply.call(this,state);if(state.facets&&state.facets.open!==this.facetOpen&&!this.destroyed){if(this.facetPanel)this.setFacetPanelOpen(state.facets.open).catch(error=>this.emit("error",{error}));else this.facetOpen=state.facets.open}
|
|
1073
|
-
return applied},initializeState(){if(this.initialState?.facets)this.facetOpen=this.initialState.facets.open;const ready=FACET_STATE.init.call(this);return this.view.facets||this.opts.facets?Promise.all([ready,this.loadFacets().catch(error=>this.emit("error",{error}))]).then(([result])=>result):ready}});const GRID_FORMAT=definePart(DataGrid,"formatting","conditional formatting",()=>({DataGrid,h,setText,setClass,fill,gridFreeze,gridDateInputMoment,cellValue,cellText,foldText,toneOf,toneVariable,numberFormat,gridButton,gridVariant,gridOption,gridInputLabel,gridIcon,gridDecorateButton,GRID_REPORTING,loadPart,definePart,announceMenu,boundedPattern,wildcardMatch,svgIcon,overlayTheme}));Object.assign(DataGrid.prototype,{loadFormatting(){return this.formatLoad||=loadPart(GRID_FORMAT).then(()=>this.startFormatting(),error=>{this.formatLoad=null;throw error})},setFormatRules(rules){return this.loadFormatting().then(()=>this.setFormatRules(rules))},validateFormatRules(rules){return this.loadFormatting().then(()=>this.validateFormatRules(rules))},openFormatRules(){return this.loadFormatting().then(()=>this.openFormatRules())},getFormatRules(){return gridFreeze(JSON.parse(JSON.stringify(this.formatRules||this.view.formatRules||[])))}});DEFAULT_LABELS=Object.freeze(Object.assign({},DEFAULT_LABELS,{gridLiveOrderChanged:"Order changed",gridLiveResort:"Re-sort",gridLiveNewData:"New data",gridLiveRefresh:"Refresh",gridLiveOrderHint:"Rows keep their places while data changes. Re-sort to move them where the sort puts them.",gridLiveChanged:"Rows changed: {added} added, {updated} updated, {removed} removed",gridLiveSorted:"Rows moved to their sorted places.",gridLiveRecordRemoved:"This record was removed."}));const GRID_LIVE=definePart(DataGrid,"live","live data",()=>({DataGrid,h,setText,fill,gridButton,gridIcon,gridQuery,gridResultShape,gridQueryRows,gridCompare,gridOrder,gridIdOrder,validateGridRows,validateGridPage,validateGridCursorPage,gridFreeze,requireIdentifier,checkDocument,cellValue,PROTOCOL,GRID_REPORTING,GRID_CALCULATIONS,VIEW_MODES,inlineGridSource}));const GRID_LIVE_API=["applyTransaction","addRows","updateRows","removeRows","setRows","flushTransactions","refreshRows","resort","poll"];for(const name of GRID_LIVE_API)DataGrid.prototype[name]=function(...args){return this.loadLive().then(()=>this[name](...args))};Object.assign(DataGrid.prototype,{loadLive(){if(this.view.rowIdentity==="ordinal")return Promise.reject(new Error("CanopyX: ordinal row identity is snapshot-local; keyed live updates require stable row keys."));return this.liveLoad||=loadPart(GRID_LIVE).then(()=>this.destroyed||this.startLive()).catch(error=>{this.liveLoad=null;throw error})},getLiveState(){return this.liveStatus?this.liveStatus():gridFreeze({orderChanged:false,newData:false,pending:0,polling:false,revision:this.snapshot?.revision??null})}});const GRID_LIVE_INIT=DataGrid.prototype.initializeState;DataGrid.prototype.initializeState=function(){const ready=GRID_LIVE_INIT.call(this);return this.view.live&&this.opts.live!==false||this.opts.live?Promise.all([ready,this.loadLive().catch(error=>this.emit("error",{error}))]).then(([result])=>result):ready};const GRID_OPTIONS_PART=definePart(DataGrid,"grid-options","grid footer and query extensions",()=>({DataGrid,GRID_OPTIONS,GRID_OPTION_GRIDS,h,setText,fill,gridQuery,gridQueryRows,gridCompare,gridKeyCompare,gridSortScalar,gridMatches,gridMatchesGroup,gridResultShape,GRID_REPORTING,gridScalar,gridFreeze,gridOperationActive,numberText,isCellObject,cellValue,requireIdentifier,validStructuralCount,PROTOCOL}));const OPTIONS_REQUEST=DataGrid.prototype.requestPage;DataGrid.prototype.requestPage=async function(query,signal){if(!gridOptionsUsed(this.view,this.plugins))return OPTIONS_REQUEST.call(this,query,signal);await loadPart(GRID_OPTIONS_PART);gridOperationActive(this,signal);GRID_OPTIONS.attach(this);const page=await OPTIONS_REQUEST.call(this,query,signal);return GRID_OPTIONS.page(this,query,signal,page)};const GRID_PAGER_IMPL={},GRID_PAGER=definePart(DataGrid,"pager","pager controls",()=>({DataGrid,GRID_PAGER_IMPL,h,setText,fill,gridButton,gridOption,numberFormat,gridCountLabel}));const GRID_PAGER_INIT=DataGrid.prototype.initializeState;DataGrid.prototype.initializeState=function(){const ready=GRID_PAGER_INIT.call(this);return!this.pager||!this.view.pager||GRID_PAGER_IMPL.installed?ready:Promise.all([ready,loadPart(GRID_PAGER).then(()=>this.destroyed||this.buildPager())
|
|
1082
|
+
return applied},initializeState(){if(this.initialState?.facets)this.facetOpen=this.initialState.facets.open;const ready=FACET_STATE.init.call(this);return this.view.facets||this.opts.facets?Promise.all([ready,this.loadFacets().catch(error=>this.emit("error",{error}))]).then(([result])=>result):ready}});const GRID_FORMAT=definePart(DataGrid,"formatting","conditional formatting",()=>({DataGrid,h,setText,setClass,fill,gridFreeze,gridDateInputMoment,cellValue,cellText,foldText,toneOf,toneVariable,numberFormat,gridButton,gridVariant,gridOption,gridInputLabel,gridIcon,gridDecorateButton,GRID_REPORTING,loadPart,definePart,announceMenu,boundedPattern,wildcardMatch,svgIcon,overlayTheme}));Object.assign(DataGrid.prototype,{loadFormatting(){return this.formatLoad||=loadPart(GRID_FORMAT).then(()=>this.startFormatting(),error=>{this.formatLoad=null;throw error})},setFormatRules(rules){return this.loadFormatting().then(()=>this.setFormatRules(rules))},validateFormatRules(rules){return this.loadFormatting().then(()=>this.validateFormatRules(rules))},openFormatRules(){return this.loadFormatting().then(()=>this.openFormatRules())},getFormatRules(){return gridFreeze(JSON.parse(JSON.stringify(this.formatRules||this.view.formatRules||[])))}});DEFAULT_LABELS=Object.freeze(Object.assign({},DEFAULT_LABELS,{gridLiveOrderChanged:"Order changed",gridLiveResort:"Re-sort",gridLiveNewData:"New data",gridLiveRefresh:"Refresh",gridLiveOrderHint:"Rows keep their places while data changes. Re-sort to move them where the sort puts them.",gridLiveChanged:"Rows changed: {added} added, {updated} updated, {removed} removed",gridLiveSorted:"Rows moved to their sorted places.",gridLiveRecordRemoved:"This record was removed."}));const GRID_LIVE=definePart(DataGrid,"live","live data",()=>({DataGrid,h,setText,fill,gridButton,gridIcon,gridQuery,gridResultShape,gridQueryRows,gridCompare,gridOrder,gridIdOrder,validateGridRows,validateGridPage,validateGridCursorPage,gridFreeze,requireIdentifier,checkDocument,cellValue,PROTOCOL,GRID_REPORTING,GRID_CALCULATIONS,VIEW_MODES,inlineGridSource}));const GRID_LIVE_API=["applyTransaction","addRows","updateRows","removeRows","setRows","flushTransactions","refreshRows","resort","poll"];for(const name of GRID_LIVE_API)DataGrid.prototype[name]=function(...args){return this.loadLive().then(()=>this[name](...args))};Object.assign(DataGrid.prototype,{loadLive(){if(this.view.rowIdentity==="ordinal")return Promise.reject(new Error("CanopyX: ordinal row identity is snapshot-local; keyed live updates require stable row keys."));return this.liveLoad||=loadPart(GRID_LIVE).then(()=>this.destroyed||this.startLive()).catch(error=>{this.liveLoad=null;throw error})},getLiveState(){return this.liveStatus?this.liveStatus():gridFreeze({orderChanged:false,newData:false,pending:0,polling:false,revision:this.snapshot?.revision??null})}});const GRID_LIVE_INIT=DataGrid.prototype.initializeState;DataGrid.prototype.initializeState=function(){const ready=GRID_LIVE_INIT.call(this);return this.view.live&&this.opts.live!==false||this.opts.live?Promise.all([ready,this.loadLive().catch(error=>this.emit("error",{error}))]).then(([result])=>result):ready};const GRID_OPTIONS_PART=definePart(DataGrid,"grid-options","grid footer and query extensions",()=>({DataGrid,validateGridPage,GRID_OPTIONS,GRID_OPTION_GRIDS,h,setText,fill,gridQuery,gridQueryRows,gridCompare,gridKeyCompare,gridSortScalar,gridMatches,gridMatchesGroup,gridResultShape,GRID_REPORTING,gridScalar,gridFreeze,gridOperationActive,numberText,isCellObject,cellValue,requireIdentifier,validStructuralCount,PROTOCOL}));const OPTIONS_REQUEST=DataGrid.prototype.requestPage;DataGrid.prototype.requestPage=async function(query,signal){if(!gridOptionsUsed(this.view,this.plugins))return OPTIONS_REQUEST.call(this,query,signal);await loadPart(GRID_OPTIONS_PART);gridOperationActive(this,signal);GRID_OPTIONS.attach(this);const page=await OPTIONS_REQUEST.call(this,query,signal);return GRID_OPTIONS.page(this,query,signal,page)};DataGrid.prototype.selectRowRange=async function(start,end,options={}){this.selectionController?.abort();const controller=this.selectionController=new AbortController(),epoch=this.queryEpoch;try{await loadPart(GRID_OPTIONS_PART);if(controller.signal.aborted||epoch!==this.queryEpoch)throw new DOMException("Selection was superseded.","AbortError");return await this.readSelectionRange(start,end,options,controller)}finally{controller.abort();if(this.selectionController===controller)this.selectionController=null}};const GRID_PAGER_IMPL={},GRID_PAGER=definePart(DataGrid,"pager","pager controls",()=>({DataGrid,GRID_PAGER_IMPL,h,setText,fill,gridButton,gridOption,numberFormat,gridCountLabel}));const GRID_PAGER_INIT=DataGrid.prototype.initializeState;DataGrid.prototype.initializeState=function(){const ready=GRID_PAGER_INIT.call(this);return!this.pager||!this.view.pager||GRID_PAGER_IMPL.installed?ready:Promise.all([ready,loadPart(GRID_PAGER).then(()=>this.destroyed||this.buildPager())
|
|
1074
1083
|
.catch(error=>{this.pager.hidden=this.opts.toolbar===false;this.emit("error",{error})})]).then(([result])=>result)};const GRID_PATH=definePart(DataGrid,"path","path view",()=>({DataGrid,h,setText,fill,cellValue,cellText,badgeElement,applyTone,toneOf,PROTOCOL}));const GRID_PATH_INIT=DataGrid.prototype.initializeState;DataGrid.prototype.initializeState=function(){const start=()=>this.destroyed?undefined:GRID_PATH_INIT.call(this);return this.view.path?loadPart(GRID_PATH).then(()=>{if(!this.destroyed)this.validatePathSource()}).then(start).then(async result=>{if(!this.destroyed)await this.startPath();return result}):start()};const GRID_PLAN=definePart(DataGrid,"plan","plan view",()=>({DataGrid,h,setText,fill,cellValue,cellText,gridFreeze}));const GRID_PLAN_INIT=DataGrid.prototype.initializeState;DataGrid.prototype.initializeState=function(){const start=()=>GRID_PLAN_INIT.call(this);return this.view.plan?loadPart(GRID_PLAN).then(async()=>{this.validatePlanDefinition();const result=await start();if(this.view.rowData&&!this.opts.source){await this.source.decoded;this.validatePlanDefinition(true)}
|
|
1075
1084
|
return result}):start()};const PRESENTERS_INIT=DataGrid.prototype.initializeState;DataGrid.prototype.initializeState=function(){const ready=PRESENTERS_INIT.call(this);return[...this.columns,...(this.view.record?.fields||[])].some(column=>column.presenter||column.wrap)?Promise.all([ready,this.loadPresenters()]).then(([result])=>result):ready};DataGrid.prototype.parts["record-panel"]=RECORD_PART;RECORD_IMPL.grid={DataGrid,gridCellRenderer,createDataGrid,gridFreeze,gridQuery,gridResultShape,validatePresenter:gridPresenter};DataGrid.prototype.openRecord=TreeGrid.prototype.openRecord;DataGrid.prototype.loadRecordPanel=function(){return this.recordLoad||=loadRecordPanel().then(()=>{this.version++;this.scheduleRender()},error=>this.emit("error",{error}))};DataGrid.prototype.recordNeeded=function(row){return!!this.view.record||this.columns.some(column=>column.presenter?.kind==="structured")||
|
|
1076
1085
|
!!row&&Object.values(row.cells).some(cell=>isCellObject(cell)&&RECORD_STRUCTURE.some(name=>cell[name]!==undefined))};const GRID_RECORD_INIT=DataGrid.prototype.initializeState;DataGrid.prototype.initializeState=function(){const ready=GRID_RECORD_INIT.call(this);return this.columns.some(column=>column.presenter?.kind==="structured")?Promise.all([ready,this.loadRecordPanel()]).then(([result])=>result):ready};const GRID_DATA_IMPL={},GRID_DATA=definePart(DataGrid,"data","row data",()=>({GRID_DATA_IMPL,PROTOCOL,validateGridRows,repairGridCell,inlineGridSource,loadSidecar,gridIdOrder,gridInlineRevision}));function rowDataSource(grid){let inner=null;const source={reset:()=>{inner=null},query:(query,options)=>
|
|
@@ -1087,14 +1096,14 @@ const CHANGES_IMPL={},activeChangeViews=new WeakMap();const CHANGES_PART=defineP
|
|
|
1087
1096
|
errorText=null};const showError=error=>{if(destroyed)return;impl?.destroy();impl=null;failure=error;clearError();notice=h("div","cx-mount-error");notice.setAttribute("role","alert");setText(notice,error&&error.message?error.message:String(error));host.appendChild(notice);errorText=notice.textContent;host.setAttribute("data-cx-error",errorText);host.dispatchEvent(new CustomEvent("canopyx:error",{detail:{error},bubbles:true}))};const mount=view=>{clearError();impl=CHANGES_IMPL[kind](host,{...options,view});failure=null;return impl.ready};const ready=loadPart(CHANGES_PART).then(()=>{if(destroyed)throw cancelled();loaded=true;return mount(currentView)});const api={element:host};Object.defineProperty(api,"view",{enumerable:true,get:()=>impl?impl.document():currentView});for(const method of CHANGE_VIEW_METHODS[kind])api[method]=(...args)=>{const invoke=()=>{if(destroyed)throw cancelled();if(method==="update"){currentView=args[0];try{return impl?impl.update(...args):mount(currentView)}
|
|
1088
1097
|
catch(error){showError(error);throw error}}
|
|
1089
1098
|
if(failure)throw failure;return impl[method](...args)};if(destroyed)throw cancelled();return loaded?invoke():ready.then(invoke)};api.ready=ready.then(()=>{if(destroyed)throw cancelled();return api});api.ready.catch(()=>{});api.destroy=()=>{if(destroyed)return;destroyed=true;impl?.destroy();stopTheme?.();if(activeChangeViews.get(host)===api)activeChangeViews.delete(host);if(host.canopyx===api)delete host.canopyx;host.removeAttribute("data-canopyx-mounted");clearError();for(const className of addedClasses)host.classList.remove(className);if(!hadClass&&!host.classList.length)host.removeAttribute("class")};ready.catch(showError);if(kind==="propagation")bindTimeSlider(api,options,kind,value=>CHANGES_IMPL.validatePropagation(value),showError);Object.freeze(api);activeChangeViews.set(host,api);host.classList.add("cx-host","cx-change-host");host.setAttribute("data-canopyx-mounted","true");host.canopyx=api;stopTheme=watchTheme(host);return api}}
|
|
1090
|
-
const CHANGES_API={createDiff:changeViewFactory("diff","createDiff"),createChangeList:changeViewFactory("changes","createChangeList"),createPropagation:changeViewFactory("propagation","createPropagation")};const CHANGE_VIEW_TYPES={diff:CHANGES_API.createDiff,changes:CHANGES_API.createChangeList,propagation:CHANGES_API.createPropagation};DEFAULT_LABELS=Object.freeze(Object.assign({},DEFAULT_LABELS,{gridCellRangeSelected:"{rows} rows × {columns} columns selected",gridCellRangesSelected:"{ranges} ranges selected, {cells} cells",gridCellRangeCleared:"Cell selection cleared",gridCopyCells:"Copy cells",gridCopyCellsWithHeaders:"Copy cells with headers",gridPasteCells:"Paste",gridSelectAllCells:"Select all cells",gridCellsCopied:"Copied {rows} rows × {columns} columns",gridCellsPasted:"Pasted {count} cells",gridPasteRefused:"{count} cells were not pasted",gridPasteReadOnly:"This cell cannot be changed.",gridPasteType:"“{value}” is not a valid value for {column}.",gridPasteReport:"Paste report",gridPasteCell:"Row {row}, {column}: {reason}",gridFillHandle:"Drag to fill the cells below",gridCellsFilled:"Filled {count} cells",gridCellMenu:"Cell actions",gridClearCellRanges:"Clear cell selection"}));const GRID_PART_CONTEXT=()=>({DataGrid,h,setText,fill,columnWidth,foldText,gridButton,gridIcon,gridDecorateButton,cellText,cellValue,isCellObject,numberFormat,gridFreeze,gridMomentFromParts,requireIdentifier,loadGridFilterEditor,CELL_CONTROLS,reachable,gridExportField,bindContextMenu});const GRID_COLUMN_GROUPS=definePart(DataGrid,"column-groups","column groups",GRID_PART_CONTEXT);const GRID_CELL_RANGE=definePart(DataGrid,"cell-range","cell ranges",GRID_PART_CONTEXT);const GRID_PART_API=[["column-groups","getColumnGroups","setColumnGroupVisible"],["cell-range","getCellRanges","setCellRanges","clearCellRanges","selectAllCells","copyCellRanges","getCellRangeText","pasteCells"]];const gridPartLoader=(part,start)=>function(){return(this.partLoads||={})[start]||=loadPart(part).then(()=>this.destroyed||this["start"+start]()).catch(error=>{this.partLoads[start]=null;throw error})};DataGrid.prototype.loadColumnGroups=gridPartLoader(GRID_COLUMN_GROUPS,"ColumnGroups");DataGrid.prototype.loadCellRanges=gridPartLoader(GRID_CELL_RANGE,"CellRanges");for(const[part,read,...actions]of GRID_PART_API){const load=part==="cell-range"?"loadCellRanges":"loadColumnGroups";DataGrid.prototype[read]=()=>[];for(const name of actions){const stub=DataGrid.prototype[name]=function(...args){return this[load]().then(()=>{if(DataGrid.prototype[name]===stub)throw new Error("CanopyX: the "+part+" part did not install "+name+".");return this[name](...args)})}}}
|
|
1091
|
-
const GRID_PARTS_INIT=DataGrid.prototype.initializeState;DataGrid.prototype.initializeState=function(){const ready=GRID_PARTS_INIT.call(this),range=this.opts.rangeSelection??this.view.rangeSelection;const parts=[this.view.columnGroups?.length&&this.loadColumnGroups(),range&&range.enabled!==false&&this.loadCellRanges()].filter(Boolean);return parts.length?Promise.all([ready,...parts.map(part=>part.catch(error=>this.emit("error",{error})))]).then(([result])=>result):ready};const GRID_COMPARE=definePart(DataGrid,"compare","dataset comparison",()=>({DataGrid,h,setText,fill,plural,cellValue,numberFormat,gridQueryStart,gridQuery}));const GRID_VIEW_INTENTS=definePart(DataGrid,"view-intents","view intents",()=>({DataGrid,h,setText,fill,gridButton,gridVariant,gridQuery,gridQueryStart,gridFreeze,GRID_FILTER_LABELS,GRID_REPORTING,watchOverlayTheme}));for(const name of["getViewIntent","validateViewIntent","previewViewIntent","applyViewIntent"]){const stub=DataGrid.prototype[name]=function(...args){return loadPart(GRID_VIEW_INTENTS).then(()=>{if(this.destroyed)throw new DOMException("Grid was destroyed.","AbortError");if(DataGrid.prototype[name]===stub)throw new Error("CanopyX: view intents did not install "+name+".");return this[name](...args)})}}
|
|
1099
|
+
const CHANGES_API={createDiff:changeViewFactory("diff","createDiff"),createChangeList:changeViewFactory("changes","createChangeList"),createPropagation:changeViewFactory("propagation","createPropagation")};const CHANGE_VIEW_TYPES={diff:CHANGES_API.createDiff,changes:CHANGES_API.createChangeList,propagation:CHANGES_API.createPropagation};DEFAULT_LABELS=Object.freeze(Object.assign({},DEFAULT_LABELS,{gridCellRangeSelected:"{rows} rows × {columns} columns selected",gridCellRangesSelected:"{ranges} ranges selected, {cells} cells",gridCellRangeCleared:"Cell selection cleared",gridCopyCells:"Copy cells",gridCopyCellsWithHeaders:"Copy cells with headers",gridPasteCells:"Paste",gridSelectAllCells:"Select all cells",gridCellsCopied:"Copied {rows} rows × {columns} columns",gridCellsPasted:"Pasted {count} cells",gridPasteRefused:"{count} cells were not pasted",gridPasteReadOnly:"This cell cannot be changed.",gridPasteType:"“{value}” is not a valid value for {column}.",gridPasteReport:"Paste report",gridPasteCell:"Row {row}, {column}: {reason}",gridFillHandle:"Drag to fill the cells below",gridCellsFilled:"Filled {count} cells",gridCellMenu:"Cell actions",gridClearCellRanges:"Clear cell selection"}));const GRID_PART_CONTEXT=()=>({DataGrid,h,setText,fill,columnWidth,foldText,gridButton,gridIcon,gridDecorateButton,cellText,cellValue,isCellObject,numberFormat,gridFreeze,gridMomentFromParts,requireIdentifier,loadGridFilterEditor,CELL_CONTROLS,reachable,gridExportField,bindContextMenu});const GRID_COLUMN_GROUPS=definePart(DataGrid,"column-groups","column groups",GRID_PART_CONTEXT);const GRID_CELL_RANGE=definePart(DataGrid,"cell-range","cell ranges",GRID_PART_CONTEXT);const GRID_PART_API=[["column-groups","getColumnGroups","setColumnGroupVisible"],["column-groups","getColumnBands"],["cell-range","getCellRanges","setCellRanges","clearCellRanges","selectAllCells","copyCellRanges","getCellRangeText","pasteCells"]];const gridPartLoader=(part,start)=>function(){return(this.partLoads||={})[start]||=loadPart(part).then(()=>this.destroyed||this["start"+start]()).catch(error=>{this.partLoads[start]=null;throw error})};DataGrid.prototype.loadColumnGroups=gridPartLoader(GRID_COLUMN_GROUPS,"ColumnGroups");DataGrid.prototype.loadCellRanges=gridPartLoader(GRID_CELL_RANGE,"CellRanges");for(const[part,read,...actions]of GRID_PART_API){const load=part==="cell-range"?"loadCellRanges":"loadColumnGroups";DataGrid.prototype[read]=()=>[];for(const name of actions){const stub=DataGrid.prototype[name]=function(...args){return this[load]().then(()=>{if(DataGrid.prototype[name]===stub)throw new Error("CanopyX: the "+part+" part did not install "+name+".");return this[name](...args)})}}}
|
|
1100
|
+
const GRID_PARTS_INIT=DataGrid.prototype.initializeState;DataGrid.prototype.initializeState=function(){const ready=GRID_PARTS_INIT.call(this),range=this.opts.rangeSelection??this.view.rangeSelection;const parts=[(this.view.columnBands??this.view.columnGroups)?.length&&this.loadColumnGroups(),range&&range.enabled!==false&&this.loadCellRanges()].filter(Boolean);return parts.length?Promise.all([ready,...parts.map(part=>part.catch(error=>this.emit("error",{error})))]).then(([result])=>result):ready};const GRID_COMPARE=definePart(DataGrid,"compare","dataset comparison",()=>({DataGrid,h,setText,fill,plural,cellValue,numberFormat,gridQueryStart,gridQuery}));const GRID_VIEW_INTENTS=definePart(DataGrid,"view-intents","view intents",()=>({DataGrid,h,setText,fill,gridButton,gridVariant,gridQuery,gridQueryStart,gridFreeze,GRID_FILTER_LABELS,GRID_REPORTING,watchOverlayTheme}));for(const name of["getViewIntent","validateViewIntent","previewViewIntent","applyViewIntent"]){const stub=DataGrid.prototype[name]=function(...args){return loadPart(GRID_VIEW_INTENTS).then(()=>{if(this.destroyed)throw new DOMException("Grid was destroyed.","AbortError");if(DataGrid.prototype[name]===stub)throw new Error("CanopyX: view intents did not install "+name+".");return this[name](...args)})}}
|
|
1092
1101
|
DataGrid.prototype.getOnlyChanges=function(){return false};DataGrid.prototype.setOnlyChanges=function(...args){return loadPart(GRID_COMPARE).then(()=>{if(this.destroyed)throw new DOMException("Grid was destroyed.","AbortError");this.startDatasetCompare();return this.setOnlyChanges(...args)})};const DATA_VIEWS_INIT=DataGrid.prototype.initializeState;DataGrid.prototype.initializeState=function(){const parts=[this.view.compare&&loadPart(GRID_COMPARE),this.view.viewIntents&&loadPart(GRID_VIEW_INTENTS)].filter(Boolean);if(!parts.length)return DATA_VIEWS_INIT.call(this);return Promise.all(parts).then(()=>{if(this.destroyed)throw new DOMException("Grid was destroyed.","AbortError");if(this.view.compare)this.startDatasetCompare();return DATA_VIEWS_INIT.call(this)})};function gridVariant(button,variant){button.dataset.variant=variant;return button}
|
|
1093
1102
|
function gridButton(text,run){const button=h("button","cx-button");button.type="button";setText(button,text);button.onclick=event=>{button.focus({preventScroll:true});run(event)};return button}
|
|
1094
1103
|
let keyboardInput=false;if(typeof document!=="undefined"){document.addEventListener("keydown",()=>{keyboardInput=true},true);document.addEventListener("pointerdown",()=>{keyboardInput=false},true)}
|
|
1095
1104
|
const focusDrawerTitle=title=>{if(keyboardInput&&title===document.activeElement&&!title.matches(":focus-visible"))title.blur();title.toggleAttribute("data-cx-pointer-focus",!keyboardInput);if(!keyboardInput)title.addEventListener("blur",()=>title.removeAttribute("data-cx-pointer-focus"),{once:true});title.focus({preventScroll:true,focusVisible:keyboardInput})};function gridInputLabel(text,input){const label=h("label","cx-grid-field");label.appendChild(document.createTextNode(text));label.appendChild(input);return label}
|
|
1096
1105
|
function gridOption(value,text){const option=h("option");option.value=value;setText(option,text);return option}
|
|
1097
|
-
const MENU_EVENT="canopyx:closemenus",announceMenu=source=>document.dispatchEvent(new CustomEvent(MENU_EVENT,{detail:{source}}));const TOOLBAR_PANELS={startMenus(){this.controlFlyouts=[];this.disposeControls=()=>this.controlFlyouts.forEach(flyout=>flyout.dispose());let pressed=null;for(const type of["mouseup","click","keydown","pointercancel"])document.addEventListener(type,()=>{pressed=null},{capture:true,signal:this.lifetime.signal});for(const type of["pointerdown","focusin",MENU_EVENT])document.addEventListener(type,event=>{if(type==="pointerdown")pressed=event.target;const node=type==="focusin"&&pressed?.isConnected&&event.target.contains(pressed)?pressed:event.detail?.source||event.target;if(type!==MENU_EVENT||event.target.contains(this.host))this.closeMenusOutside(node)},{signal:this.lifetime.signal})},closeMenusOutside(node){const holds=element=>element&&(UI_TOOLS.owns?.(element,node)??element.contains(node));if(this.pendingColumnMenu&&!holds(this.pendingColumnMenu.anchor))this.pendingColumnMenu=null;for(const details of this.toolbar.querySelectorAll(".cx-columns[open]"))if(!holds(details))details.open=false;const popover=this.gridPopover;if(popover&&!holds(popover.panel)&&!holds(popover.anchor))this.closeGridPopover(false);const cellMenu=this.cellMenuPanel;if(cellMenu&&!holds(cellMenu)&&!holds(this.cellMenuHit?.cell))this.cellMenuBinding?.close("menus",false,true)},closeMenus(){this.closeMenusOutside(document)},controlPanel(title,className,onOpen){const details=h("details","cx-columns "+className),summary=h("summary","cx-btn"),panel=h("div","cx-columns-list cx-grid-panel cx-pop");summary.setAttribute("role","button");panel.setAttribute("aria-label",title);if(className!=="cx-grid-filters")summary.classList.add("ghost");setText(summary,title);details.append(summary,panel);this.toolbar.appendChild(details);summary.prepend(gridIcon(className.slice(8).replace("rs","r")));panel.popover="manual";const flyout=watchFlyout(details,panel,()=>details.open);this.controlFlyouts.push(flyout);details.addEventListener("toggle",()=>{if(details.open){announceMenu(details);if(onOpen)onOpen(panel);flyout.open()}else{flyout.close();for(const inner of panel.querySelectorAll("details[open]"))inner.open=false}});details.addEventListener("keydown",event=>{if(event.key==="Escape"&&details.open){details.open=false;flyout.close();summary.focus();event.preventDefault();event.stopPropagation()}});return{details,panel}},buildSavedViews(){const panel=this.controlPanel(this.labels.gridViews,"cx-grid-views").panel;const choice=this.savedChoice=h("select"),name=h("input");name.type="text";name.maxLength=100;choice.setAttribute("aria-label",this.labels.gridChooseView);panel.appendChild(choice);panel.appendChild(gridInputLabel(this.labels.gridViewName,name));const error=h("p","cx-grid-control-error");error.setAttribute("role","status");const run=action=>{try{Promise.resolve(action()).then(()=>setText(error,""),failure=>setText(error,failure.message))}
|
|
1106
|
+
const MENU_EVENT="canopyx:closemenus",announceMenu=source=>document.dispatchEvent(new CustomEvent(MENU_EVENT,{detail:{source}}));const TOOLBAR_PANELS={startMenus(){this.controlFlyouts=[];this.disposeControls=()=>this.controlFlyouts.forEach(flyout=>flyout.dispose());let pressed=null;for(const type of["mouseup","click","keydown","pointercancel"])document.addEventListener(type,()=>{pressed=null},{capture:true,signal:this.lifetime.signal});for(const type of["pointerdown","focusin",MENU_EVENT])document.addEventListener(type,event=>{if(type==="pointerdown")pressed=event.target;const node=type==="focusin"&&pressed?.isConnected&&event.target.contains(pressed)?pressed:event.detail?.source||event.target;if(type!==MENU_EVENT||event.target.contains(this.host))this.closeMenusOutside(node)},{signal:this.lifetime.signal})},closeMenusOutside(node){const holds=element=>element&&(UI_TOOLS.owns?.(element,node)??element.contains(node));if(this.pendingColumnMenu&&!holds(this.pendingColumnMenu.anchor))this.pendingColumnMenu=null;for(const details of this.toolbar.querySelectorAll(".cx-columns[open]"))if(!holds(details))details.open=false;const popover=this.gridPopover;if(popover&&!holds(popover.panel)&&!holds(popover.anchor))this.closeGridPopover(false);const cellMenu=this.cellMenuPanel;if(cellMenu&&!holds(cellMenu)&&!holds(this.cellMenuHit?.cell))this.cellMenuBinding?.close("menus",false,true)},closeMenus(){this.closeMenusOutside(document)},controlPanel(title,className,onOpen){const details=h("details","cx-columns "+className),summary=h("summary","cx-btn"),panel=h("div","cx-columns-list cx-grid-panel cx-pop");summary.setAttribute("role","button");panel.setAttribute("role","dialog");panel.setAttribute("aria-label",title);if(className!=="cx-grid-filters")summary.classList.add("ghost");setText(summary,title);details.append(summary,panel);this.toolbar.appendChild(details);summary.prepend(gridIcon(className.slice(8).replace("rs","r")));panel.popover="manual";const flyout=watchFlyout(details,panel,()=>details.open);this.controlFlyouts.push(flyout);details.addEventListener("toggle",()=>{if(details.open){announceMenu(details);if(onOpen)onOpen(panel);flyout.open()}else{flyout.close();for(const inner of panel.querySelectorAll("details[open]"))inner.open=false}});details.addEventListener("keydown",event=>{if(event.key==="Escape"&&details.open){details.open=false;flyout.close();summary.focus();event.preventDefault();event.stopPropagation()}});return{details,panel}},buildSavedViews(){const panel=this.controlPanel(this.labels.gridViews,"cx-grid-views").panel;const choice=this.savedChoice=h("select"),name=h("input");name.type="text";name.maxLength=100;choice.setAttribute("aria-label",this.labels.gridChooseView);panel.appendChild(choice);panel.appendChild(gridInputLabel(this.labels.gridViewName,name));const error=h("p","cx-grid-control-error");error.setAttribute("role","status");const run=action=>{try{Promise.resolve(action()).then(()=>setText(error,""),failure=>setText(error,failure.message))}
|
|
1098
1107
|
catch(failure){setText(error,failure.message)}};panel.appendChild(gridButton(this.labels.gridApply,()=>run(()=>this.applySavedView(choice.value))));panel.appendChild(gridButton(this.labels.gridSaveView,()=>run(()=>this.saveView(name.value))));panel.appendChild(gridButton(this.labels.gridRemoveView,()=>run(()=>this.removeSavedView(choice.value))));panel.appendChild(error);this.syncSavedViews()},syncSavedViews(){if(!this.savedChoice)return;const selected=this.savedChoice.value;this.savedChoice.textContent="";this.savedChoice.appendChild(gridOption("",this.labels.gridChooseView));this.getSavedViews().forEach(name=>this.savedChoice.appendChild(gridOption(name,name)));if(this.savedViews.has(selected))this.savedChoice.value=selected},placeMenus(phone){if(this.overflow)for(const selector of[".cx-grid-views",".cx-grid-export"]){const item=this.toolbar.querySelector(selector);if(!item)continue;item.open=false;if(phone)this.overflow.panel.appendChild(item);else this.toolbar.insertBefore(item,selector===".cx-grid-views"?this.slots?.afterViews||this.spacer:this.overflow.details)}}};function gridCountLabel(element,label,values,marks=/(\{count\}|\{selected\})/){
|
|
1099
1108
|
element.replaceChildren(...label.split(marks).map((part,index)=>{if(index%2===0)return document.createTextNode(fill(part,values));const bold=h("b");setText(bold,fill(part,values));return bold}))}
|
|
1100
1109
|
DEFAULT_LABELS=Object.freeze(Object.assign({},DEFAULT_LABELS,{gridRegexSearch:"Search pattern",gridResultCount:"{count} of {total} rows",gridClearQuery:"Clear search and filters",gridRemoveSearch:"Clear search: {search}",gridGroupedFilters:"Grouped filters ({count} conditions)",gridRemoveGroup:"Clear grouped filters",gridRemoveCondition:"Remove condition: {condition}"}));Object.assign(DataGrid.prototype,{buildGridSearch(){const search=h("div","cx-search"),input=this.searchInput=h("input","cx-search-input"),signal=this.lifetime.signal;input.type="search";input.placeholder=this.labels.searchPlaceholder;input.setAttribute("aria-label",this.labels.searchPlaceholder);const update=()=>{clearTimeout(this.searchTimer);this.searchTimer=null;if(this.destroyed||this.searchComposing)return;if(this.queryForChange().search===input.value){input.setCustomValidity("");return}
|
|
@@ -1153,19 +1162,20 @@ capturedOptions={...capture,columns}}}
|
|
|
1153
1162
|
const exported=this.prepareExport(capturedOptions);const cardColumns=layout==="stacked"?(projection||exported.request.columns.map(column=>column.id)).map(id=>this.columns.find(column=>column.id===id)):[];const cardRoles=cardColumns.map((column,index)=>VIEW_MODES.cardRole(column,index,cardColumns));if(projection)GRID_REPORTING.captureCardText?.(exported.request,tokenColumns);return this.runGridHook(async signal=>{await loadExportPart();const progress=(phase,completed)=>onProgress?.(Object.freeze({phase,completed,total:exported.request.recordCount}));const snapshot=await EXPORT_IMPL.snapshot(this,exported,maxRows,signal,progress);if(typeof this.opts.onPrint==="function")await this.opts.onPrint({snapshot,signal,layout});else await EXPORT_IMPL.printSnapshot(this,snapshot,signal,layout,template,projection,cardRoles);gridOperationActive(this,signal);progress("ready",snapshot.rows.length)},capture.signal,exportTimeout(this,{timeoutMs}))},buildExportControls(){this.toolbar.appendChild(Object.assign(gridButton(this.labels.gridDetails,()=>{try{const row=this.focused||[...this.rowCache.values()].find(item=>this.selected.has(item.key));if(!row||row.status)throw new Error("CanopyX: focus a record for details.");this.openDetails(row.key).catch(error=>this.emit("error",{error}))}catch(error){this.emit("error",{error})}}),{className:"cx-button cx-grid-details"}));const print=this.printButton=gridButton(this.labels.gridPrint,()=>Promise.resolve().then(()=>this.exportControl?
|
|
1154
1163
|
this.exportFromMenu((options,onProgress)=>this.print({...options,onProgress})):this.print({scope:"filtered"}))
|
|
1155
1164
|
.catch(error=>this.emit("error",{error})));print.classList.add("cx-grid-print");print.hidden=this.tools.export!==false;this.toolbar.appendChild(print);if(this.tools.export!==false)this.exportControl=this.controlPanel(this.labels.gridExport,"cx-grid-export",panel=>this.renderGridExport(panel))},async renderGridExport(panel){if(panel.firstChild)return;setText(panel,this.labels.loading);try{await loadExportPart();if(!this.destroyed&&panel.isConnected){this.renderGridExport(panel);this.controlFlyouts.forEach(item=>item.position())}}
|
|
1156
|
-
catch(error){if(!this.destroyed&&panel.isConnected){setText(panel,this.labels.gridLoadFailed);panel.appendChild(gridButton(this.labels.gridRetry,()=>this.renderGridExport(panel,setText(panel,""))));this.emit("error",{error})}}}});DataGrid.prototype.hiddenViewColumns=function(){return this.columns.filter(column=>!column.hidden&&(column.responsiveHidden||column.fitHidden))};DataGrid.prototype.phoneLineColumns=function(){if(this.host.clientWidth>640||(this.layoutMode||"fit")!=="fit")return[];const hidden=this.hiddenViewColumns().sort((a,b)=>gridRank(a)- gridRank(b));const compact=this.columns.filter(column=>!column.hidden&&!column.responsiveHidden&&!column.fitHidden).length<=2;return hidden.filter(column=>gridLevel(column)===0||compact).slice(0,2)};DataGrid.prototype.
|
|
1165
|
+
catch(error){if(!this.destroyed&&panel.isConnected){setText(panel,this.labels.gridLoadFailed);panel.appendChild(gridButton(this.labels.gridRetry,()=>this.renderGridExport(panel,setText(panel,""))));this.emit("error",{error})}}}});DataGrid.prototype.hiddenViewColumns=function(){return this.columns.filter(column=>!column.hidden&&(column.responsiveHidden||column.fitHidden))};DataGrid.prototype.phoneLineColumns=function(){if(this.host.clientWidth>640||(this.layoutMode||"fit")!=="fit")return[];const hidden=this.hiddenViewColumns().sort((a,b)=>gridRank(a)- gridRank(b));const compact=this.columns.filter(column=>!column.hidden&&!column.responsiveHidden&&!column.fitHidden).length<=2;return hidden.filter(column=>gridLevel(column)===0||compact).slice(0,2)};DataGrid.prototype.paintHiddenFields=function(slot,row,column){if(this.phone&&column.identity)slot.cell.title=cellText(row.cells[column.id],column,this.fmt)||"";const first=column===this.cols[0],fields=first&&this.phone?this.phoneLineColumns(row):[];let button=slot.hiddenFields;const hidden=first&&(this.phone||this.desktopHiddenFields)?this.hiddenViewColumns().filter(column=>!fields.includes(column)):[],count=hidden.length;if(!count){button?.remove();slot.hiddenFields=null}
|
|
1157
1166
|
else{if(!button){button=gridButton("",()=>Promise.resolve().then(()=>this.openDetails(button.dataset.cxRecord)).catch(error=>this.emit("error",{error})));button.classList.add("cx-hidden-fields");button.tabIndex=-1}
|
|
1158
|
-
const label=this.
|
|
1167
|
+
const label=fill(plural(this.labels.hiddenColumns,count,this.lang),{count:numberFormat(this.lang).format(count)}),titles=hidden.map(item=>item.title).join(", ");button.dataset.cxRecord=row.id;button.setAttribute("aria-label",label+": "+titles);button.title=titles;setText(button,label);slot.hiddenFields=button}
|
|
1159
1168
|
if(!first||!this.phone){slot.childSlots?.forEach(disposeHostSlot);slot.childSlots=null;slot.phoneLine?.remove();slot.phoneLine=null;if(slot.phonePrimary){slot.phonePrimary.replaceWith(...slot.phonePrimary.childNodes);slot.phonePrimary=null}
|
|
1160
1169
|
if(first&&count)slot.cell.appendChild(button);return}
|
|
1161
1170
|
let primary=slot.phonePrimary;if(!primary||primary.parentNode!==slot.cell)primary=h("span","cx-phone-primary");for(const node of[...slot.cell.childNodes])if(node!==primary&&node!==slot.phoneLine&&node!==button)primary.appendChild(node);if(primary.parentNode!==slot.cell)slot.cell.prepend(primary);slot.phonePrimary=primary;if(!fields.length&&!count){slot.childSlots?.forEach(disposeHostSlot);slot.childSlots=null;slot.phoneLine?.remove();slot.phoneLine=null;return}
|
|
1162
1171
|
let line=slot.phoneLine;if(!line||line.parentNode!==slot.cell){line=h("span","cx-phone-fields");slot.cell.appendChild(line)}
|
|
1163
1172
|
slot.phoneLine=line;const shape=JSON.stringify(fields.map(item=>item.id));if(line.dataset.cxFields!==shape){slot.childSlots?.forEach(disposeHostSlot);line.replaceChildren();line.dataset.cxFields=shape;slot.childSlots=[];for(const field of fields){const item=h("span","cx-phone-field"),label=h("span","cx-phone-field-title"),value=h("span","cx-phone-value");setText(label,field.title+":");item.append(label,value);line.appendChild(item);const content=value.appendChild(h("span","cx-content")),textSpan=content.appendChild(h("span","cx-text"));slot.childSlots.push({cell:value,content,base:"cx-phone-value",cls:null,title:null,badges:[],mode:"default",textSpan,text:textSpan.appendChild(document.createTextNode(""))})}}
|
|
1164
|
-
if(count&&button.parentNode!==
|
|
1173
|
+
const disclosure=fields.length?line.lastElementChild:line;if(count&&button.parentNode!==disclosure)disclosure.appendChild(button);fields.forEach((field,index)=>{this.paintSlot(slot.childSlots[index],row,field,this.columns.indexOf(field),{level:0,expanded:false});const value=slot.childSlots[index].cell;value.title=cellText(row.cells[field.id],field,this.fmt)||""})};DataGrid.prototype.syncGridPhoneValues=function(){if(!this.phone)return;for(const value of this.canvas.querySelectorAll(".cx-phone-value")){if(value.querySelector(".p-pill,.p-state")&&value.scrollWidth>value.clientWidth+1)value.tabIndex=0;else value.removeAttribute("tabindex")}};LINK_IMPL.DataGrid=DataGrid;LINK_IMPL.gridQueryStart=gridQueryStart;linkMethods(DataGrid);linkGridPart(DataGrid);function createDataGrid(host,options){if(!host||!options||!options.view)throw new Error("CanopyX: createDataGrid needs a host element and a grid document.");if(options.recordDrawerModal!==undefined&&typeof options.recordDrawerModal!=="boolean")
|
|
1174
|
+
throw new Error("CanopyX: recordDrawerModal must be a Boolean.");const existing=activeGrids.get(host);if(existing)return existing;const grid=new DataGrid(host,options);const api={element:host,view:grid.view,ready:startPlugins(grid,()=>api),getTimeZone:()=>grid.local?"local":"utc",getSelection:()=>[...grid.selected],clearSelection:()=>grid.setSelection([]),getLoadedRows:ids=>{const wanted=new Set(Array.isArray(ids)?ids:[]),rows=[];for(const row of grid.rowCache.values())if(wanted.has(row.key))rows.push({id:row.key,cells:JSON.parse(JSON.stringify(row.h.cells||{}))});return rows},focus:()=>grid.setFocus(grid.focused||grid.rowItem(grid.rowAt(grid.logicalTop())),true),refresh:()=>{grid.version++;grid.scheduleRender()},reload:()=>grid.setQuery(gridQueryStart(grid.queryForChange(true)),grid.pendingPaging&&
|
|
1165
1175
|
{pageLength:grid.pendingPaging.pageLength,allRows:grid.pendingPaging.allRows}),destroy:()=>{grid.destroy();if(activeGrids.get(host)===api)activeGrids.delete(host);if(host.canopyx===api)delete host.canopyx}};for(const name of["getQuery","setQuery","sort","getPaging","goToPage","setPageLength","firstPage","previousPage","nextPage","getOnlyChanges","setOnlyChanges","setColumnWidth","autoFitColumn","autoFitColumns","autoSizeColumns","setColumnPriority","resetColumns","setColumnPinned","setColumnVisible","setColumnOrder","getState","setState","resetView","getSavedViews","saveView","applySavedView","removeSavedView","setTimeZone","setSelection","prepareExport","toCsv","copy","exportToHost","exportAs","print","openDetails","openRecord","scrollToRow","retry","closeMenus","getFormatRules","setFormatRules","openFormatRules","getCalculatedColumns","setCalculatedColumns","openCalculatedColumn","getLayout","setLayout","getMatches","setSearchHighlight","nextMatch","previousMatch",...GRID_EDIT_API,...GRID_LIVE_API,...GRID_CALENDAR_API,"getLiveState","getFacetPanel","setFacetPanelOpen"])
|
|
1166
1176
|
api[name]=(...args)=>grid[name](...args);for(const[,read,...names]of GRID_PART_API){api[read]=(...args)=>grid[read](...args);for(const name of names)api[name]=(...args)=>{try{return Promise.resolve(grid[name](...args))}catch(error){return Promise.reject(error)}}}
|
|
1167
1177
|
GRID_REPORTING.api?.(api,grid);for(const name of["getViewIntent","validateViewIntent","previewViewIntent","applyViewIntent"])
|
|
1168
|
-
api[name]=(...args)=>{try{return Promise.resolve(grid[name](...args))}catch(error){return Promise.reject(error)}};Object.assign(api,linkApi(grid));api.ready=linkReady(grid,api.ready);Object.freeze(api);activeGrids.set(host,api);host.setAttribute("data-canopyx-mounted","true");host.canopyx=api;recordStart(grid);return api}
|
|
1178
|
+
api[name]=(...args)=>{try{return Promise.resolve(grid[name](...args))}catch(error){return Promise.reject(error)}};Object.assign(api,linkApi(grid));api.ready=linkReady(grid,api.ready);Object.defineProperty(api,"selectOnClick",{enumerable:true,get:()=>grid.selectOnClick,set:value=>{if(typeof value!=="boolean")throw new Error("CanopyX: selectOnClick is a boolean.");grid.selectOnClick=value}});Object.freeze(api);activeGrids.set(host,api);host.setAttribute("data-canopyx-mounted","true");host.canopyx=api;recordStart(grid);return api}
|
|
1169
1179
|
const GRID_ENHANCE_IMPL={},GRID_ENHANCE=definePart(DataGrid,"enhance","table enhancement",()=>({DataGrid,GRID_ENHANCE_IMPL,PROTOCOL,createDataGrid,h,setText,gridQueryRows,gridCompare,gridResultShape,isIdentifier,GRID_REPORTING,loadPart,GRID_PAGER}));const gridEnhancer=table=>(target,options)=>loadPart(GRID_ENHANCE).then(()=>GRID_ENHANCE_IMPL.create(target,options,table));const GRID_API={createDataGrid,createCalendar,enhance:gridEnhancer(true),grid:gridEnhancer(false)};Object.assign(VIEW_MODES,{DataGrid,gridMatches,gridResultShape});Object.assign(DataGrid.prototype,VIEW_MODE_METHODS);definePart(DataGrid,"highlight","search highlighting",viewModeContext);definePart(DataGrid,"layouts","layout modes",viewModeContext);const MODES_BASE={};for(const name of["prepareState","build","getState","readGridState","applyStatePresentation","initializeState"])MODES_BASE[name]=DataGrid.prototype[name];Object.assign(DataGrid.prototype,{prepareState(){this.prepareViewModes();if(this.view.stickyHeader!==undefined&&typeof this.view.stickyHeader!=="boolean")throw new Error("CanopyX: stickyHeader is a boolean.");readCardTemplate(this.view.cardTemplate,this.columns,this.layoutOptions);const result=MODES_BASE.prepareState.call(this);this.modeState(this.defaultState);if(this.initialState)this.adoptModes(this.initialState);return result},build(){MODES_BASE.build.call(this);this.host.setAttribute("data-cx-density",this.density);this.lifetime.signal.addEventListener("abort",()=>this.host.removeAttribute("data-cx-layout"),{once:true});this.modesStarted=this.highlightOptions||this.layoutOptions||this.view.stickyHeader?this.startViewModes():null},getState(){return this.modeState(MODES_BASE.getState.call(this))},readGridState(state){return Object.assign(MODES_BASE.readGridState.call(this,state),readModeState(this,state))},applyStatePresentation(state){const applied=MODES_BASE.applyStatePresentation.call(this,state);this.applyModeState(state);return applied},initializeState(){const ready=MODES_BASE.initializeState.call(this);return this.modesStarted?Promise.all([ready,this.modesStarted]).then(([result])=>result):ready}});const FLOW_GRID_VIEWS=Object.freeze({grid:createDataGrid,tree:createTreeGrid,get reporting(){return typeof GRID_REPORTING==="object"&&typeof GRID_REPORTING.api==="function"}});function checkIntentPath(path){if(!Array.isArray(path)||!path.length)throw new Error("CanopyX: checking needs a complete node-ID path.");const seen=new Set();return path.map(id=>{requireIdentifier(id,"checking path ID");if(seen.has(id))throw new Error("CanopyX: a checking path cannot repeat an ID.");seen.add(id);return id})}
|
|
1170
1180
|
function checkBranch(){return{value:null,mask:0,children:new Map()}}
|
|
1171
1181
|
class CheckIntents{constructor(items,mode){if(!Array.isArray(items))throw new Error("CanopyX: checkIntents must be an array.");this.mode=mode;this.root=checkBranch();for(const item of items){if(!item||typeof item.checked!=="boolean")throw new Error("CanopyX: a checking intent needs a boolean checked value.");const path=checkIntentPath(item.path);let branch=this.root;for(const id of path){if(!branch.children.has(id))branch.children.set(id,checkBranch());branch=branch.children.get(id)}
|
|
@@ -1287,7 +1297,8 @@ const FLOW_ASYNC_METHODS=["next","back","goTo","setState","validate","submit","r
|
|
|
1287
1297
|
.catch(error=>host.dispatchEvent(new CustomEvent("canopyx:error",{detail:{error,hook:"part"},bubbles:true}))))]).then(async()=>{if(destroyed)throw destroyedError();impl=FLOW_IMPL.create(host,options,editors);return impl.ready});const api={element:host,flow:options.flow,view:options.flow};for(const name of FLOW_SYNC_METHODS)api[name]=(...args)=>requireImpl(name)[name](...args);for(const name of FLOW_ASYNC_METHODS)api[name]=(...args)=>{if(destroyed)return Promise.reject(destroyedError());return ready.then(()=>requireImpl(name)[name](...args))};api.ready=ready.then(()=>{if(destroyed)throw destroyedError();return api});api.ready.catch(()=>{});api.destroy=()=>{if(destroyed)return;destroyed=true;disposeTheme();try{impl?.destroy()}
|
|
1288
1298
|
finally{impl=null;mountError?.remove();if(activeFlows.get(host)===api){activeFlows.delete(host);if(host.canopyx===api)delete host.canopyx;host.removeAttribute("data-canopyx-mounted");host.removeAttribute("data-cx-ready");host.removeAttribute("data-cx-error");host.classList.remove("cx-flow-host")}}};ready.catch(error=>{if(destroyed)return;const notice=mountError=h("div","cx-mount-error");notice.setAttribute("role","alert");setText(notice,error&&error.message?error.message:String(error));host.appendChild(notice);host.setAttribute("data-cx-error",notice.textContent);host.dispatchEvent(new CustomEvent("canopyx:error",{detail:{error},bubbles:true}))});Object.freeze(api);activeFlows.set(host,api);host.classList.add("cx-host","cx-flow-host");host.setAttribute("data-canopyx-mounted","true");host.canopyx=api;return api}
|
|
1289
1299
|
const FLOW_API={createFlow};function createTreeGrid(host,options){if(!host||!options||!options.view){throw new Error("CanopyX: createTreeGrid needs a host element and a view document.")}
|
|
1290
|
-
|
|
1300
|
+
if(options.recordDrawerModal!==undefined&&typeof options.recordDrawerModal!=="boolean")
|
|
1301
|
+
throw new Error("CanopyX: recordDrawerModal must be a Boolean.");const existing=activeGrids.get(host);if(existing)return existing;const grid=new TreeGrid(host,options);const api=Object.assign({element:host,view:grid.view,ready:startPlugins(grid,()=>api),expandPath:(ids,o)=>grid.expandPath(ids,o),setFilter:(filter,o)=>{if(!grid.queryAware)grid.clearDeclaredFilters();grid.setFilter(filter,o)},setFilterActive:(id,active)=>grid.setFilterActive(id,active),setActiveFilters:(ids)=>grid.setActiveFilters(ids),updateActiveFilters:(change)=>grid.updateActiveFilters(change),getActiveFilters:()=>Array.from(grid.activeFilters),sort:(columnId,direction)=>grid.sort(columnId,direction),getQuery:()=>grid.getQuery(),setQuery:(query,options)=>grid.setQuery(query,options),setColumnVisible:(columnId,visible)=>grid.setColumnVisible(columnId,visible),setColumnWidth:(columnId,width)=>grid.setColumnWidth(columnId,width),setTreeColumnPinned:(pinned)=>grid.setTreeColumnPinned(pinned),setTimeZone:(zone)=>grid.setTimeZone(zone),getTimeZone:()=>(grid.local?"local":"utc"),refresh:()=>{grid.version++;grid.scheduleRender()},reload:(id,options)=>grid.reload(id,options),readLocation:()=>grid.readLocation(),getSelected:()=>Array.from(grid.selected).map((w)=>w.h),setSelection:(ids)=>grid.setSelection(ids),clearSelection:()=>grid.setSelection([]),selectAll:(options)=>grid.selectAll(options),focus:()=>{if(grid.destroyed)return;const target=grid.indexOf(grid.focused)>=0?grid.focused:grid.rows[0];if(target)grid.setFocus(target,true);else grid.grid.focus({preventScroll:true})},visibleRows:()=>grid.visibleRows(),toOutline:()=>grid.toOutline(),getState:()=>grid.getState(),setState:(state)=>grid.setState(state),getLayout:()=>grid.getLayout(),setLayout:(change)=>grid.setLayout(change),getMatches:()=>grid.getMatches(),setSearchHighlight:(enabled)=>grid.setSearchHighlight(enabled),nextMatch:(options)=>grid.nextMatch(options),previousMatch:(options)=>grid.previousMatch(options),search:(query,limit)=>grid.search(query,limit||(grid.view.search&&grid.view.search.maxResults)||20),loadMore:(id)=>{const w=id==null?grid.root:grid.keyMap.get(id);return w?grid.loadMore(w):Promise.resolve()},applyCounts:(doc)=>grid.applyCounts(doc),refreshCounts:(ids)=>grid.refreshCounts(ids),closeMenus:()=>grid.closeMenus?.(),destroy:()=>{grid.destroy();if(activeGrids.get(host)===api)activeGrids.delete(host);if(host.canopyx===api)delete host.canopyx}},grid.interactionApi&&grid.interactionApi(),linkApi(grid));for(const name of["prepareExport","exportAs","getSavedViews","saveView","applySavedView","removeSavedView","resetView","setColumnOrder","resetColumns","setColumnPinned","openDetails","openRecord"])
|
|
1291
1302
|
api[name]=(...args)=>{if(grid[name])return grid[name](...args);const error=new Error("CanopyX: "+name+" needs the tree tools part.");if(/^(exportAs|applySavedView|resetView|openDetails|openRecord)$/.test(name)) return Promise.reject(error);
|
|
1292
1303
|
throw error};api.ready=linkReady(grid,api.ready);Object.freeze(api);activeGrids.set(host,api);host.setAttribute("data-canopyx-mounted","true");host.canopyx=api;recordStart(grid);return api}
|
|
1293
1304
|
const configured=new Map();function configure(viewId,options){requireIdentifier(viewId,"view ID");if(!options||typeof options!=="object"){throw new Error("CanopyX: configure needs a view id and an options object.")}
|