"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getEditableValue = exports.Field = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _eui = require("@elastic/eui");
var _i18n = require("@kbn/i18n");
var _i18nReact = require("@kbn/i18n-react");
var _field_code_editor = require("./field_code_editor");
var _lib = require("../../lib");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0 and the Server Side Public License, v 1; you may not use this file except
 * in compliance with, at your election, the Elastic License 2.0 or the Server
 * Side Public License, v 1.
 */

const getEditableValue = (type, value, defVal) => {
  const val = value === null || value === undefined ? defVal : value;
  switch (type) {
    case 'array':
      return val.join(', ');
    case 'boolean':
      return !!val;
    case 'number':
      return Number(val);
    case 'image':
      return val;
    default:
      return val || '';
  }
};
exports.getEditableValue = getEditableValue;
class Field extends _react.PureComponent {
  constructor(...args) {
    super(...args);
    (0, _defineProperty2.default)(this, "changeImageForm", /*#__PURE__*/_react.default.createRef());
    (0, _defineProperty2.default)(this, "handleChange", unsavedChanges => {
      this.props.handleChange(this.props.setting.name, unsavedChanges);
    });
    (0, _defineProperty2.default)(this, "resetField", () => {
      const {
        type,
        defVal
      } = this.props.setting;
      if (type === 'image') {
        this.cancelChangeImage();
        return this.handleChange({
          value: getEditableValue(type, defVal, defVal),
          changeImage: true
        });
      }
      return this.handleChange({
        value: getEditableValue(type, defVal)
      });
    });
    (0, _defineProperty2.default)(this, "onCodeEditorChange", value => {
      const {
        defVal,
        type
      } = this.props.setting;
      let newUnsavedValue;
      let errorParams = {};
      switch (type) {
        case 'json':
          const isJsonArray = Array.isArray(JSON.parse(defVal || '{}'));
          newUnsavedValue = value || (isJsonArray ? '[]' : '{}');
          try {
            JSON.parse(newUnsavedValue);
          } catch (e) {
            errorParams = {
              error: _i18n.i18n.translate('advancedSettings.field.codeEditorSyntaxErrorMessage', {
                defaultMessage: 'Invalid JSON syntax'
              }),
              isInvalid: true
            };
          }
          break;
        default:
          newUnsavedValue = value;
      }
      this.handleChange({
        value: newUnsavedValue,
        ...errorParams
      });
    });
    (0, _defineProperty2.default)(this, "onFieldChangeSwitch", e => {
      return this.onFieldChange(e.target.checked);
    });
    (0, _defineProperty2.default)(this, "onFieldChangeEvent", e => this.onFieldChange(e.target.value));
    (0, _defineProperty2.default)(this, "onFieldChange", targetValue => {
      const {
        type,
        value,
        defVal,
        options
      } = this.props.setting;
      let newUnsavedValue;
      switch (type) {
        case 'boolean':
          const {
            unsavedChanges
          } = this.props;
          const currentValue = unsavedChanges ? unsavedChanges.value : getEditableValue(type, value, defVal);
          newUnsavedValue = !currentValue;
          break;
        case 'number':
          newUnsavedValue = Number(targetValue);
          break;
        case 'select':
          if (typeof (options === null || options === void 0 ? void 0 : options[0]) === 'number') {
            newUnsavedValue = Number(targetValue);
          } else {
            newUnsavedValue = targetValue;
          }
          break;
        default:
          newUnsavedValue = targetValue;
      }
      this.handleChange({
        value: newUnsavedValue
      });
    });
    (0, _defineProperty2.default)(this, "onImageChange", async files => {
      if (files == null) return;
      if (!files.length) {
        this.setState({
          unsavedValue: null
        });
        return;
      }
      const file = files[0];
      try {
        let base64Image = '';
        if (file instanceof File) {
          base64Image = await this.getImageAsBase64(file);
        }
        this.handleChange({
          changeImage: true,
          value: base64Image
        });
      } catch (err) {
        this.props.toasts.addDanger(_i18n.i18n.translate('advancedSettings.field.imageChangeErrorMessage', {
          defaultMessage: 'Image could not be saved'
        }));
        this.cancelChangeImage();
      }
    });
    (0, _defineProperty2.default)(this, "changeImage", () => {
      this.handleChange({
        value: null,
        changeImage: true
      });
    });
    (0, _defineProperty2.default)(this, "cancelChangeImage", () => {
      var _this$changeImageForm;
      if ((_this$changeImageForm = this.changeImageForm.current) !== null && _this$changeImageForm !== void 0 && _this$changeImageForm.fileInput) {
        this.changeImageForm.current.fileInput.value = '';
        this.changeImageForm.current.handleChange();
      }
      if (this.props.clearChange) {
        this.props.clearChange(this.props.setting.name);
      }
    });
  }
  getDisplayedDefaultValue(type, defVal, optionLabels = {}) {
    if (defVal === undefined || defVal === null || defVal === '') {
      return 'null';
    }
    switch (type) {
      case 'array':
        return defVal.join(', ');
      case 'select':
        return optionLabels.hasOwnProperty(String(defVal)) ? optionLabels[String(defVal)] : String(defVal);
      default:
        return String(defVal);
    }
  }
  componentDidUpdate(prevProps) {
    var _prevProps$unsavedCha, _this$props$unsavedCh;
    if (prevProps.setting.type === 'image' && (_prevProps$unsavedCha = prevProps.unsavedChanges) !== null && _prevProps$unsavedCha !== void 0 && _prevProps$unsavedCha.value && !((_this$props$unsavedCh = this.props.unsavedChanges) !== null && _this$props$unsavedCh !== void 0 && _this$props$unsavedCh.value)) {
      this.cancelChangeImage();
    }
  }
  async getImageAsBase64(file) {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    return new Promise((resolve, reject) => {
      reader.onload = () => {
        resolve(reader.result);
      };
      reader.onerror = err => {
        reject(err);
      };
    });
  }
  renderField(setting, ariaDescribedBy) {
    const {
      enableSaving,
      unsavedChanges,
      loading
    } = this.props;
    const {
      name,
      value,
      type,
      options,
      optionLabels = {},
      isOverridden,
      defVal,
      ariaName
    } = setting;
    const a11yProps = ariaDescribedBy ? {
      'aria-label': ariaName,
      'aria-describedby': ariaDescribedBy
    } : {
      'aria-label': ariaName
    };
    const currentValue = unsavedChanges ? unsavedChanges.value : getEditableValue(type, value, defVal);
    switch (type) {
      case 'boolean':
        return /*#__PURE__*/_react.default.createElement(_eui.EuiSwitch, (0, _extends2.default)({
          label: !!currentValue ? /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
            id: "advancedSettings.field.onLabel",
            defaultMessage: "On"
          }) : /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
            id: "advancedSettings.field.offLabel",
            defaultMessage: "Off"
          }),
          checked: !!currentValue,
          onChange: this.onFieldChangeSwitch,
          disabled: loading || isOverridden || !enableSaving,
          "data-test-subj": `advancedSetting-editField-${name}`
        }, a11yProps));
      case 'markdown':
      case 'json':
        return /*#__PURE__*/_react.default.createElement("div", {
          "data-test-subj": `advancedSetting-editField-${name}`
        }, /*#__PURE__*/_react.default.createElement(_field_code_editor.FieldCodeEditor, {
          value: currentValue,
          onChange: this.onCodeEditorChange,
          type: type,
          isReadOnly: isOverridden || !enableSaving,
          a11yProps: a11yProps,
          name: `advancedSetting-editField-${name}-editor`
        }));
      case 'image':
        const changeImage = unsavedChanges === null || unsavedChanges === void 0 ? void 0 : unsavedChanges.changeImage;
        if (!(0, _lib.isDefaultValue)(setting) && !changeImage) {
          return /*#__PURE__*/_react.default.createElement(_eui.EuiImage, (0, _extends2.default)({}, a11yProps, {
            allowFullScreen: true,
            url: value,
            alt: name
          }));
        } else {
          return /*#__PURE__*/_react.default.createElement(_eui.EuiFilePicker, {
            disabled: loading || isOverridden || !enableSaving,
            onChange: this.onImageChange,
            accept: ".jpg,.jpeg,.png",
            ref: this.changeImageForm,
            fullWidth: true,
            "data-test-subj": `advancedSetting-editField-${name}`,
            "aria-label": name
          });
        }
      case 'select':
        return /*#__PURE__*/_react.default.createElement(_eui.EuiSelect, (0, _extends2.default)({}, a11yProps, {
          value: currentValue,
          options: options.map(option => {
            return {
              text: optionLabels.hasOwnProperty(option) ? optionLabels[option] : option,
              value: option
            };
          }),
          onChange: this.onFieldChangeEvent,
          isLoading: loading,
          disabled: loading || isOverridden || !enableSaving,
          fullWidth: true,
          "data-test-subj": `advancedSetting-editField-${name}`
        }));
      case 'number':
        return /*#__PURE__*/_react.default.createElement(_eui.EuiFieldNumber, (0, _extends2.default)({}, a11yProps, {
          value: currentValue,
          onChange: this.onFieldChangeEvent,
          isLoading: loading,
          disabled: loading || isOverridden || !enableSaving,
          fullWidth: true,
          "data-test-subj": `advancedSetting-editField-${name}`
        }));
      case 'color':
        return /*#__PURE__*/_react.default.createElement(_eui.EuiColorPicker, (0, _extends2.default)({}, a11yProps, {
          color: currentValue,
          onChange: this.onFieldChange,
          disabled: loading || isOverridden || !enableSaving,
          format: "hex",
          "data-test-subj": `advancedSetting-editField-${name}`
        }));
      default:
        return /*#__PURE__*/_react.default.createElement(_eui.EuiFieldText, (0, _extends2.default)({}, a11yProps, {
          value: currentValue,
          onChange: this.onFieldChangeEvent,
          isLoading: loading,
          disabled: loading || isOverridden || !enableSaving,
          fullWidth: true,
          "data-test-subj": `advancedSetting-editField-${name}`
        }));
    }
  }
  renderLabel(setting) {
    return setting.name;
  }
  renderHelpText(setting) {
    if (setting.isOverridden) {
      return /*#__PURE__*/_react.default.createElement(_eui.EuiText, {
        size: "xs"
      }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
        id: "advancedSettings.field.helpText",
        defaultMessage: "This setting is overridden by the Kibana server and can not be changed."
      }));
    }
    const canUpdateSetting = this.props.enableSaving;
    const defaultLink = this.renderResetToDefaultLink(setting);
    const imageLink = this.renderChangeImageLink(setting);
    if (canUpdateSetting && (defaultLink || imageLink)) {
      return /*#__PURE__*/_react.default.createElement("span", null, defaultLink, imageLink);
    }
    return null;
  }
  renderTitle(setting) {
    const {
      unsavedChanges
    } = this.props;
    const isInvalid = unsavedChanges === null || unsavedChanges === void 0 ? void 0 : unsavedChanges.isInvalid;
    const unsavedIconLabel = unsavedChanges ? isInvalid ? _i18n.i18n.translate('advancedSettings.field.invalidIconLabel', {
      defaultMessage: 'Invalid'
    }) : _i18n.i18n.translate('advancedSettings.field.unsavedIconLabel', {
      defaultMessage: 'Unsaved'
    }) : undefined;
    return /*#__PURE__*/_react.default.createElement("h3", null, /*#__PURE__*/_react.default.createElement("span", {
      className: "mgtAdvancedSettings__fieldTitle"
    }, setting.displayName || setting.name), setting.isCustom ? /*#__PURE__*/_react.default.createElement(_eui.EuiIconTip, {
      type: "asterisk",
      color: "primary",
      "aria-label": _i18n.i18n.translate('advancedSettings.field.customSettingAriaLabel', {
        defaultMessage: 'Custom setting'
      }),
      content: /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
        id: "advancedSettings.field.customSettingTooltip",
        defaultMessage: "Custom setting"
      })
    }) : '', unsavedChanges ? /*#__PURE__*/_react.default.createElement(_eui.EuiIconTip, {
      anchorClassName: "mgtAdvancedSettings__fieldTitleUnsavedIcon",
      type: isInvalid ? 'warning' : 'dot',
      color: isInvalid ? 'danger' : 'warning',
      "aria-label": unsavedIconLabel,
      content: unsavedIconLabel
    }) : '');
  }
  renderDescription(setting) {
    let description;
    let deprecation;
    if (setting.deprecation) {
      const links = this.props.docLinks;
      deprecation = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiToolTip, {
        content: setting.deprecation.message
      }, /*#__PURE__*/_react.default.createElement(_eui.EuiBadge, {
        color: "warning",
        onClick: () => {
          window.open(links.management[setting.deprecation.docLinksKey], '_blank');
        },
        onClickAriaLabel: _i18n.i18n.translate('advancedSettings.field.deprecationClickAreaLabel', {
          defaultMessage: 'Click to view deprecation documentation for {settingName}.',
          values: {
            settingName: setting.name
          }
        })
      }, "Deprecated")), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, {
        size: "s"
      }));
    }
    if ( /*#__PURE__*/_react.default.isValidElement(setting.description)) {
      description = setting.description;
    } else {
      description = /*#__PURE__*/_react.default.createElement("div", {
        /*
         * Justification for dangerouslySetInnerHTML:
         * Setting description may contain formatting and links to documentation.
         */
        dangerouslySetInnerHTML: {
          __html: setting.description || ''
        } // eslint-disable-line react/no-danger
      });
    }

    return /*#__PURE__*/_react.default.createElement(_react.Fragment, null, deprecation, description, this.renderDefaultValue(setting));
  }
  renderDefaultValue(setting) {
    const {
      type,
      defVal,
      optionLabels
    } = setting;
    if ((0, _lib.isDefaultValue)(setting)) {
      return;
    }
    return /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, {
      size: "s"
    }), /*#__PURE__*/_react.default.createElement(_eui.EuiText, {
      size: "xs"
    }, type === 'json' ? /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
      id: "advancedSettings.field.defaultValueTypeJsonText",
      defaultMessage: "Default: {value}",
      values: {
        value: /*#__PURE__*/_react.default.createElement(_eui.EuiCodeBlock, {
          language: "json",
          paddingSize: "s",
          overflowHeight: defVal.length >= 500 ? 300 : undefined
        }, this.getDisplayedDefaultValue(type, defVal))
      }
    })) : /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
      id: "advancedSettings.field.defaultValueText",
      defaultMessage: "Default: {value}",
      values: {
        value: /*#__PURE__*/_react.default.createElement(_eui.EuiCode, null, this.getDisplayedDefaultValue(type, defVal, optionLabels))
      }
    }))));
  }
  renderResetToDefaultLink(setting) {
    var _this$props$unsavedCh2;
    const {
      defVal,
      ariaName,
      name
    } = setting;
    if (defVal === ((_this$props$unsavedCh2 = this.props.unsavedChanges) === null || _this$props$unsavedCh2 === void 0 ? void 0 : _this$props$unsavedCh2.value) || (0, _lib.isDefaultValue)(setting) || this.props.loading) {
      return;
    }
    return /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_eui.EuiLink, {
      "aria-label": _i18n.i18n.translate('advancedSettings.field.resetToDefaultLinkAriaLabel', {
        defaultMessage: 'Reset {ariaName} to default',
        values: {
          ariaName
        }
      }),
      onClick: this.resetField,
      "data-test-subj": `advancedSetting-resetField-${name}`
    }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
      id: "advancedSettings.field.resetToDefaultLinkText",
      defaultMessage: "Reset to default"
    })), "\xA0\xA0\xA0");
  }
  renderChangeImageLink(setting) {
    var _this$props$unsavedCh3;
    const changeImage = (_this$props$unsavedCh3 = this.props.unsavedChanges) === null || _this$props$unsavedCh3 === void 0 ? void 0 : _this$props$unsavedCh3.changeImage;
    const {
      type,
      value,
      ariaName,
      name
    } = setting;
    if (type !== 'image' || !value || changeImage) {
      return;
    }
    return /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_eui.EuiLink, {
      "aria-label": _i18n.i18n.translate('advancedSettings.field.changeImageLinkAriaLabel', {
        defaultMessage: 'Change {ariaName}',
        values: {
          ariaName
        }
      }),
      onClick: this.changeImage,
      "data-test-subj": `advancedSetting-changeImage-${name}`
    }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
      id: "advancedSettings.field.changeImageLinkText",
      defaultMessage: "Change image"
    })));
  }
  render() {
    const {
      setting,
      unsavedChanges
    } = this.props;
    const error = unsavedChanges === null || unsavedChanges === void 0 ? void 0 : unsavedChanges.error;
    const isInvalid = unsavedChanges === null || unsavedChanges === void 0 ? void 0 : unsavedChanges.isInvalid;
    const className = (0, _classnames.default)('mgtAdvancedSettings__field', {
      'mgtAdvancedSettings__field--unsaved': unsavedChanges,
      'mgtAdvancedSettings__field--invalid': isInvalid
    });
    const groupId = `${setting.name}-group`;
    const unsavedId = `${setting.name}-unsaved`;
    return /*#__PURE__*/_react.default.createElement(_eui.EuiDescribedFormGroup, {
      id: groupId,
      className: className,
      title: this.renderTitle(setting),
      description: this.renderDescription(setting),
      fullWidth: true
    }, /*#__PURE__*/_react.default.createElement(_eui.EuiFormRow, {
      isInvalid: isInvalid,
      error: error,
      label: this.renderLabel(setting),
      helpText: this.renderHelpText(setting),
      className: "mgtAdvancedSettings__fieldRow",
      hasChildLabel: setting.type !== 'boolean',
      fullWidth: true
    }, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, this.renderField(setting, unsavedChanges ? `${groupId} ${unsavedId}` : undefined), unsavedChanges && /*#__PURE__*/_react.default.createElement(_eui.EuiScreenReaderOnly, null, /*#__PURE__*/_react.default.createElement("p", {
      id: `${unsavedId}`
    }, unsavedChanges.error ? unsavedChanges.error : _i18n.i18n.translate('advancedSettings.field.settingIsUnsaved', {
      defaultMessage: 'Setting is currently not saved.'
    }))))));
  }
}
exports.Field = Field;