UNPKG

@adaptabletools/adaptable

Version:

Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

183 lines (182 loc) 7.52 kB
import SimpleButton from '../../components/SimpleButton'; import * as React from 'react'; import { useRerender } from '../../components/utils/useRerender'; import { renderWithAdaptableContext } from '../../View/renderWithAdaptableContext'; import { LAYOUT_SELECT } from '../../Redux/ActionsReducers/LayoutRedux'; const ActionButtons = (props) => { const { buttons, adaptableApi, context, rerender } = props; return (React.createElement(React.Fragment, null, buttons.map((button, index) => { if (button.hidden && button.hidden(button, context)) { return; } const buttonIcon = adaptableApi.internalApi.getIconForButton(button, context, { height: 15, width: 15, }); const buttonStyle = adaptableApi.internalApi.getStyleForButton(button, context); const buttonLabel = adaptableApi.internalApi.getLabelForButton(button, context); const buttonTooltip = adaptableApi.internalApi.getTooltipForButton(button, context); const handleClick = () => { button.onClick?.(button, context); // Timeout to let any updates to be done before re-rendering the component setTimeout(() => { // when called again it triggers a re-render // https:reactjs.org/docs/react-dom.html#render rerender(); }, 16); }; const disabled = button.disabled && button.disabled(button, context); const identifier = button.label ?? button.icon?.name ?? button.tooltip ?? `${index + 1}`; return (React.createElement(SimpleButton, { key: button.Uuid, "data-name": `action-button-${identifier}`, variant: buttonStyle?.variant ?? 'text', disabled: disabled, tooltip: buttonTooltip, icon: buttonIcon, tone: buttonStyle?.tone ?? 'none', onClick: handleClick, className: buttonStyle?.className, accessLevel: 'Full' }, buttonLabel)); }))); }; export const ReactActionColumnRenderer = (props) => { const rerender = useRerender(); const adaptable = props.context.__adaptable; if (!adaptable) { console.warn('Adaptable not found in context of ActionColumnRenderer'); return null; } const { actionButtons, actionColumn } = adaptable.api.actionColumnApi.internalApi.getActionColumnsAndButtons(props.colDef); if (!actionColumn || !actionButtons.length) { return null; } const isGroupedRow = adaptable.api.gridApi.isGroupRowNode(props.node); const isSummaryRow = adaptable.api.gridApi.isSummaryNode(props.node); let shouldRender = true; if (isGroupedRow) { if (actionColumn.rowScope?.ExcludeGroupRows) { shouldRender = false; } } else if (isSummaryRow) { if (actionColumn.rowScope?.ExcludeSummaryRows) { shouldRender = false; } } else { if (actionColumn.rowScope?.ExcludeDataRows) { shouldRender = false; } } if (!shouldRender) { return null; } // subscribe to the LayoutChange event and rerender on change const unsubscribe = adaptable.api.eventApi.on('AdaptableStateChanged', (eventInfo) => { if (eventInfo.actionName === LAYOUT_SELECT) { if (eventInfo.oldState.Layout.CurrentLayout !== eventInfo.newState.Layout.CurrentLayout) { rerender(); } } }); // unsubscribe on unmount React.useEffect(() => { return () => { unsubscribe(); }; }, []); const pkValue = adaptable.getPrimaryKeyValueFromRowNode(props.node, props.api); const buttonContext = { actionColumn, primaryKeyValue: pkValue, rowNode: props.node, ...adaptable.api.internalApi.buildBaseContext(), data: props.data, }; return (React.createElement("div", { className: "ab-ActionColumn" }, React.createElement(ActionButtons, { buttons: actionButtons, adaptableApi: adaptable.api, context: buttonContext, rerender: rerender }))); }; export class ActionColumnRenderer { // gets called once before the renderer is used init(params) { const adaptable = params.context.__adaptable; if (!adaptable) { console.warn('Adaptable not found in context of ActionColumnRenderer'); return null; } const { actionButtons, actionColumn } = adaptable.api.actionColumnApi.internalApi.getActionColumnsAndButtons(params.colDef); if (!actionColumn || !actionButtons.length) { return; } this.actionButtons = actionButtons; // create the cell this.eGui = document.createElement('div'); this.eGui.className = 'ab-ActionColumn'; const isGroupedRow = adaptable.api.gridApi.isGroupRowNode(params.node); const isSummaryRow = adaptable.api.gridApi.isSummaryNode(params.node); let shouldRender = true; if (isGroupedRow) { if (actionColumn.rowScope?.ExcludeGroupRows) { shouldRender = false; } } else if (isSummaryRow) { if (actionColumn.rowScope?.ExcludeSummaryRows) { shouldRender = false; } } else { if (actionColumn.rowScope?.ExcludeDataRows) { shouldRender = false; } } if (!shouldRender) { this.eGui.innerHTML = ''; return; } const pkValue = adaptable.getPrimaryKeyValueFromRowNode(params.node, params.api); const buttonContext = { actionColumn, primaryKeyValue: pkValue, rowNode: params.node, ...adaptable.api.internalApi.buildBaseContext(), data: params.data, }; const eGui = this.eGui; const doRender = () => { this.unmountReactRoot = adaptable.renderReactRoot(renderWithAdaptableContext(ActionButtons({ buttons: this.actionButtons, context: buttonContext, rerender: doRender, adaptableApi: adaptable.api, }), adaptable), eGui); }; this.render = doRender; this.layoutSwitchUnsubscribe = adaptable.api.eventApi.on('AdaptableStateChanged', (eventInfo) => { if (eventInfo.actionName === LAYOUT_SELECT) { if (eventInfo.oldState.Layout.CurrentLayout !== eventInfo.newState.Layout.CurrentLayout) { const { actionButtons: freshActionButtons } = adaptable.api.actionColumnApi.internalApi.getActionColumnsAndButtons(params.colDef); this.actionButtons = freshActionButtons; doRender(); } } }); doRender(); } // defined on init // used to re-render in refresh render() { } // gets called once when grid ready to insert the element getGui() { return this.eGui; } // gets called whenever the user gets the cell to refresh refresh(params) { // return true to tell the grid we refreshed successfully this.render(); return true; } // gets called when the cell is removed from the grid destroy() { this.layoutSwitchUnsubscribe?.(); this.unmountReactRoot?.(); // do cleanup, remove event listener from button if (this.eGui) { this.eGui.removeEventListener('click', this.eventListener); } } }