Enhance table layouts
Enhance the result table layout for assignments
This commit is contained in:
parent
9d7028ea5f
commit
53b9ce73f2
@ -215,6 +215,10 @@ export class ChartsComponent extends BaseViewComponent {
|
|||||||
*/
|
*/
|
||||||
@Input()
|
@Input()
|
||||||
public pieChartOptions: ChartOptions = {
|
public pieChartOptions: ChartOptions = {
|
||||||
|
responsive: true,
|
||||||
|
legend: {
|
||||||
|
position: 'left'
|
||||||
|
},
|
||||||
aspectRatio: 1
|
aspectRatio: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,6 +194,12 @@ export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel
|
|||||||
@Input()
|
@Input()
|
||||||
public showListOfSpeakers = true;
|
public showListOfSpeakers = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To optionally hide the menu slot
|
||||||
|
*/
|
||||||
|
@Input()
|
||||||
|
public showMenu = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fix value for the height of the rows in the virtual-scroll-list.
|
* Fix value for the height of the rows in the virtual-scroll-list.
|
||||||
*/
|
*/
|
||||||
@ -347,7 +353,7 @@ export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel
|
|||||||
hidden.push('selection');
|
hidden.push('selection');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.alwaysShowMenu && !this.isMobile) {
|
if ((!this.alwaysShowMenu && !this.isMobile) || !this.showMenu) {
|
||||||
hidden.push('menu');
|
hidden.push('menu');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,18 @@ export class AssignmentPoll extends BasePoll<
|
|||||||
public global_abstain: boolean;
|
public global_abstain: boolean;
|
||||||
public description: string;
|
public description: string;
|
||||||
|
|
||||||
|
public get isMethodY(): boolean {
|
||||||
|
return this.pollmethod === AssignmentPollMethod.Votes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isMethodYN(): boolean {
|
||||||
|
return this.pollmethod === AssignmentPollMethod.YN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isMethodYNA(): boolean {
|
||||||
|
return this.pollmethod === AssignmentPollMethod.YNA;
|
||||||
|
}
|
||||||
|
|
||||||
public get pollmethodFields(): CalculablePollKey[] {
|
public get pollmethodFields(): CalculablePollKey[] {
|
||||||
if (this.pollmethod === AssignmentPollMethod.YN) {
|
if (this.pollmethod === AssignmentPollMethod.YN) {
|
||||||
return ['yes', 'no'];
|
return ['yes', 'no'];
|
||||||
|
@ -16,20 +16,29 @@
|
|||||||
|
|
||||||
<!-- Detailview for poll -->
|
<!-- Detailview for poll -->
|
||||||
<ng-template #viewTemplate>
|
<ng-template #viewTemplate>
|
||||||
<ng-container *ngIf="isReady">
|
<div *ngIf="isReady">
|
||||||
<h1>{{ poll.title }}</h1>
|
<h1>{{ poll.title }}</h1>
|
||||||
<span *ngIf="poll.type !== 'analog'">{{ poll.typeVerbose | translate }}</span>
|
<span *ngIf="poll.type !== 'analog'">{{ poll.typeVerbose | translate }}</span>
|
||||||
|
|
||||||
<div *ngIf="poll.stateHasVotes">
|
<div *ngIf="poll.stateHasVotes">
|
||||||
<div [class]="chartType === 'horizontalBar' ? 'result-wrapper-bar-chart' : 'result-wrapper-pie-chart'">
|
<div class="assignment-result-wrapper">
|
||||||
<!-- Result Table -->
|
<!-- Result Table -->
|
||||||
<table class="assignment-result-table">
|
<table class="assignment-result-table">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th translate>Candidates</th>
|
<th translate>Candidates</th>
|
||||||
<th translate>Votes</th>
|
<th>
|
||||||
|
<span *ngIf="!poll.isMethodY" translate>
|
||||||
|
Yes
|
||||||
|
</span>
|
||||||
|
<span *ngIf="poll.isMethodY" translate>
|
||||||
|
Votes
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th translate *ngIf="!poll.isMethodY">No</th>
|
||||||
|
<th translate *ngIf="poll.isMethodYNA">Abstain</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr *ngFor="let row of poll.tableData">
|
<tr *ngFor="let row of poll.tableData" [class]="row.class">
|
||||||
<td>
|
<td>
|
||||||
<span>
|
<span>
|
||||||
{{ row.votingOption | pollKeyVerbose | translate }}
|
{{ row.votingOption | pollKeyVerbose | translate }}
|
||||||
@ -39,16 +48,8 @@
|
|||||||
{{ row.votingOptionSubtitle }}
|
{{ row.votingOptionSubtitle }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td *ngFor="let vote of row.value">
|
||||||
<div *ngFor="let vote of row.value">
|
<div class="single-result" *ngIf="vote && voteFitsMethod(vote)">
|
||||||
<div class="single-result" *ngIf="voteFitsMethod(vote)">
|
|
||||||
<os-icon-container *ngIf="vote.icon" [icon]="vote.icon">
|
|
||||||
{{ vote.vote | pollKeyVerbose | translate }}
|
|
||||||
</os-icon-container>
|
|
||||||
<span *ngIf="!vote.icon">
|
|
||||||
{{ vote.vote | pollKeyVerbose | translate }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
{{ vote.amount | parsePollNumber }}
|
{{ vote.amount | parsePollNumber }}
|
||||||
<span *ngIf="vote.showPercent">
|
<span *ngIf="vote.showPercent">
|
||||||
@ -56,7 +57,6 @@
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -71,12 +71,12 @@
|
|||||||
[labels]="candidatesLabels"
|
[labels]="candidatesLabels"
|
||||||
[data]="chartDataSubject"
|
[data]="chartDataSubject"
|
||||||
[hasPadding]="false"
|
[hasPadding]="false"
|
||||||
[legendPosition]="isVotedPoll ? 'right' : 'top'"
|
legendPosition="right"
|
||||||
></os-charts>
|
></os-charts>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Single Votes Table -->
|
<!-- Single Votes Table -->
|
||||||
<ng-container class="named-result-table" *ngIf="poll.type === 'named'">
|
<div class="named-result-table" *ngIf="poll.type === 'named'">
|
||||||
<h3>{{ 'Single votes' | translate }}</h3>
|
<h3>{{ 'Single votes' | translate }}</h3>
|
||||||
<os-list-view-table
|
<os-list-view-table
|
||||||
*ngIf="votesDataObservable"
|
*ngIf="votesDataObservable"
|
||||||
@ -85,47 +85,41 @@
|
|||||||
[filterProps]="filterProps"
|
[filterProps]="filterProps"
|
||||||
[allowProjector]="false"
|
[allowProjector]="false"
|
||||||
[fullScreen]="false"
|
[fullScreen]="false"
|
||||||
[vScrollFixed]="isVotedPoll ? -1 : 60"
|
[vScrollFixed]="-1"
|
||||||
listStorageKey="assignment-poll-vote"
|
listStorageKey="assignment-poll-vote"
|
||||||
|
[showListOfSpeakers]="false"
|
||||||
|
[showMenu]="false"
|
||||||
[cssClasses]="{ 'single-votes-table': true }"
|
[cssClasses]="{ 'single-votes-table': true }"
|
||||||
>
|
>
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div *pblNgridHeaderCellDef="'user'; col as col">
|
<div *pblNgridHeaderCellDef="'user'; col as col">
|
||||||
{{ col.label | translate }}
|
{{ col.label | translate }}
|
||||||
</div>
|
</div>
|
||||||
<div *pblNgridHeaderCellDef="'*'; col as col">
|
<div *pblNgridHeaderCellDef="'votes'; col as col">
|
||||||
{{ col.label | translate }}
|
{{ col.label | translate }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Content -->
|
<!-- Content -->
|
||||||
<div *pblNgridCellDef="'user'; row as vote">
|
<div *pblNgridCellDef="'user'; row as vote">
|
||||||
<b *ngIf="vote.user">{{ vote.user.getFullName() }}</b>
|
<div *ngIf="vote.user">
|
||||||
<b *ngIf="!vote.user">{{ 'Anonymous' | translate }}</b>
|
{{ vote.user.getShortName() }}
|
||||||
|
<div class="user-subtitle" *ngIf="vote.user.getLevelAndNumber()">
|
||||||
|
{{ vote.user.getLevelAndNumber() }}
|
||||||
</div>
|
</div>
|
||||||
<!-- Y/N/(A) -->
|
|
||||||
<ng-container *ngIf="poll.pollmethod !== AssignmentPollMethod.Votes">
|
|
||||||
<ng-container *ngFor="let option of poll.options">
|
|
||||||
<div
|
|
||||||
*pblNgridCellDef="'votes-' + option.user_id; row as vote"
|
|
||||||
[ngClass]="voteOptionStyle[vote.votes[option.user_id].value].css"
|
|
||||||
class="vote-field"
|
|
||||||
>
|
|
||||||
<mat-icon> {{ voteOptionStyle[vote.votes[option.user_id].value].icon }}</mat-icon>
|
|
||||||
{{ vote.votes[option.user_id].valueVerbose | translate }}
|
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
<div *ngIf="!vote.user">
|
||||||
</ng-container>
|
{{ 'Anonymous' | translate }}
|
||||||
<!-- Votes method -->
|
</div>
|
||||||
<ng-container *ngIf="poll.pollmethod === AssignmentPollMethod.Votes">
|
</div>
|
||||||
<div *pblNgridCellDef="'votes'; row as vote">
|
|
||||||
<div *ngFor="let candidate of vote.votes">{{ candidate }}</div>
|
<div *pblNgridCellDef="'votes'; row as vote" >
|
||||||
|
<div class="single-vote-result" *ngFor="let candidate of vote.votes">{{ candidate }}</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
|
||||||
</os-list-view-table>
|
</os-list-view-table>
|
||||||
<div *ngIf="!votesDataObservable">
|
<div *ngIf="!votesDataObservable">
|
||||||
{{ 'The individual votes were anonymized.' | translate }}
|
{{ 'The individual votes were anonymized.' | translate }}
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Meta Infos -->
|
<!-- Meta Infos -->
|
||||||
@ -142,7 +136,7 @@
|
|||||||
{{ '100% base' | translate }}: {{ poll.percentBaseVerbose | translate }}
|
{{ '100% base' | translate }}: {{ poll.percentBaseVerbose | translate }}
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<!-- More Menu -->
|
<!-- More Menu -->
|
||||||
|
@ -1,39 +1,14 @@
|
|||||||
@import '~assets/styles/variables.scss';
|
@import '~assets/styles/variables.scss';
|
||||||
@import '~assets/styles/poll-colors.scss';
|
@import '~assets/styles/poll-colors.scss';
|
||||||
|
|
||||||
%assignment-result-wrapper {
|
.assignment-result-wrapper {
|
||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-gap: 10px;
|
grid-gap: 10px;
|
||||||
}
|
|
||||||
|
|
||||||
.result-wrapper-bar-chart {
|
.assignment-result-table {
|
||||||
@extend %assignment-result-wrapper;
|
border-collapse: collapse;
|
||||||
grid-template-areas:
|
|
||||||
'results'
|
|
||||||
'chart'
|
|
||||||
'names';
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-wrapper-pie-chart {
|
|
||||||
@extend %assignment-result-wrapper;
|
|
||||||
grid-template-areas:
|
|
||||||
'chart'
|
|
||||||
'results'
|
|
||||||
'names';
|
|
||||||
}
|
|
||||||
|
|
||||||
@include desktop {
|
|
||||||
.result-wrapper-pie-chart {
|
|
||||||
grid-template-areas:
|
|
||||||
'results chart'
|
|
||||||
'names names';
|
|
||||||
grid-template-columns: 2fr 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.assignment-result-table {
|
|
||||||
grid-area: results;
|
|
||||||
th {
|
th {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
font-weight: initial;
|
font-weight: initial;
|
||||||
@ -47,27 +22,48 @@
|
|||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.single-result {
|
tr.sums {
|
||||||
display: flex;
|
border-bottom: none;
|
||||||
|
td {
|
||||||
|
padding-top: 1em;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user + .sums {
|
||||||
|
td {
|
||||||
|
padding-top: 4em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pie-chart {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 50%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.assignment-result-chart {
|
.single-vote-result + .single-vote-result {
|
||||||
grid-area: chart;
|
margin-top: 1em;
|
||||||
}
|
|
||||||
|
|
||||||
.pie-chart {
|
|
||||||
max-width: 300px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.named-result-table {
|
.named-result-table {
|
||||||
grid-area: names;
|
|
||||||
.mat-form-field {
|
.mat-form-field {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.single-votes-table {
|
||||||
|
display: block;
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vote-field {
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
padding-right: 12px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.assignment-poll-meta {
|
.assignment-poll-meta {
|
||||||
@ -76,22 +72,6 @@
|
|||||||
padding-top: 20px;
|
padding-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.single-votes-table {
|
|
||||||
display: block;
|
|
||||||
height: 500px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.openslides-theme .pbl-ngrid-row:hover {
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.openslides-theme os-list-view-table os-sort-filter-bar .custom-table-header {
|
|
||||||
&,
|
|
||||||
.action-buttons .input-container input {
|
|
||||||
background: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.voted-yes {
|
.voted-yes {
|
||||||
color: $votes-yes-color;
|
color: $votes-yes-color;
|
||||||
}
|
}
|
||||||
@ -104,6 +84,18 @@
|
|||||||
color: $votes-abstain-color;
|
color: $votes-abstain-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// theme
|
||||||
|
.openslides-theme .pbl-ngrid-row:hover {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openslides-theme os-list-view-table os-sort-filter-bar .custom-table-header {
|
||||||
|
&,
|
||||||
|
.action-buttons .input-container input {
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.openslides-theme .pbl-ngrid-no-data {
|
.openslides-theme .pbl-ngrid-no-data {
|
||||||
top: 10%;
|
top: 10%;
|
||||||
}
|
}
|
||||||
@ -123,11 +115,3 @@
|
|||||||
border-right: 1px solid #e0e0e0;
|
border-right: 1px solid #e0e0e0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.vote-field {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
padding-right: 12px;
|
|
||||||
}
|
|
||||||
|
@ -11,9 +11,7 @@ import { AssignmentPollRepositoryService } from 'app/core/repositories/assignmen
|
|||||||
import { AssignmentVoteRepositoryService } from 'app/core/repositories/assignments/assignment-vote-repository.service';
|
import { AssignmentVoteRepositoryService } from 'app/core/repositories/assignments/assignment-vote-repository.service';
|
||||||
import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service';
|
import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service';
|
||||||
import { PromptService } from 'app/core/ui-services/prompt.service';
|
import { PromptService } from 'app/core/ui-services/prompt.service';
|
||||||
import { ViewportService } from 'app/core/ui-services/viewport.service';
|
|
||||||
import { ChartType } from 'app/shared/components/charts/charts.component';
|
import { ChartType } from 'app/shared/components/charts/charts.component';
|
||||||
import { AssignmentPollMethod } from 'app/shared/models/assignments/assignment-poll';
|
|
||||||
import { BasePollDetailComponent } from 'app/site/polls/components/base-poll-detail.component';
|
import { BasePollDetailComponent } from 'app/site/polls/components/base-poll-detail.component';
|
||||||
import { VotingResult } from 'app/site/polls/models/view-base-poll';
|
import { VotingResult } from 'app/site/polls/models/view-base-poll';
|
||||||
import { PollService } from 'app/site/polls/services/poll.service';
|
import { PollService } from 'app/site/polls/services/poll.service';
|
||||||
@ -27,8 +25,6 @@ import { ViewAssignmentPoll } from '../../models/view-assignment-poll';
|
|||||||
encapsulation: ViewEncapsulation.None
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
export class AssignmentPollDetailComponent extends BasePollDetailComponent<ViewAssignmentPoll> {
|
export class AssignmentPollDetailComponent extends BasePollDetailComponent<ViewAssignmentPoll> {
|
||||||
public AssignmentPollMethod = AssignmentPollMethod;
|
|
||||||
|
|
||||||
public columnDefinitionSingleVotes: PblColumnDefinition[];
|
public columnDefinitionSingleVotes: PblColumnDefinition[];
|
||||||
|
|
||||||
public filterProps = ['user.getFullName'];
|
public filterProps = ['user.getFullName'];
|
||||||
@ -41,10 +37,6 @@ export class AssignmentPollDetailComponent extends BasePollDetailComponent<ViewA
|
|||||||
return this._chartType;
|
return this._chartType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get isVotedPoll(): boolean {
|
|
||||||
return this.poll.pollmethod === AssignmentPollMethod.Votes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _chartType: ChartType = 'horizontalBar';
|
private _chartType: ChartType = 'horizontalBar';
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
@ -58,67 +50,48 @@ export class AssignmentPollDetailComponent extends BasePollDetailComponent<ViewA
|
|||||||
pollDialog: AssignmentPollDialogService,
|
pollDialog: AssignmentPollDialogService,
|
||||||
pollService: PollService,
|
pollService: PollService,
|
||||||
votesRepo: AssignmentVoteRepositoryService,
|
votesRepo: AssignmentVoteRepositoryService,
|
||||||
private operator: OperatorService,
|
private operator: OperatorService
|
||||||
private viewport: ViewportService
|
|
||||||
) {
|
) {
|
||||||
super(title, translate, matSnackbar, repo, route, groupRepo, prompt, pollDialog, pollService, votesRepo);
|
super(title, translate, matSnackbar, repo, route, groupRepo, prompt, pollDialog, pollService, votesRepo);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected createVotesData(): void {
|
protected createVotesData(): void {
|
||||||
const votes = {};
|
const votes = {};
|
||||||
let i = -1;
|
|
||||||
|
|
||||||
const definitions: PblColumnDefinition[] = [
|
const definitions: PblColumnDefinition[] = [
|
||||||
{
|
{
|
||||||
prop: 'user',
|
prop: 'user',
|
||||||
label: 'Participant',
|
label: 'Participant',
|
||||||
width: '180px',
|
width: '40%',
|
||||||
pin: this.viewport.isMobile ? undefined : 'start'
|
minWidth: 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'votes',
|
||||||
|
label: 'Votes',
|
||||||
|
width: '60%',
|
||||||
|
minWidth: 300
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
if (this.isVotedPoll) {
|
|
||||||
definitions.push(this.getVoteColumnDefinition('votes', 'Votes'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* builds an object of the following form:
|
|
||||||
* {
|
|
||||||
* userId: {
|
|
||||||
* user: ViewUser,
|
|
||||||
* votes: { candidateId: voteValue } // for YN(A)
|
|
||||||
* | candidate_name[] // for Votes
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
for (const option of this.poll.options) {
|
for (const option of this.poll.options) {
|
||||||
if (!this.isVotedPoll) {
|
|
||||||
definitions.push(this.getVoteColumnDefinition('votes-' + option.user_id, option.user.getFullName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const vote of option.votes) {
|
for (const vote of option.votes) {
|
||||||
// if poll was pseudoanonymized, use a negative index to not interfere with
|
const userId = vote.user_id;
|
||||||
// possible named votes (although this should never happen)
|
|
||||||
const userId = vote.user_id || --i;
|
|
||||||
if (!votes[userId]) {
|
if (!votes[userId]) {
|
||||||
votes[userId] = {
|
votes[userId] = {
|
||||||
user: vote.user,
|
user: vote.user,
|
||||||
votes: this.isVotedPoll ? [] : {}
|
votes: []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// on votes method, we fill an array with all chosen candidates
|
|
||||||
// on YN(A) we map candidate ids to the vote
|
|
||||||
if (this.isVotedPoll) {
|
|
||||||
if (vote.weight > 0) {
|
if (vote.weight > 0) {
|
||||||
|
if (this.poll.isMethodY) {
|
||||||
if (vote.value === 'Y') {
|
if (vote.value === 'Y') {
|
||||||
votes[userId].votes.push(option.user.getFullName());
|
votes[userId].votes.push(option.user.getFullName());
|
||||||
} else if (vote.value === 'N') {
|
} else {
|
||||||
votes[userId].votes.push(this.translate.instant('No'));
|
votes[userId].votes.push(this.voteValueToLabel(vote.value));
|
||||||
} else if (vote.value === 'A') {
|
|
||||||
votes[userId].votes.push(this.translate.instant('Abstain'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
votes[userId].votes[option.user_id] = vote;
|
votes[userId].votes.push(`${option.user.getShortName()}: ${this.voteValueToLabel(vote.value)}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,17 +102,20 @@ export class AssignmentPollDetailComponent extends BasePollDetailComponent<ViewA
|
|||||||
this.isReady = true;
|
this.isReady = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getVoteColumnDefinition(prop: string, label: string): PblColumnDefinition {
|
private voteValueToLabel(vote: 'Y' | 'N' | 'A'): string {
|
||||||
return {
|
if (vote === 'Y') {
|
||||||
prop: prop,
|
return this.translate.instant('Yes');
|
||||||
label: label,
|
} else if (vote === 'N') {
|
||||||
minWidth: 80,
|
return this.translate.instant('No');
|
||||||
width: 'auto'
|
} else if (vote === 'A') {
|
||||||
};
|
return this.translate.instant('Abstain');
|
||||||
|
} else {
|
||||||
|
throw new Error(`voteValueToLabel received illegal arguments: ${vote}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected initChartData(): void {
|
protected initChartData(): void {
|
||||||
if (this.isVotedPoll) {
|
if (this.poll.isMethodY) {
|
||||||
this._chartType = 'doughnut';
|
this._chartType = 'doughnut';
|
||||||
this.chartDataSubject.next(this.pollService.generateCircleChartData(this.poll));
|
this.chartDataSubject.next(this.pollService.generateCircleChartData(this.poll));
|
||||||
} else {
|
} else {
|
||||||
@ -152,11 +128,11 @@ export class AssignmentPollDetailComponent extends BasePollDetailComponent<ViewA
|
|||||||
}
|
}
|
||||||
|
|
||||||
public voteFitsMethod(result: VotingResult): boolean {
|
public voteFitsMethod(result: VotingResult): boolean {
|
||||||
if (this.poll.pollmethod === AssignmentPollMethod.Votes) {
|
if (this.poll.isMethodY) {
|
||||||
if (result.vote === 'abstain' || result.vote === 'no') {
|
if (result.vote === 'abstain' || result.vote === 'no') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (this.poll.pollmethod === AssignmentPollMethod.YN) {
|
} else if (this.poll.isMethodYN) {
|
||||||
if (result.vote === 'abstain') {
|
if (result.vote === 'abstain') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ export class ViewAssignmentPoll extends ViewBasePoll<AssignmentPoll, AssignmentP
|
|||||||
const tableData: PollTableData[] = this.options.map(candidate => ({
|
const tableData: PollTableData[] = this.options.map(candidate => ({
|
||||||
votingOption: candidate.user.short_name,
|
votingOption: candidate.user.short_name,
|
||||||
votingOptionSubtitle: candidate.user.getLevelAndNumber(),
|
votingOptionSubtitle: candidate.user.getLevelAndNumber(),
|
||||||
|
class: 'user',
|
||||||
value: this.voteTableKeys.map(
|
value: this.voteTableKeys.map(
|
||||||
key =>
|
key =>
|
||||||
({
|
({
|
||||||
@ -84,6 +84,7 @@ export class ViewAssignmentPoll extends ViewBasePoll<AssignmentPoll, AssignmentP
|
|||||||
tableData.push(
|
tableData.push(
|
||||||
...this.sumTableKeys.map(key => ({
|
...this.sumTableKeys.map(key => ({
|
||||||
votingOption: key.vote,
|
votingOption: key.vote,
|
||||||
|
class: 'sums',
|
||||||
value: [
|
value: [
|
||||||
{
|
{
|
||||||
amount: this[key.vote],
|
amount: this[key.vote],
|
||||||
@ -93,7 +94,6 @@ export class ViewAssignmentPoll extends ViewBasePoll<AssignmentPoll, AssignmentP
|
|||||||
]
|
]
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
return tableData;
|
return tableData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import { E2EImportsModule } from 'e2e-imports.module';
|
|||||||
|
|
||||||
import { PollFormComponent } from './poll-form.component';
|
import { PollFormComponent } from './poll-form.component';
|
||||||
|
|
||||||
fdescribe('PollFormComponent', () => {
|
describe('PollFormComponent', () => {
|
||||||
let component: PollFormComponent<any>;
|
let component: PollFormComponent<any>;
|
||||||
let fixture: ComponentFixture<PollFormComponent<any>>;
|
let fixture: ComponentFixture<PollFormComponent<any>>;
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ export enum PollClassType {
|
|||||||
export interface PollTableData {
|
export interface PollTableData {
|
||||||
votingOption: string;
|
votingOption: string;
|
||||||
votingOptionSubtitle?: string;
|
votingOptionSubtitle?: string;
|
||||||
|
class?: string;
|
||||||
value: VotingResult[];
|
value: VotingResult[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,10 +163,10 @@ export abstract class ViewBasePoll<
|
|||||||
public abstract get percentBaseVerbose(): string;
|
public abstract get percentBaseVerbose(): string;
|
||||||
|
|
||||||
public get showAbstainPercent(): boolean {
|
public get showAbstainPercent(): boolean {
|
||||||
return this.onehundred_percent_base === PercentBase.YNA;
|
return this.poll.onehundred_percent_base === PercentBase.YNA;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract readonly pollClassType: PollClassType;
|
public abstract readonly pollClassType: 'motion' | 'assignment';
|
||||||
|
|
||||||
public canBeVotedFor: () => boolean;
|
public canBeVotedFor: () => boolean;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user