UNPKG

@adaptabletools/adaptable

Version:

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

439 lines (438 loc) 36 kB
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"] })); };