Added reset button
This commit is contained in:
parent
d4d7c9de99
commit
800b7536e8
|
@ -8,7 +8,8 @@
|
|||
<ng-container *ngIf="(viewModel$ | async) as data; else spinner">
|
||||
<app-election [viewModel]="data" (valueChanges)="onValueChanges($event)"
|
||||
[electedCandidates]="electedCandidates$ | async"
|
||||
(calculate)="onCalculate($event)"></app-election>
|
||||
(calculate)="onCalculate($event)"
|
||||
(reset)="onReset()"></app-election>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
loadElectionResultAction,
|
||||
loadPartiesAction,
|
||||
loadSingleElectionAction,
|
||||
modifyElectionResultAction
|
||||
modifyElectionResultAction, resetElectionResult
|
||||
} from "../store/elections.actions";
|
||||
import {DEFAULT_RESULT, ElectionResult} from "../model/election-result";
|
||||
import {FormElectionResult} from "../model/form-election-result";
|
||||
|
@ -111,4 +111,8 @@ export class ElectionContainerComponent implements OnInit {
|
|||
onCalculate(event: ElectionResult) {
|
||||
this.store.dispatch(calculateAction({payload: event}));
|
||||
}
|
||||
|
||||
onReset() {
|
||||
this.store.dispatch(resetElectionResult());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
|
||||
<app-election-result [electedCandidates]="electedCandidates" [parties]="viewModel.parties"></app-election-result>
|
||||
|
||||
<button class="mt-2" mat-raised-button i18n #calculateButton (keyup.enter)="onCalculate()" (click)="onCalculate()">
|
||||
<mat-spinner class="spinner" *ngIf="showSpinner"></mat-spinner>
|
||||
Calculate
|
||||
</button>
|
||||
<div class="row">
|
||||
<button class="mt-2" mat-raised-button i18n="@@button.calculate" #calculateButton (keyup.enter)="onCalculate()" (click)="onCalculate()">
|
||||
<mat-spinner class="spinner" *ngIf="showSpinner"></mat-spinner>
|
||||
Calculate
|
||||
</button>
|
||||
|
||||
<button class="mt-2" mat-raised-button i18n="@@button.reset" (keyup.enter)="onReset()" (click)="onReset()">Reset</button>
|
||||
</div>
|
||||
|
||||
<form [formGroup]="form">
|
||||
<mat-tab-group>
|
||||
|
|
|
@ -9,3 +9,7 @@
|
|||
.mt-2 {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.row {
|
||||
@include mixins.justifyContent(space-between);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import {ElectionResult} from "../model/election-result";
|
|||
import {FormElectionResult} from "../model/form-election-result";
|
||||
import {ElectedCandidates} from "../model/elected-candidates";
|
||||
import {mapConstituencyResultsForm, mapOverallResultsForm} from "../store/elections.reducer";
|
||||
import {debounceTime, distinctUntilChanged} from "rxjs";
|
||||
import {debounceTime, distinctUntilChanged, filter} from "rxjs";
|
||||
|
||||
@Component({
|
||||
selector: 'app-election',
|
||||
|
@ -34,6 +34,8 @@ export class ElectionComponent implements OnInit {
|
|||
readonly valueChanges: EventEmitter<FormElectionResult> = new EventEmitter<FormElectionResult>();
|
||||
@Output()
|
||||
readonly calculate: EventEmitter<ElectionResult> = new EventEmitter<ElectionResult>();
|
||||
@Output()
|
||||
readonly reset: EventEmitter<boolean> = new EventEmitter<boolean>();
|
||||
|
||||
constructor(private fb: FormBuilder) {
|
||||
this.overallResults = this.fb.group({});
|
||||
|
@ -82,6 +84,7 @@ export class ElectionComponent implements OnInit {
|
|||
})
|
||||
this.constituencyToId = constituencyToId;
|
||||
this.constituencyNumberToName = constituencyNumberToName;
|
||||
this.updateForm(data.electionResult);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
@ -133,6 +136,40 @@ export class ElectionComponent implements OnInit {
|
|||
this.calculate.emit(electionResult);
|
||||
}
|
||||
|
||||
onReset() {
|
||||
this.reset.emit(true);
|
||||
}
|
||||
|
||||
private updateForm(electionResult: ModifiedElectionResult) {
|
||||
for (const votingResult of electionResult.overallResults) {
|
||||
const formGroup = this.overallResults.get(votingResult.partyAbbreviation);
|
||||
formGroup?.get('votesOnNomination')?.setValue(votingResult.votesOnNomination, { emitEvent: false });
|
||||
formGroup?.get('votesThroughHealing')?.setValue(votingResult.votesThroughHealing, { emitEvent: false });
|
||||
const votesPerPosition = formGroup?.get('votesPerPosition');
|
||||
const {map, entries} = this.buildVotesPerPosition(votingResult);
|
||||
for (const number of entries) {
|
||||
votesPerPosition?.get(number)?.setValue(map.get(number) || 0, { emitEvent: false });
|
||||
}
|
||||
}
|
||||
for (const constituencyNumber of electionResult.constituencyResults.keys()) {
|
||||
const constituency = this.constituencyToId.get(+constituencyNumber);
|
||||
const votingResults = electionResult.constituencyResults.get(constituencyNumber);
|
||||
if (constituency == null || votingResults == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const constituencyFormGroup = this.constituencyResults.get(constituency.name);
|
||||
|
||||
for (const votingResult of votingResults) {
|
||||
const formGroup = constituencyFormGroup?.get(votingResult.partyAbbreviation);
|
||||
const votesPerPosition = formGroup?.get('votesPerPosition');
|
||||
for (const number in votingResult.votesPerPosition) {
|
||||
votesPerPosition?.get(number)?.setValue(votingResult.votesPerPosition[number], { emitEvent: false });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private setUpForm(election: Election, electionResult: ModifiedElectionResult) {
|
||||
this.overallResults = this.fb.group({});
|
||||
this.constituencyResults = this.fb.group({});
|
||||
|
@ -150,15 +187,7 @@ export class ElectionComponent implements OnInit {
|
|||
partyAbbreviation: this.fb.control<string>(votingResult.partyAbbreviation),
|
||||
nominationName: this.fb.control<string>(votingResult.nominationName),
|
||||
});
|
||||
const map = new Map<string, number>();
|
||||
for (const number in votingResult.votesPerPosition) {
|
||||
map.set(number, votingResult.votesPerPosition[number]);
|
||||
}
|
||||
const entries = [...map.entries()]
|
||||
.sort((a, b) => {
|
||||
return +a[0] - +b[0];
|
||||
})
|
||||
.map(entry => entry[0]);
|
||||
const {map, entries} = this.buildVotesPerPosition(votingResult);
|
||||
for (const number of entries) {
|
||||
votesPerPosition.addControl(number, this.fb.control<number>(map.get(number) || 0));
|
||||
}
|
||||
|
@ -193,13 +222,14 @@ export class ElectionComponent implements OnInit {
|
|||
}
|
||||
this.form.valueChanges.pipe(
|
||||
debounceTime(1000),
|
||||
distinctUntilChanged()
|
||||
distinctUntilChanged(),
|
||||
).subscribe({
|
||||
next: (value: {
|
||||
overallResults: { [name: string]: VotingResult },
|
||||
constituencyResults: { [name: string]: { [name: string]: VotingResult } }
|
||||
}) => {
|
||||
const modifiedValue: FormElectionResult = {...value,
|
||||
const modifiedValue: FormElectionResult = {
|
||||
...value,
|
||||
constituencyResults: {}
|
||||
};
|
||||
for (const name in value.constituencyResults) {
|
||||
|
@ -217,4 +247,17 @@ export class ElectionComponent implements OnInit {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
private buildVotesPerPosition(votingResult: VotingResult) {
|
||||
const map = new Map<string, number>();
|
||||
for (const number in votingResult.votesPerPosition) {
|
||||
map.set(number, votingResult.votesPerPosition[number]);
|
||||
}
|
||||
const entries = [...map.entries()]
|
||||
.sort((a, b) => {
|
||||
return +a[0] - +b[0];
|
||||
})
|
||||
.map(entry => entry[0]);
|
||||
return {map, entries};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ export enum ActionTypes {
|
|||
|
||||
Calculate = '[Elections] Calculate',
|
||||
CalculateFinished = '[Elections] Calculate Finished',
|
||||
|
||||
ResetElectionResult = '[Elections] Reset Election Result',
|
||||
}
|
||||
|
||||
export const loadAllElectionsAction = createAction(
|
||||
|
@ -77,3 +79,7 @@ export const calculateFinishedAction = createAction(
|
|||
ActionTypes.CalculateFinished,
|
||||
props<{payload: ElectedCandidates}>()
|
||||
);
|
||||
|
||||
export const resetElectionResult = createAction(
|
||||
ActionTypes.ResetElectionResult
|
||||
);
|
||||
|
|
|
@ -5,7 +5,7 @@ import {
|
|||
loadElectionResultFinishedAction,
|
||||
loadPartiesFinishedAction,
|
||||
loadSingleElectionFinishedAction,
|
||||
modifyElectionResultAction
|
||||
modifyElectionResultAction, resetElectionResult
|
||||
} from "./elections.actions";
|
||||
import {createReducer, on} from "@ngrx/store";
|
||||
import {DEFAULT_RESULT, ElectionResult} from "../model/election-result";
|
||||
|
@ -73,7 +73,17 @@ export const electionsReducer = createReducer(
|
|||
action) => ({
|
||||
...state,
|
||||
electedCandidates: {...action.payload}
|
||||
}))
|
||||
})),
|
||||
on(resetElectionResult, (state, action) => ({
|
||||
...state,
|
||||
modifiedElectionResult: {
|
||||
constituencyResults: mapConstituencyResults(state.originalElectionResult.constituencyResults),
|
||||
electionName: state.originalElectionResult.electionName,
|
||||
overallResults: state.originalElectionResult.overallResults.map(votingResult => {
|
||||
return {...votingResult}
|
||||
})
|
||||
}
|
||||
})),
|
||||
);
|
||||
|
||||
function mapConstituencyResults(results: { [name: string]: VotingResult[] }): { [name: string]: VotingResult[] } {
|
||||
|
|
|
@ -202,14 +202,20 @@
|
|||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1566538032864437775" datatype="html">
|
||||
<source><x id="START_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="<mat-spinner class="spinner" *ngIf="showSpinner">"/><x id="CLOSE_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="</mat-spinner>"/> Calculate
|
||||
</source>
|
||||
<target><x id="START_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="<mat-spinner class="spinner" *ngIf="showSpinner">"/><x id="CLOSE_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="</mat-spinner>"/> Berechne
|
||||
</target>
|
||||
<trans-unit id="button.calculate" datatype="html">
|
||||
<source><x id="START_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="<mat-spinner class="spinner" *ngIf="showSpinner">"/><x id="CLOSE_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="</mat-spinner>"/> Calculate </source>
|
||||
<target><x id="START_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="<mat-spinner class="spinner" *ngIf="showSpinner">"/><x id="CLOSE_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="</mat-spinner>"/> Berechne </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">6,8</context>
|
||||
<context context-type="linenumber">7,9</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="button.reset" datatype="html">
|
||||
<source>Reset</source>
|
||||
<target>Zurücksetzen</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2620368114367873419" datatype="html">
|
||||
|
@ -217,7 +223,7 @@
|
|||
<target>Bezirksergebnisse</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">13</context>
|
||||
<context context-type="linenumber">16</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5278344113066375587" datatype="html">
|
||||
|
@ -225,7 +231,7 @@
|
|||
<target>Listenstimmen</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">20</context>
|
||||
<context context-type="linenumber">23</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="652158218369589359" datatype="html">
|
||||
|
@ -233,7 +239,7 @@
|
|||
<target>Stimmen durch Heilungsregel</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">25</context>
|
||||
<context context-type="linenumber">28</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4355395580941190554" datatype="html">
|
||||
|
@ -241,7 +247,7 @@
|
|||
<target>Wahlkreisergebnisse</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">39</context>
|
||||
<context context-type="linenumber">42</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8889535199141263248" datatype="html">
|
||||
|
|
|
@ -180,40 +180,46 @@
|
|||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1566538032864437775" datatype="html">
|
||||
<source><x id="START_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="<mat-spinner class="spinner" *ngIf="showSpinner">"/><x id="CLOSE_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="</mat-spinner>"/> Calculate
|
||||
</source>
|
||||
<trans-unit id="button.calculate" datatype="html">
|
||||
<source><x id="START_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="<mat-spinner class="spinner" *ngIf="showSpinner">"/><x id="CLOSE_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="</mat-spinner>"/> Calculate </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">6,8</context>
|
||||
<context context-type="linenumber">7,9</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="button.reset" datatype="html">
|
||||
<source>Reset</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2620368114367873419" datatype="html">
|
||||
<source>Overall results</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">13</context>
|
||||
<context context-type="linenumber">16</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5278344113066375587" datatype="html">
|
||||
<source>Votes on nomination</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">20</context>
|
||||
<context context-type="linenumber">23</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="652158218369589359" datatype="html">
|
||||
<source>Votes through healing</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">25</context>
|
||||
<context context-type="linenumber">28</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4355395580941190554" datatype="html">
|
||||
<source>Constituency results</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">39</context>
|
||||
<context context-type="linenumber">42</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8889535199141263248" datatype="html">
|
||||
|
|
|
@ -180,40 +180,46 @@
|
|||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1566538032864437775" datatype="html">
|
||||
<source><x id="START_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="<mat-spinner class="spinner" *ngIf="showSpinner">"/><x id="CLOSE_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="</mat-spinner>"/> Calculate
|
||||
</source>
|
||||
<trans-unit id="button.calculate" datatype="html">
|
||||
<source><x id="START_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="<mat-spinner class="spinner" *ngIf="showSpinner">"/><x id="CLOSE_TAG_MAT_SPINNER" ctype="x-mat_spinner" equiv-text="</mat-spinner>"/> Calculate </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">6,8</context>
|
||||
<context context-type="linenumber">7,9</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="button.reset" datatype="html">
|
||||
<source>Reset</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2620368114367873419" datatype="html">
|
||||
<source>Overall results</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">13</context>
|
||||
<context context-type="linenumber">16</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5278344113066375587" datatype="html">
|
||||
<source>Votes on nomination</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">20</context>
|
||||
<context context-type="linenumber">23</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="652158218369589359" datatype="html">
|
||||
<source>Votes through healing</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">25</context>
|
||||
<context context-type="linenumber">28</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4355395580941190554" datatype="html">
|
||||
<source>Constituency results</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/elections/election/election.component.html</context>
|
||||
<context context-type="linenumber">39</context>
|
||||
<context context-type="linenumber">42</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8889535199141263248" datatype="html">
|
||||
|
|
Loading…
Reference in New Issue