Skip to content
Snippets Groups Projects
Commit 049d54d9 authored by marcopat's avatar marcopat
Browse files

stepper

parent 7d1f18bc
Branches
No related tags found
No related merge requests found
Showing
with 756 additions and 179 deletions
export enum MenuType {
SHARED = 'SHARED',
PERSONAL = 'PERSONAL',
PUBLIC = 'PUBLIC'
PUBLIC = 'PUBLIC',
}
export namespace MenuType {
......
......@@ -3,7 +3,7 @@ import { ManageDashboardPageComponent } from './manage-dashboard-page/manage-das
import { GoogleMapsModule } from '@angular/google-maps';
import { LeafletMarkerClusterModule } from '@asymmetrik/ngx-leaflet-markercluster';
import { NgxEchartsModule } from 'ngx-echarts';
import { NbCardModule, NbRadioModule, NbSpinnerModule, NbDatepickerModule, NbInputModule, NbButtonModule, NbSelectModule, NbTimepickerModule, NbIconModule, NbTooltipModule, NbTabsetModule, NbListModule, NbFormFieldModule, NbActionsModule, NbAutocompleteModule, NbDialogModule, NbAccordionModule, NbOptionModule, NbLayoutModule, NbCheckboxModule, NbToggleModule, NbStepperModule, NbUserModule} from '@nebular/theme';
import { NbCardModule, NbRadioModule, NbSpinnerModule, NbDatepickerModule, NbInputModule, NbButtonModule, NbSelectModule, NbTimepickerModule, NbIconModule, NbTooltipModule, NbTabsetModule, NbListModule, NbFormFieldModule, NbActionsModule, NbAutocompleteModule, NbDialogModule, NbAccordionModule, NbOptionModule, NbLayoutModule, NbCheckboxModule, NbToggleModule, NbStepperModule, NbUserModule, NbStepperComponent} from '@nebular/theme';
import { ThemeModule } from '../../@theme/theme.module';
import { DashboardManagementRoutingModule } from './dashboard-management-routing.module';
import { MatCardModule } from '@angular/material/card';
......@@ -62,7 +62,7 @@ import {MatDialogModule} from '@angular/material/dialog';
NbTooltipModule,
SharedModule,
NbAccordionModule,
NbStepperModule,
NgApexchartsModule,
NbOptionModule,
NbLayoutModule,
......@@ -93,6 +93,7 @@ import {MatDialogModule} from '@angular/material/dialog';
StatisticsComponent,
DashboardCloneWizardComponent,
ChartViewComponent,
],
})
export class DashboardManagementModule { }
......@@ -17,24 +17,6 @@
</div>
</nb-form-field>
<!-- <nb-form-field class="col-6 mb-1 mt-1">
<div class="d-flex flex-column">
<label for="shared" class="label mr-2">
<nb-icon icon="info-outline" nbTooltip="{{'dashboardPage.shared_info'|translate}}" ></nb-icon>
{{'dashboardPage.shared'|translate}} {{disabledTarget?'':'*'}}
</label>
<nb-select fullWidth formControlName="shared" size="small" name="shared"
placeholder="{{'dashboardPage.shared'|translate}}"
[nbTooltip]="getMessageDisabledTarget()">
<nb-option *ngFor="let item of sharedDomain" [value]="item">
{{item}}
</nb-option>
</nb-select>
</div>
</nb-form-field> -->
<nb-form-field class="col-12 mb-1 mt-1">
<div class="d-flex flex-column">
<label for="description" class="label mr-2">
......@@ -56,27 +38,197 @@
name="note" formControlName="note"></textarea>
</div>
</nb-form-field>
</div>
</nb-card-body>
<div class="justify-content-between">
<button nbButton status="primary" (click)="backClicked()" size="small">
<nb-icon icon="backspace-outline"></nb-icon> {{'general.back'|translate}}
</button>
<button class="next-button text-white bg-success" size="small" nbButton disabled nbStepperNext>next</button>
</div>
</nb-step>
<nb-step>
<ngx-menu-filter [pageId]="pageId" [pageName]="pageName" (sendFilter)="updateSharedPersonalTypology($event)" ></ngx-menu-filter>
<div class="d-flex justify-content-between" *ngIf="isEditable==true">
<nb-card class="col-md-3 col-sm-12">
<nb-card-header>
{{'dashboardPage.name'|translate}}
</nb-card-header>
<nb-card-body>
{{dashboardPage.name}}
</nb-card-body>
</nb-card>
<nb-card class="col-md-2 col-sm-12">
<nb-card-header>
{{'dashboardPage.margin_label'|translate}}
</nb-card-header>
<nb-card-body>
<div class="row ">
<div class="col-sm justify-content-between">
{{'dashboardPage.margin'|translate}}
<input nbInput fieldSize="small" [(ngModel)]="options.margin" min="0"
nbTooltip="{{'dashboardPage.margin_description'|translate}}" max="30" step="1" type="number"
(ngModelChange)="changedOptions()">
</div>
</div>
<div class="row">
<div class="col-sm justify-content-between">
<nb-checkbox [(ngModel)]="options.outerMargin" (ngModelChange)="changedOptions()"
nbTooltip="{{'dashboardPage.outer_margin_description'|translate}}">
{{'dashboardPage.outer_margin'|translate}}
</nb-checkbox>
</div>
</div>
</nb-card-body>
</nb-card>
<nb-card class="col-md-4 col-sm-12">
<nb-card-header>
{{'dashboardPage.checkbox_label'|translate}}
</nb-card-header>
<nb-card-body>
<div class="row">
<div class="col-sm justify-content-between">
<nb-checkbox [(ngModel)]="options.draggable.enabled" (ngModelChange)="changedOptions()"
nbTooltip="{{'dashboardPage.drag_items'|translate}}">
{{'dashboardPage.drag_items'|translate}}
</nb-checkbox>
</div>
<div class="col-sm justify-content-between">
<nb-checkbox [(ngModel)]="options.disablePushOnDrag" (ngModelChange)="changedOptions()"
nbTooltip="{{'dashboardPage.disable_push_on_drag_description'|translate}}">
{{'dashboardPage.disable_push_on_drag'|translate}}
</nb-checkbox>
</div>
</div>
<div class="row">
<div class="col-sm justify-content-between">
<nb-checkbox [(ngModel)]="options.pushItems" (ngModelChange)="changedOptions()"
nbTooltip="{{'dashboardPage.push_items_description'|translate}}">
{{'dashboardPage.push_items'|translate}}
</nb-checkbox>
</div>
<div class="col-sm justify-content-between">
<nb-checkbox [(ngModel)]="options.swap" (ngModelChange)="changedOptions()"
nbTooltip="{{'dashboardPage.swap_items_description'|translate}}">
{{'dashboardPage.swap_items'|translate}}
</nb-checkbox>
</div>
</div>
</nb-card-body>
</nb-card>
<div>
<button class="add-button" nbButton size="medium" hero status="primary" nbTooltip="{{'general.back'|translate}}"
(click)="backClicked()" class="add-button cols-2">
<nb-icon icon="arrow-back-outline"></nb-icon>
</button>
<button class="save-button" nbButton size="medium" hero status="primary"
nbTooltip="{{'general.save'|translate}} {{'general.component'|translate}}" (click)="saveDashboard()"
class="add-button cols-2">
<nb-icon icon="save-outline"></nb-icon>
</button>
<button class="add-button" nbButton size="medium" hero status="primary"
nbTooltip="{{'general.add'|translate}} {{'general.component'|translate}}" (click)="addItem()"
class="add-button cols-2">
<nb-icon icon="plus-square-outline"></nb-icon>
</button>
</div>
</div>
<gridster [options]="options">
<gridster-item [item]="i" *ngFor="let i of items">
<div *ngIf="i.type=='IMAGE'" class="image-container">
<img [src]="buildImage(i)" [alt]="i.image">
</div>
<div *ngIf="i.type=='TEXT'" class="text-container" [innerHTML]="i.text | safeHtml">
</div>
<div *ngIf="i.type=='WEATHER'">
<ngx-weather [weather_title]="i.weather_title" [weather_subtitle]="i.weather_subtitle">
</ngx-weather>
</div>
<!-- MAP -->
<div class="map" *ngIf="i.type=='MAP'">
<h2>{{i.map_title}}</h2>
<div #map class="map" leaflet [leafletOptions]="mapOptions" (leafletMapReady)="onMapReady($event, i.map)">
</div>
</div>
<div *ngIf="i.type=='STATISTICS'">
<ngx-statistics [statistics_title]="i.statistics_title" [statistics_subtitle]="i.statistics_subtitle"
[statistics_value]="i.statistics_value" [statistics_icon]="i.statistics_icon">
</ngx-statistics>
</div>
<!--
<div *ngIf="i.type=='CHART'" [innerHTML]="i.chart | safeHtml"></div>
-->
<div *ngIf="i.type=='CHART'">
<ngx-chart-view [chartContent]="i.chart"></ngx-chart-view>
</div>
<div *ngIf="i.type=='IFRAME'" [innerHTML]="i.iframe | safeHtml">
</div>
<div class="itemButtons" *ngIf="isEditable==true">
<button nbButton class="remove-button" (mousedown)="$event.stopPropagation()"
nbTooltip="{{'general.delete'|translate}} {{'general.component'|translate}}" (click)="removeItem(i)">
<nb-icon icon="trash-2-outline"></nb-icon>
</button>
<button nbButton class="component-button" (mousedown)="$event.stopPropagation()"
nbTooltip="{{'general.edit'|translate}} {{'general.component'|translate}}" (click)="editItem(i, items)">
<nb-icon icon="edit-2-outline"></nb-icon>
</button>
<button nbButton class="component-button"
nbTooltip="{{'general.drag'|translate}} {{'general.component'|translate}}">
<nb-icon icon="move-outline"></nb-icon>
</button>
</div>
</gridster-item>
</gridster>
<button class="next-button text-white bg-success " size="small" nbButton nbStepperPrevious>back</button>
<button class="next-button text-white bg-success " size="small" nbButton nbStepperNext>next</button>
</nb-step>
<nb-step>
<nb-form-field class="col-6 mb-1 mt-1">
<div class="d-flex flex-column">
<label for="shared" class="label mr-2">
<nb-icon icon="info-outline" nbTooltip="{{'dashboardPage.shared_info'|translate}}" ></nb-icon>
{{'dashboardPage.shared'|translate}} {{disabledTarget?'menu':'*'}}
</label>
<nb-select fullWidth formControlName="shared" size="small" name="shared"
placeholder="{{'dashboardPage.shared'|translate}}"
[nbTooltip]="getMessageDisabledTarget()">
<nb-option *ngFor="let items of dataType()" [value]="items">
{{items}}
</nb-option>
</nb-select>
</div>
</nb-form-field>
<ngx-target-filter [pageId]="pageId" [disabledTarget]="disabledTarget"></ngx-target-filter>
<button class="next-button text-white bg-success " size="small" nbButton nbStepperPrevious>back</button>
<button type="submit" nbButton status="primary" (click)="storePage()" size="small" [disabled]="page.invalid">
<nb-icon icon="save"></nb-icon>{{'general.save'|translate}}
</button>
</nb-step>
</nb-stepper>
<nb-card-footer class="d-flex justify-content-between">
<!-- <nb-card-footer class="d-flex justify-content-between">
<button nbButton status="primary" (click)="backClicked()" size="small">
<nb-icon icon="backspace-outline"></nb-icon> {{'general.back'|translate}}
</button>
<button type="submit" nbButton status="primary" (click)="storePage()" size="small" [disabled]="page.invalid">
<nb-icon icon="save"></nb-icon>{{'general.save'|translate}}
</button>
</nb-card-footer>
</nb-card-footer> -->
</nb-card>
......
gridster {
background-color: #dddddd;
}
.addItemButton {
margin: 20px !important;
}
.itemButtons {
position: absolute;
bottom: 5px;
right: 5px;
}
.component-button {
margin: 3px !important;
}
.image-container {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
.text-container {
margin: 5px;
}
img {
max-width: 100%;
max-height: 100%;
}
.add-button {
margin: 10px;
}
.map {
height: 24em;
width: 100%;
margin-left: 0.45em;
}
import { Component, Input, OnInit } from '@angular/core';
import { Component, Inject, Input, OnInit, Optional } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { NbToastrService } from '@nebular/theme';
import { NbDialogService, NbToastrService } from '@nebular/theme';
import { TranslateService } from '@ngx-translate/core';
import { DashboardPage } from '../../../model/dashboard-page.model';
import { DashboardPage, IDashboardPage } from '../../../model/dashboard-page.model';
import { DashboardPageCrudService } from '../services/dashboard-page-crud.service';
import { Location } from '@angular/common';
import { FormManagerService } from '../services/form-manager.service';
import { MenuType } from '../../../model/enumeration/menu-type.model';
import { MenuItemCrudService } from '../services/menu-item-crud.service';
import { Draggable, GridsterConfig, GridsterItem, PushDirections, Resizable } from 'angular-gridster2';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { ConfigService } from '@ngx-config/core';
import { DomSanitizer } from "@angular/platform-browser";
import * as L from 'leaflet';
import { DialogComponent } from '../../shared/dialog/dialog.component';
import { DashboardComponentDialogComponent } from '../dashboard-component-dialog/dashboard-component-dialog.component';
interface Safe extends GridsterConfig {
draggable: Draggable;
resizable: Resizable;
pushDirections: PushDirections;
}
interface DashboardModalData {
parsedId: number;
parsedEditMode: boolean;
}
@Component({
selector: 'ngx-dashboard-page',
......@@ -18,10 +37,28 @@ import { MenuItemCrudService } from '../services/menu-item-crud.service';
export class DashboardPageComponent implements OnInit {
@Input() page: FormGroup = new FormGroup({});
sharedDomain = [true, false];
sharedType = MenuType;
dataType(): Array<string> {
const keys = Object.keys(this.sharedType);
return keys.slice(keys.length/10,keys.length-1);
}
changeEvent: DashboardPageComponent;
handleStepChange(e: DashboardPageComponent): void {
this.changeEvent = e;
}
public options: GridsterConfig;
public items:Array<GridsterItem>;
public itemsClone:Array<GridsterItem>;
public dashboardPage: DashboardPage = new DashboardPage();
public id: string;
public componentType: string;
public isEditable = true;
pageId: string; //For Targets
pageName: string; //For MenuItem
disabledTarget: boolean; //For Targets
private ENABLE_DELAY:boolean;
private DELAY:number;
constructor(
private formService: FormManagerService,
......@@ -29,12 +66,58 @@ export class DashboardPageComponent implements OnInit {
private menuItemService: MenuItemCrudService,
private router: Router,
private route: ActivatedRoute,
private _sanitizer: DomSanitizer,
private toastrService: NbToastrService,
private translateService: TranslateService,
private _location: Location
) { }
private _location: Location,
public dialogService: NbDialogService,
public dashboardPageService: DashboardPageCrudService,
private configService: ConfigService,
@Optional() @Inject(MAT_DIALOG_DATA) public dashboardModalData: DashboardModalData
) {
this.ENABLE_DELAY = this.configService.getSettings("dashboard-controller.enable_delay");
this.DELAY = this.configService.getSettings("dashboard-controller.delay");
}
ngOnInit(): void {
this.options = this.getDefaultOption();
this.items = [];
this.itemsClone = [];
this.route.paramMap.subscribe( paramMap => {
this.items = [];
this.id = paramMap.get('id');
if (this.dashboardModalData != null && this.dashboardModalData != undefined){
this.id = this.dashboardModalData.parsedId as unknown as string;
this.isEditable = this.dashboardModalData.parsedEditMode;
this.options = this.getDefaultOption();
}
//console.log("Retrieved Content for Page with Id: " + this.id);
this.dashboardPageService.getPageById(this.id).subscribe((data) => {
this.dashboardPage=data;
if (data.content !== "" && data.content !== undefined && data.content !== null){
if (this.ENABLE_DELAY == true) {
this.fillItemsWithDelay(data);
} else {
this.items = JSON.parse(data.content);
}
}
});
});
this.route.queryParams.subscribe(params => {
if (params['isEditable'] != undefined && params['isEditable'] != null){
this.isEditable = params['isEditable'] == "true" ? true : false;
this.options = this.getDefaultOption();
}
});
this.page = this.formService.pageFormCreator(new DashboardPage());
this.route.paramMap.subscribe(params => {
......@@ -48,6 +131,186 @@ export class DashboardPageComponent implements OnInit {
});
}
private fillItemsWithDelay (data: IDashboardPage) {
try {
let itemsTemp = JSON.parse(data.content);
itemsTemp.forEach((element, i) => {
if (element['chart'] != undefined && element['chart'] != null) {
setTimeout(() => {
// console.log(element);
this.items.push(element);
}, i * this.DELAY);
} else {
this.items.push(element);
}
});
} catch (e) {
console.log("## Error in Dashboard page content during visualization due to " + e);
this.toastrService.danger(this.translateService.instant('dashboardPage.visualization_catch_error'));
}
}
removeItem(item) {
this.dialogService.open(DialogComponent,
{ context: { title: this.translateService.instant('general.delete') + " " + this.translateService.instant('general.component') ,
message: this.translateService.instant('general.deleteConfirm')} })
.onClose.subscribe(
(res) => {
this.items.splice(this.items.indexOf(item), 1);
}, err => {
// console.log(err);
this.toastrService.danger(this.translateService.instant('dashboardPage.operation_failed'), this.translateService.instant('general.error'));
}
);
}
addItem() {
let item: GridsterItem = { cols: 2, rows: 2, y: 0, x: 0 }; //default added item
this.items.push(item);
}
editItem(item: GridsterItem, items: GridsterItem[]) {
const dialogRef = this.dialogService
.open(DashboardComponentDialogComponent, {
context: {
item,
items,
},
})
.onClose.subscribe(
(item) => {
item && (this.items = item) && this.options.api.optionsChanged() // optionsChanged() refreshes and applies changes
}
);
}
changedOptions(): void {
if (this.options.api && this.options.api.optionsChanged) {
this.options.api.optionsChanged();
}
}
saveDashboard(){
this.dashboardPage.content = JSON.stringify(this.items);
this.dashboardPageService.updatePageById(this.dashboardPage)
.subscribe((res) => {
// console.log('## Saved Dashboard with id:' + this.dashboardPage.id);
this.toastrService.success(this.translateService.instant('dashboardPage.updated'), this.translateService.instant('general.success'));
},err => {
// console.log(err);
this.toastrService.danger(this.translateService.instant('dashboardPage.operation_failed'), this.translateService.instant('general.error'));
});
}
/** Ask confirm before to go back */
backClicked() {
this.dialogService.open(DialogComponent,
{ context: { title: this.translateService.instant('dashboardComponent.title') ,
message: this.translateService.instant('dashboardPage.back_modal') } })
.onClose.subscribe(res => {
if (res) {
this._location.back();
} else return;
});
}
/**
* Return modified string trusted (in case of base 64 string) or untouched image string in case or URL
* @param item object with Image URL or image string in BASE 64
* @returns trasted image url or string
*/
buildImage(item: any) {
if (item.url == false){
if (item.image != undefined && item.image.length>10 && "data:image/jpeg;base64" == item.image.substr(0,10) ) {
return this._sanitizer.bypassSecurityTrustResourceUrl(item.image);
} else{
return item.image;
}
}else{
if (item.imageUrl != undefined && item.imageUrl.length>10 && "data:image/jpeg;base64" == item.imageUrl.substr(0,10) ) {
return this._sanitizer.bypassSecurityTrustResourceUrl(item.imageUrl);
} else{
return item.imageUrl;
}
}
}
private getDefaultOption(): any{
return {
pushItems: true,
minCols: 20,
minRows: 12,
fixedRowHeight: 120,
setGridSize: true,
mobileBreakpoint: 0,
gridType: "scrollVertical",
resizable: {
enabled: this.isEditable,
},
draggable: {
enabled: this.isEditable,
},
margin: 10,
outerMargin: true,
swap: this.isEditable
};
}
/** MAP Section WIP **/
mapOptions = {
layers: [
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '...' }),
],
zoom: 9,
center: L.latLng({ lat: 52.372664783594274, lng: 4.8950958251953125 }),
};
onMapReady(map: L.Map, mapUrl: string) {
console.log("### onMapReady, map ==> " + map);
this.initializeMap(mapUrl, map);
}
public getMapLayer(title, l): L.GeoJSON {
let layer = L.geoJSON(l,
{
onEachFeature: (feature, layer) => {
let text = "";
for (let p in feature.properties) {
text += `${p}: ${feature.properties[p]}\n`;
}
layer.bindPopup(text);
},
style: function () {
return { color: '#248175', weight: 7, opacity: 0.8 }
}
},
).on('popupclose', ($event) => {})
layer['_id'] = title;
return layer;
}
private initializeMap(mapUrl: string, map: L.Map) {
this.dashboardPageService.getGeoJsonMap(mapUrl).subscribe(res => {
let currentLayer = this.getMapLayer(mapUrl, <any>res);
console.log("# initializeMap, currentLayer => " + currentLayer);
setTimeout(() => {
map.invalidateSize();
map.addLayer(currentLayer);
map.fitBounds(currentLayer.getBounds(), {
padding: [50, 50]
});
}, 50);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
});
}
editPage(page: DashboardPage) {
this.page = this.formService.pageFormCreator(page);
......@@ -103,9 +366,7 @@ export class DashboardPageComponent implements OnInit {
this.toastrService.danger(error.error.message, this.translateService.instant('general.error'))
}
backClicked() {
this._location.back();
}
updateSharedPersonalTypology($event) {
this.menuItemService.getByPageId(this.pageId).subscribe(
......
<nb-card>
<nb-card-header class="d-flex justify-content-between">
<h4>{{'general.menu_blocks'|translate}}</h4>
<button nbButton size="small" status="info" routerLink="../add-menu-block-page"
status="primary">{{'general.add'|translate}} {{'general.menu_blocks'|translate}}</button>
</nb-card-header>
<nb-card-body>
<ng2-smart-table [settings]="settings" [source]="source"></ng2-smart-table>
<nb-stepper #stepper>
<nb-step [stepControl]="page" label="First step">
<h4>
{{ "general.manage" | translate }}
{{ "general.dashboard" | translate }}
</h4>
<nb-card-body [formGroup]="page">
<div class="row">
<nb-form-field class="col-6 mb-1 mt-1">
<div class="d-flex flex-column">
<label for="name" class="label mr-2">
{{ "dashboardPage.name" | translate }} *
</label>
<input
type="text"
nbInput
fullWidth
fieldSize="small"
placeholder="{{ 'dashboardPage.name' | translate }}"
name="name"
formControlName="name"
nbTooltip="{{ 'general.mandatory_field' | translate }}"
/>
</div>
</nb-form-field>
<nb-form-field class="col-3 mb-1 mt-1">
<div class="d-flex flex-column">
<label for="shared" class="label mr-2">
<nb-icon
icon="info-outline"
nbTooltip="{{ 'dashboardPage.shared_info' | translate }}"
></nb-icon>
{{ "dashboardPage.shared" | translate }}
{{ disabledTarget ? "" : "*" }}
</label>
<nb-select
fullWidth
formControlName="shared"
size="small"
name="shared"
placeholder="{{ 'dashboardPage.shared' | translate }}"
[nbTooltip]="getMessageDisabledTarget()"
>
<nb-option *ngFor="let item of sharedDomain" [value]="item">
{{ item }}
</nb-option>
</nb-select>
</div>
</nb-form-field>
<!---->
<nb-form-field class="col-3 mb-1 mt-1">
<div class="d-flex flex-column">
<label for="shared" class="label mr-2">
<nb-icon
icon="info-outline"
nbTooltip="{{ 'dashboardPage.shared_info' | translate }}"
></nb-icon>
{{ "dashboardPage.shared" | translate }}
{{ disabledTarget ? "" : "*" }}
</label>
<nb-select
fullWidth
formControlName="shared"
size="small"
name="shared"
placeholder="{{ 'dashboardPage.shared' | translate }}"
[nbTooltip]="getMessageDisabledTarget()"
>
<nb-option *ngFor="let items of sharedTypes()" [value]="items">
{{ items }}
</nb-option>
</nb-select>
</div>
</nb-form-field>
<!---->
<nb-form-field class="col-12 mb-1 mt-1">
<div class="d-flex flex-column">
<label for="description" class="label mr-2">
{{ "dashboardPage.description" | translate }}
</label>
<input
type="text"
nbInput
fullWidth
fieldSize="small"
placeholder="{{ 'dashboardPage.description' | translate }}"
description="name"
formControlName="description"/>
</div>
</nb-form-field>
</div>
<div class="row">
<nb-form-field class="col-12 mb-1 mt-1">
<div class="d-flex flex-column">
<label for="note" class="label mr-2">
{{ "dashboardPage.note" | translate }}
</label>
<textarea
nbInput
fullWidth
rows="3"
type="text"
fieldSize="small"
placeholder="{{ 'dashboardPage.note' | translate }}"
name="note"
formControlName="note"
></textarea>
</div>
</nb-form-field>
</div>
</nb-card-body>
<nb-card-footer class="d-flex justify-content-between">
<button nbButton nbStepperNext class="bg-success text-white">next</button>
</nb-card-footer>
</nb-step>
<nb-step [stepControl]="page" label="Second step">
<ngx-target-filter
[pageId]="pageId"
[disabledTarget]="disabledTarget"
></ngx-target-filter>
<nb-card-footer class="d-flex justify-content-between">
<button nbButton nbStepperPrevious class="bg-success text-white">Back</button>
<button
type="submit"
nbButton
status="primary"
(click)="storePage()"
size="small"
[disabled]="page.invalid">
<nb-icon icon="save"></nb-icon>{{ "general.save" | translate }}
</button>
</nb-card-footer>
</nb-step>
</nb-stepper>
</nb-card-body>
</nb-card>
\ No newline at end of file
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { NbDialogService, NbToastrService } from '@nebular/theme';
import { Component, Input, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { NbToastrService } from '@nebular/theme';
import { TranslateService } from '@ngx-translate/core';
import { LocalDataSource } from 'ng2-smart-table';
import { DashboardPage } from '../../../model/dashboard-page.model';
import { DashboardPageCrudService } from '../services/dashboard-page-crud.service';
import { Location } from '@angular/common';
import { FormManagerService } from '../services/form-manager.service';
import { MenuType } from '../../../model/enumeration/menu-type.model';
import { MenuBlock } from '../../../model/menu-block.model';
import { DialogComponent } from '../../shared/dialog/dialog.component';
import { TableActionsComponent } from '../../shared/table-actions/table-actions.component';
import { MenuBlockCrudService } from '../services/menu-block-crud.service';
import { MenuItemCrudService } from '../services/menu-item-crud.service';
@Component({
selector: 'ngx-manage-menu-blocks',
......@@ -15,137 +17,123 @@ import { MenuBlockCrudService } from '../services/menu-block-crud.service';
styleUrls: ['./manage-menu-blocks.component.scss']
})
export class ManageMenuBlocksComponent implements OnInit {
source: LocalDataSource;
settings: any;
menuBlocks: Array<MenuBlock>=[];
@Input() page: FormGroup = new FormGroup({});
sharedDomain = [true, false];
sharedType = MenuType;
sharedTypes():Array<string>{
const keys = Object.keys(this.sharedType);
return keys;
}
pageId: string; //For Targets
pageName: string; //For MenuItem
disabledTarget: boolean; //For Targets
constructor( private service: MenuBlockCrudService,
constructor(
private formService: FormManagerService,
private service: DashboardPageCrudService,
private menuItemService: MenuItemCrudService,
private router: Router,
private dialogService: NbDialogService,
private route: ActivatedRoute,
private toastrService: NbToastrService,
private translateService: TranslateService,
private toastrService: NbToastrService)
{
this.initTableSettings();
}
private _location: Location
) { }
ngOnInit(): void {
this.source = new LocalDataSource();
this.fetchTableData();
}
this.page = this.formService.pageFormCreator(new DashboardPage());
fetchTableData() {
this.service.getAllEditable().subscribe(
(data) => {
this.menuBlocks=data;
this.source.load(data);
this.route.paramMap.subscribe(params => {
this.pageId = params.get('id');
if (this.pageId) {
this.service.getPageById(this.pageId).subscribe(
(event: DashboardPage) => { this.editPage(event);
},
error => (this.showError(error))
error => this.showError(error)
);
}
});
showSuccess() {
this.toastrService.success(this.translateService.instant('menuBlocks.deleted'), this.translateService.instant('general.success'));
}
showError(error) {
if (error.status == '500' && error.ok == false ) {
// More Menu Items linked to the Menu Block.
this.toastrService.danger(this.translateService.instant('menuBlock.delete_fk_error'), this.translateService.instant('general.error'))
} else {
this.toastrService.danger(error.message, this.translateService.instant('general.error'))
}
}
editPage(page: DashboardPage) {
this.page = this.formService.pageFormCreator(page);
this.pageName = page.name;
//this.disabledTarget = page.type!=undefined ? page.type != MenuType.SHARED : true;
this.menuItemService.getByPageId(this.pageId).subscribe(
(data) => { this.disabledTarget = data!=null && data.length>0 ? data[0].type != MenuType.SHARED : true; },
error => (this.showError(error))
);
initTableSettings(): void {
let typeFilter=[]; //FIX
let types = MenuType.values();
for(let curType of types) {
typeFilter.push({ value: curType.value, title: curType.enumVal })
}
this.settings = {
mode: 'external',
columns: {
type: {
title: this.translateService.instant('menuBlock.type'),
filter: {
type: 'list',
config: {
selectText: '',
list: typeFilter
storePage(): void {
if (this.page.value.id == null) {
console.log('## CREATE DASHBOARD WITH ID:' + this.page.value.id);
let tmp = <DashboardPage>this.page.getRawValue();
this.pageName = tmp.name;
//this.disabledTarget = tmp.type!=undefined ? tmp.type != MenuType.SHARED : true;
this.service.createPage(tmp).subscribe(
(data: DashboardPage) => {
// console.log("# DASHBOARD CREATED, DATA => " + data);
data.shared= false;
console.log(data)
this.router.navigate(['/pages/dashboard-management/manage-dashboard-pages']);
this.showSuccess();
},
error => (this.showError(error))
);
}
else {
console.log('# MODIFY DASHBOARD WITH ID:' + this.page.value.id);
let tmp = <DashboardPage>this.page.getRawValue();
this.pageName = tmp.name;
//this.disabledTarget = tmp.type!=undefined ? tmp.type != MenuType.SHARED : true;
this.service.updatePageById(tmp).subscribe(
(data: DashboardPage) => {
this.editPage(data);
this.showSuccess();
},
code: {
title: this.translateService.instant('menuBlock.code')
},
label: {
title: this.translateService.instant('menuBlock.label')
},
error => (this.showError(error))
);
/*
id: {
title: this.translateService.instant('menuBlock.id'),
filter: false
},
order: {
title: this.translateService.instant('menuBlock.order'),
filter: false
},
*/
actions: {
title: this.translateService.instant('general.actions'),
filter: false,
sort: false,
type: 'custom',
valuePrepareFunction: (cell, row) => {
return [
{action:'edit', enabled:true, status:"info", icon:"edit-2", tooltip:this.translateService.instant('general.edit')},
{action:'delete', enabled:true, status:"danger", icon:"trash-2", tooltip:this.translateService.instant('general.delete')},
];
},
renderComponent: TableActionsComponent,
onComponentInitFunction: (instance) => {
instance.onCustom.subscribe(value => {
this.onCustom(value,instance.rowData);
});
},
}
},
}
actions: {
add: false,
edit: false,
delete: false,
},
showSuccess() {
this.page.value.id == null
? this.toastrService.success(this.translateService.instant('dashboardPage.created'), this.translateService.instant('Success'))
: this.toastrService.success(this.translateService.instant('dashboardPage.updated'), this.translateService.instant('Success'));
}
};
showError(error) {
this.toastrService.danger(error.error.message, this.translateService.instant('general.error'))
}
onCustom(event, data) {
if (event == 'edit') {
this.router.navigate(['/pages/dashboard-management/edit-menu-block-page/' + data.id])
};
if (event == 'delete') {
this.dialogService.open(DialogComponent, { context: {
title: this.translateService.instant('general.delete') + " " + this.translateService.instant('menuBlock.title') ,
message: this.translateService.instant('general.deleteConfirm') } })
.onClose.subscribe(res => {
if (res) {
this.service.deleteById(data.id).subscribe(() => {
this.fetchTableData();
console.log(`# Menu Block with id=${data.id} has been deleted.`);
this.showSuccess();
updateSharedPersonalTypology($event) {
this.menuItemService.getByPageId(this.pageId).subscribe(
(data) => {
this.disabledTarget = data!=null && data.length>0 ? data[0].type != MenuType.SHARED : true;
// console.log("# Broadcast event updateSharedPersonalTypology disabledTarget => " + this.disabledTarget);
if (this.disabledTarget){
this.page.get("shared").disable();
}else{
this.page.get("shared").enable();
}
},
error => (this.showError(error))
);
} else return;
});
}
};
getMessageDisabledTarget(){
return this.disabledTarget
? this.translateService.instant('dashboardPage.not_mandatory_field')
: this.translateService.instant('general.mandatory_field');
}
}
<nb-card *ngIf="!disabledTarget">
<nb-card-header >
<div class="d-flex flex-row justify-content-between align-items-center mt-2" [formGroup]="form" >
<div class="d-flex flex-row align-items-center mt-2" [formGroup]="form" >
<h4>
{{'general.targets'|translate}}
<nb-icon icon="info-outline" nbTooltip="{{'target.add_button_info'|translate}}" ></nb-icon>
......@@ -25,8 +25,8 @@
<nb-icon icon="person-outline"></nb-icon>{{'general.add' | translate}} {{'TargetType.PERSON'| translate}}
</button>
<!-- ROLES -->
<!--
ROLES
<nb-select *ngIf="!useIDM4Target" size="small" placeholder="{{'target.select_role'|translate}}" formControlName="selectedAvailableRole"
nbTooltip="{{'target.select_role'|translate}}">
<nb-option *ngFor="let role of filterTarget(fullListAvailableRole,'ROLE'); " [value]="role">
......@@ -36,16 +36,16 @@
<nb-select *ngIf="useIDM4Target" size="small" placeholder="{{'target.select_role'|translate}}" formControlName="selectedAvailableRoleIDM"
nbTooltip="{{'target.select_role'|translate}}">
<nb-option *ngFor="let role of filterIDMRoles(fullListAvailableRoleIDM); " [value]="role">
<!--{{role.name}} - {{role.description}}-->
{{role.name}}
</nb-option>
{{role.name}} - {{role.description}}-->
<!-- {{role.name}} -->
<!-- </nb-option>
</nb-select>
<button nbButton size="small" status="primary" (click)="addTargetRole()" >
<nb-icon icon="globe-2-outline"></nb-icon>{{'general.add' | translate}} {{'TargetType.ROLE'| translate}}
</button>
<!-- GROUPS -->
<nb-select *ngIf="!useIDM4Target" size="small" placeholder="{{'target.select_group'|translate}}" formControlName="selectedAvailableGroup"
GROUPS -->
<!-- <nb-select *ngIf="!useIDM4Target" size="small" placeholder="{{'target.select_group'|translate}}" formControlName="selectedAvailableGroup"
nbTooltip="{{'target.select_group'|translate}}">
<nb-option *ngFor="let group of filterTarget(fullListAvailableGroup,'GROUP'); " [value]="group">
{{group.code}} - {{group.value}}
......@@ -59,7 +59,7 @@
</nb-select>
<button nbButton size="small" status="primary" (click)="addTargetGroup()">
<nb-icon icon="globe-2-outline"></nb-icon>{{'general.add' | translate}} {{'TargetType.GROUP'| translate}}
</button>
</button> -->
</div>
......
import { NgModule } from '@angular/core';
import { NbMenuModule, NbDatepickerModule } from '@nebular/theme';
import { NbMenuModule, NbDatepickerModule, NbStepperModule } from '@nebular/theme';
import { ThemeModule } from '../@theme/theme.module';
import { PagesComponent } from './pages.component';
import { PagesRoutingModule } from './pages-routing.module';
......@@ -17,6 +17,7 @@ import { UtilitiesComponent } from './utilities/utilities.component';
SharedModule,
MiscellaneousModule,
TranslateModule,
NbStepperModule,
],
declarations: [
PagesComponent,
......
......@@ -54,7 +54,7 @@
"description": "Description",
"content": "Content",
"note": "Note",
"shared": "Published",
"shared": "Menu Type",
"createdDate": "Created Date",
"createdBy": "Created By",
"dashboardComponent": "Dashboard Component",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment