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
4 changes: 4 additions & 0 deletions projects/admin-core/assets/locale/messages.admin-core.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1610,6 +1610,10 @@
<source>Search title</source>
<target>Suchtitel</target>
</trans-unit>
<trans-unit id="admin-core.components.toc-show-edit-layer-icon" datatype="html">
<source>Show edit layer icon</source>
<target>Symbol zum Bearbeiten der Ebene anzeigen</target>
</trans-unit>
<trans-unit id="admin-core.feature-type-settings-updated" datatype="html">
<source>Feature type settings updated</source>
<target>Feature-Typ-Einstellungen aktualisiert</target>
Expand Down
3 changes: 3 additions & 0 deletions projects/admin-core/assets/locale/messages.admin-core.en.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,9 @@
<trans-unit id="admin-core.components.simple-search-title" datatype="html">
<source>Search title</source>
</trans-unit>
<trans-unit id="admin-core.components.toc-show-edit-layer-icon" datatype="html">
<source>Show edit layer icon</source>
</trans-unit>
<trans-unit id="admin-core.feature-type-settings-updated" datatype="html">
<source>Feature type settings updated</source>
</trans-unit>
Expand Down
4 changes: 4 additions & 0 deletions projects/admin-core/assets/locale/messages.admin-core.nl.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1609,6 +1609,10 @@
<source>Search title</source>
<target>Zoeken titel</target>
</trans-unit>
<trans-unit id="admin-core.components.toc-show-edit-layer-icon" datatype="html">
<source>Show edit layer icon</source>
<target>Toon icoon voor het bewerken van de laag</target>
</trans-unit>
<trans-unit id="admin-core.feature-type-settings-updated" datatype="html">
<source>Feature type settings updated</source>
<target>Feature type instellingen aangepast</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { EditComponentConfigComponent } from './edit-config/edit-component-confi
import { GeolocationConfigComponent } from './geolocation-config/geolocation-config.component';
import { InfoConfigComponent } from './info-config/info-config.component';
import { DrawingConfigComponent } from './drawing-config/drawing-config.component';
import { TocComponentConfigComponent } from './toc-config/toc-component-config.component';

@NgModule({
declarations: [
Expand All @@ -30,6 +31,7 @@ import { DrawingConfigComponent } from './drawing-config/drawing-config.componen
GeolocationConfigComponent,
InfoConfigComponent,
DrawingConfigComponent,
TocComponentConfigComponent,
],
imports: [
CommonModule,
Expand All @@ -48,7 +50,7 @@ export class ComponentsModule {
const configurationComponentService = inject(ConfigurationComponentRegistryService);

/* eslint-disable max-len */
configurationComponentService.registerConfigurationComponents(BaseComponentTypeEnum.TOC, $localize `:@@admin-core.application.component-table-of-contents:Table of contents`, BaseComponentConfigComponent);
configurationComponentService.registerConfigurationComponents(BaseComponentTypeEnum.TOC, $localize `:@@admin-core.application.component-table-of-contents:Table of contents`, TocComponentConfigComponent);
configurationComponentService.registerConfigurationComponents(BaseComponentTypeEnum.LEGEND, $localize `:@@admin-core.application.component-legend:Legend`, BaseComponentConfigComponent);
configurationComponentService.registerConfigurationComponents(BaseComponentTypeEnum.DRAWING, $localize `:@@admin-core.application.component-drawing:Drawing`, DrawingConfigComponent);
configurationComponentService.registerConfigurationComponents(BaseComponentTypeEnum.PRINT, $localize `:@@admin-core.application.component-print:Print`, BaseComponentConfigComponent);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<tm-admin-base-component-config [type]="type"
[label]="label"
[config]="config"
i18n-titleLabel="@@admin-core.application.component-table-of-contents"
titleLabel="Table of contents">
<div [formGroup]="formGroup">
<mat-checkbox formControlName="showEditLayerIcon"
i18n="@@admin-core.components.toc-show-edit-layer-icon">Show edit layer icon</mat-checkbox>
</div>
</tm-admin-base-component-config>
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { ChangeDetectionStrategy, Component, DestroyRef, Input, inject } from '@angular/core';
import {
BaseComponentTypeEnum, TocConfigModel,
} from '@tailormap-viewer/api';
import { FormControl, FormGroup } from '@angular/forms';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { ComponentConfigurationService } from '../../services/component-configuration.service';
import { ConfigurationComponentModel } from '../configuration-component.model';
import { debounceTime } from 'rxjs';

@Component({
selector: 'tm-admin-edit-component-config',
templateUrl: './toc-component-config.component.html',
styleUrls: ['./toc-component-config.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false,
})
export class TocComponentConfigComponent implements ConfigurationComponentModel<TocConfigModel> {
private componentConfigService = inject(ComponentConfigurationService);
private destroyRef = inject(DestroyRef);

@Input()
public type: BaseComponentTypeEnum | undefined;

@Input()
public label: string | undefined;

@Input()
public set config(config: TocConfigModel | undefined) {
this._config = config;
this.initForm(config);
}
public get config() {
return this._config;
}
private _config: TocConfigModel | undefined;

public formGroup = new FormGroup({
showEditLayerIcon: new FormControl<boolean>(false),
});

constructor() {
this.formGroup.valueChanges
.pipe(takeUntilDestroyed(this.destroyRef), debounceTime(250))
.subscribe(() => {
if (!this.formGroup.valid) {
return;
}
this.saveConfig();
});
}

public initForm(config: TocConfigModel | undefined) {
this.formGroup.patchValue({ showEditLayerIcon: config?.showEditLayerIcon ?? false }, { emitEvent: false });
}

private saveConfig() {
this.componentConfigService.updateConfigForKey<TocConfigModel>(this.type, 'showEditLayerIcon', this.formGroup.value.showEditLayerIcon);
}
}
1 change: 1 addition & 0 deletions projects/api/src/lib/models/component-config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export * from './edit-config.model';
export * from './geolocation-config.model';
export * from './info-component-config.model';
export * from './drawing-component-config.model';
export * from './toc-config.model';
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ComponentBaseConfigModel } from '../component-base-config.model';

export interface TocConfigModel extends ComponentBaseConfigModel {
showEditLayerIcon?: boolean;
}
4 changes: 4 additions & 0 deletions projects/core/assets/locale/messages.core.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,10 @@
<source>Details for <x id="INTERPOLATION" equiv-text="{{node.layer?.title || node.name}}"/></source>
<target>Details für <x id="INTERPOLATION" equiv-text="{{node.layer?.title || node.name}}"/></target>
</trans-unit>
<trans-unit id="core.toc.edit-layer" datatype="html">
<source>Edit layer</source>
<target>Ebene bearbeiten</target>
</trans-unit>
<trans-unit id="core.toc.filter-by-layer-name" datatype="html">
<source>Filter by layer name...</source>
<target>Nach Ebenennamen filtern...</target>
Expand Down
3 changes: 3 additions & 0 deletions projects/core/assets/locale/messages.core.en.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,9 @@
<trans-unit id="core.toc.details-for" datatype="html">
<source>Details for <x id="INTERPOLATION" equiv-text="{{node.layer?.title || node.name}}"/></source>
</trans-unit>
<trans-unit id="core.toc.edit-layer" datatype="html">
<source>Edit layer</source>
</trans-unit>
<trans-unit id="core.toc.filter-by-layer-name" datatype="html">
<source>Filter by layer name...</source>
</trans-unit>
Expand Down
4 changes: 4 additions & 0 deletions projects/core/assets/locale/messages.core.nl.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,10 @@
<source>Details for <x id="INTERPOLATION" equiv-text="{{node.layer?.title || node.name}}"/></source>
<target>Details voor <x id="INTERPOLATION" equiv-text="{{node.layer?.title || node.name}}"/></target>
</trans-unit>
<trans-unit id="core.toc.edit-layer" datatype="html">
<source>Edit layer</source>
<target>Laag bewerken</target>
</trans-unit>
<trans-unit id="core.toc.filter-by-layer-name" datatype="html">
<source>Filter by layer name...</source>
<target>Filter op laagnaam...</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,14 @@
matListItemMeta>
</mat-icon>
}
@if (isInScale() && isLayerEditable() && node.checked) {
<mat-icon class="icon"
(click)="editLayerClicked(node)"
svgIcon="edit"
tmTooltip="Edit layer"
i18n-tmTooltip=":@@core.toc.edit-layer"
matListItemMeta>
</mat-icon>
}
</div>
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,15 @@ export class TocNodeLayerComponent {
@Input()
public filteredLayerIds: string[] = [];

@Input()
public editableLayerIds: string[] = [];

@Output()
public zoomToScale = new EventEmitter<number>();

@Output()
public editLayer = new EventEmitter<string>();

public isLevel() {
return this.node?.type === 'level';
}
Expand All @@ -56,6 +62,10 @@ export class TocNodeLayerComponent {
return this.filteredLayerIds.includes(this.node?.id || '');
}

public isLayerEditable() {
return this.editableLayerIds.includes(this.node?.id || '');
}

public zoomToLayer($event: MouseEvent, node: TreeModel<AppLayerModel>) {
$event.stopPropagation();
const scales: number[] = [];
Expand All @@ -72,4 +82,7 @@ export class TocNodeLayerComponent {
this.zoomToScale.emit(zoomToScale);
}

public editLayerClicked(node: TreeModel<AppLayerModel>) {
this.editLayer.emit(node.id);
}
}
5 changes: 4 additions & 1 deletion projects/core/src/lib/components/toc/toc/toc.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
[layersWithoutWebMercator]="layersWithoutWebMercator()"
[tiles3DLayerIds]="tiles3DLayerIds()"
[filteredLayerIds]="filteredLayerIds()"
(zoomToScale)="zoomToScale($event)"></tm-toc-node-layer>
[editableLayerIds]="config?.showEditLayerIcon && editComponentEnabled ? editableLayerIds() : []"
(zoomToScale)="zoomToScale($event)"
(editLayer)="editLayer($event)"
></tm-toc-node-layer>
</ng-template>

@if (visible$ | async) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { render, screen, waitFor } from '@testing-library/angular';
import { createMockStore } from '@ngrx/store/testing';
import { MenubarService } from '../../menubar';
import { of } from 'rxjs';
import { SharedModule } from '@tailormap-viewer/shared';
import { LoadingStateEnum, SharedModule } from '@tailormap-viewer/shared';
import userEvent from '@testing-library/user-event';
import { MatIconTestingModule } from '@angular/material/icon/testing';
import {
Expand All @@ -21,6 +21,7 @@ import { Store } from '@ngrx/store';
import { TocNodeDetailsComponent } from '../toc-node-details/toc-node-details.component';
import { getMapServiceMock } from '../../../test-helpers/map-service.mock.spec';
import { selectFilteredLayerIds } from '../../../state/filter-state/filter.selectors';
import { selectComponentsConfig, selectViewerLoadingState } from '../../../state';

const buildMockStore = (selectedLayer = '') => {
const layers = [
Expand All @@ -44,6 +45,8 @@ const buildMockStore = (selectedLayer = '') => {
{ selector: selectLayersWithoutWebMercatorIds, value: [] },
{ selector: select3dTilesLayers, value: [] },
{ selector: selectFilteredLayerIds, value: [] },
{ selector: selectViewerLoadingState, value: LoadingStateEnum.LOADED },
{ selector: selectComponentsConfig, value: [] },
],
});
};
Expand Down
34 changes: 31 additions & 3 deletions projects/core/src/lib/components/toc/toc/toc.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ import { map, tap } from 'rxjs/operators';
import { MenubarService } from '../../menubar';
import { TocMenuButtonComponent } from '../toc-menu-button/toc-menu-button.component';
import { Store } from '@ngrx/store';
import { AppLayerModel, BaseComponentTypeEnum } from '@tailormap-viewer/api';
import { AppLayerModel, BaseComponentConfigHelper, BaseComponentTypeEnum, EditConfigModel, TocConfigModel } from '@tailormap-viewer/api';
import { MapService } from '@tailormap-viewer/map';
import { selectFilteredLayerTree, selectFilterEnabled } from '../state/toc.selectors';
import { toggleFilterEnabled } from '../state/toc.actions';
import {
select3dTilesLayers, selectIn3dView, selectLayersWithoutWebMercatorIds, selectSelectedNode, selectSelectedNodeId,
select3dTilesLayers, selectEditableLayers, selectIn3dView, selectLayersWithoutWebMercatorIds, selectSelectedNode, selectSelectedNodeId,
} from '../../../map/state/map.selectors';
import { moveLayerTreeNode, setLayerVisibility, toggleSelectedLayerId, toggleLevelExpansion } from '../../../map/state/map.actions';
import { selectFilteredLayerIds } from '../../../state/filter-state/filter.selectors';
import { setEditActive, setSelectedEditLayer } from '../../edit/state/edit.actions';
import { ComponentConfigHelper } from '../../../shared';

interface AppLayerTreeModel extends BaseTreeModel {
metadata: AppLayerModel;
Expand All @@ -38,7 +40,6 @@ export class TocComponent implements OnInit, OnDestroy {
private mapService = inject(MapService);
private ngZone = inject(NgZone);


private destroyed = new Subject();
public visible$: Observable<boolean> = of(false);
public scale: number | null = null;
Expand All @@ -54,6 +55,11 @@ export class TocComponent implements OnInit, OnDestroy {
public layersWithoutWebMercator: Signal<string[]> = signal([]);
public tiles3DLayerIds: Signal<string[]> = signal([]);
public filteredLayerIds: Signal<string[]> = signal([]);
public editableLayerIds: Signal<string[]> = signal([]);

public config: TocConfigModel | undefined;

public editComponentEnabled = !BaseComponentConfigHelper.isComponentDisabledByDefault(BaseComponentTypeEnum.EDIT);

public ngOnInit(): void {
this.visible$ = this.menubarService.isComponentVisible$(BaseComponentTypeEnum.TOC);
Expand Down Expand Up @@ -94,11 +100,29 @@ export class TocComponent implements OnInit, OnDestroy {

this.menubarService.registerComponent({ type: BaseComponentTypeEnum.TOC, component: TocMenuButtonComponent });

ComponentConfigHelper.useInitialConfigForComponent<TocConfigModel>(
this.store$,
BaseComponentTypeEnum.TOC,
config => {
this.config = config;
},
);

ComponentConfigHelper.useInitialConfigForComponent<EditConfigModel>(
this.store$,
BaseComponentTypeEnum.EDIT,
config => {
this.editComponentEnabled = config.enabled;
},
);

this.in3D = this.store$.selectSignal(selectIn3dView);
this.layersWithoutWebMercator = this.store$.selectSignal(selectLayersWithoutWebMercatorIds);
const tiles3DLayers = this.store$.selectSignal(select3dTilesLayers);
this.tiles3DLayerIds = computed(() => tiles3DLayers().map(l => l.id));
this.filteredLayerIds = this.store$.selectSignal(selectFilteredLayerIds);
const editableLayers = this.store$.selectSignal(selectEditableLayers);
this.editableLayerIds = computed(() => editableLayers().map(layer => layer.id));
}

public getDropZoneConfig() {
Expand Down Expand Up @@ -139,4 +163,8 @@ export class TocComponent implements OnInit, OnDestroy {
this.mapService.zoomToScale(minScale);
}

public editLayer(layer: string) {
this.store$.dispatch(setSelectedEditLayer( { layer }));
this.store$.dispatch(setEditActive({ active: true }));
}
}
Loading