Skip to content

Commit

Permalink
Merge pull request #744 from geoadmin/develop
Browse files Browse the repository at this point in the history
New Release v1.12.0 - #minor
  • Loading branch information
ltshb authored Mar 27, 2024
2 parents d72f8c7 + c0b9916 commit 8c29798
Show file tree
Hide file tree
Showing 150 changed files with 21,113 additions and 2,886 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ yarn-error.log*
*.sublime-*
*.code-*

# vite
vite.config.js.timestamp-*.mjs

# Cypress and friends
tests/cypress/downloads
tests/cypress/videos
Expand Down
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"trailingComma": "es5",
"tabWidth": 4,
"jsxSingleQuote": false,
"plugins": ["prettier-plugin-jsdoc"],
"plugins": ["prettier-plugin-jsdoc", "@prettier/plugin-xml"],
"overrides": [{
"files": "*.md",
"options": {
Expand Down
521 changes: 320 additions & 201 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"build:int": "npm run build -- --mode integration",
"build:prod": "npm run build -- --mode production",
"update:translations": "node scripts/generate-i18n-files.js",
"check:external": "npx vite-node scripts/check-external-layers-providers.js",
"delete:reports": "rimraf tests/results/ || true",
"delete:reports:unit": "rimraf tests/results/unit/ || true"
},
Expand All @@ -38,13 +39,16 @@
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/vue-fontawesome": "^3.0.6",
"@geoblocks/cesium-compass": "^0.5.0",
"@geoblocks/mapfishprint": "^0.2.7",
"@geoblocks/ol-maplibre-layer": "^0.1.3",
"@ivanv/vue-collapse-transition": "^1.0.2",
"@mapbox/togeojson": "^0.16.2",
"@popperjs/core": "^2.11.8",
"@turf/area": "^6.5.0",
"@turf/bbox": "^6.5.0",
"@turf/boolean-contains": "^6.5.0",
"@turf/boolean-point-in-polygon": "^6.5.0",
"@turf/buffer": "^6.5.0",
"@turf/centroid": "^6.5.0",
"@turf/distance": "^6.5.0",
"@turf/explode": "^6.5.0",
Expand Down Expand Up @@ -84,6 +88,7 @@
"@cypress/vite-dev-server": "^5.0.7",
"@cypress/vue": "^6.0.0",
"@nuintun/qrcode": "^3.4.0",
"@prettier/plugin-xml": "^3.3.1",
"@rushstack/eslint-patch": "^1.7.2",
"@types/jsdom": "^21.1.6",
"@types/node": "^18.19.21",
Expand Down Expand Up @@ -118,10 +123,10 @@
"sass": "^1.71.1",
"start-server-and-test": "^2.0.3",
"typescript": "^5.3.3",
"vite": "^5.1.4",
"vite-node": "^1.3.1",
"vite": "^5.2.2",
"vite-node": "^1.4.0",
"vite-plugin-static-copy": "^1.0.1",
"vitest": "^1.3.1",
"vitest": "^1.4.0",
"vue-tsc": "^1.8.27",
"write-yaml-file": "^5.0.0",
"yargs": "^17.7.2"
Expand Down
15 changes: 3 additions & 12 deletions src/api/__tests__/search.api.spec.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
import { expect } from 'chai'
import { describe, it } from 'vitest'

import { FeatureSearchResult } from '@/api/search.api'
import { sanitizeTitle } from '@/api/search.api'

describe('Builds object by extracting all relevant attributes from the backend', () => {
describe('FeatureSearchResult.getSimpleTitle', () => {
it('Returns title removing HTML', () => {
const expectedResult = 'Some irrelevant stuff 123 Test'
const expectedResultWrappedInHtml = '<i>Some irrelevant stuff</i> <b>123 Test</b>'
const testInstance = new FeatureSearchResult(
expectedResultWrappedInHtml,
'',
123,
[],
[],
10
)
expect(testInstance.getSimpleTitle()).to.eq(expectedResult)
expect(sanitizeTitle(expectedResultWrappedInHtml)).to.eq(expectedResult)
})

it('Returns title as is if no HTML is present', () => {
const expectedResult = 'Test 123 Test'
const testInstance = new FeatureSearchResult(expectedResult, '', 123, [], [], 10)
expect(testInstance.getSimpleTitle()).to.eq(expectedResult)
expect(sanitizeTitle(expectedResult)).to.eq(expectedResult)
})
})
})
83 changes: 31 additions & 52 deletions src/api/features/EditableFeature.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,66 +16,45 @@ export const EditableFeatureTypes = {
/** Describe a feature that can be edited by the user, such as feature from the current drawing */
export default class EditableFeature extends SelectableFeature {
/**
* @param {String | Number} id Unique identifier for this feature (unique in the context it
* comes from, not for the whole app)
* @param {Number[][]} coordinates Coordinates [[x,y],[x2.y2],...] or [x,y] if point geometry
* coordinates of this feature
* @param {Object} geometry GeoJSON representation of this feature
* @param {String} title Title of this feature
* @param {String} description A description of this feature, can not be HTML content (only
* text)
* @param {EditableFeatureTypes} featureType Type of this editable feature
* @param {FeatureStyleColor} textColor Color for the text of this feature
* @param {FeatureStyleSize} textSize Size of the text for this feature
* @param {FeatureStyleColor} fillColor Color of the icon (if defined)
* @param {DrawingIcon} icon Icon that will be covering this feature, can be null
* @param {FeatureStyleSize} iconSize Size of the icon (if defined) that will be covering this
* feature
* @param {String | Number} featureData.id Unique identifier for this feature (unique in the
* context it comes from, not for the whole app)
* @param {Number[][]} featureData.coordinates Coordinates [[x,y],[x2.y2],...] or [x,y] if point
* geometry coordinates of this feature
* @param {Object} featureData.geometry GeoJSON representation of this feature
* @param {String} featureData.title Title of this feature
* @param {String} featureData.description A description of this feature, can not be HTML
* content (only text)
* @param {EditableFeatureTypes} featureData.featureType Type of this editable feature
* @param {FeatureStyleColor} featureData.textColor Color for the text of this feature
* @param {FeatureStyleSize} featureData.textSize Size of the text for this feature
* @param {FeatureStyleColor} featureData.fillColor Color of the icon (if defined)
* @param {DrawingIcon} featureData.icon Icon that will be covering this feature, can be null
* @param {FeatureStyleSize} featureData.iconSize Size of the icon (if defined) that will be
* covering this feature
*/
constructor(
id,
coordinates,
geometry,
title = '',
description = '',
featureType,
textColor = RED,
textSize = MEDIUM,
fillColor = RED,
icon = null,
iconSize = MEDIUM
) {
super(id, coordinates, title, description, geometry, true)
constructor(featureData) {
const {
id,
coordinates,
geometry,
title = '',
description = '',
featureType,
textColor = RED,
textSize = MEDIUM,
fillColor = RED,
icon = null,
iconSize = MEDIUM,
} = featureData
super({ id, coordinates, title, description, geometry, isEditable: true })
this._featureType = featureType
this._textColor = textColor
this._textSize = textSize
this._fillColor = fillColor
this._icon = icon
this._iconSize = iconSize
this._geodesicCoordinates = null
}

/**
* Create a new Editable Features. Omitted parameters means the default value of the constructor
* will be used.
*
* @param {any} obj An object with key value pairs for the parameters of the constructor
* @returns The new object
*/
static newFeature(obj) {
return new EditableFeature(
obj.id,
obj.coordinates,
obj.geometry,
obj.title,
obj.description,
obj.featureType,
obj.textColor,
obj.textSize,
obj.fillColor,
obj.icon,
obj.iconSize
)
this._isDragged = false
}

/**
Expand Down
39 changes: 23 additions & 16 deletions src/api/features/LayerFeature.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,35 @@ import LayerTypes from '@/api/layers/LayerTypes.enum.js'
/** Describe a feature from the backend, so a feature linked to a backend layer. */
export default class LayerFeature extends SelectableFeature {
/**
* @param {AbstractLayer} layer The layer in which this feature belongs
* @param {Number | String} id The unique feature ID in the layer it is part of
* @param {String} name The name (localized) of this feature
* @param {Object | String} data Data for this feature's popup (or tooltip).
* @param {Number[][]} coordinates Coordinate in the current projection ([[x,y],[x2,y2],...])
* @param {Number[]} extent Extent of the feature expressed with two point, bottom left and top
* right
* @param {Object} geometry GeoJSON geometry (if exists)
* @param {AbstractLayer} featureData.layer The layer in which this feature belongs
* @param {Number | String} featureData.id The unique feature ID in the layer it is part of
* @param {String} featureData.name The name (localized) of this feature
* @param {Object | String} featureData.data Data for this feature's popup (or tooltip).
* @param {[[Number, Number]]} featureData.coordinates Coordinate in the current projection
* ([[x,y],[x2,y2],...])
* @param {[Number, Number, Number, Number]} featureData.extent Extent of the feature expressed
* with two point, bottom left and top right
* @param {Object | null} [featureData.geometry=null] GeoJSON geometry (if exists). Default is
* `null`
*/
constructor(layer, id, name, data, coordinates, extent, geometry = null) {
super(id, coordinates, layer.name, name, geometry, false)
constructor(featureData) {
const { layer, id, name, data, coordinates, extent, geometry = null } = featureData
super({
id,
coordinates,
// using the layer name as title (so that user can differentiate the source)
title: layer.name,
// and the name as description (so that we do not lose track of this data)
description: name,
extent,
geometry,
isEditable: false,
})
this.layer = layer
this.data = data
this.extent = extent
// We can't trust the content of the popup data for external layers, and for KML layers.
// For KML, the issue is that user can create text-rich (HTML) description with links, and such.
// It would then be possible to do some XSS through this, so we need to sanitize this before showing it.
this.popupDataCanBeTrusted = !this.layer.isExternal && this.layer.type !== LayerTypes.KML
}

// overwriting get ID so that we use the layer ID with the feature ID
get id() {
return `${this.layer.id}-${this._id}`
}
}
50 changes: 26 additions & 24 deletions src/api/features/SelectableFeature.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,39 @@ import log from '@/utils/logging.js'
*/
export default class SelectableFeature extends EventEmitter {
/**
* @param {String | Number} id Unique identifier for this feature (unique in the context it
* comes from, not for the whole app)
* @param {Number[][]} coordinates [[x,y],[x2,y2],...] coordinates of the center of this feature
* @param {String} title Title of this feature
* @param {String} description A description of this feature, can not be HTML content (only
* text)
* @param {Object} geometry GeoJSON representation of this feature (if it has a geometry, for
* points it isn't necessary)
* @param {Boolean} isEditable Whether this feature is editable when selected (color, size,
* etc...)
* @param {String | Number} featureData.id Unique identifier for this feature (unique in the
* context it comes from, not for the whole app)
* @param {[[Number, Number]]} featureData.coordinates Coordinates of the center of this
* feature. Format is [[x,y],[x2,y2],...]
* @param {String} featureData.title Title of this feature
* @param {String | null} [featureData.description=null] A description of this feature, cannot
* be HTML content (only text). Default is `null`
* @param {[Number, Number, Number, Number] | null} [featureData.extent=null] Extent of this
* feature (if any) expressed as [minX, minY, maxX, maxY]. Default is `null`
* @param {Object | null} [featureData.geometry=null] GeoJSON representation of this feature (if
* it has a geometry, for points it isn't necessary). Default is `null`
* @param {Boolean} [featureData.isEditable=false] Whether this feature is editable when
* selected (color, size, etc...). Default is `false`
*/
constructor(id, coordinates, title, description, geometry = null, isEditable = false) {
constructor(featureData) {
super()
this._id = id
const {
id,
coordinates,
title,
description = null,
extent = null,
geometry = null,
isEditable = false,
} = featureData
this.id = id
// using the setter for coordinate (see below)
this.coordinates = coordinates
this.title = title
this.description = description
this.geometry = geometry
this._isEditable = !!isEditable
this._isDragged = false
this.extent = extent
this.isEditable = !!isEditable
}

/**
Expand Down Expand Up @@ -63,11 +75,6 @@ export default class SelectableFeature extends EventEmitter {
this.emitChangeEvent(changeType)
}

get id() {
return this._id
}
// ID is immutable, no setter

get coordinates() {
return this._coordinates
}
Expand Down Expand Up @@ -118,9 +125,4 @@ export default class SelectableFeature extends EventEmitter {
this._description = newDescription
this.emitStylingChangeEvent('description')
}

get isEditable() {
return this._isEditable
}
// isEditable is immutable, no setter
}
Loading

0 comments on commit 8c29798

Please sign in to comment.