@atlaskit/dynamic-table
Version:
A dynamic table displays rows of data with built-in pagination, sorting, and re-ordering functionality.
285 lines (281 loc) • 12.2 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = _interopRequireWildcard(require("react"));
var _usePlatformLeafEventHandler = require("@atlaskit/analytics-next/usePlatformLeafEventHandler");
var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
var _assertIsSortable = require("../internal/assert-is-sortable");
var _getPageRows = require("../internal/get-page-rows");
var _validateSortKey = require("../internal/validate-sort-key");
var _caption = require("../styled/caption");
var _emptyViewContainer = require("../styled/empty-view-container");
var _emptyViewWithFixedHeight = require("../styled/empty-view-with-fixed-height");
var _paginationWrapper = require("../styled/pagination-wrapper");
var _table = require("../styled/table");
var _body = _interopRequireDefault(require("./body"));
var _errorBoundary = require("./error-boundary");
var _loadingContainer = _interopRequireDefault(require("./loading-container"));
var _loadingContainerAdvanced = _interopRequireDefault(require("./loading-container-advanced"));
var _managedPagination = _interopRequireDefault(require("./managed-pagination"));
var _tableHead = _interopRequireDefault(require("./table-head"));
var _excluded = ["isRankable", "isRanking", "onRankStart", "onRankEnd", "isRankingDisabled"];
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
function toggleSortOrder(currentSortOrder) {
switch (currentSortOrder) {
case 'DESC':
return 'ASC';
case 'ASC':
return 'DESC';
default:
return currentSortOrder;
}
}
var DynamicTable = function DynamicTable(_ref) {
var caption = _ref.caption,
head = _ref.head,
highlightedRowIndex = _ref.highlightedRowIndex,
rows = _ref.rows,
sortKey = _ref.sortKey,
sortOrder = _ref.sortOrder,
loadingLabel = _ref.loadingLabel,
onPageRowsUpdate = _ref.onPageRowsUpdate,
testId = _ref.testId,
passedDownTotalRows = _ref.totalRows,
label = _ref.label,
_ref$isLoading = _ref.isLoading,
isLoading = _ref$isLoading === void 0 ? false : _ref$isLoading,
_ref$isFixedSize = _ref.isFixedSize,
isFixedSize = _ref$isFixedSize === void 0 ? false : _ref$isFixedSize,
_ref$rowsPerPage = _ref.rowsPerPage,
rowsPerPage = _ref$rowsPerPage === void 0 ? Infinity : _ref$rowsPerPage,
_ref$onSetPage = _ref.onSetPage,
onSetPage = _ref$onSetPage === void 0 ? _noop.default : _ref$onSetPage,
_ref$onSort = _ref.onSort,
providedOnSort = _ref$onSort === void 0 ? _noop.default : _ref$onSort,
_ref$page = _ref.page,
page = _ref$page === void 0 ? 1 : _ref$page,
emptyView = _ref.emptyView,
_ref$isRankable = _ref.isRankable,
isRankable = _ref$isRankable === void 0 ? false : _ref$isRankable,
_ref$isRankingDisable = _ref.isRankingDisabled,
isRankingDisabled = _ref$isRankingDisable === void 0 ? false : _ref$isRankingDisable,
_ref$onRankStart = _ref.onRankStart,
onRankStart = _ref$onRankStart === void 0 ? _noop.default : _ref$onRankStart,
_ref$onRankEnd = _ref.onRankEnd,
providedOnRankEnd = _ref$onRankEnd === void 0 ? _noop.default : _ref$onRankEnd,
loadingSpinnerSize = _ref.loadingSpinnerSize,
_ref$paginationi18n = _ref.paginationi18n,
paginationi18n = _ref$paginationi18n === void 0 ? {
prev: 'Previous Page',
next: 'Next Page',
label: 'Pagination',
pageLabel: 'Page'
} : _ref$paginationi18n;
var _useState = (0, _react.useState)(false),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
isRanking = _useState2[0],
setIsRanking = _useState2[1];
var tableBodyRef = (0, _react.useRef)(null);
var onSort = (0, _usePlatformLeafEventHandler.usePlatformLeafEventHandler)({
fn: providedOnSort,
action: 'sorted',
componentName: 'dynamicTable',
packageName: "@atlaskit/dynamic-table",
packageVersion: "19.3.3"
});
var onRankEnd = (0, _usePlatformLeafEventHandler.usePlatformLeafEventHandler)({
fn: providedOnRankEnd,
action: 'ranked',
componentName: 'dynamicTable',
packageName: "@atlaskit/dynamic-table",
packageVersion: "19.3.3"
});
(0, _react.useEffect)(function () {
(0, _validateSortKey.validateSortKey)(sortKey, head);
(0, _assertIsSortable.assertIsSortable)(head);
}, [sortKey, head]);
var onSortHandler = function onSortHandler(item) {
return function () {
var key = item.key;
if (!key) {
return;
}
if (onSort && isRankable && key === sortKey && sortOrder === 'DESC') {
onSort({
key: null,
sortOrder: null,
item: item
});
return;
}
var sortOrderFormatted = key !== sortKey ? 'ASC' : toggleSortOrder(sortOrder);
if (onSort) {
onSort({
key: key,
item: item,
sortOrder: sortOrderFormatted
});
}
};
};
var onSetPageHandler = function onSetPageHandler(page, event) {
onSetPage(page, event);
};
var onRankStartHandler = function onRankStartHandler(params) {
setIsRanking(true);
onRankStart(params);
};
var onRankEndHandler = function onRankEndHandler(params) {
setIsRanking(false);
onRankEnd(params);
};
var getSpinnerSize = function getSpinnerSize() {
if (loadingSpinnerSize) {
return loadingSpinnerSize;
}
return (0, _getPageRows.getPageRows)(rows || [], page, rowsPerPage).length > 2 ? 'large' : 'small';
};
var renderEmptyBody = function renderEmptyBody() {
if (isLoading) {
return /*#__PURE__*/_react.default.createElement(_emptyViewWithFixedHeight.EmptyViewWithFixedHeight, {
testId: testId
});
}
return emptyView && /*#__PURE__*/_react.default.createElement(_emptyViewContainer.EmptyViewContainer, {
testId: testId
}, emptyView);
};
var rowsLength = rows && rows.length;
var totalPages;
// set a flag to denote the dynamic table might get only one page of data
// for paginated data
var isTotalPagesControlledExternally = false;
if (passedDownTotalRows && Number.isInteger(passedDownTotalRows) && rowsPerPage && rowsLength && rowsLength <= passedDownTotalRows) {
/**
* If total number of rows / records have been passed down as prop
* Then table is being fed paginated data from server or other sources
* In this case, we want to respect information passed down by server or external source
* Rather than relying on our computation based on number of rows
*/
totalPages = Math.ceil(passedDownTotalRows / rowsPerPage);
isTotalPagesControlledExternally = true;
} else {
totalPages = rowsLength && rowsPerPage ? Math.ceil(rowsLength / rowsPerPage) : 0;
}
totalPages = totalPages < 1 ? 1 : totalPages;
var getPageNumber = page > totalPages ? totalPages : page; // page! required, because typescript can't yet see defaultProps to know that this won't be undefined
var rowsExist = !!rowsLength;
var spinnerSize = getSpinnerSize();
var emptyBody = renderEmptyBody();
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_loadingContainerAdvanced.default, {
isLoading: isLoading && rowsExist,
spinnerSize: spinnerSize,
targetRef: function targetRef() {
return tableBodyRef.current;
},
testId: testId,
loadingLabel: loadingLabel
}, /*#__PURE__*/_react.default.createElement(_table.Table, {
isFixedSize: isFixedSize,
"aria-label": label,
hasDataRow: rowsExist,
testId: testId,
isLoading: isLoading
}, !!caption && /*#__PURE__*/_react.default.createElement(_caption.Caption, null, caption), head && /*#__PURE__*/_react.default.createElement(_tableHead.default, {
head: head,
onSort: onSortHandler,
sortKey: sortKey,
sortOrder: sortOrder,
isRanking: isRanking,
isRankable: isRankable,
isFixedSize: isFixedSize,
testId: testId
}), rowsExist && /*#__PURE__*/_react.default.createElement(TableBody, {
ref: tableBodyRef,
highlightedRowIndex: highlightedRowIndex,
rows: rows,
head: head,
sortKey: sortKey,
sortOrder: sortOrder,
rowsPerPage: rowsPerPage,
page: getPageNumber,
isFixedSize: isFixedSize || false,
onPageRowsUpdate: onPageRowsUpdate,
isTotalPagesControlledExternally: isTotalPagesControlledExternally,
testId: testId,
isRankable: isRankable,
isRanking: isRanking,
onRankStart: onRankStartHandler,
onRankEnd: onRankEndHandler,
isRankingDisabled: isRankingDisabled || isLoading || false
}))), totalPages <= 1 ? null :
/*#__PURE__*/
// only show pagination if there's MORE than 1 page
_react.default.createElement(_paginationWrapper.PaginationWrapper, {
testId: testId
}, /*#__PURE__*/_react.default.createElement(_managedPagination.default, {
value: getPageNumber,
onChange: onSetPageHandler,
total: totalPages,
i18n: paginationi18n,
isDisabled: isLoading,
testId: testId
})), !rowsExist && emptyBody && /*#__PURE__*/_react.default.createElement(_loadingContainer.default, {
isLoading: isLoading,
spinnerSize: "large",
testId: testId,
loadingLabel: loadingLabel
}, emptyBody));
};
var RankableTableBody = /*#__PURE__*/(0, _react.lazy)(function () {
return Promise.resolve().then(function () {
return _interopRequireWildcard(require( /* webpackChunkName: '@atlaskit-internal_dynamic-table' */'./rankable/body'));
});
});
var TableBody = /*#__PURE__*/(0, _react.forwardRef)(function TableBody(_ref2, ref) {
var _ref2$isRankable = _ref2.isRankable,
isRankable = _ref2$isRankable === void 0 ? false : _ref2$isRankable,
isRanking = _ref2.isRanking,
onRankStart = _ref2.onRankStart,
onRankEnd = _ref2.onRankEnd,
isRankingDisabled = _ref2.isRankingDisabled,
bodyProps = (0, _objectWithoutProperties2.default)(_ref2, _excluded);
var canRank = isRankable && !bodyProps.sortKey;
/**
* React 16 does not support SSR for lazy components,
* so we avoid rendering the `Suspense` on the server.
*/
var _useState3 = (0, _react.useState)(false),
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
canRenderRankable = _useState4[0],
setCanRenderRankable = _useState4[1];
(0, _react.useEffect)(function () {
if (canRank) {
setCanRenderRankable(true);
}
}, [canRank]);
var nonRankableBody = /*#__PURE__*/_react.default.createElement(_body.default, (0, _extends2.default)({
ref: ref
}, bodyProps));
return canRank && canRenderRankable ? /*#__PURE__*/_react.default.createElement(_errorBoundary.ErrorBoundary, {
fallback: nonRankableBody
}, /*#__PURE__*/_react.default.createElement(_react.Suspense, {
fallback: nonRankableBody
}, /*#__PURE__*/_react.default.createElement(RankableTableBody, (0, _extends2.default)({
ref: ref
}, bodyProps, {
isRanking: isRanking,
onRankStart: onRankStart,
onRankEnd: onRankEnd,
isRankingDisabled: isRankingDisabled
})))) : nonRankableBody;
});
// eslint-disable-next-line @repo/internal/react/require-jsdoc
var _default = exports.default = DynamicTable;