@evotecit/canopyx 0.3.18 → 0.3.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CanopyX.Html/Assets/canopyx-board.css +12 -12
  2. package/CanopyX.Html/Assets/canopyx-board.js +1 -1
  3. package/CanopyX.Html/Assets/canopyx-calendar.css +70 -57
  4. package/CanopyX.Html/Assets/canopyx-calendar.js +14 -14
  5. package/CanopyX.Html/Assets/canopyx-cell-range.css +4 -4
  6. package/CanopyX.Html/Assets/canopyx-cell-range.js +1 -1
  7. package/CanopyX.Html/Assets/canopyx-changes.css +55 -55
  8. package/CanopyX.Html/Assets/canopyx-changes.js +1 -1
  9. package/CanopyX.Html/Assets/canopyx-column-groups.css +5 -1
  10. package/CanopyX.Html/Assets/canopyx-column-groups.js +15 -9
  11. package/CanopyX.Html/Assets/canopyx-compare.css +4 -4
  12. package/CanopyX.Html/Assets/canopyx-compare.js +1 -1
  13. package/CanopyX.Html/Assets/canopyx-detail-rows.css +4 -4
  14. package/CanopyX.Html/Assets/canopyx-detail-rows.js +1 -1
  15. package/CanopyX.Html/Assets/canopyx-editing.css +3 -3
  16. package/CanopyX.Html/Assets/canopyx-editing.js +1 -1
  17. package/CanopyX.Html/Assets/canopyx-enhance.js +2 -2
  18. package/CanopyX.Html/Assets/canopyx-export.js +8 -8
  19. package/CanopyX.Html/Assets/canopyx-facets.css +19 -18
  20. package/CanopyX.Html/Assets/canopyx-facets.js +1 -1
  21. package/CanopyX.Html/Assets/canopyx-filter-editor.css +24 -24
  22. package/CanopyX.Html/Assets/canopyx-filter-editor.js +3 -3
  23. package/CanopyX.Html/Assets/canopyx-flow-checks.css +2 -2
  24. package/CanopyX.Html/Assets/canopyx-flow-checks.js +1 -1
  25. package/CanopyX.Html/Assets/canopyx-flow-command.css +3 -3
  26. package/CanopyX.Html/Assets/canopyx-flow-command.js +1 -1
  27. package/CanopyX.Html/Assets/canopyx-flow-dialog.css +2 -2
  28. package/CanopyX.Html/Assets/canopyx-flow-dialog.js +1 -1
  29. package/CanopyX.Html/Assets/canopyx-flow-drafts.css +2 -2
  30. package/CanopyX.Html/Assets/canopyx-flow-drafts.js +1 -1
  31. package/CanopyX.Html/Assets/canopyx-flow-entry.css +24 -23
  32. package/CanopyX.Html/Assets/canopyx-flow-entry.js +4 -4
  33. package/CanopyX.Html/Assets/canopyx-flow-host.css +2 -2
  34. package/CanopyX.Html/Assets/canopyx-flow-host.js +1 -1
  35. package/CanopyX.Html/Assets/canopyx-flow-module.mjs +4 -4
  36. package/CanopyX.Html/Assets/canopyx-flow-pick.css +4 -4
  37. package/CanopyX.Html/Assets/canopyx-flow-pick.js +1 -1
  38. package/CanopyX.Html/Assets/canopyx-flow-preview.css +1 -1
  39. package/CanopyX.Html/Assets/canopyx-flow-preview.js +1 -1
  40. package/CanopyX.Html/Assets/canopyx-flow-records.css +2 -2
  41. package/CanopyX.Html/Assets/canopyx-flow-records.js +1 -1
  42. package/CanopyX.Html/Assets/canopyx-flow-tasks.css +4 -4
  43. package/CanopyX.Html/Assets/canopyx-flow-tasks.js +1 -1
  44. package/CanopyX.Html/Assets/canopyx-flow.css +41 -41
  45. package/CanopyX.Html/Assets/canopyx-flow.js +1 -1
  46. package/CanopyX.Html/Assets/canopyx-format-editor.css +9 -9
  47. package/CanopyX.Html/Assets/canopyx-format-editor.js +1 -1
  48. package/CanopyX.Html/Assets/canopyx-formatting.css +13 -13
  49. package/CanopyX.Html/Assets/canopyx-formatting.js +3 -3
  50. package/CanopyX.Html/Assets/canopyx-forms.css +3 -3
  51. package/CanopyX.Html/Assets/canopyx-forms.js +1 -1
  52. package/CanopyX.Html/Assets/canopyx-grid-module.mjs +53 -42
  53. package/CanopyX.Html/Assets/canopyx-grid-options.css +8 -8
  54. package/CanopyX.Html/Assets/canopyx-grid-options.js +9 -2
  55. package/CanopyX.Html/Assets/canopyx-grid.css +99 -96
  56. package/CanopyX.Html/Assets/canopyx-grid.js +53 -42
  57. package/CanopyX.Html/Assets/canopyx-grouping.css +7 -7
  58. package/CanopyX.Html/Assets/canopyx-grouping.js +1 -1
  59. package/CanopyX.Html/Assets/canopyx-highlight.css +10 -10
  60. package/CanopyX.Html/Assets/canopyx-highlight.js +1 -1
  61. package/CanopyX.Html/Assets/canopyx-interactive.css +50 -49
  62. package/CanopyX.Html/Assets/canopyx-interactive.js +10 -8
  63. package/CanopyX.Html/Assets/canopyx-layouts.css +9 -9
  64. package/CanopyX.Html/Assets/canopyx-layouts.js +2 -2
  65. package/CanopyX.Html/Assets/canopyx-link.css +3 -3
  66. package/CanopyX.Html/Assets/canopyx-link.js +3 -3
  67. package/CanopyX.Html/Assets/canopyx-links.js +2 -2
  68. package/CanopyX.Html/Assets/canopyx-live.css +2 -2
  69. package/CanopyX.Html/Assets/canopyx-live.js +1 -1
  70. package/CanopyX.Html/Assets/canopyx-matrix.css +31 -31
  71. package/CanopyX.Html/Assets/canopyx-matrix.js +1 -1
  72. package/CanopyX.Html/Assets/canopyx-module.mjs +10 -8
  73. package/CanopyX.Html/Assets/canopyx-pager.css +1 -1
  74. package/CanopyX.Html/Assets/canopyx-pager.js +1 -1
  75. package/CanopyX.Html/Assets/canopyx-path.css +8 -8
  76. package/CanopyX.Html/Assets/canopyx-path.js +1 -1
  77. package/CanopyX.Html/Assets/canopyx-pivot.css +10 -10
  78. package/CanopyX.Html/Assets/canopyx-pivot.js +3 -3
  79. package/CanopyX.Html/Assets/canopyx-plan.css +24 -17
  80. package/CanopyX.Html/Assets/canopyx-plan.js +13 -9
  81. package/CanopyX.Html/Assets/canopyx-record-panel.css +47 -42
  82. package/CanopyX.Html/Assets/canopyx-record-panel.js +16 -9
  83. package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +56 -52
  84. package/CanopyX.Html/Assets/canopyx-reporting.css +104 -101
  85. package/CanopyX.Html/Assets/canopyx-reporting.js +56 -52
  86. package/CanopyX.Html/Assets/canopyx-stack.css +6 -6
  87. package/CanopyX.Html/Assets/canopyx-stack.js +1 -1
  88. package/CanopyX.Html/Assets/canopyx-time-slider.css +5 -5
  89. package/CanopyX.Html/Assets/canopyx-time-slider.js +1 -1
  90. package/CanopyX.Html/Assets/canopyx-timeline.css +19 -19
  91. package/CanopyX.Html/Assets/canopyx-timeline.js +2 -2
  92. package/CanopyX.Html/Assets/canopyx-tree-tools.css +21 -21
  93. package/CanopyX.Html/Assets/canopyx-tree-tools.js +3 -3
  94. package/CanopyX.Html/Assets/canopyx-ui-menu.css +7 -7
  95. package/CanopyX.Html/Assets/canopyx-ui-menu.js +1 -1
  96. package/CanopyX.Html/Assets/canopyx-ui-navigation.css +5 -5
  97. package/CanopyX.Html/Assets/canopyx-ui-navigation.js +1 -1
  98. package/CanopyX.Html/Assets/canopyx-ui-overlays.css +5 -5
  99. package/CanopyX.Html/Assets/canopyx-ui-overlays.js +5 -2
  100. package/CanopyX.Html/Assets/canopyx-ui-picker.css +2 -2
  101. package/CanopyX.Html/Assets/canopyx-ui-picker.js +1 -1
  102. package/CanopyX.Html/Assets/canopyx-ui-stepper.css +12 -12
  103. package/CanopyX.Html/Assets/canopyx-ui-stepper.js +1 -1
  104. package/CanopyX.Html/Assets/canopyx-ui-tabs.css +8 -8
  105. package/CanopyX.Html/Assets/canopyx-ui-tabs.js +1 -1
  106. package/CanopyX.Html/Assets/canopyx-view-intents.css +1 -1
  107. package/CanopyX.Html/Assets/canopyx-view-intents.js +1 -1
  108. package/CanopyX.Html/Assets/canopyx.css +47 -46
  109. package/CanopyX.Html/Assets/canopyx.js +10 -8
  110. package/JavaScript/column-groups.d.ts +24 -4
  111. package/JavaScript/grid.d.ts +11 -1
  112. package/JavaScript/hosts.d.ts +2 -0
  113. package/JavaScript/protocol.d.ts +2 -0
  114. package/JavaScript/records.d.ts +2 -0
  115. package/README.md +76 -206
  116. package/README.nuget.md +63 -87
  117. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- (function(global){"use strict";const installed=new WeakSet();const part={version:"2a4059ade4ca1439",requires:["ui-menu"],install(context){if(installed.has(context.RECORD_IMPL))return;const{RECORD_IMPL,UI_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;function changeCellText(cell,column,fmt){if(cell==null)return "—";const structured=isCellObject(cell)&&["items","fields","records","events","changes"].some(name=>cell[name]);if(isCellObject(cell)&&cellValue(cell)==null&&!cell.text&&!structured)return "null";const text=cellText(cell,column,fmt);return text.length?text:'""'}
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"cb6bcd1baf644a51",requires:["ui-menu"],install(context){if(installed.has(context.RECORD_IMPL))return;const{RECORD_IMPL,UI_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;function changeCellText(cell,column,fmt){if(cell==null)return "—";const structured=isCellObject(cell)&&["items","fields","records","events","changes"].some(name=>cell[name]);if(isCellObject(cell)&&cellValue(cell)==null&&!cell.text&&!structured)return "null";const text=cellText(cell,column,fmt);return text.length?text:'""'}
2
2
  const RECORD_KINDS=["items","fields","records","events","changes"],RECORD_LINK_KEY=/^[A-Za-z][\w.-]{0,31}$/, RECORD_MAX_STRUCTURE_DEPTH = 8;
3
3
  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)}
4
4
  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)}
@@ -100,7 +100,8 @@ for(const change of changes){if(!change||!recordText(change.name,4096))recordFai
100
100
  line.append(name,before,after);body.appendChild(line)}
101
101
  const thead=h("thead");thead.appendChild(head);table.append(caption,thead,body);element.appendChild(table)}
102
102
  let RECORD_SHOW_EMPTY=false;const recordId=(dialog,kind,id)=>dialog.id+"-"+kind+"-"+String(id).replace(/[^\w-]/g, "_");
103
- const recordOnDispose=(signal,cleanup)=>{const dispose=()=>{try{cleanup()}catch(error){console.error(error)}};if(signal.aborted)dispose();else signal.addEventListener("abort",dispose,{once:true})};function recordContext(view,record,dialog,context,payload){const ctx={view,record,payload,dialog,labels:view.labels,fmt:view.fmt,signal:context.signal,index:context.index,origins:0,pending:[],phone:view.host.clientWidth<=640,print:!!context.print,width:context.print?520:view.host.clientWidth<=640?300:380,row:{id:record.id,cells:recordMerge(record.cells,payload?.cells,record.fields,payload?.fields)},node:view.kind==="tree"?{...record,cells:recordMerge(record.cells,payload?.cells)}:null};ctx.navigate=(ref,origin)=>recordNavigate(ctx,ref,origin);ctx.repaint=()=>{if(!context.signal.aborted&&dialog._cxRecord===record&&dialog.isConnected)recordRepaint(view,dialog,record,context.index)};return ctx}
103
+ const recordOnDispose=(signal,cleanup)=>{const dispose=()=>{try{cleanup()}catch(error){console.error(error)}};if(signal.aborted)dispose();else signal.addEventListener("abort",dispose,{once:true})};const recordJump=(body,tools,section,instant)=>{const top=section.getBoundingClientRect().top-body.getBoundingClientRect().top+body.scrollTop -(tools.isConnected?tools.offsetHeight:0);const reduce=global.matchMedia?.("(prefers-reduced-motion: reduce)").matches;body.scrollTo({top:Math.max(0,Math.round(top)),behavior:reduce||instant?"instant":"smooth"})};const recordTrail=(sections,id)=>{for(const section of sections){if(section.id===id)return[id];const inner=recordTrail(section.sections,id);if(inner)return[section.id,...inner]}
104
+ return null};function recordContext(view,record,dialog,context,payload){const ctx={view,record,payload,dialog,labels:view.labels,fmt:view.fmt,signal:context.signal,index:context.index,origins:0,pending:[],phone:view.host.clientWidth<=640,print:!!context.print,width:context.print?520:view.host.clientWidth<=640?300:380,row:{id:record.id,cells:recordMerge(record.cells,payload?.cells,record.fields,payload?.fields)},node:view.kind==="tree"?{...record,cells:recordMerge(record.cells,payload?.cells)}:null};ctx.navigate=(ref,origin)=>recordNavigate(ctx,ref,origin);ctx.repaint=()=>{if(!context.signal.aborted&&dialog._cxRecord===record&&dialog.isConnected)recordRepaint(view,dialog,record,context.index)};return ctx}
104
105
  function recordMerge(...sources){const cells=Object.create(null);for(const source of sources)if(source)for(const key of Object.keys(source))if(key!=="__proto__")cells[key]=source[key];return cells}
105
106
  function recordRepaint(view,dialog,record,index){const body=dialog.querySelector(".cx-drawer-body"),scroll=body?.scrollTop||0,active=document.activeElement,inside=body?.contains(active);const section=inside&&active.closest("[data-cx-section]")?.getAttribute("data-cx-section"),field=inside&&active.closest("[data-cx-field]")?.getAttribute("data-cx-field");const kind=inside&&[...active.classList].find(name=>name.startsWith("cx-record-")),id=inside&&active.id;dialog._cxPaint(record,index);if(body)body.scrollTop=scroll;if(!inside||body.contains(document.activeElement))return;const scope=field?body.querySelector('[data-cx-field="'+CSS.escape(field)+ '"]'):section?body.querySelector('[data-cx-section="'+CSS.escape(section)+ '"]'):body;const title=dialog.querySelector(".cx-drawer-h h4"),target=id&&body.querySelector("#"+CSS.escape(id))||kind&&scope?.querySelector("."+kind)||title;if(target===title)view.focusRing(title);else target?.focus({preventScroll:true})}
106
107
  const recordVisible=(ctx,field,cell,showEmpty)=>showEmpty||!recordEmpty(cell,field,ctx.fmt)||ctx.view.recordKeepField?.(field.id,ctx.record)===true;function recordHasContent(ctx,section,showEmpty){return!!section.renderer||section.fields.some(field=>recordVisible(ctx,field,recordCell(ctx.view,ctx.record,ctx.payload,field),showEmpty))||
@@ -122,12 +123,14 @@ RECORD_IMPL.paint=(view,record,body,dialog,context)=>{const state=dialog._cxPane
122
123
  state.index=context.index;let layout;try{layout=recordLayout(view,recordFields(view))}
123
124
  catch(error){view.emit("error",{error});return view.paintDrawerBody.call(Object.create(view,{recordNeeded:{value:()=>false}}),record,body,dialog,context)}
124
125
  const entry=recordEnsure(view,record.id),payload=entry?.state==="ready"?entry.payload:null,ctx=recordContext(view,record,dialog,context,payload);if(view.loadHistory&&!view._recordHistory&&(view.view.record?.fields||[]).some(field=>["statusStrip","sparklineBars","sparklineLine"].includes(field.presenter?.kind)))
125
- view._recordHistory=Promise.resolve(view.loadHistory()).then(()=>{if(dialog.isConnected&&dialog._cxRecord)recordRepaint(view,dialog,dialog._cxRecord,dialog._cxPanel?.index)},()=>{});const showEmpty=RECORD_SHOW_EMPTY||!layout.hideEmpty;const tabs=layout.tabs.filter(tab=>tab.sections.some(section=>recordHasContent(ctx,section,showEmpty)));if(!tabs.length)tabs.push(layout.tabs[0]);if(!tabs.some(tab=>tab.id===state.tab))state.tab=tabs[0].id;recordSummary(ctx,layout,dialog);body.replaceChildren();const tools=h("div","cx-record-tools"),panel=h("div","cx-record-panel"),sub=h("div","cx-record-subtools");let tabLifetime,tabContext;const paintTab=()=>{tabLifetime?.abort();tabLifetime=new AbortController();tabContext=recordContext(view,record,dialog,{...context,signal:AbortSignal.any([context.signal,tabLifetime.signal])},payload);const tab=tabs.find(item=>item.id===state.tab),sections=tab.sections.map(section=>recordSection(tabContext,section,state,showEmpty)).filter(Boolean);panel.replaceChildren(...sections);sub.replaceChildren();if(tabs.length>1){panel.setAttribute("role","tabpanel");panel.id=recordId(dialog,"p",tab.id);panel.setAttribute("aria-labelledby",recordId(dialog,"t",tab.id));panel.tabIndex=0}
126
- if(layout.jump!==false&&sections.length>=(layout.jump?2:4)){const jump=h("nav","cx-record-jump");jump.setAttribute("aria-label",ctx.labels.recordSections);for(const element of sections){const target=element.querySelector(".cx-record-toggle");jump.appendChild(recordButton(target.textContent,()=>{element.scrollIntoView({block:"start"});target.focus({preventScroll:true})},"cx-record-jump-link"))}
126
+ view._recordHistory=Promise.resolve(view.loadHistory()).then(()=>{if(dialog.isConnected&&dialog._cxRecord)recordRepaint(view,dialog,dialog._cxRecord,dialog._cxPanel?.index)},()=>{});const showEmpty=RECORD_SHOW_EMPTY||!layout.hideEmpty;const tabs=layout.tabs.filter(tab=>tab.sections.some(section=>recordHasContent(ctx,section,showEmpty)));if(!tabs.length)tabs.push(layout.tabs[0]);const owner=state.jump&&tabs.find(tab=>recordTrail(tab.sections,state.jump));if(owner){state.tab=owner.id;for(const id of recordTrail(owner.sections,state.jump))state.collapsed.set(id,false)}
127
+ if(!tabs.some(tab=>tab.id===state.tab))state.tab=tabs[0].id;recordSummary(ctx,layout,dialog);body.replaceChildren();const tools=h("div","cx-record-tools"),panel=h("div","cx-record-panel"),sub=h("div","cx-record-subtools");let tabLifetime,tabContext;const paintTab=()=>{tabLifetime?.abort();tabLifetime=new AbortController();tabContext=recordContext(view,record,dialog,{...context,signal:AbortSignal.any([context.signal,tabLifetime.signal])},payload);const tab=tabs.find(item=>item.id===state.tab),sections=tab.sections.map(section=>recordSection(tabContext,section,state,showEmpty)).filter(Boolean);panel.replaceChildren(...sections);sub.replaceChildren();if(tabs.length>1){panel.setAttribute("role","tabpanel");panel.id=recordId(dialog,"p",tab.id);panel.setAttribute("aria-labelledby",recordId(dialog,"t",tab.id));panel.tabIndex=0}
128
+ if(layout.jump!==false&&sections.length>=(layout.jump?2:4)){const jump=h("nav","cx-record-jump");jump.setAttribute("aria-label",ctx.labels.recordSections);for(const element of sections){const target=element.querySelector(".cx-record-toggle");jump.appendChild(recordButton(target.textContent,()=>{recordJump(body,tools,element);target.focus({preventScroll:true})},"cx-record-jump-link"))}
127
129
  sub.appendChild(jump)}
128
130
  const hidden=layout.hideEmpty?recordEmptyCount(ctx,layout.tabs.flatMap(item=>item.sections)):0;if(hidden||RECORD_SHOW_EMPTY&&layout.hideEmpty){const toggle=recordButton(RECORD_SHOW_EMPTY?ctx.labels.recordHideEmpty:fill(ctx.labels.recordShowEmpty,{count:recordCount(ctx,hidden)}),()=>{RECORD_SHOW_EMPTY=!RECORD_SHOW_EMPTY;recordRepaint(view,dialog,record,context.index);dialog.querySelector(".cx-record-empty")?.focus()},"cx-record-empty");toggle.setAttribute("aria-pressed",String(RECORD_SHOW_EMPTY));sub.appendChild(toggle)}
129
131
  sub.hidden=!sub.firstChild};const select=(id,focus)=>{state.tab=id;for(const button of tools.querySelectorAll("[role=tab]")){const on=button.id===recordId(dialog,"t",id);button.setAttribute("aria-selected",String(on));button.tabIndex=on?0:-1;if(on)button.setAttribute("aria-controls",recordId(dialog,"p",id));else button.removeAttribute("aria-controls")}
130
- paintTab();recordMount(tabContext,panel);dialog.dispatchEvent(new CustomEvent("cx-drawer-paint",{detail:{id:record.id,index:context.index??null}}));if(focus)tools.querySelector("[aria-selected=true]")?.focus()};if(tabs.length>1)tools.appendChild(recordTabs(ctx,layout,state,tabs,select));tools.appendChild(sub);paintTab();body.append(tools,panel);tools.hidden=tabs.length<2&&sub.hidden;if(entry?.state==="loading"){const note=h("p","cx-record-note");setText(note,ctx.labels.loading);panel.prepend(note);entry.promise.then(()=>ctx.repaint(),()=>ctx.repaint())}else if(entry?.state==="error"){const note=h("p","cx-record-note cx-record-error");setText(note,fill(ctx.labels.recordLoadFailed,{error:entry.error.message}));note.setAttribute("role","alert");note.appendChild(recordButton(ctx.labels.recordRetry,()=>{view._recordPayloads.delete(recordCacheKey(view,record.id));ctx.repaint()},"cx-record-retry"));panel.prepend(note)}
132
+ paintTab();recordMount(tabContext,panel);dialog.dispatchEvent(new CustomEvent("cx-drawer-paint",{detail:{id:record.id,index:context.index??null}}));if(focus)tools.querySelector("[aria-selected=true]")?.focus()};if(tabs.length>1)tools.appendChild(recordTabs(ctx,layout,state,tabs,select));tools.appendChild(sub);paintTab();body.append(tools,panel);body.style.paddingBlockStart="0px";tools.hidden=tabs.length<2&&sub.hidden;if(state.jump&&entry?.state!=="loading"){const jump=state.jump,find=()=>body.querySelector('[data-cx-section="'+CSS.escape(jump)+ '"]');if(find())global.requestAnimationFrame(()=>{const target=find();if(state.jump!==jump||!target)return;state.jump=null;recordJump(body,body.querySelector(".cx-record-tools")||tools,target,true)});else state.jump=null}
133
+ if(entry?.state==="loading"){const note=h("p","cx-record-note");setText(note,ctx.labels.loading);panel.prepend(note);entry.promise.then(()=>ctx.repaint(),()=>ctx.repaint())}else if(entry?.state==="error"){const note=h("p","cx-record-note cx-record-error");setText(note,fill(ctx.labels.recordLoadFailed,{error:entry.error.message}));note.setAttribute("role","alert");note.appendChild(recordButton(ctx.labels.recordRetry,()=>{view._recordPayloads.delete(recordCacheKey(view,record.id));ctx.repaint()},"cx-record-retry"));panel.prepend(note)}
131
134
  recordLinkWrite(view,record,dialog)};function recordSummary(ctx,layout,dialog){const box=dialog.querySelector(".cx-record-summary");if(!box)return;box.replaceChildren();const header=layout.header,value=id=>{const field=layout.byId.get(id);return field&&[field,recordCell(ctx.view,ctx.record,ctx.payload,field)]};if(header?.status){const[field,cell]=value(header.status)||[];if(field&&!recordEmpty(cell,field,ctx.fmt)){const status=h("div","cx-record-status");status.setAttribute("data-cx-fact",field.id);recordValue(ctx,field,cell,status);box.appendChild(status)}}
132
135
  const facts=h("dl","cx-record-facts");for(const id of header?.facts||[]){const[field,cell]=value(id)||[];if(!field||recordEmpty(cell,field,ctx.fmt))continue;const item=h("div","cx-record-fact"),term=h("dt"),detail=h("dd");item.setAttribute("data-cx-fact",field.id);setText(term,field.title);recordValue(ctx,field,cell,detail);item.append(term,detail);facts.appendChild(item)}
133
136
  if(facts.firstChild)box.appendChild(facts);box.hidden=!box.firstChild}
@@ -146,18 +149,22 @@ if(!row)recordFail("record "+id+" is not available.");const returnFocus=options.
146
149
  return view.openGridDrawer(row,index,returnFocus,options)}
147
150
  async function recordOpenNode(view,id,options){await view.requirePart("tree-tools");let w=view.keyMap.get(id);if(!w&&Array.isArray(options.path)&&options.path.length){await view.expandPath(options.path,{focus:false});w=view.keyMap.get(id)}
148
151
  if(!w)recordFail("record "+id+" is not available.");return view.showDetails(id,{...options,node:w.h})}
149
- const recordLinkKey=view=>view.view.record?.deepLink?.key||"record";const recordLinkParams=()=>(global.location.hash||"").replace(/^#/, "").split("&").filter(Boolean);
152
+ const recordLinkKey=view=>view.view.record?.deepLink?.key||"record";const recordSectionPrefix=view=>recordLinkKey(view)+ "Section="+encodeURIComponent(view.view.id)+ ":";function recordLinkSection(view){const prefix=recordSectionPrefix(view),param=recordLinkParams().find(item=>item.startsWith(prefix));try{return param&&decodeURIComponent(param.slice(prefix.length))||null}
153
+ catch(error){return null}}
154
+ const recordLinkParams=()=>(global.location.hash||"").replace(/^#/, "").split("&").filter(Boolean);
150
155
  const recordLinkPath=ids=>ids.map(encodeURIComponent).join("/");function recordLinkRead(view){const prefix=recordLinkKey(view)+ "=";for(const param of recordLinkParams()){const value=param.startsWith(prefix)?param.slice(prefix.length):"",at=value.indexOf(":");if(at<1)continue;try{if(decodeURIComponent(value.slice(0,at))!==view.view.id)continue;const rest=value.slice(at+1),ids=(view.kind==="tree"?rest.split("/"):[rest]).map(decodeURIComponent);if(ids.every(id=>id))return ids}catch(error){}}
151
156
  return null}
152
157
  function recordLinkFor(view,record){const ids=[];if(view.kind==="tree")for(let w=view.keyMap.get(record.id);w&&w!==view.root&&w.key!=null;w=w.parent)ids.unshift(w.key);return recordLinkKey(view)+ "="+encodeURIComponent(view.view.id)+ ":"+recordLinkPath(ids.length?ids:[record.id])}
153
158
  const recordLinkPrefix=view=>recordLinkKey(view)+ "="+encodeURIComponent(view.view.id)+ ":";function recordAddress(view,record){const prefix=recordLinkPrefix(view),params=recordLinkParams().filter(param=>!param.startsWith(prefix));params.push(recordLinkFor(view,record));return global.location.href.replace(/#.*$/, "") + "#" + params.join("&");
154
159
  }
155
- function recordLinkWrite(view,record,dialog){if(!view.view.record?.deepLink)return;const link=record&&recordLinkFor(view,record);view._recordLinkOwner=record?{dialog,link}:null;const prefix=recordLinkPrefix(view),params=recordLinkParams().filter(param=>!param.startsWith(prefix));if(record)params.push(link);const hash=params.length?"#"+params.join("&"):"";if((global.location.hash||"")===hash)return;try{global.history.replaceState(global.history.state,"",hash||global.location.pathname+global.location.search)}
160
+ function recordLinkWrite(view,record,dialog){if(!view.view.record?.deepLink)return;const link=record&&recordLinkFor(view,record);view._recordLinkOwner=record?{dialog,link}:null;const prefix=recordLinkPrefix(view),section=recordSectionPrefix(view),params=recordLinkParams().filter(param=>!param.startsWith(prefix)&&!param.startsWith(section));if(record)params.push(link);const hash=params.length?"#"+params.join("&"):"";if((global.location.hash||"")===hash)return;try{global.history.replaceState(global.history.state,"",hash||global.location.pathname+global.location.search)}
156
161
  catch(error){}
157
162
  view._recordLinkOpen=record?recordLinkPath(recordLinkRead(view)||[]):null}
158
163
  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}
159
- 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}
160
- 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)}
164
+ if(key===view._recordLinkOpen&&(!owner||owner.open||owner._replaced)){const section=recordLinkSection(view);if(section&&owner?.open&&owner._cxPanel&&owner._cxRecord){owner._cxPanel.jump=section;recordRepaint(view,owner,owner._cxRecord,owner._cxPanel.index);recordLinkWrite(view,owner._cxRecord,owner)}
165
+ return}
166
+ view._recordLinkOwner=null;view._recordLinkOpen=key;const section=recordLinkSection(view);RECORD_IMPL.open(view,ids[ids.length-1],section?{path:ids,section}:{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}
167
+ 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,jump:typeof options.section==="string"&&options.section||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)}
161
168
  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}
162
169
  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)}
163
170
  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}