"use client"; import { useMemo, useState } from "react"; import Link from "@/components/link"; import type { CanonicalHousekeepingHref, HousekeepingSurface, HousekeepingWorkItem, } from "../contracts"; import type { HousekeepingInboxResponse } from "../inbox/inbox-service"; import { toHousekeepingHref } from "../routing/href"; export interface OperationalInboxLabels { readonly title: string; readonly domainFilter: string; readonly stateFilter: string; readonly priorityFilter: string; readonly all: string; readonly loading: string; readonly empty: string; readonly partial: string; readonly open: string; } export interface OperationalInboxFilters { readonly domain: string; readonly state: string; readonly priority: string; } export function filterOperationalInboxItems( items: readonly HousekeepingWorkItem[], filters: OperationalInboxFilters, ): readonly HousekeepingWorkItem[] { return items.filter( (item) => (filters.domain === "all" || item.domain === filters.domain) && (filters.state === "all" || item.state === filters.state) && (filters.priority === "all" || item.priority === filters.priority), ); } export function projectOperationalInboxHref( href: CanonicalHousekeepingHref, surface: HousekeepingSurface, ) { return toHousekeepingHref(href, surface); } function unique(values: readonly string[]): readonly string[] { return [...new Set(values)].sort((left, right) => left.localeCompare(right)); } export function OperationalInbox({ response, labels, surface, loading = false, titles = {}, }: { readonly response: HousekeepingInboxResponse; readonly labels: OperationalInboxLabels; readonly surface: HousekeepingSurface; readonly loading?: boolean; readonly titles?: Readonly>; }) { const [domain, setDomain] = useState("all"); const [state, setState] = useState("all"); const [priority, setPriority] = useState("all"); const domains = useMemo( () => unique(response.items.map((item) => item.domain)), [response.items], ); const states = useMemo( () => unique(response.items.map((item) => item.state)), [response.items], ); const priorities = useMemo( () => unique(response.items.map((item) => item.priority)), [response.items], ); const items = useMemo( () => filterOperationalInboxItems(response.items, { domain, state, priority, }), [domain, priority, response.items, state], ); return (

{labels.title}

{loading ?

{labels.loading}

: null} {!loading ? ( <>
{response.errors.length > 0 ? (

{labels.partial}

) : null} {items.length === 0 ?

{labels.empty}

: null} ) : null}
); }