mirror of
https://github.com/SuiteCRM/SuiteCRM-Core.git
synced 2025-09-04 10:14:13 +08:00
Fix navbar rendering
- Fix: items still being displayed when navigation cache is cleared - Fix: duplicate entries were added to the more dropdown - Move the ready checks to the navbar abstract - Move the display type decision logic to the navbar abstract - Add ready method to be easier to check if dependencies are loaded - Cleanup -- add js doc -- format code
This commit is contained in:
parent
77c7057328
commit
7195848d86
4 changed files with 187 additions and 69 deletions
|
@ -2,9 +2,10 @@ import {ActionLinkModel} from './action-link-model';
|
|||
import {CurrentUserModel} from './current-user-model';
|
||||
import {AllMenuModel} from './all-menu-model';
|
||||
import {LogoModel} from '../logo/logo-model';
|
||||
import {NavbarModuleMap, GroupedTab} from '@base/facades/navigation/navigation.facade';
|
||||
import {GroupedTab, NavbarModuleMap} from '@base/facades/navigation/navigation.facade';
|
||||
import {LanguageListStringMap, LanguageStringMap} from '@base/facades/language/language.facade';
|
||||
import {MenuItem} from '@components/navbar/navbar.abstract';
|
||||
import {UserPreferenceMap} from '@base/facades/user-preference/user-preference.facade';
|
||||
|
||||
export interface NavbarModel {
|
||||
authenticated: boolean;
|
||||
|
@ -17,6 +18,17 @@ export interface NavbarModel {
|
|||
|
||||
resetMenu(): void;
|
||||
|
||||
build(
|
||||
tabs: string[],
|
||||
modules: NavbarModuleMap,
|
||||
appStrings: LanguageStringMap,
|
||||
modStrings: LanguageListStringMap,
|
||||
appListStrings: LanguageListStringMap,
|
||||
menuItemThreshold: number,
|
||||
groupedTabs: GroupedTab[],
|
||||
userPreferences: UserPreferenceMap
|
||||
): void;
|
||||
|
||||
buildGroupTabMenu(
|
||||
items: string[],
|
||||
modules: NavbarModuleMap,
|
||||
|
@ -25,7 +37,7 @@ export interface NavbarModel {
|
|||
appListStrings: LanguageListStringMap,
|
||||
menuItemThreshold: number,
|
||||
groupedTabs: GroupedTab[]
|
||||
): void;
|
||||
): void;
|
||||
|
||||
buildTabMenu(
|
||||
items: string[],
|
||||
|
@ -33,5 +45,5 @@ export interface NavbarModel {
|
|||
appStrings: LanguageStringMap,
|
||||
modStrings: LanguageListStringMap,
|
||||
appListStrings: LanguageListStringMap,
|
||||
menuItemThreshold: number): void;
|
||||
menuItemThreshold: number): void;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import {NavbarModel} from './navbar-model';
|
||||
import {LogoAbstract} from '../logo/logo-abstract';
|
||||
import {NavbarModule, NavbarModuleMap, GroupedTab} from "@base/facades/navigation/navigation.facade";
|
||||
import {GroupedTab, NavbarModuleMap} from '@base/facades/navigation/navigation.facade';
|
||||
import {LanguageListStringMap, LanguageStringMap} from '@base/facades/language/language.facade';
|
||||
|
||||
import {CurrentUserModel} from './current-user-model';
|
||||
import {ActionLinkModel} from './action-link-model';
|
||||
import {ready} from '@base/utils/object-utils';
|
||||
import {UserPreferenceMap} from '@base/facades/user-preference/user-preference.facade';
|
||||
|
||||
export interface RecentRecordsMenuItem {
|
||||
summary: string;
|
||||
|
@ -16,7 +18,7 @@ export interface MenuItem {
|
|||
label: string;
|
||||
url: string;
|
||||
route?: string;
|
||||
params?: { [key: string]: string; }
|
||||
params?: { [key: string]: string };
|
||||
};
|
||||
icon: string;
|
||||
submenu: MenuItem[];
|
||||
|
@ -65,28 +67,96 @@ export class NavbarAbstract implements NavbarModel {
|
|||
};
|
||||
menu: MenuItem[] = [];
|
||||
|
||||
public resetMenu() {
|
||||
/**
|
||||
* Reset menus
|
||||
*/
|
||||
public resetMenu(): void {
|
||||
this.menu = [];
|
||||
this.all.modules = [];
|
||||
this.all.extra = [];
|
||||
}
|
||||
|
||||
public buildGroupTabMenu(items: string[], modules: NavbarModuleMap, appStrings: LanguageStringMap,
|
||||
modStrings: LanguageListStringMap, appListStrings: LanguageListStringMap, threshold: number, groupedTabs: GroupedTab[]): void
|
||||
{
|
||||
/**
|
||||
* Build navbar
|
||||
* @param tabs
|
||||
* @param modules
|
||||
* @param appStrings
|
||||
* @param modStrings
|
||||
* @param appListStrings
|
||||
* @param menuItemThreshold
|
||||
* @param groupedTabs
|
||||
* @param userPreferences
|
||||
*/
|
||||
public build(
|
||||
tabs: string[],
|
||||
modules: NavbarModuleMap,
|
||||
appStrings: LanguageStringMap,
|
||||
modStrings: LanguageListStringMap,
|
||||
appListStrings: LanguageListStringMap,
|
||||
menuItemThreshold: number,
|
||||
groupedTabs: GroupedTab[],
|
||||
userPreferences: UserPreferenceMap
|
||||
): void {
|
||||
|
||||
this.resetMenu();
|
||||
|
||||
if (!ready([tabs, modules, appStrings, modStrings, appListStrings, userPreferences])) {
|
||||
return;
|
||||
}
|
||||
|
||||
const navigationParadigm = userPreferences.navigation_paradigm;
|
||||
|
||||
if (navigationParadigm.toString() === 'm') {
|
||||
this.buildTabMenu(tabs, modules, appStrings, modStrings, appListStrings, menuItemThreshold);
|
||||
return;
|
||||
}
|
||||
|
||||
if (navigationParadigm.toString() === 'gm') {
|
||||
this.buildGroupTabMenu(tabs, modules, appStrings, modStrings, appListStrings, menuItemThreshold, groupedTabs);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Group tab menu
|
||||
* @param items
|
||||
* @param modules
|
||||
* @param appStrings
|
||||
* @param modStrings
|
||||
* @param appListStrings
|
||||
* @param threshold
|
||||
* @param groupedTabs
|
||||
*/
|
||||
public buildGroupTabMenu(
|
||||
items: string[],
|
||||
modules: NavbarModuleMap,
|
||||
appStrings: LanguageStringMap,
|
||||
modStrings: LanguageListStringMap,
|
||||
appListStrings: LanguageListStringMap,
|
||||
threshold: number,
|
||||
groupedTabs: GroupedTab[]): void {
|
||||
|
||||
const navItems = [];
|
||||
const moreItems = [];
|
||||
|
||||
if (!items || items.length === 0) {
|
||||
this.menu = navItems;
|
||||
this.all.extra = moreItems;
|
||||
this.all.modules = moreItems;
|
||||
return;
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
groupedTabs.forEach((groupedTab: any) => {
|
||||
|
||||
|
||||
if (count <= threshold) {
|
||||
navItems.push(this.buildTabGroupedMenuItem(groupedTab.labelKey, groupedTab.modules, modules, appStrings, modStrings, appListStrings));
|
||||
navItems.push(this.buildTabGroupedMenuItem(
|
||||
groupedTab.labelKey,
|
||||
groupedTab.modules,
|
||||
modules,
|
||||
appStrings,
|
||||
modStrings,
|
||||
appListStrings
|
||||
));
|
||||
}
|
||||
|
||||
count++;
|
||||
|
@ -94,23 +164,31 @@ export class NavbarAbstract implements NavbarModel {
|
|||
|
||||
this.menu = navItems;
|
||||
this.all.modules = moreItems;
|
||||
this.all.extra = moreItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build tab / module menu
|
||||
* @param items
|
||||
* @param modules
|
||||
* @param appStrings
|
||||
* @param modStrings
|
||||
* @param appListStrings
|
||||
* @param threshold
|
||||
*/
|
||||
public buildTabMenu(items: string[],
|
||||
modules: NavbarModuleMap,
|
||||
appStrings: LanguageStringMap,
|
||||
modStrings: LanguageListStringMap,
|
||||
appListStrings: LanguageListStringMap,
|
||||
threshold: number
|
||||
): void {
|
||||
modules: NavbarModuleMap,
|
||||
appStrings: LanguageStringMap,
|
||||
modStrings: LanguageListStringMap,
|
||||
appListStrings: LanguageListStringMap,
|
||||
threshold: number
|
||||
): void {
|
||||
|
||||
const navItems = [];
|
||||
const moreItems = [];
|
||||
|
||||
if (!items || items.length === 0) {
|
||||
this.menu = navItems;
|
||||
this.all.extra = moreItems;
|
||||
this.all.modules = moreItems;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -132,9 +210,17 @@ export class NavbarAbstract implements NavbarModel {
|
|||
|
||||
this.menu = navItems;
|
||||
this.all.modules = moreItems;
|
||||
this.all.extra = moreItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Grouped Tab menu item
|
||||
* @param moduleLabel to display
|
||||
* @param groupedModules list
|
||||
* @param modules list
|
||||
* @param appStrings list
|
||||
* @param modStrings list
|
||||
* @param appListStrings list
|
||||
*/
|
||||
public buildTabGroupedMenuItem(
|
||||
moduleLabel: string,
|
||||
groupedModules: any[],
|
||||
|
@ -166,6 +252,14 @@ export class NavbarAbstract implements NavbarModel {
|
|||
return menuItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Grouped menu
|
||||
* @param groupedModules
|
||||
* @param modules
|
||||
* @param appStrings
|
||||
* @param modStrings
|
||||
* @param appListStrings
|
||||
*/
|
||||
public buildGroupedMenu(
|
||||
groupedModules: any[],
|
||||
modules: NavbarModuleMap,
|
||||
|
@ -178,25 +272,33 @@ export class NavbarAbstract implements NavbarModel {
|
|||
|
||||
groupedModules.forEach((groupedModule) => {
|
||||
|
||||
let module = modules[groupedModule];
|
||||
const module = modules[groupedModule];
|
||||
|
||||
if (module === undefined) {
|
||||
if (!module) {
|
||||
return;
|
||||
}
|
||||
|
||||
groupedItems.push(this.buildTabMenuItem(groupedModule, module, appStrings, modStrings, appListStrings));
|
||||
});
|
||||
|
||||
|
||||
return groupedItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build module menu items
|
||||
* @param module
|
||||
* @param moduleInfo
|
||||
* @param appStrings
|
||||
* @param modStrings
|
||||
* @param appListStrings
|
||||
*/
|
||||
public buildTabMenuItem(
|
||||
module: string,
|
||||
moduleInfo: any,
|
||||
appStrings: LanguageStringMap,
|
||||
modStrings: LanguageListStringMap,
|
||||
appListStrings: LanguageListStringMap
|
||||
): MenuItem {
|
||||
): MenuItem {
|
||||
|
||||
let moduleUrl = (moduleInfo && moduleInfo.defaultRoute) || moduleInfo.defaultRoute;
|
||||
let moduleRoute = null;
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
import {Component, OnInit, HostListener} from '@angular/core';
|
||||
import {Component, HostListener, OnInit} from '@angular/core';
|
||||
import {ApiService} from '../../services/api/api.service';
|
||||
import {NavbarModel} from './navbar-model';
|
||||
import {NavbarAbstract} from './navbar.abstract';
|
||||
import {combineLatest, Observable} from 'rxjs';
|
||||
|
||||
import {NavbarModuleMap, NavigationFacade, GroupedTab} from '@base/facades/navigation/navigation.facade';
|
||||
import {NavbarModuleMap, NavigationFacade} from '@base/facades/navigation/navigation.facade';
|
||||
import {LanguageFacade, LanguageListStringMap, LanguageStringMap} from '@base/facades/language/language.facade';
|
||||
|
||||
import {UserPreferenceMap, UserPreferenceFacade} from '@base/facades/user-preference/user-preference.facade';
|
||||
import {UserPreferenceFacade, UserPreferenceMap} from '@base/facades/user-preference/user-preference.facade';
|
||||
|
||||
import {map} from 'rxjs/operators';
|
||||
import { exists } from 'fs';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-navbar-ui',
|
||||
|
@ -44,55 +43,29 @@ export class NavbarUiComponent implements OnInit {
|
|||
groupedTabs$: Observable<any> = this.navigationFacade.groupedTabs$;
|
||||
|
||||
vm$ = combineLatest([
|
||||
this.tabs$,
|
||||
this.modules$,
|
||||
this.appStrings$,
|
||||
this.appListStrings$,
|
||||
this.modStrings$,
|
||||
this.tabs$,
|
||||
this.modules$,
|
||||
this.appStrings$,
|
||||
this.appListStrings$,
|
||||
this.modStrings$,
|
||||
this.userPreferences$,
|
||||
this.groupedTabs$
|
||||
]).pipe(
|
||||
map((
|
||||
[
|
||||
map(([tabs, modules, appStrings, appListStrings, modStrings, userPreferences, groupedTabs]) => {
|
||||
|
||||
this.navbar.build(
|
||||
tabs,
|
||||
modules,
|
||||
appStrings,
|
||||
appListStrings,
|
||||
modStrings,
|
||||
userPreferences,
|
||||
groupedTabs
|
||||
]) => {
|
||||
|
||||
if (tabs && tabs.length > 0 &&
|
||||
modules && Object.keys(modules).length > 0 &&
|
||||
appStrings && Object.keys(appStrings).length > 0 &&
|
||||
modStrings && Object.keys(modStrings).length > 0 &&
|
||||
appListStrings && Object.keys(appListStrings).length > 0 &&
|
||||
userPreferences['navigation_paradigm'] && userPreferences['navigation_paradigm'].toString() == "m"
|
||||
) {
|
||||
this.navbar.resetMenu();
|
||||
this.navbar.buildTabMenu(tabs, modules, appStrings, modStrings, appListStrings, this.menuItemThreshold);
|
||||
}
|
||||
|
||||
if (tabs && tabs.length > 0 &&
|
||||
modules && Object.keys(modules).length > 0 &&
|
||||
appStrings && Object.keys(appStrings).length > 0 &&
|
||||
modStrings && Object.keys(modStrings).length > 0 &&
|
||||
appListStrings && Object.keys(appListStrings).length > 0 &&
|
||||
userPreferences['navigation_paradigm'] && userPreferences['navigation_paradigm'].toString() == "gm"
|
||||
) {
|
||||
this.navbar.resetMenu();
|
||||
this.navbar.buildGroupTabMenu(tabs, modules, appStrings, modStrings, appListStrings, this.menuItemThreshold, groupedTabs);
|
||||
}
|
||||
appListStrings,
|
||||
this.menuItemThreshold,
|
||||
groupedTabs,
|
||||
userPreferences
|
||||
)
|
||||
|
||||
return {
|
||||
tabs,
|
||||
modules,
|
||||
appStrings,
|
||||
appListStrings,
|
||||
modStrings,
|
||||
userPreferences,
|
||||
groupedTabs
|
||||
tabs, modules, appStrings, appListStrings, modStrings, userPreferences, groupedTabs
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
|
@ -5,3 +5,34 @@
|
|||
* @returns any
|
||||
*/
|
||||
export const deepClone = (obj: any): any => JSON.parse(JSON.stringify(obj));
|
||||
|
||||
/**
|
||||
* Check if all entries have been loaded and are ready to use
|
||||
*
|
||||
* @param entries
|
||||
* @returns boolean
|
||||
*/
|
||||
export const ready = (entries: (Array<any> | Record<string, any>)[]): boolean => {
|
||||
let areReady = true;
|
||||
|
||||
entries.every(entry => {
|
||||
|
||||
if (!entry) {
|
||||
areReady = false;
|
||||
return false;
|
||||
}
|
||||
if (Array.isArray(entry) && entry.length <= 0) {
|
||||
areReady = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof entry === 'object' && Object.keys(entry).length <= 0) {
|
||||
areReady = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return areReady;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue