diff --git a/src/features/forms/components/GenericField.vue b/src/features/forms/components/GenericField.vue index 11be3c3648ddafd183b58854342b8b8c3560d330..3b1fa7e2b8fd85ae66dd9f1f801c31af9354ef25 100644 --- a/src/features/forms/components/GenericField.vue +++ b/src/features/forms/components/GenericField.vue @@ -1,5 +1,5 @@ <script setup lang="ts"> -import { FormRepeatChangeAction, FormUpdatedAction, Input } from '@/src/shared/interfaces'; +import { FormRepeatChangeAction, FormRepeatMoveAction, FormUpdatedAction, Input } from '@/src/shared/interfaces'; import GenericInput from './inputs/GenericInput.vue'; import { useEditorStore, useUndoRedoStore } from '@/src/shared/stores'; import { graphService } from '@/src/shared/services'; @@ -93,6 +93,9 @@ function handleRemoveRepeatInput(element, value, id: string): void { } function handleMoveRepeatInput(element, value, id: string): void { + + onAddMoveUndoAction(id, value.oldIndex, value.newIndex); + if(currentNode.data.elements && !editorStore.openedNodeId) { changeContentOrder(value.oldIndex, value.newIndex, currentNode.id); } else { @@ -115,7 +118,7 @@ function handleChangeRepeatInput(element, value, id: string): void { } } -function onAddRepeatUndoAction(repeatEvent, formValueId: string): void { +function onAddChangeUndoAction(repeatEvent, formValueId: string): void { const { type, value, index, id } = repeatEvent; const action: FormRepeatChangeAction = { @@ -132,6 +135,21 @@ function onAddRepeatUndoAction(repeatEvent, formValueId: string): void { undoRedoStore.addAction(action); } + +function onAddMoveUndoAction(formValueId: string, oldIndex: number, newIndex: number): void { + + const action: FormRepeatMoveAction = { + type: 'formRepeatUpdated', + nodeId: currentNode.id, + elementId: editorStore.openedElementId, + formValueId, + updateType: 'move', + oldIndex, + newIndex + }; + + undoRedoStore.addAction(action); +} // Repeat Input end function onCheck(value: boolean, id:string) { @@ -172,7 +190,7 @@ function onAddUndoAction(value: { oldValue: string, newValue: string }, id: stri @check="onCheck($event, input.id)" @repeat-input="onRepeatInput($event, input.id)" @add-undo-action="onAddUndoAction($event, input.id)" - @add-repeat-undo-action="onAddRepeatUndoAction($event, input.id)" + @add-repeat-undo-action="onAddChangeUndoAction($event, input.id)" /> </template> diff --git a/src/shared/interfaces/undoRedo.interface.ts b/src/shared/interfaces/undoRedo.interface.ts index 54b8cb0cdcae8c6d59bf8fc5d835e3db9e04621c..59c7cf7b1f18aa7d923d154efdce703a7ec675e7 100644 --- a/src/shared/interfaces/undoRedo.interface.ts +++ b/src/shared/interfaces/undoRedo.interface.ts @@ -49,7 +49,6 @@ export interface FormRepeatUpdatedAction extends UndoRedoAction { nodeId: string; elementId: string; formValueId: string; - repeatId: string; updateType: 'change' | 'add' | 'remove' | 'move'; } @@ -58,11 +57,12 @@ export interface FormRepeatChangeAction extends FormRepeatUpdatedAction { oldValue: string; newValue: string; index: number; + repeatId: string; } export interface FormRepeatMutateAction extends FormRepeatUpdatedAction { updateType: 'add' | 'remove'; - value: string; + value: any; index: number; } diff --git a/src/shared/services/graph/content.service.ts b/src/shared/services/graph/content.service.ts index 1cf797dc24d9f35cc1fb27e0b7e050b3f6faac90..80b9eb7423b852569367b5bb053e36091d4f1964 100644 --- a/src/shared/services/graph/content.service.ts +++ b/src/shared/services/graph/content.service.ts @@ -94,41 +94,3 @@ export function getContentDefaultValues(type) { return {...acc, ...keyValues}; }, {}); } - -export function updateElementValue(elementId: string, nodeId: string, valueId: string, value: string): void { - const { id, formType, formValues } = getElementInfo(elementId, nodeId); - - if(editorStore.openedElementId !== id) { - const parentId = nodeId !== elementId ? nodeId : null; - editorStore.openFormPanel(id, formType, formValues, parentId); - } - - formValues[valueId] = value; -} - -export function updateRepeatElementValue(elementId: string, nodeId: string, valueId: string, value: string, repeatIndex: number, repeatId: string): void { - const { id, formType, formValues } = getElementInfo(elementId, nodeId); - - if(editorStore.openedElementId !== id) { - const parentId = nodeId !== elementId ? nodeId : null; - editorStore.openFormPanel(id, formType, formValues, parentId); - } - - const repeatInput = formValues[valueId][repeatIndex]; - repeatInput[repeatId] = value; -} - -function getElementInfo(elementId: string, nodeId: string): {id: string, formType: string, formValues: any} { - const node = findNode(nodeId); - - let id, formType, formValues; - if(nodeId === elementId) { - id = node.id; - ({ formType, formValues } = node.data); - } else { - const element = node.data.elements.find(e => e.id === elementId); - ({ id, formType, formValues } = element); - } - - return { id, formType, formValues }; -} \ No newline at end of file diff --git a/src/shared/services/graph/form.service.ts b/src/shared/services/graph/form.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..a5922addbfdf4e6f11c68130600182fb7baa29a3 --- /dev/null +++ b/src/shared/services/graph/form.service.ts @@ -0,0 +1,68 @@ +import { useEditorStore} from '../../stores'; +import { useVueFlow } from '@vue-flow/core'; + +const editorStore = useEditorStore(); +const { findNode } = useVueFlow({ id: 'main' }); + +export function updateElementValue(elementId: string, nodeId: string, valueId: string, value: string): void { + const { id, formType, formValues } = getElementInfo(elementId, nodeId); + + verifyAndOpenFormPanel(id, formType, formValues, nodeId); + + formValues[valueId] = value; +} + +export function updateRepeatElementValue(elementId: string, nodeId: string, valueId: string, value: string, repeatIndex: number, repeatId: string): void { + const { id, formType, formValues } = getElementInfo(elementId, nodeId); + + verifyAndOpenFormPanel(id, formType, formValues, nodeId); + + const repeatInput = formValues[valueId][repeatIndex]; + repeatInput[repeatId] = value; +} + +export function removeRepeatElement(elementId: string, nodeId: string, formValueId: string, index: number): void { + const { id, formType, formValues } = getElementInfo(elementId, nodeId); + + verifyAndOpenFormPanel(id, formType, formValues, nodeId); + + formValues[formValueId].splice(index, 1); +} + +export function addRepeatElement(elementId: string, nodeId: string, formValueId: string, repeatElement, index: number): void { + const { id, formType, formValues } = getElementInfo(elementId, nodeId); + + verifyAndOpenFormPanel(id, formType, formValues, nodeId); + + formValues[formValueId].splice(index, 0, repeatElement); +} + +export function moveRepeatElement(elementId: string, nodeId: string, formValueId: string, oldIndex: number, newIndex: number): void { + const { id, formType, formValues } = getElementInfo(elementId, nodeId); + + verifyAndOpenFormPanel(id, formType, formValues, nodeId); + + const [repeatElement] = formValues[formValueId].splice(oldIndex, 1); + formValues[formValueId].splice(newIndex, 0, repeatElement); +} + +function getElementInfo(elementId: string, nodeId: string): {id: string, formType: string, formValues: any} { + const node = findNode(nodeId); + + let id, formType, formValues; + if(nodeId === elementId) { + id = node.id; + ({ formType, formValues } = node.data); + } else { + const element = node.data.elements.find(e => e.id === elementId); + ({ id, formType, formValues } = element); + } + + return { id, formType, formValues }; +} + +function verifyAndOpenFormPanel(id: string, formType: string, formValues, parentId: string): void { + if(editorStore.openedElementId !== id) { + editorStore.openFormPanel(id, formType, formValues, parentId); + } +} \ No newline at end of file diff --git a/src/shared/services/graph/index.ts b/src/shared/services/graph/index.ts index e77bda7ef2971072d2499ae2a5794485fc14699b..4ca074ea8b2b672e670e2cf489042b9fdc45c0c3 100644 --- a/src/shared/services/graph/index.ts +++ b/src/shared/services/graph/index.ts @@ -1,2 +1,3 @@ export * from './content.service'; -export * from './node.service'; \ No newline at end of file +export * from './node.service'; +export * from './form.service'; \ No newline at end of file diff --git a/src/shared/stores/undoRedo/functions/form.ts b/src/shared/stores/undoRedo/functions/form.ts index 4d78d1c2dfff9dc13e9425f5a02a65360ff595fe..77839184b3500a1819de3e8eab34d3919e3b8b51 100644 --- a/src/shared/stores/undoRedo/functions/form.ts +++ b/src/shared/stores/undoRedo/functions/form.ts @@ -1,5 +1,5 @@ -import { FormRepeatChangeAction, FormUpdatedAction, UndoRedoAction } from '@/src/shared/interfaces'; -import { updateElementValue, updateRepeatElementValue } from '@/src/shared/services/graph'; +import { FormRepeatChangeAction, FormRepeatMoveAction, FormRepeatMutateAction, FormRepeatUpdatedAction, FormUpdatedAction, UndoRedoAction } from '@/src/shared/interfaces'; +import { addRepeatElement, moveRepeatElement, removeRepeatElement, updateElementValue, updateRepeatElementValue } from '@/src/shared/services/graph'; export function updateFormAction(action: FormUpdatedAction, reverseStack: UndoRedoAction[]): void { const { elementId, nodeId, formValueId, oldValue, newValue } = action; @@ -15,7 +15,29 @@ export function updateFormAction(action: FormUpdatedAction, reverseStack: UndoRe reverseStack.push(reverseAction); } -export function updateRepeatFormAction(action: FormRepeatChangeAction, reverseStack: UndoRedoAction[]): void { +export function updateRepeatFormAction(action: FormRepeatUpdatedAction, reverseStack: UndoRedoAction[]): void { + const { updateType } = action; + + switch(updateType) { + case 'change': + handleRepeatChangeAction(action as FormRepeatChangeAction, reverseStack); + break; + + case 'add': + handleRepeatAddAction(action as FormRepeatMutateAction, reverseStack); + break; + + case 'remove': + handleRepeatRemoveAction(action as FormRepeatMutateAction, reverseStack); + break; + + case 'move': + handleRepeatMoveAction(action as FormRepeatMoveAction, reverseStack); + break; + } +} + +function handleRepeatChangeAction(action: FormRepeatChangeAction, reverseStack: UndoRedoAction[]): void { const { elementId, nodeId, formValueId, oldValue, newValue, index, repeatId } = action; updateRepeatElementValue(elementId, nodeId, formValueId, oldValue, index, repeatId); @@ -29,6 +51,48 @@ export function updateRepeatFormAction(action: FormRepeatChangeAction, reverseSt reverseStack.push(reverseAction); } +function handleRepeatAddAction(action: FormRepeatMutateAction, reverseStack: UndoRedoAction[]): void { + const { elementId, nodeId, formValueId, index } = action; + + removeRepeatElement(elementId, nodeId, formValueId, index); + + const reverseAction: FormRepeatMutateAction = { + ...action, + updateType: 'remove', + }; + + reverseStack.push(reverseAction); +} + +function handleRepeatRemoveAction(action: FormRepeatMutateAction, reverseStack: UndoRedoAction[]): void { + const { elementId, nodeId, formValueId, value, index} = action; + + addRepeatElement(elementId, nodeId, formValueId, value, index); + + const reverseAction: FormRepeatMutateAction = { + ...action, + updateType: 'add', + }; + reverseStack.push(reverseAction); +} + +function handleRepeatMoveAction(action: FormRepeatMoveAction, reverseStack: UndoRedoAction[]): void { + const { elementId, nodeId, formValueId, oldIndex, newIndex } = action; + + console.log('handling repeat move action'); + + moveRepeatElement(elementId, nodeId, formValueId, oldIndex, newIndex); + + const reverseAction: FormRepeatMoveAction = { + ...action, + oldIndex: newIndex, + newIndex: oldIndex, + }; + + reverseStack.push(reverseAction); +} + + export function ignoreUndoRedoOnFocus(event: KeyboardEvent): void { const { key, ctrlKey, metaKey } = event; if(ctrlKey || metaKey) {