-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WCMS-21498: Add fullscreen mode to dataset table tab (#237)
- Loading branch information
1 parent
72d722d
commit 375dda0
Showing
17 changed files
with
592 additions
and
364 deletions.
There are no files selected for viewing
109 changes: 109 additions & 0 deletions
109
src/components/DataTableControls/DataTableControls.test.jsx
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,109 @@ | ||
import React from "react"; | ||
import { render, screen } from "@testing-library/react"; | ||
import DataTableControls from "."; | ||
import { ManageColumnsContext } from "../DatasetTableTab/DataTableStateWrapper"; | ||
import { DataTableContext } from "../../templates/Dataset"; | ||
import * as resource from "../../tests/fixtures/resource.json"; | ||
import * as distribution from "../../tests/fixtures/distribution.json"; | ||
|
||
describe('DataTableControls', () => { | ||
resource.setSort = jest.fn(); | ||
it('Renders correctly', () => { | ||
render( | ||
<DataTableContext.Provider value={{ | ||
resource: resource, | ||
distribution: distribution.distribution[0], | ||
rootUrl: "test/api/", | ||
}}> | ||
<ManageColumnsContext.Provider value={{ | ||
columnOrder: [], | ||
setColumnOrder: jest.fn(), | ||
setColumnVisibility: jest.fn() | ||
}}> | ||
<DataTableControls | ||
id={"test"} | ||
columns={[]} | ||
defaultColumnOrder={[]} | ||
isModal={false} | ||
closeFullScreenModal={jest.fn()} | ||
/> | ||
</ManageColumnsContext.Provider> | ||
</DataTableContext.Provider> | ||
) | ||
expect(screen.getByRole("button", {name: "Manage columns - Opens in a dialog"})).toBeInTheDocument(); | ||
expect(screen.getByRole("button", {name: "Full Screen mode - Opens in a dialog"})).toBeInTheDocument(); | ||
}); | ||
it('Renders hidden columns', () => { | ||
const columns = [ | ||
{ | ||
"id": "teaching_hospital_ccn", | ||
"depth": 0, | ||
"columnDef": { | ||
"header": "Teaching_Hospital_CCN", | ||
"filterFn": "auto", | ||
"sortingFn": "auto", | ||
"sortUndefined": 1, | ||
"aggregationFn": "auto", | ||
"size": 150, | ||
"minSize": 20, | ||
"maxSize": 9007199254740991, | ||
"accessorKey": "teaching_hospital_ccn" | ||
}, | ||
"columns": [], | ||
"getIsVisible": () => false // mock not visible | ||
}, | ||
{ | ||
"id": "change_type", | ||
"depth": 0, | ||
"columnDef": { | ||
"header": "Change_Type", | ||
"filterFn": "auto", | ||
"sortingFn": "auto", | ||
"sortUndefined": 1, | ||
"aggregationFn": "auto", | ||
"size": 150, | ||
"minSize": 20, | ||
"maxSize": 9007199254740991, | ||
"accessorKey": "change_type" | ||
}, | ||
"columns": [], | ||
"getIsVisible": () => true | ||
}, | ||
]; | ||
render( | ||
<ManageColumnsContext.Provider value={{ | ||
columnOrder: [], | ||
setColumnOrder: jest.fn(), | ||
setColumnVisibility: jest.fn() | ||
}}> | ||
<DataTableControls | ||
id={"test"} | ||
columns={columns} | ||
defaultColumnOrder={[]} | ||
isModal={true} | ||
closeFullScreenModal={jest.fn()} | ||
/> | ||
</ManageColumnsContext.Provider> | ||
); | ||
expect(screen.getByText("1 Columns Hidden")).toBeInTheDocument(); | ||
}) | ||
it('Does not render the full screen dialog if we are already in a dialog', () => { | ||
render( | ||
<ManageColumnsContext.Provider value={{ | ||
columnOrder: [], | ||
setColumnOrder: jest.fn(), | ||
setColumnVisibility: jest.fn() | ||
}}> | ||
<DataTableControls | ||
id={"test"} | ||
columns={[]} | ||
defaultColumnOrder={[]} | ||
isModal={true} | ||
closeFullScreenModal={jest.fn()} | ||
/> | ||
</ManageColumnsContext.Provider> | ||
); | ||
expect(screen.queryByRole("button", {name: "Full Screen mode - Opens in a dialog"})).not.toBeInTheDocument(); | ||
expect(screen.getByRole("button", {name: "Close Full Screen dialog"})).toBeInTheDocument(); | ||
}) | ||
}) |
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,66 @@ | ||
import React from "react"; | ||
import { useState } from "react"; | ||
import { Alert } from "@cmsgov/design-system"; | ||
import ManageColumns from "../ManageColumns/ManageColumns"; | ||
import FullScreenDataTable from "../FullScreenDataTable"; | ||
|
||
const DataTableControls = ( | ||
{id, columns, defaultColumnOrder, isModal, closeFullScreenModal} : { | ||
id: string, | ||
columns: Array<any>, | ||
defaultColumnOrder: Array<string>, | ||
isModal: boolean, | ||
closeFullScreenModal: Function | ||
} | ||
) => { | ||
const [manageColumnsModalOpen, setManageColumnsModalOpen] = useState(false); | ||
const [fullScreenModalOpen, setFullScreenModalOpen] = useState(false); | ||
|
||
const hiddenColumns = columns.filter(c => c.getIsVisible() === false ).length; | ||
|
||
return ( | ||
<> | ||
<div className='ds-u-border-top--1 ds-u-fill--gray-lightest ds-u-display--flex ds-u-justify-content--between'> | ||
<div> | ||
{hiddenColumns > 0 && ( | ||
<Alert variation="warn">{hiddenColumns} Columns Hidden</Alert> | ||
)} | ||
</div> | ||
<div> | ||
<button | ||
aria-label='Manage columns - Opens in a dialog' | ||
className="ds-c-button ds-c-button--ghost ds-u-margin-y--1" | ||
onClick={() => { | ||
setManageColumnsModalOpen(true) | ||
}} | ||
><i className="far fa-cog ds-u-margin-right--1"></i>Manage Columns</button> | ||
<button | ||
aria-label={isModal ? 'Close Full Screen dialog' : 'Full Screen mode - Opens in a dialog'} | ||
className="ds-c-button ds-c-button--ghost ds-u-margin-y--1" | ||
onClick={() => { | ||
if (isModal) { | ||
closeFullScreenModal(); | ||
} else { | ||
setFullScreenModalOpen(true) | ||
} | ||
}} | ||
><i className={`fa ${isModal ? 'fa-compress' : 'fa-expand'} ds-u-margin-right--1`}></i>{isModal ? "Exit Full Screen" : "Full Screen"}</button> | ||
</div> | ||
</div> | ||
<div> | ||
<ManageColumns | ||
id={id} | ||
columns={columns} | ||
defaultColumnOrder={defaultColumnOrder} | ||
modalOpen={manageColumnsModalOpen} | ||
setModalOpen={setManageColumnsModalOpen} | ||
/> | ||
{!isModal && ( | ||
<FullScreenDataTable modalOpen={fullScreenModalOpen} setModalOpen={setFullScreenModalOpen} /> | ||
)} | ||
</div> | ||
</> | ||
) | ||
}; | ||
|
||
export default DataTableControls; |
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,43 @@ | ||
import React from "react"; | ||
import { createContext, useContext, useState } from "react"; | ||
import DatasetTable from "."; | ||
import { DataTableContext } from "../../templates/Dataset"; | ||
|
||
export const ManageColumnsContext = createContext({}) | ||
|
||
const DataTableStateWrapper = () => { | ||
const { id, datasetTableControls } = useContext(DataTableContext); | ||
// a wrapper component to keep column state synced between full screen and regular modes | ||
const localStorageData = id ? JSON.parse(localStorage.getItem(id) as string) : null; | ||
|
||
const defaultPage = 1; | ||
const [page, setPage] = useState(defaultPage); | ||
|
||
const [columnOrder, setColumnOrder] = useState(() => { | ||
if (datasetTableControls && localStorageData) | ||
return localStorageData.tableColumnOrder; | ||
else | ||
return []; | ||
}) | ||
const [columnVisibility, setColumnVisibility] = useState(() => { | ||
if (datasetTableControls && localStorageData) | ||
return localStorageData.tableColumnVisibility; | ||
else | ||
return {}; | ||
}) | ||
|
||
return ( | ||
<ManageColumnsContext.Provider value={{ | ||
columnOrder: columnOrder, | ||
setColumnOrder: setColumnOrder, | ||
columnVisibility: columnVisibility, | ||
setColumnVisibility: setColumnVisibility, | ||
page: page, | ||
setPage: setPage | ||
}}> | ||
<DatasetTable /> | ||
</ManageColumnsContext.Provider> | ||
) | ||
} | ||
|
||
export default DataTableStateWrapper; |
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,43 +1,98 @@ | ||
import React from 'react'; | ||
import { render, screen } from '@testing-library/react'; | ||
import { render, screen, act } from '@testing-library/react'; | ||
import '@testing-library/jest-dom'; | ||
import DatasetTable from './index'; | ||
import DataTableStateWrapper from './DataTableStateWrapper'; | ||
import * as resource from "../../tests/fixtures/resource.json"; | ||
import * as distribution from "../../tests/fixtures/distribution.json"; | ||
import { DataTableContext } from '../../templates/Dataset'; | ||
|
||
describe('<DatasetTableTab />', () => { | ||
test("Renders correctly", () => { | ||
window.scrollTo = jest.fn(); | ||
beforeEach(() => { | ||
resource.setSort = jest.fn(); | ||
}) | ||
test("Renders correctly", () => { | ||
render( | ||
<DatasetTable | ||
resource={resource} | ||
distribution={distribution.distribution[0]} | ||
rootUrl={"test/api/"} | ||
/>) | ||
<DataTableContext.Provider value={{ | ||
resource: resource, | ||
distribution: distribution.distribution[0], | ||
rootUrl: "test/api/" | ||
}} > | ||
<DataTableStateWrapper /> | ||
</DataTableContext.Provider> | ||
) | ||
|
||
expect(screen.getByText("Data filters: none")).toBeInTheDocument(); | ||
expect(screen.getByRole("table")).toBeInTheDocument(); | ||
expect(screen.getByRole("navigation")).toHaveClass("ds-c-pagination"); | ||
}); | ||
test("Renders data dictionary info banner if prop is provided", () => { | ||
resource.setSort = jest.fn(); | ||
render( | ||
<DatasetTable | ||
resource={resource} | ||
distribution={distribution.distribution[0]} | ||
rootUrl={"test/api/"} | ||
dataDictionaryBanner={true} | ||
/>) | ||
<DataTableContext.Provider value={{ | ||
resource: resource, | ||
distribution: distribution.distribution[0], | ||
rootUrl: "test/api/", | ||
dataDictionaryBanner: true | ||
}} > | ||
<DataTableStateWrapper /> | ||
</DataTableContext.Provider> | ||
) | ||
expect(screen.getByText('Click on the "Data Dictionary" tab above for full column definitions')).toBeInTheDocument(); | ||
}); | ||
test("Does not render data dictionary info banner if prop is not provided", () => { | ||
resource.setSort = jest.fn(); | ||
render( | ||
<DatasetTable | ||
resource={resource} | ||
distribution={distribution.distribution[0]} | ||
rootUrl={"test/api/"} | ||
/>) | ||
<DataTableContext.Provider value={{ | ||
resource: resource, | ||
distribution: distribution.distribution[0], | ||
rootUrl: "test/api/" | ||
}} > | ||
<DataTableStateWrapper /> | ||
</DataTableContext.Provider> | ||
) | ||
expect(screen.queryByText('Click on the "Data Dictionary" tab above for full column definitions')).not.toBeInTheDocument(); | ||
}); | ||
test("Renders controls if prop is provided", () => { | ||
render( | ||
<DataTableContext.Provider value={{ | ||
resource: resource, | ||
distribution: distribution.distribution[0], | ||
rootUrl: "test/api/", | ||
datasetTableControls: true | ||
}} > | ||
<DataTableStateWrapper /> | ||
</DataTableContext.Provider> | ||
) | ||
|
||
expect(screen.queryAllByText("Manage Columns")).toHaveLength(2); | ||
expect(screen.queryByText("Full Screen")).toBeInTheDocument(); | ||
}) | ||
test("State is synchronized between regular and full screen mode", async () => { | ||
render( | ||
<DataTableContext.Provider value={{ | ||
resource: resource, | ||
distribution: distribution.distribution[0], | ||
rootUrl: "test/api/", | ||
datasetTableControls: true | ||
}} > | ||
<DataTableStateWrapper /> | ||
</DataTableContext.Provider> | ||
) | ||
// Is there a better way to do this test because every step seems to need an act | ||
await act(async () => { | ||
await screen.queryAllByText("Manage Columns")[0].click(); | ||
}); | ||
await act(async() => { | ||
await screen.getByRole('checkbox', {name: "Select all"}).click() | ||
}) | ||
await act(async() => { | ||
await screen.getByRole('button', {name: 'Save'}).click(); | ||
}) | ||
await act(async() => { | ||
await screen.getByRole('button', {name: 'Full Screen mode - Opens in a dialog'}).click(); | ||
}) | ||
await act(async () => { | ||
await screen.queryAllByText("Manage Columns")[1].click(); | ||
}); | ||
expect(screen.getByRole('checkbox', {name: "Select all"})).not.toBeChecked(); | ||
}, 10000) | ||
}); |
Oops, something went wrong.