mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-01 03:01:13 -04:00
fix(ui): add missing translations (#5096)
* first string only to test * more strings changed * almost half strings added in json file * more strings added * more changes * few strings and t function changed * resolved * errors resolved * chore(ui): fmt en.json --------- Co-authored-by: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
This commit is contained in:
@@ -17,6 +17,7 @@ import IAIInformationalPopover from 'common/components/IAIInformationalPopover/I
|
||||
import ScrollableContent from 'features/nodes/components/sidePanel/ScrollableContent';
|
||||
import { memo } from 'react';
|
||||
import { FaCircleExclamation } from 'react-icons/fa6';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const selector = createSelector(
|
||||
stateSelector,
|
||||
@@ -38,6 +39,7 @@ const listItemStyles: ChakraProps['sx'] = {
|
||||
};
|
||||
|
||||
const ParamDynamicPromptsPreview = () => {
|
||||
const { t } = useTranslation();
|
||||
const { prompts, parsingError, isLoading, isError } =
|
||||
useAppSelector(selector);
|
||||
|
||||
@@ -69,7 +71,7 @@ const ParamDynamicPromptsPreview = () => {
|
||||
overflow="hidden"
|
||||
textOverflow="ellipsis"
|
||||
>
|
||||
Prompts Preview ({prompts.length})
|
||||
{t('dynamicPrompts.promptsPreview')} ({prompts.length})
|
||||
{parsingError && ` - ${parsingError}`}
|
||||
</FormLabel>
|
||||
<Flex
|
||||
|
||||
@@ -115,7 +115,7 @@ const DeleteBoardModal = (props: Props) => {
|
||||
<AlertDialogOverlay>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader fontSize="lg" fontWeight="bold">
|
||||
Delete {boardToDelete.board_name}
|
||||
{t('controlnet.delete')} {boardToDelete.board_name}
|
||||
</AlertDialogHeader>
|
||||
|
||||
<AlertDialogBody>
|
||||
@@ -136,7 +136,7 @@ const DeleteBoardModal = (props: Props) => {
|
||||
bottomMessage={t('boards.bottomMessage')}
|
||||
/>
|
||||
)}
|
||||
<Text>Deleted boards cannot be restored.</Text>
|
||||
<Text>{t('boards.deletedBoardsCannotbeRestored')}</Text>
|
||||
<Text>
|
||||
{canRestoreDeletedImagesFromBin
|
||||
? t('gallery.deleteImageBin')
|
||||
@@ -149,21 +149,21 @@ const DeleteBoardModal = (props: Props) => {
|
||||
sx={{ justifyContent: 'space-between', width: 'full', gap: 2 }}
|
||||
>
|
||||
<IAIButton ref={cancelRef} onClick={handleClose}>
|
||||
Cancel
|
||||
{t('boards.cancel')}
|
||||
</IAIButton>
|
||||
<IAIButton
|
||||
colorScheme="warning"
|
||||
isLoading={isLoading}
|
||||
onClick={handleDeleteBoardOnly}
|
||||
>
|
||||
Delete Board Only
|
||||
{t('boards.deleteBoardOnly')}
|
||||
</IAIButton>
|
||||
<IAIButton
|
||||
colorScheme="error"
|
||||
isLoading={isLoading}
|
||||
onClick={handleDeleteBoardAndImages}
|
||||
>
|
||||
Delete Board and Images
|
||||
{t('boards.deleteBoardAndImages')}
|
||||
</IAIButton>
|
||||
</Flex>
|
||||
</AlertDialogFooter>
|
||||
|
||||
@@ -2,13 +2,14 @@ import { MenuItem } from '@chakra-ui/react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { FaTrash } from 'react-icons/fa';
|
||||
import { BoardDTO } from 'services/api/types';
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
type Props = {
|
||||
board: BoardDTO;
|
||||
setBoardToDelete?: (board?: BoardDTO) => void;
|
||||
};
|
||||
|
||||
const GalleryBoardContextMenuItems = ({ board, setBoardToDelete }: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const handleDelete = useCallback(() => {
|
||||
if (!setBoardToDelete) {
|
||||
return;
|
||||
@@ -34,7 +35,7 @@ const GalleryBoardContextMenuItems = ({ board, setBoardToDelete }: Props) => {
|
||||
icon={<FaTrash />}
|
||||
onClick={handleDelete}
|
||||
>
|
||||
Delete Board
|
||||
{t('boards.deleteBoard')}
|
||||
</MenuItem>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -170,7 +170,10 @@ const CurrentImagePreview = () => {
|
||||
useThumbailFallback
|
||||
dropLabel={t('gallery.setCurrentImage')}
|
||||
noContentFallback={
|
||||
<IAINoContentFallback icon={FaImage} label="No image selected" />
|
||||
<IAINoContentFallback
|
||||
icon={FaImage}
|
||||
label={t('gallery.noImageSelected')}
|
||||
/>
|
||||
}
|
||||
dataTestId="image-preview"
|
||||
/>
|
||||
|
||||
@@ -104,7 +104,7 @@ const MultipleSelectionMenuItems = () => {
|
||||
</MenuItem>
|
||||
)}
|
||||
<MenuItem icon={<FaFolder />} onClickCapture={handleChangeBoard}>
|
||||
Change Board
|
||||
{t('boards.changeBoard')}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
sx={{ color: 'error.600', _dark: { color: 'error.300' } }}
|
||||
|
||||
@@ -224,14 +224,14 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => {
|
||||
</MenuItem>
|
||||
)}
|
||||
<MenuItem icon={<FaFolder />} onClickCapture={handleChangeBoard}>
|
||||
Change Board
|
||||
{t('boards.changeBoard')}
|
||||
</MenuItem>
|
||||
{imageDTO.starred ? (
|
||||
<MenuItem
|
||||
icon={customStarUi ? customStarUi.off.icon : <MdStar />}
|
||||
onClickCapture={handleUnstarImage}
|
||||
>
|
||||
{customStarUi ? customStarUi.off.text : `Unstar Image`}
|
||||
{customStarUi ? customStarUi.off.text : t('controlnet.unstarImage')}
|
||||
</MenuItem>
|
||||
) : (
|
||||
<MenuItem
|
||||
|
||||
@@ -95,7 +95,7 @@ const ParamLoRASelect = () => {
|
||||
|
||||
return (
|
||||
<IAIMantineSearchableSelect
|
||||
placeholder={data.length === 0 ? 'All LoRAs added' : 'Add LoRA'}
|
||||
placeholder={data.length === 0 ? 'All LoRAs added' : t('models.addLora')}
|
||||
value={null}
|
||||
data={data}
|
||||
nothingFound="No matching LoRAs"
|
||||
|
||||
@@ -3,8 +3,10 @@ import IAIButton from 'common/components/IAIButton';
|
||||
import { useCallback, useState } from 'react';
|
||||
import AdvancedAddModels from './AdvancedAddModels';
|
||||
import SimpleAddModels from './SimpleAddModels';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function AddModels() {
|
||||
const { t } = useTranslation();
|
||||
const [addModelMode, setAddModelMode] = useState<'simple' | 'advanced'>(
|
||||
'simple'
|
||||
);
|
||||
@@ -27,14 +29,14 @@ export default function AddModels() {
|
||||
isChecked={addModelMode == 'simple'}
|
||||
onClick={handleAddModelSimple}
|
||||
>
|
||||
Simple
|
||||
{t('common.simple')}
|
||||
</IAIButton>
|
||||
<IAIButton
|
||||
size="sm"
|
||||
isChecked={addModelMode == 'advanced'}
|
||||
onClick={handleAddModelAdvanced}
|
||||
>
|
||||
Advanced
|
||||
{t('common.advanced')}
|
||||
</IAIButton>
|
||||
</ButtonGroup>
|
||||
<Flex
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { SelectItem } from '@mantine/core';
|
||||
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import AdvancedAddCheckpoint from './AdvancedAddCheckpoint';
|
||||
import AdvancedAddDiffusers from './AdvancedAddDiffusers';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const advancedAddModeData: SelectItem[] = [
|
||||
{ label: 'Diffusers', value: 'diffusers' },
|
||||
{ label: 'Checkpoint / Safetensors', value: 'checkpoint' },
|
||||
];
|
||||
|
||||
export type ManualAddMode = 'diffusers' | 'checkpoint';
|
||||
|
||||
export default function AdvancedAddModels() {
|
||||
@@ -25,6 +20,14 @@ export default function AdvancedAddModels() {
|
||||
setAdvancedAddMode(v as ManualAddMode);
|
||||
}, []);
|
||||
|
||||
const advancedAddModeData: SelectItem[] = useMemo(
|
||||
() => [
|
||||
{ label: t('modelManager.diffusersModels'), value: 'diffusers' },
|
||||
{ label: t('modelManager.checkpointOrSafetensors'), value: 'checkpoint' },
|
||||
],
|
||||
[t]
|
||||
);
|
||||
|
||||
return (
|
||||
<Flex flexDirection="column" gap={4} width="100%">
|
||||
<IAIMantineSelect
|
||||
|
||||
@@ -4,13 +4,14 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import IAIIconButton from 'common/components/IAIIconButton';
|
||||
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useCallback, useEffect, useState, useMemo } from 'react';
|
||||
import { FaTimes } from 'react-icons/fa';
|
||||
import { setAdvancedAddScanModel } from '../../store/modelManagerSlice';
|
||||
import AdvancedAddCheckpoint from './AdvancedAddCheckpoint';
|
||||
import AdvancedAddDiffusers from './AdvancedAddDiffusers';
|
||||
import { ManualAddMode, advancedAddModeData } from './AdvancedAddModels';
|
||||
import { ManualAddMode } from './AdvancedAddModels';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { SelectItem } from '@mantine/core';
|
||||
|
||||
export default function ScanAdvancedAddModels() {
|
||||
const advancedAddScanModel = useAppSelector(
|
||||
@@ -19,6 +20,14 @@ export default function ScanAdvancedAddModels() {
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const advancedAddModeData: SelectItem[] = useMemo(
|
||||
() => [
|
||||
{ label: t('modelManager.diffusersModels'), value: 'diffusers' },
|
||||
{ label: t('modelManager.checkpointOrSafetensors'), value: 'checkpoint' },
|
||||
],
|
||||
[t]
|
||||
);
|
||||
|
||||
const [advancedAddMode, setAdvancedAddMode] =
|
||||
useState<ManualAddMode>('diffusers');
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ export default function MergeModelsPanel() {
|
||||
|
||||
<Flex columnGap={4}>
|
||||
<IAIMantineSelect
|
||||
label="Model Type"
|
||||
label={t('modelManager.modelType')}
|
||||
w="100%"
|
||||
data={baseModelTypeSelectData}
|
||||
value={baseModel}
|
||||
|
||||
@@ -13,6 +13,7 @@ import DiffusersModelEdit from './ModelManagerPanel/DiffusersModelEdit';
|
||||
import LoRAModelEdit from './ModelManagerPanel/LoRAModelEdit';
|
||||
import ModelList from './ModelManagerPanel/ModelList';
|
||||
import { ALL_BASE_MODELS } from 'services/api/constants';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function ModelManagerPanel() {
|
||||
const [selectedModelId, setSelectedModelId] = useState<string>();
|
||||
@@ -45,6 +46,7 @@ type ModelEditProps = {
|
||||
};
|
||||
|
||||
const ModelEdit = (props: ModelEditProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { model } = props;
|
||||
|
||||
if (model?.model_format === 'checkpoint') {
|
||||
@@ -75,7 +77,7 @@ const ModelEdit = (props: ModelEditProps) => {
|
||||
userSelect: 'none',
|
||||
}}
|
||||
>
|
||||
<Text variant="subtext">No Model Selected</Text>
|
||||
<Text variant="subtext">{t('modelManager.noModelSelected')}</Text>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -54,7 +54,7 @@ export default function SyncModelsButton(props: SyncModelsButtonProps) {
|
||||
minW="max-content"
|
||||
{...rest}
|
||||
>
|
||||
Sync Models
|
||||
{t('modelManager.syncModels')}
|
||||
</IAIButton>
|
||||
) : (
|
||||
<IAIIconButton
|
||||
|
||||
@@ -127,7 +127,7 @@ const WorkflowEditorSettings = forwardRef((_, ref) => {
|
||||
py: 4,
|
||||
}}
|
||||
>
|
||||
<Heading size="sm">General</Heading>
|
||||
<Heading size="sm">{t('parameters.general')}</Heading>
|
||||
<IAISwitch
|
||||
formLabelProps={formLabelProps}
|
||||
onChange={handleChangeShouldAnimate}
|
||||
@@ -159,7 +159,7 @@ const WorkflowEditorSettings = forwardRef((_, ref) => {
|
||||
helperText={t('nodes.fullyContainNodesHelp')}
|
||||
/>
|
||||
<Heading size="sm" pt={4}>
|
||||
Advanced
|
||||
{t('common.advanced')}
|
||||
</Heading>
|
||||
<IAISwitch
|
||||
formLabelProps={formLabelProps}
|
||||
|
||||
@@ -10,9 +10,11 @@ import { memo } from 'react';
|
||||
import InspectorDataTab from './InspectorDataTab';
|
||||
import InspectorOutputsTab from './InspectorOutputsTab';
|
||||
import InspectorTemplateTab from './InspectorTemplateTab';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import InspectorDetailsTab from './InspectorDetailsTab';
|
||||
|
||||
const InspectorPanel = () => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Flex
|
||||
layerStyle="first"
|
||||
@@ -30,10 +32,10 @@ const InspectorPanel = () => {
|
||||
sx={{ display: 'flex', flexDir: 'column', w: 'full', h: 'full' }}
|
||||
>
|
||||
<TabList>
|
||||
<Tab>Details</Tab>
|
||||
<Tab>Outputs</Tab>
|
||||
<Tab>Data</Tab>
|
||||
<Tab>Template</Tab>
|
||||
<Tab>{t('common.details')}</Tab>
|
||||
<Tab>{t('common.outputs')}</Tab>
|
||||
<Tab>{t('common.data')}</Tab>
|
||||
<Tab>{t('common.template')}</Tab>
|
||||
</TabList>
|
||||
|
||||
<TabPanels>
|
||||
|
||||
@@ -10,8 +10,10 @@ import { memo } from 'react';
|
||||
import WorkflowGeneralTab from './WorkflowGeneralTab';
|
||||
import WorkflowJSONTab from './WorkflowJSONTab';
|
||||
import WorkflowLinearTab from './WorkflowLinearTab';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const WorkflowPanel = () => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Flex
|
||||
layerStyle="first"
|
||||
@@ -29,8 +31,8 @@ const WorkflowPanel = () => {
|
||||
sx={{ display: 'flex', flexDir: 'column', w: 'full', h: 'full' }}
|
||||
>
|
||||
<TabList>
|
||||
<Tab>Linear</Tab>
|
||||
<Tab>Details</Tab>
|
||||
<Tab>{t('common.linear')}</Tab>
|
||||
<Tab>{t('common.details')}</Tab>
|
||||
<Tab>JSON</Tab>
|
||||
</TabList>
|
||||
|
||||
|
||||
@@ -5,16 +5,9 @@ import { IAISelectDataType } from 'common/components/IAIMantineSearchableSelect'
|
||||
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
||||
import { setCanvasCoherenceMode } from 'features/parameters/store/generationSlice';
|
||||
import { CanvasCoherenceModeParam } from 'features/parameters/types/parameterSchemas';
|
||||
|
||||
import { memo, useCallback } from 'react';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const coherenceModeSelectData: IAISelectDataType[] = [
|
||||
{ label: 'Unmasked', value: 'unmasked' },
|
||||
{ label: 'Mask', value: 'mask' },
|
||||
{ label: 'Mask Edge', value: 'edge' },
|
||||
];
|
||||
|
||||
const ParamCanvasCoherenceMode = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const canvasCoherenceMode = useAppSelector(
|
||||
@@ -22,6 +15,15 @@ const ParamCanvasCoherenceMode = () => {
|
||||
);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const coherenceModeSelectData: IAISelectDataType[] = useMemo(
|
||||
() => [
|
||||
{ label: t('parameters.unmasked'), value: 'unmasked' },
|
||||
{ label: t('unifiedCanvas.mask'), value: 'mask' },
|
||||
{ label: t('parameters.maskEdge'), value: 'edge' },
|
||||
],
|
||||
[t]
|
||||
);
|
||||
|
||||
const handleCoherenceModeChange = useCallback(
|
||||
(v: string | null) => {
|
||||
if (!v) {
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import { useCanvasGenerationMode } from 'features/canvas/hooks/useCanvasGenerationMode';
|
||||
import { memo } from 'react';
|
||||
|
||||
const GENERATION_MODE_NAME_MAP = {
|
||||
txt2img: 'Text to Image',
|
||||
img2img: 'Image to Image',
|
||||
inpaint: 'Inpaint',
|
||||
outpaint: 'Inpaint',
|
||||
};
|
||||
import { memo, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const GenerationModeStatusText = () => {
|
||||
const generationMode = useCanvasGenerationMode();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const GENERATION_MODE_NAME_MAP = useMemo(
|
||||
() => ({
|
||||
txt2img: t('common.txt2img'),
|
||||
img2img: t('common.img2img'),
|
||||
inpaint: t('common.inpaint'),
|
||||
outpaint: t('common.outpaint'),
|
||||
}),
|
||||
[t]
|
||||
);
|
||||
|
||||
return (
|
||||
<Box>
|
||||
Mode: {generationMode ? GENERATION_MODE_NAME_MAP[generationMode] : '...'}
|
||||
{t('accessibility.mode')}:{' '}
|
||||
{generationMode ? GENERATION_MODE_NAME_MAP[generationMode] : '...'}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
ESRGANModelName,
|
||||
esrganModelNameChanged,
|
||||
} from 'features/parameters/store/postprocessingSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const ESRGAN_MODEL_NAMES: SelectItem[] = [
|
||||
@@ -37,6 +38,8 @@ export const ESRGAN_MODEL_NAMES: SelectItem[] = [
|
||||
];
|
||||
|
||||
export default function ParamESRGANModel() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const esrganModelName = useAppSelector(
|
||||
(state: RootState) => state.postprocessing.esrganModelName
|
||||
);
|
||||
@@ -50,7 +53,7 @@ export default function ParamESRGANModel() {
|
||||
|
||||
return (
|
||||
<IAIMantineSelect
|
||||
label="ESRGAN Model"
|
||||
label={t('models.esrganModel')}
|
||||
value={esrganModelName}
|
||||
itemComponent={IAIMantineSelectItemWithTooltip}
|
||||
onChange={handleChange}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Flex, Text } from '@chakra-ui/react';
|
||||
import { memo } from 'react';
|
||||
import { COLUMN_WIDTHS } from './constants';
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
const QueueListHeader = () => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Flex
|
||||
alignItems="center"
|
||||
@@ -22,16 +23,16 @@ const QueueListHeader = () => {
|
||||
<Text variant="subtext">#</Text>
|
||||
</Flex>
|
||||
<Flex ps={0.5} w={COLUMN_WIDTHS.statusBadge} alignItems="center">
|
||||
<Text variant="subtext">status</Text>
|
||||
<Text variant="subtext">{t('queue.status')}</Text>
|
||||
</Flex>
|
||||
<Flex ps={0.5} w={COLUMN_WIDTHS.time} alignItems="center">
|
||||
<Text variant="subtext">time</Text>
|
||||
<Text variant="subtext">{t('queue.time')}</Text>
|
||||
</Flex>
|
||||
<Flex ps={0.5} w={COLUMN_WIDTHS.batchId} alignItems="center">
|
||||
<Text variant="subtext">batch</Text>
|
||||
<Text variant="subtext">{t('queue.batch')}</Text>
|
||||
</Flex>
|
||||
<Flex ps={0.5} w={COLUMN_WIDTHS.fieldValues} alignItems="center">
|
||||
<Text variant="subtext">batch field values</Text>
|
||||
<Text variant="subtext">{t('queue.batchFieldValues')}</Text>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
@@ -298,13 +298,13 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
|
||||
<Heading size="sm">{t('settings.generation')}</Heading>
|
||||
<SettingsSchedulers />
|
||||
<SettingSwitch
|
||||
label="Enable NSFW Checker"
|
||||
label={t('settings.enableNSFWChecker')}
|
||||
isDisabled={!isNSFWCheckerAvailable}
|
||||
isChecked={shouldUseNSFWChecker}
|
||||
onChange={handleChangeShouldUseNSFWChecker}
|
||||
/>
|
||||
<SettingSwitch
|
||||
label="Enable Invisible Watermark"
|
||||
label={t('settings.enableInvisibleWatermark')}
|
||||
isDisabled={!isWatermarkerAvailable}
|
||||
isChecked={shouldUseWatermarker}
|
||||
onChange={handleChangeShouldUseWatermarker}
|
||||
@@ -351,7 +351,7 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
|
||||
/>
|
||||
)}
|
||||
<SettingSwitch
|
||||
label="Enable informational popovers"
|
||||
label={t('settings.enableInformationalPopovers')}
|
||||
isChecked={shouldEnableInformationalPopovers}
|
||||
onChange={handleChangeShouldEnableInformationalPopovers}
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Tab, TabList, TabPanel, TabPanels, Tabs } from '@chakra-ui/react';
|
||||
import i18n from 'i18n';
|
||||
import { ReactNode, memo } from 'react';
|
||||
import { ReactNode, memo, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import ImportModelsPanel from '../../../../modelManager/subpanels/ImportModelsPanel';
|
||||
import MergeModelsPanel from '../../../../modelManager/subpanels/MergeModelsPanel';
|
||||
import ModelManagerPanel from '../../../../modelManager/subpanels/ModelManagerPanel';
|
||||
@@ -18,30 +18,34 @@ type ModelManagerTabInfo = {
|
||||
content: ReactNode;
|
||||
};
|
||||
|
||||
const tabs: ModelManagerTabInfo[] = [
|
||||
{
|
||||
id: 'modelManager',
|
||||
label: i18n.t('modelManager.modelManager'),
|
||||
content: <ModelManagerPanel />,
|
||||
},
|
||||
{
|
||||
id: 'importModels',
|
||||
label: i18n.t('modelManager.importModels'),
|
||||
content: <ImportModelsPanel />,
|
||||
},
|
||||
{
|
||||
id: 'mergeModels',
|
||||
label: i18n.t('modelManager.mergeModels'),
|
||||
content: <MergeModelsPanel />,
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: i18n.t('modelManager.settings'),
|
||||
content: <ModelManagerSettingsPanel />,
|
||||
},
|
||||
];
|
||||
|
||||
const ModelManagerTab = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const tabs: ModelManagerTabInfo[] = useMemo(
|
||||
() => [
|
||||
{
|
||||
id: 'modelManager',
|
||||
label: t('modelManager.modelManager'),
|
||||
content: <ModelManagerPanel />,
|
||||
},
|
||||
{
|
||||
id: 'importModels',
|
||||
label: t('modelManager.importModels'),
|
||||
content: <ImportModelsPanel />,
|
||||
},
|
||||
{
|
||||
id: 'mergeModels',
|
||||
label: t('modelManager.mergeModels'),
|
||||
content: <MergeModelsPanel />,
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: t('modelManager.settings'),
|
||||
content: <ModelManagerSettingsPanel />,
|
||||
},
|
||||
],
|
||||
[t]
|
||||
);
|
||||
return (
|
||||
<Tabs
|
||||
isLazy
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useDroppableTypesafe } from 'features/dnd/hooks/typesafeHooks';
|
||||
import { CanvasInitialImageDropData } from 'features/dnd/types';
|
||||
import { isValidDrop } from 'features/dnd/util/isValidDrop';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const droppableData: CanvasInitialImageDropData = {
|
||||
id: 'canvas-intial-image',
|
||||
@@ -13,6 +14,7 @@ const droppableData: CanvasInitialImageDropData = {
|
||||
};
|
||||
|
||||
const UnifiedCanvasContent = () => {
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
isOver,
|
||||
setNodeRef: setDroppableRef,
|
||||
@@ -40,7 +42,10 @@ const UnifiedCanvasContent = () => {
|
||||
<IAICanvasToolbar />
|
||||
<IAICanvas />
|
||||
{isValidDrop(droppableData, active) && (
|
||||
<IAIDropOverlay isOver={isOver} label="Set Canvas Initial Image" />
|
||||
<IAIDropOverlay
|
||||
isOver={isOver}
|
||||
label={t('toast.setCanvasInitialImage')}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user