update tslint -> eslint
This commit is contained in:
@@ -1,26 +1,29 @@
|
||||
<app-card heading="Angehängte Dateien">
|
||||
|
||||
|
||||
<div *ngIf="currentUpload">
|
||||
<div class="progress">
|
||||
<div [ngStyle]="{ 'width': currentUpload?.progress + '%' }" class="progress-bar progress-bar-animated"></div>
|
||||
<div
|
||||
[ngStyle]="{ width: currentUpload?.progress + '%' }"
|
||||
class="progress-bar progress-bar-animated"
|
||||
></div>
|
||||
</div>
|
||||
Progress: {{currentUpload?.name}} | {{currentUpload?.progress}}% Complete
|
||||
Progress: {{ currentUpload?.name }} | {{ currentUpload?.progress }}%
|
||||
Complete
|
||||
</div>
|
||||
<div class="upload">
|
||||
<label>
|
||||
<input (change)="detectFiles($event)" type="file">
|
||||
<input (change)="detectFiles($event)" type="file"/>
|
||||
</label>
|
||||
|
||||
<button (click)="uploadSingle()"
|
||||
[disabled]="!selectedFiles"
|
||||
mat-icon-button>
|
||||
<button
|
||||
(click)="uploadSingle()"
|
||||
[disabled]="!selectedFiles"
|
||||
mat-icon-button
|
||||
>
|
||||
<mat-icon>cloud_upload</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p *ngFor="let file of (files$|async)">
|
||||
<p *ngFor="let file of files$ | async">
|
||||
<app-file [file]="file" [songId]="songId"></app-file>
|
||||
</p>
|
||||
</app-card>
|
||||
|
||||
|
||||
@@ -6,12 +6,13 @@ describe('EditFileComponent', () => {
|
||||
let component: EditFileComponent;
|
||||
let fixture: ComponentFixture<EditFileComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [EditFileComponent]
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
void TestBed.configureTestingModule({
|
||||
declarations: [EditFileComponent],
|
||||
}).compileComponents();
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(EditFileComponent);
|
||||
@@ -20,6 +21,6 @@ describe('EditFileComponent', () => {
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
void expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,41 +10,33 @@ import {File} from '../../../services/file';
|
||||
@Component({
|
||||
selector: 'app-edit-file',
|
||||
templateUrl: './edit-file.component.html',
|
||||
styleUrls: ['./edit-file.component.less']
|
||||
styleUrls: ['./edit-file.component.less'],
|
||||
})
|
||||
export class EditFileComponent {
|
||||
|
||||
public selectedFiles: FileList;
|
||||
public currentUpload: Upload;
|
||||
public songId: string;
|
||||
public files$: Observable<File[]>;
|
||||
|
||||
|
||||
constructor(
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private uploadService: UploadService,
|
||||
private fileService: FileDataService,
|
||||
) {
|
||||
this.activatedRoute.params.pipe(
|
||||
map(param => param.songId),
|
||||
).subscribe(songId => {
|
||||
public constructor(private activatedRoute: ActivatedRoute, private uploadService: UploadService, private fileService: FileDataService) {
|
||||
this.activatedRoute.params.pipe(map((param: {songId: string}) => param.songId)).subscribe(songId => {
|
||||
this.songId = songId;
|
||||
});
|
||||
|
||||
this.files$ = this.activatedRoute.params.pipe(
|
||||
map(param => param.songId),
|
||||
map((param: {songId: string}) => param.songId),
|
||||
switchMap(songId => this.fileService.read$(songId))
|
||||
);
|
||||
}
|
||||
|
||||
detectFiles(event) {
|
||||
this.selectedFiles = event.target.files;
|
||||
public detectFiles(event: Event): void {
|
||||
const target = event.target as HTMLInputElement;
|
||||
this.selectedFiles = target.files;
|
||||
}
|
||||
|
||||
public async uploadSingle() {
|
||||
public uploadSingle(): void {
|
||||
const file = this.selectedFiles.item(0);
|
||||
this.currentUpload = new Upload(file as any);
|
||||
await this.uploadService.pushUpload(this.songId, this.currentUpload);
|
||||
this.currentUpload = new Upload(file);
|
||||
this.uploadService.pushUpload(this.songId, this.currentUpload);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
<fa-icon [icon]="faTrash"></fa-icon>
|
||||
</button>
|
||||
|
||||
<a [href]="url$|async" target="_blank">{{name}}</a>
|
||||
<a [href]="url$ | async" target="_blank">{{ name }}</a>
|
||||
|
||||
@@ -6,12 +6,13 @@ describe('FileComponent', () => {
|
||||
let component: FileComponent;
|
||||
let fixture: ComponentFixture<FileComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [FileComponent]
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
void TestBed.configureTestingModule({
|
||||
declarations: [FileComponent],
|
||||
}).compileComponents();
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FileComponent);
|
||||
@@ -20,6 +21,6 @@ describe('FileComponent', () => {
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
void expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,20 +7,20 @@ import {FileService} from '../../../../services/file.service';
|
||||
@Component({
|
||||
selector: 'app-file',
|
||||
templateUrl: './file.component.html',
|
||||
styleUrls: ['./file.component.less']
|
||||
styleUrls: ['./file.component.less'],
|
||||
})
|
||||
export class FileComponent {
|
||||
public url$: Observable<string>;
|
||||
public name: string;
|
||||
public faTrash = faTrashAlt;
|
||||
@Input() songId: string;
|
||||
@Input() public songId: string;
|
||||
private fileId: string;
|
||||
private path: string;
|
||||
|
||||
constructor(private fileService: FileService) {
|
||||
}
|
||||
public constructor(private fileService: FileService) {}
|
||||
|
||||
@Input() set file(file: File) {
|
||||
@Input()
|
||||
public set file(file: File) {
|
||||
this.url$ = this.fileService.getDownloadUrl(file.path + '/' + file.name);
|
||||
this.name = file.name;
|
||||
this.fileId = file.id;
|
||||
|
||||
@@ -6,11 +6,11 @@ describe('EditSongGuard', () => {
|
||||
let guard: EditSongGuard;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
void TestBed.configureTestingModule({});
|
||||
guard = TestBed.inject(EditSongGuard);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(guard).toBeTruthy();
|
||||
void expect(guard).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,16 +4,15 @@ import {Observable} from 'rxjs';
|
||||
import {EditComponent} from './edit.component';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class EditSongGuard implements CanDeactivate<unknown> {
|
||||
canDeactivate(
|
||||
public canDeactivate(
|
||||
component: EditComponent,
|
||||
currentRoute: ActivatedRouteSnapshot,
|
||||
currentState: RouterStateSnapshot,
|
||||
nextState?: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
|
||||
|
||||
nextState?: RouterStateSnapshot
|
||||
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
|
||||
return component.editSongComponent.askForSave(nextState);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,48 +1,58 @@
|
||||
<app-card *ngIf="song" [heading]="song.number + ' bearbeiten'" closeLink="../">
|
||||
|
||||
<form [formGroup]="form" class="form">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Titel</mat-label>
|
||||
<input formControlName="title" matInput>
|
||||
<input formControlName="title" matInput/>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="fourth">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Typ</mat-label>
|
||||
<mat-select formControlName="type">
|
||||
<mat-option *ngFor="let type of types" [value]="type">{{type | songType}}</mat-option>
|
||||
<mat-option *ngFor="let type of types" [value]="type">{{
|
||||
type | songType
|
||||
}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Tonart</mat-label>
|
||||
<mat-select formControlName="key">
|
||||
<mat-option *ngFor="let key of keys" [value]="key">{{key|key}}</mat-option>
|
||||
<mat-option *ngFor="let key of keys" [value]="key">{{
|
||||
key | key
|
||||
}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Tempo</mat-label>
|
||||
<input formControlName="tempo" matInput>
|
||||
<input formControlName="tempo" matInput/>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Status</mat-label>
|
||||
<mat-select formControlName="status">
|
||||
<mat-option *ngFor="let status of status" [value]="status">{{status | status}}</mat-option>
|
||||
<mat-option *ngFor="let status of status" [value]="status">{{
|
||||
status | status
|
||||
}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Songtext</mat-label>
|
||||
<textarea (focus)="songtextFocus=true" (focusout)="songtextFocus=false" [mat-autosize]="true"
|
||||
formControlName="text" matInput></textarea>
|
||||
<textarea
|
||||
(focus)="songtextFocus = true"
|
||||
(focusout)="songtextFocus = false"
|
||||
[mat-autosize]="true"
|
||||
formControlName="text"
|
||||
matInput
|
||||
></textarea>
|
||||
</mat-form-field>
|
||||
<div *ngIf="songtextFocus" class="song-text-help">
|
||||
<h3>Vorschau</h3>
|
||||
<app-song-text [text]="form.value.text" chordMode="show"></app-song-text>
|
||||
<h3>Hinweise zur Bearbeitung</h3>
|
||||
<h4>Aufbau</h4>
|
||||
Der Liedtext wird hintereinander weg geschrieben. Dabei werden Strophen, Refrain und Bridge jeweils durch
|
||||
eine zusätzliche Zeile Markiert. z.B.
|
||||
Der Liedtext wird hintereinander weg geschrieben. Dabei werden Strophen,
|
||||
Refrain und Bridge jeweils durch eine zusätzliche Zeile Markiert. z.B.
|
||||
<pre>
|
||||
Strophe
|
||||
Text der ersten Strophe
|
||||
@@ -54,9 +64,10 @@
|
||||
Und hier der Refrain
|
||||
</pre>
|
||||
<h3>Akkorde</h3>
|
||||
Die Akktorde werden jeweils in der Zeile über dem jeweiligen Liedtext geschrieben.
|
||||
Sie werden jeweils durch Leerzeichen an die entsprechende Position gebracht.
|
||||
Bitte keine Tabulatoren verwenden! Folgende Schreibweisen sind erlaubt:
|
||||
Die Akktorde werden jeweils in der Zeile über dem jeweiligen Liedtext
|
||||
geschrieben. Sie werden jeweils durch Leerzeichen an die entsprechende
|
||||
Position gebracht. Bitte keine Tabulatoren verwenden! Folgende
|
||||
Schreibweisen sind erlaubt:
|
||||
<pre>
|
||||
Dur: C D E
|
||||
Moll: c d e
|
||||
@@ -76,21 +87,31 @@
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Kommentar</mat-label>
|
||||
<textarea [mat-autosize]="true" formControlName="comment" matInput></textarea>
|
||||
<textarea
|
||||
[mat-autosize]="true"
|
||||
formControlName="comment"
|
||||
matInput
|
||||
></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-chip-list #chipList>
|
||||
<mat-chip (removed)="removeFlag(flag)" *ngFor="let flag of flags"
|
||||
[removable]="true" [selectable]="false">
|
||||
{{flag}}
|
||||
<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">
|
||||
<input
|
||||
(matChipInputTokenEnd)="addFlag($event)"
|
||||
[matChipInputAddOnBlur]="true"
|
||||
[matChipInputFor]="chipList"
|
||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
||||
placeholder="Attribute"
|
||||
/>
|
||||
</mat-chip-list>
|
||||
</mat-form-field>
|
||||
|
||||
@@ -98,54 +119,62 @@
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Rechtlicher Status</mat-label>
|
||||
<mat-select formControlName="legalType">
|
||||
<mat-option *ngFor="let key of legalType" [value]="key">{{key|legalType}}</mat-option>
|
||||
<mat-option *ngFor="let key of legalType" [value]="key">{{
|
||||
key | legalType
|
||||
}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Rechteinhaber</mat-label>
|
||||
<mat-select formControlName="legalOwner">
|
||||
<mat-option *ngFor="let key of legalOwner" [value]="key">{{key|legalOwner}}</mat-option>
|
||||
<mat-option *ngFor="let key of legalOwner" [value]="key">{{
|
||||
key | legalOwner
|
||||
}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Rechteinhaber ID (z.B. CCLI Liednummer)</mat-label>
|
||||
<input formControlName="legalOwnerId" matInput>
|
||||
<a *ngIf="form.value.legalOwner==='CCLI'" class="link-ccli"
|
||||
href="https://songselect.ccli.com/Songs/{{form.value.legalOwnerId}}"
|
||||
matSuffix
|
||||
matTooltip="CCLI Link: https://songselect.ccli.com/Songs/{{form.value.legalOwnerId}}"
|
||||
matTooltipPosition="before" target="_blank">
|
||||
<input formControlName="legalOwnerId" matInput/>
|
||||
<a
|
||||
*ngIf="form.value.legalOwner === 'CCLI'"
|
||||
class="link-ccli"
|
||||
href="https://songselect.ccli.com/Songs/{{ form.value.legalOwnerId }}"
|
||||
matSuffix
|
||||
matTooltip="CCLI Link: https://songselect.ccli.com/Songs/{{
|
||||
form.value.legalOwnerId
|
||||
}}"
|
||||
matTooltipPosition="before"
|
||||
target="_blank"
|
||||
>
|
||||
<fa-icon [icon]="faLink"></fa-icon>
|
||||
</a>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Künstler</mat-label>
|
||||
<input formControlName="artist" matInput>
|
||||
<input formControlName="artist" matInput/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Verlag</mat-label>
|
||||
<input formControlName="label" matInput>
|
||||
<input formControlName="label" matInput/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Nutzungsbedingungen</mat-label>
|
||||
<input formControlName="termsOfUse" matInput>
|
||||
<input formControlName="termsOfUse" matInput/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>abweichende Quelle</mat-label>
|
||||
<input formControlName="origin" matInput>
|
||||
<input formControlName="origin" matInput/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<app-button-row>
|
||||
<app-button (click)="onSave()" [icon]="faSave">Speichern</app-button>
|
||||
</app-button-row>
|
||||
</app-card>
|
||||
|
||||
|
||||
@@ -6,12 +6,13 @@ describe('EditSongComponent', () => {
|
||||
let component: EditSongComponent;
|
||||
let fixture: ComponentFixture<EditSongComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [EditSongComponent]
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
void TestBed.configureTestingModule({
|
||||
declarations: [EditSongComponent],
|
||||
}).compileComponents();
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(EditSongComponent);
|
||||
@@ -20,6 +21,6 @@ describe('EditSongComponent', () => {
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
void expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ import {SaveDialogComponent} from './save-dialog/save-dialog.component';
|
||||
@Component({
|
||||
selector: 'app-edit-song',
|
||||
templateUrl: './edit-song.component.html',
|
||||
styleUrls: ['./edit-song.component.less']
|
||||
styleUrls: ['./edit-song.component.less'],
|
||||
})
|
||||
export class EditSongComponent implements OnInit {
|
||||
public song: Song;
|
||||
@@ -28,36 +28,31 @@ export class EditSongComponent implements OnInit {
|
||||
public legalOwner = SongService.LEGAL_OWNER;
|
||||
public legalType = SongService.LEGAL_TYPE;
|
||||
public flags: string[] = [];
|
||||
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||
public readonly separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||
public faRemove = faTimesCircle;
|
||||
public faSave = faSave;
|
||||
public faLink = faExternalLinkAlt;
|
||||
public songtextFocus = false;
|
||||
|
||||
constructor(
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private songService: SongService,
|
||||
private editService: EditService,
|
||||
private router: Router,
|
||||
public dialog: MatDialog
|
||||
) {
|
||||
}
|
||||
public constructor(private activatedRoute: ActivatedRoute, private songService: SongService, private editService: EditService, private router: Router, public dialog: MatDialog) {}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.activatedRoute.params.pipe(
|
||||
map(param => param.songId),
|
||||
switchMap(songId => this.songService.read$(songId)),
|
||||
first()
|
||||
).subscribe(song => {
|
||||
this.song = song;
|
||||
this.form = this.editService.createSongForm(song);
|
||||
this.form.controls.flags.valueChanges.subscribe(_ => this.onFlagsChanged(_));
|
||||
this.onFlagsChanged(this.form.controls.flags.value);
|
||||
});
|
||||
this.activatedRoute.params
|
||||
.pipe(
|
||||
map((param: {songId: string}) => param.songId),
|
||||
switchMap(songId => this.songService.read$(songId)),
|
||||
first()
|
||||
)
|
||||
.subscribe(song => {
|
||||
this.song = song;
|
||||
this.form = this.editService.createSongForm(song);
|
||||
this.form.controls.flags.valueChanges.subscribe(_ => this.onFlagsChanged(_));
|
||||
this.onFlagsChanged(this.form.controls.flags.value);
|
||||
});
|
||||
}
|
||||
|
||||
public async onSave(): Promise<void> {
|
||||
const data = this.form.value;
|
||||
const data = this.form.value as Partial<Song>;
|
||||
await this.songService.update$(this.song.id, data);
|
||||
this.form.markAsPristine();
|
||||
await this.router.navigateByUrl('songs/' + this.song.id);
|
||||
@@ -83,6 +78,22 @@ export class EditSongComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
public askForSave(nextState?: RouterStateSnapshot): boolean {
|
||||
if (!this.form.dirty) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const dialogRef = this.dialog.open(SaveDialogComponent, {
|
||||
width: '350px',
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((save: boolean) => {
|
||||
void this.onSaveDialogAfterClosed(save, nextState.url).then();
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private onFlagsChanged(flagArray: string): void {
|
||||
if (!flagArray) {
|
||||
this.flags = [];
|
||||
@@ -92,30 +103,13 @@ export class EditSongComponent implements OnInit {
|
||||
this.flags = flagArray.split(';').filter(_ => !!_);
|
||||
}
|
||||
|
||||
public askForSave(nextState?: RouterStateSnapshot): boolean {
|
||||
if (!this.form.dirty) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const dialogRef = this.dialog.open(SaveDialogComponent, {
|
||||
width: '350px'
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((save: boolean) => {
|
||||
this.onSaveDialogAfterClosed(save, nextState.url).then();
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private async onSaveDialogAfterClosed(save: boolean, url: string) {
|
||||
if (save) {
|
||||
const data = this.form.value;
|
||||
const data = this.form.value as Partial<Song>;
|
||||
await this.songService.update$(this.song.id, data);
|
||||
}
|
||||
|
||||
this.form.markAsPristine();
|
||||
await this.router.navigateByUrl(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,5 +4,7 @@
|
||||
</div>
|
||||
<div mat-dialog-actions>
|
||||
<button [mat-dialog-close]="false" mat-button>Änderungen verwerfen</button>
|
||||
<button [mat-dialog-close]="true" cdkFocusInitial mat-button>Speichern</button>
|
||||
<button [mat-dialog-close]="true" cdkFocusInitial mat-button>
|
||||
Speichern
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -6,12 +6,13 @@ describe('SaveDialogComponent', () => {
|
||||
let component: SaveDialogComponent;
|
||||
let fixture: ComponentFixture<SaveDialogComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [SaveDialogComponent]
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
void TestBed.configureTestingModule({
|
||||
declarations: [SaveDialogComponent],
|
||||
}).compileComponents();
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SaveDialogComponent);
|
||||
@@ -20,6 +21,6 @@ describe('SaveDialogComponent', () => {
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
void expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-save-dialog',
|
||||
templateUrl: './save-dialog.component.html',
|
||||
styleUrls: ['./save-dialog.component.less']
|
||||
styleUrls: ['./save-dialog.component.less'],
|
||||
})
|
||||
export class SaveDialogComponent implements OnInit {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
export class SaveDialogComponent {}
|
||||
|
||||
@@ -6,12 +6,13 @@ describe('EditComponent', () => {
|
||||
let component: EditComponent;
|
||||
let fixture: ComponentFixture<EditComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [EditComponent]
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
void TestBed.configureTestingModule({
|
||||
declarations: [EditComponent],
|
||||
}).compileComponents();
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(EditComponent);
|
||||
@@ -20,6 +21,6 @@ describe('EditComponent', () => {
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
void expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@ import {EditSongComponent} from './edit-song/edit-song.component';
|
||||
@Component({
|
||||
selector: 'app-edit',
|
||||
templateUrl: './edit.component.html',
|
||||
styleUrls: ['./edit.component.less']
|
||||
styleUrls: ['./edit.component.less'],
|
||||
})
|
||||
export class EditComponent {
|
||||
@ViewChild(EditSongComponent) public editSongComponent: EditSongComponent;
|
||||
|
||||
@@ -27,7 +27,6 @@ import {MatDialogModule} from '@angular/material/dialog';
|
||||
import {HistoryComponent} from './history/history.component';
|
||||
import {SongTextModule} from '../../../../widget-modules/components/song-text/song-text.module';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [EditComponent, EditSongComponent, EditFileComponent, FileComponent, SaveDialogComponent, HistoryComponent],
|
||||
exports: [EditComponent],
|
||||
@@ -56,8 +55,6 @@ import {SongTextModule} from '../../../../widget-modules/components/song-text/so
|
||||
MatTooltipModule,
|
||||
MatDialogModule,
|
||||
SongTextModule,
|
||||
|
||||
]
|
||||
],
|
||||
})
|
||||
export class EditModule {
|
||||
}
|
||||
export class EditModule {}
|
||||
|
||||
@@ -3,10 +3,10 @@ import {TestBed} from '@angular/core/testing';
|
||||
import {EditService} from './edit.service';
|
||||
|
||||
describe('EditService', () => {
|
||||
beforeEach(() => TestBed.configureTestingModule({}));
|
||||
beforeEach(() => void TestBed.configureTestingModule({}));
|
||||
|
||||
it('should be created', () => {
|
||||
const service: EditService = TestBed.get(EditService);
|
||||
expect(service).toBeTruthy();
|
||||
const service: EditService = TestBed.inject(EditService);
|
||||
void expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,13 +3,9 @@ import {Song} from '../../services/song';
|
||||
import {FormControl, FormGroup} from '@angular/forms';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class EditService {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
public createSongForm(song: Song): FormGroup {
|
||||
return new FormGroup({
|
||||
text: new FormControl(song.text),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<app-card *ngIf="song && song.edits" heading="letzte Änderungen">
|
||||
<div *ngFor="let edit of song.edits" class="list">
|
||||
<div>{{edit.username}}</div>
|
||||
<div>{{edit.timestamp.toDate()|date:'dd.MM.yyyy'}}</div>
|
||||
<div>{{ edit.username }}</div>
|
||||
<div>{{ edit.timestamp.toDate() | date: "dd.MM.yyyy" }}</div>
|
||||
</div>
|
||||
</app-card>
|
||||
|
||||
@@ -6,12 +6,13 @@ describe('HistoryComponent', () => {
|
||||
let component: HistoryComponent;
|
||||
let fixture: ComponentFixture<HistoryComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [HistoryComponent]
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
void TestBed.configureTestingModule({
|
||||
declarations: [HistoryComponent],
|
||||
}).compileComponents();
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(HistoryComponent);
|
||||
@@ -20,6 +21,6 @@ describe('HistoryComponent', () => {
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
void expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,25 +7,22 @@ import {Song} from '../../../services/song';
|
||||
@Component({
|
||||
selector: 'app-history',
|
||||
templateUrl: './history.component.html',
|
||||
styleUrls: ['./history.component.less']
|
||||
styleUrls: ['./history.component.less'],
|
||||
})
|
||||
export class HistoryComponent implements OnInit {
|
||||
public song: Song;
|
||||
|
||||
constructor(
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private songService: SongService,
|
||||
) {
|
||||
}
|
||||
|
||||
public constructor(private activatedRoute: ActivatedRoute, private songService: SongService) {}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.activatedRoute.params.pipe(
|
||||
map(param => param.songId),
|
||||
switchMap(songId => this.songService.read$(songId)),
|
||||
first()
|
||||
).subscribe(song => {
|
||||
this.song = song;
|
||||
});
|
||||
this.activatedRoute.params
|
||||
.pipe(
|
||||
map((param: {songId: string}) => param.songId),
|
||||
switchMap(songId => this.songService.read$(songId)),
|
||||
first()
|
||||
)
|
||||
.subscribe(song => {
|
||||
this.song = song;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<a [href]="url$|async" target="_blank">
|
||||
{{name}}
|
||||
<a [href]="url$ | async" target="_blank">
|
||||
{{ name }}
|
||||
</a>
|
||||
|
||||
@@ -6,12 +6,13 @@ describe('FileComponent', () => {
|
||||
let component: FileComponent;
|
||||
let fixture: ComponentFixture<FileComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [FileComponent]
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
void TestBed.configureTestingModule({
|
||||
declarations: [FileComponent],
|
||||
}).compileComponents();
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FileComponent);
|
||||
@@ -20,6 +21,6 @@ describe('FileComponent', () => {
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
void expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {File} from '../../services/file';
|
||||
import {AngularFireStorage} from '@angular/fire/storage';
|
||||
import {Observable} from 'rxjs';
|
||||
@@ -6,24 +6,18 @@ import {Observable} from 'rxjs';
|
||||
@Component({
|
||||
selector: 'app-file',
|
||||
templateUrl: './file.component.html',
|
||||
styleUrls: ['./file.component.less']
|
||||
styleUrls: ['./file.component.less'],
|
||||
})
|
||||
export class FileComponent implements OnInit {
|
||||
export class FileComponent {
|
||||
public url$: Observable<string>;
|
||||
public name: string;
|
||||
|
||||
constructor(private storage: AngularFireStorage) {
|
||||
}
|
||||
|
||||
@Input() set file(file: File) {
|
||||
public constructor(private storage: AngularFireStorage) {}
|
||||
|
||||
@Input()
|
||||
public set file(file: File) {
|
||||
const ref = this.storage.ref(file.path + '/' + file.name);
|
||||
this.url$ = ref.getDownloadURL();
|
||||
this.url$ = ref.getDownloadURL() as Observable<string>;
|
||||
this.name = file.name;
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
<app-card closeLink="../" heading="Neues Lied">
|
||||
|
||||
<div [formGroup]="form" class="split">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Nummer</mat-label>
|
||||
<input formControlName="number" matInput>
|
||||
<input formControlName="number" matInput/>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Titel</mat-label>
|
||||
<input autofocus formControlName="title" matInput>
|
||||
<input autofocus formControlName="title" matInput/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
@@ -15,4 +14,3 @@
|
||||
<app-button (click)="onSave()" [icon]="faSave">Anlegen</app-button>
|
||||
</app-button-row>
|
||||
</app-card>
|
||||
|
||||
|
||||
@@ -6,12 +6,13 @@ describe('NewComponent', () => {
|
||||
let component: NewComponent;
|
||||
let fixture: ComponentFixture<NewComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [NewComponent]
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
void TestBed.configureTestingModule({
|
||||
declarations: [NewComponent],
|
||||
}).compileComponents();
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(NewComponent);
|
||||
@@ -20,6 +21,6 @@ describe('NewComponent', () => {
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
void expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,14 +10,13 @@ import {Router} from '@angular/router';
|
||||
@Component({
|
||||
selector: 'app-new',
|
||||
templateUrl: './new.component.html',
|
||||
styleUrls: ['./new.component.less']
|
||||
styleUrls: ['./new.component.less'],
|
||||
})
|
||||
export class NewComponent implements OnInit {
|
||||
public faSave = faSave;
|
||||
public form: FormGroup;
|
||||
|
||||
constructor(private songService: SongService, private router: Router) {
|
||||
}
|
||||
public constructor(private songService: SongService, private router: Router) {}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.form = new FormGroup({
|
||||
@@ -25,23 +24,27 @@ export class NewComponent implements OnInit {
|
||||
title: new FormControl(null, Validators.required),
|
||||
});
|
||||
|
||||
this.songService.list$().pipe(autoComplete(this)).subscribe(songs => {
|
||||
const freeSongnumber = this.getFreeSongNumber(songs);
|
||||
this.form.controls.number.setValue(freeSongnumber);
|
||||
});
|
||||
this.songService
|
||||
.list$()
|
||||
.pipe(autoComplete(this))
|
||||
.subscribe(songs => {
|
||||
const freeSongnumber = this.getFreeSongNumber(songs);
|
||||
this.form.controls.number.setValue(freeSongnumber);
|
||||
});
|
||||
}
|
||||
|
||||
public async onSave(): Promise<void> {
|
||||
const number = this.form.value.number;
|
||||
const title = this.form.value.title;
|
||||
const newSongId = await this.songService.new(number, title);
|
||||
const value = this.form.value as {number: number; title: string};
|
||||
const songNumber = value.number;
|
||||
const title = value.title;
|
||||
const newSongId = await this.songService.new(songNumber, title);
|
||||
await this.router.navigateByUrl('/songs/' + newSongId + '/edit');
|
||||
}
|
||||
|
||||
private getFreeSongNumber(songs: Song[]): Number {
|
||||
const numbers = songs.map(_ => _.number);
|
||||
private getFreeSongNumber(songs: Song[]): number {
|
||||
const songNumber = songs.map(_ => _.number);
|
||||
for (let i = 1; i < Number.MAX_SAFE_INTEGER; i++) {
|
||||
if (!numbers.some(_ => _ === i)) {
|
||||
if (!songNumber.some(_ => _ === i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,19 +9,8 @@ import {ButtonRowModule} from '../../../../widget-modules/components/button-row/
|
||||
import {ButtonModule} from '../../../../widget-modules/components/button/button.module';
|
||||
import {AutofocusModule} from '../../../../widget-modules/directives/autofocus/autofocus.module';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [NewComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
CardModule,
|
||||
ReactiveFormsModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
ButtonRowModule,
|
||||
ButtonModule,
|
||||
AutofocusModule
|
||||
]
|
||||
imports: [CommonModule, CardModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, ButtonRowModule, ButtonModule, AutofocusModule],
|
||||
})
|
||||
export class NewModule {
|
||||
}
|
||||
export class NewModule {}
|
||||
|
||||
@@ -1,47 +1,74 @@
|
||||
<div class="split">
|
||||
<app-card *ngIf="song$ | async as song" [heading]="song.number + ' - ' + song.title" closeLink="../">
|
||||
<app-card
|
||||
*ngIf="song$ | async as song"
|
||||
[heading]="song.number + ' - ' + song.title"
|
||||
closeLink="../"
|
||||
>
|
||||
<div class="song">
|
||||
<div>
|
||||
<div *appRole="['leader', 'contributor']" class="detail">
|
||||
<div>Typ: {{song.type | songType}}</div>
|
||||
<div>Tonart: {{song.key}}</div>
|
||||
<div>Tempo: {{song.tempo}}</div>
|
||||
<div>Status: {{(song.status|status) || 'entwurf'}}</div>
|
||||
<div *ngIf="song.legalOwner">Rechteinhaber: {{song.legalOwner|legalOwner}}</div>
|
||||
<div *ngIf="song.legalOwnerId && song.legalOwner==='CCLI'">
|
||||
<a href="https://songselect.ccli.com/Songs/{{song.legalOwnerId}}" target="_blank">
|
||||
CCLI Nummer: {{song.legalOwnerId}}
|
||||
<div>Typ: {{ song.type | songType }}</div>
|
||||
<div>Tonart: {{ song.key }}</div>
|
||||
<div>Tempo: {{ song.tempo }}</div>
|
||||
<div>Status: {{ (song.status | status) || "entwurf" }}</div>
|
||||
<div *ngIf="song.legalOwner">
|
||||
Rechteinhaber: {{ song.legalOwner | legalOwner }}
|
||||
</div>
|
||||
<div *ngIf="song.legalOwnerId && song.legalOwner === 'CCLI'">
|
||||
<a
|
||||
href="https://songselect.ccli.com/Songs/{{ song.legalOwnerId }}"
|
||||
target="_blank"
|
||||
>
|
||||
CCLI Nummer: {{ song.legalOwnerId }}
|
||||
</a>
|
||||
</div>
|
||||
<div *ngIf="song.legalOwnerId && song.legalOwner!=='CCLI'">Rechteinhaber ID: {{song.legalOwnerId}}</div>
|
||||
<div *ngIf="song.artist">Künstler: {{song.artist}}</div>
|
||||
<div *ngIf="song.label">Verlag: {{song.label}}</div>
|
||||
<div *ngIf="song.origin">Quelle: {{song.origin}}</div>
|
||||
<div *ngIf="song.origin">Quelle: {{song.origin}}</div>
|
||||
<div *ngIf="song.legalOwnerId && song.legalOwner !== 'CCLI'">
|
||||
Rechteinhaber ID: {{ song.legalOwnerId }}
|
||||
</div>
|
||||
<div *ngIf="song.artist">Künstler: {{ song.artist }}</div>
|
||||
<div *ngIf="song.label">Verlag: {{ song.label }}</div>
|
||||
<div *ngIf="song.origin">Quelle: {{ song.origin }}</div>
|
||||
<div *ngIf="song.origin">Quelle: {{ song.origin }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="text">{{song.text}}</div>-->
|
||||
<app-song-text *ngIf="user$|async as user" [chordMode]="user.chordMode" [showSwitch]="true"
|
||||
[text]="song.text"></app-song-text>
|
||||
<app-song-text
|
||||
*ngIf="user$ | async as user"
|
||||
[chordMode]="user.chordMode"
|
||||
[showSwitch]="true"
|
||||
[text]="song.text"
|
||||
></app-song-text>
|
||||
|
||||
<mat-chip-list *appRole="['leader', 'contributor']" aria-label="Attribute">
|
||||
<mat-chip *ngFor="let flag of getFlags(song.flags)">{{flag}}</mat-chip>
|
||||
<mat-chip-list
|
||||
*appRole="['leader', 'contributor']"
|
||||
aria-label="Attribute"
|
||||
>
|
||||
<mat-chip *ngFor="let flag of getFlags(song.flags)">{{
|
||||
flag
|
||||
}}</mat-chip>
|
||||
</mat-chip-list>
|
||||
|
||||
<div *appRole="['leader', 'contributor']" class="text">{{song.comment}}</div>
|
||||
|
||||
<div *appRole="['leader', 'contributor']" class="text">
|
||||
{{ song.comment }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<app-button-row>
|
||||
<app-button (click)="onDelete(song.id)" *appRole="['admin']" [icon]="faDelete">Löschen</app-button>
|
||||
<app-button *appRole="['contributor']" [icon]="faEdit" routerLink="edit">Bearbeiten</app-button>
|
||||
<app-button
|
||||
(click)="onDelete(song.id)"
|
||||
*appRole="['admin']"
|
||||
[icon]="faDelete"
|
||||
>Löschen
|
||||
</app-button>
|
||||
<app-button *appRole="['contributor']" [icon]="faEdit" routerLink="edit"
|
||||
>Bearbeiten
|
||||
</app-button>
|
||||
</app-button-row>
|
||||
|
||||
</app-card>
|
||||
<ng-container *ngIf="(files$|async) as files">
|
||||
<app-card *ngIf="files.length>0" heading="Anhänge">
|
||||
<p *ngFor="let file of (files$|async)">
|
||||
<ng-container *ngIf="files$ | async as files">
|
||||
<app-card *ngIf="files.length > 0" heading="Anhänge">
|
||||
<p *ngFor="let file of files$ | async">
|
||||
<app-file [file]="file"></app-file>
|
||||
</p>
|
||||
</app-card>
|
||||
|
||||
@@ -9,18 +9,17 @@ describe('SongComponent', () => {
|
||||
let fixture: ComponentFixture<SongComponent>;
|
||||
|
||||
const mockActivatedRoute = {
|
||||
params: of({songId: '4711'})
|
||||
params: of({songId: '4711'}),
|
||||
};
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [SongComponent],
|
||||
providers: [
|
||||
{provide: ActivatedRoute, useValue: mockActivatedRoute}
|
||||
]
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
void TestBed.configureTestingModule({
|
||||
declarations: [SongComponent],
|
||||
providers: [{provide: ActivatedRoute, useValue: mockActivatedRoute}],
|
||||
}).compileComponents();
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SongComponent);
|
||||
@@ -29,7 +28,6 @@ describe('SongComponent', () => {
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
void expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ import {faTrash} from '@fortawesome/free-solid-svg-icons/faTrash';
|
||||
@Component({
|
||||
selector: 'app-song',
|
||||
templateUrl: './song.component.html',
|
||||
styleUrls: ['./song.component.less']
|
||||
styleUrls: ['./song.component.less'],
|
||||
})
|
||||
export class SongComponent implements OnInit {
|
||||
public song$: Observable<Song>;
|
||||
@@ -23,24 +23,18 @@ export class SongComponent implements OnInit {
|
||||
public faEdit = faEdit;
|
||||
public faDelete = faTrash;
|
||||
|
||||
constructor(
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private songService: SongService,
|
||||
private fileService: FileDataService,
|
||||
private userService: UserService,
|
||||
private router: Router,
|
||||
) {
|
||||
public constructor(private activatedRoute: ActivatedRoute, private songService: SongService, private fileService: FileDataService, private userService: UserService, private router: Router) {
|
||||
this.user$ = userService.user$;
|
||||
}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.song$ = this.activatedRoute.params.pipe(
|
||||
map(param => param.songId),
|
||||
map((param: {songId: string}) => param.songId),
|
||||
switchMap(songId => this.songService.read$(songId))
|
||||
);
|
||||
|
||||
this.files$ = this.activatedRoute.params.pipe(
|
||||
map(param => param.songId),
|
||||
map((param: {songId: string}) => param.songId),
|
||||
switchMap(songId => this.fileService.read$(songId))
|
||||
);
|
||||
}
|
||||
@@ -50,7 +44,7 @@ export class SongComponent implements OnInit {
|
||||
return [];
|
||||
}
|
||||
return flags.split(';').filter(_ => !!_);
|
||||
}
|
||||
};
|
||||
|
||||
public async onDelete(songId: string): Promise<void> {
|
||||
await this.songService.delete(songId);
|
||||
|
||||
@@ -14,7 +14,6 @@ import {StatusTranslaterModule} from '../../../widget-modules/pipes/status-trans
|
||||
import {ButtonModule} from '../../../widget-modules/components/button/button.module';
|
||||
import {FileComponent} from './file/file.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [SongComponent, FileComponent],
|
||||
exports: [SongComponent],
|
||||
@@ -32,7 +31,6 @@ import {FileComponent} from './file/file.component';
|
||||
RoleModule,
|
||||
StatusTranslaterModule,
|
||||
ButtonModule,
|
||||
]
|
||||
],
|
||||
})
|
||||
export class SongModule {
|
||||
}
|
||||
export class SongModule {}
|
||||
|
||||
Reference in New Issue
Block a user