diff --git a/frontend/web/components/App.js b/frontend/web/components/App.js
index 7d1eef011414..c2ca0c3a374a 100644
--- a/frontend/web/components/App.js
+++ b/frontend/web/components/App.js
@@ -1,4 +1,4 @@
-import React, { Component } from 'react'
+import React, { Component, Fragment } from 'react'
import { matchPath } from 'react-router'
import { withRouter } from 'react-router-dom'
import amplitude from 'amplitude-js'
@@ -22,6 +22,7 @@ import { getOrganisationUsage } from 'common/services/useOrganisationUsage'
import Button from './base/forms/Button'
import Icon from 'components/Icon'
import AccountStore from 'common/stores/account-store'
+import InfoMessage from './InfoMessage'
const App = class extends Component {
static propTypes = {
@@ -38,6 +39,7 @@ const App = class extends Component {
lastEnvironmentId: '',
lastProjectId: '',
pin: '',
+ showAnnouncement: true,
totalApiCalls: 0,
}
@@ -210,6 +212,11 @@ const App = class extends Component {
this.context.router.history.replace('/')
}
+ closeAnnouncement = (announcementId) => {
+ this.setState({ showAnnouncement: false })
+ flagsmith.setTrait(`dismissed_announcement`, announcementId)
+ }
+
render() {
if (
Utils.getFlagsmithHasFeature('dark_mode') &&
@@ -276,6 +283,11 @@ const App = class extends Component {
if (document.location.href.includes('widget')) {
return
{this.props.children}
}
+ const announcementValue = JSON.parse(
+ Utils.getFlagsmithValue('announcement'),
+ )
+ const dismissed = flagsmith.getTrait('dismissed_announcement')
+ const showBanner = !dismissed || dismissed !== announcementValue.id
return (
@@ -471,7 +483,30 @@ const App = class extends Component {
) : (
- this.props.children
+
+ {user &&
+ showBanner &&
+ Utils.getFlagsmithHasFeature('announcement') &&
+ this.state.showAnnouncement && (
+
+
+ this.closeAnnouncement(announcementValue.id)
+ }
+ buttonText={announcementValue.buttonText}
+ url={announcementValue.url}
+ >
+
+
{announcementValue.description}
+
+
+
+ )}
+ {this.props.children}
+
)}
)}
diff --git a/frontend/web/components/InfoMessage.js b/frontend/web/components/InfoMessage.js
index ad55ec3edb59..be3787e917bc 100644
--- a/frontend/web/components/InfoMessage.js
+++ b/frontend/web/components/InfoMessage.js
@@ -5,16 +5,40 @@ import Icon from './Icon'
export default class InfoMessage extends PureComponent {
static displayName = 'InfoMessage'
+ handleOpenNewWindow = () => {
+ window.open(this.props.url, '_blank')
+ if (this.props.isClosable) {
+ this.props.close()
+ }
+ }
+
render() {
+ const infoMessageClass = `alert alert-info ${
+ this.props.infoMessageClass || 'flex-1'
+ }`
+ const titleDescClass = this.props.infoMessageClass
+ ? `${this.props.infoMessageClass} body mr-2`
+ : ''
+
return (
-
+
-
+
{this.props.title || 'NOTE'}
{this.props.children}
+ {this.props.url && (
+
+ )}
+ {this.props.isClosable && (
+
+
+
+ )}
)
}
diff --git a/frontend/web/styles/project/_alert.scss b/frontend/web/styles/project/_alert.scss
index 69774f4ca21e..37daba5b6ea7 100644
--- a/frontend/web/styles/project/_alert.scss
+++ b/frontend/web/styles/project/_alert.scss
@@ -56,6 +56,18 @@
color: $text-icon-dark;
}
}
+
+.announcement {
+ margin: auto;
+ margin-top: 10px;
+ display: flex;
+ flex-direction: row;
+ .body {
+ flex-direction: column;
+ justify-content: flex-start;
+ }
+}
+
.dark {
.alert {
color: $alert-color-dark;