diff --git a/samples/grids/grid/disabled-summaries/src/index.css b/samples/grids/grid/disabled-summaries/src/index.css index 03040d6bba..c112b91ee9 100644 --- a/samples/grids/grid/disabled-summaries/src/index.css +++ b/samples/grids/grid/disabled-summaries/src/index.css @@ -17,28 +17,47 @@ font-weight: bold; } -.grid-wrapper .summary-button { +.grid-wrapper .summary-column-button { + position: relative; margin-right: 1rem; + margin-bottom: 0.5rem; } -igc-dialog { +.summaries-dropdown { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + background: white; border: 1px solid #e0e0e0; - border-radius: 8px; + border-radius: 4px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + min-width: 200px; + padding: 8px 0; } -igc-dialog::part(title) { +.summaries-dropdown-title { + padding: 8px 16px; + margin: 0; + font-weight: 600; color: #1E6DFE; + border-bottom: 1px solid #e0e0e0; } -.summaries-dialog-items { +.summaries-dropdown-items { display: flex; flex-direction: column; - align-items: flex-start; + padding: 8px 0; } -.summaries-dialog-items .summaries-dialog-item { +.summaries-dropdown-item { + padding: 4px 16px; +} + +.summaries-dropdown-buttons { display: flex; - align-items: center; - padding: 0 1rem; + justify-content: space-between; + padding: 8px 16px; + border-top: 1px solid #e0e0e0; } diff --git a/samples/grids/grid/disabled-summaries/src/index.tsx b/samples/grids/grid/disabled-summaries/src/index.tsx index 1c6f605c0c..099bc98a26 100644 --- a/samples/grids/grid/disabled-summaries/src/index.tsx +++ b/samples/grids/grid/disabled-summaries/src/index.tsx @@ -2,12 +2,14 @@ import React, { useEffect, useState } from "react"; import ReactDOM from "react-dom/client"; import "./index.css"; -import { IgrButton, IgrDialog, IgrCheckbox } from "igniteui-react"; +import { IgrButton, IgrCheckbox } from "igniteui-react"; import { IgrGrid, IgrColumn, IgrSummaryOperand, IgrSummaryResult, + IgrNumberSummaryOperand, + IgrDateSummaryOperand, } from "igniteui-react-grids"; import NwindData from "./NwindData.json"; @@ -122,385 +124,174 @@ class DiscontinuedSummary extends IgrSummaryOperand { } } -interface SummaryColumn { +interface SummaryCheckbox { + summaryKey: string; + summaryLabel: string; + checked: boolean; +} + +interface ColumnConfig { + label: string; field: string; - header: string; - hasSummary: boolean; - dataType?: string; - summaries?: any; - disabledSummaries: string[]; + dataType?: "string" | "number" | "boolean" | "date"; + summaryClass?: any; + summaries: SummaryCheckbox[]; } export default function DisabledSummariesSample() { - // State const [nwindData, setNwindData] = useState([]); - const [currentColumn, setCurrentColumn] = useState( - null - ); - const [currentColumnSource, setCurrentColumnSource] = useState< - "dialog" | "toggle" | null - >(null); - const [pendingUpdateType, setPendingUpdateType] = useState< - null | "disableAll" | "enableAll" - >(null); - const [disableAllBtnDisabled, setDisableAllBtnDisabled] = useState(false); - const [enableAllBtnDisabled, setEnableAllBtnDisabled] = useState(false); - const [checkboxStates, setCheckboxStates] = useState([]); - const [columns, setColumns] = useState([ - { - field: "ProductID", - header: "ProductID", - hasSummary: true, - disabledSummaries: [], - }, - { - field: "ProductName", - header: "Product Name", - hasSummary: true, - disabledSummaries: [], - }, - { - field: "UnitPrice", - header: "Unit Price", - hasSummary: true, - dataType: "number", - disabledSummaries: [], - }, - { - field: "UnitsInStock", - header: "Units In Stock", - hasSummary: true, - dataType: "number", - summaries: UnitsInStockSummary, - disabledSummaries: [], - }, - { - field: "Discontinued", - header: "Discontinued", - hasSummary: true, - summaries: DiscontinuedSummary, - disabledSummaries: [], - }, - { - field: "OrderDate", - header: "Order Date", - hasSummary: true, - dataType: "date", - disabledSummaries: [], - }, + const [openDropdownIndex, setOpenDropdownIndex] = useState(null); + const [columns, setColumns] = useState([ + { label: "Product ID", field: "ProductID", summaries: [] }, + { label: "Product Name", field: "ProductName", summaries: [] }, + { label: "Unit Price", field: "UnitPrice", dataType: "number", summaries: [] }, + { label: "Units In Stock", field: "UnitsInStock", dataType: "number", summaryClass: UnitsInStockSummary, summaries: [] }, + { label: "Discontinued", field: "Discontinued", summaryClass: DiscontinuedSummary, summaries: [] }, + { label: "Order Date", field: "OrderDate", dataType: "date", summaries: [] }, ]); - // Refs - let grid: IgrGrid; - const gridRef = (ref: IgrGrid) => { - grid = ref; - }; - let dialog: IgrDialog; - const dialogRef = (ref: IgrDialog) => { - dialog = ref; - if (dialog) { - dialog.closeOnOutsideClick = true; - dialog.keepOpenOnEscape = false; - } - }; - useEffect(() => { setNwindData(NwindData); }, []); useEffect(() => { - if (!currentColumn) return; - - const shouldShowDialog = currentColumnSource === "dialog"; - const shouldMarkForCheck = - currentColumnSource === "toggle" || - pendingUpdateType === "disableAll" || - pendingUpdateType === "enableAll"; - - if (shouldShowDialog) { - updateCheckboxes(); - dialog?.show(); - setCurrentColumnSource(null); - } - - if (shouldMarkForCheck && grid) { - updateCheckboxes(); - grid.markForCheck(); - setPendingUpdateType(null); - setCurrentColumnSource(null); + if (nwindData.length > 0 && columns[0].summaries.length === 0) { + initializeSummaries(); } - }, [currentColumn, currentColumnSource, pendingUpdateType, grid]); + }, [nwindData]); - const openDialog = (column: any) => { - const columnState = columns.find((c) => c.field === column.field); - setCurrentColumn(columnState!); - setCurrentColumnSource("dialog"); - setCheckboxStates([]); + const defaultSummaryOperands: Record IgrSummaryOperand> = { + number: IgrNumberSummaryOperand, + date: IgrDateSummaryOperand, }; - const getSummaryResults = ( - operand: any, - data: any[], - field: string - ): IgrSummaryResult[] => { - if (typeof operand === "function") { - operand = new operand(); - } - if (operand instanceof IgrSummaryOperand) { - return operand.operate([], data, field, null); - } else if (!operand) { - return new IgrSummaryOperand().operate([], data, field, null); - } - return []; - }; - - const getDefaultSummaries = ( - data: any[], - field: string - ): IgrSummaryResult[] => { - const columnInstance = grid.columns.find((c) => c.field === field); - if ( - columnInstance && - columnInstance.summaries && - typeof columnInstance.summaries.operate === "function" - ) { - return columnInstance.summaries.operate([], data, field, null); - } - return []; + const getSummaries = (column: ColumnConfig): SummaryCheckbox[] => { + const OperandClass = column.summaryClass ?? defaultSummaryOperands[column.dataType!] ?? IgrSummaryOperand; + const summaryResults = new OperandClass().operate([], nwindData, column.field, null); + return summaryResults.map((summary: IgrSummaryResult) => ({ + summaryKey: summary.key, + summaryLabel: summary.label, + checked: true, + })); }; - const updateCheckboxes = () => { - if (!currentColumn || !grid) return; + const initializeSummaries = () => { + if (nwindData.length === 0) return; - const gridData: any[] = grid.data; - let allSummaries: IgrSummaryResult[] = []; - if (currentColumn.summaries) { - allSummaries = getSummaryResults( - currentColumn.summaries, - gridData, - currentColumn.field - ); - } else { - allSummaries = getDefaultSummaries(gridData, currentColumn.field); - } - - let allDisabled: boolean = true; - let allEnabled: boolean = true; - - const newCheckboxStates: any[] = allSummaries.map((summary) => { - const isDisabled = currentColumn.disabledSummaries.includes(summary.key); - if (isDisabled) { - allEnabled = false; - } else { - allDisabled = false; - } - return { - label: summary.label, - key: summary.key, - checked: isDisabled, - }; - }); + const updatedColumns = columns.map((column) => ({ + ...column, + summaries: getSummaries(column), + })); - setCheckboxStates(newCheckboxStates); - setDisableAllBtnDisabled(allDisabled); - setEnableAllBtnDisabled(allEnabled); + setColumns(updatedColumns); }; - const toggleSummary = (summaryKey: string) => { - if (!currentColumn || !grid) return; + const getCheckedSummariesCount = (summaries: SummaryCheckbox[]): number => { + return summaries.filter((item) => item.checked).length; + }; - const updatedDisabledSummaries = currentColumn.disabledSummaries.includes( - summaryKey - ) - ? currentColumn.disabledSummaries.filter((key: any) => key !== summaryKey) - : [...currentColumn.disabledSummaries, summaryKey]; + const getDisabledSummaries = (summaries: SummaryCheckbox[]): string[] => { + return summaries.filter((item) => !item.checked).map((item) => item.summaryKey); + }; - const updatedColumns = columns.map((col: any) => - col.field === currentColumn.field - ? { ...col, disabledSummaries: updatedDisabledSummaries } - : col - ); + const toggleDropdown = (index: number) => { + setOpenDropdownIndex(openDropdownIndex === index ? null : index); + }; - setCurrentColumn((prev) => ({ - ...prev, - disabledSummaries: updatedDisabledSummaries, - })); + const toggleCheckbox = (columnIndex: number, summaryIndex: number) => { + const updatedColumns = [...columns]; + const column = updatedColumns[columnIndex]; + column.summaries[summaryIndex].checked = !column.summaries[summaryIndex].checked; setColumns(updatedColumns); - setCurrentColumnSource("toggle"); }; - const disableAllSummaries = () => { - if (!currentColumn || !grid) return; - - const gridData: any[] = grid.data; - let allSummaries: IgrSummaryResult[] = currentColumn.summaries - ? getSummaryResults( - currentColumn.summaries, - gridData, - currentColumn.field - ) - : getDefaultSummaries(gridData, currentColumn.field); - - const allSummaryKeys: string[] = allSummaries.map((s) => s.key); - - const updatedColumns = columns.map((col: any) => - col.field === currentColumn.field - ? { ...col, disabledSummaries: allSummaryKeys } - : col - ); - - setCurrentColumn((prev) => ({ - ...prev, - disabledSummaries: allSummaryKeys, - })); + const uncheckAllColumns = (columnIndex: number) => { + const updatedColumns = [...columns]; + const column = updatedColumns[columnIndex]; + column.summaries.forEach((item) => (item.checked = false)); setColumns(updatedColumns); - setDisableAllBtnDisabled(true); - setEnableAllBtnDisabled(false); - - setPendingUpdateType("disableAll"); }; - const enableAllSummaries = () => { - if (!currentColumn || !grid) return; - - const updatedColumns = columns.map((col: any) => - col.field === currentColumn.field - ? { ...col, disabledSummaries: [] } - : col - ); - - setCurrentColumn((prev) => ({ ...prev, disabledSummaries: [] })); + const checkAllColumns = (columnIndex: number) => { + const updatedColumns = [...columns]; + const column = updatedColumns[columnIndex]; + column.summaries.forEach((item) => (item.checked = true)); setColumns(updatedColumns); - setDisableAllBtnDisabled(false); - setEnableAllBtnDisabled(true); - - setPendingUpdateType("enableAll"); }; return (
-

Disable Summaries for Column:

- {columns.map((col: any) => ( - openDialog({ field: col.field, header: col.header })} - > - {col.header} - +
Toggle Summaries for Column:
+ {columns.map((column, columnIndex) => ( +
+ toggleDropdown(columnIndex)} + > + + {column.label} ({getCheckedSummariesCount(column.summaries)}) + + + {openDropdownIndex === columnIndex && ( +
+

Disabled Summaries

+
+ {column.summaries.map((summary, summaryIndex) => ( + toggleCheckbox(columnIndex, summaryIndex)} + > + {summary.summaryLabel} + + ))} +
+
+ uncheckAllColumns(columnIndex)} + > + Disable All + + checkAllColumns(columnIndex)} + > + Enable All + +
+
+ )} +
))}
- -
- {currentColumn && - checkboxStates.map((checkbox: any) => ( - toggleSummary(checkbox.key)} - > - {checkbox.label} - - ))} -
- - Disable All - - - Enable All - -
-
- - col.field === "ProductID") - ?.disabledSummaries - } - > - col.field === "ProductName") - ?.disabledSummaries - } - > - col.field === "UnitPrice") - ?.disabledSummaries - } - > - col.field === "UnitsInStock") - ?.disabledSummaries - } - > - col.field === "Discontinued") - ?.disabledSummaries - } - > + + {columns.map((column) => ( col.field === "OrderDate") - ?.disabledSummaries - } - > - -
+ summaries={column.summaryClass} + disabledSummaries={getDisabledSummaries(column.summaries)} + /> + ))} +
); }