Updates sidebar on dashboard
This commit is contained in:
@@ -10,8 +10,8 @@ class ConversationApi extends ApiClient {
|
|||||||
return axios.get(`${this.url}/${conversationID}/labels`);
|
return axios.get(`${this.url}/${conversationID}/labels`);
|
||||||
}
|
}
|
||||||
|
|
||||||
createLabels(conversationID) {
|
updateLabels(conversationID, labels) {
|
||||||
return axios.get(`${this.url}/${conversationID}/labels`);
|
return axios.post(`${this.url}/${conversationID}/labels`, { labels });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@import '~widget/assets/scss/mixins';
|
||||||
|
|
||||||
//borders
|
//borders
|
||||||
@mixin border-nil() {
|
@mixin border-nil() {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
@@ -139,7 +141,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@mixin elegent-shadow() {
|
@mixin elegent-shadow() {
|
||||||
box-shadow: 0 10px 25px 0 rgba(49,49,93,0.15);
|
box-shadow: 0 10px 25px 0 rgba(49, 49, 93, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin elegant-card() {
|
@mixin elegant-card() {
|
||||||
@@ -181,41 +183,55 @@
|
|||||||
// .element{
|
// .element{
|
||||||
// @include arrow(top, #000, 50px);
|
// @include arrow(top, #000, 50px);
|
||||||
// }
|
// }
|
||||||
@mixin arrow($direction, $color, $size){
|
@mixin arrow($direction, $color, $size) {
|
||||||
display: block;
|
display: block;
|
||||||
height: 0;
|
height: 0;
|
||||||
width: 0;
|
width: 0;
|
||||||
content: '';
|
content: '';
|
||||||
|
|
||||||
@if $direction == 'top' {
|
@if $direction=='top' {
|
||||||
border-left: $size solid transparent;
|
border-left: $size solid transparent;
|
||||||
border-right: $size solid transparent;
|
border-right: $size solid transparent;
|
||||||
border-bottom: $size solid $color;
|
border-bottom: $size solid $color;
|
||||||
} @else if $direction == 'right' {
|
}
|
||||||
border-top: $size solid transparent;
|
|
||||||
border-bottom: $size solid transparent;
|
@else if $direction=='right' {
|
||||||
border-left: $size solid $color;
|
border-top: $size solid transparent;
|
||||||
} @else if $direction == 'bottom' {
|
border-bottom: $size solid transparent;
|
||||||
border-top: $size solid $color;
|
border-left: $size solid $color;
|
||||||
border-right: $size solid transparent;
|
}
|
||||||
border-left: $size solid transparent;
|
|
||||||
} @else if $direction == 'left' {
|
@else if $direction=='bottom' {
|
||||||
border-top: $size solid transparent;
|
border-top: $size solid $color;
|
||||||
border-right: $size solid $color;
|
border-right: $size solid transparent;
|
||||||
border-bottom: $size solid transparent;
|
border-left: $size solid transparent;
|
||||||
} @else if $direction == 'top-left' {
|
}
|
||||||
border-top: $size solid $color;
|
|
||||||
border-right: $size solid transparent;
|
@else if $direction=='left' {
|
||||||
} @else if $direction == 'top-right' {
|
border-top: $size solid transparent;
|
||||||
border-top: $size solid $color;
|
border-right: $size solid $color;
|
||||||
border-left: $size solid transparent;
|
border-bottom: $size solid transparent;
|
||||||
} @else if $direction == 'bottom-left' {
|
}
|
||||||
border-bottom: $size solid $color;
|
|
||||||
border-right: $size solid transparent;
|
@else if $direction=='top-left' {
|
||||||
} @else if $direction == 'bottom-right' {
|
border-top: $size solid $color;
|
||||||
border-bottom: $size solid $color;
|
border-right: $size solid transparent;
|
||||||
border-left: $size solid transparent;
|
}
|
||||||
}
|
|
||||||
|
@else if $direction=='top-right' {
|
||||||
|
border-top: $size solid $color;
|
||||||
|
border-left: $size solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $direction=='bottom-left' {
|
||||||
|
border-bottom: $size solid $color;
|
||||||
|
border-right: $size solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $direction=='bottom-right' {
|
||||||
|
border-bottom: $size solid $color;
|
||||||
|
border-left: $size solid transparent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin text-ellipsis {
|
@mixin text-ellipsis {
|
||||||
|
|||||||
@@ -53,6 +53,16 @@ $color-body: #3C4858;
|
|||||||
$color-heading: #1F2D3D;
|
$color-heading: #1F2D3D;
|
||||||
$color-extra-light-blue: #F5F7F9;
|
$color-extra-light-blue: #F5F7F9;
|
||||||
|
|
||||||
|
$primary-color: $color-woot;
|
||||||
|
$secondary-color: #FF5216;
|
||||||
|
$success-color: #13ce66;
|
||||||
|
$warning-color: #ffc82c;
|
||||||
|
$alert-color: #ff4949;
|
||||||
|
|
||||||
|
// Color-palettes
|
||||||
|
|
||||||
|
$color-primary-dark: darken($color-woot, 20%);
|
||||||
|
|
||||||
// Thumbnail
|
// Thumbnail
|
||||||
$thumbnail-radius: 4rem;
|
$thumbnail-radius: 4rem;
|
||||||
|
|
||||||
@@ -81,3 +91,6 @@ $swift-ease-out: all $swift-ease-out-duration $swift-ease-out-timing-function !d
|
|||||||
|
|
||||||
// Ionicons
|
// Ionicons
|
||||||
$ionicons-font-path: '~ionicons/fonts';
|
$ionicons-font-path: '~ionicons/fonts';
|
||||||
|
|
||||||
|
// Transitions
|
||||||
|
$transition-ease-in: all 0.250s ease-in;
|
||||||
|
|||||||
@@ -2,7 +2,13 @@
|
|||||||
margin-bottom: $space-normal;
|
margin-bottom: $space-normal;
|
||||||
min-height: 38px;
|
min-height: 38px;
|
||||||
|
|
||||||
> .multiselect__tags {
|
&.multiselect--active {
|
||||||
|
>.multiselect__tags {
|
||||||
|
border-color: $color-woot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
>.multiselect__tags {
|
||||||
@include margin(0);
|
@include margin(0);
|
||||||
border: 1px solid $color-border;
|
border: 1px solid $color-border;
|
||||||
min-height: 44px;
|
min-height: 44px;
|
||||||
@@ -13,12 +19,34 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.multiselect__tag {
|
.multiselect__tag {
|
||||||
|
|
||||||
|
$vertical-space: $space-smaller+$space-micro;
|
||||||
margin-top: $space-one;
|
margin-top: $space-one;
|
||||||
|
background: $color-background;
|
||||||
|
color: $color-heading;
|
||||||
|
padding: $vertical-space $space-medium $vertical-space $space-one;
|
||||||
|
}
|
||||||
|
|
||||||
|
.multiselect__tag-icon {
|
||||||
|
line-height: $space-medium + $space-micro;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
color: $color-primary-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $color-background;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
color: $color-woot;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.multiselect__input {
|
.multiselect__input {
|
||||||
@include ghost-input;
|
@include ghost-input;
|
||||||
@include padding($zero);
|
@include padding($zero);
|
||||||
|
font-size: $font-size-small;
|
||||||
|
|
||||||
margin-bottom: $zero;
|
margin-bottom: $zero;
|
||||||
}
|
}
|
||||||
@@ -41,4 +69,50 @@
|
|||||||
top: 60%;
|
top: 60%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.multiselect__content .multiselect__option {
|
||||||
|
font-size: $font-size-small;
|
||||||
|
font-weight: $font-weight-normal;
|
||||||
|
|
||||||
|
&.multiselect__option--highlight {
|
||||||
|
font-weight: $font-weight-medium;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.sidebar-labels-wrap {
|
||||||
|
|
||||||
|
&.has-edited,
|
||||||
|
&:hover {
|
||||||
|
.multiselect {
|
||||||
|
cursor: pointer;
|
||||||
|
margin-top: $space-small;
|
||||||
|
|
||||||
|
>.multiselect__tags {
|
||||||
|
border-color: $color-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
>.multiselect__select {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.multiselect {
|
||||||
|
|
||||||
|
>.multiselect__select {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
>.multiselect__tags {
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.multiselect--active {
|
||||||
|
>.multiselect__tags {
|
||||||
|
border-color: $color-woot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .icon {
|
>.icon {
|
||||||
font-size: $font-size-default;
|
font-size: $font-size-default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.tiny {
|
||||||
|
font-size: $font-size-mini;
|
||||||
|
padding: $space-small $space-slab;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.round {
|
||||||
|
border-radius: $space-larger;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.button--fixed-right-top {
|
.button--fixed-right-top {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
@include flex;
|
@include flex;
|
||||||
@include flex-align($x: justify, $y: middle);
|
@include flex-align($x: justify, $y: middle);
|
||||||
@include border-normal-bottom;
|
@include border-normal-bottom;
|
||||||
|
|
||||||
// Resolve Button
|
// Resolve Button
|
||||||
.button {
|
.button {
|
||||||
@include margin(0);
|
@include margin(0);
|
||||||
@@ -44,6 +45,7 @@
|
|||||||
.user--name {
|
.user--name {
|
||||||
@include margin(0);
|
@include margin(0);
|
||||||
font-size: $font-size-medium;
|
font-size: $font-size-medium;
|
||||||
|
text-transform: capitalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user--profile__meta {
|
.user--profile__meta {
|
||||||
@@ -64,7 +66,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.button.resolve--button {
|
.button.resolve--button {
|
||||||
> .icon {
|
>.icon {
|
||||||
padding-right: $space-small;
|
padding-right: $space-small;
|
||||||
font-size: $font-size-default;
|
font-size: $font-size-default;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,16 +47,19 @@
|
|||||||
@include background-gray;
|
@include background-gray;
|
||||||
@include margin(0);
|
@include margin(0);
|
||||||
@include border-normal-left;
|
@include border-normal-left;
|
||||||
|
|
||||||
.current-chat {
|
.current-chat {
|
||||||
@include flex;
|
@include flex;
|
||||||
@include full-height;
|
@include full-height;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@include flex-align(center, middle);
|
@include flex-align(center, middle);
|
||||||
|
|
||||||
div {
|
div {
|
||||||
@include flex;
|
@include flex;
|
||||||
@include full-height;
|
@include full-height;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@include flex-align(center, middle);
|
@include flex-align(center, middle);
|
||||||
|
|
||||||
img {
|
img {
|
||||||
@include margin($space-normal);
|
@include margin($space-normal);
|
||||||
width: 10rem;
|
width: 10rem;
|
||||||
@@ -87,7 +90,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
|
||||||
> li {
|
>li {
|
||||||
@include flex;
|
@include flex;
|
||||||
@include flex-shrink;
|
@include flex-shrink;
|
||||||
@include margin($zero $zero $space-smaller);
|
@include margin($zero $zero $space-smaller);
|
||||||
@@ -147,7 +150,7 @@
|
|||||||
@include flex-align(right, null);
|
@include flex-align(right, null);
|
||||||
|
|
||||||
.wrap {
|
.wrap {
|
||||||
margin-right: $space-small;
|
margin-right: $space-normal;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
.tabs-title {
|
.tabs-title {
|
||||||
a {
|
a {
|
||||||
font-size: $font-size-default;
|
font-size: $font-size-default;
|
||||||
|
font-weight: $font-weight-medium;
|
||||||
padding-bottom: $space-slab;
|
padding-bottom: $space-slab;
|
||||||
padding-top: $space-slab;
|
padding-top: $space-slab;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
src="~dashboard/assets/images/fb-badge.png"
|
src="~dashboard/assets/images/fb-badge.png"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
v-else-if="badge === 'Channel::WebWidget' && status === 'online'"
|
v-else-if="status === 'online'"
|
||||||
class="source-badge user--online"
|
class="source-badge user--online"
|
||||||
:style="statusStyle"
|
:style="statusStyle"
|
||||||
></div>
|
></div>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
:username="chat.meta.sender.name"
|
:username="chat.meta.sender.name"
|
||||||
/>
|
/>
|
||||||
<div class="user--profile__meta">
|
<div class="user--profile__meta">
|
||||||
<h3 v-if="!isContactPanelOpen" class="user--name text-truncate">
|
<h3 class="user--name text-truncate">
|
||||||
{{ chat.meta.sender.name }}
|
{{ chat.meta.sender.name }}
|
||||||
</h3>
|
</h3>
|
||||||
<button
|
<button
|
||||||
@@ -93,7 +93,9 @@ export default {
|
|||||||
];
|
];
|
||||||
},
|
},
|
||||||
viewProfileButtonLabel() {
|
viewProfileButtonLabel() {
|
||||||
return `${this.isContactPanelOpen ? 'Hide' : 'View'} Profile`;
|
return `${
|
||||||
|
this.isContactPanelOpen ? 'Close' : 'Open'
|
||||||
|
} Conversation Details`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"CONTACT_PANEL": {
|
"CONTACT_PANEL": {
|
||||||
|
"CONVERSATION_TITLE": "Conversation Details",
|
||||||
"BROWSER": "Browser",
|
"BROWSER": "Browser",
|
||||||
"OS": "Operating System",
|
"OS": "Operating System",
|
||||||
"INITIATED_FROM": "Initiated from",
|
"INITIATED_FROM": "Initiated from",
|
||||||
@@ -10,7 +11,10 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"NO_RECORDS_FOUND": "There are no labels associated to this conversation.",
|
"NO_RECORDS_FOUND": "There are no labels associated to this conversation.",
|
||||||
"TITLE": "Labels"
|
"TITLE": "Conversation Labels",
|
||||||
|
"UPDATE_BUTTON": "Update Labels",
|
||||||
|
"ADD_BUTTON": "Add Labels",
|
||||||
|
"UPDATE_ERROR": "Couldn't update labels, try Again 🧐"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="contact-conversation--panel">
|
<div class="contact-conversation--panel">
|
||||||
<contact-details-item
|
<contact-details-item :title="$t('CONTACT_PANEL.CONVERSATIONS.TITLE')" />
|
||||||
icon="ion-chatbubbles"
|
|
||||||
:title="$t('CONTACT_PANEL.CONVERSATIONS.TITLE')"
|
|
||||||
/>
|
|
||||||
<div v-if="!uiFlags.isFetching">
|
<div v-if="!uiFlags.isFetching">
|
||||||
<i v-if="!previousConversations.length">
|
<p v-if="!previousConversations.length" class="no-results">
|
||||||
{{ $t('CONTACT_PANEL.CONVERSATIONS.NO_RECORDS_FOUND') }}
|
{{ $t('CONTACT_PANEL.CONVERSATIONS.NO_RECORDS_FOUND') }}
|
||||||
</i>
|
</p>
|
||||||
<div v-else class="contact-conversation--list">
|
<div v-else class="contact-conversation--list">
|
||||||
<conversation-card
|
<conversation-card
|
||||||
v-for="conversation in previousConversations"
|
v-for="conversation in previousConversations"
|
||||||
@@ -78,11 +75,17 @@ export default {
|
|||||||
@import '~dashboard/assets/scss/mixins';
|
@import '~dashboard/assets/scss/mixins';
|
||||||
|
|
||||||
.contact-conversation--panel {
|
.contact-conversation--panel {
|
||||||
@include border-normal-top;
|
padding: $space-normal;
|
||||||
padding: $space-medium;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-conversation--list {
|
.contact-conversation--list {
|
||||||
margin-top: -$space-normal;
|
margin-top: $space-normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-results {
|
||||||
|
margin: 0;
|
||||||
|
color: $color-gray;
|
||||||
|
padding: 0 $space-small;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="conv-details--item">
|
<div class="conv-details--item">
|
||||||
<div class="conv-details--item__label">
|
<h4 class="conv-details--item__label">
|
||||||
<i :class="icon" class="conv-details--item__icon"></i>
|
<i :class="icon" class="conv-details--item__icon"></i>
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</div>
|
</h4>
|
||||||
<div v-if="value" class="conv-details--item__value">
|
<div v-if="value" class="conv-details--item__value">
|
||||||
{{ value }}
|
{{ value }}
|
||||||
</div>
|
</div>
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
title: { type: String, required: true },
|
title: { type: String, required: true },
|
||||||
icon: { type: String, required: true },
|
icon: { type: String, default: '' },
|
||||||
value: { type: [String, Number], default: '' },
|
value: { type: [String, Number], default: '' },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -32,16 +32,18 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.conv-details--item__icon {
|
.conv-details--item__icon {
|
||||||
padding-right: $space-micro;
|
padding-right: $space-smaller;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conv-details--item__label {
|
.conv-details--item__label {
|
||||||
font-weight: $font-weight-medium;
|
font-weight: $font-weight-medium;
|
||||||
margin-bottom: $space-micro;
|
margin-bottom: $space-micro;
|
||||||
|
font-size: $font-size-small;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conv-details--item__value {
|
.conv-details--item__value {
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
|
margin-top: $space-slab;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -48,6 +48,12 @@
|
|||||||
{{ contact.additional_attributes.description }}
|
{{ contact.additional_attributes.description }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<conversation-labels :conversation-id="conversationId" />
|
||||||
|
<contact-conversations
|
||||||
|
v-if="contact.id"
|
||||||
|
:contact-id="contact.id"
|
||||||
|
:conversation-id="conversationId"
|
||||||
|
/>
|
||||||
<div v-if="browser" class="conversation--details">
|
<div v-if="browser" class="conversation--details">
|
||||||
<contact-details-item
|
<contact-details-item
|
||||||
v-if="browser.browser_name"
|
v-if="browser.browser_name"
|
||||||
@@ -74,13 +80,6 @@
|
|||||||
icon="ion-clock"
|
icon="ion-clock"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<contact-conversations
|
|
||||||
v-if="contact.id"
|
|
||||||
:contact-id="contact.id"
|
|
||||||
:conversation-id="conversationId"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<conversation-labels :conversation-id="conversationId" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -169,9 +168,11 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.contact--profile {
|
.contact--profile {
|
||||||
width: 100%;
|
padding: $space-normal;
|
||||||
padding: $space-normal $space-medium $zero;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
margin: $space-medium $space-normal 0;
|
||||||
|
@include elegant-card;
|
||||||
|
@include light-shadow;
|
||||||
|
|
||||||
.user-thumbnail-box {
|
.user-thumbnail-box {
|
||||||
margin-right: $space-normal;
|
margin-right: $space-normal;
|
||||||
@@ -191,9 +192,10 @@ export default {
|
|||||||
|
|
||||||
.contact--name {
|
.contact--name {
|
||||||
@include text-ellipsis;
|
@include text-ellipsis;
|
||||||
|
text-transform: capitalize;
|
||||||
|
|
||||||
font-weight: $font-weight-bold;
|
font-weight: $font-weight-bold;
|
||||||
font-size: $font-size-default;
|
font-size: $font-size-medium;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact--email {
|
.contact--email {
|
||||||
@@ -210,8 +212,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.conversation--details {
|
.conversation--details {
|
||||||
padding: $space-medium;
|
padding: $space-two $space-normal;
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.conversation--labels {
|
.conversation--labels {
|
||||||
|
|||||||
@@ -1,21 +1,51 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="contact-conversation--panel">
|
<div
|
||||||
<contact-details-item
|
class="contact-conversation--panel sidebar-labels-wrap"
|
||||||
icon="ion-pricetags"
|
:class="hasEditedClass"
|
||||||
:title="$t('CONTACT_PANEL.LABELS.TITLE')"
|
>
|
||||||
/>
|
<div v-if="!conversationUiFlags.isFetching" class="wrap">
|
||||||
<div v-if="!uiFlags.isFetching">
|
<div class="contact-conversation--list">
|
||||||
<i v-if="!labels.length">
|
<label class="select-tags">
|
||||||
{{ $t('CONTACT_PANEL.LABELS.NO_RECORDS_FOUND') }}
|
{{ $t('CONTACT_PANEL.LABELS.TITLE') }}
|
||||||
</i>
|
<p v-if="!savedLabels.length && !showLabelInput" class="no-results">
|
||||||
<div v-else class="contact-conversation--list">
|
{{ $t('CONTACT_PANEL.LABELS.NO_RECORDS_FOUND') }}
|
||||||
<span
|
<button
|
||||||
v-for="label in labels"
|
type="button success"
|
||||||
:key="label"
|
class="button nice tiny"
|
||||||
class="conversation--label label primary"
|
@click="showLabelBox"
|
||||||
>
|
>
|
||||||
{{ label }}
|
{{ $t('CONTACT_PANEL.LABELS.ADD_BUTTON') }}
|
||||||
</span>
|
</button>
|
||||||
|
</p>
|
||||||
|
<multiselect
|
||||||
|
v-if="showLabelInput || savedLabels.length"
|
||||||
|
v-model="selectedLabels"
|
||||||
|
:options="savedLabels"
|
||||||
|
tag-placeholder="Add this as new tag"
|
||||||
|
placeholder="Search or add a tag"
|
||||||
|
:multiple="true"
|
||||||
|
:taggable="true"
|
||||||
|
@tag="addLabel"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<div class="row align-middle align-justify">
|
||||||
|
<span v-if="labelUiFlags.isError" class="error">{{
|
||||||
|
$t('CONTACT_PANEL.LABELS.UPDATE_ERROR')
|
||||||
|
}}</span>
|
||||||
|
<button
|
||||||
|
v-if="hasEdited"
|
||||||
|
type="button"
|
||||||
|
class="button nice tiny"
|
||||||
|
@click="onUpdateLabels"
|
||||||
|
>
|
||||||
|
<spinner v-if="labelUiFlags.isUpdating" size="tiny" />
|
||||||
|
{{
|
||||||
|
labelUiFlags.isUpdating
|
||||||
|
? 'saving...'
|
||||||
|
: $t('CONTACT_PANEL.LABELS.UPDATE_BUTTON')
|
||||||
|
}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<spinner v-else></spinner>
|
<spinner v-else></spinner>
|
||||||
@@ -24,12 +54,11 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import Spinner from 'shared/components/Spinner.vue';
|
import Spinner from 'shared/components/Spinner';
|
||||||
import ContactDetailsItem from './ContactDetailsItem.vue';
|
import ConversationAPI from '../../../api/conversations';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
ContactDetailsItem,
|
|
||||||
Spinner,
|
Spinner,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
@@ -38,25 +67,75 @@ export default {
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isSearching: false,
|
||||||
|
selectedLabels: [],
|
||||||
|
showLabelInput: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
labels() {
|
hasEdited() {
|
||||||
return this.$store.getters['conversationLabels/getConversationLabels'](
|
if (this.selectedLabels.length !== this.savedLabels.length) {
|
||||||
this.conversationId
|
return true;
|
||||||
|
}
|
||||||
|
const isSame = this.selectedLabels.every(label =>
|
||||||
|
this.savedLabels.includes(label)
|
||||||
);
|
);
|
||||||
|
return !isSame;
|
||||||
|
},
|
||||||
|
savedLabels() {
|
||||||
|
const saved = this.$store.getters[
|
||||||
|
'conversationLabels/getConversationLabels'
|
||||||
|
](this.conversationId);
|
||||||
|
return saved;
|
||||||
|
},
|
||||||
|
hasEditedClass() {
|
||||||
|
return this.hasEdited ? 'has-edited' : '';
|
||||||
},
|
},
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
uiFlags: 'contactConversations/getUIFlags',
|
conversationUiFlags: 'contactConversations/getUIFlags',
|
||||||
|
labelUiFlags: 'conversationLabels/getUIFlags',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
conversationId(newConversationId, prevConversationId) {
|
conversationId(newConversationId, prevConversationId) {
|
||||||
if (newConversationId && newConversationId !== prevConversationId) {
|
if (newConversationId && newConversationId !== prevConversationId) {
|
||||||
this.$store.dispatch('conversationLabels/get', newConversationId);
|
this.$store
|
||||||
|
.dispatch('conversationLabels/get', newConversationId)
|
||||||
|
.then(() => {
|
||||||
|
this.selectedLabels = [...this.savedLabels];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$store.dispatch('conversationLabels/get', this.conversationId);
|
this.$store
|
||||||
|
.dispatch('conversationLabels/get', this.conversationId)
|
||||||
|
.then(() => {
|
||||||
|
this.selectedLabels = [...this.savedLabels];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addLabel(label) {
|
||||||
|
this.selectedLabels = [...this.selectedLabels, label];
|
||||||
|
},
|
||||||
|
asyncSearchLabels(query) {
|
||||||
|
this.isSearching = true;
|
||||||
|
ConversationAPI(query).then(response => {
|
||||||
|
this.countries = response;
|
||||||
|
this.isLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onUpdateLabels() {
|
||||||
|
this.$store.dispatch('conversationLabels/update', {
|
||||||
|
conversationId: this.conversationId,
|
||||||
|
labels: this.selectedLabels,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
showLabelBox() {
|
||||||
|
this.showLabelInput = true;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@@ -66,12 +145,7 @@ export default {
|
|||||||
@import '~dashboard/assets/scss/mixins';
|
@import '~dashboard/assets/scss/mixins';
|
||||||
|
|
||||||
.contact-conversation--panel {
|
.contact-conversation--panel {
|
||||||
@include border-normal-top;
|
padding: $space-normal;
|
||||||
padding: $space-medium;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact-conversation--list {
|
|
||||||
margin-top: -$space-normal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.conversation--label {
|
.conversation--label {
|
||||||
@@ -80,4 +154,36 @@ export default {
|
|||||||
font-size: $font-size-small;
|
font-size: $font-size-small;
|
||||||
padding: $space-smaller;
|
padding: $space-smaller;
|
||||||
}
|
}
|
||||||
|
.wrap {
|
||||||
|
margin-top: $space-slab;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-tags {
|
||||||
|
margin-top: $space-small;
|
||||||
|
.multiselect {
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
transition: $transition-ease-in;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin-top: $space-small;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-results {
|
||||||
|
margin: $space-normal 0 0 0;
|
||||||
|
color: $color-gray;
|
||||||
|
padding: 0 $space-small;
|
||||||
|
font-weight: $font-weight-normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
color: $alert-color;
|
||||||
|
font-size: $font-size-mini;
|
||||||
|
font-weight: $font-weight-medium;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ const state = {
|
|||||||
records: {},
|
records: {},
|
||||||
uiFlags: {
|
uiFlags: {
|
||||||
isFetching: false,
|
isFetching: false,
|
||||||
|
isUpdating: false,
|
||||||
|
isError: false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -38,6 +40,30 @@ export const actions = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
update: async ({ commit }, { conversationId, labels }) => {
|
||||||
|
commit(types.default.SET_CONVERSATION_LABELS_UI_FLAG, {
|
||||||
|
isUpdating: true,
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
const response = await ConversationAPI.updateLabels(
|
||||||
|
conversationId,
|
||||||
|
labels
|
||||||
|
);
|
||||||
|
commit(types.default.SET_CONVERSATION_LABELS, {
|
||||||
|
id: conversationId,
|
||||||
|
data: response.data.payload,
|
||||||
|
});
|
||||||
|
commit(types.default.SET_CONVERSATION_LABELS_UI_FLAG, {
|
||||||
|
isUpdating: false,
|
||||||
|
isError: false,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
commit(types.default.SET_CONVERSATION_LABELS_UI_FLAG, {
|
||||||
|
isUpdating: false,
|
||||||
|
isError: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mutations = {
|
export const mutations = {
|
||||||
|
|||||||
@@ -1,7 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<span class="spinner small"></span>
|
<span class="spinner" :class="size"></span>
|
||||||
</template>
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
size: {
|
||||||
|
type: String,
|
||||||
|
default: 'small',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '~widget/assets/scss/variables';
|
@import '~widget/assets/scss/variables';
|
||||||
|
|
||||||
@@ -39,7 +48,7 @@
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|
||||||
&.message {
|
&.message {
|
||||||
padding: $space-normal;
|
padding: $space-one;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
@@ -63,5 +72,17 @@
|
|||||||
margin-top: -$space-small;
|
margin-top: -$space-small;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.tiny {
|
||||||
|
width: $space-one;
|
||||||
|
height: $space-one;
|
||||||
|
padding: 0 $space-smaller;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
width: $space-one;
|
||||||
|
height: $space-one;
|
||||||
|
margin-top: -$space-small + $space-micro;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// scss-lint:disable PseudoElement SpaceBeforeBrace VendorPrefix
|
// scss-lint:disable PseudoElement SpaceBeforeBrace VendorPrefix
|
||||||
$shadow-color-1: rgba(50, 50, 93, 0.2);
|
$shadow-color-1: rgba(50, 50, 93, 0.08);
|
||||||
$shadow-color-2: rgba(0, 0, 0, 0.07);
|
$shadow-color-2: rgba(0, 0, 0, 0.07);
|
||||||
$shadow-color-3: rgba(50, 50, 93, .08);
|
$shadow-color-3: rgba(50, 50, 93, .08);
|
||||||
$shadow-color-4: rgba(0, 0, 0, .05);
|
$shadow-color-4: rgba(0, 0, 0, .05);
|
||||||
|
|||||||
@@ -101,10 +101,10 @@ export const SDK_CSS = ` .woot-widget-holder {
|
|||||||
width: 400px !important;
|
width: 400px !important;
|
||||||
min-height: 250px !important;
|
min-height: 250px !important;
|
||||||
max-height: 590px !important;
|
max-height: 590px !important;
|
||||||
-o-border-radius: 8px !important;
|
-o-border-radius: 16px !important;
|
||||||
-moz-border-radius: 8px !important;
|
-moz-border-radius: 16px !important;
|
||||||
-webkit-border-radius: 8px !important;
|
-webkit-border-radius: 16px !important;
|
||||||
border-radius: 8px !important;
|
border-radius: 16px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
<Thumbnail
|
<Thumbnail
|
||||||
size="24px"
|
size="24px"
|
||||||
:username="user.name"
|
:username="user.name"
|
||||||
status="online"
|
|
||||||
:src="user.avatar"
|
:src="user.avatar"
|
||||||
has-border
|
has-border
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user