mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-20 10:50:08 +03:00
parent
b4565b9b78
commit
5c340a5372
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
@ -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 (
|
||||
<div style={{ height }}
|
||||
className={clsx(baseClass, className, {
|
||||
[`${baseClass}--empty`]: Children.count(children) === 0,
|
||||
[`${baseClass}--prevent-interaction`]: preventInteraction,
|
||||
[`${baseClass}--showOption`]: showOption
|
||||
})}
|
||||
>
|
||||
<div style={{ height }} className={className}>
|
||||
<div
|
||||
className={`${baseClass}__scroll-container`}
|
||||
className={classes.scrollable}
|
||||
onWheel={onWheel}
|
||||
ref={containerElement}
|
||||
style={style}
|
||||
|
@ -1,48 +1,43 @@
|
||||
import React, { memo } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import { makeStyles, Chip, Box, Typography, Avatar } from '@material-ui/core'
|
||||
import { makeStyles, Typography } from '@material-ui/core'
|
||||
import DatastoreIcon from '@material-ui/icons/FolderOpen'
|
||||
|
||||
import SelectCard from 'client/components/Cards/SelectCard'
|
||||
import { StatusBadge } from 'client/components/Status'
|
||||
import { StatusBadge, StatusChip } from 'client/components/Status'
|
||||
import Datastore from 'client/constants/datastore'
|
||||
|
||||
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 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 }) =>
|
||||
<Chip size="small" title={label} label={label} {...props} />
|
||||
|
||||
return (
|
||||
<SelectCard
|
||||
stylesProps={{ minHeight: 160 }}
|
||||
cardProps={{ className: classes.card, elevation: 2 }}
|
||||
icon={
|
||||
<StatusBadge stateColor={state.color} >
|
||||
<Avatar className={classes.avatar} title={state.name}>{ID}</Avatar>
|
||||
<StatusBadge stateColor={state.color}>
|
||||
<DatastoreIcon />
|
||||
</StatusBadge>
|
||||
}
|
||||
title={(
|
||||
<Box component="span" className={classes.title}>
|
||||
<Typography noWrap>{NAME}</Typography>
|
||||
{renderChip({ label: type.name })}
|
||||
</Box>
|
||||
)}
|
||||
cardHeaderProps={{ disableTypography: true }}
|
||||
title={
|
||||
<span className={classes.title}>
|
||||
<Typography title={NAME} noWrap component='span'>
|
||||
{NAME}
|
||||
</Typography>
|
||||
<StatusChip stateColor={'#c6c6c6'}>{type.name}</StatusChip>
|
||||
</span>
|
||||
}
|
||||
subheader={`#${ID}`}
|
||||
isSelected={isSelected}
|
||||
handleClick={handleClick}
|
||||
actions={actions}
|
||||
|
@ -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 }) =>
|
||||
<Chip size="small" title={label} label={label} {...props} />
|
||||
|
||||
return (
|
||||
<SelectCard
|
||||
stylesProps={{ minHeight: 160 }}
|
||||
cardProps={{ className: classes.card, elevation: 2 }}
|
||||
icon={
|
||||
<StatusBadge stateColor={state.color}>
|
||||
<Avatar className={classes.avatar} title={state.name}>{ID}</Avatar>
|
||||
<HostIcon />
|
||||
</StatusBadge>
|
||||
}
|
||||
title={(
|
||||
<Box component="span" className={classes.title}>
|
||||
<Typography noWrap>{NAME}</Typography>
|
||||
{renderChip({ label: mad })}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
title={
|
||||
<span className={classes.title}>
|
||||
<Typography title={NAME} noWrap component='span'>
|
||||
{NAME}
|
||||
</Typography>
|
||||
<StatusChip stateColor={'#c6c6c6'}>{mad}</StatusChip>
|
||||
</span>
|
||||
}
|
||||
subheader={`#${ID}`}
|
||||
isSelected={isSelected}
|
||||
handleClick={handleClick}
|
||||
actions={actions}
|
||||
|
@ -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(
|
||||
<SelectCard
|
||||
stylesProps={{ minHeight: 120 }}
|
||||
cardProps={{ className: classes.card, elevation: 2 }}
|
||||
icon={<Avatar className={classes.avatar} title={ID}>{ID}</Avatar>}
|
||||
icon={<NetworkIcon />}
|
||||
title={NAME}
|
||||
subheader={`#${ID}`}
|
||||
isSelected={isSelected}
|
||||
handleClick={handleClick}
|
||||
actions={actions}
|
||||
|
@ -38,10 +38,13 @@ const ProvisionCard = memo(
|
||||
|
||||
return (
|
||||
<SelectCard
|
||||
title={`(ID: ${ID}) - ${NAME}`}
|
||||
title={NAME}
|
||||
subheader={`#${ID}`}
|
||||
isSelected={isSelected}
|
||||
handleClick={handleClick}
|
||||
action={actions?.map(action => <Action key={action?.cy} {...action} />)}
|
||||
action={actions?.map(action =>
|
||||
<Action key={action?.cy} {...action} />
|
||||
)}
|
||||
icon={
|
||||
isProvider ? (
|
||||
<ProviderIcon />
|
||||
|
@ -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 (
|
||||
<SelectCard
|
||||
stylesProps={{ minHeight: 80 }}
|
||||
isSelected={isSelected}
|
||||
handleClick={handleClick}
|
||||
title={title}
|
||||
mediaProps={image && {
|
||||
component: 'img',
|
||||
image: imgSource,
|
||||
draggable: false
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}, (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
|
@ -59,29 +59,32 @@ const SelectCard = memo(({
|
||||
}
|
||||
>
|
||||
{/* CARD HEADER */}
|
||||
{(title || subheader || icon || action) && <CardHeader
|
||||
action={action}
|
||||
avatar={icon}
|
||||
classes={{
|
||||
content: classes.headerContent,
|
||||
avatar: classes.headerAvatar
|
||||
}}
|
||||
title={title}
|
||||
titleTypographyProps={{
|
||||
variant: 'body1',
|
||||
noWrap: true,
|
||||
className: classes.header,
|
||||
title
|
||||
}}
|
||||
subheader={subheader}
|
||||
subheaderTypographyProps={{
|
||||
variant: 'body2',
|
||||
noWrap: true,
|
||||
className: classes.subheader,
|
||||
title: subheader
|
||||
}}
|
||||
{...cardHeaderProps}
|
||||
/>}
|
||||
{(title || subheader || icon || action) && (
|
||||
<CardHeader
|
||||
action={action}
|
||||
avatar={icon}
|
||||
classes={{
|
||||
root: classes.headerRoot,
|
||||
content: classes.headerContent,
|
||||
avatar: classes.headerAvatar
|
||||
}}
|
||||
title={title}
|
||||
titleTypographyProps={{
|
||||
variant: 'body1',
|
||||
noWrap: true,
|
||||
className: classes.header,
|
||||
title: typeof title === 'string' ? title : undefined
|
||||
}}
|
||||
subheader={subheader}
|
||||
subheaderTypographyProps={{
|
||||
variant: 'body2',
|
||||
noWrap: true,
|
||||
className: classes.subheader,
|
||||
title: typeof subheader === 'string' ? subheader : undefined
|
||||
}}
|
||||
{...cardHeaderProps}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 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,
|
||||
|
@ -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
|
||||
},
|
||||
|
@ -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 (
|
||||
<div className={clsx([classes.root, classes[severity]])}>
|
||||
<div className={classes.time}>{timestamp}</div>
|
||||
<div className={classes.message}>{sanitize}</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
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 (
|
||||
<Box borderRadius={5} bgcolor={'#1d1f21'} width={1} height={1} style={{ fontSize: '1.1em', wordBreak: 'break-word' }}>
|
||||
<Box borderRadius={5} bgcolor={'#1d1f21'} width={1} height={1} className={classes.root}>
|
||||
<AutoScrollBox scrollBehavior="auto">
|
||||
{Object.entries(log)?.map(([command, entries]) =>
|
||||
Object.entries(entries)?.map(([commandId, messages]) =>
|
||||
|
80
src/fireedge/src/client/components/DebugLog/message.js
Normal file
80
src/fireedge/src/client/components/DebugLog/message.js
Normal file
@ -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 (
|
||||
<div
|
||||
className={clsx(classes.root, classes[severity])}
|
||||
onClick={() => setCollapse(false)}
|
||||
>
|
||||
<div className={classes.arrow}>
|
||||
{isCollapsed && <ChevronRightIcon fontSize='small' />}
|
||||
</div>
|
||||
<div className={classes.time}>{timestamp}</div>
|
||||
<div className={classes.message}>
|
||||
{isCollapsed ? `${sanitize.slice(0, MAX_CHARS)}...` : sanitize}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
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
|
@ -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,
|
||||
|
@ -68,6 +68,7 @@ export default makeStyles(theme => ({
|
||||
// HEADER MENU
|
||||
// -------------------------------
|
||||
header: {
|
||||
userSelect: 'none',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '1rem',
|
||||
|
@ -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
|
||||
})
|
||||
}))
|
||||
|
||||
|
@ -40,7 +40,7 @@ const Info = memo(({ data }) => {
|
||||
<Typography>{NAME}</Typography>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Typography >{Tr(T.Description)}</Typography>
|
||||
<Typography>{Tr(T.Description)}</Typography>
|
||||
<Typography noWrap>{description}</Typography>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
|
@ -29,6 +29,8 @@ function Providers () {
|
||||
|
||||
useEffect(() => { fetchRequest() }, [])
|
||||
|
||||
const handleCancel = () => setShowDialog(false)
|
||||
|
||||
return (
|
||||
<Container disableGutters>
|
||||
<ListHeader
|
||||
@ -52,7 +54,8 @@ function Providers () {
|
||||
isProvider: true,
|
||||
handleClick: () => 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 && (
|
||||
<DialogRequest
|
||||
request={() => getProvider({ id: showDialog.id })}
|
||||
dialogProps={{
|
||||
title: showDialog.title,
|
||||
handleCancel: () => setShowDialog(false),
|
||||
handleAccept: showDialog.handleAccept
|
||||
}}
|
||||
dialogProps={{ handleCancel, ...showDialog }}
|
||||
>
|
||||
{({ data }) => <Information data={data} />}
|
||||
</DialogRequest>
|
||||
|
@ -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 () {
|
||||
<DialogRequest
|
||||
withTabs
|
||||
request={() => getProvision({ id: showDialog.id })}
|
||||
dialogProps={{
|
||||
title: showDialog.title,
|
||||
handleCancel,
|
||||
handleAccept: showDialog.handleAccept
|
||||
}}
|
||||
dialogProps={{ handleCancel, ...showDialog }}
|
||||
>
|
||||
{props => createElement(showDialog.content, props)}
|
||||
</DialogRequest>
|
||||
|
Loading…
x
Reference in New Issue
Block a user