Merge pull request #5765 from tsiegleauq/poll-create-layout-enhance
Enhance poll dialog layout
This commit is contained in:
commit
acd33b8207
@ -3,6 +3,7 @@
|
|||||||
[matTooltip]="iconTooltip"
|
[matTooltip]="iconTooltip"
|
||||||
[class]="iconAction ? 'pointer' : ''"
|
[class]="iconAction ? 'pointer' : ''"
|
||||||
(click)="iconClick()"
|
(click)="iconClick()"
|
||||||
|
[color]="color"
|
||||||
>{{ icon }}</mat-icon
|
>{{ icon }}</mat-icon
|
||||||
>
|
>
|
||||||
<span class="content-node" [ngClass]="noWrap ? 'single-line' : 'break-lines'">
|
<span class="content-node" [ngClass]="noWrap ? 'single-line' : 'break-lines'">
|
||||||
@ -13,5 +14,6 @@
|
|||||||
[matTooltip]="iconTooltip"
|
[matTooltip]="iconTooltip"
|
||||||
[class]="iconAction ? 'pointer' : ''"
|
[class]="iconAction ? 'pointer' : ''"
|
||||||
(click)="iconClick()"
|
(click)="iconClick()"
|
||||||
|
[color]="color"
|
||||||
>{{ icon }}</mat-icon
|
>{{ icon }}</mat-icon
|
||||||
>
|
>
|
||||||
|
@ -51,6 +51,9 @@ export class IconContainerComponent {
|
|||||||
@Input()
|
@Input()
|
||||||
public noWrap = false;
|
public noWrap = false;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
public color: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional action for clicking on the icon.
|
* Optional action for clicking on the icon.
|
||||||
*/
|
*/
|
||||||
|
@ -1,24 +1,3 @@
|
|||||||
.submit-buttons {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.meta-text {
|
|
||||||
font-style: italic;
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-right: 10px;
|
|
||||||
mat-chip {
|
|
||||||
margin-left: 5px;
|
|
||||||
margin-right: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.candidate-name {
|
|
||||||
word-wrap: break-word;
|
|
||||||
width: 100%;
|
|
||||||
border-bottom: 1px solid grey;
|
|
||||||
}
|
|
||||||
|
|
||||||
.votes-grid {
|
.votes-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-gap: 5px;
|
grid-gap: 5px;
|
||||||
@ -29,12 +8,3 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sum-value {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.width-600 {
|
|
||||||
max-width: 600px;
|
|
||||||
}
|
|
||||||
|
@ -9,13 +9,22 @@
|
|||||||
</mat-card-title>
|
</mat-card-title>
|
||||||
|
|
||||||
<!-- Type and State -->
|
<!-- Type and State -->
|
||||||
<div class="italic spacer-bottom-20">
|
<div class="type-and-state italic spacer-bottom-20">
|
||||||
<span *osPerms="'assignments.can_manage'; and: poll.type === 'pseudoanonymous'">
|
<span *osPerms="'assignments.can_manage'; and: poll.isEVoting">
|
||||||
<button mat-icon-button color="warn" (click)="openVotingWarning()">
|
<os-icon-container
|
||||||
<mat-icon> warning </mat-icon>
|
class="poll-type"
|
||||||
</button>
|
icon="info"
|
||||||
|
size="large"
|
||||||
|
color="primary"
|
||||||
|
[swap]="true"
|
||||||
|
[showIcon]="poll.isAnon"
|
||||||
|
(iconAction)="openVotingWarning()"
|
||||||
|
>
|
||||||
|
{{ poll.typeVerbose | translate }}
|
||||||
|
</os-icon-container>
|
||||||
|
<span *ngIf="poll.isAnon"> </span>
|
||||||
|
·
|
||||||
</span>
|
</span>
|
||||||
<span *ngIf="poll.type !== 'analog'"> {{ poll.typeVerbose | translate }} · </span>
|
|
||||||
<span>
|
<span>
|
||||||
{{ poll.stateVerbose | translate }}
|
{{ poll.stateVerbose | translate }}
|
||||||
</span>
|
</span>
|
||||||
|
@ -19,4 +19,14 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
margin: auto 0;
|
margin: auto 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.type-and-state {
|
||||||
|
display: flex;
|
||||||
|
span {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.poll-type {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,21 +21,28 @@
|
|||||||
|
|
||||||
<!-- Subtitle -->
|
<!-- Subtitle -->
|
||||||
<div class="italic spacer-bottom-20">
|
<div class="italic spacer-bottom-20">
|
||||||
<span *osPerms="'motions.can_manage_polls'; and: poll.type === 'pseudoanonymous'">
|
<!-- Type and State -->
|
||||||
<button mat-icon-button color="warn" (click)="openVotingWarning()">
|
<div class="type-and-state italic spacer-bottom-20">
|
||||||
<mat-icon>warning</mat-icon>
|
<span *osPerms="permission.motionsCanManagePolls; and: poll.isEVoting">
|
||||||
</button>
|
<os-icon-container
|
||||||
</span>
|
class="poll-type"
|
||||||
|
icon="info"
|
||||||
|
color="primary"
|
||||||
|
[swap]="true"
|
||||||
|
[showIcon]="poll.isAnon"
|
||||||
|
(iconAction)="openVotingWarning()"
|
||||||
|
>
|
||||||
|
{{ poll.typeVerbose | translate }}
|
||||||
|
</os-icon-container>
|
||||||
|
<span *ngIf="poll.isAnon"> </span>
|
||||||
|
·
|
||||||
|
</span>
|
||||||
|
|
||||||
<!-- Subtitle -->
|
<!-- State -->
|
||||||
<span *ngIf="pollService.isElectronicVotingEnabled && poll.type !== 'analog'">
|
<span>
|
||||||
{{ poll.typeVerbose | translate }} ·
|
{{ poll.stateVerbose | translate }}
|
||||||
</span>
|
</span>
|
||||||
|
</div>
|
||||||
<!-- State chip -->
|
|
||||||
<span>
|
|
||||||
{{ poll.stateVerbose | translate }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Change state button -->
|
<!-- Change state button -->
|
||||||
|
@ -28,6 +28,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.type-and-state {
|
||||||
|
display: flex;
|
||||||
|
span {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.poll-type {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.poll-chart-wrapper {
|
.poll-chart-wrapper {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
@ -10,21 +10,26 @@
|
|||||||
|
|
||||||
<form [formGroup]="contentForm" class="poll-preview-meta-info-form">
|
<form [formGroup]="contentForm" class="poll-preview-meta-info-form">
|
||||||
<ng-container *ngIf="!data || !data.state || data.isCreated">
|
<ng-container *ngIf="!data || !data.state || data.isCreated">
|
||||||
<!-- Poll Type -->
|
<div class="info-grid">
|
||||||
<mat-form-field class="pollType" *ngIf="isEVotingEnabled">
|
<!-- Poll Type -->
|
||||||
<mat-select [placeholder]="PollPropertyVerbose.type | translate" formControlName="type" required>
|
<mat-form-field *ngIf="isEVotingEnabled">
|
||||||
<mat-option *ngFor="let option of pollTypes | keyvalue" [value]="option.key">
|
<mat-select [placeholder]="PollPropertyVerbose.type | translate" formControlName="type" required>
|
||||||
{{ option.value | translate }}
|
<mat-option *ngFor="let option of pollTypes | keyvalue" [value]="option.key">
|
||||||
</mat-option>
|
{{ option.value | translate }}
|
||||||
</mat-select>
|
</mat-option>
|
||||||
<mat-error>{{ 'This field is required.' | translate }}</mat-error>
|
</mat-select>
|
||||||
<mat-hint (click)="openVotingWarning()" *ngIf="showNonNominalWarning">
|
<mat-icon
|
||||||
{{ 'Not suitable for formal secret voting!' | translate }}</mat-hint
|
color="primary"
|
||||||
>
|
matSuffix
|
||||||
</mat-form-field>
|
*ngIf="showNonNominalWarning"
|
||||||
|
(click)="openVotingWarning($event)"
|
||||||
|
>
|
||||||
|
info
|
||||||
|
</mat-icon>
|
||||||
|
<mat-error>{{ 'This field is required.' | translate }}</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
<!-- Groups entitled to Vote -->
|
<!-- Groups entitled to Vote -->
|
||||||
<div class="suboption">
|
|
||||||
<mat-form-field *ngIf="contentForm.get('type').value && contentForm.get('type').value !== 'analog'">
|
<mat-form-field *ngIf="contentForm.get('type').value && contentForm.get('type').value !== 'analog'">
|
||||||
<os-search-value-selector
|
<os-search-value-selector
|
||||||
formControlName="groups_id"
|
formControlName="groups_id"
|
||||||
@ -37,34 +42,36 @@
|
|||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Poll Methods -->
|
<div class="info-grid">
|
||||||
<mat-form-field *ngIf="pollMethods">
|
<!-- Poll Methods -->
|
||||||
<mat-select
|
<mat-form-field *ngIf="pollMethods">
|
||||||
[placeholder]="PollPropertyVerbose.pollmethod | translate"
|
<mat-select
|
||||||
formControlName="pollmethod"
|
[placeholder]="PollPropertyVerbose.pollmethod | translate"
|
||||||
required
|
formControlName="pollmethod"
|
||||||
>
|
required
|
||||||
<mat-option *ngFor="let option of pollMethods | keyvalue: keepEntryOrder" [value]="option.key">
|
>
|
||||||
{{ option.value | translate }}
|
<mat-option *ngFor="let option of pollMethods | keyvalue: keepEntryOrder" [value]="option.key">
|
||||||
</mat-option>
|
{{ option.value | translate }}
|
||||||
</mat-select>
|
</mat-option>
|
||||||
<mat-error>{{ 'This field is required.' | translate }}</mat-error>
|
</mat-select>
|
||||||
</mat-form-field>
|
<mat-error>{{ 'This field is required.' | translate }}</mat-error>
|
||||||
</ng-container>
|
</mat-form-field>
|
||||||
|
|
||||||
<!-- Amount of Votes and global options -->
|
<!-- Amount of Votes -->
|
||||||
<div class="suboption" *ngIf="showAmountAndGlobal(data)">
|
<mat-form-field *ngIf="showAmountAndGlobal(data)">
|
||||||
<mat-form-field>
|
<input
|
||||||
<input
|
type="number"
|
||||||
type="number"
|
matInput
|
||||||
matInput
|
placeholder="{{ PollPropertyVerbose.votes_amount | translate }}"
|
||||||
placeholder="{{ PollPropertyVerbose.votes_amount | translate }}"
|
formControlName="votes_amount"
|
||||||
formControlName="votes_amount"
|
min="1"
|
||||||
min="1"
|
required
|
||||||
required
|
/>
|
||||||
/>
|
</mat-form-field>
|
||||||
</mat-form-field>
|
</div>
|
||||||
<div class="global-options">
|
|
||||||
|
<!-- Amount of Votes and global options -->
|
||||||
|
<div class="global-options" *ngIf="showAmountAndGlobal(data)">
|
||||||
<mat-checkbox formControlName="global_yes">
|
<mat-checkbox formControlName="global_yes">
|
||||||
{{ PollPropertyVerbose.global_yes | translate }}
|
{{ PollPropertyVerbose.global_yes | translate }}
|
||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
@ -73,7 +80,7 @@
|
|||||||
{{ PollPropertyVerbose.global_abstain | translate }}
|
{{ PollPropertyVerbose.global_abstain | translate }}
|
||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</ng-container>
|
||||||
|
|
||||||
<!-- 100 Percent Base -->
|
<!-- 100 Percent Base -->
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
|
@ -2,16 +2,11 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pollType {
|
|
||||||
.mat-hint {
|
|
||||||
color: red;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.poll-preview-meta-info-form {
|
.poll-preview-meta-info-form {
|
||||||
.suboption {
|
.info-grid {
|
||||||
margin-left: 1.5em;
|
display: grid;
|
||||||
|
column-gap: 1em;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-checkbox {
|
.mat-checkbox {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
@ -29,7 +29,8 @@ import { PollService } from '../../services/poll.service';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'os-poll-form',
|
selector: 'os-poll-form',
|
||||||
templateUrl: './poll-form.component.html',
|
templateUrl: './poll-form.component.html',
|
||||||
styleUrls: ['./poll-form.component.scss']
|
styleUrls: ['./poll-form.component.scss'],
|
||||||
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
export class PollFormComponent<T extends ViewBasePoll, S extends PollService>
|
export class PollFormComponent<T extends ViewBasePoll, S extends PollService>
|
||||||
extends BaseViewComponentDirective
|
extends BaseViewComponentDirective
|
||||||
@ -160,14 +161,16 @@ export class PollFormComponent<T extends ViewBasePoll, S extends PollService>
|
|||||||
this.contentForm.get('pollmethod').valueChanges.subscribe(method => {
|
this.contentForm.get('pollmethod').valueChanges.subscribe(method => {
|
||||||
if (method) {
|
if (method) {
|
||||||
this.updatePercentBases(method);
|
this.updatePercentBases(method);
|
||||||
this.setVotesAmountCtrl();
|
this.setWarning();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
// poll type changes
|
// poll type changes
|
||||||
this.contentForm.get('type').valueChanges.subscribe(() => {
|
this.contentForm.get('type').valueChanges.subscribe(() => {
|
||||||
this.setVotesAmountCtrl();
|
this.setWarning();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.setWarning();
|
||||||
}
|
}
|
||||||
|
|
||||||
private disablePollType(): void {
|
private disablePollType(): void {
|
||||||
@ -232,7 +235,7 @@ export class PollFormComponent<T extends ViewBasePoll, S extends PollService>
|
|||||||
* Disable votes_amount form control if the poll type is anonymous
|
* Disable votes_amount form control if the poll type is anonymous
|
||||||
* and the poll method is votes.
|
* and the poll method is votes.
|
||||||
*/
|
*/
|
||||||
private setVotesAmountCtrl(): void {
|
private setWarning(): void {
|
||||||
if (this.contentForm.get('type').value === PollType.Pseudoanonymous) {
|
if (this.contentForm.get('type').value === PollType.Pseudoanonymous) {
|
||||||
this.showNonNominalWarning = true;
|
this.showNonNominalWarning = true;
|
||||||
} else {
|
} else {
|
||||||
@ -297,7 +300,8 @@ export class PollFormComponent<T extends ViewBasePoll, S extends PollService>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public openVotingWarning(): void {
|
public openVotingWarning(event: MouseEvent): void {
|
||||||
|
event.stopPropagation();
|
||||||
this.dialog.open(VotingPrivacyWarningComponent, infoDialogSettings);
|
this.dialog.open(VotingPrivacyWarningComponent, infoDialogSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user