Feature: Add/Edit conversation labels (#488)

Co-authored-by: Pranav Raj S <pranavrajs@gmail.com>
This commit is contained in:
Nithin David Thomas 2020-02-16 15:46:26 +05:30 committed by GitHub
parent 77473dc2aa
commit e61ba95cf7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 863 additions and 323 deletions

View file

@ -1,7 +1,281 @@
# Default application configuration that all configurations inherit from.
scss_files: '**/*.scss'
plugin_directories: ['.scss-linters']
# List of gem names to load custom linters from (make sure they are already
# installed)
plugin_gems: []
# Default severity of all linters.
severity: warning
linters: linters:
BangFormat:
enabled: true
space_before_bang: true
space_after_bang: false
BemDepth:
enabled: false
max_elements: 1
BorderZero:
enabled: true
convention: zero # or `none`
ChainedClasses:
enabled: false
ColorKeyword:
enabled: true
ColorVariable:
enabled: true
Comment:
enabled: true
style: silent
DebugStatement:
enabled: true
DeclarationOrder:
enabled: true
DisableLinterReason:
enabled: false
DuplicateProperty:
enabled: true
ElsePlacement:
enabled: true
style: same_line # or 'new_line'
EmptyLineBetweenBlocks:
enabled: true
ignore_single_line_blocks: true
EmptyRule:
enabled: true
ExtendDirective:
enabled: false
FinalNewline:
enabled: true
present: true
HexLength:
enabled: true
style: short # or 'long'
HexNotation:
enabled: true
style: lowercase # or 'uppercase'
HexValidation:
enabled: true
IdSelector:
enabled: true
ImportantRule:
enabled: true
ImportPath:
enabled: true
leading_underscore: false
filename_extension: false
Indentation:
enabled: true
allow_non_nested_indentation: false
character: space # or 'tab'
width: 2
LeadingZero: LeadingZero:
enabled: false enabled: false
MergeableSelector:
enabled: true
force_nesting: true
NameFormat:
enabled: true
allow_leading_underscore: true
convention: hyphenated_lowercase # or 'camel_case', or 'snake_case', or a regex pattern
NestingDepth:
enabled: true
max_depth: 6
ignore_parent_selectors: false
PlaceholderInExtend:
enabled: true
PrivateNamingConvention:
enabled: false
prefix: _
PropertyCount:
enabled: false
include_nested: false
max_properties: 10
PropertySortOrder:
enabled: true
ignore_unspecified: false
min_properties: 2
separate_groups: false
PropertySpelling:
enabled: true
extra_properties: []
disabled_properties: []
PropertyUnits:
enabled: true
global: [
'ch',
'em',
'ex',
'rem', # Font-relative lengths
'cm',
'in',
'mm',
'pc',
'pt',
'px',
'q', # Absolute lengths
'vh',
'vw',
'vmin',
'vmax', # Viewport-percentage lengths
'fr', # Grid fractional lengths
'deg',
'grad',
'rad',
'turn', # Angle
'ms',
's', # Duration
'Hz',
'kHz', # Frequency
'dpi',
'dpcm',
'dppx', # Resolution
'%',
] # Other
properties: {}
PseudoElement:
enabled: true
QualifyingElement:
enabled: true
allow_element_with_attribute: false
allow_element_with_class: false
allow_element_with_id: false
SelectorDepth:
enabled: true
max_depth: 5
SelectorFormat:
enabled: false
Shorthand:
enabled: true
allowed_shorthands: [1, 2, 3, 4]
SingleLinePerProperty:
enabled: true
allow_single_line_rule_sets: true
SingleLinePerSelector:
enabled: true
SpaceAfterComma:
enabled: true
style: one_space # or 'no_space', or 'at_least_one_space'
SpaceAfterComment:
enabled: false
style: one_space # or 'no_space', or 'at_least_one_space'
allow_empty_comments: true
SpaceAfterPropertyColon:
enabled: true
style: one_space # or 'no_space', or 'at_least_one_space', or 'aligned'
SpaceAfterPropertyName:
enabled: true
SpaceAfterVariableColon:
enabled: false
style: one_space # or 'no_space', 'at_least_one_space' or 'one_space_or_newline'
SpaceAfterVariableName:
enabled: true
SpaceAroundOperator:
enabled: true
style: one_space # or 'at_least_one_space', or 'no_space'
SpaceBeforeBrace:
enabled: true
style: space # or 'new_line'
allow_single_line_padding: false
SpaceBetweenParens:
enabled: true
spaces: 0
StringQuotes:
enabled: true
style: single_quotes # or double_quotes
TrailingSemicolon:
enabled: true
TrailingWhitespace:
enabled: true
TrailingZero:
enabled: false
TransitionAll:
enabled: false
UnnecessaryMantissa:
enabled: true
UnnecessaryParentReference:
enabled: true
UrlFormat:
enabled: true
UrlQuotes:
enabled: true
VariableForProperty:
enabled: false
properties: []
VendorPrefix:
enabled: true
identifier_list: base
additional_identifiers: []
excluded_identifiers: []
ZeroUnit:
enabled: true
Compass::*:
enabled: false
exclude: exclude:
- 'app/javascript/widget/assets/scss/_reset.scss' - 'app/javascript/widget/assets/scss/_reset.scss'
- 'app/javascript/widget/assets/scss/sdk.css' - 'app/javascript/widget/assets/scss/sdk.css'

View file

@ -87,6 +87,7 @@ group :development do
end end
group :development, :test do group :development, :test do
# locking until https://github.com/codeclimate/test-reporter/issues/418 is resolved
gem 'action-cable-testing' gem 'action-cable-testing'
gem 'bundle-audit', require: false gem 'bundle-audit', require: false
gem 'byebug', platform: :mri gem 'byebug', platform: :mri
@ -100,9 +101,9 @@ group :development, :test do
gem 'rubocop-performance', require: false gem 'rubocop-performance', require: false
gem 'rubocop-rails', require: false gem 'rubocop-rails', require: false
gem 'rubocop-rspec', require: false gem 'rubocop-rspec', require: false
gem 'scss_lint', require: false
gem 'seed_dump' gem 'seed_dump'
gem 'shoulda-matchers' gem 'shoulda-matchers'
# locking until https://github.com/codeclimate/test-reporter/issues/418 is resolved
gem 'simplecov', '0.17.1', require: false gem 'simplecov', '0.17.1', require: false
gem 'spring' gem 'spring'
gem 'spring-watcher-listen' gem 'spring-watcher-listen'

View file

@ -393,8 +393,15 @@ GEM
rubocop-rspec (1.37.1) rubocop-rspec (1.37.1)
rubocop (>= 0.68.1) rubocop (>= 0.68.1)
ruby-progressbar (1.10.1) ruby-progressbar (1.10.1)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
scout_apm (2.6.6) scout_apm (2.6.6)
parser parser
scss_lint (0.59.0)
sass (~> 3.5, >= 3.5.5)
seed_dump (3.3.1) seed_dump (3.3.1)
activerecord (>= 4) activerecord (>= 4)
activesupport (>= 4) activesupport (>= 4)
@ -539,6 +546,7 @@ DEPENDENCIES
rubocop-rails rubocop-rails
rubocop-rspec rubocop-rspec
scout_apm scout_apm
scss_lint
seed_dump seed_dump
sentry-raven sentry-raven
shoulda-matchers shoulda-matchers

View file

@ -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 });
} }
} }

View file

@ -10,6 +10,6 @@ describe('#ConversationApi', () => {
expect(conversations).toHaveProperty('update'); expect(conversations).toHaveProperty('update');
expect(conversations).toHaveProperty('delete'); expect(conversations).toHaveProperty('delete');
expect(conversations).toHaveProperty('getLabels'); expect(conversations).toHaveProperty('getLabels');
expect(conversations).toHaveProperty('createLabels'); expect(conversations).toHaveProperty('updateLabels');
}); });
}); });

View file

@ -41,29 +41,34 @@
// 36. Tooltip // 36. Tooltip
// 37. Top Bar // 37. Top Bar
@import "~foundation-sites/scss/util/util"; @import '~foundation-sites/scss/util/util';
// 1. Global // 1. Global
// --------- // ---------
$global-font-size: 10px; $global-font-size: 10px;
$global-width: 100%; $global-width: 100%;
$global-lineheight: 1.5; $global-lineheight: 1.5;
$foundation-palette: ( $foundation-palette: (primary: $color-woot,
primary: $color-woot,
secondary: #777, secondary: #777,
success: #13ce66, success: #13ce66,
warning: #ffc82c, warning: #ffc82c,
alert: #ff4949 alert: #ff4949);
);
$light-gray: #c0ccda; $light-gray: #c0ccda;
$medium-gray: #8492a6; $medium-gray: #8492a6;
$dark-gray: $color-gray; $dark-gray: $color-gray;
$black: #000000; $black: #000;
$white: #fff; $white: #fff;
$body-background: $white; $body-background: $white;
$body-font-color: $color-body; $body-font-color: $color-body;
$body-font-family: 'Inter', -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", $body-font-family: 'Inter',
Roboto, "Helvetica Neue", Arial, sans-serif; -apple-system,
system-ui,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
"Helvetica Neue",
Arial,
sans-serif;
$body-antialiased: true; $body-antialiased: true;
$global-margin: $space-one; $global-margin: $space-one;
$global-padding: $space-one; $global-padding: $space-one;
@ -79,13 +84,11 @@ $print-transparent-backgrounds: true;
// 2. Breakpoints // 2. Breakpoints
// -------------- // --------------
$breakpoints: ( $breakpoints: (small: 0,
small: 0,
medium: 640px, medium: 640px,
large: 1024px, large: 1024px,
xlarge: 1200px, xlarge: 1200px,
xxlarge: 1440px xxlarge: 1440px);
);
$print-breakpoint: large; $print-breakpoint: large;
$breakpoint-classes: (small medium large); $breakpoint-classes: (small medium large);
@ -94,10 +97,8 @@ $breakpoint-classes: (small medium large);
$grid-row-width: $global-width; $grid-row-width: $global-width;
$grid-column-count: 12; $grid-column-count: 12;
$grid-column-gutter: ( $grid-column-gutter: (small: $zero,
small: $zero, medium: $zero);
medium: $zero
);
$grid-column-align-edge: true; $grid-column-align-edge: true;
$block-grid-max: 8; $block-grid-max: 8;
@ -105,54 +106,24 @@ $block-grid-max: 8;
// ------------------ // ------------------
$header-font-family: $body-font-family; $header-font-family: $body-font-family;
$header-font-weight: $global-weight-normal; $header-font-weight: $font-weight-medium;
$header-font-style: normal; $header-font-style: normal;
$font-family-monospace: $body-font-family; $font-family-monospace: $body-font-family;
$header-color: $color-heading; $header-color: $color-heading;
$header-lineheight: 1.4; $header-lineheight: 1.4;
$header-margin-bottom: 0.5rem; $header-margin-bottom: 0.5rem;
$header-styles: ( $header-styles: (small: ("h1": ("font-size": 24),
small: ( "h2": ("font-size": 20),
"h1": ( "h3": ("font-size": 19),
"font-size": 24 "h4": ("font-size": 18),
), "h5": ("font-size": 17),
"h2": ( "h6": ("font-size": 16)),
"font-size": 20 medium: ("h1": ("font-size": 48),
), "h2": ("font-size": 40),
"h3": ( "h3": ("font-size": 31),
"font-size": 19 "h4": ("font-size": 25),
), "h5": ("font-size": 20),
"h4": ( "h6": ("font-size": 16)));
"font-size": 18
),
"h5": (
"font-size": 17
),
"h6": (
"font-size": 16
)
),
medium: (
"h1": (
"font-size": 48
),
"h2": (
"font-size": 40
),
"h3": (
"font-size": 31
),
"h4": (
"font-size": 25
),
"h5": (
"font-size": 20
),
"h6": (
"font-size": 16
)
)
);
$header-text-rendering: optimizeLegibility; $header-text-rendering: optimizeLegibility;
$small-font-size: 80%; $small-font-size: 80%;
$header-small-font-color: $medium-gray; $header-small-font-color: $medium-gray;
@ -186,7 +157,7 @@ $blockquote-padding: rem-calc(9 20 0 19);
$blockquote-border: 1px solid $medium-gray; $blockquote-border: 1px solid $medium-gray;
$cite-font-size: rem-calc(13); $cite-font-size: rem-calc(13);
$cite-color: $dark-gray; $cite-color: $dark-gray;
$cite-pseudo-content: "\2014 \0020"; $cite-pseudo-content: '\2014 \0020';
$keystroke-font: $font-family-monospace; $keystroke-font: $font-family-monospace;
$keystroke-color: $black; $keystroke-color: $black;
$keystroke-background: $light-gray; $keystroke-background: $light-gray;
@ -272,24 +243,23 @@ $button-background-hover: scale-color($button-background, $lightness: -15%);
$button-color: $white; $button-color: $white;
$button-color-alt: $white; $button-color-alt: $white;
$button-radius: $global-radius; $button-radius: $global-radius;
$button-sizes: ( $button-sizes: (tiny: $font-size-micro,
tiny: $font-size-micro,
small: $font-size-mini, small: $font-size-mini,
default: $font-size-default, default: $font-size-default,
large: $font-size-large large: $font-size-large);
);
$button-palette: $foundation-palette; $button-palette: $foundation-palette;
$button-opacity-disabled: 0.25; $button-opacity-disabled: 0.25;
$button-background-hover-lightness: -20%; $button-background-hover-lightness: -20%;
$button-hollow-hover-lightness: -50%; $button-hollow-hover-lightness: -50%;
$button-transition: background-color 0.25s ease-out, color 0.25s ease-out; $button-transition: background-color 0.25s ease-out,
color 0.25s ease-out;
// 12. Button Group // 12. Button Group
// ---------------- // ----------------
$buttongroup-margin: 1rem; $buttongroup-margin: 1rem;
$buttongroup-spacing: 1px; $buttongroup-spacing: 1px;
$buttongroup-child-selector: ".button"; $buttongroup-child-selector: '.button';
$buttongroup-expand-max: 6; $buttongroup-expand-max: 6;
$buttongroup-radius-on-each: true; $buttongroup-radius-on-each: true;
@ -322,18 +292,12 @@ $card-margin: $global-margin;
// ---------------- // ----------------
$closebutton-position: right top; $closebutton-position: right top;
$closebutton-offset-horizontal: ( $closebutton-offset-horizontal: (small: 0.66rem,
small: 0.66rem, medium: 1rem);
medium: 1rem $closebutton-offset-vertical: (small: 0.33em,
); medium: 0.5rem);
$closebutton-offset-vertical: ( $closebutton-size: (small: 1.5em,
small: 0.33em, medium: 2em);
medium: 0.5rem
);
$closebutton-size: (
small: 1.5em,
medium: 2em
);
$closebutton-lineheight: 1; $closebutton-lineheight: 1;
$closebutton-color: $dark-gray; $closebutton-color: $dark-gray;
$closebutton-color-hover: $black; $closebutton-color-hover: $black;
@ -356,11 +320,9 @@ $dropdown-border: 1px solid $medium-gray;
$dropdown-font-size: 1rem; $dropdown-font-size: 1rem;
$dropdown-width: 300px; $dropdown-width: 300px;
$dropdown-radius: $global-radius; $dropdown-radius: $global-radius;
$dropdown-sizes: ( $dropdown-sizes: (tiny: 100px,
tiny: 100px,
small: 200px, small: 200px,
large: 400px large: 400px);
);
// 18. Dropdown Menu // 18. Dropdown Menu
// ----------------- // -----------------
@ -455,12 +417,10 @@ $meter-fill-bad: $alert-color;
// 24. Off-canvas // 24. Off-canvas
// -------------- // --------------
$offcanvas-sizes: ( $offcanvas-sizes: (small: 23rem,
small: 23rem,
medium: 23rem, medium: 23rem,
); );
$offcanvas-vertical-sizes: ( $offcanvas-vertical-sizes: (small: 23rem,
small: 23rem,
medium: 23rem, medium: 23rem,
); );
$offcanvas-background: $light-gray; $offcanvas-background: $light-gray;
@ -472,7 +432,7 @@ $offcanvas-transition-length: 0.5s;
$offcanvas-transition-timing: ease; $offcanvas-transition-timing: ease;
$offcanvas-fixed-reveal: true; $offcanvas-fixed-reveal: true;
$offcanvas-exit-background: rgba($white, 0.25); $offcanvas-exit-background: rgba($white, 0.25);
$maincontent-class: "off-canvas-content"; $maincontent-class: 'off-canvas-content';
// 25. Orbit // 25. Orbit
// --------- // ---------
@ -520,10 +480,8 @@ $progress-radius: $global-radius;
// -------------------- // --------------------
$responsive-embed-margin-bottom: rem-calc(16); $responsive-embed-margin-bottom: rem-calc(16);
$responsive-embed-ratios: ( $responsive-embed-ratios: (default: 4 by 3,
default: 4 by 3, widescreen: 16 by 9);
widescreen: 16 by 9
);
// 29. Reveal // 29. Reveal
// ---------- // ----------
@ -576,10 +534,8 @@ $table-border: 1px solid transparent;
$table-padding: rem-calc(8 10 10); $table-padding: rem-calc(8 10 10);
$table-hover-scale: 2%; $table-hover-scale: 2%;
$table-row-hover: darken($table-background, $table-hover-scale); $table-row-hover: darken($table-background, $table-hover-scale);
$table-row-stripe-hover: darken( $table-row-stripe-hover: darken($table-background,
$table-background, $table-color-scale + $table-hover-scale);
$table-color-scale + $table-hover-scale
);
$table-is-striped: false; $table-is-striped: false;
$table-striped-background: smart-scale($table-background, $table-color-scale); $table-striped-background: smart-scale($table-background, $table-color-scale);
$table-stripe: even; $table-stripe: even;

View file

@ -1,3 +1,8 @@
@import '~widget/assets/scss/mixins';
$elegant-shadow-color: rgba(49, 49, 93, 0.15);
$spinner-before-border-color: rgba(255, 255, 255, 0.7);
//borders //borders
@mixin border-nil() { @mixin border-nil() {
border-color: transparent; border-color: transparent;
@ -77,8 +82,8 @@
&:active, &:active,
&:hover, &:hover,
&:focus { &:focus {
box-shadow: none;
border-color: transparent; border-color: transparent;
box-shadow: none;
} }
} }
@ -117,7 +122,6 @@
// full height // full height
@mixin full-height() { @mixin full-height() {
height: 100%; height: 100%;
// COmmenting because unneccessary scroll is apprearing on some pages eg: settings/agents / inboxes
} }
@mixin round-corner() { @mixin round-corner() {
@ -139,7 +143,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 $elegant-shadow-color;
} }
@mixin elegant-card() { @mixin elegant-card() {
@ -154,20 +158,20 @@
} }
} }
&:before { &::before {
content: ''; animation: spinner .9s linear infinite;
border: 2px solid $spinner-before-border-color;
border-radius: 50%;
border-top-color: lighten($color-woot, 10%);
box-sizing: border-box; box-sizing: border-box;
content: '';
height: $space-medium;
left: 50%;
margin-left: -$space-one;
margin-top: -$space-one;
position: absolute; position: absolute;
top: 50%; top: 50%;
left: 50%;
width: $space-medium; width: $space-medium;
height: $space-medium;
margin-top: -$space-one;
margin-left: -$space-one;
border-radius: 50%;
border: 2px solid rgba(255, 255, 255, 0.7);
border-top-color: lighten($color-woot, 10%);
animation: spinner .9s linear infinite;
} }
} }
@ -181,41 +185,41 @@
// .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-bottom: $size solid $color;
border-right: $size solid transparent; border-left: $size solid transparent;
border-bottom: $size solid $color; border-right: $size solid transparent;
} @else if $direction == 'right' { } @else if $direction == 'right' {
border-top: $size solid transparent; border-bottom: $size solid transparent;
border-bottom: $size solid transparent; border-left: $size solid $color;
border-left: $size solid $color; border-top: $size solid transparent;
} @else if $direction == 'bottom' { } @else if $direction == 'bottom' {
border-top: $size solid $color; border-left: $size solid transparent;
border-right: $size solid transparent; border-right: $size solid transparent;
border-left: $size solid transparent; border-top: $size solid $color;
} @else if $direction == 'left' { } @else if $direction == 'left' {
border-top: $size solid transparent; border-bottom: $size solid transparent;
border-right: $size solid $color; border-right: $size solid $color;
border-bottom: $size solid transparent; border-top: $size solid transparent;
} @else if $direction == 'top-left' { } @else if $direction == 'top-left' {
border-top: $size solid $color; border-right: $size solid transparent;
border-right: $size solid transparent; border-top: $size solid $color;
} @else if $direction == 'top-right' { } @else if $direction == 'top-right' {
border-top: $size solid $color; border-left: $size solid transparent;
border-left: $size solid transparent; border-top: $size solid $color;
} @else if $direction == 'bottom-left' { } @else if $direction == 'bottom-left' {
border-bottom: $size solid $color; border-bottom: $size solid $color;
border-right: $size solid transparent; border-right: $size solid transparent;
} @else if $direction == 'bottom-right' { } @else if $direction == 'bottom-right' {
border-bottom: $size solid $color; border-bottom: $size solid $color;
border-left: $size solid transparent; border-left: $size solid transparent;
} }
} }
@mixin text-ellipsis { @mixin text-ellipsis {

View file

@ -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;

View file

@ -1,32 +1,24 @@
@mixin label-multiselect-hover {
&::after {
color: $color-primary-dark;
}
&:hover {
background: $color-background;
&::after {
color: $color-woot;
}
}
}
.multiselect { .multiselect {
margin-bottom: $space-normal; margin-bottom: $space-normal;
min-height: 38px; min-height: 38px;
> .multiselect__tags { &.multiselect--active {
@include margin(0); >.multiselect__tags {
border: 1px solid $color-border; border-color: $color-woot;
min-height: 44px;
padding-top: $zero;
.multiselect__placeholder {
padding-top: $space-small;
}
.multiselect__tag {
margin-top: $space-one;
}
.multiselect__input {
@include ghost-input;
@include padding($zero);
margin-bottom: $zero;
}
.multiselect__single {
@include padding($space-one);
margin-bottom: 0;
} }
} }
@ -41,4 +33,91 @@
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;
}
}
}
.multiselect>.multiselect__tags {
@include margin(0);
border: 1px solid $color-border;
min-height: 44px;
padding-top: $zero;
.multiselect__tags-wrap {
display: inline-block;
line-height: 1;
margin-top: $space-smaller;
}
.multiselect__placeholder {
padding-top: $space-small;
}
.multiselect__tag {
$vertical-space: $space-smaller + $space-micro;
background: $color-background;
color: $color-heading;
margin-top: $space-smaller;
padding: $vertical-space $space-medium $vertical-space $space-one;
}
.multiselect__tag-icon {
@include label-multiselect-hover;
line-height: $space-medium + $space-micro;
}
.multiselect__input {
@include ghost-input;
@include padding($zero);
font-size: $font-size-small;
margin-bottom: $zero;
}
.multiselect__single {
@include padding($space-one);
margin-bottom: 0;
}
}
.sidebar-labels-wrap {
&.has-edited,
&:hover {
.multiselect {
cursor: pointer;
}
.multiselect>.multiselect__tags {
border-color: $color-border;
}
.multiselect>.multiselect__select {
visibility: visible;
}
}
.multiselect {
margin-top: $space-small;
>.multiselect__select {
visibility: hidden;
}
>.multiselect__tags {
border-color: transparent;
}
&.multiselect--active>.multiselect__tags {
border-color: $color-woot;
}
}
} }

View file

@ -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 {

View file

@ -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;
} }

View file

@ -2,8 +2,8 @@
@include flex; @include flex;
@include flex-shrink; @include flex-shrink;
@include padding($space-normal $zero $zero $space-normal); @include padding($space-normal $zero $zero $space-normal);
position: relative;
cursor: pointer; cursor: pointer;
position: relative;
&.active { &.active {
background: $color-background; background: $color-background;
@ -18,63 +18,63 @@
.conversation--user { .conversation--user {
font-size: $font-size-small; font-size: $font-size-small;
margin-bottom: $zero; margin-bottom: $zero;
text-transform: capitalize;
.label { .label {
position: relative;
top: $space-micro;
left: $space-micro; left: $space-micro;
max-width: $space-jumbo; max-width: $space-jumbo;
overflow: hidden; overflow: hidden;
position: relative;
text-overflow: ellipsis; text-overflow: ellipsis;
top: $space-micro;
white-space: nowrap; white-space: nowrap;
} }
} }
.conversation--message { .conversation--message {
height: $space-medium;
margin: $zero;
font-size: $font-size-small;
line-height: $space-medium;
font-weight: $font-weight-light;
text-overflow: ellipsis;
overflow: hidden;
color: $color-body; color: $color-body;
width: 27rem; font-size: $font-size-small;
white-space: nowrap; font-weight: $font-weight-light;
height: $space-medium;
line-height: $space-medium;
margin: $zero;
max-width: 96%; max-width: 96%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 27rem;
} }
.conversation--meta { .conversation--meta {
@include flex;
display: block; display: block;
flex-direction: column;
position: absolute; position: absolute;
right: $space-normal; right: $space-normal;
top: $space-normal; top: $space-normal;
@include flex;
flex-direction: column;
.unread { .unread {
$unread-size: $space-two - $space-micro; $unread-size: $space-two - $space-micro;
display: none;
height: $unread-size;
min-width: $unread-size;
background: darken($success-color, 3%);
text-align: center;
padding: 0 $space-smaller;
line-height: $unread-size;
color: $color-white;
font-weight: $font-weight-medium;
font-size: $font-size-mini;
margin-left: auto;
@include round-corner; @include round-corner;
background: darken($success-color, 3%);
color: $color-white;
display: none;
font-size: $font-size-mini;
font-weight: $font-weight-medium;
height: $unread-size;
line-height: $unread-size;
margin-left: auto;
margin-top: $space-smaller; margin-top: $space-smaller;
min-width: $unread-size;
padding: 0 $space-smaller;
text-align: center;
} }
.timestamp { .timestamp {
font-size: $font-size-mini;
color: $dark-gray; color: $dark-gray;
line-height: $space-normal;
font-weight: $font-weight-normal;
font-size: $font-size-micro; font-size: $font-size-micro;
font-weight: $font-weight-normal;
line-height: $space-normal;
margin-left: auto; margin-left: auto;
} }
} }

View file

@ -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;
} }

View file

@ -1,10 +1,10 @@
.reply-box { .reply-box {
@include elegant-card;
border-bottom: 0;
margin: $space-normal; margin: $space-normal;
margin-top: 0; margin-top: 0;
border-bottom: 0;
@include elegant-card;
transition: height 2s $ease-in-out-cubic;
max-height: $space-jumbo * 2; max-height: $space-jumbo * 2;
transition: height 2s $ease-in-out-cubic;
.reply-box__top { .reply-box__top {
@include flex; @include flex;
@ -12,26 +12,25 @@
@include padding($space-one $space-normal); @include padding($space-one $space-normal);
@include background-white; @include background-white;
@include margin(0); @include margin(0);
position: relative;
border-top-left-radius: $space-small; border-top-left-radius: $space-small;
border-top-right-radius: $space-small; border-top-right-radius: $space-small;
position: relative;
.canned { .canned {
@include elegant-card; @include elegant-card;
z-index: 100; background: $color-white;
position: absolute;
background: #fff;
width: 24rem;
left: 0;
border-top: $space-small solid $color-white;
border-bottom: $space-small solid $color-white; border-bottom: $space-small solid $color-white;
border-top: $space-small solid $color-white;
left: 0;
max-height: 14rem; max-height: 14rem;
overflow: scroll; overflow: scroll;
position: absolute;
width: 24rem;
z-index: 100;
.active { .active a {
a { background: $color-woot;
background: $color-woot;
}
} }
} }
@ -43,30 +42,30 @@
&.is-private { &.is-private {
background: lighten($warning-color, 38%); background: lighten($warning-color, 38%);
> input { >input {
background: lighten($warning-color, 38%); background: lighten($warning-color, 38%);
} }
} }
> .icon { >.icon {
font-size: $font-size-medium;
color: $medium-gray; color: $medium-gray;
margin-right: $space-small;
cursor: pointer; cursor: pointer;
font-size: $font-size-medium;
margin-right: $space-small;
&.active { &.active {
color: $color-woot; color: $color-woot;
} }
} }
> textarea { >textarea {
@include ghost-input(); @include ghost-input();
@include margin(0); @include margin(0);
resize: none;
background: transparent; background: transparent;
// Override min-height : 50px in foundation // Override min-height : 50px in foundation
// //
min-height: 1rem; min-height: 1rem;
resize: none;
} }
} }
@ -80,48 +79,47 @@
.tabs { .tabs {
border: 0; border: 0;
padding: 0;
flex: 1; flex: 1;
padding: 0;
.tabs-title { .tabs-title {
margin: 0; margin: 0;
transition: background .2s $ease-in-out-cubic; transition: all .2s $ease-in-out-cubic;
transition: color .2s $ease-in-out-cubic; transition-property: color, background;
a { a {
font-weight: $font-weight-medium;
padding: $space-one $space-two; padding: $space-one $space-two;
} }
&:first-child { &.is-private.is-active {
border-bottom-left-radius: $space-small; background: lighten($warning-color, 38%);
&.is-active { a {
@include border-light-right; border-bottom-color: darken($warning-color, 15%);
border-left: 0; color: darken($warning-color, 15%);
a {
border-bottom-left-radius: $space-small;
}
} }
} }
}
&.is-private { .tabs-title:first-child {
&.is-active { border-bottom-left-radius: $space-small;
background: lighten($warning-color, 38%);
a { &.is-active {
border-bottom-color: darken($warning-color, 15%); @include border-light-right;
color: darken($warning-color, 15%); border-left: 0;
}
a {
border-bottom-left-radius: $space-small;
} }
} }
} }
.is-active { .is-active {
@include background-white; @include background-white;
margin-top: -1px;
@include border-light-left; @include border-light-left;
@include border-light-right; @include border-light-right;
margin-top: -1px;
} }
.message-length { .message-length {
@ -138,11 +136,11 @@
} }
.send-button { .send-button {
height: 3.6rem;
border-bottom-right-radius: $space-small; border-bottom-right-radius: $space-small;
padding-top: $space-small; height: 3.6rem;
padding-right: $space-two;
padding-left: $space-two; padding-left: $space-two;
padding-right: $space-two;
padding-top: $space-small;
.icon { .icon {
margin-left: $space-small; margin-left: $space-small;

View file

@ -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;
} }

View file

@ -14,15 +14,19 @@ export default {
props: { props: {
username: { username: {
type: String, type: String,
default: '',
}, },
backgroundColor: { backgroundColor: {
type: String, type: String,
default: 'white',
}, },
color: { color: {
type: String, type: String,
default: '#1f93ff',
}, },
customStyle: { customStyle: {
type: Object, type: Object,
default: undefined,
}, },
size: { size: {
type: Number, type: Number,
@ -30,6 +34,7 @@ export default {
}, },
src: { src: {
type: String, type: String,
default: '',
}, },
rounded: { rounded: {
type: Boolean, type: Boolean,
@ -72,7 +77,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.avatar-container { .avatar-container {
display: flex; display: flex;
font-weight: bold; font-weight: 500;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
text-align: center; text-align: center;

View file

@ -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>

View file

@ -93,7 +93,11 @@ export default {
]; ];
}, },
viewProfileButtonLabel() { viewProfileButtonLabel() {
return `${this.isContactPanelOpen ? 'Hide' : 'View'} Profile`; return `${
this.isContactPanelOpen
? this.$t('CONVERSATION.HEADER.CLOSE')
: this.$t('CONVERSATION.HEADER.OPEN')
} ${this.$t('CONVERSATION.HEADER.DETAILS')}`;
}, },
}, },

View file

@ -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",
@ -9,8 +10,11 @@
"TITLE": "Previous Conversations" "TITLE": "Previous Conversations"
}, },
"LABELS": { "LABELS": {
"NO_RECORDS_FOUND": "There are no labels associated to this conversation.", "TITLE": "Conversation Labels",
"TITLE": "Labels" "UPDATE_BUTTON": "Update Labels",
"UPDATE_ERROR": "Couldn't update labels, try again.",
"TAG_PLACEHOLDER": "Add new label",
"PLACEHOLDER": "Search or add a label"
} }
} }
} }

View file

@ -10,7 +10,10 @@
"LOADING_INBOXES": "Loading inboxes", "LOADING_INBOXES": "Loading inboxes",
"LOADING_CONVERSATIONS": "Loading Conversations", "LOADING_CONVERSATIONS": "Loading Conversations",
"HEADER": { "HEADER": {
"RESOLVE_ACTION": "Resolve" "RESOLVE_ACTION": "Resolve",
"OPEN": "More",
"CLOSE": "Close",
"DETAILS": "details"
}, },
"FOOTER": { "FOOTER": {
"MSG_INPUT": "Shift + enter for new line. Start with '/' to select a Canned Response.", "MSG_INPUT": "Shift + enter for new line. Start with '/' to select a Canned Response.",

View file

@ -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,13 @@ 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 $space-normal $space-normal $space-medium;
padding: $space-medium; padding-top: 0;
} }
.contact-conversation--list { .no-results {
margin-top: -$space-normal; margin: 0;
color: $color-gray;
padding: 0 $space-small;
} }
</style> </style>

View file

@ -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 v-if="icon" :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: '' },
}, },
}; };
@ -25,23 +25,25 @@ export default {
@import '~dashboard/assets/scss/mixins'; @import '~dashboard/assets/scss/mixins';
.conv-details--item { .conv-details--item {
padding-bottom: $space-normal; padding-bottom: $space-medium;
&:last-child { &:last-child {
padding-bottom: 0; padding-bottom: 0;
} }
.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-small;
} }
} }
</style> </style>

View file

@ -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>
@ -164,15 +163,13 @@ export default {
@include border-normal-left; @include border-normal-left;
font-size: $font-size-small; font-size: $font-size-small;
overflow-y: auto; overflow-y: auto;
background: $color-white; background: white;
overflow: auto; overflow: auto;
} }
.contact--profile { .contact--profile {
width: 100%; padding: $space-medium $space-normal 0 $space-medium;
padding: $space-normal $space-medium $zero;
align-items: center; align-items: center;
.user-thumbnail-box { .user-thumbnail-box {
margin-right: $space-normal; margin-right: $space-normal;
} }
@ -191,9 +188,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 +208,7 @@ export default {
} }
.conversation--details { .conversation--details {
padding: $space-medium; padding: $space-two $space-normal $space-two $space-medium;
width: 100%;
} }
.conversation--labels { .conversation--labels {

View file

@ -1,21 +1,42 @@
<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> <multiselect
<div v-else class="contact-conversation--list"> v-model="selectedLabels"
<span :options="savedLabels"
v-for="label in labels" :tag-placeholder="$t('CONTACT_PANEL.LABELS.TAG_PLACEHOLDER')"
:key="label" :placeholder="$t('CONTACT_PANEL.LABELS.PLACEHOLDER')"
class="conversation--label label primary" :multiple="true"
> :taggable="true"
{{ label }} hide-selected
</span> :show-labels="false"
@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 +45,10 @@
<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';
export default { export default {
components: { components: {
ContactDetailsItem,
Spinner, Spinner,
}, },
props: { props: {
@ -38,25 +57,64 @@ export default {
required: true, required: true,
}, },
}, },
data() {
return {
isSearching: false,
selectedLabels: [],
};
},
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.fetchLabels(newConversationId);
} }
}, },
}, },
mounted() { mounted() {
this.$store.dispatch('conversationLabels/get', this.conversationId); const { conversationId } = this;
this.fetchLabels(conversationId);
},
methods: {
addLabel(label) {
this.selectedLabels = [...this.selectedLabels, label];
},
onUpdateLabels() {
this.$store.dispatch('conversationLabels/update', {
conversationId: this.conversationId,
labels: this.selectedLabels,
});
},
async fetchLabels(conversationId) {
try {
await this.$store.dispatch('conversationLabels/get', conversationId);
this.selectedLabels = [...this.savedLabels];
// eslint-disable-next-line no-empty
} catch (error) {}
},
}, },
}; };
</script> </script>
@ -66,12 +124,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 $space-normal $space-normal $space-medium;
padding: $space-medium;
}
.contact-conversation--list {
margin-top: -$space-normal;
} }
.conversation--label { .conversation--label {
@ -80,4 +133,38 @@ 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-wrap {
padding: 0 $space-small;
}
.no-results {
margin: $space-normal 0 0 0;
color: $color-gray;
font-weight: $font-weight-normal;
}
.error {
color: $alert-color;
font-size: $font-size-mini;
font-weight: $font-weight-medium;
}
</style> </style>

View file

@ -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 = {

View file

@ -32,4 +32,46 @@ describe('#actions', () => {
]); ]);
}); });
}); });
describe('#update', () => {
it('updates correct actions if API is success', async () => {
axios.post.mockResolvedValue({
data: { payload: { conversationId: '1', labels: ['on-hold'] } },
});
await actions.update(
{ commit },
{ conversationId: '1', labels: ['on-hold'] }
);
expect(commit.mock.calls).toEqual([
[types.default.SET_CONVERSATION_LABELS_UI_FLAG, { isUpdating: true }],
[
types.default.SET_CONVERSATION_LABELS,
{
id: '1',
data: { conversationId: '1', labels: ['on-hold'] },
},
],
[
types.default.SET_CONVERSATION_LABELS_UI_FLAG,
{ isUpdating: false, isError: false },
],
]);
});
it('sends correct actions if API is error', async () => {
axios.post.mockRejectedValue({ message: 'Incorrect header' });
await actions.update(
{ commit },
{ conversationId: '1', labels: ['on-hold'] }
);
expect(commit.mock.calls).toEqual([
[types.default.SET_CONVERSATION_LABELS_UI_FLAG, { isUpdating: true }],
[
types.default.SET_CONVERSATION_LABELS_UI_FLAG,
{ isUpdating: false, isError: true },
],
]);
});
});
}); });

View file

@ -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>

View file

@ -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);

View file

@ -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;
} }
} }

View file

@ -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
/> />

View file

@ -107,6 +107,9 @@
"*.rb": [ "*.rb": [
"rubocop -a", "rubocop -a",
"git add" "git add"
],
"*.scss": [
"scss-lint"
] ]
} }
} }