feat(navigation): make dragging a project to a parent work

This commit is contained in:
kolaente 2023-03-27 13:21:47 +02:00
parent 2cd8861e9b
commit 713edd4dfb
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
5 changed files with 21 additions and 11 deletions

View File

@ -5,7 +5,6 @@
<!-- @update:modelValue="(projects) => updateActiveProjects(n, projects)"--> <!-- @update:modelValue="(projects) => updateActiveProjects(n, projects)"-->
<!-- v-for="(p, pk) in projects"--> <!-- v-for="(p, pk) in projects"-->
<!-- :key="p.id"--> <!-- :key="p.id"-->
<!-- :data-project-id="p.id"-->
<!-- :data-project-index="pk"--> <!-- :data-project-index="pk"-->
<draggable <draggable
v-model="availableProjects" v-model="availableProjects"
@ -29,6 +28,7 @@
<li <li
class="list-menu loader-container is-loading-small" class="list-menu loader-container is-loading-small"
:class="{'is-loading': projectUpdating[p.id]}" :class="{'is-loading': projectUpdating[p.id]}"
:data-project-id="p.id"
> >
<section> <section>
<BaseButton <BaseButton
@ -73,7 +73,7 @@
</section> </section>
<ProjectsNavigation <ProjectsNavigation
v-if="p.childProjects.length > 0 && !collapsedProjects[p.id]" v-if="p.childProjects.length > 0 && !collapsedProjects[p.id]"
:projects="p.childProjects" v-model="p.childProjects"
/> />
</li> </li>
</template> </template>
@ -98,8 +98,10 @@ import {useBaseStore} from '@/stores/base'
import {useProjectStore} from '@/stores/projects' import {useProjectStore} from '@/stores/projects'
const props = defineProps<{ const props = defineProps<{
projects: IProject[], modelValue: IProject[],
}>() }>()
const emit = defineEmits(['update:modelValue'])
const drag = ref(false) const drag = ref(false)
const dragOptions = { const dragOptions = {
animation: 100, animation: 100,
@ -117,7 +119,7 @@ const currentProject = computed(() => baseStore.currentProject)
const collapsedProjects = ref<{ [id: IProject['id']]: boolean }>({}) const collapsedProjects = ref<{ [id: IProject['id']]: boolean }>({})
const availableProjects = ref<IProject[]>([]) const availableProjects = ref<IProject[]>([])
watch( watch(
() => props.projects, () => props.modelValue,
projects => { projects => {
availableProjects.value = projects availableProjects.value = projects
projects.forEach(p => collapsedProjects.value[p.id] = false) projects.forEach(p => collapsedProjects.value[p.id] = false)
@ -136,7 +138,10 @@ async function saveProjectPosition(e: SortableEvent) {
// To work around that we're explicitly checking that case here and decrease the index. // 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.length ? e.newIndex - 1 : e.newIndex
const project = projectsActive[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 projectBefore = projectsActive[newIndex - 1] ?? null
const projectAfter = projectsActive[newIndex + 1] ?? null const projectAfter = projectsActive[newIndex + 1] ?? null
projectUpdating.value[project.id] = true projectUpdating.value[project.id] = true
@ -159,7 +164,9 @@ async function saveProjectPosition(e: SortableEvent) {
await projectStore.updateProject({ await projectStore.updateProject({
...project, ...project,
position, position,
parentProjectId,
}) })
emit('update:modelValue', availableProjects.value)
} finally { } finally {
projectUpdating.value[project.id] = false projectUpdating.value[project.id] = false
} }

View File

@ -49,7 +49,7 @@
</nav> </nav>
<nav class="menu namespaces-lists"> <nav class="menu namespaces-lists">
<ProjectsNavigation :projects="projects"/> <ProjectsNavigation v-model="projects"/>
</nav> </nav>
<!-- <nav class="menu namespaces-lists loader-container is-loading-small" :class="{'is-loading': loading}">--> <!-- <nav class="menu namespaces-lists loader-container is-loading-small" :class="{'is-loading': loading}">-->
@ -146,7 +146,9 @@ onBeforeMount(async () => {
await projectStore.loadProjects() await projectStore.loadProjects()
}) })
const projects = computed(() => Object.values(projectStore.projects).sort((a, b) => a.position < b.position ? -1 : 1)) const projects = computed(() => Object.values(projectStore.projects)
.filter(p => p.parentProjectId === 0)
.sort((a, b) => a.position < b.position ? -1 : 1))
function updateActiveProjects(namespace: INamespace, activeProjects: IProject[]) { function updateActiveProjects(namespace: INamespace, activeProjects: IProject[]) {
// This is a bit hacky: since we do have to filter out the archived items from the list // This is a bit hacky: since we do have to filter out the archived items from the list

View File

@ -19,6 +19,7 @@ export interface IProject extends IAbstract {
position: number position: number
backgroundBlurHash: string backgroundBlurHash: string
childProjects: IProject[] | null childProjects: IProject[] | null
parentProjectId: number
created: Date created: Date
updated: Date updated: Date

View File

@ -23,6 +23,7 @@ export default class ProjectModel extends AbstractModel<IProject> implements IPr
position = 0 position = 0
backgroundBlurHash = '' backgroundBlurHash = ''
childProjects = [] childProjects = []
parentProjectId = 0
created: Date = null created: Date = null
updated: Date = null updated: Date = null

View File

@ -62,6 +62,8 @@ export const useProjectStore = defineStore('project', () => {
function setProject(project: IProject) { function setProject(project: IProject) {
projects.value[project.id] = project projects.value[project.id] = project
update(project) update(project)
project.childProjects?.forEach(setProject)
if (baseStore.currentProject?.id === project.id) { if (baseStore.currentProject?.id === project.id) {
baseStore.setCurrentProject(project) baseStore.setCurrentProject(project)
@ -69,10 +71,7 @@ export const useProjectStore = defineStore('project', () => {
} }
function setProjects(newProjects: IProject[]) { function setProjects(newProjects: IProject[]) {
newProjects.forEach(l => { newProjects.forEach(setProject)
projects.value[l.id] = l
add(l)
})
} }
function removeProjectById(project: IProject) { function removeProjectById(project: IProject) {