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