Skip to content

Commit fb7b2f6

Browse files
committed
feat(app): toggle all provider models
1 parent e0f1c3c commit fb7b2f6

4 files changed

Lines changed: 37 additions & 5 deletions

File tree

packages/app/src/components/dialog-manage-models.tsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Dialog } from "@opencode-ai/ui/dialog"
22
import { List } from "@opencode-ai/ui/list"
33
import { Switch } from "@opencode-ai/ui/switch"
4+
import { Tooltip } from "@opencode-ai/ui/tooltip"
45
import { Button } from "@opencode-ai/ui/button"
56
import type { Component } from "solid-js"
67
import { useLocal } from "@/context/local"
@@ -18,6 +19,14 @@ export const DialogManageModels: Component = () => {
1819
dialog.show(() => <DialogSelectProvider />)
1920
}
2021
const providerRank = (id: string) => popularProviders.indexOf(id)
22+
const providerList = (providerID: string) => local.model.list().filter((x) => x.provider.id === providerID)
23+
const providerVisible = (providerID: string) =>
24+
providerList(providerID).every((x) => local.model.visible({ modelID: x.id, providerID: x.provider.id }))
25+
const setProviderVisibility = (providerID: string, checked: boolean) => {
26+
providerList(providerID).forEach((x) => {
27+
local.model.setVisibility({ modelID: x.id, providerID: x.provider.id }, checked)
28+
})
29+
}
2130

2231
return (
2332
<Dialog
@@ -36,7 +45,28 @@ export const DialogManageModels: Component = () => {
3645
items={local.model.list()}
3746
filterKeys={["provider.name", "name", "id"]}
3847
sortBy={(a, b) => a.name.localeCompare(b.name)}
39-
groupBy={(x) => x.provider.name}
48+
groupBy={(x) => x.provider.id}
49+
groupHeader={(group) => {
50+
const provider = group.items[0].provider
51+
return (
52+
<>
53+
<span>{provider.name}</span>
54+
<Tooltip
55+
placement="top"
56+
value={language.t("dialog.model.manage.provider.toggle", { provider: provider.name })}
57+
>
58+
<Switch
59+
class="-mr-1"
60+
checked={providerVisible(provider.id)}
61+
onChange={(checked) => setProviderVisibility(provider.id, checked)}
62+
hideLabel
63+
>
64+
{provider.name}
65+
</Switch>
66+
</Tooltip>
67+
</>
68+
)
69+
}}
4070
sortGroupsBy={(a, b) => {
4171
const aRank = providerRank(a.items[0].provider.id)
4272
const bRank = providerRank(b.items[0].provider.id)

packages/app/src/i18n/en.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ export const dict = {
109109
"dialog.model.empty": "No model results",
110110
"dialog.model.manage": "Manage models",
111111
"dialog.model.manage.description": "Customize which models appear in the model selector.",
112+
"dialog.model.manage.provider.toggle": "Toggle all {{provider}} models",
112113

113114
"dialog.model.unpaid.freeModels.title": "Free models provided by OpenCode",
114115
"dialog.model.unpaid.addMore.title": "Add more models from popular providers",

packages/ui/src/components/list.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export interface ListProps<T> extends FilteredListProps<T> {
4545
itemWrapper?: (item: T, node: JSX.Element) => JSX.Element
4646
divider?: boolean
4747
add?: ListAddProps
48+
groupHeader?: (group: { category: string; items: T[] }) => JSX.Element
4849
}
4950

5051
export interface ListRef {
@@ -206,7 +207,7 @@ export function List<T>(props: ListProps<T> & { ref?: (ref: ListRef) => void })
206207
)
207208
}
208209

209-
function GroupHeader(groupProps: { category: string }): JSX.Element {
210+
function GroupHeader(groupProps: { group: { category: string; items: T[] } }): JSX.Element {
210211
const [stuck, setStuck] = createSignal(false)
211212
const [header, setHeader] = createSignal<HTMLDivElement | undefined>(undefined)
212213

@@ -228,7 +229,7 @@ export function List<T>(props: ListProps<T> & { ref?: (ref: ListRef) => void })
228229

229230
return (
230231
<div data-slot="list-header" data-stuck={stuck()} ref={setHeader}>
231-
{groupProps.category}
232+
{props.groupHeader?.(groupProps.group) ?? groupProps.group.category}
232233
</div>
233234
)
234235
}
@@ -323,7 +324,7 @@ export function List<T>(props: ListProps<T> & { ref?: (ref: ListRef) => void })
323324
return (
324325
<div data-slot="list-group">
325326
<Show when={group.category}>
326-
<GroupHeader category={group.category} />
327+
<GroupHeader group={group} />
327328
</Show>
328329
<div data-slot="list-items">
329330
<For each={group.items}>

packages/ui/src/components/switch.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export interface SwitchProps extends ParentProps<ComponentProps<typeof Kobalte>>
1010
export function Switch(props: SwitchProps) {
1111
const [local, others] = splitProps(props, ["children", "class", "hideLabel", "description"])
1212
return (
13-
<Kobalte {...others} data-component="switch">
13+
<Kobalte {...others} class={local.class} data-component="switch">
1414
<Kobalte.Input data-slot="switch-input" />
1515
<Show when={local.children}>
1616
<Kobalte.Label data-slot="switch-label" classList={{ "sr-only": local.hideLabel }}>

0 commit comments

Comments
 (0)