diff --git a/src/fireedge/package.json b/src/fireedge/package.json
index d1afda42c4..75cceeac88 100644
--- a/src/fireedge/package.json
+++ b/src/fireedge/package.json
@@ -82,7 +82,6 @@
"fuse.js": "^6.4.1",
"guacamole-lite": "^0.6.3",
"helmet": "^4.1.1",
- "html-entities": "^1.3.1",
"http": "^0.0.1-security",
"http-proxy-middleware": "^1.0.5",
"https": "^1.0.0",
@@ -130,4 +129,4 @@
"yup": "^0.29.3",
"zeromq": "^5.2.0"
}
-}
+}
\ No newline at end of file
diff --git a/src/fireedge/src/client/components/AutoScrollBox/index.js b/src/fireedge/src/client/components/AutoScrollBox/index.js
index 3770fe32df..a6cda462af 100644
--- a/src/fireedge/src/client/components/AutoScrollBox/index.js
+++ b/src/fireedge/src/client/components/AutoScrollBox/index.js
@@ -1,11 +1,24 @@
-import React, { memo, Children, useEffect, useRef, useState } from 'react'
+import React, { memo, useEffect, useRef, useState } from 'react'
import PropTypes from 'prop-types'
-import clsx from 'clsx'
import { makeStyles, Chip, Slide } from '@material-ui/core'
import ArrowBottomIcon from '@material-ui/icons/VerticalAlignBottom'
const useStyles = makeStyles(theme => ({
+ scrollable: {
+ padding: theme.spacing(1),
+ overflowY: 'scroll',
+ '&::-webkit-scrollbar': {
+ width: 14
+ },
+ '&::-webkit-scrollbar-thumb': {
+ backgroundClip: 'content-box',
+ border: '4px solid transparent',
+ borderRadius: 7,
+ boxShadow: 'inset 0 0 0 10px',
+ color: theme.palette.secondary.light
+ }
+ },
wrapperButton: {
top: 5,
position: 'sticky',
@@ -14,8 +27,6 @@ const useStyles = makeStyles(theme => ({
button: { padding: theme.spacing(0, 2) }
}))
-const baseClass = 'react-auto-scroll'
-
const AutoScrollBox = memo(({
children,
className,
@@ -30,9 +41,7 @@ const AutoScrollBox = memo(({
const containerElement = useRef(null)
const style = {
- padding: 8,
height,
- overflowY: 'scroll',
scrollBehavior: 'auto',
pointerEvents: preventInteraction ? 'none' : 'auto'
}
@@ -74,15 +83,9 @@ const AutoScrollBox = memo(({
}, [children, containerElement, autoScroll])
return (
-
+
({
- title: { display: 'flex', gap: '8px' },
- avatar: {
- width: '5ch',
- height: '5ch',
- color: theme.palette.primary.contrastText
- },
- card: { backgroundColor: theme.palette.primary.main }
+ card: { backgroundColor: theme.palette.primary.main },
+ title: { display: 'flex', gap: '0.5rem' }
}))
-
const DatastoreCard = memo(
({ value, isSelected, handleClick, actions }) => {
+ const classes = useStyles()
+
const { ID, NAME, TYPE, STATE } = value
const type = Datastore.TYPES[TYPE]
const state = Datastore.STATES[STATE]
- const classes = useStyles()
-
- const renderChip = ({ label, ...props }) =>
-
return (
- {ID}
+
+
}
- title={(
-
- {NAME}
- {renderChip({ label: type.name })}
-
- )}
- cardHeaderProps={{ disableTypography: true }}
+ title={
+
+
+ {NAME}
+
+ {type.name}
+
+ }
+ subheader={`#${ID}`}
isSelected={isSelected}
handleClick={handleClick}
actions={actions}
diff --git a/src/fireedge/src/client/components/Cards/HostCard.js b/src/fireedge/src/client/components/Cards/HostCard.js
index bb9d4ca0c1..eb070f6356 100644
--- a/src/fireedge/src/client/components/Cards/HostCard.js
+++ b/src/fireedge/src/client/components/Cards/HostCard.js
@@ -1,48 +1,45 @@
import React, { memo } from 'react'
import PropTypes from 'prop-types'
-import { makeStyles, Avatar, Chip, Box, Typography } from '@material-ui/core'
+import { makeStyles, Chip, Box, Typography } from '@material-ui/core'
+import HostIcon from '@material-ui/icons/VideogameAsset'
import SelectCard from 'client/components/Cards/SelectCard'
-import { StatusBadge } from 'client/components/Status'
+import { StatusBadge, StatusChip } from 'client/components/Status'
import Host from 'client/constants/host'
const useStyles = makeStyles(theme => ({
- title: { display: 'flex', gap: '8px' },
- avatar: {
- width: '5ch',
- height: '5ch',
- color: theme.palette.primary.contrastText
- },
- card: { backgroundColor: theme.palette.primary.main }
+ card: { backgroundColor: theme.palette.primary.main },
+ title: { display: 'flex', gap: '0.5rem' }
}))
const HostCard = memo(
({ value, isSelected, handleClick, actions }) => {
+ const classes = useStyles()
+
const { ID, NAME, STATE, IM_MAD: imMad, VM_MAD: vmMad } = value
const state = Host.STATES[STATE]
const mad = imMad === vmMad ? imMad : `${imMad}/${vmMad}`
- const classes = useStyles()
-
- const renderChip = ({ label, ...props }) =>
-
-
return (
- {ID}
+
}
- title={(
-
- {NAME}
- {renderChip({ label: mad })}
-
- )}
+
+ title={
+
+
+ {NAME}
+
+ {mad}
+
+ }
+ subheader={`#${ID}`}
isSelected={isSelected}
handleClick={handleClick}
actions={actions}
diff --git a/src/fireedge/src/client/components/Cards/NetworkCard.js b/src/fireedge/src/client/components/Cards/NetworkCard.js
index 28ac452c30..6df213e6ef 100644
--- a/src/fireedge/src/client/components/Cards/NetworkCard.js
+++ b/src/fireedge/src/client/components/Cards/NetworkCard.js
@@ -1,16 +1,11 @@
import React, { memo } from 'react'
import PropTypes from 'prop-types'
-import { makeStyles, Avatar } from '@material-ui/core'
+import { makeStyles } from '@material-ui/core'
+import NetworkIcon from '@material-ui/icons/AccountTree'
import SelectCard from 'client/components/Cards/SelectCard'
const useStyles = makeStyles(theme => ({
- title: { display: 'flex', gap: '8px' },
- avatar: {
- width: '5ch',
- height: '5ch',
- color: theme.palette.primary.contrastText
- },
card: { backgroundColor: theme.palette.primary.main }
}))
@@ -23,8 +18,9 @@ const NetworkCard = memo(
{ID}}
+ icon={}
title={NAME}
+ subheader={`#${ID}`}
isSelected={isSelected}
handleClick={handleClick}
actions={actions}
diff --git a/src/fireedge/src/client/components/Cards/ProvisionCard.js b/src/fireedge/src/client/components/Cards/ProvisionCard.js
index fc9fcb69a2..4c3a89f958 100644
--- a/src/fireedge/src/client/components/Cards/ProvisionCard.js
+++ b/src/fireedge/src/client/components/Cards/ProvisionCard.js
@@ -38,10 +38,13 @@ const ProvisionCard = memo(
return (
)}
+ action={actions?.map(action =>
+
+ )}
icon={
isProvider ? (
diff --git a/src/fireedge/src/client/components/Cards/ProvisionTemplateCard-delete.js b/src/fireedge/src/client/components/Cards/ProvisionTemplateCard-delete.js
deleted file mode 100644
index 49313db3fb..0000000000
--- a/src/fireedge/src/client/components/Cards/ProvisionTemplateCard-delete.js
+++ /dev/null
@@ -1,56 +0,0 @@
-import React, { memo, useMemo } from 'react'
-import PropTypes from 'prop-types'
-
-import SelectCard from 'client/components/Cards/SelectCard'
-import { isExternalURL } from 'client/utils'
-import { PROVIDER_IMAGES_URL, PROVISION_IMAGES_URL } from 'client/constants'
-
-const ProvisionTemplateCard = memo(
- ({ value, title, isSelected, isProvider, handleClick }) => {
- const IMAGES_URL = isProvider ? PROVIDER_IMAGES_URL : PROVISION_IMAGES_URL
- const { image } = (isProvider ? value?.plain : value) ?? {}
-
- const imgSource = useMemo(() =>
- isExternalURL(image) ? image : `${IMAGES_URL}/${image}`
- , [image])
-
- return (
-
- )
- }, (prev, next) => prev.isSelected === next.isSelected
-)
-
-ProvisionTemplateCard.propTypes = {
- value: PropTypes.shape({
- name: PropTypes.string.isRequired,
- plain: PropTypes.shape({
- image: PropTypes.string
- })
- }),
- title: PropTypes.string,
- isProvider: PropTypes.bool,
- isSelected: PropTypes.bool,
- handleClick: PropTypes.func
-}
-
-ProvisionTemplateCard.defaultProps = {
- value: {},
- title: undefined,
- isProvider: undefined,
- isSelected: undefined,
- handleClick: undefined
-}
-
-ProvisionTemplateCard.displayName = 'ProvisionTemplateCard'
-
-export default ProvisionTemplateCard
diff --git a/src/fireedge/src/client/components/Cards/SelectCard/index.js b/src/fireedge/src/client/components/Cards/SelectCard/index.js
index 25b4dc8d42..4e867fc6f2 100644
--- a/src/fireedge/src/client/components/Cards/SelectCard/index.js
+++ b/src/fireedge/src/client/components/Cards/SelectCard/index.js
@@ -59,29 +59,32 @@ const SelectCard = memo(({
}
>
{/* CARD HEADER */}
- {(title || subheader || icon || action) && }
+ {(title || subheader || icon || action) && (
+
+ )}
{/* CARD CONTENT */}
{children}
@@ -150,10 +153,7 @@ SelectCard.propTypes = {
PropTypes.string,
PropTypes.object
]),
- cardHeaderProps: PropTypes.shape({
- titleTypographyProps: PropTypes.object,
- subheaderTypographyProps: PropTypes.object
- }),
+ cardHeaderProps: PropTypes.object,
mediaProps: PropTypes.shape({
classes: PropTypes.object,
className: PropTypes.string,
diff --git a/src/fireedge/src/client/components/Cards/SelectCard/styles.js b/src/fireedge/src/client/components/Cards/SelectCard/styles.js
index 2acb059cbb..82f7f38a99 100644
--- a/src/fireedge/src/client/components/Cards/SelectCard/styles.js
+++ b/src/fireedge/src/client/components/Cards/SelectCard/styles.js
@@ -34,11 +34,12 @@ export default makeStyles(theme => ({
}
},
media: {},
+ headerRoot: { alignItems: 'end' },
+ headerContent: { overflow: 'auto' },
headerAvatar: {
display: 'flex',
color: theme.palette.primary.contrastText
},
- headerContent: { overflowX: 'hidden' },
header: {
color: theme.palette.primary.contrastText
},
diff --git a/src/fireedge/src/client/components/DebugLog/index.js b/src/fireedge/src/client/components/DebugLog/index.js
index 57ae9e12e7..6f3b3b44ad 100644
--- a/src/fireedge/src/client/components/DebugLog/index.js
+++ b/src/fireedge/src/client/components/DebugLog/index.js
@@ -1,71 +1,30 @@
import React, { useEffect, useState, memo } from 'react'
import PropTypes from 'prop-types'
-import clsx from 'clsx'
import { makeStyles, Box } from '@material-ui/core'
import AutoScrollBox from 'client/components/AutoScrollBox'
+import Message from 'client/components/DebugLog/message'
import { DEBUG_LEVEL } from 'client/constants'
-import AnsiHtml from 'client/components/DebugLog/ansiHtml'
-
-const useStyles = makeStyles(theme => ({
+const debugLogStyles = makeStyles(theme => ({
root: {
- display: 'flex',
- marginBottom: '0.3em',
- padding: '0.5em 0',
- cursor: 'default',
- fontFamily: 'monospace',
- '&:hover': {
- background: '#333537'
+ fontSize: '1.1em',
+ wordBreak: 'break-word',
+ '&::-webkit-scrollbar': {
+ width: 14
+ },
+ '&::-webkit-scrollbar-thumb': {
+ backgroundClip: 'content-box',
+ border: '4px solid transparent',
+ borderRadius: 7,
+ boxShadow: 'inset 0 0 0 10px',
+ color: theme.palette.primary.light
}
- },
- time: {
- paddingLeft: '0.5em',
- minWidth: '220px'
- },
- message: {
- color: '#fafafa'
- },
- [DEBUG_LEVEL.ERROR]: { borderLeft: `0.3em solid ${theme.palette.error.light}` },
- [DEBUG_LEVEL.WARN]: { borderLeft: `0.3em solid ${theme.palette.warning.main}` },
- [DEBUG_LEVEL.INFO]: { borderLeft: `0.3em solid ${theme.palette.info.main}` },
- [DEBUG_LEVEL.DEBUG]: { borderLeft: `0.3em solid ${theme.palette.debug.main}` }
+ }
}))
-// --------------------------------------------
-// MESSAGE COMPONENT
-// --------------------------------------------
-
-const Message = memo(({ timestamp = '', severity = DEBUG_LEVEL.DEBUG, message }) => {
- const classes = useStyles()
- const sanitize = AnsiHtml(message)
-
- return (
-
-
{timestamp}
-
{sanitize}
-
- )
-})
-
-Message.propTypes = {
- timestamp: PropTypes.string,
- severity: PropTypes.string,
- message: PropTypes.string,
- index: PropTypes.oneOfType([
- PropTypes.string,
- PropTypes.number
- ])
-}
-
-Message.defaultProps = { log: [], message: '', index: 0 }
-Message.displayName = 'Message'
-
-// --------------------------------------------
-// DEBUG LOG COMPONENT
-// --------------------------------------------
-
const DebugLog = memo(({ uuid, socket, logDefault }) => {
+ const classes = debugLogStyles()
const [log, setLog] = useState(logDefault)
useEffect(() => {
@@ -83,7 +42,7 @@ const DebugLog = memo(({ uuid, socket, logDefault }) => {
}, [])
return (
-
+
{Object.entries(log)?.map(([command, entries]) =>
Object.entries(entries)?.map(([commandId, messages]) =>
diff --git a/src/fireedge/src/client/components/DebugLog/message.js b/src/fireedge/src/client/components/DebugLog/message.js
new file mode 100644
index 0000000000..e0bb8880c9
--- /dev/null
+++ b/src/fireedge/src/client/components/DebugLog/message.js
@@ -0,0 +1,80 @@
+import React, { memo, useState, useRef } from 'react'
+import PropTypes from 'prop-types'
+import clsx from 'clsx'
+
+import { makeStyles } from '@material-ui/core'
+import ChevronRightIcon from '@material-ui/icons/ChevronRight'
+
+import { DEBUG_LEVEL } from 'client/constants'
+import AnsiHtml from 'client/components/DebugLog/ansiHtml'
+
+const MAX_CHARS = 80
+
+const useStyles = makeStyles(theme => ({
+ root: {
+ display: 'flex',
+ alignItems: 'center',
+ marginBottom: '0.3em',
+ padding: '0.5em 0',
+ cursor: ({ isCollapsed }) => isCollapsed ? 'pointer' : 'default',
+ fontFamily: 'monospace',
+ '&:hover': {
+ background: '#333537'
+ }
+ },
+ arrow: {
+ padding: '0 0.5em',
+ width: '32px'
+ },
+ time: {
+ minWidth: '220px'
+ },
+ message: {
+ color: '#fafafa'
+ },
+ [DEBUG_LEVEL.ERROR]: { borderLeft: `0.3em solid ${theme.palette.error.light}` },
+ [DEBUG_LEVEL.WARN]: { borderLeft: `0.3em solid ${theme.palette.warning.light}` },
+ [DEBUG_LEVEL.INFO]: { borderLeft: `0.3em solid ${theme.palette.info.light}` },
+ [DEBUG_LEVEL.DEBUG]: { borderLeft: `0.3em solid ${theme.palette.debug.main}` }
+}))
+
+// --------------------------------------------
+// MESSAGE COMPONENT
+// --------------------------------------------
+
+const Message = memo(({ timestamp, severity, message }) => {
+ const [isCollapsed, setCollapse] = useState(() => message?.length >= MAX_CHARS)
+ const classes = useStyles({ isCollapsed })
+ const sanitize = AnsiHtml(message)
+
+ return (
+ setCollapse(false)}
+ >
+
+ {isCollapsed && }
+
+
{timestamp}
+
+ {isCollapsed ? `${sanitize.slice(0, MAX_CHARS)}...` : sanitize}
+
+
+ )
+})
+
+Message.propTypes = {
+ timestamp: PropTypes.string,
+ severity: PropTypes.oneOf([Object.keys(DEBUG_LEVEL)]),
+ message: PropTypes.string
+}
+
+Message.defaultProps = {
+ timestamp: '',
+ severity: DEBUG_LEVEL.DEBUG,
+ message: ''
+}
+
+Message.displayName = 'Message'
+
+export default Message
diff --git a/src/fireedge/src/client/components/Header/styles.js b/src/fireedge/src/client/components/Header/styles.js
index b491f3e298..efc087233a 100644
--- a/src/fireedge/src/client/components/Header/styles.js
+++ b/src/fireedge/src/client/components/Header/styles.js
@@ -9,6 +9,7 @@ export default makeStyles(theme => ({
: theme.palette.primary.main
},
title: {
+ userSelect: 'none',
flexGrow: 1,
display: 'inline-flex',
color: theme.palette.primary.contrastText,
diff --git a/src/fireedge/src/client/components/Sidebar/styles.js b/src/fireedge/src/client/components/Sidebar/styles.js
index cc6fa82d8f..6c7b590d7d 100644
--- a/src/fireedge/src/client/components/Sidebar/styles.js
+++ b/src/fireedge/src/client/components/Sidebar/styles.js
@@ -68,6 +68,7 @@ export default makeStyles(theme => ({
// HEADER MENU
// -------------------------------
header: {
+ userSelect: 'none',
display: 'flex',
alignItems: 'center',
padding: '1rem',
diff --git a/src/fireedge/src/client/components/Status/Chip.js b/src/fireedge/src/client/components/Status/Chip.js
index 903c898627..e3f6dec901 100644
--- a/src/fireedge/src/client/components/Status/Chip.js
+++ b/src/fireedge/src/client/components/Status/Chip.js
@@ -1,21 +1,19 @@
import React, { memo } from 'react'
import PropTypes from 'prop-types'
-import { makeStyles, Typography } from '@material-ui/core'
+import { makeStyles, Typography, lighten } from '@material-ui/core'
import { addOpacityToColor } from 'client/utils'
const useStyles = makeStyles(theme => ({
- root: ({ stateColor }) => ({
- color: stateColor,
- backgroundColor: addOpacityToColor(stateColor, 0.08),
+ root: ({ stateColor = theme.palette.primary.main }) => ({
+ color: lighten(stateColor, 0.75),
+ backgroundColor: addOpacityToColor(stateColor, 0.2),
cursor: 'default',
padding: theme.spacing('0.25rem', '0.5rem'),
- minWidth: 20,
borderRadius: 2,
textTransform: 'uppercase',
fontSize: theme.typography.overline.fontSize,
- fontWeight: theme.typography.fontWeightBold,
- lineHeight: 'normal'
+ fontWeight: theme.typography.fontWeightBold
})
}))
diff --git a/src/fireedge/src/client/containers/Providers/Sections/info.js b/src/fireedge/src/client/containers/Providers/Sections/info.js
index f4049e730c..7844d13599 100644
--- a/src/fireedge/src/client/containers/Providers/Sections/info.js
+++ b/src/fireedge/src/client/containers/Providers/Sections/info.js
@@ -40,7 +40,7 @@ const Info = memo(({ data }) => {
{NAME}
- {Tr(T.Description)}
+ {Tr(T.Description)}
{description}
diff --git a/src/fireedge/src/client/containers/Providers/index.js b/src/fireedge/src/client/containers/Providers/index.js
index 71ac418b00..a6cda9a8a1 100644
--- a/src/fireedge/src/client/containers/Providers/index.js
+++ b/src/fireedge/src/client/containers/Providers/index.js
@@ -29,6 +29,8 @@ function Providers () {
useEffect(() => { fetchRequest() }, [])
+ const handleCancel = () => setShowDialog(false)
+
return (
setShowDialog({
id: ID,
- title: `(ID: ${ID}) ${NAME}`
+ title: NAME,
+ subheader: `#${ID}`
}),
actions: [
{
@@ -64,7 +67,7 @@ function Providers () {
{
handleClick: () => setShowDialog({
id: ID,
- title: `DELETE provider - (ID: ${ID}) ${NAME}`,
+ title: `DELETE provider - #${ID} - ${NAME}`,
handleAccept: () => {
deleteProvider({ id: ID })
setShowDialog(false)
@@ -82,11 +85,7 @@ function Providers () {
{showDialog !== false && (
getProvider({ id: showDialog.id })}
- dialogProps={{
- title: showDialog.title,
- handleCancel: () => setShowDialog(false),
- handleAccept: showDialog.handleAccept
- }}
+ dialogProps={{ handleCancel, ...showDialog }}
>
{({ data }) => }
diff --git a/src/fireedge/src/client/containers/Provisions/index.js b/src/fireedge/src/client/containers/Provisions/index.js
index 52746e6925..42771d08ab 100644
--- a/src/fireedge/src/client/containers/Provisions/index.js
+++ b/src/fireedge/src/client/containers/Provisions/index.js
@@ -52,13 +52,14 @@ function Provisions () {
cardsProps={({ value: { ID, NAME } }) => ({
handleClick: () => setShowDialog({
id: ID,
- title: `(ID: ${ID}) ${NAME}`,
+ title: NAME,
+ subheader: `#${ID}`,
content: DialogInfo
}),
actions: [{
handleClick: () => setShowDialog({
id: ID,
- title: `DELETE provision - (ID: ${ID}) ${NAME}`,
+ title: `DELETE provision - #${ID} - ${NAME}`,
handleAccept: () => {
deleteProvision({ id: ID })
setShowDialog(false)
@@ -77,11 +78,7 @@ function Provisions () {
getProvision({ id: showDialog.id })}
- dialogProps={{
- title: showDialog.title,
- handleCancel,
- handleAccept: showDialog.handleAccept
- }}
+ dialogProps={{ handleCancel, ...showDialog }}
>
{props => createElement(showDialog.content, props)}