import {
Component,
Input,
Optional,
OnInit,
OnDestroy,
Injector
} from '@angular/core'
import { FormControl } from '@angular/forms'
import { Router } from '@angular/router'
import { Location } from '@angular/common'
import { PopoverController } from '@ionic/angular'
import { SubscriptionLike } from 'rxjs'
import { RccToastController } from '../../modals-provider'
import { MetaStore } from '../meta-store.class'
import { MetaAction } from '../meta-store.commons'
//TODO: abstract popover
@Component({
templateUrl: './popover.html'
})
export class PopoverComponent {
public actions? : MetaAction<any,any,any>[] = []
public getHandler? : (action:MetaAction<any,any,any>) => (...args: any[]) => any
constructor(
public popoverController: PopoverController
){}
}
@Component({
selector: 'rcc-meta-store-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'],
})
export class HeaderComponent implements OnInit, OnDestroy{
@Input()
public metaStore! : MetaStore<any,any,any>
@Optional() @Input()
public filterControl! : FormControl | null
public showSearch : boolean = false
public actions : MetaAction<any,any,any>[] = []
private subscriptions : SubscriptionLike[] = []
constructor(
public popoverController : PopoverController,
public rccToastController : RccToastController,
public router : Router,
public location : Location,
public injector : Injector
) {}
ngOnInit(){
this.actions = this.metaStore.metaActions
if(this.filterControl) this.actions.unshift({
label: "META_STORE.ACTIONS.FILTER_ITEMS",
icon: "filter",
handler: () => this.toggleFilter()
})
this.subscriptions.push(
this.location.subscribe( popstate =>{
this.showSearch = !!popstate.state.showSearch
if(!this.showSearch && this.filterControl) this.filterControl.setValue('')
})
)
}
public toggleFilter(){
this.showSearch = !this.showSearch
const path = this.location.path()
this.showSearch
? this.location.go(path, '', {showSearch: true})
: this.location.back()
}
public getHandler(itemAction: MetaAction<any,any,any>) : () => any {
if( 'handler' in itemAction ) {
return () => Promise.resolve(itemAction.handler(this.metaStore))
.then(
(result:any) => {
itemAction.successMessage
? this.rccToastController.success(itemAction.successMessage)
: result
},
(reason:any) => {
itemAction.failureMessage
? this.rccToastController.failure(itemAction.failureMessage)
: Promise.reject(reason)
}
)
}
if( 'path' in itemAction ){
return () => this.router.navigateByUrl(itemAction.path)
}
if( 'handlerFactory' in itemAction){
const deps = (itemAction.deps||[]).map( dependency => this.injector.get(dependency) )
const raw_handler = itemAction.handlerFactory(...deps)
return () => raw_handler(this.metaStore)
}
return (function(): never {
throw new Error("HeaderComponent.getHandler() ItemAction must have on of the following properties: handler, path and handlerFactory. "+JSON.stringify(itemAction) )
})()
}
public async showActions(event: Event){
const popover = await this.popoverController.create({
component: PopoverComponent,
translucent: true,
componentProps: {
actions: this.actions,
getHandler: (action:any) => this.getHandler(action)
},
event
})
return await popover.present()
}
ngOnDestroy(){
this.subscriptions.forEach( sub => sub.unsubscribe() )
}
}
<ion-header >
<ion-toolbar
style = "align-items: center !important"
>
<rcc-common-header
slot = "start"
[id] = "metaStore.name + '-menu-button' | toID: 'rcc-e2e'"
>
</rcc-common-header>
<ion-title
style = "align-self: center !important"
class = "ion-text-center"
[id] = "metaStore.name | toID: 'rcc-e2e'"
>
{{ metaStore.name | translate }}
</ion-title>
<ion-buttons
slot = "primary"
>
<ion-button
*ngIf = "actions.length > 1"
(click) = "showActions($event)"
[id] = "metaStore.name + '-actions' | toID: 'rcc-e2e'"
>
<ion-icon
[name] = "'actions' | rccIcon"
slot = "icon-only"
[class] = "metaStore.name + '-action' | toID: 'rcc-e2e'"
></ion-icon>
</ion-button>
<ion-button
*ngIf = "actions.length == 1"
(click) = "getHandler(actions[0])()"
>
<ion-icon
[name] = "actions[0].icon | rccIcon"
slot = "icon-only"
></ion-icon>
</ion-button>
</ion-buttons>
</ion-toolbar>
<ion-toolbar *ngIf = "filterControl && showSearch"
>
<ion-searchbar
*ngIf = "filterControl && showSearch"
[formControl] = "filterControl"
[id] = "metaStore.name + '-searchbar' | toID: 'rcc-e2e'"
>
</ion-searchbar>
<ion-buttons slot = "primary">
<ion-button
*ngIf = "filterControl && showSearch"
(click) = "toggleFilter()"
>
<ion-icon
[name] = "'close' | rccIcon"
slot = "icon-only"
[class] = "metaStore.name + '-action' | toID: 'rcc-e2e'"
></ion-icon>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>