Skip to content

Commit

Permalink
feat: Update UX for adding label in a conversation (chatwoot#2243)
Browse files Browse the repository at this point in the history
  • Loading branch information
iamsivin authored May 17, 2021
1 parent ef26111 commit 60177ef
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 76 deletions.
1 change: 1 addition & 0 deletions app/javascript/dashboard/components/ui/Label.vue
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export default {
.label--icon,
.close--icon {
font-size: var(--font-size-micro);
cursor: pointer;
}
&.small .label--icon,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,87 +8,104 @@
: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 class="dropdown-wrap">
<div
:class="{ 'dropdown-pane--open': showSearchDropdownLabel }"
class="dropdown-pane"
>
<label-dropdown
v-if="showSearchDropdownLabel"
:account-labels="accountLabels"
:selected-labels="savedLabels"
:conversation-id="conversationId"
@add="addItem"
@remove="removeItem"
/>
</div>
</div>
</div>
<add-label-to-conversation
v-if="isEditing"
:conversation-id="conversationId"
:account-labels="accountLabels"
:saved-labels="savedLabels"
:show.sync="isEditing"
:on-close="closeEditModal"
:update-labels="onUpdateLabels"
/>
</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) {
this.fetchLabels(newConversationId);
}
},
},
mounted() {
const { conversationId } = this;
this.fetchLabels(conversationId);
},
methods: {
async onUpdateLabels(selectedLabels) {
try {
Expand All @@ -100,13 +117,28 @@ export default {
// Ignore error
}
},
onEdit() {
this.isEditing = true;
toggleLabels() {
this.showSearchDropdownLabel = !this.showSearchDropdownLabel;
},
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);
},
closeEditModal() {
bus.$emit('fetch_conversation_stats');
this.isEditing = false;
closeDropdownLabel() {
this.showSearchDropdownLabel = false;
},
async fetchLabels(conversationId) {
if (!conversationId) {
return;
Expand All @@ -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;
}
transition: $transition-ease-in;
margin-bottom: 0;
}
}
.button {
margin-top: $space-small;
margin-left: auto;
}
.label-wrap {
margin-left: var(--space-two);
position: relative;
line-height: var(--space-medium);
bottom: var(--space-small);
.no-results-wrap {
padding: 0 $space-small;
}
.dropdown-wrap {
display: flex;
position: absolute;
margin-right: var(--space-medium);
top: var(--space-medium);
width: 100%;
left: -1px;
.no-results {
margin: $space-normal 0 0 0;
color: $color-gray;
font-weight: $font-weight-normal;
.dropdown-pane {
width: 100%;
box-sizing: border-box;
}
}
}
}
.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>
33 changes: 21 additions & 12 deletions app/javascript/shared/components/ui/dropdown/AddLabel.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
<template>
<div>
<woot-button
variant="hollow"
size="tiny"
icon="ion-plus-round"
color-scheme="secondary"
@click="toggleLabels"
>
{{ $t('CONTACT_PANEL.LABELS.MODAL.ADD_BUTTON') }}
</woot-button>
</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>
</template>

<script>
Expand All @@ -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>

0 comments on commit 60177ef

Please sign in to comment.