UNPKG

@adaptabletools/adaptable

Version:

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

178 lines (177 loc) 11.9 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { CheckBox } from '../../../components/CheckBox'; import ErrorBox from '../../../components/ErrorBox'; import FormLayout, { FormRow } from '../../../components/FormLayout'; import { Tag } from '../../../components/Tag'; import { ColorPicker } from '../../../components/ColorPicker'; import { useOnePageAdaptableWizardContext } from '../../Wizard/OnePageAdaptableWizard'; import { Box, Flex } from '../../../components/Flex'; import { SingleSelect } from '../../../components/NewSelect'; import Input from '../../../components/Input'; import { getCellBoxStyleSummaryItems, StyledColumnCellStyleEditor, } from './StyledColumnSliceStyleEditors'; import { Card } from '../../../components/Card'; import { renderSummaryStringTags } from '../../Wizard/SummaryColorTag'; import { DEFAULT_RATING_GAP, DEFAULT_RATING_ICON, DEFAULT_RATING_MAX, DEFAULT_RATING_SIZE, } from './StyledColumnWizardStyleSection/Components/StyledColumnRatingPreview'; const STYLE_FORM_SIZES = ['200px', '1fr']; const ICON_CHOICES = [ { value: 'Star', label: 'Star' }, { value: 'Heart', label: 'Heart' }, { value: 'Circle', label: 'Circle' }, { value: 'Thumb', label: 'Thumb' }, ]; const formatRatingToolTipSummary = (toolTipText) => toolTipText ?.map((t) => (t === 'CellValue' ? 'Cell Value' : 'Percentage Value')) .join(' + ') ?? ''; const buildStyledColumnRatingStyleSummaryStrings = (rating, options) => { const items = [ `Max: ${rating.Max ?? DEFAULT_RATING_MAX}`, `Icon: ${rating.Icon ?? DEFAULT_RATING_ICON}`, ]; if (rating.FilledColor) { items.push(`Filled Colour: ${rating.FilledColor}`); } if (rating.EmptyColor) { items.push(`Empty Colour: ${rating.EmptyColor}`); } if (rating.Size != null) { items.push(`Icon Size: ${rating.Size}px`); } if (rating.Gap != null) { items.push(`Icon Gap: ${rating.Gap}px`); } items.push(`Allow Half: ${(rating.AllowHalf ?? true) ? 'Yes' : 'No'}`); items.push(`Show Value: ${rating.ShowValue ? 'Yes' : 'No'}`); if (rating.ToolTipText?.length) { items.push(`Tooltip: ${formatRatingToolTipSummary(rating.ToolTipText)}`); } else if (options.includeEmptyTooltip) { items.push('Tooltip: No Tooltip'); } getCellBoxStyleSummaryItems(rating.Cell).forEach(({ label, value }) => { items.push(`${label}: ${value}`); }); return items; }; export const getStyledColumnRatingStyleViewValues = (data) => { const rating = data.RatingStyle; if (!rating) { return []; } return buildStyledColumnRatingStyleSummaryStrings(rating, { includeEmptyTooltip: false, }); }; const resolveCssVar = (varName, fallbackHex) => { if (typeof window === 'undefined') return fallbackHex; try { const v = getComputedStyle(document.documentElement) .getPropertyValue(varName) .trim(); return v || fallbackHex; } catch { return fallbackHex; } }; const getDisplayedFilledColor = (rating) => rating.FilledColor || resolveCssVar('--ab-color-warn', '#f5a623'); const getDisplayedEmptyColor = (rating) => { if (rating.EmptyColor) return rating.EmptyColor; if (typeof window === 'undefined') return 'rgba(127, 127, 127, 0.22)'; try { const fg = getComputedStyle(document.body).color || 'rgb(0, 0, 0)'; const m = fg.match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/); if (m) { return `rgba(${m[1]}, ${m[2]}, ${m[3]}, 0.22)`; } } catch { } return 'rgba(127, 127, 127, 0.22)'; }; export const renderStyledColumnRatingSummary = (data) => { const rating = data.RatingStyle; if (!rating) { return _jsx(Tag, { children: "No Styling Defined" }); } const items = buildStyledColumnRatingStyleSummaryStrings(rating, { includeEmptyTooltip: true, }); return renderSummaryStringTags(items); }; export const isValidRatingStyle = (data) => { const rating = data.RatingStyle; if (!rating) { return 'Rating Style is missing'; } if (rating.Max != undefined && (rating.Max < 1 || !Number.isFinite(rating.Max))) { return 'Max must be a positive number'; } if (rating.Size != undefined && rating.Size < 4) { return 'Icon size must be at least 4 pixels'; } return true; }; export const StyledColumnWizardRatingSection = (props) => { const { data, api } = useOnePageAdaptableWizardContext(); const rating = data.RatingStyle ?? {}; const disabled = !data.ColumnId; if (!data.ColumnId) { return (_jsx(Box, { children: _jsx(ErrorBox, { className: "twa:mt-2", children: "You need to select a column before styling." }) })); } const update = (patch) => { props.onChange({ ...data, RatingStyle: { ...rating, ...patch }, }); }; const toggleToolTipText = (token, checked) => { const current = rating.ToolTipText ?? []; const next = checked ? [...current.filter((t) => t !== token), token] : current.filter((t) => t !== token); update({ ToolTipText: next }); }; return (_jsxs(Box, { children: [_jsxs(Card, { shadow: false, className: "twa:mb-3", children: [_jsx(Card.Title, { children: "Icon" }), _jsx(Card.Body, { children: _jsxs(FormLayout, { sizes: [...STYLE_FORM_SIZES], children: [_jsx(FormRow, { label: "Max:", children: _jsxs(Flex, { alignItems: "center", className: "twa:gap-2", children: [_jsx(Input, { type: "number", min: 1, step: 1, value: rating.Max ?? '', placeholder: String(DEFAULT_RATING_MAX), style: { width: 80 }, onChange: (event) => { const raw = event.target.value; if (raw === '' || raw == null) { update({ Max: undefined }); return; } const parsed = Number(raw); update({ Max: Number.isFinite(parsed) && parsed >= 1 ? Math.floor(parsed) : undefined, }); } }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:min-w-0 twa:shrink", children: "Icon count and rating cap (no auto scaling is applied)" })] }) }), _jsx(FormRow, { label: "Icon:", children: _jsx(Box, { className: "twa:max-w-[160px]", children: _jsx(SingleSelect, { className: "twa:w-full", value: rating.Icon ?? DEFAULT_RATING_ICON, onValueChange: (v) => update({ Icon: v }), items: ICON_CHOICES }) }) }), _jsx(FormRow, { label: "Filled Colour:", children: _jsx(ColorPicker, { disabled: disabled, api: api, value: getDisplayedFilledColor(rating), onChange: (c) => update({ FilledColor: c }) }) }), _jsx(FormRow, { label: "Empty Colour:", children: _jsx(ColorPicker, { disabled: disabled, api: api, value: getDisplayedEmptyColor(rating), onChange: (c) => update({ EmptyColor: c }) }) }), _jsx(FormRow, { label: "Icon Size (px):", children: _jsxs(Flex, { alignItems: "center", className: "twa:gap-2", children: [_jsx(Input, { type: "number", min: 4, step: 1, value: rating.Size ?? '', placeholder: String(DEFAULT_RATING_SIZE), style: { width: 80 }, onChange: (event) => { const raw = event.target.value; if (raw === '' || raw == null) { update({ Size: undefined }); return; } const parsed = Number(raw); update({ Size: Number.isFinite(parsed) && parsed >= 4 ? parsed : undefined, }); } }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:min-w-0 twa:shrink", children: "Square pixel size of each icon" })] }) }), _jsx(FormRow, { label: "Icon Gap (px):", children: _jsxs(Flex, { alignItems: "center", className: "twa:gap-2", children: [_jsx(Input, { type: "number", min: 0, step: 1, value: rating.Gap ?? '', placeholder: String(DEFAULT_RATING_GAP), style: { width: 80 }, onChange: (event) => { const raw = event.target.value; if (raw === '' || raw == null) { update({ Gap: undefined }); return; } const parsed = Number(raw); update({ Gap: Number.isFinite(parsed) && parsed >= 0 ? parsed : undefined, }); } }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:min-w-0 twa:shrink", children: "Pixel space between adjacent icons" })] }) }), _jsx(FormRow, { label: "Allow Half Icons:", children: _jsx(CheckBox, { disabled: disabled, className: "twa:ml-2", checked: rating.AllowHalf ?? true, onChange: (checked) => update({ AllowHalf: checked }), children: "Render fractional values as a partial icon (e.g. 3.5 \u2192 \u2605\u2605\u2605\u00BD\u2606)" }) })] }) })] }), _jsxs(Card, { shadow: false, className: "twa:mb-3", children: [_jsx(Card.Title, { children: "Text" }), _jsx(Card.Body, { children: _jsxs(FormLayout, { sizes: [...STYLE_FORM_SIZES], children: [_jsx(FormRow, { label: "Show Value:", children: _jsx(CheckBox, { disabled: disabled, className: "twa:ml-2", checked: rating.ShowValue ?? false, onChange: (checked) => update({ ShowValue: checked }), children: "Display the numeric value beside the icons" }) }), _jsx(FormRow, { label: "Tooltip:", children: _jsxs(Flex, { flexDirection: "column", className: "twa:gap-1 twa:ml-2", children: [_jsx(CheckBox, { disabled: disabled, checked: rating.ToolTipText?.includes('CellValue') ?? false, onChange: (checked) => toggleToolTipText('CellValue', checked), children: "Cell Value" }), _jsx(CheckBox, { disabled: disabled, checked: rating.ToolTipText?.includes('PercentageValue') ?? false, onChange: (checked) => toggleToolTipText('PercentageValue', checked), children: "Percentage Value (value \u00F7 Max)" })] }) })] }) })] }), _jsxs(Card, { shadow: false, className: "twa:mb-3", children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Cell" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[500px]", children: "Optional Cell Style properties overrides Format Column properties)" })] }), _jsx(Card.Body, { children: _jsx(StyledColumnCellStyleEditor, { api: api, disabled: disabled, value: rating.Cell, onChange: (next) => { if (next) { update({ Cell: next }); } else { const cleaned = { ...rating }; delete cleaned.Cell; props.onChange({ ...data, RatingStyle: cleaned }); } } }) })] })] })); };