UNCLASSIFIED

Commit 86022f04 authored by hunter.congress's avatar hunter.congress
Browse files

fix addTeams

parents ebd07711 b8edfaa2
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,11 +40,7 @@ export default { ...@@ -33,11 +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 +58,7 @@ export default { ...@@ -55,6 +58,7 @@ 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);
}, },
}; };
...@@ -132,24 +132,27 @@ export default { ...@@ -132,24 +132,27 @@ export default {
this.init(); this.init();
}, },
add() { add() {
this.$emit("add", this.toAdd); this.$emit("add", this.toAdd, this.leads);
this.init(); this.init();
}, },
edit() { edit() {
// merge members and leads // merge members and leads
const members = new Map(); const members = new Map();
console.log("MEMBER",members) if (this.toAdd.members) {
this.toAdd.members.forEach((member) => { this.toAdd.members.forEach((member) => {
member.TeamMember = { isTeamLead: false }; member.TeamMember = { isTeamLead: false };
members.set(member.id, member); members.set(member.id, member);
}); });
this.leads.forEach((lead) => { }
lead.TeamMember = { isTeamLead: true }; if (this.leads) {
members.set(lead.id, lead); this.leads.forEach((lead) => {
}); lead.TeamMember = { isTeamLead: true };
members.set(lead.id, lead);
});
}
this.toAdd.members = [...members.values()]; this.toAdd.members = [...members.values()];
this.$emit("edit", this.toAdd, this.leads); this.$emit("edit", this.toAdd);
this.init(); this.init();
}, },
}, },
......
...@@ -154,7 +154,6 @@ export default { ...@@ -154,7 +154,6 @@ export default {
async query(val) { async query(val) {
try { try {
const newItems = await UserService.search({ q: val }); const newItems = await UserService.search({ q: val });
console.log(newItems);
if (this.model) { if (this.model) {
if (Array.isArray(this.model)) { if (Array.isArray(this.model)) {
this.items = uniq([...newItems.users, ...this.model]); this.items = uniq([...newItems.users, ...this.model]);
......
...@@ -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() {
...@@ -293,7 +298,6 @@ export default { ...@@ -293,7 +298,6 @@ export default {
this.team = await TeamService.getMyTeam(); this.team = await TeamService.getMyTeam();
} }
} else { } else {
console.log("THIS CANNOT BE ME");
await this.getTeams(); await this.getTeams();
} }
} catch (error) { } catch (error) {
...@@ -308,7 +312,6 @@ export default { ...@@ -308,7 +312,6 @@ export default {
} }
try { try {
this.team = await TeamService.getTeam(this.$route.params.teamId); this.team = await TeamService.getTeam(this.$route.params.teamId);
console.log("TEAM", this.team);
} catch (error) { } catch (error) {
console.error("!teams error!", error); console.error("!teams error!", error);
} finally { } finally {
...@@ -334,20 +337,18 @@ export default { ...@@ -334,20 +337,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() { async addMember() {
this.state.isAddingBusy = true; this.state.isAddingBusy = true;
const members = this.memberToAdd.map((member) => ({
userId: member.id,
isTeamLead: false,
}));
try { try {
await TeamService.addMembers(members, this.$route.params.teamId); await TeamService.addMembers(
this.memberToAdd = members; 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);
...@@ -362,16 +363,6 @@ export default { ...@@ -362,16 +363,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(
...@@ -393,12 +384,11 @@ export default { ...@@ -393,12 +384,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);
......
...@@ -309,7 +309,6 @@ export default { ...@@ -309,7 +309,6 @@ export default {
try { try {
const response = await TeamService.getTeams(this.params); const response = await TeamService.getTeams(this.params);
this.teams = response.teams; this.teams = response.teams;
console.log(this.teams);
this.total = response.meta.total; this.total = response.meta.total;
} catch (error) { } catch (error) {
console.error("!teams error!", error); console.error("!teams error!", error);
...@@ -318,11 +317,16 @@ export default { ...@@ -318,11 +317,16 @@ export default {
this.fetchingData = false; this.fetchingData = false;
} }
}, },
async addTeam(toAdd) { async addTeam(toAdd, leads) {
this.state.isAddingBusy = true; this.state.isAddingBusy = true;
try { try {
await TeamService.addTeam(toAdd); const team = await TeamService.addTeam(toAdd);
this.teamToAdd = toAdd; leads = leads.map((member) => ({
...member,
TeamMember: { isTeamLead: true },
}));
await TeamService.addMembers(leads, team.id);
this.teamToAdd = { ...toAdd, leads: leads };
this.snackbars.add = true; this.snackbars.add = true;
} catch (e) { } catch (e) {
console.error("unable to add", e); console.error("unable to add", e);
......
...@@ -29,7 +29,7 @@ describe("AddTeam", () => { ...@@ -29,7 +29,7 @@ describe("AddTeam", () => {
wrapper.vm.$emit = jest.fn(); wrapper.vm.$emit = jest.fn();
wrapper.vm.edit(); wrapper.vm.edit();
expect(wrapper.vm.$emit).toHaveBeenCalledWith("edit", { expect(wrapper.vm.$emit).toHaveBeenCalledWith("edit", {
memberCount: { count: 0 }, members: [],
}); });
}); });
it("should trigger cancel", async () => { it("should trigger cancel", async () => {
...@@ -68,8 +68,6 @@ describe("AddTeam", () => { ...@@ -68,8 +68,6 @@ describe("AddTeam", () => {
wrapper.vm.$emit = jest.fn(); wrapper.vm.$emit = jest.fn();
wrapper.vm.add(); wrapper.vm.add();
expect(wrapper.vm.$emit).toHaveBeenCalledWith("add", { expect(wrapper.vm.$emit).toHaveBeenCalledWith("add", {});
memberCount: { count: 0 },
});
}); });
}); });
...@@ -118,15 +118,13 @@ describe("components/EditableInput", () => { ...@@ -118,15 +118,13 @@ describe("components/EditableInput", () => {
}, },
}, },
}, },
props: {
value: "mockValue",
},
localVue, localVue,
vuetify, vuetify,
}); });
wrapper.vm.$emit = jest.fn(); wrapper.vm.$emit = jest.fn();
await wrapper.setProps({ value: "newMockValue" }); await wrapper.setProps({ value: "newMockValue" });
await wrapper.setData({ model: "MockValue" });
wrapper.vm.updateValue(); wrapper.vm.updateValue();
expect(wrapper.vm.$emit).toHaveBeenCalled(); expect(wrapper.vm.$emit).toHaveBeenCalled();
}); });
......
...@@ -3,7 +3,7 @@ import Vuetify from "vuetify"; ...@@ -3,7 +3,7 @@ import Vuetify from "vuetify";
import UserSelect from "@/components/UserSelect"; import UserSelect from "@/components/UserSelect";
import UserService from "@/api/services/user"; import UserService from "@/api/services/user";
describe("LaunchboardAdmin", () => { describe("UserSelect", () => {
// vuetify has to be mocked for the v-autocomplete to not crash // vuetify has to be mocked for the v-autocomplete to not crash
let vuetify; let vuetify;
beforeEach(() => { beforeEach(() => {
...@@ -119,7 +119,7 @@ describe("LaunchboardAdmin", () => { ...@@ -119,7 +119,7 @@ describe("LaunchboardAdmin", () => {
vuetify, vuetify,
}); });
UserService.search = jest.fn().mockResolvedValue(["a"]); UserService.search = jest.fn().mockResolvedValue({ users: ["a"] });
// multiple model // multiple model
wrapper.vm.model = ["b", "c"]; wrapper.vm.model = ["b", "c"];
......
...@@ -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