...
Use a CLI command to generate a state component with a custom name and sidebar link. The link appears in the navigation menu on the left. (sidebar-navigation = default)
Code Block language bash linenumbers true eo g state custom
Use a CLI command to install the maps package (takes some time).
Code Block language bash linenumbers true npm install -P ng2-charts@1.6.0
Import ChartsModule module to CustomStatesModule.
Code Block language js title custom-states.module.ts linenumbers true import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {Route, RouterModule} from '@angular/router'; import {EoFrameworkModule} from '@eo-sdk/client'; import {EoLinkPlugin} from '@eo-sdk/client'; import {AuthGuard} from '@eo-sdk/client'; import {CustomComponent} from './custom/custom.component'; import {ChartsModule} from 'ng2-charts'; export const routes: Route[] = [ {path: CustomComponent.path, component: CustomComponent, canActivate: [AuthGuard]}, ]; export const links: EoLinkPlugin[] = [ CustomComponent ]; @NgModule({ imports: [ CommonModule, EoFrameworkModule, RouterModule.forChild(routes), ChartsModule ], declarations: [CustomComponent] }) export class CustomStatesModule { }
Update custom.component.ts to load current chart data.
Code Block language js title custom.component.ts linenumbers true import {Component, ViewChild} from '@angular/core'; import {Chart} from 'chart.js'; import {TranslateService, SearchService} from '@eo-sdk/core'; import {BaseChartDirective} from 'ng2-charts'; // In the following line ', UnsubscribeOnDestroy' has to be removed when updating to version 9.10 or younger: import {AppSearchService, UnsubscribeOnDestroy} from '@eo-sdk/client'; import {takeUntil} from 'rxjs/operators'; @Component({ selector: 'eo-custom', templateUrl: './custom.component.html', styleUrls: ['./custom.component.scss'] }) // in the following line 'extends UnsubscribeOnDestroy' has to be removed when updating to version 9.10 or younger: export class CustomComponent extends UnsubscribeOnDestroy { static id = 'eo.custom.state.custom'; static path = 'custom/custom'; static matchType = new RegExp('sidebar-navigation'); groupCount: number; totalCount: number; chart; activeType = 0; types = []; @ViewChild(BaseChartDirective) chartEl: BaseChartDirective; constructor(private translate: TranslateService, private searchService: SearchService, private appSearchService: AppSearchService) { super(); this.fetchData(); } chartClicked(el?) { if (!el || (this.activeType === this.groupCount && el.active[0])) { this.activeType = el ? el.active[0]._index : this.groupCount; this.chart = this.dataToChart(this.types[this.activeType]); setTimeout(() => { this.chartEl.chart.config.data.labels = this.chart.labels; this.chartEl.chart.update(); }, 0); } } dataToChart(groups: any[]): Chart { return { data: [{ data: groups.map(g => g.count), label: '' }], labels: groups.map(g => g.label) }; } private fetchData() { this.appSearchService.setTerm(''); this.appSearchService .queryState$ .pipe( takeUntil(this.componentDestroyed$) ) .subscribe(res => { this.totalCount = res.count; this.groupCount = this.appSearchService.objectTypeGroups.length; this.types = []; const main = this.appSearchService.objectTypeGroups.map((g) => { const type = g.types.map(t => ({label: t.label, count: res.aggregations.type.get(t.qname) || 0})); this.types.push(type.sort((a, b) => b.count - a.count)); return { label: g.label === '0' ? this.translate.instant('eo.quicksearch.result.group.global') : g.label, count: type.map(t => t.count).reduce((a, b) => a + b, 0) }; }); this.types.push(main.sort((a, b) => b.count - a.count)); this.chartClicked(); } ); } }
Update custom-state.component.html to include a chart component.
Code Block language xml title custom-state.component.html linenumbers true <button class="summary" (click)="chartClicked()"> <span class="label" *ngIf="activeType != groupCount">{{types[groupCount][activeType].label}}: </span> <span class="count" *ngIf="activeType != groupCount"> {{types[groupCount][activeType].count}} of </span> <span class="total">{{totalCount}}</span> </button> <div class="chart-container"> <canvas baseChart *ngIf="chart" height="100%" [datasets]="chart.data" [labels]="chart.labels" [chartType]="'doughnut'" (chartClick)="chartClicked($event)"></canvas> </div>
To finish this state, add some styling
Code Block language css title custom-state.component.scss linenumbers true :host { flex: 1; display: flex; flex-flow: column; .summary { align-items: baseline; position: absolute; right: 30px; top: 30px; flex: 1 1 auto; display: flex; background: papayawhip; border-radius: 4px; padding: 16px; border: 1px solid rgba(255, 255, 255, 0.2); .label { font-size: 1.5em; } .count { font-size: 2.5em; } .total { font-size: 3.5em; } } .chart-container { flex: 0 0 auto; } }
Use a CLI command to generate labels/translations.
Code Block language bash linenumbers true eo g label eo.custom.state.custom --en "Custom state" --de "Custom state"
...
Use a CLI command to generate a simple preview state component. The link appears in the navigation menu on the left. (sidebar-navigation = default)
Code Block language bash title Terminal eo g state simple-preview
Update the simple-preview component implementation. Please update queryParams based on your scheme!
Code Block language xml title simple-preview.component.html <eo-media *ngIf="item" [dmsObject]="item" [useVersion]="item.id === item.content?.id" #viewer> </eo-media>
Code Block language css title simple-preview.component.scss /* fullscreen setup */ :host { position: fixed !important; top: 0; right: 0; bottom: 0; left: 0; z-index: 10 !important; }
Code Block language js title simple-preview.component.ts import {Component, OnInit} from '@angular/core'; import {DmsObject, DmsParams, DmsService} from '@eo-sdk/core'; import {ActivatedRoute} from '@angular/router'; // The following line has to be removed when updating to version 9.10 or younger: import {UnsubscribeOnDestroy} from '@eo-sdk/client'; import {takeUntil, filter} from 'rxjs/operators'; @Component({ selector: 'eo-simple-preview', templateUrl: './simple-preview.component.html', styleUrls: ['./simple-preview.component.scss'] })'] }) // In the following line 'extends UnsubscribeOnDestroy' has to be removed when updating to version 9.10 or younger: export class SimplePreviewComponent extends UnsubscribeOnDestroy implements OnInit { static id = 'eo.custom.state.simple-preview'; static path = 'custom/simple-preview'; static matchType = new RegExp('sidebar-navigation'); /* set specific existing ID of DMS object to provide correct link */ static queryParams = {id: '0000'}; item: DmsObject; constructor(private dmsService: DmsService, private route: ActivatedRoute) { super(); } loadDmsObject(params: DmsParams) { this.dmsService .getDmsObjectByParams(params) .subscribe(val => this.item = val) } ngOnInit() { this.route .queryParams .pipe(takeUntil(this.componentDestroyed$), filter(params => params.id)) .subscribe(params => this.loadDmsObject(params as DmsParams)); } }
Use a CLI command to generate a simple list state component. The link appears in the navigation menu on the left. (sidebar-navigation = default)
Code Block language bash title Terminal eo g state simple-list
Update the simple-list component implementation (a double-click redirects to the simple preview state). Please update queryParams based on your scheme!
Code Block language xml title simple-list.component.html <eo-result-list [query]="query" [hasIcon]="true" (onDoubleClick)="onDoubleClick($event)"></eo-result-list>
Code Block language css title simple-list.component.scss /* fullscreen setup */ :host { position: fixed !important; top: 0; right: 0; bottom: 0; left: 0; z-index: 10 !important; }
Code Block language js title simple-list.component.ts import {Component, OnInit} from '@angular/core'; import {SearchService, SearchQuery, SearchResult} from '@eo-sdk/core'; import {ActivatedRoute, Router, NavigationExtras} from '@angular/router'; import {takeUntil, filter} from 'rxjs/operators'; // The following line has to be removed when updating to version 9.10 or younger: import {UnsubscribeOnDestroy} from '@eo-sdk/client'; import {SimplePreviewComponent} from '../simple-preview/simple-preview.component'; @Component({ selector: 'eo-simple-list', templateUrl: './simple-list.component.html', styleUrls: ['./simple-list.component.scss'] }) // In the following line 'extends UnsubscribeOnDestroy' has to be removed when updating to version 9.10 or younger: export class SimpleListComponent extends UnsubscribeOnDestroy implements OnInit { static id = 'eo.custom.state.simple-list'; static path = 'custom/simple-list'; static matchType = new RegExp('sidebar-navigation'); /* set specific existing query to provide correct link */ /* multiple ways how to set query based on input format */ // static queryParams = {query : '%7B%22types%22%3A%5B%22eoxemail%22%5D%7D'}; // static queryParams = {query : decodeURIComponent('%257B%2522types%2522%253A%255B%2522eoxemail%2522%255D%257D')}; static queryParams = {query: encodeURIComponent(JSON.stringify({'types': ['eoxemail']}))}; query: SearchQuery; searchResult: SearchResult = new SearchResult(); constructor(private route: ActivatedRoute, private router: Router, private searchService: SearchService) { super(); } getParams() { this.route .queryParams .pipe(takeUntil(this.componentDestroyed$), filter(params => params.query)) .subscribe((params: any) => { this.query = JSON.parse(decodeURIComponent(params.query)); const defaultQuery = this.searchService.buildQuery(this.query); this.searchService .getChunkedResult(defaultQuery, 0, 10000) .subscribe(result => { this.searchResult = result; }); }); } onDoubleClick(event) { const {id, version, typeName} = event.data; const queryParams: NavigationExtras = {queryParams: {id, version, 'type': typeName}}; const url = this.router.createUrlTree([SimplePreviewComponent.path], queryParams).toString(); window.open(url); } ngOnInit() { this.getParams(); } }
We need to generate a guard to deactivate the original behavior of the result list component
Code Block language bash title Terminal ng generate guard eo-custom-client/custom-states/simple-list/can-deactivate-list --spec false
Update can-deactivate-list.guard.ts
Code Block language js title can-deactivate-list.guard.ts linenumbers true import {Injectable} from '@angular/core'; import {CanDeactivate} from '@angular/router'; import {SimpleListComponent} from './simple-list.component'; @Injectable({ providedIn: 'root' }) export class CanDeactivateListGuard implements CanDeactivate<SimpleListComponent> { canDeactivate() { return false; } }
Add CanDeactivateListGuard guard to the custom-states module.
Code Block language js title custom-states.module.ts linenumbers true import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {Route, RouterModule} from '@angular/router'; import {EoFrameworkModule} from '@eo-sdk/client'; import {EoLinkPlugin} from '@eo-sdk/client'; import {AuthGuard} from '@eo-sdk/client'; import {SimpleListComponent} from './simple-list/simple-list.component'; import {CanDeactivateListGuard} from './simple-list/can-deactivate-list.guard'; import {SimplePreviewComponent} from './simple-preview/simple-preview.component'; export const routes: Route[] = [ {path: SimplePreviewComponent.path, component: SimplePreviewComponent, canActivate: [AuthGuard]}, {path: SimpleListComponent.path, component: SimpleListComponent, canActivate: [AuthGuard], canDeactivate: [CanDeactivateListGuard]}, ]; export const links: EoLinkPlugin[] = [ SimplePreviewComponent, SimpleListComponent, ]; @NgModule({ imports: [ CommonModule, EoFrameworkModule, RouterModule.forChild(routes) ], declarations: [SimpleListComponent, SimplePreviewComponent] }) export class CustomStatesModule { }
Use a CLI command to generate labels/translations.
Code Block language bash linenumbers true eo g label eo.custom.state.simple-list --en "Simple List" --de "Einfache Liste"
Code Block language bash linenumbers true eo g label eo.custom.state.simple-preview --en "Simple Preview" --de "Einfache Vorschau"
...