Portals Popover component (#5052)

* Portal Switch component

* Review fixes

* Update storybook props

* Review changes

* Popover component

* Review changes and moved the files to helpcenter folder
This commit is contained in:
Fayaz Ahmed
2022-07-27 14:37:55 +05:30
committed by GitHub
parent ce66b31422
commit 806e5efd7a
6 changed files with 254 additions and 141 deletions
@@ -0,0 +1,95 @@
<template>
<div class="portal-popover__container">
<header>
<div class="actions">
<h2 class="block-title">
{{ $t('HELP_CENTER.PORTAL.POPOVER.TITLE') }}
</h2>
<router-link to="#" class="new-popover-link">
<fluent-icon icon="add" size="16" />
<span>
{{ $t('HELP_CENTER.PORTAL.POPOVER.NEW_PORTAL_LINK') }}
</span>
</router-link>
</div>
<p class="subtitle">
{{ $t('HELP_CENTER.PORTAL.POPOVER.SUBTITLE') }}
</p>
</header>
<div>
<portal-switch
v-for="portal in portals"
:key="portal.id"
:portal="portal"
/>
</div>
<footer>
<woot-button variant="link">
{{ $t('HELP_CENTER.PORTAL.POPOVER.CANCEL_BUTTON_LABEL') }}
</woot-button>
<woot-button>
{{ $t('HELP_CENTER.PORTAL.POPOVER.CHOOSE_LOCALE_BUTTON') }}
</woot-button>
</footer>
</div>
</template>
<script>
import PortalSwitch from './PortalSwitch.vue';
export default {
components: {
PortalSwitch,
},
props: {
portals: {
type: Array,
default: () => [],
},
},
};
</script>
<style lang="scss" scoped>
.portal-popover__container {
padding: var(--space-normal);
background-color: var(--white);
border-radius: var(--border-radius-normal);
box-shadow: var(--shadow-large);
max-width: 48rem;
header {
.actions {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: var(--space-smaller);
.new-popover-link {
display: flex;
align-items: center;
padding: var(--space-half) var(--space-one);
background-color: var(--s-25);
font-size: var(--font-size-mini);
color: var(--s-500);
margin-left: var(--space-small);
border-radius: var(--border-radius-normal);
span {
margin-left: var(--space-small);
}
}
.subtitle {
font-size: var(--font-size-mini);
color: var(--s-600);
}
}
}
footer {
display: flex;
justify-content: end;
align-items: center;
gap: var(--space-small);
}
}
</style>
@@ -0,0 +1,164 @@
<template>
<div class="portal" :class="{ active }">
<thumbnail :username="portal.name" variant="square" />
<div class="actions-container">
<header>
<div>
<h2 class="portal-title">{{ portal.name }}</h2>
<p class="portal-count">
{{ portal.articles_count }}
{{ $t('HELP_CENTER.PORTAL.ARTICLES_LABEL') }}
</p>
</div>
<span v-if="active" class="badge">{{
$t('HELP_CENTER.PORTAL.ACTIVE_BADGE')
}}</span>
</header>
<div class="portal-locales">
<h2 class="locale-title">
{{ $t('HELP_CENTER.PORTAL.CHOOSE_LOCALE_LABEL') }}
</h2>
<ul>
<li v-for="locale in portal.locales" :key="locale.code">
<label :for="`locale-${locale.code}`" class="locale-item">
<input
:id="`locale-${locale.code}`"
v-model="selectedLocale"
type="radio"
name="locale"
:value="locale.code"
/>
<div>
<p>{{ locale.name }}</p>
<span>
{{ locale.articles_count }}
{{ $t('HELP_CENTER.PORTAL.ARTICLES_LABEL') }} -
{{ locale.code }}
</span>
</div>
</label>
</li>
<li>
<a>+ {{ $t('HELP_CENTER.PORTAL.ADD_NEW_LOCALE') }}</a>
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
import thumbnail from 'dashboard/components/widgets/Thumbnail';
export default {
components: {
thumbnail,
},
props: {
portal: {
type: Object,
default: () => ({}),
},
active: {
type: Boolean,
default: false,
},
},
data() {
return {
selectedLocale: '',
};
},
mounted() {
this.selectedLocale = this.portal.locales[0].code;
},
};
</script>
<style lang="scss" scoped>
.portal {
background-color: var(--white);
padding: var(--space-normal);
border: 1px solid var(--color-border-dark);
border-radius: var(--border-radius-medium);
position: relative;
display: flex;
margin-bottom: var(--space-normal);
&.active {
border: 1px solid var(--w-400);
}
.actions-container {
margin-left: var(--space-one);
flex-grow: 1;
header {
display: flex;
align-items: flex-start;
justify-content: space-between;
margin-bottom: var(--space-one);
.badge {
font-size: var(--font-size-mini);
background-color: var(--w-100);
color: var(--w-600);
padding: var(--space-smaller) var(--space-small);
}
.portal-title {
color: var(--s-900);
font-size: var(--font-size-medium);
font-weight: var(--font-weight-bold);
margin-bottom: 0;
}
.portal-count {
font-size: var(--font-size-mini);
margin-bottom: 0;
color: var(--s-500);
}
}
.portal-locales {
.locale-title {
color: var(--s-600);
font-size: var(--font-size-default);
font-weight: var(--font-weight-medium);
}
ul {
list-style: none;
padding: 0;
margin: 0;
.locale-item {
display: flex;
align-items: flex-start;
margin-bottom: var(--space-smaller);
cursor: pointer;
padding: var(--space-smaller);
border-radius: var(--border-radius-normal);
&:hover {
background-color: var(--w-25);
}
p {
margin-bottom: 0;
}
span {
color: var(--s-500);
font-size: var(--font-size-small);
}
}
}
}
}
}
label > [type='radio'] {
margin-bottom: 0;
margin-top: var(--space-smaller);
margin-right: var(--space-one);
}
</style>
@@ -0,0 +1,80 @@
import PortalPopover from '../PortalPopover.vue';
export default {
title: 'Components/Help Center/Portal Popover',
component: PortalPopover,
argTypes: {
active: {
defaultValue: false,
control: {
type: 'boolean',
},
},
},
};
const Template = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { PortalPopover },
template:
'<PortalPopover v-bind="$props" @click="onClick">{{label}}</PortalPopover>',
});
export const Primary = Template.bind({});
Primary.args = {
portals: [
{
name: 'Chatwoot Help Center',
articles_count: 124,
locales: [
{
name: 'English',
code: 'en',
articles_count: 12,
},
{
name: 'Español',
code: 'es',
articles_count: 42,
},
{
name: 'French',
code: 'fr',
articles_count: 29,
},
{
name: 'Italian',
code: 'it',
articles_count: 4,
},
{
name: 'German',
code: 'de',
articles_count: 66,
},
],
},
{
name: 'Chatwoot Docs',
articles_count: 16,
locales: [
{
name: 'English',
code: 'en',
articles_count: 12,
},
{
name: 'Japanese',
code: 'jp',
articles_count: 4,
},
{
name: 'Mandarin',
code: 'CH',
articles_count: 6,
},
],
},
],
};
@@ -0,0 +1,58 @@
import PortalSwitch from '../PortalSwitch.vue';
export default {
title: 'Components/Help Center/Portal Switch',
component: PortalSwitch,
argTypes: {
active: {
defaultValue: false,
control: {
type: 'boolean',
},
},
},
};
const Template = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { PortalSwitch },
template:
'<PortalSwitch v-bind="$props" @click="onClick">{{label}}</PortalSwitch>',
});
export const Primary = Template.bind({});
Primary.args = {
active: false,
portal: {
name: 'Chatwoot Help Center',
articles_count: 124,
locales: [
{
name: 'English',
code: 'en',
articles_count: 12,
},
{
name: 'Español',
code: 'es',
articles_count: 42,
},
{
name: 'French',
code: 'fr',
articles_count: 29,
},
{
name: 'Italian',
code: 'it',
articles_count: 4,
},
{
name: 'German',
code: 'de',
articles_count: 66,
},
],
},
};