mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Model Form Styling
This commit is contained in:
parent
df858eb3f9
commit
ce6fb8ea29
@ -6,7 +6,7 @@ interface IAIInputProps extends InputProps {
|
|||||||
label?: string;
|
label?: string;
|
||||||
width?: string | number;
|
width?: string | number;
|
||||||
value?: string;
|
value?: string;
|
||||||
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
|
onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function IAIInput(props: IAIInputProps) {
|
export default function IAIInput(props: IAIInputProps) {
|
||||||
@ -26,17 +26,19 @@ export default function IAIInput(props: IAIInputProps) {
|
|||||||
isInvalid={isInvalid}
|
isInvalid={isInvalid}
|
||||||
isDisabled={isDisabled}
|
isDisabled={isDisabled}
|
||||||
>
|
>
|
||||||
<FormLabel
|
{label !== '' && (
|
||||||
fontSize={fontSize}
|
<FormLabel
|
||||||
fontWeight="bold"
|
fontSize={fontSize}
|
||||||
alignItems="center"
|
fontWeight="bold"
|
||||||
whiteSpace="nowrap"
|
alignItems="center"
|
||||||
marginBottom={0}
|
whiteSpace="nowrap"
|
||||||
marginRight={0}
|
marginBottom={0}
|
||||||
className="input-label"
|
marginRight={0}
|
||||||
>
|
className="input-label"
|
||||||
{label}
|
>
|
||||||
</FormLabel>
|
{label}
|
||||||
|
</FormLabel>
|
||||||
|
)}
|
||||||
<Input {...rest} className="input-entry" size={'sm'} width={width} />
|
<Input {...rest} className="input-entry" size={'sm'} width={width} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
|
@ -24,7 +24,7 @@ interface Props extends Omit<NumberInputProps, 'onChange'> {
|
|||||||
labelFontSize?: string | number;
|
labelFontSize?: string | number;
|
||||||
width?: string | number;
|
width?: string | number;
|
||||||
showStepper?: boolean;
|
showStepper?: boolean;
|
||||||
value: number;
|
value?: number;
|
||||||
onChange: (v: number) => void;
|
onChange: (v: number) => void;
|
||||||
min: number;
|
min: number;
|
||||||
max: number;
|
max: number;
|
||||||
|
@ -1,40 +1,40 @@
|
|||||||
import {
|
import {
|
||||||
Button,
|
|
||||||
Flex,
|
Flex,
|
||||||
FormControl,
|
FormControl,
|
||||||
FormErrorMessage,
|
FormErrorMessage,
|
||||||
FormHelperText,
|
FormHelperText,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
HStack,
|
HStack,
|
||||||
Input,
|
|
||||||
Modal,
|
Modal,
|
||||||
ModalBody,
|
ModalBody,
|
||||||
ModalCloseButton,
|
ModalCloseButton,
|
||||||
ModalContent,
|
ModalContent,
|
||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
NumberDecrementStepper,
|
|
||||||
NumberIncrementStepper,
|
|
||||||
NumberInput,
|
|
||||||
NumberInputField,
|
|
||||||
NumberInputStepper,
|
|
||||||
Text,
|
Text,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
VStack,
|
VStack,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FaPlus } from 'react-icons/fa';
|
import IAIInput from 'common/components/IAIInput';
|
||||||
import { Field, FieldInputProps, Formik, FormikProps } from 'formik';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
import type { RootState } from 'app/store';
|
|
||||||
import { addNewModel } from 'app/socketio/actions';
|
|
||||||
import type { InvokeModelConfigProps } from 'app/invokeai';
|
|
||||||
import IAICheckbox from 'common/components/IAICheckbox';
|
import IAICheckbox from 'common/components/IAICheckbox';
|
||||||
import IAIButton from 'common/components/IAIButton';
|
import IAIButton from 'common/components/IAIButton';
|
||||||
|
|
||||||
import SearchModels from './SearchModels';
|
import SearchModels from './SearchModels';
|
||||||
|
|
||||||
|
import { addNewModel } from 'app/socketio/actions';
|
||||||
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
|
import { FaPlus } from 'react-icons/fa';
|
||||||
|
import { Field, Formik } from 'formik';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import type { FieldInputProps, FormikProps } from 'formik';
|
||||||
|
import type { RootState } from 'app/store';
|
||||||
|
import type { InvokeModelConfigProps } from 'app/invokeai';
|
||||||
|
|
||||||
const MIN_MODEL_SIZE = 64;
|
const MIN_MODEL_SIZE = 64;
|
||||||
const MAX_MODEL_SIZE = 2048;
|
const MAX_MODEL_SIZE = 2048;
|
||||||
|
|
||||||
@ -128,16 +128,17 @@ export default function AddModel() {
|
|||||||
isInvalid={!!errors.name && touched.name}
|
isInvalid={!!errors.name && touched.name}
|
||||||
isRequired
|
isRequired
|
||||||
>
|
>
|
||||||
<FormLabel htmlFor="name">
|
<FormLabel htmlFor="name" fontSize="sm">
|
||||||
{t('modelmanager:name')}
|
{t('modelmanager:name')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<VStack alignItems={'start'}>
|
<VStack alignItems={'start'}>
|
||||||
<Field
|
<Field
|
||||||
as={Input}
|
as={IAIInput}
|
||||||
id="name"
|
id="name"
|
||||||
name="name"
|
name="name"
|
||||||
type="text"
|
type="text"
|
||||||
validate={baseValidation}
|
validate={baseValidation}
|
||||||
|
width="lg"
|
||||||
/>
|
/>
|
||||||
{!!errors.name && touched.name ? (
|
{!!errors.name && touched.name ? (
|
||||||
<FormErrorMessage>{errors.name}</FormErrorMessage>
|
<FormErrorMessage>{errors.name}</FormErrorMessage>
|
||||||
@ -154,15 +155,16 @@ export default function AddModel() {
|
|||||||
isInvalid={!!errors.description && touched.description}
|
isInvalid={!!errors.description && touched.description}
|
||||||
isRequired
|
isRequired
|
||||||
>
|
>
|
||||||
<FormLabel htmlFor="description">
|
<FormLabel htmlFor="description" fontSize="sm">
|
||||||
{t('modelmanager:description')}
|
{t('modelmanager:description')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<VStack alignItems={'start'}>
|
<VStack alignItems={'start'}>
|
||||||
<Field
|
<Field
|
||||||
as={Input}
|
as={IAIInput}
|
||||||
id="description"
|
id="description"
|
||||||
name="description"
|
name="description"
|
||||||
type="text"
|
type="text"
|
||||||
|
width="lg"
|
||||||
/>
|
/>
|
||||||
{!!errors.description && touched.description ? (
|
{!!errors.description && touched.description ? (
|
||||||
<FormErrorMessage>
|
<FormErrorMessage>
|
||||||
@ -181,15 +183,16 @@ export default function AddModel() {
|
|||||||
isInvalid={!!errors.config && touched.config}
|
isInvalid={!!errors.config && touched.config}
|
||||||
isRequired
|
isRequired
|
||||||
>
|
>
|
||||||
<FormLabel htmlFor="config">
|
<FormLabel htmlFor="config" fontSize="sm">
|
||||||
{t('modelmanager:config')}
|
{t('modelmanager:config')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<VStack alignItems={'start'}>
|
<VStack alignItems={'start'}>
|
||||||
<Field
|
<Field
|
||||||
as={Input}
|
as={IAIInput}
|
||||||
id="config"
|
id="config"
|
||||||
name="config"
|
name="config"
|
||||||
type="text"
|
type="text"
|
||||||
|
width="lg"
|
||||||
/>
|
/>
|
||||||
{!!errors.config && touched.config ? (
|
{!!errors.config && touched.config ? (
|
||||||
<FormErrorMessage>{errors.config}</FormErrorMessage>
|
<FormErrorMessage>{errors.config}</FormErrorMessage>
|
||||||
@ -206,15 +209,16 @@ export default function AddModel() {
|
|||||||
isInvalid={!!errors.weights && touched.weights}
|
isInvalid={!!errors.weights && touched.weights}
|
||||||
isRequired
|
isRequired
|
||||||
>
|
>
|
||||||
<FormLabel htmlFor="config">
|
<FormLabel htmlFor="config" fontSize="sm">
|
||||||
{t('modelmanager:modelLocation')}
|
{t('modelmanager:modelLocation')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<VStack alignItems={'start'}>
|
<VStack alignItems={'start'}>
|
||||||
<Field
|
<Field
|
||||||
as={Input}
|
as={IAIInput}
|
||||||
id="weights"
|
id="weights"
|
||||||
name="weights"
|
name="weights"
|
||||||
type="text"
|
type="text"
|
||||||
|
width="lg"
|
||||||
/>
|
/>
|
||||||
{!!errors.weights && touched.weights ? (
|
{!!errors.weights && touched.weights ? (
|
||||||
<FormErrorMessage>
|
<FormErrorMessage>
|
||||||
@ -230,11 +234,17 @@ export default function AddModel() {
|
|||||||
|
|
||||||
{/* VAE */}
|
{/* VAE */}
|
||||||
<FormControl isInvalid={!!errors.vae && touched.vae}>
|
<FormControl isInvalid={!!errors.vae && touched.vae}>
|
||||||
<FormLabel htmlFor="vae">
|
<FormLabel htmlFor="vae" fontSize="sm">
|
||||||
{t('modelmanager:vaeLocation')}
|
{t('modelmanager:vaeLocation')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<VStack alignItems={'start'}>
|
<VStack alignItems={'start'}>
|
||||||
<Field as={Input} id="vae" name="vae" type="text" />
|
<Field
|
||||||
|
as={IAIInput}
|
||||||
|
id="vae"
|
||||||
|
name="vae"
|
||||||
|
type="text"
|
||||||
|
width="lg"
|
||||||
|
/>
|
||||||
{!!errors.vae && touched.vae ? (
|
{!!errors.vae && touched.vae ? (
|
||||||
<FormErrorMessage>{errors.vae}</FormErrorMessage>
|
<FormErrorMessage>{errors.vae}</FormErrorMessage>
|
||||||
) : (
|
) : (
|
||||||
@ -250,7 +260,7 @@ export default function AddModel() {
|
|||||||
<FormControl
|
<FormControl
|
||||||
isInvalid={!!errors.width && touched.width}
|
isInvalid={!!errors.width && touched.width}
|
||||||
>
|
>
|
||||||
<FormLabel htmlFor="width">
|
<FormLabel htmlFor="width" fontSize="sm">
|
||||||
{t('modelmanager:width')}
|
{t('modelmanager:width')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<VStack alignItems={'start'}>
|
<VStack alignItems={'start'}>
|
||||||
@ -262,26 +272,20 @@ export default function AddModel() {
|
|||||||
field: FieldInputProps<number>;
|
field: FieldInputProps<number>;
|
||||||
form: FormikProps<InvokeModelConfigProps>;
|
form: FormikProps<InvokeModelConfigProps>;
|
||||||
}) => (
|
}) => (
|
||||||
<NumberInput
|
<IAINumberInput
|
||||||
{...field}
|
|
||||||
id="width"
|
id="width"
|
||||||
name="width"
|
name="width"
|
||||||
min={MIN_MODEL_SIZE}
|
min={MIN_MODEL_SIZE}
|
||||||
max={MAX_MODEL_SIZE}
|
max={MAX_MODEL_SIZE}
|
||||||
step={64}
|
step={64}
|
||||||
|
value={form.values.width}
|
||||||
onChange={(value) =>
|
onChange={(value) =>
|
||||||
form.setFieldValue(
|
form.setFieldValue(
|
||||||
field.name,
|
field.name,
|
||||||
Number(value)
|
Number(value)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
/>
|
||||||
<NumberInputField />
|
|
||||||
<NumberInputStepper>
|
|
||||||
<NumberIncrementStepper />
|
|
||||||
<NumberDecrementStepper />
|
|
||||||
</NumberInputStepper>
|
|
||||||
</NumberInput>
|
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
@ -301,7 +305,7 @@ export default function AddModel() {
|
|||||||
<FormControl
|
<FormControl
|
||||||
isInvalid={!!errors.height && touched.height}
|
isInvalid={!!errors.height && touched.height}
|
||||||
>
|
>
|
||||||
<FormLabel htmlFor="height">
|
<FormLabel htmlFor="height" fontSize="sm">
|
||||||
{t('modelmanager:height')}
|
{t('modelmanager:height')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<VStack alignItems={'start'}>
|
<VStack alignItems={'start'}>
|
||||||
@ -313,26 +317,20 @@ export default function AddModel() {
|
|||||||
field: FieldInputProps<number>;
|
field: FieldInputProps<number>;
|
||||||
form: FormikProps<InvokeModelConfigProps>;
|
form: FormikProps<InvokeModelConfigProps>;
|
||||||
}) => (
|
}) => (
|
||||||
<NumberInput
|
<IAINumberInput
|
||||||
{...field}
|
|
||||||
id="height"
|
id="height"
|
||||||
name="height"
|
name="height"
|
||||||
min={MIN_MODEL_SIZE}
|
min={MIN_MODEL_SIZE}
|
||||||
max={MAX_MODEL_SIZE}
|
max={MAX_MODEL_SIZE}
|
||||||
step={64}
|
step={64}
|
||||||
|
value={form.values.height}
|
||||||
onChange={(value) =>
|
onChange={(value) =>
|
||||||
form.setFieldValue(
|
form.setFieldValue(
|
||||||
field.name,
|
field.name,
|
||||||
Number(value)
|
Number(value)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
/>
|
||||||
<NumberInputField />
|
|
||||||
<NumberInputStepper>
|
|
||||||
<NumberIncrementStepper />
|
|
||||||
<NumberDecrementStepper />
|
|
||||||
</NumberInputStepper>
|
|
||||||
</NumberInput>
|
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
@ -349,13 +347,13 @@ export default function AddModel() {
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
||||||
<Button
|
<IAIButton
|
||||||
type="submit"
|
type="submit"
|
||||||
className="modal-close-btn"
|
className="modal-close-btn"
|
||||||
isLoading={isProcessing}
|
isLoading={isProcessing}
|
||||||
>
|
>
|
||||||
{t('modelmanager:addModel')}
|
{t('modelmanager:addModel')}
|
||||||
</Button>
|
</IAIButton>
|
||||||
</VStack>
|
</VStack>
|
||||||
</form>
|
</form>
|
||||||
)}
|
)}
|
||||||
|
@ -1,31 +1,34 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import type { RootState } from 'app/store';
|
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import IAIInput from 'common/components/IAIInput';
|
||||||
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
|
import IAIButton from 'common/components/IAIButton';
|
||||||
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import _ from 'lodash';
|
|
||||||
import type { InvokeModelConfigProps } from 'app/invokeai';
|
|
||||||
import {
|
import {
|
||||||
Button,
|
|
||||||
Flex,
|
Flex,
|
||||||
FormControl,
|
FormControl,
|
||||||
FormErrorMessage,
|
FormErrorMessage,
|
||||||
FormHelperText,
|
FormHelperText,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
Input,
|
HStack,
|
||||||
NumberDecrementStepper,
|
|
||||||
NumberIncrementStepper,
|
|
||||||
NumberInput,
|
|
||||||
NumberInputField,
|
|
||||||
NumberInputStepper,
|
|
||||||
Text,
|
Text,
|
||||||
VStack,
|
VStack,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
|
||||||
import { Field, Formik } from 'formik';
|
import { Field, Formik } from 'formik';
|
||||||
import type { FieldInputProps, FormikProps } from 'formik';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { addNewModel } from 'app/socketio/actions';
|
import { addNewModel } from 'app/socketio/actions';
|
||||||
|
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
import type { RootState } from 'app/store';
|
||||||
|
import type { FieldInputProps, FormikProps } from 'formik';
|
||||||
|
import type { InvokeModelConfigProps } from 'app/invokeai';
|
||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
[systemSelector],
|
[systemSelector],
|
||||||
(system) => {
|
(system) => {
|
||||||
@ -115,15 +118,16 @@ export default function ModelEdit() {
|
|||||||
isInvalid={!!errors.description && touched.description}
|
isInvalid={!!errors.description && touched.description}
|
||||||
isRequired
|
isRequired
|
||||||
>
|
>
|
||||||
<FormLabel htmlFor="description">
|
<FormLabel htmlFor="description" fontSize="sm">
|
||||||
{t('modelmanager:description')}
|
{t('modelmanager:description')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<VStack alignItems={'start'}>
|
<VStack alignItems={'start'}>
|
||||||
<Field
|
<Field
|
||||||
as={Input}
|
as={IAIInput}
|
||||||
id="description"
|
id="description"
|
||||||
name="description"
|
name="description"
|
||||||
type="text"
|
type="text"
|
||||||
|
width="lg"
|
||||||
/>
|
/>
|
||||||
{!!errors.description && touched.description ? (
|
{!!errors.description && touched.description ? (
|
||||||
<FormErrorMessage>{errors.description}</FormErrorMessage>
|
<FormErrorMessage>{errors.description}</FormErrorMessage>
|
||||||
@ -140,11 +144,17 @@ export default function ModelEdit() {
|
|||||||
isInvalid={!!errors.config && touched.config}
|
isInvalid={!!errors.config && touched.config}
|
||||||
isRequired
|
isRequired
|
||||||
>
|
>
|
||||||
<FormLabel htmlFor="config">
|
<FormLabel htmlFor="config" fontSize="sm">
|
||||||
{t('modelmanager:config')}
|
{t('modelmanager:config')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<VStack alignItems={'start'}>
|
<VStack alignItems={'start'}>
|
||||||
<Field as={Input} id="config" name="config" type="text" />
|
<Field
|
||||||
|
as={IAIInput}
|
||||||
|
id="config"
|
||||||
|
name="config"
|
||||||
|
type="text"
|
||||||
|
width="lg"
|
||||||
|
/>
|
||||||
{!!errors.config && touched.config ? (
|
{!!errors.config && touched.config ? (
|
||||||
<FormErrorMessage>{errors.config}</FormErrorMessage>
|
<FormErrorMessage>{errors.config}</FormErrorMessage>
|
||||||
) : (
|
) : (
|
||||||
@ -160,11 +170,17 @@ export default function ModelEdit() {
|
|||||||
isInvalid={!!errors.weights && touched.weights}
|
isInvalid={!!errors.weights && touched.weights}
|
||||||
isRequired
|
isRequired
|
||||||
>
|
>
|
||||||
<FormLabel htmlFor="config">
|
<FormLabel htmlFor="config" fontSize="sm">
|
||||||
{t('modelmanager:modelLocation')}
|
{t('modelmanager:modelLocation')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<VStack alignItems={'start'}>
|
<VStack alignItems={'start'}>
|
||||||
<Field as={Input} id="weights" name="weights" type="text" />
|
<Field
|
||||||
|
as={IAIInput}
|
||||||
|
id="weights"
|
||||||
|
name="weights"
|
||||||
|
type="text"
|
||||||
|
width="lg"
|
||||||
|
/>
|
||||||
{!!errors.weights && touched.weights ? (
|
{!!errors.weights && touched.weights ? (
|
||||||
<FormErrorMessage>{errors.weights}</FormErrorMessage>
|
<FormErrorMessage>{errors.weights}</FormErrorMessage>
|
||||||
) : (
|
) : (
|
||||||
@ -177,11 +193,17 @@ export default function ModelEdit() {
|
|||||||
|
|
||||||
{/* VAE */}
|
{/* VAE */}
|
||||||
<FormControl isInvalid={!!errors.vae && touched.vae}>
|
<FormControl isInvalid={!!errors.vae && touched.vae}>
|
||||||
<FormLabel htmlFor="vae">
|
<FormLabel htmlFor="vae" fontSize="sm">
|
||||||
{t('modelmanager:vaeLocation')}
|
{t('modelmanager:vaeLocation')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<VStack alignItems={'start'}>
|
<VStack alignItems={'start'}>
|
||||||
<Field as={Input} id="vae" name="vae" type="text" />
|
<Field
|
||||||
|
as={IAIInput}
|
||||||
|
id="vae"
|
||||||
|
name="vae"
|
||||||
|
type="text"
|
||||||
|
width="lg"
|
||||||
|
/>
|
||||||
{!!errors.vae && touched.vae ? (
|
{!!errors.vae && touched.vae ? (
|
||||||
<FormErrorMessage>{errors.vae}</FormErrorMessage>
|
<FormErrorMessage>{errors.vae}</FormErrorMessage>
|
||||||
) : (
|
) : (
|
||||||
@ -192,10 +214,10 @@ export default function ModelEdit() {
|
|||||||
</VStack>
|
</VStack>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
<VStack width={'100%'}>
|
<HStack width={'100%'}>
|
||||||
{/* Width */}
|
{/* Width */}
|
||||||
<FormControl isInvalid={!!errors.width && touched.width}>
|
<FormControl isInvalid={!!errors.width && touched.width}>
|
||||||
<FormLabel htmlFor="width">
|
<FormLabel htmlFor="width" fontSize="sm">
|
||||||
{t('modelmanager:width')}
|
{t('modelmanager:width')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<VStack alignItems={'start'}>
|
<VStack alignItems={'start'}>
|
||||||
@ -207,23 +229,17 @@ export default function ModelEdit() {
|
|||||||
field: FieldInputProps<number>;
|
field: FieldInputProps<number>;
|
||||||
form: FormikProps<InvokeModelConfigProps>;
|
form: FormikProps<InvokeModelConfigProps>;
|
||||||
}) => (
|
}) => (
|
||||||
<NumberInput
|
<IAINumberInput
|
||||||
{...field}
|
|
||||||
id="width"
|
id="width"
|
||||||
name="width"
|
name="width"
|
||||||
min={MIN_MODEL_SIZE}
|
min={MIN_MODEL_SIZE}
|
||||||
max={MAX_MODEL_SIZE}
|
max={MAX_MODEL_SIZE}
|
||||||
step={64}
|
step={64}
|
||||||
|
value={form.values.width}
|
||||||
onChange={(value) =>
|
onChange={(value) =>
|
||||||
form.setFieldValue(field.name, Number(value))
|
form.setFieldValue(field.name, Number(value))
|
||||||
}
|
}
|
||||||
>
|
/>
|
||||||
<NumberInputField />
|
|
||||||
<NumberInputStepper>
|
|
||||||
<NumberIncrementStepper />
|
|
||||||
<NumberDecrementStepper />
|
|
||||||
</NumberInputStepper>
|
|
||||||
</NumberInput>
|
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
@ -239,7 +255,7 @@ export default function ModelEdit() {
|
|||||||
|
|
||||||
{/* Height */}
|
{/* Height */}
|
||||||
<FormControl isInvalid={!!errors.height && touched.height}>
|
<FormControl isInvalid={!!errors.height && touched.height}>
|
||||||
<FormLabel htmlFor="height">
|
<FormLabel htmlFor="height" fontSize="sm">
|
||||||
{t('modelmanager:height')}
|
{t('modelmanager:height')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<VStack alignItems={'start'}>
|
<VStack alignItems={'start'}>
|
||||||
@ -251,23 +267,17 @@ export default function ModelEdit() {
|
|||||||
field: FieldInputProps<number>;
|
field: FieldInputProps<number>;
|
||||||
form: FormikProps<InvokeModelConfigProps>;
|
form: FormikProps<InvokeModelConfigProps>;
|
||||||
}) => (
|
}) => (
|
||||||
<NumberInput
|
<IAINumberInput
|
||||||
{...field}
|
|
||||||
id="height"
|
id="height"
|
||||||
name="height"
|
name="height"
|
||||||
min={MIN_MODEL_SIZE}
|
min={MIN_MODEL_SIZE}
|
||||||
max={MAX_MODEL_SIZE}
|
max={MAX_MODEL_SIZE}
|
||||||
step={64}
|
step={64}
|
||||||
|
value={form.values.height}
|
||||||
onChange={(value) =>
|
onChange={(value) =>
|
||||||
form.setFieldValue(field.name, Number(value))
|
form.setFieldValue(field.name, Number(value))
|
||||||
}
|
}
|
||||||
>
|
/>
|
||||||
<NumberInputField />
|
|
||||||
<NumberInputStepper>
|
|
||||||
<NumberIncrementStepper />
|
|
||||||
<NumberDecrementStepper />
|
|
||||||
</NumberInputStepper>
|
|
||||||
</NumberInput>
|
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
@ -280,15 +290,15 @@ export default function ModelEdit() {
|
|||||||
)}
|
)}
|
||||||
</VStack>
|
</VStack>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</VStack>
|
</HStack>
|
||||||
|
|
||||||
<Button
|
<IAIButton
|
||||||
type="submit"
|
type="submit"
|
||||||
className="modal-close-btn"
|
className="modal-close-btn"
|
||||||
isLoading={isProcessing}
|
isLoading={isProcessing}
|
||||||
>
|
>
|
||||||
{t('modelmanager:updateModel')}
|
{t('modelmanager:updateModel')}
|
||||||
</Button>
|
</IAIButton>
|
||||||
</VStack>
|
</VStack>
|
||||||
</form>
|
</form>
|
||||||
)}
|
)}
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
import { useState, ChangeEvent, ReactNode } from 'react';
|
import { useState } from 'react';
|
||||||
import { Flex, Text } from '@chakra-ui/react';
|
import { Flex, Text } from '@chakra-ui/react';
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { RootState } from 'app/store';
|
import IAIInput from 'common/components/IAIInput';
|
||||||
import { SystemState } from 'features/system/store/systemSlice';
|
|
||||||
import AddModel from './AddModel';
|
import AddModel from './AddModel';
|
||||||
import ModelListItem from './ModelListItem';
|
import ModelListItem from './ModelListItem';
|
||||||
import _ from 'lodash';
|
|
||||||
import IAIInput from 'common/components/IAIInput';
|
|
||||||
import { useAppSelector } from 'app/storeHooks';
|
import { useAppSelector } from 'app/storeHooks';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
import type { ChangeEvent, ReactNode } from 'react';
|
||||||
|
import type { RootState } from 'app/store';
|
||||||
|
import type { SystemState } from 'features/system/store/systemSlice';
|
||||||
|
|
||||||
const modelListSelector = createSelector(
|
const modelListSelector = createSelector(
|
||||||
(state: RootState) => state.system,
|
(state: RootState) => state.system,
|
||||||
(system: SystemState) => {
|
(system: SystemState) => {
|
||||||
|
@ -1,17 +1,11 @@
|
|||||||
import { EditIcon, DeleteIcon } from '@chakra-ui/icons';
|
import { EditIcon, DeleteIcon } from '@chakra-ui/icons';
|
||||||
import {
|
import { Button, Flex, Spacer, Text, Tooltip } from '@chakra-ui/react';
|
||||||
Button,
|
|
||||||
Flex,
|
|
||||||
IconButton,
|
|
||||||
Spacer,
|
|
||||||
Text,
|
|
||||||
Tooltip,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { ModelStatus } from 'app/invokeai';
|
import { ModelStatus } from 'app/invokeai';
|
||||||
import { deleteModel, requestModelChange } from 'app/socketio/actions';
|
import { deleteModel, requestModelChange } from 'app/socketio/actions';
|
||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAIAlertDialog from 'common/components/IAIAlertDialog';
|
import IAIAlertDialog from 'common/components/IAIAlertDialog';
|
||||||
|
import IAIIconButton from 'common/components/IAIIconButton';
|
||||||
import { setOpenModel } from 'features/system/store/systemSlice';
|
import { setOpenModel } from 'features/system/store/systemSlice';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -37,12 +31,13 @@ export default function ModelListItem(props: ModelListItemProps) {
|
|||||||
dispatch(requestModelChange(name));
|
dispatch(requestModelChange(name));
|
||||||
};
|
};
|
||||||
|
|
||||||
const openModel = () => {
|
const openModel = () => {
|
||||||
dispatch(setOpenModel(name));
|
dispatch(setOpenModel(name));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleModelDelete = () => {
|
const handleModelDelete = () => {
|
||||||
dispatch(deleteModel(name));
|
dispatch(deleteModel(name));
|
||||||
|
dispatch(setOpenModel(null));
|
||||||
};
|
};
|
||||||
|
|
||||||
const statusTextColor = () => {
|
const statusTextColor = () => {
|
||||||
@ -63,9 +58,8 @@ export default function ModelListItem(props: ModelListItemProps) {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
|
|
||||||
<Flex gap={4} alignItems="center">
|
<Flex gap={2} alignItems="center">
|
||||||
<Text color={statusTextColor()}>{status}</Text>
|
<Text color={statusTextColor()}>{status}</Text>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
onClick={handleChangeModel}
|
onClick={handleChangeModel}
|
||||||
@ -74,25 +68,26 @@ export default function ModelListItem(props: ModelListItemProps) {
|
|||||||
>
|
>
|
||||||
{t('modelmanager:load')}
|
{t('modelmanager:load')}
|
||||||
</Button>
|
</Button>
|
||||||
<IconButton
|
<IAIIconButton
|
||||||
icon={<EditIcon />}
|
icon={<EditIcon />}
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
onClick={openModel}
|
onClick={openModel}
|
||||||
aria-label="Modify Config"
|
aria-label="Modify Config"
|
||||||
isDisabled={status === 'active' || isProcessing || !isConnected}
|
isDisabled={status === 'active' || isProcessing || !isConnected}
|
||||||
className=" modal-close-btn"
|
className=" modal-close-btn"
|
||||||
/>
|
/>
|
||||||
<IAIAlertDialog
|
<IAIAlertDialog
|
||||||
title={t('modelmanager:deleteModel')}
|
title={t('modelmanager:deleteModel')}
|
||||||
acceptCallback={handleModelDelete}
|
acceptCallback={handleModelDelete}
|
||||||
acceptButtonText={t('modelmanager:delete')}
|
acceptButtonText={t('modelmanager:delete')}
|
||||||
triggerComponent={
|
triggerComponent={
|
||||||
<IconButton
|
<IAIIconButton
|
||||||
icon={<DeleteIcon />}
|
icon={<DeleteIcon />}
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
aria-label={t('modelmanager:deleteConfig')}
|
aria-label={t('modelmanager:deleteConfig')}
|
||||||
isDisabled={status === 'active' || isProcessing || !isConnected}
|
isDisabled={status === 'active' || isProcessing || !isConnected}
|
||||||
className=" modal-close-btn"
|
className=" modal-close-btn"
|
||||||
|
style={{ backgroundColor: 'var(--btn-delete-image)' }}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -7,11 +7,14 @@ import {
|
|||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import React, { cloneElement, ReactElement } from 'react';
|
import React, { cloneElement } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import ModelEdit from './ModelEdit';
|
import ModelEdit from './ModelEdit';
|
||||||
import ModelList from './ModelList';
|
import ModelList from './ModelList';
|
||||||
|
|
||||||
|
import type { ReactElement } from 'react';
|
||||||
|
|
||||||
type ModelManagerModalProps = {
|
type ModelManagerModalProps = {
|
||||||
children: ReactElement;
|
children: ReactElement;
|
||||||
};
|
};
|
||||||
|
@ -1,23 +1,29 @@
|
|||||||
import { Box, Flex, VStack } from '@chakra-ui/react';
|
import React from 'react';
|
||||||
import { addNewModel, searchForModels } from 'app/socketio/actions';
|
|
||||||
import { RootState } from 'app/store';
|
|
||||||
import IAICheckbox from 'common/components/IAICheckbox';
|
import IAICheckbox from 'common/components/IAICheckbox';
|
||||||
import React, { ReactNode, ChangeEvent } from 'react';
|
|
||||||
import { MdFindInPage } from 'react-icons/md';
|
|
||||||
import _ from 'lodash';
|
|
||||||
import IAIButton from 'common/components/IAIButton';
|
import IAIButton from 'common/components/IAIButton';
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
import IAIIconButton from 'common/components/IAIIconButton';
|
||||||
|
|
||||||
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
|
import { Box, Flex, VStack } from '@chakra-ui/react';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { FaPlus } from 'react-icons/fa';
|
import { FaPlus } from 'react-icons/fa';
|
||||||
|
import { MdFindInPage } from 'react-icons/md';
|
||||||
|
|
||||||
|
import { addNewModel, searchForModels } from 'app/socketio/actions';
|
||||||
import {
|
import {
|
||||||
setFoundModels,
|
setFoundModels,
|
||||||
setSearchFolder,
|
setSearchFolder,
|
||||||
} from 'features/system/store/systemSlice';
|
} from 'features/system/store/systemSlice';
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
|
||||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
|
||||||
import { setShouldShowExistingModelsInSearch } from 'features/options/store/optionsSlice';
|
import { setShouldShowExistingModelsInSearch } from 'features/options/store/optionsSlice';
|
||||||
import { FoundModel } from 'app/invokeai';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import _ from 'lodash';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
import type { RootState } from 'app/store';
|
||||||
|
import type { ReactNode, ChangeEvent } from 'react';
|
||||||
|
import type { FoundModel } from 'app/invokeai';
|
||||||
|
|
||||||
const existingModelsSelector = createSelector([systemSelector], (system) => {
|
const existingModelsSelector = createSelector([systemSelector], (system) => {
|
||||||
const { model_list } = system;
|
const { model_list } = system;
|
||||||
|
@ -23,6 +23,7 @@ import ModelManagerModal from './ModelManager/ModelManagerModal';
|
|||||||
import LanguagePicker from './LanguagePicker';
|
import LanguagePicker from './LanguagePicker';
|
||||||
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { MdSettings } from 'react-icons/md';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Header, includes color mode toggle, settings button, status message.
|
* Header, includes color mode toggle, settings button, status message.
|
||||||
@ -120,9 +121,9 @@ const SiteHeader = () => {
|
|||||||
tooltip={t('common:settingsLabel')}
|
tooltip={t('common:settingsLabel')}
|
||||||
variant="link"
|
variant="link"
|
||||||
data-variant="link"
|
data-variant="link"
|
||||||
fontSize={20}
|
fontSize={22}
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
icon={<FaWrench />}
|
icon={<MdSettings />}
|
||||||
/>
|
/>
|
||||||
</SettingsModal>
|
</SettingsModal>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user