|
1 | 1 | import { useEffect, useMemo, useRef, useState } from "react"; |
2 | 2 | import { Activity, ArrowLeft, Box, CheckCircle2, FileText, GitCommitHorizontal, ImageIcon, Network, RotateCw, ShieldAlert, Skull, Star, TerminalSquare } from "lucide-react"; |
| 3 | +import { containerCurrentState, containerLastState, currentStateTime, lastStateTime } from "../lib/podLifecycle"; |
3 | 4 | import { matchesSelector, ownsPod, referencesResource, workloadKinds } from "../lib/resourceRelationships"; |
4 | 5 | import type { ContainerDetails, HealthState, PodActionResult, PodCondition, ResourceDetails, ResourceRow } from "../types/kube"; |
5 | 6 | import { PodEventRail } from "./PodEventRail"; |
6 | 7 | import { PodIssueStrip } from "./PodIssueStrip"; |
| 8 | +import { PodLifecycleRail } from "./PodLifecycleRail"; |
7 | 9 | import { PodLinkStrip } from "./PodLinkStrip"; |
8 | 10 | import { PodPlacementStrip } from "./PodPlacementStrip"; |
9 | 11 | import { PodTerminal, type LogMode } from "./PodTerminal"; |
@@ -115,6 +117,7 @@ export function ResourceDetail({ |
115 | 117 | <> |
116 | 118 | <PodIssueStrip details={details} resource={resource} onOpenPreviousLogs={() => openLogs("previous")} /> |
117 | 119 | <PodStatusPanel details={details} resource={resource} /> |
| 120 | + <PodLifecycleRail details={details} /> |
118 | 121 | <PodPlacementStrip pod={details.pod} /> |
119 | 122 | <PodLinkStrip |
120 | 123 | allResources={allResources} |
@@ -502,59 +505,6 @@ function ContainerStateFact({ |
502 | 505 | ); |
503 | 506 | } |
504 | 507 |
|
505 | | -function containerCurrentState(container: ContainerDetails) { |
506 | | - const parts = [ |
507 | | - container.state, |
508 | | - container.reason, |
509 | | - container.exitCode == null ? "" : `exit ${container.exitCode}`, |
510 | | - ].filter(Boolean); |
511 | | - |
512 | | - return parts.join(" / "); |
513 | | -} |
514 | | - |
515 | | -function containerLastState(container: ContainerDetails) { |
516 | | - const parts = [ |
517 | | - container.lastReason, |
518 | | - container.lastExitCode == null ? "" : `exit ${container.lastExitCode}`, |
519 | | - ].filter(Boolean); |
520 | | - |
521 | | - return parts.join(" / "); |
522 | | -} |
523 | | - |
524 | | -function currentStateTime(container: ContainerDetails) { |
525 | | - if (container.startedAt) { |
526 | | - return `since ${formatLifecycleTime(container.startedAt)}`; |
527 | | - } |
528 | | - if (container.finishedAt) { |
529 | | - return `ended ${formatLifecycleTime(container.finishedAt)}`; |
530 | | - } |
531 | | - return ""; |
532 | | -} |
533 | | - |
534 | | -function lastStateTime(container: ContainerDetails) { |
535 | | - if (container.lastFinishedAt) { |
536 | | - return `ended ${formatLifecycleTime(container.lastFinishedAt)}`; |
537 | | - } |
538 | | - if (container.lastStartedAt) { |
539 | | - return `started ${formatLifecycleTime(container.lastStartedAt)}`; |
540 | | - } |
541 | | - return ""; |
542 | | -} |
543 | | - |
544 | | -function formatLifecycleTime(value: string) { |
545 | | - const timestamp = Date.parse(value); |
546 | | - if (Number.isNaN(timestamp)) { |
547 | | - return value.replace("T", " ").replace("Z", ""); |
548 | | - } |
549 | | - |
550 | | - return new Intl.DateTimeFormat(undefined, { |
551 | | - month: "short", |
552 | | - day: "numeric", |
553 | | - hour: "2-digit", |
554 | | - minute: "2-digit", |
555 | | - }).format(timestamp); |
556 | | -} |
557 | | - |
558 | 508 | function ActionResult({ |
559 | 509 | onConfirm, |
560 | 510 | resource, |
|
0 commit comments