wip: use map instead of object to store projects
This commit is contained in:
parent
d694f168b2
commit
634af32400
|
@ -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",
|
||||
|
|
|
@ -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==}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
Reference in New Issue