@evotecit/canopyx 0.3.13 → 0.3.16

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.
Files changed (103) hide show
  1. package/CanopyX.Html/Assets/canopyx-calendar-edit.js +36 -18
  2. package/CanopyX.Html/Assets/canopyx-calendar-ics.js +7 -5
  3. package/CanopyX.Html/Assets/canopyx-calendar.css +124 -116
  4. package/CanopyX.Html/Assets/canopyx-calendar.js +74 -54
  5. package/CanopyX.Html/Assets/canopyx-cell-range.css +8 -8
  6. package/CanopyX.Html/Assets/canopyx-cell-range.js +1 -1
  7. package/CanopyX.Html/Assets/canopyx-changes.css +113 -113
  8. package/CanopyX.Html/Assets/canopyx-changes.js +7 -10
  9. package/CanopyX.Html/Assets/canopyx-column-groups.css +5 -5
  10. package/CanopyX.Html/Assets/canopyx-column-groups.js +1 -1
  11. package/CanopyX.Html/Assets/canopyx-data.js +2 -2
  12. package/CanopyX.Html/Assets/canopyx-detail-rows.css +9 -9
  13. package/CanopyX.Html/Assets/canopyx-detail-rows.js +2 -2
  14. package/CanopyX.Html/Assets/canopyx-editing.css +18 -18
  15. package/CanopyX.Html/Assets/canopyx-editing.js +1 -1
  16. package/CanopyX.Html/Assets/canopyx-enhance.js +2 -2
  17. package/CanopyX.Html/Assets/canopyx-facets.css +33 -33
  18. package/CanopyX.Html/Assets/canopyx-facets.js +5 -6
  19. package/CanopyX.Html/Assets/canopyx-filter-editor.css +57 -57
  20. package/CanopyX.Html/Assets/canopyx-filter-editor.js +7 -5
  21. package/CanopyX.Html/Assets/canopyx-flow-checks.css +13 -11
  22. package/CanopyX.Html/Assets/canopyx-flow-checks.js +5 -4
  23. package/CanopyX.Html/Assets/canopyx-flow-command.css +7 -7
  24. package/CanopyX.Html/Assets/canopyx-flow-command.js +1 -1
  25. package/CanopyX.Html/Assets/canopyx-flow-dialog.css +9 -7
  26. package/CanopyX.Html/Assets/canopyx-flow-dialog.js +1 -1
  27. package/CanopyX.Html/Assets/canopyx-flow-drafts.css +7 -7
  28. package/CanopyX.Html/Assets/canopyx-flow-drafts.js +1 -1
  29. package/CanopyX.Html/Assets/canopyx-flow-entry.css +17 -76
  30. package/CanopyX.Html/Assets/canopyx-flow-entry.js +11 -5
  31. package/CanopyX.Html/Assets/canopyx-flow-facts.js +2 -0
  32. package/CanopyX.Html/Assets/canopyx-flow-host.css +4 -4
  33. package/CanopyX.Html/Assets/canopyx-flow-host.js +1 -1
  34. package/CanopyX.Html/Assets/canopyx-flow-module.mjs +11 -5
  35. package/CanopyX.Html/Assets/canopyx-flow-pick.css +4 -4
  36. package/CanopyX.Html/Assets/canopyx-flow-pick.js +1 -1
  37. package/CanopyX.Html/Assets/canopyx-flow-preview.css +6 -6
  38. package/CanopyX.Html/Assets/canopyx-flow-preview.js +1 -1
  39. package/CanopyX.Html/Assets/canopyx-flow-records.css +3 -3
  40. package/CanopyX.Html/Assets/canopyx-flow-records.js +1 -1
  41. package/CanopyX.Html/Assets/canopyx-flow-tasks.css +17 -17
  42. package/CanopyX.Html/Assets/canopyx-flow-tasks.js +1 -1
  43. package/CanopyX.Html/Assets/canopyx-flow.css +79 -79
  44. package/CanopyX.Html/Assets/canopyx-flow.js +8 -7
  45. package/CanopyX.Html/Assets/canopyx-format-editor.css +23 -23
  46. package/CanopyX.Html/Assets/canopyx-format-editor.js +2 -3
  47. package/CanopyX.Html/Assets/canopyx-formatting.css +17 -17
  48. package/CanopyX.Html/Assets/canopyx-formatting.js +5 -5
  49. package/CanopyX.Html/Assets/canopyx-forms.css +5 -5
  50. package/CanopyX.Html/Assets/canopyx-forms.js +1 -1
  51. package/CanopyX.Html/Assets/canopyx-grid-module.mjs +97 -54
  52. package/CanopyX.Html/Assets/canopyx-grid-options.css +10 -0
  53. package/CanopyX.Html/Assets/canopyx-grid-options.js +47 -0
  54. package/CanopyX.Html/Assets/canopyx-grid.css +199 -261
  55. package/CanopyX.Html/Assets/canopyx-grid.js +97 -54
  56. package/CanopyX.Html/Assets/canopyx-grouping.css +17 -17
  57. package/CanopyX.Html/Assets/canopyx-grouping.js +12 -9
  58. package/CanopyX.Html/Assets/canopyx-highlight.css +14 -14
  59. package/CanopyX.Html/Assets/canopyx-highlight.js +2 -2
  60. package/CanopyX.Html/Assets/canopyx-interactive.css +94 -155
  61. package/CanopyX.Html/Assets/canopyx-interactive.js +33 -14
  62. package/CanopyX.Html/Assets/canopyx-labels-de.js +5 -0
  63. package/CanopyX.Html/Assets/canopyx-labels-es.js +5 -0
  64. package/CanopyX.Html/Assets/canopyx-labels-fr.js +5 -0
  65. package/CanopyX.Html/Assets/canopyx-labels-it.js +5 -0
  66. package/CanopyX.Html/Assets/canopyx-labels-pl.js +5 -0
  67. package/CanopyX.Html/Assets/canopyx-layouts.css +17 -17
  68. package/CanopyX.Html/Assets/canopyx-layouts.js +2 -10
  69. package/CanopyX.Html/Assets/canopyx-link.css +7 -7
  70. package/CanopyX.Html/Assets/canopyx-link.js +1 -1
  71. package/CanopyX.Html/Assets/canopyx-live.css +9 -9
  72. package/CanopyX.Html/Assets/canopyx-live.js +20 -15
  73. package/CanopyX.Html/Assets/canopyx-matrix.css +74 -74
  74. package/CanopyX.Html/Assets/canopyx-matrix.js +3 -4
  75. package/CanopyX.Html/Assets/canopyx-module.mjs +33 -14
  76. package/CanopyX.Html/Assets/canopyx-pager.css +2 -2
  77. package/CanopyX.Html/Assets/canopyx-pager.js +1 -1
  78. package/CanopyX.Html/Assets/canopyx-presenters.js +2 -2
  79. package/CanopyX.Html/Assets/canopyx-record-panel.css +57 -49
  80. package/CanopyX.Html/Assets/canopyx-record-panel.js +13 -8
  81. package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +101 -57
  82. package/CanopyX.Html/Assets/canopyx-reporting.css +214 -276
  83. package/CanopyX.Html/Assets/canopyx-reporting.js +101 -57
  84. package/CanopyX.Html/Assets/canopyx-timeline.css +28 -28
  85. package/CanopyX.Html/Assets/canopyx-timeline.js +11 -10
  86. package/CanopyX.Html/Assets/canopyx-tree-tools.css +47 -47
  87. package/CanopyX.Html/Assets/canopyx-tree-tools.js +3 -3
  88. package/CanopyX.Html/Assets/canopyx.css +81 -142
  89. package/CanopyX.Html/Assets/canopyx.js +33 -14
  90. package/JavaScript/calendar.d.ts +15 -0
  91. package/JavaScript/flow.d.ts +6 -0
  92. package/JavaScript/grid.d.ts +29 -4
  93. package/JavaScript/live.d.ts +2 -0
  94. package/JavaScript/locales/de.mjs +5 -0
  95. package/JavaScript/locales/es.mjs +5 -0
  96. package/JavaScript/locales/fr.mjs +5 -0
  97. package/JavaScript/locales/it.mjs +5 -0
  98. package/JavaScript/locales/pl.mjs +5 -0
  99. package/JavaScript/plugins.d.ts +4 -0
  100. package/JavaScript/protocol.d.ts +1 -1
  101. package/JavaScript/records.d.ts +18 -4
  102. package/README.md +6 -2
  103. package/package.json +5 -1
@@ -1,4 +1,4 @@
1
- (function(global){"use strict";const installed=new WeakSet();const part={version:"e78e0e62d74d6811",install(context){if(installed.has(context.RECORD_IMPL))return;const{RECORD_IMPL,TreeGrid,h,setText,fill,cellText,cellValue,isCellObject,formatValue,toneOf,applyTone,toneColors,validateGridRows,badgeElement,loadSidecar,requireIdentifier,PROTOCOL,foldText,createTreeGrid,svgIcon,gridExportField,columnNumericTone,columnValueTone,validateColumnValues}=context;const RECORD_KINDS=["items","fields","records","events","changes"],RECORD_LINK_KEY=/^[A-Za-z][\w.-]{0,31}$/, RECORD_MAX_STRUCTURE_DEPTH = 8;
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"82aa828bc880087b",install(context){if(installed.has(context.RECORD_IMPL))return;const{RECORD_IMPL,TreeGrid,h,setText,fill,cellText,cellValue,isCellObject,formatValue,toneOf,applyTone,toneColors,validateGridRows,badgeElement,loadSidecar,requireIdentifier,PROTOCOL,foldText,createTreeGrid,svgIcon,gridExportField,columnNumericTone,columnValueTone,validateColumnValues}=context;const RECORD_KINDS=["items","fields","records","events","changes"],RECORD_LINK_KEY=/^[A-Za-z][\w.-]{0,31}$/, RECORD_MAX_STRUCTURE_DEPTH = 8;
2
2
  const recordKind=cell=>{const kinds=isCellObject(cell)&&!Array.isArray(cell)?RECORD_KINDS.filter(name=>cell[name]!==undefined):[];if(kinds.length>1)recordFail("a cell carries at most one structured value.");return kinds[0]||null};const recordFail=message=>{throw new Error("CanopyX: "+message)};const recordText=(value,max=256)=>typeof value==="string"&&!!value.trim()&&value.length<=max;const recordGridHelpers=()=>RECORD_IMPL.grid||{};function recordCheckValue(cell,depth=0){if(cell==null)return;if(depth>RECORD_MAX_STRUCTURE_DEPTH)recordFail("structured values nest at most "+RECORD_MAX_STRUCTURE_DEPTH+" levels.");const kind=recordKind(cell);if(kind==="items")for(const item of cell.items||[])recordCheckValue(item,depth+1);if(kind==="fields")for(const field of cell.fields||[])recordCheckValue(field.value,depth+1);if(kind==="changes")for(const change of cell.changes||[]){recordCheckValue(change.before,depth+1);recordCheckValue(change.after,depth+1)}
3
3
  if(kind==="events")for(const event of cell.events||[])for(const change of event.changes||[]){recordCheckValue(change.before,depth+1);recordCheckValue(change.after,depth+1)}
4
4
  if(kind==="records")recordCheckRows(cell.records.rows||cell.records.roots,depth+1)}
@@ -72,7 +72,7 @@ function recordCollection(ctx,field,list,element){if(!list||typeof list!=="objec
72
72
  fill(labels.recordCount,{shown:recordCount(ctx,rows.length),total:recordCount(ctx,total)}));if(total>5||total>rows.length||ctx.print)head.appendChild(count);if(!ctx.print&&list.target?.view){const openAll=recordButton(labels.recordOpenAll,()=>recordOpenAll(ctx,field,list).catch(error=>ctx.view.emit("error",{error})),"cx-record-open-all","open");openAll.disabled=!recordCanOpenAll(list);head.appendChild(openAll)}
73
73
  const body=h("div","cx-record-collection-b");if(head.firstChild)block.appendChild(head);block.appendChild(body);if(ctx.print)recordTable(ctx,list,body);else if(ctx.phone&&!list.roots)recordCards(ctx,field,list,body);else recordNested(ctx,field,list,body);if(!ctx.print&&!list.roots&&rows.length<total&&recordLoader(ctx.view)){const more=recordButton(labels.recordLoadMore,()=>recordMore(ctx,field,list,more),"cx-record-load-more");block.appendChild(more)}
74
74
  element.appendChild(block)}
75
- function recordNested(ctx,field,list,body){const grid=recordGridHelpers(),host=h("div","cx-host cx-record-nested"),rows=list.rows,tree=!!list.roots||!grid.createDataGrid;host.setAttribute("data-cx-theme",ctx.view.host.getAttribute("data-cx-theme")||"auto");const columns=list.columns.map(column=>({kind:"text",sortable:true,...column})),id="cx-record-" + ++recordNestedSeq;const byKey=new Map(rows.map((row,at)=>["r"+String(at).padStart(6,"0"),row]));const open=item=>{const row=byKey.get(item.id)||item,ref=recordRowRef(list,row);if(ref)ctx.navigate(ref,host)};let api;if(tree){const roots=list.roots||rows.map(row=>({id:row.id,label:recordRowTitle(list,row,ctx.fmt),cells:row.cells}));host.classList.add("cx-record-nested-tree");api=createTreeGrid(host,{view:{protocol:PROTOCOL,type:"view",id,label:field.title,columns,source:{kind:"inline"},roots,rowHeight:30},labels:ctx.view.opts.labels,toolbar:false,onDetails:({node})=>open(node)})}else{const length=Math.min(Math.max(list.pageLength||10,1),100),paged=rows.length>length;api=grid.createDataGrid(host,{view:{protocol:PROTOCOL,type:"grid",id,label:field.title,rowHeight:30,pageSize:Math.min(10000,Math.max(rows.length,1)),selection:"none",search:rows.length>8,columns,source:{kind:"inline"},rows:[...byKey].map(([key,row])=>({...row,id:key})),toolbar:{filters:false,columns:false,views:false,export:false,more:false,count:false,columnMenus:false},...(paged?{presentation:"paged",pageLength:length}:{}),rowAction:rows.some(row=>recordRowRef(list,row))?"details":"none"},labels:ctx.view.opts.labels,...(rows.length>8?{}:{toolbar:false}),onDetails:({row})=>open(row)})}
75
+ function recordNested(ctx,field,list,body){const grid=recordGridHelpers(),host=h("div","cx-host cx-record-nested"),rows=list.rows,tree=!!list.roots||!grid.createDataGrid;const columns=list.columns.map(column=>({kind:"text",sortable:true,...column})),id="cx-record-" + ++recordNestedSeq;const byKey=new Map(rows.map((row,at)=>["r"+String(at).padStart(6,"0"),row]));const open=item=>{const row=byKey.get(item.id)||item,ref=recordRowRef(list,row);if(ref)ctx.navigate(ref,host)};let api;if(tree){const roots=list.roots||rows.map(row=>({id:row.id,label:recordRowTitle(list,row,ctx.fmt),cells:row.cells}));host.classList.add("cx-record-nested-tree");api=createTreeGrid(host,{view:{protocol:PROTOCOL,type:"view",id,label:field.title,columns,source:{kind:"inline"},roots,rowHeight:30},labels:ctx.view.opts.labels,toolbar:false,onDetails:({node})=>open(node)})}else{const length=Math.min(Math.max(list.pageLength||10,1),100),paged=rows.length>length;api=grid.createDataGrid(host,{view:{protocol:PROTOCOL,type:"grid",id,label:field.title,rowHeight:30,pageSize:Math.min(10000,Math.max(rows.length,1)),selection:"none",search:rows.length>8,columns,source:{kind:"inline"},rows:[...byKey].map(([key,row])=>({...row,id:key})),toolbar:{filters:false,columns:false,views:false,export:false,more:false,count:false,columnMenus:false},...(paged?{presentation:"paged",pageLength:length}:{}),rowAction:rows.some(row=>recordRowRef(list,row))?"details":"none"},labels:ctx.view.opts.labels,...(rows.length>8?{}:{toolbar:false}),onDetails:({row})=>open(row)})}
76
76
  host.style.setProperty("--cx-record-rows",String(Math.min(tree?(list.roots||rows).length:Math.min(rows.length,list.pageLength||10),12)));body.appendChild(host);recordOnDispose(ctx.signal,()=>api.destroy());api.ready?.catch(error=>{if(!ctx.signal.aborted)ctx.view.emit("error",{error})})}
77
77
  function recordCards(ctx,field,list,body){const holder=h("div","cx-record-cards"),rows=list.rows,columns=list.columns,step=10;const card=row=>{const item=h("div","cx-record-card"),title=h("div","cx-record-card-title"),ref=recordRowRef(list,row),text=recordRowTitle(list,row,ctx.fmt);item.setAttribute("role","group");item.setAttribute("aria-label",text);if(ref)recordLink(ctx,{value:text,ref},{id:field.id,kind:"text"},title);else setText(title,text);const fields=h("dl","cx-dl");for(const column of columns.slice(1)){const cell=row.cells?.[column.id],spec={id:column.id,title:column.title,kind:column.kind||"text"};if(recordEmpty(cell,spec,ctx.fmt))continue;const term=h("dt"),value=h("dd");setText(term,column.title);recordValue(ctx,spec,cell,value,1);fields.append(term,value)}
78
78
  item.append(title,fields);return item};for(const row of rows.slice(0,step))holder.appendChild(card(row));body.appendChild(holder);if(rows.length>step){const more=recordButton(fill(ctx.labels.recordShowAll,{count:recordCount(ctx,rows.length)}),()=>{more.remove();for(const row of rows.slice(step))holder.appendChild(card(row));holder.children[step]?.querySelector("button")?.focus()},"cx-record-more");body.appendChild(more)}}
@@ -136,7 +136,7 @@ return api.openRecord(ref.id,{stack:[...state.stack,entry].slice(-20),returnFocu
136
136
  function recordBack(view,dialog,steps=1){const stack=dialog._cxPanel?.stack||[],entry=stack[stack.length-steps],api=entry&&recordApi(entry.view);if(!api)return;api.openRecord(entry.id,{stack:stack.slice(0,stack.length-steps),tab:entry.tab,origin:entry.origin,back:true,returnFocus:dialog._returnFocus})
137
137
  .then(()=>recordRetire(dialog),error=>{recordAnnounce(dialog,fill(view.labels.recordUnavailable,{id:entry.id}));view.emit("error",{error})})}
138
138
  function recordRetire(dialog){if(dialog.isConnected&&dialog.open&&document.querySelectorAll("dialog.cx-drawer[open]").length>1){dialog._replaced=true;dialog.close();dialog.remove()}}
139
- RECORD_IMPL.open=async(view,id,options={})=>{requireIdentifier(id,"record ID");if(view.destroyed)recordFail("the view was destroyed.");await view.ready;const dialog=view.kind==="tree"?await recordOpenNode(view,id,options):await recordOpenRow(view,id,options);if(!dialog)return;const origin=options.origin&&dialog.querySelector('[data-cx-origin="'+CSS.escape(options.origin)+ '"]');if(origin)origin.focus({preventScroll:false});if(options.stack)recordAnnounce(dialog,fill(options.back?view.labels.recordBackTo:view.labels.recordShowing,{record:recordTitle(dialog)}))};async function recordOpenRow(view,id,options){await view.requirePart("filter-editor");let index=null,row=null;const loaded=[...view.rowCache.values()].find(item=>!item.status&&item.key===id);if(loaded){row=loaded.h;index=loaded._ri;if(!view.pendingQuery)await view.focusResult(index,false).catch(()=>{})}
139
+ RECORD_IMPL.open=async(view,id,options={})=>{requireIdentifier(id,"record ID");if(view.destroyed)recordFail("the view was destroyed.");await view.ready;if(options.reload===true)RECORD_IMPL.invalidate(view,id);const dialog=view.kind==="tree"?await recordOpenNode(view,id,options):await recordOpenRow(view,id,options);if(!dialog)return;const origin=options.origin&&dialog.querySelector('[data-cx-origin="'+CSS.escape(options.origin)+ '"]');if(origin)origin.focus({preventScroll:false});if(options.stack)recordAnnounce(dialog,fill(options.back?view.labels.recordBackTo:view.labels.recordShowing,{record:recordTitle(dialog)}))};async function recordOpenRow(view,id,options){await view.requirePart("filter-editor");let index=null,row=null;const loaded=[...view.rowCache.values()].find(item=>!item.status&&item.key===id);if(loaded){row=loaded.h;index=loaded._ri;if(!view.pendingQuery)await view.focusResult(index,false).catch(()=>{})}
140
140
  else if(view.acceptedQuery&&!view.pendingQuery&&typeof view.source.position==="function"){const position=await view.runGridHook(signal=>view.source.position(view.acceptedQuery,id,{signal}));if(Number.isInteger(position)&&position>=0&&position<view.rowCount()){await view.focusResult(position,false);const item=view.rowCache.get(position);if(item&&!item.status&&item.key===id){row=item.h;index=position}}}
141
141
  if(!row&&typeof view.source.row==="function")row=view.source.row(id);if(!row&&recordLoader(view)){const key=recordCacheKey(view,id);const payload=await recordFetch(view,id,{row:true});if(payload?.row){row=payload.row;(view._recordPayloads||=new Map()).set(key,{state:"ready",payload,promise:Promise.resolve(payload)})}}
142
142
  if(!row)recordFail("record "+id+" is not available.");const returnFocus=options.returnFocus||document.activeElement;if(typeof view.opts.onDetails==="function"){const record=recordGridHelpers().gridFreeze(JSON.parse(JSON.stringify(row)));await view.runGridHook(signal=>view.opts.onDetails({row:record,query:view.acceptedQuery,signal,returnFocus}));return null}
@@ -155,13 +155,18 @@ view._recordLinkOpen=record?recordLinkPath(recordLinkRead(view)||[]):null}
155
155
  RECORD_IMPL.start=view=>{if(view._recordStarted||!view.view.record?.deepLink)return;view._recordStarted=true;const read=()=>{const ids=recordLinkRead(view),key=ids?recordLinkPath(ids):null,owner=view._recordLinkOwner?.dialog;if(!ids){view._recordLinkOpen=null;view._recordLinkOwner=null;return}
156
156
  if(key===view._recordLinkOpen&&(!owner||owner.open||owner._replaced))return;view._recordLinkOwner=null;view._recordLinkOpen=key;RECORD_IMPL.open(view,ids[ids.length-1],{path:ids}).catch(error=>view.emit("error",{error}))};global.addEventListener("hashchange",read,{signal:view.lifetime.signal});view.lifetime.signal.addEventListener("abort",()=>{view._recordLinkOwner=null;view._recordLinkOpen=null},{once:true});Promise.resolve(view.ready).then(read,()=>{})};RECORD_IMPL.decorate=(view,dialog,{head,identity,options})=>{if(!view.view.record)return;try{recordSpec(view)}catch(error){return}
157
157
  dialog.id||=view.id+"-record";dialog.classList.add("cx-record-drawer");const state=dialog._cxPanel={stack:Array.isArray(options.stack)?options.stack:[],tab:options.tab||null,collapsed:new Map()},labels=view.labels;const live=h("div","cx-record-live cx-sr-only");live.setAttribute("aria-live","polite");dialog.appendChild(live);if(state.stack.length){const trail=h("nav","cx-record-trail"),crumbs=h("ol","cx-record-crumbs"),last=state.stack[state.stack.length-1];trail.setAttribute("aria-label",labels.recordTrail);const back=recordButton(labels.recordBack,()=>recordBack(view,dialog),"cx-record-back","back");back.setAttribute("aria-label",fill(labels.recordBackTo,{record:last.title||last.id}));state.stack.slice(-3).forEach((entry,at,list)=>{const item=h("li");item.appendChild(recordButton(entry.title||entry.id,()=>recordBack(view,dialog,list.length-at),"cx-record-crumb"));crumbs.appendChild(item)});trail.append(back,crumbs);identity.prepend(trail)}
158
- const summary=h("div","cx-record-summary");summary.hidden=true;head.after(summary);recordActionsMenu(view,dialog,identity);dialog.addEventListener("keydown",event=>{if(event.altKey&&event.key==="ArrowLeft"&&state.stack.length){event.preventDefault();recordBack(view,dialog)}});dialog.addEventListener("close",()=>{if(view.destroyed)return;const owner=view._recordLinkOwner;if(owner?.dialog!==dialog)return;if(dialog._replaced){view._recordLinkOwner=null;return}
159
- const ids=recordLinkRead(view);if(ids&&owner.link===recordLinkPrefix(view)+ recordLinkPath(ids))recordLinkWrite(view,null);view._recordLinkOwner=null;view._recordLinkOpen=null},{once:true})};function recordActionsMenu(view,dialog,identity){const spec=recordSpec(view),switches=spec.actions||{},labels=view.labels,items=[];const add=(label,task)=>items.push({label,task});if(switches.link!==false&&spec.deepLink)add(labels.recordCopyLink,()=>recordCopy(view,dialog,recordAddress(view,dialog._cxRecord)));if(switches.copy!==false){add(labels.recordCopyValues,()=>recordCopy(view,dialog,recordExport(view,dialog,"text")));add(labels.recordCopyJson,()=>recordCopy(view,dialog,recordExport(view,dialog,"json")))}
158
+ const summary=h("div","cx-record-summary");summary.hidden=true;head.after(summary);let projectedSubtitle;if(typeof view.opts.recordHeading==="function")dialog.addEventListener("cx-drawer-paint",()=>{if(projectedSubtitle){setText(projectedSubtitle,"");projectedSubtitle.hidden=true}
159
+ try{const heading=view.opts.recordHeading(Object.freeze(JSON.parse(JSON.stringify(dialog._cxRecord))));if(heading&&typeof heading.title==="string"&&heading.title.length<=512)setText(identity.querySelector("h4"),heading.title);if(heading&&typeof heading.subtitle==="string"&&heading.subtitle.length<=2000){let subtitle=identity.querySelector("p");if(!subtitle){subtitle=projectedSubtitle=h("p");identity.appendChild(subtitle)}
160
+ subtitle.classList.add("cx-record-subtitle");setText(subtitle,heading.subtitle);subtitle.hidden=!heading.subtitle}}catch(error){view.emit("error",{error})}});recordActionsMenu(view,dialog,identity);dialog.addEventListener("keydown",event=>{if(event.altKey&&event.key==="ArrowLeft"&&state.stack.length){event.preventDefault();recordBack(view,dialog)}});dialog.addEventListener("close",()=>{if(view.destroyed)return;const owner=view._recordLinkOwner;if(owner?.dialog!==dialog)return;if(dialog._replaced){view._recordLinkOwner=null;return}
161
+ const ids=recordLinkRead(view);if(ids&&owner.link===recordLinkPrefix(view)+ recordLinkPath(ids))recordLinkWrite(view,null);view._recordLinkOwner=null;view._recordLinkOpen=null},{once:true})};function recordActionsMenu(view,dialog,identity){dialog.querySelector(".cx-record-footer")?.remove();const spec=recordSpec(view),switches=spec.actions||{},labels=view.labels,items=[];const failed=error=>{recordAnnounce(dialog,error?.message??String(error));view.emit("error",{error})};const add=(label,task,prominent=false,visible=()=>true)=>{let running=false,button;const run=async()=>{if(running||!visible())return;running=true;if(button)button.disabled=true;try{return await task()}
162
+ finally{running=false;if(button)button.disabled=false}};const item={label,task:run,visible,primary:typeof prominent==="function"?prominent:()=>prominent===true};items.push(item);if(prominent){let footer=dialog.querySelector(".cx-record-footer");if(!footer){footer=h("footer","cx-record-footer");dialog.appendChild(footer)}
163
+ button=recordButton(label,()=>{Promise.resolve().then(run).catch(failed)},"cx-record-btn cx-record-primary");item.footer=button;footer.appendChild(button)}};if(switches.link!==false&&spec.deepLink)add(labels.recordCopyLink,()=>recordCopy(view,dialog,recordAddress(view,dialog._cxRecord)));if(switches.copy!==false){add(labels.recordCopyValues,()=>recordCopy(view,dialog,recordExport(view,dialog,"text")));add(labels.recordCopyJson,()=>recordCopy(view,dialog,recordExport(view,dialog,"json")))}
160
164
  if(switches.export!==false){add(labels.recordExportCsv,()=>recordDownload(view,dialog,"csv"));add(labels.recordExportJson,()=>recordDownload(view,dialog,"json"))}
161
- if(switches.print!==false)add(labels.recordPrint,()=>recordPrint(view,dialog));for(const action of[...(Array.isArray(view.opts.recordActions)?view.opts.recordActions:[]),...view.plugins.flatMap(item=>item.recordActions||[])]){if(!action||typeof action.label!=="string"||typeof action.run!=="function")continue;add(action.label,()=>{const record=dialog._cxRecord,entry=recordEntry(view,record.id);return action.run(Object.freeze({record:JSON.parse(JSON.stringify(record)),view:view.view.id,api:view.host.canopyx,payload:entry?.payload||null,signal:view.lifetime.signal}))})}
162
- if(!items.length)return;const menu=h("div","cx-record-menu"),toggle=recordButton("",()=>show(list.hidden),"cx-record-menu-btn","more"),list=h("div","cx-record-menu-list");list.id=dialog.id+"-actions";list.setAttribute("role","menu");list.setAttribute("aria-label",labels.recordActions);list.hidden=true;toggle.setAttribute("aria-label",labels.recordActions);toggle.title=labels.recordActions;toggle.setAttribute("aria-haspopup","menu");toggle.setAttribute("aria-expanded","false");toggle.setAttribute("aria-controls",list.id);const show=open=>{list.hidden=!open;toggle.setAttribute("aria-expanded",String(open));if(open)buttons[0].focus()};const buttons=items.map(item=>{const button=recordButton(item.label,()=>{show(false);toggle.focus();Promise.resolve().then(item.task).catch(error=>{recordAnnounce(dialog,error.message);view.emit("error",{error})})},"cx-record-menu-item");button.setAttribute("role","menuitem");button.tabIndex=-1;return button});list.append(...buttons);menu.append(toggle,list);identity.after(menu);menu.addEventListener("keydown",event=>{if(list.hidden)return;if(event.key==="Escape"){event.preventDefault();event.stopPropagation();show(false);toggle.focus();return}
165
+ if(switches.print!==false)add(labels.recordPrint,()=>recordPrint(view,dialog));for(const action of[...(Array.isArray(view.opts.recordActions)?view.opts.recordActions:[]),...view.plugins.flatMap(item=>item.recordActions||[])]){if(!action||typeof action.label!=="string"||typeof action.run!=="function")continue;const context=()=>{const record=dialog._cxRecord,entry=record&&recordEntry(view,record.id);return Object.freeze({record:record?JSON.parse(JSON.stringify(record)):{id:""},view:view.view.id,api:view.host.canopyx,payload:entry?.state==="ready"?JSON.parse(JSON.stringify(entry.payload)):null,signal:view.lifetime.signal})};const condition=(value,fallback)=>{if(typeof value!=="function")return value===undefined?fallback:value===true;try{return value(context())===true}catch(error){failed(error);return false}};add(action.label,()=>action.run(context()),()=>condition(action.prominent,false),()=>condition(action.visible,true))}
166
+ if(!items.length)return;const menu=h("div","cx-record-menu"),toggle=recordButton("",()=>show(list.hidden),"cx-record-menu-btn","more"),list=h("div","cx-record-menu-list");list.id=dialog.id+"-actions";list.setAttribute("role","menu");list.setAttribute("aria-label",labels.recordActions);list.hidden=true;toggle.setAttribute("aria-label",labels.recordActions);toggle.title=labels.recordActions;toggle.setAttribute("aria-haspopup","menu");toggle.setAttribute("aria-expanded","false");toggle.setAttribute("aria-controls",list.id);const show=open=>{list.hidden=!open;toggle.setAttribute("aria-expanded",String(open));if(open)buttons.find(button=>!button.hidden)?.focus()};const buttons=items.map(item=>{const button=recordButton(item.label,()=>{show(false);toggle.focus();Promise.resolve().then(item.task).catch(failed)},"cx-record-menu-item");button.setAttribute("role","menuitem");button.tabIndex=-1;item.button=button;return button});list.append(...buttons);menu.append(toggle,list);identity.after(menu);menu.addEventListener("keydown",event=>{if(list.hidden)return;if(event.key==="Escape"){event.preventDefault();event.stopPropagation();show(false);toggle.focus();return}
163
167
  if(event.key==="Tab"){show(false);return}
164
- const at=buttons.indexOf(document.activeElement);if(at<0||!["ArrowDown","ArrowUp","Home","End"].includes(event.key))return;event.preventDefault();event.stopPropagation();buttons[{ArrowDown:(at+1)%buttons.length,ArrowUp:(at-1+buttons.length)%buttons.length,Home:0,End:buttons.length-1}[event.key]].focus()});menu.addEventListener("focusout",event=>{if(!menu.contains(event.relatedTarget)&&event.relatedTarget)show(false)});dialog.addEventListener("pointerdown",event=>{if(!menu.contains(event.target))show(false)})}
168
+ const visible=buttons.filter(button=>!button.hidden),at=visible.indexOf(document.activeElement);if(at<0||!["ArrowDown","ArrowUp","Home","End"].includes(event.key))return;event.preventDefault();event.stopPropagation();visible[{ArrowDown:(at+1)%visible.length,ArrowUp:(at-1+visible.length)%visible.length,Home:0,End:visible.length-1}[event.key]].focus()});menu.addEventListener("focusout",event=>{if(!menu.contains(event.relatedTarget)&&event.relatedTarget)show(false)});dialog.addEventListener("pointerdown",event=>{if(!menu.contains(event.target))show(false)});const paint=()=>{for(const item of items){const visible=item.visible();item.button.hidden=!visible;if(item.footer)item.footer.hidden=!visible||!item.primary()}
169
+ menu.hidden=!items.some(item=>!item.button.hidden);const footer=dialog.querySelector(".cx-record-footer");if(footer)footer.hidden=!items.some(item=>item.footer&&!item.footer.hidden);if(menu.hidden)show(false)};dialog.addEventListener("cx-drawer-paint",paint);paint()}
165
170
  async function recordCopy(view,dialog,text){if(!global.navigator.clipboard?.writeText)recordFail("the clipboard is not available.");await global.navigator.clipboard.writeText(text);recordAnnounce(dialog,view.labels.recordCopied)}
166
171
  function recordFlat(cell,field,fmt){const kind=recordKind(cell),text=(value,spec=field)=>recordFlat(value,spec,fmt);if(kind==="items")return cell.items.map(item=>text(item)).join(", ");if(kind==="fields")return cell.fields.map(entry=>entry.name+": "+text(entry.value,{kind:entry.kind||"text"})).join("; ");if(kind==="records")return(cell.records.rows||cell.records.roots||[]).map(row=>cell.records.columns.map(column=>text(row.cells?.[column.id]??null,column)).filter(Boolean).join(" · ")).join("\n");if(kind==="events")return cell.events.map(event=>[event.time?formatValue(event.time,"datetime",fmt):"",event.kind,event.actor,event.summary].filter(Boolean).join(" · ")).join("\n");if(kind==="changes")return cell.changes.map(change=>change.name+": "+text(change.before??null)+ " → "+text(change.after??null)).join("\n");return cellText(cell,field.column||field,fmt)}
167
172
  function recordData(view,dialog){const record=dialog._cxRecord,entry=recordEntry(view,record.id),payload=entry?.state==="ready"?entry.payload:null;const fields=recordFields(view),layout=recordLayout(view,fields),items=[],seen=new Set();const walk=(sections,path)=>{for(const section of sections){const name=path?path+" / "+section.label:section.label;for(const field of section.fields)if(!seen.has(field.id)){seen.add(field.id);items.push({section:name,field,cell:recordCell(view,record,payload,field)})}