@oicl/openbridge-webcomponents 2.1.0-next.1 → 2.1.0-next.2

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.
Files changed (55) hide show
  1. package/README.md +1 -0
  2. package/bundle/openbridge-webcomponents.bundle.js +352 -244
  3. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  4. package/custom-elements.json +944 -90
  5. package/dist/building-blocks/alert-list/alert-list-base.d.ts +60 -0
  6. package/dist/building-blocks/alert-list/alert-list-base.d.ts.map +1 -0
  7. package/dist/building-blocks/alert-list/alert-list-base.js +191 -0
  8. package/dist/building-blocks/alert-list/alert-list-base.js.map +1 -0
  9. package/dist/building-blocks/alert-list/alert-list.css.js.map +1 -1
  10. package/dist/building-blocks/alert-list/alert-list.d.ts +13 -26
  11. package/dist/building-blocks/alert-list/alert-list.d.ts.map +1 -1
  12. package/dist/building-blocks/alert-list/alert-list.js +7 -142
  13. package/dist/building-blocks/alert-list/alert-list.js.map +1 -1
  14. package/dist/components/alert-icon/alert-icon.d.ts.map +1 -1
  15. package/dist/components/alert-icon/alert-icon.js +6 -5
  16. package/dist/components/alert-icon/alert-icon.js.map +1 -1
  17. package/dist/components/alert-list-details/alert-list-details.css.js +4 -1
  18. package/dist/components/alert-list-details/alert-list-details.css.js.map +1 -1
  19. package/dist/components/alert-menu/alert-menu.css.js +3 -42
  20. package/dist/components/alert-menu/alert-menu.css.js.map +1 -1
  21. package/dist/components/alert-menu/alert-menu.d.ts +28 -6
  22. package/dist/components/alert-menu/alert-menu.d.ts.map +1 -1
  23. package/dist/components/alert-menu/alert-menu.js +81 -60
  24. package/dist/components/alert-menu/alert-menu.js.map +1 -1
  25. package/dist/components/alert-menu-item/alert-menu-item.d.ts +16 -6
  26. package/dist/components/alert-menu-item/alert-menu-item.d.ts.map +1 -1
  27. package/dist/components/alert-menu-item/alert-menu-item.js +11 -2
  28. package/dist/components/alert-menu-item/alert-menu-item.js.map +1 -1
  29. package/dist/components/number-input-field/number-input-field.css.js +8 -2
  30. package/dist/components/number-input-field/number-input-field.css.js.map +1 -1
  31. package/dist/components/number-input-field/number-input-field.d.ts +15 -1
  32. package/dist/components/number-input-field/number-input-field.d.ts.map +1 -1
  33. package/dist/components/number-input-field/number-input-field.js +38 -44
  34. package/dist/components/number-input-field/number-input-field.js.map +1 -1
  35. package/dist/components/textbox/textbox.css.js +3 -9
  36. package/dist/components/textbox/textbox.css.js.map +1 -1
  37. package/dist/components/textbox/textbox.d.ts +3 -0
  38. package/dist/components/textbox/textbox.d.ts.map +1 -1
  39. package/dist/components/textbox/textbox.js.map +1 -1
  40. package/dist/generated/locales/es-419.d.ts +1 -1
  41. package/dist/generated/locales/es-419.js +1 -1
  42. package/dist/generated/locales/es-419.js.map +1 -1
  43. package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js +2 -1
  44. package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js.map +1 -1
  45. package/dist/pages/alert-detail-page/alert-detail-page.js +1 -1
  46. package/dist/pages/alert-detail-page/alert-detail-page.js.map +1 -1
  47. package/dist/pages/alert-list-page-small/alert-list-page-small-base.d.ts +63 -0
  48. package/dist/pages/alert-list-page-small/alert-list-page-small-base.d.ts.map +1 -0
  49. package/dist/pages/alert-list-page-small/alert-list-page-small-base.js +126 -0
  50. package/dist/pages/alert-list-page-small/alert-list-page-small-base.js.map +1 -0
  51. package/dist/pages/alert-list-page-small/alert-list-page-small.d.ts +12 -15
  52. package/dist/pages/alert-list-page-small/alert-list-page-small.d.ts.map +1 -1
  53. package/dist/pages/alert-list-page-small/alert-list-page-small.js +41 -92
  54. package/dist/pages/alert-list-page-small/alert-list-page-small.js.map +1 -1
  55. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"alert-icon.js","names":[],"sources":["../../../src/components/alert-icon/alert-icon.ts"],"sourcesContent":["import {LitElement, html, css, TemplateResult, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport '../../icons/icon-caution-color-iec.js';\nimport {customElement} from '../../decorator.js';\nimport {\n AlertType,\n FlashingSpeed,\n type ResolvedFlashingSpeed,\n} from '../../types.js';\nimport {\n AlertFlashPhase,\n getBamAlertTypeForBlinking,\n resolveFlashingSpeed,\n} from '../../alert-severity.js';\nimport '../../icons/icon-alarm-badge-outline.js';\nimport '../../icons/icon-warning-badge-outline.js';\nimport '../../icons/icon-caution-badge-outline.js';\nimport '../../icons/icon-alarm-acknowledged-iec.js';\nimport '../../icons/icon-warning-acknowledged-iec.js';\nimport '../../icons/icon-alarm-rectified-iec.js';\nimport '../../icons/icon-warning-rectified-iec.js';\nimport '../../icons/icon-alarm-rectified-outlined.js';\nimport '../../icons/icon-warning-rectified-outlined.js';\nimport '../../icons/icon-alarm-silenced-iec.js';\nimport '../../icons/icon-alarm-silenced-outlined.js';\nimport '../../icons/icon-warning-silenced-iec.js';\nimport '../../icons/icon-warning-silenced-outlined.js';\nimport '../../icons/icon-alarm-unacknowledged-iec.js';\nimport '../../icons/icon-alarm-acknowledged-outlined.js';\nimport '../../icons/icon-warning-unacknowledged-iec.js';\nimport '../../icons/icon-warning-unacknowledged-outlined.js';\n\nimport '../../icons/icon-critical-badge.js';\nimport '../alert-frame/diagnostic-badge.js';\nimport {criticalA, criticalB} from './icons/icon-critical.js';\nimport {\n criticalUnacknowledgedA,\n criticalUnacknowledgedB,\n} from './icons/icon-critical-unacknowledged.js';\nimport {\n criticalSilencedA,\n criticalSilencedB,\n} from './icons/icon-critical-silenced.js';\nimport {\n criticalRectifiedA,\n criticalRectifiedB,\n} from './icons/icon-critical-rectified.js';\nimport {criticalAcknowledged} from './icons/icon-critical-acknowledged.js';\nimport {\n lowUnacknowledgedA,\n lowUnacknowledgedB,\n} from './icons/icon-low-unacknowledged.js';\nimport {lowSilencedA, lowSilencedB} from './icons/icon-low-silenced.js';\nimport {lowRectifiedA, lowRectifiedB} from './icons/icon-low-rectified.js';\nimport {lowAcknowledged} from './icons/icon-low-acknowledged.js';\nimport {FlashingController} from '../../palettes/flashing-controller.js';\n\nenum AlertIconState {\n Silenced = 'silenced',\n Unacknowledged = 'unacknowledged',\n Acknowledged = 'acknowledged',\n Rectified = 'rectified',\n}\n\nenum AlertIconName {\n AlarmSilenced = 'alarm-silenced',\n AlarmUnack = 'alarm-unack',\n AlarmRectified = 'alarm-rectified',\n WarningUnack = 'warning-unack',\n WarningRectified = 'warning-rectified',\n WarningSilenced = 'warning-silenced',\n Critical = 'critical',\n CriticalUnack = 'critical-unack',\n CriticalSilenced = 'critical-silenced',\n CriticalRectified = 'critical-rectified',\n LowUnack = 'low-unack',\n LowSilenced = 'low-silenced',\n LowRectified = 'low-rectified',\n}\n\nconst mapping = {\n [AlertIconName.AlarmSilenced]: {\n a: html`<obi-alarm-silenced-iec usecsscolor></obi-alarm-silenced-iec>`,\n b: html`<obi-alarm-silenced-outlined\n usecsscolor\n ></obi-alarm-silenced-outlined>`,\n },\n [AlertIconName.AlarmUnack]: {\n a: html`<obi-alarm-unacknowledged-iec\n usecsscolor\n ></obi-alarm-unacknowledged-iec>`,\n b: html`<obi-alarm-acknowledged-outlined\n usecsscolor\n ></obi-alarm-acknowledged-outlined>`,\n },\n [AlertIconName.AlarmRectified]: {\n a: html`<obi-alarm-rectified-iec usecsscolor></obi-alarm-rectified-iec>`,\n b: html`<obi-alarm-rectified-outlined\n usecsscolor\n ></obi-alarm-rectified-outlined>`,\n },\n [AlertIconName.WarningUnack]: {\n a: html`<obi-warning-unacknowledged-iec\n usecsscolor\n ></obi-warning-unacknowledged-iec>`,\n b: html`<obi-warning-unacknowledged-outlined\n usecsscolor\n ></obi-warning-unacknowledged-outlined>`,\n },\n [AlertIconName.WarningRectified]: {\n a: html`<obi-warning-rectified-iec\n usecsscolor\n ></obi-warning-rectified-iec>`,\n b: html`<obi-warning-rectified-outlined\n usecsscolor\n ></obi-warning-rectified-outlined>`,\n },\n [AlertIconName.WarningSilenced]: {\n a: html`<obi-warning-silenced-iec usecsscolor></obi-warning-silenced-iec>`,\n b: html`<obi-warning-silenced-outlined\n usecsscolor\n ></obi-warning-silenced-outlined>`,\n },\n [AlertIconName.Critical]: {\n a: criticalA,\n b: criticalB,\n },\n [AlertIconName.CriticalUnack]: {\n a: criticalUnacknowledgedA,\n b: criticalUnacknowledgedB,\n },\n [AlertIconName.CriticalSilenced]: {\n a: criticalSilencedA,\n b: criticalSilencedB,\n },\n [AlertIconName.CriticalRectified]: {\n a: criticalRectifiedA,\n b: criticalRectifiedB,\n },\n [AlertIconName.LowUnack]: {\n a: lowUnacknowledgedA,\n b: lowUnacknowledgedB,\n },\n [AlertIconName.LowSilenced]: {\n a: lowSilencedA,\n b: lowSilencedB,\n },\n [AlertIconName.LowRectified]: {\n a: lowRectifiedA,\n b: lowRectifiedB,\n },\n};\n/**\n * `obc-alert-icon` – Animated alert icon for signaling alarm and warning states.\n *\n * Displays a specialized icon with a blinking effect to visually indicate alert or warning conditions. The icon type is determined by the `name` property, supporting both alarm and warning variants in different states (such as silenced, unacknowledged, or rectified).\n *\n * Appears in notification areas, alert banners, or status panels to draw attention to active or historical alert conditions. The blinking animation helps highlight urgency or status changes without requiring user interaction.\n *\n * ## Features\n * - **Multiple Icon Types:** Supports all alarm and warning types.\n * - **Flashing:** Two SVG layers alternate at the design tempo (fast for critical/alarm/high, slow for warning/medium, very slow for low and for every rectified alert); acknowledged icons are steady.\n * - **Adaptive Styling:** Applies different CSS variables for alarm and warning types to allow for distinct visual cues (e.g., color, blink timing).\n * - **Scalable:** Designed to fit any container size; scales with its parent element.\n *\n * ## Usage Guidelines\n * Use `obc-alert-icon` to visually represent the status of alarms or warnings in notification panels, alert lists, or system status areas. The blinking effect is intended to draw user attention to active or recent alert conditions. Select the appropriate `name` value to match the alert state you wish to indicate.\n *\n * **TODO(designer):** Provide guidance on when to use each icon variant (e.g., when to use \"rectified\" vs. \"silenced\"), and any best practices for icon placement or blink timing.\n *\n * ## Properties\n * - `type` (AlertType): The type of alarm to display.\n * - `status` (AlarmStatus): The status of the alarm to display.\n *\n * ## Best Practices\n * - Only use the blinking alert icon for states that require immediate or prominent user attention.\n * - Ensure the icon is sized appropriately for its context (e.g., 32x32px or 64x64px for status panels).\n * - Avoid using multiple blinking icons in close proximity to prevent visual overload.\n *\n * ## Example\n * ```html\n * <obc-alert-icon .alarmType=${alarm.type} .alarmStatus=${alarm.status}></obc-alert-icon>\n * ```\n *\n * @property flashingSpeed - Flash tempo: `default` resolves from the alert type and state,\n * `fast`, `slow`, `very-slow` force a tempo, `fixed` never flashes. Acknowledged icons are\n * always steady.\n * @availableWhen acknowledged type in [Alarm, Warning, LevelCritical, LevelHigh, LevelMedium, LevelLow]\n * @availableWhen active type in [Alarm, Warning, LevelCritical, LevelHigh, LevelMedium, LevelLow]\n * @stable\n */\n@customElement('obc-alert-icon')\nexport class ObcAlertIcon extends LitElement {\n @property({type: String}) alertType: AlertType = AlertType.Alarm;\n /* @deprecated use `alertType` instead */\n @property({type: String}) type?: AlertType;\n @property({type: Boolean}) acknowledged?: boolean;\n @property({type: Boolean}) active?: boolean;\n @property({type: Boolean}) silenced?: boolean;\n\n @property({type: String}) flashingSpeed: FlashingSpeed =\n FlashingSpeed.Default;\n\n protected readonly flashing = new FlashingController(\n this,\n () => this.resolvedFlashingSpeed\n );\n\n get resolvedFlashingSpeed(): ResolvedFlashingSpeed {\n // Caution and diagnostic have no flashing glyph pair, whatever the speed.\n if (this.acknowledged || !this.icon) {\n return FlashingSpeed.Fixed;\n }\n return resolveFlashingSpeed(\n this.flashingSpeed,\n this._effectiveType,\n this.active === false ? AlertFlashPhase.Rectified : AlertFlashPhase.Active\n );\n }\n\n private get _effectiveType(): AlertType {\n if (this.type) {\n return this.type;\n }\n return this.alertType;\n }\n\n private get bamType(): AlertType {\n return getBamAlertTypeForBlinking(this._effectiveType);\n }\n\n private get _effectiveState(): AlertIconState {\n if (this.active === false) {\n return AlertIconState.Rectified;\n } else if (this.acknowledged) {\n return AlertIconState.Acknowledged;\n } else if (this.silenced) {\n return AlertIconState.Silenced;\n } else if (this.active === true) {\n return AlertIconState.Unacknowledged;\n }\n return AlertIconState.Unacknowledged;\n }\n\n get icon() {\n if (this._effectiveType === AlertType.LevelCritical) {\n switch (this._effectiveState) {\n case AlertIconState.Rectified:\n return mapping[AlertIconName.CriticalRectified];\n case AlertIconState.Silenced:\n return mapping[AlertIconName.CriticalSilenced];\n case AlertIconState.Unacknowledged:\n return mapping[AlertIconName.CriticalUnack];\n default:\n return mapping[AlertIconName.Critical];\n }\n } else if (this._effectiveType === AlertType.LevelLow) {\n switch (this._effectiveState) {\n case AlertIconState.Rectified:\n return mapping[AlertIconName.LowRectified];\n case AlertIconState.Silenced:\n return mapping[AlertIconName.LowSilenced];\n case AlertIconState.Unacknowledged:\n return mapping[AlertIconName.LowUnack];\n default:\n return mapping[AlertIconName.LowUnack];\n }\n } else if (this.bamType === AlertType.Alarm) {\n switch (this._effectiveState) {\n case AlertIconState.Rectified:\n return mapping[AlertIconName.AlarmRectified];\n case AlertIconState.Silenced:\n return mapping[AlertIconName.AlarmSilenced];\n case AlertIconState.Unacknowledged:\n return mapping[AlertIconName.AlarmUnack];\n default:\n return null;\n }\n } else if (this.bamType === AlertType.Warning) {\n if (this.active === false) {\n return mapping[AlertIconName.WarningRectified];\n } else if (this.acknowledged) {\n return mapping[AlertIconName.WarningSilenced];\n } else {\n return mapping[AlertIconName.WarningUnack];\n }\n }\n\n return null;\n }\n\n private renderStaticIcon(): TemplateResult | typeof nothing {\n // Caution and diagnostic always show a fixed symbol, regardless of state.\n if (this._effectiveType === AlertType.Caution) {\n return html`<obi-caution-color-iec usecsscolor></obi-caution-color-iec>`;\n }\n if (this._effectiveType === AlertType.LevelDiagnostic) {\n return html`<obi-diagnostic-badge\n style=\"color: var(--alert-diagnostic-color);\"\n ></obi-diagnostic-badge>`;\n }\n if (this._effectiveState === AlertIconState.Acknowledged) {\n if (this._effectiveType === AlertType.LevelCritical) {\n return html`${criticalAcknowledged}`;\n }\n if (this._effectiveType === AlertType.LevelLow) {\n return html`${lowAcknowledged}`;\n }\n switch (this.bamType) {\n case AlertType.Alarm:\n return html`<obi-alarm-acknowledged-iec\n usecsscolor\n ></obi-alarm-acknowledged-iec>`;\n case AlertType.Warning:\n return html`<obi-warning-acknowledged-iec\n usecsscolor\n ></obi-warning-acknowledged-iec>`;\n default:\n return nothing;\n }\n } else if (this._effectiveState === AlertIconState.Rectified) {\n if (this._effectiveType === AlertType.LevelCritical) {\n return html`${criticalRectifiedB}`;\n }\n if (this._effectiveType === AlertType.LevelLow) {\n return html`${lowRectifiedB}`;\n }\n switch (this.bamType) {\n case AlertType.Alarm:\n return html`<obi-alarm-rectified-outlined\n usecsscolor\n ></obi-alarm-rectified-outlined>`;\n case AlertType.Warning:\n return html`<obi-warning-rectified-outlined\n usecsscolor\n ></obi-warning-rectified-outlined>`;\n default:\n return nothing;\n }\n }\n return nothing;\n }\n\n override render() {\n if (!this._effectiveType) {\n return html`<div>No alarm</div>`;\n }\n const tempo = this.resolvedFlashingSpeed;\n const icons = this.icon;\n if (tempo !== FlashingSpeed.Fixed && icons) {\n return html`\n <div class=${classMap({wrapper: true, [`flash-${tempo}`]: true})}>\n <span class=\"a\">${icons.a}</span>\n <span class=\"b\">${icons.b}</span>\n </div>\n `;\n }\n return html`<div class=\"wrapper\">${this.renderStaticIcon()}</div>`;\n }\n\n static override styles = css`\n .wrapper {\n height: 100%;\n width: 100%;\n position: relative;\n\n obi-diagnostic-badge,\n obi-critical-badge {\n display: block;\n height: 100%;\n width: 100%;\n position: absolute;\n top: 0;\n left: 0;\n }\n\n svg,\n .a,\n .b {\n height: 100%;\n width: 100%;\n position: absolute;\n top: 0;\n left: 0;\n }\n &.flash-fast .a {\n opacity: var(--flash-fast-on);\n }\n\n &.flash-fast .b {\n opacity: var(--flash-fast-off);\n }\n\n &.flash-slow .a {\n opacity: var(--flash-slow-on);\n }\n\n &.flash-slow .b {\n opacity: var(--flash-slow-off);\n }\n\n &.flash-very-slow .a {\n opacity: var(--flash-very-slow-on);\n }\n\n &.flash-very-slow .b {\n opacity: var(--flash-very-slow-off);\n }\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-alert-icon': ObcAlertIcon;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"alert-icon.js","names":[],"sources":["../../../src/components/alert-icon/alert-icon.ts"],"sourcesContent":["import {LitElement, html, css, TemplateResult, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport '../../icons/icon-caution-color-iec.js';\nimport {customElement} from '../../decorator.js';\nimport {\n AlertType,\n FlashingSpeed,\n type ResolvedFlashingSpeed,\n} from '../../types.js';\nimport {\n AlertFlashPhase,\n getBamAlertTypeForBlinking,\n resolveFlashingSpeed,\n} from '../../alert-severity.js';\nimport '../../icons/icon-alarm-badge-outline.js';\nimport '../../icons/icon-warning-badge-outline.js';\nimport '../../icons/icon-caution-badge-outline.js';\nimport '../../icons/icon-alarm-acknowledged-iec.js';\nimport '../../icons/icon-warning-acknowledged-iec.js';\nimport '../../icons/icon-alarm-rectified-iec.js';\nimport '../../icons/icon-warning-rectified-iec.js';\nimport '../../icons/icon-alarm-rectified-outlined.js';\nimport '../../icons/icon-warning-rectified-outlined.js';\nimport '../../icons/icon-alarm-silenced-iec.js';\nimport '../../icons/icon-alarm-silenced-outlined.js';\nimport '../../icons/icon-warning-silenced-iec.js';\nimport '../../icons/icon-warning-silenced-outlined.js';\nimport '../../icons/icon-alarm-unacknowledged-iec.js';\nimport '../../icons/icon-alarm-acknowledged-outlined.js';\nimport '../../icons/icon-warning-unacknowledged-iec.js';\nimport '../../icons/icon-warning-unacknowledged-outlined.js';\n\nimport '../../icons/icon-critical-badge.js';\nimport '../alert-frame/diagnostic-badge.js';\nimport {criticalA, criticalB} from './icons/icon-critical.js';\nimport {\n criticalUnacknowledgedA,\n criticalUnacknowledgedB,\n} from './icons/icon-critical-unacknowledged.js';\nimport {\n criticalSilencedA,\n criticalSilencedB,\n} from './icons/icon-critical-silenced.js';\nimport {\n criticalRectifiedA,\n criticalRectifiedB,\n} from './icons/icon-critical-rectified.js';\nimport {criticalAcknowledged} from './icons/icon-critical-acknowledged.js';\nimport {\n lowUnacknowledgedA,\n lowUnacknowledgedB,\n} from './icons/icon-low-unacknowledged.js';\nimport {lowSilencedA, lowSilencedB} from './icons/icon-low-silenced.js';\nimport {lowRectifiedA, lowRectifiedB} from './icons/icon-low-rectified.js';\nimport {lowAcknowledged} from './icons/icon-low-acknowledged.js';\nimport {FlashingController} from '../../palettes/flashing-controller.js';\n\nenum AlertIconState {\n Silenced = 'silenced',\n Unacknowledged = 'unacknowledged',\n Acknowledged = 'acknowledged',\n Rectified = 'rectified',\n}\n\nenum AlertIconName {\n AlarmSilenced = 'alarm-silenced',\n AlarmUnack = 'alarm-unack',\n AlarmRectified = 'alarm-rectified',\n WarningUnack = 'warning-unack',\n WarningRectified = 'warning-rectified',\n WarningSilenced = 'warning-silenced',\n Critical = 'critical',\n CriticalUnack = 'critical-unack',\n CriticalSilenced = 'critical-silenced',\n CriticalRectified = 'critical-rectified',\n LowUnack = 'low-unack',\n LowSilenced = 'low-silenced',\n LowRectified = 'low-rectified',\n}\n\nconst mapping = {\n [AlertIconName.AlarmSilenced]: {\n a: html`<obi-alarm-silenced-iec usecsscolor></obi-alarm-silenced-iec>`,\n b: html`<obi-alarm-silenced-outlined\n usecsscolor\n ></obi-alarm-silenced-outlined>`,\n },\n [AlertIconName.AlarmUnack]: {\n a: html`<obi-alarm-unacknowledged-iec\n usecsscolor\n ></obi-alarm-unacknowledged-iec>`,\n b: html`<obi-alarm-acknowledged-outlined\n usecsscolor\n ></obi-alarm-acknowledged-outlined>`,\n },\n [AlertIconName.AlarmRectified]: {\n a: html`<obi-alarm-rectified-iec usecsscolor></obi-alarm-rectified-iec>`,\n b: html`<obi-alarm-rectified-outlined\n usecsscolor\n ></obi-alarm-rectified-outlined>`,\n },\n [AlertIconName.WarningUnack]: {\n a: html`<obi-warning-unacknowledged-iec\n usecsscolor\n ></obi-warning-unacknowledged-iec>`,\n b: html`<obi-warning-unacknowledged-outlined\n usecsscolor\n ></obi-warning-unacknowledged-outlined>`,\n },\n [AlertIconName.WarningRectified]: {\n a: html`<obi-warning-rectified-iec\n usecsscolor\n ></obi-warning-rectified-iec>`,\n b: html`<obi-warning-rectified-outlined\n usecsscolor\n ></obi-warning-rectified-outlined>`,\n },\n [AlertIconName.WarningSilenced]: {\n a: html`<obi-warning-silenced-iec usecsscolor></obi-warning-silenced-iec>`,\n b: html`<obi-warning-silenced-outlined\n usecsscolor\n ></obi-warning-silenced-outlined>`,\n },\n [AlertIconName.Critical]: {\n a: criticalA,\n b: criticalB,\n },\n [AlertIconName.CriticalUnack]: {\n a: criticalUnacknowledgedA,\n b: criticalUnacknowledgedB,\n },\n [AlertIconName.CriticalSilenced]: {\n a: criticalSilencedA,\n b: criticalSilencedB,\n },\n [AlertIconName.CriticalRectified]: {\n a: criticalRectifiedA,\n b: criticalRectifiedB,\n },\n [AlertIconName.LowUnack]: {\n a: lowUnacknowledgedA,\n b: lowUnacknowledgedB,\n },\n [AlertIconName.LowSilenced]: {\n a: lowSilencedA,\n b: lowSilencedB,\n },\n [AlertIconName.LowRectified]: {\n a: lowRectifiedA,\n b: lowRectifiedB,\n },\n};\n/**\n * `obc-alert-icon` – Animated alert icon for signaling alarm and warning states.\n *\n * Displays a specialized icon with a blinking effect to visually indicate alert or warning conditions. The icon type is determined by the `name` property, supporting both alarm and warning variants in different states (such as silenced, unacknowledged, or rectified).\n *\n * Appears in notification areas, alert banners, or status panels to draw attention to active or historical alert conditions. The blinking animation helps highlight urgency or status changes without requiring user interaction.\n *\n * ## Features\n * - **Multiple Icon Types:** Supports all alarm and warning types.\n * - **Flashing:** Two SVG layers alternate at the design tempo (fast for critical/alarm/high, slow for warning/medium, very slow for low and for every rectified alert); acknowledged icons are steady.\n * - **Adaptive Styling:** Applies different CSS variables for alarm and warning types to allow for distinct visual cues (e.g., color, blink timing).\n * - **Scalable:** Designed to fit any container size; scales with its parent element.\n *\n * ## Usage Guidelines\n * Use `obc-alert-icon` to visually represent the status of alarms or warnings in notification panels, alert lists, or system status areas. The blinking effect is intended to draw user attention to active or recent alert conditions. Select the appropriate `name` value to match the alert state you wish to indicate.\n *\n * **TODO(designer):** Provide guidance on when to use each icon variant (e.g., when to use \"rectified\" vs. \"silenced\"), and any best practices for icon placement or blink timing.\n *\n * ## Properties\n * - `type` (AlertType): The type of alarm to display.\n * - `status` (AlarmStatus): The status of the alarm to display.\n *\n * ## Best Practices\n * - Only use the blinking alert icon for states that require immediate or prominent user attention.\n * - Ensure the icon is sized appropriately for its context (e.g., 32x32px or 64x64px for status panels).\n * - Avoid using multiple blinking icons in close proximity to prevent visual overload.\n *\n * ## Example\n * ```html\n * <obc-alert-icon .alarmType=${alarm.type} .alarmStatus=${alarm.status}></obc-alert-icon>\n * ```\n *\n * @property flashingSpeed - Flash tempo: `default` resolves from the alert type and state,\n * `fast`, `slow`, `very-slow` force a tempo, `fixed` never flashes. Acknowledged icons are\n * always steady.\n * @availableWhen acknowledged type in [Alarm, Warning, LevelCritical, LevelHigh, LevelMedium, LevelLow]\n * @availableWhen active type in [Alarm, Warning, LevelCritical, LevelHigh, LevelMedium, LevelLow]\n * @stable\n */\n@customElement('obc-alert-icon')\nexport class ObcAlertIcon extends LitElement {\n @property({type: String}) alertType: AlertType = AlertType.Alarm;\n /* @deprecated use `alertType` instead */\n @property({type: String}) type?: AlertType;\n @property({type: Boolean}) acknowledged?: boolean;\n @property({type: Boolean}) active?: boolean;\n @property({type: Boolean}) silenced?: boolean;\n\n @property({type: String}) flashingSpeed: FlashingSpeed =\n FlashingSpeed.Default;\n\n protected readonly flashing = new FlashingController(\n this,\n () => this.resolvedFlashingSpeed\n );\n\n get resolvedFlashingSpeed(): ResolvedFlashingSpeed {\n // Caution and diagnostic have no flashing glyph pair, whatever the speed.\n if (this.acknowledged || !this.icon) {\n return FlashingSpeed.Fixed;\n }\n return resolveFlashingSpeed(\n this.flashingSpeed,\n this._effectiveType,\n this.active === false ? AlertFlashPhase.Rectified : AlertFlashPhase.Active\n );\n }\n\n private get _effectiveType(): AlertType {\n if (this.type) {\n return this.type;\n }\n return this.alertType;\n }\n\n private get bamType(): AlertType {\n return getBamAlertTypeForBlinking(this._effectiveType);\n }\n\n private get _effectiveState(): AlertIconState {\n if (this.active === false) {\n return AlertIconState.Rectified;\n } else if (this.acknowledged) {\n return AlertIconState.Acknowledged;\n } else if (this.silenced) {\n return AlertIconState.Silenced;\n } else if (this.active === true) {\n return AlertIconState.Unacknowledged;\n }\n return AlertIconState.Unacknowledged;\n }\n\n get icon() {\n if (this._effectiveType === AlertType.LevelCritical) {\n switch (this._effectiveState) {\n case AlertIconState.Rectified:\n return mapping[AlertIconName.CriticalRectified];\n case AlertIconState.Silenced:\n return mapping[AlertIconName.CriticalSilenced];\n case AlertIconState.Unacknowledged:\n return mapping[AlertIconName.CriticalUnack];\n default:\n return mapping[AlertIconName.Critical];\n }\n } else if (this._effectiveType === AlertType.LevelLow) {\n switch (this._effectiveState) {\n case AlertIconState.Rectified:\n return mapping[AlertIconName.LowRectified];\n case AlertIconState.Silenced:\n return mapping[AlertIconName.LowSilenced];\n case AlertIconState.Unacknowledged:\n return mapping[AlertIconName.LowUnack];\n default:\n return mapping[AlertIconName.LowUnack];\n }\n } else if (this.bamType === AlertType.Alarm) {\n switch (this._effectiveState) {\n case AlertIconState.Rectified:\n return mapping[AlertIconName.AlarmRectified];\n case AlertIconState.Silenced:\n return mapping[AlertIconName.AlarmSilenced];\n case AlertIconState.Unacknowledged:\n return mapping[AlertIconName.AlarmUnack];\n default:\n return null;\n }\n } else if (this.bamType === AlertType.Warning) {\n switch (this._effectiveState) {\n case AlertIconState.Rectified:\n return mapping[AlertIconName.WarningRectified];\n case AlertIconState.Silenced:\n return mapping[AlertIconName.WarningSilenced];\n case AlertIconState.Unacknowledged:\n return mapping[AlertIconName.WarningUnack];\n default:\n return null;\n }\n }\n\n return null;\n }\n\n private renderStaticIcon(): TemplateResult | typeof nothing {\n // Caution and diagnostic always show a fixed symbol, regardless of state.\n if (this._effectiveType === AlertType.Caution) {\n return html`<obi-caution-color-iec usecsscolor></obi-caution-color-iec>`;\n }\n if (this._effectiveType === AlertType.LevelDiagnostic) {\n return html`<obi-diagnostic-badge\n style=\"color: var(--alert-diagnostic-color);\"\n ></obi-diagnostic-badge>`;\n }\n if (this._effectiveState === AlertIconState.Acknowledged) {\n if (this._effectiveType === AlertType.LevelCritical) {\n return html`${criticalAcknowledged}`;\n }\n if (this._effectiveType === AlertType.LevelLow) {\n return html`${lowAcknowledged}`;\n }\n switch (this.bamType) {\n case AlertType.Alarm:\n return html`<obi-alarm-acknowledged-iec\n usecsscolor\n ></obi-alarm-acknowledged-iec>`;\n case AlertType.Warning:\n return html`<obi-warning-acknowledged-iec\n usecsscolor\n ></obi-warning-acknowledged-iec>`;\n default:\n return nothing;\n }\n } else if (this._effectiveState === AlertIconState.Rectified) {\n if (this._effectiveType === AlertType.LevelCritical) {\n return html`${criticalRectifiedB}`;\n }\n if (this._effectiveType === AlertType.LevelLow) {\n return html`${lowRectifiedB}`;\n }\n switch (this.bamType) {\n case AlertType.Alarm:\n return html`<obi-alarm-rectified-outlined\n usecsscolor\n ></obi-alarm-rectified-outlined>`;\n case AlertType.Warning:\n return html`<obi-warning-rectified-outlined\n usecsscolor\n ></obi-warning-rectified-outlined>`;\n default:\n return nothing;\n }\n }\n // Steady but still owed an ACK, such as with a `fixed` flashing speed.\n return this.icon ? html`${this.icon.a}` : nothing;\n }\n\n override render() {\n if (!this._effectiveType) {\n return html`<div>No alarm</div>`;\n }\n const tempo = this.resolvedFlashingSpeed;\n const icons = this.icon;\n if (tempo !== FlashingSpeed.Fixed && icons) {\n return html`\n <div class=${classMap({wrapper: true, [`flash-${tempo}`]: true})}>\n <span class=\"a\">${icons.a}</span>\n <span class=\"b\">${icons.b}</span>\n </div>\n `;\n }\n return html`<div class=\"wrapper\">${this.renderStaticIcon()}</div>`;\n }\n\n static override styles = css`\n .wrapper {\n height: 100%;\n width: 100%;\n position: relative;\n\n obi-diagnostic-badge,\n obi-critical-badge {\n display: block;\n height: 100%;\n width: 100%;\n position: absolute;\n top: 0;\n left: 0;\n }\n\n svg,\n .a,\n .b {\n height: 100%;\n width: 100%;\n position: absolute;\n top: 0;\n left: 0;\n }\n &.flash-fast .a {\n opacity: var(--flash-fast-on);\n }\n\n &.flash-fast .b {\n opacity: var(--flash-fast-off);\n }\n\n &.flash-slow .a {\n opacity: var(--flash-slow-on);\n }\n\n &.flash-slow .b {\n opacity: var(--flash-slow-off);\n }\n\n &.flash-very-slow .a {\n opacity: var(--flash-very-slow-on);\n }\n\n &.flash-very-slow .b {\n opacity: var(--flash-very-slow-off);\n }\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-alert-icon': ObcAlertIcon;\n }\n}\n"],"mappings":"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"}
@@ -60,7 +60,6 @@ obc-table::part(grid) {
60
60
  .empty-list .icon {
61
61
  height: 96px;
62
62
  width: 96px;
63
- color: var(--on-flat-neutral-color);
64
63
  }
65
64
 
66
65
  .empty-list .empty-title {
@@ -88,6 +87,10 @@ obc-table::part(grid) {
88
87
  max-width: 344px;
89
88
  text-align: center;
90
89
  }
90
+
91
+ .empty-list .icon {
92
+ color: var(--on-flat-neutral-color);
93
+ }
91
94
  `;
92
95
  //#endregion
93
96
  export { alert_list_details_default as default };
@@ -1 +1 @@
1
- {"version":3,"file":"alert-list-details.css.js","names":[],"sources":["../../../src/components/alert-list-details/alert-list-details.css?inline"],"sourcesContent":[".wrapper {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n user-select: none;\n}\n\n.alert-list {\n min-height: 0;\n flex-grow: 0;\n}\n\n.spacer {\n flex-grow: 1;\n}\n\n.action {\n display: flex;\n height: var(--app-components-tool-bar-touch-target-size);\n padding: 0px var(--app-components-alert-toolbar-margin-horizontal);\n justify-content: space-between;\n align-items: center;\n flex-shrink: 0;\n flex-grow: 0;\n border-top: 1px solid var(--border-divider-color);\n background: var(--container-section-color);\n box-shadow: var(--shadow-flat);\n\n .btn-group {\n display: flex;\n }\n}\n\nobc-table::part(grid) {\n grid-template-columns: 1fr repeat(4, min-content);\n}\n\n.wrapper.small obc-table::part(grid) {\n grid-template-columns: 1fr min-content var(\n --app-components-alert-table-row-ack-container-width-small\n );\n}\n\n.empty-list {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n gap: var(--app-components-alert-menu-button-spacing);\n\n .icon {\n height: 96px;\n width: 96px;\n color: var(--on-flat-neutral-color);\n }\n\n .empty-title {\n color: var(--element-active-color);\n @mixin font-body-active;\n }\n\n .empty-description {\n color: var(--element-neutral-color);\n @mixin font-body;\n max-width: 344px;\n text-align: center;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"alert-list-details.css.js","names":[],"sources":["../../../src/components/alert-list-details/alert-list-details.css?inline"],"sourcesContent":[".wrapper {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n user-select: none;\n}\n\n.alert-list {\n min-height: 0;\n flex-grow: 0;\n}\n\n.spacer {\n flex-grow: 1;\n}\n\n.action {\n display: flex;\n height: var(--app-components-tool-bar-touch-target-size);\n padding: 0px var(--app-components-alert-toolbar-margin-horizontal);\n justify-content: space-between;\n align-items: center;\n flex-shrink: 0;\n flex-grow: 0;\n border-top: 1px solid var(--border-divider-color);\n background: var(--container-section-color);\n box-shadow: var(--shadow-flat);\n\n .btn-group {\n display: flex;\n }\n}\n\nobc-table::part(grid) {\n grid-template-columns: 1fr repeat(4, min-content);\n}\n\n.wrapper.small obc-table::part(grid) {\n grid-template-columns: 1fr min-content var(\n --app-components-alert-table-row-ack-container-width-small\n );\n}\n\n.empty-list {\n @mixin alert-list-empty;\n\n .icon {\n color: var(--on-flat-neutral-color);\n }\n}\n"],"mappings":""}
@@ -77,52 +77,13 @@ var alert_menu_default = css`* {
77
77
  min-width: 120px;
78
78
  }
79
79
 
80
- .empty-list {
81
- display: flex;
82
- flex-direction: column;
83
- align-items: center;
84
- justify-content: center;
85
- height: 100%;
86
- gap: var(--app-components-alert-menu-button-spacing);
87
- }
88
-
89
- .empty-list .icon {
90
- height: 96px;
91
- width: 96px;
92
- }
93
-
94
- .empty-list .empty-title {
95
- color: var(--element-active-color);
96
- font-family: var(--global-typography-font-family);
97
- font-weight: var(--global-typography-ui-body-active-font-weight);
98
- font-size: var(--global-typography-ui-body-active-font-size);
99
- line-height: var(--global-typography-ui-body-active-line-height);
100
- font-feature-settings:
101
- "liga" off,
102
- "clig" off,
103
- "ss04" on;
104
- }
105
-
106
- .empty-list .empty-description {
107
- color: var(--element-neutral-color);
108
- font-family: var(--global-typography-font-family);
109
- font-weight: var(--global-typography-ui-body-font-weight);
110
- font-size: var(--global-typography-ui-body-font-size);
111
- line-height: var(--global-typography-ui-body-line-height);
112
- font-feature-settings:
113
- "liga" off,
114
- "clig" off,
115
- "ss04" on;
116
- max-width: 344px;
117
- text-align: center;
118
- }
119
-
120
80
  ::slotted(*) {
121
81
  display: block;
122
82
  will-change: transform;
123
83
  }
124
84
 
125
- .alert-list.all ::slotted([shelved]) {
85
+ .alert-list.all ::slotted([shelved]),
86
+ .alert-list.all ::slotted([status="rectified-unacknowledged"]) {
126
87
  display: none;
127
88
  }
128
89
 
@@ -130,7 +91,7 @@ var alert_menu_default = css`* {
130
91
  display: none;
131
92
  }
132
93
 
133
- .alert-list.unacked ::slotted(:not([status="unacknowledged"])),.alert-list.unacked ::slotted([shelved]) {
94
+ .alert-list.unacked ::slotted(:not([status="unacknowledged"]):not([status="rectified-unacknowledged"])),.alert-list.unacked ::slotted([shelved]) {
134
95
  display: none;
135
96
  }
136
97
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"alert-menu.css.js","names":[],"sources":["../../../src/components/alert-menu/alert-menu.css?inline"],"sourcesContent":["@mixin soft-dismiss;\n\n* {\n box-sizing: border-box;\n}\n\n.wrapper {\n width: var(--app-components-alert-menu-width);\n height: 560px;\n max-width: 100vw;\n}\n\n.container {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.alert-list {\n flex-shrink: 1;\n flex-grow: 1;\n min-height: 0;\n overflow: hidden;\n position: relative;\n}\n\n.action {\n display: flex;\n min-height: var(--app-components-alert-menu-footer-container-height);\n padding: calc(\n (\n var(--app-components-alert-menu-footer-container-height) -\n var(--ui-components-button-touch-target-size) - 2px\n ) /\n 2\n )\n var(--app-components-alert-menu-footer-padding-horizontal);\n align-items: center;\n gap: var(--app-components-alert-menu-button-spacing);\n flex-shrink: 0;\n flex-wrap: wrap;\n align-self: stretch;\n border-top: 1px solid var(--border-divider-color);\n background: var(--container-global-color);\n\n obc-button::part(visible-wrapper) {\n height: 100%;\n }\n\n .btn {\n flex: 1;\n min-width: 120px;\n }\n}\n\n.empty-list {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n gap: var(--app-components-alert-menu-button-spacing);\n\n .icon {\n height: 96px;\n width: 96px;\n }\n\n .empty-title {\n color: var(--element-active-color);\n @mixin font-body-active;\n }\n\n .empty-description {\n color: var(--element-neutral-color);\n @mixin font-body;\n max-width: 344px;\n text-align: center;\n }\n}\n\n::slotted(*) {\n display: block;\n will-change: transform;\n}\n\n.alert-list.all ::slotted([shelved]) {\n display: none;\n}\n\n.alert-list.shelved ::slotted(:not([shelved])) {\n display: none;\n}\n\n.alert-list.unacked {\n ::slotted(:not([status=\"unacknowledged\"])),\n ::slotted([shelved]) {\n display: none;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"alert-menu.css.js","names":[],"sources":["../../../src/components/alert-menu/alert-menu.css?inline"],"sourcesContent":["@mixin soft-dismiss;\n\n* {\n box-sizing: border-box;\n}\n\n.wrapper {\n width: var(--app-components-alert-menu-width);\n height: 560px;\n max-width: 100vw;\n}\n\n.container {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.alert-list {\n flex-shrink: 1;\n flex-grow: 1;\n min-height: 0;\n overflow: hidden;\n position: relative;\n}\n\n.action {\n display: flex;\n min-height: var(--app-components-alert-menu-footer-container-height);\n padding: calc(\n (\n var(--app-components-alert-menu-footer-container-height) -\n var(--ui-components-button-touch-target-size) - 2px\n ) /\n 2\n )\n var(--app-components-alert-menu-footer-padding-horizontal);\n align-items: center;\n gap: var(--app-components-alert-menu-button-spacing);\n flex-shrink: 0;\n flex-wrap: wrap;\n align-self: stretch;\n border-top: 1px solid var(--border-divider-color);\n background: var(--container-global-color);\n\n obc-button::part(visible-wrapper) {\n height: 100%;\n }\n\n .btn {\n flex: 1;\n min-width: 120px;\n }\n}\n\n::slotted(*) {\n display: block;\n will-change: transform;\n}\n\n.alert-list.all ::slotted([shelved]),\n.alert-list.all ::slotted([status=\"rectified-unacknowledged\"]) {\n display: none;\n}\n\n.alert-list.shelved ::slotted(:not([shelved])) {\n display: none;\n}\n\n.alert-list.unacked {\n ::slotted(\n :not([status=\"unacknowledged\"]):not([status=\"rectified-unacknowledged\"])\n ),\n ::slotted([shelved]) {\n display: none;\n }\n}\n"],"mappings":""}
@@ -1,4 +1,4 @@
1
- import { LitElement } from 'lit';
1
+ import { CSSResultGroup, LitElement, PropertyValues, TemplateResult } from 'lit';
2
2
  import { PopoverController } from '../../internal/popover-controller.js';
3
3
  import '../button/button.js';
4
4
  import '../../icons/icon-chevron-right-google.js';
@@ -16,6 +16,14 @@ export type ObcAckAllVisibleClickEvent = CustomEvent<{
16
16
  }[];
17
17
  tabName: 'shelved' | 'unacked' | 'all';
18
18
  }>;
19
+ /** One tab of an alert menu: its name, its label and its empty state. */
20
+ export interface AlertMenuTab {
21
+ /** Names the tab in `ack-all-visible-click` and in the `empty-<tab>-*` slots. */
22
+ name: string;
23
+ title: string;
24
+ emptyTitle: string;
25
+ emptyIcon: TemplateResult;
26
+ }
19
27
  /**
20
28
  * `<obc-alert-menu>` – A tabbed alert summary panel for displaying, acknowledging, and managing active alerts.
21
29
  *
@@ -23,7 +31,7 @@ export type ObcAckAllVisibleClickEvent = CustomEvent<{
23
31
  *
24
32
  * ### Features
25
33
  * - **Tabbed organization:** Switch between "Unacked", "Active", and (optionally) "Shelved" tabs for focused alert review.
26
- * - **Alert filtering:** Each tab displays only relevant alerts (e.g., "Unacked" shows only unacknowledged, non-shelved items).
34
+ * - **Alert filtering:** Each tab displays only relevant alerts: "Unacked" shows the non-shelved items still waiting for acknowledgment (`unacknowledged` or `rectified-unacknowledged`), "Active" every non-shelved item except the `rectified-unacknowledged` ones. A subclass changes the tabs and the list through the `tabs` and `renderList` hooks.
27
35
  * - **Bulk actions:** "ACK visible" button allows acknowledging all currently visible (filtered) alerts at once.
28
36
  * - **Silence and navigation:** Dedicated buttons to silence alerts or jump to the full alert list.
29
37
  * - **Dynamic content:** Supports any number of `<obc-alert-menu-item>` children, with automatic empty-state messaging and icons per tab.
@@ -117,13 +125,27 @@ export declare class ObcAlertMenu extends LitElement {
117
125
  showSilenceButton: boolean;
118
126
  /** If true, shows the "Alerts" navigation button in the action bar. When hidden, the "ACK visible" button expands to fill the freed space. */
119
127
  showAlertListButton: boolean;
120
- private _selectedTabIndex;
128
+ /** The `name` of the tab the user picked; the second tab shows until then. */
129
+ private _selectedTabName?;
121
130
  private alertList;
122
131
  private handleAckAllVisibleClick;
123
132
  private onTabChange;
124
- private getSelectedTab;
125
- render(): import('lit-html').TemplateResult<1>;
126
- static styles: import('lit').CSSResult;
133
+ protected willUpdate(changedProperties: PropertyValues<this>): void;
134
+ /** Whether the menu offers "ACK visible" at all; `canAckAll` enables it. */
135
+ protected get offersAckAll(): boolean;
136
+ /** The tabs in display order; the menu opens on the second one. */
137
+ protected get tabs(): AlertMenuTab[];
138
+ /** Where the selected tab sits in `tabs`: the one the user picked, else the second. */
139
+ private selectedTabIndex;
140
+ private get selectedTab();
141
+ /**
142
+ * The list that shows the selected tab's items. The CSS hides the items the
143
+ * tab leaves out; the filter tells the list which ones those are.
144
+ */
145
+ protected renderList(tab: AlertMenuTab, content: TemplateResult): TemplateResult;
146
+ private tabFilter;
147
+ render(): TemplateResult<1>;
148
+ static styles: CSSResultGroup;
127
149
  }
128
150
  declare global {
129
151
  interface HTMLElementTagNameMap {
@@ -1 +1 @@
1
- {"version":3,"file":"alert-menu.d.ts","sourceRoot":"","sources":["../../../src/components/alert-menu/alert-menu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAGzD,OAAO,qBAAqB,CAAC;AAC7B,OAAO,0CAA0C,CAAC;AAClD,OAAO,iCAAiC,CAAC;AACzC,OAAO,gCAAgC,CAAC;AACxC,OAAO,4BAA4B,CAAC;AACpC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,oCAAoC,CAAC;AAC5C,OAAO,+BAA+B,CAAC;AAGvC,OAAO,gDAAgD,CAAC;AAIxD,OAAO,EAAC,iBAAiB,EAAC,MAAM,sCAAsC,CAAC;AAEvE,MAAM,MAAM,0BAA0B,GAAG,WAAW,CAAC;IACnD,eAAe,EAAE;QAAC,OAAO,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IACzD,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,KAAK,CAAC;CACxC,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkFG;AACH,qBAKa,YAAa,SAAQ,UAAU;IACf,WAAW,UAAS;IAEpB,IAAI,UAAS;IAExC,SAAS,CAAC,QAAQ,CAAC,qBAAqB,oBAA+B;IAE5C,UAAU,EAAE,OAAO,CAAS;IAE5B,SAAS,EAAE,OAAO,CAAS;IAET,iBAAiB,EAAE,OAAO,CAChE;IAEsC,mBAAmB,EAAE,OAAO,CAClE;IAEE,OAAO,CAAC,iBAAiB,CAAK;IAGvC,OAAO,CAAC,SAAS,CAAgB;IAEjC,OAAO,CAAC,wBAAwB;IAahC,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,cAAc;IA+Cb,MAAM;IAqFf,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,YAAY,CAAC;KAChC;CACF"}
1
+ {"version":3,"file":"alert-menu.d.ts","sourceRoot":"","sources":["../../../src/components/alert-menu/alert-menu.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,UAAU,EACV,cAAc,EACd,cAAc,EAIf,MAAM,KAAK,CAAC;AAGb,OAAO,qBAAqB,CAAC;AAC7B,OAAO,0CAA0C,CAAC;AAClD,OAAO,iCAAiC,CAAC;AACzC,OAAO,gCAAgC,CAAC;AACxC,OAAO,4BAA4B,CAAC;AACpC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,oCAAoC,CAAC;AAC5C,OAAO,+BAA+B,CAAC;AAGvC,OAAO,gDAAgD,CAAC;AAIxD,OAAO,EAAC,iBAAiB,EAAC,MAAM,sCAAsC,CAAC;AAEvE,MAAM,MAAM,0BAA0B,GAAG,WAAW,CAAC;IACnD,eAAe,EAAE;QAAC,OAAO,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IACzD,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,KAAK,CAAC;CACxC,CAAC,CAAC;AAEH,yEAAyE;AACzE,MAAM,WAAW,YAAY;IAC3B,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,cAAc,CAAC;CAC3B;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkFG;AACH,qBAKa,YAAa,SAAQ,UAAU;IACf,WAAW,UAAS;IAEpB,IAAI,UAAS;IAExC,SAAS,CAAC,QAAQ,CAAC,qBAAqB,oBAA+B;IAE5C,UAAU,EAAE,OAAO,CAAS;IAE5B,SAAS,EAAE,OAAO,CAAS;IAET,iBAAiB,EAAE,OAAO,CAChE;IAEsC,mBAAmB,EAAE,OAAO,CAClE;IAEP,8EAA8E;IACrE,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAG3C,OAAO,CAAC,SAAS,CAAoB;IAErC,OAAO,CAAC,wBAAwB;IAahC,OAAO,CAAC,WAAW;cAIA,UAAU,CAAC,iBAAiB,EAAE,cAAc,CAAC,IAAI,CAAC;IASrE,4EAA4E;IAC5E,SAAS,KAAK,YAAY,IAAI,OAAO,CAEpC;IAED,mEAAmE;IACnE,SAAS,KAAK,IAAI,IAAI,YAAY,EAAE,CAwBnC;IAED,uFAAuF;IACvF,OAAO,CAAC,gBAAgB;IAKxB,OAAO,KAAK,WAAW,GAGtB;IAED;;;OAGG;IACH,SAAS,CAAC,UAAU,CAClB,GAAG,EAAE,YAAY,EACjB,OAAO,EAAE,cAAc,GACtB,cAAc;IAQjB,OAAO,CAAC,SAAS;IAcR,MAAM;IA2Ff,OAAgB,MAAM,EAAE,cAAc,CAA2B;CAClE;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,YAAY,CAAC;KAChC;CACF"}
@@ -16,6 +16,7 @@ import { localized, msg } from "@lit/localize";
16
16
  import { LitElement, html, nothing, unsafeCSS } from "lit";
17
17
  import { property, query, state } from "lit/decorators.js";
18
18
  //#region src/components/alert-menu/alert-menu.ts
19
+ var WAITING_FOR_ACK = [ObcAlertMenuItemStatus.Unacknowledged, ObcAlertMenuItemStatus.RectifiedUnacknowledged];
19
20
  var ObcAlertMenu = class ObcAlertMenu extends LitElement {
20
21
  constructor(..._args) {
21
22
  super(..._args);
@@ -26,88 +27,108 @@ var ObcAlertMenu = class ObcAlertMenu extends LitElement {
26
27
  this.canAckAll = false;
27
28
  this.showSilenceButton = true;
28
29
  this.showAlertListButton = true;
29
- this._selectedTabIndex = 1;
30
30
  }
31
31
  handleAckAllVisibleClick() {
32
32
  const visibleElements = this.alertList.getVisibleElements();
33
33
  this.dispatchEvent(new CustomEvent("ack-all-visible-click", { detail: {
34
34
  visibleElements,
35
- tabName: this.getSelectedTab().name
35
+ tabName: this.selectedTab.name
36
36
  } }));
37
37
  }
38
38
  onTabChange(e) {
39
- this._selectedTabIndex = e.detail.tab;
39
+ this._selectedTabName = this.tabs[e.detail.tab]?.name;
40
40
  }
41
- getSelectedTab() {
42
- if (this._selectedTabIndex === 0) return {
41
+ willUpdate(changedProperties) {
42
+ super.willUpdate(changedProperties);
43
+ if (!this.tabs.some((tab) => tab.name === this._selectedTabName)) this._selectedTabName = void 0;
44
+ }
45
+ /** Whether the menu offers "ACK visible" at all; `canAckAll` enables it. */
46
+ get offersAckAll() {
47
+ return true;
48
+ }
49
+ /** The tabs in display order; the menu opens on the second one. */
50
+ get tabs() {
51
+ const tabs = [{
43
52
  name: "unacked",
53
+ title: msg("Unacked"),
44
54
  emptyTitle: msg("No unacknowledged alerts"),
45
- emptyDescription: msg("Go to the 'Alert list' for more details or to manage existing alerts."),
46
- emptyIcon: html`<obi-unacknowledged></obi-unacknowledged>`,
47
- class: "unacked",
48
- filter: (item) => {
49
- return item.getAttribute("status") === ObcAlertMenuItemStatus.Unacknowledged && !item.hasAttribute("shelved");
50
- }
51
- };
52
- else if (this._selectedTabIndex === 2) return {
53
- name: "shelved",
54
- emptyTitle: msg("No shelved alerts"),
55
- emptyDescription: msg("Go to the 'Alert list' for more details or to manage existing alerts."),
56
- emptyIcon: html`<obi-alerts-shelf></obi-alerts-shelf>`,
57
- class: "shelved",
58
- filter: (item) => {
59
- return item.hasAttribute("shelved");
60
- }
61
- };
62
- else return {
55
+ emptyIcon: html`<obi-unacknowledged></obi-unacknowledged>`
56
+ }, {
63
57
  name: "all",
58
+ title: msg("Active"),
64
59
  emptyTitle: msg("No active alerts"),
65
- emptyDescription: msg("Go to the 'Alert list' for more details or to manage existing alerts."),
66
- emptyIcon: html`<obi-alerts></obi-alerts>`,
67
- class: "all",
68
- filter: (item) => {
69
- return !item.hasAttribute("shelved");
70
- }
71
- };
60
+ emptyIcon: html`<obi-alerts></obi-alerts>`
61
+ }];
62
+ if (this.hasShelved) tabs.push({
63
+ name: "shelved",
64
+ title: msg("Shelved"),
65
+ emptyTitle: msg("No shelved alerts"),
66
+ emptyIcon: html`<obi-alerts-shelf></obi-alerts-shelf>`
67
+ });
68
+ return tabs;
69
+ }
70
+ /** Where the selected tab sits in `tabs`: the one the user picked, else the second. */
71
+ selectedTabIndex(tabs) {
72
+ const index = tabs.findIndex((tab) => tab.name === this._selectedTabName);
73
+ return index === -1 ? 1 : index;
74
+ }
75
+ get selectedTab() {
76
+ const tabs = this.tabs;
77
+ return tabs[this.selectedTabIndex(tabs)];
78
+ }
79
+ /**
80
+ * The list that shows the selected tab's items. The CSS hides the items the
81
+ * tab leaves out; the filter tells the list which ones those are.
82
+ */
83
+ renderList(tab, content) {
84
+ return html`<obc-alert-list
85
+ class="alert-list ${tab.name}"
86
+ .filter=${(item) => this.tabFilter(tab.name, item)}
87
+ >${content}</obc-alert-list
88
+ >`;
89
+ }
90
+ tabFilter(name, item) {
91
+ const status = item.getAttribute("status") ?? "";
92
+ if (name === "unacked") return WAITING_FOR_ACK.includes(status) && !item.hasAttribute("shelved");
93
+ if (name === "shelved") return item.hasAttribute("shelved");
94
+ return !item.hasAttribute("shelved") && status !== ObcAlertMenuItemStatus.RectifiedUnacknowledged;
72
95
  }
73
96
  render() {
74
- const t = this.getSelectedTab();
97
+ const tabs = this.tabs;
98
+ const selectedIndex = this.selectedTabIndex(tabs);
99
+ const t = tabs[selectedIndex];
75
100
  return html`
76
101
  <obc-tabbed-card
77
- .nTabs=${this.hasShelved ? 3 : 2}
102
+ .nTabs=${tabs.length}
78
103
  class="wrapper"
79
104
  part="wrapper"
80
- .selectedTab=${this._selectedTabIndex}
105
+ .selectedTab=${selectedIndex}
81
106
  hasDefaultSlotOnly
82
107
  @tab-change=${this.onTabChange}
83
108
  >
84
- <span slot="tab-title-0">${msg("Unacked")}</span>
85
- <span slot="tab-title-1">${msg("Active")}</span>
86
- ${this.hasShelved ? html`<span slot="tab-title-2">${msg("Shelved")}</span>` : nothing}
109
+ ${tabs.map((tab, index) => html`<span slot="tab-title-${index}">${tab.title}</span>`)}
87
110
  <div class="container">
88
- <obc-alert-list class="alert-list ${t.class}" .filter=${t.filter}>
89
- <slot></slot>
90
- <slot name="empty-${t.name}-title" slot="empty-title"
91
- >${t.emptyTitle}</slot
92
- >
93
- <slot name="empty-${t.name}-description" slot="empty-description"
94
- >${t.emptyDescription}</slot
95
- >
96
- <slot name="empty-${t.name}-icon" slot="empty-icon"
97
- >${t.emptyIcon}</slot
98
- >
99
- </obc-alert-list>
111
+ ${this.renderList(t, html`<slot></slot>
112
+ <slot name="empty-${t.name}-title" slot="empty-title"
113
+ >${t.emptyTitle}</slot
114
+ >
115
+ <slot name="empty-${t.name}-description" slot="empty-description"
116
+ >${msg("Go to the 'Alert list' for more details or to manage existing alerts.")}</slot
117
+ >
118
+ <slot name="empty-${t.name}-icon" slot="empty-icon"
119
+ >${t.emptyIcon}</slot
120
+ >`)}
100
121
  <div class="action">
101
- <obc-button
102
- variant="raised"
103
- .disabled=${!this.canAckAll}
104
- fullWidth
105
- class="btn"
106
- data-testid="ack-all-visible-button"
107
- @click=${this.handleAckAllVisibleClick}
108
- >
109
- ${msg("ACK visible")}
110
- </obc-button>
122
+ ${this.offersAckAll ? html`<obc-button
123
+ variant="raised"
124
+ .disabled=${!this.canAckAll}
125
+ fullWidth
126
+ class="btn"
127
+ data-testid="ack-all-visible-button"
128
+ @click=${this.handleAckAllVisibleClick}
129
+ >
130
+ ${msg("ACK visible")}
131
+ </obc-button>` : nothing}
111
132
  ${this.showSilenceButton ? html`<obc-button
112
133
  variant="normal"
113
134
  fullWidth
@@ -153,8 +174,8 @@ __decorate([property({
153
174
  type: Boolean,
154
175
  attribute: false
155
176
  })], ObcAlertMenu.prototype, "showAlertListButton", void 0);
156
- __decorate([state()], ObcAlertMenu.prototype, "_selectedTabIndex", void 0);
157
- __decorate([query("obc-alert-list")], ObcAlertMenu.prototype, "alertList", void 0);
177
+ __decorate([state()], ObcAlertMenu.prototype, "_selectedTabName", void 0);
178
+ __decorate([query(".alert-list")], ObcAlertMenu.prototype, "alertList", void 0);
158
179
  ObcAlertMenu = __decorate([localized(), customElement("obc-alert-menu")], ObcAlertMenu);
159
180
  //#endregion
160
181
  export { ObcAlertMenu };
@@ -1 +1 @@
1
- {"version":3,"file":"alert-menu.js","names":[],"sources":["../../../src/components/alert-menu/alert-menu.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property, query, state} from 'lit/decorators.js';\nimport compentStyle from './alert-menu.css?inline';\nimport '../button/button.js';\nimport '../../icons/icon-chevron-right-google.js';\nimport '../../icons/icon-silence-iec.js';\nimport '../../icons/icon-alert-list.js';\nimport '../../icons/icon-alerts.js';\nimport '../../icons/icon-alerts-shelf.js';\nimport '../../icons/icon-unacknowledged.js';\nimport '../tabbed-card/tabbed-card.js';\nimport {localized, msg} from '@lit/localize';\nimport {customElement} from '../../decorator.js';\nimport '../../building-blocks/alert-list/alert-list.js';\nimport {ObcAlertList} from '../../building-blocks/alert-list/alert-list.js';\nimport {ObcTabbedCardChangeEvent} from '../tabbed-card/tabbed-card.js';\nimport {ObcAlertMenuItemStatus} from '../alert-menu-item/alert-menu-item.js';\nimport {PopoverController} from '../../internal/popover-controller.js';\n\nexport type ObcAckAllVisibleClickEvent = CustomEvent<{\n visibleElements: {element: HTMLElement; index: number}[];\n tabName: 'shelved' | 'unacked' | 'all';\n}>;\n\n/**\n * `<obc-alert-menu>` – A tabbed alert summary panel for displaying, acknowledging, and managing active alerts.\n *\n * Provides a compact, interactive menu for reviewing current alerts, grouped by status (e.g., unacknowledged, active, shelved). Users can acknowledge visible alerts, silence notifications, or navigate to a full alert list. Designed for quick triage and management of alert items in a sidebar or overlay context.\n *\n * ### Features\n * - **Tabbed organization:** Switch between \"Unacked\", \"Active\", and (optionally) \"Shelved\" tabs for focused alert review.\n * - **Alert filtering:** Each tab displays only relevant alerts (e.g., \"Unacked\" shows only unacknowledged, non-shelved items).\n * - **Bulk actions:** \"ACK visible\" button allows acknowledging all currently visible (filtered) alerts at once.\n * - **Silence and navigation:** Dedicated buttons to silence alerts or jump to the full alert list.\n * - **Dynamic content:** Supports any number of `<obc-alert-menu-item>` children, with automatic empty-state messaging and icons per tab.\n * - **Responsive layout:** Adapts to available space, with scrollable alert lists and sticky action bar.\n * - **Customizable:** Optionally show/hide the \"Shelved\" tab via `hasShelved` property; enable/disable bulk ACK via `canAckAll`.\n *\n * ### Usage Guidelines\n * Use `<obc-alert-menu>` to provide users with a focused, actionable summary of current alerts, typically in a sidebar, overlay, or dashboard context. Ideal for scenarios where users need to quickly review, acknowledge, or silence multiple alerts without leaving their current workflow. Avoid using for persistent, always-visible alert banners; for that, use a dedicated alert banner or notification system.\n *\n * - Place one or more `<obc-alert-menu-item>` elements as children to populate the alert list.\n * - Use the `hasShelved` property to enable the \"Shelved\" tab if your application supports alert shelving.\n * - Use the `canAckAll` property to control whether the \"ACK visible\" button is enabled (e.g., only when there are unacknowledged alerts in view).\n * - Listen for custom events (`ack-all-visible-click`, `silence-click`, `go-to-alert-list-click`) to handle user actions.\n *\n * **TODO(designer):** Confirm if there are recommended maximum numbers of alerts to display, or if there are best practices for when to use the \"Shelved\" tab.\n *\n * ### Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |----------------------------------|----------------------------------|----------------------------------------------------------------|\n * | (default) | Always | Place one or more `<obc-alert-menu-item>` elements as alert rows. |\n * | empty-<tab>-title | Selected tab is empty | Custom title for the empty state (`<tab>` is one of `unacked`, `all`, `shelved`). |\n * | empty-<tab>-description | Selected tab is empty | Custom description for the empty state (`<tab>` is one of `unacked`, `all`, `shelved`). |\n * | empty-<tab>-icon | Selected tab is empty | Custom icon for the empty state (`<tab>` is one of `unacked`, `all`, `shelved`). |\n *\n * ### Properties\n * - `hasShelved` (boolean): If true, displays the \"Shelved\" tab and enables shelving support. Default: false.\n * - `canAckAll` (boolean): If true, enables the \"ACK visible\" button for bulk acknowledgment. Default: false.\n * - `showSilenceButton` (boolean): If true, shows the \"Silence\" button. Default: true.\n * - `showAlertListButton` (boolean): If true, shows the \"Alerts\" navigation button. Default: true.\n *\n * ### Events\n * - **ack-all-visible-click** – Fired when the \"ACK visible\" button is clicked. The event detail includes the list of visible alert elements and the current tab name.\n * - **silence-click** – Fired when the \"Silence\" button is clicked.\n * - **go-to-alert-list-click** – Fired when the \"Alerts\" navigation button is clicked.\n *\n * ### Best Practices and Constraints\n * - Only enable \"ACK visible\" when there are actionable, unacknowledged alerts in the current view.\n * - Use the \"Shelved\" tab only if your application supports shelving alerts; otherwise, omit it for simplicity.\n * - For accessibility, keep all alert items and action buttons keyboard navigable.\n * - Do not use this component for persistent, always-on-screen alerts; use banners or dialogs for critical, persistent notifications.\n *\n * ### Example\n * ```\n * <obc-alert-menu hasShelved canAckAll>\n * <obc-alert-menu-item active hasTime>\n * <obi-placeholder slot=\"alert-icon\"></obi-placeholder>\n * <span slot=\"title\">Engine Overheat</span>\n * <span slot=\"description\">Main engine temperature exceeds threshold</span>\n * <span slot=\"time\">09:12:34</span>\n * </obc-alert-menu-item>\n * <!-- More alert items... -->\n * </obc-alert-menu>\n * ```\n *\n * @property hasShelved - If true, displays the \"Shelved\" tab and enables shelving support for alerts.\n * Set to false to hide the \"Shelved\" tab and related filtering.\n * @property canAckAll - If true, enables the \"ACK visible\" button, allowing users to acknowledge all currently visible alerts in the active tab.\n * Should be set to true only when there are unacknowledged alerts in view.\n * @property showSilenceButton - If true, shows the \"Silence\" button in the action bar.\n * When hidden, the \"ACK visible\" button expands to fill the freed space.\n * @property showAlertListButton - If true, shows the \"Alerts\" navigation button in the action bar.\n * When hidden, the \"ACK visible\" button expands to fill the freed space.\n * @property softDismiss - Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself.\n * @property open - Whether the menu is showing.\n * @availableWhen open softDismiss==true\n * @slot - The alerts items as ObcAlertMenuItem\n * @slot empty-<tab>-title - Custom empty-state title for the selected tab (`<tab>` is one of `unacked`, `all`, `shelved`)\n * @slot empty-<tab>-description - Custom empty-state description for the selected tab (`<tab>` is one of `unacked`, `all`, `shelved`)\n * @slot empty-<tab>-icon - Custom empty-state icon for the selected tab (`<tab>` is one of `unacked`, `all`, `shelved`)\n * @fires {ObcAckAllVisibleClickEvent} ack-all-visible-click - Fired when the ack all visible button is clicked\n * @fires {CustomEvent} silence-click - Fired when the silence button is clicked\n * @fires {CustomEvent} go-to-alert-list-click - Fired when the go to alert list button is clicked\n * @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives.\n */\n@localized()\n/**\n * @stable\n */\n@customElement('obc-alert-menu')\nexport class ObcAlertMenu extends LitElement {\n @property({type: Boolean}) softDismiss = false;\n\n @property({type: Boolean}) open = false;\n\n protected readonly softDismissController = new PopoverController(this);\n\n @property({type: Boolean}) hasShelved: boolean = false;\n\n @property({type: Boolean}) canAckAll: boolean = false;\n\n @property({type: Boolean, attribute: false}) showSilenceButton: boolean =\n true;\n\n @property({type: Boolean, attribute: false}) showAlertListButton: boolean =\n true;\n\n @state() private _selectedTabIndex = 1;\n\n @query('obc-alert-list')\n private alertList!: ObcAlertList;\n\n private handleAckAllVisibleClick() {\n const panel = this.alertList;\n const visibleElements = panel.getVisibleElements();\n this.dispatchEvent(\n new CustomEvent('ack-all-visible-click', {\n detail: {\n visibleElements: visibleElements,\n tabName: this.getSelectedTab().name,\n },\n })\n );\n }\n\n private onTabChange(e: ObcTabbedCardChangeEvent) {\n this._selectedTabIndex = e.detail.tab;\n }\n\n private getSelectedTab() {\n if (this._selectedTabIndex === 0) {\n return {\n name: 'unacked',\n emptyTitle: msg('No unacknowledged alerts'),\n emptyDescription: msg(\n \"Go to the 'Alert list' for more details or to manage existing alerts.\"\n ),\n emptyIcon: html`<obi-unacknowledged></obi-unacknowledged>`,\n class: 'unacked',\n filter: (item: HTMLElement) => {\n return (\n item.getAttribute('status') ===\n ObcAlertMenuItemStatus.Unacknowledged &&\n !item.hasAttribute('shelved')\n );\n },\n };\n } else if (this._selectedTabIndex === 2) {\n return {\n name: 'shelved',\n emptyTitle: msg('No shelved alerts'),\n emptyDescription: msg(\n \"Go to the 'Alert list' for more details or to manage existing alerts.\"\n ),\n emptyIcon: html`<obi-alerts-shelf></obi-alerts-shelf>`,\n class: 'shelved',\n filter: (item: HTMLElement) => {\n return item.hasAttribute('shelved');\n },\n };\n } else {\n return {\n name: 'all',\n emptyTitle: msg('No active alerts'),\n emptyDescription: msg(\n \"Go to the 'Alert list' for more details or to manage existing alerts.\"\n ),\n emptyIcon: html`<obi-alerts></obi-alerts>`,\n class: 'all',\n filter: (item: HTMLElement) => {\n return !item.hasAttribute('shelved');\n },\n };\n }\n }\n\n override render() {\n const t = this.getSelectedTab();\n\n return html`\n <obc-tabbed-card\n .nTabs=${this.hasShelved ? 3 : 2}\n class=\"wrapper\"\n part=\"wrapper\"\n .selectedTab=${this._selectedTabIndex}\n hasDefaultSlotOnly\n @tab-change=${this.onTabChange}\n >\n <span slot=\"tab-title-0\">${msg('Unacked')}</span>\n <span slot=\"tab-title-1\">${msg('Active')}</span>\n ${\n this.hasShelved\n ? html`<span slot=\"tab-title-2\">${msg('Shelved')}</span>`\n : nothing\n }\n <div class=\"container\">\n <obc-alert-list class=\"alert-list ${t.class}\" .filter=${t.filter}>\n <slot></slot>\n <slot name=\"empty-${t.name}-title\" slot=\"empty-title\"\n >${t.emptyTitle}</slot\n >\n <slot name=\"empty-${t.name}-description\" slot=\"empty-description\"\n >${t.emptyDescription}</slot\n >\n <slot name=\"empty-${t.name}-icon\" slot=\"empty-icon\"\n >${t.emptyIcon}</slot\n >\n </obc-alert-list>\n <div class=\"action\">\n <obc-button\n variant=\"raised\"\n .disabled=${!this.canAckAll}\n fullWidth\n class=\"btn\"\n data-testid=\"ack-all-visible-button\"\n @click=${this.handleAckAllVisibleClick}\n >\n ${msg('ACK visible')}\n </obc-button>\n ${\n this.showSilenceButton\n ? html`<obc-button\n variant=\"normal\"\n fullWidth\n class=\"btn\"\n showLeadingIcon\n @click=${() =>\n this.dispatchEvent(new CustomEvent('silence-click'))}\n >\n <obi-silence-iec slot=\"leading-icon\"></obi-silence-iec>\n ${msg('Silence')}\n </obc-button>`\n : nothing\n }\n ${\n this.showAlertListButton\n ? html`<obc-button\n variant=\"normal\"\n class=\"btn\"\n fullWidth\n showLeadingIcon\n showTrailingIcon\n @click=${() =>\n this.dispatchEvent(\n new CustomEvent('go-to-alert-list-click')\n )}\n >\n <obi-alert-list slot=\"leading-icon\"></obi-alert-list>\n <obi-chevron-right-google\n slot=\"trailing-icon\"\n ></obi-chevron-right-google>\n ${msg('Alerts')}\n </obc-button>`\n : nothing\n }\n </div>\n </div>\n </obc-tabbed-card>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-alert-menu': ObcAlertMenu;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"alert-menu.js","names":[],"sources":["../../../src/components/alert-menu/alert-menu.ts"],"sourcesContent":["import {\n CSSResultGroup,\n LitElement,\n PropertyValues,\n TemplateResult,\n html,\n nothing,\n unsafeCSS,\n} from 'lit';\nimport {property, query, state} from 'lit/decorators.js';\nimport compentStyle from './alert-menu.css?inline';\nimport '../button/button.js';\nimport '../../icons/icon-chevron-right-google.js';\nimport '../../icons/icon-silence-iec.js';\nimport '../../icons/icon-alert-list.js';\nimport '../../icons/icon-alerts.js';\nimport '../../icons/icon-alerts-shelf.js';\nimport '../../icons/icon-unacknowledged.js';\nimport '../tabbed-card/tabbed-card.js';\nimport {localized, msg} from '@lit/localize';\nimport {customElement} from '../../decorator.js';\nimport '../../building-blocks/alert-list/alert-list.js';\nimport type {ObcAlertListBase} from '../../building-blocks/alert-list/alert-list-base.js';\nimport {ObcTabbedCardChangeEvent} from '../tabbed-card/tabbed-card.js';\nimport {ObcAlertMenuItemStatus} from '../alert-menu-item/alert-menu-item.js';\nimport {PopoverController} from '../../internal/popover-controller.js';\n\nexport type ObcAckAllVisibleClickEvent = CustomEvent<{\n visibleElements: {element: HTMLElement; index: number}[];\n tabName: 'shelved' | 'unacked' | 'all';\n}>;\n\n/** One tab of an alert menu: its name, its label and its empty state. */\nexport interface AlertMenuTab {\n /** Names the tab in `ack-all-visible-click` and in the `empty-<tab>-*` slots. */\n name: string;\n title: string;\n emptyTitle: string;\n emptyIcon: TemplateResult;\n}\n\nconst WAITING_FOR_ACK: string[] = [\n ObcAlertMenuItemStatus.Unacknowledged,\n ObcAlertMenuItemStatus.RectifiedUnacknowledged,\n];\n\n/**\n * `<obc-alert-menu>` – A tabbed alert summary panel for displaying, acknowledging, and managing active alerts.\n *\n * Provides a compact, interactive menu for reviewing current alerts, grouped by status (e.g., unacknowledged, active, shelved). Users can acknowledge visible alerts, silence notifications, or navigate to a full alert list. Designed for quick triage and management of alert items in a sidebar or overlay context.\n *\n * ### Features\n * - **Tabbed organization:** Switch between \"Unacked\", \"Active\", and (optionally) \"Shelved\" tabs for focused alert review.\n * - **Alert filtering:** Each tab displays only relevant alerts: \"Unacked\" shows the non-shelved items still waiting for acknowledgment (`unacknowledged` or `rectified-unacknowledged`), \"Active\" every non-shelved item except the `rectified-unacknowledged` ones. A subclass changes the tabs and the list through the `tabs` and `renderList` hooks.\n * - **Bulk actions:** \"ACK visible\" button allows acknowledging all currently visible (filtered) alerts at once.\n * - **Silence and navigation:** Dedicated buttons to silence alerts or jump to the full alert list.\n * - **Dynamic content:** Supports any number of `<obc-alert-menu-item>` children, with automatic empty-state messaging and icons per tab.\n * - **Responsive layout:** Adapts to available space, with scrollable alert lists and sticky action bar.\n * - **Customizable:** Optionally show/hide the \"Shelved\" tab via `hasShelved` property; enable/disable bulk ACK via `canAckAll`.\n *\n * ### Usage Guidelines\n * Use `<obc-alert-menu>` to provide users with a focused, actionable summary of current alerts, typically in a sidebar, overlay, or dashboard context. Ideal for scenarios where users need to quickly review, acknowledge, or silence multiple alerts without leaving their current workflow. Avoid using for persistent, always-visible alert banners; for that, use a dedicated alert banner or notification system.\n *\n * - Place one or more `<obc-alert-menu-item>` elements as children to populate the alert list.\n * - Use the `hasShelved` property to enable the \"Shelved\" tab if your application supports alert shelving.\n * - Use the `canAckAll` property to control whether the \"ACK visible\" button is enabled (e.g., only when there are unacknowledged alerts in view).\n * - Listen for custom events (`ack-all-visible-click`, `silence-click`, `go-to-alert-list-click`) to handle user actions.\n *\n * **TODO(designer):** Confirm if there are recommended maximum numbers of alerts to display, or if there are best practices for when to use the \"Shelved\" tab.\n *\n * ### Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |----------------------------------|----------------------------------|----------------------------------------------------------------|\n * | (default) | Always | Place one or more `<obc-alert-menu-item>` elements as alert rows. |\n * | empty-<tab>-title | Selected tab is empty | Custom title for the empty state (`<tab>` is one of `unacked`, `all`, `shelved`). |\n * | empty-<tab>-description | Selected tab is empty | Custom description for the empty state (`<tab>` is one of `unacked`, `all`, `shelved`). |\n * | empty-<tab>-icon | Selected tab is empty | Custom icon for the empty state (`<tab>` is one of `unacked`, `all`, `shelved`). |\n *\n * ### Properties\n * - `hasShelved` (boolean): If true, displays the \"Shelved\" tab and enables shelving support. Default: false.\n * - `canAckAll` (boolean): If true, enables the \"ACK visible\" button for bulk acknowledgment. Default: false.\n * - `showSilenceButton` (boolean): If true, shows the \"Silence\" button. Default: true.\n * - `showAlertListButton` (boolean): If true, shows the \"Alerts\" navigation button. Default: true.\n *\n * ### Events\n * - **ack-all-visible-click** – Fired when the \"ACK visible\" button is clicked. The event detail includes the list of visible alert elements and the current tab name.\n * - **silence-click** – Fired when the \"Silence\" button is clicked.\n * - **go-to-alert-list-click** – Fired when the \"Alerts\" navigation button is clicked.\n *\n * ### Best Practices and Constraints\n * - Only enable \"ACK visible\" when there are actionable, unacknowledged alerts in the current view.\n * - Use the \"Shelved\" tab only if your application supports shelving alerts; otherwise, omit it for simplicity.\n * - For accessibility, keep all alert items and action buttons keyboard navigable.\n * - Do not use this component for persistent, always-on-screen alerts; use banners or dialogs for critical, persistent notifications.\n *\n * ### Example\n * ```\n * <obc-alert-menu hasShelved canAckAll>\n * <obc-alert-menu-item active hasTime>\n * <obi-placeholder slot=\"alert-icon\"></obi-placeholder>\n * <span slot=\"title\">Engine Overheat</span>\n * <span slot=\"description\">Main engine temperature exceeds threshold</span>\n * <span slot=\"time\">09:12:34</span>\n * </obc-alert-menu-item>\n * <!-- More alert items... -->\n * </obc-alert-menu>\n * ```\n *\n * @property hasShelved - If true, displays the \"Shelved\" tab and enables shelving support for alerts.\n * Set to false to hide the \"Shelved\" tab and related filtering.\n * @property canAckAll - If true, enables the \"ACK visible\" button, allowing users to acknowledge all currently visible alerts in the active tab.\n * Should be set to true only when there are unacknowledged alerts in view.\n * @property showSilenceButton - If true, shows the \"Silence\" button in the action bar.\n * When hidden, the \"ACK visible\" button expands to fill the freed space.\n * @property showAlertListButton - If true, shows the \"Alerts\" navigation button in the action bar.\n * When hidden, the \"ACK visible\" button expands to fill the freed space.\n * @property softDismiss - Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself.\n * @property open - Whether the menu is showing.\n * @availableWhen open softDismiss==true\n * @slot - The alerts items as ObcAlertMenuItem\n * @slot empty-<tab>-title - Custom empty-state title for the selected tab (`<tab>` is one of `unacked`, `all`, `shelved`)\n * @slot empty-<tab>-description - Custom empty-state description for the selected tab (`<tab>` is one of `unacked`, `all`, `shelved`)\n * @slot empty-<tab>-icon - Custom empty-state icon for the selected tab (`<tab>` is one of `unacked`, `all`, `shelved`)\n * @fires {ObcAckAllVisibleClickEvent} ack-all-visible-click - Fired when the ack all visible button is clicked\n * @fires {CustomEvent} silence-click - Fired when the silence button is clicked\n * @fires {CustomEvent} go-to-alert-list-click - Fired when the go to alert list button is clicked\n * @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives.\n */\n@localized()\n/**\n * @stable\n */\n@customElement('obc-alert-menu')\nexport class ObcAlertMenu extends LitElement {\n @property({type: Boolean}) softDismiss = false;\n\n @property({type: Boolean}) open = false;\n\n protected readonly softDismissController = new PopoverController(this);\n\n @property({type: Boolean}) hasShelved: boolean = false;\n\n @property({type: Boolean}) canAckAll: boolean = false;\n\n @property({type: Boolean, attribute: false}) showSilenceButton: boolean =\n true;\n\n @property({type: Boolean, attribute: false}) showAlertListButton: boolean =\n true;\n\n /** The `name` of the tab the user picked; the second tab shows until then. */\n @state() private _selectedTabName?: string;\n\n @query('.alert-list')\n private alertList!: ObcAlertListBase;\n\n private handleAckAllVisibleClick() {\n const panel = this.alertList;\n const visibleElements = panel.getVisibleElements();\n this.dispatchEvent(\n new CustomEvent('ack-all-visible-click', {\n detail: {\n visibleElements: visibleElements,\n tabName: this.selectedTab.name,\n },\n })\n );\n }\n\n private onTabChange(e: ObcTabbedCardChangeEvent) {\n this._selectedTabName = this.tabs[e.detail.tab]?.name;\n }\n\n protected override willUpdate(changedProperties: PropertyValues<this>) {\n super.willUpdate(changedProperties);\n // A picked tab that goes away, as Shelved does when `hasShelved` turns\n // off, gives way to the second tab, which stays when the tab returns.\n if (!this.tabs.some((tab) => tab.name === this._selectedTabName)) {\n this._selectedTabName = undefined;\n }\n }\n\n /** Whether the menu offers \"ACK visible\" at all; `canAckAll` enables it. */\n protected get offersAckAll(): boolean {\n return true;\n }\n\n /** The tabs in display order; the menu opens on the second one. */\n protected get tabs(): AlertMenuTab[] {\n const tabs = [\n {\n name: 'unacked',\n title: msg('Unacked'),\n emptyTitle: msg('No unacknowledged alerts'),\n emptyIcon: html`<obi-unacknowledged></obi-unacknowledged>`,\n },\n {\n name: 'all',\n title: msg('Active'),\n emptyTitle: msg('No active alerts'),\n emptyIcon: html`<obi-alerts></obi-alerts>`,\n },\n ];\n if (this.hasShelved) {\n tabs.push({\n name: 'shelved',\n title: msg('Shelved'),\n emptyTitle: msg('No shelved alerts'),\n emptyIcon: html`<obi-alerts-shelf></obi-alerts-shelf>`,\n });\n }\n return tabs;\n }\n\n /** Where the selected tab sits in `tabs`: the one the user picked, else the second. */\n private selectedTabIndex(tabs: AlertMenuTab[]): number {\n const index = tabs.findIndex((tab) => tab.name === this._selectedTabName);\n return index === -1 ? 1 : index;\n }\n\n private get selectedTab(): AlertMenuTab {\n const tabs = this.tabs;\n return tabs[this.selectedTabIndex(tabs)];\n }\n\n /**\n * The list that shows the selected tab's items. The CSS hides the items the\n * tab leaves out; the filter tells the list which ones those are.\n */\n protected renderList(\n tab: AlertMenuTab,\n content: TemplateResult\n ): TemplateResult {\n return html`<obc-alert-list\n class=\"alert-list ${tab.name}\"\n .filter=${(item: HTMLElement) => this.tabFilter(tab.name, item)}\n >${content}</obc-alert-list\n >`;\n }\n\n private tabFilter(name: string, item: HTMLElement): boolean {\n const status = item.getAttribute('status') ?? '';\n if (name === 'unacked') {\n return WAITING_FOR_ACK.includes(status) && !item.hasAttribute('shelved');\n }\n if (name === 'shelved') {\n return item.hasAttribute('shelved');\n }\n return (\n !item.hasAttribute('shelved') &&\n status !== ObcAlertMenuItemStatus.RectifiedUnacknowledged\n );\n }\n\n override render() {\n const tabs = this.tabs;\n const selectedIndex = this.selectedTabIndex(tabs);\n const t = tabs[selectedIndex];\n\n return html`\n <obc-tabbed-card\n .nTabs=${tabs.length}\n class=\"wrapper\"\n part=\"wrapper\"\n .selectedTab=${selectedIndex}\n hasDefaultSlotOnly\n @tab-change=${this.onTabChange}\n >\n ${tabs.map(\n (tab, index) =>\n html`<span slot=\"tab-title-${index}\">${tab.title}</span>`\n )}\n <div class=\"container\">\n ${this.renderList(\n t,\n html`<slot></slot>\n <slot name=\"empty-${t.name}-title\" slot=\"empty-title\"\n >${t.emptyTitle}</slot\n >\n <slot name=\"empty-${t.name}-description\" slot=\"empty-description\"\n >${msg(\n \"Go to the 'Alert list' for more details or to manage existing alerts.\"\n )}</slot\n >\n <slot name=\"empty-${t.name}-icon\" slot=\"empty-icon\"\n >${t.emptyIcon}</slot\n >`\n )}\n <div class=\"action\">\n ${\n this.offersAckAll\n ? html`<obc-button\n variant=\"raised\"\n .disabled=${!this.canAckAll}\n fullWidth\n class=\"btn\"\n data-testid=\"ack-all-visible-button\"\n @click=${this.handleAckAllVisibleClick}\n >\n ${msg('ACK visible')}\n </obc-button>`\n : nothing\n }\n ${\n this.showSilenceButton\n ? html`<obc-button\n variant=\"normal\"\n fullWidth\n class=\"btn\"\n showLeadingIcon\n @click=${() =>\n this.dispatchEvent(new CustomEvent('silence-click'))}\n >\n <obi-silence-iec slot=\"leading-icon\"></obi-silence-iec>\n ${msg('Silence')}\n </obc-button>`\n : nothing\n }\n ${\n this.showAlertListButton\n ? html`<obc-button\n variant=\"normal\"\n class=\"btn\"\n fullWidth\n showLeadingIcon\n showTrailingIcon\n @click=${() =>\n this.dispatchEvent(\n new CustomEvent('go-to-alert-list-click')\n )}\n >\n <obi-alert-list slot=\"leading-icon\"></obi-alert-list>\n <obi-chevron-right-google\n slot=\"trailing-icon\"\n ></obi-chevron-right-google>\n ${msg('Alerts')}\n </obc-button>`\n : nothing\n }\n </div>\n </div>\n </obc-tabbed-card>\n `;\n }\n\n static override styles: CSSResultGroup = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-alert-menu': ObcAlertMenu;\n }\n}\n"],"mappings":"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"}