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:
Nithin David Thomas 2021-02-13 14:58:05 +05:30 committed by GitHub
parent 8d45849d0c
commit eaafc45f45
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 110 additions and 4 deletions

View file

@ -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,
}, },
}); });
} }

View file

@ -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();
}, },

View file

@ -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>

View file

@ -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: {

View file

@ -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",

View file

@ -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() {

View file

@ -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,
}),
},
], ],
}; };

View file

@ -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,
}, },
}; };

View file

@ -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,
}); });
}); });

View file

@ -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);
}); });
}); });

View file

@ -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;
}, },

View file

@ -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)