generated from dream-aim-deliver/dad-ui-kit-starter-template
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implemented a SelectableSourceDataAGGrid component
- Loading branch information
Showing
6 changed files
with
223 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
"use client"; | ||
import { z } from "zod"; | ||
import { BaseAGGrid } from "./BaseAGGrid"; | ||
import { ColDef } from "ag-grid-community"; | ||
import { useState } from "react"; | ||
|
||
import { Button as ShadcnButton } from "@/components/button/index"; | ||
|
||
const SourceDataRowSchema = z.object({ | ||
id: z.string(), | ||
name: z.string(), | ||
relativePath: z.string(), | ||
createdAt: z.string(), | ||
}); | ||
|
||
/** | ||
* SourceDataRow is a type that represents the structure of the data that will be displayed in the AG Grid. | ||
*/ | ||
export type SelectableSourceDataRow = z.infer<typeof SourceDataRowSchema>; | ||
|
||
/** | ||
* SourceDataAGGridProps is an interface that defines the props for the SourceDataAGGrid component. | ||
* @param rowData: the data to be displayed in the AG Grid. Must be an array of SourceDataRow objects. | ||
* @param buttonsWithCallBack: an array of objects containing a reactComponent and a callbackFunction. | ||
*/ | ||
export interface SelectableSourceDataAGGridProps { | ||
rowData: SelectableSourceDataRow[]; | ||
isLoading: boolean; | ||
handleConfirmSelection: (selectedRows: SelectableSourceDataRow[]) => void; | ||
errorOverlayProps?: { | ||
errorStatus: boolean; | ||
overlayText: string; | ||
}; | ||
} | ||
|
||
const ConfirmSelectionButton = ({ onClick }: { onClick: () => void }) => { | ||
return ( | ||
<ShadcnButton | ||
label={"Confirm Selection"} | ||
variant="default" | ||
onClick={onClick} | ||
title="Confirm the selected rows" | ||
/> | ||
); | ||
}; | ||
|
||
/** | ||
* SourceDataAGGrid is a react component that displays a table of source data in an AG Grid. | ||
* @param rowData: the data to be displayed in the AG Grid. Must be an array of SourceDataRow objects. | ||
* @param handleDownloadSourceData: a function that is called when the download button is clicked. | ||
* @param handleUploadSourceData: a function that is called when the upload button is clicked. | ||
* @param isLoading: a boolean that indicates whether the data is still loading. | ||
* @param errorOverlayProps: an object that contains the error status and overlay text. | ||
* @returns a react component that displays a table of source data in an AG Grid. | ||
*/ | ||
export function SelectableSourceDataAGGrid( | ||
props: SelectableSourceDataAGGridProps, | ||
) { | ||
const [columnDefs] = useState<ColDef[]>([ | ||
{ | ||
headerCheckboxSelection: true, | ||
headerCheckboxSelectionFilteredOnly: true, | ||
checkboxSelection: true, | ||
headerName: "ID", | ||
filter: false, | ||
field: "id", | ||
flex: 0.3, | ||
}, | ||
{ | ||
headerName: "Name", | ||
field: "name", | ||
flex: 1.5, | ||
}, | ||
{ | ||
headerName: "Relative Path", | ||
field: "relativePath", | ||
flex: 2, | ||
}, | ||
{ | ||
headerName: "Created At", | ||
field: "createdAt", | ||
flex: 1, | ||
}, | ||
{ | ||
headerName: "", | ||
filter: false, | ||
flex: 0.5, | ||
}, | ||
]); | ||
|
||
return ( | ||
<div> | ||
<BaseAGGrid | ||
isLoading={props.isLoading} | ||
rowData={props.rowData} | ||
columnDefs={columnDefs} | ||
componentsWithCallBack={[ | ||
{ | ||
reactComponent: ConfirmSelectionButton, | ||
callbackFunction: props.handleConfirmSelection, | ||
}, | ||
]} | ||
errorOverlayProps={props.errorOverlayProps} | ||
/> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
|
||
import { | ||
SelectableSourceDataAGGrid, | ||
SelectableSourceDataRow, | ||
} from "@/components/table/SelectableSourceDataAGGrid"; | ||
|
||
const meta: Meta = { | ||
title: "Components/AGGrid/SelectableSourceData", | ||
component: SelectableSourceDataAGGrid, | ||
parameters: { | ||
layout: "centered", | ||
}, | ||
tags: ["autodocs"], | ||
} satisfies Meta<typeof SelectableSourceDataAGGrid>; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof meta>; | ||
|
||
function randomChoice<T>(list: T[]): T { | ||
const randomIndex = Math.floor(Math.random() * list.length); | ||
return list[randomIndex]; | ||
} | ||
|
||
const thousand = Array.from({ length: 1000 }, (_, i) => i + 1); | ||
|
||
function getRandomDate(start: Date, end: Date): Date { | ||
const startTimestamp = start.getTime(); | ||
const endTimestamp = end.getTime(); | ||
const randomTimestamp = | ||
startTimestamp + Math.random() * (endTimestamp - startTimestamp); | ||
return new Date(randomTimestamp); | ||
} | ||
|
||
const dataGenerator = () => { | ||
const topics = [ | ||
"wildfires", | ||
"earthquakes", | ||
"floods", | ||
"hurricanes", | ||
"tornadoes", | ||
]; | ||
const file_number = randomChoice(thousand); | ||
const extensions = ["txt", "csv", "json", "xml"]; | ||
const ext = randomChoice(extensions); | ||
const relative_path = `/sda/${randomChoice<number>(thousand)}/${randomChoice<string>(topics)}/file_${file_number}.${ext}`; | ||
|
||
const startDate_c = new Date(2024, 0, 1); | ||
const endDate_c = new Date(2024, 1, 1); | ||
const created_at = getRandomDate(startDate_c, endDate_c).toISOString(); | ||
|
||
const datum: SelectableSourceDataRow = { | ||
id: randomChoice(thousand).toString(), | ||
name: `File names can be long ${file_number}`, | ||
relativePath: relative_path, | ||
createdAt: created_at, | ||
}; | ||
|
||
return datum; | ||
}; | ||
|
||
export const LoadingWithNoData: Story = { | ||
args: { | ||
rowData: [], | ||
isLoading: true, | ||
}, | ||
}; | ||
|
||
export const ErrorState: Story = { | ||
args: { | ||
rowData: [], | ||
isLoading: false, | ||
errorOverlayProps: { | ||
errorStatus: true, | ||
overlayText: | ||
"An error occurred while fetching the data: lorem ipsum dolor sit amet, consectetur adipiscing elit. nullam nec purus. nullam nec purus. nullam nec purus. an error occurred while fetching the data: lorem ipsum dolor sit amet, consectetur adipiscing elit. nullam nec purus. nullam nec purus. nullam nec purus. an error occurred while fetching the data: lorem ipsum dolor sit amet, consectetur adipiscing elit. nullam nec purus. nullam nec purus. nullam nec purus. an error occurred while fetching the data: lorem ipsum dolor sit amet, consectetur adipiscing elit. nullam nec purus. nullam nec purus. nullam nec purus. an error occurred while fetching the data: lorem ipsum dolor sit amet, consectetur adipiscing elit. nullam nec purus. nullam nec purus. nullam nec purus. an error occurred while fetching the data: lorem ipsum dolor sit amet, consectetur adipiscing elit. nullam nec purus. nullam nec purus. nullam nec purus.an error occurred while fetching the data: lorem ipsum dolor sit amet, consectetur adipiscing elit. nullam nec purus. nullam nec purus. nullam nec purus. an error occurred while fetching the data: lorem ipsum dolor sit amet, consectetur adipiscing elit. nullam nec purus. nullam nec purus. nullam nec purus. an error occurred while fetching the data: lorem ipsum dolor sit amet, consectetur adipiscing elit. nullam nec purus. nullam nec purus. nullam nec purus. an error occurred while fetching the data: lorem ipsum dolor sit amet, consectetur adipiscing elit. nullam nec purus. nullam nec purus. nullam nec purus. an error occurred while fetching the data: lorem ipsum dolor sit amet, consectetur adipiscing elit. nullam nec purus. nullam nec purus. nullam nec purus. an error occurred while fetching the data: lorem ipsum dolor sit amet, consectetur adipiscing elit. nullam nec purus. nullam nec purus. nullam nec purus.", | ||
}, | ||
}, | ||
}; | ||
|
||
export const WithAlertFunctions: Story = { | ||
args: { | ||
rowData: Array.from({ length: 106 }, dataGenerator), | ||
isLoading: false, | ||
handleConfirmSelection: (selectedRows: SelectableSourceDataRow[]) => { | ||
alert( | ||
"Selected rows:\n\n" + | ||
selectedRows.map((row) => JSON.stringify(row)).join("\n\n"), | ||
); | ||
}, | ||
}, | ||
}; |