> = ({
const transitionStats =
template !== undefined ? ActiveTransition(template, workspace) : undefined;
+ const sidebarOption = useTab("sidebar", "");
+ const setSidebarOption = (newOption: string) => {
+ const { set, value } = sidebarOption;
+ if (value === newOption) {
+ set("");
+ } else {
+ set(newOption);
+ }
+ };
+
+ const selectedResourceId = useTab("resources", "");
+ const resources = [...workspace.latest_build.resources].sort(
+ (a, b) => countAgents(b) - countAgents(a),
+ );
+ const selectedResource = workspace.latest_build.resources.find(
+ (r) => r.id === selectedResourceId.value,
+ );
+ useEffect(() => {
+ if (resources.length > 0 && selectedResourceId.value === "") {
+ selectedResourceId.set(resources[0].id);
+ }
+ }, [resources, selectedResourceId]);
+
return (
> = ({
height: "100%",
overflowY: "auto",
borderRight: `1px solid ${theme.palette.divider}`,
+ display: "flex",
+ flexDirection: "column",
}}
>
{
- const sidebarOption = searchParams.get("sidebar");
- if (sidebarOption === "history") {
- searchParams.delete("sidebar");
- } else {
- searchParams.set("sidebar", "history");
- }
- setSearchParams(searchParams);
+ setSidebarOption("resources");
+ }}
+ >
+
+
+ {
+ setSidebarOption("history");
}}
>
- {searchParams.get("sidebar") === "history" && (
+ {sidebarOption.value === "resources" && (
+
+ )}
+ {sidebarOption.value === "history" && (
)}
@@ -342,9 +374,9 @@ export const Workspace: FC> = ({
{buildLogs}
- {resources && resources.length > 0 && (
- (
> = ({
);
};
+const countAgents = (resource: TypesGen.WorkspaceResource) => {
+ return resource.agents ? resource.agents.length : 0;
+};
+
const styles = {
content: {
padding: 24,
@@ -377,6 +413,7 @@ const styles = {
},
dotBackground: (theme) => ({
+ minHeight: "100%",
padding: 24,
"--d": "1px",
background: `
diff --git a/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx b/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx
index eecbe295a243b..f267d1689f1fd 100644
--- a/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx
+++ b/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx
@@ -224,7 +224,6 @@ export const WorkspaceReadyPage = ({
displayError(message);
}
}}
- resources={workspace.latest_build.resources}
canUpdateWorkspace={canUpdateWorkspace}
updateMessage={latestVersion?.message}
canChangeVersions={canChangeVersions}
diff --git a/site/src/pages/WorkspacesPage/BatchActions.tsx b/site/src/pages/WorkspacesPage/BatchActions.tsx
index 24f304cccdcf1..c3064ca35b65e 100644
--- a/site/src/pages/WorkspacesPage/BatchActions.tsx
+++ b/site/src/pages/WorkspacesPage/BatchActions.tsx
@@ -10,7 +10,7 @@ import { deleteWorkspace, startWorkspace, stopWorkspace } from "api/api";
import type { Workspace } from "api/typesGenerated";
import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog";
import { displayError } from "components/GlobalSnackbar/utils";
-import { getIconPathResource } from "components/Resources/ResourceAvatar";
+import { getResourceIconPath } from "utils/workspace";
import { Stack } from "components/Stack/Stack";
interface UseBatchActionsProps {
@@ -126,7 +126,7 @@ export const BatchDeleteConfirmation: FC = ({
...new Set(
checkedWorkspaces.flatMap((workspace) =>
workspace.latest_build.resources.map(
- (resource) => resource.icon || getIconPathResource(resource.type),
+ (resource) => resource.icon || getResourceIconPath(resource.type),
),
),
),
@@ -257,7 +257,7 @@ const Resources: FC = ({ workspaces }) => {
if (!resources[resource.type]) {
resources[resource.type] = {
count: 0,
- icon: resource.icon || getIconPathResource(resource.type),
+ icon: resource.icon || getResourceIconPath(resource.type),
};
}
diff --git a/site/src/utils/workspace.tsx b/site/src/utils/workspace.tsx
index 606fc343035cb..981a511b76fb4 100644
--- a/site/src/utils/workspace.tsx
+++ b/site/src/utils/workspace.tsx
@@ -285,3 +285,23 @@ export const workspaceUpdatePolicy = (
}
return workspace.automatic_updates;
};
+
+// These resources (i.e. docker_image, kubernetes_deployment) map to Terraform
+// resource types. These are the most used ones and are based on user usage.
+// We may want to update from time-to-time.
+const BUILT_IN_ICON_PATHS: Record = {
+ docker_volume: "/icon/database.svg",
+ docker_container: "/icon/memory.svg",
+ docker_image: "/icon/container.svg",
+ kubernetes_persistent_volume_claim: "/icon/database.svg",
+ kubernetes_pod: "/icon/memory.svg",
+ google_compute_disk: "/icon/database.svg",
+ google_compute_instance: "/icon/memory.svg",
+ aws_instance: "/icon/memory.svg",
+ kubernetes_deployment: "/icon/memory.svg",
+};
+const FALLBACK_ICON = "/icon/widgets.svg";
+
+export const getResourceIconPath = (resourceType: string): string => {
+ return BUILT_IN_ICON_PATHS[resourceType] ?? FALLBACK_ICON;
+};