mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
remove input field from form
This commit is contained in:
committed by
psychedelicious
parent
e34ed199c9
commit
2496ac19c4
@@ -1950,6 +1950,7 @@
|
||||
"zoomToNode": "Zoom to Node",
|
||||
"nodeFieldTooltip": "To add a node field, click the small plus sign button on the field in the Workflow Editor, or drag the field by its name into the form.",
|
||||
"addToForm": "Add to Form",
|
||||
"removeFromForm": "Remove from Form",
|
||||
"label": "Label",
|
||||
"showDescription": "Show Description",
|
||||
"showShuffle": "Show Shuffle",
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { IconButton } from '@invoke-ai/ui-library';
|
||||
import { useAddRemoveFormElement } from 'features/nodes/components/sidePanel/builder/use-add-remove-form-element';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiMinusBold, PiPlusBold } from 'react-icons/pi';
|
||||
|
||||
type Props = {
|
||||
nodeId: string;
|
||||
fieldName: string;
|
||||
};
|
||||
|
||||
export const InputFieldAddRemoveFormRoot = memo(({ nodeId, fieldName }: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const { isAddedToRoot, addNodeFieldToRoot, removeNodeFieldFromRoot } = useAddRemoveFormElement(nodeId, fieldName);
|
||||
|
||||
const description = useMemo(() => {
|
||||
return isAddedToRoot ? t('workflows.builder.removeFromForm') : t('workflows.builder.addToForm');
|
||||
}, [isAddedToRoot, t]);
|
||||
|
||||
const icon = useMemo(() => {
|
||||
return isAddedToRoot ? <PiMinusBold /> : <PiPlusBold />;
|
||||
}, [isAddedToRoot]);
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
return isAddedToRoot ? removeNodeFieldFromRoot() : addNodeFieldToRoot();
|
||||
}, [isAddedToRoot, addNodeFieldToRoot, removeNodeFieldFromRoot]);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
tooltip={description}
|
||||
aria-label={description}
|
||||
icon={icon}
|
||||
pointerEvents="auto"
|
||||
size="xs"
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
InputFieldAddRemoveFormRoot.displayName = 'InputFieldAddRemoveFormRoot';
|
||||
@@ -1,30 +0,0 @@
|
||||
import { IconButton } from '@invoke-ai/ui-library';
|
||||
import { useAddNodeFieldToRoot } from 'features/nodes/components/sidePanel/builder/use-add-node-field-to-root';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiPlusBold } from 'react-icons/pi';
|
||||
|
||||
type Props = {
|
||||
nodeId: string;
|
||||
fieldName: string;
|
||||
};
|
||||
|
||||
export const InputFieldAddToFormRoot = memo(({ nodeId, fieldName }: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const { isAddedToRoot, addNodeFieldToRoot } = useAddNodeFieldToRoot(nodeId, fieldName);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
tooltip={t('workflows.builder.addToForm')}
|
||||
aria-label={t('workflows.builder.addToForm')}
|
||||
icon={<PiPlusBold />}
|
||||
pointerEvents="auto"
|
||||
size="xs"
|
||||
onClick={addNodeFieldToRoot}
|
||||
isDisabled={isAddedToRoot}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
InputFieldAddToFormRoot.displayName = 'InputFieldAddToFormRoot';
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { SystemStyleObject } from '@invoke-ai/ui-library';
|
||||
import { Flex, Spacer } from '@invoke-ai/ui-library';
|
||||
import { InputFieldAddToFormRoot } from 'features/nodes/components/flow/nodes/Invocation/fields/InputFieldAddToFormRoot';
|
||||
import { InputFieldDescriptionPopover } from 'features/nodes/components/flow/nodes/Invocation/fields/InputFieldDescriptionPopover';
|
||||
import { InputFieldHandle } from 'features/nodes/components/flow/nodes/Invocation/fields/InputFieldHandle';
|
||||
import { InputFieldResetToDefaultValueIconButton } from 'features/nodes/components/flow/nodes/Invocation/fields/InputFieldResetToDefaultValueIconButton';
|
||||
@@ -12,6 +11,7 @@ import { NO_DRAG_CLASS } from 'features/nodes/types/constants';
|
||||
import type { FieldInputTemplate } from 'features/nodes/types/field';
|
||||
import { memo, useRef } from 'react';
|
||||
|
||||
import { InputFieldAddRemoveFormRoot } from './InputFieldAddRemoveFormRoot';
|
||||
import { InputFieldRenderer } from './InputFieldRenderer';
|
||||
import { InputFieldTitle } from './InputFieldTitle';
|
||||
import { InputFieldWrapper } from './InputFieldWrapper';
|
||||
@@ -113,7 +113,7 @@ const DirectField = memo(({ nodeId, fieldName, isInvalid, isConnected, fieldTemp
|
||||
<Flex className="direct-field-action-buttons">
|
||||
<InputFieldDescriptionPopover nodeId={nodeId} fieldName={fieldName} />
|
||||
<InputFieldResetToDefaultValueIconButton nodeId={nodeId} fieldName={fieldName} />
|
||||
<InputFieldAddToFormRoot nodeId={nodeId} fieldName={fieldName} />
|
||||
<InputFieldAddRemoveFormRoot nodeId={nodeId} fieldName={fieldName} />
|
||||
</Flex>
|
||||
</Flex>
|
||||
<InputFieldRenderer nodeId={nodeId} fieldName={fieldName} />
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { useInputFieldInstance } from 'features/nodes/hooks/useInputFieldInstance';
|
||||
import { useInputFieldTemplateOrThrow } from 'features/nodes/hooks/useInputFieldTemplateOrThrow';
|
||||
import { formElementAdded } from 'features/nodes/store/nodesSlice';
|
||||
import { buildSelectWorkflowFormNodeExists, selectFormRootElementId } from 'features/nodes/store/selectors';
|
||||
import { formElementAdded, formElementRemoved } from 'features/nodes/store/nodesSlice';
|
||||
import { buildSelectWorkflowFormNodeElement, selectFormRootElementId } from 'features/nodes/store/selectors';
|
||||
import { buildNodeFieldElement } from 'features/nodes/types/workflow';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
export const useAddNodeFieldToRoot = (nodeId: string, fieldName: string) => {
|
||||
export const useAddRemoveFormElement = (nodeId: string, fieldName: string) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const rootElementId = useAppSelector(selectFormRootElementId);
|
||||
const fieldTemplate = useInputFieldTemplateOrThrow(fieldName);
|
||||
const field = useInputFieldInstance(fieldName);
|
||||
const selectWorkflowFormNodeExists = useMemo(
|
||||
() => buildSelectWorkflowFormNodeExists(nodeId, fieldName),
|
||||
const selectWorkflowFormNodeElement = useMemo(
|
||||
() => buildSelectWorkflowFormNodeElement(nodeId, fieldName),
|
||||
[nodeId, fieldName]
|
||||
);
|
||||
const isAddedToRoot = useAppSelector(selectWorkflowFormNodeExists);
|
||||
const workflowFormNodeElement = useAppSelector(selectWorkflowFormNodeElement);
|
||||
const isAddedToRoot = useMemo(() => {
|
||||
return !!workflowFormNodeElement;
|
||||
}, [workflowFormNodeElement]);
|
||||
|
||||
const addNodeFieldToRoot = useCallback(() => {
|
||||
const element = buildNodeFieldElement(nodeId, fieldName, fieldTemplate.type);
|
||||
@@ -28,5 +31,16 @@ export const useAddNodeFieldToRoot = (nodeId: string, fieldName: string) => {
|
||||
);
|
||||
}, [nodeId, fieldName, fieldTemplate.type, dispatch, rootElementId, field.value]);
|
||||
|
||||
return { isAddedToRoot, addNodeFieldToRoot };
|
||||
const removeNodeFieldFromRoot = useCallback(() => {
|
||||
if (!workflowFormNodeElement) {
|
||||
return;
|
||||
}
|
||||
dispatch(
|
||||
formElementRemoved({
|
||||
id: workflowFormNodeElement.id,
|
||||
})
|
||||
);
|
||||
}, [workflowFormNodeElement, dispatch]);
|
||||
|
||||
return { isAddedToRoot, addNodeFieldToRoot, removeNodeFieldFromRoot };
|
||||
};
|
||||
@@ -103,7 +103,10 @@ export const selectWorkflowFormNodeFieldFieldIdentifiersDeduped = createSelector
|
||||
);
|
||||
|
||||
export const buildSelectElement = (id: string) => createNodesSelector((workflow) => workflow.form?.elements[id]);
|
||||
export const buildSelectWorkflowFormNodeExists = (nodeId: string, fieldName: string) =>
|
||||
createSelector(selectWorkflowFormNodeFieldFieldIdentifiersDeduped, (identifiers) =>
|
||||
identifiers.some((identifier) => identifier.nodeId === nodeId && identifier.fieldName === fieldName)
|
||||
export const buildSelectWorkflowFormNodeElement = (nodeId: string, fieldName: string) =>
|
||||
createSelector(selectNodeFieldElements, (elements) =>
|
||||
elements.find(
|
||||
(element) =>
|
||||
element.data.fieldIdentifier.nodeId === nodeId && element.data.fieldIdentifier.fieldName === fieldName
|
||||
)
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user