mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
Adding grouping selector UI
This commit is contained in:
parent
0a1fb29c9f
commit
3f35c35a13
@ -1,4 +1,4 @@
|
||||
import {SortingMethods} from './entities/SortingMethods';
|
||||
import {SortingByTypes, SortingMethod} from './entities/SortingMethods';
|
||||
|
||||
/**
|
||||
* This contains the action of the supported list of *.pg2conf files.
|
||||
@ -6,15 +6,15 @@ import {SortingMethods} from './entities/SortingMethods';
|
||||
*/
|
||||
export const PG2ConfMap = {
|
||||
sorting: {
|
||||
'.order_descending_name.pg2conf': SortingMethods.descName,
|
||||
'.order_ascending_name.pg2conf': SortingMethods.ascName,
|
||||
'.order_descending_date.pg2conf': SortingMethods.descDate,
|
||||
'.order_ascending_date.pg2conf': SortingMethods.ascDate,
|
||||
'.order_descending_rating.pg2conf': SortingMethods.descRating,
|
||||
'.order_ascending_rating.pg2conf': SortingMethods.ascRating,
|
||||
'.order_random.pg2conf': SortingMethods.random,
|
||||
'.order_descending_person_count.pg2conf': SortingMethods.descPersonCount,
|
||||
'.order_ascending_person_count.pg2conf': SortingMethods.descPersonCount,
|
||||
'.order_descending_name.pg2conf': {method: SortingByTypes.Name, ascending: false} as SortingMethod,
|
||||
'.order_ascending_name.pg2conf': {method: SortingByTypes.Name, ascending: true} as SortingMethod,
|
||||
'.order_descending_date.pg2conf': {method: SortingByTypes.Date, ascending: false} as SortingMethod,
|
||||
'.order_ascending_date.pg2conf': {method: SortingByTypes.Date, ascending: true} as SortingMethod,
|
||||
'.order_descending_rating.pg2conf': {method: SortingByTypes.Rating, ascending: false} as SortingMethod,
|
||||
'.order_ascending_rating.pg2conf': {method: SortingByTypes.Rating, ascending: true} as SortingMethod,
|
||||
'.order_random.pg2conf': {method: SortingByTypes.Rating, ascending: null} as SortingMethod,
|
||||
'.order_descending_person_count.pg2conf': {method: SortingByTypes.PersonCount, ascending: false} as SortingMethod,
|
||||
'.order_ascending_person_count.pg2conf': {method: SortingByTypes.PersonCount, ascending: true} as SortingMethod,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -18,6 +18,7 @@ import {
|
||||
ClientPhotoConvertingConfig,
|
||||
ClientServiceConfig,
|
||||
ClientSharingConfig,
|
||||
ClientSortingConfig,
|
||||
ClientThumbnailConfig,
|
||||
ClientUserConfig,
|
||||
ClientVideoConfig,
|
||||
@ -28,7 +29,7 @@ import {SubConfigClass} from 'typeconfig/src/decorators/class/SubConfigClass';
|
||||
import {ConfigProperty} from 'typeconfig/src/decorators/property/ConfigPropoerty';
|
||||
import {DefaultsJobs} from '../../entities/job/JobDTO';
|
||||
import {SearchQueryDTO, SearchQueryTypes, TextSearch,} from '../../entities/SearchQueryDTO';
|
||||
import {SortingMethods} from '../../entities/SortingMethods';
|
||||
import {SortingByTypes} from '../../entities/SortingMethods';
|
||||
import {UserRoles} from '../../entities/UserDTO';
|
||||
import {MediaPickDTO} from '../../entities/MediaPickDTO';
|
||||
import {MessagingConfig} from './MessagingConfig';
|
||||
@ -888,7 +889,7 @@ export class ServerAlbumCoverConfig {
|
||||
text: '',
|
||||
} as TextSearch;
|
||||
@ConfigProperty({
|
||||
arrayType: SortingMethods,
|
||||
arrayType: ClientSortingConfig,
|
||||
tags: {
|
||||
name: $localize`Cover Sorting`,
|
||||
uiResetNeeded: {db: true},
|
||||
@ -896,10 +897,10 @@ export class ServerAlbumCoverConfig {
|
||||
},
|
||||
description: $localize`If multiple cover is available sorts them by these methods and selects the first one.`,
|
||||
})
|
||||
Sorting: SortingMethods[] = [
|
||||
SortingMethods.descRating,
|
||||
SortingMethods.descDate,
|
||||
SortingMethods.descPersonCount,
|
||||
Sorting: ClientSortingConfig[] = [
|
||||
new ClientSortingConfig(SortingByTypes.Rating, false),
|
||||
new ClientSortingConfig(SortingByTypes.Date, false),
|
||||
new ClientSortingConfig(SortingByTypes.PersonCount, false)
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-inferrable-types */
|
||||
import 'reflect-metadata';
|
||||
import {SortingMethods} from '../../entities/SortingMethods';
|
||||
import {SortingByTypes, SortingMethod} from '../../entities/SortingMethods';
|
||||
import {UserRoles} from '../../entities/UserDTO';
|
||||
import {ConfigProperty, SubConfigClass} from 'typeconfig/common';
|
||||
import {SearchQueryDTO} from '../../entities/SearchQueryDTO';
|
||||
@ -519,7 +519,7 @@ export class ClientMapConfig {
|
||||
arrayType: MapPathGroupConfig,
|
||||
tags: {
|
||||
name: $localize`Path theme groups`,
|
||||
githubIssue:647,
|
||||
githubIssue: 647,
|
||||
priority: ConfigPriority.underTheHood
|
||||
} as TAGS,
|
||||
description: $localize`Markers are grouped and themed by these settings`,
|
||||
@ -880,6 +880,30 @@ export class ThemesConfig {
|
||||
)];
|
||||
}
|
||||
|
||||
@SubConfigClass<TAGS>({tags: {client: true}, softReadonly: true})
|
||||
export class ClientSortingConfig implements SortingMethod {
|
||||
|
||||
|
||||
constructor(method: SortingByTypes = SortingByTypes.Date, ascending: boolean = true) {
|
||||
this.method = method;
|
||||
this.ascending = ascending;
|
||||
}
|
||||
|
||||
@ConfigProperty({
|
||||
type: SortingByTypes,
|
||||
tags: {
|
||||
name: $localize`Method`,
|
||||
},
|
||||
})
|
||||
method: SortingByTypes = SortingByTypes.Date;
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Ascending`,
|
||||
},
|
||||
})
|
||||
ascending: boolean = true;
|
||||
}
|
||||
|
||||
@SubConfigClass<TAGS>({tags: {client: true}, softReadonly: true})
|
||||
export class ClientGalleryConfig {
|
||||
@ -901,22 +925,24 @@ export class ClientGalleryConfig {
|
||||
enableOnScrollRendering: boolean = true;
|
||||
|
||||
@ConfigProperty({
|
||||
type: SortingMethods, tags: {
|
||||
type: ClientSortingConfig,
|
||||
tags: {
|
||||
name: $localize`Default sorting`,
|
||||
priority: ConfigPriority.advanced,
|
||||
},
|
||||
description: $localize`Default sorting method for photo and video in a directory results.`
|
||||
})
|
||||
defaultPhotoSortingMethod: SortingMethods = SortingMethods.ascDate;
|
||||
defaultPhotoSortingMethod: ClientSortingConfig = new ClientSortingConfig(SortingByTypes.Date, true);
|
||||
|
||||
@ConfigProperty({
|
||||
type: SortingMethods, tags: {
|
||||
type: ClientSortingConfig,
|
||||
tags: {
|
||||
name: $localize`Default search sorting`,
|
||||
priority: ConfigPriority.advanced,
|
||||
},
|
||||
description: $localize`Default sorting method for photo and video in a search results.`
|
||||
})
|
||||
defaultSearchSortingMethod: SortingMethods = SortingMethods.descDate;
|
||||
defaultSearchSortingMethod: ClientSortingConfig = new ClientSortingConfig(SortingByTypes.Date, false);
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import {SearchQueryDTO} from './SearchQueryDTO';
|
||||
import {SortingMethods} from './SortingMethods';
|
||||
import {SortingMethod} from './SortingMethods';
|
||||
|
||||
export interface MediaPickDTO {
|
||||
searchQuery: SearchQueryDTO;
|
||||
sortBy: SortingMethods[];
|
||||
sortBy: SortingMethod[];
|
||||
pick: number;
|
||||
}
|
||||
|
@ -2,14 +2,15 @@
|
||||
* Order of these enums determines the order in the UI.
|
||||
* Keep spaces between the values, so new value can be added in between without changing the existing ones
|
||||
*/
|
||||
export enum SortingMethods {
|
||||
ascName = 10,
|
||||
descName = 11,
|
||||
ascDate = 20,
|
||||
descDate = 21,
|
||||
ascRating = 30,
|
||||
descRating = 31,
|
||||
ascPersonCount = 40,
|
||||
descPersonCount = 41,
|
||||
export enum SortingByTypes {
|
||||
Name = 10,
|
||||
Date = 20,
|
||||
Rating = 30,
|
||||
PersonCount = 40,
|
||||
random = 100 // let's keep random as the last in the UI
|
||||
}
|
||||
|
||||
export interface SortingMethod {
|
||||
method: SortingByTypes;
|
||||
ascending: boolean;
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { SortingMethods } from '../../../common/entities/SortingMethods';
|
||||
import {Pipe, PipeTransform} from '@angular/core';
|
||||
import {SortingByTypes} from '../../../common/entities/SortingMethods';
|
||||
import {EnumTranslations} from '../ui/EnumTranslations';
|
||||
|
||||
@Pipe({ name: 'stringifySorting' })
|
||||
@Pipe({name: 'stringifySorting'})
|
||||
export class StringifySortingMethod implements PipeTransform {
|
||||
|
||||
transform(method: SortingMethods): string {
|
||||
return EnumTranslations[SortingMethods[method]];
|
||||
transform(method: SortingByTypes): string {
|
||||
return EnumTranslations[SortingByTypes[method]];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {UserRoles} from '../../../common/entities/UserDTO';
|
||||
import {ConfigPriority, MapProviders, NavigationLinkTypes, ScrollUpModes} from '../../../common/config/public/ClientConfig';
|
||||
import {ReIndexingSensitivity} from '../../../common/config/private/PrivateConfig';
|
||||
import {SortingMethods} from '../../../common/entities/SortingMethods';
|
||||
import {SearchQueryTypes} from '../../../common/entities/SearchQueryDTO';
|
||||
import {ConfigStyle} from './settings/settings.service';
|
||||
import {SortingByTypes} from '../../../common/entities/SortingMethods';
|
||||
|
||||
export const EnumTranslations: Record<string, string> = {};
|
||||
export const enumToTranslatedArray = (EnumType: any): { key: number; value: string }[] => {
|
||||
@ -44,15 +44,11 @@ EnumTranslations[ReIndexingSensitivity[ReIndexingSensitivity.high]] = $localize`
|
||||
EnumTranslations[ReIndexingSensitivity[ReIndexingSensitivity.medium]] = $localize`medium`;
|
||||
|
||||
|
||||
EnumTranslations[SortingMethods[SortingMethods.descDate]] = $localize`descending date`;
|
||||
EnumTranslations[SortingMethods[SortingMethods.ascDate]] = $localize`ascending date`;
|
||||
EnumTranslations[SortingMethods[SortingMethods.descName]] = $localize`descending name`;
|
||||
EnumTranslations[SortingMethods[SortingMethods.ascName]] = $localize`ascending name`;
|
||||
EnumTranslations[SortingMethods[SortingMethods.descRating]] = $localize`descending rating`;
|
||||
EnumTranslations[SortingMethods[SortingMethods.ascRating]] = $localize`ascending rating`;
|
||||
EnumTranslations[SortingMethods[SortingMethods.random]] = $localize`random`;
|
||||
EnumTranslations[SortingMethods[SortingMethods.ascPersonCount]] = $localize`ascending persons`;
|
||||
EnumTranslations[SortingMethods[SortingMethods.descPersonCount]] = $localize`descending persons`;
|
||||
EnumTranslations[SortingByTypes[SortingByTypes.Date]] = $localize`date`;
|
||||
EnumTranslations[SortingByTypes[SortingByTypes.Name]] = $localize`name`;
|
||||
EnumTranslations[SortingByTypes[SortingByTypes.Rating]] = $localize`rating`;
|
||||
EnumTranslations[SortingByTypes[SortingByTypes.random]] = $localize`random`;
|
||||
EnumTranslations[SortingByTypes[SortingByTypes.PersonCount]] = $localize`persons`;
|
||||
|
||||
|
||||
EnumTranslations[NavigationLinkTypes[NavigationLinkTypes.url]] = $localize`Url`;
|
||||
|
@ -1,16 +1,15 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {DirectoryPathDTO, ParentDirectoryDTO,} from '../../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO,} from '../../../../common/entities/DirectoryDTO';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {IAutoCompleteItem} from '../../../../common/entities/AutoCompleteItem';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
||||
import {SortingMethod} from '../../../../common/entities/SortingMethods';
|
||||
import {VersionService} from '../../model/version.service';
|
||||
import {SearchQueryDTO, SearchQueryTypes,} from '../../../../common/entities/SearchQueryDTO';
|
||||
import {ContentWrapper} from '../../../../common/entities/ConentWrapper';
|
||||
import {ContentWrapperWithError} from './content.service';
|
||||
import {ThemeModes} from '../../../../common/config/public/ClientConfig';
|
||||
import {SearchResultDTO} from '../../../../common/entities/SearchResultDTO';
|
||||
|
||||
interface CacheItem<T> {
|
||||
timestamp: number;
|
||||
@ -97,7 +96,7 @@ export class GalleryCacheService {
|
||||
}
|
||||
}
|
||||
|
||||
public getSorting(cw: ContentWrapper): SortingMethods {
|
||||
public getSorting(cw: ContentWrapper): SortingMethod {
|
||||
let key = GalleryCacheService.SORTING_PREFIX;
|
||||
if (cw?.searchResult?.searchQuery) {
|
||||
key += JSON.stringify(cw.searchResult.searchQuery);
|
||||
@ -106,7 +105,7 @@ export class GalleryCacheService {
|
||||
}
|
||||
const tmp = localStorage.getItem(key);
|
||||
if (tmp != null) {
|
||||
return parseInt(tmp, 10);
|
||||
return JSON.parse(tmp);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -128,8 +127,8 @@ export class GalleryCacheService {
|
||||
|
||||
public setSorting(
|
||||
cw: ContentWrapper,
|
||||
sorting: SortingMethods
|
||||
): SortingMethods {
|
||||
sorting: SortingMethod
|
||||
): void {
|
||||
try {
|
||||
let key = GalleryCacheService.SORTING_PREFIX;
|
||||
if (cw?.searchResult?.searchQuery) {
|
||||
@ -137,12 +136,11 @@ export class GalleryCacheService {
|
||||
} else {
|
||||
key += cw?.directory?.path + '/' + cw?.directory?.name;
|
||||
}
|
||||
localStorage.setItem(key, sorting.toString());
|
||||
localStorage.setItem(key, JSON.stringify(sorting));
|
||||
} catch (e) {
|
||||
this.reset();
|
||||
console.error(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public getAutoComplete(
|
||||
|
@ -59,35 +59,77 @@
|
||||
[class.btn-secondary]="sortingService.sorting.value !== DefaultSorting"
|
||||
[class.btn-outline-secondary]="sortingService.sorting.value == DefaultSorting"
|
||||
aria-controls="sorting-dropdown">
|
||||
<app-sorting-method-icon [method]="sortingService.sorting.value"></app-sorting-method-icon>
|
||||
<ng-icon
|
||||
[name]="sortingService.sorting.value.ascending ? 'ionArrowDownOutline' : 'ionArrowUpOutline'"></ng-icon>
|
||||
<app-sorting-method-icon [method]="sortingService.sorting.value.method"></app-sorting-method-icon>
|
||||
</button>
|
||||
<div id="sorting-dropdown" *dropdownMenu class="dropdown-menu dropdown-menu-right"
|
||||
role="menu" aria-labelledby="button-alignment">
|
||||
<div class="row flex-nowrap">
|
||||
<div class="col-6">
|
||||
Sorting
|
||||
<div class="col-6 p-1 border-end">
|
||||
<span class="ps-2">Sorting</span>
|
||||
<div class="row">
|
||||
<div class="dropdown-item sorting-grouping-item" role="menuitem"
|
||||
*ngFor="let type of sortingMethodsType"
|
||||
(click)="setSorting(type.key)">
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.sorting.value.method == type.key"
|
||||
*ngFor="let type of sortingByTypes"
|
||||
(click)="setSortingBy(type.key)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<app-sorting-method-icon [method]="type.key"></app-sorting-method-icon>
|
||||
</div>
|
||||
<div class="d-inline-block">{{type.key | stringifySorting}}</div>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.sorting.value.ascending == true"
|
||||
(click)="setSortingAscending(true)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<ng-icon name="">ionArrowUpOutline</ng-icon>
|
||||
</div>
|
||||
<div class="d-inline-block" i18n>ascending</div>
|
||||
</div>
|
||||
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.sorting.value.ascending == false"
|
||||
(click)="setSortingAscending(false)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<ng-icon name="ionArrowDownOutline"></ng-icon>
|
||||
</div>
|
||||
<div class="d-inline-block" i18n>descending</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
Grouping
|
||||
<div class="col-6 p-1">
|
||||
<span class="ps-2">Grouping</span>
|
||||
<div class="row">
|
||||
<div class="dropdown-item sorting-grouping-item" role="menuitem"
|
||||
*ngFor="let type of sortingMethodsType"
|
||||
(click)="setGrouping(type.key)">
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.grouping.value.method == type.key"
|
||||
*ngFor="let type of sortingByTypes"
|
||||
(click)="setGroupingBy(type.key)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<app-sorting-method-icon [method]="type.key"></app-sorting-method-icon>
|
||||
</div>
|
||||
<div class="d-inline-block">{{type.key | stringifySorting}}</div>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.grouping.value.ascending == true"
|
||||
(click)="setGroupingAscending(true)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<ng-icon name="ionArrowUpOutline"></ng-icon>
|
||||
</div>
|
||||
<div class="d-inline-block" i18n>ascending</div>
|
||||
</div>
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.grouping.value.ascending == false"
|
||||
(click)="setGroupingAscending(false)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<ng-icon name="ionArrowDownOutline"></ng-icon>
|
||||
</div>
|
||||
<div class="d-inline-block" i18n>descending</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@ import {AuthenticationService} from '../../../model/network/authentication.servi
|
||||
import {QueryService} from '../../../model/query.service';
|
||||
import {ContentService, ContentWrapperWithError, DirectoryContent,} from '../content.service';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {SortingMethods} from '../../../../../common/entities/SortingMethods';
|
||||
import {SortingByTypes, SortingMethod} from '../../../../../common/entities/SortingMethods';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {SearchQueryTypes, TextSearch, TextSearchQueryMatchTypes,} from '../../../../../common/entities/SearchQueryDTO';
|
||||
import {Observable} from 'rxjs';
|
||||
@ -23,8 +23,8 @@ import {FilterService} from '../filter/filter.service';
|
||||
providers: [RouterLink],
|
||||
})
|
||||
export class GalleryNavigatorComponent {
|
||||
public SortingMethods = SortingMethods;
|
||||
public sortingMethodsType: { key: number; value: string }[] = [];
|
||||
public SortingByTypes = SortingByTypes;
|
||||
public sortingByTypes: { key: number; value: string }[] = [];
|
||||
public readonly config = Config;
|
||||
// DefaultSorting = Config.Gallery.defaultPhotoSortingMethod;
|
||||
public readonly SearchQueryTypes = SearchQueryTypes;
|
||||
@ -52,7 +52,7 @@ export class GalleryNavigatorComponent {
|
||||
private router: Router,
|
||||
public sanitizer: DomSanitizer
|
||||
) {
|
||||
this.sortingMethodsType = Utils.enumToArray(SortingMethods);
|
||||
this.sortingByTypes = Utils.enumToArray(SortingByTypes);
|
||||
this.RootFolderName = $localize`Home`;
|
||||
this.wrappedContent = this.galleryService.content;
|
||||
this.directoryContent = this.wrappedContent.pipe(
|
||||
@ -137,20 +137,35 @@ export class GalleryNavigatorComponent {
|
||||
: 0;
|
||||
}
|
||||
|
||||
get DefaultSorting(): SortingMethods {
|
||||
get DefaultSorting(): SortingMethod {
|
||||
return this.sortingService.getDefaultSorting(
|
||||
this.galleryService.content.value
|
||||
);
|
||||
}
|
||||
|
||||
setSorting(sorting: SortingMethods): void {
|
||||
this.sortingService.setSorting(sorting);
|
||||
this.sortingService.setGrouping(sorting);
|
||||
setSortingBy(sorting: SortingByTypes): void {
|
||||
const s = {method: sorting, ascending: this.sortingService.sorting.value.ascending};
|
||||
this.sortingService.setSorting(s);
|
||||
this.sortingService.setGrouping(s);
|
||||
}
|
||||
setGrouping(grouping: SortingMethods): void {
|
||||
this.sortingService.setGrouping(grouping);
|
||||
|
||||
setSortingAscending(asc: boolean) {
|
||||
const s = {method: this.sortingService.sorting.value.method, ascending: asc};
|
||||
this.sortingService.setSorting(s);
|
||||
this.sortingService.setGrouping(s);
|
||||
}
|
||||
|
||||
setGroupingBy(grouping: SortingByTypes): void {
|
||||
const s = {method: grouping, ascending: this.sortingService.grouping.value.ascending};
|
||||
this.sortingService.setGrouping(s);
|
||||
}
|
||||
|
||||
setGroupingAscending(asc: boolean) {
|
||||
const s = {method: this.sortingService.grouping.value.method, ascending: asc};
|
||||
this.sortingService.setGrouping(s);
|
||||
}
|
||||
|
||||
|
||||
getDownloadZipLink(): string {
|
||||
const c = this.galleryService.content.value;
|
||||
if (!c.directory) {
|
||||
|
@ -4,7 +4,7 @@ import {NetworkService} from '../../../model/network/network.service';
|
||||
import {GalleryCacheService} from '../cache.gallery.service';
|
||||
import {BehaviorSubject, Observable} from 'rxjs';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {SortingMethods} from '../../../../../common/entities/SortingMethods';
|
||||
import {SortingByTypes, SortingMethod} from '../../../../../common/entities/SortingMethods';
|
||||
import {PG2ConfMap} from '../../../../../common/PG2ConfMap';
|
||||
import {ContentService, DirectoryContent} from '../content.service';
|
||||
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
|
||||
@ -17,8 +17,8 @@ import {FileDTO} from '../../../../../common/entities/FileDTO';
|
||||
|
||||
@Injectable()
|
||||
export class GallerySortingService {
|
||||
public sorting: BehaviorSubject<SortingMethods>;
|
||||
public grouping: BehaviorSubject<SortingMethods>;
|
||||
public sorting: BehaviorSubject<SortingMethod>;
|
||||
public grouping: BehaviorSubject<SortingMethod>;
|
||||
private collator = new Intl.Collator(undefined, {numeric: true});
|
||||
|
||||
constructor(
|
||||
@ -28,11 +28,11 @@ export class GallerySortingService {
|
||||
private rndService: SeededRandomService,
|
||||
private datePipe: DatePipe
|
||||
) {
|
||||
this.sorting = new BehaviorSubject<SortingMethods>(
|
||||
Config.Gallery.defaultPhotoSortingMethod
|
||||
this.sorting = new BehaviorSubject(
|
||||
{method: Config.Gallery.defaultPhotoSortingMethod.method, ascending: Config.Gallery.defaultPhotoSortingMethod.ascending}
|
||||
);
|
||||
this.grouping = new BehaviorSubject<SortingMethods>(
|
||||
SortingMethods.ascDate // TODO: move to config
|
||||
this.grouping = new BehaviorSubject(
|
||||
{method: Config.Gallery.defaultPhotoSortingMethod.method, ascending: Config.Gallery.defaultPhotoSortingMethod.ascending}
|
||||
);
|
||||
this.galleryService.content.subscribe((c) => {
|
||||
if (c) {
|
||||
@ -46,7 +46,7 @@ export class GallerySortingService {
|
||||
});
|
||||
}
|
||||
|
||||
getDefaultSorting(cw: ContentWrapper): SortingMethods {
|
||||
getDefaultSorting(cw: ContentWrapper): SortingMethod {
|
||||
if (cw.directory && cw.directory.metaFile) {
|
||||
for (const file in PG2ConfMap.sorting) {
|
||||
if (cw.directory.metaFile.some((f) => f.name === file)) {
|
||||
@ -60,7 +60,7 @@ export class GallerySortingService {
|
||||
return Config.Gallery.defaultPhotoSortingMethod;
|
||||
}
|
||||
|
||||
setSorting(sorting: SortingMethods): void {
|
||||
setSorting(sorting: SortingMethod): void {
|
||||
this.sorting.next(sorting);
|
||||
if (this.galleryService.content.value) {
|
||||
if (
|
||||
@ -79,60 +79,39 @@ export class GallerySortingService {
|
||||
}
|
||||
}
|
||||
|
||||
setGrouping(grouping: SortingMethods): void {
|
||||
setGrouping(grouping: SortingMethod): void {
|
||||
this.grouping.next(grouping);
|
||||
}
|
||||
|
||||
private sortMedia(sorting: SortingMethods, media: MediaDTO[]): void {
|
||||
private sortMedia(sorting: SortingMethod, media: MediaDTO[]): void {
|
||||
if (!media) {
|
||||
return;
|
||||
}
|
||||
switch (sorting) {
|
||||
case SortingMethods.ascName:
|
||||
switch (sorting.method) {
|
||||
case SortingByTypes.Name:
|
||||
media.sort((a: PhotoDTO, b: PhotoDTO) =>
|
||||
this.collator.compare(a.name, b.name)
|
||||
);
|
||||
break;
|
||||
case SortingMethods.descName:
|
||||
media.sort((a: PhotoDTO, b: PhotoDTO) =>
|
||||
this.collator.compare(b.name, a.name)
|
||||
);
|
||||
break;
|
||||
case SortingMethods.ascDate:
|
||||
case SortingByTypes.Date:
|
||||
media.sort((a: PhotoDTO, b: PhotoDTO): number => {
|
||||
return a.metadata.creationDate - b.metadata.creationDate;
|
||||
});
|
||||
break;
|
||||
case SortingMethods.descDate:
|
||||
media.sort((a: PhotoDTO, b: PhotoDTO): number => {
|
||||
return b.metadata.creationDate - a.metadata.creationDate;
|
||||
});
|
||||
break;
|
||||
case SortingMethods.ascRating:
|
||||
case SortingByTypes.Rating:
|
||||
media.sort(
|
||||
(a: PhotoDTO, b: PhotoDTO) =>
|
||||
(a.metadata.rating || 0) - (b.metadata.rating || 0)
|
||||
);
|
||||
break;
|
||||
case SortingMethods.descRating:
|
||||
media.sort(
|
||||
(a: PhotoDTO, b: PhotoDTO) =>
|
||||
(b.metadata.rating || 0) - (a.metadata.rating || 0)
|
||||
);
|
||||
break;
|
||||
case SortingMethods.ascPersonCount:
|
||||
case SortingByTypes.PersonCount:
|
||||
media.sort(
|
||||
(a: PhotoDTO, b: PhotoDTO) =>
|
||||
(a.metadata?.faces?.length || 0) - (b.metadata?.faces?.length || 0)
|
||||
);
|
||||
break;
|
||||
case SortingMethods.descPersonCount:
|
||||
media.sort(
|
||||
(a: PhotoDTO, b: PhotoDTO) =>
|
||||
(b.metadata?.faces?.length || 0) - (a.metadata?.faces?.length || 0)
|
||||
);
|
||||
break;
|
||||
case SortingMethods.random:
|
||||
case SortingByTypes.random:
|
||||
this.rndService.setSeed(media.length);
|
||||
media.sort((a: PhotoDTO, b: PhotoDTO): number => {
|
||||
if (a.name.toLowerCase() < b.name.toLowerCase()) {
|
||||
@ -148,6 +127,9 @@ export class GallerySortingService {
|
||||
});
|
||||
break;
|
||||
}
|
||||
if (!sorting.ascending) {
|
||||
media.reverse();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -169,14 +151,14 @@ export class GallerySortingService {
|
||||
metaFile: dirContent.metaFile,
|
||||
};
|
||||
if (c.directories) {
|
||||
switch (sorting) {
|
||||
case SortingMethods.ascRating: // directories do not have rating
|
||||
case SortingMethods.ascName:
|
||||
switch (sorting.method) {
|
||||
case SortingByTypes.Rating: // directories do not have rating
|
||||
case SortingByTypes.Name:
|
||||
c.directories.sort((a, b) =>
|
||||
this.collator.compare(a.name, b.name)
|
||||
);
|
||||
break;
|
||||
case SortingMethods.ascDate:
|
||||
case SortingByTypes.Date:
|
||||
if (
|
||||
Config.Gallery.enableDirectorySortingByDate === true
|
||||
) {
|
||||
@ -189,26 +171,7 @@ export class GallerySortingService {
|
||||
this.collator.compare(a.name, b.name)
|
||||
);
|
||||
break;
|
||||
case SortingMethods.descRating: // directories do not have rating
|
||||
case SortingMethods.descName:
|
||||
c.directories.sort((a, b) =>
|
||||
this.collator.compare(b.name, a.name)
|
||||
);
|
||||
break;
|
||||
case SortingMethods.descDate:
|
||||
if (
|
||||
Config.Gallery.enableDirectorySortingByDate === true
|
||||
) {
|
||||
c.directories.sort(
|
||||
(a, b) => b.lastModified - a.lastModified
|
||||
);
|
||||
break;
|
||||
}
|
||||
c.directories.sort((a, b) =>
|
||||
this.collator.compare(b.name, a.name)
|
||||
);
|
||||
break;
|
||||
case SortingMethods.random:
|
||||
case SortingByTypes.random:
|
||||
this.rndService.setSeed(c.directories.length);
|
||||
c.directories
|
||||
.sort((a, b): number => {
|
||||
@ -225,6 +188,10 @@ export class GallerySortingService {
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
if (!sorting.ascending) {
|
||||
c.directories.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
// group
|
||||
@ -232,21 +199,17 @@ export class GallerySortingService {
|
||||
const mCopy = dirContent.media;
|
||||
this.sortMedia(grouping, mCopy);
|
||||
let groupFN = (m: MediaDTO) => '';
|
||||
switch (grouping) {
|
||||
case SortingMethods.ascDate:
|
||||
case SortingMethods.descDate:
|
||||
switch (grouping.method) {
|
||||
case SortingByTypes.Date:
|
||||
groupFN = (m: MediaDTO) => this.datePipe.transform(m.metadata.creationDate, 'longDate');
|
||||
break;
|
||||
case SortingMethods.ascName:
|
||||
case SortingMethods.descName:
|
||||
case SortingByTypes.Name:
|
||||
groupFN = (m: MediaDTO) => m.name.at(0).toLowerCase();
|
||||
break;
|
||||
case SortingMethods.descRating:
|
||||
case SortingMethods.ascRating:
|
||||
case SortingByTypes.Rating:
|
||||
groupFN = (m: MediaDTO) => ((m as PhotoDTO).metadata.rating || 0).toString();
|
||||
break;
|
||||
case SortingMethods.descPersonCount:
|
||||
case SortingMethods.ascPersonCount:
|
||||
case SortingByTypes.PersonCount:
|
||||
groupFN = (m: MediaDTO) => ((m as PhotoDTO).metadata.faces || []).length.toString();
|
||||
break;
|
||||
}
|
||||
|
@ -253,7 +253,7 @@
|
||||
(ngModelChange)="onChange($event)"
|
||||
class="form-select"
|
||||
[(ngModel)]="mp.sortBy[k]">
|
||||
<option *ngFor="let opt of SortingMethods" [ngValue]="opt.key">{{opt.value}}
|
||||
<option *ngFor="let opt of SortingByTypes" [ngValue]="opt.key">{{opt.value}}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
|
@ -19,8 +19,8 @@ import {
|
||||
ScheduledJobTriggerConfig
|
||||
} from '../../../../../common/config/private/PrivateConfig';
|
||||
import {ControlValueAccessor, NG_VALIDATORS, NG_VALUE_ACCESSOR, ValidationErrors, Validator} from '@angular/forms';
|
||||
import {enumToTranslatedArray} from '../../EnumTranslations';
|
||||
import {SortingMethods} from '../../../../../common/entities/SortingMethods';
|
||||
import {EnumTranslations} from '../../EnumTranslations';
|
||||
import {SortingByTypes, SortingMethod} from '../../../../../common/entities/SortingMethods';
|
||||
import {MediaPickDTO} from '../../../../../common/entities/MediaPickDTO';
|
||||
import {SearchQueryTypes, TextSearch} from '../../../../../common/entities/SearchQueryDTO';
|
||||
|
||||
@ -65,15 +65,15 @@ export class WorkflowComponent implements ControlValueAccessor, Validator, OnIni
|
||||
allowParallelRun: false,
|
||||
};
|
||||
public readonly ConfigStyle = ConfigStyle;
|
||||
SortingMethods = enumToTranslatedArray(SortingMethods);
|
||||
SortingByTypes: { key: SortingMethod; value: string }[];
|
||||
|
||||
|
||||
error: string;
|
||||
|
||||
constructor(
|
||||
public settingsService: SettingsService,
|
||||
public jobsService: ScheduledJobsService,
|
||||
public backendTextService: BackendtextService,
|
||||
public settingsService: SettingsService,
|
||||
public jobsService: ScheduledJobsService,
|
||||
public backendTextService: BackendtextService,
|
||||
) {
|
||||
this.JobTriggerTypeMap = [
|
||||
{key: JobTriggerType.after, value: $localize`after`},
|
||||
@ -91,6 +91,22 @@ export class WorkflowComponent implements ControlValueAccessor, Validator, OnIni
|
||||
$localize`Sunday`,
|
||||
$localize`day`,
|
||||
]; // 7
|
||||
|
||||
this.SortingByTypes = [];
|
||||
for (const enumMember in SortingByTypes) {
|
||||
const key = parseInt(enumMember, 10);
|
||||
if (key >= 0) {
|
||||
this.SortingByTypes.push({
|
||||
key: {method: key, ascending: true} as SortingMethod,
|
||||
value: EnumTranslations[SortingByTypes[enumMember]] || SortingByTypes[enumMember] + $localize`ascending`
|
||||
});
|
||||
this.SortingByTypes.push({
|
||||
key: {method: key, ascending: false} as SortingMethod,
|
||||
value: EnumTranslations[SortingByTypes[enumMember]] || SortingByTypes[enumMember] + $localize`descending`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
atTimeLocal(atTime: number): Date {
|
||||
@ -115,27 +131,27 @@ export class WorkflowComponent implements ControlValueAccessor, Validator, OnIni
|
||||
|
||||
remove(schedule: JobScheduleDTO): void {
|
||||
this.schedules.splice(
|
||||
this.schedules.indexOf(schedule),
|
||||
1
|
||||
this.schedules.indexOf(schedule),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
jobTypeChanged(schedule: JobScheduleDTO): void {
|
||||
const job = this.jobsService.availableJobs.value.find(
|
||||
(t) => t.Name === schedule.jobName
|
||||
(t) => t.Name === schedule.jobName
|
||||
);
|
||||
schedule.config = schedule.config || {};
|
||||
if (job.ConfigTemplate) {
|
||||
job.ConfigTemplate.forEach(
|
||||
(ct) => (schedule.config[ct.id] = ct.defaultValue)
|
||||
(ct) => (schedule.config[ct.id] = ct.defaultValue)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
jobTriggerTypeChanged(
|
||||
triggerType: JobTriggerType,
|
||||
schedule: JobScheduleDTO
|
||||
triggerType: JobTriggerType,
|
||||
schedule: JobScheduleDTO
|
||||
): void {
|
||||
switch (triggerType) {
|
||||
case JobTriggerType.never:
|
||||
@ -165,7 +181,7 @@ export class WorkflowComponent implements ControlValueAccessor, Validator, OnIni
|
||||
value = value.replace(new RegExp(',', 'g'), ';');
|
||||
value = value.replace(new RegExp(' ', 'g'), ';');
|
||||
configElement[id] = value
|
||||
.split(';').filter((i: string) => i != '');
|
||||
.split(';').filter((i: string) => i != '');
|
||||
}
|
||||
|
||||
getArray(configElement: Record<string, number[]>, id: string): string {
|
||||
@ -176,46 +192,46 @@ export class WorkflowComponent implements ControlValueAccessor, Validator, OnIni
|
||||
value = value.replace(new RegExp(',', 'g'), ';');
|
||||
value = value.replace(new RegExp(' ', 'g'), ';');
|
||||
configElement[id] = value
|
||||
.split(';')
|
||||
.map((s: string) => parseInt(s, 10))
|
||||
.filter((i: number) => !isNaN(i) && i > 0);
|
||||
.split(';')
|
||||
.map((s: string) => parseInt(s, 10))
|
||||
.filter((i: number) => !isNaN(i) && i > 0);
|
||||
}
|
||||
|
||||
|
||||
public shouldIdent(curr: JobScheduleDTO, prev: JobScheduleDTO): boolean {
|
||||
return (
|
||||
curr &&
|
||||
curr.trigger.type === JobTriggerType.after &&
|
||||
prev &&
|
||||
prev.name === curr.trigger.afterScheduleName
|
||||
curr &&
|
||||
curr.trigger.type === JobTriggerType.after &&
|
||||
prev &&
|
||||
prev.name === curr.trigger.afterScheduleName
|
||||
);
|
||||
}
|
||||
|
||||
public sortedSchedules(): JobScheduleDTO[] {
|
||||
return (this.schedules || [])
|
||||
.slice()
|
||||
.sort((a: JobScheduleDTO, b: JobScheduleDTO) => {
|
||||
return (
|
||||
this.getNextRunningDate(a, this.schedules) -
|
||||
this.getNextRunningDate(b, this.schedules)
|
||||
);
|
||||
});
|
||||
.slice()
|
||||
.sort((a: JobScheduleDTO, b: JobScheduleDTO) => {
|
||||
return (
|
||||
this.getNextRunningDate(a, this.schedules) -
|
||||
this.getNextRunningDate(b, this.schedules)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
prepareNewJob(): void {
|
||||
const jobName = this.jobsService.availableJobs.value[0].Name;
|
||||
this.newSchedule = new JobScheduleConfig('new job',
|
||||
jobName,
|
||||
new NeverJobTriggerConfig());
|
||||
jobName,
|
||||
new NeverJobTriggerConfig());
|
||||
|
||||
// setup job specific config
|
||||
const job = this.jobsService.availableJobs.value.find(
|
||||
(t) => t.Name === jobName
|
||||
(t) => t.Name === jobName
|
||||
);
|
||||
this.newSchedule.config = this.newSchedule.config || {};
|
||||
if (job.ConfigTemplate) {
|
||||
job.ConfigTemplate.forEach(
|
||||
(ct) => (this.newSchedule.config[ct.id] = ct.defaultValue)
|
||||
(ct) => (this.newSchedule.config[ct.id] = ct.defaultValue)
|
||||
);
|
||||
}
|
||||
this.jobModalQL.first.show();
|
||||
@ -225,12 +241,12 @@ export class WorkflowComponent implements ControlValueAccessor, Validator, OnIni
|
||||
// make unique job name
|
||||
const jobName = this.newSchedule.jobName;
|
||||
const count = this.schedules.filter(
|
||||
(s: JobScheduleDTO) => s.jobName === jobName
|
||||
(s: JobScheduleDTO) => s.jobName === jobName
|
||||
).length;
|
||||
this.newSchedule.name =
|
||||
count === 0
|
||||
? jobName
|
||||
: this.backendTextService.getJobName(jobName) + ' ' + (count + 1);
|
||||
count === 0
|
||||
? jobName
|
||||
: this.backendTextService.getJobName(jobName) + ' ' + (count + 1);
|
||||
this.schedules.push(this.newSchedule);
|
||||
|
||||
this.jobModalQL.first.hide();
|
||||
@ -242,24 +258,24 @@ export class WorkflowComponent implements ControlValueAccessor, Validator, OnIni
|
||||
}
|
||||
|
||||
private getNextRunningDate(
|
||||
sch: JobScheduleDTO,
|
||||
list: JobScheduleDTO[],
|
||||
depth = 0
|
||||
sch: JobScheduleDTO,
|
||||
list: JobScheduleDTO[],
|
||||
depth = 0
|
||||
): number {
|
||||
if (depth > list.length) {
|
||||
return 0;
|
||||
}
|
||||
if (sch.trigger.type === JobTriggerType.never) {
|
||||
return (
|
||||
list
|
||||
.map((s) => s.name)
|
||||
.sort()
|
||||
.indexOf(sch.name) * -1
|
||||
list
|
||||
.map((s) => s.name)
|
||||
.sort()
|
||||
.indexOf(sch.name) * -1
|
||||
);
|
||||
}
|
||||
if (sch.trigger.type === JobTriggerType.after) {
|
||||
const parent = list.find(
|
||||
(s) => s.name === (sch.trigger as AfterJobTrigger).afterScheduleName
|
||||
(s) => s.name === (sch.trigger as AfterJobTrigger).afterScheduleName
|
||||
);
|
||||
if (parent) {
|
||||
return this.getNextRunningDate(parent, list, depth + 1) + 0.001;
|
||||
@ -294,10 +310,6 @@ export class WorkflowComponent implements ControlValueAccessor, Validator, OnIni
|
||||
}
|
||||
|
||||
|
||||
AsSortArray(configElement: string | number | string[] | number[] | MediaPickDTO[]): SortingMethods[] {
|
||||
return configElement as SortingMethods[];
|
||||
}
|
||||
|
||||
AsMediaPickDTOArray(configElement: string | number | string[] | number[] | MediaPickDTO[]): MediaPickDTO[] {
|
||||
return configElement as MediaPickDTO[];
|
||||
}
|
||||
@ -306,14 +318,14 @@ export class WorkflowComponent implements ControlValueAccessor, Validator, OnIni
|
||||
configElement.splice(i, 1);
|
||||
}
|
||||
|
||||
AddNewSorting(configElement: string | number | string[] | number[] | MediaPickDTO[]): void {
|
||||
(configElement as SortingMethods[]).push(SortingMethods.ascDate);
|
||||
AddNewSorting(configElement: string | number | string[] | number[] | MediaPickDTO[] | SortingMethod[]): void {
|
||||
(configElement as SortingMethod[]).push({method: SortingByTypes.Date, ascending: true});
|
||||
}
|
||||
|
||||
AddNewMediaPickDTO(configElement: string | number | string[] | number[] | MediaPickDTO[]): void {
|
||||
(configElement as MediaPickDTO[]).push({
|
||||
searchQuery: {type: SearchQueryTypes.any_text, text: ''} as TextSearch,
|
||||
sortBy: [SortingMethods.descRating],
|
||||
sortBy: [{method: SortingByTypes.Rating, ascending: true}],
|
||||
pick: 5
|
||||
});
|
||||
}
|
||||
|
@ -1,37 +1,17 @@
|
||||
<ng-container [ngSwitch]="method">
|
||||
<ng-container *ngSwitchCase="SortingMethods.descName">
|
||||
<ng-icon name="ionArrowDownOutline"></ng-icon>
|
||||
<ng-container *ngSwitchCase="SortingByTypes.Name">
|
||||
<span>A</span>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="SortingMethods.ascName">
|
||||
<ng-icon name="ionArrowUpOutline"></ng-icon>
|
||||
<span>A</span>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="SortingMethods.descRating">
|
||||
<ng-icon name="ionArrowDownOutline"></ng-icon>
|
||||
<ng-container *ngSwitchCase="SortingByTypes.Rating">
|
||||
<ng-icon name="ionStarOutline"></ng-icon>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="SortingMethods.ascRating">
|
||||
<ng-icon name="ionArrowUpOutline"></ng-icon>
|
||||
<ng-icon name="ionStarOutline"></ng-icon>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="SortingMethods.descDate">
|
||||
<ng-icon name="ionArrowDownOutline"></ng-icon>
|
||||
<ng-container *ngSwitchCase="SortingByTypes.Date">
|
||||
<ng-icon name="ionCalendarOutline"></ng-icon>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="SortingMethods.ascDate">
|
||||
<ng-icon name="ionArrowUpOutline"></ng-icon>
|
||||
<ng-icon name="ionCalendarOutline"></ng-icon>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="SortingMethods.descPersonCount">
|
||||
<ng-icon name="ionArrowDownOutline"></ng-icon>
|
||||
<ng-container *ngSwitchCase="SortingByTypes.PersonCount">
|
||||
<ng-icon name="ionPersonOutline"></ng-icon>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="SortingMethods.ascPersonCount">
|
||||
<ng-icon name="ionArrowUpOutline"></ng-icon>
|
||||
<ng-icon name="ionPersonOutline"></ng-icon>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="SortingMethods.random">
|
||||
<ng-container *ngSwitchCase="SortingByTypes.random">
|
||||
<ng-icon name="ionShuffleOutline"></ng-icon>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
||||
import {SortingByTypes} from '../../../../common/entities/SortingMethods';
|
||||
|
||||
@Component({
|
||||
selector: 'app-sorting-method-icon',
|
||||
@ -7,6 +7,6 @@ import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
||||
styleUrls: ['./sorting-method-icon.component.css']
|
||||
})
|
||||
export class SortingMethodIconComponent {
|
||||
@Input() method: SortingMethods;
|
||||
SortingMethods = SortingMethods;
|
||||
@Input() method: SortingByTypes;
|
||||
SortingByTypes = SortingByTypes;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user