Show "Deleted user" if a poll user cannot be found
Fixes an error that would freeze OpenSlides If a user was deleted but registered as a poll option, The Assignment Detail View would freeze
This commit is contained in:
parent
96f96f09ee
commit
5e1b5b5658
@ -14,7 +14,7 @@
|
|||||||
<div *ngFor="let option of options" class="votes-grid">
|
<div *ngFor="let option of options" class="votes-grid">
|
||||||
<div>
|
<div>
|
||||||
<span *ngIf="option.user">{{ option.user.getFullName() }}</span>
|
<span *ngIf="option.user">{{ option.user.getFullName() }}</span>
|
||||||
<span *ngIf="!option.user">{{ 'Unknown user' | translate }}</span>
|
<i *ngIf="!option.user">{{ unknownUserLabel | translate }}</i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
@ -19,7 +19,7 @@ import { BasePollDialogComponent } from 'app/site/polls/components/base-poll-dia
|
|||||||
import { PollFormComponent } from 'app/site/polls/components/poll-form/poll-form.component';
|
import { PollFormComponent } from 'app/site/polls/components/poll-form/poll-form.component';
|
||||||
import { PollPropertyVerbose } from 'app/site/polls/models/view-base-poll';
|
import { PollPropertyVerbose } from 'app/site/polls/models/view-base-poll';
|
||||||
import { ViewUser } from 'app/site/users/models/view-user';
|
import { ViewUser } from 'app/site/users/models/view-user';
|
||||||
import { AssignmentPollService } from '../../services/assignment-poll.service';
|
import { AssignmentPollService, UnknownUserLabel } from '../../services/assignment-poll.service';
|
||||||
|
|
||||||
type OptionsObject = { user_id: number; user: ViewUser }[];
|
type OptionsObject = { user_id: number; user: ViewUser }[];
|
||||||
|
|
||||||
@ -34,6 +34,7 @@ type OptionsObject = { user_id: number; user: ViewUser }[];
|
|||||||
export class AssignmentPollDialogComponent
|
export class AssignmentPollDialogComponent
|
||||||
extends BasePollDialogComponent<ViewAssignmentPoll, AssignmentPollService>
|
extends BasePollDialogComponent<ViewAssignmentPoll, AssignmentPollService>
|
||||||
implements OnInit {
|
implements OnInit {
|
||||||
|
public unknownUserLabel = UnknownUserLabel;
|
||||||
/**
|
/**
|
||||||
* The summary values that will have fields in the dialog
|
* The summary values that will have fields in the dialog
|
||||||
*/
|
*/
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
{{ option.user.getLevelAndNumber() }}
|
{{ option.user.getLevelAndNumber() }}
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<span *ngIf="!option.user">{{ 'Unknown user' | translate }}</span>
|
<i *ngIf="!option.user">{{ unknownUserLabel | translate }}</i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngFor="let action of voteActions">
|
<div *ngFor="let action of voteActions">
|
||||||
|
@ -43,7 +43,8 @@
|
|||||||
.vote-candidate-name {
|
.vote-candidate-name {
|
||||||
grid-area: name;
|
grid-area: name;
|
||||||
display: flex;
|
display: flex;
|
||||||
span {
|
span,
|
||||||
|
i {
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
margin-bottom: auto;
|
margin-bottom: auto;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import { ViewAssignmentOption } from 'app/site/assignments/models/view-assignmen
|
|||||||
import { ViewAssignmentPoll } from 'app/site/assignments/models/view-assignment-poll';
|
import { ViewAssignmentPoll } from 'app/site/assignments/models/view-assignment-poll';
|
||||||
import { BasePollVoteComponentDirective, VoteOption } from 'app/site/polls/components/base-poll-vote.component';
|
import { BasePollVoteComponentDirective, VoteOption } from 'app/site/polls/components/base-poll-vote.component';
|
||||||
import { ViewUser } from 'app/site/users/models/view-user';
|
import { ViewUser } from 'app/site/users/models/view-user';
|
||||||
|
import { UnknownUserLabel } from '../../services/assignment-poll.service';
|
||||||
|
|
||||||
const voteOptions = {
|
const voteOptions = {
|
||||||
Yes: {
|
Yes: {
|
||||||
@ -47,6 +48,7 @@ const voteOptions = {
|
|||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class AssignmentPollVoteComponent extends BasePollVoteComponentDirective<ViewAssignmentPoll> implements OnInit {
|
export class AssignmentPollVoteComponent extends BasePollVoteComponentDirective<ViewAssignmentPoll> implements OnInit {
|
||||||
|
public unknownUserLabel = UnknownUserLabel;
|
||||||
public AssignmentPollMethod = AssignmentPollMethod;
|
public AssignmentPollMethod = AssignmentPollMethod;
|
||||||
public PollType = PollType;
|
public PollType = PollType;
|
||||||
public voteActions: VoteOption[] = [];
|
public voteActions: VoteOption[] = [];
|
||||||
|
@ -72,15 +72,18 @@ export class AssignmentPollComponent
|
|||||||
this.descriptionForm = this.formBuilder.group({
|
this.descriptionForm = this.formBuilder.group({
|
||||||
description: this.poll ? this.poll.description : ''
|
description: this.poll ? this.poll.description : ''
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('the poll: ', this.poll);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print the PDF of this poll with the corresponding options and numbers
|
* Print the PDF of this poll with the corresponding options and numbers
|
||||||
*/
|
*/
|
||||||
public printBallot(): void {
|
public printBallot(): void {
|
||||||
this.pdfService.printBallots(this.poll);
|
try {
|
||||||
|
this.pdfService.printBallots(this.poll);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
this.raiseError(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public openVotingWarning(): void {
|
public openVotingWarning(): void {
|
||||||
|
@ -141,9 +141,14 @@ export class AssignmentPollPdfService extends PollPdfService {
|
|||||||
return a.weight - b.weight;
|
return a.weight - b.weight;
|
||||||
});
|
});
|
||||||
const resultObject = candidates.map(cand => {
|
const resultObject = candidates.map(cand => {
|
||||||
return poll.pollmethod === AssignmentPollMethod.Y
|
const candidateName = cand.user?.full_name;
|
||||||
? this.createBallotOption(cand.user.full_name)
|
if (candidateName) {
|
||||||
: this.createYNBallotEntry(cand.user.full_name, poll.pollmethod);
|
return poll.pollmethod === AssignmentPollMethod.Y
|
||||||
|
? this.createBallotOption(candidateName)
|
||||||
|
: this.createYNBallotEntry(candidateName, poll.pollmethod);
|
||||||
|
} else {
|
||||||
|
throw new Error(this.translate.instant('This ballot contains deleted users.'));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (poll.pollmethod === AssignmentPollMethod.Y) {
|
if (poll.pollmethod === AssignmentPollMethod.Y) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { ConstantsService } from 'app/core/core-services/constants.service';
|
import { ConstantsService } from 'app/core/core-services/constants.service';
|
||||||
@ -23,6 +24,7 @@ import {
|
|||||||
VotingResult
|
VotingResult
|
||||||
} from 'app/site/polls/services/poll.service';
|
} from 'app/site/polls/services/poll.service';
|
||||||
|
|
||||||
|
export const UnknownUserLabel = _('Deleted user');
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
@ -159,11 +161,13 @@ export class AssignmentPollService extends PollService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Since pollData does not have any subtitle option
|
// Since pollData does not have any subtitle option
|
||||||
if (candidate instanceof ViewAssignmentOption) {
|
if (candidate instanceof ViewAssignmentOption && candidate.user) {
|
||||||
pollTableEntry.votingOption = candidate.user.short_name;
|
pollTableEntry.votingOption = candidate.user.short_name;
|
||||||
pollTableEntry.votingOptionSubtitle = candidate.user.getLevelAndNumber();
|
pollTableEntry.votingOptionSubtitle = candidate.user.getLevelAndNumber();
|
||||||
} else {
|
} else if (candidate.user) {
|
||||||
pollTableEntry.votingOption = (candidate as PollDataOption).user.short_name;
|
pollTableEntry.votingOption = (candidate as PollDataOption).user.short_name;
|
||||||
|
} else {
|
||||||
|
pollTableEntry.votingOption = UnknownUserLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pollTableEntry;
|
return pollTableEntry;
|
||||||
@ -248,8 +252,8 @@ export class AssignmentPollService extends PollService {
|
|||||||
}
|
}
|
||||||
return resultLabel;
|
return resultLabel;
|
||||||
});
|
});
|
||||||
|
const optionName = option.user?.short_name ?? UnknownUserLabel;
|
||||||
return `${option.user.short_name} · ${votingResults.join(' · ')}`;
|
return `${optionName} · ${votingResults.join(' · ')}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,12 @@
|
|||||||
<ng-container *ngIf="data.data.assignment_related_users && data.data.assignment_related_users.length">
|
<ng-container *ngIf="data.data.assignment_related_users && data.data.assignment_related_users.length">
|
||||||
<ol *ngIf="data.data.number_poll_candidates">
|
<ol *ngIf="data.data.number_poll_candidates">
|
||||||
<li *ngFor="let candidate of data.data.assignment_related_users">
|
<li *ngFor="let candidate of data.data.assignment_related_users">
|
||||||
{{ candidate.user }}
|
{{ getUserName(candidate) }}
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<ul *ngIf="!data.data.number_poll_candidates">
|
<ul *ngIf="!data.data.number_poll_candidates">
|
||||||
<li *ngFor="let candidate of data.data.assignment_related_users">
|
<li *ngFor="let candidate of data.data.assignment_related_users">
|
||||||
{{ candidate.user }}
|
{{ getUserName(candidate) }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -26,4 +26,8 @@ export class AssignmentSlideComponent extends BaseSlideComponentDirective<Assign
|
|||||||
public constructor() {
|
public constructor() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getUserName(relatedUser: { user: string }): string {
|
||||||
|
return relatedUser.user;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user