Merge pull request #4527 from tsiegleauq/list-of-speakers-template
Add prettier list of speakers
This commit is contained in:
commit
faa0a6077e
@ -1,17 +1,17 @@
|
||||
<div cdkDropList class="os-card" [cdkDropListDisabled]="!enable" (cdkDropListDropped)="drop($event)">
|
||||
<div class="box line" *ngIf="!array.length">
|
||||
<div cdkDropList [cdkDropListDisabled]="!enable" (cdkDropListDropped)="drop($event)">
|
||||
<div class="line" *ngIf="!array.length">
|
||||
<span translate>No data</span>
|
||||
</div>
|
||||
<div class="box line" *ngFor="let item of array; let i = index" cdkDrag>
|
||||
<div class="section-one" cdkDragHandle *ngIf="enable">
|
||||
<div class="line" *ngFor="let item of array; let i = index" cdkDrag>
|
||||
<div class="section-one backgroundColorLight" cdkDragHandle *ngIf="enable">
|
||||
<mat-icon>drag_indicator</mat-icon>
|
||||
</div>
|
||||
<div class="section-two">
|
||||
<div class="section-two backgroundColorLight">
|
||||
<!-- {number}. {item.getTitle()} -->
|
||||
<span *ngIf="count">{{ i + 1 }}. </span>
|
||||
<span>{{ item.getTitle() }}</span>
|
||||
</div>
|
||||
<div class="section-three">
|
||||
<div class="section-three backgroundColorLight">
|
||||
<!-- Extra controls slot using implicit template references -->
|
||||
<ng-template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ $implicit: item }"></ng-template>
|
||||
</div>
|
||||
|
@ -1,19 +1,11 @@
|
||||
@import '~assets/styles/drag.scss';
|
||||
|
||||
.box {
|
||||
width: 100%;
|
||||
border-bottom: solid 1px #ccc;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.box:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.line {
|
||||
display: table;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
min-height: 50px;
|
||||
margin-bottom: 5px;
|
||||
|
||||
.section-one {
|
||||
display: table-cell;
|
||||
@ -28,7 +20,12 @@
|
||||
.section-two {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
width: 80%;
|
||||
width: 100%;
|
||||
padding-left: 20px;
|
||||
|
||||
span + span {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.section-three {
|
||||
|
@ -11,85 +11,100 @@
|
||||
</div>
|
||||
</os-head-bar>
|
||||
|
||||
<h1 class="title on-transition-fade" *ngIf="viewItem">{{ viewItem.getTitle() }}</h1>
|
||||
<mat-card class="os-card speaker-card" *ngIf="viewItem">
|
||||
<!-- Title -->
|
||||
<h1 class="title on-transition-fade" *ngIf="viewItem">{{ viewItem.getTitle() }}</h1>
|
||||
|
||||
<mat-card class="speaker-card" *ngIf="viewItem">
|
||||
<!-- List of finished speakers -->
|
||||
<mat-expansion-panel *ngIf="finishedSpeakers && finishedSpeakers.length > 0" class="finished-list">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title translate> Last speakers </mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<mat-list>
|
||||
<!-- {Number}. {full_name} {time} minutes (Start time: {begin_time}) [close button] -->
|
||||
<mat-list-item *ngFor="let speaker of finishedSpeakers; let number = index">
|
||||
<div class="finished-prefix">
|
||||
<span>{{ number + 1 }}. {{ speaker }}</span>
|
||||
<div class="finished-speaker-grid">
|
||||
<div class="number">{{ number + 1 }}.</div>
|
||||
<div class="name">{{ speaker }}</div>
|
||||
<div class="time">
|
||||
{{ durationString(speaker) }} ({{ 'Start time' | translate }}: {{ startTimeToString(speaker) }})
|
||||
</div>
|
||||
<div class="controls">
|
||||
<button
|
||||
mat-icon-button
|
||||
matTooltip="{{ 'Remove' | translate }}"
|
||||
*osPerms="'agenda.can_manage_list_of_speakers'"
|
||||
(click)="onDeleteButton(speaker)"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="finished-suffix">
|
||||
{{ durationString(speaker) }} ({{ 'Start time' | translate }}:
|
||||
{{ startTimeToString(speaker) }})
|
||||
</div>
|
||||
<button
|
||||
mat-stroked-button
|
||||
matTooltip="{{ 'Remove' | translate }}"
|
||||
*osPerms="'agenda.can_manage_list_of_speakers'"
|
||||
(click)="onDeleteButton(speaker)"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<!-- horizontal separation line -->
|
||||
<mat-divider *ngIf="finishedSpeakers && finishedSpeakers.length"></mat-divider>
|
||||
<div *ngIf="finishedSpeakers && finishedSpeakers.length" class="spacer-bottom-40"></div>
|
||||
|
||||
<!-- Current Speaker -->
|
||||
<div class="current-speaker" *ngIf="activeSpeaker">
|
||||
<mat-icon class="speaking-icon">play_arrow</mat-icon>
|
||||
<span class="speaking-name">{{ activeSpeaker }}</span>
|
||||
<span class="prefix">
|
||||
<mat-icon>mic</mat-icon>
|
||||
</span>
|
||||
|
||||
<button
|
||||
mat-stroked-button
|
||||
matTooltip="{{ 'End speech' | translate }}"
|
||||
*osPerms="'agenda.can_manage_list_of_speakers'"
|
||||
(click)="onStopButton()"
|
||||
>
|
||||
<mat-icon>mic_off</mat-icon>
|
||||
<span translate>Stop</span>
|
||||
</button>
|
||||
<span class="name">{{ activeSpeaker }}</span>
|
||||
|
||||
<span class="suffix">
|
||||
<!-- Stop speaker button -->
|
||||
<button
|
||||
mat-icon-button
|
||||
matTooltip="{{ 'End speech' | translate }}"
|
||||
*osPerms="'agenda.can_manage_list_of_speakers'"
|
||||
(click)="onStopButton()"
|
||||
>
|
||||
<mat-icon>stop</mat-icon>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Waiting speakers -->
|
||||
<div>
|
||||
<div class="waiting-list" *ngIf="speakers && speakers.length > 0">
|
||||
<os-sorting-list
|
||||
[input]="speakers"
|
||||
[live]="true"
|
||||
[count]="true"
|
||||
[enable]="opCanManage()"
|
||||
(sortEvent)="onSortingChange($event)"
|
||||
>
|
||||
<!-- implicit item references into the component using ng-template slot -->
|
||||
<ng-template let-item>
|
||||
<span *osPerms="'agenda.can_manage_list_of_speakers'">
|
||||
<span *ngIf="hasSpokenCount(item)" class="red-warning-text speaker-warning">
|
||||
{{ hasSpokenCount(item) + 1 }}. <span translate>contribution</span>
|
||||
</span>
|
||||
<span *ngIf="item.gender">({{ item.gender | translate }})</span>
|
||||
<div class="waiting-list" *ngIf="speakers && speakers.length > 0">
|
||||
<os-sorting-list
|
||||
[input]="speakers"
|
||||
[live]="true"
|
||||
[count]="true"
|
||||
[enable]="opCanManage()"
|
||||
(sortEvent)="onSortingChange($event)"
|
||||
>
|
||||
<!-- implicit item references into the component using ng-template slot -->
|
||||
<ng-template let-item>
|
||||
<span *osPerms="'agenda.can_manage_list_of_speakers'">
|
||||
<span *ngIf="hasSpokenCount(item)" class="red-warning-text speaker-warning">
|
||||
{{ hasSpokenCount(item) + 1 }}. <span translate>contribution</span>
|
||||
</span>
|
||||
<mat-button-toggle-group *osPerms="'agenda.can_manage_list_of_speakers'">
|
||||
<mat-button-toggle matTooltip="{{ 'Begin speech' | translate }}" (click)="onStartButton(item)">
|
||||
<mat-icon>mic</mat-icon>
|
||||
<span translate>Start</span>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle matTooltip="{{ 'Mark speaker' | translate }}" (click)="onMarkButton(item)">
|
||||
<mat-icon>{{ item.marked ? 'star' : 'star_border' }}</mat-icon>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle matTooltip="{{ 'Remove' | translate }}" (click)="onDeleteButton(item)">
|
||||
<mat-icon>close</mat-icon>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</ng-template>
|
||||
</os-sorting-list>
|
||||
</div>
|
||||
<span *ngIf="item.gender">({{ item.gender | translate }})</span>
|
||||
</span>
|
||||
|
||||
<!-- Start, start and delete buttons -->
|
||||
<span *osPerms="'agenda.can_manage_list_of_speakers'">
|
||||
<!-- start button -->
|
||||
<button mat-icon-button matTooltip="{{ 'Begin speech' | translate }}" (click)="onStartButton(item)">
|
||||
<mat-icon>play_arrow</mat-icon>
|
||||
</button>
|
||||
|
||||
<!-- star button -->
|
||||
<button mat-icon-button matTooltip="{{ 'Mark speaker' | translate }}" (click)="onMarkButton(item)">
|
||||
<mat-icon>{{ item.marked ? 'star' : 'star_border' }}</mat-icon>
|
||||
</button>
|
||||
|
||||
<!-- delete button -->
|
||||
<button mat-icon-button matTooltip="{{ 'Remove' | translate }}" (click)="onDeleteButton(item)">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</span>
|
||||
</ng-template>
|
||||
</os-sorting-list>
|
||||
</div>
|
||||
|
||||
<!-- Search for speakers -->
|
||||
@ -110,11 +125,11 @@
|
||||
<!-- Add me and remove me if OP has correct permission -->
|
||||
<div *osPerms="'agenda.can_be_speaker'" class="add-self-buttons">
|
||||
<div *ngIf="speakers && !closedList">
|
||||
<button mat-raised-button (click)="addNewSpeaker()" *ngIf="!isOpInList()">
|
||||
<button mat-stroked-button (click)="addNewSpeaker()" *ngIf="!isOpInList()">
|
||||
<mat-icon>add</mat-icon>
|
||||
<span translate>Add me</span>
|
||||
</button>
|
||||
<button mat-raised-button (click)="onDeleteButton()" *ngIf="isOpInList()">
|
||||
<button mat-stroked-button (click)="onDeleteButton()" *ngIf="isOpInList()">
|
||||
<mat-icon>remove</mat-icon>
|
||||
<span translate>Remove me</span>
|
||||
</button>
|
||||
|
@ -1,72 +1,147 @@
|
||||
@import '~@angular/material/theming';
|
||||
|
||||
@mixin os-list-of-speakers-style($theme) {
|
||||
$primary: map-get($theme, primary);
|
||||
$accent: map-get($theme, accent);
|
||||
$warn: map-get($theme, warn);
|
||||
$contrast: map-get($primary, contrast);
|
||||
$foreground: map-get($theme, foreground);
|
||||
|
||||
.current-speaker {
|
||||
background-color: mat-color($accent) !important;
|
||||
|
||||
> span {
|
||||
color: mat-color($accent, default-contrast);
|
||||
}
|
||||
}
|
||||
|
||||
.finished-speaker-grid {
|
||||
> .number .name .controls {
|
||||
color: mat-color($foreground, text);
|
||||
}
|
||||
|
||||
> .time {
|
||||
color: mat-color($foreground, secondary-text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
.speaker-card {
|
||||
margin: 0 20px 0 20px;
|
||||
padding: 0;
|
||||
.finished-list {
|
||||
box-shadow: none !important;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.finished-list {
|
||||
margin-bottom: 15px;
|
||||
.finished-suffix {
|
||||
color: slategray;
|
||||
font-size: 80%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.mat-list-item {
|
||||
height: auto;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.mat-list-item {
|
||||
height: auto;
|
||||
}
|
||||
.finished-speaker-grid {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
grid-template-areas: 'number name time controls';
|
||||
grid-gap: 5px;
|
||||
grid-template-columns: 30px 1fr min-content min-content;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-left: 10px;
|
||||
@media only screen and (max-width: 960px) {
|
||||
.finished-speaker-grid {
|
||||
grid-template-areas:
|
||||
'number name controls'
|
||||
'number time controls';
|
||||
grid-template-columns: 30px 1fr min-content;
|
||||
}
|
||||
}
|
||||
|
||||
.current-speaker {
|
||||
padding: 10px 25px 15px 25px;
|
||||
display: table;
|
||||
.speaking-icon {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.speaking-name {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
font-weight: bold;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
button {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.number {
|
||||
grid-area: number;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.waiting-list {
|
||||
padding: 10px 25px 0 25px;
|
||||
width: 75%;
|
||||
.name {
|
||||
grid-area: name;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
form {
|
||||
padding: 15px 25px 10px 25px;
|
||||
width: auto;
|
||||
.time {
|
||||
grid-area: time;
|
||||
margin: 0;
|
||||
//allows pushing this grid area as small as possible and aligns the end to the same level
|
||||
white-space: nowrap;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
.search-users {
|
||||
display: grid;
|
||||
.mat-form-field {
|
||||
width: 100%;
|
||||
.controls {
|
||||
grid-area: controls;
|
||||
margin: 0;
|
||||
opacity: 0.7;
|
||||
|
||||
.mat-icon-button {
|
||||
height: 20px;
|
||||
line-height: 1;
|
||||
|
||||
.mat-icon {
|
||||
line-height: 19px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.add-self-buttons {
|
||||
padding: 20px 0 20px 25px;
|
||||
.current-speaker {
|
||||
display: table;
|
||||
width: -webkit-fill-available;
|
||||
height: 50px;
|
||||
margin: 50px 25px 20px 25px;
|
||||
box-shadow: 0px 3px 10px 0px rgba(0, 0, 0, 0.25);
|
||||
|
||||
.prefix {
|
||||
display: table-cell;
|
||||
padding: 0 15px;
|
||||
vertical-align: middle;
|
||||
.mat-icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.speaker-warning {
|
||||
margin-right: 5px;
|
||||
.name {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
font-weight: bold;
|
||||
padding-left: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.suffix {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
white-space: nowrap;
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.waiting-list {
|
||||
padding: 10px 25px 0 25px;
|
||||
}
|
||||
|
||||
form {
|
||||
padding: 15px 25px 10px 25px;
|
||||
width: auto;
|
||||
|
||||
.search-users {
|
||||
display: grid;
|
||||
.mat-form-field {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.add-self-buttons {
|
||||
padding: 15px 0 20px 25px;
|
||||
}
|
||||
|
||||
.speaker-warning {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
@ -81,7 +81,7 @@
|
||||
}
|
||||
|
||||
.backgroundColorLight {
|
||||
background-color: mat-color($background, status-bar);
|
||||
background-color: mat-color($background, hover);
|
||||
color: mat-color($foreground, text) !important;
|
||||
}
|
||||
}
|
||||
|
@ -7,10 +7,11 @@
|
||||
@import './assets/styles/openslides-dark-theme.scss';
|
||||
@import './assets/styles/openslides-green-theme.scss';
|
||||
|
||||
/** Import the component-related stylesheets here */
|
||||
/** Import the component-related style sheets here */
|
||||
@import './app/site/site.component.scss-theme.scss';
|
||||
@import './assets/styles/global-components-style.scss';
|
||||
@import './app/shared/components/projector-button/projector-button.component.scss';
|
||||
@import './app/site/agenda/components/list-of-speakers/list-of-speakers.component.scss';
|
||||
|
||||
/** fonts */
|
||||
@import './assets/styles/fonts.scss';
|
||||
@ -21,6 +22,7 @@
|
||||
@include os-site-theme($theme);
|
||||
@include os-components-style($theme);
|
||||
@include os-projector-button-style($theme);
|
||||
@include os-list-of-speakers-style($theme);
|
||||
/** More components are added here */
|
||||
}
|
||||
|
||||
@ -408,6 +410,9 @@ button.mat-menu-item.selected {
|
||||
.spacer-bottom-20 {
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
.spacer-bottom-40 {
|
||||
margin-bottom: 40px !important;
|
||||
}
|
||||
.spacer-left-10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user