'use strict';var normalizeComponent=require('./normalize-component-d9981c57.js'),_typeof=require('./typeof-6b9e62b8.js'),objectSpread2=require('./objectSpread2-56f1d323.js');require('./es.object.to-string-f27a75a8.js'),require('./es.object.values-1f44a4ee.js'),require('./es.object.keys-c57f02bd.js'),require('./es.array.includes-3990bfec.js'),require('./es.array.filter-6fabfac0.js'),require('./es.array.sort-7d68b195.js'),require('./es.array.map-4cfed4ef.js'),require('./es.json.stringify-f88f52bf.js'),require('./es.array.concat-bb8715dc.js'),require('./web.dom-collections.for-each-c07b0e22.js'),require('./es.regexp.to-string-5606f728.js'),require('./es.string.includes-ec03e639.js');var BaseIcon=require('./BaseIcon-1ed3bf6e.js'),i18n=require('./i18n-68e039d3.js');require('./classof-819fc780.js'),require('./export-61511812.js'),require('./object-keys-12f2c5e5.js'),require('./array-iteration-f8b4483d.js'),require('./function-bind-context-e4685306.js'),require('./array-species-create-c414c2ec.js'),require('./array-method-has-species-support-983ac207.js'),require('./create-property-240c71a5.js'),require('./array-method-is-strict-99341ee3.js'),require('./dom-iterables-e2602b7e.js'),require('./regexp-flags-abc49c4a.js'),require('./is-regexp-d6f1551e.js'),require('./es.array.join-88750c41.js'),require('./regexp-exec-abstract-216cd44a.js'),require('./string-multibyte-a2dff6e3.js'),require('./es.string.split-98e29ede.js');/**
 * Component creating a form according to a provided [openAPI](https://www.openapis.org/) standard
 */

var script = {
  name: 'BaseForm',
  components: {
    BaseFormFieldCreator: function BaseFormFieldCreator() {
      return Promise.resolve().then(function(){return require('./BaseFormFieldCreator-fa95f2be.js')});
    },
    BaseIcon: BaseIcon["default"]
  },
  mixins: [i18n.i],
  props: {
    /**
     * the json object containing all the field information incl. x-attributes
     * for placeholder, field type, etc.
     */
    formFieldJson: {
      type: Object,
      required: true
    },

    /**
     * the values for each field if any already present
     */
    valueList: {
      type: Object,
      default: function _default() {
        return {};
      }
    },

    /**
     * set current language
     */
    language: {
      type: String,
      default: 'en'
    },

    /**
     * provide information about all available languages
     */
    availableLocales: {
      type: Array,
      default: function _default() {
        return [];
      }
    },

    /**
     * an id for field groups to still have unique field ids
     */
    formId: {
      type: String,
      default: ''
    },

    /**
     * define additional style for the form
     * should be an object eg. { 'padding-top': 0 }
     */
    formStyle: {
      type: Object,
      default: function _default() {
        return {};
      }
    },

    /**
     * define fields (specify field name!) for which tabs should be shown
     */
    fieldsWithTabs: {
      type: Array,
      default: function _default() {
        return [];
      }
    },

    /**
     * enter the field name of a field that is currently fetching autocomplete
     * results
     */
    fieldIsLoading: {
      type: String,
      default: ''
    },

    /**
     * provide a object that contains the options list for all
     * fields with autocomplete / chips input
     */
    dropDownLists: {
      type: Object,
      default: function _default() {
        return {};
      }
    },

    /**
     * define if error icon should be shown<br>
     * for an example on how it looks on an individual form field see [BaseInput](#baseinput)
     */
    showErrorIcon: {
      type: Boolean,
      default: false
    },

    /**
     * if true a remove icon will be shown allowing to remove
     * all input at once<br>
     * for an example on how it looks on an individual form field see [BaseInput](#baseinput)
     */
    clearable: {
      type: Boolean,
      default: false
    },

    /**
     * provide an object with settings and properties for each field, this is used to set
     * `required`, `invalid`, `errorMessage` for each field this is applicable to<br>
     * for an example on how these properties look on an individual form field
     * see [BaseInput](#baseinput)
     */
    fieldProps: {
      type: Object,
      default: function _default() {
        return {
          required: false,
          invalid: false,
          errorMessage: ''
        };
      },
      validator: function validator(val) {
        return Object.values(val).every(function (fieldProps) {
          return Object.keys(fieldProps).every(function (fieldProp) {
            return ['required', 'invalid', 'errorMessage'].includes(fieldProp);
          });
        });
      }
    }
  },
  data: function data() {
    return {
      /**
       * variable to be able to focus to the field after multipy
       * @type {?Object}
       * @property {number} index - the index of the new field in the array
       * @property {string} name - the name of the field
       */
      multiplyParams: null,

      /**
       * remember the field for which autocomplete is fetching
       * @type {string}
       */
      fetchingAutocompleteFor: '',

      /**
       * variable saving the current field input string during
       * autocomplete functionality
       * @type {string}
       */
      currentInputString: '',

      /**
       * internal representation of valueList (containing values for all input fields)
       * @type {Object}
       * @property {?string|?Array|?Object} [the name of the input field]
       */
      valueListInt: {}
    };
  },
  computed: {
    /**
     * get a list of all form fields that are taking half of the
     * width of a form
     * @returns {Object[]}
     */
    formFieldsHalf: function formFieldsHalf() {
      return this.formFieldListInt.filter(function (field) {
        return field['x-attrs'] && field['x-attrs'].field_format === 'half';
      });
    },

    /**
     * internal form field list, sorted and with additional name property to save
     * the name of the input field in a variable, also filtered from fields that
     * should not be shown
     *
     * @returns {Object[]}
     * @property {string} name - the name of the input field
     * @property {*} [*] all other properties contained in the swagger
     */
    formFieldListInt: function formFieldListInt() {
      var _this = this;

      return Object.keys(this.formFieldJson) // filter out hidden properties and $ref property from JSON
      .filter(function (key) {
        return !_this.formFieldJson[key].$ref && !(_this.formFieldJson[key]['x-attrs'] && _this.formFieldJson[key]['x-attrs'].hidden);
      }).map(function (key) {
        return objectSpread2.a(objectSpread2.a({}, {
          name: key
        }), _this.formFieldJson[key]);
      }) // sort the fields according to their x-attribute (order)
      .sort(function (a, b) {
        if (a['x-attrs'] && b['x-attrs']) {
          if (a['x-attrs'].order > b['x-attrs'].order) {
            return 1;
          }

          return -1;
        }

        return -1;
      });
    }
  },
  watch: {
    valueList: {
      handler: function handler(val) {
        var _this2 = this;

        var changedValues = Object.keys(this.valueListInt).some(function (key) {
          return JSON.stringify(_this2.valueListInt[key]) !== JSON.stringify(val[key]);
        });

        if (changedValues) {
          this.initializeValueObject();
        }
      },
      deep: true
    },
    formFieldJson: {
      handler: function handler() {
        // if new field specifications were set - also reset the properties of the value object
        this.valueListInt = {}; // initialize value object with new properties

        this.initializeValueObject();
      },
      immediate: true
    }
  },
  updated: function updated() {
    if (this.multiplyParams && this.multiplyParams.name) {
      var elements = this.$refs[this.multiplyParams.name];

      if (elements.length) {
        // this seems like a stupid hack however had to do this because if 'getElementsByTagName'
        // was evaluated immediately it came back empty for 'textarea' since for some reason
        // this was not in the DOM tree yet... (no problems for input fields / subforms tho)
        setTimeout(function (params) {
          var inputs = elements[params.index].getElementsByTagName('textarea').length ? elements[params.index].getElementsByTagName('textarea') : elements[params.index].getElementsByTagName('input');

          if (inputs.length) {
            inputs[0].focus();
          }
        }, 50, this.multiplyParams);
      }

      this.multiplyParams = null;
    }
  },
  methods: {
    fetchAutocomplete: function fetchAutocomplete(params) {
      this.currentInputString = params.value;
      this.fetchingAutocompleteFor = params.name;
      /**
       * triggered if field has an autocomplete functionality
       * (chips-input, autocomplete-input, chips-below-input)
       *
       * @event fetch-autocomplete
       *
       * @param {Object} params - the spread object with following properties
       * @property {string} value - the string to autocomplete
       * @property {string} name - the name of the field
       * @property {string} source - the url to request the data from
       * @property {?string} equivalent - string specified for related fields
       * e.g. for contributor roles equivalent is 'contributor'
       */

      this.$emit('fetch-autocomplete', params);
    },
    // check if field can be multiplied
    allowMultiply: function allowMultiply(el) {
      // field can be multiplied if it is an array and not a chips or chips-below
      // field
      return el.type === 'array' && el['x-attrs'] && !['chips', 'chips-below'].includes(el['x-attrs'].field_type);
    },
    // triggered on user clicking multiply button
    multiplyField: function multiplyField(field) {
      this.valueListInt[field.name].push(this.getInitialFieldValue(field.items));
      this.multiplyParams = {
        index: this.valueListInt[field.name].length - 1,
        name: field.name
      }; // inform parent of changes

      this.propagateValueListChanges();
    },
    // remove multiplied field again
    removeField: function removeField(field, index) {
      var fieldGroupValues = this.valueListInt[field.name]; // only splice off group if more than one field visible

      if (fieldGroupValues && fieldGroupValues.length > 1) {
        fieldGroupValues.splice(index, 1); // else just clear the fields
      } else {
        this.$set(fieldGroupValues, index, this.getInitialFieldValue(field.items));
      } // inform parent of changes


      this.propagateValueListChanges();
    },
    propagateValueListChanges: function propagateValueListChanges() {
      /**
       * event triggered when the values of a field were altered or a form
       * field was added or removed
       *
       * @event values-changed
       * @param {Object[]} valueListInt
       */
      this.$emit('values-changed', this.valueListInt);
    },
    // check if field is half field and the second of two halves
    isHalfFieldSecond: function isHalfFieldSecond(field) {
      var index = this.formFieldsHalf.indexOf(field);
      return index > 0 && !!(index % 2);
    },
    getFieldName: function getFieldName(val) {
      return val.title || this.getI18nTerm("form.".concat(val.name) || val.name);
    },
    formFieldComponentProps: function formFieldComponentProps(element, index, valueIndex) {
      var comboIndex = valueIndex >= 0 ? "".concat(index, "_").concat(valueIndex) : index;
      var elementProps = this.fieldProps[element.name];
      return {
        field: element,
        label: this.getFieldName(element),
        dropDownList: this.dropDownLists[element.name],
        secondaryDropdown: this.dropDownLists["".concat(element.name, "_secondary")],
        language: this.language,
        availableLocales: this.availableLocales,
        sortText: this.getI18nTerm('form.sort') || 'Sort',
        fieldKey: "".concat(element.name, "_").concat(comboIndex, "_").concat(this.formId),
        fieldValue: valueIndex >= 0 ? this.valueListInt[element.name][valueIndex] : this.valueListInt[element.name],
        autocompleteLoading: this.fieldIsLoading === element.name,
        // add component props to form fields creator props if list contains a field_type 'group'
        fieldGroupParams: this.formFieldListInt.some(function (field) {
          return field['x-attrs'] && field['x-attrs'].field_type === 'group';
        }) ? this.$props : null,
        clearable: this.clearable,
        showErrorIcon: this.showErrorIcon,
        required: elementProps ? elementProps.required : false,
        errorMessage: elementProps ? elementProps.errorMessage : '',
        invalid: elementProps ? elementProps.invalid : false
      };
    },
    setFieldValue: function setFieldValue(value, fieldName, index) {
      this.currentInputString = '';

      if (index >= 0) {
        this.$set(this.valueListInt[fieldName], index, JSON.parse(JSON.stringify(value)));
      } else {
        this.$set(this.valueListInt, fieldName, value ? JSON.parse(JSON.stringify(value)) : value);
      }

      this.$emit('values-changed', this.valueListInt);
    },
    initializeValueObject: function initializeValueObject() {
      var _this3 = this;

      this.formFieldListInt.forEach(function (field) {
        _this3.$set(_this3.valueListInt, field.name, _this3.getInitialFieldValue(field));
      });
    },
    getInitialFieldValue: function getInitialFieldValue(field) {
      var _this4 = this;

      var value = this.valueList[field.name];

      if (field.type === 'integer') {
        return value ? value.toString() : '';
      } // check special case single-choice chips (is chips but is saved as
      // (multilang) object on backend)


      if (field['x-attrs'] && field['x-attrs'].field_type && field['x-attrs'].field_type.includes('chips') && field.type === 'object') {
        if (value && Object.keys(value).length) {
          return [].concat(value);
        }

        return [];
      } // check if field is array


      if (field.type === 'array') {
        // check if values are already present and set those if yes
        if (_typeof._(value) === 'object' && value && value.length) {
          return [].concat(value);
        }

        if (field['x-attrs'] && field['x-attrs'].field_type && !field['x-attrs'].field_type.includes('chips') && field.items.type === 'object') {
          return [].concat(this.getInitialFieldValue(field.items));
        } // else return empty array


        return []; // check if field is object
      }

      if (field.type === 'object') {
        var initObj = {}; // for each property in the object also get initial values

        Object.keys(field.properties).forEach(function (key) {
          _this4.$set(initObj, key, _this4.getInitialFieldValue(field.properties[key]));
        });
        return objectSpread2.a(objectSpread2.a({}, initObj), value);
      } // check if field is boolean


      if (field.type === 'boolean') {
        return value;
      } // if it is not a array or object simply return value from list or empty string


      return typeof value === 'string' ? value : '';
    },
    checkFieldContent: function checkFieldContent(fieldValues) {
      var _this5 = this;

      var hasContent = false;

      if (fieldValues && _typeof._(fieldValues) === 'object') {
        if (fieldValues.length >= 0) {
          fieldValues.forEach(function (values) {
            hasContent = _this5.checkFieldContent(values) || hasContent;
          });
        } else {
          var objectKeys = Object.keys(fieldValues);
          objectKeys.forEach(function (key) {
            hasContent = _this5.checkFieldContent(fieldValues[key]) || hasContent;
          });
        }
      } else {
        hasContent = fieldValues === 0 || !!fieldValues || hasContent;
      }

      return hasContent;
    }
  }
};var __vue_script__ = script;
/* template */

var __vue_render__ = function __vue_render__() {
  var _vm = this;

  var _h = _vm.$createElement;

  var _c = _vm._self._c || _h;

  return _c('div', {
    staticClass: "base-form",
    style: _vm.formStyle
  }, [_vm._l(_vm.formFieldListInt, function (element, index) {
    return [!_vm.allowMultiply(element) ? _c('BaseFormFieldCreator', _vm._b({
      key: element.name + "_" + index + "_" + _vm.formId,
      class: ['base-form-field', _vm.formFieldsHalf.indexOf(element) >= 0 ? 'base-form-field-half' : 'base-form-field-full', {
        'base-form-field-left-margin': _vm.isHalfFieldSecond(element)
      }],
      on: {
        "field-value-changed": function fieldValueChanged($event) {
          return _vm.setFieldValue($event, element.name);
        },
        "fetch-autocomplete": _vm.fetchAutocomplete
      }
    }, 'BaseFormFieldCreator', _vm.formFieldComponentProps(element, index), false)) : [_vm._l(_vm.valueListInt[element.name], function (value, valueIndex) {
      return _c('div', {
        key: element.name + "_" + index + "_" + valueIndex + "_" + _vm.formId + "_wrapper",
        ref: element.name,
        refInFor: true,
        class: ['base-form-field', _vm.formFieldsHalf.indexOf(element) >= 0 ? 'base-form-field-half' : 'base-form-field-full', {
          'base-form-field-left-margin': _vm.isHalfFieldSecond(element)
        }]
      }, [_c('BaseFormFieldCreator', _vm._b({
        key: element.name + "_" + index + "_" + valueIndex + "_" + _vm.formId,
        on: {
          "field-value-changed": function fieldValueChanged($event) {
            _vm.setFieldValue($event, element.name, valueIndex, element['x-attrs'] ? element['x-attrs'].equivalent : '');
          },
          "fetch-autocomplete": _vm.fetchAutocomplete,
          "subform-input": function subformInput($event) {
            return _vm.setFieldValue($event, element.name, valueIndex);
          }
        }
      }, 'BaseFormFieldCreator', _vm.formFieldComponentProps(element, index, valueIndex), false)), _vm._v(" "), _vm.checkFieldContent(_vm.valueList[element.name]) || _vm.valueListInt[element.name].length > 1 ? _c('div', {
        key: index + "_button_" + valueIndex + "_" + _vm.formId,
        staticClass: "group-add"
      }, [_c('button', {
        staticClass: "field-group-button",
        attrs: {
          "type": "button"
        },
        on: {
          "click": function click($event) {
            $event.preventDefault();
            return _vm.removeField(element, valueIndex);
          }
        }
      }, [_c('span', [_vm._v("\n              " + _vm._s(_vm.valueListInt[element.name].length === 1 ? _vm.getI18nTerm('form.clearField') || 'Clear' : _vm.getI18nTerm('form.removeField', -1, {
        fieldType: _vm.getFieldName(element)
      })) + "\n            ")]), _vm._v(" "), _c('span', [_c('base-icon', {
        staticClass: "field-group-icon",
        attrs: {
          "name": "remove"
        }
      })], 1)])]) : _vm._e()], 1);
    }), _vm._v(" "), _c('div', {
      key: 'multiplyButton' + index,
      staticClass: "group-multiply"
    }, [_c('button', {
      staticClass: "field-group-button",
      attrs: {
        "type": "button"
      },
      on: {
        "click": function click($event) {
          $event.preventDefault();
          return _vm.multiplyField(element);
        }
      }
    }, [_c('span', [_vm._v("\n            " + _vm._s(_vm.getI18nTerm('form.addGroup', -1, {
      fieldType: _vm.getFieldName(element)
    })) + "\n          ")]), _vm._v(" "), _c('span', [_c('base-icon', {
      staticClass: "field-group-icon",
      attrs: {
        "name": "plus"
      }
    })], 1)])])]];
  })], 2);
};

var __vue_staticRenderFns__ = [];
/* style */

var __vue_inject_styles__ = undefined;
/* scoped */

var __vue_scope_id__ = "data-v-c93d1bfe";
/* module identifier */

var __vue_module_identifier__ = "data-v-c93d1bfe";
/* functional template */

var __vue_is_functional_template__ = false;
/* style inject */

/* style inject SSR */

/* style inject shadow dom */

var __vue_component__ = /*#__PURE__*/normalizeComponent.n({
  render: __vue_render__,
  staticRenderFns: __vue_staticRenderFns__
}, __vue_inject_styles__, __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, false, undefined, undefined, undefined);

var BaseForm = __vue_component__;exports["default"]=BaseForm;