Skip to content

Commit

Permalink
feat: Improve Top and Left Menu Tree View - MEED-7436 - Meeds-io/meed…
Browse files Browse the repository at this point in the history
…s#2371 (#4008)

This change will make the first level of Sites Tree displayed as same
level as the root node when the only root navigation to enhance UX.
  • Loading branch information
boubaker authored and exo-swf committed Sep 10, 2024
1 parent 8802f33 commit 7e1a419
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,13 @@
</v-list-item-action>
</v-flex>
<v-flex>
<v-list>
<v-list v-if="spaceNavigations">
<site-navigation-tree
:navigations="spaceNavigations"
:site-name="spaceGroupId"
:space-unread-items="spaceUnreadItems" />
:space-unread-items="spaceUnreadItems"
:selected-name="selectedNavigationName"
collapsed />
</v-list>
</v-flex>
</v-container>
Expand All @@ -171,9 +173,10 @@ export default {
},
},
data: () => ({
spaceNavigations: [],
spaceNavigations: null,
externalExtensions: [],
spaceUnreadItems: null,
selectedNavigationName: null,
loading: false,
}),
computed: {
Expand Down Expand Up @@ -248,7 +251,7 @@ export default {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
if (this.spaceId) {
this.spaceNavigations = [];
this.spaceNavigations = null;
this.retrieveSpaceNavigations()
.then(() => this.refreshExtensions());
}
Expand All @@ -266,6 +269,8 @@ export default {
created() {
document.addEventListener('space-unread-activities-updated', this.applySpaceUnreadChanges);
this.retrieveSpaceNavigations(this.spaceId);
this.selectedNavigationName = eXo.env.portal.siteKeyName === this.spaceGroupId
&& eXo.env.portal.selectedNodeUri?.split?.('/')?.reverse?.()?.[0];
},
methods: {
applySpaceUnreadChanges(event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@
:navigations="site.siteNavigations"
:site-name="site?.name"
:enable-change-home="enableChangeHome"
:selected-name="expandSelectionOnly && selectedNavigationName" />
:selected-name="selectedNavigationName"
collapsed />
</v-card>
<exo-confirm-dialog
ref="confirmDialog"
Expand Down Expand Up @@ -106,7 +107,7 @@ export default {
created() {
this.$root.$on('update-home-link', this.selectHome);
document.addEventListener('homeLinkUpdated', () => this.homeLink = eXo.env.portal.homeLink);
this.selectedNavigationName = eXo.env.portal.selectedNodeUri?.split?.('/')?.reverse?.()?.[0];
this.selectedNavigationName = eXo.env.portal.siteKeyName === this.site.name && eXo.env.portal.selectedNodeUri?.split?.('/')?.reverse?.()?.[0];
},
methods: {
navigationUri(navigation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@

<template>
<v-treeview
v-if="navigationTree"
id="siteNavigationTree"
:open.sync="openLevel"
:items="navigations"
:items="navigationTree"
:active="active"
active-class="v-item--active v-list-item--active"
class="treeView-item my-2"
Expand Down Expand Up @@ -53,6 +54,10 @@ export default {
type: Boolean,
default: false,
},
collapsed: {
type: Boolean,
default: false,
},
spaceUnreadItems: {
type: Object,
default: null
Expand All @@ -64,15 +69,17 @@ export default {
},
data: () => ({
selectedNodeUri: eXo.env.portal.selectedNodeUri,
currentSite: eXo.env.portal.portalName,
currentSite: eXo.env.portal.siteKeyName,
}),
computed: {
openLevel() {
if (this.selectedName) {
const ids = [this.selectedName];
const splittedCurrentUri = this.selectedNodeUri.split('/');
ids.push (...splittedCurrentUri);
ids.push (...splittedCurrentUri.slice(1));
return ids;
} else if (this.collapsed) {
return [];
} else {
const ids = [];
if (this.navigations?.length) {
Expand All @@ -86,6 +93,17 @@ export default {
return ids;
}
},
navigationTree() {
if (this.navigations?.length === 1) {
const navigations = JSON.parse(JSON.stringify(this.navigations));
const rootNavigation = navigations[0];
const rootNavigationChildren = navigations[0]?.children || [];
rootNavigation.children = [];
return this.filterNodes([rootNavigation, ...rootNavigationChildren]);
} else {
return this.navigations;
}
},
firstNavigationId() {
return this.navigations?.[0]?.id;
},
Expand All @@ -97,5 +115,23 @@ export default {
return [splittedCurrentUri[splittedCurrentUri.length -1]];
},
},
methods: {
filterNodes(navigations) {
if (navigations?.length) {
return navigations.map(n => {
n.children = this.filterNodes(n.children);
if (n.children?.length
|| n.pageLink
|| n.pageKey) {
return n;
} else {
return [];
}
}).filter(n => n.children?.length || n.pageLink || n.pageKey);
} else {
return [];
}
},
},
};
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,23 @@
:left="$vuetify.rtl"
:open-on-hover="isOpenedOnHover"
bottom
offset-y>
offset-y
eager>
<template #activator="{ on, attrs }">
<v-tab
v-if="hasPage || hasChildren && childrenHasPage"
:class="`mx-auto text-break ${notClickable}`"
v-on="on"
v-bind="attrs"
:href="navigationNodeUri"
:target="navigationNodeTarget"
:link="hasPage"
:aria-label="navigation.label"
:class="`mx-auto text-break ${notClickable}`"
:value="navigationNodeUri"
v-on="on"
v-bind="attrs"
role="tab"
@click.stop="checkLink(navigation, $event)"
@click="openUrl(navigationNodeUri, navigationNodeTarget)"
@change="updateNavigationState(navigation.uri)">
@change="updateNavigationState">
<span
class="text-truncate-3">
{{ navigation.label }}
Expand All @@ -63,18 +65,14 @@
:navigation="children"
:base-site-uri="baseSiteUri"
:parent-navigation-uri="navigation.uri"
@update-navigation-state="updateNavigationState" />
:selected-path="selectedPath"
@update-navigation-state="updateNavigationState"
@select="updateNavigationState" />
</v-menu>
</template>

<script>
export default {
data () {
return {
showMenu: false,
isOpenedOnHover: true,
};
},
props: {
navigation: {
type: Object,
Expand All @@ -83,19 +81,22 @@ export default {
baseSiteUri: {
type: String,
default: null
}
},
watch: {
showMenu() {
this.isOpenedOnHover = !this.showMenu;
this.$root.$emit('close-sibling-drop-menus', this);
}
},
selectedPath: {
type: String,
default: null
},
},
created() {
document.addEventListener('click', this.handleCloseMenu);
this.$root.$on('close-sibling-drop-menus', this.handleCloseSiblingMenus);
data () {
return {
showMenu: false,
isOpenedOnHover: true,
};
},
computed: {
isSelected() {
return this.selectedPath === this.navigationNodeUri;
},
notClickable() {
return `${this.hasPage ? ' ' : ' not-clickable ' }`;
},
Expand All @@ -113,11 +114,29 @@ export default {
},
childrenHasPage() {
return this.checkChildrenHasPage(this.navigation);
}
},
},
watch: {
showMenu() {
this.isOpenedOnHover = !this.showMenu;
this.$root.$emit('close-sibling-drop-menus', this);
},
isSelected: {
immediate: true,
handler() {
if (this.isSelected) {
this.updateNavigationState();
}
}
},
},
created() {
document.addEventListener('click', this.handleCloseMenu);
this.$root.$on('close-sibling-drop-menus', this.handleCloseSiblingMenus);
},
methods: {
updateNavigationState(value) {
this.$emit('update-navigation-state', `${this.baseSiteUri}${value}`);
updateNavigationState() {
this.$emit('update-navigation-state', this.navigationNodeUri);
},
checkLink(navigation, e) {
if (!navigation.pageKey) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,21 @@
dense>
<v-list-item
v-if="hasPage || hasChildren && childrenHasPage"
class="pt-0 pb-0"
:href="navigationNodeUri"
:target="navigationNodeTarget"
@click.stop="checkLink(navigation, $event)"
:link="!!hasPage">
:link="!!hasPage"
class="pt-0 pb-0"
@click.stop="checkLink(navigation, $event)">
<v-menu
v-model="showMenu"
rounded
:position-x="positionX"
:position-y="positionY"
transition="slide-x-reverse-transition"
absolute
:left="$vuetify.rtl"
:open-on-hover="isOpenedOnHover"
absolute
eager
offset-x>
<template #activator="{ attrs, on }">
<v-list-item-title
Expand Down Expand Up @@ -70,22 +71,16 @@
:navigation="children"
:parent-navigation-uri="parentNavigationUri"
:base-site-uri="baseSiteUri"
@update-navigation-state="updateNavigationState" />
:selected-path="selectedPath"
@update-navigation-state="updateNavigationState"
@select="$emit('select')" />
</v-menu>
</v-list-item>
</v-list>
</template>

<script>
export default {
data() {
return {
isOpenedOnHover: true,
showMenu: false,
positionX: 0,
positionY: 0,
};
},
props: {
navigation: {
type: Object,
Expand All @@ -98,19 +93,19 @@ export default {
parentNavigationUri: {
type: String,
default: null
}
},
watch: {
showMenu() {
this.isOpenedOnHover = !this.showMenu;
this.positionX = window.innerWidth - (window.innerWidth - this.$el.getBoundingClientRect().right);
this.positionY = this.$el.getBoundingClientRect().top;
this.$root.$emit('close-sibling-drop-menus-children', this);
}
},
selectedPath: {
type: String,
default: null
},
},
created() {
window.addEventListener('resize', this.updateSize);
this.$root.$on('close-sibling-drop-menus-children', this.handleCloseSiblingMenus);
data() {
return {
isOpenedOnHover: true,
showMenu: false,
positionX: 0,
positionY: 0,
};
},
computed: {
hasChildren() {
Expand All @@ -123,12 +118,37 @@ export default {
return this.checkChildrenHasPage(this.navigation);
},
navigationNodeUri() {
return this.navigation?.pageLink && this.urlVerify(this.navigation?.pageLink) || `${this.baseSiteUri}${this.navigation.uri}`;
return this.navigation?.pageLink
&& this.urlVerify(this.navigation?.pageLink)
|| `${this.baseSiteUri}${this.navigation.uri}`;
},
isSelected() {
return this.navigationNodeUri === this.selectedPath;
},
navigationNodeTarget() {
return this.navigation?.target === 'SAME_TAB' && '_self' || '_blank';
},
},
watch: {
isSelected: {
immediate: true,
handler() {
if (this.isSelected) {
this.$emit('select');
}
}
},
showMenu() {
this.isOpenedOnHover = !this.showMenu;
this.positionX = window.innerWidth - (window.innerWidth - this.$el.getBoundingClientRect().right);
this.positionY = this.$el.getBoundingClientRect().top;
this.$root.$emit('close-sibling-drop-menus-children', this);
},
},
created() {
window.addEventListener('resize', this.updateSize);
this.$root.$on('close-sibling-drop-menus-children', this.handleCloseSiblingMenus);
},
methods: {
checkLink(navigation, e) {
if (!navigation.pageKey) {
Expand Down
Loading

0 comments on commit 7e1a419

Please sign in to comment.