Skip to content
Draft
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Directive, inject, signal, viewChild } from '@angular/core';
import { rxResource } from '@angular/core/rxjs-interop';
import { computed, Directive, inject, signal, viewChild } from '@angular/core';
import { UntypedFormBuilder } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Fqid, Id } from '@app/domain/definitions/key-types';
Expand All @@ -8,7 +7,6 @@ import { PollVisibility } from '@app/domain/models/poll';
import { PollUpdatePayload } from '@app/gateways/vote-api.service';
import { ViewPoll } from '@app/site/pages/meetings/pages/polls';
import { BaseUiComponent } from '@app/ui/base/base-ui-component';
import { map } from 'rxjs';

import { PollEditResultComponent } from '../components/poll-edit-result/poll-edit-result.component';
import { PollFormComponent } from '../components/poll-form/poll-form.component';
Expand Down Expand Up @@ -42,21 +40,17 @@ export abstract class BasePollDialogComponent extends BaseUiComponent {
protected pollForm = viewChild.required(PollFormComponent);
protected pollResultForm = viewChild(PollEditResultComponent);

public get formsValid(): boolean {
public formsValid = computed<boolean>(() => {
if (!this.pollForm) {
return false;
}

return this.pollForm().pollForm.valid;
}
return this.pollForm().isValid();
});

public analogPollFormOpen = signal(false);
public isAnalogPoll = rxResource({
params: () => this.pollForm(),
defaultValue: false,
stream({ params }) {
return params.pollForm.get(`visibility`).valueChanges.pipe(map(v => v === PollVisibility.Manually));
}
public isAnalogPoll = computed(() => {
return this.pollForm().form.visibility().value() === PollVisibility.Manually;
});

protected formBuilder = inject(UntypedFormBuilder);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Component, computed, effect, inject, input } from '@angular/core';
import { Component, computed, effect, inject, input, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { PollState } from '@app/domain/models/poll';

Expand All @@ -10,16 +11,19 @@ export abstract class PollFormBaseComponent {

public data = input.required<Partial<ViewPoll>>();

public formValid = signal<boolean>(false);

public pollStarted = computed<boolean>(() => {
return this.data().state && this.data().state !== PollState.Created;
});

protected fb = inject(UntypedFormBuilder);
protected readonly fb = inject(UntypedFormBuilder);

public constructor() {
this.initForm();

effect(this.onDataUpdated.bind(this));
this.form.valueChanges.pipe(takeUntilDestroyed()).subscribe(() => this.formValid.set(this.form.valid));
}

protected abstract initForm(): void;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<form [formGroup]="form">
@if (!pollStarted()) {
@if (!pollStarted() && !hideMethod()) {
<div class="margin-bottom-15 info-grid">
<mat-form-field>
<mat-label>{{ 'Election method' | translate }}</mat-label>
Expand All @@ -8,19 +8,23 @@
<mat-option [value]="true">{{ 'Yes/No/Abstain' | translate }}</mat-option>
</mat-select>
</mat-form-field>
<div></div>
</div>
}

<mat-form-field>
<mat-label>{{ '100% base' | translate }}</mat-label>
<mat-select formControlName="onehundred_percent_base" panelClass="percent-base-panel" required>
@for (option of validPercentBases; track option[0]) {
@if (option[0] !== 'yes_no_abstain' || form.get('allow_abstain').getRawValue()) {
<mat-option [value]="option[0]">
{{ option[1] | translate }}
</mat-option>
<div class="info-grid">
<mat-form-field>
<mat-label>{{ '100% base' | translate }}</mat-label>
<mat-select formControlName="onehundred_percent_base" panelClass="percent-base-panel" required>
@for (option of validPercentBases; track option[0]) {
@if (option[0] !== 'yes_no_abstain' || form.get('allow_abstain').getRawValue()) {
<mat-option [value]="option[0]">
{{ option[1] | translate }}
</mat-option>
}
}
}
</mat-select>
</mat-form-field>
</mat-select>
</mat-form-field>
<div></div>
</div>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.info-grid {
display: grid;
column-gap: 1em;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));

> mat-checkbox {
padding-top: 10px;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatFormFieldModule } from '@angular/material/form-field';
Expand All @@ -9,6 +9,11 @@ import { _, TranslatePipe } from '@ngx-translate/core';
import { ViewPoll } from '../../../../pages/polls';
import { PollFormBaseComponent } from '../poll-config-form-base.component';

export interface PollFormApproval {
allow_abstain: boolean;
onehundred_percent_base: ApprovalOnehundredPercentBase;
}

@Component({
selector: 'os-poll-form-approval',
imports: [ReactiveFormsModule, MatFormFieldModule, MatSelectModule, MatCheckboxModule, TranslatePipe],
Expand All @@ -17,6 +22,8 @@ import { PollFormBaseComponent } from '../poll-config-form-base.component';
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PollFormApprovalComponent extends PollFormBaseComponent {
public hideMethod = input<boolean>(false);

public validPercentBases: [ApprovalOnehundredPercentBase, string][] = [
[`yes_no`, _('Yes/No')],
[`yes_no_abstain`, _('Yes/No/Abstain')],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
<form [formGroup]="form">
<div class="poll-preview-meta-info-form">
@if (!pollStarted()) {
<mat-form-field>
<mat-label>{{ 'Election method' | translate }}</mat-label>
<mat-select formControlName="allow_abstain">
<mat-option [value]="false">{{ 'Yes/No' | translate }}</mat-option>
<mat-option [value]="true">{{ 'Yes/No/Abstain' | translate }}</mat-option>
</mat-select>
</mat-form-field>
<div class="margin-bottom-15 info-grid">
@if (!hideMethod()) {
<mat-form-field>
<mat-label>{{ 'Election method' | translate }}</mat-label>
<mat-select formControlName="allow_abstain">
<mat-option [value]="false">{{ 'Yes/No' | translate }}</mat-option>
<mat-option [value]="true">{{ 'Yes/No/Abstain' | translate }}</mat-option>
</mat-select>
</mat-form-field>
}
<div class="info-grid">
<mat-form-field>
<mat-label>{{ 'Min amount of votes' | translate }}</mat-label>
<input formControlName="min_options_amount" matInput required type="number" />
Expand All @@ -18,25 +20,31 @@
<mat-label>{{ 'Max amount of votes' | translate }}</mat-label>
<input formControlName="max_options_amount" matInput required type="number" />
</mat-form-field>
</div>

<div class="margin-bottom-15 info-grid">
<div></div>
<mat-form-field>
<mat-label>{{ 'Max amount of yes votes' | translate }}</mat-label>
<input formControlName="max_yes_amount" matInput required type="number" />
</mat-form-field>
</div>
}

<mat-form-field>
<mat-label>{{ '100% base' | translate }}</mat-label>
<mat-select formControlName="onehundred_percent_base" panelClass="percent-base-panel" required>
@for (option of validPercentBases; track option) {
@if (option[0] !== 'yes_no_abstain' || form.get('allow_abstain').getRawValue()) {
<mat-option [value]="option[0]">
{{ option[1] | translate }}
</mat-option>
<div class="info-grid">
<mat-form-field>
<mat-label>{{ '100% base' | translate }}</mat-label>
<mat-select formControlName="onehundred_percent_base" panelClass="percent-base-panel" required>
@for (option of validPercentBases; track option) {
@if (option[0] !== 'yes_no_abstain' || form.get('allow_abstain').getRawValue()) {
<mat-option [value]="option[0]">
{{ option[1] | translate }}
</mat-option>
}
}
}
</mat-select>
</mat-form-field>
</mat-select>
</mat-form-field>
<div></div>
</div>
</div>
</form>
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,20 @@ import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { RatingApprovalOnehundredPercentBase } from '@app/domain/models/poll/poll-config-rating-approval';
import { RatingScoreOnehundredPercentBase } from '@app/domain/models/poll/poll-config-rating-score';
import { _, TranslatePipe } from '@ngx-translate/core';

import { ViewPoll } from '../../../../pages/polls';
import { PollFormBaseComponent } from '../poll-config-form-base.component';

export interface PollFormRatingApproval {
max_options_amount: number;
min_options_amount: number;
max_yes_amount: number;
onehundred_percent_base: RatingScoreOnehundredPercentBase;
display_chart: string;
}

@Component({
selector: 'os-poll-form-rating-approval',
imports: [
Expand All @@ -35,6 +44,7 @@ export class PollFormRatingApprovalComponent extends PollFormBaseComponent {
[`disabled`, _('Disabled (no percents)')]
];

public hideMethod = input<boolean>(false);
public optionAmount = input<number>(null);

protected initForm(): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
<form [formGroup]="form">
<div class="poll-preview-meta-info-form">
@if (!pollStarted()) {
<div class="margin-bottom-15">
<mat-checkbox formControlName="allow_general_abstain">
{{ 'General abstain' | translate }}
</mat-checkbox>
</div>

<div class="margin-bottom-15 info-grid">
<div class="info-grid">
@if (!form.get('allow_general_abstain').value) {
<mat-form-field>
<mat-label>{{ 'Min amount of votes' | translate }}</mat-label>
Expand All @@ -23,7 +17,7 @@
</mat-form-field>
</div>

<div class="margin-bottom-15 info-grid">
<div class="info-grid">
@if (!form.get('allow_general_abstain').value) {
<mat-form-field>
<mat-label>{{ 'Min amount of options voted' | translate }}</mat-label>
Expand All @@ -40,22 +34,32 @@
</div>

<div class="margin-bottom-15 info-grid">
<div></div>
<mat-form-field>
<mat-label>{{ 'Max votes per option' | translate }}</mat-label>
<input formControlName="max_votes_per_option" matInput type="number" />
</mat-form-field>
</div>

<div class="margin-bottom-15">
<mat-checkbox formControlName="allow_general_abstain">
{{ 'General abstain' | translate }}
</mat-checkbox>
</div>
}

<mat-form-field>
<mat-label>{{ '100% base' | translate }}</mat-label>
<mat-select formControlName="onehundred_percent_base" panelClass="percent-base-panel" required>
@for (option of validPercentBases; track option) {
<mat-option [value]="option[0]">
{{ option[1] | translate }}
</mat-option>
}
</mat-select>
</mat-form-field>
<div class="margin-bottom-15 info-grid">
<mat-form-field>
<mat-label>{{ '100% base' | translate }}</mat-label>
<mat-select formControlName="onehundred_percent_base" panelClass="percent-base-panel" required>
@for (option of validPercentBases; track option) {
<mat-option [value]="option[0]">
{{ option[1] | translate }}
</mat-option>
}
</mat-select>
</mat-form-field>
<div></div>
</div>
</div>
</form>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ import { _, TranslatePipe } from '@ngx-translate/core';
import { ViewPoll } from '../../../../pages/polls';
import { PollFormBaseComponent } from '../poll-config-form-base.component';

export interface PollFormRatingScore {
max_options_amount: number;
min_options_amount: number;
max_votes_per_option: number;
max_vote_sum: number;
min_vote_sum: number;
onehundred_percent_base: RatingScoreOnehundredPercentBase;
}

@Component({
selector: 'os-poll-form-rating-score',
imports: [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<form [formGroup]="form">
@if (!pollStarted()) {
@if (!pollStarted() && !hideMethod()) {
<div class="margin-bottom-15">
<mat-form-field>
<mat-label>{{ 'Election method' | translate }}</mat-label>
Expand All @@ -13,20 +13,6 @@

<div class="poll-preview-meta-info-form">
@if (!pollStarted()) {
<div class="margin-bottom-15">
<mat-checkbox formControlName="allow_general_abstain">
{{ 'General abstain' | translate }}
</mat-checkbox>

<mat-checkbox formControlName="allow_nota">
@if (form.get('strike_out').value) {
{{ 'General approval' | translate }}
} @else {
{{ 'General rejection' | translate }}
}
</mat-checkbox>
</div>

<div class="info-grid">
@if (!form.get('allow_general_abstain').value) {
<mat-form-field>
Expand All @@ -42,6 +28,20 @@
<input formControlName="max_options_amount" matInput required type="number" />
</mat-form-field>
</div>

<div class="margin-bottom-15">
<mat-checkbox formControlName="allow_general_abstain">
{{ 'General abstain' | translate }}
</mat-checkbox>

<mat-checkbox formControlName="allow_nota">
@if (form.get('strike_out').value) {
{{ 'General approval' | translate }}
} @else {
{{ 'General rejection' | translate }}
}
</mat-checkbox>
</div>
}

<div class="margin-bottom-15 info-grid">
Expand Down
Loading
Loading