Skip to content

Commit 8de93f8

Browse files
authored
[2.x] feat: Add header extension seams to the queue dashboard widget (#4850)
* Add header extension seams to the queue dashboard widget Give QueueWidget two overridable ItemList seams for its header, mirroring the existing tiles() pattern: - titleItems(): content appended after the title (e.g. status pills). Empty by default. - headerActions(): the action controls on the right. Ships the refresh button as a default item; a subclass can add its own (e.g. a link to a fuller dashboard). The refresh button now lives in headerActions() rather than being inlined, so core's own header renders identically. Purely additive: a subclass can enrich the header without overriding content() and duplicating its markup. Lets an extension that subclasses this widget (e.g. fof/horizon, which binds an enriched QueueStatsProvider) surface at-a-glance state and a link to its own dashboard on the shared queue card. * Lay out the queue widget header actions in a row The headerActions() seam holds the refresh button plus any controls a subclass adds, but the .QueueWidget-headerActions wrapper had no layout of its own, so multiple items would flow without spacing. Give it a flex row with a gap. (Right-alignment is already handled by space-between on .QueueWidget-header — this is only about spacing the items within.)
1 parent b515de7 commit 8de93f8

2 files changed

Lines changed: 42 additions & 7 deletions

File tree

framework/core/js/src/admin/components/QueueWidget.tsx

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,21 +62,46 @@ export default class QueueWidget<CustomAttrs extends IDashboardWidgetAttrs = IDa
6262
<div className="QueueWidget-header">
6363
<h3 className="QueueWidget-title">
6464
<Icon name="fas fa-stream" /> {app.translator.trans('core.admin.queue_widget.title')}
65+
{this.titleItems().toArray()}
6566
</h3>
66-
<Button
67-
className="Button Button--icon Button--flat"
68-
icon="fas fa-sync-alt"
69-
loading={this.loading}
70-
onclick={() => this.load()}
71-
aria-label={app.translator.trans('core.admin.queue_widget.refresh')}
72-
/>
67+
<div className="QueueWidget-headerActions">{this.headerActions().toArray()}</div>
7368
</div>
7469

7570
{!this.stats ? <LoadingIndicator /> : <div className="QueueWidget-tiles">{this.tiles().toArray()}</div>}
7671
</div>
7772
);
7873
}
7974

75+
/**
76+
* Content appended after the widget title — e.g. status pills. Empty by
77+
* default; a subclass adds items to surface at-a-glance state.
78+
*/
79+
titleItems(): ItemList<Mithril.Children> {
80+
return new ItemList<Mithril.Children>();
81+
}
82+
83+
/**
84+
* Action controls on the right of the header. Ships with the refresh button;
85+
* a subclass can add its own (e.g. a link to a fuller dashboard).
86+
*/
87+
headerActions(): ItemList<Mithril.Children> {
88+
const items = new ItemList<Mithril.Children>();
89+
90+
items.add(
91+
'refresh',
92+
<Button
93+
className="Button Button--icon Button--flat"
94+
icon="fas fa-sync-alt"
95+
loading={this.loading}
96+
onclick={() => this.load()}
97+
aria-label={app.translator.trans('core.admin.queue_widget.refresh')}
98+
/>,
99+
100
100+
);
101+
102+
return items;
103+
}
104+
80105
tiles(): ItemList<Mithril.Children> {
81106
const items = new ItemList<Mithril.Children>();
82107
const totals = this.stats!.totals;

framework/core/less/admin/QueueWidget.less

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@
88
padding: 16px 20px 12px;
99
}
1010

11+
// Right-hand header controls. `space-between` on -header already pushes this
12+
// to the right (it's the second flex child after -title); this lays its own
13+
// items — the refresh button plus anything a subclass adds via
14+
// headerActions() — out in a row with consistent spacing.
15+
&-headerActions {
16+
display: flex;
17+
align-items: center;
18+
gap: 8px;
19+
}
20+
1121
&-title {
1222
display: flex;
1323
align-items: center;

0 commit comments

Comments
 (0)