chore: Remove older UI (#11720)

This commit is contained in:
Sivin Varghese
2025-07-01 09:43:44 +05:30
committed by GitHub
parent 58da92a252
commit 24ea968b00
369 changed files with 974 additions and 9363 deletions

View File

@@ -1,6 +1,6 @@
<script>
import { mapGetters } from 'vuex';
import AddAccountModal from '../dashboard/components/layout/sidebarComponents/AddAccountModal.vue';
import AddAccountModal from './components/app/AddAccountModal.vue';
import LoadingState from './components/widgets/LoadingState.vue';
import NetworkNotification from './components/NetworkNotification.vue';
import UpdateBanner from './components/app/UpdateBanner.vue';

View File

@@ -1,101 +0,0 @@
.slide-fade-enter-active {
transition: all 0.3s var(--ease-in-cubic);
}
.slide-fade-leave-active {
transition: all 0.3s var(--ease-out-cubic);
}
.slide-fade-enter,
.slide-fade-leave-to {
opacity: 0;
transform: translateX(10px);
}
.slide-fade-enter {
transform: translateX($space-micro);
}
.slide-fade-leave-to {
transform: translateX($space-medium);
}
.conversations-list-enter-active,
.conversations-list-leave-active {
transition: all 0.25s var(--ease-out-cubic);
}
.conversations-list-enter,
.conversations-list-leave-to {
opacity: 0;
transform: translateX($space-medium);
}
.slide-up-enter-active {
transition: all 0.3s var(--ease-in-cubic);
}
.slide-up-leave-active {
transition: all 0.3s var(--ease-out-cubic);
}
.slide-up-enter,
.slide-up-leave-to {
opacity: 0;
transform: translateY(-$space-medium);
}
.menu-slide-enter-active,
.menu-slide-leave-active {
transform: translateY(0);
transition:
transform 0.25s var(--ease-in-cubic),
opacity 0.15s var(--ease-in-cubic);
}
.menu-slide-enter,
.menu-slide-leave-to {
opacity: 0;
transform: translateY($space-small);
}
.toast-fade-enter-active {
transition: all 0.3s var(--ease-in-sine);
}
.toast-fade-leave-active {
transition: all 0.1s var(--ease-out-sine);
}
.toast-fade-enter,
.toast-fade-leave-to {
opacity: 0;
transform: translateY(-$space-small);
}
.modal-fade-enter-active {
transition: all 0.3s var(--ease-in-sine);
}
.modal-fade-leave-active {
transition: all 0.1s var(--ease-out-sine);
}
.modal-fade-enter,
.modal-fade-leave-to {
opacity: 0;
}
.network-notification-fade-enter-active {
transition: all 0.1s var(--ease-in-sine);
}
.network-notification-fade-leave-active {
transition: all 0.1s var(--ease-out-sine);
}
.network-notification-fade-enter,
.network-notification-fade-leave-to {
opacity: 0;
transform: translateY(-$space-small);
}

View File

@@ -201,3 +201,8 @@ code {
}
}
}
// Table
table {
@apply border-spacing-0 text-sm w-full;
}

View File

@@ -1,38 +0,0 @@
@import 'dashboard/assets/scss/variables';
.formulate-input {
.formulate-input-errors {
list-style-type: none;
margin: 0;
padding: 0;
}
.formulate-input-error {
color: var(--r-400);
display: block;
font-size: var(--font-size-small);
font-weight: $font-weight-normal;
margin-bottom: $space-one;
width: 100%;
}
}
.integration-hooks {
.formulate-input[data-type='checkbox'] {
.formulate-input-wrapper {
@apply flex;
.formulate-input-element {
@apply pr-2;
input {
@apply mb-0;
}
}
}
.formulate-input-element-decorator {
@apply hidden;
}
}
}

View File

@@ -1,21 +0,0 @@
// loader class
.spinner {
@include color-spinner();
@apply inline-block h-6 py-0 px-6 relative align-middle w-6;
&.message {
@apply bg-white dark:bg-slate-800 rounded-full left-0 my-3 mx-auto p-4 top-0;
&::before {
@apply -ml-3 -mt-3;
}
}
&.small {
@apply h-4 w-4;
&::before {
@apply h-4 -mt-2 w-4;
}
}
}

View File

@@ -1,48 +0,0 @@
// scss-lint:disable SpaceAfterPropertyColon
@import 'shared/assets/fonts/inter';
// Inter,
html,
body {
font-family:
'Inter',
-apple-system,
system-ui,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
'Helvetica Neue',
Tahoma,
Arial,
sans-serif !important;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
height: 100%;
margin: 0;
padding: 0;
width: 100%;
}
.app-wrapper {
@apply h-screen flex-grow-0 min-h-0 w-full;
.button--fixed-top {
@apply fixed ltr:right-2 rtl:left-2 top-2 flex flex-row;
}
}
.banner + .app-wrapper {
// Reduce the height of the dashboard to make room for the banner.
// And causing the top right green-action button to be pushed down when scrolling.
@apply h-[calc(100%-48px)];
.button--fixed-top {
@apply top-14;
}
.off-canvas-content {
.button--fixed-top {
@apply top-2;
}
}
}

View File

@@ -1,101 +0,0 @@
@import 'dashboard/assets/scss/variables';
$spinner-before-border-color: rgba(255, 255, 255, 0.7);
// input form
@mixin ghost-input() {
box-shadow: none;
border-color: transparent;
&:active,
&:hover,
&:focus {
border-color: transparent;
box-shadow: none;
}
}
@mixin color-spinner() {
@keyframes spinner {
to {
transform: rotate(360deg);
}
}
&::before {
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;
content: '';
height: $space-medium;
left: 50%;
margin-left: -$space-one;
margin-top: -$space-one;
position: absolute;
top: 50%;
width: $space-medium;
}
}
// --------------------------------------------------------
// arrows
// --------------------------------------------------------
// $direction: top, left, right, bottom, top-left, top-right, bottom-left, bottom-right
// $color: hex, rgb or rbga
// $size: px or em
// @example
// .element{
// @include arrow(top, #000, 50px);
// }
@mixin arrow($direction, $color, $size) {
display: block;
height: 0;
width: 0;
content: '';
@if $direction == 'top' {
border-bottom: $size solid $color;
border-left: $size solid transparent;
border-right: $size solid transparent;
}
@else if $direction == 'right' {
border-bottom: $size solid transparent;
border-left: $size solid $color;
border-top: $size solid transparent;
}
@else if $direction == 'bottom' {
border-left: $size solid transparent;
border-right: $size solid transparent;
border-top: $size solid $color;
}
@else if $direction == 'left' {
border-bottom: $size solid transparent;
border-right: $size solid $color;
border-top: $size solid transparent;
}
@else if $direction == 'top-left' {
border-right: $size solid transparent;
border-top: $size solid $color;
}
@else if $direction == 'top-right' {
border-left: $size solid transparent;
border-top: $size solid $color;
}
@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;
}
}

View File

@@ -1,204 +0,0 @@
.app-rtl--wrapper {
direction: rtl;
// Woot Tabs
.tabs-title {
&:first-child {
margin-left: var(--space-small);
margin-right: unset;
}
&:last-child {
margin-left: unset;
margin-right: var(--space-small);
}
}
// woot tables
table,
thead,
th {
text-align: right;
}
// Table footer
.footer {
.page-meta {
direction: initial;
}
}
// Wizard box
.wizard-box {
direction: initial;
}
// Conversation details
.conversation-details-wrap {
.conversation-panel {
// Message text
.text-content {
p {
unicode-bidi: plaintext;
}
ul {
padding-left: unset;
padding-right: var(--space-two);
}
li {
text-align: right;
}
}
// Message items and actions
li {
&.right {
.sender--info {
padding: var(--space-small) var(--space-smaller)
var(--space-smaller) 0;
}
.context-menu-wrap {
margin-left: 0;
margin-right: auto;
}
}
}
}
// Conversation footer
.conversation-footer {
.preview-item {
direction: initial;
}
}
// Custom attributes section in conversation sidebar
.conversation-sidebar-wrap .checkbox-wrap {
.checkbox {
margin-left: var(--space-small);
}
}
}
// Conversation list
.conversations-list-wrap {
border-right: 0;
.conversation {
.conversation--meta {
left: $space-normal;
right: unset;
.unread {
margin-left: unset;
margin-right: auto;
}
}
.assignee-label {
margin-left: 0;
margin-right: var(--space-one);
}
.show-more--button {
margin: unset;
transform: rotate(180deg);
}
}
// Basic filter dropdown
.basic-filter {
left: 0;
right: unset;
}
// Bulk actions
.bulk-action__container {
.triangle {
left: var(--triangle-position);
right: unset;
}
.bulk-action__agents {
left: var(--space-small);
right: unset;
}
.labels-container {
left: var(--space-small);
right: unset;
.label-checkbox {
margin: 0 0 0 var(--space-one);
}
}
.actions-container {
left: var(--space-small);
right: unset;
}
.bulk-action__teams {
left: var(--space-small);
right: unset;
}
}
}
// Contact notes
.card.note-wrap {
.time-stamp {
unicode-bidi: plaintext;
}
}
// Toggle switch
.toggle-button {
&.small {
span {
&.active {
transform: translate(var(--space-minus-small), var(--space-zero));
}
}
}
span {
--minus-space-one-point-five: -0.9375rem;
&.active {
transform: translate(
var(--minus-space-one-point-five),
var(--space-zero)
);
}
}
}
// Modal
.modal-container {
text-align: right;
.modal-footer {
button {
margin-left: 0;
margin-right: var(--space-small);
}
}
}
// Other changes
.colorpicker--chrome {
direction: initial;
}
.mention--box {
direction: initial;
}
.contact--form .input-group {
direction: initial;
}
}

View File

@@ -1,97 +0,0 @@
// Font sizes
$font-size-nano: 0.5rem;
$font-size-micro: 0.675rem;
$font-size-mini: 0.75rem;
$font-size-small: 0.875rem;
$font-size-default: 1rem;
$font-size-medium: 1.125rem;
$font-size-large: 1.375rem;
$font-size-big: 1.5rem;
$font-size-bigger: 1.75rem;
$font-size-mega: 2.125rem;
$font-size-giga: 2.5rem;
// spaces
$zero: 0;
$space-micro: 0.125rem;
$space-smaller: 0.25rem;
$space-small: 0.5rem;
$space-one: 0.675rem;
$space-slab: 0.75rem;
$space-normal: 1rem;
$space-two: 1.25rem;
$space-medium: 1.5rem;
$space-large: 2rem;
$space-larger: 3rem;
$space-jumbo: 4rem;
$space-mega: 6.25rem;
// font-weight
$font-weight-feather: 100;
$font-weight-light: 300;
$font-weight-normal: 400;
$font-weight-medium: 500;
$font-weight-bold: 600;
$font-weight-black: 700;
//Navbar
$nav-bar-width: 14.375rem;
$header-height: 3.5rem;
$woot-logo-padding: $space-large $space-two;
// Colors
$color-woot: #1f93ff;
$color-gray: #6e6f73;
$color-light-gray: #999a9b;
$color-border: var(--s-75);
$color-border-light: var(--s-50);
$color-border-dark: var(--s-100);
$color-background: var(--s-50);
$color-background-light: var(--s-25);
$color-white: #fff;
$color-body: #3c4858;
$color-heading: #1f2d3d;
$color-extra-light-blue: #f5f7f9;
$primary-color: $color-woot;
$secondary-color: #5d7592;
$success-color: #44ce4b;
$warning-color: #ffc532;
$alert-color: #ff382d;
$masked-bg: rgba(0, 0, 0, .4);
// Color-palettes
$color-primary-light: #c7e3ff;
$color-primary-dark: darken($color-woot, 20%);
// Thumbnail
$thumbnail-radius: 2.5rem;
// chat-header
$conv-header-height: 2.5rem;
// Inbox List
$inbox-thumb-size: 3rem;
// Snackbar default
$woot-snackbar-bg: #323232;
$woot-snackbar-button: #ffeb3b;
$swift-ease-out-duration: .4s !default;
$swift-ease-out-function: cubic-bezier(0.37, 0, 0.63, 1) !default;
$swift-ease-out: all $swift-ease-out-duration $swift-ease-out-function !default;
// Transitions
$transition-ease-in: all 0.250s ease-in;
:root {
--dashboard-app-tabs-height: 2.4375rem;
}

View File

@@ -1,3 +1,4 @@
// scss-lint:disable SpaceAfterPropertyColon
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
@@ -8,54 +9,66 @@
// Next Colors
@import 'next-colors';
@import 'shared/assets/stylesheets/animations';
@import 'shared/assets/stylesheets/colors';
@import 'shared/assets/stylesheets/spacing';
@import 'shared/assets/stylesheets/font-size';
@import 'shared/assets/stylesheets/font-weights';
@import 'shared/assets/stylesheets/shadows';
@import 'shared/assets/stylesheets/border-radius';
@import 'shared/assets/stylesheets/z-index';
@import 'variables';
@import 'mixins';
@import 'helper-classes';
@import 'formulate';
@import 'date-picker';
@import 'layout';
@import 'animations';
@import 'rtl';
@import 'widgets/base';
@import 'widgets/conversation-view';
@import 'widgets/tabs';
@import 'widgets/woot-tables';
// Base styles for elements
@import 'base';
// Plugins
@import 'plugins/multiselect';
@import 'plugins/dropdown';
@import 'plugins/date-picker';
html,
body {
font-family:
'Inter',
-apple-system,
system-ui,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
'Helvetica Neue',
Tahoma,
Arial,
sans-serif !important;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
height: 100%;
margin: 0;
padding: 0;
width: 100%;
}
.app-wrapper {
@apply h-screen flex-grow-0 min-h-0 w-full;
.button--fixed-top {
@apply fixed ltr:right-2 rtl:left-2 top-2 flex flex-row;
}
}
.banner + .app-wrapper {
// Reduce the height of the dashboard to make room for the banner.
// And causing the top right green-action button to be pushed down when scrolling.
@apply h-[calc(100%-48px)];
.button--fixed-top {
@apply top-14;
}
.off-canvas-content {
.button--fixed-top {
@apply top-2;
}
}
}
.tooltip {
@apply bg-slate-900 text-white py-1 px-2 z-40 text-xs rounded-md dark:bg-slate-200 dark:text-slate-900 max-w-96;
@apply bg-n-solid-2 text-n-slate-12 py-1 px-2 z-40 text-xs rounded-md max-w-96;
}
#app {
@apply h-full w-full;
}
.hide {
@apply hidden;
}
.n-blue-border {
@apply border-n-blue-border;
}
.n-blue-text {
@apply text-n-blue-text;
}
.custom-dashed-border {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25'%3E%3Crect x='0' y='0' width='100%25' height='100%25' fill='none' rx='16' ry='16' stroke='%23E2E3E7' stroke-width='2' stroke-dasharray='6, 8' stroke-dashoffset='0' stroke-linecap='round'/%3E%3C/svg%3E");
background-position: center;
@@ -67,351 +80,6 @@
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25'%3E%3Crect x='0' y='0' width='100%25' height='100%25' fill='none' rx='16' ry='16' stroke='%23343434' stroke-width='2' stroke-dasharray='6, 8' stroke-dashoffset='0' stroke-linecap='round'/%3E%3C/svg%3E");
}
// scss-lint:disable PropertySortOrder
@layer base {
:root {
--color-amber-25: 254 253 251;
--color-amber-50: 255 249 237;
--color-amber-75: 255 243 208;
--color-amber-100: 255 236 183;
--color-amber-200: 255 224 161;
--color-amber-300: 245 208 140;
--color-amber-400: 228 187 120;
--color-amber-500: 214 163 92;
--color-amber-600: 214 163 92;
--color-amber-700: 255 186 26;
--color-amber-800: 145 89 48;
--color-amber-900: 79 52 34;
--color-ash-100: 235 235 239;
--color-ash-200: 228 228 233;
--color-ash-25: 252 252 253;
--color-ash-300: 221 221 227;
--color-ash-400: 211 212 219;
--color-ash-50: 249 249 251;
--color-ash-500: 185 187 198;
--color-ash-600: 139 141 152;
--color-ash-700: 126 128 138;
--color-ash-75: 242 242 245;
--color-ash-800: 96 100 108;
--color-ash-900: 28 32 36;
--color-primary-25: 251 253 255;
--color-primary-50: 245 249 255;
--color-primary-75: 233 243 255;
--color-primary-100: 218 236 255;
--color-primary-200: 201 226 255;
--color-primary-300: 181 213 255;
--color-primary-400: 155 195 252;
--color-primary-500: 117 171 247;
--color-primary-600: 39 129 246;
--color-primary-700: 16 115 233;
--color-primary-800: 8 109 224;
--color-primary-900: 11 50 101;
--color-ruby-100: 255 220 225;
--color-ruby-200: 255 206 214;
--color-ruby-25: 255 252 253;
--color-ruby-300: 248 191 200;
--color-ruby-400: 239 172 184;
--color-ruby-50: 255 247 248;
--color-ruby-500: 229 146 163;
--color-ruby-600: 229 70 102;
--color-ruby-700: 220 59 93;
--color-ruby-75: 254 234 237;
--color-ruby-800: 202 36 77;
--color-ruby-900: 100 23 43;
--color-teal-100: 224 248 243;
--color-teal-200: 204 243 234;
--color-teal-25: 250 254 253;
--color-teal-300: 184 234 224;
--color-teal-400: 161 222 210;
--color-teal-50: 243 251 249;
--color-teal-500: 83 185 171;
--color-teal-600: 18 165 148;
--color-teal-700: 13 155 138;
--color-teal-75: 236 249 255;
--color-teal-800: 0 133 115;
--color-teal-900: 13 61 56;
--color-green-25: 251 254 252;
--color-green-50: 244 251 246;
--color-green-75: 230 246 235;
--color-green-100: 214 241 223;
--color-green-200: 196 232 209;
--color-green-300: 173 221 192;
--color-green-400: 142 206 170;
--color-green-500: 91 185 139;
--color-green-600: 48 164 108;
--color-green-700: 43 154 102;
--color-green-800: 33 131 88;
--color-green-900: 25 59 45;
--color-mint-25: 249 254 253;
--color-mint-50: 242 251 249;
--color-mint-75: 221 249 242;
--color-mint-100: 200 244 233;
--color-mint-200: 179 236 222;
--color-mint-300: 156 224 208;
--color-mint-400: 126 207 189;
--color-mint-500: 76 187 165;
--color-mint-600: 134 234 212;
--color-mint-700: 125 224 203;
--color-mint-800: 2 120 100;
--color-mint-900: 22 67 60;
--color-sky-25: 249 254 255;
--color-sky-50: 241 250 253;
--color-sky-75: 225 246 253;
--color-sky-100: 209 240 250;
--color-sky-200: 190 231 245;
--color-sky-300: 169 218 237;
--color-sky-400: 141 202 227;
--color-sky-500: 96 179 215;
--color-sky-600: 124 226 254;
--color-sky-700: 116 218 248;
--color-sky-800: 0 116 158;
--color-sky-900: 29 62 86;
--color-indigo-25: 253 253 254;
--color-indigo-50: 247 249 255;
--color-indigo-75: 237 242 254;
--color-indigo-100: 225 233 255;
--color-indigo-200: 210 222 255;
--color-indigo-300: 193 208 255;
--color-indigo-400: 171 189 249;
--color-indigo-500: 141 164 239;
--color-indigo-600: 62 99 221;
--color-indigo-700: 51 88 212;
--color-indigo-800: 58 91 199;
--color-indigo-900: 31 45 92;
--color-iris-25: 253 253 255;
--color-iris-50: 248 248 255;
--color-iris-75: 240 241 254;
--color-iris-100: 230 231 255;
--color-iris-200: 218 220 255;
--color-iris-300: 203 205 255;
--color-iris-400: 184 186 248;
--color-iris-500: 155 158 240;
--color-iris-600: 91 91 214;
--color-iris-700: 81 81 205;
--color-iris-800: 87 83 198;
--color-iris-900: 39 41 98;
--color-violet-25: 253 252 254;
--color-violet-50: 250 248 255;
--color-violet-75: 244 240 254;
--color-violet-100: 235 228 255;
--color-violet-200: 225 217 255;
--color-violet-300: 212 202 254;
--color-violet-400: 194 181 245;
--color-violet-500: 170 153 236;
--color-violet-600: 110 86 207;
--color-violet-700: 101 77 196;
--color-violet-800: 101 80 185;
--color-violet-900: 47 38 95;
--color-pink-25: 255 252 254;
--color-pink-50: 254 247 251;
--color-pink-75: 254 233 245;
--color-pink-100: 251 220 239;
--color-pink-200: 246 206 231;
--color-pink-300: 239 191 221;
--color-pink-400: 231 172 208;
--color-pink-500: 221 147 194;
--color-pink-600: 214 64 159;
--color-pink-700: 207 56 151;
--color-pink-800: 194 41 138;
--color-pink-900: 101 18 73;
--color-orange-25: 254 252 251;
--color-orange-50: 255 247 237;
--color-orange-75: 255 239 214;
--color-orange-100: 255 223 181;
--color-orange-200: 255 209 154;
--color-orange-300: 255 193 130;
--color-orange-400: 245 174 115;
--color-orange-500: 236 148 85;
--color-orange-600: 247 107 21;
--color-orange-700: 239 95 0;
--color-orange-800: 204 78 0;
--color-orange-900: 88 45 29;
}
// scss-lint:disable QualifyingElement
body.dark {
--color-amber-25: 31 19 0;
--color-amber-50: 37 24 4;
--color-amber-75: 48 32 11;
--color-amber-100: 57 39 15;
--color-amber-200: 67 46 18;
--color-amber-300: 83 57 22;
--color-amber-400: 111 77 29;
--color-amber-500: 169 118 42;
--color-amber-600: 169 118 42;
--color-amber-700: 255 203 71;
--color-amber-800: 255 204 77;
--color-amber-900: 255 231 179;
--color-ash-100: 46 48 53;
--color-ash-200: 53 55 60;
--color-ash-25: 24 24 26;
--color-ash-300: 60 63 68;
--color-ash-400: 70 75 80;
--color-ash-50: 27 27 31;
--color-ash-500: 90 97 101;
--color-ash-600: 105 110 119;
--color-ash-700: 120 127 133;
--color-ash-75: 39 40 45;
--color-ash-800: 173 177 184;
--color-ash-900: 237 238 240;
--color-primary-25: 10 17 28;
--color-primary-50: 15 24 38;
--color-primary-75: 15 39 72;
--color-primary-100: 10 49 99;
--color-primary-200: 18 61 117;
--color-primary-300: 29 74 134;
--color-primary-400: 40 89 156;
--color-primary-500: 48 106 186;
--color-primary-600: 39 129 246;
--color-primary-700: 21 116 231;
--color-primary-800: 126 182 255;
--color-primary-900: 205 227 255;
--color-ruby-100: 78 19 37;
--color-ruby-200: 94 26 46;
--color-ruby-25: 25 17 19;
--color-ruby-300: 111 37 57;
--color-ruby-400: 136 52 71;
--color-ruby-50: 30 21 23;
--color-ruby-500: 179 68 90;
--color-ruby-600: 229 70 102;
--color-ruby-700: 236 90 114;
--color-ruby-75: 58 20 30;
--color-ruby-800: 255 148 157;
--color-ruby-900: 254 210 225;
--color-teal-100: 2 59 55;
--color-teal-200: 8 72 67;
--color-teal-25: 13 21 20;
--color-teal-300: 28 105 97;
--color-teal-400: 28 105 97;
--color-teal-50: 17 28 27;
--color-teal-500: 32 126 115;
--color-teal-600: 41 163 131;
--color-teal-700: 14 179 158;
--color-teal-75: 13 45 42;
--color-teal-800: 11 216 182;
--color-teal-900: 173 240 221;
--color-green-25: 14 21 18;
--color-green-50: 18 27 23;
--color-green-75: 19 45 33;
--color-green-100: 17 59 41;
--color-green-200: 23 73 51;
--color-green-300: 32 87 62;
--color-green-400: 40 104 74;
--color-green-500: 47 124 87;
--color-green-600: 48 164 108;
--color-green-700: 51 176 116;
--color-green-800: 61 214 140;
--color-green-900: 177 241 203;
--color-mint-25: 14 21 21;
--color-mint-50: 15 27 27;
--color-mint-75: 9 44 43;
--color-mint-100: 0 58 56;
--color-mint-200: 0 71 68;
--color-mint-300: 16 86 80;
--color-mint-400: 30 104 95;
--color-mint-500: 39 127 112;
--color-mint-600: 134 234 212;
--color-mint-700: 168 245 229;
--color-mint-800: 88 213 186;
--color-mint-900: 196 245 225;
--color-sky-25: 14 21 21;
--color-sky-50: 15 27 27;
--color-sky-75: 9 44 43;
--color-sky-100: 0 58 56;
--color-sky-200: 0 71 68;
--color-sky-300: 16 86 80;
--color-sky-400: 30 104 95;
--color-sky-500: 39 127 112;
--color-sky-600: 134 234 212;
--color-sky-700: 168 245 229;
--color-sky-800: 88 213 186;
--color-sky-900: 196 245 225;
--color-indigo-25: 17 19 31;
--color-indigo-50: 20 23 38;
--color-indigo-75: 24 36 73;
--color-indigo-100: 29 46 98;
--color-indigo-200: 37 57 116;
--color-indigo-300: 48 67 132;
--color-indigo-400: 58 79 151;
--color-indigo-500: 67 93 177;
--color-indigo-600: 62 99 221;
--color-indigo-700: 84 114 228;
--color-indigo-800: 158 177 255;
--color-indigo-900: 214 225 255;
--color-iris-25: 19 19 30;
--color-iris-50: 23 22 37;
--color-iris-75: 32 34 72;
--color-iris-100: 38 42 101;
--color-iris-200: 48 51 116;
--color-iris-300: 61 62 130;
--color-iris-400: 74 74 149;
--color-iris-500: 89 88 177;
--color-iris-600: 91 91 214;
--color-iris-700: 110 106 222;
--color-iris-800: 177 169 255;
--color-iris-900: 224 223 254;
--color-violet-25: 20 18 31;
--color-violet-50: 27 21 37;
--color-violet-75: 41 31 67;
--color-violet-100: 51 37 91;
--color-violet-200: 60 46 105;
--color-violet-300: 71 56 118;
--color-violet-400: 86 70 139;
--color-violet-500: 105 88 173;
--color-violet-600: 110 86 207;
--color-violet-700: 125 102 217;
--color-violet-800: 186 167 255;
--color-violet-900: 226 221 254;
--color-pink-25: 25 17 23;
--color-pink-50: 33 18 29;
--color-pink-75: 55 23 47;
--color-pink-100: 75 20 61;
--color-pink-200: 89 28 71;
--color-pink-300: 105 41 85;
--color-pink-400: 131 56 105;
--color-pink-500: 168 72 133;
--color-pink-600: 214 64 159;
--color-pink-700: 222 81 168;
--color-pink-800: 255 141 204;
--color-pink-900: 253 209 234;
--color-orange-25: 23 18 14;
--color-orange-50: 30 22 15;
--color-orange-75: 51 30 11;
--color-orange-100: 70 33 0;
--color-orange-200: 86 40 0;
--color-orange-300: 102 53 12;
--color-orange-400: 126 69 29;
--color-orange-500: 163 88 41;
--color-orange-600: 247 107 21;
--color-orange-700: 255 128 31;
--color-orange-800: 255 160 87;
--color-orange-900: 255 224 194;
}
}
@layer utilities {
/* Hide scrollbar for Chrome, Safari and Opera */
.no-scrollbar::-webkit-scrollbar {

View File

@@ -30,11 +30,11 @@
.mx-input:disabled,
.mx-input[readonly] {
@apply bg-white dark:bg-slate-900 cursor-pointer;
@apply bg-n-background cursor-pointer;
}
.mx-icon-calendar {
@apply dark:text-slate-500;
@apply text-n-slate-10;
}
}
@@ -43,17 +43,17 @@
.cell {
&.disabled {
@apply bg-slate-25 dark:bg-slate-900 text-slate-200 dark:text-slate-300;
@apply bg-n-slate-2 dark:bg-n-background text-n-slate-10;
}
&:hover,
&.hover-in-range,
&.in-range {
@apply bg-slate-75 dark:bg-slate-700 text-slate-900 dark:text-slate-100;
@apply bg-n-slate-3 dark:bg-n-solid-3 text-n-slate-12;
}
}
.mx-calendar+.mx-calendar {
.mx-calendar + .mx-calendar {
@apply border-l border-n-weak;
}
@@ -62,7 +62,7 @@
}
.mx-time {
@apply border-0 bg-white dark:bg-slate-800;
@apply border-0 bg-n-background dark:bg-n-solid-2;
.mx-time-header {
@apply border-0;
@@ -70,11 +70,11 @@
.mx-time-item {
&.disabled {
@apply bg-slate-25 dark:bg-slate-900;
@apply bg-n-slate-2 dark:bg-n-background;
}
&:hover {
@apply bg-slate-75 dark:bg-slate-700;
@apply bg-n-slate-3 dark:bg-n-solid-3;
}
}
}

View File

@@ -1,7 +0,0 @@
.dropdown-pane {
@apply border rounded-lg hidden relative invisible shadow-lg border-n-strong dark:border-n-strong box-content p-2 w-fit z-[9999];
&.dropdown-pane--open {
@apply bg-n-alpha-3 backdrop-blur-[100px] absolute block visible;
}
}

View File

@@ -17,6 +17,10 @@
@apply mb-4;
}
&.invalid .multiselect__tags {
@apply border-0 outline outline-1 outline-n-ruby-8 dark:outline-n-ruby-8 hover:outline-n-ruby-9 dark:hover:outline-n-ruby-9 disabled:outline-n-ruby-8 dark:disabled:outline-n-ruby-8;
}
&.multiselect--disabled {
@apply opacity-50 rounded-lg cursor-not-allowed pointer-events-auto;
@@ -124,8 +128,7 @@
}
.multiselect__input {
@include ghost-input;
@apply text-sm h-[2.875rem] mb-0 p-0;
@apply text-sm h-[2.875rem] mb-0 p-0 shadow-none border-transparent hover:border-transparent hover:shadow-none focus:border-transparent focus:shadow-none active:border-transparent active:shadow-none;
}
.multiselect__single {

View File

@@ -1 +0,0 @@
// to be removed

View File

@@ -1 +0,0 @@
// to be removed

View File

@@ -1,261 +0,0 @@
// scss-lint:disable MergeableSelector
@tailwind utilities;
@layer utilities {
.custom-gradient {
background-image: linear-gradient(
-180deg,
transparent 3%,
rgb(76 81 85) 130%
);
}
.bubble-with-types {
@apply py-2 text-sm font-normal bg-woot-500 dark:bg-woot-500 relative px-4 m-0 text-white dark:text-white;
.message-text__wrap {
@apply relative;
.link {
@apply text-white dark:text-white underline;
}
}
.image,
.video {
@apply cursor-pointer relative;
.modal-container {
@apply text-center;
}
.modal-image {
@apply max-h-[76vh] max-w-[76vw];
}
.modal-video {
@apply max-h-[76vh] max-w-[76vw];
}
&::before {
@apply custom-gradient bottom-0 h-[20%] content-[''] left-0 absolute w-full opacity-80;
}
}
}
}
.conversation-panel {
@apply flex-shrink flex-grow basis-px flex flex-col overflow-y-auto relative h-full m-0 pb-4;
}
.conversation-panel > li {
@apply flex flex-shrink-0 flex-grow-0 flex-auto max-w-full mt-0 mr-0 mb-1 ml-0 relative first:mt-auto last:mb-0;
&.unread--toast {
+ .right {
@apply mb-1;
}
+ .left {
@apply mb-0;
}
span {
@apply shadow-lg rounded-full bg-woot-500 dark:bg-woot-500 text-white dark:text-white text-xs font-medium my-2.5 mx-auto px-2.5 py-1.5;
}
}
.bubble {
@apply bubble-with-types text-left break-words;
.aplayer {
@apply shadow-none;
font-family: inherit;
}
}
&.left {
.bubble {
@apply rounded-r-lg rounded-l mr-auto break-words;
&:not(.is-unsupported) {
@apply border border-slate-50 dark:border-slate-700 bg-white dark:bg-slate-700 text-black-900 dark:text-slate-50;
}
&.is-image {
@apply rounded-lg;
}
.link {
@apply text-woot-600 dark:text-woot-600;
}
.file {
.attachment-name {
@apply text-slate-700 dark:text-woot-300;
}
.icon-wrap {
@apply text-woot-600 dark:text-woot-600;
}
.download {
@apply text-woot-600 dark:text-woot-600;
}
}
}
+ .right {
@apply mt-2.5;
.bubble {
@apply rounded-tr-lg;
}
}
+ .unread--toast {
+ .right {
@apply mt-2.5;
.bubble {
@apply rounded-tr-lg;
}
}
+ .left {
@apply mt-0;
}
}
}
&.right {
@apply justify-end;
.wrap {
@apply flex items-end mr-4 text-right;
.sender--info {
@apply pt-2 pb-1 pr-0 pl-2;
}
}
.bubble {
@apply ml-auto break-words rounded-l-lg rounded-r;
&.is-private {
@apply text-black-900 dark:text-white relative border border-solid bg-yellow-100 dark:bg-yellow-700 border-yellow-200 dark:border-yellow-600/25;
blockquote {
@apply border-slate-400 dark:border-slate-400 text-slate-800 dark:text-slate-300;
p {
@apply text-slate-600 dark:text-slate-300;
}
}
}
&.is-image {
@apply rounded-lg;
.message__mail-head {
@apply px-4 py-2;
}
}
}
+ .left {
@apply mt-2.5;
.bubble {
@apply rounded-tl-lg;
}
}
+ .unread--toast {
+ .left {
@apply rounded-lg;
.bubble {
@apply rounded-tl-lg;
}
}
+ .right {
@apply mt-0;
}
}
}
&.center {
@apply items-center justify-center;
}
.wrap {
max-width: Min(31rem, 84%);
@apply my-0 mx-4;
.sender--name {
@apply text-xs mb-1;
}
}
.sender--thumbnail {
@apply h-3 mr-3 mt-0.5 w-3 rounded-full;
}
.activity-wrap {
@apply flex justify-center text-sm my-1 mx-0 py-1 pr-0.5 pl-2.5 bg-slate-50 dark:bg-slate-600 text-slate-800 dark:text-slate-100 rounded-md border border-slate-100 dark:border-slate-600 border-solid;
.is-text {
@apply inline-flex items-center text-start 2xl:flex;
}
}
}
.activity-wrap .message-text__wrap {
.text-content p {
@apply mb-0;
}
}
.conversation-footer {
@apply flex relative flex-col;
}
.left .bubble .text-content {
h1,
h2,
h3,
h4,
h5,
h6 {
@apply text-slate-800 dark:text-slate-100;
}
a {
@apply text-woot-500 dark:text-woot-500 underline;
}
p:last-child {
@apply mb-0;
}
}
.right .bubble .text-content {
h1,
h2,
h3,
h4,
h5,
h6 {
@apply text-white dark:text-white;
}
a {
@apply text-white dark:text-white underline;
}
p:last-child {
@apply mb-0;
}
}

View File

@@ -1,77 +0,0 @@
.tabs--container {
@apply flex;
}
.tabs--container--with-border {
@apply border-b border-b-n-weak;
}
.tabs--container--compact.tab--chat-type {
.tabs-title {
a {
@apply py-2 text-sm;
}
}
}
.tabs {
@apply border-r-0 border-l-0 border-t-0 flex min-w-[6.25rem] py-0 px-4 list-none mb-0;
}
.tabs--with-scroll {
@apply overflow-hidden py-0 px-1;
max-width: calc(100% - 64px);
}
.tabs--scroll-button {
@apply items-center rounded-none cursor-pointer flex h-auto justify-center min-w-[2rem];
}
// Tab chat type
.tab--chat-type {
@apply flex;
.tabs-title {
a {
@apply text-base font-medium py-3;
}
}
}
.tabs-title {
@apply flex-shrink-0 my-0 mx-2;
.badge {
@apply bg-n-alpha-black2 dark:bg-n-solid-3 rounded-md text-n-slate-11 h-5 flex items-center justify-center text-xxs font-semibold my-0 mx-1 px-1 py-0;
}
&:first-child {
@apply ml-0;
}
&:last-child {
@apply mr-0;
}
&:hover,
&:focus {
a {
@apply text-n-slate-12;
}
}
a {
@apply flex items-center flex-row border-b py-2.5 select-none cursor-pointer border-transparent text-n-slate-11 text-sm top-[1px] relative;
transition: border-color 0.15s $swift-ease-out-function;
}
&.is-active {
a {
@apply border-b border-n-brand text-n-blue-text;
}
.badge {
@apply bg-n-brand/10 dark:bg-n-brand/20 text-n-blue-text;
}
}
}

View File

@@ -1,90 +0,0 @@
table {
@apply border-spacing-0 text-sm w-full;
}
.woot-table {
thead {
th {
@apply font-semibold tracking-[1px] text-left px-2.5 uppercase text-slate-900 dark:text-slate-200;
}
}
tbody {
tr {
@apply border-b border-slate-50 dark:border-slate-800/30;
}
td {
@apply p-2.5 text-slate-700 dark:text-slate-100;
}
}
tr {
.show-if-hover {
transition: opacity 0.2s $swift-ease-out-function;
@apply opacity-0;
}
&:hover {
.show-if-hover {
@apply opacity-100;
}
}
}
.agent-name {
@apply block font-medium capitalize;
}
.woot-thumbnail {
@apply rounded-full h-[3.125rem] w-[3.125rem];
}
.button-wrapper {
@apply flex justify-start flex-row min-w-[12.5rem] gap-1;
}
.button {
margin: 0;
}
}
.ve-table {
.ve-table-container.ve-table-border-around {
@apply border-slate-200 dark:border-slate-700;
}
.ve-table-content {
.ve-table-header .ve-table-header-tr .ve-table-header-th {
@apply bg-slate-50 dark:bg-slate-800 text-slate-800 dark:text-slate-100 border-slate-100 dark:border-slate-700/50;
}
.ve-table-body .ve-table-body-tr .ve-table-body-td {
@apply bg-white dark:bg-slate-900 text-slate-900 dark:text-slate-100 border-slate-75 dark:border-slate-800;
}
.ve-table-body.ve-table-row-hover .ve-table-body-tr:hover td {
@apply bg-slate-50 dark:bg-slate-700 text-slate-800 dark:text-slate-100;
}
}
}
.table-pagination {
.ve-pagination-total {
@apply text-slate-600 dark:text-slate-200;
}
.ve-pagination-goto {
@apply text-slate-600 dark:text-slate-200;
.ve-pagination-goto-input {
@apply bg-white dark:bg-slate-900 text-slate-600 dark:text-slate-200;
}
}
.ve-pagination-li {
@apply bg-white dark:bg-slate-900 text-slate-600 dark:text-slate-200 border-slate-75 dark:border-slate-700;
}
}

View File

@@ -40,9 +40,9 @@ const handleSubmit = campaignDetails => {
<template>
<div
class="w-[25rem] z-50 min-w-0 absolute top-10 ltr:right-0 rtl:left-0 bg-n-alpha-3 backdrop-blur-[100px] p-6 rounded-xl border border-slate-50 dark:border-slate-900 shadow-md flex flex-col gap-6 max-h-[85vh] overflow-y-auto"
class="w-[25rem] z-50 min-w-0 absolute top-10 ltr:right-0 rtl:left-0 bg-n-alpha-3 backdrop-blur-[100px] p-6 rounded-xl border border-n-weak shadow-md flex flex-col gap-6 max-h-[85vh] overflow-y-auto"
>
<h3 class="text-base font-medium text-slate-900 dark:text-slate-50">
<h3 class="text-base font-medium text-n-slate-12">
{{ t(`CAMPAIGN.LIVE_CHAT.CREATE.TITLE`) }}
</h3>
<LiveChatCampaignForm

View File

@@ -306,7 +306,7 @@ defineExpose({ prepareCampaignDetails, isSubmitDisabled });
variant="faded"
color="slate"
:label="t('CAMPAIGN.LIVE_CHAT.CREATE.FORM.BUTTONS.CANCEL')"
class="w-full bg-n-alpha-2 n-blue-text hover:bg-n-alpha-3"
class="w-full bg-n-alpha-2 text-n-blue-text hover:bg-n-alpha-3"
@click="handleCancel"
/>
<Button

View File

@@ -39,9 +39,9 @@ const handleClose = () => emit('close');
<template>
<div
class="w-[25rem] z-50 min-w-0 absolute top-10 ltr:right-0 rtl:left-0 bg-n-alpha-3 backdrop-blur-[100px] p-6 rounded-xl border border-slate-50 dark:border-slate-900 shadow-md flex flex-col gap-6"
class="w-[25rem] z-50 min-w-0 absolute top-10 ltr:right-0 rtl:left-0 bg-n-alpha-3 backdrop-blur-[100px] p-6 rounded-xl border border-n-weak shadow-md flex flex-col gap-6"
>
<h3 class="text-base font-medium text-slate-900 dark:text-slate-50">
<h3 class="text-base font-medium text-n-slate-12">
{{ t(`CAMPAIGN.SMS.CREATE.TITLE`) }}
</h3>
<SMSCampaignForm @submit="handleSubmit" @cancel="handleClose" />

View File

@@ -174,7 +174,7 @@ const handleSubmit = async () => {
color="slate"
type="button"
:label="t('CAMPAIGN.SMS.CREATE.FORM.BUTTONS.CANCEL')"
class="w-full bg-n-alpha-2 n-blue-text hover:bg-n-alpha-3"
class="w-full bg-n-alpha-2 text-n-blue-text hover:bg-n-alpha-3"
@click="handleCancel"
/>
<Button

View File

@@ -130,7 +130,7 @@ const onMergeContacts = async () => {
variant="faded"
color="slate"
:label="t('CONTACTS_LAYOUT.SIDEBAR.MERGE.BUTTONS.CANCEL')"
class="w-full bg-n-alpha-2 n-blue-text hover:bg-n-alpha-3"
class="w-full bg-n-alpha-2 text-n-blue-text hover:bg-n-alpha-3"
@click="resetState"
/>
<Button

View File

@@ -35,7 +35,7 @@ const messageClass = computed(() => {
case 'error':
return 'text-n-ruby-9 dark:text-n-ruby-9';
case 'success':
return 'text-green-500 dark:text-green-400';
return 'text-n-teal-10 dark:text-n-teal-10';
default:
return 'text-n-slate-11 dark:text-n-slate-11';
}

View File

@@ -35,12 +35,12 @@ defineProps({
<div class="flex flex-col items-center justify-center gap-6">
<div class="flex flex-col items-center justify-center gap-3">
<h2
class="text-3xl font-medium text-center text-slate-900 dark:text-white font-interDisplay"
class="text-3xl font-medium text-center text-n-slate-12 font-interDisplay"
>
{{ title }}
</h2>
<p
class="max-w-xl text-base text-center text-slate-600 dark:text-slate-300 font-interDisplay tracking-[0.3px]"
class="max-w-xl text-base text-center text-n-slate-11 font-interDisplay tracking-[0.3px]"
>
{{ subtitle }}
</p>

View File

@@ -70,7 +70,7 @@ const category = {
<div
v-for="(article, index) in articles"
:key="index"
class="px-20 py-4 bg-white dark:bg-slate-900"
class="px-20 py-4 bg-n-background"
>
<ArticleCard
:id="article.id"

View File

@@ -32,7 +32,7 @@ const categories = [
<div
v-for="(category, index) in categories"
:key="index"
class="px-20 py-4 bg-white dark:bg-slate-900"
class="px-20 py-4 bg-n-background"
>
<CategoryCard
:id="category.id"

View File

@@ -121,11 +121,7 @@ const handleAction = ({ action, value }) => {
</div>
<span
class="text-sm line-clamp-3"
:class="
hasDescription
? 'text-slate-500 dark:text-slate-400'
: 'text-slate-400 dark:text-slate-700'
"
:class="hasDescription ? 'text-n-slate-11' : 'text-n-slate-9'"
>
{{ description }}
</span>

View File

@@ -8,7 +8,7 @@ import ArticleEmptyState from './ArticleEmptyState.vue';
:layout="{ type: 'single', width: '1100px' }"
>
<Variant title="Article Empty State">
<div class="w-full h-full px-20 mx-auto bg-white dark:bg-slate-900">
<div class="w-full h-full px-20 mx-auto bg-n-background">
<ArticleEmptyState />
</div>
</Variant>

View File

@@ -8,7 +8,7 @@ import PortalEmptyState from './PortalEmptyState.vue';
:layout="{ type: 'single', width: '1100px' }"
>
<Variant title="Portal Empty State">
<div class="w-full h-full px-20 mx-auto bg-white dark:bg-slate-900">
<div class="w-full h-full px-20 mx-auto bg-n-background">
<PortalEmptyState />
</div>
</Variant>

View File

@@ -14,7 +14,7 @@ const locales = [
:layout="{ type: 'grid', width: '800px' }"
>
<Variant title="Locale Card">
<div class="px-10 py-4 bg-white dark:bg-slate-900">
<div class="px-10 py-4 bg-n-background">
<div v-for="(locale, index) in locales" :key="index" class="px-20 py-2">
<LocaleCard
:locale="locale.name"

View File

@@ -55,9 +55,7 @@ const handleAction = ({ action, value }) => {
<CardLayout>
<div class="flex justify-between gap-2">
<div class="flex items-center justify-start gap-2">
<span
class="text-sm font-medium text-slate-900 dark:text-slate-50 line-clamp-1"
>
<span class="text-sm font-medium text-n-slate-12 line-clamp-1">
{{ locale }} ({{ localeCode }})
</span>
<span
@@ -69,9 +67,7 @@ const handleAction = ({ action, value }) => {
</div>
<div class="flex items-center justify-end gap-4">
<div class="flex items-center gap-4">
<span
class="text-sm text-slate-500 dark:text-slate-400 whitespace-nowrap"
>
<span class="text-sm text-n-slate-11 whitespace-nowrap">
{{
$t(
'HELP_CENTER.LOCALES_PAGE.LOCALE_CARD.ARTICLES_COUNT',
@@ -79,10 +75,8 @@ const handleAction = ({ action, value }) => {
)
}}
</span>
<div class="w-px h-3 bg-slate-75 dark:bg-slate-800" />
<span
class="text-sm text-slate-500 dark:text-slate-400 whitespace-nowrap"
>
<div class="w-px h-3 bg-n-weak" />
<span class="text-sm text-n-slate-11 whitespace-nowrap">
{{
$t(
'HELP_CENTER.LOCALES_PAGE.LOCALE_CARD.CATEGORIES_COUNT',

View File

@@ -146,7 +146,7 @@ const previewArticle = () => {
<style lang="scss" scoped>
::v-deep {
.ProseMirror .empty-node::before {
@apply text-slate-200 dark:text-slate-500 text-base;
@apply text-n-slate-10 text-base;
}
.ProseMirror-menubar-wrapper {
@@ -161,7 +161,7 @@ const previewArticle = () => {
.editor-root .has-selection {
.ProseMirror-menubar {
@apply h-8 rounded-lg !px-2 z-50 bg-slate-50 dark:bg-slate-800 items-center gap-4 ml-0 mb-0 shadow-md border border-slate-75 dark:border-slate-700/50;
@apply h-8 rounded-lg !px-2 z-50 bg-n-solid-3 items-center gap-4 ml-0 mb-0 shadow-md outline outline-1 outline-n-weak;
display: flex;
top: var(--selection-top, auto) !important;
left: var(--selection-left, 0) !important;
@@ -180,6 +180,10 @@ const previewArticle = () => {
}
}
}
.ProseMirror-menu-active {
@apply bg-n-slate-3;
}
}
}
}

View File

@@ -206,7 +206,7 @@ onMounted(() => {
/>
</OnClickOutside>
</div>
<div class="w-px h-3 bg-slate-50 dark:bg-slate-800" />
<div class="w-px h-3 bg-n-weak" />
<div class="relative">
<OnClickOutside @trigger="openCategoryList = false">
<Button
@@ -239,7 +239,7 @@ onMounted(() => {
</OnClickOutside>
</div>
<div class="w-px h-3 bg-slate-50 dark:bg-slate-800" />
<div class="w-px h-3 bg-n-weak" />
<div class="relative">
<OnClickOutside @trigger="openProperties = false">
<Button

View File

@@ -128,7 +128,7 @@ const updateArticleStatus = async ({ value }) => {
<div class="flex items-center gap-4">
<span
v-if="isUpdating || isSaved"
class="text-xs font-medium transition-all duration-300 text-slate-500 dark:text-slate-400"
class="text-xs font-medium transition-all duration-300 text-n-slate-11"
>
{{ statusText }}
</span>

View File

@@ -64,7 +64,7 @@ const articles = [
<template>
<Story title="Pages/HelpCenter/ArticlesPage" :layout="{ type: 'single' }">
<Variant title="All Articles">
<div class="w-full min-h-screen bg-white dark:bg-slate-900">
<div class="w-full min-h-screen bg-n-background">
<ArticlesPage :articles="articles" />
</div>
</Variant>

View File

@@ -201,7 +201,7 @@ const categories = [
<template>
<Story title="Pages/HelpCenter/CategoryPage" :layout="{ type: 'single' }">
<Variant title="All Categories">
<div class="w-full min-h-screen bg-white dark:bg-slate-900">
<div class="w-full min-h-screen bg-n-background">
<CategoriesPage :categories="categories" />
</div>
</Variant>

View File

@@ -90,9 +90,9 @@ const handleCategory = async formData => {
<template>
<div
class="w-[25rem] absolute top-10 ltr:right-0 rtl:left-0 bg-n-alpha-3 backdrop-blur-[100px] p-6 rounded-xl border border-slate-50 dark:border-slate-900 shadow-md flex flex-col gap-6"
class="w-[25rem] absolute top-10 ltr:right-0 rtl:left-0 bg-n-alpha-3 backdrop-blur-[100px] p-6 rounded-xl border border-n-weak shadow-md flex flex-col gap-6"
>
<h3 class="text-base font-medium text-slate-900 dark:text-slate-50">
<h3 class="text-base font-medium text-n-slate-12">
{{
t(
`HELP_CENTER.CATEGORY_PAGE.CATEGORY_DIALOG.HEADER.${mode.toUpperCase()}`

View File

@@ -246,7 +246,7 @@ defineExpose({ state, isSubmitDisabled });
variant="faded"
color="slate"
:label="t('HELP_CENTER.CATEGORY_PAGE.CATEGORY_DIALOG.BUTTONS.CANCEL')"
class="w-full bg-n-alpha-2 n-blue-text hover:bg-n-alpha-3"
class="w-full bg-n-alpha-2 text-n-blue-text hover:bg-n-alpha-3"
@click="handleCancel"
/>
<Button

View File

@@ -147,10 +147,8 @@ const handleBreadcrumbClick = () => {
/>
</OnClickOutside>
</div>
<div class="w-px h-3.5 rounded my-auto bg-slate-75 dark:bg-slate-800" />
<span
class="min-w-0 text-sm font-medium truncate text-slate-800 dark:text-slate-100"
>
<div class="w-px h-3.5 rounded my-auto bg-n-weak" />
<span class="min-w-0 text-sm font-medium truncate text-n-slate-12">
{{
t('HELP_CENTER.CATEGORY_PAGE.CATEGORY_HEADER.CATEGORIES_COUNT', {
n: categoriesCount,

View File

@@ -44,7 +44,7 @@ const locales = [
<template>
<Story title="Pages/HelpCenter/LocalePage" :layout="{ type: 'single' }">
<Variant title="All Locales">
<div class="w-full min-h-screen bg-white dark:bg-slate-900">
<div class="w-full min-h-screen bg-n-background">
<LocalesPage :locales="locales" />
</div>
</Variant>

View File

@@ -35,7 +35,7 @@ const localeCount = computed(() => props.locales?.length);
<template #header-actions>
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<span class="text-sm font-medium text-slate-800 dark:text-slate-100">
<span class="text-sm font-medium text-n-slate-12">
{{ $t('HELP_CENTER.LOCALES_PAGE.LOCALES_COUNT', localeCount) }}
</span>
</div>

View File

@@ -211,7 +211,7 @@ const handleAvatarDelete = () => {
class="grid items-start justify-between w-full gap-2 grid-cols-[200px,1fr]"
>
<label
class="text-sm font-medium whitespace-nowrap py-2.5 text-slate-900 dark:text-slate-50"
class="text-sm font-medium whitespace-nowrap py-2.5 text-n-slate-12"
>
{{ t('HELP_CENTER.PORTAL_SETTINGS.FORM.NAME.LABEL') }}
</label>
@@ -229,7 +229,7 @@ const handleAvatarDelete = () => {
class="grid items-start justify-between w-full gap-2 grid-cols-[200px,1fr]"
>
<label
class="text-sm font-medium whitespace-nowrap py-2.5 text-slate-900 dark:text-slate-50"
class="text-sm font-medium whitespace-nowrap py-2.5 text-n-slate-12"
>
{{ t('HELP_CENTER.PORTAL_SETTINGS.FORM.HEADER_TEXT.LABEL') }}
</label>
@@ -245,7 +245,7 @@ const handleAvatarDelete = () => {
class="grid items-start justify-between w-full gap-2 grid-cols-[200px,1fr]"
>
<label
class="text-sm font-medium whitespace-nowrap text-slate-900 py-2.5 dark:text-slate-50"
class="text-sm font-medium whitespace-nowrap text-n-slate-12 py-2.5"
>
{{ t('HELP_CENTER.PORTAL_SETTINGS.FORM.PAGE_TITLE.LABEL') }}
</label>
@@ -261,7 +261,7 @@ const handleAvatarDelete = () => {
class="grid items-start justify-between w-full gap-2 grid-cols-[200px,1fr]"
>
<label
class="text-sm font-medium whitespace-nowrap text-slate-900 py-2.5 dark:text-slate-50"
class="text-sm font-medium whitespace-nowrap text-n-slate-12 py-2.5"
>
{{ t('HELP_CENTER.PORTAL_SETTINGS.FORM.HOME_PAGE_LINK.LABEL') }}
</label>
@@ -281,7 +281,7 @@ const handleAvatarDelete = () => {
class="grid items-start justify-between w-full gap-2 grid-cols-[200px,1fr]"
>
<label
class="text-sm font-medium whitespace-nowrap py-2.5 text-slate-900 dark:text-slate-50"
class="text-sm font-medium whitespace-nowrap py-2.5 text-n-slate-12"
>
{{ t('HELP_CENTER.PORTAL_SETTINGS.FORM.SLUG.LABEL') }}
</label>
@@ -299,7 +299,7 @@ const handleAvatarDelete = () => {
class="grid items-start justify-between w-full gap-2 grid-cols-[200px,1fr]"
>
<label
class="text-sm font-medium whitespace-nowrap py-2.5 text-slate-900 dark:text-slate-50"
class="text-sm font-medium whitespace-nowrap py-2.5 text-n-slate-12"
>
{{ t('HELP_CENTER.PORTAL_SETTINGS.FORM.LIVE_CHAT_WIDGET.LABEL') }}
</label>
@@ -317,7 +317,7 @@ const handleAvatarDelete = () => {
</div>
<div class="flex items-start justify-between w-full gap-2">
<label
class="text-sm font-medium whitespace-nowrap py-2.5 text-slate-900 dark:text-slate-50"
class="text-sm font-medium whitespace-nowrap py-2.5 text-n-slate-12"
>
{{ t('HELP_CENTER.PORTAL_SETTINGS.FORM.BRAND_COLOR.LABEL') }}
</label>

View File

@@ -5,7 +5,7 @@ import PortalSettings from './PortalSettings.vue';
<template>
<Story title="Pages/HelpCenter/PortalSettings" :layout="{ type: 'single' }">
<Variant title="Default">
<div class="w-[1000px] min-h-screen bg-white dark:bg-slate-900">
<div class="w-[1000px] min-h-screen bg-n-background">
<PortalSettings />
</div>
</Variant>

View File

@@ -81,13 +81,13 @@ const handleDeletePortal = () => {
:is-fetching="isFetching"
@update-portal="handleUpdatePortal"
/>
<div class="w-full h-px bg-slate-50 dark:bg-slate-800/50" />
<div class="w-full h-px bg-n-weak" />
<PortalConfigurationSettings
:active-portal="activePortal"
:is-fetching="isFetching"
@update-portal-configuration="handleUpdatePortalConfiguration"
/>
<div class="w-full h-px bg-slate-50 dark:bg-slate-800/50" />
<div class="w-full h-px bg-n-weak" />
<div class="flex items-end justify-between w-full gap-4">
<div class="flex flex-col gap-2">
<h6 class="text-base font-medium text-n-slate-12">

View File

@@ -32,7 +32,7 @@ const portals = [
:layout="{ type: 'grid', width: '510px' }"
>
<Variant title="Portal Switcher">
<div class="h-[500px] p-4 bg-slate-100 dark:bg-slate-900">
<div class="h-[500px] p-4 bg-n-slate-2 dark:bg-n-background">
<PortalSwitcher
:portals="portals"
header="Choose a Portal"

View File

@@ -100,7 +100,7 @@ const redirectToPortalHomePage = () => {
<div class="flex flex-col gap-1">
<div class="flex items-center gap-2">
<h2
class="text-base font-medium cursor-pointer text-slate-900 dark:text-slate-50 w-fit hover:underline"
class="text-base font-medium cursor-pointer text-n-slate-12 w-fit hover:underline"
@click="redirectToPortalHomePage"
>
{{ t('HELP_CENTER.PORTAL_SWITCHER.PORTALS') }}
@@ -115,7 +115,7 @@ const redirectToPortalHomePage = () => {
@click="onClickPreviewPortal"
/>
</div>
<p class="text-sm text-slate-600 dark:text-slate-300">
<p class="text-sm text-n-slate-11">
{{ t('HELP_CENTER.PORTAL_SWITCHER.CREATE_PORTAL') }}
</p>
</div>

View File

@@ -5,7 +5,7 @@ import Avatar from './Avatar.vue';
<template>
<Story title="Components/Avatar" :layout="{ type: 'grid', width: '400' }">
<Variant title="Default">
<div class="flex p-4 space-x-4 bg-white dark:bg-slate-900">
<div class="flex p-4 space-x-4 bg-n-background">
<Avatar
name=""
src="https://api.dicebear.com/9.x/thumbs/svg?seed=Amaya"
@@ -16,7 +16,7 @@ import Avatar from './Avatar.vue';
</Variant>
<Variant title="Different Shapes">
<div class="gap-4 p-4 bg-white dark:bg-slate-900">
<div class="gap-4 p-4 bg-n-background">
<Avatar
src="https://api.dicebear.com/9.x/thumbs/svg?seed=Amaya"
name=""
@@ -34,7 +34,7 @@ import Avatar from './Avatar.vue';
</Variant>
<Variant title="Different Sizes">
<div class="flex flex-wrap gap-4 p-4 bg-white dark:bg-slate-900">
<div class="flex flex-wrap gap-4 p-4 bg-n-background">
<Avatar
src="https://api.dicebear.com/9.x/avataaars/svg?seed=Felix"
:size="48"
@@ -57,7 +57,7 @@ import Avatar from './Avatar.vue';
</Variant>
<Variant title="With Status">
<div class="flex flex-wrap gap-4 p-4 bg-white dark:bg-slate-900">
<div class="flex flex-wrap gap-4 p-4 bg-n-background">
<Avatar
src="https://api.dicebear.com/9.x/thumbs/svg?seed=Felix"
status="online"
@@ -77,7 +77,7 @@ import Avatar from './Avatar.vue';
</Variant>
<Variant title="With Custom Icon">
<div class="flex flex-wrap gap-4 p-4 bg-white dark:bg-slate-900">
<div class="flex flex-wrap gap-4 p-4 bg-n-background">
<Avatar name="Custom Icon" icon-name="i-lucide-user" :size="48" />
<Avatar
name="Custom Industry"
@@ -88,7 +88,7 @@ import Avatar from './Avatar.vue';
</Variant>
<Variant title="Upload States">
<div class="flex flex-wrap gap-4 p-4 bg-white dark:bg-slate-900">
<div class="flex flex-wrap gap-4 p-4 bg-n-background">
<!-- Empty state with upload -->
<Avatar name="Upload New" allow-upload :size="48" />
@@ -103,7 +103,7 @@ import Avatar from './Avatar.vue';
</Variant>
<Variant title="Name Initials">
<div class="flex flex-wrap gap-4 p-4 bg-white dark:bg-slate-900">
<div class="flex flex-wrap gap-4 p-4 bg-n-background">
<Avatar name="Catherine" :size="48" />
<Avatar name="John Doe" :size="48" />
<Avatar name="Rose Doe John" :size="48" />

View File

@@ -29,32 +29,32 @@ const longBreadcrumb = ref([
:layout="{ type: 'grid', width: '800px' }"
>
<Variant title="Single Item">
<div class="w-full p-4 bg-white dark:bg-slate-900">
<div class="w-full p-4 bg-n-background">
<Breadcrumb :items="singleItem" />
</div>
</Variant>
<Variant title="Two Items">
<div class="w-full p-4 bg-white dark:bg-slate-900">
<div class="w-full p-4 bg-n-background">
<Breadcrumb :items="twoItems" />
</div>
</Variant>
<Variant title="Three Items with Count">
<div class="w-full p-4 bg-white dark:bg-slate-900">
<div class="w-full p-4 bg-n-background">
<Breadcrumb :items="threeItems" count-label="articles" />
</div>
</Variant>
<Variant title="Long Breadcrumb">
<div class="w-full p-4 bg-white dark:bg-slate-900">
<div class="w-full p-4 bg-n-background">
<Breadcrumb :items="longBreadcrumb" count-label="articles" />
</div>
</Variant>
<Variant title="RTL Support">
<div dir="rtl">
<div class="w-full p-4 bg-white dark:bg-slate-900">
<div class="w-full p-4 bg-n-background">
<Breadcrumb :items="threeItems" count-label="articles" />
</div>
</div>

View File

@@ -36,9 +36,7 @@ const onClick = event => {
icon="i-lucide-chevron-right"
class="flex-shrink-0 mx-2 size-4 text-n-slate-11 dark:text-n-slate-11"
/>
<span
class="text-sm truncate text-slate-900 dark:text-slate-50 max-w-56"
>
<span class="text-sm truncate text-n-slate-12 max-w-56">
{{ item.emoji ? item.emoji : '' }} {{ item.label }}
</span>
</template>

View File

@@ -11,7 +11,7 @@ const SIZES = ['default', 'sm', 'lg'];
<Story title="Components/Button" :layout="{ type: 'grid', width: '800px' }">
<!-- Basic Variants -->
<Variant title="Basic Variants">
<div class="flex flex-wrap gap-2 p-4 bg-white dark:bg-slate-900">
<div class="flex flex-wrap gap-2 p-4 bg-n-background">
<Button
v-for="variant in VARIANTS"
:key="variant"
@@ -23,7 +23,7 @@ const SIZES = ['default', 'sm', 'lg'];
<!-- Colors -->
<Variant title="Color Variants">
<div class="flex flex-wrap gap-2 p-4 bg-white dark:bg-slate-900">
<div class="flex flex-wrap gap-2 p-4 bg-n-background">
<Button
v-for="color in COLORS"
:key="color"
@@ -35,16 +35,14 @@ const SIZES = ['default', 'sm', 'lg'];
<!-- Sizes -->
<Variant title="Size Variants">
<div
class="flex flex-wrap items-center gap-2 p-4 bg-white dark:bg-slate-900"
>
<div class="flex flex-wrap items-center gap-2 p-4 bg-n-background">
<Button v-for="size in SIZES" :key="size" :label="size" :size="size" />
</div>
</Variant>
<!-- Icons -->
<Variant title="Icons">
<div class="flex flex-wrap gap-2 p-4 bg-white dark:bg-slate-900">
<div class="flex flex-wrap gap-2 p-4 bg-n-background">
<Button label="Leading Icon" icon="i-lucide-plus" />
<Button label="Trailing Icon" icon="i-lucide-plus" trailing-icon />
<Button icon="i-lucide-plus" />
@@ -53,7 +51,7 @@ const SIZES = ['default', 'sm', 'lg'];
<!-- Loading State -->
<Variant title="Loading State">
<div class="flex flex-wrap gap-2 p-4 bg-white dark:bg-slate-900">
<div class="flex flex-wrap gap-2 p-4 bg-n-background">
<Button label="Loading" is-loading />
<Button label="Loading" variant="outline" is-loading />
<Button is-loading icon="i-lucide-plus" />
@@ -62,7 +60,7 @@ const SIZES = ['default', 'sm', 'lg'];
<!-- Disabled State -->
<Variant title="Disabled State">
<div class="flex flex-wrap gap-2 p-4 bg-white dark:bg-slate-900">
<div class="flex flex-wrap gap-2 p-4 bg-n-background">
<Button label="Disabled" disabled />
<Button label="Disabled Outline" variant="outline" disabled />
<Button label="Disabled Icon" icon="delete" disabled />
@@ -78,7 +76,7 @@ const SIZES = ['default', 'sm', 'lg'];
<!-- Color Combinations -->
<Variant title="Color & Variant Combinations">
<div class="flex flex-wrap gap-2 p-4 bg-white dark:bg-slate-900">
<div class="flex flex-wrap gap-2 p-4 bg-n-background">
<template v-for="color in COLORS" :key="color">
<Button
v-for="variant in VARIANTS"
@@ -93,7 +91,7 @@ const SIZES = ['default', 'sm', 'lg'];
<!-- Icon Positions -->
<Variant title="Icon Positions & Sizes">
<div class="flex flex-wrap gap-2 p-4 bg-white dark:bg-slate-900">
<div class="flex flex-wrap gap-2 p-4 bg-n-background">
<template v-for="size in SIZES" :key="size">
<Button
:label="`${size} Leading`"
@@ -113,7 +111,7 @@ const SIZES = ['default', 'sm', 'lg'];
<!-- Ghost & Link Variants -->
<Variant title="Ghost & Link Variants">
<div class="flex flex-wrap gap-2 p-4 bg-white dark:bg-slate-900">
<div class="flex flex-wrap gap-2 p-4 bg-n-background">
<Button label="Ghost Button" variant="ghost" color="slate" />
<Button
label="Ghost with Icon"

View File

@@ -15,7 +15,7 @@ const incrementCount = () => {
:layout="{ type: 'grid', width: '400px' }"
>
<Variant title="Basic">
<div class="grid gap-2 p-4 bg-white dark:bg-slate-900">
<div class="grid gap-2 p-4 bg-n-background">
<p>{{ count }}</p>
<ConfirmButton
label="Delete"
@@ -26,7 +26,7 @@ const incrementCount = () => {
</Variant>
<Variant title="Color Change">
<div class="grid gap-2 p-4 bg-white dark:bg-slate-900">
<div class="grid gap-2 p-4 bg-n-background">
<p>{{ count }}</p>
<ConfirmButton
label="Archive"

View File

@@ -12,7 +12,7 @@ import { assistantsList } from 'dashboard/components-next/captain/pageComponents
<div
v-for="(assistant, index) in assistantsList"
:key="index"
class="px-20 py-4 bg-white dark:bg-slate-900"
class="px-20 py-4 bg-n-background"
>
<AssistantCard
:id="assistant.id"

View File

@@ -12,7 +12,7 @@ import { documentsList } from 'dashboard/components-next/captain/pageComponents/
<div
v-for="(doc, index) in documentsList"
:key="index"
class="px-20 py-4 bg-white dark:bg-slate-900"
class="px-20 py-4 bg-n-background"
>
<DocumentCard
:id="doc.id"

View File

@@ -12,7 +12,7 @@ import { inboxes } from 'dashboard/components-next/captain/pageComponents/emptyS
<div
v-for="inbox in inboxes"
:key="inbox.id"
class="px-20 py-4 bg-white dark:bg-slate-900"
class="px-20 py-4 bg-n-background"
>
<InboxCard :id="inbox.id" :inbox="inbox" />
</div>

View File

@@ -12,7 +12,7 @@ import { responsesList } from 'dashboard/components-next/captain/pageComponents/
<div
v-for="(response, index) in responsesList"
:key="index"
class="px-20 py-4 bg-white dark:bg-slate-900"
class="px-20 py-4 bg-n-background"
>
<ResponseCard
:id="response.id"

View File

@@ -159,7 +159,7 @@ watch(
variant="faded"
color="slate"
:label="t('CAPTAIN.FORM.CANCEL')"
class="w-full bg-n-alpha-2 n-blue-text hover:bg-n-alpha-3"
class="w-full bg-n-alpha-2 text-n-blue-text hover:bg-n-alpha-3"
@click="handleCancel"
/>
<Button

View File

@@ -99,7 +99,7 @@ const handleSubmit = async () => {
variant="faded"
color="slate"
:label="t('CAPTAIN.FORM.CANCEL')"
class="w-full bg-n-alpha-2 n-blue-text hover:bg-n-alpha-3"
class="w-full bg-n-alpha-2 text-n-blue-text hover:bg-n-alpha-3"
@click="handleCancel"
/>
<Button

View File

@@ -100,7 +100,7 @@ const handleSubmit = async () => {
variant="faded"
color="slate"
:label="t('CAPTAIN.FORM.CANCEL')"
class="w-full bg-n-alpha-2 n-blue-text hover:bg-n-alpha-3"
class="w-full bg-n-alpha-2 text-n-blue-text hover:bg-n-alpha-3"
@click="handleCancel"
/>
<Button

View File

@@ -146,7 +146,7 @@ watch(
variant="faded"
color="slate"
:label="t('CAPTAIN.FORM.CANCEL')"
class="w-full bg-n-alpha-2 n-blue-text hover:bg-n-alpha-3"
class="w-full bg-n-alpha-2 text-n-blue-text hover:bg-n-alpha-3"
@click="handleCancel"
/>
<Button

View File

@@ -90,7 +90,7 @@ const pickerRef = ref(null);
input,
.vc-input__input {
@apply bg-n-background text-slate-900 dark:text-slate-50 rounded-md shadow-none;
@apply bg-n-background text-n-slate-12 rounded-md shadow-none;
}
.vc-input__label {

View File

@@ -15,14 +15,14 @@ const selectedValue = ref('');
<template>
<Story title="Components/ComboBox" :layout="{ type: 'grid', width: '300px' }">
<Variant title="Default">
<div class="w-full p-4 bg-white h-80 dark:bg-slate-900">
<div class="w-full p-4 bg-n-background h-80">
<ComboBox v-model="selectedValue" :options="options" />
<p class="mt-2">Selected value: {{ selectedValue }}</p>
</div>
</Variant>
<Variant title="Disabled">
<div class="w-full p-4 bg-white h-80 dark:bg-slate-900">
<div class="w-full p-4 bg-n-background h-80">
<ComboBox :options="options" disabled />
</div>
</Variant>

View File

@@ -69,7 +69,7 @@ defineExpose({
:value="searchValue"
type="search"
:placeholder="searchPlaceholder || t('COMBOBOX.SEARCH_PLACEHOLDER')"
class="reset-base w-full py-2 pl-10 pr-2 text-sm focus:outline-none border-none rounded-t-md bg-n-solid-1 text-slate-900 dark:text-slate-50"
class="reset-base w-full py-2 pl-10 pr-2 text-sm focus:outline-none border-none rounded-t-md bg-n-solid-1 text-n-slate-12"
@input="onInputSearch"
/>
</div>
@@ -102,10 +102,7 @@ defineExpose({
class="flex-shrink-0 i-lucide-check size-4 text-n-slate-11"
/>
</li>
<li
v-if="options.length === 0"
class="px-3 py-2 text-sm text-slate-600 dark:text-slate-300"
>
<li v-if="options.length === 0" class="px-3 py-2 text-sm text-n-slate-11">
{{ emptyState || t('COMBOBOX.EMPTY_STATE') }}
</li>
</ul>

View File

@@ -20,14 +20,14 @@ const preselectedValues = ref([1, 2]);
:layout="{ type: 'grid', width: '300px' }"
>
<Variant title="Default">
<div class="w-full p-4 bg-white h-80 dark:bg-slate-900">
<div class="w-full p-4 bg-n-background h-80">
<TagMultiSelectComboBox v-model="selectedValues" :options="options" />
<p class="mt-2">Selected values: {{ selectedValues }}</p>
</div>
</Variant>
<Variant title="With Preselected Values">
<div class="w-full p-4 bg-white h-80 dark:bg-slate-900">
<div class="w-full p-4 bg-n-background h-80">
<TagMultiSelectComboBox
v-model="preselectedValues"
:options="options"
@@ -37,13 +37,13 @@ const preselectedValues = ref([1, 2]);
</Variant>
<Variant title="Disabled">
<div class="w-full p-4 bg-white h-80 dark:bg-slate-900">
<div class="w-full p-4 bg-n-background h-80">
<TagMultiSelectComboBox :options="options" disabled />
</div>
</Variant>
<Variant title="With Error">
<div class="w-full p-4 bg-white h-80 dark:bg-slate-900">
<div class="w-full p-4 bg-n-background h-80">
<TagMultiSelectComboBox
:options="options"
has-error

View File

@@ -49,7 +49,10 @@ const toggleSidebar = () => {
</script>
<template>
<div v-if="showCopilotLauncher" class="fixed bottom-4 right-4 z-50">
<div
v-if="showCopilotLauncher"
class="fixed bottom-4 ltr:right-4 rtl:left-4 z-50"
>
<div class="rounded-full bg-n-alpha-2 p-1">
<Button
icon="i-woot-captain"

View File

@@ -20,7 +20,7 @@ const handleAction = () => {
<template>
<Story title="Components/DropdownMenu" :layout="{ type: 'grid', width: 300 }">
<Variant title="Default">
<div class="p-4 bg-white h-72 dark:bg-slate-900">
<div class="p-4 bg-n-background h-72">
<div class="relative">
<Button label="Open Menu" size="sm" @click="toggleDropdown" />
<DropdownMenu
@@ -34,13 +34,13 @@ const handleAction = () => {
</Variant>
<Variant title="Always Open">
<div class="p-4 bg-white h-72 dark:bg-slate-900">
<div class="p-4 bg-n-background h-72">
<DropdownMenu :menu-items="menuItems" @action="handleAction" />
</div>
</Variant>
<Variant title="Custom Items">
<div class="p-4 bg-white h-72 dark:bg-slate-900">
<div class="p-4 bg-n-background h-72">
<DropdownMenu
:menu-items="[
{ label: 'Custom 1', action: 'custom1', icon: 'file-upload' },
@@ -53,7 +53,7 @@ const handleAction = () => {
</Variant>
<Variant title="With search">
<div class="p-4 bg-white h-72 dark:bg-slate-900">
<div class="p-4 bg-n-background h-72">
<DropdownMenu
:menu-items="[
{ label: 'Custom 1', action: 'custom1', icon: 'file-upload' },

View File

@@ -51,7 +51,7 @@ const menuItems = ref([
:layout="{ type: 'grid', width: 400, height: 800 }"
>
<Variant title="Profile Menu">
<div class="p-4 bg-white h-[500px] dark:bg-slate-900">
<div class="p-4 bg-n-background h-[500px]">
<DropdownContainer>
<template #trigger="{ toggle }">
<Button label="Open Menu" size="sm" @click="toggle" />

View File

@@ -8,13 +8,13 @@ import InlineInput from './InlineInput.vue';
:layout="{ type: 'grid', width: '400' }"
>
<Variant title="Default">
<div class="p-4 bg-white dark:bg-slate-800">
<div class="p-4 bg-n-background">
<InlineInput id="inline-input-1" placeholder="Default InlineInput" />
</div>
</Variant>
<Variant title="With Label">
<div class="p-4 bg-white dark:bg-slate-800">
<div class="p-4 bg-n-background">
<InlineInput
id="inline-input-2"
label="Username"
@@ -24,7 +24,7 @@ import InlineInput from './InlineInput.vue';
</Variant>
<Variant title="Disabled">
<div class="p-4 bg-white dark:bg-slate-800">
<div class="p-4 bg-n-background">
<InlineInput
id="inline-input-3"
label="Disabled InlineInput"
@@ -35,24 +35,24 @@ import InlineInput from './InlineInput.vue';
</Variant>
<Variant title="With Custom Classes">
<div class="flex flex-col gap-4 p-4 bg-white dark:bg-slate-800">
<div class="flex flex-col gap-4 p-4 bg-n-background">
<InlineInput
id="inline-input-4"
label="Custom Input Class"
placeholder="Custom input style"
custom-input-class="placeholder:text-green-200 dark:placeholder:text-green-800"
custom-input-class="placeholder:text-n-teal-6 dark:placeholder:text-n-teal-6"
/>
<InlineInput
id="inline-input-5"
label="Custom Label Class"
placeholder="Custom label style"
custom-label-class="text-green-600 dark:text-green-400"
custom-label-class="text-n-teal-6 dark:text-n-teal-6"
/>
</div>
</Variant>
<Variant title="Different Types">
<div class="flex flex-col gap-4 p-4 bg-white dark:bg-slate-800">
<div class="flex flex-col gap-4 p-4 bg-n-background">
<InlineInput
id="inline-input-6"
label="Text"

View File

@@ -5,25 +5,25 @@ import Input from './Input.vue';
<template>
<Story title="Components/Input" :layout="{ type: 'grid', width: '400' }">
<Variant title="Default">
<div class="p-4 bg-white dark:bg-slate-800">
<div class="p-4 bg-n-background">
<Input placeholder="Default Input" />
</div>
</Variant>
<Variant title="With Label">
<div class="p-4 bg-white dark:bg-slate-800">
<div class="p-4 bg-n-background">
<Input label="Username" placeholder="Enter your username" />
</div>
</Variant>
<Variant title="Disabled">
<div class="p-4 bg-white dark:bg-slate-800">
<div class="p-4 bg-n-background">
<Input label="Disabled Input" placeholder="Can't type here" disabled />
</div>
</Variant>
<Variant title="With Message">
<div class="flex flex-col gap-4 p-4 bg-white dark:bg-slate-800">
<div class="flex flex-col gap-4 p-4 bg-n-background">
<Input
label="Email"
placeholder="Enter your email"
@@ -46,7 +46,7 @@ import Input from './Input.vue';
</Variant>
<Variant title="Different Types">
<div class="flex flex-col gap-4 p-4 bg-white dark:bg-slate-800">
<div class="flex flex-col gap-4 p-4 bg-n-background">
<Input label="Text" type="text" placeholder="Text input" />
<Input label="Number" type="number" placeholder="Number input" />
<Input label="Password" type="password" placeholder="Password input" />
@@ -56,11 +56,11 @@ import Input from './Input.vue';
</Variant>
<Variant title="Custom Input Class">
<div class="p-4 bg-white dark:bg-slate-800">
<div class="p-4 bg-n-background">
<Input
label="Custom Style"
placeholder="Custom input class"
custom-input-class="border-yellow-500 dark:border-yellow-700"
custom-input-class="border-n-amber-5 dark:border-n-amber-5"
/>
</div>
</Variant>

View File

@@ -38,7 +38,7 @@ const messageClass = computed(() => {
case 'error':
return 'text-n-ruby-9 dark:text-n-ruby-9';
case 'success':
return 'text-green-500 dark:text-green-400';
return 'text-n-teal-10 dark:text-n-teal-10';
default:
return 'text-n-slate-11 dark:text-n-slate-11';
}

View File

@@ -74,7 +74,7 @@ const action = computed(() => ({
<style lang="scss">
.join-call-button {
margin: var(--space-small) 0;
margin: 0.5rem 0;
}
.video-call--container {
@@ -83,9 +83,9 @@ const action = computed(() => ({
right: 0;
width: 100%;
height: 100%;
z-index: var(--z-index-high);
padding: var(--space-smaller);
background: var(--b-800);
z-index: 1000;
padding: 0.25rem;
@apply bg-n-background;
iframe {
width: 100%;
@@ -95,7 +95,7 @@ const action = computed(() => ({
button {
position: absolute;
top: var(--space-smaller);
top: 0.25rem;
right: 10rem;
}
}

View File

@@ -34,7 +34,7 @@ const displayFileName = computed(() => {
const textColorClass = computed(() => {
const colorMap = {
'7z': 'dark:text-[#EDEEF0] text-[#2F265F]',
csv: 'text-amber-12',
csv: 'text-n-amber-12',
doc: 'dark:text-[#D6E1FF] text-[#1F2D5C]', // indigo-12
docx: 'dark:text-[#D6E1FF] text-[#1F2D5C]', // indigo-12
json: 'text-n-slate-12',

View File

@@ -23,7 +23,7 @@ const singlePageState = createPaginationState(1, 10, 16);
:layout="{ type: 'grid', width: '957' }"
>
<Variant title="Default">
<div class="p-4 bg-white dark:bg-slate-900">
<div class="p-4 bg-n-background">
<PaginationFooter
:current-page="defaultState.currentPage.value"
:total-items="defaultState.totalItems"
@@ -34,7 +34,7 @@ const singlePageState = createPaginationState(1, 10, 16);
</Variant>
<Variant title="Middle Page">
<div class="p-4 bg-white dark:bg-slate-900">
<div class="p-4 bg-n-background">
<PaginationFooter
:current-page="middlePageState.currentPage.value"
:total-items="middlePageState.totalItems"
@@ -45,7 +45,7 @@ const singlePageState = createPaginationState(1, 10, 16);
</Variant>
<Variant title="Last Page">
<div class="p-4 bg-white dark:bg-slate-900">
<div class="p-4 bg-n-background">
<PaginationFooter
:current-page="lastPageState.currentPage.value"
:total-items="lastPageState.totalItems"
@@ -56,7 +56,7 @@ const singlePageState = createPaginationState(1, 10, 16);
</Variant>
<Variant title="Custom Items Per Page">
<div class="p-4 bg-white dark:bg-slate-900">
<div class="p-4 bg-n-background">
<PaginationFooter
:current-page="customItemsState.currentPage.value"
:total-items="customItemsState.totalItems"
@@ -67,7 +67,7 @@ const singlePageState = createPaginationState(1, 10, 16);
</Variant>
<Variant title="Single Page">
<div class="p-4 bg-white dark:bg-slate-900">
<div class="p-4 bg-n-background">
<PaginationFooter
:current-page="singlePageState.currentPage.value"
:total-items="singlePageState.totalItems"

View File

@@ -23,10 +23,11 @@ const showBadge = useMapGetter(props.getterKeys.badge);
:is="to ? 'router-link' : 'div'"
class="flex items-center gap-2 px-2 py-1.5 rounded-lg h-8"
role="button"
draggable="false"
:to="to"
:title="label"
:class="{
'n-blue-text bg-n-alpha-2 font-medium': isActive && !hasActiveChild,
'text-n-blue-text bg-n-alpha-2 font-medium': isActive && !hasActiveChild,
'text-n-slate-12 font-medium': hasActiveChild,
'text-n-slate-11 hover:bg-n-alpha-2': !isActive && !hasActiveChild,
}"

View File

@@ -33,7 +33,7 @@ const shouldRenderComponent = computed(() => {
:title="label"
class="flex h-8 items-center gap-2 px-2 py-1 rounded-lg max-w-[9.438rem] hover:bg-gradient-to-r from-transparent via-n-slate-3/70 to-n-slate-3/70 group"
:class="{
'n-blue-text bg-n-alpha-2 active': active,
'text-n-blue-text bg-n-alpha-2 active': active,
}"
>
<component

View File

@@ -111,11 +111,7 @@ const allowedMenuItems = computed(() => {
</script>
<template>
<DropdownContainer
class="relative w-full min-w-0"
:class="{ 'z-20': isOpen }"
@close="emit('close')"
>
<DropdownContainer class="relative w-full min-w-0" @close="emit('close')">
<template #trigger="{ toggle, isOpen }">
<button
class="flex gap-2 items-center rounded-lg cursor-pointer text-left w-full hover:bg-n-alpha-1 p-1"

View File

@@ -19,7 +19,7 @@ const updateValue = () => {
<template>
<button
type="button"
class="relative h-4 transition-colors duration-200 ease-in-out rounded-full w-7 focus:outline-none focus:ring-1 focus:ring-primary-500 focus:ring-offset-n-slate-2 focus:ring-offset-2"
class="relative h-4 transition-colors duration-200 ease-in-out rounded-full w-7 focus:outline-none focus:ring-1 focus:ring-n-brand focus:ring-offset-n-slate-2 focus:ring-offset-2"
:class="modelValue ? 'bg-n-brand' : 'bg-n-alpha-1 dark:bg-n-alpha-2'"
role="switch"
:aria-checked="modelValue"
@@ -30,8 +30,8 @@ const updateValue = () => {
class="absolute top-0.5 left-0.5 h-3 w-3 transform rounded-full shadow-sm transition-transform duration-200 ease-in-out"
:class="
modelValue
? 'translate-x-3 bg-white'
: 'translate-x-0 bg-white dark:bg-n-black'
? 'translate-x-3 bg-n-background'
: 'translate-x-0 bg-n-background'
"
/>
</button>

View File

@@ -25,13 +25,13 @@ const handleTabChanged = tab => {
<template>
<Story title="Components/TabBar" :layout="{ type: 'grid', width: '920px' }">
<Variant title="Default">
<div class="p-4 bg-white dark:bg-slate-900">
<div class="p-4 bg-n-background">
<TabBar :tabs="defaultTabs" @tab-changed="handleTabChanged" />
</div>
</Variant>
<Variant title="Custom Tabs with Initial Tab">
<div class="p-4 bg-white dark:bg-slate-900">
<div class="p-4 bg-n-background">
<TabBar
:tabs="customTabs"
:initial-active-tab="1"
@@ -41,7 +41,7 @@ const handleTabChanged = tab => {
</Variant>
<Variant title="No Counts">
<div class="p-4 bg-white dark:bg-slate-900">
<div class="p-4 bg-n-background">
<TabBar
:tabs="[{ label: 'Tab 1' }, { label: 'Tab 2' }, { label: 'Tab 3' }]"
@tab-changed="handleTabChanged"
@@ -50,7 +50,7 @@ const handleTabChanged = tab => {
</Variant>
<Variant title="Single Tab">
<div class="p-4 bg-white dark:bg-slate-900">
<div class="p-4 bg-n-background">
<TabBar
:tabs="[{ label: 'Single Tab', count: 42 }]"
@tab-changed="handleTabChanged"

View File

@@ -9,19 +9,19 @@ const description = ref('');
<template>
<Story title="Components/TextArea" :layout="{ type: 'grid', width: '400' }">
<Variant title="Default">
<div class="p-4 bg-white dark:bg-slate-800">
<div class="p-4 bg-n-background">
<TextArea placeholder="Default TextArea" />
</div>
</Variant>
<Variant title="With Label">
<div class="p-4 bg-white dark:bg-slate-800">
<div class="p-4 bg-n-background">
<TextArea label="Description" placeholder="Enter your description" />
</div>
</Variant>
<Variant title="Disabled">
<div class="p-4 bg-white dark:bg-slate-800">
<div class="p-4 bg-n-background">
<TextArea
label="Disabled TextArea"
placeholder="Can't type here"
@@ -31,7 +31,7 @@ const description = ref('');
</Variant>
<Variant title="With Character Count">
<div class="p-4 bg-white dark:bg-slate-800">
<div class="p-4 bg-n-background">
<TextArea
v-model="bio"
label="Bio"
@@ -43,7 +43,7 @@ const description = ref('');
</Variant>
<Variant title="Custom Max Length">
<div class="p-4 bg-white dark:bg-slate-800">
<div class="p-4 bg-n-background">
<TextArea
v-model="description"
label="Long Description"
@@ -55,11 +55,11 @@ const description = ref('');
</Variant>
<Variant title="Custom TextArea Class">
<div class="p-4 bg-white dark:bg-slate-800">
<div class="p-4 bg-n-background">
<TextArea
label="Custom Style"
placeholder="Custom textarea class"
custom-text-area-class="border-yellow-500 dark:border-yellow-700"
custom-text-area-class="border-n-amber-5 dark:border-n-amber-5"
/>
</div>
</Variant>

View File

@@ -47,7 +47,7 @@ const messageClass = computed(() => {
case 'error':
return 'text-n-ruby-9 dark:text-n-ruby-9';
case 'success':
return 'text-green-500 dark:text-green-400';
return 'text-n-teal-10 dark:text-n-teal-10';
default:
return 'text-n-slate-11 dark:text-n-slate-11';
}
@@ -179,7 +179,7 @@ onMounted(() => {
}"
:disabled="disabled"
rows="1"
class="flex w-full reset-base text-sm p-0 !rounded-none !bg-transparent dark:!bg-transparent !border-0 !outline-0 !mb-0 placeholder:text-n-slate-10 dark:placeholder:text-n-slate-10 text-n-slate-12 dark:text-n-slate-12 disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-slate-25 dark:disabled:bg-slate-900"
class="flex w-full reset-base text-sm p-0 !rounded-none !bg-transparent dark:!bg-transparent !border-0 !outline-0 !mb-0 placeholder:text-n-slate-10 dark:placeholder:text-n-slate-10 text-n-slate-12 dark:text-n-slate-12 disabled:cursor-not-allowed disabled:opacity-50"
@input="handleInput"
@focus="handleFocus"
@blur="handleBlur"

View File

@@ -31,6 +31,7 @@ import DeleteCustomViews from 'dashboard/routes/dashboard/customviews/DeleteCust
import ConversationBulkActions from './widgets/conversation/conversationBulkActions/Index.vue';
import IntersectionObserver from './IntersectionObserver.vue';
import TeleportWithDirection from 'dashboard/components-next/TeleportWithDirection.vue';
import Spinner from 'dashboard/components-next/spinner/Spinner.vue';
import { useUISettings } from 'dashboard/composables/useUISettings';
import { useAlert } from 'dashboard/composables';
@@ -953,12 +954,12 @@ watch(conversationFilters, (newVal, oldVal) => {
</DynamicScrollerItem>
</template>
<template #after>
<div v-if="chatListLoading" class="text-center">
<span class="mt-4 mb-4 spinner" />
<div v-if="chatListLoading" class="flex justify-center my-4">
<Spinner class="text-n-brand" />
</div>
<p
v-else-if="showEndOfListMessage"
class="p-4 text-center text-slate-400 dark:text-slate-300"
class="p-4 text-center text-n-slate-11"
>
{{ $t('CHAT_LIST.EOF') }}
</p>

View File

@@ -1,10 +1,8 @@
<script setup>
import { computed } from 'vue';
import { useUISettings } from 'dashboard/composables/useUISettings';
import { useMapGetter } from 'dashboard/composables/store.js';
import { formatNumber } from '@chatwoot/utils';
import wootConstants from 'dashboard/constants/globals';
import { FEATURE_FLAGS } from 'dashboard/featureFlags';
import ConversationBasicFilter from './widgets/conversation/ConversationBasicFilter.vue';
import SwitchLayout from 'dashboard/routes/dashboard/conversation/search/SwitchLayout.vue';
@@ -30,11 +28,6 @@ const emit = defineEmits([
const { uiSettings, updateUISettings } = useUISettings();
const currentAccountId = useMapGetter('getCurrentAccountId');
const isFeatureEnabledonAccount = useMapGetter(
'accounts/isFeatureEnabledonAccount'
);
const onBasicFilterChange = (value, type) => {
emit('basicFilterChange', value, type);
};
@@ -43,13 +36,6 @@ const hasAppliedFiltersOrActiveFolders = computed(() => {
return props.hasAppliedFilters || props.hasActiveFolders;
});
const showV4View = computed(() => {
return isFeatureEnabledonAccount.value(
currentAccountId.value,
FEATURE_FLAGS.CHATWOOT_V4
);
});
const allCount = computed(() => props.conversationStats?.allCount || 0);
const formattedAllCount = computed(() => formatNumber(allCount.value));
@@ -174,7 +160,6 @@ const toggleConversationLayout = () => {
@change-filter="onBasicFilterChange"
/>
<SwitchLayout
v-if="showV4View"
:is-on-expanded-layout="isOnExpandedLayout"
@toggle="toggleConversationLayout"
/>

View File

@@ -14,13 +14,13 @@ defineProps({
<template>
<div class="flex flex-col items-start w-full gap-6">
<div class="flex flex-col w-full gap-4">
<h4 v-if="title" class="text-lg font-medium text-ash-900">
<h4 v-if="title" class="text-lg font-medium text-n-slate-12">
{{ title }}
</h4>
<div class="flex flex-row items-center justify-between">
<div class="flex-grow h-px bg-ash-200" />
<div class="flex-grow h-px bg-n-weak" />
</div>
<p v-if="description" class="mb-0 text-sm font-normal text-ash-900">
<p v-if="description" class="mb-0 text-sm font-normal text-n-slate-12">
{{ description }}
</p>
</div>

View File

@@ -28,19 +28,19 @@ export default {
<img v-if="headerImage" :src="headerImage" alt="No image" />
<h2
data-test-id="modal-header-title"
class="text-base font-semibold leading-6 text-slate-800 dark:text-slate-50"
class="text-base font-semibold leading-6 text-n-slate-12"
>
{{ headerTitle }}
</h2>
<p
v-if="headerContent"
data-test-id="modal-header-content"
class="w-full mt-2 text-sm leading-5 break-words text-slate-600 dark:text-slate-300"
class="w-full mt-2 text-sm leading-5 break-words text-n-slate-11"
>
{{ headerContent }}
<span
v-if="headerContentValue"
class="text-sm font-semibold text-slate-600 dark:text-slate-300"
class="text-sm font-semibold text-n-slate-11"
>
{{ headerContentValue }}
</span>

View File

@@ -30,15 +30,10 @@ export default {
>
<div class="grid grid-cols-1 lg:grid-cols-8 gap-6">
<div class="col-span-2">
<p
v-if="title"
class="text-base text-woot-500 dark:text-woot-500 mb-0 font-medium"
>
<p v-if="title" class="text-base text-n-brand mb-0 font-medium">
{{ title }}
</p>
<p
class="text-sm mb-2 text-slate-700 dark:text-slate-300 leading-5 tracking-normal mt-2"
>
<p class="text-sm mb-2 text-n-slate-11 leading-5 tracking-normal mt-2">
<slot v-if="subTitle" name="subTitle">
{{ subTitle }}
</slot>

View File

@@ -1,49 +0,0 @@
<script>
import { FEATURE_FLAGS } from 'dashboard/featureFlags';
import { BUS_EVENTS } from 'shared/constants/busEvents';
import { mapGetters } from 'vuex';
import { emitter } from 'shared/helpers/mitt';
import NextButton from 'dashboard/components-next/button/Button.vue';
export default {
components: {
NextButton,
},
props: {
size: {
type: String,
default: 'sm',
},
},
computed: {
...mapGetters({
accountId: 'getCurrentAccountId',
isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount',
}),
hasNextSidebar() {
return this.isFeatureEnabledonAccount(
this.accountId,
FEATURE_FLAGS.CHATWOOT_V4
);
},
},
methods: {
onMenuItemClick() {
emitter.emit(BUS_EVENTS.TOGGLE_SIDEMENU);
},
},
};
</script>
<!-- eslint-disable-next-line vue/no-root-v-if -->
<template>
<NextButton
v-if="!hasNextSidebar"
ghost
slate
:size="size"
icon="i-lucide-menu"
class="-ml-3"
@click="onMenuItemClick"
/>
</template>

View File

@@ -178,7 +178,7 @@ useEmitter(CMD_RESOLVE_CONVERSATION, onCmdResolveConversation);
<div
v-if="showActionsDropdown"
v-on-clickaway="closeDropdown"
class="dropdown-pane dropdown-pane--open left-auto top-full mt-0.5 start-0 xl:start-auto xl:end-0 max-w-[12.5rem] min-w-[9.75rem]"
class="border rounded-lg shadow-lg border-n-strong dark:border-n-strong box-content p-2 w-fit z-10 bg-n-alpha-3 backdrop-blur-[100px] absolute block left-auto top-full mt-0.5 start-0 xl:start-auto xl:end-0 max-w-[12.5rem] min-w-[9.75rem] [&_ul>li]:mb-0"
>
<WootDropdownMenu class="mb-0">
<WootDropdownItem v-if="!isPending">
@@ -209,11 +209,3 @@ useEmitter(CMD_RESOLVE_CONVERSATION, onCmdResolveConversation);
</div>
</div>
</template>
<style lang="scss" scoped>
.dropdown-pane {
.dropdown-menu__item {
@apply mb-0;
}
}
</style>

View File

@@ -8,7 +8,7 @@ import { FEATURE_FLAGS } from 'dashboard/featureFlags';
defineProps({
conversationInboxType: {
type: String,
required: true,
default: '',
},
});

View File

@@ -15,7 +15,6 @@ import Label from './ui/Label.vue';
import LoadingState from './widgets/LoadingState.vue';
import ModalHeader from './ModalHeader.vue';
import Modal from './Modal.vue';
import SidemenuIcon from './SidemenuIcon.vue';
import Spinner from 'shared/components/Spinner.vue';
import Tabs from './ui/Tabs/Tabs.vue';
import TabsItem from './ui/Tabs/TabsItem.vue';
@@ -38,7 +37,6 @@ const WootUIKit = {
LoadingState,
Modal,
ModalHeader,
SidemenuIcon,
Spinner,
Tabs,
TabsItem,

View File

@@ -1,157 +0,0 @@
<script>
import { mapGetters } from 'vuex';
import { useAlert } from 'dashboard/composables';
import { useImpersonation } from 'dashboard/composables/useImpersonation';
import WootDropdownItem from 'shared/components/ui/dropdown/DropdownItem.vue';
import WootDropdownMenu from 'shared/components/ui/dropdown/DropdownMenu.vue';
import WootDropdownHeader from 'shared/components/ui/dropdown/DropdownHeader.vue';
import WootDropdownDivider from 'shared/components/ui/dropdown/DropdownDivider.vue';
import AvailabilityStatusBadge from '../widgets/conversation/AvailabilityStatusBadge.vue';
import wootConstants from 'dashboard/constants/globals';
import NextButton from 'dashboard/components-next/button/Button.vue';
const { AVAILABILITY_STATUS_KEYS } = wootConstants;
export default {
components: {
WootDropdownHeader,
WootDropdownDivider,
WootDropdownMenu,
WootDropdownItem,
AvailabilityStatusBadge,
NextButton,
},
setup() {
const { isImpersonating } = useImpersonation();
return { isImpersonating };
},
data() {
return {
isStatusMenuOpened: false,
isUpdating: false,
};
},
computed: {
...mapGetters({
getCurrentUserAvailability: 'getCurrentUserAvailability',
currentAccountId: 'getCurrentAccountId',
currentUserAutoOffline: 'getCurrentUserAutoOffline',
}),
statusList() {
return [
this.$t('PROFILE_SETTINGS.FORM.AVAILABILITY.STATUS.ONLINE'),
this.$t('PROFILE_SETTINGS.FORM.AVAILABILITY.STATUS.BUSY'),
this.$t('PROFILE_SETTINGS.FORM.AVAILABILITY.STATUS.OFFLINE'),
];
},
availabilityDisplayLabel() {
const availabilityIndex = AVAILABILITY_STATUS_KEYS.findIndex(
key => key === this.currentUserAvailability
);
return this.statusList[availabilityIndex];
},
currentUserAvailability() {
return this.getCurrentUserAvailability;
},
availabilityStatuses() {
return this.statusList.map((statusLabel, index) => ({
label: statusLabel,
value: AVAILABILITY_STATUS_KEYS[index],
disabled:
this.currentUserAvailability === AVAILABILITY_STATUS_KEYS[index],
}));
},
},
methods: {
openStatusMenu() {
this.isStatusMenuOpened = true;
},
closeStatusMenu() {
this.isStatusMenuOpened = false;
},
updateAutoOffline(autoOffline) {
this.$store.dispatch('updateAutoOffline', {
accountId: this.currentAccountId,
autoOffline,
});
},
changeAvailabilityStatus(availability) {
if (this.isImpersonating) {
useAlert(
this.$t('PROFILE_SETTINGS.FORM.AVAILABILITY.IMPERSONATING_ERROR')
);
return;
}
if (this.isUpdating) {
return;
}
this.isUpdating = true;
try {
this.$store.dispatch('updateAvailability', {
availability,
account_id: this.currentAccountId,
});
} catch (error) {
useAlert(
this.$t('PROFILE_SETTINGS.FORM.AVAILABILITY.SET_AVAILABILITY_ERROR')
);
} finally {
this.isUpdating = false;
}
},
},
};
</script>
<template>
<WootDropdownMenu>
<WootDropdownHeader :title="$t('SIDEBAR.SET_AVAILABILITY_TITLE')" />
<WootDropdownItem
v-for="status in availabilityStatuses"
:key="status.value"
class="flex items-baseline"
>
<NextButton
sm
:color="status.disabled ? 'blue' : 'slate'"
:variant="status.disabled ? 'faded' : 'ghost'"
class="status-change--dropdown-button !w-full !justify-start"
@click="changeAvailabilityStatus(status.value)"
>
<AvailabilityStatusBadge :status="status.value" />
<span class="min-w-0 truncate font-medium text-xs">
{{ status.label }}
</span>
</NextButton>
</WootDropdownItem>
<WootDropdownDivider />
<WootDropdownItem class="flex items-center justify-between px-3 py-2 m-0">
<div class="flex items-center">
<fluent-icon
v-tooltip.right-start="$t('SIDEBAR.SET_AUTO_OFFLINE.INFO_TEXT')"
icon="info"
size="14"
class="mt-px"
/>
<span
class="mx-2 my-0 text-xs font-medium text-slate-600 dark:text-slate-100"
>
{{ $t('SIDEBAR.SET_AUTO_OFFLINE.TEXT') }}
</span>
</div>
<woot-switch
size="small"
class="mx-1 mt-px mb-0"
:model-value="currentUserAutoOffline"
@input="updateAutoOffline"
/>
</WootDropdownItem>
<WootDropdownDivider />
</WootDropdownMenu>
</template>

View File

@@ -1,246 +0,0 @@
<script>
import { mapGetters } from 'vuex';
import { getSidebarItems } from './config/default-sidebar';
import { useKeyboardEvents } from 'dashboard/composables/useKeyboardEvents';
import { useAccount } from 'dashboard/composables/useAccount';
import { useRoute, useRouter } from 'vue-router';
import PrimarySidebar from './sidebarComponents/Primary.vue';
import SecondarySidebar from './sidebarComponents/Secondary.vue';
import { routesWithPermissions } from '../../routes';
import {
getUserPermissions,
hasPermissions,
} from '../../helper/permissionsHelper';
export default {
components: {
PrimarySidebar,
SecondarySidebar,
},
props: {
showSecondarySidebar: {
type: Boolean,
default: true,
},
},
emits: [
'toggleAccountModal',
'showAddLabelPopup',
'openNotificationPanel',
'closeKeyShortcutModal',
'openKeyShortcutModal',
],
setup(props, { emit }) {
const route = useRoute();
const router = useRouter();
const { accountId } = useAccount();
const toggleKeyShortcutModal = () => {
emit('openKeyShortcutModal');
};
const closeKeyShortcutModal = () => {
emit('closeKeyShortcutModal');
};
const isCurrentRouteSameAsNavigation = routeName => {
return route.name === routeName;
};
const navigateToRoute = routeName => {
if (!isCurrentRouteSameAsNavigation(routeName)) {
router.push({ name: routeName });
}
};
const keyboardEvents = {
'$mod+Slash': {
action: toggleKeyShortcutModal,
},
'$mod+Escape': {
action: closeKeyShortcutModal,
},
'Alt+KeyC': {
action: () => navigateToRoute('home'),
},
'Alt+KeyV': {
action: () => navigateToRoute('contacts_dashboard'),
},
'Alt+KeyR': {
action: () => navigateToRoute('account_overview_reports'),
},
'Alt+KeyS': {
action: () => navigateToRoute('agent_list'),
},
};
useKeyboardEvents(keyboardEvents);
return {
toggleKeyShortcutModal,
accountId,
};
},
data() {
return {
showOptionsMenu: false,
};
},
computed: {
...mapGetters({
currentUser: 'getCurrentUser',
globalConfig: 'globalConfig/get',
inboxes: 'inboxes/getInboxes',
isACustomBrandedInstance: 'globalConfig/isACustomBrandedInstance',
isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount',
isOnChatwootCloud: 'globalConfig/isOnChatwootCloud',
labels: 'labels/getLabelsOnSidebar',
teams: 'teams/getMyTeams',
}),
activeCustomView() {
if (this.activePrimaryMenu.key === 'contacts') {
return 'contact';
}
if (this.activePrimaryMenu.key === 'conversations') {
return 'conversation';
}
return '';
},
customViews() {
if (!this.activeCustomView) {
return [];
}
return this.$store.getters['customViews/getCustomViewsByFilterType'](
this.activeCustomView
);
},
isConversationOrContactActive() {
return (
this.activePrimaryMenu.key === 'contacts' ||
this.activePrimaryMenu.key === 'conversations'
);
},
sideMenuConfig() {
return getSidebarItems(this.accountId);
},
primaryMenuItems() {
const userPermissions = getUserPermissions(
this.currentUser,
this.accountId
);
const menuItems = this.sideMenuConfig.primaryMenu;
return menuItems.filter(menuItem => {
const isAvailableForTheUser = hasPermissions(
routesWithPermissions[menuItem.toStateName],
userPermissions
);
if (!isAvailableForTheUser) {
return false;
}
if (
menuItem.alwaysVisibleOnChatwootInstances &&
!this.isACustomBrandedInstance
) {
return true;
}
if (menuItem.featureFlag) {
return this.isFeatureEnabledonAccount(
this.accountId,
menuItem.featureFlag
);
}
return true;
});
},
activeSecondaryMenu() {
const { secondaryMenu } = this.sideMenuConfig;
const { name: currentRoute } = this.$route;
const activeSecondaryMenu =
secondaryMenu.find(menuItem =>
menuItem.routes.includes(currentRoute)
) || {};
return activeSecondaryMenu;
},
activePrimaryMenu() {
const activePrimaryMenu =
this.primaryMenuItems.find(
menuItem => menuItem.key === this.activeSecondaryMenu.parentNav
) || {};
return activePrimaryMenu;
},
hasSecondaryMenu() {
return (
this.activeSecondaryMenu.menuItems &&
this.activeSecondaryMenu.menuItems.length
);
},
hasSecondarySidebar() {
// if it is explicitly stated to show and it has secondary menu items to show
// showSecondarySidebar corresponds to the UI settings, indicating if the user has toggled it
return this.showSecondarySidebar && this.hasSecondaryMenu;
},
},
watch: {
activeCustomView() {
this.fetchCustomViews();
},
},
mounted() {
this.$store.dispatch('labels/get');
this.$store.dispatch('inboxes/get');
this.$store.dispatch('notifications/unReadCount');
this.$store.dispatch('teams/get');
this.$store.dispatch('attributes/get');
this.fetchCustomViews();
},
methods: {
fetchCustomViews() {
if (this.isConversationOrContactActive) {
this.$store.dispatch('customViews/get', this.activeCustomView);
}
},
toggleSupportChatWindow() {
window.$chatwoot.toggle();
},
toggleAccountModal() {
this.$emit('toggleAccountModal');
},
showAddLabelPopup() {
this.$emit('showAddLabelPopup');
},
openNotificationPanel() {
this.$emit('openNotificationPanel');
},
},
};
</script>
<template>
<aside class="flex h-full">
<PrimarySidebar
:logo-source="globalConfig.logoThumbnail"
:installation-name="globalConfig.installationName"
:is-a-custom-branded-instance="isACustomBrandedInstance"
:account-id="accountId"
:menu-items="primaryMenuItems"
:active-menu-item="activePrimaryMenu.key"
@toggle-accounts="toggleAccountModal"
@open-key-shortcut-modal="toggleKeyShortcutModal"
@open-notification-panel="openNotificationPanel"
/>
<SecondarySidebar
v-if="hasSecondarySidebar"
:account-id="accountId"
:inboxes="inboxes"
:labels="labels"
:teams="teams"
:custom-views="customViews"
:menu-config="activeSecondaryMenu"
:current-user="currentUser"
:is-on-chatwoot-cloud="isOnChatwootCloud"
@add-label="showAddLabelPopup"
@toggle-accounts="toggleAccountModal"
/>
</aside>
</template>

View File

@@ -1,19 +0,0 @@
import conversations from './sidebarItems/conversations';
import contacts from './sidebarItems/contacts';
import reports from './sidebarItems/reports';
import campaigns from './sidebarItems/campaigns';
import settings from './sidebarItems/settings';
import notifications from './sidebarItems/notifications';
import primaryMenu from './sidebarItems/primaryMenu';
export const getSidebarItems = accountId => ({
primaryMenu: primaryMenu(accountId),
secondaryMenu: [
conversations(accountId),
contacts(accountId),
reports(accountId),
campaigns(accountId),
settings(accountId),
notifications(accountId),
],
});

View File

@@ -1,26 +0,0 @@
import { frontendURL } from '../../../../helper/URLHelper';
const campaigns = accountId => ({
parentNav: 'campaigns',
routes: ['campaigns_sms_index', 'campaigns_livechat_index'],
menuItems: [
{
icon: 'arrow-swap',
label: 'LIVE_CHAT',
key: 'ongoingCampaigns',
hasSubMenu: false,
toState: frontendURL(`accounts/${accountId}/campaigns/live_chat`),
toStateName: 'campaigns_livechat_index',
},
{
key: 'oneOffCampaigns',
icon: 'sound-source',
label: 'SMS',
hasSubMenu: false,
toState: frontendURL(`accounts/${accountId}/campaigns/sms`),
toStateName: 'campaigns_sms_index',
},
],
});
export default campaigns;

View File

@@ -1,32 +0,0 @@
import { frontendURL } from '../../../../helper/URLHelper';
const contacts = accountId => ({
parentNav: 'contacts',
routes: [
'contacts_dashboard_index',
'contacts_dashboard_segments_index',
'contacts_dashboard_labels_index',
'contacts_edit',
'contacts_edit_segment',
'contacts_edit_label',
'contacts_dashboard_active',
],
menuItems: [
{
icon: 'contact-card-group',
label: 'ALL_CONTACTS',
hasSubMenu: false,
toState: frontendURL(`accounts/${accountId}/contacts?page=1`),
toStateName: 'contacts_dashboard_index',
},
{
icon: 'visitor-contacts',
label: 'ACTIVE',
hasSubMenu: false,
toState: frontendURL(`accounts/${accountId}/contacts/active`),
toStateName: 'contacts_dashboard_active',
},
],
});
export default contacts;

View File

@@ -1,50 +0,0 @@
import { frontendURL } from '../../../../helper/URLHelper';
const conversations = accountId => ({
parentNav: 'conversations',
routes: [
'home',
'inbox_dashboard',
'inbox_conversation',
'conversation_through_inbox',
'notifications_dashboard',
'label_conversations',
'conversations_through_label',
'team_conversations',
'conversations_through_team',
'conversation_mentions',
'conversation_through_mentions',
'conversation_participating',
'conversation_through_participating',
'folder_conversations',
'conversations_through_folders',
'conversation_unattended',
'conversation_through_unattended',
],
menuItems: [
{
icon: 'chat',
label: 'ALL_CONVERSATIONS',
key: 'conversations',
toState: frontendURL(`accounts/${accountId}/dashboard`),
toolTip: 'Conversation from all subscribed inboxes',
toStateName: 'home',
},
{
icon: 'mention',
label: 'MENTIONED_CONVERSATIONS',
key: 'conversation_mentions',
toState: frontendURL(`accounts/${accountId}/mentions/conversations`),
toStateName: 'conversation_mentions',
},
{
icon: 'mail-unread',
label: 'UNATTENDED_CONVERSATIONS',
key: 'conversation_unattended',
toState: frontendURL(`accounts/${accountId}/unattended/conversations`),
toStateName: 'conversation_unattended',
},
],
});
export default conversations;

View File

@@ -1,7 +0,0 @@
const notifications = () => ({
parentNav: 'notifications',
routes: ['notifications_index'],
menuItems: [],
});
export default notifications;

View File

@@ -1,70 +0,0 @@
import { FEATURE_FLAGS } from '../../../../featureFlags';
import { frontendURL } from '../../../../helper/URLHelper';
const primaryMenuItems = accountId => [
{
icon: 'mail-inbox',
key: 'inboxView',
label: 'INBOX_VIEW',
featureFlag: FEATURE_FLAGS.INBOX_VIEW,
toState: frontendURL(`accounts/${accountId}/inbox-view`),
toStateName: 'inbox_view',
},
{
icon: 'chat',
key: 'conversations',
label: 'CONVERSATIONS',
toState: frontendURL(`accounts/${accountId}/dashboard`),
toStateName: 'home',
},
{
icon: 'captain',
key: 'captain',
label: 'CAPTAIN',
featureFlag: FEATURE_FLAGS.CAPTAIN,
toState: frontendURL(`accounts/${accountId}/captain/documents`),
toStateName: 'captain',
},
{
icon: 'book-contacts',
key: 'contacts',
label: 'CONTACTS',
featureFlag: FEATURE_FLAGS.CRM,
toState: frontendURL(`accounts/${accountId}/contacts`),
toStateName: 'contacts_dashboard_index',
},
{
icon: 'arrow-trending-lines',
key: 'reports',
label: 'REPORTS',
featureFlag: FEATURE_FLAGS.REPORTS,
toState: frontendURL(`accounts/${accountId}/reports`),
toStateName: 'account_overview_reports',
},
{
icon: 'megaphone',
key: 'campaigns',
label: 'CAMPAIGNS',
featureFlag: FEATURE_FLAGS.CAMPAIGNS,
toState: frontendURL(`accounts/${accountId}/campaigns`),
toStateName: 'campaigns_ongoing_index',
},
{
icon: 'library',
key: 'helpcenter',
label: 'HELP_CENTER.TITLE',
featureFlag: FEATURE_FLAGS.HELP_CENTER,
alwaysVisibleOnChatwootInstances: true,
toState: frontendURL(`accounts/${accountId}/portals/portal_articles_index`),
toStateName: 'portals_index',
},
{
icon: 'settings',
key: 'settings',
label: 'SETTINGS',
toState: frontendURL(`accounts/${accountId}/settings`),
toStateName: 'settings_home',
},
];
export default primaryMenuItems;

View File

@@ -1,7 +0,0 @@
const profileSettings = () => ({
parentNav: 'profileSettings',
routes: ['profile_settings_index'],
menuItems: [],
});
export default profileSettings;

View File

@@ -1,87 +0,0 @@
import { FEATURE_FLAGS } from '../../../../featureFlags';
import { frontendURL } from '../../../../helper/URLHelper';
const reports = accountId => ({
parentNav: 'reports',
routes: [
'account_overview_reports',
'conversation_reports',
'csat_reports',
'bot_reports',
'agent_reports',
'label_reports',
'inbox_reports',
'inbox_reports_show',
'team_reports',
'sla_reports',
],
menuItems: [
{
icon: 'arrow-trending-lines',
label: 'REPORTS_OVERVIEW',
hasSubMenu: false,
toState: frontendURL(`accounts/${accountId}/reports/overview`),
toStateName: 'account_overview_reports',
},
{
icon: 'chat',
label: 'REPORTS_CONVERSATION',
hasSubMenu: false,
toState: frontendURL(`accounts/${accountId}/reports/conversation`),
toStateName: 'conversation_reports',
},
{
icon: 'emoji',
label: 'CSAT',
hasSubMenu: false,
toState: frontendURL(`accounts/${accountId}/reports/csat`),
toStateName: 'csat_reports',
},
{
icon: 'bot',
label: 'REPORTS_BOT',
hasSubMenu: false,
featureFlag: FEATURE_FLAGS.RESPONSE_BOT,
toState: frontendURL(`accounts/${accountId}/reports/bot`),
toStateName: 'bot_reports',
},
{
icon: 'people',
label: 'REPORTS_AGENT',
hasSubMenu: false,
toState: frontendURL(`accounts/${accountId}/reports/agent`),
toStateName: 'agent_reports',
},
{
icon: 'tag',
label: 'REPORTS_LABEL',
hasSubMenu: false,
toState: frontendURL(`accounts/${accountId}/reports/label`),
toStateName: 'label_reports',
},
{
icon: 'mail-inbox-all',
label: 'REPORTS_INBOX',
hasSubMenu: false,
toState: frontendURL(`accounts/${accountId}/reports/inboxes`),
toStateName: 'inbox_reports',
},
{
icon: 'people-team',
label: 'REPORTS_TEAM',
hasSubMenu: false,
toState: frontendURL(`accounts/${accountId}/reports/teams`),
toStateName: 'team_reports',
},
{
icon: 'document-list-clock',
label: 'REPORTS_SLA',
hasSubMenu: false,
featureFlag: FEATURE_FLAGS.SLA,
toState: frontendURL(`accounts/${accountId}/reports/sla`),
toStateName: 'sla_reports',
},
],
});
export default reports;

Some files were not shown because too many files have changed in this diff Show More