Files
2026-11-14 09:56:45 +00:00

43 lines
1.7 KiB
TypeScript

"use client"
// The workspace page's projects, with a count of those ticked. The count exists only in the browser, so the
// loader cannot translate it: the page hands over the message with its placeholder left in, and this island
// fills it with `formatMessage`, which brings the language's plural rules and no catalogue (F10, decision 2).
import { formatMessage } from "@conusai-kit/i18n/format"
import { ResourceList } from "@conusai-kit/ui/patterns"
import { useUiLabel } from "@conusai-kit/ui/primitives"
import { type ReactElement, useState } from "react"
export interface ProjectPickerProps {
readonly label: string
readonly column: string
readonly empty: string
readonly projects: readonly { readonly slug: string; readonly name: string; readonly href: string }[]
/** `{count, plural, ...}`, in the person's language, not yet filled in. */
readonly selected: string
readonly locale: string
}
export function ProjectPicker({ projects, selected, locale, label, column, empty }: ProjectPickerProps): ReactElement {
const [picked, setPicked] = useState<ReadonlySet<string>>(new Set())
const selectAll = useUiLabel("selectAll")
return (
<ResourceList
label={label}
columns={[{ id: "name", header: column, wrap: true }]}
data={projects}
rowId={(project) => project.slug}
rowHref={(project) => project.href}
rowLabel={(project) => project.name}
selectionMode="multiple"
selectionLabel={selectAll}
rowSelectionLabel={(project) => project.name}
selectedKeys={picked}
onSelectionChange={setPicked}
count={formatMessage(selected, { count: picked.size }, locale)}
empty={{ title: empty }}
/>
)
}