diff --git a/dashboard/src/components/Cards/BaseCard.tsx b/dashboard/src/components/Cards/BaseCard.tsx index a755073..d7f3d89 100644 --- a/dashboard/src/components/Cards/BaseCard.tsx +++ b/dashboard/src/components/Cards/BaseCard.tsx @@ -8,7 +8,7 @@ interface IBaseCard { } const containerClassName = - 'flex flex-col rounded-xl bg-white w-1/2 h-fit border border-darkGray text-black'; + 'flex flex-col rounded-xl bg-white w-full h-fit border border-darkGray text-black'; const BaseCard = ({ title, content, className }: IBaseCard): JSX.Element => { return ( diff --git a/dashboard/src/components/Cards/ListingComponentCard/ListingComponentCard.tsx b/dashboard/src/components/Cards/ListingComponentCard/ListingComponentCard.tsx index 710bb4e..6414d00 100644 --- a/dashboard/src/components/Cards/ListingComponentCard/ListingComponentCard.tsx +++ b/dashboard/src/components/Cards/ListingComponentCard/ListingComponentCard.tsx @@ -4,42 +4,29 @@ import ListingComponentItem, { IListingComponentItem, } from '@/components/ListingComponentItem/ListingComponentItem'; -import BaseCard from '../BaseCard'; - export interface IListingComponent { items: IListingComponentItem[]; title: string; + type: 'listing'; } interface IListedComponent { items: IListingComponentItem[]; } -const ListedContent = ({ items }: IListedComponent): JSX.Element => { +const ListingComponentContent = ({ items }: IListedComponent): JSX.Element => { const content = useMemo(() => { return items.map(item => ( )); }, [items]); - return
{content}
; -}; - -const ListingComponentCard = ({ - title, - items, -}: IListingComponent): JSX.Element => { - return ( - } - /> - ); + return
{content}
; }; -export default ListingComponentCard; +export default ListingComponentContent; diff --git a/dashboard/src/components/Cards/ListingComponentCard/ListingComponentsCars.stories.tsx b/dashboard/src/components/Cards/ListingComponentCard/ListingComponentsCars.stories.tsx deleted file mode 100644 index b04b885..0000000 --- a/dashboard/src/components/Cards/ListingComponentCard/ListingComponentsCars.stories.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; - -import ListingComponentCard from './ListingComponentCard'; - -const meta = { - title: 'ListingComponentCard', - component: ListingComponentCard, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -const itemsDefault = [ - { - errors: 1, - warnings: 888, - text: 'allmodconfig', - }, - { - errors: 1, - warnings: 1, - text: 'microdroid_defconfig', - }, - { - errors: 2, - warnings: 3, - text: 'x86_64_defconfig', - }, - { - errors: 1, - warnings: 2, - text: 'i386_defconfig', - }, - { - errors: 1, - warnings: 1, - text: 'rv32_defconfig', - }, -]; - -const itemsErrors = [ - { - errors: 8, - warnings: 0, - text: 'include/linux/fortify-string.h:57:29: error: ‘__builtin_memcpy’ offset 32 is out of the bounds [0, 0] [-Werror=array-bounds]', - }, - { - errors: 2, - warnings: 0, - text: 'drivers/net/ethernet/realtek/r8169_main.c:5512:23: error: ‘rtl8169_pm_ops’ undeclared here (not in a function); did you mean ‘rtl8169_poll’?', - }, - { - errors: 1, - warnings: 0, - text: 'arch/x86/include/asm/string_32.h:150:25: error: ‘__builtin_memcpy’ offset 32 is out of the bounds [0, 0] [-Werror=array-bounds]', - }, -]; - -const itemsWarnings = [ - { - errors: 0, - warnings: 10, - text: 'cc1: all warnings being treated as errors', - }, - { - errors: 0, - warnings: 6, - text: 'drivers/of/unittest-data/tests-phandle.dtsi:12.18-22: Warning (node_name_vs_property_name): /testcase-data/duplicate-name: node name and property name conflict', - }, - { - errors: 0, - warnings: 5, - text: 'WARNING: modpost: vmlinux: memblock_end_of_DRAM: EXPORT_SYMBOL used for init symbol. Remove __init or EXPORT_SYMBOL.', - }, -]; - -export const Default: Story = { - args: { - items: itemsDefault, - title: 'Configs', - }, -}; - -export const Warnings: Story = { - args: { - items: itemsWarnings, - title: 'Configs', - }, -}; - -export const Errors: Story = { - args: { - items: itemsErrors, - title: 'Configs', - }, -}; diff --git a/dashboard/src/components/GroupCards/GroupListingComponentCard.tsx b/dashboard/src/components/GroupCards/GroupListingComponentCard.tsx new file mode 100644 index 0000000..6db02e1 --- /dev/null +++ b/dashboard/src/components/GroupCards/GroupListingComponentCard.tsx @@ -0,0 +1,48 @@ +import { useMemo } from 'react'; + +import ListingComponentContent, { + IListingComponent, +} from '../Cards/ListingComponentCard/ListingComponentCard'; +import Summary, { ISummary } from '../Summary/Summary'; +import BaseCard from '../Cards/BaseCard'; + +interface IListingComponentCardsGroup { + cards: (IListingComponent | ISummary)[]; +} + +interface ICardContent { + card: IListingComponent | ISummary; +} + +const ListingComponentCardsGroup = ({ + cards, +}: IListingComponentCardsGroup): JSX.Element => { + const cardsList = useMemo(() => { + return cards.map(card => ( + } + /> + )); + }, [cards]); + return
{cardsList}
; +}; + +const CardContent = ({ card }: ICardContent): JSX.Element => { + if (card.type === 'listing' && card.items) { + return ; + } else if (card.type === 'summary' && card.summaryBody) { + return ( + + ); + } else { + return <>; + } +}; + +export default ListingComponentCardsGroup; diff --git a/dashboard/src/components/ListingComponentItem/ListingComponentItem.tsx b/dashboard/src/components/ListingComponentItem/ListingComponentItem.tsx index cb5ab5c..1f5948c 100644 --- a/dashboard/src/components/ListingComponentItem/ListingComponentItem.tsx +++ b/dashboard/src/components/ListingComponentItem/ListingComponentItem.tsx @@ -5,6 +5,7 @@ import ColoredCircle from '../ColoredCircle/ColoredCircle'; export interface IListingComponentItem { warnings?: number; errors?: number; + success?: number; text?: string; hasBottomBorder?: boolean; } @@ -19,6 +20,7 @@ const ListingComponentItem = ({ warnings, errors, text, + success, hasBottomBorder, }: IListingComponentItem): JSX.Element => { const hasBorder = hasBottomBorder ? 'border-b' : ''; @@ -36,10 +38,18 @@ const ListingComponentItem = ({ <> ); + const itemSuccess = + success && success > 0 ? ( + + ) : ( + <> + ); + return (
{itemError} {itemWarning} + {itemSuccess} {text}
); diff --git a/dashboard/src/components/Summary/Summary.stories.tsx b/dashboard/src/components/Summary/Summary.stories.tsx deleted file mode 100644 index e2f2c51..0000000 --- a/dashboard/src/components/Summary/Summary.stories.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; - -import Summary, { ISummaryItem } from './Summary'; - -const meta = { - title: 'Summary', - component: Summary, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -const items: ISummaryItem[] = [ - { - arch: { - errors: 4, - warnings: 1, - text: 'arm64', - }, - compilers: [ - 'aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110', - 'Debian clang version 17.0.6 (++20231208085823+6009708b436...)', - ], - }, - { - arch: { - errors: 4, - warnings: 1, - text: 'arm64', - }, - compilers: [ - 'aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110', - 'Debian clang version 17.0.6 (++20231208085823+6009708b436...)', - ], - }, - { - arch: { - errors: 4, - warnings: 1, - text: 'arm64', - }, - compilers: [ - 'aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110', - 'Debian clang version 17.0.6 (++20231208085823+6009708b436...)', - ], - }, - { - arch: { - errors: 4, - warnings: 1, - text: 'arm64', - }, - compilers: [ - 'aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110', - 'Debian clang version 17.0.6 (++20231208085823+6009708b436++20231208085823+6009708b436++20231208085823+6009708b436++20231208085823+6009708b436)', - ], - }, -]; - -export const Default: Story = { - args: { - summaryBody: items, - title: 'Summary', - summaryHeaders: ['Arch', 'Compiler'], - }, -}; diff --git a/dashboard/src/components/Summary/Summary.tsx b/dashboard/src/components/Summary/Summary.tsx index d9861b6..9651bb3 100644 --- a/dashboard/src/components/Summary/Summary.tsx +++ b/dashboard/src/components/Summary/Summary.tsx @@ -1,14 +1,17 @@ import { useMemo } from 'react'; -import BaseCard from '../Cards/BaseCard'; import BaseTable from '../Table/BaseTable'; import { TableBody, TableCell, TableRow } from '../ui/table'; import ListingComponentItem, { IListingComponentItem, } from '../ListingComponentItem/ListingComponentItem'; -export interface ISummary { +export interface ISummary extends ISummaryTable { title: string; + type: 'summary'; +} + +export interface ISummaryTable { summaryHeaders: string[]; summaryBody: ISummaryItem[]; } @@ -19,10 +22,9 @@ export interface ISummaryItem { } const Summary = ({ - title, summaryHeaders, summaryBody, -}: ISummary): JSX.Element => { +}: ISummaryTable): JSX.Element => { const summaryHeadersRow = useMemo( () => summaryHeaders.map(header => {header}), [summaryHeaders], @@ -41,16 +43,10 @@ const Summary = ({ ); return ( - {summaryBodyRows}} - /> - } + {summaryBodyRows}} /> ); }; @@ -72,6 +68,7 @@ const SummaryItem = ({ arch, compilers }: ISummaryItem): JSX.Element => { errors={arch.errors} warnings={arch.warnings} text={arch.text} + success={arch.success} /> diff --git a/dashboard/src/routes/TreeDetails/TreeDetails.tsx b/dashboard/src/routes/TreeDetails/TreeDetails.tsx index 9ecab58..fff2a6d 100644 --- a/dashboard/src/routes/TreeDetails/TreeDetails.tsx +++ b/dashboard/src/routes/TreeDetails/TreeDetails.tsx @@ -1,13 +1,69 @@ +import { useParams } from 'react-router-dom'; + +import { useEffect, useState } from 'react'; + import TreeDetailsTab from '@/components/Tabs/TreeDetailsTab'; import FilterButton from '@/components/Button/FilterButton'; +import { useTreeDetail } from '@/api/TreeDetails'; + +import { TreeDetails as TreeDetailsType } from '@/types/tree/TreeDetails'; +import { IListingComponentItem } from '@/components/ListingComponentItem/ListingComponentItem'; +import ListingComponentCardsGroup from '@/components/GroupCards/GroupListingComponentCard'; +import { ISummary, ISummaryItem } from '@/components/Summary/Summary'; +import { IListingComponent } from '@/components/Cards/ListingComponentCard/ListingComponentCard'; const TreeDetails = (): JSX.Element => { + const { treeId } = useParams(); + const { data } = useTreeDetail(treeId ?? ''); + + const [configs, setConfigs] = useState(); + const [archictectures, setArchitectures] = useState(); + + useEffect(() => { + if (data as TreeDetailsType) { + const configsData: IListingComponentItem[] = Object.entries( + (data as TreeDetailsType).summary.configs, + ).map(([key, value]) => ({ + text: key, + errors: value.invalid, + success: value.valid, + })); + setConfigs(configsData); + + const archData: ISummaryItem[] = Object.entries( + (data as TreeDetailsType).summary.architectures, + ).map(([key, value]) => ({ + arch: { text: key, errors: value.invalid, success: value.invalid }, + compilers: value.compilers, + })); + + setArchitectures(archData); + } + }, [data]); + return (
+
+ +
); };