2026-03-01 13:54:48 +08:00
|
|
|
import { type Component, For, Show } from "solid-js";
|
2026-02-28 16:28:07 +08:00
|
|
|
import type { CommanderEntry } from "./types";
|
|
|
|
|
import { getResultClass } from "./hooks";
|
|
|
|
|
|
|
|
|
|
export interface CommanderEntriesProps {
|
|
|
|
|
entries: () => CommanderEntry[];
|
2026-02-28 16:49:02 +08:00
|
|
|
onCommandClick?: (command: string) => void;
|
2026-03-01 13:54:48 +08:00
|
|
|
loading?: boolean;
|
|
|
|
|
error?: string;
|
2026-02-28 16:28:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const CommanderEntries: Component<CommanderEntriesProps> = (props) => {
|
2026-02-28 16:49:02 +08:00
|
|
|
let containerRef: HTMLDivElement | undefined;
|
|
|
|
|
|
|
|
|
|
const handleCommandClick = (command: string) => {
|
|
|
|
|
if (props.onCommandClick) {
|
|
|
|
|
props.onCommandClick(command);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-02-28 16:28:07 +08:00
|
|
|
return (
|
2026-02-28 16:49:02 +08:00
|
|
|
<div
|
|
|
|
|
ref={containerRef}
|
|
|
|
|
class="commander-entries flex-1 overflow-auto p-3 bg-white space-y-2"
|
|
|
|
|
>
|
2026-02-28 16:28:07 +08:00
|
|
|
<Show
|
2026-03-01 13:54:48 +08:00
|
|
|
when={props.loading}
|
2026-02-28 16:28:07 +08:00
|
|
|
fallback={
|
2026-03-01 13:54:48 +08:00
|
|
|
<Show
|
|
|
|
|
when={props.error}
|
|
|
|
|
fallback={
|
|
|
|
|
<Show
|
|
|
|
|
when={props.entries().length > 0}
|
|
|
|
|
fallback={
|
|
|
|
|
<div class="text-gray-400 text-center py-8">暂无命令执行记录</div>
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
<For each={props.entries()}>
|
|
|
|
|
{(entry) => (
|
|
|
|
|
<div class="border-l-2 border-gray-300 pl-3 py-1">
|
|
|
|
|
<div class="flex items-center justify-between text-xs text-gray-500 mb-1">
|
|
|
|
|
<span
|
|
|
|
|
class="font-mono cursor-pointer hover:text-blue-600 hover:underline"
|
|
|
|
|
onClick={() => handleCommandClick(entry.command)}
|
|
|
|
|
title="点击复制到输入框"
|
|
|
|
|
>
|
|
|
|
|
{entry.command}
|
|
|
|
|
</span>
|
|
|
|
|
<span>
|
|
|
|
|
{entry.timestamp.toLocaleTimeString()}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class={`text-sm whitespace-pre-wrap ${getResultClass(entry.result.type)}`}
|
|
|
|
|
innerHTML={entry.result.isHtml ? entry.result.message : undefined}
|
|
|
|
|
>
|
|
|
|
|
{!entry.result.isHtml && entry.result.message}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</For>
|
|
|
|
|
</Show>
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
<div class="text-red-500 text-center py-8">{props.error}</div>
|
|
|
|
|
</Show>
|
2026-02-28 16:28:07 +08:00
|
|
|
}
|
|
|
|
|
>
|
2026-03-01 13:54:48 +08:00
|
|
|
<div class="flex items-center justify-center h-full">
|
|
|
|
|
<div class="text-gray-500 flex items-center gap-2">
|
|
|
|
|
<div class="animate-spin rounded-full h-5 w-5 border-b-2 border-blue-600"></div>
|
|
|
|
|
<span>加载命令模板中...</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-02-28 16:28:07 +08:00
|
|
|
</Show>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|