Skip to content

Commit

Permalink
Merge pull request #521 from traPtitech/dashboard/tmp-view
Browse files Browse the repository at this point in the history
temporary view of dashboard
  • Loading branch information
motoki317 authored May 6, 2023
2 parents 9f24151 + 2ab7d8e commit bcf4da0
Show file tree
Hide file tree
Showing 19 changed files with 921 additions and 299 deletions.
1 change: 1 addition & 0 deletions dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"@bufbuild/connect-web": "0.8.6",
"@bufbuild/protobuf": "1.2.0",
"@solidjs/router": "0.8.2",
"ansi-to-html": "0.7.2",
"solid-icons": "1.0.4",
"solid-js": "1.7.3"
}
Expand Down
67 changes: 67 additions & 0 deletions dashboard/src/components/AppNav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { styled } from '@macaron-css/solid'
import { vars } from '/@/theme'
import { providerToIcon } from '/@/libs/application'
import { A } from '@solidjs/router'
import { Button } from '/@/components/Button'
import { JSXElement } from 'solid-js'
import { CenterInline } from '/@/libs/layout'

const AppTitleContainer = styled('div', {
base: {
display: 'flex',
flexDirection: 'row',
gap: '14px',
alignContent: 'center',

marginTop: '48px',
fontSize: '32px',
fontWeight: 'bold',
color: vars.text.black1,
},
})

const AppTitle = styled('div', {
base: {
display: 'flex',
flexDirection: 'row',
gap: '8px',
},
})

const AppNavContainer = styled('div', {
base: {
marginTop: '20px',
display: 'flex',
flexDirection: 'row',
gap: '20px',
}
})

export interface AppNavProps {
repoName: string
appName: string
appID: string
}

export const AppNav = (props: AppNavProps): JSXElement => {
return (
<>
<AppTitleContainer>
<CenterInline>{providerToIcon('GitHub', 36)}</CenterInline>
<AppTitle>
<div>{props.repoName}</div>
<div>/</div>
<div>{props.appName}</div>
</AppTitle>
</AppTitleContainer>
<AppNavContainer>
<A href={`/apps/${props.appID}`}>
<Button color='black1' size='large'>General</Button>
</A>
<A href={`/apps/${props.appID}/builds`}>
<Button color='black1' size='large'>Builds</Button>
</A>
</AppNavContainer>
</>
)
}
29 changes: 29 additions & 0 deletions dashboard/src/components/BuildStatusIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { JSXElement } from 'solid-js'
import { AiFillCheckCircle, AiFillExclamationCircle, AiFillMinusCircle } from 'solid-icons/ai'
import { vars } from '/@/theme'
import { IoReloadCircle } from 'solid-icons/io'
import { Build_BuildStatus } from '/@/api/neoshowcase/protobuf/gateway_pb'
import { Dynamic } from 'solid-js/web'

interface IconProps {
size: number
}
const components: Record<Build_BuildStatus, (size: IconProps) => JSXElement> = {
[Build_BuildStatus.QUEUED]: (props) => <AiFillMinusCircle size={props.size} color={vars.text.black4} />,
[Build_BuildStatus.BUILDING]: (props) => <IoReloadCircle size={props.size} color={vars.icon.pending} />,
[Build_BuildStatus.SUCCEEDED]: (props) => <AiFillCheckCircle size={props.size} color={vars.icon.success1} />,
[Build_BuildStatus.FAILED]: (props) => <AiFillExclamationCircle size={props.size} color={vars.icon.error} />,
[Build_BuildStatus.CANCELLED]: (props) => <AiFillExclamationCircle size={props.size} color={vars.text.black4} />,
[Build_BuildStatus.SKIPPED]: (props) => <AiFillExclamationCircle size={props.size} color={vars.text.black4} />,
}

interface Props {
state: Build_BuildStatus
size?: number
}

export const BuildStatusIcon = (props: Props): JSXElement => {
return (
<Dynamic component={components[props.state]} size={props.size ?? 20} />
)
}
70 changes: 70 additions & 0 deletions dashboard/src/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { styled } from '@macaron-css/solid'
import { vars } from '/@/theme'
import { JSXElement } from 'solid-js'

const Container = styled('div', {
base: {
display: 'flex',
borderRadius: '4px',
},
variants: {
cursor: {
none: {},
pointer: {
cursor: 'pointer',
},
},
color: {
black1: {
backgroundColor: vars.bg.black1,
},
},
size: {
large: {
minWidth: '180px',
height: '44px',
},
},
},
})

const Text = styled('div', {
base: {
margin: 'auto',
},
variants: {
color: {
black1: {
color: vars.text.white1,
},
},
size: {
large: {
fontSize: '16px',
fontWeight: 'bold',
},
},
},
})

export interface Props {
children: JSXElement
color: 'black1'
size: 'large'
onclick?: () => void
}

export const Button = (props: Props) => {
return (
<Container
color={props.color}
size={props.size}
cursor={props.onclick !== undefined ? 'pointer' : 'none'}
onclick={props.onclick}
>
<Text color={props.color} size={props.size}>
{props.children}
</Text>
</Container>
)
}
69 changes: 69 additions & 0 deletions dashboard/src/components/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { styled } from '@macaron-css/solid'
import { vars } from '/@/theme'

export const CardsContainer = styled('div', {
base: {
marginTop: '24px',
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
gap: '40px',
},
})

export const Card = styled('div', {
base: {
minWidth: '320px',
borderRadius: '4px',
border: `1px solid ${vars.bg.white4}`,
background: vars.bg.white1,
padding: '24px 36px',

display: 'flex',
flexDirection: 'column',
gap: '24px',
},
})

export const CardTitle = styled('div', {
base: {
fontSize: '24px',
fontWeight: 600,
},
})

export const CardItems = styled('div', {
base: {
display: 'flex',
flexDirection: 'column',
gap: '20px',
},
})

export const CardItem = styled('div', {
base: {
display: 'flex',
flexDirection: 'row',
gap: '8px',
},
})

export const CardItemTitle = styled('div', {
base: {
fontSize: '16px',
color: vars.text.black3,
},
})

export const CardItemContent = styled('div', {
base: {
marginLeft: 'auto',
fontSize: '16px',
color: vars.text.black1,

display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: '4px',
},
})
32 changes: 32 additions & 0 deletions dashboard/src/components/Log.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { styled } from '@macaron-css/solid'
import { vars } from '/@/theme'

export const LogContainer = styled('div', {
base: {
display: 'flex',
flexDirection: 'column',

backgroundColor: vars.bg.black1,
padding: '10px',
color: vars.text.white1,
borderRadius: '4px',

maxHeight: '500px',
overflowY: 'scroll',
},
variants: {
overflowX: {
wrap: {
whiteSpace: 'pre-wrap',
overflowWrap: 'anywhere',
},
scroll: {
whiteSpace: 'nowrap',
overflowX: 'scroll',
}
}
},
defaultVariants: {
overflowX: 'wrap',
}
})
8 changes: 4 additions & 4 deletions dashboard/src/components/RepositoryRow.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { JSXElement } from 'solid-js'
import { For, JSXElement } from 'solid-js'
import { StatusIcon } from '/@/components/StatusIcon'
import { Application, Repository } from '/@/api/neoshowcase/protobuf/gateway_pb'
import { applicationState, providerToIcon, repositoryURLToProvider } from '/@/libs/application'
Expand Down Expand Up @@ -147,9 +147,9 @@ export const RepositoryRow = ({ repo, apps }: Props): JSXElement => {
<div>Add&nbsp;branch</div>
</AddBranchButton>
</Header>
{apps.map((app, i) => (
<For each={apps} children={(app, i) => (
<A href={`/apps/${app.id}`}>
<ApplicationContainer upperBorder={i === apps.length - 1 ? 'none' : 'line'}>
<ApplicationContainer upperBorder={i() === apps.length - 1 ? 'none' : 'line'}>
<StatusIcon state={applicationState(app)} />
<AppDetail>
<AppName>{app.name}</AppName>
Expand All @@ -163,7 +163,7 @@ export const RepositoryRow = ({ repo, apps }: Props): JSXElement => {
</AppDetail>
</ApplicationContainer>
</A>
))}
)} />
</Container>
)
}
27 changes: 15 additions & 12 deletions dashboard/src/components/StatusIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import { JSXElement } from 'solid-js'
import { JSXElement, Match, Switch } from 'solid-js'
import { AiFillCheckCircle, AiFillMinusCircle } from 'solid-icons/ai'
import { vars } from '/@/theme'
import { IoReloadCircle } from 'solid-icons/io'
import { ApplicationState } from '/@/libs/application'
import { Dynamic } from 'solid-js/web'

interface IconProps {
size: number
}
const components: Record<ApplicationState, (props: IconProps) => JSXElement> = {
Idle: (props) => <AiFillMinusCircle size={props.size} color={vars.text.black4} />,
Deploying: (props) => <IoReloadCircle size={props.size} color={vars.icon.pending} />,
Running: (props) => <AiFillCheckCircle size={props.size} color={vars.icon.success1} />,
Static: (props) => <AiFillCheckCircle size={props.size} color={vars.icon.success2} />,
}

interface Props {
state: ApplicationState
size?: number
}

export const StatusIcon = (props: Props): JSXElement => {
const size = () => props.size ?? 20
switch (props.state) {
case ApplicationState.Idle:
return <AiFillMinusCircle size={size()} color={vars.text.black4} />
case ApplicationState.Deploying:
return <IoReloadCircle size={size()} color={vars.icon.pending} />
case ApplicationState.Running:
return <AiFillCheckCircle size={size()} color={vars.icon.success1} />
case ApplicationState.Static:
return <AiFillCheckCircle size={size()} color={vars.icon.success2} />
}
return (
<Dynamic component={components[props.state]} size={props.size ?? 20} />
)
}
17 changes: 16 additions & 1 deletion dashboard/src/libs/application.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { Provider } from '/@/components/RepositoryRow'
import { Application, BuildConfig, DeployType, Website } from '/@/api/neoshowcase/protobuf/gateway_pb'
import {
Application,
Build_BuildStatus,
BuildConfig,
DeployType,
Website,
} from '/@/api/neoshowcase/protobuf/gateway_pb'
import { JSXElement } from 'solid-js'
import { AiFillGithub, AiFillGitlab } from 'solid-icons/ai'
import { SiGitea } from 'solid-icons/si'
Expand All @@ -13,6 +19,15 @@ export const buildTypeStr: Record<BuildConfig['buildConfig']['case'], string> =
staticDockerfile: 'Static (Dockerfile)',
}

export const buildStatusStr: Record<Build_BuildStatus, string> = {
[Build_BuildStatus.QUEUED]: 'Queued',
[Build_BuildStatus.BUILDING]: 'Building',
[Build_BuildStatus.SUCCEEDED]: 'Succeeded',
[Build_BuildStatus.FAILED]: 'Failed',
[Build_BuildStatus.CANCELLED]: 'Cancelled',
[Build_BuildStatus.SKIPPED]: 'Skipped',
}

export enum ApplicationState {
Idle = 'Idle',
Deploying = 'Deploying',
Expand Down
Loading

0 comments on commit bcf4da0

Please sign in to comment.