diff --git a/corkboard.png b/corkboard.png new file mode 100644 index 0000000..1d435bc Binary files /dev/null and b/corkboard.png differ diff --git a/index.html b/index.html index ac50385..d8841a9 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - VueFlow Dialogue Editor + Corkboard
diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..65c1d3d Binary files /dev/null and b/logo.png differ diff --git a/package.json b/package.json index 7a5b17d..7f853d8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "vueflow-dialogue-editor", - "version": "0.0.0", - "private": true, + "name": "corkboard", + "version": "1.0.0", + "private": false, "type": "module", "scripts": { "dev": "vite", diff --git a/pin-icon.png b/pin-icon.png deleted file mode 100644 index e775180..0000000 Binary files a/pin-icon.png and /dev/null differ diff --git a/public/favicon.ico b/public/favicon.ico index df36fcf..11094a6 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/src/App.vue b/src/App.vue index ef505cd..da23c74 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,5 +1,5 @@ /** -VueFlow Dialogue Editor by NOKORI, 2024 +Corkboard Dialogue/Node-based Editor by NOKORIWARE, 2024 Uses the following APIs: -VueFlow -VueQuill @@ -30,13 +30,18 @@ import Icon from './Icon.vue' import { v4 as uuidv4 } from 'uuid'; const { onInit, screenToFlowCoordinate, - onConnect, onNodesInitialized, onNodeDrag, updateNode, findNode, getNodes, + onConnect, onNodesInitialized, onNodeDrag, updateNode, findNode, isNodeIntersecting, getIntersectingNodes, addNodes, onNodeDoubleClick, onNodesChange, applyNodeChanges, onNodeContextMenu, removeNodes, addEdges, onEdgeDoubleClick, onEdgesChange, applyEdgeChanges, onEdgeContextMenu, removeEdges, onSelectionContextMenu, onPaneContextMenu, - toObject, fromObject } = useVueFlow(); + toObject, fromObject, + getNodes, getEdges, vueFlowRef, } = useVueFlow(); + + +//If enabled, a dialog will ask the user to confirm the deletion of elements +let confirmDelete = true; //Node intersecting const panelEl = ref() @@ -59,14 +64,13 @@ onConnect(addEdges) const deleteKey = 'Delete'; const confirmDeleteDialog = useConfirmDeleteDialog(); +//Node Deleting onNodesChange(async (changes) => { const nextChanges = [] for (const change of changes) { if (change.type === 'remove') { - //await causes the isConfirmed const to wait on a response from the dialog.confirmDefault function - const isConfirmed = await confirmDeleteDialog.confirmDefault(change.id) - if (isConfirmed) { + if (await canDelete(change)) { componentUtil.deleteComponents(getNodes, change.id); nextChanges.push(change) } @@ -75,10 +79,11 @@ onNodesChange(async (changes) => { } } + confirmDelete = true; applyNodeChanges(nextChanges) }) -//Edge Renaming +//Edge Deleting onEdgesChange(async (changes) => { const nextChanges = [] @@ -88,9 +93,7 @@ onEdgesChange(async (changes) => { } if (change.type === 'remove') { - const isConfirmed = await confirmDeleteDialog.confirmDefault(change.id) - - if (isConfirmed) { + if (await canDelete(change)) { nextChanges.push(change) } } else { @@ -98,9 +101,20 @@ onEdgesChange(async (changes) => { } } + confirmDelete = true; applyEdgeChanges(nextChanges) }) +async function canDelete(change) { + if (confirmDelete) { + //await causes the isConfirmed const to wait on a response from the dialog.confirmDefault function + return await confirmDeleteDialog.confirmDefault(change.id); + } + + return true; +} + +//Edge Renaming onEdgeDoubleClick(({ mouseEvent, edge }) => { editingEdge.value = edge; mouseX = edge.sourceX; @@ -295,6 +309,18 @@ const panelPosition = computed(() => { /* Saving & Loading Data */ +async function onReset() { + const isConfirmed = await confirmDeleteDialog.confirmReset(); + + if (isConfirmed) { + + confirmDelete = false; + removeNodes(getNodes.value); + + } + +} + function onSave() { const saveData = JSON.stringify(toObject(), null, 2); @@ -369,24 +395,31 @@ async function onLoad() { - + + + + + + - - + + - + +
- +
diff --git a/src/Icon.vue b/src/Icon.vue index cca0daf..2357c26 100644 --- a/src/Icon.vue +++ b/src/Icon.vue @@ -7,6 +7,7 @@ defineProps({ }) + \ No newline at end of file diff --git a/src/components/DialogConfirmDeleteUse.js b/src/components/DialogConfirmDeleteUse.js index e5859d7..133556e 100644 --- a/src/components/DialogConfirmDeleteUse.js +++ b/src/components/DialogConfirmDeleteUse.js @@ -20,13 +20,6 @@ export function useDialogConfirmDelete() { } } -export function useConfirmDeleteDialog() { - return{ - confirm, - confirmDefault - } -} - function confirm(msg) { isVisible.value = true message.value = msg @@ -50,6 +43,29 @@ function confirmDefault(id){ )); } +function confirmReset(){ + return confirm(h( + 'span', + { + style: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + gap: '8px', + }, + }, + [`Reset workspace?`, h('br'), `This cannot be undone.`], + )); +} + +export function useConfirmDeleteDialog() { + return{ + confirm, + confirmDefault, + confirmReset + } +} + //Another way /*export function useDialog() { return { diff --git a/src/initial-elements.js b/src/initial-elements.js index 5666bff..ba894e0 100644 --- a/src/initial-elements.js +++ b/src/initial-elements.js @@ -1,4 +1,3 @@ -import { MarkerType } from '@vue-flow/core'; import { reactive } from 'vue'; import { v4 as uuidv4 } from 'uuid'; @@ -10,8 +9,8 @@ export const initialNodes = reactive([ position: { x: 0, y: 0 }, // all nodes can have a data object containing any data you want to pass to the node // a label can property can be used for default nodes - data: { - label: 'Node 1', + data: { + label: 'Node 1', body: "", components: [] }, @@ -23,7 +22,7 @@ export const initialNodes = reactive([ { id: uuidv4(), type: 'text-field', - position: { x: 400, y: 0 }, + position: { x: 500, y: 0 }, data: { label: 'Node 2' }, }, @@ -31,7 +30,7 @@ export const initialNodes = reactive([ { id: uuidv4(), type: 'text-area', - position: { x: 700, y: 0 }, + position: { x: 900, y: 0 }, data: { label: 'Node 3', body: '' }, }, @@ -39,8 +38,11 @@ export const initialNodes = reactive([ { id: uuidv4(), type: 'note', - position: { x: 300, y: 400 }, - data: { label: 'Note Node', body: 'Welcome!' }, + position: { x: 375, y: 175 }, + data: { + label: 'Welcome to Corkboard!', + body: 'Getting Started:
  1. Right click the background to bring up the context menu
  2. Double click nodes to delete and modify them
  3. Drag attribute nodes over text area nodes to combine them
  4. Save & load projects using the toolbar in the upper-left
' + }, }, ]); diff --git a/src/nodes/ComponentUtil.js b/src/nodes/ComponentUtil.js index 2ed76b9..5966b28 100644 --- a/src/nodes/ComponentUtil.js +++ b/src/nodes/ComponentUtil.js @@ -40,7 +40,7 @@ export function useComponentUtil() { for (const node of nodes.value){ - console.log(node.id); + //console.log(node.id); if (node.id == componentNodeID){ continue;