From ff60879e77bc1c3c698ebf77c3ab8942fa32bc54 Mon Sep 17 00:00:00 2001 From: NathanViaud <nathan.viaud@inria.fr> Date: Wed, 7 Jun 2023 16:22:31 +0200 Subject: [PATCH] Adding RepeatFormAction cases & functionnal move case --- .../forms/components/GenericField.vue | 24 ++++++- src/shared/interfaces/undoRedo.interface.ts | 4 +- src/shared/services/graph/content.service.ts | 38 ---------- src/shared/services/graph/form.service.ts | 68 ++++++++++++++++++ src/shared/services/graph/index.ts | 3 +- src/shared/stores/undoRedo/functions/form.ts | 70 ++++++++++++++++++- 6 files changed, 160 insertions(+), 47 deletions(-) create mode 100644 src/shared/services/graph/form.service.ts diff --git a/src/features/forms/components/GenericField.vue b/src/features/forms/components/GenericField.vue index 11be3c36..3b1fa7e2 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 54b8cb0c..59c7cf7b 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 1cf797dc..80b9eb74 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 00000000..a5922add --- /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 e77bda7e..4ca074ea 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 4d78d1c2..77839184 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) { -- GitLab