mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
feat(ui): builder edit/view buttons
This commit is contained in:
@@ -12,7 +12,7 @@ import {
|
||||
useRootContainerDropTarget,
|
||||
} from 'features/nodes/components/sidePanel/builder/use-builder-dnd';
|
||||
import {
|
||||
formModeToggled,
|
||||
formModeChanged,
|
||||
formReset,
|
||||
selectFormIsEmpty,
|
||||
selectFormLayout,
|
||||
@@ -37,19 +37,30 @@ export const WorkflowBuilder = memo(() => {
|
||||
dispatch(formReset());
|
||||
}, [dispatch]);
|
||||
|
||||
const setToViewMode = useCallback(() => {
|
||||
dispatch(formModeChanged({ mode: 'view' }));
|
||||
}, [dispatch]);
|
||||
|
||||
const setToEditMode = useCallback(() => {
|
||||
dispatch(formModeChanged({ mode: 'edit' }));
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<ScrollableContent>
|
||||
<Flex justifyContent="center" w="full" h="full" p={4}>
|
||||
<Flex flexDir="column" w={mode === 'view' ? '512px' : 'min-content'} h="full" minW="512px" gap={4}>
|
||||
<ButtonGroup isAttached={false} justifyContent="center">
|
||||
<ToggleModeButton />
|
||||
<AddFormElementDndButton type="row" />
|
||||
<AddFormElementDndButton type="column" />
|
||||
<AddFormElementDndButton type="divider" />
|
||||
<AddFormElementDndButton type="heading" />
|
||||
<AddFormElementDndButton type="text" />
|
||||
<Button onClick={resetForm}>{t('common.reset')}</Button>
|
||||
</ButtonGroup>
|
||||
{mode === 'edit' && (
|
||||
<ButtonGroup isAttached={false} justifyContent="center">
|
||||
<AddFormElementDndButton type="row" />
|
||||
<AddFormElementDndButton type="column" />
|
||||
<AddFormElementDndButton type="divider" />
|
||||
<AddFormElementDndButton type="heading" />
|
||||
<AddFormElementDndButton type="text" />
|
||||
<Button onClick={setToViewMode}>{t('common.view')}</Button>
|
||||
<Button onClick={resetForm}>{t('common.reset')}</Button>
|
||||
</ButtonGroup>
|
||||
)}
|
||||
{mode === 'view' && !isEmpty && <Button onClick={setToEditMode}>{t('common.edit')}</Button>}
|
||||
{!isEmpty && <FormLayout />}
|
||||
{mode === 'view' && isEmpty && <EmptyStateViewMode />}
|
||||
{mode === 'edit' && isEmpty && <EmptyStateEditMode />}
|
||||
@@ -76,8 +87,8 @@ FormLayout.displayName = 'FormLayout';
|
||||
const EmptyStateViewMode = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const toggleMode = useCallback(() => {
|
||||
dispatch(formModeToggled());
|
||||
const setToEditMode = useCallback(() => {
|
||||
dispatch(formModeChanged({ mode: 'edit' }));
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
@@ -85,7 +96,7 @@ const EmptyStateViewMode = memo(() => {
|
||||
<Text variant="subtext" fontSize="md">
|
||||
{t('workflows.builder.emptyRootPlaceholderViewMode')}
|
||||
</Text>
|
||||
<Button onClick={toggleMode}>{t('common.edit')}</Button>
|
||||
<Button onClick={setToEditMode}>{t('common.edit')}</Button>
|
||||
</Flex>
|
||||
);
|
||||
});
|
||||
@@ -116,18 +127,6 @@ const EmptyStateEditMode = memo(() => {
|
||||
});
|
||||
EmptyStateEditMode.displayName = 'EmptyStateEditMode';
|
||||
|
||||
const ToggleModeButton = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const mode = useAppSelector(selectWorkflowFormMode);
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
dispatch(formModeToggled());
|
||||
}, [dispatch]);
|
||||
|
||||
return <Button onClick={onClick}>{mode === 'view' ? 'Edit' : 'View'}</Button>;
|
||||
});
|
||||
ToggleModeButton.displayName = 'ToggleModeButton';
|
||||
|
||||
const useAddFormElementDnd = (
|
||||
type: Exclude<FormElement['type'], 'node-field' | 'container'> | 'row' | 'column',
|
||||
draggableRef: RefObject<HTMLElement>,
|
||||
|
||||
@@ -227,8 +227,9 @@ export const workflowSlice = createSlice({
|
||||
formElementContainerDataChanged: (state, action: FormElementDataChangedAction<ContainerElement>) => {
|
||||
formElementDataChangedReducer(state, action, isContainerElement);
|
||||
},
|
||||
formModeToggled: (state) => {
|
||||
state.formMode = state.formMode === 'edit' ? 'view' : 'edit';
|
||||
formModeChanged: (state, action: PayloadAction<{ mode: 'view' | 'edit' }>) => {
|
||||
const { mode } = action.payload;
|
||||
state.formMode = mode;
|
||||
},
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
@@ -364,7 +365,7 @@ export const {
|
||||
formElementTextDataChanged,
|
||||
formElementNodeFieldDataChanged,
|
||||
formElementContainerDataChanged,
|
||||
formModeToggled,
|
||||
formModeChanged,
|
||||
} = workflowSlice.actions;
|
||||
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
@@ -499,81 +500,6 @@ const reparentElement = (args: {
|
||||
// We should never get here!
|
||||
};
|
||||
|
||||
// const moveElement = (args: {
|
||||
// formState: NonNullable<WorkflowV3['form']>;
|
||||
// id: string;
|
||||
// containerId?: string;
|
||||
// index?: number;
|
||||
// }) => {
|
||||
// const { formState, id, containerId, index } = args;
|
||||
// const { elements } = formState;
|
||||
|
||||
// const element = elements[id];
|
||||
|
||||
// // Bail if the element doesn't exist
|
||||
// if (!element) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // The element is being moved within the root
|
||||
// if (containerId === undefined && element.parentId === undefined) {
|
||||
// formState.layout.splice(index ?? formState.layout.length, 0, id);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // The element is being moved within its current container
|
||||
// if (containerId !== undefined && element.parentId !== undefined && containerId === element.parentId) {
|
||||
// const parent = formState.elements[element.parentId];
|
||||
// if (!parent || !isContainerElement(parent)) {
|
||||
// return;
|
||||
// }
|
||||
// parent.data.children.splice(index ?? parent.data.children.length, 0, id);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // Element is being moved from a container to the root
|
||||
// if (!containerId && element.parentId !== undefined) {
|
||||
// const oldParent = formState.elements[element.parentId];
|
||||
// if (!oldParent || !isContainerElement(oldParent)) {
|
||||
// return;
|
||||
// }
|
||||
// oldParent.data.children = oldParent.data.children.filter((childId) => childId !== id);
|
||||
// formState.layout.splice(index || formState.layout.length, 0, id);
|
||||
// element.parentId = undefined;
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // Element is being moved from the root to a container
|
||||
// if (containerId && element.parentId === undefined) {
|
||||
// const newParent = formState.elements[containerId];
|
||||
// if (!newParent || !isContainerElement(newParent)) {
|
||||
// return;
|
||||
// }
|
||||
// newParent.data.children.splice(index ?? newParent.data.children.length, 0, id);
|
||||
// formState.layout = formState.layout.filter((elId) => elId !== id);
|
||||
// element.parentId = containerId;
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // Element is being moved from one container to another
|
||||
// if (containerId !== undefined && element.parentId !== undefined && containerId !== element.parentId) {
|
||||
// const oldParent = formState.elements[element.parentId];
|
||||
// if (!oldParent || !isContainerElement(oldParent)) {
|
||||
// return;
|
||||
// }
|
||||
// const newParent = formState.elements[containerId];
|
||||
// if (!newParent || !isContainerElement(newParent)) {
|
||||
// return;
|
||||
// }
|
||||
// oldParent.data.children = oldParent.data.children.filter((childId) => childId !== id);
|
||||
// newParent.data.children.splice(index ?? newParent.data.children.length, 0, id);
|
||||
// element.parentId = containerId;
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // Should never get here - we've covered all cases
|
||||
// };
|
||||
|
||||
const addElement = (args: {
|
||||
formState: NonNullable<WorkflowV3['form']>;
|
||||
element: FormElement;
|
||||
|
||||
Reference in New Issue
Block a user