diff --git a/adapter/i18n/en.pot b/adapter/i18n/en.pot
index da6efefa..7cd6b8da 100644
--- a/adapter/i18n/en.pot
+++ b/adapter/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: 2024-04-24T13:58:13.591Z\n"
-"PO-Revision-Date: 2024-04-24T13:58:13.591Z\n"
+"POT-Creation-Date: 2024-06-21T08:27:55.991Z\n"
+"PO-Revision-Date: 2024-06-21T08:27:55.991Z\n"
msgid "Save your data"
msgstr "Save your data"
@@ -39,6 +39,12 @@ msgstr "An error occurred in the DHIS2 application."
msgid "Technical details copied to clipboard"
msgstr "Technical details copied to clipboard"
+msgid "There was a problem loading this plugin"
+msgstr "There was a problem loading this plugin"
+
+msgid "Copy debug info to clipboard"
+msgstr "Copy debug info to clipboard"
+
msgid "Try again"
msgstr "Try again"
@@ -48,9 +54,6 @@ msgstr "Something went wrong"
msgid "Redirect to safe login mode"
msgstr "Redirect to safe login mode"
-msgid "Redirect to safe login mode"
-msgstr "Redirect to safe login mode"
-
msgid "Hide technical details"
msgstr "Hide technical details"
diff --git a/adapter/src/components/ErrorBoundary.js b/adapter/src/components/ErrorBoundary.js
index 6365848d..e8049e84 100644
--- a/adapter/src/components/ErrorBoundary.js
+++ b/adapter/src/components/ErrorBoundary.js
@@ -8,18 +8,35 @@ import styles from './styles/ErrorBoundary.style.js'
// In order to avoid using @dhis2/ui components in the error boundary - as anything
// that breaks within it will not be caught properly - we define a component
// with the same styles as Button
-const UIButton = ({ children, onClick }) => (
+const UIButton = ({ children, onClick, plugin }) => (
<>
-
+
>
)
UIButton.propTypes = {
children: PropTypes.node.isRequired,
onClick: PropTypes.func.isRequired,
+ plugin: PropTypes.bool,
}
+const InfoIcon24 = () => (
+
+)
+
const translatedErrorHeading = i18n.t(
'An error occurred in the DHIS2 application.'
)
@@ -61,6 +78,13 @@ export class ErrorBoundary extends Component {
})
}
+ handleCopyErrorDetailsPlugin = ({ error, errorInfo }) => {
+ const errorDetails = `${error}\n${error?.stack}\n${errorInfo?.componentStack}`
+ navigator.clipboard.writeText(errorDetails).then(() => {
+ alert(i18n.t('Technical details copied to clipboard'))
+ })
+ }
+
handleSafeLoginRedirect = () => {
window.location.href =
this.props.baseURL +
@@ -77,10 +101,26 @@ export class ErrorBoundary extends Component {
<>
-
I am the default plugin boundary
+
+
+ {i18n.t(
+ 'There was a problem loading this plugin'
+ )}
+
+
{
+ this.handleCopyErrorDetailsPlugin({
+ error: this.state.error,
+ errorInfo: this.state.errorInfo,
+ })
+ }}
+ >
+ {i18n.t('Copy debug info to clipboard')}
+
{onRetry && (
-
-
+
+
{i18n.t('Try again')}
diff --git a/adapter/src/components/styles/Button.style.js b/adapter/src/components/styles/Button.style.js
index b251dce3..b096d000 100644
--- a/adapter/src/components/styles/Button.style.js
+++ b/adapter/src/components/styles/Button.style.js
@@ -7,7 +7,8 @@ import css from 'styled-jsx/css'
const grey900 = '#21934',
grey500 = '#a0adba',
grey200 = '#f3f5f7',
- primary600 = '#147cd7'
+ primary600 = '#147cd7',
+ grey600 = '#6C7787'
export default css`
button {
@@ -87,4 +88,15 @@ export default css`
button:focus::after {
border-color: ${primary600};
}
+
+ .pluginButton {
+ /*small*/
+ height: 28px;
+ padding: 0 6px;
+ font-size: 14px;
+ line-height: 16px;
+
+ /*text color for plugin error*/
+ color: ${grey600};
+ }
`
diff --git a/adapter/src/components/styles/ErrorBoundary.style.js b/adapter/src/components/styles/ErrorBoundary.style.js
index cceaa76c..3ab75c0b 100644
--- a/adapter/src/components/styles/ErrorBoundary.style.js
+++ b/adapter/src/components/styles/ErrorBoundary.style.js
@@ -6,7 +6,8 @@ const bgColor = '#F4F6F8',
secondaryTextColor = '#494949',
errorColor = '#D32F2F',
grey050 = '#FBFCFD',
- red200 = '#ffcdd2'
+ grey100 = '#F8F9FA',
+ grey600 = '#6C7787'
export default css`
.mask {
@@ -103,10 +104,28 @@ export default css`
}
.pluginBoundary {
- background-color: ${red200};
+ background-color: ${grey100};
+ height: 100vh;
+ width: 100vw;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding-block-start: 16px;
+ }
+
+ .pluginErrorMessage {
+ margin-block-start: 8px;
+ color: ${grey600};
+ }
+
+ .pluginErrorCopy {
+ margin-block-start: 8px;
+ color: ${grey600};
+ text-decoration: underline;
+ font-size: 14px;
}
- .pluginBoundary span {
- display: inline-block;
+ .pluginRetry {
+ margin-block-start: 16px;
}
`
diff --git a/shell/src/PluginOuterErrorBoundary.js b/shell/src/PluginOuterErrorBoundary.js
index 38f7092a..697490cb 100644
--- a/shell/src/PluginOuterErrorBoundary.js
+++ b/shell/src/PluginOuterErrorBoundary.js
@@ -1,6 +1,23 @@
import PropTypes from 'prop-types'
import React, { Component } from 'react'
+const grey100 = '#F8F9FA',
+ grey600 = '#6C7787'
+
+const InfoIcon24 = () => (
+
+)
+
export class PluginOuterErrorBoundary extends Component {
constructor(props) {
super(props)
@@ -20,7 +37,34 @@ export class PluginOuterErrorBoundary extends Component {
render() {
const { children } = this.props
if (this.state.error) {
- return Plugin outermost error boundary
+ return (
+ <>
+
+
+
+ There was a problem loading this plugin
+
+
+
+ >
+ )
}
return children