feat: Improve setting.model selector

This commit is contained in:
evenwan 2024-09-14 09:31:05 +08:00
parent df62736ff6
commit 84a7afcd94
3 changed files with 30 additions and 10 deletions

View File

@ -5,12 +5,17 @@ import Locale from "../locales";
import { InputRange } from "./input-range"; import { InputRange } from "./input-range";
import { ListItem, Select } from "./ui-lib"; import { ListItem, Select } from "./ui-lib";
import { useAllModels } from "../utils/hooks"; import { useAllModels } from "../utils/hooks";
import { groupBy } from "lodash-es";
export function ModelConfigList(props: { export function ModelConfigList(props: {
modelConfig: ModelConfig; modelConfig: ModelConfig;
updateConfig: (updater: (config: ModelConfig) => void) => void; updateConfig: (updater: (config: ModelConfig) => void) => void;
}) { }) {
const allModels = useAllModels(); const allModels = useAllModels();
const groupModels = groupBy(
allModels.filter((v) => v.available),
"provider.providerName",
);
const value = `${props.modelConfig.model}@${props.modelConfig?.providerName}`; const value = `${props.modelConfig.model}@${props.modelConfig?.providerName}`;
return ( return (
@ -19,6 +24,7 @@ export function ModelConfigList(props: {
<Select <Select
aria-label={Locale.Settings.Model} aria-label={Locale.Settings.Model}
value={value} value={value}
align="left"
onChange={(e) => { onChange={(e) => {
const [model, providerName] = e.currentTarget.value.split("@"); const [model, providerName] = e.currentTarget.value.split("@");
props.updateConfig((config) => { props.updateConfig((config) => {
@ -27,13 +33,15 @@ export function ModelConfigList(props: {
}); });
}} }}
> >
{allModels {Object.keys(groupModels).map((providerName, index) => (
.filter((v) => v.available) <optgroup label={providerName} key={index}>
.map((v, i) => ( {groupModels[providerName].map((v, i) => (
<option value={`${v.name}@${v.provider?.providerName}`} key={i}> <option value={`${v.name}@${v.provider?.providerName}`} key={i}>
{v.displayName}({v.provider?.providerName}) {v.displayName}
</option> </option>
))} ))}
</optgroup>
))}
</Select> </Select>
</ListItem> </ListItem>
<ListItem <ListItem

View File

@ -252,6 +252,12 @@
position: relative; position: relative;
max-width: fit-content; max-width: fit-content;
&.left-align-option {
option {
text-align: left;
}
}
.select-with-icon-select { .select-with-icon-select {
height: 100%; height: 100%;
border: var(--border-in-light); border: var(--border-in-light);

View File

@ -292,13 +292,19 @@ export function PasswordInput(
export function Select( export function Select(
props: React.DetailedHTMLProps< props: React.DetailedHTMLProps<
React.SelectHTMLAttributes<HTMLSelectElement>, React.SelectHTMLAttributes<HTMLSelectElement> & {
align?: "left" | "center";
},
HTMLSelectElement HTMLSelectElement
>, >,
) { ) {
const { className, children, ...otherProps } = props; const { className, children, align, ...otherProps } = props;
return ( return (
<div className={`${styles["select-with-icon"]} ${className}`}> <div
className={`${styles["select-with-icon"]} ${
align === "left" ? styles["left-align-option"] : ""
} ${className}`}
>
<select className={styles["select-with-icon-select"]} {...otherProps}> <select className={styles["select-with-icon-select"]} {...otherProps}>
{children} {children}
</select> </select>