mirror of
https://github.com/SuiteCRM/SuiteCRM-Core.git
synced 2025-09-04 10:14:13 +08:00
Display recently viewed in navbar
This commit is contained in:
parent
9d3f39e173
commit
5fb1a82f65
28 changed files with 204 additions and 173 deletions
|
@ -2,3 +2,4 @@ parameters:
|
|||
ui:
|
||||
alert_timeout: 3
|
||||
modal_buttons_collapse_breakpoint: 4
|
||||
navigation_max_module_recently_viewed: 5
|
||||
|
|
|
@ -128,13 +128,12 @@
|
|||
<ul class="navbar-nav grouped">
|
||||
|
||||
<li *ngIf="navbar.current" class="top-nav nav-item dropdown non-grouped active">
|
||||
<scrm-menu-item [item]="navbar.current" [languages]="vm.languages"></scrm-menu-item>
|
||||
<scrm-menu-item [item]="navbar.current"></scrm-menu-item>
|
||||
</li>
|
||||
|
||||
<li *ngFor="let item of navbar.menu" class="top-nav nav-item dropdown main-grouped">
|
||||
<scrm-grouped-menu-item
|
||||
[item]="item"
|
||||
[languages]="vm.languages"
|
||||
[subNavCollapse]="subNavCollapse"
|
||||
>
|
||||
</scrm-grouped-menu-item>
|
||||
|
@ -143,7 +142,7 @@
|
|||
</ul>
|
||||
|
||||
<scrm-menu-items-list [items]="navbar.all.modules"
|
||||
[label]="vm.languages.appStrings['LBL_TABGROUP_ALL'] || ''">
|
||||
labelKey="LBL_TABGROUP_ALL">
|
||||
</scrm-menu-items-list>
|
||||
|
||||
</ng-container>
|
||||
|
@ -157,15 +156,15 @@
|
|||
|
||||
<ul class="navbar-nav">
|
||||
<li *ngIf="navbar.current" class="top-nav nav-item dropdown non-grouped active">
|
||||
<scrm-menu-item [item]="navbar.current" [languages]="vm.languages"></scrm-menu-item>
|
||||
<scrm-menu-item [item]="navbar.current"></scrm-menu-item>
|
||||
</li>
|
||||
<li *ngFor="let item of navbar.menu" class="top-nav nav-item dropdown non-grouped">
|
||||
<scrm-menu-item [item]="item" [languages]="vm.languages"></scrm-menu-item>
|
||||
<scrm-menu-item [item]="item"></scrm-menu-item>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<scrm-menu-items-list [items]="navbar.all.modules"
|
||||
[label]="vm.languages.appStrings['LBL_MORE'] || ''">
|
||||
labelKey="LBL_MORE">
|
||||
</scrm-menu-items-list>
|
||||
|
||||
</ng-container>
|
||||
|
|
|
@ -45,7 +45,7 @@ import {ModuleNavigation} from '../../../services/navigation/module-navigation/m
|
|||
import {ModuleNameMapper} from '../../../services/navigation/module-name-mapper/module-name-mapper.service';
|
||||
import {AppState, AppStateStore} from '../../../store/app-state/app-state.store';
|
||||
import {AuthService} from '../../../services/auth/auth.service';
|
||||
import {MenuItem} from 'common';
|
||||
import {MenuItem, ready} from 'common';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-base-navbar',
|
||||
|
@ -76,7 +76,7 @@ export class BaseNavbarComponent implements OnInit, OnDestroy {
|
|||
moduleNameMapper = new ModuleNameMapper(this.systemConfigStore);
|
||||
actionNameMapper = new ActionNameMapper(this.systemConfigStore);
|
||||
routeConverter = new RouteConverter(this.moduleNameMapper, this.actionNameMapper, this.systemConfigStore);
|
||||
navbar: NavbarModel = new NavbarAbstract(this.routeConverter, this.moduleNavigation);
|
||||
navbar: NavbarModel;
|
||||
maxTabs = 8;
|
||||
screen: ScreenSize = ScreenSize.Medium;
|
||||
|
||||
|
@ -88,13 +88,13 @@ export class BaseNavbarComponent implements OnInit, OnDestroy {
|
|||
|
||||
vm$ = combineLatest([
|
||||
this.navigation$,
|
||||
this.languages$,
|
||||
this.userPreferences$,
|
||||
this.currentUser$,
|
||||
this.appState$,
|
||||
this.screenSize.screenSize$
|
||||
this.screenSize.screenSize$,
|
||||
this.languages$,
|
||||
]).pipe(
|
||||
map(([navigation, languages, userPreferences, currentUser, appState, screenSize]) => {
|
||||
map(([navigation, userPreferences, currentUser, appState, screenSize, language]) => {
|
||||
|
||||
if (screenSize) {
|
||||
this.screen = screenSize;
|
||||
|
@ -102,50 +102,37 @@ export class BaseNavbarComponent implements OnInit, OnDestroy {
|
|||
|
||||
this.calculateMaxTabs(navigation);
|
||||
|
||||
this.navbar.build(
|
||||
navigation,
|
||||
languages,
|
||||
userPreferences,
|
||||
currentUser,
|
||||
appState,
|
||||
this.maxTabs
|
||||
);
|
||||
this.navbar.resetMenu();
|
||||
if (ready([language.appStrings, language.modStrings, language.appListStrings, userPreferences, currentUser])) {
|
||||
this.navbar.build(
|
||||
navigation,
|
||||
currentUser,
|
||||
this.maxTabs,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
navigation, languages, userPreferences, appState
|
||||
navigation, userPreferences, appState
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
constructor(protected navigationStore: NavigationStore,
|
||||
protected languageStore: LanguageStore,
|
||||
protected userPreferenceStore: UserPreferenceStore,
|
||||
protected systemConfigStore: SystemConfigStore,
|
||||
protected appState: AppStateStore,
|
||||
protected authService: AuthService,
|
||||
protected moduleNavigation: ModuleNavigation,
|
||||
protected screenSize: ScreenSizeObserverService
|
||||
constructor(
|
||||
protected navigationStore: NavigationStore,
|
||||
protected languageStore: LanguageStore,
|
||||
protected userPreferenceStore: UserPreferenceStore,
|
||||
protected systemConfigStore: SystemConfigStore,
|
||||
protected appState: AppStateStore,
|
||||
protected authService: AuthService,
|
||||
protected moduleNavigation: ModuleNavigation,
|
||||
protected screenSize: ScreenSizeObserverService,
|
||||
) {
|
||||
const navbar = new NavbarAbstract(this.routeConverter, this.moduleNavigation);
|
||||
this.setNavbar(navbar);
|
||||
|
||||
BaseNavbarComponent.instances.push(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public API
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reset component instance
|
||||
*/
|
||||
static reset(): void {
|
||||
BaseNavbarComponent.instances.forEach((navbarComponent: BaseNavbarComponent) => {
|
||||
navbarComponent.loaded = false;
|
||||
navbarComponent.navbar = new NavbarAbstract(navbarComponent.routeConverter, navbarComponent.moduleNavigation);
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize(event: any): void {
|
||||
const innerWidth = event.target.innerWidth;
|
||||
|
@ -153,8 +140,15 @@ export class BaseNavbarComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
const navbar = new NavbarAbstract(this.routeConverter, this.moduleNavigation);
|
||||
const navbar = new NavbarAbstract(
|
||||
this.routeConverter,
|
||||
this.moduleNavigation,
|
||||
this.userPreferenceStore,
|
||||
this.languageStore,
|
||||
this.appState
|
||||
);
|
||||
this.setNavbar(navbar);
|
||||
|
||||
this.authService.isUserLoggedIn.subscribe(value => {
|
||||
this.isUserLoggedIn = value;
|
||||
});
|
||||
|
@ -197,6 +191,10 @@ export class BaseNavbarComponent implements OnInit, OnDestroy {
|
|||
return this.systemConfigStore.getHomePage();
|
||||
}
|
||||
|
||||
public getCloseCallBack(myDrop): Function {
|
||||
return () => myDrop.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal API
|
||||
*/
|
||||
|
@ -204,7 +202,7 @@ export class BaseNavbarComponent implements OnInit, OnDestroy {
|
|||
/**
|
||||
* Set navbar model
|
||||
*
|
||||
* @param {{}} navbar model
|
||||
* @param {object} navbar model
|
||||
*/
|
||||
protected setNavbar(navbar: NavbarModel): void {
|
||||
this.navbar = navbar;
|
||||
|
@ -232,8 +230,4 @@ export class BaseNavbarComponent implements OnInit, OnDestroy {
|
|||
this.maxTabs = maxTabs;
|
||||
}
|
||||
}
|
||||
|
||||
getCloseCallBack(myDrop): Function {
|
||||
return () => myDrop.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,9 +58,8 @@
|
|||
[link]="subitem.link">
|
||||
</scrm-menu-item-link>
|
||||
</li>
|
||||
<li>
|
||||
<scrm-menu-recently-viewed [languages]="languages"
|
||||
[records]="sub.recentRecords"></scrm-menu-recently-viewed>
|
||||
<li *ngIf="sub.module">
|
||||
<scrm-menu-recently-viewed [module]="sub.module"></scrm-menu-recently-viewed>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {MenuItem} from 'common';
|
||||
import {LanguageStrings} from '../../../store/language/language.store';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-base-grouped-menu-item',
|
||||
|
@ -35,7 +34,6 @@ import {LanguageStrings} from '../../../store/language/language.store';
|
|||
})
|
||||
export class BaseGroupedMenuItemComponent {
|
||||
@Input() item: MenuItem;
|
||||
@Input() languages: LanguageStrings;
|
||||
@Input() subNavCollapse: boolean;
|
||||
|
||||
constructor() {
|
||||
|
|
|
@ -27,5 +27,5 @@
|
|||
-->
|
||||
<ndc-dynamic *ngIf="getType"
|
||||
[ndcDynamicComponent]="getType"
|
||||
[ndcDynamicInputs]="{'item': item, 'languages': languages, 'subNavCollapse': subNavCollapse}">
|
||||
[ndcDynamicInputs]="{'item': item, 'subNavCollapse': subNavCollapse}">
|
||||
</ndc-dynamic>
|
||||
|
|
|
@ -95,7 +95,7 @@ const groupedMockMenuItem = {
|
|||
|
||||
@Component({
|
||||
selector: 'grouped-menu-item-test-host-component',
|
||||
template: '<scrm-grouped-menu-item [item]="item" [languages]="languages" [subNavCollapse]="subNavCollapse"></scrm-grouped-menu-item>'
|
||||
template: '<scrm-grouped-menu-item [item]="item" [subNavCollapse]="subNavCollapse"></scrm-grouped-menu-item>'
|
||||
})
|
||||
class GroupedMenuItemTestHostComponent {
|
||||
item: MenuItem = groupedMockMenuItem;
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {MenuItem} from 'common';
|
||||
import {LanguageStrings} from '../../../store/language/language.store';
|
||||
import {GroupedMenuItemRegistry} from './grouped-menu-item.registry';
|
||||
|
||||
@Component({
|
||||
|
@ -36,7 +35,6 @@ import {GroupedMenuItemRegistry} from './grouped-menu-item.registry';
|
|||
})
|
||||
export class GroupedMenuItemComponent {
|
||||
@Input() item: MenuItem;
|
||||
@Input() languages: LanguageStrings;
|
||||
@Input() subNavCollapse: boolean;
|
||||
|
||||
constructor(protected registry: GroupedMenuItemRegistry) {
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
|
||||
</div>
|
||||
|
||||
<scrm-menu-recently-viewed [languages]="languages" [records]="item.recentRecords"></scrm-menu-recently-viewed>
|
||||
<ng-container *ngIf="item && item.module">
|
||||
<scrm-menu-recently-viewed [module]="item.module"></scrm-menu-recently-viewed>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {MenuItem} from 'common';
|
||||
import {LanguageStrings} from '../../../store/language/language.store';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-base-menu-item',
|
||||
|
@ -35,7 +34,6 @@ import {LanguageStrings} from '../../../store/language/language.store';
|
|||
})
|
||||
export class BaseMenuItemComponent {
|
||||
@Input() item: MenuItem;
|
||||
@Input() languages: LanguageStrings;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
|
|
@ -28,5 +28,5 @@
|
|||
|
||||
<ndc-dynamic *ngIf="getType"
|
||||
[ndcDynamicComponent]="getType"
|
||||
[ndcDynamicInputs]="{'item': item, 'languages': languages}">
|
||||
[ndcDynamicInputs]="{'item': item}">
|
||||
</ndc-dynamic>
|
||||
|
|
|
@ -75,7 +75,7 @@ const mockMenuItem = {
|
|||
|
||||
@Component({
|
||||
selector: 'menu-item-test-host-component',
|
||||
template: '<scrm-menu-item [item]="item" [languages]="languages"></scrm-menu-item>'
|
||||
template: '<scrm-menu-item [item]="item"></scrm-menu-item>'
|
||||
})
|
||||
class MenuItemTestHostComponent {
|
||||
item: MenuItem = mockMenuItem;
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {MenuItem} from 'common';
|
||||
import {LanguageStrings} from '../../../store/language/language.store';
|
||||
import {MenuItemRegistry} from './menu-item.registry';
|
||||
|
||||
@Component({
|
||||
|
@ -36,7 +35,6 @@ import {MenuItemRegistry} from './menu-item.registry';
|
|||
})
|
||||
export class MenuItemComponent {
|
||||
@Input() item: MenuItem;
|
||||
@Input() languages: LanguageStrings;
|
||||
|
||||
constructor(protected registry: MenuItemRegistry) {
|
||||
}
|
||||
|
|
|
@ -29,7 +29,9 @@
|
|||
|
||||
<li class="top-nav nav-item dropdown non-grouped">
|
||||
|
||||
<a class="nav-link-nongrouped dropdown-toggle">{{label}}</a>
|
||||
<a class="nav-link-nongrouped dropdown-toggle">
|
||||
<scrm-label [labelKey]="labelKey"></scrm-label>
|
||||
</a>
|
||||
|
||||
<div aria-labelledby="navbarDropdownMenuLink"
|
||||
class="dropdown-menu more-menu submenu"
|
||||
|
|
|
@ -34,7 +34,7 @@ import {MenuItem} from 'common';
|
|||
})
|
||||
export class BaseMenuItemsListComponent {
|
||||
@Input() items: MenuItem[];
|
||||
@Input() label: string;
|
||||
@Input() labelKey: string;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
|
|
@ -27,6 +27,6 @@
|
|||
-->
|
||||
<ndc-dynamic *ngIf="getType"
|
||||
[ndcDynamicComponent]="getType"
|
||||
[ndcDynamicInputs]="{'items': items, 'label': label}">
|
||||
[ndcDynamicInputs]="{'items': items, 'labelKey': labelKey}">
|
||||
</ndc-dynamic>
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ const mockMenuItems = [
|
|||
|
||||
@Component({
|
||||
selector: 'menu-item-list-test-host-component',
|
||||
template: '<scrm-menu-items-list [items]="items" [label]="label"></scrm-menu-items-list>'
|
||||
template: '<scrm-menu-items-list [items]="items" [labelKey]="label"></scrm-menu-items-list>'
|
||||
})
|
||||
class MenuItemListTestHostComponent {
|
||||
items = mockMenuItems;
|
||||
|
|
|
@ -35,7 +35,7 @@ import {MenuItemsListRegistry} from './menu-items-list-registry';
|
|||
})
|
||||
export class MenuItemsListComponent {
|
||||
@Input() items: MenuItem[];
|
||||
@Input() label: string;
|
||||
@Input() labelKey: string;
|
||||
|
||||
constructor(protected registry: MenuItemsListRegistry) {
|
||||
}
|
||||
|
|
|
@ -26,8 +26,13 @@
|
|||
*/
|
||||
-->
|
||||
<ng-container *ngIf="records && records.length">
|
||||
<h4 class="recently-viewed-header">{{languages.appStrings['LBL_LAST_VIEWED'] || ''}}</h4>
|
||||
<div *ngFor="let recentRecord of records" class="nav-item">
|
||||
<a [href]="recentRecord.url" class="nav-link action-link">{{ recentRecord.summary }}</a>
|
||||
<h4 class="recently-viewed-header mt-0 pb-1 pl-2 pr-2">
|
||||
<scrm-label labelKey="LBL_LAST_VIEWED"></scrm-label>
|
||||
</h4>
|
||||
<div *ngFor="let recentRecord of records | slice:0:maxDisplayed" class="nav-item">
|
||||
<a [routerLink]="this.buildRoute(recentRecord)"
|
||||
class="nav-link action-link pb-2 pt-2">
|
||||
{{ recentRecord.attributes.item_summary }}
|
||||
</a>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
|
|
@ -24,19 +24,90 @@
|
|||
* the words "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {RecentRecordsMenuItem} from 'common';
|
||||
import {LanguageStrings} from '../../../store/language/language.store';
|
||||
import {Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges} from '@angular/core';
|
||||
import {RecentlyViewed} from 'common';
|
||||
import {ModuleNavigation} from '../../../services/navigation/module-navigation/module-navigation.service';
|
||||
import {ModuleNameMapper} from '../../../services/navigation/module-name-mapper/module-name-mapper.service';
|
||||
import {SystemConfigStore} from '../../../store/system-config/system-config.store';
|
||||
import {MetadataStore} from '../../../store/metadata/metadata.store.service';
|
||||
import {map} from 'rxjs/operators';
|
||||
import {Subscription} from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-base-menu-recently-viewed',
|
||||
templateUrl: './base-menu-recently-viewed.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class BaseMenuRecentlyViewedComponent {
|
||||
@Input() records: RecentRecordsMenuItem[];
|
||||
@Input() languages: LanguageStrings;
|
||||
export class BaseMenuRecentlyViewedComponent implements OnInit, OnDestroy, OnChanges {
|
||||
@Input() module: string;
|
||||
maxDisplayed: number = 5;
|
||||
records: RecentlyViewed[];
|
||||
protected subs: Subscription[] = [];
|
||||
|
||||
constructor() {
|
||||
|
||||
constructor(
|
||||
protected navigation: ModuleNavigation,
|
||||
protected nameMapper: ModuleNameMapper,
|
||||
protected configs: SystemConfigStore,
|
||||
protected metadata: MetadataStore
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
const ui = this.configs.getConfigValue('ui') ?? {};
|
||||
this.maxDisplayed = parseInt(ui.navigation_max_module_recently_viewed) ?? 5;
|
||||
this.initMetadata$();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
const moduleChanges = changes?.module ?? null;
|
||||
|
||||
if (moduleChanges === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const previousModule = changes?.module?.previousValue ?? '';
|
||||
const currentModule = changes?.module?.currentValue ?? '';
|
||||
if (previousModule !== currentModule) {
|
||||
this.clear();
|
||||
this.initMetadata$();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build route from recently viewed item
|
||||
* @param item
|
||||
*/
|
||||
buildRoute(item: RecentlyViewed): string {
|
||||
const legacyName = item.attributes.module_name ?? '';
|
||||
const module = this.nameMapper.toFrontend(legacyName) ?? '';
|
||||
const id = item.attributes.item_id ?? '';
|
||||
return this.navigation.getRecordRouterLink(module, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init metadata subscription
|
||||
* @protected
|
||||
*/
|
||||
protected initMetadata$(): void {
|
||||
const moduleMeta$ = this.metadata.allModuleMetadata$.pipe(map(value => value[this.module] ?? null));
|
||||
|
||||
this.subs.push(moduleMeta$.subscribe(meta => {
|
||||
this.records = meta?.recentlyViewed ?? null;
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear subscription and data
|
||||
* @protected
|
||||
*/
|
||||
protected clear() {
|
||||
this.records = null;
|
||||
this.subs.forEach(sub => sub.unsubscribe());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,5 +27,5 @@
|
|||
-->
|
||||
<ndc-dynamic *ngIf="getType"
|
||||
[ndcDynamicComponent]="getType"
|
||||
[ndcDynamicInputs]="{'records': records, 'languages': languages}">
|
||||
[ndcDynamicInputs]="{'module': module}">
|
||||
</ndc-dynamic>
|
||||
|
|
|
@ -54,7 +54,7 @@ const recentRecords = [
|
|||
|
||||
@Component({
|
||||
selector: 'menu-recently-viewed-test-host-component',
|
||||
template: '<scrm-menu-recently-viewed [records]="records" [languages]="languages"></scrm-menu-recently-viewed>'
|
||||
template: '<scrm-menu-recently-viewed [records]="records"></scrm-menu-recently-viewed>'
|
||||
})
|
||||
class MenuRecentlyViewedTestHostComponent {
|
||||
records = recentRecords;
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
*/
|
||||
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {RecentRecordsMenuItem} from 'common';
|
||||
import {LanguageStrings} from '../../../store/language/language.store';
|
||||
import {MenuRecentlyViewedRegistry} from './menu-recently-viewed-registry';
|
||||
|
||||
@Component({
|
||||
|
@ -35,8 +33,7 @@ import {MenuRecentlyViewedRegistry} from './menu-recently-viewed-registry';
|
|||
styleUrls: []
|
||||
})
|
||||
export class MenuRecentlyViewedComponent {
|
||||
@Input() records: RecentRecordsMenuItem[];
|
||||
@Input() languages: LanguageStrings;
|
||||
@Input() module: string;
|
||||
|
||||
constructor(protected registry: MenuRecentlyViewedRegistry) {
|
||||
}
|
||||
|
|
|
@ -61,14 +61,11 @@
|
|||
[link]="subitem.link"></scrm-menu-item-link>
|
||||
</li>
|
||||
|
||||
<ng-template
|
||||
[ngIf]="item.recentRecords && item.recentRecords.length">
|
||||
<h4 class="recently-viewed-header">RECENTLY VIEWED</h4>
|
||||
<li *ngFor="let rec of item.recentRecords" class="nav-item">
|
||||
<a class="mobile-nav-link action-link"
|
||||
href="#/{{ rec.showSelectModalmoduleName }}/{{ rec.itemId }}">{{ rec.itemSummary }}</a>
|
||||
<ng-container *ngIf="item && item.module">
|
||||
<li (click)="onClose && onClose()">
|
||||
<scrm-menu-recently-viewed [module]="item.module"></scrm-menu-recently-viewed>
|
||||
</li>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
|
||||
</ng-template>
|
||||
</ngb-panel>
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
<ng-container *ngIf="mainNavLink">
|
||||
<div class="mobile-menu-items">
|
||||
|
||||
<li (click)="changeSubNav($event, item.submenu, navigationType)" *ngFor="let item of mainItems"
|
||||
<li (click)="changeSubNav($event, item.submenu, navigationType, item)" *ngFor="let item of mainItems"
|
||||
class=" d-flex align-items-center">
|
||||
<a class="flex-grow-1 mobile-nav-link pl-3 pr-3 pt-2 pb-2">{{ item.link.label }}</a>
|
||||
<scrm-image class="sicon-xs mobile-nav-arrow pl-3 pr-3" image="arrow_right_filled"
|
||||
|
@ -50,7 +50,7 @@
|
|||
</li>
|
||||
|
||||
<ng-container>
|
||||
<li (click)="changeSubNav($event, all, 'gm')"
|
||||
<li (click)="changeSubNav($event, all, 'gm', null)"
|
||||
class=" d-flex align-items-center">
|
||||
<a class="flex-grow-1 mobile-nav-link pl-3 pr-3 pt-2 pb-2">
|
||||
<scrm-label labelKey="LBL_MORE"></scrm-label>
|
||||
|
@ -68,6 +68,14 @@
|
|||
|
||||
<scrm-mobile-module-menu [items]="submenu" [onClose]="onClose"></scrm-mobile-module-menu>
|
||||
|
||||
<ng-container *ngIf="subNavItem && subNavItem.module">
|
||||
<div class="mobile-menu-items">
|
||||
<li (click)="onClose && onClose()" class="">
|
||||
<scrm-menu-recently-viewed [module]="subNavItem.module"></scrm-menu-recently-viewed>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="subNavigationType === 'gm'">
|
||||
|
|
|
@ -41,6 +41,7 @@ export class BaseMobileMenuComponent implements OnInit {
|
|||
|
||||
mainItems: MenuItem[];
|
||||
submenu: MenuItem[] = [];
|
||||
subNavItem: MenuItem;
|
||||
|
||||
subNavigationType = 'mm';
|
||||
backLink = false;
|
||||
|
@ -64,11 +65,13 @@ export class BaseMobileMenuComponent implements OnInit {
|
|||
* @param {object} event triggered
|
||||
* @param {object} items
|
||||
* @param navigationType
|
||||
* @param item
|
||||
*/
|
||||
public changeSubNav(event: Event, items: MenuItem[], navigationType: string): void {
|
||||
public changeSubNav(event: Event, items: MenuItem[], navigationType: string, item: MenuItem): void {
|
||||
this.mobileSubNav = !this.mobileSubNav;
|
||||
this.backLink = !this.backLink;
|
||||
this.mainNavLink = !this.mainNavLink;
|
||||
this.subNavItem = item;
|
||||
this.submenu = items;
|
||||
this.subNavigationType = navigationType;
|
||||
}
|
||||
|
|
|
@ -29,10 +29,7 @@ import {CurrentUserModel} from './current-user-model';
|
|||
import {AllMenuModel} from './all-menu-model';
|
||||
import {LogoModel} from '../logo/logo-model';
|
||||
import {MenuItem} from 'common';
|
||||
import {LanguageStringMap, LanguageStrings} from '../../store/language/language.store';
|
||||
import {GroupedTab, NavbarModuleMap, Navigation, UserActionMenu} from '../../store/navigation/navigation.store';
|
||||
import {UserPreferenceMap} from '../../store/user-preference/user-preference.store';
|
||||
import {AppState} from '../../store/app-state/app-state.store';
|
||||
|
||||
export interface NavbarModel {
|
||||
authenticated: boolean;
|
||||
|
@ -48,24 +45,19 @@ export interface NavbarModel {
|
|||
|
||||
build(
|
||||
navigation: Navigation,
|
||||
languages: LanguageStrings,
|
||||
userPreferences: UserPreferenceMap,
|
||||
currentUser: CurrentUserModel,
|
||||
appState: AppState,
|
||||
itemThreshold: number
|
||||
itemThreshold: number,
|
||||
): void;
|
||||
|
||||
buildGroupTabMenu(
|
||||
items: string[],
|
||||
modules: NavbarModuleMap,
|
||||
languages: LanguageStrings,
|
||||
threshold: number,
|
||||
groupedTabs: GroupedTab[],
|
||||
sort: boolean
|
||||
): void;
|
||||
|
||||
buildUserActionMenu(
|
||||
appStrings: LanguageStringMap,
|
||||
userActionMenu: UserActionMenu[],
|
||||
currentUser: CurrentUserModel
|
||||
): void;
|
||||
|
|
|
@ -29,7 +29,7 @@ import {LogoAbstract} from '../logo/logo-abstract';
|
|||
import {CurrentUserModel} from './current-user-model';
|
||||
import {ActionLinkModel} from './action-link-model';
|
||||
import {MenuItem, ready, User} from 'common';
|
||||
import {LanguageStringMap, LanguageStrings} from '../../store/language/language.store';
|
||||
import {LanguageStore} from '../../store/language/language.store';
|
||||
import {
|
||||
GroupedTab,
|
||||
NavbarModule,
|
||||
|
@ -39,9 +39,9 @@ import {
|
|||
} from '../../store/navigation/navigation.store';
|
||||
import {LinkTarget} from './link-target';
|
||||
import {RouteConverter} from '../../services/navigation/route-converter/route-converter.service';
|
||||
import {UserPreferenceMap} from '../../store/user-preference/user-preference.store';
|
||||
import {UserPreferenceStore} from '../../store/user-preference/user-preference.store';
|
||||
import {ModuleNavigation} from '../../services/navigation/module-navigation/module-navigation.service';
|
||||
import {AppState} from '../../store/app-state/app-state.store';
|
||||
import {AppStateStore} from '../../store/app-state/app-state.store';
|
||||
|
||||
export class NavbarAbstract implements NavbarModel {
|
||||
authenticated = true;
|
||||
|
@ -66,7 +66,10 @@ export class NavbarAbstract implements NavbarModel {
|
|||
|
||||
constructor(
|
||||
private routeConverter: RouteConverter,
|
||||
protected moduleNavigation: ModuleNavigation
|
||||
protected moduleNavigation: ModuleNavigation,
|
||||
protected preferences: UserPreferenceStore,
|
||||
protected language: LanguageStore,
|
||||
protected appState: AppStateStore,
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -85,12 +88,10 @@ export class NavbarAbstract implements NavbarModel {
|
|||
/**
|
||||
* Build user action menu
|
||||
*
|
||||
* @param {object} appStrings map
|
||||
* @param {[]} userActionMenu info
|
||||
* @param {object} currentUser info
|
||||
*/
|
||||
public buildUserActionMenu(
|
||||
appStrings: LanguageStringMap,
|
||||
userActionMenu: UserActionMenu[],
|
||||
currentUser: CurrentUserModel
|
||||
): void {
|
||||
|
@ -115,7 +116,7 @@ export class NavbarAbstract implements NavbarModel {
|
|||
url = this.routeConverter.toFrontEndLink(url);
|
||||
}
|
||||
|
||||
const label = appStrings[subMenu.labelKey];
|
||||
const label = this.language.getAppString(subMenu.labelKey) ?? '';
|
||||
|
||||
this.globalActions.push({
|
||||
link: {
|
||||
|
@ -133,39 +134,27 @@ export class NavbarAbstract implements NavbarModel {
|
|||
* Build navbar
|
||||
*
|
||||
* @param {object} navigation info
|
||||
* @param {object} language map
|
||||
* @param {object} userPreferences info
|
||||
* @param {object} currentUser info
|
||||
* @param {object} appState info
|
||||
* @param {number} maxTabs to display
|
||||
*/
|
||||
public build(
|
||||
navigation: Navigation,
|
||||
language: LanguageStrings,
|
||||
userPreferences: UserPreferenceMap,
|
||||
currentUser: CurrentUserModel,
|
||||
appState: AppState,
|
||||
maxTabs: number
|
||||
maxTabs: number,
|
||||
): void {
|
||||
|
||||
this.resetMenu();
|
||||
this.buildUserActionMenu(navigation.userActionMenu, currentUser);
|
||||
|
||||
if (!ready([language.appStrings, language.modStrings, language.appListStrings, userPreferences, currentUser])) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildUserActionMenu(language.appStrings, navigation.userActionMenu, currentUser);
|
||||
|
||||
const navigationParadigm = userPreferences.navigation_paradigm.toString();
|
||||
const sort = userPreferences.sort_modules_by_name.toString() === 'on';
|
||||
const navigationParadigm = this.preferences.getUserPreference('navigation_paradigm');
|
||||
const sort = this.preferences.getUserPreference('sort_modules_by_name') === 'on';
|
||||
|
||||
if (navigationParadigm === 'm') {
|
||||
this.buildModuleNavigation(navigation, language, appState, maxTabs, sort);
|
||||
this.buildModuleNavigation(navigation, maxTabs, sort);
|
||||
return;
|
||||
}
|
||||
|
||||
if (navigationParadigm === 'gm') {
|
||||
this.buildGroupedNavigation(navigation, language, appState, maxTabs, sort);
|
||||
this.buildGroupedNavigation(navigation, maxTabs, sort);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +164,6 @@ export class NavbarAbstract implements NavbarModel {
|
|||
*
|
||||
* @param {[]} items list
|
||||
* @param {object} modules info
|
||||
* @param {object} languages map
|
||||
* @param {number} threshold limit
|
||||
* @param {object} groupedTabs info
|
||||
* @param {boolean} sort flag
|
||||
|
@ -183,7 +171,6 @@ export class NavbarAbstract implements NavbarModel {
|
|||
public buildGroupTabMenu(
|
||||
items: string[],
|
||||
modules: NavbarModuleMap,
|
||||
languages: LanguageStrings,
|
||||
threshold: number,
|
||||
groupedTabs: GroupedTab[],
|
||||
sort: boolean
|
||||
|
@ -194,7 +181,7 @@ export class NavbarAbstract implements NavbarModel {
|
|||
|
||||
if (items && items.length > 0) {
|
||||
items.forEach((module) => {
|
||||
moreItems.push(this.buildTabMenuItem(module, modules[module], languages));
|
||||
moreItems.push(this.buildTabMenuItem(module, modules[module]));
|
||||
});
|
||||
|
||||
if (sort) {
|
||||
|
@ -210,7 +197,6 @@ export class NavbarAbstract implements NavbarModel {
|
|||
groupedTab.labelKey,
|
||||
groupedTab.modules,
|
||||
modules,
|
||||
languages,
|
||||
sort
|
||||
));
|
||||
}
|
||||
|
@ -232,71 +218,63 @@ export class NavbarAbstract implements NavbarModel {
|
|||
* Build module navigation
|
||||
*
|
||||
* @param {object} navigation info
|
||||
* @param {object} languages map
|
||||
* @param {object} appState info
|
||||
* @param {number} maxTabs to use
|
||||
* @param {boolean} sort flag
|
||||
*/
|
||||
protected buildModuleNavigation(
|
||||
navigation: Navigation,
|
||||
languages: LanguageStrings,
|
||||
appState: AppState,
|
||||
maxTabs: number,
|
||||
sort: boolean
|
||||
sort: boolean,
|
||||
): void {
|
||||
|
||||
if (!ready([navigation.tabs, navigation.modules])) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildTabMenu(navigation.tabs, navigation.modules, languages, maxTabs, appState, sort);
|
||||
this.buildSelectedModule(navigation, languages, appState);
|
||||
this.buildTabMenu(navigation.tabs, navigation.modules, maxTabs, sort);
|
||||
this.buildSelectedModule(navigation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build grouped navigation
|
||||
*
|
||||
* @param {object} navigation info
|
||||
* @param {object} languages map
|
||||
* @param {object} appState info
|
||||
* @param {number} maxTabs to use
|
||||
* @param {boolean} sort flag
|
||||
*/
|
||||
protected buildGroupedNavigation(
|
||||
navigation: Navigation,
|
||||
languages: LanguageStrings,
|
||||
appState: AppState,
|
||||
maxTabs: number,
|
||||
sort: boolean
|
||||
sort: boolean,
|
||||
): void {
|
||||
|
||||
if (!ready([navigation.tabs, navigation.modules, navigation.groupedTabs])) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildGroupTabMenu(navigation.tabs, navigation.modules, languages, maxTabs, navigation.groupedTabs, sort);
|
||||
this.buildSelectedModule(navigation, languages, appState);
|
||||
this.buildGroupTabMenu(navigation.tabs, navigation.modules, maxTabs, navigation.groupedTabs, sort);
|
||||
this.buildSelectedModule(navigation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build selected module
|
||||
*
|
||||
* @param {object} navigation info
|
||||
* @param {object} languages map
|
||||
* @param {object} appState info
|
||||
*/
|
||||
protected buildSelectedModule(navigation: Navigation, languages: LanguageStrings, appState: AppState): void {
|
||||
if (!appState || !appState.module || appState.module === 'home') {
|
||||
protected buildSelectedModule(
|
||||
navigation: Navigation,
|
||||
): void {
|
||||
const module = this.appState.getModule() ?? '';
|
||||
|
||||
if (module === '' || module === 'home') {
|
||||
return;
|
||||
}
|
||||
|
||||
const module = appState.module;
|
||||
|
||||
if (!navigation.modules[module]) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.current = this.buildTabMenuItem(module, navigation.modules[module], languages);
|
||||
this.current = this.buildTabMenuItem(module, navigation.modules[module]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -304,18 +282,14 @@ export class NavbarAbstract implements NavbarModel {
|
|||
*
|
||||
* @param {[]} items list
|
||||
* @param {object} modules info
|
||||
* @param {object} languages map
|
||||
* @param {number} threshold limit
|
||||
* @param {object} appState info
|
||||
* @param {boolean} sort flag
|
||||
*/
|
||||
protected buildTabMenu(
|
||||
items: string[],
|
||||
modules: NavbarModuleMap,
|
||||
languages: LanguageStrings,
|
||||
threshold: number,
|
||||
appState: AppState,
|
||||
sort: boolean
|
||||
sort: boolean,
|
||||
): void {
|
||||
|
||||
const navItems = [];
|
||||
|
@ -330,9 +304,9 @@ export class NavbarAbstract implements NavbarModel {
|
|||
let count = 0;
|
||||
items.forEach((module: string) => {
|
||||
|
||||
const item = this.buildTabMenuItem(module, modules[module], languages);
|
||||
const item = this.buildTabMenuItem(module, modules[module]);
|
||||
|
||||
if (module === 'home' || appState.module === module || count >= threshold) {
|
||||
if (module === 'home' || this.appState.getModule() === module || count >= threshold) {
|
||||
moreItems.push(item);
|
||||
} else {
|
||||
navItems.push(item);
|
||||
|
@ -357,7 +331,6 @@ export class NavbarAbstract implements NavbarModel {
|
|||
* @param {string} moduleLabel to display
|
||||
* @param {object} groupedModules list
|
||||
* @param {object} modules list
|
||||
* @param {object} languages map
|
||||
* @param {boolean} sort flag
|
||||
*
|
||||
* @returns {object} group tab menu item
|
||||
|
@ -366,19 +339,18 @@ export class NavbarAbstract implements NavbarModel {
|
|||
moduleLabel: string,
|
||||
groupedModules: any[],
|
||||
modules: NavbarModuleMap,
|
||||
languages: LanguageStrings,
|
||||
sort: boolean
|
||||
): any {
|
||||
|
||||
return {
|
||||
link: {
|
||||
label: (languages.appStrings && languages.appStrings[moduleLabel]) || moduleLabel,
|
||||
label: this.language.getAppString(moduleLabel) || moduleLabel,
|
||||
url: '',
|
||||
route: null,
|
||||
params: null
|
||||
},
|
||||
icon: '',
|
||||
submenu: this.buildGroupedMenu(groupedModules, modules, languages, sort)
|
||||
submenu: this.buildGroupedMenu(groupedModules, modules, sort)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -387,7 +359,6 @@ export class NavbarAbstract implements NavbarModel {
|
|||
*
|
||||
* @param {object} groupedModules info
|
||||
* @param {object} modules map
|
||||
* @param {object} languages maps
|
||||
* @param {boolean} sort flag
|
||||
*
|
||||
* @returns {[]} menu item array
|
||||
|
@ -395,7 +366,6 @@ export class NavbarAbstract implements NavbarModel {
|
|||
protected buildGroupedMenu(
|
||||
groupedModules: any[],
|
||||
modules: NavbarModuleMap,
|
||||
languages: LanguageStrings,
|
||||
sort: boolean
|
||||
): MenuItem[] {
|
||||
|
||||
|
@ -410,7 +380,7 @@ export class NavbarAbstract implements NavbarModel {
|
|||
return;
|
||||
}
|
||||
|
||||
const moduleMenuItem = this.buildTabMenuItem(groupedModule, module, languages);
|
||||
const moduleMenuItem = this.buildTabMenuItem(groupedModule, module);
|
||||
|
||||
if (groupedModule === 'home') {
|
||||
homeMenuItem = moduleMenuItem;
|
||||
|
@ -436,27 +406,26 @@ export class NavbarAbstract implements NavbarModel {
|
|||
*
|
||||
* @param {string} module name
|
||||
* @param {object} moduleInfo info
|
||||
* @param {object} languages object
|
||||
*
|
||||
* @returns {object} menuItem
|
||||
*/
|
||||
protected buildTabMenuItem(
|
||||
module: string,
|
||||
moduleInfo: NavbarModule,
|
||||
languages: LanguageStrings,
|
||||
): MenuItem {
|
||||
|
||||
const moduleRoute = this.moduleNavigation.getModuleRoute(moduleInfo);
|
||||
|
||||
const menuItem = {
|
||||
link: {
|
||||
label: this.moduleNavigation.getModuleLabel(moduleInfo, languages.appListStrings),
|
||||
label: this.moduleNavigation.getModuleLabel(moduleInfo, this.language.getLanguageStrings()?.appListStrings ?? {}),
|
||||
url: moduleRoute.url,
|
||||
route: moduleRoute.route,
|
||||
params: null
|
||||
},
|
||||
icon: (module === 'home') ? 'home' : '',
|
||||
submenu: []
|
||||
submenu: [],
|
||||
module: module ?? null
|
||||
};
|
||||
|
||||
if (moduleInfo) {
|
||||
|
@ -466,7 +435,7 @@ export class NavbarAbstract implements NavbarModel {
|
|||
|
||||
menuItem.submenu.push({
|
||||
link: {
|
||||
label: this.moduleNavigation.getActionLabel(module, subMenu, languages),
|
||||
label: this.moduleNavigation.getActionLabel(module, subMenu, this.language.getLanguageStrings()),
|
||||
url: moduleActionRoute.url,
|
||||
route: moduleActionRoute.route,
|
||||
params: moduleActionRoute.params
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue