fix literal strings in MM UI

This commit is contained in:
Mary Hipp 2024-02-26 14:40:38 -05:00 committed by Kent Keirsey
parent 49b04f7db8
commit 66f6013436
9 changed files with 90 additions and 63 deletions

View File

@ -692,6 +692,7 @@
"addDiffuserModel": "Add Diffusers",
"addManually": "Add Manually",
"addModel": "Add Model",
"addModels": "Add Models",
"addNew": "Add New",
"addNewModel": "Add New Model",
"addSelected": "Add Selected",
@ -736,6 +737,7 @@
"descriptionValidationMsg": "Add a description for your model",
"deselectAll": "Deselect All",
"diffusersModels": "Diffusers",
"edit": "Edit",
"findModels": "Find Models",
"formMessageDiffusersModelLocation": "Diffusers Model Location",
"formMessageDiffusersModelLocationDesc": "Please enter at least one.",
@ -744,6 +746,7 @@
"height": "Height",
"heightValidationMsg": "Default height of your model.",
"ignoreMismatch": "Ignore Mismatches Between Selected Models",
"imageEncoderModelId": "Image Encoder Model ID",
"importModels": "Import Models",
"importQueue": "Import Queue",
"inpainting": "v1 Inpainting",
@ -774,8 +777,11 @@
"modelMergeHeaderHelp1": "You can merge up to three different models to create a blend that suits your needs.",
"modelMergeHeaderHelp2": "Only Diffusers are available for merging. If you want to merge a checkpoint model, please convert it to Diffusers first.",
"modelMergeInterpAddDifferenceHelp": "In this mode, Model 3 is first subtracted from Model 2. The resulting version is blended with Model 1 with the alpha rate set above.",
"modelMetadata": "Model Metadata",
"modelName": "Model Name",
"modelOne": "Model 1",
"modelsFound": "Models Found",
"modelSettings": "Model Settings",
"modelsMerged": "Models Merged",
"modelsMergeFailed": "Model Merge Failed",
"modelsSynced": "Models Synced",
@ -795,20 +801,24 @@
"notLoaded": "not loaded",
"oliveModels": "Olives",
"onnxModels": "Onnx",
"path": "Path",
"pathToCustomConfig": "Path To Custom Config",
"pickModelType": "Pick Model Type",
"predictionType": "Prediction Type (for Stable Diffusion 2.x Models and occasional Stable Diffusion 1.x Models)",
"predictionType": "Prediction Type",
"prune": "Prune",
"pruneTooltip": "Prune finished imports from queue",
"quickAdd": "Quick Add",
"removeFromQueue": "Remove From Queue",
"repo_id": "Repo ID",
"repoIDValidationMsg": "Online repository of your model",
"repoVariant": "Repo Variant",
"safetensorModels": "SafeTensors",
"sameFolder": "Same folder",
"scan": "Scan",
"scanFolder": "Scan folder",
"scanAgain": "Scan Again",
"scanForModels": "Scan For Models",
"scanResults": "Scan Results",
"search": "Search",
"selectAll": "Select All",
"selectAndAdd": "Select and Add Models Listed Below",
@ -819,9 +829,11 @@
"showExisting": "Show Existing",
"sigmoid": "Sigmoid",
"simpleModelDesc": "Provide a path to a local Diffusers model, local checkpoint / safetensors model a HuggingFace Repo ID, or a checkpoint/diffusers model URL.",
"source": "Source",
"statusConverting": "Converting",
"syncModels": "Sync Models",
"syncModelsDesc": "If your models are out of sync with the backend, you can refresh them up using this option. This is generally handy in cases where you add models to the InvokeAI root folder or autoimport directory after the application has booted.",
"upcastAttention": "Upcast Attention",
"updateModel": "Update Model",
"useCustomConfig": "Use Custom Config",
"v1": "v1",
@ -836,7 +848,8 @@
"variant": "Variant",
"weightedSum": "Weighted Sum",
"width": "Width",
"widthValidationMsg": "Default width of your model."
"widthValidationMsg": "Default width of your model.",
"ztsnrTraining": "ZTSNR Training"
},
"models": {
"addLora": "Add LoRA",

View File

@ -20,7 +20,6 @@ import ControlAdapterShouldAutoConfig from './ControlAdapterShouldAutoConfig';
import ControlNetCanvasImageImports from './imports/ControlNetCanvasImageImports';
import { ParamControlAdapterBeginEnd } from './parameters/ParamControlAdapterBeginEnd';
import ParamControlAdapterControlMode from './parameters/ParamControlAdapterControlMode';
import ParamControlAdapterModel from './parameters/ParamControlAdapterModel';
import ParamControlAdapterProcessorSelect from './parameters/ParamControlAdapterProcessorSelect';
import ParamControlAdapterResizeMode from './parameters/ParamControlAdapterResizeMode';
import ParamControlAdapterWeight from './parameters/ParamControlAdapterWeight';
@ -73,7 +72,7 @@ const ControlAdapterConfig = (props: { id: string; number: number }) => {
</Flex>
<Flex gap={4} alignItems="center">
<Box minW={0} w="full" transitionProperty="common" transitionDuration="0.1s">
<ParamControlAdapterModel id={id} />
{/* <ParamControlAdapterModel id={id} /> */}
</Box>
{activeTabName === 'unifiedCanvas' && <ControlNetCanvasImageImports id={id} />}
<IconButton

View File

@ -126,7 +126,7 @@ export const AdvancedImport = () => {
<Flex flexDirection="column" gap={4} width="100%" pb={10}>
<Flex alignItems="flex-end" gap="4">
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Model Type</FormLabel>
<FormLabel>{t('modelManager.modelType')}</FormLabel>
<ModelTypeSelect<AnyModelConfig> control={control} name="type" />
</FormControl>
<Text px="2" fontSize="xs" textAlign="center">
@ -157,17 +157,17 @@ export const AdvancedImport = () => {
</Flex>
<Flex gap={4}>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Base Model</FormLabel>
<FormLabel>{t('modelManager.baseModel')}</FormLabel>
<BaseModelSelect<AnyModelConfig> control={control} name="base" />
</FormControl>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Format</FormLabel>
<FormLabel>{t('common.format')}</FormLabel>
<ModelFormatSelect<AnyModelConfig> control={control} name="format" />
</FormControl>
</Flex>
<Flex gap={4}>
<FormControl flexDir="column" alignItems="flex-start" gap={1} isInvalid={Boolean(errors.path)}>
<FormLabel>Path</FormLabel>
<FormLabel>{t('modelManager.path')}</FormLabel>
<Input
{...register('path', {
validate: (value) => value.trim().length > 0 || 'Must provide a path',
@ -181,39 +181,39 @@ export const AdvancedImport = () => {
<Flex gap={4}>
{watchedModelFormat === 'diffusers' && (
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Repo Variant</FormLabel>
<FormLabel>{t('modelManager.repoVariant')}</FormLabel>
<RepoVariantSelect<AnyModelConfig> control={control} name="repo_variant" />
</FormControl>
)}
{watchedModelFormat === 'checkpoint' && (
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Config Path</FormLabel>
<FormLabel>{t('modelManager.pathToConfig')}</FormLabel>
<Input {...register('config')} />
</FormControl>
)}
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Variant</FormLabel>
<FormLabel>{t('modelManager.variant')}</FormLabel>
<ModelVariantSelect<AnyModelConfig> control={control} name="variant" />
</FormControl>
</Flex>
<Flex gap={4}>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Prediction Type</FormLabel>
<FormLabel>{t('modelManager.predictionType')}</FormLabel>
<PredictionTypeSelect<AnyModelConfig> control={control} name="prediction_type" />
</FormControl>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Upcast Attention</FormLabel>
<FormLabel>{t('modelManager.upcastAttention')}</FormLabel>
<BooleanSelect<AnyModelConfig> control={control} name="upcast_attention" />
</FormControl>
</Flex>
<Flex gap={4}>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>ZTSNR Training</FormLabel>
<FormLabel>{t('modelManager.ztsnrTraining')}</FormLabel>
<BooleanSelect<AnyModelConfig> control={control} name="ztsnr_training" />
</FormControl>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>VAE Path</FormLabel>
<FormLabel>{t('modelManager.vaeLocation')}</FormLabel>
<Input {...register('vae')} />
</FormControl>
</Flex>
@ -222,7 +222,7 @@ export const AdvancedImport = () => {
{watchedModelType === 'ip_adapter' && (
<Flex gap={4}>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Image Encoder Model ID</FormLabel>
<FormLabel>{t('modelManager.imageEncoderModelId')}</FormLabel>
<Input {...register('image_encoder_model_id')} />
</FormControl>
</Flex>

View File

@ -1,8 +1,8 @@
import { Divider, Flex, Heading, IconButton, Input, InputGroup, InputRightElement } from '@invoke-ai/ui-library';
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
import { t } from 'i18next';
import type { ChangeEventHandler } from 'react';
import { useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { PiXBold } from 'react-icons/pi';
import type { ScanFolderResponse } from 'services/api/endpoints/models';
@ -13,6 +13,7 @@ type ScanModelResultsProps = {
};
export const ScanModelsResults = ({ results }: ScanModelResultsProps) => {
const { t } = useTranslation();
const [searchTerm, setSearchTerm] = useState('');
const filteredResults = useMemo(() => {
@ -36,7 +37,7 @@ export const ScanModelsResults = ({ results }: ScanModelResultsProps) => {
<Flex flexDir="column" gap={2} mt={4} height="100%">
<Flex justifyContent="space-between" alignItems="center">
<Heading fontSize="md" as="h4">
Scan Results
{t('modelManager.scanResults')}
</Heading>
<InputGroup maxW="300px" size="xs">
<Input

View File

@ -1,4 +1,5 @@
import { Box, Flex, Heading, Tab, TabList, TabPanel, TabPanels, Tabs } from '@invoke-ai/ui-library';
import { useTranslation } from 'react-i18next';
import { AdvancedImport } from './AddModelPanel/AdvancedImport';
import { ImportQueue } from './AddModelPanel/ImportQueue/ImportQueue';
@ -6,17 +7,18 @@ import { ScanModelsForm } from './AddModelPanel/ScanModels/ScanModelsForm';
import { SimpleImport } from './AddModelPanel/SimpleImport';
export const ImportModels = () => {
const { t } = useTranslation();
return (
<Flex layerStyle="first" p={3} borderRadius="base" w="full" h="full" flexDir="column" gap={2}>
<Box w="full" p={2}>
<Heading fontSize="xl">Add Model</Heading>
<Heading fontSize="xl">{t('modelManager.addModel')}</Heading>
</Box>
<Box layerStyle="second" borderRadius="base" w="full" h="50%" overflow="hidden">
<Tabs variant="collapse" height="100%">
<TabList>
<Tab>Simple</Tab>
<Tab>Advanced</Tab>
<Tab>Scan</Tab>
<Tab>{t('common.simple')}</Tab>
<Tab>{t('modelManager.advanced')}</Tab>
<Tab>{t('modelManager.scan')}</Tab>
</TabList>
<TabPanels p={3} height="100%">
<TabPanel>

View File

@ -3,11 +3,13 @@ import { useAppDispatch } from 'app/store/storeHooks';
import { SyncModelsIconButton } from 'features/modelManagerV2/components/SyncModels/SyncModelsIconButton';
import { setSelectedModelKey } from 'features/modelManagerV2/store/modelManagerV2Slice';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import ModelList from './ModelManagerPanel/ModelList';
import { ModelListNavigation } from './ModelManagerPanel/ModelListNavigation';
export const ModelManager = () => {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const handleClickAddModel = useCallback(() => {
dispatch(setSelectedModelKey(null));
@ -17,11 +19,11 @@ export const ModelManager = () => {
<Box layerStyle="first" p={3} borderRadius="base" w="50%" h="full">
<Flex w="full" p={3} justifyContent="space-between" alignItems="center">
<Flex gap={2}>
<Heading fontSize="xl">Model Manager</Heading>
<Heading fontSize="xl">{t('common.modelManager')}</Heading>
<SyncModelsIconButton />
</Flex>
<Button colorScheme="invokeYellow" onClick={handleClickAddModel}>
Add Models
{t('modelManager.addModels')}
</Button>
</Flex>
<Box layerStyle="second" p={3} borderRadius="base" w="full" h="full">

View File

@ -2,6 +2,7 @@ import { Button, Menu, MenuButton, MenuItem, MenuList } from '@invoke-ai/ui-libr
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { setFilteredModelType } from 'features/modelManagerV2/store/modelManagerV2Slice';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { IoFilter } from 'react-icons/io5';
export const MODEL_TYPE_LABELS: { [key: string]: string } = {
@ -17,6 +18,7 @@ export const MODEL_TYPE_LABELS: { [key: string]: string } = {
};
export const ModelTypeFilter = () => {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const filteredModelType = useAppSelector((s) => s.modelmanagerV2.filteredModelType);
@ -34,10 +36,10 @@ export const ModelTypeFilter = () => {
return (
<Menu>
<MenuButton as={Button} leftIcon={<IoFilter />}>
{filteredModelType ? MODEL_TYPE_LABELS[filteredModelType] : 'All Models'}
{filteredModelType ? MODEL_TYPE_LABELS[filteredModelType] : t('modelManager.allModels')}
</MenuButton>
<MenuList>
<MenuItem onClick={clearModelType}>All Models</MenuItem>
<MenuItem onClick={clearModelType}>{t('modelManager.allModels')}</MenuItem>
{Object.keys(MODEL_TYPE_LABELS).map((option) => (
<MenuItem
key={option}

View File

@ -143,18 +143,18 @@ export const ModelEdit = () => {
}, [dispatch]);
if (isLoading) {
return <Text>Loading</Text>;
return <Text>{t('common.loading')}</Text>;
}
if (!modelData) {
return <Text>Something went wrong</Text>;
return <Text>{t('common.somethingWentWrong')}</Text>;
}
return (
<Flex flexDir="column" h="full">
<form onSubmit={handleSubmit(onSubmit)}>
<FormControl flexDir="column" alignItems="flex-start" gap={1} isInvalid={Boolean(errors.name)}>
<Flex w="full" justifyContent="space-between" gap={4} alignItems="center">
<FormLabel hidden={true}>Model Name</FormLabel>
<FormLabel hidden={true}>{t('modelManager.modelName')}</FormLabel>
<Input
{...register('name', {
validate: (value) => value.trim().length > 3 || 'Must be at least 3 characters',
@ -164,7 +164,7 @@ export const ModelEdit = () => {
<Flex gap={2}>
<Button size="sm" onClick={handleClickCancel}>
Cancel
{t('common.cancel')}
</Button>
<Button
size="sm"
@ -173,7 +173,7 @@ export const ModelEdit = () => {
isLoading={isSubmitting}
isDisabled={Boolean(Object.keys(errors).length)}
>
Save
{t('common.save')}
</Button>
</Flex>
</Flex>
@ -183,30 +183,30 @@ export const ModelEdit = () => {
<Flex flexDir="column" gap={3} mt="4">
<Flex>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Description</FormLabel>
<FormLabel>{t('modelManager.description')}</FormLabel>
<Textarea fontSize="md" resize="none" {...register('description')} />
</FormControl>
</Flex>
<Heading as="h3" fontSize="md" mt="4">
Model Settings
{t('modelManager.modelSettings')}
</Heading>
<Flex gap={4}>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Base Model</FormLabel>
<FormLabel>{t('modelManager.baseModel')}</FormLabel>
<BaseModelSelect<AnyModelConfig> control={control} name="base" />
</FormControl>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Model Type</FormLabel>
<FormLabel>{t('modelManager.modelType')}</FormLabel>
<ModelTypeSelect<AnyModelConfig> control={control} name="type" />
</FormControl>
</Flex>
<Flex gap={4}>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Format</FormLabel>
<FormLabel>{t('common.format')}</FormLabel>
<ModelFormatSelect<AnyModelConfig> control={control} name="format" />
</FormControl>
<FormControl flexDir="column" alignItems="flex-start" gap={1} isInvalid={Boolean(errors.path)}>
<FormLabel>Path</FormLabel>
<FormLabel>{t('modelManager.path')}</FormLabel>
<Input
{...register('path', {
validate: (value) => value.trim().length > 0 || 'Must provide a path',
@ -220,39 +220,39 @@ export const ModelEdit = () => {
<Flex gap={4}>
{watchedModelFormat === 'diffusers' && (
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Repo Variant</FormLabel>
<FormLabel>{t('modelManager.repoVariant')}</FormLabel>
<RepoVariantSelect<AnyModelConfig> control={control} name="repo_variant" />
</FormControl>
)}
{watchedModelFormat === 'checkpoint' && (
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Config Path</FormLabel>
<FormLabel>{t('modelManager.pathToConfig')}</FormLabel>
<Input {...register('config')} />
</FormControl>
)}
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Variant</FormLabel>
<FormLabel>{t('modelManager.variant')}</FormLabel>
<ModelVariantSelect<AnyModelConfig> control={control} name="variant" />
</FormControl>
</Flex>
<Flex gap={4}>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Prediction Type</FormLabel>
<FormLabel>{t('modelManager.predictionType')}</FormLabel>
<PredictionTypeSelect<AnyModelConfig> control={control} name="prediction_type" />
</FormControl>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Upcast Attention</FormLabel>
<FormLabel>{t('modelManager.upcastAttention')}</FormLabel>
<BooleanSelect<AnyModelConfig> control={control} name="upcast_attention" />
</FormControl>
</Flex>
<Flex gap={4}>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>ZTSNR Training</FormLabel>
<FormLabel>{t('modelManager.ztsnrTraining')}</FormLabel>
<BooleanSelect<AnyModelConfig> control={control} name="ztsnr_training" />
</FormControl>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>VAE Path</FormLabel>
<FormLabel>{t('modelManager.vaeLocation')}</FormLabel>
<Input {...register('vae')} />
</FormControl>
</Flex>
@ -261,7 +261,7 @@ export const ModelEdit = () => {
{watchedModelType === 'ip_adapter' && (
<Flex gap={4}>
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Image Encoder Model ID</FormLabel>
<FormLabel>{t('modelManager.imageEncoderModelId')}</FormLabel>
<Input {...register('image_encoder_model_id')} />
</FormControl>
</Flex>

View File

@ -4,6 +4,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import DataViewer from 'features/gallery/components/ImageMetadataViewer/DataViewer';
import { setSelectedModelMode } from 'features/modelManagerV2/store/modelManagerV2Slice';
import { useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { IoPencil } from 'react-icons/io5';
import { useGetModelConfigQuery, useGetModelMetadataQuery } from 'services/api/endpoints/models';
import type {
@ -21,6 +22,7 @@ import { ModelAttrView } from './ModelAttrView';
import { ModelConvert } from './ModelConvert';
export const ModelView = () => {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const selectedModelKey = useAppSelector((s) => s.modelmanagerV2.selectedModelKey);
const { data, isLoading } = useGetModelConfigQuery(selectedModelKey ?? skipToken);
@ -64,11 +66,11 @@ export const ModelView = () => {
}, [dispatch]);
if (isLoading) {
return <Text>Loading</Text>;
return <Text>{t('common.loading')}</Text>;
}
if (!modelData) {
return <Text>Something went wrong</Text>;
return <Text>{t('common.somethingWentWrong')}</Text>;
}
return (
<Flex flexDir="column" h="full">
@ -78,11 +80,15 @@ export const ModelView = () => {
{modelData.name}
</Heading>
{modelData.source && <Text variant="subtext">Source: {modelData.source}</Text>}
{modelData.source && (
<Text variant="subtext">
{t('modelManager.source')}: {modelData.source}
</Text>
)}
</Flex>
<Flex gap={2}>
<Button size="sm" leftIcon={<IoPencil />} colorScheme="invokeYellow" onClick={handleEditModel}>
Edit
{t('modelManager.edit')}
</Button>
{modelData.type === 'main' && modelData.format === 'checkpoint' && <ModelConvert model={modelData} />}
</Flex>
@ -93,41 +99,43 @@ export const ModelView = () => {
<ModelAttrView label="Description" value={modelData.description} />
</Flex>
<Heading as="h3" fontSize="md" mt="4">
Model Settings
{t('modelManager.modelSettings')}
</Heading>
<Box layerStyle="second" borderRadius="base" p={3}>
<Flex flexDir="column" gap={3}>
<Flex gap={2}>
<ModelAttrView label="Base Model" value={modelData.base} />
<ModelAttrView label="Model Type" value={modelData.type} />
<ModelAttrView label={t('modelManager.baseModel')} value={modelData.base} />
<ModelAttrView label={t('modelManager.modelType')} value={modelData.type} />
</Flex>
<Flex gap={2}>
<ModelAttrView label="Format" value={modelData.format} />
<ModelAttrView label="Path" value={modelData.path} />
<ModelAttrView label={t('common.format')} value={modelData.format} />
<ModelAttrView label={t('modelManager.path')} value={modelData.path} />
</Flex>
{modelData.type === 'main' && (
<>
<Flex gap={2}>
{modelData.format === 'diffusers' && (
<ModelAttrView label="Repo Variant" value={modelData.repo_variant} />
<ModelAttrView label={t('modelManager.repoVariant')} value={modelData.repo_variant} />
)}
{modelData.format === 'checkpoint' && (
<ModelAttrView label={t('modelManager.pathToConfig')} value={modelData.config} />
)}
{modelData.format === 'checkpoint' && <ModelAttrView label="Config Path" value={modelData.config} />}
<ModelAttrView label="Variant" value={modelData.variant} />
<ModelAttrView label={t('modelManager.variant')} value={modelData.variant} />
</Flex>
<Flex gap={2}>
<ModelAttrView label="Prediction Type" value={modelData.prediction_type} />
<ModelAttrView label="Upcast Attention" value={`${modelData.upcast_attention}`} />
<ModelAttrView label={t('modelManager.predictionType')} value={modelData.prediction_type} />
<ModelAttrView label={t('modelManager.upcastAttention')} value={`${modelData.upcast_attention}`} />
</Flex>
<Flex gap={2}>
<ModelAttrView label="ZTSNR Training" value={`${modelData.ztsnr_training}`} />
<ModelAttrView label="VAE" value={modelData.vae} />
<ModelAttrView label={t('modelManager.ztsnrTraining')} value={`${modelData.ztsnr_training}`} />
<ModelAttrView label={t('modelManager.vae')} value={modelData.vae} />
</Flex>
</>
)}
{modelData.type === 'ip_adapter' && (
<Flex gap={2}>
<ModelAttrView label="Image Encoder Model ID" value={modelData.image_encoder_model_id} />
<ModelAttrView label={t('modelManager.imageEncoderModelId')} value={modelData.image_encoder_model_id} />
</Flex>
)}
</Flex>
@ -137,7 +145,7 @@ export const ModelView = () => {
{metadata && (
<>
<Heading as="h3" fontSize="md" mt="4">
Model Metadata
{t('modelManager.modelMetadata')}
</Heading>
<Flex h="full" w="full" p={2}>
<DataViewer label="metadata" data={metadata} />