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;