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

Commit0bbb1c9

Browse files
committed
feat: Add links to the resource card for workspace applications (#2067)
* fix: Use proper webpack config for dev modeThis was broken when improving the build times. The typecheckerunfortunately missed it!* feat: Add links to the resource card for workspace applicationsFixes#1907 and#805.I'll make this pretty in another PR!* Improve style
1 parent9d72bb6 commit0bbb1c9

File tree

9 files changed

+298
-95
lines changed

9 files changed

+298
-95
lines changed

‎site/src/AppRouter.tsx

Lines changed: 96 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -19,145 +19,155 @@ import { WorkspaceBuildPage } from "./pages/WorkspaceBuildPage/WorkspaceBuildPag
1919
import{WorkspacePage}from"./pages/WorkspacePage/WorkspacePage"
2020
import{WorkspaceSchedulePage}from"./pages/WorkspaceSchedulePage/WorkspaceSchedulePage"
2121

22+
constWorkspaceAppErrorPage=lazy(()=>import("./pages/WorkspaceAppErrorPage/WorkspaceAppErrorPage"))
2223
constTerminalPage=lazy(()=>import("./pages/TerminalPage/TerminalPage"))
2324
constWorkspacesPage=lazy(()=>import("./pages/WorkspacesPage/WorkspacesPage"))
2425
constCreateWorkspacePage=lazy(()=>import("./pages/CreateWorkspacePage/CreateWorkspacePage"))
2526

2627
exportconstAppRouter:FC=()=>(
2728
<Suspensefallback={<></>}>
2829
<Routes>
29-
<Routepath="/">
30+
<Route
31+
index
32+
element={
33+
<RequireAuth>
34+
<IndexPage/>
35+
</RequireAuth>
36+
}
37+
/>
38+
39+
<Routepath="login"element={<LoginPage/>}/>
40+
<Routepath="healthz"element={<HealthzPage/>}/>
41+
<Route
42+
path="cli-auth"
43+
element={
44+
<RequireAuth>
45+
<CliAuthenticationPage/>
46+
</RequireAuth>
47+
}
48+
/>
49+
50+
<Routepath="workspaces">
3051
<Route
3152
index
3253
element={
33-
<RequireAuth>
34-
<IndexPage/>
35-
</RequireAuth>
54+
<AuthAndFrame>
55+
<WorkspacesPage/>
56+
</AuthAndFrame>
3657
}
3758
/>
3859

39-
<Routepath="login"element={<LoginPage/>}/>
40-
<Routepath="healthz"element={<HealthzPage/>}/>
4160
<Route
42-
path="cli-auth"
61+
path="new"
4362
element={
4463
<RequireAuth>
45-
<CliAuthenticationPage/>
64+
<CreateWorkspacePage/>
4665
</RequireAuth>
4766
}
4867
/>
4968

50-
<Routepath="workspaces">
69+
<Routepath=":workspace">
5170
<Route
5271
index
5372
element={
5473
<AuthAndFrame>
55-
<WorkspacesPage/>
74+
<WorkspacePage/>
5675
</AuthAndFrame>
5776
}
5877
/>
59-
6078
<Route
61-
path="new"
79+
path="schedule"
6280
element={
6381
<RequireAuth>
64-
<CreateWorkspacePage/>
82+
<WorkspaceSchedulePage/>
6583
</RequireAuth>
6684
}
6785
/>
68-
69-
<Routepath=":workspace">
70-
<Route
71-
index
72-
element={
73-
<AuthAndFrame>
74-
<WorkspacePage/>
75-
</AuthAndFrame>
76-
}
77-
/>
78-
<Route
79-
path="schedule"
80-
element={
81-
<RequireAuth>
82-
<WorkspaceSchedulePage/>
83-
</RequireAuth>
84-
}
85-
/>
86-
</Route>
8786
</Route>
87+
</Route>
8888

89-
<Routepath="templates">
90-
<Route
91-
index
92-
element={
93-
<AuthAndFrame>
94-
<TemplatesPage/>
95-
</AuthAndFrame>
96-
}
97-
/>
89+
<Routepath="templates">
90+
<Route
91+
index
92+
element={
93+
<AuthAndFrame>
94+
<TemplatesPage/>
95+
</AuthAndFrame>
96+
}
97+
/>
9898

99-
<Route
100-
path=":template"
101-
element={
102-
<AuthAndFrame>
103-
<TemplatePage/>
104-
</AuthAndFrame>
105-
}
106-
/>
107-
</Route>
99+
<Route
100+
path=":template"
101+
element={
102+
<AuthAndFrame>
103+
<TemplatePage/>
104+
</AuthAndFrame>
105+
}
106+
/>
107+
</Route>
108108

109-
<Routepath="users">
110-
<Route
111-
index
112-
element={
113-
<AuthAndFrame>
114-
<UsersPage/>
115-
</AuthAndFrame>
116-
}
117-
/>
109+
<Routepath="users">
110+
<Route
111+
index
112+
element={
113+
<AuthAndFrame>
114+
<UsersPage/>
115+
</AuthAndFrame>
116+
}
117+
/>
118+
<Route
119+
path="create"
120+
element={
121+
<RequireAuth>
122+
<CreateUserPage/>
123+
</RequireAuth>
124+
}
125+
/>
126+
</Route>
127+
128+
<Routepath="settings"element={<SettingsLayout/>}>
129+
<Routepath="account"element={<AccountPage/>}/>
130+
<Routepath="security"element={<SecurityPage/>}/>
131+
<Routepath="ssh-keys"element={<SSHKeysPage/>}/>
132+
</Route>
133+
134+
<Route
135+
path="builds/:buildId"
136+
element={
137+
<AuthAndFrame>
138+
<WorkspaceBuildPage/>
139+
</AuthAndFrame>
140+
}
141+
/>
142+
143+
<Routepath="/@:username">
144+
<Routepath=":workspace">
118145
<Route
119-
path="create"
146+
path="terminal"
120147
element={
121148
<RequireAuth>
122-
<CreateUserPage/>
149+
<TerminalPage/>
123150
</RequireAuth>
124151
}
125152
/>
126-
</Route>
127153

128-
<Routepath="settings"element={<SettingsLayout/>}>
129-
<Routepath="account"element={<AccountPage/>}/>
130-
<Routepath="security"element={<SecurityPage/>}/>
131-
<Routepath="ssh-keys"element={<SSHKeysPage/>}/>
132-
</Route>
133-
134-
<Routepath=":username">
135-
<Routepath=":workspace">
154+
<Routepath="apps">
136155
<Route
137-
path="terminal"
156+
path=":app/*"
138157
element={
139-
<RequireAuth>
140-
<TerminalPage/>
141-
</RequireAuth>
158+
<AuthAndFrame>
159+
<WorkspaceAppErrorPage/>
160+
</AuthAndFrame>
142161
}
143162
/>
144163
</Route>
145164
</Route>
165+
</Route>
146166

147-
<Route
148-
path="builds/:buildId"
149-
element={
150-
<AuthAndFrame>
151-
<WorkspaceBuildPage/>
152-
</AuthAndFrame>
153-
}
154-
/>
155-
156-
{/* Using path="*"" means "match anything", so this route
167+
{/* Using path="*"" means "match anything", so this route
157168
acts like a catch-all for URLs that we don't have explicit
158169
routes for. */}
159-
<Routepath="*"element={<NotFoundPage/>}/>
160-
</Route>
170+
<Routepath="*"element={<NotFoundPage/>}/>
161171
</Routes>
162172
</Suspense>
163173
)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import{Story}from"@storybook/react"
2+
import{MockWorkspace}from"../../testHelpers/renderHelpers"
3+
import{AppLink,AppLinkProps}from"./AppLink"
4+
5+
exportdefault{
6+
title:"components/AppLink",
7+
component:AppLink,
8+
}
9+
10+
constTemplate:Story<AppLinkProps>=(args)=><AppLink{...args}/>
11+
12+
exportconstWithIcon=Template.bind({})
13+
WithIcon.args={
14+
userName:"developer",
15+
workspaceName:MockWorkspace.name,
16+
appName:"code-server",
17+
appIcon:"/code.svg",
18+
}
19+
20+
exportconstWithoutIcon=Template.bind({})
21+
WithoutIcon.args={
22+
userName:"developer",
23+
workspaceName:MockWorkspace.name,
24+
appName:"code-server",
25+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
importLinkfrom"@material-ui/core/Link"
2+
import{makeStyles}from"@material-ui/core/styles"
3+
importReact,{FC}from"react"
4+
import*asTypesGenfrom"../../api/typesGenerated"
5+
import{combineClasses}from"../../util/combineClasses"
6+
7+
exportinterfaceAppLinkProps{
8+
userName:TypesGen.User["username"]
9+
workspaceName:TypesGen.Workspace["name"]
10+
appName:TypesGen.WorkspaceApp["name"]
11+
appIcon:TypesGen.WorkspaceApp["icon"]
12+
}
13+
14+
exportconstAppLink:FC<AppLinkProps>=({ userName, workspaceName, appName, appIcon})=>{
15+
conststyles=useStyles()
16+
consthref=`/@${userName}/${workspaceName}/apps/${appName}`
17+
18+
return(
19+
<Linkhref={href}target="_blank"className={styles.link}>
20+
<img
21+
className={combineClasses([styles.icon,appIcon==="" ?"empty" :""])}
22+
alt={`${appName} Icon`}
23+
src={appIcon||""}
24+
/>
25+
{appName}
26+
</Link>
27+
)
28+
}
29+
30+
constuseStyles=makeStyles((theme)=>({
31+
link:{
32+
color:theme.palette.text.secondary,
33+
display:"flex",
34+
alignItems:"center",
35+
},
36+
37+
icon:{
38+
width:16,
39+
height:16,
40+
marginRight:theme.spacing(1.5),
41+
42+
// If no icon is provided we still want the padding on the left
43+
// to occur.
44+
"&.empty":{
45+
opacity:0,
46+
},
47+
},
48+
}))

‎site/src/components/Resources/Resources.tsx

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import useTheme from "@material-ui/styles/useTheme"
88
import{FC}from"react"
99
import{Workspace,WorkspaceResource}from"../../api/typesGenerated"
1010
import{getDisplayAgentStatus}from"../../util/workspace"
11+
import{AppLink}from"../AppLink/AppLink"
12+
import{Stack}from"../Stack/Stack"
1113
import{TableHeaderRow}from"../TableHeaders/TableHeaders"
1214
import{TerminalLink}from"../TerminalLink/TerminalLink"
1315
import{WorkspaceSection}from"../WorkspaceSection/WorkspaceSection"
@@ -83,14 +85,26 @@ export const Resources: FC<ResourcesProps> = ({ resources, getResourcesError, wo
8385
<spanclassName={styles.operatingSystem}>{agent.operating_system}</span>
8486
</TableCell>
8587
<TableCell>
86-
{agent.status==="connected"&&(
87-
<TerminalLink
88-
className={styles.accessLink}
89-
workspaceName={workspace.name}
90-
agentName={agent.name}
91-
userName={workspace.owner_name}
92-
/>
93-
)}
88+
<Stack>
89+
{agent.status==="connected"&&(
90+
<TerminalLink
91+
className={styles.accessLink}
92+
workspaceName={workspace.name}
93+
agentName={agent.name}
94+
userName={workspace.owner_name}
95+
/>
96+
)}
97+
{agent.status==="connected"&&
98+
agent.apps.map((app)=>(
99+
<AppLink
100+
key={app.name}
101+
appIcon={app.icon}
102+
appName={app.name}
103+
userName={workspace.owner_name}
104+
workspaceName={workspace.name}
105+
/>
106+
))}
107+
</Stack>
94108
</TableCell>
95109
<TableCell>
96110
<spanstyle={{color:getDisplayAgentStatus(theme,agent).color}}>

‎site/src/components/TerminalLink/TerminalLink.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export interface TerminalLinkProps {
2626
*/
2727
exportconstTerminalLink:FC<TerminalLinkProps>=({ agentName, userName="me", workspaceName, className})=>{
2828
conststyles=useStyles()
29-
consthref=`/${userName}/${workspaceName}${agentName ?`.${agentName}` :""}/terminal`
29+
consthref=`/@${userName}/${workspaceName}${agentName ?`.${agentName}` :""}/terminal`
3030

3131
return(
3232
<Link
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import{FC,useMemo}from"react"
2+
import{useParams}from"react-router-dom"
3+
import{WorkspaceAppErrorPageView}from"./WorkspaceAppErrorPageView"
4+
5+
constWorkspaceAppErrorView:FC=()=>{
6+
const{ app}=useParams()
7+
constmessage=useMemo(()=>{
8+
consttag=document.getElementById("api-response")
9+
if(!tag){
10+
thrownewError("dev error: api-response meta tag not found")
11+
}
12+
returntag.getAttribute("data-message")asstring
13+
},[])
14+
15+
return<WorkspaceAppErrorPageViewappName={appasstring}message={message}/>
16+
}
17+
18+
exportdefaultWorkspaceAppErrorView

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp