Skip to content
Open
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
23 changes: 19 additions & 4 deletions packages/geoadmin-log/src/Message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,37 @@
export class Message {
msg: string
params: Record<string, any>

/**
* Flag telling that the user has seen the error and closed it, to avoid seeing again
*/
isAcknowledged: boolean
sourceId? : string
/**
* @param {string} msg Translation key message
* @param {any} params Translation params to pass to i18n (used for message formatting)
*/
constructor(msg: string, params: Record<string, any> | null = null) {
constructor(msgParams: Record<string, any> ) {
const {
msg = 'unknown_message',
params = {},
isAcknowledged = false,
sourceId = undefined
} = msgParams
this.msg = msg
this.params = params ?? {}
this.params = params
this.isAcknowledged = isAcknowledged
this.sourceId = sourceId
}

// It is important that the Acknowledgement of the message is not part of the equality check.
// As this is used to stop new errors that have the same source to be dispatched.
isEquals(object: Message) {
return (
object instanceof Message &&
object.msg === this.msg &&
Object.keys(this.params).length === Object.keys(object.params).length &&
Object.keys(this.params).every((key) => this.params[key] === object.params[key])
Object.keys(this.params).every((key) => this.params[key] === object.params[key]) &&
this.sourceId === object.sourceId
)
}
}
Expand Down
91 changes: 91 additions & 0 deletions packages/geoadmin-log/src/__test__/message.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { expect } from 'chai'
import { ErrorMessage } from 'packages/geoadmin-log/src/Message'
import { describe, it } from 'vitest'

describe('Unit Tests for messages', () => {
describe('checking equality between messages', () => {
it('Ensure that errors with no sources are considered equal too when the rest is equal', () => {
const msg1 = new ErrorMessage({ msg: 'test text', params: {} })
const msg2 = new ErrorMessage({ msg: 'test text', params: {} })
const msg3 = new ErrorMessage({
msg: 'test text',
params: { key1: 'value1', key2: 'value2' },
})
const msg4 = new ErrorMessage({
msg: 'test text',
params: { key1: 'value1', key2: 'value2' },
})
expect(msg1.isEquals(msg1)).to.equal(true)
expect(msg1.isEquals(msg2)).to.equal(true)
expect(msg3.isEquals(msg3)).to.equal(true)
expect(msg3.isEquals(msg4)).to.equal(true)
})
it('detects equality and inequality between two messages', () => {
// messages without parameter
const simpleTextMsg1 = new ErrorMessage({
msg: 'test text',
params: {},
sourceId: 'test_source_12345',
})
const copyOfimpleTextMsg1 = new ErrorMessage({
msg: 'test text',
params: {},
sourceId: 'test_source_12345',
})
const simpleTextMsg1OtherSource = new ErrorMessage({
msg: 'test text',
params: {},
sourceId: 'test_source_02345',
})
const simpleTextMsg2 = new ErrorMessage({
msg: 'Another test text',
params: {},
sourceId: 'test_source_12345',
})

expect(simpleTextMsg1.isEquals(simpleTextMsg1)).to.be.true
expect(simpleTextMsg1.isEquals(copyOfimpleTextMsg1)).to.be.true
expect(simpleTextMsg1.isEquals(simpleTextMsg1OtherSource)).to.be.false // different source
expect(simpleTextMsg1.isEquals(simpleTextMsg2)).to.be.false // different msg

// messages with parameters
const paramMsg1 = new ErrorMessage({
msg: 'test text',
params: { key1: 'value1', key2: 'value2' },
sourceId: 'test_source_12345',
})
const copyOfParamMsg1 = new ErrorMessage({
msg: 'test text',
params: { key1: 'value1', key2: 'value2' },
sourceId: 'test_source_12345',
})
const paramMsg2 = new ErrorMessage({
msg: 'test text',
params: { key1: 'value2', key2: 'value2' },
sourceId: 'test_source_12345',
})

const paramMsg3 = new ErrorMessage({
msg: 'test text',
params: { key2: 'value1', key3: 'value2' },
sourceId: 'test_source_12345',
})
const paramMsg4 = new ErrorMessage({
msg: 'Another test text',
params: { key1: 'value1', key2: 'value2' },
sourceId: 'test_source_12345',
})
expect(simpleTextMsg1.isEquals(paramMsg1)).to.be.false // empty params vs params
expect(paramMsg1.isEquals(paramMsg1)).to.be.true
expect(paramMsg1.isEquals(copyOfParamMsg1)).to.be.true
expect(paramMsg1.isEquals(paramMsg4)).to.be.false // different text with params
expect(paramMsg1.isEquals(paramMsg2)).to.be.false // different values in params
expect(paramMsg1.isEquals(paramMsg3)).to.be.false // different keys in params
})
it('ensure that acknowledement of a message does not change equality', () => {
const msg1 = new ErrorMessage({ msg: 'test', params: {}, isAcknowledged: false })
const msg2 = new ErrorMessage({ msg: 'test', params: {}, isAcknowledged: true })
expect(msg1.isEquals(msg2)).to.be.true
})
})
})
2 changes: 1 addition & 1 deletion packages/mapviewer/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const dispatcher = { dispatcher: 'App.vue' }

let debouncedOnResize
const showFeedbackPopup = computed(() => {
return store.state.ui.errors.size + store.state.ui.warnings.size > 0
return store.getters.getFirstError || store.getters.getFirstWarning
})
const showDebugToolbar = computed(() => !IS_TESTING_WITH_CYPRESS && store.getters.hasDevSiteWarning)

Expand Down
9 changes: 6 additions & 3 deletions packages/mapviewer/src/api/errorQueues.api.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { ErrorMessage } from '@geoadmin/log/Message'

export function getStandardErrorMessage(query, urlParamName) {
return new ErrorMessage('url_parameter_error', {
param: urlParamName,
value: query,
return new ErrorMessage({
msg: 'url_parameter_error',
params: {
param: urlParamName,
value: query,
},
})
}

Expand Down
7 changes: 5 additions & 2 deletions packages/mapviewer/src/modules/drawing/DrawingModule.vue
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,11 @@ watch(availableIconSets, () => {
const icon = getIcon(iconArgs, null /*iconStyle*/, availableIconSets.value, () => {
store.dispatch('addWarnings', {
warnings: [
new WarningMessage('kml_icon_set_not_found', {
iconSetName: iconArgs.set,
new WarningMessage({
msg: 'kml_icon_set_not_found',
params: {
iconSetName: iconArgs.set,
},
}),
],
...dispatcher,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,8 @@ function mediaTypes() {
{{ t('modify_description') }}
</label>
<GeoadminTooltip
:tooltip-content="t('display_on_map')"
v-if="isFeatureMarker || isFeatureText"
:tooltip-content="t('display_on_map')"
>
<button
class="btn btn-sm btn-light d-flex align-items-center mb-2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import { getWmtsXyzUrl } from '@/utils/layerUtils'
const dispatcher = { dispatcher: 'CesiumWMTSLayer.vue' }

const MAXIMUM_LEVEL_OF_DETAILS = 18
const unsupportedProjectionError = new ErrorMessage('3d_unsupported_projection')
const unsupportedProjectionError = new ErrorMessage({
msg: '3d_unsupported_projection',
sourceId: wmtsLayerConfig.id,
})

const { wmtsLayerConfig, zIndex, parentLayerOpacity } = defineProps({
wmtsLayerConfig: {
Expand Down Expand Up @@ -59,6 +62,7 @@ const tileMatrixSet = computed(() => {
error: unsupportedProjectionError,
...dispatcher,
})
store.dispatch('addErrors', [unsupportedProjectionError], dispatcher)
}
return wmtsLayerConfig.tileMatrixSets
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,12 @@ function iconUrlProxy(url) {
(url) => {
store.dispatch('addWarnings', {
warnings: [
new WarningMessage('kml_icon_url_cors_issue', {
layerName: layerName.value,
url: url,
new WarningMessage({
msg: 'kml_icon_url_cors_issue',
params: {
layerName: layerName.value,
url: url,
},
}),
],
...dispatcher,
Expand All @@ -102,9 +105,12 @@ function iconUrlProxy(url) {
(url) => {
store.dispatch('addWarnings', {
warnings: [
new WarningMessage('kml_icon_url_scheme_http', {
layerName: layerName.value,
url: url,
new WarningMessage({
msg: 'kml_icon_url_scheme_http',
params: {
layerName: layerName.value,
url: url,
},
}),
],
...dispatcher,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ async function loadFile() {
await handleFileSource(fileUrl.value, false)
if (!fileUrl.value.match(/^https:\/\//)) {
store.dispatch('addWarnings', {
warnings: [new WarningMessage('import_http_external_file_warning', {})],
warnings: [
new WarningMessage({ msg: 'import_http_external_file_warning', params: {} }),
],
dispatcher: 'Import File Online Tab',
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,12 @@ export class KMLParser extends FileParser {

if (!isKmlFeaturesValid(kmlAsText)) {
kmlLayer.addWarningMessage(
new WarningMessage('kml_malformed', {
filename: kmlLayer.name ?? kmlLayer.id,
new WarningMessage({
msg: 'kml_malformed',
params: {
filename: kmlLayer.name ?? kmlLayer.id,
},
sourceId: kmlLayer.id,
})
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,28 @@ import UnknownProjectionError from '@/modules/menu/components/advancedTools/Impo
* function).
*
* @param {Error} error An error raised by a FileParser, or the parseAll
* @param {AbstractLayer} layer The layer which originated the error
* @returns {ErrorMessage}
*/
export default function generateErrorMessageFromErrorType(error) {
export default function generateErrorMessageFromErrorType(error, layer) {
if (error instanceof AxiosError || /fetch/.test(error.message)) {
return new ErrorMessage('loading_error_network_failure')
return new ErrorMessage({
msg: 'loading_error_network_failure',
sourceId: layer?.id,
})
} else if (error instanceof OutOfBoundsError) {
return new ErrorMessage('imported_file_out_of_bounds')
return new ErrorMessage({
msg: 'imported_file_out_of_bounds',
sourceId: layer?.id,
})
} else if (error instanceof EmptyFileContentError) {
return new ErrorMessage('kml_gpx_file_empty')
return new ErrorMessage({ msg: 'kml_gpx_file_empty', sourceId: layer?.id })
} else if (error instanceof UnknownProjectionError) {
return new ErrorMessage('unknown_projection_error', { epsg: error.epsg })
return new ErrorMessage({
msg: 'unknown_projection_error',
params: { epsg: error.epsg },
sourceId: layer?.id,
})
}
return new ErrorMessage('invalid_import_file_error')
return new ErrorMessage({ msg: 'invalid_import_file_error', sourceId: layer?.id })
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,12 @@ export default function useImportFile() {
projection.value.bounds.isInBounds(extent[2], extent[3])
if (!isLayerFullyInBound) {
layer.addWarningMessage(
new WarningMessage('file_imported_partially_out_of_bounds', {
filename: layer.name ?? layer.id,
new WarningMessage({
msg: 'file_imported_partially_out_of_bounds',
params: {
filename: layer.name ?? layer.id,
},
sourceId: layer.id,
})
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function onToggleCompareSlider() {

if (hasNoVisibleLayer.value) {
store.dispatch('addWarnings', {
warnings: [new WarningMessage('no_layers_info_compare')],
warnings: [new WarningMessage({ msg: 'no_layers_info_compare' })],
...dispatcher,
})
}
Expand Down
20 changes: 10 additions & 10 deletions packages/mapviewer/src/router/storeSync/LayerParamConfig.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,6 @@ function dispatchLayersFromUrlIntoStore(to, store, urlParamValue) {
)
if (layerObject) {
if (layerObject.type === LayerTypes.KML && layerObject.adminId) {
promisesForAllDispatch.push(
store.dispatch('setShowDrawingOverlay', {
show: true,
dispatcher: STORE_DISPATCHER_ROUTER_PLUGIN,
})
)

promisesForAllDispatch.push(
store.dispatch('setIsVisitWithAdminId', {
value: true,
Expand Down Expand Up @@ -284,11 +277,17 @@ function validateUrlInput(store, query) {
.filter((layer) => !store.getters.getLayerConfigById(layer.id))
.forEach((layer) => {
if (!layer.baseUrl) {
faultyLayers.push(new ErrorMessage('url_layer_error', { layer: layer.id }))
faultyLayers.push(
new ErrorMessage({ msg: 'url_layer_error', params: { layer: layer.id } })
)
} else if (!layer.baseUrl?.match(url_matcher)?.length > 0) {
localLayers.push(
new WarningMessage('url_external_layer_no_scheme_warning', {
layer: `${layer.type}|${layer.baseUrl}`,
new WarningMessage({
msg: 'url_external_layer_no_scheme_warning',
params: {
layer: `${layer.type}|${layer.baseUrl}`,
},
sourceId: layer.baseUrl,
})
)
}
Expand Down Expand Up @@ -321,6 +320,7 @@ export default class LayerParamConfig extends AbstractParamConfig {
'setSelectedFeatures',
'addSelectedFeatures',
'updateLayer',
'updateLayers',
],
setValuesInStore: dispatchLayersFromUrlIntoStore,
extractValueFromStore: generateLayerUrlParamFromStoreValues,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function dispatchTimeSliderFromUrlParam(to, store, urlParamValue) {
dispatcher: STORE_DISPATCHER_ROUTER_PLUGIN,
})
)
if (store.getters.visibleLayers.some(layer => layer.hasMultipleTimestamps)) {
if (store.getters.visibleLayers.some((layer) => layer.hasMultipleTimestamps)) {
promisesForAllDispatch.push(
store.dispatch('setTimeSliderActive', {
timeSliderActive: true,
Expand Down Expand Up @@ -52,7 +52,7 @@ function validateUrlInput(store, query) {
validationObject.warnings = []
}
validationObject.warnings.push(
new WarningMessage('time_slider_no_time_layer_active_url_warning', {})
new WarningMessage({ msg: 'time_slider_no_time_layer_active_url_warning' })
)
}
return validationObject
Expand Down
Loading
Loading