@@ -0,0 +1,42 @@
|
||||
"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 }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user