chore: cleanup namespace leftovers
This commit is contained in:
parent
749dcdcd70
commit
2e336150e0
@ -1,15 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- v-if="projectsVisible[n.id] ?? true"-->
|
|
||||||
<!-- :disabled="n.id < 0 || undefined"-->
|
|
||||||
<!-- :modelValue="p"-->
|
|
||||||
<!-- @update:modelValue="(projects) => updateActiveProjects(n, projects)"-->
|
|
||||||
<!-- v-for="(p, pk) in projects"-->
|
|
||||||
<!-- :key="p.id"-->
|
|
||||||
<!-- :data-project-index="pk"-->
|
|
||||||
<draggable
|
<draggable
|
||||||
v-model="availableProjects"
|
v-model="availableProjects"
|
||||||
v-bind="dragOptions"
|
v-bind="dragOptions"
|
||||||
group="namespace-lists"
|
group="projects"
|
||||||
@start="() => drag = true"
|
@start="() => drag = true"
|
||||||
@end="saveProjectPosition"
|
@end="saveProjectPosition"
|
||||||
handle=".handle"
|
handle=".handle"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<aside :class="{'is-active': menuActive}" class="namespace-container">
|
<aside :class="{'is-active': menuActive}" class="menu-container">
|
||||||
<nav class="menu top-menu">
|
<nav class="menu top-menu">
|
||||||
<router-link :to="{name: 'home'}" class="logo">
|
<router-link :to="{name: 'home'}" class="logo">
|
||||||
<Logo width="164" height="48"/>
|
<Logo width="164" height="48"/>
|
||||||
@ -48,99 +48,28 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<nav class="menu namespaces-lists">
|
<nav class="menu">
|
||||||
<ProjectsNavigation v-model="projects"/>
|
<ProjectsNavigation v-model="projects"/>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- <nav class="menu namespaces-lists loader-container is-loading-small" :class="{'is-loading': loading}">-->
|
|
||||||
<!-- <template v-for="(n, nk) in namespaces" :key="n.id">-->
|
|
||||||
<!-- <div class="namespace-title" :class="{'has-menu': n.id > 0}">-->
|
|
||||||
<!-- <BaseButton-->
|
|
||||||
<!-- @click="toggleProjects(n.id)"-->
|
|
||||||
<!-- class="menu-label"-->
|
|
||||||
<!-- v-tooltip="namespaceTitles[nk]"-->
|
|
||||||
<!-- >-->
|
|
||||||
<!-- <ColorBubble-->
|
|
||||||
<!-- v-if="n.hexColor !== ''"-->
|
|
||||||
<!-- :color="n.hexColor"-->
|
|
||||||
<!-- class="mr-1"-->
|
|
||||||
<!-- />-->
|
|
||||||
<!-- <span class="name">{{ namespaceTitles[nk] }}</span>-->
|
|
||||||
<!-- <div-->
|
|
||||||
<!-- class="icon menu-item-icon is-small toggle-lists-icon pl-2"-->
|
|
||||||
<!-- :class="{'active': typeof projectsVisible[n.id] !== 'undefined' ? projectsVisible[n.id] : true}"-->
|
|
||||||
<!-- >-->
|
|
||||||
<!-- <icon icon="chevron-down"/>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <span class="count" :class="{'ml-2 mr-0': n.id > 0}">-->
|
|
||||||
<!-- ({{ namespaceProjectsCount[nk] }})-->
|
|
||||||
<!-- </span>-->
|
|
||||||
<!-- </BaseButton>-->
|
|
||||||
<!-- <namespace-settings-dropdown class="menu-list-dropdown" :namespace="n" v-if="n.id > 0"/>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <!–-->
|
|
||||||
<!-- NOTE: a v-model / computed setter is not possible, since the updateActiveProjects function-->
|
|
||||||
<!-- triggered by the change needs to have access to the current namespace-->
|
|
||||||
<!-- –>-->
|
|
||||||
|
|
||||||
<!-- </template>-->
|
|
||||||
<!-- </nav>-->
|
|
||||||
<PoweredByLink/>
|
<PoweredByLink/>
|
||||||
</aside>
|
</aside>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, computed, onBeforeMount} from 'vue'
|
import {computed, onBeforeMount} from 'vue'
|
||||||
import draggable from 'zhyswan-vuedraggable'
|
|
||||||
import type {SortableEvent} from 'sortablejs'
|
|
||||||
|
|
||||||
import BaseButton from '@/components/base/BaseButton.vue'
|
|
||||||
import ProjectSettingsDropdown from '@/components/project/project-settings-dropdown.vue'
|
|
||||||
import PoweredByLink from '@/components/home/PoweredByLink.vue'
|
import PoweredByLink from '@/components/home/PoweredByLink.vue'
|
||||||
import Logo from '@/components/home/Logo.vue'
|
import Logo from '@/components/home/Logo.vue'
|
||||||
|
|
||||||
import {calculateItemPosition} from '@/helpers/calculateItemPosition'
|
|
||||||
import {getProjectTitle} from '@/helpers/getProjectTitle'
|
|
||||||
import type {IProject} from '@/modelTypes/IProject'
|
|
||||||
import type {INamespace} from '@/modelTypes/INamespace'
|
|
||||||
import ColorBubble from '@/components/misc/colorBubble.vue'
|
|
||||||
|
|
||||||
import {useBaseStore} from '@/stores/base'
|
import {useBaseStore} from '@/stores/base'
|
||||||
import {useProjectStore} from '@/stores/projects'
|
import {useProjectStore} from '@/stores/projects'
|
||||||
import ProjectsNavigation from '@/components/home/ProjectsNavigation.vue'
|
import ProjectsNavigation from '@/components/home/ProjectsNavigation.vue'
|
||||||
|
|
||||||
|
|
||||||
const baseStore = useBaseStore()
|
const baseStore = useBaseStore()
|
||||||
const menuActive = computed(() => baseStore.menuActive)
|
|
||||||
const loading = computed(() => namespaceStore.isLoading)
|
|
||||||
|
|
||||||
|
|
||||||
const namespaces = computed(() => {
|
|
||||||
return namespaceStore.namespaces.filter(n => !n.isArchived)
|
|
||||||
})
|
|
||||||
const activeProjects = computed(() => {
|
|
||||||
return namespaces.value.map(({projects}) => {
|
|
||||||
return projects?.filter(item => {
|
|
||||||
return typeof item !== 'undefined' && !item.isArchived
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const namespaceTitles = computed(() => {
|
|
||||||
return []
|
|
||||||
})
|
|
||||||
|
|
||||||
const namespaceProjectsCount = computed(() => {
|
|
||||||
return namespaces.value.map((_, index) => activeProjects.value[index]?.length ?? 0)
|
|
||||||
})
|
|
||||||
|
|
||||||
const projectStore = useProjectStore()
|
const projectStore = useProjectStore()
|
||||||
|
const menuActive = computed(() => baseStore.menuActive)
|
||||||
|
|
||||||
function toggleProjects(namespaceId: INamespace['id']) {
|
|
||||||
projectsVisible.value[namespaceId] = !projectsVisible.value[namespaceId]
|
|
||||||
}
|
|
||||||
|
|
||||||
const projectsVisible = ref<{ [id: INamespace['id']]: boolean }>({})
|
|
||||||
// FIXME: async action will be unfinished when component mounts
|
// FIXME: async action will be unfinished when component mounts
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
await projectStore.loadProjects()
|
await projectStore.loadProjects()
|
||||||
@ -149,25 +78,6 @@ onBeforeMount(async () => {
|
|||||||
const projects = computed(() => Object.values(projectStore.projects)
|
const projects = computed(() => Object.values(projectStore.projects)
|
||||||
.filter(p => p.parentProjectId === 0)
|
.filter(p => p.parentProjectId === 0)
|
||||||
.sort((a, b) => a.position < b.position ? -1 : 1))
|
.sort((a, b) => a.position < b.position ? -1 : 1))
|
||||||
|
|
||||||
function updateActiveProjects(namespace: INamespace, activeProjects: IProject[]) {
|
|
||||||
// This is a bit hacky: since we do have to filter out the archived items from the list
|
|
||||||
// for vue draggable updating it is not as simple as replacing it.
|
|
||||||
// To work around this, we merge the active projects with the archived ones. Doing so breaks the order
|
|
||||||
// because now all archived projects are sorted after the active ones. This is fine because they are sorted
|
|
||||||
// later when showing them anyway, and it makes the merging happening here a lot easier.
|
|
||||||
const projects = [
|
|
||||||
...activeProjects,
|
|
||||||
...namespace.projects.filter(l => l.isArchived),
|
|
||||||
]
|
|
||||||
|
|
||||||
namespaceStore.setNamespaceById({
|
|
||||||
...namespace,
|
|
||||||
projects,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -183,7 +93,7 @@ function updateActiveProjects(namespace: INamespace, activeProjects: IProject[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.namespace-container {
|
.menu-container {
|
||||||
background: var(--site-background);
|
background: var(--site-background);
|
||||||
color: $vikunja-nav-color;
|
color: $vikunja-nav-color;
|
||||||
padding: 0 0 1rem;
|
padding: 0 0 1rem;
|
||||||
@ -229,76 +139,7 @@ function updateActiveProjects(namespace: INamespace, activeProjects: IProject[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.namespaces-lists {
|
.menu {
|
||||||
padding-top: math.div($navbar-padding, 2);
|
padding-top: math.div($navbar-padding, 2);
|
||||||
|
|
||||||
.menu-label {
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: 700;
|
|
||||||
font-weight: bold;
|
|
||||||
font-family: $vikunja-font;
|
|
||||||
color: $vikunja-nav-color;
|
|
||||||
font-weight: 600;
|
|
||||||
min-height: 2.5rem;
|
|
||||||
padding-top: 0;
|
|
||||||
padding-left: $navbar-padding;
|
|
||||||
|
|
||||||
overflow: hidden;
|
|
||||||
margin-bottom: 0;
|
|
||||||
flex: 1 1 auto;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.count {
|
|
||||||
color: var(--grey-500);
|
|
||||||
margin-right: .5rem;
|
|
||||||
// align brackets with number
|
|
||||||
font-feature-settings: "case";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.favorite {
|
|
||||||
margin-left: .25rem;
|
|
||||||
transition: opacity $transition, color $transition;
|
|
||||||
opacity: 1;
|
|
||||||
|
|
||||||
&.is-favorite {
|
|
||||||
color: var(--warning);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@media(hover: hover) and (pointer: fine) {
|
|
||||||
.list-menu .favorite {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-menu:hover .favorite,
|
|
||||||
.favorite.is-favorite {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-menu-title {
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.color-bubble {
|
|
||||||
width: 14px;
|
|
||||||
height: 14px;
|
|
||||||
flex-basis: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.is-archived {
|
|
||||||
min-width: 85px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -17,8 +17,6 @@ import {useBaseStore} from '@/stores/base'
|
|||||||
|
|
||||||
const {add, remove, search, update} = createNewIndexer('projects', ['title', 'description'])
|
const {add, remove, search, update} = createNewIndexer('projects', ['title', 'description'])
|
||||||
|
|
||||||
const FavoriteProjectsNamespace = -2
|
|
||||||
|
|
||||||
export interface ProjectState {
|
export interface ProjectState {
|
||||||
[id: IProject['id']]: IProject
|
[id: IProject['id']]: IProject
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user