Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Navigation side bar (#1904) #1914

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion hermes-console/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import AppNotificationProvider from '@/components/app-notification/AppNotificationProvider.vue';
import ConsoleFooter from '@/components/console-footer/ConsoleFooter.vue';
import ConsoleHeader from '@/components/console-header/ConsoleHeader.vue';
import NavigationDrawer from '@/components/navigation-drawer/NavigationDrawer.vue';

const configStore = useAppConfigStore();
configStore.loadConfig();
Expand All @@ -13,7 +14,7 @@
<v-app class="fill-height">
<div v-if="configStore.loadedConfig">
<console-header />

<navigation-drawer v-if="$route.name !== 'home'" />
<v-main class="main">
<app-notification-provider>
<router-view />
Expand Down
130 changes: 130 additions & 0 deletions hermes-console/src/components/navigation-drawer/NavigationDrawer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<script setup lang="ts">
import { isAdmin } from '@/utils/roles-util';
import { useAppConfigStore } from '@/store/app-config/useAppConfigStore';
import { useAuthStore } from '@/store/auth/useAuthStore';
import { useRoles } from '@/composables/roles/use-roles/useRoles';
import { useRoute } from 'vue-router';

import { computed, ref } from 'vue';
import NavigationItem from '@/components/navigation-drawer/NavigationItem.vue';
const authStore = useAuthStore();
const isLoggedIn = computed(() => authStore.isUserAuthorized);
const userData = computed(() => authStore.userData);
const route = useRoute();
const routeName = computed(() => route.name);

const configStore = useAppConfigStore();
const roles = useRoles(null, null)?.roles;
const rail = ref(false);
</script>

<template>
<v-navigation-drawer :rail="rail" permanent @click="rail = false">
<template v-if="!isLoggedIn">
<v-list>
<v-list-item
:prepend-avatar="`https://alleavatar.allegrogroup.com/${userData.user_name}.jpg`"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it is opensourced repository we can't hardcode such internal links. We should remove it or make it a configurable string, but the second option would require more changes also on the backend site of hermes-management.

Copy link
Contributor

@pitagoras3 pitagoras3 Nov 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Mateusz, could you remove this?

:title="isLoggedIn ? userData.full_name : 'Logged out'"
>
<template v-slot:append>
<v-btn
icon="mdi-chevron-left"
variant="text"
@click.stop="rail = !rail"
></v-btn>
</template>
</v-list-item>
</v-list>

<v-divider></v-divider>
</template>
<v-list density="compact" nav>
<navigation-item
icon="mdi-cog"
translation-key="homeView.links.console"
name="groups"
:current-route-name="routeName"
/>

<v-list-group value="Favorites">
<template v-slot:activator="{ props }">
<navigation-item
v-bind="props"
prepend-icon="mdi-star"
translation-key="homeView.links.favorites"
name="favorites"
:readonly="true"
/>
</template>

<navigation-item
translation-key="homeView.links.subscriptions"
name="favoriteSubscriptions"
:current-route-name="routeName"
/>
<navigation-item
translation-key="homeView.links.topics"
name="favoriteTopics"
:current-route-name="routeName"
/>
</v-list-group>
<navigation-item
icon="mdi-chart-bar"
translation-key="homeView.links.statistics"
name="stats"
:current-route-name="routeName"
/>
<navigation-item
icon="mdi-magnify"
translation-key="homeView.links.search"
name="search"
:current-route-name="routeName"
/>
<navigation-item
icon="mdi-chart-multiple"
translation-key="homeView.links.runtime"
name="runtime"
:external-url="configStore.loadedConfig.dashboard.metrics"
/>
<navigation-item
icon="mdi-book-open-variant"
translation-key="homeView.links.documentation"
name="docs"
:external-url="configStore.loadedConfig.dashboard.docs"
/>
<navigation-item
icon="mdi-currency-usd"
translation-key="homeView.links.costs"
name="costs"
:external-url="configStore.loadedConfig.costs.globalDetailsUrl"
/>
<v-list-group value="Admin" v-if="isAdmin(roles)">
<template v-slot:activator="{ props }">
<navigation-item
v-bind="props"
translation-key="homeView.links.adminTools"
name="adminTools"
icon="mdi-security"
:readonly="true"
/>
</template>

<navigation-item
translation-key="homeView.links.readiness"
name="readiness"
:current-route-name="routeName"
/>
<navigation-item
translation-key="homeView.links.constraints"
name="constraints"
:current-route-name="routeName"
/>
<navigation-item
translation-key="homeView.links.consistency"
name="consistency"
:current-route-name="routeName"
/>
</v-list-group>
</v-list>
</v-navigation-drawer>
</template>
42 changes: 42 additions & 0 deletions hermes-console/src/components/navigation-drawer/NavigationItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<script setup lang="ts">
import { defineProps } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();

const props = defineProps<{
icon?: string;
translationKey: string;
name: string;
currentRouteName?: string;
readonly?: boolean;
externalUrl?: string;
}>();

function navigateToRoute() {
if (props.readonly || props.externalUrl) {
return;
}
router.push({ name: props.name });
}
</script>

<template>
<v-list-item
:prepend-icon="icon"
:title="!externalUrl ? $t(translationKey) : ''"
:active="currentRouteName === name"
:value="name"
@click="navigateToRoute"
>
<a v-if="externalUrl" :href="externalUrl" target="_blank">
<v-list-item-title>{{ $t(translationKey) }}</v-list-item-title>
</a>
</v-list-item>
</template>

<style scoped lang="scss">
a {
text-decoration: none;
color: inherit;
}
</style>
6 changes: 6 additions & 0 deletions hermes-console/src/i18n/en-US/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@ const en_US = {
console: 'Console',
favoriteTopics: 'Favorite topics',
favoriteSubscriptions: 'Favorite subs',
topics: 'Topics',
subscriptions: 'Subscriptions',
runtime: 'Runtime',
statistics: 'Stats',
search: 'Search',
documentation: 'Docs',
costs: 'Costs',
adminTools: 'Admin tools',
favorites: 'Favorites',
readiness: 'Readiness',
constraints: 'Constraints',
consistency: 'Consistency',
},
},
header: {
Expand Down
10 changes: 8 additions & 2 deletions hermes-console/src/store/auth/useAuthStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,14 @@ export const useAuthStore = defineStore('auth', {
},
},
getters: {
userData(state: AuthStoreState): { exp: number } {
return state.accessToken ? jwtDecode(state.accessToken) : { exp: 0 };
userData(state: AuthStoreState): {
exp: number;
full_name: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Here, we implicitly expect that JWT contains full_name and user_name in the token.

This may not be true for our Open Source users. I would suggest to simplify the sidebar, by removing info about logged in user.

user_name: string;
} {
return state.accessToken
? jwtDecode(state.accessToken)
: { exp: 0, full_name: '', user_name: '' };
},
isUserAuthorized(state: AuthStoreState): boolean {
const expiresAt = this.userData.exp * 1000;
Expand Down
Loading