ra-core
Version:
Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React
151 lines • 7.2 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DataTableBase = void 0;
const React = __importStar(require("react"));
const react_1 = require("react");
const union_js_1 = __importDefault(require("lodash/union.js"));
const difference_js_1 = __importDefault(require("lodash/difference.js"));
const useListContextWithProps_1 = require("../controller/list/useListContextWithProps.cjs");
const core_1 = require("../core/index.cjs");
const util_1 = require("../util/index.cjs");
const DataTableCallbacksContext_1 = require("./DataTableCallbacksContext.cjs");
const DataTableConfigContext_1 = require("./DataTableConfigContext.cjs");
const DataTableDataContext_1 = require("./DataTableDataContext.cjs");
const DataTableSelectedIdsContext_1 = require("./DataTableSelectedIdsContext.cjs");
const DataTableSortContext_1 = require("./DataTableSortContext.cjs");
const DataTableStoreContext_1 = require("./DataTableStoreContext.cjs");
const DataTableBase = function DataTable(props) {
const resourceFromContext = (0, core_1.useResourceContext)(props);
const { children, empty, expand, hiddenColumns = emptyArray, hasBulkActions, hover, loading, isRowSelectable, isRowExpandable, resource, rowClick, expandSingle = false, } = props;
const { sort, data, isPending, onSelect, onToggleItem, selectedIds, setSort, total, } = (0, useListContextWithProps_1.useListContextWithProps)(props);
const storeKey = props.storeKey || `${resourceFromContext}.datatable`;
const handleSort = (0, util_1.useEvent)((event) => {
event.stopPropagation();
if (!setSort)
return;
const newField = event.currentTarget.dataset.field || 'id';
const newOrder = sort?.field === newField
? sort?.order === 'ASC'
? 'DESC'
: 'ASC'
: event.currentTarget.dataset.order || 'ASC';
setSort({ field: newField, order: newOrder });
});
const lastSelected = (0, react_1.useRef)(null);
(0, react_1.useEffect)(() => {
if (!selectedIds || selectedIds.length === 0) {
lastSelected.current = null;
}
}, [JSON.stringify(selectedIds)]); // eslint-disable-line react-hooks/exhaustive-deps
// we manage row selection here instead of in the rows level to allow shift+click to select an array of rows
const handleToggleItem = (0, util_1.useEvent)((id, event) => {
if (!data)
return;
const ids = data.map(record => record.id);
const lastSelectedIndex = ids.indexOf(lastSelected.current);
if (event.shiftKey && lastSelectedIndex !== -1) {
const index = ids.indexOf(id);
const idsBetweenSelections = ids.slice(Math.min(lastSelectedIndex, index), Math.max(lastSelectedIndex, index) + 1);
const isClickedItemSelected = selectedIds?.includes(id);
const newSelectedIds = isClickedItemSelected
? (0, difference_js_1.default)(selectedIds, idsBetweenSelections)
: (0, union_js_1.default)(selectedIds, idsBetweenSelections);
onSelect?.(isRowSelectable
? newSelectedIds.filter((id) => isRowSelectable(data.find(record => record.id === id)))
: newSelectedIds);
}
else {
onToggleItem?.(id);
}
lastSelected.current = id;
});
const storeContextValue = (0, react_1.useMemo)(() => ({
storeKey,
defaultHiddenColumns: hiddenColumns,
}), [storeKey, hiddenColumns]);
const configContextValue = (0, react_1.useMemo)(() => ({
expand,
expandSingle,
hasBulkActions,
hover,
}), [expand, expandSingle, hasBulkActions, hover]);
const callbacksContextValue = (0, react_1.useMemo)(() => ({
handleSort: setSort ? handleSort : undefined,
handleToggleItem: onToggleItem ? handleToggleItem : undefined,
isRowExpandable,
isRowSelectable,
onSelect,
rowClick,
}), [
setSort,
handleSort,
handleToggleItem,
isRowExpandable,
isRowSelectable,
onSelect,
onToggleItem,
rowClick,
]);
if (isPending === true) {
return loading;
}
/**
* Once loaded, the data for the list may be empty. Instead of
* displaying the table header with zero data rows,
* the DataTable displays the empty component.
*/
if (data == null || data.length === 0 || total === 0) {
return empty ?? null;
}
/**
* After the initial load, if the data for the list isn't empty,
* and even if the data is refreshing (e.g. after a filter change),
* the DataTable displays the current data.
*/
return (React.createElement(DataTableStoreContext_1.DataTableStoreContext.Provider, { value: storeContextValue },
React.createElement(DataTableSortContext_1.DataTableSortContext.Provider, { value: sort },
React.createElement(DataTableSelectedIdsContext_1.DataTableSelectedIdsContext.Provider, { value: selectedIds },
React.createElement(DataTableCallbacksContext_1.DataTableCallbacksContext.Provider, { value: callbacksContextValue },
React.createElement(DataTableConfigContext_1.DataTableConfigContext.Provider, { value: configContextValue },
React.createElement(core_1.OptionalResourceContextProvider, { value: resource },
React.createElement(DataTableDataContext_1.DataTableDataContext.Provider, { value: data }, children))))))));
};
exports.DataTableBase = DataTableBase;
const emptyArray = [];
//# sourceMappingURL=DataTableBase.js.map