import { n as normalizeComponent, u as use, r as registerComponent } from './normalize-component-63e8c7a0.js';
import './regexp-exec-abstract-04d119fc.js';
import './es.string.search-d018b707.js';
import './es.object.to-string-5a59fbfc.js';
import './es.array.includes-1f433385.js';
import './es.string.includes-53dbb113.js';
import './web.dom-collections.iterator-5ecbd86d.js';
import { _ as _toConsumableArray } from './toConsumableArray-fb122614.js';
import './es.number.constructor-16a232f3.js';
import './es.object.keys-6369b884.js';
import './es.array.map-093cfbca.js';
import './es.array.filter-9f634d7c.js';
import './es.array.concat-9f3136dc.js';
import './es.string.iterator-eb7ab984.js';
import { i as i18n } from './i18n-e25edebe.js';
import './export-ecf4b1cb.js';
import './string-multibyte-88926e02.js';
import './regexp-flags-b5fc4ddb.js';
import './classof-b10e7604.js';
import './object-keys-a5d351f7.js';
import './is-regexp-5558fd03.js';
import './function-bind-context-b3fabf77.js';
import './set-to-string-tag-452fb9b0.js';
import './set-species-77dd094d.js';
import './dom-iterables-b6f5ef3b.js';
import './unsupportedIterableToArray-577176bf.js';
import './object-set-prototype-of-9853ad1a.js';
import './array-iteration-dec5536e.js';
import './array-species-create-afb281e6.js';
import './array-method-has-species-support-d96108b0.js';
import './create-property-c00b5c27.js';
import './es.string.split-cd1f3afc.js';

/**
 * Component to select elements from a list, including search, options and pagination elements.
 */

var script = {
  name: 'BaseEntrySelector',
  components: {
    BaseDropDown: function BaseDropDown() {
      return import('./BaseDropDown-920e537b.js').then(function (m) {
        return m.default || m;
      });
    },
    BaseLoader: function BaseLoader() {
      return import('./BaseLoader-a5bfc4d9.js').then(function (m) {
        return m.default || m;
      });
    },
    BaseMenuList: function BaseMenuList() {
      return import('./BaseMenuList-6ab59c89.js').then(function (m) {
        return m.default || m;
      });
    },
    BaseOptions: function BaseOptions() {
      return import('./BaseOptions-1269f245.js').then(function (m) {
        return m.default || m;
      });
    },
    BasePagination: function BasePagination() {
      return import('./BasePagination-52fceef8.js').then(function (m) {
        return m.default || m;
      });
    },
    BaseSearch: function BaseSearch() {
      return import('./BaseSearch-70086489.js').then(function (m) {
        return m.default || m;
      });
    },
    BaseSelectOptions: function BaseSelectOptions() {
      return import('./BaseSelectOptions-ed2b39fa.js').then(function (m) {
        return m.default || m;
      });
    }
  },
  mixins: [i18n],
  props: {
    /**
     * list of entries to display. Unless the slot 'entries' is used this should be an object with
     * properties compatible with [BaseMenuList](#basemenulist) 'list' object array
     */
    entries: {
      type: Array,
      default: function _default() {
        return [];
      }
    },

    /**
     * provide the total number of entries for pagination calculations
     */
    entriesTotal: {
      type: Number,
      default: null
    },

    /**
     * number of entries per page (this does not steer the number of entries displayed
     * (the correct number needs to be provided by 'entries') but is solely
     * needed for correct pagination calculations)
     */
    entriesPerPage: {
      type: Number,
      default: 10
    },

    /**
     * define if entries are selectable - thus if checkboxes are available
     */
    entriesSelectable: {
      type: Boolean,
      default: false
    },

    /**
     * specify a maximum number of entries that can be selected<br>
     * specify '0' if there should be no limit
     */
    maxSelectedEntries: {
      type: Number,
      default: 0
    },

    /**
     * specify a custom height - mainly useful if component is within a pop up.
     * Use a valid CSS height
     * property value.
     */
    height: {
      type: String,
      default: ''
    },

    /**
     * flag to set if loader should be shown (for fetch requests)
     */
    isLoading: {
      type: Boolean,
      default: false
    },

    /**
     * specify an entry to be marked active (color border on left side)
     */
    activeEntry: {
      type: Number,
      default: -1
    },

    /**
     * specify a language (ISO 639-1) (used for label if label is language specific object
     * e.g. { de: 'xxx', en: 'yyy' })
     */
    language: {
      type: String,
      default: 'en'
    },

    /**
     * hide options completely (necessary if only before or after slot elements should remain)
     */
    optionsHidden: {
      type: Boolean,
      default: false
    },

    /**
     * define options to filter entries
     * structure e.g.: [{ label: { de: "Alle Typen", en: "All Types" }, source: "" }]
     */
    entryTypes: {
      type: Array,
      default: function _default() {
        return [];
      }
    },

    /**
     * specify config options for your sorting drop down element (if 'sortOptions are
     * provided<br>
     * Needs to be an object with the following properties:<br>
     *  *label*: specify a label for the sort options drop down (purely for accessibility purposes)
     *  *default*: specify a default option that the drop down is initialized with<br>
     *    this needs to have the same object structure as the objects in 'entryTypes'<br>
     *    if no default is provided the first option in the list will be selected
     *  *valuePropertyName*: specify the name of the property that contains a unique value
     */
    entryTypesConfig: {
      type: Object,
      default: function _default() {
        return {
          label: 'filter by type',
          default: null,
          valuePropertyName: 'value'
        };
      },
      validator: function validator(value) {
        return !value || ['label', 'default', 'valuePropertyName'].every(function (key) {
          return Object.keys(value).includes(key);
        });
      }
    },

    /**
     * define options for sorting entries <br>
     * structure e.g: [{ label: 'By Type', value: 'type_en' }]
     */
    sortOptions: {
      type: Array,
      default: function _default() {
        return [];
      }
    },

    /**
     * specify config options for your sorting drop down element (if 'sortOptions are
     * provided<br>
     * Needs to be an object with the following properties:<br>
     *  *label*: specify a label for the sort options drop down (purely for accessibility purposes)
     *  *default*: specify a default option that the drop down is initialized with.
     *    if none is specified the first type in the 'sortOptions' will be used.<br>
     *    This needs to be an object with the same properties as 'sortOptions'.
     *  *valuePropertyName*: specify the name of the property that contains a unique value
     */
    sortConfig: {
      type: Object,
      default: function _default() {
        return {
          label: 'sort entries',
          default: null,
          valuePropertyName: 'value'
        };
      },
      validator: function validator(value) {
        return !value || Object.keys(value).every(function (key) {
          return ['label', 'default', 'valuePropertyName'].includes(key);
        });
      }
    },

    /**
     * specify informational texts for the component (especially helpful to provide language
     * specific text - this needs to be an object with the following
     * properties (if you dont want to display any text leave an empty string:  <br>
     *   <br>
     *     <b>noEntriesTitle</b>: Header text shown if search for string returned no results<br>
     *     <b>noEntriesSubtext</b>: subtext shown if search for string returned no result <br>
     *     <b>options</b>: Text for title button<br>
     *        This needs to be an object containing a 'show' and 'hide' property that are shown when
     *        'entriesSelecable' is true or false respectively<br>
     *     <b>search</b>: placeholder in search input field<br>
     *     <b>selectAll</b>: Text for Select All button <br>
     *     <b>selectNone</b>: Text for Select None button <br>
     *     <b>entriesSelected</b>: Text for number of entries (x) selected information displayed as
     *      'x {provided text} <br>
     *  <br>
     *  The values of this object might be plain string or a key for an i18n file (in case it is not
     *  an object that is required! - in that case the above applies to the values within that
     *  object)<br>
     */
    entrySelectorText: {
      type: Object,
      default: function _default() {
        return {
          noEntriesTitle: 'No matching entries found',
          noEntriesSubtext: 'Please adjust your search criteria.',
          options: {
            show: 'options',
            hide: 'options'
          },
          search: 'Search',
          selectAll: 'Select All',
          selectNone: 'Select None',
          entriesSelected: 'entries selected',
          maxEntriesReached: 'Maximum Number Exceeded!'
        };
      },
      // checking if all necessary properties are part of the provided object
      validator: function validator(val) {
        return ['noEntriesTitle', 'noEntriesSubtext', 'options', 'search', 'selectAll', 'selectNone', 'entriesSelected', 'maxEntriesReached'].every(function (prop) {
          return Object.keys(val).includes(prop);
        }) && ['show', 'hide'].every(function (requiredProp) {
          return Object.keys(val.options).includes(requiredProp);
        });
      }
    }
  },
  data: function data() {
    return {
      /**
       * variable to store filter text entered into search
       * @type {string}
       */
      filterString: '',

      /**
       * variable to store selected filter type
       * @type {Object}
       */
      filterType: {},

      /**
       * variable to store selected sort option
       * @type {Object}
       */
      sortParam: {},
      headHasShadow: false,
      pageNumber: 1,
      showOptions: false,
      // TODO: eventually it would make sense to have selected entries settable from outside
      selectedEntries: [],

      /**
       * timeout to prevent triggering of search after every key stroke
       * @type {?number}
       * TODO: eventually this should be kept in front end to give more individual control to
       * component users
       */
      timeout: null
    };
  },
  computed: {
    /**
     * create object for the element style attribute
     * @returns {Object}
     */
    calcStyle: function calcStyle() {
      return this.height ? {
        height: this.height
      } : {};
    },

    /**
     * calculate page total for pagination from available numbers
     * @returns {number}
     */
    pageTotal: function pageTotal() {
      return this.entriesPerPage ? Math.ceil(this.entriesTotal / this.entriesPerPage) : 0;
    },

    /**
     * BaseMenuList components needs a list of id's for selected entries
     * @returns {string[]}
     */
    selectedListIds: function selectedListIds() {
      return this.selectedEntries.map(function (entry) {
        return entry.id;
      });
    },

    /**
     * to calc the correct max-with for the sort and type drop downs we need to know how
     * many there are
     * @type {number}
     */
    dropDownElementsCount: function dropDownElementsCount() {
      if (this.sortOptions && this.sortOptions.length && this.entryTypes && this.entryTypes.length) {
        return 2;
      }

      return 1;
    },

    /**
     * filter entries which are not disabled
     *
     * @returns {Object[]}
     */
    selectableEntries: function selectableEntries() {
      return this.entries.filter(function (entry) {
        return !entry.disabled;
      });
    }
  },
  watch: {
    /**
     * watch outside variable to have it in sync with internal 'showOptions'
     */
    entriesSelectable: {
      handler: function handler(val) {
        if (val !== this.showOptions) {
          this.showOptions = val;
        }
      },
      immediate: true
    },
    showOptions: function showOptions(val) {
      // delete selected when options menu is closed and reset select all
      if (!val) {
        this.selectedEntries = [];
      }

      if (val !== this.entriesSelectable) {
        /**
         * emit event to inform parent about toggle triggered and keep prop variable
         * entriesSelectable in sync
         * @event update:entries-selectable
         * @type {boolean}
         */
        this.$emit('update:entries-selectable', this.showOptions);
      }
    },

    /**
     * watch selectedEntries to inform parent of changes in selection
     */
    selectedEntries: function selectedEntries() {
      /**
       * event emitted every time the selected entries change
       * @event selected-changed
       * @type {Object[]}
       */
      this.$emit('selected-changed', this.selectedEntries);
    }
  },
  created: function created() {
    // set the default option for the drop down menus
    this.sortParam = this.sortConfig.default || (this.sortOptions.length ? this.sortOptions[0] : {});
    this.filterType = this.entryTypesConfig.default || (this.entryTypes.length ? this.entryTypes[0] : {});
  },
  mounted: function mounted() {
    // fetch initial entries
    this.fetchEntries(); // add scroll listener to determine if head shadow should be displayed

    this.$refs.body.addEventListener('scroll', this.scroll);
  },
  beforeDestroy: function beforeDestroy() {
    this.$refs.body.removeEventListener('scroll', this.scroll);
  },
  methods: {
    /**
     * select all or none entries
     *
     * @param {Boolean} selected
     */
    changeAllSelectState: function changeAllSelectState(selected) {
      if (selected) {
        // add all visible entries to selected list
        this.selectedEntries = this.selectedEntries.concat(this.selectableEntries); // deduplicate by creating set and convert back to array

        this.selectedEntries = _toConsumableArray(new Set(this.selectedEntries));
      } else {
        var entriesIds = this.entries.map(function (entry) {
          return entry.id;
        });
        this.selectedEntries = this.selectedEntries.filter(function (entry) {
          return !entriesIds.includes(entry.id);
        });
      }
    },
    fetchEntries: function fetchEntries() {
      var _this = this;

      if (this.timeout) {
        clearTimeout(this.timeout);
        this.timeout = null;
      }

      this.timeout = setTimeout(function () {
        /**
         * Event emitted to fetch entries
         *
         * @event fetch-entries
         * @property {string} page - current pagination page
         * @property {string} query - the search string
         * @property {object} sort - the sort filter
         * @property {object} type - the type filter
         */
        _this.$emit('fetch-entries', {
          page: _this.pageNumber,
          query: _this.filterString,
          sort: _this.sortParam,
          type: _this.filterType
        });
      }, 600);
    },
    filterEntries: function filterEntries(value, type) {
      var _this2 = this;

      if (type === 'type') {
        this.fetchEntries();
      } else if (type === 'title') {
        if (this.timeout) {
          clearTimeout(this.timeout);
          this.timeout = null;
        }

        this.timeout = setTimeout(function () {
          if (value.length === 0 || value.length > 2) {
            _this2.fetchEntries();
          }
        }, 600);
      }

      this.pageNumber = 1;
    },
    scroll: function scroll() {
      if (this.$refs.body.scrollTop) {
        this.headHasShadow = true;
        return;
      }

      this.headHasShadow = false;
    },

    /**
     *
     * @param {Object} obj - selected entry
     * @property {boolean} obj.selected - variable indicating if entry was selected or deselected
     * @property {string} obj.index - the index of the selected or deselected entry in 'entries'
     * @public
     */
    selectEntry: function selectEntry(obj) {
      var _this3 = this;

      if (obj.selected) {
        this.selectedEntries.push(this.entries[obj.index]);
      } else {
        this.selectedEntries = this.selectedEntries.filter(function (entry) {
          return entry.id !== _this3.entries[obj.index].id;
        });
      }
    },
    setPage: function setPage(number) {
      this.pageNumber = number;
      this.fetchEntries();
    },
    entryClicked: function entryClicked(index) {
      /**
       * Triggered when the entry is clicked
       *
       * @event entry-clicked
       * @type {string}
       */
      this.$emit('entry-clicked', this.entries[index].id);
    }
  }
};

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-entry-selector",
    style: _vm.calcStyle
  }, [_c('div', {
    ref: "head",
    class: ['base-entry-selector__head', {
      'base-entry-selector__head--shadow': _vm.headHasShadow
    }]
  }, [_vm._t("head", function () {
    return [_c('BaseSearch', {
      staticClass: "base-entry-selector__head__search-bar",
      attrs: {
        "show-image": true,
        "placeholder": _vm.getI18nTerm(_vm.entrySelectorText.search)
      },
      on: {
        "input": function input($event) {
          return _vm.filterEntries($event, 'title');
        }
      },
      model: {
        value: _vm.filterString,
        callback: function callback($$v) {
          _vm.filterString = $$v;
        },
        expression: "filterString"
      }
    })];
  }), _vm._v(" "), _c('div', {
    staticClass: "base-entry-selector__options"
  }, [_c('BaseOptions', {
    ref: "baseOptions",
    attrs: {
      "show-options": _vm.showOptions,
      "options-hidden": _vm.optionsHidden,
      "use-options-button-on": 'always',
      "show-after-options-below": true,
      "options-button-icon": {
        show: 'options-menu',
        hide: 'options-menu'
      },
      "options-button-text": _vm.entrySelectorText.options,
      "align-options": "left"
    },
    on: {
      "update:showOptions": function updateShowOptions($event) {
        _vm.showOptions = $event;
      },
      "update:show-options": function updateShowOptions($event) {
        _vm.showOptions = $event;
      }
    }
  }, [_c('template', {
    slot: "afterOptions"
  }, [_c('div', {
    staticClass: "base-entry-selector__dropdowns"
  }, [_vm._t("after-options", function () {
    return [_vm.sortOptions.length ? _c('BaseDropDown', {
      ref: "baseDropDown",
      staticClass: "base-entry-selector__dropdowns__dropdown",
      style: {
        maxWidth: 100 / _vm.dropDownElementsCount + "%"
      },
      attrs: {
        "id": _vm.sortConfig.label + "-sort-drop-down",
        "label": _vm.sortConfig.label,
        "options": _vm.sortOptions,
        "with-spacing": false,
        "align-drop-down": _vm.entryTypes.length ? 'left' : 'right',
        "value-prop": _vm.sortConfig.valuePropertyName
      },
      on: {
        "value-selected": _vm.fetchEntries
      },
      model: {
        value: _vm.sortParam,
        callback: function callback($$v) {
          _vm.sortParam = $$v;
        },
        expression: "sortParam"
      }
    }) : _vm._e(), _vm._v(" "), _vm.entryTypes.length ? _c('BaseDropDown', {
      ref: "baseDropDown",
      staticClass: "base-entry-selector__dropdowns__dropdown",
      style: {
        maxWidth: 100 / _vm.dropDownElementsCount + "%"
      },
      attrs: {
        "id": _vm.entryTypesConfig.label + "-types-drop-down",
        "label": _vm.entryTypesConfig.label,
        "options": _vm.entryTypes,
        "language": _vm.language,
        "with-spacing": false,
        "value-prop": _vm.entryTypesConfig.valuePropertyName,
        "align-drop-down": "right"
      },
      on: {
        "value-selected": function valueSelected($event) {
          return _vm.filterEntries($event, 'type');
        }
      },
      model: {
        value: _vm.filterType,
        callback: function callback($$v) {
          _vm.filterType = $$v;
        },
        expression: "filterType"
      }
    }) : _vm._e()];
  })], 2)]), _vm._v(" "), _c('template', {
    slot: "options"
  }, [_vm._t("option-actions")], 2)], 2)], 1), _vm._v(" "), _vm.showOptions ? _c('BaseSelectOptions', {
    ref: "selectOptions",
    attrs: {
      "select-text": _vm.getI18nTerm(_vm.entrySelectorText.selectAll),
      "selected-number-text": _vm.getI18nTerm(_vm.entrySelectorText.entriesSelected),
      "deselect-text": _vm.getI18nTerm(_vm.entrySelectorText.selectNone),
      "list": _vm.selectableEntries,
      "selected-list": _vm.selectedEntries,
      "select-all-disabled": !!_vm.maxSelectedEntries && !(_vm.selectableEntries.length < _vm.maxSelectedEntries - _vm.selectedListIds.length || !_vm.selectableEntries.some(function (entry) {
        return !_vm.selectedListIds.includes(entry.id);
      }))
    },
    on: {
      "selected": _vm.changeAllSelectState
    },
    scopedSlots: _vm._u([{
      key: "selectedText",
      fn: function fn() {
        return [_vm._v("\n        " + _vm._s("" + _vm.selectedListIds.length + (_vm.maxSelectedEntries ? "/" + _vm.maxSelectedEntries : '') + "\n        " + _vm.getI18nTerm(_vm.entrySelectorText.entriesSelected)) + "\n        "), !!_vm.maxSelectedEntries && _vm.selectedListIds.length >= _vm.maxSelectedEntries ? _c('span', [_vm._v("\n          " + _vm._s("(" + _vm.getI18nTerm(_vm.entrySelectorText.maxEntriesReached) + ")") + "\n        ")]) : _vm._e()];
      },
      proxy: true
    }], null, false, 303893673)
  }) : _vm._e()], 2), _vm._v(" "), _c('div', {
    ref: "body",
    staticClass: "base-entry-selector__body"
  }, [_vm.isLoading ? _c('div', {
    staticClass: "loading-area"
  }, [_c('BaseLoader', {
    class: {
      'base-entry-selector__loader__center': _vm.entries.length < 4
    }
  })], 1) : _vm._e(), _vm._v(" "), _vm._t("entries", function () {
    return [_vm.entries.length ? _c('BaseMenuList', {
      key: "menu-list",
      ref: "menuList",
      staticClass: "base-entry-selector__body__entries",
      attrs: {
        "select-active": _vm.showOptions,
        "list": _vm.entries,
        "active-entry": _vm.activeEntry,
        "selected-list": _vm.selectedListIds
      },
      on: {
        "clicked": _vm.entryClicked,
        "selected": _vm.selectEntry
      },
      scopedSlots: _vm._u([{
        key: "thumbnails",
        fn: function fn(ref) {
          var item = ref.item;
          return [_vm._t("thumbnails", null, {
            "item": item
          })];
        }
      }], null, true)
    }) : !_vm.isLoading ? _c('div', {
      staticClass: "base-entry-selector__no-entries"
    }, [_c('p', {
      staticClass: "base-entry-selector__no-entries__title"
    }, [_vm._v("\n          " + _vm._s(_vm.getI18nTerm(_vm.entrySelectorText.noEntriesTitle)) + "\n        ")]), _vm._v(" "), _c('p', {
      staticClass: "base-entry-selector__no-entries__subtext"
    }, [_vm._v("\n          " + _vm._s(_vm.getI18nTerm(_vm.entrySelectorText.noEntriesSubtext)) + "\n        ")])]) : _vm._e()];
  }, {
    "entries": _vm.entries,
    "selectEntry": _vm.selectEntry
  })], 2), _vm._v(" "), _vm.pageTotal > 1 ? _c('BasePagination', {
    ref: "pagination",
    attrs: {
      "total": _vm.pageTotal,
      "current": _vm.pageNumber
    },
    on: {
      "set-page": _vm.setPage
    }
  }) : _vm._e()], 1);
};

var __vue_staticRenderFns__ = [];
/* style */

var __vue_inject_styles__ = undefined;
/* scoped */

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

var __vue_module_identifier__ = undefined;
/* functional template */

var __vue_is_functional_template__ = false;
/* style inject */

/* style inject SSR */

/* style inject shadow dom */

var __vue_component__ = /*#__PURE__*/normalizeComponent({
  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 BaseEntrySelector = __vue_component__;

var Plugin = {
  install: function install(Vue) {
    registerComponent(Vue, BaseEntrySelector);
  }
};
use(Plugin);

export { BaseEntrySelector, Plugin as default };
