| author | |
| committer | |
| log | 6088c8104cfda0c11eafd1e1f636d47106fee136 |
| tree | 293f7a31f5e53fc3b00da30fe4fcf469c3e0ed15 |
| parent | a1390ac655927cda10cfab3e4678d456db7b54b8 |
| signature | Signed by PGP key B5690EEEBB952194 |
3 files changed, 53 insertions(+), 66 deletions(-)
apps/web/src/components/settings/DiagnosticsSettings.tsx+3-48| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | import { ProcessSignalActions } from "./ProcessSignalActions"; | ||
| 1 | import { RefreshIcon } from "~/components/ui/refresh-icon"; | 2 | import { RefreshIcon } from "~/components/ui/refresh-icon"; |
| 2 | import { | 3 | import { |
| 3 | AlertTriangleIcon, | 4 | AlertTriangleIcon, |
| ... | @@ -309,51 +310,6 @@ function ProcessNameCell({ | ... | @@ -309,51 +310,6 @@ function ProcessNameCell({ |
| 309 | ); | 310 | ); |
| 310 | } | 311 | } |
| 311 | 312 | ||
| 312 | function ProcessSignalActions({ | ||
| 313 | process, | ||
| 314 | isSignaling, | ||
| 315 | onSignal, | ||
| 316 | }: { | ||
| 317 | process: ServerProcessDiagnosticsEntry; | ||
| 318 | isSignaling: boolean; | ||
| 319 | onSignal: (pid: number, signal: ServerProcessSignal) => void; | ||
| 320 | }) { | ||
| 321 | return ( | ||
| 322 | <div className="flex items-center justify-end gap-1.5"> | ||
| 323 | <Tooltip> | ||
| 324 | <TooltipTrigger | ||
| 325 | render={ | ||
| 326 | <button | ||
| 327 | type="button" | ||
| 328 | disabled={isSignaling} | ||
| 329 | className="cursor-pointer text-[11px] font-medium text-muted-foreground underline-offset-2 hover:text-foreground hover:underline disabled:pointer-events-none disabled:opacity-50" | ||
| 330 | onClick={() => onSignal(process.pid, "SIGINT")} | ||
| 331 | > | ||
| 332 | INT | ||
| 333 | </button> | ||
| 334 | } | ||
| 335 | /> | ||
| 336 | <TooltipPopup side="top">Send SIGINT</TooltipPopup> | ||
| 337 | </Tooltip> | ||
| 338 | <Tooltip> | ||
| 339 | <TooltipTrigger | ||
| 340 | render={ | ||
| 341 | <button | ||
| 342 | type="button" | ||
| 343 | disabled={isSignaling} | ||
| 344 | className="cursor-pointer text-[11px] font-medium text-destructive underline-offset-2 hover:underline disabled:pointer-events-none disabled:opacity-50" | ||
| 345 | onClick={() => onSignal(process.pid, "SIGKILL")} | ||
| 346 | > | ||
| 347 | KILL | ||
| 348 | </button> | ||
| 349 | } | ||
| 350 | /> | ||
| 351 | <TooltipPopup side="top">Send SIGKILL</TooltipPopup> | ||
| 352 | </Tooltip> | ||
| 353 | </div> | ||
| 354 | ); | ||
| 355 | } | ||
| 356 | |||
| 357 | function ProcessDiagnosticsTable({ | 313 | function ProcessDiagnosticsTable({ |
| 358 | processes, | 314 | processes, |
| 359 | signalingPid, | 315 | signalingPid, |
| ... | @@ -469,9 +425,8 @@ function ProcessDiagnosticsTable({ | ... | @@ -469,9 +425,8 @@ function ProcessDiagnosticsTable({ |
| 469 | </td> | 425 | </td> |
| 470 | <td className="p-2 align-middle sm:pr-4"> | 426 | <td className="p-2 align-middle sm:pr-4"> |
| 471 | <ProcessSignalActions | 427 | <ProcessSignalActions |
| 472 | process={process} | 428 | disabled={signalingPid === process.pid} |
| 473 | isSignaling={signalingPid === process.pid} | 429 | onSignal={(signal) => onSignal(process.pid, signal)} |
| 474 | onSignal={onSignal} | ||
| 475 | /> | 430 | /> |
| 476 | </td> | 431 | </td> |
| 477 | </tr> | 432 | </tr> |
apps/web/src/components/settings/ProcessSignalActions.tsx created+48| ... | @@ -0,0 +1,48 @@ | ||
| 1 | import type { ServerProcessSignal } from "@t3tools/contracts"; | ||
| 2 | |||
| 3 | import { InlineButton } from "../ui/button"; | ||
| 4 | import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; | ||
| 5 | |||
| 6 | /** Process ownership and confirmation stay with the diagnostics view. */ | ||
| 7 | export function ProcessSignalActions({ | ||
| 8 | disabled, | ||
| 9 | onSignal, | ||
| 10 | }: { | ||
| 11 | disabled: boolean; | ||
| 12 | onSignal: (signal: ServerProcessSignal) => void; | ||
| 13 | }) { | ||
| 14 | return ( | ||
| 15 | <div className="flex items-center justify-end gap-1.5"> | ||
| 16 | <Tooltip> | ||
| 17 | <TooltipTrigger | ||
| 18 | render={ | ||
| 19 | <InlineButton | ||
| 20 | disabled={disabled} | ||
| 21 | aria-label="Send SIGINT" | ||
| 22 | className="text-[11px] font-medium text-muted-foreground underline-offset-2 hover:text-foreground hover:underline" | ||
| 23 | onClick={() => onSignal("SIGINT")} | ||
| 24 | > | ||
| 25 | INT | ||
| 26 | </InlineButton> | ||
| 27 | } | ||
| 28 | /> | ||
| 29 | <TooltipPopup side="top">Send SIGINT</TooltipPopup> | ||
| 30 | </Tooltip> | ||
| 31 | <Tooltip> | ||
| 32 | <TooltipTrigger | ||
| 33 | render={ | ||
| 34 | <InlineButton | ||
| 35 | disabled={disabled} | ||
| 36 | aria-label="Send SIGKILL" | ||
| 37 | className="text-[11px] font-medium text-destructive underline-offset-2 hover:underline" | ||
| 38 | onClick={() => onSignal("SIGKILL")} | ||
| 39 | > | ||
| 40 | KILL | ||
| 41 | </InlineButton> | ||
| 42 | } | ||
| 43 | /> | ||
| 44 | <TooltipPopup side="top">Send SIGKILL</TooltipPopup> | ||
| 45 | </Tooltip> | ||
| 46 | </div> | ||
| 47 | ); | ||
| 48 | } | ||
apps/web/src/components/settings/ResourceTelemetryDiagnostics.tsx+2-18| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | import { ProcessSignalActions } from "./ProcessSignalActions"; | ||
| 1 | import { RefreshIcon } from "~/components/ui/refresh-icon"; | 2 | import { RefreshIcon } from "~/components/ui/refresh-icon"; |
| 2 | import { | 3 | import { |
| 3 | ActivityIcon, | 4 | ActivityIcon, |
| ... | @@ -535,24 +536,7 @@ function ProcessActions({ | ... | @@ -535,24 +536,7 @@ function ProcessActions({ |
| 535 | } | 536 | } |
| 536 | const isSignaling = signalingKeys.has(processIdentityKey(process)); | 537 | const isSignaling = signalingKeys.has(processIdentityKey(process)); |
| 537 | return ( | 538 | return ( |
| 538 | <div className="flex items-center justify-end gap-1.5"> | 539 | <ProcessSignalActions disabled={isSignaling} onSignal={(signal) => onSignal(process, signal)} /> |
| 539 | <button | ||
| 540 | type="button" | ||
| 541 | disabled={isSignaling} | ||
| 542 | className="cursor-pointer text-[10px] font-semibold text-muted-foreground hover:text-foreground disabled:opacity-50" | ||
| 543 | onClick={() => onSignal(process, "SIGINT")} | ||
| 544 | > | ||
| 545 | INT | ||
| 546 | </button> | ||
| 547 | <button | ||
| 548 | type="button" | ||
| 549 | disabled={isSignaling} | ||
| 550 | className="cursor-pointer text-[10px] font-semibold text-destructive hover:underline disabled:opacity-50" | ||
| 551 | onClick={() => onSignal(process, "SIGKILL")} | ||
| 552 | > | ||
| 553 | KILL | ||
| 554 | </button> | ||
| 555 | </div> | ||
| 556 | ); | 540 | ); |
| 557 | } | 541 | } |
| 558 | 542 |