Chore: Updates design of conversation list

This commit is contained in:
Nithin David 2021-12-03 20:46:49 +05:30
parent 1c29f5bbe4
commit 2be97cf50a
15 changed files with 264 additions and 223 deletions

View file

@ -55,11 +55,60 @@ code {
padding-right: var(--space-normal);
}
$badge-size: var(--space-normal);
$label-badge-size: var(--space-slab);
.badge {
height: min-content;
line-height: 1;
font-weight: var(--font-weight-bold);
border-radius: var(--border-radius-normal);
&.small {
font-size: var(--font-size-nano);
min-width: var(--space-slab);
padding: var(--space-micro);
}
&.rounded {
border-radius: var(--space-mega);
}
&.secondary {
min-width: unset;
background: var(--s-75);
color: var(--s-500);
font-weight: var(--font-weight-bold);
}
}
.badge--label,
.badge--icon {
display: inline-flex;
border-radius: var(--border-radius-small);
margin-right: var(--space-smaller);
background: var(--s-100);
}
.badge--icon {
align-items: center;
height: $badge-size;
justify-content: center;
min-width: $badge-size;
.svg-icon {
color: inherit;
}
}
.badge--label {
height: $label-badge-size;
min-width: $label-badge-size;
margin-left: var(--space-smaller);
}
.padding-right-small {
padding-right: var(--space-one);
}

View file

@ -217,10 +217,10 @@ $accordionmenu-arrow-size: 6px;
$badge-background: $primary-color;
$badge-color: $white;
$badge-color-alt: $black;
$badge-color-alt: $color-body;
$badge-palette: $foundation-palette;
$badge-padding: var(--space-smaller);
$badge-minwidth: 2.1em;
$badge-minwidth: var(--space-normal);
$badge-font-size: var(--font-size-nano);
// 10. Breadcrumbs

View file

@ -37,6 +37,10 @@ $default-button-height: 4.0rem;
border-radius: $space-larger;
}
&.not-rounded {
border-radius: 0;
}
// @TODO Use with link
&.compact {

View file

@ -13,48 +13,22 @@
.conversation {
@include flex;
@include flex-shrink;
@include padding(0 0 0 $space-normal);
border-bottom: 1px solid transparent;
border-left: $space-micro solid transparent;
border-top: 1px solid transparent;
padding: 0 var(--space-small);
margin: var(--space-small);
border-radius: var(--border-radius-large);
cursor: pointer;
position: relative;
&.active {
animation: left-shift-animation .25s $swift-ease-out-function;
background: $color-background;
border-bottom-color: $color-border-light;
border-left-color: $color-woot;
border-top-color: $color-border-light;
.conversation--details {
border-top-color: transparent;
}
+.conversation .conversation--details {
border-top-color: transparent;
}
background: var(--color-background);
}
&:first-child {
.conversation--details {
border-top-color: transparent;
}
}
&:last-child {
.conversation--details {
border-bottom-color: $color-border-light;
}
}
.conversation--details {
@include margin(0 0 0 $space-one);
@include border-light-bottom;
@include border-light-top;
@include padding($space-slab 0);
border-bottom-color: transparent;
@include margin(0 0 0 $space-small);
@include padding($space-small 0);
}
.conversation--user {
@ -84,41 +58,8 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 27rem;
}
.conversation--meta {
@include flex;
flex-direction: column;
position: absolute;
right: $space-normal;
top: $space-normal;
.unread {
$unread-size: $space-normal;
@include round-corner;
@include light-shadow;
background: darken($success-color, 3%);
color: $color-white;
display: none;
font-size: $font-size-micro;
font-weight: $font-weight-black;
height: $unread-size;
line-height: $unread-size;
margin-left: auto;
margin-top: $space-smaller;
min-width: $unread-size;
padding: 0 $space-smaller;
text-align: center;
}
.timestamp {
color: $dark-gray;
font-size: $font-size-micro;
font-weight: $font-weight-normal;
line-height: $space-normal;
margin-left: auto;
}
width: auto;
flex-grow: 0;
}
&.unread-chat {

View file

@ -86,11 +86,6 @@
align-items: center;
justify-content: space-between;
.page-title {
margin-bottom: $zero;
margin-left: $space-normal;
}
.status--filter {
@include padding($zero null $zero $space-normal);
@include margin($zero);

View file

@ -6,22 +6,7 @@
border-top-width: 0;
}
// Tab chat type
.tab--chat-type {
@include flex;
.tabs-title {
a {
font-size: $font-size-default;
font-weight: $font-weight-medium;
padding-bottom: $space-slab;
padding-top: $space-slab;
}
}
}
.tabs-title {
@include margin($zero $space-slab);
.badge {
background: $color-background;
@ -33,36 +18,18 @@
padding: $space-smaller;
}
&:first-child {
margin-left: 0;
}
&:last-child {
margin-right: 0;
}
&:hover,
&:focus {
a {
color: darken($medium-gray, 20%);
}
}
a {
a,
.button {
@include position(relative, 1px null null null);
align-items: center;
border-bottom: 2px solid transparent;
color: $medium-gray;
display: flex;
flex-direction: row;
font-size: $font-size-small;
transition: border-color .15s $swift-ease-out-function;
}
&.is-active {
a {
a,
.button {
border-bottom-color: $color-woot;
color: $color-woot;
}
.badge {
@ -70,4 +37,21 @@
color: $color-woot;
}
}
// Sleek tabs
&.smooth {
a,
.button {
border-bottom: 0;
top: 0;
}
&.is-active {
.badge {
background: var(--s-100);
color: var(--s-600);
}
}
}
}

View file

@ -2,7 +2,7 @@ l<template>
<div class="conversations-list-wrap">
<slot></slot>
<div class="chat-list__top" :class="{ filter__applied: hasAppliedFilters }">
<h1 class="page-title text-truncate" :title="pageTitle">
<h1 class="page-sub-title text-truncate" :title="pageTitle">
{{ pageTitle }}
</h1>
@ -36,7 +36,6 @@ l<template>
v-if="!hasAppliedFilters"
:items="assigneeTabItems"
:active-tab="activeAssigneeTab"
class="tab--chat-type"
@chatTabChange="updateAssigneeTab"
/>
@ -382,7 +381,7 @@ export default {
width: 35rem;
}
@include breakpoint(xxlarge up) {
width: 38rem;
width: 36rem;
}
@include breakpoint(xxxlarge up) {
flex-basis: 46rem;
@ -407,4 +406,8 @@ export default {
padding: var(--space-slab) 0 !important;
border-bottom: 1px solid var(--color-border);
}
.page-sub-title {
margin-left: var(--space-normal);
}
</style>

View file

@ -73,9 +73,6 @@ export default {
};
</script>
<style lang="scss" scoped>
$badge-size: var(--space-normal);
$label-badge-size: var(--space-slab);
.button {
margin: var(--space-small) 0;
}
@ -114,32 +111,4 @@ $label-badge-size: var(--space-slab);
.inbox-icon {
font-size: var(--font-size-nano);
}
.badge--label,
.badge--icon {
display: inline-flex;
border-radius: var(--border-radius-small);
margin-right: var(--space-smaller);
background: var(--s-100);
}
.badge--icon {
align-items: center;
height: $badge-size;
justify-content: center;
min-width: $badge-size;
}
.badge--label {
height: $label-badge-size;
min-width: $label-badge-size;
margin-left: var(--space-smaller);
}
.badge.secondary {
min-width: unset;
background: var(--s-75);
color: var(--s-600);
font-weight: var(--font-weight-bold);
}
</style>

View file

@ -116,7 +116,7 @@ export default {
}
.secondary-menu--title {
color: var(--s-600);
color: var(--s-700);
display: flex;
font-weight: var(--font-weight-bold);
line-height: var(--space-two);

View file

@ -3,14 +3,21 @@
:class="{
'tabs-title': true,
'is-active': active,
[variant]: variant,
}"
>
<a @click="onTabClick">
<woot-button
:size="size"
:variant="buttonVariant"
:color-scheme="colorScheme"
:is-rounded="isRounded"
@click="onTabClick"
>
{{ name }}
<span v-if="showBadge" class="badge">
{{ getItemCount }}
</span>
</a>
</woot-button>
</li>
</template>
<script>
@ -39,6 +46,15 @@ export default {
type: Boolean,
default: true,
},
variant: {
type: String,
default: '',
// Available variants: [ '', 'smooth']
},
size: {
type: String,
default: '',
},
},
data() {
@ -55,6 +71,17 @@ export default {
getItemCount() {
return this.animatedNumber || this.count;
},
colorScheme() {
if (this.variant === 'smooth') return 'secondary';
return this.active ? '' : 'secondary';
},
buttonVariant() {
if (this.variant === 'smooth') return this.active ? 'smooth' : 'clear';
return 'clear';
},
isRounded() {
return this.variant === 'smooth';
},
},
watch: {

View file

@ -64,6 +64,10 @@ export default {
type: Boolean,
default: false,
},
isRounded: {
type: Boolean,
default: true,
},
},
computed: {
variantClasses() {
@ -86,6 +90,7 @@ export default {
this.classNames,
this.isDisabled ? 'disabled' : '',
this.isExpanded ? 'expanded' : '',
this.isRounded ? '' : 'not-rounded',
];
},
},

View file

@ -1,10 +1,12 @@
<template>
<woot-tabs :index="activeTabIndex" @change="onTabChange">
<woot-tabs class="smooth" :index="activeTabIndex" @change="onTabChange">
<woot-tabs-item
v-for="item in items"
:key="item.key"
:name="item.name"
:count="item.count"
variant="smooth"
size="small"
/>
</woot-tabs>
</template>
@ -48,3 +50,8 @@ export default {
},
};
</script>
<style lang="scss" scoped>
.smooth {
padding-bottom: var(--space-small);
}
</style>

View file

@ -1,8 +1,10 @@
<template>
<div class="inbox--name">
<fluent-icon class="inbox--icon" :icon="computedInboxClass" size="12" />
{{ inbox.name }}
</div>
<woot-label
:title="inbox.name"
:icon="computedInboxClass"
color-scheme="primary"
small
/>
</template>
<script>
import { getInboxClassByType } from 'dashboard/helper/inbox';

View file

@ -18,64 +18,80 @@
size="40px"
/>
<div class="conversation--details columns">
<div class="conversation--metadata">
<inbox-name v-if="showInboxName" :inbox="inbox" />
<span
v-if="showAssignee && assignee.name"
class="label assignee-label text-truncate"
>
<fluent-icon icon="person" size="12" />
{{ assignee.name }}
</span>
</div>
<h4 class="conversation--user">
{{ currentContact.name }}
</h4>
<p v-if="lastMessageInChat" class="conversation--message">
<fluent-icon
v-if="isMessagePrivate"
size="16"
class="message--attachment-icon last-message-icon"
icon="lock-closed"
/>
<fluent-icon
v-else-if="messageByAgent"
size="16"
class="message--attachment-icon last-message-icon"
icon="arrow-reply"
/>
<fluent-icon
v-else-if="isMessageAnActivity"
size="16"
class="message--attachment-icon last-message-icon"
icon="info"
/>
<span v-if="lastMessageInChat.content">
{{ parsedLastMessage }}
</span>
<span v-else-if="lastMessageInChat.attachments">
<fluent-icon
size="16"
class="message--attachment-icon"
:icon="attachmentIcon"
<div class="details-meta">
<h4 class="conversation--user">
{{ currentContact.name }}
</h4>
<div class="conversation--metadata">
<span
v-if="showInboxName"
:class="computedInboxClass"
class="badge small secondary badge--icon"
>
<fluent-icon
class="svg-icon"
:icon="computedInboxClass"
size="12"
/>
</span>
<thumbnail
v-if="showAssignee && assignee.name"
class="assignee-avatar"
:src="assignee.thumbnail"
:username="assignee.name"
size="16px"
/>
{{ this.$t(`${attachmentMessageContent}`) }}
</div>
</div>
<div class="message-details">
<span v-if="unreadCount" class="unread small badge success">
{{ unreadCount > 9 ? '9+' : unreadCount }}
</span>
<span v-else>
{{ $t('CHAT_LIST.NO_CONTENT') }}
</span>
</p>
<p v-else class="conversation--message">
<fluent-icon size="16" class="message--attachment-icon" icon="info" />
<span>
{{ this.$t(`CHAT_LIST.NO_MESSAGES`) }}
</span>
</p>
<div class="conversation--meta">
<span class="timestamp">
{{ dynamicTime(chat.timestamp) }}
</span>
<span class="unread">{{ unreadCount > 9 ? '9+' : unreadCount }}</span>
<p v-if="lastMessageInChat" class="conversation--message">
<fluent-icon
v-if="isMessagePrivate"
size="16"
class="message--attachment-icon last-message-icon"
icon="lock-closed"
/>
<fluent-icon
v-else-if="messageByAgent"
size="16"
class="message--attachment-icon last-message-icon"
icon="arrow-reply"
/>
<fluent-icon
v-else-if="isMessageAnActivity"
size="16"
class="message--attachment-icon last-message-icon"
icon="info"
/>
<span v-if="lastMessageInChat.content">
{{ parsedLastMessage }}
</span>
<span v-else-if="lastMessageInChat.attachments">
<fluent-icon
size="16"
class="message--attachment-icon"
:icon="attachmentIcon"
/>
{{ this.$t(`${attachmentMessageContent}`) }}
</span>
<span v-else>
{{ $t('CHAT_LIST.NO_CONTENT') }}
</span>
</p>
<p v-else class="conversation--message">
<fluent-icon size="16" class="message--attachment-icon" icon="info" />
<span>
{{ this.$t(`CHAT_LIST.NO_MESSAGES`) }}
</span>
</p>
<div class="conversation--meta">
<span class="timestamp">
{{ dynamicTime(chat.timestamp) }}
</span>
</div>
</div>
</div>
</div>
@ -83,6 +99,7 @@
<script>
import { mapGetters } from 'vuex';
import { MESSAGE_TYPE } from 'widget/helpers/constants';
import { getInboxClassByType } from 'dashboard/helper/inbox';
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';
import Thumbnail from '../Thumbnail';
import conversationMixin from '../../../mixins/conversations';
@ -229,10 +246,22 @@ export default {
this.inboxesList.length > 1
);
},
inboxName() {
const stateInbox = this.inbox;
return stateInbox.name || '';
},
inboxChannelType() {
const { channel_type: type } = this.inbox;
return `badge--${type}`;
},
computedInboxClass() {
const { phone_number: phoneNumber, channel_type: type } = this.inbox;
const classByType = getInboxClassByType(type, phoneNumber);
return classByType;
},
},
methods: {
cardClick(chat) {
@ -258,13 +287,38 @@ export default {
}
}
.has-inbox-name {
&::v-deep .user-thumbnail-box {
margin-top: var(--space-normal);
align-items: flex-start;
.conversation--meta {
display: flex;
flex-grow: 1;
flex-shrink: 0;
align-items: center;
justify-content: space-between;
.timestamp {
color: var(--s-600);
font-size: var(--font-size-micro);
font-weight: var(--font-weight-normal);
line-height: var(--space-normal);
margin-left: var(--space-small);
}
.conversation--meta {
margin-top: var(--space-normal);
}
.details-meta {
display: flex;
justify-content: space-between;
}
.message-details {
display: flex;
align-items: center;
.badge {
color: var(--white);
/* margin-left: var(--space-medium); */
margin-right: var(--space-smaller);
}
}
.badge {
&.globe-desktop {
}
}
@ -274,7 +328,7 @@ export default {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 60%;
width: 90%;
}
}
@ -284,8 +338,9 @@ export default {
.conversation--metadata {
display: flex;
justify-content: space-between;
padding-right: var(--space-normal);
justify-content: flex-end;
align-items: center;
margin-left: var(--space-normal);
.label {
background: none;
@ -296,9 +351,8 @@ export default {
padding: var(--space-micro) 0 var(--space-micro) 0;
}
.assignee-label {
display: inline-flex;
max-width: 50%;
.assignee-avatar {
margin-left: var(--space-micro);
}
}

View file

@ -164,7 +164,7 @@ export default {
.user--name {
display: inline-block;
font-size: var(--font-size-medium);
line-height: 1.3;
line-height: 1.2;
margin: 0;
text-transform: capitalize;
width: 100%;
@ -174,6 +174,7 @@ export default {
align-items: center;
display: flex;
font-size: var(--font-size-mini);
padding-top: var(--space-smaller);
.user--profile__button {
padding: 0;