From d93da22672dc08658d48d5521eb6398ce6e5a7cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20B=C3=A9gaudeau?= Date: Thu, 19 Dec 2024 14:26:20 +0100 Subject: [PATCH] [4305] Allow the deactivation of table features useless in some contexts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: https://github.com/eclipse-sirius/sirius-web/issues/4305 Signed-off-by: Stéphane Bégaudeau --- CHANGELOG.adoc | 1 + .../src/form/FormEventFragments.ts | 28 +++++++- .../TableWidgetPropertySection.tsx | 6 ++ .../src/columns/useTableColumnFiltering.ts | 16 +++-- .../columns/useTableColumnFiltering.types.ts | 9 +-- .../src/columns/useTableColumnSizing.ts | 20 ++++-- .../src/columns/useTableColumnSizing.types.ts | 8 ++- .../src/columns/useTableColumnVisibility.ts | 26 ++++--- .../columns/useTableColumnVisibility.types.ts | 10 +-- .../representation/TableRepresentation.tsx | 6 ++ .../src/rows/useResetRows.ts | 19 +++--- .../src/table/TableContent.tsx | 68 +++++++++++++------ .../src/table/TableContent.types.ts | 6 ++ .../src/table/useGlobalFilter.ts | 16 ++++- .../src/table/useGlobalFilter.types.ts | 6 +- .../src/table/useTableColumns.tsx | 12 ++-- 16 files changed, 190 insertions(+), 67 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index baa9ba328a..0a9287463a 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -64,6 +64,7 @@ This was first fixed in 2022.3.0 but broken in 2024.3.0; it is now fixed again. + Fix Explorer + Contribute the Ellipse node + Contribute the Selection Dialog +- https://github.com/eclipse-sirius/sirius-web/issues/4305[#4305] [table] Allow the deactivation of table features that are not used in some contexts === New Features diff --git a/packages/forms/frontend/sirius-components-forms/src/form/FormEventFragments.ts b/packages/forms/frontend/sirius-components-forms/src/form/FormEventFragments.ts index cf7eaf840d..91b17f77c9 100644 --- a/packages/forms/frontend/sirius-components-forms/src/form/FormEventFragments.ts +++ b/packages/forms/frontend/sirius-components-forms/src/form/FormEventFragments.ts @@ -326,16 +326,38 @@ export const widgetFields = ` iconURL table { id + paginationData { + hasPreviousPage + hasNextPage + totalRowCount + } + stripeRow + globalFilter + columnFilters { + id + value + } columns { id headerLabel + headerIconURLs + headerIndexLabel targetObjectId - targetObjectKind + targetObjectKind + width + isResizable + hidden + filterVariant } lines { id targetObjectId targetObjectKind + headerLabel + headerIconURLs + headerIndexLabel + height + isResizable cells { __typename id @@ -362,6 +384,10 @@ export const widgetFields = ` ... on TextfieldCell { stringValue: value } + ... on IconLabelCell { + label: value + iconURLs + } } } } 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 2d68d13b69..a728753a87 100644 --- a/packages/forms/frontend/sirius-components-forms/src/propertysections/TableWidgetPropertySection.tsx +++ b/packages/forms/frontend/sirius-components-forms/src/propertysections/TableWidgetPropertySection.tsx @@ -41,6 +41,12 @@ export const TableWidgetPropertySection: PropertySectionComponent {}} onGlobalFilterChange={() => {}} onColumnFiltersChange={() => {}} + enableColumnVisibility={false} + enableColumnResizing={false} + enableColumnFilters={false} + enableRowSizing={false} + enableGlobalFilter={false} + enablePagination={false} /> ); 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 f89592e74e..9b89372016 100644 --- a/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnFiltering.ts +++ b/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnFiltering.ts @@ -14,13 +14,13 @@ import { gql, useMutation } from '@apollo/client'; import { useReporting } from '@eclipse-sirius/sirius-components-core'; import { MRT_ColumnFiltersState } from 'material-react-table'; import { useEffect, useState } from 'react'; +import { ColumnFilter, GQLTable } from '../table/TableContent.types'; import { GQLChangeColumnFilterData, - GQLChangeColumnFilterVariables, GQLChangeColumnFilterInput, + GQLChangeColumnFilterVariables, UseTableColumnFilteringValue, } from './useTableColumnFiltering.types'; -import { ColumnFilter, GQLTable } from '../table/TableContent.types'; const changeColumnFilterMutation = gql` mutation changeColumnFilter($input: ChangeColumnFilterInput!) { @@ -46,12 +46,13 @@ export const useTableColumnFiltering = ( editingContextId: string, representationId: string, table: GQLTable, - onColumnFiltersChange?: (columFilters: ColumnFilter[]) => void + onColumnFiltersChange: (columFilters: ColumnFilter[]) => void, + enableColumnFilters: boolean ): UseTableColumnFilteringValue => { const [columnFilters, setColumnFilters] = useState(table.columnFilters); useEffect(() => { - if (onColumnFiltersChange) { + if (enableColumnFilters) { changeColumnFilter(columnFilters); onColumnFiltersChange(columnFilters); } @@ -78,6 +79,13 @@ export const useTableColumnFiltering = ( mutationChangeColumnFilter({ variables: { input } }); }; + if (!enableColumnFilters) { + return { + columnFilters: undefined, + setColumnFilters: undefined, + }; + } + return { columnFilters, setColumnFilters, diff --git a/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnFiltering.types.ts b/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnFiltering.types.ts index 59a35874ef..baaf80bd7b 100644 --- a/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnFiltering.types.ts +++ b/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnFiltering.types.ts @@ -13,11 +13,12 @@ import { GQLErrorPayload, GQLSuccessPayload } from '@eclipse-sirius/sirius-components-core'; import { MRT_ColumnFiltersState } from 'material-react-table'; +export type ColumnFilterSetter = ( + columnFilters: MRT_ColumnFiltersState | ((prevState: MRT_ColumnFiltersState) => MRT_ColumnFiltersState) +) => void; export interface UseTableColumnFilteringValue { - columnFilters: MRT_ColumnFiltersState; - setColumnFilters: ( - columnFilters: MRT_ColumnFiltersState | ((prevState: MRT_ColumnFiltersState) => MRT_ColumnFiltersState) - ) => void; + columnFilters: MRT_ColumnFiltersState | undefined; + setColumnFilters: ColumnFilterSetter | undefined; } export interface GQLChangeColumnFilterInput { diff --git a/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnSizing.ts b/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnSizing.ts index b2b45ee716..bc6140b8ca 100644 --- a/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnSizing.ts +++ b/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnSizing.ts @@ -16,10 +16,10 @@ import { MRT_ColumnSizingState } from 'material-react-table'; import { useEffect, useState } from 'react'; import { GQLTable } from '../table/TableContent.types'; import { - UseTableColumnSizingValue, GQLResizeColumnData, - GQLResizeColumnVariables, GQLResizeColumnInput, + GQLResizeColumnVariables, + UseTableColumnSizingValue, } from './useTableColumnSizing.types'; const resizeColumnMutation = gql` @@ -45,13 +45,16 @@ const resizeColumnMutation = gql` export const useTableColumnSizing = ( editingContextId: string, representationId: string, - table: GQLTable + table: GQLTable, + enableColumnSizing: boolean ): UseTableColumnSizingValue => { const [columnSizing, setColumnSizing] = useState({}); useEffect(() => { - for (const [columnName, columnSize] of Object.entries(columnSizing)) { - resizeColumn(columnName, columnSize); + if (enableColumnSizing) { + for (const [columnName, columnSize] of Object.entries(columnSizing)) { + resizeColumn(columnName, columnSize); + } } }, [columnSizing]); @@ -79,6 +82,13 @@ export const useTableColumnSizing = ( mutationResizeColumn({ variables: { input } }); }; + if (!enableColumnSizing) { + return { + columnSizing: {}, + setColumnSizing: undefined, + }; + } + return { columnSizing, setColumnSizing, diff --git a/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnSizing.types.ts b/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnSizing.types.ts index 09e5b54c71..abf828b53b 100644 --- a/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnSizing.types.ts +++ b/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnSizing.types.ts @@ -13,11 +13,13 @@ import { GQLErrorPayload, GQLSuccessPayload } from '@eclipse-sirius/sirius-components-core'; import { MRT_ColumnSizingState } from 'material-react-table'; +export type ColumnSizingSetter = ( + columnSizing: MRT_ColumnSizingState | ((prevState: MRT_ColumnSizingState) => MRT_ColumnSizingState) +) => void; + export interface UseTableColumnSizingValue { columnSizing: MRT_ColumnSizingState; - setColumnSizing: ( - columnSizing: MRT_ColumnSizingState | ((prevState: MRT_ColumnSizingState) => MRT_ColumnSizingState) - ) => void; + setColumnSizing: ColumnSizingSetter | undefined; } export interface GQLResizeColumnInput { diff --git a/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnVisibility.ts b/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnVisibility.ts index 98ebc09bb0..ffe891d45d 100644 --- a/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnVisibility.ts +++ b/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnVisibility.ts @@ -17,9 +17,9 @@ import { useEffect, useState } from 'react'; import { GQLTable } from '../table/TableContent.types'; import { GQLChangeColumnVisibilityData, + GQLChangeColumnVisibilityInput, GQLChangeColumnVisibilityVariables, GQLColumnVisibility, - GQLChangeColumnVisibilityInput, UseTableColumnVisibilityValue, } from './useTableColumnVisibility.types'; @@ -46,7 +46,8 @@ export const changeColumnVisibilityMutation = gql` export const useTableColumnVisibility = ( editingContextId: string, representationId: string, - table: GQLTable + table: GQLTable, + enableColumnVisibility: boolean ): UseTableColumnVisibilityValue => { const [columnVisibility, setColumnVisibility] = useState( table.columns.reduce((acc, obj) => { @@ -56,12 +57,14 @@ export const useTableColumnVisibility = ( ); useEffect(() => { - changeColumnVisibility( - Object.entries(columnVisibility).map(([columnId, visible]) => ({ - columnId, - visible, - })) - ); + if (enableColumnVisibility) { + changeColumnVisibility( + Object.entries(columnVisibility).map(([columnId, visible]) => ({ + columnId, + visible, + })) + ); + } }, [columnVisibility]); useEffect(() => { @@ -94,6 +97,13 @@ export const useTableColumnVisibility = ( mutationChangeColumnVisibility({ variables: { input } }); }; + if (!enableColumnVisibility) { + return { + columnVisibility: undefined, + setColumnVisibility: undefined, + }; + } + return { columnVisibility, setColumnVisibility, diff --git a/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnVisibility.types.ts b/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnVisibility.types.ts index cee1514a08..41dde67c09 100644 --- a/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnVisibility.types.ts +++ b/packages/tables/frontend/sirius-components-tables/src/columns/useTableColumnVisibility.types.ts @@ -13,11 +13,13 @@ import { GQLErrorPayload, GQLSuccessPayload } from '@eclipse-sirius/sirius-components-core'; import { MRT_VisibilityState } from 'material-react-table'; +export type ColumnVisibilitySetter = ( + columnVisibility: MRT_VisibilityState | ((prevState: MRT_VisibilityState) => MRT_VisibilityState) +) => void; + export interface UseTableColumnVisibilityValue { - columnVisibility: MRT_VisibilityState; - setColumnVisibility: ( - columnVisibility: MRT_VisibilityState | ((prevState: MRT_VisibilityState) => MRT_VisibilityState) - ) => void; + columnVisibility: MRT_VisibilityState | undefined; + setColumnVisibility: ColumnVisibilitySetter | undefined; } export interface GQLChangeColumnVisibilityInput { 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 a35eed9778..3a297085c9 100644 --- a/packages/tables/frontend/sirius-components-tables/src/representation/TableRepresentation.tsx +++ b/packages/tables/frontend/sirius-components-tables/src/representation/TableRepresentation.tsx @@ -83,6 +83,12 @@ export const TableRepresentation = ({ editingContextId, representationId, readOn onPaginationChange={onPaginationChange} onGlobalFilterChange={onGlobalFilterChange} onColumnFiltersChange={onColumnFiltersChange} + enableColumnVisibility + enableColumnResizing + enableColumnFilters + enableRowSizing + enableGlobalFilter + enablePagination /> ) : null} {completeMessage} diff --git a/packages/tables/frontend/sirius-components-tables/src/rows/useResetRows.ts b/packages/tables/frontend/sirius-components-tables/src/rows/useResetRows.ts index 4a19bbf4e0..08bf10e941 100644 --- a/packages/tables/frontend/sirius-components-tables/src/rows/useResetRows.ts +++ b/packages/tables/frontend/sirius-components-tables/src/rows/useResetRows.ts @@ -42,7 +42,8 @@ export const resetRowsHeightMutation = gql` export const useResetRowsMutation = ( editingContextId: string, representationId: string, - tableId: string + tableId: string, + enableRowSizing: boolean ): UseResetRowsMutationValue => { const [mutationResetRowsHeight, mutationResetRowsHeightResult] = useMutation< GQLResetRowsHeightData, @@ -51,14 +52,16 @@ export const useResetRowsMutation = ( useReporting(mutationResetRowsHeightResult, (data: GQLResetRowsHeightData) => data.resetTableRowsHeight); const resetRowsHeight = () => { - const input: GQLResetRowsHeightInput = { - id: crypto.randomUUID(), - editingContextId, - representationId, - tableId, - }; + if (enableRowSizing) { + const input: GQLResetRowsHeightInput = { + id: crypto.randomUUID(), + editingContextId, + representationId, + tableId, + }; - mutationResetRowsHeight({ variables: { input } }); + mutationResetRowsHeight({ variables: { input } }); + } }; return { 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 f13c6ff623..c85bf29492 100644 --- a/packages/tables/frontend/sirius-components-tables/src/table/TableContent.tsx +++ b/packages/tables/frontend/sirius-components-tables/src/table/TableContent.tsx @@ -35,26 +35,47 @@ export const TableContent = memo( onPaginationChange, onGlobalFilterChange, onColumnFiltersChange, + enableColumnVisibility, + enableColumnResizing, + enableColumnFilters, + enableRowSizing, + enableGlobalFilter, + enablePagination, }: TableProps) => { const { selection, setSelection } = useSelection(); - const { columns } = useTableColumns(editingContextId, representationId, table, readOnly); - const { columnSizing, setColumnSizing } = useTableColumnSizing(editingContextId, representationId, table); + const { columns } = useTableColumns( + editingContextId, + representationId, + table, + readOnly, + enableColumnVisibility, + enableColumnResizing, + enableColumnFilters + ); + const { columnSizing, setColumnSizing } = useTableColumnSizing( + editingContextId, + representationId, + table, + enableColumnResizing + ); const { columnVisibility, setColumnVisibility } = useTableColumnVisibility( editingContextId, representationId, - table + table, + enableColumnVisibility ); const { columnFilters, setColumnFilters } = useTableColumnFiltering( editingContextId, representationId, table, - onColumnFiltersChange + onColumnFiltersChange, + enableColumnFilters ); const [density, setDensity] = useState('comfortable'); const [linesState, setLinesState] = useState(table.lines); - const { resetRowsHeight } = useResetRowsMutation(editingContextId, representationId, table.id); + const { resetRowsHeight } = useResetRowsMutation(editingContextId, representationId, table.id, enableRowSizing); const [pagination, setPagination] = useState({ size: 10, @@ -97,15 +118,14 @@ export const TableContent = memo( editingContextId, representationId, table, - onGlobalFilterChange + onGlobalFilterChange, + enableGlobalFilter ); useEffect(() => { onPaginationChange(pagination.cursor, pagination.direction, pagination.size); }, [pagination.cursor, pagination.size, pagination.direction]); - const serverSidePagination: boolean = onPaginationChange !== undefined; - const handleRowHeightChange = (rowId, height) => { setLinesState((prev) => prev.map((line) => (line.id === rowId ? { ...line, height } : line))); }; @@ -127,14 +147,18 @@ export const TableContent = memo( enableEditing: !readOnly, onColumnFiltersChange: setColumnFilters, enableStickyHeader: true, - enablePagination: !serverSidePagination, - manualPagination: serverSidePagination, + enablePagination, + manualPagination: enablePagination, rowCount: table.paginationData.totalRowCount, enableRowActions: true, + enableColumnFilters, + enableHiding: enableColumnVisibility, enableSorting: false, + enableColumnResizing, + enableGlobalFilter, manualFiltering: true, onGlobalFilterChange: setGlobalFilter, - initialState: { showGlobalFilter: true }, + initialState: { showGlobalFilter: enableGlobalFilter }, onColumnSizingChange: setColumnSizing, onColumnVisibilityChange: setColumnVisibility, onDensityChange: setDensity, @@ -158,6 +182,7 @@ export const TableContent = memo( ), + enableBottomToolbar: enablePagination, renderBottomToolbarCustomActions: () => ( ( <> - + {enableRowSizing ? ( + + ) : null} ), }; @@ -199,8 +226,7 @@ export const TableContent = memo( }; } - const enableColumnResizing: boolean = table.columns.filter((column) => column.isResizable).length > 0; - if (enableColumnResizing) { + if (enableColumnResizing && table.columns.filter((column) => column.isResizable).length > 0) { tableOptions.enableColumnResizing = enableColumnResizing; tableOptions.columnResizeMode = 'onEnd'; } 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 884fffe38b..b7259cd642 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 @@ -20,6 +20,12 @@ export interface TableProps { onPaginationChange: (cursor: string | null, direction: 'PREV' | 'NEXT', size: number) => void; onGlobalFilterChange: (globalFilter: string) => void; onColumnFiltersChange: (columFilters: ColumnFilter[]) => void; + enableColumnVisibility: boolean; + enableColumnResizing: boolean; + enableColumnFilters: boolean; + enableRowSizing: boolean; + enableGlobalFilter: boolean; + enablePagination: boolean; } export interface TablePaginationState { diff --git a/packages/tables/frontend/sirius-components-tables/src/table/useGlobalFilter.ts b/packages/tables/frontend/sirius-components-tables/src/table/useGlobalFilter.ts index 5460bacbe5..49827bc7f8 100644 --- a/packages/tables/frontend/sirius-components-tables/src/table/useGlobalFilter.ts +++ b/packages/tables/frontend/sirius-components-tables/src/table/useGlobalFilter.ts @@ -44,13 +44,16 @@ export const useGlobalFilter = ( editingContextId: string, representationId: string, table: GQLTable, - onGlobalFilterChange: (globalFilter: string) => void + onGlobalFilterChange: (globalFilter: string) => void, + enableGlobalFilter: boolean ): UseGlobalFilterValue => { const [globalFilter, setGlobalFilter] = useState(table.globalFilter ?? ''); useEffect(() => { - changeGlobalFilterValue(globalFilter ?? ''); - onGlobalFilterChange(globalFilter ?? ''); + if (enableGlobalFilter) { + changeGlobalFilterValue(globalFilter ?? ''); + onGlobalFilterChange(globalFilter ?? ''); + } }, [globalFilter]); useEffect(() => { @@ -78,6 +81,13 @@ export const useGlobalFilter = ( mutationChangeGlobalFilterValue({ variables: { input } }); }; + if (!enableGlobalFilter) { + return { + globalFilter: undefined, + setGlobalFilter: undefined, + }; + } + return { globalFilter, setGlobalFilter, diff --git a/packages/tables/frontend/sirius-components-tables/src/table/useGlobalFilter.types.ts b/packages/tables/frontend/sirius-components-tables/src/table/useGlobalFilter.types.ts index 396bb5ba4a..9b23ba0ee5 100644 --- a/packages/tables/frontend/sirius-components-tables/src/table/useGlobalFilter.types.ts +++ b/packages/tables/frontend/sirius-components-tables/src/table/useGlobalFilter.types.ts @@ -12,9 +12,11 @@ *******************************************************************************/ import { GQLErrorPayload, GQLSuccessPayload } from '@eclipse-sirius/sirius-components-core'; +export type GlobalFilterSetter = (columnVisibility: string | ((prevState: string) => string)) => void; + export interface UseGlobalFilterValue { - globalFilter: string; - setGlobalFilter: (columnVisibility: string | ((prevState: string) => string)) => void; + globalFilter: string | undefined; + setGlobalFilter: GlobalFilterSetter | undefined; } export interface GQLChangeGlobalFilterValueInput { 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 9172cdd162..f1b2e09a1e 100644 --- a/packages/tables/frontend/sirius-components-tables/src/table/useTableColumns.tsx +++ b/packages/tables/frontend/sirius-components-tables/src/table/useTableColumns.tsx @@ -21,7 +21,10 @@ export const useTableColumns = ( editingContextId: string, representationId: string, table: GQLTable, - readOnly + readOnly: boolean, + enableColumnVisibility: boolean, + enableColumnSizing: boolean, + enableColumnFilters: boolean ): UseTableColumnsValue => { const columns = useMemo[]>(() => { const columnDefs: MRT_ColumnDef[] = table.columns.map((column) => { @@ -32,9 +35,10 @@ export const useTableColumns = ( Header: ({}) => { return ; }, - filterVariant: column.filterVariant, - size: column.width > 0 ? column.width : undefined, - enableResizing: column.isResizable, + filterVariant: enableColumnFilters ? column.filterVariant : undefined, + size: enableColumnSizing && column.width > 0 ? column.width : undefined, + enableResizing: enableColumnSizing && column.isResizable, + visibleInShowHideMenu: enableColumnVisibility, Cell: ({ row }) => { const cell: GQLCell | null = row.original.cells.find((cell) => column.id === cell.columnId) ?? null; return (