UNCLASSIFIED

Commit b8edfaa2 authored by graham.smith's avatar graham.smith
Browse files

team tweaks

parent 6c202fc6
import { HTTP } from "@/api/http-common"; import { HTTP } from "@/api/http-common";
const getTeamMemberBody = (users) => {
return users.map((user) => ({
userId: user.id,
isTeamLead: user.TeamMember?.isTeamLead,
}));
};
export default { export default {
async getMyTeam() { async getMyTeam() {
return await HTTP.get("/teams/my-teams"); return await HTTP.get("/teams/my-teams");
...@@ -33,10 +40,7 @@ export default { ...@@ -33,10 +40,7 @@ export default {
}); });
}, },
async updateTeamMembers(team) { async updateTeamMembers(team) {
const membersBody = team.members.map((m) => ({ const membersBody = getTeamMemberBody(team.members);
userId: m.id,
isTeamLead: m.TeamMember.isTeamLead,
}));
return HTTP.put(`/teams/${team.id}/members`, membersBody); return HTTP.put(`/teams/${team.id}/members`, membersBody);
}, },
...@@ -55,6 +59,8 @@ export default { ...@@ -55,6 +59,8 @@ export default {
}); });
}, },
async addMembers(members, teamId) { async addMembers(members, teamId) {
await HTTP.post(`/teams/${teamId}/members`, members); const membersBody = getTeamMemberBody(members);
await HTTP.post(`/teams/${teamId}/members`, membersBody);
}, },
}; };
...@@ -99,12 +99,12 @@ ...@@ -99,12 +99,12 @@
<v-card-text> <v-card-text>
<UserSelect <UserSelect
ref="userSelect" ref="userSelect"
v-model="memberToAdd" v-model="membersToAdd"
multiple multiple
:rules="[ :rules="[
inputRules.required, inputRules.required,
inputRules.duplicates( inputRules.duplicates(
memberToAdd, membersToAdd,
team.members, team.members,
'User is already a member of this team' 'User is already a member of this team'
), ),
...@@ -123,7 +123,7 @@ ...@@ -123,7 +123,7 @@
Cancel Cancel
</v-btn> </v-btn>
<v-btn <v-btn
:disabled="state.isAddingDuplicate || !memberToAdd" :disabled="state.isAddingDuplicate || !membersToAdd"
color="primary" color="primary"
:loading="state.isAddingBusy" :loading="state.isAddingBusy"
text text
...@@ -210,12 +210,17 @@ ...@@ -210,12 +210,17 @@
</v-snackbar> </v-snackbar>
<v-snackbar <v-snackbar
top top
v-if="memberToAdd" v-if="membersToAdd"
v-model="snackbars.add" v-model="snackbars.add"
:timeout="5000" :timeout="5000"
> >
<div class="text-center"> <div class="text-center">
{{ memberToAdd.name }} added to {{ team.name }} <div v-if="membersToAdd.length === 1">
{{ membersToAdd[0].name }} added to {{ team.name }}
</div>
<div v-else>
{{ membersToAdd.length }} members added to {{ team.name }}
</div>
</div> </div>
</v-snackbar> </v-snackbar>
</v-skeleton-loader> </v-skeleton-loader>
...@@ -269,7 +274,7 @@ export default { ...@@ -269,7 +274,7 @@ export default {
], ],
selectedMembers: [], selectedMembers: [],
deletingMembers: [], deletingMembers: [],
memberToAdd: null, membersToAdd: null,
inputRules, inputRules,
}), }),
async mounted() { async mounted() {
...@@ -334,22 +339,18 @@ export default { ...@@ -334,22 +339,18 @@ export default {
} }
}, },
cancelAddMember() { cancelAddMember() {
this.memberToAdd = null; this.membersToAdd = null;
this.state.isAdding = false; this.state.isAdding = false;
this.state.isAddingDuplicate = false; this.state.isAddingDuplicate = false;
this.$refs.userSelect && this.$refs.userSelect.clear(); this.$refs.userSelect && this.$refs.userSelect.clear();
}, },
async addMember(member) { async addMember() {
if (!member) {
member = this.memberToAdd;
}
this.state.isAddingBusy = true; this.state.isAddingBusy = true;
member = member.map(function (member) {
return { userId: member.id, isTeamLead: false };
});
try { try {
await TeamService.addMembers(member, this.$route.params.teamId); await TeamService.addMembers(
this.memberToAdd = member; this.membersToAdd,
this.$route.params.teamId
);
this.snackbars.add = true; this.snackbars.add = true;
} catch (e) { } catch (e) {
console.error("unable to add user", e); console.error("unable to add user", e);
...@@ -364,16 +365,6 @@ export default { ...@@ -364,16 +365,6 @@ export default {
this.snackbars.delete = false; this.snackbars.delete = false;
this.state.isDeleting = true; this.state.isDeleting = true;
this.deletingMembers = this.selectedMembers; this.deletingMembers = this.selectedMembers;
for (let i = 0; i < this.deletingMembers.length; i++) {
const tempMember = this.team.members.filter(
(member) => member.id === this.deletingMembers[i].id
);
this.deletingMembers[i] = {
...this.deletingMembers[i],
isTeamLead: tempMember[0].TeamMember.isTeamLead,
};
}
this.deletingMembers.forEach((m) => Vue.set(m, "isDeleting", true)); this.deletingMembers.forEach((m) => Vue.set(m, "isDeleting", true));
try { try {
await TeamService.deleteMembers( await TeamService.deleteMembers(
...@@ -395,12 +386,11 @@ export default { ...@@ -395,12 +386,11 @@ export default {
// keep the delete snackbar open // keep the delete snackbar open
this.snackbars.deleteTimeout = -1; this.snackbars.deleteTimeout = -1;
this.state.isUndoingDelete = true; this.state.isUndoingDelete = true;
console.log("Deleted", this.deletingMembers);
const members = this.deletingMembers.map(function (member) {
return { userId: member.id, isTeamLead: member.TeamMember.isTeamLead };
});
try { try {
await TeamService.addMembers(members, this.$route.params.teamId); await TeamService.addMembers(
this.deletingMembers,
this.$route.params.teamId
);
} catch (e) { } catch (e) {
//TODO: error message to the user??? //TODO: error message to the user???
console.error("error restoring member:", e); console.error("error restoring member:", e);
......
...@@ -252,7 +252,7 @@ describe("Team", () => { ...@@ -252,7 +252,7 @@ describe("Team", () => {
wrapper.vm.$refs = { userSelect }; wrapper.vm.$refs = { userSelect };
wrapper.vm.memberToAdd = mockMember; wrapper.vm.memberToAdd = [mockMember];
await wrapper.vm.addMember(); await wrapper.vm.addMember();
expect(TeamService.addMember).toHaveBeenCalledTimes(1); expect(TeamService.addMember).toHaveBeenCalledTimes(1);
expect(TeamService.addMember).toHaveBeenCalledWith(mockMember, 42, false); expect(TeamService.addMember).toHaveBeenCalledWith(mockMember, 42, false);
...@@ -265,11 +265,11 @@ describe("Team", () => { ...@@ -265,11 +265,11 @@ describe("Team", () => {
console.error = jest.fn(); // mock console.error when expecting error messages console.error = jest.fn(); // mock console.error when expecting error messages
const userSelect = { clear: jest.fn() }; const userSelect = { clear: jest.fn() };
TeamService.getTeam = jest.fn().mockResolvedValue({ name: "mock" }); TeamService.getTeam = jest.fn().mockResolvedValue({ name: "mock" });
TeamService.addMember = jest.fn().mockResolvedValue({ name: "mock" }); TeamService.addMembers = jest.fn().mockResolvedValue({ name: "mock" });
const wrapper = shallowMount(Team, { mocks: { $route } }); const wrapper = shallowMount(Team, { mocks: { $route } });
wrapper.vm.$refs = { userSelect }; wrapper.vm.$refs = { userSelect };
TeamService.addMember = jest.fn().mockRejectedValue("mock error"); TeamService.addMember = jest.fn().mockRejectedValue("mock error");
await wrapper.vm.addMember(mockMember); await wrapper.vm.addMember([mockMember]);
expect(wrapper.vm.state.isAdding).toEqual(false); expect(wrapper.vm.state.isAdding).toEqual(false);
expect(wrapper.vm.state.isAddingBusy).toEqual(false); expect(wrapper.vm.state.isAddingBusy).toEqual(false);
expect(userSelect.clear).toHaveBeenCalledTimes(1); expect(userSelect.clear).toHaveBeenCalledTimes(1);
...@@ -283,6 +283,7 @@ describe("Team", () => { ...@@ -283,6 +283,7 @@ describe("Team", () => {
TeamService.deleteMembers = jest.fn().mockResolvedValue(); TeamService.deleteMembers = jest.fn().mockResolvedValue();
const toDelete = { const toDelete = {
id: 46,
name: "mock member to delete", name: "mock member to delete",
TeamMember: { isTeamLead: true }, TeamMember: { isTeamLead: true },
}; };
...@@ -296,10 +297,7 @@ describe("Team", () => { ...@@ -296,10 +297,7 @@ describe("Team", () => {
expect(wrapper.vm.snackbars.delete).toEqual(true); expect(wrapper.vm.snackbars.delete).toEqual(true);
expect(wrapper.vm.state.isDeleting).toEqual(false); expect(wrapper.vm.state.isDeleting).toEqual(false);
expect(TeamService.deleteMembers).toHaveBeenCalledTimes(1); expect(TeamService.deleteMembers).toHaveBeenCalledTimes(1);
expect(TeamService.deleteMembers).toHaveBeenCalledWith( expect(TeamService.deleteMembers).toHaveBeenCalledWith([46], 42);
[{ isDeleting: false, isTeamLead: true, ...toDelete }],
42
);
expect(wrapper.vm.selectedMembers).toEqual([]); expect(wrapper.vm.selectedMembers).toEqual([]);
}); });
it("should handle error on delete team member", async () => { it("should handle error on delete team member", async () => {
...@@ -315,11 +313,12 @@ describe("Team", () => { ...@@ -315,11 +313,12 @@ describe("Team", () => {
}); });
describe("undo delete team member", () => { describe("undo delete team member", () => {
const deletingMembers = [{ name: "mock to delete" }]; const deletingMembers = [
{ id: 46, name: "mock to delete", TeamMember: { isTeamLead: true } },
];
it("should undo delete team member", async () => { it("should undo delete team member", async () => {
TeamService.getTeam = jest.fn().mockResolvedValue({ name: "mock" }); TeamService.getTeam = jest.fn().mockResolvedValue({ name: "mock" });
const wrapper = shallowMount(Team, { mocks: { $route } }); const wrapper = shallowMount(Team, { mocks: { $route } });
// await flushPromises();
TeamService.addMembers = jest.fn().mockResolvedValue(); TeamService.addMembers = jest.fn().mockResolvedValue();
...@@ -330,7 +329,10 @@ describe("Team", () => { ...@@ -330,7 +329,10 @@ describe("Team", () => {
await flushPromises(); await flushPromises();
expect(TeamService.addMembers).toHaveBeenCalledTimes(1); expect(TeamService.addMembers).toHaveBeenCalledTimes(1);
expect(TeamService.addMembers).toHaveBeenCalledWith(deletingMembers, 42); expect(TeamService.addMembers).toHaveBeenCalledWith(
[{ userId: 46, isTeamLead: true }],
42
);
expect(wrapper.vm.state.isUndoingDelete).toEqual(false); expect(wrapper.vm.state.isUndoingDelete).toEqual(false);
expect(wrapper.vm.deletingMembers).toEqual([]); expect(wrapper.vm.deletingMembers).toEqual([]);
}); });
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment