feat(admission): add group VPN exceptions
CI / validate (push) Successful in 5m45s
Release / release (push) Successful in 7m21s

This commit is contained in:
dmg
2026-08-02 10:16:16 -04:00
parent 24808b0f8c
commit 71856bb869
34 changed files with 1820 additions and 138 deletions
@@ -0,0 +1,21 @@
import { renderToStaticMarkup } from "react-dom/server";
import { describe, expect, it } from "vitest";
import { UserGroupSelect } from "./user-group-select";
describe("UserGroupSelect", () => {
it("renders the effective group and preserves the active search", () => {
const markup = renderToStaticMarkup(<UserGroupSelect
action={async () => undefined}
effectiveGroupId="group-ops"
groups={[{ id: "group-everyone", name: "everyone" }, { id: "group-ops", name: "Ops" }]}
search="alex smith"
userId="user-one"
userLabel="Alex"
/>);
expect(markup).toContain('aria-label="Group for Alex"');
expect(markup).toContain('<option value="group-ops" selected="">Ops</option>');
expect(markup).toContain('<input type="hidden" name="search" value="alex smith"/>');
expect(markup).toContain("Apply group");
});
});
@@ -0,0 +1,60 @@
"use client";
import { useFormStatus } from "react-dom";
export function UserGroupSelect({
action,
effectiveGroupId,
groups,
search,
userId,
userLabel,
}: {
action: (formData: FormData) => Promise<void>;
effectiveGroupId: string;
groups: Array<{ id: string; name: string }>;
search: string;
userId: string;
userLabel: string;
}) {
const helpId = `group-help-${userId}`;
return (
<form action={action} className="flex items-center gap-2">
<input name="userId" type="hidden" value={userId} />
<input name="search" type="hidden" value={search} />
<span className="sr-only" id={helpId}>Changing this selection applies the group immediately.</span>
<GroupSelectControl effectiveGroupId={effectiveGroupId} groups={groups} helpId={helpId} userLabel={userLabel} />
</form>
);
}
function GroupSelectControl({
effectiveGroupId,
groups,
helpId,
userLabel,
}: {
effectiveGroupId: string;
groups: Array<{ id: string; name: string }>;
helpId: string;
userLabel: string;
}) {
const { pending } = useFormStatus();
return (
<>
<select
aria-describedby={helpId}
aria-label={`Group for ${userLabel}`}
className="max-w-44 border border-line bg-canvas px-3 py-2 font-mono text-xs outline-none focus:border-accent disabled:cursor-wait disabled:opacity-60"
defaultValue={effectiveGroupId}
disabled={pending}
name="groupId"
onChange={(event) => event.currentTarget.form?.requestSubmit()}
>
{groups.map((group) => <option key={group.id} value={group.id}>{group.name}</option>)}
</select>
<span aria-live="polite" className="sr-only">{pending ? "Updating group." : ""}</span>
<button className="sr-only focus:not-sr-only" disabled={pending} type="submit">Apply group</button>
</>
);
}