UNPKG

synapse-react-client

Version:

[![Build Status](https://travis-ci.com/Sage-Bionetworks/Synapse-React-Client.svg?branch=main)](https://travis-ci.com/Sage-Bionetworks/Synapse-React-Client) [![npm version](https://badge.fury.io/js/synapse-react-client.svg)](https://badge.fury.io/js/synaps

268 lines 15.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DatasetItemsEditor = void 0; var tslib_1 = require("tslib"); var lab_1 = require("@material-ui/lab"); var react_base_table_1 = (0, tslib_1.__importDefault)(require("@sage-bionetworks/react-base-table")); var react_1 = (0, tslib_1.__importStar)(require("react")); var react_bootstrap_1 = require("react-bootstrap"); var react_tooltip_1 = (0, tslib_1.__importDefault)(require("react-tooltip")); var SkeletonTable_1 = require("../../../assets/skeletons/SkeletonTable"); var TooltipUtils_1 = require("../../../utils/functions/TooltipUtils"); var useEntity_1 = require("../../../utils/hooks/SynapseAPI/useEntity"); var useSet_1 = require("../../../utils/hooks/useSet"); var useTraceUpdate_1 = (0, tslib_1.__importDefault)(require("../../../utils/hooks/useTraceUpdate")); var synapseTypes_1 = require("../../../utils/synapseTypes"); var Typography_1 = (0, tslib_1.__importDefault)(require("../../../utils/typography/Typography")); var EntityBadgeIcons_1 = require("../../EntityBadgeIcons"); var DetailsViewTableRenderers_1 = require("../../entity_finder/details/view/DetailsViewTableRenderers"); var EntityFinderModal_1 = require("../../entity_finder/EntityFinderModal"); var TreeView_1 = require("../../entity_finder/tree/TreeView"); var IconSvg_1 = (0, tslib_1.__importDefault)(require("../../IconSvg")); var WarningModal_1 = (0, tslib_1.__importDefault)(require("../../synapse_form_wrapper/WarningModal")); var ToastMessage_1 = require("../../ToastMessage"); var Checkbox_1 = require("../../widgets/Checkbox"); var ROW_HEIGHT = 42; var TABLE_HEIGHT = 350; function DatasetItemsEditor(props) { var entityId = props.entityId, onSave = props.onSave, onClose = props.onClose; var _a = (0, react_1.useState)(false), showEntityFinder = _a[0], setShowEntityFinder = _a[1]; var _b = (0, react_1.useState)(false), showWarningModal = _b[0], setShowWarningModal = _b[1]; // Disable updating the entity after the initial fetch because we don't want to replace edits that the user makes. var _c = (0, react_1.useState)(), datasetToUpdate = _c[0], _setDatasetToUpdate = _c[1]; var setDatasetToUpdate = function (dataset) { setHasChangedSinceLastSave(true); _setDatasetToUpdate(dataset); }; var _d = (0, react_1.useState)(false), hasChangedSinceLastSave = _d[0], setHasChangedSinceLastSave = _d[1]; var _e = (0, useSet_1.useSet)(), selectedIds = _e.set, addSelectedId = _e.add, removeSelectedId = _e.remove, clearSelectedIds = _e.clear; var allItemsAreSelected = !!(datasetToUpdate && datasetToUpdate.items.length === selectedIds.size); var refetch = (0, useEntity_1.useGetEntity)(entityId, undefined, { enabled: !datasetToUpdate, onSuccess: function (dataset) { // SWC-5876: Dataset Items may be undefined. This has the same inherent meaning as the empty list, so we'll just change it to save us some null checks. if (dataset.items == null) { dataset.items = []; } setDatasetToUpdate(dataset); setHasChangedSinceLastSave(false); }, }).refetch; var mutation = (0, useEntity_1.useUpdateEntity)({ onSuccess: function () { (0, ToastMessage_1.displayToast)('Create a Version of this Dataset to freeze it in its current state', 'success', { title: 'Dataset Saved' }); if (onSave) { onSave(); } }, onError: function (error) { if (error.status === 412) { (0, ToastMessage_1.displayToast)('Re-retrieve the dataset to get the latest changes. Your current changes will be lost.', 'warning', { title: 'Dataset Updated since Last Fetched', primaryButtonText: 'Retrieve Dataset', onPrimaryButtonClick: refetch, }); } else { (0, ToastMessage_1.displayToast)(error.reason, 'danger', { title: 'An Error Occurred', }); } }, }); var tableData = datasetToUpdate === null || datasetToUpdate === void 0 ? void 0 : datasetToUpdate.items.map(function (item) { return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, item), { isSelected: selectedIds.has(item.entityId), setSelected: function (value) { return value ? addSelectedId(item.entityId) : removeSelectedId(item.entityId); } }); }); function addItemsToDataset(newItems) { setDatasetToUpdate(function (datasetToUpdate) { if (datasetToUpdate) { var existingItems = datasetToUpdate.items.filter(function (item) { return !newItems.find(function (newItem) { return newItem.targetId === item.entityId; }); }); if (existingItems.length < datasetToUpdate.items.length) { (0, ToastMessage_1.displayToast)('Files were added that were already in the dataset. The versions of those files might have been updated.', 'info'); } var items = (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], existingItems, true), newItems.map(function (item) { return ({ entityId: item.targetId, versionNumber: item.targetVersionNumber, }); }), true); return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, datasetToUpdate), { items: items }); } else { console.warn('Cannot add items to the Dataset because it is undefined. The Dataset may not have been fetched yet.'); return datasetToUpdate; } }); clearSelectedIds(); } function removeSelectedItemsFromDataset() { setDatasetToUpdate(function (dataset) { return ((0, tslib_1.__assign)((0, tslib_1.__assign)({}, dataset), { items: dataset.items.filter(function (datasetItem) { return !selectedIds.has(datasetItem.entityId); }) })); }); clearSelectedIds(); } function changeVersionOnItem(entityId, newVersion) { setDatasetToUpdate(function (dataset) { return ((0, tslib_1.__assign)((0, tslib_1.__assign)({}, dataset), { items: dataset.items.map(function (datasetItem) { return datasetItem.entityId === entityId ? { entityId: entityId, versionNumber: newVersion } : datasetItem; }) })); }); } var DatasetItemVersionRenderer = function (props) { return (react_1.default.createElement(DetailsViewTableRenderers_1.DatasetEditorVersionRenderer, (0, tslib_1.__assign)({}, props, { toggleSelection: function (datasetItem) { changeVersionOnItem(datasetItem.entityId, datasetItem.versionNumber); } }))); }; var SelectAllCheckboxRenderer = function (props) { var datasetToUpdate = props.datasetToUpdate, clearSelectedIds = props.clearSelectedIds, addSelectedId = props.addSelectedId; (0, useTraceUpdate_1.default)(props); var isChecked = allItemsAreSelected; return datasetToUpdate ? (react_1.default.createElement("div", { "data-testid": "Select All", style: { cursor: 'pointer' }, onClick: function () { if (isChecked) { clearSelectedIds(); } else { addSelectedId.apply(void 0, datasetToUpdate.items.map(function (item) { return item.entityId; })); } } }, react_1.default.createElement(Checkbox_1.Checkbox, { label: "", className: "SRC-pointer-events-none", checked: isChecked, disabled: datasetToUpdate.items.length === 0, onChange: function () { // no-op } }))) : (react_1.default.createElement(react_1.default.Fragment, null)); }; var renderedSelectAllCheckbox = datasetToUpdate ? (react_1.default.createElement(SelectAllCheckboxRenderer, { datasetToUpdate: datasetToUpdate, selectedIds: selectedIds, clearSelectedIds: clearSelectedIds, addSelectedId: addSelectedId, allItemsAreSelected: allItemsAreSelected })) : (react_1.default.createElement(react_1.default.Fragment, null)); var defaultColumns = [ { key: 'errorState', width: 30, cellRenderer: DetailsViewTableRenderers_1.EntityErrorRenderer, }, { key: 'isSelected', width: 40, dataKey: 'isSelected', headerRenderer: renderedSelectAllCheckbox, cellRenderer: DetailsViewTableRenderers_1.DatasetEditorCheckboxRenderer, }, { key: 'name', width: 350, dataKey: 'entityId', title: 'Name', resizable: true, cellRenderer: DetailsViewTableRenderers_1.EntityNameRenderer, }, { key: 'status', width: 80, dataKey: 'entityId', resizable: true, cellRenderer: DetailsViewTableRenderers_1.BadgeIconsRenderer, }, { key: 'id', width: 140, title: 'ID', dataKey: 'entityId', resizable: true, }, { key: 'version', width: 150, title: 'Version', dataKey: 'entityId', cellRenderer: DatasetItemVersionRenderer, }, { key: 'createdOn', width: 200, title: 'Created On', dataKey: 'entityId', resizable: true, cellRenderer: DetailsViewTableRenderers_1.CreatedOnRenderer, }, { key: 'modifiedOn', width: 200, title: 'Modified On', dataKey: 'entityId', resizable: true, cellRenderer: DetailsViewTableRenderers_1.ModifiedOnRenderer, }, { key: 'modifiedBy', width: 250, title: 'Modified By', dataKey: 'entityId', resizable: true, cellRenderer: DetailsViewTableRenderers_1.ModifiedByRenderer, }, { key: 'projectId', width: 300, title: 'Project', dataKey: 'entityId', resizable: true, cellRenderer: DetailsViewTableRenderers_1.ProjectRenderer, }, ]; function NoItemsPlaceholder() { return (react_1.default.createElement("div", { className: "NoItemsPlaceholder" }, react_1.default.createElement(Typography_1.default, { variant: 'headline3' }, "No items in this Dataset"), react_1.default.createElement(react_bootstrap_1.Button, { className: "AddItemsButton", variant: "outline", onClick: function () { return setShowEntityFinder(true); } }, react_1.default.createElement(IconSvg_1.default, { options: { icon: 'addCircleTwoTone' } }), react_1.default.createElement("span", null, "Add Items")))); } return (react_1.default.createElement("div", { className: "DatasetEditor bootstrap-4-backport" }, react_1.default.createElement(EntityFinderModal_1.EntityFinderModal, { configuration: { selectMultiple: true, initialScope: TreeView_1.FinderScope.ALL_PROJECTS, initialContainer: null, selectableTypes: [synapseTypes_1.EntityType.FILE], mustSelectVersionNumber: true, }, show: showEntityFinder, onClose: function () { setShowEntityFinder(false); }, title: "Add Files to Dataset", confirmButtonCopy: "Add Files", onConfirm: function (items) { addItemsToDataset(items); setShowEntityFinder(false); }, onCancel: function () { return setShowEntityFinder(false); } }), react_1.default.createElement(WarningModal_1.default, { title: "Unsaved Changes", modalBody: "Any unsaved changes will be lost. Are you sure you want to close the editor?", confirmButtonText: "Close Editor", onConfirm: function () { if (onClose) { setShowWarningModal(false); onClose(); } }, show: showWarningModal, onConfirmCallbackArgs: [], onCancel: function () { return setShowWarningModal(false); } }), react_1.default.createElement("div", { className: "DatasetEditorTopBottomPanel" }, react_1.default.createElement("div", { className: "ItemCount" }, datasetToUpdate ? (react_1.default.createElement(Typography_1.default, { variant: "headline3" }, datasetToUpdate.items.length === 0 ? 'No' : datasetToUpdate.items.length.toLocaleString(), ' ', "File", datasetToUpdate.items.length !== 1 && 's')) : (react_1.default.createElement(lab_1.Skeleton, { variant: "rect", width: 200 }))), react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline", disabled: datasetToUpdate == null, onClick: function () { return setShowEntityFinder(true); } }, "Add Items"), react_1.default.createElement(react_bootstrap_1.Button, { disabled: selectedIds.size === 0, variant: "outline", onClick: removeSelectedItemsFromDataset }, "Remove Items")), react_1.default.createElement("div", { className: "DatasetEditorTableContainer" }, datasetToUpdate ? (datasetToUpdate.items.length === 0 ? (react_1.default.createElement(NoItemsPlaceholder, null)) : (react_1.default.createElement(react_base_table_1.default, { classPrefix: "DatasetEditorTable", data: tableData, height: TABLE_HEIGHT, width: defaultColumns.reduce(function (totalWidth, column) { return totalWidth + column.width; }, 0), rowHeight: ROW_HEIGHT, overscanRowCount: 5, columns: defaultColumns, rowClassName: 'DatasetEditorRow', rowProps: function (_a) { var rowData = _a.rowData; return { 'aria-selected': rowData.isSelected, }; }, headerCellProps: { role: 'columnheader', }, onRowsRendered: TooltipUtils_1.rebuildTooltip, onScroll: TooltipUtils_1.rebuildTooltip }))) : (react_1.default.createElement(SkeletonTable_1.SkeletonTable, { className: "DatasetItemsEditorSkeleton", numRows: 8, numCols: 6, rowHeight: ROW_HEIGHT + "px" })), react_1.default.createElement(react_tooltip_1.default, { id: EntityBadgeIcons_1.ENTITY_BADGE_ICONS_TOOLTIP_ID, className: "EntityBadgeTooltip", delayShow: 100, place: 'right', effect: 'solid' })), react_1.default.createElement("div", { className: "DatasetEditorTopBottomPanel" }, react_1.default.createElement(react_bootstrap_1.Button, { variant: 'outline', onClick: function () { if (hasChangedSinceLastSave) { setShowWarningModal(true); } else if (onClose) { onClose(); } } }, "Cancel"), react_1.default.createElement(react_bootstrap_1.Button, { disabled: !datasetToUpdate, variant: 'sds-primary', onClick: function () { return mutation.mutate(datasetToUpdate); } }, "Save")))); } exports.DatasetItemsEditor = DatasetItemsEditor; //# sourceMappingURL=DatasetItemsEditor.js.map