feat(journal): add ErrorPopup to display full error messages
Introduces an ErrorPopup component that allows users to view the complete error message by clicking on the truncated error text in the JournalInput.
This commit is contained in:
parent
841fbc7bae
commit
b8cfb05e53
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* ErrorPopup — shows the full error message in a floating panel above
|
||||||
|
* the journal input area. Toggled by clicking the truncated error text.
|
||||||
|
*/
|
||||||
|
import { Component, Show } from "solid-js";
|
||||||
|
|
||||||
|
interface ErrorPopupProps {
|
||||||
|
message: string | null;
|
||||||
|
show: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ErrorPopup: Component<ErrorPopupProps> = (props) => {
|
||||||
|
return (
|
||||||
|
<Show when={props.show && props.message}>
|
||||||
|
<div class="absolute bottom-full left-2 right-2 mb-1 bg-red-50 border border-red-200 rounded shadow-lg z-50">
|
||||||
|
<div class="flex items-start justify-between px-2 pt-2 pb-1">
|
||||||
|
<p class="text-red-700 text-xs break-words">{props.message}</p>
|
||||||
|
<button
|
||||||
|
onClick={props.onClose}
|
||||||
|
class="text-red-400 hover:text-red-600 text-xs leading-none ml-2 shrink-0"
|
||||||
|
title="关闭"
|
||||||
|
>
|
||||||
|
✕
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -26,6 +26,7 @@ import { parseInput } from "./command-parser";
|
||||||
import type { CompletionItem } from "./command-parser";
|
import type { CompletionItem } from "./command-parser";
|
||||||
import { buildCompletions } from "./command-completions";
|
import { buildCompletions } from "./command-completions";
|
||||||
import { CompletionsDropdown } from "./CompletionsDropdown";
|
import { CompletionsDropdown } from "./CompletionsDropdown";
|
||||||
|
import { ErrorPopup } from "./ErrorPopup";
|
||||||
|
|
||||||
// ---- Component ----
|
// ---- Component ----
|
||||||
|
|
||||||
|
|
@ -39,6 +40,7 @@ export const JournalInput: Component = () => {
|
||||||
|
|
||||||
const [text, setText] = createSignal("");
|
const [text, setText] = createSignal("");
|
||||||
const [error, setError] = createSignal<string | null>(null);
|
const [error, setError] = createSignal<string | null>(null);
|
||||||
|
const [showErrorPopup, setShowErrorPopup] = createSignal(false);
|
||||||
const [sending, setSending] = createSignal(false);
|
const [sending, setSending] = createSignal(false);
|
||||||
const [showCompletions, setShowCompletions] = createSignal(false);
|
const [showCompletions, setShowCompletions] = createSignal(false);
|
||||||
const [selectedIdx, setSelectedIdx] = createSignal(0);
|
const [selectedIdx, setSelectedIdx] = createSignal(0);
|
||||||
|
|
@ -406,7 +408,13 @@ export const JournalInput: Component = () => {
|
||||||
|
|
||||||
<div class="flex items-center justify-between px-2 pb-2">
|
<div class="flex items-center justify-between px-2 pb-2">
|
||||||
<Show when={error()}>
|
<Show when={error()}>
|
||||||
<p class="text-red-500 text-xs truncate max-w-[60%]">{error()}</p>
|
<button
|
||||||
|
onClick={() => setShowErrorPopup((v) => !v)}
|
||||||
|
class="text-red-500 text-xs truncate max-w-[60%] text-left hover:underline"
|
||||||
|
title={error() ?? undefined}
|
||||||
|
>
|
||||||
|
{error()}
|
||||||
|
</button>
|
||||||
</Show>
|
</Show>
|
||||||
<div class="flex items-center gap-1 ml-auto">
|
<div class="flex items-center gap-1 ml-auto">
|
||||||
<button
|
<button
|
||||||
|
|
@ -422,6 +430,13 @@ export const JournalInput: Component = () => {
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Error popup */}
|
||||||
|
<ErrorPopup
|
||||||
|
message={error()}
|
||||||
|
show={showErrorPopup()}
|
||||||
|
onClose={() => setShowErrorPopup(false)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue