@gooddata/react-components
Version:
GoodData.UI - A powerful JavaScript library for building analytical applications
312 lines • 15.1 kB
JavaScript
;
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
// (C) 2007-2020 GoodData Corporation
var React = require("react");
var PropTypes = require("prop-types");
var InvertableList_1 = require("@gooddata/goodstrap/lib/List/InvertableList");
var Button_1 = require("@gooddata/goodstrap/lib/Button/Button");
var Dropdown_1 = require("@gooddata/goodstrap/lib/Dropdown/Dropdown");
var LoadingMask_1 = require("@gooddata/goodstrap/lib/core/LoadingMask");
var js_utils_1 = require("@gooddata/js-utils");
var DataSource_1 = require("@gooddata/goodstrap/lib/DataSource/DataSource");
var react_intl_1 = require("react-intl");
var classNames = require("classnames");
var last = require("lodash/last");
var pick = require("lodash/pick");
var range = require("lodash/range");
var isEqual = require("lodash/isEqual");
var debounce = require("lodash/debounce");
var noop = require("lodash/noop");
var cloneDeep = require("lodash/cloneDeep");
var isEmpty = require("lodash/isEmpty");
var AttributeFilterItem_1 = require("./AttributeFilterItem");
var ITEM_HEIGHT = 28;
var LIST_WIDTH = 240;
var MAX_SELECTION_SIZE = 500;
exports.VISIBLE_ITEMS_COUNT = 10;
var LIMIT = MAX_SELECTION_SIZE + 50;
var INITIAL_OFFSET = 0;
var getLoadingClass = function () { return React.createElement(LoadingMask_1.default, { style: { height: 306 } }); };
var getDefaultListError = function (_listError, _a) {
var intl = _a.intl;
var text = intl.formatMessage({ id: "gs.list.error" });
return React.createElement("div", { className: "gd-message error" }, text);
};
function getObjectIdFromUri(uri) {
return last(uri.split("/"));
}
exports.getObjectIdFromUri = getObjectIdFromUri;
function getProjectIdFromUri(uri) {
return uri.split("/")[3];
}
exports.getProjectIdFromUri = getProjectIdFromUri;
function loadAttributeElements(metadata, uri, searchString, offset, limit) {
if (offset === void 0) { offset = INITIAL_OFFSET; }
if (limit === void 0) { limit = LIMIT; }
var encodedSearchString = encodeURIComponent(searchString);
var projectId = getProjectIdFromUri(uri);
var objectId = getObjectIdFromUri(uri);
var options = {
limit: limit,
offset: offset,
filter: encodedSearchString,
includeTotalCountWithoutFilters: true,
};
return metadata.getValidElements(projectId, objectId, options).then(function (res) {
var _a = res.validElements, items = _a.items, total = _a.paging.total, totalCountWithoutFilters = _a.totalCountWithoutFilters;
return {
data: {
offset: offset,
limit: limit,
items: items.map(function (item) { return pick(item.element, "uri", "title"); }),
totalCount: total,
totalCountWithoutFilters: totalCountWithoutFilters,
},
};
});
}
exports.loadAttributeElements = loadAttributeElements;
var AttributeDropdownWrapped = /** @class */ (function (_super) {
__extends(AttributeDropdownWrapped, _super);
function AttributeDropdownWrapped(props) {
var _this = _super.call(this, props) || this;
_this.onSearch = function (searchString) {
_this.setState({
searchString: searchString,
isListReady: false,
}, function () {
_this.dataSource.getData({});
});
};
_this.backupSelection = function (callback) {
if (callback === void 0) { callback = noop; }
var _a = _this.state, selection = _a.selection, isInverted = _a.isInverted;
_this.setState({
prevSelection: selection,
wasInverted: isInverted,
}, callback);
};
_this.restoreSelection = function () {
var _a = _this.state, prevSelection = _a.prevSelection, wasInverted = _a.wasInverted;
_this.setState({
selection: prevSelection,
isInverted: wasInverted,
});
};
_this.resetSearchString = function () {
var searchString = _this.state.searchString;
if (searchString) {
_this.setState({
searchString: "",
isListReady: false,
});
}
};
_this.onApply = function () {
var _a = _this.state, selection = _a.selection, isInverted = _a.isInverted;
_this.props.onApply(selection, isInverted);
_this.resetSearchString();
_this.backupSelection(function () { return _this.dropdownRef.closeDropdown(); });
};
_this.onCancel = function () {
_this.restoreSelection();
_this.resetSearchString();
_this.dropdownRef.closeDropdown();
};
_this.getAttributeElements = function (uri) { return function (query) {
var _a = query.paging, _b = _a === void 0 ? {} : _a, _c = _b.offset, offset = _c === void 0 ? 0 : _c, _d = _b.limit, limit = _d === void 0 ? LIMIT : _d;
var metadata = _this.props.metadata;
var searchString = _this.state.searchString;
return loadAttributeElements(metadata, uri, searchString, offset, limit).catch(function (error) {
_this.setState({
isListInitialising: false,
isListReady: false,
listError: error,
});
throw error;
});
}; };
_this.updateSelectionByData = function (selection, items) {
return selection.map(function (selectedItem) {
var foundItem = items.find(function (item) {
return (selectedItem.uri && item.uri === selectedItem.uri) ||
(selectedItem.title && item.title === selectedItem.title);
});
return foundItem || selectedItem;
});
};
_this.onSelect = function (selection, isInverted) {
_this.setState({
selection: selection,
isInverted: isInverted,
});
};
_this.onRangeChange = function (_searchString, from, to) {
range(from, to).forEach(_this.dataSource.getRowAt);
};
_this.onDropdownToggle = function (isDropdownOpen) {
var _a = _this.state, isListReady = _a.isListReady, isListInitialising = _a.isListInitialising;
var attributeDisplayForm = _this.props.attributeDisplayForm;
if (isDropdownOpen && !isListReady && !isListInitialising) {
_this.setupDataSource(attributeDisplayForm.meta.uri);
}
if (isDropdownOpen) {
_this.backupSelection();
}
else {
_this.restoreSelection();
_this.resetSearchString();
_this.dataSource.getData({});
}
};
_this.state = {
isListInitialising: false,
isListReady: false,
listError: null,
items: [],
selection: props.selection || [],
prevSelection: null,
isInverted: props.isInverted !== undefined ? props.isInverted : !props.selection.length,
wasInverted: null,
searchString: "",
};
_this.createMediaQuery(props.fullscreenOnMobile);
_this.onSearch = debounce(_this.onSearch, 250);
return _this;
}
AttributeDropdownWrapped.prototype.componentWillReceiveProps = function (nextProps) {
if (!isEqual(nextProps.attributeDisplayForm, this.props.attributeDisplayForm)) {
this.setupDataSource(nextProps.attributeDisplayForm.meta.uri);
}
if (this.props.fullscreenOnMobile !== nextProps.fullscreenOnMobile) {
this.createMediaQuery(nextProps.fullscreenOnMobile);
}
};
AttributeDropdownWrapped.prototype.render = function () {
var _this = this;
var _a = this.props, attribute = _a.attribute, title = _a.title;
var classes = classNames("gd-attribute-filter", attribute ? "gd-id-" + js_utils_1.string.simplifyText(attribute.meta.title) : "");
return (React.createElement(Dropdown_1.default, { button: React.createElement(Dropdown_1.DropdownButton, { value: title || attribute.meta.title }), ref: function (ref) { return (_this.dropdownRef = ref); }, body: this.renderList(), className: classes, onOpenStateChanged: this.onDropdownToggle, MediaQuery: this.MediaQuery }));
};
AttributeDropdownWrapped.prototype.createMediaQuery = function (fullscreenOnMobile) {
this.MediaQuery = fullscreenOnMobile
? undefined
: function (_a) {
var children = _a.children;
return children(false);
};
};
AttributeDropdownWrapped.prototype.setupDataSource = function (uri) {
var _this = this;
var request = this.getAttributeElements(uri);
this.setState({
searchString: "",
isListInitialising: true,
listError: null,
});
this.dataSource = new DataSource_1.default(request, request, {
pageSize: LIMIT,
});
this.dataSource.onChange(function (result) {
var _a = _this.state, selection = _a.selection, prevSelection = _a.prevSelection;
var items = result.data.items.map(function (i) { return i || { empty: true }; });
var updatedSelection = _this.updateSelectionByData(selection, items);
var updatedPrevSelection = _this.updateSelectionByData(prevSelection, items);
_this.setState({
totalCount: result.data.totalCountWithoutFilters,
filteredItemsCount: result.data.totalCount,
isListReady: true,
listError: null,
items: _this.emptyValueItem(items),
selection: updatedSelection,
prevSelection: updatedPrevSelection,
isListInitialising: false,
});
});
this.dataSource.getData({});
};
AttributeDropdownWrapped.prototype.getListWidth = function () {
var _a = this.props, isMobile = _a.isMobile, fullscreenOnMobile = _a.fullscreenOnMobile;
return fullscreenOnMobile && isMobile ? undefined : LIST_WIDTH;
};
AttributeDropdownWrapped.prototype.renderOverlayWrap = function (overlayContent, applyDisabled) {
if (applyDisabled === void 0) { applyDisabled = false; }
return (React.createElement("div", { className: "gd-attribute-filter-overlay", style: { minWidth: this.getListWidth() } },
overlayContent,
this.renderButtons(applyDisabled)));
};
AttributeDropdownWrapped.prototype.emptyValueItem = function (item) {
var _this = this;
var itemClone = cloneDeep(item);
itemClone.forEach(function (item) {
if (isEmpty(item.title)) {
item.title = _this.props.emptyHeaderString;
}
});
return itemClone;
};
AttributeDropdownWrapped.prototype.getItemKey = function (item) {
return item.uri;
};
AttributeDropdownWrapped.prototype.renderList = function () {
var _a = this.state, isListReady = _a.isListReady, items = _a.items, selection = _a.selection, listError = _a.listError, totalCount = _a.totalCount, searchString = _a.searchString, filteredItemsCount = _a.filteredItemsCount;
var getListError = this.props.getListError;
if (listError) {
return this.renderOverlayWrap(getListError(listError, this.props, this.state), true);
}
return this.renderOverlayWrap(React.createElement(InvertableList_1.default, { items: items, itemsCount: parseInt(totalCount, 10), filteredItemsCount: parseInt(filteredItemsCount, 10), selection: selection, isInverted: this.state.isInverted, showSearchField: true, searchString: searchString, isLoading: !isListReady, isLoadingClass: getLoadingClass, noItemsFound: isListReady && !items.length, rowItem: React.createElement(AttributeFilterItem_1.AttributeFilterItem, null), maxSelectionSize: MAX_SELECTION_SIZE, itemHeight: ITEM_HEIGHT, height: ITEM_HEIGHT * exports.VISIBLE_ITEMS_COUNT, onRangeChange: this.onRangeChange, onSearch: this.onSearch, onSelect: this.onSelect, getItemKey: this.getItemKey }));
};
AttributeDropdownWrapped.prototype.renderButtons = function (applyDisabled) {
var intl = this.props.intl;
var cancelText = intl.formatMessage({ id: "gs.list.cancel" });
var applyText = intl.formatMessage({ id: "gs.list.apply" });
return (React.createElement("div", { className: "gd-attribute-filter-actions" },
React.createElement(Button_1.default, { className: "gd-button-secondary gd-button-small cancel-button s-cancel", onClick: this.onCancel, value: cancelText, title: cancelText }),
React.createElement(Button_1.default, { disabled: applyDisabled, className: "gd-button-action gd-button-small s-apply", onClick: this.onApply, value: applyText, title: applyText })));
};
AttributeDropdownWrapped.propTypes = {
attribute: PropTypes.object.isRequired,
attributeDisplayForm: PropTypes.object.isRequired,
projectId: PropTypes.string,
selection: PropTypes.array,
isInverted: PropTypes.bool,
isMobile: PropTypes.bool,
onApply: PropTypes.func.isRequired,
onApplyWithFilterDefinition: PropTypes.func,
fullscreenOnMobile: PropTypes.bool,
title: PropTypes.string,
getListItem: PropTypes.func,
getListError: PropTypes.func,
numericSymbols: PropTypes.array,
emptyHeaderString: PropTypes.string,
metadata: PropTypes.shape({
getValidElements: PropTypes.func.isRequired,
}).isRequired,
};
AttributeDropdownWrapped.defaultProps = {
fullscreenOnMobile: false,
title: null,
projectId: null,
selection: new Array(),
isMobile: false,
getListItem: function () { return React.createElement(AttributeFilterItem_1.AttributeFilterItem, null); },
getListError: getDefaultListError,
};
return AttributeDropdownWrapped;
}(React.PureComponent));
exports.AttributeDropdownWrapped = AttributeDropdownWrapped;
exports.AttributeDropdown = react_intl_1.injectIntl(AttributeDropdownWrapped);
//# sourceMappingURL=AttributeDropdown.js.map