diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index bde2eaa9e7..3a8a8ee40d 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -31,7 +31,7 @@ The `start` task used in our turbo configuration is now marked as `persistent` a === Improvements - +- https://github.com/eclipse-sirius/sirius-web/issues/4345[#4345] [table] Make table cells independently selectable == v2025.1.0 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..c5131a3c14 100644 --- a/packages/tables/frontend/sirius-components-tables/src/table/TableContent.tsx +++ b/packages/tables/frontend/sirius-components-tables/src/table/TableContent.tsx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 Obeo. + * Copyright (c) 2024, 2025 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -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'; @@ -43,6 +44,7 @@ export const TableContent = memo( enablePagination, }: TableProps) => { const { selection, setSelection } = useSelection(); + const theme: Theme = useTheme(); const { columns } = useTableColumns( editingContextId, @@ -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,6 +175,19 @@ 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: () => ( @@ -200,7 +211,18 @@ export const TableContent = memo( }, }, renderRowActions: ({ row }) => ( - <> +
{ + 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..a189ad202d 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 Obeo. + * Copyright (c) 2024, 2025 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -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 { diff --git a/packages/tables/frontend/sirius-components-tables/src/table/useTableColumns.tsx b/packages/tables/frontend/sirius-components-tables/src/table/useTableColumns.tsx index f1b2e09a1e..a7dd6e5847 100644 --- a/packages/tables/frontend/sirius-components-tables/src/table/useTableColumns.tsx +++ b/packages/tables/frontend/sirius-components-tables/src/table/useTableColumns.tsx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 Obeo. + * Copyright (c) 2024, 2025 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,13 +10,21 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ +import { Selection, useSelection } from '@eclipse-sirius/sirius-components-core'; import { MRT_ColumnDef } from 'material-react-table'; import { useMemo } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { Cell } from '../cells/Cell'; import { ColumnHeader } from '../columns/ColumnHeader'; import { GQLCell, GQLLine, GQLTable } from './TableContent.types'; import { UseTableColumnsValue } from './useTableColumns.types'; +const useStyles = makeStyles()(() => ({ + cell: { + width: '100%', + }, +})); + export const useTableColumns = ( editingContextId: string, representationId: string, @@ -26,6 +34,8 @@ export const useTableColumns = ( enableColumnSizing: boolean, enableColumnFilters: boolean ): UseTableColumnsValue => { + const { classes } = useStyles(); + const { setSelection } = useSelection(); const columns = useMemo[]>(() => { const columnDefs: MRT_ColumnDef[] = table.columns.map((column) => { return { @@ -41,14 +51,22 @@ export const useTableColumns = ( visibleInShowHideMenu: enableColumnVisibility, Cell: ({ row }) => { const cell: GQLCell | null = row.original.cells.find((cell) => column.id === cell.columnId) ?? null; + const onClick = () => { + if (cell) { + const newSelection: Selection = { entries: [{ id: cell.targetObjectId, kind: cell.targetObjectKind }] }; + setSelection(newSelection); + } + }; return ( - +
+ +
); }, };