UNPKG

@gooddata/react-components

Version:

GoodData.UI - A powerful JavaScript library for building analytical applications

312 lines • 15.1 kB
"use strict"; 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