@mohsinonxrm/pptb-commandbar-studio 0.7.0-beta.2 → 0.7.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.
- package/CHANGELOG.md +65 -0
- package/README.md +1 -1
- package/SECURITY.md +10 -6
- package/dist/assets/{BulkPublishModal-dGiT6nNQ.js → BulkPublishModal-B0Ecmiq1.js} +1 -1
- package/dist/assets/{CommandEditorPanel-BfcpfNps.js → CommandEditorPanel-FdBZ2zNj.js} +1 -1
- package/dist/assets/{CommandPalette-C4NOIuA3.js → CommandPalette-BL4yGqtx.js} +1 -1
- package/dist/assets/{ConflictDrawer-CW1NLdAD.js → ConflictDrawer-DAQi31Y8.js} +1 -1
- package/dist/assets/{DiffViewer-R0g0dxLc.js → DiffViewer-DVIsuwXy.js} +1 -1
- package/dist/assets/{HideInsteadOfDeleteModal-DbfHSKmm.js → HideInsteadOfDeleteModal-BBfhx5dO.js} +1 -1
- package/dist/assets/{IconPickerModal-B1AgGWq0.js → IconPickerModal-D97ew6l_.js} +1 -1
- package/dist/assets/{ImportXmlModal-DImDI43_.js → ImportXmlModal-2-0E4Ib_.js} +1 -1
- package/dist/assets/{LocalizationEditor-CeAgqq85.js → LocalizationEditor-7sYCHKMx.js} +1 -1
- package/dist/assets/{MonacoEditor-BRCY30rO.js → MonacoEditor-DGzdcWNE.js} +1 -1
- package/dist/assets/{NewButtonModal-DqdSshXe.js → NewButtonModal-CKKbFpLd.js} +1 -1
- package/dist/assets/{NewGroupModal-VysrEsbU.js → NewGroupModal-BpXuxZKo.js} +1 -1
- package/dist/assets/{NewTabModal-ChEmOjmh.js → NewTabModal-CoBSto1f.js} +1 -1
- package/dist/assets/RuleEditorPanel-Dg2vnxrc.js +1 -0
- package/dist/assets/{ScalingEditorPanel-f2Rmk9AG.js → ScalingEditorPanel-L_j0ox4f.js} +1 -1
- package/dist/assets/{TabDisplayRulesPanel-DR-c2-Km.js → TabDisplayRulesPanel-W1SMJTlj.js} +1 -1
- package/dist/assets/{UrlComposerModal-DFwPOYL1.js → UrlComposerModal-BhcG5L1S.js} +1 -1
- package/dist/assets/{WebResourceBrowser-D2RMaFeZ.js → WebResourceBrowser-CQemLOXD.js} +1 -1
- package/dist/assets/{XmlDrawer-DXyRtGs1.js → XmlDrawer-BOOdH0HN.js} +1 -1
- package/dist/assets/{index-CKs2IGe0.js → index-DUEHURiA.js} +11 -11
- package/dist/assets/{useReplaceWebResourceConfirm-C4vg9hxg.js → useReplaceWebResourceConfirm-Mb36NTI7.js} +1 -1
- package/dist/assets/xmlValidator-BB2o3QUU.js +3 -0
- package/dist/icons/icon.svg +4 -7
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/dist/assets/RuleEditorPanel-C26e1gMH.js +0 -1
- package/dist/assets/xmlValidator-TOuV4jko.js +0 -3
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,71 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [0.7.0] - 2026-10-24
|
|
13
|
+
|
|
14
|
+
Publish safety and correctness. A publish follows the connection and names the environment it
|
|
15
|
+
writes to. It keeps changes made or imported elsewhere and the publisher's details, and cleans up
|
|
16
|
+
exactly what a delete leaves unused. **Show on Unified Interface** now targets Unified Interface.
|
|
17
|
+
This release is 0.7.0-beta.1 to beta.3, and their notes below are the full list. Requires Power
|
|
18
|
+
Platform ToolBox 1.2.7 or later, as 0.6 does.
|
|
19
|
+
|
|
20
|
+
### Highlights
|
|
21
|
+
|
|
22
|
+
- **Safety:**
|
|
23
|
+
- A publish follows a PPTB connection change and never continues into the newly selected
|
|
24
|
+
environment (#120).
|
|
25
|
+
- Every write names its environment, and Production asks for a typed confirmation (#121).
|
|
26
|
+
- Uploads ask before replacing a web resource.
|
|
27
|
+
- **Changes made elsewhere are kept:**
|
|
28
|
+
- A change published elsewhere during a publish isn't overwritten; the publish stops and says
|
|
29
|
+
what changed (#102).
|
|
30
|
+
- Ribbon changes imported elsewhere but not published are published first and kept (#103).
|
|
31
|
+
- **Correctness:**
|
|
32
|
+
- The publisher's e-mail, website and addresses are kept (#104).
|
|
33
|
+
- The base language is never assumed (#106).
|
|
34
|
+
- Deletes clean up exactly what they leave unused (#108).
|
|
35
|
+
- Copies keep labels other solutions define (#137).
|
|
36
|
+
- An unreadable layer is reported, with Retry (#110).
|
|
37
|
+
- Dynamic flyouts can be published (#101).
|
|
38
|
+
- **Unified Interface filter (#152):** **Show on Unified Interface (Modern)** adds
|
|
39
|
+
`Type="Modern"`. The old filter added `Refresh`, which hid the button in Unified Interface.
|
|
40
|
+
- **Editor:**
|
|
41
|
+
- XML drawer Copy and Download work in both hosts (#122).
|
|
42
|
+
- Shortcuts work with Shift, Caps Lock and other keyboard layouts (#123).
|
|
43
|
+
- Drafts (#129) and the Tables list (#5) are fixed.
|
|
44
|
+
- Rename is offered only where it can be published (#33).
|
|
45
|
+
- **Dependencies:** `npm audit` reports 0 vulnerabilities (#117).
|
|
46
|
+
|
|
47
|
+
### ⚠️ Upgrading from 0.6.x
|
|
48
|
+
|
|
49
|
+
- If you used **Show on Unified Interface (Refresh)**, the command has a
|
|
50
|
+
`<command id>.Refresh.DisplayRule`, and the button is hidden in Unified Interface. Click
|
|
51
|
+
**Show on Unified Interface (Modern)** to replace it, then publish (#152).
|
|
52
|
+
- Nothing else changes: the PPTB requirement and the published format are the same.
|
|
53
|
+
- **0.6.x is end of life:** 0.6.2 is deprecated on npm and gets no support window, since 0.7.0
|
|
54
|
+
needs the same PPTB (see `SECURITY.md`).
|
|
55
|
+
|
|
56
|
+
## [0.7.0-beta.3] - 2026-10-24
|
|
57
|
+
|
|
58
|
+
The third beta of 0.7.0 (npm `beta`): one fix. The **Show on Unified Interface** filter added a
|
|
59
|
+
rule that hid the button in Unified Interface. Requires Power Platform ToolBox 1.2.7 or later.
|
|
60
|
+
|
|
61
|
+
### 🔧 Fixed
|
|
62
|
+
|
|
63
|
+
- **Client-type filters target the right client (#152).** Unified Interface evaluates
|
|
64
|
+
`CommandClientTypeRule` as **`Modern`**: Microsoft's `Mscrm.ShowOnlyOnModern`
|
|
65
|
+
(`Type="Modern"`) shows a button there, and `Mscrm.HideOnModern` (`Type="Modern"` with
|
|
66
|
+
`InvertResult="true"`) hides it. CBS labelled `Refresh` as Unified Interface, so **Show on
|
|
67
|
+
Unified Interface (Refresh)** added a rule that **hid the button in Unified Interface**.
|
|
68
|
+
- The quick filter is now **Show on Unified Interface (Modern)**, and `Refresh` is labelled as
|
|
69
|
+
the legacy web client. New client-type steps default to `Modern`.
|
|
70
|
+
- A filter never reuses an inverted rule such as `Mscrm.HideOnModern`.
|
|
71
|
+
- Adding a filter replaces (unbinds) another client-type filter on the same command, because
|
|
72
|
+
display rules must all pass and two would hide the button everywhere.
|
|
73
|
+
- If you used the old filter, the command has a `<command id>.Refresh.DisplayRule` and the
|
|
74
|
+
button is hidden in Unified Interface. Click **Show on Unified Interface (Modern)** to replace
|
|
75
|
+
it, then publish. This affects 0.5.x–0.7.0-beta.2.
|
|
76
|
+
|
|
12
77
|
## [0.7.0-beta.2] - 2026-10-23
|
|
13
78
|
|
|
14
79
|
The second beta of 0.7.0 (npm `beta`): correctness. A publish keeps the publisher's details and
|
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ reimagined with React 18, Fluent UI v9, and live Dataverse integration via
|
|
|
37
37
|
- Command binding with action summary chips
|
|
38
38
|
- Display rules + Enable rules pill lists with inline add/remove
|
|
39
39
|
- Scaling summary with link to full editor
|
|
40
|
-
- Advanced: form ribbon scope selector, `Mscrm.OpenRecordItem` override toggle, client-type filter shortcuts
|
|
40
|
+
- Advanced: form ribbon scope selector, `Mscrm.OpenRecordItem` override toggle, client-type filter shortcuts (Unified Interface evaluates as `Modern`; one filter per command)
|
|
41
41
|
- Conflict banner — surfaces managed-solution provenance via solution-layer API
|
|
42
42
|
|
|
43
43
|
### ⚡ Command Editor
|
package/SECURITY.md
CHANGED
|
@@ -55,11 +55,15 @@ ToolBox (PPTB) and talks to Dataverse only through the host's
|
|
|
55
55
|
| Betas (npm `beta`) | Fixed in the next beta |
|
|
56
56
|
| Anything older | ❌ |
|
|
57
57
|
|
|
58
|
-
**Everything before 0.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
**Everything before 0.7.0 is deprecated on npm and gets no further fixes**, 0.6.x and
|
|
59
|
+
0.5.x included:
|
|
60
|
+
- **Before 0.6.2:** these versions bundle DOMPurify 3.2.7 (in the Monaco editor), which has
|
|
61
|
+
critical advisories.
|
|
62
|
+
- **0.6.x:** it gets no support window after 0.7.0, because 0.7.0 needs the same Power
|
|
63
|
+
Platform ToolBox (1.2.7). Update to 0.7.0.
|
|
64
|
+
|
|
65
|
+
Use 0.7.0 or later, which requires Power Platform ToolBox 1.2.7 or later; users on an older
|
|
66
|
+
PPTB need to update it. The previous-minor support window applies from 0.7 on, to 0.7.x after
|
|
67
|
+
0.8.0 ships. See [RELEASING.md](RELEASING.md) → *Supported versions*.
|
|
64
68
|
|
|
65
69
|
Thanks for helping keep the tool safe.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{y as t,z as jn}from"./fluent-icons-DUgjkNjy.js";import{p as je,m as Wn,g as Kn,n as ze,o as _n,q as Hn,r as Gn,t as Yn,v as Jn,x as Fe,y as Zn,z as Qn,A as es,B as ns,d as Se,D as ss,F as ts,G as os,H as cn,I as is,J as as,K as Me,L as rs,M as ls,N as O,k as qe,O as Ie,P as cs,Q as ds,R as dn,S as us,T as Oe,U as ms,V as un,W as hs,X as Rn,Y as G,Z as Sn,_ as ps,$ as Ve,a0 as bs,a as Ue,u as D,a1 as fs,a2 as gs,a3 as ys,a4 as mn}from"./index-CKs2IGe0.js";import{a as A,R as se}from"./monaco-BIO15LCS.js";import{w as ws,v as In}from"./xmlValidator-TOuV4jko.js";import{M as X,f as V,ae as xs,b as W,B as $n,F as Re,I as kn,t as E,D as Cs,i as vs,j as js,k as Rs,l as Ss,a5 as Is,ao as $s,O as hn,a1 as ks,a6 as Ps,d as Xe,ap as Ns,m as Ds}from"./fluent-ui-Dde22_ZN.js";import"./dnd-BmqIZ1-i.js";import"./ruleKinds-B9hACGaq.js";import"./crmParameters-rgfZhhzN.js";let pn=0;async function We(e){const n=typeof window<"u"?window.toolboxAPI:void 0;pn++===0&&await bn(()=>n?.preventClose?.());try{return await e()}finally{--pn===0&&await bn(()=>n?.releasePreventClose?.())}}const As=2e3;async function bn(e){let n;try{await Promise.race([e(),new Promise(o=>n=setTimeout(o,As))])}catch{}finally{clearTimeout(n)}}function me(e,n){const o=e.match(new RegExp(`\\s${n}="([^"]*)"`));return o?o[1]:null}function fn(e,n,o){const r=e.indexOf(o,n);return e.slice(n,r===-1?void 0:r).match(/<result\s[^>]*>/g)??[]}function gn(e){const n=e.find(o=>me(o,"result")!=="success");if(n){const o=me(n,"errorcode")??"",r=me(n,"errortext")??"unknown error";return{ok:!1,message:`Dataverse rejected the ribbon (${o}): ${r}`}}return null}function Es(e,n){if(!e)return{ok:!1,message:"The import job returned no result data, so the ribbon import could not be verified."};if(n.kind==="application"){const i=e.search(/<ribbon\s[^>]*processed="true"/);return i===-1?{ok:!1,message:"Import completed, but Dataverse did not process the application ribbon."}:gn(fn(e,i,"</ribbon>"))??{ok:!0,message:"Application ribbon imported."}}const o=new Set(n.names.filter(Boolean).map(i=>i.toLowerCase())),r=/<entityRibbon\s[^>]*>/g;let a;for(;a=r.exec(e);){const i=(me(a[0],"id")??"").toLowerCase();if(o.has(i))return me(a[0],"processed")!=="true"?{ok:!1,message:`Dataverse did not process the ribbon for ${i}.`}:gn(fn(e,a.index,"</entityRibbon>"))??{ok:!0,message:`Ribbon for ${i} imported.`}}return{ok:!1,message:`Import completed, but Dataverse did not apply a ribbon for ${n.names.join(" / ")} (no entityRibbon result in the import job). Nothing was changed.`}}const J=window.dataverseAPI;async function Ts(e,n,o){return await o("The import"),J.execute({operationName:"ImportSolution",operationType:"action",parameters:{CustomizationFile:e,ImportJobId:n,OverwriteUnmanagedCustomizations:!0,PublishWorkflows:!1}})}async function Ls(e,n){await n("Publishing");const o=e.map(r=>`<entity>${O(r)}</entity>`).join("");return J.execute({operationName:"PublishXml",operationType:"action",parameters:{ParameterXml:`<importexportxml><entities>${o}</entities></importexportxml>`}})}function yn(e){const n=e.data?.progress;return!!(typeof n=="object"&&n!==null&&n.completed===!0||typeof e.progress=="number"&&e.progress>=100||typeof n=="number"&&n>=100||e.completedon||e.data?.completedon||e.statuscode===30)}function zs(e){const n=e.titles.map(o=>`<Title languagecode="${o.languageCode}" description="${O(o.description)}"/>`).join("");return`<LocLabel Id="${O(e.id)}"><Titles>${n}</Titles></LocLabel>`}async function Pn(e){const n=e.entity?.logicalName??"{!EntityLogicalName}",o={deletedContainerIds:e.plan.deletedContainerIds??[],movedButtons:e.plan.movedButtons??[],editedLocLabelIds:e.plan.editedLocLabelIds??[],editedTabIds:e.plan.editedTabIds??[]},r=e.locLabels.filter(l=>o.editedLocLabelIds.includes(l.id)),a=e.languageCode??1033;for(const l of e.plan.renamedLabels??[]){const h=r.find(I=>I.id===l.id)??e.locLabels.find(I=>I.id===l.id),R=[{languageCode:a,description:l.text},...(h?.titles??[]).filter(I=>I.languageCode!==a)],y=r.findIndex(I=>I.id===l.id);y>=0?r[y]={id:l.id,titles:R}:r.push({id:l.id,titles:R})}let i=r.length?je(`<RibbonDiffXml><LocLabels>${r.map(zs).join("")}</LocLabels></RibbonDiffXml>`):Wn();for(const l of e.locations){const h=Kn({current:l.current,baseline:l.baseline,commands:e.commands,enableRules:e.enableRules,displayRules:e.displayRules,locLabels:e.locLabels,entityLogicalName:n,location:l.current.location,languageCode:e.languageCode});i=ze(i,je(h))}const d=[],u=[];for(const l of e.locations)for(const h of l.current.tabs){if(!o.editedTabIds.includes(h.id))continue;if(h.tabDisplayRules.length>0){const y=_n(h,e.entity===null);y&&u.push(y)}const R=new Set(h.tabDisplayRules.map(y=>y.tabCommand));for(const y of l.baseline.tabs.find(I=>I.id===h.id)?.tabDisplayRules??[])R.has(y.tabCommand)||d.push(y.tabCommand)}u.length>0&&(i=ze(i,je(`<RibbonDiffXml><RuleDefinitions><TabDisplayRules>${u.join("")}</TabDisplayRules></RuleDefinitions></RibbonDiffXml>`)));const f=[...e.commands.filter(l=>e.plan.editedCommandIds.includes(l.id)).map(Hn)],$={enable:e.enableRules.filter(l=>e.plan.editedEnableRuleIds.includes(l.id)).map(Yn),display:e.displayRules.filter(l=>e.plan.editedDisplayRuleIds.includes(l.id)).map(Gn)};(f.length||$.enable.length||$.display.length)&&(i=ze(i,je(`<RibbonDiffXml><CommandDefinitions>${f.join("")}</CommandDefinitions><RuleDefinitions><DisplayRules>${$.display.join("")}</DisplayRules><EnableRules>${$.enable.join("")}</EnableRules></RuleDefinitions></RibbonDiffXml>`)));const S=(l,h)=>{for(const R of Array.from(l.keys()))h.includes(R)||l.delete(R)},v=e.locations.flatMap(l=>l.current.tabs.filter(h=>!l.baseline.tabs.some(R=>R.id===h.id)).map(Jn));S(i.commandDefinitions,[...e.plan.editedCommandIds,...v]),S(i.enableRules,e.plan.editedEnableRuleIds),S(i.displayRules,e.plan.editedDisplayRuleIds);const m=await Fe(e.entity?.logicalName??null),C=Zn(m),b=e.plan.deletedButtonIds.filter(l=>!C.has(l));if(b.length>0)throw new Error(`Can't delete ${b.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 w=Qn(m),P=o.deletedContainerIds.filter(l=>!w.has(l));if(P.length>0)throw new Error(`Can't delete ${P.join(", ")}: not added by this table's unmanaged customizations (it comes from a managed solution or the platform). Undo the delete.`);const j=o.movedButtons.filter(l=>!C.has(l.id)).map(l=>l.id);if(j.length>0)throw new Error(`Can't move ${j.join(", ")}: not defined in this table's unmanaged customizations. Undo the move.`);const q=es(m),Z=(e.plan.uncustomisedCommandIds??[]).filter(l=>m.commandDefinitions.has(l)&&!ns(l,q));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 K=new Set;for(const l of e.locations)for(const h of l.current.tabs)for(const R of h.groups)for(const y of Se(R))for(const I of ss(y))K.add(I);const Q=e.plan.uncustomisedCommandIds??[],Y=new Set,ee=new Set;for(const l of e.commands)if(!(!K.has(l.id)||Q.includes(l.id))){l.enableRules.forEach(h=>Y.add(h)),l.displayRules.forEach(h=>ee.add(h));for(const h of l.rawRuleRefs??[]){const R=/^\s*<(EnableRule|DisplayRule)\b[^>]*?\sId="([^"]+)"/.exec(h.xml);R&&(R[1]==="EnableRule"?Y:ee).add(R[2])}}let k=ts(m,i,{retainedCommandIds:K,editedCommandIds:e.plan.editedCommandIds,editedEnableRuleIds:e.plan.editedEnableRuleIds,editedDisplayRuleIds:e.plan.editedDisplayRuleIds,deletedControlIds:e.plan.deletedButtonIds,unhiddenControlIds:e.plan.unhiddenButtonIds,deletedContainerIds:o.deletedContainerIds,movedControls:o.movedButtons,removedTabCommands:d,uncustomisedCommandIds:Q,retainedEnableRuleIds:Y,retainedDisplayRuleIds:ee});for(const l of e.plan.renamedLabels??[])l.newLabel&&(k=os(k,l.containerId,`$LocLabels:${l.id}`));const c=new Set([...cn(m),...cn(k)].map(l=>l.id)),g={};for(const l of e.locations)for(const[h,R]of Object.entries(l.baseline.scalingByTab??{}))g[h]={maxSizes:R.maxSizes.filter(y=>!c.has(y.id)).map(y=>y.sequence),scales:R.scales.filter(y=>!c.has(y.id)).map(y=>y.sequence)};const L=is(k,g);if(L.problems.length>0)throw new Error(`Not published: ${L.problems.join("; ")}.`);return k=L.parts,{scalingChanges:L.changes,xml:rs(k),parts:k,elementCount:Me(k),preservedCount:Me(m),changedCount:Me(i),changedKeys:as(m,k),newKeys:Object.keys(k).flatMap(l=>Array.from(k[l].keys()).filter(h=>!m[l].has(h)).map(h=>`${l}:${h}`)),layerDefinitionIds:{commandIds:Array.from(m.commandDefinitions.keys()),enableRuleIds:Array.from(m.enableRules.keys()),displayRuleIds:Array.from(m.displayRules.keys())},layer:m}}function Nn(e,n){const o=[],r={},a={},i={},d={},u=new Set,f=new Set,$=new Set;for(const{current:m,baseline:C}of e.locations)for(const b of[C,m])for(const w of b.tabs)for(const P of w.groups)for(const j of Se(P))for(const q of j.menu?.sections??[])$.add(q.controlsId);for(const{current:m,baseline:C}of e.locations){Object.assign(i,C.templateLayouts);for(const b of C.tabs){o.push(b.id),b.label&&(d[b.id]={Title:b.label});for(const w of b.groups){u.add(w.id),o.push(w.id),w.label&&(d[w.id]={Title:w.label,Label:w.label});for(const P of Se(w))o.push(P.id),P.source&&(d[P.id]=P.source.attributes)}}for(const b of m.tabs)for(const w of b.groups)f.add(w.id);for(const b of[C,m])for(const w of b.tabs)for(const P of w.groups)P.template&&(a[P.id]=P.template)}const S=m=>u.has(m.groupId)&&!f.has(m.groupId);for(const{baseline:m}of e.locations)for(const[C,b]of Object.entries(m.scalingByTab??{}))r[C]={...b,maxSizes:b.maxSizes.filter(w=>!S(w)),scales:b.scales.filter(w=>!S(w))};const v=(m,C)=>{if(!m)return;const b=new Set(C??[]);return m.map(w=>w.id).filter(w=>!b.has(w))};return{changedKeys:n.changedKeys,newKeys:n.newKeys,commands:e.commands,known:{commandIds:v(e.baselineCommands,n.layerDefinitionIds?.commandIds),enableRuleIds:v(e.baselineEnableRules,n.layerDefinitionIds?.enableRuleIds),displayRuleIds:v(e.baselineDisplayRules,n.layerDefinitionIds?.displayRuleIds),elementIds:o},loadedAttributes:d,publisherPrefix:e.publisherPrefix,tabScaling:r,groupTemplates:a,templateLayouts:i,menuControlsIds:$,...e.entity?{places:{entityLogicalName:e.entity.logicalName,tabByCollection:Object.fromEntries(ls(e.locations.map(m=>m.baseline),e.entity.logicalName))}}:{}}}function Ms(e,n){return new Promise((o,r)=>{const a=setTimeout(()=>r(new Error(`it didn't finish within ${Math.round(n/1e3)} s`)),n);e.then(i=>{clearTimeout(a),o(i)},i=>{clearTimeout(a),r(i)})})}async function wn(e,n={}){const o=await Pn(e),r=Nn(e,o),a=[],i=ws(o.parts);if(n.lookupWebResources&&i.length>0)try{r.webResources=await n.lookupWebResources(i)}catch(d){a.push({severity:"warning",code:"webresource-lookup",message:`Couldn't check the ${i.length} referenced web resource(s): ${d instanceof Error?d.message:String(d)}`})}return{findings:[...In(o.parts,r),...a],xml:o.xml}}async function Os(e,n,o={}){const r=o.attempts??3,a=o.contentKeys??[];let i={missing:[],unexpected:[],differing:[]};for(let u=0;u<r;u++){u>0&&await new Promise(f=>setTimeout(f,o.delayMs??5e3));try{i=Rn(n,await Fe(e),{contentKeys:a})}catch(f){return{ok:!1,missing:[],unexpected:[],differing:[],message:`Couldn't read the published ribbon layer to verify it (${f instanceof Error?f.message:String(f)}).`}}if(i.missing.length===0&&i.unexpected.length===0&&i.differing.length===0){const f=a.length;return{ok:!0,...i,message:"Verified: the published ribbon layer has every element that was imported"+(f>0?`, and the ${f} element(s) this publish changed have the imported content.`:".")}}}const d=u=>u.slice(0,5).join(", ")+(u.length>5?", …":"");return{ok:!1,...i,message:"The published ribbon layer doesn't match what was imported"+(i.missing.length?`; missing: ${d(i.missing)}`:"")+(i.unexpected.length?`; unexpected: ${d(i.unexpected)}`:"")+(i.differing.length?`; different content: ${d(i.differing)}`:"")+". Reload the table and check before publishing again."}}class Be extends Error{constructor(n,o,r=!1){const a=r?"another solution import ran in the environment meanwhile, and what it changed may not be published yet":Dn(o);super(r?`${n}'s ribbon customizations may have changed in Dataverse since you started publishing: ${a}. Importing could overwrite that change, so nothing was imported. Publish again: the table is published first, so the change is kept.`:`${n}'s ribbon customizations changed in Dataverse since you started publishing (${a}): other ribbon changes for it were published meanwhile, from another session, tool or solution import. Importing would overwrite that change, so nothing was imported. Reload the table to get the change, then publish again.`),this.scopeLabel=n,this.changes=o,this.importRan=r,this.name="RibbonLayerChangedError",this.summary=a}scopeLabel;changes;importRan;summary}function Dn(e){const n=o=>o.slice(0,5).join(", ")+(o.length>5?", …":"");return[e.unexpected.length?`added: ${n(e.unexpected)}`:"",e.missing.length?`removed: ${n(e.missing)}`:"",e.differing.length?`changed: ${n(e.differing)}`:""].filter(Boolean).join("; ")}function Us(e){const n=e instanceof Error?e.message:String(e);return/there is (?:another|a previous) \[(\w+)\] running/i.exec(n)?.[1]??null}const Xs=e=>Object.keys(e).flatMap(n=>Array.from(e[n].keys()).map(o=>`${n}:${o}`));function An(e,n){const o=[],r=[],a=[];for(const i of Object.keys(e)){for(const[d,u]of e[i]){const f=n[i].get(d);f===void 0?o.push(`${i}:${d}`):f!==u&&a.push(`${i}:${d}`)}for(const d of n[i].keys())e[i].has(d)||r.push(`${i}:${d}`)}return{missing:o,unexpected:r,differing:a}}const En=e=>e.missing.length+e.unexpected.length+e.differing.length>0;async function Vs(e,n,o,r){const a=r.kind==="imported"?r.attempts??3:1;let i={missing:[],unexpected:[],differing:[]};for(let d=0;d<a;d++){d>0&&r.kind==="imported"&&await new Promise(f=>setTimeout(f,r.delayMs??5e3));const u=await Fe(e);if(i=r.kind==="read"?An(o,u):Rn(o,u,{contentKeys:Xs(o)}),!En(i))return}throw new Be(n,i)}function xn(e,n){return We(()=>Bs(e,n))}async function Bs(e,n){const o=e.guard??qe(),r=Ie.getState(),a=e.entity?e.entity.logicalName:"Application ribbon",i={onProgress:n,...e.busy},d=e.entity===null;if(d&&!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 u=async(c="Publishing customizations…")=>{n?.(c),await un("Publish",async()=>{d?(await o("Publishing"),await J.execute({operationName:"PublishXml",operationType:"action",parameters:{ParameterXml:"<importexportxml><ribbons><ribbon></ribbon></ribbons></importexportxml>"}})):await Ls([e.entity.logicalName],o)},i)},f=e.languageCode??await cs(),$=async c=>{n?.(`Reading existing ribbon customizations for ${a}…`),c&&r.logInfo("publish",`Reading unmanaged ribbon layer for ${a}.`);const g=await Pn({...e,languageCode:f}),L=In(g.parts,Nn({...e,publisherPrefix:e.solution.publisherPrefix},g)),l=L.filter(h=>h.severity==="error");if(c||l.length>0){r.logInfo("publish",`RibbonDiffXml for ${a}: ${g.preservedCount} existing element(s) preserved, ${g.changedCount} element(s) from this session, ${g.elementCount} total.`);for(const h of g.scalingChanges)r.logWarn("publish",ms(h));for(const h of L)h.severity==="warning"&&r.logWarn("publish",h.message)}if(l.length>0){for(const h of l)r.logError("publish",h.message);throw new Error(`The pre-publish check found ${l.length} error(s), so nothing was imported: `+l.map(h=>h.message).join("; "))}return g},S=e.publishCustomizations!==!1?await $(!1):null;n?.("Checking that no other solution operation is running…"),await ds(i);const v=await Ws(e.solution);let m=!1;const C=c=>(S&&!m&&c instanceof Error&&(c.message+=` (${a} was published first, so customizations imported elsewhere for it and not yet published are now published.)`),c);if(S){r.logInfo("publish",`Publishing ${a} first, so ribbon changes imported elsewhere but not yet published are kept.`);try{await u(`Publishing ${a} first (keeps changes imported elsewhere but not published)…`)}catch(c){throw c instanceof Error&&(c.message=`Publishing ${a} first failed, so nothing was imported: ${c.message}`),c}}let b;try{b=await $(!0)}catch(c){throw S&&c instanceof Error&&!c.message.startsWith("The pre-publish check")&&(c.message=`${a}'s customizations changed when it was published first (changes imported elsewhere and not yet published): ${c.message} Reload the table to get them, then publish again.`),C(c)}if(S){const c=An(S.layer,b.layer);En(c)&&r.logInfo("publish",`Publishing ${a} first published ribbon changes imported elsewhere (${Dn(c)}); they are kept.`)}const w=e.entity?.schemaName||e.entity?.logicalName||"",P=d?dn({applicationRibbonDiffXml:b.xml}):dn({entities:[{schemaName:w,localizedName:e.entity?.displayName||w,ribbonDiffXml:b.xml}]}),j=d?[{type:50,schemaName:":RibbonDiffXml",behavior:0}]:[{type:1,schemaName:e.entity.logicalName,behavior:2}],q=Hs({...e.solution,languageCode:f,rootComponents:j,details:v});n?.("Packaging solution ZIP…");const Z=us({"customizations.xml":Oe(P),"solution.xml":Oe(q),"[Content_Types].xml":Oe('<?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 K="";for(let c=0;c<Z.length;c++)K+=String.fromCharCode(Z[c]);const Q=btoa(K),Y=async(c,g)=>{n?.(`Importing ${a} ribbon${c}…`);const L=crypto.randomUUID();r.logInfo("publish",`Importing solution${c} (import job ${L})…`);let l=!1;await un("Import",async()=>{if(await o("Importing"),l)throw new Be(a,{missing:[],unexpected:[],differing:[]},!0);await Vs(e.entity?.logicalName??null,a,g.layer,g.as);try{await Ts(Q,L,o)}catch(N){throw hs(N)&&Us(N)?.toLowerCase()==="import"&&(l=!0),N}m=!0},i);const h=150,R=2e3;let y=await J.getImportJobStatus(L),I=0;for(;!yn(y)&&I<h;)await new Promise(N=>setTimeout(N,R)),y=await J.getImportJobStatus(L),I++,I%10===0&&n?.(`Still importing… (${I*2}s elapsed)`);if(!yn(y))throw new Error(`Solution import did not complete within ${h*R/1e3} seconds. Check Solutions › History for import job ${L}.`);n?.("Verifying the import…");const $e=await J.retrieve("importjob",L,["data"]),B=Es($e.data,d?{kind:"application"}:{kind:"entity",names:[w,e.entity.logicalName]});if(!B.ok)throw r.logError("publish",B.message),new Error(B.message);return r.logInfo("publish",B.message),L};let ee;try{ee=await Y("",{layer:b.layer,as:{kind:"read"}})}catch(c){throw C(c)}let k;if(e.publishCustomizations!==!1){await u();{r.logInfo("publish","Refreshing Unified Interface command-bar metadata (second import of the same package)…");try{await Y(" (refreshing Unified Interface metadata)",{layer:b.parts,as:{kind:"imported",delayMs:e.verifyDelayMs}}),await u()}catch(c){if(c instanceof Be)k={ok:!1,...c.changes,message:`Your changes were imported and published, but ${a}'s ribbon customizations changed in Dataverse after that (${c.summary}): other changes were published meanwhile. They weren't imported a second time to refresh Unified Interface's command-bar metadata, since that would overwrite the other change, so new or changed buttons may not appear in the app until the table's ribbon is published again. Reload the table to see the other change.`},r.logWarn("publish",k.message);else throw new Error(`Your changes were imported and published, but refreshing Unified Interface's command-bar metadata failed (${c instanceof Error?c.message:String(c)}). New or changed buttons may not appear in the app until you publish again.`)}}k||(n?.("Verifying the published ribbon…"),k=await Os(e.entity?.logicalName??null,b.parts,{delayMs:e.verifyDelayMs,contentKeys:b.changedKeys}),k.ok?r.logInfo("publish",k.message):r.logWarn("publish",k.message))}else r.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 n?.(e.publishCustomizations!==!1?`${a} ribbon published.`:`${a} ribbon imported (not published).`),{elementCount:b.elementCount,preservedCount:b.preservedCount,importJobId:ee,verification:k,parts:b.parts,changedKeys:b.changedKeys}}function Fs(e,n){return We(()=>qs(e,n))}async function qs(e,n){const o=n?.guard??qe(),r=Ie.getState(),a=n?.pollIntervalMs??2e3,i=n?.timeoutMs??600*1e3;e?.("Starting asynchronous publish (PublishAllXmlAsync)..."),r.logInfo("publish","Calling PublishAllXmlAsync action."),await o("Publishing");const u=(await J.execute({operationName:"PublishAllXmlAsync",operationType:"action"}))?.AsyncOperationId;if(!u)throw new Error("PublishAllXmlAsync did not return AsyncOperationId.");r.logInfo("publish",`PublishAllXmlAsync job id: ${u}`),e?.("Async publish job started. Waiting for completion...");const f=Date.now();let $=0,S;for(;Date.now()-f<i;){$+=1;const v=await J.retrieve("asyncoperation",u,["asyncoperationid","statecode","statuscode","name","message","friendlymessage","completedon"]);if(S=v.statuscode,v.statecode===3||!!v.completedon){if(typeof v.statuscode=="number"&&v.statuscode!==30){const C=v.friendlymessage||v.message||`statuscode=${v.statuscode}`;throw new Error(`Asynchronous publish failed: ${C}`)}return e?.("Asynchronous publish completed successfully."),r.logInfo("publish",`PublishAllXmlAsync completed in ${$} poll(s).`),{asyncOperationId:u,statusCode:v.statuscode}}e?.(`Waiting for async publish job... (poll ${$})`),await new Promise(C=>setTimeout(C,a))}throw new Error(`Asynchronous publish timed out after ${Math.round(i/1e3)} seconds (last status: ${S??"unknown"}).`)}const Tn=[["AddressTypeCode","addresstypecode"],["City","city"],["County","county"],["Country","country"],["Fax","fax"],["FreightTermsCode","freighttermscode"],["Latitude","latitude"],["Line1","line1"],["Line2","line2"],["Line3","line3"],["Longitude","longitude"],["Name","name"],["PostalCode","postalcode"],["PostOfficeBox","postofficebox"],["PrimaryContactName","primarycontactname"],["ShippingMethodCode","shippingmethodcode"],["StateOrProvince","stateorprovince"],["Telephone1","telephone1"],["Telephone2","telephone2"],["Telephone3","telephone3"],["UPSZone","upszone"],["UTCOffset","utcoffset"],["UTCConversionTimeZoneCode","utcconversiontimezonecode"]];async function Ws(e){let n;try{n=(await J.queryData(`solutions?$select=description&$expand=publisherid&$filter=uniquename eq '${e.uniqueName.replace(/'/g,"''")}'`)).value?.[0]}catch(d){throw new Error(`Couldn't read solution ${e.uniqueName} and its publisher (${d instanceof Error?d.message:String(d)}), so nothing was imported: an import without them would clear the publisher's details.`)}const o=n?.publisherid;if(!n||!o)throw new Error(`Couldn't read solution ${e.uniqueName} and its publisher, so nothing was imported: an import without them would clear the publisher's details.`);const r=o.customizationoptionvalueprefix;if(typeof r!="number")throw new Error(`Couldn't read the option-value prefix of publisher ${e.publisherUniqueName}, so nothing was imported: a wrong one would change the publisher.`);const a=d=>typeof d=="string"?d:"",i=[1,2].map(d=>Object.fromEntries(Tn.map(([,u])=>[u,o[`address${d}_${u}`]]).filter(([,u])=>u!=null&&u!==""))).map((d,u)=>({number:u+1,...d}));return{solutionDescription:a(n.description),publisherDescription:a(o.description),publisherEmail:a(o.emailaddress),publisherWebsite:a(o.supportingwebsiteurl),publisherOptionValuePrefix:r,publisherAddresses:i.filter(d=>Object.keys(d).length>1)}}const Ks=e=>O(e).replace(/\r/g,"
").replace(/\n/g,"
").replace(/\t/g,"	"),Cn=(e,n)=>e?`<Descriptions>
|
|
1
|
+
import{y as t,z as jn}from"./fluent-icons-DUgjkNjy.js";import{p as je,m as Wn,g as Kn,n as ze,o as _n,q as Hn,r as Gn,t as Yn,v as Jn,x as Fe,y as Zn,z as Qn,A as es,B as ns,d as Se,D as ss,F as ts,G as os,H as cn,I as is,J as as,K as Me,L as rs,M as ls,N as O,k as qe,O as Ie,P as cs,Q as ds,R as dn,S as us,T as Oe,U as ms,V as un,W as hs,X as Rn,Y as G,Z as Sn,_ as ps,$ as Ve,a0 as bs,a as Ue,u as D,a1 as fs,a2 as gs,a3 as ys,a4 as mn}from"./index-DUEHURiA.js";import{a as A,R as se}from"./monaco-BIO15LCS.js";import{w as ws,v as In}from"./xmlValidator-BB2o3QUU.js";import{M as X,f as V,ae as xs,b as W,B as $n,F as Re,I as kn,t as E,D as Cs,i as vs,j as js,k as Rs,l as Ss,a5 as Is,ao as $s,O as hn,a1 as ks,a6 as Ps,d as Xe,ap as Ns,m as Ds}from"./fluent-ui-Dde22_ZN.js";import"./dnd-BmqIZ1-i.js";import"./ruleKinds-B9hACGaq.js";import"./crmParameters-rgfZhhzN.js";let pn=0;async function We(e){const n=typeof window<"u"?window.toolboxAPI:void 0;pn++===0&&await bn(()=>n?.preventClose?.());try{return await e()}finally{--pn===0&&await bn(()=>n?.releasePreventClose?.())}}const As=2e3;async function bn(e){let n;try{await Promise.race([e(),new Promise(o=>n=setTimeout(o,As))])}catch{}finally{clearTimeout(n)}}function me(e,n){const o=e.match(new RegExp(`\\s${n}="([^"]*)"`));return o?o[1]:null}function fn(e,n,o){const r=e.indexOf(o,n);return e.slice(n,r===-1?void 0:r).match(/<result\s[^>]*>/g)??[]}function gn(e){const n=e.find(o=>me(o,"result")!=="success");if(n){const o=me(n,"errorcode")??"",r=me(n,"errortext")??"unknown error";return{ok:!1,message:`Dataverse rejected the ribbon (${o}): ${r}`}}return null}function Es(e,n){if(!e)return{ok:!1,message:"The import job returned no result data, so the ribbon import could not be verified."};if(n.kind==="application"){const i=e.search(/<ribbon\s[^>]*processed="true"/);return i===-1?{ok:!1,message:"Import completed, but Dataverse did not process the application ribbon."}:gn(fn(e,i,"</ribbon>"))??{ok:!0,message:"Application ribbon imported."}}const o=new Set(n.names.filter(Boolean).map(i=>i.toLowerCase())),r=/<entityRibbon\s[^>]*>/g;let a;for(;a=r.exec(e);){const i=(me(a[0],"id")??"").toLowerCase();if(o.has(i))return me(a[0],"processed")!=="true"?{ok:!1,message:`Dataverse did not process the ribbon for ${i}.`}:gn(fn(e,a.index,"</entityRibbon>"))??{ok:!0,message:`Ribbon for ${i} imported.`}}return{ok:!1,message:`Import completed, but Dataverse did not apply a ribbon for ${n.names.join(" / ")} (no entityRibbon result in the import job). Nothing was changed.`}}const J=window.dataverseAPI;async function Ts(e,n,o){return await o("The import"),J.execute({operationName:"ImportSolution",operationType:"action",parameters:{CustomizationFile:e,ImportJobId:n,OverwriteUnmanagedCustomizations:!0,PublishWorkflows:!1}})}async function Ls(e,n){await n("Publishing");const o=e.map(r=>`<entity>${O(r)}</entity>`).join("");return J.execute({operationName:"PublishXml",operationType:"action",parameters:{ParameterXml:`<importexportxml><entities>${o}</entities></importexportxml>`}})}function yn(e){const n=e.data?.progress;return!!(typeof n=="object"&&n!==null&&n.completed===!0||typeof e.progress=="number"&&e.progress>=100||typeof n=="number"&&n>=100||e.completedon||e.data?.completedon||e.statuscode===30)}function zs(e){const n=e.titles.map(o=>`<Title languagecode="${o.languageCode}" description="${O(o.description)}"/>`).join("");return`<LocLabel Id="${O(e.id)}"><Titles>${n}</Titles></LocLabel>`}async function Pn(e){const n=e.entity?.logicalName??"{!EntityLogicalName}",o={deletedContainerIds:e.plan.deletedContainerIds??[],movedButtons:e.plan.movedButtons??[],editedLocLabelIds:e.plan.editedLocLabelIds??[],editedTabIds:e.plan.editedTabIds??[]},r=e.locLabels.filter(l=>o.editedLocLabelIds.includes(l.id)),a=e.languageCode??1033;for(const l of e.plan.renamedLabels??[]){const h=r.find(I=>I.id===l.id)??e.locLabels.find(I=>I.id===l.id),R=[{languageCode:a,description:l.text},...(h?.titles??[]).filter(I=>I.languageCode!==a)],y=r.findIndex(I=>I.id===l.id);y>=0?r[y]={id:l.id,titles:R}:r.push({id:l.id,titles:R})}let i=r.length?je(`<RibbonDiffXml><LocLabels>${r.map(zs).join("")}</LocLabels></RibbonDiffXml>`):Wn();for(const l of e.locations){const h=Kn({current:l.current,baseline:l.baseline,commands:e.commands,enableRules:e.enableRules,displayRules:e.displayRules,locLabels:e.locLabels,entityLogicalName:n,location:l.current.location,languageCode:e.languageCode});i=ze(i,je(h))}const d=[],u=[];for(const l of e.locations)for(const h of l.current.tabs){if(!o.editedTabIds.includes(h.id))continue;if(h.tabDisplayRules.length>0){const y=_n(h,e.entity===null);y&&u.push(y)}const R=new Set(h.tabDisplayRules.map(y=>y.tabCommand));for(const y of l.baseline.tabs.find(I=>I.id===h.id)?.tabDisplayRules??[])R.has(y.tabCommand)||d.push(y.tabCommand)}u.length>0&&(i=ze(i,je(`<RibbonDiffXml><RuleDefinitions><TabDisplayRules>${u.join("")}</TabDisplayRules></RuleDefinitions></RibbonDiffXml>`)));const f=[...e.commands.filter(l=>e.plan.editedCommandIds.includes(l.id)).map(Hn)],$={enable:e.enableRules.filter(l=>e.plan.editedEnableRuleIds.includes(l.id)).map(Yn),display:e.displayRules.filter(l=>e.plan.editedDisplayRuleIds.includes(l.id)).map(Gn)};(f.length||$.enable.length||$.display.length)&&(i=ze(i,je(`<RibbonDiffXml><CommandDefinitions>${f.join("")}</CommandDefinitions><RuleDefinitions><DisplayRules>${$.display.join("")}</DisplayRules><EnableRules>${$.enable.join("")}</EnableRules></RuleDefinitions></RibbonDiffXml>`)));const S=(l,h)=>{for(const R of Array.from(l.keys()))h.includes(R)||l.delete(R)},v=e.locations.flatMap(l=>l.current.tabs.filter(h=>!l.baseline.tabs.some(R=>R.id===h.id)).map(Jn));S(i.commandDefinitions,[...e.plan.editedCommandIds,...v]),S(i.enableRules,e.plan.editedEnableRuleIds),S(i.displayRules,e.plan.editedDisplayRuleIds);const m=await Fe(e.entity?.logicalName??null),C=Zn(m),b=e.plan.deletedButtonIds.filter(l=>!C.has(l));if(b.length>0)throw new Error(`Can't delete ${b.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 w=Qn(m),P=o.deletedContainerIds.filter(l=>!w.has(l));if(P.length>0)throw new Error(`Can't delete ${P.join(", ")}: not added by this table's unmanaged customizations (it comes from a managed solution or the platform). Undo the delete.`);const j=o.movedButtons.filter(l=>!C.has(l.id)).map(l=>l.id);if(j.length>0)throw new Error(`Can't move ${j.join(", ")}: not defined in this table's unmanaged customizations. Undo the move.`);const q=es(m),Z=(e.plan.uncustomisedCommandIds??[]).filter(l=>m.commandDefinitions.has(l)&&!ns(l,q));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 K=new Set;for(const l of e.locations)for(const h of l.current.tabs)for(const R of h.groups)for(const y of Se(R))for(const I of ss(y))K.add(I);const Q=e.plan.uncustomisedCommandIds??[],Y=new Set,ee=new Set;for(const l of e.commands)if(!(!K.has(l.id)||Q.includes(l.id))){l.enableRules.forEach(h=>Y.add(h)),l.displayRules.forEach(h=>ee.add(h));for(const h of l.rawRuleRefs??[]){const R=/^\s*<(EnableRule|DisplayRule)\b[^>]*?\sId="([^"]+)"/.exec(h.xml);R&&(R[1]==="EnableRule"?Y:ee).add(R[2])}}let k=ts(m,i,{retainedCommandIds:K,editedCommandIds:e.plan.editedCommandIds,editedEnableRuleIds:e.plan.editedEnableRuleIds,editedDisplayRuleIds:e.plan.editedDisplayRuleIds,deletedControlIds:e.plan.deletedButtonIds,unhiddenControlIds:e.plan.unhiddenButtonIds,deletedContainerIds:o.deletedContainerIds,movedControls:o.movedButtons,removedTabCommands:d,uncustomisedCommandIds:Q,retainedEnableRuleIds:Y,retainedDisplayRuleIds:ee});for(const l of e.plan.renamedLabels??[])l.newLabel&&(k=os(k,l.containerId,`$LocLabels:${l.id}`));const c=new Set([...cn(m),...cn(k)].map(l=>l.id)),g={};for(const l of e.locations)for(const[h,R]of Object.entries(l.baseline.scalingByTab??{}))g[h]={maxSizes:R.maxSizes.filter(y=>!c.has(y.id)).map(y=>y.sequence),scales:R.scales.filter(y=>!c.has(y.id)).map(y=>y.sequence)};const L=is(k,g);if(L.problems.length>0)throw new Error(`Not published: ${L.problems.join("; ")}.`);return k=L.parts,{scalingChanges:L.changes,xml:rs(k),parts:k,elementCount:Me(k),preservedCount:Me(m),changedCount:Me(i),changedKeys:as(m,k),newKeys:Object.keys(k).flatMap(l=>Array.from(k[l].keys()).filter(h=>!m[l].has(h)).map(h=>`${l}:${h}`)),layerDefinitionIds:{commandIds:Array.from(m.commandDefinitions.keys()),enableRuleIds:Array.from(m.enableRules.keys()),displayRuleIds:Array.from(m.displayRules.keys())},layer:m}}function Nn(e,n){const o=[],r={},a={},i={},d={},u=new Set,f=new Set,$=new Set;for(const{current:m,baseline:C}of e.locations)for(const b of[C,m])for(const w of b.tabs)for(const P of w.groups)for(const j of Se(P))for(const q of j.menu?.sections??[])$.add(q.controlsId);for(const{current:m,baseline:C}of e.locations){Object.assign(i,C.templateLayouts);for(const b of C.tabs){o.push(b.id),b.label&&(d[b.id]={Title:b.label});for(const w of b.groups){u.add(w.id),o.push(w.id),w.label&&(d[w.id]={Title:w.label,Label:w.label});for(const P of Se(w))o.push(P.id),P.source&&(d[P.id]=P.source.attributes)}}for(const b of m.tabs)for(const w of b.groups)f.add(w.id);for(const b of[C,m])for(const w of b.tabs)for(const P of w.groups)P.template&&(a[P.id]=P.template)}const S=m=>u.has(m.groupId)&&!f.has(m.groupId);for(const{baseline:m}of e.locations)for(const[C,b]of Object.entries(m.scalingByTab??{}))r[C]={...b,maxSizes:b.maxSizes.filter(w=>!S(w)),scales:b.scales.filter(w=>!S(w))};const v=(m,C)=>{if(!m)return;const b=new Set(C??[]);return m.map(w=>w.id).filter(w=>!b.has(w))};return{changedKeys:n.changedKeys,newKeys:n.newKeys,commands:e.commands,known:{commandIds:v(e.baselineCommands,n.layerDefinitionIds?.commandIds),enableRuleIds:v(e.baselineEnableRules,n.layerDefinitionIds?.enableRuleIds),displayRuleIds:v(e.baselineDisplayRules,n.layerDefinitionIds?.displayRuleIds),elementIds:o},loadedAttributes:d,publisherPrefix:e.publisherPrefix,tabScaling:r,groupTemplates:a,templateLayouts:i,menuControlsIds:$,...e.entity?{places:{entityLogicalName:e.entity.logicalName,tabByCollection:Object.fromEntries(ls(e.locations.map(m=>m.baseline),e.entity.logicalName))}}:{}}}function Ms(e,n){return new Promise((o,r)=>{const a=setTimeout(()=>r(new Error(`it didn't finish within ${Math.round(n/1e3)} s`)),n);e.then(i=>{clearTimeout(a),o(i)},i=>{clearTimeout(a),r(i)})})}async function wn(e,n={}){const o=await Pn(e),r=Nn(e,o),a=[],i=ws(o.parts);if(n.lookupWebResources&&i.length>0)try{r.webResources=await n.lookupWebResources(i)}catch(d){a.push({severity:"warning",code:"webresource-lookup",message:`Couldn't check the ${i.length} referenced web resource(s): ${d instanceof Error?d.message:String(d)}`})}return{findings:[...In(o.parts,r),...a],xml:o.xml}}async function Os(e,n,o={}){const r=o.attempts??3,a=o.contentKeys??[];let i={missing:[],unexpected:[],differing:[]};for(let u=0;u<r;u++){u>0&&await new Promise(f=>setTimeout(f,o.delayMs??5e3));try{i=Rn(n,await Fe(e),{contentKeys:a})}catch(f){return{ok:!1,missing:[],unexpected:[],differing:[],message:`Couldn't read the published ribbon layer to verify it (${f instanceof Error?f.message:String(f)}).`}}if(i.missing.length===0&&i.unexpected.length===0&&i.differing.length===0){const f=a.length;return{ok:!0,...i,message:"Verified: the published ribbon layer has every element that was imported"+(f>0?`, and the ${f} element(s) this publish changed have the imported content.`:".")}}}const d=u=>u.slice(0,5).join(", ")+(u.length>5?", …":"");return{ok:!1,...i,message:"The published ribbon layer doesn't match what was imported"+(i.missing.length?`; missing: ${d(i.missing)}`:"")+(i.unexpected.length?`; unexpected: ${d(i.unexpected)}`:"")+(i.differing.length?`; different content: ${d(i.differing)}`:"")+". Reload the table and check before publishing again."}}class Be extends Error{constructor(n,o,r=!1){const a=r?"another solution import ran in the environment meanwhile, and what it changed may not be published yet":Dn(o);super(r?`${n}'s ribbon customizations may have changed in Dataverse since you started publishing: ${a}. Importing could overwrite that change, so nothing was imported. Publish again: the table is published first, so the change is kept.`:`${n}'s ribbon customizations changed in Dataverse since you started publishing (${a}): other ribbon changes for it were published meanwhile, from another session, tool or solution import. Importing would overwrite that change, so nothing was imported. Reload the table to get the change, then publish again.`),this.scopeLabel=n,this.changes=o,this.importRan=r,this.name="RibbonLayerChangedError",this.summary=a}scopeLabel;changes;importRan;summary}function Dn(e){const n=o=>o.slice(0,5).join(", ")+(o.length>5?", …":"");return[e.unexpected.length?`added: ${n(e.unexpected)}`:"",e.missing.length?`removed: ${n(e.missing)}`:"",e.differing.length?`changed: ${n(e.differing)}`:""].filter(Boolean).join("; ")}function Us(e){const n=e instanceof Error?e.message:String(e);return/there is (?:another|a previous) \[(\w+)\] running/i.exec(n)?.[1]??null}const Xs=e=>Object.keys(e).flatMap(n=>Array.from(e[n].keys()).map(o=>`${n}:${o}`));function An(e,n){const o=[],r=[],a=[];for(const i of Object.keys(e)){for(const[d,u]of e[i]){const f=n[i].get(d);f===void 0?o.push(`${i}:${d}`):f!==u&&a.push(`${i}:${d}`)}for(const d of n[i].keys())e[i].has(d)||r.push(`${i}:${d}`)}return{missing:o,unexpected:r,differing:a}}const En=e=>e.missing.length+e.unexpected.length+e.differing.length>0;async function Vs(e,n,o,r){const a=r.kind==="imported"?r.attempts??3:1;let i={missing:[],unexpected:[],differing:[]};for(let d=0;d<a;d++){d>0&&r.kind==="imported"&&await new Promise(f=>setTimeout(f,r.delayMs??5e3));const u=await Fe(e);if(i=r.kind==="read"?An(o,u):Rn(o,u,{contentKeys:Xs(o)}),!En(i))return}throw new Be(n,i)}function xn(e,n){return We(()=>Bs(e,n))}async function Bs(e,n){const o=e.guard??qe(),r=Ie.getState(),a=e.entity?e.entity.logicalName:"Application ribbon",i={onProgress:n,...e.busy},d=e.entity===null;if(d&&!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 u=async(c="Publishing customizations…")=>{n?.(c),await un("Publish",async()=>{d?(await o("Publishing"),await J.execute({operationName:"PublishXml",operationType:"action",parameters:{ParameterXml:"<importexportxml><ribbons><ribbon></ribbon></ribbons></importexportxml>"}})):await Ls([e.entity.logicalName],o)},i)},f=e.languageCode??await cs(),$=async c=>{n?.(`Reading existing ribbon customizations for ${a}…`),c&&r.logInfo("publish",`Reading unmanaged ribbon layer for ${a}.`);const g=await Pn({...e,languageCode:f}),L=In(g.parts,Nn({...e,publisherPrefix:e.solution.publisherPrefix},g)),l=L.filter(h=>h.severity==="error");if(c||l.length>0){r.logInfo("publish",`RibbonDiffXml for ${a}: ${g.preservedCount} existing element(s) preserved, ${g.changedCount} element(s) from this session, ${g.elementCount} total.`);for(const h of g.scalingChanges)r.logWarn("publish",ms(h));for(const h of L)h.severity==="warning"&&r.logWarn("publish",h.message)}if(l.length>0){for(const h of l)r.logError("publish",h.message);throw new Error(`The pre-publish check found ${l.length} error(s), so nothing was imported: `+l.map(h=>h.message).join("; "))}return g},S=e.publishCustomizations!==!1?await $(!1):null;n?.("Checking that no other solution operation is running…"),await ds(i);const v=await Ws(e.solution);let m=!1;const C=c=>(S&&!m&&c instanceof Error&&(c.message+=` (${a} was published first, so customizations imported elsewhere for it and not yet published are now published.)`),c);if(S){r.logInfo("publish",`Publishing ${a} first, so ribbon changes imported elsewhere but not yet published are kept.`);try{await u(`Publishing ${a} first (keeps changes imported elsewhere but not published)…`)}catch(c){throw c instanceof Error&&(c.message=`Publishing ${a} first failed, so nothing was imported: ${c.message}`),c}}let b;try{b=await $(!0)}catch(c){throw S&&c instanceof Error&&!c.message.startsWith("The pre-publish check")&&(c.message=`${a}'s customizations changed when it was published first (changes imported elsewhere and not yet published): ${c.message} Reload the table to get them, then publish again.`),C(c)}if(S){const c=An(S.layer,b.layer);En(c)&&r.logInfo("publish",`Publishing ${a} first published ribbon changes imported elsewhere (${Dn(c)}); they are kept.`)}const w=e.entity?.schemaName||e.entity?.logicalName||"",P=d?dn({applicationRibbonDiffXml:b.xml}):dn({entities:[{schemaName:w,localizedName:e.entity?.displayName||w,ribbonDiffXml:b.xml}]}),j=d?[{type:50,schemaName:":RibbonDiffXml",behavior:0}]:[{type:1,schemaName:e.entity.logicalName,behavior:2}],q=Hs({...e.solution,languageCode:f,rootComponents:j,details:v});n?.("Packaging solution ZIP…");const Z=us({"customizations.xml":Oe(P),"solution.xml":Oe(q),"[Content_Types].xml":Oe('<?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 K="";for(let c=0;c<Z.length;c++)K+=String.fromCharCode(Z[c]);const Q=btoa(K),Y=async(c,g)=>{n?.(`Importing ${a} ribbon${c}…`);const L=crypto.randomUUID();r.logInfo("publish",`Importing solution${c} (import job ${L})…`);let l=!1;await un("Import",async()=>{if(await o("Importing"),l)throw new Be(a,{missing:[],unexpected:[],differing:[]},!0);await Vs(e.entity?.logicalName??null,a,g.layer,g.as);try{await Ts(Q,L,o)}catch(N){throw hs(N)&&Us(N)?.toLowerCase()==="import"&&(l=!0),N}m=!0},i);const h=150,R=2e3;let y=await J.getImportJobStatus(L),I=0;for(;!yn(y)&&I<h;)await new Promise(N=>setTimeout(N,R)),y=await J.getImportJobStatus(L),I++,I%10===0&&n?.(`Still importing… (${I*2}s elapsed)`);if(!yn(y))throw new Error(`Solution import did not complete within ${h*R/1e3} seconds. Check Solutions › History for import job ${L}.`);n?.("Verifying the import…");const $e=await J.retrieve("importjob",L,["data"]),B=Es($e.data,d?{kind:"application"}:{kind:"entity",names:[w,e.entity.logicalName]});if(!B.ok)throw r.logError("publish",B.message),new Error(B.message);return r.logInfo("publish",B.message),L};let ee;try{ee=await Y("",{layer:b.layer,as:{kind:"read"}})}catch(c){throw C(c)}let k;if(e.publishCustomizations!==!1){await u();{r.logInfo("publish","Refreshing Unified Interface command-bar metadata (second import of the same package)…");try{await Y(" (refreshing Unified Interface metadata)",{layer:b.parts,as:{kind:"imported",delayMs:e.verifyDelayMs}}),await u()}catch(c){if(c instanceof Be)k={ok:!1,...c.changes,message:`Your changes were imported and published, but ${a}'s ribbon customizations changed in Dataverse after that (${c.summary}): other changes were published meanwhile. They weren't imported a second time to refresh Unified Interface's command-bar metadata, since that would overwrite the other change, so new or changed buttons may not appear in the app until the table's ribbon is published again. Reload the table to see the other change.`},r.logWarn("publish",k.message);else throw new Error(`Your changes were imported and published, but refreshing Unified Interface's command-bar metadata failed (${c instanceof Error?c.message:String(c)}). New or changed buttons may not appear in the app until you publish again.`)}}k||(n?.("Verifying the published ribbon…"),k=await Os(e.entity?.logicalName??null,b.parts,{delayMs:e.verifyDelayMs,contentKeys:b.changedKeys}),k.ok?r.logInfo("publish",k.message):r.logWarn("publish",k.message))}else r.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 n?.(e.publishCustomizations!==!1?`${a} ribbon published.`:`${a} ribbon imported (not published).`),{elementCount:b.elementCount,preservedCount:b.preservedCount,importJobId:ee,verification:k,parts:b.parts,changedKeys:b.changedKeys}}function Fs(e,n){return We(()=>qs(e,n))}async function qs(e,n){const o=n?.guard??qe(),r=Ie.getState(),a=n?.pollIntervalMs??2e3,i=n?.timeoutMs??600*1e3;e?.("Starting asynchronous publish (PublishAllXmlAsync)..."),r.logInfo("publish","Calling PublishAllXmlAsync action."),await o("Publishing");const u=(await J.execute({operationName:"PublishAllXmlAsync",operationType:"action"}))?.AsyncOperationId;if(!u)throw new Error("PublishAllXmlAsync did not return AsyncOperationId.");r.logInfo("publish",`PublishAllXmlAsync job id: ${u}`),e?.("Async publish job started. Waiting for completion...");const f=Date.now();let $=0,S;for(;Date.now()-f<i;){$+=1;const v=await J.retrieve("asyncoperation",u,["asyncoperationid","statecode","statuscode","name","message","friendlymessage","completedon"]);if(S=v.statuscode,v.statecode===3||!!v.completedon){if(typeof v.statuscode=="number"&&v.statuscode!==30){const C=v.friendlymessage||v.message||`statuscode=${v.statuscode}`;throw new Error(`Asynchronous publish failed: ${C}`)}return e?.("Asynchronous publish completed successfully."),r.logInfo("publish",`PublishAllXmlAsync completed in ${$} poll(s).`),{asyncOperationId:u,statusCode:v.statuscode}}e?.(`Waiting for async publish job... (poll ${$})`),await new Promise(C=>setTimeout(C,a))}throw new Error(`Asynchronous publish timed out after ${Math.round(i/1e3)} seconds (last status: ${S??"unknown"}).`)}const Tn=[["AddressTypeCode","addresstypecode"],["City","city"],["County","county"],["Country","country"],["Fax","fax"],["FreightTermsCode","freighttermscode"],["Latitude","latitude"],["Line1","line1"],["Line2","line2"],["Line3","line3"],["Longitude","longitude"],["Name","name"],["PostalCode","postalcode"],["PostOfficeBox","postofficebox"],["PrimaryContactName","primarycontactname"],["ShippingMethodCode","shippingmethodcode"],["StateOrProvince","stateorprovince"],["Telephone1","telephone1"],["Telephone2","telephone2"],["Telephone3","telephone3"],["UPSZone","upszone"],["UTCOffset","utcoffset"],["UTCConversionTimeZoneCode","utcconversiontimezonecode"]];async function Ws(e){let n;try{n=(await J.queryData(`solutions?$select=description&$expand=publisherid&$filter=uniquename eq '${e.uniqueName.replace(/'/g,"''")}'`)).value?.[0]}catch(d){throw new Error(`Couldn't read solution ${e.uniqueName} and its publisher (${d instanceof Error?d.message:String(d)}), so nothing was imported: an import without them would clear the publisher's details.`)}const o=n?.publisherid;if(!n||!o)throw new Error(`Couldn't read solution ${e.uniqueName} and its publisher, so nothing was imported: an import without them would clear the publisher's details.`);const r=o.customizationoptionvalueprefix;if(typeof r!="number")throw new Error(`Couldn't read the option-value prefix of publisher ${e.publisherUniqueName}, so nothing was imported: a wrong one would change the publisher.`);const a=d=>typeof d=="string"?d:"",i=[1,2].map(d=>Object.fromEntries(Tn.map(([,u])=>[u,o[`address${d}_${u}`]]).filter(([,u])=>u!=null&&u!==""))).map((d,u)=>({number:u+1,...d}));return{solutionDescription:a(n.description),publisherDescription:a(o.description),publisherEmail:a(o.emailaddress),publisherWebsite:a(o.supportingwebsiteurl),publisherOptionValuePrefix:r,publisherAddresses:i.filter(d=>Object.keys(d).length>1)}}const Ks=e=>O(e).replace(/\r/g,"
").replace(/\n/g,"
").replace(/\t/g,"	"),Cn=(e,n)=>e?`<Descriptions>
|
|
2
2
|
<Description description="${Ks(e)}" languagecode="${n}"/>
|
|
3
3
|
</Descriptions>`:"<Descriptions/>",_s=e=>e.length===0?"<Addresses/>":`<Addresses>${e.map(n=>`
|
|
4
4
|
<Address>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{y as e,h as R,z as Ae,cq as de}from"./fluent-icons-DUgjkNjy.js";import{a as N,u as x,i as Pe,b as Be,d as We,C as $e,w as Le,E as Te,e as Oe,f as Ve,h as He,j as Ue,k as _e}from"./index-CKs2IGe0.js";import{a as m}from"./monaco-BIO15LCS.js";import{C as ue}from"./CrmParameterEditor-CQD0gNNH.js";import{M as Xe}from"./MonacoEditor-BRCY30rO.js";import{ai as Je,aj as qe,ak as Ge,b as d,t as n,d as u,al as Ye,ac as Ke,ad as S,a7 as _,F as j,S as X,B as M,M as y,f as C,I as B}from"./fluent-ui-Dde22_ZN.js";import"./dnd-BmqIZ1-i.js";import"./crmParameters-rgfZhhzN.js";const Qe=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}}),os=()=>{const r=Qe(),W=N(s=>s.commandEditorOpen),z=N(s=>s.commandEditorId),I=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),G=x(s=>s.displayRules),Y=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),[E,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&&I()},[W,z,l,I]);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)}},Ee=async()=>{if(!E||ee===null||!w)return;const s=_e();k(!0),g(null),O(null);try{const a=await Ue(w,Se(re),ze(w),{displayName:w.split("/").pop(),guard:s});O(a.solutionWarning??null),D(!1)}catch(a){g(a instanceof Error?a.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]})},Fe=(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(M,{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:E?"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(Xe,{language:"javascript",value:re,readOnly:!E,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"}),E&&e.jsx(Te,{prefix:"Saves to"}),E&&e.jsx(u,{appearance:"primary",size:"small",onClick:()=>{Ee()},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(M,{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(M,{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(M,{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)=>Fe(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"?Y:G).map(t=>t.id).filter(t=>!a.includes(t)),i=s==="enable"?ve:ye,c=()=>{const t=new Set([...Y.map(U=>U.id),...G.map(U=>U.id)]),h=Oe("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(M,{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(Je,{position:"end",open:W,onOpenChange:()=>I(),className:r.drawer,children:[e.jsx(qe,{children:e.jsx(Ge,{action:e.jsx(u,{appearance:"subtle",icon:e.jsx(R,{}),onClick:I,"aria-label":"Close command editor"}),children:e.jsx(d,{size:400,weight:"semibold",style:{fontFamily:n.fontFamilyMonospace},children:l.id})})}),e.jsxs(Ye,{className:r.body,children:[e.jsxs(Ke,{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{os as CommandEditorPanel,os as default};
|
|
1
|
+
import{y as e,h as R,z as Ae,cq as de}from"./fluent-icons-DUgjkNjy.js";import{a as N,u as x,i as Pe,b as Be,d as We,C as $e,w as Le,E as Te,e as Oe,f as Ve,h as He,j as Ue,k as _e}from"./index-DUEHURiA.js";import{a as m}from"./monaco-BIO15LCS.js";import{C as ue}from"./CrmParameterEditor-CQD0gNNH.js";import{M as Xe}from"./MonacoEditor-DGzdcWNE.js";import{ai as Je,aj as qe,ak as Ge,b as d,t as n,d as u,al as Ye,ac as Ke,ad as S,a7 as _,F as j,S as X,B as M,M as y,f as C,I as B}from"./fluent-ui-Dde22_ZN.js";import"./dnd-BmqIZ1-i.js";import"./crmParameters-rgfZhhzN.js";const Qe=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}}),os=()=>{const r=Qe(),W=N(s=>s.commandEditorOpen),z=N(s=>s.commandEditorId),I=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),G=x(s=>s.displayRules),Y=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),[E,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&&I()},[W,z,l,I]);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)}},Ee=async()=>{if(!E||ee===null||!w)return;const s=_e();k(!0),g(null),O(null);try{const a=await Ue(w,Se(re),ze(w),{displayName:w.split("/").pop(),guard:s});O(a.solutionWarning??null),D(!1)}catch(a){g(a instanceof Error?a.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]})},Fe=(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(M,{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:E?"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(Xe,{language:"javascript",value:re,readOnly:!E,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"}),E&&e.jsx(Te,{prefix:"Saves to"}),E&&e.jsx(u,{appearance:"primary",size:"small",onClick:()=>{Ee()},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(M,{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(M,{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(M,{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)=>Fe(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"?Y:G).map(t=>t.id).filter(t=>!a.includes(t)),i=s==="enable"?ve:ye,c=()=>{const t=new Set([...Y.map(U=>U.id),...G.map(U=>U.id)]),h=Oe("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(M,{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(Je,{position:"end",open:W,onOpenChange:()=>I(),className:r.drawer,children:[e.jsx(qe,{children:e.jsx(Ge,{action:e.jsx(u,{appearance:"subtle",icon:e.jsx(R,{}),onClick:I,"aria-label":"Close command editor"}),children:e.jsx(d,{size:400,weight:"semibold",style:{fontFamily:n.fontFamilyMonospace},children:l.id})})}),e.jsxs(Ye,{className:r.body,children:[e.jsxs(Ke,{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{os as CommandEditorPanel,os as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{y as a,E as te,z as oe}from"./fluent-icons-DUgjkNjy.js";import{a as u}from"./monaco-BIO15LCS.js";import{a as s,u as c,Y as ae,am as ne,aa as f,ah as se,an as ie,d as le}from"./index-
|
|
1
|
+
import{y as a,E as te,z as oe}from"./fluent-icons-DUgjkNjy.js";import{a as u}from"./monaco-BIO15LCS.js";import{a as s,u as c,Y as ae,am as ne,aa as f,ah as se,an as ie,d as le}from"./index-DUEHURiA.js";import{t,B as re,b as C}from"./fluent-ui-Dde22_ZN.js";import"./dnd-BmqIZ1-i.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(),x=s(e=>e.commandPaletteOpen),N=s(e=>e.setCommandPaletteOpen),X=s(e=>e.openBulkPublish),D=s(e=>e.openXmlDrawer),p=s(e=>e.openImportXml),T=s(e=>e.openCommandEditor),v=s(e=>e.openRuleEditor),H=s(e=>e.openNewGroup),O=s(e=>e.openNewButton),P=s(e=>e.openLocalizationEditor),$=s(e=>e.themeMode),W=s(e=>e.setThemeMode),G=c(e=>e.undo),V=c(e=>e.redo),F=c(e=>e.commands),U=c(e=>e.displayRules),q=c(e=>e.enableRules),I=c(e=>e.ribbons),K=ae(e=>e.entities),A=ne(e=>e.requestEntitySwitch),Q=f(e=>e.location),Y=f(e=>e.tabId),b=f(e=>e.selectedButtonId),j=f(e=>e.selectedGroupId),[l,z]=u.useState(""),[k,d]=u.useState(0),E=u.useRef(null),n=u.useCallback(()=>{N(!1),z(""),d(0)},[N]);u.useEffect(()=>{x&&setTimeout(()=>E.current?.focus(),50)},[x]);const Z=()=>{const e=[],r=I[Q].tabs.find(o=>o.id===Y),_=r?.groups[0]?.id??null,w=j??_,R=se(ie(r?.groups.find(o=>o.id===j),b)?.kind),ee=[{id:"publish",label:"Publish all",subtitle:"Save and publish changes to Dataverse",kind:"action",action:()=>{X(),n()}},{id:"view-xml",label:"View RibbonDiffXml",subtitle:"Open XML drawer",kind:"action",action:()=>{D(),n()}},{id:"import-xml",label:"Import XML",subtitle:"Import RibbonDiffXml from clipboard",kind:"action",action:()=>{n();const o="Couldn't read the clipboard here: paste the XML into the editor (Ctrl+V).",h=navigator.clipboard?.readText?.();if(!h)return p("",o);h.then(g=>g.trim().startsWith("<")?p(g):p("","The clipboard doesn't hold XML: paste the XML into the editor."),()=>p("",o))}},{id:"new-group",label:"New group",subtitle:"Create a new ribbon group in current tab",kind:"action",action:()=>{H(),n()}},{id:"new-button",label:"New button",subtitle:w?"Create a new button in selected/current group":"Select a tab/group with at least one group first",kind:"action",action:()=>{w&&(O(w),n())}},{id:"edit-labels",label:"Edit localized labels",subtitle:R?"The selected control is shown read-only":b?"Open localization editor for selected button":"Select a button first",kind:"action",action:()=>{!b||R||(P(b),n())}},{id:"toggle-theme",label:`Toggle theme (${$==="dark"?"Dark":"Light"})`,subtitle:"Switch between light and dark",kind:"action",action:()=>{W($==="dark"?"light":"dark"),n()}},{id:"undo",label:"Undo",subtitle:"Ctrl+Z",kind:"action",action:()=>{G(),n()}},{id:"redo",label:"Redo",subtitle:"Ctrl+Shift+Z",kind:"action",action:()=>{V(),n()}}];if(e.push(...ee),!l.startsWith("@")&&!l.startsWith("/")){const o=Object.entries(I).flatMap(([h,g])=>g.tabs.flatMap(B=>B.groups.flatMap(L=>le(L).map(y=>({id:`btn-${y.id}`,label:y.label||y.id,subtitle:`${h} → ${B.label} → ${L.label}`,kind:"button",action:()=>{n()}})))));e.push(...o.slice(0,20))}return F.forEach(o=>{e.push({id:`cmd-${o.id}`,label:o.id,subtitle:`${o.actions.length} action(s)`,kind:"command",action:()=>{T(o.id),n()}})}),U.forEach(o=>{e.push({id:`dr-${o.id}`,label:o.id,subtitle:`Display rule — ${o.steps.length} step(s)`,kind:"rule",action:()=>{v(o.id,"display"),n()}})}),q.forEach(o=>{e.push({id:`er-${o.id}`,label:o.id,subtitle:`Enable rule — ${o.steps.length} step(s)`,kind:"rule",action:()=>{v(o.id,"enable"),n()}})}),(l.startsWith("@")||!l)&&K.slice(0,30).forEach(o=>{e.push({id:`ent-${o.logicalName}`,label:o.displayName,subtitle:o.logicalName,kind:"entity",action:()=>{A(o),n()}})}),e},S=l.startsWith("@")||l.startsWith("/")?l.slice(1):l,M=Z(),m=S?M.filter(e=>e.label.toLowerCase().includes(S.toLowerCase())||(e.subtitle??"").toLowerCase().includes(S.toLowerCase())):M,J=e=>{e.key==="ArrowDown"?(e.preventDefault(),d(r=>Math.min(r+1,m.length-1))):e.key==="ArrowUp"?(e.preventDefault(),d(r=>Math.max(r-1,0))):e.key==="Enter"?m[k]?.action():e.key==="Escape"&&n()};return x?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:E,className:i.searchInput,value:l,onChange:e=>{z(e.target.value),d(0)},onKeyDown:J,placeholder:"Search commands, buttons, entities… Use @ for entities, / for actions","aria-label":"Command palette search"})]}),a.jsxs("div",{className:i.results,role:"listbox",children:[m.map((e,r)=>a.jsxs("div",{className:`${i.item} ${r===k?i.itemSelected:""}`,onClick:e.action,role:"option","aria-selected":r===k,onMouseEnter:()=>d(r),children:[a.jsx(re,{appearance:"outline",size:"small",children:e.kind}),a.jsxs("div",{className:i.itemLabel,children:[a.jsx(C,{children:e.label}),e.subtitle&&a.jsx(C,{className:i.itemSub,block:!0,children:e.subtitle})]})]},e.id)),m.length===0&&a.jsx("div",{className:i.item,children:a.jsx(C,{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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{y as e,h as k,bM as C,b6 as D,z as M}from"./fluent-icons-DUgjkNjy.js";import{a as c}from"./monaco-BIO15LCS.js";import{a as u,u as B}from"./index-
|
|
1
|
+
import{y as e,h as k,bM as C,b6 as D,z as M}from"./fluent-icons-DUgjkNjy.js";import{a as c}from"./monaco-BIO15LCS.js";import{a as u,u as B}from"./index-DUEHURiA.js";import{ai as I,aj as R,ak as H,aa as L,d as N,al as E,b as a,t as o,M as h,f as x,a5 as F,B as z,T as O}from"./fluent-ui-Dde22_ZN.js";import"./dnd-BmqIZ1-i.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};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./monaco-BIO15LCS.js","./monaco-DdLsZAcA.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{R as g,a as b,_ as H}from"./monaco-BIO15LCS.js";import{y as s,h as E,z as C}from"./fluent-icons-DUgjkNjy.js";import{a as x,u,g as N}from"./index-
|
|
2
|
+
import{R as g,a as b,_ as H}from"./monaco-BIO15LCS.js";import{y as s,h as E,z as C}from"./fluent-icons-DUgjkNjy.js";import{a as x,u,g as N}from"./index-DUEHURiA.js";import{ai as O,aj as _,ak as V,aa as $,d as S,al as X,M as I,f as T,b as A,B as D,a5 as G,t as r}from"./fluent-ui-Dde22_ZN.js";import"./dnd-BmqIZ1-i.js";const P=g.lazy(()=>H(()=>import("./monaco-BIO15LCS.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
3
|
`),c=o.split(`
|
|
4
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
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(`
|
package/dist/assets/{HideInsteadOfDeleteModal-DbfHSKmm.js → HideInsteadOfDeleteModal-BBfhx5dO.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{y as r}from"./fluent-icons-DUgjkNjy.js";import{a as i,u as n,aD as u,aE as c,an as b}from"./index-
|
|
1
|
+
import{y as r}from"./fluent-icons-DUgjkNjy.js";import{a as i,u as n,aD as u,aE as c,an as b}from"./index-DUEHURiA.js";import"./monaco-BIO15LCS.js";import"./fluent-ui-Dde22_ZN.js";import"./dnd-BmqIZ1-i.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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{y as o,h as ge,E as Y,L as pe,z as me}from"./fluent-icons-DUgjkNjy.js";import{u as he}from"./useReplaceWebResourceConfirm-C4vg9hxg.js";import{a as Z,u as be,aa as j,Y as Q,l as K,as as fe,at as J,au as ye,E as we,j as Se,av as xe,O as D,aw as ke,ax as Ce,ay as ve,k as L}from"./index-CKs2IGe0.js";import{a as l,R as ee}from"./monaco-BIO15LCS.js";import{D as Re,i as je,k as Ie,j as Be,aa as Ae,d as I,l as Ne,ac as Pe,ad as W,I as M,C as $e,O as Te,a1 as Ee,t as r,b as p,B as Fe,m as ze}from"./fluent-ui-Dde22_ZN.js";import"./dnd-BmqIZ1-i.js";const De=[{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"]}],Le=["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(n){for(const y of De)if(y.keywords.some(m=>n.includes(m)))return y.category;return"General"}const oe=Le.map(n=>({name:n,category:We(n)})),Me=["All",...Array.from(new Set(oe.map(n=>n.category))).sort()],He=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:r.spacingHorizontalS},toolbar:{display:"flex",alignItems:"center",gap:r.spacingHorizontalS,flexWrap:"wrap",flexShrink:0},categoryPicker:{minWidth:"180px",maxWidth:"220px"},iconGrid:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(72px, 1fr))",gap:r.spacingHorizontalXS,overflowY:"auto",flex:1,minHeight:0,padding:r.spacingHorizontalXS},iconTile:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:"4px",padding:r.spacingHorizontalXS,borderRadius:r.borderRadiusMedium,border:"1px solid transparent",cursor:"pointer",minHeight:"64px",":hover":{backgroundColor:r.colorNeutralBackground3,border:`1px solid ${r.colorNeutralStroke1}`}},iconTileSelected:{backgroundColor:r.colorBrandBackground2,border:`1px solid ${r.colorBrandStroke1}`},iconLabel:{fontSize:r.fontSizeBase100,textAlign:"center",lineHeight:1.2,wordBreak:"break-word",color:r.colorNeutralForeground2},webResourceList:{flex:1,overflowY:"auto"},webResourceRow:{display:"flex",alignItems:"center",gap:r.spacingHorizontalS,padding:`${r.spacingHorizontalXS} ${r.spacingHorizontalS}`,cursor:"pointer",borderRadius:r.borderRadiusMedium,":hover":{backgroundColor:r.colorNeutralBackground3}},uploadArea:{flex:1,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:r.spacingHorizontalM,border:`2px dashed ${r.colorNeutralStroke2}`,borderRadius:r.borderRadiusMedium,color:r.colorNeutralForeground3}}),Xe=()=>{const n=He(),y=he(),m=Z(e=>e.iconPickerOpen),w=Z(e=>e.closeIconPicker),H=be(e=>e.setButtonProp),C=j(e=>e.selectedButtonId),v=j(e=>e.selectedGroupId),U=j(e=>e.tabId),G=j(e=>e.location),B=Q(e=>e.publisherPrefix),S=Q(e=>e.activeSolution),[O,c]=l.useState(null),[V,A]=l.useState(null),[u,_]=l.useState("fluent"),[N,re]=l.useState(""),[R,ae]=l.useState("All"),[x,se]=l.useState("regular"),[i,ne]=l.useState(null),[g,P]=l.useState(""),[$,T]=l.useState([]),[q,X]=l.useState(!1),[E,te]=l.useState(""),[b,f]=l.useState(!1);ee.useEffect(()=>{m||(c(null),A(null))},[m]),ee.useEffect(()=>{!m||u!=="webresource"||(X(!0),K("svg").then(e=>T(e)).catch(()=>T([])).finally(()=>X(!1)))},[m,u]);const le=l.useMemo(()=>{const e=E.toLowerCase();return $.filter(a=>!e||a.name.toLowerCase().includes(e))},[E,$]),ie=l.useMemo(()=>{const e=N.toLowerCase();return oe.filter(a=>(R==="All"||a.category===R)&&(e===""||a.name.toLowerCase().includes(e)))},[N,R]),ce=async()=>{if(!i||!C||!v)return;const e=L(),a=D.getState();if(c(null),!S||S.isManaged){c("Select an unmanaged solution first — the icon is added to it as an SVG web resource.");return}f(!0);try{const s=await ke(i,x,B,Ce,{busy:{onProgress:t=>a.logInfo("webresource",t)},guard:e});s.publishError&&a.logWarn("webresource",`Publishing icon web resource ${s.name} failed: ${s.publishError}. Pick the icon again or publish customizations before using the button.`),H(G,U,v,C,{icon:J(i),image16:`$webresource:${s.name}`,image32:`$webresource:${s.name}`}),a.logInfo("webresource",`${s.created?"Uploaded":"Reusing"} icon web resource ${s.name} (solution ${S.uniqueName}).`),w()}catch(s){const t=s instanceof Error?s.message:String(s);a.logError("webresource",`Fluent icon "${i}" could not be added as a web resource: ${t}`),c(`Could not add the icon as a web resource: ${t}`)}finally{f(!1)}},de=async()=>{if(!g||!C||!v)return;const e=L(),a=D.getState();c(null),A(null);const s=g.startsWith("$webresource:")?g.slice(13).trim():null;let t=null;if(s){f(!0);try{const h=$.find(F=>F.name===s),d=await ve(s,h,e);d.solutionUniqueName&&a.logInfo("webresource",`Added web resource ${s} to solution ${d.solutionUniqueName}.`),t=d.solutionWarning??null}catch(h){const d=h instanceof Error?h.message:String(h);if(/^No web resource named /.test(d)){c(d);return}t=`The icon was set, but ${s} could not be added to the solution: ${d}`,a.logError("webresource",t)}finally{f(!1)}}if(H(G,U,v,C,{image16:g,image32:g}),t){A(t);return}w()},ue=async e=>{const a=L();if(!S||S.isManaged){c("Select an unmanaged solution first — the SVG is added to it as a web resource.");return}c(null),f(!0);try{const s=await new Promise((d,F)=>{const k=new FileReader;k.onerror=()=>F(k.error??new Error("Failed to read SVG")),k.onload=()=>{const z=String(k.result??"");d(z.includes(",")?z.split(",")[1]??"":z)},k.readAsDataURL(e)}),t=`${B||"new"}_/icons/${e.name}`;await Se(t,s,11,{displayName:e.name,guard:a,onExisting:y.onExisting}),P(`$webresource:${t}`),_("webresource");const h=await K("svg");T(h)}catch(s){if(s instanceof xe)return;const t=s instanceof Error?s.message:String(s);D.getState().logError("webresource",`SVG upload failed: ${t}`),c(`Upload failed: ${t}`)}finally{f(!1)}};return o.jsxs(o.Fragment,{children:[y.dialog,o.jsx(Re,{open:m,onOpenChange:(e,a)=>!a.open&&w(),children:o.jsx(je,{className:n.surface,children:o.jsxs(Ie,{className:n.dialogBody,children:[o.jsx(Be,{action:o.jsx(I,{appearance:"subtle",icon:o.jsx(ge,{}),onClick:w,"aria-label":"Close"}),children:o.jsx(Ae,{children:"Choose Icon"})}),o.jsxs(Ne,{className:n.body,children:[o.jsxs(Pe,{selectedValue:u,onTabSelect:(e,a)=>_(a.value),size:"small",children:[o.jsx(W,{value:"fluent",children:"Fluent icons"}),o.jsx(W,{value:"webresource",children:"Web resources"}),o.jsx(W,{value:"upload",children:"Upload SVG"})]}),u==="fluent"&&o.jsxs(o.Fragment,{children:[o.jsxs("div",{className:n.toolbar,children:[o.jsx(M,{contentBefore:o.jsx(Y,{}),placeholder:"Search icons…",value:N,onChange:(e,a)=>re(a.value),size:"small",style:{flex:1}}),o.jsx($e,{className:n.categoryPicker,placeholder:"Category",value:R,onOptionSelect:(e,a)=>ae(String(a.optionValue??"All")),children:Me.map(e=>o.jsx(Te,{value:e,text:e,children:e},e))}),o.jsx(Ee,{label:x==="regular"?"Regular":"Filled",checked:x==="filled",onChange:(e,a)=>se(a.checked?"filled":"regular")})]}),o.jsx("div",{className:n.iconGrid,children:ie.map(e=>o.jsxs("div",{className:`${n.iconTile} ${i===e.name?n.iconTileSelected:""}`,onClick:()=>ne(e.name),role:"option","aria-selected":i===e.name,title:`${e.name} — ${e.category}`,children:[o.jsx(fe,{name:J(e.name),size:24,variant:x}),o.jsx("span",{className:n.iconLabel,children:e.name})]},e.name))}),i&&o.jsxs("div",{style:{display:"flex",alignItems:"center",gap:r.spacingHorizontalS,padding:r.spacingHorizontalXS,backgroundColor:r.colorNeutralBackground3,borderRadius:r.borderRadiusMedium,flexShrink:0},children:[o.jsxs(p,{size:200,style:{fontFamily:r.fontFamilyMonospace},children:['ModernImage="$webresource:',ye(B||"new",i,x),'"']}),o.jsx(Fe,{appearance:"tint",color:"success",children:"Selected"})]})]}),u==="webresource"&&o.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:r.spacingHorizontalS,flex:1},children:[o.jsx(M,{contentBefore:o.jsx(Y,{}),placeholder:"Search SVG web resources...",value:E,onChange:(e,a)=>te(a.value),size:"small"}),o.jsxs("div",{className:n.webResourceList,children:[q&&o.jsx(p,{size:200,style:{color:r.colorNeutralForeground3},children:"Loading web resources..."}),!q&&le.slice(0,200).map(e=>{const a=`$webresource:${e.name}`,s=g===a;return o.jsx("div",{className:n.webResourceRow,onClick:()=>P(a),style:{backgroundColor:s?r.colorBrandBackground2:void 0},children:o.jsx(p,{size:200,style:{fontFamily:r.fontFamilyMonospace},children:a})},e.id)})]}),o.jsx(M,{placeholder:"$webresource:publisher_/icons/…",value:g,onChange:(e,a)=>P(a.value)}),o.jsx(p,{size:100,style:{color:r.colorNeutralForeground3},children:"Both image16 and image32 will be set to this path. Use SVG for best results across all DPI levels."})]}),u==="upload"&&o.jsxs("div",{className:n.uploadArea,children:[o.jsx(pe,{fontSize:48,style:{opacity:.4}}),o.jsx(p,{children:"Drag an SVG file here, or click to browse"}),o.jsx(p,{size:200,style:{color:r.colorNeutralForeground3},children:"The file will be uploaded as a web resource in the active solution."}),o.jsx("input",{type:"file",accept:".svg",style:{display:"none"},id:"icon-upload-input",disabled:b,onChange:e=>{const a=e.target.files?.[0];e.target.value="",a&&ue(a)}}),o.jsx("label",{htmlFor:"icon-upload-input",style:{display:"inline-block",cursor:"pointer",padding:"6px 12px",background:r.colorBrandBackground,color:r.colorNeutralForegroundOnBrand,borderRadius:r.borderRadiusMedium,fontSize:r.fontSizeBase300},children:b?"Uploading...":"Browse for SVG"})]}),O&&o.jsx(p,{role:"alert",size:200,style:{color:r.colorPaletteRedForeground1,flexShrink:0},children:O}),V&&o.jsxs(p,{role:"status",size:200,style:{color:r.colorPaletteMarigoldForeground1,flexShrink:0},children:["Icon applied. ",V]})]}),o.jsxs(ze,{children:[o.jsx(we,{prefix:"Saves to"}),o.jsx("div",{style:{flex:1}}),o.jsx(I,{appearance:"secondary",onClick:w,children:"Cancel"}),u==="fluent"&&o.jsx(I,{appearance:"primary",disabled:!i||b,onClick:()=>{ce()},children:b?"Adding icon…":`Use ${i??"icon"}`}),u==="webresource"&&o.jsx(I,{appearance:"primary",disabled:!g||b,onClick:()=>{de()},children:b?"Adding icon…":"Use web resource"})]})]})})})]})};export{Xe as IconPickerModal,Xe as default};
|
|
1
|
+
import{y as o,h as ge,E as Y,L as pe,z as me}from"./fluent-icons-DUgjkNjy.js";import{u as he}from"./useReplaceWebResourceConfirm-Mb36NTI7.js";import{a as Z,u as be,aa as j,Y as Q,l as K,as as fe,at as J,au as ye,E as we,j as Se,av as xe,O as D,aw as ke,ax as Ce,ay as ve,k as L}from"./index-DUEHURiA.js";import{a as l,R as ee}from"./monaco-BIO15LCS.js";import{D as Re,i as je,k as Ie,j as Be,aa as Ae,d as I,l as Ne,ac as Pe,ad as W,I as M,C as $e,O as Te,a1 as Ee,t as r,b as p,B as Fe,m as ze}from"./fluent-ui-Dde22_ZN.js";import"./dnd-BmqIZ1-i.js";const De=[{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"]}],Le=["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(n){for(const y of De)if(y.keywords.some(m=>n.includes(m)))return y.category;return"General"}const oe=Le.map(n=>({name:n,category:We(n)})),Me=["All",...Array.from(new Set(oe.map(n=>n.category))).sort()],He=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:r.spacingHorizontalS},toolbar:{display:"flex",alignItems:"center",gap:r.spacingHorizontalS,flexWrap:"wrap",flexShrink:0},categoryPicker:{minWidth:"180px",maxWidth:"220px"},iconGrid:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(72px, 1fr))",gap:r.spacingHorizontalXS,overflowY:"auto",flex:1,minHeight:0,padding:r.spacingHorizontalXS},iconTile:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:"4px",padding:r.spacingHorizontalXS,borderRadius:r.borderRadiusMedium,border:"1px solid transparent",cursor:"pointer",minHeight:"64px",":hover":{backgroundColor:r.colorNeutralBackground3,border:`1px solid ${r.colorNeutralStroke1}`}},iconTileSelected:{backgroundColor:r.colorBrandBackground2,border:`1px solid ${r.colorBrandStroke1}`},iconLabel:{fontSize:r.fontSizeBase100,textAlign:"center",lineHeight:1.2,wordBreak:"break-word",color:r.colorNeutralForeground2},webResourceList:{flex:1,overflowY:"auto"},webResourceRow:{display:"flex",alignItems:"center",gap:r.spacingHorizontalS,padding:`${r.spacingHorizontalXS} ${r.spacingHorizontalS}`,cursor:"pointer",borderRadius:r.borderRadiusMedium,":hover":{backgroundColor:r.colorNeutralBackground3}},uploadArea:{flex:1,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:r.spacingHorizontalM,border:`2px dashed ${r.colorNeutralStroke2}`,borderRadius:r.borderRadiusMedium,color:r.colorNeutralForeground3}}),Xe=()=>{const n=He(),y=he(),m=Z(e=>e.iconPickerOpen),w=Z(e=>e.closeIconPicker),H=be(e=>e.setButtonProp),C=j(e=>e.selectedButtonId),v=j(e=>e.selectedGroupId),U=j(e=>e.tabId),G=j(e=>e.location),B=Q(e=>e.publisherPrefix),S=Q(e=>e.activeSolution),[O,c]=l.useState(null),[V,A]=l.useState(null),[u,_]=l.useState("fluent"),[N,re]=l.useState(""),[R,ae]=l.useState("All"),[x,se]=l.useState("regular"),[i,ne]=l.useState(null),[g,P]=l.useState(""),[$,T]=l.useState([]),[q,X]=l.useState(!1),[E,te]=l.useState(""),[b,f]=l.useState(!1);ee.useEffect(()=>{m||(c(null),A(null))},[m]),ee.useEffect(()=>{!m||u!=="webresource"||(X(!0),K("svg").then(e=>T(e)).catch(()=>T([])).finally(()=>X(!1)))},[m,u]);const le=l.useMemo(()=>{const e=E.toLowerCase();return $.filter(a=>!e||a.name.toLowerCase().includes(e))},[E,$]),ie=l.useMemo(()=>{const e=N.toLowerCase();return oe.filter(a=>(R==="All"||a.category===R)&&(e===""||a.name.toLowerCase().includes(e)))},[N,R]),ce=async()=>{if(!i||!C||!v)return;const e=L(),a=D.getState();if(c(null),!S||S.isManaged){c("Select an unmanaged solution first — the icon is added to it as an SVG web resource.");return}f(!0);try{const s=await ke(i,x,B,Ce,{busy:{onProgress:t=>a.logInfo("webresource",t)},guard:e});s.publishError&&a.logWarn("webresource",`Publishing icon web resource ${s.name} failed: ${s.publishError}. Pick the icon again or publish customizations before using the button.`),H(G,U,v,C,{icon:J(i),image16:`$webresource:${s.name}`,image32:`$webresource:${s.name}`}),a.logInfo("webresource",`${s.created?"Uploaded":"Reusing"} icon web resource ${s.name} (solution ${S.uniqueName}).`),w()}catch(s){const t=s instanceof Error?s.message:String(s);a.logError("webresource",`Fluent icon "${i}" could not be added as a web resource: ${t}`),c(`Could not add the icon as a web resource: ${t}`)}finally{f(!1)}},de=async()=>{if(!g||!C||!v)return;const e=L(),a=D.getState();c(null),A(null);const s=g.startsWith("$webresource:")?g.slice(13).trim():null;let t=null;if(s){f(!0);try{const h=$.find(F=>F.name===s),d=await ve(s,h,e);d.solutionUniqueName&&a.logInfo("webresource",`Added web resource ${s} to solution ${d.solutionUniqueName}.`),t=d.solutionWarning??null}catch(h){const d=h instanceof Error?h.message:String(h);if(/^No web resource named /.test(d)){c(d);return}t=`The icon was set, but ${s} could not be added to the solution: ${d}`,a.logError("webresource",t)}finally{f(!1)}}if(H(G,U,v,C,{image16:g,image32:g}),t){A(t);return}w()},ue=async e=>{const a=L();if(!S||S.isManaged){c("Select an unmanaged solution first — the SVG is added to it as a web resource.");return}c(null),f(!0);try{const s=await new Promise((d,F)=>{const k=new FileReader;k.onerror=()=>F(k.error??new Error("Failed to read SVG")),k.onload=()=>{const z=String(k.result??"");d(z.includes(",")?z.split(",")[1]??"":z)},k.readAsDataURL(e)}),t=`${B||"new"}_/icons/${e.name}`;await Se(t,s,11,{displayName:e.name,guard:a,onExisting:y.onExisting}),P(`$webresource:${t}`),_("webresource");const h=await K("svg");T(h)}catch(s){if(s instanceof xe)return;const t=s instanceof Error?s.message:String(s);D.getState().logError("webresource",`SVG upload failed: ${t}`),c(`Upload failed: ${t}`)}finally{f(!1)}};return o.jsxs(o.Fragment,{children:[y.dialog,o.jsx(Re,{open:m,onOpenChange:(e,a)=>!a.open&&w(),children:o.jsx(je,{className:n.surface,children:o.jsxs(Ie,{className:n.dialogBody,children:[o.jsx(Be,{action:o.jsx(I,{appearance:"subtle",icon:o.jsx(ge,{}),onClick:w,"aria-label":"Close"}),children:o.jsx(Ae,{children:"Choose Icon"})}),o.jsxs(Ne,{className:n.body,children:[o.jsxs(Pe,{selectedValue:u,onTabSelect:(e,a)=>_(a.value),size:"small",children:[o.jsx(W,{value:"fluent",children:"Fluent icons"}),o.jsx(W,{value:"webresource",children:"Web resources"}),o.jsx(W,{value:"upload",children:"Upload SVG"})]}),u==="fluent"&&o.jsxs(o.Fragment,{children:[o.jsxs("div",{className:n.toolbar,children:[o.jsx(M,{contentBefore:o.jsx(Y,{}),placeholder:"Search icons…",value:N,onChange:(e,a)=>re(a.value),size:"small",style:{flex:1}}),o.jsx($e,{className:n.categoryPicker,placeholder:"Category",value:R,onOptionSelect:(e,a)=>ae(String(a.optionValue??"All")),children:Me.map(e=>o.jsx(Te,{value:e,text:e,children:e},e))}),o.jsx(Ee,{label:x==="regular"?"Regular":"Filled",checked:x==="filled",onChange:(e,a)=>se(a.checked?"filled":"regular")})]}),o.jsx("div",{className:n.iconGrid,children:ie.map(e=>o.jsxs("div",{className:`${n.iconTile} ${i===e.name?n.iconTileSelected:""}`,onClick:()=>ne(e.name),role:"option","aria-selected":i===e.name,title:`${e.name} — ${e.category}`,children:[o.jsx(fe,{name:J(e.name),size:24,variant:x}),o.jsx("span",{className:n.iconLabel,children:e.name})]},e.name))}),i&&o.jsxs("div",{style:{display:"flex",alignItems:"center",gap:r.spacingHorizontalS,padding:r.spacingHorizontalXS,backgroundColor:r.colorNeutralBackground3,borderRadius:r.borderRadiusMedium,flexShrink:0},children:[o.jsxs(p,{size:200,style:{fontFamily:r.fontFamilyMonospace},children:['ModernImage="$webresource:',ye(B||"new",i,x),'"']}),o.jsx(Fe,{appearance:"tint",color:"success",children:"Selected"})]})]}),u==="webresource"&&o.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:r.spacingHorizontalS,flex:1},children:[o.jsx(M,{contentBefore:o.jsx(Y,{}),placeholder:"Search SVG web resources...",value:E,onChange:(e,a)=>te(a.value),size:"small"}),o.jsxs("div",{className:n.webResourceList,children:[q&&o.jsx(p,{size:200,style:{color:r.colorNeutralForeground3},children:"Loading web resources..."}),!q&&le.slice(0,200).map(e=>{const a=`$webresource:${e.name}`,s=g===a;return o.jsx("div",{className:n.webResourceRow,onClick:()=>P(a),style:{backgroundColor:s?r.colorBrandBackground2:void 0},children:o.jsx(p,{size:200,style:{fontFamily:r.fontFamilyMonospace},children:a})},e.id)})]}),o.jsx(M,{placeholder:"$webresource:publisher_/icons/…",value:g,onChange:(e,a)=>P(a.value)}),o.jsx(p,{size:100,style:{color:r.colorNeutralForeground3},children:"Both image16 and image32 will be set to this path. Use SVG for best results across all DPI levels."})]}),u==="upload"&&o.jsxs("div",{className:n.uploadArea,children:[o.jsx(pe,{fontSize:48,style:{opacity:.4}}),o.jsx(p,{children:"Drag an SVG file here, or click to browse"}),o.jsx(p,{size:200,style:{color:r.colorNeutralForeground3},children:"The file will be uploaded as a web resource in the active solution."}),o.jsx("input",{type:"file",accept:".svg",style:{display:"none"},id:"icon-upload-input",disabled:b,onChange:e=>{const a=e.target.files?.[0];e.target.value="",a&&ue(a)}}),o.jsx("label",{htmlFor:"icon-upload-input",style:{display:"inline-block",cursor:"pointer",padding:"6px 12px",background:r.colorBrandBackground,color:r.colorNeutralForegroundOnBrand,borderRadius:r.borderRadiusMedium,fontSize:r.fontSizeBase300},children:b?"Uploading...":"Browse for SVG"})]}),O&&o.jsx(p,{role:"alert",size:200,style:{color:r.colorPaletteRedForeground1,flexShrink:0},children:O}),V&&o.jsxs(p,{role:"status",size:200,style:{color:r.colorPaletteMarigoldForeground1,flexShrink:0},children:["Icon applied. ",V]})]}),o.jsxs(ze,{children:[o.jsx(we,{prefix:"Saves to"}),o.jsx("div",{style:{flex:1}}),o.jsx(I,{appearance:"secondary",onClick:w,children:"Cancel"}),u==="fluent"&&o.jsx(I,{appearance:"primary",disabled:!i||b,onClick:()=>{ce()},children:b?"Adding icon…":`Use ${i??"icon"}`}),u==="webresource"&&o.jsx(I,{appearance:"primary",disabled:!g||b,onClick:()=>{de()},children:b?"Adding icon…":"Use web resource"})]})]})})})]})};export{Xe as IconPickerModal,Xe as default};
|