import { useMutation, useSuspenseQuery } from '@tanstack/react-query'
import { Link } from '@tanstack/react-router'
import { useId } from 'react'
import { api, json, read } from '../../../shared/api.ts'
import { ErrorAlert } from '../../../shared/ErrorAlert.tsx'
import { lastError } from '../../../shared/errors.ts'
import { Badge } from '../../../shared/ui/Badge.tsx'
import { Radio } from '../../../shared/ui/controls.tsx'
import { Item, ItemNames } from '../../../shared/ui/ItemList.tsx'
import {
cardAlert,
SettingsEmpty,
SettingsGroup,
SettingsPage,
} from '../../../shared/ui/SettingsPage.tsx'
import { ReorderButtons } from '../components/ReorderButtons.tsx'
import { useModelsChanged } from '../hooks/changes.ts'
import { storedModel } from '../lib/models.ts'
import { moveItem } from '../lib/reorder.ts'
import { type AdminModelEntry, adminModelsQuery } from '../queries.ts'
/** The admin models from every provider, for choosing the default and the order users see. */
export function ModelsAdmin() {
const { data: models } = useSuspenseQuery(adminModelsQuery)
const modelsChanged = useModelsChanged()
const makeDefault = useMutation({
mutationFn: (model: AdminModelEntry) =>
read(api.admin.models.$put({}, json({ ...storedModel(model), default: true }))),
onSuccess: modelsChanged,
})
const reorder = useMutation({
mutationFn: (order: AdminModelEntry[]) =>
read(
api.admin.models.order.$put(
{},
json({ models: order.map(({ provider, id }) => ({ provider, id })) }),
),
),
onSuccess: modelsChanged,
})
return (
The default model, and the order people see models in. Models are added on their
provider's plugin page, under Plugins.
>
}
>
{models.length === 0 && No models yet.}
{models.length > 0 && (
{models.map((model, index) => (
makeDefault.mutate(model)}
onMove={(by) => reorder.mutate(moveItem(models, index, by))}
/>
))}
)}
)
}
interface ModelRowProps {
model: AdminModelEntry
index: number
count: number
/** Whether a move is on its way. */
moving: boolean
onMakeDefault: () => void
onMove: (by: number) => void
}
/**
* A model as a row that is also a radio, which picks it as the default from a click anywhere on
* it, with arrows that move it beside it.
*/
function ModelRow(props: ModelRowProps) {
const model = props.model
const ref = `${model.provider}/${model.id}`
const id = useId()
const warningId = useId()
return (
)
}