|
|
|
@ -57,14 +57,14 @@
|
|
|
|
|
v-tooltip="namespaceTitles[nk]"
|
|
|
|
|
>
|
|
|
|
|
<ColorBubble
|
|
|
|
|
v-if="n.hexColor !== ''"
|
|
|
|
|
:color="n.hexColor"
|
|
|
|
|
class="mr-1"
|
|
|
|
|
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-projects-icon pl-2"
|
|
|
|
|
:class="{'active': typeof projectsVisible[n.id] !== 'undefined' ? projectsVisible[n.id] : true}"
|
|
|
|
|
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>
|
|
|
|
@ -74,18 +74,18 @@
|
|
|
|
|
</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
|
|
|
|
|
-->
|
|
|
|
|
<draggable
|
|
|
|
|
<!--
|
|
|
|
|
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
|
|
|
|
|
-->
|
|
|
|
|
<draggable
|
|
|
|
|
v-if="projectsVisible[n.id] ?? true"
|
|
|
|
|
v-bind="dragOptions"
|
|
|
|
|
:modelValue="activeProjects[nk]"
|
|
|
|
|
@update:modelValue="(projects) => updateActiveProjects(n, projects)"
|
|
|
|
|
group="namespace-projects"
|
|
|
|
|
group="namespace-lists"
|
|
|
|
|
@start="() => drag = true"
|
|
|
|
|
@end="saveProjectPosition"
|
|
|
|
|
@end="saveListPosition"
|
|
|
|
|
handle=".handle"
|
|
|
|
|
:disabled="n.id < 0 || undefined"
|
|
|
|
|
tag="ul"
|
|
|
|
@ -100,45 +100,45 @@
|
|
|
|
|
{ 'dragging-disabled': n.id < 0 }
|
|
|
|
|
]
|
|
|
|
|
}"
|
|
|
|
|
>
|
|
|
|
|
<template #item="{element: l}">
|
|
|
|
|
<li
|
|
|
|
|
class="project-menu loader-container is-loading-small"
|
|
|
|
|
>
|
|
|
|
|
<template #item="{element: l}">
|
|
|
|
|
<li
|
|
|
|
|
class="list-menu loader-container is-loading-small"
|
|
|
|
|
:class="{'is-loading': projectUpdating[l.id]}"
|
|
|
|
|
>
|
|
|
|
|
<BaseButton
|
|
|
|
|
>
|
|
|
|
|
<BaseButton
|
|
|
|
|
:to="{ name: 'project.index', params: { projectId: l.id} }"
|
|
|
|
|
class="project-menu-link"
|
|
|
|
|
class="list-menu-link"
|
|
|
|
|
:class="{'router-link-exact-active': currentProject.id === l.id}"
|
|
|
|
|
>
|
|
|
|
|
>
|
|
|
|
|
<span class="icon menu-item-icon handle">
|
|
|
|
|
<icon icon="grip-lines"/>
|
|
|
|
|
</span>
|
|
|
|
|
<ColorBubble
|
|
|
|
|
<ColorBubble
|
|
|
|
|
v-if="l.hexColor !== ''"
|
|
|
|
|
:color="l.hexColor"
|
|
|
|
|
class="mr-1"
|
|
|
|
|
/>
|
|
|
|
|
<span class="project-menu-title">{{ getProjectTitle(l) }}</span>
|
|
|
|
|
</BaseButton>
|
|
|
|
|
<BaseButton
|
|
|
|
|
/>
|
|
|
|
|
<span class="list-menu-title">{{ getProjectTitle(l) }}</span>
|
|
|
|
|
</BaseButton>
|
|
|
|
|
<BaseButton
|
|
|
|
|
class="favorite"
|
|
|
|
|
:class="{'is-favorite': l.isFavorite}"
|
|
|
|
|
@click="projectStore.toggleProjectFavorite(l)"
|
|
|
|
|
>
|
|
|
|
|
<icon :icon="l.isFavorite ? 'star' : ['far', 'star']"/>
|
|
|
|
|
</BaseButton>
|
|
|
|
|
<project-settings-dropdown class="menu-list-dropdown" :project="l" v-if="l.id > 0">
|
|
|
|
|
<template #trigger="{toggleOpen}">
|
|
|
|
|
<BaseButton class="menu-list-dropdown-trigger" @click="toggleOpen">
|
|
|
|
|
<icon icon="ellipsis-h" class="icon"/>
|
|
|
|
|
</BaseButton>
|
|
|
|
|
</template>
|
|
|
|
|
</project-settings-dropdown>
|
|
|
|
|
<span class="project-setting-spacer" v-else></span>
|
|
|
|
|
</li>
|
|
|
|
|
</template>
|
|
|
|
|
</draggable>
|
|
|
|
|
>
|
|
|
|
|
<icon :icon="l.isFavorite ? 'star' : ['far', 'star']"/>
|
|
|
|
|
</BaseButton>
|
|
|
|
|
<list-settings-dropdown class="menu-list-dropdown" :list="l" v-if="l.id > 0">
|
|
|
|
|
<template #trigger="{toggleOpen}">
|
|
|
|
|
<BaseButton class="menu-list-dropdown-trigger" @click="toggleOpen">
|
|
|
|
|
<icon icon="ellipsis-h" class="icon"/>
|
|
|
|
|
</BaseButton>
|
|
|
|
|
</template>
|
|
|
|
|
</list-settings-dropdown>
|
|
|
|
|
<span class="list-setting-spacer" v-else></span>
|
|
|
|
|
</li>
|
|
|
|
|
</template>
|
|
|
|
|
</draggable>
|
|
|
|
|
</template>
|
|
|
|
|
</nav>
|
|
|
|
|
<PoweredByLink/>
|
|
|
|
@ -227,7 +227,7 @@ onBeforeMount(async () => {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
function updateActiveProjects(namespace: INamespace, activeProjects: IProject[]) {
|
|
|
|
|
// This is a bit hacky: since we do have to filter out the archived items from the project
|
|
|
|
|
// 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
|
|
|
|
@ -245,7 +245,7 @@ function updateActiveProjects(namespace: INamespace, activeProjects: IProject[])
|
|
|
|
|
|
|
|
|
|
const projectUpdating = ref<{ [id: INamespace['id']]: boolean }>({})
|
|
|
|
|
|
|
|
|
|
async function saveProjectPosition(e: SortableEvent) {
|
|
|
|
|
async function saveListPosition(e: SortableEvent) {
|
|
|
|
|
if (!e.newIndex && e.newIndex !== 0) return
|
|
|
|
|
|
|
|
|
|
const namespaceId = parseInt(e.to.dataset.namespaceId as string)
|
|
|
|
@ -327,7 +327,7 @@ $vikunja-nav-selected-width: 0.4rem;
|
|
|
|
|
// should be in own components
|
|
|
|
|
.menu {
|
|
|
|
|
.menu-label,
|
|
|
|
|
.menu-list .project-menu-link,
|
|
|
|
|
.menu-list .list-menu-link,
|
|
|
|
|
.menu-list a {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
@ -385,7 +385,7 @@ $vikunja-nav-selected-width: 0.4rem;
|
|
|
|
|
background: transparent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.project-menu-link,
|
|
|
|
|
.list-menu-link,
|
|
|
|
|
li > a {
|
|
|
|
|
color: $vikunja-nav-color;
|
|
|
|
|
padding: 0.75rem .5rem 0.75rem ($navbar-padding * 1.5 - 1.75rem);
|
|
|
|
@ -432,14 +432,14 @@ $vikunja-nav-selected-width: 0.4rem;
|
|
|
|
|
|
|
|
|
|
.top-menu {
|
|
|
|
|
margin-top: math.div($navbar-padding, 2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.menu-list {
|
|
|
|
|
li {
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
font-family: $vikunja-font;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.project-menu-link,
|
|
|
|
|
.list-menu-link,
|
|
|
|
|
li > a {
|
|
|
|
|
padding-left: 2rem;
|
|
|
|
|
display: inline-block;
|
|
|
|
@ -500,7 +500,7 @@ $vikunja-nav-selected-width: 0.4rem;
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.project-menu-title {
|
|
|
|
|
.list-menu-title {
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
width: 100%;
|
|
|
|
@ -546,12 +546,12 @@ $vikunja-nav-selected-width: 0.4rem;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.project-setting-spacer {
|
|
|
|
|
.list-setting-spacer {
|
|
|
|
|
width: 2.5rem;
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.namespaces-project.loader-container.is-loading {
|
|
|
|
|
.namespaces-list.loader-container.is-loading {
|
|
|
|
|
min-height: calc(100vh - #{$navbar-height + 1.5rem + 1rem + 1.5rem});
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|