v0.1.15 improve Port selection, hostnames and ports now have default, other UI improvements

This commit is contained in:
Yann Stepienik 2023-04-10 17:53:16 +01:00
parent d8870191c6
commit a82a436187
9 changed files with 148 additions and 63 deletions

View file

@ -16,24 +16,24 @@ const pages = {
type: 'group',
children: [
{
id: 'proxy',
title: 'Proxy Routes',
id: 'url',
title: 'URLs',
type: 'item',
url: '/ui/config/proxy',
url: '/ui/config-url',
icon: icons.NodeExpandOutlined,
},
{
id: 'users',
title: 'Manage Users',
type: 'item',
url: '/ui/config/users',
url: '/ui/config-users',
icon: icons.ProfileOutlined,
},
{
id: 'config',
title: 'Configuration',
type: 'item',
url: '/ui/config/general',
url: '/ui/config-general',
icon: icons.SettingOutlined,
}
]

View file

@ -29,6 +29,8 @@ import RestartModal from './restart';
import Autocomplete from '@mui/material/Autocomplete';
import CircularProgress from '@mui/material/CircularProgress';
import defaultport from '../../servapps/defaultport.json';
import * as API from '../../../api';
export function CosmosContainerPicker({formik, lockTarget, TargetContainer, onTargetChange}) {
@ -53,7 +55,7 @@ export function CosmosContainerPicker({formik, lockTarget, TargetContainer, onTa
if(preview) {
let protocols = preview.split("://")
let p1_ = protocols.length > 1 ? protocols[1] : protocols[0]
console.log("p1_", p1_)
targetResult = {
container: '/' + p1_.split(":")[0],
port: p1_.split(":")[1],
@ -76,6 +78,37 @@ export function CosmosContainerPicker({formik, lockTarget, TargetContainer, onTa
})
setPortsOptions(portsTemp)
targetResult.port = '80'
if(portsTemp.length > 0) {
// pick best default port
// set default to first port
targetResult.port = portsTemp[0]
// first, check if a manual override exists
let override = Object.keys(defaultport.overrides).find((key) => {
let keyMatch = new RegExp(key, "i");
return newContainer.Image.match(keyMatch) && portsTemp.includes(defaultport.overrides[key])
});
if(override) {
targetResult.port = defaultport.overrides[override]
} else {
// if not, check the default list of common ports
let priorityList = defaultport.priority;
priorityList.find((_portReg) => {
return portsTemp.find((portb) => {
let portReg = new RegExp(_portReg, "i");
if(portb.toString().match(portReg)) {
targetResult.port = portb
return true;
}
})
})
}
}
formik.setFieldValue(name, getTarget());
if(newContainer.NetworkSettings.Networks["bridge"]) {
setIsOnBridge(true);
}
@ -186,26 +219,27 @@ export function CosmosContainerPicker({formik, lockTarget, TargetContainer, onTa
{(portsOptions.length > 0) ? (<>
<InputLabel htmlFor={name + "-port"}>Container Port</InputLabel>
<TextField
<Autocomplete
className="px-2 my-2"
variant="outlined"
name={name + "-port"}
id={name + "-port"}
value={targetResult.port}
select
options={portsOptions.map((option) => (option))}
placeholder='Select a port'
onChange={(event) => {
targetResult.port = event.target.value
freeSolo
filterOptions={(x) => x} // disable filtering
getOptionLabel={(option) => '' + option}
isOptionEqualToValue={(option, value) => {
return ('' + option) === value
}}
onChange={(event, newValue) => {
targetResult.port = newValue
formik.setFieldValue(name, getTarget())
}}
>
{portsOptions.map((option) => (
<MenuItem key={option} value={option}>
{option}
</MenuItem>
))}
</TextField>
{targetResult.port == '' && <FormHelperText error id="standard-weight-helper-text-name-login">
renderInput={(params) => <TextField {...params} />}
/>
{targetResult.port == '' && targetResult.port == 0 && <FormHelperText error id="standard-weight-helper-text-name-login">
Please select a port
</FormHelperText>}
</>) : ''}

View file

@ -122,8 +122,8 @@ const ProxyManagement = () => {
}}>Refresh</Button>&nbsp;&nbsp;
<Button variant="contained" color="primary" startIcon={<PlusCircleOutlined />} onClick={() => {
routes.unshift({
Name: 'New Route',
Description: 'New Route',
Name: 'New URL',
Description: 'New URL',
Mode: "SERVAPP",
UseHost: false,
Host: '',

View file

@ -100,7 +100,7 @@ const RouteManagement = ({ routeConfig, TargetContainer, noControls=false, lockT
{(formik) => (
<form ref={myRef} noValidate onSubmit={formik.handleSubmit}>
<MainCard name={routeConfig.Name} title={
noControls ? 'New Route' :
noControls ? 'New URL' :
<div>{routeConfig.Name} &nbsp;
<Chip label={<UpOutlined />} onClick={() => up()}/> &nbsp;
<Chip label={<DownOutlined />} onClick={() => down()}/> &nbsp;

View file

@ -0,0 +1,59 @@
{
"priority": [
"80",
"3000",
"8080",
"8*",
"3*"
],
"overrides": {
"adguard": 80,
"airsonic": 4040,
"bazarr": 6767,
"bitwarden": 80,
"bookstack": 80,
"calibre(-web)?" : 8083,
"dokuwiki": 80,
"duplicati": 8200,
"emby": 8096,
"filebrowser": 80,
"ghost": 2368,
"git(lab|server)" : 80,
"gitea": 3000,
"grafana": 3000,
"heimdall": 80,
"homeassistant": 8123,
"homebridge": 8581,
"jackett": 9117,
"jdownloader": 5800,
"jellyfin": 8096,
"jitsi": 80,
"lidarr": 8686,
"letsencrypt": 80,
"ombi4k": 3579,
"moodle": 80,
"nzb360": 6789,
"nzbget": 6789,
"nzbhydra": 5076,
"ombi": 3579,
"openproject": 80,
"organizr": 80,
"pi-hole": 80,
"plex": 32400,
"portainer": 9000,
"prometheus": 9090,
"qbittorrent(vpn)?" : 8080,
"radarr": 7878,
"rocket.chat": 3000,
"sabnzbd": 8080,
"sick(chill|rage)": 8081,
"sonarr": 8989,
"synclounge": 8088,
"tautulli": 8181,
"transmission(-openvpn)?" : 9091,
"ubooquity": 2202,
"unifi-controller": 8443,
"watchtower": 8080,
"wordpress": 80
}
}

View file

@ -1,5 +1,5 @@
// material-ui
import { AppstoreAddOutlined, ReloadOutlined, SearchOutlined, SettingOutlined } from '@ant-design/icons';
import { AppstoreAddOutlined, PlusCircleOutlined, ReloadOutlined, SearchOutlined, SettingOutlined } from '@ant-design/icons';
import { Alert, Badge, Button, Card, Checkbox, Chip, CircularProgress, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Divider, Input, InputAdornment, TextField, Tooltip, Typography } from '@mui/material';
import Grid2 from '@mui/material/Unstable_Grid2/Grid2';
import { Stack } from '@mui/system';
@ -116,13 +116,13 @@ const ServeApps = () => {
return <div>
<RestartModal openModal={openRestartModal} setOpenModal={setOpenRestartModal} />
<Dialog open={openModal} onClose={() => setOpenModal(false)}>
<DialogTitle>Connect ServApp</DialogTitle>
<DialogTitle>Expose ServApp</DialogTitle>
{openModal && <>
<DialogContent>
<DialogContentText>
<Stack spacing={2}>
<div>
Welcome to the Connect Wizard. This interface will help you expose your ServApp securely to the internet.
Welcome to the URL Wizard. This interface will help you expose your ServApp securely to the internet by creating a new URL.
</div>
<div>
{openModal && !hasCosmosNetwork(openModal.Names[0]) && <Alert severity="warning">This ServApp does not appear to be connected to a Cosmos Network, so the hostname might not be accessible. The easiest way to fix this is to check the box "Force Secure Network" or manually create a sub-network in Docker.</Alert>}
@ -134,8 +134,8 @@ const ServeApps = () => {
Mode: "SERVAPP",
Name: openModal.Names[0].replace('/', ''),
Description: "Expose " + openModal.Names[0].replace('/', '') + " to the internet",
UseHost: false,
Host: '',
UseHost: true,
Host: openModal.Names[0].replace('/', '') + '.' + window.location.origin.split('://')[1],
UsePathPrefix: false,
PathPrefix: '',
Timeout: 30000,
@ -177,7 +177,7 @@ const ServeApps = () => {
updateRoutes();
}
}}>Connect</Button>
}}>Confirm</Button>
</DialogActions>
</>}
</Dialog>
@ -278,13 +278,13 @@ const ServeApps = () => {
</Stack></Stack>}
<Stack margin={1} direction="column" spacing={1} alignItems="flex-start">
<Typography variant="h6" color="text.secondary">
Proxies
URLs
</Typography>
<Stack spacing={2} direction="row">
{getContainersRoutes(app.Names[0].replace('/', '')).map((route) => {
return <><Chip
label={route.Host + route.PathPrefix}
color="primary"
color="secondary"
style={{paddingRight: '4px'}}
onClick={() => {
if(route.UseHost)
@ -293,21 +293,33 @@ const ServeApps = () => {
window.open(window.location.origin + route.PathPrefix, '_blank');
}}
onDelete={() => {
window.open('/ui/config/proxy#'+route.Name, '_blank');
window.open('/ui/config-url#'+route.Name, '_blank');
}}
deleteIcon={<SettingOutlined />}
/>
</>
})}
{getContainersRoutes(app.Names[0].replace('/', '')).length == 0 &&
<Chip label="No Proxy Setup" />}
{/* {getContainersRoutes(app.Names[0].replace('/', '')).length == 0 && */}
<Chip
label="New"
color="primary"
style={{paddingRight: '4px'}}
deleteIcon={<PlusCircleOutlined />}
onClick={() => {
setOpenModal(app);
}}
onDelete={() => {
setOpenModal(app);
}}
/>
{/* } */}
</Stack>
</Stack>
<Stack>
{/* <Stack>
<Button variant="contained" color="primary" onClick={() => {
setOpenModal(app);
}}>Connect</Button>
</Stack>
</Stack> */}
</Stack>
</Item></Grid2>
})

View file

@ -41,15 +41,15 @@ const MainRoutes = {
element: <ServeApps />
},
{
path: '/ui/config/users',
path: '/ui/config-users',
element: <UserManagement />
},
{
path: '/ui/config/general',
path: '/ui/config-general',
element: <ConfigManagement />
},
{
path: '/ui/config/proxy',
path: '/ui/config-url',
element: <ProxyManagement />
},
]

View file

@ -1,6 +1,9 @@
// ==============================|| PRESET THEME - THEME SELECTOR ||============================== //
import { purple, pink, deepPurple } from '@mui/material/colors';
const Theme = (colors) => {
console.log(colors)
const { blue, red, gold, cyan, green, grey } = colors;
const greyColors = {
0: grey[0],
@ -25,33 +28,10 @@ const Theme = (colors) => {
return {
primary: {
lighter: '#C8A2C8',
100: '#B785B7',
200: '#B785B7',
light: '#A668A6',
400: '#A668A6',
main: '#8D538D',
dark: '#704270',
700: '#533153',
darker:'#362036',
900: '#1A0E1A',
contrastText
main: purple[400],
},
secondary: {
lighter: greyColors[100],
100: greyColors[100],
200: greyColors[200],
light: greyColors[300],
400: greyColors[400],
main: greyColors[500],
600: greyColors[600],
dark: greyColors[700],
800: greyColors[800],
darker: greyColors[900],
A100: greyColors[0],
A200: greyColors.A400,
A300: greyColors.A700,
contrastText: greyColors[0]
main: deepPurple[100]
},
error: {
lighter: red[0],

View file

@ -1,6 +1,6 @@
{
"name": "cosmos-server",
"version": "0.1.14",
"version": "0.1.15",
"description": "",
"main": "test-server.js",
"bugs": {