feat: Vite + vue 3 💚 (#10047)
Fixes https://github.com/chatwoot/chatwoot/issues/8436 Fixes https://github.com/chatwoot/chatwoot/issues/9767 Fixes https://github.com/chatwoot/chatwoot/issues/10156 Fixes https://github.com/chatwoot/chatwoot/issues/6031 Fixes https://github.com/chatwoot/chatwoot/issues/5696 Fixes https://github.com/chatwoot/chatwoot/issues/9250 Fixes https://github.com/chatwoot/chatwoot/issues/9762 --------- Co-authored-by: Pranav <pranavrajs@gmail.com> Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
This commit is contained in:
@@ -9,11 +9,14 @@ import { useMessageFormatter } from 'shared/composables/useMessageFormatter';
|
||||
import routerMixin from 'widget/mixins/routerMixin';
|
||||
import { useDarkMode } from 'widget/composables/useDarkMode';
|
||||
import configMixin from 'widget/mixins/configMixin';
|
||||
import { FormKit, createInput } from '@formkit/vue';
|
||||
import PhoneInput from 'widget/components/Form/PhoneInput.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CustomButton,
|
||||
Spinner,
|
||||
FormKit,
|
||||
},
|
||||
mixins: [routerMixin, configMixin],
|
||||
props: {
|
||||
@@ -23,9 +26,13 @@ export default {
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const phoneInput = createInput(PhoneInput, {
|
||||
props: ['hasErrorInPhoneInput'],
|
||||
});
|
||||
const { formatMessage } = useMessageFormatter();
|
||||
const { getThemeClass } = useDarkMode();
|
||||
return { formatMessage, getThemeClass };
|
||||
|
||||
return { formatMessage, phoneInput, getThemeClass };
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -98,7 +105,7 @@ export default {
|
||||
...field,
|
||||
type:
|
||||
field.name === 'phoneNumber'
|
||||
? 'phoneInput'
|
||||
? this.phoneInput
|
||||
: this.findFieldType(field.type),
|
||||
}));
|
||||
},
|
||||
@@ -156,8 +163,9 @@ export default {
|
||||
'dark:text-red-400'
|
||||
)}`;
|
||||
},
|
||||
inputClass(context) {
|
||||
const { hasErrors, classification, type } = context;
|
||||
inputClass(input) {
|
||||
const { state, family: classification, type } = input.context;
|
||||
const hasErrors = state.invalid;
|
||||
if (classification === 'box' && type === 'checkbox') {
|
||||
return '';
|
||||
}
|
||||
@@ -201,9 +209,7 @@ export default {
|
||||
};
|
||||
const validationKeys = Object.keys(validations);
|
||||
const isRequired = this.isContactFieldRequired(name);
|
||||
const validation = isRequired
|
||||
? ['bail', 'required']
|
||||
: ['bail', 'optional'];
|
||||
const validation = isRequired ? ['required'] : ['optional'];
|
||||
|
||||
if (
|
||||
validationKeys.includes(name) ||
|
||||
@@ -212,10 +218,13 @@ export default {
|
||||
) {
|
||||
const validationType =
|
||||
validations[type] || validations[name] || validations[field_type];
|
||||
return validationType ? validation.concat(validationType) : validation;
|
||||
const allValidations = validationType
|
||||
? validation.concat(validationType)
|
||||
: validation;
|
||||
return allValidations.join('|');
|
||||
}
|
||||
|
||||
return [];
|
||||
return '';
|
||||
},
|
||||
findFieldType(type) {
|
||||
if (type === 'link') {
|
||||
@@ -238,7 +247,7 @@ export default {
|
||||
});
|
||||
return values;
|
||||
}
|
||||
return null;
|
||||
return {};
|
||||
},
|
||||
onSubmit() {
|
||||
const { emailAddress, fullName, phoneNumber, message } = this.formValues;
|
||||
@@ -257,10 +266,16 @@ export default {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FormulateForm
|
||||
<!-- hide the default submit button for now -->
|
||||
<FormKit
|
||||
v-model="formValues"
|
||||
class="flex flex-col flex-1 p-6 overflow-y-auto"
|
||||
@submit="onSubmit"
|
||||
type="form"
|
||||
form-class="flex flex-col flex-1 w-full p-6 overflow-y-auto"
|
||||
:incomplete-message="false"
|
||||
:submit-attrs="{
|
||||
inputClass: 'hidden',
|
||||
wrapperClass: 'hidden',
|
||||
}"
|
||||
>
|
||||
<div
|
||||
v-if="shouldShowHeaderMessage"
|
||||
@@ -268,7 +283,10 @@ export default {
|
||||
class="mb-4 text-sm leading-5 pre-chat-header-message"
|
||||
:class="getThemeClass('text-black-800', 'dark:text-slate-50')"
|
||||
/>
|
||||
<FormulateInput
|
||||
<!-- Why do the v-bind shenanigan? Because Formkit API is really bad.
|
||||
If we just pass the options as is even with null or undefined or false,
|
||||
it assumes we are trying to make a multicheckbox. This is the best we have for now -->
|
||||
<FormKit
|
||||
v-for="item in enabledPreChatFields"
|
||||
:key="item.name"
|
||||
:name="item.name"
|
||||
@@ -276,7 +294,13 @@ export default {
|
||||
:label="getLabel(item)"
|
||||
:placeholder="getPlaceHolder(item)"
|
||||
:validation="getValidation(item)"
|
||||
:options="getOptions(item)"
|
||||
v-bind="
|
||||
item.type === 'select'
|
||||
? {
|
||||
options: getOptions(item),
|
||||
}
|
||||
: undefined
|
||||
"
|
||||
:label-class="context => labelClass(context)"
|
||||
:input-class="context => inputClass(context)"
|
||||
:validation-messages="{
|
||||
@@ -292,7 +316,7 @@ export default {
|
||||
}"
|
||||
:has-error-in-phone-input="hasErrorInPhoneInput"
|
||||
/>
|
||||
<FormulateInput
|
||||
<FormKit
|
||||
v-if="!hasActiveCampaign"
|
||||
name="message"
|
||||
type="textarea"
|
||||
@@ -316,44 +340,30 @@ export default {
|
||||
<Spinner v-if="isCreating" class="p-0" />
|
||||
{{ $t('START_CONVERSATION') }}
|
||||
</CustomButton>
|
||||
</FormulateForm>
|
||||
</FormKit>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~widget/assets/scss/variables.scss';
|
||||
::v-deep {
|
||||
.wrapper[data-type='checkbox'] {
|
||||
.formulate-input-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: $space-normal;
|
||||
<style lang="scss">
|
||||
.formkit-outer {
|
||||
@apply mt-2;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-left: 0.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.wrapper {
|
||||
.formulate-input-element--date,
|
||||
.formulate-input-element--checkbox {
|
||||
input {
|
||||
color-scheme: dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.wrapper[data-type='textarea'] {
|
||||
.formulate-input-element--textarea {
|
||||
textarea {
|
||||
min-height: 8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
[data-invalid] .formkit-message {
|
||||
@apply text-red-500 block text-xs font-normal mb-1 w-full;
|
||||
}
|
||||
|
||||
.formkit-outer[data-type='checkbox'] .formkit-wrapper {
|
||||
@apply flex items-center gap-2 px-0.5;
|
||||
}
|
||||
|
||||
.formkit-messages {
|
||||
@apply list-none m-0 p-0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.pre-chat-header-message {
|
||||
.link {
|
||||
color: $color-woot;
|
||||
text-decoration: underline;
|
||||
@apply text-woot-500 underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user