From bc40e5cfe9be4f3ef2eaaf85e8b66df1dc11b792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre-=C3=89tienne=20Lord?= <7397743+pelord@users.noreply.github.com> Date: Wed, 14 Jun 2023 16:22:52 -0400 Subject: [PATCH] Workspace fixes (#1290) * Insert accent hashtag (#1258) * premier_test_ajout_hastags * insert_accent_to_the_keywords_in_order_to_use_hashtag_and(-) --------- Co-authored-by: karengeo (cherry picked from commit cf74db75a940a6ee73f634181e3a75e30cc16e16) * Corriger le parseInt qui ajuste normalement les attributs en integer (#1257) * Corriger le parseInt qui ajuste normalement les attributs en integer * Make condition a function (cherry picked from commit 1d807d63f73fd4f74f12953cc70f56fe5ecd4289) * fix(draw): drawing circle crash whole drawing component. (#1273) (cherry picked from commit 3998dccb9007a5fb4a2a98be492cca428417b5a0) * chore(Package): run the build once * 1.15.3 * refactor(workspaces): move common method to workspace utils * feat(workspaces): sourcefields with types add a cellClassFunc to the table template * refactor(entity-table): typo * fix(workspace): table scroll/overflow was not accessible * lint * lint * wip --------- Co-authored-by: MSPKarengeo <90481471+MSPKarengeo@users.noreply.github.com> Co-authored-by: Michael Lane Co-authored-by: Alexandre Caron --- .../entity-table/entity-table.component.scss | 2 +- .../shared/edition-workspace.service.ts | 13 +-- .../shared/feature-workspace.service.ts | 96 +---------------- .../workspace/shared/wfs-workspace.service.ts | 95 +--------------- .../workspace/shared/wms-workspace.service.ts | 96 +---------------- .../lib/workspace/shared/workspace.utils.ts | 101 +++++++++++++++++- 6 files changed, 116 insertions(+), 287 deletions(-) diff --git a/packages/common/src/lib/entity/entity-table/entity-table.component.scss b/packages/common/src/lib/entity/entity-table/entity-table.component.scss index 20fe679faf..c9aa32fd5e 100644 --- a/packages/common/src/lib/entity/entity-table/entity-table.component.scss +++ b/packages/common/src/lib/entity/entity-table/entity-table.component.scss @@ -59,7 +59,7 @@ table button { padding-right: 35px !important; } -.class_sting, +.class_string, .class_text, .class_number_edition { text-align: left; diff --git a/packages/geo/src/lib/workspace/shared/edition-workspace.service.ts b/packages/geo/src/lib/workspace/shared/edition-workspace.service.ts index c77aedfec6..e5c2c584a6 100644 --- a/packages/geo/src/lib/workspace/shared/edition-workspace.service.ts +++ b/packages/geo/src/lib/workspace/shared/edition-workspace.service.ts @@ -4,10 +4,7 @@ import { MatDialog } from '@angular/material/dialog'; import { ActionStore, - EntityRecord, - EntityStoreFilterCustomFuncStrategy, EntityStoreFilterSelectionStrategy, - EntityStoreStrategyFuncOptions, EntityTableColumnRenderer, EntityTableTemplate, EntityTableButton} from '@igo2/common'; @@ -40,6 +37,7 @@ import olFeature from 'ol/Feature'; import olSourceImageWMS from 'ol/source/ImageWMS'; import type { default as OlGeometry } from 'ol/geom/Geometry'; import { BehaviorSubject, Observable, throwError } from 'rxjs'; +import { createFilterInMapExtentOrResolutionStrategy } from './workspace.utils'; @Injectable({ providedIn: 'root' @@ -233,7 +231,7 @@ export class EditionWorkspaceService { store.addStrategy(inMapResolutionStrategy, true); store.addStrategy(selectionStrategy, true); store.addStrategy(selectedRecordStrategy, false); - store.addStrategy(this.createFilterInMapExtentOrResolutionStrategy(), true); + store.addStrategy(createFilterInMapExtentOrResolutionStrategy(), true); return store; } @@ -378,13 +376,6 @@ export class EditionWorkspaceService { }; } - private createFilterInMapExtentOrResolutionStrategy(): EntityStoreFilterCustomFuncStrategy { - const filterClauseFunc = (record: EntityRecord) => { - return record.state.inMapExtent === true && record.state.inMapResolution === true; - }; - return new EntityStoreFilterCustomFuncStrategy({filterClauseFunc} as EntityStoreStrategyFuncOptions); - } - public saveFeature(feature, workspace: EditionWorkspace) { if (!this.validateFeature(feature, workspace)){ return false; diff --git a/packages/geo/src/lib/workspace/shared/feature-workspace.service.ts b/packages/geo/src/lib/workspace/shared/feature-workspace.service.ts index 1020021e30..cdf488a767 100644 --- a/packages/geo/src/lib/workspace/shared/feature-workspace.service.ts +++ b/packages/geo/src/lib/workspace/shared/feature-workspace.service.ts @@ -2,12 +2,7 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { ActionStore, - EntityTableTemplate, - EntityStoreFilterCustomFuncStrategy, - EntityRecord, - EntityStoreStrategyFuncOptions, - EntityStoreFilterSelectionStrategy, - EntityTableColumnRenderer + EntityStoreFilterSelectionStrategy } from '@igo2/common'; import { @@ -15,7 +10,6 @@ import { FeatureStoreLoadingLayerStrategy, FeatureStoreSelectionStrategy, FeatureStoreInMapExtentStrategy, - Feature, FeatureMotion, FeatureStoreInMapResolutionStrategy, FeatureStoreSearchIndexStrategy, @@ -24,16 +18,13 @@ import { import { LayerService, VectorLayer } from '../../layer'; import { GeoWorkspaceOptions } from '../../layer/shared/layers/layer.interface'; import { IgoMap } from '../../map'; -import { SourceFieldsOptionsParams, FeatureDataSource, RelationOptions, CapabilitiesService } from '../../datasource'; +import { FeatureDataSource, CapabilitiesService } from '../../datasource'; import { getCommonVectorSelectedStyle } from '../../style/shared/vector/commonVectorStyle'; import { FeatureWorkspace } from './feature-workspace'; -import { skipWhile, take } from 'rxjs/operators'; import { ConfigService, StorageService } from '@igo2/core'; -import olFeature from 'ol/Feature'; -import type { default as OlGeometry } from 'ol/geom/Geometry'; -import { getGeoServiceAction } from './workspace.utils'; +import { createFilterInMapExtentOrResolutionStrategy, createTableTemplate } from './workspace.utils'; import { PropertyTypeDetectorService } from '../../utils/propertyTypeDetector/propertyTypeDetector.service'; @Injectable({ @@ -79,7 +70,7 @@ export class FeatureWorkspaceService { tableTemplate: undefined } }); - this.createTableTemplate(wks, layer); + createTableTemplate(wks, layer, this.layerService, this.ws$); return wks; } @@ -125,84 +116,7 @@ export class FeatureWorkspaceService { store.addStrategy(inMapResolutionStrategy, true); store.addStrategy(selectionStrategy, true); store.addStrategy(selectedRecordStrategy, false); - store.addStrategy(this.createFilterInMapExtentOrResolutionStrategy(), true); + store.addStrategy(createFilterInMapExtentOrResolutionStrategy(), true); return store; } - - private createTableTemplate(workspace: FeatureWorkspace, layer: VectorLayer): EntityTableTemplate { - const geoServiceAction = getGeoServiceAction(workspace, this.layerService); - const fields = layer.dataSource.options.sourceFields || []; - - const relations = layer.dataSource.options.relations || []; - - if (fields.length === 0) { - workspace.entityStore.entities$.pipe( - skipWhile(val => val.length === 0), - take(1) - ).subscribe(entities => { - const ol = (entities[0] as Feature).ol as olFeature; - const columnsFromFeatures = ol.getKeys() - .filter( - col => !col.startsWith('_') && - col !== 'geometry' && - col !== ol.getGeometryName() && - !col.match(/boundedby/gi)) - .map(key => { - return { - name: `properties.${key}`, - title: key, - renderer: EntityTableColumnRenderer.UnsanitizedHTML - }; - }); - columnsFromFeatures.unshift(...geoServiceAction); - workspace.meta.tableTemplate = { - selection: true, - sort: true, - columns: columnsFromFeatures - }; - }); - return; - } - const columns = fields.map((field: SourceFieldsOptionsParams) => { - return { - name: `properties.${field.name}`, - title: field.alias ? field.alias : field.name, - renderer: EntityTableColumnRenderer.UnsanitizedHTML, - tooltip: field.tooltip - }; - }); - - const relationsColumn = relations.map((relation: RelationOptions) => { - return { - name: `properties.${relation.name}`, - title: relation.alias ? relation.alias : relation.name, - renderer: EntityTableColumnRenderer.Icon, - icon: relation.icon, - parent: relation.parent, - type: 'relation', - tooltip: relation.tooltip, - onClick: () => { - this.ws$.next(relation.title); - }, - cellClassFunc: () => { - return { 'class_icon': true }; - } - }; - }); - - columns.push(...relationsColumn); - columns.unshift(...geoServiceAction); - workspace.meta.tableTemplate = { - selection: true, - sort: true, - columns - }; - } - - private createFilterInMapExtentOrResolutionStrategy(): EntityStoreFilterCustomFuncStrategy { - const filterClauseFunc = (record: EntityRecord) => { - return record.state.inMapExtent === true && record.state.inMapResolution === true; - }; - return new EntityStoreFilterCustomFuncStrategy({filterClauseFunc} as EntityStoreStrategyFuncOptions); - } } diff --git a/packages/geo/src/lib/workspace/shared/wfs-workspace.service.ts b/packages/geo/src/lib/workspace/shared/wfs-workspace.service.ts index 13e0b1c967..779ca0b4da 100644 --- a/packages/geo/src/lib/workspace/shared/wfs-workspace.service.ts +++ b/packages/geo/src/lib/workspace/shared/wfs-workspace.service.ts @@ -2,12 +2,7 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { ActionStore, - EntityTableTemplate, - EntityStoreFilterCustomFuncStrategy, - EntityRecord, - EntityStoreStrategyFuncOptions, - EntityStoreFilterSelectionStrategy, - EntityTableColumnRenderer + EntityStoreFilterSelectionStrategy } from '@igo2/common'; import { @@ -15,7 +10,6 @@ import { FeatureStoreLoadingLayerStrategy, FeatureStoreSelectionStrategy, FeatureStoreInMapExtentStrategy, - Feature, FeatureMotion, FeatureStoreInMapResolutionStrategy, GeoPropertiesStrategy @@ -23,16 +17,13 @@ import { import { LayerService, VectorLayer } from '../../layer'; import { GeoWorkspaceOptions } from '../../layer/shared/layers/layer.interface'; import { IgoMap } from '../../map'; -import { SourceFieldsOptionsParams, FeatureDataSource, RelationOptions, CapabilitiesService } from '../../datasource'; +import { FeatureDataSource, CapabilitiesService } from '../../datasource'; import { PropertyTypeDetectorService} from '../../utils'; import { getCommonVectorSelectedStyle } from '../../style/shared/vector/commonVectorStyle'; import { WfsWorkspace } from './wfs-workspace'; -import { skipWhile, take } from 'rxjs/operators'; import { StorageService, ConfigService } from '@igo2/core'; -import olFeature from 'ol/Feature'; -import type { default as OlGeometry } from 'ol/geom/Geometry'; -import { getGeoServiceAction } from './workspace.utils'; +import { createFilterInMapExtentOrResolutionStrategy, createTableTemplate } from './workspace.utils'; @Injectable({ providedIn: 'root' }) @@ -74,7 +65,7 @@ export class WfsWorkspaceService { tableTemplate: undefined } }); - this.createTableTemplate(wks, layer); + createTableTemplate(wks, layer, this.layerService, this.ws$); return wks; } @@ -112,83 +103,7 @@ export class WfsWorkspaceService { store.addStrategy(inMapResolutionStrategy, true); store.addStrategy(selectionStrategy, true); store.addStrategy(selectedRecordStrategy, false); - store.addStrategy(this.createFilterInMapExtentOrResolutionStrategy(), true); + store.addStrategy(createFilterInMapExtentOrResolutionStrategy(), true); return store; } - - private createTableTemplate(workspace: WfsWorkspace, layer: VectorLayer): EntityTableTemplate { - const geoServiceAction = getGeoServiceAction(workspace, this.layerService); - const fields = layer.dataSource.options.sourceFields || []; - - const relations = layer.dataSource.options.relations || []; - - if (fields.length === 0) { - workspace.entityStore.entities$.pipe( - skipWhile(val => val.length === 0), - take(1) - ).subscribe(entities => { - const ol = (entities[0] as Feature).ol as olFeature; - const columnsFromFeatures = ol.getKeys() - .filter( - col => !col.startsWith('_') && - col !== 'geometry' && - col !== ol.getGeometryName() && - !col.match(/boundedby/gi)) - .map(key => { - return { - name: `properties.${key}`, - title: key, - renderer: EntityTableColumnRenderer.UnsanitizedHTML - }; - }); - columnsFromFeatures.unshift(...geoServiceAction); - workspace.meta.tableTemplate = { - selection: true, - sort: true, - columns: columnsFromFeatures - }; - }); - return; - } - const columns = fields.map((field: SourceFieldsOptionsParams) => { - return { - name: `properties.${field.name}`, - title: field.alias ? field.alias : field.name, - renderer: EntityTableColumnRenderer.UnsanitizedHTML, - tooltip: field.tooltip - }; - }); - - const relationsColumn = relations.map((relation: RelationOptions) => { - return { - name: `properties.${relation.name}`, - title: relation.alias ? relation.alias : relation.name, - renderer: EntityTableColumnRenderer.Icon, - icon: relation.icon, - parent: relation.parent, - type: 'relation', - tooltip: relation.tooltip, - onClick: () => { - this.ws$.next(relation.title); - }, - cellClassFunc: () => { - return { 'class_icon': true }; - } - }; - }); - - columns.push(...relationsColumn); - columns.unshift(...geoServiceAction); - workspace.meta.tableTemplate = { - selection: true, - sort: true, - columns - }; - } - private createFilterInMapExtentOrResolutionStrategy(): EntityStoreFilterCustomFuncStrategy { - const filterClauseFunc = (record: EntityRecord) => { - return record.state.inMapExtent === true && record.state.inMapResolution === true; - }; - return new EntityStoreFilterCustomFuncStrategy({filterClauseFunc} as EntityStoreStrategyFuncOptions); - } } diff --git a/packages/geo/src/lib/workspace/shared/wms-workspace.service.ts b/packages/geo/src/lib/workspace/shared/wms-workspace.service.ts index 56b82d1bc8..3b63936fe8 100644 --- a/packages/geo/src/lib/workspace/shared/wms-workspace.service.ts +++ b/packages/geo/src/lib/workspace/shared/wms-workspace.service.ts @@ -1,19 +1,12 @@ import { Injectable } from '@angular/core'; import { ActionStore, - EntityRecord, - EntityStoreFilterCustomFuncStrategy, - EntityStoreFilterSelectionStrategy, - EntityStoreStrategyFuncOptions, - EntityTableColumnRenderer, - EntityTableTemplate } from '@igo2/common'; + EntityStoreFilterSelectionStrategy } from '@igo2/common'; import { StorageService, ConfigService } from '@igo2/core'; -import { skipWhile, take } from 'rxjs/operators'; -import { CapabilitiesService, RelationOptions, SourceFieldsOptionsParams, WMSDataSource } from '../../datasource'; +import { CapabilitiesService, WMSDataSource } from '../../datasource'; import { FeatureDataSource } from '../../datasource/shared/datasources/feature-datasource'; import { WFSDataSourceOptions } from '../../datasource/shared/datasources/wfs-datasource.interface'; import { - Feature, FeatureMotion, FeatureStore, FeatureStoreInMapExtentStrategy, @@ -31,11 +24,9 @@ import { QueryableDataSourceOptions } from '../../query/shared/query.interfaces' import { WfsWorkspace } from './wfs-workspace'; import { getCommonVectorSelectedStyle } from '../../style/shared/vector/commonVectorStyle'; -import olFeature from 'ol/Feature'; -import type { default as OlGeometry } from 'ol/geom/Geometry'; import { PropertyTypeDetectorService } from '../../utils/propertyTypeDetector/propertyTypeDetector.service'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; -import { getGeoServiceAction } from './workspace.utils'; +import { createFilterInMapExtentOrResolutionStrategy, createTableTemplate } from './workspace.utils'; @Injectable({ providedIn: 'root' @@ -175,7 +166,7 @@ export class WmsWorkspaceService { tableTemplate: undefined } }); - this.createTableTemplate(wks, workspaceLayer); + createTableTemplate(wks, workspaceLayer, this.layerService, this.ws$); workspaceLayer.options.workspace.workspaceId = workspaceLayer.id; layer.options.workspace = Object.assign({}, layer.options.workspace, @@ -233,84 +224,7 @@ export class WmsWorkspaceService { store.addStrategy(inMapResolutionStrategy, true); store.addStrategy(selectionStrategy, true); store.addStrategy(selectedRecordStrategy, false); - store.addStrategy(this.createFilterInMapExtentOrResolutionStrategy(), true); + store.addStrategy(createFilterInMapExtentOrResolutionStrategy(), true); return store; } - - private createTableTemplate(workspace: WfsWorkspace, layer: VectorLayer): EntityTableTemplate { - const geoServiceAction = getGeoServiceAction(workspace, this.layerService); - const fields = layer.dataSource.options.sourceFields || []; - - const relations = layer.dataSource.options.relations || []; - - if (fields.length === 0) { - workspace.entityStore.entities$.pipe( - skipWhile(val => val.length === 0), - take(1) - ).subscribe(entities => { - const ol = (entities[0] as Feature).ol as olFeature; - const columnsFromFeatures = ol.getKeys() - .filter( - col => !col.startsWith('_') && - col !== 'geometry' && - col !== ol.getGeometryName() && - !col.match(/boundedby/gi)) - .map(key => { - return { - name: `properties.${key}`, - title: key, - renderer: EntityTableColumnRenderer.UnsanitizedHTML - }; - }); - columnsFromFeatures.unshift(...geoServiceAction); - workspace.meta.tableTemplate = { - selection: true, - sort: true, - columns: columnsFromFeatures - }; - }); - return; - } - const columns = fields.map((field: SourceFieldsOptionsParams) => { - return { - name: `properties.${field.name}`, - title: field.alias ? field.alias : field.name, - renderer: EntityTableColumnRenderer.UnsanitizedHTML, - tooltip: field.tooltip - }; - }); - - const relationsColumn = relations.map((relation: RelationOptions) => { - return { - name: `properties.${relation.name}`, - title: relation.alias ? relation.alias : relation.name, - renderer: EntityTableColumnRenderer.Icon, - icon: relation.icon, - parent: relation.parent, - type: 'relation', - tooltip: relation.tooltip, - onClick: () => { - this.ws$.next(relation.title); - }, - cellClassFunc: () => { - return { 'class_icon': true }; - } - }; - }); - - columns.push(...relationsColumn); - columns.unshift(...geoServiceAction); - workspace.meta.tableTemplate = { - selection: true, - sort: true, - columns - }; - } - - private createFilterInMapExtentOrResolutionStrategy(): EntityStoreFilterCustomFuncStrategy { - const filterClauseFunc = (record: EntityRecord) => { - return record.state.inMapExtent === true && record.state.inMapResolution === true; - }; - return new EntityStoreFilterCustomFuncStrategy({filterClauseFunc} as EntityStoreStrategyFuncOptions); - } } diff --git a/packages/geo/src/lib/workspace/shared/workspace.utils.ts b/packages/geo/src/lib/workspace/shared/workspace.utils.ts index 8525370516..229ce16015 100644 --- a/packages/geo/src/lib/workspace/shared/workspace.utils.ts +++ b/packages/geo/src/lib/workspace/shared/workspace.utils.ts @@ -2,14 +2,22 @@ import { WfsWorkspace } from './wfs-workspace'; import { FeatureWorkspace } from './feature-workspace'; import { EditionWorkspace } from './edition-workspace'; import { Observable } from 'rxjs'; -import { EntityStoreFilterCustomFuncStrategy, EntityRecord, EntityTableColumnRenderer, EntityTableButton } from '@igo2/common'; -import { map } from 'rxjs/operators'; +import { + EntityStoreFilterCustomFuncStrategy, EntityRecord, + EntityTableColumnRenderer, EntityTableButton, EntityStoreStrategyFuncOptions, + EntityTableTemplate +} from '@igo2/common'; +import { map, skipWhile, take } from 'rxjs/operators'; import { Feature } from '../../feature/shared/feature.interfaces'; import { StorageScope } from '@igo2/core'; +import { EntityTableColumn } from '@igo2/common'; import { ObjectUtils } from '@igo2/utils'; import { IgoMap } from '../../map/shared/map'; import { generateIdFromSourceOptions } from '../../utils/id-generator'; -import { LayerService } from '../../layer'; +import { LayerService, VectorLayer } from '../../layer'; +import olFeature from 'ol/Feature'; +import type { default as OlGeometry } from 'ol/geom/Geometry'; +import { RelationOptions, SourceFieldsOptionsParams } from '../../datasource/shared/datasources/datasource.interface'; export function getRowsInMapExtent(layerId, storageService): boolean { return storageService.get(`workspace.rowsInMapExtent.${layerId}`) as boolean || true; @@ -115,3 +123,90 @@ export function getGeoServiceAction(workspace: FeatureWorkspace | WfsWorkspace, }]; return geoServiceAction; } + +export function createTableTemplate(workspace: FeatureWorkspace | WfsWorkspace, layer: VectorLayer, layerService: LayerService, ws$) { + const geoServiceAction = getGeoServiceAction(workspace, layerService); + const fields = layer.dataSource.options.sourceFields || []; + + const relations = layer.dataSource.options.relations || []; + + if (fields.length === 0) { + workspace.entityStore.entities$.pipe( + skipWhile(val => val.length === 0), + take(1) + ).subscribe(entities => { + const ol = (entities[0] as Feature).ol as olFeature; + const columnsFromFeatures = ol.getKeys() + .filter( + col => !col.startsWith('_') && + col !== 'geometry' && + col !== ol.getGeometryName() && + !col.match(/boundedby/gi)) + .map(key => { + return { + name: `properties.${key}`, + title: key, + renderer: EntityTableColumnRenderer.UnsanitizedHTML + }; + }); + columnsFromFeatures.unshift(...geoServiceAction); + workspace.meta.tableTemplate = { + selection: true, + sort: true, + columns: columnsFromFeatures, + tableHeight: '100%' + } as EntityTableTemplate; + }); + return; + } + const columns = fields.map((field: SourceFieldsOptionsParams) => { + + return { + name: `properties.${field.name}`, + title: field.alias ? field.alias : field.name, + renderer: EntityTableColumnRenderer.UnsanitizedHTML, + tooltip: field.tooltip, + cellClassFunc: () => { + const cellClass = {}; + if (field.type) { + cellClass[`class_${field.type}`] = true; + return cellClass; + } + }, + } as EntityTableColumn; + }); + + const relationsColumn = relations.map((relation: RelationOptions) => { + return { + name: `properties.${relation.name}`, + title: relation.alias ? relation.alias : relation.name, + renderer: EntityTableColumnRenderer.Icon, + icon: relation.icon, + parent: relation.parent, + type: 'relation', + tooltip: relation.tooltip, + onClick: () => { + ws$.next(relation.title); + }, + cellClassFunc: () => { + return { 'class_icon': true }; + } + }; + }); + + columns.push(...relationsColumn); + columns.unshift(...geoServiceAction); + workspace.meta.tableTemplate = { + selection: true, + sort: true, + columns, + tableHeight: '100%' + }; +} + +export function createFilterInMapExtentOrResolutionStrategy(): EntityStoreFilterCustomFuncStrategy { + const filterClauseFunc = (record: EntityRecord) => { + return record.state.inMapExtent === true && record.state.inMapResolution === true; + }; + return new EntityStoreFilterCustomFuncStrategy({filterClauseFunc} as EntityStoreStrategyFuncOptions); +}