diff --git a/i18n/en.pot b/i18n/en.pot
index a161cb591..42f2b57e3 100644
--- a/i18n/en.pot
+++ b/i18n/en.pot
@@ -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: 2020-02-25T15:24:49.055Z\n"
-"PO-Revision-Date: 2020-02-25T15:24:49.055Z\n"
+"POT-Creation-Date: 2020-03-11T02:00:02.349Z\n"
+"PO-Revision-Date: 2020-03-11T02:00:02.349Z\n"
msgid "Dashboard"
msgstr ""
@@ -91,6 +91,9 @@ msgstr ""
msgid "Unable to load the plugin for this item"
msgstr ""
+msgid "There was a problem loading this dashboard item"
+msgstr ""
+
msgid "No data to display"
msgstr ""
@@ -157,9 +160,6 @@ msgstr ""
msgid "Pivot tables"
msgstr ""
-msgid "Pivot tables"
-msgstr ""
-
msgid "Charts"
msgstr ""
diff --git a/src/components/Item/VisualizationItem/FatalErrorBoundary.js b/src/components/Item/VisualizationItem/FatalErrorBoundary.js
new file mode 100644
index 000000000..7687526ca
--- /dev/null
+++ b/src/components/Item/VisualizationItem/FatalErrorBoundary.js
@@ -0,0 +1,45 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import i18n from '@dhis2/d2-i18n';
+import { Warning } from './assets/icons';
+
+import classes from './styles/FatalErrorBoundary.module.css';
+
+class FatalErrorBoundary extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ errorFound: false,
+ };
+ }
+ componentDidCatch(error, info) {
+ this.setState({
+ errorFound: true,
+ });
+ console.log('error: ', error);
+ console.log('info: ', info);
+ }
+ render() {
+ if (this.state.errorFound) {
+ return (
+
+
+
+
+
+ {i18n.t(
+ 'There was a problem loading this dashboard item'
+ )}
+
+
+ );
+ }
+ return this.props.children;
+ }
+}
+
+FatalErrorBoundary.propTypes = {
+ children: PropTypes.node,
+};
+
+export default FatalErrorBoundary;
diff --git a/src/components/Item/VisualizationItem/Item.js b/src/components/Item/VisualizationItem/Item.js
index 1b4f07d99..8a3c20159 100644
--- a/src/components/Item/VisualizationItem/Item.js
+++ b/src/components/Item/VisualizationItem/Item.js
@@ -7,6 +7,7 @@ import VisualizationPlugin from '@dhis2/data-visualizer-plugin';
import i18n from '@dhis2/d2-i18n';
import DefaultPlugin from './DefaultPlugin';
+import FatalErrorBoundary from './FatalErrorBoundary';
import ItemHeader from '../ItemHeader';
import ItemHeaderButtons from './ItemHeaderButtons';
import ItemFooter from './ItemFooter';
@@ -282,7 +283,11 @@ export class Item extends Component {
? {
height: item.originalHeight - HEADER_HEIGHT - PADDING_BOTTOM,
}
- : { height: this.contentRef.offsetHeight };
+ : {
+ height: this.contentRef
+ ? this.contentRef.offsetHeight
+ : item.originalHeight - HEADER_HEIGHT - PADDING_BOTTOM,
+ };
};
render() {
@@ -308,13 +313,15 @@ export class Item extends Component {
itemId={item.id}
actionButtons={actionButtons}
/>
- (this.contentRef = ref)}
- >
- {this.state.configLoaded && this.getPluginComponent()}
-
+
+ (this.contentRef = ref)}
+ >
+ {this.state.configLoaded && this.getPluginComponent()}
+
+
{!editMode && showFooter ? : null}
>
);
diff --git a/src/components/Item/VisualizationItem/__tests__/__snapshots__/Item.spec.js.snap b/src/components/Item/VisualizationItem/__tests__/__snapshots__/Item.spec.js.snap
index 61baa92b9..db647a5bb 100644
--- a/src/components/Item/VisualizationItem/__tests__/__snapshots__/Item.spec.js.snap
+++ b/src/components/Item/VisualizationItem/__tests__/__snapshots__/Item.spec.js.snap
@@ -84,9 +84,11 @@ ShallowWrapper {
}
title="rainbow"
/>,
- ,
+
+
+ ,
null,
],
},
@@ -132,15 +134,27 @@ ShallowWrapper {
},
Object {
"instance": null,
- "key": "3",
- "nodeType": "host",
+ "key": undefined,
+ "nodeType": "class",
"props": Object {
- "children": false,
- "className": "dashboard-item-content",
+ "children": ,
+ },
+ "ref": null,
+ "rendered": Object {
+ "instance": null,
+ "key": "3",
+ "nodeType": "host",
+ "props": Object {
+ "children": false,
+ "className": "dashboard-item-content",
+ },
+ "ref": [Function],
+ "rendered": false,
+ "type": "div",
},
- "ref": [Function],
- "rendered": false,
- "type": "div",
+ "type": [Function],
},
null,
],
@@ -184,9 +198,11 @@ ShallowWrapper {
}
title="rainbow"
/>,
- ,
+
+
+ ,
null,
],
},
@@ -232,15 +248,27 @@ ShallowWrapper {
},
Object {
"instance": null,
- "key": "3",
- "nodeType": "host",
+ "key": undefined,
+ "nodeType": "class",
"props": Object {
- "children": false,
- "className": "dashboard-item-content",
+ "children": ,
},
- "ref": [Function],
- "rendered": false,
- "type": "div",
+ "ref": null,
+ "rendered": Object {
+ "instance": null,
+ "key": "3",
+ "nodeType": "host",
+ "props": Object {
+ "children": false,
+ "className": "dashboard-item-content",
+ },
+ "ref": [Function],
+ "rendered": false,
+ "type": "div",
+ },
+ "type": [Function],
},
null,
],
diff --git a/src/components/Item/VisualizationItem/assets/icons.js b/src/components/Item/VisualizationItem/assets/icons.js
index 35730b9da..5205d46a7 100644
--- a/src/components/Item/VisualizationItem/assets/icons.js
+++ b/src/components/Item/VisualizationItem/assets/icons.js
@@ -1,4 +1,5 @@
import React from 'react';
+import { colors } from '@dhis2/ui-core';
export const ThreeDots = () => (
);
+
+export const Warning = () => (
+
+);
diff --git a/src/components/Item/VisualizationItem/styles/FatalErrorBoundary.module.css b/src/components/Item/VisualizationItem/styles/FatalErrorBoundary.module.css
new file mode 100644
index 000000000..a15c79409
--- /dev/null
+++ b/src/components/Item/VisualizationItem/styles/FatalErrorBoundary.module.css
@@ -0,0 +1,13 @@
+.container {
+ text-align: center;
+ margin: 5px;
+}
+
+.icon {
+ vertical-align: middle;
+ margin-right: 3px;
+}
+
+.message {
+ font-size: 13px;
+}