Update frontend to use update models.

Add delete funtionality to Assets and Devices.
Fix bug with switching between views in assets list and devices list
Fix bug with editing owner user.
Fix bugs with dispatching.
This commit is contained in:
Mustafa Leithy 2018-03-13 11:09:10 +02:00
Родитель 23e0b213d5
Коммит 2a7eb9eed2
20 изменённых файлов: 171 добавлений и 249 удалений

Просмотреть файл

@ -2,24 +2,36 @@
Licensed under the MIT License. -->
<mat-toolbar color="primary">
<span>Add asset:</span>
<span>{{isEditable ? 'Edit Asset' : 'Add Asset'}}</span>
<span class="toolbar-spacer"></span>
<a *ngIf="isEditable" [appRoleLimiter]="Roles.Administrator" mat-icon-button mat-tooltip="Delete Asset" (click)="deleteAsset()">
<mat-icon>delete_forever</mat-icon>
</a>
</mat-toolbar>
<section>
<form (submit)="submit()">
<mat-input-container>
<input matInput placeholder="Asset Name" [(ngModel)]="asset.id" [disabled]="isEditable" name="id" required>
<mat-input-container *ngIf="isEditable">
<input matInput placeholder="Asset Id" [(ngModel)]="asset.id" disabled name="id">
</mat-input-container>
<mat-input-container>
<mat-select *ngIf="!isEditable" placeholder="Asset Type" [(ngModel)]="asset.assetType" name="assetType" required>
<input matInput placeholder="Asset Name" [(ngModel)]="asset.name" name="name" required>
</mat-input-container>
<mat-input-container>
<mat-select placeholder="Asset Type" [(ngModel)]="asset.assetType" name="assetType" [disabled]="isEditable" required>
<mat-option [value]="AssetType.Car">Car</mat-option>
<mat-option [value]="AssetType.Truck">Truck</mat-option>
</mat-select>
</mat-input-container>
<mat-input-container *ngIf="asset.trackingDeviceId">
<input matInput placeholder="Tracking Device" [(ngModel)]="asset.trackingDeviceName" name="trackingDevice" disabled>
<mat-input-container>
<mat-select placeholder="Linked Device" [(ngModel)]="asset.trackingDeviceId" name="trackingDeviceId">
<mat-option *ngFor="let device of devices" [value]="device.id">
{{device.name}}
</mat-option>
</mat-select>
</mat-input-container>
<div *ngIf="asset.assetType == AssetType.Truck" class="truck-container">
@ -66,7 +78,7 @@
<div class="pull-right">
<a mat-raised-button [routerLink]="['/assets']">Back</a>
<button *ngIf="!isEditable" mat-raised-button class="dispatch-button" type="submit">Submit</button>
<button mat-raised-button class="dispatch-button" type="submit">Submit</button>
</div>
</form>
</section>

Просмотреть файл

@ -7,8 +7,11 @@ import { Subscription } from 'rxjs/Subscription';
import { ToasterService } from 'angular2-toaster';
import { Asset, AssetType } from '../asset';
import { Roles } from '../../shared/role';
import { AssetProperties } from '../../shared/asset-properties';
import { AssetService } from '../asset.service';
import { Device } from '../../devices/device';
import { DeviceService } from '../../devices/device.service';
@Component({
selector: 'app-asset-editor-dialog',
@ -18,15 +21,18 @@ import { AssetService } from '../asset.service';
export class AssetEditorComponent implements OnInit, OnDestroy {
asset: Asset;
devices: Device[];
isEditable: boolean;
assetProperties: AssetProperties;
AssetType = AssetType;
private routerSubscription: Subscription;
private assetSubscription: Subscription;
Roles = Roles;
private isAlive: boolean;
constructor(private route: ActivatedRoute,
constructor(
private route: ActivatedRoute,
private router: Router,
private assetService: AssetService,
private deviceService: DeviceService,
private toasterService: ToasterService) {
this.asset = new Asset();
this.asset.assetType = AssetType.Car;
@ -34,21 +40,30 @@ export class AssetEditorComponent implements OnInit, OnDestroy {
}
ngOnInit() {
this.routerSubscription = this.route.params.subscribe(params => {
const id = params['id'];
if (id) {
this.isEditable = true;
this.assetSubscription = this.assetService.getAsset(id).subscribe(asset => this.asset = asset);
}
});
this.isAlive = true;
this.route.params
.takeWhile(() => this.isAlive)
.subscribe(params => {
const id = params['id'];
if (id) {
this.isEditable = true;
this.assetService.getAsset(id)
.takeWhile(() => this.isAlive)
.subscribe(asset => {
this.asset = asset;
this.assetProperties = this.asset.assetProperties;
});
}
});
this.deviceService.getDevices()
.takeWhile(() => this.isAlive)
.subscribe(devices => this.devices = devices);
}
ngOnDestroy() {
this.routerSubscription.unsubscribe();
if (this.assetSubscription && !this.assetSubscription.closed) {
this.assetSubscription.unsubscribe();
}
this.isAlive = false;
}
submit() {
@ -56,9 +71,19 @@ export class AssetEditorComponent implements OnInit, OnDestroy {
this.asset.assetProperties = this.assetProperties;
}
this.assetService.addAsset(this.asset)
.subscribe(() => this.router.navigate(['/assets']), error => {
this.toasterService.pop('error', 'Invalid Input', 'Asset ID already exists');
});
if (this.isEditable) {
this.assetService.updateAsset(this.asset)
.subscribe(() => this.router.navigate(['/assets']));
} else {
this.assetService.addAsset(this.asset)
.subscribe(() => this.router.navigate(['/assets']), error => {
this.toasterService.pop('error', 'Invalid Input', 'Asset ID already exists');
});
}
}
deleteAsset() {
this.assetService.deleteAsset(this.asset)
.subscribe(() => this.router.navigate(['/assets']));
}
}

Просмотреть файл

@ -8,8 +8,8 @@
<mat-icon>add_circle</mat-icon>
</a>
<button mat-icon-button>
<mat-icon>info</mat-icon>
</button>
<mat-icon>info</mat-icon>
</button>
</mat-toolbar>
<mat-input-container>
@ -17,18 +17,18 @@
</mat-input-container>
<mat-list>
<mat-list-item *ngFor="let asset of assets | async | filterList:filter" [class.active]="asset == selectedAsset && isAssetListSeleceted()">
<h3 mat-line (click)="showAsset(asset)">{{asset.id}}</h3>
<span mat-line class="subtle" (click)="showAsset(asset)">device: {{asset.trackingDeviceName}}</span>
<mat-list-item *ngFor="let asset of assetsList | filterList:filter" [class.active]="asset == selectedAsset && isAssetListSeleceted()">
<h3 mat-line (click)="showAsset(asset)">{{asset.name}}</h3>
<span mat-line class="subtle" (click)="showAsset(asset)">device: {{asset.trackingDevice ? asset.trackingDevice.name : ''}}</span>
<button mat-icon-button mat-tooltip='Trips' (click)="showTrips(asset)" [class.active]="asset == selectedAsset && isAssetTripsSelected()">
<mat-icon>trending_up</mat-icon>
</button>
<mat-icon>trending_up</mat-icon>
</button>
<button mat-icon-button mat-tooltip='Points' (click)="showPoints(asset)" [class.active]="asset == selectedAsset && isAssetPointsSelected()">
<mat-icon>gps_fixed</mat-icon>
</button>
<!--<a mat-icon-button [routerLink]="['/assets', asset.id]">
<mat-icon>mode_edit</mat-icon>
</a>-->
<mat-icon>gps_fixed</mat-icon>
</button>
<button mat-icon-button mat-tooltip='Edit' [routerLink]="['/assets', asset.id]">
<mat-icon>mode_edit</mat-icon>
</button>
</mat-list-item>
</mat-list>

Просмотреть файл

@ -1,61 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/* tslint:disable:no-unused-variable */
import { Injectable } from '@angular/core';
import { By } from '@angular/platform-browser';
import { async, ComponentFixture, TestBed, inject } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import { Asset, AssetType } from '../asset';
import { AssetEditorComponent } from '../asset-editor/asset-editor.component';
import { AssetListComponent } from './asset-list.component';
import { AssetService } from '../asset.service';
import { MapsService } from '../../maps/maps.service';
import 'hammerjs';
import 'rxjs/add/observable/of';
@Injectable()
export class MockAssetService {
getAssets(): Observable<Asset[]> {
return Observable.of([
{
id: 'bus99',
trackingDeviceName: 'cairo phone',
assetType: AssetType.Car,
assetProperties: {}
}
]);
}
}
describe('AssetListComponent', () => {
let component: AssetListComponent;
let fixture: ComponentFixture<AssetListComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AssetListComponent],
providers: [
MapsService,
{ provide: AssetService, useClass: MockAssetService }
],
imports: [
FormsModule
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AssetListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

Просмотреть файл

@ -29,8 +29,6 @@ enum SelectedAssetState {
styleUrls: ['./asset-list.component.css']
})
export class AssetListComponent implements OnInit, OnDestroy {
assets: Observable<Asset[]>;
points: Point[];
trips: Trip[];
filter: string;
@ -54,13 +52,16 @@ export class AssetListComponent implements OnInit, OnDestroy {
}
ngOnInit() {
this.assets = this.assetService.getAssets();
this.assets
this.assetService.getAssets()
.takeWhile(() => this.isAlive)
.skipWhile(assets => assets.length === 0)
.take(1)
.subscribe(assets => {
this.assetsList = assets;
this.assetsList = assets.sort((a, b) => {
if (a.name < b.name) { return -1; }
if (a.name > b.name) { return 1; }
return 0;
});
this.showAllAssets();
});
}
@ -80,7 +81,7 @@ export class AssetListComponent implements OnInit, OnDestroy {
} else {
this.selectedAsset = asset;
this.selectedAssetState = SelectedAssetState.PointsSelected;
this.toasterService.pop('info', '', 'Showing latest points of \" ' + this.selectedAsset.id + ' \"');
this.toasterService.pop('info', '', 'Showing latest points of \" ' + this.selectedAsset.name + ' \"');
this.unsubscribe();
this.subscription = this.assetService.getPoints(asset.id, this.selectedDateRange)
.subscribe(points => {
@ -98,7 +99,7 @@ export class AssetListComponent implements OnInit, OnDestroy {
this.selectedAsset = asset;
this.selectedAssetState = SelectedAssetState.ListSelected;
this.showAllAssets();
this.toasterService.pop('info', '', 'Following asset ' + this.selectedAsset.id);
this.toasterService.pop('info', '', 'Following asset ' + this.selectedAsset.name);
}
}
@ -108,10 +109,10 @@ export class AssetListComponent implements OnInit, OnDestroy {
.subscribe(points => {
this.mapsService.showAssetsPositions(points);
if (this.selectedAsset && !points[this.selectedAsset.id]) {
this.toasterService.pop('error', '', 'Can\'t find position of ' + this.selectedAsset.id);
if (this.selectedAsset && !points[this.selectedAsset.name]) {
this.toasterService.pop('error', '', 'Can\'t find position of ' + this.selectedAsset.name);
} else if (this.selectedAsset) {
this.mapsService.showAsset([this.selectedAsset, points[this.selectedAsset.id]]);
this.mapsService.showAsset([this.selectedAsset, points[this.selectedAsset.name]]);
}
});
}
@ -126,7 +127,7 @@ export class AssetListComponent implements OnInit, OnDestroy {
} else {
this.selectedAsset = asset;
this.selectedAssetState = SelectedAssetState.TripsSelected;
this.toasterService.pop('info', '', 'Showing latest trips of ' + this.selectedAsset.id);
this.toasterService.pop('info', '', 'Showing latest trips of ' + this.selectedAsset.name);
this.unsubscribe();
this.subscription = this.assetService.getTrips(asset.id, this.selectedDateRange)
.subscribe(trips => {

Просмотреть файл

@ -21,6 +21,14 @@ export class AssetService {
return this.dataService.post<Asset>('assets', asset);
}
updateAsset(asset: Asset): Observable<void> {
return this.dataService.put<Asset>('assets', asset.id, asset, true);
}
deleteAsset(asset: Asset): Observable<void> {
return this.dataService.delete<Asset>('assets', asset.id);
}
getAssets(): Observable<Asset[]> {
return this.dataService.get<Asset>('assets');
}
@ -57,7 +65,7 @@ export class AssetService {
}
return trips.filter(t => {
return t.startTimeStampUtc >= +dateRange.from && t.startTimeStampUtc <= +dateRange.to;
return Date.parse(t.startTimeUtc) >= +dateRange.from && Date.parse(t.startTimeUtc) <= +dateRange.to;
});
});
}

Просмотреть файл

@ -2,8 +2,11 @@
Licensed under the MIT License. -->
<mat-toolbar color="primary">
<span *ngIf="!isEditing">Add device</span>
<span *ngIf="isEditing">Edit Device</span>
<span>{{isEditing ? 'Edit Device' : 'Add Device'}}</span>
<span class="toolbar-spacer"></span>
<a *ngIf="isEditing" [appRoleLimiter]="Roles.Administrator" mat-icon-button mat-tooltip="Delete Asset" (click)="deleteDevice()">
<mat-icon>delete_forever</mat-icon>
</a>
</mat-toolbar>
<section>
@ -39,7 +42,7 @@
<mat-input-container>
<mat-select placeholder="Linked Asset" [(ngModel)]="device.assetId" name="assetId">
<mat-option *ngFor="let asset of assets" [value]="asset.id">
{{asset.id}}
{{asset.name}}
</mat-option>
</mat-select>
</mat-input-container>

Просмотреть файл

@ -9,6 +9,7 @@ import { ToasterService } from 'angular2-toaster';
import { HubConnection } from '@aspnet/signalr-client';
import { UUID } from 'angular2-uuid';
import { Roles } from '../../shared/role';
import { Asset } from '../../assets/asset';
import { AssetService } from '../../assets/asset.service';
import { Device } from '../device';
@ -26,6 +27,7 @@ export class DeviceEditorComponent implements OnInit, OnDestroy {
isEditing: boolean;
assets: Asset[];
deviceToken = '';
Roles = Roles;
private routerSubscription: Subscription;
private assetsSubscription: Subscription;
@ -111,4 +113,9 @@ export class DeviceEditorComponent implements OnInit, OnDestroy {
data: this.deviceService.getProvisioningQrCodeUrl(this.nonce)
});
}
deleteDevice() {
this.deviceService.deleteDevice(this.device)
.subscribe(() => this.router.navigate(['/devices']));
}
}

Просмотреть файл

@ -19,13 +19,13 @@
<mat-list>
<mat-list-item *ngFor="let device of devices | async | filterList:filter" [class.active]="device == selectedDevice && isDeviceListSelected()">
<h3 mat-line (click)="showDevice(device)">{{device.name}}</h3>
<span mat-line class="subtle" (click)="showDevice(device)">asset: {{device.assetId}}</span>
<span mat-line class="subtle" (click)="showDevice(device)">asset: {{device.asset ? device.asset.name : ''}}</span>
<button mat-icon-button mat-tooltip='Points' (click)="showPoints(device)" [class.active]="device == selectedDevice && isDevicePointSelected()">
<mat-icon>gps_fixed</mat-icon>
</button>
<a [appRoleLimiter]="Roles.Administrator" mat-icon-button mat-tooltip="Edit" [routerLink]="['/devices', device.id]">
<mat-icon>mode_edit</mat-icon>
</a>
<button mat-icon-button mat-tooltip='Points' (click)="showPoints(device)" [class.active]="device == selectedDevice && isDevicePointSelected()">
<mat-icon>gps_fixed</mat-icon>
</button>
</mat-list-item>
</mat-list>

Просмотреть файл

@ -1,59 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/* tslint:disable:no-unused-variable */
import { Injectable } from '@angular/core';
import { By } from '@angular/platform-browser';
import { async, ComponentFixture, TestBed, inject } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import { Device } from '../device';
import { DeviceEditorComponent } from '../device-editor/device-editor.component';
import { DeviceListComponent } from './device-list.component';
import { DeviceService } from '../device.service';
import { MapsService } from '../../maps/maps.service';
import 'hammerjs';
import 'rxjs/add/observable/of';
@Injectable()
export class MockDeviceService {
getDevices(): Observable<Device[]> {
return Observable.of([
{
id: 'cairo phone',
assetId: 'bus66'
}
]);
}
}
describe('DeviceListComponent', () => {
let component: DeviceListComponent;
let fixture: ComponentFixture<DeviceListComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [DeviceListComponent, DeviceEditorComponent],
providers: [
MapsService,
{ provide: DeviceService, useClass: MockDeviceService }
],
imports: [
FormsModule
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DeviceListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

Просмотреть файл

@ -57,6 +57,10 @@ export class DeviceService {
return this.dataService.put<Device>('devices', device.id, device, true);
}
deleteDevice(device: Device): Observable<void> {
return this.dataService.delete<Device>('devices', device.id);
}
getProvisioningQrCodeUrl(nonce: String): string {
return `${this.envSettingsService.getEnvironmentVariable(EnvironmentSettings.backendUrl)}/devices/qrcode?nonce=${nonce}`;
}

Просмотреть файл

@ -23,7 +23,7 @@
<mat-input-container>
<mat-select placeholder="Asset" [(ngModel)]="selectedAsset" name="assetId" required="true">
<mat-option *ngFor="let asset of assets" [value]="asset" (click)="checkSelected(asset)">
{{asset.id}}
{{asset.name}}
</mat-option>
</mat-select>
</mat-input-container>

Просмотреть файл

@ -134,7 +134,6 @@ export class DispatchingEditorComponent implements OnInit, OnDestroy {
}
showRoute() {
if (this.pinsAdded.length < 2 || this.pinsAdded.length > 20) {
this.toasterService.pop('error', 'Invalid Input', 'Number of Points per route has to be between 2 and 20');
return;

Просмотреть файл

@ -47,7 +47,7 @@
<h3>Available Assets:</h3>
<mat-list>
<mat-list-item *ngFor="let asset of assets">
<mat-checkbox (change)="onAssetCheckChanged($event)" [checked]="asset.checked" [name]="asset.id">{{asset.id}}</mat-checkbox>
<mat-checkbox (change)="onAssetCheckChanged($event)" [checked]="asset.checked" [name]="asset.id">{{asset.name}}</mat-checkbox>
</mat-list-item>
</mat-list>

Просмотреть файл

@ -20,10 +20,6 @@
<input matInput placeholder="Location Pin" [(ngModel)]="locationString" name="locationPin" disabled required>
</mat-input-container>
<mat-input-container *ngIf="isEditable">
<input matInput placeholder="Location Type" [(ngModel)]="locationTypeString" name="interestLevel" disabled>
</mat-input-container>
<div class="pull-right">
<a mat-raised-button [routerLink]="['/locations']">Back</a>
<button mat-raised-button class="dispatch-button " type="submit">Submit</button>

Просмотреть файл

@ -49,7 +49,6 @@ export class LocationEditorComponent implements OnInit, OnDestroy {
if (location) {
this.location = location;
this.setlocationString();
this.setLocationTypeString();
this.mapService.showLocationsPositions([this.location]);
}
});
@ -97,13 +96,9 @@ export class LocationEditorComponent implements OnInit, OnDestroy {
}
if (this.isEditable) {
if (this.didLocationChange) {
this.location.interestLevel = InterestLevel.Manual;
}
this.locationService.updateLocation(this.location)
.subscribe(() => this.router.navigate(['/locations']));
} else {
this.location.interestLevel = InterestLevel.Manual;
this.locationService.addLocation(this.location)
.subscribe(() => this.router.navigate(['/locations']));
}
@ -112,12 +107,4 @@ export class LocationEditorComponent implements OnInit, OnDestroy {
private setlocationString() {
this.locationString = '(' + this.location.latitude + ' , ' + this.location.longitude + ' )';
}
private setLocationTypeString() {
if (this.location.interestLevel === InterestLevel.Manual) {
this.locationTypeString = 'Created/Edited Manually';
} else {
this.locationTypeString = 'Automatically Generated';
}
}
}

Просмотреть файл

@ -433,7 +433,7 @@ export class BingMapsService {
strokeThickness: 2
});
this.map.entities.push(polyline);
this.locationsLayer.add(polyline);
this.centerMap(points[0]);
}
});
@ -441,13 +441,7 @@ export class BingMapsService {
showDispatchingRoutePins(locations: Location[]) {
this.load().then(() => {
this.resetMap();
this.locationsLayer.setVisible(true);
this.locationsLayer.clear();
let index = 1;
locations.forEach(location => {
location.name = this.getNormalizedLocationName(location) + ' (' + index++ + ')';
this.showLocation(location);
});
});
@ -534,9 +528,9 @@ export class BingMapsService {
/* END POINT FUNCTIONS */
/* ASSET FUNCTIONS */
showAssets(positions: [Asset, TrackingPoint][], centerMap: boolean): void {
showAssets(positions: [Asset, TrackingPoint][], centerMap: boolean, clearMap: boolean): void {
this.load().then(() => {
if (centerMap) {
if (clearMap) {
this.resetMap();
this.assetsLayer.setVisible(true);
}
@ -551,7 +545,7 @@ export class BingMapsService {
points.push(p);
const location = new Microsoft.Maps.Location(p.latitude, p.longitude);
const pushpin = new Microsoft.Maps.Pushpin(location, {
title: position[0].id,
title: position[0].name,
subTitle: this.timeConverter(p.time),
icon:
(position[0].assetType === AssetType.Car
@ -570,9 +564,9 @@ export class BingMapsService {
/* END ASSET FUNCTIONS */
/* DEVICE FUNCTIONS */
showDevices(positions: Map<string, TrackingPoint>, centerMap: boolean): void {
showDevices(positions: Map<string, TrackingPoint>, centerMap: boolean, clearMap: boolean): void {
this.load().then(() => {
if (centerMap) {
if (clearMap) {
this.resetMap();
this.devicesLayer.setVisible(true);
}
@ -666,7 +660,7 @@ export class BingMapsService {
const tripLegLocations = [];
// Show the starting stop in a leg if its different from the ending stop of the last
if (!previousTripLeg || previousTripLeg.endLocationId !== leg.startLocationId) {
if (!previousTripLeg || previousTripLeg.endLocation.id !== leg.startLocation.id) {
this.showTripLocation(leg.startLocation);
tripLegLocations.push(new Microsoft.Maps.Location(
leg.startLocation.latitude,
@ -699,7 +693,7 @@ export class BingMapsService {
previousTripLeg = leg;
// Draw a dotted line between trip leg stop locations, if they are not the same.
if (previousTripLeg && previousTripLeg.endLocationId !== leg.startLocationId) {
if (previousTripLeg && previousTripLeg.endLocation.id !== leg.startLocation.id) {
const startPoint = new Microsoft.Maps.Location(
leg.startLocation.latitude,
leg.startLocation.longitude
@ -747,7 +741,7 @@ export class BingMapsService {
}
// Draw a dotted line between trip leg stop locations, if they are not the same.
if (previousTripLeg && previousTripLeg.endLocationId !== leg.startLocationId) {
if (previousTripLeg && previousTripLeg.endLocation.id !== leg.startLocation.id) {
const startPoint = new Microsoft.Maps.Location(
leg.startLocation.latitude,
leg.startLocation.longitude

Просмотреть файл

@ -5,6 +5,7 @@ import { Local } from 'protractor/built/driverProviders';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Point } from '../shared/point';
@ -18,33 +19,33 @@ import { Asset } from '../assets/asset';
@Injectable()
export class MapsService {
private points = new Subject<Point[]>();
private trips = new Subject<Trip[]>();
private trip = new Subject<Trip>();
private geofence = new Subject<Geofence>();
private geofences = new Subject<Geofence[]>();
private currentDrawEnd = new Subject();
private geofenceCircularRadiusChange = new Subject<number>();
private geofenceCircularDraw = new Subject<[Point, number]>();
private points = new ReplaySubject<Point[]>();
private trips = new ReplaySubject<Trip[]>();
private trip = new ReplaySubject<Trip>();
private geofence = new ReplaySubject<Geofence>();
private geofences = new ReplaySubject<Geofence[]>();
private currentDrawEnd = new ReplaySubject();
private geofenceCircularRadiusChange = new ReplaySubject<number>();
private geofenceCircularDraw = new ReplaySubject<[Point, number]>();
private geofenceCircularDrawResult = new BehaviorSubject<Point>(null);
private geofencePolygonDraw = new Subject<Point[]>();
private geofencePolygonDraw = new ReplaySubject<Point[]>();
private geofencePolygonDrawResult = new BehaviorSubject<Point[]>(new Array<Point>());
private assetsPositions = new Subject<[{ [key: string]: TrackingPoint }, boolean]>();
private assetPosition = new Subject<[Asset, TrackingPoint]>();
private devicesPositions = new Subject<Map<string, TrackingPoint>>();
private devicePosition = new Subject<[string, TrackingPoint]>();
private dispatchingPinsDraw = new Subject<Location[]>();
private assetsPositions = new ReplaySubject<[{ [key: string]: TrackingPoint }, boolean]>();
private assetPosition = new ReplaySubject<[Asset, TrackingPoint]>();
private devicesPositions = new ReplaySubject<[Map<string, TrackingPoint>, boolean]>();
private devicePosition = new ReplaySubject<[string, TrackingPoint]>();
private dispatchingPinsDraw = new ReplaySubject<Location[]>();
private dispatchingPinsDrawResult = new BehaviorSubject<Location[]>(new Array<Location>());
private dispatchingPoints = new Subject<Point[]>();
private dispatchingAlternativePoints = new Subject<Point[]>();
private dispatchingPins = new Subject<Location[]>();
private locationsPositions = new Subject<Location[]>();
private locationPosition = new Subject<Location>();
private locationPinDraw = new Subject<Location>();
private locationPinResult = new Subject<Location>();
private itineraryPoint = new Subject<Point>();
private locationSearchQuery = new Subject<string>();
private locationSearchResult = new Subject<Point>();
private dispatchingPoints = new ReplaySubject<Point[]>();
private dispatchingAlternativePoints = new ReplaySubject<Point[]>();
private dispatchingPins = new ReplaySubject<Location[]>();
private locationsPositions = new ReplaySubject<Location[]>();
private locationPosition = new ReplaySubject<Location>();
private locationPinDraw = new ReplaySubject<Location>();
private locationPinResult = new ReplaySubject<Location>();
private itineraryPoint = new ReplaySubject<Point>();
private locationSearchQuery = new ReplaySubject<string>();
private locationSearchResult = new ReplaySubject<Point>();
private routeColor: number;
@ -90,8 +91,8 @@ export class MapsService {
this.assetPosition.next(position);
}
showDevicesPositions(positions: Map<string, TrackingPoint>) {
this.devicesPositions.next(positions);
showDevicesPositions(positions: Map<string, TrackingPoint>, inBackground = false) {
this.devicesPositions.next([positions, inBackground]);
}
showDevice(position: [string, TrackingPoint]) {
@ -107,11 +108,11 @@ export class MapsService {
}
startLocationPinDraw() {
this.locationPinDraw.next();
this.locationPinDraw.next(null);
}
endCurrentDraw() {
this.currentDrawEnd.next();
this.currentDrawEnd.next(null);
}
showTrips(trips: Trip[]) {
@ -156,7 +157,7 @@ export class MapsService {
return this.assetPosition.asObservable();
}
getDevicesPositions(): Observable<Map<string, TrackingPoint>> {
getDevicesPositions(): Observable<[Map<string, TrackingPoint>, boolean]> {
return this.devicesPositions.asObservable();
}

Просмотреть файл

@ -147,24 +147,29 @@ export class MapsComponent implements OnInit {
const mappedAssets = new Array<[Asset, TrackingPoint]>();
for (const k of Object.keys(positions)) {
const value = positions[k];
const asset = assets.find(val => val.id === k);
mappedAssets.push([asset, value]);
const asset = assets.find(val => val.name === k);
if (asset) {
mappedAssets.push([asset, value]);
}
}
this.bingMapsService.showAssets(
mappedAssets,
!data[1] && lastPositionCall !== 'assets'
!data[1] && lastPositionCall !== 'assets',
!data[1]
);
lastPositionCall = 'assets';
});
this.mapsService.getDevicesPositions().subscribe(positions => {
this.mapsService.getDevicesPositions().subscribe(data => {
this.bingMapsService.showDevices(
positions,
lastPositionCall !== 'devcies'
data[0],
!data[1] && lastPositionCall !== 'devices',
!data[1]
);
lastPositionCall = 'devcies';
lastPositionCall = 'devices';
});
this.mapsService.getLocationsPositions().subscribe(positions => {

Просмотреть файл

@ -25,7 +25,7 @@
<a class="partial-button" (click)="regenerateToken()">Regenerate</a>
</mat-input-container>
<mat-input-container [hidden]="user.role.name === 'Owner'">
<mat-input-container *ngIf="user.role.name !== 'Owner'">
<mat-select placeholder="Role" [(ngModel)]="user.role.name" name="role" [required]="isAddingNew">
<mat-option *ngFor="let role of roles" [value]="role.name">
{{role.name}}