@mohsinonxrm/pptb-commandbar-studio 0.8.0-beta.1 → 0.9.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.
- package/CHANGELOG.md +564 -0
- package/README.md +71 -48
- package/SECURITY.md +12 -7
- package/dist/assets/BulkPublishModal-DzDZJg0U.js +36 -0
- package/dist/assets/CommandEditorPanel-DsCP9yG4.js +1 -0
- package/dist/assets/CommandPalette-ID3kRJ9l.js +1 -0
- package/dist/assets/CompareView-DGsrcdoN.js +7 -0
- package/dist/assets/CrmParameterEditor-C22QGWff.js +1 -0
- package/dist/assets/EditorDrawer-CvCe9WeO.js +2 -0
- package/dist/assets/HideInsteadOfDeleteModal-3j9g-E9l.js +1 -0
- package/dist/assets/IconPickerModal-BLoDLbLR.js +1 -0
- package/dist/assets/ImportXmlModal-BD-L1QzJ.js +1 -0
- package/dist/assets/{MonacoEditor-uzfuRCpJ.js → MonacoEditor-BMKRZv-g.js} +1 -1
- package/dist/assets/NewButtonModal-COYXwEyk.js +1 -0
- package/dist/assets/NewGroupModal-boP_t1fI.js +1 -0
- package/dist/assets/NewTabModal-BI4afbC5.js +1 -0
- package/dist/assets/RuleEditorPanel-l8QnRFj6.js +1 -0
- package/dist/assets/ScriptView-BVyCmRvD.js +1 -0
- package/dist/assets/TabDisplayRulesPanel-gORq6MO7.js +1 -0
- package/dist/assets/TranslationsView-DubBATog.js +1 -0
- package/dist/assets/WebResourceBrowser-BATScmTw.js +1 -0
- package/dist/assets/XmlView-Bn4KlTw3.js +2 -0
- package/dist/assets/dnd-C1w9VFfC.js +5 -0
- package/dist/assets/fluent-icons-CQEhzzaC.js +1 -0
- package/dist/assets/fluent-ui-BEjALNLO.js +59 -0
- package/dist/assets/index-6so8O90C.js +136 -0
- package/dist/assets/index-D5GCH8nj.css +1 -0
- package/dist/assets/ruleKinds-BKTUiZ1-.js +1 -0
- package/dist/assets/useReplaceWebResourceConfirm-DND-V0vw.js +1 -0
- package/dist/assets/useStableKeys-BkDn7til.js +1 -0
- package/dist/assets/{xmlValidator-BkeotXuB.js → xmlValidator-PbODaIQV.js} +1 -1
- package/dist/index.html +15 -9
- package/index.html +10 -4
- package/package.json +1 -1
- package/dist/assets/BulkPublishModal-mJ41AWew.js +0 -36
- package/dist/assets/CommandEditorPanel-BiP1kPHY.js +0 -1
- package/dist/assets/CommandPalette-q51_0qRZ.js +0 -1
- package/dist/assets/ConflictDrawer-CdWv_PbN.js +0 -1
- package/dist/assets/DiffViewer-BQP5f73U.js +0 -7
- package/dist/assets/HideInsteadOfDeleteModal-C9r6ah5p.js +0 -1
- package/dist/assets/IconPickerModal-B81Tnf5i.js +0 -1
- package/dist/assets/ImportXmlModal-C0cMaS59.js +0 -1
- package/dist/assets/LocalizationEditor-DniDtrZV.js +0 -1
- package/dist/assets/NewButtonModal-BXpX1Ld5.js +0 -1
- package/dist/assets/NewGroupModal-Bh7lXq52.js +0 -1
- package/dist/assets/NewTabModal-Pntdk3in.js +0 -1
- package/dist/assets/RuleEditorPanel-BUGKgc0N.js +0 -1
- package/dist/assets/ScalingEditorPanel-p3-Yw3CO.js +0 -1
- package/dist/assets/TabDisplayRulesPanel-CSNshwaw.js +0 -1
- package/dist/assets/UrlComposerModal-WKSTwUcW.js +0 -1
- package/dist/assets/WebResourceBrowser-BK-gVU2g.js +0 -1
- package/dist/assets/XmlDrawer-CQJElnD1.js +0 -2
- package/dist/assets/dnd-Cq8OftAq.js +0 -5
- package/dist/assets/fluent-icons-BqJj6rDi.js +0 -1
- package/dist/assets/fluent-ui-QADO660t.js +0 -43
- package/dist/assets/index-D9lerlVA.css +0 -1
- package/dist/assets/index-Di2_5czx.js +0 -136
- package/dist/assets/ruleKinds-B9hACGaq.js +0 -1
- package/dist/assets/useReplaceWebResourceConfirm-BUWBVNSC.js +0 -1
- package/dist/assets/useStableKeys-p2OkzZWO.js +0 -1
package/README.md
CHANGED
|
@@ -37,9 +37,9 @@ reimagined with React 18, Fluent UI v9, and live Dataverse integration via
|
|
|
37
37
|
- Translations edit the labels a button publishes to; another solution's label, shared with every control that uses it, is read-only there
|
|
38
38
|
- Command binding with action summary chips
|
|
39
39
|
- Display rules + Enable rules pill lists with inline add/remove
|
|
40
|
-
- Scaling summary
|
|
40
|
+
- Scaling summary (read-only: the tab's groups and scaling steps)
|
|
41
41
|
- Advanced: form ribbon scope selector, `Mscrm.OpenRecordItem` override toggle, client-type filter shortcuts (Unified Interface evaluates as `Modern`; one filter per command)
|
|
42
|
-
-
|
|
42
|
+
- Provenance notice — names the managed solution and publisher a button comes from
|
|
43
43
|
|
|
44
44
|
### ⚡ Command Editor
|
|
45
45
|
- JavaScript function: library (with Browse… to Web Resource Browser), function name, positional CrmParameter editor
|
|
@@ -59,27 +59,28 @@ reimagined with React 18, Fluent UI v9, and live Dataverse integration via
|
|
|
59
59
|
- Plain-English `summarizeRule()` output
|
|
60
60
|
- CustomRule async note (Promise\<boolean\> on Unified Interface)
|
|
61
61
|
|
|
62
|
-
### 🔤
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
-
|
|
62
|
+
### 🔤 Translations
|
|
63
|
+
- A view of the editor drawer: changes apply as you type, and one Ctrl Z undoes the whole edit
|
|
64
|
+
- Label / tooltip title / tooltip body per language; the base language is the button's own text
|
|
65
|
+
- Languages by name (20 built in); add any other by its LCID
|
|
66
|
+
- A line-break button in each label field (Dataverse's `​​`)
|
|
67
|
+
- A built-in or another solution's button is read-only until you customise it
|
|
67
68
|
|
|
68
69
|
### 🖼️ Icon Picker
|
|
69
|
-
- **Fluent icons** tab —
|
|
70
|
-
- **Web resources** tab —
|
|
71
|
-
- **
|
|
70
|
+
- **Fluent icons** tab — 87 icons with search, a category filter and Regular / Filled; arrow keys move between them, Enter picks one. **Use** uploads it as an SVG web resource in your solution
|
|
71
|
+
- **Web resources** tab — the environment's SVG web resources with search; the first 300 show, and the count says when to search for the rest
|
|
72
|
+
- **Upload SVG** tab — drop an SVG or choose one; it's uploaded as a web resource in your solution
|
|
72
73
|
|
|
73
|
-
### 🗂️ Scaling
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
- Validation: non-overlapping MaxSize/Scale ranges
|
|
74
|
+
### 🗂️ Scaling
|
|
75
|
+
- Read-only for now: Properties shows a tab's groups and scaling steps. Scaling only shapes the classic ribbon; Unified Interface ignores it.
|
|
76
|
+
- Editing returns once changes to scaling can be published ([#165](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/165)).
|
|
77
77
|
|
|
78
78
|
### 🗃️ Tab Display Rules Editor
|
|
79
79
|
- One display rule per tab; the tab shows where any of its steps matches
|
|
80
80
|
- `EntityRule` (all 4 contexts, or any) + `PageRule`
|
|
81
81
|
- Info note: entity-scoped tabs can only use EntityRule; global tabs can use both
|
|
82
82
|
- Read-only for a tab your customizations don't add
|
|
83
|
+
- A view of the editor drawer: changes apply as you edit, and one Ctrl Z undoes the whole edit
|
|
83
84
|
|
|
84
85
|
### 🌐 Web Resource Browser
|
|
85
86
|
- Virtualized list with type filter, custom-only toggle, search
|
|
@@ -91,11 +92,12 @@ reimagined with React 18, Fluent UI v9, and live Dataverse integration via
|
|
|
91
92
|
- Live URL preview; `&` → `&` escaping handled automatically
|
|
92
93
|
- WinMode: Navigate / Dialog / Popup
|
|
93
94
|
|
|
94
|
-
### 📊 XML
|
|
95
|
-
-
|
|
95
|
+
### 📊 XML and Compare
|
|
96
|
+
- Views of the editor drawer: the XML of your changes opens on the location you're on, one location per tab, in Monaco (read-only; **Import this XML** hands it to the import dialog)
|
|
96
97
|
- **Copy** and **Download** use Power Platform ToolBox's clipboard and Save dialog (the browser's outside it) and say whether the XML was copied, where it was saved, or why not
|
|
97
|
-
-
|
|
98
|
-
- Monaco `DiffEditor
|
|
98
|
+
- **Format** button
|
|
99
|
+
- **Compare with published**: Monaco `DiffEditor`, side by side or unified, with an empty state when nothing has changed
|
|
100
|
+
- History's **View diff** shows what that one change did
|
|
99
101
|
- CBS-specific completions: `$LocLabels:`, `$webresource:`, `Command=`, `ModernImage=`
|
|
100
102
|
|
|
101
103
|
### 🔄 Publish Pipeline
|
|
@@ -109,13 +111,12 @@ reimagined with React 18, Fluent UI v9, and live Dataverse integration via
|
|
|
109
111
|
- Labels are written in the organization's base language, read before every publish; if it can't be read, the publish stops. The system Default solution isn't offered as a target
|
|
110
112
|
- `Mscrm.OpenRecordItem` override support — emitted as a system-command override when the user defines a JS action on it
|
|
111
113
|
|
|
112
|
-
### 🧩 Solution
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
- Live solution-layer fetch in the drawer
|
|
114
|
+
### 🧩 Solution provenance
|
|
115
|
+
- Which managed solution adds a control, read from the managed ribbon layers (`ribbondiffs`) in one query (falls back to the namespace heuristic when unavailable)
|
|
116
|
+
- 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
|
|
116
117
|
|
|
117
118
|
### ⌨️ Keyboard Shortcuts + Command Palette
|
|
118
|
-
- `Ctrl+K` — Command Palette
|
|
119
|
+
- `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
|
|
119
120
|
- `Ctrl+Z/Y`, `Ctrl+Shift+Z` — Undo / Redo (80-entry stack)
|
|
120
121
|
- `Ctrl+D` — Duplicate selected button
|
|
121
122
|
- `Ctrl+S` — Open Bulk Publish
|
|
@@ -151,7 +152,7 @@ started (if the tool's connection changes in Power Platform ToolBox, the operati
|
|
|
151
152
|
|
|
152
153
|
| Operation | When | What it does in Dataverse |
|
|
153
154
|
|---|---|---|
|
|
154
|
-
| **Publish** | **Publish
|
|
155
|
+
| **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. |
|
|
155
156
|
| **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. |
|
|
156
157
|
| **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`). |
|
|
157
158
|
| **Pick an existing web resource as an icon** | Icon picker → Web resource | Adds the web resource to the selected unmanaged solution (`AddSolutionComponent`). |
|
|
@@ -160,30 +161,44 @@ started (if the tool's connection changes in Power Platform ToolBox, the operati
|
|
|
160
161
|
Nothing else writes to Dataverse:
|
|
161
162
|
- **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`).
|
|
162
163
|
- **Export** writes a RibbonDiffXml file where you choose; **Import RibbonDiffXml** only changes the workspace until you publish.
|
|
164
|
+
- **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.
|
|
163
165
|
|
|
164
166
|
## 🖼️ Interface Overview
|
|
165
167
|
|
|
166
168
|
```
|
|
167
169
|
┌─────────────────────────────────────────────────────────────────┐
|
|
168
|
-
│ TopBar:
|
|
169
|
-
│
|
|
170
|
+
│ TopBar: Environment │ Solution │ Table │ Search (Ctrl+K) │
|
|
171
|
+
│ Undo/Redo │ XML ▾ │ Open in D365 │ View ▾ │ Help │ Publish n │
|
|
172
|
+
│ (tools move into a ⋯ menu when the window is narrow) │
|
|
173
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
174
|
+
│ Messages that need action (one at a time, + n more) │
|
|
170
175
|
├──────────────────┬──────────────────────────────┬───────────────┤
|
|
171
176
|
│ Left Pane │ Ribbon Canvas │ Properties │
|
|
172
|
-
│
|
|
173
|
-
│
|
|
174
|
-
│
|
|
175
|
-
│ •
|
|
176
|
-
│
|
|
177
|
-
│
|
|
178
|
-
│
|
|
179
|
-
│
|
|
180
|
-
│
|
|
177
|
+
│ [Structure| │ Location: Home/Sub/Form/App │ • Identity │
|
|
178
|
+
│ Solution] │ View: Group cards / Classic /│ • Command │
|
|
179
|
+
│ │ Modern / List │ │
|
|
180
|
+
│ • Structure: │ How users see it (preview) │ • Rules │
|
|
181
|
+
│ │ Groups + Buttons (DnD) │ │
|
|
182
|
+
│ tab › group › │ │ • Scaling │
|
|
183
|
+
│ control tree │ │ • Advanced │
|
|
184
|
+
│ • Solution: one │ │ │
|
|
185
|
+
│ tree: Buttons, │ │ │
|
|
186
|
+
│ Commands, │ │ │
|
|
187
|
+
│ Rules, Templ. │ │ │
|
|
181
188
|
├──────────────────┴──────────────────────────────┴───────────────┤
|
|
182
189
|
│ Bottom Panel: Commands │ Display Rules │ Enable Rules │ History │
|
|
183
190
|
│ │ Console (runtime + publish log) │
|
|
184
191
|
└─────────────────────────────────────────────────────────────────┘
|
|
185
192
|
```
|
|
186
193
|
|
|
194
|
+
The **Structure** tree is where you choose the location's tab, group or button, and each node's
|
|
195
|
+
menu (right-click, Shift+F10 or the Menu key) has its actions: a tab's Rename…, Tab display
|
|
196
|
+
rules…, Add group…, Move up / down and Delete tab…, and the same group and button menus as the
|
|
197
|
+
canvas.
|
|
198
|
+
|
|
199
|
+
Below 1200 px wide, the left pane becomes a rail with a Structure and a Solution button, each opening it as a drawer on that tab, and
|
|
200
|
+
Properties opens as a drawer when you select something, so the canvas keeps the width.
|
|
201
|
+
|
|
187
202
|
---
|
|
188
203
|
|
|
189
204
|
## 🚀 Getting Started
|
|
@@ -194,7 +209,7 @@ Command Bar Studio runs **inside [Power Platform ToolBox](https://www.powerplatf
|
|
|
194
209
|
2. Connect to a Dataverse environment
|
|
195
210
|
3. Open Command Bar Studio from the tool list
|
|
196
211
|
4. Pick an unmanaged solution from the TopBar
|
|
197
|
-
5.
|
|
212
|
+
5. Pick a table from the TopBar (only the solution's tables are listed)
|
|
198
213
|
6. Edit ribbon buttons visually; click **Publish** when done
|
|
199
214
|
|
|
200
215
|
Icons you pick or upload, and scripts you save, are created as web resources and
|
|
@@ -237,7 +252,7 @@ npm test
|
|
|
237
252
|
# Lint (zero warnings allowed)
|
|
238
253
|
npm run lint
|
|
239
254
|
|
|
240
|
-
# Check / apply Prettier formatting
|
|
255
|
+
# Check / apply Prettier formatting (CI fails when format:check does)
|
|
241
256
|
npm run format:check
|
|
242
257
|
npm run format
|
|
243
258
|
|
|
@@ -245,6 +260,8 @@ npm run format
|
|
|
245
260
|
npm run validate
|
|
246
261
|
```
|
|
247
262
|
|
|
263
|
+
The one-off Prettier pass (#118) is listed in `.git-blame-ignore-revs`, which GitHub's blame view skips. To skip it in local `git blame` too, run `git config blame.ignoreRevsFile .git-blame-ignore-revs` once.
|
|
264
|
+
|
|
248
265
|
### Standalone vs PPTB-embedded
|
|
249
266
|
|
|
250
267
|
CBS runs in two modes:
|
|
@@ -283,18 +300,25 @@ CBS runs in two modes:
|
|
|
283
300
|
```
|
|
284
301
|
src/
|
|
285
302
|
components/
|
|
286
|
-
shell/ — TopBar,
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
303
|
+
shell/ — TopBar, TablePicker, ShellMessages, Layout (resizable panes;
|
|
304
|
+
rail + drawers below 1200 px)
|
|
305
|
+
left-pane/ — LeftPane (Structure | Solution): StructurePane (tab › group ›
|
|
306
|
+
control tree), SolutionElementsPane (your solution's elements)
|
|
307
|
+
ribbon-canvas/ — RibbonCanvas, CanvasHeader, UsersBar ("How users see it"),
|
|
308
|
+
GroupCards, RibbonListView, ClassicRibbon, ModernCommandBar
|
|
309
|
+
properties-pane/ — PropertiesPane (header + collapsible sections) and its sections
|
|
310
|
+
bottom-panel/ — BottomPanel (Commands / Rules / History / Console tabs),
|
|
311
|
+
ElementGrids (the virtualized Commands and Rules grids)
|
|
312
|
+
panels/ — EditorDrawer (command, rule, script, tab display rule, XML,
|
|
313
|
+
compare and translations views): CommandEditor, RuleEditor,
|
|
314
|
+
TabDisplayRules, XmlView, CompareView, TranslationsView;
|
|
315
|
+
WebResourceBrowser
|
|
316
|
+
modals/ — BulkPublish, IconPicker, NewButton/Group/Tab, RenameGroup,
|
|
317
|
+
ChangeGroupTemplate, HideOobWarning, ImportXml, ConfirmDialog
|
|
295
318
|
command-palette/ — CommandPalette (Ctrl+K)
|
|
296
319
|
shared/ — MonacoEditor, FluentIcon, CrmParameterEditor,
|
|
297
|
-
RuleStepEditor, RuleStepPicker, ResizableHandle
|
|
320
|
+
RuleStepEditor, RuleStepPicker, ResizableHandle,
|
|
321
|
+
ButtonContextMenu (the one button menu, #182)
|
|
298
322
|
services/
|
|
299
323
|
xmlGenerator.ts — RibbonDiffXml generator (all 30 rule kinds)
|
|
300
324
|
xmlParser.ts — Merged ribbon XML parser (all 30 rule kinds)
|
|
@@ -305,7 +329,6 @@ src/
|
|
|
305
329
|
ribbonService.ts — RetrieveEntityRibbon / RetrieveApplicationRibbon
|
|
306
330
|
publishService.ts — Layer merge, solution ZIP packaging, import, publish and verification
|
|
307
331
|
ribbonProvenanceService.ts — managed-solution provenance from the managed ribbondiffs
|
|
308
|
-
conflictService.ts — fetchConflictLayersForElement
|
|
309
332
|
webResourceService.ts — loadWebResources / loadWebResourceByName / loadWebResourceContent
|
|
310
333
|
store/
|
|
311
334
|
ribbonStore.ts — Ribbon state, 80-entry undo/redo, mutationsSincePublish
|
package/SECURITY.md
CHANGED
|
@@ -51,15 +51,20 @@ ToolBox (PPTB) and talks to Dataverse only through the host's
|
|
|
51
51
|
| Version | Supported |
|
|
52
52
|
|---|---|
|
|
53
53
|
| The current stable release (npm `latest`) | ✅ Fixes and security fixes |
|
|
54
|
-
| The previous minor release | ✅ Critical and security fixes for 30 days after the next minor ships (npm `support-X.Y`) |
|
|
54
|
+
| The previous minor release | ✅ Critical and security fixes for 30 days after the next minor ships (npm `support-X.Y`), **only when the next minor requires a newer Power Platform ToolBox** |
|
|
55
55
|
| Betas (npm `beta`) | Fixed in the next beta |
|
|
56
56
|
| Anything older | ❌ |
|
|
57
57
|
|
|
58
|
-
**Everything before 0.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
**Everything before 0.8.0 is deprecated on npm and gets no further fixes**, 0.7.x, 0.6.x
|
|
59
|
+
and 0.5.x included:
|
|
60
|
+
- **Before 0.6.2:** these versions bundle DOMPurify 3.2.7 (in the Monaco editor), which has
|
|
61
|
+
critical advisories.
|
|
62
|
+
- **0.6.x and 0.7.x:** they get no support window, because the next minor needs the same Power
|
|
63
|
+
Platform ToolBox (1.2.7). Update to the latest release.
|
|
64
|
+
|
|
65
|
+
Use 0.8.0 or later, which requires Power Platform ToolBox 1.2.7 or later; users on an older
|
|
66
|
+
PPTB need to update it. A previous minor keeps a support window only when the next minor
|
|
67
|
+
raises that requirement, because only then can users be unable to update. See
|
|
68
|
+
[RELEASING.md](RELEASING.md) → *Supported versions*.
|
|
64
69
|
|
|
65
70
|
Thanks for helping keep the tool safe.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import{L as n,K as Vn,aa as us,V as hs,cm as ms,ac as ps,a8 as bs,a7 as gs,ab as fs,a4 as ys,ad as xs}from"./fluent-icons-CQEhzzaC.js";import{p as ve,e as ws,g as Cs,m as _e,d as js,f as vs,h as Rs,j as Ss,n as $s,k as Qe,o as Is,l as Ns,q as ks,r as Ps,s as He,t as Ts,v as As,w as Es,x as Sn,y as Ds,z as Ls,A as Ke,B as zs,C as Ms,D as z,E as Bn,F as en,G as Pe,H as Os,J as Us,K as $n,L as Xs,M as Ge,N as Vs,O as In,P as Bs,Q as qn,R as F,S as Fn,T as qs,U as Je,V as Fs,b as Nn,a as V,W as Ws,X as Re,Y as _s,Z as Ks,_ as Gs,$ as Hs,a0 as kn}from"./index-6so8O90C.js";import{a as $,R as re}from"./monaco-BIO15LCS.js";import{M as Js}from"./MonacoEditor-BMKRZv-g.js";import{w as Ys,v as Wn}from"./xmlValidator-PbODaIQV.js";import{L as se,N as te,Q as Ne,b as D,B as Ye,F as ke,X as _n,t as I,ag as Pn,h as ce,R as Zs,am as Qs,an as Se,ao as $e,ap as Ie,b1 as et,c as Tn,b2 as nt,a7 as st,av as tt,af as it,aj as ot}from"./fluent-ui-BEjALNLO.js";import"./dnd-C1w9VFfC.js";import"./ruleKinds-BKTUiZ1-.js";import"./crmParameters-rgfZhhzN.js";let An=0;async function nn(e){const s=typeof window<"u"?window.toolboxAPI:void 0;An++===0&&await En(()=>s?.preventClose?.());try{return await e()}finally{--An===0&&await En(()=>s?.releasePreventClose?.())}}const at=2e3;async function En(e){let s;try{await Promise.race([e(),new Promise(i=>s=setTimeout(i,at))])}catch{}finally{clearTimeout(s)}}function pe(e,s){const i=e.match(new RegExp(`\\s${s}="([^"]*)"`));return i?i[1]:null}function Dn(e,s,i){const o=e.indexOf(i,s);return e.slice(s,o===-1?void 0:o).match(/<result\s[^>]*>/g)??[]}function Ln(e){const s=e.find(i=>pe(i,"result")!=="success");if(s){const i=pe(s,"errorcode")??"",o=pe(s,"errortext")??"unknown error";return{ok:!1,message:`Dataverse rejected the ribbon (${i}): ${o}`}}return null}function lt(e,s){if(!e)return{ok:!1,message:"The import job returned no result data, so the ribbon import could not be verified."};if(s.kind==="application"){const a=e.search(/<ribbon\s[^>]*processed="true"/);return a===-1?{ok:!1,message:"Import completed, but Dataverse did not process the application ribbon."}:Ln(Dn(e,a,"</ribbon>"))??{ok:!0,message:"Application ribbon imported."}}const i=new Set(s.names.filter(Boolean).map(a=>a.toLowerCase())),o=/<entityRibbon\s[^>]*>/g;let l;for(;l=o.exec(e);){const a=(pe(l[0],"id")??"").toLowerCase();if(i.has(a))return pe(l[0],"processed")!=="true"?{ok:!1,message:`Dataverse did not process the ribbon for ${a}.`}:Ln(Dn(e,l.index,"</entityRibbon>"))??{ok:!0,message:`Ribbon for ${a} imported.`}}return{ok:!1,message:`Import completed, but Dataverse did not apply a ribbon for ${s.names.join(" / ")} (no entityRibbon result in the import job). Nothing was changed.`}}const G=window.dataverseAPI;async function rt(e,s,i){return await i("The import"),G.execute({operationName:"ImportSolution",operationType:"action",parameters:{CustomizationFile:e,ImportJobId:s,OverwriteUnmanagedCustomizations:!0,PublishWorkflows:!1}})}async function ct(e,s){await s("Publishing");const i=e.map(o=>`<entity>${z(o)}</entity>`).join("");return G.execute({operationName:"PublishXml",operationType:"action",parameters:{ParameterXml:`<importexportxml><entities>${i}</entities></importexportxml>`}})}function zn(e){const s=e.data?.progress;return!!(typeof s=="object"&&s!==null&&s.completed===!0||typeof e.progress=="number"&&e.progress>=100||typeof s=="number"&&s>=100||e.completedon||e.data?.completedon||e.statuscode===30)}function dt(e){const s=e.titles.map(i=>`<Title languagecode="${i.languageCode}" description="${z(i.description)}"/>`).join("");return`<LocLabel Id="${z(e.id)}"><Titles>${s}</Titles></LocLabel>`}async function Kn(e){const s=e.entity?.logicalName??"{!EntityLogicalName}",i={deletedContainerIds:e.plan.deletedContainerIds??[],movedButtons:e.plan.movedButtons??[],editedLocLabelIds:e.plan.editedLocLabelIds??[],editedTabIds:e.plan.editedTabIds??[],resequencedTabs:e.plan.resequencedTabs??[],resequencedGroups:e.plan.resequencedGroups??[]},o=e.locLabels.filter(r=>i.editedLocLabelIds.includes(r.id)),l=e.languageCode??1033;for(const r of e.plan.renamedLabels??[]){const h=o.find(S=>S.id===r.id)??e.locLabels.find(S=>S.id===r.id),j=[{languageCode:l,description:r.text},...(h?.titles??[]).filter(S=>S.languageCode!==l)],R=o.findIndex(S=>S.id===r.id);R>=0?o[R]={id:r.id,titles:j}:o.push({id:r.id,titles:j})}let a=o.length?ve(`<RibbonDiffXml><LocLabels>${o.map(dt).join("")}</LocLabels></RibbonDiffXml>`):ws();for(const r of e.locations){const h=Cs({current:r.current,baseline:r.baseline,commands:e.commands,enableRules:e.enableRules,displayRules:e.displayRules,locLabels:e.locLabels,entityLogicalName:s,location:r.current.location,languageCode:e.languageCode});a=_e(a,ve(h))}const c=[],u=[];for(const r of e.locations)for(const h of r.current.tabs){if(!i.editedTabIds.includes(h.id))continue;if(h.tabDisplayRules.length>0){const R=js(h,e.entity===null);R&&u.push(R)}const j=new Set(h.tabDisplayRules.map(R=>R.tabCommand));for(const R of r.baseline.tabs.find(S=>S.id===h.id)?.tabDisplayRules??[])j.has(R.tabCommand)||c.push(R.tabCommand)}u.length>0&&(a=_e(a,ve(`<RibbonDiffXml><RuleDefinitions><TabDisplayRules>${u.join("")}</TabDisplayRules></RuleDefinitions></RibbonDiffXml>`)));const y=[...e.commands.filter(r=>e.plan.editedCommandIds.includes(r.id)).map(vs)],T={enable:e.enableRules.filter(r=>e.plan.editedEnableRuleIds.includes(r.id)).map(Ss),display:e.displayRules.filter(r=>e.plan.editedDisplayRuleIds.includes(r.id)).map(Rs)};(y.length||T.enable.length||T.display.length)&&(a=_e(a,ve(`<RibbonDiffXml><CommandDefinitions>${y.join("")}</CommandDefinitions><RuleDefinitions><DisplayRules>${T.display.join("")}</DisplayRules><EnableRules>${T.enable.join("")}</EnableRules></RuleDefinitions></RibbonDiffXml>`)));const P=(r,h)=>{for(const j of Array.from(r.keys()))h.includes(j)||r.delete(j)},N=e.locations.flatMap(r=>r.current.tabs.filter(h=>!r.baseline.tabs.some(j=>j.id===h.id)).map($s));P(a.commandDefinitions,[...e.plan.editedCommandIds,...N]),P(a.enableRules,e.plan.editedEnableRuleIds),P(a.displayRules,e.plan.editedDisplayRuleIds);const m=await Qe(e.entity?.logicalName??null),v=Is(m),b=e.plan.deletedButtonIds.filter(r=>!v.has(r));if(b.length>0)throw new Error(`Can't delete ${b.join(", ")}: not defined in this table's unmanaged customizations (it comes from a managed solution or the platform). Undo the delete and hide the button instead.`);const x=Ns(m),g=i.deletedContainerIds.filter(r=>!x.has(r));if(g.length>0)throw new Error(`Can't delete ${g.join(", ")}: not added by this table's unmanaged customizations (it comes from a managed solution or the platform). Undo the delete.`);const p=i.movedButtons.filter(r=>!v.has(r.id)).map(r=>r.id);if(p.length>0)throw new Error(`Can't move ${p.join(", ")}: not defined in this table's unmanaged customizations. Undo the move.`);const q=ks(m),H=(e.plan.uncustomisedCommandIds??[]).filter(r=>m.commandDefinitions.has(r)&&!Ps(r,q));if(H.length>0)throw new Error(`Can't uncustomise ${H.join(", ")}: it is your own command (your customizations' buttons use it and no other solution defines it), so removing it would leave those buttons without a command. Undo the uncustomise.`);const J=new Set;for(const r of e.locations)for(const h of r.current.tabs)for(const j of h.groups)for(const R of He(j))for(const S of Ts(R))J.add(S);const X=e.plan.uncustomisedCommandIds??[],B=new Set,Y=new Set;for(const r of e.commands)if(!(!J.has(r.id)||X.includes(r.id))){r.enableRules.forEach(h=>B.add(h)),r.displayRules.forEach(h=>Y.add(h));for(const h of r.rawRuleRefs??[]){const j=/^\s*<(EnableRule|DisplayRule)\b[^>]*?\sId="([^"]+)"/.exec(h.xml);j&&(j[1]==="EnableRule"?B:Y).add(j[2])}}let C=As(m,a,{retainedCommandIds:J,editedCommandIds:e.plan.editedCommandIds,editedEnableRuleIds:e.plan.editedEnableRuleIds,editedDisplayRuleIds:e.plan.editedDisplayRuleIds,deletedControlIds:e.plan.deletedButtonIds,unhiddenControlIds:e.plan.unhiddenButtonIds,deletedContainerIds:i.deletedContainerIds,movedControls:i.movedButtons,resequencedContainers:[...i.resequencedTabs,...i.resequencedGroups],removedTabCommands:c,uncustomisedCommandIds:X,retainedEnableRuleIds:B,retainedDisplayRuleIds:Y});for(const r of e.plan.renamedLabels??[])r.newLabel&&(C=Es(C,r.containerId,`$LocLabels:${r.id}`));const d=new Set([...Sn(m),...Sn(C)].map(r=>r.id)),k={};for(const r of e.locations)for(const[h,j]of Object.entries(r.baseline.scalingByTab??{}))k[h]={maxSizes:j.maxSizes.filter(R=>!d.has(R.id)).map(R=>R.sequence),scales:j.scales.filter(R=>!d.has(R.id)).map(R=>R.sequence)};const A=Ds(C,k);if(A.problems.length>0)throw new Error(`Not published: ${A.problems.join("; ")}.`);return C=A.parts,{scalingChanges:A.changes,xml:zs(C),parts:C,elementCount:Ke(C),preservedCount:Ke(m),changedCount:Ke(a),changedKeys:Ls(m,C),newKeys:Object.keys(C).flatMap(r=>Array.from(C[r].keys()).filter(h=>!m[r].has(h)).map(h=>`${r}:${h}`)),layerDefinitionIds:{commandIds:Array.from(m.commandDefinitions.keys()),enableRuleIds:Array.from(m.enableRules.keys()),displayRuleIds:Array.from(m.displayRules.keys())},layer:m}}function Gn(e,s){const i=[],o={},l={},a={},c={},u=new Set,y=new Set,T=new Set;for(const{current:m,baseline:v}of e.locations)for(const b of[v,m])for(const x of b.tabs)for(const g of x.groups)for(const p of He(g))for(const q of p.menu?.sections??[])T.add(q.controlsId);for(const{current:m,baseline:v}of e.locations){Object.assign(a,v.templateLayouts);for(const b of v.tabs){i.push(b.id),b.label&&(c[b.id]={Title:b.label});for(const x of b.groups){u.add(x.id),i.push(x.id),x.label&&(c[x.id]={Title:x.label,Label:x.label});for(const g of He(x))i.push(g.id),g.source&&(c[g.id]=g.source.attributes)}}for(const b of m.tabs)for(const x of b.groups)y.add(x.id);for(const b of[v,m])for(const x of b.tabs)for(const g of x.groups)g.template&&(l[g.id]=g.template)}const P=m=>u.has(m.groupId)&&!y.has(m.groupId);for(const{baseline:m}of e.locations)for(const[v,b]of Object.entries(m.scalingByTab??{}))o[v]={...b,maxSizes:b.maxSizes.filter(x=>!P(x)),scales:b.scales.filter(x=>!P(x))};const N=(m,v)=>{if(!m)return;const b=new Set(v??[]);return m.map(x=>x.id).filter(x=>!b.has(x))};return{changedKeys:s.changedKeys,newKeys:s.newKeys,commands:e.commands,known:{commandIds:N(e.baselineCommands,s.layerDefinitionIds?.commandIds),enableRuleIds:N(e.baselineEnableRules,s.layerDefinitionIds?.enableRuleIds),displayRuleIds:N(e.baselineDisplayRules,s.layerDefinitionIds?.displayRuleIds),elementIds:i},loadedAttributes:c,publisherPrefix:e.publisherPrefix,tabScaling:o,groupTemplates:l,templateLayouts:a,menuControlsIds:T,...e.entity?{places:{entityLogicalName:e.entity.logicalName,tabByCollection:Object.fromEntries(Ms(e.locations.map(m=>m.baseline),e.entity.logicalName))}}:{}}}function ut(e,s){return new Promise((i,o)=>{const l=setTimeout(()=>o(new Error(`it didn't finish within ${Math.round(s/1e3)} s`)),s);e.then(a=>{clearTimeout(l),i(a)},a=>{clearTimeout(l),o(a)})})}async function Mn(e,s={}){const i=await Kn(e),o=Gn(e,i),l=[],a=Ys(i.parts);if(s.lookupWebResources&&a.length>0)try{o.webResources=await s.lookupWebResources(a)}catch(c){l.push({severity:"warning",code:"webresource-lookup",message:`Couldn't check the ${a.length} referenced web resource(s): ${c instanceof Error?c.message:String(c)}`})}return{findings:[...Wn(i.parts,o),...l],xml:i.xml}}async function ht(e,s,i={}){const o=i.attempts??3,l=i.contentKeys??[];let a={missing:[],unexpected:[],differing:[]};for(let u=0;u<o;u++){u>0&&await new Promise(y=>setTimeout(y,i.delayMs??5e3));try{a=qn(s,await Qe(e),{contentKeys:l})}catch(y){return{ok:!1,missing:[],unexpected:[],differing:[],message:`Couldn't read the published ribbon layer to verify it (${y instanceof Error?y.message:String(y)}).`}}if(a.missing.length===0&&a.unexpected.length===0&&a.differing.length===0){const y=l.length;return{ok:!0,...a,message:"Verified: the published ribbon layer has every element that was imported"+(y>0?`, and the ${y} element(s) this publish changed have the imported content.`:".")}}}const c=u=>u.slice(0,5).join(", ")+(u.length>5?", …":"");return{ok:!1,...a,message:"The published ribbon layer doesn't match what was imported"+(a.missing.length?`; missing: ${c(a.missing)}`:"")+(a.unexpected.length?`; unexpected: ${c(a.unexpected)}`:"")+(a.differing.length?`; different content: ${c(a.differing)}`:"")+". Reload the table and check before publishing again."}}class Ze extends Error{constructor(s,i,o=!1){const l=o?"another solution import ran in the environment meanwhile, and what it changed may not be published yet":Hn(i);super(o?`${s}'s ribbon customizations may have changed in Dataverse since you started publishing: ${l}. Importing could overwrite that change, so nothing was imported. Publish again: the table is published first, so the change is kept.`:`${s}'s ribbon customizations changed in Dataverse since you started publishing (${l}): other ribbon changes for it were published meanwhile, from another session, tool or solution import. Importing would overwrite that change, so nothing was imported. Reload the table to get the change, then publish again.`),this.scopeLabel=s,this.changes=i,this.importRan=o,this.name="RibbonLayerChangedError",this.summary=l}scopeLabel;changes;importRan;summary}function Hn(e){const s=i=>i.slice(0,5).join(", ")+(i.length>5?", …":"");return[e.unexpected.length?`added: ${s(e.unexpected)}`:"",e.missing.length?`removed: ${s(e.missing)}`:"",e.differing.length?`changed: ${s(e.differing)}`:""].filter(Boolean).join("; ")}function mt(e){const s=e instanceof Error?e.message:String(e);return/there is (?:another|a previous) \[(\w+)\] running/i.exec(s)?.[1]??null}const pt=e=>Object.keys(e).flatMap(s=>Array.from(e[s].keys()).map(i=>`${s}:${i}`));function Jn(e,s){const i=[],o=[],l=[];for(const a of Object.keys(e)){for(const[c,u]of e[a]){const y=s[a].get(c);y===void 0?i.push(`${a}:${c}`):y!==u&&l.push(`${a}:${c}`)}for(const c of s[a].keys())e[a].has(c)||o.push(`${a}:${c}`)}return{missing:i,unexpected:o,differing:l}}const Yn=e=>e.missing.length+e.unexpected.length+e.differing.length>0;async function bt(e,s,i,o){const l=o.kind==="imported"?o.attempts??3:1;let a={missing:[],unexpected:[],differing:[]};for(let c=0;c<l;c++){c>0&&o.kind==="imported"&&await new Promise(y=>setTimeout(y,o.delayMs??5e3));const u=await Qe(e);if(a=o.kind==="read"?Jn(i,u):qn(i,u,{contentKeys:pt(i)}),!Yn(a))return}throw new Ze(s,a)}function On(e,s){return nn(()=>gt(e,s)).finally(()=>Bn({afterPublish:!0}))}async function gt(e,s){const i=e.guard??en(),o=Pe.getState(),l=e.entity?e.entity.logicalName:"Application ribbon",a={onProgress:s,...e.busy},c=e.entity===null;if(c&&!e.ribbonCustomizationIds?.length)throw new Error("The selected solution does not contain Application Ribbons. Add it in make.powerapps.com (Solutions → your solution → Add existing → Application Ribbons) and reload the solution.");const u=async(d="Publishing customizations…")=>{s?.(d),await In("Publish",async()=>{c?(await i("Publishing"),await G.execute({operationName:"PublishXml",operationType:"action",parameters:{ParameterXml:"<importexportxml><ribbons><ribbon></ribbon></ribbons></importexportxml>"}})):await ct([e.entity.logicalName],i)},a)},y=e.languageCode??await Os(),T=async d=>{s?.(`Reading existing ribbon customizations for ${l}…`),d&&o.logInfo("publish",`Reading unmanaged ribbon layer for ${l}.`);const k=await Kn({...e,languageCode:y}),A=Wn(k.parts,Gn({...e,publisherPrefix:e.solution.publisherPrefix},k)),r=A.filter(h=>h.severity==="error");if(d||r.length>0){o.logInfo("publish",`RibbonDiffXml for ${l}: ${k.preservedCount} existing element(s) preserved, ${k.changedCount} element(s) from this session, ${k.elementCount} total.`);for(const h of k.scalingChanges)o.logWarn("publish",Vs(h));for(const h of A)h.severity==="warning"&&o.logWarn("publish",h.message)}if(r.length>0){for(const h of r)o.logError("publish",h.message);throw new Error(`The pre-publish check found ${r.length} error(s), so nothing was imported: `+r.map(h=>h.message).join("; "))}return k},P=e.publishCustomizations!==!1?await T(!1):null;s?.("Checking that no other solution operation is running…"),await Us(a);const N=await xt(e.solution);let m=!1;const v=d=>(P&&!m&&d instanceof Error&&(d.message+=` (${l} was published first, so customizations imported elsewhere for it and not yet published are now published.)`),d);if(P){o.logInfo("publish",`Publishing ${l} first, so ribbon changes imported elsewhere but not yet published are kept.`);try{await u(`Publishing ${l} first (keeps changes imported elsewhere but not published)…`)}catch(d){throw d instanceof Error&&(d.message=`Publishing ${l} first failed, so nothing was imported: ${d.message}`),d}}let b;try{b=await T(!0)}catch(d){throw P&&d instanceof Error&&!d.message.startsWith("The pre-publish check")&&(d.message=`${l}'s customizations changed when it was published first (changes imported elsewhere and not yet published): ${d.message} Reload the table to get them, then publish again.`),v(d)}if(P){const d=Jn(P.layer,b.layer);Yn(d)&&o.logInfo("publish",`Publishing ${l} first published ribbon changes imported elsewhere (${Hn(d)}); they are kept.`)}const x=e.entity?.schemaName||e.entity?.logicalName||"",g=c?$n({applicationRibbonDiffXml:b.xml}):$n({entities:[{schemaName:x,localizedName:e.entity?.displayName||x,ribbonDiffXml:b.xml}]}),p=c?[{type:50,schemaName:":RibbonDiffXml",behavior:0}]:[{type:1,schemaName:e.entity.logicalName,behavior:2}],q=jt({...e.solution,languageCode:y,rootComponents:p,details:N});s?.("Packaging solution ZIP…");const H=Xs({"customizations.xml":Ge(g),"solution.xml":Ge(q),"[Content_Types].xml":Ge('<?xml version="1.0" encoding="utf-8"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="xml" ContentType="application/xml"/></Types>')});let J="";for(let d=0;d<H.length;d++)J+=String.fromCharCode(H[d]);const X=btoa(J),B=async(d,k)=>{s?.(`Importing ${l} ribbon${d}…`);const A=crypto.randomUUID();o.logInfo("publish",`Importing solution${d} (import job ${A})…`);let r=!1;await In("Import",async()=>{if(await i("Importing"),r)throw new Ze(l,{missing:[],unexpected:[],differing:[]},!0);await bt(e.entity?.logicalName??null,l,k.layer,k.as);try{await rt(X,A,i)}catch(_){throw Bs(_)&&mt(_)?.toLowerCase()==="import"&&(r=!0),_}m=!0},a);const h=150,j=2e3;let R=await G.getImportJobStatus(A),S=0;for(;!zn(R)&&S<h;)await new Promise(_=>setTimeout(_,j)),R=await G.getImportJobStatus(A),S++,S%10===0&&s?.(`Still importing… (${S*2}s elapsed)`);if(!zn(R))throw new Error(`Solution import did not complete within ${h*j/1e3} seconds. Check Solutions › History for import job ${A}.`);s?.("Verifying the import…");const W=await G.retrieve("importjob",A,["data"]),Z=lt(W.data,c?{kind:"application"}:{kind:"entity",names:[x,e.entity.logicalName]});if(!Z.ok)throw o.logError("publish",Z.message),new Error(Z.message);return o.logInfo("publish",Z.message),A};let Y;try{Y=await B("",{layer:b.layer,as:{kind:"read"}})}catch(d){throw v(d)}let C;if(e.publishCustomizations!==!1){await u();{o.logInfo("publish","Refreshing Unified Interface command-bar metadata (second import of the same package)…");try{await B(" (refreshing Unified Interface metadata)",{layer:b.parts,as:{kind:"imported",delayMs:e.verifyDelayMs}}),await u()}catch(d){if(d instanceof Ze)C={ok:!1,...d.changes,message:`Your changes were imported and published, but ${l}'s ribbon customizations changed in Dataverse after that (${d.summary}): other changes were published meanwhile. They weren't imported a second time to refresh Unified Interface's command-bar metadata, since that would overwrite the other change, so new or changed buttons may not appear in the app until the table's ribbon is published again. Reload the table to see the other change.`},o.logWarn("publish",C.message);else throw new Error(`Your changes were imported and published, but refreshing Unified Interface's command-bar metadata failed (${d instanceof Error?d.message:String(d)}). New or changed buttons may not appear in the app until you publish again.`)}}C||(s?.("Verifying the published ribbon…"),C=await ht(e.entity?.logicalName??null,b.parts,{delayMs:e.verifyDelayMs,contentKeys:b.changedKeys}),C.ok?o.logInfo("publish",C.message):o.logWarn("publish",C.message))}else o.logWarn("publish","Imported without publishing. New or changed buttons appear in Unified Interface only after you publish from Command Bar Studio (which re-imports once to refresh the command-bar metadata).");return s?.(e.publishCustomizations!==!1?`${l} ribbon published.`:`${l} ribbon imported (not published).`),{elementCount:b.elementCount,preservedCount:b.preservedCount,importJobId:Y,verification:C,parts:b.parts,changedKeys:b.changedKeys}}function ft(e,s){return nn(()=>yt(e,s)).finally(()=>Bn({afterPublish:!0}))}async function yt(e,s){const i=s?.guard??en(),o=Pe.getState(),l=s?.pollIntervalMs??2e3,a=s?.timeoutMs??600*1e3;e?.("Starting asynchronous publish (PublishAllXmlAsync)..."),o.logInfo("publish","Calling PublishAllXmlAsync action."),await i("Publishing");const u=(await G.execute({operationName:"PublishAllXmlAsync",operationType:"action"}))?.AsyncOperationId;if(!u)throw new Error("PublishAllXmlAsync did not return AsyncOperationId.");o.logInfo("publish",`PublishAllXmlAsync job id: ${u}`),e?.("Async publish job started. Waiting for completion...");const y=Date.now();let T=0,P;for(;Date.now()-y<a;){T+=1;const N=await G.retrieve("asyncoperation",u,["asyncoperationid","statecode","statuscode","name","message","friendlymessage","completedon"]);if(P=N.statuscode,N.statecode===3||!!N.completedon){if(typeof N.statuscode=="number"&&N.statuscode!==30){const v=N.friendlymessage||N.message||`statuscode=${N.statuscode}`;throw new Error(`Asynchronous publish failed: ${v}`)}return e?.("Asynchronous publish completed successfully."),o.logInfo("publish",`PublishAllXmlAsync completed in ${T} poll(s).`),{asyncOperationId:u,statusCode:N.statuscode}}e?.(`Waiting for async publish job... (poll ${T})`),await new Promise(v=>setTimeout(v,l))}throw new Error(`Asynchronous publish timed out after ${Math.round(a/1e3)} seconds (last status: ${P??"unknown"}).`)}const Zn=[["AddressTypeCode","addresstypecode"],["City","city"],["County","county"],["Country","country"],["Fax","fax"],["FreightTermsCode","freighttermscode"],["Latitude","latitude"],["Line1","line1"],["Line2","line2"],["Line3","line3"],["Longitude","longitude"],["Name","name"],["PostalCode","postalcode"],["PostOfficeBox","postofficebox"],["PrimaryContactName","primarycontactname"],["ShippingMethodCode","shippingmethodcode"],["StateOrProvince","stateorprovince"],["Telephone1","telephone1"],["Telephone2","telephone2"],["Telephone3","telephone3"],["UPSZone","upszone"],["UTCOffset","utcoffset"],["UTCConversionTimeZoneCode","utcconversiontimezonecode"]];async function xt(e){let s;try{s=(await G.queryData(`solutions?$select=description&$expand=publisherid&$filter=uniquename eq '${e.uniqueName.replace(/'/g,"''")}'`)).value?.[0]}catch(c){throw new Error(`Couldn't read solution ${e.uniqueName} and its publisher (${c instanceof Error?c.message:String(c)}), so nothing was imported: an import without them would clear the publisher's details.`)}const i=s?.publisherid;if(!s||!i)throw new Error(`Couldn't read solution ${e.uniqueName} and its publisher, so nothing was imported: an import without them would clear the publisher's details.`);const o=i.customizationoptionvalueprefix;if(typeof o!="number")throw new Error(`Couldn't read the option-value prefix of publisher ${e.publisherUniqueName}, so nothing was imported: a wrong one would change the publisher.`);const l=c=>typeof c=="string"?c:"",a=[1,2].map(c=>Object.fromEntries(Zn.map(([,u])=>[u,i[`address${c}_${u}`]]).filter(([,u])=>u!=null&&u!==""))).map((c,u)=>({number:u+1,...c}));return{solutionDescription:l(s.description),publisherDescription:l(i.description),publisherEmail:l(i.emailaddress),publisherWebsite:l(i.supportingwebsiteurl),publisherOptionValuePrefix:o,publisherAddresses:a.filter(c=>Object.keys(c).length>1)}}const wt=e=>z(e).replace(/\r/g,"
").replace(/\n/g,"
").replace(/\t/g,"	"),Un=(e,s)=>e?`<Descriptions>
|
|
2
|
+
<Description description="${wt(e)}" languagecode="${s}"/>
|
|
3
|
+
</Descriptions>`:"<Descriptions/>",Ct=e=>e.length===0?"<Addresses/>":`<Addresses>${e.map(s=>`
|
|
4
|
+
<Address>
|
|
5
|
+
<AddressNumber>${s.number}</AddressNumber>${Zn.filter(([,i])=>i in s).map(([i,o])=>`
|
|
6
|
+
<${i}>${z(String(s[o]))}</${i}>`).join("")}
|
|
7
|
+
</Address>`).join("")}
|
|
8
|
+
</Addresses>`;function jt(e){const s=e.publisherUniqueName?.trim()||"DefaultPublisher",i=e.publisherName?.trim()||s,o=e.publisherPrefix?.trim()||"new",l=e.languageCode||1033,a=e.friendlyName?.trim()||e.uniqueName,c=e.rootComponents.length===0?"<RootComponents/>":`<RootComponents>
|
|
9
|
+
${e.rootComponents.map(u=>{const y=[`type="${u.type}"`];return u.schemaName&&y.push(`schemaName="${z(u.schemaName)}"`),u.id&&y.push(`id="{${z(u.id)}}"`),y.push(`behavior="${u.behavior}"`),`<RootComponent ${y.join(" ")} />`}).join(`
|
|
10
|
+
`)}
|
|
11
|
+
</RootComponents>`;return`<?xml version="1.0" encoding="utf-8"?>
|
|
12
|
+
<ImportExportXml version="9.1.0.0" SolutionPackageVersion="9.1" languagecode="${l}" generatedBy="CommandBarStudio">
|
|
13
|
+
<SolutionManifest>
|
|
14
|
+
<UniqueName>${z(e.uniqueName)}</UniqueName>
|
|
15
|
+
<LocalizedNames>
|
|
16
|
+
<LocalizedName description="${z(a)}" languagecode="${l}"/>
|
|
17
|
+
</LocalizedNames>
|
|
18
|
+
${Un(e.details.solutionDescription,l)}
|
|
19
|
+
<Version>${z(e.version)}</Version>
|
|
20
|
+
<Managed>0</Managed>
|
|
21
|
+
<Publisher>
|
|
22
|
+
<UniqueName>${z(s)}</UniqueName>
|
|
23
|
+
<LocalizedNames>
|
|
24
|
+
<LocalizedName description="${z(i)}" languagecode="${l}"/>
|
|
25
|
+
</LocalizedNames>
|
|
26
|
+
${Un(e.details.publisherDescription,l)}
|
|
27
|
+
<EMailAddress>${z(e.details.publisherEmail)}</EMailAddress>
|
|
28
|
+
<SupportingWebsiteUrl>${z(e.details.publisherWebsite)}</SupportingWebsiteUrl>
|
|
29
|
+
<CustomizationPrefix>${z(o)}</CustomizationPrefix>
|
|
30
|
+
<CustomizationOptionValuePrefix>${e.details.publisherOptionValuePrefix}</CustomizationOptionValuePrefix>
|
|
31
|
+
${Ct(e.details.publisherAddresses)}
|
|
32
|
+
</Publisher>
|
|
33
|
+
${c}
|
|
34
|
+
<MissingDependencies/>
|
|
35
|
+
</SolutionManifest>
|
|
36
|
+
</ImportExportXml>`}const vt=Vn({root:{display:"flex",flexDirection:"column",gap:I.spacingVerticalS},box:{display:"grid",gridTemplateColumns:"auto 1fr",columnGap:I.spacingHorizontalM,rowGap:I.spacingVerticalXS,padding:`${I.spacingVerticalS} ${I.spacingHorizontalM}`,backgroundColor:I.colorNeutralBackground3,borderRadius:I.borderRadiusMedium},label:{color:I.colorNeutralForeground3},value:{display:"flex",flexWrap:"wrap",alignItems:"center",columnGap:I.spacingHorizontalS,minWidth:0},secondary:{color:I.colorNeutralForeground3,wordBreak:"break-all"}});function Rt({rows:e,confirmWord:s,onConfirmationChange:i,disabled:o}){const l=vt(),[a,c]=$.useState({status:"loading"}),[u,y]=$.useState(""),T=F(p=>p.environment),P=F(p=>p.connectionUrl),N=F(p=>p.connectionVersion);$.useEffect(()=>{let p=!0;return c({status:"loading"}),Fn().then(q=>p&&c({status:"ready",connection:q})).catch(()=>p&&c({status:"ready",connection:null})),()=>{p=!1}},[T,P,N]);const m=a.status==="ready"?a.connection:null,v=qs(m?.environment),b=a.status==="ready"&&Je(m?.environment),x=a.status==="ready"&&(!b||Fs(u,s)),g=m?.environment;return $.useEffect(()=>{i(x,g)},[x,g,i]),n.jsxs("div",{className:l.root,children:[v&&n.jsx(se,{intent:"warning",children:n.jsxs(te,{children:[n.jsx(Ne,{children:"Production environment"}),"This changes the live environment."]})}),n.jsxs("div",{className:l.box,children:[n.jsx(D,{className:l.label,children:"Environment"}),n.jsx("div",{className:l.value,children:a.status==="loading"?n.jsx(D,{children:"Reading the connection…"}):m?n.jsxs(n.Fragment,{children:[n.jsx(D,{weight:"semibold",children:m.name}),m.environment&&n.jsx(Ye,{size:"medium",appearance:v?"filled":"tint",color:v?"warning":"informative",children:m.environment}),n.jsx(D,{size:200,className:l.secondary,children:m.url})]}):n.jsx(D,{children:"Unknown (the tool has no connection)"})}),e.map(p=>n.jsxs("div",{style:{display:"contents"},children:[n.jsx(D,{className:l.label,children:p.label}),n.jsx("div",{className:l.value,children:p.value})]},p.label))]}),b&&n.jsx(ke,{label:n.jsxs(n.Fragment,{children:["Type ",n.jsx("strong",{children:s})," to confirm"]}),hint:"Required on a Production environment.",children:n.jsx(_n,{value:u,onChange:(p,q)=>y(q.value),disabled:o,autoComplete:"off","aria-label":`Type ${s} to confirm`})})]})}const Qn=Vn({content:{display:"flex",flexDirection:"column",gap:I.spacingVerticalM},changes:{listStyleType:"none",margin:0,padding:0,display:"flex",flexDirection:"column",gap:I.spacingVerticalXS},change:{display:"flex",alignItems:"flex-start",gap:I.spacingHorizontalS},changeIcon:{flexShrink:0,fontSize:"16px",marginTop:"2px",color:I.colorNeutralForeground3},changeText:{flex:1,minWidth:0,overflowWrap:"anywhere"},badge:{flexShrink:0},list:{margin:`${I.spacingVerticalXS} 0 0`,paddingLeft:"20px"},options:{display:"flex",flexDirection:"column",gap:I.spacingVerticalS},timing:{color:I.colorNeutralForeground3},progressList:{display:"flex",flexDirection:"column",gap:I.spacingVerticalXS},progressRow:{display:"flex",alignItems:"center",gap:I.spacingHorizontalS},xmlHeader:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:I.spacingHorizontalS},xml:{height:"360px",border:`1px solid ${I.colorNeutralStroke2}`,borderRadius:I.borderRadiusMedium,overflow:"hidden"}}),St={pending:"Waiting",publishing:"Publishing…",success:"Done",error:"Failed"},$t={pending:"subtle",publishing:"informative",success:"success",error:"danger"},It={new:{text:"New",color:"success",icon:n.jsx(xs,{})},change:{text:"Change",color:"brand",icon:n.jsx(ys,{})},move:{text:"Move",color:"informative",icon:n.jsx(fs,{})},show:{text:"Show",color:"informative",icon:n.jsx(gs,{})},hide:{text:"Hide",color:"warning",icon:n.jsx(bs,{})},delete:{text:"Delete",color:"danger",icon:n.jsx(ps,{})}},Xn=({findings:e,showScope:s})=>{const i=Qn();return n.jsx("ul",{className:i.list,children:e.map((o,l)=>n.jsxs("li",{children:[s&&n.jsxs("strong",{children:[o.scope,": "]}),o.message]},l))})},de=(e,s,i=`${s}s`)=>`${e} ${e===1?s:i}`,Nt=3e4,Ot=()=>{const e=Qn(),s=Nn(t=>t.bulkPublishOpen),i=Nn(t=>t.closeBulkPublish),o=V(t=>t.ribbons),l=V(t=>t.baseline),a=V(t=>t.commands),c=V(t=>t.displayRules),u=V(t=>t.enableRules),y=V(t=>t.baselineCommands),T=V(t=>t.baselineEnableRules),P=V(t=>t.baselineDisplayRules),N=V(t=>t.locLabels),m=V(t=>t.baseLanguageCode),v=V(t=>t.baseLanguageUnknown),b=V(t=>t.setLayerSnapshot),x=V(t=>t.markPublished),g=F(t=>t.activeSolution),p=F(t=>t.activeEntity),q=F(t=>t.connectionUrl),H=F(t=>t.publisherPrefix),J=F(t=>t.solutionRibbonComponentIds),{entityPlan:X,appPlan:B,solutionSupportsAppRibbon:Y,includeApplicationRibbon:C,scopes:d,unsupported:k,warnings:A,changes:r}=Ws(),[h,j]=$.useState(!1),[R,S]=$.useState({}),[W,Z]=$.useState(!1),[_,es]=$.useState(!1),[ue,Te]=$.useState("targeted"),[sn,be]=$.useState(!1),Ae=ue==="allAsync"&&!sn,Ee=F(t=>t.connectionName||t.connectionUrl||"this environment"),[tn,De]=$.useState({confirmed:!1}),ns=re.useCallback((t,f)=>De({confirmed:t,environment:f}),[]),on=tn.confirmed,[ss,an]=$.useState(0),[ln,ie]=$.useState(""),[Le,rn]=$.useState(""),[ge,cn]=$.useState(g?.version??"1.0.0.0"),[ze,fe]=$.useState([]),[dn,un]=$.useState([]),[ts,is]=$.useState(0),[os,ye]=$.useState([]),[xe,Me]=$.useState("summary"),[as,Oe]=$.useState([]),hn=re.useMemo(()=>{const f=(ge||g?.version||"1.0.0.0").split(".").map(L=>Number.parseInt(L,10)||0);for(;f.length<4;)f.push(0);return f[3]+=1,f.slice(0,4).join(".")},[g?.version,ge]);re.useEffect(()=>{cn(g?.version??"1.0.0.0")},[g?.version]);const ls=p&&X?.hasChanges?p.logicalName:"application ribbon",[oe,we]=$.useState("idle"),[Ue,Xe]=$.useState([]),[mn,Ve]=$.useState([]),[pn,Be]=$.useState(""),K=s&&!!g&&k.length===0&&d.length>0,bn=g?.id,gn=g?.publisherPrefix||H,fn=re.useCallback(async()=>{const t={commands:a,enableRules:u,displayRules:c,locLabels:N,baselineCommands:y,baselineEnableRules:T,baselineDisplayRules:P,publisherPrefix:gn,languageCode:m},f={lookupWebResources:M=>Gs(M,bn)},L=[],le=[];if(p&&X?.hasChanges){const M=await Mn({...t,entity:{logicalName:p.logicalName,schemaName:p.schemaName},locations:Re.map(O=>({current:o[O],baseline:l[O]})),plan:X},f);L.push(...M.findings.map(O=>({...O,scope:p.logicalName}))),le.push({scope:p.logicalName,xml:M.xml})}if(C){const M=await Mn({...t,entity:null,locations:[{current:o.Application,baseline:l.Application}],plan:B},f);L.push(...M.findings.map(O=>({...O,scope:"Application ribbon"}))),le.push({scope:"Application ribbon",xml:M.xml})}return{findings:L,xml:le}},[p,X,B,C,o,l,a,u,c,N,y,T,P,gn,bn,m]);re.useEffect(()=>{if(!K||h||W)return;let t=!1;return we("running"),Be(""),ut(fn(),Nt).then(({findings:f,xml:L})=>{t||(Xe(f),Ve(L),we("done"))}).catch(f=>{t||(Xe([]),Ve([]),Be(f instanceof Error?f.message:String(f)),we("failed"))}),()=>{t=!0}},[K,h,W,fn]);const Q=Ue.filter(t=>t.severity==="error"),yn=Ue.filter(t=>t.severity==="warning"),xn=new Set(Ue.map(t=>t.scope)).size>1,wn=K&&(oe==="running"||Q.length>0),rs=()=>nn(async()=>{if(!g||k.length>0||d.length===0||wn||!on||v||Ae)return;j(!0);const t=en(),f=F.getState().connectionVersion,L=()=>F.getState().connectionVersion!==f,le=await Fn().catch(()=>null);if(L()){j(!1);return}if(Je(le?.environment)&&!Je(tn.environment)){De({confirmed:!1}),an(w=>w+1),j(!1),Pe.getState().logWarn("publish",`${le?.name??"The connection"} is a Production environment now: type the confirmation to publish.`);return}ie(""),fe([]),ye([]),un(d),is(r.length),S(Object.fromEntries(d.map(w=>[w,"pending"])));let M=!1;const O=[],Fe={},ne=[],je=[],We=Pe.getState(),me=w=>w instanceof Error?w.message:String(w);Le.trim()&&We.logInfo("publish",`Publish comment: ${Le.trim()}`);const Rn={commands:a,enableRules:u,displayRules:c,locLabels:N,baselineCommands:y,baselineEnableRules:T,baselineDisplayRules:P,publishCustomizations:!0,languageCode:m,solution:{uniqueName:g.uniqueName,friendlyName:g.friendlyName,version:_?hn:ge,publisherUniqueName:g.publisherUniqueName,publisherName:g.publisherName,publisherPrefix:g.publisherPrefix||H,publisherOptionValuePrefix:g.publisherOptionValuePrefix}};if(p&&X?.hasChanges){const w=p.logicalName;S(E=>({...E,[w]:"publishing"}));try{const E=await On({...Rn,guard:t,entity:{logicalName:p.logicalName,schemaName:p.schemaName,displayName:p.displayName},locations:Re.map(U=>({current:o[U],baseline:l[U]})),plan:X},U=>ie(U));O.push(...Re),Fe.entity=E.parts,Hs(q,p.logicalName,E.changedKeys),E.verification&&je.push({scope:w,result:E.verification}),S(U=>({...U,[w]:"success"}))}catch(E){M=!0,ne.push({scope:w,message:me(E)}),We.logError("publish",`Ribbon publish failed (${w}): ${me(E)}`),S(U=>({...U,[w]:"error"}))}}else p&&O.push(...Re);if(C&&!L()){const w="Application ribbon";S(E=>({...E,[w]:"publishing"}));try{const E=await On({...Rn,guard:t,entity:null,locations:[{current:o.Application,baseline:l.Application}],ribbonCustomizationIds:J??[],plan:B},U=>ie(U));O.push("Application"),Fe.application=E.parts,E.verification&&je.push({scope:w,result:E.verification}),S(U=>({...U,[w]:"success"}))}catch(E){M=!0,ne.push({scope:w,message:me(E)}),We.logError("publish",`Application ribbon publish failed: ${me(E)}`),S(U=>({...U,[w]:"error"}))}}else B.hasChanges||O.push("Application");if(!M&&ue==="allAsync")try{await ft(w=>ie(w),{guard:t})}catch(w){M=!0,ne.push({scope:"Publish all customizations",message:me(w)})}if(L()){C&&!ne.some(w=>w.scope==="Application ribbon")&&ne.push({scope:"Application ribbon",message:"Not published: the tool's connection changed during the publish."}),ye(je),fe(ne),Z(!1),j(!1);return}if(x(O,Fe),p&&O.includes("HomepageGrid")&&X?.hasChanges){const w=await kn(p.logicalName);w&&b("entity",w)}if(O.includes("Application")&&C){const w=await kn(null);w&&b("application",w)}M||ie("Done."),ye(je),fe(ne),Z(!M),j(!1)}),Cn=()=>{j(!1),S({}),un([]),Z(!1),ie(""),fe([]),ye([]),we("idle"),Xe([]),Ve([]),Be(""),Me("summary"),Oe([]),De({confirmed:!1}),Te("targeted"),be(!1),rn(""),an(t=>t+1),i()},qe=B.hasChanges&&!Y,Ce=k.length+(K?Q.length:0),jn=K?yn.length+(oe==="failed"?1:0):0;re.useEffect(()=>{Ce>0&&Oe(t=>t.includes("problems")?t:["problems",...t])},[Ce]);const ae=g?v?{intent:"error",title:"Reload the table first",text:"The organization's base language couldn't be read when the table loaded, so labels are shown in English. Publishing now could write English texts as the base language's titles."}:k.length>0?{intent:"error",title:`${de(k.length,"change")} can't be published yet`,text:`Undo ${k.length===1?"it":"them"} to publish the rest. Problems below says what each one is.`}:K&&Q.length>0?{intent:"error",title:`The check found ${de(Q.length,"problem")}`,text:`In what this publish would import. Fix ${Q.length===1?"it":"them"}, then open Publish again; Problems below lists ${Q.length===1?"it":"them"}.`}:d.length===0?qe?{intent:"warning",title:"The application ribbon can't be published from this solution",text:n.jsxs(n.Fragment,{children:["It doesn't include the Application Ribbons component. In make.powerapps.com open the solution, choose"," ",n.jsx("strong",{children:"Add existing → Application Ribbons"}),", then reload here."]})}:{intent:"info",title:"Nothing to publish",text:"Every change on this table is already published."}:Ae?{intent:"warning",title:"Confirm publishing everything",text:`Tick the confirmation under Options to publish every unpublished customization in ${Ee}.`,action:n.jsx(ce,{size:"small",onClick:()=>{Te("targeted"),be(!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."},he=p?.displayName||p?.logicalName,vn=!!p&&!!X?.hasChanges,cs=vn&&C?`Publish ${he} and the application ribbon`:!vn&&C?"Publish the application ribbon":he?`Publish ${he}`:"Publish",ds=h?"Publishing…":r.length>0?`Publish ${de(r.length,"change")}`:"Publish",ee=!h&&!W;return n.jsx(_s,{open:s,onOpenChange:t=>!t&&!h&&Cn(),size:xe==="xml"?"large":"medium",title:xe==="xml"?"What Publish imports":cs,startActions:ee?xe==="summary"?n.jsx(ce,{appearance:"subtle",icon:n.jsx(hs,{}),onClick:()=>Me("xml"),children:"View XML"}):n.jsx(ce,{appearance:"subtle",icon:n.jsx(ms,{}),onClick:()=>Me("summary"),children:"Back to summary"}):void 0,actions:n.jsxs(n.Fragment,{children:[n.jsx(ce,{appearance:"secondary",onClick:Cn,disabled:h,children:W?"Close":"Cancel"}),!W&&n.jsx(ce,{appearance:"primary",onClick:()=>{rs()},disabled:h||!g||d.length===0||k.length>0||wn||!on||v||Ae,children:ds})]}),children:xe==="xml"&&ee?n.jsxs("div",{className:e.content,children:[n.jsx(D,{children:"The complete RibbonDiffXml each import writes: your solution's layer as it is now, with your changes merged in."}),K&&oe==="running"?n.jsx(Pn,{size:"tiny",labelPosition:"after",label:"Building the XML…"}):mn.length===0?n.jsx(se,{intent:"info",layout:"multiline",children:n.jsx(te,{children:K&&oe==="failed"?`The XML couldn't be built: ${pn}`:"The XML is built once there is something to publish and nothing blocks it."})}):mn.map(t=>n.jsxs("div",{className:e.options,children:[n.jsxs("div",{className:e.xmlHeader,children:[n.jsx(D,{weight:"semibold",children:t.scope}),n.jsx(ce,{size:"small",appearance:"subtle",icon:n.jsx(us,{}),onClick:()=>{Ks(t.xml)},children:"Copy"})]}),n.jsx("div",{className:e.xml,children:n.jsx(Js,{language:"xml",value:t.xml,readOnly:!0})})]},t.scope))]}):n.jsxs("div",{className:e.content,children:[ee&&ae&&n.jsxs(se,{intent:ae.intent,layout:"multiline",children:[n.jsxs(te,{children:[n.jsx(Ne,{children:ae.title}),ae.text]}),ae.action&&n.jsx(Zs,{children:ae.action})]}),ee&&r.length>0&&n.jsxs("div",{className:e.options,children:[n.jsxs(D,{weight:"semibold",children:[de(r.length,"change")," to publish"]}),n.jsx("ul",{className:e.changes,"aria-label":"Changes to publish",children:r.map((t,f)=>{const L=It[t.kind];return n.jsxs("li",{className:e.change,children:[n.jsx("span",{className:e.changeIcon,"aria-hidden":"true",children:L.icon}),n.jsxs(D,{className:e.changeText,children:[t.action," ",n.jsx("strong",{children:t.name}),t.detail?` ${t.detail}`:""]}),n.jsx(Ye,{appearance:"tint",color:L.color,size:"medium",className:e.badge,children:L.text})]},f)})})]}),ee&&K&&oe==="running"&&n.jsx(Pn,{size:"tiny",labelPosition:"after",label:"Checking what this publish would import…"}),ee&&n.jsx(Rt,{rows:[{label:"Solution",value:g?n.jsx(D,{weight:"semibold",children:g.friendlyName||g.uniqueName}):n.jsx(D,{children:"None selected"})}],confirmWord:ls,onConfirmationChange:ns},ss),ee&&n.jsxs(Qs,{multiple:!0,collapsible:!0,openItems:as,onToggle:(t,f)=>Oe(f.openItems),children:[Ce>0&&n.jsxs(Se,{value:"problems",children:[n.jsxs($e,{children:["Problems · ",Ce]}),n.jsxs(Ie,{children:[k.length>0&&n.jsxs(n.Fragment,{children:[n.jsx(D,{block:!0,children:"These changes can't be published yet; undo them:"}),n.jsx("ul",{className:e.list,children:k.map(t=>n.jsx("li",{children:t},t))})]}),K&&Q.length>0&&n.jsx(Xn,{findings:Q,showScope:xn})]})]}),jn>0&&n.jsxs(Se,{value:"warnings",children:[n.jsxs($e,{children:["Warnings · ",jn]}),n.jsxs(Ie,{children:[n.jsx(D,{block:!0,children:"You can still publish."}),oe==="failed"&&n.jsxs(D,{block:!0,children:["The check before publishing couldn't complete (",pn,"). Publishing runs it again before anything is imported."]}),n.jsx(Xn,{findings:yn,showScope:xn})]})]}),n.jsxs(Se,{value:"info",children:[n.jsxs($e,{children:["Good to know ·"," ",A.length+1+(qe&&d.length>0?1:0)]}),n.jsx(Ie,{children:n.jsxs("ul",{className:e.list,children:[n.jsx("li",{children:"Publishing writes this table'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."}),qe&&d.length>0&&n.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"," ",n.jsx("strong",{children:"Add existing → Application Ribbons"}),", then reload here."]}),A.map(t=>n.jsx("li",{children:t},t))]})})]}),n.jsxs(Se,{value:"options",children:[n.jsx($e,{children:"Options"}),n.jsxs(Ie,{className:e.options,children:[n.jsx(ke,{label:"Also publish",children:n.jsxs(et,{value:ue==="targeted"?"Only these ribbons":"Every unpublished customization",selectedOptions:[ue],onOptionSelect:(t,f)=>{(f.optionValue==="targeted"||f.optionValue==="allAsync")&&(Te(f.optionValue),be(!1))},children:[n.jsx(Tn,{value:"targeted",children:"Only these ribbons"}),n.jsx(Tn,{value:"allAsync",children:"Every unpublished customization"})]})}),ue==="allAsync"&&n.jsx(se,{intent:"warning",layout:"multiline",children:n.jsxs(te,{children:[n.jsxs(D,{block:!0,children:["This publishes ",n.jsx("strong",{children:"every"})," ","unpublished customization in"," ",n.jsx("strong",{children:Ee}),", not only these ribbons: forms, views, tables and other people's work in progress included."]}),n.jsx(nt,{checked:sn,onChange:(t,f)=>be(f.checked===!0),label:`Publish all unpublished customizations in ${Ee}`})]})}),n.jsx(st,{label:"Increment solution version",checked:_,onChange:(t,f)=>es(f.checked===!0)}),n.jsx(ke,{label:"Solution version",children:n.jsx(_n,{value:_?hn:ge,onChange:(t,f)=>cn(f.value),disabled:_})}),n.jsx(ke,{label:"Publish comment",hint:"Written to the Console log with this publish; it isn't stored in Dataverse.",children:n.jsx(tt,{resize:"vertical",value:Le,onChange:(t,f)=>rn(f.value)})})]})]})]}),ee&&d.length>0&&n.jsx(it,{className:e.timing,children:"Publishing takes 1–4 minutes. Users may need to refresh to see the change."}),ze.length>0&&n.jsx(se,{intent:"error",layout:"multiline",children:n.jsxs(te,{children:[n.jsxs(Ne,{children:["Publish failed (",de(ze.length,"error"),")"]}),n.jsx("ul",{className:e.list,children:ze.map((t,f)=>n.jsxs("li",{style:{fontFamily:I.fontFamilyMonospace},children:[n.jsxs("strong",{children:[t.scope,":"]})," ",t.message]},f))}),n.jsxs("div",{style:{marginTop:I.spacingVerticalS},children:["Full details are in the ",n.jsx("strong",{children:"Console"})," tab of the bottom panel."]})]})}),W&&n.jsx(se,{intent:"success",layout:"multiline",children:n.jsxs(te,{children:[n.jsxs(Ne,{children:["Published ",de(ts,"change"),he&&dn.includes(p?.logicalName??"")?` to ${he}`:""]}),"Unified Interface can take up to about 25 minutes to show it. To see it sooner, run ",n.jsx("strong",{children:"Regenerate ribbon metadata"})," in Command Checker, or hard-refresh the page (Ctrl+F5)."]})}),os.map(t=>n.jsx(se,{intent:t.result.ok?"success":"warning",layout:"multiline",children:n.jsxs(te,{children:[n.jsxs("strong",{children:[t.scope,":"]})," ",t.result.message]})},t.scope)),(h||W)&&n.jsxs("div",{className:e.progressList,children:[dn.map(t=>{const f=R[t]??"pending";return n.jsxs("div",{className:e.progressRow,children:[n.jsx(Ye,{appearance:"filled",color:$t[f],size:"medium",className:e.badge,children:St[f]}),n.jsx(D,{children:t}),f==="publishing"&&n.jsx(ot,{thickness:"large",style:{flex:1}})]},t)}),ln&&!W&&n.jsx(D,{className:e.timing,children:ln})]})]})})};export{Ot as BulkPublishModal,Ot as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{L as s,K as ce,ad as U,df as ue,dg as me,s as pe,A as be,ac as he,V as xe,a4 as ge}from"./fluent-icons-CQEhzzaC.js";import{a as I}from"./monaco-BIO15LCS.js";import{D as fe,c as je,S as we,v as ye,f as Ce,C as ve,g as Re}from"./dnd-C1w9VFfC.js";import{b as j,a as x,aj as Ne,aF as Se,u as ke,c as Ae,aG as De,aH as Te,am as Ie,aC as Ee,aI as Be}from"./index-6so8O90C.js";import{C as X}from"./CrmParameterEditor-C22QGWff.js";import{u as Me}from"./useStableKeys-BkDn7til.js";import{b as v,M as q,s as Q,h as b,v as Y,w as Z,x as E,af as J,as as $e,F as C,Y as K,I as _e,T as Fe,X as W,aq as G,a7 as We,L as Le,N as Oe,t as r}from"./fluent-ui-BEjALNLO.js";import"./crmParameters-rgfZhhzN.js";const ee=ce({body:{display:"flex",flexDirection:"column",gap:r.spacingVerticalM},actionCard:{border:`1px solid ${r.colorNeutralStroke2}`,borderRadius:r.borderRadiusMedium,backgroundColor:r.colorNeutralBackground1,padding:r.spacingVerticalM,display:"flex",flexDirection:"column",gap:r.spacingVerticalS},actionHeader:{display:"flex",alignItems:"center",gap:r.spacingHorizontalXS,minWidth:0},actionTitle:{flex:1,minWidth:0},dragHandle:{cursor:"grab",touchAction:"none"},row:{display:"flex",flexWrap:"wrap",gap:r.spacingHorizontalS,alignItems:"flex-end"},library:{display:"flex",gap:r.spacingHorizontalXS,alignItems:"center"},grow:{flex:1,minWidth:0},ruleTags:{flexWrap:"wrap"},muted:{color:r.colorNeutralForeground3},usesList:{listStyleType:"none",margin:0,padding:0,display:"flex",flexDirection:"column",gap:r.spacingVerticalXS},use:{border:`1px solid ${r.colorNeutralStroke2}`,borderRadius:r.borderRadiusMedium,padding:`${r.spacingVerticalXS} ${r.spacingHorizontalS}`,display:"flex",flexDirection:"column",minWidth:0},fields:{border:"none",margin:0,padding:0,minWidth:0,display:"flex",flexDirection:"column",gap:r.spacingVerticalS,"&:disabled .fui-Input, &:disabled .fui-Select__select, &:disabled .fui-Dropdown, &:disabled .fui-Combobox":{backgroundColor:r.colorNeutralBackground3,borderTopColor:r.colorTransparentStroke,borderRightColor:r.colorTransparentStroke,borderBottomColor:r.colorTransparentStroke,borderLeftColor:r.colorTransparentStroke,color:r.colorNeutralForeground1,cursor:"default"},"&:disabled .fui-Input::after, &:disabled .fui-Dropdown::after, &:disabled .fui-Combobox::after":{display:"none"},"&:disabled input, &:disabled .fui-Dropdown__button":{color:r.colorNeutralForeground1,cursor:"default"},"&:disabled .fui-Select__icon, &:disabled .fui-Dropdown__expandIcon, &:disabled .fui-Combobox__expandIcon":{display:"none"},"&:disabled .fui-Button":{color:r.colorNeutralForegroundDisabled,borderTopColor:r.colorNeutralStrokeDisabled,borderRightColor:r.colorNeutralStrokeDisabled,borderBottomColor:r.colorNeutralStrokeDisabled,borderLeftColor:r.colorNeutralStrokeDisabled,cursor:"not-allowed"}}}),Pe=[],Ve=n=>{const d=n.trim();return d.startsWith("$webresource:")?d.slice(13).trim():d};function ze(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 He({id:n,index:d,count:u,title:R,readOnly:g,onMove:N,onRemove:B,children:w}){const y=ee(),{attributes:M,listeners:A,setNodeRef:S,setActivatorNodeRef:D,transform:T,transition:$}=Ce({id:n,disabled:g});return s.jsxs("section",{ref:S,style:{transform:ve.Transform.toString(T),transition:$},className:y.actionCard,"aria-label":`Action ${d+1}: ${R}`,children:[s.jsxs("div",{className:y.actionHeader,children:[!g&&u>1&&s.jsx(b,{ref:D,appearance:"subtle",size:"small",className:y.dragHandle,icon:s.jsx(ue,{}),"aria-label":"Drag to reorder action",...M,...A}),s.jsx(v,{weight:"semibold",className:y.actionTitle,truncate:!0,wrap:!1,children:R}),!g&&u>1&&s.jsxs(q,{children:[s.jsx(Q,{disableButtonEnhancement:!0,children:s.jsx(b,{appearance:"subtle",size:"small",icon:s.jsx(me,{}),"aria-label":"More for this action"})}),s.jsx(Y,{children:s.jsxs(Z,{children:[s.jsx(E,{icon:s.jsx(pe,{}),disabled:d===0,onClick:()=>N(d,d-1),children:"Move up"}),s.jsx(E,{icon:s.jsx(be,{}),disabled:d===u-1,onClick:()=>N(d,d+1),children:"Move down"})]})})]}),!g&&s.jsx(Fe,{content:"Remove action",relationship:"label",children:s.jsx(b,{appearance:"subtle",size:"small",icon:s.jsx(he,{}),onClick:B})})]}),w]})}const Ze=()=>{const n=ee(),d=j(e=>e.commandEditorOpen),u=j(e=>e.commandEditorId),R=j(e=>e.closeCommandEditor),g=j(e=>e.openRuleEditor),N=j(e=>e.openScriptView),B=j(e=>e.openWebResourceBrowser),w=j(e=>e.commandEditorTab),y=x(e=>e.commands),M=x(e=>e.upsertCommand),A=x(e=>e.ribbons),S=x(e=>e.locLabels),D=x(e=>e.displayRules),T=x(e=>e.enableRules),$=x(e=>e.upsertEnableRule),se=x(e=>e.upsertDisplayRule),_=Ne(),[ae,L]=I.useState(""),[re,O]=I.useState(""),l=y.find(e=>e.id===u),m=Me(`actions:${l?.id??""}`,l?.actions??Pe),f=Se(ke(l?.id));I.useEffect(()=>{d&&u&&!l&&R()},[d,u,l,R]);const P=I.useMemo(()=>u?Ae(A,u):[],[A,u]);if(!l)return null;const k=e=>{M({...l,...e})},h=(e,a)=>{const t=[...l.actions];t[e]=a,k({actions:t}),m.update()},ne=e=>{k({actions:l.actions.filter((a,t)=>t!==e)}),m.remove(e)},V=(e,a)=>{a<0||a>=l.actions.length||e===a||(k({actions:Re(l.actions,e,a)}),m.move(e,a))},oe=e=>{e.over&&V(m.keys.indexOf(String(e.active.id)),m.keys.indexOf(String(e.over.id)))},z=e=>{const a=e==="javascript"?{kind:"javascript",library:"",functionName:"",params:[]}:{kind:"url",address:"https://",params:[]};k({actions:[...l.actions,a]}),m.add()},le=(e,a)=>{if(e.kind==="javascript"){const t=Ve(e.library);return s.jsxs(s.Fragment,{children:[s.jsxs("fieldset",{disabled:f,className:n.fields,children:[s.jsx(C,{label:"Library",hint:"A JavaScript web resource, like $webresource:publisher_/scripts/file.js.",children:s.jsxs("div",{className:n.library,children:[s.jsx(W,{className:n.grow,value:e.library,onChange:(o,c)=>h(a,{...e,library:c.value.replace(/^(\s*\$webresource:\s*)+/i,"$webresource:")}),placeholder:"$webresource:publisher_/scripts/file.js"}),s.jsx(b,{onClick:()=>{Ee.set(o=>{h(a,{...e,library:`$webresource:${o.name}`})}),B()},children:"Browse…"})]})}),s.jsx(C,{label:"Function",hint:"The function's full name, including its namespace.",children:s.jsx(W,{value:e.functionName,onChange:(o,c)=>h(a,{...e,functionName:c.value}),placeholder:"Contoso.Account.approve"})}),s.jsx(G,{weight:"semibold",children:"Parameters, in order"}),s.jsx(X,{params:e.params,onChange:o=>h(a,{...e,params:o}),urlMode:!1})]}),s.jsxs("div",{className:n.row,children:[s.jsx(b,{size:"small",icon:s.jsx(xe,{}),disabled:!t,onClick:()=>N(t,!1),children:"View script"}),!f&&s.jsx(b,{size:"small",icon:s.jsx(ge,{}),disabled:!t,onClick:()=>N(t,!0),children:"Edit script"})]})]})}if(e.kind==="url"){const t=e.address.trim().startsWith("https://");return s.jsxs("fieldset",{disabled:f,className:n.fields,children:[s.jsx(C,{label:"Address",validationState:t?"none":"error",validationMessage:t?void 0:"The address must start with https://",children:s.jsx(W,{value:e.address,onChange:(o,c)=>h(a,{...e,address:c.value}),placeholder:"https://"})}),s.jsx(C,{label:"Open in",children:s.jsxs(K,{value:String(e.winMode??0),onChange:(o,c)=>h(a,{...e,winMode:parseInt(c.value)}),children:[s.jsx("option",{value:"0",children:"Navigate (0)"}),s.jsx("option",{value:"1",children:"Dialog (1)"}),s.jsx("option",{value:"2",children:"Popup (2)"})]})}),s.jsx(C,{hint:"Adds the record's details to the address: typename, type, id, orgname and the user's languages.",children:s.jsx(We,{label:"Pass parameters",checked:!!e.passParams,onChange:(o,c)=>h(a,{...e,passParams:c.checked?!0:void 0})})}),s.jsx(G,{weight:"semibold",children:"Query string parameters"}),s.jsx(X,{params:e.params,onChange:o=>h(a,{...e,params:o}),urlMode:!0})]})}return e.kind==="powerFx"||e.kind==="customApi"?s.jsx(Le,{intent:"error",children:s.jsxs(Oe,{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(v,{size:200,className:n.muted,children:e.kind==="outlookCommand"?`ActionType="${e.actionType}"${e.data?` Data="${e.data}"`:""}`:e.xml}):null},te=()=>s.jsxs(s.Fragment,{children:[s.jsx(fe,{collisionDetection:je,onDragEnd:oe,children:s.jsx(we,{items:m.keys,strategy:ye,children:l.actions.map((e,a)=>s.jsx(He,{id:m.keys[a],index:a,count:l.actions.length,title:ze(e),readOnly:f,onMove:V,onRemove:()=>ne(a),children:le(e,a)},m.keys[a]))})}),l.actions.length===0&&s.jsx(v,{className:n.muted,children:"No actions yet. The button does nothing when it's clicked."}),!f&&s.jsx("div",{children:s.jsxs(q,{children:[s.jsx(Q,{disableButtonEnhancement:!0,children:s.jsx(b,{icon:s.jsx(U,{}),children:"Add action"})}),s.jsx(Y,{children:s.jsxs(Z,{children:[s.jsx(E,{onClick:()=>z("javascript"),children:"Run JavaScript"}),s.jsx(E,{onClick:()=>z("url"),children:"Open a URL"})]})})]})}),s.jsx(J,{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."})]}),H=e=>{const a=e==="enable"?l.enableRules:l.displayRules,t=(e==="enable"?T:D).map(i=>i.id).filter(i=>!a.includes(i)),o=e==="enable"?ae:re,c=i=>k(e==="enable"?{enableRules:i}:{displayRules:i}),de=()=>{const i=new Set([...T.map(F=>F.id),...D.map(F=>F.id)]),p=Be("New",e==="enable"?"Enable":"Display",i);e==="enable"?$({id:p,steps:[]}):se({id:p,steps:[]}),c([...a,p]),g(p,e)};return s.jsxs(s.Fragment,{children:[a.length>0?s.jsx($e,{className:n.ruleTags,"aria-label":e==="enable"?"Enable rules":"Display rules",children:a.map(i=>s.jsx(Te,{ruleId:i,kind:e,onOpen:()=>g(i,e),onRemove:f?void 0:()=>c(a.filter(p=>p!==i))},i))}):s.jsxs(v,{className:n.muted,children:["No ",e," rules, so the button is always"," ",e==="enable"?"enabled":"shown","."]}),!f&&s.jsxs("div",{className:n.row,children:[s.jsx(C,{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:o,onChange:(i,p)=>e==="enable"?L(p.value):O(p.value),children:[s.jsx("option",{value:"",children:"Select a rule…"}),t.map(i=>s.jsx("option",{value:i,children:i},i))]})}),s.jsx(b,{disabled:!o,onClick:()=>{o&&(c([...a,o]),e==="enable"?L(""):O(""))},children:"Add"}),s.jsxs(b,{appearance:"subtle",icon:s.jsx(U,{}),onClick:de,children:["New ",e," rule"]})]}),e==="enable"&&s.jsx(_e,{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"})]})},ie=()=>P.length===0?s.jsx(v,{className:n.muted,children:"No button uses this command."}):s.jsx("ul",{className:n.usesList,"aria-label":"Buttons using this command",children:P.map(({location:e,tab:a,group:t,button:o})=>s.jsxs("li",{className:n.use,children:[s.jsx(v,{weight:"semibold",truncate:!0,wrap:!1,children:_(o.label,S,void 0,o.source?.labelToken)||o.id}),s.jsx(J,{className:n.muted,children:[Ie[e].label,_(a.label,S)||a.id,_(t.label,S)||t.id].join(" › ")})]},`${e}:${a.id}:${t.id}:${o.id}`))});return s.jsxs("div",{className:n.body,children:[s.jsx(De,{commandId:l.id,hideBadge:!0}),w==="actions"&&te(),w==="enable"&&H("enable"),w==="display"&&H("display"),w==="usedBy"&&ie()]})};export{Ze as CommandEditorPanel,Ze as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{L as s,m as ie,K as re}from"./fluent-icons-CQEhzzaC.js";import{a as k}from"./monaco-BIO15LCS.js";import{b as c,a as d,aj as ce,R as de,ak as ue,a6 as S,al as pe,ae as me,s as he,am as be}from"./index-6so8O90C.js";import{D as fe,d as ge,a8 as xe,af as m,B as ke,b as ne,t as n}from"./fluent-ui-BEjALNLO.js";import"./dnd-C1w9VFfC.js";const we=re({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}}),ye={action:"Action",button:"Button",command:"Command",enable:"Enable rule",display:"Display rule",table:"Table"},ve=[{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:"Tables",limit:30}],D=a=>`palette-${a.replace(/[^\w-]/g,"_")}`,Ie=()=>{const a=we(),C=c(e=>e.commandPaletteOpen),se=c(e=>e.setCommandPaletteOpen),R=c(e=>e.openBulkPublish),T=c(e=>e.openXmlDrawer),w=c(e=>e.openImportXml),E=c(e=>e.openCommandEditor),X=c(e=>e.openRuleEditor),O=c(e=>e.openNewGroup),A=c(e=>e.openNewButton),V=c(e=>e.openLocalizationEditor),W=d(e=>e.undo),z=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),U=d(e=>e.enableRules),j=d(e=>e.ribbons),N=d(e=>e.locLabels),$=ce(),_=de(e=>e.entities),q=ue(e=>e.requestEntitySwitch),I=S(e=>e.location),K=S(e=>e.tabId),Y=S(e=>e.selectedButtonId),L=S(e=>e.selectedGroupId),Q=S(e=>e.selectButtonInContext),[x,Z]=k.useState(""),[ae,h]=k.useState(0),J=k.useRef(null),ee=()=>{se(!1),Z(""),h(0)},y=x.startsWith("/")?"actions":x.startsWith("@")?"tables":"all",M=(y==="all"?x:x.slice(1)).trim().toLowerCase(),te=k.useMemo(()=>{if(!C)return[];const e=[],t=j[I].tabs.find(o=>o.id===K),i=L??t?.groups[0]?.id??null,u=pe(t?.groups.find(o=>o.id===L),Y),p=(o,r,l,f)=>e.push({id:`act-${o}`,label:r,subtitle:l,kind:"action",run:f});p("publish","Publish…","Review and publish your changes",R),p("view-xml","View XML","The XML of your changes",()=>T(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 w("",o);r.then(l=>l.trim().startsWith("<")?w(l):w("","The clipboard doesn't hold XML: paste the XML into the editor."),()=>w("",o))}),t&&p("new-group","New group…","In the current tab",O),i&&p("new-button","New button…","In the selected or first group",()=>A(i)),u&&!me(u.kind)&&(u.origin===void 0||u.origin==="unmanaged")&&p("translations","Translations…","The selected button's text",()=>V(u.id)),H&&p("undo","Undo","Ctrl+Z",W),P&&p("redo","Redo","Ctrl+Y",z);for(const[o,r]of Object.entries(j))for(const l of r.tabs)for(const f of l.groups)for(const g of he(f))e.push({id:`btn-${o}-${g.id}`,label:$(g.label,N,void 0,g.source?.labelToken)||g.id,subtitle:[be[o].label,$(l.label,N,void 0,l.source?.titleToken)||l.id,$(f.label,N,void 0,f.source?.titleToken)||f.id].join(" › "),keywords:`${g.label} ${g.id}`,kind:"button",run:()=>Q(o,l.id,f.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:()=>E(o.id)});for(const[o,r]of[[U,"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 _)e.push({id:`ent-${o.logicalName}`,label:o.displayName,subtitle:o.logicalName,kind:"table",run:()=>q(o)});return e},[C,j,I,K,L,Y,H,P,F,U,G,_,N,$,R,T,w,O,A,V,E,X,W,z,Q,q]),B=k.useMemo(()=>{const e=t=>!M||[t.label,t.subtitle??"",t.keywords??""].some(i=>i.toLowerCase().includes(M));return ve.filter(t=>y==="all"||y==="actions"&&t.kinds.includes("action")||y==="tables"&&t.kinds.includes("table")).map(t=>{const i=te.filter(u=>t.kinds.includes(u.kind)&&e(u));return{...t,shown:i.slice(0,t.limit),more:Math.max(0,i.length-t.limit)}}).filter(t=>t.shown.length>0)},[te,M,y]),v=B.flatMap(e=>e.shown),b=v[Math.min(ae,v.length-1)];k.useEffect(()=>{b&&J.current?.querySelector(`#${D(b.id)}`)?.scrollIntoView?.({block:"nearest"})},[b]);const oe=e=>{e&&(ee(),e.run())},le=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(b))};return s.jsx(fe,{open:C,onOpenChange:(e,t)=>!t.open&&ee(),children:s.jsxs(ge,{className:a.surface,"aria-label":"Command palette",children:[s.jsx("div",{className:a.search,children:s.jsx(xe,{className:a.searchBox,size:"large",autoFocus:!0,placeholder:"Search buttons, commands, rules and tables",value:x,onChange:(e,t)=>{Z(t.value),h(0)},input:{role:"combobox","aria-label":"Search","aria-expanded":!0,"aria-controls":"palette-results","aria-activedescendant":b?D(b.id):void 0,"aria-autocomplete":"list",onKeyDown:le}})}),s.jsxs("div",{ref:J,id:"palette-results",role:"listbox","aria-label":"Results",className:a.results,children:[B.map(e=>s.jsxs("div",{role:"group","aria-label":e.title,children:[s.jsx(m,{className:a.groupLabel,role:"presentation",children:e.title}),e.shown.map(t=>{const i=t===b;return s.jsxs("div",{id:D(t.id),role:"option","aria-selected":i,className:ie(a.item,i&&a.itemActive),onClick:()=>oe(t),onMouseMove:()=>h(v.indexOf(t)),children:[s.jsx(ke,{className:a.kind,appearance:"tint",size:"medium",color:t.kind==="action"?"brand":"informative",children:ye[t.kind]}),s.jsxs("span",{className:a.itemText,children:[s.jsx(ne,{className:a.itemLabel,children:t.label}),t.subtitle&&s.jsx(m,{className:a.itemSub,children:t.subtitle})]})]},t.id)}),e.more>0&&s.jsxs(m,{className:a.more,role:"presentation",children:[e.more," more: keep typing to narrow it down."]})]},e.title)),B.length===0&&s.jsxs(ne,{className:a.empty,role:"presentation",children:["Nothing matches “",x,"”."]})]}),s.jsxs("div",{className:a.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:"@ tables only"})]})]})})};export{Ie as CommandPalette,Ie as default};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./monaco-BIO15LCS.js","./monaco-DdLsZAcA.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{R as h,a as S,_}from"./monaco-BIO15LCS.js";import{L as e,d9 as z,K as $}from"./fluent-icons-CQEhzzaC.js";import{b as A,a as E,aN as C,g as F,aO as P}from"./index-6so8O90C.js";import{b as y,t as l,h as X,af as H,B as D,ah as V,ai as k,ag as I}from"./fluent-ui-BEjALNLO.js";import"./dnd-C1w9VFfC.js";const U=h.lazy(()=>_(()=>import("./monaco-BIO15LCS.js").then(t=>t.i),__vite__mapDeps([0,1]),import.meta.url).then(t=>({default:t.DiffEditor}))),W=["HomepageGrid","SubGrid","Form","Application"],G=$({root:{flex:1,display:"flex",flexDirection:"column",gap:l.spacingVerticalS,minHeight:"320px"},unchanged:{flex:1,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:l.spacingVerticalM,textAlign:"center",color:l.colorNeutralForeground3},bar:{display:"flex",alignItems:"center",flexWrap:"wrap",gap:l.spacingHorizontalS},spacer:{flex:1},muted:{color:l.colorNeutralForeground3},editor:{flex:1,minHeight:"240px",border:`1px solid ${l.colorNeutralStroke2}`,borderRadius:l.borderRadiusMedium,overflow:"hidden",position:"relative"},loading:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%"}});function q(t,n){const d=t.split(`
|
|
3
|
+
`),s=n.split(`
|
|
4
|
+
`);let a=0,c=0;const b=new Set(d),x=new Set(s);for(const m of s)b.has(m)||a++;for(const m of d)x.has(m)||c++;return{added:a,removed:c}}function j(t,n,d=!1){return W.map(s=>{const a=d?n[s]:t.ribbons[s];try{return`<!-- ${s} -->
|
|
5
|
+
`+F({location:s,current:a,baseline:n[s],commands:t.commands,displayRules:t.displayRules,enableRules:t.enableRules,locLabels:t.locLabels,entityLogicalName:a.entityLogicalName})}catch(c){return`<!-- ${s}: Error generating XML: ${String(c)} -->`}}).join(`
|
|
6
|
+
|
|
7
|
+
`)}const ee=({historyIndex:t})=>{const n=G(),d=A(i=>i.themeMode),s=t!==void 0,[a,c]=h.useState(!0),[b,x]=h.useState(!1),m=E(i=>!s&&i.mutationsSincePublish===0&&!P(i)),r=E(),o=s?r.past[t]:void 0,v=S.useMemo(()=>s?o?j(o.snapshot,r.baseline):"":j(r,r.baseline,!0),[s,o]),u=s?r.past[t+1]?.snapshot??C(r):C(r),L=S.useMemo(()=>s&&!o?"":j(u,r.baseline),[s,o,u.ribbons,u.commands,u.displayRules,u.enableRules,u.locLabels,r.baseline]),{added:N,removed:R}=q(v,L),M=h.useRef(null),B=h.useCallback(i=>{M.current=i,i.updateOptions({renderSideBySide:a});const p=[i.getOriginalEditor(),i.getModifiedEditor()];let g=0;const O=()=>{g||(g=requestAnimationFrame(()=>{g=0;for(const f of p)f.render(!0)}))},T=p.flatMap(f=>{const w=f.onDidChangeModelTokens;return w?[w.call(f,O)]:[]});i.onDidDispose(()=>{cancelAnimationFrame(g);for(const f of T)f.dispose()})},[]);return h.useEffect(()=>{M.current?.updateOptions({renderSideBySide:a})},[a]),s&&!o?e.jsx("div",{className:n.unchanged,children:e.jsx(y,{children:"This change was undone, so there's nothing to show."})}):!s&&!b&&m?e.jsxs("div",{className:n.unchanged,children:[e.jsx(z,{fontSize:40,color:l.colorPaletteGreenForeground1,"aria-hidden":"true"}),e.jsx(y,{size:500,weight:"semibold",children:"No changes since the last publish"}),e.jsx(y,{children:"What you see matches what's published for this table."}),e.jsx(X,{onClick:()=>x(!0),children:"Show the full XML anyway"})]}):e.jsxs("div",{className:n.root,children:[e.jsx(H,{className:n.muted,children:s?`${[o.op,o.target].filter(Boolean).join(" ")}${o.detail?` (${o.detail})`:""}: the XML before it (left) and after it (right).`:"The published XML (left) and the XML with your changes (right)."}),e.jsxs("div",{className:n.bar,children:[e.jsxs(D,{appearance:"tint",color:N?"success":"informative",children:["+",N," lines"]}),e.jsxs(D,{appearance:"tint",color:R?"danger":"informative",children:["-",R," lines"]}),e.jsx("div",{className:n.spacer}),e.jsxs(V,{size:"small",selectedValue:a?"side":"unified",onTabSelect:(i,p)=>c(p.value==="side"),"aria-label":"Diff layout",children:[e.jsx(k,{value:"side",children:"Side by side"}),e.jsx(k,{value:"unified",children:"Unified"})]})]}),e.jsx("div",{className:n.editor,children:e.jsx(S.Suspense,{fallback:e.jsx("div",{className:n.loading,children:e.jsx(I,{size:"small",label:"Loading the diff…"})}),children:e.jsx(U,{original:v,modified:L,language:"xml",theme:d==="dark"?"vs-dark":"vs",height:"100%",onMount:B,options:{readOnly:!0,renderSideBySide:a,lineNumbers:"on",minimap:{enabled:!1},scrollBeyondLastLine:!1,automaticLayout:!0,wordWrap:"on"}})})})]})};export{ee as CompareView,ee as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{L as e,s as g,A as b,i as j,ad as y,K as I}from"./fluent-icons-CQEhzzaC.js";import{R as P}from"./monaco-BIO15LCS.js";import{U as k}from"./crmParameters-rgfZhhzN.js";import{F as v,Y as f,X as S,a7 as R,T as p,h,t as u}from"./fluent-ui-BEjALNLO.js";const N=I({root:{display:"flex",flexDirection:"column",gap:u.spacingVerticalXS,minWidth:0},param:{display:"flex",flexWrap:"wrap",minWidth:0,gap:u.spacingHorizontalS,alignItems:"flex-end",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},addButton:{alignSelf:"flex-start"}}),A=[{label:"Context",values:["PrimaryControl","PrimaryControlId","SelectedControl","CommandProperties"]},{label:"Record",values:["PrimaryEntityTypeCode","PrimaryEntityTypeName","FirstPrimaryItemId","PrimaryItemIds"]},{label:"Selection context",values:["SelectedEntityTypeCode","SelectedEntityTypeName","FirstSelectedItemId"]},{label:"Grid selection",values:["SelectedControlSelectedItemCount","SelectedControlSelectedItemIds","SelectedControlSelectedItemReferences","SelectedControlAllItemCount","SelectedControlAllItemIds","SelectedControlAllItemReferences","SelectedControlUnselectedItemCount","SelectedControlUnselectedItemIds","SelectedControlUnselectedItemReferences"]},{label:"Org/User",values:["OrgName","OrgLcid","UserLcid"]}];function F({value:r,integer:c,onChange:x}){const[i,s]=P.useState(String(r));return P.useEffect(()=>s(Number.isFinite(r)?String(r):""),[r]),e.jsx(S,{type:"number",value:i,onChange:(C,d)=>{s(d.value);const m=Number(d.value);d.value.trim()!==""&&Number.isFinite(m)&&(!c||Number.isInteger(m))&&!/e/i.test(String(m))&&x(m)},onBlur:()=>s(Number.isFinite(r)?String(r):"")})}const z=({params:r,onChange:c,urlMode:x=!1})=>{const i=N(),s=(l,t)=>{const a=[...r];a[l]=t,c(a)},C=l=>{c(r.filter((t,a)=>a!==l))},d=(l,t)=>{const a=[...r],n=l+t;n<0||n>=a.length||([a[l],a[n]]=[a[n],a[l]],c(a))},m=()=>{c([...r,{kind:"CrmParameter",value:"PrimaryControl"}])};return e.jsxs("div",{className:i.root,children:[r.map((l,t)=>e.jsxs("div",{className:i.param,children:[e.jsx(v,{label:"Type",size:"small",className:i.typeSelect,children:e.jsxs(f,{value:l.kind,onChange:(a,n)=>{const o=n.value;o==="CrmParameter"?s(t,{kind:o,value:"PrimaryControl"}):o==="BoolParameter"?s(t,{kind:o,value:!1}):o==="IntParameter"||o==="DecimalParameter"?s(t,{kind:o,value:0}):s(t,{kind:"StringParameter",value:""})},children:[e.jsx("option",{value:"CrmParameter",children:"From the context"}),e.jsx("option",{value:"StringParameter",children:"Text"}),e.jsx("option",{value:"BoolParameter",children:"True or false"}),e.jsx("option",{value:"IntParameter",children:"Whole number"}),e.jsx("option",{value:"DecimalParameter",children:"Decimal number"})]})}),x&&e.jsx(v,{label:"Name",size:"small",className:i.nameField,validationState:l.kind==="CrmParameter"&&!l.name?"error":"none",validationMessage:l.kind==="CrmParameter"&&!l.name?"Needs a name: it's the query string key.":void 0,children:e.jsx(S,{value:l.name??"",onChange:(a,n)=>s(t,{...l,name:n.value||void 0}),placeholder:"key"})}),e.jsx(v,{label:"Value",size:"small",className:i.valueField,children:l.kind==="CrmParameter"?e.jsx(f,{value:l.value,onChange:(a,n)=>s(t,{...l,value:n.value}),children:A.map(a=>e.jsx("optgroup",{label:a.label,children:a.values.filter(n=>!x||!k.has(n)).map(n=>e.jsx("option",{value:n,children:n},n))},a.label))}):l.kind==="BoolParameter"?e.jsx(R,{checked:l.value,onChange:(a,n)=>s(t,{...l,value:n.checked}),label:l.value?"True":"False"}):l.kind==="StringParameter"?e.jsx(S,{value:String(l.value),onChange:(a,n)=>s(t,{...l,value:n.value})}):e.jsx(F,{value:l.value,integer:l.kind==="IntParameter",onChange:a=>s(t,{...l,value:a})})}),e.jsxs("div",{className:i.actions,children:[e.jsx(p,{content:`Move parameter ${t+1} up`,relationship:"label",children:e.jsx(h,{appearance:"subtle",size:"small",icon:e.jsx(g,{}),onClick:()=>d(t,-1),disabled:t===0})}),e.jsx(p,{content:`Move parameter ${t+1} down`,relationship:"label",children:e.jsx(h,{appearance:"subtle",size:"small",icon:e.jsx(b,{}),onClick:()=>d(t,1),disabled:t===r.length-1})}),e.jsx(p,{content:`Remove parameter ${t+1}`,relationship:"label",children:e.jsx(h,{appearance:"subtle",size:"small",icon:e.jsx(j,{}),onClick:()=>C(t)})})]})]},t)),e.jsx(h,{className:i.addButton,appearance:"secondary",size:"small",icon:e.jsx(y,{}),onClick:m,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-DsCP9yG4.js","./fluent-icons-CQEhzzaC.js","./monaco-BIO15LCS.js","./monaco-DdLsZAcA.css","./dnd-C1w9VFfC.js","./fluent-ui-BEjALNLO.js","./index-6so8O90C.js","./index-D5GCH8nj.css","./CrmParameterEditor-C22QGWff.js","./crmParameters-rgfZhhzN.js","./useStableKeys-BkDn7til.js","./RuleEditorPanel-l8QnRFj6.js","./ruleKinds-BKTUiZ1-.js","./ScriptView-BVyCmRvD.js","./MonacoEditor-BMKRZv-g.js","./TabDisplayRulesPanel-gORq6MO7.js","./XmlView-Bn4KlTw3.js","./CompareView-DGsrcdoN.js","./TranslationsView-DubBATog.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{a as u,_ as y}from"./monaco-BIO15LCS.js";import{L as e,K as E,a4 as w,cm as N,i as V,m as S}from"./fluent-icons-CQEhzzaC.js";import{u as L,a as x,b as g,I as D,c as z,i as B}from"./index-6so8O90C.js";import{F as P,X as A,h as j,t as l,T as C,B as F,ah as H,ai as R,af as v,U as W,aY as O,aZ as X,n as $,p as I,a_ as U,a$ as M,ag as K,b0 as Y}from"./fluent-ui-BEjALNLO.js";import"./dnd-C1w9VFfC.js";const Z=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(s,i,m,p){if(!s.trim())return"Enter an ID.";if(/\s/.test(s))return"An ID can't contain spaces.";if(s!==i&&m.some(c=>c.toLowerCase()===s.toLowerCase()))return`Another ${p} already has this ID.`}function T({label:s,current:i,ids:m,what:p,hint:c,onRename:f,onDone:h}){const r=Z(),[a,b]=u.useState(i),o=q(a,i,m,p),n=()=>{const d=a.trim();!o&&d!==i&&f(d),h()};return e.jsxs("div",{className:r.rename,children:[e.jsx(P,{className:r.field,label:s,validationState:o?"error":"none",validationMessage:o,hint:o?void 0:c,children:e.jsx(A,{className:r.input,value:a,autoFocus:!0,onChange:(d,t)=>b(t.value),onKeyDown:d=>{d.key==="Enter"&&n(),d.key==="Escape"&&(d.stopPropagation(),h())}})}),e.jsxs("div",{className:r.buttons,children:[e.jsx(j,{appearance:"primary",disabled:!!o||a.trim()===i,onClick:n,children:"Rename"}),e.jsx(j,{onClick:h,children:"Cancel"})]})]})}const G=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:s}){const i=G(),m=L(s)?.provenance,p=x(t=>t.commands.find(_=>_.id===s)),c=x(t=>z(t.ribbons,s).length),f=g(t=>t.commandEditorTab),h=g(t=>t.setCommandEditorTab),r=x(t=>t.commands).map(t=>t.id),a=x(t=>t.renameCommandId),b=g(t=>t.openCommandEditor),[o,n]=u.useState(!1),d=m&&J[m];return e.jsxs(e.Fragment,{children:[o?e.jsx(T,{label:"Command ID",current:s,ids:r,what:"command",hint:"Usually publisher.Table.Button.Command. Its buttons follow the new ID.",onRename:t=>a(s,t)&&b(t),onDone:()=>n(!1)}):e.jsxs("div",{className:i.idRow,children:[e.jsx("div",{className:i.id,children:e.jsx(D,{label:"Command ID",value:s,hideLabel:!0,action:m==="custom"&&e.jsx(C,{content:"Rename command ID",relationship:"label",children:e.jsx(j,{appearance:"subtle",icon:e.jsx(w,{}),onClick:()=>n(!0)})})})}),d&&e.jsx(F,{appearance:"tint",color:d.color,size:"medium",className:i.badge,children:d.text})]}),e.jsxs(H,{className:i.tabs,selectedValue:f,onTabSelect:(t,_)=>h(_.value),children:[e.jsx(R,{value:"actions",children:"Actions"}),e.jsxs(R,{value:"enable",children:["Enable rules (",p?.enableRules.length??0,")"]}),e.jsxs(R,{value:"display",children:["Display rules (",p?.displayRules.length??0,")"]}),e.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:s,kind:i}){const m=ee(),p=x(n=>i==="enable"?n.enableRules:n.displayRules),c=x(n=>n.commands.filter(d=>(i==="enable"?d.enableRules:d.displayRules).includes(s)).length),f=x(n=>n.renameEnableRuleId),h=x(n=>n.renameDisplayRuleId),r=g(n=>n.openRuleEditor),[a,b]=u.useState(!1),o=n=>{(i==="enable"?f(s,n):h(s,n))&&r(n,i)};return e.jsxs(e.Fragment,{children:[a?e.jsx(T,{label:"Rule ID",current:s,ids:p.map(n=>n.id),what:"rule",hint:"The commands that use it follow the new ID.",onRename:o,onDone:()=>b(!1)}):e.jsx("div",{className:m.idRow,children:e.jsx("div",{className:m.id,children:e.jsx(D,{label:"Rule ID",value:s,hideLabel:!0,action:!B(s)&&e.jsx(C,{content:"Rename rule ID",relationship:"label",children:e.jsx(j,{appearance:"subtle",icon:e.jsx(w,{}),onClick:()=>b(!0)})})})})}),e.jsxs(v,{className:m.usedBy,children:["Used by ",c," command",c===1?"":"s"]})]})}const se=u.lazy(()=>y(()=>import("./CommandEditorPanel-DsCP9yG4.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10]),import.meta.url)),ne=u.lazy(()=>y(()=>import("./RuleEditorPanel-l8QnRFj6.js"),__vite__mapDeps([11,1,2,3,6,5,4,7,12,8,9,10]),import.meta.url)),ie=u.lazy(()=>y(()=>import("./ScriptView-BVyCmRvD.js"),__vite__mapDeps([13,1,2,3,6,5,4,7,14]),import.meta.url)),te=u.lazy(()=>y(()=>import("./TabDisplayRulesPanel-gORq6MO7.js"),__vite__mapDeps([15,1,2,3,6,5,4,7,10]),import.meta.url)),oe=u.lazy(()=>y(()=>import("./XmlView-Bn4KlTw3.js"),__vite__mapDeps([16,1,2,3,6,5,4,7,14]),import.meta.url)),le=u.lazy(()=>y(()=>import("./CompareView-DGsrcdoN.js"),__vite__mapDeps([17,2,3,1,6,5,4,7]),import.meta.url)),re=u.lazy(()=>y(()=>import("./TranslationsView-DubBATog.js"),__vite__mapDeps([18,1,2,3,6,5,4,7]),import.meta.url)),de=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(s){return s.kind==="command"?"Edit command":s.kind==="rule"?`Edit ${s.ruleKind} rule`:s.kind==="tabRules"?"Tab display rules":s.kind==="xml"?"XML of your changes":s.kind==="translations"?"Translations":s.kind==="diff"?s.id==="compare"?"Compare with published":"What this change did":s.editable?"Edit script":"View script"}function he(){const s=de(),i=g(o=>o.editorStack),m=g(o=>o.editorBack),p=g(o=>o.closeEditor),c=i.length>0,[f,h]=u.useState(i);c&&i!==f&&h(i);const r=c?i:f,a=r[r.length-1],b=r[r.length-2];return u.useEffect(()=>c?(x.getState().beginEditSession(),()=>x.getState().endEditSession()):void 0,[c]),e.jsxs(W,{position:"end",open:c,onOpenChange:(o,n)=>!n.open&&p(),className:S(s.drawer,(a?.kind==="xml"||a?.kind==="diff")&&s.wide),"aria-label":a?k(a):"Editor",children:[e.jsxs(O,{children:[e.jsx(X,{children:e.jsxs($,{className:s.navigation,children:[b?e.jsx(I,{appearance:"subtle",icon:e.jsx(N,{}),onClick:m,children:k(b)}):e.jsx("span",{}),e.jsx(I,{appearance:"subtle",icon:e.jsx(V,{}),"aria-label":"Close",onClick:p})]})}),a&&e.jsx(U,{children:e.jsxs("span",{className:s.title,children:[r.length>2&&e.jsxs(v,{className:s.trail,children:[r.slice(0,-1).map(k).join(" › ")," ›"]}),k(a)]})}),a?.kind==="command"&&e.jsx(Q,{commandId:a.id},a.id),a?.kind==="rule"&&e.jsx(ae,{ruleId:a.id,kind:a.ruleKind},a.id),(a?.kind==="script"||a?.kind==="tabRules"||a?.kind==="translations")&&e.jsx("div",{className:s.idRow,children:e.jsx("div",{className:s.id,children:e.jsx(D,{label:a.kind==="tabRules"?"Tab ID":a.kind==="translations"?"Button ID":"Web resource",value:a.id,hideLabel:!0})})})]}),e.jsx(M,{className:S((a?.kind==="script"||a?.kind==="xml"||a?.kind==="diff")&&s.fill),children:e.jsxs(u.Suspense,{fallback:e.jsx(K,{size:"small",label:"Loading…"}),children:[a?.kind==="command"&&e.jsx(se,{}),a?.kind==="rule"&&e.jsx(ne,{}),a?.kind==="tabRules"&&e.jsx(te,{location:a.location,tabId:a.id}),a?.kind==="script"&&e.jsx(ie,{name:a.id,editable:a.editable},a.id),a?.kind==="xml"&&e.jsx(oe,{location:a.id},a.id),a?.kind==="translations"&&e.jsx(re,{buttonId:a.id},a.id),a?.kind==="diff"&&e.jsx(le,{historyIndex:a.historyIndex},`${a.id}:${a.historyIndex??""}`)]})}),e.jsxs(Y,{className:s.footer,children:[e.jsx(v,{className:s.hint,children:a?.kind==="script"?a.editable?"Save writes the script to Dataverse · Undo doesn't revert it":"":a?.kind==="xml"||a?.kind==="diff"?"":"Changes apply as you edit · Ctrl Z to undo"}),e.jsx(j,{appearance:"primary",onClick:p,children:"Done"})]})]})}export{he as EditorDrawer,he as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{L as c}from"./fluent-icons-CQEhzzaC.js";import{b as i,a as n,aj as b,aD as m,aE as p,al as f}from"./index-6so8O90C.js";import"./monaco-BIO15LCS.js";import"./fluent-ui-BEjALNLO.js";import"./dnd-C1w9VFfC.js";const R=()=>{const o=i(e=>e.hideInsteadOfDelete),a=i(e=>e.closeHideInsteadOfDelete),s=i(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),s("Button hidden"),a()},onConfirmDisplayRule:()=>{n.getState().hideWithDisplayRules(t.commandId)&&s("Button hidden"),a()},onCancel:a})};export{R as HideInsteadOfDeleteModal,R as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{L as o,m as V,N as Ie,K as $e}from"./fluent-icons-CQEhzzaC.js";import{u as Ne}from"./useReplaceWebResourceConfirm-DND-V0vw.js";import{b as se,a as Te,a6 as N,R as ne,an as te,Y as We,ao as ie,ap as U,aq as Be,ar as le,as as Le,G as M,at as Ee,au as Fe,av as Pe,aw as Ge,ax as De,F as z}from"./index-6so8O90C.js";import{a as t,R as ce}from"./monaco-BIO15LCS.js";import{Z as de,ah as Ve,ai as H,L as ue,N as ge,a8 as pe,b1 as Ue,c as Me,b3 as he,T as ze,h as C,b as O,af as _,ag as He,F as Oe,X as _e,t as a}from"./fluent-ui-BEjALNLO.js";import"./dnd-C1w9VFfC.js";function Xe({text:s}){return o.jsx(o.Fragment,{children:s.split(/(?=[A-Z])/).map((h,c)=>o.jsxs(t.Fragment,{children:[c>0&&o.jsx("wbr",{}),h]},c))})}const Ze=[{category:"Actions",keywords:["Add","Delete","Edit","Save","Copy","Paste","Undo","Redo","Send","Print","Refresh"]},{category:"Communication",keywords:["Mail","Chat","Phone","Call","Message"]},{category:"Navigation",keywords:["Arrow","Chevron","Navigation","Home","Back","Forward"]},{category:"System",keywords:["Settings","Info","Warning","Dismiss","Question","Checkmark","Error"]},{category:"Security",keywords:["Lock","Shield","Key","Fingerprint"]},{category:"People",keywords:["Person","People","Contact","User"]},{category:"Business",keywords:["Building","Briefcase","Money","Credit","Cart","Tag","Receipt"]},{category:"Files",keywords:["Document","Folder","Attach","Upload","Download","File"]},{category:"Web",keywords:["Globe","Link","Open","Browser","World"]},{category:"Time",keywords:["Calendar","Clock","Timer","History"]},{category:"Rating",keywords:["Star","Heart","Thumb"]},{category:"View",keywords:["Eye","Zoom","View","Window","Preview"]},{category:"Layout",keywords:["Grid","List","Table","Panel","Column","Row"]},{category:"Development",keywords:["Code","Bug","Branch","Wrench","Tool","Terminal"]},{category:"Media",keywords:["Play","Pause","Stop","Video","Audio","Camera"]},{category:"Analytics",keywords:["Chart","Data","Poll","Graph","Trend"]}],qe=["Add","Delete","Edit","Save","Copy","Cut","ClipboardPaste","Share","Mail","Chat","Phone","Search","Filter","ArrowLeft","ArrowRight","ArrowUp","ArrowDown","ChevronDown","ChevronUp","Navigation","Home","Settings","Info","Warning","Checkmark","Dismiss","QuestionCircle","LockClosed","LockOpen","Shield","Person","People","PersonAdd","Building","Briefcase","Money","CreditCard","Cart","Tag","Document","DocumentBulletList","Folder","FolderOpen","Attach","ArrowDownload","ArrowUpload","Globe","Link","Open","Calendar","Clock","Timer","Star","Heart","ThumbLike","ThumbDislike","Eye","EyeOff","ZoomIn","ZoomOut","Maximize","Minimize","Grid","List","Table","TableSimple","Code","Bug","Play","Pause","Stop","Refresh","ArrowSync","ArrowUndo","ArrowRedo","Printer","Send","Rocket","Sparkle","Trophy","Lightbulb","Bot","DataBar","ChartMultiple","Poll"];function Ye(s){for(const h of Ze)if(h.keywords.some(c=>s.includes(c)))return h.category;return"General"}const me=qe.map(s=>({name:s,category:Ye(s)})),Ke=["All",...Array.from(new Set(me.map(s=>s.category))).sort()],Qe=$e({content:{display:"flex",flexDirection:"column",gap:a.spacingVerticalS,height:"min(560px, calc(100vh - 240px))",minHeight:"320px",overflowY:"hidden"},toolbar:{display:"flex",alignItems:"center",gap:a.spacingHorizontalS,flexWrap:"wrap",flexShrink:0},search:{flex:"1 1 220px",minWidth:0},category:{minWidth:"160px"},variant:{display:"flex",gap:a.spacingHorizontalXS},iconGrid:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(88px, 1fr))",gap:a.spacingHorizontalXS,overflowY:"auto",flex:1,minHeight:0,padding:a.spacingHorizontalXXS},iconTile:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:a.spacingVerticalXS,minHeight:"72px",height:"auto",padding:a.spacingVerticalS,fontWeight:a.fontWeightRegular},iconTileSelected:{backgroundColor:a.colorBrandBackground2,border:`1px solid ${a.colorBrandStroke1}`},iconLabel:{fontSize:a.fontSizeBase200,textAlign:"center",lineHeight:a.lineHeightBase200,overflowWrap:"anywhere"},muted:{color:a.colorNeutralForeground3},selection:{display:"flex",alignItems:"center",gap:a.spacingHorizontalS,padding:`${a.spacingVerticalXS} ${a.spacingHorizontalS}`,backgroundColor:a.colorNeutralBackground3,borderRadius:a.borderRadiusMedium,flexShrink:0,minWidth:0},selectionText:{minWidth:0,display:"flex",flexDirection:"column"},resourceList:{listStyleType:"none",margin:0,padding:a.spacingHorizontalXXS,flex:1,minHeight:0,overflowY:"auto",display:"flex",flexDirection:"column",gap:a.spacingVerticalXXS},resourceRow:{width:"100%",justifyContent:"flex-start",fontFamily:a.fontFamilyMonospace,fontWeight:a.fontWeightRegular,fontSize:a.fontSizeBase200,textAlign:"start",overflowWrap:"anywhere"},dropZone:{flex:1,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:a.spacingVerticalM,padding:a.spacingVerticalL,textAlign:"center",border:`2px dashed ${a.colorNeutralStroke2}`,borderRadius:a.borderRadiusMedium,color:a.colorNeutralForeground3},dropZoneActive:{border:`2px dashed ${a.colorBrandStroke1}`,backgroundColor:a.colorBrandBackground2}}),X=300,no=()=>{const s=Qe(),h=Ne(),c=se(e=>e.iconPickerOpen),R=se(e=>e.closeIconPicker),Z=Te(e=>e.setButtonProp),A=N(e=>e.selectedButtonId),I=N(e=>e.selectedGroupId),q=N(e=>e.tabId),Y=N(e=>e.location),T=ne(e=>e.publisherPrefix),v=ne(e=>e.activeSolution),[K,d]=t.useState(null),[Q,$]=t.useState(null),[g,J]=t.useState("fluent"),[W,fe]=t.useState(""),[w,be]=t.useState("All"),[m,ee]=t.useState("regular"),[l,Se]=t.useState(null),[f,B]=t.useState(""),[x,L]=t.useState([]),[we,oe]=t.useState(!1),[E,xe]=t.useState(""),[b,y]=t.useState(!1),[ye,F]=t.useState(!1),re=t.useRef(null),Ce=de({axis:"grid-linear"}),ve=de({axis:"vertical"});ce.useEffect(()=>{c||(d(null),$(null))},[c]),ce.useEffect(()=>{!c||g!=="webresource"||(oe(!0),te("svg").then(e=>L(e)).catch(()=>L([])).finally(()=>oe(!1)))},[c,g]);const k=t.useMemo(()=>{const e=E.toLowerCase();return x.filter(r=>!e||r.name.toLowerCase().includes(e))},[E,x]),P=t.useMemo(()=>{const e=W.toLowerCase();return me.filter(r=>(w==="All"||r.category===w)&&(e===""||r.name.toLowerCase().includes(e)))},[W,w]),ke=async()=>{if(!l||!A||!I)return;const e=z(),r=M.getState();if(d(null),!v||v.isManaged){d("Select an unmanaged solution first — the icon is added to it as an SVG web resource.");return}y(!0);try{const n=await Ee(l,m,T,Fe,{busy:{onProgress:i=>r.logInfo("webresource",i)},guard:e});n.publishError&&r.logWarn("webresource",`Publishing icon web resource ${n.name} failed: ${n.publishError}. Pick the icon again or publish customizations before using the button.`),Z(Y,q,I,A,{icon:U(l),image16:`$webresource:${n.name}`,image32:`$webresource:${n.name}`}),r.logInfo("webresource",`${n.created?"Uploaded":"Reusing"} icon web resource ${n.name} (solution ${v.uniqueName}).`),R()}catch(n){const i=n instanceof Error?n.message:String(n);r.logError("webresource",`Fluent icon "${l}" could not be added as a web resource: ${i}`),d(`Could not add the icon as a web resource: ${i}`)}finally{y(!1)}},je=async()=>{if(!f||!A||!I)return;const e=le(f),r=z(),n=M.getState();d(null),$(null);const i=e.startsWith("$webresource:")?e.slice(13).trim():null;let p=null;if(i){y(!0);try{const S=x.find(G=>G.name===i),u=await Pe(i,S,r);u.solutionUniqueName&&n.logInfo("webresource",`Added web resource ${i} to solution ${u.solutionUniqueName}.`),p=u.solutionWarning??null}catch(S){const u=S instanceof Error?S.message:String(S);if(/^No web resource named /.test(u)){d(u);return}p=`The icon was set, but ${i} could not be added to the solution: ${u}`,n.logError("webresource",p)}finally{y(!1)}}if(Z(Y,q,I,A,{image16:e,image32:e}),p){$(p);return}R()},Re=async e=>{const r=z();if(!v||v.isManaged){d("Select an unmanaged solution first — the SVG is added to it as a web resource.");return}d(null),y(!0);try{const n=await new Promise((u,G)=>{const j=new FileReader;j.onerror=()=>G(j.error??new Error("Failed to read SVG")),j.onload=()=>{const D=String(j.result??"");u(D.includes(",")?D.split(",")[1]??"":D)},j.readAsDataURL(e)}),i=`${T||"new"}_/icons/${e.name}`,p=await Ge(i,n,11,{displayName:e.name,guard:r,onExisting:h.onExisting});$([p.solutionWarning,p.publishWarning].filter(Boolean).join(" ")||null),B(`$webresource:${i}`),J("webresource");const S=await te("svg");L(S)}catch(n){if(n instanceof De)return;const i=n instanceof Error?n.message:String(n);M.getState().logError("webresource",`SVG upload failed: ${i}`),d(`Upload failed: ${i}`)}finally{y(!1)}},ae=e=>{if(e){if(!/\.svg$/i.test(e.name)){d(`${e.name} isn't an SVG file.`);return}Re(e)}},Ae=f.startsWith("$webresource:")?f.slice(13):f;return o.jsxs(o.Fragment,{children:[h.dialog,o.jsxs(We,{open:c,onOpenChange:e=>!e&&R(),title:"Choose an icon",size:"large",contentClassName:s.content,startActions:o.jsx(Le,{prefix:"Saves to"}),actions:o.jsxs(o.Fragment,{children:[o.jsx(C,{onClick:R,children:"Cancel"}),g==="fluent"&&o.jsx(C,{appearance:"primary",disabled:!l||b,onClick:()=>{ke()},children:b?"Adding icon…":`Use ${l??"icon"}`}),g==="webresource"&&o.jsx(C,{appearance:"primary",disabled:!f||b,onClick:()=>{je()},children:b?"Adding icon…":"Use web resource"})]}),children:[o.jsxs(Ve,{selectedValue:g,onTabSelect:(e,r)=>J(r.value),children:[o.jsx(H,{value:"fluent",children:"Fluent icons"}),o.jsx(H,{value:"webresource",children:"Web resources"}),o.jsx(H,{value:"upload",children:"Upload SVG"})]}),K&&o.jsx(ue,{intent:"error",children:o.jsx(ge,{children:K})}),Q&&o.jsx(ue,{intent:"warning",children:o.jsxs(ge,{children:["Icon applied. ",Q]})}),g==="fluent"&&o.jsxs(o.Fragment,{children:[o.jsxs("div",{className:s.toolbar,children:[o.jsx(pe,{className:s.search,placeholder:"Search icons","aria-label":"Search icons",value:W,onChange:(e,r)=>fe(r.value)}),o.jsx(Ue,{className:s.category,"aria-label":"Category",value:w==="All"?"All categories":w,selectedOptions:[w],onOptionSelect:(e,r)=>be(String(r.optionValue??"All")),children:Ke.map(e=>o.jsx(Me,{value:e,text:e==="All"?"All categories":e,children:e==="All"?"All categories":e},e))}),o.jsxs("div",{className:s.variant,role:"group","aria-label":"Icon style",children:[o.jsx(he,{checked:m==="regular",onClick:()=>ee("regular"),children:"Regular"}),o.jsx(he,{checked:m==="filled",onClick:()=>ee("filled"),children:"Filled"})]})]}),o.jsxs("div",{className:s.iconGrid,role:"group","aria-label":`${P.length} icons`,...Ce,children:[P.map(e=>{const r=l===e.name;return o.jsx(ze,{content:`${e.name} · ${e.category}`,relationship:"description",children:o.jsxs(C,{appearance:"subtle","aria-pressed":r,className:V(s.iconTile,r&&s.iconTileSelected),onClick:()=>Se(e.name),children:[o.jsx(ie,{name:U(e.name),size:24,variant:m}),o.jsx("span",{className:s.iconLabel,children:o.jsx(Xe,{text:e.name})})]})},e.name)}),P.length===0&&o.jsx(O,{className:s.muted,children:"No icon matches."})]}),l&&o.jsxs("div",{className:s.selection,role:"status",children:[o.jsx(ie,{name:U(l),size:24,variant:m}),o.jsxs("span",{className:s.selectionText,children:[o.jsxs(O,{weight:"semibold",children:[l," ·"," ",m==="regular"?"Regular":"Filled"]}),o.jsxs(_,{className:s.muted,children:["Added to your solution as"," ",Be(T||"new",l,m)]})]})]})]}),g==="webresource"&&o.jsxs(o.Fragment,{children:[o.jsx(pe,{placeholder:"Search SVG web resources","aria-label":"Search SVG web resources",value:E,onChange:(e,r)=>xe(r.value)}),we?o.jsx(He,{size:"small",label:"Loading web resources…"}):o.jsxs(o.Fragment,{children:[o.jsx(_,{className:s.muted,role:"status",children:k.length>X?`Showing ${X} of ${k.length.toLocaleString()} SVG web resources. Search to find others.`:k.length===x.length?`${x.length.toLocaleString()} SVG web resources`:`${k.length} of ${x.length.toLocaleString()} SVG web resources`}),o.jsx("ul",{className:s.resourceList,"aria-label":"SVG web resources",...ve,children:k.slice(0,X).map(e=>{const r=`$webresource:${e.name}`,n=f===r;return o.jsx("li",{children:o.jsx(C,{appearance:"subtle","aria-pressed":n,className:V(s.resourceRow,n&&s.iconTileSelected),onClick:()=>B(r),children:e.name})},e.id)})})]}),o.jsx(Oe,{label:"Web resource",hint:"Image16 and Image32 are both set to it. SVG works at every size.",children:o.jsx(_e,{placeholder:"publisher_/icons/icon.svg",value:Ae,onChange:(e,r)=>B(r.value?le(r.value):"")})})]}),g==="upload"&&o.jsxs("div",{className:V(s.dropZone,ye&&s.dropZoneActive),onDragOver:e=>{e.preventDefault(),F(!0)},onDragLeave:()=>F(!1),onDrop:e=>{e.preventDefault(),F(!1),ae(e.dataTransfer.files?.[0])},children:[o.jsx(Ie,{fontSize:48}),o.jsx(O,{children:"Drop an SVG file here"}),o.jsx(_,{children:"It's uploaded as a web resource in your solution, then listed under Web resources to use."}),o.jsx("input",{ref:re,type:"file",accept:".svg",hidden:!0,disabled:b,onChange:e=>{const r=e.target.files?.[0];e.target.value="",ae(r)}}),o.jsx(C,{appearance:"primary",disabled:b,onClick:()=>re.current?.click(),children:b?"Uploading…":"Choose SVG…"})]})]})]})};export{no as IconPickerModal,no as default};
|