Rework assignment poll slide
Reworked assignment poll slide and refactored the assignment poll detail table into an own component
This commit is contained in:
parent
b873dc156b
commit
072ec937a1
@ -0,0 +1,42 @@
|
|||||||
|
<div *ngIf="poll">
|
||||||
|
<table class="assignment-result-table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th class="voting-option" translate>Candidates</th>
|
||||||
|
<th class="result yes">
|
||||||
|
<span *ngIf="!isMethodY" translate>
|
||||||
|
Yes
|
||||||
|
</span>
|
||||||
|
<span *ngIf="isMethodY" translate>
|
||||||
|
Votes
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="result no" translate *ngIf="!isMethodY">No</th>
|
||||||
|
<th class="result abstain" translate *ngIf="isMethodYNA">Abstain</th>
|
||||||
|
</tr>
|
||||||
|
<tr *ngFor="let row of tableData" [class]="row.class">
|
||||||
|
<td class="voting-option">
|
||||||
|
<div>
|
||||||
|
<span>
|
||||||
|
{{ row.votingOption | pollKeyVerbose | translate }}
|
||||||
|
</span>
|
||||||
|
<span class="user-subtitle" *ngIf="row.votingOptionSubtitle">
|
||||||
|
<br />
|
||||||
|
{{ row.votingOptionSubtitle }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="result" *ngFor="let vote of row.value">
|
||||||
|
<div class="single-result" [ngClass]="getVoteClass(vote)" *ngIf="vote && voteFitsMethod(vote)">
|
||||||
|
<span>
|
||||||
|
<span *ngIf="vote.showPercent">
|
||||||
|
{{ vote.amount | pollPercentBase: poll }}
|
||||||
|
</span>
|
||||||
|
{{ vote.amount | parsePollNumber }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
@ -0,0 +1,49 @@
|
|||||||
|
@import '~assets/styles/poll-styles-common.scss';
|
||||||
|
|
||||||
|
.assignment-result-table {
|
||||||
|
margin-top: 2em;
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
border-collapse: collapse;
|
||||||
|
|
||||||
|
th {
|
||||||
|
font-weight: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr {
|
||||||
|
height: 48px;
|
||||||
|
|
||||||
|
td:first-child {
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.sums {
|
||||||
|
border-bottom: none;
|
||||||
|
td {
|
||||||
|
padding-top: 1em;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.result {
|
||||||
|
text-align: right;
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.voting-option {
|
||||||
|
min-width: 200px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user + .sums {
|
||||||
|
td {
|
||||||
|
padding-top: 2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-result {
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { E2EImportsModule } from 'e2e-imports.module';
|
||||||
|
|
||||||
|
import { AssignmentPollDetailContentComponent } from './assignment-poll-detail-content.component';
|
||||||
|
|
||||||
|
describe('AssignmentPollDetailContentComponent', () => {
|
||||||
|
let component: AssignmentPollDetailContentComponent;
|
||||||
|
let fixture: ComponentFixture<AssignmentPollDetailContentComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [E2EImportsModule]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(AssignmentPollDetailContentComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,55 @@
|
|||||||
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
|
import { AssignmentPollMethod } from 'app/shared/models/assignments/assignment-poll';
|
||||||
|
import { ViewAssignmentPoll } from 'app/site/assignments/models/view-assignment-poll';
|
||||||
|
import { AssignmentPollService } from 'app/site/assignments/services/assignment-poll.service';
|
||||||
|
import { PollData, PollTableData, VotingResult } from 'app/site/polls/services/poll.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'os-assignment-poll-detail-content',
|
||||||
|
templateUrl: './assignment-poll-detail-content.component.html',
|
||||||
|
styleUrls: ['./assignment-poll-detail-content.component.scss']
|
||||||
|
})
|
||||||
|
export class AssignmentPollDetailContentComponent {
|
||||||
|
@Input()
|
||||||
|
public poll: ViewAssignmentPoll | PollData;
|
||||||
|
|
||||||
|
public constructor(private pollService: AssignmentPollService) {}
|
||||||
|
|
||||||
|
private get method(): string {
|
||||||
|
return this.poll.pollmethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isMethodY(): boolean {
|
||||||
|
return this.method === AssignmentPollMethod.Votes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isMethodYN(): boolean {
|
||||||
|
return this.method === AssignmentPollMethod.YN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isMethodYNA(): boolean {
|
||||||
|
return this.method === AssignmentPollMethod.YNA;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get tableData(): PollTableData[] {
|
||||||
|
return this.pollService.generateTableData(this.poll);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getVoteClass(votingResult: VotingResult): string {
|
||||||
|
return votingResult.vote;
|
||||||
|
}
|
||||||
|
|
||||||
|
public voteFitsMethod(result: VotingResult): boolean {
|
||||||
|
if (this.isMethodY) {
|
||||||
|
if (result.vote === 'abstain' || result.vote === 'no') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (this.isMethodYN) {
|
||||||
|
if (result.vote === 'abstain') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -123,6 +123,7 @@ import { PollKeyVerbosePipe } from './pipes/poll-key-verbose.pipe';
|
|||||||
import { PollPercentBasePipe } from './pipes/poll-percent-base.pipe';
|
import { PollPercentBasePipe } from './pipes/poll-percent-base.pipe';
|
||||||
import { VotingPrivacyWarningComponent } from './components/voting-privacy-warning/voting-privacy-warning.component';
|
import { VotingPrivacyWarningComponent } from './components/voting-privacy-warning/voting-privacy-warning.component';
|
||||||
import { MotionPollDetailContentComponent } from './components/motion-poll-detail-content/motion-poll-detail-content.component';
|
import { MotionPollDetailContentComponent } from './components/motion-poll-detail-content/motion-poll-detail-content.component';
|
||||||
|
import { AssignmentPollDetailContentComponent } from './components/assignment-poll-detail-content/assignment-poll-detail-content.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Share Module for all "dumb" components and pipes.
|
* Share Module for all "dumb" components and pipes.
|
||||||
@ -288,7 +289,8 @@ import { MotionPollDetailContentComponent } from './components/motion-poll-detai
|
|||||||
PollKeyVerbosePipe,
|
PollKeyVerbosePipe,
|
||||||
PollPercentBasePipe,
|
PollPercentBasePipe,
|
||||||
VotingPrivacyWarningComponent,
|
VotingPrivacyWarningComponent,
|
||||||
MotionPollDetailContentComponent
|
MotionPollDetailContentComponent,
|
||||||
|
AssignmentPollDetailContentComponent
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
PermsDirective,
|
PermsDirective,
|
||||||
@ -347,7 +349,8 @@ import { MotionPollDetailContentComponent } from './components/motion-poll-detai
|
|||||||
PollKeyVerbosePipe,
|
PollKeyVerbosePipe,
|
||||||
PollPercentBasePipe,
|
PollPercentBasePipe,
|
||||||
VotingPrivacyWarningComponent,
|
VotingPrivacyWarningComponent,
|
||||||
MotionPollDetailContentComponent
|
MotionPollDetailContentComponent,
|
||||||
|
AssignmentPollDetailContentComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
|
@ -28,54 +28,9 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="assignment-result-wrapper" *ngIf="poll.stateHasVotes">
|
<div class="assignment-result-wrapper" *ngIf="poll && poll.stateHasVotes">
|
||||||
<!-- Result Table -->
|
<!-- Result Table -->
|
||||||
<div>
|
<os-assignment-poll-detail-content [poll]="poll"></os-assignment-poll-detail-content>
|
||||||
<table class="assignment-result-table">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th class="voting-option" translate>Candidates</th>
|
|
||||||
<th class="result yes">
|
|
||||||
<span *ngIf="!poll.isMethodY" translate>
|
|
||||||
Yes
|
|
||||||
</span>
|
|
||||||
<span *ngIf="poll.isMethodY" translate>
|
|
||||||
Votes
|
|
||||||
</span>
|
|
||||||
</th>
|
|
||||||
<th class="result no" translate *ngIf="!poll.isMethodY">No</th>
|
|
||||||
<th class="result abstain" translate *ngIf="poll.isMethodYNA">Abstain</th>
|
|
||||||
</tr>
|
|
||||||
<tr *ngFor="let row of getTableData()" [class]="row.class">
|
|
||||||
<td class="voting-option">
|
|
||||||
<div>
|
|
||||||
<span>
|
|
||||||
{{ row.votingOption | pollKeyVerbose | translate }}
|
|
||||||
</span>
|
|
||||||
<span class="user-subtitle" *ngIf="row.votingOptionSubtitle">
|
|
||||||
<br />
|
|
||||||
{{ row.votingOptionSubtitle }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="result" *ngFor="let vote of row.value">
|
|
||||||
<div
|
|
||||||
class="single-result"
|
|
||||||
[ngClass]="getVoteClass(vote)"
|
|
||||||
*ngIf="vote && voteFitsMethod(vote)"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
<span *ngIf="vote.showPercent">
|
|
||||||
{{ vote.amount | pollPercentBase: poll }}
|
|
||||||
</span>
|
|
||||||
{{ vote.amount | parsePollNumber }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Result Chart -->
|
<!-- Result Chart -->
|
||||||
<div class="chart-wrapper">
|
<div class="chart-wrapper">
|
||||||
|
@ -1,55 +1,4 @@
|
|||||||
@import '~assets/styles/poll-colors.scss';
|
|
||||||
@import '~assets/styles/poll-styles-common.scss';
|
|
||||||
|
|
||||||
.assignment-result-wrapper {
|
.assignment-result-wrapper {
|
||||||
.assignment-result-table {
|
|
||||||
margin-top: 2em;
|
|
||||||
display: block;
|
|
||||||
overflow-x: auto;
|
|
||||||
border-collapse: collapse;
|
|
||||||
|
|
||||||
th {
|
|
||||||
font-weight: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr {
|
|
||||||
height: 48px;
|
|
||||||
|
|
||||||
td:first-child {
|
|
||||||
padding-right: 1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.sums {
|
|
||||||
border-bottom: none;
|
|
||||||
td {
|
|
||||||
padding-top: 1em;
|
|
||||||
padding-bottom: 1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.result {
|
|
||||||
text-align: right;
|
|
||||||
padding-left: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.voting-option {
|
|
||||||
min-width: 200px;
|
|
||||||
width: 100%;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user + .sums {
|
|
||||||
td {
|
|
||||||
padding-top: 2em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.single-result {
|
|
||||||
white-space: pre;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart-wrapper {
|
.chart-wrapper {
|
||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
.pie-chart {
|
.pie-chart {
|
||||||
|
@ -13,7 +13,6 @@ import { GroupRepositoryService } from 'app/core/repositories/users/group-reposi
|
|||||||
import { PromptService } from 'app/core/ui-services/prompt.service';
|
import { PromptService } from 'app/core/ui-services/prompt.service';
|
||||||
import { VoteValue } from 'app/shared/models/poll/base-vote';
|
import { VoteValue } from 'app/shared/models/poll/base-vote';
|
||||||
import { BasePollDetailComponent } from 'app/site/polls/components/base-poll-detail.component';
|
import { BasePollDetailComponent } from 'app/site/polls/components/base-poll-detail.component';
|
||||||
import { PollTableData, VotingResult } from 'app/site/polls/services/poll.service';
|
|
||||||
import { AssignmentPollDialogService } from '../../services/assignment-poll-dialog.service';
|
import { AssignmentPollDialogService } from '../../services/assignment-poll-dialog.service';
|
||||||
import { AssignmentPollService } from '../../services/assignment-poll.service';
|
import { AssignmentPollService } from '../../services/assignment-poll.service';
|
||||||
import { ViewAssignmentPoll } from '../../models/view-assignment-poll';
|
import { ViewAssignmentPoll } from '../../models/view-assignment-poll';
|
||||||
@ -121,27 +120,6 @@ export class AssignmentPollDetailComponent extends BasePollDetailComponent<ViewA
|
|||||||
return this.operator.hasPerms('assignments.can_manage');
|
return this.operator.hasPerms('assignments.can_manage');
|
||||||
}
|
}
|
||||||
|
|
||||||
public getVoteClass(votingResult: VotingResult): string {
|
|
||||||
return votingResult.vote;
|
|
||||||
}
|
|
||||||
|
|
||||||
public voteFitsMethod(result: VotingResult): boolean {
|
|
||||||
if (this.poll.isMethodY) {
|
|
||||||
if (result.vote === 'abstain' || result.vote === 'no') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (this.poll.isMethodYN) {
|
|
||||||
if (result.vote === 'abstain') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getTableData(): PollTableData[] {
|
|
||||||
return this.pollService.generateTableData(this.poll);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected onDeleted(): void {
|
protected onDeleted(): void {
|
||||||
this.router.navigate(['assignments', this.poll.assignment_id]);
|
this.router.navigate(['assignments', this.poll.assignment_id]);
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,14 @@ import {
|
|||||||
import { MajorityMethod, VOTE_UNDOCUMENTED } from 'app/shared/models/poll/base-poll';
|
import { MajorityMethod, VOTE_UNDOCUMENTED } from 'app/shared/models/poll/base-poll';
|
||||||
import { ParsePollNumberPipe } from 'app/shared/pipes/parse-poll-number.pipe';
|
import { ParsePollNumberPipe } from 'app/shared/pipes/parse-poll-number.pipe';
|
||||||
import { PollKeyVerbosePipe } from 'app/shared/pipes/poll-key-verbose.pipe';
|
import { PollKeyVerbosePipe } from 'app/shared/pipes/poll-key-verbose.pipe';
|
||||||
import { PollData, PollService, PollTableData, VotingResult } from 'app/site/polls/services/poll.service';
|
import {
|
||||||
|
PollData,
|
||||||
|
PollDataOption,
|
||||||
|
PollService,
|
||||||
|
PollTableData,
|
||||||
|
VotingResult
|
||||||
|
} from 'app/site/polls/services/poll.service';
|
||||||
|
import { ViewAssignmentOption } from '../models/view-assignment-option';
|
||||||
import { ViewAssignmentPoll } from '../models/view-assignment-poll';
|
import { ViewAssignmentPoll } from '../models/view-assignment-poll';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
@ -80,7 +87,7 @@ export class AssignmentPollService extends PollService {
|
|||||||
return poll;
|
return poll;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getGlobalVoteKeys(poll: ViewAssignmentPoll): VotingResult[] {
|
private getGlobalVoteKeys(poll: ViewAssignmentPoll | PollData): VotingResult[] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
vote: 'amount_global_no',
|
vote: 'amount_global_no',
|
||||||
@ -95,30 +102,45 @@ export class AssignmentPollService extends PollService {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public generateTableData(poll: ViewAssignmentPoll): PollTableData[] {
|
public generateTableData(poll: ViewAssignmentPoll | PollData): PollTableData[] {
|
||||||
|
console.log('poll: ', poll);
|
||||||
|
|
||||||
const tableData: PollTableData[] = poll.options
|
const tableData: PollTableData[] = poll.options
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
if (this.sortByVote) {
|
if (this.sortByVote) {
|
||||||
return b.yes - a.yes;
|
return b.yes - a.yes;
|
||||||
} else {
|
} else {
|
||||||
return b.weight - a.weight;
|
// PollData does not have weight, we need to rely on the order of things.
|
||||||
|
if (a.weight && b.weight) {
|
||||||
|
return b.weight - a.weight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(candidate => ({
|
.map((candidate: ViewAssignmentOption) => {
|
||||||
votingOption: candidate.user.short_name,
|
const pollTableEntry: PollTableData = {
|
||||||
votingOptionSubtitle: candidate.user.getLevelAndNumber(),
|
class: 'user',
|
||||||
class: 'user',
|
value: super.getVoteTableKeys(poll).map(
|
||||||
value: super.getVoteTableKeys(poll).map(
|
key =>
|
||||||
key =>
|
({
|
||||||
({
|
vote: key.vote,
|
||||||
vote: key.vote,
|
amount: candidate[key.vote],
|
||||||
amount: candidate[key.vote],
|
icon: key.icon,
|
||||||
icon: key.icon,
|
hide: key.hide,
|
||||||
hide: key.hide,
|
showPercent: key.showPercent
|
||||||
showPercent: key.showPercent
|
} as VotingResult)
|
||||||
} as VotingResult)
|
)
|
||||||
)
|
};
|
||||||
}));
|
|
||||||
|
// Since pollData does not have any subtitle option
|
||||||
|
if (candidate instanceof ViewAssignmentOption) {
|
||||||
|
pollTableEntry.votingOption = candidate.user.short_name;
|
||||||
|
pollTableEntry.votingOptionSubtitle = candidate.user.getLevelAndNumber();
|
||||||
|
} else {
|
||||||
|
pollTableEntry.votingOption = (candidate as PollDataOption).user.short_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pollTableEntry;
|
||||||
|
});
|
||||||
tableData.push(...this.formatVotingResultToTableData(this.getGlobalVoteKeys(poll), poll));
|
tableData.push(...this.formatVotingResultToTableData(this.getGlobalVoteKeys(poll), poll));
|
||||||
tableData.push(...this.formatVotingResultToTableData(super.getSumTableKeys(poll), poll));
|
tableData.push(...this.formatVotingResultToTableData(super.getSumTableKeys(poll), poll));
|
||||||
return tableData;
|
return tableData;
|
||||||
|
@ -105,17 +105,22 @@ export interface PollData {
|
|||||||
pollmethod: string;
|
pollmethod: string;
|
||||||
type: string;
|
type: string;
|
||||||
onehundred_percent_base: string;
|
onehundred_percent_base: string;
|
||||||
options: {
|
options: PollDataOption[];
|
||||||
user?: {
|
|
||||||
short_name: string;
|
|
||||||
};
|
|
||||||
yes?: number;
|
|
||||||
no?: number;
|
|
||||||
abstain?: number;
|
|
||||||
}[];
|
|
||||||
votesvalid: number;
|
votesvalid: number;
|
||||||
votesinvalid: number;
|
votesinvalid: number;
|
||||||
votescast: number;
|
votescast: number;
|
||||||
|
amount_global_no?: number;
|
||||||
|
amount_global_abstain?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PollDataOption {
|
||||||
|
user?: {
|
||||||
|
short_name?: string;
|
||||||
|
};
|
||||||
|
yes?: number;
|
||||||
|
no?: number;
|
||||||
|
abstain?: number;
|
||||||
|
weight?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OpenSlidesSettings {
|
interface OpenSlidesSettings {
|
||||||
@ -126,7 +131,7 @@ interface OpenSlidesSettings {
|
|||||||
* Interface describes the possible data for the result-table.
|
* Interface describes the possible data for the result-table.
|
||||||
*/
|
*/
|
||||||
export interface PollTableData {
|
export interface PollTableData {
|
||||||
votingOption: string;
|
votingOption?: string;
|
||||||
votingOptionSubtitle?: string;
|
votingOptionSubtitle?: string;
|
||||||
class?: string;
|
class?: string;
|
||||||
value: VotingResult[];
|
value: VotingResult[];
|
||||||
|
@ -3,11 +3,7 @@
|
|||||||
<h1 class="assignment-title">{{ data.data.assignment.title }}</h1>
|
<h1 class="assignment-title">{{ data.data.assignment.title }}</h1>
|
||||||
<h2 class="poll-title">{{ data.data.poll.title }}</h2>
|
<h2 class="poll-title">{{ data.data.poll.title }}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="charts-wrapper" *ngIf="data.data.poll.state === PollState.Published">
|
<div *ngIf="data.data.poll.state === PollState.Published">
|
||||||
<os-charts
|
<os-assignment-poll-detail-content [poll]="data.data.poll"></os-assignment-poll-detail-content>
|
||||||
[labels]="pollService.getChartLabels(data.data.poll)"
|
|
||||||
[data]="chartDataSubject | async"
|
|
||||||
[hasPadding]="false"
|
|
||||||
></os-charts>
|
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -5,7 +5,3 @@
|
|||||||
.slidetitle {
|
.slidetitle {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.charts-wrapper {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
@ -63,7 +63,7 @@ async def assignment_poll_slide(
|
|||||||
options = get_models(all_data, "assignments/assignment-option", poll["options_id"])
|
options = get_models(all_data, "assignments/assignment-option", poll["options_id"])
|
||||||
for option in sorted(options, key=lambda option: option["weight"]):
|
for option in sorted(options, key=lambda option: option["weight"]):
|
||||||
option_data: Dict[str, Any] = {
|
option_data: Dict[str, Any] = {
|
||||||
"user": {"full_name": await get_user_name(all_data, option["user_id"])}
|
"user": {"short_name": await get_user_name(all_data, option["user_id"])}
|
||||||
}
|
}
|
||||||
if poll["state"] == AssignmentPoll.STATE_PUBLISHED:
|
if poll["state"] == AssignmentPoll.STATE_PUBLISHED:
|
||||||
option_data["yes"] = float(option["yes"])
|
option_data["yes"] = float(option["yes"])
|
||||||
|
@ -16,3 +16,4 @@ roman>=2.0,<3.2
|
|||||||
setuptools>=29.0,<42.0
|
setuptools>=29.0,<42.0
|
||||||
typing_extensions>=3.6.6,<3.8
|
typing_extensions>=3.6.6,<3.8
|
||||||
websockets>=8.0,<9.0
|
websockets>=8.0,<9.0
|
||||||
|
twisted>=19.0,<20.0
|
Loading…
Reference in New Issue
Block a user