[release] v0.4.0-unstable7

This commit is contained in:
Yann Stepienik 2023-05-08 14:15:53 +01:00
parent 08d7dbbe4e
commit b4080e14f8
10 changed files with 78 additions and 44 deletions

View file

@ -0,0 +1,19 @@
import { Button, useMediaQuery, IconButton } from "@mui/material";
const ResponsiveButton = ({ children, startIcon, size, style, ...props }) => {
const isMobile = useMediaQuery((theme) => theme.breakpoints.down('sm'));
let newStyle = style || {};
if (isMobile) {
newStyle.minHeight = '40px';
newStyle.fontSize = '145%'
}
return (
<Button className="responsive-button" size={isMobile ? 'large' : size} startIcon={isMobile ? null : startIcon} {...props} style={newStyle}>
{isMobile ? startIcon : children}
</Button>
);
}
export default ResponsiveButton;

View file

@ -8,6 +8,7 @@ const StyledTabs = styled(Tabs)`
const TabPanel = (props) => { const TabPanel = (props) => {
const { children, value, index, ...other } = props; const { children, value, index, ...other } = props;
const isMobile = useMediaQuery((theme) => theme.breakpoints.down('md'));
return ( return (
<div <div
@ -21,7 +22,7 @@ const TabPanel = (props) => {
{...other} {...other}
> >
{value === index && ( {value === index && (
<Box p={3}> <Box p={isMobile ? 1 : 3}>
<Typography>{children}</Typography> <Typography>{children}</Typography>
</Box> </Box>
)} )}
@ -38,7 +39,7 @@ const a11yProps = (index) => {
const PrettyTabbedView = ({ tabs, isLoading }) => { const PrettyTabbedView = ({ tabs, isLoading }) => {
const [value, setValue] = useState(0); const [value, setValue] = useState(0);
const isMobile = useMediaQuery((theme) => theme.breakpoints.down('sm')); const isMobile = useMediaQuery((theme) => theme.breakpoints.down('md'));
const handleChange = (event, newValue) => { const handleChange = (event, newValue) => {
setValue(newValue); setValue(newValue);
@ -51,7 +52,7 @@ const PrettyTabbedView = ({ tabs, isLoading }) => {
return ( return (
<Box display="flex" height="100%" flexDirection={isMobile ? 'column' : 'row'}> <Box display="flex" height="100%" flexDirection={isMobile ? 'column' : 'row'}>
{isMobile ? ( {isMobile ? (
<Select value={value} onChange={handleSelectChange} sx={{ minWidth: 120 }}> <Select value={value} onChange={handleSelectChange} sx={{ minWidth: 120, marginBottom: '15px' }}>
{tabs.map((tab, index) => ( {tabs.map((tab, index) => (
<MenuItem key={index} value={index}> <MenuItem key={index} value={index}>
{tab.title} {tab.title}

View file

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { IconButton, Tooltip } from '@mui/material'; import { IconButton, Tooltip, useMediaQuery } from '@mui/material';
import { CheckCircleOutlined, CloseSquareOutlined, DeleteOutlined, PauseCircleOutlined, PlaySquareOutlined, ReloadOutlined, RollbackOutlined, StopOutlined, UpCircleOutlined } from '@ant-design/icons'; import { CheckCircleOutlined, CloseSquareOutlined, DeleteOutlined, PauseCircleOutlined, PlaySquareOutlined, ReloadOutlined, RollbackOutlined, StopOutlined, UpCircleOutlined } from '@ant-design/icons';
import * as API from '../../api'; import * as API from '../../api';
@ -10,6 +10,8 @@ const GetActions = ({
setIsUpdatingId setIsUpdatingId
}) => { }) => {
const [confirmDelete, setConfirmDelete] = React.useState(false); const [confirmDelete, setConfirmDelete] = React.useState(false);
const isMiniMobile = useMediaQuery((theme) => theme.breakpoints.down('xsm'));
console.log(isMiniMobile)
const doTo = (action) => { const doTo = (action) => {
setIsUpdatingId(Id, true); setIsUpdatingId(Id, true);
@ -22,56 +24,56 @@ const GetActions = ({
{ {
t: 'Update Available', t: 'Update Available',
if: ['update_available'], if: ['update_available'],
e: <IconButton className="shinyButton" color='primary' onClick={() => {doTo('update')}} size='large'> e: <IconButton className="shinyButton" color='primary' onClick={() => {doTo('update')}} size={isMiniMobile ? 'medium' : 'large'}>
<UpCircleOutlined /> <UpCircleOutlined />
</IconButton> </IconButton>
}, },
{ {
t: 'Start', t: 'Start',
if: ['exited', 'created'], if: ['exited', 'created'],
e: <IconButton onClick={() => {doTo('start')}} size='large'> e: <IconButton onClick={() => {doTo('start')}} size={isMiniMobile ? 'medium' : 'large'}>
<PlaySquareOutlined /> <PlaySquareOutlined />
</IconButton> </IconButton>
}, },
{ {
t: 'Unpause', t: 'Unpause',
if: ['paused'], if: ['paused'],
e: <IconButton onClick={() => {doTo('unpause')}} size='large'> e: <IconButton onClick={() => {doTo('unpause')}} size={isMiniMobile ? 'medium' : 'large'}>
<PlaySquareOutlined /> <PlaySquareOutlined />
</IconButton> </IconButton>
}, },
{ {
t: 'Pause', t: 'Pause',
if: ['running'], if: ['running'],
e: <IconButton onClick={() => {doTo('pause')}} size='large'> e: <IconButton onClick={() => {doTo('pause')}} size={isMiniMobile ? 'medium' : 'large'}>
<PauseCircleOutlined /> <PauseCircleOutlined />
</IconButton> </IconButton>
}, },
{ {
t: 'Stop', t: 'Stop',
if: ['paused', 'restarting', 'running'], if: ['paused', 'restarting', 'running'],
e: <IconButton onClick={() => {doTo('stop')}} size='large' variant="outlined"> e: <IconButton onClick={() => {doTo('stop')}} size={isMiniMobile ? 'medium' : 'large'} variant="outlined">
<StopOutlined /> <StopOutlined />
</IconButton> </IconButton>
}, },
{ {
t: 'Restart', t: 'Restart',
if: ['exited', 'running', 'paused', 'created', 'restarting'], if: ['exited', 'running', 'paused', 'created', 'restarting'],
e: <IconButton onClick={() => doTo('restart')} size='large'> e: <IconButton onClick={() => doTo('restart')} size={isMiniMobile ? 'medium' : 'large'}>
<ReloadOutlined /> <ReloadOutlined />
</IconButton> </IconButton>
}, },
{ {
t: 'Re-create', t: 'Re-create',
if: ['exited', 'running', 'paused', 'created', 'restarting'], if: ['exited', 'running', 'paused', 'created', 'restarting'],
e: <IconButton onClick={() => doTo('recreate')} color="error" size='large'> e: <IconButton onClick={() => doTo('recreate')} color="error" size={isMiniMobile ? 'medium' : 'large'}>
<RollbackOutlined /> <RollbackOutlined />
</IconButton> </IconButton>
}, },
{ {
t: 'Kill', t: 'Kill',
if: ['running', 'paused', 'created', 'restarting'], if: ['running', 'paused', 'created', 'restarting'],
e: <IconButton onClick={() => doTo('kill')} color="error" size='large'> e: <IconButton onClick={() => doTo('kill')} color="error" size={isMiniMobile ? 'medium' : 'large'}>
<CloseSquareOutlined /> <CloseSquareOutlined />
</IconButton> </IconButton>
}, },

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Formik } from 'formik'; import { Formik } from 'formik';
import { Button, Stack, Grid, MenuItem, TextField, IconButton, FormHelperText, CircularProgress, useTheme, Alert } from '@mui/material'; import { Button, Stack, Grid, MenuItem, TextField, IconButton, FormHelperText, CircularProgress, useTheme, Alert, useMediaQuery } from '@mui/material';
import MainCard from '../../../components/MainCard'; import MainCard from '../../../components/MainCard';
import { CosmosCheckbox, CosmosFormDivider, CosmosInputText, CosmosSelect } import { CosmosCheckbox, CosmosFormDivider, CosmosInputText, CosmosSelect }
from '../../config/users/formShortcuts'; from '../../config/users/formShortcuts';
@ -15,6 +15,8 @@ const NetworkContainerSetup = ({ config, containerInfo, refresh }) => {
const [networks, setNetworks] = React.useState([]); const [networks, setNetworks] = React.useState([]);
const theme = useTheme(); const theme = useTheme();
const isDark = theme.palette.mode === 'dark'; const isDark = theme.palette.mode === 'dark';
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
const padding = isMobile ? '15px 4px' : '20px 10px';
React.useEffect(() => { React.useEffect(() => {
API.docker.networkList().then((res) => { API.docker.networkList().then((res) => {
@ -101,11 +103,11 @@ const NetworkContainerSetup = ({ config, containerInfo, refresh }) => {
<form noValidate onSubmit={formik.handleSubmit}> <form noValidate onSubmit={formik.handleSubmit}>
<Stack spacing={2}> <Stack spacing={2}>
<MainCard title={'Ports'}> <MainCard title={'Ports'}>
<Grid container spacing={4}> <Stack spacing={4}>
<Grid item xs={12}> <div>
{formik.values.ports.map((port, idx) => ( {formik.values.ports.map((port, idx) => (
<Grid container spacing={2} key={idx}> <Grid container spacing={2} key={idx}>
<Grid item xs={4} style={{ padding: '20px 10px' }}> <Grid item xs={4} style={{ padding }}>
<TextField <TextField
label="Container Port" label="Container Port"
fullWidth fullWidth
@ -117,7 +119,7 @@ const NetworkContainerSetup = ({ config, containerInfo, refresh }) => {
}} }}
/> />
</Grid> </Grid>
<Grid item xs={4} style={{ padding: '20px 10px' }}> <Grid item xs={4} style={{ padding }}>
<TextField <TextField
fullWidth fullWidth
label="Host port" label="Host port"
@ -129,7 +131,7 @@ const NetworkContainerSetup = ({ config, containerInfo, refresh }) => {
}} }}
/> />
</Grid> </Grid>
<Grid item xs={3} style={{ padding: '20px 10px' }}> <Grid item xs={3} style={{ padding }}>
<TextField <TextField
className="px-2 my-2" className="px-2 my-2"
variant="outlined" variant="outlined"
@ -147,7 +149,7 @@ const NetworkContainerSetup = ({ config, containerInfo, refresh }) => {
<MenuItem value="udp">UDP</MenuItem> <MenuItem value="udp">UDP</MenuItem>
</TextField> </TextField>
</Grid> </Grid>
<Grid item xs={1} style={{ padding: '20px 10px' }}> <Grid item xs={1} style={{ padding }}>
<IconButton <IconButton
fullWidth fullWidth
variant="outlined" variant="outlined"
@ -180,8 +182,8 @@ const NetworkContainerSetup = ({ config, containerInfo, refresh }) => {
> >
<PlusCircleOutlined /> <PlusCircleOutlined />
</IconButton> </IconButton>
</Grid> </div>
<Grid item xs={12}> <div>
<Stack direction="column" spacing={2}> <Stack direction="column" spacing={2}>
{formik.errors.submit && ( {formik.errors.submit && (
<Grid item xs={12}> <Grid item xs={12}>
@ -201,8 +203,8 @@ const NetworkContainerSetup = ({ config, containerInfo, refresh }) => {
Update Ports Update Ports
</LoadingButton> </LoadingButton>
</Stack> </Stack>
</Grid> </div>
</Grid> </Stack>
</MainCard> </MainCard>
<MainCard title={'Networks'}> <MainCard title={'Networks'}>
<Stack spacing={2}> <Stack spacing={2}>

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Formik } from 'formik'; import { Formik } from 'formik';
import { Button, Stack, Grid, MenuItem, TextField, IconButton, FormHelperText } from '@mui/material'; import { Button, Stack, Grid, MenuItem, TextField, IconButton, FormHelperText, useMediaQuery, useTheme } from '@mui/material';
import MainCard from '../../../components/MainCard'; import MainCard from '../../../components/MainCard';
import { CosmosCheckbox, CosmosFormDivider, CosmosInputText, CosmosSelect } import { CosmosCheckbox, CosmosFormDivider, CosmosInputText, CosmosSelect }
from '../../config/users/formShortcuts'; from '../../config/users/formShortcuts';
@ -15,6 +15,9 @@ const DockerContainerSetup = ({config, containerInfo, refresh}) => {
['on-failure', 'Restart On Failure'], ['on-failure', 'Restart On Failure'],
['unless-stopped', 'Restart Unless Stopped'], ['unless-stopped', 'Restart Unless Stopped'],
]; ];
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
const padding = isMobile ? '15px 4px' : '20px 10px';
return ( return (
<div style={{ maxWidth: '1000px', width: '100%', margin: '', position: 'relative' }}> <div style={{ maxWidth: '1000px', width: '100%', margin: '', position: 'relative' }}>
@ -97,7 +100,7 @@ const DockerContainerSetup = ({config, containerInfo, refresh}) => {
<Grid item xs={12}> <Grid item xs={12}>
{formik.values.envVars.map((envVar, idx) => ( {formik.values.envVars.map((envVar, idx) => (
<Grid container spacing={2} key={idx}> <Grid container spacing={2} key={idx}>
<Grid item xs={5} style={{padding: '20px 10px'}}> <Grid item xs={5} style={{padding}}>
<TextField <TextField
label="Key" label="Key"
fullWidth fullWidth
@ -109,7 +112,7 @@ const DockerContainerSetup = ({config, containerInfo, refresh}) => {
}} }}
/> />
</Grid> </Grid>
<Grid item xs={6} style={{padding: '20px 10px'}}> <Grid item xs={6} style={{padding}}>
<TextField <TextField
fullWidth fullWidth
label="Value" label="Value"
@ -121,7 +124,7 @@ const DockerContainerSetup = ({config, containerInfo, refresh}) => {
}} }}
/> />
</Grid> </Grid>
<Grid item xs={1} style={{padding: '20px 10px'}}> <Grid item xs={1} style={{padding}}>
<IconButton <IconButton
fullWidth fullWidth
variant="outlined" variant="outlined"
@ -155,7 +158,7 @@ const DockerContainerSetup = ({config, containerInfo, refresh}) => {
<Grid item xs={12}> <Grid item xs={12}>
{formik.values.labels.map((label, idx) => ( {formik.values.labels.map((label, idx) => (
<Grid container spacing={2} key={idx}> <Grid container spacing={2} key={idx}>
<Grid item xs={5} style={{padding: '20px 10px'}}> <Grid item xs={5} style={{padding}}>
<TextField <TextField
fullWidth fullWidth
label="Key" label="Key"
@ -167,7 +170,7 @@ const DockerContainerSetup = ({config, containerInfo, refresh}) => {
}} }}
/> />
</Grid> </Grid>
<Grid item xs={6} style={{padding: '20px 10px'}}> <Grid item xs={6} style={{padding}}>
<TextField <TextField
label="Value" label="Value"
fullWidth fullWidth
@ -179,7 +182,7 @@ const DockerContainerSetup = ({config, containerInfo, refresh}) => {
}} }}
/> />
</Grid> </Grid>
<Grid item xs={1} style={{padding: '20px 10px'}}> <Grid item xs={1} style={{padding}}>
<IconButton <IconButton
fullWidth fullWidth
variant="outlined" variant="outlined"

View file

@ -4,12 +4,13 @@ import { Button, Stack, Grid, MenuItem, TextField, IconButton, FormHelperText, C
import MainCard from '../../../components/MainCard'; import MainCard from '../../../components/MainCard';
import { CosmosCheckbox, CosmosFormDivider, CosmosInputText, CosmosSelect } import { CosmosCheckbox, CosmosFormDivider, CosmosInputText, CosmosSelect }
from '../../config/users/formShortcuts'; from '../../config/users/formShortcuts';
import { ApiOutlined, CheckCircleOutlined, CloseCircleOutlined, DeleteOutlined, PlusCircleOutlined } from '@ant-design/icons'; import { ApiOutlined, CheckCircleOutlined, CloseCircleOutlined, DeleteOutlined, PlayCircleOutlined, PlusCircleOutlined } from '@ant-design/icons';
import * as API from '../../../api'; import * as API from '../../../api';
import { LoadingButton } from '@mui/lab'; import { LoadingButton } from '@mui/lab';
import PrettyTableView from '../../../components/tableView/prettyTableView'; import PrettyTableView from '../../../components/tableView/prettyTableView';
import { NetworksColumns } from '../networks'; import { NetworksColumns } from '../networks';
import NewNetworkButton from '../createNetwork'; import NewNetworkButton from '../createNetwork';
import ResponsiveButton from '../../../components/responseiveButton';
const VolumeContainerSetup = ({ config, containerInfo, refresh }) => { const VolumeContainerSetup = ({ config, containerInfo, refresh }) => {
const restartPolicies = [ const restartPolicies = [
@ -96,7 +97,7 @@ const VolumeContainerSetup = ({ config, containerInfo, refresh }) => {
getKey={(r) => r.Id} getKey={(r) => r.Id}
fullWidth fullWidth
buttons={[ buttons={[
<Button variant="outlined" color="primary" onClick={() => { <ResponsiveButton startIcon={<PlusCircleOutlined />} variant="outlined" color="primary" onClick={() => {
formik.setFieldValue('volumes', [...formik.values.volumes, { formik.setFieldValue('volumes', [...formik.values.volumes, {
Type: 'volume', Type: 'volume',
Name: '', Name: '',
@ -107,7 +108,7 @@ const VolumeContainerSetup = ({ config, containerInfo, refresh }) => {
}]); }]);
}}> }}>
New Mount Point New Mount Point
</Button> </ResponsiveButton>
]} ]}
columns={[ columns={[
{ {

View file

@ -15,6 +15,7 @@ import * as Yup from 'yup';
import * as API from '../../api'; import * as API from '../../api';
import { CosmosCheckbox } from '../config/users/formShortcuts'; import { CosmosCheckbox } from '../config/users/formShortcuts';
import ResponsiveButton from '../../components/responseiveButton';
const NewNetworkButton = ({ fullWidth, refresh }) => { const NewNetworkButton = ({ fullWidth, refresh }) => {
const [isOpened, setIsOpened] = useState(false); const [isOpened, setIsOpened] = useState(false);
@ -112,13 +113,13 @@ const NewNetworkButton = ({ fullWidth, refresh }) => {
</DialogActions>} </DialogActions>}
</FormikProvider> </FormikProvider>
</Dialog> </Dialog>
<Button <ResponsiveButton
fullWidth={fullWidth} fullWidth={fullWidth}
onClick={() => setIsOpened(true)} onClick={() => setIsOpened(true)}
startIcon={<PlusCircleOutlined />} startIcon={<PlusCircleOutlined />}
> >
New Network New Network
</Button> </ResponsiveButton>
</>; </>;
}; };

View file

@ -16,6 +16,7 @@ import HostChip from '../../components/hostChip';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import ExposeModal from './exposeModal'; import ExposeModal from './exposeModal';
import GetActions from './actionBar'; import GetActions from './actionBar';
import ResponsiveButton from '../../components/responseiveButton';
const Item = styled(Paper)(({ theme }) => ({ const Item = styled(Paper)(({ theme }) => ({
backgroundColor: theme.palette.mode === 'dark' ? '#1A2027' : '#fff', backgroundColor: theme.palette.mode === 'dark' ? '#1A2027' : '#fff',
@ -127,7 +128,7 @@ const ServeApps = () => {
} }
/> />
<Stack spacing={2}> <Stack spacing={{xs: 1, sm: 1, md: 2 }}>
<Stack direction="row" spacing={2}> <Stack direction="row" spacing={2}>
<Input placeholder="Search" <Input placeholder="Search"
value={search} value={search}
@ -140,23 +141,26 @@ const ServeApps = () => {
setSearch(e.target.value); setSearch(e.target.value);
}} }}
/> />
<Button variant="contained" startIcon={<ReloadOutlined />} onClick={() => { <ResponsiveButton variant="contained" startIcon={<ReloadOutlined />} onClick={() => {
refreshServeApps(); refreshServeApps();
}}>Refresh</Button> }}>Refresh</ResponsiveButton>
<Tooltip title="This is not implemented yet."> <Tooltip title="This is not implemented yet.">
<span style={{ cursor: 'not-allowed' }}> <span style={{ cursor: 'not-allowed' }}>
<Button variant="contained" startIcon={<AppstoreAddOutlined />} disabled>Start ServApp</Button> <ResponsiveButton
variant="contained"
startIcon={<AppstoreAddOutlined />}
disabled >Start ServApp</ResponsiveButton>
</span> </span>
</Tooltip> </Tooltip>
</Stack> </Stack>
<Grid2 container spacing={2}> <Grid2 container spacing={{xs: 1, sm: 1, md: 2 }}>
{serveApps && serveApps.filter(app => search.length < 2 || app.Names[0].toLowerCase().includes(search.toLowerCase())).map((app) => { {serveApps && serveApps.filter(app => search.length < 2 || app.Names[0].toLowerCase().includes(search.toLowerCase())).map((app) => {
return <Grid2 style={gridAnim} xs={12} sm={6} md={6} lg={6} xl={4} key={app.Id} item> return <Grid2 style={gridAnim} xs={12} sm={6} md={6} lg={6} xl={4} key={app.Id} item>
<Item> <Item>
<Stack justifyContent='space-around' direction="column" spacing={2} padding={2} divider={<Divider orientation="horizontal" flexItem />}> <Stack justifyContent='space-around' direction="column" spacing={2} padding={2} divider={<Divider orientation="horizontal" flexItem />}>
<Stack direction="column" spacing={0} alignItems="flex-start"> <Stack direction="column" spacing={0} alignItems="flex-start">
<Stack style={{position: 'relative', overflowX: 'hidden'}} direction="row" spacing={2} alignItems="center"> <Stack style={{position: 'relative', overflowX: 'hidden', width: '100%'}} direction="row" spacing={2} alignItems="center">
<Typography variant="body2" color="text.secondary"> <Typography variant="body2" color="text.secondary">
{ {
({ ({
@ -172,11 +176,11 @@ const ServeApps = () => {
</Typography> </Typography>
<Stack direction="row" spacing={2} alignItems="center"> <Stack direction="row" spacing={2} alignItems="center">
<img src={getFirstRouteFavIcon(app)} width="40px" /> <img src={getFirstRouteFavIcon(app)} width="40px" />
<Stack direction="column" spacing={0} alignItems="flex-start" style={{height: '40px'}}> <Stack direction="column" spacing={0} alignItems="flex-start" style={{height: '40px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'no-wrap'}}>
<Typography variant="h5" color="text.secondary"> <Typography variant="h5" color="text.secondary">
{app.Names[0].replace('/', '')}&nbsp; {app.Names[0].replace('/', '')}&nbsp;
</Typography> </Typography>
<Typography style={{ fontSize: '80%' }} color="text.secondary"> <Typography color="text.secondary" style={{fontSize: '80%', whiteSpace: 'nowrap', overflow: 'hidden', maxWidth: '100%', textOverflow: 'ellipsis'}}>
{app.Image} {app.Image}
</Typography> </Typography>
</Stack> </Stack>

View file

@ -28,6 +28,7 @@ export default function ThemeCustomization({ children }) {
breakpoints: { breakpoints: {
values: { values: {
xs: 0, xs: 0,
xsm: 420,
sm: 768, sm: 768,
md: 1024, md: 1024,
lg: 1266, lg: 1266,

View file

@ -1,6 +1,6 @@
{ {
"name": "cosmos-server", "name": "cosmos-server",
"version": "0.4.0-unstable6", "version": "0.4.0-unstable7",
"description": "", "description": "",
"main": "test-server.js", "main": "test-server.js",
"bugs": { "bugs": {