diff --git a/src/app/modules/songs/song-list/song-list.component.less b/src/app/modules/songs/song-list/song-list.component.less
index c4c0b3d..ceffc40 100644
--- a/src/app/modules/songs/song-list/song-list.component.less
+++ b/src/app/modules/songs/song-list/song-list.component.less
@@ -31,6 +31,31 @@
text-align: right;
}
+.filter-active {
+ padding: 10px 20px;
+ display: flex;
+ align-items: baseline;
+ gap: 10px;
+ flex-wrap: wrap;
+ color: var(--danger);
+ font-weight: bold;
+}
+
+.filter-reset-link {
+ padding: 0;
+ border: 0;
+ background: transparent;
+ color: var(--link-color);
+ cursor: pointer;
+ font: inherit;
+ font-weight: normal;
+ text-decoration: underline;
+}
+
+.filter-reset-link:hover {
+ color: var(--primary-active);
+}
+
.title {
gap: 6px;
}
diff --git a/src/app/modules/songs/song-list/song-list.component.ts b/src/app/modules/songs/song-list/song-list.component.ts
index bf32da6..cff2c03 100644
--- a/src/app/modules/songs/song-list/song-list.component.ts
+++ b/src/app/modules/songs/song-list/song-list.component.ts
@@ -21,6 +21,11 @@ interface SongListItem extends Song {
hasChordValidationIssues: boolean;
}
+interface SongListViewModel {
+ songs: SongListItem[];
+ filterActive: boolean;
+}
+
@Component({
selector: 'app-songs',
templateUrl: './song-list.component.html',
@@ -37,22 +42,31 @@ export class SongListComponent {
private route = inject(ActivatedRoute);
private textRenderingService = inject(TextRenderingService);
private filterStore = inject(FilterStoreService);
- public songs$: Observable
= combineLatest([
+ public viewModel$: Observable = 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]) => {
- return searchSongs(songs, filter.q)
+ const filteredSongs = searchSongs(songs, filter.q)
.filter(song => this.filter(song, filter))
.map(song => ({
...song,
hasChordValidationIssues: this.textRenderingService.validateChordNotation(song.text ?? '').length > 0,
}));
+
+ return {
+ songs: filteredSongs,
+ filterActive: this.isFilterActive(filter),
+ };
}),
);
public trackBy = (index: number, show: SongListItem) => show.id;
+ public resetFilter(): void {
+ this.filterStore.resetSongFilter();
+ }
+
private filter(song: Song, filter: FilterValues): boolean {
let baseFilter = !filter.type || filter.type === song.type;
baseFilter = baseFilter && (!filter.key || filter.key === song.key);
@@ -62,6 +76,10 @@ export class SongListComponent {
return baseFilter;
}
+ private isFilterActive(filter: FilterValues): boolean {
+ return !!(filter.q || filter.type || filter.key || filter.legalType || filter.flag);
+ }
+
private checkFlag(flag: string, flags: string) {
if (!flags) {
return false;
diff --git a/src/app/widget-modules/components/sidebar/page-frame.component.html b/src/app/widget-modules/components/sidebar/page-frame.component.html
index 9d4e1f8..d30d910 100644
--- a/src/app/widget-modules/components/sidebar/page-frame.component.html
+++ b/src/app/widget-modules/components/sidebar/page-frame.component.html
@@ -7,6 +7,9 @@
class="sidebar-toggle"
mat-icon-button type="button">
+ @if (menuBadge()) {
+
+ }
}
{{ title() }}
diff --git a/src/app/widget-modules/components/sidebar/page-frame.component.less b/src/app/widget-modules/components/sidebar/page-frame.component.less
index e908d47..6bd31ca 100644
--- a/src/app/widget-modules/components/sidebar/page-frame.component.less
+++ b/src/app/widget-modules/components/sidebar/page-frame.component.less
@@ -39,6 +39,17 @@
color: inherit;
}
+.sidebar-toggle-badge {
+ position: absolute;
+ right: 2px;
+ bottom: 3px;
+ width: 9px;
+ height: 9px;
+ border-radius: 50%;
+ background: var(--danger);
+ box-shadow: 0 0 0 1px var(--surface-persist);
+}
+
.sidebar-toggle:hover {
color: var(--icon-button-hover-color);
}
diff --git a/src/app/widget-modules/components/sidebar/page-frame.component.ts b/src/app/widget-modules/components/sidebar/page-frame.component.ts
index 0046738..b662595 100644
--- a/src/app/widget-modules/components/sidebar/page-frame.component.ts
+++ b/src/app/widget-modules/components/sidebar/page-frame.component.ts
@@ -18,6 +18,7 @@ export class PageFrameComponent {
public closedIcon = faBars;
public title = input.required();
public withMenu = input(true);
+ public menuBadge = input(false);
public toggle(): void {
this.collapsed = !this.collapsed;