Skip to content

Commit 5d35245

Browse files
feat(edit-content): update command bar to show all workflow actions (#35290)
## Summary Closes #35034 and #31321 - Replaces the split-button pattern in `dot-workflow-actions` with individual inline buttons, making all workflow actions discoverable - First action (rightmost): default solid button — second: outlined — third: text; actions beyond 3 collapse into an overflow popup menu (`p-menu` with `appendTo="body"`) - SEPARATOR actions are filtered out automatically - Removed `groupActions` and `SplitButton` — component is now purely computed-signal driven ## IMAGES BEFORE <img width="1586" height="743" alt="Screenshot 2026-04-14 at 2 37 36 PM" src="https://github.com/user-attachments/assets/a45b6b40-53d4-436f-ad2c-10179e26148b" /> NOW <img width="1272" height="693" alt="Screenshot 2026-04-14 at 2 37 42 PM" src="https://github.com/user-attachments/assets/75b6ea9b-df9b-472c-8e06-0348fbf12ce8" /> ## Test plan - [ ] Verify workflow actions render as individual buttons (not hidden in a split button) - [ ] Verify first action is primary, second outlined, third text - [ ] Verify overflow menu appears when there are more than 3 actions - [ ] Verify clicking overflow menu items fires the correct action - [ ] Verify SEPARATOR actions are not rendered - [ ] Verify loading spinner appears only on the primary button - [ ] Verify disabled state disables all buttons In this PR we are also closing the bug with long workflows names <img width="1167" height="577" alt="Screenshot 2026-04-14 at 2 43 52 PM" src="https://github.com/user-attachments/assets/3c47d5c7-d39c-469d-9eb4-28416e70cf56" />
1 parent d6a136a commit 5d35245

5 files changed

Lines changed: 397 additions & 289 deletions

File tree

core-web/apps/dotcms-ui-e2e/src/pages/newEditContentForm.page.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,15 @@ export class NewEditContentFormPage {
6767
}
6868

6969
/**
70-
* Clicks the primary workflow action button (Save or Publish) and waits for the API response.
71-
* New content shows "Save", existing content shows "Publish".
70+
* Clicks the workflow action that persists the content (Save or Publish) and waits for the API response.
71+
* Prefer "Save" when both Save and Publish are visible — the new command bar can show multiple
72+
* workflow buttons at once, so a single regex locator would match 2+ roles and break strict mode.
7273
*/
7374
async save() {
74-
// Match either Save or Publish — the primary action button
75-
const actionButton = this.page.getByRole('button', { name: /^(Save|Publish)$/ });
75+
const saveButton = this.page.getByRole('button', { name: 'Save' });
76+
const publishButton = this.page.getByRole('button', { name: 'Publish' });
77+
const actionButton = (await saveButton.isVisible()) ? saveButton : publishButton;
78+
7679
await expect(actionButton).toBeVisible();
7780

7881
const responsePromise = this.page.waitForResponse((response) => {

core-web/libs/edit-content/src/lib/components/dot-edit-content-form/dot-edit-content-form.component.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,7 @@
139139
identifier: currentIdentifier
140140
})
141141
"
142-
[actions]="actions"
143-
[groupActions]="true" />
142+
[actions]="actions" />
144143
}
145144
}
146145

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
1-
@for (action of $groupedActions(); track $index) {
2-
@let mainAction = action.mainAction;
3-
@let subActions = action.subActions;
4-
@if (subActions.length) {
5-
<p-splitButton
6-
(onClick)="mainAction?.command({ originalEvent: $event })"
7-
[disabled]="loading() || disabled()"
8-
[size]="getButtonSize()"
9-
[model]="subActions"
10-
[outlined]="!$first"
11-
[label]="mainAction.label" />
12-
} @else {
13-
<p-button
14-
(onClick)="mainAction?.command({ originalEvent: $event })"
15-
[loading]="loading()"
16-
[disabled]="disabled()"
17-
[size]="getButtonSize()"
18-
[variant]="!$first ? 'outlined' : undefined"
19-
[label]="mainAction.label" />
20-
}
21-
} @empty {
1+
@if ($flatActions().length === 0) {
222
<p-button
233
[loading]="loading()"
244
[disabled]="!loading()"
255
[size]="getButtonSize()"
266
[label]="(loading() ? 'Loading' : 'edit.ema.page.no.workflow.action') | dm"
277
data-testId="empty-button" />
8+
} @else {
9+
@if ($overflowActions().length) {
10+
<p-menu #overflowMenu [model]="$overflowActions()" [popup]="true" appendTo="body" />
11+
<p-button
12+
(onClick)="overflowMenu.toggle($event)"
13+
[rounded]="true"
14+
[size]="getButtonSize()"
15+
[disabled]="loading() || disabled()"
16+
icon="pi pi-ellipsis-v"
17+
[variant]="'outlined'"
18+
data-testId="overflow-button" />
19+
}
20+
@for (action of $visibleActions(); track action.id; let idx = $index; let first = $first) {
21+
<p-button
22+
(onClick)="fireAction(action)"
23+
[loading]="first && loading()"
24+
[disabled]="loading() || disabled()"
25+
[size]="getButtonSize()"
26+
[variant]="getVariant(idx)"
27+
[label]="action.name"
28+
[attr.data-testId]="'action-button-' + action.id" />
29+
}
2830
}

0 commit comments

Comments
 (0)