@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
JavaScript
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);
}
}
}