@splunk/dynamic-editors 0.42.0 → 0.42.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +28 -94
  2. package/DynamicEditor.js +70 -69
  3. package/DynamicEditor.js.map +1 -1
  4. package/containers/EditorItem.js +73 -72
  5. package/containers/EditorItem.js.map +1 -1
  6. package/containers/EditorLayout.js +81 -80
  7. package/containers/EditorLayout.js.map +1 -1
  8. package/containers/EditorLayoutItem.js +55 -54
  9. package/containers/EditorLayoutItem.js.map +1 -1
  10. package/editors/AdvancedConfigCard.js.map +1 -1
  11. package/editors/ArrayOfStringsEditor.js +4 -4
  12. package/editors/ArrayOfStringsEditor.js.map +1 -1
  13. package/editors/CheckboxEditor.js.map +1 -1
  14. package/editors/ColorEditor.js.map +1 -1
  15. package/editors/ColumnMultiSelectionByFieldNameEditor.js.map +1 -1
  16. package/editors/ColumnMultiSelectionEditor.js +4 -4
  17. package/editors/ColumnMultiSelectionEditor.js.map +1 -1
  18. package/editors/ColumnSelectionEditor.js +4 -4
  19. package/editors/ColumnSelectionEditor.js.map +1 -1
  20. package/editors/CustomizedInSourceEditor.js +4 -4
  21. package/editors/CustomizedInSourceEditor.js.map +1 -1
  22. package/editors/DynamicColorEditor.js +40 -40
  23. package/editors/DynamicColorEditor.js.map +1 -1
  24. package/editors/DynamicColorEditorWithPrecedence.js +24 -24
  25. package/editors/DynamicColorEditorWithPrecedence.js.map +1 -1
  26. package/editors/DynamicItemEditor.js +4 -4
  27. package/editors/DynamicItemEditor.js.map +1 -1
  28. package/editors/ImageEditor.js.map +1 -1
  29. package/editors/MultiColorPickerEditor.js +1 -0
  30. package/editors/MultiColorPickerEditor.js.map +1 -1
  31. package/editors/NetworkGraphDynamicColorEditor.js +39 -39
  32. package/editors/NetworkGraphDynamicColorEditor.js.map +1 -1
  33. package/editors/NumberEditor.js.map +1 -1
  34. package/editors/PercentEditor.js.map +1 -1
  35. package/editors/PresetSelectorEditor.js +1 -1
  36. package/editors/PresetSelectorEditor.js.map +1 -1
  37. package/editors/RadioBarEditor.js.map +1 -1
  38. package/editors/SelectEditor.js.map +1 -1
  39. package/editors/SeriesColorsByFieldEditor.js +1 -0
  40. package/editors/SeriesColorsByFieldEditor.js.map +1 -1
  41. package/editors/SeriesColorsEditor.js +13 -12
  42. package/editors/SeriesColorsEditor.js.map +1 -1
  43. package/editors/SliderEditor.js +3 -3
  44. package/editors/SliderEditor.js.map +1 -1
  45. package/editors/StaticItemEditor.js.map +1 -1
  46. package/editors/TableColumnFormatterEditor.js +53 -52
  47. package/editors/TableColumnFormatterEditor.js.map +1 -1
  48. package/editors/TableDynamicColorEditor.js +24 -24
  49. package/editors/TableDynamicColorEditor.js.map +1 -1
  50. package/editors/TextAreaEditor.js.map +1 -1
  51. package/editors/TextEditor.js.map +1 -1
  52. package/editors/ThresholdEditor.js.map +1 -1
  53. package/editors/ToggleEditor.js.map +1 -1
  54. package/package.json +2 -2
  55. package/shared/AdvancedControlGroup.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"SelectEditor.js","mappings":"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","sources":["webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualizations-shared/schemaUtils\"","webpack://@splunk/dynamic-editors/./src/utils/EditorFunctions.js","webpack://@splunk/dynamic-editors/./src/utils/token.js","webpack://@splunk/dynamic-editors/./src/shared/AdvancedControlGroup.tsx","webpack://@splunk/dynamic-editors/./src/shared/dimensionConstants.ts","webpack://@splunk/dynamic-editors/external commonjs2 \"@babel/runtime/helpers/defineProperty\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-icons/SlidersDoubleHorizontal\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Button\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/ControlGroup\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Select\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Tooltip\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/themes\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/ui-utils/i18n\"","webpack://@splunk/dynamic-editors/external commonjs2 \"lodash\"","webpack://@splunk/dynamic-editors/external commonjs2 \"prop-types\"","webpack://@splunk/dynamic-editors/external commonjs2 \"react\"","webpack://@splunk/dynamic-editors/external commonjs2 \"styled-components\"","webpack://@splunk/dynamic-editors/webpack/bootstrap","webpack://@splunk/dynamic-editors/webpack/runtime/compat get default export","webpack://@splunk/dynamic-editors/webpack/runtime/define property getters","webpack://@splunk/dynamic-editors/webpack/runtime/hasOwnProperty shorthand","webpack://@splunk/dynamic-editors/webpack/runtime/make namespace object","webpack://@splunk/dynamic-editors/./src/editors/SelectEditor.jsx"],"sourcesContent":["const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@splunk/visualizations-shared/schemaUtils\");","import { cloneDeep, forIn, isPlainObject, omit, set } from 'lodash';\nimport { DYNAMIC_OPTIONS_DSL_PATTERN } from '@splunk/visualizations-shared/schemaUtils';\n\n/**\n * Return values, or parse enum values if values do not exist\n * @param {Object} itemSchema Validation config for an editor item\n * @param {Object[]} values List of predefined { label, value } objects for use by editor\n * @returns {Object[]} List of { label, value } objects for use by editor\n */\nexport const getOptions = (itemSchema, values) => {\n if (Array.isArray(values)) {\n return values;\n }\n\n if (itemSchema && Array.isArray(itemSchema.enum)) {\n return itemSchema.enum.map(item => ({ value: item }));\n }\n\n throw Error(`No valid values provided to editor: ${JSON.stringify(itemSchema)}`);\n};\n\nexport function handleOptionsChange(name, value, options = { debounce: false }) {\n const { visualization } = this.props;\n if (value == null) {\n this.props.onVisualizationChange(\n {\n ...visualization,\n options: omit(visualization.options, [name]),\n },\n options\n );\n } else {\n this.props.onVisualizationChange(\n {\n ...visualization,\n options: {\n ...visualization.options,\n [name]: value,\n },\n },\n options\n );\n }\n}\n\n/*\n * @method isMultipleRulesSchema\n * @param {Object} itemSchema\n * @returns {Boolean}\n */\nexport const isMultipleRulesSchema = itemSchema => !!itemSchema.anyOf && itemSchema.anyOf.length > 0;\n\n/*\n * @method isDynamicOptionSchema\n * @param {Object} schema\n * @returns {Boolean}\n */\nexport const isDynamicOptionSchema = schema =>\n schema.type === 'string' && schema.pattern === DYNAMIC_OPTIONS_DSL_PATTERN;\n\n/*\n * @method isNestedOption\n * @param {String} optionName\n * @returns {Boolean}\n */\nexport const isNestedOption = optionName => {\n const nestedOptionPattern = /^\\w+\\[\\d+\\]\\.(.+)$/;\n return nestedOptionPattern.exec(optionName) !== null;\n};\n\n/*\n * @method getStaticItemSchema\n * @param {Object} itemSchema\n * @returns {Object} staticItemSchema\n */\nexport const getStaticItemSchema = itemSchema => {\n if (!isMultipleRulesSchema(itemSchema)) {\n return itemSchema;\n }\n\n const staticSchema = itemSchema.anyOf.find(schema => !isDynamicOptionSchema(schema));\n return { ...omit(itemSchema, 'anyOf'), ...staticSchema };\n};\n\n/**\n * @method isContextCompatibleWithFormatter\n * @param {Array | Object} contextConfig\n * @param {String} formatterType\n * @returns {Boolean} true if context structure is compatible with formatter type\n */\nconst isContextCompatibleWithFormatter = (contextConfig, formatterType) => {\n if (!contextConfig || !formatterType) {\n return false;\n }\n\n // Gradient formatter expects an object with 'colors' property\n if (formatterType === 'gradient') {\n return (\n typeof contextConfig === 'object' && !Array.isArray(contextConfig) && 'colors' in contextConfig\n );\n }\n\n // Range/Match formatters expect an array\n if (formatterType === 'rangeValue' || formatterType === 'matchValue') {\n return Array.isArray(contextConfig);\n }\n\n // For unknown formatters, assume compatible to maintain existing behavior\n return true;\n};\n\n/**\n * @method getFormatterConfig\n * @param {Object} props\n * @param {Array | Object} [props.contextConfig]\n * @param {Array} props.formatters\n * @param {String} props.formatterFromDSL\n * @param {String} props.selectedDataSelector\n * @returns {Array | Object} the default formatter config of dynamic color editors' fomatter\n */\nexport const getFormatterConfig = ({ contextConfig, formatters, formatterFromDSL, selectedDataSelector }) => {\n // If no context exists, use default config\n if (!contextConfig) {\n const currentFormatter = formatters?.find(formatter => formatter.value === formatterFromDSL);\n const formatterConfig = currentFormatter?.defaults?.[selectedDataSelector];\n return formatterConfig || [];\n }\n\n // If no formatter type is provided, return context as-is for backward compatibility\n if (!formatterFromDSL) {\n return contextConfig;\n }\n\n // Check if existing context is compatible with the formatter type\n if (isContextCompatibleWithFormatter(contextConfig, formatterFromDSL)) {\n return contextConfig;\n }\n\n // Context is incompatible, use default config instead\n const currentFormatter = formatters?.find(formatter => formatter.value === formatterFromDSL);\n const formatterConfig = currentFormatter?.defaults?.[selectedDataSelector];\n return formatterConfig || [];\n};\n\n/**\n * @method isSupportedDataSelector\n * @param {Object} config\n * @param {String} config.selectedDataSelector e.g. 'majorValue'\n * @param {Array} config.dataSelectors e.g. [{ label: 'value', value: 'majorValue'}]\n * @returns {Boolean} true if dataSelectors includes selectedDataSelector\n */\nexport const isSupportedDataSelector = ({ selectedDataSelector, dataSelectors }) => {\n if (!selectedDataSelector || !dataSelectors?.length) {\n return false;\n }\n return dataSelectors.some(ds => ds.value === selectedDataSelector);\n};\n\n/**\n * @method isSupportedFormatter\n * @param {Object} config\n * @param {String} [config.selectedFormatterType] e.g. 'rangeValue'\n * @param {Array} [config.formattersFromEditor] e.g. [{ label: 'rangle', value: 'rangeValue', defaults: {}}]\n * @param {Object} config.supportedFormatters e.g. {rangeValue: {}, matchValue: {}}\n * @returns {Boolean} true if formattersFromEditor includes selectedFormatterType and selectedFormatterType is one of supportedFormatters on editor\n */\nexport const isSupportedFormatter = ({\n selectedFormatterType,\n formattersFromEditor,\n supportedFormatters,\n}) => {\n if (\n !selectedFormatterType ||\n !supportedFormatters?.[selectedFormatterType] ||\n !formattersFromEditor?.length\n ) {\n return false;\n }\n return formattersFromEditor.some(fm => fm.value === selectedFormatterType);\n};\n\n/**\n * @method getFilteredRowsByShowEditor filters the EditorItem objects which are visible based on showEditor property\n * @param {Object} args\n * @param {Array} args.row\n * @param {Object} args.options // item options\n * @param {Object} args.encoding\n * @param {Object} args.featureFlags\n * @returns array of EditorItem objects or empty array\n */\nexport const getFilteredRowsByShowEditor = ({ row, options, encoding, featureFlags }) => {\n if (!row || !Array.isArray(row)) {\n return [];\n }\n const filteredRow = row.filter(\n item =>\n typeof item.showEditor === 'undefined' ||\n (typeof item.showEditor === 'function' && item.showEditor({ options, encoding, featureFlags }))\n );\n return filteredRow;\n};\n\n/**\n * @method removeEmptyEntries Removes of all entries where the value is null, undefined, and convert nulls in arrays to undefined\n * @param {Object} obj\n */\nconst removeEmptyEntries = obj => {\n const returnObj = cloneDeep(obj);\n forIn(returnObj, (value, key) => {\n if ((value !== null && value !== undefined && Array.isArray(value)) || isPlainObject(value)) {\n returnObj[key] = removeEmptyEntries(returnObj[key]);\n }\n if (Array.isArray(value)) {\n returnObj[key] = value.map(val => (val === null ? undefined : val));\n }\n if (value === null || value === undefined) {\n delete returnObj[key];\n }\n });\n return returnObj;\n};\n\n/**\n * @method getToggleOffValueForDataColors determines the appropriate value when toggling off dataColors\n * @param {Object} config\n * @param {String} config.name - the option name (e.g., 'dataColors', 'layers[0].dataColors')\n * @param {Object} config.options - all visualization options\n * @param {String[]} config.dataSelectors - available data selectors (e.g., ['areaValues'])\n * @returns {String} appropriate toggle-off value (empty string or gradient fallback)\n */\nexport const getToggleOffValueForDataColors = ({ name, options, dataSelectors = [] }) => {\n // Only process dataColors options\n if (!name?.includes('dataColors')) {\n return '';\n }\n\n // Check if this is a choropleth layer by examining the layer configuration\n const isChoroplethLayer = () => {\n // Handle top-level dataColors\n if (name === 'dataColors') {\n return options?.type === 'choropleth' || options?.layerType === 'choropleth';\n }\n\n // Handle nested layer dataColors (e.g., layers[0].dataColors)\n const layerPattern = /^layers\\[(\\d+)\\]\\.dataColors$/;\n const layerMatch = layerPattern.exec(name);\n if (layerMatch) {\n const layerIndex = parseInt(layerMatch[1], 10);\n const layer = options?.layers?.[layerIndex];\n return layer?.type === 'choropleth' || layer?.layerType === 'choropleth';\n }\n\n return false;\n };\n\n // Check if areaValues is available as a data selector\n const hasAreaValuesSelector = dataSelectors.includes('areaValues');\n\n // Return gradient fallback for choropleth layers with areaValues, empty string otherwise\n if (isChoroplethLayer() && hasAreaValuesSelector) {\n return '> areaValues | gradient()';\n }\n\n return '';\n};\n\n/**\n * @method convertEmptyDataColorsForChoropleth handles the conversion of empty dataColors option to gradient fallback for choropleth layers\n * @param {Object} config\n * @param {String} config.option - the option name (e.g., 'dataColors', 'layers[0].dataColors')\n * @param {Any} config.value - the option value\n * @param {Object} config.options - all visualization options\n * @param {String[]} config.dataSelectors - available data selectors (e.g., ['areaValues'])\n * @returns {String|Any} converted value for choropleth or original value\n */\nexport const convertEmptyDataColorsForChoropleth = ({ option, value, options, dataSelectors = [] }) => {\n // Only process dataColors options\n if (!option?.includes('dataColors')) {\n return value;\n }\n\n // Only convert empty string values\n if (value !== '') {\n return value;\n }\n\n // Use the toggle-off value logic\n return getToggleOffValueForDataColors({ name: option, options, dataSelectors });\n};\n\n/**\n * @method setOption sets an options value\n * @param {String} option\n * @param {Any} value\n * @param {Object} oldVisualization\n * @param {Object} optionSchema\n * @param {Object} defaultOverrides\n * @param {String[]} dataSelectors - available data selectors for choropleth conversion\n * @returns visualization object with updated options\n */\nexport const setOption = (option, value, oldVisualization, optionSchema, defaultOverrides, dataSelectors) => {\n const obj = {\n ...oldVisualization,\n };\n\n let newOption = option;\n let newValue = value;\n\n // Apply choropleth-specific conversion for empty dataColors\n if (newValue === '' && newOption?.includes('dataColors')) {\n newValue = convertEmptyDataColorsForChoropleth({\n option: newOption,\n value: newValue,\n options: oldVisualization.options,\n dataSelectors,\n });\n }\n\n // Remove from definition if value is null/undefined, and the key is explicitly set in the optionSchema\n if ((newValue === null || newValue === undefined) && optionSchema[newOption]) {\n obj.options = omit(oldVisualization.options, newOption);\n return obj;\n }\n\n // Remove from definition if value is the same as the default from the overrides or the schema\n const schemaDefault = defaultOverrides?.[newOption] ?? optionSchema[newOption]?.default;\n if (typeof schemaDefault !== 'undefined' && newValue === schemaDefault) {\n obj.options = omit(oldVisualization.options, newOption);\n return obj;\n }\n // Copy options\n obj.options = cloneDeep(oldVisualization.options);\n obj.options ??= {};\n // ColumnSelectionEditor returns the option as an object\n // with a key/value pair inside that object with the param value as undefiend\n if ((value === null || value === undefined) && isPlainObject(option) && isPlainObject(option.options)) {\n [newOption] = Object.keys(option.options);\n [newValue] = Object.values(option.options);\n }\n // Select explicitly exposed option first for non arrays / objects\n if (optionSchema[newOption]) {\n if (optionSchema[newOption].type !== 'array') {\n obj.options[newOption] = newValue;\n return obj;\n }\n }\n // Set option using loadash to translate string path like `object.object.key` to target a specific key within nested objects\n if (newValue === null) {\n newValue = undefined;\n }\n set(obj.options, newOption, newValue);\n // Remove any null, undefined, nad nulls from arrays\n obj.options = removeEmptyEntries(obj.options);\n return obj;\n};\n","const TOKEN_NAMESPACE_PREFIX_PATTERN = /(\\w+:)?/.source;\n// ex: token.name|suh (old-style filter chain)\n// ex: token.name|lower|capitalize (new-style filter chain)\nconst TOKEN_NAME_CHARS_PATTERN = /([^$|:]+?)(\\|[|\\w]+)?/.source;\n// ex: $ns:token.name|suh$\nconst TOKEN_PATTERN = /\\$/.source + TOKEN_NAMESPACE_PREFIX_PATTERN + TOKEN_NAME_CHARS_PATTERN + /\\$/.source;\n\nconst TokenRegExp = new RegExp(TOKEN_PATTERN);\n\nexport const hasTokens = value => typeof value === 'string' && TokenRegExp.test(value);\n","import React, { Children, cloneElement } from 'react';\nimport type { ReactElement } from 'react';\nimport * as T from 'prop-types';\nimport styled from 'styled-components';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport AdvancedConfigIcon from '@splunk/react-icons/SlidersDoubleHorizontal';\nimport { variables } from '@splunk/themes';\nimport Tooltip from '@splunk/react-ui/Tooltip';\nimport Button, { ButtonClickHandler, ButtonProps } from '@splunk/react-ui/Button';\nimport SUIControlGroup from '@splunk/react-ui/ControlGroup';\nimport type { ControlGroupPropsBase } from '@splunk/react-ui/ControlGroup';\n\ninterface AdvancedControlGroupProps extends Omit<ControlGroupPropsBase, 'splunkTheme'> {\n 'data-test'?: string;\n style?: Record<string, string | number>;\n isAdvanced?: boolean;\n onClick?: React.MouseEventHandler<HTMLDivElement>;\n onAdvancedConfigButtonClick?: ButtonClickHandler;\n}\n\ninterface AdvancedConfigButtonProps {\n label?: string;\n onClick?: ButtonClickHandler;\n}\n\n// remove all surrounding margins. let parent add padding\nconst ControlGroupContainer = styled(SUIControlGroup)`\n margin-top: 0;\n padding: 0;\n // adjust bottom margin according to theme\n margin-bottom: ${variables.spacingMedium};\n width: 100%;\n\n // remove top margin of the first component in control group\n &:first-child {\n margin-top: 0;\n }\n\n // remove bottom margin of the last component in control group\n &:last-child {\n margin-bottom: 0;\n }\n // remove top padding on label of the first control group\n [data-test='label']:first-of-type {\n padding-top: 0;\n }\n`;\n\n// override tooltip to set desired config button style\nconst StyledToolTip = styled(Tooltip)`\n display: flex;\n > span {\n display: flex;\n width: 35px;\n }\n`;\n\nconst StyledAdvancedConfigButton = styled(Button)<ButtonProps>`\n color: ${variables.contentColorActive} !important;\n &:hover {\n background-color: ${variables.interactiveColorOverlayDrag} !important;\n }\n`;\n\nexport const AdvancedConfigButton = ({\n label = '',\n onClick,\n}: AdvancedConfigButtonProps): React.ReactElement => {\n return (\n <StyledToolTip\n data-test={`${label}-advanced-config-button-tooltip`}\n content={_('Advanced configurations')}\n >\n <StyledAdvancedConfigButton\n data-test={`${label}-advanced-config-button`}\n icon={<AdvancedConfigIcon data-test={`${label}-advanced-config-button-icon`} />}\n appearance=\"subtle\"\n onClick={onClick}\n />\n </StyledToolTip>\n );\n};\n\nconst AdvancedControlGroup = ({\n 'data-test': dataTest,\n children,\n isAdvanced = false,\n label,\n hideLabel,\n labelPosition,\n labelWidth,\n tooltip,\n help,\n style,\n error,\n controlsLayout,\n onClick,\n onAdvancedConfigButtonClick,\n}: AdvancedControlGroupProps): React.ReactElement => (\n <ControlGroupContainer\n data-test={dataTest ?? 'control-group'}\n label={label}\n hideLabel={hideLabel}\n labelPosition={labelPosition}\n labelWidth={labelWidth}\n tooltip={tooltip}\n help={help}\n error={error}\n style={style}\n onClick={onClick}\n controlsLayout={controlsLayout}\n >\n {isAdvanced\n ? Children.toArray(children)\n .filter(Boolean)\n .map(child =>\n cloneElement(child as ReactElement, {\n style: { flex: 1 },\n })\n )\n : children}\n {isAdvanced ? <AdvancedConfigButton label={label} onClick={onAdvancedConfigButtonClick} /> : null}\n </ControlGroupContainer>\n);\n\nAdvancedControlGroup.propTypes = {\n /**\n * Style overriding SUI ControlGroup\n */\n style: T.object,\n /**\n * Whether the current editor is enabled with advanced configurations\n */\n isAdvanced: T.bool,\n /**\n * Callback for editor click\n */\n onClick: T.func,\n /**\n * Callback for advanced config button click\n */\n onAdvancedConfigButtonClick: T.func,\n};\n\nexport default AdvancedControlGroup;\n","export const FLYOUT_PADDING = 21;\nexport const COLUMN_FLYOUT_PADDING = 16;\nexport const FLYOUT_WIDTH = 344;\n\nexport const VERTICAL_EDITOR_SPACING = 16;\n\nexport const DROPDOWN_MENU_WIDTH = 327;\n\nexport const editorStyle = { width: '100%' };\n","module.exports = require(\"@babel/runtime/helpers/defineProperty\");","module.exports = require(\"@splunk/react-icons/SlidersDoubleHorizontal\");","module.exports = require(\"@splunk/react-ui/Button\");","module.exports = require(\"@splunk/react-ui/ControlGroup\");","module.exports = require(\"@splunk/react-ui/Select\");","module.exports = require(\"@splunk/react-ui/Tooltip\");","module.exports = require(\"@splunk/themes\");","module.exports = require(\"@splunk/ui-utils/i18n\");","module.exports = require(\"lodash\");","module.exports = require(\"prop-types\");","module.exports = require(\"react\");","module.exports = require(\"styled-components\");","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import React, { useCallback } from 'react';\nimport T from 'prop-types';\nimport Select from '@splunk/react-ui/Select';\nimport { hasTokens } from '../utils/token';\nimport { getOptions } from '../utils/EditorFunctions';\nimport { editorStyle } from '../shared/dimensionConstants';\nimport ControlGroup from '../shared/AdvancedControlGroup';\n\nconst SelectEditor = ({\n onChange,\n name,\n itemSchema,\n values,\n value,\n labelPosition = 'top',\n labelWidth,\n label,\n tooltip,\n isDisabled = false,\n isAdvanced,\n hideLabel,\n help,\n}) => {\n const options = getOptions(itemSchema, values);\n const disabled = hasTokens(value) || isDisabled;\n const handleChange = useCallback((event, { value: v }) => onChange(event, name, v), [onChange, name]);\n\n return (\n <ControlGroup\n label={label}\n labelPosition={labelPosition}\n labelWidth={labelWidth}\n tooltip={tooltip}\n help={help}\n isAdvanced={isAdvanced}\n hideLabel={hideLabel}\n >\n <Select\n data-test={name}\n onChange={handleChange}\n value={value}\n disabled={disabled}\n style={editorStyle}\n >\n {options.map(v => (\n <Select.Option\n key={v.value}\n value={v.value}\n label={v.label || v.value}\n icon={v.icon ? <v.icon /> : null}\n description={v.description}\n />\n ))}\n </Select>\n </ControlGroup>\n );\n};\n\nSelectEditor.propTypes = {\n /**\n * Callback when selecting an item from the menu\n *\n * @param {SyntheticEvent} event The React `SyntheticEvent`\n * @param {string} name The option name\n * @param {string|boolean} value The option value\n */\n onChange: T.func.isRequired,\n /**\n * The option name\n */\n name: T.string.isRequired,\n /**\n * The item JSON schema, it should contain `enum` property. Note this will only be used when `values` prop is undefined\n */\n itemSchema: T.object,\n /**\n * The option values that can be selected\n */\n values: T.arrayOf(\n T.shape({\n label: T.string,\n value: T.oneOfType([T.string, T.number]).isRequired,\n description: T.string,\n })\n ),\n /**\n * The option value\n */\n value: T.oneOfType([T.string, T.number]),\n /**\n * A human readable label for the option\n */\n label: T.string.isRequired,\n /**\n * Label position\n */\n labelPosition: T.oneOf(['left', 'top']),\n labelWidth: T.number,\n /**\n * Text to display in a tooltip next to the label\n */\n tooltip: T.string,\n /**\n * Disabled state of component\n */\n isDisabled: T.bool,\n /**\n * As advanced editor to show advanced config button\n */\n isAdvanced: T.bool,\n /**\n * Disable label of control group\n */\n hideLabel: T.bool,\n /**\n * Text to display under the the input\n */\n help: T.string,\n};\n\nexport default SelectEditor;\n"],"names":["require","getOptions","itemSchema","values","Array","isArray","enum","map","item","value","Error","JSON","stringify","TokenRegExp","RegExp","source","hasTokens","test","ControlGroupContainer","variables","spacingMedium","StyledToolTip","StyledAdvancedConfigButton","contentColorActive","interactiveColorOverlayDrag","AdvancedConfigButton","label","onClick","content","_","icon","appearance","AdvancedControlGroup","dataTest","children","isAdvanced","hideLabel","labelPosition","labelWidth","tooltip","help","style","error","controlsLayout","onAdvancedConfigButtonClick","Children","toArray","filter","Boolean","child","cloneElement","flex","propTypes","T","object","bool","func","editorStyle","width","module","exports","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","call","n","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","r","Symbol","toStringTag","SelectEditor","onChange","name","isDisabled","options","disabled","handleChange","useCallback","event","v","React","ControlGroup","Select","description","isRequired"],"sourceRoot":""}
1
+ {"version":3,"file":"SelectEditor.js","mappings":"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","sources":["webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualizations-shared/schemaUtils\"","webpack://@splunk/dynamic-editors/./src/utils/EditorFunctions.js","webpack://@splunk/dynamic-editors/./src/utils/token.js","webpack://@splunk/dynamic-editors/./src/shared/AdvancedControlGroup.tsx","webpack://@splunk/dynamic-editors/./src/shared/dimensionConstants.ts","webpack://@splunk/dynamic-editors/external commonjs2 \"@babel/runtime/helpers/defineProperty\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-icons/SlidersDoubleHorizontal\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Button\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/ControlGroup\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Select\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Tooltip\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/themes\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/ui-utils/i18n\"","webpack://@splunk/dynamic-editors/external commonjs2 \"lodash\"","webpack://@splunk/dynamic-editors/external commonjs2 \"prop-types\"","webpack://@splunk/dynamic-editors/external commonjs2 \"react\"","webpack://@splunk/dynamic-editors/external commonjs2 \"styled-components\"","webpack://@splunk/dynamic-editors/webpack/bootstrap","webpack://@splunk/dynamic-editors/webpack/runtime/compat get default export","webpack://@splunk/dynamic-editors/webpack/runtime/define property getters","webpack://@splunk/dynamic-editors/webpack/runtime/hasOwnProperty shorthand","webpack://@splunk/dynamic-editors/webpack/runtime/make namespace object","webpack://@splunk/dynamic-editors/./src/editors/SelectEditor.jsx"],"sourcesContent":["const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@splunk/visualizations-shared/schemaUtils\");","import { cloneDeep, forIn, isPlainObject, omit, set } from 'lodash';\nimport { DYNAMIC_OPTIONS_DSL_PATTERN } from '@splunk/visualizations-shared/schemaUtils';\n\n/**\n * Return values, or parse enum values if values do not exist\n * @param {Object} itemSchema Validation config for an editor item\n * @param {Object[]} values List of predefined { label, value } objects for use by editor\n * @returns {Object[]} List of { label, value } objects for use by editor\n */\nexport const getOptions = (itemSchema, values) => {\n if (Array.isArray(values)) {\n return values;\n }\n\n if (itemSchema && Array.isArray(itemSchema.enum)) {\n return itemSchema.enum.map(item => ({ value: item }));\n }\n\n throw Error(`No valid values provided to editor: ${JSON.stringify(itemSchema)}`);\n};\n\nexport function handleOptionsChange(name, value, options = { debounce: false }) {\n const { visualization } = this.props;\n if (value == null) {\n this.props.onVisualizationChange(\n {\n ...visualization,\n options: omit(visualization.options, [name]),\n },\n options\n );\n } else {\n this.props.onVisualizationChange(\n {\n ...visualization,\n options: {\n ...visualization.options,\n [name]: value,\n },\n },\n options\n );\n }\n}\n\n/*\n * @method isMultipleRulesSchema\n * @param {Object} itemSchema\n * @returns {Boolean}\n */\nexport const isMultipleRulesSchema = itemSchema => !!itemSchema.anyOf && itemSchema.anyOf.length > 0;\n\n/*\n * @method isDynamicOptionSchema\n * @param {Object} schema\n * @returns {Boolean}\n */\nexport const isDynamicOptionSchema = schema =>\n schema.type === 'string' && schema.pattern === DYNAMIC_OPTIONS_DSL_PATTERN;\n\n/*\n * @method isNestedOption\n * @param {String} optionName\n * @returns {Boolean}\n */\nexport const isNestedOption = optionName => {\n const nestedOptionPattern = /^\\w+\\[\\d+\\]\\.(.+)$/;\n return nestedOptionPattern.exec(optionName) !== null;\n};\n\n/*\n * @method getStaticItemSchema\n * @param {Object} itemSchema\n * @returns {Object} staticItemSchema\n */\nexport const getStaticItemSchema = itemSchema => {\n if (!isMultipleRulesSchema(itemSchema)) {\n return itemSchema;\n }\n\n const staticSchema = itemSchema.anyOf.find(schema => !isDynamicOptionSchema(schema));\n return { ...omit(itemSchema, 'anyOf'), ...staticSchema };\n};\n\n/**\n * @method isContextCompatibleWithFormatter\n * @param {Array | Object} contextConfig\n * @param {String} formatterType\n * @returns {Boolean} true if context structure is compatible with formatter type\n */\nconst isContextCompatibleWithFormatter = (contextConfig, formatterType) => {\n if (!contextConfig || !formatterType) {\n return false;\n }\n\n // Gradient formatter expects an object with 'colors' property\n if (formatterType === 'gradient') {\n return (\n typeof contextConfig === 'object' && !Array.isArray(contextConfig) && 'colors' in contextConfig\n );\n }\n\n // Range/Match formatters expect an array\n if (formatterType === 'rangeValue' || formatterType === 'matchValue') {\n return Array.isArray(contextConfig);\n }\n\n // For unknown formatters, assume compatible to maintain existing behavior\n return true;\n};\n\n/**\n * @method getFormatterConfig\n * @param {Object} props\n * @param {Array | Object} [props.contextConfig]\n * @param {Array} props.formatters\n * @param {String} props.formatterFromDSL\n * @param {String} props.selectedDataSelector\n * @returns {Array | Object} the default formatter config of dynamic color editors' fomatter\n */\nexport const getFormatterConfig = ({ contextConfig, formatters, formatterFromDSL, selectedDataSelector }) => {\n // If no context exists, use default config\n if (!contextConfig) {\n const currentFormatter = formatters?.find(formatter => formatter.value === formatterFromDSL);\n const formatterConfig = currentFormatter?.defaults?.[selectedDataSelector];\n return formatterConfig || [];\n }\n\n // If no formatter type is provided, return context as-is for backward compatibility\n if (!formatterFromDSL) {\n return contextConfig;\n }\n\n // Check if existing context is compatible with the formatter type\n if (isContextCompatibleWithFormatter(contextConfig, formatterFromDSL)) {\n return contextConfig;\n }\n\n // Context is incompatible, use default config instead\n const currentFormatter = formatters?.find(formatter => formatter.value === formatterFromDSL);\n const formatterConfig = currentFormatter?.defaults?.[selectedDataSelector];\n return formatterConfig || [];\n};\n\n/**\n * @method isSupportedDataSelector\n * @param {Object} config\n * @param {String} config.selectedDataSelector e.g. 'majorValue'\n * @param {Array} config.dataSelectors e.g. [{ label: 'value', value: 'majorValue'}]\n * @returns {Boolean} true if dataSelectors includes selectedDataSelector\n */\nexport const isSupportedDataSelector = ({ selectedDataSelector, dataSelectors }) => {\n if (!selectedDataSelector || !dataSelectors?.length) {\n return false;\n }\n return dataSelectors.some(ds => ds.value === selectedDataSelector);\n};\n\n/**\n * @method isSupportedFormatter\n * @param {Object} config\n * @param {String} [config.selectedFormatterType] e.g. 'rangeValue'\n * @param {Array} [config.formattersFromEditor] e.g. [{ label: 'rangle', value: 'rangeValue', defaults: {}}]\n * @param {Object} config.supportedFormatters e.g. {rangeValue: {}, matchValue: {}}\n * @returns {Boolean} true if formattersFromEditor includes selectedFormatterType and selectedFormatterType is one of supportedFormatters on editor\n */\nexport const isSupportedFormatter = ({\n selectedFormatterType,\n formattersFromEditor,\n supportedFormatters,\n}) => {\n if (\n !selectedFormatterType ||\n !supportedFormatters?.[selectedFormatterType] ||\n !formattersFromEditor?.length\n ) {\n return false;\n }\n return formattersFromEditor.some(fm => fm.value === selectedFormatterType);\n};\n\n/**\n * @method getFilteredRowsByShowEditor filters the EditorItem objects which are visible based on showEditor property\n * @param {Object} args\n * @param {Array} args.row\n * @param {Object} args.options // item options\n * @param {Object} args.encoding\n * @param {Object} args.featureFlags\n * @returns array of EditorItem objects or empty array\n */\nexport const getFilteredRowsByShowEditor = ({ row, options, encoding, featureFlags }) => {\n if (!row || !Array.isArray(row)) {\n return [];\n }\n const filteredRow = row.filter(\n item =>\n typeof item.showEditor === 'undefined' ||\n (typeof item.showEditor === 'function' && item.showEditor({ options, encoding, featureFlags }))\n );\n return filteredRow;\n};\n\n/**\n * @method removeEmptyEntries Removes of all entries where the value is null, undefined, and convert nulls in arrays to undefined\n * @param {Object} obj\n */\nconst removeEmptyEntries = obj => {\n const returnObj = cloneDeep(obj);\n forIn(returnObj, (value, key) => {\n if ((value !== null && value !== undefined && Array.isArray(value)) || isPlainObject(value)) {\n returnObj[key] = removeEmptyEntries(returnObj[key]);\n }\n if (Array.isArray(value)) {\n returnObj[key] = value.map(val => (val === null ? undefined : val));\n }\n if (value === null || value === undefined) {\n delete returnObj[key];\n }\n });\n return returnObj;\n};\n\n/**\n * @method getToggleOffValueForDataColors determines the appropriate value when toggling off dataColors\n * @param {Object} config\n * @param {String} config.name - the option name (e.g., 'dataColors', 'layers[0].dataColors')\n * @param {Object} config.options - all visualization options\n * @param {String[]} config.dataSelectors - available data selectors (e.g., ['areaValues'])\n * @returns {String} appropriate toggle-off value (empty string or gradient fallback)\n */\nexport const getToggleOffValueForDataColors = ({ name, options, dataSelectors = [] }) => {\n // Only process dataColors options\n if (!name?.includes('dataColors')) {\n return '';\n }\n\n // Check if this is a choropleth layer by examining the layer configuration\n const isChoroplethLayer = () => {\n // Handle top-level dataColors\n if (name === 'dataColors') {\n return options?.type === 'choropleth' || options?.layerType === 'choropleth';\n }\n\n // Handle nested layer dataColors (e.g., layers[0].dataColors)\n const layerPattern = /^layers\\[(\\d+)\\]\\.dataColors$/;\n const layerMatch = layerPattern.exec(name);\n if (layerMatch) {\n const layerIndex = parseInt(layerMatch[1], 10);\n const layer = options?.layers?.[layerIndex];\n return layer?.type === 'choropleth' || layer?.layerType === 'choropleth';\n }\n\n return false;\n };\n\n // Check if areaValues is available as a data selector\n const hasAreaValuesSelector = dataSelectors.includes('areaValues');\n\n // Return gradient fallback for choropleth layers with areaValues, empty string otherwise\n if (isChoroplethLayer() && hasAreaValuesSelector) {\n return '> areaValues | gradient()';\n }\n\n return '';\n};\n\n/**\n * @method convertEmptyDataColorsForChoropleth handles the conversion of empty dataColors option to gradient fallback for choropleth layers\n * @param {Object} config\n * @param {String} config.option - the option name (e.g., 'dataColors', 'layers[0].dataColors')\n * @param {Any} config.value - the option value\n * @param {Object} config.options - all visualization options\n * @param {String[]} config.dataSelectors - available data selectors (e.g., ['areaValues'])\n * @returns {String|Any} converted value for choropleth or original value\n */\nexport const convertEmptyDataColorsForChoropleth = ({ option, value, options, dataSelectors = [] }) => {\n // Only process dataColors options\n if (!option?.includes('dataColors')) {\n return value;\n }\n\n // Only convert empty string values\n if (value !== '') {\n return value;\n }\n\n // Use the toggle-off value logic\n return getToggleOffValueForDataColors({ name: option, options, dataSelectors });\n};\n\n/**\n * @method setOption sets an options value\n * @param {String} option\n * @param {Any} value\n * @param {Object} oldVisualization\n * @param {Object} optionSchema\n * @param {Object} defaultOverrides\n * @param {String[]} dataSelectors - available data selectors for choropleth conversion\n * @returns visualization object with updated options\n */\nexport const setOption = (option, value, oldVisualization, optionSchema, defaultOverrides, dataSelectors) => {\n const obj = {\n ...oldVisualization,\n };\n\n let newOption = option;\n let newValue = value;\n\n // Apply choropleth-specific conversion for empty dataColors\n if (newValue === '' && newOption?.includes('dataColors')) {\n newValue = convertEmptyDataColorsForChoropleth({\n option: newOption,\n value: newValue,\n options: oldVisualization.options,\n dataSelectors,\n });\n }\n\n // Remove from definition if value is null/undefined, and the key is explicitly set in the optionSchema\n if ((newValue === null || newValue === undefined) && optionSchema[newOption]) {\n obj.options = omit(oldVisualization.options, newOption);\n return obj;\n }\n\n // Remove from definition if value is the same as the default from the overrides or the schema\n const schemaDefault = defaultOverrides?.[newOption] ?? optionSchema[newOption]?.default;\n if (typeof schemaDefault !== 'undefined' && newValue === schemaDefault) {\n obj.options = omit(oldVisualization.options, newOption);\n return obj;\n }\n // Copy options\n obj.options = cloneDeep(oldVisualization.options);\n obj.options ??= {};\n // ColumnSelectionEditor returns the option as an object\n // with a key/value pair inside that object with the param value as undefiend\n if ((value === null || value === undefined) && isPlainObject(option) && isPlainObject(option.options)) {\n [newOption] = Object.keys(option.options);\n [newValue] = Object.values(option.options);\n }\n // Select explicitly exposed option first for non arrays / objects\n if (optionSchema[newOption]) {\n if (optionSchema[newOption].type !== 'array') {\n obj.options[newOption] = newValue;\n return obj;\n }\n }\n // Set option using loadash to translate string path like `object.object.key` to target a specific key within nested objects\n if (newValue === null) {\n newValue = undefined;\n }\n set(obj.options, newOption, newValue);\n // Remove any null, undefined, nad nulls from arrays\n obj.options = removeEmptyEntries(obj.options);\n return obj;\n};\n","const TOKEN_NAMESPACE_PREFIX_PATTERN = /(\\w+:)?/.source;\n// ex: token.name|suh (old-style filter chain)\n// ex: token.name|lower|capitalize (new-style filter chain)\nconst TOKEN_NAME_CHARS_PATTERN = /([^$|:]+?)(\\|[|\\w]+)?/.source;\n// ex: $ns:token.name|suh$\nconst TOKEN_PATTERN = /\\$/.source + TOKEN_NAMESPACE_PREFIX_PATTERN + TOKEN_NAME_CHARS_PATTERN + /\\$/.source;\n\nconst TokenRegExp = new RegExp(TOKEN_PATTERN);\n\nexport const hasTokens = value => typeof value === 'string' && TokenRegExp.test(value);\n","import React, { Children, cloneElement } from 'react';\nimport type { ReactElement } from 'react';\nimport * as T from 'prop-types';\nimport styled from 'styled-components';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport AdvancedConfigIcon from '@splunk/react-icons/SlidersDoubleHorizontal';\nimport { variables } from '@splunk/themes';\nimport Tooltip from '@splunk/react-ui/Tooltip';\nimport type { ButtonClickHandler, ButtonProps } from '@splunk/react-ui/Button';\nimport Button from '@splunk/react-ui/Button';\nimport SUIControlGroup from '@splunk/react-ui/ControlGroup';\nimport type { ControlGroupPropsBase } from '@splunk/react-ui/ControlGroup';\n\ninterface AdvancedControlGroupProps extends Omit<ControlGroupPropsBase, 'splunkTheme'> {\n 'data-test'?: string;\n style?: Record<string, string | number>;\n isAdvanced?: boolean;\n onClick?: React.MouseEventHandler<HTMLDivElement>;\n onAdvancedConfigButtonClick?: ButtonClickHandler;\n}\n\ninterface AdvancedConfigButtonProps {\n label?: string;\n onClick?: ButtonClickHandler;\n}\n\n// remove all surrounding margins. let parent add padding\nconst ControlGroupContainer = styled(SUIControlGroup)`\n margin-top: 0;\n padding: 0;\n // adjust bottom margin according to theme\n margin-bottom: ${variables.spacingMedium};\n width: 100%;\n\n // remove top margin of the first component in control group\n &:first-child {\n margin-top: 0;\n }\n\n // remove bottom margin of the last component in control group\n &:last-child {\n margin-bottom: 0;\n }\n // remove top padding on label of the first control group\n [data-test='label']:first-of-type {\n padding-top: 0;\n }\n`;\n\n// override tooltip to set desired config button style\nconst StyledToolTip = styled(Tooltip)`\n display: flex;\n > span {\n display: flex;\n width: 35px;\n }\n`;\n\nconst StyledAdvancedConfigButton = styled(Button)<ButtonProps>`\n color: ${variables.contentColorActive} !important;\n &:hover {\n background-color: ${variables.interactiveColorOverlayDrag} !important;\n }\n`;\n\nexport const AdvancedConfigButton = ({\n label = '',\n onClick,\n}: AdvancedConfigButtonProps): React.ReactElement => {\n return (\n <StyledToolTip\n data-test={`${label}-advanced-config-button-tooltip`}\n content={_('Advanced configurations')}\n >\n <StyledAdvancedConfigButton\n data-test={`${label}-advanced-config-button`}\n icon={<AdvancedConfigIcon data-test={`${label}-advanced-config-button-icon`} />}\n appearance=\"subtle\"\n onClick={onClick}\n />\n </StyledToolTip>\n );\n};\n\nconst AdvancedControlGroup = ({\n 'data-test': dataTest,\n children,\n isAdvanced = false,\n label,\n hideLabel,\n labelPosition,\n labelWidth,\n tooltip,\n help,\n style,\n error,\n controlsLayout,\n onClick,\n onAdvancedConfigButtonClick,\n}: AdvancedControlGroupProps): React.ReactElement => (\n <ControlGroupContainer\n data-test={dataTest ?? 'control-group'}\n label={label}\n hideLabel={hideLabel}\n labelPosition={labelPosition}\n labelWidth={labelWidth}\n tooltip={tooltip}\n help={help}\n error={error}\n style={style}\n onClick={onClick}\n controlsLayout={controlsLayout}\n >\n {isAdvanced\n ? Children.toArray(children)\n .filter(Boolean)\n .map(child =>\n cloneElement(child as ReactElement, {\n style: { flex: 1 },\n })\n )\n : children}\n {isAdvanced ? <AdvancedConfigButton label={label} onClick={onAdvancedConfigButtonClick} /> : null}\n </ControlGroupContainer>\n);\n\nAdvancedControlGroup.propTypes = {\n /**\n * Style overriding SUI ControlGroup\n */\n style: T.object,\n /**\n * Whether the current editor is enabled with advanced configurations\n */\n isAdvanced: T.bool,\n /**\n * Callback for editor click\n */\n onClick: T.func,\n /**\n * Callback for advanced config button click\n */\n onAdvancedConfigButtonClick: T.func,\n};\n\nexport default AdvancedControlGroup;\n","export const FLYOUT_PADDING = 21;\nexport const COLUMN_FLYOUT_PADDING = 16;\nexport const FLYOUT_WIDTH = 344;\n\nexport const VERTICAL_EDITOR_SPACING = 16;\n\nexport const DROPDOWN_MENU_WIDTH = 327;\n\nexport const editorStyle = { width: '100%' };\n","module.exports = require(\"@babel/runtime/helpers/defineProperty\");","module.exports = require(\"@splunk/react-icons/SlidersDoubleHorizontal\");","module.exports = require(\"@splunk/react-ui/Button\");","module.exports = require(\"@splunk/react-ui/ControlGroup\");","module.exports = require(\"@splunk/react-ui/Select\");","module.exports = require(\"@splunk/react-ui/Tooltip\");","module.exports = require(\"@splunk/themes\");","module.exports = require(\"@splunk/ui-utils/i18n\");","module.exports = require(\"lodash\");","module.exports = require(\"prop-types\");","module.exports = require(\"react\");","module.exports = require(\"styled-components\");","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import React, { useCallback } from 'react';\nimport T from 'prop-types';\nimport Select from '@splunk/react-ui/Select';\nimport { hasTokens } from '../utils/token';\nimport { getOptions } from '../utils/EditorFunctions';\nimport { editorStyle } from '../shared/dimensionConstants';\nimport ControlGroup from '../shared/AdvancedControlGroup';\n\nconst SelectEditor = ({\n onChange,\n name,\n itemSchema,\n values,\n value,\n labelPosition = 'top',\n labelWidth,\n label,\n tooltip,\n isDisabled = false,\n isAdvanced,\n hideLabel,\n help,\n}) => {\n const options = getOptions(itemSchema, values);\n const disabled = hasTokens(value) || isDisabled;\n const handleChange = useCallback((event, { value: v }) => onChange(event, name, v), [onChange, name]);\n\n return (\n <ControlGroup\n label={label}\n labelPosition={labelPosition}\n labelWidth={labelWidth}\n tooltip={tooltip}\n help={help}\n isAdvanced={isAdvanced}\n hideLabel={hideLabel}\n >\n <Select\n data-test={name}\n onChange={handleChange}\n value={value}\n disabled={disabled}\n style={editorStyle}\n >\n {options.map(v => (\n <Select.Option\n key={v.value}\n value={v.value}\n label={v.label || v.value}\n icon={v.icon ? <v.icon /> : null}\n description={v.description}\n />\n ))}\n </Select>\n </ControlGroup>\n );\n};\n\nSelectEditor.propTypes = {\n /**\n * Callback when selecting an item from the menu\n *\n * @param {SyntheticEvent} event The React `SyntheticEvent`\n * @param {string} name The option name\n * @param {string|boolean} value The option value\n */\n onChange: T.func.isRequired,\n /**\n * The option name\n */\n name: T.string.isRequired,\n /**\n * The item JSON schema, it should contain `enum` property. Note this will only be used when `values` prop is undefined\n */\n itemSchema: T.object,\n /**\n * The option values that can be selected\n */\n values: T.arrayOf(\n T.shape({\n label: T.string,\n value: T.oneOfType([T.string, T.number]).isRequired,\n description: T.string,\n })\n ),\n /**\n * The option value\n */\n value: T.oneOfType([T.string, T.number]),\n /**\n * A human readable label for the option\n */\n label: T.string.isRequired,\n /**\n * Label position\n */\n labelPosition: T.oneOf(['left', 'top']),\n labelWidth: T.number,\n /**\n * Text to display in a tooltip next to the label\n */\n tooltip: T.string,\n /**\n * Disabled state of component\n */\n isDisabled: T.bool,\n /**\n * As advanced editor to show advanced config button\n */\n isAdvanced: T.bool,\n /**\n * Disable label of control group\n */\n hideLabel: T.bool,\n /**\n * Text to display under the the input\n */\n help: T.string,\n};\n\nexport default SelectEditor;\n"],"names":["require","getOptions","itemSchema","values","Array","isArray","enum","map","item","value","Error","JSON","stringify","TokenRegExp","RegExp","source","hasTokens","test","ControlGroupContainer","variables","spacingMedium","StyledToolTip","StyledAdvancedConfigButton","contentColorActive","interactiveColorOverlayDrag","AdvancedConfigButton","label","onClick","content","_","icon","appearance","AdvancedControlGroup","dataTest","children","isAdvanced","hideLabel","labelPosition","labelWidth","tooltip","help","style","error","controlsLayout","onAdvancedConfigButtonClick","Children","toArray","filter","Boolean","child","cloneElement","flex","propTypes","T","object","bool","func","editorStyle","width","module","exports","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","call","n","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","r","Symbol","toStringTag","SelectEditor","onChange","name","isDisabled","options","disabled","handleChange","useCallback","event","v","React","ControlGroup","Select","description","isRequired"],"sourceRoot":""}
@@ -24,6 +24,7 @@
24
24
  height: 24px;
25
25
  background-color: ${e=>e.color};
26
26
  border-radius: 2px;
27
+ border: 1px solid ${c.default.neutral100};
27
28
  `,k=s.default.div`
28
29
  box-sizing: border-box;
29
30
  padding: 8px;
@@ -1 +1 @@
1
- {"version":3,"file":"SeriesColorsByFieldEditor.js","mappings":"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","sources":["webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/ScreenReaderContent\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualizations-shared/colorConstants\"","webpack://@splunk/dynamic-editors/./src/editors/ColorEditor.jsx","webpack://@splunk/dynamic-editors/./src/editors/MultiColorPickerEditor.tsx","webpack://@splunk/dynamic-editors/./src/editors/SeriesColorsByFieldEditor.tsx","webpack://@splunk/dynamic-editors/./src/hooks/useDataSource.tsx","webpack://@splunk/dynamic-editors/./src/interfaces/BaseEditorProps.ts","webpack://@splunk/dynamic-editors/./src/shared/AdvancedControlGroup.tsx","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-icons/SlidersDoubleHorizontal\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Button\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Color\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/ControlGroup\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/FormRows\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Popover\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Select\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Text\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Tooltip\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/themes\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/themes/variables\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/ui-utils/i18n\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/ui-utils/id\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualization-color-palettes\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualization-context/DataSourceContext\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualization-encoding/EncodingParser\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualization-encoding/Options\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualizations-shared/colorUtils\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualizations-shared/dataSourceUtils\"","webpack://@splunk/dynamic-editors/external commonjs2 \"lodash\"","webpack://@splunk/dynamic-editors/external commonjs2 \"prop-types\"","webpack://@splunk/dynamic-editors/external commonjs2 \"react\"","webpack://@splunk/dynamic-editors/external commonjs2 \"styled-components\"","webpack://@splunk/dynamic-editors/webpack/bootstrap","webpack://@splunk/dynamic-editors/webpack/runtime/compat get default export","webpack://@splunk/dynamic-editors/webpack/runtime/define property getters","webpack://@splunk/dynamic-editors/webpack/runtime/hasOwnProperty shorthand","webpack://@splunk/dynamic-editors/webpack/runtime/make namespace object","webpack://@splunk/dynamic-editors/webpack/startup"],"sourcesContent":["const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@splunk/react-ui/ScreenReaderContent\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@splunk/visualizations-shared/colorConstants\");","import React, { useEffect, useCallback, useState, useMemo } from 'react';\nimport T from 'prop-types';\nimport styled from 'styled-components';\nimport { debounce, noop, toLower } from 'lodash';\nimport { variables } from '@splunk/themes';\nimport Color from '@splunk/react-ui/Color';\nimport Text from '@splunk/react-ui/Text';\nimport { createDOMID } from '@splunk/ui-utils/id';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport ScreenReaderContent from '@splunk/react-ui/ScreenReaderContent';\nimport { COLOR_EDITOR_PALETTE } from '@splunk/visualizations-shared/colorConstants';\nimport { isColor } from '@splunk/visualizations-shared/colorUtils';\nimport ControlGroup from '../shared/AdvancedControlGroup';\n\nconst TextContainer = styled.div`\n max-height: ${variables.inputHeight};\n width: 100%;\n min-width: 0;\n`;\n\n// hardcoded style to sync with SUI color picker's hardcoded dimensions\n// TODO(fkurniawan): see if we can leverage prisma's consolidated textInput out of the box instead of our own component\n// right now, we're using hideInput\nconst StyledText = styled(Text)`\n max-height: ${variables.inputHeight};\n`;\n\n/**\n * Trims the color input and returns the result, or default color if the default color is valid, or previous color\n * @param {String} color The color the user entered\n * @param {String} defaultColor The default color of the component\n * @param {String} prevColor The previous color of the component\n * @returns {String}\n */\nconst getColor = ({ color, defaultColor, prevColor }) => {\n const newColor = typeof color === 'string' ? color.trim() : color;\n\n // color === null is `N/A` in color picker\n if (isColor(newColor) || newColor === null) {\n return newColor;\n }\n\n if (isColor(defaultColor)) {\n return defaultColor;\n }\n\n if (isColor(prevColor) || prevColor === null) {\n return prevColor;\n }\n\n return 'transparent';\n};\n\nconst ColorAndTextWrapper = ({\n id,\n showTextInput,\n color,\n palette,\n handleColorChange,\n labelledBy,\n textWidth,\n value,\n name,\n handleTextColorChange,\n handleKeyPress,\n handleBlur,\n isDisabled,\n}) => {\n const textLabelId = useMemo(() => createDOMID('color-code'), []);\n\n return (\n <>\n <div>\n <Color\n key=\"color-editor\"\n append={showTextInput}\n value={getColor({ color })}\n palette={palette}\n onChange={handleColorChange}\n data-test={`color-picker-${name}`}\n disabled={isDisabled}\n hideInput\n labelledBy={labelledBy}\n />\n </div>\n {showTextInput && (\n <TextContainer data-test=\"text-container\" textWidth={textWidth}>\n <ScreenReaderContent id={textLabelId}>{_('Color code input')}</ScreenReaderContent>\n <StyledText\n key={value}\n data-test={name}\n prepend\n value={color === null ? 'N/A' : color}\n onChange={handleTextColorChange}\n onKeyDown={handleKeyPress}\n onBlur={handleBlur}\n disabled={isDisabled}\n // hardcoded style to sync with SUI color picker's hardcoded dimensions\n // TODO(fkurniawan): see if we can leverage prisma's consolidated textInput out of the box\n style={{ height: '32px' }}\n labelledBy={`${labelledBy} ${textLabelId}`}\n inputId={id}\n />\n </TextContainer>\n )}\n </>\n );\n};\n\nColorAndTextWrapper.propTypes = {\n id: T.string,\n showTextInput: T.bool,\n color: T.string,\n palette: T.arrayOf(T.string),\n handleColorChange: T.func,\n labelledBy: T.string,\n textWidth: T.oneOfType([T.string, T.number]),\n value: T.string,\n name: T.string.isRequired,\n handleTextColorChange: T.func,\n handleKeyPress: T.func,\n handleBlur: T.func,\n isDisabled: T.bool,\n};\n\nconst defaultItemSchema = { default: 'transparent' };\nconst emptyStyle = {};\n\n// The propTypes typing for TS callers isn't working for the onChange callback\n/**\n * @param {Object} props\n * @param {(e: import('react').SyntheticEvent, name: string, value: string) => void} [props.onChange]\n * @returns\n */\nconst ColorEditor = ({\n name = 'color',\n value = 'transparent',\n label = '',\n labelPosition = 'top',\n labelWidth,\n palette = COLOR_EDITOR_PALETTE,\n onChange = noop,\n itemSchema = defaultItemSchema,\n isDisabled = false,\n textWidth = 'auto',\n hideLabel = false,\n showTextInput = true,\n style: customEditorStyle = emptyStyle,\n}) => {\n const [color, setColor] = useState(value);\n\n useEffect(() => {\n setColor(value);\n }, [value]);\n\n const debouncedOnChange = useMemo(() => debounce(onChange, 250), [onChange]);\n\n const handleColorChange = useCallback(\n ({ value: val }) => {\n const newColor = getColor({ color: val, defaultColor: itemSchema.default, prevColor: value });\n setColor(newColor);\n if (value !== newColor) {\n // No event to pass back, so it is null\n debouncedOnChange(null, name, newColor);\n }\n },\n [debouncedOnChange, itemSchema.default, name, value]\n );\n\n const handleTextColorChange = useCallback((_event, { value: val }) => {\n const colorToValue = toLower(val).trim() === 'n/a' ? null : val;\n setColor(colorToValue);\n }, []);\n\n const handleKeyPress = useCallback(\n event => {\n if (event.key === 'Escape') {\n setColor(value);\n return;\n }\n if (event.key !== 'Enter') {\n return;\n }\n\n if (value !== color) {\n const newColor = getColor({ color, defaultColor: itemSchema.default, prevColor: value });\n setColor(newColor);\n if (newColor !== value) {\n onChange(event, name, newColor);\n }\n }\n },\n [name, color, value, onChange, itemSchema.default]\n );\n\n const handleBlur = useCallback(\n event => {\n if (color !== value) {\n const newColor = getColor({ color, defaultColor: itemSchema.default, prevColor: value });\n setColor(newColor);\n if (newColor !== value) {\n onChange(event, name, newColor);\n }\n }\n },\n [name, color, value, onChange, itemSchema.default]\n );\n\n return (\n <ControlGroup\n label={label}\n labelPosition={labelPosition}\n labelWidth={labelWidth}\n style={customEditorStyle}\n hideLabel={hideLabel}\n controlsLayout=\"fillJoin\"\n >\n <ColorAndTextWrapper\n showTextInput={showTextInput}\n color={color}\n palette={palette}\n handleColorChange={handleColorChange}\n name={name}\n isDisabled={isDisabled}\n textWidth={textWidth}\n value={value}\n handleTextColorChange={handleTextColorChange}\n handleKeyPress={handleKeyPress}\n handleBlur={handleBlur}\n />\n </ControlGroup>\n );\n};\n\nColorEditor.propTypes = {\n /**\n * The option name\n */\n name: T.string.isRequired,\n\n /**\n * The option value\n */\n value: T.string,\n\n /**\n * @param {Object} itemSchema Either the dataContract or schema for the selected item\n */\n itemSchema: T.object,\n\n /**\n * A human readable label for the option\n */\n label: T.string.isRequired,\n\n /**\n * Flag to hide the editor label\n */\n hideLabel: T.bool,\n\n /**\n * Flag to hide the color text input\n */\n showTextInput: T.bool,\n\n /**\n * Custom styling for the editor layout, eg: setting margin-bottom to 0px for ControlGroup, SUI has it at 15px\n */\n style: T.object,\n\n /**\n * Label position\n */\n labelPosition: T.oneOf(['top', 'left']),\n\n /**\n * Label position\n */\n labelWidth: T.number,\n\n /**\n * An array of color swatch values\n */\n palette: T.arrayOf(T.string),\n\n /**\n * Callback when changing the text value\n *\n * @param {SyntheticEvent} event The react `SyntheticEvent`\n * @param {string} name The option name\n * @param {string} value The option value\n */\n onChange: T.func.isRequired,\n /**\n * Disabled state of component\n */\n isDisabled: T.bool,\n textWidth: T.oneOfType([T.string, T.number]),\n};\n\nexport default ColorEditor;\n","import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react';\nimport * as T from 'prop-types';\nimport styled from 'styled-components';\nimport { noop } from 'lodash';\nimport variables from '@splunk/themes/variables';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport FormRows from '@splunk/react-ui/FormRows';\nimport { createDOMID } from '@splunk/ui-utils/id';\nimport Button from '@splunk/react-ui/Button';\nimport Popover, { PopoverRequestCloseHandler } from '@splunk/react-ui/Popover';\nimport { VIZ_CATEGORICAL } from '@splunk/visualization-color-palettes';\nimport { BaseEditorPropTypes } from '../interfaces/BaseEditorProps';\nimport type { BaseEditorProps } from '../interfaces/BaseEditorProps';\nimport ControlGroup from '../shared/AdvancedControlGroup';\nimport ColorEditor from './ColorEditor';\n\nconst popoverStyle = { padding: '10px' };\nconst colorButtonStyle = { width: '314px' };\n\nconst StyledButton = styled(Button)`\n padding: 8px;\n width: 100%;\n min-height: 40px;\n & > span {\n display: grid;\n grid-template-columns: repeat(auto-fill, 26px);\n justify-content: space-evenly;\n grid-gap: 4px;\n }\n background-color: ${variables.interactiveColorBackground};\n`;\n\nconst ColorChip = styled.div`\n width: 26px;\n height: 24px;\n background-color: ${(props): string => props.color};\n border-radius: 2px;\n`;\n\nconst StyledFlyoutContent = styled.div`\n box-sizing: border-box;\n padding: 8px;\n width: 312px;\n max-height: 484px;\n background-color: ${variables.backgroundColorPopup};\n`;\n\nconst FlyoutHeader = styled.div`\n font-weight: 500;\n font-size: 14px;\n line-height: 20px;\n padding: 8px 8px 0 8px;\n font-family: ${variables.fontFamily};\n color: ${variables.contentColorActive};\n`;\n\nconst ColorListEditor = styled.div`\n height: 412px;\n overflow-y: auto;\n padding: 8px 10px;\n`;\n\nexport interface ColorFlyoutEditorProps {\n colors: string[];\n handleColorRemove: (_e, { index }: { index: number }) => void;\n handleColorChange: (idx: number) => (_evt, name: string, value: string) => void;\n CustomColorMatchEditor?: (props: { index: number }) => React.ReactNode;\n flyoutTitle: string;\n addColorButtonLabel: string;\n handleColorAdd: () => void;\n handleColorMove: (data: { fromIndex: number; toIndex: number }) => void;\n}\n\nexport const ColorFlyoutEditor = ({\n colors,\n CustomColorMatchEditor,\n handleColorRemove,\n handleColorChange,\n flyoutTitle,\n addColorButtonLabel,\n handleColorAdd,\n handleColorMove,\n}: ColorFlyoutEditorProps) => {\n const ColorRowItems = useMemo(() => {\n return colors.map((color, idx) => {\n // disable the color editor's text input when a custom input editor is available to render adjacently\n const showTextInput = CustomColorMatchEditor == null;\n return (\n <FormRows.Row\n index={idx}\n key={createDOMID()}\n data-color={color}\n onRequestRemove={handleColorRemove}\n >\n <div style={{ display: 'flex', justifyContent: 'space-between' }}>\n <ColorEditor\n value={color}\n key={createDOMID()}\n onChange={handleColorChange(idx)}\n hideLabel\n label=\" \"\n name=\"color\"\n style={{ marginBottom: 0, marginTop: 0, width: showTextInput ? '100%' : 32 }}\n showTextInput={showTextInput}\n />\n {typeof CustomColorMatchEditor === 'function' && (\n <CustomColorMatchEditor index={idx} />\n )}\n </div>\n </FormRows.Row>\n );\n });\n }, [colors, CustomColorMatchEditor, handleColorRemove, handleColorChange]);\n\n return (\n <StyledFlyoutContent data-test=\"MultiColorPickerFlyoutContent\">\n <FlyoutHeader data-test=\"MultiColorPickerFlyoutTitle\">{flyoutTitle}</FlyoutHeader>\n <ColorListEditor>\n <FormRows\n addLabel={addColorButtonLabel}\n onRequestAdd={handleColorAdd}\n onRequestMove={handleColorMove}\n data-test=\"ColorListEditor\"\n >\n {ColorRowItems}\n </FormRows>\n </ColorListEditor>\n </StyledFlyoutContent>\n );\n};\n\nexport interface MultiColorPickerEditorProps extends BaseEditorProps {\n CustomColorMatchEditor?: (props: { index: number }) => React.ReactNode;\n canReorderColors?: boolean;\n value: string[];\n flyoutTitle?: string;\n addColorButtonLabel?: string;\n hideLabel?: boolean;\n canAddNewColors?: boolean;\n}\n\nconst MultiColorPickerEditor: React.FunctionComponent<MultiColorPickerEditorProps> = ({\n CustomColorMatchEditor,\n onChange = noop,\n canReorderColors = true,\n value: vizColors = VIZ_CATEGORICAL,\n flyoutTitle = _('Customize colors'),\n addColorButtonLabel = _('Add color'),\n name = 'seriesColors',\n label = '',\n labelPosition = 'top',\n labelWidth,\n isDisabled = false,\n hideLabel = true,\n canAddNewColors = true,\n}) => {\n const [showFlyout, setShowFlyout] = useState(false);\n const [colors, setColors] = useState(vizColors);\n const buttonRef = useRef(null);\n\n useEffect(() => {\n setColors(vizColors);\n }, [vizColors]);\n\n // callbacks to add, remove, update and reorder a color form row\n const handleColorAdd = useCallback(() => {\n const userColorsSet = new Set(colors);\n let nextColor = VIZ_CATEGORICAL.find(color => !userColorsSet.has(color));\n if (!nextColor) {\n // All picked, count appearances\n const countMap = new Map<string, number>();\n VIZ_CATEGORICAL.forEach(color => countMap.set(color, 0));\n colors.forEach(color => {\n countMap.set(color, (countMap.get(color) || 0) + 1);\n });\n // Find color with minimum appearances\n let minCount = Infinity;\n VIZ_CATEGORICAL.forEach(color => {\n const count = countMap.get(color) || 0;\n if (count < minCount) {\n minCount = count;\n nextColor = color;\n }\n });\n }\n onChange(null, name, [...colors, nextColor]);\n }, [name, onChange, colors]);\n\n const handleColorChange = useCallback(\n idx => (_evt, _name, value) => {\n const colorsCopy = [...colors];\n colorsCopy.splice(idx, 1, value);\n onChange(null, name, colorsCopy);\n },\n [name, onChange, colors]\n );\n\n const handleColorRemove = useCallback(\n (e, { index }) => {\n const colorsCopy = [...colors];\n colorsCopy.splice(index, 1);\n onChange(null, name, colorsCopy);\n },\n [name, onChange, colors]\n );\n\n const handleColorMove = useCallback(\n ({ fromIndex, toIndex }) => {\n const colorsCopy = [...colors];\n const movedColor = colorsCopy[fromIndex];\n colorsCopy.splice(fromIndex, 1); // first, delete the color at the original position\n colorsCopy.splice(toIndex, 0, movedColor); // then reinsert it at the new position\n onChange(null, name, colorsCopy);\n },\n [name, onChange, colors]\n );\n\n /**\n * custom logic is required for closing the flyout as the FormRows component is rendered inside a Popover, and\n * when we sort the form rows, the popover closes mid-sorting (closeReason=\"clickAway\") as the dragged element is\n * taken out of the flow. Current workaround is to check if the event's source element has a sortable handle,\n * if yes, the flyout is kept open.\n *\n * Additionally, focus is returned to the trigger button when exiting through escape key press\n */\n const handleFlyoutClose: PopoverRequestCloseHandler = useCallback(({ event, reason }) => {\n // @ts-ignore\n if (!event?.srcElement?.sortableHandle) {\n setShowFlyout(false);\n }\n if (reason === 'escapeKey') {\n buttonRef.current.focus();\n }\n }, []);\n\n const ColorChips = useMemo(\n () => colors.map(color => <ColorChip color={color} key={createDOMID()} />),\n [colors]\n );\n\n const toggleShowFlyout = useCallback(() => {\n setShowFlyout(isShown => !isShown);\n }, []);\n\n return (\n <ControlGroup\n label={label}\n labelPosition={labelPosition}\n labelWidth={labelWidth}\n hideLabel={hideLabel}\n data-test=\"MultiColorPickerEditor\"\n >\n <StyledButton\n inline={false}\n data-test=\"MultiColorPickerButton\"\n appearance=\"default\"\n ref={buttonRef}\n onClick={toggleShowFlyout}\n disabled={isDisabled}\n style={colorButtonStyle}\n >\n {ColorChips}\n </StyledButton>\n <Popover\n data-test=\"MultiColorPickerFlyout\"\n open={showFlyout}\n anchor={buttonRef.current}\n defaultPlacement=\"horizontal\"\n style={popoverStyle}\n onRequestClose={handleFlyoutClose}\n takeFocus\n >\n <ColorFlyoutEditor\n colors={colors}\n CustomColorMatchEditor={CustomColorMatchEditor}\n handleColorRemove={handleColorRemove}\n handleColorChange={handleColorChange}\n handleColorAdd={canAddNewColors ? handleColorAdd : undefined}\n handleColorMove={canReorderColors ? handleColorMove : undefined}\n flyoutTitle={flyoutTitle}\n addColorButtonLabel={addColorButtonLabel}\n />\n </Popover>\n </ControlGroup>\n );\n};\n\nMultiColorPickerEditor.propTypes = {\n ...BaseEditorPropTypes,\n /**\n * Colors can be reordered manually\n */\n canReorderColors: T.bool,\n /**\n * Can add a new color\n */\n canAddNewColors: T.bool,\n /**\n * List of colors\n */\n value: T.arrayOf(T.string),\n /**\n * Title of the flyout editor\n */\n flyoutTitle: T.string,\n /**\n * Button label for adding a new color row\n */\n addColorButtonLabel: T.string,\n /**\n * Custom input editor for mapping a value to color, eg: dropdown for field -> color\n */\n CustomColorMatchEditor: T.func,\n /**\n * Flag to hide the editor label\n */\n hideLabel: T.bool,\n};\n\nexport default MultiColorPickerEditor;\n","import React, { useState, useCallback, useEffect, useMemo } from 'react';\nimport * as T from 'prop-types';\nimport { isEmpty } from 'lodash';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport { createDOMID } from '@splunk/ui-utils/id';\nimport Select from '@splunk/react-ui/Select';\nimport { Options } from '@splunk/visualization-encoding/Options';\nimport EncodingParser from '@splunk/visualization-encoding/EncodingParser';\nimport { getDataSourceStateInfo } from '@splunk/visualizations-shared/dataSourceUtils';\nimport MultiColorPickerEditor from './MultiColorPickerEditor';\nimport ControlGroup from '../shared/AdvancedControlGroup';\nimport { BaseEditorPropTypes } from '../interfaces/BaseEditorProps';\nimport type { BaseEditorProps } from '../interfaces/BaseEditorProps';\nimport { useDataSource } from '../hooks/useDataSource';\n\ntype ObjS = Record<string, string>;\ninterface FieldEditorProps {\n fields: string[];\n dsFields: string[];\n handleFieldChange: (args: { newFieldIndex: number; currFieldIndex: number }) => void;\n}\n\nconst FieldEditor = ({\n fields,\n dsFields,\n handleFieldChange,\n}: FieldEditorProps): (({ index }: { index: number }) => JSX.Element) => {\n const FieldSelector = ({ index }) => {\n const SelectOptions = useMemo(\n () =>\n dsFields.map((dsField, idx) => (\n <Select.Option\n label={dsField}\n value={idx}\n key={createDOMID()}\n data-test={`${dsField}-${index}`}\n />\n )),\n [index]\n );\n\n const handleChange = useCallback(\n (e, { value: newFieldIndex }): void => {\n handleFieldChange({ newFieldIndex, currFieldIndex: index });\n },\n [index]\n );\n\n const selectedField = dsFields.indexOf(fields[index]);\n\n return (\n <Select\n value={selectedField}\n onChange={handleChange}\n style={{ width: 190 }}\n data-test=\"field-select\"\n >\n {SelectOptions}\n </Select>\n );\n };\n FieldSelector.propTypes = {\n index: T.number,\n };\n return FieldSelector;\n};\n\nexport type SeriesColorsByFieldEditorProps = BaseEditorProps & { isCategorical?: boolean };\n\nconst defaultValue = {} as SeriesColorsByFieldEditorProps['value'];\nconst defaultOptions = {} as SeriesColorsByFieldEditorProps['options'];\nconst defaultOptionsSchema = {} as SeriesColorsByFieldEditorProps['optionsSchema'];\n\nconst SeriesColorsByFieldEditor = ({\n name,\n value = defaultValue,\n dataSourceBindings,\n onChange,\n options = defaultOptions,\n isCategorical = false,\n context,\n optionsSchema = defaultOptionsSchema,\n}: SeriesColorsByFieldEditorProps) => {\n const [colors, setColors] = useState<string[]>(Object.values(value));\n const [fields, setFields] = useState<string[]>(Object.keys(value));\n\n useEffect(() => {\n setColors(Object.values(value));\n setFields(Object.keys(value));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [JSON.stringify(value)]);\n\n // fetch the dataSource fields\n const dataSource = useDataSource({ dataSourceBindings, dataSourceKey: 'primary' });\n const { isLoading } = useMemo(() => getDataSourceStateInfo(dataSource), [dataSource]);\n\n // for bubble and scatter, we fallback on the 'category' option default in case it's not user defined\n const { category = optionsSchema?.category?.default } = options ?? {};\n\n const dsFields = useMemo(() => {\n if (isCategorical) {\n if (!category) {\n return [];\n }\n\n if (Array.isArray(category)) {\n return [...new Set(category.map(val => val?.toString()).filter(val => !isEmpty(val)))];\n }\n\n if (!isLoading && EncodingParser.isDslString(category)) {\n const results = Options.evaluate(\n { context, options: { ...options, category } },\n { primary: dataSource }\n );\n if (Array.isArray(results.category)) {\n return [\n ...new Set(results.category.map(val => val?.toString()).filter(val => !isEmpty(val))),\n ];\n }\n }\n\n return [];\n }\n return dataSource?.data?.fields.map(val => val.name) ?? [];\n }, [context, dataSource, isCategorical, options, category, isLoading]);\n\n const { editorLabel, flyoutTitle, addColorButtonLabel } = useMemo(\n () =>\n isCategorical\n ? {\n editorLabel: _('Series colors by category name'),\n flyoutTitle: _('Color by category name'),\n addColorButtonLabel: _('Add category'),\n }\n : {\n editorLabel: _('Series colors by field name'),\n flyoutTitle: _('Color by field name'),\n addColorButtonLabel: _('Add field'),\n },\n [isCategorical]\n );\n\n // create the mapping of fields -> colors\n const getUpdatedValue = ({ updatedColors, updatedFields }) => {\n const updatedValue: ObjS = {};\n updatedFields.forEach((field, idx) => {\n updatedValue[field] = updatedColors[idx];\n });\n return updatedValue;\n };\n\n const handleColorChange = useCallback(\n (_evt: null, _name: string, updatedColors: string[]): void => {\n // don't allow the user to add a new field row if all fields are mapped to a color\n if (updatedColors.length > dsFields.length) {\n return;\n }\n\n const updatedFields = fields;\n\n // new field row has been added\n if (updatedColors.length > colors.length) {\n const newField = dsFields.find(dsField => !fields.includes(dsField));\n updatedFields.push(newField);\n }\n\n // if a field row is removed, remove the field entry associated with that row\n if (updatedColors.length < colors.length) {\n const delRowIndex = colors.findIndex(color => !updatedColors.includes(color));\n updatedFields.splice(delRowIndex, 1);\n }\n\n onChange(null, name, getUpdatedValue({ updatedColors, updatedFields }));\n },\n [dsFields, onChange, name, fields, colors]\n );\n\n const handleFieldChange = useCallback(\n ({ newFieldIndex, currFieldIndex }: { newFieldIndex: number; currFieldIndex: number }): void => {\n // find if the selected field has already been set in a different field row\n const doesFieldExist = fields.includes(dsFields[newFieldIndex]);\n\n const updatedFields = fields;\n\n // fields have to be swapped\n if (doesFieldExist) {\n const existingFieldIndex = fields.indexOf(dsFields[newFieldIndex]);\n const currField = fields[currFieldIndex];\n updatedFields[currFieldIndex] = fields[existingFieldIndex];\n updatedFields[existingFieldIndex] = currField;\n } else {\n updatedFields[currFieldIndex] = dsFields[newFieldIndex]; // a new field has been selected and we don't need to swap fields\n }\n\n onChange(null, name, getUpdatedValue({ updatedColors: colors, updatedFields }));\n },\n [fields, dsFields, colors, name, onChange]\n );\n\n const CustomColorMatchEditor = useMemo(\n () => FieldEditor({ fields, dsFields, handleFieldChange }),\n [dsFields, fields, handleFieldChange]\n );\n\n return (\n <ControlGroup label={editorLabel} labelPosition=\"top\" data-test=\"SeriesColorsByFieldEditor\">\n <MultiColorPickerEditor\n value={colors}\n onChange={handleColorChange}\n name=\"series\"\n canReorderColors={false}\n flyoutTitle={flyoutTitle}\n addColorButtonLabel={addColorButtonLabel}\n CustomColorMatchEditor={CustomColorMatchEditor}\n isDisabled={dsFields.length < 1}\n canAddNewColors={fields.length < dsFields.length}\n />\n </ControlGroup>\n );\n};\n\nSeriesColorsByFieldEditor.propTypes = { ...BaseEditorPropTypes, isCategorical: T.bool };\n\nexport default SeriesColorsByFieldEditor;\n","import { useState, useEffect, useContext } from 'react';\nimport DataSourceContext, {\n type BindingsSnapshot,\n type DataSourceApi,\n} from '@splunk/visualization-context/DataSourceContext';\nimport { get, isFunction } from 'lodash';\n\ninterface UseDataSourceParams {\n dataSourceBindings: BindingsSnapshot;\n dataSourceKey: string;\n}\n// @TODO(pwied): use DataSource interface in return type (w/o dependency on @splunk/visualizations)\nexport const useDataSource = ({\n dataSourceBindings,\n dataSourceKey,\n}: UseDataSourceParams): BindingsSnapshot => {\n const dataSourceApi = useContext<DataSourceApi>(DataSourceContext);\n const [dataSource, setDataSource] = useState<BindingsSnapshot>();\n useEffect((): (() => void) => {\n if (!get(dataSourceBindings, dataSourceKey)) {\n setDataSource(null);\n return () => undefined;\n }\n const unsubscribe =\n isFunction(dataSourceApi.subscribe) &&\n dataSourceApi.subscribe(dataSourceKey, (snapshot): void => setDataSource(snapshot));\n return () => {\n if (unsubscribe) {\n unsubscribe();\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [dataSourceBindings]);\n return dataSource;\n};\n","import * as T from 'prop-types';\nimport type { JSONSchema7 } from 'json-schema';\n\nexport interface BaseEditorProps {\n name: string;\n value: any;\n onChange?: (...args: any[]) => void;\n label?: string; // @TODO(pwied): this should not live in editor props\n labelPosition?: 'top' | 'left'; // ^^^\n context?: Record<string, any>;\n labelWidth?: number;\n isAdvanced?: boolean;\n isDisabled?: boolean;\n dataSourceBindings?: Record<string, any>;\n options?: { [k: string]: any };\n optionsSchema?: {\n [key: string]: JSONSchema7;\n };\n}\n\nexport const BaseEditorPropTypes: Record<keyof BaseEditorProps, T.Validator<any>> = {\n name: T.string.isRequired,\n value: T.oneOfType([T.string, T.object, T.arrayOf(T.string)]),\n context: T.object,\n label: T.string,\n labelPosition: T.oneOf(['top', 'left']),\n labelWidth: T.number,\n onChange: T.func,\n isAdvanced: T.bool,\n isDisabled: T.bool,\n dataSourceBindings: T.object,\n options: T.object,\n optionsSchema: T.object,\n};\n","import React, { Children, cloneElement } from 'react';\nimport type { ReactElement } from 'react';\nimport * as T from 'prop-types';\nimport styled from 'styled-components';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport AdvancedConfigIcon from '@splunk/react-icons/SlidersDoubleHorizontal';\nimport { variables } from '@splunk/themes';\nimport Tooltip from '@splunk/react-ui/Tooltip';\nimport Button, { ButtonClickHandler, ButtonProps } from '@splunk/react-ui/Button';\nimport SUIControlGroup from '@splunk/react-ui/ControlGroup';\nimport type { ControlGroupPropsBase } from '@splunk/react-ui/ControlGroup';\n\ninterface AdvancedControlGroupProps extends Omit<ControlGroupPropsBase, 'splunkTheme'> {\n 'data-test'?: string;\n style?: Record<string, string | number>;\n isAdvanced?: boolean;\n onClick?: React.MouseEventHandler<HTMLDivElement>;\n onAdvancedConfigButtonClick?: ButtonClickHandler;\n}\n\ninterface AdvancedConfigButtonProps {\n label?: string;\n onClick?: ButtonClickHandler;\n}\n\n// remove all surrounding margins. let parent add padding\nconst ControlGroupContainer = styled(SUIControlGroup)`\n margin-top: 0;\n padding: 0;\n // adjust bottom margin according to theme\n margin-bottom: ${variables.spacingMedium};\n width: 100%;\n\n // remove top margin of the first component in control group\n &:first-child {\n margin-top: 0;\n }\n\n // remove bottom margin of the last component in control group\n &:last-child {\n margin-bottom: 0;\n }\n // remove top padding on label of the first control group\n [data-test='label']:first-of-type {\n padding-top: 0;\n }\n`;\n\n// override tooltip to set desired config button style\nconst StyledToolTip = styled(Tooltip)`\n display: flex;\n > span {\n display: flex;\n width: 35px;\n }\n`;\n\nconst StyledAdvancedConfigButton = styled(Button)<ButtonProps>`\n color: ${variables.contentColorActive} !important;\n &:hover {\n background-color: ${variables.interactiveColorOverlayDrag} !important;\n }\n`;\n\nexport const AdvancedConfigButton = ({\n label = '',\n onClick,\n}: AdvancedConfigButtonProps): React.ReactElement => {\n return (\n <StyledToolTip\n data-test={`${label}-advanced-config-button-tooltip`}\n content={_('Advanced configurations')}\n >\n <StyledAdvancedConfigButton\n data-test={`${label}-advanced-config-button`}\n icon={<AdvancedConfigIcon data-test={`${label}-advanced-config-button-icon`} />}\n appearance=\"subtle\"\n onClick={onClick}\n />\n </StyledToolTip>\n );\n};\n\nconst AdvancedControlGroup = ({\n 'data-test': dataTest,\n children,\n isAdvanced = false,\n label,\n hideLabel,\n labelPosition,\n labelWidth,\n tooltip,\n help,\n style,\n error,\n controlsLayout,\n onClick,\n onAdvancedConfigButtonClick,\n}: AdvancedControlGroupProps): React.ReactElement => (\n <ControlGroupContainer\n data-test={dataTest ?? 'control-group'}\n label={label}\n hideLabel={hideLabel}\n labelPosition={labelPosition}\n labelWidth={labelWidth}\n tooltip={tooltip}\n help={help}\n error={error}\n style={style}\n onClick={onClick}\n controlsLayout={controlsLayout}\n >\n {isAdvanced\n ? Children.toArray(children)\n .filter(Boolean)\n .map(child =>\n cloneElement(child as ReactElement, {\n style: { flex: 1 },\n })\n )\n : children}\n {isAdvanced ? <AdvancedConfigButton label={label} onClick={onAdvancedConfigButtonClick} /> : null}\n </ControlGroupContainer>\n);\n\nAdvancedControlGroup.propTypes = {\n /**\n * Style overriding SUI ControlGroup\n */\n style: T.object,\n /**\n * Whether the current editor is enabled with advanced configurations\n */\n isAdvanced: T.bool,\n /**\n * Callback for editor click\n */\n onClick: T.func,\n /**\n * Callback for advanced config button click\n */\n onAdvancedConfigButtonClick: T.func,\n};\n\nexport default AdvancedControlGroup;\n","module.exports = require(\"@splunk/react-icons/SlidersDoubleHorizontal\");","module.exports = require(\"@splunk/react-ui/Button\");","module.exports = require(\"@splunk/react-ui/Color\");","module.exports = require(\"@splunk/react-ui/ControlGroup\");","module.exports = require(\"@splunk/react-ui/FormRows\");","module.exports = require(\"@splunk/react-ui/Popover\");","module.exports = require(\"@splunk/react-ui/Select\");","module.exports = require(\"@splunk/react-ui/Text\");","module.exports = require(\"@splunk/react-ui/Tooltip\");","module.exports = require(\"@splunk/themes\");","module.exports = require(\"@splunk/themes/variables\");","module.exports = require(\"@splunk/ui-utils/i18n\");","module.exports = require(\"@splunk/ui-utils/id\");","module.exports = require(\"@splunk/visualization-color-palettes\");","module.exports = require(\"@splunk/visualization-context/DataSourceContext\");","module.exports = require(\"@splunk/visualization-encoding/EncodingParser\");","module.exports = require(\"@splunk/visualization-encoding/Options\");","module.exports = require(\"@splunk/visualizations-shared/colorUtils\");","module.exports = require(\"@splunk/visualizations-shared/dataSourceUtils\");","module.exports = require(\"lodash\");","module.exports = require(\"prop-types\");","module.exports = require(\"react\");","module.exports = require(\"styled-components\");","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(7364);\n"],"names":["require","TextContainer","styled","variables","inputHeight","StyledText","Text","getColor","color","defaultColor","prevColor","newColor","trim","isColor","ColorAndTextWrapper","id","showTextInput","palette","handleColorChange","labelledBy","textWidth","value","name","handleTextColorChange","handleKeyPress","handleBlur","isDisabled","textLabelId","useMemo","createDOMID","React","Color","key","append","onChange","disabled","hideInput","ScreenReaderContent","_","prepend","onKeyDown","onBlur","style","height","inputId","propTypes","T","isRequired","defaultItemSchema","default","emptyStyle","ColorEditor","label","labelPosition","labelWidth","COLOR_EDITOR_PALETTE","noop","itemSchema","hideLabel","customEditorStyle","setColor","useState","useEffect","debouncedOnChange","debounce","useCallback","val","_event","colorToValue","toLower","event","ControlGroup","controlsLayout","popoverStyle","padding","colorButtonStyle","width","StyledButton","interactiveColorBackground","ColorChip","div","props","StyledFlyoutContent","backgroundColorPopup","FlyoutHeader","fontFamily","contentColorActive","ColorListEditor","ColorFlyoutEditor","colors","CustomColorMatchEditor","handleColorRemove","flyoutTitle","addColorButtonLabel","handleColorAdd","handleColorMove","ColorRowItems","map","idx","Row","index","onRequestRemove","display","justifyContent","marginBottom","marginTop","addLabel","onRequestAdd","onRequestMove","MultiColorPickerEditor","canReorderColors","vizColors","VIZ_CATEGORICAL","canAddNewColors","showFlyout","setShowFlyout","setColors","buttonRef","useRef","userColorsSet","Set","nextColor","find","has","countMap","Map","forEach","set","get","minCount","Infinity","count","_evt","_name","colorsCopy","splice","e","fromIndex","toIndex","movedColor","handleFlyoutClose","reason","srcElement","sortableHandle","current","focus","ColorChips","toggleShowFlyout","isShown","inline","appearance","ref","onClick","open","anchor","defaultPlacement","onRequestClose","takeFocus","undefined","BaseEditorPropTypes","bool","arrayOf","string","func","defaultValue","defaultOptions","defaultOptionsSchema","SeriesColorsByFieldEditor","dataSourceBindings","options","isCategorical","context","optionsSchema","Object","values","fields","setFields","keys","JSON","stringify","dataSource","useDataSource","dataSourceKey","isLoading","getDataSourceStateInfo","category","dsFields","Array","isArray","toString","filter","isEmpty","isDslString","results","Options","evaluate","primary","data","editorLabel","getUpdatedValue","updatedColors","updatedFields","updatedValue","field","length","newField","dsField","includes","push","delRowIndex","findIndex","handleFieldChange","newFieldIndex","currFieldIndex","doesFieldExist","existingFieldIndex","indexOf","currField","FieldSelector","SelectOptions","Option","handleChange","selectedField","number","FieldEditor","dataSourceApi","useContext","setDataSource","unsubscribe","isFunction","subscribe","snapshot","oneOfType","object","oneOf","isAdvanced","ControlGroupContainer","spacingMedium","StyledToolTip","StyledAdvancedConfigButton","interactiveColorOverlayDrag","AdvancedConfigButton","content","icon","AdvancedControlGroup","dataTest","children","tooltip","help","error","onAdvancedConfigButtonClick","Children","toArray","Boolean","child","cloneElement","flex","module","exports","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","call","n","getter","__esModule","d","a","definition","o","defineProperty","enumerable","obj","prop","prototype","hasOwnProperty","r","Symbol","toStringTag","__webpack_exports__"],"sourceRoot":""}
1
+ {"version":3,"file":"SeriesColorsByFieldEditor.js","mappings":"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","sources":["webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/ScreenReaderContent\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualizations-shared/colorConstants\"","webpack://@splunk/dynamic-editors/./src/editors/ColorEditor.jsx","webpack://@splunk/dynamic-editors/./src/editors/MultiColorPickerEditor.tsx","webpack://@splunk/dynamic-editors/./src/editors/SeriesColorsByFieldEditor.tsx","webpack://@splunk/dynamic-editors/./src/hooks/useDataSource.tsx","webpack://@splunk/dynamic-editors/./src/interfaces/BaseEditorProps.ts","webpack://@splunk/dynamic-editors/./src/shared/AdvancedControlGroup.tsx","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-icons/SlidersDoubleHorizontal\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Button\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Color\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/ControlGroup\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/FormRows\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Popover\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Select\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Text\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/react-ui/Tooltip\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/themes\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/themes/variables\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/ui-utils/i18n\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/ui-utils/id\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualization-color-palettes\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualization-context/DataSourceContext\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualization-encoding/EncodingParser\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualization-encoding/Options\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualizations-shared/colorUtils\"","webpack://@splunk/dynamic-editors/external commonjs2 \"@splunk/visualizations-shared/dataSourceUtils\"","webpack://@splunk/dynamic-editors/external commonjs2 \"lodash\"","webpack://@splunk/dynamic-editors/external commonjs2 \"prop-types\"","webpack://@splunk/dynamic-editors/external commonjs2 \"react\"","webpack://@splunk/dynamic-editors/external commonjs2 \"styled-components\"","webpack://@splunk/dynamic-editors/webpack/bootstrap","webpack://@splunk/dynamic-editors/webpack/runtime/compat get default export","webpack://@splunk/dynamic-editors/webpack/runtime/define property getters","webpack://@splunk/dynamic-editors/webpack/runtime/hasOwnProperty shorthand","webpack://@splunk/dynamic-editors/webpack/runtime/make namespace object","webpack://@splunk/dynamic-editors/webpack/startup"],"sourcesContent":["const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@splunk/react-ui/ScreenReaderContent\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@splunk/visualizations-shared/colorConstants\");","import React, { useEffect, useCallback, useState, useMemo } from 'react';\nimport T from 'prop-types';\nimport styled from 'styled-components';\nimport { debounce, noop, toLower } from 'lodash';\nimport { variables } from '@splunk/themes';\nimport Color from '@splunk/react-ui/Color';\nimport Text from '@splunk/react-ui/Text';\nimport { createDOMID } from '@splunk/ui-utils/id';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport ScreenReaderContent from '@splunk/react-ui/ScreenReaderContent';\nimport { COLOR_EDITOR_PALETTE } from '@splunk/visualizations-shared/colorConstants';\nimport { isColor } from '@splunk/visualizations-shared/colorUtils';\nimport ControlGroup from '../shared/AdvancedControlGroup';\n\nconst TextContainer = styled.div`\n max-height: ${variables.inputHeight};\n width: 100%;\n min-width: 0;\n`;\n\n// hardcoded style to sync with SUI color picker's hardcoded dimensions\n// TODO(fkurniawan): see if we can leverage prisma's consolidated textInput out of the box instead of our own component\n// right now, we're using hideInput\nconst StyledText = styled(Text)`\n max-height: ${variables.inputHeight};\n`;\n\n/**\n * Trims the color input and returns the result, or default color if the default color is valid, or previous color\n * @param {String} color The color the user entered\n * @param {String} defaultColor The default color of the component\n * @param {String} prevColor The previous color of the component\n * @returns {String}\n */\nconst getColor = ({ color, defaultColor, prevColor }) => {\n const newColor = typeof color === 'string' ? color.trim() : color;\n\n // color === null is `N/A` in color picker\n if (isColor(newColor) || newColor === null) {\n return newColor;\n }\n\n if (isColor(defaultColor)) {\n return defaultColor;\n }\n\n if (isColor(prevColor) || prevColor === null) {\n return prevColor;\n }\n\n return 'transparent';\n};\n\nconst ColorAndTextWrapper = ({\n id,\n showTextInput,\n color,\n palette,\n handleColorChange,\n labelledBy,\n textWidth,\n value,\n name,\n handleTextColorChange,\n handleKeyPress,\n handleBlur,\n isDisabled,\n}) => {\n const textLabelId = useMemo(() => createDOMID('color-code'), []);\n\n return (\n <>\n <div>\n <Color\n key=\"color-editor\"\n append={showTextInput}\n value={getColor({ color })}\n palette={palette}\n onChange={handleColorChange}\n data-test={`color-picker-${name}`}\n disabled={isDisabled}\n hideInput\n labelledBy={labelledBy}\n />\n </div>\n {showTextInput && (\n <TextContainer data-test=\"text-container\" textWidth={textWidth}>\n <ScreenReaderContent id={textLabelId}>{_('Color code input')}</ScreenReaderContent>\n <StyledText\n key={value}\n data-test={name}\n prepend\n value={color === null ? 'N/A' : color}\n onChange={handleTextColorChange}\n onKeyDown={handleKeyPress}\n onBlur={handleBlur}\n disabled={isDisabled}\n // hardcoded style to sync with SUI color picker's hardcoded dimensions\n // TODO(fkurniawan): see if we can leverage prisma's consolidated textInput out of the box\n style={{ height: '32px' }}\n labelledBy={`${labelledBy} ${textLabelId}`}\n inputId={id}\n />\n </TextContainer>\n )}\n </>\n );\n};\n\nColorAndTextWrapper.propTypes = {\n id: T.string,\n showTextInput: T.bool,\n color: T.string,\n palette: T.arrayOf(T.string),\n handleColorChange: T.func,\n labelledBy: T.string,\n textWidth: T.oneOfType([T.string, T.number]),\n value: T.string,\n name: T.string.isRequired,\n handleTextColorChange: T.func,\n handleKeyPress: T.func,\n handleBlur: T.func,\n isDisabled: T.bool,\n};\n\nconst defaultItemSchema = { default: 'transparent' };\nconst emptyStyle = {};\n\n// The propTypes typing for TS callers isn't working for the onChange callback\n/**\n * @param {Object} props\n * @param {(e: import('react').SyntheticEvent, name: string, value: string) => void} [props.onChange]\n * @returns\n */\nconst ColorEditor = ({\n name = 'color',\n value = 'transparent',\n label = '',\n labelPosition = 'top',\n labelWidth,\n palette = COLOR_EDITOR_PALETTE,\n onChange = noop,\n itemSchema = defaultItemSchema,\n isDisabled = false,\n textWidth = 'auto',\n hideLabel = false,\n showTextInput = true,\n style: customEditorStyle = emptyStyle,\n}) => {\n const [color, setColor] = useState(value);\n\n useEffect(() => {\n setColor(value);\n }, [value]);\n\n const debouncedOnChange = useMemo(() => debounce(onChange, 250), [onChange]);\n\n const handleColorChange = useCallback(\n ({ value: val }) => {\n const newColor = getColor({ color: val, defaultColor: itemSchema.default, prevColor: value });\n setColor(newColor);\n if (value !== newColor) {\n // No event to pass back, so it is null\n debouncedOnChange(null, name, newColor);\n }\n },\n [debouncedOnChange, itemSchema.default, name, value]\n );\n\n const handleTextColorChange = useCallback((_event, { value: val }) => {\n const colorToValue = toLower(val).trim() === 'n/a' ? null : val;\n setColor(colorToValue);\n }, []);\n\n const handleKeyPress = useCallback(\n event => {\n if (event.key === 'Escape') {\n setColor(value);\n return;\n }\n if (event.key !== 'Enter') {\n return;\n }\n\n if (value !== color) {\n const newColor = getColor({ color, defaultColor: itemSchema.default, prevColor: value });\n setColor(newColor);\n if (newColor !== value) {\n onChange(event, name, newColor);\n }\n }\n },\n [name, color, value, onChange, itemSchema.default]\n );\n\n const handleBlur = useCallback(\n event => {\n if (color !== value) {\n const newColor = getColor({ color, defaultColor: itemSchema.default, prevColor: value });\n setColor(newColor);\n if (newColor !== value) {\n onChange(event, name, newColor);\n }\n }\n },\n [name, color, value, onChange, itemSchema.default]\n );\n\n return (\n <ControlGroup\n label={label}\n labelPosition={labelPosition}\n labelWidth={labelWidth}\n style={customEditorStyle}\n hideLabel={hideLabel}\n controlsLayout=\"fillJoin\"\n >\n <ColorAndTextWrapper\n showTextInput={showTextInput}\n color={color}\n palette={palette}\n handleColorChange={handleColorChange}\n name={name}\n isDisabled={isDisabled}\n textWidth={textWidth}\n value={value}\n handleTextColorChange={handleTextColorChange}\n handleKeyPress={handleKeyPress}\n handleBlur={handleBlur}\n />\n </ControlGroup>\n );\n};\n\nColorEditor.propTypes = {\n /**\n * The option name\n */\n name: T.string.isRequired,\n\n /**\n * The option value\n */\n value: T.string,\n\n /**\n * @param {Object} itemSchema Either the dataContract or schema for the selected item\n */\n itemSchema: T.object,\n\n /**\n * A human readable label for the option\n */\n label: T.string.isRequired,\n\n /**\n * Flag to hide the editor label\n */\n hideLabel: T.bool,\n\n /**\n * Flag to hide the color text input\n */\n showTextInput: T.bool,\n\n /**\n * Custom styling for the editor layout, eg: setting margin-bottom to 0px for ControlGroup, SUI has it at 15px\n */\n style: T.object,\n\n /**\n * Label position\n */\n labelPosition: T.oneOf(['top', 'left']),\n\n /**\n * Label position\n */\n labelWidth: T.number,\n\n /**\n * An array of color swatch values\n */\n palette: T.arrayOf(T.string),\n\n /**\n * Callback when changing the text value\n *\n * @param {SyntheticEvent} event The react `SyntheticEvent`\n * @param {string} name The option name\n * @param {string} value The option value\n */\n onChange: T.func.isRequired,\n /**\n * Disabled state of component\n */\n isDisabled: T.bool,\n textWidth: T.oneOfType([T.string, T.number]),\n};\n\nexport default ColorEditor;\n","import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react';\nimport * as T from 'prop-types';\nimport styled from 'styled-components';\nimport { noop } from 'lodash';\nimport variables from '@splunk/themes/variables';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport FormRows from '@splunk/react-ui/FormRows';\nimport { createDOMID } from '@splunk/ui-utils/id';\nimport Button from '@splunk/react-ui/Button';\nimport type { PopoverRequestCloseHandler } from '@splunk/react-ui/Popover';\nimport Popover from '@splunk/react-ui/Popover';\nimport { VIZ_CATEGORICAL } from '@splunk/visualization-color-palettes';\nimport { BaseEditorPropTypes } from '../interfaces/BaseEditorProps';\nimport type { BaseEditorProps } from '../interfaces/BaseEditorProps';\nimport ControlGroup from '../shared/AdvancedControlGroup';\nimport ColorEditor from './ColorEditor';\n\nconst popoverStyle = { padding: '10px' };\nconst colorButtonStyle = { width: '314px' };\n\nconst StyledButton = styled(Button)`\n padding: 8px;\n width: 100%;\n min-height: 40px;\n & > span {\n display: grid;\n grid-template-columns: repeat(auto-fill, 26px);\n justify-content: space-evenly;\n grid-gap: 4px;\n }\n background-color: ${variables.interactiveColorBackground};\n`;\n\nconst ColorChip = styled.div`\n width: 26px;\n height: 24px;\n background-color: ${(props): string => props.color};\n border-radius: 2px;\n border: 1px solid ${variables.neutral100};\n`;\n\nconst StyledFlyoutContent = styled.div`\n box-sizing: border-box;\n padding: 8px;\n width: 312px;\n max-height: 484px;\n background-color: ${variables.backgroundColorPopup};\n`;\n\nconst FlyoutHeader = styled.div`\n font-weight: 500;\n font-size: 14px;\n line-height: 20px;\n padding: 8px 8px 0 8px;\n font-family: ${variables.fontFamily};\n color: ${variables.contentColorActive};\n`;\n\nconst ColorListEditor = styled.div`\n height: 412px;\n overflow-y: auto;\n padding: 8px 10px;\n`;\n\nexport interface ColorFlyoutEditorProps {\n colors: string[];\n handleColorRemove: (_e, { index }: { index: number }) => void;\n handleColorChange: (idx: number) => (_evt, name: string, value: string) => void;\n CustomColorMatchEditor?: (props: { index: number }) => React.ReactNode;\n flyoutTitle: string;\n addColorButtonLabel: string;\n handleColorAdd: () => void;\n handleColorMove: (data: { fromIndex: number; toIndex: number }) => void;\n}\n\nexport const ColorFlyoutEditor = ({\n colors,\n CustomColorMatchEditor,\n handleColorRemove,\n handleColorChange,\n flyoutTitle,\n addColorButtonLabel,\n handleColorAdd,\n handleColorMove,\n}: ColorFlyoutEditorProps) => {\n const ColorRowItems = useMemo(() => {\n return colors.map((color, idx) => {\n // disable the color editor's text input when a custom input editor is available to render adjacently\n const showTextInput = CustomColorMatchEditor == null;\n return (\n <FormRows.Row\n index={idx}\n key={createDOMID()}\n data-color={color}\n onRequestRemove={handleColorRemove}\n >\n <div style={{ display: 'flex', justifyContent: 'space-between' }}>\n <ColorEditor\n value={color}\n key={createDOMID()}\n onChange={handleColorChange(idx)}\n hideLabel\n label=\" \"\n name=\"color\"\n style={{ marginBottom: 0, marginTop: 0, width: showTextInput ? '100%' : 32 }}\n showTextInput={showTextInput}\n />\n {typeof CustomColorMatchEditor === 'function' && (\n <CustomColorMatchEditor index={idx} />\n )}\n </div>\n </FormRows.Row>\n );\n });\n }, [colors, CustomColorMatchEditor, handleColorRemove, handleColorChange]);\n\n return (\n <StyledFlyoutContent data-test=\"MultiColorPickerFlyoutContent\">\n <FlyoutHeader data-test=\"MultiColorPickerFlyoutTitle\">{flyoutTitle}</FlyoutHeader>\n <ColorListEditor>\n <FormRows\n addLabel={addColorButtonLabel}\n onRequestAdd={handleColorAdd}\n onRequestMove={handleColorMove}\n data-test=\"ColorListEditor\"\n >\n {ColorRowItems}\n </FormRows>\n </ColorListEditor>\n </StyledFlyoutContent>\n );\n};\n\nexport interface MultiColorPickerEditorProps extends BaseEditorProps {\n CustomColorMatchEditor?: (props: { index: number }) => React.ReactNode;\n canReorderColors?: boolean;\n value: string[];\n flyoutTitle?: string;\n addColorButtonLabel?: string;\n hideLabel?: boolean;\n canAddNewColors?: boolean;\n}\n\nconst MultiColorPickerEditor: React.FunctionComponent<MultiColorPickerEditorProps> = ({\n CustomColorMatchEditor,\n onChange = noop,\n canReorderColors = true,\n value: vizColors = VIZ_CATEGORICAL,\n flyoutTitle = _('Customize colors'),\n addColorButtonLabel = _('Add color'),\n name = 'seriesColors',\n label = '',\n labelPosition = 'top',\n labelWidth,\n isDisabled = false,\n hideLabel = true,\n canAddNewColors = true,\n}) => {\n const [showFlyout, setShowFlyout] = useState(false);\n const [colors, setColors] = useState(vizColors);\n const buttonRef = useRef(null);\n\n useEffect(() => {\n setColors(vizColors);\n }, [vizColors]);\n\n // callbacks to add, remove, update and reorder a color form row\n const handleColorAdd = useCallback(() => {\n const userColorsSet = new Set(colors);\n let nextColor = VIZ_CATEGORICAL.find(color => !userColorsSet.has(color));\n if (!nextColor) {\n // All picked, count appearances\n const countMap = new Map<string, number>();\n VIZ_CATEGORICAL.forEach(color => countMap.set(color, 0));\n colors.forEach(color => {\n countMap.set(color, (countMap.get(color) || 0) + 1);\n });\n // Find color with minimum appearances\n let minCount = Infinity;\n VIZ_CATEGORICAL.forEach(color => {\n const count = countMap.get(color) || 0;\n if (count < minCount) {\n minCount = count;\n nextColor = color;\n }\n });\n }\n onChange(null, name, [...colors, nextColor]);\n }, [name, onChange, colors]);\n\n const handleColorChange = useCallback(\n idx => (_evt, _name, value) => {\n const colorsCopy = [...colors];\n colorsCopy.splice(idx, 1, value);\n onChange(null, name, colorsCopy);\n },\n [name, onChange, colors]\n );\n\n const handleColorRemove = useCallback(\n (e, { index }) => {\n const colorsCopy = [...colors];\n colorsCopy.splice(index, 1);\n onChange(null, name, colorsCopy);\n },\n [name, onChange, colors]\n );\n\n const handleColorMove = useCallback(\n ({ fromIndex, toIndex }) => {\n const colorsCopy = [...colors];\n const movedColor = colorsCopy[fromIndex];\n colorsCopy.splice(fromIndex, 1); // first, delete the color at the original position\n colorsCopy.splice(toIndex, 0, movedColor); // then reinsert it at the new position\n onChange(null, name, colorsCopy);\n },\n [name, onChange, colors]\n );\n\n /**\n * custom logic is required for closing the flyout as the FormRows component is rendered inside a Popover, and\n * when we sort the form rows, the popover closes mid-sorting (closeReason=\"clickAway\") as the dragged element is\n * taken out of the flow. Current workaround is to check if the event's source element has a sortable handle,\n * if yes, the flyout is kept open.\n *\n * Additionally, focus is returned to the trigger button when exiting through escape key press\n */\n const handleFlyoutClose: PopoverRequestCloseHandler = useCallback(({ event, reason }) => {\n // @ts-ignore\n if (!event?.srcElement?.sortableHandle) {\n setShowFlyout(false);\n }\n if (reason === 'escapeKey') {\n buttonRef.current.focus();\n }\n }, []);\n\n const ColorChips = useMemo(\n () => colors.map(color => <ColorChip color={color} key={createDOMID()} />),\n [colors]\n );\n\n const toggleShowFlyout = useCallback(() => {\n setShowFlyout(isShown => !isShown);\n }, []);\n\n return (\n <ControlGroup\n label={label}\n labelPosition={labelPosition}\n labelWidth={labelWidth}\n hideLabel={hideLabel}\n data-test=\"MultiColorPickerEditor\"\n >\n <StyledButton\n inline={false}\n data-test=\"MultiColorPickerButton\"\n appearance=\"default\"\n ref={buttonRef}\n onClick={toggleShowFlyout}\n disabled={isDisabled}\n style={colorButtonStyle}\n >\n {ColorChips}\n </StyledButton>\n <Popover\n data-test=\"MultiColorPickerFlyout\"\n open={showFlyout}\n anchor={buttonRef.current}\n defaultPlacement=\"horizontal\"\n style={popoverStyle}\n onRequestClose={handleFlyoutClose}\n takeFocus\n >\n <ColorFlyoutEditor\n colors={colors}\n CustomColorMatchEditor={CustomColorMatchEditor}\n handleColorRemove={handleColorRemove}\n handleColorChange={handleColorChange}\n handleColorAdd={canAddNewColors ? handleColorAdd : undefined}\n handleColorMove={canReorderColors ? handleColorMove : undefined}\n flyoutTitle={flyoutTitle}\n addColorButtonLabel={addColorButtonLabel}\n />\n </Popover>\n </ControlGroup>\n );\n};\n\nMultiColorPickerEditor.propTypes = {\n ...BaseEditorPropTypes,\n /**\n * Colors can be reordered manually\n */\n canReorderColors: T.bool,\n /**\n * Can add a new color\n */\n canAddNewColors: T.bool,\n /**\n * List of colors\n */\n value: T.arrayOf(T.string),\n /**\n * Title of the flyout editor\n */\n flyoutTitle: T.string,\n /**\n * Button label for adding a new color row\n */\n addColorButtonLabel: T.string,\n /**\n * Custom input editor for mapping a value to color, eg: dropdown for field -> color\n */\n CustomColorMatchEditor: T.func,\n /**\n * Flag to hide the editor label\n */\n hideLabel: T.bool,\n};\n\nexport default MultiColorPickerEditor;\n","import React, { useState, useCallback, useEffect, useMemo } from 'react';\nimport * as T from 'prop-types';\nimport { isEmpty } from 'lodash';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport { createDOMID } from '@splunk/ui-utils/id';\nimport Select from '@splunk/react-ui/Select';\nimport { Options } from '@splunk/visualization-encoding/Options';\nimport EncodingParser from '@splunk/visualization-encoding/EncodingParser';\nimport { getDataSourceStateInfo } from '@splunk/visualizations-shared/dataSourceUtils';\nimport MultiColorPickerEditor from './MultiColorPickerEditor';\nimport ControlGroup from '../shared/AdvancedControlGroup';\nimport { BaseEditorPropTypes } from '../interfaces/BaseEditorProps';\nimport type { BaseEditorProps } from '../interfaces/BaseEditorProps';\nimport { useDataSource } from '../hooks/useDataSource';\n\ntype ObjS = Record<string, string>;\ninterface FieldEditorProps {\n fields: string[];\n dsFields: string[];\n handleFieldChange: (args: { newFieldIndex: number; currFieldIndex: number }) => void;\n}\n\nconst FieldEditor = ({\n fields,\n dsFields,\n handleFieldChange,\n}: FieldEditorProps): (({ index }: { index: number }) => JSX.Element) => {\n const FieldSelector = ({ index }) => {\n const SelectOptions = useMemo(\n () =>\n dsFields.map((dsField, idx) => (\n <Select.Option\n label={dsField}\n value={idx}\n key={createDOMID()}\n data-test={`${dsField}-${index}`}\n />\n )),\n [index]\n );\n\n const handleChange = useCallback(\n (e, { value: newFieldIndex }): void => {\n handleFieldChange({ newFieldIndex, currFieldIndex: index });\n },\n [index]\n );\n\n const selectedField = dsFields.indexOf(fields[index]);\n\n return (\n <Select\n value={selectedField}\n onChange={handleChange}\n style={{ width: 190 }}\n data-test=\"field-select\"\n >\n {SelectOptions}\n </Select>\n );\n };\n FieldSelector.propTypes = {\n index: T.number,\n };\n return FieldSelector;\n};\n\nexport type SeriesColorsByFieldEditorProps = BaseEditorProps & { isCategorical?: boolean };\n\nconst defaultValue = {} as SeriesColorsByFieldEditorProps['value'];\nconst defaultOptions = {} as SeriesColorsByFieldEditorProps['options'];\nconst defaultOptionsSchema = {} as SeriesColorsByFieldEditorProps['optionsSchema'];\n\nconst SeriesColorsByFieldEditor = ({\n name,\n value = defaultValue,\n dataSourceBindings,\n onChange,\n options = defaultOptions,\n isCategorical = false,\n context,\n optionsSchema = defaultOptionsSchema,\n}: SeriesColorsByFieldEditorProps) => {\n const [colors, setColors] = useState<string[]>(Object.values(value));\n const [fields, setFields] = useState<string[]>(Object.keys(value));\n\n useEffect(() => {\n setColors(Object.values(value));\n setFields(Object.keys(value));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [JSON.stringify(value)]);\n\n // fetch the dataSource fields\n const dataSource = useDataSource({ dataSourceBindings, dataSourceKey: 'primary' });\n const { isLoading } = useMemo(() => getDataSourceStateInfo(dataSource), [dataSource]);\n\n // for bubble and scatter, we fallback on the 'category' option default in case it's not user defined\n const { category = optionsSchema?.category?.default } = options ?? {};\n\n const dsFields = useMemo(() => {\n if (isCategorical) {\n if (!category) {\n return [];\n }\n\n if (Array.isArray(category)) {\n return [...new Set(category.map(val => val?.toString()).filter(val => !isEmpty(val)))];\n }\n\n if (!isLoading && EncodingParser.isDslString(category)) {\n const results = Options.evaluate(\n { context, options: { ...options, category } },\n { primary: dataSource }\n );\n if (Array.isArray(results.category)) {\n return [\n ...new Set(results.category.map(val => val?.toString()).filter(val => !isEmpty(val))),\n ];\n }\n }\n\n return [];\n }\n return dataSource?.data?.fields.map(val => val.name) ?? [];\n }, [context, dataSource, isCategorical, options, category, isLoading]);\n\n const { editorLabel, flyoutTitle, addColorButtonLabel } = useMemo(\n () =>\n isCategorical\n ? {\n editorLabel: _('Series colors by category name'),\n flyoutTitle: _('Color by category name'),\n addColorButtonLabel: _('Add category'),\n }\n : {\n editorLabel: _('Series colors by field name'),\n flyoutTitle: _('Color by field name'),\n addColorButtonLabel: _('Add field'),\n },\n [isCategorical]\n );\n\n // create the mapping of fields -> colors\n const getUpdatedValue = ({ updatedColors, updatedFields }) => {\n const updatedValue: ObjS = {};\n updatedFields.forEach((field, idx) => {\n updatedValue[field] = updatedColors[idx];\n });\n return updatedValue;\n };\n\n const handleColorChange = useCallback(\n (_evt: null, _name: string, updatedColors: string[]): void => {\n // don't allow the user to add a new field row if all fields are mapped to a color\n if (updatedColors.length > dsFields.length) {\n return;\n }\n\n const updatedFields = fields;\n\n // new field row has been added\n if (updatedColors.length > colors.length) {\n const newField = dsFields.find(dsField => !fields.includes(dsField));\n updatedFields.push(newField);\n }\n\n // if a field row is removed, remove the field entry associated with that row\n if (updatedColors.length < colors.length) {\n const delRowIndex = colors.findIndex(color => !updatedColors.includes(color));\n updatedFields.splice(delRowIndex, 1);\n }\n\n onChange(null, name, getUpdatedValue({ updatedColors, updatedFields }));\n },\n [dsFields, onChange, name, fields, colors]\n );\n\n const handleFieldChange = useCallback(\n ({ newFieldIndex, currFieldIndex }: { newFieldIndex: number; currFieldIndex: number }): void => {\n // find if the selected field has already been set in a different field row\n const doesFieldExist = fields.includes(dsFields[newFieldIndex]);\n\n const updatedFields = fields;\n\n // fields have to be swapped\n if (doesFieldExist) {\n const existingFieldIndex = fields.indexOf(dsFields[newFieldIndex]);\n const currField = fields[currFieldIndex];\n updatedFields[currFieldIndex] = fields[existingFieldIndex];\n updatedFields[existingFieldIndex] = currField;\n } else {\n updatedFields[currFieldIndex] = dsFields[newFieldIndex]; // a new field has been selected and we don't need to swap fields\n }\n\n onChange(null, name, getUpdatedValue({ updatedColors: colors, updatedFields }));\n },\n [fields, dsFields, colors, name, onChange]\n );\n\n const CustomColorMatchEditor = useMemo(\n () => FieldEditor({ fields, dsFields, handleFieldChange }),\n [dsFields, fields, handleFieldChange]\n );\n\n return (\n <ControlGroup label={editorLabel} labelPosition=\"top\" data-test=\"SeriesColorsByFieldEditor\">\n <MultiColorPickerEditor\n value={colors}\n onChange={handleColorChange}\n name=\"series\"\n canReorderColors={false}\n flyoutTitle={flyoutTitle}\n addColorButtonLabel={addColorButtonLabel}\n CustomColorMatchEditor={CustomColorMatchEditor}\n isDisabled={dsFields.length < 1}\n canAddNewColors={fields.length < dsFields.length}\n />\n </ControlGroup>\n );\n};\n\nSeriesColorsByFieldEditor.propTypes = { ...BaseEditorPropTypes, isCategorical: T.bool };\n\nexport default SeriesColorsByFieldEditor;\n","import { useState, useEffect, useContext } from 'react';\nimport DataSourceContext, {\n type BindingsSnapshot,\n type DataSourceApi,\n} from '@splunk/visualization-context/DataSourceContext';\nimport { get, isFunction } from 'lodash';\n\ninterface UseDataSourceParams {\n dataSourceBindings: BindingsSnapshot;\n dataSourceKey: string;\n}\n// @TODO(pwied): use DataSource interface in return type (w/o dependency on @splunk/visualizations)\nexport const useDataSource = ({\n dataSourceBindings,\n dataSourceKey,\n}: UseDataSourceParams): BindingsSnapshot => {\n const dataSourceApi = useContext<DataSourceApi>(DataSourceContext);\n const [dataSource, setDataSource] = useState<BindingsSnapshot>();\n useEffect((): (() => void) => {\n if (!get(dataSourceBindings, dataSourceKey)) {\n setDataSource(null);\n return () => undefined;\n }\n const unsubscribe =\n isFunction(dataSourceApi.subscribe) &&\n dataSourceApi.subscribe(dataSourceKey, (snapshot): void => setDataSource(snapshot));\n return () => {\n if (unsubscribe) {\n unsubscribe();\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [dataSourceBindings]);\n return dataSource;\n};\n","import * as T from 'prop-types';\nimport type { JSONSchema7 } from 'json-schema';\n\nexport interface BaseEditorProps {\n name: string;\n value: any;\n onChange?: (...args: any[]) => void;\n label?: string; // @TODO(pwied): this should not live in editor props\n labelPosition?: 'top' | 'left'; // ^^^\n context?: Record<string, any>;\n labelWidth?: number;\n isAdvanced?: boolean;\n isDisabled?: boolean;\n dataSourceBindings?: Record<string, any>;\n options?: { [k: string]: any };\n optionsSchema?: {\n [key: string]: JSONSchema7;\n };\n}\n\nexport const BaseEditorPropTypes: Record<keyof BaseEditorProps, T.Validator<any>> = {\n name: T.string.isRequired,\n value: T.oneOfType([T.string, T.object, T.arrayOf(T.string)]),\n context: T.object,\n label: T.string,\n labelPosition: T.oneOf(['top', 'left']),\n labelWidth: T.number,\n onChange: T.func,\n isAdvanced: T.bool,\n isDisabled: T.bool,\n dataSourceBindings: T.object,\n options: T.object,\n optionsSchema: T.object,\n};\n","import React, { Children, cloneElement } from 'react';\nimport type { ReactElement } from 'react';\nimport * as T from 'prop-types';\nimport styled from 'styled-components';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport AdvancedConfigIcon from '@splunk/react-icons/SlidersDoubleHorizontal';\nimport { variables } from '@splunk/themes';\nimport Tooltip from '@splunk/react-ui/Tooltip';\nimport type { ButtonClickHandler, ButtonProps } from '@splunk/react-ui/Button';\nimport Button from '@splunk/react-ui/Button';\nimport SUIControlGroup from '@splunk/react-ui/ControlGroup';\nimport type { ControlGroupPropsBase } from '@splunk/react-ui/ControlGroup';\n\ninterface AdvancedControlGroupProps extends Omit<ControlGroupPropsBase, 'splunkTheme'> {\n 'data-test'?: string;\n style?: Record<string, string | number>;\n isAdvanced?: boolean;\n onClick?: React.MouseEventHandler<HTMLDivElement>;\n onAdvancedConfigButtonClick?: ButtonClickHandler;\n}\n\ninterface AdvancedConfigButtonProps {\n label?: string;\n onClick?: ButtonClickHandler;\n}\n\n// remove all surrounding margins. let parent add padding\nconst ControlGroupContainer = styled(SUIControlGroup)`\n margin-top: 0;\n padding: 0;\n // adjust bottom margin according to theme\n margin-bottom: ${variables.spacingMedium};\n width: 100%;\n\n // remove top margin of the first component in control group\n &:first-child {\n margin-top: 0;\n }\n\n // remove bottom margin of the last component in control group\n &:last-child {\n margin-bottom: 0;\n }\n // remove top padding on label of the first control group\n [data-test='label']:first-of-type {\n padding-top: 0;\n }\n`;\n\n// override tooltip to set desired config button style\nconst StyledToolTip = styled(Tooltip)`\n display: flex;\n > span {\n display: flex;\n width: 35px;\n }\n`;\n\nconst StyledAdvancedConfigButton = styled(Button)<ButtonProps>`\n color: ${variables.contentColorActive} !important;\n &:hover {\n background-color: ${variables.interactiveColorOverlayDrag} !important;\n }\n`;\n\nexport const AdvancedConfigButton = ({\n label = '',\n onClick,\n}: AdvancedConfigButtonProps): React.ReactElement => {\n return (\n <StyledToolTip\n data-test={`${label}-advanced-config-button-tooltip`}\n content={_('Advanced configurations')}\n >\n <StyledAdvancedConfigButton\n data-test={`${label}-advanced-config-button`}\n icon={<AdvancedConfigIcon data-test={`${label}-advanced-config-button-icon`} />}\n appearance=\"subtle\"\n onClick={onClick}\n />\n </StyledToolTip>\n );\n};\n\nconst AdvancedControlGroup = ({\n 'data-test': dataTest,\n children,\n isAdvanced = false,\n label,\n hideLabel,\n labelPosition,\n labelWidth,\n tooltip,\n help,\n style,\n error,\n controlsLayout,\n onClick,\n onAdvancedConfigButtonClick,\n}: AdvancedControlGroupProps): React.ReactElement => (\n <ControlGroupContainer\n data-test={dataTest ?? 'control-group'}\n label={label}\n hideLabel={hideLabel}\n labelPosition={labelPosition}\n labelWidth={labelWidth}\n tooltip={tooltip}\n help={help}\n error={error}\n style={style}\n onClick={onClick}\n controlsLayout={controlsLayout}\n >\n {isAdvanced\n ? Children.toArray(children)\n .filter(Boolean)\n .map(child =>\n cloneElement(child as ReactElement, {\n style: { flex: 1 },\n })\n )\n : children}\n {isAdvanced ? <AdvancedConfigButton label={label} onClick={onAdvancedConfigButtonClick} /> : null}\n </ControlGroupContainer>\n);\n\nAdvancedControlGroup.propTypes = {\n /**\n * Style overriding SUI ControlGroup\n */\n style: T.object,\n /**\n * Whether the current editor is enabled with advanced configurations\n */\n isAdvanced: T.bool,\n /**\n * Callback for editor click\n */\n onClick: T.func,\n /**\n * Callback for advanced config button click\n */\n onAdvancedConfigButtonClick: T.func,\n};\n\nexport default AdvancedControlGroup;\n","module.exports = require(\"@splunk/react-icons/SlidersDoubleHorizontal\");","module.exports = require(\"@splunk/react-ui/Button\");","module.exports = require(\"@splunk/react-ui/Color\");","module.exports = require(\"@splunk/react-ui/ControlGroup\");","module.exports = require(\"@splunk/react-ui/FormRows\");","module.exports = require(\"@splunk/react-ui/Popover\");","module.exports = require(\"@splunk/react-ui/Select\");","module.exports = require(\"@splunk/react-ui/Text\");","module.exports = require(\"@splunk/react-ui/Tooltip\");","module.exports = require(\"@splunk/themes\");","module.exports = require(\"@splunk/themes/variables\");","module.exports = require(\"@splunk/ui-utils/i18n\");","module.exports = require(\"@splunk/ui-utils/id\");","module.exports = require(\"@splunk/visualization-color-palettes\");","module.exports = require(\"@splunk/visualization-context/DataSourceContext\");","module.exports = require(\"@splunk/visualization-encoding/EncodingParser\");","module.exports = require(\"@splunk/visualization-encoding/Options\");","module.exports = require(\"@splunk/visualizations-shared/colorUtils\");","module.exports = require(\"@splunk/visualizations-shared/dataSourceUtils\");","module.exports = require(\"lodash\");","module.exports = require(\"prop-types\");","module.exports = require(\"react\");","module.exports = require(\"styled-components\");","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(7364);\n"],"names":["require","TextContainer","styled","variables","inputHeight","StyledText","Text","getColor","color","defaultColor","prevColor","newColor","trim","isColor","ColorAndTextWrapper","id","showTextInput","palette","handleColorChange","labelledBy","textWidth","value","name","handleTextColorChange","handleKeyPress","handleBlur","isDisabled","textLabelId","useMemo","createDOMID","React","Color","key","append","onChange","disabled","hideInput","ScreenReaderContent","_","prepend","onKeyDown","onBlur","style","height","inputId","propTypes","T","isRequired","defaultItemSchema","default","emptyStyle","ColorEditor","label","labelPosition","labelWidth","COLOR_EDITOR_PALETTE","noop","itemSchema","hideLabel","customEditorStyle","setColor","useState","useEffect","debouncedOnChange","debounce","useCallback","val","_event","colorToValue","toLower","event","ControlGroup","controlsLayout","popoverStyle","padding","colorButtonStyle","width","StyledButton","interactiveColorBackground","ColorChip","div","props","neutral100","StyledFlyoutContent","backgroundColorPopup","FlyoutHeader","fontFamily","contentColorActive","ColorListEditor","ColorFlyoutEditor","colors","CustomColorMatchEditor","handleColorRemove","flyoutTitle","addColorButtonLabel","handleColorAdd","handleColorMove","ColorRowItems","map","idx","Row","index","onRequestRemove","display","justifyContent","marginBottom","marginTop","addLabel","onRequestAdd","onRequestMove","MultiColorPickerEditor","canReorderColors","vizColors","VIZ_CATEGORICAL","canAddNewColors","showFlyout","setShowFlyout","setColors","buttonRef","useRef","userColorsSet","Set","nextColor","find","has","countMap","Map","forEach","set","get","minCount","Infinity","count","_evt","_name","colorsCopy","splice","e","fromIndex","toIndex","movedColor","handleFlyoutClose","reason","srcElement","sortableHandle","current","focus","ColorChips","toggleShowFlyout","isShown","inline","appearance","ref","onClick","open","anchor","defaultPlacement","onRequestClose","takeFocus","undefined","BaseEditorPropTypes","bool","arrayOf","string","func","defaultValue","defaultOptions","defaultOptionsSchema","SeriesColorsByFieldEditor","dataSourceBindings","options","isCategorical","context","optionsSchema","Object","values","fields","setFields","keys","JSON","stringify","dataSource","useDataSource","dataSourceKey","isLoading","getDataSourceStateInfo","category","dsFields","Array","isArray","toString","filter","isEmpty","isDslString","results","Options","evaluate","primary","data","editorLabel","getUpdatedValue","updatedColors","updatedFields","updatedValue","field","length","newField","dsField","includes","push","delRowIndex","findIndex","handleFieldChange","newFieldIndex","currFieldIndex","doesFieldExist","existingFieldIndex","indexOf","currField","FieldSelector","SelectOptions","Option","handleChange","selectedField","number","FieldEditor","dataSourceApi","useContext","setDataSource","unsubscribe","isFunction","subscribe","snapshot","oneOfType","object","oneOf","isAdvanced","ControlGroupContainer","spacingMedium","StyledToolTip","StyledAdvancedConfigButton","interactiveColorOverlayDrag","AdvancedConfigButton","content","icon","AdvancedControlGroup","dataTest","children","tooltip","help","error","onAdvancedConfigButtonClick","Children","toArray","Boolean","child","cloneElement","flex","module","exports","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","call","n","getter","__esModule","d","a","definition","o","defineProperty","enumerable","obj","prop","prototype","hasOwnProperty","r","Symbol","toStringTag","__webpack_exports__"],"sourceRoot":""}