/* * Copyright (C) 2023 StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ import {Component, Input, OnDestroy} from '@angular/core'; import {LangChangeEvent, TranslateService} from '@ngx-translate/core'; import {SCLanguage, SCThingTranslator, SCThingType, SCTranslations} from '@openstapps/core'; import {Subscription} from 'rxjs'; import {ContextMenuService} from './context-menu.service'; import {FilterContext, FilterFacet, SortContext, SortContextOption} from './context-type'; /** * The context menu * * It can be configured with sorting types and filtering on facets * * Example:
* `` */ @Component({ selector: 'stapps-context', templateUrl: 'context-menu.html', }) export class ContextMenuComponent implements OnDestroy { /** * Id of the content the menu is used for */ @Input() contentId: string; /** * Amount of filter options shown on compact view */ compactFilterOptionCount = 5; /** * Container for the filter context */ filterOption: FilterContext; /** * Picks facets based on the compact filter option and sorts * them based on * * No specific type => Type name alphabetically => Bucket count */ get facets(): FilterFacet[] { const options = this.filterOption.compact ? this.filterOption.options.slice(0, this.compactFilterOptionCount) : this.filterOption.options; return options.filter(it => it.buckets.length > 0); } /** * Possible languages to be used for translation */ language: keyof SCTranslations; /** * Mapping of SCThingType */ scThingType = SCThingType; /** * Container for the sort context */ sortOption: SortContext; /** * Array of all Subscriptions */ subscriptions: Subscription[] = []; /** * Core translator */ translator: SCThingTranslator; constructor( private translateService: TranslateService, private readonly contextMenuService: ContextMenuService, ) { this.language = this.translateService.currentLang as keyof SCTranslations; this.translator = new SCThingTranslator(this.language); this.subscriptions.push( this.translateService.onLangChange.subscribe((event: LangChangeEvent) => { this.language = event.lang as keyof SCTranslations; this.translator = new SCThingTranslator(this.language); }), this.contextMenuService.filterContextChanged$.subscribe(filterContext => { this.filterOption = filterContext; }), this.contextMenuService.sortOptions.subscribe(sortContext => { this.sortOption = sortContext; }), ); } /** * Sets selected filter options and updates listener */ filterChanged = () => { this.contextMenuService.contextFilterChanged(this.filterOption); }; /** * Returns translated property value */ getTranslatedPropertyValue(onlyForType: SCThingType, field: string, key?: string): string | undefined { return this.translator.translatedPropertyValue(onlyForType, field, key); } /** * Unsubscribe from Observables */ ngOnDestroy() { for (const sub of this.subscriptions) { sub.unsubscribe(); } } /** * Resets filter options */ resetFilter = (option: FilterContext) => { for (const filterFacet of option.options) for (const filterBucket of filterFacet.buckets) { filterBucket.checked = false; } this.contextMenuService.contextFilterChanged(this.filterOption); }; /** * Updates selected sort option and updates listener */ sortChanged = (option: SortContext, value: SortContextOption) => { if (option.value === value.value) { if (value.reversible) { option.reversed = !option.reversed; } } else { option.value = value.value; if (value.reversible) { option.reversed = false; } } this.contextMenuService.contextSortChanged(option); }; }