@mohsinonxrm/pptb-commandbar-studio 0.9.0-beta.2 → 0.10.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +242 -2
  2. package/README.md +16 -14
  3. package/SECURITY.md +4 -4
  4. package/dist/assets/BulkPublishModal-9_XxYmS2.js +2 -0
  5. package/dist/assets/CommandEditorPanel-BtBG8540.js +1 -0
  6. package/dist/assets/CommandPalette-C2YXN_gD.js +1 -0
  7. package/dist/assets/CompareView-Beq5V68_.js +11 -0
  8. package/dist/assets/CrmParameterEditor-DfZv5BuF.js +1 -0
  9. package/dist/assets/EditorDrawer-D0K8zHVK.js +2 -0
  10. package/dist/assets/HideInsteadOfDeleteModal-C4AKxh50.js +1 -0
  11. package/dist/assets/IconPickerModal-B9UeIP7Z.js +1 -0
  12. package/dist/assets/ImportXmlModal-Cf75oVpN.js +1 -0
  13. package/dist/assets/{MonacoEditor-DweI16yt.js → MonacoEditor-B3J81C8F.js} +2 -2
  14. package/dist/assets/NewButtonModal-DhGNLWEW.js +1 -0
  15. package/dist/assets/NewGroupModal-CMLOZ15C.js +1 -0
  16. package/dist/assets/NewTabModal-N7FF7DT1.js +1 -0
  17. package/dist/assets/RuleEditorPanel-C9CcMM1s.js +1 -0
  18. package/dist/assets/ScriptView-B0ILfTWe.js +1 -0
  19. package/dist/assets/TabDisplayRulesPanel-DVMEaWWv.js +1 -0
  20. package/dist/assets/TitleTranslationsView-C68zJcNK.js +1 -0
  21. package/dist/assets/TranslationsView-BZXsG_LU.js +1 -0
  22. package/dist/assets/WebResourceBrowser-DEXq2SCy.js +1 -0
  23. package/dist/assets/XmlView-DEUwTHCt.js +2 -0
  24. package/dist/assets/crmParameters-Dxz06tk4.js +1 -0
  25. package/dist/assets/{dnd-iy5K5XAJ.js → dnd-C19d6Mn0.js} +1 -1
  26. package/dist/assets/fluent-ui-BThr2m8u.js +59 -0
  27. package/dist/assets/index-Df9NSpg6.js +136 -0
  28. package/dist/assets/index-browser-Bmt9T2GD.js +2 -0
  29. package/dist/assets/languages-CGjPBPNA.js +1 -0
  30. package/dist/assets/{monaco-cQE5XS3B.js → monaco-DzBcrxae.js} +1 -1
  31. package/dist/assets/monacoSetup-BRltj-y7.js +1 -0
  32. package/dist/assets/publishService-CKoTOngS.js +36 -0
  33. package/dist/assets/ribbonXsdCheck-CJBpxpVm.js +1923 -0
  34. package/dist/assets/{server.browser-DTeSoizu.js → server.browser-BokSAg1N.js} +1 -1
  35. package/dist/assets/useReplaceWebResourceConfirm-BUfgdCRQ.js +1 -0
  36. package/dist/assets/{useStableKeys-49o4VnxU.js → useStableKeys-EsghhjoV.js} +1 -1
  37. package/dist/assets/xmlValidator-Dki8Hf7Y.js +3 -0
  38. package/dist/assets/xmllint-CcuGSrO9.wasm +0 -0
  39. package/dist/assets/xmllint-browser-C85XrDSU.js +4 -0
  40. package/dist/index.html +3 -3
  41. package/package.json +2 -1
  42. package/dist/assets/BulkPublishModal-DjdSDcWe.js +0 -36
  43. package/dist/assets/CommandEditorPanel-DYsxUTOk.js +0 -1
  44. package/dist/assets/CommandPalette-DihgRpHI.js +0 -1
  45. package/dist/assets/CompareView-CdQo0D6e.js +0 -7
  46. package/dist/assets/CrmParameterEditor-DO6Rt764.js +0 -1
  47. package/dist/assets/EditorDrawer-Cid60F3b.js +0 -2
  48. package/dist/assets/HideInsteadOfDeleteModal-Bk_foggy.js +0 -1
  49. package/dist/assets/IconPickerModal-CW_pvpVS.js +0 -1
  50. package/dist/assets/ImportXmlModal-BcszuTi-.js +0 -1
  51. package/dist/assets/NewButtonModal-C2fAUuZI.js +0 -1
  52. package/dist/assets/NewGroupModal-BDr4DPBs.js +0 -1
  53. package/dist/assets/NewTabModal-CYc1fc2A.js +0 -1
  54. package/dist/assets/RuleEditorPanel-BxGrJYo4.js +0 -1
  55. package/dist/assets/ScriptView-tkdIK4sg.js +0 -1
  56. package/dist/assets/TabDisplayRulesPanel-S_AxUWfB.js +0 -1
  57. package/dist/assets/TranslationsView-DZIGE2pC.js +0 -1
  58. package/dist/assets/WebResourceBrowser-Dc3kBMvH.js +0 -1
  59. package/dist/assets/XmlView-B0weY9hR.js +0 -2
  60. package/dist/assets/crmParameters-rgfZhhzN.js +0 -1
  61. package/dist/assets/fluent-ui-CQyNN9H3.js +0 -59
  62. package/dist/assets/index-DRTwBo4g.js +0 -136
  63. package/dist/assets/monacoSetup-BIq1zGyP.js +0 -1
  64. package/dist/assets/ruleKinds-BKTUiZ1-.js +0 -1
  65. package/dist/assets/useReplaceWebResourceConfirm-BhU1AM5L.js +0 -1
  66. package/dist/assets/xmlValidator-CnbyWxHe.js +0 -3
package/CHANGELOG.md CHANGED
@@ -9,6 +9,246 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [0.10.0-beta.1] - 2026-11-14
13
+
14
+ The first beta of 0.10.0 (npm `beta`): editor and publish correctness, and performance.
15
+ - **Publish:** imports run in the background, with **Cancel** and **View import log**, and a
16
+ failed import says why (#107). The publish dialog also checks the XML against Microsoft's ribbon
17
+ schema, as warnings only (#126).
18
+ - **Faster editing:** an edit copies only the ribbon it changes, and checking for unpublished
19
+ changes no longer writes out the whole workspace (#111).
20
+ - **Compare with published** shows what Publish will import, moved tabs included (#216).
21
+ - **Translate tab and group titles** (#136).
22
+ - **Fixes:** global command bar locations (#166), sub-grid notes (#167), Microsoft's grid and
23
+ quick action rules (#162), scaling and template checks (#165), Open a URL with web resources
24
+ (#160), the context value picker (#161), and raw `$Resources:` keys (#201).
25
+ - **The solution picker** is the scope chip FetchXML Studio and Dataverse Request Studio share
26
+ (#174, #264), and Command Bar Studio says "entity" throughout.
27
+
28
+ It includes everything in 0.9.0. Requires Power Platform ToolBox 1.2.7 or later, as 0.9 does.
29
+
30
+ ### ⚡ Performance
31
+
32
+ - **Typing in a field no longer copies every ribbon (#111).** Each edit, keystrokes included,
33
+ copied all four ribbons (main grid, sub-grid, form and application) before changing one of them.
34
+ Now it copies only the ribbon it changes; the others are shared with the step before. On a large
35
+ entity that's about a quarter of the copying per keystroke.
36
+ - **Checking for unpublished changes no longer writes out the whole workspace (#111).** After an
37
+ undo, a redo, a load or a publish, Command Bar Studio wrote the ribbons, commands, rules and
38
+ labels and their loaded versions out as text to see whether anything was left to publish. Now it
39
+ skips everything still as loaded and compares only what was edited. On a large entity an undo is
40
+ about ten times faster. An edit typed back to what was loaded still counts as no change.
41
+
42
+ ### ✨ Added
43
+
44
+ - **The publish dialog checks against Microsoft's ribbon schema (#126).** Once the dialog has built
45
+ the RibbonDiffXml each import would write, it checks it against Microsoft's ribbon schemas
46
+ (RibbonCore, RibbonTypes and RibbonWSS 9.0.0.2090) and lists what they don't allow under
47
+ **Warnings**, under its own heading, each with the element and the rule, for example "Element
48
+ 'Button', attribute 'Bogus': The attribute 'Bogus' is not allowed.". **These are only ever
49
+ warnings, and Publish stays enabled:** the schemas are from 2017, and Dataverse accepts ribbon XML
50
+ they don't describe. If Dataverse rejects the import, Publish shows its error. A finding in
51
+ something this publish doesn't write is marked as already published; past 50 findings, the rest
52
+ are summed up in one line. Publishing anyway logs the findings to the Console log. The check runs
53
+ after the dialog's own check and never holds Publish back. The validator (xmllint compiled to
54
+ WebAssembly, about 0.8 MB) loads the first time the dialog runs it, in a Web Worker; where the
55
+ host doesn't allow workers, **Good to know** says the check couldn't run. The checks that block a
56
+ publish are unchanged.
57
+ - **Translate tab and group titles (#136).** A tab's or group's menu (in Structure, and a group's
58
+ ⋮ on the canvas) has **Translate title…**, which opens the title's translations in the editor
59
+ drawer, like a button's. The base language is the title itself (editing it renames the tab or
60
+ group); other languages are added, typed and removed as for buttons. Only your own tabs and
61
+ groups can be translated, as only they can be renamed. A title whose label other tabs, groups or
62
+ buttons share stays read-only (its translations would change for all of them), and so does a
63
+ copied or imported title until you change it. A new tab's or group's title is now published with
64
+ every language it has; before, only the base language was written.
65
+
66
+ ### 🔧 Changed
67
+
68
+ - **The solution picker is the scope chip FetchXML Studio and Dataverse Request Studio share
69
+ (#174, #264).** The top bar's solution button now reads **Solution: Sales Core v1.2.0** (three
70
+ version parts, so a patch reads apart from its parent), with an **Unmanaged** badge and the
71
+ publisher prefix, which is warning-coloured for the org's default publisher. Its tooltip has the
72
+ full name, unique name, version and publisher. With nothing chosen it reads **Choose scope**, in
73
+ outline like the chosen state, so Publish stays the top bar's one primary button. The popover is
74
+ titled **Solution**, searches name, unique name and version, and ends with "Changes apply right
75
+ away." and **Done**. On an environment where no solution is chosen yet, a first-run tip points at
76
+ the chip; **Choose scope** opens it, and **Got it** dismisses the tip for that environment.
77
+ - **"Entity", not "table".** Command Bar Studio now says entity wherever it said table: the top
78
+ bar's picker (**Choose entity**), the canvas, the Structure pane, dialogs, rule labels
79
+ (**Entity**, **Entity privilege**, **Entity property**, **Form's entity**), the command palette
80
+ (`@` for entities only), messages, the Console log and the README. It matches the ribbon's own
81
+ names (`EntityRule`, `Mscrm.HomepageGrid.<entity>`) and Ribbon Workbench. The maker portal's
82
+ **Add existing › Table** is still named as the portal names it. Wording only: what publishes is
83
+ unchanged.
84
+
85
+ ### 🔧 Fixed
86
+
87
+ - **Buttons for the global command bar go only where it shows them (#166).** Microsoft's docs
88
+ support one place for your buttons on `Mscrm.GlobalTab`: its New group
89
+ (`Mscrm.GlobalTab.New.Controls._children`), in Unified Interface. CBS let you add groups to
90
+ GlobalTab and buttons to its other groups, and published them without a word. Now:
91
+ - **No new groups on GlobalTab:** Add group, Duplicate group and New group are disabled there and
92
+ say why.
93
+ - **New buttons only in the New group:** on GlobalTab's other groups, Add button, Duplicate (and
94
+ Ctrl+D), a flyout's Add item and Customise button are disabled or refused with the reason. Move
95
+ to and the Solution tab's Add to don't offer those groups, and dropping a button there is
96
+ refused. Your buttons already there stay editable.
97
+ - **The publish dialog warns** about anything already added outside the New group (an import,
98
+ say).
99
+ - **The Application ribbon's note** says this, instead of "Buttons on GlobalTab appear in the
100
+ global command bar".
101
+ - **The sub-grid note matches Unified Interface (#167).** "About this location" and a banner on
102
+ the Classic canvas said a sub-grid supports only Add, Show List and Delete, with icons that can't
103
+ change. That's the pre-Unified-Interface page. A live check showed Unified Interface shows the
104
+ entity's whole sub-grid command bar, and that overriding a built-in sub-grid button's label, icon
105
+ and command takes effect. The note now says so, and the banner is gone, as the other location
106
+ banners went in 0.9.0 (#181).
107
+ - **The context value picker explains itself (#161).** Under a parameter's **Value**, the field
108
+ now says what the chosen value passes, in Microsoft's terms: FirstPrimaryItemId is the record
109
+ being viewed (empty on a main grid), PrimaryControl the form's context, SelectedControl the grid's.
110
+ Some old descriptions were wrong (FirstPrimaryItemId said "first selected record").
111
+ PrimaryEntityTypeCode and SelectedEntityTypeCode read "(deprecated)", and picking one warns to
112
+ use the …TypeName value instead. A loaded value the list doesn't have, or one a URL can't take,
113
+ now shows as itself; before, the picker showed PrimaryControl while keeping the real value.
114
+ - **A failed import says why (#107).** When the import itself fails with a fault that doesn't
115
+ give the reason (a generic server error, a timeout), Publish now reads the import job and adds
116
+ its own failure, for example "Dataverse couldn't import the solution (0x80048033): …". When an
117
+ import succeeds but no ribbon was applied, the job's failure is shown, if it has one, instead of
118
+ "no entityRibbon result". Quotes, apostrophes and ampersands in Dataverse's text are decoded.
119
+ - **Imports run in the background, and you can cancel them (#107).** Publish now imports with
120
+ `ImportSolutionAsync` and follows the system job it starts, so a long import can't hit a host or
121
+ HTTP timeout. A failed job shows Dataverse's message with the import job's own failure. While
122
+ ribbons import, **Cancel** stops the publish: Command Bar Studio stops waiting, asks Dataverse to
123
+ cancel the import, and says what happened. Dataverse may refuse or finish the import anyway, and
124
+ the message says so. What didn't finish isn't marked published, so those changes stay to
125
+ publish. An import that takes more than 10 minutes is stopped the same way. The second import,
126
+ which only refreshes Unified Interface's command-bar metadata, runs after your changes are
127
+ published: cancelling it, or it failing, no longer fails the publish. Your changes count as
128
+ published, with a warning that the app may not show them until the next publish, or for up to
129
+ about 25 minutes. After a failed or cancelled import, **View import log** shows the import job's
130
+ log read-only in the publish dialog; when Dataverse rejected the solution file outright, it says
131
+ there is no log.
132
+ - **Adding a language by typing it no longer adds two (#136).** Typing an LCID such as 1036 in
133
+ **Add a language** and pressing Enter added French and the first language in the list (German);
134
+ the list now narrows to what's typed.
135
+ - **Built-in buttons and groups no longer show raw keys (#201).** A button whose label is a
136
+ one-word resource key showed the key: the account grid's **OpenAllRecordsViewImageButtonText**
137
+ now reads "Open All Records View". A tab or group without a title showed its whole id
138
+ (`Mscrm.HomepageGrid.account.MainTab.ModernClient`) wherever it's named: the Structure tree, the
139
+ group cards, the Classic canvas, the List view, Move to, the Solution tab's Add a copy, the
140
+ command palette, Properties and the editors. It now reads "Modern Client"; an id ending in a word
141
+ like Group or Tab is still shown as the id. The List view's search still finds a group by its
142
+ id. Display only: what publishes is unchanged.
143
+ - **Open a URL accepts web resources and relative addresses (#160).** The address showed a red
144
+ "must start with https://" for `$webresource:` and relative addresses, which Microsoft documents
145
+ and recommends. Now only an empty address is an error, and `http://` is a warning (a dialog can't
146
+ show it). **Browse…** picks a web resource, as it does for a script. For a web resource, the
147
+ field lists the query string names it reads, and a parameter with another name is flagged: the
148
+ page's request fails on it, so put your own values in `data`. Every query string parameter now
149
+ needs a name, not only a context value; changing a parameter's type keeps its name; and a new
150
+ one is text instead of PrimaryControl, which means nothing in an address. **Open in** reads New
151
+ window (default), Modal dialog and Modeless dialog, as Microsoft names them, and a new **Window
152
+ settings** field sets WinParams, such as a dialog's size. The publish check also stops a bare
153
+ `$webresource:` with no name.
154
+ - **Microsoft's grid and quick action rules can be bound (#162).** Microsoft documents placing a
155
+ grid command with the enable rules `Mscrm.ShowOnGrid`, `Mscrm.ShowOnQuickAction` and
156
+ `Mscrm.ShowOnGridAndQuickAction`, but they live in the application ribbon, so an entity's rule
157
+ list didn't offer them. For a main grid command, the command editor's **Add an existing enable
158
+ rule** now lists them under Microsoft's grid rules, and so does the Properties pane's **Bind an
159
+ existing enable rule**. The publish check knows them. A bound rule that isn't in the loaded ribbon
160
+ no longer opens an editor that closes at once, there or in the bottom panel's Commands list: its
161
+ tag says why there's nothing to open. A display rule that a sub-grid button uses now warns about a
162
+ **Column value** step: Microsoft says Unified Interface doesn't check one there, so put it in an
163
+ enable rule.
164
+ - **Scaling and layout checks (#165).** A new group whose template isn't one CBS lists now gets its
165
+ MaxSize from the template's largest layout as loaded; when nothing knows the template, the publish
166
+ dialog warns that the group gets none (every group needs one on the classic ribbon). The publish
167
+ check also warns when a control's **Template alias** isn't one its group's template has: the
168
+ classic ribbon doesn't lay it out (Unified Interface ignores templates). An unused helper that had
169
+ the MaxSize / Scale order backwards is gone. Scaling stays read-only until changes to it can be
170
+ published.
171
+ - **Compare with published shows what Publish writes (#216).** Compare built both sides from the
172
+ generator alone, so changes only Publish's merge writes, such as a moved tab, showed +0 / −0.
173
+ Compare now reads your published customizations for the entity (and the application ribbon, when
174
+ it's published too) and compares them with the RibbonDiffXml Publish would import. When that can't
175
+ be built (no connection, a change Publish can't write yet, or no answer within 30 s), it compares
176
+ the generated XML as before and says why. Application ribbon changes Publish can't import yet (the
177
+ solution has no Application Ribbons) are left out, and Compare says so.
178
+
179
+ ## [0.9.0] - 2026-11-14
180
+
181
+ The UX overhaul in Fluent 2, and Edit mode. Command Bar Studio now shows a Structure tree and
182
+ group cards you can reorder, edits commands, rules, scripts and XML in one drawer, and says what
183
+ a publish will do before it runs. This release is 0.9.0-beta.1 to 0.9.0-beta.3, whose notes below
184
+ are the full list. Requires Power Platform ToolBox 1.2.7 or later, as 0.8 does.
185
+
186
+ ### Highlights
187
+
188
+ - **Edit mode (#193):**
189
+ - a Structure tree of tabs, groups and buttons, and group cards you can reorder;
190
+ - "How users see it", a preview of the command bar;
191
+ - a Solution tab, an entity picker in the top bar, and a List view that fits and sorts.
192
+ - **One editor drawer** for commands, rules, scripts, XML, Compare and Translations, with Done
193
+ and one Undo step per drawer.
194
+ - **Properties:** sections by kind, with texts shown as the canvas shows them. A button that
195
+ isn't yours is read-only until you customise it, and since beta.3 its rules can't be bound or
196
+ unbound from Properties either (#267).
197
+ - **The publish dialog** says what will publish and why Publish is blocked.
198
+ - **Dialogs** use one shell and open on the right control: search boxes get focus, and default
199
+ names are selected so typing replaces them (#268).
200
+ - **Keyboard and screen readers (#23):** the pane resize handles work from the keyboard, and the
201
+ Classic and Modern canvases have accurate roles and keyboard selection.
202
+ - **Lighter start (#118):** the code editor loads the first time you open one, with XML and
203
+ JavaScript only; the package is 2.7 MB smaller (16.3 → 13.6 MB unpacked).
204
+ - **Fixes:** closing Compare no longer logs a disposed-model error (#266).
205
+
206
+ ### ⚠️ Upgrading from 0.8.x
207
+
208
+ - **Changes you'll notice:**
209
+ - **Layout:** the entity picker moved from the left pane to the top bar. The left pane has
210
+ Structure and Solution tabs, and the canvas view (Group cards, Classic, Modern or List) is
211
+ picked from **View** above the canvas.
212
+ - **Editors:** commands, rules, scripts, XML, Compare and Translations open in one drawer
213
+ instead of separate panels and dialogs; **Done** closes it.
214
+ - **Microsoft's buttons:** Properties and the command editor are read-only for a button or
215
+ command that isn't yours until you choose **Customise command**.
216
+ - **Nothing else changes:** the PPTB requirement and the published format are the same.
217
+ - **0.8.x is end of life:** 0.8.0 is deprecated on npm and gets no support window, because
218
+ 0.9.0 needs the same PPTB (see `SECURITY.md`).
219
+ - **0.9.0-beta.3 wasn't published to npm.** Its fixes ship in 0.9.0.
220
+
221
+ ## [0.9.0-beta.3] - 2026-11-12
222
+
223
+ Not published to npm: these fixes ship in 0.9.0.
224
+
225
+ ### 🔧 Fixed
226
+
227
+ - **Closing Compare no longer throws an error (#266).** Closing **Compare with published** or a
228
+ History diff could log "TextModel got disposed before DiffEditorWidget model got reset" in the
229
+ tool's console. The editor library disposed the two texts before the diff editor that showed
230
+ them; now they're disposed after it. Compare's repaint listeners are released when it closes,
231
+ too: they were never removed, because Monaco doesn't announce when a diff editor is disposed.
232
+ - **Properties no longer changes Microsoft's commands without Customise command (#267).** On an
233
+ out-of-the-box button, **Display rules** and **Enable rules** in Properties still offered Bind,
234
+ Create new rule and unbinding, which changed Microsoft's command straight away. The command
235
+ editor has kept such commands read-only since 0.9.0-beta.1. Properties now does the same: the
236
+ bound rules still open, and a line says to customise the command to change them. After
237
+ **Customise command**, binding works as before.
238
+ - **Dialogs start where you type (#268).** The web resource browser and the icon picker open on
239
+ their search box instead of the Close button. New button, New group and New tab open with their
240
+ default name ("New Button", …) selected, so typing replaces it instead of adding to it; Renaming
241
+ a tab or group selects the current name.
242
+
243
+ ### 🏗️ Technical
244
+
245
+ - **Every tag is checked in PPTB first (#263, as FetchXML Studio #306).** Each PR was checked in
246
+ PPTB on its own build, but the build a tag publishes (every merged change plus the version
247
+ bump, built by `release.yml`) wasn't run in PPTB until it was on npm. RELEASING.md's new
248
+ *Before every tag* step runs the rehearsal's `package` tarball in PPTB, with a short smoke
249
+ list that includes a publish on a test table, before any beta, stable or hotfix tag. The smoke
250
+ test of the published beta before `latest` stays.
251
+
12
252
  ## [0.9.0-beta.2] - 2026-11-01
13
253
 
14
254
  ### 🔧 Changed
@@ -22,8 +262,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
22
262
  - **The tool starts without loading the code editor (#118).** Monaco (about 4 MB) loaded with the
23
263
  tool, before any editor opened. It now loads the first time you open the XML view, Compare, a
24
264
  script, Import XML or the publish dialog's XML. It brings XML and JavaScript only: the other
25
- languages and the CSS, HTML and JSON workers are gone, and the package is 3.3 MB smaller
26
- (16.3 → 13.0 MB unpacked).
265
+ languages and the CSS, HTML and JSON workers are gone, and the package is 2.7 MB smaller
266
+ (16.3 → 13.6 MB unpacked).
27
267
 
28
268
  ### 🔧 Fixed
29
269
 
package/README.md CHANGED
@@ -30,7 +30,7 @@ reimagined with React 18, Fluent UI v9, and live Dataverse integration via
30
30
  - Tab drag-to-reorder, inline rename (double-click), `+ Add tab`
31
31
  - Context menus on buttons and groups — hide/show, duplicate, move, rename, delete, override OOB
32
32
  - A copy (duplicate, customise button) keeps the labels another solution defines, so it shows the same text; edit its text to give it labels of its own. A duplicated group with a platform or another solution's title keeps it: rename the copy before publishing if it should read differently
33
- - If your unmanaged ribbon customizations can't be read when a table loads, a warning says so (labels may show as ids, ownership is unknown), with **Retry**
33
+ - If your unmanaged ribbon customizations can't be read when an entity loads, a warning says so (labels may show as ids, ownership is unknown), with **Retry**
34
34
 
35
35
  ### 📋 Properties Pane
36
36
  - Identity: label, translations (multi-LCID), tooltip, icon picker, image16/32, kind (for new controls; a menu item is a button or a flyout), sequence, template alias
@@ -95,8 +95,9 @@ reimagined with React 18, Fluent UI v9, and live Dataverse integration via
95
95
  - CBS-specific completions: `$LocLabels:`, `$webresource:`, `Command=`, `ModernImage=`
96
96
 
97
97
  ### 🔄 Publish Pipeline
98
- - Read → merge → write: reads the table's existing unmanaged ribbon layer (CustomActions, commands, rules, labels) and merges your changes into it, so customizations made elsewhere (e.g. with Ribbon Workbench) are kept
98
+ - Read → merge → write: reads the entity's existing unmanaged ribbon layer (CustomActions, commands, rules, labels) and merges your changes into it, so customizations made elsewhere (e.g. with Ribbon Workbench) are kept
99
99
  - Pre-publish validation — blocking errors stop the import; warnings are logged. It includes the schema rules the import enforces (empty rules, one-branch OrRules, function names, required values, numbers)
100
+ - Microsoft's ribbon schema check (RibbonCore / RibbonTypes / RibbonWSS 9.0.0.2090) in the publish dialog — warnings only, never blocks: Dataverse accepts ribbon XML the 2017 schema doesn't describe
100
101
  - Solution ZIP packaging with `behavior=2` (shell-only) root component — does **not** pull in all entity subcomponents
101
102
  - Import → publish → re-import → publish, so Unified Interface picks up the change
102
103
  - Waits and retries while the environment is busy with another import, publish or ribbon-metadata job
@@ -107,10 +108,10 @@ reimagined with React 18, Fluent UI v9, and live Dataverse integration via
107
108
 
108
109
  ### 🧩 Solution provenance
109
110
  - Which managed solution adds a control, read from the managed ribbon layers (`ribbondiffs`) in one query (falls back to the namespace heuristic when unavailable)
110
- - Notice in the properties pane for managed-solution buttons. Dataverse layers ribbon customizations per table, not per button, so there's no per-button layer list
111
+ - Notice in the properties pane for managed-solution buttons. Dataverse layers ribbon customizations per entity, not per button, so there's no per-button layer list
111
112
 
112
113
  ### ⌨️ Keyboard Shortcuts + Command Palette
113
- - `Ctrl+K` — Command Palette: search buttons, commands, rules and tables, and run actions. Arrow keys and Enter; `/` for actions only, `@` for tables only. Choosing a button selects it on the canvas; only actions that can run now are listed
114
+ - `Ctrl+K` — Command Palette: search buttons, commands, rules and entities, and run actions. Arrow keys and Enter; `/` for actions only, `@` for entities only. Choosing a button selects it on the canvas; only actions that can run now are listed
114
115
  - `Ctrl+Z/Y`, `Ctrl+Shift+Z` — Undo / Redo (80-entry stack)
115
116
  - `Ctrl+D` — Duplicate selected button
116
117
  - `Ctrl+S` — Open Bulk Publish
@@ -122,12 +123,12 @@ reimagined with React 18, Fluent UI v9, and live Dataverse integration via
122
123
 
123
124
  ### 💾 Persistence
124
125
  - Unpublished changes are saved as a draft in `localStorage` after every change, per org,
125
- solution and table: everything the publish needs (canvas, commands, rules, labels,
126
+ solution and entity: everything the publish needs (canvas, commands, rules, labels,
126
127
  un-hides, customised / uncustomised commands). Only what differs from the loaded ribbon
127
- is stored, compressed: a few KB per table
128
- - When the table loads again, a dialog offers to **Restore** the draft on top of the ribbon
128
+ is stored, compressed: a few KB per entity
129
+ - When the entity loads again, a dialog offers to **Restore** the draft on top of the ribbon
129
130
  as loaded (one undo step) or **Discard** it. Drafts older than 30 days are discarded
130
- - Switching table or solution with unpublished changes asks first: **Keep as draft**,
131
+ - Switching entity or solution with unpublished changes asks first: **Keep as draft**,
131
132
  **Discard** or **Cancel**. When the browser storage is full, a banner says so and
132
133
  **Keep as draft** is disabled, so the changes are never dropped silently
133
134
  - Pane widths, collapsed state, view mode all persisted
@@ -139,22 +140,22 @@ reimagined with React 18, Fluent UI v9, and live Dataverse integration via
139
140
  Command Bar Studio only reads from Dataverse until you use one of the operations below. Every
140
141
  write shows the **target environment** first: the connection's name and type (Production
141
142
  highlighted) are always in the top bar and next to every button that writes, and the publish
142
- dialog names the environment, solution and tables. On a **Production** connection you type the
143
- table's logical name (or `application ribbon`) before **Publish** is enabled; the other
143
+ dialog names the environment, solution and entities. On a **Production** connection you type the
144
+ entity's logical name (or `application ribbon`) before **Publish** is enabled; the other
144
145
  operations add or change a single web resource and don't ask for it. Writes run as the connected user, or the
145
146
  user PPTB is impersonating, and only go to the connection the tool was on when the operation
146
147
  started (if the tool's connection changes in Power Platform ToolBox, the operation stops).
147
148
 
148
149
  | Operation | When | What it does in Dataverse |
149
150
  |---|---|---|
150
- | **Publish** | **Publish n changes** in the top bar, or Ctrl+S | Builds a solution package for the selected unmanaged solution with the table's **complete** ribbon customization (what is in the solution's layer, plus your changes) and imports it **twice** (`ImportSolution` with `OverwriteUnmanagedCustomizations`), then publishes the table (`PublishXml`) and reads the layer back to verify it. It first publishes the table (`PublishXml`), so ribbon changes imported elsewhere but not yet published become part of the layer it reads, instead of being replaced; the publish at the end would publish them anyway. Just before each import it reads the layer again: if it changed since it was read (published from another session or tool), nothing is imported. The same for the application ribbon, when the solution contains the Application Ribbons component. **Also publish all customizations** adds `PublishAllXmlAsync`, which publishes everything unpublished in the environment (anyone's), so it asks for its own confirmation. The **Publish comment** is written to the Console log. |
151
+ | **Publish** | **Publish n changes** in the top bar, or Ctrl+S | Builds a solution package for the selected unmanaged solution with the entity's **complete** ribbon customization (what is in the solution's layer, plus your changes) and imports it **twice** (`ImportSolutionAsync` with `OverwriteUnmanagedCustomizations`, following the system job it starts; **Cancel** stops waiting and asks Dataverse to cancel it, and **View import log** shows a failed import's log), then publishes the entity (`PublishXml`) and reads the layer back to verify it. It first publishes the entity (`PublishXml`), so ribbon changes imported elsewhere but not yet published become part of the layer it reads, instead of being replaced; the publish at the end would publish them anyway. Just before each import it reads the layer again: if it changed since it was read (published from another session or tool), nothing is imported. The same for the application ribbon, when the solution contains the Application Ribbons component. **Also publish all customizations** adds `PublishAllXmlAsync`, which publishes everything unpublished in the environment (anyone's), so it asks for its own confirmation. The **Publish comment** is written to the Console log. |
151
152
  | **Upload a web resource** | Web resource browser → **Upload**; icon picker → **Upload SVG** | Creates a web resource named `<prefix>_/<folder>/<file name>` and adds it to the selected unmanaged solution (`AddSolutionComponent`). If one with that name exists you choose **Replace** (its content changes everywhere it is used), **Keep existing** or **Cancel**; a managed one can only be kept. It is published (`PublishXml`), so a replaced file is live at once. |
152
153
  | **Pick a Fluent icon** | Icon picker → Fluent icons | Creates the SVG web resource `<prefix>_/icons/cbs/<icon>.svg` (an existing one is reused, never overwritten), adds it to the solution and publishes it (`PublishXml`). |
153
154
  | **Pick an existing web resource as an icon** | Icon picker → Web resource | Adds the web resource to the selected unmanaged solution (`AddSolutionComponent`). |
154
155
  | **Save a script** | Command editor → JavaScript action → **Save Web Resource** | Updates the content of the script you opened, adds it to the solution and publishes it (`PublishXml`), so users get the new version at once. The button shows the environment it saves to. |
155
156
 
156
157
  Nothing else writes to Dataverse:
157
- - **Unsaved changes** are kept as a draft in the browser storage of Power Platform ToolBox on your machine (`localStorage`), per environment, solution and table. A note of the last publish is kept for the session (`sessionStorage`).
158
+ - **Unsaved changes** are kept as a draft in the browser storage of Power Platform ToolBox on your machine (`localStorage`), per environment, solution and entity. A note of the last publish is kept for the session (`sessionStorage`).
158
159
  - **Export** writes a RibbonDiffXml file where you choose; **Import RibbonDiffXml** only changes the workspace until you publish.
159
160
  - **Import RibbonDiffXml** (XML → Import XML…): paste the XML on the left; **Preview** lists each change (Add / Update / Hide) and every problem on the right. Click a problem with a line to go to it. **Import n changes** is one change, which Undo takes back.
160
161
 
@@ -162,7 +163,7 @@ Nothing else writes to Dataverse:
162
163
 
163
164
  ```
164
165
  ┌─────────────────────────────────────────────────────────────────┐
165
- │ TopBar: Environment │ Solution │ Table │ Search (Ctrl+K) │
166
+ │ TopBar: Environment │ Solution │ Entity │ Search (Ctrl+K) │
166
167
  │ Undo/Redo │ XML ▾ │ Open in D365 │ View ▾ │ Help │ Publish n │
167
168
  │ (tools move into a ⋯ menu when the window is narrow) │
168
169
  ├─────────────────────────────────────────────────────────────────┤
@@ -204,7 +205,7 @@ Command Bar Studio runs **inside [Power Platform ToolBox](https://www.powerplatf
204
205
  2. Connect to a Dataverse environment
205
206
  3. Open Command Bar Studio from the tool list
206
207
  4. Pick an unmanaged solution from the TopBar
207
- 5. Pick a table from the TopBar (only the solution's tables are listed)
208
+ 5. Pick an entity from the TopBar (only the solution's entities are listed)
208
209
  6. Edit ribbon buttons visually; click **Publish** when done
209
210
 
210
211
  Icons you pick or upload, and scripts you save, are created as web resources and
@@ -318,6 +319,7 @@ src/
318
319
  xmlGenerator.ts — RibbonDiffXml generator (all 30 rule kinds)
319
320
  xmlParser.ts — Merged ribbon XML parser (all 30 rule kinds)
320
321
  xmlValidator.ts — Pre-import validation with user-friendly messages
322
+ ribbonXsdCheck.ts — Microsoft's ribbon schema check (xmllint WebAssembly; warnings only)
321
323
  publishPlan.ts — What a publish changes per location (and what it can't)
322
324
  ribbonDiffMerge.ts — Merges your changes into the existing unmanaged layer
323
325
  dataverse/
package/SECURITY.md CHANGED
@@ -55,14 +55,14 @@ 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.8.0 is deprecated on npm and gets no further fixes**, 0.7.x, 0.6.x
59
- and 0.5.x included:
58
+ **Everything before 0.9.0 is deprecated on npm and gets no further fixes**, 0.8.x, 0.7.x,
59
+ 0.6.x and 0.5.x included:
60
60
  - **Before 0.6.2:** these versions bundle DOMPurify 3.2.7 (in the Monaco editor), which has
61
61
  critical advisories.
62
- - **0.6.x and 0.7.x:** they get no support window, because the next minor needs the same Power
62
+ - **0.6.x, 0.7.x and 0.8.x:** they get no support window, because the next minor needs the same Power
63
63
  Platform ToolBox (1.2.7). Update to the latest release.
64
64
 
65
- Use 0.8.0 or later, which requires Power Platform ToolBox 1.2.7 or later; users on an older
65
+ Use 0.9.0 or later, which requires Power Platform ToolBox 1.2.7 or later; users on an older
66
66
  PPTB need to update it. A previous minor keeps a support window only when the next minor
67
67
  raises that requirement, because only then can users be unable to update. See
68
68
  [RELEASING.md](RELEASING.md) → *Supported versions*.
@@ -0,0 +1,2 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./ribbonXsdCheck-CJBpxpVm.js","./preload-helper-PPVm8Dsz.js","./index-Df9NSpg6.js","./fluent-ui-BThr2m8u.js","./dnd-C19d6Mn0.js","./index-D5GCH8nj.css"])))=>i.map(i=>d[i]);
2
+ import{_ as pn}from"./preload-helper-PPVm8Dsz.js";import{r as l,j as e,af as C,ag as k,ah as ue,c as u,B as is,y as Re,aA as Us,m as Ws,t as c,W as M,e5 as ss,k as N,ax as Is,ai as Ms,ed as mn,ee as Ce,ef as ke,eg as Ne,eY as gn,d as zs,eZ as bn,dY as xn,em as fn,z as jn,e_ as Hs,ea as yn,$ as Sn,cR as vn,az as wn,av as Cn,au as kn,ay as Nn,ar as Pn,aC as Rn}from"./fluent-ui-BThr2m8u.js";import{d as S,g as Js,e as An,r as os,f as En,b as $s,a as f,h as Tn,E as Pe,A as In,j as Vs,l as Mn,k as ns,w as zn,m as $n,n as Ls}from"./index-Df9NSpg6.js";import{M as Fs}from"./MonacoEditor-B3J81C8F.js";import{c as Os,w as _s,f as Vn,a as Ln,i as Fn,b as On,d as _n,p as Ds,e as Dn}from"./publishService-CKoTOngS.js";import"./dnd-C19d6Mn0.js";import"./xmlValidator-Dki8Hf7Y.js";import"./crmParameters-Dxz06tk4.js";const Bn=Ws({root:{display:"flex",flexDirection:"column",gap:c.spacingVerticalS},box:{display:"grid",gridTemplateColumns:"auto 1fr",columnGap:c.spacingHorizontalM,rowGap:c.spacingVerticalXS,padding:`${c.spacingVerticalS} ${c.spacingHorizontalM}`,backgroundColor:c.colorNeutralBackground3,borderRadius:c.borderRadiusMedium},label:{color:c.colorNeutralForeground3},value:{display:"flex",flexWrap:"wrap",alignItems:"center",columnGap:c.spacingHorizontalS,minWidth:0},secondary:{color:c.colorNeutralForeground3,wordBreak:"break-all"}});function Un({rows:o,confirmWord:x,onConfirmationChange:v,disabled:b}){const m=Bn(),[P,_]=l.useState({status:"loading"}),[H,Q]=l.useState(""),ee=S(i=>i.environment),se=S(i=>i.connectionUrl),ne=S(i=>i.connectionVersion);l.useEffect(()=>{let i=!0;return _({status:"loading"}),Js().then(ie=>i&&_({status:"ready",connection:ie})).catch(()=>i&&_({status:"ready",connection:null})),()=>{i=!1}},[ee,se,ne]);const j=P.status==="ready"?P.connection:null,D=An(j?.environment),te=P.status==="ready"&&os(j?.environment),de=P.status==="ready"&&(!te||En(H,x)),h=j?.environment;return l.useEffect(()=>{v(de,h)},[de,h,v]),e.jsxs("div",{className:m.root,children:[D&&e.jsx(C,{intent:"warning",children:e.jsxs(k,{children:[e.jsx(ue,{children:"Production environment"}),"This changes the live environment."]})}),e.jsxs("div",{className:m.box,children:[e.jsx(u,{className:m.label,children:"Environment"}),e.jsx("div",{className:m.value,children:P.status==="loading"?e.jsx(u,{children:"Reading the connection…"}):j?e.jsxs(e.Fragment,{children:[e.jsx(u,{weight:"semibold",children:j.name}),j.environment&&e.jsx(is,{size:"medium",appearance:D?"filled":"tint",color:D?"warning":"informative",children:j.environment}),e.jsx(u,{size:200,className:m.secondary,children:j.url})]}):e.jsx(u,{children:"Unknown (the tool has no connection)"})}),o.map(i=>e.jsxs("div",{style:{display:"contents"},children:[e.jsx(u,{className:m.label,children:i.label}),e.jsx("div",{className:m.value,children:i.value})]},i.label))]}),te&&e.jsx(Re,{label:e.jsxs(e.Fragment,{children:["Type ",e.jsx("strong",{children:x})," to confirm"]}),hint:"Required on a Production environment.",children:e.jsx(Us,{value:H,onChange:(i,ie)=>Q(ie.value),disabled:b,autoComplete:"off","aria-label":`Type ${x} to confirm`})})]})}const ls=Ws({content:{display:"flex",flexDirection:"column",gap:c.spacingVerticalM},changes:{listStyleType:"none",margin:0,padding:0,display:"flex",flexDirection:"column",gap:c.spacingVerticalXS},change:{display:"flex",alignItems:"flex-start",gap:c.spacingHorizontalS},changeIcon:{flexShrink:0,fontSize:"16px",marginTop:"2px",color:c.colorNeutralForeground3},changeText:{flex:1,minWidth:0,overflowWrap:"anywhere"},badge:{flexShrink:0},list:{margin:`${c.spacingVerticalXS} 0 0`,paddingLeft:"20px"},options:{display:"flex",flexDirection:"column",gap:c.spacingVerticalS},timing:{color:c.colorNeutralForeground3},progressList:{display:"flex",flexDirection:"column",gap:c.spacingVerticalXS},progressRow:{display:"flex",alignItems:"center",gap:c.spacingHorizontalS},xmlHeader:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:c.spacingHorizontalS},xml:{height:"360px",border:`1px solid ${c.colorNeutralStroke2}`,borderRadius:c.borderRadiusMedium,overflow:"hidden"}}),Wn={pending:"Waiting",publishing:"Publishing…",success:"Done",error:"Failed",cancelled:"Cancelled"},Hn={pending:"subtle",publishing:"informative",success:"success",error:"danger",cancelled:"warning"},Jn={new:{text:"New",color:"success",icon:e.jsx(Rn,{})},change:{text:"Change",color:"brand",icon:e.jsx(Pn,{})},move:{text:"Move",color:"informative",icon:e.jsx(Nn,{})},show:{text:"Show",color:"informative",icon:e.jsx(kn,{})},hide:{text:"Hide",color:"warning",icon:e.jsx(Cn,{})},delete:{text:"Delete",color:"danger",icon:e.jsx(wn,{})}},ts=({findings:o,showScope:x})=>{const v=ls();return e.jsx("ul",{className:v.list,children:o.map((b,m)=>e.jsxs("li",{children:[x&&e.jsxs("strong",{children:[b.scope,": "]}),b.message]},m))})},Bs=({errors:o,onViewLog:x})=>{const v=ls();return e.jsx("ul",{className:v.list,children:o.map((b,m)=>e.jsxs("li",{children:[e.jsxs("span",{style:{fontFamily:c.fontFamilyMonospace},children:[e.jsxs("strong",{children:[b.scope,":"]})," ",b.message]}),b.importJobId&&e.jsxs(e.Fragment,{children:[" ",e.jsx(N,{size:"small",appearance:"transparent",icon:e.jsx(Hs,{}),onClick:()=>x(b),children:"View import log"})]})]},m))})},Z=(o,x,v=`${x}s`)=>`${o} ${o===1?x:v}`,Xn=3e4,Gn=6e4,tt=()=>{const o=ls(),x=$s(s=>s.bulkPublishOpen),v=$s(s=>s.closeBulkPublish),b=f(s=>s.ribbons),m=f(s=>s.baseline),P=f(s=>s.commands),_=f(s=>s.displayRules),H=f(s=>s.enableRules),Q=f(s=>s.baselineCommands),ee=f(s=>s.baselineEnableRules),se=f(s=>s.baselineDisplayRules),ne=f(s=>s.locLabels),j=f(s=>s.baseLanguageCode),D=f(s=>s.baseLanguageUnknown),te=f(s=>s.setLayerSnapshot),de=f(s=>s.markPublished),h=S(s=>s.activeSolution),i=S(s=>s.activeEntity),ie=S(s=>s.connectionUrl),as=S(s=>s.publisherPrefix),Xs=S(s=>s.solutionRibbonComponentIds),{entityPlan:z,appPlan:oe,solutionSupportsAppRibbon:Gs,includeApplicationRibbon:$,scopes:R,unsupported:A,warnings:rs,changes:J}=Tn(),[E,X]=l.useState(!1),[Ks,V]=l.useState({}),[B,Ae]=l.useState(!1),[pe,qs]=l.useState(!1),[G,Ee]=l.useState("targeted"),[cs,me]=l.useState(!1),Te=G==="allAsync"&&!cs,Ie=S(s=>s.connectionName||s.connectionUrl||"this environment"),[hs,Me]=l.useState({confirmed:!1}),Ys=M.useCallback((s,n)=>Me({confirmed:s,environment:n}),[]),us=hs.confirmed,[Zs,ds]=l.useState(0),[ps,le]=l.useState(""),[ze,ms]=l.useState(""),[ge,gs]=l.useState(h?.version??"1.0.0.0"),[$e,be]=l.useState([]),U=M.useRef(null),[Qs,Ve]=l.useState(!1),[Le,bs]=l.useState(!1),[y,ae]=l.useState(null);M.useEffect(()=>()=>U.current?.abort(),[]);const[Fe,xs]=l.useState([]),[en,sn]=l.useState(0),[nn,xe]=l.useState([]),[K,re]=l.useState("summary"),[tn,Oe]=l.useState([]),fs=M.useMemo(()=>{const n=(ge||h?.version||"1.0.0.0").split(".").map(a=>Number.parseInt(a,10)||0);for(;n.length<4;)n.push(0);return n[3]+=1,n.slice(0,4).join(".")},[h?.version,ge]);M.useEffect(()=>{gs(h?.version??"1.0.0.0")},[h?.version]);const on=i&&z?.hasChanges?i.logicalName:"application ribbon",[L,fe]=l.useState("idle"),[_e,De]=l.useState([]),[q,Be]=l.useState([]),[js,Ue]=l.useState(""),w=x&&!!h&&A.length===0&&R.length>0,ys=h?.id,Ss=h?.publisherPrefix||as,vs=M.useCallback(async()=>{const s={commands:P,enableRules:H,displayRules:_,locLabels:ne,baselineCommands:Q,baselineEnableRules:ee,baselineDisplayRules:se,publisherPrefix:Ss,languageCode:j},n={lookupWebResources:p=>Mn(p,ys)},a=[],d=[];if(i&&z?.hasChanges){const p=await Os({...s,entity:{logicalName:i.logicalName,schemaName:i.schemaName},locations:Pe.map(g=>({current:b[g],baseline:m[g]})),plan:z},n);a.push(...p.findings.map(g=>({...g,scope:i.logicalName}))),d.push({scope:i.logicalName,xml:p.xml,entity:!0,changedKeys:p.changedKeys})}if($){const p=await Os({...s,entity:null,locations:[{current:b.Application,baseline:m.Application}],plan:oe},n);a.push(...p.findings.map(g=>({...g,scope:"Application ribbon"}))),d.push({scope:"Application ribbon",xml:p.xml,entity:!1,changedKeys:p.changedKeys})}return{findings:a,xml:d}},[i,z,oe,$,b,m,P,H,_,ne,Q,ee,se,Ss,ys,j]);M.useEffect(()=>{if(!w||E||B)return;let s=!1;return fe("running"),Ue(""),_s(vs(),Xn).then(({findings:n,xml:a})=>{s||(De(n),Be(a),fe("done"))}).catch(n=>{s||(De([]),Be([]),Ue(n instanceof Error?n.message:String(n)),fe("failed"))}),()=>{s=!0}},[w,E,B,vs]);const[We,je]=l.useState("idle"),[ye,He]=l.useState([]),[ln,ws]=l.useState("");M.useEffect(()=>{if(L!=="done"||q.length===0){je("idle"),He([]);return}let s=!1;return je("running"),ws(""),_s((async()=>{const{checkRibbonSchema:a}=await pn(async()=>{const{checkRibbonSchema:p}=await import("./ribbonXsdCheck-CJBpxpVm.js");return{checkRibbonSchema:p}},__vite__mapDeps([0,1,2,3,4,5]),import.meta.url),d=[];for(const p of q){const g=await a({xml:p.xml,entity:p.entity,changedKeys:p.changedKeys});d.push(...g.map(T=>({...T,scope:p.scope})))}return d})(),Gn).then(a=>{s||(He(a),je("done"))}).catch(a=>{s||(He([]),ws(a instanceof Error?a.message:String(a)),je("unavailable"))}),()=>{s=!0}},[L,q]);const Je=We==="running"?"Checking against Microsoft's ribbon schema…":We==="unavailable"?`Microsoft's ribbon schema check couldn't run here (${ln}). It never blocks publishing.`:"",F=_e.filter(s=>s.severity==="error"),Cs=_e.filter(s=>s.severity==="warning"),Xe=q.length>1||new Set(_e.map(s=>s.scope)).size>1,ks=w&&(L==="running"||F.length>0),an=()=>{if(U.current)return;const s=new AbortController;U.current=s,cn(s.signal).finally(()=>{U.current===s&&(U.current=null),Ve(!1),bs(!1)})},rn=()=>{!U.current||Le||(bs(!0),le("Cancelling…"),ns.getState().logWarn("publish","Publish cancelled."),U.current.abort())},Ge=s=>{if(!s.importJobId)return;const n=s.importJobId;ae({scope:s.scope,importJobId:n}),re("log"),Vn(n).then(a=>ae(d=>d?.importJobId===n?{...d,xml:a}:d),a=>ae(d=>d?.importJobId===n?{...d,error:a instanceof Error?a.message:String(a)}:d))},cn=s=>Ln(async()=>{if(!h||A.length>0||R.length===0||ks||!us||D||Te)return;X(!0);const n=zn(),a=S.getState().connectionVersion,d=()=>S.getState().connectionVersion!==a,p=await Js().catch(()=>null);if(d()){X(!1);return}if(os(p?.environment)&&!os(hs.environment)){Me({confirmed:!1}),ds(t=>t+1),X(!1),ns.getState().logWarn("publish",`${p?.name??"The connection"} is a Production environment now: type the confirmation to publish.`);return}le(""),be([]),xe([]),xs(R),sn(J.length),V(Object.fromEntries(R.map(t=>[t,"pending"]))),ae(null),re("summary"),Ve(!0);let g=!1;const T=[],Ze={},W=[],Qe=t=>{s.aborted||le(t)},As=(t,r,I)=>{g=!0;const es=Fn(r);W.push({scope:t,message:we(r),importJobId:_n(r),cancelled:es,mayStillFinish:On(r)}),es?he.logWarn("publish",`${I} cancelled: ${we(r)}`):he.logError("publish",`${I} failed: ${we(r)}`),V(dn=>({...dn,[t]:es?"cancelled":"error"}))},Es=t=>{g=!0,W.push({scope:t,message:"Not published: you cancelled the publish.",cancelled:!0}),V(r=>({...r,[t]:"cancelled"}))},ve=[],he=ns.getState(),we=t=>t instanceof Error?t.message:String(t);ze.trim()&&he.logInfo("publish",`Publish comment: ${ze.trim()}`),We==="running"&&he.logInfo("publish","Microsoft's ribbon schema check hadn't finished when this publish started; its findings aren't logged.");for(const t of ye)he.logWarn("publish",`Microsoft's ribbon schema doesn't allow this (${t.scope}): ${t.message}`);const Ts={commands:P,enableRules:H,displayRules:_,locLabels:ne,baselineCommands:Q,baselineEnableRules:ee,baselineDisplayRules:se,publishCustomizations:!0,signal:s,languageCode:j,solution:{uniqueName:h.uniqueName,friendlyName:h.friendlyName,version:pe?fs:ge,publisherUniqueName:h.publisherUniqueName,publisherName:h.publisherName,publisherPrefix:h.publisherPrefix||as,publisherOptionValuePrefix:h.publisherOptionValuePrefix}};if(i&&z?.hasChanges){const t=i.logicalName;V(r=>({...r,[t]:"publishing"}));try{const r=await Ds({...Ts,guard:n,entity:{logicalName:i.logicalName,schemaName:i.schemaName,displayName:i.displayName},locations:Pe.map(I=>({current:b[I],baseline:m[I]})),plan:z},Qe);T.push(...Pe),Ze.entity=r.parts,$n(ie,i.logicalName,r.changedKeys),r.verification&&ve.push({scope:t,result:r.verification}),V(I=>({...I,[t]:"success"}))}catch(r){As(t,r,`Ribbon publish (${t})`)}}else i&&T.push(...Pe);if($&&!d()&&s.aborted)Es("Application ribbon");else if($&&!d()){const t="Application ribbon";V(r=>({...r,[t]:"publishing"}));try{const r=await Ds({...Ts,guard:n,entity:null,locations:[{current:b.Application,baseline:m.Application}],ribbonCustomizationIds:Xs??[],plan:oe},Qe);T.push("Application"),Ze.application=r.parts,r.verification&&ve.push({scope:t,result:r.verification}),V(I=>({...I,[t]:"success"}))}catch(r){As(t,r,"Application ribbon publish")}}else oe.hasChanges||T.push("Application");if(Ve(!1),!g&&G==="allAsync"&&s.aborted)Es("Publish all customizations");else if(!g&&G==="allAsync")try{await Dn(Qe,{guard:n})}catch(t){g=!0,W.push({scope:"Publish all customizations",message:we(t)})}if(d()){$&&!W.some(t=>t.scope==="Application ribbon")&&W.push({scope:"Application ribbon",message:"Not published: the tool's connection changed during the publish."}),xe(ve),be(W),Ae(!1),X(!1);return}if(de(T,Ze),i&&T.includes("HomepageGrid")&&z?.hasChanges){const t=await Ls(i.logicalName);t&&te("entity",t)}if(T.includes("Application")&&$){const t=await Ls(null);t&&te("application",t)}g||le("Done."),xe(ve),be(W),Ae(!g),X(!1)}),Ns=()=>{X(!1),V({}),xs([]),Ae(!1),le(""),be([]),xe([]),fe("idle"),De([]),Be([]),Ue(""),re("summary"),ae(null),Oe([]),Me({confirmed:!1}),Ee("targeted"),me(!1),ms(""),ds(s=>s+1),v()},Ke=oe.hasChanges&&!Gs,Se=A.length+(w?F.length:0),Ps=w?Cs.length+ye.length+(L==="failed"?1:0):0;M.useEffect(()=>{Se>0&&Oe(s=>s.includes("problems")?s:["problems",...s])},[Se]);const Y=h?D?{intent:"error",title:"Reload the entity first",text:"The organization's base language couldn't be read when the entity loaded, so labels are shown in English. Publishing now could write English texts as the base language's titles."}:A.length>0?{intent:"error",title:`${Z(A.length,"change")} can't be published yet`,text:`Undo ${A.length===1?"it":"them"} to publish the rest. Problems below says what each one is.`}:w&&F.length>0?{intent:"error",title:`The check found ${Z(F.length,"problem")}`,text:`In what this publish would import. Fix ${F.length===1?"it":"them"}, then open Publish again; Problems below lists ${F.length===1?"it":"them"}.`}:R.length===0?Ke?{intent:"warning",title:"The application ribbon can't be published from this solution",text:e.jsxs(e.Fragment,{children:["It doesn't include the Application Ribbons component. In make.powerapps.com open the solution, choose"," ",e.jsx("strong",{children:"Add existing → Application Ribbons"}),", then reload here."]})}:{intent:"info",title:"Nothing to publish",text:"Every change on this entity is already published."}:Te?{intent:"warning",title:"Confirm publishing everything",text:`Tick the confirmation under Options to publish every unpublished customization in ${Ie}.`,action:e.jsx(N,{size:"small",onClick:()=>{Ee("targeted"),me(!1)},children:"Only these ribbons"})}:null:{intent:"warning",title:"Choose a solution",text:"Publishing imports into a solution: choose one in the top bar first."},ce=i?.displayName||i?.logicalName,Rs=!!i&&!!z?.hasChanges,hn=Rs&&$?`Publish ${ce} and the application ribbon`:!Rs&&$?"Publish the application ribbon":ce?`Publish ${ce}`:"Publish",un=E?"Publishing…":J.length>0?`Publish ${Z(J.length,"change")}`:"Publish",O=!E&&!B,qe=$e.filter(s=>!s.cancelled),Ye=$e.filter(s=>s.cancelled);return e.jsx(In,{open:x,onOpenChange:s=>!s&&!E&&Ns(),size:K==="summary"?"medium":"large",title:K==="xml"?"What Publish imports":K==="log"&&y?`Import log: ${y.scope}`:hn,startActions:O?K==="summary"?e.jsx(N,{appearance:"subtle",icon:e.jsx(Sn,{}),onClick:()=>re("xml"),children:"View XML"}):e.jsx(N,{appearance:"subtle",icon:e.jsx(vn,{}),onClick:()=>re("summary"),children:"Back to summary"}):void 0,actions:e.jsxs(e.Fragment,{children:[E?e.jsx(N,{appearance:"secondary",onClick:rn,disabled:!Qs||Le,children:Le?"Cancelling…":"Cancel"}):e.jsx(N,{appearance:"secondary",onClick:Ns,children:B?"Close":"Cancel"}),!B&&e.jsx(N,{appearance:"primary",onClick:an,disabled:E||!h||R.length===0||A.length>0||ks||!us||D||Te,children:un})]}),children:K==="log"&&y?e.jsxs("div",{className:o.content,children:[e.jsxs(u,{children:["What Dataverse recorded for import job ",y.importJobId,": each component it processed, with its result."]}),y.error!==void 0?e.jsx(C,{intent:"error",layout:"multiline",children:e.jsxs(k,{children:["The import log couldn't be read: ",y.error]})}):y.xml===void 0?e.jsx(ss,{size:"tiny",labelPosition:"after",label:"Reading the import log…"}):y.xml===null?e.jsx(C,{intent:"info",layout:"multiline",children:e.jsx(k,{children:"There's no import log for this import. Dataverse writes one once it starts importing the solution; a solution file it rejects outright has none."})}):e.jsxs("div",{className:o.options,children:[e.jsxs("div",{className:o.xmlHeader,children:[e.jsx(u,{weight:"semibold",children:y.scope}),e.jsx(N,{size:"small",appearance:"subtle",icon:e.jsx(Is,{}),onClick:()=>{Vs(y.xml??"")},children:"Copy"})]}),e.jsx("div",{className:o.xml,children:e.jsx(Fs,{language:"xml",value:y.xml,readOnly:!0})})]})]}):K==="xml"&&O?e.jsxs("div",{className:o.content,children:[e.jsx(u,{children:"The complete RibbonDiffXml each import writes: your solution's layer as it is now, with your changes merged in."}),w&&L==="running"?e.jsx(ss,{size:"tiny",labelPosition:"after",label:"Building the XML…"}):q.length===0?e.jsx(C,{intent:"info",layout:"multiline",children:e.jsx(k,{children:w&&L==="failed"?`The XML couldn't be built: ${js}`:"The XML is built once there is something to publish and nothing blocks it."})}):q.map(s=>e.jsxs("div",{className:o.options,children:[e.jsxs("div",{className:o.xmlHeader,children:[e.jsx(u,{weight:"semibold",children:s.scope}),e.jsx(N,{size:"small",appearance:"subtle",icon:e.jsx(Is,{}),onClick:()=>{Vs(s.xml)},children:"Copy"})]}),e.jsx("div",{className:o.xml,children:e.jsx(Fs,{language:"xml",value:s.xml,readOnly:!0})})]},s.scope))]}):e.jsxs("div",{className:o.content,children:[O&&Y&&e.jsxs(C,{intent:Y.intent,layout:"multiline",children:[e.jsxs(k,{children:[e.jsx(ue,{children:Y.title}),Y.text]}),Y.action&&e.jsx(Ms,{children:Y.action})]}),O&&J.length>0&&e.jsxs("div",{className:o.options,children:[e.jsxs(u,{weight:"semibold",children:[Z(J.length,"change")," to publish"]}),e.jsx("ul",{className:o.changes,"aria-label":"Changes to publish",children:J.map((s,n)=>{const a=Jn[s.kind];return e.jsxs("li",{className:o.change,children:[e.jsx("span",{className:o.changeIcon,"aria-hidden":"true",children:a.icon}),e.jsxs(u,{className:o.changeText,children:[s.action," ",e.jsx("strong",{children:s.name}),s.detail?` ${s.detail}`:""]}),e.jsx(is,{appearance:"tint",color:a.color,size:"medium",className:o.badge,children:a.text})]},n)})})]}),O&&w&&L==="running"&&e.jsx(ss,{size:"tiny",labelPosition:"after",label:"Checking what this publish would import…"}),O&&e.jsx(Un,{rows:[{label:"Solution",value:h?e.jsx(u,{weight:"semibold",children:h.friendlyName||h.uniqueName}):e.jsx(u,{children:"None selected"})}],confirmWord:on,onConfirmationChange:Ys},Zs),O&&e.jsxs(mn,{multiple:!0,collapsible:!0,openItems:tn,onToggle:(s,n)=>Oe(n.openItems),children:[Se>0&&e.jsxs(Ce,{value:"problems",children:[e.jsxs(ke,{children:["Problems · ",Se]}),e.jsxs(Ne,{children:[A.length>0&&e.jsxs(e.Fragment,{children:[e.jsx(u,{block:!0,children:"These changes can't be published yet; undo them:"}),e.jsx("ul",{className:o.list,children:A.map(s=>e.jsx("li",{children:s},s))})]}),w&&F.length>0&&e.jsx(ts,{findings:F,showScope:Xe})]})]}),Ps>0&&e.jsxs(Ce,{value:"warnings",children:[e.jsxs(ke,{children:["Warnings · ",Ps]}),e.jsxs(Ne,{children:[e.jsx(u,{block:!0,children:"You can still publish."}),L==="failed"&&e.jsxs(u,{block:!0,children:["The check before publishing couldn't complete (",js,"). Publishing runs it again before anything is imported."]}),e.jsx(ts,{findings:Cs,showScope:Xe}),ye.length>0&&e.jsxs(e.Fragment,{children:[e.jsx(u,{block:!0,weight:"semibold",children:"Microsoft's ribbon schema"}),e.jsx(u,{block:!0,children:"Microsoft's schema from 2017 doesn't allow these. Dataverse may still accept them; if it rejects the import, Publish shows its error."}),e.jsx(ts,{findings:ye,showScope:Xe})]})]})]}),e.jsxs(Ce,{value:"info",children:[e.jsxs(ke,{children:["Good to know ·"," ",rs.length+1+(Ke&&R.length>0?1:0)+(Je?1:0)]}),e.jsx(Ne,{children:e.jsxs("ul",{className:o.list,children:[e.jsx("li",{children:"Publishing writes this entity's complete ribbon customization: what is already published, plus your changes. Ribbon changes imported elsewhere but not published are published first, so they are kept. Each ribbon is imported twice so Unified Interface picks up the change."}),Ke&&R.length>0&&e.jsxs("li",{children:["Your application ribbon changes stay pending: this solution doesn't include the Application Ribbons component. In make.powerapps.com open the solution, choose"," ",e.jsx("strong",{children:"Add existing → Application Ribbons"}),", then reload here."]}),rs.map(s=>e.jsx("li",{children:s},s)),Je&&e.jsx("li",{children:Je})]})})]}),e.jsxs(Ce,{value:"options",children:[e.jsx(ke,{children:"Options"}),e.jsxs(Ne,{className:o.options,children:[e.jsx(Re,{label:"Also publish",children:e.jsxs(gn,{value:G==="targeted"?"Only these ribbons":"Every unpublished customization",selectedOptions:[G],onOptionSelect:(s,n)=>{(n.optionValue==="targeted"||n.optionValue==="allAsync")&&(Ee(n.optionValue),me(!1))},children:[e.jsx(zs,{value:"targeted",children:"Only these ribbons"}),e.jsx(zs,{value:"allAsync",children:"Every unpublished customization"})]})}),G==="allAsync"&&e.jsx(C,{intent:"warning",layout:"multiline",children:e.jsxs(k,{children:[e.jsxs(u,{block:!0,children:["This publishes ",e.jsx("strong",{children:"every"})," ","unpublished customization in"," ",e.jsx("strong",{children:Ie}),", not only these ribbons: forms, views, entities and other people's work in progress included."]}),e.jsx(bn,{checked:cs,onChange:(s,n)=>me(n.checked===!0),label:`Publish all unpublished customizations in ${Ie}`})]})}),e.jsx(xn,{label:"Increment solution version",checked:pe,onChange:(s,n)=>qs(n.checked===!0)}),e.jsx(Re,{label:"Solution version",children:e.jsx(Us,{value:pe?fs:ge,onChange:(s,n)=>gs(n.value),disabled:pe})}),e.jsx(Re,{label:"Publish comment",hint:"Written to the Console log with this publish; it isn't stored in Dataverse.",children:e.jsx(fn,{resize:"vertical",value:ze,onChange:(s,n)=>ms(n.value)})})]})]})]}),O&&R.length>0&&e.jsx(jn,{className:o.timing,children:"Publishing takes 1–4 minutes. Users may need to refresh to see the change."}),Ye.length>0&&e.jsx(C,{intent:"warning",layout:"multiline",children:e.jsxs(k,{children:[e.jsx(ue,{children:"Publish cancelled"}),Ye.some(s=>s.mayStillFinish)?"An import that was already running may still finish in Dataverse. Check Solutions › History before you publish again.":"What didn't publish stays to publish.",e.jsx(Bs,{errors:Ye,onViewLog:Ge})]})}),qe.length>0&&e.jsx(C,{intent:"error",layout:"multiline",children:e.jsxs(k,{children:[e.jsxs(ue,{children:["Publish failed (",Z(qe.length,"error"),")"]}),e.jsx(Bs,{errors:qe,onViewLog:Ge}),e.jsxs("div",{style:{marginTop:c.spacingVerticalS},children:["Full details are in the ",e.jsx("strong",{children:"Console"})," tab of the bottom panel."]})]})}),B&&e.jsx(C,{intent:"success",layout:"multiline",children:e.jsxs(k,{children:[e.jsxs(ue,{children:["Published ",Z(en,"change"),ce&&Fe.includes(i?.logicalName??"")?` to ${ce}`:""]}),"Unified Interface can take up to about 25 minutes to show it. To see it sooner, run ",e.jsx("strong",{children:"Regenerate ribbon metadata"})," in Command Checker, or hard-refresh the page (Ctrl+F5)."]})}),nn.map(s=>e.jsxs(C,{intent:s.result.ok?"success":"warning",layout:"multiline",children:[e.jsxs(k,{children:[e.jsxs("strong",{children:[s.scope,":"]})," ",s.result.message]}),s.result.importJobId&&e.jsx(Ms,{children:e.jsx(N,{size:"small",icon:e.jsx(Hs,{}),onClick:()=>Ge({scope:s.scope,message:s.result.message,importJobId:s.result.importJobId}),children:"View import log"})})]},s.scope)),(E||B||$e.length>0)&&Fe.length>0&&e.jsxs("div",{className:o.progressList,children:[Fe.map(s=>{const n=Ks[s]??"pending";return e.jsxs("div",{className:o.progressRow,children:[e.jsx(is,{appearance:"filled",color:Hn[n],size:"medium",className:o.badge,children:Wn[n]}),e.jsx(u,{children:s}),n==="publishing"&&e.jsx(yn,{thickness:"large",style:{flex:1}})]},s)}),ps&&E&&e.jsx(u,{className:o.timing,children:ps})]})]})})};export{tt as BulkPublishModal,tt as default};
@@ -0,0 +1 @@
1
+ import{r as I,j as s,m as be,c as R,Y as se,Z as ae,k as b,aC as J,a0 as re,a1 as oe,a4 as W,z as G,ej as he,y as w,aB as K,I as ge,dL as xe,dM as fe,cN as je,cL as we,T as ye,az as ve,aA as _,eh as Y,$ as Ce,ar as Re,dY as Ne,af as Se,ag as Ae,t as o}from"./fluent-ui-BThr2m8u.js";import{D as ke,c as Ee,S as Te,v as $e,f as De,C as Me,g as Be}from"./dnd-C19d6Mn0.js";import{b as y,a as x,H as Ie,a6 as _e,u as We,c as Le,a7 as Pe,a8 as Oe,a9 as Fe,M as ze,N as q,a3 as Q,aa as He}from"./index-Df9NSpg6.js";import{C as Z}from"./CrmParameterEditor-DfZv5BuF.js";import{W as ee}from"./crmParameters-Dxz06tk4.js";import{u as Ue}from"./useStableKeys-EsghhjoV.js";import"./preload-helper-PPVm8Dsz.js";const ne=be({body:{display:"flex",flexDirection:"column",gap:o.spacingVerticalM},actionCard:{border:`1px solid ${o.colorNeutralStroke2}`,borderRadius:o.borderRadiusMedium,backgroundColor:o.colorNeutralBackground1,padding:o.spacingVerticalM,display:"flex",flexDirection:"column",gap:o.spacingVerticalS},actionHeader:{display:"flex",alignItems:"center",gap:o.spacingHorizontalXS,minWidth:0},actionTitle:{flex:1,minWidth:0},dragHandle:{cursor:"grab",touchAction:"none"},row:{display:"flex",flexWrap:"wrap",gap:o.spacingHorizontalS,alignItems:"flex-end"},library:{display:"flex",gap:o.spacingHorizontalXS,alignItems:"center"},grow:{flex:1,minWidth:0},ruleTags:{flexWrap:"wrap"},muted:{color:o.colorNeutralForeground3},usesList:{listStyleType:"none",margin:0,padding:0,display:"flex",flexDirection:"column",gap:o.spacingVerticalXS},use:{border:`1px solid ${o.colorNeutralStroke2}`,borderRadius:o.borderRadiusMedium,padding:`${o.spacingVerticalXS} ${o.spacingHorizontalS}`,display:"flex",flexDirection:"column",minWidth:0},fields:{border:"none",margin:0,padding:0,minWidth:0,display:"flex",flexDirection:"column",gap:o.spacingVerticalS,"&:disabled .fui-Input, &:disabled .fui-Select__select, &:disabled .fui-Dropdown, &:disabled .fui-Combobox":{backgroundColor:o.colorNeutralBackground3,borderTopColor:o.colorTransparentStroke,borderRightColor:o.colorTransparentStroke,borderBottomColor:o.colorTransparentStroke,borderLeftColor:o.colorTransparentStroke,color:o.colorNeutralForeground1,cursor:"default"},"&:disabled .fui-Input::after, &:disabled .fui-Dropdown::after, &:disabled .fui-Combobox::after":{display:"none"},"&:disabled input, &:disabled .fui-Dropdown__button":{color:o.colorNeutralForeground1,cursor:"default"},"&:disabled .fui-Select__icon, &:disabled .fui-Dropdown__expandIcon, &:disabled .fui-Combobox__expandIcon":{display:"none"},"&:disabled .fui-Button":{color:o.colorNeutralForegroundDisabled,borderTopColor:o.colorNeutralStrokeDisabled,borderRightColor:o.colorNeutralStrokeDisabled,borderBottomColor:o.colorNeutralStrokeDisabled,borderLeftColor:o.colorNeutralStrokeDisabled,cursor:"not-allowed"}}}),Ve=[],Xe=n=>{const d=n.trim();return d.startsWith("$webresource:")?d.slice(13).trim():d};function Je(n){switch(n.kind){case"javascript":return"Run JavaScript";case"url":return"Open a URL";case"powerFx":return"Power Fx (not supported)";case"customApi":return"Custom API (not supported)";case"outlookCommand":return"Outlook command";case"raw":return n.tagName;default:return"Action"}}function Ge({id:n,index:d,count:m,title:N,readOnly:f,onMove:S,onRemove:D,children:v}){const C=ne(),{attributes:L,listeners:M,setNodeRef:A,setActivatorNodeRef:k,transform:E,transition:P}=De({id:n,disabled:f});return s.jsxs("section",{ref:A,style:{transform:Me.Transform.toString(E),transition:P},className:C.actionCard,"aria-label":`Action ${d+1}: ${N}`,children:[s.jsxs("div",{className:C.actionHeader,children:[!f&&m>1&&s.jsx(b,{ref:k,appearance:"subtle",size:"small",className:C.dragHandle,icon:s.jsx(xe,{}),"aria-label":"Drag to reorder action",...L,...M}),s.jsx(R,{weight:"semibold",className:C.actionTitle,truncate:!0,wrap:!1,children:N}),!f&&m>1&&s.jsxs(se,{children:[s.jsx(ae,{disableButtonEnhancement:!0,children:s.jsx(b,{appearance:"subtle",size:"small",icon:s.jsx(fe,{}),"aria-label":"More for this action"})}),s.jsx(re,{children:s.jsxs(oe,{children:[s.jsx(W,{icon:s.jsx(je,{}),disabled:d===0,onClick:()=>S(d,d-1),children:"Move up"}),s.jsx(W,{icon:s.jsx(we,{}),disabled:d===m-1,onClick:()=>S(d,d+1),children:"Move down"})]})})]}),!f&&s.jsx(ye,{content:"Remove action",relationship:"label",children:s.jsx(b,{appearance:"subtle",size:"small",icon:s.jsx(ve,{}),onClick:D})})]}),v]})}const as=()=>{const n=ne(),d=y(e=>e.commandEditorOpen),m=y(e=>e.commandEditorId),N=y(e=>e.closeCommandEditor),f=y(e=>e.openRuleEditor),S=y(e=>e.openScriptView),D=y(e=>e.openWebResourceBrowser),v=y(e=>e.commandEditorTab),C=x(e=>e.commands),L=x(e=>e.upsertCommand),M=x(e=>e.ribbons),A=x(e=>e.locLabels),k=x(e=>e.displayRules),E=x(e=>e.enableRules),P=x(e=>e.upsertEnableRule),le=x(e=>e.upsertDisplayRule),O=Ie(),[ie,z]=I.useState(""),[te,H]=I.useState(""),i=C.find(e=>e.id===m),h=Ue(`actions:${i?.id??""}`,i?.actions??Ve),j=_e(We(i?.id));I.useEffect(()=>{d&&m&&!i&&N()},[d,m,i,N]);const B=I.useMemo(()=>m?Le(M,m):[],[M,m]);if(!i)return null;const T=e=>{L({...i,...e})},p=(e,a)=>{const l=[...i.actions];l[e]=a,T({actions:l}),h.update()},de=e=>{T({actions:i.actions.filter((a,l)=>l!==e)}),h.remove(e)},U=(e,a)=>{a<0||a>=i.actions.length||e===a||(T({actions:Be(i.actions,e,a)}),h.move(e,a))},ce=e=>{e.over&&U(h.keys.indexOf(String(e.active.id)),h.keys.indexOf(String(e.over.id)))},V=e=>{const a=e==="javascript"?{kind:"javascript",library:"",functionName:"",params:[]}:{kind:"url",address:"https://",params:[]};T({actions:[...i.actions,a]}),h.add()},ue=(e,a)=>{if(e.kind==="javascript"){const l=Xe(e.library);return s.jsxs(s.Fragment,{children:[s.jsxs("fieldset",{disabled:j,className:n.fields,children:[s.jsx(w,{label:"Library",hint:"A JavaScript web resource, like $webresource:publisher_/scripts/file.js.",children:s.jsxs("div",{className:n.library,children:[s.jsx(_,{className:n.grow,value:e.library,onChange:(t,c)=>p(a,{...e,library:c.value.replace(/^(\s*\$webresource:\s*)+/i,"$webresource:")}),placeholder:"$webresource:publisher_/scripts/file.js"}),s.jsx(b,{onClick:()=>{Q.set(t=>{p(a,{...e,library:`$webresource:${t.name}`})}),D()},children:"Browse…"})]})}),s.jsx(w,{label:"Function",hint:"The function's full name, including its namespace.",children:s.jsx(_,{value:e.functionName,onChange:(t,c)=>p(a,{...e,functionName:c.value}),placeholder:"Contoso.Account.approve"})}),s.jsx(Y,{weight:"semibold",children:"Parameters, in order"}),s.jsx(Z,{params:e.params,onChange:t=>p(a,{...e,params:t}),urlMode:!1})]}),s.jsxs("div",{className:n.row,children:[s.jsx(b,{size:"small",icon:s.jsx(Ce,{}),disabled:!l,onClick:()=>S(l,!1),children:"View script"}),!j&&s.jsx(b,{size:"small",icon:s.jsx(Re,{}),disabled:!l,onClick:()=>S(l,!0),children:"Edit script"})]})]})}if(e.kind==="url"){const l=e.address.trim(),t=/^\$webresource:/i.test(l),c=!l||/^https?:\/\/$/i.test(l)||/^\$webresource:$/i.test(l)?"error":/^http:\/\//i.test(l)?"warning":"none",$=c==="error"?"Enter the address to open, or pick a web resource.":c==="warning"?"Use https://: a dialog can't show an http:// page.":void 0;return s.jsxs("fieldset",{disabled:j,className:n.fields,children:[s.jsx(w,{label:"Address",validationState:c,validationMessage:$,hint:t?`A web resource reads only these query string names: ${ee.join(", ")}. Put your own values in data.`:"An https:// address, a relative address, or $webresource:<name>.",children:s.jsxs("div",{className:n.library,children:[s.jsx(_,{className:n.grow,value:e.address,onChange:(g,r)=>p(a,{...e,address:r.value.replace(/^(\s*\$webresource:\s*)+/i,"$webresource:")}),placeholder:"https://"}),s.jsx(b,{onClick:()=>{Q.set(g=>{p(a,{...e,address:`$webresource:${g.name}`})}),D()},children:"Browse…"})]})}),s.jsx(w,{label:"Open in",children:s.jsxs(K,{value:String(e.winMode??0),onChange:(g,r)=>p(a,{...e,winMode:parseInt(r.value)}),children:[s.jsx("option",{value:"0",children:"New window (default)"}),s.jsx("option",{value:"1",children:"Modal dialog"}),s.jsx("option",{value:"2",children:"Modeless dialog"})]})}),s.jsx(w,{label:"Window settings",hint:"Optional. The dialog's size, for example dialogWidth:640px;dialogHeight:480px.",children:s.jsx(_,{value:e.winParams??"",onChange:(g,r)=>p(a,{...e,winParams:r.value.trim()?r.value:void 0}),placeholder:"dialogWidth:640px;dialogHeight:480px"})}),s.jsx(w,{hint:"Adds the record's details to the address: typename, type, id, orgname and the user's languages.",children:s.jsx(Ne,{label:"Pass parameters",checked:!!e.passParams,onChange:(g,r)=>p(a,{...e,passParams:r.checked?!0:void 0})})}),s.jsx(Y,{weight:"semibold",children:"Query string parameters"}),s.jsx(Z,{params:e.params,onChange:g=>p(a,{...e,params:g}),urlMode:!0,allowedNames:t?ee:void 0})]})}return e.kind==="powerFx"||e.kind==="customApi"?s.jsx(Se,{intent:"error",children:s.jsxs(Ae,{children:["Classic ribbon commands can't run"," ",e.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"," ",s.jsx("code",{children:"Xrm.WebApi.online.execute"}),"), or build the command with modern commanding in the app designer."]})}):e.kind==="outlookCommand"||e.kind==="raw"?s.jsx(R,{size:200,className:n.muted,children:e.kind==="outlookCommand"?`ActionType="${e.actionType}"${e.data?` Data="${e.data}"`:""}`:e.xml}):null},me=()=>s.jsxs(s.Fragment,{children:[s.jsx(ke,{collisionDetection:Ee,onDragEnd:ce,children:s.jsx(Te,{items:h.keys,strategy:$e,children:i.actions.map((e,a)=>s.jsx(Ge,{id:h.keys[a],index:a,count:i.actions.length,title:Je(e),readOnly:j,onMove:U,onRemove:()=>de(a),children:ue(e,a)},h.keys[a]))})}),i.actions.length===0&&s.jsx(R,{className:n.muted,children:"No actions yet. The button does nothing when it's clicked."}),!j&&s.jsx("div",{children:s.jsxs(se,{children:[s.jsx(ae,{disableButtonEnhancement:!0,children:s.jsx(b,{icon:s.jsx(J,{}),children:"Add action"})}),s.jsx(re,{children:s.jsxs(oe,{children:[s.jsx(W,{onClick:()=>V("javascript"),children:"Run JavaScript"}),s.jsx(W,{onClick:()=>V("url"),children:"Open a URL"})]})})]})}),s.jsx(G,{className:n.muted,children:"Every user's browser gets the command's definition, even when the button is hidden. Don't put secrets in function names or parameters."})]}),X=e=>{const a=e==="enable"?i.enableRules:i.displayRules,l=(e==="enable"?E:k).map(r=>r.id).filter(r=>!a.includes(r)),t=e==="enable"&&(B.length===0||B.some(r=>r.location==="HomepageGrid"))?Oe.filter(r=>!a.includes(r.id)&&!l.includes(r.id)):[],c=e==="enable"?ie:te,$=r=>T(e==="enable"?{enableRules:r}:{displayRules:r}),g=()=>{const r=new Set([...E.map(F=>F.id),...k.map(F=>F.id)]),u=He("New",e==="enable"?"Enable":"Display",r);e==="enable"?P({id:u,steps:[]}):le({id:u,steps:[]}),$([...a,u]),f(u,e)};return s.jsxs(s.Fragment,{children:[a.length>0?s.jsx(he,{className:n.ruleTags,"aria-label":e==="enable"?"Enable rules":"Display rules",children:a.map(r=>s.jsx(Fe,{ruleId:r,kind:e,onOpen:(e==="enable"?E:k).some(u=>u.id===r)?()=>f(r,e):void 0,onRemove:j?void 0:()=>$(a.filter(u=>u!==r))},r))}):s.jsxs(R,{className:n.muted,children:["No ",e," rules, so the button is always"," ",e==="enable"?"enabled":"shown","."]}),!j&&s.jsxs("div",{className:n.row,children:[s.jsx(w,{label:`Add an existing ${e} rule`,style:{flex:"1 1 260px",minWidth:0},children:s.jsxs(K,{style:{width:"100%",maxWidth:"100%",minWidth:0},value:c,onChange:(r,u)=>e==="enable"?z(u.value):H(u.value),children:[s.jsx("option",{value:"",children:"Select a rule…"}),l.map(r=>s.jsx("option",{value:r,children:r},r)),t.length>0&&s.jsx("optgroup",{label:"Microsoft's grid rules",children:t.map(r=>s.jsxs("option",{value:r.id,children:[r.label," (",r.id,")"]},r.id))})]})}),s.jsx(b,{disabled:!c,onClick:()=>{c&&($([...a,c]),e==="enable"?z(""):H(""))},children:"Add"}),s.jsxs(b,{appearance:"subtle",icon:s.jsx(J,{}),onClick:g,children:["New ",e," rule"]})]}),e==="enable"&&s.jsx(ge,{size:"small",info:"Disabled buttons are hidden in the modern command bar (Unified Interface). In the classic ribbon, they stay visible but do nothing when clicked.",children:"What a failing enable rule does"})]})},pe=()=>B.length===0?s.jsx(R,{className:n.muted,children:"No button uses this command."}):s.jsx("ul",{className:n.usesList,"aria-label":"Buttons using this command",children:B.map(({location:e,tab:a,group:l,button:t})=>s.jsxs("li",{className:n.use,children:[s.jsx(R,{weight:"semibold",truncate:!0,wrap:!1,children:O(t.label,A,void 0,t.source?.labelToken)||t.id}),s.jsx(G,{className:n.muted,children:[ze[e].label,q(a.id,O(a.label,A)),q(l.id,O(l.label,A))].join(" › ")})]},`${e}:${a.id}:${l.id}:${t.id}`))});return s.jsxs("div",{className:n.body,children:[s.jsx(Pe,{commandId:i.id,hideBadge:!0}),v==="actions"&&me(),v==="enable"&&X("enable"),v==="display"&&X("display"),v==="usedBy"&&pe()]})};export{as as CommandEditorPanel,as as default};
@@ -0,0 +1 @@
1
+ import{r as w,j as s,D as re,f as ce,dZ as de,z as m,B as ue,c as ne,e as pe,m as me,t as n}from"./fluent-ui-BThr2m8u.js";import{b as c,a as d,H as he,d as fe,J as be,o as S,L as ge,C as xe,q as we,M as ke,N as se}from"./index-Df9NSpg6.js";import"./preload-helper-PPVm8Dsz.js";import"./dnd-C19d6Mn0.js";const ye=me({surface:{width:"calc(100vw - 32px)",maxWidth:"640px",padding:0,alignSelf:"flex-start",marginTop:"10vh",overflow:"hidden",display:"flex",flexDirection:"column",maxHeight:"calc(80vh)"},search:{padding:n.spacingVerticalM,borderBottom:`1px solid ${n.colorNeutralStroke2}`},searchBox:{width:"100%",maxWidth:"none"},results:{overflowY:"auto",padding:`${n.spacingVerticalXS} 0`,minHeight:0,flex:1},groupLabel:{display:"block",padding:`${n.spacingVerticalS} ${n.spacingHorizontalM} ${n.spacingVerticalXXS}`,color:n.colorNeutralForeground3,fontWeight:n.fontWeightSemibold},item:{display:"flex",alignItems:"center",gap:n.spacingHorizontalS,padding:`${n.spacingVerticalS} ${n.spacingHorizontalM}`,cursor:"pointer",minWidth:0},itemActive:{backgroundColor:n.colorNeutralBackground1Selected,boxShadow:`inset 2px 0 0 ${n.colorBrandStroke1}`},kind:{flexShrink:0,minWidth:"72px",justifyContent:"center"},itemText:{flex:1,minWidth:0,display:"flex",flexDirection:"column"},itemLabel:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},itemSub:{color:n.colorNeutralForeground3,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},more:{display:"block",padding:`${n.spacingVerticalXXS} ${n.spacingHorizontalM}`,color:n.colorNeutralForeground3},empty:{display:"block",padding:n.spacingVerticalL,textAlign:"center",color:n.colorNeutralForeground3},footer:{display:"flex",flexWrap:"wrap",gap:n.spacingHorizontalL,padding:`${n.spacingVerticalS} ${n.spacingHorizontalM}`,borderTop:`1px solid ${n.colorNeutralStroke2}`,color:n.colorNeutralForeground3}}),ve={action:"Action",button:"Button",command:"Command",enable:"Enable rule",display:"Display rule",table:"Entity"},Se=[{kinds:["action"],title:"Actions",limit:1/0},{kinds:["button"],title:"Buttons",limit:20},{kinds:["command"],title:"Commands",limit:30},{kinds:["enable","display"],title:"Rules",limit:30},{kinds:["table"],title:"Entities",limit:30}],D=i=>`palette-${i.replace(/[^\w-]/g,"_")}`,Ie=()=>{const i=ye(),$=c(e=>e.commandPaletteOpen),ie=c(e=>e.setCommandPaletteOpen),E=c(e=>e.openBulkPublish),R=c(e=>e.openXmlDrawer),k=c(e=>e.openImportXml),T=c(e=>e.openCommandEditor),X=c(e=>e.openRuleEditor),O=c(e=>e.openNewGroup),z=c(e=>e.openNewButton),A=c(e=>e.openLocalizationEditor),V=d(e=>e.undo),W=d(e=>e.redo),H=d(e=>e.past.length>0),P=d(e=>e.future.length>0),F=d(e=>e.commands),G=d(e=>e.displayRules),q=d(e=>e.enableRules),j=d(e=>e.ribbons),N=d(e=>e.locLabels),C=he(),U=fe(e=>e.entities),_=be(e=>e.requestEntitySwitch),I=S(e=>e.location),K=S(e=>e.tabId),Y=S(e=>e.selectedButtonId),L=S(e=>e.selectedGroupId),Z=S(e=>e.selectButtonInContext),[x,J]=w.useState(""),[le,h]=w.useState(0),Q=w.useRef(null),ee=()=>{ie(!1),J(""),h(0)},y=x.startsWith("/")?"actions":x.startsWith("@")?"tables":"all",M=(y==="all"?x:x.slice(1)).trim().toLowerCase(),te=w.useMemo(()=>{if(!$)return[];const e=[],t=j[I].tabs.find(o=>o.id===K),a=L??t?.groups[0]?.id??null,u=ge(t?.groups.find(o=>o.id===L),Y),p=(o,r,l,b)=>e.push({id:`act-${o}`,label:r,subtitle:l,kind:"action",run:b});p("publish","Publish…","Review and publish your changes",E),p("view-xml","View XML","The XML of your changes",()=>R(I)),p("import-xml","Import XML…","Import RibbonDiffXml from the clipboard",()=>{const o="Couldn't read the clipboard here: paste the XML into the editor (Ctrl+V).",r=navigator.clipboard?.readText?.();if(!r)return k("",o);r.then(l=>l.trim().startsWith("<")?k(l):k("","The clipboard doesn't hold XML: paste the XML into the editor."),()=>k("",o))}),t&&p("new-group","New group…","In the current tab",O),a&&p("new-button","New button…","In the selected or first group",()=>z(a)),u&&!xe(u.kind)&&(u.origin===void 0||u.origin==="unmanaged")&&p("translations","Translations…","The selected button's text",()=>A(u.id)),H&&p("undo","Undo","Ctrl+Z",V),P&&p("redo","Redo","Ctrl+Y",W);for(const[o,r]of Object.entries(j))for(const l of r.tabs)for(const b of l.groups)for(const g of we(b))e.push({id:`btn-${o}-${g.id}`,label:C(g.label,N,void 0,g.source?.labelToken)||g.id,subtitle:[ke[o].label,se(l.id,C(l.label,N,void 0,l.source?.titleToken)),se(b.id,C(b.label,N,void 0,b.source?.titleToken))].join(" › "),keywords:`${g.label} ${g.id}`,kind:"button",run:()=>Z(o,l.id,b.id,g.id)});for(const o of F)e.push({id:`cmd-${o.id}`,label:o.id,subtitle:`${o.actions.length} action${o.actions.length===1?"":"s"}`,kind:"command",run:()=>T(o.id)});for(const[o,r]of[[q,"enable"],[G,"display"]])for(const l of o)e.push({id:`${r}-${l.id}`,label:l.id,subtitle:`${l.steps.length} step${l.steps.length===1?"":"s"}`,kind:r,run:()=>X(l.id,r)});for(const o of U)e.push({id:`ent-${o.logicalName}`,label:o.displayName,subtitle:o.logicalName,kind:"table",run:()=>_(o)});return e},[$,j,I,K,L,Y,H,P,F,q,G,U,N,C,E,R,k,O,z,A,T,X,V,W,Z,_]),B=w.useMemo(()=>{const e=t=>!M||[t.label,t.subtitle??"",t.keywords??""].some(a=>a.toLowerCase().includes(M));return Se.filter(t=>y==="all"||y==="actions"&&t.kinds.includes("action")||y==="tables"&&t.kinds.includes("table")).map(t=>{const a=te.filter(u=>t.kinds.includes(u.kind)&&e(u));return{...t,shown:a.slice(0,t.limit),more:Math.max(0,a.length-t.limit)}}).filter(t=>t.shown.length>0)},[te,M,y]),v=B.flatMap(e=>e.shown),f=v[Math.min(le,v.length-1)];w.useEffect(()=>{f&&Q.current?.querySelector(`#${D(f.id)}`)?.scrollIntoView?.({block:"nearest"})},[f]);const oe=e=>{e&&(ee(),e.run())},ae=e=>{e.key==="ArrowDown"?(e.preventDefault(),h(t=>Math.min(t+1,v.length-1))):e.key==="ArrowUp"?(e.preventDefault(),h(t=>Math.max(t-1,0))):e.key==="Home"?(e.preventDefault(),h(0)):e.key==="End"?(e.preventDefault(),h(v.length-1)):e.key==="Enter"&&(e.preventDefault(),oe(f))};return s.jsx(re,{open:$,onOpenChange:(e,t)=>!t.open&&ee(),children:s.jsxs(ce,{className:i.surface,"aria-label":"Command palette",children:[s.jsx("div",{className:i.search,children:s.jsx(de,{className:i.searchBox,size:"large",autoFocus:!0,placeholder:"Search buttons, commands, rules and entities",value:x,onChange:(e,t)=>{J(t.value),h(0)},input:{role:"combobox","aria-label":"Search","aria-expanded":!0,"aria-controls":"palette-results","aria-activedescendant":f?D(f.id):void 0,"aria-autocomplete":"list",onKeyDown:ae}})}),s.jsxs("div",{ref:Q,id:"palette-results",role:"listbox","aria-label":"Results",className:i.results,children:[B.map(e=>s.jsxs("div",{role:"group","aria-label":e.title,children:[s.jsx(m,{className:i.groupLabel,role:"presentation",children:e.title}),e.shown.map(t=>{const a=t===f;return s.jsxs("div",{id:D(t.id),role:"option","aria-selected":a,className:pe(i.item,a&&i.itemActive),onClick:()=>oe(t),onMouseMove:()=>h(v.indexOf(t)),children:[s.jsx(ue,{className:i.kind,appearance:"tint",size:"medium",color:t.kind==="action"?"brand":"informative",children:ve[t.kind]}),s.jsxs("span",{className:i.itemText,children:[s.jsx(ne,{className:i.itemLabel,children:t.label}),t.subtitle&&s.jsx(m,{className:i.itemSub,children:t.subtitle})]})]},t.id)}),e.more>0&&s.jsxs(m,{className:i.more,role:"presentation",children:[e.more," more: keep typing to narrow it down."]})]},e.title)),B.length===0&&s.jsxs(ne,{className:i.empty,role:"presentation",children:["Nothing matches “",x,"”."]})]}),s.jsxs("div",{className:i.footer,"aria-hidden":"true",children:[s.jsx(m,{children:"↑ ↓ move"}),s.jsx(m,{children:"Enter choose"}),s.jsx(m,{children:"Esc close"}),s.jsx(m,{children:"/ actions only"}),s.jsx(m,{children:"@ entities only"})]})]})})};export{Ie as CommandPalette,Ie as default};
@@ -0,0 +1,11 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./monacoSetup-BRltj-y7.js","./monaco-DzBcrxae.js","./fluent-ui-BThr2m8u.js","./preload-helper-PPVm8Dsz.js","./monaco-DQA8g3bM.css"])))=>i.map(i=>d[i]);
2
+ import{_ as D}from"./preload-helper-PPVm8Dsz.js";import{r as N,W as v,j as s,c as k,dF as V,t as b,k as W,e5 as O,af as H,ag as G,z as Y,B as z,e6 as q,e7 as I,m as K}from"./fluent-ui-BThr2m8u.js";import{h as J,a as p,d as Q,E as Z,ak as ee,b as se,al as X,ai as te,am as ne}from"./index-Df9NSpg6.js";import{g as $,w as ae}from"./publishService-CKoTOngS.js";import"./dnd-C19d6Mn0.js";import"./xmlValidator-Dki8Hf7Y.js";import"./crmParameters-Dxz06tk4.js";const E={status:"fallback",before:"",after:""},ie=3e4;function oe(n){const{entityPlan:a,appPlan:m,includeApplicationRibbon:e,unsupported:r}=J(),h=p(t=>t.ribbons),y=p(t=>t.baseline),S=p(t=>t.commands),g=p(t=>t.enableRules),c=p(t=>t.displayRules),l=p(t=>t.locLabels),w=p(t=>t.baseLanguageCode),d=Q(t=>t.activeEntity),[P,u]=N.useState({...E,status:"loading"}),j=r.join(`
3
+ `);return N.useEffect(()=>{if(!n)return;if(j){u({...E,note:"Publish can't write some of these changes yet (the publish dialog says which), so this compares the XML generated from your changes."});return}const t={commands:S,enableRules:g,displayRules:c,locLabels:l,languageCode:w},R=[...d&&a?.hasChanges?[{name:d.logicalName,run:()=>$({...t,entity:{logicalName:d.logicalName,schemaName:d.schemaName},locations:Z.map(i=>({current:h[i],baseline:y[i]})),plan:a})}]:[],...e?[{name:"Application ribbon",run:()=>$({...t,entity:null,locations:[{current:h.Application,baseline:y.Application}],plan:m})}]:[]];if(R.length===0){u(E);return}let L=!1;u(i=>({...i,status:"loading"}));const C=m.hasChanges&&!e?"Your application ribbon changes aren't shown: Publish can't import them until the solution has the Application Ribbons component.":void 0;return ae(Promise.all(R.map(async i=>({name:i.name,merged:await i.run()}))),ie).then(i=>{if(L)return;const T=i.length>1,o=f=>i.map(x=>(T?`<!-- ${x.name} -->
4
+ `:"")+f(x.merged)).join(`
5
+
6
+ `);u({status:"ready",before:o(f=>ee(f.layer)),after:o(f=>f.xml),note:C})}).catch(i=>{L||u({...E,note:`Couldn't build what Publish writes (${i instanceof Error?i.message:String(i)}), so this compares the XML generated from your changes.`})}),()=>{L=!0}},[n,j,d,a,m,e,h,y,S,g,c,l,w]),P}const re=v.lazy(()=>D(()=>import("./monacoSetup-BRltj-y7.js"),__vite__mapDeps([0,1,2,3,4]),import.meta.url).then(()=>D(()=>import("./monaco-DzBcrxae.js").then(n=>n.i),__vite__mapDeps([1,2,3,4]),import.meta.url)).then(n=>({default:n.DiffEditor}))),le=["HomepageGrid","SubGrid","Form","Application"],ce=K({root:{flex:1,display:"flex",flexDirection:"column",gap:b.spacingVerticalS,minHeight:"320px"},unchanged:{flex:1,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:b.spacingVerticalM,textAlign:"center",color:b.colorNeutralForeground3},bar:{display:"flex",alignItems:"center",flexWrap:"wrap",gap:b.spacingHorizontalS},spacer:{flex:1},muted:{color:b.colorNeutralForeground3},editor:{flex:1,minHeight:"240px",border:`1px solid ${b.colorNeutralStroke2}`,borderRadius:b.borderRadiusMedium,overflow:"hidden",position:"relative"},loading:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%"}});function de(n,a){const m=n.split(`
7
+ `),e=a.split(`
8
+ `);let r=0,h=0;const y=new Set(m),S=new Set(e);for(const g of e)y.has(g)||r++;for(const g of m)S.has(g)||h++;return{added:r,removed:h}}function _(n,a,m=!1){return le.map(e=>{const r=m?a[e]:n.ribbons[e];try{return`<!-- ${e} -->
9
+ `+te({location:e,current:r,baseline:a[e],commands:n.commands,displayRules:n.displayRules,enableRules:n.enableRules,locLabels:n.locLabels,entityLogicalName:r.entityLogicalName})}catch(h){return`<!-- ${e}: Error generating XML: ${String(h)} -->`}}).join(`
10
+
11
+ `)}const ye=({historyIndex:n})=>{const a=ce(),m=se(o=>o.themeMode),e=n!==void 0,[r,h]=v.useState(!0),[y,S]=v.useState(!1),g=p(o=>!e&&o.mutationsSincePublish===0&&!ne(o)),c=p(),l=e?c.past[n]:void 0,w=N.useMemo(()=>e?l?_(l.snapshot,c.baseline):"":_(c,c.baseline,!0),[e,l]),d=e?c.past[n+1]?.snapshot??X(c):X(c),P=N.useMemo(()=>e&&!l?"":_(d,c.baseline),[e,l,d.ribbons,d.commands,d.displayRules,d.enableRules,d.locLabels,c.baseline]),u=oe(!e),j=!e&&u.status==="ready",t=j?u.before:w,R=j?u.after:P,{added:L,removed:C}=de(t,R),i=v.useRef(null),T=v.useCallback(o=>{i.current=o,o.updateOptions({renderSideBySide:r});const f=[o.getOriginalEditor(),o.getModifiedEditor()];let x=0;const F=()=>{x||(x=requestAnimationFrame(()=>{x=0;for(const M of f)M.render(!0)}))},U=f.flatMap(M=>{const B=M.onDidChangeModelTokens;return B?[B.call(M,F)]:[]}),A=o.getModel();o.getModifiedEditor().onDidDispose(()=>{cancelAnimationFrame(x);for(const M of U)M.dispose();setTimeout(()=>{A?.original.dispose(),A?.modified.dispose()})})},[]);return v.useEffect(()=>{i.current?.updateOptions({renderSideBySide:r})},[r]),e&&!l?s.jsx("div",{className:a.unchanged,children:s.jsx(k,{children:"This change was undone, so there's nothing to show."})}):!e&&!y&&g?s.jsxs("div",{className:a.unchanged,children:[s.jsx(V,{fontSize:40,color:b.colorPaletteGreenForeground1,"aria-hidden":"true"}),s.jsx(k,{size:500,weight:"semibold",children:"No changes since the last publish"}),s.jsx(k,{children:"What you see matches what's published for this entity."}),s.jsx(W,{onClick:()=>S(!0),children:"Show the full XML anyway"})]}):!e&&u.status==="loading"?s.jsx("div",{className:a.unchanged,children:s.jsx(O,{size:"small",label:"Reading what's published…"})}):s.jsxs("div",{className:a.root,children:[!e&&u.note&&s.jsx(H,{intent:"info",children:s.jsx(G,{children:u.note})}),s.jsx(Y,{className:a.muted,children:e?`${[l.op,l.target].filter(Boolean).join(" ")}${l.detail?` (${l.detail})`:""}: the XML before it (left) and after it (right).`:j?"Your published customizations (left) and what Publish imports (right).":"The published XML (left) and the XML with your changes (right)."}),s.jsxs("div",{className:a.bar,children:[s.jsxs(z,{appearance:"tint",color:L?"success":"informative",children:["+",L," lines"]}),s.jsxs(z,{appearance:"tint",color:C?"danger":"informative",children:["-",C," lines"]}),s.jsx("div",{className:a.spacer}),s.jsxs(q,{size:"small",selectedValue:r?"side":"unified",onTabSelect:(o,f)=>h(f.value==="side"),"aria-label":"Diff layout",children:[s.jsx(I,{value:"side",children:"Side by side"}),s.jsx(I,{value:"unified",children:"Unified"})]})]}),s.jsx("div",{className:a.editor,children:s.jsx(N.Suspense,{fallback:s.jsx("div",{className:a.loading,children:s.jsx(O,{size:"small",label:"Loading the diff…"})}),children:s.jsx(re,{original:t,modified:R,language:"xml",theme:m==="dark"?"vs-dark":"vs",height:"100%",keepCurrentOriginalModel:!0,keepCurrentModifiedModel:!0,onMount:T,options:{readOnly:!0,renderSideBySide:r,lineNumbers:"on",minimap:{enabled:!1},scrollBeyondLastLine:!1,automaticLayout:!0,wordWrap:"on"}})})})]})};export{ye as CompareView,ye as default};
@@ -0,0 +1 @@
1
+ import{j as t,y as C,aB as y,aA as P,dY as R,T as p,k as h,cN as A,cL as N,l as E,aC as T,m as _,W as b,t as u}from"./fluent-ui-BThr2m8u.js";import{D as g,U as f,c as D}from"./crmParameters-Dxz06tk4.js";const F=_({root:{display:"flex",flexDirection:"column",gap:u.spacingVerticalXS,minWidth:0},param:{display:"flex",flexWrap:"wrap",minWidth:0,gap:u.spacingHorizontalS,alignItems:"flex-start",padding:u.spacingVerticalXS,border:`1px solid ${u.colorNeutralStroke2}`,borderRadius:u.borderRadiusMedium},typeSelect:{flex:"0 1 170px",minWidth:"130px"},nameField:{flex:"0 1 150px",minWidth:"110px"},valueField:{flex:"1 1 160px",minWidth:0,"& .fui-Select, & .fui-Input, & select":{width:"100%",minWidth:0}},actions:{display:"flex",gap:u.spacingHorizontalXS,flexShrink:0,marginTop:"20px"},addButton:{alignSelf:"flex-start"}}),I=[{label:"Context",values:["PrimaryControl","PrimaryControlId","SelectedControl","CommandProperties"]},{label:"Record",values:["PrimaryEntityTypeCode","PrimaryEntityTypeName","FirstPrimaryItemId","PrimaryItemIds"]},{label:"Selection context",values:["SelectedEntityTypeCode","SelectedEntityTypeName","FirstSelectedItemId"]},{label:"Grid selection",values:["SelectedControlSelectedItemCount","SelectedControlSelectedItemIds","SelectedControlSelectedItemReferences","SelectedControlAllItemCount","SelectedControlAllItemIds","SelectedControlAllItemReferences","SelectedControlUnselectedItemCount","SelectedControlUnselectedItemIds","SelectedControlUnselectedItemReferences"]},{label:"Org/User",values:["OrgName","OrgLcid","UserLcid"]}];function U({value:r,integer:m,onChange:o}){const[v,i]=b.useState(String(r));return b.useEffect(()=>i(Number.isFinite(r)?String(r):""),[r]),t.jsx(P,{type:"number",value:v,onChange:(s,x)=>{i(x.value);const c=Number(x.value);x.value.trim()!==""&&Number.isFinite(c)&&(!m||Number.isInteger(c))&&!/e/i.test(String(c))&&o(c)},onBlur:()=>i(Number.isFinite(r)?String(r):"")})}const z=({params:r,onChange:m,urlMode:o=!1,allowedNames:v})=>{const i=F(),s=(e,l)=>{const n=[...r];n[e]=l,m(n)},x=e=>{m(r.filter((l,n)=>n!==e))},c=(e,l)=>{const n=[...r],a=e+l;a<0||a>=n.length||([n[e],n[a]]=[n[a],n[e]],m(n))},k=()=>{m([...r,o?{kind:"StringParameter",value:""}:{kind:"CrmParameter",value:"PrimaryControl"}])},j=e=>{if(!o)return;if(!e.name?.trim())return"Needs a name: it's the query string key.";if(v&&!v.includes(e.name??""))return`A web resource accepts only ${v.join(", ")}: put your own values in data.`};return t.jsxs("div",{className:i.root,children:[r.map((e,l)=>t.jsxs("div",{className:i.param,children:[t.jsx(C,{label:"Type",size:"small",className:i.typeSelect,children:t.jsxs(y,{value:e.kind,onChange:(n,a)=>{const d=a.value,S=e.name;d==="CrmParameter"?s(l,{kind:d,name:S,value:o?"PrimaryEntityTypeName":"PrimaryControl"}):d==="BoolParameter"?s(l,{kind:d,name:S,value:!1}):d==="IntParameter"||d==="DecimalParameter"?s(l,{kind:d,name:S,value:0}):s(l,{kind:"StringParameter",name:S,value:""})},children:[t.jsx("option",{value:"CrmParameter",children:"From the context"}),t.jsx("option",{value:"StringParameter",children:"Text"}),t.jsx("option",{value:"BoolParameter",children:"True or false"}),t.jsx("option",{value:"IntParameter",children:"Whole number"}),t.jsx("option",{value:"DecimalParameter",children:"Decimal number"})]})}),o&&t.jsx(C,{label:"Name",size:"small",className:i.nameField,validationState:j(e)?e.name?.trim()?"warning":"error":"none",validationMessage:j(e),children:t.jsx(P,{value:e.name??"",onChange:(n,a)=>s(l,{...e,name:a.value||void 0}),placeholder:"key"})}),t.jsx(C,{label:"Value",size:"small",className:i.valueField,hint:e.kind==="CrmParameter"?D(String(e.value))??"A value CBS doesn't list, kept as loaded.":void 0,validationState:e.kind==="CrmParameter"&&g[String(e.value)]?"warning":"none",validationMessage:e.kind==="CrmParameter"&&g[String(e.value)]?`Deprecated: use ${g[String(e.value)]}.`:void 0,children:e.kind==="CrmParameter"?t.jsxs(y,{value:e.value,onChange:(n,a)=>s(l,{...e,value:a.value}),children:[!I.some(n=>n.values.includes(e.value))||o&&f.has(String(e.value))?t.jsx("optgroup",{label:"As loaded",children:t.jsx("option",{value:String(e.value),children:String(e.value)})}):null,I.map(n=>t.jsx("optgroup",{label:n.label,children:n.values.filter(a=>!o||!f.has(a)).map(a=>t.jsx("option",{value:a,children:g[a]?`${a} (deprecated)`:a},a))},n.label))]}):e.kind==="BoolParameter"?t.jsx(R,{checked:e.value,onChange:(n,a)=>s(l,{...e,value:a.checked}),label:e.value?"True":"False"}):e.kind==="StringParameter"?t.jsx(P,{value:String(e.value),onChange:(n,a)=>s(l,{...e,value:a.value})}):t.jsx(U,{value:e.value,integer:e.kind==="IntParameter",onChange:n=>s(l,{...e,value:n})})}),t.jsxs("div",{className:i.actions,children:[t.jsx(p,{content:`Move parameter ${l+1} up`,relationship:"label",children:t.jsx(h,{appearance:"subtle",size:"small",icon:t.jsx(A,{}),onClick:()=>c(l,-1),disabled:l===0})}),t.jsx(p,{content:`Move parameter ${l+1} down`,relationship:"label",children:t.jsx(h,{appearance:"subtle",size:"small",icon:t.jsx(N,{}),onClick:()=>c(l,1),disabled:l===r.length-1})}),t.jsx(p,{content:`Remove parameter ${l+1}`,relationship:"label",children:t.jsx(h,{appearance:"subtle",size:"small",icon:t.jsx(E,{}),onClick:()=>x(l)})})]})]},l)),t.jsx(h,{className:i.addButton,appearance:"secondary",size:"small",icon:t.jsx(T,{}),onClick:k,children:"Add parameter"})]})};export{z as C};
@@ -0,0 +1,2 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./CommandEditorPanel-BtBG8540.js","./fluent-ui-BThr2m8u.js","./dnd-C19d6Mn0.js","./index-Df9NSpg6.js","./preload-helper-PPVm8Dsz.js","./index-D5GCH8nj.css","./CrmParameterEditor-DfZv5BuF.js","./crmParameters-Dxz06tk4.js","./useStableKeys-EsghhjoV.js","./RuleEditorPanel-C9CcMM1s.js","./ScriptView-B0ILfTWe.js","./MonacoEditor-B3J81C8F.js","./TabDisplayRulesPanel-DVMEaWWv.js","./XmlView-DEUwTHCt.js","./CompareView-Beq5V68_.js","./publishService-CKoTOngS.js","./xmlValidator-Dki8Hf7Y.js","./TranslationsView-BZXsG_LU.js","./languages-CGjPBPNA.js","./TitleTranslationsView-C68zJcNK.js"])))=>i.map(i=>d[i]);
2
+ import{_ as g}from"./preload-helper-PPVm8Dsz.js";import{r as m,j as a,y as N,aA as V,k as j,m as E,t as l,T as S,ar as w,B as L,e6 as z,e7 as R,z as D,al as A,eT as P,eU as B,N as H,R as T,cR as W,l as F,eV as O,eW as X,e5 as $,e as v,eX as U}from"./fluent-ui-BThr2m8u.js";import{u as M,a as x,b as y,I,c as G,i as K}from"./index-Df9NSpg6.js";import"./dnd-C19d6Mn0.js";const Y=E({rename:{display:"flex",alignItems:"flex-start",gap:l.spacingHorizontalS,marginTop:l.spacingVerticalXS},field:{flex:1,minWidth:0},input:{fontFamily:l.fontFamilyMonospace},buttons:{display:"flex",gap:l.spacingHorizontalXS,marginTop:"22px"}});function q(n,s,u,p){if(!n.trim())return"Enter an ID.";if(/\s/.test(n))return"An ID can't contain spaces.";if(n!==s&&u.some(c=>c.toLowerCase()===n.toLowerCase()))return`Another ${p} already has this ID.`}function C({label:n,current:s,ids:u,what:p,hint:c,onRename:f,onDone:h}){const r=Y(),[e,b]=m.useState(s),o=q(e,s,u,p),t=()=>{const d=e.trim();!o&&d!==s&&f(d),h()};return a.jsxs("div",{className:r.rename,children:[a.jsx(N,{className:r.field,label:n,validationState:o?"error":"none",validationMessage:o,hint:o?void 0:c,children:a.jsx(V,{className:r.input,value:e,autoFocus:!0,onChange:(d,i)=>b(i.value),onKeyDown:d=>{d.key==="Enter"&&t(),d.key==="Escape"&&(d.stopPropagation(),h())}})}),a.jsxs("div",{className:r.buttons,children:[a.jsx(j,{appearance:"primary",disabled:!!o||e.trim()===s,onClick:t,children:"Rename"}),a.jsx(j,{onClick:h,children:"Cancel"})]})]})}const Z=E({idRow:{display:"flex",alignItems:"center",gap:l.spacingHorizontalS,minWidth:0,marginTop:l.spacingVerticalXS},id:{flex:1,minWidth:0},badge:{flexShrink:0},tabs:{marginTop:l.spacingVerticalS,marginLeft:`calc(-1 * ${l.spacingHorizontalM})`}}),J={custom:{text:"Yours",color:"success"},customising:{text:"Your copy",color:"brand"},customised:{text:"Your copy",color:"brand"},oob:{text:"Read-only",color:"informative"},uncustomising:{text:"Read-only",color:"informative"},reloadRequired:{text:"Read-only",color:"informative"}};function Q({commandId:n}){const s=Z(),u=M(n)?.provenance,p=x(i=>i.commands.find(_=>_.id===n)),c=x(i=>G(i.ribbons,n).length),f=y(i=>i.commandEditorTab),h=y(i=>i.setCommandEditorTab),r=x(i=>i.commands).map(i=>i.id),e=x(i=>i.renameCommandId),b=y(i=>i.openCommandEditor),[o,t]=m.useState(!1),d=u&&J[u];return a.jsxs(a.Fragment,{children:[o?a.jsx(C,{label:"Command ID",current:n,ids:r,what:"command",hint:"Usually publisher.entity.Button.Command. Its buttons follow the new ID.",onRename:i=>e(n,i)&&b(i),onDone:()=>t(!1)}):a.jsxs("div",{className:s.idRow,children:[a.jsx("div",{className:s.id,children:a.jsx(I,{label:"Command ID",value:n,hideLabel:!0,action:u==="custom"&&a.jsx(S,{content:"Rename command ID",relationship:"label",children:a.jsx(j,{appearance:"subtle",icon:a.jsx(w,{}),onClick:()=>t(!0)})})})}),d&&a.jsx(L,{appearance:"tint",color:d.color,size:"medium",className:s.badge,children:d.text})]}),a.jsxs(z,{className:s.tabs,selectedValue:f,onTabSelect:(i,_)=>h(_.value),children:[a.jsx(R,{value:"actions",children:"Actions"}),a.jsxs(R,{value:"enable",children:["Enable rules (",p?.enableRules.length??0,")"]}),a.jsxs(R,{value:"display",children:["Display rules (",p?.displayRules.length??0,")"]}),a.jsxs(R,{value:"usedBy",children:["Used by (",c,")"]})]})]})}const ee=E({idRow:{display:"flex",alignItems:"center",gap:l.spacingHorizontalS,minWidth:0,marginTop:l.spacingVerticalXS},id:{flex:1,minWidth:0},usedBy:{color:l.colorNeutralForeground3}});function ae({ruleId:n,kind:s}){const u=ee(),p=x(t=>s==="enable"?t.enableRules:t.displayRules),c=x(t=>t.commands.filter(d=>(s==="enable"?d.enableRules:d.displayRules).includes(n)).length),f=x(t=>t.renameEnableRuleId),h=x(t=>t.renameDisplayRuleId),r=y(t=>t.openRuleEditor),[e,b]=m.useState(!1),o=t=>{(s==="enable"?f(n,t):h(n,t))&&r(t,s)};return a.jsxs(a.Fragment,{children:[e?a.jsx(C,{label:"Rule ID",current:n,ids:p.map(t=>t.id),what:"rule",hint:"The commands that use it follow the new ID.",onRename:o,onDone:()=>b(!1)}):a.jsx("div",{className:u.idRow,children:a.jsx("div",{className:u.id,children:a.jsx(I,{label:"Rule ID",value:n,hideLabel:!0,action:!K(n)&&a.jsx(S,{content:"Rename rule ID",relationship:"label",children:a.jsx(j,{appearance:"subtle",icon:a.jsx(w,{}),onClick:()=>b(!0)})})})})}),a.jsxs(D,{className:u.usedBy,children:["Used by ",c," command",c===1?"":"s"]})]})}const ne=m.lazy(()=>g(()=>import("./CommandEditorPanel-BtBG8540.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8]),import.meta.url)),te=m.lazy(()=>g(()=>import("./RuleEditorPanel-C9CcMM1s.js"),__vite__mapDeps([9,1,3,4,2,5,6,7,8]),import.meta.url)),se=m.lazy(()=>g(()=>import("./ScriptView-B0ILfTWe.js"),__vite__mapDeps([10,1,3,4,2,5,11]),import.meta.url)),ie=m.lazy(()=>g(()=>import("./TabDisplayRulesPanel-DVMEaWWv.js"),__vite__mapDeps([12,1,3,4,2,5,8]),import.meta.url)),oe=m.lazy(()=>g(()=>import("./XmlView-DEUwTHCt.js"),__vite__mapDeps([13,1,3,4,2,5,11]),import.meta.url)),le=m.lazy(()=>g(()=>import("./CompareView-Beq5V68_.js"),__vite__mapDeps([14,4,1,3,2,5,15,16,7]),import.meta.url)),re=m.lazy(()=>g(()=>import("./TranslationsView-BZXsG_LU.js"),__vite__mapDeps([17,1,3,4,2,5,18]),import.meta.url)),de=m.lazy(()=>g(()=>import("./TitleTranslationsView-C68zJcNK.js"),__vite__mapDeps([19,1,3,4,2,5,18]),import.meta.url)),ce=E({drawer:{width:"720px",maxWidth:"90vw"},wide:{width:"960px"},fill:{display:"flex",flexDirection:"column"},navigation:{justifyContent:"space-between"},title:{display:"flex",flexDirection:"column",gap:l.spacingVerticalXXS,minWidth:0},trail:{color:l.colorNeutralForeground3},idRow:{display:"flex",alignItems:"center",gap:l.spacingHorizontalS,minWidth:0,marginTop:l.spacingVerticalXS},id:{flex:1,minWidth:0},footer:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:l.spacingHorizontalM},hint:{color:l.colorNeutralForeground3}});function k(n){return n.kind==="command"?"Edit command":n.kind==="rule"?`Edit ${n.ruleKind} rule`:n.kind==="tabRules"?"Tab display rules":n.kind==="xml"?"XML of your changes":n.kind==="translations"?"Translations":n.kind==="titleTranslations"?n.container==="tab"?"Tab title translations":"Group title translations":n.kind==="diff"?n.id==="compare"?"Compare with published":"What this change did":n.editable?"Edit script":"View script"}function he(){const n=ce(),s=y(o=>o.editorStack),u=y(o=>o.editorBack),p=y(o=>o.closeEditor),c=s.length>0,[f,h]=m.useState(s);c&&s!==f&&h(s);const r=c?s:f,e=r[r.length-1],b=r[r.length-2];return m.useEffect(()=>c?(x.getState().beginEditSession(),()=>x.getState().endEditSession()):void 0,[c]),a.jsxs(A,{position:"end",open:c,onOpenChange:(o,t)=>!t.open&&p(),className:v(n.drawer,(e?.kind==="xml"||e?.kind==="diff")&&n.wide),"aria-label":e?k(e):"Editor",children:[a.jsxs(P,{children:[a.jsx(B,{children:a.jsxs(H,{className:n.navigation,children:[b?a.jsx(T,{appearance:"subtle",icon:a.jsx(W,{}),onClick:u,children:k(b)}):a.jsx("span",{}),a.jsx(T,{appearance:"subtle",icon:a.jsx(F,{}),"aria-label":"Close",onClick:p})]})}),e&&a.jsx(O,{children:a.jsxs("span",{className:n.title,children:[r.length>2&&a.jsxs(D,{className:n.trail,children:[r.slice(0,-1).map(k).join(" › ")," ›"]}),k(e)]})}),e?.kind==="command"&&a.jsx(Q,{commandId:e.id},e.id),e?.kind==="rule"&&a.jsx(ae,{ruleId:e.id,kind:e.ruleKind},e.id),(e?.kind==="script"||e?.kind==="tabRules"||e?.kind==="translations"||e?.kind==="titleTranslations")&&a.jsx("div",{className:n.idRow,children:a.jsx("div",{className:n.id,children:a.jsx(I,{label:e.kind==="tabRules"?"Tab ID":e.kind==="translations"?"Button ID":e.kind==="titleTranslations"?e.container==="tab"?"Tab ID":"Group ID":"Web resource",value:e.id,hideLabel:!0})})})]}),a.jsx(X,{className:v((e?.kind==="script"||e?.kind==="xml"||e?.kind==="diff")&&n.fill),children:a.jsxs(m.Suspense,{fallback:a.jsx($,{size:"small",label:"Loading…"}),children:[e?.kind==="command"&&a.jsx(ne,{}),e?.kind==="rule"&&a.jsx(te,{}),e?.kind==="tabRules"&&a.jsx(ie,{location:e.location,tabId:e.id}),e?.kind==="script"&&a.jsx(se,{name:e.id,editable:e.editable},e.id),e?.kind==="xml"&&a.jsx(oe,{location:e.id},e.id),e?.kind==="translations"&&a.jsx(re,{buttonId:e.id},e.id),e?.kind==="titleTranslations"&&a.jsx(de,{location:e.location,container:e.container,tabId:e.tabId,id:e.id},e.id),e?.kind==="diff"&&a.jsx(le,{historyIndex:e.historyIndex},`${e.id}:${e.historyIndex??""}`)]})}),a.jsxs(U,{className:n.footer,children:[a.jsx(D,{className:n.hint,children:e?.kind==="script"?e.editable?"Save writes the script to Dataverse · Undo doesn't revert it":"":e?.kind==="xml"||e?.kind==="diff"?"":"Changes apply as you edit · Ctrl Z to undo"}),a.jsx(j,{appearance:"primary",onClick:p,children:"Done"})]})]})}export{he as EditorDrawer,he as default};
@@ -0,0 +1 @@
1
+ import{j as c}from"./fluent-ui-BThr2m8u.js";import{b as s,a as n,H as b,a4 as m,a5 as p,L as f}from"./index-Df9NSpg6.js";import"./preload-helper-PPVm8Dsz.js";import"./dnd-C19d6Mn0.js";const O=()=>{const o=s(e=>e.hideInsteadOfDelete),a=s(e=>e.closeHideInsteadOfDelete),i=s(e=>e.announce),t=n(e=>o?f(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),r=n(e=>e.locLabels),u=b();return!o||!t||!l?null:c.jsx(m,{open:!0,buttonLabel:u(t.label,r,void 0,t.source?.labelToken),buttonId:t.id,commandId:t.commandId,deleteBlockedReason:p(t,l),onConfirmHide:()=>{n.getState().hideOobButton(o.location,o.tabId,o.groupId,o.buttonId),i("Button hidden"),a()},onConfirmDisplayRule:()=>{n.getState().hideWithDisplayRules(t.commandId)&&i("Button hidden"),a()},onCancel:a})};export{O as HideInsteadOfDeleteModal,O as default};