Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const styles = {
}),
dialogContent: (theme) => ({
color: theme.palette.text.secondary,
padding: 40,
padding: "40px 40px 20px",
}),
dialogTitle: (theme) => ({
margin: 0,
Expand Down
4 changes: 2 additions & 2 deletions site/src/components/Dialogs/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ const styles = {
},

"&:hover:not(:disabled)": {
backgroundColor: theme.experimental.roles.danger.disabled.fill,
borderColor: theme.experimental.roles.danger.disabled.outline,
backgroundColor: theme.experimental.roles.danger.hover.fill,
borderColor: theme.experimental.roles.danger.hover.outline,
},

"&.Mui-disabled": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@ export const WorkspaceOutdatedTooltip: FC<TooltipProps> = (props) => {
);
};

export const WorkspaceOutdatedTooltipContent = (props: TooltipProps) => {
export const WorkspaceOutdatedTooltipContent: FC<TooltipProps> = ({
onUpdateVersion,
ariaLabel,
latestVersionId,
templateName,
}) => {
const popover = usePopover();
const { onUpdateVersion, ariaLabel, latestVersionId, templateName } = props;
const { data: activeVersion } = useQuery({
...templateVersion(latestVersionId),
enabled: popover.isOpen,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ export const DeleteDialog: Story = {
args: {
queryKey: ["tokens"],
token: MockToken,
setToken: () => {
return null;
},
setToken: () => null,
},
};
6 changes: 3 additions & 3 deletions site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useDashboard } from "components/Dashboard/DashboardProvider";
import { useFeatureVisibility } from "hooks/useFeatureVisibility";
import { FC, useEffect, useState } from "react";
import { type FC, useEffect, useState } from "react";
import { Helmet } from "react-helmet-async";
import { useNavigate } from "react-router-dom";
import { Workspace } from "./Workspace";
Expand Down Expand Up @@ -42,11 +42,11 @@ interface WorkspaceReadyPageProps {
permissions: WorkspacePermissions;
}

export const WorkspaceReadyPage = ({
export const WorkspaceReadyPage: FC<WorkspaceReadyPageProps> = ({
workspace,
template,
permissions,
}: WorkspaceReadyPageProps): JSX.Element => {
}) => {
const navigate = useNavigate();
const queryClient = useQueryClient();
const { buildInfo } = useDashboard();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { action } from "@storybook/addon-actions";
import type { Meta, StoryObj } from "@storybook/react";
import { chromatic } from "testHelpers/chromatic";
import { MockWorkspace, MockUser2 } from "testHelpers/entities";
import { BatchDeleteConfirmation } from "./BatchActions";
import { BatchDeleteConfirmation } from "./BatchDeleteConfirmation";

const meta: Meta<typeof BatchDeleteConfirmation> = {
title: "pages/WorkspacesPage/BatchDelete",
title: "pages/WorkspacesPage/BatchDeleteConfirmation",
parameters: { chromatic },
component: BatchDeleteConfirmation,
args: {
onClose: action("onClose"),
Expand Down Expand Up @@ -35,4 +37,4 @@ type Story = StoryObj<typeof BatchDeleteConfirmation>;

const Example: Story = {};

export { Example as BatchDelete };
export { Example as BatchDeleteConfirmation };
Original file line number Diff line number Diff line change
Expand Up @@ -2,68 +2,15 @@ import PersonOutlinedIcon from "@mui/icons-material/PersonOutlined";
import ScheduleIcon from "@mui/icons-material/Schedule";
import { visuallyHidden } from "@mui/utils";
import dayjs from "dayjs";
import "dayjs/plugin/relativeTime";
import { type Interpolation, type Theme } from "@emotion/react";
import relativeTime from "dayjs/plugin/relativeTime";
import { useTheme, type Interpolation, type Theme } from "@emotion/react";
import { type FC, type ReactNode, useState } from "react";
import { useMutation } from "react-query";
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 { getResourceIconPath } from "utils/workspace";
import { Stack } from "components/Stack/Stack";
import { getResourceIconPath } from "utils/workspace";

interface UseBatchActionsProps {
onSuccess: () => Promise<void>;
}

export function useBatchActions(options: UseBatchActionsProps) {
const { onSuccess } = options;

const startAllMutation = useMutation({
mutationFn: async (workspaces: Workspace[]) => {
return Promise.all(
workspaces.map((w) =>
startWorkspace(w.id, w.latest_build.template_version_id),
),
);
},
onSuccess,
onError: () => {
displayError("Failed to start workspaces");
},
});

const stopAllMutation = useMutation({
mutationFn: async (workspaces: Workspace[]) => {
return Promise.all(workspaces.map((w) => stopWorkspace(w.id)));
},
onSuccess,
onError: () => {
displayError("Failed to stop workspaces");
},
});

const deleteAllMutation = useMutation({
mutationFn: async (workspaces: Workspace[]) => {
return Promise.all(workspaces.map((w) => deleteWorkspace(w.id)));
},
onSuccess,
onError: () => {
displayError("Failed to delete workspaces");
},
});

return {
startAll: startAllMutation.mutateAsync,
stopAll: stopAllMutation.mutateAsync,
deleteAll: deleteAllMutation.mutateAsync,
isLoading:
startAllMutation.isLoading ||
stopAllMutation.isLoading ||
deleteAllMutation.isLoading,
};
}
dayjs.extend(relativeTime);

type BatchDeleteConfirmationProps = {
checkedWorkspaces: Workspace[];
Expand Down Expand Up @@ -182,6 +129,8 @@ const Consequences: FC = () => {
};

const Workspaces: FC<StageProps> = ({ workspaces }) => {
const theme = useTheme();

const mostRecent = workspaces.reduce(
(latestSoFar, against) => {
if (!latestSoFar) {
Expand Down Expand Up @@ -209,7 +158,9 @@ const Workspaces: FC<StageProps> = ({ workspaces }) => {
alignItems="center"
justifyContent="space-between"
>
<span css={{ fontWeight: 500, color: "#fff" }}>
<span
css={{ fontWeight: 500, color: theme.experimental.l1.text }}
>
{workspace.name}
</span>
<Stack css={{ gap: 0, fontSize: 14, width: 128 }}>
Expand All @@ -234,7 +185,12 @@ const Workspaces: FC<StageProps> = ({ workspaces }) => {
</li>
))}
</ul>
<Stack justifyContent="center" direction="row" css={{ fontSize: 14 }}>
<Stack
justifyContent="center"
direction="row"
wrap="wrap"
css={{ gap: "6px 20px", fontSize: 14 }}
>
<Stack direction="row" alignItems="center" spacing={1}>
<PersonIcon />
<span>{ownersCount}</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { action } from "@storybook/addon-actions";
import type { Meta, StoryObj } from "@storybook/react";
import { useQueryClient } from "react-query";
import { chromatic } from "testHelpers/chromatic";
import {
MockWorkspace,
MockRunningOutdatedWorkspace,
MockDormantOutdatedWorkspace,
MockOutdatedWorkspace,
MockTemplateVersion,
MockUser2,
} from "testHelpers/entities";
import {
BatchUpdateConfirmation,
type Update,
} from "./BatchUpdateConfirmation";

const workspaces = [
{ ...MockRunningOutdatedWorkspace, id: "1" },
{ ...MockDormantOutdatedWorkspace, id: "2" },
{ ...MockOutdatedWorkspace, id: "3" },
{ ...MockOutdatedWorkspace, id: "4" },
{ ...MockWorkspace, id: "5" },
{
...MockRunningOutdatedWorkspace,
id: "6",
owner_id: MockUser2.id,
owner_name: MockUser2.username,
},
];

const updates = new Map<string, Update>();
for (const it of workspaces) {
const versionId = it.template_active_version_id;
const version = updates.get(versionId);

if (version) {
version.affected_workspaces.push(it);
continue;
}

updates.set(versionId, {
...MockTemplateVersion,
template_display_name: it.template_display_name,
affected_workspaces: [it],
});
}

const meta: Meta<typeof BatchUpdateConfirmation> = {
title: "pages/WorkspacesPage/BatchUpdateConfirmation",
parameters: { chromatic },
component: BatchUpdateConfirmation,
decorators: [
(Story) => {
const queryClient = useQueryClient();
for (const [id, it] of updates) {
queryClient.setQueryData(["batchUpdate", id], it);
}
return <Story />;
},
],
args: {
onClose: action("onClose"),
onConfirm: action("onConfirm"),
open: true,
checkedWorkspaces: workspaces,
},
};

export default meta;
type Story = StoryObj<typeof BatchUpdateConfirmation>;

const Example: Story = {};

export { Example as BatchUpdateConfirmation };
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy