| 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 | import { ProcessSignalActions } from "./ProcessSignalActions"; | |
| 1 | 2 | import { RefreshIcon } from "~/components/ui/refresh-icon"; |
| 2 | 3 | import { |
| 3 | 4 | AlertTriangleIcon, |
| ... | ... | @@ -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 | 313 | function ProcessDiagnosticsTable({ |
| 358 | 314 | processes, |
| 359 | 315 | signalingPid, |
| ... | ... | @@ -469,9 +425,8 @@ function ProcessDiagnosticsTable({ |
| 469 | 425 | </td> |
| 470 | 426 | <td className="p-2 align-middle sm:pr-4"> |
| 471 | 427 | <ProcessSignalActions |
| 472 | process={process} | |
| 473 | isSignaling={signalingPid === process.pid} | |
| 474 | onSignal={onSignal} | |
| 428 | disabled={signalingPid === process.pid} | |
| 429 | onSignal={(signal) => onSignal(process.pid, signal)} | |
| 475 | 430 | /> |
| 476 | 431 | </td> |
| 477 | 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 | import { ProcessSignalActions } from "./ProcessSignalActions"; | |
| 1 | 2 | import { RefreshIcon } from "~/components/ui/refresh-icon"; |
| 2 | 3 | import { |
| 3 | 4 | ActivityIcon, |
| ... | ... | @@ -535,24 +536,7 @@ function ProcessActions({ |
| 535 | 536 | } |
| 536 | 537 | const isSignaling = signalingKeys.has(processIdentityKey(process)); |
| 537 | 538 | return ( |
| 538 | <div className="flex items-center justify-end gap-1.5"> | |
| 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> | |
| 539 | <ProcessSignalActions disabled={isSignaling} onSignal={(signal) => onSignal(process, signal)} /> | |
| 556 | 540 | ); |
| 557 | 541 | } |
| 558 | 542 |