Skip to content

Commit

Permalink
Merge pull request #80 from UgnisSoftware/UGN-284
Browse files Browse the repository at this point in the history
Fix UGN-284 table losing data on filter
  • Loading branch information
masiulis authored Mar 18, 2022
2 parents 0fc20c5 + d9aa932 commit edcae16
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 8 deletions.
29 changes: 21 additions & 8 deletions src/steps/ValidationStep/ValidationStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Table } from "../../components/Table"
import { SubmitDataAlert } from "../../components/Alerts/SubmitDataAlert"
import type { Data } from "../../types"
import type { themeOverrides } from "../../theme"
import type { RowsChangeData } from "react-data-grid"

type Props<T extends string> = {
initialData: Data<T>[]
Expand All @@ -25,17 +26,30 @@ export const ValidationStep = <T extends string>({ initialData }: Props<T>) => {
const [filterByErrors, setFilterByErrors] = useState(false)
const [showSubmitAlert, setShowSubmitAlert] = useState(false)

const updateData = useCallback(
(rows: typeof data) => {
setData(addErrorsAndRunHooks<T>(rows, fields, rowHook, tableHook))
},
[setData, addErrorsAndRunHooks, rowHook, tableHook],
)

const deleteSelectedRows = () => {
if (selectedRows.size) {
const newData = data.filter((value) => !selectedRows.has(value.__index))
updateRow(newData)
updateData(newData)
setSelectedRows(new Set())
}
}

const updateRow = useCallback(
(rows: typeof data) => {
setData(addErrorsAndRunHooks<T>(rows, fields, rowHook, tableHook))
const updateRowTable = useCallback(
(rows: typeof data, changedData?: RowsChangeData<typeof data[number]>) => {
const changes = changedData?.indexes.reduce((acc, val) => {
const realIndex = rows[val].__index
acc[realIndex] = rows[val]
return acc
}, {} as Record<number, typeof data[number]>)
const newData = Object.assign([], data, changes)
updateData(newData)
},
[setData, addErrorsAndRunHooks, rowHook, tableHook],
)
Expand All @@ -45,9 +59,8 @@ export const ValidationStep = <T extends string>({ initialData }: Props<T>) => {
const tableData = useMemo(() => {
if (filterByErrors) {
return data.filter((value, index) => {
const originalValue = data[index]
if (originalValue?.__errors) {
return Object.values(originalValue.__errors)?.filter((err) => err.level === "error").length
if (value?.__errors) {
return Object.values(value.__errors)?.filter((err) => err.level === "error").length
}
return false
})
Expand Down Expand Up @@ -114,7 +127,7 @@ export const ValidationStep = <T extends string>({ initialData }: Props<T>) => {
<Table
rowKeyGetter={rowKeyGetter}
rows={tableData}
onRowsChange={updateRow}
onRowsChange={updateRowTable}
columns={columns}
selectedRows={selectedRows}
onSelectedRowsChange={setSelectedRows}
Expand Down
91 changes: 91 additions & 0 deletions src/steps/ValidationStep/tests/ValidationStep.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,97 @@ describe("Validation step tests", () => {
const filteredRowsWithHeader = await screen.findAllByRole("row")
expect(filteredRowsWithHeader).toHaveLength(2)
})

test("Filters rows with errors, fixes row, removes filter", async () => {
const UNIQUE_NAME = "very unique name"
const SECOND_UNIQUE_NAME = "another unique name"
const FINAL_NAME = "just name"
const initialData = [
{
name: UNIQUE_NAME,
},
{
name: undefined,
},
{
name: SECOND_UNIQUE_NAME,
},
]
const result = [
{
name: UNIQUE_NAME,
},
{
name: FINAL_NAME,
},
{
name: SECOND_UNIQUE_NAME,
},
]
const fields = [
{
label: "Name",
key: "name",
fieldType: {
type: "input",
},
validations: [
{
rule: "required",
errorMessage: "Name is required",
},
],
},
] as const

const onSubmit = jest.fn()
render(
<Providers theme={defaultTheme} rsiValues={{ ...mockValues, fields, onSubmit }}>
<ModalWrapper isOpen={true} onClose={() => {}}>
<ValidationStep initialData={initialData} />
</ModalWrapper>
</Providers>,
)

const allRowsWithHeader = await screen.findAllByRole("row")
expect(allRowsWithHeader).toHaveLength(4)

const validRow = screen.getByText(UNIQUE_NAME)
expect(validRow).toBeInTheDocument()

const switchFilter = getFilterSwitch()

userEvent.click(switchFilter)

const filteredRowsWithHeader = await screen.findAllByRole("row")
expect(filteredRowsWithHeader).toHaveLength(2)

// don't really know another way to select an empty cell
const emptyCell = screen.getAllByRole("gridcell", { name: undefined })[1]
console.log(emptyCell)
userEvent.click(emptyCell)

await userEvent.keyboard(FINAL_NAME + "{enter}")

const filteredRowsNoErrorsWithHeader = await screen.findAllByRole("row")
expect(filteredRowsNoErrorsWithHeader).toHaveLength(1)

userEvent.click(switchFilter)

const allRowsFixedWithHeader = await screen.findAllByRole("row")
expect(allRowsFixedWithHeader).toHaveLength(4)

const finishButton = screen.getByRole("button", {
name: "Confirm",
})

userEvent.click(finishButton)

await waitFor(() => {
expect(onSubmit).toBeCalled()
})
})

test("Filters rows with unique errors", async () => {
const NON_UNIQUE_NAME = "very unique name"
const initialData = [
Expand Down

0 comments on commit edcae16

Please sign in to comment.