app tiles
This commit is contained in:
parent
363a82a845
commit
1a71656508
|
|
@ -63,7 +63,7 @@ export function DashboardLanding({ render }: { render: () => void }) {
|
||||||
</TabBar>
|
</TabBar>
|
||||||
|
|
||||||
<TabContent active={dashboardTab === 'urls' || undefined}>
|
<TabContent active={dashboardTab === 'urls' || undefined}>
|
||||||
<Urls />
|
<Urls render={render} />
|
||||||
</TabContent>
|
</TabContent>
|
||||||
|
|
||||||
<TabContent active={dashboardTab === 'logs' || undefined}>
|
<TabContent active={dashboardTab === 'logs' || undefined}>
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
import { buildAppUrl } from '../../shared/urls'
|
import { buildAppUrl } from '../../shared/urls'
|
||||||
import { apps } from '../state'
|
import { apps, setSelectedApp } from '../state'
|
||||||
import {
|
import {
|
||||||
EmptyState,
|
EmptyState,
|
||||||
StatusDot,
|
Tile,
|
||||||
UrlLeft,
|
TileGrid,
|
||||||
UrlLink,
|
TileIcon,
|
||||||
UrlList,
|
TileName,
|
||||||
UrlPort,
|
TilePort,
|
||||||
UrlRow,
|
TileStatus,
|
||||||
} from '../styles'
|
} from '../styles'
|
||||||
|
|
||||||
export function Urls() {
|
export function Urls({ render }: { render: () => void }) {
|
||||||
const nonTools = apps.filter(a => !a.tool)
|
const nonTools = apps.filter(a => !a.tool)
|
||||||
|
|
||||||
if (nonTools.length === 0) {
|
if (nonTools.length === 0) {
|
||||||
|
|
@ -18,26 +18,32 @@ export function Urls() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UrlList>
|
<TileGrid>
|
||||||
{nonTools.map(app => {
|
{nonTools.map(app => {
|
||||||
const url = buildAppUrl(app.name, location.origin)
|
const url = buildAppUrl(app.name, location.origin)
|
||||||
const running = app.state === 'running'
|
const running = app.state === 'running'
|
||||||
|
|
||||||
|
const openAppPage = (e: MouseEvent) => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
setSelectedApp(app.name)
|
||||||
|
render()
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UrlRow key={app.name}>
|
<Tile
|
||||||
<UrlLeft>
|
key={app.name}
|
||||||
<StatusDot state={app.state} />
|
href={running ? url : undefined}
|
||||||
<span>{app.icon}</span>
|
target={running ? '_blank' : undefined}
|
||||||
{running ? (
|
style={running ? undefined : { cursor: 'default' }}
|
||||||
<UrlLink href={url} target="_blank">{url}</UrlLink>
|
>
|
||||||
) : (
|
<TileStatus state={app.state} onClick={openAppPage} />
|
||||||
<span style={{ color: 'var(--colors-textFaint)' }}>{app.name}</span>
|
<TileIcon>{app.icon}</TileIcon>
|
||||||
)}
|
<TileName>{app.name}</TileName>
|
||||||
</UrlLeft>
|
<TilePort>{app.port ? `:${app.port}` : '\u2014'}</TilePort>
|
||||||
{app.port ? <UrlPort>:{app.port}</UrlPort> : null}
|
</Tile>
|
||||||
</UrlRow>
|
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</UrlList>
|
</TileGrid>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -203,58 +203,73 @@ export const LogStatus = define('LogStatus', {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// URL List
|
// App Tiles Grid
|
||||||
export const UrlLeft = define('UrlLeft', {
|
export const TileGrid = define('TileGrid', {
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: 8,
|
|
||||||
minWidth: 0,
|
|
||||||
})
|
|
||||||
|
|
||||||
export const UrlLink = define('UrlLink', {
|
|
||||||
base: 'a',
|
|
||||||
color: theme('colors-link'),
|
|
||||||
textDecoration: 'none',
|
|
||||||
overflow: 'hidden',
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
selectors: {
|
|
||||||
'&:hover': { textDecoration: 'underline' },
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
export const UrlList = define('UrlList', {
|
|
||||||
width: '100%',
|
width: '100%',
|
||||||
minWidth: 400,
|
maxWidth: 900,
|
||||||
maxWidth: 800,
|
display: 'grid',
|
||||||
|
gridTemplateColumns: 'repeat(auto-fill, minmax(240px, 1fr))',
|
||||||
|
gap: 20,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const Tile = define('Tile', {
|
||||||
|
base: 'a',
|
||||||
|
position: 'relative',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: 8,
|
||||||
|
padding: '28px 20px 24px',
|
||||||
background: theme('colors-bgElement'),
|
background: theme('colors-bgElement'),
|
||||||
border: `1px solid ${theme('colors-border')}`,
|
border: `1px solid ${theme('colors-border')}`,
|
||||||
borderRadius: theme('radius-md'),
|
borderRadius: theme('radius-md'),
|
||||||
overflow: 'hidden',
|
textDecoration: 'none',
|
||||||
})
|
cursor: 'pointer',
|
||||||
|
|
||||||
export const UrlPort = define('UrlPort', {
|
|
||||||
fontFamily: theme('fonts-mono'),
|
|
||||||
fontSize: 12,
|
|
||||||
color: theme('colors-textFaint'),
|
|
||||||
flexShrink: 0,
|
|
||||||
})
|
|
||||||
|
|
||||||
export const UrlRow = define('UrlRow', {
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
alignItems: 'center',
|
|
||||||
padding: '10px 16px',
|
|
||||||
fontFamily: theme('fonts-mono'),
|
|
||||||
fontSize: 13,
|
|
||||||
selectors: {
|
selectors: {
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
background: theme('colors-bgHover'),
|
background: theme('colors-bgHover'),
|
||||||
},
|
borderColor: theme('colors-textFaint'),
|
||||||
'&:not(:last-child)': {
|
},
|
||||||
borderBottom: `1px solid ${theme('colors-border')}`,
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const TileIcon = define('TileIcon', {
|
||||||
|
fontSize: 48,
|
||||||
|
lineHeight: 1,
|
||||||
|
userSelect: 'none',
|
||||||
|
})
|
||||||
|
|
||||||
|
export const TileName = define('TileName', {
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: 600,
|
||||||
|
color: theme('colors-text'),
|
||||||
|
textAlign: 'center',
|
||||||
|
})
|
||||||
|
|
||||||
|
export const TilePort = define('TilePort', {
|
||||||
|
fontFamily: theme('fonts-mono'),
|
||||||
|
fontSize: 13,
|
||||||
|
color: theme('colors-textFaint'),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const TileStatus = define('TileStatus', {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 8,
|
||||||
|
right: 8,
|
||||||
|
width: 2,
|
||||||
|
height: 2,
|
||||||
|
borderRadius: '50%',
|
||||||
|
cursor: 'pointer',
|
||||||
|
padding: 4,
|
||||||
|
backgroundClip: 'content-box',
|
||||||
|
variants: {
|
||||||
|
state: {
|
||||||
|
error: { background: theme('colors-statusInvalid') },
|
||||||
|
invalid: { background: theme('colors-statusInvalid') },
|
||||||
|
stopped: { background: theme('colors-statusStopped') },
|
||||||
|
starting: { background: theme('colors-statusStarting') },
|
||||||
|
running: { background: theme('colors-statusRunning') },
|
||||||
|
stopping: { background: theme('colors-statusStarting') },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,12 @@ export {
|
||||||
LogStatus,
|
LogStatus,
|
||||||
LogText,
|
LogText,
|
||||||
LogTimestamp,
|
LogTimestamp,
|
||||||
UrlLeft,
|
Tile,
|
||||||
UrlLink,
|
TileGrid,
|
||||||
UrlList,
|
TileIcon,
|
||||||
UrlPort,
|
TileName,
|
||||||
UrlRow,
|
TilePort,
|
||||||
|
TileStatus,
|
||||||
VitalCard,
|
VitalCard,
|
||||||
VitalLabel,
|
VitalLabel,
|
||||||
VitalsSection,
|
VitalsSection,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user