Skip to content

Commit

Permalink
Add Koji tagging requests
Browse files Browse the repository at this point in the history
Signed-off-by: Nikola Forró <[email protected]>
  • Loading branch information
nforro committed Nov 25, 2024
1 parent bf6b2dd commit 8b02289
Show file tree
Hide file tree
Showing 11 changed files with 511 additions and 0 deletions.
45 changes: 45 additions & 0 deletions frontend/src/apiDefinitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,51 @@ export interface KojiBuild {
web_url: string;
}

// /api/koji-tag-requests
export interface KojiTagRequestGroup {
branch_name: string | null;
tag_request_submitted_time: number;
chroot: string;
sidetag: string;
nvr: string;
packit_id: number;
// TODO: @Venefilyn - change interface depending on status of pr_id or branch_item.
// They seem to be mutually exclusive so can be sure one is null and other is string
pr_id: number | null;
project_url: string;
release: string | null;
repo_name: string;
repo_namespace: string;
task_id: string | null;
web_url: string;
}

// /api/koji-tag-requests/$id
export interface KojiTagRequest {
anitya_package: string | null;
anitya_project_id: number | null;
anitya_project_name: string | null;
anitya_version: string | null;
branch_name: string | null;
tag_request_submitted_time: number;
chroot: string;
sidetag: string;
nvr: string;
commit_sha: string;
issue_id: number | null;
non_git_upstream: boolean;
// TODO: @Venefilyn - change interface depending on status of pr_id or branch_item.
// They seem to be mutually exclusive so can be sure one is null and other is string
pr_id: number | null;
project_url: string;
release: string | null;
repo_name: string;
repo_namespace: string;
run_ids: number[];
task_id: string;
web_url: string;
}

// /api/srpm-builds
export interface SRPMBuildGroup {
branch_name: string | null;
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/components/jobs/Jobs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ const Jobs = () => {
<NavItem isActive={!!matchRoute(jobTypeObject("openscanhub"))}>
<Link {...jobTypeObject("openscanhub")}>OpenScanHub</Link>
</NavItem>
<NavItem isActive={!!matchRoute(jobTypeObject("koji-tag-requests"))}>
<Link {...jobTypeObject("koji-tag-requests")}>
Koji Tagging Requests
</Link>
</NavItem>
</NavList>
</Nav>
<PageSection hasBodyWrapper={false}>
Expand Down
133 changes: 133 additions & 0 deletions frontend/src/components/koji/KojiTagRequest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// Copyright Contributors to the Packit project.
// SPDX-License-Identifier: MIT

import {
Card,
CardBody,
Content,
DescriptionList,
DescriptionListDescription,
DescriptionListGroup,
DescriptionListTerm,
Label,
PageSection,
Title,
} from "@patternfly/react-core";
import { Table, Tbody, Td, Tr } from "@patternfly/react-table";
import { useQuery } from "@tanstack/react-query";
import { Link } from "@tanstack/react-router";
import { kojiTagRequestQueryOptions } from "../../queries/koji/kojiTagRequestQuery";
import { Route as KojiRoute } from "../../routes/jobs_/koji-tag-request.$id";
import { ErrorConnection } from "../errors/ErrorConnection";
import { LabelLink } from "../shared/LabelLink";
import { Preloader } from "../shared/Preloader";
import { SHACopy } from "../shared/SHACopy";
import { Timestamp } from "../shared/Timestamp";
import { StatusLabel } from "../statusLabels/StatusLabel";
import { TriggerLink, TriggerSuffix } from "../trigger/TriggerLink";

export const KojiTagRequest = () => {
const { id } = KojiRoute.useParams();
const { data, isLoading, isError } = useQuery(
kojiTagRequestQueryOptions({ id }),
);

// If backend API is down
if (isError) {
return <ErrorConnection />;
}

// Show preloader if waiting for API data
if (isLoading || data === undefined) {
return <Preloader />;
}

if ("error" in data) {
return (
<PageSection hasBodyWrapper={false}>
<Card>
<CardBody>
<Title headingLevel="h1" size="lg">
Not Found.
</Title>
</CardBody>
</Card>
</PageSection>
);
}
return (
<>
<PageSection hasBodyWrapper={false}>
<Content>
<Content component="h1">Koji Tagging Request Results</Content>
<strong>
<TriggerLink trigger={data}>
<TriggerSuffix trigger={data} />
</TriggerLink>
<SHACopy
project_url={data.project_url}
commit_sha={data.commit_sha}
/>
</strong>
<br />
</Content>
</PageSection>

<PageSection hasBodyWrapper={false}>
<Card>
<CardBody>
<DescriptionList
columnModifier={{
default: "1Col",
sm: "2Col",
}}
>
<DescriptionListGroup>
<DescriptionListTerm>Koji Tagging Request</DescriptionListTerm>
<DescriptionListDescription>
<StatusLabel
target={data.chroot}
status="unknown"
link={data.web_url}
/>
</DescriptionListDescription>
<DescriptionListTerm>Sidetag</DescriptionListTerm>
<DescriptionListDescription>
<strong>
<a
href={`https://koji.fedoraproject.org/koji/search?match=exact&type=tag&terms=${data.sidetag}`}
target="_blank"
rel="noreferrer"
>
{data.sidetag}
</a>
</strong>
</DescriptionListDescription>
<DescriptionListTerm>NVR</DescriptionListTerm>
<DescriptionListDescription>
<strong>
<a
href={`https://koji.fedoraproject.org/koji/search?match=exact&type=build&terms=${data.nvr}`}
target="_blank"
rel="noreferrer"
>
{data.nvr}
</a>
</strong>
</DescriptionListDescription>
</DescriptionListGroup>
<DescriptionListGroup>
<DescriptionListTerm>
Koji tagging request submitted
</DescriptionListTerm>
<DescriptionListDescription>
{<Timestamp stamp={data.tag_request_submitted_time} />}
</DescriptionListDescription>
</DescriptionListGroup>
</DescriptionList>
</CardBody>
</Card>
</PageSection>
</>
);
};
155 changes: 155 additions & 0 deletions frontend/src/components/koji/KojiTagRequestsTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// Copyright Contributors to the Packit project.
// SPDX-License-Identifier: MIT

import React, { useMemo } from "react";

import {
Table,
TableVariant,
Tbody,
Td,
Th,
Thead,
Tr,
} from "@patternfly/react-table";

import { SkeletonTable } from "@patternfly/react-component-groups";
import { useInfiniteQuery } from "@tanstack/react-query";
import { Timestamp } from "../../components/shared/Timestamp";
import {
TriggerLink,
TriggerSuffix,
} from "../../components/trigger/TriggerLink";
import { kojiTagRequestsQueryOptions } from "../../queries/koji/kojiTagRequestsQuery";
import { ForgeIcon } from "../icons/ForgeIcon";
import { LoadMore } from "../shared/LoadMore";
import { StatusLabel } from "../statusLabels/StatusLabel";

export const KojiTagRequestsTable = () => {
// Headings
const columnNames = {
forge: "Forge",
trigger: "Trigger",
target: "Target",
sidetag: "Sidetag",
nvr: "NVR",
timeSubmitted: "Time Submitted",
kojiTagRequestTask: "Koji Tagging Request Task",
};

const { data, isLoading, isFetchingNextPage, hasNextPage, fetchNextPage } =
useInfiniteQuery(kojiTagRequestsQueryOptions());

// Create a memoization of all the data when we flatten it out. Ideally one should render all the pages separately so that rendering will be done faster
const rows = useMemo(() => (data ? data.pages.flat() : []), [data]);

const TableHeads = [
<Th key={columnNames.forge}>
<span className="pf-v6-u-screen-reader">{columnNames.forge}</span>
</Th>,
<Th key={columnNames.trigger} width={20}>
{columnNames.trigger}
</Th>,
<Th key={columnNames.target} width={15}>
{columnNames.target}
</Th>,
<Th key={columnNames.sidetag} width={15}>
{columnNames.sidetag}
</Th>,
<Th key={columnNames.nvr} width={15}>
{columnNames.nvr}
</Th>,
<Th key={columnNames.timeSubmitted} width={15}>
{columnNames.timeSubmitted}
</Th>,
<Th key={columnNames.kojiTagRequestTask} width={15}>
{columnNames.kojiTagRequestTask}
</Th>,
];

if (isLoading) {
return (
<SkeletonTable
variant={TableVariant.compact}
rows={10}
columns={TableHeads}
/>
);
}

return (
<>
<Table aria-label="Koji tagging requests" variant={TableVariant.compact}>
<Thead>
<Tr>{TableHeads}</Tr>
</Thead>
<Tbody>
{rows.map((koji_tag_request) => (
<Tr key={koji_tag_request.packit_id}>
<Td dataLabel={columnNames.forge}>
<ForgeIcon url={koji_tag_request.project_url} />
</Td>
<Td dataLabel={columnNames.trigger}>
<strong>
<TriggerLink trigger={koji_tag_request}>
<TriggerSuffix trigger={koji_tag_request} />
</TriggerLink>
</strong>
</Td>
<Td dataLabel={columnNames.target}>
<StatusLabel
target={koji_tag_request.chroot}
status="unknown"
link={`/jobs/koji-tag-request/${koji_tag_request.packit_id}`}
/>
</Td>
<Td dataLabel={columnNames.sidetag}>
<strong>
<a
href={`https://koji.fedoraproject.org/koji/search?match=exact&type=tag&terms=${koji_tag_request.sidetag}`}
target="_blank"
rel="noreferrer"
>
{koji_tag_request.sidetag}
</a>
</strong>
</Td>
<Td dataLabel={columnNames.nvr}>
<strong>
<a
href={`https://koji.fedoraproject.org/koji/search?match=exact&type=build&terms=${koji_tag_request.nvr}`}
target="_blank"
rel="noreferrer"
>
{koji_tag_request.nvr}
</a>
</strong>
</Td>
<Td dataLabel={columnNames.timeSubmitted}>
<Timestamp
stamp={koji_tag_request.tag_request_submitted_time}
/>
</Td>
<Td dataLabel={columnNames.kojiTagRequestTask}>
<strong>
<a
href={koji_tag_request.web_url}
target="_blank"
rel="noreferrer"
>
{koji_tag_request.task_id}
</a>
</strong>
</Td>
</Tr>
))}
</Tbody>
</Table>
<LoadMore
isFetchingNextPage={isFetchingNextPage}
hasNextPage={hasNextPage}
fetchNextPage={() => void fetchNextPage()}
/>
</>
);
};
28 changes: 28 additions & 0 deletions frontend/src/queries/koji/kojiTagRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright Contributors to the Packit project.
// SPDX-License-Identifier: MIT

import { KojiTagRequest } from "../../apiDefinitions";

export interface fetchKojiTagRequestProps {
id: string;
signal?: AbortSignal;
}

// Fetch data from dashboard backend (or if we want, directly from the API)
export const fetchKojiTagRequest = async ({
id,
signal,
}: fetchKojiTagRequestProps): Promise<KojiTagRequest> => {
const data = await fetch(
`${import.meta.env.VITE_API_URL}/koji-tag-requests/${id}`,
{ signal },
)
.then((response) => response.json())
.catch((err) => {
if (err.status === 404) {
throw new Error(`Koji tagging request ${id} not found!`);
}
throw err;
});
return data;
};
Loading

0 comments on commit 8b02289

Please sign in to comment.