Skip to content

Commit

Permalink
4001 - Datatable use Datagrid - Headers (#4108)
Browse files Browse the repository at this point in the history
* 4001 - Clone TableHead as GridHead using DataCells

* 4001 - Add getODPHeader util

* 4001 - Extract cell rendering logic to custom hook

* 4001 - Update styles

* 4001 - Update OdpHeaderCell

* 4001 - Fix ReviewSummaryIndicator placement

* 4001 - Update odp header class name

* 4001 - Add GridHeadCell component

* 4001 - Remove cycle return

* 4001 - Move getODPHeader

* 4001 - Add GridHeadCellProps type

* 4001 - Use classNames

* 4001 - Update getODPHeader import path
  • Loading branch information
yaguzmang authored Nov 13, 2024
1 parent 34d5769 commit fe9521f
Show file tree
Hide file tree
Showing 13 changed files with 300 additions and 3 deletions.
42 changes: 42 additions & 0 deletions src/client/pages/Section/DataTable/Table/GridHead/GridHead.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react'

import { Col as TypeCol, Row as TypeRow, RowType, Table } from 'meta/assessment'
import { RecordAssessmentData } from 'meta/data'

import GridHeadCell from 'client/pages/Section/DataTable/Table/GridHead/GridHeadCell'

type Props = {
assessmentName: string
data: RecordAssessmentData
headers: Array<string>
table: Table
}

const GridHead: React.FC<Props> = (props) => {
const { assessmentName, data, headers, table } = props

const rowsHeader = table.rows.filter((row) => row.props.type === RowType.header)

return (
<>
{rowsHeader.map((row: TypeRow, rowIndex: number) =>
row.cols.map((col: TypeCol, colIndex: number) => {
return (
<GridHeadCell
assessmentName={assessmentName}
col={col}
colIndex={colIndex}
data={data}
headers={headers}
row={row}
rowIndex={rowIndex}
table={table}
/>
)
})
)}
</>
)
}

export default GridHead
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react'
import { useTranslation } from 'react-i18next'

import { Cols } from 'meta/assessment'

import { useCycle } from 'client/store/assessment'
import { DataCell } from 'client/components/DataGrid'
import OdpHeaderCell from 'client/pages/Section/DataTable/Table/GridHead/OdpHeaderCell'

import { useGridHeadCellProps } from './hooks/useGridHeadCellProps'
import { GridHeadCellProps } from './types'

const GridHeadCell: React.FC<GridHeadCellProps> = (props) => {
const { col, table } = props

const cycle = useCycle()
const { className, gridColumn, gridRow, lastCol, odpHeader } = useGridHeadCellProps(props)

const { t } = useTranslation()

if (odpHeader) {
return (
<OdpHeaderCell
key={col.uuid}
className={className}
gridColumn={gridColumn}
gridRow={gridRow}
lastCol={lastCol}
odpId={odpHeader.id}
odpYear={odpHeader.year}
sectionName={table.props.name}
/>
)
}

return (
<DataCell key={col.uuid} className={className} gridColumn={gridColumn} gridRow={gridRow} header lastCol={lastCol}>
{Cols.getLabel({ cycle, col, t })}
</DataCell>
)
}

export default GridHeadCell
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Country } from 'meta/area'
import { Col, Table } from 'meta/assessment'

type OdpYear = {
id: number
year: string
}

type Props = {
col: Col
columnName: string
country: Country
odpYears: Array<OdpYear>
showOdp: boolean
table: Table
}

type Returned = OdpYear | undefined

export const getODPHeader = (props: Props): Returned => {
const { col, columnName, country, odpYears, showOdp, table } = props

let odpHeader: Returned
const isODPVisible = showOdp && table.props.odp && !col.props.labels
if (isODPVisible) {
odpHeader = odpYears?.find((odp) => odp.year === columnName)
}
if (table.props.name === 'forestCharacteristics' && !country.props.forestCharacteristics.useOriginalDataPoint) {
odpHeader = undefined
}

return odpHeader
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useMemo } from 'react'

import classNames from 'classnames'

import { Cols } from 'meta/assessment'

import { useAssessmentCountry } from 'client/store/area'
import { useCycle } from 'client/store/assessment'
import { useOriginalDataPointYears } from 'client/store/data'
import { useShowOriginalDatapoints } from 'client/store/ui/assessmentSection'
import { getODPColSpan } from 'client/pages/Section/DataTable/Table/utils/getODPColSpan'

import { GridHeadCellProps } from '../types'
import { getODPHeader } from './getODPHeader'

type Returned = {
className: string
gridColumn: string
gridRow: string
lastCol: boolean
odpHeader?: {
id: number
year: string
}
}

export const useGridHeadCellProps = (props: GridHeadCellProps): Returned => {
const { assessmentName, col, colIndex, data, headers, row, rowIndex, table } = props

const country = useAssessmentCountry()
const cycle = useCycle()
const odpYears = useOriginalDataPointYears()
const showOdp = useShowOriginalDatapoints()

return useMemo<Returned>(() => {
const { odp: isOdpTable } = table.props

const { colSpan: defaultColSpan, rowSpan } = Cols.getStyle({ col, cycle })
const columnName = headers[colIndex]

const odpHeader = getODPHeader({ col, columnName, country, odpYears, showOdp, table })

let colSpan = defaultColSpan
if (isOdpTable && !defaultColSpan) {
colSpan = getODPColSpan({ assessmentName, cycleName: cycle.name, data, headers, table })
}

const { index } = col.props
const isHeaderLeft = (index === 0 && rowIndex === 0) || row.props?.readonly
const className = classNames('table-grid__data-cell', { left: isHeaderLeft })

const gridColumn = `span ${colSpan}`
const gridRow = `span ${rowSpan}`
const lastCol = colIndex === row.cols.length - 1

return {
className,
gridColumn,
gridRow,
lastCol,
odpHeader,
}
}, [assessmentName, col, colIndex, country, cycle, data, headers, odpYears, row, rowIndex, showOdp, table])
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './GridHeadCell'
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Col, Row, Table } from 'meta/assessment'
import { RecordAssessmentData } from 'meta/data'

export type GridHeadCellProps = {
assessmentName: string
col: Col
colIndex: number
data: RecordAssessmentData
headers: Array<string>
row: Row
rowIndex: number
table: Table
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@import 'src/client/style/partials';

.table-grid__odp-cell.header {
font-weight: 700;
background-color: rgba($ui-accent, 10%);

.link {
text-decoration: underline;
}

.review-summary-status {
margin: 0 $spacing-xxxs;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import './OdpHeaderCell.scss'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { Link } from 'react-router-dom'

import classNames from 'classnames'

import { Routes } from 'meta/routes'
import { TooltipId } from 'meta/tooltip'

import { useAssessment, useCycle } from 'client/store/assessment'
import { useOdpReviewSummary } from 'client/store/ui/review/hooks'
import { useCountryIso } from 'client/hooks'
import { useIsPrintRoute } from 'client/hooks/useIsRoute'
import { DataCell } from 'client/components/DataGrid'
import ReviewSummaryIndicator from 'client/components/ReviewSummaryIndicator'

type Props = {
className: string
gridColumn: string
gridRow: string
lastCol?: boolean
odpId: number
odpYear: string
sectionName: string
}

const OdpHeaderCell: React.FC<Props> = (props) => {
const { className, gridColumn, gridRow, lastCol, odpId, odpYear, sectionName } = props

const assessment = useAssessment()
const countryIso = useCountryIso()
const cycle = useCycle()

const { print } = useIsPrintRoute()
const { t } = useTranslation()

const reviewStatus = useOdpReviewSummary(odpId)

if (print) {
return (
<DataCell className={className} gridColumn={gridColumn} gridRow={gridRow}>
{odpYear}
</DataCell>
)
}

return (
<DataCell
className={classNames(className, 'table-grid__odp-cell')}
gridColumn={gridColumn}
gridRow={gridRow}
header
lastCol={lastCol}
>
<Link
className="link"
data-tooltip-content={t('nationalDataPoint.clickOnNDP')}
data-tooltip-id={TooltipId.info}
to={Routes.OriginalDataPoint.generatePath({
assessmentName: assessment.props.name,
countryIso,
cycleName: cycle.name,
sectionName,
year: odpYear,
})}
>
{odpYear}
<ReviewSummaryIndicator status={reviewStatus} />
</Link>
</DataCell>
)
}

OdpHeaderCell.defaultProps = {
lastCol: false,
}

export default OdpHeaderCell
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './OdpHeaderCell'
1 change: 1 addition & 0 deletions src/client/pages/Section/DataTable/Table/GridHead/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './GridHead'
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
//}

.table-grid__data-cell {
align-items: center;
display: flex;
justify-content: end;
padding: 10px;
text-align: right;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
@import 'src/client/style/partials';

.table-grid__data-cell.header {
text-align: center;
justify-content: space-around;

&.left {
text-align: left;
justify-content: start;
}

&.category {
Expand All @@ -25,6 +25,6 @@
&.subcategory1,
&.subcategory2 {
font-weight: 400;
text-align: left;
justify-content: start;
}
}
3 changes: 3 additions & 0 deletions src/client/pages/Section/DataTable/Table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import ButtonTableExport from 'client/components/ButtonTableExport'
import { DataGrid } from 'client/components/DataGrid'
import ButtonCopyValues from 'client/pages/Section/DataTable/Table/ButtonCopyValues'
import ButtonTableClear from 'client/pages/Section/DataTable/Table/ButtonTableClear'
import GridHead from 'client/pages/Section/DataTable/Table/GridHead'
import GridRow from 'client/pages/Section/DataTable/Table/GridRow'
import TableBody from 'client/pages/Section/DataTable/Table/TableBody'
import TableHead from 'client/pages/Section/DataTable/Table/TableHead'
Expand Down Expand Up @@ -64,6 +65,8 @@ const Table: React.FC<Props> = (props) => {
</div>

<DataGrid className="table-grid" gridTemplateColumns={`minmax(auto, 400px) repeat(${headers.length},1fr)`}>
<GridHead assessmentName={assessmentName} data={data} headers={headers} table={table} />

{rowsData.map((row, index) => (
<GridRow
key={row.uuid}
Expand Down

0 comments on commit fe9521f

Please sign in to comment.