@mohsinonxrm/pptb-commandbar-studio 0.5.1 → 0.6.0

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 (84) hide show
  1. package/CHANGELOG.md +363 -99
  2. package/LICENSE +661 -661
  3. package/README.md +343 -316
  4. package/SECURITY.md +62 -0
  5. package/dist/assets/BulkPublishModal-DqX2QmUD.js +29 -0
  6. package/dist/assets/CommandEditorPanel-DidGBtFC.js +1 -0
  7. package/dist/assets/CommandPalette-AuDfsF8l.js +1 -0
  8. package/dist/assets/ConflictDrawer-DxQ_jd-x.js +1 -0
  9. package/dist/assets/CrmParameterEditor-BdmP65mF.js +1 -0
  10. package/dist/assets/DiffViewer-BZuqvP4f.js +7 -0
  11. package/dist/assets/HideInsteadOfDeleteModal-BYHCTZrG.js +1 -0
  12. package/dist/assets/IconPickerModal-Bw0C7KwV.js +1 -0
  13. package/dist/assets/ImportXmlModal-B8NgiUDZ.js +1 -0
  14. package/dist/assets/LocalizationEditor-tmniX5PC.js +1 -0
  15. package/dist/assets/MonacoEditor-Bbg9u2FW.js +2 -0
  16. package/dist/assets/NewButtonModal-BVvlbCv4.js +1 -0
  17. package/dist/assets/NewGroupModal-CgQy-uo4.js +1 -0
  18. package/dist/assets/NewTabModal-B_2-kwAx.js +1 -0
  19. package/dist/assets/RuleEditorPanel-BkNwBgaP.js +1 -0
  20. package/dist/assets/ScalingEditorPanel-ezMkzvG1.js +1 -0
  21. package/dist/assets/TabDisplayRulesPanel-trzExQ1T.js +1 -0
  22. package/dist/assets/UrlComposerModal-BlVXHKRM.js +1 -0
  23. package/dist/assets/WebResourceBrowser-DaPOZQ5X.js +1 -0
  24. package/dist/assets/XmlDrawer-BI6Wy6kL.js +2 -0
  25. package/dist/assets/crmParameters-rgfZhhzN.js +1 -0
  26. package/dist/assets/cssMode-DdC7kBk-.js +1 -0
  27. package/dist/assets/{dnd-DHB99ZH7.js → dnd-fsSwRnQv.js} +2 -2
  28. package/dist/assets/{editor.worker-CdQrwHl8.js → editor.worker-1APKdqmi.js} +2 -2
  29. package/dist/assets/fluent-icons-DxKNRZ1A.js +1 -0
  30. package/dist/assets/fluent-ui-D7EtYwEg.js +43 -0
  31. package/dist/assets/{freemarker2-B8bME0pA.js → freemarker2-DDn-Wpd6.js} +1 -1
  32. package/dist/assets/{handlebars-zIyCxTW6.js → handlebars-Ck_SjSJx.js} +1 -1
  33. package/dist/assets/{html-B5hFqu3X.js → html-BaJUqhKx.js} +1 -1
  34. package/dist/assets/htmlMode-CnYhJfhG.js +1 -0
  35. package/dist/assets/index-Bu7BlRFk.js +139 -0
  36. package/dist/assets/{javascript-BQGsYMat.js → javascript-2UlV1Qbm.js} +1 -1
  37. package/dist/assets/{jsonMode-CR0b-9Un.js → jsonMode-BmSpB9yr.js} +1 -1
  38. package/dist/assets/{liquid-DLq8jbP8.js → liquid-CE2reFvH.js} +1 -1
  39. package/dist/assets/{lspLanguageFeatures-C3buAG32.js → lspLanguageFeatures-BvbzEddk.js} +2 -2
  40. package/dist/assets/{mdx-5ni22WXY.js → mdx-BvcZv3tC.js} +1 -1
  41. package/dist/assets/{monaco-BLZnQb2P.js → monaco-Bx8A1Vm1.js} +4 -4
  42. package/dist/assets/monaco-Dprb6f6S.css +1 -0
  43. package/dist/assets/{python-F20Pd69B.js → python-MTPSN2vk.js} +1 -1
  44. package/dist/assets/{razor-3xmsG6cc.js → razor-Ccq_CgR8.js} +1 -1
  45. package/dist/assets/ruleKinds-B9hACGaq.js +1 -0
  46. package/dist/assets/{server.browser-DfdiBs1P.js → server.browser-C3R9jebn.js} +1 -1
  47. package/dist/assets/{tsMode-Cyusk9p4.js → tsMode-2cv3qhqp.js} +1 -1
  48. package/dist/assets/{typescript-BXT-ECX3.js → typescript-BD6t7JEG.js} +1 -1
  49. package/dist/assets/webResourceService-CvyHBu7T.js +1 -0
  50. package/dist/assets/{xml-Cwzeco8o.js → xml-DJGPA7j9.js} +1 -1
  51. package/dist/assets/xmlValidator-D7JG-eNC.js +3 -0
  52. package/dist/assets/{yaml-BHUePD-R.js → yaml-Cpl0dvFM.js} +1 -1
  53. package/dist/icons/icon.svg +16 -0
  54. package/dist/index.html +24 -18
  55. package/index.html +18 -12
  56. package/package.json +18 -32
  57. package/dist/assets/BulkPublishModal-DlglMah4.js +0 -29
  58. package/dist/assets/CommandEditorPanel-4pYnil3i.js +0 -1
  59. package/dist/assets/CommandPalette-iYxzI2G_.js +0 -1
  60. package/dist/assets/ConflictDrawer-DBPRRkoa.js +0 -1
  61. package/dist/assets/DiffViewer-DFBJPZKA.js +0 -7
  62. package/dist/assets/IconPickerModal-Bg0Zc8UZ.js +0 -1
  63. package/dist/assets/ImportXmlModal-BccMoaDv.js +0 -3
  64. package/dist/assets/LocalizationEditor-DVZy2uLy.js +0 -1
  65. package/dist/assets/MonacoEditor-DFYisBG6.js +0 -2
  66. package/dist/assets/NewButtonModal-D5Hz1yx4.js +0 -1
  67. package/dist/assets/NewGroupModal-BgTVG-VJ.js +0 -1
  68. package/dist/assets/NewTabModal-7-ZPcPi-.js +0 -1
  69. package/dist/assets/RuleEditorPanel-BwQzOQBe.js +0 -1
  70. package/dist/assets/ScalingEditorPanel-B221zNLL.js +0 -1
  71. package/dist/assets/TabDisplayRulesPanel-drKzEO_E.js +0 -1
  72. package/dist/assets/UrlComposerModal-Bnifp4oB.js +0 -1
  73. package/dist/assets/WebResourceBrowser-qtcNTNge.js +0 -1
  74. package/dist/assets/XmlDrawer-CN941TbU.js +0 -2
  75. package/dist/assets/cssMode-DFSY9yCW.js +0 -1
  76. package/dist/assets/fluent-icons-DiKr_qRE.js +0 -1
  77. package/dist/assets/fluent-ui-kUA2U4Gr.js +0 -43
  78. package/dist/assets/htmlMode-BmPxEBms.js +0 -1
  79. package/dist/assets/index-DjHxPFpB.js +0 -6
  80. package/dist/assets/monaco-Dvl_Svmm.css +0 -1
  81. package/dist/assets/webResourceService-Ck07E3GN.js +0 -1
  82. package/dist/assets/xmlGenerator-DEaVrfZJ.js +0 -130
  83. package/dist/stats.html +0 -4949
  84. package/npm-shrinkwrap.json +0 -13253
package/SECURITY.md ADDED
@@ -0,0 +1,62 @@
1
+ # Security Policy
2
+
3
+ ## Reporting a Vulnerability
4
+
5
+ Please do **not** open a public issue for security concerns. Use GitHub
6
+ Security Advisories (private):
7
+ <https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/security/advisories/new>
8
+
9
+ I'll acknowledge receipt within a few business days and coordinate a fix +
10
+ disclosure timeline with you.
11
+
12
+ ## Scope
13
+
14
+ Command Bar Studio is a client-side visual designer for Dataverse classic
15
+ ribbon / command bar customizations. It runs embedded in Power Platform
16
+ ToolBox (PPTB) and talks to Dataverse only through the host's
17
+ `dataverseAPI` bridge. Vulnerability reports of interest:
18
+
19
+ - **Authentication / token handling** — any path that could leak a
20
+ Dataverse access token, the PPTB session token, or a connection's
21
+ credentials from the host bridge.
22
+ - **Cross-site / injection** — XSS or markup injection via labels,
23
+ tooltips, rule values, web resource content, icon SVGs, or imported
24
+ RibbonDiffXml rendered in the canvas, XML drawer or diff viewer.
25
+ - **Generated customizations** — paths where the studio could emit
26
+ RibbonDiffXml or a solution package that does something other than what
27
+ the user designed (e.g. injecting commands, rules or web resources the
28
+ user didn't add).
29
+ - **CSP / sandbox escape** — anything that lets studio code execute
30
+ outside the host's iframe / allowed origins, or fetch from a
31
+ non-Dataverse host.
32
+ - **Local persistence** — the auto-saved draft in `localStorage` being
33
+ read across org scopes, or a crafted draft triggering code execution on
34
+ restore.
35
+ - **Dependency vulnerabilities** — known CVEs in production dependencies
36
+ (`@fluentui/*`, `monaco-editor`, `fflate`, etc.) that affect the shipped
37
+ bundle.
38
+
39
+ ## Out of scope
40
+
41
+ - **Changes the user makes to their own environment** — publishing ribbon
42
+ customizations is the tool's purpose; the user is responsible for what
43
+ they publish. Use a development environment first.
44
+ - **Behavior of JavaScript web resources or Power Fx** that the user
45
+ writes and wires to commands — the studio only references them.
46
+ - **Dev-only tooling** (anything under `dev/`) — it is not part of the
47
+ published npm package.
48
+
49
+ ## Supported versions
50
+
51
+ | Version | Supported |
52
+ |---|---|
53
+ | The current stable release (npm `latest`) | ✅ Fixes and security fixes |
54
+ | The previous minor release | ✅ Critical and security fixes for 30 days after the next minor ships (npm `support-X.Y`) |
55
+ | Betas (npm `beta`) | Fixed in the next beta |
56
+ | Anything older | ❌ |
57
+
58
+ 0.5.x keeps critical and security fixes for 30 days after 0.6.0 ships, because 0.6
59
+ requires Power Platform ToolBox 1.2.7. See [RELEASING.md](RELEASING.md) →
60
+ *Supported versions*.
61
+
62
+ Thanks for helping keep the tool safe.
@@ -0,0 +1,29 @@
1
+ import{z as n,y as ws}from"./fluent-icons-DxKNRZ1A.js";import{a as L,R as se}from"./monaco-Bx8A1Vm1.js";import{p as fe,h as xs,g as Cs,m as Se,j as Is,k as Rs,l as js,n as Ss,o as vs,q as rs,r as ks,s as Ds,t as Ps,v as $s,e as ge,x as Ns,y as As,z as Ls,A as Ge,B as Es,D as Ts,E as ve,F as zs,G as Xs,H as B,c as Ae,I as Ms,J as Os,K as Je,L as Us,M as ke,N as Bs,O as Ye,P as Vs,a as De,u as S,b as re,Q as Fs,R as Ks,S as Ze}from"./index-Bu7BlRFk.js";import{w as qs,v as cs}from"./xmlValidator-D7JG-eNC.js";import{c as Ws}from"./webResourceService-CvyHBu7T.js";import{D as _s,h as Hs,i as Gs,j as Js,k as Ys,M as O,e as U,t as _,a5 as Zs,T as Pe,F as $e,an as Qs,O as Qe,I as en,a1 as sn,a6 as nn,B as Ne,c as tn,ao as on,l as an}from"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";import"./ruleKinds-B9hACGaq.js";import"./crmParameters-rgfZhhzN.js";let es=0;async function Le(e){const t=typeof window<"u"?window.toolboxAPI:void 0;es++===0&&await ss(()=>t?.preventClose?.());try{return await e()}finally{--es===0&&await ss(()=>t?.releasePreventClose?.())}}const ln=2e3;async function ss(e){let t;try{await Promise.race([e(),new Promise(i=>t=setTimeout(i,ln))])}catch{}finally{clearTimeout(t)}}function ce(e,t){const i=e.match(new RegExp(`\\s${t}="([^"]*)"`));return i?i[1]:null}function ns(e,t,i){const d=e.indexOf(i,t);return e.slice(t,d===-1?void 0:d).match(/<result\s[^>]*>/g)??[]}function ts(e){const t=e.find(i=>ce(i,"result")!=="success");if(t){const i=ce(t,"errorcode")??"",d=ce(t,"errortext")??"unknown error";return{ok:!1,message:`Dataverse rejected the ribbon (${i}): ${d}`}}return null}function rn(e,t){if(!e)return{ok:!1,message:"The import job returned no result data, so the ribbon import could not be verified."};if(t.kind==="application"){const a=e.search(/<ribbon\s[^>]*processed="true"/);return a===-1?{ok:!1,message:"Import completed, but Dataverse did not process the application ribbon."}:ts(ns(e,a,"</ribbon>"))??{ok:!0,message:"Application ribbon imported."}}const i=new Set(t.names.filter(Boolean).map(a=>a.toLowerCase())),d=/<entityRibbon\s[^>]*>/g;let c;for(;c=d.exec(e);){const a=(ce(c[0],"id")??"").toLowerCase();if(i.has(a))return ce(c[0],"processed")!=="true"?{ok:!1,message:`Dataverse did not process the ribbon for ${a}.`}:ts(ns(e,c.index,"</entityRibbon>"))??{ok:!0,message:`Ribbon for ${a} imported.`}}return{ok:!1,message:`Import completed, but Dataverse did not apply a ribbon for ${t.names.join(" / ")} (no entityRibbon result in the import job). Nothing was changed.`}}const Y=window.dataverseAPI;function cn(e,t){return Y.execute({operationName:"ImportSolution",operationType:"action",parameters:{CustomizationFile:e,ImportJobId:t,OverwriteUnmanagedCustomizations:!0,PublishWorkflows:!1}})}function dn(e){const t=e.map(i=>`<entity>${B(i)}</entity>`).join("");return Y.execute({operationName:"PublishXml",operationType:"action",parameters:{ParameterXml:`<importexportxml><entities>${t}</entities></importexportxml>`}})}function os(e){const t=e.data?.progress;return!!(typeof t=="object"&&t!==null&&t.completed===!0||typeof e.progress=="number"&&e.progress>=100||typeof t=="number"&&t>=100||e.completedon||e.data?.completedon||e.statuscode===30)}function un(e){const t=e.titles.map(i=>`<Title languagecode="${i.languageCode}" description="${B(i.description)}"/>`).join("");return`<LocLabel Id="${B(e.id)}"><Titles>${t}</Titles></LocLabel>`}async function ds(e){const t=e.entity?.logicalName??"{!EntityLogicalName}",i={deletedContainerIds:e.plan.deletedContainerIds??[],movedButtons:e.plan.movedButtons??[],editedLocLabelIds:e.plan.editedLocLabelIds??[],editedTabIds:e.plan.editedTabIds??[]},d=e.locLabels.filter(o=>i.editedLocLabelIds.includes(o.id)),c=e.languageCode??1033;for(const o of e.plan.renamedLabels??[]){const p=d.find(T=>T.id===o.id)??e.locLabels.find(T=>T.id===o.id),g=[{languageCode:c,description:o.text},...(p?.titles??[]).filter(T=>T.languageCode!==c)],I=d.findIndex(T=>T.id===o.id);I>=0?d[I]={id:o.id,titles:g}:d.push({id:o.id,titles:g})}let a=d.length?fe(`<RibbonDiffXml><LocLabels>${d.map(un).join("")}</LocLabels></RibbonDiffXml>`):xs();for(const o of e.locations){const p=Cs({current:o.current,baseline:o.baseline,commands:e.commands,enableRules:e.enableRules,displayRules:e.displayRules,locLabels:e.locLabels,entityLogicalName:t,location:o.current.location,languageCode:e.languageCode});a=Se(a,fe(p))}const r=[],b=[];for(const o of e.locations)for(const p of o.current.tabs){if(!i.editedTabIds.includes(p.id))continue;if(p.tabDisplayRules.length>0){const I=Is(p,e.entity===null);I&&b.push(I)}const g=new Set(p.tabDisplayRules.map(I=>I.tabCommand));for(const I of o.baseline.tabs.find(T=>T.id===p.id)?.tabDisplayRules??[])g.has(I.tabCommand)||r.push(I.tabCommand)}b.length>0&&(a=Se(a,fe(`<RibbonDiffXml><RuleDefinitions><TabDisplayRules>${b.join("")}</TabDisplayRules></RuleDefinitions></RibbonDiffXml>`)));const m=[...e.commands.filter(o=>e.plan.editedCommandIds.includes(o.id)).map(Rs)],R={enable:e.enableRules.filter(o=>e.plan.editedEnableRuleIds.includes(o.id)).map(Ss),display:e.displayRules.filter(o=>e.plan.editedDisplayRuleIds.includes(o.id)).map(js)};(m.length||R.enable.length||R.display.length)&&(a=Se(a,fe(`<RibbonDiffXml><CommandDefinitions>${m.join("")}</CommandDefinitions><RuleDefinitions><DisplayRules>${R.display.join("")}</DisplayRules><EnableRules>${R.enable.join("")}</EnableRules></RuleDefinitions></RibbonDiffXml>`)));const x=(o,p)=>{for(const g of Array.from(o.keys()))p.includes(g)||o.delete(g)},$=e.locations.flatMap(o=>o.current.tabs.filter(p=>!o.baseline.tabs.some(g=>g.id===p.id)).map(vs));x(a.commandDefinitions,[...e.plan.editedCommandIds,...$]),x(a.enableRules,e.plan.editedEnableRuleIds),x(a.displayRules,e.plan.editedDisplayRuleIds);const u=await rs(e.entity?.logicalName??null),D=ks(u),C=e.plan.deletedButtonIds.filter(o=>!D.has(o));if(C.length>0)throw new Error(`Can't delete ${C.join(", ")}: not defined in this table's unmanaged customizations (it comes from a managed solution or the platform). Undo the delete and hide the button instead.`);const f=Ds(u),v=i.deletedContainerIds.filter(o=>!f.has(o));if(v.length>0)throw new Error(`Can't delete ${v.join(", ")}: not added by this table's unmanaged customizations (it comes from a managed solution or the platform). Undo the delete.`);const V=i.movedButtons.filter(o=>!D.has(o.id)).map(o=>o.id);if(V.length>0)throw new Error(`Can't move ${V.join(", ")}: not defined in this table's unmanaged customizations. Undo the move.`);const F=Ps(u),Z=(e.plan.uncustomisedCommandIds??[]).filter(o=>u.commandDefinitions.has(o)&&!$s(o,F));if(Z.length>0)throw new Error(`Can't uncustomise ${Z.join(", ")}: it is your own command (your customizations' buttons use it and no other solution defines it), so removing it would leave those buttons without a command. Undo the uncustomise.`);const M=new Set;for(const o of e.locations)for(const p of o.current.tabs)for(const g of p.groups)for(const I of ge(g))for(const T of Ns(I))M.add(T);const y=e.plan.uncustomisedCommandIds??[],E=new Set,H=new Set;for(const o of e.commands)if(!(!M.has(o.id)||y.includes(o.id))){o.enableRules.forEach(p=>E.add(p)),o.displayRules.forEach(p=>H.add(p));for(const p of o.rawRuleRefs??[]){const g=/^\s*<(EnableRule|DisplayRule)\b[^>]*?\sId="([^"]+)"/.exec(p.xml);g&&(g[1]==="EnableRule"?E:H).add(g[2])}}let h=As(u,a,{retainedCommandIds:M,editedCommandIds:e.plan.editedCommandIds,editedEnableRuleIds:e.plan.editedEnableRuleIds,editedDisplayRuleIds:e.plan.editedDisplayRuleIds,deletedControlIds:e.plan.deletedButtonIds,unhiddenControlIds:e.plan.unhiddenButtonIds,deletedContainerIds:i.deletedContainerIds,movedControls:i.movedButtons,removedTabCommands:r,uncustomisedCommandIds:y,retainedEnableRuleIds:E,retainedDisplayRuleIds:H});for(const o of e.plan.renamedLabels??[])o.newLabel&&(h=Ls(h,o.containerId,`$LocLabels:${o.id}`));const w=new Set([...Ge(u),...Ge(h)].map(o=>o.id)),K={};for(const o of e.locations)for(const[p,g]of Object.entries(o.baseline.scalingByTab??{}))K[p]={maxSizes:g.maxSizes.filter(I=>!w.has(I.id)).map(I=>I.sequence),scales:g.scales.filter(I=>!w.has(I.id)).map(I=>I.sequence)};const q=Es(h,K);if(q.problems.length>0)throw new Error(`Not published: ${q.problems.join("; ")}.`);return h=q.parts,{scalingChanges:q.changes,xml:zs(h),parts:h,elementCount:ve(h),preservedCount:ve(u),changedCount:ve(a),changedKeys:Ts(u,h),newKeys:Object.keys(h).flatMap(o=>Array.from(h[o].keys()).filter(p=>!u[o].has(p)).map(p=>`${o}:${p}`)),layerDefinitionIds:{commandIds:Array.from(u.commandDefinitions.keys()),enableRuleIds:Array.from(u.enableRules.keys()),displayRuleIds:Array.from(u.displayRules.keys())}}}function us(e,t){const i=[],d={},c={},a={},r={},b=new Set,m=new Set,R=new Set;for(const{current:u,baseline:D}of e.locations)for(const C of[D,u])for(const f of C.tabs)for(const v of f.groups)for(const V of ge(v))for(const F of V.menu?.sections??[])R.add(F.controlsId);for(const{current:u,baseline:D}of e.locations){Object.assign(a,D.templateLayouts);for(const C of D.tabs){i.push(C.id),C.label&&(r[C.id]={Title:C.label});for(const f of C.groups){b.add(f.id),i.push(f.id),f.label&&(r[f.id]={Title:f.label,Label:f.label});for(const v of ge(f))i.push(v.id),v.source&&(r[v.id]=v.source.attributes)}}for(const C of u.tabs)for(const f of C.groups)m.add(f.id);for(const C of[D,u])for(const f of C.tabs)for(const v of f.groups)v.template&&(c[v.id]=v.template)}const x=u=>b.has(u.groupId)&&!m.has(u.groupId);for(const{baseline:u}of e.locations)for(const[D,C]of Object.entries(u.scalingByTab??{}))d[D]={...C,maxSizes:C.maxSizes.filter(f=>!x(f)),scales:C.scales.filter(f=>!x(f))};const $=(u,D)=>{if(!u)return;const C=new Set(D??[]);return u.map(f=>f.id).filter(f=>!C.has(f))};return{changedKeys:t.changedKeys,newKeys:t.newKeys,commands:e.commands,known:{commandIds:$(e.baselineCommands,t.layerDefinitionIds?.commandIds),enableRuleIds:$(e.baselineEnableRules,t.layerDefinitionIds?.enableRuleIds),displayRuleIds:$(e.baselineDisplayRules,t.layerDefinitionIds?.displayRuleIds),elementIds:i},loadedAttributes:r,publisherPrefix:e.publisherPrefix,tabScaling:d,groupTemplates:c,templateLayouts:a,menuControlsIds:R,...e.entity?{places:{entityLogicalName:e.entity.logicalName,tabByCollection:Object.fromEntries(Xs(e.locations.map(u=>u.baseline),e.entity.logicalName))}}:{}}}function mn(e,t){return new Promise((i,d)=>{const c=setTimeout(()=>d(new Error(`it didn't finish within ${Math.round(t/1e3)} s`)),t);e.then(a=>{clearTimeout(c),i(a)},a=>{clearTimeout(c),d(a)})})}async function is(e,t={}){const i=await ds(e),d=us(e,i),c=[],a=qs(i.parts);if(t.lookupWebResources&&a.length>0)try{d.webResources=await t.lookupWebResources(a)}catch(r){c.push({severity:"warning",code:"webresource-lookup",message:`Couldn't check the ${a.length} referenced web resource(s): ${r instanceof Error?r.message:String(r)}`})}return{findings:[...cs(i.parts,d),...c],xml:i.xml}}async function hn(e,t,i={}){const d=i.attempts??3,c=i.contentKeys??[];let a={missing:[],unexpected:[],differing:[]};for(let b=0;b<d;b++){b>0&&await new Promise(m=>setTimeout(m,i.delayMs??5e3));try{a=Vs(t,await rs(e),{contentKeys:c})}catch(m){return{ok:!1,missing:[],unexpected:[],differing:[],message:`Couldn't read the published ribbon layer to verify it (${m instanceof Error?m.message:String(m)}).`}}if(a.missing.length===0&&a.unexpected.length===0&&a.differing.length===0){const m=c.length;return{ok:!0,...a,message:"Verified: the published ribbon layer has every element that was imported"+(m>0?`, and the ${m} element(s) this publish changed have the imported content.`:".")}}}const r=b=>b.slice(0,5).join(", ")+(b.length>5?", …":"");return{ok:!1,...a,message:"The published ribbon layer doesn't match what was imported"+(a.missing.length?`; missing: ${r(a.missing)}`:"")+(a.unexpected.length?`; unexpected: ${r(a.unexpected)}`:"")+(a.differing.length?`; different content: ${r(a.differing)}`:"")+". Reload the table and check before publishing again."}}function as(e,t){return Le(()=>pn(e,t))}async function pn(e,t){const i=Ae.getState(),d=e.entity?e.entity.logicalName:"Application ribbon",c={onProgress:t,...e.busy};t?.(`Reading existing ribbon customizations for ${d}…`),i.logInfo("publish",`Reading unmanaged ribbon layer for ${d}.`);const a=e.languageCode??await Ms(),r=await ds({...e,languageCode:a});i.logInfo("publish",`RibbonDiffXml for ${d}: ${r.preservedCount} existing element(s) preserved, ${r.changedCount} element(s) from this session, ${r.elementCount} total.`);for(const y of r.scalingChanges)i.logWarn("publish",Os(y));const b=cs(r.parts,us({...e,publisherPrefix:e.solution.publisherPrefix},r));for(const y of b)y.severity==="warning"&&i.logWarn("publish",y.message);const m=b.filter(y=>y.severity==="error");if(m.length>0){for(const y of m)i.logError("publish",y.message);throw new Error(`The pre-publish check found ${m.length} error(s), so nothing was imported: `+m.map(y=>y.message).join("; "))}const R=e.entity===null;if(R&&!e.ribbonCustomizationIds?.length)throw new Error("The selected solution does not contain Application Ribbons. Add it in make.powerapps.com (Solutions → your solution → Add existing → Application Ribbons) and reload the solution.");const x=e.entity?.schemaName||e.entity?.logicalName||"",$=R?Je({applicationRibbonDiffXml:r.xml}):Je({entities:[{schemaName:x,localizedName:e.entity?.displayName||x,ribbonDiffXml:r.xml}]}),u=R?[{type:50,schemaName:":RibbonDiffXml",behavior:0}]:[{type:1,schemaName:e.entity.logicalName,behavior:2}],D=gn({...e.solution,languageCode:a,rootComponents:u});t?.("Packaging solution ZIP…");const C=Us({"customizations.xml":ke($),"solution.xml":ke(D),"[Content_Types].xml":ke('<?xml version="1.0" encoding="utf-8"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="xml" ContentType="application/xml"/></Types>')});let f="";for(let y=0;y<C.length;y++)f+=String.fromCharCode(C[y]);const v=btoa(f),V=async y=>{t?.(`Importing ${d} ribbon${y}…`);const E=crypto.randomUUID();i.logInfo("publish",`Importing solution${y} (import job ${E})…`),await Ye("Import",()=>cn(v,E),c);const H=150,h=2e3;let w=await Y.getImportJobStatus(E),K=0;for(;!os(w)&&K<H;)await new Promise(p=>setTimeout(p,h)),w=await Y.getImportJobStatus(E),K++,K%10===0&&t?.(`Still importing… (${K*2}s elapsed)`);if(!os(w))throw new Error(`Solution import did not complete within ${H*h/1e3} seconds. Check Solutions › History for import job ${E}.`);t?.("Verifying the import…");const q=await Y.retrieve("importjob",E,["data"]),o=rn(q.data,R?{kind:"application"}:{kind:"entity",names:[x,e.entity.logicalName]});if(!o.ok)throw i.logError("publish",o.message),new Error(o.message);return i.logInfo("publish",o.message),E},F=async()=>{t?.("Publishing customizations…"),await Ye("Publish",async()=>{R?await Y.execute({operationName:"PublishXml",operationType:"action",parameters:{ParameterXml:"<importexportxml><ribbons><ribbon></ribbon></ribbons></importexportxml>"}}):await dn([e.entity.logicalName])},c)};t?.("Checking that no other solution operation is running…"),await Bs(c);const Z=await V("");let M;if(e.publishCustomizations!==!1){await F();{i.logInfo("publish","Refreshing Unified Interface command-bar metadata (second import of the same package)…");try{await V(" (refreshing Unified Interface metadata)"),await F()}catch(y){throw new Error(`Your changes were imported and published, but refreshing Unified Interface's command-bar metadata failed (${y instanceof Error?y.message:String(y)}). New or changed buttons may not appear in the app until you publish again.`)}}t?.("Verifying the published ribbon…"),M=await hn(e.entity?.logicalName??null,r.parts,{delayMs:e.verifyDelayMs,contentKeys:r.changedKeys}),M.ok?i.logInfo("publish",M.message):i.logWarn("publish",M.message)}else i.logWarn("publish","Imported without publishing. New or changed buttons appear in Unified Interface only after you publish from Command Bar Studio (which re-imports once to refresh the command-bar metadata).");return t?.(e.publishCustomizations!==!1?`${d} ribbon published.`:`${d} ribbon imported (not published).`),{elementCount:r.elementCount,preservedCount:r.preservedCount,importJobId:Z,verification:M,parts:r.parts,changedKeys:r.changedKeys}}function bn(e,t){return Le(()=>fn(e,t))}async function fn(e,t){const i=Ae.getState(),d=2e3,c=600*1e3;e?.("Starting asynchronous publish (PublishAllXmlAsync)..."),i.logInfo("publish","Calling PublishAllXmlAsync action.");const r=(await Y.execute({operationName:"PublishAllXmlAsync",operationType:"action"}))?.AsyncOperationId;if(!r)throw new Error("PublishAllXmlAsync did not return AsyncOperationId.");i.logInfo("publish",`PublishAllXmlAsync job id: ${r}`),e?.("Async publish job started. Waiting for completion...");const b=Date.now();let m=0,R;for(;Date.now()-b<c;){m+=1;const x=await Y.retrieve("asyncoperation",r,["asyncoperationid","statecode","statuscode","name","message","friendlymessage","completedon"]);if(R=x.statuscode,x.statecode===3||!!x.completedon){if(typeof x.statuscode=="number"&&x.statuscode!==30){const u=x.friendlymessage||x.message||`statuscode=${x.statuscode}`;throw new Error(`Asynchronous publish failed: ${u}`)}return e?.("Asynchronous publish completed successfully."),i.logInfo("publish",`PublishAllXmlAsync completed in ${m} poll(s).`),{asyncOperationId:r,statusCode:x.statuscode}}e?.(`Waiting for async publish job... (poll ${m})`),await new Promise(u=>setTimeout(u,d))}throw new Error(`Asynchronous publish timed out after ${Math.round(c/1e3)} seconds (last status: ${R??"unknown"}).`)}function gn(e){const t=e.publisherUniqueName?.trim()||"DefaultPublisher",i=e.publisherName?.trim()||t,d=e.publisherPrefix?.trim()||"new",c=e.languageCode||1033,a=e.friendlyName?.trim()||e.uniqueName,r=e.rootComponents.length===0?"<RootComponents/>":`<RootComponents>
2
+ ${e.rootComponents.map(b=>{const m=[`type="${b.type}"`];return b.schemaName&&m.push(`schemaName="${B(b.schemaName)}"`),b.id&&m.push(`id="{${B(b.id)}}"`),m.push(`behavior="${b.behavior}"`),`<RootComponent ${m.join(" ")} />`}).join(`
3
+ `)}
4
+ </RootComponents>`;return`<?xml version="1.0" encoding="utf-8"?>
5
+ <ImportExportXml version="9.1.0.0" SolutionPackageVersion="9.1" languagecode="${c}" generatedBy="CommandBarStudio">
6
+ <SolutionManifest>
7
+ <UniqueName>${B(e.uniqueName)}</UniqueName>
8
+ <LocalizedNames>
9
+ <LocalizedName description="${B(a)}" languagecode="${c}"/>
10
+ </LocalizedNames>
11
+ <Descriptions/>
12
+ <Version>${B(e.version)}</Version>
13
+ <Managed>0</Managed>
14
+ <Publisher>
15
+ <UniqueName>${B(t)}</UniqueName>
16
+ <LocalizedNames>
17
+ <LocalizedName description="${B(i)}" languagecode="${c}"/>
18
+ </LocalizedNames>
19
+ <Descriptions/>
20
+ <EMailAddress/>
21
+ <SupportingWebsiteUrl/>
22
+ <CustomizationPrefix>${B(d)}</CustomizationPrefix>
23
+ <CustomizationOptionValuePrefix>${e.publisherOptionValuePrefix??1e4}</CustomizationOptionValuePrefix>
24
+ <Addresses/>
25
+ </Publisher>
26
+ ${r}
27
+ <MissingDependencies/>
28
+ </SolutionManifest>
29
+ </ImportExportXml>`}const yn=ws({content:{display:"flex",flexDirection:"column",gap:_.spacingVerticalM},progressList:{display:"flex",flexDirection:"column",gap:_.spacingVerticalXS},progressRow:{display:"flex",alignItems:"center",gap:_.spacingHorizontalS}}),ls=({findings:e,showScope:t})=>n.jsx("ul",{style:{margin:`${_.spacingVerticalXS} 0 0`,paddingLeft:20},children:e.map((i,d)=>n.jsxs("li",{children:[t&&n.jsxs("strong",{children:[i.scope,": "]}),i.message]},d))}),oe=["HomepageGrid","SubGrid","Form"],wn=3e4,Pn=()=>{const e=yn(),t=De(s=>s.bulkPublishOpen),i=De(s=>s.closeBulkPublish),d=De(s=>s.openXmlDrawer),c=S(s=>s.ribbons),a=S(s=>s.baseline),r=S(s=>s.commands),b=S(s=>s.displayRules),m=S(s=>s.enableRules),R=S(s=>s.baselineCommands),x=S(s=>s.baselineEnableRules),$=S(s=>s.baselineDisplayRules),u=S(s=>s.locLabels),D=S(s=>s.baselineLocLabels),C=S(s=>s.layers),f=S(s=>s.pendingUnhides),v=S(s=>s.orphans),V=S(s=>s.pendingOrphanDeletes),F=S(s=>s.customisedCommandIds),Z=S(s=>s.uncustomisedCommandIds),M=S(s=>s.baseLanguageCode),y=S(s=>s.setLayerSnapshot),E=S(s=>s.markPublished),H=S(s=>s.mutationsSincePublish),h=re(s=>s.activeSolution),w=re(s=>s.activeEntity),K=re(s=>s.connectionUrl),q=re(s=>s.publisherPrefix),o=re(s=>s.solutionRibbonComponentIds),p=Array.isArray(o)&&o.length>0,[g,I]=L.useState(!1),[T,G]=L.useState({}),[N,Ee]=L.useState(!1),[de,ms]=L.useState(!1),[ye,hs]=L.useState("targeted"),[Te,ne]=L.useState(""),[ze,ps]=L.useState(""),[ue,Xe]=L.useState(h?.version??"1.0.0.0"),[me,we]=L.useState([]),[bs,Me]=L.useState([]),[fs,xe]=L.useState([]),Oe=se.useMemo(()=>{const l=(ue||h?.version||"1.0.0.0").split(".").map(z=>Number.parseInt(z,10)||0);for(;l.length<4;)l.push(0);return l[3]+=1,l.slice(0,4).join(".")},[h?.version,ue]);se.useEffect(()=>{Xe(h?.version??"1.0.0.0")},[h?.version]);const he=se.useCallback((s,l,z)=>Fs({locations:s.map(P=>({current:c[P],baseline:a[P]})),excludeCommandIds:z,locLabels:u,baselineLocLabels:D,layer:C[l]??void 0,unhiddenLayerHideIds:f[l],deletedOrphans:v[l].filter(P=>V[l].includes(P.id)),customisedCommandIds:F,uncustomisedCommandIds:Z[l],commands:r,baselineCommands:R,enableRules:m,baselineEnableRules:x,displayRules:b,baselineDisplayRules:$}),[c,a,r,R,m,x,b,$,u,D,C,f,v,V,F,Z]),W=se.useMemo(()=>w?he(oe,"entity"):null,[w,he]),J=se.useMemo(()=>{const s=new Set;if(w)for(const l of oe)for(const z of c[l].tabs)for(const P of z.groups)for(const X of ge(P))X.commandId&&s.add(X.commandId);return he(["Application"],"application",s)},[he,w,c]),ie=J.hasChanges&&p,ae=[...W?.unsupported??[],...J.unsupported],Ue=[...W?.warnings??[],...J.warnings],Q=[...w&&W?.hasChanges?[w.logicalName]:[],...ie?["Application ribbon"]:[]],[Ce,pe]=L.useState("idle"),[Ie,Re]=L.useState([]),[gs,je]=L.useState(""),ee=t&&!!h&&ae.length===0&&Q.length>0,Be=h?.id,Ve=h?.publisherPrefix||q,Fe=se.useCallback(async()=>{const s={commands:r,enableRules:m,displayRules:b,locLabels:u,baselineCommands:R,baselineEnableRules:x,baselineDisplayRules:$,publisherPrefix:Ve,languageCode:M},l={lookupWebResources:P=>Ws(P,Be)},z=[];if(w&&W?.hasChanges){const{findings:P}=await is({...s,entity:{logicalName:w.logicalName,schemaName:w.schemaName},locations:oe.map(X=>({current:c[X],baseline:a[X]})),plan:W},l);z.push(...P.map(X=>({...X,scope:w.logicalName})))}if(ie){const{findings:P}=await is({...s,entity:null,locations:[{current:c.Application,baseline:a.Application}],plan:J},l);z.push(...P.map(X=>({...X,scope:"Application ribbon"})))}return z},[w,W,J,ie,c,a,r,m,b,u,R,x,$,Ve,Be,M]);se.useEffect(()=>{if(!ee||g||N)return;let s=!1;return pe("running"),je(""),mn(Fe(),wn).then(l=>{s||(Re(l),pe("done"))}).catch(l=>{s||(Re([]),je(l instanceof Error?l.message:String(l)),pe("failed"))}),()=>{s=!0}},[ee,g,N,Fe]);const te=Ie.filter(s=>s.severity==="error"),be=Ie.filter(s=>s.severity==="warning"),Ke=new Set(Ie.map(s=>s.scope)).size>1,qe=ee&&(Ce==="running"||te.length>0),ys=()=>Le(async()=>{if(!h||ae.length>0||Q.length===0||qe)return;I(!0),ne(""),we([]),xe([]),Me(Q),G(Object.fromEntries(Q.map(j=>[j,"pending"])));let s=!1;const l=[],z={},P=[],X=[],_e=Ae.getState(),le=j=>j instanceof Error?j.message:String(j),He={commands:r,enableRules:m,displayRules:b,locLabels:u,baselineCommands:R,baselineEnableRules:x,baselineDisplayRules:$,publishCustomizations:!0,solution:{uniqueName:h.uniqueName,friendlyName:h.friendlyName,version:de?Oe:ue,publisherUniqueName:h.publisherUniqueName,publisherName:h.publisherName,publisherPrefix:h.publisherPrefix||q,publisherOptionValuePrefix:h.publisherOptionValuePrefix}};if(w&&W?.hasChanges){const j=w.logicalName;G(k=>({...k,[j]:"publishing"}));try{const k=await as({...He,entity:{logicalName:w.logicalName,schemaName:w.schemaName,displayName:w.displayName},locations:oe.map(A=>({current:c[A],baseline:a[A]})),plan:W},A=>ne(A));l.push(...oe),z.entity=k.parts,Ks(K,w.logicalName,k.changedKeys),k.verification&&X.push({scope:j,result:k.verification}),G(A=>({...A,[j]:"success"}))}catch(k){s=!0,P.push({scope:j,message:le(k)}),_e.logError("publish",`Ribbon publish failed (${j}): ${le(k)}`),G(A=>({...A,[j]:"error"}))}}else w&&l.push(...oe);if(ie){const j="Application ribbon";G(k=>({...k,[j]:"publishing"}));try{const k=await as({...He,entity:null,locations:[{current:c.Application,baseline:a.Application}],ribbonCustomizationIds:o??[],plan:J},A=>ne(A));l.push("Application"),z.application=k.parts,k.verification&&X.push({scope:j,result:k.verification}),G(A=>({...A,[j]:"success"}))}catch(k){s=!0,P.push({scope:j,message:le(k)}),_e.logError("publish",`Application ribbon publish failed: ${le(k)}`),G(A=>({...A,[j]:"error"}))}}else J.hasChanges||l.push("Application");if(!s&&ye==="allAsync")try{await bn(j=>ne(j))}catch(j){s=!0,P.push({scope:"Publish all customizations",message:le(j)})}E(l,z),w&&l.includes("HomepageGrid")&&W?.hasChanges&&y("entity",await Ze(w.logicalName)),l.includes("Application")&&ie&&y("application",await Ze(null)),s||ne("Done."),xe(X),we(P),Ee(!s),I(!1)}),We=()=>{I(!1),G({}),Me([]),Ee(!1),ne(""),we([]),xe([]),pe("idle"),Re([]),je(""),i()};return n.jsx(_s,{open:t,onOpenChange:()=>!g&&We(),children:n.jsxs(Hs,{style:{maxWidth:"640px",maxHeight:"92vh",display:"flex",flexDirection:"column"},children:[n.jsx(Gs,{children:"Publish to Dataverse"}),n.jsxs(Js,{style:{flex:1,minHeight:0,overflow:"hidden"},children:[n.jsx(Ys,{style:{overflowY:"auto",maxHeight:"100%"},children:n.jsxs("div",{className:e.content,children:[!h&&n.jsx(O,{intent:"warning",children:n.jsx(U,{children:"No solution selected. Please select a solution first."})}),ae.length>0&&!N&&n.jsx(O,{intent:"error",layout:"multiline",children:n.jsxs(U,{children:[n.jsx("strong",{children:"These changes can't be published yet. Undo them to publish:"}),n.jsx("ul",{style:{margin:`${_.spacingVerticalXS} 0 0`,paddingLeft:20},children:ae.map(s=>n.jsx("li",{children:s},s))})]})}),Ue.length>0&&!N&&n.jsx(O,{intent:"info",layout:"multiline",children:n.jsxs(U,{children:[n.jsx("strong",{children:"Good to know:"}),n.jsx("ul",{style:{margin:`${_.spacingVerticalXS} 0 0`,paddingLeft:20},children:Ue.map(s=>n.jsx("li",{children:s},s))})]})}),ee&&!N&&!g&&Ce==="running"&&n.jsxs("div",{className:e.progressRow,children:[n.jsx(Zs,{size:"tiny"}),n.jsx(Pe,{children:"Checking the ribbon customizations before publishing…"})]}),ee&&!N&&Ce==="failed"&&n.jsx(O,{intent:"warning",layout:"multiline",children:n.jsxs(U,{children:["The pre-publish check couldn't complete (",gs,"). Publishing runs the check again before anything is imported."]})}),ee&&!N&&te.length>0&&n.jsx(O,{intent:"error",layout:"multiline",children:n.jsxs(U,{children:[n.jsxs("strong",{children:["Publishing is blocked: the pre-publish check found ",te.length," error",te.length!==1?"s":"",". Fix"," ",te.length!==1?"them":"it",", then reopen this dialog:"]}),n.jsx(ls,{findings:te,showScope:Ke})]})}),ee&&!N&&be.length>0&&n.jsx(O,{intent:"warning",layout:"multiline",children:n.jsxs(U,{children:[n.jsxs("strong",{children:[be.length," warning",be.length!==1?"s":""," — you can still publish:"]}),n.jsx(ls,{findings:be,showScope:Ke})]})}),J.hasChanges&&!p&&!N&&n.jsx(O,{intent:"warning",layout:"multiline",children:n.jsxs(U,{children:["You changed the Application ribbon, but this solution doesn't include the Application Ribbons component, so those changes stay pending. In make.powerapps.com open the solution, choose ",n.jsx("strong",{children:"Add existing → Application Ribbons"}),", then reload here."]})}),n.jsx(O,{intent:"info",layout:"multiline",children:n.jsxs(U,{children:["Publishing writes this table's complete ribbon customization: what is already published, plus your changes. Ribbon changes on this table that were imported elsewhere but ",n.jsx("strong",{children:"not published"})," are replaced. Publishing takes about 1–4 minutes (the ribbon is imported twice so Unified Interface picks up the change). Users may need to refresh the page, or navigate away and back, to see the update. You have ",n.jsx("strong",{children:H})," change(s) since the last publish."]})}),me.length>0&&n.jsx(O,{intent:"error",layout:"multiline",children:n.jsxs(U,{children:[n.jsxs("strong",{children:["Publish failed (",me.length," error",me.length!==1?"s":"",")"]}),n.jsx("ul",{style:{margin:`${_.spacingVerticalXS} 0 0`,paddingLeft:20},children:me.map((s,l)=>n.jsxs("li",{style:{fontFamily:_.fontFamilyMonospace},children:[n.jsxs("strong",{children:[s.scope,":"]})," ",s.message]},l))}),n.jsxs("div",{style:{marginTop:_.spacingVerticalS},children:["Full details are in the ",n.jsx("strong",{children:"Console"})," tab of the bottom panel."]})]})}),!g&&!N&&n.jsxs(n.Fragment,{children:[n.jsxs(Pe,{children:[n.jsx("strong",{children:"Will publish:"})," ",Q.length>0?Q.join(", "):"nothing (there are no changes to publish)"]}),n.jsx($e,{label:"Afterwards",children:n.jsxs(Qs,{value:ye==="targeted"?"Publish only these ribbons":"Also publish all customizations (PublishAllXmlAsync)",selectedOptions:[ye],onOptionSelect:(s,l)=>{(l.optionValue==="targeted"||l.optionValue==="allAsync")&&hs(l.optionValue)},children:[n.jsx(Qe,{value:"targeted",children:"Publish only these ribbons"}),n.jsx(Qe,{value:"allAsync",children:"Also publish all customizations (PublishAllXmlAsync)"})]})}),n.jsx($e,{label:"Solution version",children:n.jsx(en,{size:"small",value:de?Oe:ue,onChange:(s,l)=>Xe(l.value),disabled:de})}),n.jsx(sn,{label:"Increment solution version",checked:de,onChange:(s,l)=>ms(l.checked===!0)}),n.jsx($e,{label:"Publish comment",children:n.jsx(nn,{resize:"vertical",value:ze,onChange:(s,l)=>ps(l.value)})}),n.jsx(Ne,{appearance:"subtle",onClick:()=>{d(),i()},children:"View RibbonDiffXml"})]}),N&&n.jsx(O,{intent:"info",layout:"multiline",children:n.jsx(U,{children:"Unified Interface caches command bars by metadata version, and publishing a ribbon doesn't always change that version. If the app still shows the old command bar, hard-refresh the page (Ctrl+F5) or sign out and back in; it can take several minutes to appear for users who already had the table open."})}),fs.map(s=>n.jsx(O,{intent:s.result.ok?"success":"warning",layout:"multiline",children:n.jsxs(U,{children:[n.jsxs("strong",{children:[s.scope,":"]})," ",s.result.message]})},s.scope)),(g||N)&&n.jsxs("div",{className:e.progressList,children:[bs.map(s=>{const l=T[s]??"pending";return n.jsxs("div",{className:e.progressRow,children:[n.jsx(tn,{appearance:"filled",color:l==="success"?"success":l==="error"?"danger":l==="publishing"?"informative":"subtle",size:"small",children:l}),n.jsx(Pe,{children:s}),l==="publishing"&&n.jsx(on,{thickness:"large",style:{flex:1}})]},s)}),Te&&n.jsx(O,{intent:"info",children:n.jsx(U,{children:Te})})]})]})}),n.jsxs(an,{children:[n.jsx(Ne,{appearance:"secondary",onClick:We,disabled:g,children:N?"Close":"Cancel"}),!N&&n.jsx(Ne,{appearance:"primary",onClick:()=>{ys()},disabled:g||!h||Q.length===0||ae.length>0||qe,children:g?"Publishing...":"Publish"})]})]})]})})};export{Pn as BulkPublishModal,Pn as default};
@@ -0,0 +1 @@
1
+ import{z as e,h as R,y as Ae,cq as de}from"./fluent-icons-DxKNRZ1A.js";import{a as m}from"./monaco-Bx8A1Vm1.js";import{a as N,u as x,i as Pe,d as Be,e as We,C as $e,w as Le,f as Te}from"./index-Bu7BlRFk.js";import{C as ue}from"./CrmParameterEditor-BdmP65mF.js";import{M as Oe}from"./MonacoEditor-Bbg9u2FW.js";import{a as Ve,b as He,s as Ue}from"./webResourceService-CvyHBu7T.js";import{ah as _e,ai as Xe,aj as Je,T as d,t as n,B as u,ak as qe,ac as Ye,ad as S,a7 as _,F as j,S as X,c as E,M as y,e as C,I as B}from"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";import"./crmParameters-rgfZhhzN.js";const Ge=Ae({drawer:{width:"640px",maxWidth:"90vw"},body:{display:"flex",flexDirection:"column",gap:n.spacingVerticalS,padding:n.spacingVerticalM,overflowY:"auto"},actionCard:{border:`1px solid ${n.colorNeutralStroke2}`,borderRadius:n.borderRadiusMedium,padding:n.spacingVerticalM,display:"flex",flexDirection:"column",gap:n.spacingVerticalS},actionHeader:{display:"flex",alignItems:"center",justifyContent:"space-between"},row:{display:"flex",gap:n.spacingHorizontalS,alignItems:"flex-end"},ruleRow:{display:"inline-flex",alignItems:"center",gap:n.spacingHorizontalXS},ruleRemoveBtn:{minWidth:"20px",width:"20px",height:"20px"},ruleChip:{cursor:"pointer"},rulePills:{display:"flex",flexWrap:"wrap",gap:n.spacingHorizontalXS},versionsList:{display:"flex",flexDirection:"column",gap:n.spacingVerticalXS},versionRow:{border:`1px solid ${n.colorNeutralStroke2}`,borderRadius:n.borderRadiusMedium,padding:n.spacingVerticalXS,display:"flex",justifyContent:"space-between",gap:n.spacingHorizontalS},versionMeta:{fontSize:n.fontSizeBase100,color:n.colorNeutralForeground3},securityNote:{fontSize:n.fontSizeBase100},readOnly:{border:"none",margin:0,padding:0,minWidth:0,display:"flex",flexDirection:"column",gap:n.spacingVerticalS},codePanel:{border:`1px solid ${n.colorNeutralStroke2}`,borderRadius:n.borderRadiusMedium,padding:n.spacingVerticalS,display:"flex",flexDirection:"column",gap:n.spacingVerticalS}}),is=()=>{const r=Ge(),W=N(s=>s.commandEditorOpen),z=N(s=>s.commandEditorId),M=N(s=>s.closeCommandEditor),me=N(s=>s.openCommandEditor),J=N(s=>s.openRuleEditor),pe=N(s=>s.openWebResourceBrowser),$=x(s=>s.commands),he=x(s=>s.upsertCommand),xe=x(s=>s.renameCommandId),q=x(s=>s.ribbons),Y=x(s=>s.displayRules),G=x(s=>s.enableRules),be=x(s=>s.past),je=x(s=>s.upsertEnableRule),fe=x(s=>s.upsertDisplayRule),[f,ge]=m.useState("actions"),[p,K]=m.useState(""),[ve,Q]=m.useState(""),[ye,Z]=m.useState(""),[ee,L]=m.useState(null),[I,se]=m.useState(!1),[ae,k]=m.useState(!1),[T,g]=m.useState(null),[ne,O]=m.useState(null),[re,F]=m.useState(""),[Ce,D]=m.useState(!1),[w,le]=m.useState(null),l=$.find(s=>s.id===z),we=Pe(Be(l?.id)),Re=s=>{const a=s.trim();return a.startsWith("$webresource:")?a.slice(13).trim():a},Ne=s=>{if(!s)return"";const a=Uint8Array.from(atob(s),o=>o.charCodeAt(0));return new TextDecoder().decode(a)},Se=s=>{const a=new TextEncoder().encode(s);let o="";for(let i=0;i<a.length;i+=1)o+=String.fromCharCode(a[i]);return btoa(o)},ze=s=>{const a=s.split(".").pop()?.toLowerCase()??"";return{html:1,css:2,js:3,xml:4,png:5,jpg:6,gif:7,xsl:9,ico:10,svg:11,resx:12}[a]??3};m.useEffect(()=>{l&&K(l.id)},[l]),m.useEffect(()=>{W&&z&&!l&&M()},[W,z,l,M]);const A=m.useMemo(()=>l?p.trim()?/\s/.test(p)?"Command ID cannot contain whitespace.":p!==l.id&&$.some(s=>s.id.toLowerCase()===p.toLowerCase())?"A command with this ID already exists.":"":"Command ID is required.":"",[p,l,$]),V=m.useMemo(()=>Object.entries(q).flatMap(([s,a])=>a.tabs.flatMap(o=>o.groups.flatMap(i=>We(i).filter(c=>c.commandId===z).map(c=>({location:s,tab:o,group:i,button:c}))))),[q,z]),ie=V.length;if(!l)return null;const oe=async(s,a)=>{const o=l.actions[s];if(!o||o.kind!=="javascript")return;const i=Re(o.library);if(!i){g("JavaScript library must be a valid $webresource path."),L(s),se(a),F(""),le(null);return}L(s),se(a),k(!0),g(null),O(null),D(!1),le(i);try{const c=await Ve(i);if(!c){F(""),g(`Web resource not found: ${i}`);return}const t=await He(c.id);F(Ne(t))}catch(c){g(c instanceof Error?c.message:"Failed to load web resource content."),F("")}finally{k(!1)}},Fe=async()=>{if(!(!I||ee===null||!w)){k(!0),g(null),O(null);try{const s=await Ue(w,Se(re),ze(w),{displayName:w.split("/").pop()});O(s.solutionWarning??null),D(!1)}catch(s){g(s instanceof Error?s.message:"Failed to save web resource content.")}finally{k(!1)}}},v=s=>{he({...l,...s})},b=(s,a)=>{const o=[...l.actions];o[s]=a,v({actions:o})},P=s=>{v({actions:l.actions.filter((a,o)=>o!==s)})},H=s=>{const a=s==="javascript"?{kind:"javascript",library:"",functionName:"",params:[]}:{kind:"url",address:"https://",params:[]};v({actions:[...l.actions,a]})},Ee=(s,a)=>{const o=ee===a;if(s.kind==="javascript")return e.jsxs("div",{className:r.actionCard,children:[e.jsxs("div",{className:r.actionHeader,children:[e.jsx(E,{appearance:"filled",color:"success",size:"small",children:"JavaScript"}),e.jsx(u,{appearance:"subtle",size:"small",icon:e.jsx(R,{}),onClick:()=>P(a),"aria-label":"Remove action"})]}),e.jsx(j,{label:"Library (Web Resource)",children:e.jsxs("div",{style:{display:"flex",gap:"4px",alignItems:"center"},children:[e.jsx(B,{style:{flex:1},value:s.library,onChange:(i,c)=>b(a,{...s,library:c.value.replace(/^(\s*\$webresource:\s*)+/i,"$webresource:")}),placeholder:"$webresource:publisher_/scripts/myfile.js"}),e.jsx(u,{appearance:"subtle",size:"small",onClick:()=>{Le.set(i=>{b(a,{...s,library:`$webresource:${i.name}`})}),pe()},children:"Browse…"})]})}),e.jsx(j,{label:"Function name",children:e.jsx(B,{value:s.functionName,onChange:(i,c)=>b(a,{...s,functionName:c.value}),placeholder:"MyNamespace.myFunction"})}),e.jsx(y,{intent:"info",children:e.jsx(C,{children:"Read-only function preview and Monaco editing are available in the web resource browser integration path."})}),e.jsx(_,{children:"Parameters (positional)"}),e.jsx(ue,{params:s.params,onChange:i=>b(a,{...s,params:i}),urlMode:!1}),e.jsxs("div",{className:r.row,children:[e.jsx(u,{appearance:"subtle",size:"small",onClick:()=>{oe(a,!1)},children:"Function preview"}),e.jsx(u,{appearance:"subtle",size:"small",onClick:()=>{oe(a,!0)},children:"Open in Monaco"})]}),o&&e.jsxs("div",{className:r.codePanel,children:[e.jsxs("div",{className:r.row,children:[e.jsx(d,{weight:"semibold",children:I?"Monaco Editor":"Function Preview"}),w&&e.jsx(d,{size:200,style:{fontFamily:n.fontFamilyMonospace},children:w})]}),T&&e.jsx(y,{intent:"error",children:e.jsx(C,{children:T})}),ne&&e.jsx(y,{intent:"warning",children:e.jsx(C,{children:ne})}),ae?e.jsx(d,{style:{color:n.colorNeutralForeground3},children:"Loading source…"}):e.jsx("div",{style:{height:240},children:e.jsx(Oe,{language:"javascript",value:re,readOnly:!I,onChange:i=>{F(i),D(!0)},options:{wordWrap:"on"}})}),e.jsxs("div",{className:r.row,children:[e.jsx(u,{appearance:"subtle",size:"small",onClick:()=>{L(null),g(null),D(!1)},children:"Close"}),I&&e.jsx(u,{appearance:"primary",size:"small",onClick:()=>{Fe()},disabled:!Ce||ae||!!T,children:"Save Web Resource"})]})]})]},a);if(s.kind==="url"){const i=s.address.trim().startsWith("https://");return e.jsxs("div",{className:r.actionCard,children:[e.jsxs("div",{className:r.actionHeader,children:[e.jsx(E,{appearance:"filled",color:"informative",size:"small",children:"URL"}),e.jsx(u,{appearance:"subtle",size:"small",icon:e.jsx(R,{}),onClick:()=>P(a),"aria-label":"Remove action"})]}),e.jsx(y,{intent:"warning",children:e.jsx(C,{children:e.jsx(d,{className:r.securityNote,children:"⚠ Ampersands in URLs are automatically escaped as & in the generated XML."})})}),e.jsx(j,{label:"Address",validationState:i?"none":"error",validationMessage:i?void 0:"URL must start with https://",children:e.jsx(B,{value:s.address,onChange:(c,t)=>b(a,{...s,address:t.value}),placeholder:"https://..."})}),e.jsx(j,{label:"Open in (WinMode)",children:e.jsxs(X,{value:String(s.winMode??0),onChange:(c,t)=>b(a,{...s,winMode:parseInt(t.value)}),children:[e.jsx("option",{value:"0",children:"Navigate (0)"}),e.jsx("option",{value:"1",children:"Dialog (1)"}),e.jsx("option",{value:"2",children:"Popup (2)"})]})}),e.jsx(j,{children:e.jsxs(u,{appearance:s.passParams?"primary":"subtle",size:"small",onClick:()=>b(a,{...s,passParams:s.passParams?void 0:!0}),children:[s.passParams?"✓ PassParams ON":"PassParams OFF"," — appends typename, type, id, orgname…"]})}),e.jsx(_,{children:"Parameters (named)"}),e.jsx(ue,{params:s.params,onChange:c=>b(a,{...s,params:c}),urlMode:!0})]},a)}return s.kind==="powerFx"||s.kind==="customApi"?e.jsxs("div",{className:r.actionCard,children:[e.jsxs("div",{className:r.actionHeader,children:[e.jsxs(E,{appearance:"filled",color:"danger",size:"small",children:[s.kind==="powerFx"?"Power Fx":"Custom API"," — not supported"]}),e.jsx(u,{appearance:"subtle",size:"small",icon:e.jsx(R,{}),onClick:()=>P(a),"aria-label":"Remove action"})]}),e.jsx(y,{intent:"error",children:e.jsxs(C,{children:["Classic ribbon commands can't run"," ",s.kind==="powerFx"?"Power Fx":"Custom API"," actions, so this command can't be published while it has one. Remove it and use a JavaScript function instead (for example, call the API with ",e.jsx("code",{children:"Xrm.WebApi.online.execute"}),"), or build the command with modern commanding in the app designer."]})})]},a):s.kind==="outlookCommand"||s.kind==="raw"?e.jsxs("div",{className:r.actionCard,children:[e.jsxs("div",{className:r.actionHeader,children:[e.jsx(E,{appearance:"outline",size:"small",children:s.kind==="outlookCommand"?"Outlook command":s.tagName}),e.jsx(u,{appearance:"subtle",size:"small",icon:e.jsx(R,{}),onClick:()=>P(a),"aria-label":"Remove action"})]}),e.jsx(d,{size:200,style:{color:n.colorNeutralForeground3},children:s.kind==="outlookCommand"?`ActionType="${s.actionType}"${s.data?` Data="${s.data}"`:""}`:s.xml})]},a):null},Me=()=>e.jsxs(e.Fragment,{children:[l.actions.map((s,a)=>Ee(s,a)),l.actions.length===0&&e.jsx(d,{italic:!0,style:{color:n.colorNeutralForeground3},children:"No actions defined — button will do nothing when clicked."}),e.jsxs("div",{className:r.row,children:[e.jsx(j,{label:"Action type",style:{minWidth:"220px"},children:e.jsxs(X,{onChange:(s,a)=>{const o=a.value;o&&H(o)},value:"",children:[e.jsx("option",{value:"",children:"Add action..."}),e.jsx("option",{value:"javascript",children:"JavaScript function"}),e.jsx("option",{value:"url",children:"URL action"})]})}),e.jsx(u,{icon:e.jsx(de,{}),appearance:"secondary",size:"small",onClick:()=>H("javascript"),children:"Add JavaScript function"}),e.jsx(u,{icon:e.jsx(de,{}),appearance:"secondary",size:"small",onClick:()=>H("url"),children:"Add URL action"})]})]}),Ie=()=>e.jsxs(e.Fragment,{children:[e.jsx(j,{label:"Command ID",children:e.jsx(B,{value:p,onChange:(s,a)=>K(a.value),style:{fontFamily:n.fontFamilyMonospace}})}),A&&e.jsx(d,{style:{color:n.colorPaletteRedForeground1,fontSize:n.fontSizeBase100},children:A}),e.jsx(u,{appearance:"secondary",size:"small",disabled:!p.trim()||!!A||p===l.id,onClick:()=>{if(!p.trim()||A)return;const s=p.trim();xe(l.id,s)&&me(s)},children:"Apply ID change"}),e.jsx(d,{style:{color:n.colorNeutralForeground3,fontSize:n.fontSizeBase200},children:"Naming convention: Publisher.EntityName.ButtonName.Command"}),e.jsx(y,{intent:"warning",children:e.jsx(C,{children:e.jsxs(d,{className:r.securityNote,children:["⚠ ",e.jsx("strong",{children:"Security:"})," All command definitions are visible in browser source regardless of button visibility. Do not embed sensitive logic, credentials, or privileged information in command parameters or function names."]})})})]}),te=s=>{const a=s==="enable"?l.enableRules:l.displayRules,o=(s==="enable"?G:Y).map(t=>t.id).filter(t=>!a.includes(t)),i=s==="enable"?ve:ye,c=()=>{const t=new Set([...G.map(U=>U.id),...Y.map(U=>U.id)]),h=Te("New",s==="enable"?"Enable":"Display",t);s==="enable"?je({id:h,steps:[]}):fe({id:h,steps:[]}),J(h,s)};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:r.rulePills,children:[a.map(t=>e.jsxs("div",{className:r.ruleRow,children:[e.jsx(E,{appearance:"outline",size:"medium",className:r.ruleChip,onClick:()=>J(t,s),role:"button",tabIndex:0,children:t}),e.jsx(u,{appearance:"subtle",size:"small",className:r.ruleRemoveBtn,icon:e.jsx(R,{}),"aria-label":`Unbind ${t}`,onClick:()=>{v(s==="enable"?{enableRules:l.enableRules.filter(h=>h!==t)}:{displayRules:l.displayRules.filter(h=>h!==t)})}})]},t)),a.length===0&&e.jsxs(d,{italic:!0,style:{color:n.colorNeutralForeground3},children:["No ",s," rules — always ",s==="enable"?"enabled":"visible","."]})]}),e.jsxs("div",{className:r.row,children:[e.jsx(j,{label:`Bind existing ${s} rule`,style:{minWidth:"260px"},children:e.jsxs(X,{value:i,onChange:(t,h)=>s==="enable"?Q(h.value):Z(h.value),children:[e.jsx("option",{value:"",children:"Select a rule…"}),o.map(t=>e.jsx("option",{value:t,children:t},t))]})}),e.jsx(u,{appearance:"secondary",size:"small",disabled:!i,onClick:()=>{i&&(s==="enable"?(v({enableRules:[...l.enableRules,i]}),Q("")):(v({displayRules:[...l.displayRules,i]}),Z("")))},children:"Bind selected"}),e.jsxs(u,{appearance:"subtle",size:"small",onClick:c,children:["Create new ",s," rule"]})]}),s==="enable"&&e.jsx(y,{intent:"info",children:e.jsxs(C,{children:["Disabled buttons are ",e.jsx("strong",{children:"hidden"})," in the modern command bar (Unified Interface). In the classic ribbon, disabled buttons remain visible but do not respond to clicks."]})})]})},ke=()=>e.jsxs(e.Fragment,{children:[e.jsxs(d,{children:["Referenced by ",e.jsx("strong",{children:ie})," button(s)."]}),V.length>0&&e.jsx("div",{className:r.versionsList,children:V.map(s=>e.jsx("div",{className:r.versionRow,children:e.jsxs("div",{children:[e.jsx(d,{weight:"semibold",style:{fontFamily:n.fontFamilyMonospace},children:s.button.id}),e.jsxs(d,{className:r.versionMeta,children:[s.location," → ",s.tab.label," → ",s.group.label]})]})},`${s.location}:${s.tab.id}:${s.group.id}:${s.button.id}`))})]}),ce=be.filter(s=>s.target===l.id||s.detail.includes(l.id)).slice().reverse(),De=()=>e.jsx(e.Fragment,{children:ce.length===0?e.jsx(d,{style:{color:n.colorNeutralForeground3},children:"No command-specific history entries yet."}):e.jsx("div",{className:r.versionsList,children:ce.map((s,a)=>e.jsxs("div",{className:r.versionRow,children:[e.jsxs("div",{children:[e.jsx(d,{weight:"semibold",children:s.op}),e.jsx(d,{className:r.versionMeta,children:s.detail})]}),e.jsx(d,{className:r.versionMeta,children:new Date(s.ts).toLocaleString()})]},`${s.ts}-${a}`))})});return e.jsxs(_e,{position:"end",open:W,onOpenChange:()=>M(),className:r.drawer,children:[e.jsx(Xe,{children:e.jsx(Je,{action:e.jsx(u,{appearance:"subtle",icon:e.jsx(R,{}),onClick:M,"aria-label":"Close command editor"}),children:e.jsx(d,{size:400,weight:"semibold",style:{fontFamily:n.fontFamilyMonospace},children:l.id})})}),e.jsxs(qe,{className:r.body,children:[e.jsxs(Ye,{selectedValue:f,onTabSelect:(s,a)=>ge(a.value),children:[e.jsx(S,{value:"actions",children:"Actions"}),e.jsx(S,{value:"enableRules",children:"Enable rules"}),e.jsx(S,{value:"displayRules",children:"Display rules"}),e.jsx(S,{value:"settings",children:"Settings"}),e.jsxs(S,{value:"references",children:["References (",ie,")"]}),e.jsx(S,{value:"versions",children:"Versions"})]}),e.jsx(_,{}),e.jsx($e,{commandId:l.id}),e.jsxs("fieldset",{disabled:we,className:r.readOnly,children:[f==="actions"&&Me(),f==="enableRules"&&te("enable"),f==="displayRules"&&te("display"),f==="settings"&&Ie()]}),f==="references"&&ke(),f==="versions"&&De()]})]})};export{is as CommandEditorPanel,is as default};
@@ -0,0 +1 @@
1
+ import{z as a,E as te,y as oe}from"./fluent-icons-DxKNRZ1A.js";import{a as u}from"./monaco-Bx8A1Vm1.js";import{a as s,u as c,b as ae,a7 as ne,X as h,a2 as se,a8 as ie,e as le}from"./index-Bu7BlRFk.js";import{t,c as re,T as y}from"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";const ce=oe({backdrop:{position:"fixed",inset:0,backgroundColor:"rgba(0,0,0,0.5)",zIndex:1e3,display:"flex",alignItems:"flex-start",justifyContent:"center",paddingTop:"10vh"},palette:{width:"640px",maxWidth:"90vw",backgroundColor:t.colorNeutralBackground1,borderRadius:t.borderRadiusLarge,boxShadow:t.shadow64,overflow:"hidden"},searchRow:{display:"flex",alignItems:"center",padding:`${t.spacingVerticalM} ${t.spacingHorizontalM}`,borderBottom:`1px solid ${t.colorNeutralStroke1}`,gap:t.spacingHorizontalS},searchInput:{flex:1,border:"none",outline:"none",fontSize:t.fontSizeBase400,backgroundColor:"transparent"},results:{maxHeight:"400px",overflowY:"auto"},group:{paddingTop:t.spacingVerticalXS},groupLabel:{padding:`${t.spacingVerticalXXS} ${t.spacingHorizontalM}`,color:t.colorNeutralForeground3,fontSize:t.fontSizeBase100,fontWeight:t.fontWeightSemibold,textTransform:"uppercase",letterSpacing:"0.08em"},item:{display:"flex",alignItems:"center",gap:t.spacingHorizontalS,padding:`${t.spacingVerticalXS} ${t.spacingHorizontalM}`,cursor:"pointer","&:hover":{backgroundColor:t.colorNeutralBackground1Hover}},itemSelected:{backgroundColor:t.colorNeutralBackground1Hover},itemLabel:{flex:1},itemSub:{color:t.colorNeutralForeground3,fontSize:t.fontSizeBase200},footer:{padding:`${t.spacingVerticalXS} ${t.spacingHorizontalM}`,borderTop:`1px solid ${t.colorNeutralStroke1}`,color:t.colorNeutralForeground3,fontSize:t.fontSizeBase100,display:"flex",gap:t.spacingHorizontalL}}),he=()=>{const i=ce(),g=s(e=>e.commandPaletteOpen),N=s(e=>e.setCommandPaletteOpen),L=s(e=>e.openBulkPublish),X=s(e=>e.openXmlDrawer),f=s(e=>e.openImportXml),D=s(e=>e.openCommandEditor),C=s(e=>e.openRuleEditor),T=s(e=>e.openNewGroup),H=s(e=>e.openNewButton),O=s(e=>e.openLocalizationEditor),v=s(e=>e.themeMode),P=s(e=>e.setThemeMode),W=c(e=>e.undo),G=c(e=>e.redo),V=c(e=>e.commands),F=c(e=>e.displayRules),U=c(e=>e.enableRules),$=c(e=>e.ribbons),q=ae(e=>e.entities),K=ne(e=>e.requestEntitySwitch),A=h(e=>e.location),Q=h(e=>e.tabId),p=h(e=>e.selectedButtonId),I=h(e=>e.selectedGroupId),[l,j]=u.useState(""),[x,d]=u.useState(0),z=u.useRef(null),n=u.useCallback(()=>{N(!1),j(""),d(0)},[N]);u.useEffect(()=>{g&&setTimeout(()=>z.current?.focus(),50)},[g]);const Z=()=>{const e=[],r=$[A].tabs.find(o=>o.id===Q),J=r?.groups[0]?.id??null,S=I??J,R=se(ie(r?.groups.find(o=>o.id===I),p)?.kind),_=[{id:"publish",label:"Publish all",subtitle:"Save and publish changes to Dataverse",kind:"action",action:()=>{L(),n()}},{id:"view-xml",label:"View RibbonDiffXml",subtitle:"Open XML drawer",kind:"action",action:()=>{X(),n()}},{id:"import-xml",label:"Import XML",subtitle:"Import RibbonDiffXml from clipboard",kind:"action",action:()=>{n();const o=navigator.clipboard?.readText?.();if(!o)return f();o.then(m=>f(m.trim().startsWith("<")?m:""),()=>f())}},{id:"new-group",label:"New group",subtitle:"Create a new ribbon group in current tab",kind:"action",action:()=>{T(),n()}},{id:"new-button",label:"New button",subtitle:S?"Create a new button in selected/current group":"Select a tab/group with at least one group first",kind:"action",action:()=>{S&&(H(S),n())}},{id:"edit-labels",label:"Edit localized labels",subtitle:R?"The selected control is shown read-only":p?"Open localization editor for selected button":"Select a button first",kind:"action",action:()=>{!p||R||(O(p),n())}},{id:"toggle-theme",label:`Toggle theme (${v==="dark"?"Dark":"Light"})`,subtitle:"Switch between light and dark",kind:"action",action:()=>{P(v==="dark"?"light":"dark"),n()}},{id:"undo",label:"Undo",subtitle:"Ctrl+Z",kind:"action",action:()=>{W(),n()}},{id:"redo",label:"Redo",subtitle:"Ctrl+Shift+Z",kind:"action",action:()=>{G(),n()}}];if(e.push(..._),!l.startsWith("@")&&!l.startsWith("/")){const o=Object.entries($).flatMap(([m,ee])=>ee.tabs.flatMap(M=>M.groups.flatMap(B=>le(B).map(w=>({id:`btn-${w.id}`,label:w.label||w.id,subtitle:`${m} → ${M.label} → ${B.label}`,kind:"button",action:()=>{n()}})))));e.push(...o.slice(0,20))}return V.forEach(o=>{e.push({id:`cmd-${o.id}`,label:o.id,subtitle:`${o.actions.length} action(s)`,kind:"command",action:()=>{D(o.id),n()}})}),F.forEach(o=>{e.push({id:`dr-${o.id}`,label:o.id,subtitle:`Display rule — ${o.steps.length} step(s)`,kind:"rule",action:()=>{C(o.id,"display"),n()}})}),U.forEach(o=>{e.push({id:`er-${o.id}`,label:o.id,subtitle:`Enable rule — ${o.steps.length} step(s)`,kind:"rule",action:()=>{C(o.id,"enable"),n()}})}),(l.startsWith("@")||!l)&&q.slice(0,30).forEach(o=>{e.push({id:`ent-${o.logicalName}`,label:o.displayName,subtitle:o.logicalName,kind:"entity",action:()=>{K(o),n()}})}),e},k=l.startsWith("@")||l.startsWith("/")?l.slice(1):l,E=Z(),b=k?E.filter(e=>e.label.toLowerCase().includes(k.toLowerCase())||(e.subtitle??"").toLowerCase().includes(k.toLowerCase())):E,Y=e=>{e.key==="ArrowDown"?(e.preventDefault(),d(r=>Math.min(r+1,b.length-1))):e.key==="ArrowUp"?(e.preventDefault(),d(r=>Math.max(r-1,0))):e.key==="Enter"?b[x]?.action():e.key==="Escape"&&n()};return g?a.jsx("div",{className:i.backdrop,onClick:n,role:"presentation",children:a.jsxs("div",{className:i.palette,onClick:e=>e.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":"Command palette",children:[a.jsxs("div",{className:i.searchRow,children:[a.jsx(te,{style:{color:t.colorNeutralForeground3,flexShrink:0}}),a.jsx("input",{ref:z,className:i.searchInput,value:l,onChange:e=>{j(e.target.value),d(0)},onKeyDown:Y,placeholder:"Search commands, buttons, entities… Use @ for entities, / for actions","aria-label":"Command palette search"})]}),a.jsxs("div",{className:i.results,role:"listbox",children:[b.map((e,r)=>a.jsxs("div",{className:`${i.item} ${r===x?i.itemSelected:""}`,onClick:e.action,role:"option","aria-selected":r===x,onMouseEnter:()=>d(r),children:[a.jsx(re,{appearance:"outline",size:"small",children:e.kind}),a.jsxs("div",{className:i.itemLabel,children:[a.jsx(y,{children:e.label}),e.subtitle&&a.jsx(y,{className:i.itemSub,block:!0,children:e.subtitle})]})]},e.id)),b.length===0&&a.jsx("div",{className:i.item,children:a.jsx(y,{style:{color:t.colorNeutralForeground3},children:"No results"})})]}),a.jsxs("div",{className:i.footer,children:[a.jsx("span",{children:"↑↓ navigate"}),a.jsx("span",{children:"↵ select"}),a.jsx("span",{children:"Esc close"}),a.jsx("span",{children:"@ entities"}),a.jsx("span",{children:"/ actions"})]})]})}):null};export{he as CommandPalette,he as default};
@@ -0,0 +1 @@
1
+ import{z as e,h as k,bM as C,b6 as D,y as M}from"./fluent-icons-DxKNRZ1A.js";import{a as c}from"./monaco-Bx8A1Vm1.js";import{a as u,u as B}from"./index-Bu7BlRFk.js";import{ah as I,ai as R,aj as H,aa as L,B as N,ak as E,T as a,t as o,M as h,e as x,a5 as F,c as z,m as O}from"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";function $(){return window.dataverseAPI}function P(i){const l=i.map(s=>{const r=s.publisherid,d=s.versionnumber,m=typeof d=="number"?d:Number(d??0)||0;return{solutionId:String(s.solutionid??""),solutionName:String(s.friendlyname??s.uniquename??"Unknown Solution"),publisher:String(r?.friendlyname??r?.customizationprefix??"Unknown Publisher"),managed:!!s.ismanaged,importedOn:s.modifiedon?String(s.modifiedon):void 0,wins:!1,versionNumber:m}});return l.sort((s,r)=>s.versionNumber-r.versionNumber),l.length>0&&(l[l.length-1].wins=!0),l.map(({versionNumber:s,...r})=>r)}async function A(i){if(!i)return null;const r=(await $().getSolutions(["solutionid","friendlyname","uniquename","ismanaged","publisherid","versionnumber","modifiedon"])).value;return r.length<=1?null:{elementId:i,elementKind:"button",solutions:P(r)}}const T=M({drawer:{width:"560px",maxWidth:"95vw"},body:{display:"flex",flexDirection:"column",gap:o.spacingHorizontalM,padding:o.spacingHorizontalM,overflowY:"auto"},solutionRow:{display:"flex",flexDirection:"column",gap:o.spacingHorizontalXS,padding:o.spacingHorizontalS,border:`1px solid ${o.colorNeutralStroke2}`,borderRadius:o.borderRadiusMedium,backgroundColor:o.colorNeutralBackground2},solutionRowWinner:{border:`2px solid ${o.colorBrandStroke1}`,backgroundColor:o.colorBrandBackground2},solutionHeader:{display:"flex",alignItems:"center",gap:o.spacingHorizontalS},elementId:{fontFamily:o.fontFamilyMonospace,fontSize:o.fontSizeBase200,backgroundColor:o.colorNeutralBackground4,padding:`2px ${o.spacingHorizontalXS}`,borderRadius:o.borderRadiusSmall,wordBreak:"break-all"}}),K=()=>{const i=T(),l=u(n=>n.conflictDrawerOpen),s=u(n=>n.conflictElementId),r=u(n=>n.closeConflictDrawer),d=u(n=>n.openXmlDrawer),m=B(n=>n.conflicts),[p,b]=c.useState(null),[j,f]=c.useState(!1),[v,g]=c.useState(null);c.useEffect(()=>{if(!l||!s){b(null),g(null),f(!1);return}let n=!1;return f(!0),g(null),A(s).then(t=>{n||b(t)}).catch(t=>{n||g(t instanceof Error?t.message:"Failed to load conflict layers")}).finally(()=>{n||f(!1)}),()=>{n=!0}},[l,s]);const w=m.filter(n=>n.elementId===s),y=c.useMemo(()=>p||w[0],[p,w]),S=y?[...y.solutions].sort((n,t)=>n.wins===t.wins?0:n.wins?1:-1):[];return e.jsxs(I,{className:i.drawer,open:l,position:"end",onOpenChange:(n,t)=>!t.open&&r(),children:[e.jsx(R,{children:e.jsx(H,{action:e.jsx(N,{appearance:"subtle",icon:e.jsx(k,{}),onClick:r,"aria-label":"Close"}),children:e.jsx(L,{children:"Solution Conflicts"})})}),e.jsx(E,{children:e.jsxs("div",{className:i.body,children:[s&&e.jsxs("div",{children:[e.jsx(a,{size:200,style:{color:o.colorNeutralForeground3},children:"Conflicting element:"}),e.jsx("div",{className:i.elementId,children:s})]}),e.jsx(h,{intent:"warning",children:e.jsx(x,{children:e.jsx(a,{size:200,children:"Multiple solutions customize this element. Dataverse applies them in solution import order — the most recently imported solution wins."})})}),e.jsx(h,{intent:"info",children:e.jsx(x,{children:e.jsxs(a,{size:200,children:[e.jsx("strong",{children:"To resolve:"})," Merge changes into one solution, or use solution layering to control evaluation order. Managed solutions appear as read-only layers — to resolve, merge the customization into your unmanaged solution."]})})}),j&&e.jsx("div",{style:{display:"flex",justifyContent:"center",padding:o.spacingHorizontalM},children:e.jsx(F,{label:"Loading solution layers..."})}),v&&e.jsx(h,{intent:"error",children:e.jsx(x,{children:v})}),!j&&S.length===0&&e.jsx(a,{style:{color:o.colorNeutralForeground3,textAlign:"center"},children:"No conflict details available from environment layers."}),S.map((n,t)=>e.jsxs("div",{className:`${i.solutionRow} ${n.wins?i.solutionRowWinner:""}`,children:[e.jsxs("div",{className:i.solutionHeader,children:[e.jsx(a,{weight:"semibold",children:n.solutionName}),n.wins&&e.jsx(z,{appearance:"filled",color:"brand",children:"WINS"}),n.managed&&e.jsx(O,{content:"Managed solution — read-only",relationship:"label",children:e.jsx(C,{style:{color:o.colorNeutralForeground3}})}),e.jsx(z,{appearance:"outline",size:"small",children:n.managed?"Managed":"Unmanaged"})]}),e.jsxs(a,{size:200,style:{color:o.colorNeutralForeground3},children:["Publisher: ",n.publisher]}),n.importedOn&&e.jsxs(a,{size:200,style:{color:o.colorNeutralForeground3},children:["Imported: ",new Date(n.importedOn).toLocaleString()]}),e.jsx("div",{style:{display:"flex",gap:o.spacingHorizontalS,flexWrap:"wrap"},children:e.jsx(N,{appearance:"subtle",size:"small",icon:e.jsx(D,{}),onClick:d,children:"View XML diff"})})]},`${n.solutionId}-${t}`))]})})]})};export{K as ConflictDrawer,K as default};
@@ -0,0 +1 @@
1
+ import{z as e,s as h,A as P,h as g,cq as y,y as f}from"./fluent-icons-DxKNRZ1A.js";import{U as j}from"./crmParameters-rgfZhhzN.js";import{S as v,F as I,I as S,am as k,c as b,B as u,T as R,t as o}from"./fluent-ui-D7EtYwEg.js";const N=f({root:{display:"flex",flexDirection:"column",gap:o.spacingVerticalXS},param:{display:"flex",gap:o.spacingHorizontalS,alignItems:"flex-end",padding:o.spacingVerticalXS,border:`1px solid ${o.colorNeutralStroke2}`,borderRadius:o.borderRadiusMedium},typeSelect:{width:"140px",flexShrink:0},valueField:{flex:1},actions:{display:"flex",gap:o.spacingHorizontalXS,flexShrink:0},addButton:{alignSelf:"flex-start"},hint:{color:o.colorNeutralForeground3,fontSize:o.fontSizeBase100}}),A=[{label:"Context",values:["PrimaryControl","PrimaryControlId","SelectedControl","CommandProperties"]},{label:"Record",values:["PrimaryEntityTypeCode","PrimaryEntityTypeName","FirstPrimaryItemId","PrimaryItemIds"]},{label:"Selection context",values:["SelectedEntityTypeCode","SelectedEntityTypeName","FirstSelectedItemId"]},{label:"Grid selection",values:["SelectedControlSelectedItemCount","SelectedControlSelectedItemIds","SelectedControlSelectedItemReferences","SelectedControlAllItemCount","SelectedControlAllItemIds","SelectedControlAllItemReferences","SelectedControlUnselectedItemCount","SelectedControlUnselectedItemIds","SelectedControlUnselectedItemReferences"]},{label:"Org/User",values:["OrgName","OrgLcid","UserLcid"]}],B=({params:c,onChange:d,urlMode:m=!1})=>{const i=N(),s=(l,t)=>{const r=[...c];r[l]=t,d(r)},C=l=>{d(c.filter((t,r)=>r!==l))},x=(l,t)=>{const r=[...c],a=l+t;a<0||a>=r.length||([r[l],r[a]]=[r[a],r[l]],d(r))},p=()=>{d([...c,{kind:"CrmParameter",value:"PrimaryControl"}])};return e.jsxs("div",{className:i.root,children:[c.map((l,t)=>e.jsxs("div",{className:i.param,children:[e.jsx("div",{className:i.typeSelect,children:e.jsxs(v,{value:l.kind,onChange:(r,a)=>{const n=a.value;n==="CrmParameter"?s(t,{kind:n,value:"PrimaryControl"}):n==="BoolParameter"?s(t,{kind:n,value:!1}):n==="IntParameter"||n==="DecimalParameter"?s(t,{kind:n,value:0}):s(t,{kind:"StringParameter",value:""})},children:[e.jsx("option",{value:"CrmParameter",children:"CrmParameter"}),e.jsx("option",{value:"StringParameter",children:"String"}),e.jsx("option",{value:"BoolParameter",children:"Boolean"}),e.jsx("option",{value:"IntParameter",children:"Integer"}),e.jsx("option",{value:"DecimalParameter",children:"Decimal"})]})}),m&&e.jsx(I,{label:"Name (querystring key)",style:{width:"130px",flexShrink:0},children:e.jsx(S,{value:l.name??"",onChange:(r,a)=>s(t,{...l,name:a.value||void 0}),placeholder:"key"})}),e.jsx("div",{className:i.valueField,children:l.kind==="CrmParameter"?e.jsx(v,{value:l.value,onChange:(r,a)=>s(t,{...l,value:a.value}),children:A.map(r=>r.values.filter(a=>!m||!j.has(a)).map(a=>e.jsx("option",{value:a,children:a},a)))}):l.kind==="BoolParameter"?e.jsx(k,{checked:l.value,onChange:(r,a)=>s(t,{...l,value:a.checked}),label:"true"}):e.jsx(S,{type:l.kind==="StringParameter"?"text":"number",value:String(l.value),onChange:(r,a)=>{const n=l.kind==="StringParameter"?a.value:l.kind==="IntParameter"?parseInt(a.value):parseFloat(a.value);s(t,{...l,value:n})}})}),m&&l.kind==="CrmParameter"&&!l.name&&e.jsx(b,{appearance:"filled",color:"warning",size:"small",title:"Name required for URL actions"}),e.jsxs("div",{className:i.actions,children:[e.jsx(u,{appearance:"subtle",size:"small",icon:e.jsx(h,{}),onClick:()=>x(t,-1),disabled:t===0,"aria-label":"Move up"}),e.jsx(u,{appearance:"subtle",size:"small",icon:e.jsx(P,{}),onClick:()=>x(t,1),disabled:t===c.length-1,"aria-label":"Move down"}),e.jsx(u,{appearance:"subtle",size:"small",icon:e.jsx(g,{}),onClick:()=>C(t),"aria-label":"Remove parameter"})]})]},t)),m&&e.jsxs(R,{className:i.hint,children:["For URL actions, each CrmParameter must have a ",e.jsx("code",{children:"name"})," attribute (querystring key)."]}),e.jsx(u,{className:i.addButton,appearance:"secondary",size:"small",icon:e.jsx(y,{}),onClick:p,children:"Add parameter"})]})};export{B as C};
@@ -0,0 +1,7 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./monaco-Bx8A1Vm1.js","./monaco-Dprb6f6S.css"])))=>i.map(i=>d[i]);
2
+ import{R as g,a as b,_ as H}from"./monaco-Bx8A1Vm1.js";import{z as s,h as E,y as C}from"./fluent-icons-DxKNRZ1A.js";import{a as x,u,g as N}from"./index-Bu7BlRFk.js";import{ah as O,ai as _,aj as V,aa as $,B as S,ak as X,M as I,e as T,T as A,c as D,a5 as G,t as r}from"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";const P=g.lazy(()=>H(()=>import("./monaco-Bx8A1Vm1.js").then(n=>n.i),__vite__mapDeps([0,1]),import.meta.url).then(n=>({default:n.DiffEditor}))),W=["HomepageGrid","SubGrid","Form","Application"],U=C({drawer:{},body:{display:"flex",flexDirection:"column",flex:"1 1 auto",minHeight:0,overflow:"hidden",gap:r.spacingHorizontalS},statsBar:{display:"flex",alignItems:"center",gap:r.spacingHorizontalS,padding:`${r.spacingVerticalXS} ${r.spacingHorizontalM}`,flexShrink:0},toggleRow:{display:"flex",alignItems:"center",gap:r.spacingHorizontalS,padding:`${r.spacingVerticalXS} ${r.spacingHorizontalM}`,borderBottom:`1px solid ${r.colorNeutralStroke2}`,flexShrink:0},editorWrap:{flex:1,height:0,minHeight:"400px",overflow:"hidden",position:"relative"}});function F(n,o){const l=n.split(`
3
+ `),c=o.split(`
4
+ `);let d=0,a=0;const f=new Set(l),t=new Set(c);for(const i of c)f.has(i)||d++;for(const i of l)t.has(i)||a++;return{added:d,removed:a}}function B(n,o,l,c,d,a,f){const t=[];for(const i of W){const p=f?o[i]:n[i],m=o[i];try{t.push(`<!-- ${i} -->
5
+ `+N({location:i,current:p,baseline:m,commands:l,displayRules:c,enableRules:d,locLabels:a,entityLogicalName:p.entityLogicalName}))}catch(h){t.push(`<!-- ${i}: Error generating XML: ${String(h)} -->`)}}return t.join(`
6
+
7
+ `)}const Z=()=>{const n=U(),o=x(e=>e.diffViewerOpen),l=x(e=>e.diffViewerMode),c=x(e=>e.closeDiffViewer),d=x(e=>e.themeMode),[a,f]=g.useState(!0),t=u(e=>e.ribbons),i=u(e=>e.baseline),p=u(e=>e.commands),m=u(e=>e.displayRules),h=u(e=>e.enableRules),y=u(e=>e.locLabels),R=d==="dark",j=b.useMemo(()=>B(t,i,p,m,h,y,!0),[o]),w=b.useMemo(()=>B(t,i,p,m,h,y,!1),[o,t,i,p,m,h,y]),{added:k,removed:L}=F(j,w),v=g.useRef(null),z=g.useCallback(e=>{v.current=e,e.updateOptions({renderSideBySide:a})},[]);return g.useEffect(()=>{v.current?.updateOptions({renderSideBySide:a})},[a]),s.jsxs(O,{className:n.drawer,open:o,position:"end",size:"full",onOpenChange:(e,M)=>!M.open&&c(),children:[s.jsx(_,{children:s.jsx(V,{action:s.jsx(S,{appearance:"subtle",icon:s.jsx(E,{}),onClick:c,"aria-label":"Close"}),children:s.jsx($,{children:l==="compare"?"Compare to baseline":"Diff viewer"})})}),s.jsx(X,{style:{display:"flex",flexDirection:"column",flex:"1 1 auto",minHeight:0,overflow:"hidden"},children:s.jsxs("div",{className:n.body,children:[s.jsx(I,{intent:"info",children:s.jsx(T,{children:s.jsx(A,{size:200,children:l==="compare"?"Showing current state vs. last published baseline.":"Showing the change introduced by this history entry."})})}),s.jsxs("div",{className:n.toggleRow,children:[s.jsxs(D,{appearance:"tint",color:"success",children:["+",k," lines"]}),s.jsxs(D,{appearance:"tint",color:"danger",children:["-",L," lines"]}),s.jsx("div",{style:{flex:1}}),s.jsx(S,{appearance:a?"primary":"subtle",size:"small",onClick:()=>f(!0),children:"Side by side"}),s.jsx(S,{appearance:a?"subtle":"primary",size:"small",onClick:()=>f(!1),children:"Unified"})]}),s.jsx("div",{className:n.editorWrap,children:s.jsx(b.Suspense,{fallback:s.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%"},children:s.jsx(G,{size:"medium",label:"Loading diff editor…"})}),children:s.jsx(P,{original:j,modified:w,language:"xml",theme:R?"vs-dark":"vs",height:"100%",onMount:z,options:{readOnly:!0,renderSideBySide:a,lineNumbers:"on",minimap:{enabled:!1},scrollBeyondLastLine:!1,automaticLayout:!0,wordWrap:"on"}})})})]})})]})};export{Z as DiffViewer,Z as default};
@@ -0,0 +1 @@
1
+ import{z as r}from"./fluent-icons-DxKNRZ1A.js";import{a as i,u as n,ag as u,ah as c,a8 as b}from"./index-Bu7BlRFk.js";import"./monaco-Bx8A1Vm1.js";import"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";const h=()=>{const o=i(e=>e.hideInsteadOfDelete),a=i(e=>e.closeHideInsteadOfDelete),s=i(e=>e.announce),t=n(e=>o?b(e.ribbons[o.location].tabs.find(d=>d.id===o.tabId)?.groups.find(d=>d.id===o.groupId),o.buttonId):void 0),l=n(e=>o?e.baseline[o.location]:void 0);return!o||!t||!l?null:r.jsx(u,{open:!0,buttonLabel:t.label,commandId:t.commandId,deleteBlockedReason:c(t,l),onConfirmHide:()=>{n.getState().hideOobButton(o.location,o.tabId,o.groupId,o.buttonId),s("Button hidden"),a()},onConfirmDisplayRule:()=>{n.getState().hideWithDisplayRules(t.commandId)&&s("Button hidden"),a()},onCancel:a})};export{h as HideInsteadOfDeleteModal,h as default};
@@ -0,0 +1 @@
1
+ import{z as r,h as pe,E as q,L as he,y as me}from"./fluent-icons-DxKNRZ1A.js";import{a as l,R as X}from"./monaco-Bx8A1Vm1.js";import{O as be,a as Y,u as fe,X as T,b as Z,aa as ye,c as U,ab as we}from"./index-Bu7BlRFk.js";import{s as J,p as Se,l as Q,d as xe}from"./webResourceService-CvyHBu7T.js";import{D as Ce,h as ke,j as ve,i as Re,aa as je,B as A,k as Be,ac as Ie,ad as W,I as H,C as $e,O as Te,a1 as Ae,t as s,T as y,c as Pe,l as Ee}from"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";function G(a){return a.replace(/([A-Z])/g,(t,i,c)=>(c>0?"_":"")+t.toLowerCase())}function Ne(a){const t=new TextEncoder().encode(a);let i="";for(let c=0;c<t.length;c++)i+=String.fromCharCode(t[c]);return btoa(i)}function ee(a,t="regular"){return`${G(a)}${t==="filled"?".filled":""}.svg`}function oe(a,t,i="regular"){const c=a.trim().replace(/_+$/,"");if(!c)throw new Error("A publisher prefix is required to name the icon web resource");return`${c}_/icons/cbs/${ee(t,i)}`}const Fe=11,De=2*6e4,K={save:J,publish:Se},Le=new Set;async function ze(a,t,i,c,g={}){const x=g.save??K.save,I=g.publish??K.publish,v=g.published??Le,w=oe(i,a,t),h=await c(a,20,t);if(!h)throw new Error(`Could not convert the Fluent icon "${a}" to SVG`);const m=await x(w,Ne(h),Fe,{displayName:`${ee(a,t)} (CBS icon)`,keepExisting:!0}),d={name:w,id:m.id,created:m.created};if(!v.has(m.id))try{await be(`Publishing icon web resource ${w}`,()=>I(m.id),{timeoutMs:De,...g.busy}),v.add(m.id)}catch(C){d.publishError=C instanceof Error?C.message:String(C)}return d}const Me=[{category:"Actions",keywords:["Add","Delete","Edit","Save","Copy","Paste","Undo","Redo","Send","Print","Refresh"]},{category:"Communication",keywords:["Mail","Chat","Phone","Call","Message"]},{category:"Navigation",keywords:["Arrow","Chevron","Navigation","Home","Back","Forward"]},{category:"System",keywords:["Settings","Info","Warning","Dismiss","Question","Checkmark","Error"]},{category:"Security",keywords:["Lock","Shield","Key","Fingerprint"]},{category:"People",keywords:["Person","People","Contact","User"]},{category:"Business",keywords:["Building","Briefcase","Money","Credit","Cart","Tag","Receipt"]},{category:"Files",keywords:["Document","Folder","Attach","Upload","Download","File"]},{category:"Web",keywords:["Globe","Link","Open","Browser","World"]},{category:"Time",keywords:["Calendar","Clock","Timer","History"]},{category:"Rating",keywords:["Star","Heart","Thumb"]},{category:"View",keywords:["Eye","Zoom","View","Window","Preview"]},{category:"Layout",keywords:["Grid","List","Table","Panel","Column","Row"]},{category:"Development",keywords:["Code","Bug","Branch","Wrench","Tool","Terminal"]},{category:"Media",keywords:["Play","Pause","Stop","Video","Audio","Camera"]},{category:"Analytics",keywords:["Chart","Data","Poll","Graph","Trend"]}],Ue=["Add","Delete","Edit","Save","Copy","Cut","ClipboardPaste","Share","Mail","Chat","Phone","Search","Filter","ArrowLeft","ArrowRight","ArrowUp","ArrowDown","ChevronDown","ChevronUp","Navigation","Home","Settings","Info","Warning","Checkmark","Dismiss","QuestionCircle","LockClosed","LockOpen","Shield","Person","People","PersonAdd","Building","Briefcase","Money","CreditCard","Cart","Tag","Document","DocumentBulletList","Folder","FolderOpen","Attach","ArrowDownload","ArrowUpload","Globe","Link","Open","Calendar","Clock","Timer","Star","Heart","ThumbLike","ThumbDislike","Eye","EyeOff","ZoomIn","ZoomOut","Maximize","Minimize","Grid","List","Table","TableSimple","Code","Bug","Play","Pause","Stop","Refresh","ArrowSync","ArrowUndo","ArrowRedo","Printer","Send","Rocket","Sparkle","Trophy","Lightbulb","Bot","DataBar","ChartMultiple","Poll"];function We(a){for(const t of Me)if(t.keywords.some(i=>a.includes(i)))return t.category;return"General"}const re=Ue.map(a=>({name:a,category:We(a)})),He=["All",...Array.from(new Set(re.map(a=>a.category))).sort()],Ge=me({surface:{width:"720px",maxWidth:"95vw",height:"min(580px, 90vh)",maxHeight:"90vh",overflow:"hidden"},dialogBody:{display:"flex",flexDirection:"column",height:"100%",minHeight:0},body:{display:"flex",flexDirection:"column",flex:1,minHeight:0,overflow:"hidden",gap:s.spacingHorizontalS},toolbar:{display:"flex",alignItems:"center",gap:s.spacingHorizontalS,flexWrap:"wrap",flexShrink:0},categoryPicker:{minWidth:"180px",maxWidth:"220px"},iconGrid:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(72px, 1fr))",gap:s.spacingHorizontalXS,overflowY:"auto",flex:1,minHeight:0,padding:s.spacingHorizontalXS},iconTile:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:"4px",padding:s.spacingHorizontalXS,borderRadius:s.borderRadiusMedium,border:"1px solid transparent",cursor:"pointer",minHeight:"64px",":hover":{backgroundColor:s.colorNeutralBackground3,border:`1px solid ${s.colorNeutralStroke1}`}},iconTileSelected:{backgroundColor:s.colorBrandBackground2,border:`1px solid ${s.colorBrandStroke1}`},iconLabel:{fontSize:s.fontSizeBase100,textAlign:"center",lineHeight:1.2,wordBreak:"break-word",color:s.colorNeutralForeground2},webResourceList:{flex:1,overflowY:"auto"},webResourceRow:{display:"flex",alignItems:"center",gap:s.spacingHorizontalS,padding:`${s.spacingHorizontalXS} ${s.spacingHorizontalS}`,cursor:"pointer",borderRadius:s.borderRadiusMedium,":hover":{backgroundColor:s.colorNeutralBackground3}},uploadArea:{flex:1,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:s.spacingHorizontalM,border:`2px dashed ${s.colorNeutralStroke2}`,borderRadius:s.borderRadiusMedium,color:s.colorNeutralForeground3}}),Ze=()=>{const a=Ge(),t=Y(e=>e.iconPickerOpen),i=Y(e=>e.closeIconPicker),c=fe(e=>e.setButtonProp),g=T(e=>e.selectedButtonId),x=T(e=>e.selectedGroupId),I=T(e=>e.tabId),v=T(e=>e.location),w=Z(e=>e.publisherPrefix),h=Z(e=>e.activeSolution),[m,d]=l.useState(null),[C,P]=l.useState(null),[b,_]=l.useState("fluent"),[E,se]=l.useState(""),[$,ae]=l.useState("All"),[R,te]=l.useState("regular"),[u,ne]=l.useState(null),[f,N]=l.useState(""),[F,D]=l.useState([]),[O,V]=l.useState(!1),[L,ie]=l.useState(""),[j,k]=l.useState(!1);X.useEffect(()=>{t||(d(null),P(null))},[t]),X.useEffect(()=>{!t||b!=="webresource"||(V(!0),Q("svg").then(e=>D(e)).catch(()=>D([])).finally(()=>V(!1)))},[t,b]);const le=l.useMemo(()=>{const e=L.toLowerCase();return F.filter(o=>!e||o.name.toLowerCase().includes(e))},[L,F]),ce=l.useMemo(()=>{const e=E.toLowerCase();return re.filter(o=>($==="All"||o.category===$)&&(e===""||o.name.toLowerCase().includes(e)))},[E,$]),de=async()=>{if(!u||!g||!x)return;const e=U.getState();if(d(null),!h||h.isManaged){d("Select an unmanaged solution first — the icon is added to it as an SVG web resource.");return}k(!0);try{const o=await ze(u,R,w,we,{busy:{onProgress:n=>e.logInfo("webresource",n)}});o.publishError&&e.logWarn("webresource",`Publishing icon web resource ${o.name} failed: ${o.publishError}. Pick the icon again or publish customizations before using the button.`),c(v,I,x,g,{icon:G(u),image16:`$webresource:${o.name}`,image32:`$webresource:${o.name}`}),e.logInfo("webresource",`${o.created?"Uploaded":"Reusing"} icon web resource ${o.name} (solution ${h.uniqueName}).`),i()}catch(o){const n=o instanceof Error?o.message:String(o);e.logError("webresource",`Fluent icon "${u}" could not be added as a web resource: ${n}`),d(`Could not add the icon as a web resource: ${n}`)}finally{k(!1)}},ue=async()=>{if(!f||!g||!x)return;const e=U.getState();d(null),P(null);const o=f.startsWith("$webresource:")?f.slice(13).trim():null;let n=null;if(o){k(!0);try{const S=F.find(z=>z.name===o),p=await xe(o,S);p.solutionUniqueName&&e.logInfo("webresource",`Added web resource ${o} to solution ${p.solutionUniqueName}.`),n=p.solutionWarning??null}catch(S){const p=S instanceof Error?S.message:String(S);if(/^No web resource named /.test(p)){d(p);return}n=`The icon was set, but ${o} could not be added to the solution: ${p}`,e.logError("webresource",n)}finally{k(!1)}}if(c(v,I,x,g,{image16:f,image32:f}),n){P(n);return}i()},ge=async e=>{if(!h||h.isManaged){d("Select an unmanaged solution first — the SVG is added to it as a web resource.");return}d(null),k(!0);try{const o=await new Promise((p,z)=>{const B=new FileReader;B.onerror=()=>z(B.error??new Error("Failed to read SVG")),B.onload=()=>{const M=String(B.result??"");p(M.includes(",")?M.split(",")[1]??"":M)},B.readAsDataURL(e)}),n=`${w||"new"}_/icons/${e.name}`;await J(n,o,11,{displayName:e.name}),N(`$webresource:${n}`),_("webresource");const S=await Q("svg");D(S)}catch(o){const n=o instanceof Error?o.message:String(o);U.getState().logError("webresource",`SVG upload failed: ${n}`),d(`Upload failed: ${n}`)}finally{k(!1)}};return r.jsx(Ce,{open:t,onOpenChange:(e,o)=>!o.open&&i(),children:r.jsx(ke,{className:a.surface,children:r.jsxs(ve,{className:a.dialogBody,children:[r.jsx(Re,{action:r.jsx(A,{appearance:"subtle",icon:r.jsx(pe,{}),onClick:i,"aria-label":"Close"}),children:r.jsx(je,{children:"Choose Icon"})}),r.jsxs(Be,{className:a.body,children:[r.jsxs(Ie,{selectedValue:b,onTabSelect:(e,o)=>_(o.value),size:"small",children:[r.jsx(W,{value:"fluent",children:"Fluent icons"}),r.jsx(W,{value:"webresource",children:"Web resources"}),r.jsx(W,{value:"upload",children:"Upload SVG"})]}),b==="fluent"&&r.jsxs(r.Fragment,{children:[r.jsxs("div",{className:a.toolbar,children:[r.jsx(H,{contentBefore:r.jsx(q,{}),placeholder:"Search icons…",value:E,onChange:(e,o)=>se(o.value),size:"small",style:{flex:1}}),r.jsx($e,{className:a.categoryPicker,placeholder:"Category",value:$,onOptionSelect:(e,o)=>ae(String(o.optionValue??"All")),children:He.map(e=>r.jsx(Te,{value:e,text:e,children:e},e))}),r.jsx(Ae,{label:R==="regular"?"Regular":"Filled",checked:R==="filled",onChange:(e,o)=>te(o.checked?"filled":"regular")})]}),r.jsx("div",{className:a.iconGrid,children:ce.map(e=>r.jsxs("div",{className:`${a.iconTile} ${u===e.name?a.iconTileSelected:""}`,onClick:()=>ne(e.name),role:"option","aria-selected":u===e.name,title:`${e.name} — ${e.category}`,children:[r.jsx(ye,{name:G(e.name),size:24,variant:R}),r.jsx("span",{className:a.iconLabel,children:e.name})]},e.name))}),u&&r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:s.spacingHorizontalS,padding:s.spacingHorizontalXS,backgroundColor:s.colorNeutralBackground3,borderRadius:s.borderRadiusMedium,flexShrink:0},children:[r.jsxs(y,{size:200,style:{fontFamily:s.fontFamilyMonospace},children:['ModernImage="$webresource:',oe(w||"new",u,R),'"']}),r.jsx(Pe,{appearance:"tint",color:"success",children:"Selected"})]})]}),b==="webresource"&&r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:s.spacingHorizontalS,flex:1},children:[r.jsx(H,{contentBefore:r.jsx(q,{}),placeholder:"Search SVG web resources...",value:L,onChange:(e,o)=>ie(o.value),size:"small"}),r.jsxs("div",{className:a.webResourceList,children:[O&&r.jsx(y,{size:200,style:{color:s.colorNeutralForeground3},children:"Loading web resources..."}),!O&&le.slice(0,200).map(e=>{const o=`$webresource:${e.name}`,n=f===o;return r.jsx("div",{className:a.webResourceRow,onClick:()=>N(o),style:{backgroundColor:n?s.colorBrandBackground2:void 0},children:r.jsx(y,{size:200,style:{fontFamily:s.fontFamilyMonospace},children:o})},e.id)})]}),r.jsx(H,{placeholder:"$webresource:publisher_/icons/…",value:f,onChange:(e,o)=>N(o.value)}),r.jsx(y,{size:100,style:{color:s.colorNeutralForeground3},children:"Both image16 and image32 will be set to this path. Use SVG for best results across all DPI levels."})]}),b==="upload"&&r.jsxs("div",{className:a.uploadArea,children:[r.jsx(he,{fontSize:48,style:{opacity:.4}}),r.jsx(y,{children:"Drag an SVG file here, or click to browse"}),r.jsx(y,{size:200,style:{color:s.colorNeutralForeground3},children:"The file will be uploaded as a web resource in the active solution."}),r.jsx("input",{type:"file",accept:".svg",style:{display:"none"},id:"icon-upload-input",onChange:e=>{const o=e.target.files?.[0];o&&ge(o)}}),r.jsx("label",{htmlFor:"icon-upload-input",style:{display:"inline-block",cursor:"pointer",padding:"6px 12px",background:s.colorBrandBackground,color:s.colorNeutralForegroundOnBrand,borderRadius:s.borderRadiusMedium,fontSize:s.fontSizeBase300},children:j?"Uploading...":"Browse for SVG"})]}),m&&r.jsx(y,{role:"alert",size:200,style:{color:s.colorPaletteRedForeground1,flexShrink:0},children:m}),C&&r.jsxs(y,{role:"status",size:200,style:{color:s.colorPaletteMarigoldForeground1,flexShrink:0},children:["Icon applied. ",C]})]}),r.jsxs(Ee,{children:[r.jsx(A,{appearance:"secondary",onClick:i,children:"Cancel"}),b==="fluent"&&r.jsx(A,{appearance:"primary",disabled:!u||j,onClick:()=>{de()},children:j?"Adding icon…":`Use ${u??"icon"}`}),b==="webresource"&&r.jsx(A,{appearance:"primary",disabled:!f||j,onClick:()=>{ue()},children:j?"Adding icon…":"Use web resource"})]})]})})})};export{Ze as IconPickerModal,Ze as default};
@@ -0,0 +1 @@
1
+ import{z as l}from"./fluent-icons-DxKNRZ1A.js";import{a as X}from"./monaco-Bx8A1Vm1.js";import{a1 as Te,x as Be,a2 as He,a3 as ze,a4 as Fe,a5 as _e,a6 as Pe,a as ae,u as Ue,X as We,b as Je}from"./index-Bu7BlRFk.js";import{a as Ye}from"./xmlValidator-D7JG-eNC.js";import{M as Ke}from"./MonacoEditor-Bbg9u2FW.js";import{D as Ve,h as Qe,i as Ze,j as et,k as tt,T as De,M,e as q,ap as le,l as ot,B as Z}from"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";import"./ruleKinds-B9hACGaq.js";import"./crmParameters-rgfZhhzN.js";const fe=["HomepageGrid","SubGrid","Form"],ce=[...fe,"Application"],de=new Set(["Button","FlyoutAnchor","SplitButton","TextBox","ComboBox","CheckBox"]),ue=new Set(["flyout","splitButton"]),pe=/^Mscrm\.(HomepageGrid|SubGrid|Form)\.([^.]+)\./,Ie="._children",nt=/<(EnableRule|DisplayRule)\b[^>]*?\sId="([^"]+)"/,me=/\$LocLabels:([^"'\s<]+)/g,Le="cbs.import.Tab",st="cbs.import.Group",ve=(a,g)=>JSON.stringify(a)===JSON.stringify(g);function O(a){return a?Array.from(a.children):[]}function it(a){return Object.fromEntries(Array.from(a.attributes).map(g=>[g.name,g.value]))}function rt(a,g,c){const m=a.documentElement;if(m.tagName==="RibbonDiffXml")return m;const S=Array.from(a.getElementsByTagName("RibbonDiffXml")),A=Array.from(a.querySelectorAll("Entities > Entity")).flatMap(r=>{const $=O(r),N=$.find(L=>L.tagName==="RibbonDiffXml"),w=$.find(L=>L.tagName==="Name")?.textContent?.trim()??"";return N?[{name:w,rdx:N}]:[]}),R=S.find(r=>r.parentElement===m);if(A.length===0&&!R){if(S.length===1)return S[0];throw new Error(S.length===0?"No <RibbonDiffXml> element found.":`The XML has ${S.length} <RibbonDiffXml> elements and none belongs to a table or the application ribbon — paste just one.`)}const I=[...A.map(r=>r.name||"(unnamed table)"),...R?["the application ribbon"]:[]].join(", ");if(c){if(R)return R;throw new Error(`The XML has no application ribbon RibbonDiffXml (it has: ${I}). Open that table's ribbon to import its customizations.`)}const y=A.find(r=>r.name.toLowerCase()===g.toLowerCase());if(y)return y.rdx;throw new Error(`The XML has no RibbonDiffXml for ${g||"the loaded table"} (it has: ${I}). Load that table, or open the application ribbon for the application ribbon's customizations.`)}function at(a){switch(a){case"HomePageGrid":return"HomepageGrid";case"Form":return"Form";case"SubGridStandard":case"SubGridAssociated":return"SubGrid";default:return}}function lt(a){const g=a.languageCode??1033,c=a.entityLogicalName,m=new DOMParser().parseFromString(a.xml,"application/xml");if(m.querySelector("parsererror"))throw new Error("The XML is not well-formed.");const S=a.activeLocation==="Application",A=rt(m,c,S),R=new XMLSerializer,I=R.serializeToString(A),y=[],r=[],$=[],N=!!c&&new RegExp(`Mscrm\\.(HomepageGrid|SubGrid|Form)\\.${c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\.`,"i").test(I),w=S&&!(A===m.documentElement&&N);A!==m.documentElement?$.push(`Imported the RibbonDiffXml of ${w?"the application ribbon":c} from the document.`):S&&!w&&$.push(`The XML's Locations name the ${c} table, so it was imported as that table's customizations, not the application ribbon's.`);const L=w?"Application":fe.includes(a.activeLocation)?a.activeLocation:"HomepageGrid",v=Te(I,a.activeLocation,c),x=(e,t,o)=>{const s=new Map,n=new Map;for(const f of t)s.set(f.id,f),n.set(f.id,(n.get(f.id)??0)+1);for(const[f,b]of n)b>1&&$.push(`${o} ${f} is defined ${b} times in the XML — the last one was used.`);const u=Array.from(s.values()),i=[...e],p=[];let h=0;for(const f of u){const b=i.findIndex(T=>T.id===f.id);if(b>=0&&ve(i[b],f)){h++;continue}y.push(`${o} ${f.id} ${b>=0?"updated":"added"}`),b>=0?i[b]=f:i.push(f),p.push(f.id)}return{out:i,changedIds:p,unchanged:h}},d=x(a.commands,v.commands,"Command"),C=x(a.enableRules,v.enableRules,"Enable rule"),k=x(a.displayRules,v.displayRules,"Display rule"),B=x(a.locLabels,v.locLabels,"Label"),H=B.out,be=d.unchanged+C.unchanged+k.unchanged+B.unchanged,G=(e,t)=>e&&Pe(e,H,g)||t,D=JSON.parse(JSON.stringify(a.ribbons));let j=!1,z=0;const ee=new Set,te=e=>{if(w)return ce.slice().reverse();const t=pe.exec(e),o=t&&t[2]!=="{!EntityLogicalName}"?t[1]:L;return[o,...fe.filter(s=>s!==o),"Application"]},F=(e,t)=>{w&&e!=="Application"?$.push(`${t} is on the table's ribbon (${e}), not the application ribbon: the change is published with the table.`):!w&&e==="Application"&&$.push(`${t} was found only on the application ribbon: the change is published to the application ribbon and affects every table.`)},oe=[],E=(e,t)=>{e&&e!==t&&oe.push(e)},_=e=>{for(const t of te(e))for(const o of D[t].tabs){const s=o.groups.find(n=>n.id===e);if(s)return{location:t,tab:o,group:s}}},P=e=>{for(const t of te(e)){const o=D[t].tabs.find(s=>s.id===e);if(o)return{location:t,tab:o}}},U=e=>{for(const t of te(e)){const o=[];for(const s of D[t].tabs)for(const n of s.groups)for(const u of n.buttons)u.id===e&&o.push({group:n,button:u});if(o.length>0)return{location:t,found:o}}},W=(e,t)=>{const o=pe.exec(t);let s="it isn't in the loaded ribbon";o&&o[2]!=="{!EntityLogicalName}"&&c&&o[2]!==c?s=`it belongs to the ${o[2]} table, but ${c} is loaded`:(o?.[2]==="{!EntityLogicalName}"||t.startsWith("Mscrm.Global"))&&(s="it belongs to the application ribbon, which isn't loaded with it"),r.push(`${e}: Location "${t}" not found — ${s}.`)},je=O(A.querySelector(":scope > RuleDefinitions > TabDisplayRules")).map(e=>R.serializeToString(e)).join(""),ne=e=>Te(`<RibbonDiffXml><UI><Ribbon><Tabs>${e}</Tabs></Ribbon></UI><RuleDefinitions><TabDisplayRules>${je}</TabDisplayRules></RuleDefinitions></RibbonDiffXml>`,a.activeLocation,c,H).ribbon.tabs[0],J=e=>R.serializeToString(e),ge=e=>ne(`<Tab Id="${Le}"><Groups><Group Id="${st}"><Controls>${J(e)}</Controls></Group></Groups></Tab>`)?.groups[0]?.buttons.find(t=>t.id===e.getAttribute("Id")),ye=e=>{const t=e.source;t&&(e.label=G(t.labelToken,e.id),t.tooltipTitleToken&&(e.tooltipTitle=G(t.tooltipTitleToken,"")),t.tooltipBodyToken&&(e.tooltipBody=G(t.tooltipBodyToken,"")))},Y=e=>{for(const t of e.source?.xml?[e.source.xml]:Object.values(e.source?.attributes??{}))for(const[,o]of t.matchAll(me))H.some(s=>s.id===o)||r.push(`${e.id}: references label ${o}, which neither the XML nor the loaded ribbon defines — add its <LocLabel> or the publish will fail.`)},$e=e=>({titleToken:e.getAttribute("Title")??void 0,attributes:it(e)}),xe=(e,t)=>(_e(e,{origin:"unmanaged"}),e.hidden=!1,t!==void 0&&!e.source?.attributes.Sequence&&(e.sequence=t),ye(e),Y(e),e),se=e=>r.push(`${e}: flyout / split buttons and their menus can't be imported yet (#27).`),Ne=(e,t)=>{const o=new Set(Array.from(e.querySelectorAll("Menu *")).map(n=>n.getAttribute("Id")).filter(n=>!!n)),s=[];for(const n of t?.buttons??[])o.has(n.id)||(ue.has(n.kind)?se(n.id):s.push(xe(n)));return s},K=(e,t)=>{const o=e.findIndex(s=>s.sequence>t.sequence);e.splice(o<0?e.length:o,0,t)},Ae=(e,t,o)=>{const s=U(e),n=ge(t);if(!s||!n)return!1;ye(n),Y(n),F(s.location,e);for(const{group:u,button:i}of s.found){if(n.kind!==i.kind)return r.push(`${e}: changing a <${t.tagName}> into another kind of control isn't supported.`),!0;if(ue.has(i.kind))return se(e),!0;const p=JSON.parse(JSON.stringify(i));Object.assign(i,{label:n.label,tooltipTitle:n.tooltipTitle,tooltipBody:n.tooltipBody,icon:n.icon,image16:n.image16,image32:n.image32,commandId:n.commandId,templateAlias:n.templateAlias||i.templateAlias,source:structuredClone(n.source)});const h=n.source?.attributes.Sequence?n.sequence:o;h!==void 0&&h!==i.sequence&&(i.origin==="unmanaged"?(u.buttons.splice(u.buttons.indexOf(i),1),i.sequence=h,K(u.buttons,i)):r.push(`${e}: Sequence ${h} not applied — only your own buttons can be re-ordered.`)),Fe(p,i)||p.sequence!==i.sequence?(j=!0,y.push(`Updated ${i.label} (${e}) on ${s.location}`),n.templateAlias||$.push(`${e}: the override has no TemplateAlias — ${i.templateAlias} from the loaded control is kept.`)):(Object.assign(i,p),ve(p.source?.attributes,n.source?.attributes)?z++:r.push(`${e}: the override only changes attributes CBS doesn't publish yet (label, tooltip, icon, command and template alias are).`))}return!0},Se=(e,t,o,s)=>{const n=t.getAttribute("Id");if(!n)return r.push(`CustomAction ${e.getAttribute("Id")}: the control has no Id.`);const u=U(n);if(u){u.found.some(h=>h.group.id===o)||r.push(`${n}: already in group ${u.found[0].group.id} — updated there, not moved to ${o}.`),Ae(n,t,s)&&E(e.getAttribute("Id"),`${n}.Override.CustomAction`);return}const i=_(o);if(!i)return W(`${n}`,e.getAttribute("Location")??"");const p=ge(t);if(!p)return r.push(`${n}: couldn't read the <${t.tagName}>.`);if(ue.has(p.kind))return se(n);K(i.group.buttons,xe(p,s)),F(i.location,n),E(e.getAttribute("Id"),`${n}.CustomAction`),j=!0,y.push(`Added ${p.label} (${n}) to ${i.group.id} on ${i.location}`)},Ce=(e,t)=>{const o=ne(`<Tab Id="${Le}"><Groups>${J(e)}</Groups></Tab>`)?.groups[0];if(!o)return;const s=$e(e);return Y({id:o.id,source:s}),{...o,label:G(s.titleToken,o.id),source:s,sequence:e.getAttribute("Sequence")===null?t??o.sequence:o.sequence,buttons:Ne(e,o)}},Ee=(e,t,o,s)=>{const n=t.getAttribute("Id");if(!n)return r.push(`CustomAction ${e.getAttribute("Id")}: the group has no Id.`);if(_(n)){r.push(`Group ${n} already exists — it was left as is (re-titling groups isn't supported).`);for(const h of O(t.querySelector(":scope > Controls")))de.has(h.tagName)?Se(e,h,n,void 0):He(ze[h.tagName])&&r.push(`${h.getAttribute("Id")??"(no Id)"}: adding a <${h.tagName}> to an existing group isn't supported — Command Bar Studio shows it read-only.`);return}const i=P(o);if(!i)return W(`Group ${n}`,e.getAttribute("Location")??"");const p=Ce(t,s);if(!p)return r.push(`Group ${n}: couldn't read the <Group>.`);K(i.tab.groups,p),F(i.location,n),E(e.getAttribute("Id"),`${n}.CustomAction`),j=!0,y.push(`Added group ${p.label} (${n}) with ${p.buttons.length} control(s) to ${o} on ${i.location}`)},Oe=(e,t,o)=>{const s=t.getAttribute("Id");if(!s)return r.push(`CustomAction ${e.getAttribute("Id")}: the tab has no Id.`);if(P(s))return r.push(`Tab ${s} already exists — it was left as is.`);const n=ne(J(t));if(!n)return r.push(`Tab ${s}: couldn't read the <Tab>.`);const u=n.tabDisplayRules.flatMap(T=>T.rules.map(we=>we.kind==="EntityRule"?at(we.context):void 0)),i=w?"Application":u.find(T=>!!T)??pe.exec(s)?.[1]??L,h=Array.from(t.querySelectorAll(":scope > Groups > Group")).map(T=>Ce(T,void 0)).filter(T=>!!T),f=$e(t);Y({id:s,source:f});const b={...n,label:G(f.titleToken,s),source:f,sequence:t.getAttribute("Sequence")===null?o??n.sequence:n.sequence,groups:h};K(D[i].tabs,b),E(e.getAttribute("Id"),`${s}.CustomAction`),b.commandId&&(ee.add(b.commandId),d.out.some(T=>T.id===b.commandId)||(d.out.push({id:b.commandId,enableRules:[],displayRules:[],actions:[]}),d.changedIds.push(b.commandId),$.push(`Tab ${s}: its Command ${b.commandId} has no CommandDefinition in the XML — an empty one was added.`))),j=!0,y.push(`Added tab ${b.label} (${s}) with ${h.length} group(s) to ${i}`),t.querySelector(":scope > Scaling > Scale")&&r.push(`Tab ${s}: its <Scale> steps weren't imported — CBS writes a default MaxSize for each group.`)},Ge=e=>{const t=e.getAttribute("Location")??"",o=U(t);if(o){const s=o.found.filter(n=>!n.button.hidden);for(const n of s)n.button.hidden=!0;s.length>0?(F(o.location,t),E(e.getAttribute("HideActionId"),`${t}.HideAction`),j=!0,y.push(`Hid ${s[0].button.label} (${t}) on ${o.location}`)):z++;return}if(_(t)||P(t))return r.push(`Hiding ${t}: hiding whole groups or tabs isn't supported yet — hide their buttons.`);r.push(`Hiding ${t}: not found in the loaded ribbon (it may belong to another table, or already be hidden by your customizations).`)},Xe=e=>{const t=e.getAttribute("Id")??"(no Id)",o=e.getAttribute("Location")??"",s=e.getAttribute("Sequence"),n=s===null?void 0:parseInt(s,10),u=O(e.querySelector(":scope > CommandUIDefinition"))[0];if(!u)return r.push(`CustomAction ${t}: no <CommandUIDefinition> content.`);const i=u.tagName;if(o.endsWith(Ie)){const p=o.slice(0,-Ie.length);return p.endsWith(".Controls")&&de.has(i)?Se(e,u,p.slice(0,-9),n):p.endsWith(".Groups")&&i==="Group"?Ee(e,u,p.slice(0,-7),n):p==="Mscrm.Tabs"&&i==="Tab"?Oe(e,u,n):p.endsWith(".Scaling")&&(i==="MaxSize"||i==="Scale")?r.push(`CustomAction ${t}: <${i}> scaling isn't imported — CBS writes a default MaxSize for each new group.`):r.push(`CustomAction ${t}: a <${i}> at "${o}" isn't supported.`)}if(de.has(i)&&u.getAttribute("Id")===o){if(Ae(o,u,n)){E(t,`${o}.Override.CustomAction`);return}return W(`Override ${t}`,o)}return U(o)||_(o)||P(o)?r.push(`CustomAction ${t}: replacing ${o} with a <${i}> isn't supported — only overriding a control with the same Id is.`):W(`CustomAction ${t}`,o)},Me=O(A.querySelector(":scope > CustomActions"));for(const e of Me)e.tagName==="CustomAction"?Xe(e):e.tagName==="HideCustomAction"?Ge(e):r.push(`<${e.tagName}> in CustomActions isn't supported.`);const V=new Set;for(const e of ce)for(const t of D[e].tabs)for(const o of t.groups)for(const s of o.buttons)for(const n of Be(s))V.add(n);for(const e of ee)V.add(e);const ie=new Set,re=new Set;for(const e of d.out)if(V.has(e.id)){e.enableRules.forEach(t=>ie.add(t)),e.displayRules.forEach(t=>re.add(t));for(const t of e.rawRuleRefs??[]){const o=nt.exec(t.xml);o&&(o[1]==="EnableRule"?ie:re).add(o[2])}}const Q=(e,t,o,s)=>{for(const n of e)t.has(n)||r.push(`${o} ${n} was imported but ${s}, so it won't be published.`)};Q(d.changedIds,V,"Command","no button on the loaded ribbon uses it"),Q(C.changedIds,ie,"Enable rule","no command a button uses references it"),Q(k.changedIds,re,"Display rule","no command a button uses references it");const Re=new Set(Array.from(J(A).matchAll(me),e=>e[1]));for(const e of ce)for(const t of D[e].tabs)for(const o of t.groups)for(const s of o.buttons)for(const n of Object.values(s.source?.attributes??{}))for(const u of n.matchAll(me))Re.add(u[1]);Q(B.changedIds,Re,"Label","nothing references it");const qe=Array.from(A.querySelectorAll(":scope > RuleDefinitions > TabDisplayRules > TabDisplayRule"));for(const e of qe){const t=e.getAttribute("TabCommand")??"";ee.has(t)||r.push(`TabDisplayRule for ${t}: only the display rules of tabs this import adds are imported.`);const o=O(e).filter(s=>s.tagName!=="EntityRule"&&s.tagName!=="PageRule");o.length>0&&r.push(`TabDisplayRule for ${t}: ${o.map(s=>`<${s.tagName}>`).join(", ")} not imported — only EntityRule and PageRule are supported.`)}oe.length>0&&$.push(`Ids normalised: CBS publishes CustomAction / HideCustomAction ids as {control}.CustomAction, {control}.Override.CustomAction and {control}.HideAction, so ${oe.join(", ")} will be written under those ids.`),be+z>0&&y.push(`${be+z} control(s) / definition(s) were already up to date`);const ke=j||d.changedIds.length+C.changedIds.length+k.changedIds.length+B.changedIds.length>0;return{ribbons:j?D:a.ribbons,commands:d.out,enableRules:C.out,displayRules:k.out,locLabels:H,applied:y,notApplied:r,notes:$,changed:ke}}function ct(a,g){const c=Ue.getState(),m=lt({xml:a,ribbons:c.ribbons,commands:c.commands,enableRules:c.enableRules,displayRules:c.displayRules,locLabels:c.locLabels,entityLogicalName:Je.getState().activeEntity?.logicalName??c.ribbons.HomepageGrid.entityLogicalName,activeLocation:We.getState().location,languageCode:c.baseLanguageCode});return g&&m.changed&&c.applyImport(m,`${m.applied.length} change(s)`),m}const he=({items:a})=>l.jsx("ul",{style:{margin:"4px 0 0",paddingLeft:"20px",maxHeight:"160px",overflowY:"auto"},children:a.map((g,c)=>l.jsx("li",{children:l.jsx(De,{size:200,children:g})},c))}),$t=()=>{const a=ae(d=>d.importXmlOpen),g=ae(d=>d.importXmlSeed),c=ae(d=>d.closeImportXml),[m,S]=X.useState(""),[A,R]=X.useState([]),[I,y]=X.useState(null),[r,$]=X.useState("");X.useEffect(()=>{a&&(S(g),R([]),y(null),$(""))},[a,g]);const N=d=>{S(d),I?.imported||y(null)},w=()=>{const d=Ye(m);return R(d),d.every(C=>C.severity==="warning")},L=d=>{if(w()){$("");try{y({result:ct(m,d),imported:d})}catch(C){y(null),$(C instanceof Error?C.message:String(C))}}},v=I?.imported===!0,x=I?.result;return l.jsx(Ve,{open:a,onOpenChange:()=>c(),children:l.jsxs(Qe,{style:{maxWidth:"960px",width:"92vw",height:"80vh",maxHeight:"860px"},children:[l.jsx(Ze,{children:"Import RibbonDiffXml"}),l.jsxs(et,{style:{height:"100%",display:"flex",flexDirection:"column"},children:[l.jsxs(tt,{style:{flex:1,minHeight:0,display:"flex",flexDirection:"column",gap:"8px"},children:[l.jsx(De,{size:200,children:"Paste a RibbonDiffXml (for example from Ribbon Workbench or a solution's customizations.xml — the loaded table's part is used, or the application ribbon's when that is on screen). Commands, rules and labels are added or replaced by id; new buttons, groups and tabs are added to the loaded ribbon; overrides and hides edit the existing controls. Everything imported becomes one unpublished change, which Undo takes back as a whole."}),l.jsx("div",{style:{flex:1,minHeight:0},children:l.jsx(Ke,{language:"xml",value:m,onChange:N,readOnly:v,height:"100%",options:{wordWrap:"on",lineNumbers:"on",padding:{top:8}}})}),A.length>0&&l.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"4px"},children:A.map((d,C)=>l.jsx(M,{intent:d.severity==="warning"?"warning":"error",children:l.jsxs(q,{children:[d.message,d.lineHint?` (${d.lineHint})`:""]})},C))}),r&&l.jsx(M,{intent:"error",children:l.jsx(q,{children:r})}),x&&l.jsx(M,{intent:x.changed?"success":"info",layout:"multiline",children:l.jsxs(q,{children:[l.jsx(le,{children:v?x.changed?"Imported — review the changes, then publish":"Nothing to import — the session already has all of it":"Preview — nothing has changed yet"}),x.applied.length>0&&l.jsx(he,{items:x.applied})]})}),x&&x.notes.length>0&&l.jsx(M,{intent:"info",layout:"multiline",children:l.jsxs(q,{children:[l.jsx(le,{children:"Good to know"}),l.jsx(he,{items:x.notes})]})}),x&&x.notApplied.length>0&&l.jsx(M,{intent:"warning",layout:"multiline",children:l.jsxs(q,{children:[l.jsx(le,{children:v?"Not imported / won't be published":"Can't be imported / won't be published"}),l.jsx(he,{items:x.notApplied})]})})]}),l.jsx(ot,{children:v?l.jsx(Z,{appearance:"primary",onClick:c,children:"Close"}):l.jsxs(l.Fragment,{children:[l.jsx(Z,{appearance:"secondary",onClick:c,children:"Cancel"}),l.jsx(Z,{appearance:"secondary",onClick:()=>L(!1),disabled:!m.trim(),children:"Preview"}),l.jsx(Z,{appearance:"primary",onClick:()=>L(!0),disabled:!m.trim(),children:"Import"})]})})]})]})})};export{$t as ImportXmlModal,$t as default};
@@ -0,0 +1 @@
1
+ import{z as a,h as M,cq as P,co as q,y as G,cB as J}from"./fluent-icons-DxKNRZ1A.js";import{R as N,a as B}from"./monaco-Bx8A1Vm1.js";import{a as L,u as m,e as V,a9 as Y}from"./index-Bu7BlRFk.js";import{D as Q,h as Z,j as ee,i as ae,aa as te,c as $,B as x,k as le,I as oe,T as H,t as i,m as F,l as ne}from"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";const f={1033:{name:"English (US)",flag:"🇺🇸"},1031:{name:"German",flag:"🇩🇪"},1034:{name:"Spanish",flag:"🇪🇸"},1036:{name:"French",flag:"🇫🇷"},1040:{name:"Italian",flag:"🇮🇹"},1041:{name:"Japanese",flag:"🇯🇵"},1042:{name:"Korean",flag:"🇰🇷"},1043:{name:"Dutch",flag:"🇳🇱"},1044:{name:"Norwegian",flag:"🇳🇴"},1045:{name:"Polish",flag:"🇵🇱"},1046:{name:"Portuguese (Brazil)",flag:"🇧🇷"},1049:{name:"Russian",flag:"🇷🇺"},1053:{name:"Swedish",flag:"🇸🇪"},1054:{name:"Thai",flag:"🇹🇭"},1055:{name:"Turkish",flag:"🇹🇷"},1057:{name:"Indonesian",flag:"🇮🇩"},1058:{name:"Ukrainian",flag:"🇺🇦"},1066:{name:"Vietnamese",flag:"🇻🇳"},2052:{name:"Chinese (Simplified)",flag:"🇨🇳"},3082:{name:"Spanish (Spain)",flag:"🇪🇸"}},ie=Object.keys(f).map(Number),se=G({surface:{width:"760px",maxWidth:"95vw",maxHeight:"80vh"},body:{display:"flex",flexDirection:"column",gap:i.spacingHorizontalM,overflowY:"auto"},chipRow:{display:"flex",flexWrap:"wrap",gap:i.spacingHorizontalXS,alignItems:"center"},chip:{cursor:"pointer",userSelect:"none"},table:{width:"100%",borderCollapse:"collapse"},th:{textAlign:"left",fontSize:i.fontSizeBase100,fontWeight:i.fontWeightSemibold,color:i.colorNeutralForeground3,paddingBottom:i.spacingHorizontalXS,borderBottom:`1px solid ${i.colorNeutralStroke2}`},td:{verticalAlign:"top",paddingTop:i.spacingHorizontalXS,paddingBottom:i.spacingHorizontalXS,paddingRight:i.spacingHorizontalS,borderBottom:`1px solid ${i.colorNeutralStroke3}`},langCell:{whiteSpace:"nowrap",width:"160px"},actionCell:{width:"40px"},insertBreakBtn:{fontSize:i.fontSizeBase100,height:"20px",minWidth:"unset",padding:`0 ${i.spacingHorizontalXS}`},noteBar:{backgroundColor:i.colorNeutralBackground3,borderRadius:i.borderRadiusMedium,padding:`${i.spacingHorizontalXS} ${i.spacingHorizontalS}`,fontSize:i.fontSizeBase100,color:i.colorNeutralForeground3}}),he=()=>{const n=se(),p=L(e=>e.localizationEditorOpen),c=L(e=>e.localizationEditorButtonId),u=L(e=>e.closeLocalizationEditor),h=m(e=>e.locLabels),v=m(e=>e.upsertLocLabel),W=m(e=>e.batch),k=m(e=>e.ribbons),d=m(e=>e.baseLanguageCode),X=N.useMemo(()=>{if(c){for(const e of Object.values(k))for(const t of e.tabs)for(const l of t.groups)for(const s of V(l))if(s.id===c)return s.source}},[k,c]),y=c?Y(c,X):null,b=y?.label??null,j=y?.tooltipTitle??null,S=y?.tooltipBody??null,I=B.useCallback(()=>{const e=h.find(o=>o.id===b),t=h.find(o=>o.id===j),l=h.find(o=>o.id===S),s=new Set([d]);return e?.titles.forEach(o=>s.add(o.languageCode)),t?.titles.forEach(o=>s.add(o.languageCode)),l?.titles.forEach(o=>s.add(o.languageCode)),Array.from(s).sort((o,r)=>o===d?-1:r===d?1:o-r).map(o=>({lcid:o,label:e?.titles.find(r=>r.languageCode===o)?.description??"",tooltipTitle:t?.titles.find(r=>r.languageCode===o)?.description??"",tooltipBody:l?.titles.find(r=>r.languageCode===o)?.description??""}))},[h,b,j,S,d]),[g,C]=B.useState([]),[R,w]=B.useState("");N.useEffect(()=>{p&&C(I())},[p,I]);const z=(e,t,l)=>{C(s=>s.map(o=>o.lcid===e?{...o,[t]:l}:o))},T=(e,t,l)=>{if(!l)return;const s=l.selectionStart??l.value.length,o=l.selectionEnd??l.value.length,r=g.find(K=>K.lcid===e)?.[t]??"",_=r.slice(0,s)+"​​"+r.slice(o);z(e,t,_)},D=()=>{const e=parseInt(R,10);!e||g.find(t=>t.lcid===e)||(C(t=>[...t,{lcid:e,label:"",tooltipTitle:"",tooltipBody:""}]),w(""))},E=e=>{e!==d&&C(t=>t.filter(l=>l.lcid!==e))},O=()=>{if(!b||!j||!S)return;const e=t=>g.filter(l=>l[t]).map(l=>({languageCode:l.lcid,description:l[t]}));W(()=>{e("label").length>0&&v({id:b,titles:e("label")}),e("tooltipTitle").length>0&&v({id:j,titles:e("tooltipTitle")}),e("tooltipBody").length>0&&v({id:S,titles:e("tooltipBody")})}),u()},U=g.find(e=>e.lcid===d);return a.jsx(Q,{open:p,onOpenChange:(e,t)=>!t.open&&u(),children:a.jsx(Z,{className:n.surface,children:a.jsxs(ee,{children:[a.jsxs(ae,{action:a.jsx(x,{appearance:"subtle",icon:a.jsx(M,{}),onClick:u,"aria-label":"Close"}),children:[a.jsxs(te,{children:["Translations — ",U?.label||c||"Button"]}),a.jsxs($,{appearance:"tint",size:"small",style:{marginLeft:8},children:[g.length," language",g.length!==1?"s":""]})]}),a.jsxs(le,{className:n.body,children:[a.jsxs("div",{className:n.chipRow,children:[g.map(e=>{const t=f[e.lcid];return a.jsxs($,{className:n.chip,appearance:e.label?"filled":"outline",color:e.label?"brand":"informative",size:"medium",children:[t?.flag??"🌐"," ",t?.name??`LCID ${e.lcid}`,e.lcid!==d&&a.jsx("span",{style:{marginLeft:4,cursor:"pointer",opacity:.7},onClick:()=>E(e.lcid),"aria-label":`Remove ${t?.name}`,children:"×"})]},e.lcid)}),a.jsxs("div",{style:{display:"flex",gap:4,alignItems:"center"},children:[a.jsx(oe,{size:"small",style:{width:"180px"},placeholder:"LCID or language…",value:R,onChange:(e,t)=>w(t.value),list:"lcid-list",onKeyDown:e=>e.key==="Enter"&&D()}),a.jsx("datalist",{id:"lcid-list",children:ie.filter(e=>!g.find(t=>t.lcid===e)).map(e=>a.jsxs("option",{value:String(e),children:[f[e]?.flag," ",f[e]?.name," (",e,")"]},e))}),a.jsx(x,{size:"small",appearance:"subtle",icon:a.jsx(P,{}),onClick:D,"aria-label":"Add language"})]})]}),a.jsxs("div",{className:n.noteBar,children:["💡 LCID ",d," (",f[d]?.name??"base language",`) is the organisation's base language and cannot be removed. Use "Insert ​​" to force a line break in long labels.`]}),a.jsxs("table",{className:n.table,children:[a.jsx("thead",{children:a.jsxs("tr",{children:[a.jsx("th",{className:n.th,style:{width:"160px"},children:"Language"}),a.jsx("th",{className:n.th,children:"Label"}),a.jsx("th",{className:n.th,children:"Tooltip title"}),a.jsx("th",{className:n.th,children:"Tooltip body"}),a.jsx("th",{className:n.th,style:{width:"40px"}})]})}),a.jsx("tbody",{children:g.map(e=>{const t=f[e.lcid];return a.jsxs("tr",{children:[a.jsxs("td",{className:`${n.td} ${n.langCell}`,children:[a.jsxs(H,{size:200,children:[t?.flag??"🌐"," ",t?.name??`LCID ${e.lcid}`]}),a.jsx("br",{}),a.jsx(H,{size:100,style:{color:i.colorNeutralForeground3},children:e.lcid})]}),a.jsx("td",{className:n.td,children:a.jsx(A,{value:e.label,onChange:l=>z(e.lcid,"label",l),onInsertBreak:l=>T(e.lcid,"label",l)})}),a.jsx("td",{className:n.td,children:a.jsx(A,{value:e.tooltipTitle,onChange:l=>z(e.lcid,"tooltipTitle",l),onInsertBreak:l=>T(e.lcid,"tooltipTitle",l)})}),a.jsx("td",{className:n.td,children:a.jsx(re,{value:e.tooltipBody,onChange:l=>z(e.lcid,"tooltipBody",l)})}),a.jsx("td",{className:`${n.td} ${n.actionCell}`,children:e.lcid!==d&&a.jsx(F,{content:"Remove this language",relationship:"label",children:a.jsx(x,{appearance:"subtle",size:"small",icon:a.jsx(q,{}),onClick:()=>E(e.lcid),"aria-label":"Remove language"})})})]},e.lcid)})})]})]}),a.jsxs(ne,{children:[a.jsx(x,{appearance:"secondary",onClick:u,children:"Cancel"}),a.jsx(x,{appearance:"primary",onClick:O,children:"Save translations"})]})]})})})};function A({value:n,onChange:p,onInsertBreak:c}){const u=N.useRef(null);return a.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:2},children:[a.jsx("input",{ref:u,style:{width:"100%",fontFamily:"inherit",fontSize:13,padding:"3px 6px",border:"1px solid var(--colorNeutralStroke1)",borderRadius:4,boxSizing:"border-box"},value:n,onChange:h=>p(h.target.value)}),a.jsx(F,{content:"Insert Dataverse line break (​​)",relationship:"label",children:a.jsxs("button",{type:"button",onClick:()=>c(u.current),style:{fontSize:11,border:"none",background:"none",color:"var(--colorNeutralForeground3)",cursor:"pointer",padding:0,textAlign:"left",display:"flex",alignItems:"center",gap:2},children:[a.jsx(J,{fontSize:12})," Insert ⏎"]})})]})}function re({value:n,onChange:p}){return a.jsx("textarea",{style:{width:"100%",fontFamily:"inherit",fontSize:13,padding:"3px 6px",border:"1px solid var(--colorNeutralStroke1)",borderRadius:4,boxSizing:"border-box",resize:"vertical",minHeight:"42px"},value:n,onChange:c=>p(c.target.value),rows:2})}export{he as LocalizationEditor,he as default};
@@ -0,0 +1,2 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./monaco-Bx8A1Vm1.js","./monaco-Dprb6f6S.css"])))=>i.map(i=>d[i]);
2
+ import{a as l,R as f,_ as h}from"./monaco-Bx8A1Vm1.js";import{z as t}from"./fluent-icons-DxKNRZ1A.js";import{a as u}from"./index-Bu7BlRFk.js";import{a5 as x}from"./fluent-ui-D7EtYwEg.js";const _=f.lazy(()=>h(()=>import("./monaco-Bx8A1Vm1.js").then(o=>o.i),__vite__mapDeps([0,1]),import.meta.url)),y=({language:o,value:r,onChange:a,readOnly:s=!1,height:i="100%",options:m={},onMount:n})=>{const d=u(e=>e.themeMode)==="dark"?"vs-dark":"vs",c={readOnly:s,minimap:{enabled:!1},wordWrap:o==="xml"?"on":"off",scrollBeyondLastLine:!1,automaticLayout:!0,...m},p=e=>{a&&e!==void 0&&a(e)};return t.jsx(l.Suspense,{fallback:t.jsx(x,{size:"medium",label:"Loading editor…"}),children:t.jsx(_,{height:i,language:o,value:r,theme:d,options:c,onChange:p,onMount:n})})};export{y as M};
@@ -0,0 +1 @@
1
+ import{z as e}from"./fluent-icons-DxKNRZ1A.js";import{a as S}from"./monaco-Bx8A1Vm1.js";import{a as B,u as i,X as b,b as p,e as O,Y as z,c as G}from"./index-Bu7BlRFk.js";import{D as K,h as Y,i as _,j as q,k as M,F as C,I as U,S as X,T as $,l as H,B as I}from"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";const tt=()=>{const n=B(t=>t.newButtonGroupId),l=B(t=>t.closeNewButton),v=i(t=>t.createButton),w=i(t=>t.upsertCommand),y=i(t=>t.batch),N=b(t=>t.selectButtonInContext),D=p(t=>t.publisherPrefix),E=p(t=>t.activeSolution),s=b(t=>t.location),T=b(t=>t.tabId),k=p(t=>t.activeEntity),R=n!==null,[r,m]=S.useState("New Button"),[h,x]=S.useState("button"),F=()=>{if(!n||!s)return;const t=E?.publisherPrefix?.trim()||D?.trim()||"new",a=k?.logicalName??"global",c=i.getState().ribbons,L=i.getState().commands,f=new Set(L.map(o=>o.id));for(const o of Object.values(c))for(const d of o.tabs)for(const P of d.groups)for(const A of O(P))f.add(A.id);const{id:g,commandId:j}=z(t,a,s,r,f),u=c[s].tabs.find(o=>o.groups.some(d=>d.id===n))?.id??T;if(!c[s].tabs.some(o=>o.id===u)){G.getState().logError("canvas",`Could not add the button: group ${n} was not found.`),l();return}y(()=>{v({location:s,tabId:u,groupId:n,button:{id:g,label:r,kind:h,templateAlias:"o1",commandId:j,hidden:!1,oob:!1,custom:!0,managed:!1}}),w({id:j,enableRules:[],displayRules:[],actions:[]})}),N(s,u,n,g),m("New Button"),x("button"),l()};return e.jsx(K,{open:R,onOpenChange:()=>l(),children:e.jsxs(Y,{children:[e.jsx(_,{children:"New button"}),e.jsxs(q,{children:[e.jsxs(M,{children:[e.jsx(C,{label:"Label",required:!0,children:e.jsx(U,{value:r,onChange:(t,a)=>m(a.value),autoFocus:!0})}),e.jsx(C,{label:"Kind",children:e.jsxs(X,{value:h,onChange:(t,a)=>x(a.value),children:[e.jsx("option",{value:"button",children:"Button"}),e.jsx("option",{value:"flyout",children:"Flyout anchor"}),e.jsx("option",{value:"splitButton",children:"Split button"})]})}),e.jsx($,{size:200,style:{display:"block",marginTop:"8px"},children:"A command definition will be created automatically. You can edit it in the Command Editor."})]}),e.jsxs(H,{children:[e.jsx(I,{appearance:"secondary",onClick:l,children:"Cancel"}),e.jsx(I,{appearance:"primary",onClick:F,disabled:!r.trim(),children:"Create button"})]})]})]})})};export{tt as NewButtonModal,tt as default};
@@ -0,0 +1 @@
1
+ import{z as e}from"./fluent-icons-DxKNRZ1A.js";import{a as u}from"./monaco-Bx8A1Vm1.js";import{a as p,u as g,X as d}from"./index-Bu7BlRFk.js";import{D as v,h as y,i as w,j as G,k as C,F as x,I as F,S as L,T as S,l as f,B as h}from"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";const z=()=>{const b=p(o=>o.newGroupOpen),a=p(o=>o.closeNewGroup),j=g(o=>o.createGroup),s=d(o=>o.location),n=d(o=>o.tabId),[t,r]=u.useState("New Group"),[i,c]=u.useState("Flexible2"),m=()=>{!s||!n||(j({location:s,tabId:n,group:{label:t,template:i,buttons:[]}}),r("New Group"),c("Flexible2"),a())};return e.jsx(v,{open:b,onOpenChange:()=>a(),children:e.jsxs(y,{children:[e.jsx(w,{children:"New group"}),e.jsxs(G,{children:[e.jsxs(C,{children:[e.jsx(x,{label:"Label",required:!0,children:e.jsx(F,{value:t,onChange:(o,l)=>r(l.value),autoFocus:!0})}),e.jsx(x,{label:"Group template",children:e.jsxs(L,{value:i,onChange:(o,l)=>c(l.value),children:[e.jsx("option",{value:"Flexible2",children:"Flexible2 (recommended)"}),e.jsx("option",{value:"Flexible",children:"Flexible"}),e.jsx("option",{value:"Layout2",children:"Layout2"}),e.jsx("option",{value:"Layout3",children:"Layout3"}),e.jsx("option",{value:"Layout4",children:"Layout4"})]})}),e.jsx(S,{size:200,style:{display:"block",marginTop:"8px"},children:"The group template defines how buttons scale when the ribbon is resized."})]}),e.jsxs(f,{children:[e.jsx(h,{appearance:"secondary",onClick:a,children:"Cancel"}),e.jsx(h,{appearance:"primary",onClick:m,disabled:!t.trim(),children:"Create group"})]})]})]})})};export{z as NewGroupModal,z as default};
@@ -0,0 +1 @@
1
+ import{z as e,h as B,y as F}from"./fluent-icons-DxKNRZ1A.js";import{a as S,R as _}from"./monaco-Bx8A1Vm1.js";import{X as E,u as c,b as N,a as C,Z as O,_ as $,$ as L,a0 as H}from"./index-Bu7BlRFk.js";import{D as G,h as U,j as X,i as Z,aa as q,B as h,k as P,M as D,e as I,T as d,F as v,I as w,t as s,l as W}from"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";const Y={HomepageGrid:"home grid",Form:"form",SubGrid:"sub-grid",Application:""},J=F({surface:{width:"480px",maxWidth:"95vw"},body:{display:"flex",flexDirection:"column",gap:s.spacingHorizontalM},hint:{fontFamily:s.fontFamilyMonospace,fontSize:s.fontSizeBase100,color:s.colorNeutralForeground3,backgroundColor:s.colorNeutralBackground3,padding:`${s.spacingHorizontalXS} ${s.spacingHorizontalS}`,borderRadius:s.borderRadiusMedium}}),se=()=>{const b=J(),[t,p]=S.useState("New Tab"),[g,x]=S.useState(""),o=E(a=>a.location),R=c(a=>a.createTab),u=c(a=>a.ribbons),m=c(a=>a.baseline),j=c(a=>a.layers),z=N(a=>a.activeEntity);N(a=>a.publisherPrefix);const A=C(a=>a.newTabOpen),l=C(a=>a.closeNewTab),y=_.useMemo(()=>O({baseline:m,layers:j},u),[m,j,u]),M=o==="Application"?"global":z?.logicalName??u[o].entityLogicalName,T=$(M,`${o}.${t}`,"Tab",y),n=g.trim(),r=n?L(n)??(/[^a-zA-Z0-9._]/.test(n)?"Use letters, digits, dots and underscores only":y.has(n)?"This ID is already used":null):null,f=n||T,k=()=>{r||(R(o,{id:f,label:t,tabDisplayRules:[],groups:[]}),p("New Tab"),x(""),l())};return e.jsx(G,{open:A,onOpenChange:(a,i)=>!i.open&&l(),children:e.jsx(U,{className:b.surface,children:e.jsxs(X,{children:[e.jsx(Z,{action:e.jsx(h,{appearance:"subtle",icon:e.jsx(B,{}),onClick:l,"aria-label":"Close"}),children:e.jsx(q,{children:"Add Tab"})}),e.jsxs(P,{className:b.body,children:[e.jsx(D,{intent:"info",children:e.jsx(I,{children:e.jsx(d,{size:200,children:o==="Application"?"A tab is shown only where a Tab Display Rule allows it. Add one in Tab rules before publishing.":`The tab gets a Tab Display Rule for this table's ${Y[o]}. You can change it in Tab rules.`})})}),e.jsx(D,{intent:"info",children:e.jsx(I,{children:e.jsx(d,{size:200,children:H})})}),e.jsx(v,{label:"Tab label",required:!0,children:e.jsx(w,{value:t,onChange:(a,i)=>p(i.value),placeholder:"My Tab"})}),e.jsx(v,{label:"Tab ID",hint:"Leave blank to auto-generate from label",validationState:r?"error":"none",validationMessage:r??void 0,children:e.jsx(w,{value:g,onChange:(a,i)=>x(i.value),placeholder:T})}),e.jsxs("div",{children:[e.jsx(d,{size:100,style:{color:s.colorNeutralForeground3},children:"Generated ID:"}),e.jsx("div",{className:b.hint,children:f})]}),e.jsxs(d,{size:200,style:{color:s.colorNeutralForeground3},children:["Location: ",e.jsx("strong",{children:o})]})]}),e.jsxs(W,{children:[e.jsx(h,{appearance:"secondary",onClick:l,children:"Cancel"}),e.jsx(h,{appearance:"primary",disabled:!t.trim()||!!r,onClick:k,children:"Create tab"})]})]})})})};export{se as NewTabModal,se as default};
@@ -0,0 +1 @@
1
+ import{z as e,y as L,h as X,cq as K}from"./fluent-icons-DxKNRZ1A.js";import{a as I,R as te}from"./monaco-Bx8A1Vm1.js";import{a as _,u as $}from"./index-Bu7BlRFk.js";import{R as se,i as oe,a as V}from"./ruleKinds-B9hACGaq.js";import{T as E,t as o,I as y,B as O,c as q,F as s,S as h,am as w,P as Q,b as Y,d as J,ah as ce,ai as ue,aj as de,ak as pe,M as he,e as me,a7 as H}from"./fluent-ui-D7EtYwEg.js";import{C as xe}from"./CrmParameterEditor-BdmP65mF.js";import{f as Z,D as ye,c as ve,S as je,v as ge,g as Re,C as be}from"./dnd-fsSwRnQv.js";import"./crmParameters-rgfZhhzN.js";const fe=L({root:{display:"flex",flexDirection:"column",gap:o.spacingVerticalXS},search:{marginBottom:o.spacingVerticalXS},group:{display:"flex",flexDirection:"column",gap:o.spacingVerticalXXS},groupLabel:{color:o.colorNeutralForeground3,paddingTop:o.spacingVerticalXS},kindButton:{justifyContent:"flex-start",textAlign:"left"}});function Ce(l){switch(l){case"CommandClientTypeRule":return{kind:l,type:"Refresh"};case"CrmClientTypeRule":return{kind:l,type:"Web"};case"FormStateRule":return{kind:l,state:"Existing"};case"FormTypeRule":return{kind:l,type:"Main"};case"SelectionCountRule":return{kind:l,minimum:1};case"EntityRule":return{kind:l};case"CustomRule":return{kind:l,library:"$webresource:",functionName:""};case"ValueRule":return{kind:l,field:"",value:""};case"SkuRule":return{kind:l,sku:"Online"};case"OrRule":return{kind:l,groups:[[{kind:"FormStateRule",state:"Existing"}],[{kind:"FormStateRule",state:"Create"}]]};case"FeatureControlRule":return{kind:l,featureControlBit:"",expectedValue:!0};case"OrganizationSettingRule":return{kind:l,setting:"IsSharepointEnabled"};case"EntityPrivilegeRule":return{kind:l,privilegeType:"Read",privilegeDepth:"Basic"};case"EntityPropertyRule":return{kind:l,propertyName:"IsCustomizable",propertyValue:!0};case"RecordPrivilegeRule":return{kind:l,privilegeType:"Read"};case"RelationshipTypeRule":return{kind:l,appliesTo:"SelectedEntity"};case"MiscellaneousPrivilegeRule":return{kind:l,privilegeName:"ExportToExcel"};case"FormEntityContextRule":return{kind:l,entityName:""};case"PageRule":return{kind:l,address:""};case"CrmOfflineAccessStateRule":return{kind:l,state:"Online"};case"CrmOutlookClientTypeRule":return{kind:l,type:"CrmForOutlook"};case"CrmOutlookClientVersionRule":return{kind:l,major:15,minor:0,build:0,revision:0};case"DeviceTypeRule":return{kind:l,type:"Web"};case"OptionSetRule":return{kind:l,optionSet:"",stateCode:"",objectTypeCode:""};case"OutlookItemTrackingRule":return{kind:l,trackedInCrm:!0};case"OutlookRenderTypeRule":return{kind:l,type:"Web"};case"OutlookVersionRule":return{kind:l,version:"2010"};case"HideForTabletExperienceRule":return{kind:l};case"ReferencingAttributeRequiredRule":return{kind:l};default:return{kind:l}}}const ee=({onSelect:l,container:t,insideOr:d=!1})=>{const p=fe(),[c,f]=I.useState(""),R=se.map(x=>({...x,kinds:x.kinds.filter(m=>{if(t&&!oe(m,t,d)||d&&m==="OrRule")return!1;const C=V[m]??m;return!c||C.toLowerCase().includes(c.toLowerCase())||m.toLowerCase().includes(c.toLowerCase())})})).filter(x=>x.kinds.length>0);return e.jsxs("div",{className:p.root,children:[e.jsx(E,{size:100,style:{color:o.colorNeutralForeground3},children:"Quick action rules are OOB references and should be bound by ID (for example, Mscrm.ShowOnQuickAction), not created as custom step kinds."}),e.jsx(y,{className:p.search,placeholder:"Search rule kinds…",value:c,onChange:(x,m)=>f(m.value)}),R.map(x=>e.jsxs("div",{className:p.group,children:[e.jsx(E,{size:100,weight:"semibold",className:p.groupLabel,children:x.label}),x.kinds.map(m=>e.jsx(O,{appearance:"subtle",className:p.kindButton,onClick:()=>l(Ce(m)),children:V[m]??m},m))]},x.label))]})},Se=L({step:{display:"flex",flexDirection:"column",gap:o.spacingVerticalXS,padding:o.spacingVerticalS,border:`1px solid ${o.colorNeutralStroke2}`,borderRadius:o.borderRadiusMedium,backgroundColor:o.colorNeutralBackground2},header:{display:"flex",alignItems:"center",justifyContent:"space-between"},kindBadge:{flexShrink:0},fields:{display:"flex",flexDirection:"column",gap:o.spacingVerticalXS},row:{display:"flex",gap:o.spacingHorizontalS,alignItems:"flex-end",flexWrap:"wrap"},nested:{display:"flex",flexDirection:"column",gap:o.spacingVerticalXS,paddingLeft:o.spacingHorizontalM,borderLeft:`2px solid ${o.colorBrandStroke2}`},nestedToolbar:{display:"flex",alignItems:"center",gap:o.spacingHorizontalXS},pickerSurface:{minWidth:"300px",maxHeight:"50vh",overflowY:"auto",padding:o.spacingVerticalS}}),G=["Create","Read","Write","Delete","Assign","Share","Append","AppendTo"],W=["None","Basic","Local","Deep","Global"],Ee=["DuplicateDetectionEnabled","GridFiltersEnabled","HasStateCode","IsConnectionsEnabled","MailMergeEnabled","WorksWithQueue","HasActivities","IsActivity","HasNotes","IsCustomizable","IsActivityParty","HasEmailAddresses","IsChildEntity","IsImportable","IsEnabledForCharts","IsBusinessProcessEnabled","HasFeedback","IsBPFEntity"],Te=["ExportToExcel","MailMerge","GoOffline","OfflineSynchronize","PublishReports"],le=({step:l,onChange:t,onRemove:d,container:p})=>{const c=Se(),[f,R]=te.useState(null),x=l.kind!=="OrRule"&&l.kind!=="RawRule",m=x?l.invertResult:void 0,C=x?l.default:void 0,r=a=>{t({...l,...a})},k=a=>{if(!a.trim())return;const n=parseInt(a,10);return Number.isNaN(n)?void 0:n},A=()=>{switch(l.kind){case"CommandClientTypeRule":return e.jsx(s,{label:"Type",children:e.jsxs(h,{value:l.type,onChange:(a,n)=>r({type:n.value}),children:[e.jsx("option",{value:"Refresh",children:"Refresh (Unified Interface / modern web)"}),e.jsx("option",{value:"Modern",children:"Modern (Dynamics 365 for tablets)"}),e.jsx("option",{value:"Legacy",children:"Legacy (classic ribbon + Outlook list views)"})]})});case"CrmClientTypeRule":return e.jsx(s,{label:"Type",children:e.jsxs(h,{value:l.type,onChange:(a,n)=>r({type:n.value}),children:[e.jsx("option",{value:"Web",children:"Web"}),e.jsx("option",{value:"Outlook",children:"Outlook"})]})});case"FormStateRule":return e.jsx(s,{label:"State",children:e.jsx(h,{value:l.state,onChange:(a,n)=>r({state:n.value}),children:["Create","Existing","ReadOnly","Disabled","BulkEdit"].map(a=>e.jsx("option",{value:a,children:a},a))})});case"FormTypeRule":return e.jsx(s,{label:"Type",children:e.jsx(h,{value:l.type,onChange:(a,n)=>r({type:n.value}),children:["Main","Preview","AppointmentBook","Dashboard","Quick","QuickCreate","Card","MainInteractionCentric"].map(a=>e.jsx("option",{value:a,children:a},a))})});case"SelectionCountRule":return e.jsxs("div",{className:c.row,children:[e.jsx(s,{label:"Minimum",children:e.jsx(y,{value:String(l.minimum??""),onChange:(a,n)=>r({minimum:n.value?parseInt(n.value):void 0}),style:{width:"80px"}})}),e.jsx(s,{label:"Maximum",children:e.jsx(y,{type:"number",value:String(l.maximum??""),onChange:(a,n)=>r({maximum:n.value?parseInt(n.value):void 0}),style:{width:"80px"}})}),e.jsx(s,{label:"Applies To",children:e.jsxs(h,{value:l.appliesTo??"",onChange:(a,n)=>r({appliesTo:n.value}),children:[e.jsx("option",{value:"",children:"Any"}),e.jsx("option",{value:"PrimaryEntity",children:"PrimaryEntity"}),e.jsx("option",{value:"SelectedEntity",children:"SelectedEntity"})]})})]});case"EntityRule":return e.jsxs("div",{className:c.row,children:[e.jsx(s,{label:"Entity name",children:e.jsx(y,{value:l.entityName??"",onChange:(a,n)=>r({entityName:n.value||void 0})})}),e.jsx(s,{label:"Applies To",children:e.jsxs(h,{value:l.appliesTo??"",onChange:(a,n)=>r({appliesTo:n.value}),children:[e.jsx("option",{value:"",children:"Any"}),e.jsx("option",{value:"PrimaryEntity",children:"PrimaryEntity"}),e.jsx("option",{value:"SelectedEntity",children:"SelectedEntity"})]})}),e.jsx(s,{label:"Context",children:e.jsxs(h,{value:l.context??"",onChange:(a,n)=>r({context:n.value||void 0}),children:[e.jsx("option",{value:"",children:"Any"}),e.jsx("option",{value:"Form",children:"Form"}),e.jsx("option",{value:"HomePageGrid",children:"HomePageGrid"}),e.jsx("option",{value:"SubGridStandard",children:"SubGridStandard"}),e.jsx("option",{value:"SubGridAssociated",children:"SubGridAssociated"})]})})]});case"FormEntityContextRule":return e.jsx(s,{label:"Entity name",children:e.jsx(y,{value:l.entityName,onChange:(a,n)=>r({entityName:n.value})})});case"CustomRule":return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:c.row,children:[e.jsx(s,{label:"Library ($webresource:)",children:e.jsx(y,{value:l.library,onChange:(a,n)=>r({library:n.value}),placeholder:"$webresource:..."})}),e.jsx(s,{label:"Function name",children:e.jsx(y,{value:l.functionName,onChange:(a,n)=>r({functionName:n.value})})})]}),e.jsx(s,{label:"Parameters",children:e.jsx(xe,{params:l.params??[],onChange:a=>r({params:a.length?a:void 0})})}),e.jsx(E,{size:100,style:{color:o.colorNeutralForeground3},children:"Async support: on Unified Interface, custom rules can return Promise<boolean>; unresolved promises default to false after 10 seconds."})]});case"CrmOfflineAccessStateRule":return e.jsx(s,{label:"State",children:e.jsxs(h,{value:l.state,onChange:(a,n)=>r({state:n.value}),children:[e.jsx("option",{value:"Online",children:"Online"}),e.jsx("option",{value:"Offline",children:"Offline"})]})});case"CrmOutlookClientTypeRule":return e.jsx(s,{label:"Type",children:e.jsxs(h,{value:l.type,onChange:(a,n)=>r({type:n.value}),children:[e.jsx("option",{value:"CrmForOutlook",children:"CrmForOutlook"}),e.jsx("option",{value:"CrmForOutlookOfflineAccess",children:"CrmForOutlookOfflineAccess"})]})});case"CrmOutlookClientVersionRule":return e.jsxs("div",{className:c.row,children:[e.jsx(s,{label:"Major",children:e.jsx(y,{type:"number",value:String(l.major),onChange:(a,n)=>r({major:k(n.value)??l.major}),style:{width:"84px"}})}),e.jsx(s,{label:"Minor",children:e.jsx(y,{type:"number",value:String(l.minor??""),onChange:(a,n)=>r({minor:k(n.value)}),style:{width:"84px"}})}),e.jsx(s,{label:"Build",children:e.jsx(y,{type:"number",value:String(l.build??""),onChange:(a,n)=>r({build:k(n.value)}),style:{width:"84px"}})}),e.jsx(s,{label:"Revision",children:e.jsx(y,{type:"number",value:String(l.revision??""),onChange:(a,n)=>r({revision:k(n.value)}),style:{width:"84px"}})})]});case"DeviceTypeRule":return e.jsx(s,{label:"Device type",children:e.jsxs(h,{value:l.type,onChange:(a,n)=>r({type:n.value}),children:[e.jsx("option",{value:"None",children:"None"}),e.jsx("option",{value:"Phone",children:"Phone"}),e.jsx("option",{value:"Tablet",children:"Tablet"}),e.jsx("option",{value:"Web",children:"Web"}),e.jsx("option",{value:"Outlook",children:"Outlook"}),e.jsx("option",{value:"InteractionCentric",children:"InteractionCentric"})]})});case"EntityPrivilegeRule":return e.jsxs("div",{className:c.row,children:[e.jsx(s,{label:"Entity (optional)",children:e.jsx(y,{value:l.entityName??"",onChange:(a,n)=>r({entityName:n.value||void 0})})}),e.jsx(s,{label:"Applies To",children:e.jsxs(h,{value:l.appliesTo??"",onChange:(a,n)=>r({appliesTo:n.value||void 0}),children:[e.jsx("option",{value:"",children:"Any"}),e.jsx("option",{value:"PrimaryEntity",children:"PrimaryEntity"}),e.jsx("option",{value:"SelectedEntity",children:"SelectedEntity"})]})}),e.jsx(s,{label:"Privilege",children:e.jsx(h,{value:l.privilegeType,onChange:(a,n)=>r({privilegeType:n.value}),children:G.map(a=>e.jsx("option",{value:a,children:a},a))})}),e.jsx(s,{label:"Depth",children:e.jsx(h,{value:l.privilegeDepth,onChange:(a,n)=>r({privilegeDepth:n.value}),children:W.map(a=>e.jsx("option",{value:a,children:a},a))})})]});case"EntityPropertyRule":return e.jsxs("div",{className:c.row,children:[e.jsx(s,{label:"Entity (optional)",children:e.jsx(y,{value:l.entityName??"",onChange:(a,n)=>r({entityName:n.value||void 0})})}),e.jsx(s,{label:"Applies To",children:e.jsxs(h,{value:l.appliesTo??"",onChange:(a,n)=>r({appliesTo:n.value||void 0}),children:[e.jsx("option",{value:"",children:"Any"}),e.jsx("option",{value:"PrimaryEntity",children:"PrimaryEntity"}),e.jsx("option",{value:"SelectedEntity",children:"SelectedEntity"})]})}),e.jsx(s,{label:"Property",children:e.jsx(h,{value:l.propertyName,onChange:(a,n)=>r({propertyName:n.value}),children:Ee.map(a=>e.jsx("option",{value:a,children:a},a))})}),e.jsx(w,{label:"Property value",checked:l.propertyValue,onChange:(a,n)=>r({propertyValue:n.checked===!0})})]});case"ValueRule":return e.jsxs("div",{className:c.row,children:[e.jsx(s,{label:"Field",children:e.jsx(y,{value:l.field,onChange:(a,n)=>r({field:n.value})})}),e.jsx(s,{label:"Value",children:e.jsx(y,{value:l.value,onChange:(a,n)=>r({value:n.value})})})]});case"OrRule":{const a=g=>t({...l,groups:g.filter(b=>b.length>0)}),n=(g,b)=>e.jsxs(Q,{open:f===g,onOpenChange:(v,u)=>R(u.open?g:null),children:[e.jsx(Y,{children:e.jsx(O,{icon:e.jsx(K,{}),appearance:"secondary",size:"small",children:b})}),e.jsx(J,{className:c.pickerSurface,children:e.jsx(ee,{container:p,insideOr:!0,onSelect:v=>{a(g==="new"?[...l.groups,[v]]:l.groups.map((u,S)=>S===g?[...u,v]:u)),R(null)}})})]});return e.jsxs("div",{className:c.nested,children:[l.groups.map((g,b)=>e.jsxs("div",{className:c.nested,children:[e.jsxs(E,{size:100,weight:"semibold",children:[b===0?"Either":"Or",g.length>1?" (all of)":""]}),g.map((v,u)=>e.jsx(le,{step:v,container:p,onChange:S=>a(l.groups.map((T,D)=>D===b?T.map((P,M)=>M===u?S:P):T)),onRemove:()=>a(l.groups.map((S,T)=>T===b?S.filter((D,P)=>P!==u):S))},`${b}-${u}-${v.kind}`)),e.jsx("div",{className:c.nestedToolbar,children:n(b,"And…")})]},b)),e.jsxs("div",{className:c.nestedToolbar,children:[n("new","Add Or branch"),e.jsx(E,{size:100,style:{color:o.colorNeutralForeground3},children:"An OrRule needs at least two branches."})]})]})}case"FeatureControlRule":return e.jsxs("div",{className:c.row,children:[e.jsx(s,{label:"Feature control bit",children:e.jsx(y,{value:l.featureControlBit,onChange:(a,n)=>r({featureControlBit:n.value})})}),e.jsx(w,{label:"Expected value",checked:l.expectedValue,onChange:(a,n)=>r({expectedValue:n.checked===!0})})]});case"RawRule":return e.jsxs(e.Fragment,{children:[e.jsx(E,{size:100,style:{color:o.colorNeutralForeground3},children:"Command Bar Studio doesn't edit this rule; it is kept exactly as loaded."}),e.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap",fontSize:"11px"},children:l.xml})]});case"SkuRule":return e.jsx(s,{label:"SKU",children:e.jsxs(h,{value:l.sku,onChange:(a,n)=>r({sku:n.value}),children:[e.jsx("option",{value:"Online",children:"Online"}),e.jsx("option",{value:"OnPremise",children:"OnPremise"}),e.jsx("option",{value:"Spla",children:"Spla"})]})});case"OrganizationSettingRule":return e.jsx(s,{label:"Setting",children:e.jsx(h,{value:l.setting,onChange:(a,n)=>r({setting:n.value}),children:["IsSharepointEnabled","IsSOPIntegrationEnabled","IsFiscalCalendarDefined","IsReadFormModeDefined","IsBPFEntityCustomizationFeatureEnabled"].map(a=>e.jsx("option",{value:a,children:a},a))})});case"MiscellaneousPrivilegeRule":return e.jsxs("div",{className:c.row,children:[e.jsxs(s,{label:"Privilege name",children:[e.jsx(y,{value:l.privilegeName,onChange:(a,n)=>r({privilegeName:n.value}),placeholder:"ExportToExcel",list:"misc-privilege-suggestions"}),e.jsx("datalist",{id:"misc-privilege-suggestions",children:Te.map(a=>e.jsx("option",{value:a},a))})]}),e.jsx(s,{label:"Depth (optional)",children:e.jsxs(h,{value:l.privilegeDepth??"",onChange:(a,n)=>r({privilegeDepth:n.value||void 0}),children:[e.jsx("option",{value:"",children:"Any"}),W.map(a=>e.jsx("option",{value:a,children:a},a))]})})]});case"OptionSetRule":return e.jsxs("div",{className:c.row,children:[e.jsx(s,{label:"Option set",children:e.jsx(y,{value:l.optionSet,onChange:(a,n)=>r({optionSet:n.value})})}),e.jsx(s,{label:"State code",children:e.jsx(y,{value:l.stateCode,onChange:(a,n)=>r({stateCode:n.value})})}),e.jsx(s,{label:"Object type code",children:e.jsx(y,{value:l.objectTypeCode,onChange:(a,n)=>r({objectTypeCode:n.value})})})]});case"OutlookItemTrackingRule":return e.jsxs("div",{className:c.row,children:[e.jsx(w,{label:"Tracked in CRM",checked:l.trackedInCrm,onChange:(a,n)=>r({trackedInCrm:n.checked===!0})}),e.jsx(s,{label:"Applies To",children:e.jsx(h,{value:l.appliesTo??"PrimaryEntity",onChange:(a,n)=>r({appliesTo:n.value}),children:e.jsx("option",{value:"PrimaryEntity",children:"PrimaryEntity"})})})]});case"OutlookRenderTypeRule":return e.jsx(s,{label:"Render type",children:e.jsxs(h,{value:l.type,onChange:(a,n)=>r({type:n.value}),children:[e.jsx("option",{value:"Web",children:"Web"}),e.jsx("option",{value:"Outlook",children:"Outlook"})]})});case"OutlookVersionRule":return e.jsx(s,{label:"Outlook version",children:e.jsxs(h,{value:l.version,onChange:(a,n)=>r({version:n.value}),children:[e.jsx("option",{value:"2003",children:"2003"}),e.jsx("option",{value:"2007",children:"2007"}),e.jsx("option",{value:"2010",children:"2010"})]})});case"PageRule":return e.jsx(s,{label:"Address pattern",children:e.jsx(y,{value:l.address,onChange:(a,n)=>r({address:n.value}),placeholder:"main.aspx"})});case"RecordPrivilegeRule":return e.jsxs("div",{className:c.row,children:[e.jsx(s,{label:"Privilege",children:e.jsx(h,{value:l.privilegeType,onChange:(a,n)=>r({privilegeType:n.value}),children:G.map(a=>e.jsx("option",{value:a,children:a},a))})}),e.jsx(s,{label:"Applies To",children:e.jsxs(h,{value:l.appliesTo??"",onChange:(a,n)=>r({appliesTo:n.value||void 0}),children:[e.jsx("option",{value:"",children:"Default"}),e.jsx("option",{value:"PrimaryEntity",children:"PrimaryEntity"})]})})]});case"RelationshipTypeRule":return e.jsxs("div",{className:c.row,children:[e.jsx(s,{label:"Applies To",children:e.jsx(h,{value:l.appliesTo,disabled:!0,children:e.jsx("option",{value:"SelectedEntity",children:"SelectedEntity"})})}),e.jsx(s,{label:"Relationship type",children:e.jsxs(h,{value:l.relationshipType??"",onChange:(a,n)=>r({relationshipType:n.value||void 0}),children:[e.jsx("option",{value:"",children:"Any"}),e.jsx("option",{value:"OneToMany",children:"OneToMany"}),e.jsx("option",{value:"ManyToMany",children:"ManyToMany"}),e.jsx("option",{value:"NoRelationship",children:"NoRelationship"})]})}),e.jsx(w,{label:"Allow custom relationship",checked:l.allowCustomRelationship===!0,onChange:(a,n)=>r({allowCustomRelationship:n.checked===!0})}),e.jsx(w,{label:"Allow system relationship",checked:l.allowSystemRelationship===!0,onChange:(a,n)=>r({allowSystemRelationship:n.checked===!0})})]});default:return e.jsxs(E,{size:200,italic:!0,style:{color:o.colorNeutralForeground3},children:[l.kind," — no additional parameters"]})}};return e.jsxs("div",{className:c.step,role:"listitem",children:[e.jsxs("div",{className:c.header,children:[e.jsx(q,{appearance:"outline",size:"small",className:c.kindBadge,children:V[l.kind]??l.kind}),e.jsx(O,{appearance:"subtle",icon:e.jsx(X,{}),size:"small",onClick:d,"aria-label":`Remove ${l.kind} step`})]}),e.jsxs("div",{className:c.fields,children:[A(),e.jsx("div",{className:c.row,children:x&&e.jsxs(e.Fragment,{children:[e.jsx(s,{label:"Default",title:"Value the rule returns when it cannot be evaluated.",children:e.jsxs(h,{value:C===void 0?"":String(C),onChange:(a,n)=>r({default:n.value===""?void 0:n.value==="true"}),children:[e.jsx("option",{value:"",children:"(not set)"}),e.jsx("option",{value:"true",children:"true"}),e.jsx("option",{value:"false",children:"false"})]})}),e.jsx(w,{label:"Invert result",checked:m===!0,title:"Reverse the evaluated result.",onChange:(a,n)=>r({invertResult:n.checked===!0?!0:void 0})})]})})]})]})};function Ne(l){return l.length===0?"No steps defined — rule always passes.":l.map(B).join(" AND ")}function B(l){const t="invertResult"in l&&l.invertResult?"NOT ":"";switch(l.kind){case"SelectionCountRule":{const d=l.minimum!==void 0?`at least ${l.minimum}`:null,p=l.maximum!==void 0?`at most ${l.maximum}`:null,c=[d,p].filter(Boolean).join(" and "),f=l.appliesTo?` (${l.appliesTo})`:"";return`${t}Selection count is ${c}${f}`}case"EntityRule":{const d=l.entityName??"any entity",p=l.context?` in ${l.context} context`:"",c=l.appliesTo?` (${l.appliesTo})`:"";return`${t}Entity is "${d}"${p}${c}`}case"FormStateRule":return`${t}Form state is "${l.state}"`;case"CommandClientTypeRule":return`${t}Client type is "${l.type}" (${$e(l.type)})`;case"CrmClientTypeRule":return`${t}CRM client type is "${l.type}"`;case"CustomRule":return`${t}Custom rule: ${l.functionName}() from ${l.library}`;case"OrRule":return`(${l.groups.map(p=>p.length===1?B(p[0]):`(${p.map(B).join(" AND ")})`).join(" OR ")})`;case"FeatureControlRule":return`${t}Feature "${l.featureControlBit}" is ${l.expectedValue?"on":"off"}`;case"RawRule":return`${l.tagName} (kept as XML)`;case"MiscellaneousPrivilegeRule":{const d=l.privilegeDepth?` at ${l.privilegeDepth} depth`:"";return`${t}User has "${l.privilegeName}" privilege${d}`}case"EntityPrivilegeRule":{const d=l.entityName?` on "${l.entityName}"`:"",p=l.appliesTo?` (${l.appliesTo})`:"";return`${t}User has ${l.privilegeType} privilege${d} at ${l.privilegeDepth} depth${p}`}case"EntityPropertyRule":{const d=l.entityName?` for "${l.entityName}"`:"";return`${t}Entity property "${l.propertyName}" is ${l.propertyValue}${d}`}case"FormTypeRule":return`${t}Form type is "${l.type}"`;case"FormEntityContextRule":return`${t}Form entity context is "${l.entityName}"`;case"ValueRule":return`${t}Field "${l.field}" equals "${l.value}"`;case"SkuRule":return`${t}SKU is "${l.sku}"`;case"HideForTabletExperienceRule":return`${t}Hide for tablet experience`;case"OrganizationSettingRule":return`${t}Organization setting "${l.setting}" is enabled`;case"PageRule":return`${t}Page address matches "${l.address}"`;case"RecordPrivilegeRule":{const d=l.appliesTo?` (${l.appliesTo})`:"";return`${t}User has ${l.privilegeType} privilege on current record${d}`}case"RelationshipTypeRule":{const d=l.relationshipType??"any";return`${t}Relationship type is "${d}" (${l.appliesTo})`}case"ReferencingAttributeRequiredRule":return`${t}Referencing attribute is required`;case"OutlookItemTrackingRule":return`${t}Outlook item is ${l.trackedInCrm?"":"not "}tracked in CRM`;case"OutlookRenderTypeRule":return`${t}Outlook render type is "${l.type}"`;case"OutlookVersionRule":return`${t}Outlook version is "${l.version}"`;case"CrmOfflineAccessStateRule":return`${t}CRM offline state is "${l.state}"`;case"CrmOutlookClientTypeRule":return`${t}CRM Outlook client type is "${l.type}"`;case"CrmOutlookClientVersionRule":return`${t}CRM Outlook client version is ${l.major}.${l.minor??0}+`;case"DeviceTypeRule":return`${t}Device type is "${l.type}"`;case"OptionSetRule":return`${t}Option set "${l.optionSet}" state code is "${l.stateCode}"`;default:return"Unknown rule step"}}function $e(l){switch(l){case"Modern":return"Dynamics 365 tablets";case"Refresh":return"Unified Interface / modern web";case"Legacy":return"Classic ribbon / Outlook list views";default:return l}}let Oe=0;const U=(l,t)=>Array.from({length:t},()=>`${l}#${++Oe}`);function ke(l,t){const[d,p]=I.useState(null),c=I.useMemo(()=>U(l,t.length),[l,t]),f=!!d&&d.scope===l&&d.keys.length===t.length&&(d.items===t||d.pending);d?.pending&&p({...d,items:f?t:d.items,pending:!1});const R=f?d.keys:c,x=m=>p({scope:l,items:t,pending:!0,keys:m});return{keys:R,add:()=>x([...R,...U(l,1)]),remove:m=>x(R.filter((C,r)=>r!==m)),move:(m,C)=>x(Z(R,m,C)),update:()=>x(R)}}const we=L({drawer:{width:"560px",maxWidth:"90vw"},body:{display:"flex",flexDirection:"column",gap:o.spacingVerticalS,padding:o.spacingVerticalM,overflowY:"auto"},header:{display:"flex",alignItems:"center",gap:o.spacingHorizontalS},stepsList:{display:"flex",flexDirection:"column",gap:o.spacingVerticalXS,listStyle:"none",padding:0,margin:0},summary:{padding:o.spacingVerticalS,backgroundColor:o.colorNeutralBackground3,borderRadius:o.borderRadiusMedium,fontStyle:"italic",color:o.colorNeutralForeground2,fontSize:o.fontSizeBase200},addRow:{display:"flex",gap:o.spacingHorizontalS},pickerPopover:{maxHeight:"60vh",overflowY:"auto",minWidth:"320px",padding:o.spacingVerticalM},usedBy:{color:o.colorNeutralForeground3,fontSize:o.fontSizeBase200},ruleIdRow:{display:"flex",alignItems:"flex-end",gap:o.spacingHorizontalS},ruleIdInput:{fontFamily:o.fontFamilyMonospace},error:{color:o.colorPaletteRedForeground1,fontSize:o.fontSizeBase100},sortableItem:{listStyle:"none"},sortableInner:{display:"flex",alignItems:"flex-start",gap:o.spacingHorizontalS},dragHandle:{marginTop:o.spacingVerticalS,cursor:"grab"}}),Ie=[],Le=()=>{const l=we(),t=_(i=>i.ruleEditorOpen),d=_(i=>i.ruleEditorId),p=_(i=>i.ruleEditorKind),c=_(i=>i.closeRuleEditor),f=_(i=>i.openRuleEditor),R=$(i=>i.enableRules),x=$(i=>i.displayRules),m=$(i=>i.commands),C=$(i=>i.upsertEnableRule),r=$(i=>i.upsertDisplayRule),k=$(i=>i.renameEnableRuleId),A=$(i=>i.renameDisplayRuleId),[a,n]=I.useState(!1),[g,b]=I.useState(""),v=p==="enable",u=v?R.find(i=>i.id===d):x.find(i=>i.id===d);I.useEffect(()=>{u&&b(u.id)},[u]);const S=ke(`${p}:${u?.id??""}`,u?.steps??Ie),T=S.keys,D=m.filter(i=>v?i.enableRules.includes(d??""):i.displayRules.includes(d??"")).length,P=(i,j)=>{if(!u)return;const N=[...u.steps];N[i]=j,S.update(),v?C({...u,steps:N}):r({...u,steps:N})},M=i=>{if(!u)return;const j=u.steps.filter((N,F)=>F!==i);S.remove(i),v?C({...u,steps:j}):r({...u,steps:j})},ne=i=>{if(!u)return;const j=[...u.steps,i];S.add(),v?C({...u,steps:j}):r({...u,steps:j}),n(!1)},ae=i=>{if(!u||!i.over||i.active.id===i.over.id)return;const j=T.indexOf(String(i.active.id)),N=T.indexOf(String(i.over.id));if(j<0||N<0)return;const F=Z(u.steps,j,N);S.move(j,N),v?C({...u,steps:F}):r({...u,steps:F})};if(!u)return null;const re=Ne(u.steps),ie=(v?R:x).some(i=>i.id===g.trim()&&i.id!==u.id),z=g.trim()?/\s/.test(g)?"Rule ID cannot contain whitespace.":ie?"A rule with this ID already exists.":"":"Rule ID is required.";return e.jsxs(ce,{position:"end",open:t,onOpenChange:()=>c(),className:l.drawer,children:[e.jsx(ue,{children:e.jsx(de,{action:e.jsx(O,{appearance:"subtle",icon:e.jsx(X,{}),onClick:c,"aria-label":"Close rule editor"}),children:e.jsxs("div",{className:l.header,children:[e.jsx(q,{appearance:"filled",color:v?"success":"informative",size:"small",children:v?"Enable":"Display"}),e.jsx(E,{size:400,weight:"semibold",style:{fontFamily:o.fontFamilyMonospace},children:u.id})]})})}),e.jsxs(pe,{className:l.body,children:[e.jsxs(E,{className:l.usedBy,children:["Used by ",D," command(s)"]}),e.jsxs("div",{className:l.ruleIdRow,children:[e.jsx(y,{className:l.ruleIdInput,value:g,onChange:(i,j)=>b(j.value),"aria-label":"Rule ID"}),e.jsx(O,{appearance:"secondary",size:"small",disabled:!g.trim()||!!z||g===u.id,onClick:()=>{const i=g.trim();(v?k(u.id,i):A(u.id,i))&&f(i,v?"enable":"display")},children:"Apply ID change"})]}),z&&e.jsx(E,{className:l.error,children:z}),v&&e.jsx(he,{intent:"warning",children:e.jsx(me,{children:"Enable rules have a restricted set of allowed step types. Display-only rule kinds are disabled."})}),e.jsx(H,{children:"Steps (ALL must pass)"}),e.jsx(ye,{collisionDetection:ve,onDragEnd:ae,children:e.jsx(je,{items:T,strategy:ge,children:e.jsxs("ol",{className:l.stepsList,role:"list","aria-label":"Rule steps",children:[u.steps.map((i,j)=>e.jsx(Pe,{id:T[j],styles:l,children:e.jsx(le,{step:i,onChange:N=>P(j,N),onRemove:()=>M(j),container:v?"enable":"display"})},T[j])),u.steps.length===0&&e.jsx(E,{italic:!0,style:{color:o.colorNeutralForeground3},children:"No steps yet — all buttons with this rule will be visible/enabled by default."})]})})}),e.jsxs(Q,{open:a,onOpenChange:(i,j)=>n(j.open),children:[e.jsx(Y,{children:e.jsx(O,{icon:e.jsx(K,{}),appearance:"secondary",onClick:()=>n(!0),children:"Add step"})}),e.jsx(J,{className:l.pickerPopover,children:e.jsx(ee,{onSelect:ne,container:v?"enable":"display"})})]}),e.jsx(H,{children:"Plain-English summary"}),e.jsx("div",{className:l.summary,role:"note","aria-label":"Rule summary",children:re})]})]})};function Pe({id:l,children:t,styles:d}){const{attributes:p,listeners:c,setNodeRef:f,setActivatorNodeRef:R,transform:x,transition:m}=Re({id:l});return e.jsx("li",{ref:f,className:d.sortableItem,style:{transform:be.Transform.toString(x),transition:m},children:e.jsxs("div",{className:d.sortableInner,children:[e.jsx(O,{ref:R,appearance:"subtle",size:"small",className:d.dragHandle,...p,...c,"aria-label":"Drag to reorder step",children:"Drag"}),e.jsx("div",{style:{flex:1},children:t})]})})}export{Le as RuleEditorPanel,Le as default};
@@ -0,0 +1 @@
1
+ import{z as e,h as O,co as I,cq as C,y as $}from"./fluent-icons-DxKNRZ1A.js";import{a as M,R as X}from"./monaco-Bx8A1Vm1.js";import{a as k,X as H,u as q}from"./index-Bu7BlRFk.js";import{ah as A,ai as P,aj as U,aa as G,B as c,ak as Y,T as x,t as l,a7 as R,c as B,F as p,S as j,I as L}from"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";const Z=$({drawer:{width:"600px",maxWidth:"95vw"},body:{display:"flex",flexDirection:"column",gap:l.spacingHorizontalM,padding:l.spacingHorizontalM,overflowY:"auto"},stepRow:{display:"flex",flexDirection:"column",gap:l.spacingHorizontalXS,padding:l.spacingHorizontalS,border:`1px solid ${l.colorNeutralStroke2}`,borderRadius:l.borderRadiusMedium,backgroundColor:l.colorNeutralBackground2},stepHeader:{display:"flex",alignItems:"center",gap:l.spacingHorizontalS},stepFields:{display:"flex",gap:l.spacingHorizontalS,flexWrap:"wrap",alignItems:"flex-end"},sectionLabel:{color:l.colorNeutralForeground3,textTransform:"uppercase",fontSize:l.fontSizeBase100,letterSpacing:"0.5px",fontWeight:l.fontWeightSemibold},warningNote:{backgroundColor:l.colorStatusWarningBackground1,borderRadius:l.borderRadiusMedium,padding:`${l.spacingHorizontalXS} ${l.spacingHorizontalS}`,fontSize:l.fontSizeBase100}}),D=["Large","LargeLarge","LargeMedium","LargeSmall","MediumLarge","MediumMedium","MediumSmall","SmallMedium","SmallSmall","Popup"],ae=()=>{const o=Z(),b=k(a=>a.scalingEditorOpen),S=k(a=>a.closeScalingEditor),y=H(a=>a.location),u=H(a=>a.tabId),T=q(a=>a.ribbons),_=q(a=>a.setScaling),v=T[y],r=v.tabs.find(a=>a.id===u),h=u?v.scalingByTab?.[u]:void 0,[w,g]=M.useState([]),[N,m]=M.useState([]);X.useEffect(()=>{if(!(!b||!r)){if(h){g([...h.maxSizes]),m([...h.scales]);return}g([{id:`MaxSize.${r.id}.1`,groupId:r.groups[0]?.id??"",size:"Large",sequence:10}]),m([{id:`Scale.${r.id}.1`,groupId:r.groups[0]?.id??"",size:"SmallSmall",sequence:200}])}},[b,r,h]);const d=r?.groups??[],E=()=>{g(a=>[...a,{id:`MaxSize.${a.length+1}`,groupId:d[0]?.id??"",size:"Large",sequence:(a.length+1)*10}])},F=()=>{m(a=>[...a,{id:`Scale.${a.length+1}`,groupId:d[0]?.id??"",size:"SmallSmall",sequence:200+(a.length+1)*10}])},z=(a,i)=>{g(s=>s.map((n,t)=>t===a?{...n,...i}:n))},f=(a,i)=>{m(s=>s.map((n,t)=>t===a?{...n,...i}:n))},W=()=>{_(y,u,{tabId:u,maxSizes:w,scales:N}),S()};return e.jsxs(A,{className:o.drawer,open:b,position:"end",onOpenChange:(a,i)=>!i.open&&S(),children:[e.jsx(P,{children:e.jsx(U,{action:e.jsx(c,{appearance:"subtle",icon:e.jsx(O,{}),onClick:S,"aria-label":"Close"}),children:e.jsx(G,{children:"Scaling Editor"})})}),e.jsx(Y,{children:e.jsxs("div",{className:o.body,children:[e.jsxs("div",{className:o.warningNote,children:["⚠ ",e.jsx("strong",{children:"Scaling applies ONLY to the Classic ribbon"})," — forms NOT updated to Unified Interface, and Dynamics 365 for Outlook list views. The modern command bar (Unified Interface) ignores all MaxSize and Scale definitions entirely."]}),r&&e.jsxs(x,{size:200,style:{color:l.colorNeutralForeground3},children:["Tab: ",e.jsx("strong",{children:r.label})," (",r.id,")"]}),e.jsx(R,{}),e.jsxs("div",{children:[e.jsx(x,{className:o.sectionLabel,children:"MaxSize (largest size, shown first)"}),e.jsx(x,{size:100,style:{color:l.colorNeutralForeground3,display:"block",marginBottom:l.spacingHorizontalS},children:"Sequence numbers must be lower than all Scale step sequence numbers."}),w.map((a,i)=>e.jsxs("div",{className:o.stepRow,style:{marginBottom:l.spacingHorizontalXS},children:[e.jsxs("div",{className:o.stepHeader,children:[e.jsxs(B,{appearance:"tint",color:"brand",size:"small",children:["MaxSize ",i+1]}),e.jsx("div",{style:{flex:1}}),e.jsx(c,{appearance:"subtle",size:"small",icon:e.jsx(I,{}),onClick:()=>g(s=>s.filter((n,t)=>t!==i))})]}),e.jsxs("div",{className:o.stepFields,children:[e.jsx(p,{label:"Group",style:{minWidth:"160px"},children:e.jsxs(j,{size:"small",value:a.groupId,onChange:(s,n)=>z(i,{groupId:n.value}),children:[d.length===0&&e.jsx("option",{value:"",children:"— no groups —"}),d.map(s=>e.jsx("option",{value:s.id,children:s.label||s.id},s.id))]})}),e.jsx(p,{label:"Size",style:{minWidth:"140px"},children:e.jsx(j,{size:"small",value:a.size,onChange:(s,n)=>z(i,{size:n.value}),children:D.map(s=>e.jsx("option",{value:s,children:s},s))})}),e.jsx(p,{label:"Sequence",style:{width:"80px"},children:e.jsx(L,{size:"small",type:"number",value:String(a.sequence),onChange:(s,n)=>z(i,{sequence:parseInt(n.value,10)||0})})})]})]},i)),e.jsx(c,{appearance:"subtle",size:"small",icon:e.jsx(C,{}),onClick:E,children:"Add MaxSize"})]}),e.jsx(R,{}),e.jsxs("div",{children:[e.jsx(x,{className:o.sectionLabel,children:"Scale steps (collapse order — top-down)"}),e.jsx(x,{size:100,style:{color:l.colorNeutralForeground3,display:"block",marginBottom:l.spacingHorizontalS},children:"Scale elements are applied in document order (top-down when shrinking, bottom-up when growing). Sequence numbers must be higher than all MaxSize sequence numbers."}),N.map((a,i)=>e.jsxs("div",{className:o.stepRow,style:{marginBottom:l.spacingHorizontalXS},children:[e.jsxs("div",{className:o.stepHeader,children:[e.jsxs(B,{appearance:"tint",color:"informative",size:"small",children:["Scale ",i+1]}),e.jsx("div",{style:{flex:1}}),e.jsx(c,{appearance:"subtle",size:"small",icon:e.jsx(I,{}),onClick:()=>m(s=>s.filter((n,t)=>t!==i))})]}),e.jsxs("div",{className:o.stepFields,children:[e.jsx(p,{label:"Group",style:{minWidth:"160px"},children:e.jsxs(j,{size:"small",value:a.groupId,onChange:(s,n)=>f(i,{groupId:n.value}),children:[d.length===0&&e.jsx("option",{value:"",children:"— no groups —"}),d.map(s=>e.jsx("option",{value:s.id,children:s.label||s.id},s.id))]})}),e.jsx(p,{label:"Size",style:{minWidth:"140px"},children:e.jsx(j,{size:"small",value:a.size,onChange:(s,n)=>f(i,{size:n.value}),children:D.map(s=>e.jsx("option",{value:s,children:s},s))})}),e.jsx(p,{label:"Sequence",style:{width:"80px"},children:e.jsx(L,{size:"small",type:"number",value:String(a.sequence),onChange:(s,n)=>f(i,{sequence:parseInt(n.value,10)||0})})})]})]},i)),e.jsx(c,{appearance:"subtle",size:"small",icon:e.jsx(C,{}),onClick:F,children:"Add Scale step"})]}),e.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:l.spacingHorizontalS,paddingTop:l.spacingHorizontalS},children:[e.jsx(c,{appearance:"secondary",onClick:S,children:"Cancel"}),e.jsx(c,{appearance:"primary",onClick:W,children:"Save scaling"})]})]})})]})};export{ae as ScalingEditorPanel,ae as default};
@@ -0,0 +1 @@
1
+ import{z as e,h as X,co as T,cq as I,y as L}from"./fluent-icons-DxKNRZ1A.js";import{a as P,R as V}from"./monaco-Bx8A1Vm1.js";import{a as E,X as w,u as F}from"./index-Bu7BlRFk.js";import{ah as Y,ai as J,aj as K,aa as Q,B as c,ak as Z,M as H,e as N,T as p,t as o,c as ee,F as x,I as v,S}from"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";function C(){return{kind:"EntityRule",appliesTo:"PrimaryEntity",context:"HomePageGrid"}}function A(){return{kind:"PageRule",address:""}}const ae=L({drawer:{width:"560px",maxWidth:"95vw"},body:{display:"flex",flexDirection:"column",gap:o.spacingHorizontalM,padding:o.spacingHorizontalM,overflowY:"auto"},ruleRow:{display:"flex",flexDirection:"column",gap:o.spacingHorizontalXS,padding:o.spacingHorizontalS,border:`1px solid ${o.colorNeutralStroke2}`,borderRadius:o.borderRadiusMedium,backgroundColor:o.colorNeutralBackground2},ruleHeader:{display:"flex",alignItems:"center",gap:o.spacingHorizontalS},stepFields:{display:"flex",gap:o.spacingHorizontalS,alignItems:"flex-end",flexWrap:"wrap"}}),re=()=>{const b=ae(),j=E(a=>a.tabDisplayRulesOpen),h=E(a=>a.closeTabDisplayRules),g=w(a=>a.location),z=w(a=>a.tabId),B=F(a=>a.ribbons),M=F(a=>a.setTabDisplayRules),i=B[g].tabs.find(a=>a.id===z),f=g==="Application",D=!!i?.commandId,[y,d]=P.useState(()=>i?.tabDisplayRules??[]),[k,u]=P.useState(null);V.useEffect(()=>{j&&(u(null),d(i?.tabDisplayRules??[]))},[j,i]);const _=()=>{d(a=>[...a,{tabCommand:i?.commandId??"",rules:[C()]}])},G=a=>{d(l=>l.filter((s,n)=>n!==a))},W=(a,l)=>{D||d(s=>s.map((n,t)=>t===a?{...n,tabCommand:l}:n))},m=(a,l,s)=>{d(n=>n.map((t,r)=>r===a?{...t,rules:t.rules.map((R,U)=>U===l?s:R)}:t))},$=a=>{d(l=>l.map((s,n)=>n===a?{...s,rules:[...s.rules,f?A():C()]}:s))},O=(a,l)=>{d(s=>s.map((n,t)=>t===a?{...n,rules:n.rules.filter((r,R)=>R!==l)}:n))},q=()=>{if(!i){u("No active tab selected.");return}for(const[a,l]of y.entries()){if(!l.tabCommand.trim()){u(`Rule ${a+1}: tabCommand is required.`);return}if(i.commandId&&l.tabCommand!==i.commandId){u(`Rule ${a+1}: tabCommand must match the tab command ID (${i.commandId}).`);return}if(!f&&l.rules.some(s=>s.kind==="PageRule")){u(`Rule ${a+1}: PageRule is only valid for Application ribbon tabs.`);return}}u(null),M(g,z,y),h()};return e.jsxs(Y,{className:b.drawer,open:j,position:"end",onOpenChange:(a,l)=>!l.open&&h(),children:[e.jsx(J,{children:e.jsx(K,{action:e.jsx(c,{appearance:"subtle",icon:e.jsx(X,{}),onClick:h,"aria-label":"Close"}),children:e.jsx(Q,{children:"Tab Display Rules"})})}),e.jsx(Z,{children:e.jsxs("div",{className:b.body,children:[k&&e.jsx(H,{intent:"error",children:e.jsx(N,{children:k})}),e.jsx(H,{intent:"info",children:e.jsx(N,{children:e.jsxs(p,{size:200,children:["Tabs are ",e.jsx("strong",{children:"hidden by default"}),". Each Tab Display Rule defines when this tab is shown. The tabCommand must match the tab's Command ID."]})})}),i&&e.jsxs("div",{children:[e.jsxs(p,{size:200,style:{color:o.colorNeutralForeground3},children:["Tab: ",e.jsx("strong",{children:i.label})," (",i.id,")"]}),i.commandId&&e.jsxs(p,{size:200,style:{color:o.colorNeutralForeground3,display:"block"},children:["Command ID:"," ",e.jsx("code",{style:{fontFamily:o.fontFamilyMonospace},children:i.commandId})]})]}),y.length===0&&e.jsx(p,{style:{color:o.colorNeutralForeground3,textAlign:"center"},children:"No display rules — this tab will be hidden."}),y.map((a,l)=>e.jsxs("div",{className:b.ruleRow,children:[e.jsxs("div",{className:b.ruleHeader,children:[e.jsxs(ee,{appearance:"outline",size:"small",children:["Rule ",l+1]}),e.jsx("div",{style:{flex:1}}),e.jsx(c,{appearance:"subtle",size:"small",icon:e.jsx(T,{}),onClick:()=>G(l),"aria-label":"Remove rule"})]}),e.jsx(x,{label:"Tab command ID",hint:"Must match Tab.commandId",children:e.jsx(v,{value:a.tabCommand,onChange:(s,n)=>W(l,n.value),disabled:D,size:"small",style:{fontFamily:o.fontFamilyMonospace}})}),e.jsx(p,{size:100,weight:"semibold",style:{color:o.colorNeutralForeground3},children:"Steps"}),a.rules.map((s,n)=>e.jsxs("div",{className:b.stepFields,children:[e.jsx(x,{label:"Type",style:{minWidth:"140px"},children:e.jsxs(S,{size:"small",value:s.kind,onChange:(t,r)=>{r.value==="PageRule"?m(l,n,A()):m(l,n,C())},children:[e.jsx("option",{value:"EntityRule",children:"Entity Rule"}),f&&e.jsx("option",{value:"PageRule",children:"Page Rule"})]})}),s.kind==="EntityRule"&&e.jsxs(e.Fragment,{children:[e.jsx(x,{label:"Applies to",style:{minWidth:"130px"},children:e.jsxs(S,{size:"small",value:s.appliesTo??"PrimaryEntity",onChange:(t,r)=>m(l,n,{...s,appliesTo:r.value}),children:[e.jsx("option",{value:"PrimaryEntity",children:"Primary entity"}),e.jsx("option",{value:"SelectedEntity",children:"Selected entity"})]})}),e.jsx(x,{label:"Context",style:{minWidth:"160px"},children:e.jsxs(S,{size:"small",value:s.context??"HomePageGrid",onChange:(t,r)=>m(l,n,{...s,context:r.value}),children:[e.jsx("option",{value:"Form",children:"Form"}),e.jsx("option",{value:"HomePageGrid",children:"Home Page Grid"}),e.jsx("option",{value:"SubGridStandard",children:"SubGrid Standard"}),e.jsx("option",{value:"SubGridAssociated",children:"SubGrid Associated"})]})}),e.jsx(x,{label:"Entity (optional)",children:e.jsx(v,{size:"small",value:s.entityName??"",onChange:(t,r)=>m(l,n,{...s,entityName:r.value||void 0}),placeholder:"any"})})]}),s.kind==="PageRule"&&e.jsx(x,{label:"Address pattern",style:{flex:1},children:e.jsx(v,{size:"small",value:s.address,onChange:(t,r)=>m(l,n,{...s,address:r.value}),placeholder:"https://…"})}),e.jsx(c,{appearance:"subtle",size:"small",icon:e.jsx(T,{}),onClick:()=>O(l,n),"aria-label":"Remove step"})]},n)),e.jsx(c,{appearance:"subtle",size:"small",icon:e.jsx(I,{}),onClick:()=>$(l),children:"Add step"}),e.jsx(p,{size:100,style:{color:o.colorNeutralForeground3},children:"Info: EntityRule is valid for entity-scoped tabs. Use PageRule only for globally-scoped application ribbon tabs."})]},l)),e.jsx(c,{appearance:"subtle",icon:e.jsx(I,{}),onClick:_,children:"Add display rule"}),e.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:o.spacingHorizontalS,paddingTop:o.spacingHorizontalS},children:[e.jsx(c,{appearance:"secondary",onClick:h,children:"Cancel"}),e.jsx(c,{appearance:"primary",onClick:q,children:"Save rules"})]})]})})]})};export{re as TabDisplayRulesPanel,re as default};
@@ -0,0 +1 @@
1
+ import{z as e,h as D,co as M,cq as L,y as $}from"./fluent-icons-DxKNRZ1A.js";import{a as n,R as A}from"./monaco-Bx8A1Vm1.js";import{a as k}from"./index-Bu7BlRFk.js";import{D as F,h as I,j as _,i as T,aa as X,B as c,k as H,F as u,I as j,a1 as O,T as i,t as l,S as V,l as E}from"./fluent-ui-D7EtYwEg.js";import"./dnd-fsSwRnQv.js";const q=$({surface:{width:"720px",maxWidth:"95vw",maxHeight:"84vh",height:"84vh"},body:{display:"flex",flexDirection:"column",gap:l.spacingHorizontalM,overflowY:"auto"},paramRow:{display:"flex",alignItems:"flex-end",gap:l.spacingHorizontalS},urlPreview:{fontFamily:l.fontFamilyMonospace,fontSize:l.fontSizeBase200,backgroundColor:l.colorNeutralBackground3,padding:`${l.spacingVerticalXS} ${l.spacingHorizontalS}`,borderRadius:l.borderRadiusMedium,wordBreak:"break-all",border:`1px solid ${l.colorNeutralStroke2}`},passParamsTable:{display:"grid",gridTemplateColumns:"120px 1fr",gap:`${l.spacingVerticalXS} ${l.spacingHorizontalS}`,fontSize:l.fontSizeBase200},warnNote:{backgroundColor:l.colorStatusWarningBackground1,borderRadius:l.borderRadiusMedium,padding:`${l.spacingVerticalXS} ${l.spacingHorizontalS}`,fontSize:l.fontSizeBase100}}),f=[{key:"typename",desc:"Logical name of the table"},{key:"type",desc:"Entity type code (integer — may vary between orgs)"},{key:"id",desc:"GUID of the primary record"},{key:"orgname",desc:"Unique organization name"},{key:"userlcid",desc:"User's language LCID"},{key:"orglcid",desc:"Organization's base language LCID"}],W=[{label:"New tab (Navigate)",value:"0"},{label:"Dialog",value:"1"},{label:"Popup",value:"2"}],Z=()=>{const r=q(),S=k(a=>a.urlComposerOpen),d=k(a=>a.closeUrlComposer),[t,z]=n.useState("https://"),[p,C]=n.useState(!1),[w,R]=n.useState("0"),[h,g]=n.useState([]),x=n.useMemo(()=>{const a=[...h].filter(s=>s.key.trim()).map(s=>`${encodeURIComponent(s.key)}={${s.value||s.key}}`);return p&&f.forEach(s=>{a.push(`${s.key}={${s.key}}`)}),a.length>0?`${t}?${a.join("&")}`:t},[t,p,h]),U=n.useMemo(()=>x.replace(/&/g,"&amp;"),[x]),N=()=>{g(a=>[...a,{key:"",value:""}])},P=a=>{g(s=>s.filter((m,o)=>o!==a))},v=(a,s,m)=>{g(o=>o.map((b,B)=>B===a?{...b,[s]:m}:b))},y=t.startsWith("https://");return e.jsx(F,{open:S,onOpenChange:(a,s)=>!s.open&&d(),children:e.jsx(I,{className:r.surface,children:e.jsxs(_,{style:{height:"100%"},children:[e.jsx(T,{action:e.jsx(c,{appearance:"subtle",icon:e.jsx(D,{}),onClick:d,"aria-label":"Close"}),children:e.jsx(X,{children:"URL Action Composer"})}),e.jsxs(H,{className:r.body,children:[e.jsx(u,{label:"Base URL",required:!0,validationState:y?"none":"error",validationMessage:y?void 0:"URL must start with https://",children:e.jsx(j,{value:t,onChange:(a,s)=>z(s.value),placeholder:"https://contoso.com/page"})}),e.jsxs("div",{className:r.warnNote,children:["⚠ Ampersands in URLs must be escaped as ",e.jsx("code",{children:"&amp;"})," in XML. CBS handles this automatically when generating XML."]}),e.jsx(O,{label:"PassParams — append standard record context parameters",checked:p,onChange:(a,s)=>C(s.checked)}),p&&e.jsxs("div",{children:[e.jsx(i,{size:200,weight:"semibold",children:"Standard PassParams:"}),e.jsx("div",{className:r.passParamsTable,children:f.map(a=>e.jsxs(A.Fragment,{children:[e.jsx("code",{style:{fontFamily:l.fontFamilyMonospace,fontSize:l.fontSizeBase200},children:a.key}),e.jsx(i,{size:100,style:{color:l.colorNeutralForeground3},children:a.desc})]},a.key))}),e.jsxs(i,{size:100,style:{color:l.colorStatusWarningForeground1,marginTop:l.spacingVerticalXS,display:"block"},children:["Note: Use ",e.jsx("code",{children:"typename"})," instead of ",e.jsx("code",{children:"type"})," for reliability — type codes can differ between environments."]})]}),e.jsxs("div",{children:[e.jsx(i,{weight:"semibold",size:200,children:"Custom query parameters"}),e.jsxs(i,{size:100,style:{color:l.colorNeutralForeground3,display:"block",marginBottom:l.spacingVerticalXS},children:["Each parameter becomes a querystring key=value pair. Use CRM tokens like"," ",e.jsx("code",{children:"{id}"}),"."]}),h.map((a,s)=>e.jsxs("div",{className:r.paramRow,style:{marginBottom:l.spacingHorizontalXS},children:[e.jsx(u,{label:"Key",style:{flex:1},children:e.jsx(j,{size:"small",value:a.key,onChange:(m,o)=>v(s,"key",o.value),placeholder:"paramName"})}),e.jsx(u,{label:"Value / token",style:{flex:1},children:e.jsx(j,{size:"small",value:a.value,onChange:(m,o)=>v(s,"value",o.value),placeholder:"static value or {id}"})}),e.jsx(c,{appearance:"subtle",size:"small",icon:e.jsx(M,{}),onClick:()=>P(s),"aria-label":"Remove parameter",style:{marginBottom:"4px"}})]},s)),e.jsx(c,{appearance:"subtle",size:"small",icon:e.jsx(L,{}),onClick:N,children:"Add parameter"})]}),e.jsx(u,{label:"Open in",children:e.jsx(V,{value:w,onChange:(a,s)=>R(s.value),children:W.map(a=>e.jsx("option",{value:a.value,children:a.label},a.value))})}),e.jsxs("div",{children:[e.jsx(i,{size:200,weight:"semibold",style:{display:"block",marginBottom:"4px"},children:"URL preview (tokens shown literally):"}),e.jsx("div",{className:r.urlPreview,children:x})]}),e.jsxs("div",{children:[e.jsxs(i,{size:200,weight:"semibold",style:{display:"block",marginBottom:"4px"},children:["XML-encoded URL (",e.jsx("code",{children:"&"})," → ",e.jsx("code",{children:"&amp;"}),"):"]}),e.jsx("div",{className:r.urlPreview,children:U})]})]}),e.jsxs(E,{children:[e.jsx(c,{appearance:"secondary",onClick:d,children:"Cancel"}),e.jsx(c,{appearance:"primary",disabled:!y,onClick:d,children:"Apply URL"})]})]})})})};export{Z as UrlComposerModal,Z as default};