diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index c8806953ae..a4c73b8fd0 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -25,7 +25,7 @@ === Improvements - +- https://github.com/eclipse-sirius/sirius-web/issues/4345[#4345] [table] Make table cells independently selectable == v2025.1.0 diff --git a/packages/forms/frontend/sirius-components-forms/src/propertysections/TableWidgetPropertySection.tsx b/packages/forms/frontend/sirius-components-forms/src/propertysections/TableWidgetPropertySection.tsx index a728753a87..a9b3a2c358 100644 --- a/packages/forms/frontend/sirius-components-forms/src/propertysections/TableWidgetPropertySection.tsx +++ b/packages/forms/frontend/sirius-components-forms/src/propertysections/TableWidgetPropertySection.tsx @@ -46,7 +46,7 @@ export const TableWidgetPropertySection: PropertySectionComponent ); diff --git a/packages/tables/frontend/sirius-components-tables/src/cells/Cell.tsx b/packages/tables/frontend/sirius-components-tables/src/cells/Cell.tsx index 10b5e2e4a1..77aa0e62f8 100644 --- a/packages/tables/frontend/sirius-components-tables/src/cells/Cell.tsx +++ b/packages/tables/frontend/sirius-components-tables/src/cells/Cell.tsx @@ -11,8 +11,10 @@ * Obeo - initial API and implementation *******************************************************************************/ +import { Selection, useSelection } from '@eclipse-sirius/sirius-components-core'; import Typography from '@mui/material/Typography'; import { memo } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { GQLCell, GQLCheckboxCell, @@ -34,10 +36,23 @@ const isMultiSelectCell = (cell: GQLCell): cell is GQLMultiSelectCell => cell.__ const isTextfieldCell = (cell: GQLCell): cell is GQLTextfieldCell => cell.__typename === 'TextfieldCell'; const isIconLabelCell = (cell: GQLCell): cell is GQLIconLabelCell => cell.__typename === 'IconLabelCell'; +const useStyles = makeStyles()(() => ({ + cell: { + width: '100%', + }, +})); + export const Cell = memo(({ editingContextId, representationId, tableId, cell, disabled }: CellProps) => { + const { classes } = useStyles(); + const { setSelection } = useSelection(); if (cell) { + const onClick = () => { + const newSelection: Selection = { entries: [{ id: cell.targetObjectId, kind: cell.targetObjectKind }] }; + setSelection(newSelection); + }; + let cellContent: JSX.Element | undefined; if (isCheckboxCell(cell)) { - return ( + cellContent = ( ); } else if (isTextfieldCell(cell)) { - return ( + cellContent = ( ); } else if (isSelectCell(cell)) { - return ( + cellContent = ( ); } else if (isMultiSelectCell(cell)) { - return ( + cellContent = ( ); } else if (isIconLabelCell(cell)) { - return ( + cellContent = ( ); } + if (cellContent) { + return ( +
+ {cellContent} +
+ ); + } } return ; }); diff --git a/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnFiltering.ts b/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnFiltering.ts index 9b89372016..740cef9566 100644 --- a/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnFiltering.ts +++ b/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnFiltering.ts @@ -81,7 +81,7 @@ export const useTableColumnFiltering = ( if (!enableColumnFilters) { return { - columnFilters: undefined, + columnFilters: [], setColumnFilters: undefined, }; } diff --git a/packages/tables/frontend/sirius-components-tables/src/representation/TableRepresentation.tsx b/packages/tables/frontend/sirius-components-tables/src/representation/TableRepresentation.tsx index 3a297085c9..9bbcbc1aad 100644 --- a/packages/tables/frontend/sirius-components-tables/src/representation/TableRepresentation.tsx +++ b/packages/tables/frontend/sirius-components-tables/src/representation/TableRepresentation.tsx @@ -88,7 +88,7 @@ export const TableRepresentation = ({ editingContextId, representationId, readOn enableColumnFilters enableRowSizing enableGlobalFilter - enablePagination + enableCursorBasedPagination /> ) : null} {completeMessage} diff --git a/packages/tables/frontend/sirius-components-tables/src/table/TableContent.tsx b/packages/tables/frontend/sirius-components-tables/src/table/TableContent.tsx index c85bf29492..53956fedf2 100644 --- a/packages/tables/frontend/sirius-components-tables/src/table/TableContent.tsx +++ b/packages/tables/frontend/sirius-components-tables/src/table/TableContent.tsx @@ -12,6 +12,7 @@ *******************************************************************************/ import { Selection, useSelection } from '@eclipse-sirius/sirius-components-core'; import Box from '@mui/material/Box'; +import { Theme, useTheme } from '@mui/material/styles'; import { MaterialReactTable, MRT_DensityState, MRT_TableOptions, useMaterialReactTable } from 'material-react-table'; import { memo, useEffect, useState } from 'react'; import { SettingsButton } from '../actions/SettingsButton'; @@ -40,9 +41,10 @@ export const TableContent = memo( enableColumnFilters, enableRowSizing, enableGlobalFilter, - enablePagination, + enableCursorBasedPagination, }: TableProps) => { const { selection, setSelection } = useSelection(); + const theme: Theme = useTheme(); const { columns } = useTableColumns( editingContextId, @@ -147,8 +149,8 @@ export const TableContent = memo( enableEditing: !readOnly, onColumnFiltersChange: setColumnFilters, enableStickyHeader: true, - enablePagination, - manualPagination: enablePagination, + enablePagination: !enableCursorBasedPagination, + manualPagination: enableCursorBasedPagination, rowCount: table.paginationData.totalRowCount, enableRowActions: true, enableColumnFilters, @@ -165,10 +167,6 @@ export const TableContent = memo( state: { columnSizing, columnVisibility, globalFilter, density, columnFilters }, muiTableBodyRowProps: ({ row }) => { return { - onClick: () => { - const newSelection: Selection = { entries: [{ id: row.original.targetObjectId, kind: 'Object' }] }; - setSelection(newSelection); - }, selected: selection.entries.map((entry) => entry.id).includes(row.original.targetObjectId), sx: { backgroundColor: 'transparent', // required to remove the default mui backgroundColor that is defined as !important @@ -177,12 +175,25 @@ export const TableContent = memo( }, }; }, + muiTableBodyCellProps: ({ cell, row }) => { + const rowSelected = selection.entries.map((entry) => entry.id).includes(row.original.targetObjectId); + const cellTargetObjectId = row.original.cells.find( + (originalCell) => originalCell.columnId === cell.column.id + )?.targetObjectId; + const cellSelected = + cellTargetObjectId && selection.entries.map((entry) => entry.id).includes(cellTargetObjectId); + return { + sx: { + border: !rowSelected && cellSelected ? `2px dashed ${theme.palette.action.selected}` : undefined, + }, + }; + }, renderTopToolbarCustomActions: () => ( ), - enableBottomToolbar: enablePagination, + enableBottomToolbar: enableCursorBasedPagination, renderBottomToolbarCustomActions: () => ( ( - <> +
{ + const newSelection: Selection = { + entries: [ + { + id: row.original.targetObjectId, + kind: row.original.targetObjectKind, + }, + ], + }; + setSelection(newSelection); + }}> {enableRowSizing ? ( ) : null} - +
), }; diff --git a/packages/tables/frontend/sirius-components-tables/src/table/TableContent.types.ts b/packages/tables/frontend/sirius-components-tables/src/table/TableContent.types.ts index b7259cd642..d2b7f52ffd 100644 --- a/packages/tables/frontend/sirius-components-tables/src/table/TableContent.types.ts +++ b/packages/tables/frontend/sirius-components-tables/src/table/TableContent.types.ts @@ -25,7 +25,7 @@ export interface TableProps { enableColumnFilters: boolean; enableRowSizing: boolean; enableGlobalFilter: boolean; - enablePagination: boolean; + enableCursorBasedPagination: boolean; } export interface TablePaginationState { @@ -86,6 +86,7 @@ export interface GQLColumn { export interface GQLLine { id: string; targetObjectId: string; + targetObjectKind: string; cells: GQLCell[]; headerLabel: string; headerIconURLs: string[]; @@ -104,6 +105,8 @@ export interface GQLCell { __typename: string; id: string; columnId: string; + targetObjectId: string; + targetObjectKind: string; } export interface GQLTextfieldCell extends GQLCell {