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

Commit1adad41

Browse files
feat: display user apps in the workspaces table (#17744)
Related to#17311**Demo:**<img width="1511" alt="Screenshot 2025-05-09 at 11 46 59"src="https://github.com/user-attachments/assets/3e9ba618-ed5d-4eeb-996f-d7bcceb9f1a9"/>
1 parent4970fb9 commit1adad41

File tree

3 files changed

+95
-18
lines changed

3 files changed

+95
-18
lines changed

‎site/src/pages/WorkspacesPage/WorkspacesPageView.stories.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
MockTemplate,
2424
MockUserOwner,
2525
MockWorkspace,
26+
MockWorkspaceAgent,
2627
MockWorkspaceAppStatus,
2728
mockApiError,
2829
}from"testHelpers/entities";
@@ -299,6 +300,42 @@ export const InvalidPageNumber: Story = {
299300
},
300301
};
301302

303+
exportconstMultipleApps:Story={
304+
args:{
305+
workspaces:[
306+
{
307+
...MockWorkspace,
308+
latest_build:{
309+
...MockWorkspace.latest_build,
310+
resources:[
311+
{
312+
...MockWorkspace.latest_build.resources[0],
313+
agents:[
314+
{
315+
...MockWorkspaceAgent,
316+
apps:[
317+
{
318+
...MockWorkspaceAgent.apps[0],
319+
display_name:"App 1",
320+
id:"app-1",
321+
},
322+
{
323+
...MockWorkspaceAgent.apps[0],
324+
display_name:"App 2",
325+
id:"app-2",
326+
},
327+
],
328+
},
329+
],
330+
},
331+
],
332+
},
333+
},
334+
],
335+
count:allWorkspaces.length,
336+
},
337+
};
338+
302339
exportconstShowOrganizations:Story={
303340
args:{
304341
workspaces:[{ ...MockWorkspace,organization_name:"limbus-co"}],

‎site/src/pages/WorkspacesPage/WorkspacesTable.tsx

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { Avatar } from "components/Avatar/Avatar";
1919
import{AvatarData}from"components/Avatar/AvatarData";
2020
import{AvatarDataSkeleton}from"components/Avatar/AvatarDataSkeleton";
2121
import{Button}from"components/Button/Button";
22+
import{ExternalImage}from"components/ExternalImage/ExternalImage";
2223
import{VSCodeIcon}from"components/Icons/VSCodeIcon";
2324
import{VSCodeInsidersIcon}from"components/Icons/VSCodeInsidersIcon";
2425
import{InfoTooltip}from"components/InfoTooltip/InfoTooltip";
@@ -63,6 +64,7 @@ import {
6364
getVSCodeHref,
6465
openAppInNewWindow,
6566
}from"modules/apps/apps";
67+
import{useAppLink}from"modules/apps/useAppLink";
6668
import{useDashboard}from"modules/dashboard/useDashboard";
6769
import{WorkspaceAppStatus}from"modules/workspaces/WorkspaceAppStatus/WorkspaceAppStatus";
6870
import{WorkspaceDormantBadge}from"modules/workspaces/WorkspaceDormantBadge/WorkspaceDormantBadge";
@@ -622,6 +624,9 @@ const PrimaryAction: FC<PrimaryActionProps> = ({
622624
);
623625
};
624626

627+
// The total number of apps that can be displayed in the workspace row
628+
constWORKSPACE_APPS_SLOTS=4;
629+
625630
typeWorkspaceAppsProps={
626631
workspace:Workspace;
627632
};
@@ -647,11 +652,18 @@ const WorkspaceApps: FC<WorkspaceAppsProps> = ({ workspace }) => {
647652
returnnull;
648653
}
649654

655+
constbuiltinApps=newSet(agent.display_apps);
656+
builtinApps.delete("port_forwarding_helper");
657+
builtinApps.delete("ssh_helper");
658+
659+
constremainingSlots=WORKSPACE_APPS_SLOTS-builtinApps.size;
660+
constuserApps=agent.apps.slice(0,remainingSlots);
661+
650662
constbuttons:ReactNode[]=[];
651663

652-
if(agent.display_apps.includes("vscode")){
664+
if(builtinApps.has("vscode")){
653665
buttons.push(
654-
<AppLink
666+
<BaseIconLink
655667
key="vscode"
656668
isLoading={!token}
657669
label="Open VSCode"
@@ -664,13 +676,13 @@ const WorkspaceApps: FC<WorkspaceAppsProps> = ({ workspace }) => {
664676
})}
665677
>
666678
<VSCodeIcon/>
667-
</AppLink>,
679+
</BaseIconLink>,
668680
);
669681
}
670682

671-
if(agent.display_apps.includes("vscode_insiders")){
683+
if(builtinApps.has("vscode_insiders")){
672684
buttons.push(
673-
<AppLink
685+
<BaseIconLink
674686
key="vscode-insiders"
675687
label="Open VSCode Insiders"
676688
isLoading={!token}
@@ -683,18 +695,29 @@ const WorkspaceApps: FC<WorkspaceAppsProps> = ({ workspace }) => {
683695
})}
684696
>
685697
<VSCodeInsidersIcon/>
686-
</AppLink>,
698+
</BaseIconLink>,
687699
);
688700
}
689701

690-
if(agent.display_apps.includes("web_terminal")){
702+
for(constappofuserApps){
703+
buttons.push(
704+
<IconAppLink
705+
key={app.id}
706+
app={app}
707+
workspace={workspace}
708+
agent={agent}
709+
/>,
710+
);
711+
}
712+
713+
if(builtinApps.has("web_terminal")){
691714
consthref=getTerminalHref({
692715
username:workspace.owner_name,
693716
workspace:workspace.name,
694717
agent:agent.name,
695718
});
696719
buttons.push(
697-
<AppLink
720+
<BaseIconLink
698721
key="terminal"
699722
href={href}
700723
onClick={(e)=>{
@@ -704,21 +727,45 @@ const WorkspaceApps: FC<WorkspaceAppsProps> = ({ workspace }) => {
704727
label="Open Terminal"
705728
>
706729
<SquareTerminalIcon/>
707-
</AppLink>,
730+
</BaseIconLink>,
708731
);
709732
}
710733

711734
returnbuttons;
712735
};
713736

714-
typeAppLinkProps=PropsWithChildren<{
737+
typeIconAppLinkProps={
738+
app:WorkspaceApp;
739+
workspace:Workspace;
740+
agent:WorkspaceAgent;
741+
};
742+
743+
constIconAppLink:FC<IconAppLinkProps>=({ app, workspace, agent})=>{
744+
constlink=useAppLink(app,{
745+
workspace,
746+
agent,
747+
});
748+
749+
return(
750+
<BaseIconLink
751+
key={app.id}
752+
label={`Open${link.label}`}
753+
href={link.href}
754+
onClick={link.onClick}
755+
>
756+
<ExternalImagesrc={app.icon??"/icon/widgets.svg"}/>
757+
</BaseIconLink>
758+
);
759+
};
760+
761+
typeBaseIconLinkProps=PropsWithChildren<{
715762
label:string;
716763
href:string;
717764
isLoading?:boolean;
718765
onClick?:(e:React.MouseEvent<HTMLAnchorElement>)=>void;
719766
}>;
720767

721-
constAppLink:FC<AppLinkProps>=({
768+
constBaseIconLink:FC<BaseIconLinkProps>=({
722769
href,
723770
isLoading,
724771
label,

‎site/src/testHelpers/entities.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -896,17 +896,10 @@ export const MockWorkspaceApp: TypesGen.WorkspaceApp = {
896896
id:"test-app",
897897
slug:"test-app",
898898
display_name:"Test App",
899-
icon:"",
900899
subdomain:false,
901900
health:"disabled",
902901
external:false,
903-
url:"",
904902
sharing_level:"owner",
905-
healthcheck:{
906-
url:"",
907-
interval:0,
908-
threshold:0,
909-
},
910903
hidden:false,
911904
open_in:"slim-window",
912905
statuses:[],

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp