fix: improve projectView storing and add migration

This commit is contained in:
Dominik Pschenitschni 2023-01-19 18:08:42 +01:00 committed by kolaente
parent 01cb413ccd
commit 5283b871db
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
3 changed files with 106 additions and 69 deletions

100
src/helpers/projectView.ts Normal file
View File

@ -0,0 +1,100 @@
import type { RouteRecordName } from 'vue-router'
import router from '@/router'
import type {IProject} from '@/modelTypes/IProject'
export type ProjectRouteName = Extract<RouteRecordName, string>
export type ProjectViewSettings = Record<
IProject['id'],
Extract<RouteRecordName, ProjectRouteName>
>
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
}
}

View File

@ -1,63 +0,0 @@
import type { IProject } from '@/modelTypes/IProject'
type ProjectView = Record<IProject['id'], string>
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]
}

View File

@ -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},
}
},