From 842f204123afc3b9b4633b68de58cffb3af4f912 Mon Sep 17 00:00:00 2001 From: Dominik Pschenitschni Date: Thu, 19 Jan 2023 18:08:42 +0100 Subject: [PATCH] fix: improve projectView storing and add migration --- src/helpers/projectView.ts | 100 +++++++++++++++++++++++++++++++++ src/helpers/saveProjectView.ts | 63 --------------------- src/router/index.ts | 12 ++-- 3 files changed, 106 insertions(+), 69 deletions(-) create mode 100644 src/helpers/projectView.ts delete mode 100644 src/helpers/saveProjectView.ts diff --git a/src/helpers/projectView.ts b/src/helpers/projectView.ts new file mode 100644 index 000000000..1afb00e67 --- /dev/null +++ b/src/helpers/projectView.ts @@ -0,0 +1,100 @@ +import type { RouteRecordName } from 'vue-router' +import router from '@/router' + +import type {IProject} from '@/modelTypes/IProject' + +export type ProjectRouteName = Extract +export type ProjectViewSettings = Record< + IProject['id'], + Extract +> + +const SETTINGS_KEY_PROJECT_VIEW = 'projectView' + +// TODO: remove migration when releasing 1.0 +type ListViewSettings = ProjectViewSettings +const SETTINGS_KEY_DEPRECATED_LIST_VIEW = 'listView' +function migrateStoredProjectRouteSettings() { + try { + const listViewSettingsString = localStorage.getItem(SETTINGS_KEY_DEPRECATED_LIST_VIEW) + if (listViewSettingsString === null) { + return + } + + // A) the first version stored one setting for all lists in a string + if (listViewSettingsString.startsWith('list.')) { + const projectView = listViewSettingsString.replace('list.', 'project.') + + if (!router.hasRoute(projectView)) { + return + } + return projectView as RouteRecordName + } + + // B) the last version used a 'list.' prefix + const listViewSettings: ListViewSettings = JSON.parse(listViewSettingsString) + + const projectViewSettingEntries = Object.entries(listViewSettings).map(([id, value]) => { + return [id, value.replace('list.', 'project.')] + }) + const projectViewSettings = Object.fromEntries(projectViewSettingEntries) + + localStorage.setItem(SETTINGS_KEY_PROJECT_VIEW, JSON.stringify(projectViewSettings)) + } catch(e) { + // + } finally { + localStorage.removeItem(SETTINGS_KEY_DEPRECATED_LIST_VIEW) + } +} + +/** + * Save the current project view to local storage + */ +export function saveProjectView(projectId: IProject['id'], routeName: string) { + if (routeName.includes('settings.')) { + return + } + + if (!projectId) { + return + } + + // We use local storage and not the store here to make it persistent across reloads. + const savedProjectView = localStorage.getItem(SETTINGS_KEY_PROJECT_VIEW) + let savedProjectViewSettings: ProjectViewSettings | false = false + if (savedProjectView !== null) { + savedProjectViewSettings = JSON.parse(savedProjectView) as ProjectViewSettings + } + + let projectViewSettings: ProjectViewSettings = {} + if (savedProjectViewSettings) { + projectViewSettings = savedProjectViewSettings + } + + projectViewSettings[projectId] = routeName + localStorage.setItem(SETTINGS_KEY_PROJECT_VIEW, JSON.stringify(projectViewSettings)) +} + +export const getProjectView = (projectId: IProject['id']) => { + // TODO: remove migration when releasing 1.0 + const migratedProjectView = migrateStoredProjectRouteSettings() + + if (migratedProjectView !== undefined && router.hasRoute(migratedProjectView)) { + return migratedProjectView + } + + try { + const projectViewSettingsString = localStorage.getItem(SETTINGS_KEY_PROJECT_VIEW) + if (!projectViewSettingsString) { + throw new Error() + } + + const projectViewSettings = JSON.parse(projectViewSettingsString) as ProjectViewSettings + if (router.hasRoute(projectViewSettings[projectId])) { + throw new Error() + } + return projectViewSettings[projectId] + } catch (e) { + return + } +} \ No newline at end of file diff --git a/src/helpers/saveProjectView.ts b/src/helpers/saveProjectView.ts deleted file mode 100644 index 879b6b0e9..000000000 --- a/src/helpers/saveProjectView.ts +++ /dev/null @@ -1,63 +0,0 @@ -import type { IProject } from '@/modelTypes/IProject' - -type ProjectView = Record - -const DEFAULT_PROJECT_VIEW = 'project.list' as const -const PROJECT_VIEW_SETTINGS_KEY = 'projectView' - -/** - * Save the current project view to local storage - */ -export function saveProjectView(projectId: IProject['id'], routeName: string) { - if (routeName.includes('settings.')) { - return - } - - if (!projectId) { - return - } - - // We use local storage and not the store here to make it persistent across reloads. - const savedProjectView = localStorage.getItem(PROJECT_VIEW_SETTINGS_KEY) - let savedProjectViewJson: ProjectView | false = false - if (savedProjectView !== null) { - savedProjectViewJson = JSON.parse(savedProjectView) as ProjectView - } - - let projectView: ProjectView = {} - if (savedProjectViewJson) { - projectView = savedProjectViewJson - } - - projectView[projectId] = routeName - localStorage.setItem(PROJECT_VIEW_SETTINGS_KEY, JSON.stringify(projectView)) -} - -export const getProjectView = (projectId: IProject['id']) => { - // Migrate old setting over - // TODO: remove when 1.0 release - const oldListViewSettings = localStorage.getItem('listView') - if (oldListViewSettings !== null) { - localStorage.setItem(PROJECT_VIEW_SETTINGS_KEY, oldListViewSettings) - localStorage.removeItem('listView') - } - - // Remove old stored settings - // TODO: remove when 1.0 release - const savedProjectView = localStorage.getItem(PROJECT_VIEW_SETTINGS_KEY) - if (savedProjectView !== null && savedProjectView.startsWith('project.')) { - localStorage.removeItem(PROJECT_VIEW_SETTINGS_KEY) - } - - if (!savedProjectView) { - return DEFAULT_PROJECT_VIEW - } - - const savedProjectViewJson: ProjectView = JSON.parse(savedProjectView) - - if (!savedProjectViewJson[projectId]) { - return DEFAULT_PROJECT_VIEW - } - - return savedProjectViewJson[projectId] -} \ No newline at end of file diff --git a/src/router/index.ts b/src/router/index.ts index 7b220638e..6a2a30346 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -2,7 +2,7 @@ import { createRouter, createWebHistory } from 'vue-router' import type { RouteLocation } from 'vue-router' import {saveLastVisited} from '@/helpers/saveLastVisited' -import {saveProjectView, getProjectView} from '@/helpers/saveProjectView' +import {saveProjectView, getProjectView} from '@/helpers/projectView' import {parseDateOrString} from '@/helpers/time/parseDateOrString' import {getNextWeekDate} from '@/helpers/time/getNextWeekDate' import {setTitle} from '@/helpers/setTitle' @@ -357,14 +357,14 @@ const router = createRouter({ name: 'project.index', redirect(to) { // Redirect the user to list view by default + const savedProjectView = getProjectView(Number(to.params.projectId as string)) - const savedProjectView = getProjectView(to.params.projectId) - console.debug('Replaced list view with', savedProjectView) + if (savedProjectView) { + console.log('Replaced list view with', savedProjectView) + } return { - name: router.hasRoute(savedProjectView) - ? savedProjectView - : 'project.list', + name: savedProjectView || 'project.list', params: {projectId: to.params.projectId}, } },