Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import { ConfirmDialogService, LoadingStateEnum, SharedDirectivesModule, SharedI
import userEvent from '@testing-library/user-event';
import { TestBed } from '@angular/core/testing';
import { MatIconTestingModule } from '@angular/material/icon/testing';
import { createMapServiceMock } from '../../../map/components/map-drawing-buttons/map-drawing-buttons.component.spec';
import { initialDrawingState, drawingStateKey } from '../state/drawing.state';
import { selectComponentsConfig, selectViewerLoadingState } from '../../../state';
import { BaseComponentTypeEnum } from '@tailormap-viewer/api';
import { createMapServiceMockWithDrawingTools } from '../../../test-helpers/map-service.mock.spec';

const setup = async (isComponentVisible = true, selectors: any[] = []) => {
const mapServiceMock = createMapServiceMock();
const mapServiceMock = createMapServiceMockWithDrawingTools();
const menubarServiceMock = {
isComponentVisible$: jest.fn(() => of(isComponentVisible)),
registerComponent: jest.fn(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import { FeatureUpdatedService } from '../../../services/feature-updated.service
import { hideFeatureInfoDialog, reopenFeatureInfoDialog } from '../../feature-info/state/feature-info.actions';
import { ComponentConfigHelper } from '../../../shared/helpers/component-config.helper';
import { withLatestFrom } from 'rxjs/operators';
import { activateTool } from '../../toolbar/state/toolbar.actions';
import { ToolbarComponentEnum } from '../../toolbar/models/toolbar-component.enum';

@Component({
selector: 'tm-edit-dialog',
Expand Down Expand Up @@ -175,7 +173,6 @@ export class EditDialogComponent {
this.store$.select(selectEditOpenedFromFeatureInfo).pipe(take(1)).subscribe(openedFromFeatureInfo => {
if (openedFromFeatureInfo && reopenFeatureInfo) {
this.store$.dispatch(setEditActive({ active: false }));
this.store$.dispatch(activateTool({ tool: ToolbarComponentEnum.FEATURE_INFO }));
this.store$.dispatch(reopenFeatureInfoDialog());
}
});
Expand Down Expand Up @@ -244,7 +241,6 @@ export class EditDialogComponent {
this.resetChanges();
if (openedFromFeatureInfo) {
this.store$.dispatch(setEditActive({ active: false }));
this.store$.dispatch(activateTool({ tool: ToolbarComponentEnum.FEATURE_INFO }));
this.store$.dispatch(reopenFeatureInfoDialog());
}
}
Expand Down
12 changes: 9 additions & 3 deletions projects/core/src/lib/components/edit/edit/edit.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import { ApplicationLayerService } from '../../../map/services/application-layer
import {
AppLayerModel, AttributeType, AuthenticatedUserService, BaseComponentTypeEnum, EditConfigModel, GeometryType,
} from '@tailormap-viewer/api';
import { activateTool } from '../../toolbar/state/toolbar.actions';
import { ToolbarComponentEnum } from '../../toolbar/models/toolbar-component.enum';
import { DrawingType, MapService, ScaleHelper } from '@tailormap-viewer/map';
import { ComponentConfigHelper } from '../../../shared';

Expand Down Expand Up @@ -110,6 +108,15 @@ export class EditComponent implements OnInit {
&& this.selectedCopyLayerIds.length == 0 || this.selectedCopyLayerIds.includes(layer.id));
this.layersToCreateNewFeaturesFrom.set(layers);
});

this.mapService.someToolsEnabled$([BaseComponentTypeEnum.EDIT])
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(enabled => {
if (!enabled) {
// Maybe we should check for changes and then ask what the user wants to do?
this.store$.dispatch(setEditActive({ active: false }));
}
});
}

public isLine() {
Expand Down Expand Up @@ -151,7 +158,6 @@ export class EditComponent implements OnInit {
this.store$.dispatch(setEditActive({ active: editActive }));
if (editActive) {
this.store$.dispatch(hideFeatureInfoDialog());
this.store$.dispatch(activateTool({ tool: ToolbarComponentEnum.EDIT, preventMapToolActivation: true }));
}
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TestBed } from '@angular/core/testing';
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
import { EditMapToolService } from './edit-map-tool.service';
import { provideMockStore } from "@ngrx/store/testing";
import { selectEditStatus, selectNewFeatureGeometryType, selectSelectedEditFeature } from "../state/edit.selectors";
Expand All @@ -22,7 +22,11 @@ describe('EditMapToolService', () => {
mapServiceMock.provider,
{ provide: ApplicationLayerService, useValue: mockApplicationLayerService },
provideMockStore({
initialState: {},
initialState: {
edit: {
features: [],
},
},
selectors: [
{ selector: selectEditStatus, value: editStatus },
{ selector: selectNewFeatureGeometryType, value: 'rectangle' },
Expand All @@ -40,46 +44,50 @@ describe('EditMapToolService', () => {
};
};

test('should disable the edit tools when edit tool is inactive', () => {
test('should disable the edit tools when edit tool is inactive', fakeAsync(() => {
const { service, enableTool, disableTool } = setup('inactive');
expect(service).toBeTruthy();
tick(0);
expect(enableTool).not.toHaveBeenCalled();
expect(disableTool).toBeCalledTimes(3);
expect(disableTool).nthCalledWith(1, ToolTypeEnum.MapClick, true);
expect(disableTool).nthCalledWith(2, ToolTypeEnum.Modify, true);
expect(disableTool).nthCalledWith(3, ToolTypeEnum.Draw, false);
});
}));

test('should enable the correct tools when edit tool is active', () => {
test('should enable the correct tools when edit tool is active', fakeAsync(() => {
const { service, enableTool, disableTool } = setup('active');
expect(service).toBeTruthy();
tick(0);
expect(enableTool).toHaveBeenCalled();
expect(enableTool).nthCalledWith(1, ToolTypeEnum.MapClick, true);
expect(disableTool).toBeCalledTimes(2);
expect(disableTool).nthCalledWith(1, ToolTypeEnum.Modify, true);
expect(disableTool).nthCalledWith(2, ToolTypeEnum.Draw, true);
});
}));

test('should enable the correct tools when editing a feature', () => {
test('should enable the correct tools when editing a feature', fakeAsync(() => {
const { service, enableTool, disableTool } = setup('edit_feature');
expect(service).toBeTruthy();
tick(0);
expect(disableTool).toBeCalledTimes(1);
expect(disableTool).toBeCalledWith(ToolTypeEnum.Draw, true);

expect(enableTool).toBeCalledTimes(2);
expect(enableTool).nthCalledWith(1, ToolTypeEnum.MapClick, true);
expect(enableTool).nthCalledWith(2, ToolTypeEnum.Modify, false, { geometry: 'POINT(0 0)' });
});
}));

test('should enable the correct tools when creating a feature', () => {
test('should enable the correct tools when creating a feature', fakeAsync(() => {
const { service, enableTool, disableTool } = setup('create_feature');
expect(service).toBeTruthy();
tick(0);
expect(disableTool).toBeCalledTimes(2);
expect(disableTool).nthCalledWith(1, ToolTypeEnum.MapClick, true);
expect(disableTool).nthCalledWith(2, ToolTypeEnum.Modify, true);

expect(enableTool).toBeCalledTimes(1);
expect(enableTool).toBeCalledWith( ToolTypeEnum.Draw, true, { type: 'rectangle' });
});
}));

});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DestroyRef, Injectable, OnDestroy, inject } from '@angular/core';
import { DestroyRef, Injectable, inject } from '@angular/core';
import {
DrawingToolConfigModel,
DrawingToolEvent,
Expand All @@ -16,20 +16,19 @@ import {
selectEditStatus, selectEditError$, selectNewFeatureGeometryType, selectSelectedEditFeature, selectCopiedFeatures,
} from '../state/edit.selectors';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { BehaviorSubject, combineLatest, concatMap, forkJoin, map, merge, Observable, of, switchMap, take, tap } from 'rxjs';
import { deregisterTool, registerTool } from '../../toolbar/state/toolbar.actions';
import { ToolbarComponentEnum } from '../../toolbar/models/toolbar-component.enum';
import { BehaviorSubject, combineLatest, concatMap, debounceTime, forkJoin, map, merge, Observable, of, switchMap, take, tap } from 'rxjs';
import { loadCopyFeatures, loadEditFeatures } from '../state/edit.actions';
import { SnackBarMessageComponent, SnackBarMessageOptionsModel } from '@tailormap-viewer/shared';
import { MatSnackBar } from '@angular/material/snack-bar';
import { withLatestFrom } from 'rxjs/operators';
import { ApplicationStyleService } from '../../../services/application-style.service';
import { ApplicationLayerService } from '../../../map/services/application-layer.service';
import { BaseComponentTypeEnum } from '@tailormap-viewer/api';

@Injectable({
providedIn: 'root',
})
export class EditMapToolService implements OnDestroy {
export class EditMapToolService {
private mapService = inject(MapService);
private store$ = inject(Store);
private snackBar = inject(MatSnackBar);
Expand All @@ -51,12 +50,11 @@ export class EditMapToolService implements OnDestroy {

constructor() {

this.mapService.createTool$<MapClickToolModel, MapClickToolConfigModel>({ type: ToolTypeEnum.MapClick })
this.mapService.createTool$<MapClickToolModel, MapClickToolConfigModel>({ type: ToolTypeEnum.MapClick, owner: BaseComponentTypeEnum.EDIT })
.pipe(
takeUntilDestroyed(this.destroyRef),
tap(({ tool }) => {
this.editMapClickToolId = tool.id;
this.store$.dispatch(registerTool({ tool: { id: ToolbarComponentEnum.EDIT, mapToolId: tool.id } }));
}),
concatMap(({ tool }) => tool?.mapClick$ || of(null)),
)
Expand All @@ -79,6 +77,7 @@ export class EditMapToolService implements OnDestroy {
this.mapService.createTool$<ModifyToolModel, ModifyToolConfigModel>({
type: ToolTypeEnum.Modify,
style,
owner: BaseComponentTypeEnum.EDIT,
})
.pipe(
takeUntilDestroyed(this.destroyRef),
Expand Down Expand Up @@ -117,6 +116,7 @@ export class EditMapToolService implements OnDestroy {
this.mapService.createTool$<DrawingToolModel, DrawingToolConfigModel>({
type: ToolTypeEnum.Draw,
style,
owner: BaseComponentTypeEnum.EDIT,
})
.pipe(
takeUntilDestroyed(this.destroyRef),
Expand All @@ -135,6 +135,7 @@ export class EditMapToolService implements OnDestroy {
.pipe(
withLatestFrom(this.mapService.getToolManager$()),
takeUntilDestroyed(this.destroyRef),
debounceTime(0), // debounce to avoid multiple rapid enable/disable tool calls
)
.subscribe(([[ editStatus, newFeatureGeometryType, editGeometry ], toolManager ]) => {
if (this.createdGeometrySubject.getValue() !== null) {
Expand Down Expand Up @@ -184,10 +185,6 @@ export class EditMapToolService implements OnDestroy {
}));
}

public ngOnDestroy() {
this.store$.dispatch(deregisterTool({ tool: ToolbarComponentEnum.EDIT }));
}

private handleMapClick(evt: { mapCoordinates: [number, number]; mouseCoordinates: [number, number]; pointerType?: string }) {
this.store$.select(selectEditStatus).pipe(take(1))
.subscribe(status => {
Expand Down
18 changes: 2 additions & 16 deletions projects/core/src/lib/components/edit/state/edit.effects.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { Injectable, inject } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import * as EditActions from './edit.actions';
import { filter, map, switchMap } from 'rxjs';
import { map, switchMap } from 'rxjs';
import { FeatureInfoService } from '../../feature-info';
import { withLatestFrom } from 'rxjs/operators';
import { selectEditActive, selectSelectedCopyLayer, selectSelectedEditLayer } from './edit.selectors';
import { selectSelectedCopyLayer, selectSelectedEditLayer } from './edit.selectors';
import { Store } from '@ngrx/store';
import { activateTool } from '../../toolbar/state/toolbar.actions';
import { ToolbarComponentEnum } from '../../toolbar/models/toolbar-component.enum';
import { setEditActive } from './edit.actions';

@Injectable()
export class EditEffects {
Expand Down Expand Up @@ -50,15 +47,4 @@ export class EditEffects {
);
});

public activeTool$ = createEffect(() => {
return this.actions$.pipe(
ofType(activateTool),
withLatestFrom(this.store$.select(selectEditActive)),
filter(([ action, editActive ]) => editActive && action.tool !== ToolbarComponentEnum.EDIT),
map(() => {
return setEditActive({ active: false });
}),
);
});

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import { render } from '@testing-library/angular';
import { FeatureInfoComponent } from './feature-info.component';
import { Store } from '@ngrx/store';
import { loadFeatureInfo } from '../state/feature-info.actions';
import { of } from 'rxjs';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { SnackBarMessageComponent } from '@tailormap-viewer/shared';
import { getMapServiceMock } from '../../../test-helpers/map-service.mock.spec';
import { FeatureInfoService } from '../feature-info.service';
import { registerTool } from '../../toolbar/state/toolbar.actions';
import { ToolbarComponentEnum } from '../../toolbar/models/toolbar-component.enum';

const setup = async (returnError = false) => {
const mapServiceMock = getMapServiceMock(tool => ({
Expand Down Expand Up @@ -52,13 +48,11 @@ describe('FeatureInfoComponent', () => {
afterEach(() => { jest.useRealTimers(); });

test('should render', async () => {
const { mapServiceMock, mockDispatch, mockSelect } = await setup();
const { mapServiceMock, mockSelect } = await setup();
expect(mapServiceMock.mapService.createTool$).toHaveBeenCalled();
const highlightArgs = Array.from(mapServiceMock.mapService.renderFeatures$.mock.calls[0]);
expect(highlightArgs.length).toEqual(3);
expect(highlightArgs[0]).toEqual('feature-info-highlight-layer');

expect(mockDispatch).toHaveBeenCalledWith(registerTool({ tool: { id: ToolbarComponentEnum.FEATURE_INFO, mapToolId: 'MapClick' } }));
expect(mockSelect).toHaveBeenCalled();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ import { combineLatest, concatMap, filter, of, Subject, takeUntil, tap } from 'r
import { Store } from '@ngrx/store';
import { featureInfoLoaded } from '../state/feature-info.actions';
import {
selectCurrentlySelectedFeatureGeometry, selectFeatureInfoFeatures, selectLoadingFeatureInfo, selectMapCoordinates,
selectCurrentlySelectedFeatureGeometry, selectFeatureInfoFeatures, selectLoadingFeatureInfo,
selectMapCoordinates,
} from '../state/feature-info.selectors';
import { deregisterTool, registerTool } from '../../toolbar/state/toolbar.actions';
import { ToolbarComponentEnum } from '../../toolbar/models/toolbar-component.enum';
import { FeatureStylingHelper } from '../../../shared/helpers/feature-styling.helper';
import { FeatureInfoService } from '../feature-info.service';
import {
select3dTilesLayers, selectIn3dView, selectVisibleLayersWithAttributes, selectVisibleWMSLayersWithoutAttributes,
} from '../../../map/state/map.selectors';
import { take, withLatestFrom } from 'rxjs/operators';
import { FeatureUpdatedService } from '../../../services';
import { BaseComponentTypeEnum } from '@tailormap-viewer/api';

@Component({
selector: 'tm-feature-info',
Expand All @@ -37,14 +37,17 @@ export class FeatureInfoComponent implements OnInit, OnDestroy {

private static DEFAULT_ERROR_MESSAGE = $localize `:@@core.feature-info.error-loading-feature-info:Something went wrong while getting feature info, please try again`;
private static DEFAULT_NO_FEATURES_FOUND_MESSAGE = $localize `:@@core.feature-info.no-features-found:No features found`;
private tool: string | undefined;

public ngOnInit(): void {
this.mapService.createTool$<MapClickToolModel, MapClickToolConfigModel>({ type: ToolTypeEnum.MapClick, autoEnable: true })
this.mapService.createTool$<MapClickToolModel, MapClickToolConfigModel>({
type: ToolTypeEnum.MapClick,
autoEnable: true,
owner: BaseComponentTypeEnum.FEATURE_INFO,
})
.pipe(
takeUntil(this.destroyed),
tap(({ tool }) => {
this.store$.dispatch(registerTool({ tool: { id: ToolbarComponentEnum.FEATURE_INFO, mapToolId: tool.id } }));
}),
tap(({ tool }) => this.tool = tool.id),
concatMap(({ tool }) => tool?.mapClick$ || of(null)),
)
.subscribe(mapClick => {
Expand All @@ -70,13 +73,11 @@ export class FeatureInfoComponent implements OnInit, OnDestroy {
this.featureInfoService.updateSingleFeature(updatedFeatureInFeatureInfo.__fid, updatedFeatureInFeatureInfo.layerId);
}
});

}

public ngOnDestroy() {
this.destroyed.next(null);
this.destroyed.complete();
this.store$.dispatch(deregisterTool({ tool: ToolbarComponentEnum.FEATURE_INFO }));
}

private handleMapClick(evt: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { SwitchFilterComponent } from './edit-attribute-filters/switch-filter/sw
import { DatePickerFilterComponent } from './edit-attribute-filters/date-picker-filter/date-picker-filter.component';
import { DropdownListFilterComponent } from './edit-attribute-filters/dropdown-list-filter/dropdown-list-filter.component';
import { ResetFiltersButtonComponent } from './reset-filters-button/reset-filters-button.component';
import { MapDrawingButtonsComponent } from './spatial-filter-form-draw-geometries/map-drawing-buttons/map-drawing-buttons.component';



Expand All @@ -48,6 +49,7 @@ import { ResetFiltersButtonComponent } from './reset-filters-button/reset-filter
DatePickerFilterComponent,
DropdownListFilterComponent,
ResetFiltersButtonComponent,
MapDrawingButtonsComponent,
],
imports: [
CommonModule,
Expand Down
Loading
Loading