feat: Dark Mode (#7471)

This commit is contained in:
Sivin Varghese
2023-07-21 22:10:25 +05:30
committed by GitHub
parent 480f34803b
commit 40ec0d109a
264 changed files with 2932 additions and 6814 deletions
@@ -1,13 +1,16 @@
<template>
<div class="column">
<div class="flex flex-col">
<woot-modal-header :header-title="headerTitle" />
<form class="row modal-content" @submit.prevent="applyText">
<form
class="modal-content flex flex-col w-full"
@submit.prevent="applyText"
>
<div v-if="draftMessage" class="w-full">
<h4 class="sub-block-title margin-top-1 ">
<h4 class="text-base mt-1 text-slate-700 dark:text-slate-100">
{{ $t('INTEGRATION_SETTINGS.OPEN_AI.ASSISTANCE_MODAL.DRAFT_TITLE') }}
</h4>
<p v-dompurify-html="formatMessage(draftMessage, false)" />
<h4 class="sub-block-title margin-top-1">
<h4 class="text-base mt-1 text-slate-700 dark:text-slate-100">
{{
$t('INTEGRATION_SETTINGS.OPEN_AI.ASSISTANCE_MODAL.GENERATED_TITLE')
}}
@@ -18,7 +21,7 @@
<p v-else v-dompurify-html="formatMessage(generatedContent, false)" />
</div>
<div class="modal-footer justify-content-end w-full">
<div class="flex flex-row justify-end gap-2 py-2 px-0 w-full">
<woot-button variant="clear" @click.prevent="onClose">
{{
$t('INTEGRATION_SETTINGS.OPEN_AI.ASSISTANCE_MODAL.BUTTONS.CANCEL')
@@ -98,7 +101,7 @@ export default {
<style lang="scss" scoped>
.modal-content {
padding-top: var(--space-small);
@apply pt-2 px-8 pb-8;
}
.container {
@@ -1,29 +1,37 @@
<template>
<div class="preview-item__wrap">
<div
class="preview-item__wrap flex flex-col overflow-auto mt-4 max-h-[12.5rem]"
>
<div
v-for="(attachment, index) in attachments"
:key="attachment.id"
class="preview-item"
class="preview-item flex p-1 bg-slate-50 dark:bg-slate-800 rounded-md w-[15rem] mb-1"
>
<div class="thumb-wrap">
<div class="max-w-[4rem] flex-shrink-0 w-6 flex items-center">
<img
v-if="isTypeImage(attachment.resource)"
class="image-thumb"
:src="attachment.thumb"
/>
<span v-else class="attachment-thumb"> 📄 </span>
<span v-else class="w-6 h-6 text-lg relative -top-px text-left">
📄
</span>
</div>
<div class="file-name-wrap">
<span class="item">
<div class="max-w-[60%] min-w-[50%] overflow-hidden text-ellipsis ml-2">
<span
class="h-4 overflow-hidden text-sm font-medium text-ellipsis whitespace-nowrap"
>
{{ fileName(attachment.resource) }}
</span>
</div>
<div class="file-size-wrap">
<span class="item text-truncate">
<div class="w-[30%] justify-center">
<span
class="item overflow-hidden text-xs text-ellipsis whitespace-nowrap"
>
{{ formatFileSize(attachment.resource) }}
</span>
</div>
<div class="remove-file-wrap">
<div class="flex items-center justify-center">
<woot-button
v-if="!isTypeAudio(attachment.resource)"
class="remove--attachment clear secondary"
@@ -70,103 +78,20 @@ export default {
};
</script>
<style lang="scss" scoped>
.preview-item__wrap {
display: flex;
flex-direction: column;
overflow: auto;
margin-top: var(--space-normal);
max-height: 12.5rem;
}
.preview-item {
display: flex;
padding: var(--space-slab) 0 0;
background: var(--color-background-light);
background: var(--b-50);
border-radius: var(--border-radius-normal);
width: 15rem;
padding: var(--space-smaller);
margin-bottom: var(--space-one);
}
.thumb-wrap {
max-width: var(--space-jumbo);
flex-shrink: 0;
width: var(--space-medium);
display: flex;
align-items: center;
}
.image-thumb {
width: var(--space-medium);
height: var(--space-medium);
object-fit: cover;
border-radius: var(--border-radius-small);
}
.attachment-thumb {
width: var(--space-medium);
height: var(--space-medium);
font-size: var(--font-size-medium);
text-align: center;
position: relative;
top: -1px;
text-align: left;
@apply w-6 h-6 object-cover rounded-sm;
}
.file-name-wrap,
.file-size-wrap {
display: flex;
align-items: center;
padding: 0 var(--space-smaller);
@apply flex items-center py-0 px-1;
> .item {
margin: 0;
overflow: hidden;
font-size: var(--font-size-mini);
font-weight: var(--font-weight-medium);
@apply m-0 overflow-hidden text-xs font-medium;
}
}
.preview-header {
padding: var(--space-slab) var(--space-slab) 0 var(--space-slab);
}
.file-name-wrap {
max-width: 60%;
min-width: 50%;
overflow: hidden;
text-overflow: ellipsis;
margin-left: var(--space-small);
.item {
height: var(--space-normal);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.file-size-wrap {
width: 30%;
justify-content: center;
}
.remove-file-wrap {
display: flex;
align-items: center;
justify-content: center;
}
.remove--attachment {
width: var(--space-medium);
height: var(--space-medium);
border-radius: var(--space-medium);
font-size: var(--font-size-small);
cursor: pointer;
&:hover {
background: var(--color-background);
}
@apply w-6 h-6 rounded-md text-sm cursor-pointer hover:bg-slate-50 dark:hover:bg-slate-800;
}
</style>
@@ -16,7 +16,7 @@
</option>
</select>
<div v-if="showActionInput" class="filter__answer--wrap">
<div v-if="inputType">
<div v-if="inputType" class="w-full">
<div
v-if="inputType === 'search_select'"
class="multiselect-wrap--small"
@@ -201,102 +201,80 @@ export default {
<style lang="scss" scoped>
.filter {
background: var(--color-background);
padding: var(--space-small);
border: 1px solid var(--color-border);
border-radius: var(--border-radius-medium);
margin-bottom: var(--space-small);
@apply bg-slate-50 dark:bg-slate-800 p-2 border border-solid border-slate-75 dark:border-slate-600 rounded-md mb-2;
&.is-a-macro {
margin-bottom: 0;
background: var(--white);
padding: var(--space-zero);
border: unset;
border-radius: unset;
@apply mb-0 bg-white dark:bg-slate-700 p-0 border-0 rounded-none;
}
}
.no-margin-bottom {
margin-bottom: 0;
@apply mb-0;
}
.filter.has-error {
background: var(--r-50);
@apply bg-red-50 dark:bg-red-100;
}
.filter-inputs {
display: flex;
@apply flex;
}
.filter-error {
color: var(--r-500);
display: block;
margin: var(--space-smaller) 0;
@apply text-red-500 dark:text-red-600 block my-1 mx-0;
}
.action__question,
.filter__operator {
margin-bottom: var(--space-zero);
margin-right: var(--space-smaller);
@apply mb-0 mr-1;
}
.action__question {
max-width: 50%;
@apply max-w-[50%];
}
.action__question.full-width {
max-width: 100%;
@apply max-w-full;
}
.filter__answer--wrap {
margin-right: var(--space-smaller);
flex-grow: 1;
max-width: 50%;
@apply max-w-[50%] flex-grow mr-1 flex w-full items-center justify-start;
input {
margin-bottom: 0;
@apply mb-0;
}
}
.filter__answer {
&.answer--text-input {
margin-bottom: var(--space-zero);
@apply mb-0;
}
}
.filter__join-operator-wrap {
position: relative;
z-index: var(--z-index-twenty);
margin: var(--space-zero);
@apply relative z-20 m-0;
}
.filter__join-operator {
display: flex;
align-items: center;
justify-content: center;
position: relative;
margin: var(--space-one) var(--space-zero);
@apply flex items-center justify-center relative my-2.5 mx-0;
.operator__line {
position: absolute;
width: 100%;
border-bottom: 1px solid var(--color-border);
@apply absolute w-full border-b border-solid border-slate-75 dark:border-slate-600;
}
.operator__select {
position: relative;
width: auto;
margin-bottom: var(--space-zero) !important;
@apply relative w-auto;
}
}
.multiselect {
margin-bottom: var(--space-zero);
@apply mb-0;
}
.action-message {
margin: var(--space-small) var(--space-zero) var(--space-zero);
@apply mt-2 mx-0 mb-0;
}
// Prosemirror does not have a native way of hiding the menu bar, hence
::v-deep .ProseMirror-menubar {
display: none;
@apply hidden;
}
</style>
@@ -82,37 +82,22 @@ export default {
<style scoped>
input[type='file'] {
display: none;
@apply hidden;
}
.input-wrapper {
display: flex;
height: 39px;
background-color: var(--white);
border-radius: var(--border-radius-small);
border: 1px dashed var(--w-100);
padding: var(--space-smaller) var(--space-small);
align-items: center;
font-size: var(--font-size-mini);
cursor: pointer;
@apply flex h-9 bg-white dark:bg-slate-900 py-1 px-2 items-center text-xs cursor-pointer rounded-sm border border-dashed border-woot-100 dark:border-woot-500;
}
.success-icon {
margin-right: var(--space-small);
color: var(--g-500);
@apply text-green-500 dark:text-green-600 mr-2;
}
.error-icon {
margin-right: var(--space-small);
color: var(--r-500);
@apply text-red-500 dark:text-red-600 mr-2;
}
.processing {
cursor: not-allowed;
opacity: 0.9;
@apply cursor-not-allowed opacity-90;
}
.file-button {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
margin-bottom: 0;
@apply whitespace-nowrap overflow-hidden text-ellipsis w-full mb-0;
}
</style>
@@ -38,16 +38,18 @@ export default {
};
</script>
<style lang="scss" scoped>
<style scoped>
@tailwind components;
@layer components {
.avatar-color {
background-image: linear-gradient(to top, #c2e1ff 0%, #d6ebff 100%);
}
.dark-avatar-color {
background-image: linear-gradient(to top, #135899 0%, #135899 100%);
}
}
.avatar-container {
display: flex;
line-height: 100%;
font-weight: 500;
align-items: center;
justify-content: center;
text-align: center;
background-image: linear-gradient(to top, var(--w-100) 0%, var(--w-75) 100%);
color: var(--w-600);
cursor: default;
@apply flex leading-[100%] font-medium items-center justify-center text-center cursor-default avatar-color dark:dark-avatar-color text-woot-600 dark:text-woot-200;
}
</style>
@@ -1,9 +1,15 @@
<template>
<div class="row empty-state">
<h3 class="title">
<div class="empty-state py-16 px-1 ml-0 mr-0">
<h3
v-if="title"
class="text-slate-700 dark:text-slate-200 block text-center w-full text-4xl font-thin"
>
{{ title }}
</h3>
<p class="message">
<p
v-if="message"
class="block text-center text-slate-500 dark:text-slate-400 my-4 mx-auto w-[90%]"
>
{{ message }}
</p>
<slot />
@@ -14,7 +20,6 @@ export default {
props: {
title: { type: String, default: '' },
message: { type: String, default: '' },
buttonText: { type: String, default: '' },
},
};
</script>
@@ -1,11 +1,14 @@
<template>
<div class="filters">
<div class="filter" :class="{ error: v.values.$dirty && v.values.$error }">
<div class="filter-inputs">
<div>
<div
class="rounded-md p-2 border border-solid"
:class="getInputErrorClass(v.values.$dirty, v.values.$error)"
>
<div class="flex">
<select
v-if="groupedFilters"
v-model="attributeKey"
class="filter__question"
class="bg-white max-w-[30%] dark:bg-slate-900 mb-0 mr-1 text-slate-800 dark:text-slate-100 border-slate-75 dark:border-slate-600"
@change="resetFilter()"
>
<optgroup
@@ -25,7 +28,7 @@
<select
v-else
v-model="attributeKey"
class="filter__question"
class="bg-white max-w-[30%] dark:bg-slate-900 mb-0 mr-1 text-slate-800 dark:text-slate-100 border-slate-75 dark:border-slate-600"
@change="resetFilter()"
>
<option
@@ -38,7 +41,10 @@
</option>
</select>
<select v-model="filterOperator" class="filter__operator">
<select
v-model="filterOperator"
class="bg-white dark:bg-slate-900 max-w-[20%] mb-0 mr-1 text-slate-800 dark:text-slate-100 border-slate-75 dark:border-slate-600"
>
<option
v-for="(operator, o) in operators"
:key="o"
@@ -48,7 +54,7 @@
</option>
</select>
<div v-if="showUserInput" class="filter__answer--wrap">
<div v-if="showUserInput" class="filter__answer--wrap mr-1 flex-grow">
<div
v-if="inputType === 'multi_select'"
class="multiselect-wrap--small"
@@ -90,14 +96,14 @@
v-model="values"
type="date"
:editable="false"
class="answer--text-input datepicker"
class="mb-0 datepicker"
/>
</div>
<input
v-else
v-model="values"
type="text"
class="answer--text-input"
class="mb-0"
placeholder="Enter value"
/>
</div>
@@ -108,14 +114,25 @@
@click="removeFilter"
/>
</div>
<p v-if="v.values.$dirty && v.values.$error" class="filter-error">
<p
v-if="v.values.$dirty && v.values.$error"
class="text-red-500 dark:text-red-600 block my-1 mx-0"
>
{{ $t('FILTER.EMPTY_VALUE_ERROR') }}
</p>
</div>
<div v-if="showQueryOperator" class="filter__join-operator">
<hr class="operator__line" />
<select v-model="query_operator" class="operator__select">
<div
v-if="showQueryOperator"
class="flex items-center justify-center relative my-2.5 mx-0"
>
<hr
class="w-full absolute border-b border-solid border-slate-75 dark:border-slate-600"
/>
<select
v-model="query_operator"
class="bg-white dark:bg-slate-900 mb-0 w-auto relative text-slate-800 dark:text-slate-100 border-slate-75 dark:border-slate-600"
>
<option value="and">
{{ $t('FILTER.QUERY_DROPDOWN_LABELS.AND') }}
</option>
@@ -254,86 +271,22 @@ export default {
resetFilter() {
this.$emit('resetFilter');
},
getInputErrorClass(isDirty, hasError) {
return isDirty && hasError
? 'bg-red-50 dark:bg-red-200 border-red-100 dark:border-red-300 '
: 'bg-slate-50 dark:bg-slate-800 border-slate-75 dark:border-slate-600 ';
},
},
};
</script>
<style lang="scss" scoped>
.filter {
background: var(--color-background);
padding: var(--space-small);
border: 1px solid var(--color-border);
border-radius: var(--border-radius-medium);
}
.filter.error {
background: var(--r-50);
}
.filter-inputs {
display: flex;
}
.filter-error {
color: var(--r-500);
display: block;
margin: var(--space-smaller) 0;
}
.filter__question,
.filter__operator {
margin-bottom: var(--space-zero);
margin-right: var(--space-smaller);
}
.filter__question {
max-width: 30%;
}
.filter__operator {
max-width: 20%;
}
.filter__answer--wrap {
margin-right: var(--space-smaller);
flex-grow: 1;
input {
margin-bottom: 0;
}
}
.filter__answer {
&.answer--text-input {
margin-bottom: var(--space-zero);
}
}
.filter__join-operator-wrap {
position: relative;
z-index: var(--z-index-twenty);
margin: var(--space-zero);
}
.filter__join-operator {
display: flex;
align-items: center;
justify-content: center;
position: relative;
margin: var(--space-one) var(--space-zero);
.operator__line {
position: absolute;
width: 100%;
border-bottom: 1px solid var(--color-border);
}
.operator__select {
position: relative;
width: auto;
margin-bottom: var(--space-zero) !important;
@apply bg-white dark:bg-slate-900 mb-0 text-slate-800 dark:text-slate-100 border-slate-75 dark:border-slate-600;
}
}
.multiselect {
margin-bottom: var(--space-zero);
@apply mb-0;
}
</style>
@@ -1,13 +1,22 @@
<template>
<div class="option-item--inbox">
<span class="badge--icon">
<fluent-icon :icon="computedInboxIcon" size="14" />
<div class="flex items-center h-[2.375rem] min-w-0 py-0 px-1">
<span
class="inline-flex rounded mr-1 rtl:ml-1 rtl:mr-0 bg-slate-25 dark:bg-slate-700 p-0.5 items-center flex-shrink-0 justify-center w-6 h-6"
>
<fluent-icon
:icon="computedInboxIcon"
size="14"
class="text-slate-800 dark:text-slate-200"
/>
</span>
<div class="option__user-data">
<div class="flex flex-col w-full min-w-0 ml-1 mr-1">
<h5 class="option__title">
{{ name }}
</h5>
<p class="option__body text-truncate" :title="inboxIdentifier">
<p
class="option__body overflow-hidden whitespace-nowrap text-ellipsis"
:title="inboxIdentifier"
>
{{ inboxIdentifier || computedInboxType }}
</p>
</div>
@@ -58,45 +67,10 @@ export default {
</script>
<style lang="scss" scoped>
.option-item--inbox {
display: flex;
align-items: center;
height: 2.375rem;
min-width: 0;
padding: 0 var(--space-smaller);
}
.badge--icon {
display: inline-flex;
border-radius: var(--border-radius-small);
margin-right: var(--space-smaller);
background: var(--s-25);
padding: var(--space-micro);
align-items: center;
flex-shrink: 0;
justify-content: center;
width: var(--space-medium);
height: var(--space-medium);
}
.option__user-data {
display: flex;
flex-direction: column;
width: 100%;
min-width: 0;
margin-left: var(--space-smaller);
margin-right: var(--space-smaller);
}
.option__body {
display: inline-block;
color: var(--s-600);
font-size: var(--font-size-small);
line-height: 1.3;
min-width: 0;
margin: 0;
@apply inline-block text-slate-600 dark:text-slate-200 leading-[1.3] min-w-0 m-0;
}
.option__title {
line-height: 1.1;
font-size: var(--font-size-mini);
margin: 0;
@apply leading-[1.1] text-xs m-0 text-slate-800 dark:text-slate-100;
}
</style>
@@ -1,6 +1,12 @@
<template>
<div class="inbox--name">
<fluent-icon class="inbox--icon" :icon="computedInboxClass" size="12" />
<div
class="inbox--name inline-flex items-center py-0.5 px-0 leading-3 font-medium bg-none text-slate-600 dark:text-slate-500 text-xs my-0 mx-2.5"
>
<fluent-icon
class="mr-0.5 rtl:ml-0.5 rtl:mr-0"
:icon="computedInboxClass"
size="12"
/>
{{ inbox.name }}
</div>
</template>
@@ -23,20 +29,3 @@ export default {
},
};
</script>
<style scoped>
.inbox--name {
align-items: center;
display: inline-flex;
padding: var(--space-micro) 0;
line-height: var(--space-slab);
font-weight: var(--font-weight-medium);
background: none;
color: var(--s-600);
font-size: var(--font-size-mini);
margin: 0 var(--space-one);
}
.inbox--icon {
margin-right: var(--space-micro);
}
</style>
@@ -1,9 +1,14 @@
<template>
<div class="column page-top-banner">
<h2 class="page-sub-title">
<div
class="bg-slate-25 dark:bg-slate-900 pt-4 pb-0 px-8 border-b border-solid border-slate-50 dark:border-slate-800/50"
>
<h2 class="text-2xl text-slate-800 dark:text-slate-100">
{{ headerTitle }}
</h2>
<p v-if="headerContent" class="small-12 column">
<p
v-if="headerContent"
class="w-full text-slate-600 dark:text-slate-300 text-sm mb-2"
>
{{ headerContent }}
</p>
<slot />
@@ -24,10 +29,3 @@ export default {
},
};
</script>
<style lang="scss" scoped>
.page-top-banner {
border-bottom: 1px solid var(--color-border-light);
background: var(--s-25);
padding: var(--space-normal) var(--space-large) 0;
}
</style>
@@ -1,7 +1,10 @@
<template>
<footer v-if="isFooterVisible" class="footer">
<footer
v-if="isFooterVisible"
class="bg-white dark:bg-slate-800 h-[60px] border-t border-solid border-slate-75 dark:border-slate-700/50 flex items-center justify-between py-0 px-4"
>
<div class="left-aligned-wrap">
<div class="page-meta">
<div class="text-xs text-slate-600 dark:text-slate-200">
<strong>{{ firstIndex }}</strong>
- <strong>{{ lastIndex }}</strong> of
<strong>{{ totalCount }}</strong> items
@@ -161,22 +164,10 @@ export default {
</script>
<style lang="scss" scoped>
.footer {
height: 60px;
border-top: 1px solid var(--color-border);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 var(--space-normal);
}
.page-meta {
font-size: var(--font-size-mini);
}
.goto-first,
.goto-last {
i:last-child {
margin-left: var(--space-minus-smaller);
@apply -ml-1;
}
}
</style>
@@ -128,10 +128,12 @@ export default {
return { width: statusSize, height: statusSize };
},
thumbnailClass() {
const classname = this.hasBorder ? 'border' : '';
const className = this.hasBorder
? 'border border-solid border-white dark:border-slate-700/50'
: '';
const variant =
this.variant === 'circle' ? 'thumbnail-rounded' : 'thumbnail-square';
return `user-thumbnail ${classname} ${variant}`;
return `user-thumbnail ${className} ${variant}`;
},
thumbnailBoxClass() {
const boxClass = this.variant === 'circle' ? 'is-rounded' : '';
@@ -185,14 +187,9 @@ export default {
box-sizing: border-box;
object-fit: cover;
vertical-align: initial;
&.border {
border: 1px solid white;
}
}
.source-badge {
background: white;
border-radius: var(--border-radius-small);
bottom: var(--space-minus-micro);
box-shadow: var(--shadow-small);
@@ -201,6 +198,7 @@ export default {
position: absolute;
right: 0;
width: var(--space-slab);
@apply bg-white dark:bg-slate-900;
}
.user-online-status {
@@ -213,15 +211,15 @@ export default {
}
.user-online-status--online {
background: var(--g-400);
@apply bg-green-400 dark:bg-green-400;
}
.user-online-status--busy {
background: var(--y-500);
@apply bg-yellow-500 dark:bg-yellow-500;
}
.user-online-status--offline {
background: var(--s-500);
@apply bg-slate-500 dark:bg-slate-500;
}
}
</style>
@@ -6,7 +6,9 @@
:username="user.name"
:status="user.availability_status"
/>
<h6 class="text-block-title user-name text-truncate text-capitalize">
<h6
class="text-block-title user-name overflow-hidden whitespace-nowrap text-ellipsis text-capitalize"
>
{{ user.name }}
</h6>
</div>
@@ -33,12 +35,10 @@ export default {
<style scoped lang="scss">
.row--user-block {
align-items: center;
display: flex;
text-align: left;
@apply items-center flex text-left;
.user-name {
margin: 0 var(--space-small);
@apply my-0 mx-2 text-slate-700 dark:text-slate-100;
}
}
</style>
@@ -445,69 +445,61 @@ export default {
@import '~@chatwoot/prosemirror-schema/src/styles/base.scss';
.ProseMirror-menubar-wrapper {
display: flex;
flex-direction: column;
@apply flex flex-col;
.ProseMirror-menubar {
min-height: var(--space-two) !important;
margin-left: var(--space-minus-one);
padding-bottom: 0;
}
@apply -ml-2.5 pb-0 bg-white dark:bg-slate-900 text-slate-700 dark:text-slate-100;
.ProseMirror-menu-active {
@apply bg-slate-75 dark:bg-slate-800;
}
}
> .ProseMirror {
padding: 0;
word-break: break-word;
@apply p-0 break-words text-slate-800 dark:text-slate-100;
}
}
.editor-root {
width: 100%;
position: relative;
@apply w-full relative;
}
.ProseMirror-woot-style {
min-height: 5rem;
max-height: 7.5rem;
overflow: auto;
@apply overflow-auto min-h-[5rem] max-h-[7.5rem];
}
.ProseMirror-prompt {
z-index: var(--z-index-highest);
background: var(--color-background-light);
border-radius: var(--border-radius-normal);
border: 1px solid var(--color-border);
@apply z-50 bg-slate-25 dark:bg-slate-700 rounded-md border border-solid border-slate-75 dark:border-slate-800;
}
.is-private {
.prosemirror-mention-node {
font-weight: var(--font-weight-medium);
background: var(--s-50);
color: var(--s-900);
padding: 0 var(--space-smaller);
@apply font-medium bg-slate-50 dark:bg-slate-200 text-slate-900 dark:text-slate-900 py-0 px-1;
}
.ProseMirror-menubar {
background: var(--y-50);
.ProseMirror-menubar-wrapper {
.ProseMirror-menubar {
@apply bg-yellow-50 dark:bg-yellow-50 text-slate-700 dark:text-slate-700;
}
> .ProseMirror {
@apply text-slate-800 dark:text-slate-800;
}
}
}
.editor-wrap {
margin-bottom: var(--space-normal);
@apply mb-4;
}
.message-editor {
border: 1px solid var(--color-border);
border-radius: var(--border-radius-normal);
padding: 0 var(--space-slab);
margin-bottom: 0;
@apply border border-solid border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-900 rounded-md py-0 px-1 mb-0;
}
.editor_warning {
border: 1px solid var(--r-400);
@apply border border-solid border-red-400 dark:border-red-400;
}
.editor-warning__message {
color: var(--r-400);
font-weight: var(--font-weight-normal);
padding: var(--space-smaller) 0 0 0;
@apply text-red-400 dark:text-red-400 font-normal pt-1 pb-0 px-0;
}
</style>
@@ -103,7 +103,7 @@
class="modal-mask"
>
<fluent-icon icon="cloud-backup" />
<h4 class="page-sub-title">
<h4 class="page-sub-title text-slate-600 dark:text-slate-200">
{{ $t('CONVERSATION.REPLYBOX.DRAG_DROP') }}
</h4>
</div>
@@ -323,48 +323,35 @@ export default {
<style lang="scss" scoped>
.bottom-box {
display: flex;
justify-content: space-between;
padding: var(--space-slab) var(--space-normal);
@apply flex justify-between py-3 px-4;
&.is-note-mode {
background: var(--y-50);
@apply bg-yellow-50 dark:bg-yellow-50;
}
}
.left-wrap .button {
margin-right: var(--space-small);
}
.left-wrap {
align-items: center;
display: flex;
@apply items-center flex gap-2;
}
.right-wrap {
display: flex;
@apply flex;
}
::v-deep .file-uploads {
label {
cursor: pointer;
@apply cursor-pointer;
}
&:hover .button {
background: var(--s-100);
@apply dark:bg-slate-800 bg-slate-100;
}
}
.modal-mask {
color: var(--s-600);
background: var(--white-transparent);
flex-direction: column;
}
.page-sub-title {
color: var(--s-600);
@apply text-slate-600 dark:text-slate-200 bg-white_transparent dark:bg-black_transparent flex-col;
}
.icon {
font-size: 5rem;
@apply text-[5rem];
}
</style>
@@ -1,6 +1,6 @@
<template>
<div class="top-box">
<div class="mode-wrap button-group">
<div class="bg-black-50 flex justify-between dark:bg-slate-800">
<div class="button-group">
<woot-button
variant="clear"
class="button--reply"
@@ -20,8 +20,8 @@
{{ $t('CONVERSATION.REPLYBOX.PRIVATE_NOTE') }}
</woot-button>
</div>
<div class="action-wrap">
<div v-if="isMessageLengthReachingThreshold" class="tabs-title">
<div class="flex items-center my-0 mx-4">
<div v-if="isMessageLengthReachingThreshold" class="text-xs">
<span :class="charLengthClass">
{{ characterLengthWarning }}
</span>
@@ -90,7 +90,7 @@ export default {
};
},
charLengthClass() {
return this.charactersRemaining < 0 ? 'message-error' : 'message-length';
return this.charactersRemaining < 0 ? 'text-red-600' : 'text-slate-600';
},
characterLengthWarning() {
return this.charactersRemaining < 0
@@ -118,70 +118,34 @@ export default {
</script>
<style lang="scss" scoped>
.top-box {
display: flex;
justify-content: space-between;
@apply bg-black-50 dark:bg-slate-800;
}
.button-group {
border: 0;
padding: 0;
margin: 0;
@apply flex border-0 p-0 m-0;
.button {
font-size: var(--font-size-small);
font-weight: var(--font-weight-medium);
padding: var(--space-one) var(--space-normal);
margin: 0;
position: relative;
z-index: 1;
@apply text-sm font-medium py-2.5 px-4 m-0 relative z-10;
&.is-active {
background: white;
@apply bg-white dark:bg-slate-900;
}
}
.button--reply {
border-radius: 0;
@apply border-r border-b-0 border-l-0 border-slate-50 dark:border-slate-700;
@apply border-r rounded-none border-b-0 border-l-0 border-t-0 border-slate-50 dark:border-slate-700;
&:hover,
&:focus {
@apply border-r border-slate-50 dark:border-slate-700;
}
}
.button--note {
border-radius: 0;
@apply border-l-0 rounded-none;
&.is-active {
@apply border-r border-b-0 border-slate-50 dark:border-slate-700;
background: var(--y-50);
@apply border-r border-b-0 bg-yellow-50 dark:bg-yellow-50 border-t-0 border-slate-50 dark:border-slate-700;
}
&:hover,
&:active {
color: var(--y-700);
@apply text-yellow-700 dark:text-yellow-700;
}
}
}
.button--note {
color: var(--y-600);
}
.action-wrap {
display: flex;
align-items: center;
margin: 0 var(--space-normal);
font-size: var(--font-size-mini);
.message-error {
color: var(--r-600);
}
.message-length {
color: var(--s-600);
}
@apply text-yellow-600 dark:text-yellow-600;
}
</style>
@@ -1,57 +1 @@
<template>
<select v-model="activeStatus" class="status--filter" @change="onTabChange()">
<option
v-for="(value, status) in $t('CHAT_LIST.CHAT_STATUS_FILTER_ITEMS')"
:key="status"
:value="status"
>
{{ value['TEXT'] }}
</option>
</select>
</template>
<script>
import wootConstants from 'dashboard/constants/globals';
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
import { hasPressedAltAndBKey } from 'shared/helpers/KeyboardHelpers';
export default {
mixins: [eventListenerMixins],
data: () => ({
activeStatus: wootConstants.STATUS_TYPE.OPEN,
}),
methods: {
handleKeyEvents(e) {
if (hasPressedAltAndBKey(e)) {
if (this.activeStatus === wootConstants.STATUS_TYPE.OPEN) {
this.activeStatus = wootConstants.STATUS_TYPE.RESOLVED;
} else if (this.activeStatus === wootConstants.STATUS_TYPE.RESOLVED) {
this.activeStatus = wootConstants.STATUS_TYPE.PENDING;
} else if (this.activeStatus === wootConstants.STATUS_TYPE.PENDING) {
this.activeStatus = wootConstants.STATUS_TYPE.SNOOZED;
} else if (this.activeStatus === wootConstants.STATUS_TYPE.SNOOZED) {
this.activeStatus = wootConstants.STATUS_TYPE.ALL;
} else if (this.activeStatus === wootConstants.STATUS_TYPE.ALL) {
this.activeStatus = wootConstants.STATUS_TYPE.OPEN;
}
}
this.onTabChange();
},
onTabChange() {
this.$store.dispatch('setChatStatusFilter', this.activeStatus);
this.$emit('onChangeFilter', this.activeStatus);
},
},
};
</script>
<style lang="scss" scoped>
.status--filter {
background-color: var(--color-background-light);
border: 1px solid var(--color-border);
font-size: var(--font-size-mini);
height: var(--space-medium);
margin: 0 var(--space-smaller);
padding: 0 var(--space-medium) 0 var(--space-small);
width: auto;
}
</style>
<!-- // not using this component -->
@@ -1,22 +1,30 @@
<template>
<div class="column">
<div>
<woot-modal-header :header-title="filterModalHeaderTitle">
<p>{{ filterModalSubTitle }}</p>
<p class="text-slate-600 dark:text-slate-200">
{{ filterModalSubTitle }}
</p>
</woot-modal-header>
<div class="column modal-content">
<div v-if="isFolderView" class="columns">
<div class="p-8">
<div v-if="isFolderView">
<label class="input-label" :class="{ error: !activeFolderNewName }">
{{ $t('FILTER.FOLDER_LABEL') }}
<input v-model="activeFolderNewName" type="text" class="name-input" />
<input
v-model="activeFolderNewName"
type="text"
class="folder-input border-slate-75 dark:border-slate-600 bg-white dark:bg-slate-900 text-slate-900 dark:text-slate-100"
/>
<span v-if="!activeFolderNewName" class="message">
{{ $t('FILTER.EMPTY_VALUE_ERROR') }}
</span>
</label>
<label class="input-label">
<label class="mb-1">
{{ $t('FILTER.FOLDER_QUERY_LABEL') }}
</label>
</div>
<div class="medium-12 columns filters-wrap">
<div
class="p-4 rounded-lg bg-slate-25 dark:bg-slate-700 border border-solid border-slate-50 dark:border-slate-700 mb-4"
>
<filter-input-box
v-for="(filter, i) in appliedFilters"
:key="i"
@@ -37,7 +45,7 @@
@resetFilter="resetFilter(i, appliedFilters[i])"
@removeFilter="removeFilter(i)"
/>
<div class="filter-actions">
<div class="mt-4">
<woot-button
icon="add"
color-scheme="success"
@@ -49,8 +57,8 @@
</woot-button>
</div>
</div>
<div class="medium-12 columns">
<div class="modal-footer justify-content-end w-full">
<div class="w-full">
<div class="flex flex-row justify-end gap-2 py-2 px-0 w-full">
<woot-button class="button clear" @click.prevent="onClose">
{{ $t('FILTER.CANCEL_BUTTON_LABEL') }}
</woot-button>
@@ -371,23 +379,7 @@ export default {
};
</script>
<style lang="scss" scoped>
.filters-wrap {
padding: var(--space-normal);
border-radius: var(--border-radius-large);
border: 1px solid var(--color-border);
background: var(--color-background-light);
margin-bottom: var(--space-normal);
}
.filter-actions {
margin-top: var(--space-normal);
}
.input-label {
margin-bottom: var(--space-smaller);
.name-input {
width: 50%;
}
.folder-input {
@apply w-[50%];
}
</style>
@@ -1,5 +1,5 @@
<template>
<div class="position-relative">
<div class="relative flex">
<woot-button
v-tooltip.right="$t('CHAT_LIST.SORT_TOOLTIP_LABEL')"
variant="smooth"
@@ -12,10 +12,12 @@
<div
v-if="showActionsDropdown"
v-on-clickaway="closeDropdown"
class="dropdown-pane dropdown-pane--open basic-filter"
class="dropdown-pane dropdown-pane--open mt-1 right-0 basic-filter"
>
<div class="filter__item">
<span>{{ this.$t('CHAT_LIST.CHAT_SORT.STATUS') }}</span>
<div class="items-center flex justify-between last:mt-4">
<span class="text-slate-800 dark:text-slate-100 text-xs font-medium">{{
this.$t('CHAT_LIST.CHAT_SORT.STATUS')
}}</span>
<filter-item
type="status"
:selected-value="chatStatus"
@@ -24,8 +26,10 @@
@onChangeFilter="onChangeFilter"
/>
</div>
<div class="filter__item">
<span>{{ this.$t('CHAT_LIST.CHAT_SORT.ORDER_BY') }}</span>
<div class="items-center flex justify-between last:mt-4">
<span class="text-slate-800 dark:text-slate-100 text-xs font-medium">{{
this.$t('CHAT_LIST.CHAT_SORT.ORDER_BY')
}}</span>
<filter-item
type="sort"
:selected-value="chatSortFilter"
@@ -87,36 +91,6 @@ export default {
</script>
<style lang="scss" scoped>
.basic-filter {
margin-top: var(--space-smaller);
padding: var(--space-normal);
right: 0;
width: 13.125rem;
span {
font-size: var(--font-size-small);
font-weight: var(--font-weight-medium);
}
.filter__item {
align-items: center;
display: flex;
justify-content: space-between;
&:last-child {
margin-top: var(--space-normal);
}
span {
font-size: var(--font-size-mini);
}
}
}
.icon {
margin-right: var(--space-smaller);
}
.dropdown-icon {
margin-left: var(--space-smaller);
@apply w-52 p-4 top-6;
}
</style>
@@ -13,7 +13,7 @@
<woot-tabs
v-if="dashboardApps.length && currentChat.id"
:index="activeIndex"
class="dashboard-app--tabs"
class="dashboard-app--tabs bg-white dark:bg-slate-900 -mt-px"
@change="onDashboardAppTabChange"
>
<woot-tabs-item
@@ -34,7 +34,10 @@
@contact-panel-toggle="onToggleContactPanel"
/>
<empty-state v-else :is-on-expanded-layout="isOnExpandedLayout" />
<div v-show="showContactPanel" class="conversation-sidebar-wrap">
<div
v-show="showContactPanel"
class="conversation-sidebar-wrap basis-full sm:basis-[17.5rem] md:basis-[18.75rem] lg:basis-[19.375rem] xl:basis-[20.625rem] 2xl:basis-[25rem] rtl:border-r border-slate-50 dark:border-slate-700 h-auto overflow-auto z-10 flex-shrink-0 flex-grow-0"
>
<contact-panel
v-if="showContactPanel"
:conversation-id="currentChat.id"
@@ -141,12 +144,8 @@ export default {
};
</script>
<style lang="scss" scoped>
@import '~dashboard/assets/scss/woot';
.conversation-details-wrap {
display: flex;
flex-direction: column;
min-width: 0;
width: 100%;
@apply flex flex-col min-w-0 w-full;
&.with-border-right {
@apply border-r border-slate-50 dark:border-slate-700;
@@ -154,40 +153,18 @@ export default {
}
.dashboard-app--tabs {
background: var(--white);
margin-top: -1px;
min-height: var(--dashboard-app-tabs-height);
::v-deep {
.tabs-title {
a {
@apply pb-2 pt-1;
}
}
}
}
.conversation-sidebar-wrap {
@apply border-r border-slate-50 dark:border-slate-700;
background: white;
flex-basis: 100%;
@include breakpoint(medium up) {
flex-basis: 17.5rem;
}
@include breakpoint(large up) {
flex-basis: 18.75rem;
}
@include breakpoint(xlarge up) {
flex-basis: 19.375rem;
}
@include breakpoint(xxlarge up) {
flex-basis: 20.625rem;
}
@include breakpoint(xxxlarge up) {
flex-basis: 25rem;
}
&::v-deep .contact--panel {
width: 100%;
height: 100%;
max-width: 100%;
@apply w-full h-full max-w-full;
}
}
</style>
@@ -1,8 +1,8 @@
<template>
<div
class="conversation group border-t border-transparent"
class="conversation flex flex-shrink-0 flex-grow-0 w-auto max-w-full cursor-pointer relative py-0 px-4 border-transparent border-l-2 border-t-0 border-b-0 border-r-0 border-solid items-start hover:bg-slate-50 dark:hover:bg-slate-800 group"
:class="{
active: isActiveChat,
'active bg-slate-50 dark:bg-slate-800 border-woot-500': isActiveChat,
'unread-chat': hasUnread,
'has-inbox-name': showInboxName,
'conversation-selected': selected,
@@ -31,41 +31,50 @@
size="40px"
/>
<div
class="conversation--details border-b group-last:border-transparent group-hover:border-transparent border-slate-50 dark:border-slate-800 columns"
class="py-3 px-0 border-b group-last:border-transparent group-hover:border-transparent border-slate-50 dark:border-slate-800/75 columns"
>
<div class="conversation--metadata">
<div class="flex justify-between">
<inbox-name v-if="showInboxName" :inbox="inbox" />
<div class="conversation-metadata-attributes">
<div class="flex gap-2 ml-2 rtl:mr-2 rtl:ml-0">
<span
v-if="showAssignee && assignee.name"
class="label assignee-label text-truncate"
class="text-slate-500 dark:text-slate-400 text-xs font-medium leading-3 py-0.5 px-0 inline-flex text-ellipsis overflow-hidden whitespace-nowrap"
>
<fluent-icon icon="person" size="12" />
<fluent-icon
icon="person"
size="12"
class="text-slate-500 dark:text-slate-400"
/>
{{ assignee.name }}
</span>
<priority-mark :priority="chat.priority" />
</div>
</div>
<h4 class="conversation--user">
<h4
class="conversation--user text-sm my-0 mx-2 capitalize pt-0.5 text-ellipsis overflow-hidden whitespace-nowrap w-[60%] text-slate-900 dark:text-slate-100"
>
{{ currentContact.name }}
</h4>
<p v-if="lastMessageInChat" class="conversation--message">
<p
v-if="lastMessageInChat"
class="conversation--message text-slate-700 dark:text-slate-200 text-sm my-0 mx-2 leading-6 h-6 max-w-[96%] w-[16.875rem] overflow-hidden text-ellipsis whitespace-nowrap"
>
<fluent-icon
v-if="isMessagePrivate"
size="16"
class="message--attachment-icon last-message-icon"
class="-mt-0.5 align-middle text-slate-600 dark:text-slate-300 inline-block"
icon="lock-closed"
/>
<fluent-icon
v-else-if="messageByAgent"
size="16"
class="message--attachment-icon last-message-icon"
class="-mt-0.5 align-middle text-slate-600 dark:text-slate-300 inline-block"
icon="arrow-reply"
/>
<fluent-icon
v-else-if="isMessageAnActivity"
size="16"
class="message--attachment-icon last-message-icon"
class="-mt-0.5 align-middle text-slate-600 dark:text-slate-300 inline-block"
icon="info"
/>
<span v-if="lastMessageInChat.content">
@@ -75,7 +84,7 @@
<fluent-icon
v-if="attachmentIcon"
size="16"
class="message--attachment-icon"
class="-mt-0.5 align-middle inline-block"
:icon="attachmentIcon"
/>
{{ this.$t(`${attachmentMessageContent}`) }}
@@ -84,20 +93,31 @@
{{ $t('CHAT_LIST.NO_CONTENT') }}
</span>
</p>
<p v-else class="conversation--message">
<fluent-icon size="16" class="message--attachment-icon" icon="info" />
<p
v-else
class="conversation--message text-slate-700 dark:text-slate-200 text-sm my-0 mx-2 leading-6 h-6 max-w-[96%] w-[16.875rem] overflow-hidden text-ellipsis whitespace-nowrap"
>
<fluent-icon
size="16"
class="-mt-0.5 align-middle"
icon="info inline-block"
/>
<span>
{{ this.$t(`CHAT_LIST.NO_MESSAGES`) }}
</span>
</p>
<div class="conversation--meta">
<span class="timestamp">
<div class="conversation--meta flex flex-col absolute right-4 top-4">
<span class="text-black-600 text-xxs font-normal leading-4 ml-auto">
<time-ago
:last-activity-timestamp="chat.timestamp"
:created-at-timestamp="chat.created_at"
/>
</span>
<span class="unread">{{ unreadCount > 9 ? '9+' : unreadCount }}</span>
<span
class="unread shadow-lg rounded-full hidden text-xxs font-semibold h-4 leading-4 ml-auto mt-1 min-w-[1rem] px-1 py-0 text-center text-white bg-green-400"
>
{{ unreadCount > 9 ? '9+' : unreadCount }}
</span>
</div>
<card-labels :conversation-id="chat.id" />
</div>
@@ -400,94 +420,51 @@ export default {
</script>
<style lang="scss" scoped>
.conversation {
align-items: flex-start;
&.unread-chat {
.unread {
@apply block;
}
.conversation--message {
@apply font-semibold;
}
.conversation--user {
@apply font-semibold;
}
}
&:hover {
background: var(--color-background-light);
&.compact {
@apply pl-0;
.conversation--details {
@apply rounded-sm ml-0 pl-5 pr-2;
}
}
&::v-deep .user-thumbnail-box {
margin-top: var(--space-normal);
@apply mt-4;
}
}
.conversation-selected {
background: var(--color-background-light);
}
.has-inbox-name {
&::v-deep .user-thumbnail-box {
margin-top: var(--space-large);
&.conversation-selected {
@apply bg-slate-25 dark:bg-slate-800;
}
&.has-inbox-name {
&::v-deep .user-thumbnail-box {
@apply mt-8;
}
.checkbox-wrapper {
@apply mt-8;
}
.conversation--meta {
@apply mt-4;
}
}
.checkbox-wrapper {
margin-top: var(--space-large);
}
.conversation--meta {
margin-top: var(--space-normal);
}
}
@apply h-10 w-10 flex items-center justify-center rounded-full cursor-pointer mt-4 hover:bg-woot-100 dark:hover:bg-woot-800;
.conversation--details {
.conversation--user {
padding-top: var(--space-micro);
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 60%;
}
}
.last-message-icon {
color: var(--s-600);
}
.conversation--metadata {
display: flex;
justify-content: space-between;
.label {
background: none;
color: var(--s-500);
font-size: var(--font-size-mini);
font-weight: var(--font-weight-medium);
line-height: var(--space-slab);
padding: var(--space-micro) 0 var(--space-micro) 0;
}
.conversation-metadata-attributes {
display: flex;
gap: var(--space-small);
margin-left: var(--space-small);
}
.assignee-label {
display: inline-flex;
max-width: 50%;
}
}
.message--attachment-icon {
margin-top: var(--space-minus-micro);
vertical-align: middle;
}
.checkbox-wrapper {
height: 40px;
width: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 100%;
margin-top: var(--space-normal);
cursor: pointer;
&:hover {
background-color: var(--w-100);
}
input[type='checkbox'] {
margin: var(--space-zero);
cursor: pointer;
input[type='checkbox'] {
@apply m-0 cursor-pointer;
}
}
}
</style>
@@ -1,9 +1,13 @@
<template>
<div class="conv-header flex-col md:flex-row">
<div
class="bg-white dark:bg-slate-900 flex justify-between items-center py-2 px-4 border-b border-slate-50 dark:border-slate-800/50 flex-col md:flex-row"
>
<div
class="flex-1 w-100 flex flex-col md:flex-row items-center justify-center"
>
<div class="user">
<div
class="flex justify-center items-center mr-4 rtl:mr-0 rtl:ml-4 min-w-0"
>
<back-button v-if="showBackButton" :back-url="backButtonUrl" />
<Thumbnail
:src="currentContact.thumbnail"
@@ -11,31 +15,38 @@
:username="currentContact.name"
:status="currentContact.availability_status"
/>
<div class="user--profile__meta">
<div class="items-start flex flex-col ml-2 rtl:ml-0 rtl:mr-2 min-w-0">
<woot-button
variant="link"
color-scheme="secondary"
class="text-truncate"
class="overflow-hidden whitespace-nowrap text-ellipsis"
@click.prevent="$emit('contact-panel-toggle')"
>
<h3 class="sub-block-title user--name text-truncate">
<h3
class="text-base inline-block leading-tight capitalize m-0 p-0 text-ellipsis overflow-hidden whitespace-nowrap text-slate-900 dark:text-slate-100"
>
<span>{{ currentContact.name }}</span>
<fluent-icon
v-if="!isHMACVerified"
v-tooltip="$t('CONVERSATION.UNVERIFIED_SESSION')"
size="14"
class="hmac-warning__icon"
class="text-yellow-600 dark:text-yellow-500 my-0 mx-0.5"
icon="warning"
/>
</h3>
</woot-button>
<div class="conversation--header--actions text-truncate">
<div
class="conversation--header--actions items-center flex text-xs gap-2 text-ellipsis overflow-hidden whitespace-nowrap"
>
<inbox-name v-if="hasMultipleInboxes" :inbox="inbox" />
<span v-if="isSnoozed" class="snoozed--display-text">
<span
v-if="isSnoozed"
class="font-medium text-yellow-600 dark:text-yellow-500"
>
{{ snoozedDisplayText }}
</span>
<woot-button
class="user--profile__button"
class="p-0"
size="small"
variant="link"
@click="$emit('contact-panel-toggle')"
@@ -46,8 +57,8 @@
</div>
</div>
<div
class="header-actions-wrap mt-3 lg:mt-0"
:class="{ 'has-open-sidebar': isContactPanelOpen }"
class="header-actions-wrap items-center flex flex-row flex-grow justify-end mt-3 lg:mt-0"
:class="{ 'justify-end': isContactPanelOpen }"
>
<more-actions :conversation-id="currentChat.id" />
</div>
@@ -161,54 +172,9 @@ export default {
</script>
<style lang="scss" scoped>
.conv-header {
flex: 0 0 var(--space-jumbo);
flex-direction: row;
}
.option__desc {
display: flex;
align-items: center;
}
.option__desc {
&::v-deep .status-badge {
margin-right: var(--space-small);
min-width: 0;
flex-shrink: 0;
}
}
.user--name {
display: inline-block;
line-height: 1.2;
text-transform: capitalize;
margin: 0;
padding: 0;
}
.conversation--header--actions {
align-items: center;
display: flex;
font-size: var(--font-size-mini);
gap: var(--space-small);
::v-deep .inbox--name {
margin: 0;
@apply m-0;
}
.user--profile__button {
padding: 0;
}
.snoozed--display-text {
font-weight: var(--font-weight-medium);
color: var(--y-600);
}
}
.hmac-warning__icon {
color: var(--y-600);
margin: 0 var(--space-micro);
}
</style>
@@ -1,12 +1,12 @@
<template>
<woot-modal :show.sync="show" :on-close="onCancel">
<div class="column content-box">
<div class="h-auto overflow-auto flex flex-col">
<woot-modal-header
:header-title="$t('EMAIL_TRANSCRIPT.TITLE')"
:header-content="$t('EMAIL_TRANSCRIPT.DESC')"
/>
<form @submit.prevent="onSubmit">
<div class="medium-12 columns">
<form class="w-full" @submit.prevent="onSubmit">
<div class="w-full">
<div v-if="currentChat.meta.sender && currentChat.meta.sender.email">
<input
id="contact"
@@ -43,7 +43,7 @@
$t('EMAIL_TRANSCRIPT.FORM.SEND_TO_OTHER_EMAIL_ADDRESS')
}}</label>
</div>
<div v-if="sentToOtherEmailAddress" class="medium-6 columns">
<div v-if="sentToOtherEmailAddress" class="w-[50%] mt-1">
<label :class="{ error: $v.email.$error }">
<input
v-model.trim="email"
@@ -57,16 +57,14 @@
</label>
</div>
</div>
<div class="modal-footer">
<div class="medium-12 row">
<woot-submit-button
:button-text="$t('EMAIL_TRANSCRIPT.SUBMIT')"
:disabled="!isFormValid"
/>
<button class="button clear" @click.prevent="onCancel">
{{ $t('EMAIL_TRANSCRIPT.CANCEL') }}
</button>
</div>
<div class="flex flex-row justify-end gap-2 py-2 px-0 w-full">
<woot-submit-button
:button-text="$t('EMAIL_TRANSCRIPT.SUBMIT')"
:disabled="!isFormValid"
/>
<button class="button clear" @click.prevent="onCancel">
{{ $t('EMAIL_TRANSCRIPT.CANCEL') }}
</button>
</div>
</form>
</div>
@@ -1,5 +1,9 @@
<template>
<select v-model="activeValue" class="status--filter" @change="onTabChange()">
<select
v-model="activeValue"
class="bg-slate-25 dark:bg-slate-700 text-xs h-6 my-0 mx-1 py-0 pr-6 pl-2 w-32 border border-solid border-slate-75 dark:border-slate-600 text-slate-800 dark:text-slate-100"
@change="onTabChange()"
>
<option v-for="(value, status) in items" :key="status" :value="status">
{{ $t(`${pathPrefix}.${status}.TEXT`) }}
</option>
@@ -42,14 +46,3 @@ export default {
},
};
</script>
<style lang="scss" scoped>
.status--filter {
background-color: var(--color-background-light);
border: 1px solid var(--color-border);
font-size: var(--font-size-mini);
height: var(--space-medium);
margin: 0 var(--space-smaller);
padding: 0 var(--space-medium) 0 var(--space-small);
width: 126px;
}
</style>
@@ -511,94 +511,82 @@ export default {
<style lang="scss">
.wrap {
> .bubble {
min-width: 128px;
@apply min-w-[128px];
&.is-image,
&.is-video {
padding: 0;
overflow: hidden;
@apply p-0 overflow-hidden;
.image,
.video {
max-width: 20rem;
padding: var(--space-micro);
@apply max-w-[20rem] p-0.5;
> img,
> video {
border-radius: var(--border-radius-medium);
@apply rounded-lg;
}
> video {
height: 100%;
object-fit: cover;
width: 100%;
@apply h-full w-full object-cover;
}
}
.video {
height: 11.25rem;
@apply h-[11.25rem];
}
}
&.is-image.is-text > .message-text__wrap,
&.is-video.is-text > .message-text__wrap {
max-width: 20rem;
padding: var(--space-small) var(--space-normal);
@apply max-w-[20rem] py-2 px-4;
}
&.is-private .file.message-text__wrap {
.file--icon {
color: var(--w-400);
@apply text-woot-400 dark:text-woot-400;
}
.text-block-title {
color: #3c4858;
@apply text-slate-700 dark:text-slate-700;
}
.download.button {
color: var(--w-400);
@apply text-woot-400 dark:text-woot-400;
}
}
&.is-private.is-text > .message-text__wrap .link {
color: var(--w-700);
@apply text-woot-700 dark:text-woot-700;
}
&.is-private.is-text > .message-text__wrap .prosemirror-mention-node {
font-weight: var(--font-weight-black);
background: none;
border-radius: var(--border-radius-small);
padding: 0;
color: var(--color-body);
text-decoration: underline;
@apply font-bold bg-none rounded-sm p-0 text-slate-700 dark:text-slate-700 underline;
}
&.is-from-bot {
background: var(--v-400);
@apply bg-violet-400 dark:bg-violet-400;
.message-text--metadata .time {
color: var(--v-50);
@apply text-violet-50 dark:text-violet-50;
}
&.is-private .message-text--metadata .time {
color: var(--s-400);
@apply text-slate-400 dark:text-slate-400;
}
}
&.is-failed {
background: var(--r-200);
@apply bg-red-200 dark:bg-red-200;
.message-text--metadata .time {
color: var(--r-50);
@apply text-red-50 dark:text-red-50;
}
}
}
&.is-pending {
position: relative;
opacity: 0.8;
@apply relative opacity-80;
.spinner {
position: absolute;
bottom: var(--space-smaller);
right: var(--space-smaller);
@apply absolute bottom-1 right-1;
}
> .is-image.is-text.bubble > .message-text__wrap {
padding: 0;
@apply p-0;
}
}
}
@@ -608,135 +596,97 @@ export default {
}
.sender--info {
align-items: center;
color: var(--b-700);
display: inline-flex;
padding: var(--space-smaller) 0;
@apply items-center text-black-700 dark:text-black-100 inline-flex py-1 px-0;
.sender--available-name {
font-size: var(--font-size-mini);
margin-left: var(--space-smaller);
@apply text-xs ml-1;
}
}
.message-failed--alert {
color: var(--r-900);
flex-grow: 1;
text-align: right;
margin-top: var(--space-smaller) var(--space-smaller) 0 0;
@apply text-red-900 dark:text-red-900 flex-grow text-right mt-1 mr-1 mb-0 ml-0;
}
li.left,
li.right {
display: flex;
align-items: flex-end;
@apply flex items-end;
}
li.left.has-tweet-menu .context-menu {
margin-bottom: var(--space-medium);
@apply mb-6;
}
li.has-bg {
background: var(--w-75);
@apply bg-woot-75 dark:bg-woot-600;
}
li.right .context-menu-wrap {
margin-left: auto;
@apply ml-auto;
}
li.right {
flex-direction: row-reverse;
justify-content: flex-end;
@apply flex-row-reverse justify-end;
.wrap.is-pending {
margin-left: auto;
@apply ml-auto;
}
.wrap.is-failed {
display: flex;
align-items: flex-end;
margin-left: auto;
@apply flex items-end ml-auto;
}
}
.has-context-menu {
background: var(--color-background);
@apply bg-slate-50 dark:bg-slate-700;
}
.context-menu {
position: relative;
@apply relative;
}
/* Markdown styling */
.bubble .text-content {
p code {
background-color: var(--s-75);
display: inline-block;
line-height: 1;
border-radius: var(--border-radius-small);
padding: var(--space-smaller);
@apply bg-slate-75 dark:bg-slate-700 inline-block leading-none rounded-sm p-1;
}
pre {
background-color: var(--s-75);
border-color: var(--s-75);
color: var(--s-800);
border-radius: var(--border-radius-normal);
padding: var(--space-small);
margin-top: var(--space-smaller);
margin-bottom: var(--space-small);
display: block;
line-height: 1.7;
white-space: pre-wrap;
@apply bg-slate-75 dark:bg-slate-700 block border-slate-75 dark:border-slate-700 text-slate-800 dark:text-slate-100 rounded-md p-2 mt-1 mb-2 leading-relaxed whitespace-pre-wrap;
code {
background-color: transparent;
color: var(--s-800);
padding: 0;
@apply bg-transparent text-slate-800 dark:text-slate-100 p-0;
}
}
blockquote {
border-left: var(--space-micro) solid var(--s-75);
color: var(--s-800);
margin: var(--space-smaller) 0;
padding: var(--space-small) var(--space-small) 0 var(--space-normal);
@apply border-l-4 mx-0 my-1 pt-2 pr-2 pb-0 pl-4 border-slate-75 border-solid dark:border-slate-700 text-slate-800 dark:text-slate-100;
}
}
.right .bubble .text-content {
p code {
background-color: var(--w-600);
color: var(--white);
@apply bg-woot-600 dark:bg-woot-600 text-white dark:text-white;
}
pre {
background-color: var(--w-800);
border-color: var(--w-700);
color: var(--white);
@apply bg-woot-800 dark:bg-woot-800 border-woot-700 dark:border-woot-700 text-white dark:text-white;
code {
background-color: transparent;
color: var(--white);
@apply bg-transparent text-white dark:text-white;
}
}
blockquote {
border-left: var(--space-micro) solid var(--w-400);
color: var(--white);
@apply border-l-4 border-solid border-woot-400 dark:border-woot-400 text-white dark:text-white;
p {
color: var(--w-75);
@apply text-woot-75 dark:text-woot-75;
}
}
}
.story-reply-quote {
border-left: var(--space-micro) solid var(--s-75);
color: var(--s-600);
margin: var(--space-small) var(--space-normal) 0;
padding: var(--space-small) var(--space-small) 0 var(--space-small);
@apply mt-2 mx-4 mb-0 px-2 pb-0 pt-2 border-l-4 border-solid border-slate-75 dark:border-slate-600 text-slate-600 dark:text-slate-200;
}
</style>
@@ -1,5 +1,5 @@
<template>
<div class="view-box fill-height">
<div class="m-0 flex flex-col justify-between h-full flex-grow min-w-0">
<banner
v-if="!currentChat.can_reply"
color-scheme="alert"
@@ -16,19 +16,19 @@
@close="removeTweetSelection"
/>
<div class="sidebar-toggle__wrap">
<div class="flex justify-end">
<woot-button
variant="smooth"
size="tiny"
color-scheme="secondary"
class="sidebar-toggle--button"
class="rounded-bl-calc rtl:rotate-180 rounded-tl-calc fixed top-[6.25rem] z-10 bg-white dark:bg-slate-700 border-slate-50 dark:border-slate-600 border-solid border border-r-0 box-border"
:icon="isRightOrLeftIcon"
@click="onToggleContactPanel"
/>
</div>
<ul class="conversation-panel">
<transition name="slide-up">
<li class="spinner--container">
<li class="min-h-[4rem]">
<span v-if="shouldShowSpinner" class="spinner message" />
</li>
</transition>
@@ -44,7 +44,7 @@
:is-web-widget-inbox="isAWebWidgetInbox"
/>
<li v-show="unreadMessageCount != 0" class="unread--toast">
<span class="text-uppercase">
<span>
{{ unreadMessageCount }}
{{
unreadMessageCount > 1
@@ -535,68 +535,41 @@ export default {
};
</script>
<style scoped lang="scss">
.spinner--container {
min-height: var(--space-jumbo);
}
.view-box.fill-height {
height: auto;
flex-grow: 1;
min-width: 0;
}
.modal-mask {
&::v-deep {
.ProseMirror-woot-style {
max-height: 25rem;
}
.reply-box {
border: 1px solid var(--color-border);
max-width: 75rem;
width: 70%;
}
.reply-box .reply-box__top {
position: relative;
min-height: 27.5rem;
}
.reply-box__top .input {
min-height: 27.5rem;
}
.emoji-dialog {
position: fixed;
left: unset;
position: absolute;
bottom: var(--space-smaller);
}
<style scoped>
@tailwind components;
@layer components {
.rounded-bl-calc {
border-bottom-left-radius: calc(1.5rem + 1px);
}
}
.sidebar-toggle__wrap {
display: flex;
justify-content: flex-end;
.sidebar-toggle--button {
position: fixed;
.rounded-tl-calc {
border-top-left-radius: calc(1.5rem + 1px);
}
}
</style>
top: var(--space-mega);
z-index: var(--z-index-low);
<style scoped lang="scss">
.modal-mask {
&::v-deep {
.ProseMirror-woot-style {
@apply max-h-[25rem];
}
background: var(--white);
.reply-box {
@apply border border-solid border-slate-75 dark:border-slate-600 max-w-[75rem] w-[70%];
}
padding: inherit 0;
border-top-left-radius: calc(
var(--space-medium) + 1px
); /* 100px of height + 10px of border */
border-bottom-left-radius: calc(
var(--space-medium) + 1px
); /* 100px of height + 10px of border */
border: 1px solid var(--color-border-light);
border-right: 0;
box-sizing: border-box;
.reply-box .reply-box__top {
@apply relative min-h-[27.5rem];
}
.reply-box__top .input {
@apply min-h-[27.5rem];
}
.emoji-dialog {
@apply absolute left-auto bottom-1;
}
}
}
</style>
@@ -1,5 +1,5 @@
<template>
<div class="flex-container actions--container">
<div class="flex actions--container relative items-center gap-2">
<woot-button
v-if="!currentChat.muted"
v-tooltip="$t('CONTACT_PANEL.MUTE_CONTACT')"
@@ -87,31 +87,15 @@ export default {
};
</script>
<style scoped lang="scss">
.actions--container {
align-items: center;
.resolve-actions {
margin-left: var(--space-small);
}
}
.more--button {
align-items: center;
display: flex;
margin-left: var(--space-small);
}
.actions--container {
position: relative;
@apply items-center flex ml-2 rtl:ml-0 rtl:mr-2;
}
.dropdown-pane {
right: var(--space-minus-small);
top: 48px;
@apply -right-2 top-12;
}
.icon {
margin-right: var(--space-smaller);
min-width: var(--space-normal);
@apply mr-1 rtl:mr-0 rtl:ml-1 min-w-[1rem];
}
</style>
@@ -6,10 +6,10 @@
delay: { show: 1500, hide: 0 },
hideOnClick: true,
}"
class="shrink-0 rounded-xs inline-flex w-3 h-3 "
class="shrink-0 rounded-sm inline-flex w-3.5 h-3.5"
:class="{
'bg-red-50 text-red-500': isUrgent,
'bg-slate-50 text-slate-600': !isUrgent,
'bg-red-50 dark:bg-red-700 dark:bg-opacity-30 text-red-500 dark:text-red-600': isUrgent,
'bg-slate-50 dark:bg-slate-700 text-slate-600 dark:text-slate-200': !isUrgent,
}"
>
<fluent-icon
@@ -1091,51 +1091,34 @@ export default {
<style lang="scss" scoped>
.send-button {
margin-bottom: 0;
@apply mb-0;
}
.message-signature-wrap {
margin: 0 var(--space-normal);
padding: var(--space-small);
display: flex;
align-items: baseline;
justify-content: space-between;
border: 1px dashed var(--s-100);
border-radius: var(--border-radius-small);
max-height: 8vh;
overflow: auto;
&:hover {
background: var(--s-25);
}
@apply my-0 mx-4 px-1 flex max-h-[8vh] items-baseline justify-between hover:bg-slate-25 dark:hover:bg-slate-800 border border-dashed border-slate-100 dark:border-slate-700 rounded-sm overflow-auto;
}
.message-signature {
width: fit-content;
margin: 0;
@apply w-fit m-0;
}
.attachment-preview-box {
padding: 0 var(--space-normal);
background: transparent;
@apply bg-transparent py-0 px-4;
}
.reply-box {
@apply border-r border-slate-50 dark:border-slate-700 bg-white dark:bg-slate-900;
@apply border-t border-slate-50 dark:border-slate-700 bg-white dark:bg-slate-900;
&.is-private {
background: var(--y-50);
@apply bg-yellow-50 dark:bg-yellow-50;
}
}
.send-button {
margin-bottom: 0;
@apply mb-0;
}
.reply-box__top {
position: relative;
padding: 0 var(--space-normal);
border-top: 1px solid var(--color-border);
margin-top: -1px;
@apply relative py-0 px-4 -mt-px border-t border-solid border-slate-50 dark:border-slate-700;
}
.emoji-dialog {
@@ -1177,10 +1160,10 @@ export default {
}
}
.message-signature {
margin-bottom: 0;
@apply mb-0;
::v-deep p:last-child {
margin-bottom: 0;
@apply mb-0;
}
}
@@ -147,31 +147,23 @@ export default {
</script>
<style lang="scss" scoped>
.input-group-wrap .message {
font-size: var(--font-size-small);
color: var(--r-500);
@apply text-sm text-red-500 dark:text-red-500;
}
.input-group {
border-bottom: 1px solid var(--color-border);
margin-bottom: var(--space-smaller);
margin-top: var(--space-smaller);
@apply border-b border-solid border-slate-75 dark:border-slate-700 my-1;
.input-group-label {
border-color: transparent;
background: transparent;
font-size: var(--font-size-mini);
font-weight: var(--font-weight-bold);
padding-left: 0;
@apply border-transparent bg-transparent text-xs font-semibold pl-0;
}
.input-group-field::v-deep input {
margin-bottom: 0;
border-color: transparent;
@apply mb-0 border-transparent;
}
}
.input-group.error {
border-bottom-color: var(--r-500);
@apply border-b-red-500 dark:border-b-red-500;
.input-group-label {
color: var(--r-500);
@apply text-red-500 dark:text-red-500;
}
}
</style>
@@ -9,21 +9,28 @@
:id="`mention-item-${index}`"
:key="agent.id"
:class="{ active: index === selectedIndex }"
class="last:mb-2 items-center rounded-md flex p-2"
@click="onAgentSelect(index)"
@mouseover="onHover(index)"
>
<div class="mention--thumbnail">
<div class="mr-2">
<woot-thumbnail
:src="agent.thumbnail"
:username="agent.name"
size="32px"
/>
</div>
<div class="mention--metadata text-truncate">
<h5 class="text-block-title mention--user-name text-truncate">
<div
class="flex-1 max-w-full overflow-hidden whitespace-nowrap text-ellipsis"
>
<h5
class="mention--user-name mb-0 text-sm text-slate-900 dark:text-slate-100 overflow-hidden whitespace-nowrap text-ellipsis"
>
{{ agent.name }}
</h5>
<div class="text-truncate mention--email text-truncate">
<div
class="mention--email overflow-hidden whitespace-nowrap text-ellipsis text-slate-700 dark:text-slate-300 text-xs"
>
{{ agent.email }}
</div>
</div>
@@ -88,69 +95,29 @@ export default {
<style scoped lang="scss">
.mention--box {
background: var(--white);
border-radius: var(--border-radius-normal);
border-top: 1px solid var(--color-border);
box-shadow: var(--shadow-medium);
font-size: var(--font-size-small);
left: 0;
bottom: 100%;
line-height: 1.2;
max-height: 12.5rem;
overflow: auto;
padding: var(--space-small) var(--space-small) 0 var(--space-small);
position: absolute;
width: 100%;
z-index: 100;
@apply bg-white text-sm dark:bg-slate-700 rounded-md overflow-auto absolute w-full z-[100] pt-2 px-2 pb-0 shadow-md left-0 leading-[1.2] bottom-full max-h-[12.5rem] border-t border-solid border-slate-75 dark:border-slate-800;
&.with-bottom-border {
border-bottom: var(--space-small) solid var(--white);
@apply border-b-[0.5rem] border-solid border-white dark:border-slate-600;
li {
&:last-child {
margin-bottom: 0;
@apply mb-0;
}
}
}
li {
align-items: center;
border-radius: var(--border-radius-normal);
display: flex;
padding: var(--space-small);
&.active {
background: var(--s-50);
@apply bg-slate-50 dark:bg-slate-800;
.mention--user-name {
color: var(--s-900);
@apply text-slate-900 dark:text-slate-100;
}
.mention--email {
color: var(--s-800);
@apply text-slate-800 dark:text-slate-200;
}
}
&:last-child {
margin-bottom: var(--space-small);
}
}
}
.mention--thumbnail {
margin-right: var(--space-small);
}
.mention--user-name {
margin-bottom: 0;
}
.mention--email {
color: var(--s-700);
font-size: var(--font-size-mini);
}
.mention--metadata {
flex: 1;
max-width: 100%;
}
</style>
@@ -1,5 +1,5 @@
<template>
<div class="medium-12 columns">
<div class="w-full">
<textarea
v-model="processedString"
rows="4"
@@ -119,55 +119,40 @@ export default {
<style scoped lang="scss">
.template__variables-container {
padding: var(--space-one);
@apply p-2.5;
}
.variables-label {
font-size: var(--font-size-small);
font-weight: var(--font-weight-bold);
margin-bottom: var(--space-one);
@apply text-sm font-semibold mb-2.5;
}
.template__variable-item {
align-items: center;
display: flex;
margin-bottom: var(--space-one);
@apply items-center flex mb-2.5;
.label {
font-size: var(--font-size-mini);
@apply text-xs;
}
.variable-input {
flex: 1;
font-size: var(--font-size-small);
margin-left: var(--space-one);
@apply flex-1 text-sm ml-2.5;
}
.variable-label {
background-color: var(--s-75);
border-radius: var(--border-radius-normal);
display: inline-block;
font-size: var(--font-size-mini);
padding: var(--space-one) var(--space-medium);
@apply bg-slate-75 dark:bg-slate-700 text-slate-700 dark:text-slate-100 inline-block rounded-md text-xs py-2.5 px-6;
}
}
footer {
display: flex;
justify-content: flex-end;
@apply flex justify-end;
button {
margin-left: var(--space-one);
@apply ml-2.5;
}
}
.error {
background-color: var(--r-100);
border-radius: var(--border-radius-normal);
color: var(--r-800);
padding: var(--space-one);
text-align: center;
@apply bg-red-100 dark:bg-red-100 rounded-md text-red-800 dark:text-red-800 p-2.5 text-center;
}
.template-input {
background-color: var(--s-25);
@apply bg-slate-25 dark:bg-slate-900 text-slate-700 dark:text-slate-100;
}
</style>
@@ -1,5 +1,5 @@
<template>
<div class="medium-12 columns">
<div class="w-full">
<div class="templates__list-search">
<fluent-icon icon="search" class="search-icon" size="16" />
<input
@@ -96,61 +96,35 @@ export default {
<style scoped lang="scss">
.flex-between {
display: flex;
justify-content: space-between;
margin-bottom: var(--space-one);
@apply flex justify-between mb-2.5;
}
.templates__list-search {
align-items: center;
background-color: var(--s-25);
border-radius: var(--border-radius-medium);
border: 1px solid var(--s-100);
display: flex;
margin-bottom: var(--space-one);
padding: 0 var(--space-one);
@apply items-center flex bg-slate-25 dark:bg-slate-900 mb-2.5 py-0 px-2.5 rounded-md border border-solid border-slate-100 dark:border-slate-700;
.search-icon {
color: var(--s-400);
@apply text-slate-400 dark:text-slate-300;
}
.templates__search-input {
background-color: transparent;
border: var(--space-large);
font-size: var(--font-size-mini);
height: unset;
margin: var(--space-zero);
@apply bg-transparent border-0 text-xs h-auto m-0;
}
}
.template__list-container {
background-color: var(--s-25);
border-radius: var(--border-radius-medium);
max-height: 18.75rem;
overflow-y: auto;
padding: var(--space-one);
@apply bg-slate-25 dark:bg-slate-900 rounded-md max-h-[18.75rem] overflow-y-auto p-2.5;
.template__list-item {
border-radius: var(--border-radius-medium);
cursor: pointer;
display: block;
padding: var(--space-one);
text-align: left;
width: 100%;
&:hover {
background-color: var(--w-50);
}
@apply rounded-lg cursor-pointer block p-2.5 text-left w-full hover:bg-woot-50 dark:hover:bg-slate-600;
.label-title {
font-size: var(--font-size-small);
@apply text-sm;
}
.label-category {
margin-top: var(--space-two);
@apply mt-5;
span {
font-size: var(--font-size-small);
font-weight: var(--font-weight-bold);
@apply text-sm font-semibold;
}
}
@@ -161,13 +135,10 @@ export default {
}
.strong {
font-size: var(--font-size-mini);
font-weight: var(--font-weight-bold);
@apply text-xs font-semibold;
}
hr {
border-bottom: 1px solid var(--s-100);
margin: var(--space-one) auto;
max-width: 95%;
@apply border-b border-solid border-slate-100 dark:border-slate-700 my-2.5 mx-auto max-w-[95%];
}
</style>
@@ -256,25 +256,25 @@ export default {
<style lang="scss" scoped>
.right {
.message-text--metadata {
align-items: center;
@apply items-center;
.time {
color: var(--w-100);
@apply text-woot-100 dark:text-woot-100;
}
.action--icon {
color: var(--white);
@apply text-white dark:text-white;
&.read-tick {
color: var(--v-100);
@apply text-violet-100 dark:text-violet-100;
}
&.read-indicator {
color: var(--g-200);
@apply text-green-200 dark:text-green-200;
}
}
.lock--icon--private {
color: var(--s-400);
@apply text-slate-400 dark:text-slate-400;
}
}
}
@@ -282,41 +282,31 @@ export default {
.left {
.message-text--metadata {
.time {
color: var(--s-400);
@apply text-slate-400 dark:text-slate-200;
}
}
}
.message-text--metadata {
align-items: flex-start;
display: flex;
@apply items-start flex;
.time {
margin-right: var(--space-small);
display: block;
font-size: var(--font-size-micro);
line-height: 1.8;
@apply mr-2 block text-xxs leading-[1.8];
}
.action--icon {
margin-right: var(--space-small);
margin-left: var(--space-small);
color: var(--s-900);
@apply mr-2 ml-2 text-slate-900 dark:text-slate-100;
}
a {
color: var(--s-900);
@apply text-slate-900 dark:text-slate-100;
}
}
.activity-wrap {
.message-text--metadata {
.time {
color: var(--s-300);
display: flex;
text-align: center;
font-size: var(--font-size-micro);
margin-left: 0;
@apply ml-2 rtl:mr-2 rtl:ml-0 flex text-center text-xxs text-slate-300 dark:text-slate-200;
}
}
}
@@ -325,35 +315,28 @@ export default {
.is-video {
.message-text--metadata {
.time {
bottom: var(--space-smaller);
color: var(--white);
position: absolute;
right: var(--space-small);
white-space: nowrap;
@apply bottom-1 text-white dark:text-slate-50 absolute right-2 whitespace-nowrap;
&.has-status-icon {
right: var(--space-large);
line-height: 2;
@apply right-8 leading-loose;
}
}
.read-tick {
position: absolute;
bottom: var(--space-small);
right: var(--space-small);
@apply absolute bottom-2 right-2;
}
}
}
.is-private {
.message-text--metadata {
align-items: center;
@apply items-center;
.time {
color: var(--s-400);
@apply text-slate-400 dark:text-slate-400;
}
.icon {
color: var(--s-400);
@apply text-slate-400 dark:text-slate-400;
}
}
@@ -361,18 +344,16 @@ export default {
&.is-video {
.time {
position: inherit;
padding-left: var(--space-one);
@apply pl-2.5;
}
}
}
.delivered-icon {
margin-left: -var(--space-normal);
@apply ml-4;
}
.read-indicator-wrap {
line-height: 1;
display: flex;
align-items: center;
@apply leading-none flex items-center;
}
</style>
@@ -2,7 +2,9 @@
<div class="contact--group">
<fluent-icon icon="call" class="file--icon" size="18" />
<div class="meta">
<p class="text-truncate margin-bottom-0">
<p
class="overflow-hidden whitespace-nowrap text-ellipsis margin-bottom-0"
>
{{ phoneNumber }}
</p>
</div>
@@ -4,7 +4,9 @@
<fluent-icon icon="location" class="file--icon" size="32" />
</div>
<div class="meta">
<h5 class="text-block-title text-truncate">
<h5
class="text-block-title overflow-hidden whitespace-nowrap text-ellipsis"
>
{{ name }}
</h5>
<div class="link-wrap">
@@ -47,32 +49,22 @@ export default {
<style lang="scss" scoped>
.location {
display: flex;
flex-direction: row;
padding: var(--space-smaller) 0;
cursor: pointer;
@apply flex flex-row py-1 px-0 cursor-pointer;
.icon-wrap {
color: var(--s-600);
line-height: 1;
margin: 0 var(--space-smaller);
@apply text-slate-600 dark:text-slate-200 leading-none my-0 mx-1;
}
.text-block-title {
margin: 0;
color: var(--s-800);
word-break: break-word;
@apply m-0 text-slate-800 dark:text-slate-100 break-words;
}
.meta {
display: flex;
flex-direction: column;
align-items: flex-start;
padding-right: var(--space-normal);
@apply flex flex-col items-center pr-4;
}
.link-wrap {
display: flex;
@apply flex;
}
}
</style>
@@ -5,26 +5,49 @@
:show-close-button="false"
:on-close="onClose"
>
<div v-on-clickaway="onClose" class="gallery-modal--wrap" @click="onClose">
<div class="gallery-modal--header">
<div class="header-info--wrap" @click.stop>
<div
v-on-clickaway="onClose"
class="bg-white dark:bg-slate-900 flex flex-col h-[inherit] w-[inherit]"
@click="onClose"
>
<div class="items-center flex h-16 justify-between py-2 px-6 w-full">
<div class="items-center flex justify-start min-w-[15rem]" @click.stop>
<thumbnail
:username="senderDetails.name"
:src="senderDetails.avatar"
/>
<div class="header-info">
<h3 class="sub-block-title sender-name">
<span class="text-truncate">{{ senderDetails.name }}</span>
<div
class="flex items-start flex-col justify-center ml-2 rtl:ml-0 rtl:mr-2"
>
<h3
class="sub-block-title inline-block leading-[1.4] m-0 p-0 capitalize"
>
<span
class="text-slate-800 dark:text-slate-100 overflow-hidden whitespace-nowrap text-ellipsis"
>
{{ senderDetails.name }}
</span>
</h3>
<span class="time-stamp text-truncate">{{ readableTime }}</span>
<span
class="text-xs m-0 p-0 text-slate-400 dark:text-slate-200 overflow-hidden whitespace-nowrap text-ellipsis"
>
{{ readableTime }}
</span>
</div>
</div>
<div class="file-name--header text-block-title">
<span class="text-truncate">
<div
class="items-center text-slate-700 dark:text-slate-100 flex font-semibold justify-start min-w-0 p-1 w-auto text-block-title"
>
<span
class="text-slate-700 dark:text-slate-100 overflow-hidden whitespace-nowrap text-ellipsis"
>
{{ fileNameFromDataUrl }}
</span>
</div>
<div class="header-actions" @click.stop>
<div
class="items-center flex gap-2 justify-end min-w-[15rem]"
@click.stop
>
<woot-button
size="large"
color-scheme="secondary"
@@ -41,8 +64,8 @@
/>
</div>
</div>
<div class="gallery-modal--body">
<div class="attachment-toggle--button">
<div class="items-center flex h-full justify-center w-full">
<div class="flex justify-center min-w-[6.25rem] w-[6.25rem]">
<woot-button
v-if="hasMoreThanOneAttachment"
size="large"
@@ -58,13 +81,13 @@
"
/>
</div>
<div class="attachments-viewer">
<div class="attachment-view">
<div class="flex items-center flex-col justify-center w-full h-full">
<div>
<img
v-if="isImage"
:key="activeAttachment.message_id"
:src="activeAttachment.data_url"
class="modal-image skip-context-menu"
class="modal-image skip-context-menu my-0 mx-auto"
@click.stop
/>
<video
@@ -73,7 +96,7 @@
:src="activeAttachment.data_url"
controls
playsInline
class="modal-video skip-context-menu"
class="modal-video skip-context-menu my-0 mx-auto"
@click.stop
/>
<audio
@@ -87,7 +110,7 @@
</audio>
</div>
</div>
<div class="attachment-toggle--button">
<div class="flex justify-center min-w-[6.25rem] w-[6.25rem]">
<woot-button
v-if="hasMoreThanOneAttachment"
size="large"
@@ -104,8 +127,10 @@
/>
</div>
</div>
<div class="gallery-modal--footer">
<div class="header-count text-block-title">
<div class="items-center flex h-16 justify-center w-full py-2 px-6">
<div
class="items-center rounded-sm flex font-semibold justify-center min-w-[5rem] p-1 bg-slate-25 dark:bg-slate-800 text-slate-600 dark:text-slate-200 text-block-title"
>
<span class="count">
{{ `${activeImageIndex + 1} / ${allAttachments.length}` }}
</span>
@@ -252,123 +277,3 @@ export default {
},
};
</script>
<style lang="scss" scoped>
.gallery-modal--wrap {
display: flex;
flex-direction: column;
height: inherit;
width: inherit;
.gallery-modal--header {
align-items: center;
display: flex;
height: var(--space-jumbo);
justify-content: space-between;
padding: var(--space-small) var(--space-medium);
width: 100%;
.header-info--wrap {
align-items: center;
display: flex;
justify-content: flex-start;
min-width: var(--space-giga);
.header-info {
align-items: flex-start;
display: flex;
flex-direction: column;
justify-content: center;
margin-left: var(--space-small);
.sender-name {
display: inline-block;
line-height: 1.4;
margin: 0;
padding: 0;
text-transform: capitalize;
}
.time-stamp {
color: var(--s-400);
font-size: var(--font-size-mini);
margin: 0;
padding: 0;
}
}
}
.file-name--header {
align-items: center;
color: var(--s-700);
display: flex;
font-weight: var(--font-weight-bold);
justify-content: flex-start;
min-width: 0;
padding: var(--space-smaller);
width: auto;
}
.header-actions {
align-items: center;
display: flex;
gap: var(--space-small);
justify-content: flex-end;
min-width: var(--space-giga);
}
}
.gallery-modal--body {
align-items: center;
display: flex;
height: 100%;
justify-content: center;
width: 100%;
}
.gallery-modal--footer {
align-items: center;
display: flex;
height: var(--space-jumbo);
justify-content: center;
padding: var(--space-small) var(--space-medium);
width: 100%;
.header-count {
align-items: center;
border-radius: var(--border-radius-small);
background-color: var(--s-25);
color: var(--s-600);
display: flex;
font-weight: var(--font-weight-bold);
justify-content: center;
min-width: 5rem;
padding: var(--space-smaller);
}
}
.attachments-viewer {
display: flex;
flex-direction: column;
height: 100%;
justify-content: center;
width: 100%;
.attachment-view {
img {
margin: 0 auto;
}
video {
margin: 0 auto;
}
}
}
.attachment-toggle--button {
display: flex;
justify-content: center;
min-width: var(--space-mega);
width: var(--space-mega);
}
}
</style>
@@ -1,5 +1,5 @@
<template>
<div class="menu-container">
<div class="bg-white dark:bg-slate-700 shadow-xl rounded-md p-1">
<menu-item
v-if="!hasUnreadMessages"
:option="unreadOption"
@@ -243,12 +243,3 @@ export default {
},
};
</script>
<style lang="scss" scoped>
.menu-container {
padding: var(--space-smaller);
background-color: var(--white);
box-shadow: var(--shadow-context-menu);
border-radius: var(--border-radius-normal);
}
</style>
@@ -19,7 +19,9 @@
size="20px"
class="agent-thumbnail"
/>
<p class="menu-label text-truncate">{{ option.label }}</p>
<p class="menu-label overflow-hidden whitespace-nowrap text-ellipsis">
{{ option.label }}
</p>
</div>
</template>
@@ -44,22 +46,14 @@ export default {
<style scoped lang="scss">
.menu {
display: flex;
align-items: center;
flex-wrap: nowrap;
width: calc(var(--space-mega) * 2);
padding: var(--space-smaller);
border-radius: var(--border-radius-small);
overflow: hidden;
@apply flex items-center flex-nowrap p-1 rounded-sm overflow-hidden cursor-pointer;
.menu-label {
margin: 0 var(--space-small);
font-size: var(--font-size-mini);
flex-shrink: 0;
@apply my-0 mx-2 text-xs flex-shrink-0;
}
&:hover {
background-color: var(--w-500);
color: var(--white);
@apply bg-woot-500 dark:bg-woot-500 text-white dark:text-slate-50;
}
}
@@ -68,10 +62,6 @@ export default {
}
.label-pill {
width: var(--space-normal);
height: var(--space-normal);
border-radius: var(--border-radius-rounded);
border: 1px solid var(--s-50);
flex-shrink: 0;
@apply w-4 h-4 rounded-full border border-slate-50 border-solid dark:border-slate-900 flex-shrink-0;
}
</style>
@@ -1,14 +1,17 @@
<template>
<div
class="menu-with-submenu flex-between"
:class="{ disabled: !subMenuAvailable }"
class="menu-with-submenu min-width-calc w-full p-1 flex items-center h-7 rounded-md relative bg-white dark:bg-slate-700 justify-between hover:bg-woot-75 cursor-pointer dark:hover:bg-slate-800"
:class="!subMenuAvailable ? 'opacity-50 cursor-not-allowed' : ''"
>
<div class="menu-left">
<div class="flex items-center">
<fluent-icon :icon="option.icon" size="14" class="menu-icon" />
<p class="menu-label">{{ option.label }}</p>
<p class="my-0 mx-2 text-xs">{{ option.label }}</p>
</div>
<fluent-icon icon="chevron-right" size="12" />
<div v-if="subMenuAvailable" class="submenu">
<div
v-if="subMenuAvailable"
class="submenu bg-white dark:bg-slate-700 p-1 shadow-lg rounded-md absolute left-full top-0 hidden min-h-min max-h-[15rem] overflow-y-auto overflow-x-hidden cursor-pointer"
>
<slot />
</div>
</div>
@@ -31,61 +34,12 @@ export default {
<style scoped lang="scss">
.menu-with-submenu {
width: 100%;
padding: var(--space-smaller);
border-radius: var(--border-radius-small);
position: relative;
min-width: calc(var(--space-mega) * 2);
background-color: var(--white);
.menu-left {
display: flex;
align-items: center;
.menu-label {
margin: 0 var(--space-small);
font-size: var(--font-size-mini);
}
}
.submenu {
padding: var(--space-smaller);
background-color: var(--white);
box-shadow: var(--shadow-context-menu);
border-radius: var(--border-radius-normal);
position: absolute;
position: absolute;
left: 100%;
top: 0;
display: none;
min-height: min-content;
max-height: var(--space-giga);
overflow-y: auto;
// Need this because Firefox adds a horizontal scrollbar, if a text is truncated inside.
overflow-x: hidden;
}
min-width: calc(6.25rem * 2);
&:hover {
background-color: var(--w-75);
.submenu {
display: block;
@apply block;
}
&:before {
content: '';
position: absolute;
z-index: var(--z-index-highest);
bottom: -65%;
height: 75%;
right: 0%;
width: 50%;
clip-path: polygon(100% 0, 0% 0%, 100% 100%);
}
}
&.disabled {
opacity: 0.5;
cursor: not-allowed;
}
}
</style>
@@ -2,13 +2,7 @@
<div v-on-clickaway="onCloseAgentList" class="bulk-action__agents">
<div class="triangle">
<svg height="12" viewBox="0 0 24 12" width="24">
<path
d="M20 12l-8-8-12 12"
fill="var(--white)"
fill-rule="evenodd"
stroke="var(--s-50)"
stroke-width="1px"
/>
<path d="M20 12l-8-8-12 12" fill-rule="evenodd" stroke-width="1px" />
</svg>
</div>
<div class="header flex-between">
@@ -190,110 +184,73 @@ export default {
<style scoped lang="scss">
.bulk-action__agents {
background-color: var(--white);
border-radius: var(--border-radius-large);
border: 1px solid var(--s-50);
box-shadow: var(--shadow-dropdown-pane);
max-width: 75%;
position: absolute;
right: var(--space-small);
top: var(--space-larger);
transform-origin: top right;
width: auto;
z-index: var(--z-index-twenty);
min-width: var(--space-giga);
@apply max-w-[75%] absolute right-2 top-12 origin-top-right w-auto z-20 min-w-[15rem] bg-white dark:bg-slate-800 rounded-lg border border-solid border-slate-50 dark:border-slate-700 shadow-md;
.header {
padding: var(--space-one);
@apply p-2.5;
span {
font-size: var(--font-size-small);
font-weight: var(--font-weight-medium);
@apply text-sm font-medium;
}
}
.container {
max-height: var(--space-giga);
overflow-y: auto;
@apply overflow-y-auto max-h-[15rem];
.agent__list-container {
height: 100%;
@apply h-full;
}
.agent-list-search {
padding: 0 var(--space-one);
border: 1px solid var(--s-100);
border-radius: var(--border-radius-medium);
background-color: var(--s-50);
@apply py-0 px-2.5 bg-slate-50 dark:bg-slate-900 border border-solid border-slate-100 dark:border-slate-600/70 rounded-md;
.search-icon {
color: var(--s-400);
@apply text-slate-400 dark:text-slate-200;
}
.agent--search_input {
border: 0;
font-size: var(--font-size-mini);
margin: 0;
background-color: transparent;
height: unset;
@apply border-0 text-xs m-0 dark:bg-transparent bg-transparent h-[unset];
}
}
}
.triangle {
display: block;
z-index: var(--z-index-one);
position: absolute;
top: var(--space-minus-slab);
right: var(--triangle-position);
text-align: left;
@apply block z-10 absolute -top-3 text-left;
svg path {
@apply fill-white dark:fill-slate-800 stroke-slate-50 dark:stroke-slate-600/50;
}
}
}
ul {
margin: 0;
list-style: none;
@apply m-0 list-none;
li {
&:last-child {
.agent-list-item {
@apply last:rounded-b-lg;
}
}
}
}
.agent-list-item {
display: flex;
align-items: center;
padding: var(--space-one);
cursor: pointer;
&:hover {
background-color: var(--s-50);
}
@apply flex items-center p-2.5 cursor-pointer hover:bg-slate-50 dark:hover:bg-slate-900;
span {
font-size: var(--font-size-small);
@apply text-sm;
}
}
.agent-confirmation-container {
display: flex;
flex-direction: column;
height: 100%;
padding: var(--space-one);
@apply flex flex-col h-full p-2.5;
p {
flex-grow: 1;
@apply flex-grow;
}
.agent-confirmation-actions {
width: 100%;
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: var(--space-one);
@apply w-full grid grid-cols-2 gap-2.5;
}
}
.search-container {
padding: 0 var(--space-one);
position: sticky;
top: 0;
z-index: var(--z-index-twenty);
background-color: var(--white);
@apply py-0 px-2.5 sticky top-0 z-20 bg-white dark:bg-slate-800;
}
.agent__list-loading {
height: calc(95% - var(--space-one));
margin: var(--space-one);
border-radius: var(--border-radius-medium);
background-color: var(--s-50);
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: var(--space-two);
@apply m-2.5 rounded-md bg-slate-25 dark:bg-slate-900 flex items-center justify-center flex-col p-5 h-[calc(95%-6.25rem)];
}
</style>
@@ -194,33 +194,23 @@ export default {
}
.bulk-action__container {
border-bottom: 1px solid var(--s-100);
padding: var(--space-normal);
position: relative;
@apply p-4 relative border-b border-solid border-slate-100 dark:border-slate-600/70;
}
.bulk-action__panel {
cursor: pointer;
@apply cursor-pointer;
span {
font-size: var(--font-size-mini);
margin: 0 var(--space-smaller);
@apply text-xs my-0 mx-1;
}
input[type='checkbox'] {
cursor: pointer;
margin: var(--space-zero);
@apply cursor-pointer m-0;
}
}
.bulk-action__alert {
background-color: var(--y-50);
border-radius: var(--border-radius-small);
border: 1px solid var(--y-300);
color: var(--y-700);
font-size: var(--font-size-mini);
margin-top: var(--space-small);
padding: var(--space-smaller) var(--space-small);
@apply bg-yellow-50 text-yellow-700 rounded text-xs mt-2 py-1 px-2 border border-solid border-yellow-300 dark:border-yellow-300/10 dark:bg-yellow-200/20 dark:text-yellow-400;
}
.popover-animation-enter-active,
@@ -229,23 +219,23 @@ export default {
}
.popover-animation-enter {
opacity: 0;
transform: scale(0.95);
@apply opacity-0;
}
.popover-animation-enter-to {
opacity: 1;
transform: scale(1);
@apply opacity-100;
}
.popover-animation-leave {
opacity: 1;
transform: scale(1);
@apply opacity-100;
}
.popover-animation-leave-to {
opacity: 0;
transform: scale(0.95);
@apply opacity-0;
}
.label-actions-box {
@@ -2,13 +2,7 @@
<div v-on-clickaway="onClose" class="labels-container">
<div class="triangle">
<svg height="12" viewBox="0 0 24 12" width="24">
<path
d="M20 12l-8-8-12 12"
fill="var(--white)"
fill-rule="evenodd"
stroke="var(--s-50)"
stroke-width="1px"
/>
<path d="M20 12l-8-8-12 12" fill-rule="evenodd" stroke-width="1px" />
</svg>
</div>
<div class="header flex-between">
@@ -50,7 +44,11 @@
:value="label.title"
class="label-checkbox"
/>
<span class="label-title text-truncate">{{ label.title }}</span>
<span
class="label-title overflow-hidden whitespace-nowrap text-ellipsis"
>
{{ label.title }}
</span>
<span
class="label-pill"
:style="{ backgroundColor: label.color }"
@@ -61,6 +59,7 @@
<footer class="labels-list__footer">
<woot-button
size="small"
is-expanded
color-scheme="primary"
:disabled="!selectedLabels.length"
@click="$emit('assign', selectedLabels)"
@@ -108,178 +107,115 @@ export default {
<style scoped lang="scss">
.labels-list {
display: flex;
flex-direction: column;
max-height: var(--space-giga);
min-height: auto;
@apply flex flex-col max-h-[15rem] min-h-[auto];
.labels-list__header {
background-color: var(--white);
padding: 0 var(--space-one);
@apply bg-white dark:bg-slate-800 py-0 px-2.5;
}
.labels-list__body {
flex: 1;
overflow-y: auto;
padding: var(--space-one) 0;
@apply flex-1 overflow-y-auto py-2.5 mx-0;
}
.labels-list__footer {
padding: var(--space-small);
@apply p-2;
button {
width: 100%;
@apply w-full;
.button__content {
@apply text-center;
}
}
}
}
.label-list-search {
background-color: var(--s-50);
border-radius: var(--border-radius-medium);
border: 1px solid var(--s-100);
padding: 0 var(--space-one);
@apply bg-slate-50 dark:bg-slate-900 py-0 px-2.5 border border-solid border-slate-100 dark:border-slate-600/70 rounded-md;
.search-icon {
color: var(--s-400);
@apply text-slate-400 dark:text-slate-200;
}
.label--search_input {
background-color: transparent;
border: 0;
font-size: var(--font-size-mini);
height: unset;
margin: 0;
@apply border-0 text-xs m-0 dark:bg-transparent bg-transparent h-[unset];
}
}
.labels-container {
background-color: var(--white);
border-radius: var(--border-radius-large);
border: 1px solid var(--s-50);
box-shadow: var(--shadow-dropdown-pane);
max-width: var(--space-giga);
min-width: var(--space-giga);
position: absolute;
right: var(--space-small);
top: var(--space-larger);
transform-origin: top right;
width: auto;
z-index: var(--z-index-twenty);
@apply absolute right-2 top-12 origin-top-right w-auto z-20 max-w-[15rem] min-w-[15rem] bg-white dark:bg-slate-800 rounded-lg border border-solid border-slate-50 dark:border-slate-700 shadow-md;
.header {
padding: var(--space-one);
@apply p-2.5;
span {
font-size: var(--font-size-small);
font-weight: var(--font-weight-medium);
@apply text-sm font-medium;
}
}
.container {
max-height: var(--space-giga);
overflow-y: auto;
@apply max-h-[15rem] overflow-y-auto;
.label__list-container {
height: 100%;
}
.label-list-search {
padding: 0 var(--space-one);
border: 1px solid var(--s-100);
border-radius: var(--border-radius-medium);
background-color: var(--s-50);
.search-icon {
color: var(--s-400);
}
.label--search_input {
border: 0;
font-size: var(--font-size-mini);
margin: 0;
background-color: transparent;
height: unset;
}
@apply h-full;
}
}
.triangle {
display: block;
position: absolute;
right: var(--triangle-position);
text-align: left;
top: var(--space-minus-slab);
z-index: var(--z-index-one);
@apply block z-10 absolute text-left -top-3;
svg path {
@apply fill-white dark:fill-slate-800 stroke-slate-50 dark:stroke-slate-600/50;
}
}
}
ul {
margin: 0;
list-style: none;
@apply m-0 list-none;
}
.labels-placeholder {
padding: var(--space-small);
@apply p-2;
}
.label__list-item {
margin: var(--space-smaller) 0;
padding: 0 var(--space-one);
@apply my-1 mx-0 py-0 px-2.5;
.item {
align-items: center;
border-radius: var(--border-radius-medium);
cursor: pointer;
display: flex;
padding: var(--space-smaller) var(--space-one);
&:hover {
background-color: var(--s-50);
}
@apply items-center rounded-md cursor-pointer flex py-1 px-2.5 hover:bg-slate-50 dark:hover:bg-slate-900;
&.label-selected {
background-color: var(--s-50);
@apply bg-slate-50 dark:bg-slate-900;
}
span {
font-size: var(--font-size-small);
@apply text-sm;
}
.label-checkbox {
margin: 0 var(--space-one) 0 0;
@apply my-0 mr-2.5 ml-0;
}
.label-title {
flex-grow: 1;
width: 100%;
@apply flex-grow w-full;
}
.label-pill {
background-color: var(--s-50);
border-radius: var(--border-radius-medium);
height: var(--space-slab);
width: var(--space-slab);
flex-shrink: 0;
border: 1px solid var(--color-border-light);
@apply bg-slate-50 rounded-md h-3 w-3 flex-shrink-0 border border-solid border-slate-50 dark:border-slate-900;
}
}
}
.search-container {
background-color: var(--white);
padding: 0 var(--space-one);
position: sticky;
top: 0;
z-index: var(--z-index-twenty);
@apply bg-white py-0 px-2.5 sticky top-0 z-20;
}
.actions-container {
background-color: var(--white);
bottom: 0;
padding: var(--space-small);
position: sticky;
z-index: var(--z-index-twenty);
@apply bg-white dark:bg-slate-900 bottom-0 p-2 sticky z-20;
button {
width: 100%;
@apply w-full;
}
}
</style>
@@ -2,13 +2,7 @@
<div v-on-clickaway="onClose" class="bulk-action__teams">
<div class="triangle">
<svg height="12" viewBox="0 0 24 12" width="24">
<path
d="M20 12l-8-8-12 12"
fill="var(--white)"
fill-rule="evenodd"
stroke="var(--s-50)"
stroke-width="1px"
/>
<path d="M20 12l-8-8-12 12" fill-rule="evenodd" stroke-width="1px" />
</svg>
</div>
<div class="header flex-between">
@@ -91,83 +85,60 @@ export default {
<style scoped lang="scss">
.bulk-action__teams {
background-color: var(--white);
border-radius: var(--border-radius-large);
border: 1px solid var(--s-50);
box-shadow: var(--shadow-dropdown-pane);
max-width: 75%;
position: absolute;
right: var(--space-small);
top: var(--space-larger);
transform-origin: top right;
width: auto;
z-index: var(--z-index-twenty);
min-width: var(--space-giga);
@apply max-w-[75%] absolute right-2 top-12 origin-top-right w-auto z-20 min-w-[15rem] bg-white dark:bg-slate-800 rounded-lg border border-solid border-slate-50 dark:border-slate-700 shadow-md;
.header {
padding: var(--space-one);
@apply p-2.5;
span {
font-size: var(--font-size-small);
font-weight: var(--font-weight-medium);
@apply text-sm font-medium;
}
}
.container {
max-height: var(--space-giga);
overflow-y: auto;
@apply overflow-y-auto max-h-[15rem];
.team__list-container {
height: 100%;
@apply h-full;
}
.agent-list-search {
padding: 0 var(--space-one);
border: 1px solid var(--s-100);
border-radius: var(--border-radius-medium);
background-color: var(--s-50);
@apply py-0 px-2.5 bg-slate-50 dark:bg-slate-900 border border-solid border-slate-100 dark:border-slate-600/70 rounded-md;
.search-icon {
color: var(--s-400);
@apply text-slate-400 dark:text-slate-200;
}
.agent--search_input {
border: 0;
font-size: var(--font-size-mini);
margin: 0;
background-color: transparent;
height: unset;
@apply border-0 text-xs m-0 dark:bg-transparent bg-transparent h-[unset];
}
}
}
.triangle {
display: block;
z-index: var(--z-index-one);
position: absolute;
top: var(--space-minus-slab);
right: var(--triangle-position);
text-align: left;
@apply block z-10 absolute text-left -top-3;
svg path {
@apply fill-white dark:fill-slate-800 stroke-slate-50 dark:stroke-slate-600/50;
}
}
}
ul {
margin: 0;
list-style: none;
@apply m-0 list-none;
li {
&:last-child {
.agent-list-item {
@apply last:rounded-b-lg;
}
}
}
}
.team__list-item {
display: flex;
align-items: center;
padding: var(--space-one);
cursor: pointer;
&:hover {
background-color: var(--s-50);
}
@apply flex items-center p-2.5 cursor-pointer hover:bg-slate-50 dark:hover:bg-slate-900;
span {
font-size: var(--font-size-small);
@apply text-sm;
}
}
.search-container {
padding: 0 var(--space-one);
position: sticky;
top: 0;
z-index: var(--z-index-twenty);
background-color: var(--white);
@apply py-0 px-2.5 sticky top-0 z-20 bg-white dark:bg-slate-800;
}
</style>
@@ -2,13 +2,7 @@
<div v-on-clickaway="onClose" class="actions-container">
<div class="triangle">
<svg height="12" viewBox="0 0 24 12" width="24">
<path
d="M20 12l-8-8-12 12"
fill="var(--white)"
fill-rule="evenodd"
stroke="var(--s-50)"
stroke-width="1px"
/>
<path d="M20 12l-8-8-12 12" fill-rule="evenodd" stroke-width="1px" />
</svg>
</div>
<div class="header flex-between">
@@ -126,42 +120,30 @@ export default {
<style scoped lang="scss">
.actions-container {
background-color: var(--white);
border-radius: var(--border-radius-large);
border: 1px solid var(--s-50);
box-shadow: var(--shadow-dropdown-pane);
position: absolute;
right: var(--space-small);
top: var(--space-larger);
transform-origin: top right;
width: auto;
z-index: var(--z-index-twenty);
@apply absolute right-2 top-12 origin-top-right w-auto z-20 bg-white dark:bg-slate-800 rounded-lg border border-solid border-slate-50 dark:border-slate-700 shadow-md;
.header {
padding: var(--space-one);
@apply p-2.5;
span {
font-size: var(--font-size-small);
font-weight: var(--font-weight-medium);
@apply text-sm font-medium;
}
}
.container {
padding: var(--space-one);
padding-top: var(--space-zero);
@apply px-2.5 pt-0 pb-2.5;
}
.triangle {
display: block;
position: absolute;
right: var(--triangle-position);
text-align: left;
top: var(--space-minus-slab);
z-index: var(--z-index-one);
@apply block z-10 absolute text-left -top-3;
svg path {
@apply fill-white dark:fill-slate-800 stroke-slate-50 dark:stroke-slate-600/50;
}
}
}
ul {
margin: 0;
list-style: none;
@apply m-0 list-none;
}
</style>
@@ -2,9 +2,12 @@
<div
v-show="activeLabels.length"
ref="labelContainer"
class="label-container"
class="label-container mt-0.5 mx-2 mb-0"
>
<div class="labels-wrap" :class="{ expand: showAllLabels }">
<div
class="labels-wrap flex items-end min-w-0 flex-shrink"
:class="{ expand: showAllLabels }"
>
<woot-label
v-for="(label, index) in activeLabels"
:key="label.id"
@@ -22,7 +25,7 @@
? $t('CONVERSATION.CARD.HIDE_LABELS')
: $t('CONVERSATION.CARD.SHOW_LABELS')
"
class="show-more--button"
class="show-more--button sticky flex-shrink-0 right-0 mr-6 rtl:rotate-180"
color-scheme="secondary"
variant="hollow"
:icon="showAllLabels ? 'chevron-left' : 'chevron-right'"
@@ -84,53 +87,35 @@ export default {
<style lang="scss" scoped>
.show-more--button {
height: var(--space-two);
position: sticky;
flex-shrink: 0;
right: 0;
margin-right: var(--space-medium);
@apply h-5;
&.secondary:focus {
color: var(--s-700);
border-color: var(--s-300);
@apply text-slate-700 dark:text-slate-200 border-slate-300 dark:border-slate-700;
}
}
.label-container {
margin: var(--space-micro) var(--space-small) 0;
}
.labels-wrap {
display: flex;
align-items: center;
min-width: 0;
flex-shrink: 1;
&.expand {
height: auto;
overflow: visible;
flex-flow: row wrap;
@apply h-auto overflow-visible flex-row flex-wrap;
.label {
margin-bottom: var(--space-smaller);
@apply mb-1;
}
.show-more--button {
margin-bottom: var(--space-smaller);
@apply mb-1;
}
}
.secondary {
border: 1px solid var(--s-100);
@apply border border-solid border-slate-100 dark:border-slate-700;
}
.label {
margin-bottom: 0;
@apply mb-0;
}
}
.hidden {
visibility: hidden;
position: absolute;
@apply invisible absolute;
}
</style>
@@ -2,6 +2,8 @@
<label class="input-container">
<span v-if="label">{{ label }}</span>
<input
class="bg-white dark:bg-slate-900 text-slate-900 dark:text-slate-100 border-slate-200 dark:border-slate-600"
:class="{ 'input-margin': error }"
:value="value"
:type="type"
:placeholder="placeholder"
@@ -65,10 +67,11 @@ export default {
</script>
<style scoped lang="scss">
.help-text {
margin-top: var(--space-micro);
font-size: var(--font-size-mini);
color: var(--s-600);
font-style: normal;
@apply mt-0.5 text-xs not-italic text-slate-600 dark:text-slate-400;
}
.input-margin {
margin-bottom: 2px !important;
}
.message {
margin-top: 0 !important;
@@ -1,12 +1,20 @@
<template>
<div class="phone-input--wrap">
<div class="phone-input--wrap relative">
<div class="phone-input" :class="{ 'has-error': error }">
<div class="country-emoji--wrap" @click="toggleCountryDropdown">
<h5 v-if="activeCountry.emoji">{{ activeCountry.emoji }}</h5>
<div
class="cursor-pointer py-2 pr-1 pl-2 rounded-tl-md rounded-bl-md flex items-center justify-center gap-2 bg-slate-25 dark:bg-slate-700 h-10 w-[3.25rem]"
@click="toggleCountryDropdown"
>
<h5 v-if="activeCountry.emoji" class="mb-0">
{{ activeCountry.emoji }}
</h5>
<fluent-icon v-else icon="globe" class="fluent-icon" size="16" />
<fluent-icon icon="chevron-down" class="fluent-icon" size="12" />
</div>
<span v-if="activeDialCode" class="country-dial--code">
<span
v-if="activeDialCode"
class="flex bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-normal text-base leading-normal py-2 pl-2 pr-0"
>
{{ activeDialCode }}
</span>
<input
@@ -41,15 +49,22 @@
}"
@click="onSelectCountry(country)"
>
<span class="country-emoji">{{ country.emoji }}</span>
<span class="text-base mr-1">{{ country.emoji }}</span>
<span class="country-name">
<span
class="max-w-[7.5rem] overflow-hidden text-ellipsis whitespace-nowrap"
>
{{ country.name }}
</span>
<span class="country-dial-code">{{ country.dial_code }}</span>
<span class="ml-1 text-slate-300 dark:text-slate-300 text-xs">{{
country.dial_code
}}</span>
</div>
<div v-if="filteredCountriesBySearch.length === 0">
<span class="no-results">No results found</span>
<span
class="flex items-center justify-center text-sm text-slate-500 dark:text-slate-300 mt-4"
>No results found</span
>
</div>
</div>
</div>
@@ -237,124 +252,39 @@ export default {
</script>
<style scoped lang="scss">
.phone-input--wrap {
position: relative;
.phone-input {
display: flex;
align-items: center;
justify-content: flex-start;
margin-bottom: var(--space-normal);
border: 1px solid var(--s-200);
border-radius: var(--border-radius-normal);
@apply flex items-center justify-start mb-4 rounded-md border border-solid border-slate-200 dark:border-slate-600;
&.has-error {
border: 1px solid var(--r-400);
@apply border border-solid border-red-400 dark:border-red-400;
}
}
.country-emoji--wrap {
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: var(--space-small);
background: var(--s-25);
height: 2.5rem;
width: 3.25rem;
border-radius: var(--border-radius-normal) 0 0 var(--border-radius-normal);
padding: var(--space-small) var(--space-smaller) var(--space-small)
var(--space-small);
h5 {
margin-bottom: 0;
}
}
.country-dial--code {
display: flex;
color: var(--s-300);
font-size: var(--space-normal);
font-weight: normal;
line-height: 1.5;
padding: var(--space-small) 0 var(--space-small) var(--space-small);
}
.phone-input--field {
margin-bottom: 0;
border: 0;
@apply mb-0 rounded-tl-none rounded-bl-none border-0;
}
.country-dropdown {
z-index: var(--z-index-low);
position: absolute;
height: var(--space-giga);
width: 12.5rem;
overflow-y: auto;
top: 2.5rem;
border-radius: var(--border-radius-default);
padding: 0 0 var(--space-smaller) 0;
background-color: var(--white);
box-shadow: var(--shadow-context-menu);
border-radius: var(--border-radius-normal);
@apply z-10 absolute h-60 w-[12.5rem] shadow-md overflow-y-auto top-10 rounded px-0 pt-0 pb-1 bg-white dark:bg-slate-900;
.dropdown-search--wrap {
top: 0;
position: sticky;
background-color: var(--white);
padding: var(--space-smaller);
@apply top-0 sticky bg-white dark:bg-slate-900 p-1;
.dropdown-search {
height: var(--space-large);
margin-bottom: 0;
font-size: var(--font-size-small);
border: 1px solid var(--s-200) !important;
@apply h-8 mb-0 text-sm border border-solid border-slate-200 dark:border-slate-600;
}
}
.country-dropdown--item {
display: flex;
align-items: center;
height: 1.75rem;
padding: 0 var(--space-smaller);
cursor: pointer;
@apply flex items-center h-7 py-0 px-1 cursor-pointer hover:bg-slate-50 dark:hover:bg-slate-700;
&.active {
background-color: var(--s-50);
@apply bg-slate-50 dark:bg-slate-700;
}
&.focus {
background-color: var(--s-25);
@apply bg-slate-25 dark:bg-slate-800;
}
&:hover {
background-color: var(--s-50);
}
.country-emoji {
font-size: var(--font-size-default);
margin-right: var(--space-smaller);
}
.country-name {
max-width: 7.5rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.country-dial-code {
margin-left: var(--space-smaller);
color: var(--s-300);
font-size: var(--font-size-mini);
}
}
.no-results {
display: flex;
align-items: center;
justify-content: center;
color: var(--s-500);
margin-top: var(--space-normal);
}
}
}
@@ -79,41 +79,26 @@ export default {
<style scoped lang="scss">
.mention--box {
background: var(--white);
border-radius: var(--border-radius-normal);
border-top: 1px solid var(--color-border);
box-shadow: var(--shadow-medium);
left: 0;
bottom: 100%;
max-height: 9.75rem;
overflow: auto;
padding: var(--space-small) var(--space-small) 0;
position: absolute;
width: 100%;
z-index: 100;
@apply bg-white dark:bg-slate-700 rounded-md overflow-auto absolute w-full z-[100] pt-2 px-2 pb-0 shadow-md left-0 bottom-full max-h-[9.75rem] border-t border-solid border-slate-75 dark:border-slate-800;
.dropdown-menu__item:last-child {
padding-bottom: var(--space-smaller);
@apply pb-1;
}
.active {
color: var(--white);
@apply text-white dark:text-white;
&:hover {
color: var(--w-700);
@apply bg-woot-700 dark:bg-woot-700;
}
}
.button {
transition: none;
height: var(--space-large);
line-height: 1.4;
@apply transition-none h-8 leading-[1.4];
}
}
.canned-item__button::v-deep .button__content {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@apply overflow-hidden text-ellipsis whitespace-nowrap;
}
</style>
@@ -1,8 +1,8 @@
<template>
<modal :show.sync="show" :on-close="cancel">
<div class="column content-box">
<div class="h-auto overflow-auto flex flex-col">
<woot-modal-header :header-title="title" :header-content="description" />
<div class="modal-footer">
<div class="flex flex-row justify-end gap-2 py-4 px-6 w-full">
<woot-button variant="clear" @click="cancel">
{{ cancelLabel }}
</woot-button>
@@ -1,63 +1,83 @@
<template>
<woot-modal :show="show" size="medium" :on-close="() => $emit('close')">
<div class="column content-box">
<div class="h-auto overflow-auto flex flex-col">
<woot-modal-header
:header-title="$t('SIDEBAR_ITEMS.KEYBOARD_SHORTCUTS')"
/>
<div class="shortcut__wrap margin-top-3">
<div class="title-key__wrap">
<h5 class="text-block-title">
<div class="grid grid-cols-2 gap-x-5 gap-y-3 pt-0 px-8 pb-8 mt-6">
<div class="flex justify-between items-center min-w-[25rem]">
<h5 class="text-sm text-slate-800 dark:text-slate-100">
{{ $t('KEYBOARD_SHORTCUTS.TOGGLE_MODAL') }}
</h5>
<div class="shortcut-key__wrap">
<p class="shortcut-key">
<div class="flex items-center mb-1 ml-2">
<p
class="shortcut-key items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
>
{{ $t('KEYBOARD_SHORTCUTS.KEYS.WINDOWS_KEY_AND_COMMAND_KEY') }}
</p>
<p class="shortcut-key key">
<p
class="shortcut-key items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs flex justify-center min-w-[2rem] rtl:mr-0 rtl:ml-2"
>
{{ $t('KEYBOARD_SHORTCUTS.KEYS.FORWARD_SLASH_KEY') }}
</p>
</div>
</div>
</div>
<div class="shortcut__wrap">
<div class="title-key__wrap">
<h5 class="text-block-title">
<div class="grid grid-cols-2 gap-x-5 gap-y-3 pt-0 px-8 pb-8">
<div class="flex justify-between items-center min-w-[25rem]">
<h5 class="text-sm text-slate-800 dark:text-slate-100">
{{ $t('KEYBOARD_SHORTCUTS.TITLE.OPEN_CONVERSATION') }}
</h5>
<div class="shortcut-key__wrap">
<div class="open-conversation__key">
<span class="shortcut-key">
<div class="flex items-center mb-1 ml-2">
<div class="flex mr-2">
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
>
{{ $t('KEYBOARD_SHORTCUTS.KEYS.ALT_OR_OPTION_KEY') }}
</span>
<span class="shortcut-key">
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
>
J
</span>
<span class="forward-slash text-block-title">
<span
class="flex items-center font-semibold text-sm text-slate-800 dark:text-slate-100"
>
{{ $t('KEYBOARD_SHORTCUTS.KEYS.FORWARD_SLASH_KEY') }}
</span>
</div>
<span class="shortcut-key">
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
>
{{ $t('KEYBOARD_SHORTCUTS.KEYS.ALT_OR_OPTION_KEY') }}
</span>
<span class="shortcut-key key">
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs flex justify-center min-w-[2rem] rtl:mr-0 rtl:ml-2"
>
K
</span>
</div>
</div>
<div class="title-key__wrap">
<h5 class="text-block-title">
<div class="flex justify-between items-center min-w-[25rem]">
<h5 class="text-sm text-slate-800 dark:text-slate-100">
{{ $t('KEYBOARD_SHORTCUTS.TITLE.RESOLVE_AND_NEXT') }}
</h5>
<div class="shortcut-key__wrap">
<span class="shortcut-key">
<div class="flex items-center mb-1 ml-2">
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
>
{{ $t('KEYBOARD_SHORTCUTS.KEYS.WINDOWS_KEY_AND_COMMAND_KEY') }}
</span>
<span class="shortcut-key">
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
>
{{ $t('KEYBOARD_SHORTCUTS.KEYS.ALT_OR_OPTION_KEY') }}
</span>
<span class="shortcut-key key">
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs flex justify-center min-w-[2rem] rtl:mr-0 rtl:ml-2"
>
E
</span>
</div>
@@ -65,16 +85,20 @@
<div
v-for="shortcutKey in shortcutKeys"
:key="shortcutKey.id"
class="title-key__wrap"
class="flex justify-between items-center min-w-[25rem]"
>
<h5 class="text-block-title">
<h5 class="text-sm text-slate-800 dark:text-slate-100">
{{ title(shortcutKey) }}
</h5>
<div class="shortcut-key__wrap">
<span class="shortcut-key">
<div class="flex items-center mb-1 ml-2">
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
>
{{ shortcutKey.firstkey }}
</span>
<span class="shortcut-key key">
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs flex justify-center min-w-[2rem] rtl:mr-0 rtl:ml-2"
>
{{ shortcutKey.secondKey }}
</span>
</div>
@@ -108,64 +132,8 @@ export default {
},
};
</script>
<style lang="scss" scoped>
.title-shortcut-key__wrap {
display: flex;
}
.page-title {
font-size: var(--font-size-big);
font-weight: var(--font-weight-bold);
}
.shortcut-key__wrap {
display: flex;
align-items: center;
margin-bottom: var(--space-smaller);
margin-left: var(--space-small);
}
.shortcut__wrap {
display: grid;
grid-template-columns: repeat(2, 0.5fr);
gap: var(--space-smaller) var(--space-large);
margin-top: var(--space-small);
padding: 0 var(--space-large) var(--space-large);
}
.title-key__wrap {
display: flex;
justify-content: space-between;
align-items: center;
min-width: 25rem;
}
.forward-slash {
display: flex;
align-items: center;
font-weight: var(--font-weight-bold);
}
.shortcut-key {
background: var(--color-background);
padding: var(--space-small) var(--space-one);
font-weight: var(--font-weight-bold);
font-size: var(--font-size-mini);
align-items: center;
border-radius: var(--border-radius-normal);
margin-right: var(--space-small);
}
.key {
display: flex;
justify-content: center;
min-width: var(--space-large);
margin-right: 0;
}
.open-conversation__key {
display: flex;
margin-right: var(--space-small);
@apply py-2 px-2.5;
}
</style>