diff --git a/app/javascript/dashboard/api/specs/teams.spec.js b/app/javascript/dashboard/api/specs/teams.spec.js
index 7622a5417..6b01ab359 100644
--- a/app/javascript/dashboard/api/specs/teams.spec.js
+++ b/app/javascript/dashboard/api/specs/teams.spec.js
@@ -11,5 +11,6 @@ describe('#TeamsAPI', () => {
expect(teams).toHaveProperty('delete');
expect(teams).toHaveProperty('getAgents');
expect(teams).toHaveProperty('addAgents');
+ expect(teams).toHaveProperty('updateAgents');
});
});
diff --git a/app/javascript/dashboard/api/teams.js b/app/javascript/dashboard/api/teams.js
index 9c117c71b..ba202dff2 100644
--- a/app/javascript/dashboard/api/teams.js
+++ b/app/javascript/dashboard/api/teams.js
@@ -15,6 +15,12 @@ export class TeamsAPI extends ApiClient {
user_ids: agentsList,
});
}
+
+ updateAgents({ teamId, agentsList }) {
+ return axios.patch(`${this.url}/${teamId}/team_members`, {
+ user_ids: agentsList,
+ });
+ }
}
export default new TeamsAPI();
diff --git a/app/javascript/dashboard/components/layout/Sidebar.vue b/app/javascript/dashboard/components/layout/Sidebar.vue
index 19c56c2af..59d0c67cb 100644
--- a/app/javascript/dashboard/components/layout/Sidebar.vue
+++ b/app/javascript/dashboard/components/layout/Sidebar.vue
@@ -178,7 +178,6 @@ export default {
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`),
diff --git a/app/javascript/dashboard/components/widgets/conversation/ConversationBox.vue b/app/javascript/dashboard/components/widgets/conversation/ConversationBox.vue
index 587f78304..d6d5bbd85 100644
--- a/app/javascript/dashboard/components/widgets/conversation/ConversationBox.vue
+++ b/app/javascript/dashboard/components/widgets/conversation/ConversationBox.vue
@@ -74,6 +74,7 @@ export default {
flex-direction: column;
width: 100%;
border-left: 1px solid var(--color-border);
+ background: var(--color-background-light);
}
.messages-and-sidebar {
diff --git a/app/javascript/dashboard/i18n/default-sidebar.js b/app/javascript/dashboard/i18n/default-sidebar.js
index c4074e433..7faa7d2e8 100644
--- a/app/javascript/dashboard/i18n/default-sidebar.js
+++ b/app/javascript/dashboard/i18n/default-sidebar.js
@@ -75,6 +75,13 @@ export const getSidebarItems = accountId => ({
'settings_integrations_integration',
'general_settings',
'general_settings_index',
+ 'settings_teams_list',
+ 'settings_teams_new',
+ 'settings_teams_add_agents',
+ 'settings_teams_finish',
+ 'settings_teams_edit',
+ 'settings_teams_edit_members',
+ 'settings_teams_edit_finish',
],
menuItems: {
back: {
@@ -91,6 +98,13 @@ export const getSidebarItems = accountId => ({
toState: frontendURL(`accounts/${accountId}/settings/agents/list`),
toStateName: 'agent_list',
},
+ teams: {
+ icon: 'ion-ios-people',
+ label: 'TEAMS',
+ hasSubMenu: false,
+ toState: frontendURL(`accounts/${accountId}/settings/teams/list`),
+ toStateName: 'settings_teams_list',
+ },
inboxes: {
icon: 'ion-archive',
label: 'INBOXES',
diff --git a/app/javascript/dashboard/i18n/locale/en/index.js b/app/javascript/dashboard/i18n/locale/en/index.js
index 5dfc44e4b..53d1438c2 100644
--- a/app/javascript/dashboard/i18n/locale/en/index.js
+++ b/app/javascript/dashboard/i18n/locale/en/index.js
@@ -13,6 +13,7 @@ import { default as _settings } from './settings.json';
import { default as _signup } from './signup.json';
import { default as _integrations } from './integrations.json';
import { default as _generalSettings } from './generalSettings.json';
+import { default as _teamsSettings } from './teamsSettings.json';
export default {
..._agentMgmt,
@@ -30,4 +31,5 @@ export default {
..._signup,
..._integrations,
..._generalSettings,
+ ..._teamsSettings,
};
diff --git a/app/javascript/dashboard/i18n/locale/en/teamsSettings.json b/app/javascript/dashboard/i18n/locale/en/teamsSettings.json
new file mode 100644
index 000000000..a836134df
--- /dev/null
+++ b/app/javascript/dashboard/i18n/locale/en/teamsSettings.json
@@ -0,0 +1,123 @@
+{
+ "TEAMS_SETTINGS": {
+ "NEW_TEAM": "Create new team",
+ "HEADER": "Teams",
+ "SIDEBAR_TXT": "
Teams
Teams let you organize your agents into groups based on their responsibilities.
A user can be part of multiple teams. You can assign conversations to a team when you are working collaboratively.
",
+ "LIST": {
+ "404": "There are no teams created on this account.",
+ "EDIT_TEAM": "Edit team"
+ },
+ "CREATE_FLOW": {
+ "CREATE": {
+ "TITLE": "Create a new team",
+ "DESC": "Add a title and description to your new team."
+ },
+ "AGENTS": {
+ "BUTTON_TEXT": "Add agents to team",
+ "TITLE": "Add agents to team - %{teamName}",
+ "DESC": "Add Agents to your newly created team. This lets you collaborate as a team on conversations, get notified on new events in the same conversation."
+ },
+ "WIZARD": [{
+ "title": "Create",
+ "route": "settings_teams_new",
+ "body": "Create a new team of agents."
+ },
+ {
+ "title": "Add Agents",
+ "route": "settings_teams_add_agents",
+ "body": "Add agents to the team."
+ },
+ {
+ "title": "Finish",
+ "route": "settings_teams_finish",
+ "body": "You are all set to go!"
+ }
+ ]
+ },
+ "EDIT_FLOW": {
+ "CREATE": {
+ "TITLE": "Edit your team details",
+ "DESC": "Edit title and description to your team.",
+ "BUTTON_TEXT": "Update team"
+ },
+ "AGENTS": {
+ "BUTTON_TEXT": "Update agents in team",
+ "TITLE": "Add agents to team - %{teamName}",
+ "DESC": "Add Agents to your newly created team. All the added agents will be notified when a conversation is assigned to this team."
+ },
+ "WIZARD": [{
+ "title": "Team details",
+ "route": "settings_teams_edit",
+ "body": "Change name, description and other details."
+ },
+ {
+ "title": "Edit Agents",
+ "route": "settings_teams_edit_members",
+ "body": "Edit agents in your team."
+ },
+ {
+ "title": "Finish",
+ "route": "settings_teams_edit_finish",
+ "body": "You are all set to go!"
+ }
+ ]
+ },
+ "TEAM_FORM": {
+ "ERROR_MESSAGE": "Couldn't save the team details. Try again."
+ },
+ "AGENTS": {
+ "AGENT": "AGENT",
+ "EMAIL": "EMAIL",
+ "BUTTON_TEXT": "Add agents",
+ "ADD_AGENTS": "Adding Agents to your Team...",
+ "SELECT": "select",
+ "SELECT_ALL": "select all agents",
+ "SELECTED_COUNT": "%{selected} out of %{total} agents selected."
+ },
+ "ADD": {
+ "TITLE": "Add agents to team - %{teamName}",
+ "DESC": "Add Agents to your newly created team. This lets you collaborate as a team on conversations, get notified on new events in the same conversation.",
+ "SELECT": "select",
+ "SELECT_ALL": "select all agents",
+ "SELECTED_COUNT": "%{selected} out of %{total} agents selected.",
+ "BUTTON_TEXT": "Add agents",
+ "AGENT_VALIDATION_ERROR": "Select atleaset one agent."
+ },
+
+ "FINISH": {
+ "TITLE": "Your team is ready!",
+ "MESSAGE": "You can now collaborate as a team on conversations. Happy supporting ",
+ "BUTTON_TEXT": "Finish"
+ },
+ "DELETE": {
+ "BUTTON_TEXT": "Delete",
+ "API": {
+ "SUCCESS_MESSAGE": "Team deleted successfully.",
+ "ERROR_MESSAGE": "Couldn't delete the team. Try again."
+ },
+ "CONFIRM": {
+ "TITLE": "Are you sure want to delete - %{teamName}",
+ "MESSAGE": "Deleting the team will remove the team assignment from the conversations assigned to this team.",
+ "YES": "Delete ",
+ "NO": "Cancel"
+ }
+ },
+ "SETTINGS": "Settings",
+ "FORM": {
+ "UPDATE": "Update team",
+ "CREATE": "Create team",
+ "NAME": {
+ "LABEL": "Team name",
+ "PLACEHOLDER": "Example: Sales, Customer Support"
+ },
+ "DESCRIPTION": {
+ "LABEL": "Team Description",
+ "PLACEHOLDER": "Short description about this team."
+ },
+ "AUTO_ASSIGN": {
+ "LABEL": "Allow auto assign for this team."
+ },
+ "SUBMIT_CREATE": "Create team"
+ }
+ }
+}
diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue
index 83d6b57f6..93820a9ac 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue
+++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue
@@ -404,6 +404,7 @@ export default {
this.selectedTabIndex = 0;
this.selectedAgents = [];
this.$store.dispatch('agents/get');
+ this.$store.dispatch('teams/get');
this.$store.dispatch('inboxes/get').then(() => {
this.fetchAttachedAgents();
this.avatarUrl = this.inbox.avatar_url;
diff --git a/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js b/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js
index c82f5dfe4..46617349c 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js
+++ b/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js
@@ -7,6 +7,7 @@ import integrations from './integrations/integrations.routes';
import labels from './labels/labels.routes';
import profile from './profile/profile.routes';
import reports from './reports/reports.routes';
+import teams from './teams/teams.routes';
import store from '../../../store';
export default {
@@ -30,5 +31,6 @@ export default {
...labels.routes,
...profile.routes,
...reports.routes,
+ ...teams.routes,
],
};
diff --git a/app/javascript/dashboard/routes/dashboard/settings/teams/AgentSelector.vue b/app/javascript/dashboard/routes/dashboard/settings/teams/AgentSelector.vue
new file mode 100644
index 000000000..6a0bb7e21
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/teams/AgentSelector.vue
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/teams/Create/AddAgents.vue b/app/javascript/dashboard/routes/dashboard/settings/teams/Create/AddAgents.vue
new file mode 100644
index 000000000..ec59c6b94
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/teams/Create/AddAgents.vue
@@ -0,0 +1,117 @@
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/teams/Create/CreateTeam.vue b/app/javascript/dashboard/routes/dashboard/settings/teams/Create/CreateTeam.vue
new file mode 100644
index 000000000..ff596a953
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/teams/Create/CreateTeam.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/teams/Create/Index.vue b/app/javascript/dashboard/routes/dashboard/settings/teams/Create/Index.vue
new file mode 100644
index 000000000..33f6b3c3f
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/teams/Create/Index.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/teams/Edit/EditAgents.vue b/app/javascript/dashboard/routes/dashboard/settings/teams/Edit/EditAgents.vue
new file mode 100644
index 000000000..e99384dff
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/teams/Edit/EditAgents.vue
@@ -0,0 +1,139 @@
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/teams/Edit/EditTeam.vue b/app/javascript/dashboard/routes/dashboard/settings/teams/Edit/EditTeam.vue
new file mode 100644
index 000000000..fc795fab6
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/teams/Edit/EditTeam.vue
@@ -0,0 +1,77 @@
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/teams/Edit/Index.vue b/app/javascript/dashboard/routes/dashboard/settings/teams/Edit/Index.vue
new file mode 100644
index 000000000..f85042003
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/teams/Edit/Index.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/teams/FinishSetup.vue b/app/javascript/dashboard/routes/dashboard/settings/teams/FinishSetup.vue
new file mode 100644
index 000000000..5290c369e
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/teams/FinishSetup.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+ {{ $t('TEAMS_SETTINGS.FINISH.BUTTON_TEXT') }}
+
+
+
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/teams/Index.vue b/app/javascript/dashboard/routes/dashboard/settings/teams/Index.vue
new file mode 100644
index 000000000..ac74ed1ae
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/teams/Index.vue
@@ -0,0 +1,140 @@
+
+
+
+
+
+ {{ $t('TEAMS_SETTINGS.LIST.404') }}
+
+ {{ $t('TEAMS_SETTINGS.NEW_TEAM') }}
+
+
+
+
+
+
+ |
+ {{ item.name }}
+ {{ item.description }}
+ |
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/teams/TeamForm.vue b/app/javascript/dashboard/routes/dashboard/settings/teams/TeamForm.vue
new file mode 100644
index 000000000..7f388c734
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/teams/TeamForm.vue
@@ -0,0 +1,99 @@
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/teams/helpers/validations.js b/app/javascript/dashboard/routes/dashboard/settings/teams/helpers/validations.js
new file mode 100644
index 000000000..3f063a0c4
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/teams/helpers/validations.js
@@ -0,0 +1,10 @@
+import { required, minLength } from 'vuelidate/lib/validators';
+
+export default {
+ title: {
+ required,
+ minLength: minLength(2),
+ },
+ description: {},
+ showOnSidebar: {},
+};
diff --git a/app/javascript/dashboard/routes/dashboard/settings/teams/teams.routes.js b/app/javascript/dashboard/routes/dashboard/settings/teams/teams.routes.js
new file mode 100644
index 000000000..95429bd46
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/teams/teams.routes.js
@@ -0,0 +1,91 @@
+/* eslint arrow-body-style: 0 */
+import SettingsContent from '../Wrapper';
+import TeamsHome from './Index';
+import CreateStepWrap from './Create/Index';
+import EditStepWrap from './Edit/Index';
+import CreateTeam from './Create/CreateTeam';
+import EditTeam from './Edit/EditTeam';
+import AddAgents from './Create/AddAgents';
+import EditAgents from './Edit/EditAgents';
+import FinishSetup from './FinishSetup';
+import { frontendURL } from '../../../../helper/URLHelper';
+
+export default {
+ routes: [
+ {
+ path: frontendURL('accounts/:accountId/settings/teams'),
+ component: SettingsContent,
+ props: params => {
+ const showBackButton = params.name !== 'settings_teams_list';
+ return {
+ headerTitle: 'TEAMS_SETTINGS.HEADER',
+ headerButtonText: 'TEAMS_SETTINGS.NEW_TEAM',
+ icon: 'ion-ios-people',
+ newButtonRoutes: ['settings_teams_new'],
+ showBackButton,
+ };
+ },
+ children: [
+ {
+ path: '',
+ name: 'settings_teams',
+ redirect: 'list',
+ },
+ {
+ path: 'list',
+ name: 'settings_teams_list',
+ component: TeamsHome,
+ roles: ['administrator'],
+ },
+ {
+ path: 'new',
+ component: CreateStepWrap,
+ children: [
+ {
+ path: '',
+ name: 'settings_teams_new',
+ component: CreateTeam,
+ roles: ['administrator'],
+ },
+ {
+ path: ':teamId/finish',
+ name: 'settings_teams_finish',
+ component: FinishSetup,
+ roles: ['administrator'],
+ },
+ {
+ path: ':teamId/agents',
+ name: 'settings_teams_add_agents',
+ roles: ['administrator'],
+ component: AddAgents,
+ },
+ ],
+ },
+ {
+ path: ':teamId/edit',
+ component: EditStepWrap,
+ children: [
+ {
+ path: '',
+ name: 'settings_teams_edit',
+ component: EditTeam,
+ roles: ['administrator'],
+ },
+ {
+ path: 'agents',
+ name: 'settings_teams_edit_members',
+ component: EditAgents,
+ roles: ['administrator'],
+ },
+ {
+ path: 'finish',
+ name: 'settings_teams_edit_finish',
+ roles: ['administrator'],
+ component: FinishSetup,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+};
diff --git a/app/javascript/dashboard/store/modules/specs/teamMembers/actions.spec.js b/app/javascript/dashboard/store/modules/specs/teamMembers/actions.spec.js
index 07cb244a9..d293a19eb 100644
--- a/app/javascript/dashboard/store/modules/specs/teamMembers/actions.spec.js
+++ b/app/javascript/dashboard/store/modules/specs/teamMembers/actions.spec.js
@@ -56,4 +56,27 @@ describe('#actions', () => {
]);
});
});
+
+ describe('#update', () => {
+ it('sends correct actions if API is success', async () => {
+ axios.patch.mockResolvedValue({ data: teamMembers });
+ await actions.update({ commit }, { agentsList: teamMembers, teamId: 1 });
+
+ expect(commit.mock.calls).toEqual([
+ [SET_TEAM_MEMBERS_UI_FLAG, { isUpdating: true }],
+ [ADD_AGENTS_TO_TEAM, { data: teamMembers }],
+ [SET_TEAM_MEMBERS_UI_FLAG, { isUpdating: false }],
+ ]);
+ });
+ it('sends correct actions if API is error', async () => {
+ axios.patch.mockRejectedValue({ message: 'Incorrect header' });
+ await expect(
+ actions.update({ commit }, { agentsList: teamMembers, teamId: 1 })
+ ).rejects.toThrow(Error);
+ expect(commit.mock.calls).toEqual([
+ [SET_TEAM_MEMBERS_UI_FLAG, { isUpdating: true }],
+ [SET_TEAM_MEMBERS_UI_FLAG, { isUpdating: false }],
+ ]);
+ });
+ });
});
diff --git a/app/javascript/dashboard/store/modules/specs/teams/actions.spec.js b/app/javascript/dashboard/store/modules/specs/teams/actions.spec.js
index 855322105..8c11fb3a7 100644
--- a/app/javascript/dashboard/store/modules/specs/teams/actions.spec.js
+++ b/app/javascript/dashboard/store/modules/specs/teams/actions.spec.js
@@ -60,7 +60,7 @@ describe('#actions', () => {
describe('#update', () => {
it('sends correct actions if API is success', async () => {
- axios.patch.mockResolvedValue({ data: { payload: teamsList[1] } });
+ axios.patch.mockResolvedValue({ data: teamsList[1] });
await actions.update({ commit }, teamsList[1]);
expect(commit.mock.calls).toEqual([
diff --git a/app/javascript/dashboard/store/modules/teamMembers.js b/app/javascript/dashboard/store/modules/teamMembers.js
index 581cac4f8..d93df1793 100644
--- a/app/javascript/dashboard/store/modules/teamMembers.js
+++ b/app/javascript/dashboard/store/modules/teamMembers.js
@@ -46,6 +46,20 @@ export const actions = {
commit(SET_TEAM_MEMBERS_UI_FLAG, { isCreating: false });
}
},
+ update: async ({ commit }, { agentsList, teamId }) => {
+ commit(SET_TEAM_MEMBERS_UI_FLAG, { isUpdating: true });
+ try {
+ const response = await TeamsAPI.updateAgents({
+ agentsList,
+ teamId,
+ });
+ commit(ADD_AGENTS_TO_TEAM, response);
+ } catch (error) {
+ throw new Error(error);
+ } finally {
+ commit(SET_TEAM_MEMBERS_UI_FLAG, { isUpdating: false });
+ }
+ },
};
export const mutations = {
diff --git a/app/javascript/dashboard/store/modules/teams/actions.js b/app/javascript/dashboard/store/modules/teams/actions.js
index 39bc38df2..be6b842e2 100644
--- a/app/javascript/dashboard/store/modules/teams/actions.js
+++ b/app/javascript/dashboard/store/modules/teams/actions.js
@@ -56,7 +56,7 @@ export const actions = {
commit(SET_TEAM_UI_FLAG, { isUpdating: true });
try {
const response = await TeamsAPI.update(id, updateObj);
- commit(EDIT_TEAM, response.data.payload);
+ commit(EDIT_TEAM, response.data);
} catch (error) {
throw new Error(error);
} finally {
diff --git a/yarn.lock b/yarn.lock
index d6319983a..011be7572 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -11790,4 +11790,4 @@ yauzl@2.10.0, yauzl@^2.10.0:
integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=
dependencies:
buffer-crc32 "~0.2.3"
- fd-slicer "~1.1.0"
+ fd-slicer "~1.1.0"
\ No newline at end of file