Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitce7bf0b

Browse files
feat: Redesign the workspace page (#1620)
1 parent0622603 commitce7bf0b

File tree

15 files changed

+436
-316
lines changed

15 files changed

+436
-316
lines changed

‎.vscode/settings.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"coderd",
88
"coderdtest",
99
"codersdk",
10+
"cronstrue",
1011
"devel",
1112
"drpc",
1213
"drpcconn",
Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
import{makeStyles}from"@material-ui/core/styles"
22
importReactfrom"react"
33

4-
exportinterfaceStackProps{
5-
spacing?:number
4+
typeDirection="column"|"row"
5+
6+
interfaceStyleProps{
7+
spacing:number
8+
direction:Direction
69
}
710

811
constuseStyles=makeStyles((theme)=>({
912
stack:{
1013
display:"flex",
11-
flexDirection:"column",
12-
gap:({ spacing}:{spacing:number})=>theme.spacing(spacing),
14+
flexDirection:({ direction}:StyleProps)=>direction,
15+
gap:({ spacing}:StyleProps)=>theme.spacing(spacing),
1316
},
1417
}))
1518

16-
exportconstStack:React.FC<StackProps>=({ children, spacing=2})=>{
17-
conststyles=useStyles({ spacing})
19+
exportinterfaceStackProps{
20+
spacing?:number
21+
direction?:Direction
22+
}
23+
24+
exportconstStack:React.FC<StackProps>=({ children, spacing=2, direction="column"})=>{
25+
conststyles=useStyles({ spacing, direction})
1826
return<divclassName={styles.stack}>{children}</div>
1927
}

‎site/src/components/Workspace/Workspace.tsx‎

Lines changed: 42 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ import { makeStyles } from "@material-ui/core/styles"
22
importTypographyfrom"@material-ui/core/Typography"
33
importReactfrom"react"
44
import*asTypesGenfrom"../../api/typesGenerated"
5+
import{MONOSPACE_FONT_FAMILY}from"../../theme/constants"
56
import{WorkspaceStatus}from"../../util/workspace"
67
import{BuildsTable}from"../BuildsTable/BuildsTable"
7-
import{WorkspaceSchedule}from"../WorkspaceSchedule/WorkspaceSchedule"
8+
import{Stack}from"../Stack/Stack"
9+
import{WorkspaceActions}from"../WorkspaceActions/WorkspaceActions"
810
import{WorkspaceSection}from"../WorkspaceSection/WorkspaceSection"
9-
import{WorkspaceStatusBar}from"../WorkspaceStatusBar/WorkspaceStatusBar"
11+
import{WorkspaceStats}from"../WorkspaceStats/WorkspaceStats"
1012

1113
exportinterfaceWorkspaceProps{
1214
handleStart:()=>void
@@ -34,76 +36,62 @@ export const Workspace: React.FC<WorkspaceProps> = ({
3436

3537
return(
3638
<divclassName={styles.root}>
37-
<divclassName={styles.vertical}>
38-
<WorkspaceStatusBar
39-
workspace={workspace}
40-
handleStart={handleStart}
41-
handleStop={handleStop}
42-
handleRetry={handleRetry}
43-
handleUpdate={handleUpdate}
44-
workspaceStatus={workspaceStatus}
45-
/>
39+
<divclassName={styles.header}>
40+
<div>
41+
<Typographyvariant="h4"className={styles.title}>
42+
{workspace.name}
43+
</Typography>
4644

47-
<divclassName={styles.horizontal}>
48-
<divclassName={styles.sidebarContainer}>
49-
<WorkspaceSectiontitle="Applications">
50-
<Placeholder/>
51-
</WorkspaceSection>
52-
<WorkspaceScheduleworkspace={workspace}/>
53-
54-
<WorkspaceSectiontitle="Dev URLs">
55-
<Placeholder/>
56-
</WorkspaceSection>
57-
58-
<WorkspaceSectiontitle="Resources">
59-
<Placeholder/>
60-
</WorkspaceSection>
61-
</div>
45+
<Typographycolor="textSecondary"className={styles.subtitle}>
46+
{workspace.owner_name}
47+
</Typography>
48+
</div>
6249

63-
<divclassName={styles.timelineContainer}>
64-
<WorkspaceSectiontitle="Timeline"contentsProps={{className:styles.timelineContents}}>
65-
<BuildsTablebuilds={builds}className={styles.timelineTable}/>
66-
</WorkspaceSection>
67-
</div>
50+
<divclassName={styles.headerActions}>
51+
<WorkspaceActions
52+
workspace={workspace}
53+
handleStart={handleStart}
54+
handleStop={handleStop}
55+
handleRetry={handleRetry}
56+
handleUpdate={handleUpdate}
57+
workspaceStatus={workspaceStatus}
58+
/>
6859
</div>
6960
</div>
70-
</div>
71-
)
72-
}
7361

74-
/**
75-
* Temporary placeholder component until we have the sections implemented
76-
* Can be removed once the Workspace page has all the necessary sections
77-
*/
78-
constPlaceholder:React.FC=()=>{
79-
return(
80-
<divstyle={{textAlign:"center",opacity:"0.5"}}>
81-
<Typographyvariant="caption">Not yet implemented</Typography>
62+
<Stackspacing={3}>
63+
<WorkspaceStatsworkspace={workspace}/>
64+
<WorkspaceSectiontitle="Timeline"contentsProps={{className:styles.timelineContents}}>
65+
<BuildsTablebuilds={builds}className={styles.timelineTable}/>
66+
</WorkspaceSection>
67+
</Stack>
8268
</div>
8369
)
8470
}
8571

86-
exportconstuseStyles=makeStyles(()=>{
72+
exportconstuseStyles=makeStyles((theme)=>{
8773
return{
8874
root:{
8975
display:"flex",
9076
flexDirection:"column",
9177
},
92-
horizontal:{
78+
header:{
79+
paddingTop:theme.spacing(5),
80+
paddingBottom:theme.spacing(5),
81+
fontFamily:MONOSPACE_FONT_FAMILY,
9382
display:"flex",
94-
flexDirection:"row",
83+
alignItems:"center",
9584
},
96-
vertical:{
97-
display:"flex",
98-
flexDirection:"column",
85+
headerActions:{
86+
marginLeft:"auto",
9987
},
100-
sidebarContainer:{
101-
display:"flex",
102-
flexDirection:"column",
103-
flex:"0 0 350px",
88+
title:{
89+
fontWeight:600,
90+
fontFamily:"inherit",
10491
},
105-
timelineContainer:{
106-
flex:1,
92+
subtitle:{
93+
fontFamily:"inherit",
94+
marginTop:theme.spacing(0.5),
10795
},
10896
timelineContents:{
10997
margin:0,
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
importPlayArrowRoundedIconfrom"@material-ui/icons/PlayArrowRounded"
2+
import{ComponentMeta,Story}from"@storybook/react"
3+
importReactfrom"react"
4+
import{WorkspaceActionButton,WorkspaceActionButtonProps}from"./WorkspaceActionButton"
5+
6+
exportdefault{
7+
title:"components/WorkspaceActionButton",
8+
component:WorkspaceActionButton,
9+
}asComponentMeta<typeofWorkspaceActionButton>
10+
11+
constTemplate:Story<WorkspaceActionButtonProps>=(args)=><WorkspaceActionButton{...args}/>
12+
13+
exportconstExample=Template.bind({})
14+
Example.args={
15+
icon:<PlayArrowRoundedIcon/>,
16+
label:"Start workspace",
17+
loadingLabel:"Starting workspace",
18+
isLoading:false,
19+
}
20+
21+
exportconstLoading=Template.bind({})
22+
Loading.args={
23+
icon:<PlayArrowRoundedIcon/>,
24+
label:"Start workspace",
25+
loadingLabel:"Starting workspace",
26+
isLoading:true,
27+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
importButtonfrom"@material-ui/core/Button"
2+
importCircularProgressfrom"@material-ui/core/CircularProgress"
3+
import{makeStyles}from"@material-ui/core/styles"
4+
importReactfrom"react"
5+
6+
exportinterfaceWorkspaceActionButtonProps{
7+
label:string
8+
loadingLabel:string
9+
isLoading:boolean
10+
icon:JSX.Element
11+
onClick:()=>void
12+
className?:string
13+
}
14+
15+
exportconstWorkspaceActionButton:React.FC<WorkspaceActionButtonProps>=({
16+
label,
17+
loadingLabel,
18+
isLoading,
19+
icon,
20+
onClick,
21+
className,
22+
})=>{
23+
conststyles=useStyles()
24+
25+
return(
26+
<Button
27+
className={className}
28+
startIcon={isLoading ?<CircularProgresssize={12}className={styles.spinner}/> :icon}
29+
onClick={onClick}
30+
disabled={isLoading}
31+
>
32+
{isLoading ?loadingLabel :label}
33+
</Button>
34+
)
35+
}
36+
37+
constuseStyles=makeStyles((theme)=>({
38+
spinner:{
39+
color:theme.palette.text.disabled,
40+
marginRight:theme.spacing(1),
41+
},
42+
}))
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
importButtonfrom"@material-ui/core/Button"
2+
importLinkfrom"@material-ui/core/Link"
3+
import{makeStyles}from"@material-ui/core/styles"
4+
importCloudDownloadIconfrom"@material-ui/icons/CloudDownload"
5+
importPlayArrowRoundedIconfrom"@material-ui/icons/PlayArrowRounded"
6+
importReplayIconfrom"@material-ui/icons/Replay"
7+
importStopIconfrom"@material-ui/icons/Stop"
8+
importReactfrom"react"
9+
import{LinkasRouterLink}from"react-router-dom"
10+
import{Workspace}from"../../api/typesGenerated"
11+
import{WorkspaceStatus}from"../../util/workspace"
12+
import{Stack}from"../Stack/Stack"
13+
import{WorkspaceActionButton}from"../WorkspaceActionButton/WorkspaceActionButton"
14+
15+
exportconstLanguage={
16+
stop:"Stop workspace",
17+
stopping:"Stopping workspace",
18+
start:"Start workspace",
19+
starting:"Starting workspace",
20+
retry:"Retry",
21+
update:"Update workspace",
22+
}
23+
24+
/**
25+
* Jobs submitted while another job is in progress will be discarded,
26+
* so check whether workspace job status has reached completion (whether successful or not).
27+
*/
28+
constcanAcceptJobs=(workspaceStatus:WorkspaceStatus)=>
29+
["started","stopped","deleted","error","canceled"].includes(workspaceStatus)
30+
31+
exportinterfaceWorkspaceActionsProps{
32+
workspace:Workspace
33+
workspaceStatus:WorkspaceStatus
34+
handleStart:()=>void
35+
handleStop:()=>void
36+
handleRetry:()=>void
37+
handleUpdate:()=>void
38+
}
39+
40+
exportconstWorkspaceActions:React.FC<WorkspaceActionsProps>=({
41+
workspace,
42+
workspaceStatus,
43+
handleStart,
44+
handleStop,
45+
handleRetry,
46+
handleUpdate,
47+
})=>{
48+
conststyles=useStyles()
49+
50+
return(
51+
<Stackdirection="row"spacing={1}>
52+
<Linkunderline="none"component={RouterLink}to="edit">
53+
<Buttonvariant="outlined">Settings</Button>
54+
</Link>
55+
{(workspaceStatus==="started"||workspaceStatus==="stopping")&&(
56+
<WorkspaceActionButton
57+
className={styles.actionButton}
58+
icon={<StopIcon/>}
59+
onClick={handleStop}
60+
label={Language.stop}
61+
loadingLabel={Language.stopping}
62+
isLoading={workspaceStatus==="stopping"}
63+
/>
64+
)}
65+
{(workspaceStatus==="stopped"||workspaceStatus==="starting")&&(
66+
<WorkspaceActionButton
67+
className={styles.actionButton}
68+
icon={<PlayArrowRoundedIcon/>}
69+
onClick={handleStart}
70+
label={Language.start}
71+
loadingLabel={Language.starting}
72+
isLoading={workspaceStatus==="starting"}
73+
/>
74+
)}
75+
{workspaceStatus==="error"&&(
76+
<ButtonclassName={styles.actionButton}startIcon={<ReplayIcon/>}onClick={handleRetry}>
77+
{Language.retry}
78+
</Button>
79+
)}
80+
{workspace.outdated&&canAcceptJobs(workspaceStatus)&&(
81+
<ButtonclassName={styles.actionButton}startIcon={<CloudDownloadIcon/>}onClick={handleUpdate}>
82+
{Language.update}
83+
</Button>
84+
)}
85+
</Stack>
86+
)
87+
}
88+
89+
constuseStyles=makeStyles((theme)=>({
90+
actionButton:{
91+
// Set fixed width for the action buttons so they will not change the size
92+
// during the transitions
93+
width:theme.spacing(30),
94+
},
95+
}))

‎site/src/components/WorkspaceBuildStats/WorkspaceBuildStats.tsx‎

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { makeStyles, useTheme } from "@material-ui/core/styles"
33
importReactfrom"react"
44
import{LinkasRouterLink}from"react-router-dom"
55
import{WorkspaceBuild}from"../../api/typesGenerated"
6-
import{MONOSPACE_FONT_FAMILY}from"../../theme/constants"
6+
import{CardRadius,MONOSPACE_FONT_FAMILY}from"../../theme/constants"
77
import{combineClasses}from"../../util/combineClasses"
88
import{displayWorkspaceBuildDuration,getDisplayStatus}from"../../util/workspace"
99

@@ -57,17 +57,21 @@ export const WorkspaceBuildStats: React.FC<WorkspaceBuildStatsProps> = ({ build
5757

5858
constuseStyles=makeStyles((theme)=>({
5959
stats:{
60-
paddingTop:theme.spacing(3),
61-
paddingBottom:theme.spacing(3),
60+
paddingLeft:theme.spacing(2),
61+
paddingRight:theme.spacing(2),
62+
backgroundColor:theme.palette.background.paper,
63+
borderRadius:CardRadius,
6264
display:"flex",
6365
alignItems:"center",
6466
color:theme.palette.text.secondary,
6567
fontFamily:MONOSPACE_FONT_FAMILY,
68+
border:`1px solid${theme.palette.divider}`,
6669
},
6770

6871
statItem:{
6972
minWidth:theme.spacing(20),
70-
paddingRight:theme.spacing(3),
73+
padding:theme.spacing(2),
74+
paddingTop:theme.spacing(1.75),
7175
},
7276

7377
statsLabel:{
@@ -80,14 +84,14 @@ const useStyles = makeStyles((theme) => ({
8084
statsValue:{
8185
fontSize:16,
8286
marginTop:theme.spacing(0.25),
83-
display:"block",
87+
display:"inline-block",
8488
},
8589

8690
statsDivider:{
8791
width:1,
8892
height:theme.spacing(5),
8993
backgroundColor:theme.palette.divider,
90-
marginRight:theme.spacing(3),
94+
marginRight:theme.spacing(2),
9195
},
9296

9397
capitalize:{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp