Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/app/submissions/submissions.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,7 @@ export class SubmissionsComponent implements OnInit, AfterViewChecked, OnDestroy
}

appendTeamInfo$(submission): Observable<any> {
if (!submission.team) { return of({ ...submission, teamName: '' }); }
return this.teamsService.getTeamName(submission.team).pipe(map((teamInfo: any) => ({ ...submission, teamInfo })));
return of({ ...submission, teamInfo: submission.team || null });
}

getTeamTypeLabel(teamType: string): string {
Expand Down
56 changes: 31 additions & 25 deletions src/app/submissions/submissions.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,25 +196,38 @@ export class SubmissionsService {
}, []);
}

sendSubmissionRequests(users: any[], { parentId, parent }) {
sendSubmissionRequests(users: any[], { parentId, parent }, team?: { _id: string, name: string, type: string }) {
const queryOr = team ? [{ 'team._id': team._id }] : users.map((user: any) => ({ 'user._id': user._id, 'source': user.planetCode }));

return this.couchService.post('submissions/_find', findDocuments({
parentId,
'parent': { '_rev': parent._rev },
'$or': users.map((user: any) => ({ 'user._id': user._id, 'source': user.planetCode }))
'$or': queryOr
})).pipe(
switchMap((submissions: any) => {
const sender = this.userService.get().name;

if (team) {
const teamSubmissionExists = submissions.docs.some((s: any) => s.team?._id === team._id && s.parent._rev === parent._rev);
if (teamSubmissionExists) {
return this.couchService.updateDocument('submissions/_bulk_docs', { 'docs': [] });
}
return this.couchService.updateDocument('submissions/_bulk_docs', {
'docs': [this.createNewSubmission({ user: {}, parentId, parent, type: 'survey', sender, team })]
});
}

const newSubmissionUsers = users.filter((user: any) =>
submissions.docs.findIndex((s: any) => (s.user._id === user._id && s.parent._rev === parent._rev)) === -1
);
const sender = this.userService.get().name;
return this.couchService.updateDocument('submissions/_bulk_docs', {
'docs': newSubmissionUsers.map((user) => this.createNewSubmission({ user, parentId, parent, type: 'survey', sender }))
});
})
);
}

createSubmission(parent: any, type: string, user: any = {}, team?: string) {
createSubmission(parent: any, type: string, user: any = {}, team?: { _id: string, name: string, type: string }) {
return this.couchService.updateDocument('submissions', this.createNewSubmission({ parentId: parent._id, parent, user, type, team }));
}

Expand Down Expand Up @@ -271,17 +284,14 @@ export class SubmissionsService {
questions: Array.isArray(sub.parent.questions) ? sub.parent.questions : exam.questions
}
}));
const filteredSubmissions = team ? normalizedSubmissions.filter(s => s.team === team) : normalizedSubmissions;
return forkJoin(
filteredSubmissions.map(submission => {
if (submission.team) {
return this.teamsService.getTeamName(submission.team).pipe(map(teamInfo => ({ ...submission, teamInfo })));
}
return of(submission);
})
).pipe(map((updatedSubmissions: any[]): [any[], number, string[]] => [ updatedSubmissions, time, questionTexts ]));
const filteredSubmissions = team ? normalizedSubmissions.filter(s => s.team?._id === team) : normalizedSubmissions;
const submissionsWithTeamInfo = filteredSubmissions.map(submission => ({
...submission,
teamInfo: submission.team ? { name: submission.team.name, type: submission.team.type } : null
}));
return of<[any[], number, string[]]>([submissionsWithTeamInfo, time, questionTexts]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few things that were here before that could be improved:

  • This doesn't need to be a switchMap, it can just be a map since it's returning a static value not another observable. Then you can remove the of and just return the array on this line.
  • I think the indentation was a little off here. Bumping the switchMap, or map, down to a new line and then indenting the function would make this clearer.

}),
tap(([ updatedSubmissions, time, questionTexts ]) => {
tap(([ updatedSubmissions, time, questionTexts ]: [any[], number, string[]]) => {
const title = `${toProperCase($localize`${type}`)} - ${$localize`${exam.name}`} (${updatedSubmissions.length})`;
const data = updatedSubmissions.map(submission => {
const answerIndexes = this.answerIndexes(questionTexts, submission);
Expand All @@ -291,6 +301,7 @@ export class SubmissionsService {
ageFromBirthDate(time, submission.user.birthDate) :
submission.user.age || 'N/A',
'Planet': submission.source,
[$localize`Source`]: submission.androidId !== undefined ? 'myPlanet' : 'Planet',
[$localize`Date`]: fullLabel(submission.lastUpdateTime),
[$localize`Group`]: submission.teamInfo?.name || 'N/A',
[$localize`Group Type`]: submission.teamInfo?.type || 'N/A',
Expand Down Expand Up @@ -454,7 +465,7 @@ export class SubmissionsService {
questions: Array.isArray(sub.parent.questions) ? sub.parent.questions : exam.questions
}
}));
const filteredSubmissions = team ? normalizedSubmissions.filter(s => s.team === team) : normalizedSubmissions;
const filteredSubmissions = team ? normalizedSubmissions.filter(s => s.team?._id === team) : normalizedSubmissions;
if (!filteredSubmissions.length) {
this.dialogsLoadingService.stop();
this.planetMessageService.showMessage($localize`There is no survey response`);
Expand All @@ -463,17 +474,10 @@ export class SubmissionsService {
const planetsWithName = attachNamesToPlanets(planets);
const submissionsWithPlanetName = filteredSubmissions.map(submission => ({
...submission,
planetName: codeToPlanetName(submission.source, this.stateService.configuration, planetsWithName)
planetName: codeToPlanetName(submission.source, this.stateService.configuration, planetsWithName),
teamInfo: submission.team ? { name: submission.team.name, type: submission.team.type } : null
}));
return forkJoin(
submissionsWithPlanetName.map(submission => {
if (submission.team) {
return this.teamsService.getTeamName(submission.team).pipe(map(teamInfo => ({ ...submission, teamInfo })));
}
return of(submission);
})
).pipe(map((updatedSubmissions: any[]): [ any[], number, string[] ] => [ updatedSubmissions, time, questionTexts ])
);
return of<[any[], number, string[]]>([submissionsWithPlanetName, time, questionTexts]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, since we're no longer pulling in team info here via another observable we can just use a map instead of switchMap and return the array.

})
).subscribe(async tuple => {
if (!tuple) { return; }
Expand Down Expand Up @@ -524,13 +528,15 @@ export class SubmissionsService {
submission.user.age;
const userGender = submission.user.gender;
const communityOrNation = submission.planetName;
const planetSource = submission.androidId !== undefined ? 'myPlanet' : 'Planet';
const teamType = submission.teamInfo?.type ? toProperCase(submission.teamInfo.type) : '';
const teamName = submission.teamInfo?.name || '';
const teamInfo = teamType && teamName ? `<strong>${teamType}</strong>: ${teamName}` : '';
return [
`<h3>${$localize`Submission`} ${index + 1}</h3>`,
`<ul>`,
`<li><strong>Planet ${communityOrNation}</strong></li>`,
`<li><strong>${$localize`Source:`}</strong> ${planetSource}</li>`,
`<li><strong>${$localize`Date:`}</strong> ${shortDate}</li>`,
teamInfo ? `<li>${teamInfo}</li>` : '',
userGender ? `<li><strong>${$localize`Gender:`}</strong> ${userGender}</li>` : '',
Expand Down
50 changes: 32 additions & 18 deletions src/app/surveys/surveys.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export class SurveysComponent implements OnInit, AfterViewInit, OnDestroy {
const teamIds = [
...new Set([
survey.teamId,
...relatedSubmissions.map(sub => sub.user?.membershipDoc?.teamId)
...relatedSubmissions.map(sub => sub.team?._id)
])
].filter(Boolean);
return {
Expand All @@ -129,7 +129,7 @@ export class SurveysComponent implements OnInit, AfterViewInit, OnDestroy {
taken: this.teamId || this.routeTeamId
? relatedSubmissions.filter(
(data) => data.status === 'complete' &&
(data.team === this.teamId || data.team === this.routeTeamId)).length
(data.team?._id === this.teamId || data.team?._id === this.routeTeamId)).length
: relatedSubmissions.filter(data => data.status === 'complete').length
};
}),
Expand Down Expand Up @@ -164,7 +164,7 @@ export class SurveysComponent implements OnInit, AfterViewInit, OnDestroy {
...submission.parent,
taken: submission.status !== 'pending' ? 1 : 0,
parent: true,
teamId: submission.user?.membershipDoc?.teamId
teamId: submission.team?._id
} ];
}
return parentSurveys;
Expand Down Expand Up @@ -311,15 +311,22 @@ export class SurveysComponent implements OnInit, AfterViewInit, OnDestroy {
this.submissionsService.getSubmissions(
findDocuments({ type: 'survey', 'parent._rev': survey._rev, 'parent._id': survey._id })
).subscribe((submissions: any[]) => {
const submissionIds = submissions.map((submission: any) => submission.user.membershipDoc?.teamId);
const submissionIds = submissions.map((submission: any) => submission.team?._id).filter(Boolean);
const excludeIds = survey.teamId ? [ ...submissionIds, survey.teamId ] : submissionIds;
this.dialogRef = this.dialog.open(DialogsAddTableComponent, {
width: '80vw',
data: {
okClick: (selection: any[]) => {
this.dialogsLoadingService.start();
this.sendSurvey(survey, selection).subscribe(() => {
this.dialogsLoadingService.stop();
selection.forEach(item => {
const teamInfo = {
_id: item.doc._id,
name: item.doc.name,
type: item.doc.type
};
this.sendSurvey(survey, [], teamInfo).subscribe(() => {
this.dialogsLoadingService.stop();
});
});
},
excludeIds: [ ...excludeIds ],
Expand All @@ -332,11 +339,12 @@ export class SurveysComponent implements OnInit, AfterViewInit, OnDestroy {
adoptSurvey(survey) {
this.couchService.get('teams/' + this.routeTeamId).subscribe(
team => {
const selection = {
doc: team,
membershipDoc: { teamId: this.routeTeamId }
const teamInfo = {
_id: team._id,
name: team.name,
type: team.type
};
this.sendSurvey(survey, [ selection ], true).subscribe(() => {
this.sendSurvey(survey, [], teamInfo).subscribe(() => {
this.loadSurveys();
});
},
Expand All @@ -346,13 +354,13 @@ export class SurveysComponent implements OnInit, AfterViewInit, OnDestroy {
);
}

sendSurvey(survey: any, users: any[], isAdopt: boolean = false): Observable<void> {
sendSurvey(survey: any, users: any[], team?: { _id: string, name: string, type: string }): Observable<void> {
return this.submissionsService.sendSubmissionRequests(users, {
'parentId': survey._id,
'parent': survey
}).pipe(
}, team).pipe(
tap(() => {
const message = isAdopt ? $localize`Survey adopted` : $localize`Survey requests sent`;
const message = team ? $localize`Survey adopted` : $localize`Survey requests sent`;
this.planetMessageService.showMessage(message);
if (this.dialogRef) {
this.dialogRef.close();
Expand All @@ -367,11 +375,17 @@ export class SurveysComponent implements OnInit, AfterViewInit, OnDestroy {
}

recordSurvey(survey: any) {
this.submissionsService.createSubmission(survey, 'survey', {}, this.teamId || this.routeTeamId || '' ).subscribe((res: any) => {
this.router.navigate([
this.teamId ? 'surveys/dispense' : 'dispense',
{ questionNum: 1, submissionId: res.id, status: 'pending', mode: 'take', snap: this.route.snapshot.url }
], { relativeTo: this.route });
const targetTeamId = this.teamId || this.routeTeamId;
const teamObservable = targetTeamId ? this.couchService.get('teams/' + targetTeamId) : of(null);

teamObservable.subscribe((team: any) => {
const teamInfo = team ? { _id: team._id, name: team.name, type: team.type } : undefined;
this.submissionsService.createSubmission(survey, 'survey', {}, teamInfo).subscribe((res: any) => {
this.router.navigate([
this.teamId ? 'surveys/dispense' : 'dispense',
{ questionNum: 1, submissionId: res.id, status: 'pending', mode: 'take', snap: this.route.snapshot.url }
], { relativeTo: this.route });
});
});
}

Expand Down
12 changes: 0 additions & 12 deletions src/app/teams/teams.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,18 +381,6 @@ export class TeamsService {
return this.updateTeam(newServicesDoc);
}

getTeamName(teamId: string): Observable<Object> {
return this.couchService.get(`${this.dbName}/${teamId}`).pipe(
map((team: any) => {
if (team) {
return { 'name': team.name, 'type': team.type };
}
return { id: teamId };
}),
catchError(() => of({ id: teamId, missing: true }))
);
}

getTeamsByUser(userName: string, userPlanetCode: string) {
const selector = {
'$or': [
Expand Down
Loading