107 lines
3.6 KiB
TypeScript
107 lines
3.6 KiB
TypeScript
"use client"
|
|
|
|
import { Button } from "@conusai-kit/ui/primitives"
|
|
|
|
// The enablement controls of the organization's settings page: the current state, the enable
|
|
// button with its typed refusal reasons (plan, policy, quota), and disable — which preserves
|
|
// every collection, document and the service's index.
|
|
|
|
import { describeError, useWrite } from "@conusai-kit/ui/data"
|
|
import { PageSection } from "@conusai-kit/ui/patterns"
|
|
import { type ReactElement, useState } from "react"
|
|
|
|
export interface SettingsSectionLabels {
|
|
readonly heading: string
|
|
readonly state: string
|
|
readonly stateOn: string
|
|
readonly stateOff: string
|
|
readonly backend: string
|
|
readonly backendPlatform: string
|
|
readonly enable: string
|
|
readonly enabling: string
|
|
readonly disable: string
|
|
readonly disabling: string
|
|
readonly enabledDone: string
|
|
readonly disabledDone: string
|
|
readonly planRequired: string
|
|
readonly featureDisabled: string
|
|
readonly quotaExhausted: string
|
|
readonly upgrade: string
|
|
readonly hint: string
|
|
readonly failed: string
|
|
}
|
|
|
|
type View = { kind: "idle" } | { kind: "busy" } | { kind: "message"; text: string; alert: boolean }
|
|
|
|
export function SettingsSection({
|
|
org,
|
|
initial,
|
|
labels,
|
|
}: {
|
|
org: string
|
|
initial: { enabled: boolean; backend: string | null }
|
|
labels: SettingsSectionLabels
|
|
}): ReactElement {
|
|
const enableAi = useWrite<{ org: string }, unknown>("knowledge.settings.enableDocumentAi")
|
|
const disableAi = useWrite<{ org: string }, unknown>("knowledge.settings.disableDocumentAi")
|
|
const [enabled, setEnabled] = useState(initial.enabled)
|
|
const [view, setView] = useState<View>({ kind: "idle" })
|
|
|
|
const enable = async (): Promise<void> => {
|
|
setView({ kind: "busy" })
|
|
try {
|
|
await enableAi.mutate({ org })
|
|
setEnabled(true)
|
|
setView({ kind: "message", text: labels.enabledDone, alert: false })
|
|
} catch (error) {
|
|
const code = (error as { problem?: { code?: string } } | null)?.problem?.code ?? "unknown"
|
|
if (code === "plan_required") {
|
|
setView({ kind: "message", text: `${labels.planRequired} ${labels.upgrade}`, alert: true })
|
|
} else if (code === "quota_exhausted") {
|
|
setView({ kind: "message", text: labels.quotaExhausted, alert: true })
|
|
} else if (code === "feature_disabled") {
|
|
setView({ kind: "message", text: labels.featureDisabled, alert: true })
|
|
} else {
|
|
setView({ kind: "message", text: describeError(error), alert: true })
|
|
}
|
|
}
|
|
}
|
|
|
|
const disable = async (): Promise<void> => {
|
|
setView({ kind: "busy" })
|
|
try {
|
|
await disableAi.mutate({ org })
|
|
setEnabled(false)
|
|
setView({ kind: "message", text: labels.disabledDone, alert: false })
|
|
} catch (error) {
|
|
setView({ kind: "message", text: describeError(error), alert: true })
|
|
}
|
|
}
|
|
|
|
return (
|
|
<PageSection title={labels.heading}>
|
|
<p>{labels.hint}</p>
|
|
<dl>
|
|
<dt>{labels.state}</dt>
|
|
<dd>{enabled ? labels.stateOn : labels.stateOff}</dd>
|
|
{initial.backend !== null ? (
|
|
<>
|
|
<dt>{labels.backend}</dt>
|
|
<dd>{labels.backendPlatform}</dd>
|
|
</>
|
|
) : null}
|
|
</dl>
|
|
{view.kind === "message" ? <p role={view.alert ? "alert" : "status"}>{view.text}</p> : null}
|
|
{enabled ? (
|
|
<Button type="button" disabled={view.kind === "busy"} onClick={() => void disable()}>
|
|
{view.kind === "busy" ? labels.disabling : labels.disable}
|
|
</Button>
|
|
) : (
|
|
<Button type="button" disabled={view.kind === "busy"} onClick={() => void enable()}>
|
|
{view.kind === "busy" ? labels.enabling : labels.enable}
|
|
</Button>
|
|
)}
|
|
</PageSection>
|
|
)
|
|
}
|