fix(webui): keep DataGrid actions out of form submission

This commit is contained in:
2026-07-20 17:58:32 +02:00
parent 1678602fd6
commit 9b5418db78
4 changed files with 39 additions and 0 deletions

View File

@@ -22,6 +22,7 @@
"preview": "vite preview --host 127.0.0.1 --port 4173",
"audit:i18n-structural": "node scripts/audit-i18n-structural.mjs",
"test:file-drop-zone": "rm -rf .file-drop-test-build && mkdir -p .file-drop-test-build && printf '{\"type\":\"commonjs\"}\\n' > .file-drop-test-build/package.json && tsc -p tsconfig.file-drop-tests.json && node .file-drop-test-build/tests/file-drop-resolver.test.js && node scripts/test-file-drop-zone-structure.mjs",
"test:data-grid-actions": "rm -rf .component-test-build && mkdir -p .component-test-build && printf '{\"type\":\"commonjs\"}\\n' > .component-test-build/package.json && tsc -p tsconfig.component-tests.json && node .component-test-build/tests/data-grid-actions.test.js",
"test:module-capabilities": "rm -rf .module-test-build && mkdir -p .module-test-build && printf '{\"type\":\"commonjs\"}\n' > .module-test-build/package.json && tsc -p tsconfig.module-tests.json && node .module-test-build/tests/module-capabilities.test.js && node .module-test-build/tests/privacy-policy.test.js",
"test:module-permutations": "node scripts/test-module-permutations.mjs",
"test:mail-components": "rm -rf .component-test-build && mkdir -p .component-test-build && printf '{\"type\":\"commonjs\"}\\n' > .component-test-build/package.json && tsc -p tsconfig.component-tests.json && node .component-test-build/tests/mail-components.test.js"

View File

@@ -860,6 +860,7 @@ export function DataGridRowActions({
return (
<div className="data-grid-row-actions">
<Button
type="button"
variant="primary"
className="data-grid-row-action is-add"
aria-label={translatedAddLabel}
@@ -870,6 +871,7 @@ export function DataGridRowActions({
<Plus size={16} aria-hidden="true" />
</Button>
<Button
type="button"
variant="secondary"
className="data-grid-row-action is-reorder"
aria-label={translatedMoveUpLabel}
@@ -880,6 +882,7 @@ export function DataGridRowActions({
<ArrowUp size={16} aria-hidden="true" />
</Button>
<Button
type="button"
variant="secondary"
className="data-grid-row-action is-reorder"
aria-label={translatedMoveDownLabel}
@@ -890,6 +893,7 @@ export function DataGridRowActions({
<ArrowDown size={16} aria-hidden="true" />
</Button>
<Button
type="button"
variant="danger"
className="data-grid-row-action is-remove"
aria-label={translatedRemoveLabel}
@@ -917,6 +921,7 @@ export function DataGridEmptyAction({
return (
<div className="data-grid-row-actions data-grid-empty-row-actions">
<Button
type="button"
variant="primary"
className="data-grid-row-action is-add"
aria-label={translatedLabel}

View File

@@ -0,0 +1,32 @@
function assertEqual<T>(actual: T, expected: T, message: string): void {
if (actual !== expected) throw new Error(`${message}: expected ${String(expected)}, got ${String(actual)}`);
}
import { renderToStaticMarkup } from "react-dom/server";
import { DataGridEmptyAction, DataGridRowActions } from "../src/components/table/DataGrid";
function noop() {}
function buttonCount(markup: string): number {
return markup.match(/<button\b/g)?.length ?? 0;
}
function nonSubmittingButtonCount(markup: string): number {
return markup.match(/<button\b[^>]*\btype="button"/g)?.length ?? 0;
}
const rowActions = renderToStaticMarkup(
<form>
<DataGridRowActions onAddBelow={noop} onRemove={noop} onMoveUp={noop} onMoveDown={noop} />
</form>
);
assertEqual(buttonCount(rowActions), 4, "row actions render the expected controls");
assertEqual(nonSubmittingButtonCount(rowActions), 4, "row actions do not submit an enclosing form");
const emptyAction = renderToStaticMarkup(
<form>
<DataGridEmptyAction onAdd={noop} />
</form>
);
assertEqual(buttonCount(emptyAction), 1, "empty action renders the expected control");
assertEqual(nonSubmittingButtonCount(emptyAction), 1, "empty action does not submit an enclosing form");

View File

@@ -18,6 +18,7 @@
"jsx": "react-jsx"
},
"include": [
"tests/data-grid-actions.test.tsx",
"tests/mail-components.test.tsx",
"src/components/CredentialPanel.tsx",
"src/components/email/EmailAddressInput.tsx",