Integrate admin panel to backend
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* SuiteCRM is a customer relationship management program developed by SalesAgility Ltd.
|
||||
* Copyright (C) 2023 SalesAgility Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License version 3 as published by the
|
||||
* Free Software Foundation with the addition of the following permission added
|
||||
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
|
||||
* IN WHICH THE COPYRIGHT IS OWNED BY SALESAGILITY, SALESAGILITY DISCLAIMS THE
|
||||
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
*
|
||||
* 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 Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License
|
||||
* version 3, these Appropriate Legal Notices must retain the display of the
|
||||
* "Supercharged by SuiteCRM" logo. If the display of the logos is not reasonably
|
||||
* feasible for technical reasons, the Appropriate Legal Notices must display
|
||||
* the words "Supercharged by SuiteCRM".
|
||||
*/
|
||||
import {ObjectMap} from 'common';
|
||||
|
||||
export interface AdminMetadata {
|
||||
adminPanel?: AdminMetadataModel[];
|
||||
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface AdminMetadataModel {
|
||||
titleLabelKey: string,
|
||||
descriptionLabelKey: string,
|
||||
linkGroup: AdminLinkGroupModel[],
|
||||
icon: string
|
||||
}
|
||||
|
||||
export interface AdminLinkGroupModel {
|
||||
[key: string]: any;
|
||||
|
||||
category?: string,
|
||||
descriptionKey?: string,
|
||||
titleKey?: string,
|
||||
icon?: string
|
||||
link?: string,
|
||||
params?: ObjectMap
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
* SuiteCRM is a customer relationship management program developed by SalesAgility Ltd.
|
||||
* Copyright (C) 2021 SalesAgility Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License version 3 as published by the
|
||||
* Free Software Foundation with the addition of the following permission added
|
||||
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
|
||||
* IN WHICH THE COPYRIGHT IS OWNED BY SALESAGILITY, SALESAGILITY DISCLAIMS THE
|
||||
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
*
|
||||
* 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 Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License
|
||||
* version 3, these Appropriate Legal Notices must retain the display of the
|
||||
* "Supercharged by SuiteCRM" logo. If the display of the logos is not reasonably
|
||||
* feasible for technical reasons, the Appropriate Legal Notices must display
|
||||
* the words "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
import {Injectable} from '@angular/core';
|
||||
import {BehaviorSubject, Observable, of} from 'rxjs';
|
||||
import {distinctUntilChanged, map, shareReplay} from 'rxjs/operators';
|
||||
import {AppStateStore} from '../app-state/app-state.store';
|
||||
import {StateStore} from '../state';
|
||||
import {deepClone, ObjectMap} from 'common';
|
||||
import {AdminMetadata} from './admin-metadata.model';
|
||||
|
||||
|
||||
const initialState: AdminMetadata = {
|
||||
adminPanel: []
|
||||
};
|
||||
|
||||
let internalState: AdminMetadata = deepClone(initialState);
|
||||
|
||||
let cache$: Observable<any> = null;
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class AdminMetadataStore implements StateStore {
|
||||
|
||||
/**
|
||||
* Public long-lived observable streams
|
||||
*/
|
||||
adminPanel$: Observable<ObjectMap>;
|
||||
|
||||
protected store = new BehaviorSubject<AdminMetadata>(internalState);
|
||||
protected state$ = this.store.asObservable();
|
||||
|
||||
constructor(
|
||||
protected appStateStore: AppStateStore,
|
||||
) {
|
||||
this.adminPanel$ = this.state$.pipe(map(state => state.adminPanel), distinctUntilChanged());
|
||||
}
|
||||
|
||||
/**
|
||||
* Public Api
|
||||
*/
|
||||
|
||||
/**
|
||||
* Clear state
|
||||
*/
|
||||
public clear(): void {
|
||||
cache$ = null;
|
||||
this.updateState(deepClone(initialState));
|
||||
}
|
||||
|
||||
public clearAuthBased(): void {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently active admin panel
|
||||
*
|
||||
* @returns {object} the admin panel
|
||||
*/
|
||||
public getAdminPanel(): AdminMetadata {
|
||||
return internalState.adminPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if loaded
|
||||
*/
|
||||
public isCached(): boolean {
|
||||
return cache$ !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal API
|
||||
*/
|
||||
|
||||
/**
|
||||
* Update the state
|
||||
*
|
||||
* @param {object} state to set
|
||||
*/
|
||||
protected updateState(state: AdminMetadata): void {
|
||||
this.store.next(internalState = state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set pre-loaded adminMetadata and cache
|
||||
*/
|
||||
public set(adminMetadata: AdminMetadata): void {
|
||||
cache$ = of(adminMetadata).pipe(shareReplay(1));
|
||||
this.updateState(adminMetadata);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -28,7 +28,7 @@ import {Injectable} from '@angular/core';
|
|||
import {BehaviorSubject, Observable, of} from 'rxjs';
|
||||
import {catchError, map, shareReplay, tap} from 'rxjs/operators';
|
||||
import {EntityGQL} from '../../services/api/graphql-api/api.entity.get';
|
||||
import {deepClone, emptyObject} from 'common';
|
||||
import {deepClone, emptyObject, ObjectMap} from 'common';
|
||||
import {StateStore} from '../state';
|
||||
import {AppStateStore} from '../app-state/app-state.store';
|
||||
import {LanguageStore, LanguageStrings} from '../language/language.store';
|
||||
|
@ -38,6 +38,9 @@ import {UserPreferenceMap, UserPreferenceStore} from '../user-preference/user-pr
|
|||
import {NavigationStore} from '../navigation/navigation.store';
|
||||
import {Metadata, MetadataMap, MetadataStore} from '../metadata/metadata.store.service';
|
||||
import {ApolloQueryResult} from '@apollo/client/core';
|
||||
import {AdminMetadataStore} from '../admin-metadata/admin-metadata.store';
|
||||
import {AuthService} from '../../services/auth/auth.service';
|
||||
import {AdminMetadata} from '../admin-metadata/admin-metadata.model';
|
||||
|
||||
export interface AppMetadata {
|
||||
loaded?: boolean;
|
||||
|
@ -49,6 +52,7 @@ export interface AppMetadata {
|
|||
navigation?: any;
|
||||
moduleMetadata?: MetadataMap;
|
||||
minimalModuleMetadata?: MetadataMap;
|
||||
adminMetadata?: AdminMetadata;
|
||||
}
|
||||
|
||||
export interface AppMetadataFlags {
|
||||
|
@ -61,6 +65,7 @@ export interface AppMetadataFlags {
|
|||
navigation?: boolean;
|
||||
moduleMetadata?: boolean;
|
||||
minimalModuleMetadata?: boolean;
|
||||
adminMetadata?: boolean;
|
||||
}
|
||||
|
||||
|
||||
|
@ -72,7 +77,8 @@ const initialState: AppMetadataFlags = {
|
|||
modStrings: false,
|
||||
themeImages: false,
|
||||
navigation: false,
|
||||
moduleMetadata: false
|
||||
moduleMetadata: false,
|
||||
adminMetadata: false
|
||||
};
|
||||
|
||||
let internalState: AppMetadataFlags = deepClone(initialState);
|
||||
|
@ -105,6 +111,7 @@ export class AppMetadataStore implements StateStore {
|
|||
'themeImages',
|
||||
'navigation',
|
||||
'moduleMetadata',
|
||||
'adminMetadata'
|
||||
];
|
||||
|
||||
constructor(
|
||||
|
@ -115,6 +122,8 @@ export class AppMetadataStore implements StateStore {
|
|||
protected config: SystemConfigStore,
|
||||
protected preferences: UserPreferenceStore,
|
||||
protected navigation: NavigationStore,
|
||||
protected adminMetadataStore:AdminMetadataStore,
|
||||
protected auth: AuthService
|
||||
) {
|
||||
this.metadata$ = this.state$;
|
||||
}
|
||||
|
@ -217,6 +226,10 @@ export class AppMetadataStore implements StateStore {
|
|||
types.push('themeImages')
|
||||
}
|
||||
|
||||
if (!this.isAdminMetadataLoaded()) {
|
||||
types.push('adminMetadata');
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
|
@ -240,6 +253,10 @@ export class AppMetadataStore implements StateStore {
|
|||
return this.navigation.isCached();
|
||||
}
|
||||
|
||||
protected isAdminMetadataLoaded(): boolean {
|
||||
return !!(internalState.adminMetadata ?? false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal API
|
||||
*/
|
||||
|
@ -259,7 +276,6 @@ export class AppMetadataStore implements StateStore {
|
|||
* @returns {object} Observable<{}>
|
||||
*/
|
||||
protected fetch(module: string, types: string[] = []): Observable<AppMetadataFlags> {
|
||||
|
||||
const fieldsToRetrieve = {
|
||||
fields: [
|
||||
...this.fieldsMetadata.fields,
|
||||
|
@ -286,7 +302,7 @@ export class AppMetadataStore implements StateStore {
|
|||
this.setNavigation(appMetadata, result);
|
||||
this.setLanguages(appMetadata, result);
|
||||
this.setModuleMetadata(appMetadata, result);
|
||||
|
||||
this.setAdminMetadata(appMetadata,result);
|
||||
return appMetadata;
|
||||
})
|
||||
);
|
||||
|
@ -373,6 +389,14 @@ export class AppMetadataStore implements StateStore {
|
|||
}
|
||||
}
|
||||
|
||||
protected setAdminMetadata(currentMetadata: AppMetadataFlags, appMetadata: AppMetadata) {
|
||||
const adminMetadata = appMetadata?.adminMetadata ?? {};
|
||||
if (!emptyObject(adminMetadata)) {
|
||||
currentMetadata.adminMetadata = true;
|
||||
this.adminMetadataStore.set(adminMetadata);
|
||||
}
|
||||
}
|
||||
|
||||
protected mapPreferences(preferences: any): UserPreferenceMap {
|
||||
const userPreferences: UserPreferenceMap = {};
|
||||
Object.keys(preferences).forEach((prefKey) => {
|
||||
|
|
|
@ -26,13 +26,22 @@
|
|||
*/
|
||||
-->
|
||||
|
||||
<div class="card text-center border-0" >
|
||||
<scrm-image image="{{content.icon}}" [wrapperClass]="'sicon-3x'"></scrm-image>
|
||||
<div class="card text-center border-0" *ngIf="content">
|
||||
<scrm-image [image]="content.icon" [wrapperClass]="'sicon-3x'"></scrm-image>
|
||||
<div class="card-body">
|
||||
<h6 class="card-title admin-card-title" title="{{content.titleDesc}}">{{content.title}}</h6>
|
||||
<div *ngFor="let link of content.links">
|
||||
<a class="card-link admin-card-link" routerLink="{{link.path}}" title="{{link.titleDesc}}">{{link.title}}</a>
|
||||
</div>
|
||||
|
||||
<h6 class="card-title admin-card-title" [title]="language.getFieldLabel(content.descriptionLabelKey)">
|
||||
<scrm-label [labelKey]="content.titleLabelKey"></scrm-label>
|
||||
</h6>
|
||||
<ng-container *ngIf="content.linkGroup">
|
||||
<div *ngFor="let item of content.linkGroup">
|
||||
<a class="card-link admin-card-link"
|
||||
[routerLink]="item.link"
|
||||
[queryParams]="item?.params"
|
||||
queryParamsHandling="merge"
|
||||
[title]="language.getFieldLabel(item.descriptionKey)">
|
||||
<scrm-label [labelKey]="item.titleKey"></scrm-label>
|
||||
</a>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
*/
|
||||
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {MenuItem} from 'common';
|
||||
import {LanguageStore} from '../../../../store/language/language.store';
|
||||
import {AdminLinkGroupModel} from '../../../../store/admin-metadata/admin-metadata.model';
|
||||
|
||||
|
||||
@Component({
|
||||
|
@ -34,8 +35,8 @@ import {MenuItem} from 'common';
|
|||
styleUrls: [],
|
||||
})
|
||||
export class AdminCardComponent {
|
||||
@Input() content: any;
|
||||
@Input() content: AdminLinkGroupModel;
|
||||
|
||||
constructor() {}
|
||||
constructor(public language: LanguageStore) {}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
<div class="admin-view d-flex align-items-center">
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-4 col-lg-3" *ngFor="let data of mockData">
|
||||
<div class="col-12 col-sm-6 col-md-4 col-lg-3" *ngFor="let data of adminPanelData">
|
||||
|
||||
<scrm-admin-card [content]="data"></scrm-admin-card>
|
||||
|
||||
|
|
|
@ -24,8 +24,13 @@
|
|||
* the words "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
import {Component} from '@angular/core';
|
||||
import {SystemConfigStore} from '../../../../store/system-config/system-config.store';
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {AdminMetadataStore} from '../../../../store/admin-metadata/admin-metadata.store';
|
||||
import {
|
||||
AdminLinkGroupModel,
|
||||
AdminMetadata,
|
||||
AdminMetadataModel
|
||||
} from '../../../../store/admin-metadata/admin-metadata.model';
|
||||
|
||||
|
||||
@Component({
|
||||
|
@ -33,296 +38,39 @@ import {SystemConfigStore} from '../../../../store/system-config/system-config.s
|
|||
templateUrl: './admin-panel.component.html',
|
||||
styleUrls: [],
|
||||
})
|
||||
export class AdminPanelComponent {
|
||||
export class AdminPanelComponent implements OnInit {
|
||||
|
||||
mockData:Array<any> = [
|
||||
{
|
||||
icon: 'icon_users_and_authentication',
|
||||
title: 'Users & Authentication',
|
||||
titleDesc: 'Create, edit, activate and deactivate users in SuiteCRM.',
|
||||
links: [
|
||||
{
|
||||
title:'User Management',
|
||||
titleDesc:'Manage user accounts and passwords',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title:'Role Management',
|
||||
titleDesc:'Manage role membership and properties',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title:'Password Management',
|
||||
titleDesc:'Manage password requirements and expiration',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title:'OAuth2 Clients and Tokens',
|
||||
titleDesc:'Manage which clients have access to the OAuth2 Server and view session log and revoke active sessions',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title:'OAuth Keys',
|
||||
titleDesc:'OAuth key management',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title:'Security Suite Group Management',
|
||||
titleDesc:'Security Suite Group Editor',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title:'Security Suite Settings',
|
||||
titleDesc:'Configure Security Suite settings such as group inheritance, additive security, etc',
|
||||
path:'/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: 'icon_system',
|
||||
title: 'System',
|
||||
titleDesc: 'Configure the system-wide settings according to the specifications of your organization. Users can override some of the default locale settings within their user settings page.',
|
||||
links: [
|
||||
{
|
||||
title: 'System Settings',
|
||||
titleDesc: 'Configure system-wide settings',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Currencies',
|
||||
titleDesc: 'Set up currencies and conversion rates',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Languages',
|
||||
titleDesc: 'Manage which languages are available for users',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Locale',
|
||||
titleDesc: 'Set default localization settings for your system',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'PDF Settings',
|
||||
titleDesc: 'Change PDF Settings',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Search Settings',
|
||||
titleDesc: 'Configure the global search preferences for the system',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Elasticsearch',
|
||||
titleDesc: 'Configure Elasticsearch preferences',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Scheduler',
|
||||
titleDesc: 'Set up scheduled events',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Themes',
|
||||
titleDesc: 'Choose themes for users to be able to select',
|
||||
path:'/'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: 'icon_module_settings',
|
||||
title: 'Module Settings',
|
||||
titleDesc: 'Configure Module specifics and settings',
|
||||
links: [
|
||||
{
|
||||
title: 'Activity Stream Settings',
|
||||
titleDesc: 'Enable the user feed and module feeds for the My Activity Stream dashlet',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Business hours',
|
||||
titleDesc: 'Restrict Workflow & Case automations to certain days and times',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Case Module Settings',
|
||||
titleDesc: 'Change settings for Cases and the Cases Portal',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Configure Module Menu Filters',
|
||||
titleDesc: 'Create and edit module menu filters',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Connectors',
|
||||
titleDesc: 'Manage connector settings',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Display Modules and Subpanels',
|
||||
titleDesc: 'Choose which modules are displayed in the navigation bar and which subpanels are displayed system-wide',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'History Subpanel',
|
||||
titleDesc: 'Enable/Disable contacts\' emails in history',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Sales Module Settings',
|
||||
titleDesc: 'Change settings for Quotes, Contracts and Invoices',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Releases',
|
||||
titleDesc: 'Manage releases and versions',
|
||||
path:'/'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: 'icon_email',
|
||||
title: 'Email',
|
||||
titleDesc: 'Manage outbound and inbound emails. The email settings must be configured in order to enable users to send out email and newsletter campaigns.',
|
||||
links: [
|
||||
{
|
||||
title: 'Email Settings',
|
||||
titleDesc: 'Configure email settings',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Inbound Email',
|
||||
titleDesc: 'Set up group mail accounts for monitoring inbound email and manage personal inbound mail account information for users',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Outbound Email',
|
||||
titleDesc: 'Configure outbound email settings',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'External OAuth Connections',
|
||||
titleDesc: 'Setup external OAuth connections',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Campaign Email Settings',
|
||||
titleDesc: 'Configure email settings for campaigns',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Email Queue',
|
||||
titleDesc: 'Manage the outbound email queue',
|
||||
path:'/'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: 'icon_admin_tools',
|
||||
title: 'Admin Tools',
|
||||
titleDesc: 'Repair, backup and run diagnosis on your SuiteCRM instance',
|
||||
links: [
|
||||
{
|
||||
title: 'Repair',
|
||||
titleDesc: 'Check and repair SuiteCRM',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Backups',
|
||||
titleDesc: 'Backup SuiteCRM files',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Diagnostic Tool',
|
||||
titleDesc: 'Capture system configuration for diagnostics and analysis',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Import Wizard',
|
||||
titleDesc: 'Use the import wizard to easily import records into the system',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Module Loader',
|
||||
titleDesc: 'Add or remove SuiteCRM modules, themes, language packs and other extensions',
|
||||
path:'/'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: 'icon_developer_tools',
|
||||
title: 'Developer Tools',
|
||||
titleDesc: 'Create and edit modules and module layouts, manage standard and custom fields and configure tabs.',
|
||||
links: [
|
||||
{
|
||||
title: 'Studio',
|
||||
titleDesc: 'Customize module fields, layouts and relationships',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Rename Modules',
|
||||
titleDesc: 'Change the names of the modules appearing within the application',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Module Builder',
|
||||
titleDesc: 'Build new modules to expand the functionality of SuiteCRM',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Dropdown Editor',
|
||||
titleDesc: 'Add, delete, or change the dropdown lists',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Workflow Manager',
|
||||
titleDesc: 'Manage, Add, delete or change Workflow processes',
|
||||
path:'/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: 'icon_google_suite',
|
||||
title: 'Google Suite',
|
||||
titleDesc: 'Manage your Google Suite Integration.',
|
||||
links: [
|
||||
{
|
||||
title: 'Google Calendar Settings',
|
||||
titleDesc: 'Configuration settings to adjust your Google Calendar',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Google Maps Settings',
|
||||
titleDesc: 'Configuration settings to adjust your Google Maps',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Geocoded Counts',
|
||||
titleDesc: 'Shows the number of module objects geocoded, grouped by geocoding response',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Geocoding Test',
|
||||
titleDesc: 'Run a single geocoding test with detailed display results.',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Geocode Addresses',
|
||||
titleDesc: 'Geocode your object addreses. This process may take a few minutes!',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
title: 'Address Cache',
|
||||
titleDesc: 'Provides access to Address Cache information. This is only cache.',
|
||||
path:'/'
|
||||
},
|
||||
]
|
||||
}
|
||||
];
|
||||
adminPanelData: AdminMetadataModel[] = [];
|
||||
|
||||
constructor(protected configs: SystemConfigStore) {
|
||||
constructor(protected adminMetaData: AdminMetadataStore) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
const adminData: AdminMetadata = this.adminMetaData.getAdminPanel();
|
||||
this.setData(adminData);
|
||||
}
|
||||
|
||||
protected setData(adminData: AdminMetadata): void {
|
||||
adminData.forEach(({icon, titleLabelKey, descriptionLabelKey, linkGroup}) => {
|
||||
this.adminPanelData.push({
|
||||
icon,
|
||||
titleLabelKey,
|
||||
descriptionLabelKey,
|
||||
linkGroup: this.setLinkGroups(linkGroup)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected setLinkGroups(groupData: AdminLinkGroupModel): AdminLinkGroupModel[] {
|
||||
let linkGroups: AdminLinkGroupModel[] = [];
|
||||
let linkGroupKeys: string[] = Object.keys(groupData);
|
||||
for (let j = 0; j < linkGroupKeys.length; j++) {
|
||||
let linkGroup = groupData[linkGroupKeys[j]];
|
||||
let links = Object.values(linkGroup);
|
||||
for (let i = 0; i < links.length; i++) {
|
||||
linkGroups.push(links[i]);
|
||||
}
|
||||
}
|
||||
return linkGroups;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ import {AdminCardModule} from '../admin-card/admin-card.module';
|
|||
imports: [
|
||||
CommonModule,
|
||||
AdminCardModule
|
||||
|
||||
]
|
||||
})
|
||||
export class AdminPanelModule {
|
||||
|
|
|
@ -144,7 +144,7 @@ export class AppInit {
|
|||
});
|
||||
|
||||
routes.push({
|
||||
path: 'administration/new',
|
||||
path: 'administration/index',
|
||||
component: AdminPanelComponent,
|
||||
canActivate: [AuthGuard],
|
||||
runGuardsAndResolvers: 'always',
|
||||
|
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |