From 1a04fdd4bc81a16b225b583de0677c8cdba908cb Mon Sep 17 00:00:00 2001 From: Manuel Martin Date: Wed, 17 Apr 2024 13:24:05 +0200 Subject: [PATCH 1/3] Add support for a system notification that can be configured in the admin --- src/ui/EditorContainer.js | 45 ++++++++++++++------- src/ui/dialogs/NotificationDialog.js | 56 ++++++++++++++++++++++++++ src/ui/layout/Notification.js | 60 ++++++++++++++++++++++++++++ src/ui/projects/ProjectsPage.js | 18 ++++++++- 4 files changed, 164 insertions(+), 15 deletions(-) create mode 100644 src/ui/dialogs/NotificationDialog.js create mode 100644 src/ui/layout/Notification.js diff --git a/src/ui/EditorContainer.js b/src/ui/EditorContainer.js index c100282ed..741b3136b 100644 --- a/src/ui/EditorContainer.js +++ b/src/ui/EditorContainer.js @@ -42,6 +42,7 @@ import defaultTemplateUrl from "./../assets/templates/crater.spoke"; import tutorialTemplateUrl from "./../assets/templates/tutorial.spoke"; import { TERMS, PRIVACY } from "../constants"; +import NotificationDialog from "./dialogs/NotificationDialog"; const StyledEditorContainer = styled.div` display: flex; @@ -104,23 +105,39 @@ class EditorContainer extends Component { const projectId = match.params.projectId; const queryParams = new URLSearchParams(location.search); - if (projectId === "new") { - if (queryParams.has("template")) { - this.loadProjectTemplate(queryParams.get("template")); - } else if (queryParams.has("sceneId")) { - this.loadScene(queryParams.get("sceneId")); + const load = () => { + if (projectId === "new") { + if (queryParams.has("template")) { + this.loadProjectTemplate(queryParams.get("template")); + } else if (queryParams.has("sceneId")) { + this.loadScene(queryParams.get("sceneId")); + } else { + this.loadProjectTemplate(defaultTemplateUrl); + } + } else if (projectId === "tutorial") { + this.loadProjectTemplate(tutorialTemplateUrl, true); } else { - this.loadProjectTemplate(defaultTemplateUrl); + this.loadProject(projectId); } - } else if (projectId === "tutorial") { - this.loadProjectTemplate(tutorialTemplateUrl, true); - } else { - this.loadProject(projectId); - } - if (projectId === "tutorial") { - trackEvent("Tutorial Start"); - this.setState({ onboardingContext: { enabled: true } }); + if (projectId === "tutorial") { + trackEvent("Tutorial Start"); + this.setState({ onboardingContext: { enabled: true } }); + } + }; + + const features = window.APP_CONFIG; + if (features["show_global_notification"]) { + this.showDialog(NotificationDialog, { + title: "Admin notification", + message: features["global_notification_body"], + link: features["global_notification_link"], + onClosed: load, + onConfirm: load, + onCancel: null + }); + } else { + load(); } } diff --git a/src/ui/dialogs/NotificationDialog.js b/src/ui/dialogs/NotificationDialog.js new file mode 100644 index 000000000..568d25f0f --- /dev/null +++ b/src/ui/dialogs/NotificationDialog.js @@ -0,0 +1,56 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import Dialog, { DialogContent } from "./Dialog"; +import styled from "styled-components"; +import { Button } from "../inputs/Button"; + +const NotificationDialogContainer = styled(Dialog)` + max-width: 600px; + + ${DialogContent} { + padding: 0; + } +`; + +const NotificationMessage = styled.code` + white-space: pre-wrap; + overflow-wrap: break-word; + overflow-x: hidden; + overflow-y: auto; + padding: 16px; + color: ${props => props.theme.red}; +`; + +export default class NotificationDialog extends Component { + componentDidMount() {} + + openLink = () => { + window.open(this.props.link); + this.props.onClosed(); + }; + + renderBottomNav() { + return this.props.link ? : null; + } + + render() { + const { message, onClosed, ...props } = this.props; + + return ( + + {message} + + ); + } +} + +NotificationDialog.propTypes = { + title: PropTypes.string.isRequired, + message: PropTypes.string.isRequired, + link: PropTypes.string, + onClosed: PropTypes.func +}; + +NotificationDialog.defaultProps = { + title: "Notification" +}; diff --git a/src/ui/layout/Notification.js b/src/ui/layout/Notification.js new file mode 100644 index 000000000..3ea42b7ab --- /dev/null +++ b/src/ui/layout/Notification.js @@ -0,0 +1,60 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import styled from "styled-components"; + +const NotificationContainer = styled.div` + display: flex; + align-items: center; + justify-content: center; +`; + +const StyledNotification = styled.div` + min-height: 24px; + margin: 1em 20px; + display: flex; + justify-content: center; + align-items: center; + font-size: 1.1em; + padding: 1em; + border-radius: 6px; + background-color: ${props => props.theme.red}; +`; + +const Content = styled.span` + max-width: 50vw; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +`; + +const ViewMore = styled.div` + text-align: center; + margin-left: 1em; + a { + color: ${props => props.theme.blue}; + } +`; + +export default class Notification extends Component { + render() { + const { body, link } = this.props; + return ( + + + {body} + + + Learn more + + + + + ); + } +} + +Notification.propTypes = { + body: PropTypes.string.isRequired, + link: PropTypes.string, + onClosed: PropTypes.func +}; diff --git a/src/ui/projects/ProjectsPage.js b/src/ui/projects/ProjectsPage.js index 375bb6b0d..92574b4eb 100644 --- a/src/ui/projects/ProjectsPage.js +++ b/src/ui/projects/ProjectsPage.js @@ -18,6 +18,7 @@ import { Link } from "react-router-dom"; import LatestUpdate from "../whats-new/LatestUpdate"; import { connectMenu, ContextMenu, MenuItem } from "../layout/ContextMenu"; import styled from "styled-components"; +import Notification from "../layout/Notification"; export const ProjectsSection = styled.section` padding-bottom: 100px; @@ -87,7 +88,10 @@ class ProjectsPage extends Component { scenes: [], loading: isAuthenticated, isAuthenticated, - error: null + error: null, + showGlobalNotification: false, + globalNotificationBody: null, + globalNotificationLink: null }; } @@ -122,6 +126,15 @@ class ProjectsPage extends Component { this.setState({ error, loading: false }); }); } + + const features = window.APP_CONFIG && window.APP_CONFIG["features"]; + if (features) { + this.setState({ + showGlobalNotification: features["show_global_notification"], + globalNotificationBody: features["global_notification_body"], + globalNotificationLink: features["global_notification_link"] + }); + } } onDeleteProject = project => { @@ -172,6 +185,9 @@ class ProjectsPage extends Component {

Projects

+ {this.state.showGlobalNotification && ( + + )} From 0757ed047b4427259f337deef37c8dfb144abd9b Mon Sep 17 00:00:00 2001 From: Manuel Martin Date: Wed, 17 Apr 2024 14:54:47 +0200 Subject: [PATCH 2/3] Fix get features in EditorContainer --- src/ui/EditorContainer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/EditorContainer.js b/src/ui/EditorContainer.js index 741b3136b..65d891e13 100644 --- a/src/ui/EditorContainer.js +++ b/src/ui/EditorContainer.js @@ -126,7 +126,7 @@ class EditorContainer extends Component { } }; - const features = window.APP_CONFIG; + const features = window.APP_CONFIG && window.APP_CONFIG["features"]; if (features["show_global_notification"]) { this.showDialog(NotificationDialog, { title: "Admin notification", From 85e8dbc6680a2e8c6d99eb16edd72c3a8a1aae5e Mon Sep 17 00:00:00 2001 From: Manuel Martin Date: Thu, 18 Apr 2024 15:51:57 +0200 Subject: [PATCH 3/3] Hardcode message --- src/ui/EditorContainer.js | 6 +++++- src/ui/projects/ProjectsPage.js | 13 +++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/ui/EditorContainer.js b/src/ui/EditorContainer.js index 65d891e13..865a55fc2 100644 --- a/src/ui/EditorContainer.js +++ b/src/ui/EditorContainer.js @@ -126,7 +126,11 @@ class EditorContainer extends Component { } }; - const features = window.APP_CONFIG && window.APP_CONFIG["features"]; + const features = { + show_global_notification: true, + global_notification_body: "COPY HERE", + global_notification_link: "https://mozilla.org" + }; if (features["show_global_notification"]) { this.showDialog(NotificationDialog, { title: "Admin notification", diff --git a/src/ui/projects/ProjectsPage.js b/src/ui/projects/ProjectsPage.js index 92574b4eb..173838d76 100644 --- a/src/ui/projects/ProjectsPage.js +++ b/src/ui/projects/ProjectsPage.js @@ -127,14 +127,11 @@ class ProjectsPage extends Component { }); } - const features = window.APP_CONFIG && window.APP_CONFIG["features"]; - if (features) { - this.setState({ - showGlobalNotification: features["show_global_notification"], - globalNotificationBody: features["global_notification_body"], - globalNotificationLink: features["global_notification_link"] - }); - } + this.setState({ + showGlobalNotification: true, + globalNotificationBody: "COPY HERE", + globalNotificationLink: "https://mozilla.org" + }); } onDeleteProject = project => {