From 96f6aeddf7593e8eba8a8ac96d8ab9d8e340ee71 Mon Sep 17 00:00:00 2001 From: Mariana Sartorato Date: Thu, 18 Jul 2024 12:41:51 -0300 Subject: [PATCH] feat(#72): add build status table to tree details --- .../Accordion/Accordion.stories.tsx | 98 ------------------- .../src/components/Accordion/Accordion.tsx | 25 +++-- .../src/components/Table/BuildsTable.tsx | 28 ------ .../Tabs/TreeDetails/TreeDetailsBuildTab.tsx | 80 ++++++++++++--- dashboard/src/locales/messages/index.ts | 10 +- .../src/routes/TreeDetails/TreeDetails.tsx | 2 +- 6 files changed, 95 insertions(+), 148 deletions(-) delete mode 100644 dashboard/src/components/Accordion/Accordion.stories.tsx delete mode 100644 dashboard/src/components/Table/BuildsTable.tsx diff --git a/dashboard/src/components/Accordion/Accordion.stories.tsx b/dashboard/src/components/Accordion/Accordion.stories.tsx deleted file mode 100644 index ef8ebec..0000000 --- a/dashboard/src/components/Accordion/Accordion.stories.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; - -import Accordion, { IAccordionItems } from './Accordion'; - -const meta = { - title: 'Accordion', - component: Accordion, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -const itemsBuild: IAccordionItems[] = [ - { - trigger: { - config: 'config', - compiler: 'compiler', - date: 'dd/mm/yyyy', - buildErrors: 5, - buildTime: '500 seconds', - status: 'valid', - }, - content: AAAAa, - }, - { - trigger: { - config: 'config', - compiler: 'compiler', - date: 'dd/mm/yyyy', - buildErrors: 5, - buildTime: '500 seconds', - status: 'valid', - }, - content: AAAAa, - }, - { - trigger: { - config: 'config', - compiler: 'compiler', - date: 'dd/mm/yyyy', - buildErrors: 5, - buildTime: '500 seconds', - status: 'valid', - }, - content: AAAAa, - }, -]; - -const headersBuild = [ - 'config', - 'compiler', - 'date', - 'build errors', - 'build time', - 'status', -]; - -const itemsTest: IAccordionItems[] = [ - { - trigger: { - testPlans: 'aaaaaaa', - testErrors: 5, - testSuccessfull: 12, - status: 'invalid', - }, - content: AAAAa, - }, - { - trigger: { - testPlans: 'aaaaaaasdkjmla', - testErrors: 5, - testSuccessfull: 12, - status: 'valid', - }, - content: BBB, - }, -]; -const headersTest = ['test plan', 'test results', 'status']; - -export const Builds: Story = { - args: { - items: itemsBuild, - headers: headersBuild, - type: 'build', - }, -}; - -export const Tests: Story = { - args: { - items: itemsTest, - headers: headersTest, - type: 'test', - }, -}; diff --git a/dashboard/src/components/Accordion/Accordion.tsx b/dashboard/src/components/Accordion/Accordion.tsx index 1193964..6114ecc 100644 --- a/dashboard/src/components/Accordion/Accordion.tsx +++ b/dashboard/src/components/Accordion/Accordion.tsx @@ -1,7 +1,9 @@ -import { ReactNode, useMemo } from 'react'; +import { ReactElement, ReactNode, useMemo } from 'react'; import { MdCheck, MdClose } from 'react-icons/md'; +import { FormattedMessage } from 'react-intl'; + import { TableBody, TableCell, TableRow } from '../ui/table'; import BaseTable from '../Table/BaseTable'; import { @@ -13,7 +15,7 @@ import ColoredCircle from '../ColoredCircle/ColoredCircle'; import { ItemType } from '../ListingItem/ListingItem'; export interface IAccordion { - headers: string[]; + headers?: ReactElement[]; items: IAccordionItems[]; type: 'build' | 'test'; } @@ -44,11 +46,20 @@ export type AccordionItemTestsTrigger = { status?: 'valid' | 'invalid'; }; -const Accordion = ({ headers, items, type }: IAccordion): JSX.Element => { - const accordionTableHeader = useMemo( - () => headers.map(header => {header}), - [headers], - ); +const headersBuilds = [ + , + , + , + , + , + , +]; + +const Accordion = ({ items, type }: IAccordion): JSX.Element => { + const accordionTableHeader = type === 'build' ? headersBuilds : []; return ( { - return ( -
- {buildsData && ( - - )} -
- ); -}; - -export default BuildsTable; diff --git a/dashboard/src/components/Tabs/TreeDetails/TreeDetailsBuildTab.tsx b/dashboard/src/components/Tabs/TreeDetails/TreeDetailsBuildTab.tsx index 8e9c416..6459b0c 100644 --- a/dashboard/src/components/Tabs/TreeDetails/TreeDetailsBuildTab.tsx +++ b/dashboard/src/components/Tabs/TreeDetails/TreeDetailsBuildTab.tsx @@ -1,13 +1,16 @@ import { FormattedMessage } from 'react-intl'; -import { useMemo } from 'react'; +import { useCallback, useMemo, useState } from 'react'; import CardsGroup from '@/components/CardsGroup/CardsGroup'; -import { Colors } from '@/components/StatusChart/StatusCharts'; +import { Colors, IStatusChart } from '@/components/StatusChart/StatusCharts'; import { ITreeDetails } from '@/routes/TreeDetails/TreeDetails'; -import BuildsTable from '@/components/Table/BuildsTable'; import { TableInfo } from '@/components/Table/TableInfo'; import { usePagination } from '@/hooks/usePagination'; +import Accordion from '@/components/Accordion/Accordion'; +import { Button } from '@/components/ui/button'; +import { IListingContent } from '@/components/ListingContent/ListingContent'; +import { ISummary } from '@/components/Summary/Summary'; interface ITreeDetailsBuildTab { treeDetailsData?: ITreeDetails; @@ -16,19 +19,42 @@ interface ITreeDetailsBuildTab { const TreeDetailsBuildTab = ({ treeDetailsData, }: ITreeDetailsBuildTab): JSX.Element => { + const [filterBy, setFilterBy] = useState<'error' | 'success' | 'all'>('all'); const accordionContent = useMemo(() => { return treeDetailsData?.builds.map(row => ({ trigger: { ...row, - buildTime: `${row.buildTime?.split('.')[0]} ${()}`, - date: row.date?.split(' ')[0], + config: row.config ?? '-', + compiler: row.compiler ?? '-', + buildTime: row.buildTime ? ( + + {typeof row.buildTime === 'number' + ? Math.floor(row.buildTime) + ' ' + : row.buildTime} + + + ) : ( + '-' + ), + date: row.date?.split('T')[0], }, content: <>, })); }, [treeDetailsData?.builds]); + const filteredContent = + filterBy === 'error' + ? accordionContent?.filter( + row => row.trigger.buildErrors && row.trigger.buildErrors > 0, + ) + : filterBy === 'success' + ? accordionContent?.filter( + row => row.trigger.status && row.trigger.status === 'valid', + ) + : accordionContent; + const { startIndex, endIndex, onClickGoForward, onClickGoBack } = - usePagination(accordionContent?.length ?? 0, ITEMS_PER_PAGE); + usePagination(filteredContent?.length ?? 0, ITEMS_PER_PAGE); const cards = useMemo( () => [ { @@ -57,12 +83,12 @@ const TreeDetailsBuildTab = ({ color: Colors.Gray, }, ], - }, + } as IStatusChart, { items: treeDetailsData?.configs ?? [], title: , type: 'listing', - }, + } as IListingContent, { summaryBody: treeDetailsData?.archs ?? [], title: , @@ -74,7 +100,7 @@ const TreeDetailsBuildTab = ({ />, ], type: 'summary', - }, + } as ISummary, ], [ treeDetailsData?.archs, @@ -85,15 +111,42 @@ const TreeDetailsBuildTab = ({ ], ); + const onClickFilter = useCallback((type: 'error' | 'success' | 'all') => { + setFilterBy(type); + }, []); + return (
- {accordionContent && ( + {filteredContent && (
-
+
+
+ + + +
-
{ date: value.start_time, buildTime: value.duration, compiler: value.compiler, - buildErrors: value.test_status.error, + buildErrors: value.test_status?.error ?? 0, status: value.valid ? 'valid' : 'invalid', }));