diff --git a/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicenseCard.test.tsx b/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicenseCard.test.tsx
index 09737c1e98..294ec59a41 100644
--- a/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicenseCard.test.tsx
+++ b/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicenseCard.test.tsx
@@ -1,6 +1,6 @@
import { MockLicenseResponse } from "testHelpers/entities";
import { render } from "testHelpers/renderHelpers";
-import { screen } from "@testing-library/react";
+import { screen, within } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { LicenseCard } from "./LicenseCard";
@@ -56,7 +56,8 @@ describe("LicenseCard", () => {
const removeButton = await screen.findByRole("button", { name: /remove/i });
await user.click(removeButton);
- await screen.findByText(/This license has already expired/);
+ const dialog = await screen.findByTestId("dialog");
+ expect(dialog).toHaveTextContent(/This license has already expired/);
});
it("shows disabling features warning for active licenses", async () => {
@@ -106,4 +107,40 @@ describe("LicenseCard", () => {
// Then
await screen.findByText("1 / 3");
});
+
+ it("requires typing the license ID before allowing removal", async () => {
+ const user = userEvent.setup();
+ const onRemove = vi.fn();
+ const license = MockLicenseResponse[0];
+
+ render(
+ ,
+ );
+
+ await user.click(screen.getByRole("button", { name: /remove/i }));
+
+ const dialog = await screen.findByTestId("dialog");
+ const dialogScope = within(dialog);
+ const confirmButton = dialogScope.getByRole("button", { name: "Remove" });
+ expect(confirmButton).toBeDisabled();
+
+ const confirmationInput = dialogScope.getByTestId(
+ "delete-dialog-name-confirmation",
+ );
+ await user.type(confirmationInput, "wrong");
+ expect(confirmButton).toBeDisabled();
+
+ await user.clear(confirmationInput);
+ await user.type(confirmationInput, String(license.id));
+ expect(confirmButton).toBeEnabled();
+
+ await user.click(confirmButton);
+ expect(onRemove).toHaveBeenCalledWith(license.id);
+ });
});
diff --git a/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicenseCard.tsx b/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicenseCard.tsx
index 9f93de7368..169fe25328 100644
--- a/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicenseCard.tsx
+++ b/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicenseCard.tsx
@@ -1,6 +1,6 @@
import type { GetLicensesResponse } from "api/api";
import { Button } from "components/Button/Button";
-import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog";
+import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog";
import { Pill } from "components/Pill/Pill";
import dayjs from "dayjs";
import { type FC, useState } from "react";
@@ -25,6 +25,7 @@ export const LicenseCard: FC = ({
>(undefined);
const currentUserLimit = license.claims.features.user_limit || userLimitLimit;
+ const confirmationName = licenseIDMarkedForRemoval?.toString() ?? "";
const isExpired = dayjs
.unix(license.claims.license_expires)
@@ -41,26 +42,27 @@ export const LicenseCard: FC = ({
key={license.id}
className="license-card rounded-lg border border-solid border-border bg-surface-secondary p-4 text-sm shadow-sm"
>
- {
- if (!licenseIDMarkedForRemoval) {
- return;
- }
+ if (!licenseIDMarkedForRemoval) return;
onRemove(licenseIDMarkedForRemoval);
setLicenseIDMarkedForRemoval(undefined);
}}
- onClose={() => setLicenseIDMarkedForRemoval(undefined)}
- title="Confirm License Removal"
- confirmLoading={isRemoving}
+ onCancel={() => setLicenseIDMarkedForRemoval(undefined)}
+ entity="license"
+ name={confirmationName}
+ label="ID of the license to remove"
+ title="Confirm license removal"
+ verb="Removing"
confirmText="Remove"
- description={
+ info={
isExpired
? "This license has already expired and is not providing any features. Removing it will not affect your current entitlements."
: "Removing this license will disable all Premium features. You can add a new license at any time."
}
+ confirmLoading={isRemoving}
/>