Improves UX for conversation watchers
This commit is contained in:
parent
db2d87195a
commit
6ad52e1426
3 changed files with 115 additions and 47 deletions
|
@ -343,11 +343,6 @@
|
|||
"SUCCESS_MESSAGE": "Contact merged successfully",
|
||||
"ERROR_MESSAGE": "Could not merge contacts, try again!"
|
||||
}
|
||||
},
|
||||
"CONVERSATION_WATCHERS": {
|
||||
"NO_RECORDS_FOUND": "No results found",
|
||||
"ADD_WATCHERS": "Select watchers",
|
||||
"REMANING_WATCHERS_TEXT": "+%{count} others",
|
||||
"TOTAL_WATCHERS_TEXT": "%{count} people are watching."
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -239,5 +239,20 @@
|
|||
"BCC": "Bcc",
|
||||
"CC": "Cc",
|
||||
"SUBJECT": "Subject"
|
||||
},
|
||||
"CONVERSATION_WATCHERS": {
|
||||
"NO_RECORDS_FOUND": "No results found",
|
||||
"ADD_WATCHERS": "Select watchers",
|
||||
"REMANING_WATCHERS_TEXT": "+%{count} others",
|
||||
"REMANING_WATCHER_TEXT": "+%{count} other",
|
||||
"TOTAL_WATCHERS_TEXT": "%{count} people are watching.",
|
||||
"TOTAL_WATCHER_TEXT": "%{count} person is watching.",
|
||||
"NO_WATCHERS_TEXT": "No one is watching!.",
|
||||
"WATCH_CONVERSATION": "Watch conversation",
|
||||
"YOU_ARE_WATCHING": "You are watching this",
|
||||
"API": {
|
||||
"ERROR_MESSAGE": "Could not update, try again!",
|
||||
"SUCCESS_MESSAGE": "Watchers updated!"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,17 +3,16 @@
|
|||
<div class="subscribers--collapsed">
|
||||
<div class="content-wrap">
|
||||
<div>
|
||||
<ThumbnailGroup
|
||||
:more-thumbnails-text="
|
||||
$t('CONVERSATION_WATCHERS.REMANING_WATCHERS_TEXT', {
|
||||
agentCount: moreAgentCount,
|
||||
})
|
||||
"
|
||||
:users-list="participantList"
|
||||
/>
|
||||
<p v-if="watchersList.length" class="total-watchers">
|
||||
<spinner v-if="watchersUiFlas.isFetching" size="tiny" />
|
||||
{{ totalWatchersText }}
|
||||
</p>
|
||||
<p v-else class="text-muted">
|
||||
{{ $t('CONVERSATION_WATCHERS.NO_WATCHERS_TEXT') }}
|
||||
</p>
|
||||
</div>
|
||||
<woot-button
|
||||
v-tooltip.top-end="$t('CONVERSATION_WATCHERS.ADD_WATCHERS')"
|
||||
v-tooltip.left="$t('CONVERSATION_WATCHERS.ADD_WATCHERS')"
|
||||
:title="$t('CONVERSATION_WATCHERS.ADD_WATCHERS')"
|
||||
icon="settings"
|
||||
size="tiny"
|
||||
|
@ -23,14 +22,24 @@
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p class="total-watchers">
|
||||
{{
|
||||
$t('CONVERSATION_WATCHERS.TOTAL_WATCHERS_TEXT', {
|
||||
count: selectedParticipants.length,
|
||||
})
|
||||
}}
|
||||
<div class="actions">
|
||||
<thumbnail-group
|
||||
:more-thumbnails-text="moreThumbnailsText"
|
||||
:show-more-thumbnails-count="showMoreThumbs"
|
||||
:users-list="thumbnailList"
|
||||
/>
|
||||
<p v-if="isUserWatching" class="text-muted">
|
||||
{{ $t('CONVERSATION_WATCHERS.YOU_ARE_WATCHING') }}
|
||||
</p>
|
||||
<woot-button
|
||||
v-else
|
||||
icon="arrow-right"
|
||||
variant="link"
|
||||
size="small"
|
||||
@click="onSelfAssign"
|
||||
>
|
||||
{{ $t('CONVERSATION_WATCHERS.WATCH_CONVERSATION') }}
|
||||
</woot-button>
|
||||
</div>
|
||||
<div
|
||||
v-on-clickaway="
|
||||
|
@ -55,7 +64,7 @@
|
|||
</div>
|
||||
<multiselect-dropdown-items
|
||||
:options="agentList"
|
||||
:selected-items="selectedParticipants"
|
||||
:selected-items="selectedWatchers"
|
||||
:has-thumbnail="true"
|
||||
@click="onClickItem"
|
||||
/>
|
||||
|
@ -65,16 +74,19 @@
|
|||
|
||||
<script>
|
||||
import { mixin as clickaway } from 'vue-clickaway';
|
||||
import Spinner from 'shared/components/Spinner';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import { mapGetters } from 'vuex';
|
||||
import ThumbnailGroup from 'dashboard/components/widgets/ThumbnailGroup';
|
||||
import MultiselectDropdownItems from 'shared/components/ui/MultiselectDropdownItems';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Spinner,
|
||||
ThumbnailGroup,
|
||||
MultiselectDropdownItems,
|
||||
},
|
||||
mixins: [clickaway],
|
||||
mixins: [alertMixin, clickaway],
|
||||
props: {
|
||||
conversationId: {
|
||||
type: [Number, String],
|
||||
|
@ -87,41 +99,73 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
selectedParticipants: [],
|
||||
selectedWatchers: [],
|
||||
showDropDown: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
agentList: 'agents/getAgents',
|
||||
watchersUiFlas: 'conversationWatchers/getUIFlags',
|
||||
currentUser: 'getCurrentUser',
|
||||
}),
|
||||
participantsFromStore() {
|
||||
watchersFromStore() {
|
||||
return this.$store.getters['conversationWatchers/getByConversationId'](
|
||||
this.conversationId
|
||||
);
|
||||
},
|
||||
participantList: {
|
||||
watchersList: {
|
||||
get() {
|
||||
return this.selectedParticipants;
|
||||
return this.selectedWatchers;
|
||||
},
|
||||
set(participants) {
|
||||
this.selectedParticipants = [...participants];
|
||||
this.selectedWatchers = [...participants];
|
||||
const userIds = participants.map(el => el.id);
|
||||
this.updateParticipant(userIds);
|
||||
},
|
||||
},
|
||||
isUserWatching() {
|
||||
return this.selectedWatchers.some(
|
||||
watcher => watcher.id === this.currentUser.id
|
||||
);
|
||||
},
|
||||
thumbnailList() {
|
||||
return this.selectedWatchers.slice(0, 4);
|
||||
},
|
||||
moreAgentCount() {
|
||||
const maxThumbnailCount = 4;
|
||||
return this.participantList.length - maxThumbnailCount;
|
||||
return this.watchersList.length - maxThumbnailCount;
|
||||
},
|
||||
moreThumbnailsText() {
|
||||
if (this.moreAgentCount > 1) {
|
||||
return this.$t('CONVERSATION_WATCHERS.REMANING_WATCHERS_TEXT', {
|
||||
count: this.moreAgentCount,
|
||||
});
|
||||
}
|
||||
return this.$t('CONVERSATION_WATCHERS.REMANING_WATCHER_TEXT', {
|
||||
count: 1,
|
||||
});
|
||||
},
|
||||
showMoreThumbs() {
|
||||
return this.moreAgentCount > 0;
|
||||
},
|
||||
totalWatchersText() {
|
||||
if (this.selectedWatchers.length > 1) {
|
||||
return this.$t('CONVERSATION_WATCHERS.TOTAL_WATCHERS_TEXT', {
|
||||
count: this.selectedWatchers.length,
|
||||
});
|
||||
}
|
||||
return this.$t('CONVERSATION_WATCHERS.TOTAL_WATCHER_TEXT', {
|
||||
count: 1,
|
||||
});
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
conversationId() {
|
||||
this.$store.dispatch('conversationWatchers/clear');
|
||||
this.fetchParticipants();
|
||||
},
|
||||
participantsFromStore(participants) {
|
||||
this.selectedParticipants = [...participants];
|
||||
watchersFromStore(participants) {
|
||||
this.selectedWatchers = [...participants];
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
@ -130,14 +174,24 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
fetchParticipants() {
|
||||
this.$store.dispatch('conversationWatchers/show', this.conversationId);
|
||||
const conversationId = this.conversationId;
|
||||
this.$store.dispatch('conversationWatchers/show', { conversationId });
|
||||
},
|
||||
async updateParticipant(userIds) {
|
||||
await this.$store.dispatch('conversationWatchers/update', {
|
||||
conversationId: this.conversationId,
|
||||
// Move to camel case
|
||||
user_ids: userIds,
|
||||
});
|
||||
const conversationId = this.conversationId;
|
||||
let alertMessage = this.$t('CONVERSATION_WATCHERS.API.SUCCESS_MESSAGE');
|
||||
|
||||
try {
|
||||
await this.$store.dispatch('conversationWatchers/update', {
|
||||
conversationId,
|
||||
userIds,
|
||||
});
|
||||
} catch (error) {
|
||||
alertMessage =
|
||||
error?.message || this.$t('CONVERSATION_WATCHERS.API.ERROR_MESSAGE');
|
||||
} finally {
|
||||
this.showAlert(alertMessage);
|
||||
}
|
||||
this.fetchParticipants();
|
||||
},
|
||||
onOpenDropdown() {
|
||||
|
@ -147,20 +201,23 @@ export default {
|
|||
this.showDropDown = false;
|
||||
},
|
||||
onClickItem(agent) {
|
||||
const isAgentSelected = this.participantList.some(
|
||||
const isAgentSelected = this.watchersList.some(
|
||||
participant => participant.id === agent.id
|
||||
);
|
||||
|
||||
if (isAgentSelected) {
|
||||
const updatedList = this.participantList.filter(
|
||||
const updatedList = this.watchersList.filter(
|
||||
participant => participant.id !== agent.id
|
||||
);
|
||||
|
||||
this.participantList = [...updatedList];
|
||||
this.watchersList = [...updatedList];
|
||||
} else {
|
||||
this.participantList = [...this.participantList, agent];
|
||||
this.watchersList = [...this.watchersList, agent];
|
||||
}
|
||||
},
|
||||
onSelfAssign() {
|
||||
this.watchersList = [...this.selectedWatchers, this.currentUser];
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -191,10 +248,6 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.total-watchers {
|
||||
font-size: var(--font-size-small);
|
||||
color: var(--s-600);
|
||||
}
|
||||
.subscribers--collapsed {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
@ -215,4 +268,9 @@ export default {
|
|||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in a new issue