feat: Opening and closing portal switch (#5126)

This commit is contained in:
Sivin Varghese
2022-07-28 14:52:05 +05:30
committed by GitHub
parent 41df70fb96
commit ef9ea99b91
15 changed files with 336 additions and 37 deletions

View File

@@ -1,44 +0,0 @@
import { action } from '@storybook/addon-actions';
import ArticleHeader from './ArticleHeader';
export default {
title: 'Components/Help Center/Header',
component: ArticleHeader,
argTypes: {
headerTitle: {
defaultValue: 'All articles',
control: {
type: 'text',
},
},
count: {
defaultValue: 112,
control: {
type: 'number',
},
},
selectedValue: {
defaultValue: 'Status',
control: {
type: 'text',
},
},
},
};
const Template = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { ArticleHeader },
template:
'<article-header v-bind="$props" @openModal="openFilterModal" @open="openDropdown" @close="closeDropdown" ></article-header>',
});
export const ArticleHeaderView = Template.bind({});
ArticleHeaderView.args = {
headerTitle: 'All articles',
count: 112,
selectedValue: 'Status',
openFilterModal: action('openedFilterModal'),
openDropdown: action('opened'),
closeDropdown: action('closed'),
};

View File

@@ -1,176 +0,0 @@
<template>
<div class="header--wrap">
<div class="header-left--wrap">
<h3 class="page-title">{{ headerTitle }}</h3>
<span class="text-block-title count-view">{{ `(${count})` }}</span>
</div>
<div class="header-right--wrap">
<woot-button
class-names="article--buttons"
icon="filter"
color-scheme="secondary"
variant="hollow"
size="small"
@click="openFilterModal"
>
{{ $t('HELP_CENTER.HEADER.FILTER') }}
</woot-button>
<woot-button
class-names="article--buttons"
icon="arrow-sort"
color-scheme="secondary"
size="small"
variant="hollow"
@click="openDropdown"
>
{{ $t('HELP_CENTER.HEADER.SORT') }}
<span class="selected-value">
{{ selectedValue }}
<Fluent-icon class="dropdown-arrow" icon="chevron-down" size="14" />
</span>
</woot-button>
<div
v-if="showSortByDropdown"
v-on-clickaway="closeDropdown"
class="dropdown-pane dropdown-pane--open"
>
<woot-dropdown-menu>
<woot-dropdown-item>
<woot-button
variant="clear"
color-scheme="secondary"
size="small"
icon="send-clock"
>
{{ $t('HELP_CENTER.HEADER.DROPDOWN_OPTIONS.PUBLISHED') }}
</woot-button>
</woot-dropdown-item>
<woot-dropdown-item>
<woot-button
variant="clear"
color-scheme="secondary"
size="small"
icon="dual-screen-clock"
>
{{ $t('HELP_CENTER.HEADER.DROPDOWN_OPTIONS.DRAFT') }}
</woot-button>
</woot-dropdown-item>
<woot-dropdown-item>
<woot-button
variant="clear"
color-scheme="secondary"
size="small"
icon="calendar-clock"
>
{{ $t('HELP_CENTER.HEADER.DROPDOWN_OPTIONS.ARCHIVED') }}
</woot-button>
</woot-dropdown-item>
</woot-dropdown-menu>
</div>
<woot-button
v-tooltip.top-end="$t('HELP_CENTER.HEADER.SETTINGS_BUTTON')"
icon="settings"
class-names="article--buttons"
variant="hollow"
size="small"
color-scheme="secondary"
/>
<woot-button
class-names="article--buttons"
size="small"
color-scheme="primary"
@click="onClickNewArticlePage"
>
{{ $t('HELP_CENTER.HEADER.NEW_BUTTON') }}
</woot-button>
</div>
</div>
</template>
<script>
import { mixin as clickaway } from 'vue-clickaway';
import WootDropdownItem from 'shared/components/ui/dropdown/DropdownItem.vue';
import WootDropdownMenu from 'shared/components/ui/dropdown/DropdownMenu.vue';
import FluentIcon from 'shared/components/FluentIcon/DashboardIcon';
export default {
components: {
FluentIcon,
WootDropdownItem,
WootDropdownMenu,
},
mixins: [clickaway],
props: {
headerTitle: {
type: String,
default: '',
},
count: {
type: Number,
default: 0,
},
selectedValue: {
type: String,
default: '',
},
},
data() {
return {
showSortByDropdown: false,
};
},
methods: {
openFilterModal() {
this.$emit('openModal');
},
openDropdown() {
this.$emit('open');
this.showSortByDropdown = true;
},
closeDropdown() {
this.$emit('close');
this.showSortByDropdown = false;
},
onClickNewArticlePage() {
this.$emit('newArticlePage');
},
},
};
</script>
<style scoped lang="scss">
.header--wrap {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
height: var(--space-larger);
}
.header-left--wrap {
display: flex;
align-items: center;
}
.header-right--wrap {
display: flex;
align-items: center;
}
.count-view {
margin-left: var(--space-smaller);
}
.dropdown-pane--open {
top: var(--space-larger);
right: 14.8rem;
}
.selected-value {
display: inline-flex;
margin-left: var(--space-smaller);
color: var(--b-900);
align-items: center;
}
.dropdown-arrow {
margin-left: var(--space-smaller);
}
.article--buttons {
margin-left: var(--space-smaller);
}
</style>

View File

@@ -1,39 +0,0 @@
import { action } from '@storybook/addon-actions';
import EditArticleHeader from './EditArticleHeader';
export default {
title: 'Components/Help Center/Header',
component: EditArticleHeader,
argTypes: {
backButtonLabel: {
defaultValue: 'Articles',
control: {
type: 'text',
},
},
draftState: {
defaultValue: 'saving',
control: {
type: 'text',
},
},
},
};
const Template = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { EditArticleHeader },
template:
'<edit-article-header v-bind="$props" @back="onClickGoBack" @show="showPreview" @add="onClickAdd" @open="openSidebar" @close="closeSidebar" ></edit-article-header>',
});
export const EditArticleHeaderView = Template.bind({});
EditArticleHeaderView.args = {
backButtonLabel: 'Articles',
draftState: 'saving',
onClickGoBack: action('goBack'),
showPreview: action('previewOpened'),
onClickAdd: action('added'),
openSidebar: action('openedSidebar'),
closeSidebar: action('closedSidebar'),
};

View File

@@ -1,154 +0,0 @@
<template>
<div class="header--wrap">
<div class="header-left--wrap">
<woot-button
icon="chevron-left"
class-names="article-back-buttons"
variant="clear"
color-scheme="primary"
@click="onClickGoBack"
>
{{ backButtonLabel }}
</woot-button>
</div>
<div class="header-right--wrap">
<span v-if="showDraftStatus" class="draft-status">
{{ draftStatusText }}
</span>
<woot-button
class-names="article--buttons"
icon="globe"
color-scheme="secondary"
variant="hollow"
size="small"
@click="showPreview"
>
{{ $t('HELP_CENTER.EDIT_HEADER.PREVIEW') }}
</woot-button>
<woot-button
class-names="article--buttons"
icon="add"
color-scheme="secondary"
variant="hollow"
size="small"
@click="onClickAdd"
>
{{ $t('HELP_CENTER.EDIT_HEADER.ADD_TRANSLATION') }}
</woot-button>
<woot-button
v-if="isSidebarOpen"
v-tooltip.top-end="$t('HELP_CENTER.EDIT_HEADER.OPEN_SIDEBAR')"
icon="pane-open"
class-names="article--buttons"
variant="hollow"
size="small"
color-scheme="secondary"
@click="openSidebar"
/>
<woot-button
v-else
v-tooltip.top-end="$t('HELP_CENTER.EDIT_HEADER.CLOSE_SIDEBAR')"
icon="pane-close"
class-names="article--buttons"
variant="hollow"
size="small"
color-scheme="secondary"
@click="closeSidebar"
/>
<woot-button
class-names="article--buttons"
size="small"
color-scheme="primary"
>
{{ $t('HELP_CENTER.EDIT_HEADER.PUBLISH_BUTTON') }}
</woot-button>
</div>
</div>
</template>
<script>
export default {
props: {
backButtonLabel: {
type: String,
default: '',
},
draftState: {
type: String,
default: '',
},
},
data() {
return {
isSidebarOpen: true,
};
},
computed: {
isDraftStatusSavingOrSaved() {
return this.draftState === 'saving' || 'saved';
},
draftStatusText() {
if (this.draftState === 'saving') {
return this.$t('HELP_CENTER.EDIT_HEADER.SAVING');
}
if (this.draftState === 'saved') {
return this.$t('HELP_CENTER.EDIT_HEADER.SAVED');
}
return '';
},
showDraftStatus() {
return this.isDraftStatusSavingOrSaved;
},
},
methods: {
onClickGoBack() {
this.$emit('back');
},
showPreview() {
this.$emit('show');
},
onClickAdd() {
this.$emit('add');
},
openSidebar() {
this.$emit('open');
this.isSidebarOpen = true;
},
closeSidebar() {
this.$emit('close');
this.isSidebarOpen = false;
},
},
};
</script>
<style scoped lang="scss">
.header--wrap {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
height: var(--space-larger);
}
.header-left--wrap {
display: flex;
align-items: center;
}
.header-right--wrap {
display: flex;
align-items: center;
}
.article-back-buttons {
padding-left: 0;
}
.article--buttons {
margin-left: var(--space-smaller);
}
.draft-status {
margin-right: var(--space-smaller);
margin-left: var(--space-normal);
color: var(--s-400);
align-items: center;
font-size: var(--font-size-mini);
}
</style>

View File

@@ -1,134 +0,0 @@
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',
},
],
},
],
};

View File

@@ -1,88 +0,0 @@
<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>

View File

@@ -1,113 +0,0 @@
<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-small) 0 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>

View File

@@ -1,62 +0,0 @@
<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>