fix: apply ESLint rule vue/component-tags-order
This commit is contained in:
@@ -1,41 +1,3 @@
|
||||
<!-- eslint-disable vue/no-mutating-props -->
|
||||
<template>
|
||||
<modal :show.sync="show" :on-close="onClose">
|
||||
<woot-modal-header
|
||||
:header-title="$t('CUSTOM_ATTRIBUTES.ADD.TITLE')"
|
||||
:header-content="$t('CUSTOM_ATTRIBUTES.ADD.DESC')"
|
||||
/>
|
||||
<form class="w-full" @submit.prevent="addCustomAttribute">
|
||||
<woot-input
|
||||
v-model.trim="attributeName"
|
||||
:class="{ error: v$.attributeName.$error }"
|
||||
class="w-full"
|
||||
:error="attributeNameError"
|
||||
:label="$t('CUSTOM_ATTRIBUTES.FORM.NAME.LABEL')"
|
||||
:placeholder="$t('CUSTOM_ATTRIBUTES.FORM.NAME.PLACEHOLDER')"
|
||||
@input="v$.attributeName.$touch"
|
||||
/>
|
||||
<woot-input
|
||||
v-model.trim="attributeValue"
|
||||
class="w-full"
|
||||
:label="$t('CUSTOM_ATTRIBUTES.FORM.VALUE.LABEL')"
|
||||
:placeholder="$t('CUSTOM_ATTRIBUTES.FORM.VALUE.PLACEHOLDER')"
|
||||
/>
|
||||
<div class="flex items-center justify-end gap-2 px-0 py-2">
|
||||
<woot-button
|
||||
:is-disabled="v$.attributeName.$invalid || isCreating"
|
||||
:is-loading="isCreating"
|
||||
>
|
||||
{{ $t('CUSTOM_ATTRIBUTES.FORM.CREATE') }}
|
||||
</woot-button>
|
||||
<woot-button variant="clear" @click.prevent="onClose">
|
||||
{{ $t('CUSTOM_ATTRIBUTES.FORM.CANCEL') }}
|
||||
</woot-button>
|
||||
</div>
|
||||
</form>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Modal from 'dashboard/components/Modal.vue';
|
||||
import { useVuelidate } from '@vuelidate/core';
|
||||
@@ -98,3 +60,41 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- eslint-disable vue/no-mutating-props -->
|
||||
<template>
|
||||
<modal :show.sync="show" :on-close="onClose">
|
||||
<woot-modal-header
|
||||
:header-title="$t('CUSTOM_ATTRIBUTES.ADD.TITLE')"
|
||||
:header-content="$t('CUSTOM_ATTRIBUTES.ADD.DESC')"
|
||||
/>
|
||||
<form class="w-full" @submit.prevent="addCustomAttribute">
|
||||
<woot-input
|
||||
v-model.trim="attributeName"
|
||||
:class="{ error: v$.attributeName.$error }"
|
||||
class="w-full"
|
||||
:error="attributeNameError"
|
||||
:label="$t('CUSTOM_ATTRIBUTES.FORM.NAME.LABEL')"
|
||||
:placeholder="$t('CUSTOM_ATTRIBUTES.FORM.NAME.PLACEHOLDER')"
|
||||
@input="v$.attributeName.$touch"
|
||||
/>
|
||||
<woot-input
|
||||
v-model.trim="attributeValue"
|
||||
class="w-full"
|
||||
:label="$t('CUSTOM_ATTRIBUTES.FORM.VALUE.LABEL')"
|
||||
:placeholder="$t('CUSTOM_ATTRIBUTES.FORM.VALUE.PLACEHOLDER')"
|
||||
/>
|
||||
<div class="flex items-center justify-end gap-2 px-0 py-2">
|
||||
<woot-button
|
||||
:is-disabled="v$.attributeName.$invalid || isCreating"
|
||||
:is-loading="isCreating"
|
||||
>
|
||||
{{ $t('CUSTOM_ATTRIBUTES.FORM.CREATE') }}
|
||||
</woot-button>
|
||||
<woot-button variant="clear" @click.prevent="onClose">
|
||||
{{ $t('CUSTOM_ATTRIBUTES.FORM.CANCEL') }}
|
||||
</woot-button>
|
||||
</div>
|
||||
</form>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
@@ -1,3 +1,41 @@
|
||||
<script>
|
||||
import EmojiOrIcon from 'shared/components/EmojiOrIcon.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EmojiOrIcon,
|
||||
},
|
||||
props: {
|
||||
label: { type: String, required: true },
|
||||
icon: { type: String, default: '' },
|
||||
emoji: { type: String, default: '' },
|
||||
value: { type: [String, Number], default: '' },
|
||||
showEdit: { type: Boolean, default: false },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isEditing: false,
|
||||
editedValue: this.value,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
focusInput() {
|
||||
this.$refs.inputfield.focus();
|
||||
},
|
||||
onEdit() {
|
||||
this.isEditing = true;
|
||||
this.$nextTick(() => {
|
||||
this.focusInput();
|
||||
});
|
||||
},
|
||||
onUpdate() {
|
||||
this.isEditing = false;
|
||||
this.$emit('update', this.editedValue);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="contact-attribute">
|
||||
<div class="title-wrap">
|
||||
@@ -49,44 +87,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import EmojiOrIcon from 'shared/components/EmojiOrIcon.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EmojiOrIcon,
|
||||
},
|
||||
props: {
|
||||
label: { type: String, required: true },
|
||||
icon: { type: String, default: '' },
|
||||
emoji: { type: String, default: '' },
|
||||
value: { type: [String, Number], default: '' },
|
||||
showEdit: { type: Boolean, default: false },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isEditing: false,
|
||||
editedValue: this.value,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
focusInput() {
|
||||
this.$refs.inputfield.focus();
|
||||
},
|
||||
onEdit() {
|
||||
this.isEditing = true;
|
||||
this.$nextTick(() => {
|
||||
this.focusInput();
|
||||
});
|
||||
},
|
||||
onUpdate() {
|
||||
this.isEditing = false;
|
||||
this.$emit('update', this.editedValue);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.contact-attribute {
|
||||
margin-bottom: var(--space-small);
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
<template>
|
||||
<div class="option-item--user">
|
||||
<thumbnail :src="thumbnail" size="28px" :username="name" />
|
||||
<div class="option__user-data">
|
||||
<h5 class="option__title">
|
||||
{{ name }}
|
||||
<span v-if="identifier" class="user-identifier">
|
||||
(ID: {{ identifier }})
|
||||
</span>
|
||||
</h5>
|
||||
<p class="option__body">
|
||||
<span v-if="email" class="email-icon-wrap">
|
||||
<fluent-icon class="merge-contact--icon" icon="mail" size="12" />
|
||||
{{ email }}
|
||||
</span>
|
||||
<span v-if="phoneNumber" class="phone-icon-wrap">
|
||||
<fluent-icon class="merge-contact--icon" icon="call" size="12" />
|
||||
{{ phoneNumber }}
|
||||
</span>
|
||||
<span v-if="!phoneNumber && !email">{{ '---' }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Thumbnail from '../../../components/widgets/Thumbnail.vue';
|
||||
|
||||
@@ -55,6 +30,31 @@ export default {
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="option-item--user">
|
||||
<thumbnail :src="thumbnail" size="28px" :username="name" />
|
||||
<div class="option__user-data">
|
||||
<h5 class="option__title">
|
||||
{{ name }}
|
||||
<span v-if="identifier" class="user-identifier">
|
||||
(ID: {{ identifier }})
|
||||
</span>
|
||||
</h5>
|
||||
<p class="option__body">
|
||||
<span v-if="email" class="email-icon-wrap">
|
||||
<fluent-icon class="merge-contact--icon" icon="mail" size="12" />
|
||||
{{ email }}
|
||||
</span>
|
||||
<span v-if="phoneNumber" class="phone-icon-wrap">
|
||||
<fluent-icon class="merge-contact--icon" icon="call" size="12" />
|
||||
{{ phoneNumber }}
|
||||
</span>
|
||||
<span v-if="!phoneNumber && !email">{{ '---' }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.option-item--user {
|
||||
@apply flex items-center;
|
||||
|
||||
@@ -1,3 +1,53 @@
|
||||
<script>
|
||||
import Attribute from './ContactAttribute.vue';
|
||||
|
||||
export default {
|
||||
components: { Attribute },
|
||||
props: {
|
||||
contact: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
additionalAttributes() {
|
||||
return this.contact.additional_attributes || {};
|
||||
},
|
||||
company() {
|
||||
const { company = {} } = this.contact;
|
||||
return company;
|
||||
},
|
||||
customAttributes() {
|
||||
const { custom_attributes: customAttributes = {} } = this.contact;
|
||||
return customAttributes;
|
||||
},
|
||||
customAttributekeys() {
|
||||
return Object.keys(this.customAttributes).filter(key => {
|
||||
const value = this.customAttributes[key];
|
||||
return value !== null && value !== undefined;
|
||||
});
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onEmailUpdate(value) {
|
||||
this.$emit('update', { email: value });
|
||||
},
|
||||
onPhoneUpdate(value) {
|
||||
this.$emit('update', { phone_number: value });
|
||||
},
|
||||
onLocationUpdate(value) {
|
||||
this.$emit('update', { location: value });
|
||||
},
|
||||
handleCustomCreate() {
|
||||
this.$emit('create-attribute');
|
||||
},
|
||||
onCustomAttributeUpdate(key, value) {
|
||||
this.$emit('update', { custom_attributes: { [key]: value } });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="contact-fields">
|
||||
<h3 class="text-lg title">
|
||||
@@ -51,56 +101,6 @@
|
||||
</woot-button>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Attribute from './ContactAttribute.vue';
|
||||
|
||||
export default {
|
||||
components: { Attribute },
|
||||
props: {
|
||||
contact: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
additionalAttributes() {
|
||||
return this.contact.additional_attributes || {};
|
||||
},
|
||||
company() {
|
||||
const { company = {} } = this.contact;
|
||||
return company;
|
||||
},
|
||||
customAttributes() {
|
||||
const { custom_attributes: customAttributes = {} } = this.contact;
|
||||
return customAttributes;
|
||||
},
|
||||
customAttributekeys() {
|
||||
return Object.keys(this.customAttributes).filter(key => {
|
||||
const value = this.customAttributes[key];
|
||||
return value !== null && value !== undefined;
|
||||
});
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onEmailUpdate(value) {
|
||||
this.$emit('update', { email: value });
|
||||
},
|
||||
onPhoneUpdate(value) {
|
||||
this.$emit('update', { phone_number: value });
|
||||
},
|
||||
onLocationUpdate(value) {
|
||||
this.$emit('update', { location: value });
|
||||
},
|
||||
handleCustomCreate() {
|
||||
this.$emit('create-attribute');
|
||||
},
|
||||
onCustomAttributeUpdate(key, value) {
|
||||
this.$emit('update', { custom_attributes: { [key]: value } });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.contact-fields {
|
||||
|
||||
@@ -1,46 +1,3 @@
|
||||
<template>
|
||||
<div class="contact--intro">
|
||||
<thumbnail
|
||||
:src="contact.thumbnail"
|
||||
size="64px"
|
||||
:username="contact.name"
|
||||
:status="contact.availability_status"
|
||||
/>
|
||||
|
||||
<div class="contact--details">
|
||||
<h2 class="text-lg contact--name">
|
||||
{{ contact.name }}
|
||||
</h2>
|
||||
<h3 class="text-base contact--work">
|
||||
{{ contact.title }}
|
||||
<i v-if="company.name" class="icon ion-minus-round" />
|
||||
<span class="company-name">{{ company.name }}</span>
|
||||
</h3>
|
||||
<p v-if="additionalAttributes.description" class="contact--bio">
|
||||
{{ additionalAttributes.description }}
|
||||
</p>
|
||||
<social-icons :social-profiles="socialProfiles" />
|
||||
</div>
|
||||
<div class="contact-actions">
|
||||
<woot-button
|
||||
class="new-message"
|
||||
size="small expanded"
|
||||
icon="ion-paper-airplane"
|
||||
@click="onNewMessageClick"
|
||||
>
|
||||
{{ $t('CONTACT_PANEL.NEW_MESSAGE') }}
|
||||
</woot-button>
|
||||
<woot-button
|
||||
variant="hollow"
|
||||
size="small expanded"
|
||||
icon="edit"
|
||||
@click="onEditClick"
|
||||
>
|
||||
{{ $t('EDIT_CONTACT.BUTTON_LABEL') }}
|
||||
</woot-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
|
||||
import SocialIcons from 'dashboard/routes/dashboard/conversation/contact/SocialIcons.vue';
|
||||
@@ -84,6 +41,49 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="contact--intro">
|
||||
<thumbnail
|
||||
:src="contact.thumbnail"
|
||||
size="64px"
|
||||
:username="contact.name"
|
||||
:status="contact.availability_status"
|
||||
/>
|
||||
|
||||
<div class="contact--details">
|
||||
<h2 class="text-lg contact--name">
|
||||
{{ contact.name }}
|
||||
</h2>
|
||||
<h3 class="text-base contact--work">
|
||||
{{ contact.title }}
|
||||
<i v-if="company.name" class="icon ion-minus-round" />
|
||||
<span class="company-name">{{ company.name }}</span>
|
||||
</h3>
|
||||
<p v-if="additionalAttributes.description" class="contact--bio">
|
||||
{{ additionalAttributes.description }}
|
||||
</p>
|
||||
<social-icons :social-profiles="socialProfiles" />
|
||||
</div>
|
||||
<div class="contact-actions">
|
||||
<woot-button
|
||||
class="new-message"
|
||||
size="small expanded"
|
||||
icon="ion-paper-airplane"
|
||||
@click="onNewMessageClick"
|
||||
>
|
||||
{{ $t('CONTACT_PANEL.NEW_MESSAGE') }}
|
||||
</woot-button>
|
||||
<woot-button
|
||||
variant="hollow"
|
||||
size="small expanded"
|
||||
icon="edit"
|
||||
@click="onEditClick"
|
||||
>
|
||||
{{ $t('EDIT_CONTACT.BUTTON_LABEL') }}
|
||||
</woot-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.contact--details {
|
||||
|
||||
@@ -1,34 +1,3 @@
|
||||
<template>
|
||||
<div class="panel">
|
||||
<contact-intro
|
||||
:contact="contact"
|
||||
@message="toggleConversationModal"
|
||||
@edit="toggleEditModal"
|
||||
/>
|
||||
<contact-fields
|
||||
:contact="contact"
|
||||
@update="updateField"
|
||||
@create-attribute="toggleCustomAttributeModal"
|
||||
/>
|
||||
<edit-contact
|
||||
v-if="showEditModal"
|
||||
:show="showEditModal"
|
||||
:contact="contact"
|
||||
@cancel="toggleEditModal"
|
||||
/>
|
||||
<new-conversation
|
||||
v-if="enableNewConversation"
|
||||
:show="showConversationModal"
|
||||
:contact="contact"
|
||||
@cancel="toggleConversationModal"
|
||||
/>
|
||||
<add-custom-attribute
|
||||
:show="showCustomAttributeModal"
|
||||
@cancel="toggleCustomAttributeModal"
|
||||
@create="createCustomAttribute"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import EditContact from 'dashboard/routes/dashboard/conversation/contact/EditContact.vue';
|
||||
import NewConversation from 'dashboard/routes/dashboard/conversation/contact/NewConversation.vue';
|
||||
@@ -97,6 +66,37 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="panel">
|
||||
<contact-intro
|
||||
:contact="contact"
|
||||
@message="toggleConversationModal"
|
||||
@edit="toggleEditModal"
|
||||
/>
|
||||
<contact-fields
|
||||
:contact="contact"
|
||||
@update="updateField"
|
||||
@create-attribute="toggleCustomAttributeModal"
|
||||
/>
|
||||
<edit-contact
|
||||
v-if="showEditModal"
|
||||
:show="showEditModal"
|
||||
:contact="contact"
|
||||
@cancel="toggleEditModal"
|
||||
/>
|
||||
<new-conversation
|
||||
v-if="enableNewConversation"
|
||||
:show="showConversationModal"
|
||||
:contact="contact"
|
||||
@cancel="toggleConversationModal"
|
||||
/>
|
||||
<add-custom-attribute
|
||||
:show="showCustomAttributeModal"
|
||||
@cancel="toggleCustomAttributeModal"
|
||||
@create="createCustomAttribute"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.panel {
|
||||
|
||||
@@ -1,3 +1,70 @@
|
||||
<script>
|
||||
import { useVuelidate } from '@vuelidate/core';
|
||||
import { required } from '@vuelidate/validators';
|
||||
|
||||
import MergeContactSummary from 'dashboard/modules/contact/components/MergeContactSummary.vue';
|
||||
import ContactDropdownItem from './ContactDropdownItem.vue';
|
||||
|
||||
export default {
|
||||
components: { MergeContactSummary, ContactDropdownItem },
|
||||
props: {
|
||||
primaryContact: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
isSearching: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isMerging: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
searchResults: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
return { v$: useVuelidate() };
|
||||
},
|
||||
validations: {
|
||||
primaryContact: {
|
||||
required,
|
||||
},
|
||||
parentContact: {
|
||||
required,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
parentContact: undefined,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
parentContactName() {
|
||||
return this.parentContact ? this.parentContact.name : '';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
searchChange(query) {
|
||||
this.$emit('search', query);
|
||||
},
|
||||
onSubmit() {
|
||||
this.v$.$touch();
|
||||
if (this.v$.$invalid) {
|
||||
return;
|
||||
}
|
||||
this.$emit('submit', this.parentContact.id);
|
||||
},
|
||||
onCancel() {
|
||||
this.$emit('cancel');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form @submit.prevent="onSubmit">
|
||||
<div>
|
||||
@@ -113,73 +180,6 @@
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useVuelidate } from '@vuelidate/core';
|
||||
import { required } from '@vuelidate/validators';
|
||||
|
||||
import MergeContactSummary from 'dashboard/modules/contact/components/MergeContactSummary.vue';
|
||||
import ContactDropdownItem from './ContactDropdownItem.vue';
|
||||
|
||||
export default {
|
||||
components: { MergeContactSummary, ContactDropdownItem },
|
||||
props: {
|
||||
primaryContact: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
isSearching: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isMerging: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
searchResults: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
return { v$: useVuelidate() };
|
||||
},
|
||||
validations: {
|
||||
primaryContact: {
|
||||
required,
|
||||
},
|
||||
parentContact: {
|
||||
required,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
parentContact: undefined,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
parentContactName() {
|
||||
return this.parentContact ? this.parentContact.name : '';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
searchChange(query) {
|
||||
this.$emit('search', query);
|
||||
},
|
||||
onSubmit() {
|
||||
this.v$.$touch();
|
||||
if (this.v$.$invalid) {
|
||||
return;
|
||||
}
|
||||
this.$emit('submit', this.parentContact.id);
|
||||
},
|
||||
onCancel() {
|
||||
this.$emit('cancel');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* TDOD: Clean errors in forms style */
|
||||
.error .message {
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
primaryContactName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
parentContactName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-if="parentContactName"
|
||||
@@ -31,18 +46,3 @@
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
primaryContactName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
parentContactName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user