@adaptabletools/adaptable
Version:
Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
235 lines (234 loc) • 13 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { ButtonNew } from '../../Components/Buttons/ButtonNew';
import SimpleButton from '../../../components/SimpleButton';
import Input from '../../../components/Input';
import FormLayout, { FormRow } from '../../../components/FormLayout';
import { CheckBox } from '../../../components/CheckBox';
import { cloneObject } from '../../../Utilities/Helpers/Helper';
import StringExtensions from '../../../Utilities/Extensions/StringExtensions';
import { AdaptableIconSelector } from '../../Components/AdaptableIconSelector';
import { Box, Flex } from '../../../components/Flex';
import { sentenceCase } from '../../../Utilities/Extensions/StringExtensions';
import { SingleSelect } from '../../../components/NewSelect';
import { Tag } from '../../../components/Tag';
import { CollapsibleWizardCard, getWizardAccordionSectionClassName, useWizardCardAccordion, } from '../../Wizard/CollapsibleWizardCard';
import { cn } from '../../../lib/utils';
const alertButtonCardId = (index) => `alert-button-${index}`;
const TONE_OPTIONS = [
{
label: 'Tone: Use Alert Tone',
value: 'text',
},
...['success', 'info', 'error', 'warning', 'accent', 'neutral'].map((tone) => {
return {
label: renderTone({ label: StringExtensions.CapitaliseFirstLetter(tone), value: tone }),
value: tone,
};
}),
];
const AlertButtonPreview = ({ button, messageType }) => {
const buttonStyle = button.ButtonStyle ?? {};
const variant = (buttonStyle.variant ?? 'raised');
const tone = (buttonStyle.tone ??
messageType.toLowerCase());
const icon = button.icon && 'name' in button.icon && button.icon.name ? button.icon : undefined;
return (_jsx(SimpleButton, { variant: variant, tone: tone, icon: icon, className: "twa:cursor-default twa:pointer-events-none", tabIndex: -1, children: button.Label || 'Untitled' }));
};
function renderTone(option) {
return (_jsxs(Flex, { flexDirection: "row", alignItems: "center", children: [_jsx(SimpleButton, { className: "twa:mr-2 twa:w-[10px] twa:h-[10px] twa:line-height-0 twa:rounded-[100%] twa:bg-current", tone: option.value, variant: "text" }), option.label] }));
}
const getButtonCommands = (button) => {
if (button.Command && typeof button.Command === 'string') {
return [button.Command];
}
if (button.Command && Array.isArray(button.Command)) {
return button.Command;
}
return [];
};
const AlertButtonActionTags = ({ button }) => {
const commands = getButtonCommands(button);
if (!commands.length) {
return null;
}
return (_jsx(_Fragment, { children: commands.map((command) => (_jsx(Tag, { className: "twa:shrink-0", children: sentenceCase(command) }, command))) }));
};
const AlertButtonCardSummary = ({ button }) => {
const commands = getButtonCommands(button);
if (!commands.length) {
return _jsx(Tag, { children: "No actions" });
}
return (_jsx(Flex, { flexWrap: "wrap", className: "twa:gap-1", children: _jsx(AlertButtonActionTags, { button: button }) }));
};
const AlertButtonCompactSummary = ({ button }) => (_jsxs(Flex, { alignItems: "center", className: "twa:gap-1 twa:min-w-0 twa:overflow-hidden twa:flex-wrap", children: [_jsx(Tag, { className: "twa:shrink-0", children: button.Label || 'Untitled' }), _jsx(AlertButtonActionTags, { button: button })] }));
const AlertButtonEditorForm = ({ button, index, alertButtons, buttonCommands, onChange, }) => {
const buttonStyle = button.ButtonStyle;
const buttonLabel = button.Label;
const btnCommands = getButtonCommands(button);
const btnUserFunctions = btnCommands.filter((command) => !buttonCommands.includes(command));
const setVariant = (variant) => {
onChange(alertButtons.map((btn, i) => {
if (i === index) {
const nextButtonStyle = { ...btn.ButtonStyle };
nextButtonStyle.variant = variant;
return {
...btn,
ButtonStyle: nextButtonStyle,
};
}
return btn;
}));
};
const setTone = (tone) => {
onChange(alertButtons.map((btn, i) => {
if (i === index) {
const nextButtonStyle = { ...btn.ButtonStyle };
if (tone == null) {
delete nextButtonStyle.tone;
}
else {
nextButtonStyle.tone = tone;
}
return {
...btn,
ButtonStyle: nextButtonStyle,
};
}
return btn;
}));
};
const handleCommandChange = (checked, commandName) => {
let commands = btnCommands;
if (!checked) {
commands = commands.filter((a) => a !== commandName);
}
else {
commands = [...commands, commandName];
}
onChange(alertButtons.map((btn, i) => {
if (i === index) {
return {
...btn,
Command: commands.length ? commands : undefined,
};
}
return btn;
}));
};
let iconSelector = null;
if (!button.icon || (button.icon && 'name' in button.icon)) {
iconSelector = (_jsx(AdaptableIconSelector, { value: button.icon && 'name' in button.icon ? button?.icon?.name : '', onChange: (iconName) => {
onChange(alertButtons.map((btn) => {
if (btn === button) {
return {
...btn,
icon: {
name: iconName,
},
};
}
return btn;
}));
} }));
}
return (_jsxs(FormLayout, { children: [_jsx(FormRow, { label: _jsx(Box, { className: "twa:text-2", children: "Button Text" }), children: _jsx(Input, { value: buttonLabel, className: "twa:max-w-[200px]", onChange: (e) => {
onChange(alertButtons.map((btn, i) => {
if (i === index) {
return { ...btn, Label: e.target.value };
}
return btn;
}));
} }) }), _jsx(FormRow, { label: _jsx(Box, { className: "twa:text-2", children: "Style" }), children: _jsxs(Flex, { flexDirection: "row", className: "twa:gap-2 twa:flex-wrap", children: [_jsx(SingleSelect, { items: ['text', 'outlined', 'raised'].map((variant) => {
return {
label: StringExtensions.CapitaliseFirstLetter(variant),
value: variant,
};
}), renderValue: (option) => `Variant: ${option.label}`, value: buttonStyle?.variant, onValueChange: (value) => {
setVariant(value);
} }), _jsx(SingleSelect, { items: TONE_OPTIONS, onValueChange: (value) => {
if (value === 'text') {
setTone(null);
return;
}
setTone(value);
}, value: buttonStyle?.tone ?? 'text' })] }) }), _jsx(FormRow, { label: _jsx(Box, { className: "twa:text-2", children: "Actions" }), children: _jsxs(Flex, { flexDirection: "row", className: "twa:gap-3 twa:flex-wrap", children: [buttonCommands.map((commandName) => {
return (_jsx(CheckBox, { onChange: (checked) => handleCommandChange(checked, commandName), checked: button.Command === commandName ||
(Array.isArray(button.Command) && button.Command.includes(commandName)), children: _jsx(Box, { className: "twa:text-2", children: sentenceCase(commandName) }) }, commandName));
}), btnUserFunctions.length ? (_jsx(CheckBox, { checked: true, disabled: true, children: _jsxs(Box, { className: "twa:text-2", children: ["User function", btnUserFunctions.length > 1 ? 's' : '', ": ", btnUserFunctions.join(', ')] }) })) : null] }) }), iconSelector && (_jsx(FormRow, { label: _jsx(Box, { className: "twa:text-2", children: "Icon" }), children: _jsx(Box, { children: iconSelector }) }))] }));
};
export const AlertButtonsEditor = (props) => {
const { api, adaptableAlert } = props;
const onChange = (newButtons) => {
props.onChange(newButtons);
};
const alertDefinition = adaptableAlert.alertDefinition;
const messageType = alertDefinition?.MessageType ?? 'Info';
const isRowRemovedAlert = api.alertApi.internalApi.isAlertDefinitionForRemovedRowChangeEvent(alertDefinition);
const hasHighlightCell = props.alertType !== 'RowChange';
const hasHighlightRow = !isRowRemovedAlert;
const hasJumpToCell = props.alertType !== 'RowChange';
const hasJumpToRow = !isRowRemovedAlert;
const hasSuspend = true;
const hasUndo = props.alertType === 'DataChange';
const alertButtons = cloneObject(props.AlertButtons || []) || [];
const buttonCommands = [];
if (hasHighlightRow) {
buttonCommands.push('highlight-row');
}
if (hasJumpToRow) {
buttonCommands.push('jump-to-row');
}
if (hasHighlightCell) {
buttonCommands.push('highlight-cell');
}
if (hasJumpToCell) {
buttonCommands.push('jump-to-cell');
}
if (hasUndo) {
buttonCommands.push('undo');
}
if (hasSuspend) {
buttonCommands.push('suspend');
}
const commandHandlers = api.optionsApi.getAlertOptions().commandHandlers;
if (commandHandlers) {
commandHandlers.forEach((ch) => {
buttonCommands.push(ch.name);
});
}
const { bindCard, hasExpandedCard, expandedFillsSpace, expandedId, setExpandedId } = useWizardCardAccordion(null);
const handleAddButton = () => {
const newIndex = alertButtons.length;
onChange([
...(alertButtons || []),
{
Label: 'OK',
ButtonStyle: {
variant: 'raised',
},
},
]);
setExpandedId(alertButtonCardId(newIndex));
};
const handleDeleteButton = (index) => {
if (alertButtons.length <= 1) {
return;
}
const cardId = alertButtonCardId(index);
onChange(alertButtons.filter((_, i) => i !== index));
if (expandedId === cardId) {
setExpandedId(null);
return;
}
if (expandedId?.startsWith('alert-button-')) {
const expandedIndex = Number(expandedId.replace('alert-button-', ''));
if (!Number.isNaN(expandedIndex) && expandedIndex > index) {
setExpandedId(alertButtonCardId(expandedIndex - 1));
}
}
};
return (_jsxs(Box, { className: cn(getWizardAccordionSectionClassName(hasExpandedCard, expandedFillsSpace), 'twa:mt-3'), children: [_jsxs(Flex, { flexDirection: "row", alignItems: "center", justifyContent: "space-between", className: "twa:mb-2 twa:shrink-0", children: [_jsx(Box, { className: "twa:text-2 twa:max-w-[520px]", children: "Add buttons to the notification and set actions to perform when clicked" }), _jsx(ButtonNew, { onClick: handleAddButton, children: "Add" })] }), _jsx(Flex, { flexDirection: "column", className: "twa:gap-3 twa:min-h-0", children: alertButtons.map((button, index) => {
const cardBinding = bindCard(alertButtonCardId(index));
return (_jsx(CollapsibleWizardCard, { ...cardBinding, surface: "panel", "data-name": `alert-button-${index}`, title: `Button ${index + 1}`, help: "Set button text, style, icon, and actions", collapsedHelp: false, compactSummary: _jsx(AlertButtonCompactSummary, { button: button }), headerVisual: _jsxs(Flex, { alignItems: "center", justifyContent: "space-end", className: "twa:gap-1 twa:min-w-0 twa:overflow-hidden twa:flex-wrap", children: [_jsx(AlertButtonPreview, { button: button, messageType: messageType }), cardBinding.compact ? _jsx(AlertButtonActionTags, { button: button }) : null] }), headerActions: _jsx(SimpleButton, { icon: "delete", disabled: alertButtons.length <= 1, variant: "text", tooltip: alertButtons.length <= 1 ? 'Cannot remove last button' : 'Delete button', onClick: () => handleDeleteButton(index) }), summary: _jsx(AlertButtonCardSummary, { button: button }), bodyClassName: "twa:!pt-0", children: _jsx(AlertButtonEditorForm, { button: button, index: index, alertButtons: alertButtons, buttonCommands: buttonCommands, onChange: onChange }) }, alertButtonCardId(index)));
}) })] }));
};