Merge branch 'develop' into feat/email-forwarding
This commit is contained in:
@@ -1,38 +1,33 @@
|
||||
<script>
|
||||
import Thumbnail from '../../../components/widgets/Thumbnail.vue';
|
||||
<script setup>
|
||||
import Avatar from 'next/avatar/Avatar.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Thumbnail,
|
||||
defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
thumbnail: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
phoneNumber: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
identifier: {
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
},
|
||||
thumbnail: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
};
|
||||
email: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
phoneNumber: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
identifier: {
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="option-item--user">
|
||||
<Thumbnail :src="thumbnail" size="28px" :username="name" />
|
||||
<Avatar :src="thumbnail" :size="28" :name="name" rounded-full />
|
||||
<div class="option__user-data">
|
||||
<h5 class="option__title">
|
||||
{{ name }}
|
||||
@@ -60,7 +55,7 @@ export default {
|
||||
@apply flex items-center;
|
||||
}
|
||||
.user-identifier {
|
||||
@apply text-xs ml-0.5 text-slate-700 dark:text-slate-100;
|
||||
@apply text-xs ml-0.5 text-n-slate-12;
|
||||
}
|
||||
.option__user-data {
|
||||
@apply flex flex-col flex-grow ml-2 mr-2;
|
||||
@@ -73,10 +68,10 @@ export default {
|
||||
@apply relative top-px mr-0.5 rtl:mr-0 rtl:ml-0.5;
|
||||
}
|
||||
.option__title {
|
||||
@apply text-slate-800 dark:text-slate-100 font-medium mb-0.5;
|
||||
@apply text-n-slate-12 font-medium mb-0.5;
|
||||
}
|
||||
.option__body {
|
||||
@apply text-xs text-slate-700 dark:text-slate-100 mt-1;
|
||||
@apply text-xs text-n-slate-12 mt-1;
|
||||
}
|
||||
|
||||
.option__user-data .option__body {
|
||||
|
||||
@@ -130,15 +130,15 @@ export default {
|
||||
</div>
|
||||
<div class="flex multiselect-wrap--medium">
|
||||
<div
|
||||
class="w-8 relative text-base text-slate-100 dark:text-slate-600 after:content-[''] after:h-12 after:w-0 after:left-4 after:absolute after:border-l after:border-solid after:border-slate-100 after:dark:border-slate-600 before:content-[''] before:h-0 before:w-4 before:left-4 before:top-12 before:absolute before:border-b before:border-solid before:border-slate-100 before:dark:border-slate-600"
|
||||
class="w-8 relative text-base text-n-strong after:content-[''] after:h-12 after:w-0 ltr:after:left-4 rtl:after:right-4 after:absolute after:border-l after:border-solid after:border-n-strong before:content-[''] before:h-0 before:w-4 ltr:before:left-4 rtl:before:right-4 before:top-12 before:absolute before:border-b before:border-solid before:border-n-strong"
|
||||
>
|
||||
<fluent-icon
|
||||
icon="arrow-up"
|
||||
class="absolute -top-1 left-2"
|
||||
class="absolute -top-1 ltr:left-2 rtl:right-2"
|
||||
size="17"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col w-full">
|
||||
<div class="flex flex-col w-full ltr:pl-8 rtl:pr-8">
|
||||
<label class="multiselect__label">
|
||||
{{ $t('MERGE_CONTACTS.PRIMARY.TITLE') }}
|
||||
<woot-label
|
||||
|
||||
@@ -17,9 +17,9 @@ export default {
|
||||
<template>
|
||||
<div
|
||||
v-if="parentContactName"
|
||||
class="my-4 relative p-2.5 border rounded-[4px] text-slate-800 dark:text-slate-100 border-slate-100 dark:border-slate-700 bg-white dark:bg-slate-800"
|
||||
class="my-4 relative p-2.5 border rounded-[4px] text-n-slate-12 border-n-weak bg-n-background"
|
||||
>
|
||||
<h5 class="text-base font-medium text-slate-900 dark:text-white">
|
||||
<h5 class="text-base font-medium text-n-slate-12">
|
||||
{{ $t('MERGE_CONTACTS.SUMMARY.TITLE') }}
|
||||
</h5>
|
||||
<ul class="ml-0 list-none">
|
||||
|
||||
@@ -273,7 +273,7 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.menu-container {
|
||||
@apply p-1 bg-white dark:bg-slate-900 shadow-xl rounded-md;
|
||||
@apply p-1 bg-n-background shadow-xl rounded-md;
|
||||
|
||||
hr:first-child {
|
||||
@apply hidden;
|
||||
@@ -293,10 +293,6 @@ export default {
|
||||
@apply font-medium text-base;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
@apply pt-4 pb-8 px-8;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { ref, useTemplateRef, onMounted, watch, nextTick } from 'vue';
|
||||
import { ref, useTemplateRef, onMounted, watch, nextTick, computed } from 'vue';
|
||||
import { useMessageFormatter } from 'shared/composables/useMessageFormatter';
|
||||
import ReadMore from './ReadMore.vue';
|
||||
|
||||
@@ -8,9 +8,9 @@ const props = defineProps({
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: '',
|
||||
message: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
searchTerm: {
|
||||
type: String,
|
||||
@@ -18,6 +18,24 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const messageContent = computed(() => {
|
||||
// We perform search on either content or email subject or transcribed text
|
||||
if (props.message.content) {
|
||||
return props.message.content;
|
||||
}
|
||||
|
||||
const { content_attributes = {} } = props.message;
|
||||
const { email = {} } = content_attributes || {};
|
||||
if (email.subject) {
|
||||
return email.subject;
|
||||
}
|
||||
|
||||
const audioAttachment = props.message.attachments.find(
|
||||
attachment => attachment.file_type === 'audio'
|
||||
);
|
||||
return audioAttachment?.transcribed_text || '';
|
||||
});
|
||||
|
||||
const { highlightContent } = useMessageFormatter();
|
||||
|
||||
const messageContainer = useTemplateRef('messageContainer');
|
||||
@@ -38,7 +56,8 @@ const escapeHtml = html => {
|
||||
return p.innerText;
|
||||
};
|
||||
|
||||
const prepareContent = (content = '') => {
|
||||
const prepareContent = () => {
|
||||
const content = messageContent.value || '';
|
||||
const escapedText = escapeHtml(content);
|
||||
return highlightContent(
|
||||
escapedText,
|
||||
@@ -65,7 +84,7 @@ onMounted(() => {
|
||||
{{ $t('SEARCH.WROTE') }}
|
||||
</p>
|
||||
<ReadMore :shrink="isOverflowing" @expand="isOverflowing = false">
|
||||
<div v-dompurify-html="prepareContent(content)" class="message-content" />
|
||||
<div v-dompurify-html="prepareContent()" class="message-content" />
|
||||
</ReadMore>
|
||||
</blockquote>
|
||||
</template>
|
||||
@@ -74,6 +93,7 @@ onMounted(() => {
|
||||
.message {
|
||||
@apply py-0 px-2 mt-2;
|
||||
}
|
||||
|
||||
.message-content::v-deep p,
|
||||
.message-content::v-deep li::marker {
|
||||
@apply text-n-slate-11 mb-1;
|
||||
|
||||
@@ -102,7 +102,7 @@ const visibleInfoItems = computed(() =>
|
||||
>
|
||||
<InboxName
|
||||
:inbox="inbox"
|
||||
class="mr-2 rtl:mr-0 rtl:ml-2 bg-n-slate-3 dark:bg-n-solid-3 text-n-slate-11 dark:text-n-slate-11"
|
||||
class="mx-2 bg-n-slate-3 dark:bg-n-solid-3 text-n-slate-11 dark:text-n-slate-11"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -54,7 +54,7 @@ const getName = message => {
|
||||
>
|
||||
<MessageContent
|
||||
:author="getName(message)"
|
||||
:content="message.content"
|
||||
:message="message"
|
||||
:search-term="query"
|
||||
/>
|
||||
</SearchResultConversationItem>
|
||||
|
||||
@@ -41,6 +41,7 @@ const onTabChange = index => {
|
||||
:name="item.name"
|
||||
:count="item.count"
|
||||
:show-badge="item.showBadge"
|
||||
is-compact
|
||||
/>
|
||||
</woot-tabs>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@ import WidgetHead from './WidgetHead.vue';
|
||||
import WidgetBody from './WidgetBody.vue';
|
||||
import WidgetFooter from './WidgetFooter.vue';
|
||||
import InputRadioGroup from 'dashboard/routes/dashboard/settings/inbox/components/InputRadioGroup.vue';
|
||||
import globalConfigMixin from 'shared/mixins/globalConfigMixin';
|
||||
import { useBranding } from 'shared/composables/useBranding';
|
||||
import { mapGetters } from 'vuex';
|
||||
|
||||
export default {
|
||||
@@ -14,7 +14,6 @@ export default {
|
||||
WidgetFooter,
|
||||
InputRadioGroup,
|
||||
},
|
||||
mixins: [globalConfigMixin],
|
||||
props: {
|
||||
welcomeHeading: {
|
||||
type: String,
|
||||
@@ -57,6 +56,12 @@ export default {
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const { replaceInstallationName } = useBranding();
|
||||
return {
|
||||
replaceInstallationName,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
widgetScreens: [
|
||||
@@ -140,7 +145,7 @@ export default {
|
||||
</div>
|
||||
<div
|
||||
v-if="isWidgetVisible"
|
||||
class="widget-wrapper flex flex-col justify-between rounded-lg shadow-md bg-slate-25 dark:bg-slate-800 h-[31.25rem] w-80"
|
||||
class="widget-wrapper flex flex-col justify-between rounded-lg shadow-md bg-n-slate-2 dark:bg-n-solid-1 h-[31.25rem] w-80"
|
||||
>
|
||||
<WidgetHead :config="getWidgetConfig" />
|
||||
<div>
|
||||
@@ -151,7 +156,7 @@ export default {
|
||||
<WidgetFooter :config="getWidgetConfig" />
|
||||
<div class="py-2.5 flex justify-center">
|
||||
<a
|
||||
class="items-center gap-0.5 text-slate-500 dark:text-slate-400 cursor-pointer flex filter grayscale opacity-90 hover:grayscale-0 hover:opacity-100 text-xxs"
|
||||
class="items-center gap-0.5 text-n-slate-11 cursor-pointer flex filter grayscale opacity-90 hover:grayscale-0 hover:opacity-100 text-xxs"
|
||||
>
|
||||
<img
|
||||
class="max-w-2.5 max-h-2.5"
|
||||
@@ -159,9 +164,8 @@ export default {
|
||||
/>
|
||||
<span>
|
||||
{{
|
||||
useInstallationName(
|
||||
$t('INBOX_MGMT.WIDGET_BUILDER.BRANDING_TEXT'),
|
||||
globalConfig.installationName
|
||||
replaceInstallationName(
|
||||
$t('INBOX_MGMT.WIDGET_BUILDER.BRANDING_TEXT')
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
|
||||
@@ -28,7 +28,7 @@ defineProps({
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white shadow rounded-[1.25rem] rounded-bl-[0.25rem] px-4 py-3 inline-block text-sm text-slate-900 dark:text-white dark:bg-slate-700"
|
||||
class="shadow rounded-[1.25rem] rounded-bl-[0.25rem] px-4 py-3 inline-block text-sm text-n-slate-12 bg-n-background dark:bg-n-solid-3"
|
||||
>
|
||||
<div>
|
||||
<p class="m-0">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { ref, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import ResizableTextArea from 'shared/components/ResizableTextArea.vue';
|
||||
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
|
||||
import Avatar from 'next/avatar/Avatar.vue';
|
||||
import FluentIcon from 'shared/components/FluentIcon/Index.vue';
|
||||
|
||||
const props = defineProps({
|
||||
@@ -27,24 +27,24 @@ const getStatusText = computed(() => {
|
||||
<div class="relative flex flex-col w-full px-4">
|
||||
<div
|
||||
v-if="config.isDefaultScreen"
|
||||
class="p-4 bg-white rounded-md shadow-sm dark:bg-slate-700"
|
||||
class="p-4 rounded-md shadow-sm bg-n-background dark:bg-n-solid-2"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<div
|
||||
class="text-sm font-medium leading-4 text-slate-700 dark:text-slate-50"
|
||||
class="text-sm font-medium leading-4 text-n-slate-12 dark:text-n-slate-50"
|
||||
>
|
||||
{{ getStatusText }}
|
||||
</div>
|
||||
<div class="mt-1 text-xs text-slate-500 dark:text-slate-100">
|
||||
<div class="mt-1 text-xs text-n-slate-11">
|
||||
{{ config.replyTime }}
|
||||
</div>
|
||||
</div>
|
||||
<Thumbnail username="C" size="34px" />
|
||||
<Avatar name="C" :size="34" rounded-full />
|
||||
</div>
|
||||
<button
|
||||
v-if="config.isDefaultScreen"
|
||||
class="inline-flex items-center justify-between px-2 py-1 mt-1 -ml-2 font-medium leading-6 bg-transparent rounded-md text-slate-800 dark:bg-transparent dark:text-slate-50 hover:bg-slate-25 dark:hover:bg-slate-800"
|
||||
class="inline-flex items-center justify-between px-2 py-1 mt-1 -ml-2 font-medium leading-6 bg-transparent rounded-md text-n-slate-12 dark:bg-transparent"
|
||||
:style="{ color: config.color }"
|
||||
>
|
||||
<span class="pr-2 text-xs">
|
||||
@@ -59,8 +59,8 @@ const getStatusText = computed(() => {
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="flex items-center h-10 bg-white rounded-md dark:bg-slate-700"
|
||||
:class="{ 'ring-2 ring-woot-500 dark:ring-woot-400': isInputFocused }"
|
||||
class="flex items-center h-10 bg-white rounded-md dark:!bg-n-slate-3"
|
||||
:class="{ 'ring-2 ring-n-brand dark:ring-n-brand': isInputFocused }"
|
||||
>
|
||||
<ResizableTextArea
|
||||
id="chat-input"
|
||||
@@ -68,7 +68,7 @@ const getStatusText = computed(() => {
|
||||
:placeholder="
|
||||
$t('INBOX_MGMT.WIDGET_BUILDER.FOOTER.CHAT_INPUT_PLACEHOLDER')
|
||||
"
|
||||
class="flex-grow !bg-white border-0 outline-none !outline-0 border-none h-8 text-sm dark:!bg-slate-700 pb-0 !pt-1.5 resize-none px-3 !mb-0 focus:outline-none rounded-md"
|
||||
class="flex-grow !bg-white border-0 outline-none !outline-0 border-none h-8 text-sm dark:!bg-n-slate-3 pb-0 !pt-1.5 resize-none px-3 !mb-0 focus:outline-none rounded-md"
|
||||
@focus="isInputFocused = true"
|
||||
@blur="isInputFocused = false"
|
||||
/>
|
||||
|
||||
@@ -26,8 +26,8 @@ const isDefaultScreen = computed(() => {
|
||||
class="rounded-t-lg flex-shrink-0 transition-[max-height] duration-300"
|
||||
:class="
|
||||
isDefaultScreen
|
||||
? 'bg-slate-25 dark:bg-slate-800 px-4 py-5'
|
||||
: 'bg-white dark:bg-slate-900 p-4'
|
||||
? 'bg-n-slate-2 dark:bg-n-solid-1 px-4 py-5'
|
||||
: 'bg-n-slate-2 dark:bg-n-solid-1 p-4'
|
||||
"
|
||||
>
|
||||
<div class="relative top-px">
|
||||
@@ -40,17 +40,15 @@ const isDefaultScreen = computed(() => {
|
||||
/>
|
||||
<div v-if="!isDefaultScreen">
|
||||
<div class="flex items-center justify-start gap-1">
|
||||
<span
|
||||
class="text-base font-medium leading-3 text-slate-900 dark:text-white"
|
||||
>
|
||||
<span class="text-base font-medium leading-3 text-n-slate-12">
|
||||
{{ config.websiteName }}
|
||||
</span>
|
||||
<div
|
||||
v-if="config.isOnline"
|
||||
class="w-2 h-2 bg-green-500 rounded-full"
|
||||
class="w-2 h-2 bg-n-teal-10 rounded-full"
|
||||
/>
|
||||
</div>
|
||||
<span class="mt-1 text-xs text-slate-600 dark:text-slate-400">
|
||||
<span class="mt-1 text-xs text-n-slate-11">
|
||||
{{ config.replyTime }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user