@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.152 → 2.0.0-next.153
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/.storybook/vitest.setup.ts +1 -1
- package/bundle/openbridge-webcomponents.bundle.js +4717 -4485
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +374 -52
- package/dist/alert-severity.d.ts +19 -1
- package/dist/alert-severity.d.ts.map +1 -1
- package/dist/alert-severity.js +48 -2
- package/dist/alert-severity.js.map +1 -1
- package/dist/components/alert-button/alert-button.css.js +7 -1513
- package/dist/components/alert-button/alert-button.css.js.map +1 -1
- package/dist/components/alert-button/alert-button.d.ts +40 -96
- package/dist/components/alert-button/alert-button.d.ts.map +1 -1
- package/dist/components/alert-button/alert-button.js +40 -107
- package/dist/components/alert-button/alert-button.js.map +1 -1
- package/dist/components/alert-button-item/alert-button-item.css.js +1570 -0
- package/dist/components/alert-button-item/alert-button-item.css.js.map +1 -0
- package/dist/components/alert-button-item/alert-button-item.d.ts +134 -0
- package/dist/components/alert-button-item/alert-button-item.d.ts.map +1 -0
- package/dist/components/alert-button-item/alert-button-item.js +210 -0
- package/dist/components/alert-button-item/alert-button-item.js.map +1 -0
- package/dist/components/alert-counter-item/alert-counter-item.css.js +25 -0
- package/dist/components/alert-counter-item/alert-counter-item.css.js.map +1 -0
- package/dist/components/alert-counter-item/alert-counter-item.d.ts +77 -0
- package/dist/components/alert-counter-item/alert-counter-item.d.ts.map +1 -0
- package/dist/components/alert-counter-item/alert-counter-item.js +87 -0
- package/dist/components/alert-counter-item/alert-counter-item.js.map +1 -0
- package/dist/components/alert-frame/alert-frame.css.js +23 -27
- package/dist/components/alert-frame/alert-frame.css.js.map +1 -1
- package/dist/components/alert-frame/alert-frame.d.ts +7 -6
- package/dist/components/alert-frame/alert-frame.d.ts.map +1 -1
- package/dist/components/alert-frame/alert-frame.js +6 -9
- package/dist/components/alert-frame/alert-frame.js.map +1 -1
- package/dist/components/tree-navigation-item/tree-navigation-item.d.ts +7 -34
- package/dist/components/tree-navigation-item/tree-navigation-item.d.ts.map +1 -1
- package/dist/components/tree-navigation-item/tree-navigation-item.js +3 -32
- package/dist/components/tree-navigation-item/tree-navigation-item.js.map +1 -1
- package/dist/generated/locales/es-419.d.ts +11 -3
- package/dist/generated/locales/es-419.d.ts.map +1 -1
- package/dist/generated/locales/es-419.js +11 -3
- package/dist/generated/locales/es-419.js.map +1 -1
- package/dist/generated/locales/fi-FI.d.ts +8 -0
- package/dist/generated/locales/fi-FI.d.ts.map +1 -1
- package/dist/generated/locales/fi-FI.js +8 -0
- package/dist/generated/locales/fi-FI.js.map +1 -1
- package/dist/navigation-instruments/readout/readout.css.js +4 -29
- package/dist/navigation-instruments/readout/readout.css.js.map +1 -1
- package/dist/navigation-instruments/readout/readout.d.ts.map +1 -1
- package/dist/navigation-instruments/readout/readout.js +1 -9
- package/dist/navigation-instruments/readout/readout.js.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js +5 -34
- package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.js +1 -9
- package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
- package/dist/palettes/blinking.d.ts +6 -2
- package/dist/palettes/blinking.d.ts.map +1 -1
- package/dist/palettes/blinking.js +6 -2
- package/dist/palettes/blinking.js.map +1 -1
- package/dist/types.d.ts +15 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/alert-severity.spec.ts +81 -2
- package/src/alert-severity.ts +74 -0
- package/src/components/alert-button/alert-button.css +7 -196
- package/src/components/alert-button/alert-button.spec.ts +119 -68
- package/src/components/alert-button/alert-button.stories.ts +24 -0
- package/src/components/alert-button/alert-button.ts +49 -211
- package/src/components/alert-button-item/alert-button-item.css +242 -0
- package/src/components/alert-button-item/alert-button-item.spec.ts +299 -0
- package/src/components/alert-button-item/alert-button-item.stories.ts +178 -0
- package/src/components/alert-button-item/alert-button-item.ts +289 -0
- package/src/components/alert-counter-item/alert-counter-item.css +15 -0
- package/src/components/alert-counter-item/alert-counter-item.spec.ts +91 -0
- package/src/components/alert-counter-item/alert-counter-item.stories.ts +66 -0
- package/src/components/alert-counter-item/alert-counter-item.ts +128 -0
- package/src/components/alert-frame/alert-frame.css +23 -27
- package/src/components/alert-frame/alert-frame.spec.ts +19 -1
- package/src/components/alert-frame/alert-frame.stories.ts +47 -0
- package/src/components/alert-frame/alert-frame.ts +16 -17
- package/src/components/tree-navigation-item/tree-navigation-item.ts +10 -60
- package/src/generated/locales/es-419.ts +11 -3
- package/src/generated/locales/fi-FI.ts +8 -0
- package/src/navigation-instruments/readout/readout.css +4 -29
- package/src/navigation-instruments/readout/readout.ts +1 -9
- package/src/navigation-instruments/readout-list-item/readout-list-item.css +5 -33
- package/src/navigation-instruments/readout-list-item/readout-list-item.ts +1 -9
- package/src/palettes/blinking.spec.ts +38 -23
- package/src/palettes/blinking.ts +12 -4
- package/src/types.ts +16 -0
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import {describe, expect, it} from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
AlertFlashPhase,
|
|
4
|
+
alertCountsLabel,
|
|
5
|
+
alertTypeLabel,
|
|
6
|
+
rankAlertCounts,
|
|
7
|
+
resolveFlashingSpeed,
|
|
8
|
+
} from './alert-severity.js';
|
|
9
|
+
import {
|
|
10
|
+
ALERT_SEVERITY_PRIORITY,
|
|
11
|
+
AlertType,
|
|
12
|
+
FlashingSpeed,
|
|
13
|
+
type AlertCounts,
|
|
14
|
+
} from './types.js';
|
|
4
15
|
|
|
5
16
|
describe('resolveFlashingSpeed', () => {
|
|
6
17
|
it.each([
|
|
@@ -54,3 +65,71 @@ describe('resolveFlashingSpeed', () => {
|
|
|
54
65
|
);
|
|
55
66
|
});
|
|
56
67
|
});
|
|
68
|
+
|
|
69
|
+
describe('rankAlertCounts', () => {
|
|
70
|
+
it('keeps positive counts, most severe first', () => {
|
|
71
|
+
expect(
|
|
72
|
+
rankAlertCounts({
|
|
73
|
+
countCaution: 6,
|
|
74
|
+
countLevelDiagnostic: 1,
|
|
75
|
+
countAlarm: 2,
|
|
76
|
+
countWarning: 0,
|
|
77
|
+
countLevelCritical: 1,
|
|
78
|
+
countLevelLow: -3,
|
|
79
|
+
})
|
|
80
|
+
).toEqual([
|
|
81
|
+
{type: AlertType.LevelCritical, count: 1},
|
|
82
|
+
{type: AlertType.Alarm, count: 2},
|
|
83
|
+
{type: AlertType.Caution, count: 6},
|
|
84
|
+
{type: AlertType.LevelDiagnostic, count: 1},
|
|
85
|
+
]);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('orders every severity by ALERT_SEVERITY_PRIORITY', () => {
|
|
89
|
+
const one: AlertCounts = {
|
|
90
|
+
countLevelDiagnostic: 1,
|
|
91
|
+
countLevelLow: 1,
|
|
92
|
+
countCaution: 1,
|
|
93
|
+
countLevelMedium: 1,
|
|
94
|
+
countWarning: 1,
|
|
95
|
+
countLevelHigh: 1,
|
|
96
|
+
countAlarm: 1,
|
|
97
|
+
countLevelCritical: 1,
|
|
98
|
+
};
|
|
99
|
+
expect(rankAlertCounts(one).map((entry) => entry.type)).toEqual(
|
|
100
|
+
ALERT_SEVERITY_PRIORITY
|
|
101
|
+
);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('combines into the total typed as the most severe present', () => {
|
|
105
|
+
expect(
|
|
106
|
+
rankAlertCounts({countWarning: 4, countCaution: 6, countAlarm: 2}, true)
|
|
107
|
+
).toEqual([{type: AlertType.Alarm, count: 12}]);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('returns nothing when nothing is counted', () => {
|
|
111
|
+
expect(rankAlertCounts({})).toEqual([]);
|
|
112
|
+
expect(rankAlertCounts({countAlarm: 0}, true)).toEqual([]);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe('alertTypeLabel', () => {
|
|
117
|
+
it('names every severity', () => {
|
|
118
|
+
for (const type of Object.values(AlertType)) {
|
|
119
|
+
expect(alertTypeLabel(type)).not.toBe('');
|
|
120
|
+
}
|
|
121
|
+
expect(alertTypeLabel(AlertType.LevelHigh)).toBe('High');
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
describe('alertCountsLabel', () => {
|
|
126
|
+
it('lists the ranked counts, then the shelved count', () => {
|
|
127
|
+
expect(
|
|
128
|
+
alertCountsLabel({countCaution: 6, countAlarm: 2, countWarning: 4}, 9)
|
|
129
|
+
).toBe('2 Alarm, 4 Warning, 6 Caution, 9 Shelved');
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('is empty when nothing is counted', () => {
|
|
133
|
+
expect(alertCountsLabel({})).toBe('');
|
|
134
|
+
});
|
|
135
|
+
});
|
package/src/alert-severity.ts
CHANGED
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
* alarm-style no-ack icon.
|
|
26
26
|
* - Priority: re-exports `ALERT_SEVERITY_PRIORITY`, the ordered severity list
|
|
27
27
|
* (most → least severe) used to sort alerts.
|
|
28
|
+
* - Counts: `rankAlertCounts` orders per-severity counts and can combine
|
|
29
|
+
* them; `alertTypeLabel` and `alertCountsLabel` build accessible names.
|
|
28
30
|
*
|
|
29
31
|
* Usage:
|
|
30
32
|
* ```ts
|
|
@@ -44,10 +46,12 @@
|
|
|
44
46
|
* );
|
|
45
47
|
* ```
|
|
46
48
|
*/
|
|
49
|
+
import {msg} from '@lit/localize';
|
|
47
50
|
import {
|
|
48
51
|
AlertType,
|
|
49
52
|
ALERT_SEVERITY_PRIORITY,
|
|
50
53
|
FlashingSpeed,
|
|
54
|
+
type AlertCounts,
|
|
51
55
|
type ResolvedFlashingSpeed,
|
|
52
56
|
} from './types.js';
|
|
53
57
|
|
|
@@ -234,3 +238,73 @@ export function usesAlarmNoAckIcon(type: AlertType): boolean {
|
|
|
234
238
|
AlertType.LevelHigh,
|
|
235
239
|
].includes(type);
|
|
236
240
|
}
|
|
241
|
+
|
|
242
|
+
/** One severity and its alert count, as `rankAlertCounts` returns them. */
|
|
243
|
+
export interface RankedAlertCount {
|
|
244
|
+
type: AlertType;
|
|
245
|
+
count: number;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const ALERT_COUNT_FIELD: Record<AlertType, keyof AlertCounts> = {
|
|
249
|
+
[AlertType.Alarm]: 'countAlarm',
|
|
250
|
+
[AlertType.Warning]: 'countWarning',
|
|
251
|
+
[AlertType.Caution]: 'countCaution',
|
|
252
|
+
[AlertType.LevelCritical]: 'countLevelCritical',
|
|
253
|
+
[AlertType.LevelHigh]: 'countLevelHigh',
|
|
254
|
+
[AlertType.LevelMedium]: 'countLevelMedium',
|
|
255
|
+
[AlertType.LevelLow]: 'countLevelLow',
|
|
256
|
+
[AlertType.LevelDiagnostic]: 'countLevelDiagnostic',
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* The positive counts, most severe first by `ALERT_SEVERITY_PRIORITY`.
|
|
261
|
+
* `combine` folds them into one entry: the total, typed as the most severe
|
|
262
|
+
* category present.
|
|
263
|
+
*/
|
|
264
|
+
export function rankAlertCounts(
|
|
265
|
+
counts: AlertCounts,
|
|
266
|
+
combine = false
|
|
267
|
+
): RankedAlertCount[] {
|
|
268
|
+
const ranked = ALERT_SEVERITY_PRIORITY.map((type) => ({
|
|
269
|
+
type,
|
|
270
|
+
count: counts[ALERT_COUNT_FIELD[type]] ?? 0,
|
|
271
|
+
})).filter((entry) => entry.count > 0);
|
|
272
|
+
if (!combine || ranked.length === 0) {
|
|
273
|
+
return ranked;
|
|
274
|
+
}
|
|
275
|
+
const total = ranked.reduce((sum, entry) => sum + entry.count, 0);
|
|
276
|
+
return [{type: ranked[0].type, count: total}];
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const ALERT_TYPE_LABEL: Record<AlertType, () => string> = {
|
|
280
|
+
[AlertType.Alarm]: () => msg('Alarm'),
|
|
281
|
+
[AlertType.Warning]: () => msg('Warning'),
|
|
282
|
+
[AlertType.Caution]: () => msg('Caution'),
|
|
283
|
+
[AlertType.LevelCritical]: () => msg('Critical'),
|
|
284
|
+
[AlertType.LevelHigh]: () => msg('High'),
|
|
285
|
+
[AlertType.LevelMedium]: () => msg('Medium'),
|
|
286
|
+
[AlertType.LevelLow]: () => msg('Low'),
|
|
287
|
+
[AlertType.LevelDiagnostic]: () => msg('Diagnostic'),
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
/** Localized severity name, read at render time so a locale switch applies. */
|
|
291
|
+
export function alertTypeLabel(type: AlertType): string {
|
|
292
|
+
return ALERT_TYPE_LABEL[type]();
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Accessible summary of the counts, e.g. "2 Alarm, 4 Warning, 9 Shelved";
|
|
297
|
+
* empty when nothing is counted.
|
|
298
|
+
*/
|
|
299
|
+
export function alertCountsLabel(
|
|
300
|
+
counts: AlertCounts,
|
|
301
|
+
shelvedCount = 0
|
|
302
|
+
): string {
|
|
303
|
+
const parts = rankAlertCounts(counts).map(
|
|
304
|
+
({type, count}) => `${count} ${alertTypeLabel(type)}`
|
|
305
|
+
);
|
|
306
|
+
if (shelvedCount > 0) {
|
|
307
|
+
parts.push(`${shelvedCount} ${msg('Shelved')}`);
|
|
308
|
+
}
|
|
309
|
+
return parts.join(', ');
|
|
310
|
+
}
|
|
@@ -16,8 +16,7 @@
|
|
|
16
16
|
padding-top: var(--app-components-alert-button-tall-padding-vertical);
|
|
17
17
|
padding-bottom: var(--app-components-alert-button-tall-padding-vertical);
|
|
18
18
|
|
|
19
|
-
& .visible-wrapper
|
|
20
|
-
& .blink {
|
|
19
|
+
& .silence-button .visible-wrapper {
|
|
21
20
|
height: 100%;
|
|
22
21
|
}
|
|
23
22
|
}
|
|
@@ -27,6 +26,11 @@
|
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
28
|
|
|
29
|
+
obc-alert-button-item {
|
|
30
|
+
flex-grow: 1; /* the bell takes the width the silence button leaves */
|
|
31
|
+
flex-basis: var(--global-size-spacing-touch-target-min);
|
|
32
|
+
}
|
|
33
|
+
|
|
30
34
|
button {
|
|
31
35
|
appearance: none;
|
|
32
36
|
background: none;
|
|
@@ -46,199 +50,6 @@ button {
|
|
|
46
50
|
height: var(--global-size-spacing-icon-icon-size-regular);
|
|
47
51
|
}
|
|
48
52
|
|
|
49
|
-
.alert-button {
|
|
50
|
-
position: relative;
|
|
51
|
-
display: flex;
|
|
52
|
-
justify-content: center;
|
|
53
|
-
.type-flat & {
|
|
54
|
-
@mixin style style=flat visibleWrapperClass=.visible-wrapper;
|
|
55
|
-
@mixin style style=flat visibleWrapperClass=.blink;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.type-normal & .visible-wrapper,
|
|
59
|
-
.type-enhanced & .visible-wrapper {
|
|
60
|
-
width: 100%;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.type-normal & {
|
|
64
|
-
@mixin style style=normal visibleWrapperClass=.visible-wrapper;
|
|
65
|
-
@mixin style style=normal visibleWrapperClass=.blink;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.type-enhanced.alert-type-alarm & {
|
|
69
|
-
@mixin style style=normal visibleWrapperClass=.blink;
|
|
70
|
-
@mixin style style=alarm visibleWrapperClass=.visible-wrapper;
|
|
71
|
-
& .visible-wrapper {
|
|
72
|
-
color: var(--on-alarm-active-color);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.type-enhanced.alert-type-warning & {
|
|
77
|
-
@mixin style style=normal visibleWrapperClass=.blink;
|
|
78
|
-
@mixin style style=warning visibleWrapperClass=.visible-wrapper;
|
|
79
|
-
& .visible-wrapper {
|
|
80
|
-
color: var(--on-warning-active-color);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.type-enhanced.alert-type-caution & {
|
|
85
|
-
@mixin style style=normal visibleWrapperClass=.blink;
|
|
86
|
-
@mixin style style=caution visibleWrapperClass=.visible-wrapper;
|
|
87
|
-
& .visible-wrapper {
|
|
88
|
-
color: var(--on-caution-active-color);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
.type-enhanced.alert-type-level-critical & {
|
|
93
|
-
@mixin style style=normal visibleWrapperClass=.blink;
|
|
94
|
-
@mixin style style=critical visibleWrapperClass=.visible-wrapper;
|
|
95
|
-
& .visible-wrapper {
|
|
96
|
-
color: var(--on-critical-active-color);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
.type-enhanced.alert-type-level-high & {
|
|
101
|
-
@mixin style style=normal visibleWrapperClass=.blink;
|
|
102
|
-
@mixin style style=alarm visibleWrapperClass=.visible-wrapper;
|
|
103
|
-
& .visible-wrapper {
|
|
104
|
-
color: var(--on-alarm-active-color);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
.type-enhanced.alert-type-level-medium & {
|
|
109
|
-
@mixin style style=normal visibleWrapperClass=.blink;
|
|
110
|
-
@mixin style style=warning visibleWrapperClass=.visible-wrapper;
|
|
111
|
-
& .visible-wrapper {
|
|
112
|
-
color: var(--on-warning-active-color);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
.type-enhanced.alert-type-level-low & {
|
|
117
|
-
@mixin style style=normal visibleWrapperClass=.blink;
|
|
118
|
-
@mixin style style=caution visibleWrapperClass=.visible-wrapper;
|
|
119
|
-
& .visible-wrapper {
|
|
120
|
-
color: var(--on-caution-active-color);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
.type-enhanced.alert-type-level-diagnostic & {
|
|
125
|
-
@mixin style style=normal visibleWrapperClass=.blink;
|
|
126
|
-
@mixin style style=notification visibleWrapperClass=.visible-wrapper;
|
|
127
|
-
& .visible-wrapper {
|
|
128
|
-
color: var(--on-notification-active-color);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
& .visible-wrapper,
|
|
133
|
-
& .blink {
|
|
134
|
-
border-radius: var(--ui-components-button-border-radius-top-left)
|
|
135
|
-
var(--ui-components-button-border-radius-top-right)
|
|
136
|
-
var(--ui-components-button-border-radius-bottom-right)
|
|
137
|
-
var(--ui-components-button-border-radius-bottom-left);
|
|
138
|
-
height: var(--ui-components-icon-button-visual-target-size);
|
|
139
|
-
min-width: var(--ui-components-icon-button-visual-target-size);
|
|
140
|
-
display: flex;
|
|
141
|
-
justify-content: center;
|
|
142
|
-
align-items: center;
|
|
143
|
-
color: var(--on-normal-neutral-color);
|
|
144
|
-
@mixin font-button;
|
|
145
|
-
|
|
146
|
-
.has-silence & {
|
|
147
|
-
border-top-right-radius: 0;
|
|
148
|
-
border-bottom-right-radius: 0;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.type-flat & .visible-wrapper {
|
|
153
|
-
color: var(--on-flat-neutral-color);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
& .blink {
|
|
157
|
-
position: absolute;
|
|
158
|
-
top: 0;
|
|
159
|
-
right: 0;
|
|
160
|
-
bottom: 0;
|
|
161
|
-
left: 0;
|
|
162
|
-
margin: auto;
|
|
163
|
-
|
|
164
|
-
.type-flat & {
|
|
165
|
-
width: min-content;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
.flash-fast .alert-button {
|
|
171
|
-
.visible-wrapper {
|
|
172
|
-
opacity: var(--flash-fast-on);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
.blink {
|
|
176
|
-
opacity: var(--flash-fast-off);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
.flash-slow .alert-button {
|
|
181
|
-
.visible-wrapper {
|
|
182
|
-
opacity: var(--flash-slow-on);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
.blink {
|
|
186
|
-
opacity: var(--flash-slow-off);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
.flash-very-slow .alert-button {
|
|
191
|
-
.visible-wrapper {
|
|
192
|
-
opacity: var(--flash-very-slow-on);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
.blink {
|
|
196
|
-
opacity: var(--flash-very-slow-off);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
.counter .alert-button .visible-wrapper,
|
|
201
|
-
.counter .alert-button .blink {
|
|
202
|
-
padding: 0px var(--ui-components-button-padding-horizontal);
|
|
203
|
-
gap: var(--app-components-alert-button-item-counter-spacing);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
.alert-type-alarm {
|
|
207
|
-
--icon-fill: var(--alarm-enabled-background-color);
|
|
208
|
-
--icon-stroke: var(--alarm-pressed-border-color);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
.alert-type-warning {
|
|
212
|
-
--icon-fill: var(--warning-enabled-background-color);
|
|
213
|
-
--icon-stroke: var(--warning-pressed-border-color);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
.alert-type-caution,
|
|
217
|
-
.alert-type-level-low {
|
|
218
|
-
--icon-fill: var(--caution-enabled-background-color);
|
|
219
|
-
--icon-stroke: var(--caution-pressed-border-color);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
.alert-type-level-critical {
|
|
223
|
-
--icon-fill: var(--alert-critical-color);
|
|
224
|
-
--icon-stroke: var(--alert-critical-outline-color);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
.alert-type-level-high {
|
|
228
|
-
--icon-fill: var(--alarm-enabled-background-color);
|
|
229
|
-
--icon-stroke: var(--alarm-pressed-border-color);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
.alert-type-level-medium {
|
|
233
|
-
--icon-fill: var(--warning-enabled-background-color);
|
|
234
|
-
--icon-stroke: var(--warning-pressed-border-color);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
.alert-type-level-diagnostic {
|
|
238
|
-
--icon-fill: var(--alert-diagnostic-color);
|
|
239
|
-
--icon-stroke: var(--alert-diagnostic-outline-color);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
53
|
.silence-button {
|
|
243
54
|
@mixin style style=normal visibleWrapperClass=.visible-wrapper;
|
|
244
55
|
color: var(--on-normal-neutral-color);
|
|
@@ -248,7 +59,7 @@ button {
|
|
|
248
59
|
height: var(--ui-components-icon-button-visual-target-size);
|
|
249
60
|
border-radius: 0 var(--ui-components-button-border-radius-top-right)
|
|
250
61
|
var(--ui-components-button-border-radius-bottom-right) 0;
|
|
251
|
-
border-left: 0;
|
|
62
|
+
border-left: 0; /* the item's right border is the divider */
|
|
252
63
|
display: flex;
|
|
253
64
|
justify-content: center;
|
|
254
65
|
align-items: center;
|
|
@@ -1,99 +1,150 @@
|
|
|
1
1
|
import {describe, expect, it} from 'vitest';
|
|
2
|
-
import './alert-button.js';
|
|
3
|
-
import {ObcAlertButton} from './alert-button.js';
|
|
4
2
|
import {render} from 'vitest-browser-lit';
|
|
5
|
-
import {html} from 'lit';
|
|
3
|
+
import {html, type TemplateResult} from 'lit';
|
|
4
|
+
import './alert-button.js';
|
|
5
|
+
import {ObcAlertButton, ObcAlertButtonType} from './alert-button.js';
|
|
6
|
+
import type {ObcAlertButtonItem} from '../alert-button-item/alert-button-item.js';
|
|
6
7
|
import {AlertType, FlashingSpeed} from '../../types.js';
|
|
7
8
|
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
.
|
|
11
|
-
.
|
|
9
|
+
async function setup(
|
|
10
|
+
template: TemplateResult = html`<obc-alert-button
|
|
11
|
+
.nAlerts=${3}
|
|
12
|
+
.alertType=${AlertType.Alarm}
|
|
13
|
+
counter
|
|
14
|
+
blinking
|
|
15
|
+
></obc-alert-button>`
|
|
16
|
+
) {
|
|
17
|
+
const screen = render(template);
|
|
18
|
+
const el = screen.container.querySelector(
|
|
19
|
+
'obc-alert-button'
|
|
20
|
+
) as ObcAlertButton;
|
|
21
|
+
await el.updateComplete;
|
|
22
|
+
const item = el.shadowRoot!.querySelector(
|
|
23
|
+
'obc-alert-button-item'
|
|
24
|
+
) as ObcAlertButtonItem;
|
|
25
|
+
await item.updateComplete;
|
|
26
|
+
return {el, item};
|
|
12
27
|
}
|
|
13
28
|
|
|
14
|
-
describe('obc-alert-button
|
|
15
|
-
async
|
|
16
|
-
|
|
17
|
-
Pick<
|
|
18
|
-
ObcAlertButton,
|
|
19
|
-
'nAlerts' | 'alertType' | 'blinking' | 'flashingSpeed'
|
|
20
|
-
>
|
|
21
|
-
> = {}
|
|
22
|
-
) {
|
|
23
|
-
const screen = render(
|
|
29
|
+
describe('obc-alert-button', () => {
|
|
30
|
+
it('forwards the alert state to its item', async () => {
|
|
31
|
+
const {item} = await setup(
|
|
24
32
|
html`<obc-alert-button
|
|
25
|
-
.nAlerts=${
|
|
26
|
-
.alertType=${
|
|
27
|
-
.
|
|
28
|
-
.flashingSpeed=${
|
|
33
|
+
.nAlerts=${3}
|
|
34
|
+
.alertType=${AlertType.Warning}
|
|
35
|
+
.type=${ObcAlertButtonType.Enhanced}
|
|
36
|
+
.flashingSpeed=${FlashingSpeed.Slow}
|
|
37
|
+
counter
|
|
38
|
+
blinking
|
|
39
|
+
large
|
|
29
40
|
></obc-alert-button>`
|
|
30
41
|
);
|
|
31
|
-
const el = screen.container.querySelector(
|
|
32
|
-
'obc-alert-button'
|
|
33
|
-
) as ObcAlertButton;
|
|
34
|
-
await el.updateComplete;
|
|
35
|
-
return el;
|
|
36
|
-
}
|
|
37
42
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
expect([
|
|
44
|
+
item.type,
|
|
45
|
+
item.alertType,
|
|
46
|
+
item.nAlerts,
|
|
47
|
+
item.counter,
|
|
48
|
+
item.blinking,
|
|
49
|
+
item.flashingSpeed,
|
|
50
|
+
item.fillHeight,
|
|
51
|
+
]).toEqual([
|
|
52
|
+
ObcAlertButtonType.Enhanced,
|
|
53
|
+
AlertType.Warning,
|
|
54
|
+
3,
|
|
55
|
+
true,
|
|
56
|
+
true,
|
|
57
|
+
FlashingSpeed.Slow,
|
|
58
|
+
true,
|
|
59
|
+
]);
|
|
43
60
|
});
|
|
44
61
|
|
|
45
|
-
it('
|
|
46
|
-
|
|
47
|
-
|
|
62
|
+
it('forwards the global counter and drops it in flat mode', async () => {
|
|
63
|
+
const counts = {countAlarm: 1, countWarning: 10, countCaution: 15};
|
|
64
|
+
const {el, item} = await setup(
|
|
65
|
+
html`<obc-alert-button
|
|
66
|
+
globalCounter
|
|
67
|
+
.nAlerts=${26}
|
|
68
|
+
.counts=${counts}
|
|
69
|
+
.shelvedCount=${9}
|
|
70
|
+
></obc-alert-button>`
|
|
71
|
+
);
|
|
72
|
+
expect([item.globalCounter, item.counts, item.shelvedCount]).toEqual([
|
|
73
|
+
true,
|
|
74
|
+
counts,
|
|
75
|
+
9,
|
|
48
76
|
]);
|
|
49
|
-
expect(durations(await setup({alertType: AlertType.Caution}))).toEqual([]);
|
|
50
|
-
});
|
|
51
77
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
});
|
|
78
|
+
el.flatMaxBreakpointPx = window.innerWidth + 1;
|
|
79
|
+
await el.updateComplete;
|
|
80
|
+
await item.updateComplete;
|
|
56
81
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
expect(
|
|
62
|
-
durations(await setup({flashingSpeed: FlashingSpeed.Fixed}))
|
|
63
|
-
).toEqual([]);
|
|
82
|
+
expect([item.type, item.globalCounter]).toEqual([
|
|
83
|
+
ObcAlertButtonType.Flat,
|
|
84
|
+
false,
|
|
85
|
+
]);
|
|
64
86
|
});
|
|
65
87
|
|
|
66
|
-
it('
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
88
|
+
it('passes the flat breakpoint on as the item type', async () => {
|
|
89
|
+
const {item} = await setup(
|
|
90
|
+
html`<obc-alert-button
|
|
91
|
+
.nAlerts=${3}
|
|
92
|
+
.flatMaxBreakpointPx=${window.innerWidth + 1}
|
|
93
|
+
></obc-alert-button>`
|
|
94
|
+
);
|
|
70
95
|
|
|
71
|
-
expect(
|
|
96
|
+
expect(item.type).toBe(ObcAlertButtonType.Flat);
|
|
72
97
|
});
|
|
73
98
|
|
|
74
|
-
it('
|
|
75
|
-
const el = await setup();
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
parent.removeChild(el);
|
|
99
|
+
it('flashes through its item', async () => {
|
|
100
|
+
const {el, item} = await setup();
|
|
101
|
+
expect(item.getAnimations()).toHaveLength(1);
|
|
79
102
|
expect(el.getAnimations()).toHaveLength(0);
|
|
80
103
|
|
|
81
|
-
|
|
82
|
-
// again, so this only passes if the controller re-syncs on connect.
|
|
83
|
-
parent.appendChild(el);
|
|
104
|
+
el.blinking = false;
|
|
84
105
|
await el.updateComplete;
|
|
106
|
+
await item.updateComplete;
|
|
85
107
|
|
|
86
|
-
expect(
|
|
108
|
+
expect(item.getAnimations()).toHaveLength(0);
|
|
87
109
|
});
|
|
88
110
|
|
|
89
|
-
it('
|
|
90
|
-
const el = await setup(
|
|
111
|
+
it('joins the item to the silence button', async () => {
|
|
112
|
+
const {el, item} = await setup(
|
|
113
|
+
html`<obc-alert-button
|
|
114
|
+
.nAlerts=${3}
|
|
115
|
+
showSilenceButton
|
|
116
|
+
></obc-alert-button>`
|
|
117
|
+
);
|
|
118
|
+
expect(item.hasAttribute('data-group-item-not-last')).toBe(true);
|
|
91
119
|
|
|
92
|
-
el.
|
|
93
|
-
await el.updateComplete;
|
|
94
|
-
el.counter = true;
|
|
120
|
+
el.showSilenceButton = false;
|
|
95
121
|
await el.updateComplete;
|
|
96
122
|
|
|
97
|
-
expect(
|
|
123
|
+
expect(item.hasAttribute('data-group-item-not-last')).toBe(false);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('fires click-alert when the item is clicked', async () => {
|
|
127
|
+
const {el, item} = await setup();
|
|
128
|
+
let fired = 0;
|
|
129
|
+
el.addEventListener('click-alert', () => fired++);
|
|
130
|
+
|
|
131
|
+
item.shadowRoot!.querySelector('button')!.click();
|
|
132
|
+
|
|
133
|
+
expect(fired).toBe(1);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('names the silence button', async () => {
|
|
137
|
+
const {el} = await setup(
|
|
138
|
+
html`<obc-alert-button
|
|
139
|
+
.nAlerts=${3}
|
|
140
|
+
showSilenceButton
|
|
141
|
+
></obc-alert-button>`
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
expect(
|
|
145
|
+
el
|
|
146
|
+
.shadowRoot!.querySelector('.silence-button')!
|
|
147
|
+
.getAttribute('aria-label')
|
|
148
|
+
).toBe('Silence');
|
|
98
149
|
});
|
|
99
150
|
});
|
|
@@ -31,6 +31,8 @@ const meta: Meta<typeof ObcAlertButton> = {
|
|
|
31
31
|
options: Object.values(FlashingSpeed),
|
|
32
32
|
control: {type: 'select'},
|
|
33
33
|
},
|
|
34
|
+
counts: {control: {type: 'object'}},
|
|
35
|
+
shelvedCount: {control: {type: 'number', min: 0}},
|
|
34
36
|
width: {control: {type: 'range', min: 64, max: 1028, step: 1}},
|
|
35
37
|
},
|
|
36
38
|
decorators: [widthDecorator],
|
|
@@ -254,3 +256,25 @@ export const NormalLevelDiagnostic: Story = {
|
|
|
254
256
|
nAlerts: 1,
|
|
255
257
|
},
|
|
256
258
|
};
|
|
259
|
+
|
|
260
|
+
const GLOBAL_COUNTS = {countAlarm: 1, countWarning: 10, countCaution: 15};
|
|
261
|
+
|
|
262
|
+
export const GlobalCounter: Story = {
|
|
263
|
+
args: {
|
|
264
|
+
globalCounter: true,
|
|
265
|
+
nAlerts: 26,
|
|
266
|
+
counts: GLOBAL_COUNTS,
|
|
267
|
+
width: 168,
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
export const GlobalCounterShelvedSilence: Story = {
|
|
272
|
+
args: {
|
|
273
|
+
globalCounter: true,
|
|
274
|
+
nAlerts: 26,
|
|
275
|
+
counts: GLOBAL_COUNTS,
|
|
276
|
+
shelvedCount: 9,
|
|
277
|
+
showSilenceButton: true,
|
|
278
|
+
width: 244,
|
|
279
|
+
},
|
|
280
|
+
};
|