fix: vue 3 followup fixes (#10213)

Fixes: CW-3602,  CW-3606, CW-3605, CW-3601, CW-3603, CW-3600, CW-3598

-
[CW-3602](https://linear.app/chatwoot/issue/CW-3602/chat-list-infinite-loader-fetching-only-odd-numbered-pages)
Chat list pagination broken
-
[CW-3606](https://linear.app/chatwoot/issue/CW-3606/saving-greeting-message-is-not-working-in-inbox-settings)
Greetings message not getting saved
-
[CW-3605](https://linear.app/chatwoot/issue/CW-3605/copy-and-paste-image-attachment-not-working-in-widget)
Paste not working on widget
-
[CW-3601](https://linear.app/chatwoot/issue/CW-3601/edit-category-is-not-working-properly)
Edit category not updating
-
[CW-3603](https://linear.app/chatwoot/issue/CW-3603/delete-filter-is-not-working)
Delete filter modal not toggling
-
[CW-3600](https://linear.app/chatwoot/issue/CW-3600/portal-editor-is-not-working-properly)
Portal editor events were flaky
-
[CW-3598](https://linear.app/chatwoot/issue/CW-3598/rearrange-of-pre-chat-form-fields-throws-an-error)
Prechat form re-order bug

---------

Co-authored-by: Vishnu Narayanan <iamwishnu@gmail.com>
This commit is contained in:
Shivam Mishra
2024-10-03 19:59:07 +05:30
committed by GitHub
parent 701135df92
commit b3262597c1
17 changed files with 204 additions and 136 deletions

View File

@@ -537,12 +537,6 @@ function loadMoreConversations() {
return; return;
} }
// Increment the current page
store.dispatch('conversationPage/setCurrentPage', {
filter: currentPageFilterKey.value,
page: currentFiltersPage.value + 1,
});
if (!hasAppliedFiltersOrActiveFolders.value) { if (!hasAppliedFiltersOrActiveFolders.value) {
fetchConversations(); fetchConversations();
} else if (hasActiveFolders.value) { } else if (hasActiveFolders.value) {

View File

@@ -61,17 +61,9 @@ export default {
plugins: [imagePastePlugin(this.handleImageUpload)], plugins: [imagePastePlugin(this.handleImageUpload)],
}; };
}, },
computed: {
contentFromEditor() {
if (editorView) {
return ArticleMarkdownSerializer.serialize(editorView.state.doc);
}
return '';
},
},
watch: { watch: {
modelValue(newValue = '') { modelValue(newValue = '') {
if (newValue !== this.contentFromEditor) { if (newValue !== this.contentFromEditor()) {
this.reloadState(); this.reloadState();
} }
}, },
@@ -96,6 +88,12 @@ export default {
this.focusEditorInputField(); this.focusEditorInputField();
}, },
methods: { methods: {
contentFromEditor() {
if (editorView) {
return ArticleMarkdownSerializer.serialize(editorView.state.doc);
}
return '';
},
openFileBrowser() { openFileBrowser() {
this.$refs.imageUploadInput.click(); this.$refs.imageUploadInput.click();
}, },
@@ -213,8 +211,8 @@ export default {
editorView.focus(); editorView.focus();
}, },
emitOnChange() { emitOnChange() {
this.$emit('update:modelValue', this.contentFromEditor); this.$emit('update:modelValue', this.contentFromEditor());
this.$emit('input', this.contentFromEditor); this.$emit('input', this.contentFromEditor());
}, },
onKeyup() { onKeyup() {
this.$emit('keyup'); this.$emit('keyup');

View File

@@ -1,20 +1,22 @@
<script> <script>
import { defineModel } from 'vue';
import { useVuelidate } from '@vuelidate/core'; import { useVuelidate } from '@vuelidate/core';
import { required, minLength, email } from '@vuelidate/validators'; import { required, minLength, email } from '@vuelidate/validators';
import { useAlert } from 'dashboard/composables'; import { useAlert } from 'dashboard/composables';
export default { export default {
props: { props: {
show: {
type: Boolean,
default: false,
},
currentChat: { currentChat: {
type: Object, type: Object,
default: () => ({}), default: () => ({}),
}, },
}, },
emits: ['cancel'], emits: ['cancel', 'update:show'],
setup() { setup() {
const show = defineModel('show', { type: Boolean, default: false }); return { v$: useVuelidate() };
return { v$: useVuelidate(), show };
}, },
data() { data() {
return { return {
@@ -31,6 +33,14 @@ export default {
}, },
}, },
computed: { computed: {
localShow: {
get() {
return this.show;
},
set(value) {
this.$emit('update:show', value);
},
},
sentToOtherEmailAddress() { sentToOtherEmailAddress() {
return this.selectedType === 'other_email_address'; return this.selectedType === 'other_email_address';
}, },
@@ -81,7 +91,7 @@ export default {
</script> </script>
<template> <template>
<woot-modal v-model:show="show" :on-close="onCancel"> <woot-modal v-model:show="localShow" :on-close="onCancel">
<div class="flex flex-col h-auto overflow-auto"> <div class="flex flex-col h-auto overflow-auto">
<woot-modal-header <woot-modal-header
:header-title="$t('EMAIL_TRANSCRIPT.TITLE')" :header-title="$t('EMAIL_TRANSCRIPT.TITLE')"

View File

@@ -1,5 +1,4 @@
<script> <script>
import { defineModel } from 'vue';
import TemplatesPicker from './TemplatesPicker.vue'; import TemplatesPicker from './TemplatesPicker.vue';
import TemplateParser from './TemplateParser.vue'; import TemplateParser from './TemplateParser.vue';
export default { export default {
@@ -8,23 +7,30 @@ export default {
TemplateParser, TemplateParser,
}, },
props: { props: {
show: {
type: Boolean,
default: false,
},
inboxId: { inboxId: {
type: Number, type: Number,
default: undefined, default: undefined,
}, },
}, },
emits: ['onSend', 'cancel'], emits: ['onSend', 'cancel', 'update:show'],
setup() {
const show = defineModel('show', { type: Boolean, default: false });
return { show };
},
data() { data() {
return { return {
selectedWaTemplate: null, selectedWaTemplate: null,
}; };
}, },
computed: { computed: {
localShow: {
get() {
return this.show;
},
set(value) {
this.$emit('update:show', value);
},
},
modalHeaderContent() { modalHeaderContent() {
return this.selectedWaTemplate return this.selectedWaTemplate
? this.$t('WHATSAPP_TEMPLATES.MODAL.TEMPLATE_SELECTED_SUBTITLE', { ? this.$t('WHATSAPP_TEMPLATES.MODAL.TEMPLATE_SELECTED_SUBTITLE', {
@@ -51,7 +57,7 @@ export default {
</script> </script>
<template> <template>
<woot-modal v-model:show="show" :on-close="onClose" size="modal-big"> <woot-modal v-model:show="localShow" :on-close="onClose" size="modal-big">
<woot-modal-header <woot-modal-header
:header-title="$t('WHATSAPP_TEMPLATES.MODAL.TITLE')" :header-title="$t('WHATSAPP_TEMPLATES.MODAL.TITLE')"
:header-content="modalHeaderContent" :header-content="modalHeaderContent"

View File

@@ -1,5 +1,4 @@
<script> <script>
import { defineModel } from 'vue';
import { required } from '@vuelidate/validators'; import { required } from '@vuelidate/validators';
import { useVuelidate } from '@vuelidate/core'; import { useVuelidate } from '@vuelidate/core';
import Modal from '../../Modal.vue'; import Modal from '../../Modal.vue';
@@ -9,6 +8,7 @@ export default {
Modal, Modal,
}, },
props: { props: {
show: { type: Boolean, default: false },
title: { type: String, default: '' }, title: { type: String, default: '' },
message: { type: String, default: '' }, message: { type: String, default: '' },
confirmText: { type: String, default: '' }, confirmText: { type: String, default: '' },
@@ -16,10 +16,9 @@ export default {
confirmValue: { type: String, default: '' }, confirmValue: { type: String, default: '' },
confirmPlaceHolderText: { type: String, default: '' }, confirmPlaceHolderText: { type: String, default: '' },
}, },
emits: ['onClose', 'onConfirm'], emits: ['onClose', 'onConfirm', 'update:show'],
setup() { setup() {
const show = defineModel('show', { type: Boolean, default: false }); return { v$: useVuelidate() };
return { v$: useVuelidate(), show };
}, },
data() { data() {
return { return {
@@ -34,6 +33,16 @@ export default {
}, },
}, },
}, },
computed: {
localShow: {
get() {
return this.show;
},
set(value) {
this.$emit('update:show', value);
},
},
},
methods: { methods: {
closeModal() { closeModal() {
this.value = ''; this.value = '';
@@ -47,7 +56,7 @@ export default {
</script> </script>
<template> <template>
<Modal v-model:show="show" :on-close="closeModal"> <Modal v-model:show="localShow" :on-close="closeModal">
<woot-modal-header :header-title="title" :header-content="message" /> <woot-modal-header :header-title="title" :header-content="message" />
<form @submit.prevent="onConfirm"> <form @submit.prevent="onConfirm">
<woot-input <woot-input

View File

@@ -1,5 +1,4 @@
<script> <script>
import { defineModel } from 'vue';
import { useAlert, useTrack } from 'dashboard/composables'; import { useAlert, useTrack } from 'dashboard/composables';
import MergeContact from 'dashboard/modules/contact/components/MergeContact.vue'; import MergeContact from 'dashboard/modules/contact/components/MergeContact.vue';
@@ -11,17 +10,16 @@ import { CONTACTS_EVENTS } from '../../helper/AnalyticsHelper/events';
export default { export default {
components: { MergeContact }, components: { MergeContact },
props: { props: {
show: {
type: Boolean,
default: false,
},
primaryContact: { primaryContact: {
type: Object, type: Object,
required: true, required: true,
}, },
}, },
emits: ['close'], emits: ['close', 'update:show'],
setup() {
const show = defineModel('show', { type: Boolean, default: false });
return { show };
},
data() { data() {
return { return {
isSearching: false, isSearching: false,
@@ -32,6 +30,14 @@ export default {
...mapGetters({ ...mapGetters({
uiFlags: 'contacts/getUIFlags', uiFlags: 'contacts/getUIFlags',
}), }),
localShow: {
get() {
return this.show;
},
set(value) {
this.$emit('update:show', value);
},
},
}, },
methods: { methods: {
@@ -73,7 +79,7 @@ export default {
</script> </script>
<template> <template>
<woot-modal v-model:show="show" :on-close="onClose"> <woot-modal v-model:show="localShow" :on-close="onClose">
<woot-modal-header <woot-modal-header
:header-title="$t('MERGE_CONTACTS.TITLE')" :header-title="$t('MERGE_CONTACTS.TITLE')"
:header-content="$t('MERGE_CONTACTS.DESCRIPTION')" :header-content="$t('MERGE_CONTACTS.DESCRIPTION')"

View File

@@ -1,5 +1,4 @@
<script> <script>
import { defineModel } from 'vue';
import Modal from 'dashboard/components/Modal.vue'; import Modal from 'dashboard/components/Modal.vue';
import { useVuelidate } from '@vuelidate/core'; import { useVuelidate } from '@vuelidate/core';
import { required, minLength } from '@vuelidate/validators'; import { required, minLength } from '@vuelidate/validators';
@@ -9,15 +8,18 @@ export default {
Modal, Modal,
}, },
props: { props: {
show: {
type: Boolean,
default: false,
},
isCreating: { isCreating: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
}, },
emits: ['create', 'cancel'], emits: ['create', 'cancel', 'update:show'],
setup() { setup() {
const show = defineModel('show', { type: Boolean, default: false }); return { v$: useVuelidate() };
return { v$: useVuelidate(), show };
}, },
data() { data() {
return { return {
@@ -32,6 +34,14 @@ export default {
}, },
}, },
computed: { computed: {
localShow: {
get() {
return this.show;
},
set(value) {
this.$emit('update:show', value);
},
},
attributeNameError() { attributeNameError() {
if (this.v$.attributeName.$error) { if (this.v$.attributeName.$error) {
return this.$t('CUSTOM_ATTRIBUTES.FORM.NAME.ERROR'); return this.$t('CUSTOM_ATTRIBUTES.FORM.NAME.ERROR');
@@ -61,7 +71,7 @@ export default {
</script> </script>
<template> <template>
<Modal v-model:show="show" :on-close="onClose"> <Modal v-model:show="localShow" :on-close="onClose">
<woot-modal-header <woot-modal-header
:header-title="$t('CUSTOM_ATTRIBUTES.ADD.TITLE')" :header-title="$t('CUSTOM_ATTRIBUTES.ADD.TITLE')"
:header-content="$t('CUSTOM_ATTRIBUTES.ADD.DESC')" :header-content="$t('CUSTOM_ATTRIBUTES.ADD.DESC')"

View File

@@ -1,5 +1,4 @@
<script> <script>
import { defineModel } from 'vue';
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import ContactForm from './ContactForm.vue'; import ContactForm from './ContactForm.vue';
@@ -7,18 +6,26 @@ export default {
components: { components: {
ContactForm, ContactForm,
}, },
emits: ['cancel'], props: {
setup() { show: {
const show = defineModel('show', { type: Boolean, default: false }); type: Boolean,
default: false,
return { show }; },
}, },
emits: ['cancel', 'update:show'],
computed: { computed: {
...mapGetters({ ...mapGetters({
uiFlags: 'contacts/getUIFlags', uiFlags: 'contacts/getUIFlags',
}), }),
localShow: {
get() {
return this.show;
},
set(value) {
this.$emit('update:show', value);
},
},
}, },
methods: { methods: {
onCancel() { onCancel() {
this.$emit('cancel'); this.$emit('cancel');
@@ -35,7 +42,7 @@ export default {
<template> <template>
<woot-modal <woot-modal
v-model:show="show" v-model:show="localShow"
:on-close="onCancel" :on-close="onCancel"
modal-type="right-aligned" modal-type="right-aligned"
> >

View File

@@ -1,5 +1,4 @@
<script> <script>
import { defineModel } from 'vue';
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import ContactForm from './ContactForm.vue'; import ContactForm from './ContactForm.vue';
@@ -8,20 +7,28 @@ export default {
ContactForm, ContactForm,
}, },
props: { props: {
show: {
type: Boolean,
default: false,
},
contact: { contact: {
type: Object, type: Object,
default: () => ({}), default: () => ({}),
}, },
}, },
emits: ['cancel'], emits: ['cancel', 'update:show'],
setup() {
const show = defineModel('show', { type: Boolean, default: false });
return { show };
},
computed: { computed: {
...mapGetters({ ...mapGetters({
uiFlags: 'contacts/getUIFlags', uiFlags: 'contacts/getUIFlags',
}), }),
localShow: {
get() {
return this.show;
},
set(value) {
this.$emit('update:show', value);
},
},
}, },
methods: { methods: {
@@ -44,7 +51,7 @@ export default {
<template> <template>
<woot-modal <woot-modal
v-model:show="show" v-model:show="localShow"
:on-close="onCancel" :on-close="onCancel"
modal-type="right-aligned" modal-type="right-aligned"
> >

View File

@@ -1,5 +1,4 @@
<script> <script>
import { defineModel } from 'vue';
import ConversationForm from './ConversationForm.vue'; import ConversationForm from './ConversationForm.vue';
export default { export default {
@@ -7,15 +6,25 @@ export default {
ConversationForm, ConversationForm,
}, },
props: { props: {
show: {
type: Boolean,
default: false,
},
contact: { contact: {
type: Object, type: Object,
default: () => ({}), default: () => ({}),
}, },
}, },
emits: ['cancel'], emits: ['cancel', 'update:show'],
setup() { computed: {
const show = defineModel('show', { type: Boolean, default: false }); localShow: {
return { show }; get() {
return this.show;
},
set(value) {
this.$emit('update:show', value);
},
},
}, },
watch: { watch: {
'contact.id'(id) { 'contact.id'(id) {
@@ -45,7 +54,7 @@ export default {
</script> </script>
<template> <template>
<woot-modal v-model:show="show" :on-close="onCancel"> <woot-modal v-model:show="localShow" :on-close="onCancel">
<div class="flex flex-col h-auto overflow-auto"> <div class="flex flex-col h-auto overflow-auto">
<woot-modal-header <woot-modal-header
:header-title="$t('NEW_CONVERSATION.TITLE')" :header-title="$t('NEW_CONVERSATION.TITLE')"

View File

@@ -1,11 +1,14 @@
<script> <script>
import { defineModel } from 'vue';
import { useAlert } from 'dashboard/composables'; import { useAlert } from 'dashboard/composables';
import { CONTACTS_EVENTS } from '../../../helper/AnalyticsHelper/events'; import { CONTACTS_EVENTS } from '../../../helper/AnalyticsHelper/events';
import { useTrack } from 'dashboard/composables'; import { useTrack } from 'dashboard/composables';
export default { export default {
props: { props: {
show: {
type: Boolean,
default: false,
},
activeCustomView: { activeCustomView: {
type: Object, type: Object,
default: () => {}, default: () => {},
@@ -23,12 +26,16 @@ export default {
default: () => {}, default: () => {},
}, },
}, },
emits: ['close'], emits: ['close', 'update:show'],
setup() {
const show = defineModel('show', { type: Boolean, default: false });
return { show };
},
computed: { computed: {
localShow: {
get() {
return this.show;
},
set(value) {
this.$emit('update:show', value);
},
},
activeCustomViews() { activeCustomViews() {
if (this.activeFilterType === 0) { if (this.activeFilterType === 0) {
return 'conversation'; return 'conversation';
@@ -93,8 +100,8 @@ export default {
<template> <template>
<div> <div>
<woot-delete-modal <woot-delete-modal
v-if="show" v-if="localShow"
v-model:show="show" v-model:show="localShow"
:on-close="closeDeletePopup" :on-close="closeDeletePopup"
:on-confirm="deleteSavedCustomViews" :on-confirm="deleteSavedCustomViews"
:title="$t('FILTER.CUSTOM_VIEWS.DELETE.MODAL.CONFIRM.TITLE')" :title="$t('FILTER.CUSTOM_VIEWS.DELETE.MODAL.CONFIRM.TITLE')"

View File

@@ -1,5 +1,4 @@
<script> <script>
import { defineModel } from 'vue';
import Modal from 'dashboard/components/Modal.vue'; import Modal from 'dashboard/components/Modal.vue';
import { required } from '@vuelidate/validators'; import { required } from '@vuelidate/validators';
import { useVuelidate } from '@vuelidate/core'; import { useVuelidate } from '@vuelidate/core';
@@ -13,15 +12,18 @@ export default {
Modal, Modal,
}, },
props: { props: {
show: {
type: Boolean,
default: false,
},
portal: { portal: {
type: Object, type: Object,
default: () => ({}), default: () => ({}),
}, },
}, },
emits: ['cancel'], emits: ['cancel', 'update:show'],
setup() { setup() {
const show = defineModel('show', { type: Boolean, default: false }); return { v$: useVuelidate() };
return { v$: useVuelidate(), show };
}, },
data() { data() {
return { return {
@@ -30,6 +32,14 @@ export default {
}; };
}, },
computed: { computed: {
localShow: {
get() {
return this.show;
},
set(value) {
this.$emit('update:show', value);
},
},
addedLocales() { addedLocales() {
const { allowed_locales: allowedLocales } = this.portal.config; const { allowed_locales: allowedLocales } = this.portal.config;
return allowedLocales.map(locale => locale.code); return allowedLocales.map(locale => locale.code);
@@ -96,7 +106,7 @@ export default {
</script> </script>
<template> <template>
<Modal v-model:show="show" :on-close="onClose"> <Modal v-model:show="localShow" :on-close="onClose">
<woot-modal-header <woot-modal-header
:header-title="$t('HELP_CENTER.PORTAL.ADD_LOCALE.TITLE')" :header-title="$t('HELP_CENTER.PORTAL.ADD_LOCALE.TITLE')"
:header-content="$t('HELP_CENTER.PORTAL.ADD_LOCALE.SUB_TITLE')" :header-content="$t('HELP_CENTER.PORTAL.ADD_LOCALE.SUB_TITLE')"

View File

@@ -1,5 +1,4 @@
<script> <script>
import { defineModel } from 'vue';
import { required, minLength } from '@vuelidate/validators'; import { required, minLength } from '@vuelidate/validators';
import { useVuelidate } from '@vuelidate/core'; import { useVuelidate } from '@vuelidate/core';
import { useAlert, useTrack } from 'dashboard/composables'; import { useAlert, useTrack } from 'dashboard/composables';
@@ -10,6 +9,10 @@ import NameEmojiInput from './NameEmojiInput.vue';
export default { export default {
components: { NameEmojiInput }, components: { NameEmojiInput },
props: { props: {
show: {
type: Boolean,
default: false,
},
portalName: { portalName: {
type: String, type: String,
default: '', default: '',
@@ -23,10 +26,9 @@ export default {
default: '', default: '',
}, },
}, },
emits: ['create', 'cancel'], emits: ['create', 'cancel', 'update:show'],
setup() { setup() {
const show = defineModel('show', { type: Boolean, default: false }); return { v$: useVuelidate() };
return { v$: useVuelidate(), show };
}, },
data() { data() {
return { return {
@@ -46,6 +48,14 @@ export default {
}, },
}, },
computed: { computed: {
localShow: {
get() {
return this.show;
},
set(value) {
this.$emit('update:show', value);
},
},
selectedPortalSlug() { selectedPortalSlug() {
return this.$route.params.portalSlug return this.$route.params.portalSlug
? this.$route.params.portalSlug ? this.$route.params.portalSlug
@@ -111,7 +121,7 @@ export default {
</script> </script>
<template> <template>
<woot-modal v-model:show="show" :on-close="onClose"> <woot-modal v-model:show="localShow" :on-close="onClose">
<woot-modal-header <woot-modal-header
:header-title="$t('HELP_CENTER.CATEGORY.ADD.TITLE')" :header-title="$t('HELP_CENTER.CATEGORY.ADD.TITLE')"
:header-content="$t('HELP_CENTER.CATEGORY.ADD.SUB_TITLE')" :header-content="$t('HELP_CENTER.CATEGORY.ADD.SUB_TITLE')"

View File

@@ -1,5 +1,4 @@
<script> <script>
import { defineModel } from 'vue';
import { required, minLength } from '@vuelidate/validators'; import { required, minLength } from '@vuelidate/validators';
import { useVuelidate } from '@vuelidate/core'; import { useVuelidate } from '@vuelidate/core';
import { useAlert, useTrack } from 'dashboard/composables'; import { useAlert, useTrack } from 'dashboard/composables';
@@ -10,6 +9,10 @@ import CategoryNameIconInput from './NameEmojiInput.vue';
export default { export default {
components: { CategoryNameIconInput }, components: { CategoryNameIconInput },
props: { props: {
show: {
type: Boolean,
default: false,
},
portalName: { portalName: {
type: String, type: String,
default: '', default: '',
@@ -27,10 +30,9 @@ export default {
default: '', default: '',
}, },
}, },
emits: ['update', 'cancel'], emits: ['update', 'cancel', 'update:show'],
setup() { setup() {
const show = defineModel('show', { type: Boolean, default: false }); return { v$: useVuelidate() };
return { v$: useVuelidate(), show };
}, },
data() { data() {
return { return {
@@ -51,6 +53,14 @@ export default {
}, },
}, },
computed: { computed: {
localShow: {
get() {
return this.show;
},
set(value) {
this.$emit('update:show', value);
},
},
slugError() { slugError() {
if (this.v$.slug.$error) { if (this.v$.slug.$error) {
return this.$t('HELP_CENTER.CATEGORY.ADD.SLUG.ERROR'); return this.$t('HELP_CENTER.CATEGORY.ADD.SLUG.ERROR');
@@ -120,7 +130,7 @@ export default {
</script> </script>
<template> <template>
<woot-modal v-model:show="show" :on-close="onClose"> <woot-modal v-model:show="localShow" :on-close="onClose">
<woot-modal-header <woot-modal-header
:header-title="$t('HELP_CENTER.CATEGORY.EDIT.TITLE')" :header-title="$t('HELP_CENTER.CATEGORY.EDIT.TITLE')"
:header-content="$t('HELP_CENTER.CATEGORY.EDIT.SUB_TITLE')" :header-content="$t('HELP_CENTER.CATEGORY.EDIT.SUB_TITLE')"

View File

@@ -106,7 +106,7 @@ export default {
:label="label" :label="label"
:placeholder="placeholder" :placeholder="placeholder"
:help-text="helpText" :help-text="helpText"
@input="onNameChange" @update:model-value="onNameChange"
/> />
<EmojiInput <EmojiInput
v-if="showEmojiPicker" v-if="showEmojiPicker"

View File

@@ -1,47 +1,21 @@
<script> <script setup>
import { computed } from 'vue';
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor.vue'; import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor.vue';
import ResizableTextArea from 'shared/components/ResizableTextArea.vue'; import ResizableTextArea from 'shared/components/ResizableTextArea.vue';
export default { const props = defineProps({
components: { modelValue: { type: String, default: '' },
WootMessageEditor, richtext: { type: Boolean, default: false },
ResizableTextArea, label: { type: String, default: '' },
}, placeholder: { type: String, default: '' },
props: { });
value: {
type: String, const emit = defineEmits(['update:modelValue']);
default: '',
}, const greetingsMessage = computed({
richtext: { get: () => props.modelValue,
type: Boolean, set: value => emit('update:modelValue', value),
default: false, });
},
label: {
type: String,
default: '',
},
placeholder: {
type: String,
default: '',
},
},
emits: ['input'],
data() {
return {
greetingsMessage: this.value,
};
},
watch: {
value(newValue) {
this.greetingsMessage = newValue;
},
},
methods: {
handleInput() {
this.$emit('input', this.greetingsMessage);
},
},
};
</script> </script>
<template> <template>
@@ -57,7 +31,6 @@ export default {
class="bg-white input dark:bg-slate-900" class="bg-white input dark:bg-slate-900"
:placeholder="placeholder" :placeholder="placeholder"
:min-height="4" :min-height="4"
@input="handleInput"
/> />
</div> </div>
<ResizableTextArea <ResizableTextArea

View File

@@ -41,7 +41,9 @@ export default {
methods: { methods: {
handleClipboardPaste(e) { handleClipboardPaste(e) {
const items = (e.clipboardData || e.originalEvent.clipboardData).items; const items = (e.clipboardData || e.originalEvent.clipboardData).items;
items.forEach(item => { // items is a DataTransferItemList object which does not have forEach method
const itemsArray = Array.from(items);
itemsArray.forEach(item => {
if (item.kind === 'file') { if (item.kind === 'file') {
e.preventDefault(); e.preventDefault();
const file = item.getAsFile(); const file = item.getAsFile();