feat(sort): implement sorting functionality for playlists with user-defined options

This commit is contained in:
4gray committed 2025-03-01 22:27:50 +01:00
1 parent 6b9e021d74
commit 996cb30f4c
7 files changed
+256 -28

No files matched your search

@@ -16,20 +16,22 @@
>
<mat-icon>add</mat-icon>
</button>
<!-- <button
mat-icon-button
[matTooltip]="'HOME.FILTER_BY_NAME' | translate"
data-test-id="filter-playlist-by-name"
>
<mat-icon>search</mat-icon>
</button> -->
<!-- Sort button -->
<button
mat-icon-button
[matMenuTriggerFor]="sortMenu"
[matTooltip]="'HOME.SORT_PLAYLISTS' | translate"
data-test-id="sort-playlists"
>
<mat-icon>sort</mat-icon>
</button>
<button
mat-icon-button
[matMenuTriggerFor]="filterPlaylistMenu"
[matTooltip]="'HOME.FILTER_BY_TYPE' | translate"
data-test-id="filter-playlist-by-type"
>
<mat-icon>filter_list</mat-icon>
<mat-icon>filter_alt</mat-icon>
</button>
<button
*ngIf="isElectron || isTauri; else pwaMenu"
@@ -41,12 +43,84 @@
<mat-icon>settings</mat-icon>
</button>
<!-- Sort menu -->
<mat-menu #sortMenu="matMenu">
<div
class="dropdown-menu-header"
(click)="$event.stopPropagation()"
>
{{ 'HOME.SORT_BY' | translate }}
</div>
<button
mat-menu-item
(click)="setSortOptions(SortBy.NAME, SortOrder.ASC)"
[class.active-sort]="isSortActive(SortBy.NAME, SortOrder.ASC)"
>
<mat-icon>sort_by_alpha</mat-icon>
<span>{{ 'HOME.SORT_OPTIONS.NAME_ASC' | translate }}</span>
<mat-icon
*ngIf="isSortActive(SortBy.NAME, SortOrder.ASC)"
class="check-icon"
>check</mat-icon
>
</button>
<button
mat-menu-item
(click)="setSortOptions(SortBy.NAME, SortOrder.DESC)"
[class.active-sort]="isSortActive(SortBy.NAME, SortOrder.DESC)"
>
<mat-icon>sort_by_alpha</mat-icon>
<span>{{ 'HOME.SORT_OPTIONS.NAME_DESC' | translate }}</span>
<mat-icon
*ngIf="isSortActive(SortBy.NAME, SortOrder.DESC)"
class="check-icon"
>check</mat-icon
>
</button>
<mat-divider></mat-divider>
<button
mat-menu-item
(click)="setSortOptions(SortBy.DATE_ADDED, SortOrder.DESC)"
[class.active-sort]="
isSortActive(SortBy.DATE_ADDED, SortOrder.DESC)
"
>
<mat-icon>date_range</mat-icon>
<span>{{ 'HOME.SORT_OPTIONS.NEWEST' | translate }}</span>
<mat-icon
*ngIf="isSortActive(SortBy.DATE_ADDED, SortOrder.DESC)"
class="check-icon"
>check</mat-icon
>
</button>
<button
mat-menu-item
(click)="setSortOptions(SortBy.DATE_ADDED, SortOrder.ASC)"
[class.active-sort]="
isSortActive(SortBy.DATE_ADDED, SortOrder.ASC)
"
>
<mat-icon>date_range</mat-icon>
<span>{{ 'HOME.SORT_OPTIONS.OLDEST' | translate }}</span>
<mat-icon
*ngIf="isSortActive(SortBy.DATE_ADDED, SortOrder.ASC)"
class="check-icon"
>check</mat-icon
>
</button>
</mat-menu>
<mat-menu #filterPlaylistMenu="matMenu">
<section
(click)="$event.stopPropagation()"
class="filter-container"
>
<h4>{{ 'HOME.FILTER_BY_TYPE' | translate }}:</h4>
<div
class="dropdown-menu-header"
(click)="$event.stopPropagation()"
>
{{ 'HOME.FILTER_BY_TYPE' | translate }}
</div>
@for (type of playlistTypes; track $index) {
<p>
<mat-checkbox
@@ -50,6 +50,21 @@
color: #fff;
}
.dropdown-menu-header {
padding: 0 16px;
margin: 8px 0;
font-size: 12px;
font-weight: 500;
}
.active-sort {
background-color: rgba(0, 0, 0, 0.04);
}
.check-icon {
margin-left: 8px;
}
@media (max-width: 599px) {
.subtitle {
display: none;
@@ -16,6 +16,7 @@ import { open } from '@tauri-apps/plugin-shell';
import { NgxWhatsNewModule } from 'ngx-whats-new';
import { HomeComponent } from '../../../home/home.component';
import { DataService } from '../../../services/data.service';
import { SortBy, SortOrder, SortService } from '../../../services/sort.service';
import { WhatsNewService } from '../../../services/whats-new.service';
import { setSelectedFilters } from '../../../state/actions';
import { selectActiveTypeFilters } from '../../../state/selectors';
@@ -91,13 +92,18 @@ export class HeaderComponent implements OnInit {
selectedTypeFilters = this.store.selectSignal(selectActiveTypeFilters);
SortBy = SortBy;
SortOrder = SortOrder;
currentSortOptions: { by: SortBy; order: SortOrder };
constructor(
private activatedRoute: ActivatedRoute,
private dialog: MatDialog,
private dataService: DataService,
private router: Router,
private store: Store,
private whatsNewService: WhatsNewService
private whatsNewService: WhatsNewService,
private sortService: SortService
) {
effect(() => {
if (this.selectedTypeFilters) {
@@ -107,6 +113,10 @@ export class HeaderComponent implements OnInit {
});
}
});
this.sortService.getSortOptions().subscribe((options) => {
this.currentSortOptions = options;
});
}
ngOnInit() {
@@ -174,4 +184,15 @@ export class HeaderComponent implements OnInit {
})
);
}
setSortOptions(by: SortBy, order: SortOrder): void {
this.sortService.setSortOptions({ by, order });
}
isSortActive(by: SortBy, order: SortOrder): boolean {
return (
this.currentSortOptions?.by === by &&
this.currentSortOptions?.order === order
);
}
}