Skip to content

Commit

Permalink
feat: add buildData to issueDetails
Browse files Browse the repository at this point in the history
Closes #705
  • Loading branch information
MarceloRobert committed Dec 23, 2024
1 parent f2b0018 commit 2f37bb0
Show file tree
Hide file tree
Showing 10 changed files with 304 additions and 10 deletions.
3 changes: 3 additions & 0 deletions backend/kernelCI_app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,7 @@ def viewCache(view):
path("issue/<str:issue_id>/version/<str:version>/tests",
viewCache(views.IssueDetailsTests),
name="issueDetailsTests"),
path("issue/<str:issue_id>/version/<str:version>/builds",
viewCache(views.IssueDetailsBuilds),
name="issueDetailsBuilds"),
]
60 changes: 60 additions & 0 deletions backend/kernelCI_app/views/issueDetailsBuildsView.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from typing import Dict, Optional
from django.http import HttpResponseBadRequest, HttpResponseNotFound, JsonResponse
from django.views import View
from kernelCI_app.models import Incidents
from kernelCI_app.utils import getErrorResponseBody


class IssueDetailsBuilds(View):
def _fetch_incidents(self, *, issue_id: str, version: int) -> Optional[Dict]:
fields = [
"build__id",
"build__architecture",
"build__config_name",
"build__valid",
"build__start_time",
"build__duration",
"build__compiler",
]

builds = Incidents.objects.filter(
issue_id=issue_id, issue_version=version
).values(*fields)

return [
{
"id": build["build__id"],
"architecture": build["build__architecture"],
"config_name": build["build__config_name"],
"valid": build["build__valid"],
"start_time": build["build__start_time"],
"duration": build["build__duration"],
"compiler": build["build__compiler"],
}
for build in builds
]

def get(self, _request, issue_id: Optional[str], version: Optional[str]):
missing_params = []
if issue_id is None:
missing_params.append("issue_id")
if version is None:
missing_params.append("version")
if len(missing_params) != 0:
return HttpResponseBadRequest(
getErrorResponseBody("Missing parameters: ", missing_params)
)

try:
parsed_version = int(version)
except ValueError:
return HttpResponseBadRequest(
getErrorResponseBody("Invalid version parameter, must be an integer")
)

builds_data = self._fetch_incidents(issue_id=issue_id, version=parsed_version)

if builds_data is None:
return HttpResponseNotFound(getErrorResponseBody("Builds not found"))

return JsonResponse(builds_data, safe=False)
53 changes: 53 additions & 0 deletions backend/requests/issue-details-builds-get.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
http http://localhost:8000/api/issue/maestro:f61865c29254c199ba015e5f48acfc070aff0eb0/version/0/builds

# HTTP/1.1 200 OK
# Cache-Control: max-age=0
# Content-Length: 872
# Content-Type: application/json
# Cross-Origin-Opener-Policy: same-origin
# Date: Mon, 23 Dec 2024 19:25:24 GMT
# Expires: Mon, 23 Dec 2024 19:25:24 GMT
# Referrer-Policy: same-origin
# Server: WSGIServer/0.2 CPython/3.12.7
# Vary: origin
# X-Content-Type-Options: nosniff
# X-Frame-Options: DENY

# [
# {
# "architecture": "arm",
# "compiler": "clang-17",
# "config_name": "imx_v6_v7_defconfig+allmodconfig",
# "duration": null,
# "id": "maestro:673fcc50923416c0c98dfea6",
# "start_time": "2024-11-22T00:12:00.124Z",
# "valid": false
# },
# {
# "architecture": "arm",
# "compiler": "clang-17",
# "config_name": "imx_v6_v7_defconfig+allmodconfig",
# "duration": null,
# "id": "maestro:67406b8c923416c0c98f75ad",
# "start_time": "2024-11-22T11:31:24.629Z",
# "valid": false
# },
# {
# "architecture": "arm",
# "compiler": "clang-17",
# "config_name": "imx_v6_v7_defconfig+allmodconfig",
# "duration": null,
# "id": "maestro:67409557923416c0c98fa534",
# "start_time": "2024-11-22T14:29:43.011Z",
# "valid": false
# },
# {
# "architecture": "arm",
# "compiler": "clang-17",
# "config_name": "imx_v6_v7_defconfig+allmodconfig",
# "duration": null,
# "id": "maestro:674079b4923416c0c98f79ba",
# "start_time": "2024-11-22T12:31:48.309Z",
# "valid": false
# }
# ]
23 changes: 22 additions & 1 deletion dashboard/src/api/issueDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useQuery } from '@tanstack/react-query';

import type { TIssueDetails } from '@/types/issueDetails';

import type { TestHistory } from '@/types/general';
import type { BuildsTableBuild, TestHistory } from '@/types/general';

import http from './api';

Expand Down Expand Up @@ -48,3 +48,24 @@ export const useIssueDetailsTests = (
queryFn: () => fetchIssueDetailsTests(issueId, versionNumber),
});
};

const fetchIssueDetailsBuilds = async (
issueId: string,
versionNumber: string,
): Promise<BuildsTableBuild[]> => {
const res = await http.get(
`/api/issue/${issueId}/version/${versionNumber}/builds`,
);

return res.data;
};

export const useIssueDetailsBuilds = (
issueId: string,
versionNumber: string,
): UseQueryResult<BuildsTableBuild[]> => {
return useQuery({
queryKey: ['issueBuildsData', issueId, versionNumber],
queryFn: () => fetchIssueDetailsBuilds(issueId, versionNumber),
});
};
21 changes: 20 additions & 1 deletion dashboard/src/components/IssueDetails/IssueDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,23 @@ import { getMiscSection } from '@/components/Section/MiscSection';

import { useIssueDetails } from '@/api/issueDetails';

import type { TableFilter, TestsTableFilter } from '@/types/tree/TreeDetails';
import type {
BuildsTableFilter,
TableFilter,
TestsTableFilter,
} from '@/types/tree/TreeDetails';

import { IssueDetailsTestSection } from './IssueDetailsTestSection';
import { IssueDetailsBuildSection } from './IssueDetailsBuildSection';

interface IIssueDetails {
issueId?: string;
versionNumber?: string;
tableFilter: TableFilter;
onClickTestFilter: (filter: TestsTableFilter) => void;
getTestTableRowLink: (testId: string) => LinkProps;
onClickBuildFilter: (filter: BuildsTableFilter) => void;
getBuildTableRowLink: (testId: string) => LinkProps;
}

export const IssueDetails = ({
Expand All @@ -34,13 +41,16 @@ export const IssueDetails = ({
tableFilter,
onClickTestFilter,
getTestTableRowLink,
onClickBuildFilter,
getBuildTableRowLink,
}: IIssueDetails): JSX.Element => {
const { data, error, isLoading } = useIssueDetails(
issueId ?? '',
versionNumber ?? '',
);

const hasTest = data && data.test_status !== null;
const hasBuild = data && data.build_valid !== null;

const { formatMessage } = useIntl();

Expand Down Expand Up @@ -162,6 +172,15 @@ export const IssueDetails = ({
onClickFilter={onClickTestFilter}
/>
)}
{hasBuild && (
<IssueDetailsBuildSection
issueId={issueId}
versionNumber={versionNumber}
buildTableFilter={tableFilter.buildsTable}
getTableRowLink={getBuildTableRowLink}
onClickFilter={onClickBuildFilter}
/>
)}
</ErrorBoundary>
);
};
73 changes: 73 additions & 0 deletions dashboard/src/components/IssueDetails/IssueDetailsBuildSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import type { LinkProps } from '@tanstack/react-router';

import { useIntl } from 'react-intl';

import { useMemo } from 'react';

import { Separator } from '@/components/ui/separator';
import { MemoizedSectionError } from '@/components/DetailsPages/SectionError';
import type {
AccordionItemBuilds,
BuildsTableFilter,
TableFilter,
} from '@/types/tree/TreeDetails';

import { useIssueDetailsBuilds } from '@/api/issueDetails';

import { BuildsTable } from '@/components/BuildsTable/BuildsTable';
import { sanitizeBuildTable } from '@/utils/utils';

interface IIssueDetailsBuildSection {
issueId?: string;
versionNumber?: string;
buildTableFilter: TableFilter['buildsTable'];
onClickFilter: (filter: BuildsTableFilter) => void;
getTableRowLink: (testId: string) => LinkProps;
}

export const IssueDetailsBuildSection = ({
issueId,
versionNumber,
buildTableFilter,
onClickFilter,
getTableRowLink,
}: IIssueDetailsBuildSection): JSX.Element => {
const { data, error, isLoading } = useIssueDetailsBuilds(
issueId ?? '',
versionNumber ?? '',
);

const { formatMessage } = useIntl();

const buildData = useMemo((): AccordionItemBuilds[] => {
if (!data) {
return [];
}
return sanitizeBuildTable(data);
}, [data]);

return (
<>
<h2 className="text-2xl font-bold">
{formatMessage({ id: 'global.builds' })}
</h2>
<Separator className="my-6 bg-darkGray" />
{data ? (
<div className="flex flex-col gap-6">
<BuildsTable
tableKey="issueDetailsBuilds"
buildItems={buildData}
filter={buildTableFilter}
getRowLink={getTableRowLink}
onClickFilter={onClickFilter}
/>
</div>
) : (
<MemoizedSectionError
isLoading={isLoading}
errorMessage={error?.message}
/>
)}
</>
);
};
37 changes: 34 additions & 3 deletions dashboard/src/pages/IssueDetails/IssueDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { useNavigate, useParams, useSearch } from '@tanstack/react-router';
import { useCallback } from 'react';

import { IssueDetails } from '@/components/IssueDetails/IssueDetails';
import {
zTableFilterInfoDefault,
type TestsTableFilter,
import type {
BuildsTableFilter,
TestsTableFilter,
} from '@/types/tree/TreeDetails';
import { zTableFilterInfoDefault } from '@/types/tree/TreeDetails';

const CURRENT_ROUTE = '/issue/$issueId/version/$versionNumber';

Expand Down Expand Up @@ -44,13 +45,43 @@ const IssueDetailsPage = (): JSX.Element => {
[navigate],
);

const getBuildTableRowLink = useCallback(
(buildId: string): LinkProps => ({
to: '/build/$buildId',
params: {
buildId: buildId,
},
search: s => s,
}),
[],
);

const onClickBuildFilter = useCallback(
(filter: BuildsTableFilter): void => {
navigate({
search: previousParams => {
return {
...previousParams,
tableFilter: {
...(previousParams.tableFilter ?? zTableFilterInfoDefault),
buildsTable: filter,
},
};
},
});
},
[navigate],
);

return (
<IssueDetails
issueId={issueId}
versionNumber={versionNumber}
tableFilter={searchParams.tableFilter ?? zTableFilterInfoDefault}
onClickTestFilter={onClickTestFilter}
getTestTableRowLink={getTestTableRowLink}
onClickBuildFilter={onClickBuildFilter}
getBuildTableRowLink={getBuildTableRowLink}
/>
);
};
Expand Down
11 changes: 11 additions & 0 deletions dashboard/src/types/general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ export type BuildsTabBuild = {
tree_index?: number;
};

export type BuildsTableBuild = Pick<
BuildsTabBuild,
| 'id'
| 'architecture'
| 'config_name'
| 'valid'
| 'start_time'
| 'duration'
| 'compiler'
>;

export type BuildStatus = {
valid: number;
invalid: number;
Expand Down
3 changes: 2 additions & 1 deletion dashboard/src/utils/constants/tables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export type TableKeys =
| 'hardwareDetailsTests'
| 'hardwareDetailsTrees'
| 'buildDetailsTests'
| 'issueDetailsTests';
| 'issueDetailsTests'
| 'issueDetailsBuilds';
Loading

0 comments on commit 2f37bb0

Please sign in to comment.