@@ -8,20 +8,12 @@ import type {
8
8
Workspace ,
9
9
WorkspaceAgent ,
10
10
WorkspaceAgentMetadata ,
11
- WorkspaceApp ,
12
11
} from "api/typesGenerated" ;
13
12
import { isAxiosError } from "axios" ;
14
13
import { Button } from "components/Button/Button" ;
15
14
import { DropdownArrow } from "components/DropdownArrow/DropdownArrow" ;
16
- import {
17
- DropdownMenu ,
18
- DropdownMenuContent ,
19
- DropdownMenuItem ,
20
- DropdownMenuTrigger ,
21
- } from "components/DropdownMenu/DropdownMenu" ;
22
15
import { Stack } from "components/Stack/Stack" ;
23
16
import { useProxy } from "contexts/ProxyContext" ;
24
- import { Folder } from "lucide-react" ;
25
17
import { useFeatureVisibility } from "modules/dashboard/useFeatureVisibility" ;
26
18
import { AppStatuses } from "pages/WorkspacePage/AppStatuses" ;
27
19
import {
@@ -36,15 +28,14 @@ import {
36
28
import { useQuery } from "react-query" ;
37
29
import AutoSizer from "react-virtualized-auto-sizer" ;
38
30
import type { FixedSizeList as List , ListOnScrollProps } from "react-window" ;
39
- import { AgentButton } from "./AgentButton " ;
31
+ import { Apps , organizeAgentApps } from "./AgentApps/AgentApps " ;
40
32
import { AgentDevcontainerCard } from "./AgentDevcontainerCard" ;
41
33
import { AgentLatency } from "./AgentLatency" ;
42
34
import { AGENT_LOG_LINE_HEIGHT } from "./AgentLogs/AgentLogLine" ;
43
35
import { AgentLogs } from "./AgentLogs/AgentLogs" ;
44
36
import { AgentMetadata } from "./AgentMetadata" ;
45
37
import { AgentStatus } from "./AgentStatus" ;
46
38
import { AgentVersion } from "./AgentVersion" ;
47
- import { AppLink } from "./AppLink/AppLink" ;
48
39
import { DownloadAgentLogsButton } from "./DownloadAgentLogsButton" ;
49
40
import { PortForwardButton } from "./PortForwardButton" ;
50
41
import { AgentSSHButton } from "./SSHButton/SSHButton" ;
@@ -354,93 +345,6 @@ export const AgentRow: FC<AgentRowProps> = ({
354
345
) ;
355
346
} ;
356
347
357
- export type AppSection = {
358
- /**
359
- * If there is no `group`, just render all of the apps inline. If there is a
360
- * group name, show them all in a dropdown.
361
- */
362
- group ?: string ;
363
-
364
- apps : WorkspaceApp [ ] ;
365
- } ;
366
-
367
- /**
368
- * organizeAgentApps returns an ordering of agent apps that accounts for
369
- * grouping. When we receive the list of apps from the backend, they have
370
- * already been "ordered" by their `order` attribute, but we are not given that
371
- * value. We must be careful to preserve that ordering, while also properly
372
- * grouping together all apps of any given group.
373
- *
374
- * The position of the group overall is determined by the `order` position of
375
- * the first app in the group. There may be several sections returned without
376
- * a group name, to allow placing grouped apps in between non-grouped apps. Not
377
- * every ungrouped section is expected to have a group in between, to make the
378
- * algorithm a little simpler to implement.
379
- */
380
- export function organizeAgentApps ( apps : readonly WorkspaceApp [ ] ) : AppSection [ ] {
381
- let currentSection : AppSection | undefined = undefined ;
382
- const appGroups : AppSection [ ] = [ ] ;
383
- const groupsByName = new Map < string , AppSection > ( ) ;
384
-
385
- for ( const app of apps ) {
386
- if ( app . hidden ) {
387
- continue ;
388
- }
389
-
390
- if ( ! currentSection || app . group !== currentSection . group ) {
391
- const existingSection = groupsByName . get ( app . group ! ) ;
392
- if ( existingSection ) {
393
- currentSection = existingSection ;
394
- } else {
395
- currentSection = {
396
- group : app . group ,
397
- apps : [ ] ,
398
- } ;
399
- appGroups . push ( currentSection ) ;
400
- if ( app . group ) {
401
- groupsByName . set ( app . group , currentSection ) ;
402
- }
403
- }
404
- }
405
-
406
- currentSection . apps . push ( app ) ;
407
- }
408
-
409
- return appGroups ;
410
- }
411
-
412
- export type AppsProps = {
413
- section : AppSection ;
414
- agent : WorkspaceAgent ;
415
- workspace : Workspace ;
416
- } ;
417
-
418
- export const Apps : FC < AppsProps > = ( { section, agent, workspace } ) => {
419
- return section . group ? (
420
- < DropdownMenu >
421
- < DropdownMenuTrigger asChild >
422
- < AgentButton >
423
- < Folder />
424
- { section . group }
425
- </ AgentButton >
426
- </ DropdownMenuTrigger >
427
- < DropdownMenuContent align = "start" >
428
- { section . apps . map ( ( app ) => (
429
- < DropdownMenuItem key = { app . slug } >
430
- < AppLink grouped app = { app } agent = { agent } workspace = { workspace } />
431
- </ DropdownMenuItem >
432
- ) ) }
433
- </ DropdownMenuContent >
434
- </ DropdownMenu >
435
- ) : (
436
- < >
437
- { section . apps . map ( ( app ) => (
438
- < AppLink key = { app . slug } app = { app } agent = { agent } workspace = { workspace } />
439
- ) ) }
440
- </ >
441
- ) ;
442
- } ;
443
-
444
348
const styles = {
445
349
agentRow : ( theme ) => ( {
446
350
fontSize : 14 ,
0 commit comments