Skip to content

Commit

Permalink
[4345] Make table cells independently selectable
Browse files Browse the repository at this point in the history
Bug: #4345
Signed-off-by: Florian ROUËNÉ <[email protected]>
  • Loading branch information
frouene committed Jan 3, 2025
1 parent 00cbf2b commit b4a92ec
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 15 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,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

Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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,
Expand All @@ -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 = (
<CheckboxCell
editingContextId={editingContextId}
representationId={representationId}
Expand All @@ -47,7 +62,7 @@ export const Cell = memo(({ editingContextId, representationId, tableId, cell, d
/>
);
} else if (isTextfieldCell(cell)) {
return (
cellContent = (
<TextfieldCell
editingContextId={editingContextId}
representationId={representationId}
Expand All @@ -57,7 +72,7 @@ export const Cell = memo(({ editingContextId, representationId, tableId, cell, d
/>
);
} else if (isSelectCell(cell)) {
return (
cellContent = (
<SelectCell
editingContextId={editingContextId}
representationId={representationId}
Expand All @@ -67,7 +82,7 @@ export const Cell = memo(({ editingContextId, representationId, tableId, cell, d
/>
);
} else if (isMultiSelectCell(cell)) {
return (
cellContent = (
<MultiSelectCell
editingContextId={editingContextId}
representationId={representationId}
Expand All @@ -77,7 +92,7 @@ export const Cell = memo(({ editingContextId, representationId, tableId, cell, d
/>
);
} else if (isIconLabelCell(cell)) {
return (
cellContent = (
<IconLabelCell
editingContextId={editingContextId}
representationId={representationId}
Expand All @@ -86,6 +101,13 @@ export const Cell = memo(({ editingContextId, representationId, tableId, cell, d
/>
);
}
if (cellContent) {
return (
<div className={classes.cell} onClick={onClick}>
{cellContent}
</div>
);
}
}
return <Typography></Typography>;
});
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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';
Expand Down Expand Up @@ -43,6 +44,7 @@ export const TableContent = memo(
enablePagination,
}: TableProps) => {
const { selection, setSelection } = useSelection();
const theme: Theme = useTheme();

const { columns } = useTableColumns(
editingContextId,
Expand Down Expand Up @@ -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
Expand All @@ -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: () => (
<Box>
<SettingsButton editingContextId={editingContextId} representationId={representationId} table={table} />
Expand All @@ -200,7 +211,18 @@ export const TableContent = memo(
},
},
renderRowActions: ({ row }) => (
<>
<div
onClick={() => {
const newSelection: Selection = {
entries: [
{
id: row.original.targetObjectId,
kind: row.original.targetObjectKind,
},
],
};
setSelection(newSelection);
}}>
<RowHeader row={row.original} />
{enableRowSizing ? (
<ResizeRowHandler
Expand All @@ -212,7 +234,7 @@ export const TableContent = memo(
onRowHeightChanged={handleRowHeightChange}
/>
) : null}
</>
</div>
),
};

Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -86,6 +86,7 @@ export interface GQLColumn {
export interface GQLLine {
id: string;
targetObjectId: string;
targetObjectKind: string;
cells: GQLCell[];
headerLabel: string;
headerIconURLs: string[];
Expand All @@ -104,6 +105,8 @@ export interface GQLCell {
__typename: string;
id: string;
columnId: string;
targetObjectId: string;
targetObjectKind: string;
}

export interface GQLTextfieldCell extends GQLCell {
Expand Down

0 comments on commit b4a92ec

Please sign in to comment.