@appbaseio/reactivesearch-vue
Version:
A Vue UI components library for building search experiences
954 lines (938 loc) • 38.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var reactivecore = require('@appbaseio/reactivecore');
var constants = require('@appbaseio/reactivecore/lib/utils/constants');
var _transformOn = _interopDefault(require('@vue/babel-helper-vue-transform-on'));
var _rollupPluginBabelHelpers = require('./_rollupPluginBabelHelpers-1a877b17.js');
var vue = require('vue');
var VueTypes = _interopDefault(require('vue-types'));
var helper = require('@appbaseio/reactivecore/lib/utils/helper');
var vueEmotion = require('@appbaseio/vue-emotion');
var css = require('@emotion/css');
require('polished');
require('./Button-7aee17e3.js');
var vueTypes = require('./vueTypes-adf43075.js');
var Pagination = require('./Pagination-8bda127c.js');
require('@appbaseio/reactivecore/lib/utils/transform');
require('redux');
var index = require('./index-7ca9570e.js');
var ComponentWrapper = require('./ComponentWrapper-3bedbe57.js');
var PreferencesConsumer = require('./PreferencesConsumer-37cab7a0.js');
require('./Title-d513ac26.js');
var ListItem = require('./ListItem-f272f502.js');
var Card = require('./Card-abff695e.js');
var Flex = require('./Flex-f7af0673.js');
var _templateObject;
var PoweredByImage = vueEmotion.styled('img')(_templateObject || (_templateObject = _rollupPluginBabelHelpers._taggedTemplateLiteralLoose(["\n\twidth: 110px;\n"])));
var PoweredBy = function PoweredBy() {
return vue.createVNode("a", {
"href": "https://appbase.io/",
"target": "_blank",
"rel": "noopener noreferrer"
}, [vue.createVNode(PoweredByImage, {
"src": "https://cdn.jsdelivr.net/gh/appbaseio/cdn@d2ec210045e59104ee5485841fa17b23fc83f097/appbase/logos/rbc-logo.svg"
}, null)]);
};
var ResultListWrapper = {
name: 'ResultListWrapper',
functional: true,
render: function render(context) {
return vue.createVNode("div", vue.mergeProps({
"className": ListItem.container
}, context.$props), [context.$slots["default"]()]);
}
};
ResultListWrapper.install = function (Vue) {
Vue.component(ResultListWrapper.name, ResultListWrapper);
};
var ResultCardsWrapper = {
name: 'ResultCardsWrapper',
functional: true,
render: function render(context) {
return vue.createVNode("div", vue.mergeProps({
"className": Card.container
}, context.$props), [context.$slots["default"]()]);
}
};
ResultCardsWrapper.install = function (Vue) {
Vue.component(ResultCardsWrapper.name, ResultCardsWrapper);
};
var _templateObject$1, _templateObject2;
var resultStats = css.css(_templateObject$1 || (_templateObject$1 = _rollupPluginBabelHelpers._taggedTemplateLiteralLoose(["\n\tflex-grow: 1;\n\tfont-size: 0.82rem;\n"])));
var sortOptions = css.css(_templateObject2 || (_templateObject2 = _rollupPluginBabelHelpers._taggedTemplateLiteralLoose(["\n\tcolor: #424242;\n\theight: 32px;\n\tfont-size: 0.82rem;\n\tpadding: 0 25px 0 10px;\n\tbackground: url(data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0Ljk1IDEwIj48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2ZmZjt9LmNscy0ye2ZpbGw6IzQ0NDt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPmFycm93czwvdGl0bGU+PHJlY3QgY2xhc3M9ImNscy0xIiB3aWR0aD0iNC45NSIgaGVpZ2h0PSIxMCIvPjxwb2x5Z29uIGNsYXNzPSJjbHMtMiIgcG9pbnRzPSIxLjQxIDQuNjcgMi40OCAzLjE4IDMuNTQgNC42NyAxLjQxIDQuNjciLz48cG9seWdvbiBjbGFzcz0iY2xzLTIiIHBvaW50cz0iMy41NCA1LjMzIDIuNDggNi44MiAxLjQxIDUuMzMgMy41NCA1LjMzIi8+PC9zdmc+)\n\t\tno-repeat 95% 50%;\n\tbackground-color: #fff;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tappearance: none;\n\t-webkit-border-radius: 0;\n\tborder-radius: 0;\n\tborder: 0;\n\toutline: 1px solid #ddd;\n\toutline-offset: -1px;\n"])));
var recordImpressions = reactivecore.Actions.recordImpressions;
var isEqual = reactivecore.helper.isEqual;
var debounce = function debounce(method, delay) {
clearTimeout(method._tId);
// eslint-disable-next-line
method._tId = setTimeout(function () {
method();
}, delay);
};
var ImpressionTracker = {
name: 'ImpressionTracker',
inject: ['$$store'],
props: {
hits: vueTypes.types.hits
},
created: function created() {
// Represents the list of hits returned by the query
this.currentHits = []; // An array of hits objects
// An object to track the recorded impressions
// It can have the values in following shape
// { "hit_id": { "index": "test" }}
this.trackedIds = {};
// An object to know the the un-tracked impression i.e not recorded by BE
// It can have the values in following shape
// { "query_id": [{ "id": "hit_id", "index": "test"}]}
this.waitingToBeTracked = {};
},
mounted: function mounted() {
this.setCurrentHits(this.hits);
// Add scroll events to track the impressions
if (window) {
window.addEventListener('scroll', this.tracker);
}
},
destroy: function destroy() {
// Clear the interval
this.clearTrackerInterval();
},
watch: {
hits: function hits(newVal, oldVal) {
if (newVal && newVal !== oldVal) {
// Only compare hit ids for performance reasons
var prevHitIds = oldVal.map(function (hit) {
return hit._id;
});
var currentHitIds = newVal.map(function (hit) {
return hit._id;
});
if (!isEqual(currentHitIds, prevHitIds)) {
this.setCurrentHits(newVal);
}
}
}
},
methods: {
inViewPort: function inViewPort(el) {
var rect = el.getBoundingClientRect();
return rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth);
},
setCurrentHits: function setCurrentHits(hits) {
this.currentHits = hits;
// Reset the tracked Ids for new hits
this.trackedIds = {};
if (hits && hits.length) {
this.tracker();
// Run the tracker function on an interval of 1s to track the impressions for
// non-scroll views for e.g on tab change
this.setTrackerInterval();
}
},
recordImpression: function recordImpression() {
var _this = this;
if (Object.keys(this.waitingToBeTracked).length) {
var unTrackedHits = _rollupPluginBabelHelpers._extends({}, this.waitingToBeTracked);
Object.keys(unTrackedHits).forEach(function (queryId) {
if (unTrackedHits[queryId] && unTrackedHits[queryId].length) {
_this.trackImpressions(queryId, unTrackedHits[queryId]);
// Removed tracked impressions from waiting list
delete _this.waitingToBeTracked[queryId];
}
});
}
},
addToWaitingList: function addToWaitingList(hitObject) {
var queryId = this.getQueryId();
if (hitObject && queryId) {
var impression = {
id: hitObject._id,
index: hitObject._index
};
// Check if query id already present in waiting list
if (this.waitingToBeTracked[queryId]) {
this.waitingToBeTracked[queryId].push(impression);
} else {
this.waitingToBeTracked[queryId] = [impression];
}
}
},
tracker: function tracker() {
var _this2 = this;
if (!this.getHitIds().length) {
this.clearTrackerInterval();
return;
}
// only run at client-side
if (window && document) {
this.getHitIds().forEach(function (id) {
var element = document.getElementById(id);
if (element) {
if (_this2.inViewPort(element)) {
// Add the hit id in the list of tracked ids
var hitObject = _this2.currentHits.find(function (hit) {
return hit._id === id;
});
_this2.trackedIds[id] = true;
// Add hit to waiting list to be recorded
_this2.addToWaitingList(hitObject);
}
}
});
}
debounce(this.recordImpression, 300);
},
setTrackerInterval: function setTrackerInterval() {
this.intervalID = setInterval(this.tracker, 1000);
},
clearTrackerInterval: function clearTrackerInterval() {
if (this.intervalID) {
clearInterval(this.intervalID);
// Reset interval ID
this.intervalID = null;
}
},
getQueryId: function getQueryId() {
var state = this.$$store ? this.$$store.getState() : null;
return state ? state.analytics.searchId : null;
},
getHitIds: function getHitIds() {
var _this3 = this;
return this.currentHits.map(function (hit) {
return hit._id;
}).filter(function (id) {
return !_this3.trackedIds[id];
});
}
},
render: function render() {
return this.$slots["default"]();
}
};
var mapDispatchToProps = {
trackImpressions: recordImpressions
};
var ImpressionTracker$1 = index.connect(function () {
return null;
}, mapDispatchToProps)(ImpressionTracker);
function _isSlot(s) {
return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
}
var setQueryOptions = reactivecore.Actions.setQueryOptions,
updateQuery = reactivecore.Actions.updateQuery,
loadMore = reactivecore.Actions.loadMore,
setValue = reactivecore.Actions.setValue,
updateComponentProps = reactivecore.Actions.updateComponentProps,
setDefaultQuery = reactivecore.Actions.setDefaultQuery,
recordResultClick = reactivecore.Actions.recordResultClick;
var isEqual$1 = reactivecore.helper.isEqual,
getQueryOptions = reactivecore.helper.getQueryOptions,
getClassName = reactivecore.helper.getClassName,
parseHits = reactivecore.helper.parseHits,
getCompositeAggsQuery = reactivecore.helper.getCompositeAggsQuery,
getResultStats = reactivecore.helper.getResultStats,
extractQueryFromCustomQuery = reactivecore.helper.extractQueryFromCustomQuery,
getOptionsForCustomQuery = reactivecore.helper.getOptionsForCustomQuery;
var ReactiveList = {
name: 'ReactiveList',
components: {
ResultListWrapper: ResultListWrapper,
ResultCardsWrapper: ResultCardsWrapper
},
data: function data() {
var currentPageState = 0;
var defaultPage = this.defaultPage || -1;
if (defaultPage >= 0) {
currentPageState = defaultPage;
} else if (this.currentPage) {
currentPageState = Math.max(this.currentPage - 1, 0);
}
this.__state = {
from: currentPageState * this.size,
currentPageState: currentPageState
};
return this.__state;
},
created: function created() {
var _this = this;
// no support for pagination and aggregationField together
if (this.pagination && this.aggregationField) {
console.warn('Pagination is not supported when aggregationField is present. The list will be rendered with infinite scroll');
}
var defaultPage = this.defaultPage || -1;
if (defaultPage >= 0) {
this.currentPageState = defaultPage;
this.from = this.currentPageState * this.$props.size;
}
this.internalComponent = this.$props.componentId + "__internal";
this.sortOptionIndex = 0;
if (this.defaultSortOption && this.sortOptions && Array.isArray(this.sortOptions)) {
this.sortOptionIndex = this.sortOptions.findIndex(function (s) {
return s.label === _this.defaultSortOption;
});
}
if (this.urlSortOption) {
this.sortOptionIndex = this.$props.sortOptions.findIndex(function (s) {
return s.label === _this.urlSortOption;
}) || 0;
}
this.updateComponentProps(this.componentId, {
from: this.from
}, constants.componentTypes.reactiveList);
this.updateComponentProps(this.internalComponent, {
from: this.from
}, constants.componentTypes.reactiveList);
},
props: {
currentPage: VueTypes.number,
includeFields: vueTypes.types.includeFields,
// component props
className: vueTypes.types.string,
componentId: vueTypes.types.stringRequired,
compoundClause: vueTypes.types.compoundClause,
dataField: vueTypes.types.string,
vectorDataField: vueTypes.types.string,
aggregationField: vueTypes.types.string,
aggregationSize: VueTypes.number,
defaultQuery: vueTypes.types.func,
defaultSortOption: vueTypes.types.string,
excludeFields: vueTypes.types.excludeFields,
innerClass: vueTypes.types.style,
listClass: VueTypes.string.def(''),
loader: vueTypes.types.title,
render: vueTypes.types.func,
renderItem: vueTypes.types.func,
renderNoResults: VueTypes.any.def('No Results found.'),
renderError: vueTypes.types.title,
renderResultStats: vueTypes.types.func,
pages: VueTypes.number.def(5),
pagination: VueTypes.bool.def(false),
infiniteScroll: VueTypes.bool.def(true),
paginationAt: VueTypes.oneOf(['top', 'bottom', 'both']).def('bottom'),
react: vueTypes.types.react,
scrollOnChange: VueTypes.bool.def(true),
showResultStats: VueTypes.bool.def(true),
showEndPage: VueTypes.bool.def(false),
size: VueTypes.number.def(10),
candidates: VueTypes.number.def(10),
sortBy: vueTypes.types.sortBy,
sortOptions: vueTypes.types.sortOptions,
URLParams: VueTypes.bool.def(false),
prevLabel: vueTypes.types.string,
nextLabel: vueTypes.types.string,
distinctField: vueTypes.types.string,
distinctFieldConfig: vueTypes.types.props,
index: VueTypes.string,
endpoint: vueTypes.types.endpointConfig
},
computed: {
shouldRenderPagination: function shouldRenderPagination() {
return this.pagination && !this.aggregationField;
},
totalPages: function totalPages() {
return Math.ceil(this.total / this.$props.size) || 0;
},
hasPageChangeListener: function hasPageChangeListener() {
return this.$attrs && this.$attrs.pageChange;
},
hasResultStatsListener: function hasResultStatsListener() {
return this.$attrs && this.$attrs.resultStats;
},
stats: function stats() {
return _rollupPluginBabelHelpers._extends({}, getResultStats(this), {
currentPage: this.currentPageState,
displayedResults: this.data.length
});
},
hasCustomRender: function hasCustomRender() {
return index.hasCustomRenderer(this);
},
showInfiniteScroll: function showInfiniteScroll() {
// Pagination has higher priority then infinite scroll
return this.infiniteScroll && !this.shouldRenderPagination;
},
data: function data() {
var results = parseHits(this.hits) || [];
var parsedPromotedResults = parseHits(this.promotedResults) || [];
var filteredResults = results;
if (parsedPromotedResults.length) {
var ids = parsedPromotedResults.map(function (item) {
return item._id;
}).filter(Boolean);
if (ids) {
filteredResults = filteredResults.filter(function (item) {
return !ids.includes(item._id);
});
}
filteredResults = [].concat(parsedPromotedResults, filteredResults);
}
return helper.withClickIds(filteredResults);
}
},
watch: {
sortOptions: function sortOptions(newVal, oldVal) {
if (!isEqual$1(oldVal, newVal)) {
this.updateQueryOptions(this.$props);
}
},
sortBy: function sortBy(newVal, oldVal) {
if (oldVal !== newVal) {
this.updateQueryOptions(this.$props);
}
},
size: function size(newVal, oldVal) {
if (oldVal !== newVal) {
this.updateQueryOptions(this.$props);
}
},
dataField: function dataField(newVal, oldVal) {
if (oldVal !== newVal) {
this.updateQueryOptions(this.$props);
}
},
includeFields: function includeFields(newVal, oldVal) {
if (oldVal !== newVal) {
this.updateQueryOptions(this.$props);
}
},
excludeFields: function excludeFields(newVal, oldVal) {
if (oldVal !== newVal) {
this.updateQueryOptions(this.$props);
}
},
defaultQuery: function defaultQuery(newVal, oldVal) {
if (!index.isQueryIdentical(newVal, oldVal, null, this.$props)) {
var options = getQueryOptions(this.$props);
options.from = 0;
this.$defaultQuery = newVal(null, this.$props);
var query = extractQueryFromCustomQuery(this.$defaultQuery);
var queryOptions = getOptionsForCustomQuery(this.$defaultQuery);
if (queryOptions) {
options = _rollupPluginBabelHelpers._extends({}, options, queryOptions);
}
// Update calculated default query in store
index.updateDefaultQuery(this.componentId, this.setDefaultQuery, this.$props);
this.setQueryOptions(this.$props.componentId, _rollupPluginBabelHelpers._extends({}, options, this.getAggsQuery()), !query);
this.updateQuery({
componentId: this.internalComponent,
query: query
}, true); // reset page because of query change
this.currentPageState = 0;
this.from = 0;
}
},
promotedResults: function promotedResults(newVal, oldVal) {
if (!isEqual$1(newVal, oldVal)) {
this.$emit('data', this.getData());
}
},
hidden: function hidden(newVal, oldVal) {
if (!isEqual$1(newVal, oldVal)) {
this.$emit('data', this.getData());
}
},
time: function time(newVal, oldVal) {
if (!isEqual$1(newVal, oldVal)) {
this.$emit('data', this.getData());
}
},
hits: function hits(newVal, oldVal) {
this.$emit('data', this.getData());
if (this.shouldRenderPagination) {
// called when page is changed
if (this.isLoading && (oldVal || newVal)) {
if (this.hasPageChangeListener) {
this.$emit('pageChange', this.currentPageState + 1, this.totalPages);
this.$emit('page-change', this.currentPageState + 1, this.totalPages);
} else if (this.scrollOnChange) {
window.scrollTo(0, 0);
}
}
} else if (oldVal && newVal) {
if (oldVal.length !== newVal.length || newVal.length === this.$props.total) {
if (newVal.length < oldVal.length) {
// query has changed
if (this.scrollOnChange) {
window.scrollTo(0, 0);
}
this.from = 0;
}
}
}
},
rawData: function rawData(newVal, oldVal) {
if (!isEqual$1(newVal, oldVal)) {
this.$emit('data', this.getData());
}
},
currentPage: function currentPage(newVal, oldVal) {
if (oldVal !== newVal && newVal > 0 && newVal <= this.totalPages) {
this.setPage(newVal - 1);
}
},
infiniteScroll: function infiniteScroll(newVal, oldVal) {
if (newVal !== oldVal) {
if (newVal && !this.pagination) {
window.addEventListener('scroll', this.scrollHandler);
} else {
window.removeEventListener('scroll', this.scrollHandler);
}
}
},
pagination: function pagination(newVal, oldVal) {
if (newVal !== oldVal) {
if (!newVal && this.infiniteScroll) {
window.addEventListener('scroll', this.scrollHandler);
} else {
window.removeEventListener('scroll', this.scrollHandler);
}
} // handle window url history change (on native back and forth interactions)
},
defaultPage: function defaultPage(newVal, oldVal) {
if (this.currentPageState !== newVal && oldVal !== newVal) {
this.setPage(newVal >= 0 ? newVal : 0);
}
},
isLoading: function isLoading(newVal, oldVal) {
if (newVal !== oldVal) {
this.$emit('loading', newVal);
}
}
},
mounted: function mounted() {
if (this.defaultPage < 0 && this.currentPage > 0) {
this.setPageURL(this.$props.componentId, this.currentPage, this.$props.componentId, false, this.URLParams);
}
var options = getQueryOptions(this.$props);
options.from = this.$data.from;
if (this.sortOptions && this.sortOptions[this.sortOptionIndex]) {
var _ref;
var sortField = this.sortOptions[this.sortOptionIndex].dataField;
var sortBy = this.sortOptions[this.sortOptionIndex].sortBy;
options.sort = [(_ref = {}, _ref[sortField] = {
order: sortBy
}, _ref)];
// To handle sort options for RS API
this.updateComponentProps(this.componentId, {
dataField: sortField,
sortBy: sortBy
}, constants.componentTypes.reactiveList);
} else if (this.$props.sortBy) {
var _ref2;
options.sort = [(_ref2 = {}, _ref2[this.$props.dataField] = {
order: this.$props.sortBy
}, _ref2)];
} // Override sort query with defaultQuery's sort if defined
this.$defaultQuery = null;
if (this.$props.defaultQuery) {
this.$defaultQuery = this.$props.defaultQuery();
options = _rollupPluginBabelHelpers._extends({}, options, getOptionsForCustomQuery(this.$defaultQuery));
// Update calculated default query in store
index.updateDefaultQuery(this.componentId, this.setDefaultQuery, this.$props);
}
// execute is set to false at the time of mount
var query = extractQueryFromCustomQuery(this.$defaultQuery);
var execute = false;
this.setQueryOptions(this.$props.componentId, _rollupPluginBabelHelpers._extends({}, options, this.getAggsQuery()), execute);
if (this.$defaultQuery) {
this.updateQuery({
componentId: this.internalComponent,
query: query
}, execute);
} else {
this.updateQuery({
componentId: this.internalComponent,
query: null
}, execute);
} // query will be executed here
if (this.showInfiniteScroll) {
window.addEventListener('scroll', this.scrollHandler);
}
},
beforeUnmount: function beforeUnmount() {
if (this.showInfiniteScroll) {
window.removeEventListener('scroll', this.scrollHandler);
}
},
render: function render() {
var _this2 = this;
var hits = this.$data.hits;
var results = parseHits(hits) || [];
return vue.createVNode("div", {
"style": this.$props.style,
"class": this.$props.className
}, [this.isLoading && this.shouldRenderPagination && this.showInfiniteScroll && (this.$slots.loader || this.$props.loader), this.renderErrorComponent(), vue.createVNode(Flex.Flex, {
"labelPosition": this.sortOptions ? 'right' : 'left',
"class": getClassName(this.$props.innerClass, 'resultsInfo')
}, {
"default": function _default() {
return [_this2.sortOptions ? _this2.renderSortOptions() : null, _this2.$props.showResultStats && results.length ? _this2.renderStats() : null];
}
}), !this.isLoading && hits && hits.length === 0 ? this.renderNoResult() : null, this.shouldRenderPagination && (this.$props.paginationAt === 'top' || this.$props.paginationAt === 'both') ? vue.createVNode(Pagination.Pagination, {
"pages": this.$props.pages,
"totalPages": this.totalPages,
"currentPage": this.currentPageState,
"setPage": this.setPage,
"innerClass": this.$props.innerClass,
"prevLabel": this.$props.prevLabel,
"nextLabel": this.$props.nextLabel
}, null) : null, this.renderResults(), this.isLoading && !this.shouldRenderPagination ? this.$slots.loader || this.$props.loader || vue.createVNode("div", {
"style": {
textAlign: 'center',
margin: '20px 0',
color: '#666'
}
}, [vue.createTextVNode("Loading...")]) : null, this.shouldRenderPagination && (this.$props.paginationAt === 'bottom' || this.$props.paginationAt === 'both') ? vue.createVNode(Pagination.Pagination, {
"pages": this.$props.pages,
"totalPages": Math.ceil(this.$data.total / this.$props.size),
"currentPage": this.currentPageState,
"setPage": this.setPage,
"showEndPage": this.$props.showEndPage,
"innerClass": this.$props.innerClass,
"prevLabel": this.$props.prevLabel,
"nextLabel": this.$props.nextLabel
}, null) : null, this.url.endsWith('appbase.io') && results.length ? vue.createVNode(Flex.Flex, {
"direction": "row-reverse",
"class": getClassName(this.$props.innerClass, 'poweredBy')
}, {
"default": function _default() {
return [vue.createVNode(PoweredBy, null, null)];
}
}) : null]);
},
methods: {
renderErrorComponent: function renderErrorComponent() {
var renderError = this.$slots.renderError || this.$props.renderError;
if (renderError && this.error && !this.isLoading) {
return index.isFunction(renderError) ? renderError(this.error) : renderError;
}
return null;
},
renderResults: function renderResults() {
var _this3 = this;
var size = this.$props.size;
var renderItem = this.$slots.renderItem || this.$props.renderItem;
var element = this.hasCustomRender ? this.getComponent() : vue.createVNode("div", {
"class": this.$props.listClass + " " + getClassName(this.$props.innerClass, 'list')
}, [this.data.map(function (item, index) {
return renderItem({
item: item,
count: _this3.currentPageState * size + index + 1,
triggerClickAnalytics: function triggerClickAnalytics() {
return _this3.triggerClickAnalytics(_this3.currentPageState * size + index);
}
});
})]);
// If analytics is set to true then render with impression tracker
return this.analytics ? vue.createVNode(ImpressionTracker$1, {
"hits": this.data
}, _isSlot(element) ? element : {
"default": function _default() {
return [element];
}
}) : element;
},
updateQueryOptions: function updateQueryOptions(props) {
var options = getQueryOptions(props);
options.from = this.$data.from;
if (props.sortOptions && Array.isArray(props.sortOptions)) {
var sortOptionIndex = props.defaultSortOption ? props.sortOptions.findIndex(function (s) {
return s.label === props.defaultSortOption;
}) : 0;
if (props.sortOptions[sortOptionIndex]) {
var _ref3;
options.sort = [(_ref3 = {}, _ref3[props.sortOptions[sortOptionIndex].dataField] = {
order: props.sortOptions[sortOptionIndex].sortBy
}, _ref3)];
}
} else if (props.sortBy) {
var _ref4;
options.sort = [(_ref4 = {}, _ref4[props.dataField] = {
order: props.sortBy
}, _ref4)];
}
this.setQueryOptions(this.$props.componentId, _rollupPluginBabelHelpers._extends({}, options, this.getAggsQuery()), true);
},
getAggsQuery: function getAggsQuery() {
var _this$$props = this.$props,
size = _this$$props.size,
aggregationField = _this$$props.aggregationField;
var afterKey = this.$data.afterKey;
var queryOptions = {
size: size
};
if (aggregationField) {
queryOptions.aggs = getCompositeAggsQuery({
props: this.$props,
after: afterKey || null,
showTopHits: true
}).aggs;
}
return queryOptions;
},
scrollHandler: function scrollHandler() {
if (!this.isLoading && window.innerHeight + window.pageYOffset + 300 >= document.body.scrollHeight) {
this.loadMore();
}
},
loadMore: function loadMore() {
if (this.aggregationField && !this.afterKey) return;
if (this.hits && !this.shouldRenderPagination && this.total > this.hits.length) {
var value = this.$data.from + this.$props.size;
// If current hits length is less than the current from then it means
// that there are no results present.
// It can happen because of many reasons some of them are:
// 1. Using the `collapse` query to remove results
// 2. Shard failure
// In above cases infinite scroll should not load more results that can
// cause the resetting of the `from` value
if (this.hits.length < value) {
return;
}
var options = _rollupPluginBabelHelpers._extends({}, getQueryOptions(this.$props), this.getAggsQuery());
this.from = value;
// Update default query to support pagination for aggregationField
index.updateDefaultQuery(this.componentId, this.setDefaultQuery, this.$props);
this.loadMoreAction(this.$props.componentId, _rollupPluginBabelHelpers._extends({}, options, {
from: value
}), true, !!this.aggregationField);
}
},
setPage: function setPage(page) {
// pageClick will be called every time a pagination button is clicked
if (page !== this.currentPageState) {
this.$emit('pageClick', page + 1);
this.$emit('page-click', page + 1);
var value = this.$props.size * page;
var options = getQueryOptions(this.$props);
options.from = this.$data.from;
this.from = value;
this.currentPageState = page;
this.loadMoreAction(this.$props.componentId, _rollupPluginBabelHelpers._extends({}, options, {
from: value
}), false);
this.setPageURL(this.$props.componentId, page + 1, this.$props.componentId, false, this.URLParams);
}
},
renderStats: function renderStats() {
var renderResultStats = this.$slots.renderResultStats || this.$props.renderResultStats;
if (renderResultStats && this.$data.total) {
return renderResultStats(this.stats);
}
if (this.stats.numberOfResults) {
return vue.createVNode("p", {
"class": resultStats + " " + getClassName(this.$props.innerClass, 'resultStats')
}, [this.stats.numberOfResults, vue.createTextVNode(" results found in "), this.stats.time || 0, vue.createTextVNode("ms")]);
}
return null;
},
renderNoResult: function renderNoResult() {
var renderNoResults = this.$slots.renderNoResults || this.$props.renderNoResults;
if (this.$slots.renderNoResults) {
return index.isFunction(renderNoResults) ? renderNoResults() : renderNoResults;
}
return vue.createVNode("p", {
"class": getClassName(this.$props.innerClass, 'noResults') || null
}, [index.isFunction(renderNoResults) ? renderNoResults() : renderNoResults]);
},
handleSortChange: function handleSortChange(e) {
var index = e.target.value;
if (this.sortOptions && this.sortOptions[index]) {
var _ref5;
// This fixes issue #371 (where sorting a multi-result page with infinite loader breaks)
var options = getQueryOptions(this.$props);
options.from = 0;
var sortField = this.sortOptions[index].dataField;
var sortBy = this.sortOptions[index].sortBy;
options.sort = [(_ref5 = {}, _ref5[sortField] = {
order: sortBy
}, _ref5)];
this.sortOptionIndex = index;
// To handle sort options for RS API
this.updateComponentProps(this.componentId, {
dataField: sortField,
sortBy: sortBy
}, constants.componentTypes.reactiveList);
this.setQueryOptions(this.$props.componentId, options, true);
this.setPage(0);
this.currentPageState = 0;
this.from = 0;
var sortOption = this.$props.sortOptions[this.sortOptionIndex] ? this.$props.sortOptions[this.sortOptionIndex].label : null;
this.setPageURL(this.$props.componentId + "sortOption", sortOption, this.$props.componentId + "sortOption", false, this.$props.URLParams);
}
},
triggerClickAnalytics: function triggerClickAnalytics(searchPosition, documentId) {
var docId = documentId;
if (!docId) {
var _this$getData = this.getData(),
data = _this$getData.data;
var hitData = data.find(function (hit) {
return hit._click_id === searchPosition;
});
if (hitData && hitData._id) {
docId = hitData._id;
}
}
this.recordResultClick(searchPosition, docId);
},
renderSortOptions: function renderSortOptions() {
return vue.createVNode("select", vue.mergeProps(_transformOn({
change: this.handleSortChange
}), {
"class": sortOptions + " " + getClassName(this.$props.innerClass, 'sortOptions'),
"name": "sort-options",
"aria-label": "Sort options",
"value": this.sortOptionIndex
}), [this.sortOptions.map(function (sort, index) {
return vue.createVNode("option", {
"key": sort.label,
"value": index
}, [sort.label]);
})]);
},
withClickIds: function withClickIds(results) {
var _this$getAllData = this.getAllData(),
base = _this$getAllData.base;
return results.map(function (result, index) {
return _rollupPluginBabelHelpers._extends({}, result, {
_click_id: base + index
});
});
},
// Shape of the object to be returned in onData & render
getAllData: function getAllData() {
var size = this.size,
promotedResults = this.promotedResults,
aggregationData = this.aggregationData,
customData = this.customData,
currentPage = this.currentPage,
hits = this.hits;
var results = parseHits(hits) || [];
var parsedPromotedResults = parseHits(promotedResults) || [];
var base = currentPage * size;
return {
results: results,
customData: customData || {},
promotedResults: parsedPromotedResults,
aggregationData: aggregationData,
loadMore: this.loadMore,
base: base,
triggerClickAnalytics: this.triggerClickAnalytics
};
},
getData: function getData() {
var _this$getAllData2 = this.getAllData(),
promotedResults = _this$getAllData2.promotedResults,
aggregationData = _this$getAllData2.aggregationData,
customData = _this$getAllData2.customData;
return {
data: this.data,
aggregationData: this.withClickIds(aggregationData || []),
promotedData: this.withClickIds(promotedResults || []),
rawData: this.rawData,
resultStats: this.stats,
customData: customData
};
},
getComponent: function getComponent() {
var error = this.error,
isLoading = this.isLoading;
var data = _rollupPluginBabelHelpers._extends({
error: error,
loading: isLoading || false,
loadMore: this.loadMore,
triggerClickAnalytics: this.triggerClickAnalytics,
setPage: this.setPage
}, this.getData());
return index.getComponent(data, this);
}
}
};
var mapStateToProps = function mapStateToProps(state, props) {
return {
defaultPage: state.selectedValues[props.componentId] && state.selectedValues[props.componentId].value - 1,
urlSortOption: state.selectedValues[props.componentId + "sortOption"] && state.selectedValues[props.componentId + "sortOption"].value,
hits: state.hits[props.componentId] && state.hits[props.componentId].hits,
rawData: state.rawData[props.componentId],
aggregationData: state.compositeAggregations[props.componentId],
promotedResults: state.promotedResults[props.componentId],
customData: state.customData[props.componentId],
time: state.hits[props.componentId] && state.hits[props.componentId].time,
total: state.hits[props.componentId] && state.hits[props.componentId].total,
hidden: state.hits[props.componentId] && state.hits[props.componentId].hidden,
analytics: state.config && state.config.analytics,
url: state.config.url,
error: state.error[props.componentId],
afterKey: state.aggregations[props.componentId] && state.aggregations[props.componentId][props.aggregationField] && state.aggregations[props.componentId][props.aggregationField].after_key,
componentProps: state.props[props.componentId],
isLoading: state.isLoading[props.componentId]
};
};
var mapDispatchtoProps = {
loadMoreAction: loadMore,
setPageURL: setValue,
setQueryOptions: setQueryOptions,
updateQuery: updateQuery,
updateComponentProps: updateComponentProps,
setDefaultQuery: setDefaultQuery,
recordResultClick: recordResultClick
};
// Only used for SSR
ReactiveList.generateQueryOptions = function (props) {
var options = getQueryOptions(props);
var size = props.size,
dataField = props.dataField,
defaultSortOption = props.defaultSortOption,
sortOptionsNew = props.sortOptions,
currentPage = props.currentPage,
sortBy = props.sortBy;
options.from = currentPage ? (currentPage - 1) * (size || 10) : 0;
options.size = size || 10;
var getSortOption = function getSortOption() {
var _ref7;
if (defaultSortOption) {
var sortOption = sortOptionsNew.find(function (option) {
return option.label === defaultSortOption;
});
if (sortOption) {
var _ref6;
return _ref6 = {}, _ref6[sortOption.dataField] = {
order: sortOption.sortBy
}, _ref6;
}
}
return _ref7 = {}, _ref7[sortOptionsNew[0].dataField] = {
order: sortOptionsNew[0].sortBy
}, _ref7;
};
if (sortOptionsNew) {
options.sort = [getSortOption()];
} else if (sortBy) {
var _ref8;
options.sort = [(_ref8 = {}, _ref8[dataField] = {
order: sortBy
}, _ref8)];
}
return options;
};
ReactiveList.hasInternalComponent = function () {
return true;
};
var RLConnected = PreferencesConsumer.PreferencesConsumer(ComponentWrapper.ComponentWrapper(index.connect(mapStateToProps, mapDispatchtoProps)(ReactiveList), {
componentType: constants.componentTypes.reactiveList,
internalComponent: ReactiveList.hasInternalComponent()
}));
RLConnected.name = ReactiveList.name;
RLConnected.generateQueryOptions = ReactiveList.generateQueryOptions;
RLConnected.hasInternalComponent = ReactiveList.hasInternalComponent;
RLConnected.install = function (Vue) {
Vue.component(RLConnected.name, RLConnected);
Vue.component(ResultListWrapper.name, ResultListWrapper);
Vue.component(ResultCardsWrapper.name, ResultCardsWrapper);
};
// Add componentType for SSR
RLConnected.componentType = constants.componentTypes.reactiveList;
exports.RLConnected = RLConnected;
exports.default = RLConnected;