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:
@@ -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>
|
||||
Reference in New Issue
Block a user