import type { ReactView } from "@ethicdevs/react-monolith";
import React from "react";
import type { Pipeline, Stage } from "@prisma/client";
import type { CommonProps } from "../../types";
import { Layout } from "../../components/Layout";
import { PageWrapper } from "../../components/PageWrapper";
import { Grid } from "../../components/Grid";
import { Card } from "../../components/Card.styled";
import { Chip } from "../../components/Chip";
import { IslandWrapper } from "../../components/IslandWrapper.styled";
import { Colors, NamedColors } from "../../utils/style";
import { AppRoute } from "../../routes.defs";
import { buildRouteLink } from "../../utils/shared";
import Code from "../../islands/Code";
import RepositoryHero from "../../islands/RepositoryHero";
export interface PipelineDetailsViewProps extends CommonProps {
pipeline: Pipeline & { stages: Stage[] };
orgSlug: string;
repoSlug: string;
}
const PipelineDetailsView: ReactView<PipelineDetailsViewProps> = ({
commonProps,
pipeline,
orgSlug,
repoSlug,
}) => {
return (
<Layout
{...commonProps}
showDrawerPrimary
orgSlug={orgSlug}
repoSlug={repoSlug}
>
<PageWrapper style={{ gap: 16 }}>
<IslandWrapper
style={{ position: "sticky", top: 64 }}
data-islandid={`${RepositoryHero.name}$$0`}
>
<RepositoryHero
themeScheme={commonProps.themeScheme}
path={`Pipeline > #${pipeline.name ?? "Unknown"}`}
showForkButton={false}
showNewButton
newButtonText={"Download Artifacts"}
newButtonUrl={buildRouteLink(
AppRoute.REPOSITORY_PIPELINE_ARTEFACTS,
{
orgSlug: orgSlug,
repoSlug: repoSlug,
pipelineId: pipeline.id,
},
)}
parentOrg={{
id: "",
createdAt: new Date(Date.now()),
updatedAt: new Date(Date.now()),
slug: orgSlug,
ownerId: "",
kind: "PERSONAL",
visibility: "PUBLIC",
avatarUri: null,
displayName: orgSlug,
websiteUrl: null,
}}
repo={{
id: "",
forkedFromRepoId: null,
organizationId: "",
slug: repoSlug,
createdAt: new Date(Date.now()),
updatedAt: new Date(Date.now()),
lastPushedAt: null,
visibility: "PUBLIC",
isFork: false,
keywords: [],
avatarUri: null,
displayName: repoSlug,
shortDescription: null,
websiteUrl: null,
}}
/>
</IslandWrapper>
<Grid.Row fluid nowrap gap={8} alignItems={"center"}>
<Chip
themeScheme={commonProps.themeScheme}
color={
{
PENDING: Colors.PRIMARY_01,
RUNNING: Colors.CYAN_01,
PASSED: Colors.GREEN_01,
FAILED: Colors.RED_01,
CANCELED: Colors.BLACK_01,
}[pipeline.status]
}
>
{
{
PENDING: "Pending",
RUNNING: "Running",
PASSED: "Passed",
FAILED: "Failed",
CANCELED: "Canceled",
}[pipeline.status]
}
</Chip>
</Grid.Row>
<Grid.Row fluid gap={4} alignItems={"flex-start"}>
{pipeline.stages
.sort((a, b) => a.order - b.order)
.map((stage) => (
<Card
themeScheme={commonProps.themeScheme}
style={{ flex: 1, padding: 4 }}
>
<Grid.Col key={stage.id} fluid gap={4}>
<h3 style={{ margin: 0 }}>
<a
href={buildRouteLink(
AppRoute.REPOSITORY_PIPELINE_STAGE_DETAILS,
{
orgSlug,
repoSlug,
pipelineId: pipeline.id,
stageId: stage.id,
},
)}
>
{stage.name ?? stage.id}
</a>
</h3>
<Grid.Row fluid nowrap gap={4} alignItems={"center"}>
<div
style={{
fontSize: 11,
color: NamedColors.TEXT_MUTED[commonProps.themeScheme],
}}
>
#{stage.order}
</div>
<div
style={{
fontSize: 11,
color: NamedColors.TEXT_MUTED[commonProps.themeScheme],
}}
>
{stage.updatedAt.toLocaleString()}
</div>
</Grid.Row>
<Chip
themeScheme={commonProps.themeScheme}
color={
{
PENDING: Colors.PRIMARY_01,
RUNNING: Colors.CYAN_01,
PASSED: Colors.GREEN_01,
FAILED: Colors.RED_01,
CANCELED: Colors.BLACK_01,
}[stage.status]
}
>
{
{
PENDING: "Pending",
RUNNING: "Running",
PASSED: "Passed",
FAILED: "Failed",
CANCELED: "Canceled",
}[stage.status]
}
</Chip>
{}
</Grid.Col>
</Card>
))}
</Grid.Row>
{pipeline.manifest && (
<Grid.Col fluid nowrap gap={4}>
<IslandWrapper data-islandid={`${Code.name}$$0`}>
<Code
themeScheme={commonProps.themeScheme}
language={"shell"}
code={`${orgSlug}/${repoSlug}/.gitfoss.ci`}
whiteSpace={"pre-wrap"}
/>
</IslandWrapper>
<IslandWrapper data-islandid={`${Code.name}$$1`}>
<Code
themeScheme={commonProps.themeScheme}
language={"yaml"}
code={pipeline.manifest}
whiteSpace={"pre-wrap"}
/>
</IslandWrapper>
</Grid.Col>
)}
</PageWrapper>
</Layout>
);
};
PipelineDetailsView.displayName = "PipelineDetailsView";
export default PipelineDetailsView;