Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/summary component #90

Merged
merged 4 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions dashboard/src/components/Cards/BaseCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ const containerClassName =

const BaseCard = ({ title, content, className }: IBaseCard): JSX.Element => {
return (
<div className={classNames(className, containerClassName)}>
<div className="flex flex-col w-full h-full p-4 gap-2">
<span className="font-bold border-b border-darkGray pb-2">{title}</span>
<div className={classNames(containerClassName, className)}>
<div className="flex flex-col w-full h-full pt-4 gap-2">
<span className="font-bold border-b border-darkGray pb-2 pl-3">
{title}
</span>
{content}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,61 +1,20 @@
import { useMemo } from 'react';

import classNames from 'classnames';
import ListingComponentItem, {
IListingComponentItem,
} from '@/components/ListingComponentItem/ListingComponentItem';

import BaseCard from '../BaseCard';
import ColoredCircle from '../../ColoredCircle/ColoredCircle';

export interface IListingComponent {
items: IListingComponentItem[];
title: string;
}

interface IListingComponentItem {
warnings?: number;
errors?: number;
text?: string;
hasBottomBorder?: boolean;
}

interface IListedComponent {
items: IListingComponentItem[];
}

export enum ComponentType {
Warning,
Error,
}

const ListingComponentItem = ({
warnings,
errors,
text,
hasBottomBorder,
}: IListingComponentItem): JSX.Element => {
const hasBorder = hasBottomBorder ? 'border-b' : '';
const itemError =
errors && errors > 0 ? (
<ColoredCircle quantity={errors} type={ComponentType.Error} />
) : (
<></>
);

const itemWarning =
warnings && warnings > 0 ? (
<ColoredCircle quantity={warnings} type={ComponentType.Warning} />
) : (
<></>
);

return (
<div className={classNames('flex flex-row gap-2 pb-1', hasBorder)}>
{itemError}
{itemWarning}
<span className="text-black text-sm">{text}</span>
</div>
);
};

const ListedContent = ({ items }: IListedComponent): JSX.Element => {
const content = useMemo(() => {
return items.map(item => (
Expand Down
2 changes: 1 addition & 1 deletion dashboard/src/components/ColoredCircle/ColoredCircle.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import classNames from 'classnames';

import { ComponentType } from '@/components/Cards/ListingComponentCard/ListingComponentCard';
import { ComponentType } from '../ListingComponentItem/ListingComponentItem';

interface IColoredCircle {
quantity: number;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import classNames from 'classnames';

import ColoredCircle from '../ColoredCircle/ColoredCircle';

export interface IListingComponentItem {
warnings?: number;
errors?: number;
text?: string;
hasBottomBorder?: boolean;
}

export enum ComponentType {
Warning,
Error,
}

const ListingComponentItem = ({
warnings,
errors,
text,
hasBottomBorder,
}: IListingComponentItem): JSX.Element => {
const hasBorder = hasBottomBorder ? 'border-b' : '';
const itemError =
errors && errors > 0 ? (
<ColoredCircle quantity={errors} type={ComponentType.Error} />
) : (
<></>
);

const itemWarning =
warnings && warnings > 0 ? (
<ColoredCircle quantity={warnings} type={ComponentType.Warning} />
) : (
<></>
);

return (
<div className={classNames('flex flex-row gap-2 pb-1', hasBorder)}>
{itemError}
{itemWarning}
<span className="text-black text-sm">{text}</span>
</div>
);
};

export default ListingComponentItem;
70 changes: 70 additions & 0 deletions dashboard/src/components/Summary/Summary.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
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<typeof Summary>;

export default meta;
type Story = StoryObj<typeof meta>;

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'],
},
};
84 changes: 84 additions & 0 deletions dashboard/src/components/Summary/Summary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
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 {
title: string;
summaryHeaders: string[];
summaryBody: ISummaryItem[];
}

export interface ISummaryItem {
arch: IListingComponentItem;
compilers: string[];
}

const Summary = ({
title,
summaryHeaders,
summaryBody,
}: ISummary): JSX.Element => {
const summaryHeadersRow = useMemo(
() => summaryHeaders.map(header => <span key={header}>{header}</span>),
[summaryHeaders],
);

const summaryBodyRows = useMemo(
() =>
summaryBody.map(row => (
<SummaryItem
key={row.arch.text}
arch={row.arch}
compilers={row.compilers}
/>
)),
[summaryBody],
);

return (
<BaseCard
title={title}
className="w-fit bg-mediumGray"
content={
<BaseTable
className="!rounded-[0rem] bg-mediumGray"
headers={summaryHeadersRow}
body={<TableBody>{summaryBodyRows}</TableBody>}
/>
}
/>
);
};

const SummaryItem = ({ arch, compilers }: ISummaryItem): JSX.Element => {
const compilersElement = useMemo(
() =>
compilers.map(compiler => (
<span key={compiler} className="line-clamp-1">
{compiler}
</span>
)),
[compilers],
);
return (
<TableRow>
<TableCell>
<ListingComponentItem
errors={arch.errors}
warnings={arch.warnings}
text={arch.text}
/>
</TableCell>
<TableCell>
<div className="flex flex-col gap-1">{compilersElement}</div>
</TableCell>
</TableRow>
);
};

export default Summary;
20 changes: 13 additions & 7 deletions dashboard/src/components/Table/BaseTable.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import type { ReactElement } from 'react';

import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';

import { Table, TableHead, TableHeader, TableRow } from '../ui/table';

interface IBaseTable {
headers: string[];
headers: ReactElement[];
body: ReactElement;
className?: string;
}

const BaseTable = ({ headers, body }: IBaseTable): JSX.Element => {
const BaseTable = ({ headers, body, className }: IBaseTable): JSX.Element => {
return (
<div>
<Table className="rounded-lg text-black bg-white w-full">
<div className="h-full">
<Table
className={classNames(
className,
'rounded-lg text-black bg-white w-full',
)}
>
<TableHeader className="bg-mediumGray">
<TableRow>
{headers.map(column => (
<TableHead className="text-black border-b" key={column}>
<FormattedMessage id={column} />
<TableHead className="text-black border-b" key={column.key}>
{column}
</TableHead>
))}
</TableRow>
Expand Down
12 changes: 9 additions & 3 deletions dashboard/src/components/Table/TreeTable.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useMemo } from 'react';

import { FormattedMessage } from 'react-intl';

import { TableRow, TableCell } from '../ui/table';

import { TreeTableBody } from '../../types/tree/Tree';
Expand Down Expand Up @@ -51,9 +53,13 @@ const TreeTable = ({ treeTableRows }: ITreeTable): JSX.Element => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [treeTableRows]);

return (
<BaseTable headers={treeTableColumnsLabelId} body={<>{treeTableBody}</>} />
);
const treeTableHeaders = useMemo(() => {
return treeTableColumnsLabelId.map(columnLabelId => (
<FormattedMessage key={columnLabelId} id={columnLabelId} />
));
}, []);

return <BaseTable headers={treeTableHeaders} body={<>{treeTableBody}</>} />;
};

export default TreeTable;
Loading