diff --git a/.angular-cli.json b/.angular-cli.json
index f66c44f..b3f6b54 100644
--- a/.angular-cli.json
+++ b/.angular-cli.json
@@ -21,6 +21,7 @@
"styles": [
"../node_modules/bulma/css/bulma.css",
"../node_modules/font-awesome/css/font-awesome.css",
+ "../node_modules/ng-org-chart/styles.css",
"styles.scss"
],
"scripts": [],
diff --git a/package-lock.json b/package-lock.json
index d239cef..05ed780 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4999,6 +4999,11 @@
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
"dev": true
},
+ "ng-org-chart": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/ng-org-chart/-/ng-org-chart-1.2.0.tgz",
+ "integrity": "sha1-9xLMn3fdA2k0ESwjmgHDPhqGyYI="
+ },
"ng2-charts": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-1.6.0.tgz",
diff --git a/package.json b/package.json
index 4e498fd..eddf037 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,7 @@
"core-js": "^2.4.1",
"font-awesome": "^4.7.0",
"moment": "^2.18.1",
+ "ng-org-chart": "^1.2.0",
"ng2-charts": "^1.6.0",
"ng2-google-charts": "^3.0.1",
"rxjs": "^5.4.2",
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index c978e13..7425b5b 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -1,3 +1,4 @@
+import { OrganizationPageComponent } from './home-page/organization-page/organization-page.component';
import { NotFoundPageComponent } from './home-page/not-found-page/not-found-page.component';
import { CrudPageComponent } from './home-page/crud-page/crud-page.component';
import { MapsPageComponent } from './maps-page/maps-page.component';
@@ -52,6 +53,7 @@ const routes: Routes = [
path: 'fileupload', component: FileUploadPageComponent
},
{ path: 'crud', component: CrudPageComponent },
+ { path: 'organization', component: OrganizationPageComponent},
]
},
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index d3fe8ed..78d4070 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -31,6 +31,8 @@ import { GoogleChartPageComponent } from './home-page/chart-page/google-chart-pa
import { HighchartsPageComponent } from './home-page/chart-page/highcharts-page/highcharts-page.component';
import { Ng2GoogleChartsModule } from 'ng2-google-charts';
import { NotFoundPageComponent } from './home-page/not-found-page/not-found-page.component';
+import { OrgChartModule } from 'ng-org-chart';
+import { OrganizationPageComponent } from './home-page/organization-page/organization-page.component';
export function highchartsFactory() {
return highcharts;
@@ -57,7 +59,8 @@ export function highchartsFactory() {
GoogleChartPageComponent,
HighchartsPageComponent,
NotFoundPageComponent,
- FileUploadMasterPageComponent
+ FileUploadMasterPageComponent,
+ OrganizationPageComponent
],
imports: [
BrowserModule,
@@ -69,7 +72,8 @@ export function highchartsFactory() {
}),
ChartsModule,
Ng2GoogleChartsModule,
- ChartModule
+ ChartModule,
+ OrgChartModule
],
providers: [AuthGuard, AuthService, ChatService, {
provide: HighchartsStatic,
diff --git a/src/app/home-page/home-page.component.html b/src/app/home-page/home-page.component.html
index 437b015..9a17cc8 100644
--- a/src/app/home-page/home-page.component.html
+++ b/src/app/home-page/home-page.component.html
@@ -39,6 +39,9 @@
Crud Master
+
+ Organization
+
Sign Out
@@ -106,6 +109,11 @@
Crud Master
+
+
+ Organization
+
+
Sign Out
diff --git a/src/app/home-page/organization-page/organization-page.component.html b/src/app/home-page/organization-page/organization-page.component.html
new file mode 100644
index 0000000..8c388e5
--- /dev/null
+++ b/src/app/home-page/organization-page/organization-page.component.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/home-page/organization-page/organization-page.component.scss b/src/app/home-page/organization-page/organization-page.component.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/home-page/organization-page/organization-page.component.spec.ts b/src/app/home-page/organization-page/organization-page.component.spec.ts
new file mode 100644
index 0000000..8219ef9
--- /dev/null
+++ b/src/app/home-page/organization-page/organization-page.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { OrganizationPageComponent } from './organization-page.component';
+
+describe('OrganizationPageComponent', () => {
+ let component: OrganizationPageComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ OrganizationPageComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OrganizationPageComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should be created', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/home-page/organization-page/organization-page.component.ts b/src/app/home-page/organization-page/organization-page.component.ts
new file mode 100644
index 0000000..89c12c5
--- /dev/null
+++ b/src/app/home-page/organization-page/organization-page.component.ts
@@ -0,0 +1,64 @@
+import { EmployeeApi } from './../../../shared/services/custom/Employee';
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-organization-page',
+ templateUrl: './organization-page.component.html',
+ styleUrls: ['./organization-page.component.scss']
+})
+export class OrganizationPageComponent implements OnInit {
+
+ topEmployee: any = {
+ name: 'No Data',
+ designation: '',
+ subordinates: []
+ };
+ dataEmployee: any = [];
+
+ constructor(
+ public employeeApi: EmployeeApi
+ ) { }
+
+ ngOnInit() {
+ this.loadData();
+ }
+
+ loadData() {
+ this.employeeApi.find({
+ order: 'parentid DESC',
+ include: 'employeeposition',
+ }).subscribe(result => {
+ if (result.length !== 0) {
+ for (const data of result) {
+ this.dataEmployee.push({
+ id: data['id'],
+ name: data['name'],
+ designation: data['employeeposition']['name'],
+ subordinates: []
+ });
+ }
+
+ result.forEach((data, index) => {
+ if (data['parentid'] !== 'null') {
+ const temp = this.dataEmployee[index];
+ // Search parent by parentid
+ result.forEach((cek, indexcek) => {
+ if (data['parentid'] === cek['id']) {
+ this.dataEmployee[indexcek]['subordinates'].push(temp);
+ this.dataEmployee[indexcek]['subordinates']
+ .sort((a: any, b: any) => {
+ if (a.id < b.id) { return -1;
+ } else if (a.id > b.id) { return 1;
+ } else { return 0; }
+ }
+ );
+ delete this.dataEmployee[index];
+ }
+ });
+ }
+ });
+ this.topEmployee = this.dataEmployee.filter(item => item !== null)[0];
+ }
+ });
+ }
+}
diff --git a/src/shared/index.ts b/src/shared/index.ts
index ebef823..6167315 100644
--- a/src/shared/index.ts
+++ b/src/shared/index.ts
@@ -59,6 +59,8 @@ import { ChatdetailApi } from './services/custom/Chatdetail';
import { StorageUploadApi } from './services/custom/StorageUpload';
import { MapApi } from './services/custom/Map';
import { ProfiledataApi } from './services/custom/Profiledata';
+import { EmployeepositionApi } from './services/custom/Employeeposition';
+import { EmployeeApi } from './services/custom/Employee';
/**
* @module SDKBrowserModule
* @description
@@ -101,6 +103,8 @@ export class SDKBrowserModule {
StorageUploadApi,
MapApi,
ProfiledataApi,
+ EmployeepositionApi,
+ EmployeeApi,
internalStorageProvider,
{ provide: SDKStorage, useClass: StorageBrowser },
{ provide: SocketDriver, useClass: SocketBrowser }
diff --git a/src/shared/models/Employee.ts b/src/shared/models/Employee.ts
new file mode 100644
index 0000000..cd99f24
--- /dev/null
+++ b/src/shared/models/Employee.ts
@@ -0,0 +1,79 @@
+/* tslint:disable */
+import {
+ Employeeposition
+} from '../index';
+
+declare var Object: any;
+export interface EmployeeInterface {
+ "parentid"?: number;
+ "id"?: number;
+ "name": string;
+ "employeepositionId": number;
+ employeeposition?: Employeeposition;
+}
+
+export class Employee implements EmployeeInterface {
+ "parentid": number;
+ "id": number;
+ "name": string;
+ "employeepositionId": number;
+ employeeposition: Employeeposition;
+ constructor(data?: EmployeeInterface) {
+ Object.assign(this, data);
+ }
+ /**
+ * The name of the model represented by this $resource,
+ * i.e. `Employee`.
+ */
+ public static getModelName() {
+ return "Employee";
+ }
+ /**
+ * @method factory
+ * @author Jonathan Casarrubias
+ * @license MIT
+ * This method creates an instance of Employee for dynamic purposes.
+ **/
+ public static factory(data: EmployeeInterface): Employee{
+ return new Employee(data);
+ }
+ /**
+ * @method getModelDefinition
+ * @author Julien Ledun
+ * @license MIT
+ * This method returns an object that represents some of the model
+ * definitions.
+ **/
+ public static getModelDefinition() {
+ return {
+ name: 'Employee',
+ plural: 'Employees',
+ path: 'Employees',
+ properties: {
+ "parentid": {
+ name: 'parentid',
+ type: 'number'
+ },
+ "id": {
+ name: 'id',
+ type: 'number'
+ },
+ "name": {
+ name: 'name',
+ type: 'string'
+ },
+ "employeepositionId": {
+ name: 'employeepositionId',
+ type: 'number'
+ },
+ },
+ relations: {
+ employeeposition: {
+ name: 'employeeposition',
+ type: 'Employeeposition',
+ model: 'Employeeposition'
+ },
+ }
+ }
+ }
+}
diff --git a/src/shared/models/Employeeposition.ts b/src/shared/models/Employeeposition.ts
new file mode 100644
index 0000000..6e03cc6
--- /dev/null
+++ b/src/shared/models/Employeeposition.ts
@@ -0,0 +1,57 @@
+/* tslint:disable */
+
+declare var Object: any;
+export interface EmployeepositionInterface {
+ "name": string;
+ "id"?: number;
+}
+
+export class Employeeposition implements EmployeepositionInterface {
+ "name": string;
+ "id": number;
+ constructor(data?: EmployeepositionInterface) {
+ Object.assign(this, data);
+ }
+ /**
+ * The name of the model represented by this $resource,
+ * i.e. `Employeeposition`.
+ */
+ public static getModelName() {
+ return "Employeeposition";
+ }
+ /**
+ * @method factory
+ * @author Jonathan Casarrubias
+ * @license MIT
+ * This method creates an instance of Employeeposition for dynamic purposes.
+ **/
+ public static factory(data: EmployeepositionInterface): Employeeposition{
+ return new Employeeposition(data);
+ }
+ /**
+ * @method getModelDefinition
+ * @author Julien Ledun
+ * @license MIT
+ * This method returns an object that represents some of the model
+ * definitions.
+ **/
+ public static getModelDefinition() {
+ return {
+ name: 'Employeeposition',
+ plural: 'Employeepositions',
+ path: 'Employeepositions',
+ properties: {
+ "name": {
+ name: 'name',
+ type: 'string'
+ },
+ "id": {
+ name: 'id',
+ type: 'number'
+ },
+ },
+ relations: {
+ }
+ }
+ }
+}
diff --git a/src/shared/models/index.ts b/src/shared/models/index.ts
index d74f933..53a0e71 100644
--- a/src/shared/models/index.ts
+++ b/src/shared/models/index.ts
@@ -10,5 +10,7 @@ export * from './Chatdetail';
export * from './StorageUpload';
export * from './Map';
export * from './Profiledata';
+export * from './Employeeposition';
+export * from './Employee';
export * from './BaseModels';
export * from './FireLoopRef';
diff --git a/src/shared/services/custom/Employee.ts b/src/shared/services/custom/Employee.ts
new file mode 100644
index 0000000..39cc706
--- /dev/null
+++ b/src/shared/services/custom/Employee.ts
@@ -0,0 +1,134 @@
+/* tslint:disable */
+import { Injectable, Inject, Optional } from '@angular/core';
+import { Http, Response } from '@angular/http';
+import { SDKModels } from './SDKModels';
+import { BaseLoopBackApi } from '../core/base.service';
+import { LoopBackConfig } from '../../lb.config';
+import { LoopBackAuth } from '../core/auth.service';
+import { LoopBackFilter, } from '../../models/BaseModels';
+import { JSONSearchParams } from '../core/search.params';
+import { ErrorHandler } from '../core/error.service';
+import { Subject } from 'rxjs/Subject';
+import { Observable } from 'rxjs/Rx';
+import { Employee } from '../../models/Employee';
+import { SocketConnection } from '../../sockets/socket.connections';
+import { Employeeposition } from '../../models/Employeeposition';
+
+
+/**
+ * Api services for the `Employee` model.
+ */
+@Injectable()
+export class EmployeeApi extends BaseLoopBackApi {
+
+ constructor(
+ @Inject(Http) protected http: Http,
+ @Inject(SocketConnection) protected connection: SocketConnection,
+ @Inject(SDKModels) protected models: SDKModels,
+ @Inject(LoopBackAuth) protected auth: LoopBackAuth,
+ @Inject(JSONSearchParams) protected searchParams: JSONSearchParams,
+ @Optional() @Inject(ErrorHandler) protected errorHandler: ErrorHandler
+ ) {
+ super(http, connection, models, auth, searchParams, errorHandler);
+ }
+
+ /**
+ * Fetches belongsTo relation employeeposition.
+ *
+ * @param {any} id Employee id
+ *
+ * @param {boolean} refresh
+ *
+ * @returns {object} An empty reference that will be
+ * populated with the actual data once the response is returned
+ * from the server.
+ *
+ *
+ * (The remote method definition does not provide any description.
+ * This usually means the response is a `Employee` object.)
+ *
+ */
+ public getEmployeeposition(id: any, refresh: any = {}, customHeaders?: Function): Observable {
+ let _method: string = "GET";
+ let _url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() +
+ "/Employees/:id/employeeposition";
+ let _routeParams: any = {
+ id: id
+ };
+ let _postBody: any = {};
+ let _urlParams: any = {};
+ if (typeof refresh !== 'undefined' && refresh !== null) _urlParams.refresh = refresh;
+ let result = this.request(_method, _url, _routeParams, _urlParams, _postBody, null, customHeaders);
+ return result;
+ }
+
+ /**
+ * Patch an existing model instance or insert a new one into the data source.
+ *
+ * @param {object} data Request data.
+ *
+ * - `data` – `{object}` - Model instance data
+ *
+ * @returns {object} An empty reference that will be
+ * populated with the actual data once the response is returned
+ * from the server.
+ *
+ *
+ * (The remote method definition does not provide any description.
+ * This usually means the response is a `Employee` object.)
+ *
+ */
+ public patchOrCreate(data: any = {}, customHeaders?: Function): Observable {
+ let _method: string = "PATCH";
+ let _url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() +
+ "/Employees";
+ let _routeParams: any = {};
+ let _postBody: any = {
+ data: data
+ };
+ let _urlParams: any = {};
+ let result = this.request(_method, _url, _routeParams, _urlParams, _postBody, null, customHeaders);
+ return result;
+ }
+
+ /**
+ * Patch attributes for a model instance and persist it into the data source.
+ *
+ * @param {any} id Employee id
+ *
+ * @param {object} data Request data.
+ *
+ * - `data` – `{object}` - An object of model property name/value pairs
+ *
+ * @returns {object} An empty reference that will be
+ * populated with the actual data once the response is returned
+ * from the server.
+ *
+ *
+ * (The remote method definition does not provide any description.
+ * This usually means the response is a `Employee` object.)
+ *
+ */
+ public patchAttributes(id: any, data: any = {}, customHeaders?: Function): Observable {
+ let _method: string = "PATCH";
+ let _url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() +
+ "/Employees/:id";
+ let _routeParams: any = {
+ id: id
+ };
+ let _postBody: any = {
+ data: data
+ };
+ let _urlParams: any = {};
+ let result = this.request(_method, _url, _routeParams, _urlParams, _postBody, null, customHeaders);
+ return result;
+ }
+
+ /**
+ * The name of the model represented by this $resource,
+ * i.e. `Employee`.
+ */
+ public getModelName() {
+ return "Employee";
+ }
+}
diff --git a/src/shared/services/custom/Employeeposition.ts b/src/shared/services/custom/Employeeposition.ts
new file mode 100644
index 0000000..34f00f0
--- /dev/null
+++ b/src/shared/services/custom/Employeeposition.ts
@@ -0,0 +1,103 @@
+/* tslint:disable */
+import { Injectable, Inject, Optional } from '@angular/core';
+import { Http, Response } from '@angular/http';
+import { SDKModels } from './SDKModels';
+import { BaseLoopBackApi } from '../core/base.service';
+import { LoopBackConfig } from '../../lb.config';
+import { LoopBackAuth } from '../core/auth.service';
+import { LoopBackFilter, } from '../../models/BaseModels';
+import { JSONSearchParams } from '../core/search.params';
+import { ErrorHandler } from '../core/error.service';
+import { Subject } from 'rxjs/Subject';
+import { Observable } from 'rxjs/Rx';
+import { Employeeposition } from '../../models/Employeeposition';
+import { SocketConnection } from '../../sockets/socket.connections';
+
+
+/**
+ * Api services for the `Employeeposition` model.
+ */
+@Injectable()
+export class EmployeepositionApi extends BaseLoopBackApi {
+
+ constructor(
+ @Inject(Http) protected http: Http,
+ @Inject(SocketConnection) protected connection: SocketConnection,
+ @Inject(SDKModels) protected models: SDKModels,
+ @Inject(LoopBackAuth) protected auth: LoopBackAuth,
+ @Inject(JSONSearchParams) protected searchParams: JSONSearchParams,
+ @Optional() @Inject(ErrorHandler) protected errorHandler: ErrorHandler
+ ) {
+ super(http, connection, models, auth, searchParams, errorHandler);
+ }
+
+ /**
+ * Patch an existing model instance or insert a new one into the data source.
+ *
+ * @param {object} data Request data.
+ *
+ * - `data` – `{object}` - Model instance data
+ *
+ * @returns {object} An empty reference that will be
+ * populated with the actual data once the response is returned
+ * from the server.
+ *
+ *
+ * (The remote method definition does not provide any description.
+ * This usually means the response is a `Employeeposition` object.)
+ *
+ */
+ public patchOrCreate(data: any = {}, customHeaders?: Function): Observable {
+ let _method: string = "PATCH";
+ let _url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() +
+ "/Employeepositions";
+ let _routeParams: any = {};
+ let _postBody: any = {
+ data: data
+ };
+ let _urlParams: any = {};
+ let result = this.request(_method, _url, _routeParams, _urlParams, _postBody, null, customHeaders);
+ return result;
+ }
+
+ /**
+ * Patch attributes for a model instance and persist it into the data source.
+ *
+ * @param {any} id Employeeposition id
+ *
+ * @param {object} data Request data.
+ *
+ * - `data` – `{object}` - An object of model property name/value pairs
+ *
+ * @returns {object} An empty reference that will be
+ * populated with the actual data once the response is returned
+ * from the server.
+ *
+ *
+ * (The remote method definition does not provide any description.
+ * This usually means the response is a `Employeeposition` object.)
+ *
+ */
+ public patchAttributes(id: any, data: any = {}, customHeaders?: Function): Observable {
+ let _method: string = "PATCH";
+ let _url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() +
+ "/Employeepositions/:id";
+ let _routeParams: any = {
+ id: id
+ };
+ let _postBody: any = {
+ data: data
+ };
+ let _urlParams: any = {};
+ let result = this.request(_method, _url, _routeParams, _urlParams, _postBody, null, customHeaders);
+ return result;
+ }
+
+ /**
+ * The name of the model represented by this $resource,
+ * i.e. `Employeeposition`.
+ */
+ public getModelName() {
+ return "Employeeposition";
+ }
+}
diff --git a/src/shared/services/custom/SDKModels.ts b/src/shared/services/custom/SDKModels.ts
index 68dd8b9..b2ab1cc 100644
--- a/src/shared/services/custom/SDKModels.ts
+++ b/src/shared/services/custom/SDKModels.ts
@@ -11,6 +11,8 @@ import { Chatdetail } from '../../models/Chatdetail';
import { StorageUpload } from '../../models/StorageUpload';
import { Map } from '../../models/Map';
import { Profiledata } from '../../models/Profiledata';
+import { Employeeposition } from '../../models/Employeeposition';
+import { Employee } from '../../models/Employee';
export interface Models { [name: string]: any }
@@ -29,6 +31,8 @@ export class SDKModels {
StorageUpload: StorageUpload,
Map: Map,
Profiledata: Profiledata,
+ Employeeposition: Employeeposition,
+ Employee: Employee,
};
diff --git a/src/shared/services/custom/index.ts b/src/shared/services/custom/index.ts
index 567725d..b179ab2 100644
--- a/src/shared/services/custom/index.ts
+++ b/src/shared/services/custom/index.ts
@@ -10,5 +10,7 @@ export * from './Chatdetail';
export * from './StorageUpload';
export * from './Map';
export * from './Profiledata';
+export * from './Employeeposition';
+export * from './Employee';
export * from './SDKModels';
export * from './logger.service';
diff --git a/src/styles.scss b/src/styles.scss
index 94450f6..90d268f 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -2,3 +2,22 @@
html{
overflow: auto;
}
+
+.oc-border {
+ border: 1px solid black;
+}
+
+.oc-background {
+ background-color: cornflowerblue;
+}
+
+.oc-name {
+ font-family: Times New Roman;
+ white-space: nowrap;
+}
+
+.oc-designation {
+ font-family: Trebuchet;
+ font-style: italic;
+ white-space: nowrap;
+}
\ No newline at end of file