-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
2,108 additions
and
20 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
16 changes: 2 additions & 14 deletions
16
webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Load.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 |
---|---|---|
@@ -1,24 +1,12 @@ | ||
import { useOutletContext } from "react-router"; | ||
import useAppSelector from "../../../../../../redux/hooks/useAppSelector"; | ||
import { getCurrentAreaId } from "../../../../../../redux/selectors"; | ||
import { MatrixStats, StudyMetadata } from "../../../../../../common/types"; | ||
import MatrixInput from "../../../../../common/MatrixInput"; | ||
import { Root } from "./style"; | ||
import Matrix from "../../../../../common/MatrixGrid/Matrix"; | ||
|
||
function Load() { | ||
const { study } = useOutletContext<{ study: StudyMetadata }>(); | ||
const currentArea = useAppSelector(getCurrentAreaId); | ||
const url = `input/load/series/load_${currentArea}`; | ||
|
||
//////////////////////////////////////////////////////////////// | ||
// JSX | ||
//////////////////////////////////////////////////////////////// | ||
|
||
return ( | ||
<Root> | ||
<MatrixInput study={study} url={url} computStats={MatrixStats.STATS} /> | ||
</Root> | ||
); | ||
return <Matrix url={url} />; | ||
} | ||
|
||
export default Load; |
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,84 @@ | ||
import { Divider, Skeleton } from "@mui/material"; | ||
import MatrixGrid from "."; | ||
import { useMatrix } from "./useMatrix"; | ||
import { useState } from "react"; | ||
import { useTranslation } from "react-i18next"; | ||
import ImportDialog from "../dialogs/ImportDialog"; | ||
import { useOutletContext } from "react-router"; | ||
import { StudyMetadata } from "../../../common/types"; | ||
import { MatrixContainer, MatrixHeader, MatrixTitle } from "./style"; | ||
import MatrixActions from "./MatrixActions"; | ||
|
||
interface MatrixProps { | ||
url: string; | ||
title?: string; | ||
enableTimeSeriesColumns?: boolean; | ||
enableAggregateColumns?: boolean; | ||
} | ||
|
||
function Matrix({ | ||
url, | ||
title = "global.timeSeries", | ||
enableTimeSeriesColumns = true, | ||
enableAggregateColumns = false, | ||
}: MatrixProps) { | ||
const { t } = useTranslation(); | ||
const { study } = useOutletContext<{ study: StudyMetadata }>(); | ||
const [openImportDialog, setOpenImportDialog] = useState(false); | ||
|
||
const { | ||
matrixData, | ||
isLoading, | ||
columns, | ||
dateTime, | ||
handleCellEdit, | ||
handleMultipleCellsEdit, | ||
handleImport, | ||
} = useMatrix(study.id, url, enableTimeSeriesColumns, enableAggregateColumns); | ||
|
||
if (isLoading || !matrixData) { | ||
return <Skeleton sx={{ height: 1, transform: "none" }} />; | ||
} | ||
|
||
//////////////////////////////////////////////////////////////// | ||
// JSX | ||
//////////////////////////////////////////////////////////////// | ||
|
||
return ( | ||
<MatrixContainer> | ||
<MatrixHeader> | ||
<MatrixTitle>{t(title)}</MatrixTitle> | ||
<MatrixActions | ||
onImport={() => setOpenImportDialog(true)} | ||
studyId={study.id} | ||
path={url} | ||
disabled={matrixData.data.length === 0} | ||
/> | ||
</MatrixHeader> | ||
|
||
<Divider sx={{ width: 1, mt: 1, mb: 2 }} /> | ||
|
||
<MatrixGrid | ||
data={matrixData.data} | ||
columns={columns} | ||
rows={matrixData.data.length} | ||
dateTime={dateTime} | ||
onCellEdit={handleCellEdit} | ||
onMultipleCellsEdit={handleMultipleCellsEdit} | ||
/> | ||
|
||
{openImportDialog && ( | ||
<ImportDialog | ||
open={openImportDialog} | ||
title={t("matrix.importNewMatrix")} | ||
dropzoneText={t("matrix.message.importHint")} | ||
onCancel={() => setOpenImportDialog(false)} | ||
onImport={handleImport} | ||
accept={{ "text/*": [".csv", ".tsv", ".txt"] }} | ||
/> | ||
)} | ||
</MatrixContainer> | ||
); | ||
} | ||
|
||
export default Matrix; |
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,43 @@ | ||
import { Box } from "@mui/material"; | ||
import SplitButton from "../buttons/SplitButton"; | ||
import DownloadMatrixButton from "../DownloadMatrixButton"; | ||
import FileDownload from "@mui/icons-material/FileDownload"; | ||
import { useTranslation } from "react-i18next"; | ||
|
||
interface MatrixActionsProps { | ||
onImport: () => void; | ||
studyId: string; | ||
path: string; | ||
disabled: boolean; | ||
} | ||
|
||
function MatrixActions({ | ||
onImport, | ||
studyId, | ||
path, | ||
disabled, | ||
}: MatrixActionsProps) { | ||
const { t } = useTranslation(); | ||
|
||
//////////////////////////////////////////////////////////////// | ||
// JSX | ||
//////////////////////////////////////////////////////////////// | ||
|
||
return ( | ||
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}> | ||
<SplitButton | ||
options={[t("global.import.fromFile"), t("global.import.fromDatabase")]} | ||
onClick={onImport} | ||
size="small" | ||
ButtonProps={{ | ||
startIcon: <FileDownload />, | ||
}} | ||
> | ||
{t("global.import")} | ||
</SplitButton> | ||
<DownloadMatrixButton studyId={studyId} path={path} disabled={disabled} /> | ||
</Box> | ||
); | ||
} | ||
|
||
export default MatrixActions; |
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,218 @@ | ||
import { render } from "@testing-library/react"; | ||
import MatrixGrid, { MatrixGridProps } from "."; | ||
import Box from "@mui/material/Box"; | ||
import { mockGetBoundingClientRect } from "../../../tests/mocks/mockGetBoundingClientRect"; | ||
import { type EnhancedGridColumn } from "./types"; | ||
import { ColumnDataType } from "./utils"; | ||
|
||
beforeEach(() => { | ||
mockGetBoundingClientRect(); | ||
}); | ||
|
||
function renderMatrixGrid( | ||
width: string, | ||
height: string, | ||
data: MatrixGridProps["data"], | ||
columns: EnhancedGridColumn[], | ||
rows: number, | ||
) { | ||
return render( | ||
<Box style={{ width, height }}> | ||
<MatrixGrid | ||
data={data} | ||
rows={rows} | ||
columns={columns} | ||
width="100%" | ||
height="100%" | ||
/> | ||
</Box>, | ||
); | ||
} | ||
|
||
function assertDimensions( | ||
element: HTMLElement, | ||
expectedWidth: number, | ||
expectedHeight: number, | ||
) { | ||
const rect = element.getBoundingClientRect(); | ||
expect(rect.width).toBe(expectedWidth); | ||
expect(rect.height).toBe(expectedHeight); | ||
} | ||
|
||
describe("MatrixGrid rendering", () => { | ||
test("MatrixGrid should be rendered within a 450x500px container and match these dimensions", () => { | ||
const data = [ | ||
[1, 2, 3], | ||
[4, 5, 6], | ||
]; | ||
|
||
const columns = [ | ||
{ | ||
id: "col1", | ||
title: "Column 1", | ||
width: 100, | ||
type: ColumnDataType.Number, | ||
editable: true, | ||
order: 0, | ||
}, | ||
{ | ||
id: "col2", | ||
title: "Column 2", | ||
width: 100, | ||
type: ColumnDataType.Number, | ||
editable: true, | ||
order: 1, | ||
}, | ||
{ | ||
id: "col3", | ||
title: "Column 3", | ||
width: 100, | ||
type: ColumnDataType.Number, | ||
editable: true, | ||
order: 2, | ||
}, | ||
]; | ||
|
||
const rows = 2; | ||
|
||
// Render the MatrixGrid inside a parent container with specific dimensions | ||
const { container } = renderMatrixGrid( | ||
"450px", // Use inline style for exact measurement | ||
"500px", | ||
data, | ||
columns, | ||
rows, | ||
); | ||
|
||
const matrix = container.firstChild; | ||
|
||
if (matrix instanceof HTMLElement) { | ||
expect(matrix).toBeInTheDocument(); | ||
assertDimensions(matrix, 450, 500); | ||
} else { | ||
throw new Error("Expected an HTMLElement but received a different node."); | ||
} | ||
}); | ||
|
||
test("MatrixGrid should render correctly with no data", () => { | ||
const data: MatrixGridProps["data"] = []; | ||
|
||
const columns = [ | ||
{ | ||
id: "col1", | ||
title: "Column 1", | ||
width: 100, | ||
type: ColumnDataType.Number, | ||
editable: true, | ||
order: 0, | ||
}, | ||
{ | ||
id: "col2", | ||
title: "Column 2", | ||
width: 100, | ||
type: ColumnDataType.Number, | ||
editable: true, | ||
order: 1, | ||
}, | ||
{ | ||
id: "col3", | ||
title: "Column 3", | ||
width: 100, | ||
type: ColumnDataType.Number, | ||
editable: true, | ||
order: 2, | ||
}, | ||
]; | ||
|
||
const rows = 0; | ||
|
||
const { container } = renderMatrixGrid( | ||
"450px", | ||
"500px", | ||
data, | ||
columns, | ||
rows, | ||
); | ||
|
||
const matrix = container.firstChild; | ||
|
||
if (matrix instanceof HTMLElement) { | ||
expect(matrix).toBeInTheDocument(); | ||
assertDimensions(matrix, 450, 500); | ||
} else { | ||
throw new Error("Expected an HTMLElement but received a different node."); | ||
} | ||
}); | ||
|
||
test("MatrixGrid should match the provided dimensions when resized", () => { | ||
const data = [ | ||
[1, 2, 3], | ||
[4, 5, 6], | ||
]; | ||
|
||
const columns = [ | ||
{ | ||
id: "col1", | ||
title: "Column 1", | ||
width: 100, | ||
type: ColumnDataType.Number, | ||
editable: true, | ||
order: 0, | ||
}, | ||
{ | ||
id: "col2", | ||
title: "Column 2", | ||
width: 100, | ||
type: ColumnDataType.Number, | ||
editable: true, | ||
order: 1, | ||
}, | ||
{ | ||
id: "col3", | ||
title: "Column 3", | ||
width: 100, | ||
type: ColumnDataType.Number, | ||
editable: true, | ||
order: 2, | ||
}, | ||
]; | ||
|
||
const rows = 2; | ||
|
||
const { container, rerender } = renderMatrixGrid( | ||
"450px", | ||
"500px", | ||
data, | ||
columns, | ||
rows, | ||
); | ||
|
||
let matrix = container.firstChild; | ||
|
||
if (matrix instanceof HTMLElement) { | ||
assertDimensions(matrix, 450, 500); | ||
} else { | ||
throw new Error("Expected an HTMLElement but received a different node."); | ||
} | ||
|
||
rerender( | ||
<Box style={{ width: "300px", height: "400px" }}> | ||
<MatrixGrid | ||
data={data} | ||
rows={rows} | ||
columns={columns} | ||
width="100%" | ||
height="100%" | ||
/> | ||
</Box>, | ||
); | ||
|
||
matrix = container.firstChild; | ||
|
||
if (matrix instanceof HTMLElement) { | ||
assertDimensions(matrix, 300, 400); | ||
} else { | ||
throw new Error("Expected an HTMLElement but received a different node."); | ||
} | ||
}); | ||
}); |
Oops, something went wrong.