diff --git a/package-lock.json b/package-lock.json
index d1d7d2301b0b59cf6f3fc01cee5a40ad7ba4a799..034baa47c2ade305678e7be9e2c3a0ce9f88bc49 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15368,6 +15368,12 @@
         "tslib": "^2.0.0"
       }
     },
+    "ng2-completer": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/ng2-completer/-/ng2-completer-9.0.1.tgz",
+      "integrity": "sha512-zEKehHdCK8E/k4Y0HepprGdYBHr2AOsaq4QpeqoCyUElOOC5M3qi3ZEHV1VF54I7heBQktswwXe5UyWduJ0Xeg==",
+      "dev": true
+    },
     "ng2-smart-table": {
       "version": "1.6.0",
       "resolved": "https://registry.npmjs.org/ng2-smart-table/-/ng2-smart-table-1.6.0.tgz",
diff --git a/package.json b/package.json
index e4e59323acda71e633e480f8acfd09028465ba95..e5450467ff22408f3d118a115e3c4830df4dbda8 100644
--- a/package.json
+++ b/package.json
@@ -133,6 +133,7 @@
     "karma-coverage-istanbul-reporter": "~3.0.2",
     "karma-jasmine": "~4.0.0",
     "karma-jasmine-html-reporter": "^1.5.0",
+    "ng2-completer": "^9.0.1",
     "npm-run-all": "4.0.2",
     "protractor": "~7.0.0",
     "rimraf": "2.6.1",
diff --git a/src/app/model/clone-dashboard.model.ts b/src/app/model/clone-dashboard.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..924bf77d5bf331830b98fd97e87f2b80b28f16e5
--- /dev/null
+++ b/src/app/model/clone-dashboard.model.ts
@@ -0,0 +1,20 @@
+import { CloningOptionType } from "./enumeration/cloning-option-type.model";
+
+export interface ICloneDashboard {
+  id?: number;
+  dashboardName?: string;
+  option?: CloningOptionType | null;
+}
+
+export class CloneDashboard implements ICloneDashboard {
+  constructor(
+    public id?: number,
+    public dashboardName?: string,
+    public option?: CloningOptionType | null
+  ) {
+  }
+}
+
+export function getCloneDashboardIdentifier(cloneDashboard: ICloneDashboard): number | undefined {
+  return cloneDashboard.id;
+}
\ No newline at end of file
diff --git a/src/app/model/dashboard-component.model.ts b/src/app/model/dashboard-component.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e6e02aa25aee191f526e06d3aff330b47e169f3f
--- /dev/null
+++ b/src/app/model/dashboard-component.model.ts
@@ -0,0 +1,30 @@
+import { IDashboardPage } from "./dashboard-page.model";
+import { ComponentType } from "./enumeration/component-type.model";
+
+export interface IDashboardComponent {
+  id?: number;
+  componentType?: ComponentType;
+  componentName?: string;
+  componentcontent?: string | null;
+  componentPosition?: string | null;
+  //createdDate?: dayjs.Dayjs | null;
+  createdBy?: string | null;
+  dashboardPage?: IDashboardPage | null;
+}
+
+export class DashboardComponent implements IDashboardComponent {
+  constructor(
+    public id?: number,
+    public componentType?: ComponentType,
+    public componentName?: string,
+    public componentcontent?: string | null,
+    public componentPosition?: string | null,
+    //public createdDate?: dayjs.Dayjs | null,
+    public createdBy?: string | null,
+    public dashboardPage?: IDashboardPage | null
+  ) {}
+}
+
+export function getDashboardComponentIdentifier(dashboardComponent: IDashboardComponent): number | undefined {
+  return dashboardComponent.id;
+}
diff --git a/src/app/model/dashboard-page.model.ts b/src/app/model/dashboard-page.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fbf9a1c20ebed736b8c1a7ae2ef7bbf979936b69
--- /dev/null
+++ b/src/app/model/dashboard-page.model.ts
@@ -0,0 +1,44 @@
+import { IDashboardComponent } from "./dashboard-component.model";
+import { MenuType } from "./enumeration/menu-type.model";
+import { IMenuItem } from "./menu-item.model";
+import { ITarget } from "./target.model";
+
+export interface IDashboardPage {
+  id?: number;
+  name?: string;
+  description?: string | null;
+  content?: string;
+  note?: string | null;
+  shared?: boolean | null;
+  pageOwner?: boolean | null;
+  type?: MenuType | null,
+  //createdDate?: dayjs.Dayjs | null;
+  createdBy?: string | null;
+  dashboardComponents?: IDashboardComponent[] | null;
+  menuItem?: IMenuItem | null;
+  targets?: ITarget[] | null;
+}
+
+export class DashboardPage implements IDashboardPage {
+  constructor(
+    public id?: number,
+    public name?: string,
+    public description?: string | null,
+    public content?: string,
+    public note?: string | null,
+    public shared?: boolean | null,
+    public pageOwner?: boolean | null,
+    public type?: MenuType | null,
+    //public createdDate?: dayjs.Dayjs | null,
+    public createdBy?: string | null,
+    public dashboardComponents?: IDashboardComponent[] | null,
+    public menuItem?: IMenuItem | null,
+    public targets?: ITarget[] | null
+  ) {
+    this.shared = this.shared ?? false;
+  }
+}
+
+export function getDashboardPageIdentifier(dashboardPage: IDashboardPage): number | undefined {
+  return dashboardPage.id;
+}
\ No newline at end of file
diff --git a/src/app/model/enumeration/cloning-option-type.model.ts b/src/app/model/enumeration/cloning-option-type.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8cad56724b22eb1cf44c12a24606f77b9eb53145
--- /dev/null
+++ b/src/app/model/enumeration/cloning-option-type.model.ts
@@ -0,0 +1,20 @@
+export enum CloningOptionType {
+    NONE =      'NONE',
+    MENU =      'MENU',
+    TARGETS =   'TARGETS',
+    COMPONENTS ='COMPONENTS',
+    ALL =       'ALL',
+  }
+  
+  export namespace CloningOptionType {
+    export function values() {
+      return Object.keys(CloningOptionType)
+        .filter((type) => isNaN(<any>type) && type !== 'values')
+        .map((x) => {
+          return {
+            enumVal: x,
+            value: x,
+          };
+        });
+    }
+  }
\ No newline at end of file
diff --git a/src/app/model/enumeration/component-type.model.ts b/src/app/model/enumeration/component-type.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4c7947a6fe227f069d32201a3cfc5e10d26dac51
--- /dev/null
+++ b/src/app/model/enumeration/component-type.model.ts
@@ -0,0 +1,23 @@
+export enum ComponentType {
+  TEXT = 'TEXT',
+  IMAGE = 'IMAGE',
+  CHART = 'CHART',
+  IFRAME = 'IFRAME',
+  WEATHER = 'WEATHER',
+  MAP = 'MAP',
+  STATISTICS = 'STATISTICS'
+}
+
+
+export namespace ComponentType {
+  export function values() {
+    return Object.keys(ComponentType)
+      .filter((type) => isNaN(<any>type) && type !== 'values')
+      .map((x) => {
+        return {
+          enumVal: x,
+          value: x,
+        };
+      });
+  }
+}
diff --git a/src/app/model/enumeration/menu-type.model.ts b/src/app/model/enumeration/menu-type.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..08ad953ec02da0fb9bb41227a6413a639d489984
--- /dev/null
+++ b/src/app/model/enumeration/menu-type.model.ts
@@ -0,0 +1,17 @@
+export enum MenuType {
+  SHARED = 'SHARED',
+  PERSONAL = 'PERSONAL',
+}
+
+export namespace MenuType {
+  export function values() {
+    return Object.keys(MenuType)
+      .filter((type) => isNaN(<any>type) && type !== 'values')
+      .map((x) => {
+        return {
+          enumVal: x,
+          value: x,
+        };
+      });
+  }
+}
\ No newline at end of file
diff --git a/src/app/model/enumeration/target-type.model.ts b/src/app/model/enumeration/target-type.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f4788fd82245dbbe5b3b164a01440c3ca76a782d
--- /dev/null
+++ b/src/app/model/enumeration/target-type.model.ts
@@ -0,0 +1,18 @@
+export enum TargetType {
+  PERSON = 'PERSON',
+  GROUP = 'GROUP',
+  ROLE = 'ROLE',
+}
+
+export namespace TargetType {
+  export function values() {
+    return Object.keys(TargetType)
+      .filter((type) => isNaN(<any>type) && type !== 'values')
+      .map((x) => {
+        return {
+          enumVal: x,
+          value: x,
+        };
+      });
+  }
+}
\ No newline at end of file
diff --git a/src/app/model/group-representation.model.ts b/src/app/model/group-representation.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..90a3ed963d767f4bdffe73c236c280389d0592e6
--- /dev/null
+++ b/src/app/model/group-representation.model.ts
@@ -0,0 +1,20 @@
+
+export interface IGroupRepresentation {
+    id?: string;
+    name?: string;
+    path?: string;
+    subGroups?: Array<IGroupRepresentation>;
+  }
+  
+  export class GroupRepresentation implements IGroupRepresentation {
+    constructor(
+      public id?: string,
+      public name?: string,
+      public path?: string,
+      public subGroups?:  Array<IGroupRepresentation>
+    ) {}
+  }
+  
+  export function getGroupRepresentationIdentifier(groupRepresentation: IGroupRepresentation): string | undefined {
+    return groupRepresentation.id;
+  }
\ No newline at end of file
diff --git a/src/app/model/menu-block.model.ts b/src/app/model/menu-block.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7f8c9c05cfba07ef54f3158420ef03f40286389c
--- /dev/null
+++ b/src/app/model/menu-block.model.ts
@@ -0,0 +1,32 @@
+import { MenuType } from "./enumeration/menu-type.model";
+import { IMenuItem } from "./menu-item.model";
+
+export interface IMenuBlock {
+    id?: number;
+    code?: string;
+    label?: string;
+    order?: number | null;
+    type?: MenuType;
+    icon?: string;
+    //createdDate?: dayjs.Dayjs | null;
+    createdBy?: string | null;
+    linkedItems?: IMenuItem[] | null;
+  }
+  
+  export class MenuBlock implements IMenuBlock {
+    constructor(
+      public id?: number,
+      public code?: string,
+      public label?: string,
+      public order?: number | null,
+      public type?: MenuType,
+      public icon?: string,
+      //public createdDate?: dayjs.Dayjs | null,
+      public createdBy?: string | null,
+      public linkedItems?: IMenuItem[] | null
+    ) {}
+  }
+  
+  export function getMenuBlockIdentifier(menuBlock: IMenuBlock): number | undefined {
+    return menuBlock.id;
+  }
\ No newline at end of file
diff --git a/src/app/model/menu-item.model.ts b/src/app/model/menu-item.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0606319f344a272a87b6a3439e88958121a6e0dd
--- /dev/null
+++ b/src/app/model/menu-item.model.ts
@@ -0,0 +1,35 @@
+import { IDashboardPage } from "./dashboard-page.model";
+import { MenuType } from "./enumeration/menu-type.model";
+import { IMenuBlock } from "./menu-block.model";
+
+export interface IMenuItem {
+  id?: number;
+  code?: string;
+  label?: string;
+  order?: number | null;
+  type?: MenuType;
+  icon?: string;
+  //createdDate?: dayjs.Dayjs | null;
+  createdBy?: string | null;
+  dashboardPage?: IDashboardPage | null;
+  menuBlock?: IMenuBlock | null;
+}
+
+export class MenuItem implements IMenuItem {
+  constructor(
+    public id?: number,
+    public code?: string,
+    public label?: string,
+    public order?: number | null,
+    public type?: MenuType,
+    public icon?: string,
+    //public createdDate?: dayjs.Dayjs | null,
+    public createdBy?: string | null,
+    public dashboardPage?: IDashboardPage | null,
+    public menuBlock?: IMenuBlock | null
+  ) {}
+}
+
+export function getMenuItemIdentifier(menuItem: IMenuItem): number | undefined {
+  return menuItem.id;
+}
diff --git a/src/app/model/role-representation.model.ts b/src/app/model/role-representation.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8756614218cb0756f889de7e79497ff1c4df0995
--- /dev/null
+++ b/src/app/model/role-representation.model.ts
@@ -0,0 +1,22 @@
+
+export interface IRoleRepresentation {
+    id?: string;
+    name?: string;
+    description?: string;
+    composite?: boolean;
+    clientRole?: boolean;
+  }
+  
+  export class RoleRepresentation implements IRoleRepresentation {
+    constructor(
+      public id?: string,
+      public name?: string,
+      public description?: string,
+      public composite?: boolean,
+      public clientRole?: boolean
+    ) {}
+  }
+  
+  export function getRoleRepresentationIdentifier(roleRepresentation: IRoleRepresentation): string | undefined {
+    return roleRepresentation.id;
+  }
\ No newline at end of file
diff --git a/src/app/model/target-available.model.ts b/src/app/model/target-available.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..96a1d45b66226de70f2e83cc21fe3ce0eab04e2f
--- /dev/null
+++ b/src/app/model/target-available.model.ts
@@ -0,0 +1,25 @@
+import { TargetType } from "./enumeration/target-type.model";
+
+export interface ITargetAvailable {
+  id?: number;
+  type?: TargetType;
+  code?: string;
+  value?: string;
+  //createdDate?: dayjs.Dayjs | null;
+  createdBy?: string | null;
+}
+
+export class TargetAvailable implements ITargetAvailable {
+  constructor(
+    public id?: number,
+    public type?: TargetType,
+    public code?: string,
+    public value?: string,
+    //public createdDate?: dayjs.Dayjs | null,
+    public createdBy?: string | null
+  ) {}
+}
+
+export function getTargetAvailableIdentifier(targetAvailable: ITargetAvailable): number | undefined {
+  return targetAvailable.id;
+}
\ No newline at end of file
diff --git a/src/app/model/target.model.ts b/src/app/model/target.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5f34f2d460bce8924a97a325b4a5a12873e8ebd2
--- /dev/null
+++ b/src/app/model/target.model.ts
@@ -0,0 +1,28 @@
+import { IDashboardPage } from "./dashboard-page.model";
+import { TargetType } from "./enumeration/target-type.model";
+
+export interface ITarget {
+  id?: number;
+  type?: TargetType;
+  name?: string;
+  note?: string | null;
+  //createdDate?: dayjs.Dayjs | null;
+  createdBy?: string | null;
+  dashboardPage?: IDashboardPage | null;
+}
+
+export class Target implements ITarget {
+  constructor(
+    public id?: number,
+    public type?: TargetType,
+    public name?: string,
+    public note?: string | null,
+    //public createdDate?: dayjs.Dayjs | null,
+    public createdBy?: string | null,
+    public dashboardPage?: IDashboardPage | null
+  ) {}
+}
+
+export function getTargetIdentifier(target: ITarget): number | undefined {
+  return target.id;
+}
\ No newline at end of file
diff --git a/src/app/model/user.model.ts b/src/app/model/user.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..32a565db04bf2880d7a299e226c4a31ad9d18c11
--- /dev/null
+++ b/src/app/model/user.model.ts
@@ -0,0 +1,22 @@
+
+export interface IUser {
+  id?: string;
+  username?: string;
+  firstName?: string;
+  lastName?: string;
+  email?: string;
+}
+
+export class User implements IUser {
+  constructor(
+    public id?: string,
+    public username?: string,
+    public firstName?: string,
+    public lastName?: string,
+    public email?: string
+  ) {}
+}
+
+export function getUserIdentifier(user: IUser): string | undefined {
+  return user.id;
+}
\ No newline at end of file
diff --git a/src/app/pages/dashboard-management/chart-view/chart-view.component.html b/src/app/pages/dashboard-management/chart-view/chart-view.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..e85cf3ee88a3ed3c6650c41a1d0766fa66b13b9c
--- /dev/null
+++ b/src/app/pages/dashboard-management/chart-view/chart-view.component.html
@@ -0,0 +1,7 @@
+
+<div [innerHTML]="chartContent | safeHtml">
+</div>
+
+<!--
+<iframe [src]="chartContent | safeHtml"></iframe>
+-->
diff --git a/src/app/pages/dashboard-management/chart-view/chart-view.component.scss b/src/app/pages/dashboard-management/chart-view/chart-view.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/pages/dashboard-management/chart-view/chart-view.component.spec.ts b/src/app/pages/dashboard-management/chart-view/chart-view.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..68b0e808a512b4336c9fcc8fc591127e76c089f4
--- /dev/null
+++ b/src/app/pages/dashboard-management/chart-view/chart-view.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ChartViewComponent } from './chart-view.component';
+
+describe('ChartViewComponent', () => {
+  let component: ChartViewComponent;
+  let fixture: ComponentFixture<ChartViewComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ ChartViewComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ChartViewComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/chart-view/chart-view.component.ts b/src/app/pages/dashboard-management/chart-view/chart-view.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1a4cb1f66fa44e642e7dd3a18465061352e45eb1
--- /dev/null
+++ b/src/app/pages/dashboard-management/chart-view/chart-view.component.ts
@@ -0,0 +1,17 @@
+import { Component, Input, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'ngx-chart-view',
+  templateUrl: './chart-view.component.html',
+  styleUrls: ['./chart-view.component.scss']
+})
+export class ChartViewComponent implements OnInit {
+  @Input() chartContent: string;
+
+  constructor() { 
+  }
+
+  ngOnInit(): void {
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/dashboard-clone-wizard/dashboard-clone-wizard.component.html b/src/app/pages/dashboard-management/dashboard-clone-wizard/dashboard-clone-wizard.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..0deea456a0c68a64600749a8c7194cef9c3eb84a
--- /dev/null
+++ b/src/app/pages/dashboard-management/dashboard-clone-wizard/dashboard-clone-wizard.component.html
@@ -0,0 +1,156 @@
+<nb-card>
+    <nb-card-body>
+        <nb-stepper orientation="horizontal">
+            <nb-step [label]="labelOne"
+                [stepControl]="selectedDashboardFormGroup.invalid || !isEmptyObject(selectedDashboardFormGroup.value.selectedDashboard)">
+                <form [formGroup]="selectedDashboardFormGroup" (ngSubmit)="onSubmitFirst(selectedDashboard)">
+                    <ng-template #labelOne>{{'dashboardClone.step_one'|translate}}</ng-template>
+                    <h4>{{'dashboardClone.question_one'|translate}}</h4>
+
+                    <div class="d-flex flex-row align-items-end">
+                        <div class="d-flex flex-column">
+                            <label for="name" class="label mr-2">
+                                {{'dashboardClone.source_dashboard'|translate}} *
+                            </label>
+                            <nb-select size="medium" placeholder="{{'dashboardClone.select_dashboard'|translate}}"
+                                formControlName="selectedDashboard" [(selected)]="selectedDashboard">
+                                <nb-option-group title="{{'MenuType.SHARED'|translate}}">
+                                    <nb-option *ngFor="let dashboardPage of fullListDashboardPageShared;"
+                                        [value]="dashboardPage">
+                                        {{dashboardPage.name}}
+                                    </nb-option>
+                                </nb-option-group>
+                                <nb-option-group title="{{'MenuType.PERSONAL'|translate}}">
+                                    <nb-option *ngFor="let dashboardPage of fullListDashboardPagePersonal;"
+                                        [value]="dashboardPage">
+                                        {{dashboardPage.name}}
+                                    </nb-option>
+                                </nb-option-group>
+                            </nb-select>
+                        </div>
+
+
+                        <div class="ml-3">
+                            <button nbButton size="small" status="info"
+                                nbTooltip="{{'dashboardClone.action_preview'|translate}}"
+                                (click)="previewDashboard(selectedDashboardFormGroup.value.selectedDashboard.id)">
+                                {{'dashboardClone.action_preview'|translate}}
+                            </button>
+                            <nb-icon class="ml-2" icon="info-outline" nbTooltip="{{'dashboardClone.info'|translate}}">
+                            </nb-icon>
+                        </div>
+                    </div>
+
+
+                    <div class="row my-2 mt-50">
+                        <div class="col-sm text-center">
+                            <button nbButton size="small" status="primary" nbStepperPrevious disabled type="button">
+                                {{'dashboardClone.action_prev'|translate}}
+                            </button>
+                        </div>
+                        <div class="col-sm text-center">
+                            <button nbButton size="small" status="primary" nbStepperNext
+                                [disabled]="selectedDashboardFormGroup.invalid || !isEmptyObject(selectedDashboardFormGroup.value.selectedDashboard)"
+                                type="submit"
+                                (click)="onSubmitFirst(selectedDashboardFormGroup.value.selectedDashboard)">
+                                {{'dashboardClone.action_next'|translate}}
+                            </button>
+                        </div>
+                    </div>
+                </form>
+            </nb-step>
+
+
+
+            <nb-step [label]="labelTwo" [stepControl]="createdDashboardFormGroup">
+                <form [formGroup]="createdDashboardFormGroup" (ngSubmit)="onSubmitSecond(createdDashboardFormGroup.value.createdDashboardName, 
+                    createdDashboardFormGroup.value.createdDashboardCloneTargets)">
+                    <ng-template #labelTwo>
+                        {{'dashboardClone.step_two'|translate}}
+                    </ng-template>
+                    <h4>{{'dashboardClone.question_two'|translate}}</h4>
+
+                    <div class="d-flex flex-column">
+                        <label for="name" class="label mr-2">
+                            {{'dashboardClone.cloned_dashboard_name'|translate}} *
+                        </label>
+                        <input type="text" nbInput placeholder=" {{'dashboardClone.add_dashboard_name'|translate}}"
+                            formControlName="createdDashboardName">
+                    </div>
+                    <div *ngIf="getSharedStatus()" class="m-3">
+                        <nb-toggle labelPosition="end" formControlName="createdDashboardCloneTargets">
+                            {{'dashboardClone.clone_targets'|translate}}
+                        </nb-toggle>
+                    </div>
+                    <div class="row my-2">
+                        <div class="col-sm text-center">
+                            <button nbButton size="small" status="primary" nbStepperPrevious type="button">
+                                {{'dashboardClone.action_prev'|translate}}
+                            </button>
+                        </div>
+                        <div class="col-sm text-center">
+                            <button nbButton size="small" status="primary" nbStepperNext
+                                [disabled]="createdDashboardFormGroup.invalid" type="submit"
+                                (click)="onSubmitSecond(createdDashboardFormGroup.value.createdDashboardName, createdDashboardFormGroup.value.createdDashboardCloneTargets)">
+
+                                {{'dashboardClone.action_next'|translate}}
+                            </button>
+                        </div>
+                    </div>
+                </form>
+            </nb-step>
+
+
+
+            <nb-step label="{{'dashboardClone.step_three'|translate}}">
+                <h4>{{'dashboardClone.question_three'|translate}}</h4>
+                <nb-card>
+                    <nb-list>
+                        <nb-list-item>
+                            <nb-user name="{{'dashboardClone.question_one'|translate}}"
+                                title="{{selectedDashboardFormGroup.value.selectedDashboard.name}}"
+                                picture="/assets/images/browser-outline.png" shape="semi-round">
+                            </nb-user>
+                        </nb-list-item>
+                        <nb-icon icon=" info-outline" nbTooltip="{{'dashboardClone.action_preview'|translate}}"
+                            (click)="previewDashboard(selectedDashboardFormGroup.value.selectedDashboard.id)">
+                        </nb-icon>
+                        <nb-list-item>
+                            <nb-user name="{{'dashboardClone.question_two'|translate}}"
+                                title="{{createdDashboardFormGroup.value.createdDashboardName}}"
+                                picture="/assets/images/edit-outline.png" shape="semi-round">
+                            </nb-user>
+                        </nb-list-item>
+                        <nb-list-item>
+                            <nb-user name="{{'dashboardClone.question_targets'|translate}}"
+                                title="{{createdDashboardFormGroup.value.createdDashboardCloneTargets}}"
+                                picture="/assets/images/checkmark-outline.png" shape="semi-round"
+                                *ngIf="createdDashboardFormGroup.value.createdDashboardCloneTargets !== null && createdDashboardFormGroup.value.createdDashboardCloneTargets !== false">
+                            </nb-user>
+                            <nb-user name="{{'dashboardClone.question_targets'|translate}}"
+                                title="{{createdDashboardFormGroup.value.createdDashboardCloneTargets}}"
+                                picture="/assets/images/close-outline.png" shape="semi-round"
+                                *ngIf="!(createdDashboardFormGroup.value.createdDashboardCloneTargets !== null && createdDashboardFormGroup.value.createdDashboardCloneTargets !== false)">
+                            </nb-user>
+                        </nb-list-item>
+                    </nb-list>
+                </nb-card>
+                <div class="row my-2">
+                    <div class="col-sm text-center">
+                        <button nbButton size="small" status="primary" nbStepperPrevious type="button">
+                            {{'dashboardClone.action_prev'|translate}}
+                        </button>
+                    </div>
+                    <div class="col-sm text-center">
+                        <button nbButton size="small" status="primary" nbStepperNext (click)="executeClone()"
+                            type="submit">
+                            {{'dashboardClone.action_clone'|translate}}
+                        </button>
+                    </div>
+                </div>
+            </nb-step>
+
+
+        </nb-stepper>
+    </nb-card-body>
+</nb-card>
\ No newline at end of file
diff --git a/src/app/pages/dashboard-management/dashboard-clone-wizard/dashboard-clone-wizard.component.scss b/src/app/pages/dashboard-management/dashboard-clone-wizard/dashboard-clone-wizard.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/pages/dashboard-management/dashboard-clone-wizard/dashboard-clone-wizard.component.spec.ts b/src/app/pages/dashboard-management/dashboard-clone-wizard/dashboard-clone-wizard.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8fa4049b58a21194cc9424a6b28d7cdc2e30b791
--- /dev/null
+++ b/src/app/pages/dashboard-management/dashboard-clone-wizard/dashboard-clone-wizard.component.spec.ts
@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { DashboardCloneWizardComponent } from './dashboard-clone-wizard.component';
+
+describe('DashboardCloneWizardComponent', () => {
+  let component: DashboardCloneWizardComponent;
+  let fixture: ComponentFixture<DashboardCloneWizardComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ DashboardCloneWizardComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(DashboardCloneWizardComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/dashboard-clone-wizard/dashboard-clone-wizard.component.ts b/src/app/pages/dashboard-management/dashboard-clone-wizard/dashboard-clone-wizard.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d65a19ea5311916a30f82e43908dd9ae9ae7ebb7
--- /dev/null
+++ b/src/app/pages/dashboard-management/dashboard-clone-wizard/dashboard-clone-wizard.component.ts
@@ -0,0 +1,138 @@
+import { Component, OnInit } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { MatDialog } from '@angular/material/dialog';
+import { ActivatedRoute, Router } from '@angular/router';
+import { NbToastrService } from '@nebular/theme';
+import { TranslateService } from '@ngx-translate/core';
+import { ICloneDashboard } from '../../../model/clone-dashboard.model';
+import { IDashboardPage } from '../../../model/dashboard-page.model';
+import { CloningOptionType } from '../../../model/enumeration/cloning-option-type.model';
+import { MenuType } from '../../../model/enumeration/menu-type.model';
+import { ITarget } from '../../../model/target.model';
+import { ManageDashboardPageContentComponent } from '../manage-dashboard-page-content/manage-dashboard-page-content.component';
+import { DashboardPageCrudService } from '../services/dashboard-page-crud.service';
+
+@Component({
+  selector: 'ngx-dashboard-clone-wizard',
+  templateUrl: './dashboard-clone-wizard.component.html',
+  styleUrls: ['./dashboard-clone-wizard.component.scss']
+})
+export class DashboardCloneWizardComponent implements OnInit {
+  selectedDashboardFormGroup: FormGroup;
+  createdDashboardFormGroup: FormGroup;
+  selectedDashboard: IDashboardPage = {};
+  createdDashboard: ICloneDashboard = {}; 
+  createdDashboardCloneTargets: ITarget;
+  selectedDashboardFromRoute: IDashboardPage = {};
+  private foundDashboard: IDashboardPage;
+
+  fullListEditableDashboards: Array<IDashboardPage> = [];
+  fullListDashboardPageShared: Array<IDashboardPage> = [];
+  fullListDashboardPagePersonal: Array<IDashboardPage> = [];
+
+  public parsedId =  0; 
+
+  private CLONED_SUFFIX = " (cloned)";
+
+  constructor(
+    private readonly formBuilder: FormBuilder,
+    private dashboardPageCrudService: DashboardPageCrudService,
+    private toastrService: NbToastrService,
+    private translateService: TranslateService,
+    private router: Router,
+    private route: ActivatedRoute,
+    private dialogService: MatDialog
+  ) { }
+
+  ngOnInit(): void {
+    this.selectedDashboardFormGroup = this.formBuilder.group({
+      selectedDashboard: [this.selectedDashboard, Validators.nullValidator]
+    });
+
+    this.createdDashboardFormGroup = this.formBuilder.group({
+      createdDashboardName: [this.createdDashboard.dashboardName, Validators.required],
+      createdDashboardCloneTargets: [this.createdDashboardCloneTargets, ''],
+    });
+
+    this.dashboardPageCrudService.getClonablePages().subscribe(
+      (res) => {
+      this.fullListEditableDashboards = res;
+      this.fullListDashboardPageShared = this.fullListEditableDashboards.filter(x => x.type == MenuType.SHARED);
+      this.fullListDashboardPagePersonal = this.fullListEditableDashboards.filter(x => x.type == MenuType.PERSONAL);
+
+      this.route.queryParams.subscribe(params => {
+        if (params['parsedId'] != undefined && params['parsedId'] != null) {
+          this.parsedId = params['parsedId'];
+          this.foundDashboard = this.fullListEditableDashboards.find(x => x.id == this.parsedId);
+          this.selectedDashboardFormGroup.patchValue( { selectedDashboard: this.foundDashboard });  
+        }
+      });
+    },
+      error => (this.showError(error))
+    );
+  }
+
+  getSharedStatus(){
+    return this.selectedDashboardFormGroup.value.selectedDashboard?.type == 'SHARED' ? true : false;
+  }
+
+  isEmptyObject(object: any){
+    return !!Object.keys(object).length;
+  }
+
+  onSubmitFirst(selected : IDashboardPage){
+    this.selectedDashboard = selected;
+    this.createdDashboardFormGroup.patchValue( { createdDashboardName: (this.selectedDashboard.name + this.CLONED_SUFFIX) });  
+  }
+
+  onSubmitSecond(name: any , targets: any){
+    this.createdDashboard.dashboardName = name;
+    if (targets !== undefined && targets !== null){
+      this.createdDashboardCloneTargets = targets;
+    }
+  }
+
+  /** Invoke API to clone the Dashboard */
+  executeClone(){
+    //console.log("## selectedDashboard.id: "+ this.selectedDashboard.id + "  selectedDashboard:" + this.selectedDashboard);
+    if (this.selectedDashboard.id == null || this.selectedDashboard.id == undefined){
+      this.showError(this.translateService.instant('dashboardClone.clone_missing_parameter'));
+    }
+    this.createdDashboard.id = this.selectedDashboard.id;
+    if (this.createdDashboard){
+      this.createdDashboard.option = CloningOptionType.TARGETS;
+    }
+    this.dashboardPageCrudService.duplicatePageWithParams(this.createdDashboard)    
+    .subscribe( (res) => {
+        console.log('## Dashboard has been succesfully cloned, (original) id: ' + this.createdDashboard.id);
+        this.router.navigate(['/pages/dashboard-management/manage-dashboard-pages']);
+        this.showSuccess();
+      },err => {
+        console.log("# Error during cloning due to e: " + err);
+        this.showError(err);
+    });
+
+  }
+
+  showSuccess() {
+    this.toastrService.success(this.translateService.instant('dashboardPage.succesfully_cloned'), this.translateService.instant('Success'));
+  }
+
+  showError(error) {
+    this.toastrService.danger(error.message, this.translateService.instant('general.error'))
+  }
+
+  previewDashboard(id: number) {
+    if (id !== null && id !== undefined) {
+      let dialogRef = this.dialogService.open(ManageDashboardPageContentComponent, {
+        height: '720px',
+        width: '1280px',
+        data: {
+          parsedId: this.selectedDashboard.id,
+          parsedEditMode: false,
+        }
+      });
+    }
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/dashboard-component-dialog/dashboard-component-dialog.component.html b/src/app/pages/dashboard-management/dashboard-component-dialog/dashboard-component-dialog.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..db76a42a97745894841a30d16e62a0e43019d271
--- /dev/null
+++ b/src/app/pages/dashboard-management/dashboard-component-dialog/dashboard-component-dialog.component.html
@@ -0,0 +1,150 @@
+<nb-card>
+    <nb-card-header>{{'dashboardComponent.properties'|translate}}</nb-card-header>
+
+    <nb-card-body>
+        <div class="d-flex flex-column">
+            <div class="item-select">
+                <label class="label mr-2">{{'dashboardComponent.selectComponentType'|translate}}</label>
+                <nb-select size="small" placeholder="{{'dashboardComponent.selectComponentType'|translate}}"
+                    [(selected)]="selectedItemType">
+                    <nb-option value='TEXT'>{{'ComponentType.TEXT'|translate}}</nb-option>
+                    <nb-option value='IMAGE'>{{'ComponentType.IMAGE'|translate}}</nb-option>
+                    <nb-option value='CHART'>{{'ComponentType.CHART'|translate}}</nb-option>
+                    <nb-option value='IFRAME'>{{'ComponentType.IFRAME'|translate}}</nb-option>
+                    <nb-option value='STATISTICS'>{{'ComponentType.STATISTICS'|translate}}</nb-option>
+                    <!--<nb-option value='MAP'>{{'ComponentType.MAP'|translate}}</nb-option>-->
+                    <nb-option value='WEATHER'>{{'ComponentType.WEATHER'|translate}}</nb-option>
+                </nb-select>
+            </div>
+        </div>
+        <div class="d-flex flex-column">
+            <p></p>
+        </div>
+
+        <div *ngIf="selectedItemType=='TEXT'">
+            <angular-editor [placeholder]="'dashboardComponent.fill_text'|translate" [(ngModel)]="item.text"
+                [config]="editorConfig"></angular-editor>
+        </div>
+
+        <div *ngIf="selectedItemType=='IMAGE'">
+            <div *ngIf="item.image !== undefined && item.image !== null && item.url == false" class="image-preview">
+                <img [src]="item.image" [alt]="item.image">
+            </div>
+            <div *ngIf="item.imageUrl !== undefined && item.imageUrl !== null && item.url == true"
+                class="image-preview">
+                <img [src]="item.imageUrl" [alt]="item.imageUrl">
+            </div>
+            <nb-radio-group [(ngModel)]="selectedOption">
+                <nb-radio value="upload-file">{{'dashboardComponent.upload_from_file'|translate}}</nb-radio>
+                <nb-radio value="upload-url">{{'dashboardComponent.upload_from_url/base64'|translate}}</nb-radio>
+            </nb-radio-group>
+            <div [hidden]="getHiddenFileUploadBlock()">
+                <label class="label mr-2">{{'dashboardComponent.label_upload_image'|translate}}</label>
+                <button type="button" nbButton
+                    (click)="fileInput.click()">{{'dashboardComponent.choose_file'|translate}}</button>
+
+                <input hidden type="file" id="file" (change)="fileChangeEvent($event)" #fileInput />
+                <image-cropper [imageChangedEvent]="imageChangedEvent"
+                    [maintainAspectRatio]="maintainAspectRatioVariable" [aspectRatio]="aspectRatioVariable" format="jpg"
+                    (imageCropped)="imageCropped($event)" (imageLoaded)="imageLoaded()" (cropperReady)="cropperReady()"
+                    (loadImageFailed)="loadImageFailed()">
+                </image-cropper>
+            </div>
+
+            <div *ngIf="item.url=='true' || selectedOption == 'upload-url'">
+                <label class="label mr-2">{{'dashboardComponent.label_image_url'|translate}}</label>
+                <textarea nbInput fullWidth placeholder="{{'dashboardComponent.fill_image'|translate}}" rows="8"
+                    [(ngModel)]="item.imageUrl"></textarea>
+            </div>
+        </div>
+
+        <div *ngIf="selectedItemType=='CHART'" class="chart-select">
+            <label class="label mr-2">{{'dashboardComponent.label_datalet'|translate}}</label>
+            <nb-select placeholder="{{'dashboardComponent.select_datalet'|translate}}" [(selected)]="dataletObject">
+                <nb-option *ngFor="let datalet of datalets" [value]='datalet'> {{ datalet.title }}
+                </nb-option>
+            </nb-select>
+        </div>
+
+        <div *ngIf="selectedItemType=='CHART' 
+            && dataletObject !== undefined && dataletObject !== null 
+            && dataletObject.datalet_html !== undefined && dataletObject.datalet_html !== null"
+            [innerHTML]="dataletObject.datalet_html | safeHtml">
+        </div>
+
+        <div *ngIf="selectedItemType=='IFRAME'">
+            <div>
+                <label class="label mr-2">{{'dashboardComponent.label_content'|translate}}</label>
+                <textarea nbInput fullWidth placeholder="{{'dashboardComponent.fill_iframe'|translate}}" rows="8"
+                    [(ngModel)]="item.iframe"></textarea>
+            </div>
+        </div>
+
+        <!-- MAP -->
+        <div *ngIf="selectedItemType=='MAP'">
+            <div>
+                <label class="label mr-2">{{'dashboardComponent.label_title'|translate}}</label>
+                <textarea nbInput fullWidth placeholder="{{'dashboardComponent.fill_map_title'|translate}}"
+                    [(ngModel)]="item.map_title"></textarea>
+            </div>
+            <div>
+                <label class="label mr-2">{{'dashboardComponent.label_geoJsonurl'|translate}}</label>
+                <textarea nbInput fullWidth
+                    placeholder="{{'dashboardComponent.fill_map'|translate}} {{'dashboardComponent.example_map_url'|translate}}"
+                    rows="8" [(ngModel)]="item.map"></textarea>
+            </div>
+        </div>
+        
+        <div *ngIf="selectedItemType=='WEATHER'">
+            <div>
+                <label class="label mr-2">{{'dashboardComponent.label_title'|translate}}</label>
+                <textarea nbInput fullWidth placeholder="{{'dashboardComponent.fill_weather_title'|translate}}"
+                    [(ngModel)]="item.weather_title"></textarea>
+            </div>
+            <div>
+                <label class="label mr-2">{{'dashboardComponent.label_subtitle'|translate}}</label>
+                <textarea nbInput fullWidth placeholder="{{'dashboardComponent.fill_weather_subtitle'|translate}}"
+                    [(ngModel)]="item.weather_subtitle"></textarea>
+            </div>
+        </div>
+
+        <div *ngIf="selectedItemType=='STATISTICS'">
+            <div>
+                <label class="label mr-2">{{'dashboardComponent.label_title'|translate}}</label>
+                <textarea nbInput fullWidth placeholder="{{'dashboardComponent.fill_statistics_title'|translate}}"
+                    [(ngModel)]="item.statistics_title"></textarea>
+            </div>
+            <div>
+                <label class="label mr-2">{{'dashboardComponent.label_subtitle'|translate}}</label>
+                <textarea nbInput fullWidth placeholder="{{'dashboardComponent.fill_statistics_subtitle'|translate}}"
+                    [(ngModel)]="item.statistics_subtitle"></textarea>
+            </div>
+            <div>
+                <label class="label mr-2">{{'dashboardComponent.label_value'|translate}}</label>
+                <textarea nbInput fullWidth placeholder="{{'dashboardComponent.fill_statistics_value'|translate}}"
+                    [(ngModel)]="item.statistics_value"></textarea>
+            </div>
+            <div>
+                <label class="label mr-2">{{'dashboardComponent.label_icon'|translate}}</label>
+                <nb-icon [icon]="item.statistics_icon">{{item.statistics_icon}}</nb-icon>
+                <nb-select fullWidth size="small" placeholder="{{'dashboardComponent.fill_statistics_icon'|translate}}"
+                    [(ngModel)]="item.statistics_icon">
+                    <nb-option *ngFor="let icon of statisticsIcons" [value]='icon'> {{ icon }} </nb-option>
+                </nb-select>
+            </div>
+        </div>
+    </nb-card-body>
+
+    <nb-card-footer>
+        <div class="row my-2">
+            <div class="col-sm text-center">
+                <button nbButton status="danger" size="small"
+                    (click)="onCancelClick()">{{'general.cancel'|translate}}</button>
+            </div>
+            <div class="col-sm text-center">
+                <button nbButton status="info" size="small" (click)="onSaveClick(item, selectedItemType)"
+                    cdkFocusInitial>{{'general.save'|translate}}</button>
+            </div>
+        </div>
+    </nb-card-footer>
+</nb-card>
\ No newline at end of file
diff --git a/src/app/pages/dashboard-management/dashboard-component-dialog/dashboard-component-dialog.component.scss b/src/app/pages/dashboard-management/dashboard-component-dialog/dashboard-component-dialog.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..434730d041210cb7496b4b668a5fe00d3ac749f7
--- /dev/null
+++ b/src/app/pages/dashboard-management/dashboard-component-dialog/dashboard-component-dialog.component.scss
@@ -0,0 +1,29 @@
+nb-card {
+  min-width: 800px;
+  min-height: 500px;
+  max-width: 95vw;
+  max-height: 95vh;
+}
+
+.item-select {
+  display: inline-block;
+}
+
+.chart-select {
+  display: inline-block;
+  margin-left: 5px;
+}
+
+.image-preview {
+  margin: 5px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: 100%;
+  height: 100%;
+}
+
+/*.image-picker {
+  display: flex;
+  justify-content: center;
+}*/
diff --git a/src/app/pages/dashboard-management/dashboard-component-dialog/dashboard-component-dialog.component.spec.ts b/src/app/pages/dashboard-management/dashboard-component-dialog/dashboard-component-dialog.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fc6602f77dfe1f6218efbd8dfb96146959b71fde
--- /dev/null
+++ b/src/app/pages/dashboard-management/dashboard-component-dialog/dashboard-component-dialog.component.spec.ts
@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { DashboardComponentDialogComponent } from './dashboard-component-dialog.component';
+
+describe('DashboardComponentDialogComponent', () => {
+  let component: DashboardComponentDialogComponent;
+  let fixture: ComponentFixture<DashboardComponentDialogComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ DashboardComponentDialogComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(DashboardComponentDialogComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/dashboard-component-dialog/dashboard-component-dialog.component.ts b/src/app/pages/dashboard-management/dashboard-component-dialog/dashboard-component-dialog.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7a574662c96a4a07a2c459117844ffbe1c84b520
--- /dev/null
+++ b/src/app/pages/dashboard-management/dashboard-component-dialog/dashboard-component-dialog.component.ts
@@ -0,0 +1,247 @@
+import { Component, OnInit, Input } from "@angular/core";
+import { AngularEditorConfig } from "@kolkov/angular-editor";
+import { NbDialogRef, NbToastrService } from "@nebular/theme";
+import { TranslateService } from "@ngx-translate/core";
+import { GridsterItem } from "angular-gridster2";
+import { ImageCroppedEvent } from "ngx-image-cropper";
+import { Datalet } from "../../data-catalogue/model/datalet";
+import { DataCatalogueAdminApiService } from "../../data-catalogue/services/data-catalogue-admin-api.service";
+
+export interface DialogData {
+  componentType: string;
+  name: string;
+}
+
+@Component({
+  selector: 'ngx-dashboard-component-dialog',
+  templateUrl: './dashboard-component-dialog.component.html',
+  styleUrls: ['./dashboard-component-dialog.component.scss']
+})
+export class DashboardComponentDialogComponent implements OnInit {
+  @Input() selectedItemType: string;
+  @Input() items: GridsterItem[];
+  @Input() item: GridsterItem;
+
+  itemIndex;
+  datalets: Array<Datalet>;
+  selectedItem: Datalet;
+  dataletObject: Datalet = {};
+  imageChangedEvent: any = '';
+  imageFile: any = '';
+  croppedImage: any = '';
+  imageBackup;
+  imageUrlBackup;
+  selectedOption: string;
+  maintainAspectRatioVariable: boolean = false;
+  aspectRatioVariable: string = "";
+  statisticsIcons: Array<string>;
+
+  editorConfig: AngularEditorConfig = {
+    editable: true,
+    spellcheck: true,
+    height: 'auto',
+    minHeight: '0',
+    maxHeight: 'auto',
+    width: 'auto',
+    minWidth: '0',
+    translate: 'yes',
+    enableToolbar: true,
+    showToolbar: true,
+    placeholder: 'Enter text here...',
+    defaultParagraphSeparator: '',
+    defaultFontName: '',
+    defaultFontSize: '',
+    fonts: [
+      { class: 'arial', name: 'Arial' },
+      { class: 'times-new-roman', name: 'Times New Roman' },
+      { class: 'calibri', name: 'Calibri' },
+      { class: 'comic-sans-ms', name: 'Comic Sans MS' }
+    ],
+    customClasses: [
+      {
+        name: 'quote',
+        class: 'quote',
+      },
+      {
+        name: 'redText',
+        class: 'redText'
+      },
+      {
+        name: 'titleText',
+        class: 'titleText',
+        tag: 'h1',
+      },
+    ],
+    uploadUrl: 'v1/image',
+    // upload: (file: File) => { ... }
+    uploadWithCredentials: false,
+    sanitize: false,
+    toolbarPosition: 'top',
+    toolbarHiddenButtons: [
+      [
+        'fontName',
+        // 'undo',
+        // 'redo',
+        // 'bold',
+        // 'italic',
+        // 'underline',
+        // 'strikeThrough',
+        // 'subscript',
+        // 'superscript',
+        // 'justifyLeft',
+        // 'justifyCenter',
+        // 'justifyRight',
+        // 'justifyFull',
+        // 'indent',
+        // 'outdent',
+        // 'insertUnorderedList',
+        // 'insertOrderedList',
+        // 'heading',
+      ],
+      [
+        'customClasses',
+        'insertImage',
+        'insertVideo',
+        'removeFormat',
+        'toggleEditorMode',
+        // 'fontSize',
+        // 'textColor',
+        // 'backgroundColor',
+        // 'link',
+        // 'unlink',
+        // 'insertHorizontalRule',
+      ]
+    ]
+  };
+
+  constructor(
+    public dialogRef: NbDialogRef<DashboardComponentDialogComponent>,
+    private dataCatalogueAdminApiservice: DataCatalogueAdminApiService,
+    private toastrService: NbToastrService,
+    private translateService: TranslateService
+    ) {
+  }
+
+  ngOnInit() {
+    this.itemIndex = this.items.indexOf(this.item);
+    this.selectedItemType = this.item.type;
+    this.statisticsIcons = this.getEvaIcon();
+
+    this.dataCatalogueAdminApiservice.getAllDatalets().subscribe(
+      (response: Array<Datalet>) => {
+        if (response !== undefined  && response !== null) {
+          try{
+            this.datalets = response;
+            if (this.selectedItemType == 'CHART'){
+              this.dataletObject = this.datalets.find(x => x.datalet_html === this.item.chart);
+              // console.log(this.dataletObject);
+            }
+          } catch(e) {
+            console.log("# Error in Dashboard page content deserialization due to " + e);
+            this.toastrService.danger(this.translateService.instant('dashboardComponent.catch_error'));
+          }
+        }
+    },  
+    (error: any) => {
+      // console.log("# Data Catalogue Error => "+ error);
+      this.toastrService.danger(error.message, this.translateService.instant('general.datacatalogue_error'))
+    }
+    );
+
+    //Radio Button for Image upload
+    this.selectedOption = (this.item.url == true) ? 'upload-url' : 'upload-file';
+  }
+
+  onCancelClick(): void {
+    if (this.imageBackup !== undefined) {
+      this.item.image = this.imageBackup;
+    }
+    if (this.imageUrlBackup !== undefined) {
+      this.item.imageUrl = this.imageUrlBackup;
+    }
+    this.dialogRef.close();
+  }
+
+  onSaveClick( item, selectedItemType ): void {
+    item.type = selectedItemType;
+
+    if (selectedItemType == 'CHART') {
+      // console.log(this.dataletObject);
+      item.chart = this.dataletObject.datalet_html;
+      item.chartTitle = this.dataletObject.title;
+    
+    } else if (selectedItemType == 'IMAGE') {
+      if (this.croppedImage !== undefined && this.croppedImage !== null && (this.croppedImage.length > 3 || this.croppedImage.length == 0)){
+        if (this.croppedImage.length > 3){
+          item.image = this.croppedImage;
+        }
+      }
+      if (this.selectedOption=='upload-url'){
+        item.url = true;
+        item.image = null;
+      } else{
+        item.url = false;
+        item.imageUrl = null;
+      }
+
+    } else if (selectedItemType == 'MAP'){
+      // console.log("# Here saved map: ", item);
+    }
+    
+    this.items[this.itemIndex] = item;
+    this.dialogRef.close(this.items);
+  }
+
+  // Move into a property file
+  getEvaIcon() {
+    return [
+            'award-outline',
+            'at-outline',
+            'car-outline',
+            'checkmark-circle-2-outline',
+            'cloud-download-outline',
+            'color-palette-outline',
+            'email-outline', 
+            'external-link-outline',
+            'facebook-outline',
+            'flag-outline', 
+            'globe-outline', 
+            'github-outline',
+            'google-outline',
+            'heart-outline',
+            'linkedin-outline',
+            'monitor-outline', 
+            'message-square-outline',
+            'percent-outline',
+            'pie-chart-outline',
+            'person-outline', 
+            'pin-outline', 
+            'sun-outline',
+            'unlock-outline',
+    ];
+  }
+
+  fileChangeEvent(event: any): void {
+    this.imageChangedEvent = event;
+  }
+
+  imageCropped(event: ImageCroppedEvent) {
+    this.croppedImage = event.base64;
+  }
+
+  imageLoaded() {
+    this.imageBackup = this.item.image;
+    this.imageUrlBackup = this.item.imageUrl;
+    this.item.image = undefined; 
+    this.item.imageUrl = undefined;
+  }
+
+  getHiddenUrlBlock(){
+    return (this.selectedOption!=='upload-url');
+  }
+
+  getHiddenFileUploadBlock(){
+    return (this.selectedOption!=='upload-file');
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/dashboard-management-routing.module.ts b/src/app/pages/dashboard-management/dashboard-management-routing.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2c96c90b7b43a266cb5c51b4249c9adb031351ea
--- /dev/null
+++ b/src/app/pages/dashboard-management/dashboard-management-routing.module.ts
@@ -0,0 +1,50 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { DashboardCloneWizardComponent } from './dashboard-clone-wizard/dashboard-clone-wizard.component';
+import { DashboardPageComponent } from './dashboard-page/dashboard-page.component';
+import { ManageDashboardPageContentComponent } from './manage-dashboard-page-content/manage-dashboard-page-content.component';
+import { ManageDashboardPageComponent } from './manage-dashboard-page/manage-dashboard-page.component';
+import { ManageMenuBlocksComponent } from './manage-menu-blocks/manage-menu-blocks.component';
+import { MenuBlocksPageComponent } from './menu-blocks-page/menu-blocks-page.component';
+
+const routes: Routes = [
+  {
+    path: 'manage-dashboard-pages',
+    component: ManageDashboardPageComponent
+  },
+  {
+    path: 'add-dashboard-page',
+    component: DashboardPageComponent
+  },
+  {
+    path: 'edit-dashboard-page/:id',
+    component: DashboardPageComponent
+  },
+  {
+    path: 'edit-dashboard-page-content/:id',
+    component: ManageDashboardPageContentComponent
+  },
+  {
+    path: 'manage-menu-blocks',
+    component: ManageMenuBlocksComponent
+  },
+  {
+    path: 'add-menu-block-page',
+    component: MenuBlocksPageComponent
+  },
+  {
+    path: 'edit-menu-block-page/:id',
+    component: MenuBlocksPageComponent
+  },
+  {
+    path: 'dashboard-clone-wizard',
+    component: DashboardCloneWizardComponent
+  }
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class DashboardManagementRoutingModule { }
+
diff --git a/src/app/pages/dashboard-management/dashboard-management.module.ts b/src/app/pages/dashboard-management/dashboard-management.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0b11c7148c8db72d65691579c7b4bb706264b60e
--- /dev/null
+++ b/src/app/pages/dashboard-management/dashboard-management.module.ts
@@ -0,0 +1,98 @@
+import { NgModule } from '@angular/core';
+import { ManageDashboardPageComponent } from './manage-dashboard-page/manage-dashboard-page.component';
+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 { ThemeModule } from '../../@theme/theme.module';
+import { DashboardManagementRoutingModule } from './dashboard-management-routing.module';
+import { MatCardModule } from '@angular/material/card';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { NgApexchartsModule } from "ng-apexcharts";
+import { Ng2SmartTableModule } from 'ng2-smart-table';
+import { CommonModule } from '@angular/common';
+import { DashboardPageComponent } from './dashboard-page/dashboard-page.component';
+import { SharedModule } from '../shared/shared.module';
+import { AngularEditorModule } from "@kolkov/angular-editor";
+import { GridsterModule } from 'angular-gridster2';
+import { MatIconModule } from '@angular/material/icon';
+import { ManageDashboardPageContentComponent } from './manage-dashboard-page-content/manage-dashboard-page-content.component';
+import { DashboardComponentDialogComponent } from './dashboard-component-dialog/dashboard-component-dialog.component';
+import { TranslateModule } from '@ngx-translate/core';
+import { TargetFilterComponent } from './target-filter/target-filter.component';
+import { MenuFilterComponent } from './menu-filter/menu-filter.component';
+import { ManageMenuBlocksComponent } from './manage-menu-blocks/manage-menu-blocks.component';
+import { WeatherComponent } from './weather/weather.component';
+import { StatisticsComponent } from './statistics/statistics.component';
+import { MenuBlocksPageComponent } from './menu-blocks-page/menu-blocks-page.component';
+import { ImageCropperModule } from 'ngx-image-cropper';
+import { LeafletModule } from '@asymmetrik/ngx-leaflet';
+import { DashboardCloneWizardComponent } from './dashboard-clone-wizard/dashboard-clone-wizard.component';
+import { ChartViewComponent } from './chart-view/chart-view.component';
+import {MatDialogModule} from '@angular/material/dialog';
+
+
+@NgModule({
+  imports: [
+    CommonModule,
+    ThemeModule,
+    GoogleMapsModule,
+    NbDialogModule.forChild(),
+    DashboardManagementRoutingModule,
+    NgxEchartsModule,
+    NbCardModule,
+    Ng2SmartTableModule,
+    MatCardModule,
+    NbRadioModule,
+    NbTabsetModule,
+    FormsModule,
+    NbSpinnerModule,
+    ReactiveFormsModule,
+    NbListModule,
+    NbFormFieldModule,
+    NbActionsModule,
+    NbAutocompleteModule,
+    NbInputModule,
+    NbDatepickerModule,
+    NbButtonModule,
+    NbSelectModule,
+    NbTimepickerModule,
+    LeafletMarkerClusterModule,
+    NbIconModule,
+    NbTooltipModule,
+    SharedModule,
+    NbAccordionModule,
+
+    NgApexchartsModule,
+    NbOptionModule,
+    NbLayoutModule,
+    NbCheckboxModule,
+    AngularEditorModule,
+    GridsterModule,
+    MatIconModule,
+    TranslateModule,
+    ImageCropperModule,
+    NbToggleModule,
+    NbStepperModule,
+    NbUserModule,
+    LeafletModule.forRoot(),
+    MatDialogModule,
+
+  ],
+  exports: [],
+  declarations: [
+    ManageDashboardPageComponent,
+    DashboardPageComponent,
+    ManageDashboardPageContentComponent,
+    DashboardComponentDialogComponent,
+    TargetFilterComponent,
+    MenuFilterComponent,
+    ManageMenuBlocksComponent,
+    MenuBlocksPageComponent,
+    WeatherComponent,
+    StatisticsComponent,
+    DashboardCloneWizardComponent,
+    ChartViewComponent,
+  ],
+})
+export class DashboardManagementModule { }
diff --git a/src/app/pages/dashboard-management/dashboard-page/dashboard-page.component.html b/src/app/pages/dashboard-management/dashboard-page/dashboard-page.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..a876c8e90efdc4c10d81fcdc601527553beb14e2
--- /dev/null
+++ b/src/app/pages/dashboard-management/dashboard-page/dashboard-page.component.html
@@ -0,0 +1,83 @@
+<nb-card>
+    <nb-card-header>
+        <h4>{{'general.manage'|translate}} {{'general.dashboard'|translate}}</h4>
+    </nb-card-header>
+
+    <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-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>
+                    
+                    <!-- toggle -->
+                    <!--
+                    <nb-card-body class="example-items-col">
+                        <nb-toggle [nbTooltip]="getMessageDisabledTarget()" formControlName="shared">{{'dashboardPage.shared'|translate}}</nb-toggle>
+                    </nb-card-body>
+                    -->
+
+                </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 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>
+
+
+<ngx-menu-filter [pageId]="pageId" [pageName]="pageName" (sendFilter)="updateSharedPersonalTypology($event)" ></ngx-menu-filter>
+
+<ngx-target-filter [pageId]="pageId" [disabledTarget]="disabledTarget"></ngx-target-filter>
diff --git a/src/app/pages/dashboard-management/dashboard-page/dashboard-page.component.scss b/src/app/pages/dashboard-management/dashboard-page/dashboard-page.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/pages/dashboard-management/dashboard-page/dashboard-page.component.spec.ts b/src/app/pages/dashboard-management/dashboard-page/dashboard-page.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..865185a9c69327b258eba2bbf0c7075c35697448
--- /dev/null
+++ b/src/app/pages/dashboard-management/dashboard-page/dashboard-page.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DashboardPageComponent } from './dashboard-page.component';
+
+describe('DashboardPageComponent', () => {
+  let component: DashboardPageComponent;
+  let fixture: ComponentFixture<DashboardPageComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ DashboardPageComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(DashboardPageComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/dashboard-page/dashboard-page.component.ts b/src/app/pages/dashboard-management/dashboard-page/dashboard-page.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a362e7dac70ed9b7138af77733a31deed095b12c
--- /dev/null
+++ b/src/app/pages/dashboard-management/dashboard-page/dashboard-page.component.ts
@@ -0,0 +1,131 @@
+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 { 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 { MenuItemCrudService } from '../services/menu-item-crud.service';
+
+@Component({
+  selector: 'ngx-dashboard-page',
+  templateUrl: './dashboard-page.component.html',
+  styleUrls: ['./dashboard-page.component.scss']
+})
+export class DashboardPageComponent implements OnInit {
+  @Input() page: FormGroup = new FormGroup({});
+  sharedDomain = [true, false];
+ 
+  pageId: string; //For Targets
+  pageName: string; //For MenuItem
+  disabledTarget: boolean; //For Targets
+
+  constructor(
+    private formService: FormManagerService,
+    private service: DashboardPageCrudService,
+    private menuItemService: MenuItemCrudService,
+    private router: Router,
+    private route: ActivatedRoute,
+    private toastrService: NbToastrService,
+    private translateService: TranslateService,
+    private _location: Location
+  ) { }
+
+  ngOnInit(): void {
+    this.page = this.formService.pageFormCreator(new DashboardPage());
+    
+    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)
+        );
+      }
+    });
+
+  }
+
+  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)) 
+      );
+
+  }
+
+  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);
+          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();
+        },
+        error => (this.showError(error))
+      );
+      
+    }
+  }
+
+  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'))
+  }
+
+  backClicked() {
+    this._location.back();
+  }
+  
+  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))
+    );
+  }
+
+  getMessageDisabledTarget(){
+    return this.disabledTarget 
+    ? this.translateService.instant('dashboardPage.not_mandatory_field')
+    : this.translateService.instant('general.mandatory_field');
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/manage-dashboard-page-content/manage-dashboard-page-content.component.html b/src/app/pages/dashboard-management/manage-dashboard-page-content/manage-dashboard-page-content.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..05b9e89a122b33d989b9eae7e11a89cd8f9a478b
--- /dev/null
+++ b/src/app/pages/dashboard-management/manage-dashboard-page-content/manage-dashboard-page-content.component.html
@@ -0,0 +1,142 @@
+<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>
\ No newline at end of file
diff --git a/src/app/pages/dashboard-management/manage-dashboard-page-content/manage-dashboard-page-content.component.scss b/src/app/pages/dashboard-management/manage-dashboard-page-content/manage-dashboard-page-content.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..f7c7db0747bafd64c308b5fb98059b213fcdc0a8
--- /dev/null
+++ b/src/app/pages/dashboard-management/manage-dashboard-page-content/manage-dashboard-page-content.component.scss
@@ -0,0 +1,43 @@
+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;
+}
diff --git a/src/app/pages/dashboard-management/manage-dashboard-page-content/manage-dashboard-page-content.component.spec.ts b/src/app/pages/dashboard-management/manage-dashboard-page-content/manage-dashboard-page-content.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dd18b5be12b0086438dc7aa6f68a22008b452254
--- /dev/null
+++ b/src/app/pages/dashboard-management/manage-dashboard-page-content/manage-dashboard-page-content.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ManageDashboardPageContentComponent } from './manage-dashboard-page-content.component';
+
+describe('ManageDashboardPageContentComponent', () => {
+  let component: ManageDashboardPageContentComponent;
+  let fixture: ComponentFixture<ManageDashboardPageContentComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ ManageDashboardPageContentComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ManageDashboardPageContentComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/manage-dashboard-page-content/manage-dashboard-page-content.component.ts b/src/app/pages/dashboard-management/manage-dashboard-page-content/manage-dashboard-page-content.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c3ddfa4049a414c154261cc4b6f82dc175c2c978
--- /dev/null
+++ b/src/app/pages/dashboard-management/manage-dashboard-page-content/manage-dashboard-page-content.component.ts
@@ -0,0 +1,280 @@
+import { Component, Inject, OnInit, Optional } from "@angular/core";
+import { ActivatedRoute } from "@angular/router";
+import { NbDialogService, NbToastrService } from "@nebular/theme";
+import { Draggable, GridsterConfig, GridsterItem, PushDirections, Resizable } from "angular-gridster2";
+import { DashboardPage, IDashboardPage } from "../../../model/dashboard-page.model";
+import { DashboardComponentDialogComponent } from "../dashboard-component-dialog/dashboard-component-dialog.component";
+import { DashboardPageCrudService } from "../services/dashboard-page-crud.service";
+import { TranslateService } from "@ngx-translate/core";
+import { DialogComponent } from "../../shared/dialog/dialog.component";
+import { Location } from '@angular/common';
+import { DomSanitizer } from "@angular/platform-browser";
+import * as L from 'leaflet';
+import { MAT_DIALOG_DATA } from "@angular/material/dialog";
+import { ConfigService } from '@ngx-config/core';
+
+interface Safe extends GridsterConfig {
+  draggable: Draggable;
+  resizable: Resizable;
+  pushDirections: PushDirections;
+}
+
+interface DashboardModalData {
+  parsedId: number;
+  parsedEditMode: boolean;
+}
+
+@Component({
+  selector: 'ngx-manage-dashboard-page-content',
+  templateUrl: './manage-dashboard-page-content.component.html',
+  styleUrls: ['./manage-dashboard-page-content.component.scss']
+})
+export class ManageDashboardPageContentComponent implements OnInit {
+  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;  //Change options to disable drag and drop
+  
+  //WorkAroud for BUG on ng-gridster+iframe
+  private ENABLE_DELAY:boolean; 
+  private DELAY:number; 
+
+  constructor(public dialogService: NbDialogService, 
+              public dashboardPageService: DashboardPageCrudService, 
+              private route: ActivatedRoute,
+              private _sanitizer: DomSanitizer,
+              private toastrService: NbToastrService,
+              private translateService: TranslateService,
+              private _location: Location,
+              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(){
+      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();
+        }
+      });
+
+  }
+
+  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);
+    });
+  }
+ 
+
+}
diff --git a/src/app/pages/dashboard-management/manage-dashboard-page/manage-dashboard-page.component.html b/src/app/pages/dashboard-management/manage-dashboard-page/manage-dashboard-page.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..f020b7940e6237edd72c3b369cdfa0e9627e6081
--- /dev/null
+++ b/src/app/pages/dashboard-management/manage-dashboard-page/manage-dashboard-page.component.html
@@ -0,0 +1,10 @@
+<nb-card>
+    <nb-card-header class="d-flex justify-content-between">
+        <h4>{{'dashboardPage.title'|translate}}</h4>
+        <button nbButton size="small" status="info" routerLink="../add-dashboard-page" status="primary">{{'general.add'|translate}} {{'general.dashboard'|translate}}</button>
+    </nb-card-header>
+
+    <nb-card-body>
+        <ng2-smart-table [settings]="settings" [source]="source"></ng2-smart-table>
+    </nb-card-body>
+</nb-card>
\ No newline at end of file
diff --git a/src/app/pages/dashboard-management/manage-dashboard-page/manage-dashboard-page.component.scss b/src/app/pages/dashboard-management/manage-dashboard-page/manage-dashboard-page.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/pages/dashboard-management/manage-dashboard-page/manage-dashboard-page.component.spec.ts b/src/app/pages/dashboard-management/manage-dashboard-page/manage-dashboard-page.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cef3dd1c07909813926f7e553c52a24d253ef76e
--- /dev/null
+++ b/src/app/pages/dashboard-management/manage-dashboard-page/manage-dashboard-page.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ManageDashboardPageComponent } from './manage-dashboard-page.component';
+
+describe('ManageDashboardPageComponent', () => {
+  let component: ManageDashboardPageComponent;
+  let fixture: ComponentFixture<ManageDashboardPageComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ ManageDashboardPageComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ManageDashboardPageComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/manage-dashboard-page/manage-dashboard-page.component.ts b/src/app/pages/dashboard-management/manage-dashboard-page/manage-dashboard-page.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ebe35ccdae7a02c690856cf04853c117318eb1af
--- /dev/null
+++ b/src/app/pages/dashboard-management/manage-dashboard-page/manage-dashboard-page.component.ts
@@ -0,0 +1,164 @@
+import { Component, OnInit} from '@angular/core';
+import { Router } from '@angular/router';
+import { NbDialogService, NbToastrService } from '@nebular/theme';
+import { TranslateService } from '@ngx-translate/core';
+import { LocalDataSource } from 'ng2-smart-table';
+import { DashboardPage } from '../../../model/dashboard-page.model';
+import { MenuType } from '../../../model/enumeration/menu-type.model';
+import { DialogComponent } from '../../shared/dialog/dialog.component';
+import { TableActionsComponent } from '../../shared/table-actions/table-actions.component';
+import { DashboardPageCrudService } from '../services/dashboard-page-crud.service';
+
+@Component({
+  selector: 'ngx-manage-dashboard-page',
+  templateUrl: './manage-dashboard-page.component.html',
+  styleUrls: ['./manage-dashboard-page.component.scss']
+})
+export class ManageDashboardPageComponent implements OnInit {
+  source: LocalDataSource;
+  settings: any;
+  pages: Array<DashboardPage>=[];
+
+  constructor(  private service: DashboardPageCrudService,
+                private router: Router,
+                private dialogService: NbDialogService,
+                private translateService: TranslateService,
+                private toastrService: NbToastrService) 
+    { 
+      this.initTableSettings();
+    }
+
+  ngOnInit(): void {
+    this.source = new LocalDataSource();
+    this.fetchTableData();
+  }
+
+  fetchTableData() {
+    this.service.getEditablePages().subscribe( 
+    (data) => {
+      this.pages=data;
+      this.source.load(data);
+    },
+      error => (this.showError(error))
+    );
+  }
+
+  showSuccess() {
+    this.toastrService.success(this.translateService.instant('dashboardPage.deleted'), this.translateService.instant('general.success'));
+  }
+  
+  showError(error) {
+    this.toastrService.danger(error.message, this.translateService.instant('general.error'))
+  }
+
+  initTableSettings(): void {
+    let sharedFilter=[];
+    let booleans = [true, false]
+    for(let myShared of booleans){
+      sharedFilter.push({ value: myShared, title: myShared })
+    }
+
+    let menuTypeFilter=[];
+    for(let mType of MenuType.values()){
+      menuTypeFilter.push({ value: mType.enumVal, title: this.translateService.instant("MenuType."+mType.enumVal) })
+    }
+
+
+    this.settings = {
+      mode: 'external',
+      columns: {
+        shared: {
+          title: this.translateService.instant('dashboardPage.shared'),
+          filter: {
+            type: 'list',
+            config: {
+              selectText: '',
+              list: sharedFilter
+            },
+          }
+        },
+        type: {
+          title: this.translateService.instant('menuItem.title'),
+          filter: {
+            type: 'list',
+            config: {
+              selectText: '',
+              list: menuTypeFilter
+            },
+          }
+        },
+        name: {
+          title: this.translateService.instant('dashboardPage.name')
+        },
+        description: {
+          title:  this.translateService.instant('dashboardPage.description')
+        },
+        note: {
+          title:  this.translateService.instant('dashboardPage.note')
+        },
+        
+        /*content: {
+          title: this.translateService.instant('dashboardPage.content'),
+          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')},
+              {action:'editDashboard', enabled:true, status:"alert", icon:"edit", tooltip:this.translateService.instant('general.editContent')}
+            ];
+          }, 
+          renderComponent: TableActionsComponent,
+          onComponentInitFunction: (instance) => {
+            instance.onCustom.subscribe(value => {
+              this.onCustom(value,instance.rowData);
+            });
+          },          
+        }
+      },
+
+      actions: {
+        add: false,
+        edit: false,
+        delete: false,
+      },
+
+    };
+  }
+
+  onCustom(event, data) {
+
+    if (event == 'edit') {
+      this.router.navigate(['/pages/dashboard-management/edit-dashboard-page/' + data.id])
+    };
+
+    if (event == 'editDashboard') {
+      this.router.navigate(['/pages/dashboard-management/edit-dashboard-page-content/' + data.id])
+    }
+
+    if (event == 'delete') {
+
+      this.dialogService.open(DialogComponent, { context: { title: this.translateService.instant('general.delete') + " " + this.translateService.instant('general.dashboard') , message: this.translateService.instant('general.deleteConfirm') } }).onClose.subscribe(res => {
+        if (res) {
+          //this.service.deletePageById(data.id).subscribe(() => {
+          this.service.deleteDeepPageById(data.id).subscribe(() => {
+            this.fetchTableData();
+            console.log(`Dashboard Page with id=${data.id} has been deleted.`),
+              this.showSuccess();
+          },
+            error => (this.showError(error))
+          );
+        } else return;
+
+      });
+
+    };
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/manage-menu-blocks/manage-menu-blocks.component.html b/src/app/pages/dashboard-management/manage-menu-blocks/manage-menu-blocks.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..97c5807e4fbd02169506e142e5b258623bd3958f
--- /dev/null
+++ b/src/app/pages/dashboard-management/manage-menu-blocks/manage-menu-blocks.component.html
@@ -0,0 +1,11 @@
+<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-card-body>
+</nb-card>
\ No newline at end of file
diff --git a/src/app/pages/dashboard-management/manage-menu-blocks/manage-menu-blocks.component.scss b/src/app/pages/dashboard-management/manage-menu-blocks/manage-menu-blocks.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/pages/dashboard-management/manage-menu-blocks/manage-menu-blocks.component.spec.ts b/src/app/pages/dashboard-management/manage-menu-blocks/manage-menu-blocks.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0420e7c68b23fc96139a0d594e3731c3913da5df
--- /dev/null
+++ b/src/app/pages/dashboard-management/manage-menu-blocks/manage-menu-blocks.component.spec.ts
@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ManageMenuBlocksComponent } from './manage-menu-blocks.component';
+
+describe('ManageMenuBlocksComponent', () => {
+  let component: ManageMenuBlocksComponent;
+  let fixture: ComponentFixture<ManageMenuBlocksComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ ManageMenuBlocksComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ManageMenuBlocksComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/manage-menu-blocks/manage-menu-blocks.component.ts b/src/app/pages/dashboard-management/manage-menu-blocks/manage-menu-blocks.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3905f59580c44fb59d2aa364e926a8eda2981348
--- /dev/null
+++ b/src/app/pages/dashboard-management/manage-menu-blocks/manage-menu-blocks.component.ts
@@ -0,0 +1,151 @@
+import { Component, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+import { NbDialogService, NbToastrService } from '@nebular/theme';
+import { TranslateService } from '@ngx-translate/core';
+import { LocalDataSource } from 'ng2-smart-table';
+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';
+
+@Component({
+  selector: 'ngx-manage-menu-blocks',
+  templateUrl: './manage-menu-blocks.component.html',
+  styleUrls: ['./manage-menu-blocks.component.scss']
+})
+export class ManageMenuBlocksComponent implements OnInit {
+  source: LocalDataSource;
+  settings: any;
+  menuBlocks: Array<MenuBlock>=[];
+
+  constructor(  private service: MenuBlockCrudService,
+                private router: Router,
+                private dialogService: NbDialogService,
+                private translateService: TranslateService,
+                private toastrService: NbToastrService) 
+    { 
+      this.initTableSettings();
+    }
+
+  ngOnInit(): void {
+    this.source = new LocalDataSource();
+    this.fetchTableData();
+  }
+
+  fetchTableData() {
+    this.service.getAllEditable().subscribe(
+      (data) => {
+      this.menuBlocks=data;
+      this.source.load(data);
+    },
+      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'))
+    }
+  }
+
+  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
+            },
+          }
+        },
+        code: {
+          title: this.translateService.instant('menuBlock.code')
+        },        
+        label: {
+          title: this.translateService.instant('menuBlock.label')
+        },
+        
+        /*
+        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,
+      },
+
+    };
+  }
+
+  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();
+          },
+            error => (this.showError(error))
+          );
+        } else return;
+
+      });
+
+    };
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/menu-blocks-page/menu-blocks-page.component.html b/src/app/pages/dashboard-management/menu-blocks-page/menu-blocks-page.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..940eff3b668379da8b95d5b57e13d5872a3a09c8
--- /dev/null
+++ b/src/app/pages/dashboard-management/menu-blocks-page/menu-blocks-page.component.html
@@ -0,0 +1,42 @@
+<nb-card>
+    <nb-card-header>
+        <h4>{{'general.manage'|translate}} {{'general.menu_blocks'|translate}}</h4>
+    </nb-card-header>
+
+    <nb-card-body [formGroup]="block" class="col-md-6 d-flex flex-row justify-content-around">
+
+        <div class="form-group d-flex flex-column" >
+            <label for="type" class="label">
+                <nb-icon icon="info-outline" nbTooltip="{{'menuBlock.type_info'|translate}}" ></nb-icon> 
+                {{'menuBlock.type'|translate}} *
+            </label>
+            
+            <nb-select fullWidth formControlName="type" size="small" name="type"
+                    placeholder="{{'menuBlock.type'|translate}}"
+                    nbTooltip="{{'general.mandatory_field'|translate}}">
+                    <nb-option *ngFor="let item of typeDomain" [value]="item.enumVal">
+                        {{item.enumVal}}
+                    </nb-option>
+            </nb-select>
+            
+        </div>
+
+        <div class="form-group d-flex flex-column" >
+            <label for="label" class="label">
+                {{'menuBlock.label'|translate}} *
+            </label>
+            <input type="text" nbInput fullWidth fieldSize="small" placeholder="{{'menuBlock.label'|translate}}"
+                label="label" formControlName="label" nbTooltip="{{'general.mandatory_field'|translate}}">
+        </div>
+
+    </nb-card-body>
+
+    <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)="storeBlock()" size="small" [disabled]="block.invalid">
+            <nb-icon icon="save"></nb-icon>{{'general.save'|translate}}
+        </button>
+    </nb-card-footer>
+</nb-card>
\ No newline at end of file
diff --git a/src/app/pages/dashboard-management/menu-blocks-page/menu-blocks-page.component.scss b/src/app/pages/dashboard-management/menu-blocks-page/menu-blocks-page.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/pages/dashboard-management/menu-blocks-page/menu-blocks-page.component.spec.ts b/src/app/pages/dashboard-management/menu-blocks-page/menu-blocks-page.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2e5cde2f541f721e6388bffa5f4e874b7d1e5700
--- /dev/null
+++ b/src/app/pages/dashboard-management/menu-blocks-page/menu-blocks-page.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MenuBlocksPageComponent } from './menu-blocks-page.component';
+
+describe('MenuBlocksPageComponent', () => {
+  let component: MenuBlocksPageComponent;
+  let fixture: ComponentFixture<MenuBlocksPageComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ MenuBlocksPageComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(MenuBlocksPageComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/menu-blocks-page/menu-blocks-page.component.ts b/src/app/pages/dashboard-management/menu-blocks-page/menu-blocks-page.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bd41928f35a2cb09b4a3b81dc5905101118012eb
--- /dev/null
+++ b/src/app/pages/dashboard-management/menu-blocks-page/menu-blocks-page.component.ts
@@ -0,0 +1,97 @@
+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 { MenuBlock } from '../../../model/menu-block.model';
+import { MenuBlockCrudService } from '../services/menu-block-crud.service';
+import { Location } from '@angular/common';
+import { MenuFormManagerService } from '../services/menu-form-manager.service';
+import { MenuType } from '../../../model/enumeration/menu-type.model';
+
+@Component({
+  selector: 'ngx-menu-blocks-page',
+  templateUrl: './menu-blocks-page.component.html',
+  styleUrls: ['./menu-blocks-page.component.scss']
+})
+export class MenuBlocksPageComponent implements OnInit {
+
+  @Input() block: FormGroup = new FormGroup({});
+  typeDomain = MenuType.values(); //Fix
+  blockId: string; //For targets
+
+  constructor(
+    private formService: MenuFormManagerService,
+    private service: MenuBlockCrudService,
+    private router: Router,
+    private route: ActivatedRoute,
+    private toastrService: NbToastrService,
+    private translateService: TranslateService,
+    private _location: Location
+  ) { }
+
+  ngOnInit(): void {
+    this.block = this.formService.pageFormCreator(new MenuBlock());
+    this.route.paramMap.subscribe(params => {
+      this.blockId = params.get('id');
+      if (this.blockId) {
+        this.service.getById(this.blockId).subscribe(
+          (event: MenuBlock) =>{ this.editBlock(event); },
+          (err: any) => console.log(err)
+        );;
+      }
+    });
+  }
+
+  editBlock(menuBlock: MenuBlock) {
+    this.block = this.formService.pageFormCreator(menuBlock);
+  }
+
+  storeBlock(): void {
+    if (this.block.value.id == null) {
+      //console.log('## CREATE MENU-BLOCK WITH ID:' + this.block.value.id);
+      let objToAdd = <MenuBlock> this.block.getRawValue();
+      objToAdd.code = objToAdd.label!=null ? objToAdd.label.replace(/\s/g, "_").toUpperCase() : objToAdd.label;
+      //console.log('objToAdd =>  ' , JSON.stringify(objToAdd));
+
+      this.service.create(objToAdd).subscribe(
+        (data: MenuBlock) => {
+          //console.log("Menu block created, data => " + data);
+          this.router.navigate(['/pages/dashboard-management/manage-menu-blocks']);
+          this.showSuccess();
+        },
+        error => (this.showError(error))
+      );
+      
+    }
+    else {
+      //console.log('## EDIT MENU-BLOCK WITH ID:' + this.block.value.id);
+      let objToModify = <MenuBlock>this.block.getRawValue()
+      objToModify.code = objToModify.label!=null ? objToModify.label.replace(/\s/g, "_").toUpperCase() : objToModify.label;
+      this.service.update(objToModify).subscribe(
+        (data: MenuBlock) => {
+          this.editBlock(data);
+          this.showSuccess();
+        },
+        error => (this.showError(error))
+      );
+    }
+  }
+
+  showSuccess() {
+    this.block.value.id == null ?
+      this.toastrService.success(this.translateService.instant('menuBlock.created'), this.translateService.instant('Success')) :
+      this.toastrService.success(this.translateService.instant('menuBlock.updated'), this.translateService.instant('Success'));
+  }
+
+  showError(error) {
+    this.toastrService.danger(error.error.message, this.translateService.instant('general.error'))
+  }
+
+  backClicked() {
+    this._location.back();
+  }
+  
+}
+
+
diff --git a/src/app/pages/dashboard-management/menu-filter/menu-filter.component.html b/src/app/pages/dashboard-management/menu-filter/menu-filter.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..d99c25278ab1a1bbb4ae3b583a1029e39f3eda2a
--- /dev/null
+++ b/src/app/pages/dashboard-management/menu-filter/menu-filter.component.html
@@ -0,0 +1,40 @@
+<nb-card>
+    <nb-card-header>
+        <div class="d-flex flex-row justify-content-between align-items-center mt-2" [formGroup]="form">
+            <h4>{{'menuItem.title'|translate}}
+                <nb-icon icon="info-outline" nbTooltip="{{'menuItem.add_button_info'|translate}}"></nb-icon>
+                <nb-icon icon="message-circle" nbTooltip="{{'menuBlock.select_menu_block_info'|translate}}"></nb-icon>
+            </h4>
+
+            <nb-select size="small" placeholder="{{'menuBlock.select_menu_block'|translate}}"
+                formControlName="selectedMenuBlock" nbTooltip="{{'menuBlock.select_menu_block'|translate}}">
+
+                <nb-option-group title="{{'MenuType.SHARED'|translate}}">
+                    <nb-option *ngFor="let blockMenu of fullListBlockShared; " [value]="blockMenu">
+                        {{blockMenu.label}}
+                    </nb-option>
+                </nb-option-group>
+
+                <nb-option-group title="{{'MenuType.PERSONAL'|translate}}">
+                    <nb-option *ngFor="let blockMenu of fullListBlockPersonal; " [value]="blockMenu">
+                        {{blockMenu.label}}
+                    </nb-option>
+                </nb-option-group>
+            </nb-select>
+
+            <input nbInput fieldSize="small" placeholder="{{'menuItem.menu_item_label'|translate}}"
+                formControlName="selectedMenuItemLabel">
+            <button nbButton size="small" status="primary" nbTooltip="{{'menuItem.copy_info'|translate}}" (click)="generateLabel()" [disabled]="disableButton()">
+                <nb-icon icon="copy-outline"></nb-icon>{{'general.copy' | translate}}
+            </button>
+            
+            <button nbButton size="small" status="primary" (click)="addMenuItem()" [disabled]="disableButton()">
+                <nb-icon icon="list-outline"></nb-icon>{{'general.add' | translate}} {{'menuItem.title'| translate}}
+            </button>
+        </div>
+
+    </nb-card-header>
+    <nb-card-body>
+        <ng2-smart-table [settings]="settings" [source]="source"></ng2-smart-table>
+    </nb-card-body>
+</nb-card>
\ No newline at end of file
diff --git a/src/app/pages/dashboard-management/menu-filter/menu-filter.component.scss b/src/app/pages/dashboard-management/menu-filter/menu-filter.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/pages/dashboard-management/menu-filter/menu-filter.component.spec.ts b/src/app/pages/dashboard-management/menu-filter/menu-filter.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..aa3543efe7fc4c89fb6d6d7110c1241b2217ba43
--- /dev/null
+++ b/src/app/pages/dashboard-management/menu-filter/menu-filter.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MenuFilterComponent } from './menu-filter.component';
+
+describe('MenuFilterComponent', () => {
+  let component: MenuFilterComponent;
+  let fixture: ComponentFixture<MenuFilterComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ MenuFilterComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(MenuFilterComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/menu-filter/menu-filter.component.ts b/src/app/pages/dashboard-management/menu-filter/menu-filter.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..68d586748877b0c5b3a071e0a6d634ff17b78774
--- /dev/null
+++ b/src/app/pages/dashboard-management/menu-filter/menu-filter.component.ts
@@ -0,0 +1,254 @@
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { NbDialogService, NbToastrService } from '@nebular/theme';
+import { TranslateService } from '@ngx-translate/core';
+import { LocalDataSource } from 'ng2-smart-table';
+import { DashboardPage } from '../../../model/dashboard-page.model';
+import { MenuType } from '../../../model/enumeration/menu-type.model';
+import { IMenuBlock } from '../../../model/menu-block.model';
+import { IMenuItem, MenuItem } from '../../../model/menu-item.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-menu-filter',
+  templateUrl: './menu-filter.component.html',
+  styleUrls: ['./menu-filter.component.scss']
+})
+export class MenuFilterComponent implements OnInit {
+  @Input() pageId: string;
+  @Input() pageName: string;
+  @Output() sendFilter = new EventEmitter<any>() //Broadcast event for disabledTarget
+  
+  //SMART TABLES
+  source: LocalDataSource;
+  settings: any;
+  sharedMenuItems: Array<IMenuItem>=[];
+
+  toAddMenuItem: IMenuItem;
+  fullListBlockEditable: Array<IMenuBlock> = [];
+  fullListBlockShared: Array<IMenuBlock> = [];
+  fullListBlockPersonal: Array<IMenuBlock> = [];
+
+  form: FormGroup;
+  selectedMenuBlock: IMenuBlock;
+  selectedMenuItemLabel: string;
+
+  constructor(
+    private fb: FormBuilder,
+    private menuItemService: MenuItemCrudService,
+    private menuBlockCrudService: MenuBlockCrudService,
+    private dialogService: NbDialogService,
+    private toastrService: NbToastrService,
+    private translateService: TranslateService) { }
+
+  ngOnInit(): void {
+    this.initTableSettings();
+    this.source = new LocalDataSource();
+    this.fetchTableData();
+
+    this.form = this.fb.group({
+      selectedMenuBlock: [this.selectedMenuBlock, Validators.nullValidator],
+      selectedMenuItemLabel: [this.selectedMenuItemLabel, Validators.nullValidator],
+    })
+
+    this.menuBlockCrudService.getAllEditable().subscribe(res => {
+      this.fullListBlockEditable = res;
+      this.fullListBlockShared = this.fullListBlockEditable.filter(x => x.type == MenuType.SHARED);
+      this.fullListBlockPersonal = this.fullListBlockEditable.filter(x => x.type == MenuType.PERSONAL);
+    });
+    
+  }
+
+  fetchTableData() {
+    if (this.pageId!=undefined) {
+      this.menuItemService.getByPageId(this.pageId).subscribe(
+        //Success
+        (data: Array<IMenuItem>) => {
+          this.sharedMenuItems = data;
+          for(let currMenuItem of this.sharedMenuItems){
+            // Read MenuItem Label
+            this.menuBlockCrudService.getById(''+currMenuItem.menuBlock.id).subscribe(res2 => {
+              if (res2 != undefined && res2 != null && res2.label != undefined && res2.label != null) {
+                this.sharedMenuItems[0].menuBlock.label = res2.label; //Only a Menu Block is linked to item!!
+                this.source.load(this.sharedMenuItems);
+              } else {
+                this.source.load(this.sharedMenuItems);
+              }
+            });
+          }
+          if (this.sharedMenuItems){
+            this.source.load(this.sharedMenuItems);
+          }
+        },
+        //Error
+        error => (this.showError(error)));
+    }
+  }
+
+  addMenuItem() {
+    console.log("# Add MenuItem linked to dashboard with pageId =>" + this.pageId);
+    const menuBlock = this.form.get('selectedMenuBlock').value;
+    const menuItemLabel = this.form.get('selectedMenuItemLabel').value;
+    
+    if (menuBlock == undefined || menuBlock == null){
+      this.showWarning('menuBlock.select_menu_block');
+      return;
+    }
+
+    if (menuItemLabel == undefined || menuItemLabel == null){
+      this.showWarning('menuItem.add_menu_item_label');
+      return;
+    }
+
+    this.toAddMenuItem = this.buildMenuItem(menuBlock, menuItemLabel, menuBlock.type, Number(this.pageId));
+    this.menuItemService.create(this.toAddMenuItem).subscribe(
+      (data: MenuItem) => {
+        this.showSuccess('menuItem.created');
+        this.fetchTableData();
+        this.form.reset(); //Clean select and input
+
+        this.broadcastInfo(); //Broadcast event for disabledTarget
+      },
+      error => (this.showError(error))
+    );
+  }
+
+  private buildMenuItem(menuBlock: IMenuBlock, menuItemLabel: string, type:MenuType, pageId: number) {
+    const newItem = new MenuItem();
+    newItem.dashboardPage = new DashboardPage();
+    newItem.dashboardPage.id = pageId;
+    newItem.type = type;
+    newItem.label = menuItemLabel;
+    newItem.code = menuItemLabel!=null ? menuItemLabel.replace(/\s/g, "_").toUpperCase() : menuItemLabel;
+    newItem.menuBlock = menuBlock;
+    return newItem;
+  }
+
+  showSuccess(operation:string) {
+    this.toastrService.success(this.translateService.instant(operation), this.translateService.instant('general.success'));
+  }
+  
+  showError(error) {
+    this.toastrService.danger(error.error.message, this.translateService.instant('general.error'))
+  }
+
+  showWarning(operation:string) {
+    this.toastrService.warning(this.translateService.instant(operation), this.translateService.instant('general.warning'));
+  }
+
+
+  initTableSettings(): void {
+    let menuTypeFilter=[];
+    for(let mType of MenuType.values()){
+      menuTypeFilter.push({ value: mType.enumVal, title: this.translateService.instant("MenuType."+mType.enumVal) })
+    }
+
+    this.settings = {
+      mode: 'external',
+      attr: {
+        class: 'table table-bordered'
+      },
+      columns: {
+        /*id: {
+          title: this.translateService.instant('menuItem.id'),
+        },
+        */
+        type: {
+          title: this.translateService.instant('menuItem.type'),
+          valuePrepareFunction: (cell, row) => { 
+            if(row.type!=undefined && row.type!=null)
+              return this.translateService.instant('MenuType.' + row.type) 
+            else return '';
+          },
+          filter: {
+            type: 'list',
+            config: {
+              selectText: '',
+              list: menuTypeFilter
+            },
+          }
+        },
+        menuBlock: {
+          title: this.translateService.instant('menuBlock.title') + " " + this.translateService.instant('menuBlock.label'),
+          valuePrepareFunction: (cell, row) => { 
+            if(row.menuBlock!=undefined && row.menuBlock!=null){
+              return row.menuBlock.label;
+            }
+            else return '';
+          }
+        },
+        /*code: {
+          title: this.translateService.instant('menuItem.code'),
+        },
+        */
+        label: {
+          title: this.translateService.instant('menuItem.title') + " " + this.translateService.instant('menuItem.label')
+        },
+        actions: {
+          title: this.translateService.instant('general.actions'),
+          filter: false,
+          sort: false,
+          type: 'custom',
+          valuePrepareFunction: (cell, row) => {
+            return [
+              {action:'delete', enabled:true, status:"danger", icon:"trash-2", tooltip:this.translateService.instant('general.delete')+ " " + this.translateService.instant('menuItem.title')}
+            ];
+          }, 
+          renderComponent: TableActionsComponent,
+          onComponentInitFunction: (instance) => {
+            instance.onCustom.subscribe(value => {
+              this.onCustom(value,instance.rowData);
+            });
+          },          
+        }
+
+      },
+
+      actions: {
+        add: false,
+        edit: false,
+        delete: false,
+      },
+
+    };
+  }
+
+  onCustom(event, data) {
+    if (event == 'delete') {
+      this.dialogService
+          .open( DialogComponent, { context: { 
+              title: this.translateService.instant('general.delete') + " " + this.translateService.instant('menuItem.title') , 
+              message: this.translateService.instant('general.deleteConfirm')} })
+          .onClose.subscribe(res => {
+        if (res) {
+          this.menuItemService.deleteById(data.id).subscribe( (res) => {
+            this.fetchTableData();
+            console.log(`## MenuItem with id=${data.id} has been deleted.`),
+            this.showSuccess('menuItem.deleted');
+
+            this.broadcastInfo(); //Broadcast event for disabledTarget
+          },
+            error => (this.showError(error))
+          );
+        } else return;
+
+      });
+    };
+  }
+
+  disableButton() {
+    return this.pageId == null || (this.sharedMenuItems!=undefined && this.sharedMenuItems.length > 0) ? true : false;
+  }
+
+  generateLabel(){
+    this.form.patchValue( { selectedMenuItemLabel: this.pageName });  
+  }
+
+  broadcastInfo() {
+    this.sendFilter.emit(this.form.getRawValue());
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/services/dashboard-page-crud.service.spec.ts b/src/app/pages/dashboard-management/services/dashboard-page-crud.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bdae39c829b6e8df12e9bc0cf3ca90b6b5780ada
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/dashboard-page-crud.service.spec.ts
@@ -0,0 +1,15 @@
+import { TestBed } from '@angular/core/testing';
+import { DashboardPageCrudService } from './dashboard-page-crud.service';
+
+describe('DashboardPageCrudService', () => {
+  let service: DashboardPageCrudService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(DashboardPageCrudService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/services/dashboard-page-crud.service.ts b/src/app/pages/dashboard-management/services/dashboard-page-crud.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c615538ac65d3f04921e27e04f28a073018b555b
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/dashboard-page-crud.service.ts
@@ -0,0 +1,81 @@
+import { Injectable } from '@angular/core';
+import { ConfigService } from '@ngx-config/core';
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { Observable, of } from 'rxjs';
+import { IDashboardPage } from '../../../model/dashboard-page.model';
+import { ICloneDashboard } from '../../../model/clone-dashboard.model';
+import AMTram2020 from '../../../../assets/map/am_tram_2020.json';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class DashboardPageCrudService {
+  private apiURL: any;
+
+  constructor(configService: ConfigService, private http: HttpClient) {
+    this.apiURL = configService.getSettings("dashboard-controller.api_base_url");
+  }
+
+  getAllPages(): Observable<Array<IDashboardPage>> {
+    return this.http.get<Array<IDashboardPage>>(`${this.apiURL}/api/all-dashboard-pages`);
+  }
+
+  getSharedPages(): Observable<Array<IDashboardPage>> {
+    return this.http.get<Array<IDashboardPage>>(`${this.apiURL}/api/shared-dashboard-pages`);
+  }
+
+  getPersonalPages(): Observable<Array<IDashboardPage>> {
+    return this.http.get<Array<IDashboardPage>>(`${this.apiURL}/api/personal-dashboard-pages`);
+  }
+
+  getEditablePages(): Observable<Array<IDashboardPage>> {
+    return this.http.get<Array<IDashboardPage>>(`${this.apiURL}/api/editable-dashboard-pages`);
+  }
+
+  getClonablePages(): Observable<Array<IDashboardPage>> {
+    return this.http.get<Array<IDashboardPage>>(`${this.apiURL}/api/clonable-dashboard-pages`);
+  }
+
+  getPageById(id: string): Observable<IDashboardPage> {
+    return this.http.get<IDashboardPage>(`${this.apiURL}/api/dashboard-pages/${id}`);
+  }
+
+  createPage(page: IDashboardPage): Observable<IDashboardPage> {
+    let httpHeaders = new HttpHeaders({ 'Content-type': 'application/json' });
+    return this.http.post<IDashboardPage>(`${this.apiURL}/api/dashboard-pages`, page, { headers: httpHeaders });
+  }
+
+  deletePageById(id: string): any {
+    return this.http.delete<IDashboardPage>(`${this.apiURL}/api/dashboard-pages/${id}`);
+  }
+
+  deleteDeepPageById(id: string): any {
+    return this.http.delete<IDashboardPage>(`${this.apiURL}/api/dashboard-pages-deep/${id}`);
+  }
+
+  updatePageById(page: IDashboardPage): Observable<IDashboardPage> {
+    let httpHeaders = new HttpHeaders({ 'Content-type': 'application/json' });
+    return this.http.put<IDashboardPage>(`${this.apiURL}/api/dashboard-pages/${page.id}`, page, {
+      headers: httpHeaders,
+    });
+  }
+
+  duplicatePage(id: string): Observable<IDashboardPage> {
+    return this.http.get<IDashboardPage>(`${this.apiURL}/api/duplicate-dashboard-pages/${id}`);
+  }
+
+  duplicatePageWithParams(cloneDashboard: ICloneDashboard): Observable<IDashboardPage> {
+    let httpHeaders = new HttpHeaders({ 'Content-type': 'application/json' });
+    return this.http.post<IDashboardPage>(`${this.apiURL}/api/duplicate-by-params-dashboard-pages`, cloneDashboard, { headers: httpHeaders });
+  }
+
+  getGeoJsonMap(url: string): Observable<any> {
+    //Mocked mode A => http://localhost:4200/assets/map/am_tram_2018.json
+    //Mocked mode B => http://localhost:4200/assets/map/2020-March-heatgeo-5minutes.json
+    if (url == undefined || url == null)
+      return of(AMTram2020);
+    else 
+      return this.http.get<any>(`${url}`);
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/services/form-manager.service.spec.ts b/src/app/pages/dashboard-management/services/form-manager.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..39e8d3f822efd1d245603db8f986f51308cfdaa5
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/form-manager.service.spec.ts
@@ -0,0 +1,15 @@
+import { TestBed } from '@angular/core/testing';
+import { FormManagerService } from './form-manager.service';
+
+describe('FormManagerService', () => {
+  let service: FormManagerService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(FormManagerService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/services/form-manager.service.ts b/src/app/pages/dashboard-management/services/form-manager.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7fafacdf2d5a348db580650b94366f9b6b2dcc04
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/form-manager.service.ts
@@ -0,0 +1,29 @@
+import { Injectable } from '@angular/core';
+import { FormGroup, FormControl, FormArray, Validators } from '@angular/forms';
+import { IDashboardPage } from '../../../model/dashboard-page.model';
+
+
+@Injectable({
+
+  providedIn: 'root'
+})
+export class FormManagerService {
+
+  constructor() { }
+
+
+  pageFormCreator(page: IDashboardPage): FormGroup {
+
+    let group: any = {
+      id: new FormControl(page.id || null),
+      name: new FormControl(page.name || null, Validators.required),
+      description: new FormControl(page.description || null),
+      note: new FormControl(page.note || null),
+      shared: new FormControl(page.shared || null, Validators.required),
+      content: new FormControl(page.content || null),
+    };
+
+    return new FormGroup(group);
+
+  }
+}
\ No newline at end of file
diff --git a/src/app/pages/dashboard-management/services/menu-block-crud.service.spec.ts b/src/app/pages/dashboard-management/services/menu-block-crud.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dae1ff56c4d043c984c190fbeb65e53570f8e06d
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/menu-block-crud.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { MenuBlockCrudService } from './menu-block-crud.service';
+
+describe('MenuBlockCrudService', () => {
+  let service: MenuBlockCrudService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(MenuBlockCrudService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/services/menu-block-crud.service.ts b/src/app/pages/dashboard-management/services/menu-block-crud.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..08403a36a69851bf5c3afc222d0a69368eb68378
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/menu-block-crud.service.ts
@@ -0,0 +1,57 @@
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { ConfigService } from '@ngx-config/core';
+import { Observable } from 'rxjs';
+import { IMenuBlock } from '../../../model/menu-block.model';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class MenuBlockCrudService {
+  private apiURL: any;
+
+  constructor(configService: ConfigService, private http: HttpClient) {
+    this.apiURL = configService.getSettings("dashboard-controller.api_base_url");
+  }
+
+  getAll(): Observable<Array<IMenuBlock>> {
+    return this.http.get<Array<IMenuBlock>>(`${this.apiURL}/api/menu-blocks`);
+  }
+
+  getAllShared(): Observable<Array<IMenuBlock>> {
+    return this.http.get<Array<IMenuBlock>>(`${this.apiURL}/api/shared-menu-blocks`);
+  }
+
+  getAllPersonal(): Observable<Array<IMenuBlock>> {
+    return this.http.get<Array<IMenuBlock>>(`${this.apiURL}/api/personal-menu-blocks`);
+  }
+
+  getAllLinked(): Observable<Array<IMenuBlock>> {
+    return this.http.get<Array<IMenuBlock>>(`${this.apiURL}/api/linked-menu-blocks`);
+  }
+
+  getAllEditable(): Observable<Array<IMenuBlock>> {
+    return this.http.get<Array<IMenuBlock>>(`${this.apiURL}/api/editable-menu-blocks`);
+  }
+
+  getById(id: string): Observable<IMenuBlock> {
+    return this.http.get<IMenuBlock>(`${this.apiURL}/api/menu-blocks/${id}`);
+  }
+
+  create(menuBlock: IMenuBlock): Observable<IMenuBlock> {
+    let httpHeaders = new HttpHeaders({ 'Content-type': 'application/json' });
+    return this.http.post<IMenuBlock>(`${this.apiURL}/api/menu-blocks`, menuBlock, { headers: httpHeaders });
+  }
+
+  deleteById(id: string): any {
+    return this.http.delete<IMenuBlock>(`${this.apiURL}/api/menu-blocks/${id}`);
+  }
+
+  update(menuBlock: IMenuBlock): Observable<IMenuBlock> {
+    let httpHeaders = new HttpHeaders({ 'Content-type': 'application/json' });
+    return this.http.put<IMenuBlock>(`${this.apiURL}/api/menu-blocks/${menuBlock.id}`, menuBlock, {
+      headers: httpHeaders,
+    });
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/services/menu-form-manager.service.spec.ts b/src/app/pages/dashboard-management/services/menu-form-manager.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b0274df300d5d66a42630d4d7a43cc91f177a6c6
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/menu-form-manager.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { MenuFormManagerService } from './menu-form-manager.service';
+
+describe('MenuFormManagerService', () => {
+  let service: MenuFormManagerService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(MenuFormManagerService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/services/menu-form-manager.service.ts b/src/app/pages/dashboard-management/services/menu-form-manager.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..57b80fde460eaaf2757809883be731732ce0e506
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/menu-form-manager.service.ts
@@ -0,0 +1,28 @@
+import { Injectable } from '@angular/core';
+import { FormControl, FormGroup, Validators } from '@angular/forms';
+import { IMenuBlock } from '../../../model/menu-block.model';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class MenuFormManagerService {
+
+  constructor() { }
+
+
+  pageFormCreator(block: IMenuBlock): FormGroup {
+
+    let group: any = {
+      id: new FormControl(block.id || null),
+      code:  new FormControl(block.code || null),
+      label: new FormControl(block.label || null, Validators.required),
+      order: new FormControl(block.order || null),
+      type: new FormControl(block.type || null, Validators.required),
+      // createdDate: new FormControl(block.createdDate || null),
+      createdBy: new FormControl(block.createdBy || null),
+      menuItems: new FormControl(block.linkedItems || null),
+    };
+
+    return new FormGroup(group);
+  }
+}
diff --git a/src/app/pages/dashboard-management/services/menu-item-crud.service.spec.ts b/src/app/pages/dashboard-management/services/menu-item-crud.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..28c6183f614c280c3aaf2d4d937e9426e27f7531
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/menu-item-crud.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { MenuItemCrudService } from './menu-item-crud.service';
+
+describe('MenuItemCrudService', () => {
+  let service: MenuItemCrudService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(MenuItemCrudService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/services/menu-item-crud.service.ts b/src/app/pages/dashboard-management/services/menu-item-crud.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3bda87ff86287a43689233f98cbe478ee2323997
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/menu-item-crud.service.ts
@@ -0,0 +1,45 @@
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { ConfigService } from '@ngx-config/core';
+import { Observable } from 'rxjs';
+import { IMenuItem } from '../../../model/menu-item.model';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class MenuItemCrudService {
+  private apiURL: any;
+
+  constructor(configService: ConfigService, private http: HttpClient) {
+    this.apiURL = configService.getSettings("dashboard-controller.api_base_url");
+  }
+
+  getAll(): Observable<Array<IMenuItem>> {
+    return this.http.get<Array<IMenuItem>>(`${this.apiURL}/api/menu-items`);
+  }
+
+  getById(id: string): Observable<IMenuItem> {
+    return this.http.get<IMenuItem>(`${this.apiURL}/api/menu-items/${id}`);
+  }
+
+  getByPageId(pageId: string): Observable<Array<IMenuItem>> {
+    return this.http.get<Array<IMenuItem>>(`${this.apiURL}/api/menu-items-bypage/${pageId}`);
+  }
+
+  create(menuItem: IMenuItem): Observable<IMenuItem> {
+    let httpHeaders = new HttpHeaders({ 'Content-type': 'application/json' });
+    return this.http.post<IMenuItem>(`${this.apiURL}/api/menu-items`, menuItem, { headers: httpHeaders });
+  }
+
+  deleteById(id: string): any {
+    return this.http.delete<IMenuItem>(`${this.apiURL}/api/menu-items/${id}`);
+  }
+
+  update(menuItem: IMenuItem): Observable<IMenuItem> {
+    let httpHeaders = new HttpHeaders({ 'Content-type': 'application/json' });
+    return this.http.put<IMenuItem>(`${this.apiURL}/api/menu-items/${menuItem.id}`, menuItem, {
+      headers: httpHeaders,
+    });
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/services/menu-mapper.service.spec.ts b/src/app/pages/dashboard-management/services/menu-mapper.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c0f429e3e32e97bf7fcee0bb35de93910425051f
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/menu-mapper.service.spec.ts
@@ -0,0 +1,15 @@
+import { TestBed } from '@angular/core/testing';
+import { MenuMapperService } from './menu-mapper.service';
+
+describe('MenuMapperService', () => {
+  let service: MenuMapperService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(MenuMapperService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/services/menu-mapper.service.ts b/src/app/pages/dashboard-management/services/menu-mapper.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..23330d72ecfb0c7d574567ebc10dc172e92e7378
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/menu-mapper.service.ts
@@ -0,0 +1,67 @@
+import { Injectable } from '@angular/core';
+import { NbMenuItem } from '@nebular/theme';
+import { MenuType } from '../../../model/enumeration/menu-type.model';
+import { IMenuBlock } from '../../../model/menu-block.model';
+import { IMenuItem } from '../../../model/menu-item.model';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class MenuMapperService {
+
+  constructor() {
+  }
+
+  /**
+   * JMA - This is a mapper to convert IMenuItem into NbMenuItem child.
+   * 
+   * @param IMenuItem 
+   * @returns NbMenuItem
+   */
+  mapItemToNbMenuItem(menuItem: IMenuItem): any {
+    //console.log('Mapping item: ', menuItem);
+    let nbMenuItem = new NbMenuItem;
+    if (menuItem.dashboardPage !== undefined && menuItem.dashboardPage !== null && menuItem.dashboardPage.id !== null) {
+      nbMenuItem.link ='/pages/dashboard-management/edit-dashboard-page-content/'+menuItem.dashboardPage.id;
+      nbMenuItem.queryParams = {isEditable: false};
+    }
+    if (menuItem.label !== undefined && menuItem.label !== null) {
+      nbMenuItem.title = menuItem.label;
+    }
+    /*if (menuItem.type !== undefined && menuItem.type !== null) {
+      nbMenuItem.icon = menuItem.type == MenuType.SHARED ? 'globe-outline' : 'lock-outline';
+    }*/
+    return nbMenuItem;
+  }
+
+
+  /**
+   * JMA - This is a mapper to convert IMenuBlock into NbMenuItem father.
+   * 
+   * @param IMenuBlock 
+   * @returns NbMenuItem
+   */
+  mapBlockToNbMenuItem(menuBlock: IMenuBlock): any {
+    let nbMenuItem = new NbMenuItem();
+    //console.log('link ' + menuBlock.code);
+    if (menuBlock.code !== undefined && menuBlock.code !== null) {
+      nbMenuItem.link = menuBlock.code;
+    }
+    //console.log('title ' + menuBlock.label);
+    if (menuBlock.label !== undefined && menuBlock.label !== null) {
+      nbMenuItem.title = menuBlock.label;
+    }
+    if (menuBlock.type !== undefined && menuBlock.type !== null) {
+      nbMenuItem.icon = menuBlock.type == MenuType.SHARED ? 'globe-outline' : 'lock-outline';
+    }
+    //console.log('Check not undef: ', menuBlock.linkedItems !== undefined, 'Check not null: ', menuBlock.linkedItems !== null);
+    //console.log('Menu items: ', menuBlock.linkedItems);
+
+    if (menuBlock.linkedItems !== undefined || menuBlock.linkedItems !== null) {
+      // console.log('### menuBlock.linkedItems ===> ', menuBlock.linkedItems);
+      nbMenuItem.children = menuBlock.linkedItems.map(item => this.mapItemToNbMenuItem(item)); // TODO: finish
+    }
+    return nbMenuItem;
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/services/target-available-crud.service.spec.ts b/src/app/pages/dashboard-management/services/target-available-crud.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..60b126839b2339f7037afa5c56d1abade5e1ffd5
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/target-available-crud.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { TargetAvailableCrudService } from './target-available-crud.service';
+
+describe('TargetAvailableCrudService', () => {
+  let service: TargetAvailableCrudService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(TargetAvailableCrudService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/services/target-available-crud.service.ts b/src/app/pages/dashboard-management/services/target-available-crud.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1885fe9c67790d67e977ce49b53b9e3ce31b4501
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/target-available-crud.service.ts
@@ -0,0 +1,45 @@
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { ConfigService } from '@ngx-config/core';
+import { Subject, Observable } from 'rxjs';
+import { ITargetAvailable } from '../../../model/target-available.model';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class TargetAvailableCrudService {
+  private apiURL: any;
+
+  constructor(configService: ConfigService, private http: HttpClient) {
+    this.apiURL = configService.getSettings("dashboard-controller.api_base_url");
+  }
+
+  getAll(): Observable<Array<ITargetAvailable>> {
+    return this.http.get<Array<ITargetAvailable>>(`${this.apiURL}/api/target-availables`);
+  }
+
+  getAvailableTargetById(id: string): Observable<ITargetAvailable> {
+    return this.http.get<ITargetAvailable>(`${this.apiURL}/api/target-availables/${id}`);
+  }
+
+  getAvailableTargetsByType(type: string): Observable<Array<ITargetAvailable>> {
+    return this.http.get<Array<ITargetAvailable>>(`${this.apiURL}/api/target-availables-bytype/${type}`);
+  }
+
+  createAvailableTarget(target: ITargetAvailable): Observable<ITargetAvailable> {
+    let httpHeaders = new HttpHeaders({ 'Content-type': 'application/json' });
+    return this.http.post<ITargetAvailable>(`${this.apiURL}/api/target-availables`, target, { headers: httpHeaders });
+  }
+
+  deleteAvailableTargetById(id: string): any {
+    return this.http.delete<ITargetAvailable>(`${this.apiURL}/api/target-availables/${id}`);
+  }
+
+  updateAvailableTarget(target: ITargetAvailable): Observable<ITargetAvailable> {
+    let httpHeaders = new HttpHeaders({ 'Content-type': 'application/json' });
+    return this.http.put<ITargetAvailable>(`${this.apiURL}/api/target-availables/${target.id}`, target, {
+      headers: httpHeaders,
+    });
+  }
+  
+}
diff --git a/src/app/pages/dashboard-management/services/target-crud.service.spec.ts b/src/app/pages/dashboard-management/services/target-crud.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f4358d3bd4f3adabb0ba1736c3111d6961108c05
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/target-crud.service.spec.ts
@@ -0,0 +1,15 @@
+import { TestBed } from '@angular/core/testing';
+import { TargetCrudService } from './target-crud.service';
+
+describe('TargetCrudService', () => {
+  let service: TargetCrudService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(TargetCrudService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/services/target-crud.service.ts b/src/app/pages/dashboard-management/services/target-crud.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6793209f7a87ba4bdc201fe390a890d7c29f8484
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/target-crud.service.ts
@@ -0,0 +1,45 @@
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { ConfigService } from '@ngx-config/core';
+import { Subject, Observable } from 'rxjs';
+import { ITarget } from '../../../model/target.model';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class TargetCrudService {
+  private apiURL: any;
+
+  constructor(configService: ConfigService, private http: HttpClient) {
+    this.apiURL = configService.getSettings("dashboard-controller.api_base_url");
+  }
+
+  getAll(): Observable<Array<ITarget>> {
+    return this.http.get<Array<ITarget>>(`${this.apiURL}/api/targets`);
+  }
+
+  getTargetById(id: string): Observable<ITarget> {
+    return this.http.get<ITarget>(`${this.apiURL}/api/targets/${id}`);
+  }
+
+  getTargetsByPageId(pageId: string): Observable<Array<ITarget>> {
+    return this.http.get<Array<ITarget>>(`${this.apiURL}/api/targets-bypage/${pageId}`);
+  }
+
+  createTarget(target: ITarget): Observable<ITarget> {
+    let httpHeaders = new HttpHeaders({ 'Content-type': 'application/json' });
+    return this.http.post<ITarget>(`${this.apiURL}/api/targets`, target, { headers: httpHeaders });
+  }
+
+  deleteTargetById(id: string): any {
+    return this.http.delete<ITarget>(`${this.apiURL}/api/targets/${id}`);
+  }
+
+  updateTarget(target: ITarget): Observable<ITarget> {
+    let httpHeaders = new HttpHeaders({ 'Content-type': 'application/json' });
+    return this.http.put<ITarget>(`${this.apiURL}/api/targets/${target.id}`, target, {
+      headers: httpHeaders,
+    });
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/services/user-crud.service.spec.ts b/src/app/pages/dashboard-management/services/user-crud.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..aadcfe87dc4e76b706a22074e85a819265567313
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/user-crud.service.spec.ts
@@ -0,0 +1,15 @@
+import { TestBed } from '@angular/core/testing';
+import { UserCrudService } from './user-crud.service';
+
+describe('UserCrudService', () => {
+  let service: UserCrudService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(UserCrudService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/services/user-crud.service.ts b/src/app/pages/dashboard-management/services/user-crud.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..522075074b3c895be9551f33daf71ab3d4f5f4b1
--- /dev/null
+++ b/src/app/pages/dashboard-management/services/user-crud.service.ts
@@ -0,0 +1,35 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { ConfigService } from '@ngx-config/core';
+import { Observable } from 'rxjs';
+import { IGroupRepresentation } from '../../../model/group-representation.model';
+import { IRoleRepresentation } from '../../../model/role-representation.model';
+import { IUser } from '../../../model/user.model';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class UserCrudService {
+  private apiURL: any;
+
+  constructor(configService: ConfigService, private http: HttpClient) {
+    this.apiURL = configService.getSettings("dashboard-controller.api_base_url");
+  }
+
+  getIdmUsers(): Observable<Array<IUser>> {
+    return this.http.get<Array<IUser>>(`${this.apiURL}/user/get-idm-users`);
+  }
+
+  getIdmRoles(): Observable<Array<IRoleRepresentation>> {
+    return this.http.get<Array<IRoleRepresentation>>(`${this.apiURL}/user/get-idm-roles`);
+  }
+  
+  getIdmGroups(): Observable<Array<IGroupRepresentation>> {
+    return this.http.get<Array<IGroupRepresentation>>(`${this.apiURL}/user/get-idm-groups`);
+  }
+
+  getUserRoles(): Observable<Array<string>> {
+    return this.http.get<Array<string>>(`${this.apiURL}/user/get-user-roles`);
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/statistics/statistics.component.html b/src/app/pages/dashboard-management/statistics/statistics.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..edfc9c96fced11c9477c585a0958f803fa28c3f7
--- /dev/null
+++ b/src/app/pages/dashboard-management/statistics/statistics.component.html
@@ -0,0 +1,12 @@
+<nb-card size="medium">
+  <nb-card-body>
+    <span class="h3 location">{{statistics_title}}</span>
+    <span class="date">{{statistics_subtitle}}</span>
+
+    <div class="today">
+      <span class="today-temperature h1">{{statistics_value}}</span>
+      <nb-icon [icon]="statistics_icon" pack="eva" class="today-icon"></nb-icon>
+    </div>
+
+  </nb-card-body>
+</nb-card>
diff --git a/src/app/pages/dashboard-management/statistics/statistics.component.scss b/src/app/pages/dashboard-management/statistics/statistics.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..2ac7e09720a4ae2bb9367eefa46b25c683fb3d64
--- /dev/null
+++ b/src/app/pages/dashboard-management/statistics/statistics.component.scss
@@ -0,0 +1,76 @@
+@import '../../../@theme/styles/themes';
+
+@include nb-install-component() {
+
+  nb-card-body {
+    display: flex;
+    flex-direction: column;
+  }
+
+  .location,
+  .date {
+    display: block;
+  }
+
+  .location {
+    margin-bottom: 0.1rem;
+  }
+
+  .today {
+    display: flex;
+    justify-content: space-around;
+  }
+
+  .today-temperature {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    margin: 2rem 1.5rem;
+  }
+
+  .today-icon {
+    color: nb-theme(color-primary-default);
+    font-size: 10rem;
+    line-height: 1;
+    margin-top: -4rem;
+    margin-left: auto;
+    margin-right: 0.4rem;
+  }
+
+  .today-details {
+    display: flex;
+    justify-content: space-around;
+    margin-top: 2rem;
+  }
+
+  .parameter {
+    flex: 1 1 auto;
+    text-align: center;
+  }
+
+  .parameter-name,
+  .parameter-value {
+    display: block;
+  }
+
+  .caption {
+    text-transform: uppercase;
+  }
+
+  .weekly-forecast {
+    display: flex;
+    justify-content: space-around;
+    margin: auto 0;
+  }
+
+  .day {
+    display: flex;
+    flex-direction: column;
+    text-align: center;
+  }
+
+  .weather-icon {
+    font-size: 2.5rem;
+    line-height: 2.5rem;
+  }
+}
diff --git a/src/app/pages/dashboard-management/statistics/statistics.component.ts b/src/app/pages/dashboard-management/statistics/statistics.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..59922474b9a000e281d3a34b776774d5ab7567f9
--- /dev/null
+++ b/src/app/pages/dashboard-management/statistics/statistics.component.ts
@@ -0,0 +1,22 @@
+import { Component, Input, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'ngx-statistics',
+  styleUrls: ['./statistics.component.scss'],
+  templateUrl: './statistics.component.html',
+})
+
+export class StatisticsComponent implements OnInit {
+  
+  @Input() statistics_title: string;
+  @Input() statistics_subtitle: string;
+  @Input() statistics_value: string;
+  @Input() statistics_icon: string;
+
+  ngOnInit(): void {
+    //console.log("This is my statistics => " + this.statistics);
+    //this.statistics = JSON.parse(this.statistics);
+    // external-link-outline, sun-outline
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/target-filter/target-filter.component.html b/src/app/pages/dashboard-management/target-filter/target-filter.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..0515d1defb3ee06202c18aa1c07f19e202910f51
--- /dev/null
+++ b/src/app/pages/dashboard-management/target-filter/target-filter.component.html
@@ -0,0 +1,112 @@
+<nb-card *ngIf="!disabledTarget">
+    <nb-card-header >
+
+        <div class="d-flex flex-row justify-content-between align-items-center mt-2" [formGroup]="form" >
+            <h4>
+                {{'general.targets'|translate}}   
+                <nb-icon icon="info-outline" nbTooltip="{{'target.add_button_info'|translate}}" ></nb-icon> 
+            </h4>
+
+                <!-- USERS -->
+                <nb-select *ngIf="!useIDM4Target" size="small" placeholder="{{'target.select_person'|translate}}" formControlName="selectedAvailablePerson" 
+                        nbTooltip="{{'target.select_person'|translate}}">
+                    <nb-option *ngFor="let person of filterTarget(fullListAvailablePerson,'PERSON'); " [value]="person">
+                        {{person.code}} - {{person.value}}
+                    </nb-option>
+                </nb-select>
+                <nb-select *ngIf="useIDM4Target" size="small" placeholder="{{'target.select_person'|translate}}" formControlName="selectedAvailablePersonIDM" 
+                        nbTooltip="{{'target.select_person'|translate}}">
+                    <nb-option *ngFor="let person of filterIDMPersons(fullListAvailablePersonIDM); " [value]="person">
+                        <!-- {{person.firstName}} {{person.lastName}} ({{person.email}}) -->
+                        {{person.username}}
+                    </nb-option>
+                </nb-select>
+                <button nbButton size="small" status="primary" (click)="addTargetPerson()" > 
+                    <nb-icon icon="person-outline"></nb-icon>{{'general.add' | translate}} {{'TargetType.PERSON'| translate}}
+                </button>
+            
+
+                <!-- 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">
+                        {{role.code}} - {{role.value}}
+                    </nb-option>
+                </nb-select>
+                <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>
+                </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" 
+                        nbTooltip="{{'target.select_group'|translate}}">
+                    <nb-option *ngFor="let group of filterTarget(fullListAvailableGroup,'GROUP'); " [value]="group">
+                        {{group.code}} - {{group.value}}
+                    </nb-option>
+                </nb-select>
+                <nb-select *ngIf="useIDM4Target" size="small" placeholder="{{'target.select_group'|translate}}" formControlName="selectedAvailableGroupIDM" 
+                        nbTooltip="{{'target.select_group'|translate}}">
+                    <nb-option *ngFor="let group of filterIDMGroups(fullListAvailableGroupsIDM); " [value]="group">
+                        {{group.name}}
+                    </nb-option>
+                </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>
+
+        </div>
+
+    </nb-card-header>
+    <nb-card-body>
+        <ng2-smart-table [settings]="settings" [source]="source"></ng2-smart-table>
+    </nb-card-body>
+</nb-card>
+
+
+<nb-card *ngIf="disabledTarget">
+    <nb-card-header >
+        <div class="d-flex flex-row justify-content-between align-items-center mt-2">
+            <h4>
+                {{'general.targets'|translate}}   
+                <nb-icon icon="info-outline" nbTooltip="{{'target.add_button_info_disabled'|translate}}" ></nb-icon> 
+            </h4>
+                <!-- USERS -->
+                <nb-select size="small" placeholder="{{'target.select_person'|translate}}" disabled
+                        nbTooltip="{{'target.select_person'|translate}}">
+                    <nb-option></nb-option>
+                </nb-select>
+                <button nbButton size="small" status="primary" disabled>
+                    <nb-icon icon="person-outline"></nb-icon>{{'general.add' | translate}} {{'TargetType.PERSON'| translate}}
+                </button>
+            
+                <!-- ROLES -->
+                <nb-select size="small" placeholder="{{'target.select_role'|translate}}" disabled
+                        nbTooltip="{{'target.select_role'|translate}}">
+                    <nb-option></nb-option>
+                </nb-select>
+                <button nbButton size="small" status="primary" disabled>
+                    <nb-icon icon="globe-2-outline"></nb-icon>{{'general.add' | translate}} {{'TargetType.ROLE'| translate}}
+                </button>
+
+                <!-- GROUPS -->
+                <nb-select size="small" placeholder="{{'target.select_group'|translate}}" disabled
+                        nbTooltip="{{'target.select_group'|translate}}">
+                    <nb-option></nb-option>
+                </nb-select>
+                <button nbButton size="small" status="primary" disabled>
+                    <nb-icon icon="globe-2-outline"></nb-icon>{{'general.add' | translate}} {{'TargetType.GROUP'| translate}}
+                </button>
+                
+        </div>
+    </nb-card-header>
+    <nb-card-body>
+        <!-- <ng2-smart-table [settings]="settings" [source]="source"></ng2-smart-table> -->
+    </nb-card-body>
+</nb-card>
\ No newline at end of file
diff --git a/src/app/pages/dashboard-management/target-filter/target-filter.component.scss b/src/app/pages/dashboard-management/target-filter/target-filter.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/pages/dashboard-management/target-filter/target-filter.component.spec.ts b/src/app/pages/dashboard-management/target-filter/target-filter.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..56c5d31cf4c3d0a70a3da3bb725e5f647611cb29
--- /dev/null
+++ b/src/app/pages/dashboard-management/target-filter/target-filter.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TargetFilterComponent } from './target-filter.component';
+
+describe('TargetFilterComponent', () => {
+  let component: TargetFilterComponent;
+  let fixture: ComponentFixture<TargetFilterComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ TargetFilterComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(TargetFilterComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/dashboard-management/target-filter/target-filter.component.ts b/src/app/pages/dashboard-management/target-filter/target-filter.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9f163a40e9b90f98f7674c41fc44c90ef987089e
--- /dev/null
+++ b/src/app/pages/dashboard-management/target-filter/target-filter.component.ts
@@ -0,0 +1,405 @@
+import { Component, Input, OnInit } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { NbDialogService, NbToastrService } from '@nebular/theme';
+import { ConfigService } from '@ngx-config/core';
+import { TranslateService } from '@ngx-translate/core';
+import { LocalDataSource } from 'ng2-smart-table';
+import { DashboardPage } from '../../../model/dashboard-page.model';
+import { TargetType } from '../../../model/enumeration/target-type.model';
+import { IGroupRepresentation } from '../../../model/group-representation.model';
+import { IRoleRepresentation } from '../../../model/role-representation.model';
+import { ITargetAvailable } from '../../../model/target-available.model';
+import { ITarget, Target } from '../../../model/target.model';
+import { IUser } from '../../../model/user.model';
+import { DialogComponent } from '../../shared/dialog/dialog.component';
+import { TableActionsComponent } from '../../shared/table-actions/table-actions.component';
+import { TargetAvailableCrudService } from '../services/target-available-crud.service';
+import { TargetCrudService } from '../services/target-crud.service';
+import { UserCrudService } from '../services/user-crud.service';
+
+@Component({
+  selector: 'ngx-target-filter',
+  templateUrl: './target-filter.component.html',
+  styleUrls: ['./target-filter.component.scss']
+})
+export class TargetFilterComponent implements OnInit {
+  @Input() pageId: string;
+  @Input() disabledTarget: boolean = true;  // USED TO HIDE TARGET
+
+  //SMART TABLES
+  source: LocalDataSource;
+  settings: any;
+  sharedTargets: Array<ITarget>=[];
+
+  form:FormGroup;
+  toAddTarget: ITarget;  
+
+  //Available Targets
+  useIDM4Target: boolean;
+
+  //(option B) Uses data from internal table (TARGET_AVAILABLE)
+  fullListAvailablePerson:Array<ITargetAvailable>=[];
+  fullListAvailableRole:Array<ITargetAvailable>=[];
+  fullListAvailableGroup:Array<ITargetAvailable>=[];
+  selectedAvailablePerson: ITargetAvailable;
+  selectedAvailableRole: ITargetAvailable;
+  selectedAvailableGroup: ITargetAvailable;
+
+  //(option A) Uses data from IDM
+  fullListAvailablePersonIDM:Array<IUser>=[];
+  fullListAvailableRoleIDM:Array<IRoleRepresentation>=[];
+  fullListAvailableGroupsIDM:Array<IGroupRepresentation>=[];
+  selectedAvailablePersonIDM: IUser;
+  selectedAvailableRoleIDM: IRoleRepresentation;
+  selectedAvailableGroupIDM: IGroupRepresentation;
+
+  constructor(
+      private fb: FormBuilder,
+      private targetService: TargetCrudService, 
+      private configService: ConfigService,
+      private targetAvailableCrudService: TargetAvailableCrudService, 
+      private userCrudService: UserCrudService, 
+      private dialogService: NbDialogService, 
+      private toastrService: NbToastrService,
+      private translateService: TranslateService) 
+  { }
+
+  ngOnInit(): void {
+    // CHANGE THIS TO READS USERS/ROLES (GROUPS) FROM IDM or INTERNAL TABLE:
+    // true  => (option A) IDM
+    // false => (option B) INTERNAL TABLE (DEMO)
+    this.useIDM4Target = this.configService.getSettings("dashboard-controller.useIDM4Target");
+
+    this.initTableSettings();
+    this.source = new LocalDataSource();
+    this.fetchTargetTableData();
+
+    this.form = this.fb.group({
+      selectedAvailablePerson: [this.selectedAvailablePerson, Validators.nullValidator],
+      selectedAvailableRole: [this.selectedAvailableRole, Validators.nullValidator],
+      selectedAvailableGroup: [this.selectedAvailableGroup, Validators.nullValidator],
+      selectedAvailablePersonIDM: [this.selectedAvailablePersonIDM, Validators.nullValidator],
+      selectedAvailableRoleIDM: [this.selectedAvailableRoleIDM, Validators.nullValidator],
+      selectedAvailableGroupIDM: [this.selectedAvailableGroupIDM, Validators.nullValidator],
+    });
+
+    if (this.useIDM4Target == true) {
+        //Retrieve list of Person/Roles/Groups from IDM
+        this.userCrudService.getIdmUsers().subscribe( res =>{
+          this.fullListAvailablePersonIDM = res;
+        });
+        this.userCrudService.getIdmRoles().subscribe( res =>{
+          this.fullListAvailableRoleIDM = res;
+        });
+        this.userCrudService.getIdmGroups().subscribe( res =>{
+          this.fullListAvailableGroupsIDM = res;
+        });
+    } else {
+        //Retrieve list of Person/Role/Groups from internal table
+        this.targetAvailableCrudService.getAvailableTargetsByType(TargetType.PERSON).subscribe( res =>{
+          this.fullListAvailablePerson = res;
+        });
+        this.targetAvailableCrudService.getAvailableTargetsByType(TargetType.ROLE).subscribe( res =>{
+          this.fullListAvailableRole = res;
+        });
+        this.targetAvailableCrudService.getAvailableTargetsByType(TargetType.GROUP).subscribe( res =>{
+          this.fullListAvailableGroup = res;
+        });
+    }
+
+  }
+
+  fetchTargetTableData() {
+    //Retrieve Targets of the selected PageId
+    if (this.pageId!=undefined) {
+      this.targetService.getTargetsByPageId(this.pageId).subscribe(data => {
+        this.sharedTargets=data;
+        this.source.load(data);
+      });
+    }
+
+  }
+
+  addTargetPerson() {
+    console.log("# Add Person linked to dashboard with pageId =>" + this.pageId);
+    const person = this.useIDM4Target
+                 ? this.form.get('selectedAvailablePersonIDM').value
+                 : this.form.get('selectedAvailablePerson').value;
+    
+    if (person == undefined || person == null){
+      this.showWarning('target.fill_person');
+      return;
+    }
+
+    this.toAddTarget = this.useIDM4Target
+                     ? this.buildUserTargetIDM(person, TargetType.PERSON, Number(this.pageId))
+                     : this.buildTarget(person, TargetType.PERSON, Number(this.pageId));
+
+    this.targetService.createTarget(this.toAddTarget).subscribe(
+      (data: Target) => {
+        this.showSuccess('target.created');
+        this.fetchTargetTableData();
+        this.form.reset(); //Clean select person
+      },
+      error => (this.showError(error))
+    );
+  }
+
+  addTargetRole() {
+    console.log("# Add Role linked to dashboard with pageId =>" + this.pageId);
+    const role = this.useIDM4Target
+               ? this.form.get('selectedAvailableRoleIDM').value
+               : this.form.get('selectedAvailableRole').value;
+    
+    if (role == undefined || role == null){
+      this.showWarning('target.fill_role');
+      return;
+    }
+
+    this.toAddTarget = this.useIDM4Target
+                     ? this.buildRoleTargetIDM(role, TargetType.ROLE, Number(this.pageId))
+                     : this.buildTarget(role, TargetType.ROLE, Number(this.pageId));
+
+    this.targetService.createTarget(this.toAddTarget).subscribe(
+      (data: Target) => {
+        this.showSuccess('target.created');
+        this.fetchTargetTableData();
+        this.form.reset(); //Clean select person
+      },
+      error => (this.showError(error))
+    );
+  }
+
+  addTargetGroup() {
+    console.log("# Add Group linked to dashboard with pageId =>" + this.pageId);
+    const group = this.useIDM4Target
+               ? this.form.get('selectedAvailableGroupIDM').value
+               : this.form.get('selectedAvailableGroup').value;
+    
+    if (group == undefined || group == null){
+      this.showWarning('target.fill_group');
+      return;
+    }
+
+    this.toAddTarget = this.useIDM4Target
+                     ? this.buildGroupTargetIDM(group, TargetType.GROUP, Number(this.pageId))
+                     : this.buildTarget(group, TargetType.GROUP, Number(this.pageId));
+
+    this.targetService.createTarget(this.toAddTarget).subscribe(
+      (data: Target) => {
+        this.showSuccess('target.created');
+        this.fetchTargetTableData();
+        this.form.reset(); //Clean select person
+      },
+      error => (this.showError(error))
+    );
+  }
+
+  private buildTarget(target: ITargetAvailable, type: TargetType, pageId: number) {
+    const curTarget = new Target();
+    curTarget.dashboardPage = new DashboardPage();
+    curTarget.dashboardPage.id = pageId;
+    curTarget.type = type;
+    curTarget.name = target.code;
+    curTarget.note = target.value;
+    return curTarget;
+  }
+
+  private buildUserTargetIDM(person: IUser, type: TargetType, pageId: number) {
+    const curTarget = new Target();
+    curTarget.dashboardPage = new DashboardPage();
+    curTarget.dashboardPage.id = pageId;
+    curTarget.type = type;
+    curTarget.name = person.username;
+    //curTarget.note = person.firstName + " " + person.lastName + "("+person.email+")";
+    curTarget.note = person.username;
+    return curTarget;
+  }
+
+  private buildRoleTargetIDM(role: IRoleRepresentation, type: TargetType, pageId: number) {
+    const curTarget = new Target();
+    curTarget.dashboardPage = new DashboardPage();
+    curTarget.dashboardPage.id = pageId;
+    curTarget.type = type;
+    curTarget.name = role.name;
+    //curTarget.note = role.description;
+    curTarget.note = role.name;
+    return curTarget;
+  }
+
+  private buildGroupTargetIDM(group: IGroupRepresentation, type: TargetType, pageId: number) {
+    const curTarget = new Target();
+    curTarget.dashboardPage = new DashboardPage();
+    curTarget.dashboardPage.id = pageId;
+    curTarget.type = type;
+    curTarget.name = group.name;
+    curTarget.note = group.name;
+    return curTarget;
+  }
+
+  initTableSettings(): void {
+    let targetTypeFilter=[];
+    for(let targetType of TargetType.values()){
+      targetTypeFilter.push({ value: targetType.enumVal, title: this.translateService.instant("TargetType."+targetType.enumVal) })
+    }
+
+    this.settings = {
+      mode: 'external',
+      attr: {
+        class: 'table table-bordered'
+      },
+      columns: {
+        /*id: {
+          title: this.translateService.instant('target.id'),
+        },*/
+        type: {
+          title: this.translateService.instant('target.type'),
+          valuePrepareFunction: (cell, row) => { 
+            if(row.type!=undefined && row.type!=null)
+              return this.translateService.instant('TargetType.' + row.type) 
+            else return '';
+          },
+          filter: {
+            type: 'list',
+            config: {
+              selectText: '',
+              list: targetTypeFilter
+            },
+          }
+
+
+        },
+        name: {
+          title: this.translateService.instant('target.name'),
+        },
+        note: {
+          title: this.translateService.instant('target.value')
+        },
+        /*
+        dashboardPage: {
+          title: this.translateService.instant('target.dashboardPage'),
+        }, */
+        
+        actions: {
+          title: this.translateService.instant('general.actions'),
+          filter: false,
+          sort: false,
+          type: 'custom',
+          valuePrepareFunction: (cell, row) => {
+            return [
+              {action:'delete', enabled:true, status:"danger", icon:"trash-2", tooltip:this.translateService.instant('general.delete')+" " + this.translateService.instant('target.title')}
+            ];
+          }, 
+          renderComponent: TableActionsComponent,
+          onComponentInitFunction: (instance) => {
+            instance.onCustom.subscribe(value => {
+              this.onCustom(value,instance.rowData);
+            });
+          },          
+        }
+
+      },
+
+      actions: {
+        add: false,
+        edit: false,
+        delete: false,
+      },
+
+    };
+  }
+
+
+  onCustom(event, data) {
+    if (event == 'delete') {
+      this.dialogService
+          .open( DialogComponent, { context: { 
+              title: this.translateService.instant('general.delete') + " " + this.translateService.instant('general.targets') , message: this.translateService.instant('general.deleteConfirm') } })
+          .onClose.subscribe(res => {
+        if (res) {
+          this.targetService.deleteTargetById(data.id).subscribe(() => {
+            this.fetchTargetTableData();
+            console.log(`# Target with id=${data.id} has been deleted.`),
+              this.showSuccess('target.deleted');
+          },
+            error => (this.showError(error))
+          );
+        } else return;
+
+      });
+    };
+  }
+
+  showSuccess(operation:string) {
+    this.toastrService.success(this.translateService.instant(operation), this.translateService.instant('general.success'));
+  }
+  
+  showError(error) {
+    this.toastrService.danger(error.error.message, this.translateService.instant('general.error'))
+  }
+
+  showWarning(operation:string) {
+    this.toastrService.warning(this.translateService.instant(operation), this.translateService.instant('general.warning'));
+  }
+
+  /**
+   * Filter to exclude from Available Person List the ones that are into the Target list
+   * @param persons Array<IUser>
+   * @returns Array<IUser>
+   */
+  filterIDMPersons(persons: Array<IUser>) {
+    let result :Array<IUser> = [];
+    if ( this.sharedTargets != undefined &&  this.sharedTargets.length>0 && persons != undefined &&  persons.length>0){
+      persons.forEach(person => {
+        let found = this.sharedTargets.filter(x=> x.name==person.username).map(x=>x.name);
+        if ( found.length == 0 ) { result.push(person) }
+      });
+    } else { result = persons; }
+    return result;
+  }
+
+  /**
+   * Filter to exclude from Available Groups List the ones that are into the Target list
+   * @param groups Array<IGroupRepresentation>
+   * @returns Array<IGroupRepresentation>
+   */
+  filterIDMGroups(groups: Array<IGroupRepresentation>) {
+    let result :Array<IGroupRepresentation> = [];
+    if ( this.sharedTargets != undefined &&  this.sharedTargets.length>0 && groups != undefined &&  groups.length>0){
+      groups.forEach(group => {
+        let found = this.sharedTargets.filter(x=> x.name==group.name).map(x=>x.name);
+        if ( found.length == 0 ) { result.push(group) }
+      });
+    } else { result = groups; }
+    return result;
+  }
+
+ /**
+  * Filter to exclude from Available Roles List the ones that are into the Target list
+  * @param roles Array<IRoleRepresentation>
+  * @returns Array<IRoleRepresentation>
+  */
+  filterIDMRoles(roles: Array<IRoleRepresentation>) {
+    let result :Array<IRoleRepresentation> = [];
+    if ( this.sharedTargets != undefined &&  this.sharedTargets.length>0 && roles != undefined &&  roles.length>0){
+      roles.forEach(role => {
+        let found = this.sharedTargets.filter(x=> x.name==role.name).map(x=>x.name);
+        if ( found.length == 0 ) { result.push(role) }
+      });
+    } else { result = roles; }
+    return result;
+  }
+
+  filterTarget(avTarget: Array<ITargetAvailable>, targetType: string) {
+    let result :Array<ITargetAvailable> = [];
+    const selectedType = (targetType==TargetType.GROUP ? TargetType.GROUP : (targetType==TargetType.ROLE ? TargetType.ROLE : TargetType.PERSON) );
+    if ( this.sharedTargets != undefined && this.sharedTargets.length>0 && avTarget != undefined &&  avTarget.length>0){
+      avTarget.forEach(curTarget => {
+        let found = this.sharedTargets.filter(x=> x.name==curTarget.code && curTarget.type == selectedType).map(x=>x.name);
+        if ( found.length == 0 ) { result.push(curTarget) }
+      });
+    } else { result = avTarget; }
+    return result;
+  }
+
+}
diff --git a/src/app/pages/dashboard-management/weather/weather.component.html b/src/app/pages/dashboard-management/weather/weather.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..4351f30f1ef18b75a5c1a7ee0dab90f778aa789a
--- /dev/null
+++ b/src/app/pages/dashboard-management/weather/weather.component.html
@@ -0,0 +1,54 @@
+<nb-card size="medium">
+  <nb-card-body>
+    <span class="h3 location">{{weather_title}}</span>
+    <span class="date">{{weather_subtitle}}</span>
+
+    <div class="today">
+      <span class="today-temperature h1">Total items: 20&deg;</span>
+      <nb-icon icon="sun-outline" pack="eva" class="today-icon"></nb-icon>
+    </div>
+
+    <div class="today-details">
+      <div class="parameter">
+        <span class="caption parameter-name">max</span>
+        <span class="parameter-value">23&deg;</span>
+      </div>
+      <div class="parameter">
+        <span class="caption parameter-name">min</span>
+        <span class="parameter-value">19&deg;</span>
+      </div>
+      <div class="parameter">
+        <span class="caption parameter-name">wind</span>
+        <span class="parameter-value">4 km/h</span>
+      </div>
+      <div class="parameter">
+        <span class="caption parameter-name">hum</span>
+        <span class="parameter-value">87%</span>
+      </div>
+    </div>
+
+    <div class="weekly-forecast">
+      <div class="day">
+        <span class="caption">Sun</span>
+        <i class="weather-icon ion-ios-cloudy-outline"></i>
+        <span class="temperature">17&deg;</span>
+      </div>
+      <div class="day">
+        <span class="caption">Mon</span>
+        <i class="weather-icon ion-ios-sunny-outline"></i>
+        <span class="temperature">19&deg;</span>
+      </div>
+      <div class="day">
+        <span class="caption">Tue</span>
+        <i class="weather-icon ion-ios-rainy-outline"></i>
+        <span class="temperature">22&deg;</span>
+      </div>
+      <div class="day">
+        <span class="caption">Wed</span>
+        <i class="weather-icon ion-ios-partlysunny-outline"></i>
+        <span class="temperature">21&deg;</span>
+      </div>
+    </div>
+    
+  </nb-card-body>
+</nb-card>
diff --git a/src/app/pages/dashboard-management/weather/weather.component.scss b/src/app/pages/dashboard-management/weather/weather.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..2ac7e09720a4ae2bb9367eefa46b25c683fb3d64
--- /dev/null
+++ b/src/app/pages/dashboard-management/weather/weather.component.scss
@@ -0,0 +1,76 @@
+@import '../../../@theme/styles/themes';
+
+@include nb-install-component() {
+
+  nb-card-body {
+    display: flex;
+    flex-direction: column;
+  }
+
+  .location,
+  .date {
+    display: block;
+  }
+
+  .location {
+    margin-bottom: 0.1rem;
+  }
+
+  .today {
+    display: flex;
+    justify-content: space-around;
+  }
+
+  .today-temperature {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    margin: 2rem 1.5rem;
+  }
+
+  .today-icon {
+    color: nb-theme(color-primary-default);
+    font-size: 10rem;
+    line-height: 1;
+    margin-top: -4rem;
+    margin-left: auto;
+    margin-right: 0.4rem;
+  }
+
+  .today-details {
+    display: flex;
+    justify-content: space-around;
+    margin-top: 2rem;
+  }
+
+  .parameter {
+    flex: 1 1 auto;
+    text-align: center;
+  }
+
+  .parameter-name,
+  .parameter-value {
+    display: block;
+  }
+
+  .caption {
+    text-transform: uppercase;
+  }
+
+  .weekly-forecast {
+    display: flex;
+    justify-content: space-around;
+    margin: auto 0;
+  }
+
+  .day {
+    display: flex;
+    flex-direction: column;
+    text-align: center;
+  }
+
+  .weather-icon {
+    font-size: 2.5rem;
+    line-height: 2.5rem;
+  }
+}
diff --git a/src/app/pages/dashboard-management/weather/weather.component.ts b/src/app/pages/dashboard-management/weather/weather.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..659ef4ab4e9f9283ae1c2a092d864c85f262f722
--- /dev/null
+++ b/src/app/pages/dashboard-management/weather/weather.component.ts
@@ -0,0 +1,19 @@
+import { Component, Input, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'ngx-weather',
+  styleUrls: ['./weather.component.scss'],
+  templateUrl: './weather.component.html',
+})
+
+export class WeatherComponent implements OnInit {
+  
+  @Input() weather_title: any;
+  @Input() weather_subtitle: any;
+
+  ngOnInit(): void {
+    //console.log("This is my weather => " + this.weather);
+    //this.weather = JSON.parse(this.weather);
+  }
+
+}
diff --git a/src/app/pages/data-catalogue/services/data-catalogue-admin-api.service.spec.ts b/src/app/pages/data-catalogue/services/data-catalogue-admin-api.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ea1f3b437f0bb9822e86210236c45c48d08ca644
--- /dev/null
+++ b/src/app/pages/data-catalogue/services/data-catalogue-admin-api.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { DataCatalogueAdminApiService } from './data-catalogue-admin-api.service';
+
+describe('DataCatalogueAdminApiService', () => {
+  let service: DataCatalogueAdminApiService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(DataCatalogueAdminApiService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/data-catalogue/services/data-catalogue-admin-api.service.ts b/src/app/pages/data-catalogue/services/data-catalogue-admin-api.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5db056137592a4d477824c6236ee378ca8e9d76a
--- /dev/null
+++ b/src/app/pages/data-catalogue/services/data-catalogue-admin-api.service.ts
@@ -0,0 +1,21 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { ConfigService } from '@ngx-config/core';
+import { Observable } from 'rxjs';
+import { Datalet } from '../model/datalet';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class DataCatalogueAdminApiService {
+  private apiEndpoint;
+
+  constructor(private config:ConfigService,private http:HttpClient) { 
+    this.apiEndpoint=this.config.getSettings("idra_base_url");
+  }
+
+  getAllDatalets(): Observable<Array<Datalet>> {
+    return this.http.get<Array<Datalet>>(`${this.apiEndpoint}/Idra/api/v1/administration/datalets`);
+  }
+
+}
diff --git a/src/app/pages/shared/dialog/dialog.component.html b/src/app/pages/shared/dialog/dialog.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..78c8f5bd2c03c2435249aeed4dc85b731ba5e901
--- /dev/null
+++ b/src/app/pages/shared/dialog/dialog.component.html
@@ -0,0 +1,16 @@
+<nb-card>
+    <nb-card-header>{{title}}</nb-card-header>
+    <!-- <nb-card-body>{{'general.deleteConfirm'}}</nb-card-body> -->
+    <!-- <nb-card-body>{{'Do you want delete the selected item?'}}</nb-card-body> -->
+    <nb-card-body>{{message}}</nb-card-body>
+    <nb-card-footer>
+        <div class="row my-2">
+            <div class="col-sm text-center">
+                <button nbButton status="danger" size="small" (click)="close(true)">{{'Yes'}}</button>
+            </div>
+            <div class="col-sm text-center">
+                <button nbButton status="info" size="small" (click)="close(false)">{{'No'}}</button>
+            </div>
+        </div>
+    </nb-card-footer>
+</nb-card>
\ No newline at end of file
diff --git a/src/app/pages/shared/dialog/dialog.component.scss b/src/app/pages/shared/dialog/dialog.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/pages/shared/dialog/dialog.component.spec.ts b/src/app/pages/shared/dialog/dialog.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a32e0ea6939a52db96a1582ed8b6a738def82d27
--- /dev/null
+++ b/src/app/pages/shared/dialog/dialog.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DialogComponent } from './dialog.component';
+
+describe('DialogComponent', () => {
+  let component: DialogComponent;
+  let fixture: ComponentFixture<DialogComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ DialogComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(DialogComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/shared/dialog/dialog.component.ts b/src/app/pages/shared/dialog/dialog.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fc2a0c140c6a34a09fd5f6c17fd18189d4e214fb
--- /dev/null
+++ b/src/app/pages/shared/dialog/dialog.component.ts
@@ -0,0 +1,25 @@
+import { Component, OnInit } from '@angular/core';
+import { NbDialogRef } from '@nebular/theme';
+
+@Component({
+  selector: 'ngx-dialog',
+  templateUrl: './dialog.component.html',
+  styleUrls: ['./dialog.component.scss']
+})
+export class DialogComponent implements OnInit {
+
+
+  constructor(protected dialogRef: NbDialogRef<DialogComponent>) { }
+
+  title: string;
+  message: string;
+
+  ngOnInit(): void {
+  }
+
+  close(answer){
+    this.dialogRef.close(answer);
+  }
+
+
+}
diff --git a/src/app/pages/shared/shared.module.ts b/src/app/pages/shared/shared.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b6087c9ed4e966a22e610844f8046a4ef430b157
--- /dev/null
+++ b/src/app/pages/shared/shared.module.ts
@@ -0,0 +1,53 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { TableActionsComponent } from '../shared/table-actions/table-actions.component';
+import { NbAccordionModule, NbActionsModule, NbAutocompleteModule, NbBadgeModule, NbButtonModule, NbCardModule, NbChatModule, NbCheckboxModule, NbDialogModule, NbFormFieldModule, NbIconModule, NbInputModule, NbListModule, NbSelectModule, NbSpinnerModule, NbTabsetModule, NbTimepickerModule, NbTooltipModule, NbTreeGridModule } from '@nebular/theme';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { NgxPaginationModule } from 'ngx-pagination';
+import { Ng2SmartTableModule } from 'ng2-smart-table';
+import { LeafletModule } from '@asymmetrik/ngx-leaflet';
+import { DialogComponent } from './dialog/dialog.component';
+import { TranslateModule } from '@ngx-translate/core';
+
+
+
+@NgModule({
+  declarations: [
+    TableActionsComponent,
+    DialogComponent,
+  ],
+  imports: [
+    CommonModule,
+    NbCardModule,
+    FormsModule,
+    NbFormFieldModule,
+    NbButtonModule,
+    NbInputModule,
+    NbListModule,
+    NgxPaginationModule,
+    NbActionsModule,
+    NbIconModule,
+    NbSpinnerModule,
+    NbTooltipModule,
+    NbAccordionModule,
+    NbButtonModule,
+    NbTabsetModule,
+    NbDialogModule.forChild(),
+    NbTreeGridModule,
+    Ng2SmartTableModule,
+    NbSelectModule,
+    NbAutocompleteModule,
+    ReactiveFormsModule,
+    NbTimepickerModule,
+    //SharedRoutingModule,
+    NbInputModule,
+    NbCheckboxModule,
+    NbChatModule,
+    LeafletModule,
+    NbBadgeModule,
+    TranslateModule
+  ],
+  exports: [DialogComponent],
+  entryComponents:[TableActionsComponent]
+})
+export class SharedModule { }
diff --git a/src/app/pages/shared/table-actions/table-actions.component.html b/src/app/pages/shared/table-actions/table-actions.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..63b45aca6a2ca43797543ede8297a8e93bd90a27
--- /dev/null
+++ b/src/app/pages/shared/table-actions/table-actions.component.html
@@ -0,0 +1,6 @@
+<div class="d-flex flex-row justify-content-around">
+    <button *ngFor="let action of actions" nbButton ghost [status]="action.status" (click)="onCustomClicked(action.action)" [disabled]="!action.enabled">
+        <nb-icon [icon]="action.icon" [nbTooltip]="action.tooltip"></nb-icon>
+        <nb-badge *ngIf="action.badge!=undefined && action.badge" text="+1" status="success" position="bottom"></nb-badge>
+    </button>
+</div>
diff --git a/src/app/pages/shared/table-actions/table-actions.component.scss b/src/app/pages/shared/table-actions/table-actions.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/pages/shared/table-actions/table-actions.component.spec.ts b/src/app/pages/shared/table-actions/table-actions.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b3ee9860db713c6385a12509a59ddda5a68f4f38
--- /dev/null
+++ b/src/app/pages/shared/table-actions/table-actions.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TableActionsComponent } from './table-actions.component';
+
+describe('TableActionsComponent', () => {
+  let component: TableActionsComponent;
+  let fixture: ComponentFixture<TableActionsComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ TableActionsComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(TableActionsComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/pages/shared/table-actions/table-actions.component.ts b/src/app/pages/shared/table-actions/table-actions.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..619a3ca4b53f6884712ed6b7a763d59bc910068a
--- /dev/null
+++ b/src/app/pages/shared/table-actions/table-actions.component.ts
@@ -0,0 +1,34 @@
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+
+interface Action{
+  action:string;
+  enabled:boolean;
+  status:string;
+  icon:string;
+  tooltip:string;
+}
+
+@Component({
+  selector: 'ngx-table-actions',
+  templateUrl: './table-actions.component.html',
+  styleUrls: ['./table-actions.component.scss']
+})
+export class TableActionsComponent implements OnInit {
+
+  constructor() { }
+
+  @Input() value;
+
+  @Output() onCustom = new EventEmitter<string>();
+
+  actions:Array<Action>;
+
+  ngOnInit(): void {
+    this.actions=this.value;
+  }
+
+  onCustomClicked(val){
+    this.onCustom.emit(val);
+  }
+
+}
diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json
new file mode 100644
index 0000000000000000000000000000000000000000..1d44c90669bf4008dae7d688029f5b08ca034b68
--- /dev/null
+++ b/src/assets/i18n/es.json
@@ -0,0 +1,241 @@
+{
+    "homepage": {
+        "homepage": "Homepage",
+        "welcome": "Welcome "
+    },
+    "general": {
+        "success": "Success",
+        "error": "Error",
+        "warning": "Warning",
+        "copy": "Copy",
+        "manage": "Manage",
+        "add": "Add",
+        "save": "Save",
+        "back": "Back",
+        "edit": "Edit",
+        "drag": "Drag",
+        "cancel": "Cancel",
+        "delete": "Delete",
+        "created": "created",
+        "updated": "updated",
+        "reset": "Ripristina",
+        "actions": "Actions",
+        "close": "Close",
+        "username": "Username",
+        "log_in": "Login",
+        "log_out": "Logout",
+        "page": "Page",
+        "dashboard": "Dashboard",
+        "component": "Component",
+        "menu_items": "Menu Items",
+        "menu_blocks": "Menu Blocks",
+        "targets": "Targets",
+        "manage_targets": "Manage Targets",
+        "editContent":"Edit Content",
+        "deleteConfirm": "Do you want delete the selected item?",
+        "yes": "Yes",
+        "no": "No",
+        "mandatory_field": "Mandatory field",
+        "catch_error": "Error loading the results, please try again.",
+        "operation_failed": "Operation failed",
+        "datacatalogue_error": "Error in retrieving data from Data Catalogue. Please contact admin"
+    },
+    "dashboardPage":{
+        "title": "Manage Dashboard Pages",
+        "created": "A new Dashboard Page has been sucessfully created",
+        "updated": "The Dashboard Page has been sucessfully updated",
+        "deleted": "The Dashboard Page has been sucessfully deleted",
+        "succesfully_cloned": "The Dashboard Page has been sucessfully cloned",
+        "notFound": "No Dashboard Pages found",
+        "createLabel": "Create a new Dashboard Page",
+        "createOrEditLabel": "Create or edit a Dashboard Page",
+        "id": "ID",
+        "name": "Name",
+        "description": "Description",
+        "content": "Content",
+        "note": "Note",
+        "shared": "Published",
+        "createdDate": "Created Date",
+        "createdBy": "Created By",
+        "dashboardComponent": "Dashboard Component",
+        "menuItem": "Menu Item",
+        "target": "Target",
+        "margin": "Margin",
+        "drag_items": "Drag items",
+        "outer_margin": "Outer Margin",
+        "push_items": "Push Items",
+        "disable_push_on_drag": "Disable Push On Drag",
+        "swap_items": "Swap Items",
+        "shared_info": "Field to enable(true) or disable(false) the Dashboard publishing.",
+        "margin_description": "Spacing between the components",
+        "outer_margin_description": "Spacing around the components",
+        "push_items_description": "Push items when resizing and dragging",
+        "disable_push_on_drag_description": "Disable push on drag",
+        "swap_items_description": "Swap items when dragging",
+        "not_mandatory_field": "This field in only for SHARED Dashboard",
+        "checkbox_label":"Flags",
+        "margin_label":"Margin",
+        "back_modal": "Are you sure you want to go back without saving the dashboard?",
+        "catch_error": "Error loading the dashboard page, please try again.",
+        "wait_for_components": "Please wait for components to load.",
+        "visualization_catch_error": "Error in Dashboard page content during visualization. Please contact admin o try again."
+    },
+    "dashboardComponent": {
+        "list": "Dashboard Components",
+        "title": "Dashboard Component",
+        "id": "ID",
+        "componentType": "Component Type",
+        "componentName": "Component Name",
+        "componentcontent": "Componentcontent",
+        "componentPosition": "Component Position",
+        "choose_file": "Choose file",
+        "createdDate": "Created Date",
+        "createdBy": "Created By",
+        "dashboardPage": "Dashboard Page",
+        "properties":"Component properties",
+        "selectComponentType":"Select a component type",
+        "deleteConfirm":"Are you sure to delete component?",
+        "fill_text": "Enter text...",
+        "fill_image": "Paste image url or base 64 image string...",
+        "fill_chart": "Select datalet...",
+        "fill_iframe": "Enter iframe content...",
+        "fill_map": "Enter GeoJson URL of the map...",
+        "fill_map_title": "Enter Title",
+        "fill_weather_title": "Enter Title",
+        "fill_weather_subtitle": "Enter Subtitle",
+        "fill_statistics_title": "Enter Title",
+        "fill_statistics_subtitle": "Enter Subtitle",
+        "fill_statistics_value": "Enter Value",
+        "fill_statistics_icon": "Enter Icon",
+        "select_datalet": "Select a datalet...",
+        "select_aspect_ratio": "Select aspect ratio",
+        "example_map_url": "http://localhost:4200/assets/map/2020-March-heatgeo-5minutes.json",
+        "label_geoJsonurl": "GeoJSON URL",
+        "label_title": "Title",
+        "label_subtitle": "Subtitle",
+        "label_value": "Value",
+        "label_icon": "Icon",
+        "label_content": "Content",
+        "label_datalet": "Datalet",
+        "label_image_url": "Image URL",
+        "label_upload_image": "Upload Image",
+        "upload_from_file": "Upload from file",
+        "upload_from_url/base64": "Upload from url/base64",
+        "catch_error": "Error loading the dashboard component, please try again."
+    },
+    "target": {
+        "list": "Targets",
+        "title": "Target",
+        "notFound": "No Targets found",
+        "createLabel": "Create a new Target",
+        "createOrEditLabel": "Create or edit a Target",
+        "created": "Target has been succesfully created",
+        "updated": "Target has been succesfully updated",
+        "deleted": "Target has been succesfully deleted",
+        "deleteConfirm": "Are you sure you want to delete Target ?",
+        "id": "ID",
+        "type": "Type",
+        "name": "Name",
+        "note": "Note",
+        "value": "Value",
+        "fill_person":"Select person first!",
+        "fill_group":"Select group first!",
+        "fill_role":"Select role first!",
+        "createdDate": "Created Date",
+        "createdBy": "Created By",
+        "dashboardPage": "Dashboard Page",
+        "select_person":"Select Available Person",
+        "select_group":"Select Available Group",
+        "select_role":"Select Available Role",
+        "add_button_info": "Select a Person and/or a Role to share with him the Dashboard",
+        "add_button_info_disabled": "Disabled Section. To enable 'Targets' the Dashboard have to be of type SHARED"
+    },
+    "menuBlock": {
+        "list": "Menu Blocks",
+        "title": "Menu Block",
+        "created": "Menu Block has been succesfully created",
+        "updated": "Menu Block has been succesfully updated",
+        "deleted": "Menu Block has been succesfully deleted",
+        "deleteConfirm": "Are you sure you want to delete Menu Block?",
+        "id": "ID",
+        "code": "Code",
+        "label": "Label",
+        "order": "Order",
+        "type": "Type",
+        "createdDate": "Created Date",
+        "createdBy": "Created By",
+        "menuItem": "Menu Item",
+        "select_menu_block":"Select a menu block",
+        "select_menu_block_info": "Selecting a SHARED block the Dashboard will be of type SHARED, otherwise the Dashboard will be of type PERSONAL.",
+        "shared": "Shared",
+        "delete_fk_error": "Delete failed cause this menu block is linked to more menu items.",
+        "type_info": "SHARED is for sharing the menu and the dashboard linked, PERSONAL is only for private visibility (not sharing)."
+    },
+    "menuItem": {
+        "list": "Menu Items",
+        "title": "Menu Item",
+        "created": "Menu Item has been succesfully created",
+        "updated": "Menu Item has been succesfully updated",
+        "deleted": "Menu Item has been succesfully deleted",
+        "deleteConfirm": "Are you sure you want to delete Menu Item?",
+        "id": "ID",
+        "code": "Code",
+        "label": "Label",
+        "order": "Order",
+        "type": "Type",
+        "createdDate": "Created Date",
+        "createdBy": "Created By",
+        "dashboardPage": "Dashboard Page",
+        "menuBlock": "Menu Block",
+        "menu_item_label":"Menu Item label",
+        "add_menu_item_label": "Add the label of MenuItem",
+        "add_button_info": "Select a menu block and then write the menu item label to add a link to the Dashboard",
+        "copy_info": "Copy the Dashboard name into menu item label (to generate the link Name)"
+    },
+    "dashboardClone":{
+        "step_one": "First step",
+        "step_two": "Second step",
+        "step_three": "Third step",
+        "question_one": "Which Dashboard do you want to clone?",
+        "question_two": "Which Dashboard want to create?",
+        "question_three": "Do you want to proceed with cloning?",
+        "question_targets": "Do you want to clone targets?",
+        "action_clone": "Clone",
+        "action_prev": "Prev",
+        "action_next": "Next",
+        "action_preview": "Preview",
+        "clone_targets": "Clone the targets",
+        "summary_one": "Selected dashboard name:",
+        "summary_two": "Created dashboard name:",
+        "summary_three": "Created dashboard targets:",
+        "select_dashboard": "Select a dashboard",
+        "add_dashboard_name":"Dashboard name",
+        "info": "Click on the Preview button to visualize it",
+        "source_dashboard": "Source Dashboard",
+        "parameter_error": "Error: missing 1 or more parameters",
+        "cloned_dashboard_name": "Cloned Dashboard name",
+        "clone_missing_parameter": "Clone Missing Parameters"
+    },
+    "ComponentType": {
+        "null": "",
+        "TEXT": "TEXT",
+        "IMAGE": "IMAGE",
+        "CHART": "CHART",
+        "IFRAME": "IFRAME",
+        "STATISTICS": "SUMMARY",
+        "MAP": "MAP",
+        "WEATHER": "WEATHER EXAMPLE"
+      },
+    "MenuType": {
+        "null": "",
+        "SHARED": "SHARED",
+        "PERSONAL": "PERSONAL",
+        "OTHER": "EMPTY TYPE"
+    },
+    "TargetType": {
+        "null": "",
+        "PERSON": "PERSON",
+        "GROUP": "GROUP",
+        "ROLE": "ROLE"
+    }
+}
\ No newline at end of file
diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json
new file mode 100644
index 0000000000000000000000000000000000000000..5c1a48b0c5b4e6407662d70b4b04ed4e5943ad26
--- /dev/null
+++ b/src/assets/i18n/it.json
@@ -0,0 +1,241 @@
+{
+    "homepage": {
+        "homepage": "Pagina principale",
+        "welcome": "Benvenuto/a "
+    },
+    "general": {
+        "success": "Successo",
+        "error": "Errore",
+        "copy": "Copy",
+        "warning": "Warning",
+        "manage": "Manage",
+        "add": "Aggiungi",
+        "save": "Salva",
+        "back": "Indietro",
+        "edit": "Modifica",
+        "cancel": "Annulla",
+        "delete": "Elimina",
+        "drag": "Trascina",
+        "created": "creato",
+        "updated": "aggiornato",
+        "reset": "Ripristina",
+        "actions": "Azioni",
+        "close": "Chiudi",
+        "username": "Nome utente",
+        "log_in": "Accedi",
+        "log_out": "Esci",
+        "page": "Pagina",
+        "dashboard": "Dashboard",
+        "component": "Componente",
+        "menu_items": "Menu Items",
+        "menu_blocks": "Menu Blocks",
+        "targets": "Destinatari",
+        "manage_targets": "Gestione Destinatari",
+        "editContent":"Modifica Contenuto",
+        "deleteConfirm": "Sei sicuro di eliminare l'elemento?",
+        "yes": "Si",
+        "no": "No",
+        "mandatory_field": "Campo obbligatorio",
+        "catch_error": "Errore nel caricamento dei risultati, prego riprovare",
+        "operation_failed": "Operazione fallita.",
+        "datacatalogue_error": "Error in retrieving data from Data Catalogue. Please contact admin"
+    },
+    "dashboardPage":{
+        "title": "Gestisci Dashboards",
+        "created": "Nuova Dashboard creata con sucesso",
+        "updated": "Dashboard aggiornata con sucesso",
+        "succesfully_cloned": "Dashboard clonata con sucesso",
+        "deleted": "Dashboard eliminata con sucesso",
+        "notFound": "Dashboard non trovata",
+        "createLabel": "Crea una nuova Dashboard",
+        "createOrEditLabel": "Crea oppure modifica una Dashboard",
+        "id": "ID",
+        "name": "Nome",
+        "description": "Descrizione",
+        "content": "Contenuto",
+        "note": "Note",
+        "shared": "Pubblicata",
+        "createdDate": "Data di creazione",
+        "createdBy": "Creato da",
+        "dashboardComponent": "Componente della Dashboard",
+        "menuItem": "Menu Item",
+        "target": "Destinatari",
+        "margin": "Margine",
+        "drag_items": "Drag elementi",
+        "outer_margin": "Margine esterno",
+        "push_items": "Push elementi",
+        "disable_push_on_drag": "Disabilita Push On Drag",
+        "swap_items": "Swap elementi",
+        "shared_info": "Field to enable(true) or disable(false) the Dashboard publishing.",
+        "margin_description": "Spaziatura tra i componenti",
+        "outer_margin_description": "Spaziatura intorno ai componenti",
+        "push_items_description": "Spingi gli elementi durante il ridimensionamento e il trascinamento",
+        "disable_push_on_drag_description": "Disabilita la spinta al trascinamento",
+        "swap_items_description": "Scambia gli elementi durante il trascinamento",
+        "not_mandatory_field": "This field in only for SHARED Dashboard",
+        "checkbox_label":"Opzioni",
+        "margin_label":"Margini",
+        "back_modal": "Are you sure you want to go back without saving the dashboard?",
+        "catch_error": "Error loading the dashboard page, please try again.",
+        "wait_for_components": "Please wait for components to load.",
+        "visualization_catch_error": "Error in Dashboard page content during visualization. Please contact admin o try again."
+    },
+    "dashboardComponent": {
+        "list": "Dashboard Components",
+        "title": "Dashboard Component",
+        "id": "ID",
+        "componentType": "Component Type",
+        "componentName": "Component Name",
+        "componentcontent": "Componentcontent",
+        "componentPosition": "Component Position",
+        "choose_file": "Choose file",
+        "createdDate": "Created Date",
+        "createdBy": "Created By",
+        "dashboardPage": "Dashboard Page",
+        "properties":"Dettagli del componente",
+        "selectComponentType":"Seleziona un tipo di componente",
+        "deleteConfirm":"Sei sicuro di eliminare il componente?",
+        "fill_text": "Inserisci testo...",
+        "fill_image": "Inserisci immagine oppure la stringa in base 64...",
+        "fill_chart": "Seleziona datalet...",
+        "fill_iframe": "Inserisci iframe...",
+        "fill_map": "Inserisci URL del GeoJSON della mappa...",
+        "fill_map_title": "Inserisci Titolo",
+        "fill_weather_title": "Inserisci Titolo",
+        "fill_weather_subtitle": "Inserisci Sottotitolo",
+        "fill_statistics_title": "Inserisci Titolo",
+        "fill_statistics_subtitle": "Inserisci Sottotitolo",
+        "fill_statistics_value": "Inserisci Valore",
+        "fill_statistics_icon": "Seleziona icona",
+        "select_datalet": "Seleziona una datalet...",
+        "example_map_url": "http://localhost:4200/assets/map/2020-March-heatgeo-5minutes.json",
+        "select_aspect_ratio": "Select aspect ratio",
+        "label_geoJsonurl": "GeoJSON URL",
+        "label_title": "Titolo",
+        "label_subtitle": "Sottotitolo",
+        "label_value": "Valore",
+        "label_icon": "Icona",
+        "label_content": "Contenuto",
+        "label_datalet": "Datalet",
+        "label_image_url": "Image URL",
+        "label_upload_image": "Upload Image",
+        "upload_from_file": "Upload from file",
+        "upload_from_url/base64": "Upload from url/base64",
+        "catch_error": "Error loading the dashboard component, please try again."
+    },
+    "target": {
+        "list": "Destinatari",
+        "title": "Destinatario",
+        "notFound": "Nessun Destinatario",
+        "createLabel": "Crea nuovo Destinatario",
+        "createOrEditLabel": "Crea o modifica Destinatario",
+        "created": "Destinatario creato con successo",
+        "updated": "Destinatario aggiornato con successo",
+        "deleted": "Destinatario eliminato con successo",
+        "deleteConfirm": "Sei sicuro di volere eliminare il Destinatario ?",
+        "id": "ID",
+        "type": "Tipo",
+        "name": "Nome",
+        "note": "Note",
+        "value": "Value",
+        "fill_person":"Seleziona Persona prima del click!",
+        "fill_group":"Seleziona un gruppo prima del click!",
+        "fill_role":"Seleziona un ruolo prima del click!",
+        "createdDate": "Data di creazione",
+        "createdBy": "Creato da",
+        "dashboardPage": "Dashboard",
+        "select_person":"Seleziona Persona",
+        "select_group":"Seleziona Gruppo",
+        "select_role":"Seleziona Ruolo",
+        "add_button_info": "Seleziona una Persona e/o un Ruolo per condividere la Dashboard",
+        "add_button_info_disabled": "Sezione disabilitata. Per abilitare la sezione la Dashboard deve essere di tipo SHARED"
+    },
+    "menuBlock": {
+        "list": "Menu Blocks",
+        "title": "Menu Block",
+        "created": "Menu Block has been succesfully created",
+        "updated": "Menu Block has been succesfully updated",
+        "deleted": "Menu Block has been succesfully deleted",
+        "deleteConfirm": "Are you sure you want to delete Menu Block?",
+        "id": "ID",
+        "code": "Codice",
+        "label": "Etichetta",
+        "order": "Ordine",
+        "type": "Tipo",
+        "createdDate": "Data di creazione",
+        "createdBy": "Creato da",
+        "menuItem": "Menu Item",
+        "select_menu_block":"Seleziona un menu block",
+        "select_menu_block_info": "Selecting a SHARED block the Dashboard will be of type SHARED, otherwise the Dashboard will be of type PERSONAL.",
+        "shared": "Condiviso",
+        "delete_fk_error": "Eliminazione fallita poichè il menu block è collegato a più voci di menù.",
+        "type_info": "SHARED is for sharing the menu and the dashboard linked, PERSONAL is only for private visibility (not sharing)."
+    },
+    "menuItem": {
+        "list": "Menu Items",
+        "title": "Menu Item",
+        "created": "Menu Item has been succesfully created",
+        "updated": "Menu Item has been succesfully updated",
+        "deleted": "Menu Item has been succesfully deleted",
+        "deleteConfirm": "Are you sure you want to delete Menu Item?",
+        "id": "ID",
+        "code": "Code",
+        "label": "Label",
+        "order": "Order",
+        "type": "Type",
+        "createdDate": "Created Date",
+        "createdBy": "Created By",
+        "dashboardPage": "Dashboard Page",
+        "menuBlock": "Menu Block",
+        "menu_item_label":"Menu Item label",
+        "add_menu_item_label": "Add the label of MenuItem",
+        "add_button_info": "Select a menu block and then write the menu item label to add a link to the Dashboard",
+        "copy_info": "Copy the Dashboard name into menu item label (to generate the link Name)"
+    },
+    "dashboardClone":{
+        "step_one": "First step",
+        "step_two": "Second step",
+        "step_three": "Third step",
+        "question_one": "Which Dashboard do you want to clone?",
+        "question_two": "Which Dashboard want to create?",
+        "question_three": "Do you want to proceed with cloning?",
+        "question_targets": "Do you want to clone targets?",
+        "action_clone": "Clone",
+        "action_prev": "Prev",
+        "action_next": "Next",
+        "action_preview": "Preview",
+        "clone_targets": "Clone the targets",
+        "summary_one": "Selected dashboard name:",
+        "summary_two": "Created dashboard name:",
+        "summary_three": "Created dashboard targets:",
+        "select_dashboard": "Select a dashboard",
+        "add_dashboard_name":"Dashboard name",
+        "info": "Click on the Preview button to visualize it",
+        "source_dashboard": "Source Dashboard",
+        "parameter_error": "Error: missing 1 or more parameters",
+        "cloned_dashboard_name": "Cloned Dashboard name",
+        "clone_missing_parameter": "Clone Missing Parameters"
+    },
+    "ComponentType": {
+        "null": "",
+        "TEXT": "TESTO",
+        "IMAGE": "IMMAGINE",
+        "CHART": "GRAFICO",
+        "IFRAME": "IFRAME",
+        "STATISTICS": "SOMMARIO",
+        "MAP": "MAPPA",
+        "WEATHER": "WEATHER EXAMPLE"
+      },
+    "MenuType": {
+        "null": "",
+        "SHARED": "CONDIVISA",
+        "PERSONAL": "PERSONALE",
+        "OTHER": "EMPTY TYPE"
+    },
+    "TargetType": {
+        "null": "",
+        "PERSON": "PERSON",
+        "GROUP": "GROUP",
+        "ROLE": "ROLE"
+    }
+}
\ No newline at end of file
diff --git a/src/assets/images/browser-outline.png b/src/assets/images/browser-outline.png
new file mode 100644
index 0000000000000000000000000000000000000000..fc16168b533a053ec7758510ae65f72b53dd6217
Binary files /dev/null and b/src/assets/images/browser-outline.png differ
diff --git a/src/assets/images/checkmark-outline.png b/src/assets/images/checkmark-outline.png
new file mode 100644
index 0000000000000000000000000000000000000000..2f321adeb0748aad679bffd6ce22d77438fdece3
Binary files /dev/null and b/src/assets/images/checkmark-outline.png differ
diff --git a/src/assets/images/close-outline.png b/src/assets/images/close-outline.png
new file mode 100644
index 0000000000000000000000000000000000000000..a52c413421043b26a60f0a7e07c11fe74d608ad0
Binary files /dev/null and b/src/assets/images/close-outline.png differ
diff --git a/src/assets/images/edit-outline.png b/src/assets/images/edit-outline.png
new file mode 100644
index 0000000000000000000000000000000000000000..bfee63b4ca2cad6306a6c58c8f6af5731de665a5
Binary files /dev/null and b/src/assets/images/edit-outline.png differ
diff --git a/src/assets/images/urbanite-spinner.gif b/src/assets/images/urbanite-spinner.gif
new file mode 100644
index 0000000000000000000000000000000000000000..def5f9de57e2bc96cef100af6841e8d9e4cc3688
Binary files /dev/null and b/src/assets/images/urbanite-spinner.gif differ