From 25694887d4672d03c61fbb55179d38a182962977 Mon Sep 17 00:00:00 2001 From: Jack Wilburn Date: Tue, 6 Jun 2023 14:17:32 -0600 Subject: [PATCH 1/3] Add session saving and restoring to the provenance store --- src/store/provenance.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/store/provenance.ts b/src/store/provenance.ts index 836e6cd9..31dadded 100644 --- a/src/store/provenance.ts +++ b/src/store/provenance.ts @@ -1,4 +1,6 @@ +import api from '@/api'; import { findDifferencesInPrimitiveStates, getTrrackLabel, isArray } from '@/lib/provenanceUtils'; +import { getUrlVars } from '@/lib/utils'; import { Cell, ProvState, SlicingConfig } from '@/types'; import { initializeTrrack, Registry } from '@trrack/core'; import { defineStore } from 'pinia'; @@ -27,6 +29,8 @@ export const useProvenanceStore = defineStore('provenance', () => { const sliceIndex = ref(0); const sortBy = ref<{ network : string | null; node: string | null }>({ network: null, node: null }); + const { sessionId } = getUrlVars(); + // A live computed state so that we can edit the values when trrack does undo/redo const currentPiniaState = computed(() => ({ selectNeighbors, @@ -110,8 +114,24 @@ export const useProvenanceStore = defineStore('provenance', () => { const updates = findDifferencesInPrimitiveStates(getPiniaStateSnapshot(), provenance.getState()); Object.entries(updates).forEach(([key, val]) => { currentPiniaState.value[key as keyof ProvState].value = val; }); } + + api.updateSession(sessionId || '', 'network', provenance.export()); }); + // Attempt to restore session + async function restoreSession() { + if (sessionId) { + const session = await api.getSession(sessionId, 'network'); + + // If the session is empty, the API will be an empty object + // Only attempt to import if we have a string + if (typeof session.state === 'string') { + provenance.import(session.state); + } + } + } + restoreSession(); + return { provenance, selectNeighbors, From 553563b2a09a9d7ba6d429e77e200dc30e0f0e52 Mon Sep 17 00:00:00 2001 From: Jack Wilburn Date: Fri, 28 Jul 2023 10:05:39 -0600 Subject: [PATCH 2/3] Move getUrlVars to provenance store so we can access sessionId --- src/App.vue | 6 +----- src/store/index.ts | 31 ++++++++++++++----------------- src/store/provenance.ts | 18 +++++++++++++----- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/App.vue b/src/App.vue index 3d1553e8..0defab5a 100644 --- a/src/App.vue +++ b/src/App.vue @@ -24,11 +24,7 @@ const { userInfo, } = storeToRefs(store); -const urlVars = getUrlVars(); -store.fetchNetwork( - urlVars.workspace, - urlVars.network, -); +store.fetchNetwork(); // Set up provenance undo and redo, provenance is not a ref here const { provenance } = store; diff --git a/src/store/index.ts b/src/store/index.ts index 103cc58b..486a84ae 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -37,10 +37,10 @@ export const useStore = defineStore('store', () => { slicingConfig, sliceIndex, sortBy, + workspaceName, + networkName, } = storeToRefs(provStore); - const workspaceName = ref(''); - const networkName = ref(''); const loadError = ref({ message: '', href: '', @@ -290,10 +290,14 @@ export const useStore = defineStore('store', () => { }); } - async function fetchNetwork(workspaceNameLocal: string, networkNameLocal: string) { - workspaceName.value = workspaceNameLocal; - networkName.value = networkNameLocal; - + async function fetchNetwork() { + if (workspaceName.value === '' || networkName.value === '') { + loadError.value = { + message: 'Workspace and/or network were not defined in the url', + href: 'https://multinet.app', + }; + return; + } let networkLocal: NetworkSpec | undefined; // Get all table names @@ -302,17 +306,10 @@ export const useStore = defineStore('store', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { if (error.status === 404) { - if (workspaceName.value === undefined || networkName.value === undefined) { - loadError.value = { - message: 'Workspace and/or network were not defined in the url', - href: 'https://multinet.app', - }; - } else { - loadError.value = { - message: error.statusText, - href: 'https://multinet.app', - }; - } + loadError.value = { + message: error.statusText, + href: 'https://multinet.app', + }; } else if (error.status === 401) { loadError.value = { message: 'You are not authorized to view this workspace', diff --git a/src/store/provenance.ts b/src/store/provenance.ts index 31dadded..76b9fa4d 100644 --- a/src/store/provenance.ts +++ b/src/store/provenance.ts @@ -29,8 +29,6 @@ export const useProvenanceStore = defineStore('provenance', () => { const sliceIndex = ref(0); const sortBy = ref<{ network : string | null; node: string | null }>({ network: null, node: null }); - const { sessionId } = getUrlVars(); - // A live computed state so that we can edit the values when trrack does undo/redo const currentPiniaState = computed(() => ({ selectNeighbors, @@ -114,14 +112,22 @@ export const useProvenanceStore = defineStore('provenance', () => { const updates = findDifferencesInPrimitiveStates(getPiniaStateSnapshot(), provenance.getState()); Object.entries(updates).forEach(([key, val]) => { currentPiniaState.value[key as keyof ProvState].value = val; }); } + }); + + // Variables to help with session management (this is not tracked in trrack) + const { sessionId, workspace, network } = getUrlVars(); + const workspaceName = ref(workspace || ''); + const networkName = ref(network || ''); - api.updateSession(sessionId || '', 'network', provenance.export()); + // Update the session when the provenance changes + provenance.currentChange(() => { + api.updateSession(workspaceName.value, sessionId || '', 'network', provenance.export()); }); - // Attempt to restore session + // Attempt to restore session on first load async function restoreSession() { if (sessionId) { - const session = await api.getSession(sessionId, 'network'); + const session = await api.getSession(workspaceName.value, sessionId, 'network'); // If the session is empty, the API will be an empty object // Only attempt to import if we have a string @@ -146,5 +152,7 @@ export const useProvenanceStore = defineStore('provenance', () => { slicingConfig, sliceIndex, sortBy, + workspaceName, + networkName, }; }); From e1f9ccc64cbb516d06b25afd88e22b3276de5edf Mon Sep 17 00:00:00 2001 From: Jack Wilburn Date: Mon, 31 Jul 2023 13:20:20 -0600 Subject: [PATCH 3/3] Bump multinet --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index cf857048..03d80d27 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "d3": "7.8.0", "eslint-import-resolver-alias": "^1.1.2", "lineupjs": "^4.2.0", - "multinet": "^0.21.11", + "multinet": "^0.21.13", "multinet-components": "^0.0.6", "pinia": "^2.0.28", "react": "^18.2.0", diff --git a/yarn.lock b/yarn.lock index 2875b0f6..f6a0590a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3267,10 +3267,10 @@ multinet-components@^0.0.6: resolved "https://registry.yarnpkg.com/multinet-components/-/multinet-components-0.0.6.tgz#7b5b62de7a3504c0fe8b5928aea048506b209802" integrity sha512-PkAEWTtk7/7lwZhYlHfMeYFo8zutvVJ/DxMsuN4wZCddyseBAP70vTnKkLcSK3WsS96XsibWjCDl1AHz2pACIg== -multinet@^0.21.11: - version "0.21.11" - resolved "https://registry.yarnpkg.com/multinet/-/multinet-0.21.11.tgz#040209b42a7b5dc4122c30f346109094ba1e0199" - integrity sha512-7MYTnqv4Gbr+AcQB2fwkA03F5nNqBrr/mNu/sSeIUcFd6cC/nZRQyRwPa40jTjFV80HahYeHvqQZCpMvdY/PYA== +multinet@^0.21.13: + version "0.21.13" + resolved "https://registry.yarnpkg.com/multinet/-/multinet-0.21.13.tgz#a4c440b05369bcb2001a728c9ecf9cc2b86a298c" + integrity sha512-UI++fPe3nr1ueEO5VSqGtL1rb6iV8Qt7ACE2Srw2HqcHt+jdhXmaf439XZtrRHl/TqcBE6xlnsObDSnbyiHbgQ== dependencies: axios "^0.21.1" django-s3-file-field "^0.1.2"