store flags for songs
This commit is contained in:
@@ -5,17 +5,13 @@ export const fade = [
|
|||||||
trigger('fade', [
|
trigger('fade', [
|
||||||
|
|
||||||
// the "in" style determines the "resting" state of the element when it is visible.
|
// the "in" style determines the "resting" state of the element when it is visible.
|
||||||
state('in', style({opacity: 1, display: 'block', transform: 'translateY(0px)'})),
|
state('in', style({opacity: 1, transform: 'translateY(0px)'})),
|
||||||
|
|
||||||
// fade in when created. this could also be written as transition('void => *')
|
// fade in when created. this could also be written as transition('void => *')
|
||||||
transition(':enter', [
|
transition(':enter', [
|
||||||
style({opacity: 0, display: 'block', transform: 'translateY(-20px)'}),
|
style({opacity: 0, transform: 'translateY(-10px)'}),
|
||||||
animate(300)
|
animate(200)
|
||||||
]),
|
]),
|
||||||
|
|
||||||
// fade out when destroyed. this could also be written as transition('void => *')
|
|
||||||
transition(':leave',
|
|
||||||
animate(300, style({opacity: 0, display: 'block', transform: 'translateY(-20px)'})))
|
|
||||||
])
|
])
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -29,7 +25,7 @@ export const fader =
|
|||||||
left: 0,
|
left: 0,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
transform: 'scale(0.96) translateY(-10px)',
|
transform: 'scale(1) translateY(-10px)',
|
||||||
}),
|
}),
|
||||||
], {optional: true}),
|
], {optional: true}),
|
||||||
// Animate the new page in
|
// Animate the new page in
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<div *ngIf="shows$|async as shows">
|
<div *ngIf="shows$|async as shows">
|
||||||
<app-card>
|
<app-card>
|
||||||
|
|
||||||
<p *ngIf="!shows.length">Es ist derzeit keine Veranstaltung vorhanden</p>
|
<p *ngIf="!shows.length" @fade>Es ist derzeit keine Veranstaltung vorhanden</p>
|
||||||
|
|
||||||
<mat-form-field *ngIf="shows.length>0" appearance="outline">
|
<mat-form-field *ngIf="shows.length>0" @fade appearance="outline">
|
||||||
<mat-label>Veranstaltung</mat-label>
|
<mat-label>Veranstaltung</mat-label>
|
||||||
<mat-select [formControl]="showControl">
|
<mat-select [formControl]="showControl">
|
||||||
<mat-option *ngFor="let show of shows" [value]="show.id">
|
<mat-option *ngFor="let show of shows" [value]="show.id">
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<div *ngFor="let song of presentationSongs" class="song">
|
<div *ngFor="let song of presentationSongs" @fade class="song">
|
||||||
<div [class.active]="show.presentationSongId===song.id" class="title song-part">
|
<div [class.active]="show.presentationSongId===song.id" class="title song-part">
|
||||||
<div (click)="onSectionClick(song.id, -1)" class="head">{{song.title}}</div>
|
<div (click)="onSectionClick(song.id, -1)" class="head">{{song.title}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {ShowSong} from '../../shows/services/show-song';
|
|||||||
import {GlobalSettingsService} from '../../../services/global-settings.service';
|
import {GlobalSettingsService} from '../../../services/global-settings.service';
|
||||||
import {FormControl} from '@angular/forms';
|
import {FormControl} from '@angular/forms';
|
||||||
import {distinctUntilChanged, map} from 'rxjs/operators';
|
import {distinctUntilChanged, map} from 'rxjs/operators';
|
||||||
|
import {fade} from '../../../animations';
|
||||||
|
|
||||||
export interface PresentationSong {
|
export interface PresentationSong {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -21,7 +22,8 @@ export interface PresentationSong {
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-remote',
|
selector: 'app-remote',
|
||||||
templateUrl: './remote.component.html',
|
templateUrl: './remote.component.html',
|
||||||
styleUrls: ['./remote.component.less']
|
styleUrls: ['./remote.component.less'],
|
||||||
|
animations: [fade]
|
||||||
})
|
})
|
||||||
export class RemoteComponent {
|
export class RemoteComponent {
|
||||||
public shows$: Observable<Show[]>;
|
public shows$: Observable<Show[]>;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export interface Song {
|
|||||||
text: string;
|
text: string;
|
||||||
title: string;
|
title: string;
|
||||||
type: string;
|
type: string;
|
||||||
|
flags: string;
|
||||||
|
|
||||||
legalType: string;
|
legalType: string;
|
||||||
legalLink: string;
|
legalLink: string;
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export class TextRenderingService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public parse(text: string): Section[] {
|
public parse(text: string): Section[] {
|
||||||
|
if (!text) return [];
|
||||||
const arrayOfLines = text.split(/\r?\n/).filter(_ => _);
|
const arrayOfLines = text.split(/\r?\n/).filter(_ => _);
|
||||||
const indices = {
|
const indices = {
|
||||||
[SectionType.Bridge]: 0,
|
[SectionType.Bridge]: 0,
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
<div>
|
||||||
|
<app-list-header></app-list-header>
|
||||||
|
|
||||||
<app-card *ngIf="songs$ | async as songs" [@fade] [padding]="false">
|
<app-card *ngIf="songs$ | async as songs" [@fade] [padding]="false">
|
||||||
<app-list-item *ngFor="let song of songs" [routerLink]="song.id" [song]="song"></app-list-item>
|
<app-list-item *ngFor="let song of songs" [routerLink]="song.id" [song]="song"></app-list-item>
|
||||||
</app-card>
|
</app-card>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {ListItemComponent} from './list-item/list-item.component';
|
|||||||
import {CardModule} from '../../../widget-modules/components/card/card.module';
|
import {CardModule} from '../../../widget-modules/components/card/card.module';
|
||||||
import {RouterModule} from '@angular/router';
|
import {RouterModule} from '@angular/router';
|
||||||
import {LegalTypeTranslatorModule} from '../../../widget-modules/pipes/legal-type-translator/legal-type-translator.module';
|
import {LegalTypeTranslatorModule} from '../../../widget-modules/pipes/legal-type-translator/legal-type-translator.module';
|
||||||
|
import {ListHeaderModule} from '../../../widget-modules/components/list-header/list-header.module';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -15,7 +16,8 @@ import {LegalTypeTranslatorModule} from '../../../widget-modules/pipes/legal-typ
|
|||||||
RouterModule,
|
RouterModule,
|
||||||
|
|
||||||
CardModule,
|
CardModule,
|
||||||
LegalTypeTranslatorModule
|
LegalTypeTranslatorModule,
|
||||||
|
ListHeaderModule
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class SongListModule {
|
export class SongListModule {
|
||||||
|
|||||||
@@ -35,6 +35,20 @@
|
|||||||
<textarea [mat-autosize]="true" formControlName="comment" matInput></textarea>
|
<textarea [mat-autosize]="true" formControlName="comment" matInput></textarea>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-chip-list #chipList aria-label="Fruit selection">
|
||||||
|
<mat-chip (removed)="removeFlag(flag)" *ngFor="let flag of flags"
|
||||||
|
[removable]="true" [selectable]="false">
|
||||||
|
{{flag}}
|
||||||
|
<fa-icon (click)="removeFlag(flag)" [icon]="faRemove"></fa-icon>
|
||||||
|
</mat-chip>
|
||||||
|
<input (matChipInputTokenEnd)="addFlag($event)"
|
||||||
|
[matChipInputAddOnBlur]="true"
|
||||||
|
[matChipInputFor]="chipList"
|
||||||
|
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
||||||
|
placeholder="Attribute">
|
||||||
|
</mat-chip-list>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="outline">
|
<mat-form-field appearance="outline">
|
||||||
<mat-label>Rechtlicher Status</mat-label>
|
<mat-label>Rechtlicher Status</mat-label>
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ import {SongService} from '../../../services/song.service';
|
|||||||
import {EditService} from '../edit.service';
|
import {EditService} from '../edit.service';
|
||||||
import {first, map, switchMap} from 'rxjs/operators';
|
import {first, map, switchMap} from 'rxjs/operators';
|
||||||
import {KEYS} from '../../../services/key.helper';
|
import {KEYS} from '../../../services/key.helper';
|
||||||
|
import {COMMA, ENTER} from '@angular/cdk/keycodes';
|
||||||
|
import {MatChipInputEvent} from '@angular/material/chips';
|
||||||
|
import {faTimesCircle} from '@fortawesome/free-solid-svg-icons/faTimesCircle';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-edit-song',
|
selector: 'app-edit-song',
|
||||||
@@ -19,6 +22,9 @@ export class EditSongComponent implements OnInit {
|
|||||||
public types = SongService.TYPES;
|
public types = SongService.TYPES;
|
||||||
public legalOwner = SongService.LEGAL_OWNER;
|
public legalOwner = SongService.LEGAL_OWNER;
|
||||||
public legalType = SongService.LEGAL_TYPE;
|
public legalType = SongService.LEGAL_TYPE;
|
||||||
|
public flags: string[] = [];
|
||||||
|
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||||
|
public faRemove = faTimesCircle;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
@@ -36,6 +42,8 @@ export class EditSongComponent implements OnInit {
|
|||||||
).subscribe(song => {
|
).subscribe(song => {
|
||||||
this.song = song;
|
this.song = song;
|
||||||
this.form = this.editService.createSongForm(song);
|
this.form = this.editService.createSongForm(song);
|
||||||
|
this.form.controls.flags.valueChanges.subscribe(_ => this.onFlagsChanged(_))
|
||||||
|
this.onFlagsChanged(this.form.controls.flags.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,4 +53,31 @@ export class EditSongComponent implements OnInit {
|
|||||||
await this.router.navigateByUrl('songs/' + this.song.id);
|
await this.router.navigateByUrl('songs/' + this.song.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public removeFlag(flag: string): void {
|
||||||
|
const flags = this.flags.filter(_ => _ !== flag);
|
||||||
|
this.form.controls.flags.setValue(flags.reduce((a, b) => `${a};${b}`, ''));
|
||||||
|
}
|
||||||
|
|
||||||
|
public addFlag(event: MatChipInputEvent): void {
|
||||||
|
const input = event.input;
|
||||||
|
const value = event.value;
|
||||||
|
|
||||||
|
// Add our fruit
|
||||||
|
if ((value || '').trim()) {
|
||||||
|
const flags = [...this.flags, value.trim()];
|
||||||
|
this.form.controls.flags.setValue(flags.reduce((a, b) => `${a};${b}`, ''));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input) input.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
private onFlagsChanged(flagArray: string): void {
|
||||||
|
console.log(flagArray);
|
||||||
|
if (!flagArray) {
|
||||||
|
this.flags = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.flags = flagArray.split(';').filter(_ => !!_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import {FileComponent} from './edit-file/file/file.component';
|
|||||||
import {LegalOwnerTranslatorModule} from '../../../../widget-modules/pipes/legal-owner-translator/legal-owner-translator.module';
|
import {LegalOwnerTranslatorModule} from '../../../../widget-modules/pipes/legal-owner-translator/legal-owner-translator.module';
|
||||||
import {LegalTypeTranslatorModule} from '../../../../widget-modules/pipes/legal-type-translator/legal-type-translator.module';
|
import {LegalTypeTranslatorModule} from '../../../../widget-modules/pipes/legal-type-translator/legal-type-translator.module';
|
||||||
import {KeyTranslatorModule} from '../../../../widget-modules/pipes/key-translator/key-translator.module';
|
import {KeyTranslatorModule} from '../../../../widget-modules/pipes/key-translator/key-translator.module';
|
||||||
|
import {MatChipsModule} from '@angular/material/chips';
|
||||||
|
import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -39,6 +41,8 @@ import {KeyTranslatorModule} from '../../../../widget-modules/pipes/key-translat
|
|||||||
LegalOwnerTranslatorModule,
|
LegalOwnerTranslatorModule,
|
||||||
LegalTypeTranslatorModule,
|
LegalTypeTranslatorModule,
|
||||||
KeyTranslatorModule,
|
KeyTranslatorModule,
|
||||||
|
MatChipsModule,
|
||||||
|
FontAwesomeModule,
|
||||||
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ export class EditService {
|
|||||||
text: new FormControl(song.text),
|
text: new FormControl(song.text),
|
||||||
title: new FormControl(song.title),
|
title: new FormControl(song.title),
|
||||||
comment: new FormControl(song.comment),
|
comment: new FormControl(song.comment),
|
||||||
|
flags: new FormControl(song.flags),
|
||||||
key: new FormControl(song.key),
|
key: new FormControl(song.key),
|
||||||
tempo: new FormControl(song.tempo),
|
tempo: new FormControl(song.tempo),
|
||||||
type: new FormControl(song.type),
|
type: new FormControl(song.type),
|
||||||
|
|||||||
@@ -19,6 +19,10 @@
|
|||||||
<app-song-text *ngIf="user$|async as user" [chordMode]="user.chordMode" [showSwitch]="true"
|
<app-song-text *ngIf="user$|async as user" [chordMode]="user.chordMode" [showSwitch]="true"
|
||||||
[text]="song.text"></app-song-text>
|
[text]="song.text"></app-song-text>
|
||||||
|
|
||||||
|
<mat-chip-list aria-label="Attribute">
|
||||||
|
<mat-chip *ngFor="let flag of getFlags(song.flags)">{{flag}}</mat-chip>
|
||||||
|
</mat-chip-list>
|
||||||
|
|
||||||
<div class="text">{{song.comment}}</div>
|
<div class="text">{{song.comment}}</div>
|
||||||
<div>
|
<div>
|
||||||
<h3>Anhänge</h3>
|
<h3>Anhänge</h3>
|
||||||
|
|||||||
@@ -41,4 +41,9 @@ export class SongComponent implements OnInit {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getFlags = (flags: string): string[] => {
|
||||||
|
if (!flags) return [];
|
||||||
|
return flags.split(';').filter(_ => !!_);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {ButtonRowModule} from '../../../widget-modules/components/button-row/but
|
|||||||
import {RouterModule} from '@angular/router';
|
import {RouterModule} from '@angular/router';
|
||||||
import {LegalOwnerTranslatorModule} from '../../../widget-modules/pipes/legal-owner-translator/legal-owner-translator.module';
|
import {LegalOwnerTranslatorModule} from '../../../widget-modules/pipes/legal-owner-translator/legal-owner-translator.module';
|
||||||
import {SongTextModule} from '../../../widget-modules/components/song-text/song-text.module';
|
import {SongTextModule} from '../../../widget-modules/components/song-text/song-text.module';
|
||||||
|
import {MatChipsModule} from '@angular/material/chips';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -23,6 +24,7 @@ import {SongTextModule} from '../../../widget-modules/components/song-text/song-
|
|||||||
ButtonRowModule,
|
ButtonRowModule,
|
||||||
LegalOwnerTranslatorModule,
|
LegalOwnerTranslatorModule,
|
||||||
SongTextModule,
|
SongTextModule,
|
||||||
|
MatChipsModule,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class SongModule {
|
export class SongModule {
|
||||||
|
|||||||
@@ -81,3 +81,7 @@ perfect-scrollbar.scroll > .ps .ps__rail-y:hover {
|
|||||||
background-color: #222;
|
background-color: #222;
|
||||||
opacity: .3;
|
opacity: .3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mat-chip.mat-standard-chip {
|
||||||
|
background: #fffa;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user