diff --git a/package-lock.json b/package-lock.json index 69234c4..5365bcb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1316,21 +1316,21 @@ "integrity": "sha512-6NBXdZgRrHbLXw4EMgyqCIzOVAlUgr1+8QGHjlA+n5Iw2Lp/+dP3FTgAfPW/cHR/PBI3cj7gUDVUf/zD/qTPOQ==" }, "@flare/tuitio-client": { - "version": "1.2.3", - "resolved": "https://lab.code-rove.com/public-node-registry/@flare/tuitio-client/-/tuitio-client-1.2.3.tgz", - "integrity": "sha512-m1cJZNTLNXwviD2hkeAvs6I/jlC17GHkUraExfaEaYOUrmDpovE64sg6Xheb01mXnDADCdA2MYxdJgxODNJAqw==", + "version": "1.2.4", + "resolved": "https://lab.code-rove.com/public-node-registry/@flare/tuitio-client/-/tuitio-client-1.2.4.tgz", + "integrity": "sha512-qLVneFf/uACqnr6fIDceVXvIHDmE1y7z6S/sVUPAPHipXmVq8bCiqvCeyGb+If0Mjj16WexedF+FNBltg5UYCA==", "requires": { "@flare/js-utils": "^1.1.0", "axios": "^1.3.2" } }, "@flare/tuitio-client-react": { - "version": "1.2.3", - "resolved": "https://lab.code-rove.com/public-node-registry/@flare/tuitio-client-react/-/tuitio-client-react-1.2.3.tgz", - "integrity": "sha512-ry8eiNJh+TrAVu+PN/vuZ6MJXVMDDEBixz+X37rPOKzY283FhiLSJt76l0rBjfSKuFHyqE8Bx5g4mJ0XgutjMg==", + "version": "1.2.4", + "resolved": "https://lab.code-rove.com/public-node-registry/@flare/tuitio-client-react/-/tuitio-client-react-1.2.4.tgz", + "integrity": "sha512-AM/TXHI8J9YxBMS8P6YHJANYRwVGGNsssR7HU3Mo+EgkTxwImOgT1nkKNZEEQmx1O/KlOxYz58VD3YyDzA0RCQ==", "requires": { "@flare/js-utils": "^1.1.0", - "@flare/tuitio-client": "^1.2.3" + "@flare/tuitio-client": "^1.2.4" } }, "@gar/promisify": { diff --git a/package.json b/package.json index 6bee67e..187d6c6 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "private": true, "dependencies": { "@flare/js-utils": "^1.1.0", - "@flare/tuitio-client-react": "^1.2.3", + "@flare/tuitio-client-react": "^1.2.4", "@material-ui/core": "^4.11.2", "@material-ui/icons": "^4.11.2", "@material-ui/lab": "^4.0.0-alpha.61", diff --git a/public/locales/en/translations.json b/public/locales/en/translations.json index db80bf1..344789b 100644 --- a/public/locales/en/translations.json +++ b/public/locales/en/translations.json @@ -36,6 +36,18 @@ "Label": "Login", "IncorrectCredentials": "Incorrect credentials." }, + "Dashboard": { + "Announcements": { + "Guest": { + "Title": "Hello there! I'm glad you're here!", + "Message": "You are currently browsing my application as a guest. Keep in mind that you cannot perform actions, and most of the data you see is fake. The purpose of the application in this state is for presentation." + }, + "User": { + "Title": "Welcome back, {{userName}}", + "Message": "The application is in continuous development, so if you identify a problem, please report it. Thank you!" + } + } + }, "User": { "Profile": { "Label": "Profile", diff --git a/public/locales/ro/translations.json b/public/locales/ro/translations.json index 6bcaf7d..5c42e97 100644 --- a/public/locales/ro/translations.json +++ b/public/locales/ro/translations.json @@ -27,6 +27,18 @@ "Label": "Autentificare", "IncorrectCredentials": "Credențiale incorecte." }, + "Dashboard": { + "Announcements": { + "Guest": { + "Title": "Salutare! Sunt bucuros ca ești aici!", + "Message": "În acest moment, răsfoiești aplicația mea că invitat. Reține că nu poți efectua acțiuni, iar majoritatea datelor pe care le vezi sunt false. Scopul aplicației în această stare este de prezentare." + }, + "User": { + "Title": "Bine ai revenit, {{userName}}", + "Message": "Aplicația este în continuă dezvoltare, așa că dacă identifici o problemă, te rog să o raportezi. Mulțumesc!" + } + } + }, "User": { "Profile": { "Label": "Profil", diff --git a/src/components/layout/AppRoutes.js b/src/components/layout/AppRoutes.js index 18760a4..0c072b6 100644 --- a/src/components/layout/AppRoutes.js +++ b/src/components/layout/AppRoutes.js @@ -4,7 +4,7 @@ import PageNotFound from "./PageNotFound"; import NetworkContainer from "../../features/network/components/NetworkContainer"; import SystemContainer from "../../features/system/SystemContainer"; import SettingsContainer from "../../features/settings/SettingsContainer"; -import DashboardContainer from "../../features/dashboard/components/DashboardContainer"; +import DashboardContainer from "../../features/dashboard/DashboardContainer"; import UserProfileContainer from "../../features/user/profile/card/UserProfileContainer"; import AboutContainer from "../../features/about/AboutContainer"; diff --git a/src/features/dashboard/DashboardContainer.js b/src/features/dashboard/DashboardContainer.js new file mode 100644 index 0000000..cfac999 --- /dev/null +++ b/src/features/dashboard/DashboardContainer.js @@ -0,0 +1,10 @@ +import React from "react"; +import AnnouncementsSection from "./announcements/AnnouncementsSection"; + +const DashboardContainer = () => ( + <> + + +); + +export default DashboardContainer; diff --git a/src/features/dashboard/announcements/AnnouncementsSection.js b/src/features/dashboard/announcements/AnnouncementsSection.js new file mode 100644 index 0000000..03a2ef7 --- /dev/null +++ b/src/features/dashboard/announcements/AnnouncementsSection.js @@ -0,0 +1,19 @@ +import React from "react"; +import GuestAnnouncement from "./GuestAnnouncement"; +import UserAnnouncement from "./UserAnnouncement"; +import { useTuitioUserInfo } from "@flare/tuitio-client-react"; + +const AnnouncementsSection = () => { + const { userInfo, isGuest } = useTuitioUserInfo(); + const loading = !userInfo; + + if (loading) return ""; + return ( + <> + {isGuest && } + {!isGuest && } + + ); +}; + +export default AnnouncementsSection; diff --git a/src/features/dashboard/announcements/GuestAnnouncement.js b/src/features/dashboard/announcements/GuestAnnouncement.js new file mode 100644 index 0000000..a7ba9e4 --- /dev/null +++ b/src/features/dashboard/announcements/GuestAnnouncement.js @@ -0,0 +1,21 @@ +import React from "react"; +import { makeStyles } from "@material-ui/core/styles"; +import { Alert, AlertTitle } from "@material-ui/lab"; +import styles from "../styles"; +import { useTranslation } from "react-i18next"; + +const useStyles = makeStyles(styles); + +export default function GuestAnnouncement() { + const classes = useStyles(); + const { t } = useTranslation(); + + return ( +
+ + {t("Dashboard.Announcements.Guest.Title")} + {t("Dashboard.Announcements.Guest.Message")} + +
+ ); +} diff --git a/src/features/dashboard/announcements/UserAnnouncement.js b/src/features/dashboard/announcements/UserAnnouncement.js new file mode 100644 index 0000000..9ef80d6 --- /dev/null +++ b/src/features/dashboard/announcements/UserAnnouncement.js @@ -0,0 +1,30 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { makeStyles } from "@material-ui/core/styles"; +import { Alert, AlertTitle } from "@material-ui/lab"; +import styles from "../styles"; +import { useTranslation } from "react-i18next"; + +const useStyles = makeStyles(styles); + +export default function UserAnnouncement({ userData }) { + const classes = useStyles(); + const { t } = useTranslation(); + + return ( +
+ + + {t("Dashboard.Announcements.User.Title", { + userName: userData.firstName + })} + + {t("Dashboard.Announcements.User.Message")} + +
+ ); +} + +UserAnnouncement.propTypes = { + userData: PropTypes.object.isRequired +}; diff --git a/src/features/dashboard/components/DashboardContainer.js b/src/features/dashboard/components/DashboardContainer.js deleted file mode 100644 index 88c8ee0..0000000 --- a/src/features/dashboard/components/DashboardContainer.js +++ /dev/null @@ -1,5 +0,0 @@ -import React from "react"; - -const DashboardContainer = () =>

In development...

; - -export default DashboardContainer; diff --git a/src/features/dashboard/styles.js b/src/features/dashboard/styles.js new file mode 100644 index 0000000..6391186 --- /dev/null +++ b/src/features/dashboard/styles.js @@ -0,0 +1,10 @@ +const styles = theme => ({ + alert: { + width: "100%", + "& > * + *": { + marginTop: theme.spacing(1) + } + } +}); + +export default styles; diff --git a/src/features/machines/components/common/ActionButton.js b/src/features/machines/components/common/ActionButton.js index bf3742e..3e65812 100644 --- a/src/features/machines/components/common/ActionButton.js +++ b/src/features/machines/components/common/ActionButton.js @@ -3,7 +3,7 @@ import PropTypes from "prop-types"; import { IconButton, Tooltip } from "@material-ui/core"; const ActionButton = React.forwardRef((props, _ref) => { - const { action, machine, callback } = props; + const { action, machine, callback, disabled } = props; const id = `machine-item-${machine.machineId}-${action.code}`; const handleActionClick = event => { action.effect(machine, event); @@ -22,6 +22,7 @@ const ActionButton = React.forwardRef((props, _ref) => { size={"small"} onFocus={event => event.stopPropagation()} onClick={handleActionClick} + disabled={disabled} > @@ -39,7 +40,8 @@ ActionButton.propTypes = { tooltip: PropTypes.string.isRequired, effect: PropTypes.func.isRequired }).isRequired, - callback: PropTypes.func + callback: PropTypes.func, + disabled: PropTypes.bool }; export default ActionButton; diff --git a/src/features/machines/components/common/ActionsGroup.js b/src/features/machines/components/common/ActionsGroup.js index 90ad39c..0f12835 100644 --- a/src/features/machines/components/common/ActionsGroup.js +++ b/src/features/machines/components/common/ActionsGroup.js @@ -5,11 +5,13 @@ import ActionButton from "./ActionButton"; import { Menu } from "@material-ui/core"; import { MoreHoriz } from "@material-ui/icons"; import { useTranslation } from "react-i18next"; +import { useTuitioUserInfo } from "@flare/tuitio-client-react"; const ActionsGroup = ({ machine, actions, addLog }) => { const [menuAnchor, setMenuAnchor] = useState(null); const { t } = useTranslation(); + const { isSysAdmin } = useTuitioUserInfo(); const mainActions = useMemo( () => actions.filter(a => a.main === true), @@ -31,12 +33,13 @@ const ActionsGroup = ({ machine, actions, addLog }) => { return ( <> - + {mainActions.map(action => ( ))} { action={action} machine={machine} callback={handleMenuClose} + disabled={!isSysAdmin} /> ))} diff --git a/src/features/machines/components/common/WakeComponent.js b/src/features/machines/components/common/WakeComponent.js index 416918b..f118c9a 100644 --- a/src/features/machines/components/common/WakeComponent.js +++ b/src/features/machines/components/common/WakeComponent.js @@ -11,7 +11,7 @@ const initialState = { on: false }; const defaultPingInterval = 1200000; //20 minutes const defaultStartingTime = 300000; //5 minutes -const WakeComponent = ({ machine, addLog }) => { +const WakeComponent = ({ machine, addLog, disabled }) => { const [state, setState] = useState(initialState); const [trigger, setTrigger] = useState(false); @@ -91,9 +91,9 @@ const WakeComponent = ({ machine, addLog }) => { event.stopPropagation()} > @@ -105,7 +105,8 @@ const WakeComponent = ({ machine, addLog }) => { WakeComponent.propTypes = { machine: PropTypes.object.isRequired, - addLog: PropTypes.func.isRequired + addLog: PropTypes.func.isRequired, + disabled: PropTypes.bool }; export default WakeComponent;