feat: Show teams on sidebar (#1754)
Co-authored-by: Pranav Raj S <pranav@chatwoot.com> Co-authored-by: Sojan <sojan@pepalo.com>
This commit is contained in:
parent
8d45849d0c
commit
eaafc45f45
12 changed files with 110 additions and 4 deletions
|
@ -6,10 +6,11 @@ class ConversationApi extends ApiClient {
|
||||||
super('conversations', { accountScoped: true });
|
super('conversations', { accountScoped: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
get({ inboxId, status, assigneeType, page, labels }) {
|
get({ inboxId, status, assigneeType, page, labels, teamId }) {
|
||||||
return axios.get(this.url, {
|
return axios.get(this.url, {
|
||||||
params: {
|
params: {
|
||||||
inbox_id: inboxId,
|
inbox_id: inboxId,
|
||||||
|
team_id: teamId,
|
||||||
status,
|
status,
|
||||||
assignee_type: assigneeType,
|
assignee_type: assigneeType,
|
||||||
page,
|
page,
|
||||||
|
@ -56,13 +57,14 @@ class ConversationApi extends ApiClient {
|
||||||
return axios.post(`${this.url}/${conversationId}/unmute`);
|
return axios.post(`${this.url}/${conversationId}/unmute`);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta({ inboxId, status, assigneeType, labels }) {
|
meta({ inboxId, status, assigneeType, labels, teamId }) {
|
||||||
return axios.get(`${this.url}/meta`, {
|
return axios.get(`${this.url}/meta`, {
|
||||||
params: {
|
params: {
|
||||||
inbox_id: inboxId,
|
inbox_id: inboxId,
|
||||||
status,
|
status,
|
||||||
assignee_type: assigneeType,
|
assignee_type: assigneeType,
|
||||||
labels,
|
labels,
|
||||||
|
team_id: teamId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,10 @@ export default {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
activeTeam: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -128,12 +132,16 @@ export default {
|
||||||
status: this.activeStatus,
|
status: this.activeStatus,
|
||||||
page: this.currentPage + 1,
|
page: this.currentPage + 1,
|
||||||
labels: this.label ? [this.label] : undefined,
|
labels: this.label ? [this.label] : undefined,
|
||||||
|
teamId: this.activeTeam.name ? this.activeTeam.id : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
pageTitle() {
|
pageTitle() {
|
||||||
if (this.inbox.name) {
|
if (this.inbox.name) {
|
||||||
return this.inbox.name;
|
return this.inbox.name;
|
||||||
}
|
}
|
||||||
|
if (this.activeTeam.name) {
|
||||||
|
return this.activeTeam.name;
|
||||||
|
}
|
||||||
if (this.label) {
|
if (this.label) {
|
||||||
return `#${this.label}`;
|
return `#${this.label}`;
|
||||||
}
|
}
|
||||||
|
@ -162,6 +170,9 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
activeTeam() {
|
||||||
|
this.resetAndFetchData();
|
||||||
|
},
|
||||||
conversationInbox() {
|
conversationInbox() {
|
||||||
this.resetAndFetchData();
|
this.resetAndFetchData();
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,6 +13,11 @@
|
||||||
:key="item.toState"
|
:key="item.toState"
|
||||||
:menu-item="item"
|
:menu-item="item"
|
||||||
/>
|
/>
|
||||||
|
<sidebar-item
|
||||||
|
v-if="shouldShowTeams"
|
||||||
|
:key="teamSection.toState"
|
||||||
|
:menu-item="teamSection"
|
||||||
|
/>
|
||||||
<sidebar-item
|
<sidebar-item
|
||||||
v-if="shouldShowInboxes"
|
v-if="shouldShowInboxes"
|
||||||
:key="inboxSection.toState"
|
:key="inboxSection.toState"
|
||||||
|
@ -97,6 +102,7 @@ export default {
|
||||||
accountId: 'getCurrentAccountId',
|
accountId: 'getCurrentAccountId',
|
||||||
currentRole: 'getCurrentRole',
|
currentRole: 'getCurrentRole',
|
||||||
accountLabels: 'labels/getLabelsOnSidebar',
|
accountLabels: 'labels/getLabelsOnSidebar',
|
||||||
|
teams: 'teams/getMyTeams',
|
||||||
}),
|
}),
|
||||||
|
|
||||||
sidemenuItems() {
|
sidemenuItems() {
|
||||||
|
@ -125,6 +131,9 @@ export default {
|
||||||
shouldShowInboxes() {
|
shouldShowInboxes() {
|
||||||
return this.sidemenuItems.common.routes.includes(this.currentRoute);
|
return this.sidemenuItems.common.routes.includes(this.currentRoute);
|
||||||
},
|
},
|
||||||
|
shouldShowTeams() {
|
||||||
|
return this.shouldShowInboxes && this.teams.length;
|
||||||
|
},
|
||||||
inboxSection() {
|
inboxSection() {
|
||||||
return {
|
return {
|
||||||
icon: 'ion-folder',
|
icon: 'ion-folder',
|
||||||
|
@ -164,6 +173,24 @@ export default {
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
teamSection() {
|
||||||
|
return {
|
||||||
|
icon: 'ion-ios-people',
|
||||||
|
label: 'TEAMS',
|
||||||
|
hasSubMenu: true,
|
||||||
|
newLink: true,
|
||||||
|
key: 'team',
|
||||||
|
cssClass: 'menu-title align-justify teams-sidebar-menu',
|
||||||
|
toState: frontendURL(`accounts/${this.accountId}/settings/teams`),
|
||||||
|
toStateName: 'teams_list',
|
||||||
|
children: this.teams.map(team => ({
|
||||||
|
id: team.id,
|
||||||
|
label: team.name,
|
||||||
|
truncateLabel: true,
|
||||||
|
toState: frontendURL(`accounts/${this.accountId}/team/${team.id}`),
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
},
|
||||||
dashboardPath() {
|
dashboardPath() {
|
||||||
return frontendURL(`accounts/${this.accountId}/dashboard`);
|
return frontendURL(`accounts/${this.accountId}/dashboard`);
|
||||||
},
|
},
|
||||||
|
@ -179,6 +206,7 @@ export default {
|
||||||
this.$store.dispatch('labels/get');
|
this.$store.dispatch('labels/get');
|
||||||
this.$store.dispatch('inboxes/get');
|
this.$store.dispatch('inboxes/get');
|
||||||
this.$store.dispatch('notifications/unReadCount');
|
this.$store.dispatch('notifications/unReadCount');
|
||||||
|
this.$store.dispatch('teams/get');
|
||||||
this.setChatwootUser();
|
this.setChatwootUser();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -305,4 +333,8 @@ export default {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.teams-sidebar-menu + .nested.vertical.menu {
|
||||||
|
padding-left: calc(var(--space-medium) - var(--space-one));
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -14,6 +14,8 @@ export const getSidebarItems = accountId => ({
|
||||||
'profile_settings_index',
|
'profile_settings_index',
|
||||||
'label_conversations',
|
'label_conversations',
|
||||||
'conversations_through_label',
|
'conversations_through_label',
|
||||||
|
'team_conversations',
|
||||||
|
'conversations_through_team',
|
||||||
'notifications_index',
|
'notifications_index',
|
||||||
],
|
],
|
||||||
menuItems: {
|
menuItems: {
|
||||||
|
|
|
@ -124,7 +124,8 @@
|
||||||
"CANNED_RESPONSES": "Canned Responses",
|
"CANNED_RESPONSES": "Canned Responses",
|
||||||
"INTEGRATIONS": "Integrations",
|
"INTEGRATIONS": "Integrations",
|
||||||
"ACCOUNT_SETTINGS": "Account Settings",
|
"ACCOUNT_SETTINGS": "Account Settings",
|
||||||
"LABELS": "Labels"
|
"LABELS": "Labels",
|
||||||
|
"TEAMS": "Teams"
|
||||||
},
|
},
|
||||||
"CREATE_ACCOUNT": {
|
"CREATE_ACCOUNT": {
|
||||||
"NEW_ACCOUNT": "New Account",
|
"NEW_ACCOUNT": "New Account",
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
<chat-list
|
<chat-list
|
||||||
:conversation-inbox="inboxId"
|
:conversation-inbox="inboxId"
|
||||||
:label="label"
|
:label="label"
|
||||||
|
:active-team="activeTeam"
|
||||||
@conversation-load="onConversationLoad"
|
@conversation-load="onConversationLoad"
|
||||||
>
|
>
|
||||||
<button class="search--button" @click="onSearch">
|
<button class="search--button" @click="onSearch">
|
||||||
|
@ -61,6 +62,10 @@ export default {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
teamId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -81,6 +86,12 @@ export default {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
activeTeam() {
|
||||||
|
if (this.teamId) {
|
||||||
|
return this.$store.getters['teams/getTeam'](this.teamId);
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
@ -64,5 +64,24 @@ export default {
|
||||||
label: route.params.label,
|
label: route.params.label,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: frontendURL('accounts/:accountId/team/:teamId'),
|
||||||
|
name: 'team_conversations',
|
||||||
|
roles: ['administrator', 'agent'],
|
||||||
|
component: ConversationView,
|
||||||
|
props: route => ({ teamId: route.params.teamId }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: frontendURL(
|
||||||
|
'accounts/:accountId/team/:teamId/conversations/:conversationId'
|
||||||
|
),
|
||||||
|
name: 'conversations_through_team',
|
||||||
|
roles: ['administrator', 'agent'],
|
||||||
|
component: ConversationView,
|
||||||
|
props: route => ({
|
||||||
|
conversationId: route.params.conversationId,
|
||||||
|
teamId: route.params.teamId,
|
||||||
|
}),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,5 +4,13 @@ export default {
|
||||||
account_id: 1,
|
account_id: 1,
|
||||||
name: 'Test',
|
name: 'Test',
|
||||||
description: 'Some team',
|
description: 'Some team',
|
||||||
|
is_member: true,
|
||||||
|
},
|
||||||
|
2: {
|
||||||
|
id: 2,
|
||||||
|
account_id: 1,
|
||||||
|
name: 'Test 1',
|
||||||
|
description: 'Some team',
|
||||||
|
is_member: false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,7 +6,18 @@ describe('#getters', () => {
|
||||||
const state = {
|
const state = {
|
||||||
records: teamsList,
|
records: teamsList,
|
||||||
};
|
};
|
||||||
expect(getters.getTeams(state)).toEqual([teamsList[1]]);
|
expect(getters.getTeams(state)).toEqual([teamsList[1], teamsList[2]]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getMyTeams', () => {
|
||||||
|
const state = {
|
||||||
|
records: teamsList,
|
||||||
|
};
|
||||||
|
expect(
|
||||||
|
getters.getMyTeams(state, {
|
||||||
|
getTeams: [teamsList[1], teamsList[2]],
|
||||||
|
})
|
||||||
|
).toEqual([teamsList[1]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('getTeam', () => {
|
it('getTeam', () => {
|
||||||
|
@ -18,6 +29,7 @@ describe('#getters', () => {
|
||||||
account_id: 1,
|
account_id: 1,
|
||||||
name: 'Test',
|
name: 'Test',
|
||||||
description: 'Some team',
|
description: 'Some team',
|
||||||
|
is_member: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ describe('#mutations', () => {
|
||||||
it('set teams records', () => {
|
it('set teams records', () => {
|
||||||
const state = { records: {} };
|
const state = { records: {} };
|
||||||
mutations[SET_TEAMS](state, [teams[1]]);
|
mutations[SET_TEAMS](state, [teams[1]]);
|
||||||
|
mutations[SET_TEAMS](state, [teams[2]]);
|
||||||
expect(state.records).toEqual(teams);
|
expect(state.records).toEqual(teams);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,6 +2,12 @@ export const getters = {
|
||||||
getTeams($state) {
|
getTeams($state) {
|
||||||
return Object.values($state.records).sort((a, b) => a.id - b.id);
|
return Object.values($state.records).sort((a, b) => a.id - b.id);
|
||||||
},
|
},
|
||||||
|
getMyTeams($state, $getters) {
|
||||||
|
return $getters.getTeams.filter(team => {
|
||||||
|
const { is_member: isMember } = team;
|
||||||
|
return isMember;
|
||||||
|
});
|
||||||
|
},
|
||||||
getUIFlags($state) {
|
getUIFlags($state) {
|
||||||
return $state.uiFlags;
|
return $state.uiFlags;
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,3 +3,4 @@ json.name resource.name
|
||||||
json.description resource.description
|
json.description resource.description
|
||||||
json.allow_auto_assign resource.allow_auto_assign
|
json.allow_auto_assign resource.allow_auto_assign
|
||||||
json.account_id resource.account.id
|
json.account_id resource.account.id
|
||||||
|
json.is_member Current.user.teams.include?(resource)
|
||||||
|
|
Loading…
Reference in a new issue