Files
leadchat/app/javascript/dashboard/routes/dashboard/conversation/ConversationLabels.vue
2020-02-11 19:21:55 +05:30

190 lines
4.6 KiB
Vue

<template>
<div
class="contact-conversation--panel sidebar-labels-wrap"
:class="hasEditedClass"
>
<div v-if="!conversationUiFlags.isFetching" class="wrap">
<div class="contact-conversation--list">
<label class="select-tags">
{{ $t('CONTACT_PANEL.LABELS.TITLE') }}
<p v-if="!savedLabels.length && !showLabelInput" class="no-results">
{{ $t('CONTACT_PANEL.LABELS.NO_RECORDS_FOUND') }}
<button
type="button success"
class="button nice tiny"
@click="showLabelBox"
>
{{ $t('CONTACT_PANEL.LABELS.ADD_BUTTON') }}
</button>
</p>
<multiselect
v-if="showLabelInput || savedLabels.length"
v-model="selectedLabels"
:options="savedLabels"
tag-placeholder="Add this as new tag"
placeholder="Search or add a tag"
:multiple="true"
:taggable="true"
@tag="addLabel"
/>
</label>
<div class="row align-middle align-justify">
<span v-if="labelUiFlags.isError" class="error">{{
$t('CONTACT_PANEL.LABELS.UPDATE_ERROR')
}}</span>
<button
v-if="hasEdited"
type="button"
class="button nice tiny"
@click="onUpdateLabels"
>
<spinner v-if="labelUiFlags.isUpdating" size="tiny" />
{{
labelUiFlags.isUpdating
? 'saving...'
: $t('CONTACT_PANEL.LABELS.UPDATE_BUTTON')
}}
</button>
</div>
</div>
</div>
<spinner v-else></spinner>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import Spinner from 'shared/components/Spinner';
import ConversationAPI from '../../../api/conversations';
export default {
components: {
Spinner,
},
props: {
conversationId: {
type: [String, Number],
required: true,
},
},
data() {
return {
isSearching: false,
selectedLabels: [],
showLabelInput: false,
};
},
computed: {
hasEdited() {
if (this.selectedLabels.length !== this.savedLabels.length) {
return true;
}
const isSame = this.selectedLabels.every(label =>
this.savedLabels.includes(label)
);
return !isSame;
},
savedLabels() {
const saved = this.$store.getters[
'conversationLabels/getConversationLabels'
](this.conversationId);
return saved;
},
hasEditedClass() {
return this.hasEdited ? 'has-edited' : '';
},
...mapGetters({
conversationUiFlags: 'contactConversations/getUIFlags',
labelUiFlags: 'conversationLabels/getUIFlags',
}),
},
watch: {
conversationId(newConversationId, prevConversationId) {
if (newConversationId && newConversationId !== prevConversationId) {
this.$store
.dispatch('conversationLabels/get', newConversationId)
.then(() => {
this.selectedLabels = [...this.savedLabels];
});
}
},
},
mounted() {
this.$store
.dispatch('conversationLabels/get', this.conversationId)
.then(() => {
this.selectedLabels = [...this.savedLabels];
});
},
methods: {
addLabel(label) {
this.selectedLabels = [...this.selectedLabels, label];
},
asyncSearchLabels(query) {
this.isSearching = true;
ConversationAPI(query).then(response => {
this.countries = response;
this.isLoading = false;
});
},
onUpdateLabels() {
this.$store.dispatch('conversationLabels/update', {
conversationId: this.conversationId,
labels: this.selectedLabels,
});
},
showLabelBox() {
this.showLabelInput = true;
},
},
};
</script>
<style lang="scss" scoped>
@import '~dashboard/assets/scss/variables';
@import '~dashboard/assets/scss/mixins';
.contact-conversation--panel {
padding: $space-normal;
}
.conversation--label {
color: $color-white;
margin-right: $space-small;
font-size: $font-size-small;
padding: $space-smaller;
}
.wrap {
margin-top: $space-slab;
}
.select-tags {
margin-top: $space-small;
.multiselect {
&:hover {
cursor: pointer;
}
transition: $transition-ease-in;
margin-bottom: 0;
}
}
.button {
margin-top: $space-small;
margin-left: auto;
}
.no-results {
margin: $space-normal 0 0 0;
color: $color-gray;
padding: 0 $space-small;
font-weight: $font-weight-normal;
}
.error {
color: $alert-color;
font-size: $font-size-mini;
font-weight: $font-weight-medium;
}
</style>