Code owners
Assign users and groups as approvers for specific file changes. Learn more.
SidebarMenu.vue 9.64 KiB
<template>
<sidebar-menu
:menu="menu"
:collapsed="collapsed"
:relative="true"
:show-one-child="true"
:disable-hover="false"
theme="white-theme"
@toggle-collapse="collapse"
>
<template #toggle-icon>
<b-icon v-if="!collapsed" icon="arrow-bar-left" />
<b-icon v-else icon="arrow-bar-right" />
</template>
<template #dropdown-icon>
<b-icon icon="caret-right" />
</template>
</sidebar-menu>
</template>
<script lang="ts">
import Vue from "vue";
import { defineComponent } from "vue-demi";
import "bootstrap-icons/font/bootstrap-icons.css";
import "bootstrap-icons/font/fonts/bootstrap-icons.woff";
import "bootstrap-icons/font/fonts/bootstrap-icons.woff2";
// import the main store
import useMainStore from "@/store/index";
// import the project store
import useProjectStore from "@/modules/project/store";
// import the resource store
import useResourceStore from "@/modules/resource/store";
import type {
ProjectObject,
ResourceObject,
RoleObject,
} from "@coscine/api-client/dist/types/Coscine.Api.Project";
import VueSidebarMenu from "vue-sidebar-menu";
import "vue-sidebar-menu/dist/vue-sidebar-menu.css";
import type {
SidebarItem,
SidebarComponentItem,
SidebarHeaderItem,
} from "vue-sidebar-menu";
Vue.use(VueSidebarMenu);
// TODO: Waiting for role implementation (is owner for showing e.g. settings)
export default defineComponent({
setup() {
const mainStore = useMainStore();
const projectStore = useProjectStore();
const resourceStore = useResourceStore();
return { mainStore, projectStore, resourceStore };
},
data() {
return {
collapsed: false,
};
},
computed: {
currentUserRole(): RoleObject | undefined | null {
return this.projectStore.currentUserRole;
},
menu(): Array<SidebarItem | SidebarComponentItem | SidebarHeaderItem> {
return [
{
href: "/",
title: this.$t("sidebar.home").toString(),
icon: "bi bi-house",
},
...this.projectsMenu,
...this.projectMenu,
...this.resourcesMenu,
...this.subProjectsMenu,
...this.settingsMenu,
];
},
project(): ProjectObject | null {
return this.projectStore.currentProject;
},
projects(): ProjectObject[] | null {
return this.projectStore.topLevelProjects;
},
projectMenu(): Array<SidebarItem> {
if (this.project && this.project.slug) {
return [
{
href: {
name: "project-page",
params: { slug: this.project.slug },
},
title:
this.$tc("sidebar.project", 1).toString() +
": " +
this.project.displayName,
icon: "bi bi-folder-symlink",
attributes: {
title:
this.$tc("sidebar.project", 1).toString() +
": " +
this.project.displayName,
},
},
];
}
return [];
},
projectsMenu(): Array<SidebarItem> {
if (this.projects && this.projects.length && !this.project) {
return [
{
title: this.$tc("sidebar.project", 2).toString(),
href: "",
icon: "bi bi-folder2-open",
child: this.projects.map((project) => {
return {
title: project.displayName,
href: {
name: "project-page",
params: { slug: project.slug },
},
icon: "bi bi-folder2-open",
};
}) as Array<SidebarItem>,
},
];
}
return [];
},
resources(): ResourceObject[] | null {
return this.projectStore.currentResources;
},
resourcesMenu(): Array<SidebarItem> {
if (
this.resources &&
this.resources.length &&
this.project &&
this.project.slug
) {
return [
{
title: this.$tc("sidebar.resource", 2).toString(),
href: "",
icon: "bi bi-archive",
child: this.resources.map((resource) => {
return {
title:
(resource.type
? `${this.$t(
"resourceTypes." +
resource.type.displayName +
".displayName"
)}: `
: "") + resource.displayName,
href: {
name: "resource-page",
params: {
slug: this.project ? this.project.slug : undefined,
guid: resource.id,
},
},
icon: "bi bi-archive",
attributes: {
title:
(resource.type
? `${this.$t(
"resourceTypes." +
resource.type.displayName +
".displayName"
)}: `
: "") + resource.displayName,
},
badge: resource.archived
? {
text: this.$t("default.archived").toString(),
class: "vsm--badge_default",
}
: undefined,
exactPath: true,
};
}) as Array<SidebarItem>,
},
];
}
return [];
},
settingsMenu(): Array<SidebarItem> {
if (
this.project &&
this.project.slug &&
this.currentUserRole &&
this.currentUserRole.displayName === "Owner"
) {
return [
{
title: this.$t("sidebar.settings").toString(),
href: "",
icon: "bi bi-gear",
child: [
{
title: this.$t("sidebar.projectSettings").toString(),
href: {
name: "project-settings",
params: { slug: this.project.slug },
},
icon: "bi bi-pencil",
},
{
title: this.$t("sidebar.manageUsers").toString(),
href: {
name: "project-members",
params: { slug: this.project.slug },
},
icon: "bi bi-people",
},
{
title: this.$t("sidebar.manageQuota").toString(),
href: {
name: "project-quota",
params: { slug: this.project.slug },
},
icon: "bi bi-sliders",
},
],
},
];
}
return [];
},
sidebarActive(): boolean {
return this.mainStore.sidebarActive;
},
subProjects(): ProjectObject[] | null {
return this.projectStore.currentSubProjects;
},
subProjectsMenu(): Array<SidebarItem> {
if (this.subProjects && this.subProjects.length) {
return [
{
title: this.$tc("sidebar.subProject", 2).toString(),
href: "",
icon: "bi bi-folder2-open",
child: this.subProjects.map((project) => {
return {
title: project.displayName,
href: {
name: "project-page",
params: { slug: project.slug },
},
icon: "bi bi-folder2-open",
attributes: {
title:
this.$tc("sidebar.subProject", 2).toString() +
": " +
project.displayName,
},
};
}) as Array<SidebarItem>,
},
];
}
return [];
},
},
watch: {
collapsed() {
this.mainStore.sidebarActive = !this.collapsed;
},
sidebarActive() {
this.collapsed = !this.sidebarActive;
},
},
created() {
this.collapsed = !this.sidebarActive;
},
methods: {
collapse(collapsed: boolean) {
this.collapsed = collapsed;
},
},
});
</script>
<style lang="scss" scoped>
@import "/src/assets/scss/_custom.scss";
.v-sidebar-menu {
height: var(--sidebar-height);
border-radius: 0rem 0.25rem 0.25rem 0rem;
background: $light;
}
.v-sidebar-menu ::v-deep .vsm--toggle-btn {
border-radius: 0rem 0rem 0.25rem 0rem;
background-color: var(--secondary);
}
.v-sidebar-menu.vsm_expanded {
overflow-y: auto;
overflow-x: hidden;
}
.v-sidebar-menu ::v-deep .vsm--badge {
background-color: #ffc107;
border-radius: 10rem;
text-transform: capitalize;
font-weight: bold;
}
.v-sidebar-menu ::v-deep .vsm--title {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.v-sidebar-menu.vsm_expanded ::v-deep .vsm--item_open .vsm--link_level-1 {
background: $primary;
}
.v-sidebar-menu.vsm_expanded
::v-deep
.vsm--item_open
.vsm--link_level-1
.vsm--icon {
background: $primary;
}
.v-sidebar-menu.vsm_collapsed ::v-deep .vsm--mobile-item .vsm--item_open {
background-color: $primary;
}
.v-sidebar-menu.vsm_collapsed ::v-deep .vsm--mobile-item .vsm--mobile-bg {
background-color: $primary;
}
.v-sidebar-menu.vsm_collapsed
::v-deep
.vsm--link_level-1.vsm--link_hover
.vsm--icon {
background-color: $primary;
}
.v-sidebar-menu.vsm_white-theme
::v-deep
.vsm--link_level-1.vsm--link_exact-active,
.v-sidebar-menu ::v-deep .vsm--link_level-1.vsm--link_active {
box-shadow: 3px 0px 0px 0px $primary inset;
-webkit-box-shadow: 3px 0px 0px 0px $primary inset;
}
.v-sidebar-menu ::v-deep .vsm--link_level-2.vsm--link_active {
// Use this to edit the second level element when active
background-color: var(--primary);
color: $white;
}
</style>