Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 151 additions & 0 deletions monkeyai/admin/src/components/image-capability-selector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Field, FieldLabel } from "@/components/ui/field"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"

function AspectRatioGlyph({ value }: { value: string }) {
const [rawWidth, rawHeight] = value.split(":").map(Number)
const width = Number.isFinite(rawWidth) && rawWidth > 0 ? rawWidth : 1
const height = Number.isFinite(rawHeight) && rawHeight > 0 ? rawHeight : 1
const scale = Math.min(28 / width, 16 / height)

return (
<span
aria-hidden="true"
className="flex h-4 w-7 items-center justify-center"
>
<span
className="rounded-[3px] border-[1.5px] border-current/60 bg-current/5"
style={{
width: Math.max(5, Math.round(width * scale)),
height: Math.max(5, Math.round(height * scale)),
}}
/>
</span>
)
}

function SelectionHeader({
label,
selected,
total,
selectAllLabel,
onSelectAll,
}: {
label: string
selected: number
total: number
selectAllLabel: string
onSelectAll: () => void
}) {
return (
<div className="flex min-h-7 items-center justify-between gap-3">
<div className="flex items-center gap-2">
<FieldLabel>{label}</FieldLabel>
<Badge className="tabular-nums" variant="secondary">
{selected}/{total}
</Badge>
</div>
<Button
aria-label={`${label}: ${selectAllLabel}`}
className="h-6 px-2 text-xs"
disabled={selected === total}
onClick={onSelectAll}
size="sm"
type="button"
variant="ghost"
>
{selectAllLabel}
</Button>
</div>
)
}

type ImageCapabilitySelectorProps = {
qualities: string[]
aspectRatios: string[]
selectedQualities: string[]
selectedAspectRatios: string[]
qualityLabel: string
aspectRatioLabel: string
selectAllLabel: string
onQualitiesChange: (values: string[]) => void
onAspectRatiosChange: (values: string[]) => void
}

export function ImageCapabilitySelector({
qualities,
aspectRatios,
selectedQualities,
selectedAspectRatios,
qualityLabel,
aspectRatioLabel,
selectAllLabel,
onQualitiesChange,
onAspectRatiosChange,
}: ImageCapabilitySelectorProps) {
return (
<>
<Field>
<SelectionHeader
label={qualityLabel}
selected={selectedQualities.length}
total={qualities.length}
selectAllLabel={selectAllLabel}
onSelectAll={() => onQualitiesChange([...qualities])}
/>
<ToggleGroup
aria-label={qualityLabel}
className="grid w-full grid-cols-[repeat(auto-fit,minmax(7rem,1fr))] gap-2"
multiple
onValueChange={onQualitiesChange}
value={selectedQualities}
>
{qualities.map((value) => (
<ToggleGroupItem
key={value}
aria-label={value}
className="h-9 w-full min-w-0 justify-start rounded-md border border-border bg-background px-3 py-1 text-start shadow-xs transition-[border-color,background-color,transform] hover:border-foreground/25 hover:bg-muted/40 active:scale-[0.98] aria-pressed:border-primary/60 aria-pressed:bg-primary/6 aria-pressed:text-foreground"
value={value}
>
<span className="text-sm font-semibold tracking-tight">
{value}
</span>
</ToggleGroupItem>
))}
</ToggleGroup>
</Field>

<Field>
<SelectionHeader
label={aspectRatioLabel}
selected={selectedAspectRatios.length}
total={aspectRatios.length}
selectAllLabel={selectAllLabel}
onSelectAll={() => onAspectRatiosChange([...aspectRatios])}
/>
<ToggleGroup
aria-label={aspectRatioLabel}
className="grid w-full grid-cols-2 gap-2 sm:grid-cols-4"
multiple
onValueChange={onAspectRatiosChange}
value={selectedAspectRatios}
>
{aspectRatios.map((value) => (
<ToggleGroupItem
key={value}
aria-label={value}
className="h-11 w-full min-w-0 flex-col gap-0.5 rounded-md border border-border bg-background px-2 py-1 text-center shadow-xs transition-[border-color,background-color,transform] hover:border-foreground/25 hover:bg-muted/40 active:scale-[0.98] aria-pressed:border-primary/60 aria-pressed:bg-primary/6 aria-pressed:text-foreground"
value={value}
>
<AspectRatioGlyph value={value} />
<span className="text-xs font-medium tabular-nums" dir="ltr">
{value}
</span>
</ToggleGroupItem>
))}
</ToggleGroup>
</Field>
</>
)
}
4 changes: 2 additions & 2 deletions monkeyai/admin/src/i18n/locales/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,8 @@ export const ar = {
textKind: "نموذج لغوي كبير",
imageKind: "توليد الصور",
imageProvider: "مزود الصور",
imageCapabilitiesUnavailable:
"أدخل معرّف نموذج مدعوم لتحميل خيارات الصور.",
imageCapabilitiesUnavailable: "تعذر تحميل خيارات الصور لهذا المزوّد.",
selectAllSupported: "تحديد كل الخيارات المدعومة",
imageQuality: "دقة الصورة",
aspectRatio: "نسبة الأبعاد",
defaultQuality: "الدقة الافتراضية",
Expand Down
3 changes: 2 additions & 1 deletion monkeyai/admin/src/i18n/locales/de-DE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ export const deDE = {
imageKind: "Bildgenerierung",
imageProvider: "Bildanbieter",
imageCapabilitiesUnavailable:
"Unterstützte Modell-ID eingeben, um Bildoptionen zu laden.",
"Bildoptionen für diesen Anbieter konnten nicht geladen werden.",
selectAllSupported: "Alle unterstützten auswählen",
imageQuality: "Auflösungsstufe",
aspectRatio: "Seitenverhältnis",
defaultQuality: "Standardstufe",
Expand Down
3 changes: 2 additions & 1 deletion monkeyai/admin/src/i18n/locales/en-US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,8 @@ export const enUS = {
mask: "Mask",
taskStatus: "Task status",
imageCapabilitiesUnavailable:
"Enter a supported upstream model ID to load available image options.",
"Unable to load image options for this provider.",
selectAllSupported: "Select all supported",
imageQuality: "Resolution tier",
aspectRatio: "Aspect ratio",
defaultQuality: "Default tier",
Expand Down
3 changes: 2 additions & 1 deletion monkeyai/admin/src/i18n/locales/es-419.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@ export const es419 = {
imageKind: "Generación de imágenes",
imageProvider: "Proveedor de imágenes",
imageCapabilitiesUnavailable:
"Ingresa un ID de modelo compatible para cargar las opciones.",
"No se pudieron cargar las opciones de este proveedor.",
selectAllSupported: "Seleccionar compatibles",
imageQuality: "Nivel de resolución",
aspectRatio: "Relación de aspecto",
defaultQuality: "Nivel predeterminado",
Expand Down
3 changes: 2 additions & 1 deletion monkeyai/admin/src/i18n/locales/fr-FR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ export const frFR = {
imageKind: "Génération d’images",
imageProvider: "Fournisseur d’images",
imageCapabilitiesUnavailable:
"Saisissez un ID de modèle pris en charge pour charger les options.",
"Impossible de charger les options de ce fournisseur.",
selectAllSupported: "Tout sélectionner",
imageQuality: "Niveau de résolution",
aspectRatio: "Format d’image",
defaultQuality: "Niveau par défaut",
Expand Down
3 changes: 2 additions & 1 deletion monkeyai/admin/src/i18n/locales/ja-JP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,8 @@ export const jaJP = {
imageKind: "画像生成",
imageProvider: "画像プロバイダー",
imageCapabilitiesUnavailable:
"対応するモデル ID を入力すると画像設定を読み込みます。",
"このプロバイダーの画像設定を読み込めませんでした。",
selectAllSupported: "対応項目をすべて選択",
imageQuality: "解像度ランク",
aspectRatio: "アスペクト比",
defaultQuality: "既定のランク",
Expand Down
3 changes: 2 additions & 1 deletion monkeyai/admin/src/i18n/locales/ko-KR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,8 @@ export const koKR = {
imageKind: "이미지 생성",
imageProvider: "이미지 공급자",
imageCapabilitiesUnavailable:
"지원되는 모델 ID를 입력하면 이미지 옵션이 표시됩니다.",
"이 공급자의 이미지 옵션을 불러올 수 없습니다.",
selectAllSupported: "지원 항목 모두 선택",
imageQuality: "해상도 등급",
aspectRatio: "화면 비율",
defaultQuality: "기본 등급",
Expand Down
3 changes: 2 additions & 1 deletion monkeyai/admin/src/i18n/locales/ru-RU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@ export const ruRU = {
imageKind: "Генерация изображений",
imageProvider: "Поставщик изображений",
imageCapabilitiesUnavailable:
"Введите поддерживаемый ID модели, чтобы загрузить параметры.",
"Не удалось загрузить параметры этого поставщика.",
selectAllSupported: "Выбрать все поддерживаемые",
imageQuality: "Уровень разрешения",
aspectRatio: "Соотношение сторон",
defaultQuality: "Уровень по умолчанию",
Expand Down
4 changes: 2 additions & 2 deletions monkeyai/admin/src/i18n/locales/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,8 @@ export const zhCN = {
referenceImages: "参考图/原图",
mask: "蒙版",
taskStatus: "任务状态",
imageCapabilitiesUnavailable:
"请输入受支持的上游模型 ID,以加载画质和比例选项。",
imageCapabilitiesUnavailable: "无法加载该供应商的画质和比例选项。",
selectAllSupported: "全选支持项",
imageQuality: "画质档位",
aspectRatio: "比例",
defaultQuality: "默认画质",
Expand Down
4 changes: 2 additions & 2 deletions monkeyai/admin/src/i18n/locales/zh-TW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,8 @@ export const zhTW = {
textKind: "大型語言模型",
imageKind: "生圖模型",
imageProvider: "生圖供應商",
imageCapabilitiesUnavailable:
"請輸入支援的上游模型 ID,以載入畫質與比例選項。",
imageCapabilitiesUnavailable: "無法載入此供應商的畫質與比例選項。",
selectAllSupported: "全選支援項目",
imageQuality: "畫質檔位",
aspectRatio: "比例",
defaultQuality: "預設畫質",
Expand Down
Loading
Loading