@evotecit/canopyx 0.2.2 → 0.3.3
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-editing.css +1 -6
- package/CanopyX.Html/Assets/canopyx-editing.js +4 -39
- package/CanopyX.Html/Assets/canopyx-export.js +2 -2
- package/CanopyX.Html/Assets/canopyx-flow-entry.css +178 -0
- package/CanopyX.Html/Assets/canopyx-flow-entry.js +78 -0
- package/CanopyX.Html/Assets/canopyx-flow-module.mjs +80 -0
- package/CanopyX.Html/Assets/canopyx-flow.css +180 -0
- package/CanopyX.Html/Assets/canopyx-flow.js +214 -0
- package/CanopyX.Html/Assets/canopyx-forms.css +8 -0
- package/CanopyX.Html/Assets/canopyx-forms.js +39 -0
- package/CanopyX.Html/Assets/canopyx-grid-module.mjs +18 -14
- package/CanopyX.Html/Assets/canopyx-grid.css +2 -0
- package/CanopyX.Html/Assets/canopyx-grid.js +18 -14
- package/CanopyX.Html/Assets/canopyx-interactive.js +10 -9
- package/CanopyX.Html/Assets/canopyx-labels-de.js +72 -0
- package/CanopyX.Html/Assets/canopyx-labels-es.js +72 -0
- package/CanopyX.Html/Assets/canopyx-labels-fr.js +72 -0
- package/CanopyX.Html/Assets/canopyx-labels-it.js +72 -0
- package/CanopyX.Html/Assets/canopyx-labels-pl.js +72 -0
- package/CanopyX.Html/Assets/canopyx-module.mjs +10 -9
- package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +18 -14
- package/CanopyX.Html/Assets/canopyx-reporting.css +2 -0
- package/CanopyX.Html/Assets/canopyx-reporting.js +18 -14
- package/CanopyX.Html/Assets/canopyx.js +10 -9
- package/JavaScript/flow.d.ts +232 -0
- package/JavaScript/grid.d.ts +8 -5
- package/JavaScript/hosts.d.ts +3 -1
- package/JavaScript/locales/de.mjs +72 -0
- package/JavaScript/locales/es.mjs +72 -0
- package/JavaScript/locales/fr.mjs +72 -0
- package/JavaScript/locales/it.mjs +72 -0
- package/JavaScript/locales/pl.mjs +72 -0
- package/README.md +3 -2
- package/package.json +20 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/* Forms part: what every form's editors share, here the lookup combobox's suggestion list (a popover above any clipping). */
|
|
2
|
+
.cx-editor-list{position:fixed;inset:auto;margin:0;box-sizing:border-box;background:var(--cx-surface);color:var(--cx-text);border:var(--cx-size-1px) solid var(--cx-line-strong);border-radius:var(--cx-radius);box-shadow:var(--cx-panel-shadow);font:var(--cx-size-13d5px)/1.4 var(--cx-font);}
|
|
3
|
+
.cx-editor-list{max-height:var(--cx-size-240px);overflow:auto;padding:var(--cx-size-4px);}
|
|
4
|
+
.cx-editor-option,.cx-editor-note{padding:var(--cx-size-6px) var(--cx-size-8px);border-radius:var(--cx-radius-sm);white-space:nowrap;}
|
|
5
|
+
.cx-editor-option{cursor:pointer;}
|
|
6
|
+
.cx-editor-option[aria-selected="true"],.cx-editor-option:hover{background:var(--cx-selected-bg);}
|
|
7
|
+
.cx-editor-note{color:var(--cx-muted);}
|
|
8
|
+
.cx-editor::placeholder{color:color-mix(in srgb,var(--cx-text) 60%,var(--cx-surface));font-style:italic;opacity:1;}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"a8c60f205d9babca",install(context){if(installed.has(context.FORMS_IMPL))return;const{FORMS_IMPL,h,setText,fill,gridFreeze,gridMomentFromParts,boundedPattern,foldText}=context;const editPad=(number,width=2)=>String(number).padStart(width,"0");function editInput(context,type="text"){const input=h("input","cx-editor");input.type=type;input.autocomplete="off";if(typeof context.editor.placeholder==="string")input.placeholder=context.editor.placeholder;return input}
|
|
2
|
+
const EDIT_NUMBER_LOCALES=new Map();function editParseNumber(text,locale){let format=EDIT_NUMBER_LOCALES.get(locale);if(!format){let number;try{number=new Intl.NumberFormat(locale||undefined)}catch(error){number=new Intl.NumberFormat()}
|
|
3
|
+
const digits=new Map();for(let digit=0;digit<10;digit++)digits.set(number.formatToParts(digit).find(part=>part.type==="integer").value,String(digit));format={parts:number.formatToParts(-12345.6),digits};if(EDIT_NUMBER_LOCALES.size>=32)EDIT_NUMBER_LOCALES.delete(EDIT_NUMBER_LOCALES.keys().next().value);EDIT_NUMBER_LOCALES.set(locale,format)}
|
|
4
|
+
const parts=format.parts;const group=parts.find(part=>part.type==="group")?.value??",",decimal=parts.find(part=>part.type==="decimal")?.value??".";let source=Array.from(text.trim(),digit=>format.digits.get(digit)??digit).join("").replace(/[\u061c\u200e\u200f]/g, "").replace(/\u2212/g, "-");
|
|
5
|
+
const pieces=source.split(decimal),whole=pieces[0],spaced=!group.trim();if(pieces.length>2)return NaN;const groups=whole.replace(/^[-+]/, "").split(spaced ? /[\s\u00a0\u202f]/ : group);
|
|
6
|
+
if(groups.length>1&&(!/^\d{1,3}$/.test(groups[0]) || groups.slice(1).some(digits => !/^\d{3}$/.test(digits)))) return NaN;
|
|
7
|
+
source=(/^[-+]/.test(whole) ? whole[0] : "") + groups.join("") + (pieces.length > 1 ? "." + pieces[1] : "");
|
|
8
|
+
return /^[-+]?(\d+\.?\d*|\.\d+)(e[-+]?\d+)?$/i.test(source) ? Number(source) : NaN;
|
|
9
|
+
}
|
|
10
|
+
function editMoment(value,local){const date=typeof value==="string"?new Date(value):null;if(!date||Number.isNaN(date.getTime()))return null;const get=name=>date[(local?"get":"getUTC")+ name]();const seconds=get("Seconds"),milliseconds=get("Milliseconds");const time=editPad(get("Hours"))+ ":"+editPad(get("Minutes"))+
|
|
11
|
+
(seconds||milliseconds?":"+editPad(seconds)+(milliseconds?"."+editPad(milliseconds,3):""):"");return{date:editPad(get("FullYear"),4)+ "-"+editPad(get("Month")+ 1)+ "-"+editPad(get("Date")),time}}
|
|
12
|
+
function editFromParts(date,time,local){const[clock,fraction=""]=time.split("."),milliseconds=Number(fraction.padEnd(3,"0"));const[year,month,day]=date.split("-").map(Number),[hours,minutes,seconds=0]=clock.split(":").map(Number);const moment=gridMomentFromParts(year,month,day,hours,minutes,seconds,local);if(!moment||!Number.isInteger(milliseconds)||milliseconds<0||milliseconds>999)return null;moment.setUTCMilliseconds(milliseconds);return moment.toISOString().replace(".000Z","Z")}
|
|
13
|
+
function editDateEditor(context,withDate,withTime){const local=context.timeZone==="local",moment=context.column.kind==="datetime";const input=editInput(context,withDate&&withTime?"datetime-local":withDate?"date":"time");if(moment&&withTime)input.step="0.001";const parts=moment?editMoment(context.value,local):null;const start=!moment?typeof context.value==="string"?context.value:"":!parts?"":
|
|
14
|
+
withDate&&withTime?parts.date+"T"+parts.time:withDate?parts.date:parts.time;input.value=start;const displayed=input.value;let changed=false;input.addEventListener("input",()=>{changed=true});const read=()=>{if(!changed&&input.value===displayed||input.value===start)return context.value??null;if(!input.value)return null;if(!moment)return input.value;const[date,time]=withDate&&withTime?input.value.split("T"):withDate?[input.value,parts?parts.time:"00:00"]:
|
|
15
|
+
[(parts||editMoment(new Date().toISOString(),local)).date,input.value];return editFromParts(date,time,local)};return{element:input,getValue:read,error:()=>input.validity?.badInput||moment&&input.value&&read()===null?fill(context.labels.gridEditDate,{column:context.column.title}):null}}
|
|
16
|
+
function editNumberPlaces(value){const[coefficient,exponent="0"]=String(value).split("e");return Math.max(0,(coefficient.split(".")[1]||"").length-Number(exponent))}
|
|
17
|
+
const EDIT_EDITORS={text:{create(context){const input=editInput(context);input.value=context.initial??(context.value==null?"":String(context.value));return{element:input,getValue:()=>input.value===""&&context.value==null?null:input.value}}},number:{create(context){const input=editInput(context),step=context.editor.step||1,rules=context.rules;const decimals=Math.max(editNumberPlaces(step),editNumberPlaces(rules.min??0));let plain;try{plain=new Intl.NumberFormat(context.locale||undefined,{useGrouping:false,maximumSignificantDigits:21})}
|
|
18
|
+
catch(error){plain=new Intl.NumberFormat(undefined,{useGrouping:false,maximumSignificantDigits:21})}
|
|
19
|
+
input.inputMode="decimal";input.value=context.initial??(typeof context.value==="number"?plain.format(context.value):"");const read=()=>input.value.trim()===""?null:editParseNumber(input.value,context.locale);input.addEventListener("keydown",event=>{if(event.key!=="ArrowUp"&&event.key!=="ArrowDown"||event.altKey)return;if(context.readOnly){event.preventDefault();return}
|
|
20
|
+
const value=read();if(!Number.isNaN(value)){let next=(value??0)+(event.key==="ArrowUp"?step:-step);if(typeof rules.min==="number")next=Math.max(rules.min,next);if(typeof rules.max==="number")next=Math.min(rules.max,next);input.value=plain.format(decimals<=100?Number(next.toFixed(decimals)):next)}
|
|
21
|
+
event.preventDefault()});return{element:input,getValue:read,error:()=>Number.isNaN(read())?fill(context.labels.gridEditNumber,{column:context.column.title}):null}}},datetime:{create:context=>editDateEditor(context,true,true)},date:{create:context=>editDateEditor(context,true,false)},time:{create:context=>editDateEditor(context,false,true)},select:{create(context){const select=h("select","cx-editor"),options=(context.options||[]).slice();if(context.value!=null&&!options.some(option=>option.value===context.value))
|
|
22
|
+
options.unshift({value:context.value,label:context.text||String(context.value)});if(!context.rules.required||context.value==null)select.appendChild(new Option(context.labels.gridEditNone,""));options.forEach((option,index)=>{const item=new Option(option.label,String(index));item.disabled=!!option.disabledReason;select.appendChild(item)});const at=options.findIndex(option=>option.value===context.value);select.value=at<0?"":String(at);return{element:select,getValue:()=>select.value===""?null:options[Number(select.value)].value}}},toggle:{create(context){const box=h("input","cx-editor cx-editor-toggle");box.type="checkbox";box.checked=context.value===true;return{element:box,getValue:()=>box.checked}}},lookup:{create:context=>editLookupEditor(context)}};function editLookupEditor(context){const input=editInput(context),popup=h("div","cx-editor-list"),note=h("div","cx-editor-note"),list=h("div"),id=context.id+"-list",labels=context.labels;input.setAttribute("role","combobox");input.setAttribute("aria-autocomplete","list");input.setAttribute("aria-expanded","false");input.setAttribute("aria-controls",id);list.id=id;list.setAttribute("role","listbox");list.setAttribute("aria-label",context.column.title);popup.popover="manual";popup.append(note,list);popup.addEventListener("pointerdown",event=>event.preventDefault());let options=[],active=-1,timer=0,request=null;let chosen=context.initial!==undefined||context.value==null?null:{value:context.value,label:context.text||String(context.value)};input.value=context.initial??(chosen?chosen.label:"");const paint=()=>{[...list.querySelectorAll("[role=option]")].forEach((option,index)=>option.setAttribute("aria-selected",String(index===active)));if(active>=0){input.setAttribute("aria-activedescendant",id+"-"+active);list.querySelector("#"+CSS.escape(id+"-"+active))?.scrollIntoView({block:"nearest"})}
|
|
23
|
+
else input.removeAttribute("aria-activedescendant")};const close=()=>{clearTimeout(timer);request?.abort();input.setAttribute("aria-expanded","false");input.removeAttribute("aria-activedescendant");if(popup.matches(":popover-open"))popup.hidePopover()};input.addEventListener("blur",close);const show=(items,message)=>{options=items;active=items.length?0:-1;list.replaceChildren();list.hidden=!items.length;setText(note,message||"");note.hidden=!message;items.forEach((item,index)=>{const option=h("div","cx-editor-option");option.id=id+"-"+index;option.setAttribute("role","option");setText(option,item.label);option.addEventListener("click",()=>pick(index));list.appendChild(option)});if(!input.isConnected)return;const box=input.getBoundingClientRect();popup.style.left=box.left+"px";popup.style.top=box.bottom+2+"px";popup.style.minWidth=box.width+"px";if(!popup.matches(":popover-open"))popup.showPopover();input.setAttribute("aria-expanded","true");paint()};const pick=index=>{if(context.readOnly)return;chosen=options[index];input.value=chosen.label;context.remember(chosen);close()};const search=()=>{if(context.readOnly)return;clearTimeout(timer);request?.abort();const text=input.value;if(text.length<context.lookupMinLength){close();return}
|
|
24
|
+
show([],labels.gridEditSearching);timer=setTimeout(()=>{const controller=request=new AbortController();Promise.resolve().then(()=>context.lookup(text,controller.signal)).then(items=>{if(!controller.signal.aborted)show(items,items.length?null:labels.gridEditNoMatches)},error=>{if(!controller.signal.aborted&&error?.name!=="AbortError")show([],error?.message||String(error))})},200)};input.addEventListener("input",()=>{chosen=null;search()});input.addEventListener("keydown",event=>{const open=input.getAttribute("aria-expanded")==="true";if(event.key==="ArrowDown"||event.key==="ArrowUp"){if(!open)search();else if(options.length){active=Math.max(0,Math.min(options.length-1,active +(event.key==="ArrowDown"?1:-1)));paint()}
|
|
25
|
+
event.preventDefault()}else if(event.key==="Enter"&&open&&active>=0){pick(active);event.preventDefault()}
|
|
26
|
+
else if(event.key==="Escape"&&open){close();event.preventDefault();event.stopPropagation()}});const typed=()=>{const text=foldText(input.value.trim());return options.find(option=>foldText(option.label)===text)||(chosen&&foldText(chosen.label)===text?chosen:null)};const element=h("span","cx-editor-combo");element.append(input,popup);if(typeof context.initial==="string")queueMicrotask(search);return{element,control:input,getValue:()=>!input.value.trim()?null:(chosen||typed())?.value??null,error:()=>input.value.trim()&&!chosen&&!typed()?fill(labels.gridEditChoice,{column:context.column.title}):null,destroy(){clearTimeout(timer);request?.abort();close();popup.remove()}}}
|
|
27
|
+
const FORM_LABELS={gridEditRequired:"{column} is required.",gridEditNumber:"{column} must be a number.",gridEditDate:"{column} must be a valid date.",gridEditMin:"{column} must be at least {min}.",gridEditMax:"{column} must be at most {max}.",gridEditStep:"{column} must be a multiple of {step}.",gridEditMinLength:"{column} needs at least {min} characters.",gridEditMaxLength:"{column} allows at most {max} characters.",gridEditPattern:"{column} does not have the expected format.",gridEditChoice:"Choose {column} from the list.",gridEditNoMatches:"No matches",gridEditSearching:"Searching…",gridEditNone:"(none)"};function editOptions(list,id,bad=problem=>{throw new Error("CanopyX: column "+id+" "+problem+".")}){if(list===undefined)return null;if(!Array.isArray(list)||list.length>1000)bad("needs an array of at most 1000 editor options");return list.map(item=>{const option=item!==null&&typeof item==="object"?item:{value:item};if(!["string","number","boolean"].includes(typeof option.value)||option.label!==undefined&&typeof option.label!=="string")
|
|
28
|
+
bad("has an invalid editor option");return Object.freeze({value:option.value,label:option.label??String(option.value)})})}
|
|
29
|
+
function formRuleSpec(raw,rules,bad){const bound=value=>value===undefined||Number.isFinite(value)||typeof value==="string"&&!Number.isNaN(Date.parse(value));const count=value=>value===undefined||Number.isInteger(value)&&value>=0&&value<=1000000;if(raw.step!==undefined&&!(Number.isFinite(raw.step)&&raw.step>0)||![raw.min,raw.max,rules.min,rules.max].every(bound)||
|
|
30
|
+
!count(rules.minLength)||!count(rules.maxLength)||rules.required!==undefined&&typeof rules.required!=="boolean"||
|
|
31
|
+
[rules.pattern,rules.message,raw.placeholder].some(text=>text!==undefined&&typeof text!=="string"))bad("has invalid editor or validation settings");let pattern=null;if(rules.pattern!==undefined)try{pattern=boundedPattern(rules.pattern,true,true)}catch(error){bad("has an invalid or unsafe pattern")}
|
|
32
|
+
return{pattern,rules:Object.freeze({required:!!rules.required,min:rules.min??raw.min,max:rules.max??raw.max,step:raw.step,minLength:rules.minLength,maxLength:rules.maxLength,message:rules.message})}}
|
|
33
|
+
function formCheck(spec,value,kind,title,labels,shown){const rules=spec.rules;const say=(name,values)=>rules.message||fill(labels[name],{column:title,...values});if(value==null||value===""){if(rules.required)return say("gridEditRequired");return null}
|
|
34
|
+
if(kind==="number"&&!(typeof value==="number"&&Number.isFinite(value)&&Math.abs(value)<=Number.MAX_SAFE_INTEGER))return say("gridEditNumber");if(kind==="datetime"&&!(typeof value==="string"&&/^\d{4}-\d\d-\d\dT.*(?:Z|[+-]\d\d:\d\d)$/.test(value) && Number.isFinite(Date.parse(value)))) return say("gridEditDate");
|
|
35
|
+
if(typeof value==="number"||kind==="datetime"){const at=kind==="datetime"?Date.parse(value):value,of=bound=>typeof bound==="string"?Date.parse(bound):bound;if(rules.min!==undefined&&at<of(rules.min))return say("gridEditMin",{min:shown(rules.min)});if(rules.max!==undefined&&at>of(rules.max))return say("gridEditMax",{max:shown(rules.max)});const base=typeof rules.min==="number"?rules.min:0,steps=rules.step&&(value-base)/ rules.step;
|
|
36
|
+
if(typeof value==="number"&&rules.step&&Math.abs(steps-Math.round(steps))>1e-9)return say("gridEditStep",{step:shown(rules.step)})}
|
|
37
|
+
if(typeof value==="string"&&kind!=="datetime"){if(rules.minLength!==undefined&&value.length<rules.minLength)return say("gridEditMinLength",{min:rules.minLength});if(rules.maxLength!==undefined&&value.length>rules.maxLength)return say("gridEditMaxLength",{max:rules.maxLength});if(spec.pattern&&!spec.pattern.test(value))return say("gridEditPattern")}
|
|
38
|
+
return null}
|
|
39
|
+
Object.assign(FORMS_IMPL,{editPad,editInput,editParseNumber,editMoment,editFromParts,editDateEditor,editNumberPlaces,EDIT_EDITORS,editLookupEditor,editOptions,formRuleSpec,formCheck,FORM_LABELS});installed.add(context.FORMS_IMPL)}};(global.CanopyXParts||=[]).push(["forms",part])})(typeof window!=="undefined"?window:globalThis);
|
|
@@ -57,15 +57,15 @@ return{rank:1,value:String(value)}}
|
|
|
57
57
|
function compareKeys(a,b,direction){if(a.rank!==b.rank){return a.rank-b.rank}
|
|
58
58
|
if(a.rank===2){return 0}
|
|
59
59
|
const order=a.rank===0?(a.value<b.value?-1:a.value>b.value?1:0):collator.compare(a.value,b.value);return order*direction}
|
|
60
|
-
let DEFAULT_LABELS=Object.freeze({searchPlaceholder:"Search",searchResults:"Search results",searchResultCount:"{count} results",searchResultCountOfTotal:"{count} of {total} results",searchResultCountOfMany:"{count} of many results",searchNoResults:"No results",searchTooShort:"Type at least {min} characters",searchWordTooShort:"Type a word of at least {min} characters",searchFailed:"Search failed: {error}",columns:"Columns",visibleColumns:"Visible columns",resizeColumn:"Resize {column}",columnWidth:"{width} pixels",loading:"Loading…",loadError:"Could not load: {error} (Enter to retry)",queryFailed:"Could not update the view: {error}",showMore:"Show more ({loaded} of {total} loaded)",showMoreUnknownTotal:"Show more ({loaded} loaded)",pageLoaded:"{loaded} of {total} loaded",itemsLoaded:"{count} items",yes:"Yes",no:"No",utcTime:"{time} UTC",localTime:"{time} local time",mountError:"This view could not be displayed: {error}"});function labelsFor(...sources){const labels=Object.assign({},DEFAULT_LABELS);for(const source of sources){if(source==null)continue;if(typeof source!=="object"||Array.isArray(source))throw new Error("CanopyX: labels must be an object of strings.");Object.keys(source).forEach((name)=>{if(!Object.hasOwn(DEFAULT_LABELS,name)&&!/^(?:gridEdit|format|calendar)[A-Z]\w{0,63}$/.test(name)) throw new Error("CanopyX: there is no label '" + name + "'.");
|
|
61
|
-
if(typeof source[name]!=="string"||!/\S/.test(source[name])) throw new Error("CanopyX: label '" + name + "' must be a string with visible text.");
|
|
62
|
-
if((name==="utcTime"||name==="localTime")&&source[name].indexOf("{time}")<0)throw new Error("CanopyX: label '"+name+"' must hold {time}.");labels[name]=source[name]})}
|
|
63
|
-
return Object.freeze(labels)}
|
|
64
60
|
function fill(template,values){return template.replace(/\{(\w+)\}/g, (match, name) => (values && Object.hasOwn(values, name) ? String(values[name]) : match));
|
|
65
61
|
}
|
|
66
62
|
const pluralRules=new Map();function plural(template,count,lang){if(!template.startsWith("["))return template;const forms={};for(const match of template.matchAll(/\[(zero|one|two|few|many|other)\]([^[]*)/g)) forms[match[1]] = match[2];
|
|
67
63
|
let rules=pluralRules.get(lang);if(!rules){try{rules=new Intl.PluralRules(lang||"en")}catch(_){rules=new Intl.PluralRules("en")}pluralRules.set(lang,rules)}
|
|
68
64
|
return forms[rules.select(Number(count))]??forms.other??template}
|
|
65
|
+
let DEFAULT_LABELS=Object.freeze({searchPlaceholder:"Search",searchResults:"Search results",searchResultCount:"{count} results",searchResultCountOfTotal:"{count} of {total} results",searchResultCountOfMany:"{count} of many results",searchNoResults:"No results",searchTooShort:"Type at least {min} characters",searchWordTooShort:"Type a word of at least {min} characters",searchFailed:"Search failed: {error}",columns:"Columns",visibleColumns:"Visible columns",resizeColumn:"Resize {column}",columnWidth:"{width} pixels",loading:"Loading…",loadError:"Could not load: {error} (Enter to retry)",queryFailed:"Could not update the view: {error}",showMore:"Show more ({loaded} of {total} loaded)",showMoreUnknownTotal:"Show more ({loaded} loaded)",pageLoaded:"{loaded} of {total} loaded",itemsLoaded:"{count} items",yes:"Yes",no:"No",utcTime:"{time} UTC",localTime:"{time} local time",mountError:"This view could not be displayed: {error}"});function labelsFor(...sources){const labels=Object.assign({},DEFAULT_LABELS);for(const source of sources){if(source==null)continue;if(typeof source!=="object"||Array.isArray(source))throw new Error("CanopyX: labels must be an object of strings.");Object.keys(source).forEach((name)=>{if(!Object.hasOwn(DEFAULT_LABELS,name)&&!/^(?:gridEdit|format|calendar|flow)[A-Z]\w{0,63}$/.test(name)) throw new Error("CanopyX: there is no label '" + name + "'.");
|
|
66
|
+
if(typeof source[name]!=="string"||!/\S/.test(source[name])) throw new Error("CanopyX: label '" + name + "' must be a string with visible text.");
|
|
67
|
+
if((name==="utcTime"||name==="localTime")&&source[name].indexOf("{time}")<0)throw new Error("CanopyX: label '"+name+"' must hold {time}.");labels[name]=source[name]})}
|
|
68
|
+
return Object.freeze(labels)}
|
|
69
69
|
const numberFormats=new Map();function numberFormat(lang,minimum=0,maximum=3){const key=(lang||"")+ "|"+minimum+"|"+maximum;let format=numberFormats.get(key);if(!format){const digits={minimumFractionDigits:minimum,maximumFractionDigits:maximum};try{format=new Intl.NumberFormat(lang||undefined,digits)}catch(e){format=new Intl.NumberFormat(undefined,digits)}
|
|
70
70
|
if(numberFormats.size>=16)numberFormats.delete(numberFormats.keys().next().value);numberFormats.set(key,format)}
|
|
71
71
|
return format}
|
|
@@ -488,8 +488,9 @@ items.push(...page.items);total=page.total;next=page.next||null;if(next&&(next==
|
|
|
488
488
|
fill(this.labels.itemsLoaded,{count:count.format(items.length)}));this.stateChanged()}});const EXPORT_FORMATS=new Map(),EXPORT_IMPL={},exportFormatId=id=>typeof id==="string"&&/^[a-z][a-z\d-]{0,31}$/.test(id);
|
|
489
489
|
const exportFormatIds=list=>Array.isArray(list)&&new Set(list).size===list.length&&list.every(exportFormatId);function exportFormat(format){if(!format||!exportFormatId(format.id)||format.id==="csv"||
|
|
490
490
|
typeof format.label!=="string"||!format.label.trim()||typeof format.extension!=="string"||!/^[a-z\d]{1,16}$/i.test(format.extension) ||
|
|
491
|
-
format.mime!==undefined&&typeof format.mime!=="string"||
|
|
492
|
-
|
|
491
|
+
format.mime!==undefined&&typeof format.mime!=="string"||
|
|
492
|
+
format.showInMenu!==undefined&&typeof format.showInMenu!=="boolean"||typeof format.write!=="function")
|
|
493
|
+
throw new Error("CanopyX: invalid export format.");return Object.freeze({id:format.id,label:format.label,extension:format.extension,mime:format.mime||"application/octet-stream",showInMenu:format.showInMenu!==false,write:format.write})}
|
|
493
494
|
function registerExportFormat(format){format=exportFormat(format);EXPORT_FORMATS.set(format.id,format);return()=>EXPORT_FORMATS.get(format.id)===format&&EXPORT_FORMATS.delete(format.id)}
|
|
494
495
|
EXPORT_IMPL.formatsOf=function(grid){const list=grid.opts.exportFormats??grid.view.exportFormats,known=new Map(EXPORT_FORMATS);for(const format of grid.plugins.filter(item=>(grid.opts.plugins||[]).some(local=>local.name===item.name))
|
|
495
496
|
.flatMap(item=>item.exportFormats||[]))known.set(format.id,exportFormat(format));if(list===undefined)return[...known.values()];const formats=Array.isArray(list)?list.map(item=>typeof item==="string"?known.get(item):exportFormat(item)).filter(Boolean):null;if(!formats||new Set(formats.map(format=>format.id)).size!==formats.length)throw new Error("CanopyX: invalid exportFormats.");return formats};function exportTimeout(grid,options){const timeout=options?.timeoutMs??grid.opts.exportTimeoutMs??600000;if(!Number.isInteger(timeout)||timeout<1||timeout>2147483647)throw new Error("CanopyX: invalid export timeout.");return timeout}
|
|
@@ -505,7 +506,7 @@ if(active>=0){list.children[active].setAttribute("aria-selected","false")}
|
|
|
505
506
|
active=active<0?(delta<0?hits.length-1:0):(active+delta+hits.length)%hits.length;const item=list.children[active];item.setAttribute("aria-selected","true");input.setAttribute("aria-activedescendant",item.id);item.scrollIntoView({block:"nearest"})};input.addEventListener("input",()=>{cancelNavigation();sequence++;clearTimeout(timer);hits=[];close();timer=setTimeout(run,150)});input.addEventListener("keydown",(e)=>{if(e.defaultPrevented||e.isComposing)return;if(e.key==="ArrowDown"||e.key==="ArrowUp"){move(e.key==="ArrowDown"?1:-1)}else if(e.key==="Enter"){if(!list.hidden){choose(active>=0?active:0)}}else if(e.key==="Escape"){cancelNavigation();sequence++;clearTimeout(timer);if(list.hidden){input.value=""}
|
|
506
507
|
close()}else{return}
|
|
507
508
|
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 position=()=>{if(!isOpen())return;const anchor=anchorElement.getBoundingClientRect(),fixed=getComputedStyle(panel).position==="fixed";const below=Math.max(0,global.innerHeight-anchor.bottom-8);const above=Math.max(0,anchor.top-8);const opensAbove=below<120&&above>below,room=opensAbove?above:below;panel.style.maxHeight=(panel.classList.contains("cx-fb")?room:Math.min(320,room))+ "px";panel.style.top=opensAbove?"auto":fixed?anchor.bottom+"px":"100%";panel.style.bottom=opensAbove?fixed?global.innerHeight-anchor.top+"px":"100%":"auto";const width=panel.getBoundingClientRect().width;panel.style.left=Math.max(8,Math.min(anchor.left,global.innerWidth-width-8))-(fixed?0:anchor.left)+ "px"};global.addEventListener("resize",position);global.addEventListener("scroll",position,true);return{position,dispose:()=>{global.removeEventListener("resize",position);global.removeEventListener("scroll",position,true)}}}
|
|
508
|
-
const PART_URL=typeof document!=="undefined"&&document.currentScript?.src;const PARTS={"tree-tools":["ce442e100494535d","canopyx-tree-tools.149c371950d66a15.js","canopyx-tree-tools.ef7a3fb9c9115a82.css"],"filter-editor":["99cafeec3da59ffa","canopyx-filter-editor.7d9a82809044997b.js","canopyx-filter-editor.01b7bb6820dc9edb.css"],"export":["
|
|
509
|
+
const PART_URL=typeof document!=="undefined"&&document.currentScript?.src;const PARTS={"tree-tools":["ce442e100494535d","canopyx-tree-tools.149c371950d66a15.js","canopyx-tree-tools.ef7a3fb9c9115a82.css"],"filter-editor":["99cafeec3da59ffa","canopyx-filter-editor.7d9a82809044997b.js","canopyx-filter-editor.01b7bb6820dc9edb.css"],"export":["8b99c0b7b0ec37c5","canopyx-export.6989ea36f5d6da7b.js"],"history":["7d9901d2fe04df72","canopyx-history.9432e724bf14c9ed.js"],"pager":["8f804f70b96409f2","canopyx-pager.ac543250cf2f6e8b.js","canopyx-pager.08ad67c69026852e.css"],"enhance":["31162b1ffa622bf8","canopyx-enhance.65868addbc5c4a1a.js"],"data":["40fe19a1046d6813","canopyx-data.30d9664c5ef24288.js"],"forms":["a8c60f205d9babca","canopyx-forms.16987de1cdf9bda9.js","canopyx-forms.29058ce3c88af96e.css"],"flow":["75b9643b282dddb7","canopyx-flow.52d8d6168378df0c.js","canopyx-flow.3152e616c5557452.css"],"editing":["c82648dfaa7e5ee5","canopyx-editing.4fe83feec389c2ce.js","canopyx-editing.67c43d3b80f20232.css"],"column-groups":["b42238fd108a8614","canopyx-column-groups.d8ad6322f769b915.js","canopyx-column-groups.37e177d74cebb516.css"],"cell-range":["e99a39e7cccc57b1","canopyx-cell-range.647da96e57924f3e.js","canopyx-cell-range.23f3222652588441.css"],"links":["f1ab7e32b501ce37","canopyx-links.d96addeefb3eccf5.js"],"search":["521eebd6e1bbbd35","canopyx-search.14c69f4551c69f23.js"],"formatting":["6f9f3c51b0ad2a0e","canopyx-formatting.83a489f9fe5ff09c.js","canopyx-formatting.a59507e4e8334891.css"],"format-editor":["24f176a39c02944a","canopyx-format-editor.3b1dec2527e53988.js","canopyx-format-editor.1ba153c82aa87b04.css"],"link":["fa0c9e888463553b","canopyx-link.4ec39bc39fa6cf50.js","canopyx-link.8435c892613926ac.css"],"detail-rows":["6c96974326d65a4c","canopyx-detail-rows.a267cf8361634006.js","canopyx-detail-rows.8e38a8ad01fded76.css"],"grouping":["d942108ffbc023b6","canopyx-grouping.1387fa5fa1374471.js","canopyx-grouping.6c93259b4b89e523.css"],"highlight":["f39423961654c1e2","canopyx-highlight.a6f93893d36ab343.js","canopyx-highlight.5b6d2e0d979f9f9b.css"],"layouts":["fa8c686f21626884","canopyx-layouts.e7250c82a6abf52e.js","canopyx-layouts.0b75738924533ee8.css"],"facets":["f9219d35a87635f8","canopyx-facets.8bf477b7915bdcd6.js","canopyx-facets.648a88d2f36d4999.css"],"live":["2fa02b9178c6c5df","canopyx-live.b53c60db00f9caf9.js","canopyx-live.cc4b94a2dec6f064.css"],"record-panel":["bcc06276c7933af6","canopyx-record-panel.a374fb4254f9115c.js","canopyx-record-panel.f3691d54cefaab04.css"],"calendar":["2f44e057443bc649","canopyx-calendar.9dda223f0fe4597e.js","canopyx-calendar.1099197a45632f63.css"],"calendar-recurrence":["64bcc24d785bd1af","canopyx-calendar-recurrence.4b7f430c2a64de23.js"],"calendar-edit":["bdde26d4b7de2096","canopyx-calendar-edit.4ab2cf55e84f310f.js"],"calendar-ics":["feb3ed2cd67d057f","canopyx-calendar-ics.2a3af9eb3bf444fc.js"],"timeline":["3f04ba99401e9ebd","canopyx-timeline.76928f089774b3de.js","canopyx-timeline.0393f92746f8fa09.css"]},PART_CODE=new Map(),partName=name=>typeof name==="string"&&/^[a-z][a-z\d-]{0,31}$/.test(name);
|
|
509
510
|
function registerPart(name,part){if(!partName(name)||!part||typeof part.version!=="string"||typeof part.install!=="function"||
|
|
510
511
|
part.requires!==undefined&&!(Array.isArray(part.requires)&&part.requires.every(partName)))throw new Error("CanopyX: invalid part.");PART_CODE.set(name,part)}
|
|
511
512
|
function definePart(View,name,label,context){const parts=View.prototype.parts||={};return parts[name]={name,label,context,parts}}
|
|
@@ -597,13 +598,13 @@ const VIEW_MODE_METHODS={prepareViewModes(){const view=this.view,columns=this.co
|
|
|
597
598
|
if(choice.highlight!==undefined)this.highlightOn=choice.highlight;this.rowH=densityRowHeight(this,this.density);if(this.layoutMode==="fit")this.host.removeAttribute("data-cx-layout");else this.host.setAttribute("data-cx-layout",this.layoutMode)},modeState(state){if(this.layoutOptions)state.layout={mode:this.layoutMode,density:this.density};if(this.highlightOptions)state.highlight=!!this.highlightOn;return state},applyModeState(state){if(state.layout&&(state.layout.mode!==this.layoutMode||state.layout.density!==this.density))
|
|
598
599
|
this.setLayout(state.layout).catch(error=>this.emit("error",{error}));if(state.highlight!==undefined&&state.highlight!==!!this.highlightOn)
|
|
599
600
|
this.setSearchHighlight(state.highlight).catch(error=>this.emit("error",{error}))},startViewModes(){const parts=[this.highlightOptions&&"highlight",this.layoutOptions&&"layouts"].filter(Boolean);return Promise.all(parts.map(name=>this.requirePart(name).then(()=>this.destroyed||VIEW_MODES[name+"Start"](this))
|
|
600
|
-
.catch(error=>this.emit("error",{error}))))},getLayout(){return Object.freeze({mode:this.layoutMode,density:this.density,modes:this.layoutOptions?this.layoutOptions.modes:Object.freeze(["fit"])})},setLayout(change){if(!this.layoutOptions)return Promise.reject(new Error("CanopyX: this view declares no layout modes."));return this.requirePart("layouts").then(()=>VIEW_MODES.setLayout(this,change))},getMatches(){return VIEW_MODES.matches?VIEW_MODES.matches(this):Object.freeze({enabled:!!this.highlightOn,total:0,current:0,complete:true})},setSearchHighlight(enabled){if(typeof enabled!=="boolean")return Promise.reject(new Error("CanopyX: the highlight switch is a boolean."));if(!this.highlightOptions)return Promise.reject(new Error("CanopyX: this view declares no search highlighting."));return this.requirePart("highlight").then(()=>VIEW_MODES.setHighlight(this,enabled))},nextMatch(options){return this.stepMatch(1,options)},previousMatch(options){return this.stepMatch(-1,options)},stepMatch(direction,options){if(!this.highlightOptions)return Promise.reject(new Error("CanopyX: this view declares no search highlighting."));return this.requirePart("highlight").then(()=>VIEW_MODES.step(this,direction,options?.focus!==false))}};Object.assign(TreeGrid.prototype,VIEW_MODE_METHODS);const viewModeContext=()=>({VIEW_MODES,TreeGrid,h,setText,fill,numberFormat,foldText,cellText,cellValue,isCellObject,setAttr,toneOf,watchFlyout,densityRowHeight,MAX_PROTOCOL_INTEGER,LAYOUT_DENSITIES,plural,svgIcon});definePart(TreeGrid,"highlight","search highlighting",viewModeContext);definePart(TreeGrid,"layouts","layout modes",viewModeContext);const MODES_TOOLBAR=TreeGrid.prototype.buildToolbar;TreeGrid.prototype.buildToolbar=function(){MODES_TOOLBAR.call(this);if(this.highlightOptions||this.layoutOptions)this.modesReady=Promise.resolve(this.toolsReady).then(()=>this.destroyed||this.startViewModes());this.lifetime.signal.addEventListener("abort",()=>this.host.removeAttribute("data-cx-layout"),{once:true})};Object.assign(TreeGrid.prototype,{destroy(){if(this.destroyed)return;this.destroyed=true;for(const row of[...this.rendered.values(),...this.pool])disposeRowHostCells(row);this.lifetime.abort();this.dataLifetime.abort();if(this.queryController)this.queryController.abort();if(this.restoreController)this.restoreController.abort();if(this.cancelResize)this.cancelResize();clearTimeout(this.saveTimer);clearTimeout(this.layoutTimer);if(this.cancelSearch)this.cancelSearch();if(this.disposeSearchFlyout)this.disposeSearchFlyout();cancelAnimationFrame(this.rafId);this.resizeObserver.disconnect();if(this.detailObserver)this.detailObserver.disconnect();this.grid.removeEventListener("scroll",this.onScroll);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);global.removeEventListener("beforeprint",this.onPrint);global.removeEventListener("hashchange",this.onHash);global.removeEventListener("popstate",this.onHash);if(this.linkOpening)this.linkOpening.abort();[this.toolbar,this.grid,this.live,this.outline].forEach(element=>element.remove());this.host.classList.remove("cx-pin-tree");this.host.removeAttribute("data-cx-ready");this.host.removeAttribute("data-canopyx-mounted");this.keyMap.clear();this.selected.clear();this.rendered.clear();this.pool.length=0;if(this.inactiveCache)this.inactiveCache.clear();if(this.inlineRetained)this.inlineRetained.clear();this.rows=[];this.tops=[0];this.total=0;this.root.children=null;this.root.inlineCache=null;this.root.inlineOrder=null;this.focused=null;this.anchor=null;this.source=null;this.touchScroll=null;this.opts={};for(const column of this.columns)column.render=null;this.filter=null;this.declaredFilter=null;this.pendingRestorationToggles=null;this.scrolledCell=null;this.focusHandoff=null;this.cancelResize=null;this.cancelSearch=null;this.disposeSearchFlyout=null;this.canvas.replaceChildren();this.outline.replaceChildren()}});const ROW_HELPERS={};const GRID_REPORTING={};
|
|
601
|
+
.catch(error=>this.emit("error",{error}))))},getLayout(){return Object.freeze({mode:this.layoutMode,density:this.density,modes:this.layoutOptions?this.layoutOptions.modes:Object.freeze(["fit"])})},setLayout(change){if(!this.layoutOptions)return Promise.reject(new Error("CanopyX: this view declares no layout modes."));return this.requirePart("layouts").then(()=>VIEW_MODES.setLayout(this,change))},getMatches(){return VIEW_MODES.matches?VIEW_MODES.matches(this):Object.freeze({enabled:!!this.highlightOn,total:0,current:0,complete:true})},setSearchHighlight(enabled){if(typeof enabled!=="boolean")return Promise.reject(new Error("CanopyX: the highlight switch is a boolean."));if(!this.highlightOptions)return Promise.reject(new Error("CanopyX: this view declares no search highlighting."));return this.requirePart("highlight").then(()=>VIEW_MODES.setHighlight(this,enabled))},nextMatch(options){return this.stepMatch(1,options)},previousMatch(options){return this.stepMatch(-1,options)},stepMatch(direction,options){if(!this.highlightOptions)return Promise.reject(new Error("CanopyX: this view declares no search highlighting."));return this.requirePart("highlight").then(()=>VIEW_MODES.step(this,direction,options?.focus!==false))}};Object.assign(TreeGrid.prototype,VIEW_MODE_METHODS);const viewModeContext=()=>({VIEW_MODES,TreeGrid,h,setText,fill,numberFormat,foldText,cellText,cellValue,isCellObject,setAttr,toneOf,watchFlyout,densityRowHeight,MAX_PROTOCOL_INTEGER,LAYOUT_DENSITIES,plural,svgIcon});definePart(TreeGrid,"highlight","search highlighting",viewModeContext);definePart(TreeGrid,"layouts","layout modes",viewModeContext);const MODES_TOOLBAR=TreeGrid.prototype.buildToolbar;TreeGrid.prototype.buildToolbar=function(){MODES_TOOLBAR.call(this);if(this.highlightOptions||this.layoutOptions)this.modesReady=Promise.resolve(this.toolsReady).then(()=>this.destroyed||this.startViewModes());this.lifetime.signal.addEventListener("abort",()=>this.host.removeAttribute("data-cx-layout"),{once:true})};Object.assign(TreeGrid.prototype,{destroy(){if(this.destroyed)return;this.destroyed=true;for(const row of[...this.rendered.values(),...this.pool])disposeRowHostCells(row);this.lifetime.abort();this.dataLifetime.abort();if(this.queryController)this.queryController.abort();if(this.restoreController)this.restoreController.abort();if(this.cancelResize)this.cancelResize();clearTimeout(this.saveTimer);clearTimeout(this.layoutTimer);if(this.cancelSearch)this.cancelSearch();if(this.disposeSearchFlyout)this.disposeSearchFlyout();cancelAnimationFrame(this.rafId);this.resizeObserver.disconnect();if(this.detailObserver)this.detailObserver.disconnect();this.grid.removeEventListener("scroll",this.onScroll);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);global.removeEventListener("beforeprint",this.onPrint);global.removeEventListener("hashchange",this.onHash);global.removeEventListener("popstate",this.onHash);if(this.linkOpening)this.linkOpening.abort();[this.toolbar,this.grid,this.live,this.outline].forEach(element=>element.remove());this.host.classList.remove("cx-pin-tree");this.host.removeAttribute("data-cx-ready");this.host.removeAttribute("data-canopyx-mounted");this.keyMap.clear();this.selected.clear();this.rendered.clear();this.pool.length=0;if(this.inactiveCache)this.inactiveCache.clear();if(this.inlineRetained)this.inlineRetained.clear();this.rows=[];this.tops=[0];this.total=0;this.root.children=null;this.root.inlineCache=null;this.root.inlineOrder=null;this.focused=null;this.anchor=null;this.source=null;this.touchScroll=null;this.opts={};for(const column of this.columns)column.render=null;this.filter=null;this.declaredFilter=null;this.pendingRestorationToggles=null;this.scrolledCell=null;this.focusHandoff=null;this.cancelResize=null;this.cancelSearch=null;this.disposeSearchFlyout=null;this.canvas.replaceChildren();this.outline.replaceChildren()}});const ROW_HELPERS={};const GRID_REPORTING={};for(const name of["buildHeader","visibleColumns","applyWidths","setColumnWidth","startResize","cell","newCell","paintSlot","paintBadges","cellTip","paintHostSlot","setSlotContent","setTimeZone","rowCells","heldCell","restoreCell","focusCell","revealInRow","revealInCell","settleCell"])
|
|
602
|
+
ROW_HELPERS[name]=TreeGrid.prototype[name];function gridMomentFromParts(year,month,day,hours,minutes,seconds,local){const parts=[year,month,day,hours,minutes,seconds];if(!parts.every(Number.isInteger))return null;const moment=new Date(0),zone=local?"":"UTC";moment["set"+zone+"FullYear"](year,month-1,day);moment["set"+zone+"Hours"](hours,minutes,seconds,0);const actual=["FullYear","Month","Date","Hours","Minutes","Seconds"].map(name=>moment["get"+zone+name]());actual[1]++;return parts.every((value,index)=>value===actual[index])?moment:null}
|
|
601
603
|
function gridDateInputMoment(text,local){const match=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,3}))?)?$/.exec(text);
|
|
602
604
|
if(!match)return null;const moment=gridMomentFromParts(Number(match[1]),Number(match[2]),Number(match[3]),Number(match[4]),Number(match[5]),Number(match[6]||0),local);if(moment)moment.setTime(moment.getTime()+ Number((match[7]||"").padEnd(3,"0")));return moment}
|
|
603
605
|
function gridFreeze(value){if(value&&typeof value==="object"&&!Object.isFrozen(value)){Object.values(value).forEach(gridFreeze);Object.freeze(value)}
|
|
604
606
|
return value}
|
|
605
|
-
|
|
606
|
-
ROW_HELPERS[name]=TreeGrid.prototype[name];DEFAULT_LABELS=Object.freeze(Object.assign({},DEFAULT_LABELS,{gridSelectionCount:"{count} selected",gridClearSelection:"Clear selection",gridSelectionQueryUnknown:"All matching records selected; {excluded} excluded",gridFitContent:"Fit to content",gridUnpin:"Unpin",gridWhere:"Where",gridComplexFilter:"This column belongs to a mixed condition group. Edit it in Filters.",gridPinLeft:"Pin left",gridPinRight:"Pin right",gridResponsiveHidden:"Hidden at this width",gridFilterMatch:"Match",gridFilterAll:"All",gridFilterAny:"Any",gridDeleteFilterGroup:"Remove condition group",gridFacetSearch:"Search values",gridFacetChoose:"Choose a value",gridFacetCounts:"{count} matching rows; {shown} of {total} values.",gridTrue:"True",gridFalse:"False",gridHeaderFilter:"Filter {column}",gridClearColumnFilter:"Clear filter",gridSelectionAggregate:"Count: {count} · Sum: {sum} · Average: {average} · Minimum: {minimum} · Maximum: {maximum}",gridConditionValue:"Value",gridConditionUpperValue:"Upper value",gridDeleteCondition:"Remove condition",gridShowRowsWhere:"Show rows where",gridOfTheseAreTrue:"of these are true",gridOfThese:"of these",gridGroupCount:"{count} groups",gridMore:"More",gridDone:"Done",gridClearAll:"Clear all",gridRows:"rows",gridResultNoun:"{count} of {total} {noun}",gridSearchNoun:"Search {noun}",gridChart:"Chart",gridPrint:"Print",gridRowPicked:"Picked up {title}. Move to a calendar and press Enter to drop it.",gridColumnMenu:"Menu for {column}",gridSortAscending:"Sort ascending",gridSortDescending:"Sort descending",gridClearSort:"Clear sort",gridFilterColumn:"Filter…",gridHideColumn:"Hide column",gridGroupedBy:"Grouped by",gridRemoveGrouping:"Remove grouping",gridSelectAllValues:"Select all values",gridFilterValues:"Search values",gridAddCondition:"+ Condition",gridAddGroup:"+ Group",gridAnd:"and",gridOr:"or",gridEditAsText:"Edit as text",gridFilterText:"Filter expression",gridDeepFilters:"This saved filter has more than two nesting levels.",gridToday:"Today",gridYesterday:"Yesterday",gridLastSevenDays:"Last 7 days",gridLastThirtyDays:"Last 30 days",gridThisMonth:"This month",gridDateRange:"Range",gridEmpty:"No {noun}",gridEmptyReason:"There are no records to display.",gridNoMatches:"No matching {noun}",gridNoMatchesReason:"Search: {search}. Active filters: {count}.",gridRetry:"Retry",gridLoadFailed:"Could not load records",gridAll:"All",gridPageOf:"{page} of {pages}",gridStatusCount:"{count} {noun} · {selected} selected",gridDetailsSection:"Details",gridPreviousRecord:"Previous record",gridNextRecord:"Next record",gridCloseRecord:"Close record details",gridShowMore:"Show more",gridNoData:"No data",gridPeriodRange:"{from}–{to}: {state}",}));const GRID_ICONS={search:'<circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/>',filter:'<path d="M4 5h16l-6 7.5V19l-4-2v-4.5z"/>',columns:'<rect x="3.5" y="4.5" width="17" height="15" rx="2"/><path d="M9.5 4.5v15M14.5 4.5v15"/>',views:'<path d="M6 4h12v16l-6-4-6 4z"/>',export:'<path d="M12 4v11M7.5 10.5 12 15l4.5-4.5M5 19h14"/>',more:'<circle cx="5" cy="12" r="1.2"/><circle cx="12" cy="12" r="1.2"/><circle cx="19" cy="12" r="1.2"/>',close:'<path d="M6 6l12 12M18 6 6 18"/>',check:'<path d="m5 12.5 4.5 4.5L19 7.5"/>',chart:'<path d="M4 19h16M7 16V10M12 16V6M17 16v-4"/>',copy:'<rect x="8" y="8" width="11" height="11" rx="2"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/>',up:'<path d="M12 19V5M6 11l6-6 6 6"/>',down:'<path d="M12 5v14M6 13l6 6 6-6"/>',retry:'<path d="M4 12a8 8 0 1 0 2.4-5.7M4 4v4.5h4.5"/>',previous:'<path d="m14 7-5 5 5 5"/>',next:'<path d="m10 7 5 5-5 5"/>',first:'<path d="m13 7-5 5 5 5M17 7l-5 5 5 5"/>',last:'<path d="m11 7 5 5-5 5M7 7l5 5-5 5"/>'};function gridIcon(name,shapes){return svgIcon(shapes||GRID_ICONS[name]||GRID_ICONS.more)}
|
|
607
|
+
DEFAULT_LABELS=Object.freeze(Object.assign({},DEFAULT_LABELS,{gridSelectionCount:"{count} selected",gridClearSelection:"Clear selection",gridSelectionQueryUnknown:"All matching records selected; {excluded} excluded",gridFitContent:"Fit to content",gridUnpin:"Unpin",gridWhere:"Where",gridComplexFilter:"This column belongs to a mixed condition group. Edit it in Filters.",gridPinLeft:"Pin left",gridPinRight:"Pin right",gridResponsiveHidden:"Hidden at this width",gridFilterMatch:"Match",gridFilterAll:"All",gridFilterAny:"Any",gridDeleteFilterGroup:"Remove condition group",gridFacetSearch:"Search values",gridFacetChoose:"Choose a value",gridFacetCounts:"{count} matching rows; {shown} of {total} values.",gridTrue:"True",gridFalse:"False",gridHeaderFilter:"Filter {column}",gridClearColumnFilter:"Clear filter",gridSelectionAggregate:"Count: {count} · Sum: {sum} · Average: {average} · Minimum: {minimum} · Maximum: {maximum}",gridConditionValue:"Value",gridConditionUpperValue:"Upper value",gridDeleteCondition:"Remove condition",gridShowRowsWhere:"Show rows where",gridOfTheseAreTrue:"of these are true",gridOfThese:"of these",gridGroupCount:"{count} groups",gridMore:"More",gridDone:"Done",gridClearAll:"Clear all",gridRows:"rows",gridResultNoun:"{count} of {total} {noun}",gridSearchNoun:"Search {noun}",gridChart:"Chart",gridPrint:"Print",gridRowPicked:"Picked up {title}. Move to a calendar and press Enter to drop it.",gridColumnMenu:"Menu for {column}",gridSortAscending:"Sort ascending",gridSortDescending:"Sort descending",gridClearSort:"Clear sort",gridFilterColumn:"Filter…",gridHideColumn:"Hide column",gridGroupedBy:"Grouped by",gridRemoveGrouping:"Remove grouping",gridSelectAllValues:"Select all values",gridFilterValues:"Search values",gridAddCondition:"+ Condition",gridAddGroup:"+ Group",gridAnd:"and",gridOr:"or",gridEditAsText:"Edit as text",gridFilterText:"Filter expression",gridDeepFilters:"This saved filter has more than two nesting levels.",gridToday:"Today",gridYesterday:"Yesterday",gridLastSevenDays:"Last 7 days",gridLastThirtyDays:"Last 30 days",gridThisMonth:"This month",gridDateRange:"Range",gridEmpty:"No {noun}",gridEmptyReason:"There are no records to display.",gridNoMatches:"No matching {noun}",gridNoMatchesReason:"Search: {search}. Active filters: {count}.",gridRetry:"Retry",gridLoadFailed:"Could not load records",gridAll:"All",gridPageOf:"{page} of {pages}",gridStatusCount:"{count} {noun} · {selected} selected",gridDetailsSection:"Details",gridPreviousRecord:"Previous record",gridNextRecord:"Next record",gridCloseRecord:"Close record details",gridShowMore:"Show more",gridNoData:"No data",gridPeriodRange:"{from}–{to}: {state}",}));const GRID_ICONS={search:'<circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/>',filter:'<path d="M4 5h16l-6 7.5V19l-4-2v-4.5z"/>',columns:'<rect x="3.5" y="4.5" width="17" height="15" rx="2"/><path d="M9.5 4.5v15M14.5 4.5v15"/>',views:'<path d="M6 4h12v16l-6-4-6 4z"/>',export:'<path d="M12 4v11M7.5 10.5 12 15l4.5-4.5M5 19h14"/>',more:'<circle cx="5" cy="12" r="1.2"/><circle cx="12" cy="12" r="1.2"/><circle cx="19" cy="12" r="1.2"/>',close:'<path d="M6 6l12 12M18 6 6 18"/>',check:'<path d="m5 12.5 4.5 4.5L19 7.5"/>',chart:'<path d="M4 19h16M7 16V10M12 16V6M17 16v-4"/>',copy:'<rect x="8" y="8" width="11" height="11" rx="2"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/>',up:'<path d="M12 19V5M6 11l6-6 6 6"/>',down:'<path d="M12 5v14M6 13l6 6 6-6"/>',retry:'<path d="M4 12a8 8 0 1 0 2.4-5.7M4 4v4.5h4.5"/>',previous:'<path d="m14 7-5 5 5 5"/>',next:'<path d="m10 7 5 5-5 5"/>',first:'<path d="m13 7-5 5 5 5M17 7l-5 5 5 5"/>',last:'<path d="m11 7 5 5-5 5M7 7l5 5-5 5"/>'};function gridIcon(name,shapes){return svgIcon(shapes||GRID_ICONS[name]||GRID_ICONS.more)}
|
|
607
608
|
function gridDecorateButton(button,icon,ghost){button.classList.add("cx-btn");if(ghost)button.classList.add("ghost");if(icon)button.prepend(gridIcon(icon));return button}
|
|
608
609
|
function gridFilterCount(query){const count=group=>group?group.filters.length+group.groups.reduce((sum,child)=>sum+count(child),0):0;return(query?.filters?.length||0)+ count(query?.filterGroup)}
|
|
609
610
|
const GRID_FILTER_LABELS={eq:"=",ne:"≠",contains:"gridContains",startsWith:"gridStartsWith",in:"gridIn",gt:">",ge:"≥",lt:"<",le:"≤",isNull:"gridIsNull",isNotNull:"gridIsNotNull"};function gridQueryRecord(input,record,strict,cursor){if(strict&&Object.keys(input).some(key=>!Object.hasOwn(record,key)&&!(cursor&&key==="offset")))throw new Error("CanopyX: invalid state query.");return gridFreeze(record)}
|
|
@@ -936,7 +937,7 @@ for(const field of CAL_FIELDS)if(field!=="allDay"&&event[field]!=null){cells[fie
|
|
|
936
937
|
return{id,cells}});if(options.resources)used.add("resource");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:"text",hidden:field!=="description",editable:writable&&(field==="resource"||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})}
|
|
937
938
|
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)}
|
|
938
939
|
return roots}
|
|
939
|
-
const GRID_EDITING=definePart(DataGrid,"editing","editing",()=>({DataGrid,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:"Filter by",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,cellText,foldText,numberFormat,gridCellRenderer,gridFreeze}));Object.assign(DataGrid.prototype,{loadFacets(){return this.facetLoad||=loadPart(GRID_FACETS).then(()=>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")
|
|
940
|
+
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:"Filter by",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,cellText,foldText,numberFormat,gridCellRenderer,gridFreeze}));Object.assign(DataGrid.prototype,{loadFacets(){return this.facetLoad||=loadPart(GRID_FACETS).then(()=>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")
|
|
940
941
|
throw new Error("CanopyX: invalid saved facet panel state.");if(this.view.facets||this.opts.facets)state.facets={open:facets.open}}
|
|
941
942
|
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}
|
|
942
943
|
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,numberFormat,gridButton,gridOption,gridInputLabel,gridIcon,gridDecorateButton,GRID_REPORTING,loadPart,definePart,announceMenu,boundedPattern,wildcardMatch,svgIcon}));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,validateGridRows,validateGridPage,validateGridCursorPage,gridFreeze,requireIdentifier,checkDocument,cellValue,PROTOCOL,GRID_REPORTING,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(){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_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())
|
|
@@ -1123,7 +1124,10 @@ clearDropRow(){if(this.dropRow){this.dropRow.classList.remove("cx-drop-target");
|
|
|
1123
1124
|
this.dropRow=null}
|
|
1124
1125
|
dropPlacement(event,row){const bounds=row.getBoundingClientRect(),fraction=(event.clientY-bounds.top)/ bounds.height;
|
|
1125
1126
|
return fraction<0.25?"before":fraction>0.75?"after":"inside"}
|
|
1126
|
-
destroy(){this.clearDropRow();this.dragLease=null;super.destroy()}};
|
|
1127
|
+
destroy(){this.clearDropRow();this.dragLease=null;super.destroy()}};class FlowHost{}
|
|
1128
|
+
const FORMS_IMPL={},FLOW_IMPL={},activeFlows=new WeakMap();const FORMS_PART=definePart(FlowHost,"forms","forms",()=>({FORMS_IMPL,h,setText,fill,gridFreeze,gridMomentFromParts,boundedPattern,foldText}));const FLOW_PART=definePart(FlowHost,"flow","flow view",()=>({FLOW_IMPL,FORMS_IMPL,h,setText,fill,plural,foldText,boundedPattern,numberFormat,gridFreeze}));if(typeof DataGrid==="function")DataGrid.prototype.parts.forms=FORMS_PART;const FLOW_ASYNC_METHODS=["next","back","goTo","setState","validate","submit"];const FLOW_SYNC_METHODS=["getStep","getValues","setValues","getState","isDirty","reset","setFieldError","setProgress","complete"];function createFlow(host,options){if(!host||!options||!options.flow||typeof options.flow!=="object")throw new Error("CanopyX: createFlow needs a host element and a flow document.");const existing=activeFlows.get(host);if(existing)return existing;let impl=null,destroyed=false,mountError=null;const destroyedError=()=>new Error("CanopyX: this flow has been destroyed.");const requireImpl=name=>{if(destroyed)throw destroyedError();if(!impl)throw new Error("CanopyX: flow is not ready; await api.ready before calling "+name+"().");return impl};const editors=Object.assign({},...[...PLUGINS.values()].map(item=>item.editors||{}));const ready=loadPart(FLOW_PART).then(()=>{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;try{impl?.destroy()}
|
|
1129
|
+
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}
|
|
1130
|
+
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.")}
|
|
1127
1131
|
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"])
|
|
1128
1132
|
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);
|
|
1129
1133
|
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}
|
|
@@ -1137,5 +1141,5 @@ watcher.observe(host)}
|
|
|
1137
1141
|
function mount(root,automatic){const scope=root||document;const created=[];const showError=(host,err,api,view)=>{if(api){api.destroy();if(host.canopyx===api)delete host.canopyx}
|
|
1138
1142
|
const message=err&&err.message?err.message:String(err);let labels=DEFAULT_LABELS;for(const attempt of[()=>labelsFor(view&&view.labels,view&&configured.has(view.id)?configured.get(view.id).labels:null),()=>labelsFor(view&&view.labels)]){try{labels=attempt();break}catch(e){labels=DEFAULT_LABELS}}
|
|
1139
1143
|
const notice=document.createElement("div");notice.className="cx-mount-error";notice.setAttribute("role","alert");setText(notice,fill(labels.mountError,{error:message}));host.classList.add("cx-host");host.setAttribute("data-canopyx-mounted","true");host.setAttribute("data-cx-error",message);host.appendChild(notice);if(global.console)global.console.error(err)};const selector="[data-canopyx-host]:not([data-canopyx-mounted])";(scope.matches?.(selector)?[scope]:scope.querySelectorAll(selector)).forEach((host)=>{const config=host.querySelector("script.cx-config"),mode=host.getAttribute("data-cx-mount");if(!config||(automatic===true&&mode==="manual")){return}
|
|
1140
|
-
if(mode==="visible"&&host!==scope&&global.IntersectionObserver)return mountWhenVisible(host);watcher?.unobserve(host);host.setAttribute("data-canopyx-mounted","true");let view=null;try{view=JSON.parse(config.textContent);if(view===Object(view))parsedViews.add(view);const create=view&&view.type==="grid"&&typeof createDataGrid==="function"?createDataGrid:createTreeGrid;const api=create(host,Object.assign({},view&&configured.get(view.id),{view}));created.push(api);api.ready.catch((err)=>{if(view.type!=="grid"&&activeGrids.get(host)===api&&host.canopyx===api)showError(host,err,api,view)})}catch(err){showError(host,err,null,view)}});return created}
|
|
1141
|
-
global.CanopyX=Object.freeze(Object.assign({protocol:PROTOCOL,createTreeGrid,configure,unconfigure,mount:(root)=>mount(root,false),sources:Object.freeze({inline:inlineSource,sidecar:sidecarSource,remote:remoteSource}),badge:hostBadge,labels:DEFAULT_LABELS,registerExportFormat,use,registerPart,setNonce},typeof GRID_API==="object"?GRID_API:{}));if(typeof document!=="undefined"){const navigation=global.performance&&performance.getEntriesByType?performance.getEntriesByType("navigation")[0]:null;if(document.readyState==="loading"||(document.readyState==="interactive"&&navigation&&navigation.domContentLoadedEventStart===0)){document.addEventListener("DOMContentLoaded",()=>mount(document,true))}else{mount(document,true)}}})(runtimeHost);const CanopyX=runtimeHost.CanopyX;const{protocol,createTreeGrid,createDataGrid,createCalendar,enhance,grid,configure,unconfigure,mount,sources,badge,labels,registerExportFormat,use,registerPart,setNonce}=CanopyX;export{protocol,createTreeGrid,createDataGrid,createCalendar,enhance,grid,configure,unconfigure,mount,sources,badge,labels,registerExportFormat,use,registerPart,setNonce};export default CanopyX;
|
|
1144
|
+
if(mode==="visible"&&host!==scope&&global.IntersectionObserver)return mountWhenVisible(host);watcher?.unobserve(host);host.setAttribute("data-canopyx-mounted","true");let view=null;try{view=JSON.parse(config.textContent);if(view===Object(view))parsedViews.add(view);const flow=view&&view.kind==="flow"&&typeof FLOW_API==="object";const create=flow?FLOW_API.createFlow:view&&view.type==="grid"&&typeof createDataGrid==="function"?createDataGrid:createTreeGrid;const api=create(host,Object.assign({},view&&configured.get(view.id),flow?{flow:view}:{view}));created.push(api);api.ready.catch((err)=>{if(view.type!=="grid"&&activeGrids.get(host)===api&&host.canopyx===api)showError(host,err,api,view)})}catch(err){showError(host,err,null,view)}});return created}
|
|
1145
|
+
global.CanopyX=Object.freeze(Object.assign({protocol:PROTOCOL,createTreeGrid,configure,unconfigure,mount:(root)=>mount(root,false),sources:Object.freeze({inline:inlineSource,sidecar:sidecarSource,remote:remoteSource}),badge:hostBadge,labels:DEFAULT_LABELS,registerExportFormat,use,registerPart,setNonce},typeof GRID_API==="object"?GRID_API:{},typeof FLOW_API==="object"?FLOW_API:{}));if(typeof document!=="undefined"){const navigation=global.performance&&performance.getEntriesByType?performance.getEntriesByType("navigation")[0]:null;if(document.readyState==="loading"||(document.readyState==="interactive"&&navigation&&navigation.domContentLoadedEventStart===0)){document.addEventListener("DOMContentLoaded",()=>mount(document,true))}else{mount(document,true)}}})(runtimeHost);const CanopyX=runtimeHost.CanopyX;const{protocol,createTreeGrid,createDataGrid,createCalendar,createFlow,enhance,grid,configure,unconfigure,mount,sources,badge,labels,registerExportFormat,use,registerPart,setNonce}=CanopyX;export{protocol,createTreeGrid,createDataGrid,createCalendar,createFlow,enhance,grid,configure,unconfigure,mount,sources,badge,labels,registerExportFormat,use,registerPart,setNonce};export default CanopyX;
|
|
@@ -574,3 +574,5 @@ body .cx-host.cx-chrome{padding:0;}
|
|
|
574
574
|
.cx-phone .cx-hcell :is(.cx-grid-column-menu,.cx-grid-header-filter){min-width:var(--cx-size-44px);min-height:var(--cx-size-44px);}
|
|
575
575
|
.cx-grid-overlay :focus-visible{outline:var(--cx-size-2px) solid var(--cx-accent);outline-offset:var(--cx-size-2px);}
|
|
576
576
|
.cx-grid-overlay [data-cx-pointer-focus]:focus-visible{outline:none;}
|
|
577
|
+
.cx-host.cx-flow-host{min-height:0;display:block;background:transparent;}
|
|
578
|
+
.cx-host:where(.cx-flow-host:not([data-cx-height])){height:auto;}
|
|
@@ -55,15 +55,15 @@ return{rank:1,value:String(value)}}
|
|
|
55
55
|
function compareKeys(a,b,direction){if(a.rank!==b.rank){return a.rank-b.rank}
|
|
56
56
|
if(a.rank===2){return 0}
|
|
57
57
|
const order=a.rank===0?(a.value<b.value?-1:a.value>b.value?1:0):collator.compare(a.value,b.value);return order*direction}
|
|
58
|
-
let DEFAULT_LABELS=Object.freeze({searchPlaceholder:"Search",searchResults:"Search results",searchResultCount:"{count} results",searchResultCountOfTotal:"{count} of {total} results",searchResultCountOfMany:"{count} of many results",searchNoResults:"No results",searchTooShort:"Type at least {min} characters",searchWordTooShort:"Type a word of at least {min} characters",searchFailed:"Search failed: {error}",columns:"Columns",visibleColumns:"Visible columns",resizeColumn:"Resize {column}",columnWidth:"{width} pixels",loading:"Loading…",loadError:"Could not load: {error} (Enter to retry)",queryFailed:"Could not update the view: {error}",showMore:"Show more ({loaded} of {total} loaded)",showMoreUnknownTotal:"Show more ({loaded} loaded)",pageLoaded:"{loaded} of {total} loaded",itemsLoaded:"{count} items",yes:"Yes",no:"No",utcTime:"{time} UTC",localTime:"{time} local time",mountError:"This view could not be displayed: {error}"});function labelsFor(...sources){const labels=Object.assign({},DEFAULT_LABELS);for(const source of sources){if(source==null)continue;if(typeof source!=="object"||Array.isArray(source))throw new Error("CanopyX: labels must be an object of strings.");Object.keys(source).forEach((name)=>{if(!Object.hasOwn(DEFAULT_LABELS,name)&&!/^(?:gridEdit|format|calendar)[A-Z]\w{0,63}$/.test(name)) throw new Error("CanopyX: there is no label '" + name + "'.");
|
|
59
|
-
if(typeof source[name]!=="string"||!/\S/.test(source[name])) throw new Error("CanopyX: label '" + name + "' must be a string with visible text.");
|
|
60
|
-
if((name==="utcTime"||name==="localTime")&&source[name].indexOf("{time}")<0)throw new Error("CanopyX: label '"+name+"' must hold {time}.");labels[name]=source[name]})}
|
|
61
|
-
return Object.freeze(labels)}
|
|
62
58
|
function fill(template,values){return template.replace(/\{(\w+)\}/g, (match, name) => (values && Object.hasOwn(values, name) ? String(values[name]) : match));
|
|
63
59
|
}
|
|
64
60
|
const pluralRules=new Map();function plural(template,count,lang){if(!template.startsWith("["))return template;const forms={};for(const match of template.matchAll(/\[(zero|one|two|few|many|other)\]([^[]*)/g)) forms[match[1]] = match[2];
|
|
65
61
|
let rules=pluralRules.get(lang);if(!rules){try{rules=new Intl.PluralRules(lang||"en")}catch(_){rules=new Intl.PluralRules("en")}pluralRules.set(lang,rules)}
|
|
66
62
|
return forms[rules.select(Number(count))]??forms.other??template}
|
|
63
|
+
let DEFAULT_LABELS=Object.freeze({searchPlaceholder:"Search",searchResults:"Search results",searchResultCount:"{count} results",searchResultCountOfTotal:"{count} of {total} results",searchResultCountOfMany:"{count} of many results",searchNoResults:"No results",searchTooShort:"Type at least {min} characters",searchWordTooShort:"Type a word of at least {min} characters",searchFailed:"Search failed: {error}",columns:"Columns",visibleColumns:"Visible columns",resizeColumn:"Resize {column}",columnWidth:"{width} pixels",loading:"Loading…",loadError:"Could not load: {error} (Enter to retry)",queryFailed:"Could not update the view: {error}",showMore:"Show more ({loaded} of {total} loaded)",showMoreUnknownTotal:"Show more ({loaded} loaded)",pageLoaded:"{loaded} of {total} loaded",itemsLoaded:"{count} items",yes:"Yes",no:"No",utcTime:"{time} UTC",localTime:"{time} local time",mountError:"This view could not be displayed: {error}"});function labelsFor(...sources){const labels=Object.assign({},DEFAULT_LABELS);for(const source of sources){if(source==null)continue;if(typeof source!=="object"||Array.isArray(source))throw new Error("CanopyX: labels must be an object of strings.");Object.keys(source).forEach((name)=>{if(!Object.hasOwn(DEFAULT_LABELS,name)&&!/^(?:gridEdit|format|calendar|flow)[A-Z]\w{0,63}$/.test(name)) throw new Error("CanopyX: there is no label '" + name + "'.");
|
|
64
|
+
if(typeof source[name]!=="string"||!/\S/.test(source[name])) throw new Error("CanopyX: label '" + name + "' must be a string with visible text.");
|
|
65
|
+
if((name==="utcTime"||name==="localTime")&&source[name].indexOf("{time}")<0)throw new Error("CanopyX: label '"+name+"' must hold {time}.");labels[name]=source[name]})}
|
|
66
|
+
return Object.freeze(labels)}
|
|
67
67
|
const numberFormats=new Map();function numberFormat(lang,minimum=0,maximum=3){const key=(lang||"")+ "|"+minimum+"|"+maximum;let format=numberFormats.get(key);if(!format){const digits={minimumFractionDigits:minimum,maximumFractionDigits:maximum};try{format=new Intl.NumberFormat(lang||undefined,digits)}catch(e){format=new Intl.NumberFormat(undefined,digits)}
|
|
68
68
|
if(numberFormats.size>=16)numberFormats.delete(numberFormats.keys().next().value);numberFormats.set(key,format)}
|
|
69
69
|
return format}
|
|
@@ -486,8 +486,9 @@ items.push(...page.items);total=page.total;next=page.next||null;if(next&&(next==
|
|
|
486
486
|
fill(this.labels.itemsLoaded,{count:count.format(items.length)}));this.stateChanged()}});const EXPORT_FORMATS=new Map(),EXPORT_IMPL={},exportFormatId=id=>typeof id==="string"&&/^[a-z][a-z\d-]{0,31}$/.test(id);
|
|
487
487
|
const exportFormatIds=list=>Array.isArray(list)&&new Set(list).size===list.length&&list.every(exportFormatId);function exportFormat(format){if(!format||!exportFormatId(format.id)||format.id==="csv"||
|
|
488
488
|
typeof format.label!=="string"||!format.label.trim()||typeof format.extension!=="string"||!/^[a-z\d]{1,16}$/i.test(format.extension) ||
|
|
489
|
-
format.mime!==undefined&&typeof format.mime!=="string"||
|
|
490
|
-
|
|
489
|
+
format.mime!==undefined&&typeof format.mime!=="string"||
|
|
490
|
+
format.showInMenu!==undefined&&typeof format.showInMenu!=="boolean"||typeof format.write!=="function")
|
|
491
|
+
throw new Error("CanopyX: invalid export format.");return Object.freeze({id:format.id,label:format.label,extension:format.extension,mime:format.mime||"application/octet-stream",showInMenu:format.showInMenu!==false,write:format.write})}
|
|
491
492
|
function registerExportFormat(format){format=exportFormat(format);EXPORT_FORMATS.set(format.id,format);return()=>EXPORT_FORMATS.get(format.id)===format&&EXPORT_FORMATS.delete(format.id)}
|
|
492
493
|
EXPORT_IMPL.formatsOf=function(grid){const list=grid.opts.exportFormats??grid.view.exportFormats,known=new Map(EXPORT_FORMATS);for(const format of grid.plugins.filter(item=>(grid.opts.plugins||[]).some(local=>local.name===item.name))
|
|
493
494
|
.flatMap(item=>item.exportFormats||[]))known.set(format.id,exportFormat(format));if(list===undefined)return[...known.values()];const formats=Array.isArray(list)?list.map(item=>typeof item==="string"?known.get(item):exportFormat(item)).filter(Boolean):null;if(!formats||new Set(formats.map(format=>format.id)).size!==formats.length)throw new Error("CanopyX: invalid exportFormats.");return formats};function exportTimeout(grid,options){const timeout=options?.timeoutMs??grid.opts.exportTimeoutMs??600000;if(!Number.isInteger(timeout)||timeout<1||timeout>2147483647)throw new Error("CanopyX: invalid export timeout.");return timeout}
|
|
@@ -503,7 +504,7 @@ if(active>=0){list.children[active].setAttribute("aria-selected","false")}
|
|
|
503
504
|
active=active<0?(delta<0?hits.length-1:0):(active+delta+hits.length)%hits.length;const item=list.children[active];item.setAttribute("aria-selected","true");input.setAttribute("aria-activedescendant",item.id);item.scrollIntoView({block:"nearest"})};input.addEventListener("input",()=>{cancelNavigation();sequence++;clearTimeout(timer);hits=[];close();timer=setTimeout(run,150)});input.addEventListener("keydown",(e)=>{if(e.defaultPrevented||e.isComposing)return;if(e.key==="ArrowDown"||e.key==="ArrowUp"){move(e.key==="ArrowDown"?1:-1)}else if(e.key==="Enter"){if(!list.hidden){choose(active>=0?active:0)}}else if(e.key==="Escape"){cancelNavigation();sequence++;clearTimeout(timer);if(list.hidden){input.value=""}
|
|
504
505
|
close()}else{return}
|
|
505
506
|
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 position=()=>{if(!isOpen())return;const anchor=anchorElement.getBoundingClientRect(),fixed=getComputedStyle(panel).position==="fixed";const below=Math.max(0,global.innerHeight-anchor.bottom-8);const above=Math.max(0,anchor.top-8);const opensAbove=below<120&&above>below,room=opensAbove?above:below;panel.style.maxHeight=(panel.classList.contains("cx-fb")?room:Math.min(320,room))+ "px";panel.style.top=opensAbove?"auto":fixed?anchor.bottom+"px":"100%";panel.style.bottom=opensAbove?fixed?global.innerHeight-anchor.top+"px":"100%":"auto";const width=panel.getBoundingClientRect().width;panel.style.left=Math.max(8,Math.min(anchor.left,global.innerWidth-width-8))-(fixed?0:anchor.left)+ "px"};global.addEventListener("resize",position);global.addEventListener("scroll",position,true);return{position,dispose:()=>{global.removeEventListener("resize",position);global.removeEventListener("scroll",position,true)}}}
|
|
506
|
-
const PART_URL=typeof document!=="undefined"&&document.currentScript?.src;const PARTS={"tree-tools":["ce442e100494535d","canopyx-tree-tools.149c371950d66a15.js","canopyx-tree-tools.ef7a3fb9c9115a82.css"],"filter-editor":["99cafeec3da59ffa","canopyx-filter-editor.7d9a82809044997b.js","canopyx-filter-editor.01b7bb6820dc9edb.css"],"export":["
|
|
507
|
+
const PART_URL=typeof document!=="undefined"&&document.currentScript?.src;const PARTS={"tree-tools":["ce442e100494535d","canopyx-tree-tools.149c371950d66a15.js","canopyx-tree-tools.ef7a3fb9c9115a82.css"],"filter-editor":["99cafeec3da59ffa","canopyx-filter-editor.7d9a82809044997b.js","canopyx-filter-editor.01b7bb6820dc9edb.css"],"export":["8b99c0b7b0ec37c5","canopyx-export.6989ea36f5d6da7b.js"],"history":["7d9901d2fe04df72","canopyx-history.9432e724bf14c9ed.js"],"pager":["8f804f70b96409f2","canopyx-pager.ac543250cf2f6e8b.js","canopyx-pager.08ad67c69026852e.css"],"enhance":["31162b1ffa622bf8","canopyx-enhance.65868addbc5c4a1a.js"],"data":["40fe19a1046d6813","canopyx-data.30d9664c5ef24288.js"],"forms":["a8c60f205d9babca","canopyx-forms.16987de1cdf9bda9.js","canopyx-forms.29058ce3c88af96e.css"],"flow":["75b9643b282dddb7","canopyx-flow.52d8d6168378df0c.js","canopyx-flow.3152e616c5557452.css"],"editing":["c82648dfaa7e5ee5","canopyx-editing.4fe83feec389c2ce.js","canopyx-editing.67c43d3b80f20232.css"],"column-groups":["b42238fd108a8614","canopyx-column-groups.d8ad6322f769b915.js","canopyx-column-groups.37e177d74cebb516.css"],"cell-range":["e99a39e7cccc57b1","canopyx-cell-range.647da96e57924f3e.js","canopyx-cell-range.23f3222652588441.css"],"links":["f1ab7e32b501ce37","canopyx-links.d96addeefb3eccf5.js"],"search":["521eebd6e1bbbd35","canopyx-search.14c69f4551c69f23.js"],"formatting":["6f9f3c51b0ad2a0e","canopyx-formatting.83a489f9fe5ff09c.js","canopyx-formatting.a59507e4e8334891.css"],"format-editor":["24f176a39c02944a","canopyx-format-editor.3b1dec2527e53988.js","canopyx-format-editor.1ba153c82aa87b04.css"],"link":["fa0c9e888463553b","canopyx-link.4ec39bc39fa6cf50.js","canopyx-link.8435c892613926ac.css"],"detail-rows":["6c96974326d65a4c","canopyx-detail-rows.a267cf8361634006.js","canopyx-detail-rows.8e38a8ad01fded76.css"],"grouping":["d942108ffbc023b6","canopyx-grouping.1387fa5fa1374471.js","canopyx-grouping.6c93259b4b89e523.css"],"highlight":["f39423961654c1e2","canopyx-highlight.a6f93893d36ab343.js","canopyx-highlight.5b6d2e0d979f9f9b.css"],"layouts":["fa8c686f21626884","canopyx-layouts.e7250c82a6abf52e.js","canopyx-layouts.0b75738924533ee8.css"],"facets":["f9219d35a87635f8","canopyx-facets.8bf477b7915bdcd6.js","canopyx-facets.648a88d2f36d4999.css"],"live":["2fa02b9178c6c5df","canopyx-live.b53c60db00f9caf9.js","canopyx-live.cc4b94a2dec6f064.css"],"record-panel":["bcc06276c7933af6","canopyx-record-panel.a374fb4254f9115c.js","canopyx-record-panel.f3691d54cefaab04.css"],"calendar":["2f44e057443bc649","canopyx-calendar.9dda223f0fe4597e.js","canopyx-calendar.1099197a45632f63.css"],"calendar-recurrence":["64bcc24d785bd1af","canopyx-calendar-recurrence.4b7f430c2a64de23.js"],"calendar-edit":["bdde26d4b7de2096","canopyx-calendar-edit.4ab2cf55e84f310f.js"],"calendar-ics":["feb3ed2cd67d057f","canopyx-calendar-ics.2a3af9eb3bf444fc.js"],"timeline":["3f04ba99401e9ebd","canopyx-timeline.76928f089774b3de.js","canopyx-timeline.0393f92746f8fa09.css"]},PART_CODE=new Map(),partName=name=>typeof name==="string"&&/^[a-z][a-z\d-]{0,31}$/.test(name);
|
|
507
508
|
function registerPart(name,part){if(!partName(name)||!part||typeof part.version!=="string"||typeof part.install!=="function"||
|
|
508
509
|
part.requires!==undefined&&!(Array.isArray(part.requires)&&part.requires.every(partName)))throw new Error("CanopyX: invalid part.");PART_CODE.set(name,part)}
|
|
509
510
|
function definePart(View,name,label,context){const parts=View.prototype.parts||={};return parts[name]={name,label,context,parts}}
|
|
@@ -595,13 +596,13 @@ const VIEW_MODE_METHODS={prepareViewModes(){const view=this.view,columns=this.co
|
|
|
595
596
|
if(choice.highlight!==undefined)this.highlightOn=choice.highlight;this.rowH=densityRowHeight(this,this.density);if(this.layoutMode==="fit")this.host.removeAttribute("data-cx-layout");else this.host.setAttribute("data-cx-layout",this.layoutMode)},modeState(state){if(this.layoutOptions)state.layout={mode:this.layoutMode,density:this.density};if(this.highlightOptions)state.highlight=!!this.highlightOn;return state},applyModeState(state){if(state.layout&&(state.layout.mode!==this.layoutMode||state.layout.density!==this.density))
|
|
596
597
|
this.setLayout(state.layout).catch(error=>this.emit("error",{error}));if(state.highlight!==undefined&&state.highlight!==!!this.highlightOn)
|
|
597
598
|
this.setSearchHighlight(state.highlight).catch(error=>this.emit("error",{error}))},startViewModes(){const parts=[this.highlightOptions&&"highlight",this.layoutOptions&&"layouts"].filter(Boolean);return Promise.all(parts.map(name=>this.requirePart(name).then(()=>this.destroyed||VIEW_MODES[name+"Start"](this))
|
|
598
|
-
.catch(error=>this.emit("error",{error}))))},getLayout(){return Object.freeze({mode:this.layoutMode,density:this.density,modes:this.layoutOptions?this.layoutOptions.modes:Object.freeze(["fit"])})},setLayout(change){if(!this.layoutOptions)return Promise.reject(new Error("CanopyX: this view declares no layout modes."));return this.requirePart("layouts").then(()=>VIEW_MODES.setLayout(this,change))},getMatches(){return VIEW_MODES.matches?VIEW_MODES.matches(this):Object.freeze({enabled:!!this.highlightOn,total:0,current:0,complete:true})},setSearchHighlight(enabled){if(typeof enabled!=="boolean")return Promise.reject(new Error("CanopyX: the highlight switch is a boolean."));if(!this.highlightOptions)return Promise.reject(new Error("CanopyX: this view declares no search highlighting."));return this.requirePart("highlight").then(()=>VIEW_MODES.setHighlight(this,enabled))},nextMatch(options){return this.stepMatch(1,options)},previousMatch(options){return this.stepMatch(-1,options)},stepMatch(direction,options){if(!this.highlightOptions)return Promise.reject(new Error("CanopyX: this view declares no search highlighting."));return this.requirePart("highlight").then(()=>VIEW_MODES.step(this,direction,options?.focus!==false))}};Object.assign(TreeGrid.prototype,VIEW_MODE_METHODS);const viewModeContext=()=>({VIEW_MODES,TreeGrid,h,setText,fill,numberFormat,foldText,cellText,cellValue,isCellObject,setAttr,toneOf,watchFlyout,densityRowHeight,MAX_PROTOCOL_INTEGER,LAYOUT_DENSITIES,plural,svgIcon});definePart(TreeGrid,"highlight","search highlighting",viewModeContext);definePart(TreeGrid,"layouts","layout modes",viewModeContext);const MODES_TOOLBAR=TreeGrid.prototype.buildToolbar;TreeGrid.prototype.buildToolbar=function(){MODES_TOOLBAR.call(this);if(this.highlightOptions||this.layoutOptions)this.modesReady=Promise.resolve(this.toolsReady).then(()=>this.destroyed||this.startViewModes());this.lifetime.signal.addEventListener("abort",()=>this.host.removeAttribute("data-cx-layout"),{once:true})};Object.assign(TreeGrid.prototype,{destroy(){if(this.destroyed)return;this.destroyed=true;for(const row of[...this.rendered.values(),...this.pool])disposeRowHostCells(row);this.lifetime.abort();this.dataLifetime.abort();if(this.queryController)this.queryController.abort();if(this.restoreController)this.restoreController.abort();if(this.cancelResize)this.cancelResize();clearTimeout(this.saveTimer);clearTimeout(this.layoutTimer);if(this.cancelSearch)this.cancelSearch();if(this.disposeSearchFlyout)this.disposeSearchFlyout();cancelAnimationFrame(this.rafId);this.resizeObserver.disconnect();if(this.detailObserver)this.detailObserver.disconnect();this.grid.removeEventListener("scroll",this.onScroll);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);global.removeEventListener("beforeprint",this.onPrint);global.removeEventListener("hashchange",this.onHash);global.removeEventListener("popstate",this.onHash);if(this.linkOpening)this.linkOpening.abort();[this.toolbar,this.grid,this.live,this.outline].forEach(element=>element.remove());this.host.classList.remove("cx-pin-tree");this.host.removeAttribute("data-cx-ready");this.host.removeAttribute("data-canopyx-mounted");this.keyMap.clear();this.selected.clear();this.rendered.clear();this.pool.length=0;if(this.inactiveCache)this.inactiveCache.clear();if(this.inlineRetained)this.inlineRetained.clear();this.rows=[];this.tops=[0];this.total=0;this.root.children=null;this.root.inlineCache=null;this.root.inlineOrder=null;this.focused=null;this.anchor=null;this.source=null;this.touchScroll=null;this.opts={};for(const column of this.columns)column.render=null;this.filter=null;this.declaredFilter=null;this.pendingRestorationToggles=null;this.scrolledCell=null;this.focusHandoff=null;this.cancelResize=null;this.cancelSearch=null;this.disposeSearchFlyout=null;this.canvas.replaceChildren();this.outline.replaceChildren()}});const ROW_HELPERS={};const GRID_REPORTING={};
|
|
599
|
+
.catch(error=>this.emit("error",{error}))))},getLayout(){return Object.freeze({mode:this.layoutMode,density:this.density,modes:this.layoutOptions?this.layoutOptions.modes:Object.freeze(["fit"])})},setLayout(change){if(!this.layoutOptions)return Promise.reject(new Error("CanopyX: this view declares no layout modes."));return this.requirePart("layouts").then(()=>VIEW_MODES.setLayout(this,change))},getMatches(){return VIEW_MODES.matches?VIEW_MODES.matches(this):Object.freeze({enabled:!!this.highlightOn,total:0,current:0,complete:true})},setSearchHighlight(enabled){if(typeof enabled!=="boolean")return Promise.reject(new Error("CanopyX: the highlight switch is a boolean."));if(!this.highlightOptions)return Promise.reject(new Error("CanopyX: this view declares no search highlighting."));return this.requirePart("highlight").then(()=>VIEW_MODES.setHighlight(this,enabled))},nextMatch(options){return this.stepMatch(1,options)},previousMatch(options){return this.stepMatch(-1,options)},stepMatch(direction,options){if(!this.highlightOptions)return Promise.reject(new Error("CanopyX: this view declares no search highlighting."));return this.requirePart("highlight").then(()=>VIEW_MODES.step(this,direction,options?.focus!==false))}};Object.assign(TreeGrid.prototype,VIEW_MODE_METHODS);const viewModeContext=()=>({VIEW_MODES,TreeGrid,h,setText,fill,numberFormat,foldText,cellText,cellValue,isCellObject,setAttr,toneOf,watchFlyout,densityRowHeight,MAX_PROTOCOL_INTEGER,LAYOUT_DENSITIES,plural,svgIcon});definePart(TreeGrid,"highlight","search highlighting",viewModeContext);definePart(TreeGrid,"layouts","layout modes",viewModeContext);const MODES_TOOLBAR=TreeGrid.prototype.buildToolbar;TreeGrid.prototype.buildToolbar=function(){MODES_TOOLBAR.call(this);if(this.highlightOptions||this.layoutOptions)this.modesReady=Promise.resolve(this.toolsReady).then(()=>this.destroyed||this.startViewModes());this.lifetime.signal.addEventListener("abort",()=>this.host.removeAttribute("data-cx-layout"),{once:true})};Object.assign(TreeGrid.prototype,{destroy(){if(this.destroyed)return;this.destroyed=true;for(const row of[...this.rendered.values(),...this.pool])disposeRowHostCells(row);this.lifetime.abort();this.dataLifetime.abort();if(this.queryController)this.queryController.abort();if(this.restoreController)this.restoreController.abort();if(this.cancelResize)this.cancelResize();clearTimeout(this.saveTimer);clearTimeout(this.layoutTimer);if(this.cancelSearch)this.cancelSearch();if(this.disposeSearchFlyout)this.disposeSearchFlyout();cancelAnimationFrame(this.rafId);this.resizeObserver.disconnect();if(this.detailObserver)this.detailObserver.disconnect();this.grid.removeEventListener("scroll",this.onScroll);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);global.removeEventListener("beforeprint",this.onPrint);global.removeEventListener("hashchange",this.onHash);global.removeEventListener("popstate",this.onHash);if(this.linkOpening)this.linkOpening.abort();[this.toolbar,this.grid,this.live,this.outline].forEach(element=>element.remove());this.host.classList.remove("cx-pin-tree");this.host.removeAttribute("data-cx-ready");this.host.removeAttribute("data-canopyx-mounted");this.keyMap.clear();this.selected.clear();this.rendered.clear();this.pool.length=0;if(this.inactiveCache)this.inactiveCache.clear();if(this.inlineRetained)this.inlineRetained.clear();this.rows=[];this.tops=[0];this.total=0;this.root.children=null;this.root.inlineCache=null;this.root.inlineOrder=null;this.focused=null;this.anchor=null;this.source=null;this.touchScroll=null;this.opts={};for(const column of this.columns)column.render=null;this.filter=null;this.declaredFilter=null;this.pendingRestorationToggles=null;this.scrolledCell=null;this.focusHandoff=null;this.cancelResize=null;this.cancelSearch=null;this.disposeSearchFlyout=null;this.canvas.replaceChildren();this.outline.replaceChildren()}});const ROW_HELPERS={};const GRID_REPORTING={};for(const name of["buildHeader","visibleColumns","applyWidths","setColumnWidth","startResize","cell","newCell","paintSlot","paintBadges","cellTip","paintHostSlot","setSlotContent","setTimeZone","rowCells","heldCell","restoreCell","focusCell","revealInRow","revealInCell","settleCell"])
|
|
600
|
+
ROW_HELPERS[name]=TreeGrid.prototype[name];function gridMomentFromParts(year,month,day,hours,minutes,seconds,local){const parts=[year,month,day,hours,minutes,seconds];if(!parts.every(Number.isInteger))return null;const moment=new Date(0),zone=local?"":"UTC";moment["set"+zone+"FullYear"](year,month-1,day);moment["set"+zone+"Hours"](hours,minutes,seconds,0);const actual=["FullYear","Month","Date","Hours","Minutes","Seconds"].map(name=>moment["get"+zone+name]());actual[1]++;return parts.every((value,index)=>value===actual[index])?moment:null}
|
|
599
601
|
function gridDateInputMoment(text,local){const match=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,3}))?)?$/.exec(text);
|
|
600
602
|
if(!match)return null;const moment=gridMomentFromParts(Number(match[1]),Number(match[2]),Number(match[3]),Number(match[4]),Number(match[5]),Number(match[6]||0),local);if(moment)moment.setTime(moment.getTime()+ Number((match[7]||"").padEnd(3,"0")));return moment}
|
|
601
603
|
function gridFreeze(value){if(value&&typeof value==="object"&&!Object.isFrozen(value)){Object.values(value).forEach(gridFreeze);Object.freeze(value)}
|
|
602
604
|
return value}
|
|
603
|
-
|
|
604
|
-
ROW_HELPERS[name]=TreeGrid.prototype[name];DEFAULT_LABELS=Object.freeze(Object.assign({},DEFAULT_LABELS,{gridSelectionCount:"{count} selected",gridClearSelection:"Clear selection",gridSelectionQueryUnknown:"All matching records selected; {excluded} excluded",gridFitContent:"Fit to content",gridUnpin:"Unpin",gridWhere:"Where",gridComplexFilter:"This column belongs to a mixed condition group. Edit it in Filters.",gridPinLeft:"Pin left",gridPinRight:"Pin right",gridResponsiveHidden:"Hidden at this width",gridFilterMatch:"Match",gridFilterAll:"All",gridFilterAny:"Any",gridDeleteFilterGroup:"Remove condition group",gridFacetSearch:"Search values",gridFacetChoose:"Choose a value",gridFacetCounts:"{count} matching rows; {shown} of {total} values.",gridTrue:"True",gridFalse:"False",gridHeaderFilter:"Filter {column}",gridClearColumnFilter:"Clear filter",gridSelectionAggregate:"Count: {count} · Sum: {sum} · Average: {average} · Minimum: {minimum} · Maximum: {maximum}",gridConditionValue:"Value",gridConditionUpperValue:"Upper value",gridDeleteCondition:"Remove condition",gridShowRowsWhere:"Show rows where",gridOfTheseAreTrue:"of these are true",gridOfThese:"of these",gridGroupCount:"{count} groups",gridMore:"More",gridDone:"Done",gridClearAll:"Clear all",gridRows:"rows",gridResultNoun:"{count} of {total} {noun}",gridSearchNoun:"Search {noun}",gridChart:"Chart",gridPrint:"Print",gridRowPicked:"Picked up {title}. Move to a calendar and press Enter to drop it.",gridColumnMenu:"Menu for {column}",gridSortAscending:"Sort ascending",gridSortDescending:"Sort descending",gridClearSort:"Clear sort",gridFilterColumn:"Filter…",gridHideColumn:"Hide column",gridGroupedBy:"Grouped by",gridRemoveGrouping:"Remove grouping",gridSelectAllValues:"Select all values",gridFilterValues:"Search values",gridAddCondition:"+ Condition",gridAddGroup:"+ Group",gridAnd:"and",gridOr:"or",gridEditAsText:"Edit as text",gridFilterText:"Filter expression",gridDeepFilters:"This saved filter has more than two nesting levels.",gridToday:"Today",gridYesterday:"Yesterday",gridLastSevenDays:"Last 7 days",gridLastThirtyDays:"Last 30 days",gridThisMonth:"This month",gridDateRange:"Range",gridEmpty:"No {noun}",gridEmptyReason:"There are no records to display.",gridNoMatches:"No matching {noun}",gridNoMatchesReason:"Search: {search}. Active filters: {count}.",gridRetry:"Retry",gridLoadFailed:"Could not load records",gridAll:"All",gridPageOf:"{page} of {pages}",gridStatusCount:"{count} {noun} · {selected} selected",gridDetailsSection:"Details",gridPreviousRecord:"Previous record",gridNextRecord:"Next record",gridCloseRecord:"Close record details",gridShowMore:"Show more",gridNoData:"No data",gridPeriodRange:"{from}–{to}: {state}",}));const GRID_ICONS={search:'<circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/>',filter:'<path d="M4 5h16l-6 7.5V19l-4-2v-4.5z"/>',columns:'<rect x="3.5" y="4.5" width="17" height="15" rx="2"/><path d="M9.5 4.5v15M14.5 4.5v15"/>',views:'<path d="M6 4h12v16l-6-4-6 4z"/>',export:'<path d="M12 4v11M7.5 10.5 12 15l4.5-4.5M5 19h14"/>',more:'<circle cx="5" cy="12" r="1.2"/><circle cx="12" cy="12" r="1.2"/><circle cx="19" cy="12" r="1.2"/>',close:'<path d="M6 6l12 12M18 6 6 18"/>',check:'<path d="m5 12.5 4.5 4.5L19 7.5"/>',chart:'<path d="M4 19h16M7 16V10M12 16V6M17 16v-4"/>',copy:'<rect x="8" y="8" width="11" height="11" rx="2"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/>',up:'<path d="M12 19V5M6 11l6-6 6 6"/>',down:'<path d="M12 5v14M6 13l6 6 6-6"/>',retry:'<path d="M4 12a8 8 0 1 0 2.4-5.7M4 4v4.5h4.5"/>',previous:'<path d="m14 7-5 5 5 5"/>',next:'<path d="m10 7 5 5-5 5"/>',first:'<path d="m13 7-5 5 5 5M17 7l-5 5 5 5"/>',last:'<path d="m11 7 5 5-5 5M7 7l5 5-5 5"/>'};function gridIcon(name,shapes){return svgIcon(shapes||GRID_ICONS[name]||GRID_ICONS.more)}
|
|
605
|
+
DEFAULT_LABELS=Object.freeze(Object.assign({},DEFAULT_LABELS,{gridSelectionCount:"{count} selected",gridClearSelection:"Clear selection",gridSelectionQueryUnknown:"All matching records selected; {excluded} excluded",gridFitContent:"Fit to content",gridUnpin:"Unpin",gridWhere:"Where",gridComplexFilter:"This column belongs to a mixed condition group. Edit it in Filters.",gridPinLeft:"Pin left",gridPinRight:"Pin right",gridResponsiveHidden:"Hidden at this width",gridFilterMatch:"Match",gridFilterAll:"All",gridFilterAny:"Any",gridDeleteFilterGroup:"Remove condition group",gridFacetSearch:"Search values",gridFacetChoose:"Choose a value",gridFacetCounts:"{count} matching rows; {shown} of {total} values.",gridTrue:"True",gridFalse:"False",gridHeaderFilter:"Filter {column}",gridClearColumnFilter:"Clear filter",gridSelectionAggregate:"Count: {count} · Sum: {sum} · Average: {average} · Minimum: {minimum} · Maximum: {maximum}",gridConditionValue:"Value",gridConditionUpperValue:"Upper value",gridDeleteCondition:"Remove condition",gridShowRowsWhere:"Show rows where",gridOfTheseAreTrue:"of these are true",gridOfThese:"of these",gridGroupCount:"{count} groups",gridMore:"More",gridDone:"Done",gridClearAll:"Clear all",gridRows:"rows",gridResultNoun:"{count} of {total} {noun}",gridSearchNoun:"Search {noun}",gridChart:"Chart",gridPrint:"Print",gridRowPicked:"Picked up {title}. Move to a calendar and press Enter to drop it.",gridColumnMenu:"Menu for {column}",gridSortAscending:"Sort ascending",gridSortDescending:"Sort descending",gridClearSort:"Clear sort",gridFilterColumn:"Filter…",gridHideColumn:"Hide column",gridGroupedBy:"Grouped by",gridRemoveGrouping:"Remove grouping",gridSelectAllValues:"Select all values",gridFilterValues:"Search values",gridAddCondition:"+ Condition",gridAddGroup:"+ Group",gridAnd:"and",gridOr:"or",gridEditAsText:"Edit as text",gridFilterText:"Filter expression",gridDeepFilters:"This saved filter has more than two nesting levels.",gridToday:"Today",gridYesterday:"Yesterday",gridLastSevenDays:"Last 7 days",gridLastThirtyDays:"Last 30 days",gridThisMonth:"This month",gridDateRange:"Range",gridEmpty:"No {noun}",gridEmptyReason:"There are no records to display.",gridNoMatches:"No matching {noun}",gridNoMatchesReason:"Search: {search}. Active filters: {count}.",gridRetry:"Retry",gridLoadFailed:"Could not load records",gridAll:"All",gridPageOf:"{page} of {pages}",gridStatusCount:"{count} {noun} · {selected} selected",gridDetailsSection:"Details",gridPreviousRecord:"Previous record",gridNextRecord:"Next record",gridCloseRecord:"Close record details",gridShowMore:"Show more",gridNoData:"No data",gridPeriodRange:"{from}–{to}: {state}",}));const GRID_ICONS={search:'<circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/>',filter:'<path d="M4 5h16l-6 7.5V19l-4-2v-4.5z"/>',columns:'<rect x="3.5" y="4.5" width="17" height="15" rx="2"/><path d="M9.5 4.5v15M14.5 4.5v15"/>',views:'<path d="M6 4h12v16l-6-4-6 4z"/>',export:'<path d="M12 4v11M7.5 10.5 12 15l4.5-4.5M5 19h14"/>',more:'<circle cx="5" cy="12" r="1.2"/><circle cx="12" cy="12" r="1.2"/><circle cx="19" cy="12" r="1.2"/>',close:'<path d="M6 6l12 12M18 6 6 18"/>',check:'<path d="m5 12.5 4.5 4.5L19 7.5"/>',chart:'<path d="M4 19h16M7 16V10M12 16V6M17 16v-4"/>',copy:'<rect x="8" y="8" width="11" height="11" rx="2"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/>',up:'<path d="M12 19V5M6 11l6-6 6 6"/>',down:'<path d="M12 5v14M6 13l6 6 6-6"/>',retry:'<path d="M4 12a8 8 0 1 0 2.4-5.7M4 4v4.5h4.5"/>',previous:'<path d="m14 7-5 5 5 5"/>',next:'<path d="m10 7 5 5-5 5"/>',first:'<path d="m13 7-5 5 5 5M17 7l-5 5 5 5"/>',last:'<path d="m11 7 5 5-5 5M7 7l5 5-5 5"/>'};function gridIcon(name,shapes){return svgIcon(shapes||GRID_ICONS[name]||GRID_ICONS.more)}
|
|
605
606
|
function gridDecorateButton(button,icon,ghost){button.classList.add("cx-btn");if(ghost)button.classList.add("ghost");if(icon)button.prepend(gridIcon(icon));return button}
|
|
606
607
|
function gridFilterCount(query){const count=group=>group?group.filters.length+group.groups.reduce((sum,child)=>sum+count(child),0):0;return(query?.filters?.length||0)+ count(query?.filterGroup)}
|
|
607
608
|
const GRID_FILTER_LABELS={eq:"=",ne:"≠",contains:"gridContains",startsWith:"gridStartsWith",in:"gridIn",gt:">",ge:"≥",lt:"<",le:"≤",isNull:"gridIsNull",isNotNull:"gridIsNotNull"};function gridQueryRecord(input,record,strict,cursor){if(strict&&Object.keys(input).some(key=>!Object.hasOwn(record,key)&&!(cursor&&key==="offset")))throw new Error("CanopyX: invalid state query.");return gridFreeze(record)}
|
|
@@ -934,7 +935,7 @@ for(const field of CAL_FIELDS)if(field!=="allDay"&&event[field]!=null){cells[fie
|
|
|
934
935
|
return{id,cells}});if(options.resources)used.add("resource");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:"text",hidden:field!=="description",editable:writable&&(field==="resource"||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})}
|
|
935
936
|
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)}
|
|
936
937
|
return roots}
|
|
937
|
-
const GRID_EDITING=definePart(DataGrid,"editing","editing",()=>({DataGrid,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:"Filter by",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,cellText,foldText,numberFormat,gridCellRenderer,gridFreeze}));Object.assign(DataGrid.prototype,{loadFacets(){return this.facetLoad||=loadPart(GRID_FACETS).then(()=>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")
|
|
938
|
+
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:"Filter by",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,cellText,foldText,numberFormat,gridCellRenderer,gridFreeze}));Object.assign(DataGrid.prototype,{loadFacets(){return this.facetLoad||=loadPart(GRID_FACETS).then(()=>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")
|
|
938
939
|
throw new Error("CanopyX: invalid saved facet panel state.");if(this.view.facets||this.opts.facets)state.facets={open:facets.open}}
|
|
939
940
|
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}
|
|
940
941
|
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,numberFormat,gridButton,gridOption,gridInputLabel,gridIcon,gridDecorateButton,GRID_REPORTING,loadPart,definePart,announceMenu,boundedPattern,wildcardMatch,svgIcon}));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,validateGridRows,validateGridPage,validateGridCursorPage,gridFreeze,requireIdentifier,checkDocument,cellValue,PROTOCOL,GRID_REPORTING,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(){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_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())
|
|
@@ -1121,7 +1122,10 @@ clearDropRow(){if(this.dropRow){this.dropRow.classList.remove("cx-drop-target");
|
|
|
1121
1122
|
this.dropRow=null}
|
|
1122
1123
|
dropPlacement(event,row){const bounds=row.getBoundingClientRect(),fraction=(event.clientY-bounds.top)/ bounds.height;
|
|
1123
1124
|
return fraction<0.25?"before":fraction>0.75?"after":"inside"}
|
|
1124
|
-
destroy(){this.clearDropRow();this.dragLease=null;super.destroy()}};
|
|
1125
|
+
destroy(){this.clearDropRow();this.dragLease=null;super.destroy()}};class FlowHost{}
|
|
1126
|
+
const FORMS_IMPL={},FLOW_IMPL={},activeFlows=new WeakMap();const FORMS_PART=definePart(FlowHost,"forms","forms",()=>({FORMS_IMPL,h,setText,fill,gridFreeze,gridMomentFromParts,boundedPattern,foldText}));const FLOW_PART=definePart(FlowHost,"flow","flow view",()=>({FLOW_IMPL,FORMS_IMPL,h,setText,fill,plural,foldText,boundedPattern,numberFormat,gridFreeze}));if(typeof DataGrid==="function")DataGrid.prototype.parts.forms=FORMS_PART;const FLOW_ASYNC_METHODS=["next","back","goTo","setState","validate","submit"];const FLOW_SYNC_METHODS=["getStep","getValues","setValues","getState","isDirty","reset","setFieldError","setProgress","complete"];function createFlow(host,options){if(!host||!options||!options.flow||typeof options.flow!=="object")throw new Error("CanopyX: createFlow needs a host element and a flow document.");const existing=activeFlows.get(host);if(existing)return existing;let impl=null,destroyed=false,mountError=null;const destroyedError=()=>new Error("CanopyX: this flow has been destroyed.");const requireImpl=name=>{if(destroyed)throw destroyedError();if(!impl)throw new Error("CanopyX: flow is not ready; await api.ready before calling "+name+"().");return impl};const editors=Object.assign({},...[...PLUGINS.values()].map(item=>item.editors||{}));const ready=loadPart(FLOW_PART).then(()=>{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;try{impl?.destroy()}
|
|
1127
|
+
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}
|
|
1128
|
+
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.")}
|
|
1125
1129
|
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"])
|
|
1126
1130
|
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);
|
|
1127
1131
|
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}
|
|
@@ -1135,5 +1139,5 @@ watcher.observe(host)}
|
|
|
1135
1139
|
function mount(root,automatic){const scope=root||document;const created=[];const showError=(host,err,api,view)=>{if(api){api.destroy();if(host.canopyx===api)delete host.canopyx}
|
|
1136
1140
|
const message=err&&err.message?err.message:String(err);let labels=DEFAULT_LABELS;for(const attempt of[()=>labelsFor(view&&view.labels,view&&configured.has(view.id)?configured.get(view.id).labels:null),()=>labelsFor(view&&view.labels)]){try{labels=attempt();break}catch(e){labels=DEFAULT_LABELS}}
|
|
1137
1141
|
const notice=document.createElement("div");notice.className="cx-mount-error";notice.setAttribute("role","alert");setText(notice,fill(labels.mountError,{error:message}));host.classList.add("cx-host");host.setAttribute("data-canopyx-mounted","true");host.setAttribute("data-cx-error",message);host.appendChild(notice);if(global.console)global.console.error(err)};const selector="[data-canopyx-host]:not([data-canopyx-mounted])";(scope.matches?.(selector)?[scope]:scope.querySelectorAll(selector)).forEach((host)=>{const config=host.querySelector("script.cx-config"),mode=host.getAttribute("data-cx-mount");if(!config||(automatic===true&&mode==="manual")){return}
|
|
1138
|
-
if(mode==="visible"&&host!==scope&&global.IntersectionObserver)return mountWhenVisible(host);watcher?.unobserve(host);host.setAttribute("data-canopyx-mounted","true");let view=null;try{view=JSON.parse(config.textContent);if(view===Object(view))parsedViews.add(view);const create=view&&view.type==="grid"&&typeof createDataGrid==="function"?createDataGrid:createTreeGrid;const api=create(host,Object.assign({},view&&configured.get(view.id),{view}));created.push(api);api.ready.catch((err)=>{if(view.type!=="grid"&&activeGrids.get(host)===api&&host.canopyx===api)showError(host,err,api,view)})}catch(err){showError(host,err,null,view)}});return created}
|
|
1139
|
-
global.CanopyX=Object.freeze(Object.assign({protocol:PROTOCOL,createTreeGrid,configure,unconfigure,mount:(root)=>mount(root,false),sources:Object.freeze({inline:inlineSource,sidecar:sidecarSource,remote:remoteSource}),badge:hostBadge,labels:DEFAULT_LABELS,registerExportFormat,use,registerPart,setNonce},typeof GRID_API==="object"?GRID_API:{}));const navigation=global.performance&&performance.getEntriesByType?performance.getEntriesByType("navigation")[0]:null;if(document.readyState==="loading"||(document.readyState==="interactive"&&navigation&&navigation.domContentLoadedEventStart===0)){document.addEventListener("DOMContentLoaded",()=>mount(document,true))}else{mount(document,true)}})(typeof window!=="undefined"?window:this);
|
|
1142
|
+
if(mode==="visible"&&host!==scope&&global.IntersectionObserver)return mountWhenVisible(host);watcher?.unobserve(host);host.setAttribute("data-canopyx-mounted","true");let view=null;try{view=JSON.parse(config.textContent);if(view===Object(view))parsedViews.add(view);const flow=view&&view.kind==="flow"&&typeof FLOW_API==="object";const create=flow?FLOW_API.createFlow:view&&view.type==="grid"&&typeof createDataGrid==="function"?createDataGrid:createTreeGrid;const api=create(host,Object.assign({},view&&configured.get(view.id),flow?{flow:view}:{view}));created.push(api);api.ready.catch((err)=>{if(view.type!=="grid"&&activeGrids.get(host)===api&&host.canopyx===api)showError(host,err,api,view)})}catch(err){showError(host,err,null,view)}});return created}
|
|
1143
|
+
global.CanopyX=Object.freeze(Object.assign({protocol:PROTOCOL,createTreeGrid,configure,unconfigure,mount:(root)=>mount(root,false),sources:Object.freeze({inline:inlineSource,sidecar:sidecarSource,remote:remoteSource}),badge:hostBadge,labels:DEFAULT_LABELS,registerExportFormat,use,registerPart,setNonce},typeof GRID_API==="object"?GRID_API:{},typeof FLOW_API==="object"?FLOW_API:{}));const navigation=global.performance&&performance.getEntriesByType?performance.getEntriesByType("navigation")[0]:null;if(document.readyState==="loading"||(document.readyState==="interactive"&&navigation&&navigation.domContentLoadedEventStart===0)){document.addEventListener("DOMContentLoaded",()=>mount(document,true))}else{mount(document,true)}})(typeof window!=="undefined"?window:this);
|