From f36833183d71bd9edcf2dc08607c30444bbe7a82 Mon Sep 17 00:00:00 2001 From: VIAUD Nathan <nathan.viaud@inria.fr> Date: Mon, 13 Nov 2023 11:10:01 +0100 Subject: [PATCH 1/2] delete empty badges --- src/features/ePocFlow/ePocFlow.vue | 8 ++++---- src/features/ePocFlow/nodes/ActivityNode.vue | 6 +----- src/features/ePocFlow/nodes/ChapterNode.vue | 4 ++-- src/features/ePocFlow/nodes/PageNode.vue | 6 +----- .../ePocFlow/nodes/content/DraggableNode.vue | 6 +----- src/features/ePocFlow/nodes/ePocNode.vue | 4 ++-- src/features/forms/FormPanel.vue | 4 ++-- src/shared/services/editor.service.ts | 5 +++-- src/shared/services/graph.service.ts | 17 ++++++++++++++++- .../services/{ => graph}/badge.service.ts | 16 ++++++++++++++++ src/shared/services/graph/content.service.ts | 4 ++-- src/shared/services/graph/element.service.ts | 4 ++-- src/shared/services/graph/index.ts | 3 ++- src/shared/services/graph/node.service.ts | 6 +++--- src/shared/services/import.service.ts | 2 +- src/shared/services/index.ts | 2 +- src/shared/services/undoRedo.service.ts | 3 ++- src/shared/stores/editorStore.ts | 9 --------- 18 files changed, 61 insertions(+), 48 deletions(-) rename src/shared/services/{ => graph}/badge.service.ts (93%) diff --git a/src/features/ePocFlow/ePocFlow.vue b/src/features/ePocFlow/ePocFlow.vue index 5da1895d..aaca2124 100644 --- a/src/features/ePocFlow/ePocFlow.vue +++ b/src/features/ePocFlow/ePocFlow.vue @@ -24,7 +24,7 @@ import AddChapterNode from './nodes/AddChapterNode.vue'; import { NodeElement, SideAction } from '@/src/shared/interfaces'; import { addPage, createPageFromContent, removeContentFromPage, graphCopy, getSelectedNodes } from '@/src/shared/services/graph'; import { saveState, saveGivenState, getCurrentState } from '@/src/shared/services/undoRedo.service'; -import { graphService } from '@/src/shared/services'; +import { closeFormPanel, graphService } from '@/src/shared/services'; const { vueFlowRef, project, updateEdge, edges, nodes, findNode, setTransform } = useVueFlow({ id: 'main' }); @@ -84,7 +84,7 @@ function onEdgeClick (event: EdgeMouseEvent) { } function selectionStart() { - editorStore.closeFormPanel(); + closeFormPanel(); } function update(event: EdgeUpdateEvent) { @@ -99,7 +99,7 @@ function update(event: EdgeUpdateEvent) { function nodeChange(event: NodeChange[]) { const { type } = event[0]; - if(type === 'remove') editorStore.closeFormPanel(); + if(type === 'remove') closeFormPanel(); } function onDragOver() { @@ -251,7 +251,7 @@ function onPaneReady() { @dragover.prevent="onDragOver" @dragenter.prevent @edge-click="onEdgeClick" - @pane-click="editorStore.closeFormPanel()" + @pane-click="closeFormPanel()" @connect="connect" @connect-start="onConnectStart" @connect-end="onConnectEnd" diff --git a/src/features/ePocFlow/nodes/ActivityNode.vue b/src/features/ePocFlow/nodes/ActivityNode.vue index 9351f11f..d532e342 100644 --- a/src/features/ePocFlow/nodes/ActivityNode.vue +++ b/src/features/ePocFlow/nodes/ActivityNode.vue @@ -3,7 +3,7 @@ import { Handle, Position, getConnectedEdges, useVueFlow, NodeProps, Emits } fro import { computed, ref } from 'vue'; import { useEditorStore } from '@/src/shared/stores'; import { getSelectedNodes } from '@/src/shared/services/graph'; -import { exitSelectNodeMode, getConnectedBadges, graphService } from '@/src/shared/services'; +import { closeFormPanel, exitSelectNodeMode, getConnectedBadges, graphService } from '@/src/shared/services'; import DraggableNode from '@/src/features/ePocFlow/nodes/content/DraggableNode.vue'; @@ -31,10 +31,6 @@ function openPageForm(id: string, formType: string) { } } -function closeFormPanel() { - editorStore.closeFormPanel(); -} - function addHoverEffect() { page.value.classList.add('hover'); } diff --git a/src/features/ePocFlow/nodes/ChapterNode.vue b/src/features/ePocFlow/nodes/ChapterNode.vue index f687ab2b..616ef9c4 100644 --- a/src/features/ePocFlow/nodes/ChapterNode.vue +++ b/src/features/ePocFlow/nodes/ChapterNode.vue @@ -4,7 +4,7 @@ import { Handle, useVueFlow, getConnectedEdges, NodeProps, Emits } from '@vue-fl import { Position } from '@vue-flow/core'; import { computed } from 'vue'; import ContentButton from '@/src/components/ContentButton.vue'; -import { exitSelectNodeMode, getConnectedBadges, graphService } from '@/src/shared/services'; +import { closeFormPanel, exitSelectNodeMode, getConnectedBadges, graphService } from '@/src/shared/services'; const editorStore = useEditorStore(); @@ -46,7 +46,7 @@ function openForm() { } function mouseDown() { - editorStore.closeFormPanel(); + closeFormPanel(); // unselect all nodes except current node nodes.value.forEach((node) => node.selected = currentNode.id === node.id); diff --git a/src/features/ePocFlow/nodes/PageNode.vue b/src/features/ePocFlow/nodes/PageNode.vue index 11d0e02f..7ccc0001 100644 --- a/src/features/ePocFlow/nodes/PageNode.vue +++ b/src/features/ePocFlow/nodes/PageNode.vue @@ -4,7 +4,7 @@ import { computed, Ref, ref } from 'vue'; import { useEditorStore } from '@/src/shared/stores'; import { NodeElement } from '@/src/shared/interfaces'; import { unselectAllNodes } from '@/src/shared/services/graph'; -import { exitSelectNodeMode, getConnectedBadges, graphService } from '@/src/shared/services'; +import { closeFormPanel, exitSelectNodeMode, getConnectedBadges, graphService } from '@/src/shared/services'; import { questions } from '@/src/shared/data'; import DraggableNode from './content/DraggableNode.vue'; @@ -32,10 +32,6 @@ function openPageForm(id: string, formType: string) { } } -function closeFormPanel() { - editorStore.closeFormPanel(); -} - function addHoverEffect() { page.value.classList.add('hover'); } diff --git a/src/features/ePocFlow/nodes/content/DraggableNode.vue b/src/features/ePocFlow/nodes/content/DraggableNode.vue index ea3aba7a..f0c7ea09 100644 --- a/src/features/ePocFlow/nodes/content/DraggableNode.vue +++ b/src/features/ePocFlow/nodes/content/DraggableNode.vue @@ -6,7 +6,7 @@ import { NodeElement, DraggableChange } from '@/src/shared/interfaces'; import { saveState } from '@/src/shared/services/undoRedo.service'; import { addContentToPage, changeContentOrder, removeContentFromPage, openFormPanel } from '@/src/shared/services/graph'; import { useVueFlow } from '@vue-flow/core'; -import { getConnectedBadges, graphService } from '@/src/shared/services'; +import { closeFormPanel, getConnectedBadges, graphService } from '@/src/shared/services'; import ContentButton from '@/src/components/ContentButton.vue'; @@ -98,10 +98,6 @@ function dragStart(event: DragEvent, element: NodeElement, index: number) { editorStore.draggedElement.element = element; } -function closeFormPanel() { - editorStore.closeFormPanel(); -} - function onContextMenu(contentId: string) { graphService.openContextMenu('content', { pageId: currentNode.value.id, id: contentId }); } diff --git a/src/features/ePocFlow/nodes/ePocNode.vue b/src/features/ePocFlow/nodes/ePocNode.vue index 8d49b006..d8b9fb4d 100644 --- a/src/features/ePocFlow/nodes/ePocNode.vue +++ b/src/features/ePocFlow/nodes/ePocNode.vue @@ -2,7 +2,7 @@ import { useEditorStore } from '@/src/shared/stores'; import { Emits, NodeProps, useVueFlow } from '@vue-flow/core'; import ContentButton from '@/src/components/ContentButton.vue'; -import { exitSelectNodeMode, graphService } from '@/src/shared/services'; +import { closeFormPanel, exitSelectNodeMode, graphService } from '@/src/shared/services'; import { computed } from 'vue'; const editorStore = useEditorStore(); @@ -48,7 +48,7 @@ function onContextMenu() { subtitle="ePoc" :rotate="true" @click="openForm()" - @mousedown="editorStore.closeFormPanel()" + @mousedown="closeFormPanel()" @contextmenu="onContextMenu" /> </div> diff --git a/src/features/forms/FormPanel.vue b/src/features/forms/FormPanel.vue index 8019194d..d33766e4 100644 --- a/src/features/forms/FormPanel.vue +++ b/src/features/forms/FormPanel.vue @@ -4,7 +4,7 @@ import { useEditorStore } from '../../shared/stores'; import FormButton from './components/FormButton.vue'; import GenericField from './components/GenericField.vue'; import { Input, NodeElement } from '@/src/shared/interfaces'; -import { addNewBadge, deleteBadge, editorService } from '@/src/shared/services'; +import { addNewBadge, closeFormPanel, deleteBadge, editorService } from '@/src/shared/services'; import { createToaster } from '@meforma/vue-toaster'; import { confirmDelete, @@ -107,7 +107,7 @@ function minimizeFormPanel() { <div class="command-buttons"> <button v-if="isMaximized" class="btn" @click="minimizeFormPanel"><i class="icon-minimize-2"></i></button> <button v-else class="btn" @click="maximizeFormPanel"><i class="icon-maximize-2"></i></button> - <button class="btn" @click="editorStore.closeFormPanel"><i class="icon-x"></i></button> + <button class="btn" @click="closeFormPanel"><i class="icon-x"></i></button> </div> <div class="title"> <div class="form-icon"><i :class="editorStore.formPanel.form.icon"></i></div> diff --git a/src/shared/services/editor.service.ts b/src/shared/services/editor.service.ts index b1f750bd..f96fae4c 100644 --- a/src/shared/services/editor.service.ts +++ b/src/shared/services/editor.service.ts @@ -3,7 +3,7 @@ import { router } from '@/src/router'; import { useEditorStore, useGraphStore, useUndoRedoStore } from '@/src/shared/stores'; import { ePocProject } from '@/src/shared/interfaces'; import { createToaster } from '@meforma/vue-toaster'; -import { graphService } from '@/src/shared/services/graph.service'; +import { closeFormPanel, graphService } from '.'; import { createGraphEpocFromData } from '@/src/shared/services/import.service'; import { FlowExportObject, useVueFlow } from '@vue-flow/core'; @@ -81,7 +81,8 @@ const setup = function () { editorStore.loading = false; return; } - editorStore.closeFormPanel(); + + closeFormPanel(); editorStore.currentProject = ePocProject; parsedData.flow = changeScreenToPage(parsedData.flow); diff --git a/src/shared/services/graph.service.ts b/src/shared/services/graph.service.ts index faa5ac81..c6c2f62f 100644 --- a/src/shared/services/graph.service.ts +++ b/src/shared/services/graph.service.ts @@ -15,13 +15,14 @@ import { import { questions } from '@/src/shared/data'; import { useEditorStore } from '@/src/shared/stores'; import { + deleteEmptyBadges, findContent, getContentIdFromId, getElementByContentId, setNodesSelectability } from '@/src/shared/services/graph'; import { Question } from '@epoc/epoc-types/src/v2'; -import { createRule, getConditions, getValidBadges } from '@/src/shared/services/badge.service'; +import { createRule, getConditions, getValidBadges } from '@/src/shared/services/graph/badge.service'; import { Badge, NodeElement } from '@/src/shared/interfaces'; declare const api: ApiInterface; @@ -395,4 +396,18 @@ export function exportBadgesToPage(badges: Record<string, Badge>): Record<string } return res; +} + +export function closeFormPanel() { + const editorStore = useEditorStore(); + + if(editorStore.selectNodeMode) return; + + if(this.formPanel.form && this.formPanel.form.type === 'badge') { + deleteEmptyBadges(); + } + + editorStore.formPanel.form = null; + editorStore.openedElementId = null; + editorStore.openedNodeId = null; } \ No newline at end of file diff --git a/src/shared/services/badge.service.ts b/src/shared/services/graph/badge.service.ts similarity index 93% rename from src/shared/services/badge.service.ts rename to src/shared/services/graph/badge.service.ts index cd7cd745..89b5b33c 100644 --- a/src/shared/services/badge.service.ts +++ b/src/shared/services/graph/badge.service.ts @@ -215,6 +215,22 @@ export function isBadgeValid(badge): boolean { return badge.rule.and.length > 0; } +export function isBadgeEmpty(badge): boolean { + return badge.title === '' + && badge.icon === '' + && badge.description === '' + && badge.rule.and.length === 0; +} + +export function deleteEmptyBadges() { + const epocNode = findNode('1'); + const badges = epocNode.data.formValues.badges; + + for(const badgeId in badges) { + if(isBadgeEmpty(badges[badgeId])) delete badges[badgeId]; + } +} + export function getValidBadges(){ const epocNode = findNode('1'); const badges = epocNode.data.formValues.badges; diff --git a/src/shared/services/graph/content.service.ts b/src/shared/services/graph/content.service.ts index a90ad0c6..6f569056 100644 --- a/src/shared/services/graph/content.service.ts +++ b/src/shared/services/graph/content.service.ts @@ -2,7 +2,7 @@ import { useVueFlow } from '@vue-flow/core'; import { useEditorStore } from '../../stores'; import {NodeElement, SideAction} from '../../interfaces'; import { deleteNode } from './node.service'; -import {generateContentId, generateId} from '../graph.service'; +import { closeFormPanel, generateContentId, generateId } from '../graph.service'; import * as forms from '@/src/shared/data/forms'; import { deleteConnectedConditions } from '@/src/shared/services'; @@ -47,7 +47,7 @@ export function changeContentOrder(startIndex: number, finalIndex: number, pageI //? The parameter pageMoved is used when openedParentId is not usable export function removeContentFromPage(index: number, pageId: string, pageMoved?: boolean): void { - editorStore.closeFormPanel(); + closeFormPanel(); const pageNode = findNode(pageId); pageNode.data.elements.splice(index, 1); diff --git a/src/shared/services/graph/element.service.ts b/src/shared/services/graph/element.service.ts index 3ab86de8..ba1c5af2 100644 --- a/src/shared/services/graph/element.service.ts +++ b/src/shared/services/graph/element.service.ts @@ -1,7 +1,7 @@ import { useVueFlow, Node, MarkerType, Edge } from '@vue-flow/core'; import { deleteContent, deleteNode, getContentByContentId } from './'; import { useEditorStore } from '@/src/shared/stores'; -import { exitSelectNodeMode, generateId } from '../graph.service'; +import { closeFormPanel, exitSelectNodeMode, generateId } from '../graph.service'; import { ElementType, NodeElement } from '../../interfaces'; const { nodes, findNode, addEdges } = useVueFlow({ id: 'main' }); @@ -17,7 +17,7 @@ export function deleteElement(id: string, pageId?: string): void { if(pageId || !pageToDelete) deleteContent(pageId ?? editorStore.openedNodeId, id); else deleteNode(id); - editorStore.closeFormPanel(); + closeFormPanel(); } export function createEdge(sourceId: string, targetId: string): void { diff --git a/src/shared/services/graph/index.ts b/src/shared/services/graph/index.ts index b735ddb1..88587507 100644 --- a/src/shared/services/graph/index.ts +++ b/src/shared/services/graph/index.ts @@ -1,4 +1,5 @@ export * from './content.service'; export * from './node.service'; export * from './element.service'; -export * from './copyPaste.service'; \ No newline at end of file +export * from './copyPaste.service'; +export * from './badge.service'; \ No newline at end of file diff --git a/src/shared/services/graph/node.service.ts b/src/shared/services/graph/node.service.ts index c358a003..3a70fad5 100644 --- a/src/shared/services/graph/node.service.ts +++ b/src/shared/services/graph/node.service.ts @@ -5,7 +5,7 @@ import { useVueFlow, Node, getConnectedEdges } from '@vue-flow/core'; import { NodeElement, SideAction } from '../../interfaces'; import { nextTick, toRaw, watch } from 'vue'; -import { deleteConnectedConditions } from '@/src/shared/services'; +import { closeFormPanel, deleteConnectedConditions } from '@/src/shared/services'; import { addContentToPage } from './content.service'; import { generateContentId, generateId, graphService } from '../graph.service'; import { deleteElement, deleteSelection, createEdge } from '.'; @@ -314,7 +314,7 @@ export function duplicatePage(pageId?: string): void { }; addNodes([newPage]); - editorStore.closeFormPanel(); + closeFormPanel(); } export function updateNextChapter(chapterId: string): void { @@ -333,7 +333,7 @@ export function transformActivityToPage(): void { pageNode.type = 'page'; pageNode.data.formType = 'page'; delete pageNode.data.formValues.summary; - editorStore.closeFormPanel(); + closeFormPanel(); editorStore.openFormPanel(pageNode.id, pageNode.data.formType); } diff --git a/src/shared/services/import.service.ts b/src/shared/services/import.service.ts index aca76156..64cf68e9 100644 --- a/src/shared/services/import.service.ts +++ b/src/shared/services/import.service.ts @@ -9,7 +9,7 @@ import { import { generateId } from '@/src/shared/services/graph.service'; import { questions, standardPages } from '@/src/shared/data'; import { Assessment, ChoiceCondition, SimpleQuestion } from '@epoc/epoc-types/src/v1'; -import { createRule, getConditions } from '@/src/shared/services/badge.service'; +import { createRule, getConditions } from '@/src/shared/services/graph/badge.service'; import { Node } from '@vue-flow/core'; import { Badge } from '@/src/shared/interfaces'; diff --git a/src/shared/services/index.ts b/src/shared/services/index.ts index c76024e2..56a35ba2 100644 --- a/src/shared/services/index.ts +++ b/src/shared/services/index.ts @@ -1,3 +1,3 @@ export * from './editor.service'; export * from './graph.service'; -export * from './badge.service'; \ No newline at end of file +export * from './graph'; \ No newline at end of file diff --git a/src/shared/services/undoRedo.service.ts b/src/shared/services/undoRedo.service.ts index 46378bc6..6763388b 100644 --- a/src/shared/services/undoRedo.service.ts +++ b/src/shared/services/undoRedo.service.ts @@ -2,6 +2,7 @@ import { useVueFlow } from '@vue-flow/core'; import { useUndoRedoStore, useGraphStore, useEditorStore } from '../stores'; import { ePocState } from '../interfaces'; import { ApiInterface } from '../interfaces/api.interface'; +import { closeFormPanel } from '.'; const { toObject } = useVueFlow({ id: 'main' }); @@ -65,7 +66,7 @@ export function revertToState(state: string): string { const graphStore = useGraphStore(); const editorStore = useEditorStore(); - editorStore.closeFormPanel(); + closeFormPanel(); const { flow, form } = JSON.parse(state); diff --git a/src/shared/stores/editorStore.ts b/src/shared/stores/editorStore.ts index 66cddb5e..cb33366d 100644 --- a/src/shared/stores/editorStore.ts +++ b/src/shared/stores/editorStore.ts @@ -197,15 +197,6 @@ export const useEditorStore = defineStore('editor', { }); }, - closeFormPanel(): void { - //? prevent closing the form panel when selecting a node - if(this.selectNodeMode) return; - - this.formPanel.form = null; - this.openedElementId = null; - this.openedNodeId = null; - }, - closeValidationModal(): void { this.validationModal = false; }, -- GitLab From e640643e0e863e591ffb8b1f76991da25cdfa263 Mon Sep 17 00:00:00 2001 From: VIAUD Nathan <nathan.viaud@inria.fr> Date: Mon, 13 Nov 2023 11:37:29 +0100 Subject: [PATCH 2/2] fix --- src/shared/services/graph.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/services/graph.service.ts b/src/shared/services/graph.service.ts index c6c2f62f..dcbe4f64 100644 --- a/src/shared/services/graph.service.ts +++ b/src/shared/services/graph.service.ts @@ -403,7 +403,7 @@ export function closeFormPanel() { if(editorStore.selectNodeMode) return; - if(this.formPanel.form && this.formPanel.form.type === 'badge') { + if(editorStore.formPanel.form && editorStore.formPanel.form.type === 'badge') { deleteEmptyBadges(); } -- GitLab