@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.149 → 2.0.0-next.150
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/bundle/openbridge-webcomponents.bundle.js +4443 -3841
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +381 -2
- package/dist/components/alert-list-details-experimental/alert-list-details-experimental.css.js +94 -0
- package/dist/components/alert-list-details-experimental/alert-list-details-experimental.css.js.map +1 -0
- package/dist/components/alert-list-details-experimental/alert-list-details-experimental.d.ts +72 -0
- package/dist/components/alert-list-details-experimental/alert-list-details-experimental.d.ts.map +1 -0
- package/dist/components/alert-list-details-experimental/alert-list-details-experimental.js +396 -0
- package/dist/components/alert-list-details-experimental/alert-list-details-experimental.js.map +1 -0
- package/dist/components/table/table.css.js +43 -0
- package/dist/components/table/table.css.js.map +1 -1
- package/dist/components/table/table.d.ts +31 -1
- package/dist/components/table/table.d.ts.map +1 -1
- package/dist/components/table/table.js +124 -11
- package/dist/components/table/table.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/components/alert-list-details-experimental/alert-list-details-experimental.css +70 -0
- package/src/components/alert-list-details-experimental/alert-list-details-experimental.stories.ts +510 -0
- package/src/components/alert-list-details-experimental/alert-list-details-experimental.ts +457 -0
- package/src/components/table/table.css +42 -0
- package/src/components/table/table.stories.ts +279 -0
- package/src/components/table/table.ts +177 -13
- package/src/types.ts +6 -4
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import {LitElement, html, unsafeCSS} from 'lit';
|
|
2
|
+
import {customElement} from '../../decorator.js';
|
|
3
|
+
import compentStyle from './alert-list-details-experimental.css?inline';
|
|
4
|
+
import {msg} from '@lit/localize';
|
|
5
|
+
import {property, query, state} from 'lit/decorators.js';
|
|
6
|
+
import '../icon-button/icon-button.js';
|
|
7
|
+
import '../button/button.js';
|
|
8
|
+
import '../../icons/icon-silence-iec.js';
|
|
9
|
+
import '../../icons/icon-alerts.js';
|
|
10
|
+
import '../../icons/icon-alerts-shelf.js';
|
|
11
|
+
import '../../icons/icon-alerts-active.js';
|
|
12
|
+
import '../../icons/icon-alarm-rectified-iec.js';
|
|
13
|
+
import '../../icons/icon-unacknowledged.js';
|
|
14
|
+
import '../../icons/icon-alarm-noack-iec.js';
|
|
15
|
+
import '../../icons/icon-warning-noack-iec.js';
|
|
16
|
+
import '../alert-icon/alert-icon.js';
|
|
17
|
+
import {
|
|
18
|
+
Alert,
|
|
19
|
+
comparePriorityAlerts,
|
|
20
|
+
isActive,
|
|
21
|
+
isAcknowledged,
|
|
22
|
+
isBlocked,
|
|
23
|
+
isShelved,
|
|
24
|
+
} from '../../types.js';
|
|
25
|
+
import {
|
|
26
|
+
excludedFromUnackedFilter,
|
|
27
|
+
requiresAcknowledgement,
|
|
28
|
+
usesAlarmNoAckIcon,
|
|
29
|
+
} from '../../alert-severity.js';
|
|
30
|
+
import {
|
|
31
|
+
ObcTable,
|
|
32
|
+
ObcTableCellClickEvent,
|
|
33
|
+
ObcTableCellData,
|
|
34
|
+
ObcTableCellType,
|
|
35
|
+
ObcTableExpandToggleEvent,
|
|
36
|
+
ObcTableRowClickEvent,
|
|
37
|
+
ObcTableRow,
|
|
38
|
+
ObcTableColumn,
|
|
39
|
+
} from '../table/table.js';
|
|
40
|
+
import '../scrollbar/scrollbar.js';
|
|
41
|
+
|
|
42
|
+
export enum AlertListMode {
|
|
43
|
+
UNACKED = 'unacked',
|
|
44
|
+
ALL = 'all',
|
|
45
|
+
SHELVED = 'shelved',
|
|
46
|
+
BLOCKED = 'blocked',
|
|
47
|
+
RECTIFIED = 'rectified',
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type ObcAckClickEvent = CustomEvent<{
|
|
51
|
+
alert: Alert;
|
|
52
|
+
}>;
|
|
53
|
+
|
|
54
|
+
export type ObcRowClickEvent = CustomEvent<{
|
|
55
|
+
alert: Alert;
|
|
56
|
+
}>;
|
|
57
|
+
|
|
58
|
+
export function getAlertListModeData(selectedMode: AlertListMode) {
|
|
59
|
+
if (selectedMode === AlertListMode.ALL)
|
|
60
|
+
return {
|
|
61
|
+
name: AlertListMode.ALL,
|
|
62
|
+
title: msg('All'),
|
|
63
|
+
emptyTitle: msg('No active alerts'),
|
|
64
|
+
emptyIcon: html`<obi-alerts></obi-alerts>`,
|
|
65
|
+
filter: (alert: Alert) => !isShelved(alert) && isActive(alert),
|
|
66
|
+
};
|
|
67
|
+
else if (selectedMode === AlertListMode.UNACKED)
|
|
68
|
+
return {
|
|
69
|
+
name: AlertListMode.UNACKED,
|
|
70
|
+
title: msg('Unacked'),
|
|
71
|
+
emptyTitle: msg('No unacknowledged alerts'),
|
|
72
|
+
emptyIcon: html`<obi-unacknowledged></obi-unacknowledged>`,
|
|
73
|
+
filter: (alert: Alert) =>
|
|
74
|
+
!isAcknowledged(alert) &&
|
|
75
|
+
isActive(alert) &&
|
|
76
|
+
!excludedFromUnackedFilter(alert.type) &&
|
|
77
|
+
!isShelved(alert),
|
|
78
|
+
};
|
|
79
|
+
else if (selectedMode === AlertListMode.SHELVED)
|
|
80
|
+
return {
|
|
81
|
+
name: AlertListMode.SHELVED,
|
|
82
|
+
title: msg('Shelved'),
|
|
83
|
+
emptyTitle: msg('No shelved alerts'),
|
|
84
|
+
emptyIcon: html`<obi-alerts-shelf></obi-alerts-shelf>`,
|
|
85
|
+
filter: (alert: Alert) => isShelved(alert),
|
|
86
|
+
};
|
|
87
|
+
else if (selectedMode === AlertListMode.BLOCKED)
|
|
88
|
+
return {
|
|
89
|
+
name: AlertListMode.BLOCKED,
|
|
90
|
+
title: msg('Blocked'),
|
|
91
|
+
emptyTitle: msg('No blocked alerts'),
|
|
92
|
+
emptyIcon: html`<obi-alerts-active></obi-alerts-active>`,
|
|
93
|
+
filter: (alert: Alert) => isBlocked(alert),
|
|
94
|
+
};
|
|
95
|
+
else if (selectedMode === AlertListMode.RECTIFIED)
|
|
96
|
+
return {
|
|
97
|
+
name: AlertListMode.RECTIFIED,
|
|
98
|
+
title: msg('Rectified'),
|
|
99
|
+
emptyTitle: msg('No rectified alerts'),
|
|
100
|
+
emptyIcon: html`<obi-alarm-rectified-iec></obi-alarm-rectified-iec>`,
|
|
101
|
+
filter: (alert: Alert) => !isActive(alert),
|
|
102
|
+
};
|
|
103
|
+
else throw new Error('Invalid selected mode');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function canAckFilter(filter: (alert: Alert) => boolean) {
|
|
107
|
+
return (alert: Alert) =>
|
|
108
|
+
!isAcknowledged(alert) &&
|
|
109
|
+
!alert.noAck &&
|
|
110
|
+
!excludedFromUnackedFilter(alert.type) &&
|
|
111
|
+
filter(alert);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @availableWhen timeFormatter showTime==true
|
|
116
|
+
* @property defaultExpanded - Whether groups start expanded. Set false to open the list collapsed.
|
|
117
|
+
* @fires {ObcAckClickEvent} ack-click - Fired when the user clicks the "ACK" button.
|
|
118
|
+
* @fires {ObcRowClickEvent} row-click - Fired when the user clicks a row.
|
|
119
|
+
* @experimental
|
|
120
|
+
*/
|
|
121
|
+
@customElement('obc-alert-list-details-experimental')
|
|
122
|
+
export class ObcAlertListDetailsExperimental extends LitElement {
|
|
123
|
+
@property({type: String}) selectedMode: AlertListMode = AlertListMode.ALL;
|
|
124
|
+
@property({type: Array}) alerts: Alert[] = [];
|
|
125
|
+
@property({type: Boolean}) showTime: boolean = false;
|
|
126
|
+
@property({attribute: false}) timeFormatter: (time: Date) => string = (
|
|
127
|
+
time: Date
|
|
128
|
+
) => time.toLocaleTimeString(undefined, {hour12: false});
|
|
129
|
+
@property({type: Boolean}) small: boolean = false;
|
|
130
|
+
@property({type: Boolean, attribute: false}) defaultExpanded: boolean = true;
|
|
131
|
+
|
|
132
|
+
@query('obc-table')
|
|
133
|
+
private alertList!: ObcTable;
|
|
134
|
+
|
|
135
|
+
@state() private expansionOverrides = new Map<string, boolean>();
|
|
136
|
+
|
|
137
|
+
private alertByRowId = new Map<string, Alert>();
|
|
138
|
+
|
|
139
|
+
public getVisibleAlerts(): Alert[] {
|
|
140
|
+
const seen = new Set<string>();
|
|
141
|
+
return this.alertList
|
|
142
|
+
.getAllVisibleRows()
|
|
143
|
+
.map((rowId) => this.alertByRowId.get(rowId))
|
|
144
|
+
.filter((alert): alert is Alert => alert !== undefined)
|
|
145
|
+
.filter((alert) => {
|
|
146
|
+
if (seen.has(alert.id)) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
seen.add(alert.id);
|
|
150
|
+
return true;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private onRowClick(e: ObcTableRowClickEvent) {
|
|
155
|
+
const row = this.alertByRowId.get(e.detail.row.id);
|
|
156
|
+
if (row) {
|
|
157
|
+
this.dispatchEvent(
|
|
158
|
+
new CustomEvent('row-click', {detail: {alert: row}}) as ObcRowClickEvent
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private onCellButtonClick(e: ObcTableCellClickEvent) {
|
|
164
|
+
const row = this.alertByRowId.get(e.detail.rowId);
|
|
165
|
+
if (row) {
|
|
166
|
+
this.dispatchEvent(
|
|
167
|
+
new CustomEvent('ack-click', {
|
|
168
|
+
detail: {alert: row},
|
|
169
|
+
bubbles: false,
|
|
170
|
+
}) as ObcAckClickEvent
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private onExpandToggle(e: ObcTableExpandToggleEvent) {
|
|
176
|
+
const overrides = new Map(this.expansionOverrides);
|
|
177
|
+
overrides.set(e.detail.rowId, e.detail.expanded);
|
|
178
|
+
this.expansionOverrides = overrides;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
private isExpanded(rowId: string) {
|
|
182
|
+
return this.expansionOverrides.get(rowId) ?? this.defaultExpanded;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
private get columns() {
|
|
186
|
+
if (this.small) {
|
|
187
|
+
const columns: ObcTableColumn<ObcTableCellData, ObcTableRow>[] = [
|
|
188
|
+
{
|
|
189
|
+
label: 'Status',
|
|
190
|
+
key: 'status',
|
|
191
|
+
sortDirection: 'desc',
|
|
192
|
+
sortable: true,
|
|
193
|
+
compareFunction: (_a, _b, aRow, bRow) => {
|
|
194
|
+
const aAlert = this.alertByRowId.get(aRow.id);
|
|
195
|
+
const bAlert = this.alertByRowId.get(bRow.id);
|
|
196
|
+
if (aAlert && bAlert) {
|
|
197
|
+
return comparePriorityAlerts(aAlert, bAlert);
|
|
198
|
+
}
|
|
199
|
+
return 0;
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
];
|
|
203
|
+
if (this.showTime) {
|
|
204
|
+
columns.push({
|
|
205
|
+
label: 'Activated',
|
|
206
|
+
key: 'time',
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
columns.push({
|
|
210
|
+
label: 'ACK-status',
|
|
211
|
+
key: 'action',
|
|
212
|
+
});
|
|
213
|
+
return columns;
|
|
214
|
+
} else {
|
|
215
|
+
const columns: ObcTableColumn<ObcTableCellData, ObcTableRow>[] = [
|
|
216
|
+
{
|
|
217
|
+
label: 'Status',
|
|
218
|
+
key: 'status',
|
|
219
|
+
sortDirection: 'desc',
|
|
220
|
+
sortable: true,
|
|
221
|
+
compareFunction: (_a, _b, aRow, bRow) => {
|
|
222
|
+
const aAlert = this.alertByRowId.get(aRow.id);
|
|
223
|
+
const bAlert = this.alertByRowId.get(bRow.id);
|
|
224
|
+
if (aAlert && bAlert) {
|
|
225
|
+
return comparePriorityAlerts(aAlert, bAlert);
|
|
226
|
+
}
|
|
227
|
+
return 0;
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
label: 'ACK-status',
|
|
232
|
+
key: 'action',
|
|
233
|
+
dividerRight: true,
|
|
234
|
+
},
|
|
235
|
+
];
|
|
236
|
+
if (this.showTime) {
|
|
237
|
+
columns.push({
|
|
238
|
+
label: 'Activated',
|
|
239
|
+
key: 'time',
|
|
240
|
+
sortable: true,
|
|
241
|
+
compareFunction: (_a, _b, aRow, bRow) => {
|
|
242
|
+
const aAlert = this.alertByRowId.get(aRow.id);
|
|
243
|
+
const bAlert = this.alertByRowId.get(bRow.id);
|
|
244
|
+
if (aAlert && bAlert) {
|
|
245
|
+
const aTime = new Date(aAlert.time);
|
|
246
|
+
const bTime = new Date(bAlert.time);
|
|
247
|
+
return aTime.getTime() - bTime.getTime();
|
|
248
|
+
}
|
|
249
|
+
return 0;
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
columns.push({
|
|
254
|
+
label: 'Tag ID',
|
|
255
|
+
key: 'tagId',
|
|
256
|
+
sortable: true,
|
|
257
|
+
compareFunction: (a, b) => {
|
|
258
|
+
const aText =
|
|
259
|
+
a?.type === ObcTableCellType.Regular ? String(a.text ?? '') : '';
|
|
260
|
+
const bText =
|
|
261
|
+
b?.type === ObcTableCellType.Regular ? String(b.text ?? '') : '';
|
|
262
|
+
return aText.localeCompare(bText);
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
return columns;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
private get metadata() {
|
|
270
|
+
return getAlertListModeData(this.selectedMode);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
private get filteredAlerts() {
|
|
274
|
+
return this.alerts.filter(this.metadata.filter);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
private buildVisibleRows(): ObcTableRow[] {
|
|
278
|
+
const alerts = this.filteredAlerts;
|
|
279
|
+
const alertIds = new Set(alerts.map((alert) => alert.id));
|
|
280
|
+
const membersByGroupId = new Map<string, Alert[]>();
|
|
281
|
+
const roots: Alert[] = [];
|
|
282
|
+
for (const alert of alerts) {
|
|
283
|
+
const groupIds = (alert.memberOf ?? []).filter(
|
|
284
|
+
(groupId) => groupId !== alert.id && alertIds.has(groupId)
|
|
285
|
+
);
|
|
286
|
+
if (groupIds.length === 0) {
|
|
287
|
+
roots.push(alert);
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
for (const groupId of groupIds) {
|
|
291
|
+
const members = membersByGroupId.get(groupId) ?? [];
|
|
292
|
+
members.push(alert);
|
|
293
|
+
membersByGroupId.set(groupId, members);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const reachable = new Set<string>();
|
|
298
|
+
const markReachable = (alert: Alert) => {
|
|
299
|
+
if (reachable.has(alert.id)) {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
reachable.add(alert.id);
|
|
303
|
+
for (const member of membersByGroupId.get(alert.id) ?? []) {
|
|
304
|
+
markReachable(member);
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
roots.forEach(markReachable);
|
|
308
|
+
for (const alert of alerts) {
|
|
309
|
+
if (!reachable.has(alert.id)) {
|
|
310
|
+
roots.push(alert);
|
|
311
|
+
markReachable(alert);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const rows: ObcTableRow[] = [];
|
|
316
|
+
this.alertByRowId = new Map();
|
|
317
|
+
const visit = (
|
|
318
|
+
alert: Alert,
|
|
319
|
+
level: number,
|
|
320
|
+
parentRowId: string | undefined,
|
|
321
|
+
ancestors: Set<string>
|
|
322
|
+
) => {
|
|
323
|
+
const segment = encodeURIComponent(alert.id);
|
|
324
|
+
const rowId =
|
|
325
|
+
parentRowId === undefined ? segment : `${parentRowId}/${segment}`;
|
|
326
|
+
const members = membersByGroupId.get(alert.id) ?? [];
|
|
327
|
+
// A member can name a group that is also its own descendant.
|
|
328
|
+
const expandableMembers = members.filter(
|
|
329
|
+
(member) => !ancestors.has(member.id)
|
|
330
|
+
);
|
|
331
|
+
const expanded = this.isExpanded(rowId);
|
|
332
|
+
|
|
333
|
+
this.alertByRowId.set(rowId, alert);
|
|
334
|
+
rows.push({
|
|
335
|
+
...this.buildRowCells(alert),
|
|
336
|
+
id: rowId,
|
|
337
|
+
parentId: parentRowId,
|
|
338
|
+
level,
|
|
339
|
+
expandable: expandableMembers.length > 0,
|
|
340
|
+
expanded,
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
if (!expanded) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
const nextAncestors = new Set(ancestors).add(alert.id);
|
|
347
|
+
for (const member of expandableMembers) {
|
|
348
|
+
visit(member, level + 1, rowId, nextAncestors);
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
for (const alert of roots) {
|
|
353
|
+
visit(alert, 0, undefined, new Set());
|
|
354
|
+
}
|
|
355
|
+
return rows;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
private buildRowCells(
|
|
359
|
+
alert: Alert
|
|
360
|
+
): Record<string, ObcTableCellData | undefined> {
|
|
361
|
+
let action: ObcTableCellData = {
|
|
362
|
+
type: ObcTableCellType.Regular,
|
|
363
|
+
};
|
|
364
|
+
if (
|
|
365
|
+
!isAcknowledged(alert) &&
|
|
366
|
+
isActive(alert) &&
|
|
367
|
+
requiresAcknowledgement(alert.type)
|
|
368
|
+
) {
|
|
369
|
+
if (alert.noAck) {
|
|
370
|
+
const icon = usesAlarmNoAckIcon(alert.type)
|
|
371
|
+
? html`<obi-alarm-noack-iec usecsscolor></obi-alarm-noack-iec>`
|
|
372
|
+
: html`<obi-warning-noack-iec usecsscolor></obi-warning-noack-iec>`;
|
|
373
|
+
action = {
|
|
374
|
+
type: ObcTableCellType.Regular,
|
|
375
|
+
largeIcon: true,
|
|
376
|
+
icon,
|
|
377
|
+
align: 'center',
|
|
378
|
+
};
|
|
379
|
+
} else {
|
|
380
|
+
action = {
|
|
381
|
+
type: ObcTableCellType.Button,
|
|
382
|
+
text: msg('ACK'),
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const status: ObcTableCellData = {
|
|
388
|
+
type: ObcTableCellType.Regular,
|
|
389
|
+
largeIcon: true,
|
|
390
|
+
text: alert.text,
|
|
391
|
+
title: alert.source,
|
|
392
|
+
noWrap: true,
|
|
393
|
+
icon: html`<obc-alert-icon
|
|
394
|
+
.type=${alert.type}
|
|
395
|
+
.acknowledged=${isAcknowledged(alert)}
|
|
396
|
+
.active=${isActive(alert)}
|
|
397
|
+
></obc-alert-icon>`,
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
const time: ObcTableCellData | undefined = this.showTime
|
|
401
|
+
? {
|
|
402
|
+
type: ObcTableCellType.Regular,
|
|
403
|
+
text: this.timeFormatter(alert.time),
|
|
404
|
+
align: 'center',
|
|
405
|
+
neutral: true,
|
|
406
|
+
}
|
|
407
|
+
: undefined;
|
|
408
|
+
|
|
409
|
+
const tagId: ObcTableCellData | undefined = this.small
|
|
410
|
+
? undefined
|
|
411
|
+
: {
|
|
412
|
+
type: ObcTableCellType.Regular,
|
|
413
|
+
text: '#' + alert.id,
|
|
414
|
+
align: 'right',
|
|
415
|
+
};
|
|
416
|
+
return {
|
|
417
|
+
status,
|
|
418
|
+
time,
|
|
419
|
+
action,
|
|
420
|
+
tagId,
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
override render() {
|
|
425
|
+
const selectedList = this.metadata;
|
|
426
|
+
const data = this.buildVisibleRows();
|
|
427
|
+
|
|
428
|
+
return html`
|
|
429
|
+
<div class="wrapper ${this.small ? 'small' : ''}">
|
|
430
|
+
${data.length > 0
|
|
431
|
+
? html` <obc-table
|
|
432
|
+
class="alert-list"
|
|
433
|
+
.data=${data}
|
|
434
|
+
.columns=${this.columns}
|
|
435
|
+
.striped=${true}
|
|
436
|
+
.showHeader=${!this.small}
|
|
437
|
+
@row-click=${this.onRowClick}
|
|
438
|
+
@cell-button-click=${this.onCellButtonClick}
|
|
439
|
+
@expand-toggle=${this.onExpandToggle}
|
|
440
|
+
></obc-table>
|
|
441
|
+
<div class="spacer"></div>`
|
|
442
|
+
: html` <div class="empty-list">
|
|
443
|
+
<div class="icon">${selectedList.emptyIcon}</div>
|
|
444
|
+
<div class="empty-title">${selectedList.emptyTitle}</div>
|
|
445
|
+
</div>`}
|
|
446
|
+
</div>
|
|
447
|
+
`;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
static override styles = unsafeCSS(compentStyle);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
declare global {
|
|
454
|
+
interface HTMLElementTagNameMap {
|
|
455
|
+
'obc-alert-list-details-experimental': ObcAlertListDetailsExperimental;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
@@ -197,6 +197,48 @@
|
|
|
197
197
|
flex-shrink: 0;
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
+
/* ---- Hierarchy ---- */
|
|
201
|
+
|
|
202
|
+
/*
|
|
203
|
+
* Indent gutter for a hierarchical row. One step per level plus one for
|
|
204
|
+
* the chevron itself, so a leaf and a group at the same level align.
|
|
205
|
+
*/
|
|
206
|
+
.row-expander {
|
|
207
|
+
--row-indent-step: var(
|
|
208
|
+
--menu-navigation-components-table-item-icon-size
|
|
209
|
+
);
|
|
210
|
+
/* Depth of this row; the row's inline style overrides it. */
|
|
211
|
+
--row-level: 0;
|
|
212
|
+
display: flex;
|
|
213
|
+
align-items: center;
|
|
214
|
+
justify-content: flex-end;
|
|
215
|
+
flex-shrink: 0;
|
|
216
|
+
align-self: stretch;
|
|
217
|
+
width: calc((var(--row-level) + 1) * var(--row-indent-step));
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.row-expander .chevron {
|
|
221
|
+
display: flex;
|
|
222
|
+
align-items: center;
|
|
223
|
+
justify-content: center;
|
|
224
|
+
/* Pointer target floor, and the gutter is only one step wide. */
|
|
225
|
+
min-width: var(--row-indent-step);
|
|
226
|
+
min-height: var(--row-indent-step);
|
|
227
|
+
align-self: stretch;
|
|
228
|
+
color: var(--on-flat-neutral-color);
|
|
229
|
+
transition: transform 100ms ease-in-out;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.row-expander .chevron.expanded {
|
|
233
|
+
transform: rotate(90deg);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
@media (prefers-reduced-motion: reduce) {
|
|
237
|
+
.row-expander .chevron {
|
|
238
|
+
transition: none;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
200
242
|
&.large-icon .icon {
|
|
201
243
|
min-width: var(--menu-navigation-components-table-item-icon-size-large);
|
|
202
244
|
min-height: var(
|