sidemenu song list
This commit is contained in:
@@ -1,5 +1,15 @@
|
||||
.third {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
column-gap: 20px;
|
||||
.third,
|
||||
:host ::ng-deep form,
|
||||
div[formGroup] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.third {
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
:host ::ng-deep .mat-mdc-form-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -1,43 +1,48 @@
|
||||
@if (songs$ | async; as songs) {
|
||||
<div>
|
||||
<app-list-header [anyFilterActive]="anyFilterActive">
|
||||
<app-sidebar>
|
||||
<div sidebar class="sidebar-content">
|
||||
<app-filter [songs]="songs"></app-filter>
|
||||
</app-list-header>
|
||||
<app-card [padding]="false">
|
||||
@for (song of songs; track trackBy($index, song)) {
|
||||
<div [routerLink]="song.id" class="list-item">
|
||||
<div class="number">{{ song.number }}</div>
|
||||
<div class="title">
|
||||
<span>{{ song.title }}</span>
|
||||
@if (song.hasChordValidationIssues) {
|
||||
<span class="validation-star" title="Akkord-Validierungsfehler vorhanden">*</span>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<ng-container *appRole="['contributor']">
|
||||
@if (song.status === 'draft') {
|
||||
<div class="sidebar-actions">
|
||||
<app-button [icon]="faNewSong" routerLink="new">Neuen Song anlegen</app-button>
|
||||
</div>
|
||||
</div>
|
||||
<div content>
|
||||
<app-card [padding]="false">
|
||||
@for (song of songs; track trackBy($index, song)) {
|
||||
<div [routerLink]="song.id" class="list-item">
|
||||
<div class="number">{{ song.number }}</div>
|
||||
<div class="title">
|
||||
<span>{{ song.title }}</span>
|
||||
@if (song.hasChordValidationIssues) {
|
||||
<span class="validation-star" title="Akkord-Validierungsfehler vorhanden">*</span>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<ng-container *appRole="['contributor']">
|
||||
@if (song.status === 'draft') {
|
||||
<div class="warning">
|
||||
<fa-icon [icon]="faDraft"></fa-icon>
|
||||
</div>
|
||||
} @if (song.status === 'set') {
|
||||
<div class="neutral">
|
||||
<fa-icon [icon]="faDraft"></fa-icon>
|
||||
</div>
|
||||
} @if (song.status === 'final') {
|
||||
<div class="success">
|
||||
<fa-icon [icon]="faFinal"></fa-icon>
|
||||
</div>
|
||||
}
|
||||
</ng-container>
|
||||
@if (song.legalType === 'open') {
|
||||
<div class="warning">
|
||||
<fa-icon [icon]="faDraft"></fa-icon>
|
||||
</div>
|
||||
} @if (song.status === 'set') {
|
||||
<div class="neutral">
|
||||
<fa-icon [icon]="faDraft"></fa-icon>
|
||||
</div>
|
||||
} @if (song.status === 'final') {
|
||||
<div class="success">
|
||||
<fa-icon [icon]="faFinal"></fa-icon>
|
||||
<fa-icon [icon]="faLegal"></fa-icon>
|
||||
</div>
|
||||
}
|
||||
</ng-container>
|
||||
@if (song.legalType === 'open') {
|
||||
<div class="warning">
|
||||
<fa-icon [icon]="faLegal"></fa-icon>
|
||||
</div>
|
||||
}
|
||||
<div>{{ song.key }}</div>
|
||||
</div>
|
||||
<div>{{ song.key }}</div>
|
||||
</div>
|
||||
}
|
||||
</app-card>
|
||||
</div>
|
||||
}
|
||||
</app-card>
|
||||
</div>
|
||||
</app-sidebar>
|
||||
}
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
.sidebar-content {
|
||||
padding: 20px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar-actions {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
padding: 5px 20px;
|
||||
display: grid;
|
||||
|
||||
@@ -6,15 +6,16 @@ import {fade} from '../../../animations';
|
||||
import {ActivatedRoute, RouterLink} from '@angular/router';
|
||||
import {filterSong} from '../../../services/filter.helper';
|
||||
import {FilterValues} from './filter/filter-values';
|
||||
import {faBalanceScaleRight, faCheck, faPencilRuler} from '@fortawesome/free-solid-svg-icons';
|
||||
import {faBalanceScaleRight, faCheck, faPencilRuler, faPlus} from '@fortawesome/free-solid-svg-icons';
|
||||
import {TextRenderingService} from '../services/text-rendering.service';
|
||||
import {FilterStoreService} from '../../../services/filter-store.service';
|
||||
import {AsyncPipe} from '@angular/common';
|
||||
import {ListHeaderComponent} from '../../../widget-modules/components/list-header/list-header.component';
|
||||
import {FilterComponent} from './filter/filter.component';
|
||||
import {CardComponent} from '../../../widget-modules/components/card/card.component';
|
||||
import {RoleDirective} from '../../../services/user/role.directive';
|
||||
import {FaIconComponent} from '@fortawesome/angular-fontawesome';
|
||||
import {SidebarComponent} from '../../../widget-modules/components/sidebar/sidebar.component';
|
||||
import {ButtonComponent} from '../../../widget-modules/components/button/button.component';
|
||||
|
||||
interface SongListItem extends Song {
|
||||
hasChordValidationIssues: boolean;
|
||||
@@ -26,20 +27,21 @@ interface SongListItem extends Song {
|
||||
styleUrls: ['./song-list.component.less'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
animations: [fade],
|
||||
imports: [ListHeaderComponent, FilterComponent, CardComponent, RouterLink, RoleDirective, FaIconComponent, AsyncPipe],
|
||||
imports: [FilterComponent, CardComponent, RouterLink, RoleDirective, FaIconComponent, AsyncPipe, SidebarComponent, ButtonComponent],
|
||||
})
|
||||
export class SongListComponent {
|
||||
public faLegal = faBalanceScaleRight;
|
||||
public faDraft = faPencilRuler;
|
||||
public faFinal = faCheck;
|
||||
public faNewSong = faPlus;
|
||||
private route = inject(ActivatedRoute);
|
||||
private textRenderingService = inject(TextRenderingService);
|
||||
private filterStore = inject(FilterStoreService);
|
||||
|
||||
public anyFilterActive = false;
|
||||
public songs$: Observable<SongListItem[]> = combineLatest([
|
||||
this.filterStore.songFilter$,
|
||||
this.route.data.pipe(map(data => (data['songs'] as Song[]).slice().sort((a, b) => a.number - b.number))),
|
||||
]).pipe(
|
||||
map(([filter, songs]) => {
|
||||
this.anyFilterActive = this.checkIfFilterActive(filter);
|
||||
return songs
|
||||
.filter(song => this.filter(song, filter))
|
||||
.map(song => ({
|
||||
@@ -49,9 +51,6 @@ export class SongListComponent {
|
||||
.sort((a, b) => a.title?.localeCompare(b.title));
|
||||
})
|
||||
);
|
||||
public faLegal = faBalanceScaleRight;
|
||||
public faDraft = faPencilRuler;
|
||||
public faFinal = faCheck;
|
||||
|
||||
public trackBy = (index: number, show: SongListItem) => show.id;
|
||||
|
||||
@@ -65,10 +64,6 @@ export class SongListComponent {
|
||||
return baseFilter;
|
||||
}
|
||||
|
||||
private checkIfFilterActive(filter: FilterValues): boolean {
|
||||
return !!filter.q || !!filter.type || !!filter.key || !!filter.legalType || !!filter.flag;
|
||||
}
|
||||
|
||||
private checkFlag(flag: string, flags: string) {
|
||||
if (!flags) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user