mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-12-27 02:09:16 +02:00
adding zoom control and multiple layer support to maps
This commit is contained in:
parent
88a2460d48
commit
875f300ba1
@ -163,8 +163,15 @@ export class ConfigDiagnostics {
|
||||
throw new Error('Mapbox needs a valid api key.');
|
||||
}
|
||||
if (map.mapProvider === ClientConfig.MapProviders.Custom &&
|
||||
(!map.tileUrl || map.tileUrl.length === 0)) {
|
||||
throw new Error('Custom maps need a valid tile url');
|
||||
(!map.customLayers || map.customLayers.length === 0)) {
|
||||
throw new Error('Custom maps need at least one valid layer');
|
||||
}
|
||||
if (map.mapProvider === ClientConfig.MapProviders.Custom) {
|
||||
map.customLayers.forEach(l => {
|
||||
if (!l.url || l.url.length === 0) {
|
||||
throw new Error('Custom maps url need to be a valid layer');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,11 +31,16 @@ export module ClientConfig {
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
export interface MapLayers {
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface MapConfig {
|
||||
enabled: boolean;
|
||||
mapProvider: MapProviders;
|
||||
mapboxAccessToken: string;
|
||||
tileUrl: string;
|
||||
customLayers: MapLayers[];
|
||||
}
|
||||
|
||||
export interface ThumbnailConfig {
|
||||
@ -125,7 +130,7 @@ export class PublicConfigClass {
|
||||
enabled: true,
|
||||
mapProvider: ClientConfig.MapProviders.OpenStreetMap,
|
||||
mapboxAccessToken: '',
|
||||
tileUrl: ''
|
||||
customLayers: [{name: 'street', url: ''}]
|
||||
},
|
||||
RandomPhoto: {
|
||||
enabled: true
|
||||
|
@ -90,12 +90,10 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
|
||||
}
|
||||
|
||||
public containerWidth() {
|
||||
console.log(this.photoFrameDim);
|
||||
return this.root.nativeElement.width;
|
||||
}
|
||||
|
||||
public containerHeight() {
|
||||
console.log(this.photoFrameDim);
|
||||
return this.root.nativeElement.height;
|
||||
}
|
||||
|
||||
|
@ -10,46 +10,70 @@
|
||||
<yaga-map #yagaMap
|
||||
[style.width.px]="mapDimension.width"
|
||||
[style.height.px]="mapDimension.height">
|
||||
<yaga-polyline *ngFor="let path of paths"
|
||||
[latLngs]="path">
|
||||
</yaga-polyline>
|
||||
<yaga-marker
|
||||
*ngFor="let path of paths"
|
||||
[lat]="path[0].lat"
|
||||
[lng]="path[1].lng">
|
||||
</yaga-marker>
|
||||
<yaga-marker
|
||||
*ngFor="let photo of mapPhotos"
|
||||
[lat]="photo.lat"
|
||||
[lng]="photo.lng">
|
||||
<yaga-icon
|
||||
*ngIf="photo.iconUrl"
|
||||
[iconUrl]="photo.iconUrl"
|
||||
[iconSize]="yagaMap.zoom < 15 ? smallIconSize : iconSize"
|
||||
></yaga-icon>
|
||||
<yaga-popup
|
||||
(open)="loadPreview(photo)"
|
||||
[minWidth]="photo.preview.width">
|
||||
<img *ngIf="photo.preview.thumbnail.Src"
|
||||
[style.width.px]="photo.preview.width"
|
||||
[style.height.px]="photo.preview.height"
|
||||
[src]="photo.preview.thumbnail.Src | fixOrientation:photo.orientation | async">
|
||||
<div class="preview-loading"
|
||||
*ngIf="!photo.preview.thumbnail.Src"
|
||||
[style.width.px]="photo.preview.width"
|
||||
[style.height.px]="photo.preview.height">
|
||||
|
||||
<yaga-layers-control
|
||||
position="bottomright">
|
||||
|
||||
<yaga-feature-group
|
||||
[caption]="'path'"
|
||||
*ngIf="paths.length>0"
|
||||
yaga-overlay-layer="'path'">
|
||||
<yaga-polyline
|
||||
*ngFor="let path of paths"
|
||||
[latLngs]="path">
|
||||
</yaga-polyline>
|
||||
<yaga-marker
|
||||
*ngFor="let path of paths"
|
||||
[lat]="path[0].lat"
|
||||
[lng]="path[1].lng">
|
||||
</yaga-marker>
|
||||
</yaga-feature-group>
|
||||
<yaga-feature-group
|
||||
[caption]="'photos'"
|
||||
yaga-overlay-layer="'photos'">
|
||||
<yaga-marker [title]="photo.name"
|
||||
*ngFor="let photo of mapPhotos"
|
||||
[lat]="photo.lat"
|
||||
[lng]="photo.lng">
|
||||
<yaga-icon
|
||||
*ngIf="photo.iconUrl"
|
||||
[iconUrl]="photo.iconUrl"
|
||||
[iconSize]="yagaMap.zoom < 15 ? smallIconSize : iconSize"
|
||||
></yaga-icon>
|
||||
<yaga-popup
|
||||
(open)="loadPreview(photo)"
|
||||
[minWidth]="photo.preview.width">
|
||||
<img *ngIf="photo.preview.thumbnail.Src"
|
||||
[style.width.px]="photo.preview.width"
|
||||
[style.height.px]="photo.preview.height"
|
||||
[src]="photo.preview.thumbnail.Src | fixOrientation:photo.orientation | async">
|
||||
<div class="preview-loading"
|
||||
*ngIf="!photo.preview.thumbnail.Src"
|
||||
[style.width.px]="photo.preview.width"
|
||||
[style.height.px]="photo.preview.height">
|
||||
<span class="oi"
|
||||
[ngClass]="photo.preview.thumbnail.Error ? 'oi-warning' : 'oi-picture'"
|
||||
aria-hidden="true">
|
||||
</span>
|
||||
</div>
|
||||
</yaga-popup>
|
||||
</yaga-marker>
|
||||
</div>
|
||||
</yaga-popup>
|
||||
</yaga-marker>
|
||||
|
||||
</yaga-feature-group>
|
||||
<ng-container *ngFor="let l of mapService.Layers">
|
||||
<yaga-tile-layer yaga-base-layer
|
||||
[caption]="l.name"
|
||||
[url]="l.url"></yaga-tile-layer>
|
||||
</ng-container>
|
||||
|
||||
</yaga-layers-control>
|
||||
<yaga-zoom-control position="bottomright">
|
||||
|
||||
</yaga-zoom-control>
|
||||
<yaga-attribution-control
|
||||
prefix=""
|
||||
[attributions]="mapService.Attributions">
|
||||
</yaga-attribution-control>
|
||||
<yaga-tile-layer [url]="mapService.MapLayer"></yaga-tile-layer>
|
||||
</yaga-map>
|
||||
</div>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Component, ElementRef, HostListener, Input, OnChanges, ViewChild, AfterViewInit} from '@angular/core';
|
||||
import {AfterViewInit, Component, ElementRef, HostListener, Input, OnChanges, OnInit, ViewChild} from '@angular/core';
|
||||
import {PhotoDTO} from '../../../../../../common/entities/PhotoDTO';
|
||||
import {Dimension} from '../../../../model/IRenderable';
|
||||
import {FullScreenService} from '../../fullscreen.service';
|
||||
@ -23,9 +23,9 @@ import {FixOrientationPipe} from '../../../../pipes/FixOrientationPipe';
|
||||
})
|
||||
export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
|
||||
|
||||
|
||||
@Input() photos: PhotoDTO[];
|
||||
@Input() gpxFiles: FileDTO[];
|
||||
private startPosition: Dimension = null;
|
||||
public lightboxDimension: Dimension = <Dimension>{top: 0, left: 0, width: 0, height: 0};
|
||||
public mapDimension: Dimension = <Dimension>{top: 0, left: 0, width: 0, height: 0};
|
||||
public visible = false;
|
||||
@ -33,27 +33,34 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
|
||||
public opacity = 1.0;
|
||||
mapPhotos: MapPhoto[] = [];
|
||||
paths: LatLng[][] = [];
|
||||
|
||||
@ViewChild('root', {static: false}) elementRef: ElementRef;
|
||||
@ViewChild('yagaMap', {static: false}) yagaMap: MapComponent;
|
||||
|
||||
@ViewChild('root', {static: true}) elementRef: ElementRef;
|
||||
@ViewChild('yagaMap', {static: true}) yagaMap: MapComponent;
|
||||
public smallIconSize = new Point(Config.Client.Thumbnail.iconSize * 0.75, Config.Client.Thumbnail.iconSize * 0.75);
|
||||
public iconSize = new Point(Config.Client.Thumbnail.iconSize, Config.Client.Thumbnail.iconSize);
|
||||
private startPosition: Dimension = null;
|
||||
|
||||
constructor(public fullScreenService: FullScreenService,
|
||||
private thumbnailService: ThumbnailManagerService,
|
||||
public mapService: MapService) {
|
||||
}
|
||||
|
||||
|
||||
ngOnChanges() {
|
||||
if (this.visible === false) {
|
||||
return;
|
||||
}
|
||||
this.showImages();
|
||||
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
|
||||
let i = 0;
|
||||
this.yagaMap.eachLayer(l => {
|
||||
if (i >= 3 || (this.paths.length === 0 && i >= 2)) {
|
||||
this.yagaMap.removeLayer(l);
|
||||
}
|
||||
++i;
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('window:resize', ['$event'])
|
||||
@ -75,7 +82,6 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async show(position: Dimension) {
|
||||
this.hideImages();
|
||||
this.visible = true;
|
||||
@ -145,6 +151,7 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
|
||||
const iconTh = this.thumbnailService.getIcon(new MediaIcon(p));
|
||||
iconTh.Visible = true;
|
||||
const obj: MapPhoto = {
|
||||
name: p.name,
|
||||
lat: p.metadata.positionData.GPSData.latitude,
|
||||
lng: p.metadata.positionData.GPSData.longitude,
|
||||
iconThumbnail: iconTh,
|
||||
@ -175,29 +182,6 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
|
||||
|
||||
}
|
||||
|
||||
private centerMap() {
|
||||
if (this.mapPhotos.length > 0) {
|
||||
this.yagaMap.fitBounds(<any>this.mapPhotos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async loadGPXFiles(): Promise<void> {
|
||||
this.paths = [];
|
||||
for (let i = 0; i < this.gpxFiles.length; i++) {
|
||||
const file = this.gpxFiles[i];
|
||||
const path = await this.mapService.getMapPath(file);
|
||||
if (file !== this.gpxFiles[i]) { // check race condition
|
||||
return;
|
||||
}
|
||||
if (path.length === 0) {
|
||||
continue;
|
||||
}
|
||||
this.paths.push(<LatLng[]>path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public loadPreview(mp: MapPhoto) {
|
||||
mp.preview.thumbnail.load();
|
||||
mp.preview.thumbnail.CurrentlyWaiting = true;
|
||||
@ -211,15 +195,6 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
|
||||
this.mapPhotos = [];
|
||||
}
|
||||
|
||||
|
||||
private getScreenWidth() {
|
||||
return window.innerWidth;
|
||||
}
|
||||
|
||||
private getScreenHeight() {
|
||||
return window.innerHeight;
|
||||
}
|
||||
|
||||
@HostListener('window:keydown', ['$event'])
|
||||
onKeyPress(e: KeyboardEvent) {
|
||||
if (this.visible !== true) {
|
||||
@ -241,10 +216,40 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
|
||||
}
|
||||
}
|
||||
|
||||
private centerMap() {
|
||||
if (this.mapPhotos.length > 0) {
|
||||
this.yagaMap.fitBounds(<any>this.mapPhotos);
|
||||
}
|
||||
}
|
||||
|
||||
private async loadGPXFiles(): Promise<void> {
|
||||
this.paths = [];
|
||||
for (let i = 0; i < this.gpxFiles.length; i++) {
|
||||
const file = this.gpxFiles[i];
|
||||
const path = await this.mapService.getMapPath(file);
|
||||
if (file !== this.gpxFiles[i]) { // check race condition
|
||||
return;
|
||||
}
|
||||
if (path.length === 0) {
|
||||
continue;
|
||||
}
|
||||
this.paths.push(<LatLng[]>path);
|
||||
}
|
||||
}
|
||||
|
||||
private getScreenWidth() {
|
||||
return window.innerWidth;
|
||||
}
|
||||
|
||||
private getScreenHeight() {
|
||||
return window.innerHeight;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
export interface MapPhoto {
|
||||
name: string;
|
||||
lat: number;
|
||||
lng: number;
|
||||
iconUrl?: string;
|
||||
|
@ -4,30 +4,27 @@ import {FileDTO} from '../../../../../common/entities/FileDTO';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import MapLayers = ClientConfig.MapLayers;
|
||||
|
||||
@Injectable()
|
||||
export class MapService {
|
||||
|
||||
private static readonly OSMLAYERS = [{name: 'street', url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'}];
|
||||
private static MAPBOXLAYERS: MapLayers[] = [];
|
||||
|
||||
constructor(private networkService: NetworkService) {
|
||||
}
|
||||
|
||||
|
||||
public async getMapPath(file: FileDTO): Promise<MapPath[]> {
|
||||
const filePath = Utils.concatUrls(file.directory.path, file.directory.name, file.name);
|
||||
const gpx = await this.networkService.getXML('/gallery/content/' + filePath);
|
||||
const elements = gpx.getElementsByTagName('trkpt');
|
||||
const points: MapPath[] = [];
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
points.push({
|
||||
lat: parseFloat(elements[i].getAttribute('lat')),
|
||||
lng: parseFloat(elements[i].getAttribute('lon'))
|
||||
});
|
||||
MapService.MAPBOXLAYERS = [{
|
||||
name: 'street', url: 'https://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token='
|
||||
+ Config.Client.Map.mapboxAccessToken
|
||||
}, {
|
||||
name: 'satellite', url: 'https://api.tiles.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}.png?access_token='
|
||||
+ Config.Client.Map.mapboxAccessToken
|
||||
}, {
|
||||
name: 'hybrid', url: 'https://api.tiles.mapbox.com/v4/mapbox.streets-satellite/{z}/{x}/{y}.png?access_token='
|
||||
+ Config.Client.Map.mapboxAccessToken
|
||||
}
|
||||
return points;
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public get ShortAttributions(): string[] {
|
||||
const yaga = '<a href="https://yagajs.org" title="YAGA">YAGA</a>';
|
||||
const lf = '<a href="https://leaflet-ng2.yagajs.org" title="Leaflet in Angular2">leaflet-ng2</a>';
|
||||
@ -62,14 +59,33 @@ export class MapService {
|
||||
}
|
||||
|
||||
public get MapLayer(): string {
|
||||
if (Config.Client.Map.mapProvider === ClientConfig.MapProviders.Custom) {
|
||||
return Config.Client.Map.tileUrl;
|
||||
return this.Layers[0].url;
|
||||
}
|
||||
|
||||
public get Layers(): { name: string, url: string }[] {
|
||||
switch (Config.Client.Map.mapProvider) {
|
||||
case ClientConfig.MapProviders.Custom:
|
||||
return Config.Client.Map.customLayers;
|
||||
case ClientConfig.MapProviders.Mapbox:
|
||||
return MapService.MAPBOXLAYERS;
|
||||
case ClientConfig.MapProviders.OpenStreetMap:
|
||||
return MapService.OSMLAYERS;
|
||||
}
|
||||
if (Config.Client.Map.mapProvider === ClientConfig.MapProviders.Mapbox) {
|
||||
return 'https://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token='
|
||||
+ Config.Client.Map.mapboxAccessToken;
|
||||
}
|
||||
|
||||
|
||||
public async getMapPath(file: FileDTO): Promise<MapPath[]> {
|
||||
const filePath = Utils.concatUrls(file.directory.path, file.directory.name, file.name);
|
||||
const gpx = await this.networkService.getXML('/gallery/content/' + filePath);
|
||||
const elements = gpx.getElementsByTagName('trkpt');
|
||||
const points: MapPath[] = [];
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
points.push({
|
||||
lat: parseFloat(elements[i].getAttribute('lat')),
|
||||
lng: parseFloat(elements[i].getAttribute('lon'))
|
||||
});
|
||||
}
|
||||
return 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
return points;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -67,6 +67,9 @@ export abstract class SettingsComponent<T extends { [key: string]: any }, S exte
|
||||
if (!newSettings) {
|
||||
return false;
|
||||
}
|
||||
if (Array.isArray(original) && original.length !== newSettings.length) {
|
||||
return false;
|
||||
}
|
||||
const keys = Object.keys(newSettings);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
|
@ -0,0 +1,9 @@
|
||||
.custom-layer-info {
|
||||
margin-top: -2rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.custom-layer-container {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
@ -7,12 +7,12 @@
|
||||
class="switch"
|
||||
name="enabled"
|
||||
[switch-on-color]="'success'"
|
||||
[switch-inverse]="'inverse'"
|
||||
[switch-inverse]="true"
|
||||
[switch-off-text]="text.Disabled"
|
||||
[switch-on-text]="text.Enabled"
|
||||
[switch-disabled]="inProgress"
|
||||
[switch-handle-width]="'100'"
|
||||
[switch-label-width]="'20'"
|
||||
[switch-handle-width]="100"
|
||||
[switch-label-width]="20"
|
||||
[(ngModel)]="settings.enabled">
|
||||
</bSwitch>
|
||||
</div>
|
||||
@ -33,15 +33,43 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" *ngIf="settings.mapProvider === MapProviders.Custom">
|
||||
<label class="col-md-2 control-label" for="tileUrl" i18n>Map tile url</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" class="form-control" placeholder="http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
[(ngModel)]="settings.tileUrl"
|
||||
name="tileUrl" id="tileUrl" required>
|
||||
<small class="form-text text-muted">
|
||||
<ng-container i18n>The map module will use this url to fetch the map tiles.</ng-container>
|
||||
</small>
|
||||
<div class="container custom-layer-container" *ngIf="settings.mapProvider === MapProviders.Custom">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th i18n>Name</th>
|
||||
<th i18n>Tile Url*</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr *ngFor="let layer of settings.customLayers; let i = index">
|
||||
<td><input type="text" class="form-control" placeholder="Street"
|
||||
[(ngModel)]="layer.name"
|
||||
[name]="'tileName-'+i" [id]="'tileName-'+i" required></td>
|
||||
<td>
|
||||
<input type="text" class="form-control" placeholder="http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
[(ngModel)]="layer.url"
|
||||
[name]="'tileUrl-'+i" [id]="'tileUrl-'+i" required>
|
||||
</td>
|
||||
<td>
|
||||
<button [disabled]="settings.customLayers.length == 1" (click)="removeLayer(layer)"
|
||||
[ngClass]="settings.customLayers.length > 1? 'btn-danger':'btn-secondary'"
|
||||
class="btn float-right">
|
||||
<span class="oi oi-trash" aria-hidden="true" aria-label="Delete"></span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="row justify-content-end">
|
||||
<small class="form-text text-muted custom-layer-info">
|
||||
<ng-container i18n>*The map module will use these urls to fetch the map tiles.</ng-container>
|
||||
</small>
|
||||
</div>
|
||||
<div class="row justify-content-end">
|
||||
<button class="btn btn-primary"
|
||||
(click)="addNewLayer()" i18n>+ Add Layer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -52,7 +80,8 @@
|
||||
[(ngModel)]="settings.mapboxAccessToken"
|
||||
name="mapboxAccessToken" id="mapboxAccessToken" required>
|
||||
<small class="form-text text-muted">
|
||||
<ng-container i18n>MapBox needs an access token to work, create one at </ng-container><a href="https://www.mapbox.com">https://www.mapbox.com</a>.
|
||||
<ng-container i18n>MapBox needs an access token to work, create one at</ng-container>
|
||||
<a href="https://www.mapbox.com">https://www.mapbox.com</a>.
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -32,6 +32,16 @@ export class MapSettingsComponent extends SettingsComponent<ClientConfig.MapConf
|
||||
}
|
||||
|
||||
|
||||
addNewLayer() {
|
||||
this.settings.customLayers.push({
|
||||
name: 'Layer-' + this.settings.customLayers.length,
|
||||
url: ''
|
||||
});
|
||||
}
|
||||
|
||||
removeLayer(layer: ClientConfig.MapLayers) {
|
||||
this.settings.customLayers.splice(this.settings.customLayers.indexOf(layer), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,7 +46,7 @@ export class SettingsService {
|
||||
enabled: true,
|
||||
mapProvider: ClientConfig.MapProviders.OpenStreetMap,
|
||||
mapboxAccessToken: '',
|
||||
tileUrl: ''
|
||||
customLayers: [{name: 'street', url: ''}]
|
||||
},
|
||||
RandomPhoto: {
|
||||
enabled: true
|
||||
|
@ -6,11 +6,11 @@
|
||||
class="switch"
|
||||
name="enabled"
|
||||
[switch-on-color]="'success'"
|
||||
[switch-inverse]="'inverse'"
|
||||
[switch-inverse]="true"
|
||||
[switch-off-text]="text.Disabled"
|
||||
[switch-on-text]="text.Enabled"
|
||||
[switch-handle-width]="'100'"
|
||||
[switch-label-width]="'20'"
|
||||
[switch-handle-width]="100"
|
||||
[switch-label-width]="20"
|
||||
[switch-disabled]="inProgress"
|
||||
[(ngModel)]="enabled"
|
||||
(changeState)="switched($event)">
|
||||
|
@ -1,11 +1,16 @@
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import {enableProdMode} from '@angular/core';
|
||||
import {ApplicationRef, enableProdMode} from '@angular/core';
|
||||
import {environment} from './environments/environment';
|
||||
import {AppModule} from './app/app.module';
|
||||
import {enableDebugTools} from '@angular/platform-browser';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.error(err));
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule).then(moduleRef => {
|
||||
const applicationRef = moduleRef.injector.get(ApplicationRef);
|
||||
const componentRef = applicationRef.components[0];
|
||||
// allows to run `ng.profiler.timeChangeDetection();`
|
||||
enableDebugTools(componentRef);
|
||||
}).catch(err => console.error(err));
|
||||
|
@ -1,15 +0,0 @@
|
||||
import {TestProjectPage} from './app.po';
|
||||
|
||||
describe('test-project App', () => {
|
||||
let page: TestProjectPage;
|
||||
|
||||
beforeEach(() => {
|
||||
page = new TestProjectPage();
|
||||
});
|
||||
|
||||
it('should display welcome message', async (done) => {
|
||||
page.navigateTo();
|
||||
expect(await page.getParagraphText()).toEqual('Welcome to app!!');
|
||||
done();
|
||||
});
|
||||
});
|
@ -1,11 +0,0 @@
|
||||
import {browser, by, element} from 'protractor';
|
||||
|
||||
export class TestProjectPage {
|
||||
navigateTo() {
|
||||
return browser.get('/');
|
||||
}
|
||||
|
||||
getParagraphText() {
|
||||
return element(by.css('app-root h1')).getText();
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/e2e",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user