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 Dec 30, 2024
1 parent 4b778e9 commit 4078b91
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 20 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

=== 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
Expand Up @@ -46,7 +46,7 @@ export const TableWidgetPropertySection: PropertySectionComponent<GQLTableWidget
enableColumnFilters={false}
enableRowSizing={false}
enableGlobalFilter={false}
enablePagination={false}
enableCursorBasedPagination={false}
/>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Up @@ -81,7 +81,7 @@ export const useTableColumnFiltering = (

if (!enableColumnFilters) {
return {
columnFilters: undefined,
columnFilters: [],
setColumnFilters: undefined,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export const TableRepresentation = ({ editingContextId, representationId, readOn
enableColumnFilters
enableRowSizing
enableGlobalFilter
enablePagination
enableCursorBasedPagination
/>
) : null}
{completeMessage}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,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: () => (
<Box>
<SettingsButton editingContextId={editingContextId} representationId={representationId} table={table} />
</Box>
),
enableBottomToolbar: enablePagination,
enableBottomToolbar: enableCursorBasedPagination,
renderBottomToolbarCustomActions: () => (
<CursorBasedPagination
hasPrev={table.paginationData.hasPreviousPage}
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
Expand Up @@ -25,7 +25,7 @@ export interface TableProps {
enableColumnFilters: boolean;
enableRowSizing: boolean;
enableGlobalFilter: boolean;
enablePagination: boolean;
enableCursorBasedPagination: boolean;
}

export interface TablePaginationState {
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 4078b91

Please sign in to comment.