@adaptabletools/adaptable
Version:
Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
439 lines (438 loc) • 36 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as React from 'react';
import { uniq } from '../../../Utilities/Extensions/ArrayExtensions';
import { clamp } from '../../../Utilities/Extensions/NumberExtensions';
import HelpBlock from '../../../components/HelpBlock';
import Input from '../../../components/Input';
import SimpleButton from '../../../components/SimpleButton';
import { isAdaptableNumericFormatPreset, resolveDisplayFormat, } from '../../../AdaptableState/Common/AdaptableFormatPresets';
import { CheckBox } from '../../../components/CheckBox';
import FormLayout, { FormRow } from '../../../components/FormLayout';
import { AdaptableObjectRow } from '../../Components/AdaptableObjectRow';
import Radio from '../../../components/Radio';
import { useOnePageAdaptableWizardContext } from '../../Wizard/OnePageAdaptableWizard';
import StringExtensions from '../../../Utilities/Extensions/StringExtensions';
import { Tag } from '../../../components/Tag';
import { useAdaptable } from '../../AdaptableContext';
import FormatHelper from '../../../Utilities/Helpers/DisplayFormatHelper';
import { Toggle, ToggleGroup } from '../../../components/Toggle';
import { DEFAULT_DOUBLE_DISPLAY_VALUE, DEFAULT_STRING_DISPLAY_VALUE, } from '../../../Utilities/Constants/GeneralConstants';
import Textarea from '../../../components/Textarea';
import { ButtonInfo } from '../../Components/Buttons/ButtonInfo';
import { FormatColumnPlaceholderDocsLink } from '../../../Utilities/Constants/DocumentationLinkConstants';
import { PIVOT_AGGREGATION_TOTAL_COLUMN_TYPE, PIVOT_ANY_TOTAL_COLUMN_TYPE, PIVOT_COLUMN_TOTAL_COLUMN_TYPE, PIVOT_GRAND_TOTAL_COLUMN_TYPE, } from '../../../AdaptableState/Common/AdaptableColumn';
import { Box, Flex } from '../../../components/Flex';
import { Card } from '../../../components/Card';
import { isObjectEmpty } from '../../../Utilities/Extensions/ObjectExtensions';
import { DataSource, InfiniteTableGrid, } from '../../../components/InfiniteTable';
const DateFormatPresets = [
'MM/dd/yyyy',
'dd-MM-yyyy',
'MMMM do yyyy, h:mm:ss a',
'EEEE',
'MMM do yyyy',
'yyyyMMdd',
'HH:mm:ss',
];
const NUMERIC_PRESET_LABELS = {
Percentage: 'Percentage',
Thousand: 'K (Thousand)',
Million: 'M (Million)',
Billion: 'B (Billion)',
BasisPoints: 'bps (Basis Pts)',
Dollar: 'Dollar',
Sterling: 'Sterling',
Euro: 'Euro',
Yen: 'Yen',
Bitcoin: 'Bitcoin',
Integer: 'Integer',
Decimal: 'Decimal',
Accounting: 'Accounting',
FXRate: 'FX Rate',
Scientific: 'Scientific',
};
const appendDisplayFormatItem = (items, label, value) => {
if (value == null || value === '' || value === false) {
return;
}
items.push({ label, value: String(value) });
};
const appendNumberFormatOptions = (items, options) => {
appendDisplayFormatItem(items, 'Fraction Digits', options.FractionDigits);
appendDisplayFormatItem(items, 'Fraction Separator', options.FractionSeparator);
appendDisplayFormatItem(items, 'Integer Digits', options.IntegerDigits);
appendDisplayFormatItem(items, 'Integer Separator', options.IntegerSeparator);
appendDisplayFormatItem(items, 'Prefix', options.Prefix);
appendDisplayFormatItem(items, 'Suffix', options.Suffix);
if (options.ZeroDisplay !== undefined && options.ZeroDisplay !== '0') {
items.push({
label: 'Zero Display',
value: options.ZeroDisplay === '' ? 'Blank' : options.ZeroDisplay,
});
}
appendDisplayFormatItem(items, 'Content', options.Content);
if (options.Multiplier != null && options.Multiplier !== 1) {
items.push({ label: 'Multiplier', value: String(options.Multiplier) });
}
appendDisplayFormatItem(items, 'Parentheses', options.Parentheses);
appendDisplayFormatItem(items, 'Truncate', options.Truncate);
appendDisplayFormatItem(items, 'Absolute Value', options.Abs);
appendDisplayFormatItem(items, 'Ceiling', options.Ceiling);
appendDisplayFormatItem(items, 'Floor', options.Floor);
appendDisplayFormatItem(items, 'Round', options.Round);
appendDisplayFormatItem(items, 'Empty', options.Empty);
if (options.Notation === 'scientific') {
items.push({ label: 'Notation', value: 'Scientific' });
}
if (options.CustomDisplayFormats?.length) {
items.push({
label: 'Custom Formats',
value: options.CustomDisplayFormats.join(', '),
});
}
};
const appendStringFormatOptions = (items, options) => {
appendDisplayFormatItem(items, 'Case', options.Case);
appendDisplayFormatItem(items, 'Trim', options.Trim);
appendDisplayFormatItem(items, 'Prefix', options.Prefix);
appendDisplayFormatItem(items, 'Suffix', options.Suffix);
appendDisplayFormatItem(items, 'Content', options.Content);
appendDisplayFormatItem(items, 'Empty', options.Empty);
if (options.CustomDisplayFormats?.length) {
items.push({
label: 'Custom Formats',
value: options.CustomDisplayFormats.join(', '),
});
}
};
export const getFormatColumnDisplayFormatSummaryItems = (data) => {
if (data.DisplayFormat == null) {
return [];
}
if (isAdaptableNumericFormatPreset(data.DisplayFormat)) {
return [{ label: 'Preset', value: NUMERIC_PRESET_LABELS[data.DisplayFormat] }];
}
if (data.DisplayFormat &&
typeof data.DisplayFormat === 'object' &&
isObjectEmpty(data.DisplayFormat.Options)) {
return [];
}
const resolved = resolveDisplayFormat(data.DisplayFormat);
if (!resolved) {
return [];
}
const items = [];
if (resolved.Formatter === 'NumberFormatter') {
appendNumberFormatOptions(items, resolved.Options);
return items;
}
if (resolved.Formatter === 'DateFormatter') {
const options = resolved.Options;
appendDisplayFormatItem(items, 'Pattern', options.Pattern);
if (options.CustomDisplayFormats?.length) {
items.push({
label: 'Custom Formats',
value: options.CustomDisplayFormats.join(', '),
});
}
return items;
}
if (resolved.Formatter === 'StringFormatter') {
appendStringFormatOptions(items, resolved.Options);
return items;
}
return items;
};
export const hasFormatColumnDisplayFormat = (data) => getFormatColumnDisplayFormatSummaryItems(data).length > 0;
export const getFormatColumnFormatSummaryTagValues = (data) => {
const items = getFormatColumnDisplayFormatSummaryItems(data);
if (!items.length) {
return [];
}
return items.map(({ label, value }) => (label ? `${label}: ${value}` : value));
};
const renderCustomFormatter = (data, customFormatter, setFormatOption) => {
const resolved = resolveDisplayFormat(data.DisplayFormat);
return (_jsx(FormRow, { label: customFormatter.label ?? customFormatter.id, children: _jsx(CheckBox, { "data-name": customFormatter.id, checked: resolved?.Options.CustomDisplayFormats?.some?.((item) => item === customFormatter.id), onChange: (checked) => {
let newCustomFormats = resolved?.Options?.CustomDisplayFormats ?? [];
if (checked) {
newCustomFormats = [...newCustomFormats, customFormatter.id];
}
else {
newCustomFormats = newCustomFormats.filter((item) => item !== customFormatter.id);
}
setFormatOption('CustomDisplayFormats', newCustomFormats);
} }) }, customFormatter.id));
};
export const renderFormatColumnFormatSummary = (data) => {
const tagValues = getFormatColumnFormatSummaryTagValues(data);
if (!tagValues.length) {
return _jsx(Tag, { children: "No Display Format" });
}
return (_jsx(Flex, { alignItems: "center", className: "twa:flex-wrap twa:gap-2", children: tagValues.map((tag) => (_jsx(Tag, { children: tag }, tag))) }));
};
export const getFormatDisplayTypeForScope = (scope, api) => {
if (scope == undefined) {
return undefined;
}
if ('All' in scope) {
return undefined;
}
const dateTypes = api.columnApi.internalApi.getColumnDateTypes();
if ('ColumnIds' in scope) {
const columns = scope.ColumnIds.map((c) => api.columnApi.getColumnWithColumnId(c)).filter(Boolean);
const columnDataTypes = uniq(columns.map((c) => c.dataType));
if (columnDataTypes.length === 1) {
const dataType = columnDataTypes[0];
if (dataType === 'number') {
return 'number';
}
if (dateTypes.includes(dataType)) {
return 'date';
}
if (dataType === 'text') {
return 'text';
}
}
else if (columnDataTypes.length > 0 &&
columnDataTypes.every((type) => dateTypes.includes(type))) {
return 'date';
}
return undefined;
}
if ('DataTypes' in scope && scope.DataTypes.length === 1) {
const dataType = scope.DataTypes[0];
if (dataType === 'number') {
return 'number';
}
if (dateTypes.includes(dataType)) {
return 'date';
}
if (dataType === 'text') {
return 'text';
}
}
else if ('DataTypes' in scope &&
scope.DataTypes.length > 0 &&
scope.DataTypes.every((type) => dateTypes.includes(type))) {
return 'date';
}
if ('ColumnTypes' in scope && scope.ColumnTypes.length) {
const pivotTotalTypes = [
PIVOT_ANY_TOTAL_COLUMN_TYPE,
PIVOT_GRAND_TOTAL_COLUMN_TYPE,
PIVOT_COLUMN_TOTAL_COLUMN_TYPE,
PIVOT_AGGREGATION_TOTAL_COLUMN_TYPE,
];
if (scope.ColumnTypes.length > 0 &&
scope.ColumnTypes.every((type) => pivotTotalTypes.includes(type))) {
return 'number';
}
const columns = scope.ColumnTypes.flatMap((columnType) => {
return api.columnApi.getColumnsByColumnType(columnType);
});
if (columns.length) {
const allSameType = columns.every((column) => column.dataType === columns[0].dataType);
if (allSameType) {
const dataType = columns[0].dataType;
if (dataType === 'number') {
return 'number';
}
if (dateTypes.includes(dataType)) {
return 'date';
}
if (dataType === 'text') {
return 'text';
}
}
const allDateTypes = columns.every((column) => dateTypes.includes(column.dataType));
if (allDateTypes) {
return 'date';
}
}
}
return undefined;
};
const NUMBER_FORMAT_INPUT_CLASS = 'twa:w-[72px] twa:min-w-[72px] twa:max-w-[72px]';
const NUMBER_FORMAT_LABEL_COLUMN = {
name: 'label',
className: 'ab-FormLayout_column--label twa:whitespace-nowrap',
};
const NUMBER_FORMAT_CHECKBOX_CHILDREN_COLUMN = {
name: 'children',
className: 'twa:pl-2',
};
const NUMBER_FORMAT_VALUE_CHILDREN_COLUMN = {
name: 'children',
className: 'twa:pl-2',
};
const NUMBER_FORMAT_DIGIT_FORM_SIZES = ['148px', '72px'];
const NUMBER_FORMAT_VALUE_FORM_SIZES = ['92px', '72px'];
const NUMBER_FORMAT_CHECKBOX_FORM_SIZES = ['72px', 'auto'];
const DATE_FORMAT_PRESET_ROW_HEIGHT = 32;
const DATE_FORMAT_PRESET_HEADER_HEIGHT = 40;
const DateFormatPresetsTable = ({ onApplyPattern }) => {
const rows = React.useMemo(() => DateFormatPresets.map((pattern) => ({
pattern,
formattedDate: FormatHelper.DateFormatter(new Date(), { Pattern: pattern }) ?? '',
})), []);
const columns = React.useMemo(() => ({
pattern: {
field: 'pattern',
header: 'Pattern',
defaultFlex: 1,
renderMenuIcon: false,
},
formattedDate: {
field: 'formattedDate',
header: 'Formatted Date',
defaultFlex: 1,
renderMenuIcon: false,
},
apply: {
field: 'pattern',
header: '',
defaultWidth: 80,
align: 'center',
renderMenuIcon: false,
render: ({ data }) => (_jsx(SimpleButton, { "data-name": "apply-format-pattern", "data-value": data.pattern, onClick: () => onApplyPattern(data.pattern), children: "Apply" })),
},
}), [onApplyPattern]);
const tableHeight = DATE_FORMAT_PRESET_HEADER_HEIGHT + rows.length * DATE_FORMAT_PRESET_ROW_HEIGHT;
return (_jsx(DataSource, { data: rows, primaryKey: "pattern", children: _jsx(InfiniteTableGrid, { sortable: false, domProps: { style: { height: tableHeight, width: '100%' } }, columns: columns }) }));
};
const renderDateFormat = (data, _onChange, setFormatOption, scopedCustomFormatters) => {
const resolved = resolveDisplayFormat(data.DisplayFormat);
if (resolved?.Formatter !== 'DateFormatter') {
return null;
}
return (_jsxs(Flex, { flexDirection: "column", className: "twa:gap-3 twa:p-3", children: [_jsxs(Card, { shadow: false, children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Format" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[520px]", children: "Enter a Unicode date pattern (e.g. dd/MM/yyyy), or pick a preset below" })] }), _jsx(Card.Body, { children: _jsx(FormLayout, { children: _jsxs(FormRow, { label: "Pattern", children: [_jsx(Input, { "data-name": "pattern", value: resolved.Options.Pattern ?? '', onChange: (e) => setFormatOption('Pattern', e.currentTarget.value), className: "twa:mr-2" }), _jsx("span", { children: resolved.Options.Pattern &&
FormatHelper.DateFormatter(new Date(), resolved.Options, true) })] }) }) })] }), scopedCustomFormatters.length > 0 && (_jsxs(Card, { shadow: false, children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Custom Formats" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[520px]", children: "Apply a developer-defined formatter to this Column" })] }), _jsx(Card.Body, { children: _jsx(FormLayout, { children: scopedCustomFormatters.map((formatter) => renderCustomFormatter(data, formatter, setFormatOption)) }) })] })), _jsxs(Card, { shadow: false, children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Presets" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[520px]", children: "Apply a common date pattern as a starting point" })] }), _jsx(Card.Body, { className: "twa:px-0 twa:pt-0 twa:pb-1", children: _jsx(DateFormatPresetsTable, { onApplyPattern: (pattern) => setFormatOption('Pattern', pattern) }) })] })] }));
};
const renderNumberFormat = (data, onChange, setFormatOption, scopedCustomFormatters, api) => {
const resolved = resolveDisplayFormat(data.DisplayFormat);
if (resolved?.Formatter !== 'NumberFormatter') {
return null;
}
const setPreset = (preset) => {
onChange({ DisplayFormat: preset });
};
const activePreset = isAdaptableNumericFormatPreset(data.DisplayFormat)
? data.DisplayFormat
: undefined;
const IS_PERCENT = activePreset === 'Percentage';
const IS_THOUSAND = activePreset === 'Thousand';
const IS_MILLION = activePreset === 'Million';
const IS_BILLION = activePreset === 'Billion';
const IS_BASIS_POINTS = activePreset === 'BasisPoints';
const IS_DOLLAR = activePreset === 'Dollar';
const IS_STERLING = activePreset === 'Sterling';
const IS_EURO = activePreset === 'Euro';
const IS_YEN = activePreset === 'Yen';
const IS_BITCOIN = activePreset === 'Bitcoin';
const IS_INTEGER = activePreset === 'Integer';
const IS_DECIMAL = activePreset === 'Decimal';
const IS_ACCOUNTING = activePreset === 'Accounting';
const IS_FX_RATE = activePreset === 'FXRate';
const IS_SCIENTIFIC = activePreset === 'Scientific';
const showDocumentationLinks = api.internalApi.isDocumentationLinksDisplayed();
return (_jsxs(Flex, { flexDirection: "column", "data-name": 'format-column-display-format', className: "twa:gap-3 twa:p-3", children: [_jsxs(Card, { shadow: false, children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Presets" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[520px]", children: "Pick a common numeric preset as a starting point" })] }), _jsx(Card.Body, { children: _jsxs(Flex, { flexDirection: "row", className: "twa:m-2", children: [_jsxs(Flex, { flexDirection: "column", className: "twa:mr-6", children: [_jsx(Radio, { "data-name": "preset-dollar", className: "twa:my-1", checked: IS_DOLLAR, onChange: () => setPreset('Dollar'), children: "Dollar" }), _jsx(Radio, { "data-name": "preset-sterling", className: "twa:my-1", checked: IS_STERLING, onChange: () => setPreset('Sterling'), children: "Sterling" }), _jsx(Radio, { "data-name": "preset-euro", className: "twa:my-1", checked: IS_EURO, onChange: () => setPreset('Euro'), children: "Euro" }), _jsx(Radio, { "data-name": "preset-yen", className: "twa:my-1", checked: IS_YEN, onChange: () => setPreset('Yen'), children: "Yen" })] }), _jsxs(Flex, { flexDirection: "column", className: "twa:mr-6", children: [_jsx(Radio, { "data-name": "preset-thousand", className: "twa:my-1", checked: IS_THOUSAND, onChange: () => setPreset('Thousand'), children: "K (Thousand)" }), _jsx(Radio, { "data-name": "preset-million", className: "twa:my-1", checked: IS_MILLION, onChange: () => setPreset('Million'), children: "M (Million)" }), _jsx(Radio, { "data-name": "preset-billion", className: "twa:my-1", checked: IS_BILLION, onChange: () => setPreset('Billion'), children: "B (Billion)" }), _jsx(Radio, { "data-name": "preset-basis-points", className: "twa:my-1", checked: IS_BASIS_POINTS, onChange: () => setPreset('BasisPoints'), children: "bps (Basis Pts)" })] }), _jsxs(Flex, { flexDirection: "column", className: "twa:mr-6", children: [_jsx(Radio, { "data-name": "preset-integer", className: "twa:my-1", checked: IS_INTEGER, onChange: () => setPreset('Integer'), children: "Integer" }), _jsx(Radio, { "data-name": "preset-decimal", className: "twa:my-1", checked: IS_DECIMAL, onChange: () => setPreset('Decimal'), children: "Decimal" }), _jsx(Radio, { "data-name": "preset-percentage", className: "twa:my-1", checked: IS_PERCENT, onChange: () => setPreset('Percentage'), children: "Percentage" }), _jsx(Radio, { "data-name": "preset-scientific", className: "twa:my-1", checked: IS_SCIENTIFIC, onChange: () => setPreset('Scientific'), children: "Scientific" })] }), _jsxs(Flex, { flexDirection: "column", children: [_jsx(Radio, { "data-name": "preset-accounting", className: "twa:my-1", checked: IS_ACCOUNTING, onChange: () => setPreset('Accounting'), children: "Accounting" }), _jsx(Radio, { "data-name": "preset-fx-rate", className: "twa:my-1", checked: IS_FX_RATE, onChange: () => setPreset('FXRate'), children: "FX Rate" }), _jsx(Radio, { "data-name": "preset-bitcoin", className: "twa:my-1", checked: IS_BITCOIN, onChange: () => setPreset('Bitcoin'), children: "Bitcoin" })] })] }) })] }), _jsxs(Card, { shadow: false, className: "twa:pl-0", children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Format" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[520px]", children: "Fine-tune digits, separators, prefix / suffix and rounding behaviour" })] }), _jsx(Card.Body, { className: "twa:px-0 twa:pt-0 twa:pb-1", children: _jsxs(Box, { className: "twa:flex twa:flex-row twa:items-start twa:-ml-0.5", children: [_jsxs(FormLayout, { sizes: NUMBER_FORMAT_DIGIT_FORM_SIZES, columns: [NUMBER_FORMAT_LABEL_COLUMN, { name: 'children' }], className: "twa:mr-6 twa:shrink-0", children: [_jsx(FormRow, { label: "Fraction Digits", children: _jsx(Input, { className: NUMBER_FORMAT_INPUT_CLASS, "data-name": "fraction-digits", type: "number", min: "0", value: typeof resolved.Options.FractionDigits === 'number'
? resolved.Options.FractionDigits
: '', onChange: (e) => setFormatOption('FractionDigits', StringExtensions.IsNumeric(e.currentTarget.value)
? clamp(Number(e.currentTarget.value), 0, 20)
: undefined) }) }), _jsx(FormRow, { label: "Integer Digits", children: _jsx(Input, { className: NUMBER_FORMAT_INPUT_CLASS, "data-name": "integer-digits", type: "number", min: "0", value: resolved.Options.IntegerDigits, onChange: (e) => setFormatOption('IntegerDigits', StringExtensions.IsNumeric(e.currentTarget.value)
? clamp(Number(e.currentTarget.value), 0, 20)
: undefined) }) }), _jsx(FormRow, { label: "Fraction Separator", children: _jsx(Input, { className: NUMBER_FORMAT_INPUT_CLASS, "data-name": "fraction-separator", value: resolved.Options.FractionSeparator ?? '', onChange: (e) => setFormatOption('FractionSeparator', e.currentTarget.value) }) }), _jsx(FormRow, { label: "Integer Separator", children: _jsx(Input, { className: NUMBER_FORMAT_INPUT_CLASS, "data-name": "integer-separator", value: resolved.Options.IntegerSeparator ?? '', onChange: (e) => setFormatOption('IntegerSeparator', e.currentTarget.value) }) })] }), _jsxs(FormLayout, { sizes: NUMBER_FORMAT_VALUE_FORM_SIZES, columns: [NUMBER_FORMAT_LABEL_COLUMN, NUMBER_FORMAT_VALUE_CHILDREN_COLUMN], className: "twa:mr-5 twa:shrink-0", children: [_jsx(FormRow, { label: "Multiplier", children: _jsx(Input, { className: NUMBER_FORMAT_INPUT_CLASS, "data-name": "multiplier", type: "number", value: resolved.Options.Multiplier, onChange: (e) => setFormatOption('Multiplier', Number(e.currentTarget.value)) }) }), _jsx(FormRow, { label: "Prefix", children: _jsx(Input, { className: NUMBER_FORMAT_INPUT_CLASS, "data-name": "prefix", value: resolved.Options.Prefix ?? '', onChange: (e) => setFormatOption('Prefix', e.currentTarget.value) }) }), _jsx(FormRow, { label: "Suffix", children: _jsx(Input, { className: NUMBER_FORMAT_INPUT_CLASS, "data-name": "suffix", value: resolved.Options.Suffix ?? '', onChange: (e) => setFormatOption('Suffix', e.currentTarget.value) }) }), _jsx(FormRow, { label: "Zero Display", children: _jsx(Input, { className: NUMBER_FORMAT_INPUT_CLASS, "data-name": "zero-display", value: resolved.Options.ZeroDisplay === undefined ||
resolved.Options.ZeroDisplay === '0'
? '0'
: resolved.Options.ZeroDisplay, onChange: (e) => {
const value = e.currentTarget.value;
if (value === '') {
setFormatOption('ZeroDisplay', '');
}
else if (value === '0') {
setFormatOption('ZeroDisplay', undefined);
}
else {
setFormatOption('ZeroDisplay', value);
}
} }) })] }), _jsxs(Flex, { className: "twa:gap-2 twa:shrink-0", children: [_jsxs(FormLayout, { sizes: NUMBER_FORMAT_CHECKBOX_FORM_SIZES, columns: [NUMBER_FORMAT_LABEL_COLUMN, NUMBER_FORMAT_CHECKBOX_CHILDREN_COLUMN], children: [_jsx(FormRow, { label: "Parentheses", children: _jsx(CheckBox, { "data-name": "parentheses-checkbox", checked: resolved.Options.Parentheses, onChange: (checked) => setFormatOption('Parentheses', checked) }) }), _jsx(FormRow, { label: "Empty", children: _jsx(CheckBox, { "data-name": "empty-checkbox", checked: resolved.Options.Empty, onChange: (checked) => setFormatOption('Empty', checked) }) }), _jsx(FormRow, { label: "Truncate", children: _jsx(CheckBox, { "data-name": "truncate-checkbox", checked: resolved.Options.Truncate, onChange: (checked) => setFormatOption('Truncate', checked) }) }), _jsx(FormRow, { label: "Round", children: _jsx(CheckBox, { "data-name": "round-checkbox", checked: resolved.Options.Round, onChange: (checked) => setFormatOption('Round', checked) }) })] }), _jsxs(FormLayout, { sizes: NUMBER_FORMAT_CHECKBOX_FORM_SIZES, columns: [NUMBER_FORMAT_LABEL_COLUMN, { name: 'children' }], children: [_jsx(FormRow, { label: "Ceiling", children: _jsx(CheckBox, { "data-name": "ceiling-checkbox", checked: resolved.Options.Ceiling, onChange: (checked) => setFormatOption('Ceiling', checked) }) }), _jsx(FormRow, { label: "Floor", children: _jsx(CheckBox, { "data-name": "floor-checkbox", checked: resolved.Options.Floor, onChange: (checked) => setFormatOption('Floor', checked) }) }), _jsx(FormRow, { label: "Absolute", children: _jsx(CheckBox, { "data-name": "abs-checkbox", checked: resolved.Options.Abs, onChange: (checked) => setFormatOption('Abs', checked) }) }), _jsx(FormRow, { label: "Scientific", children: _jsx(CheckBox, { "data-name": "scientific-checkbox", checked: resolved.Options.Notation === 'scientific', onChange: (checked) => setFormatOption('Notation', checked ? 'scientific' : undefined) }) })] })] })] }) })] }), scopedCustomFormatters.length > 0 && (_jsxs(Card, { shadow: false, children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Custom Formats" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[520px]", children: "Apply a developer-defined formatter to this Column" })] }), _jsx(Card.Body, { children: _jsx(Flex, { flexDirection: "row", children: _jsx(FormLayout, { children: scopedCustomFormatters.map((formatter) => renderCustomFormatter(data, formatter, setFormatOption)) }) }) })] })), _jsxs(Card, { shadow: false, children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Dynamic Content" }), _jsxs(Flex, { alignItems: "center", className: "twa:gap-1 twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[520px]", children: [_jsx(Box, { children: "Provide dynamic content through the use of Placeholders" }), showDocumentationLinks && (_jsx(ButtonInfo, { variant: "text", tone: "accent", tooltip: "Learn more about using placeholders", onClick: () => window.open(FormatColumnPlaceholderDocsLink, '_blank') }))] })] }), _jsx(Card.Body, { children: _jsxs(FormLayout, { className: "twa:m-2", children: [_jsx(FormRow, { label: "", children: _jsx(Textarea, { className: "twa:min-w-[300px] twa:mt-2", rows: 3, placeholder: "", type: 'text', autoFocus: false, value: resolved.Options.Content?.toString() ?? '', onChange: (e) => setFormatOption('Content', e.currentTarget.value) }) }), ' '] }) })] }), _jsxs(Card, { shadow: false, children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Examples" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[520px]", children: "Preview the formatter against sample values" })] }), _jsxs(Card.Body, { children: [_jsx(AdaptableObjectRow, { className: "twa:font-bold", colItems: [
{ Content: 'Raw Number', Size: 1 },
{ Content: 'Formatted Number', Size: 1 },
] }), _jsx(AdaptableObjectRow, { colItems: [
{ Content: DEFAULT_DOUBLE_DISPLAY_VALUE, Size: 1 },
{
Content: FormatHelper.NumberFormatter(DEFAULT_DOUBLE_DISPLAY_VALUE, resolved.Options),
Size: 1,
},
] }), _jsx(AdaptableObjectRow, { colItems: [
{ Content: '-' + DEFAULT_DOUBLE_DISPLAY_VALUE, Size: 1 },
{
Content: FormatHelper.NumberFormatter(-DEFAULT_DOUBLE_DISPLAY_VALUE, resolved.Options),
Size: 1,
},
] }), _jsx(AdaptableObjectRow, { colItems: [
{ Content: '0.123', Size: 1 },
{
Content: FormatHelper.NumberFormatter(0.123, resolved.Options),
Size: 1,
},
] }), _jsx(AdaptableObjectRow, { colItems: [
{ Content: '0', Size: 1 },
{
Content: FormatHelper.NumberFormatter(0, resolved.Options),
Size: 1,
},
] })] })] })] }));
};
const renderStringFormat = (data, _onChange, setFormatOption, scopedCustomFormatters, api) => {
const resolved = resolveDisplayFormat(data.DisplayFormat);
if (resolved?.Formatter !== 'StringFormatter') {
return null;
}
const showDocumentationLinks = api.internalApi.isDocumentationLinksDisplayed();
return (_jsxs(Flex, { flexDirection: "column", "data-name": 'format-column-display-format', className: "twa:gap-3 twa:p-3", children: [_jsxs(Card, { shadow: false, children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Format" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[520px]", children: "Customise the string format with case, trim, prefix / suffix and dynamic content" })] }), _jsxs(Card.Body, { className: "twa:grid twa:p-2 twa:grid-cols-[1fr_1fr] twa:gap-2", children: [_jsxs(Flex, { flexDirection: "row", className: "twa:gap-2 twa:col-span-2 twa:items-center", children: [_jsx("label", { children: "Case:" }), _jsxs(ToggleGroup, { children: [_jsx(Toggle, { pressed: resolved.Options.Case === 'Upper', onPressedChange: (pressed) => setFormatOption('Case', pressed ? 'Upper' : undefined), icon: "case-upper" }), _jsx(Toggle, { pressed: resolved.Options.Case === 'Lower', onPressedChange: (pressed) => setFormatOption('Case', pressed ? 'Lower' : undefined), icon: "case-lower" }), _jsx(Toggle, { pressed: resolved.Options.Case === 'Sentence', onPressedChange: (pressed) => setFormatOption('Case', pressed ? 'Sentence' : undefined), icon: "case-sentence" })] }), _jsx(CheckBox, { "data-name": "trim-checkbox", className: "twa:ml-5", checked: resolved.Options.Trim, onChange: (checked) => setFormatOption('Trim', checked), children: "Trim" })] }), _jsxs(Flex, { flexDirection: "column", className: "twa:gap-2", children: [_jsx("label", { children: "Prefix" }), _jsx(Input, { "data-name": "prefix", value: resolved.Options.Prefix ?? '', onChange: (e) => setFormatOption('Prefix', e.currentTarget.value) })] }), _jsxs(Flex, { flexDirection: "column", className: "twa:gap-2", children: [_jsx("label", { children: "Suffix" }), _jsx(Input, { "data-name": "suffix", value: resolved.Options.Suffix ?? '', onChange: (e) => setFormatOption('Suffix', e.currentTarget.value) })] }), _jsxs(Flex, { flexDirection: "column", className: "twa:col-span-2 twa:gap-2", children: [_jsx("label", { children: "Content" }), _jsx(Textarea, { className: "twa:min-w-[300px]", rows: 3, placeholder: "", type: 'text', autoFocus: false, value: resolved.Options.Content ?? '', onChange: (e) => setFormatOption('Content', e.currentTarget.value) }), showDocumentationLinks && (_jsxs(HelpBlock, { "data-name": "query-documentation", className: "twa:mt-3 twa:mb-2 twa:p-0 twa:text-3", children: [_jsx(ButtonInfo, { className: "twa:mr-2", onClick: () => window.open(FormatColumnPlaceholderDocsLink, '_blank') }), "See how to create dynamic Display Format using placeholders"] }))] }), _jsx(CheckBox, { className: "twa:col-span-2", "data-name": "empty-checkbox", checked: resolved.Options.Empty, onChange: (checked) => setFormatOption('Empty', checked), children: "Empty" })] })] }), scopedCustomFormatters.length > 0 && (_jsxs(Card, { shadow: false, children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Custom Formats" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[520px]", children: "Apply a developer-defined formatter to this Column" })] }), _jsx(Card.Body, { children: _jsx(Flex, { flexDirection: "column", children: _jsx(FormLayout, { className: "twa:mr-3", children: scopedCustomFormatters.map((formatter) => renderCustomFormatter(data, formatter, setFormatOption)) }) }) })] })), _jsxs(Card, { shadow: false, children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Example" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[520px]", children: "Preview the formatter against a sample value" })] }), _jsxs(Card.Body, { children: [_jsx(AdaptableObjectRow, { className: "twa:font-bold", colItems: [
{ Content: 'Raw String', Size: 1 },
{ Content: 'Formatted String', Size: 1 },
] }), _jsx(AdaptableObjectRow, { colItems: [
{ Content: '"' + DEFAULT_STRING_DISPLAY_VALUE + '"', Size: 1 },
{
Content: '"' +
FormatHelper.StringFormatter(DEFAULT_STRING_DISPLAY_VALUE, resolved.Options) +
'"',
Size: 1,
},
] })] })] })] }));
};
export const FormatColumnFormatWizardSection = (props) => {
const { data } = useOnePageAdaptableWizardContext();
const adaptable = useAdaptable();
const customDisplayFormatters = adaptable.api.optionsApi.getFormatColumnOptions().customDisplayFormatters ?? [];
const update = (updated) => {
props.onChange({ ...data, ...updated });
};
const setFormatOption = (key, value) => {
const current = resolveDisplayFormat(data.DisplayFormat);
if (!current)
return;
const DisplayFormat = {
Formatter: current.Formatter,
Options: { ...current.Options, [key]: value },
};
update({ DisplayFormat });
};
const Type = isAdaptableNumericFormatPreset(data.DisplayFormat)
? 'NumberFormatter'
: data.DisplayFormat && data.DisplayFormat.Formatter;
const customScopedFormatters = customDisplayFormatters.filter((displayFormatter) => adaptable.api.columnScopeApi.isScopeInScope(data.Scope, displayFormatter.scope));
if (Type === 'NumberFormatter') {
return renderNumberFormat(data, update, setFormatOption, customScopedFormatters, adaptable.api);
}
if (Type === 'DateFormatter') {
return renderDateFormat(data, update, setFormatOption, customScopedFormatters);
}
if (Type === 'StringFormatter') {
return renderStringFormat(data, update, setFormatOption, customScopedFormatters, adaptable.api);
}
return (_jsxs(HelpBlock, { className: "twa:m-2", children: ["Setting a Display Format is only possible if ", _jsx("b", { children: "all" }), " the columns in Scope are Numeric, String or Date"] }));
};