mirror of
https://github.com/lingble/chatwoot.git
synced 2025-10-29 18:22:53 +00:00
feat: Update UX for adding label in a conversation (#2243)
This commit is contained in:
@@ -89,6 +89,7 @@ export default {
|
||||
.label--icon,
|
||||
.close--icon {
|
||||
font-size: var(--font-size-micro);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.small .label--icon,
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
</multiselect>
|
||||
</div>
|
||||
</div>
|
||||
<conversation-labels :conversation-id="conversationId" />
|
||||
<div v-if="browser.browser_name" class="conversation--details">
|
||||
<contact-details-item
|
||||
v-if="location"
|
||||
@@ -105,7 +106,6 @@
|
||||
v-if="hasContactAttributes"
|
||||
:custom-attributes="contact.custom_attributes"
|
||||
/>
|
||||
<conversation-labels :conversation-id="conversationId" />
|
||||
<contact-conversations
|
||||
v-if="contact.id"
|
||||
:contact-id="contact.id"
|
||||
@@ -359,7 +359,7 @@ export default {
|
||||
}
|
||||
|
||||
.conversation--actions {
|
||||
padding: 0 var(--space-normal) var(--space-small);
|
||||
padding: 0 var(--space-normal) var(--space-smaller);
|
||||
}
|
||||
|
||||
.multiselect__label {
|
||||
|
||||
@@ -8,76 +8,91 @@
|
||||
:title="$t('CONTACT_PANEL.LABELS.TITLE')"
|
||||
icon="ion-pricetags"
|
||||
emoji="🏷️"
|
||||
:show-edit="true"
|
||||
@edit="onEdit"
|
||||
/>
|
||||
<div class="label-wrap">
|
||||
<div v-on-clickaway="closeDropdownLabel" class="label-wrap">
|
||||
<add-label @add="toggleLabels" />
|
||||
<woot-label
|
||||
v-for="label in activeLabels"
|
||||
:key="label.id"
|
||||
:title="label.title"
|
||||
:description="label.description"
|
||||
:show-close="true"
|
||||
:bg-color="label.color"
|
||||
@click="removeItem"
|
||||
/>
|
||||
<div v-if="!activeLabels.length" class="no-label-message">
|
||||
<span>{{ $t('CONTACT_PANEL.LABELS.NO_AVAILABLE_LABELS') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<add-label-to-conversation
|
||||
v-if="isEditing"
|
||||
:conversation-id="conversationId"
|
||||
|
||||
<div class="dropdown-wrap">
|
||||
<div
|
||||
:class="{ 'dropdown-pane--open': showSearchDropdownLabel }"
|
||||
class="dropdown-pane"
|
||||
>
|
||||
<label-dropdown
|
||||
v-if="showSearchDropdownLabel"
|
||||
:account-labels="accountLabels"
|
||||
:saved-labels="savedLabels"
|
||||
:show.sync="isEditing"
|
||||
:on-close="closeEditModal"
|
||||
:update-labels="onUpdateLabels"
|
||||
:selected-labels="savedLabels"
|
||||
:conversation-id="conversationId"
|
||||
@add="addItem"
|
||||
@remove="removeItem"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<spinner v-else></spinner>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import AddLabelToConversation from './AddLabelToConversation';
|
||||
import ContactDetailsItem from '../ContactDetailsItem';
|
||||
import Spinner from 'shared/components/Spinner';
|
||||
import LabelDropdown from 'shared/components/ui/label/LabelDropdown';
|
||||
import AddLabel from 'shared/components/ui/dropdown/AddLabel';
|
||||
import { mixin as clickaway } from 'vue-clickaway';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AddLabelToConversation,
|
||||
ContactDetailsItem,
|
||||
Spinner,
|
||||
LabelDropdown,
|
||||
AddLabel,
|
||||
},
|
||||
|
||||
mixins: [clickaway],
|
||||
props: {
|
||||
conversationId: {
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
isEditing: false,
|
||||
selectedLabels: [],
|
||||
showSearchDropdownLabel: false,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
savedLabels() {
|
||||
return this.$store.getters['conversationLabels/getConversationLabels'](
|
||||
this.conversationId
|
||||
);
|
||||
},
|
||||
|
||||
...mapGetters({
|
||||
conversationUiFlags: 'contactConversations/getUIFlags',
|
||||
labelUiFlags: 'conversationLabels/getUIFlags',
|
||||
accountLabels: 'labels/getLabels',
|
||||
}),
|
||||
|
||||
activeLabels() {
|
||||
return this.accountLabels.filter(({ title }) =>
|
||||
this.savedLabels.includes(title)
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
conversationId(newConversationId, prevConversationId) {
|
||||
if (newConversationId && newConversationId !== prevConversationId) {
|
||||
@@ -85,10 +100,12 @@ export default {
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
const { conversationId } = this;
|
||||
this.fetchLabels(conversationId);
|
||||
},
|
||||
|
||||
methods: {
|
||||
async onUpdateLabels(selectedLabels) {
|
||||
try {
|
||||
@@ -100,13 +117,28 @@ export default {
|
||||
// Ignore error
|
||||
}
|
||||
},
|
||||
onEdit() {
|
||||
this.isEditing = true;
|
||||
|
||||
toggleLabels() {
|
||||
this.showSearchDropdownLabel = !this.showSearchDropdownLabel;
|
||||
},
|
||||
closeEditModal() {
|
||||
bus.$emit('fetch_conversation_stats');
|
||||
this.isEditing = false;
|
||||
|
||||
addItem(value) {
|
||||
const result = this.activeLabels.map(item => item.title);
|
||||
result.push(value.title);
|
||||
this.onUpdateLabels(result);
|
||||
},
|
||||
|
||||
removeItem(value) {
|
||||
const result = this.activeLabels
|
||||
.map(label => label.title)
|
||||
.filter(label => label !== value);
|
||||
this.onUpdateLabels(result);
|
||||
},
|
||||
|
||||
closeDropdownLabel() {
|
||||
this.showSearchDropdownLabel = false;
|
||||
},
|
||||
|
||||
async fetchLabels(conversationId) {
|
||||
if (!conversationId) {
|
||||
return;
|
||||
@@ -122,53 +154,38 @@ export default {
|
||||
@import '~dashboard/assets/scss/mixins';
|
||||
|
||||
.contact-conversation--panel {
|
||||
padding: var(--space-medium) var(--space-slab) var(--space-two);
|
||||
padding: var(--space-micro) var(--space-slab) var(--space-one)
|
||||
var(--space-slab);
|
||||
}
|
||||
|
||||
.contact-conversation--list .conv-details--item {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.conversation--label {
|
||||
color: $color-white;
|
||||
margin-right: $space-small;
|
||||
font-size: $font-size-small;
|
||||
padding: $space-smaller;
|
||||
}
|
||||
.label-wrap {
|
||||
margin-left: var(--space-medium);
|
||||
}
|
||||
.no-label-message {
|
||||
color: var(--b-500);
|
||||
}
|
||||
.contact-conversation--list {
|
||||
width: 100%;
|
||||
|
||||
.select-tags {
|
||||
.multiselect {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
.label-wrap {
|
||||
margin-left: var(--space-two);
|
||||
position: relative;
|
||||
line-height: var(--space-medium);
|
||||
bottom: var(--space-small);
|
||||
|
||||
.dropdown-wrap {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
margin-right: var(--space-medium);
|
||||
top: var(--space-medium);
|
||||
width: 100%;
|
||||
left: -1px;
|
||||
|
||||
.dropdown-pane {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
transition: $transition-ease-in;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-top: $space-small;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.no-results-wrap {
|
||||
padding: 0 $space-small;
|
||||
}
|
||||
|
||||
.no-results {
|
||||
margin: $space-normal 0 0 0;
|
||||
color: $color-gray;
|
||||
font-weight: $font-weight-normal;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: $alert-color;
|
||||
font-size: $font-size-mini;
|
||||
font-weight: $font-weight-medium;
|
||||
color: var(--r-500);
|
||||
font-size: var(--font-size-mini);
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
<template>
|
||||
<div>
|
||||
<woot-button
|
||||
variant="hollow"
|
||||
size="tiny"
|
||||
icon="ion-plus-round"
|
||||
color-scheme="secondary"
|
||||
class-names="button-wrap"
|
||||
@click="toggleLabels"
|
||||
>
|
||||
{{ $t('CONTACT_PANEL.LABELS.MODAL.ADD_BUTTON') }}
|
||||
</woot-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -22,4 +21,14 @@ export default {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.button-wrap {
|
||||
padding: var(--space-micro) var(--space-small);
|
||||
display: inline;
|
||||
line-height: 1.2;
|
||||
|
||||
&::v-deep .icon {
|
||||
font-size: var(--font-size-mini);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user