[release] version 0.5.0-unstable25
This commit is contained in:
parent
7134301f64
commit
1722f3f832
10
changelog.md
10
changelog.md
|
@ -1,13 +1,15 @@
|
||||||
## Version 0.5.0
|
## Version 0.5.0
|
||||||
- Add Terminal to containers
|
- Add Terminal to containers
|
||||||
- Add Create Container
|
- Add "Create ServApp"
|
||||||
- Add support for importing Docker Compose
|
- Add support for importing Docker Compose
|
||||||
|
- Improved icon fetching
|
||||||
|
- Change Home background and style (especially fixing the awckward light theme)
|
||||||
- Fixed 2 bugs with the smart shield, that made it too strict
|
- Fixed 2 bugs with the smart shield, that made it too strict
|
||||||
- Fixed issues that prevented from login in with different hostnames
|
- Fixed issues that prevented from login in with different hostnames
|
||||||
- Added more infoon the shield when blocking someone
|
- Added more info on the shield when blocking someone
|
||||||
- Fixed home background image
|
|
||||||
- Fixed issue where the UI would have missing icon images
|
- Fixed issue where the UI would have missing icon images
|
||||||
- Improved icon fetching for apps by following redirections
|
- Fixed Homepage showing stopped containers
|
||||||
|
- Fixed bug where you can't save changes on the URLs Screen
|
||||||
|
|
||||||
## Version 0.4.3
|
## Version 0.4.3
|
||||||
- Fix for exposing routes from the details page
|
- Fix for exposing routes from the details page
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 73 KiB |
BIN
client/src/assets/images/wallpaper2.jpg
Normal file
BIN
client/src/assets/images/wallpaper2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
BIN
client/src/assets/images/wallpaper2_light.jpg
Normal file
BIN
client/src/assets/images/wallpaper2_light.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
|
@ -61,10 +61,6 @@ const RouteConfigPage = () => {
|
||||||
routeConfig={currentRoute}
|
routeConfig={currentRoute}
|
||||||
/>
|
/>
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: 'Permissions',
|
|
||||||
children: <div>WIP</div>
|
|
||||||
},
|
|
||||||
]}/>}
|
]}/>}
|
||||||
|
|
||||||
{!config && <div style={{textAlign: 'center'}}>
|
{!config && <div style={{textAlign: 'center'}}>
|
||||||
|
|
|
@ -215,20 +215,6 @@ const ProxyManagement = () => {
|
||||||
disableElevation
|
disableElevation
|
||||||
fullWidth
|
fullWidth
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if(routes.some((route, key) => {
|
|
||||||
let errors = ValidateRoute(route, config);
|
|
||||||
if (errors && errors.length > 0) {
|
|
||||||
errors = errors.map((err) => {
|
|
||||||
return `${route.Name}: ${err}`;
|
|
||||||
});
|
|
||||||
setSubmitErrors(errors);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
})) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
setSubmitErrors([]);
|
|
||||||
}
|
|
||||||
API.config.set(cleanRoutes(updateRoutes(routes))).then(() => {
|
API.config.set(cleanRoutes(updateRoutes(routes))).then(() => {
|
||||||
setNeedSave(false);
|
setNeedSave(false);
|
||||||
setOpenModal(true);
|
setOpenModal(true);
|
||||||
|
|
|
@ -3,7 +3,8 @@ import Back from "../../components/back";
|
||||||
import { Alert, Box, CircularProgress, Grid, Stack, useTheme } from "@mui/material";
|
import { Alert, Box, CircularProgress, Grid, Stack, useTheme } from "@mui/material";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import * as API from "../../api";
|
import * as API from "../../api";
|
||||||
import wallpaper from '../../assets/images/wallpaper.jpg';
|
import wallpaper from '../../assets/images/wallpaper2.jpg';
|
||||||
|
import wallpaperLight from '../../assets/images/wallpaper2_light.jpg';
|
||||||
import Grid2 from "@mui/material/Unstable_Grid2/Grid2";
|
import Grid2 from "@mui/material/Unstable_Grid2/Grid2";
|
||||||
import { getFaviconURL } from "../../utils/routes";
|
import { getFaviconURL } from "../../utils/routes";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
@ -13,28 +14,48 @@ import IsLoggedIn from "../../isLoggedIn";
|
||||||
|
|
||||||
const HomeBackground = () => {
|
const HomeBackground = () => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
const isDark = theme.palette.mode === 'dark';
|
||||||
return (
|
return (
|
||||||
<Box sx={{ position: 'fixed', float: 'left', overflow: 'hidden', zIndex: 0, top: 0, left: 0, right: 0, bottom: 0 }}>
|
<Box sx={{ position: 'fixed', float: 'left', overflow: 'hidden', zIndex: 0, top: 0, left: 0, right: 0, bottom: 0,
|
||||||
<img src={wallpaper} style={{ display: 'inline' }} alt="Cosmos" width="100%" height="100%" />
|
// gradient
|
||||||
|
// backgroundImage: isDark ?
|
||||||
|
// `linear-gradient(#371d53, #26143a)` :
|
||||||
|
// `linear-gradient(#e6d3fb, #c8b0e2)`,
|
||||||
|
}}>
|
||||||
|
<img src={isDark ? wallpaper : wallpaperLight } style={{ display: 'inline' }} alt="Cosmos" width="100%" height="100%" />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const blockStyle = {
|
|
||||||
margin: 0,
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
overflow: 'hidden',
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
maxWidth: '78%',
|
|
||||||
verticalAlign: 'middle',
|
|
||||||
}
|
|
||||||
|
|
||||||
const HomePage = () => {
|
const HomePage = () => {
|
||||||
const { routeName } = useParams();
|
const { routeName } = useParams();
|
||||||
const [serveApps, setServeApps] = useState([]);
|
const [serveApps, setServeApps] = useState([]);
|
||||||
const [config, setConfig] = useState(null);
|
const [config, setConfig] = useState(null);
|
||||||
const [coStatus, setCoStatus] = useState(null);
|
const [coStatus, setCoStatus] = useState(null);
|
||||||
const [containers, setContainers] = useState(null);
|
const [containers, setContainers] = useState(null);
|
||||||
|
const theme = useTheme();
|
||||||
|
const isDark = theme.palette.mode === 'dark';
|
||||||
|
|
||||||
|
const blockStyle = {
|
||||||
|
margin: 0,
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
maxWidth: '78%',
|
||||||
|
verticalAlign: 'middle',
|
||||||
|
}
|
||||||
|
|
||||||
|
const appColor = isDark ? {
|
||||||
|
color: 'white',
|
||||||
|
background: 'rgba(0,0,0,0.35)',
|
||||||
|
} : {
|
||||||
|
color: 'black',
|
||||||
|
background: 'rgba(255,255,255,0.35)',
|
||||||
|
}
|
||||||
|
|
||||||
|
const backColor = isDark ? '0,0,0' : '255,255,255';
|
||||||
|
const textColor = isDark ? 'white' : 'dark';
|
||||||
|
|
||||||
|
|
||||||
const refreshStatus = () => {
|
const refreshStatus = () => {
|
||||||
API.getStatus().then((res) => {
|
API.getStatus().then((res) => {
|
||||||
|
@ -64,18 +85,19 @@ const HomePage = () => {
|
||||||
<HomeBackground />
|
<HomeBackground />
|
||||||
<style>
|
<style>
|
||||||
{`header {
|
{`header {
|
||||||
background: rgba(0.2,0.2,0.2,0.2) !important;
|
background: rgba(${backColor},0.3) !important;
|
||||||
border-bottom-color: rgba(0.4,0.4,0.4,0.4) !important;
|
border-bottom-color: rgba(${backColor},0.4) !important;
|
||||||
color: white !important;
|
color: ${textColor} !important;
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
header .MuiChip-label {
|
header .MuiChip-label {
|
||||||
color: #eee !important;
|
color: ${textColor} !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
header .MuiButtonBase-root {
|
header .MuiButtonBase-root, header .MuiChip-colorDefault {
|
||||||
color: #eee !important;
|
color: ${textColor} !important;
|
||||||
background: rgba(0.2,0.2,0.2,0.2) !important;
|
background: rgba(${backColor},0.5) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app {
|
.app {
|
||||||
|
@ -85,9 +107,15 @@ const HomePage = () => {
|
||||||
|
|
||||||
.app:hover {
|
.app:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background: rgba(0.4,0.4,0.4,0.4) !important;
|
background: rgba(${backColor},0.8) !important;
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.MuiAlert-standard {
|
||||||
|
background: rgba(${backColor},0.3) !important;
|
||||||
|
color: ${textColor} !important;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
`}
|
`}
|
||||||
</style>
|
</style>
|
||||||
<Stack style={{ zIndex: 2 }} spacing={1}>
|
<Stack style={{ zIndex: 2 }} spacing={1}>
|
||||||
|
@ -144,8 +172,8 @@ const HomePage = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return !skip && <Grid2 item xs={12} sm={6} md={4} lg={3} xl={3} xxl={2} key={route.Name}>
|
return !skip && <Grid2 item xs={12} sm={6} md={4} lg={3} xl={3} xxl={2} key={route.Name}>
|
||||||
<Box className='app' style={{ padding: 10, color: 'white', background: 'rgba(0,0,0,0.35)', borderRadius: 5 }}>
|
<Box className='app' style={{ padding: 10, borderRadius: 5, ...appColor }}>
|
||||||
<Link to={getFullOrigin(route)} target="_blank" style={{ textDecoration: 'none', color: 'white' }}>
|
<Link to={getFullOrigin(route)} target="_blank" style={{ textDecoration: 'none', ...appColor }}>
|
||||||
<Stack direction="row" spacing={2} alignItems="center">
|
<Stack direction="row" spacing={2} alignItems="center">
|
||||||
<img className="loading-image" alt="" src={getFaviconURL(route)} width="64px" height="64px"/>
|
<img className="loading-image" alt="" src={getFaviconURL(route)} width="64px" height="64px"/>
|
||||||
|
|
||||||
|
@ -162,7 +190,7 @@ const HomePage = () => {
|
||||||
|
|
||||||
{config && config.HTTPConfig.ProxyConfig.Routes.length === 0 && (
|
{config && config.HTTPConfig.ProxyConfig.Routes.length === 0 && (
|
||||||
<Grid2 item xs={12} sm={12} md={12} lg={12} xl={12}>
|
<Grid2 item xs={12} sm={12} md={12} lg={12} xl={12}>
|
||||||
<Box style={{ padding: 10, color: 'white', background: 'rgba(0,0,0,0.35)', borderRadius: 5 }}>
|
<Box style={{ padding: 10, borderRadius: 5, ...appColor }}>
|
||||||
<Stack direction="row" spacing={2} alignItems="center">
|
<Stack direction="row" spacing={2} alignItems="center">
|
||||||
<div style={{ width: '100%' }}>
|
<div style={{ width: '100%' }}>
|
||||||
<h3 style={blockStyle}>No Apps</h3>
|
<h3 style={blockStyle}>No Apps</h3>
|
||||||
|
|
|
@ -19,6 +19,7 @@ import VolumeContainerSetup from './volumes';
|
||||||
import DockerTerminal from './terminal';
|
import DockerTerminal from './terminal';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { smartDockerLogConcat, tryParseProgressLog } from '../../../utils/docker';
|
import { smartDockerLogConcat, tryParseProgressLog } from '../../../utils/docker';
|
||||||
|
import { LoadingButton } from '@mui/lab';
|
||||||
|
|
||||||
const preStyle = {
|
const preStyle = {
|
||||||
backgroundColor: '#000',
|
backgroundColor: '#000',
|
||||||
|
@ -64,7 +65,9 @@ const NewDockerService = ({service, refresh}) => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const create = () => {
|
const create = () => {
|
||||||
setLog([])
|
setLog([
|
||||||
|
'Creating Service... ',
|
||||||
|
])
|
||||||
API.docker.createService(service, (newlog) => {
|
API.docker.createService(service, (newlog) => {
|
||||||
setLog((old) => smartDockerLogConcat(old, newlog));
|
setLog((old) => smartDockerLogConcat(old, newlog));
|
||||||
preRef.current.scrollTop = preRef.current.scrollHeight;
|
preRef.current.scrollTop = preRef.current.scrollHeight;
|
||||||
|
@ -75,7 +78,7 @@ const NewDockerService = ({service, refresh}) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const needsRestart = service && service.service && service.service.some((c) => {
|
const needsRestart = service && service.services && Object.values(service.services).some((c) => {
|
||||||
return c.routes && c.routes.length > 0;
|
return c.routes && c.routes.length > 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -83,13 +86,14 @@ const NewDockerService = ({service, refresh}) => {
|
||||||
<MainCard title="Create Service">
|
<MainCard title="Create Service">
|
||||||
<RestartModal openModal={openModal} setOpenModal={setOpenModal} />
|
<RestartModal openModal={openModal} setOpenModal={setOpenModal} />
|
||||||
<Stack spacing={1}>
|
<Stack spacing={1}>
|
||||||
{!isDone && <Button
|
{!isDone && <LoadingButton
|
||||||
onClick={create}
|
onClick={create}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
fullWidth
|
fullWidth
|
||||||
|
loading={log.length && !isDone}
|
||||||
startIcon={<PlusCircleOutlined />}
|
startIcon={<PlusCircleOutlined />}
|
||||||
>Create</Button>}
|
>Create</LoadingButton>}
|
||||||
{isDone && <Stack spacing={1}>
|
{isDone && <Stack spacing={1}>
|
||||||
<Alert severity="success">Service Created!</Alert>
|
<Alert severity="success">Service Created!</Alert>
|
||||||
{needsRestart && <Alert severity="warning">Cosmos needs to be restarted to apply changes to the URLs</Alert>}
|
{needsRestart && <Alert severity="warning">Cosmos needs to be restarted to apply changes to the URLs</Alert>}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import MainCard from '../../../components/MainCard';
|
import MainCard from '../../../components/MainCard';
|
||||||
import RestartModal from '../../config/users/restart';
|
import RestartModal from '../../config/users/restart';
|
||||||
import { Alert, Button, Chip, Divider, Stack, useMediaQuery } from '@mui/material';
|
import { Alert, Button, Checkbox, Chip, Divider, Stack, useMediaQuery } from '@mui/material';
|
||||||
import HostChip from '../../../components/hostChip';
|
import HostChip from '../../../components/hostChip';
|
||||||
import { RouteMode, RouteSecurity } from '../../../components/routeComponents';
|
import { RouteMode, RouteSecurity } from '../../../components/routeComponents';
|
||||||
import { getFaviconURL } from '../../../utils/routes';
|
import { getFaviconURL } from '../../../utils/routes';
|
||||||
|
@ -56,7 +56,7 @@ const NewDockerServiceForm = () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
let service = {
|
let service = {
|
||||||
Services: {
|
services: {
|
||||||
container_name : {
|
container_name : {
|
||||||
container_name: containerInfo.Name,
|
container_name: containerInfo.Name,
|
||||||
image: containerInfo.Config.Image,
|
image: containerInfo.Config.Image,
|
||||||
|
@ -72,7 +72,7 @@ const NewDockerServiceForm = () => {
|
||||||
acc[cur] = {};
|
acc[cur] = {};
|
||||||
return acc;
|
return acc;
|
||||||
}, {}),
|
}, {}),
|
||||||
Routes: [containerInfo.Route]
|
routes: containerInfo.CreateRoute ? [containerInfo.Route] : [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -164,40 +164,53 @@ const NewDockerServiceForm = () => {
|
||||||
{
|
{
|
||||||
title: 'URL',
|
title: 'URL',
|
||||||
disabled: maxTab < 1,
|
disabled: maxTab < 1,
|
||||||
children: <Stack spacing={2}><RouteManagement TargetContainer={containerInfo}
|
children: <Stack spacing={2}>
|
||||||
routeConfig={{
|
<MainCard style={{ maxWidth: '1000px', width: '100%', margin: '', position: 'relative' }}>
|
||||||
Target: "http://"+containerInfo.Name.replace('/', '') + ":",
|
<Checkbox
|
||||||
Mode: "SERVAPP",
|
checked={containerInfo.CreateRoute}
|
||||||
Name: containerInfo.Name.replace('/', ''),
|
onChange={(e) => {
|
||||||
Description: "Expose " + containerInfo.Name.replace('/', '') + " to the internet",
|
const newValues = {
|
||||||
UseHost: true,
|
...containerInfo,
|
||||||
Host: getHostnameFromName(containerInfo.Name),
|
CreateRoute: e.target.checked,
|
||||||
UsePathPrefix: false,
|
}
|
||||||
PathPrefix: '',
|
setContainerInfo(newValues);
|
||||||
CORSOrigin: '',
|
}}
|
||||||
StripPathPrefix: false,
|
/>Create a URL to access this ServApp
|
||||||
AuthEnabled: false,
|
</MainCard>
|
||||||
Timeout: 14400000,
|
{containerInfo.CreateRoute && <RouteManagement TargetContainer={containerInfo}
|
||||||
ThrottlePerMinute: 10000,
|
routeConfig={{
|
||||||
BlockCommonBots: true,
|
Target: "http://"+containerInfo.Name.replace('/', '') + ":",
|
||||||
SmartShield: {
|
Mode: "SERVAPP",
|
||||||
Enabled: true,
|
Name: containerInfo.Name.replace('/', ''),
|
||||||
}
|
Description: "Expose " + containerInfo.Name.replace('/', '') + " to the internet",
|
||||||
}}
|
UseHost: true,
|
||||||
routeNames={[]}
|
Host: getHostnameFromName(containerInfo.Name),
|
||||||
setRouteConfig={(newRoute) => {
|
UsePathPrefix: false,
|
||||||
const newValues = {
|
PathPrefix: '',
|
||||||
...containerInfo,
|
CORSOrigin: '',
|
||||||
Route: newRoute,
|
StripPathPrefix: false,
|
||||||
}
|
AuthEnabled: false,
|
||||||
setContainerInfo(newValues);
|
Timeout: 14400000,
|
||||||
}}
|
ThrottlePerMinute: 10000,
|
||||||
up={() => {}}
|
BlockCommonBots: true,
|
||||||
down={() => {}}
|
SmartShield: {
|
||||||
deleteRoute={() => {}}
|
Enabled: true,
|
||||||
noControls
|
}
|
||||||
lockTarget
|
}}
|
||||||
/>{nav()}</Stack>
|
routeNames={[]}
|
||||||
|
setRouteConfig={(newRoute) => {
|
||||||
|
const newValues = {
|
||||||
|
...containerInfo,
|
||||||
|
Route: newRoute,
|
||||||
|
}
|
||||||
|
setContainerInfo(newValues);
|
||||||
|
}}
|
||||||
|
up={() => {}}
|
||||||
|
down={() => {}}
|
||||||
|
deleteRoute={() => {}}
|
||||||
|
noControls
|
||||||
|
lockTarget
|
||||||
|
/>}{nav()}</Stack>
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Network',
|
title: 'Network',
|
||||||
|
|
|
@ -123,7 +123,7 @@ const ContainerOverview = ({ containerInfo, config, refresh }) => {
|
||||||
disabled={isUpdating}
|
disabled={isUpdating}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setIsUpdating(true);
|
setIsUpdating(true);
|
||||||
API.docker.secure(Name, e.target.checked).then(() => {
|
API.docker.secure(Name.replace('/', ''), e.target.checked).then(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
refreshAll();
|
refreshAll();
|
||||||
}, 3000);
|
}, 3000);
|
||||||
|
@ -137,7 +137,7 @@ const ContainerOverview = ({ containerInfo, config, refresh }) => {
|
||||||
disabled={isUpdating}
|
disabled={isUpdating}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setIsUpdating(true);
|
setIsUpdating(true);
|
||||||
API.docker.autoUpdate(Name, e.target.checked).then(() => {
|
API.docker.autoUpdate(Name.replace('/', ''), e.target.checked).then(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
refreshAll();
|
refreshAll();
|
||||||
}, 3000);
|
}, 3000);
|
||||||
|
|
|
@ -226,7 +226,7 @@ const ServeApps = () => {
|
||||||
})}
|
})}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
{isUpdating[app.Id] ? <div>
|
{isUpdating[app.Names[0].replace('/', '')] ? <div>
|
||||||
<CircularProgress color="inherit" />
|
<CircularProgress color="inherit" />
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
|
@ -239,14 +239,15 @@ const ServeApps = () => {
|
||||||
checked={app.Labels['cosmos-force-network-secured'] === 'true'}
|
checked={app.Labels['cosmos-force-network-secured'] === 'true'}
|
||||||
disabled={app.State !== 'running'}
|
disabled={app.State !== 'running'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setIsUpdatingId(app.Id, true);
|
const name = app.Names[0].replace('/', '');
|
||||||
API.docker.secure(app.Id, e.target.checked).then(() => {
|
setIsUpdatingId(name, true);
|
||||||
|
API.docker.secure(name, e.target.checked).then(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setIsUpdatingId(app.Id, false);
|
setIsUpdatingId(name, false);
|
||||||
refreshServeApps();
|
refreshServeApps();
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
setIsUpdatingId(app.Id, false);
|
setIsUpdatingId(name, false);
|
||||||
refreshServeApps();
|
refreshServeApps();
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
|
@ -257,14 +258,15 @@ const ServeApps = () => {
|
||||||
checked={app.Labels['cosmos-auto-update'] === 'true'}
|
checked={app.Labels['cosmos-auto-update'] === 'true'}
|
||||||
disabled={app.State !== 'running'}
|
disabled={app.State !== 'running'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setIsUpdatingId(app.Id, true);
|
const name = app.Names[0].replace('/', '');
|
||||||
API.docker.autoUpdate(app.Id, e.target.checked).then(() => {
|
setIsUpdatingId(name, true);
|
||||||
|
API.docker.autoUpdate(name, e.target.checked).then(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setIsUpdatingId(app.Id, false);
|
setIsUpdatingId(name, false);
|
||||||
refreshServeApps();
|
refreshServeApps();
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
setIsUpdatingId(app.Id, false);
|
setIsUpdatingId(name, false);
|
||||||
refreshServeApps();
|
refreshServeApps();
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "cosmos-server",
|
"name": "cosmos-server",
|
||||||
"version": "0.5.0-unstable24",
|
"version": "0.5.0-unstable25",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "test-server.js",
|
"main": "test-server.js",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
|
|
Loading…
Reference in a new issue