address PR #765 review comments

- layoutController/site-configurations: use strict boolean check instead of
  Boolean() coercion for showInlineEvents so persisted "false" strings don't
  flip the toggle
- (kener)/+page.svelte: collapse confusing triple negation !!! to single !
- NotificationsList: add aria-label/title to the icon-only events button
  (+ "Open events page" en locale key)
- move NotificationEvent into shared $lib/types/notifications so client code
  no longer imports from the server dashboardController; controller re-exports
  it for backwards compatibility
- [page_path] and monitor pages: pass hideNotificationsPopover={showInlineEvents}
  to ThemePlus so inline and popover event surfaces stay mutually exclusive

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Raj Nandan Sharma
2026-06-19 22:28:22 +05:30
parent 3503e73f56
commit ba1d0079de
11 changed files with 35 additions and 19 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
import { resolve } from "$app/paths";
import clientResolver from "$lib/client/resolver.js";
import type { NotificationEvent } from "$lib/server/controllers/dashboardController.js";
import type { NotificationEvent } from "$lib/types/notifications.js";
interface NotificationsResponse {
notifications?: NotificationEvent[];
+9 -2
View File
@@ -6,7 +6,7 @@
import { Button } from "$lib/components/ui/button/index.js";
import { formatDate, formatDuration } from "$lib/stores/datetime";
import { t } from "$lib/stores/i18n";
import type { NotificationEvent } from "$lib/server/controllers/dashboardController.js";
import type { NotificationEvent } from "$lib/types/notifications.js";
import Calendar from "@lucide/svelte/icons/calendar-1";
import { format } from "date-fns";
import { onMount } from "svelte";
@@ -78,7 +78,14 @@
<div class="flex items-center justify-between border-b px-4 py-3">
<h4 class="text-sm font-semibold">{$t("Events")}</h4>
<Button variant="outline" href={clientResolver(resolve, resolvedEventsPath)} size="icon-sm" class="rounded-btn">
<Button
variant="outline"
href={clientResolver(resolve, resolvedEventsPath)}
size="icon-sm"
class="rounded-btn"
aria-label={$t("Open events page")}
title={$t("Open events page")}
>
<Calendar class="size-4" />
</Button>
</div>
@@ -6,7 +6,7 @@
import { requestNotifications } from "$lib/client/notifications-client.js";
import ICONS from "$lib/icons";
import { t } from "$lib/stores/i18n";
import type { NotificationEvent } from "$lib/server/controllers/dashboardController.js";
import type { NotificationEvent } from "$lib/types/notifications.js";
import { onMount } from "svelte";
interface Props {
+1
View File
@@ -87,6 +87,7 @@
"Notifications": "Notifications",
"One-time": "One-time",
"Ongoing": "Ongoing",
"Open events page": "Open events page",
"Operational": "Operational",
"Partial Degraded Performance": "Partial Degraded Performance",
"Partial System Outage": "Partial System Outage",
@@ -17,6 +17,9 @@ import type {
import type { GroupMonitorTypeData } from "../types/monitor.js";
import GC from "../../global-constants.js";
import type { LayoutServerData } from "./layoutController.js";
import type { NotificationEvent } from "../../types/notifications.js";
export type { NotificationEvent };
// Default page settings
const defaultPageSettings: PageSettingsType = {
@@ -27,16 +30,6 @@ const defaultPageSettings: PageSettingsType = {
monitor_layout_style: GC.DEFAULT_MONITOR_LAYOUT_STYLE,
};
export interface NotificationEvent {
eventURL: string;
eventTitle: string;
eventDate: string;
eventType: string;
eventStartDateTime: number;
eventEndDateTime: number | null;
eventStatus: string;
}
export interface NotificationPayload {
notifications: NotificationEvent[];
}
@@ -80,7 +80,8 @@ function NormalizeEventDisplaySettings(settings?: Partial<EventDisplaySettings>)
const defaults = structuredClone(seedSiteData.eventDisplaySettings);
return {
showInlineEvents: Boolean(settings?.showInlineEvents ?? defaults.showInlineEvents),
showInlineEvents:
typeof settings?.showInlineEvents === "boolean" ? settings.showInlineEvents : defaults.showInlineEvents,
incidents: {
...defaults.incidents,
...settings?.incidents,
+9
View File
@@ -0,0 +1,9 @@
export interface NotificationEvent {
eventURL: string;
eventTitle: string;
eventDate: string;
eventType: string;
eventStartDateTime: number;
eventEndDateTime: number | null;
eventStatus: string;
}
+1 -1
View File
@@ -172,7 +172,7 @@
</Item.Root>
</div>
<div class="grid grid-cols-1 gap-4 sm:grid-cols-16">
<div class="col-span-1 flex flex-col gap-3 sm:gap-4 {!!!showInlineEvents ? 'sm:col-span-16' : 'sm:col-span-11'}">
<div class="col-span-1 flex flex-col gap-3 sm:gap-4 {!showInlineEvents ? 'sm:col-span-16' : 'sm:col-span-11'}">
{#if !!data.monitorTags.length}
<EventsCard statusClass={data.pageStatus.statusClass} statusText={data.pageStatus.statusSummary} />
{#if showInlineEvents && data.ongoingIncidents && data.ongoingIncidents.length > 0}
+1 -1
View File
@@ -144,7 +144,7 @@
<!-- page title -->
<div class="flex flex-col gap-3 sm:gap-4">
<ThemePlus monitor_tags={data.monitorTags} />
<ThemePlus monitor_tags={data.monitorTags} hideNotificationsPopover={showInlineEvents} />
<div class="flex flex-col gap-2 px-3 py-2 sm:px-4">
{#if data.pageDetails?.page_logo}
<img
@@ -43,7 +43,11 @@
{/if}
</svelte:head>
<div class="flex flex-col gap-3">
<ThemePlus monitor_tags={[data.monitorTag]} embedMonitorTag={data.monitorTag} />
<ThemePlus
monitor_tags={[data.monitorTag]}
embedMonitorTag={data.monitorTag}
hideNotificationsPopover={showInlineEvents}
/>
<div class="flex flex-col gap-2 px-4 py-2">
{#if data.monitorImage}
<img
@@ -510,7 +510,8 @@
const defaults = structuredClone(defaultEventDisplaySettings);
return {
showInlineEvents: Boolean(parsed?.showInlineEvents ?? defaults.showInlineEvents),
showInlineEvents:
typeof parsed?.showInlineEvents === "boolean" ? parsed.showInlineEvents : defaults.showInlineEvents,
incidents: {
...defaults.incidents,
...parsed?.incidents,