feat: New sidebar component for help-center (#5017)
* feat: New sidebar component for help-center * chore: Review fixes * chore: Minor fixes Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
parent
21a8b79aa5
commit
f004db3d26
9 changed files with 511 additions and 14 deletions
|
@ -0,0 +1,134 @@
|
|||
import { action } from '@storybook/addon-actions';
|
||||
import Sidebar from './Sidebar';
|
||||
import Thumbnail from 'dashboard/components/widgets/Thumbnail';
|
||||
|
||||
export default {
|
||||
title: 'Components/Help Center/Sidebar',
|
||||
component: { Sidebar, Thumbnail },
|
||||
argTypes: {
|
||||
thumbnailSrc: {
|
||||
defaultValue: '',
|
||||
control: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
headerTitle: {
|
||||
defaultValue: '',
|
||||
control: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
subTitle: {
|
||||
defaultValue: '',
|
||||
control: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
accessibleMenuItems: [],
|
||||
additionalSecondaryMenuItems: [],
|
||||
},
|
||||
};
|
||||
|
||||
const Template = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: { Sidebar },
|
||||
template: '<sidebar v-bind="$props" @input="onSearch"></sidebar>',
|
||||
});
|
||||
|
||||
export const HelpCenterSidebarView = Template.bind({});
|
||||
HelpCenterSidebarView.args = {
|
||||
onSearch: action('search'),
|
||||
thumbnailSrc: '',
|
||||
headerTitle: 'Help Center',
|
||||
subTitle: 'English',
|
||||
accessibleMenuItems: [
|
||||
{
|
||||
icon: 'book',
|
||||
label: 'HELP_CENTER.ALL_ARTICLES',
|
||||
key: 'helpcenter_all',
|
||||
count: 199,
|
||||
toState: 'accounts/1/articles/all',
|
||||
toolTip: 'All Articles',
|
||||
toStateName: 'helpcenter_all',
|
||||
},
|
||||
{
|
||||
icon: 'pen',
|
||||
label: 'HELP_CENTER.MY_ARTICLES',
|
||||
key: 'helpcenter_mine',
|
||||
count: 112,
|
||||
toState: 'accounts/1/articles/mine',
|
||||
toolTip: 'My articles',
|
||||
toStateName: 'helpcenter_mine',
|
||||
},
|
||||
{
|
||||
icon: 'draft',
|
||||
label: 'HELP_CENTER.DRAFT',
|
||||
key: 'helpcenter_draft',
|
||||
count: 32,
|
||||
toState: 'accounts/1/articles/draft',
|
||||
toolTip: 'Draft',
|
||||
toStateName: 'helpcenter_draft',
|
||||
},
|
||||
{
|
||||
icon: 'archive',
|
||||
label: 'HELP_CENTER.ARCHIVED',
|
||||
key: 'helpcenter_archive',
|
||||
count: 10,
|
||||
toState: 'accounts/1/articles/archived',
|
||||
toolTip: 'Archived',
|
||||
toStateName: 'helpcenter_archive',
|
||||
},
|
||||
],
|
||||
additionalSecondaryMenuItems: [
|
||||
{
|
||||
icon: 'folder',
|
||||
label: 'HELP_CENTER.CATEGORY',
|
||||
hasSubMenu: true,
|
||||
key: 'category',
|
||||
children: [
|
||||
{
|
||||
id: 1,
|
||||
label: 'Getting started',
|
||||
count: 12,
|
||||
truncateLabel: true,
|
||||
toState: 'accounts/1/articles/categories/new',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
label: 'Channel',
|
||||
count: 19,
|
||||
truncateLabel: true,
|
||||
toState: 'accounts/1/articles/categories/channel',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
label: 'Feature',
|
||||
count: 24,
|
||||
truncateLabel: true,
|
||||
toState: 'accounts/1/articles/categories/feature',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
label: 'Advanced',
|
||||
count: 8,
|
||||
truncateLabel: true,
|
||||
toState: 'accounts/1/articles/categories/advanced',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
label: 'Mobile app',
|
||||
count: 3,
|
||||
truncateLabel: true,
|
||||
toState: 'accounts/1/articles/categories/mobile-app',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
label: 'Others',
|
||||
count: 39,
|
||||
truncateLabel: true,
|
||||
toState: 'accounts/1/articles/categories/others',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
|
@ -0,0 +1,88 @@
|
|||
<template>
|
||||
<div class="main-nav secondary-menu">
|
||||
<sidebar-header
|
||||
:thumbnail-src="thumbnailSrc"
|
||||
:header-title="headerTitle"
|
||||
:sub-title="subTitle"
|
||||
/>
|
||||
<sidebar-search @input="onSearch" />
|
||||
<!-- <transition-group name="menu-list" tag="ul" class="menu vertical"> -->
|
||||
<div name="menu-list" tag="ul" class="menu vertical">
|
||||
<secondary-nav-item
|
||||
v-for="menuItem in accessibleMenuItems"
|
||||
:key="menuItem.toState"
|
||||
:menu-item="menuItem"
|
||||
:is-help-center-sidebar="true"
|
||||
/>
|
||||
</div>
|
||||
<div name="menu-list" tag="ul" class="menu vertical">
|
||||
<secondary-nav-item
|
||||
v-for="menuItem in additionalSecondaryMenuItems"
|
||||
:key="menuItem.key"
|
||||
:menu-item="menuItem"
|
||||
:is-help-center-sidebar="true"
|
||||
/>
|
||||
</div>
|
||||
<!-- </transition-group> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SecondaryNavItem from 'dashboard/components/layout/sidebarComponents/SecondaryNavItem';
|
||||
import SidebarSearch from './SidebarSearch';
|
||||
import SidebarHeader from './SidebarHeader';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SecondaryNavItem,
|
||||
SidebarSearch,
|
||||
SidebarHeader,
|
||||
},
|
||||
props: {
|
||||
thumbnailSrc: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
headerTitle: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
subTitle: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
accessibleMenuItems: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
additionalSecondaryMenuItems: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
onSearch(value) {
|
||||
this.$emit('input', value);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.secondary-menu {
|
||||
background: var(--white);
|
||||
border-right: 1px solid var(--s-50);
|
||||
height: 100%;
|
||||
width: var(--space-giga);
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
padding: var(--space-small);
|
||||
|
||||
&:hover {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,113 @@
|
|||
<template>
|
||||
<div class="sidebar-header--wrap">
|
||||
<div class="header-left--side">
|
||||
<thumbnail
|
||||
size="40px"
|
||||
:src="thumbnailSrc"
|
||||
:username="headerTitle"
|
||||
variant="square"
|
||||
/>
|
||||
<div class="header-title--wrap">
|
||||
<h4 class="sub-block-title title-view">{{ headerTitle }}</h4>
|
||||
<span class="sub-title--view">{{ subTitle }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-right--side">
|
||||
<fluent-icon
|
||||
icon="arrow-up-right"
|
||||
size="28px"
|
||||
class="pop-out--icon"
|
||||
@click="popOutHelpCenter"
|
||||
/>
|
||||
<fluent-icon
|
||||
icon="arrow-swap"
|
||||
size="28px"
|
||||
class="portal-switch--icon"
|
||||
@click="openSwitchPortalModal"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Thumbnail from 'dashboard/components/widgets/Thumbnail';
|
||||
export default {
|
||||
components: {
|
||||
Thumbnail,
|
||||
},
|
||||
props: {
|
||||
thumbnailSrc: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
headerTitle: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
subTitle: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
popOutHelpCenter() {
|
||||
this.$emit('pop-out');
|
||||
},
|
||||
openSwitchPortalModal() {
|
||||
this.$emit('open');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.sidebar-header--wrap {
|
||||
display: flex;
|
||||
height: var(--space-jumbo);
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: var(--space-normal) 0;
|
||||
border-bottom: 1px solid var(--color-border-light);
|
||||
}
|
||||
|
||||
.header-title--wrap {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
margin-left: var(--space-small);
|
||||
}
|
||||
|
||||
.title-view {
|
||||
margin-bottom: var(--space-zero);
|
||||
}
|
||||
|
||||
.sub-title--view {
|
||||
font-size: var(--font-size-mini);
|
||||
color: var(--b-600);
|
||||
}
|
||||
|
||||
.header-left--side {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header-right--side {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.pop-out--icon {
|
||||
padding: var(--space-smaller);
|
||||
}
|
||||
|
||||
.portal-switch--icon {
|
||||
padding: var(--space-smaller);
|
||||
margin-left: var(--space-small);
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background: var(--s-50);
|
||||
border-radius: var(--border-radius-normal);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<div class="search-input--wrap">
|
||||
<div class="search-icon--wrap">
|
||||
<fluent-icon icon="search" size="18" class="search-icon" />
|
||||
</div>
|
||||
<input
|
||||
v-model="searchValue"
|
||||
class="search-input"
|
||||
:placeholder="$t('HELP_CENTER.SIDEBAR.SEARCH.PLACEHOLDER')"
|
||||
@input="onSearch"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
searchValue: '',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onSearch(e) {
|
||||
this.$emit('input', e.target.value);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search-input--wrap {
|
||||
display: flex;
|
||||
padding: var(--space-small) var(--space-zero);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
width: 100%;
|
||||
height: var(--space-large);
|
||||
border-radius: var(--border-radius-normal);
|
||||
background: var(--s-25);
|
||||
font-size: var(--font-size-small);
|
||||
padding: var(--space-small) var(--space-small) var(--space-small)
|
||||
var(--space-large);
|
||||
border: 1px solid var(--s-50);
|
||||
|
||||
&:focus {
|
||||
border-color: var(--w-500);
|
||||
}
|
||||
}
|
||||
|
||||
.search-icon--wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
color: var(--s-500);
|
||||
top: var(--space-small);
|
||||
left: var(--space-small);
|
||||
}
|
||||
</style>
|
|
@ -26,6 +26,9 @@
|
|||
:class="{ 'text-truncate': shouldTruncate }"
|
||||
>
|
||||
{{ label }}
|
||||
<span v-if="isHelpCenterSidebar && childItemCount" class="count-view">
|
||||
{{ childItemCount }}
|
||||
</span>
|
||||
</span>
|
||||
<span v-if="count" class="badge" :class="{ secondary: !isActive }">
|
||||
{{ count }}
|
||||
|
@ -73,6 +76,14 @@ export default {
|
|||
type: String,
|
||||
default: '',
|
||||
},
|
||||
isHelpCenterSidebar: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
childItemCount: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
showIcon() {
|
||||
|
@ -155,4 +166,19 @@ $label-badge-size: var(--space-slab);
|
|||
color: var(--s-600);
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
|
||||
.count-view {
|
||||
background: var(--s-50);
|
||||
border-radius: var(--border-radius-normal);
|
||||
color: var(--s-600);
|
||||
font-size: var(--font-size-micro);
|
||||
font-weight: var(--font-weight-bold);
|
||||
margin-left: var(--space-smaller);
|
||||
padding: var(--space-zero) var(--space-smaller);
|
||||
|
||||
&.is-active {
|
||||
background: var(--w-50);
|
||||
color: var(--w-500);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
<template>
|
||||
<li class="sidebar-item">
|
||||
<span v-if="hasSubMenu" class="secondary-menu--title fs-small">
|
||||
{{ $t(`SIDEBAR.${menuItem.label}`) }}
|
||||
</span>
|
||||
<div v-if="hasSubMenu" class="secondary-menu--wrap">
|
||||
<span class="secondary-menu--title fs-small">
|
||||
{{ $t(`SIDEBAR.${menuItem.label}`) }}
|
||||
</span>
|
||||
<div v-if="isHelpCenterSidebar" class="submenu-icons">
|
||||
<fluent-icon icon="search" class="submenu-icon" size="16" />
|
||||
<fluent-icon icon="add" class="submenu-icon" size="16" />
|
||||
</div>
|
||||
</div>
|
||||
<router-link
|
||||
v-else
|
||||
class="secondary-menu--title secondary-menu--link fs-small"
|
||||
|
@ -15,6 +21,13 @@
|
|||
size="14"
|
||||
/>
|
||||
{{ $t(`SIDEBAR.${menuItem.label}`) }}
|
||||
<span
|
||||
v-if="isHelpCenterSidebar"
|
||||
class="count-view"
|
||||
:class="computedClass"
|
||||
>
|
||||
{{ `${menuItem.count}` }}
|
||||
</span>
|
||||
<span
|
||||
v-if="menuItem.label === 'AUTOMATION'"
|
||||
data-view-component="true"
|
||||
|
@ -35,6 +48,8 @@
|
|||
:should-truncate="child.truncateLabel"
|
||||
:icon="computedInboxClass(child)"
|
||||
:warning-icon="computedInboxErrorClass(child)"
|
||||
:is-help-center-sidebar="isHelpCenterSidebar"
|
||||
:child-item-count="child.count"
|
||||
/>
|
||||
<router-link
|
||||
v-if="showItem(menuItem)"
|
||||
|
@ -79,6 +94,10 @@ export default {
|
|||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
isHelpCenterSidebar: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({ activeInbox: 'getSelectedInbox' }),
|
||||
|
@ -120,17 +139,19 @@ export default {
|
|||
// If active Inbox is present
|
||||
// donot highlight conversations
|
||||
if (this.activeInbox) return ' ';
|
||||
|
||||
if (
|
||||
this.isInboxConversation ||
|
||||
this.isTeamsSettings ||
|
||||
this.isInboxsSettings ||
|
||||
this.isIntegrationsSettings ||
|
||||
this.isApplicationsSettings
|
||||
) {
|
||||
return 'is-active';
|
||||
if (this.hasSubMenu) {
|
||||
if (
|
||||
this.isInboxConversation ||
|
||||
this.isTeamsSettings ||
|
||||
this.isInboxsSettings ||
|
||||
this.isIntegrationsSettings ||
|
||||
this.isApplicationsSettings
|
||||
) {
|
||||
return 'is-active';
|
||||
}
|
||||
return ' ';
|
||||
}
|
||||
return ' ';
|
||||
return '';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
@ -170,6 +191,11 @@ export default {
|
|||
margin: var(--space-smaller) 0 0;
|
||||
}
|
||||
|
||||
.secondary-menu--wrap {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.secondary-menu--title {
|
||||
color: var(--s-600);
|
||||
display: flex;
|
||||
|
@ -242,6 +268,7 @@ export default {
|
|||
color: var(--w-500);
|
||||
}
|
||||
}
|
||||
|
||||
.beta {
|
||||
padding-right: var(--space-smaller) !important;
|
||||
padding-left: var(--space-smaller) !important;
|
||||
|
@ -255,4 +282,34 @@ export default {
|
|||
color: var(--g-800);
|
||||
border-color: var(--g-700);
|
||||
}
|
||||
|
||||
.count-view {
|
||||
background: var(--s-50);
|
||||
border-radius: var(--border-radius-normal);
|
||||
color: var(--s-600);
|
||||
font-size: var(--font-size-micro);
|
||||
font-weight: var(--font-weight-bold);
|
||||
margin-left: var(--space-smaller);
|
||||
padding: var(--space-zero) var(--space-smaller);
|
||||
|
||||
&.is-active {
|
||||
background: var(--w-50);
|
||||
color: var(--w-500);
|
||||
}
|
||||
}
|
||||
|
||||
.submenu-icons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.submenu-icon {
|
||||
margin-left: var(--space-small);
|
||||
color: var(--s-600);
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
color: var(--w-500);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue