diff --git a/package-lock.json b/package-lock.json index 8277a9f..70f5af1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "@fullcalendar/interaction": "4.4.2", "@fullcalendar/list": "4.4.2", "@fullcalendar/timegrid": "4.4.2", - "@microsoft/signalr": "5.0.8", + "@microsoft/signalr": "^5.0.9", "@ng-bootstrap/ng-bootstrap": "10.0.0", "@ng-select/ng-select": "7.4.0", "@ngrx/effects": "12.4.0", @@ -37,7 +37,7 @@ "@ngrx/store-devtools": "12.4.0", "@ngx-translate/core": "13.0.0", "@ngx-translate/http-loader": "6.0.0", - "@resgrid/ngx-resgridlib": "1.0.7", + "@resgrid/ngx-resgridlib": "^1.1.13", "@sentry/angular": "6.16.1", "@sentry/tracing": "6.16.1", "@types/jquery": "3.5.6", @@ -54,6 +54,7 @@ "jquery": "3.5.0", "jquery-ui-sortable": "1.0.0", "jssip": "3.8.0", + "jwt-decode": "^3.1.2", "leaflet": "1.7.1", "lodash": "4.17.21", "metismenujs": "1.2.0", @@ -79,8 +80,6 @@ "replace-in-file": "6.2.0", "rxjs": "6.5.4", "sweetalert2": "9.15.1", - "tsgeo": "1.2.2", - "tslib": "2.2.0", "zone.js": "0.11.4" }, "devDependencies": { @@ -104,10 +103,30 @@ "karma-jasmine-html-reporter": "^1.5.0", "protractor": "^7.0.0", "ts-node": "~8.3.0", + "tslib": "^2.4.0", "tslint": "~6.1.3", "typescript": "~4.3.5" } }, + "../NgxResgridLib/dist/ngx-resgridlib": { + "name": "@resgrid/ngx-resgridlib", + "version": "0.0.0-development", + "extraneous": true, + "license": "Apache-2.0", + "dependencies": { + "@microsoft/signalr": "^5.0.9", + "jwt-decode": "^3.1.2", + "leaflet": "^1.7.1", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/common": "^12.0.0 || ^13.0.0", + "@angular/core": "^12.0.0 || ^13.0.0", + "@angular/platform-browser": "^12.0.0 || ^13.0.0", + "@angular/platform-browser-dynamic": "^12.0.0 || ^13.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, "node_modules/@ampproject/remapping": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-1.0.1.tgz", @@ -3249,9 +3268,9 @@ } }, "node_modules/@microsoft/signalr": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-5.0.8.tgz", - "integrity": "sha512-g5U7zGa1CeoPztA1VGLiB418sZ6gt8ZEOsX8krpegyMquzH2Qinny1zQjNsg3mgjGlJI+FXD5bO4gVsHGUp2hA==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-5.0.9.tgz", + "integrity": "sha512-pQufk3+mChfystnmYpglyRYQFp+036QmOxbZUFr2cFf2iiS8ekBX5uVBOG8OexKcsG4TcJNAU/ref90Y9+3ZiA==", "dependencies": { "abort-controller": "^3.0.0", "eventsource": "^1.0.7", @@ -3577,35 +3596,21 @@ "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" }, "node_modules/@resgrid/ngx-resgridlib": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@resgrid/ngx-resgridlib/-/ngx-resgridlib-1.0.7.tgz", - "integrity": "sha512-F601uVu5/SRuuUM5+J4V4kJKjEtg7tVzGoIVDgqJnsZifUOY9L03qJv2NpkyEuh5JjQKt9b/GPYe0a2IMHnUEA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@resgrid/ngx-resgridlib/-/ngx-resgridlib-1.1.13.tgz", + "integrity": "sha512-tRUDS71asX2p8xlaJ60XuI0SbKPuBVGhb8qZQPWLVJg+cvd8RBHJ6A6GgZqmG45xKzEqBVs+XFbQaVxynOXQcQ==", "dependencies": { "@microsoft/signalr": "^5.0.9", "jwt-decode": "^3.1.2", "leaflet": "^1.7.1", - "tsgeo": "^1.2.2", "tslib": "^2.0.0" }, "peerDependencies": { - "@angular/common": "^11.0.0 || ^12.0.0 || ^13.0.0", - "@angular/core": "^11.0.0 || ^12.0.0 || ^13.0.0", - "@microsoft/signalr": "^5.0.9", - "jwt-decode": "^3.1.2", - "leaflet": "^1.7.1", - "tsgeo": "^1.2.2" - } - }, - "node_modules/@resgrid/ngx-resgridlib/node_modules/@microsoft/signalr": { - "version": "5.0.14", - "resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-5.0.14.tgz", - "integrity": "sha512-TdATUaBcJu0UB4BmhHzJ/JeUMocKNg/P2/NlFvY6re8DNoINCsVjYDqWfW3mvXz16uFlIH1p8hdJlzt8caVdVA==", - "dependencies": { - "abort-controller": "^3.0.0", - "eventsource": "^1.0.7", - "fetch-cookie": "^0.7.3", - "node-fetch": "^2.6.0", - "ws": "^6.0.0" + "@angular/common": "^12.0.0 || ^13.0.0", + "@angular/core": "^12.0.0 || ^13.0.0", + "@angular/platform-browser": "^12.0.0 || ^13.0.0", + "@angular/platform-browser-dynamic": "^12.0.0 || ^13.0.0", + "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@schematics/angular": { @@ -11710,11 +11715,6 @@ "echarts": ">=5.0.0" } }, - "node_modules/ngx-echarts/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, "node_modules/ngx-mask": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/ngx-mask/-/ngx-mask-12.0.0.tgz", @@ -17702,15 +17702,10 @@ "typescript": ">=2.0" } }, - "node_modules/tsgeo": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tsgeo/-/tsgeo-1.2.2.tgz", - "integrity": "sha512-7xtyCMmE9miNQ+gQ158gycQMhM6nfBXTsO8ongZUFTAfA4BVZAwijfK2ed/g5d0thH+clMsrSpwRbo+FlvpkNg==" - }, "node_modules/tslib": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", - "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "node_modules/tslint": { "version": "6.1.3", @@ -21616,9 +21611,9 @@ } }, "@microsoft/signalr": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-5.0.8.tgz", - "integrity": "sha512-g5U7zGa1CeoPztA1VGLiB418sZ6gt8ZEOsX8krpegyMquzH2Qinny1zQjNsg3mgjGlJI+FXD5bO4gVsHGUp2hA==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-5.0.9.tgz", + "integrity": "sha512-pQufk3+mChfystnmYpglyRYQFp+036QmOxbZUFr2cFf2iiS8ekBX5uVBOG8OexKcsG4TcJNAU/ref90Y9+3ZiA==", "requires": { "abort-controller": "^3.0.0", "eventsource": "^1.0.7", @@ -21862,29 +21857,14 @@ "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" }, "@resgrid/ngx-resgridlib": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@resgrid/ngx-resgridlib/-/ngx-resgridlib-1.0.7.tgz", - "integrity": "sha512-F601uVu5/SRuuUM5+J4V4kJKjEtg7tVzGoIVDgqJnsZifUOY9L03qJv2NpkyEuh5JjQKt9b/GPYe0a2IMHnUEA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@resgrid/ngx-resgridlib/-/ngx-resgridlib-1.1.13.tgz", + "integrity": "sha512-tRUDS71asX2p8xlaJ60XuI0SbKPuBVGhb8qZQPWLVJg+cvd8RBHJ6A6GgZqmG45xKzEqBVs+XFbQaVxynOXQcQ==", "requires": { "@microsoft/signalr": "^5.0.9", "jwt-decode": "^3.1.2", "leaflet": "^1.7.1", - "tsgeo": "^1.2.2", "tslib": "^2.0.0" - }, - "dependencies": { - "@microsoft/signalr": { - "version": "5.0.14", - "resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-5.0.14.tgz", - "integrity": "sha512-TdATUaBcJu0UB4BmhHzJ/JeUMocKNg/P2/NlFvY6re8DNoINCsVjYDqWfW3mvXz16uFlIH1p8hdJlzt8caVdVA==", - "requires": { - "abort-controller": "^3.0.0", - "eventsource": "^1.0.7", - "fetch-cookie": "^0.7.3", - "node-fetch": "^2.6.0", - "ws": "^6.0.0" - } - } } }, "@schematics/angular": { @@ -28244,13 +28224,6 @@ "integrity": "sha512-CP+WnCcnMCNpCL9BVmDIZmhGSVPnkJhhFbQEKt0nrwV0L6d4QTAGZ+e4y6G1zTTFKkIMPHpaO0nhtDRgSXAW/w==", "requires": { "tslib": "^2.3.0" - }, - "dependencies": { - "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - } } }, "ngx-mask": { @@ -32766,15 +32739,10 @@ "yn": "^3.0.0" } }, - "tsgeo": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tsgeo/-/tsgeo-1.2.2.tgz", - "integrity": "sha512-7xtyCMmE9miNQ+gQ158gycQMhM6nfBXTsO8ongZUFTAfA4BVZAwijfK2ed/g5d0thH+clMsrSpwRbo+FlvpkNg==" - }, "tslib": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", - "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "tslint": { "version": "6.1.3", diff --git a/package.json b/package.json index c25254c..626925a 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@fullcalendar/interaction": "4.4.2", "@fullcalendar/list": "4.4.2", "@fullcalendar/timegrid": "4.4.2", - "@microsoft/signalr": "5.0.8", + "@microsoft/signalr": "^5.0.9", "@ng-bootstrap/ng-bootstrap": "10.0.0", "@ng-select/ng-select": "7.4.0", "@ngrx/effects": "12.4.0", @@ -43,7 +43,7 @@ "@ngrx/store-devtools": "12.4.0", "@ngx-translate/core": "13.0.0", "@ngx-translate/http-loader": "6.0.0", - "@resgrid/ngx-resgridlib": "1.0.7", + "@resgrid/ngx-resgridlib": "^1.1.13", "@sentry/angular": "6.16.1", "@sentry/tracing": "6.16.1", "@types/jquery": "3.5.6", @@ -60,6 +60,7 @@ "jquery": "3.5.0", "jquery-ui-sortable": "1.0.0", "jssip": "3.8.0", + "jwt-decode": "^3.1.2", "leaflet": "1.7.1", "lodash": "4.17.21", "metismenujs": "1.2.0", @@ -85,8 +86,6 @@ "replace-in-file": "6.2.0", "rxjs": "6.5.4", "sweetalert2": "9.15.1", - "tsgeo": "1.2.2", - "tslib": "2.2.0", "zone.js": "0.11.4" }, "devDependencies": { @@ -110,6 +109,7 @@ "karma-jasmine-html-reporter": "^1.5.0", "protractor": "^7.0.0", "ts-node": "~8.3.0", + "tslib": "^2.4.0", "tslint": "~6.1.3", "typescript": "~4.3.5" } diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index c857c60..a71cf78 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -33,6 +33,10 @@ const routes: Routes = [ { path: 'profile', loadChildren: () => import('./features/profile/profile.module').then(m => m.ProfileModule) + }, + { + path: 'mapping', + loadChildren: () => import('./features/mapping/mapping.module').then(m => m.MappingModule) } ]; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 05c4750..6110faf 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,17 +1,13 @@ import { BrowserModule } from '@angular/platform-browser'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { HttpClientModule, HTTP_INTERCEPTORS, HttpClient } from '@angular/common/http'; - -import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; - import { environment } from '../environments/environment'; - import { LayoutsModule } from './layouts/layouts.module'; import { NgxResgridLibModule } from '@resgrid/ngx-resgridlib'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; -import { NgxSpinnerModule } from "ngx-spinner"; +import { NgxSpinnerModule } from 'ngx-spinner'; import { StoreModule } from '@ngrx/store'; import { metaReducers, reducers } from './store/reducers'; import { EffectsModule } from '@ngrx/effects'; @@ -21,6 +17,8 @@ import { AuthModule } from './features/auth/auth.module'; import { LeafletModule } from '@asymmetrik/ngx-leaflet'; import { VoiceModule } from './features/voice/voice.module'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { MappingModule } from './features/mapping/mapping.module'; +import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; export function createTranslateLoader(http: HttpClient): any { return new TranslateHttpLoader(http, 'assets/i18n/', '.json'); @@ -73,7 +71,8 @@ let getBaseUrl = (): string => { }), AuthModule, VoiceModule, - LayoutsModule + LayoutsModule, + MappingModule ], providers: [ //{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true }, diff --git a/src/app/features/home/effects/home.effect.ts b/src/app/features/home/effects/home.effect.ts index 37aeebd..aa0070b 100644 --- a/src/app/features/home/effects/home.effect.ts +++ b/src/app/features/home/effects/home.effect.ts @@ -681,7 +681,7 @@ export class HomeEffects { this.actions$.pipe( ofType(homeAction.HomeActionTypes.SAVE_PERSONSTAFFING), mergeMap((action) => - this.personnelStaffingProvider.savePersonsStatuses({ + this.personnelStaffingProvider.savePersonsStaffings({ UserIds: action.payload.userIds, Type: action.payload.staffingType, TimestampUtc: action.payload.date.toUTCString().replace("UTC", "GMT"), diff --git a/src/app/features/home/models/dashboardPayload.ts b/src/app/features/home/models/dashboardPayload.ts index 48bf892..45f82d3 100644 --- a/src/app/features/home/models/dashboardPayload.ts +++ b/src/app/features/home/models/dashboardPayload.ts @@ -1,4 +1,4 @@ -import { CallPriorityResultData, CallResultData, CallTypeResultData, FormResultData, GetPersonnelForCallGridResultData, GetRolesForCallGridResultData, UnitStatusResultData, GroupsForCallGridData, CustomStatusResultData } from "@resgrid/ngx-resgridlib"; +import { CallPriorityResultData, CallResultData, CallTypeResultData, FormResultData, GetPersonnelForCallGridResultData, GetRolesForCallGridResultData, UnitStatusResultData, GroupsForCallGridData, CustomStatusResultData, NoteResultData } from "@resgrid/ngx-resgridlib"; export class DashboardPayload { public UnitStatuses: UnitStatusResultData[]; @@ -11,4 +11,5 @@ export class DashboardPayload { public NewCallForm: FormResultData; public PersonnelStatuses: CustomStatusResultData[]; public PersonnelStaffingLevels: CustomStatusResultData[]; + public DispatchNote: NoteResultData } diff --git a/src/app/features/home/pages/dashboard/dashboard.page.html b/src/app/features/home/pages/dashboard/dashboard.page.html index 80ed458..63d661d 100644 --- a/src/app/features/home/pages/dashboard/dashboard.page.html +++ b/src/app/features/home/pages/dashboard/dashboard.page.html @@ -286,8 +286,8 @@

Active Calls

-
 
-
 
+
 
+
 
@@ -295,63 +295,73 @@

Active Calls

+
+
+
+
+

Dispatch Note

+
+
+ +
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
- -

Statuses

-
-
- +
+
+
+
+
+
+ +

Statuses

+
+
+ -
-
-
+
diff --git a/src/app/features/home/providers/home.ts b/src/app/features/home/providers/home.ts index e97252f..6191978 100644 --- a/src/app/features/home/providers/home.ts +++ b/src/app/features/home/providers/home.ts @@ -14,6 +14,8 @@ import { DispatchService, EventsService, FormsService, + NoteResultData, + NotesService, SignalRService, UnitsService, UnitStatusService, @@ -26,6 +28,7 @@ import { selectHomeState } from "src/app/store"; import { AuthState } from "../../auth/store/auth.store"; import { selectAuthState } from "src/app/store"; import * as HomeActions from "../../../features/home/actions/home.actions"; +import { NoteResult } from "@resgrid/ngx-resgridlib/lib/models/v4/notes/noteResult"; @Injectable({ providedIn: "root", @@ -49,7 +52,8 @@ export class HomeProvider { private authStore: Store, private events: EventsService, private consts: Consts, - private customStatusesService: CustomStatusesService + private customStatusesService: CustomStatusesService, + private noteService: NotesService ) { //this.personnelStatusUpdated$ = this.events.subscribe(this.consts.SIGNALR_EVENTS.PERSONNEL_STATUS_UPDATED); //this.personnelStaffingUpdated$ = this.events.subscribe(this.consts.SIGNALR_EVENTS.PERSONNEL_STAFFING_UPDATED); @@ -70,6 +74,7 @@ export class HomeProvider { const getNewCallForm = this.formsProvider.getNewCallForm(); const getPersonnelStatus = this.customStatusesService.getActivePersonnelStatuses(); const getPersonnelStaffingLevels = this.customStatusesService.getActivePersonnelStaffingLevels(); + const getDispatchNote = this.noteService.getDispatchNote(); return forkJoin({ units: getUnits, @@ -82,6 +87,7 @@ export class HomeProvider { newCallForm: getNewCallForm, personnelStatuses: getPersonnelStatus, PersonnelStaffingLevels: getPersonnelStaffingLevels, + dispatchNote: getDispatchNote }).pipe( map((results) => { let localCalls: CallLocalResult[] = new Array(); @@ -108,6 +114,11 @@ export class HomeProvider { }); } + let dispatchNote: NoteResultData = null; + + if (results.dispatchNote && results.dispatchNote.Data) + dispatchNote = results.dispatchNote.Data; + return { UnitStatuses: results.units.Data, Calls: results.calls.Data, @@ -119,6 +130,7 @@ export class HomeProvider { NewCallForm: results.newCallForm.Data, PersonnelStatuses: results.personnelStatuses.Data, PersonnelStaffingLevels: results.PersonnelStaffingLevels.Data, + DispatchNote: dispatchNote }; }) ); diff --git a/src/app/features/home/reducers/home.reducer.ts b/src/app/features/home/reducers/home.reducer.ts index 8fb1707..8fc9d10 100644 --- a/src/app/features/home/reducers/home.reducer.ts +++ b/src/app/features/home/reducers/home.reducer.ts @@ -35,6 +35,7 @@ export function reducer(state: HomeState = initialState, action: HomeActionsUnio newCallForm: action.payload.NewCallForm, personnelStatuses: action.payload.PersonnelStatuses, personnelStaffing: action.payload.PersonnelStaffingLevels, + dispatchNote: action.payload.DispatchNote, }; case HomeActionTypes.LOADING_FAIL: diff --git a/src/app/features/home/store/home.store.ts b/src/app/features/home/store/home.store.ts index f0a8ebb..f7f908d 100644 --- a/src/app/features/home/store/home.store.ts +++ b/src/app/features/home/store/home.store.ts @@ -1,4 +1,4 @@ -import { CallFileResultData, CallNoteResultData, CallPriorityResultData, CallResultData, CallTypeResultData, CustomStatusResultData, FormResultData, GetCallTemplatesResultData, GpsLocation, MapDataAndMarkersData } from '@resgrid/ngx-resgridlib'; +import { CallFileResultData, CallNoteResultData, CallPriorityResultData, CallResultData, CallTypeResultData, CustomStatusResultData, FormResultData, GetCallTemplatesResultData, GpsLocation, MapDataAndMarkersData, NoteResultData } from '@resgrid/ngx-resgridlib'; import { CallLocalResult } from 'src/app/core/models/callLocalResult'; import { GroupsForCallResult } from 'src/app/core/models/groupsForCallResult'; import { PersonnelForCallResult } from 'src/app/core/models/personnelForCallResult'; @@ -52,6 +52,8 @@ export interface HomeState { personnelStatuses: CustomStatusResultData[]; personnelStaffing: CustomStatusResultData[]; + + dispatchNote: NoteResultData; } export const initialState: HomeState = { @@ -81,4 +83,5 @@ export const initialState: HomeState = { editCall: null, personnelStatuses: null, personnelStaffing: null, + dispatchNote: null }; \ No newline at end of file diff --git a/src/app/features/mapping/actions/mapping.actions.ts b/src/app/features/mapping/actions/mapping.actions.ts new file mode 100644 index 0000000..9506905 --- /dev/null +++ b/src/app/features/mapping/actions/mapping.actions.ts @@ -0,0 +1,31 @@ +import { Action } from "@ngrx/store"; +import { MapDataAndMarkersData } from "@resgrid/ngx-resgridlib"; + +export enum MappingActionTypes { + LOADING_MAP_DATA = "[MAPPING] LOADING_MAP_DATA", + LOADING_MAP_DATA_SUCCESS = "[MAPPING] LOADING_MAP_DATA_SUCCESS", + LOADING_MAP_DATA_FAIL = "[MAPPING] LOADING_MAP_DATA_FAIL", + LOADING_MAP_DATA_DONE = "[MAPPING] LOADING_MAP_DATA_DONE", +} + +export class LoadMapData implements Action { + readonly type = MappingActionTypes.LOADING_MAP_DATA; + constructor() {} +} + +export class LoadMapDataSuccess implements Action { + readonly type = MappingActionTypes.LOADING_MAP_DATA_SUCCESS; + constructor(public payload: MapDataAndMarkersData) {} +} + +export class LoadMapDataFail implements Action { + readonly type = MappingActionTypes.LOADING_MAP_DATA_FAIL; + constructor() {} +} + +export class LoadMapDataDone implements Action { + readonly type = MappingActionTypes.LOADING_MAP_DATA_DONE; + constructor() {} +} + +export type MappingActionsUnion = LoadMapData | LoadMapDataSuccess | LoadMapDataFail | LoadMapDataDone; diff --git a/src/app/features/mapping/effects/mapping.effect.ts b/src/app/features/mapping/effects/mapping.effect.ts new file mode 100644 index 0000000..4437a10 --- /dev/null +++ b/src/app/features/mapping/effects/mapping.effect.ts @@ -0,0 +1,66 @@ +import { Store } from "@ngrx/store"; +import { Actions, createEffect, ofType } from "@ngrx/effects"; +import { catchError, map, mergeMap } from "rxjs/operators"; +import { Injectable } from "@angular/core"; +import { from, of } from "rxjs"; +import { NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap"; +import { MappingService } from '@resgrid/ngx-resgridlib'; +import * as _ from "lodash"; +import * as mappingAction from '../actions/mapping.actions'; +import { MappingState } from "../store/mapping.store"; + +@Injectable() +export class MappingEffects { + private _modalRef: NgbModalRef; + + getUnitsList$ = createEffect(() => + this.actions$.pipe( + ofType( + mappingAction.MappingActionTypes.LOADING_MAP_DATA + ), + mergeMap((action) => + this.mapProvider.getMapDataAndMarkers().pipe( + map((data) => ({ + type: mappingAction.MappingActionTypes.LOADING_MAP_DATA_SUCCESS, + payload: data.Data, + })), + catchError(() => + of({ + type: mappingAction.MappingActionTypes.LOADING_MAP_DATA_FAIL, + }) + ) + ) + ) + ) + ); + + constructor( + private actions$: Actions, + private store: Store, + private modalService: NgbModal, + private mapProvider: MappingService, + ) {} + + runModal = (component, size) => { + this.closeModal(); + + if (!size) { + size = "md"; + } + + this._modalRef = this.modalService.open(component, { + centered: true, + backdrop: "static", + size: size, + }); + + return from(this._modalRef.result); + }; + + closeModal = () => { + if (this._modalRef) { + this._modalRef.close(); + this._modalRef = null; + } + }; +} diff --git a/src/app/features/mapping/mapping-routing.module.ts b/src/app/features/mapping/mapping-routing.module.ts new file mode 100644 index 0000000..b199891 --- /dev/null +++ b/src/app/features/mapping/mapping-routing.module.ts @@ -0,0 +1,24 @@ +import { NgModule } from '@angular/core'; +import { PreloadAllModules, RouterModule, Routes } from '@angular/router'; +import { AuthGuard } from 'src/app/core/guards/auth.guard'; +import { LayoutComponent } from 'src/app/layouts/layout/layout.component'; + +const routes: Routes = [ + { + path: '', + redirectTo: 'map', + pathMatch: 'full' + }, + { + path: 'map', + component: LayoutComponent, + loadChildren: () => import('./pages/map/map.module').then(m => m.MapPageModule), + canActivate: [ AuthGuard ] + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class CallsRoutingModule {} diff --git a/src/app/features/mapping/mapping.module.ts b/src/app/features/mapping/mapping.module.ts new file mode 100644 index 0000000..a5b1d54 --- /dev/null +++ b/src/app/features/mapping/mapping.module.ts @@ -0,0 +1,45 @@ +import { NgModule } from '@angular/core'; +import { StoreModule } from '@ngrx/store'; +import { EffectsModule } from '@ngrx/effects'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { CallsRoutingModule } from './mapping-routing.module'; +import { reducer } from './reducers/mapping.reducer'; +import { MappingEffects } from './effects/mapping.effect'; +import { NgbAlertModule, NgbDropdownModule, NgbNavModule, NgbPaginationModule, NgbTooltipModule, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap'; +import { Ng2SearchPipeModule } from 'ng2-search-filter'; +import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar'; +import { LeafletModule } from '@asymmetrik/ngx-leaflet'; +import { UiModule } from 'src/app/shared/ui/ui.module'; +import { GalleryModule } from 'ng-gallery'; +import { NgxResgridLibModule } from '@resgrid/ngx-resgridlib'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + ReactiveFormsModule, + CallsRoutingModule, + NgbAlertModule, + NgxResgridLibModule, + Ng2SearchPipeModule, + NgbNavModule, + NgbDropdownModule, + NgbTooltipModule, + PerfectScrollbarModule, + LeafletModule, + UiModule, + StoreModule.forFeature('mappingModule', reducer), + EffectsModule.forFeature([MappingEffects]), + GalleryModule, + NgbPaginationModule, + NgbTypeaheadModule + ], + providers: [], + exports: [ + + ], + entryComponents: [ + ] +}) +export class MappingModule { } diff --git a/src/app/features/mapping/pages/map/map.module.ts b/src/app/features/mapping/pages/map/map.module.ts new file mode 100644 index 0000000..0e9f2f3 --- /dev/null +++ b/src/app/features/mapping/pages/map/map.module.ts @@ -0,0 +1,47 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; +import { Ng2SearchPipeModule } from 'ng2-search-filter'; +import { MapPage } from './map.page'; +import { NgbAlertModule, NgbDropdownModule, NgbNavModule, NgbPaginationModule, NgbTooltipModule, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap'; +import { PerfectScrollbarConfigInterface, PerfectScrollbarModule, PERFECT_SCROLLBAR_CONFIG } from 'ngx-perfect-scrollbar'; +import { LeafletModule } from '@asymmetrik/ngx-leaflet'; +import { UiModule } from 'src/app/shared/ui/ui.module'; + +const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = { + suppressScrollX: true, + wheelSpeed: 0.3 +}; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + NgbAlertModule, + ReactiveFormsModule, + Ng2SearchPipeModule, + NgbNavModule, + NgbDropdownModule, + NgbTooltipModule, + PerfectScrollbarModule, + LeafletModule, + UiModule, + NgbPaginationModule, + NgbTypeaheadModule, + RouterModule.forChild([ + { + path: '', + component: MapPage + } + ]) + ], + providers: [ + { + provide: PERFECT_SCROLLBAR_CONFIG, + useValue: DEFAULT_PERFECT_SCROLLBAR_CONFIG + } + ], + declarations: [MapPage] +}) +export class MapPageModule {} diff --git a/src/app/features/mapping/pages/map/map.page.html b/src/app/features/mapping/pages/map/map.page.html new file mode 100644 index 0000000..2cbc28d --- /dev/null +++ b/src/app/features/mapping/pages/map/map.page.html @@ -0,0 +1,24 @@ +
+ +
+
+
+
+
+
+ +
+
+ Show Calls:     + Show Stations:     + Show Units:     + Show Personnel: +
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/src/app/features/mapping/pages/map/map.page.scss b/src/app/features/mapping/pages/map/map.page.scss new file mode 100644 index 0000000..3ebe680 --- /dev/null +++ b/src/app/features/mapping/pages/map/map.page.scss @@ -0,0 +1,3 @@ +#map { + height: 100%; +} \ No newline at end of file diff --git a/src/app/features/mapping/pages/map/map.page.ts b/src/app/features/mapping/pages/map/map.page.ts new file mode 100644 index 0000000..4258206 --- /dev/null +++ b/src/app/features/mapping/pages/map/map.page.ts @@ -0,0 +1,161 @@ +import { AfterViewInit, ChangeDetectorRef, Component, OnInit, QueryList, ViewChild, ViewChildren } from "@angular/core"; +import { Store } from "@ngrx/store"; +import * as _ from "lodash"; +import { MappingState } from "../../store/mapping.store"; +import * as CallsActions from "../../actions/mapping.actions"; +import { UtilsProvider } from "src/app/providers/utils"; +import { Router } from "@angular/router"; +import { Observable, Subscription } from "rxjs"; +import { selectMappingState } from "src/app/store"; +import * as MappingActions from "../../actions/mapping.actions"; +import { MapDataAndMarkersData } from "@resgrid/ngx-resgridlib"; +import * as L from "leaflet"; +import { environment } from "src/environments/environment"; + +@Component({ + selector: "app-mapping-map", + templateUrl: "map.page.html", + styleUrls: ["map.page.scss"], +}) +export class MapPage implements AfterViewInit { + public breadCrumbItems: Array<{}>; + private mappingStateSub: Subscription; + public mappingState$: Observable; + @ViewChild("map") mapContainer; + public map: any; + public markers: any[]; + public showCalls: boolean = true; + public showStations: boolean = true; + public showUnits: boolean = true; + public showPersonnel: boolean = true; + + constructor( + private mappingStore: Store, + public utilsProvider: UtilsProvider, + private router: Router, + private cdr: ChangeDetectorRef + ) { + this.mappingState$ = this.mappingStore.select(selectMappingState); + this.markers = new Array(); + } + + ngAfterViewInit(): void { + this.mappingStateSub = this.mappingState$.subscribe((state) => { + if (state && state.mapData) { + this.processMapData(state.mapData); + } + }); + + this.mappingStore.dispatch(new MappingActions.LoadMapData()); + + this.breadCrumbItems = [{ label: "Resgrid Dispatch" }, { label: "Map", active: true }]; + + this.cdr.detectChanges(); + } + + public changeShowCalls(event) { + var checked = event.target.checked; + this.showCalls = checked; + + this.mappingStore.dispatch(new MappingActions.LoadMapData()); + } + + public changeShowStations(event) { + var checked = event.target.checked; + this.showStations = checked; + + this.mappingStore.dispatch(new MappingActions.LoadMapData()); + } + + public changeShowUnits(event) { + var checked = event.target.checked; + this.showUnits = checked; + + this.mappingStore.dispatch(new MappingActions.LoadMapData()); + } + + public changeShowPeople(event) { + var checked = event.target.checked; + this.showPersonnel = checked; + + this.mappingStore.dispatch(new MappingActions.LoadMapData()); + } + + private processMapData(data: MapDataAndMarkersData) { + if (data) { + var mapCenter = this.getMapCenter(data); + + if (!this.map) { + this.map = L.map(this.mapContainer.nativeElement, { + //dragging: false, + doubleClickZoom: false, + zoomControl: false, + }); + + L.tileLayer("https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=" + environment.osmMapKey, { + attribution: + '© OpenStreetMap contributors CC-BY-SA', + }).addTo(this.map); + } + + //this.mapProvider.setMarkersForMap(this.map); + + //this.setMapBounds(); + + //if (this.map) { + this.map.setView(mapCenter, this.getMapZoomLevel(data)); + //} + + // clear map markers + if (this.markers && this.markers.length >= 0) { + for (var i = 0; i < this.markers.length; i++) { + if (this.markers[i]) { + this.map.removeLayer(this.markers[i]); + } + } + + this.markers = new Array(); + } + + if (data.MapMakerInfos && data.MapMakerInfos.length > 0) { + if (data && data.MapMakerInfos) { + data.MapMakerInfos.forEach((markerInfo) => { + + if ((markerInfo.Type == 0 && this.showCalls) || + (markerInfo.Type == 1 && this.showUnits) || + (markerInfo.Type == 2 && this.showStations)) { + let marker = L.marker([markerInfo.Latitude, markerInfo.Longitude], { + icon: L.icon({ + iconUrl: "assets/images/mapping/" + markerInfo.ImagePath + ".png", + iconSize: [32, 37], + iconAnchor: [16, 37], + }), + draggable: false, + title: markerInfo.Title, + //tooltip: markerInfo.Title, + }) + .bindTooltip(markerInfo.Title, { + permanent: true, + direction: "bottom", + }) + .addTo(this.map); + + this.markers.push(marker); + } + }); + } + + var group = L.featureGroup(this.markers); + this.map.fitBounds(group.getBounds()); + } + } + } + + private getMapCenter(data: MapDataAndMarkersData) { + return [data.CenterLat, data.CenterLon]; + } + + private getMapZoomLevel(data: MapDataAndMarkersData): any { + return data.ZoomLevel; + } +} diff --git a/src/app/features/mapping/reducers/mapping.reducer.ts b/src/app/features/mapping/reducers/mapping.reducer.ts new file mode 100644 index 0000000..9d73c92 --- /dev/null +++ b/src/app/features/mapping/reducers/mapping.reducer.ts @@ -0,0 +1,19 @@ +import { initialState, MappingState } from "../store/mapping.store"; +import { MappingActionsUnion, MappingActionTypes } from "../actions/mapping.actions"; +import * as _ from "lodash"; + +export function reducer( + state: MappingState = initialState, + action: MappingActionsUnion +): MappingState { + switch (action.type) { + case MappingActionTypes.LOADING_MAP_DATA_SUCCESS: + return { + ...state, + mapData: action.payload, + }; + default: + return state; + } +} + diff --git a/src/app/features/mapping/store/mapping.store.ts b/src/app/features/mapping/store/mapping.store.ts new file mode 100644 index 0000000..aa744cd --- /dev/null +++ b/src/app/features/mapping/store/mapping.store.ts @@ -0,0 +1,9 @@ +import { MapDataAndMarkersData } from '@resgrid/ngx-resgridlib'; + +export interface MappingState { + mapData: MapDataAndMarkersData +} + +export const initialState: MappingState = { + mapData: null +}; \ No newline at end of file diff --git a/src/app/layouts/shared/horizontalnavbar/horizontalnavbar.component.html b/src/app/layouts/shared/horizontalnavbar/horizontalnavbar.component.html deleted file mode 100644 index 7298a71..0000000 --- a/src/app/layouts/shared/horizontalnavbar/horizontalnavbar.component.html +++ /dev/null @@ -1,55 +0,0 @@ - diff --git a/src/app/layouts/shared/horizontalnavbar/horizontalnavbar.component.scss b/src/app/layouts/shared/horizontalnavbar/horizontalnavbar.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/layouts/shared/horizontalnavbar/horizontalnavbar.component.spec.ts b/src/app/layouts/shared/horizontalnavbar/horizontalnavbar.component.spec.ts deleted file mode 100644 index 0d0b30b..0000000 --- a/src/app/layouts/shared/horizontalnavbar/horizontalnavbar.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; - -import { HorizontalnavbarComponent } from './horizontalnavbar.component'; - -describe('HorizontalnavbarComponent', () => { - let component: HorizontalnavbarComponent; - let fixture: ComponentFixture; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ HorizontalnavbarComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(HorizontalnavbarComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/layouts/shared/horizontalnavbar/horizontalnavbar.component.ts b/src/app/layouts/shared/horizontalnavbar/horizontalnavbar.component.ts deleted file mode 100644 index 952c47a..0000000 --- a/src/app/layouts/shared/horizontalnavbar/horizontalnavbar.component.ts +++ /dev/null @@ -1,188 +0,0 @@ -import { Component, OnInit, AfterViewInit } from '@angular/core'; -import { Router, NavigationEnd } from '@angular/router'; - -import { EventService } from '../../../core/services/event.service'; -import { MENU } from './menu'; -import { MenuItem } from './menu.model'; - -@Component({ - selector: 'app-horizontalnavbar', - templateUrl: './horizontalnavbar.component.html', - styleUrls: ['./horizontalnavbar.component.scss'] -}) -export class HorizontalnavbarComponent implements OnInit, AfterViewInit { - - configData; - menuItems = []; - - // tslint:disable-next-line: max-line-length - constructor(private router: Router, private eventService: EventService) { - router.events.subscribe(event => { - if (event instanceof NavigationEnd) { - this.activateMenu(); - } - }); - } - - ngOnInit(): void { - - this.initialize(); - - this.configData = { - suppressScrollX: true, - wheelSpeed: 0.3 - }; - } - - /** - * On menu click - */ - onMenuClick(event: any) { - const nextEl = event.target.nextSibling; - const parent = event.target.parentNode; - if (nextEl.id !== 'navmenu') { - } else if (nextEl && !nextEl.classList.contains('show')) { - const parentEl = event.target.parentNode; - if (parentEl) { parentEl.classList.remove('show'); } - nextEl.classList.toggle('show'); - } - return false; - } - - ngAfterViewInit() { - this.activateMenu(); - } - - /** - * remove active and mm-active class - */ - _removeAllClass(className) { - const els = document.getElementsByClassName(className); - while (els[0]) { - els[0].classList.remove(className); - } - } - - /** - * Togglemenu bar - */ - toggleMenubar() { - const element = document.getElementById('topnav-menu-content'); - element.classList.toggle('show'); - } - - /** - * Activates the menu - */ - private activateMenu() { - - const resetParent = (el: any) => { - const parent = el.parentElement; - if (parent) { - parent.classList.remove('active'); - const parent2 = parent.parentElement; - this._removeAllClass('mm-active'); - this._removeAllClass('mm-show'); - if (parent2) { - parent2.classList.remove('active'); - const parent3 = parent2.parentElement; - if (parent3) { - parent3.classList.remove('active'); - const parent4 = parent3.parentElement; - if (parent4) { - parent4.classList.remove('active'); - const parent5 = parent4.parentElement; - if (parent5) { - parent5.classList.remove('active'); - } - } - } - } - } - }; - - // activate menu item based on location - const links = document.getElementsByClassName('side-nav-link-ref'); - let matchingMenuItem = null; - // tslint:disable-next-line: prefer-for-of - for (let i = 0; i < links.length; i++) { - // reset menu - resetParent(links[i]); - } - // tslint:disable-next-line: prefer-for-of - for (let i = 0; i < links.length; i++) { - // tslint:disable-next-line: no-string-literal - if (location.pathname === links[i]['pathname']) { - matchingMenuItem = links[i]; - break; - } - } - - if (matchingMenuItem) { - const parent = matchingMenuItem.parentElement; - /** - * TODO: This is hard coded way of expading/activating parent menu dropdown and working till level 3. - * We should come up with non hard coded approach - */ - if (parent) { - parent.classList.add('active'); - const parent2 = parent.parentElement; - if (parent2) { - parent2.classList.add('active'); - const parent3 = parent2.parentElement; - if (parent3) { - parent3.classList.add('active'); - const parent4 = parent3.parentElement; - if (parent4) { - parent4.classList.add('active'); - const parent5 = parent4.parentElement; - if (parent5) { - parent5.classList.add('active'); - } - } - } - } - } - } - } - - /** - * Topbar light - */ - topbarLight() { - document.body.setAttribute('data-topbar', 'light'); - document.body.removeAttribute('data-layout-size'); - } - - /** - * Set boxed width - */ - boxedWidth() { - document.body.setAttribute('data-layout-size', 'boxed'); - document.body.setAttribute('data-topbar', 'dark'); - } - - /** - * Change the layout onclick - * @param layout Change the layout - */ - changeLayout(layout: string) { - this.eventService.broadcast('changeLayout', layout); - } - - /** - * Initialize - */ - initialize(): void { - this.menuItems = MENU; - } - - /** - * Returns true or false if given menu item has child or not - * @param item menuItem - */ - hasItems(item: MenuItem) { - return item.subItems !== undefined ? item.subItems.length > 0 : false; - } - -} diff --git a/src/app/layouts/shared/horizontalnavbar/menu.model.ts b/src/app/layouts/shared/horizontalnavbar/menu.model.ts deleted file mode 100644 index ae148d8..0000000 --- a/src/app/layouts/shared/horizontalnavbar/menu.model.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface MenuItem { - id?: number; - label?: string; - icon?: string; - link?: string; - subItems?: any; - parentId?: number; - isUiElement?: boolean; -} diff --git a/src/app/layouts/shared/horizontalnavbar/menu.ts b/src/app/layouts/shared/horizontalnavbar/menu.ts deleted file mode 100644 index a80d10b..0000000 --- a/src/app/layouts/shared/horizontalnavbar/menu.ts +++ /dev/null @@ -1,438 +0,0 @@ -import { MenuItem } from './menu.model'; - -export const MENU: MenuItem[] = [ - { - id: 1, - label: 'MENUITEMS.DASHBOARDS.TEXT', - icon: 'ri-dashboard-line', - link: '/' - }, - { - id: 2, - label: 'MENUITEMS.UIELEMENTS.TEXT', - icon: 'ri-pencil-ruler-2-line', - isUiElement: true, - subItems: [ - { - id: 3, - label: 'MENUITEMS.UIELEMENTS.LIST.ALERTS', - link: '/ui/alerts', - parentId: 2 - }, - { - id: 4, - label: 'MENUITEMS.UIELEMENTS.LIST.BUTTONS', - link: '/ui/buttons', - parentId: 2 - }, - { - id: 5, - label: 'MENUITEMS.UIELEMENTS.LIST.CARDS', - link: '/ui/cards', - parentId: 2 - }, - { - id: 6, - label: 'MENUITEMS.UIELEMENTS.LIST.CAROUSEL', - link: '/ui/carousel', - parentId: 2 - }, - { - id: 7, - label: 'MENUITEMS.UIELEMENTS.LIST.DROPDOWNS', - link: '/ui/dropdowns', - parentId: 2 - }, - { - id: 8, - label: 'MENUITEMS.UIELEMENTS.LIST.GRID', - link: '/ui/grid', - parentId: 2 - }, - { - id: 9, - label: 'MENUITEMS.UIELEMENTS.LIST.IMAGES', - link: '/ui/images', - parentId: 2 - }, - { - id: 10, - label: 'MENUITEMS.UIELEMENTS.LIST.MODALS', - link: '/ui/modals', - parentId: 2 - }, - { - id: 11, - label: 'MENUITEMS.UIELEMENTS.LIST.RANGESLIDER', - link: '/ui/rangeslider', - parentId: 2 - }, - { - id: 12, - label: 'MENUITEMS.UIELEMENTS.LIST.PROGRESSBAR', - link: '/ui/progressbar', - parentId: 3 - }, - { - id: 13, - label: 'MENUITEMS.UIELEMENTS.LIST.SWEETALERT', - link: '/ui/sweet-alert', - parentId: 2 - }, - { - id: 17, - label: 'MENUITEMS.UIELEMENTS.LIST.TABS', - link: '/ui/tabs-accordions', - parentId: 2 - }, - { - id: 18, - label: 'MENUITEMS.UIELEMENTS.LIST.TYPOGRAPHY', - link: '/ui/typography', - parentId: 2 - }, - { - id: 19, - label: 'MENUITEMS.UIELEMENTS.LIST.VIDEO', - link: '/ui/video', - parentId: 2 - }, - { - id: 20, - label: 'MENUITEMS.UIELEMENTS.LIST.GENERAL', - link: '/ui/general', - parentId: 2 - } - ] - }, - { - id: 21, - label: 'MENUITEMS.APPS.TEXT', - icon: 'ri-apps-2-line', - subItems: [ - { - id: 22, - label: 'MENUITEMS.CALENDAR.TEXT', - link: '/calendar', - parentId: 21 - }, - { - id: 23, - label: 'MENUITEMS.CHAT.TEXT', - link: '/chat', - parentId: 21 - }, - { - id: 24, - label: 'MENUITEMS.EMAIL.TEXT', - subItems: [ - { - id: 25, - label: 'MENUITEMS.EMAIL.LIST.INBOX', - link: '/email/inbox', - parentId: 24 - }, - { - id: 26, - label: 'MENUITEMS.EMAIL.LIST.READEMAIL', - link: '/email/read/1', - parentId: 24 - } - ] - }, - { - id: 27, - label: 'MENUITEMS.ECOMMERCE.TEXT', - subItems: [ - { - id: 28, - label: 'MENUITEMS.ECOMMERCE.LIST.PRODUCTS', - link: '/ecommerce/products', - parentId: 27 - }, - { - id: 30, - label: 'MENUITEMS.ECOMMERCE.LIST.ORDERS', - link: '/ecommerce/orders', - parentId: 27 - }, - { - id: 31, - label: 'MENUITEMS.ECOMMERCE.LIST.CUSTOMERS', - link: '/ecommerce/customers', - parentId: 27 - }, - { - id: 32, - label: 'MENUITEMS.ECOMMERCE.LIST.CART', - link: '/ecommerce/cart', - parentId: 27 - }, - { - id: 33, - label: 'MENUITEMS.ECOMMERCE.LIST.CHECKOUT', - link: '/ecommerce/checkout', - parentId: 27 - }, - { - id: 34, - label: 'MENUITEMS.ECOMMERCE.LIST.SHOPS', - link: '/ecommerce/shops', - parentId: 27 - }, - { - id: 35, - label: 'MENUITEMS.ECOMMERCE.LIST.ADDPRODUCT', - link: '/ecommerce/add-product', - parentId: 27 - }, - ] - }, - { - id: 36, - label: 'MENUITEMS.KANBAN.TEXT', - link: '/kanban-board', - } - ] - }, - { - id: 37, - label: 'MENUITEMS.COMPONENTS.TEXT', - icon: 'ri-stack-line', - subItems: [ - { - id: 38, - label: 'MENUITEMS.FORMS.TEXT', - subItems: [ - { - id: 39, - label: 'MENUITEMS.FORMS.LIST.ELEMENTS', - link: '/form/elements', - parentId: 38 - }, - { - id: 40, - label: 'MENUITEMS.FORMS.LIST.VALIDATION', - link: '/form/validation', - parentId: 38 - }, - { - id: 41, - label: 'MENUITEMS.FORMS.LIST.ADVANCED', - link: '/form/advanced', - parentId: 38 - }, - { - id: 42, - label: 'MENUITEMS.FORMS.LIST.EDITOR', - link: '/form/editor', - parentId: 38 - }, - { - id: 43, - label: 'MENUITEMS.FORMS.LIST.FILEUPLOAD', - link: '/form/uploads', - parentId: 38 - }, - { - id: 44, - label: 'MENUITEMS.FORMS.LIST.WIZARD', - link: '/form/wizard', - parentId: 38 - }, - { - id: 45, - label: 'MENUITEMS.FORMS.LIST.MASK', - link: '/form/mask', - parentId: 38 - } - ] - }, - { - id: 46, - label: 'MENUITEMS.TABLES.TEXT', - subItems: [ - { - id: 47, - label: 'MENUITEMS.TABLES.LIST.BASIC', - link: '/tables/basic', - parentId: 46 - }, - { - id: 48, - label: 'MENUITEMS.TABLES.LIST.ADVANCED', - link: '/tables/advanced', - parentId: 46 - } - ] - }, - { - id: 48, - label: 'MENUITEMS.CHARTS.TEXT', - subItems: [ - { - id: 49, - label: 'MENUITEMS.CHARTS.LIST.APEX', - link: '/charts/apex', - parentId: 48 - }, - { - id: 50, - label: 'MENUITEMS.CHARTS.LIST.CHARTJS', - link: '/charts/chartjs', - parentId: 48 - }, - { - id: 51, - label: 'MENUITEMS.CHARTS.LIST.ECHART', - link: '/charts/echart', - parentId: 48 - } - ] - }, - { - id: 52, - label: 'MENUITEMS.ICONS.TEXT', - subItems: [ - { - id: 53, - label: 'MENUITEMS.ICONS.LIST.REMIX', - link: '/icons/remix', - parentId: 52 - }, - { - id: 54, - label: 'MENUITEMS.ICONS.LIST.MATERIALDESIGN', - link: '/icons/materialdesign', - parentId: 52 - }, - { - id: 55, - label: 'MENUITEMS.ICONS.LIST.DRIPICONS', - link: '/icons/dripicons', - parentId: 52 - }, - { - id: 56, - label: 'MENUITEMS.ICONS.LIST.FONTAWESOME', - link: '/icons/fontawesome', - parentId: 52 - } - ] - }, - { - id: 57, - label: 'MENUITEMS.MAPS.TEXT', - icon: 'ri-map-pin-line', - subItems: [ - { - id: 58, - label: 'MENUITEMS.MAPS.LIST.GOOGLEMAP', - link: '/maps/google', - parentId: 57 - }, - { - id: 59, - label: 'Leaflet Maps', - link: '/maps/leaflet', - parentId: 57 - }, - ] - } - ] - }, - { - id: 58, - label: 'MENUITEMS.PAGES.TEXT', - icon: 'ri-file-copy-2-line', - subItems: [ - { - id: 59, - label: 'MENUITEMS.AUTHENTICATION.TEXT', - icon: 'ri-account-circle-line', - subItems: [ - { - id: 60, - label: 'MENUITEMS.AUTHENTICATION.LIST.LOGIN', - link: '/pages/login-1', - parentId: 59 - }, - { - id: 61, - label: 'MENUITEMS.AUTHENTICATION.LIST.REGISTER', - link: '/pages/register-1', - parentId: 59 - }, - { - id: 62, - label: 'MENUITEMS.AUTHENTICATION.LIST.RECOVERPWD', - link: '/pages/recoverpwd-1', - parentId: 59 - }, - { - id: 63, - label: 'MENUITEMS.AUTHENTICATION.LIST.LOCKSCREEN', - link: '/pages/lock-screen-1', - parentId: 59 - } - ] - }, - { - id: 64, - label: 'MENUITEMS.UTILITY.TEXT', - icon: 'ri-profile-line', - subItems: [ - { - id: 65, - label: 'MENUITEMS.UTILITY.LIST.STARTER', - link: '/pages/starter', - parentId: 64 - }, - { - id: 66, - label: 'MENUITEMS.UTILITY.LIST.MAINTENANCE', - link: '/pages/maintenance', - parentId: 64 - }, - { - id: 67, - label: 'MENUITEMS.UTILITY.LIST.COOMINGSOON', - link: '/pages/coming-soon', - parentId: 64 - }, - { - id: 68, - label: 'MENUITEMS.UTILITY.LIST.TIMELINE', - link: '/pages/timeline', - parentId: 64 - }, - { - id: 69, - label: 'MENUITEMS.UTILITY.LIST.FAQS', - link: '/pages/faqs', - parentId: 64 - }, - { - id: 70, - label: 'MENUITEMS.UTILITY.LIST.PRICING', - link: '/pages/pricing', - parentId: 64 - }, - { - id: 71, - label: 'MENUITEMS.UTILITY.LIST.ERROR404', - link: '/pages/404', - parentId: 64 - }, - { - id: 72, - label: 'MENUITEMS.UTILITY.LIST.ERROR500', - link: '/pages/500', - parentId: 64 - }, - ] - }, - ] - } -]; - diff --git a/src/app/layouts/shared/horizontaltopbar/horizontaltopbar.component.html b/src/app/layouts/shared/horizontaltopbar/horizontaltopbar.component.html deleted file mode 100644 index 967799d..0000000 --- a/src/app/layouts/shared/horizontaltopbar/horizontaltopbar.component.html +++ /dev/null @@ -1,391 +0,0 @@ -
- -
diff --git a/src/app/layouts/shared/horizontaltopbar/horizontaltopbar.component.scss b/src/app/layouts/shared/horizontaltopbar/horizontaltopbar.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/layouts/shared/horizontaltopbar/horizontaltopbar.component.spec.ts b/src/app/layouts/shared/horizontaltopbar/horizontaltopbar.component.spec.ts deleted file mode 100644 index 72b878c..0000000 --- a/src/app/layouts/shared/horizontaltopbar/horizontaltopbar.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; - -import { HorizontaltopbarComponent } from './horizontaltopbar.component'; - -describe('HorizontaltopbarComponent', () => { - let component: HorizontaltopbarComponent; - let fixture: ComponentFixture; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ HorizontaltopbarComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(HorizontaltopbarComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/layouts/shared/horizontaltopbar/horizontaltopbar.component.ts b/src/app/layouts/shared/horizontaltopbar/horizontaltopbar.component.ts deleted file mode 100644 index b52205e..0000000 --- a/src/app/layouts/shared/horizontaltopbar/horizontaltopbar.component.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { Component, OnInit, Inject } from '@angular/core'; -import { DOCUMENT } from '@angular/common'; -import { CookieService } from 'ngx-cookie-service'; -import { Router, NavigationEnd } from '@angular/router'; - -import { environment } from '../../../../environments/environment'; -import { LanguageService } from '../../../core/services/language.service'; - -@Component({ - selector: 'app-horizontaltopbar', - templateUrl: './horizontaltopbar.component.html', - styleUrls: ['./horizontaltopbar.component.scss'] -}) -export class HorizontaltopbarComponent implements OnInit { - - configData: any; - - element: any; - cookieValue; - flagvalue; - countryName; - valueset: string; - - listLang = [ - { text: 'English', flag: 'assets/images/flags/us.jpg', lang: 'en' }, - { text: 'Spanish', flag: 'assets/images/flags/spain.jpg', lang: 'es' }, - { text: 'German', flag: 'assets/images/flags/germany.jpg', lang: 'de' }, - { text: 'Italian', flag: 'assets/images/flags/italy.jpg', lang: 'it' }, - { text: 'Russian', flag: 'assets/images/flags/russia.jpg', lang: 'ru' }, - ]; - - constructor(@Inject(DOCUMENT) private document: any, private router: Router, - public languageService: LanguageService, - public cookiesService: CookieService) { } - - ngOnInit(): void { - this.element = document.documentElement; - - this.configData = { - suppressScrollX: true, - wheelSpeed: 0.3 - }; - - this.cookieValue = this.cookiesService.get('lang'); - const val = this.listLang.filter(x => x.lang === this.cookieValue); - this.countryName = val.map(element => element.text); - if (val.length === 0) { - if (this.flagvalue === undefined) { this.valueset = 'assets/images/flags/us.jpg'; } - } else { - this.flagvalue = val.map(element => element.flag); - } - } - - /** - * Fullscreen method - */ - fullscreen() { - document.body.classList.toggle('fullscreen-enable'); - if ( - !document.fullscreenElement && !this.element.mozFullScreenElement && - !this.element.webkitFullscreenElement) { - if (this.element.requestFullscreen) { - this.element.requestFullscreen(); - } else if (this.element.mozRequestFullScreen) { - /* Firefox */ - this.element.mozRequestFullScreen(); - } else if (this.element.webkitRequestFullscreen) { - /* Chrome, Safari and Opera */ - this.element.webkitRequestFullscreen(); - } else if (this.element.msRequestFullscreen) { - /* IE/Edge */ - this.element.msRequestFullscreen(); - } - } else { - if (this.document.exitFullscreen) { - this.document.exitFullscreen(); - } else if (this.document.mozCancelFullScreen) { - /* Firefox */ - this.document.mozCancelFullScreen(); - } else if (this.document.webkitExitFullscreen) { - /* Chrome, Safari and Opera */ - this.document.webkitExitFullscreen(); - } else if (this.document.msExitFullscreen) { - /* IE/Edge */ - this.document.msExitFullscreen(); - } - } - } - - setLanguage(text: string, lang: string, flag: string) { - this.countryName = text; - this.flagvalue = flag; - this.cookieValue = lang; - this.languageService.setLanguage(lang); - } - - /** - * Togglemenu bar - */ - toggleMenubar() { - const element = document.getElementById('topnav-menu-content'); - element.classList.toggle('show'); - } - - /** - * on settings button clicked from topbar - */ - onSettingsButtonClicked() { - document.body.classList.toggle('right-bar-enabled'); - } - - /** - * Logout the user - */ - logout() { - this.router.navigate(['/account/login']); - } - -} diff --git a/src/app/layouts/shared/sidebar/menu.ts b/src/app/layouts/shared/sidebar/menu.ts index f31458f..da649a6 100644 --- a/src/app/layouts/shared/sidebar/menu.ts +++ b/src/app/layouts/shared/sidebar/menu.ts @@ -17,5 +17,11 @@ export const MENU: MenuItem[] = [ label: 'MENUITEMS.SCHEDULEDCALLS.TEXT', icon: 'ri-calendar-2-line', link: '/calls/scheduled' + }, + { + id: 3, + label: 'MENUITEMS.MAP.TEXT', + icon: 'ri-map-2-line', + link: '/mapping/map' } ]; diff --git a/src/app/store/index.ts b/src/app/store/index.ts index 577c5a7..5a46fa7 100644 --- a/src/app/store/index.ts +++ b/src/app/store/index.ts @@ -9,6 +9,7 @@ import { HomeState } from '../features/home/store/home.store'; import { VoiceState } from '../features/voice/store/voice.store'; import { CallsState } from '../features/calls/store/calls.store'; import { ProfileState } from '../features/profile/store/profile.store'; +import { MappingState } from '../features/mapping/store/mapping.store'; export interface State extends fromRoot.State { auth: AuthState; @@ -104,4 +105,7 @@ export const selectEditCallData = createSelector( -export const selectProfileState = createFeatureSelector('profileModule'); \ No newline at end of file +export const selectProfileState = createFeatureSelector('profileModule'); + + +export const selectMappingState = createFeatureSelector('mappingModule'); \ No newline at end of file diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 0f2b0f0..6809cfe 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -21,6 +21,9 @@ }, "SCHEDULEDCALLS": { "TEXT": "Scheduled Calls" + }, + "MAP": { + "TEXT": "Map" } } } \ No newline at end of file diff --git a/src/assets/images/mapping/aircraft.png b/src/assets/images/mapping/aircraft.png new file mode 100644 index 0000000..7617d50 Binary files /dev/null and b/src/assets/images/mapping/aircraft.png differ diff --git a/src/assets/images/mapping/ambulance.png b/src/assets/images/mapping/ambulance.png new file mode 100644 index 0000000..03cc1d9 Binary files /dev/null and b/src/assets/images/mapping/ambulance.png differ diff --git a/src/assets/images/mapping/blast.png b/src/assets/images/mapping/blast.png new file mode 100644 index 0000000..6a35aa5 Binary files /dev/null and b/src/assets/images/mapping/blast.png differ diff --git a/src/assets/images/mapping/bulldozer.png b/src/assets/images/mapping/bulldozer.png new file mode 100644 index 0000000..d9fadb0 Binary files /dev/null and b/src/assets/images/mapping/bulldozer.png differ diff --git a/src/assets/images/mapping/bus.png b/src/assets/images/mapping/bus.png new file mode 100644 index 0000000..651a9d2 Binary files /dev/null and b/src/assets/images/mapping/bus.png differ diff --git a/src/assets/images/mapping/camper.png b/src/assets/images/mapping/camper.png new file mode 100644 index 0000000..67bc93e Binary files /dev/null and b/src/assets/images/mapping/camper.png differ diff --git a/src/assets/images/mapping/car.png b/src/assets/images/mapping/car.png new file mode 100644 index 0000000..4fe29b0 Binary files /dev/null and b/src/assets/images/mapping/car.png differ diff --git a/src/assets/images/mapping/caraccident.png b/src/assets/images/mapping/caraccident.png new file mode 100644 index 0000000..612e259 Binary files /dev/null and b/src/assets/images/mapping/caraccident.png differ diff --git a/src/assets/images/mapping/cartwo.png b/src/assets/images/mapping/cartwo.png new file mode 100644 index 0000000..256ac40 Binary files /dev/null and b/src/assets/images/mapping/cartwo.png differ diff --git a/src/assets/images/mapping/check.png b/src/assets/images/mapping/check.png new file mode 100644 index 0000000..980ceb8 Binary files /dev/null and b/src/assets/images/mapping/check.png differ diff --git a/src/assets/images/mapping/crimescene.png b/src/assets/images/mapping/crimescene.png new file mode 100644 index 0000000..028c129 Binary files /dev/null and b/src/assets/images/mapping/crimescene.png differ diff --git a/src/assets/images/mapping/earthquake.png b/src/assets/images/mapping/earthquake.png new file mode 100644 index 0000000..cd3bf31 Binary files /dev/null and b/src/assets/images/mapping/earthquake.png differ diff --git a/src/assets/images/mapping/emergencyphone.png b/src/assets/images/mapping/emergencyphone.png new file mode 100644 index 0000000..8234819 Binary files /dev/null and b/src/assets/images/mapping/emergencyphone.png differ diff --git a/src/assets/images/mapping/fire.png b/src/assets/images/mapping/fire.png new file mode 100644 index 0000000..0aacb58 Binary files /dev/null and b/src/assets/images/mapping/fire.png differ diff --git a/src/assets/images/mapping/firstaid.png b/src/assets/images/mapping/firstaid.png new file mode 100644 index 0000000..9de8f23 Binary files /dev/null and b/src/assets/images/mapping/firstaid.png differ diff --git a/src/assets/images/mapping/flag.png b/src/assets/images/mapping/flag.png new file mode 100644 index 0000000..08f0d0b Binary files /dev/null and b/src/assets/images/mapping/flag.png differ diff --git a/src/assets/images/mapping/flood.png b/src/assets/images/mapping/flood.png new file mode 100644 index 0000000..af17507 Binary files /dev/null and b/src/assets/images/mapping/flood.png differ diff --git a/src/assets/images/mapping/fourbyfour.png b/src/assets/images/mapping/fourbyfour.png new file mode 100644 index 0000000..f03cad5 Binary files /dev/null and b/src/assets/images/mapping/fourbyfour.png differ diff --git a/src/assets/images/mapping/gathering.png b/src/assets/images/mapping/gathering.png new file mode 100644 index 0000000..23a734e Binary files /dev/null and b/src/assets/images/mapping/gathering.png differ diff --git a/src/assets/images/mapping/group.png b/src/assets/images/mapping/group.png new file mode 100644 index 0000000..61a6dd3 Binary files /dev/null and b/src/assets/images/mapping/group.png differ diff --git a/src/assets/images/mapping/helicopter.png b/src/assets/images/mapping/helicopter.png new file mode 100644 index 0000000..439af81 Binary files /dev/null and b/src/assets/images/mapping/helicopter.png differ diff --git a/src/assets/images/mapping/industry.png b/src/assets/images/mapping/industry.png new file mode 100644 index 0000000..cc0e174 Binary files /dev/null and b/src/assets/images/mapping/industry.png differ diff --git a/src/assets/images/mapping/linedown.png b/src/assets/images/mapping/linedown.png new file mode 100644 index 0000000..3693e03 Binary files /dev/null and b/src/assets/images/mapping/linedown.png differ diff --git a/src/assets/images/mapping/motorcycle.png b/src/assets/images/mapping/motorcycle.png new file mode 100644 index 0000000..0ce8cf8 Binary files /dev/null and b/src/assets/images/mapping/motorcycle.png differ diff --git a/src/assets/images/mapping/pickup.png b/src/assets/images/mapping/pickup.png new file mode 100644 index 0000000..91dcd10 Binary files /dev/null and b/src/assets/images/mapping/pickup.png differ diff --git a/src/assets/images/mapping/plowtruck.png b/src/assets/images/mapping/plowtruck.png new file mode 100644 index 0000000..211e215 Binary files /dev/null and b/src/assets/images/mapping/plowtruck.png differ diff --git a/src/assets/images/mapping/poison.png b/src/assets/images/mapping/poison.png new file mode 100644 index 0000000..4ef80a7 Binary files /dev/null and b/src/assets/images/mapping/poison.png differ diff --git a/src/assets/images/mapping/poweroutage.png b/src/assets/images/mapping/poweroutage.png new file mode 100644 index 0000000..42d390a Binary files /dev/null and b/src/assets/images/mapping/poweroutage.png differ diff --git a/src/assets/images/mapping/radiation.png b/src/assets/images/mapping/radiation.png new file mode 100644 index 0000000..bebf895 Binary files /dev/null and b/src/assets/images/mapping/radiation.png differ diff --git a/src/assets/images/mapping/search.png b/src/assets/images/mapping/search.png new file mode 100644 index 0000000..c7f3348 Binary files /dev/null and b/src/assets/images/mapping/search.png differ diff --git a/src/assets/images/mapping/shooting.png b/src/assets/images/mapping/shooting.png new file mode 100644 index 0000000..df1b5b2 Binary files /dev/null and b/src/assets/images/mapping/shooting.png differ diff --git a/src/assets/images/mapping/tires.png b/src/assets/images/mapping/tires.png new file mode 100644 index 0000000..5816702 Binary files /dev/null and b/src/assets/images/mapping/tires.png differ diff --git a/src/assets/images/mapping/tools.png b/src/assets/images/mapping/tools.png new file mode 100644 index 0000000..b421c84 Binary files /dev/null and b/src/assets/images/mapping/tools.png differ diff --git a/src/assets/images/mapping/treedown.png b/src/assets/images/mapping/treedown.png new file mode 100644 index 0000000..77933ce Binary files /dev/null and b/src/assets/images/mapping/treedown.png differ diff --git a/src/assets/images/mapping/truck.png b/src/assets/images/mapping/truck.png new file mode 100644 index 0000000..9a4d447 Binary files /dev/null and b/src/assets/images/mapping/truck.png differ diff --git a/src/assets/images/mapping/van.png b/src/assets/images/mapping/van.png new file mode 100644 index 0000000..3c499eb Binary files /dev/null and b/src/assets/images/mapping/van.png differ diff --git a/src/assets/images/mapping/velocimeter.png b/src/assets/images/mapping/velocimeter.png new file mode 100644 index 0000000..bd1786d Binary files /dev/null and b/src/assets/images/mapping/velocimeter.png differ diff --git a/src/assets/images/mapping/watercraft.png b/src/assets/images/mapping/watercraft.png new file mode 100644 index 0000000..a76dd1b Binary files /dev/null and b/src/assets/images/mapping/watercraft.png differ diff --git a/src/assets/images/mapping/workshop.png b/src/assets/images/mapping/workshop.png new file mode 100644 index 0000000..1990d31 Binary files /dev/null and b/src/assets/images/mapping/workshop.png differ diff --git a/src/assets/images/mapping/worksite.png b/src/assets/images/mapping/worksite.png new file mode 100644 index 0000000..47cd84a Binary files /dev/null and b/src/assets/images/mapping/worksite.png differ