diff --git a/examples/SaveRestore/Controls.vue b/examples/SaveRestore/Controls.vue new file mode 100644 index 00000000..9ca6cd13 --- /dev/null +++ b/examples/SaveRestore/Controls.vue @@ -0,0 +1,60 @@ + + diff --git a/examples/SaveRestore/SaveRestoreExample.vue b/examples/SaveRestore/SaveRestoreExample.vue new file mode 100644 index 00000000..38d755d5 --- /dev/null +++ b/examples/SaveRestore/SaveRestoreExample.vue @@ -0,0 +1,26 @@ + + diff --git a/examples/SaveRestore/save.css b/examples/SaveRestore/save.css new file mode 100644 index 00000000..ffd028dd --- /dev/null +++ b/examples/SaveRestore/save.css @@ -0,0 +1,11 @@ +.save__controls { + position: absolute; + right: 10px; + top: 10px; + z-index: 4; + font-size: 12px; +} + +.save__controls button { + margin-left: 5px; +} diff --git a/examples/router.ts b/examples/router.ts index ea3a18f2..bb60ab57 100644 --- a/examples/router.ts +++ b/examples/router.ts @@ -65,6 +65,14 @@ export const routes: RouterOptions['routes'] = [ path: '/overview', component: () => import('./Overview/Overview.vue'), }, + { + path: '/provider', + component: () => import('./Provider/ProviderExample.vue'), + }, + { + path: '/save-restore', + component: () => import('./SaveRestore/SaveRestoreExample.vue'), + }, ] export const router = createRouter({ diff --git a/package.json b/package.json index 373045e2..db7bb5dc 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-prettier": "^3.4.1", + "localforage": "^1.10.0", "np": "^7.5.0", "pnpm": "^6.18.0", "postcss": "^8.3.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dbf324d6..09a6d5da 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,6 +22,7 @@ specifiers: eslint-config-prettier: ^8.3.0 eslint-plugin-prettier: ^3.4.1 fast-deep-equal: ^3.1.3 + localforage: ^1.10.0 np: ^7.5.0 pinia: ^2.0.0-rc.14 pnpm: ^6.18.0 @@ -68,6 +69,7 @@ devDependencies: eslint: 7.32.0 eslint-config-prettier: 8.3.0_eslint@7.32.0 eslint-plugin-prettier: 3.4.1_6e975bd57c7acf028c1a9ddbbf60c898 + localforage: 1.10.0 np: 7.5.0 pnpm: 6.18.0 postcss: 8.3.9 @@ -3416,6 +3418,10 @@ packages: engines: {node: '>= 4'} dev: true + /immediate/3.0.6: + resolution: {integrity: sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=} + dev: true + /import-cwd/3.0.0: resolution: {integrity: sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg==} engines: {node: '>=8'} @@ -3967,6 +3973,12 @@ packages: type-check: 0.4.0 dev: true + /lie/3.1.1: + resolution: {integrity: sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=} + dependencies: + immediate: 3.0.6 + dev: true + /lilconfig/2.0.3: resolution: {integrity: sha512-EHKqr/+ZvdKCifpNrJCKxBTgk5XupZA3y/aCPY9mxfgBzmgh93Mt/WqjjQ38oMxXuvDokaKiM3lAgvSH2sjtHg==} engines: {node: '>=10'} @@ -4050,6 +4062,12 @@ packages: mlly: 0.2.10 dev: true + /localforage/1.10.0: + resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==} + dependencies: + lie: 3.1.1 + dev: true + /locate-path/2.0.0: resolution: {integrity: sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=} engines: {node: '>=4'} diff --git a/src/types/types.ts b/src/types/types.ts index 811c3c9d..c41824cf 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -6,7 +6,7 @@ import { KeyCode, PanOnScrollMode } from '~/types/panel' export type ElementId = string -export type FlowElement = Partial> | Partial> +export type FlowElement = Node | Edge export type Elements = Array> diff --git a/src/utils/graph.ts b/src/utils/graph.ts index 52a03f40..73e64903 100644 --- a/src/utils/graph.ts +++ b/src/utils/graph.ts @@ -273,7 +273,6 @@ const parseElements = (nodes: Node[], edges: Edge[]): Elements => [ n.position = n.__rf.position - n.__rf = {} as any return n }), ...edges.map((e) => ({ ...e })), @@ -282,11 +281,16 @@ const parseElements = (nodes: Node[], edges: Edge[]): Elements => [ export const onLoadGetElements = (currentStore: FlowStore) => (): Elements => parseElements(currentStore.nodes || [], currentStore.edges || []) -export const onLoadToObject = (currentStore: FlowStore) => (): FlowExportObject => ({ - elements: parseElements(currentStore.nodes || [], currentStore.edges || []), - position: [currentStore.transform[0], currentStore.transform[1]], - zoom: currentStore.transform[2], -}) +export const onLoadToObject = (currentStore: FlowStore) => (): FlowExportObject => { + // we have to stringify/parse so objects containing refs (like nodes and edges) can potentially be saved in a storage + return JSON.parse( + JSON.stringify({ + elements: parseElements(currentStore.nodes || [], currentStore.edges || []), + position: [currentStore.transform[0], currentStore.transform[1]], + zoom: currentStore.transform[2], + }), + ) +} export const getTransformForBounds = ( bounds: Rect,