-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #70 from globalfund/feat/DE-959
DE-959: Table component visual implementation
- Loading branch information
Showing
15 changed files
with
1,340 additions
and
31 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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 changes: 69 additions & 0 deletions
69
src/app/components/table-container/TableContainer.stories.tsx
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,69 @@ | ||
import React from "react"; | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
|
||
import { TableContainer } from "app/components/table-container"; | ||
import { withRouter } from "storybook-addon-react-router-v6"; | ||
import { | ||
TABLE_VARIATION_1_DATA, | ||
TABLE_VARIATION_1_COLUMNS, | ||
TABLE_VARIATION_2_DATA, | ||
TABLE_VARIATION_2_COLUMNS, | ||
TABLE_VARIATION_3_DATA, | ||
TABLE_VARIATION_3_COLUMNS, | ||
TABLE_VARIATION_4_DATA, | ||
TABLE_VARIATION_4_COLUMNS, | ||
TABLE_VARIATION_5_DATA, | ||
TABLE_VARIATION_5_COLUMNS, | ||
} from "app/components/table/data"; | ||
|
||
const Variant2Wrapper = (args: any) => { | ||
const [tab, setTab] = React.useState(args.tabsView?.selectedTab); | ||
|
||
return ( | ||
<TableContainer | ||
{...args} | ||
tabsView={ | ||
args.tabsView && { | ||
...args.tabsView, | ||
selectedTab: tab, | ||
onTabChange: setTab, | ||
} | ||
} | ||
/> | ||
); | ||
}; | ||
|
||
const meta = { | ||
title: "Components/Table Container", | ||
component: Variant2Wrapper, | ||
decorators: [withRouter], | ||
parameters: { | ||
layout: "fullscreen", | ||
}, | ||
tags: ["autodocs"], | ||
argTypes: {}, | ||
} satisfies Meta<typeof TableContainer>; | ||
|
||
export default meta; | ||
type StoryType = StoryObj<typeof meta>; | ||
|
||
export const Variant1: StoryType = { | ||
args: { | ||
dataTree: true, | ||
data: TABLE_VARIATION_1_DATA, | ||
columns: TABLE_VARIATION_1_COLUMNS, | ||
}, | ||
}; | ||
|
||
export const Variant2: StoryType = { | ||
args: { | ||
dataTree: true, | ||
data: TABLE_VARIATION_1_DATA, | ||
columns: TABLE_VARIATION_1_COLUMNS, | ||
tabsView: { | ||
tabs: ["All", "Impact Indicators", "Outcome Indicators"], | ||
selectedTab: "All", | ||
onTabChange: (tab: string) => console.log(tab), | ||
}, | ||
}, | ||
}; |
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,17 @@ | ||
import { TableProps } from "app/components/table/data"; | ||
|
||
export interface TableContainerProps extends TableProps { | ||
tabsView?: { | ||
tabs: string[]; | ||
selectedTab: string; | ||
onTabChange: (tab: string) => void; | ||
}; | ||
} | ||
|
||
export const TABLE_CONTAINER_TABS = [ | ||
"All", | ||
"Impact Indicators", | ||
"Outcome Indicators", | ||
"Modules & Coverage Indicators", | ||
"Modules & Workplan Tracking Measures", | ||
]; |
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,134 @@ | ||
import React from "react"; | ||
import Box from "@mui/material/Box"; | ||
import Button from "@mui/material/Button"; | ||
import { Table } from "app/components/table"; | ||
import IconButton from "@mui/material/IconButton"; | ||
import { TabulatorFull as Tabulator } from "tabulator-tables"; | ||
import { TableContainerProps } from "app/components/table-container/data"; | ||
import { ReactComponent as FilterIcon } from "app/assets/vectors/TableToolbarFilter.svg"; | ||
import { ReactComponent as SearchIcon } from "app/assets/vectors/TableToolbarSearch.svg"; | ||
import { ReactComponent as ColumnsIcon } from "app/assets/vectors/TableToolbarColumns.svg"; | ||
import { ReactComponent as DownloadIcon } from "app/assets/vectors/TableToolbarDownload.svg"; | ||
import { ReactComponent as FullscreenIcon } from "app/assets/vectors/TableToolbarFullscreen.svg"; | ||
|
||
export const TableContainer: React.FC<TableContainerProps> = ( | ||
props: TableContainerProps | ||
) => { | ||
const [table, setTable] = React.useState<any>(null); | ||
const fullscreenRef = React.useRef<HTMLDivElement>(null); | ||
|
||
React.useEffect(() => { | ||
const element = document.getElementById("table"); | ||
if (element) { | ||
const tabulatorTables = Tabulator.findTable("#table"); | ||
if (tabulatorTables.length > 0 && tabulatorTables[0]) { | ||
setTable(tabulatorTables[0]); | ||
} | ||
} | ||
}, []); | ||
|
||
const download = () => { | ||
if (table) { | ||
table.download("csv", "data.csv"); | ||
} | ||
}; | ||
|
||
const fullscreen = () => { | ||
if (!fullscreenRef.current) { | ||
return; | ||
} | ||
if (document.fullscreenElement) { | ||
document.exitFullscreen(); | ||
} else { | ||
fullscreenRef.current.requestFullscreen(); | ||
} | ||
}; | ||
|
||
return ( | ||
<Box | ||
gap="24px" | ||
display="flex" | ||
bgcolor="#fff" | ||
borderRadius="32px" | ||
ref={fullscreenRef} | ||
flexDirection="column" | ||
> | ||
{!props.tabsView && ( | ||
<Box | ||
gap="8px" | ||
display="flex" | ||
justifyContent="flex-end" | ||
sx={{ | ||
"& > button": { | ||
padding: "0px", | ||
}, | ||
}} | ||
> | ||
<IconButton disableRipple onClick={fullscreen}> | ||
<FullscreenIcon /> | ||
</IconButton> | ||
<IconButton disableRipple> | ||
<ColumnsIcon /> | ||
</IconButton> | ||
<IconButton disableRipple> | ||
<FilterIcon /> | ||
</IconButton> | ||
<IconButton disableRipple onClick={download}> | ||
<DownloadIcon /> | ||
</IconButton> | ||
<IconButton disableRipple> | ||
<SearchIcon /> | ||
</IconButton> | ||
</Box> | ||
)} | ||
{props.tabsView && ( | ||
<Box | ||
width="100%" | ||
display="flex" | ||
flexDirection="row" | ||
alignItems="center" | ||
justifyContent="space-between" | ||
> | ||
<Box | ||
gap="8px" | ||
display="flex" | ||
flexDirection="row" | ||
alignItems="center" | ||
sx={{ | ||
"& > button": { | ||
height: "32px", | ||
fontSize: "14px", | ||
fontWeight: "400", | ||
padding: "0px 24px", | ||
borderRadius: "8px", | ||
textTransform: "none", | ||
"&:hover": { | ||
color: "#fff", | ||
background: "#000", | ||
}, | ||
}, | ||
}} | ||
> | ||
{props.tabsView.tabs.map((tab) => ( | ||
<Button | ||
key={tab} | ||
onClick={() => props.tabsView?.onTabChange(tab)} | ||
sx={{ | ||
color: props.tabsView?.selectedTab === tab ? "#fff" : "#000", | ||
background: | ||
props.tabsView?.selectedTab === tab ? "#000" : "#F1F3F4", | ||
}} | ||
> | ||
{tab} | ||
</Button> | ||
))} | ||
</Box> | ||
<IconButton disableRipple> | ||
<SearchIcon /> | ||
</IconButton> | ||
</Box> | ||
)} | ||
<Table {...props} /> | ||
</Box> | ||
); | ||
}; |
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,100 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
|
||
import { Table } from "app/components/table"; | ||
import { withRouter } from "storybook-addon-react-router-v6"; | ||
import { | ||
TABLE_VARIATION_1_DATA, | ||
TABLE_VARIATION_1_COLUMNS, | ||
TABLE_VARIATION_2_DATA, | ||
TABLE_VARIATION_2_COLUMNS, | ||
TABLE_VARIATION_3_DATA, | ||
TABLE_VARIATION_3_COLUMNS, | ||
TABLE_VARIATION_4_DATA, | ||
TABLE_VARIATION_4_COLUMNS, | ||
TABLE_VARIATION_5_DATA, | ||
TABLE_VARIATION_5_COLUMNS, | ||
TABLE_VARIATION_6_DATA, | ||
TABLE_VARIATION_6_COLUMNS, | ||
TABLE_VARIATION_7_DATA, | ||
TABLE_VARIATION_7_COLUMNS, | ||
} from "app/components/table/data"; | ||
|
||
const meta = { | ||
title: "Components/Table", | ||
component: Table, | ||
decorators: [withRouter], | ||
parameters: { | ||
layout: "fullscreen", | ||
}, | ||
tags: ["autodocs"], | ||
argTypes: {}, | ||
} satisfies Meta<typeof Table>; | ||
|
||
export default meta; | ||
type StoryType = StoryObj<typeof meta>; | ||
|
||
export const Variant1: StoryType = { | ||
args: { | ||
dataTree: true, | ||
data: TABLE_VARIATION_1_DATA, | ||
columns: TABLE_VARIATION_1_COLUMNS, | ||
}, | ||
}; | ||
|
||
export const Variant2: StoryType = { | ||
args: { | ||
dataTree: true, | ||
dataTreeBranchElement: false, | ||
data: TABLE_VARIATION_2_DATA, | ||
columns: TABLE_VARIATION_2_COLUMNS.slice(0, 7), | ||
extraColumns: TABLE_VARIATION_2_COLUMNS.slice( | ||
7, | ||
TABLE_VARIATION_2_COLUMNS.length - 1 | ||
), | ||
}, | ||
}; | ||
|
||
export const Variant3: StoryType = { | ||
args: { | ||
dataTree: true, | ||
dataTreeBranchElement: false, | ||
data: TABLE_VARIATION_3_DATA, | ||
columns: TABLE_VARIATION_3_COLUMNS, | ||
}, | ||
}; | ||
|
||
export const Variant4: StoryType = { | ||
args: { | ||
dataTree: true, | ||
data: TABLE_VARIATION_4_DATA, | ||
columns: TABLE_VARIATION_4_COLUMNS.slice(0, 1), | ||
extraColumns: TABLE_VARIATION_4_COLUMNS.slice( | ||
1, | ||
TABLE_VARIATION_2_COLUMNS.length - 1 | ||
), | ||
}, | ||
}; | ||
|
||
export const Variant5: StoryType = { | ||
args: { | ||
dataTree: true, | ||
data: TABLE_VARIATION_5_DATA, | ||
columns: TABLE_VARIATION_5_COLUMNS, | ||
}, | ||
}; | ||
|
||
export const Variant6: StoryType = { | ||
args: { | ||
dataTree: true, | ||
data: TABLE_VARIATION_6_DATA, | ||
columns: TABLE_VARIATION_6_COLUMNS, | ||
}, | ||
}; | ||
|
||
export const Variant7: StoryType = { | ||
args: { | ||
dataTree: true, | ||
data: TABLE_VARIATION_7_DATA, | ||
columns: TABLE_VARIATION_7_COLUMNS, | ||
}, | ||
}; |
Oops, something went wrong.