Skip to content
Draft
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
8 changes: 3 additions & 5 deletions cypress/integration/fetcherrors.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,9 @@ describe('Fetch errors', () => {

cy.get('canvas', EXTENDED_TIMEOUT).should('be.visible')
cy.getByDataTest('basemapcard', EXTENDED_TIMEOUT).should('be.visible')
cy.getByDataTest('load-error-noticebox', EXTENDED_TIMEOUT).within(
() => {
cy.contains('Failed to load layer').should('be.visible')
}
)
cy.getByDataTest('layer-alert-error', EXTENDED_TIMEOUT).within(() => {
cy.contains('Failed to load layer').should('be.visible')
})
})

// TODO - need to make changes in analytics CachedDataProvider to make this test pass
Expand Down
14 changes: 7 additions & 7 deletions cypress/integration/layers/geojsonlayer.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('GeoJSON URL Layer', () => {
.contains(OVERLAY_TITLE)
.should('be.visible')

cy.getByDataTest('load-error-noticebox').should('not.exist')
cy.getByDataTest('layer-alert-error').should('not.exist')

// open the data table
cy.getByDataTest('moremenubutton').first().click()
Expand Down Expand Up @@ -127,11 +127,11 @@ describe('GeoJSON URL Layer', () => {
.should('be.visible')

// check that an error is displayed in the layer card
cy.getByDataTest('load-error-noticebox').should('be.visible')
cy.getByDataTest('load-error-noticebox')
cy.getByDataTest('layer-alert-error').should('be.visible')
cy.getByDataTest('layer-alert-error')
.contains('Failed to load layer')
.should('be.visible')
cy.getByDataTest('load-error-noticebox')
cy.getByDataTest('layer-alert-error')
.contains(
'There was a problem with this layer. Contact a system administrator.'
)
Expand Down Expand Up @@ -191,11 +191,11 @@ describe('GeoJSON URL Layer', () => {
.should('be.visible')

// check that an error is displayed in the layer card
cy.getByDataTest('load-error-noticebox').should('be.visible')
cy.getByDataTest('load-error-noticebox')
cy.getByDataTest('layer-alert-error').should('be.visible')
cy.getByDataTest('layer-alert-error')
.contains('Failed to load layer')
.should('be.visible')
cy.getByDataTest('load-error-noticebox')
cy.getByDataTest('layer-alert-error')
.contains(
'There was a problem with this layer. Contact a system administrator.'
)
Expand Down
6 changes: 3 additions & 3 deletions cypress/integration/layers/thematiclayer.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -804,11 +804,11 @@ context('Thematic Layers', () => {
.should('be.visible')

// check that an error is displayed in the layer card
cy.getByDataTest('load-error-noticebox').should('be.visible')
cy.getByDataTest('load-error-noticebox')
cy.getByDataTest('layer-alert-error').should('be.visible')
cy.getByDataTest('layer-alert-error')
.contains('Failed to load layer')
.should('be.visible')
cy.getByDataTest('load-error-noticebox')
cy.getByDataTest('layer-alert-error')
.contains(
'Organisation unit or organisation unit level is not valid'
)
Expand Down
19 changes: 19 additions & 0 deletions cypress/integration/layers/trackedentitylayer.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,25 @@ describe('Tracked Entity Layers', () => {
Layer.validateCardItems(['Malaria Entity'])
})

it('shows a warning in the layer card when there is no data', () => {
selectTeTypeAndProgram(
Layer,
'Malaria Entity',
'Malaria case diagnosis, treatment and investigation'
)

Layer.selectTab('Period')
.typeStartDate('1990-01-01')
.typeEndDate('1990-12-31')
.addToMap()

Layer.validateDialogClosed(true)

cy.getByDataTest('layer-alert-warning', EXTENDED_TIMEOUT)
.should('contain', 'No data found')
.and('contain', "Data you don't have access to is not shown")
})

it('opens a tracked entity layer popup', () => {
selectTeTypeAndProgram(
Layer,
Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/requestsErrors.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe('Error handling check for all layer types', () => {
409: 'Simulated error with status code 409',
}

cy.getByDataTest('load-error-noticebox', EXTENDED_TIMEOUT).within(
cy.getByDataTest('layer-alert-error', EXTENDED_TIMEOUT).within(
() => {
cy.contains('Failed to load layer').should('be.visible')
cy.contains(errorMessage[error]).should('be.visible')
Expand Down
93 changes: 88 additions & 5 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2026-10-05T12:46:47.530Z\n"
"PO-Revision-Date: 2026-10-05T12:46:47.531Z\n"
"POT-Creation-Date: 2026-10-06T11:43:15.235Z\n"
"PO-Revision-Date: 2026-10-06T11:43:15.235Z\n"

msgid "2020"
msgstr "2020"
Expand Down Expand Up @@ -710,6 +710,18 @@ msgstr "Duplicate layer"
msgid "Remove layer"
msgstr "Remove layer"

msgid "Hide details"
msgstr "Hide details"

msgid "Details"
msgstr "Details"

msgid "Copied"
msgstr "Copied"

msgid "Copy"
msgstr "Copy"

msgid "Filters"
msgstr "Filters"

Expand Down Expand Up @@ -1064,6 +1076,12 @@ msgstr "End date"
msgid "Not available offline"
msgstr "Not available offline"

msgid "Legend (a layer has an error)"
msgstr "Legend (a layer has an error)"

msgid "Legend (a layer has a warning)"
msgstr "Legend (a layer has a warning)"

msgid "Click to unpin legend"
msgstr "Click to unpin legend"

Expand Down Expand Up @@ -1732,6 +1750,44 @@ msgstr "Active"
msgid "Completed"
msgstr "Completed"

msgid ""
"It may have been deleted, or your access to it may have changed. Contact "
"your system administrator if you need it."
msgstr ""
"It may have been deleted, or your access to it may have changed. Contact "
"your system administrator if you need it."

msgid "You don't have access to this layer's data"
msgstr "You don't have access to this layer's data"

msgid "Your access may have changed. Contact your system administrator."
msgstr "Your access may have changed. Contact your system administrator."

msgid "This layer's program is not available"
msgstr "This layer's program is not available"

msgid "This layer's tracked entity type is not available"
msgstr "This layer's tracked entity type is not available"

msgid "This layer's org units are not available"
msgstr "This layer's org units are not available"

msgid ""
"Check the period, filters and org units. Data you don't have access to is "
"not shown."
msgstr ""
"Check the period, filters and org units. Data you don't have access to is "
"not shown."

msgid "Showing the first {{limit}} tracked entities"
msgstr "Showing the first {{limit}} tracked entities"

msgid "Narrow the period or org units to see all of them."
msgstr "Narrow the period or org units to see all of them."

msgid "Relationships could not be loaded"
msgstr "Relationships could not be loaded"

msgid "Choropleth"
msgstr "Choropleth"

Expand Down Expand Up @@ -1819,6 +1875,9 @@ msgstr "Start/end dates"
msgid "Cancelled"
msgstr "Cancelled"

msgid "Layer"
msgstr "Layer"

msgid "Could not count org units without coordinates"
msgstr "Could not count org units without coordinates"

Expand Down Expand Up @@ -1885,9 +1944,6 @@ msgstr "related"
msgid "Tracked entity"
msgstr "Tracked entity"

msgid "Displaying first {{pageSize}} tracked entities"
msgstr "Displaying first {{pageSize}} tracked entities"

msgid "not one of"
msgstr "not one of"

Expand Down Expand Up @@ -1934,6 +1990,33 @@ msgstr "Tracked entities"
msgid "Org units"
msgstr "Org units"

msgid "HTTP status"
msgstr "HTTP status"

msgid "Error code"
msgstr "Error code"

msgid "Server message"
msgstr "Server message"

msgid "Request"
msgstr "Request"

msgid "Problem"
msgstr "Problem"

msgid "App version"
msgstr "App version"

msgid "Server version"
msgstr "Server version"

msgid "Time"
msgstr "Time"

msgid "Alert"
msgstr "Alert"

msgid "Facility"
msgstr "Facility"

Expand Down
4 changes: 2 additions & 2 deletions src/components/app/App.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import cx from 'classnames'
import React, { useEffect, useState } from 'react'
import { useSelector } from 'react-redux'
import { useLayersLoader } from '../../hooks/useLayersLoader.js'
import { useLoadLayerWithRedux } from '../../hooks/useLoadLayerWithRedux.js'
import BottomPanel from '../datatable/BottomPanel.jsx'
import DownloadModeMenu from '../download/DownloadMenubar.jsx'
import DownloadSettings from '../download/DownloadSettings.jsx'
Expand Down Expand Up @@ -30,7 +30,7 @@ const App = () => {

useLoadMap()
useLoadDataStore()
useLayersLoader()
useLoadLayerWithRedux()

const [interpretationsRenderCount, setInterpretationsRenderCount] =
useState(1)
Expand Down
39 changes: 17 additions & 22 deletions src/components/layers/overlays/OverlayCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
import {
ALERT_SUCCESS,
ALERT_MESSAGE_DYNAMIC,
ERROR_CRITICAL,
} from '../../../constants/alerts.js'
import {
DOWNLOADABLE_LAYER_TYPES,
Expand All @@ -30,8 +29,9 @@ import {
APP_URLS,
CURRENT_AO_KEY,
} from '../../../util/analyticalObject.js'
import { getLayerAlerts, hasLayerError } from '../../../util/layerAlerts.js'
import LayerAlerts from '../../legend/LayerAlerts.jsx'
import Legend from '../../legend/Legend.jsx'
import LegendAlert from '../../legend/LegendAlert.jsx'
import DataDownloadDialog from '../download/DataDownloadDialog.jsx'
import LayerCard from '../LayerCard.jsx'
import styles from './styles/OverlayCard.module.css'
Expand Down Expand Up @@ -60,35 +60,30 @@ const OverlayCard = ({
isVisible,
layer: layerType,
isLoaded,
loadError,
} = layer
const hasError = hasLayerError(layer)

const canEdit = layerType !== EXTERNAL_LAYER
const canToggleDataTable = DATA_TABLE_LAYER_TYPES.includes(layerType)
const canDownload = DOWNLOADABLE_LAYER_TYPES.includes(layerType)
const canOpenAs = OPEN_AS_LAYER_TYPES.includes(layerType)

const getCardContent = () => {
if (loadError) {
return (
<div
data-test="load-error-noticebox"
className={styles.loadError}
>
<LegendAlert
alert={{ code: ERROR_CRITICAL, message: loadError }}
/>
</div>
)
}
return (
legend && (
const getCardContent = () => (
<div className={styles.content}>
<div className={styles.alerts}>
<LayerAlerts
alerts={getLayerAlerts(layer)}
layerName={name}
layerType={layerType}
/>
</div>
{legend && (
<div className={styles.legend}>
<Legend {...legend} />
</div>
)
)
}
)}
</div>
)

return (
<>
Expand Down Expand Up @@ -140,7 +135,7 @@ const OverlayCard = ({
}
: undefined
}
hasError={!!loadError}
hasError={hasError}
>
{getCardContent()}
</LayerCard>
Expand Down
Loading
Loading