feat: Add the ability to toggle the secondary sidebar in all display breakpoints (#6118)

Co-authored-by: Nithin David <1277421+nithindavid@users.noreply.github.com>
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
Sivin Varghese 2022-12-23 03:37:11 +05:30 committed by GitHub
parent dbb6c0a074
commit 2af337be10
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 72 additions and 120 deletions

View file

@ -59,12 +59,8 @@
.hamburger--menu { .hamburger--menu {
cursor: pointer; cursor: pointer;
display: none; display: block;
margin-right: $space-normal; margin-right: $space-normal;
@media screen and (max-width: 1200px) {
display: block;
}
} }
.header--icon { .header--icon {

View file

@ -1,7 +1,12 @@
<template> <template>
<button @click="onMenuItemClick"> <woot-button
<fluent-icon class="hamburger--menu" icon="list" /> size="small"
</button> variant="clear"
color-scheme="secondary"
icon="list"
class="toggle-sidebar"
@click="onMenuItemClick"
/>
</template> </template>
<script> <script>
@ -16,13 +21,8 @@ export default {
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.hamburger--menu { .toggle-sidebar {
cursor: pointer; margin-right: var(--space-small);
display: none; margin-left: var(--space-minus-small);
margin-right: var(--space-normal);
@media screen and (max-width: 1200px) {
display: block;
}
} }
</style> </style>

View file

@ -261,14 +261,7 @@ export default {
width: 20rem; width: 20rem;
flex-shrink: 0; flex-shrink: 0;
overflow-y: hidden; overflow-y: hidden;
position: unset;
@include breakpoint(xlarge down) {
position: absolute;
}
@include breakpoint(xlarge up) {
position: unset;
}
&:hover { &:hover {
overflow-y: hidden; overflow-y: hidden;

View file

@ -1,10 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SidemenuIcon matches snapshot 1`] = ` exports[`SidemenuIcon matches snapshot 1`] = `
<button> <woot-button
<fluent-icon class="toggle-sidebar"
class="hamburger--menu" color-scheme="secondary"
icon="list" icon="list"
/> size="small"
</button> variant="clear"
/>
`; `;

View file

@ -2,14 +2,14 @@
<div class="row app-wrapper"> <div class="row app-wrapper">
<sidebar <sidebar
:route="currentRoute" :route="currentRoute"
:sidebar-class-name="sidebarClassName" :show-secondary-sidebar="isSidebarOpen"
@open-notification-panel="openNotificationPanel" @open-notification-panel="openNotificationPanel"
@toggle-account-modal="toggleAccountModal" @toggle-account-modal="toggleAccountModal"
@open-key-shortcut-modal="toggleKeyShortcutModal" @open-key-shortcut-modal="toggleKeyShortcutModal"
@close-key-shortcut-modal="closeKeyShortcutModal" @close-key-shortcut-modal="closeKeyShortcutModal"
@show-add-label-popup="showAddLabelPopup" @show-add-label-popup="showAddLabelPopup"
/> />
<section class="app-content columns" :class="contentClassName"> <section class="app-content columns">
<router-view /> <router-view />
<command-bar /> <command-bar />
<account-selector <account-selector
@ -46,6 +46,7 @@ import AddAccountModal from 'dashboard/components/layout/sidebarComponents/AddAc
import AccountSelector from 'dashboard/components/layout/sidebarComponents/AccountSelector'; import AccountSelector from 'dashboard/components/layout/sidebarComponents/AccountSelector';
import AddLabelModal from 'dashboard/routes/dashboard/settings/labels/AddLabel'; import AddLabelModal from 'dashboard/routes/dashboard/settings/labels/AddLabel';
import NotificationPanel from 'dashboard/routes/dashboard/notifications/components/NotificationPanel'; import NotificationPanel from 'dashboard/routes/dashboard/notifications/components/NotificationPanel';
import uiSettingsMixin from 'dashboard/mixins/uiSettings';
export default { export default {
components: { components: {
@ -57,9 +58,9 @@ export default {
AddLabelModal, AddLabelModal,
NotificationPanel, NotificationPanel,
}, },
mixins: [uiSettingsMixin],
data() { data() {
return { return {
isSidebarOpen: false,
isOnDesktop: true, isOnDesktop: true,
showAccountModal: false, showAccountModal: false,
showCreateAccountModal: false, showCreateAccountModal: false,
@ -72,44 +73,22 @@ export default {
currentRoute() { currentRoute() {
return ' '; return ' ';
}, },
sidebarClassName() { isSidebarOpen() {
if (this.isOnDesktop) { const { show_secondary_sidebar: showSecondarySidebar } = this.uiSettings;
return ''; return showSecondarySidebar;
}
if (this.isSidebarOpen) {
return 'off-canvas is-open';
}
return 'off-canvas is-transition-push is-closed';
},
contentClassName() {
if (this.isOnDesktop) {
return '';
}
if (this.isSidebarOpen) {
return 'off-canvas-content is-open-left has-transition-push';
}
return 'off-canvas-content has-transition-push';
}, },
}, },
mounted() { mounted() {
window.addEventListener('resize', this.handleResize);
this.handleResize();
bus.$on(BUS_EVENTS.TOGGLE_SIDEMENU, this.toggleSidebar); bus.$on(BUS_EVENTS.TOGGLE_SIDEMENU, this.toggleSidebar);
}, },
beforeDestroy() { beforeDestroy() {
bus.$off(BUS_EVENTS.TOGGLE_SIDEMENU, this.toggleSidebar); bus.$off(BUS_EVENTS.TOGGLE_SIDEMENU, this.toggleSidebar);
window.removeEventListener('resize', this.handleResize);
}, },
methods: { methods: {
handleResize() {
if (window.innerWidth >= 1200) {
this.isOnDesktop = true;
} else {
this.isOnDesktop = false;
}
},
toggleSidebar() { toggleSidebar() {
this.isSidebarOpen = !this.isSidebarOpen; this.updateUISettings({
show_secondary_sidebar: !this.isSidebarOpen,
});
}, },
openCreateAccountModal() { openCreateAccountModal() {
this.showAccountModal = false; this.showAccountModal = false;
@ -142,8 +121,3 @@ export default {
}, },
}; };
</script> </script>
<style lang="scss" scoped>
.off-canvas-content.is-open-left {
transform: translateX(20rem);
}
</style>

View file

@ -1,20 +1,22 @@
<template> <template>
<div v-on-clickaway="closeSearch" class="search-wrap"> <div v-on-clickaway="closeSearch" class="search-wrap">
<div class="search" :class="{ 'is-active': showSearchBox }"> <div class="search-header--wrap">
<woot-sidemenu-icon /> <woot-sidemenu-icon v-if="!showSearchBox" />
<div class="icon"> <div class="search" :class="{ 'is-active': showSearchBox }">
<fluent-icon icon="search" class="search--icon" size="28" /> <div class="icon">
<fluent-icon icon="search" class="search--icon" size="28" />
</div>
<input
v-model="searchTerm"
class="search--input"
:placeholder="$t('CONVERSATION.SEARCH_MESSAGES')"
@focus="onSearch"
/>
<switch-layout
:is-on-expanded-layout="isOnExpandedLayout"
@toggle="$emit('toggle-conversation-layout')"
/>
</div> </div>
<input
v-model="searchTerm"
class="search--input"
:placeholder="$t('CONVERSATION.SEARCH_MESSAGES')"
@focus="onSearch"
/>
<switch-layout
:is-on-expanded-layout="isOnExpandedLayout"
@toggle="$emit('toggle-conversation-layout')"
/>
</div> </div>
<div v-if="showSearchBox" class="results-wrap"> <div v-if="showSearchBox" class="results-wrap">
<div class="show-results"> <div class="show-results">
@ -153,14 +155,21 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.search-wrap { .search-wrap {
position: relative; position: relative;
padding: var(--space-one) var(--space-normal) var(--space-smaller)
var(--space-normal);
}
.search-header--wrap {
display: flex;
justify-content: space-between;
min-height: var(--space-large);
} }
.search { .search {
display: flex; display: flex;
flex: 1;
padding: 0; padding: 0;
border-bottom: 1px solid transparent; border-bottom: 1px solid transparent;
padding: var(--space-one) var(--space-normal) var(--space-smaller)
var(--space-normal);
&:hover { &:hover {
.search--icon { .search--icon {
@ -205,6 +214,7 @@ input::placeholder {
width: 100%; width: 100%;
max-height: 70vh; max-height: 70vh;
overflow: auto; overflow: auto;
left: 0;
} }
.show-results { .show-results {

View file

@ -8,8 +8,7 @@
@close-key-shortcut-modal="closeKeyShortcutModal" @close-key-shortcut-modal="closeKeyShortcutModal"
/> />
<help-center-sidebar <help-center-sidebar
v-if="portals.length" v-if="showHelpCenterSidebar"
:class="sidebarClassName"
:header-title="headerTitle" :header-title="headerTitle"
:portal-slug="selectedPortalSlug" :portal-slug="selectedPortalSlug"
:locale-slug="selectedLocaleInPortal" :locale-slug="selectedLocaleInPortal"
@ -19,7 +18,7 @@
@open-popover="openPortalPopover" @open-popover="openPortalPopover"
@open-modal="onClickOpenAddCategoryModal" @open-modal="onClickOpenAddCategoryModal"
/> />
<section class="app-content columns" :class="contentClassName"> <section class="app-content columns">
<router-view /> <router-view />
<command-bar /> <command-bar />
<account-selector <account-selector
@ -84,7 +83,6 @@ export default {
mixins: [portalMixin, uiSettingsMixin], mixins: [portalMixin, uiSettingsMixin],
data() { data() {
return { return {
isSidebarOpen: false,
isOnDesktop: true, isOnDesktop: true,
showShortcutModal: false, showShortcutModal: false,
showNotificationPanel: false, showNotificationPanel: false,
@ -103,6 +101,15 @@ export default {
meta: 'portals/getMeta', meta: 'portals/getMeta',
isFetching: 'portals/isFetchingPortals', isFetching: 'portals/isFetchingPortals',
}), }),
isSidebarOpen() {
const {
show_help_center_secondary_sidebar: showSecondarySidebar,
} = this.uiSettings;
return showSecondarySidebar;
},
showHelpCenterSidebar() {
return this.portals.length === 0 ? false : this.isSidebarOpen;
},
selectedPortal() { selectedPortal() {
const slug = this.$route.params.portalSlug || this.lastActivePortalSlug; const slug = this.$route.params.portalSlug || this.lastActivePortalSlug;
if (slug) return this.$store.getters['portals/portalBySlug'](slug); if (slug) return this.$store.getters['portals/portalBySlug'](slug);
@ -112,24 +119,6 @@ export default {
selectedLocaleInPortal() { selectedLocaleInPortal() {
return this.$route.params.locale || this.defaultPortalLocale; return this.$route.params.locale || this.defaultPortalLocale;
}, },
sidebarClassName() {
if (this.isOnDesktop) {
return '';
}
if (this.isSidebarOpen) {
return 'off-canvas is-open';
}
return 'off-canvas is-transition-push is-closed';
},
contentClassName() {
if (this.isOnDesktop) {
return '';
}
if (this.isSidebarOpen) {
return 'off-canvas-content is-open-left has-transition-push';
}
return 'off-canvas-content has-transition-push';
},
selectedPortalName() { selectedPortalName() {
return this.selectedPortal ? this.selectedPortal.name : ''; return this.selectedPortal ? this.selectedPortal.name : '';
}, },
@ -248,8 +237,6 @@ export default {
}, },
mounted() { mounted() {
window.addEventListener('resize', this.handleResize);
this.handleResize();
bus.$on(BUS_EVENTS.TOGGLE_SIDEMENU, this.toggleSidebar); bus.$on(BUS_EVENTS.TOGGLE_SIDEMENU, this.toggleSidebar);
const slug = this.$route.params.portalSlug; const slug = this.$route.params.portalSlug;
@ -259,7 +246,6 @@ export default {
}, },
beforeDestroy() { beforeDestroy() {
bus.$off(BUS_EVENTS.TOGGLE_SIDEMENU, this.toggleSidebar); bus.$off(BUS_EVENTS.TOGGLE_SIDEMENU, this.toggleSidebar);
window.removeEventListener('resize', this.handleResize);
}, },
updated() { updated() {
const slug = this.$route.params.portalSlug; const slug = this.$route.params.portalSlug;
@ -272,15 +258,12 @@ export default {
} }
}, },
methods: { methods: {
handleResize() {
if (window.innerWidth > 1200) {
this.isOnDesktop = true;
} else {
this.isOnDesktop = false;
}
},
toggleSidebar() { toggleSidebar() {
this.isSidebarOpen = !this.isSidebarOpen; if (this.portals.length > 0) {
this.updateUISettings({
show_help_center_secondary_sidebar: !this.isSidebarOpen,
});
}
}, },
async fetchPortalAndItsCategories() { async fetchPortalAndItsCategories() {
await this.$store.dispatch('portals/index'); await this.$store.dispatch('portals/index');
@ -322,8 +305,3 @@ export default {
}, },
}; };
</script> </script>
<style lang="scss" scoped>
.off-canvas-content.is-open-left.has-transition-push {
transform: translateX(var(--space-giga));
}
</style>