Skip to content

Commit

Permalink
tables: store visible columns
Browse files Browse the repository at this point in the history
  • Loading branch information
SteRiccio committed Nov 29, 2023
1 parent 6852753 commit 1c3b800
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 11 deletions.
8 changes: 7 additions & 1 deletion webapp/components/Table/Header/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@ const Header = (props) => {
onVisibleColumnsChange,
totalCount,
visibleColumnsSelectionEnabled,
visibleColumnKeys,
} = props

return (
<div className="table__header">
{React.createElement(headerLeftComponent, { ...props, ...headerProps })}
{visibleColumnsSelectionEnabled && totalCount > 0 && (
<VisibleColumnsMenu columns={columns} onSelectionChange={onVisibleColumnsChange} />
<VisibleColumnsMenu
columns={columns}
onSelectionChange={onVisibleColumnsChange}
selectedColumnKeys={visibleColumnKeys}
/>
)}
</div>
)
Expand All @@ -34,6 +39,7 @@ Header.propTypes = {
onVisibleColumnsChange: PropTypes.func.isRequired,
totalCount: PropTypes.number.isRequired,
visibleColumnsSelectionEnabled: PropTypes.bool,
visibleColumnKeys: PropTypes.array.isRequired,
}

Header.defaultProps = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import './VisibleColumnsMenu.scss'

import React, { useCallback, useState } from 'react'
import React, { useCallback } from 'react'
import PropTypes from 'prop-types'

import { Objects } from '@openforis/arena-core'
Expand All @@ -11,16 +11,13 @@ import { ButtonMenu } from '@webapp/components'
import { Checkbox } from '@webapp/components/form'

export const VisibleColumnsMenu = (props) => {
const { columns, onSelectionChange } = props
const { columns, onSelectionChange, selectedColumnKeys } = props

const availableColumns = columns.filter((column) => !Objects.isEmpty(column.header) && column.header !== '#')

const [selectedColumnKeys, setSelectedColumnKeys] = useState(columns.map((col) => col.key))

const onColummSelectionChange = useCallback(
(key) => () => {
const selectedColumnKeysNext = ArrayUtils.addOrRemoveItem({ item: key })(selectedColumnKeys)
setSelectedColumnKeys(selectedColumnKeysNext)
onSelectionChange(selectedColumnKeysNext)
},
[onSelectionChange, selectedColumnKeys]
Expand Down Expand Up @@ -55,4 +52,5 @@ export const VisibleColumnsMenu = (props) => {
VisibleColumnsMenu.propTypes = {
columns: PropTypes.array.isRequired,
onSelectionChange: PropTypes.func.isRequired,
selectedColumnKeys: PropTypes.array,
}
2 changes: 2 additions & 0 deletions webapp/components/Table/Table.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const Table = (props) => {
onRowClick,
onVisibleColumnsChange,
selectedItems,
visibleColumnKeys,
visibleColumns,
} = useTable({
columns,
Expand Down Expand Up @@ -84,6 +85,7 @@ const Table = (props) => {
onVisibleColumnsChange={onVisibleColumnsChange}
selectedItems={selectedItems}
visibleColumnsSelectionEnabled={visibleColumnsSelectionEnabled}
visibleColumnKeys={visibleColumnKeys}
/>

<Content
Expand Down
21 changes: 16 additions & 5 deletions webapp/components/Table/useTable.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { useEffect, useCallback, useState } from 'react'
import { useEffect, useCallback, useState, useMemo } from 'react'
import { useNavigate } from 'react-router'
import { useDispatch } from 'react-redux'

import { ArrayUtils } from '@core/arrayUtils'

import { useSurveyId } from '@webapp/store/survey'
import { useAsyncGetRequest, useOnUpdate } from '@webapp/components/hooks'
import { getLimit, getOffset, getSearch, getSort, updateQuery } from '@webapp/components/Table/tableLink'
import { ArrayUtils } from '@core/arrayUtils'
import { TablesActions, useTableVisibleColumns } from '@webapp/store/ui/tables'

export const useTable = ({
columns,
Expand All @@ -15,8 +18,15 @@ export const useTable = ({
onRowClick: onRowClickProp,
selectable,
}) => {
const dispatch = useDispatch()

const [totalCount, setTotalCount] = useState(0)
const [visibleColumns, setVisibleColumns] = useState(columns)

const visibleColumnKeys = useTableVisibleColumns(module) || columns.map((column) => column.key)
const visibleColumns = useMemo(
() => columns.filter((column) => visibleColumnKeys.includes(column.key)),
[columns, visibleColumnKeys]
)

const navigate = useNavigate()
const surveyId = useSurveyId()
Expand Down Expand Up @@ -118,9 +128,9 @@ export const useTable = ({

const onVisibleColumnsChange = useCallback(
(visibleColumnKeys) => {
setVisibleColumns(columns.filter((column) => visibleColumnKeys.includes(column.key)))
dispatch(TablesActions.updateVisibleColumns({ module, visibleColumns: visibleColumnKeys }))
},
[columns]
[module]
)

return {
Expand All @@ -139,6 +149,7 @@ export const useTable = ({
onRowClick,
onVisibleColumnsChange,
selectedItems,
visibleColumnKeys,
visibleColumns,
}
}
2 changes: 2 additions & 0 deletions webapp/store/ui/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { LoaderReducer, LoaderState } from './loader'
import { DialogConfirmReducer, DialogConfirmState } from './dialogConfirm'
import { RecordReducer, RecordState } from './record'
import { SurveyFormReducer, SurveyFormState } from './surveyForm'
import { TablesReducer, TablesState } from './tables'
import { ChainReducer } from './chain'

export default combineReducers({
Expand All @@ -15,5 +16,6 @@ export default combineReducers({
[DialogConfirmState.stateKey]: DialogConfirmReducer,
[RecordState.stateKey]: RecordReducer,
[SurveyFormState.stateKey]: SurveyFormReducer,
[TablesState.stateKey]: TablesReducer,
chain: ChainReducer,
})
12 changes: 12 additions & 0 deletions webapp/store/ui/tables/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const tableVisibleColumnsUpdate = 'tables/visibleColumnsUpdate'
export const tableMaxRowsUpdate = 'tables/maxRowsUpdate'

export const updateVisibleColumns =
({ module, visibleColumns }) =>
(dispatch) =>
dispatch({ type: tableVisibleColumnsUpdate, module, visibleColumns })

export const updateMaxRows =
({ module, maxRows }) =>
(dispatch) =>
dispatch({ type: tableMaxRowsUpdate, module, maxRows })
6 changes: 6 additions & 0 deletions webapp/store/ui/tables/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { useSelector } from 'react-redux'
import * as TablesState from './state'

export const useTableMaxRows = (module) => useSelector(TablesState.getMaxRows(module))

export const useTableVisibleColumns = (module) => useSelector(TablesState.getVisibleColumns(module))
6 changes: 6 additions & 0 deletions webapp/store/ui/tables/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as TablesActions from './actions'
import TablesReducer from './reducer'
import * as TablesState from './state'

export { TablesActions, TablesReducer, TablesState }
export { useTableMaxRows, useTableVisibleColumns } from './hooks'
20 changes: 20 additions & 0 deletions webapp/store/ui/tables/reducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { exportReducer } from '@webapp/utils/reduxUtils'

import { SystemActions } from '@webapp/store/system'

import * as TablesActions from './actions'
import * as TablesState from './state'

const actionHandlers = {
// Reset form
[SystemActions.SYSTEM_RESET]: () => ({}),

// Tables
[TablesActions.tableVisibleColumnsUpdate]: (state, { module, visibleColumns }) =>
TablesState.assocVisibleColumns({ module, visibleColumns })(state),

[TablesActions.tableMaxRowsUpdate]: (state, { module, maxRows }) =>
TablesState.assocMaxRows({ module, maxRows })(state),
}

export default exportReducer(actionHandlers)
27 changes: 27 additions & 0 deletions webapp/store/ui/tables/state.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as A from '@core/arena'

import * as UiState from '../state'
import { Objects } from '@openforis/arena-core'

export const stateKey = 'tables'

const getState = A.pipe(UiState.getState, A.propOr({}, stateKey))

const keys = {
visibleColumnKeysByModule: 'visibleColumnKeysByModule',
maxRowsByModule: 'maxRowsByModule',
}

export const getVisibleColumns = (module) => A.pipe(getState, Objects.path([keys.visibleColumnKeysByModule, module]))

export const getMaxRows = (module) => A.pipe(getState, Objects.path([keys.maxRowsByModule, module]))

export const assocVisibleColumns =
({ module, visibleColumns }) =>
(state) =>
Objects.assocPath({ obj: state, path: [keys.visibleColumnKeysByModule, module], value: visibleColumns })

export const assocMaxRows =
({ module, maxRows }) =>
(state) =>
Objects.assocPath({ obj: state, path: [keys.maxRowsByModule, module], value: maxRows })

0 comments on commit 1c3b800

Please sign in to comment.