-
+
setExpanded(open ? null : id)}
+ onKeyDown={(e) => {
+ if (e.key === "Enter" || e.key === " ") {
+ e.preventDefault();
+ setExpanded(open ? null : id);
+ }
+ }}
+ role="button"
+ tabIndex={0}
+ aria-expanded={open}
>
{item.namespace} |
{item.key} |
diff --git a/packages/web/src/pages/ProfilesPage.jsx b/packages/web/src/pages/ProfilesPage.jsx
index 01b1d00..0fb4314 100644
--- a/packages/web/src/pages/ProfilesPage.jsx
+++ b/packages/web/src/pages/ProfilesPage.jsx
@@ -3,6 +3,8 @@ import { useLocation, useNavigate, useParams, useSearchParams } from "react-rout
import { LuPencil, LuPlus, LuTrash2 } from "react-icons/lu";
import { errorMessage } from "../api/client.js";
import { useDeleteProfile, useOwners, useProfileUsage, useProfiles } from "../api/hooks.js";
+import { FormSelect } from "../components/FormControls.jsx";
+import { Modal } from "../components/Modal.jsx";
import { ProfileEditorModal } from "../components/ProfileEditorModal.jsx";
import { ScriptIcon } from "../components/ScriptIcon.jsx";
import { formatTime } from "../lib/format.jsx";
@@ -129,8 +131,7 @@ export function ProfilesPage() {
Profiles
-
+
);
}
diff --git a/packages/web/src/pages/ScriptsPage.jsx b/packages/web/src/pages/ScriptsPage.jsx
index a53c358..b7268b1 100644
--- a/packages/web/src/pages/ScriptsPage.jsx
+++ b/packages/web/src/pages/ScriptsPage.jsx
@@ -8,6 +8,7 @@ import {
useInstallPlugin,
useScripts,
} from "../api/hooks.js";
+import { ConfirmDialog } from "../components/ConfirmDialog.jsx";
import { ScriptIcon } from "../components/ScriptIcon.jsx";
import { TagBadge } from "../components/TagBadge.jsx";
import { scriptTags } from "../lib/script.js";
@@ -156,6 +157,7 @@ export function ScriptsPage() {
type="button"
className="btn btn-ghost btn-xs"
title="Dry run"
+ aria-label="Dry run"
onClick={() =>
navigate(`/scripts/${encodeURIComponent(name)}/dry-run`)
}
@@ -167,6 +169,7 @@ export function ScriptsPage() {
type="button"
className="btn btn-ghost btn-xs"
title="Fork"
+ aria-label="Fork"
onClick={() => {
setForkFor(name);
setForkId(
@@ -183,6 +186,7 @@ export function ScriptsPage() {
to={`/scripts/${encodeURIComponent(name)}/edit`}
className="btn btn-ghost btn-xs"
title="Edit"
+ aria-label="Edit"
>
@@ -192,6 +196,7 @@ export function ScriptsPage() {
type="button"
className="btn btn-ghost btn-xs text-error"
title="Delete"
+ aria-label="Delete"
onClick={() => setConfirmDelete(name)}
>
@@ -259,43 +264,19 @@ export function ScriptsPage() {
) : null}
- {confirmDelete ? (
-
- ) : null}
+
setConfirmDelete(null)}
+ onConfirm={() =>
+ del.mutate(confirmDelete, {
+ onSuccess: () => setConfirmDelete(null),
+ })
+ }
+ />
);
}
diff --git a/packages/web/src/pages/SecretsPage.jsx b/packages/web/src/pages/SecretsPage.jsx
index 2442948..5333ead 100644
--- a/packages/web/src/pages/SecretsPage.jsx
+++ b/packages/web/src/pages/SecretsPage.jsx
@@ -3,6 +3,8 @@ import { useLocation, useNavigate, useParams, useSearchParams } from "react-rout
import { LuPencil, LuPlus, LuTrash2 } from "react-icons/lu";
import { errorMessage } from "../api/client.js";
import { useDeleteSecret, useOwners, useSecrets } from "../api/hooks.js";
+import { ConfirmDialog } from "../components/ConfirmDialog.jsx";
+import { FormSelect } from "../components/FormControls.jsx";
import { SecretEditorModal } from "../components/SecretEditorModal.jsx";
import { formatTime } from "../lib/format.jsx";
@@ -81,8 +83,7 @@ export function SecretsPage() {
Secrets
-
+
navigate(
`/secrets/${encodeURIComponent(s.owner)}/${encodeURIComponent(s.name)}/edit`,
@@ -166,6 +168,7 @@ export function SecretsPage() {
type="button"
className="btn btn-ghost btn-xs text-error"
title="Delete"
+ aria-label="Delete"
onClick={() => setConfirmDelete(s)}
>
@@ -190,41 +193,17 @@ export function SecretsPage() {
/>
) : null}
- {confirmDelete ? (
-
- ) : null}
+ setConfirmDelete(null)}
+ onConfirm={() =>
+ del.mutate(confirmDelete.id, { onSuccess: () => setConfirmDelete(null) })
+ }
+ />
);
}
diff --git a/packages/web/src/pages/UsersPage.jsx b/packages/web/src/pages/UsersPage.jsx
index 179f74b..114ddb7 100644
--- a/packages/web/src/pages/UsersPage.jsx
+++ b/packages/web/src/pages/UsersPage.jsx
@@ -3,6 +3,7 @@ import { useLocation, useNavigate, useParams } from "react-router-dom";
import { LuPencil, LuPlus, LuTrash2 } from "react-icons/lu";
import { errorMessage } from "../api/client.js";
import { useDeleteUser, useUsers } from "../api/hooks.js";
+import { ConfirmDialog } from "../components/ConfirmDialog.jsx";
import { UserEditorModal } from "../components/UserEditorModal.jsx";
export function UsersPage() {
@@ -88,6 +89,7 @@ export function UsersPage() {
type="button"
className="btn btn-ghost btn-xs"
title="Edit"
+ aria-label="Edit"
onClick={() =>
navigate(`/users/${encodeURIComponent(u.username)}/edit`)
}
@@ -98,6 +100,7 @@ export function UsersPage() {
type="button"
className="btn btn-ghost btn-xs text-error"
title="Delete"
+ aria-label="Delete"
onClick={() => setConfirmDelete(u)}
>
@@ -118,36 +121,16 @@ export function UsersPage() {
/>
) : null}
- {confirmDelete ? (
-
- ) : null}
+
setConfirmDelete(null)}
+ onConfirm={() =>
+ del.mutate(confirmDelete.id, { onSuccess: () => setConfirmDelete(null) })
+ }
+ />
);
}
diff --git a/packages/web/src/pages/VariablesPage.jsx b/packages/web/src/pages/VariablesPage.jsx
index b4488a1..48b5bf5 100644
--- a/packages/web/src/pages/VariablesPage.jsx
+++ b/packages/web/src/pages/VariablesPage.jsx
@@ -3,6 +3,8 @@ import { useLocation, useNavigate, useParams, useSearchParams } from "react-rout
import { LuPencil, LuPlus, LuTrash2 } from "react-icons/lu";
import { errorMessage } from "../api/client.js";
import { useDeleteVariable, useOwners, useVariables } from "../api/hooks.js";
+import { ConfirmDialog } from "../components/ConfirmDialog.jsx";
+import { FormSelect } from "../components/FormControls.jsx";
import { VariableEditorModal } from "../components/VariableEditorModal.jsx";
import { formatTime } from "../lib/format.jsx";
@@ -110,8 +112,7 @@ export function VariablesPage() {
Variables
-
+
navigate(
`/variables/${encodeURIComponent(row.owner)}/${encodeURIComponent(row.name)}/edit`,
@@ -204,6 +206,7 @@ export function VariablesPage() {
type="button"
className="btn btn-ghost btn-xs text-error"
title="Delete"
+ aria-label="Delete"
onClick={() => setConfirmDelete(row)}
>
@@ -228,41 +231,21 @@ export function VariablesPage() {
/>
) : null}
- {confirmDelete ? (
-
- ) : null}
+ setConfirmDelete(null)}
+ onConfirm={() =>
+ del.mutate(confirmDelete.id, { onSuccess: () => setConfirmDelete(null) })
+ }
+ />
);
}
diff --git a/packages/web/src/pages/WorkflowEditPage.jsx b/packages/web/src/pages/WorkflowEditPage.jsx
index 8b56cd2..efb6849 100644
--- a/packages/web/src/pages/WorkflowEditPage.jsx
+++ b/packages/web/src/pages/WorkflowEditPage.jsx
@@ -20,10 +20,8 @@ import {
saveErrorMessage,
saveWarningsFromError,
} from "../components/workflow/SaveWorkflowWarningsDialog.jsx";
-import {
- ConfirmDialog,
- WorkflowRevisionBanner,
-} from "../components/workflow/WorkflowRevisionBanner.jsx";
+import { ConfirmDialog } from "../components/ConfirmDialog.jsx";
+import { WorkflowRevisionBanner } from "../components/workflow/WorkflowRevisionBanner.jsx";
import { NEW_WORKFLOW_YAML, parseWorkflowYaml } from "../lib/workflow-doc.js";
import { useNotifications } from "../notifications.jsx";
@@ -465,6 +463,7 @@ export function WorkflowEditPage() {
title="Discard unsaved changes?"
message="You have unsaved edits. Switching versions will discard them."
confirmLabel="Discard"
+ confirmClass="btn-warning"
pending={false}
onCancel={() => setDiscardConfirm(null)}
onConfirm={() => {
diff --git a/packages/web/src/pages/WorkflowTrashPage.jsx b/packages/web/src/pages/WorkflowTrashPage.jsx
index f56d1a4..2d83ebb 100644
--- a/packages/web/src/pages/WorkflowTrashPage.jsx
+++ b/packages/web/src/pages/WorkflowTrashPage.jsx
@@ -7,6 +7,7 @@ import {
useRestoreWorkflowTrash,
useWorkflowTrash,
} from "../api/hooks.js";
+import { ConfirmDialog } from "../components/ConfirmDialog.jsx";
import { formatTime } from "../lib/format.jsx";
import { useNotifications } from "../notifications.jsx";
@@ -87,6 +88,7 @@ export function WorkflowTrashPage() {
type="button"
className="btn btn-ghost btn-xs"
title="Restore"
+ aria-label="Restore"
disabled={restore.isPending}
onClick={() =>
restore.mutate(item.id, {
@@ -105,6 +107,7 @@ export function WorkflowTrashPage() {
type="button"
className="btn btn-ghost btn-xs text-error"
title="Delete permanently"
+ aria-label="Delete permanently"
onClick={() => setConfirmPurge(item)}
>
@@ -117,46 +120,26 @@ export function WorkflowTrashPage() {
)}
- {confirmPurge ? (
-
- ) : null}
+
setConfirmPurge(null)}
+ onConfirm={() =>
+ purge.mutate(confirmPurge.id, {
+ onSuccess: () => {
+ notify.success("Permanently deleted");
+ setConfirmPurge(null);
+ },
+ })
+ }
+ />
);
}
diff --git a/packages/web/src/pages/WorkflowsPage.jsx b/packages/web/src/pages/WorkflowsPage.jsx
index 2d04983..6c3f01c 100644
--- a/packages/web/src/pages/WorkflowsPage.jsx
+++ b/packages/web/src/pages/WorkflowsPage.jsx
@@ -10,6 +10,7 @@ import {
useWorkflows,
} from "../api/hooks.js";
import { DuplicateWorkflowDialog } from "../components/DuplicateWorkflowDialog.jsx";
+import { ConfirmDialog } from "../components/ConfirmDialog.jsx";
import { WorkflowFileIcon } from "../components/WorkflowFileIcon.jsx";
import { formatTime, WorkflowStatusBadge } from "../lib/format.jsx";
@@ -80,6 +81,7 @@ export function WorkflowsPage() {
type="button"
className="btn btn-ghost btn-sm"
title="Reregister workflows"
+ aria-label="Reregister workflows"
disabled={reregister.isPending}
onClick={() => reregister.mutate()}
>
@@ -153,7 +155,11 @@ export function WorkflowsPage() {