wip: use map instead of object to store projects

This commit is contained in:
kolaente 2023-04-10 17:39:29 +02:00
parent d694f168b2
commit 634af32400
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
6 changed files with 34 additions and 29 deletions

View File

@ -61,6 +61,7 @@
"bulma-css-variables": "0.9.33",
"camel-case": "4.1.2",
"codemirror": "5.65.12",
"core-js": "^3.30.0",
"date-fns": "2.29.3",
"dayjs": "1.11.7",
"dompurify": "3.0.1",

View File

@ -54,6 +54,9 @@ dependencies:
codemirror:
specifier: 5.65.12
version: 5.65.12
core-js:
specifier: ^3.30.0
version: 3.30.0
date-fns:
specifier: 2.29.3
version: 2.29.3
@ -4236,7 +4239,7 @@ packages:
'@babel/core': 7.21.3
'@babel/preset-env': 7.20.2(@babel/core@7.21.3)
browserslist: 4.21.5
core-js: 3.29.1
core-js: 3.30.0
magic-string: 0.30.0
regenerator-runtime: 0.13.11
systemjs: 6.14.0
@ -6081,10 +6084,9 @@ packages:
browserslist: 4.21.5
dev: true
/core-js@3.29.1:
resolution: {integrity: sha512-+jwgnhg6cQxKYIIjGtAHq2nwUOolo9eoFZ4sHfUH09BLXBgxnH4gA0zEd+t+BO2cNB8idaBtZFcFTRjQJRJmAw==}
/core-js@3.30.0:
resolution: {integrity: sha512-hQotSSARoNh1mYPi9O2YaWeiq/cEB95kOrFb4NCrO4RIFt1qqNpKsaE+vy/L3oiqvND5cThqXzUU3r9F7Efztg==}
requiresBuild: true
dev: true
/core-util-is@1.0.2:
resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==}

View File

@ -42,7 +42,7 @@ import type {IProject} from '@/modelTypes/IProject'
import {useProjectStore} from '@/stores/projects'
const props = defineProps<{
modelValue?: IProject[],
modelValue?: Map<number, IProject>,
canEditOrder: boolean,
canCollapse?: boolean,
level?: number,
@ -59,11 +59,11 @@ const projectStore = useProjectStore()
// Vue draggable will modify the projects list as it changes their position which will not work on a prop.
// Hence, we'll clone the prop and work on the clone.
const availableProjects = ref<IProject[]>([])
const availableProjects = ref<Map<number, IProject>>(new Map())
watch(
() => props.modelValue,
projects => {
availableProjects.value = projects || []
availableProjects.value = projects || new Map<number, IProject>()
},
{immediate: true},
)
@ -77,14 +77,14 @@ async function saveProjectPosition(e: SortableEvent) {
// If the project was dragged to the last position, Safari will report e.newIndex as the size of the projectsActive
// array instead of using the position. Because the index is wrong in that case, dragging the project will fail.
// To work around that we're explicitly checking that case here and decrease the index.
const newIndex = e.newIndex === projectsActive.length ? e.newIndex - 1 : e.newIndex
const newIndex = e.newIndex === projectsActive.size > 0 ? e.newIndex - 1 : e.newIndex
const projectId = parseInt(e.item.dataset.projectId)
const project = projectStore.getProjectById(projectId)
const parentProjectId = e.to.parentNode.dataset.projectId ? parseInt(e.to.parentNode.dataset.projectId) : 0
const projectBefore = projectsActive[newIndex - 1] ?? null
const projectAfter = projectsActive[newIndex + 1] ?? null
const projectBefore = projectsActive.get(newIndex - 1) ?? null
const projectAfter = projectsActive.get(newIndex + 1) ?? null
projectUpdating.value[project.id] = true
const position = calculateItemPosition(

View File

@ -85,9 +85,11 @@ const menuActive = computed(() => baseStore.menuActive)
const projectsLoading = computed(() => projectStore.isLoading)
const projects = computed(() => projectStore.notArchivedRootProjects
.sort((a, b) => a.position - b.position))
// .sort((a, b) => a.position - b.position))
)
const favoriteProjects = computed(() => projectStore.favoriteProjects
.sort((a, b) => a.position - b.position))
// .sort((a, b) => a.position - b.position))
)
</script>
<style lang="scss" scoped>

View File

@ -1,3 +1,4 @@
import 'core-js/modules/esnext.map.find'
import {watch, reactive, shallowReactive, unref, toRefs, readonly, ref, computed} from 'vue'
import {acceptHMRUpdate, defineStore} from 'pinia'
import {useI18n} from 'vue-i18n'
@ -28,24 +29,23 @@ export const useProjectStore = defineStore('project', () => {
const isLoading = ref(false)
// The projects are stored as an object which has the project ids as keys.
const projects = ref<ProjectState>({})
const projectsArray = computed(() => Object.values(projects.value))
const notArchivedRootProjects = computed(() => projectsArray.value
.filter(p => p.parentProjectId === 0 && !p.isArchived))
const favoriteProjects = computed(() => projectsArray.value
.filter(p => !p.isArchived && p.isFavorite))
const hasProjects = computed(() => projects.value ? true : false)
const projects = ref<Map<number, IProject>>(new Map<number, IProject>())
const notArchivedRootProjects = computed(() => new Map([...projects.value]
.filter(p => p.parentProjectId === 0 && !p.isArchived)))
const favoriteProjects = computed(() => new Map([...projects.value]
.filter(p => !p.isArchived && p.isFavorite)))
const hasProjects = computed(() => projects.value?.size > 0)
const getProjectById = computed(() => {
return (id: IProject['id']) => typeof projects.value[id] !== 'undefined' ? projects.value[id] : null
return (id: IProject['id']) => projects.value?.get(id) ?? null
})
const getChildProjects = computed(() => {
return (id: IProject['id']) => projectsArray.value.filter(p => p.parentProjectId === id) || []
return (id: IProject['id']) => projects.value.filter(p => p.parentProjectId === id) || []
})
const findProjectByExactname = computed(() => {
return (name: string) => {
const project = Object.values(projects.value).find(l => {
const project = projects.value.find(l => {
return l.title.toLowerCase() === name.toLowerCase()
})
return typeof project === 'undefined' ? null : project
@ -56,7 +56,7 @@ export const useProjectStore = defineStore('project', () => {
return (query: string, includeArchived = false) => {
return search(query)
?.filter(value => value > 0)
.map(id => projects.value[id])
.map(id => projects.value.get(id))
.filter(project => project.isArchived === includeArchived)
|| []
}
@ -67,7 +67,7 @@ export const useProjectStore = defineStore('project', () => {
}
function setProject(project: IProject) {
projects.value[project.id] = project
projects.value?.set(project.id, project)
update(project)
if (baseStore.currentProject?.id === project.id) {
@ -81,7 +81,7 @@ export const useProjectStore = defineStore('project', () => {
function removeProjectById(project: IProject) {
remove(project)
delete projects.value[project.id]
projects.value?.delete(project.id)
}
function toggleProjectFavorite(project: IProject) {
@ -152,7 +152,7 @@ export const useProjectStore = defineStore('project', () => {
const projectService = new ProjectService()
try {
const loadedProjects = await projectService.getAll({}, {is_archived: true}) as IProject[]
projects.value = {}
projects.value = new Map<number, IProject>()
setProjects(loadedProjects)
return loadedProjects
@ -166,7 +166,7 @@ export const useProjectStore = defineStore('project', () => {
return [project]
}
const parentProject = projects.value[project.parentProjectId]
const parentProject = projects.value?.get(project.parentProjectId)
return [
...getParentProjects(parentProject),
project,
@ -176,7 +176,6 @@ export const useProjectStore = defineStore('project', () => {
return {
isLoading: readonly(isLoading),
projects: readonly(projects),
projectsArray: readonly(projectsArray),
notArchivedRootProjects: readonly(notArchivedRootProjects),
favoriteProjects: readonly(favoriteProjects),
hasProjects: readonly(hasProjects),

View File

@ -70,6 +70,7 @@
</template>
<script setup lang="ts">
import 'core-js/modules/esnext.map.filter'
import {computed} from 'vue'
import {useI18n} from 'vue-i18n'
@ -91,7 +92,7 @@ const showArchived = useStorage('showArchived', false)
const loading = computed(() => projectStore.isLoading)
const projects = computed(() => {
return projectStore.projectsArray.filter(project => showArchived.value
return projectStore.projects.filter(project => showArchived.value
? true
: !project.isArchived,
)