Files
openstapps/src/app/modules/menu/context/context-menu.component.ts

162 lines
4.5 KiB
TypeScript

/*
* 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 <https://www.gnu.org/licenses/>.
*/
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:<br>
* `<stapps-context (optionChange)="onOptionChange($event)" (settingChange)="onSettingChange($event)"
* [sortOption]="SortContext" [filterOption]="FilterContext"></stapps-context>`
*/
@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<SCLanguage>;
/**
* 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<SCLanguage>;
this.translator = new SCThingTranslator(this.language);
this.subscriptions.push(
this.translateService.onLangChange.subscribe((event: LangChangeEvent) => {
this.language = event.lang as keyof SCTranslations<SCLanguage>;
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);
};
}