@alaarab/ogrid-react-material 2.1.3 → 2.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.js +1621 -11
- package/dist/types/DataGridTable/DataGridTable.styles.d.ts +7 -0
- package/dist/types/OGrid/OGrid.d.ts +1 -1
- package/dist/types/index.d.ts +40 -1
- package/package.json +4 -4
- package/dist/esm/ColumnChooser/ColumnChooser.js +0 -53
- package/dist/esm/ColumnHeaderFilter/ColumnHeaderFilter.js +0 -34
- package/dist/esm/ColumnHeaderFilter/MultiSelectFilterPopover.js +0 -17
- package/dist/esm/ColumnHeaderFilter/PeopleFilterPopover.js +0 -17
- package/dist/esm/ColumnHeaderFilter/TextFilterPopover.js +0 -15
- package/dist/esm/ColumnHeaderFilter/index.js +0 -1
- package/dist/esm/ColumnHeaderMenu/ColumnHeaderMenu.js +0 -61
- package/dist/esm/ColumnHeaderMenu/index.js +0 -1
- package/dist/esm/DataGridTable/DataGridTable.js +0 -416
- package/dist/esm/DataGridTable/DropIndicator.js +0 -15
- package/dist/esm/DataGridTable/EmptyState.js +0 -6
- package/dist/esm/DataGridTable/GridContextMenu.js +0 -25
- package/dist/esm/DataGridTable/InlineCellEditor.js +0 -6
- package/dist/esm/DataGridTable/LoadingOverlay.js +0 -14
- package/dist/esm/DataGridTable/StatusBar.js +0 -13
- package/dist/esm/OGrid/OGrid.js +0 -31
- package/dist/esm/OGrid/index.js +0 -1
- package/dist/esm/PaginationControls/PaginationControls.js +0 -35
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-injecting CSS for DataGridTable body cells.
|
|
3
|
+
* Uses native HTML elements with CSS classes instead of MUI sx prop,
|
|
4
|
+
* eliminating ~1000 Emotion resolutions per render.
|
|
5
|
+
* Injected once via <style> tag on first import.
|
|
6
|
+
*/
|
|
7
|
+
export declare function injectDataGridStyles(): void;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
export type { IOGridProps } from '@alaarab/ogrid-react';
|
|
3
|
-
export declare const OGrid: React.ForwardRefExoticComponent<import("@alaarab/ogrid-react").IOGridProps<unknown> & React.RefAttributes<import("@alaarab/ogrid-
|
|
3
|
+
export declare const OGrid: React.ForwardRefExoticComponent<import("@alaarab/ogrid-react").IOGridProps<unknown> & React.RefAttributes<import("@alaarab/ogrid-core").IOGridApi<unknown>>>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -4,4 +4,43 @@ export { ColumnChooser, type IColumnChooserProps } from './ColumnChooser/ColumnC
|
|
|
4
4
|
export { ColumnHeaderFilter, type IColumnHeaderFilterProps } from './ColumnHeaderFilter/ColumnHeaderFilter';
|
|
5
5
|
export { PaginationControls, type IPaginationControlsProps } from './PaginationControls/PaginationControls';
|
|
6
6
|
export { ColumnHeaderMenu, type ColumnHeaderMenuProps } from './ColumnHeaderMenu/ColumnHeaderMenu';
|
|
7
|
-
export
|
|
7
|
+
export { CHECKBOX_COLUMN_WIDTH, ROW_NUMBER_COLUMN_WIDTH, DEFAULT_MIN_COLUMN_WIDTH, CELL_PADDING, GRID_BORDER_RADIUS, } from '@alaarab/ogrid-react';
|
|
8
|
+
export type { ColumnFilterType, IColumnFilterDef, IColumnMeta, IColumnDef, IColumnGroupDef, IColumnDefinition, ICellValueChangedEvent, ICellEditorProps, CellEditorParams, IValueParserParams, UserLike, UserLikeInput, FilterValue, IFilters, IFetchParams, IPageResult, IDataSource, IGridColumnState, IOGridApi, IOGridDataGridProps, RowSelectionMode, RowId, IRowSelectionChangeEvent, StatusBarPanel, IStatusBarProps, IActiveCell, ISelectionRange, HeaderCell, HeaderRow, SideBarPanelId, ISideBarDef, IDateFilterValue, IVirtualScrollConfig, IColumnReorderConfig, } from '@alaarab/ogrid-react';
|
|
9
|
+
export { toUserLike, isInSelectionRange, normalizeSelectionRange } from '@alaarab/ogrid-react';
|
|
10
|
+
export { useFilterOptions, useOGrid, useActiveCell, useCellEditing, useContextMenu, useCellSelection, useClipboard, useRowSelection, useKeyboardNavigation, useUndoRedo, useDebounce, useFillHandle, useDataGridState, useColumnHeaderFilterState, useTextFilterState, useMultiSelectFilterState, usePeopleFilterState, useDateFilterState, useColumnChooserState, useInlineCellEditorState, useColumnResize, useRichSelectState, useSelectState, useSideBarState, useTableLayout, useColumnReorder, useVirtualScroll, useListVirtualizer, useLatestRef, usePaginationControls, useDataGridTableOrchestration, useColumnMeta, } from '@alaarab/ogrid-react';
|
|
11
|
+
export type { UseFilterOptionsResult, UseOGridResult, UseOGridPagination, UseOGridColumnChooser, UseOGridLayout, UseOGridFilters, ColumnChooserPlacement, UseActiveCellResult, UseCellEditingResult, EditingCell, UseContextMenuResult, ContextMenuPosition, UseCellSelectionResult, UseCellSelectionParams, UseClipboardResult, UseClipboardParams, UseRowSelectionResult, UseRowSelectionParams, UseKeyboardNavigationResult, UseKeyboardNavigationParams, UseUndoRedoResult, UseUndoRedoParams, UseFillHandleResult, UseFillHandleParams, UseDataGridStateParams, UseDataGridStateResult, DataGridLayoutState, DataGridRowSelectionState, DataGridEditingState, DataGridCellInteractionState, DataGridContextMenuState, DataGridViewModelState, DataGridPinningState, UseColumnHeaderFilterStateParams, UseColumnHeaderFilterStateResult, UseTextFilterStateParams, UseTextFilterStateResult, UseMultiSelectFilterStateParams, UseMultiSelectFilterStateResult, UsePeopleFilterStateParams, UsePeopleFilterStateResult, UseDateFilterStateParams, UseDateFilterStateResult, UseColumnChooserStateParams, UseColumnChooserStateResult, UseInlineCellEditorStateParams, UseInlineCellEditorStateResult, InlineCellEditorType, UseColumnResizeParams, UseColumnResizeResult, UseRichSelectStateParams, UseRichSelectStateResult, UseSelectStateParams, UseSelectStateResult, UseSideBarStateParams, UseSideBarStateResult, UseTableLayoutParams, UseTableLayoutResult, UseColumnReorderParams, UseColumnReorderResult, UseVirtualScrollParams, UseVirtualScrollResult, UsePaginationControlsProps, UsePaginationControlsResult, UseDataGridTableOrchestrationParams, UseDataGridTableOrchestrationResult, UseColumnMetaParams, ColumnMetaResult, } from '@alaarab/ogrid-react';
|
|
12
|
+
export { GRID_ROOT_STYLE, CURSOR_CELL_STYLE, POPOVER_ANCHOR_STYLE, PREVENT_DEFAULT, NOOP, STOP_PROPAGATION, } from '@alaarab/ogrid-react';
|
|
13
|
+
export { OGridLayout } from '@alaarab/ogrid-react';
|
|
14
|
+
export type { OGridLayoutProps } from '@alaarab/ogrid-react';
|
|
15
|
+
export { StatusBar } from '@alaarab/ogrid-react';
|
|
16
|
+
export type { StatusBarProps, StatusBarClassNames } from '@alaarab/ogrid-react';
|
|
17
|
+
export { BaseInlineCellEditor, editorWrapperStyle, editorInputStyle, richSelectWrapperStyle, richSelectDropdownStyle, richSelectOptionStyle, richSelectOptionHighlightedStyle, richSelectNoMatchesStyle, selectEditorStyle, selectDisplayStyle, selectChevronStyle, } from '@alaarab/ogrid-react';
|
|
18
|
+
export type { BaseInlineCellEditorProps } from '@alaarab/ogrid-react';
|
|
19
|
+
export { GridContextMenu } from '@alaarab/ogrid-react';
|
|
20
|
+
export type { GridContextMenuProps, GridContextMenuClassNames } from '@alaarab/ogrid-react';
|
|
21
|
+
export { MarchingAntsOverlay } from '@alaarab/ogrid-react';
|
|
22
|
+
export type { MarchingAntsOverlayProps } from '@alaarab/ogrid-react';
|
|
23
|
+
export { SideBar } from '@alaarab/ogrid-react';
|
|
24
|
+
export type { SideBarProps, SideBarFilterColumn } from '@alaarab/ogrid-react';
|
|
25
|
+
export { BaseColumnHeaderMenu } from '@alaarab/ogrid-react';
|
|
26
|
+
export type { BaseColumnHeaderMenuProps, ColumnHeaderMenuClassNames } from '@alaarab/ogrid-react';
|
|
27
|
+
export { createOGrid } from '@alaarab/ogrid-react';
|
|
28
|
+
export type { CreateOGridComponents, GridRowProps, InlineCellEditorProps } from '@alaarab/ogrid-react';
|
|
29
|
+
export { CellErrorBoundary } from '@alaarab/ogrid-react';
|
|
30
|
+
export type { CellErrorBoundaryProps } from '@alaarab/ogrid-react';
|
|
31
|
+
export { EmptyState } from '@alaarab/ogrid-react';
|
|
32
|
+
export type { EmptyStateProps } from '@alaarab/ogrid-react';
|
|
33
|
+
export { BaseEmptyState } from '@alaarab/ogrid-react';
|
|
34
|
+
export type { BaseEmptyStateProps, BaseEmptyStateClassNames } from '@alaarab/ogrid-react';
|
|
35
|
+
export { BaseLoadingOverlay } from '@alaarab/ogrid-react';
|
|
36
|
+
export type { BaseLoadingOverlayProps, BaseLoadingOverlayClassNames } from '@alaarab/ogrid-react';
|
|
37
|
+
export { BaseDropIndicator } from '@alaarab/ogrid-react';
|
|
38
|
+
export type { BaseDropIndicatorProps } from '@alaarab/ogrid-react';
|
|
39
|
+
export { DateFilterContent, getColumnHeaderFilterStateParams, getDateFilterContentProps, } from '@alaarab/ogrid-react';
|
|
40
|
+
export type { IColumnHeaderFilterProps as IColumnHeaderFilterBaseProps, DateFilterContentProps, DateFilterClassNames, } from '@alaarab/ogrid-react';
|
|
41
|
+
export { escapeCsvValue, buildCsvHeader, buildCsvRows, exportToCsv, triggerCsvDownload, getCellValue, flattenColumns, buildHeaderRows, getFilterField, mergeFilter, deriveFilterOptionsFromData, getMultiSelectFilterFields, getStatusBarParts, getDataGridStatusBarConfig, GRID_CONTEXT_MENU_ITEMS, COLUMN_HEADER_MENU_ITEMS, getContextMenuHandlers, getColumnHeaderMenuItems, formatShortcut, getPaginationViewModel, PAGE_SIZE_OPTIONS, MAX_PAGE_BUTTONS, getHeaderFilterConfig, getCellRenderDescriptor, isRowInRange, resolveCellDisplayContent, resolveCellStyle, buildInlineEditorProps, buildPopoverEditorProps, getCellInteractionProps, parseValue, numberParser, currencyParser, dateParser, emailParser, booleanParser, computeAggregations, processClientSideData, areGridRowPropsEqual, findCtrlArrowTarget, computeTabNavigation, rangesEqual, clampSelectionToBounds, computeAutoScrollSpeed, formatCellValueForTsv, formatSelectionAsTsv, parseTsvClipboard, UndoRedoStack, } from '@alaarab/ogrid-react';
|
|
42
|
+
export type { CsvColumn, StatusBarPart, StatusBarPartsInput, GridContextMenuItem, GridContextMenuHandlerProps, PaginationViewModel, HeaderFilterConfigInput, HeaderFilterConfig, CellRenderDescriptorInput, CellRenderDescriptor, CellRenderMode, CellInteractionHandlers, ParseValueResult, AggregationResult, GridRowComparatorProps, IColumnHeaderMenuItem, ColumnHeaderMenuInput, ColumnHeaderMenuHandlers, } from '@alaarab/ogrid-react';
|
|
43
|
+
export { renderFilterContent } from '@alaarab/ogrid-react';
|
|
44
|
+
export type { FilterContentRenderers, MultiSelectRendererProps, TextRendererProps, PeopleRendererProps, DateRendererProps, } from '@alaarab/ogrid-react';
|
|
45
|
+
export type { IColumnChooserProps as IColumnChooserBaseProps } from '@alaarab/ogrid-react';
|
|
46
|
+
export type { IPaginationControlsProps as IPaginationControlsBaseProps } from '@alaarab/ogrid-react';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alaarab/ogrid-react-material",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.5",
|
|
4
4
|
"description": "OGrid React Material implementation – MUI Table–based data grid with sorting, filtering, pagination, column chooser, spreadsheet selection, and CSV export.",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./dist/types/index.d.ts",
|
|
11
11
|
"import": "./dist/esm/index.js",
|
|
12
|
-
"
|
|
12
|
+
"default": "./dist/esm/index.js"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "rimraf dist && tsc -p tsconfig.build.json",
|
|
16
|
+
"build": "rimraf dist && tsup && tsc -p tsconfig.build.json",
|
|
17
17
|
"test": "jest",
|
|
18
18
|
"storybook": "storybook dev -p 6007 --no-open",
|
|
19
19
|
"build-storybook": "storybook build"
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"node": ">=18"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@alaarab/ogrid-react": "2.1.
|
|
42
|
+
"@alaarab/ogrid-react": "2.1.5"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"@emotion/react": "^11.0.0",
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useRef } from 'react';
|
|
3
|
-
import { Button, Popover, Checkbox, Box, Typography, FormControlLabel, } from '@mui/material';
|
|
4
|
-
import { ViewColumn as ViewColumnIcon, ExpandMore as ExpandMoreIcon, ExpandLess as ExpandLessIcon, } from '@mui/icons-material';
|
|
5
|
-
import { useColumnChooserState } from '@alaarab/ogrid-react';
|
|
6
|
-
export const ColumnChooser = (props) => {
|
|
7
|
-
const { columns, visibleColumns, onVisibilityChange, onSetVisibleColumns, className } = props;
|
|
8
|
-
const [anchorEl, setAnchorEl] = useState(null);
|
|
9
|
-
const buttonRef = useRef(null);
|
|
10
|
-
const { open: isOpen, setOpen, handleClose, handleCheckboxChange: setColumnVisible, handleSelectAll, handleClearAll, visibleCount, totalCount, } = useColumnChooserState({ columns, visibleColumns, onVisibilityChange, onSetVisibleColumns });
|
|
11
|
-
const handleToggle = (e) => {
|
|
12
|
-
if (isOpen) {
|
|
13
|
-
handleClose();
|
|
14
|
-
setAnchorEl(null);
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
setAnchorEl(e.currentTarget);
|
|
18
|
-
setOpen(true);
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
const handlePopoverClose = () => {
|
|
22
|
-
handleClose();
|
|
23
|
-
setAnchorEl(null);
|
|
24
|
-
};
|
|
25
|
-
const handleCheckboxChange = (columnKey) => (ev) => {
|
|
26
|
-
ev.stopPropagation();
|
|
27
|
-
setColumnVisible(columnKey)(ev.target.checked);
|
|
28
|
-
};
|
|
29
|
-
return (_jsxs(Box, { className: className, sx: { display: 'inline-flex' }, children: [_jsxs(Button, { ref: buttonRef, variant: "outlined", size: "small", color: "inherit", startIcon: _jsx(ViewColumnIcon, {}), endIcon: isOpen ? _jsx(ExpandLessIcon, {}) : _jsx(ExpandMoreIcon, {}), onClick: handleToggle, "aria-expanded": isOpen, "aria-haspopup": "listbox", sx: {
|
|
30
|
-
textTransform: 'none',
|
|
31
|
-
fontWeight: 600,
|
|
32
|
-
borderColor: isOpen ? 'primary.main' : 'divider',
|
|
33
|
-
}, children: ["Column Visibility (", visibleCount, " of ", totalCount, ")"] }), _jsxs(Popover, { open: isOpen, anchorEl: anchorEl, onClose: handlePopoverClose, anchorOrigin: { vertical: 'bottom', horizontal: 'right' }, transformOrigin: { vertical: 'top', horizontal: 'right' }, slotProps: {
|
|
34
|
-
paper: {
|
|
35
|
-
sx: { mt: 0.5, minWidth: 220 },
|
|
36
|
-
},
|
|
37
|
-
}, children: [_jsx(Box, { sx: {
|
|
38
|
-
px: 1.5,
|
|
39
|
-
py: 1,
|
|
40
|
-
borderBottom: 1,
|
|
41
|
-
borderColor: 'divider',
|
|
42
|
-
bgcolor: 'action.hover',
|
|
43
|
-
}, children: _jsxs(Typography, { variant: "subtitle2", fontWeight: 600, children: ["Select Columns (", visibleCount, " of ", totalCount, ")"] }) }), _jsx(Box, { sx: { maxHeight: 320, overflowY: 'auto', py: 0.5 }, children: columns.map((column) => (_jsx(Box, { sx: { px: 1.5, minHeight: 32, display: 'flex', alignItems: 'center' }, children: _jsx(FormControlLabel, { control: _jsx(Checkbox, { size: "small", checked: visibleColumns.has(column.columnId), onChange: handleCheckboxChange(column.columnId), disabled: column.required === true }), label: _jsx(Typography, { variant: "body2", children: column.name }), sx: { m: 0 } }) }, column.columnId))) }), _jsxs(Box, { sx: {
|
|
44
|
-
display: 'flex',
|
|
45
|
-
justifyContent: 'flex-end',
|
|
46
|
-
gap: 1,
|
|
47
|
-
px: 1.5,
|
|
48
|
-
py: 1,
|
|
49
|
-
borderTop: 1,
|
|
50
|
-
borderColor: 'divider',
|
|
51
|
-
bgcolor: 'action.hover',
|
|
52
|
-
}, children: [_jsx(Button, { size: "small", onClick: handleClearAll, sx: { textTransform: 'none' }, children: "Clear All" }), _jsx(Button, { size: "small", variant: "contained", onClick: handleSelectAll, sx: { textTransform: 'none' }, children: "Select All" })] })] })] }));
|
|
53
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { Popover, Tooltip, IconButton, Box, Typography } from '@mui/material';
|
|
4
|
-
import { FilterList as FilterListIcon, } from '@mui/icons-material';
|
|
5
|
-
import { useColumnHeaderFilterState, getColumnHeaderFilterStateParams, renderFilterContent, } from '@alaarab/ogrid-react';
|
|
6
|
-
import { TextFilterPopover } from './TextFilterPopover';
|
|
7
|
-
import { MultiSelectFilterPopover } from './MultiSelectFilterPopover';
|
|
8
|
-
import { PeopleFilterPopover } from './PeopleFilterPopover';
|
|
9
|
-
const materialRenderers = {
|
|
10
|
-
renderMultiSelect: (p) => (_jsx(MultiSelectFilterPopover, { searchText: p.searchText, onSearchChange: p.onSearchChange, options: p.options, filteredOptions: p.filteredOptions, selected: p.selected, onOptionToggle: p.onOptionToggle, onSelectAll: p.onSelectAll, onClearSelection: p.onClearSelection, onApply: p.onApply, isLoading: p.isLoading })),
|
|
11
|
-
renderText: (p) => (_jsx(TextFilterPopover, { value: p.value, onValueChange: p.onValueChange, onApply: p.onApply, onClear: p.onClear })),
|
|
12
|
-
renderPeople: (p) => (_jsx(PeopleFilterPopover, { selectedUser: p.selectedUser, searchText: p.searchText, onSearchChange: p.onSearchChange, suggestions: p.suggestions, isLoading: p.isLoading, onUserSelect: p.onUserSelect, onClearUser: p.onClearUser, inputRef: p.inputRef })),
|
|
13
|
-
renderDate: (p) => (_jsxs(Box, { sx: { p: 1.5, display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [_jsx(Typography, { variant: "caption", sx: { minWidth: 36 }, children: "From:" }), _jsx("input", { type: "date", value: p.tempDateFrom, onChange: (e) => p.setTempDateFrom(e.target.value), style: { flex: 1, padding: '4px 6px' } })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [_jsx(Typography, { variant: "caption", sx: { minWidth: 36 }, children: "To:" }), _jsx("input", { type: "date", value: p.tempDateTo, onChange: (e) => p.setTempDateTo(e.target.value), style: { flex: 1, padding: '4px 6px' } })] }), _jsxs(Box, { sx: { display: 'flex', justifyContent: 'flex-end', gap: 1, mt: 0.5 }, children: [_jsx("button", { onClick: p.onClear, disabled: !p.tempDateFrom && !p.tempDateTo, style: { padding: '4px 12px', cursor: 'pointer' }, children: "Clear" }), _jsx("button", { onClick: p.onApply, style: { padding: '4px 12px', cursor: 'pointer' }, children: "Apply" })] })] })),
|
|
14
|
-
};
|
|
15
|
-
export const ColumnHeaderFilter = React.memo((props) => {
|
|
16
|
-
const { columnName, filterType, options = [], isLoadingOptions = false, selectedUser, } = props;
|
|
17
|
-
const state = useColumnHeaderFilterState(getColumnHeaderFilterStateParams(props));
|
|
18
|
-
const { headerRef, isFilterOpen, setFilterOpen, hasActiveFilter, popoverPosition, handlers, } = state;
|
|
19
|
-
return (_jsxs(Box, { ref: headerRef, sx: { display: 'flex', alignItems: 'center', width: '100%', minWidth: 0 }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0, overflow: 'hidden' }, children: _jsx(Tooltip, { title: columnName, arrow: true, children: _jsx(Typography, { variant: "body2", fontWeight: 600, noWrap: true, "data-header-label": true, sx: { lineHeight: 1.4 }, children: columnName }) }) }), _jsx(Box, { sx: { display: 'flex', alignItems: 'center', ml: 0.5, flexShrink: 0 }, children: filterType !== 'none' && (_jsxs(IconButton, { size: "small", onClick: handlers.handleFilterIconClick, "aria-label": `Filter ${columnName}`, title: `Filter ${columnName}`, color: hasActiveFilter || isFilterOpen ? 'primary' : 'default', sx: { p: 0.25, position: 'relative' }, children: [_jsx(FilterListIcon, { sx: { fontSize: 16 } }), hasActiveFilter && (_jsx(Box, { sx: {
|
|
20
|
-
position: 'absolute',
|
|
21
|
-
top: 2,
|
|
22
|
-
right: 2,
|
|
23
|
-
width: 6,
|
|
24
|
-
height: 6,
|
|
25
|
-
borderRadius: '50%',
|
|
26
|
-
bgcolor: 'primary.main',
|
|
27
|
-
} }))] })) }), _jsxs(Popover, { open: isFilterOpen && filterType !== 'none', onClose: () => setFilterOpen(false), anchorReference: "anchorPosition", anchorPosition: popoverPosition ?? { top: 0, left: 0 }, anchorOrigin: { vertical: 'bottom', horizontal: 'left' }, transformOrigin: { vertical: 'top', horizontal: 'left' }, slotProps: {
|
|
28
|
-
paper: {
|
|
29
|
-
sx: { mt: 0.5, overflow: 'visible' },
|
|
30
|
-
onClick: (e) => e.stopPropagation(),
|
|
31
|
-
},
|
|
32
|
-
}, children: [_jsx(Box, { sx: { borderBottom: 1, borderColor: 'divider', px: 1.5, py: 1 }, children: _jsxs(Typography, { variant: "subtitle2", children: ["Filter: ", columnName] }) }), renderFilterContent(filterType, state, options ?? [], isLoadingOptions, selectedUser, materialRenderers)] })] }));
|
|
33
|
-
});
|
|
34
|
-
ColumnHeaderFilter.displayName = 'ColumnHeaderFilter';
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { TextField, Checkbox, CircularProgress, Button, Box, Typography, InputAdornment, FormControlLabel, } from '@mui/material';
|
|
3
|
-
import { Search as SearchIcon } from '@mui/icons-material';
|
|
4
|
-
import { useListVirtualizer } from '@alaarab/ogrid-react';
|
|
5
|
-
const ITEM_HEIGHT = 40;
|
|
6
|
-
export const MultiSelectFilterPopover = ({ searchText, onSearchChange, options, filteredOptions, selected, onOptionToggle, onSelectAll, onClearSelection, onApply, isLoading, }) => {
|
|
7
|
-
const virt = useListVirtualizer({ count: filteredOptions.length, itemHeight: ITEM_HEIGHT, containerHeight: 240 });
|
|
8
|
-
return (_jsxs(Box, { sx: { width: 280 }, children: [_jsxs(Box, { sx: { p: 1.5, pb: 0.5 }, children: [_jsx(TextField, { placeholder: "Search...", value: searchText, onChange: (e) => onSearchChange(e.target.value), onKeyDown: (e) => e.stopPropagation(), autoComplete: "off", size: "small", fullWidth: true, slotProps: {
|
|
9
|
-
input: {
|
|
10
|
-
startAdornment: (_jsx(InputAdornment, { position: "start", children: _jsx(SearchIcon, { fontSize: "small" }) })),
|
|
11
|
-
},
|
|
12
|
-
} }), _jsxs(Typography, { variant: "caption", color: "text.secondary", sx: { mt: 0.5, display: 'block' }, children: [filteredOptions.length, " of ", options.length, " options"] })] }), _jsxs(Box, { sx: { display: 'flex', justifyContent: 'space-between', px: 1.5, py: 0.5 }, children: [_jsxs(Button, { size: "small", onClick: onSelectAll, children: ["Select All (", filteredOptions.length, ")"] }), _jsx(Button, { size: "small", onClick: onClearSelection, children: "Clear" })] }), _jsx(Box, { ref: virt.containerRef, onScroll: virt.onScroll, sx: { maxHeight: 240, overflowY: 'auto', px: 0.5 }, children: isLoading ? (_jsx(Box, { sx: { display: 'flex', justifyContent: 'center', py: 2 }, children: _jsx(CircularProgress, { size: 24 }) })) : filteredOptions.length === 0 ? (_jsx(Typography, { variant: "body2", color: "text.secondary", sx: { py: 2, textAlign: 'center' }, children: "No options found" })) : (_jsx(Box, { sx: { height: virt.totalHeight, position: 'relative' }, children: virt.visibleItems.map(({ index, offsetTop }) => {
|
|
13
|
-
const option = filteredOptions[index];
|
|
14
|
-
return (_jsx(FormControlLabel, { control: _jsx(Checkbox, { size: "small", checked: selected.has(option), onChange: (e) => onOptionToggle(option, e.target.checked) }), label: _jsx(Typography, { variant: "body2", children: option }), sx: { position: 'absolute', top: offsetTop, width: '100%', height: ITEM_HEIGHT, boxSizing: 'border-box', display: 'flex', alignItems: 'center', mx: 0, '& .MuiFormControlLabel-label': { flex: 1, minWidth: 0 } } }, option));
|
|
15
|
-
}) })) }), _jsxs(Box, { sx: { display: 'flex', justifyContent: 'flex-end', gap: 1, p: 1.5, pt: 1, borderTop: 1, borderColor: 'divider' }, children: [_jsx(Button, { size: "small", onClick: onClearSelection, children: "Clear" }), _jsx(Button, { size: "small", variant: "contained", onClick: onApply, children: "Apply" })] })] }));
|
|
16
|
-
};
|
|
17
|
-
MultiSelectFilterPopover.displayName = 'MultiSelectFilterPopover';
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { TextField, CircularProgress, Button, Box, Typography, InputAdornment, Avatar, IconButton, } from '@mui/material';
|
|
3
|
-
import { Search as SearchIcon, Clear as ClearIcon } from '@mui/icons-material';
|
|
4
|
-
export const PeopleFilterPopover = ({ selectedUser, searchText, onSearchChange, suggestions, isLoading, onUserSelect, onClearUser, inputRef, }) => (_jsxs(Box, { sx: { width: 300 }, children: [selectedUser && (_jsxs(Box, { sx: { p: 1.5, pb: 1, borderBottom: 1, borderColor: 'divider' }, children: [_jsx(Typography, { variant: "caption", color: "text.secondary", children: "Currently filtered by:" }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1, mt: 0.5 }, children: [_jsx(Avatar, { src: selectedUser.photo, alt: selectedUser.displayName, sx: { width: 32, height: 32 }, children: selectedUser.displayName?.[0] }), _jsxs(Box, { sx: { flex: 1, minWidth: 0 }, children: [_jsx(Typography, { variant: "body2", noWrap: true, children: selectedUser.displayName }), _jsx(Typography, { variant: "caption", color: "text.secondary", noWrap: true, children: selectedUser.email })] }), _jsx(IconButton, { size: "small", onClick: onClearUser, "aria-label": "Remove filter", children: _jsx(ClearIcon, { fontSize: "small" }) })] })] })), _jsx(Box, { sx: { p: 1.5, pb: 0.5 }, children: _jsx(TextField, { inputRef: inputRef, placeholder: "Search for a person...", value: searchText, onChange: (e) => onSearchChange(e.target.value), onKeyDown: (e) => e.stopPropagation(), autoComplete: "off", size: "small", fullWidth: true, slotProps: {
|
|
5
|
-
input: {
|
|
6
|
-
startAdornment: (_jsx(InputAdornment, { position: "start", children: _jsx(SearchIcon, { fontSize: "small" }) })),
|
|
7
|
-
},
|
|
8
|
-
} }) }), _jsx(Box, { sx: { maxHeight: 240, overflowY: 'auto' }, children: isLoading && searchText.trim() ? (_jsx(Box, { sx: { display: 'flex', justifyContent: 'center', py: 2 }, children: _jsx(CircularProgress, { size: 24 }) })) : suggestions.length === 0 && searchText.trim() ? (_jsx(Typography, { variant: "body2", color: "text.secondary", sx: { py: 2, textAlign: 'center' }, children: "No results found" })) : searchText.trim() ? (suggestions.map((user) => (_jsxs(Box, { onClick: () => onUserSelect(user), sx: {
|
|
9
|
-
display: 'flex',
|
|
10
|
-
alignItems: 'center',
|
|
11
|
-
gap: 1,
|
|
12
|
-
px: 1.5,
|
|
13
|
-
py: 1,
|
|
14
|
-
cursor: 'pointer',
|
|
15
|
-
'&:hover': { bgcolor: 'action.hover' },
|
|
16
|
-
}, children: [_jsx(Avatar, { src: user.photo, alt: user.displayName, sx: { width: 32, height: 32 }, children: user.displayName?.[0] }), _jsxs(Box, { sx: { flex: 1, minWidth: 0 }, children: [_jsx(Typography, { variant: "body2", noWrap: true, children: user.displayName }), _jsx(Typography, { variant: "caption", color: "text.secondary", noWrap: true, children: user.email })] })] }, user.id || user.email || user.displayName)))) : (_jsx(Typography, { variant: "body2", color: "text.secondary", sx: { py: 2, textAlign: 'center' }, children: "Type to search..." })) }), selectedUser && (_jsx(Box, { sx: { p: 1.5, pt: 1, borderTop: 1, borderColor: 'divider' }, children: _jsx(Button, { size: "small", fullWidth: true, onClick: onClearUser, children: "Clear Filter" }) }))] }));
|
|
17
|
-
PeopleFilterPopover.displayName = 'PeopleFilterPopover';
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { TextField, Button, Box, InputAdornment } from '@mui/material';
|
|
3
|
-
import { Search as SearchIcon } from '@mui/icons-material';
|
|
4
|
-
export const TextFilterPopover = ({ value, onValueChange, onApply, onClear, }) => (_jsxs(Box, { sx: { width: 260 }, children: [_jsx(Box, { sx: { p: 1.5 }, children: _jsx(TextField, { placeholder: "Enter search term...", value: value, onChange: (e) => onValueChange(e.target.value), onKeyDown: (e) => {
|
|
5
|
-
e.stopPropagation();
|
|
6
|
-
if (e.key === 'Enter') {
|
|
7
|
-
e.preventDefault();
|
|
8
|
-
onApply();
|
|
9
|
-
}
|
|
10
|
-
}, autoComplete: "off", size: "small", fullWidth: true, slotProps: {
|
|
11
|
-
input: {
|
|
12
|
-
startAdornment: (_jsx(InputAdornment, { position: "start", children: _jsx(SearchIcon, { fontSize: "small" }) })),
|
|
13
|
-
},
|
|
14
|
-
} }) }), _jsxs(Box, { sx: { display: 'flex', justifyContent: 'flex-end', gap: 1, p: 1.5, pt: 0 }, children: [_jsx(Button, { size: "small", disabled: !value, onClick: onClear, children: "Clear" }), _jsx(Button, { size: "small", variant: "contained", onClick: onApply, children: "Apply" })] })] }));
|
|
15
|
-
TextFilterPopover.displayName = 'TextFilterPopover';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { ColumnHeaderFilter } from './ColumnHeaderFilter';
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo, useEffect, useState } from 'react';
|
|
3
|
-
import { Menu, MenuItem, Divider } from '@mui/material';
|
|
4
|
-
import { getColumnHeaderMenuItems } from '@alaarab/ogrid-react';
|
|
5
|
-
/**
|
|
6
|
-
* Column header dropdown menu for pin/sort/autosize actions.
|
|
7
|
-
* Uses Material UI Menu component with anchor position.
|
|
8
|
-
*/
|
|
9
|
-
export function ColumnHeaderMenu(props) {
|
|
10
|
-
const { isOpen, anchorElement, onClose, onPinLeft, onPinRight, onUnpin, onSortAsc, onSortDesc, onClearSort, onAutosizeThis, onAutosizeAll, canPinLeft, canPinRight, canUnpin, currentSort, isSortable, isResizable, } = props;
|
|
11
|
-
const [anchorPosition, setAnchorPosition] = useState(undefined);
|
|
12
|
-
useEffect(() => {
|
|
13
|
-
if (isOpen && anchorElement) {
|
|
14
|
-
const rect = anchorElement.getBoundingClientRect();
|
|
15
|
-
setAnchorPosition({
|
|
16
|
-
top: rect.bottom + 4,
|
|
17
|
-
left: rect.left,
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
setAnchorPosition(undefined);
|
|
22
|
-
}
|
|
23
|
-
}, [isOpen, anchorElement]);
|
|
24
|
-
const menuInput = useMemo(() => ({
|
|
25
|
-
canPinLeft,
|
|
26
|
-
canPinRight,
|
|
27
|
-
canUnpin,
|
|
28
|
-
currentSort,
|
|
29
|
-
isSortable,
|
|
30
|
-
isResizable,
|
|
31
|
-
}), [canPinLeft, canPinRight, canUnpin, currentSort, isSortable, isResizable]);
|
|
32
|
-
const items = useMemo(() => getColumnHeaderMenuItems(menuInput), [menuInput]);
|
|
33
|
-
const handlers = useMemo(() => ({
|
|
34
|
-
pinLeft: onPinLeft,
|
|
35
|
-
pinRight: onPinRight,
|
|
36
|
-
unpin: onUnpin,
|
|
37
|
-
sortAsc: onSortAsc,
|
|
38
|
-
sortDesc: onSortDesc,
|
|
39
|
-
clearSort: onClearSort,
|
|
40
|
-
autosizeThis: onAutosizeThis,
|
|
41
|
-
autosizeAll: onAutosizeAll,
|
|
42
|
-
}), [onPinLeft, onPinRight, onUnpin, onSortAsc, onSortDesc, onClearSort, onAutosizeThis, onAutosizeAll]);
|
|
43
|
-
return (_jsx(Menu, { open: isOpen && !!anchorPosition, onClose: onClose, anchorReference: "anchorPosition", anchorPosition: anchorPosition, slotProps: {
|
|
44
|
-
paper: {
|
|
45
|
-
sx: {
|
|
46
|
-
minWidth: 140,
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
}, children: items.flatMap((item, idx) => {
|
|
50
|
-
const elements = [
|
|
51
|
-
_jsx(MenuItem, { disabled: item.disabled, onClick: () => {
|
|
52
|
-
handlers[item.id]();
|
|
53
|
-
onClose();
|
|
54
|
-
}, children: item.label }, item.id),
|
|
55
|
-
];
|
|
56
|
-
if (item.divider && idx < items.length - 1) {
|
|
57
|
-
elements.push(_jsx(Divider, {}, `${item.id}-divider`));
|
|
58
|
-
}
|
|
59
|
-
return elements;
|
|
60
|
-
}) }));
|
|
61
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { ColumnHeaderMenu } from './ColumnHeaderMenu';
|