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
8 changes: 4 additions & 4 deletions gui/src/components/native-main-profiles-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export function NativeMainProfilesView({
</form>
</>}
{action && s && <div ref={confirmationRef} role="group" tabIndex={-1} aria-labelledby={`${id}-confirm-title`}
className="notice notice-warn" style={{ marginTop: 12 }}
className="notice notice-warn" style={{ marginTop: 12, display: "block" }}
onKeyDown={event => {
if (event.key === "Escape" && !busy) { event.preventDefault(); onSelect(null); }
}}>
Expand All @@ -131,9 +131,9 @@ export function NativeMainProfilesView({
<input id={`${id}-stopped`} type="checkbox" checked={confirmedStopped}
disabled={mutationDisabled} onChange={event => onStopped(event.target.checked)} /> {t("nativeMain.stopped")}
</label></p>
<div className="row">
<button type="button" className="btn btn-sm" disabled={busy} onClick={() => onSelect(null)}>{t("nativeMain.cancel")}</button>
<button type="button" className="btn btn-sm btn-primary" disabled={mutationDisabled || !confirmedStopped || !canApplyNativeMain(s, action)}
<div className="row" style={{ flexWrap: "wrap" }}>
<button type="button" className="btn btn-sm" style={{ whiteSpace: "normal", overflowWrap: "anywhere", maxWidth: "100%" }} disabled={busy} onClick={() => onSelect(null)}>{t("nativeMain.cancel")}</button>
<button type="button" className="btn btn-sm btn-primary" style={{ whiteSpace: "normal", overflowWrap: "anywhere", maxWidth: "100%" }} disabled={mutationDisabled || !confirmedStopped || !canApplyNativeMain(s, action)}
onClick={onConfirm}>{t("nativeMain.confirm")}</button>
</div>
</div>}
Expand Down
45 changes: 45 additions & 0 deletions gui/tests/native-main-confirmation-layout.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { expect, test } from "bun:test";
import { Window } from "happy-dom";
import { renderToStaticMarkup } from "react-dom/server";
import { NativeMainProfilesView, type NativeMainProfilesViewProps } from "../src/components/native-main-profiles-view";
import { nativeMainTranslator } from "../src/i18n/native-main-copy";

const home = `/srv/${"long-home-segment/".repeat(12)}.codex`;
const profile = { id: "00000000-0000-4000-8000-000000000001", label: "example-profile", identityHint: "native:11111111", state: "inactive" as const };
const noop = () => {};
const props: NativeMainProfilesViewProps = {
t: nativeMainTranslator("de"), id: "fixture", open: true, busy: false, blocked: false,
snapshot: {
list: { effectiveCodexHome: home, activeProfileId: null, profiles: [profile] },
doctor: { effectiveCodexHome: home, activeProfileId: null, supported: true,
authStatus: "ok", keyStore: "available", vaultStatus: "ok", recoveryPending: false },
},
label: "", action: { kind: "switch", target: profile.id, label: profile.label },
confirmedStopped: false, previousId: null, error: null, result: null, refreshFailed: false,
onToggle: noop, onRefresh: noop, onLabel: noop, onRegister: noop, onSelect: noop,
onStopped: noop, onConfirm: noop,
};
const css = (await Bun.file(new URL("../src/styles.css", import.meta.url)).text()).replace(/^@import .*;$/gm, "");

test("native confirmation overrides the shared horizontal notice and permits wrapped actions", async () => {
const window = new Window();
try {
window.document.head.innerHTML = `<style>${css}</style>`;
window.document.body.innerHTML = renderToStaticMarkup(<NativeMainProfilesView {...props} />);
const panel = window.document.querySelector<HTMLElement>('[role="group"]')!;
// happy-dom checks the cascade, not browser geometry. Inherited notice flex
// previously put heading, prose, path, consent and actions in one narrow row.
expect(window.getComputedStyle(panel).display).toBe("block");
expect(panel.querySelector("code")?.textContent).toBe(home);
expect(window.getComputedStyle(panel.querySelector(".row")!).flexWrap).toBe("wrap");
for (const button of panel.querySelectorAll<HTMLButtonElement>("button")) {
const style = window.getComputedStyle(button);
expect(style.whiteSpace).toBe("normal");
expect(style.maxWidth).toBe("100%");
expect(style.overflowWrap).toBe("anywhere");
}
expect(panel.querySelector<HTMLButtonElement>(".btn-primary")!.disabled).toBe(true);
} finally {
await window.happyDOM.close();
}
});
Loading