synapse-react-client 4.0.35 → 4.0.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SWC.index.js +1 -1
- package/dist/aridhia-queries/AridhiaKeyFactory.d.ts +24 -0
- package/dist/aridhia-queries/AridhiaKeyFactory.d.ts.map +1 -0
- package/dist/aridhia-queries/AridhiaKeyFactory.js +49 -0
- package/dist/aridhia-queries/AridhiaKeyFactory.js.map +1 -0
- package/dist/aridhia-queries/FairFormPayload.d.ts +45 -0
- package/dist/aridhia-queries/FairFormPayload.d.ts.map +1 -0
- package/dist/aridhia-queries/FairFormPayload.js +0 -0
- package/dist/aridhia-queries/TransferType.d.ts +10 -0
- package/dist/aridhia-queries/TransferType.d.ts.map +1 -0
- package/dist/aridhia-queries/TransferType.js +0 -0
- package/dist/aridhia-queries/aridhiaTokenExchange.js +6 -6
- package/dist/aridhia-queries/index.d.ts +12 -0
- package/dist/aridhia-queries/index.d.ts.map +1 -1
- package/dist/aridhia-queries/index.js +12 -2
- package/dist/aridhia-queries/useAridhiaQuery.d.ts +37 -0
- package/dist/aridhia-queries/useAridhiaQuery.d.ts.map +1 -0
- package/dist/aridhia-queries/useAridhiaQuery.js +71 -0
- package/dist/aridhia-queries/useAridhiaQuery.js.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaDatasetCatalogue.d.ts +6 -0
- package/dist/aridhia-queries/useGetAridhiaDatasetCatalogue.d.ts.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaDatasetCatalogue.js +13 -0
- package/dist/aridhia-queries/useGetAridhiaDatasetCatalogue.js.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaDatasetSettings.d.ts +6 -0
- package/dist/aridhia-queries/useGetAridhiaDatasetSettings.d.ts.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaDatasetSettings.js +13 -0
- package/dist/aridhia-queries/useGetAridhiaDatasetSettings.js.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaDictionaries.d.ts +6 -0
- package/dist/aridhia-queries/useGetAridhiaDictionaries.d.ts.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaDictionaries.js +13 -0
- package/dist/aridhia-queries/useGetAridhiaDictionaries.js.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaRequests.d.ts +5 -4
- package/dist/aridhia-queries/useGetAridhiaRequests.d.ts.map +1 -1
- package/dist/aridhia-queries/useGetAridhiaRequests.js +11 -18
- package/dist/aridhia-queries/useGetAridhiaRequests.js.map +1 -1
- package/dist/aridhia-queries/useGetAridhiaWorkflow.d.ts +13 -0
- package/dist/aridhia-queries/useGetAridhiaWorkflow.d.ts.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaWorkflow.js +19 -0
- package/dist/aridhia-queries/useGetAridhiaWorkflow.js.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaWorkspaceLocations.d.ts +6 -0
- package/dist/aridhia-queries/useGetAridhiaWorkspaceLocations.d.ts.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaWorkspaceLocations.js +13 -0
- package/dist/aridhia-queries/useGetAridhiaWorkspaceLocations.js.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaWorkspaceRequestForm.d.ts +19 -0
- package/dist/aridhia-queries/useGetAridhiaWorkspaceRequestForm.d.ts.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaWorkspaceRequestForm.js +17 -0
- package/dist/aridhia-queries/useGetAridhiaWorkspaceRequestForm.js.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaWorkspaces.d.ts +6 -0
- package/dist/aridhia-queries/useGetAridhiaWorkspaces.d.ts.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaWorkspaces.js +19 -0
- package/dist/aridhia-queries/useGetAridhiaWorkspaces.js.map +1 -0
- package/dist/aridhia-queries/useSubmitAridhiaDar.d.ts +27 -0
- package/dist/aridhia-queries/useSubmitAridhiaDar.d.ts.map +1 -0
- package/dist/aridhia-queries/useSubmitAridhiaDar.js +38 -0
- package/dist/aridhia-queries/useSubmitAridhiaDar.js.map +1 -0
- package/dist/components/AccessRequirement/EntityActionsRequired.d.ts +0 -1
- package/dist/components/AccessRequirement/EntityActionsRequired.d.ts.map +1 -1
- package/dist/components/AccessRequirement/EntityActionsRequired.js +3 -6
- package/dist/components/AccessRequirement/EntityActionsRequired.js.map +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementList.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementList.js +116 -115
- package/dist/components/AccessRequirementList/AccessRequirementList.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/EDucPreviewStep/EDucPreviewStep.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/EDucPreviewStep/EDucPreviewStep.js +67 -57
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/EDucPreviewStep/EDucPreviewStep.js.map +1 -1
- package/dist/components/Aridhia/aridhiaAccessStatusUtils.d.ts +3 -3
- package/dist/components/Aridhia/aridhiaAccessStatusUtils.d.ts.map +1 -1
- package/dist/components/Aridhia/aridhiaAccessStatusUtils.js +1 -1
- package/dist/components/Aridhia/aridhiaAccessStatusUtils.js.map +1 -1
- package/dist/components/CardContainer/CardConfiguration.d.ts +8 -0
- package/dist/components/CardContainer/CardConfiguration.d.ts.map +1 -1
- package/dist/components/ChangePassword/ChangePasswordWithToken.d.ts.map +1 -1
- package/dist/components/ChangePassword/ChangePasswordWithToken.js +58 -23
- package/dist/components/ChangePassword/ChangePasswordWithToken.js.map +1 -1
- package/dist/components/ChangePassword/useChangePasswordFormState.d.ts.map +1 -1
- package/dist/components/ChangePassword/useChangePasswordFormState.js +13 -3
- package/dist/components/ChangePassword/useChangePasswordFormState.js.map +1 -1
- package/dist/components/CreateTableViewWizard/TableNameForm.d.ts.map +1 -1
- package/dist/components/CreateTableViewWizard/TableNameForm.js +11 -14
- package/dist/components/CreateTableViewWizard/TableNameForm.js.map +1 -1
- package/dist/components/DataGrid/SyncGridWithSourceButton.d.ts +1 -1
- package/dist/components/DataGrid/SyncGridWithSourceButton.d.ts.map +1 -1
- package/dist/components/DataGrid/SyncGridWithSourceButton.js +55 -61
- package/dist/components/DataGrid/SyncGridWithSourceButton.js.map +1 -1
- package/dist/components/DataGrid/components/contextMenu.d.ts.map +1 -1
- package/dist/components/DataGrid/components/contextMenu.js +15 -15
- package/dist/components/DataGrid/components/contextMenu.js.map +1 -1
- package/dist/components/DataGrid/useMergeGridWithSource.d.ts +1 -5
- package/dist/components/DataGrid/useMergeGridWithSource.d.ts.map +1 -1
- package/dist/components/DataGrid/useMergeGridWithSource.js +21 -28
- package/dist/components/DataGrid/useMergeGridWithSource.js.map +1 -1
- package/dist/components/DatasetHosting/DatasetDownloadButton.d.ts +35 -0
- package/dist/components/DatasetHosting/DatasetDownloadButton.d.ts.map +1 -0
- package/dist/components/DatasetHosting/DatasetDownloadButton.js +132 -0
- package/dist/components/DatasetHosting/DatasetDownloadButton.js.map +1 -0
- package/dist/components/DatasetHosting/DatasetHosting.d.ts +91 -0
- package/dist/components/DatasetHosting/DatasetHosting.d.ts.map +1 -0
- package/dist/components/DatasetHosting/DatasetHosting.js +58 -0
- package/dist/components/DatasetHosting/DatasetHosting.js.map +1 -0
- package/dist/components/DatasetHosting/index.d.ts +5 -0
- package/dist/components/DatasetHosting/index.d.ts.map +1 -0
- package/dist/components/DatasetHosting/index.js +3 -0
- package/dist/components/DownloadCart/ActionRequiredListItem.d.ts +0 -2
- package/dist/components/DownloadCart/ActionRequiredListItem.d.ts.map +1 -1
- package/dist/components/DownloadCart/ActionRequiredListItem.js +2 -3
- package/dist/components/DownloadCart/ActionRequiredListItem.js.map +1 -1
- package/dist/components/DownloadCart/DownloadCartPage.d.ts +1 -2
- package/dist/components/DownloadCart/DownloadCartPage.d.ts.map +1 -1
- package/dist/components/DownloadCart/DownloadCartPage.js +49 -49
- package/dist/components/DownloadCart/DownloadCartPage.js.map +1 -1
- package/dist/components/DownloadCart/DownloadListActionsRequired.d.ts +1 -5
- package/dist/components/DownloadCart/DownloadListActionsRequired.d.ts.map +1 -1
- package/dist/components/DownloadCart/DownloadListActionsRequired.js +5 -6
- package/dist/components/DownloadCart/DownloadListActionsRequired.js.map +1 -1
- package/dist/components/DownloadCart/RequestDownloadCard.d.ts +0 -2
- package/dist/components/DownloadCart/RequestDownloadCard.d.ts.map +1 -1
- package/dist/components/DownloadCart/RequestDownloadCard.js +28 -32
- package/dist/components/DownloadCart/RequestDownloadCard.js.map +1 -1
- package/dist/components/DownloadCart/TableQueryActionsRequired.d.ts +0 -2
- package/dist/components/DownloadCart/TableQueryActionsRequired.d.ts.map +1 -1
- package/dist/components/DownloadCart/TableQueryActionsRequired.js +7 -8
- package/dist/components/DownloadCart/TableQueryActionsRequired.js.map +1 -1
- package/dist/components/DownloadCart/index.d.ts +1 -2
- package/dist/components/DownloadCart/index.d.ts.map +1 -1
- package/dist/components/GenericCard/CardActionButtonStyleContext.d.ts +10 -0
- package/dist/components/GenericCard/CardActionButtonStyleContext.d.ts.map +1 -0
- package/dist/components/GenericCard/CardActionButtonStyleContext.js +10 -0
- package/dist/components/GenericCard/CardActionButtonStyleContext.js.map +1 -0
- package/dist/components/GenericCard/DuoTermTags/DuoTermTags.js +41 -41
- package/dist/components/GenericCard/GenericCardActionButton.d.ts +5 -0
- package/dist/components/GenericCard/GenericCardActionButton.d.ts.map +1 -1
- package/dist/components/GenericCard/GenericCardActionButton.js +28 -11
- package/dist/components/GenericCard/GenericCardActionButton.js.map +1 -1
- package/dist/components/GenericCard/TableRowGenericCard.d.ts +24 -0
- package/dist/components/GenericCard/TableRowGenericCard.d.ts.map +1 -1
- package/dist/components/GenericCard/TableRowGenericCard.js +205 -190
- package/dist/components/GenericCard/TableRowGenericCard.js.map +1 -1
- package/dist/components/JSONArrayEditor/JSONArrayEditor.d.ts.map +1 -1
- package/dist/components/JSONArrayEditor/JSONArrayEditor.js +42 -42
- package/dist/components/JSONArrayEditor/JSONArrayEditor.js.map +1 -1
- package/dist/components/JsonSchemaForm/JsonSchemaForm.css +1 -0
- package/dist/components/JsonSchemaForm/JsonSchemaForm.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm/JsonSchemaForm.js +13 -12
- package/dist/components/JsonSchemaForm/JsonSchemaForm.js.map +1 -1
- package/dist/components/JsonSchemaForm/JsonSchemaForm.module.js +5 -0
- package/dist/components/JsonSchemaForm/JsonSchemaForm.module.js.map +1 -0
- package/dist/components/JsonSchemaForm/JsonSchemaForm.module.scss +109 -0
- package/dist/components/QueryBuilder/QueryBuilderTypes.d.ts +39 -0
- package/dist/components/QueryBuilder/QueryBuilderTypes.d.ts.map +1 -0
- package/dist/components/QueryBuilder/QueryBuilderTypes.js +11 -0
- package/dist/components/QueryBuilder/QueryBuilderTypes.js.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderTranslation.d.ts +48 -0
- package/dist/components/QueryBuilder/queryBuilderTranslation.d.ts.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderTranslation.js +256 -0
- package/dist/components/QueryBuilder/queryBuilderTranslation.js.map +1 -0
- package/dist/components/QueryContext/QueryContext.d.ts +0 -1
- package/dist/components/QueryContext/QueryContext.d.ts.map +1 -1
- package/dist/components/QueryContext/QueryContext.js.map +1 -1
- package/dist/components/QueryWrapper/QueryWrapper.d.ts +0 -1
- package/dist/components/QueryWrapper/QueryWrapper.d.ts.map +1 -1
- package/dist/components/QueryWrapper/QueryWrapper.js +52 -53
- package/dist/components/QueryWrapper/QueryWrapper.js.map +1 -1
- package/dist/components/QueryWrapperErrorBoundary.d.ts.map +1 -1
- package/dist/components/QueryWrapperErrorBoundary.js +4 -11
- package/dist/components/QueryWrapperErrorBoundary.js.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts +0 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js.map +1 -1
- package/dist/components/SchemaDrivenAnnotationEditor/SchemaDrivenAnnotationEditor.js +123 -123
- package/dist/components/SchemaDrivenAnnotationEditor/SchemaDrivenAnnotationEditor.js.map +1 -1
- package/dist/components/SearchQueryWrapper/SearchQueryWrapper.d.ts.map +1 -1
- package/dist/components/SearchQueryWrapper/SearchQueryWrapper.js +0 -1
- package/dist/components/SearchQueryWrapper/SearchQueryWrapper.js.map +1 -1
- package/dist/components/ShareThisPage/ShareThisPage.js +30 -29
- package/dist/components/ShareThisPage/ShareThisPage.js.map +1 -1
- package/dist/components/SynapseChat/GridAgentChat.d.ts.map +1 -1
- package/dist/components/SynapseChat/GridAgentChat.js +29 -31
- package/dist/components/SynapseChat/GridAgentChat.js.map +1 -1
- package/dist/components/SynapseTable/SynapseTable.d.ts.map +1 -1
- package/dist/components/SynapseTable/SynapseTable.js +2 -1
- package/dist/components/SynapseTable/SynapseTable.js.map +1 -1
- package/dist/components/SynapseTable/export/ExternalPlatformActionsRequiredPrecheck.d.ts.map +1 -1
- package/dist/components/SynapseTable/export/ExternalPlatformActionsRequiredPrecheck.js +29 -30
- package/dist/components/SynapseTable/export/ExternalPlatformActionsRequiredPrecheck.js.map +1 -1
- package/dist/components/TanStackTable/StyledTanStackTable.d.ts +7 -0
- package/dist/components/TanStackTable/StyledTanStackTable.d.ts.map +1 -1
- package/dist/components/TanStackTable/StyledTanStackTable.js +68 -48
- package/dist/components/TanStackTable/StyledTanStackTable.js.map +1 -1
- package/dist/components/TanStackTable/useSyncedTopScrollbar.d.ts +13 -0
- package/dist/components/TanStackTable/useSyncedTopScrollbar.d.ts.map +1 -0
- package/dist/components/TanStackTable/useSyncedTopScrollbar.js +32 -0
- package/dist/components/TanStackTable/useSyncedTopScrollbar.js.map +1 -0
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.d.ts.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js +36 -34
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPage.js +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPage.js.map +1 -1
- package/dist/components/doi/CreateOrUpdateDoiModal.d.ts.map +1 -1
- package/dist/components/doi/CreateOrUpdateDoiModal.js +10 -13
- package/dist/components/doi/CreateOrUpdateDoiModal.js.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +143 -140
- package/dist/components/menu/DropdownMenu.d.ts.map +1 -1
- package/dist/components/menu/DropdownMenu.js +6 -6
- package/dist/components/menu/DropdownMenu.js.map +1 -1
- package/dist/features/entity/metadata-task/components/MetadataTasksPage.js +5 -5
- package/dist/index.js +161 -159
- package/dist/index.js.map +1 -1
- package/dist/mocks/msw/handlers/dataAccessRequestHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/dataAccessRequestHandlers.js +30 -26
- package/dist/mocks/msw/handlers/dataAccessRequestHandlers.js.map +1 -1
- package/dist/mocks/msw/handlers/resetTwoFactorAuthHandlers.d.ts +1 -0
- package/dist/mocks/msw/handlers/resetTwoFactorAuthHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/resetTwoFactorAuthHandlers.js +7 -1
- package/dist/mocks/msw/handlers/resetTwoFactorAuthHandlers.js.map +1 -1
- package/dist/mocks/msw/handlers/userProfileHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/userProfileHandlers.js +4 -0
- package/dist/mocks/msw/handlers/userProfileHandlers.js.map +1 -1
- package/dist/style/components/_all.scss +0 -1
- package/dist/style/components/_cards.scss +4 -2
- package/dist/style/main.css +1 -1
- package/dist/synapse-queries/KeyFactory.d.ts +1 -0
- package/dist/synapse-queries/KeyFactory.d.ts.map +1 -1
- package/dist/synapse-queries/KeyFactory.js +3 -0
- package/dist/synapse-queries/KeyFactory.js.map +1 -1
- package/dist/synapse-queries/dataaccess/index.js +4 -4
- package/dist/synapse-queries/dataaccess/useEDuc.d.ts +7 -0
- package/dist/synapse-queries/dataaccess/useEDuc.d.ts.map +1 -1
- package/dist/synapse-queries/dataaccess/useEDuc.js +11 -3
- package/dist/synapse-queries/dataaccess/useEDuc.js.map +1 -1
- package/dist/synapse-queries/index.js +190 -189
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/APIConstants.d.ts +1 -0
- package/dist/utils/APIConstants.d.ts.map +1 -1
- package/dist/utils/APIConstants.js +2 -2
- package/dist/utils/APIConstants.js.map +1 -1
- package/dist/utils/featureflag/FeatureFlags.d.ts +1 -4
- package/dist/utils/featureflag/FeatureFlags.d.ts.map +1 -1
- package/dist/utils/featureflag/FeatureFlags.js +1 -1
- package/dist/utils/featureflag/FeatureFlags.js.map +1 -1
- package/dist/utils/functions/RegularExpressions.d.ts +10 -0
- package/dist/utils/functions/RegularExpressions.d.ts.map +1 -1
- package/dist/utils/functions/RegularExpressions.js +7 -1
- package/dist/utils/functions/RegularExpressions.js.map +1 -1
- package/dist/utils/functions/SqlFunctions.d.ts.map +1 -1
- package/dist/utils/functions/SqlFunctions.js +19 -3
- package/dist/utils/functions/SqlFunctions.js.map +1 -1
- package/dist/utils/index.js +16 -16
- package/dist/utils/types/IsType.d.ts +4 -1
- package/dist/utils/types/IsType.d.ts.map +1 -1
- package/dist/utils/types/IsType.js +4 -4
- package/dist/utils/types/IsType.js.map +1 -1
- package/dist/utils/types/index.js +2 -2
- package/package.json +7 -7
- package/dist/components/DataGrid/useMergeGridWithRecordSet.d.ts +0 -12
- package/dist/components/DataGrid/useMergeGridWithRecordSet.d.ts.map +0 -1
- package/dist/components/DataGrid/useMergeGridWithRecordSet.js +0 -25
- package/dist/components/DataGrid/useMergeGridWithRecordSet.js.map +0 -1
- package/dist/style/components/_annotations.scss +0 -110
|
@@ -1,80 +1,100 @@
|
|
|
1
1
|
import { StyledTableContainer as e } from "../styled/StyledTableContainer.js";
|
|
2
2
|
import { getColumnSizeCssVariable as t, getCommonPinningStyles as n, getHeaderSizeCssVariable as r } from "./TanStackTableUtils.js";
|
|
3
3
|
import { MemoizedTableBody as i, TableBody as a } from "./TableBody.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { useSyncedTopScrollbar as o } from "./useSyncedTopScrollbar.js";
|
|
5
|
+
import { useLayoutEffect as s, useMemo as c, useRef as l, useState as u } from "react";
|
|
6
|
+
import { Box as d } from "@mui/material";
|
|
7
|
+
import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
8
|
+
import { flexRender as h } from "@tanstack/react-table";
|
|
9
|
+
import { useForkRef as g } from "@mui/material/utils";
|
|
7
10
|
//#region src/components/TanStackTable/StyledTanStackTable.tsx
|
|
8
|
-
function
|
|
9
|
-
let { table:
|
|
10
|
-
table:
|
|
11
|
-
slots:
|
|
12
|
-
slotProps:
|
|
13
|
-
rows:
|
|
14
|
-
rowTransform:
|
|
15
|
-
},
|
|
16
|
-
|
|
17
|
-
if (!
|
|
18
|
-
let e =
|
|
11
|
+
function _(_) {
|
|
12
|
+
let { table: v, styledTableContainerProps: y, fullWidth: b = !0, autoColumnSizing: x = !1, showTopScrollbar: S = !1, slots: C = {}, slotProps: w = {} } = _, { Thead: T = "thead", Th: E = "th", Table: D = "table", ...O } = C, { Table: k = {}, Thead: A = {}, Th: j = {}, ...M } = w, N = {
|
|
13
|
+
table: v,
|
|
14
|
+
slots: O,
|
|
15
|
+
slotProps: M,
|
|
16
|
+
rows: _.rows,
|
|
17
|
+
rowTransform: _.rowTransform
|
|
18
|
+
}, P = l(null), { containerRef: F, topScrollRef: I, targetWidth: L, handleTopScroll: R, handleBottomScroll: z } = o(P, S), { ref: B, onScroll: V, ...H } = y ?? {}, U = g(F, B), W = v.getState().columnVisibility, [G, K] = u(null), q = !x || G?.columns === v.options.columns && G?.columnVisibility === W;
|
|
19
|
+
s(() => {
|
|
20
|
+
if (!x || q || !P.current) return;
|
|
21
|
+
let e = P.current.querySelectorAll(":scope > thead > tr:first-child > th"), t = v.getFlatHeaders(), n = {};
|
|
19
22
|
t.forEach((t, r) => {
|
|
20
23
|
let i = e[r];
|
|
21
24
|
i && (n[t.column.id] = Math.ceil(i.getBoundingClientRect().width));
|
|
22
|
-
}), Object.keys(n).length > 0 && (
|
|
23
|
-
columns:
|
|
24
|
-
columnVisibility:
|
|
25
|
+
}), Object.keys(n).length > 0 && (v.setColumnSizing(n), K({
|
|
26
|
+
columns: v.options.columns,
|
|
27
|
+
columnVisibility: W
|
|
25
28
|
}));
|
|
26
29
|
}, [
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
x,
|
|
31
|
+
W,
|
|
32
|
+
q,
|
|
33
|
+
v
|
|
31
34
|
]);
|
|
32
|
-
let
|
|
33
|
-
let e =
|
|
35
|
+
let J = c(() => {
|
|
36
|
+
let e = v.getFlatHeaders(), n = {};
|
|
34
37
|
for (let i = 0; i < e.length; i++) {
|
|
35
38
|
let a = e[i];
|
|
36
39
|
n[r(a.id)] = a.getSize(), n[t(a.column.id)] = a.column.getSize();
|
|
37
40
|
}
|
|
38
41
|
return n;
|
|
39
42
|
}, [
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
]),
|
|
44
|
-
|
|
45
|
-
let
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
v.getState().columnSizingInfo,
|
|
44
|
+
v.getState().columnSizing,
|
|
45
|
+
v.getState().columnVisibility
|
|
46
|
+
]), Y;
|
|
47
|
+
Y = b ? "100%" : q ? `${v.getTotalSize()}px` : "max-content";
|
|
48
|
+
let X = v.getState().columnSizingInfo.isResizingColumn ? i : a;
|
|
49
|
+
function Z(e) {
|
|
50
|
+
V?.(e), S && z(e);
|
|
51
|
+
}
|
|
52
|
+
return /* @__PURE__ */ m(f, { children: [S && /* @__PURE__ */ p(d, {
|
|
53
|
+
ref: I,
|
|
54
|
+
onScroll: R,
|
|
55
|
+
sx: {
|
|
56
|
+
overflowX: "auto",
|
|
57
|
+
overflowY: "hidden",
|
|
58
|
+
height: "16px"
|
|
59
|
+
},
|
|
60
|
+
children: /* @__PURE__ */ p(d, { sx: {
|
|
61
|
+
width: L,
|
|
62
|
+
height: "1px"
|
|
63
|
+
} })
|
|
64
|
+
}), /* @__PURE__ */ p(e, {
|
|
65
|
+
...H,
|
|
66
|
+
ref: U,
|
|
67
|
+
onScroll: Z,
|
|
68
|
+
children: /* @__PURE__ */ m(D, {
|
|
69
|
+
...k,
|
|
70
|
+
ref: P,
|
|
51
71
|
style: {
|
|
52
|
-
...
|
|
53
|
-
tableLayout:
|
|
54
|
-
width:
|
|
55
|
-
...
|
|
72
|
+
...J,
|
|
73
|
+
tableLayout: q ? "fixed" : "auto",
|
|
74
|
+
width: Y,
|
|
75
|
+
...k.style
|
|
56
76
|
},
|
|
57
|
-
children: [/* @__PURE__ */
|
|
58
|
-
...
|
|
59
|
-
children:
|
|
77
|
+
children: [/* @__PURE__ */ p(T, {
|
|
78
|
+
...A,
|
|
79
|
+
children: v.getHeaderGroups().map((e) => /* @__PURE__ */ p("tr", { children: e.headers.map((e) => /* @__PURE__ */ m(E, {
|
|
60
80
|
colSpan: e.colSpan,
|
|
61
|
-
...
|
|
81
|
+
...j,
|
|
62
82
|
style: {
|
|
63
|
-
...
|
|
83
|
+
...q && { width: `calc(var(${r(e.id)}) * 1px)` },
|
|
64
84
|
...n(e.column),
|
|
65
|
-
...
|
|
85
|
+
...j.style
|
|
66
86
|
},
|
|
67
|
-
children: [e.isPlaceholder ? null :
|
|
87
|
+
children: [e.isPlaceholder ? null : h(e.column.columnDef.header, e.getContext()), e.column.getCanResize() && /* @__PURE__ */ p("div", {
|
|
68
88
|
className: `resizer ${e.column.getIsResizing() ? "isResizing" : ""}`,
|
|
69
89
|
onMouseDown: e.getResizeHandler(),
|
|
70
90
|
onTouchStart: e.getResizeHandler()
|
|
71
91
|
})]
|
|
72
92
|
}, e.id)) }, e.id))
|
|
73
|
-
}), /* @__PURE__ */
|
|
93
|
+
}), /* @__PURE__ */ p(X, { ...N })]
|
|
74
94
|
})
|
|
75
|
-
});
|
|
95
|
+
})] });
|
|
76
96
|
}
|
|
77
97
|
//#endregion
|
|
78
|
-
export {
|
|
98
|
+
export { _ as default };
|
|
79
99
|
|
|
80
100
|
//# sourceMappingURL=StyledTanStackTable.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StyledTanStackTable.js","names":[],"sources":["../../../src/components/TanStackTable/StyledTanStackTable.tsx"],"sourcesContent":["import {\n StyledTableContainer,\n StyledTableContainerProps,\n} from '@/components/styled/StyledTableContainer'\nimport {\n ColumnSizingState,\n flexRender,\n Row,\n Table,\n} from '@tanstack/react-table'\nimport { useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { MemoizedTableBody, TableBody, TableBodyProps } from './TableBody'\nimport {\n getColumnSizeCssVariable,\n getCommonPinningStyles,\n getHeaderSizeCssVariable,\n} from './TanStackTableUtils'\nimport { StyledTanStackTableSlotProps, StyledTanStackTableSlots } from './types'\n\nexport type StyledTanStackTableProps<TData = unknown, TRowType = Row<TData>> = {\n table: Table<TData>\n styledTableContainerProps?: StyledTableContainerProps\n fullWidth?: boolean\n /**\n * When true, uses `table-layout: auto` so the browser sizes columns to fit their content.\n * Column sizes from TanStack act as minimum widths, and columns expand to fit wider content.\n * Resizing still works — dragging a column sets a new minimum width.\n * Defaults to false (fixed layout).\n */\n autoColumnSizing?: boolean\n slots?: StyledTanStackTableSlots<TData, TRowType>\n slotProps?: StyledTanStackTableSlotProps<TData, TRowType>\n} & Pick<TableBodyProps<TData, TRowType>, 'rows' | 'rowTransform'>\n\n/**\n * Component that renders a styled table using @tanstack/react-table. Pass your table instance into the component and\n * it will render the table with the appropriate headers and rows.\n */\nexport default function StyledTanStackTable<\n TData = unknown,\n TRowType = Row<TData>,\n>(props: StyledTanStackTableProps<TData, TRowType>) {\n const {\n table,\n styledTableContainerProps,\n fullWidth = true,\n autoColumnSizing = false,\n slots = {},\n slotProps = {},\n } = props\n const {\n Thead = 'thead',\n Th = 'th',\n Table = 'table',\n ...tableBodySlots\n } = slots\n const {\n Table: tableSlotProps = {},\n Thead: theadSlotProps = {},\n Th: thSlotProps = {},\n ...tableBodySlotProps\n } = slotProps\n\n const tableBodyProps: TableBodyProps<TData, TRowType> = {\n table,\n slots: tableBodySlots,\n slotProps: tableBodySlotProps,\n rows: props.rows!,\n rowTransform: props.rowTransform!,\n }\n\n /**\n * When autoColumnSizing is true we do a two-phase render:\n * 1. Render with table-layout: auto and no width constraints so the browser\n * natively sizes each column to its content.\n * 2. After the first paint, measure each <th> and write the real pixel widths\n * into TanStack's columnSizing state, then switch to table-layout: fixed.\n *\n * This gives content-based initial sizes while still allowing the user to drag\n * a column narrower than its content.\n */\n const tableRef = useRef<HTMLTableElement>(null)\n\n // Track what columns+visibility combination was last measured so we know when\n // a re-measurement is needed (e.g. columns change or visibility is toggled).\n const columnVisibility = table.getState().columnVisibility\n const [lastMeasuredState, setLastMeasuredState] = useState<{\n columns: typeof table.options.columns\n columnVisibility: typeof columnVisibility\n } | null>(null)\n\n // hasMeasured is true when auto-sizing is disabled (nothing to do) OR when the\n // current columns+visibility matches the last measured snapshot.\n const hasMeasured =\n !autoColumnSizing ||\n (lastMeasuredState?.columns === table.options.columns &&\n lastMeasuredState?.columnVisibility === columnVisibility)\n\n // After the browser has laid out the auto-sized table, capture the widths and\n // switch to fixed layout so that the user can resize below the content width.\n // useLayoutEffect runs synchronously after DOM mutations, before the browser\n // paints, which is required for accurate DOM measurements.\n useLayoutEffect(() => {\n if (!autoColumnSizing || hasMeasured || !tableRef.current) return\n\n const ths = tableRef.current.querySelectorAll(\n ':scope > thead > tr:first-child > th',\n )\n const headers = table.getFlatHeaders()\n const newSizes: ColumnSizingState = {}\n headers.forEach((header, i) => {\n const th = ths[i] as HTMLElement | undefined\n if (th) {\n newSizes[header.column.id] = Math.ceil(th.getBoundingClientRect().width)\n }\n })\n if (Object.keys(newSizes).length > 0) {\n table.setColumnSizing(newSizes)\n setLastMeasuredState({\n columns: table.options.columns,\n columnVisibility,\n })\n }\n }, [autoColumnSizing, columnVisibility, hasMeasured, table])\n\n /**\n * Instead of calling `column.getSize()` on every render for every header\n * and especially every data cell (very expensive),\n * we will calculate all column sizes at once at the root table level in a useMemo\n * and pass the column sizes down as CSS variables to the <table> element.\n *\n * See https://tanstack.com/table/v8/docs/guide/column-sizing#advanced-column-resizing-performance\n */\n const columnSizeVars = useMemo(() => {\n const headers = table.getFlatHeaders()\n const colSizes: { [key: string]: number } = {}\n for (let i = 0; i < headers.length; i++) {\n const header = headers[i]\n colSizes[getHeaderSizeCssVariable(header.id)] = header.getSize()\n colSizes[getColumnSizeCssVariable(header.column.id)] =\n header.column.getSize()\n }\n return colSizes\n // Intentionally limit the dependencies to only recompute when the column sizes change\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [\n table.getState().columnSizingInfo,\n table.getState().columnSizing,\n table.getState().columnVisibility, // If a column is added, its width should be recalculated\n ])\n\n // Before measurement: let the browser shrink the table to content width so we\n // can read accurate sizes. After measurement: use the exact measured total.\n let tableWidth: string\n if (fullWidth) {\n tableWidth = '100%'\n } else if (!hasMeasured) {\n tableWidth = 'max-content'\n } else {\n tableWidth = `${table.getTotalSize()}px`\n }\n\n /* When resizing any column we will render this special memoized version of our table body */\n const TableBodyElement = table.getState().columnSizingInfo.isResizingColumn\n ? MemoizedTableBody\n : TableBody\n\n return (\n <StyledTableContainer {...styledTableContainerProps}>\n <Table\n {...tableSlotProps}\n ref={tableRef}\n style={{\n ...columnSizeVars,\n // Pre-measurement: auto layout so the browser can size columns to content.\n // Post-measurement: fixed layout so the user can resize below content width.\n tableLayout: hasMeasured ? 'fixed' : 'auto',\n width: tableWidth,\n ...tableSlotProps['style'],\n }}\n >\n <Thead {...theadSlotProps}>\n {table.getHeaderGroups().map(headerGroup => {\n return (\n <tr key={headerGroup.id}>\n {headerGroup.headers.map(header => (\n <Th\n key={header.id}\n colSpan={header.colSpan}\n {...thSlotProps}\n style={{\n // Pre-measurement: no width hint — let the browser size freely.\n // Post-measurement: exact width from the measured/resized value.\n ...(hasMeasured && {\n width: `calc(var(${getHeaderSizeCssVariable(\n header.id,\n )}) * 1px)`,\n }),\n ...getCommonPinningStyles(header.column),\n ...thSlotProps['style'],\n }}\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n {header.column.getCanResize() && (\n <div\n className={`resizer ${\n header.column.getIsResizing() ? 'isResizing' : ''\n }`}\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n />\n )}\n </Th>\n ))}\n </tr>\n )\n })}\n </Thead>\n <TableBodyElement<TData, TRowType> {...tableBodyProps} />\n </Table>\n </StyledTableContainer>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"StyledTanStackTable.js","names":[],"sources":["../../../src/components/TanStackTable/StyledTanStackTable.tsx"],"sourcesContent":["import {\n StyledTableContainer,\n StyledTableContainerProps,\n} from '@/components/styled/StyledTableContainer'\nimport { Box } from '@mui/material'\nimport { useForkRef } from '@mui/material/utils'\nimport {\n ColumnSizingState,\n flexRender,\n Row,\n Table,\n} from '@tanstack/react-table'\nimport { UIEvent, useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { MemoizedTableBody, TableBody, TableBodyProps } from './TableBody'\nimport {\n getColumnSizeCssVariable,\n getCommonPinningStyles,\n getHeaderSizeCssVariable,\n} from './TanStackTableUtils'\nimport { StyledTanStackTableSlotProps, StyledTanStackTableSlots } from './types'\nimport { useSyncedTopScrollbar } from './useSyncedTopScrollbar'\n\nexport type StyledTanStackTableProps<TData = unknown, TRowType = Row<TData>> = {\n table: Table<TData>\n styledTableContainerProps?: StyledTableContainerProps\n fullWidth?: boolean\n /**\n * When true, uses `table-layout: auto` so the browser sizes columns to fit their content.\n * Column sizes from TanStack act as minimum widths, and columns expand to fit wider content.\n * Resizing still works — dragging a column sets a new minimum width.\n * Defaults to false (fixed layout).\n */\n autoColumnSizing?: boolean\n /**\n * When true, renders an additional horizontal scrollbar above the table (in addition to the\n * browser's native scrollbar below it), synced to the same scroll position. Useful for wide\n * tables where the bottom scrollbar may be far from the viewport's visible area.\n * @default false\n */\n showTopScrollbar?: boolean\n slots?: StyledTanStackTableSlots<TData, TRowType>\n slotProps?: StyledTanStackTableSlotProps<TData, TRowType>\n} & Pick<TableBodyProps<TData, TRowType>, 'rows' | 'rowTransform'>\n\n/**\n * Component that renders a styled table using @tanstack/react-table. Pass your table instance into the component and\n * it will render the table with the appropriate headers and rows.\n */\nexport default function StyledTanStackTable<\n TData = unknown,\n TRowType = Row<TData>,\n>(props: StyledTanStackTableProps<TData, TRowType>) {\n const {\n table,\n styledTableContainerProps,\n fullWidth = true,\n autoColumnSizing = false,\n showTopScrollbar = false,\n slots = {},\n slotProps = {},\n } = props\n const {\n Thead = 'thead',\n Th = 'th',\n Table = 'table',\n ...tableBodySlots\n } = slots\n const {\n Table: tableSlotProps = {},\n Thead: theadSlotProps = {},\n Th: thSlotProps = {},\n ...tableBodySlotProps\n } = slotProps\n\n const tableBodyProps: TableBodyProps<TData, TRowType> = {\n table,\n slots: tableBodySlots,\n slotProps: tableBodySlotProps,\n rows: props.rows!,\n rowTransform: props.rowTransform!,\n }\n\n /**\n * When autoColumnSizing is true we do a two-phase render:\n * 1. Render with table-layout: auto and no width constraints so the browser\n * natively sizes each column to its content.\n * 2. After the first paint, measure each <th> and write the real pixel widths\n * into TanStack's columnSizing state, then switch to table-layout: fixed.\n *\n * This gives content-based initial sizes while still allowing the user to drag\n * a column narrower than its content.\n */\n const tableRef = useRef<HTMLTableElement>(null)\n\n const {\n containerRef,\n topScrollRef,\n targetWidth: tableRenderedWidth,\n handleTopScroll,\n handleBottomScroll,\n } = useSyncedTopScrollbar(tableRef, showTopScrollbar)\n\n // Merge our own container ref/onScroll with any that the caller passed via\n // styledTableContainerProps, rather than one clobbering the other.\n const {\n ref: callerContainerRef,\n onScroll: callerOnScroll,\n ...restContainerProps\n } = styledTableContainerProps ?? {}\n const mergedContainerRef = useForkRef(containerRef, callerContainerRef)\n\n // Track what columns+visibility combination was last measured so we know when\n // a re-measurement is needed (e.g. columns change or visibility is toggled).\n const columnVisibility = table.getState().columnVisibility\n const [lastMeasuredState, setLastMeasuredState] = useState<{\n columns: typeof table.options.columns\n columnVisibility: typeof columnVisibility\n } | null>(null)\n\n // hasMeasured is true when auto-sizing is disabled (nothing to do) OR when the\n // current columns+visibility matches the last measured snapshot.\n const hasMeasured =\n !autoColumnSizing ||\n (lastMeasuredState?.columns === table.options.columns &&\n lastMeasuredState?.columnVisibility === columnVisibility)\n\n // After the browser has laid out the auto-sized table, capture the widths and\n // switch to fixed layout so that the user can resize below the content width.\n // useLayoutEffect runs synchronously after DOM mutations, before the browser\n // paints, which is required for accurate DOM measurements.\n useLayoutEffect(() => {\n if (!autoColumnSizing || hasMeasured || !tableRef.current) return\n\n const ths = tableRef.current.querySelectorAll(\n ':scope > thead > tr:first-child > th',\n )\n const headers = table.getFlatHeaders()\n const newSizes: ColumnSizingState = {}\n headers.forEach((header, i) => {\n const th = ths[i] as HTMLElement | undefined\n if (th) {\n newSizes[header.column.id] = Math.ceil(th.getBoundingClientRect().width)\n }\n })\n if (Object.keys(newSizes).length > 0) {\n table.setColumnSizing(newSizes)\n setLastMeasuredState({\n columns: table.options.columns,\n columnVisibility,\n })\n }\n }, [autoColumnSizing, columnVisibility, hasMeasured, table])\n\n /**\n * Instead of calling `column.getSize()` on every render for every header\n * and especially every data cell (very expensive),\n * we will calculate all column sizes at once at the root table level in a useMemo\n * and pass the column sizes down as CSS variables to the <table> element.\n *\n * See https://tanstack.com/table/v8/docs/guide/column-sizing#advanced-column-resizing-performance\n */\n const columnSizeVars = useMemo(() => {\n const headers = table.getFlatHeaders()\n const colSizes: { [key: string]: number } = {}\n for (let i = 0; i < headers.length; i++) {\n const header = headers[i]\n colSizes[getHeaderSizeCssVariable(header.id)] = header.getSize()\n colSizes[getColumnSizeCssVariable(header.column.id)] =\n header.column.getSize()\n }\n return colSizes\n // Intentionally limit the dependencies to only recompute when the column sizes change\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [\n table.getState().columnSizingInfo,\n table.getState().columnSizing,\n table.getState().columnVisibility, // If a column is added, its width should be recalculated\n ])\n\n // Before measurement: let the browser shrink the table to content width so we\n // can read accurate sizes. After measurement: use the exact measured total.\n let tableWidth: string\n if (fullWidth) {\n tableWidth = '100%'\n } else if (!hasMeasured) {\n tableWidth = 'max-content'\n } else {\n tableWidth = `${table.getTotalSize()}px`\n }\n\n /* When resizing any column we will render this special memoized version of our table body */\n const TableBodyElement = table.getState().columnSizingInfo.isResizingColumn\n ? MemoizedTableBody\n : TableBody\n\n function handleContainerScroll(e: UIEvent<HTMLDivElement>) {\n callerOnScroll?.(e)\n if (showTopScrollbar) {\n handleBottomScroll(e)\n }\n }\n\n return (\n <>\n {showTopScrollbar && (\n <Box\n ref={topScrollRef}\n onScroll={handleTopScroll}\n sx={{ overflowX: 'auto', overflowY: 'hidden', height: '16px' }}\n >\n <Box sx={{ width: tableRenderedWidth, height: '1px' }} />\n </Box>\n )}\n <StyledTableContainer\n {...restContainerProps}\n ref={mergedContainerRef}\n onScroll={handleContainerScroll}\n >\n <Table\n {...tableSlotProps}\n ref={tableRef}\n style={{\n ...columnSizeVars,\n // Pre-measurement: auto layout so the browser can size columns to content.\n // Post-measurement: fixed layout so the user can resize below content width.\n tableLayout: hasMeasured ? 'fixed' : 'auto',\n width: tableWidth,\n ...tableSlotProps['style'],\n }}\n >\n <Thead {...theadSlotProps}>\n {table.getHeaderGroups().map(headerGroup => {\n return (\n <tr key={headerGroup.id}>\n {headerGroup.headers.map(header => (\n <Th\n key={header.id}\n colSpan={header.colSpan}\n {...thSlotProps}\n style={{\n // Pre-measurement: no width hint — let the browser size freely.\n // Post-measurement: exact width from the measured/resized value.\n ...(hasMeasured && {\n width: `calc(var(${getHeaderSizeCssVariable(\n header.id,\n )}) * 1px)`,\n }),\n ...getCommonPinningStyles(header.column),\n ...thSlotProps['style'],\n }}\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n {header.column.getCanResize() && (\n <div\n className={`resizer ${\n header.column.getIsResizing() ? 'isResizing' : ''\n }`}\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n />\n )}\n </Th>\n ))}\n </tr>\n )\n })}\n </Thead>\n <TableBodyElement<TData, TRowType> {...tableBodyProps} />\n </Table>\n </StyledTableContainer>\n </>\n )\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RefObject, UIEvent } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Keeps an optional top scrollbar in sync with a scrollable container's horizontal scroll
|
|
4
|
+
* position, sized to match the rendered width of `targetRef`'s element (e.g. a `<table>`).
|
|
5
|
+
*/
|
|
6
|
+
export declare function useSyncedTopScrollbar(targetRef: RefObject<HTMLElement | null>, enabled: boolean): {
|
|
7
|
+
containerRef: RefObject<HTMLDivElement | null>;
|
|
8
|
+
topScrollRef: RefObject<HTMLDivElement | null>;
|
|
9
|
+
targetWidth: number;
|
|
10
|
+
handleTopScroll: (e: UIEvent<HTMLDivElement>) => void;
|
|
11
|
+
handleBottomScroll: (e: UIEvent<HTMLDivElement>) => void;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=useSyncedTopScrollbar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSyncedTopScrollbar.d.ts","sourceRoot":"","sources":["../../../src/components/TanStackTable/useSyncedTopScrollbar.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAoB,MAAM,OAAO,CAAA;AAE5D;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EACxC,OAAO,EAAE,OAAO;;;;yBAaY,OAAO,CAAC,cAAc,CAAC;4BAWpB,OAAO,CAAC,cAAc,CAAC;EAkBvD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useRef as e, useState as t } from "react";
|
|
2
|
+
import { useResizeObserver as n } from "@react-hookz/web";
|
|
3
|
+
//#region src/components/TanStackTable/useSyncedTopScrollbar.ts
|
|
4
|
+
function r(r, i) {
|
|
5
|
+
let a = e(null), o = e(null), s = e(null), [c, l] = t(0);
|
|
6
|
+
n(r, (e) => l(e.target.offsetWidth), i);
|
|
7
|
+
function u(e) {
|
|
8
|
+
if (s.current === "bottom") {
|
|
9
|
+
s.current = null;
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
s.current = "top", a.current && (a.current.scrollLeft = e.currentTarget.scrollLeft);
|
|
13
|
+
}
|
|
14
|
+
function d(e) {
|
|
15
|
+
if (s.current === "top") {
|
|
16
|
+
s.current = null;
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
s.current = "bottom", o.current && (o.current.scrollLeft = e.currentTarget.scrollLeft);
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
containerRef: a,
|
|
23
|
+
topScrollRef: o,
|
|
24
|
+
targetWidth: c,
|
|
25
|
+
handleTopScroll: u,
|
|
26
|
+
handleBottomScroll: d
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { r as useSyncedTopScrollbar };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=useSyncedTopScrollbar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSyncedTopScrollbar.js","names":[],"sources":["../../../src/components/TanStackTable/useSyncedTopScrollbar.ts"],"sourcesContent":["import { useResizeObserver } from '@react-hookz/web'\nimport { RefObject, UIEvent, useRef, useState } from 'react'\n\n/**\n * Keeps an optional top scrollbar in sync with a scrollable container's horizontal scroll\n * position, sized to match the rendered width of `targetRef`'s element (e.g. a `<table>`).\n */\nexport function useSyncedTopScrollbar(\n targetRef: RefObject<HTMLElement | null>,\n enabled: boolean,\n) {\n const containerRef = useRef<HTMLDivElement>(null)\n const topScrollRef = useRef<HTMLDivElement>(null)\n const scrollSyncSourceRef = useRef<'top' | 'bottom' | null>(null)\n const [targetWidth, setTargetWidth] = useState(0)\n\n useResizeObserver(\n targetRef,\n entry => setTargetWidth((entry.target as HTMLElement).offsetWidth),\n enabled,\n )\n\n function handleTopScroll(e: UIEvent<HTMLDivElement>) {\n if (scrollSyncSourceRef.current === 'bottom') {\n scrollSyncSourceRef.current = null\n return\n }\n scrollSyncSourceRef.current = 'top'\n if (containerRef.current) {\n containerRef.current.scrollLeft = e.currentTarget.scrollLeft\n }\n }\n\n function handleBottomScroll(e: UIEvent<HTMLDivElement>) {\n if (scrollSyncSourceRef.current === 'top') {\n scrollSyncSourceRef.current = null\n return\n }\n scrollSyncSourceRef.current = 'bottom'\n if (topScrollRef.current) {\n topScrollRef.current.scrollLeft = e.currentTarget.scrollLeft\n }\n }\n\n return {\n containerRef,\n topScrollRef,\n targetWidth,\n handleTopScroll,\n handleBottomScroll,\n }\n}\n"],"mappings":";;;AAOA,SAAgB,EACd,GACA,GACA;CACA,IAAM,IAAe,EAAuB,IAAI,GAC1C,IAAe,EAAuB,IAAI,GAC1C,IAAsB,EAAgC,IAAI,GAC1D,CAAC,GAAa,KAAkB,EAAS,CAAC;CAEhD,EACE,IACA,MAAS,EAAgB,EAAM,OAAuB,WAAW,GACjE,CACF;CAEA,SAAS,EAAgB,GAA4B;EACnD,IAAI,EAAoB,YAAY,UAAU;GAC5C,EAAoB,UAAU;GAC9B;EACF;EAEA,AADA,EAAoB,UAAU,OAC1B,EAAa,YACf,EAAa,QAAQ,aAAa,EAAE,cAAc;CAEtD;CAEA,SAAS,EAAmB,GAA4B;EACtD,IAAI,EAAoB,YAAY,OAAO;GACzC,EAAoB,UAAU;GAC9B;EACF;EAEA,AADA,EAAoB,UAAU,UAC1B,EAAa,YACf,EAAa,QAAQ,aAAa,EAAE,cAAc;CAEtD;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;AACF"}
|
package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InFlightEDucSignaturesTable.d.ts","sourceRoot":"","sources":["../../../../src/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.tsx"],"names":[],"mappings":"AA2DA;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,
|
|
1
|
+
{"version":3,"file":"InFlightEDucSignaturesTable.d.ts","sourceRoot":"","sources":["../../../../src/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.tsx"],"names":[],"mappings":"AA2DA;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,mDA2D1C"}
|
|
@@ -5,30 +5,30 @@ import "../../Skeleton/index.js";
|
|
|
5
5
|
import n from "../../TanStackTable/StyledTanStackTable.js";
|
|
6
6
|
import r from "../../TanStackTable/ColumnHeader.js";
|
|
7
7
|
import { useMemo as i } from "react";
|
|
8
|
-
import { Alert as a, Box as o,
|
|
9
|
-
import { jsx as
|
|
10
|
-
import { createColumnHelper as
|
|
8
|
+
import { Alert as a, Box as o, Stack as s, Typography as c } from "@mui/material";
|
|
9
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
10
|
+
import { createColumnHelper as d, getCoreRowModel as f, useReactTable as p } from "@tanstack/react-table";
|
|
11
11
|
//#region src/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.tsx
|
|
12
|
-
var
|
|
12
|
+
var m = [
|
|
13
13
|
"sent",
|
|
14
14
|
"delivered",
|
|
15
15
|
"completed"
|
|
16
|
-
],
|
|
16
|
+
], h = {
|
|
17
17
|
sent: "Signatures pending",
|
|
18
18
|
delivered: "Signatures pending",
|
|
19
19
|
completed: "Ready to submit"
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
header: (e) => /* @__PURE__ */
|
|
20
|
+
}, g = d(), _ = [
|
|
21
|
+
g.accessor("accessRequirementName", {
|
|
22
|
+
header: (e) => /* @__PURE__ */ l(r, {
|
|
23
23
|
...e,
|
|
24
24
|
title: "Request type"
|
|
25
25
|
}),
|
|
26
26
|
enableSorting: !1,
|
|
27
27
|
enableColumnFilter: !1
|
|
28
28
|
}),
|
|
29
|
-
|
|
29
|
+
g.display({
|
|
30
30
|
id: "signatureProgress",
|
|
31
|
-
header: (e) => /* @__PURE__ */
|
|
31
|
+
header: (e) => /* @__PURE__ */ l(r, {
|
|
32
32
|
...e,
|
|
33
33
|
title: "Signature progress"
|
|
34
34
|
}),
|
|
@@ -37,48 +37,50 @@ var p = [
|
|
|
37
37
|
enableColumnFilter: !1,
|
|
38
38
|
size: 150
|
|
39
39
|
}),
|
|
40
|
-
|
|
41
|
-
header: (e) => /* @__PURE__ */
|
|
40
|
+
g.accessor("status", {
|
|
41
|
+
header: (e) => /* @__PURE__ */ l(r, {
|
|
42
42
|
...e,
|
|
43
43
|
title: "Current status"
|
|
44
44
|
}),
|
|
45
45
|
enableSorting: !1,
|
|
46
46
|
cell: (e) => {
|
|
47
47
|
let t = e.getValue();
|
|
48
|
-
return t ?
|
|
48
|
+
return t ? h[t] ?? t : "";
|
|
49
49
|
},
|
|
50
50
|
enableColumnFilter: !1,
|
|
51
51
|
size: 150
|
|
52
52
|
})
|
|
53
53
|
];
|
|
54
|
-
function
|
|
55
|
-
let { data: r, isLoading:
|
|
56
|
-
data:
|
|
57
|
-
columns:
|
|
58
|
-
getCoreRowModel:
|
|
54
|
+
function v() {
|
|
55
|
+
let { data: r, isLoading: d, error: h } = e(), g = i(() => (r ?? []).filter((e) => e.isEDuc === !0 && e.status !== void 0 && m.includes(e.status)), [r]), v = p({
|
|
56
|
+
data: g,
|
|
57
|
+
columns: _,
|
|
58
|
+
getCoreRowModel: f(),
|
|
59
59
|
columnResizeMode: "onChange"
|
|
60
60
|
});
|
|
61
|
-
return
|
|
61
|
+
return h ? /* @__PURE__ */ u(a, {
|
|
62
62
|
severity: "error",
|
|
63
63
|
children: [
|
|
64
|
-
/* @__PURE__ */
|
|
65
|
-
/* @__PURE__ */
|
|
66
|
-
|
|
64
|
+
/* @__PURE__ */ l("strong", { children: "Sorry, we couldn't load your in-flight eDUC signatures." }),
|
|
65
|
+
/* @__PURE__ */ l("br", {}),
|
|
66
|
+
h.reason
|
|
67
67
|
]
|
|
68
|
-
}) :
|
|
69
|
-
numCols:
|
|
68
|
+
}) : d ? /* @__PURE__ */ l(t, {
|
|
69
|
+
numCols: _.length,
|
|
70
70
|
fullWidthCells: !0
|
|
71
|
-
}) :
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
71
|
+
}) : g.length === 0 ? null : /* @__PURE__ */ l(o, { children: /* @__PURE__ */ u(s, {
|
|
72
|
+
sx: { gap: 2 },
|
|
73
|
+
children: [/* @__PURE__ */ l(c, {
|
|
74
|
+
variant: "headline1",
|
|
75
|
+
gutterBottom: !0,
|
|
76
|
+
children: "In-flight eDUC signatures"
|
|
77
|
+
}), /* @__PURE__ */ l(n, {
|
|
78
|
+
table: v,
|
|
79
|
+
fullWidth: !0
|
|
80
|
+
})]
|
|
81
|
+
}) });
|
|
80
82
|
}
|
|
81
83
|
//#endregion
|
|
82
|
-
export {
|
|
84
|
+
export { v as InFlightEDucSignaturesTable };
|
|
83
85
|
|
|
84
86
|
//# sourceMappingURL=InFlightEDucSignaturesTable.js.map
|
package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InFlightEDucSignaturesTable.js","names":[],"sources":["../../../../src/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.tsx"],"sourcesContent":["import { SkeletonTable } from '@/components/Skeleton'\nimport ColumnHeader from '@/components/TanStackTable/ColumnHeader'\nimport StyledTanStackTable from '@/components/TanStackTable/StyledTanStackTable'\nimport { useListAllUserDataAccessRequests } from '@/synapse-queries'\nimport { Alert, Box, Typography } from '@mui/material'\nimport {\n AccessRequestSummary,\n AccessRequestSummaryStatusEnum,\n} from '@sage-bionetworks/synapse-client'\nimport {\n createColumnHelper,\n getCoreRowModel,\n useReactTable,\n} from '@tanstack/react-table'\nimport { useMemo } from 'react'\n\nconst IN_FLIGHT_STATUSES: readonly AccessRequestSummaryStatusEnum[] = [\n 'sent',\n 'delivered',\n 'completed',\n] as const\n\nconst STATUS_DISPLAY: Record<string, string> = {\n sent: 'Signatures pending',\n delivered: 'Signatures pending',\n completed: 'Ready to submit',\n}\n\nconst columnHelper = createColumnHelper<AccessRequestSummary>()\nconst columns = [\n columnHelper.accessor('accessRequirementName', {\n header: props => <ColumnHeader {...props} title={'Request type'} />,\n enableSorting: false,\n enableColumnFilter: false,\n }),\n columnHelper.display({\n id: 'signatureProgress',\n header: props => <ColumnHeader {...props} title={'Signature progress'} />,\n enableSorting: false,\n cell: ctx => {\n const acquired = ctx.row.original.signaturesAcquired ?? 0\n const requested = ctx.row.original.signaturesRequested ?? 0\n return `${acquired} of ${requested}`\n },\n enableColumnFilter: false,\n size: 150,\n }),\n columnHelper.accessor('status', {\n header: props => <ColumnHeader {...props} title={'Current status'} />,\n enableSorting: false,\n cell: ctx => {\n const status = ctx.getValue()\n return status ? (STATUS_DISPLAY[status] ?? status) : ''\n },\n enableColumnFilter: false,\n size: 150,\n }),\n]\n\n/**\n * Lists the requester's active eDUC signatures (routed / signed but not yet submitted).\n *\n * The underlying query walks every page of `POST /dataAccessRequest/list` inside its `queryFn`\n * because filtering is done client-side pending PLFM-9907 (which will add an `isEDuc` server-side\n * filter). Once server-side filtering ships, callers can switch back to a per-page infinite query\n * with a \"Show More\" button.\n *\n * Renders nothing when the fully-loaded, filtered list is empty.\n */\nexport function InFlightEDucSignaturesTable() {\n const {\n data: summaries,\n isLoading,\n error,\n } = useListAllUserDataAccessRequests()\n\n const rows = useMemo(\n () =>\n (summaries ?? []).filter(\n summary =>\n summary.isEDuc === true &&\n summary.status !== undefined &&\n (IN_FLIGHT_STATUSES as readonly string[]).includes(summary.status),\n ),\n [summaries],\n )\n\n const table = useReactTable({\n data: rows,\n columns,\n getCoreRowModel: getCoreRowModel(),\n columnResizeMode: 'onChange',\n })\n\n if (error) {\n return (\n <Alert severity={'error'}>\n <strong>\n Sorry, we couldn't load your in-flight eDUC signatures.\n </strong>\n <br />\n {error.reason}\n </Alert>\n )\n }\n\n if (isLoading) {\n return <SkeletonTable numCols={columns.length} fullWidthCells />\n }\n\n if (rows.length === 0) {\n return null\n }\n\n return (\n <Box>\n <
|
|
1
|
+
{"version":3,"file":"InFlightEDucSignaturesTable.js","names":[],"sources":["../../../../src/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.tsx"],"sourcesContent":["import { SkeletonTable } from '@/components/Skeleton'\nimport ColumnHeader from '@/components/TanStackTable/ColumnHeader'\nimport StyledTanStackTable from '@/components/TanStackTable/StyledTanStackTable'\nimport { useListAllUserDataAccessRequests } from '@/synapse-queries'\nimport { Alert, Box, Typography, Stack } from '@mui/material'\nimport {\n AccessRequestSummary,\n AccessRequestSummaryStatusEnum,\n} from '@sage-bionetworks/synapse-client'\nimport {\n createColumnHelper,\n getCoreRowModel,\n useReactTable,\n} from '@tanstack/react-table'\nimport { useMemo } from 'react'\n\nconst IN_FLIGHT_STATUSES: readonly AccessRequestSummaryStatusEnum[] = [\n 'sent',\n 'delivered',\n 'completed',\n] as const\n\nconst STATUS_DISPLAY: Record<string, string> = {\n sent: 'Signatures pending',\n delivered: 'Signatures pending',\n completed: 'Ready to submit',\n}\n\nconst columnHelper = createColumnHelper<AccessRequestSummary>()\nconst columns = [\n columnHelper.accessor('accessRequirementName', {\n header: props => <ColumnHeader {...props} title={'Request type'} />,\n enableSorting: false,\n enableColumnFilter: false,\n }),\n columnHelper.display({\n id: 'signatureProgress',\n header: props => <ColumnHeader {...props} title={'Signature progress'} />,\n enableSorting: false,\n cell: ctx => {\n const acquired = ctx.row.original.signaturesAcquired ?? 0\n const requested = ctx.row.original.signaturesRequested ?? 0\n return `${acquired} of ${requested}`\n },\n enableColumnFilter: false,\n size: 150,\n }),\n columnHelper.accessor('status', {\n header: props => <ColumnHeader {...props} title={'Current status'} />,\n enableSorting: false,\n cell: ctx => {\n const status = ctx.getValue()\n return status ? (STATUS_DISPLAY[status] ?? status) : ''\n },\n enableColumnFilter: false,\n size: 150,\n }),\n]\n\n/**\n * Lists the requester's active eDUC signatures (routed / signed but not yet submitted).\n *\n * The underlying query walks every page of `POST /dataAccessRequest/list` inside its `queryFn`\n * because filtering is done client-side pending PLFM-9907 (which will add an `isEDuc` server-side\n * filter). Once server-side filtering ships, callers can switch back to a per-page infinite query\n * with a \"Show More\" button.\n *\n * Renders nothing when the fully-loaded, filtered list is empty.\n */\nexport function InFlightEDucSignaturesTable() {\n const {\n data: summaries,\n isLoading,\n error,\n } = useListAllUserDataAccessRequests()\n\n const rows = useMemo(\n () =>\n (summaries ?? []).filter(\n summary =>\n summary.isEDuc === true &&\n summary.status !== undefined &&\n (IN_FLIGHT_STATUSES as readonly string[]).includes(summary.status),\n ),\n [summaries],\n )\n\n const table = useReactTable({\n data: rows,\n columns,\n getCoreRowModel: getCoreRowModel(),\n columnResizeMode: 'onChange',\n })\n\n if (error) {\n return (\n <Alert severity={'error'}>\n <strong>\n Sorry, we couldn't load your in-flight eDUC signatures.\n </strong>\n <br />\n {error.reason}\n </Alert>\n )\n }\n\n if (isLoading) {\n return <SkeletonTable numCols={columns.length} fullWidthCells />\n }\n\n if (rows.length === 0) {\n return null\n }\n\n return (\n <Box>\n <Stack\n sx={{\n gap: 2,\n }}\n >\n <Typography variant=\"headline1\" gutterBottom>\n In-flight eDUC signatures\n </Typography>\n <StyledTanStackTable table={table} fullWidth={true} />\n </Stack>\n </Box>\n )\n}\n"],"mappings":";;;;;;;;;;;AAgBA,IAAM,IAAgE;CACpE;CACA;CACA;AACF,GAEM,IAAyC;CAC7C,MAAM;CACN,WAAW;CACX,WAAW;AACb,GAEM,IAAe,EAAyC,GACxD,IAAU;CACd,EAAa,SAAS,yBAAyB;EAC7C,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;EAAiB,CAAA;EAClE,eAAe;EACf,oBAAoB;CACtB,CAAC;CACD,EAAa,QAAQ;EACnB,IAAI;EACJ,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;EAAuB,CAAA;EACxE,eAAe;EACf,OAAM,MAGG,GAFU,EAAI,IAAI,SAAS,sBAAsB,EAErC,MADD,EAAI,IAAI,SAAS,uBAAuB;EAG5D,oBAAoB;EACpB,MAAM;CACR,CAAC;CACD,EAAa,SAAS,UAAU;EAC9B,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;EAAmB,CAAA;EACpE,eAAe;EACf,OAAM,MAAO;GACX,IAAM,IAAS,EAAI,SAAS;GAC5B,OAAO,IAAU,EAAe,MAAW,IAAU;EACvD;EACA,oBAAoB;EACpB,MAAM;CACR,CAAC;AACH;AAYA,SAAgB,IAA8B;CAC5C,IAAM,EACJ,MAAM,GACN,cACA,aACE,EAAiC,GAE/B,IAAO,SAER,KAAa,CAAC,GAAG,QAChB,MACE,EAAQ,WAAW,MACnB,EAAQ,WAAW,KAAA,KAClB,EAAyC,SAAS,EAAQ,MAAM,CACrE,GACF,CAAC,CAAS,CACZ,GAEM,IAAQ,EAAc;EAC1B,MAAM;EACN;EACA,iBAAiB,EAAgB;EACjC,kBAAkB;CACpB,CAAC;CAsBD,OApBI,IAEA,kBAAC,GAAD;EAAO,UAAU;YAAjB;GACE,kBAAC,UAAD,EAAA,UAAQ,0DAEA,CAAA;GACR,kBAAC,MAAD,CAAK,CAAA;GACJ,EAAM;EACF;MAIP,IACK,kBAAC,GAAD;EAAe,SAAS,EAAQ;EAAQ,gBAAA;CAAgB,CAAA,IAG7D,EAAK,WAAW,IACX,OAIP,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;EACE,IAAI,EACF,KAAK,EACP;YAHF,CAKE,kBAAC,GAAD;GAAY,SAAQ;GAAY,cAAA;aAAa;EAEjC,CAAA,GACZ,kBAAC,GAAD;GAA4B;GAAO,WAAW;EAAO,CAAA,CAChD;IACJ,CAAA;AAET"}
|
|
@@ -9,6 +9,7 @@ function f() {
|
|
|
9
9
|
return /* @__PURE__ */ l(a, {
|
|
10
10
|
sx: { gap: 2 },
|
|
11
11
|
children: [
|
|
12
|
+
/* @__PURE__ */ c(e, {}),
|
|
12
13
|
/* @__PURE__ */ c(o, {
|
|
13
14
|
variant: "headline1",
|
|
14
15
|
gutterBottom: !0,
|
|
@@ -38,7 +39,6 @@ function f() {
|
|
|
38
39
|
})
|
|
39
40
|
}), /* @__PURE__ */ c(r, { children: e.details })]
|
|
40
41
|
}, e.summary)) })] }),
|
|
41
|
-
/* @__PURE__ */ c(e, {}),
|
|
42
42
|
/* @__PURE__ */ c(t, {})
|
|
43
43
|
]
|
|
44
44
|
});
|
package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserAccessRequestHistoryPage.js","names":[],"sources":["../../../../src/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPage.tsx"],"sourcesContent":["import ExpandMoreIcon from '@mui/icons-material/ExpandMore'\nimport {\n Accordion,\n AccordionDetails,\n AccordionSummary,\n Stack,\n Typography,\n} from '@mui/material'\nimport { InFlightEDucSignaturesTable } from './InFlightEDucSignaturesTable'\nimport { UserAccessRequestHistoryTable } from './UserAccessRequestHistoryTable'\n\ntype FaqItem = {\n summary: string\n details: string\n}\n\nconst faqContent: FaqItem[] = [\n // {\n // summary:\n // 'Why do I still have access to data when I have an expired, canceled, or rejected access request?',\n // details:\n // \"This table shows all the requests you've ever been part of, including requests that were canceled, rejected, or that have since expired. If an older request was canceled, rejected, or has expired, but a newer request was approved and is still active, you'll still have access to the data.\",\n // },\n // {\n // summary: 'Some other question?',\n // details: 'Here is another answer!',\n // },\n]\n\nexport function UserAccessRequestHistoryPage() {\n return (\n <Stack\n sx={{\n gap: 2,\n }}\n >\n <Typography variant=\"headline1\" gutterBottom>\n History of your access requests\n </Typography>\n <Typography variant=\"body1\" gutterBottom>\n This list represents every access request you have been named in. It\n includes requests you've submitted yourself, and requests submitted\n by others, which you were named as a requester on.\n </Typography>\n <Typography variant=\"body1\" gutterBottom>\n Note: Requests where your access has been revoked will appear as\n "Approved".\n </Typography>\n {faqContent.length > 0 && (\n <>\n <Typography variant=\"headline2\" gutterBottom>\n Frequently Asked Questions\n </Typography>\n <div>\n {faqContent.map(faq => (\n <Accordion key={faq.summary} sx={{ p: 1 }}>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <Typography variant=\"headline3\">{faq.summary}</Typography>\n </AccordionSummary>\n <AccordionDetails>{faq.details}</AccordionDetails>\n </Accordion>\n ))}\n </div>\n </>\n )}\n <
|
|
1
|
+
{"version":3,"file":"UserAccessRequestHistoryPage.js","names":[],"sources":["../../../../src/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPage.tsx"],"sourcesContent":["import ExpandMoreIcon from '@mui/icons-material/ExpandMore'\nimport {\n Accordion,\n AccordionDetails,\n AccordionSummary,\n Stack,\n Typography,\n} from '@mui/material'\nimport { InFlightEDucSignaturesTable } from './InFlightEDucSignaturesTable'\nimport { UserAccessRequestHistoryTable } from './UserAccessRequestHistoryTable'\n\ntype FaqItem = {\n summary: string\n details: string\n}\n\nconst faqContent: FaqItem[] = [\n // {\n // summary:\n // 'Why do I still have access to data when I have an expired, canceled, or rejected access request?',\n // details:\n // \"This table shows all the requests you've ever been part of, including requests that were canceled, rejected, or that have since expired. If an older request was canceled, rejected, or has expired, but a newer request was approved and is still active, you'll still have access to the data.\",\n // },\n // {\n // summary: 'Some other question?',\n // details: 'Here is another answer!',\n // },\n]\n\nexport function UserAccessRequestHistoryPage() {\n return (\n <Stack\n sx={{\n gap: 2,\n }}\n >\n <InFlightEDucSignaturesTable />\n <Typography variant=\"headline1\" gutterBottom>\n History of your access requests\n </Typography>\n <Typography variant=\"body1\" gutterBottom>\n This list represents every access request you have been named in. It\n includes requests you've submitted yourself, and requests submitted\n by others, which you were named as a requester on.\n </Typography>\n <Typography variant=\"body1\" gutterBottom>\n Note: Requests where your access has been revoked will appear as\n "Approved".\n </Typography>\n {faqContent.length > 0 && (\n <>\n <Typography variant=\"headline2\" gutterBottom>\n Frequently Asked Questions\n </Typography>\n <div>\n {faqContent.map(faq => (\n <Accordion key={faq.summary} sx={{ p: 1 }}>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <Typography variant=\"headline3\">{faq.summary}</Typography>\n </AccordionSummary>\n <AccordionDetails>{faq.details}</AccordionDetails>\n </Accordion>\n ))}\n </div>\n </>\n )}\n <UserAccessRequestHistoryTable />\n </Stack>\n )\n}\n"],"mappings":";;;;;;AAgBA,IAAM,IAAwB,CAW9B;AAEA,SAAgB,IAA+B;CAC7C,OACE,kBAAC,GAAD;EACE,IAAI,EACF,KAAK,EACP;YAHF;GAKE,kBAAC,GAAD,CAA8B,CAAA;GAC9B,kBAAC,GAAD;IAAY,SAAQ;IAAY,cAAA;cAAa;GAEjC,CAAA;GACZ,kBAAC,GAAD;IAAY,SAAQ;IAAQ,cAAA;cAAa;GAI7B,CAAA;GACZ,kBAAC,GAAD;IAAY,SAAQ;IAAQ,cAAA;cAAa;GAG7B,CAAA;GACX,EAAW,SAAS,KACnB,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;IAAY,SAAQ;IAAY,cAAA;cAAa;GAEjC,CAAA,GACZ,kBAAC,OAAD,EAAA,UACG,EAAW,KAAI,MACd,kBAAC,GAAD;IAA6B,IAAI,EAAE,GAAG,EAAE;cAAxC,CACE,kBAAC,GAAD;KAAkB,YAAY,kBAAC,GAAD,CAAiB,CAAA;eAC7C,kBAAC,GAAD;MAAY,SAAQ;gBAAa,EAAI;KAAoB,CAAA;IACzC,CAAA,GAClB,kBAAC,GAAD,EAAA,UAAmB,EAAI,QAA0B,CAAA,CACxC;MALK,EAAI,OAKT,CACZ,EACE,CAAA,CACL,EAAA,CAAA;GAEJ,kBAAC,GAAD,CAAgC,CAAA;EAC3B;;AAEX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateOrUpdateDoiModal.d.ts","sourceRoot":"","sources":["../../../src/components/doi/CreateOrUpdateDoiModal.tsx"],"names":[],"mappings":"AAuCA,OAAO,EACL,aAAa,EAKd,MAAM,kCAAkC,CAAA;AAOzC,MAAM,MAAM,2BAA2B,GAAG;IACxC,iCAAiC;IACjC,IAAI,EAAE,OAAO,CAAA;IACb,iDAAiD;IACjD,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,yBAAyB;IACzB,UAAU,EAAE,aAAa,CAAA;IACzB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,2EAA2E;IAC3E,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAmDD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,
|
|
1
|
+
{"version":3,"file":"CreateOrUpdateDoiModal.d.ts","sourceRoot":"","sources":["../../../src/components/doi/CreateOrUpdateDoiModal.tsx"],"names":[],"mappings":"AAuCA,OAAO,EACL,aAAa,EAKd,MAAM,kCAAkC,CAAA;AAOzC,MAAM,MAAM,2BAA2B,GAAG;IACxC,iCAAiC;IACjC,IAAI,EAAE,OAAO,CAAA;IACb,iDAAiD;IACjD,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,yBAAyB;IACzB,UAAU,EAAE,aAAa,CAAA;IACzB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,2EAA2E;IAC3E,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAmDD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,2CA6WxE;AAED,eAAe,sBAAsB,CAAA"}
|
|
@@ -189,19 +189,16 @@ function E(u) {
|
|
|
189
189
|
}, e.versionNumber))]
|
|
190
190
|
})]
|
|
191
191
|
}),
|
|
192
|
-
/* @__PURE__ */ g(
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
formData
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
uiSchema: me,
|
|
203
|
-
showErrorList: !1
|
|
204
|
-
})
|
|
192
|
+
/* @__PURE__ */ g(ge, {
|
|
193
|
+
formRef: J,
|
|
194
|
+
disabled: Q || $,
|
|
195
|
+
schema: pe,
|
|
196
|
+
formData: z,
|
|
197
|
+
onChange: (e) => {
|
|
198
|
+
B(e.formData);
|
|
199
|
+
},
|
|
200
|
+
uiSchema: me,
|
|
201
|
+
showErrorList: !1
|
|
205
202
|
}),
|
|
206
203
|
W && /* @__PURE__ */ g(d, {
|
|
207
204
|
severity: "warning",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateOrUpdateDoiModal.js","names":[],"sources":["../../../src/components/doi/CreateOrUpdateDoiModal.tsx"],"sourcesContent":["import ConfirmCloseWithoutSavingDialog from '@/components/Dialog/ConfirmCloseWithoutSavingDialog'\nimport { DialogBase } from '@/components/DialogBase'\nimport { doiFormSchema, doiFormUiSchema } from '@/components/doi/DoiFormSchemas'\nimport { PrivateEntityDoiWarning } from '@/components/doi/PrivateEntityDoiWarning'\nimport { JsonSchemaForm } from '@/components/JsonSchemaForm/JsonSchemaForm'\nimport { MarkdownPopover } from '@/components/Markdown/MarkdownPopover'\nimport { StyledFormControl } from '@/components/styled/StyledFormControl'\nimport { displayToast } from '@/components/ToastMessage/ToastMessage'\nimport { useCreateOrUpdateDOI, useGetDOI } from '@/synapse-queries/doi/useDOI'\nimport { useGetVersions } from '@/synapse-queries/entity/useEntity'\nimport { useGetEntityBundle } from '@/synapse-queries/entity/useEntityBundle'\nimport { useGetPortal } from '@/synapse-queries/portal/usePortal'\nimport { useGetRealmPrincipals } from '@/synapse-queries/realm/useRealmPrincipals'\nimport { useGetCurrentUserProfile } from '@/synapse-queries/user/useUserBundle'\nimport { useGlobalIsEditingContext } from '@/utils/context/GlobalIsEditingContext'\nimport { isEntityPublic } from '@/utils/functions/AccessControlListUtils'\nimport {\n entityTypeToFriendlyName,\n isDataset,\n isTable,\n isVersionableEntity,\n} from '@/utils/functions/EntityTypeUtils'\nimport {\n BackendDestinationEnum,\n getEndpoint,\n} from '@/utils/functions/getEndpoint'\nimport { DATA_CATALOG_PATH_SEGMENT } from '@/utils/SynapseConstants'\nimport { HelpTwoTone } from '@mui/icons-material'\nimport {\n Alert,\n Button,\n InputLabel,\n Link,\n MenuItem,\n Select,\n TextField,\n Typography,\n} from '@mui/material'\nimport RJSF from '@rjsf/core'\nimport {\n DoiObjectType,\n DoiResourceTypeGeneral,\n DoiResourceTypeResourceTypeGeneralEnum,\n EntityType,\n V2Doi,\n} from '@sage-bionetworks/synapse-client'\nimport { isEmpty } from 'lodash-es'\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\n\ntype CreateOrUpdateDoiModalStep = 'warning' | 'form'\n\nexport type CreateOrUpdateDoiModalProps = {\n /** Whether the dialog is open */\n open: boolean\n /** Callback to call when the dialog is closed */\n onClose: () => void\n /** The type of object */\n objectType: DoiObjectType\n /** The ID of the object */\n objectId: string\n /** The optional version number of the object used to populate the form. */\n defaultVersionNumber?: number\n /** If minting a DOI for a portal, the ID of the portal object in Synapse */\n portalId?: string\n}\n\ntype DoiFormData = {\n titles?: string[]\n creators?: string[]\n resourceTypeGeneral?: DoiResourceTypeResourceTypeGeneralEnum\n publicationYear?: number\n}\n\nfunction getSuggestedResourceTypeGeneral(\n type: EntityType,\n): DoiResourceTypeGeneral {\n if (type === EntityType.project || type === EntityType.folder) {\n return DoiResourceTypeGeneral.Collection\n } else {\n return DoiResourceTypeGeneral.Dataset\n }\n}\n\nfunction convertDoiToFormData(doi: V2Doi): DoiFormData {\n return {\n titles: (doi.titles || []).map(title => title.title!),\n creators: (doi.creators || []).map(creator => creator.creatorName!),\n resourceTypeGeneral: doi.resourceType?.resourceTypeGeneral,\n publicationYear: doi.publicationYear,\n }\n}\n\n/**\n * Returns true if the DOI has fields that are not exposed in the UI, so we can let the user know that any changes\n * may be destructive to hidden fields.\n */\nfunction getWasModifiedViaAPI(doi: V2Doi) {\n if (doi.creators?.some(creator => !isEmpty(creator.nameIdentifiers))) {\n return true\n }\n return false\n}\n\nfunction convertFormDataToDoi(formData: DoiFormData): V2Doi {\n return {\n titles: formData.titles?.map(title => ({ title })) || [],\n creators:\n formData.creators?.map(creator => ({ creatorName: creator })) || [],\n resourceType: {\n resourceTypeGeneral: formData.resourceTypeGeneral,\n },\n publicationYear: formData.publicationYear,\n }\n}\n\nexport function CreateOrUpdateDoiModal(props: CreateOrUpdateDoiModalProps) {\n const {\n open,\n onClose,\n objectType,\n objectId,\n defaultVersionNumber,\n portalId,\n } = props\n\n const [showConfirmCloseModal, setShowConfirmCloseDialog] = useState(false)\n const [currentStep, setCurrentStep] =\n useState<CreateOrUpdateDoiModalStep | null>(null)\n const hasSetInitialStepForThisSession = useRef(false)\n const { isEditing, setIsEditing } = useGlobalIsEditingContext()\n useEffect(() => {\n setIsEditing(open)\n\n return () => {\n setIsEditing(false)\n }\n }, [open, setIsEditing])\n\n function handleClose() {\n if (isEditing) {\n setShowConfirmCloseDialog(true)\n } else {\n onClose()\n }\n }\n\n const [selectedVersionNumber, setSelectedVersionNumber] =\n useState(defaultVersionNumber)\n\n const { data: portal } = useGetPortal(portalId!, {\n enabled: Boolean(portalId),\n })\n\n const [formData, setFormData] = useState<DoiFormData>({\n titles: [''],\n creators: [''],\n })\n const { data: currentUser, isLoading: isLoadingCurrentUser } =\n useGetCurrentUserProfile()\n const { data: entityBundle, isLoading: isLoadingEntity } = useGetEntityBundle(\n objectId,\n selectedVersionNumber,\n {\n includeEntity: true,\n includeBenefactorACL: true,\n },\n {\n enabled: objectType === DoiObjectType.ENTITY,\n staleTime: Infinity,\n throwOnError: true,\n },\n )\n const { data: realmPrincipals, isLoading: isLoadingRealmPrincipals } =\n useGetRealmPrincipals()\n const { data: doi, isLoading: isLoadingDoi } = useGetDOI(\n {\n id: objectId,\n version: selectedVersionNumber,\n type: objectType,\n portalId: portalId,\n },\n {\n staleTime: Infinity,\n throwOnError: true,\n },\n )\n\n const shouldShowWarning = useMemo(() => {\n if (objectType !== DoiObjectType.ENTITY) {\n return false\n }\n return (\n open &&\n doi === null && // Creating new DOI\n entityBundle?.benefactorAcl &&\n realmPrincipals &&\n !isEntityPublic(\n entityBundle.benefactorAcl.resourceAccess,\n realmPrincipals,\n )\n )\n }, [open, doi, entityBundle, realmPrincipals, objectType])\n\n useEffect(() => {\n if (\n open &&\n !hasSetInitialStepForThisSession.current &&\n doi !== undefined && // Wait for DOI query to resolve before determining step\n shouldShowWarning !== undefined\n ) {\n const newStep = shouldShowWarning ? 'warning' : 'form'\n setCurrentStep(newStep)\n hasSetInitialStepForThisSession.current = true\n } else if (!open) {\n setCurrentStep(null)\n hasSetInitialStepForThisSession.current = false\n }\n }, [shouldShowWarning, open, doi])\n\n const doiCanBeAppliedToVersion =\n objectType === DoiObjectType.ENTITY &&\n entityBundle?.entity &&\n isVersionableEntity(entityBundle.entity)\n\n const { data: entityVersions } = useGetVersions(\n objectId,\n undefined,\n undefined,\n {\n enabled: doiCanBeAppliedToVersion,\n },\n )\n const formRef = useRef<RJSF>(null)\n\n const entityType = entityBundle?.entityType ?? EntityType.file\n const entityTypeDisplay = entityTypeToFriendlyName(entityType)\n let versionHelpMarkdown = `A DOI can be associated with a specific version of this ${entityTypeDisplay}.\n \n Versioned DOIs will link to the specified version of the ${entityTypeDisplay}.\n \n A DOI without a version will always link to the newest version of this ${entityTypeDisplay},\n so the data that someone retrieves using the DOI may change over time.`\n if (entityBundle?.entity && isTable(entityBundle.entity)) {\n const tableVersionCopy = isDataset(entityBundle.entity)\n ? 'version'\n : 'snapshot'\n versionHelpMarkdown += `\\n\\nTo create a DOI that will always link to the current set of data in the ${entityTypeDisplay},\n create a new ${tableVersionCopy} and mint a DOI for that ${tableVersionCopy}.`\n }\n\n const {\n mutate: createOrUpdateDoi,\n isPending: updateIsPending,\n error: updateDoiError,\n } = useCreateOrUpdateDOI({\n onSuccess: () => {\n displayToast('The DOI was successfully updated.', 'success')\n onClose()\n },\n })\n\n const isLoading =\n updateIsPending ||\n isLoadingCurrentUser ||\n isLoadingEntity ||\n isLoadingDoi ||\n isLoadingRealmPrincipals\n\n const wasModifiedViaAPI = Boolean(doi && getWasModifiedViaAPI(doi))\n\n useEffect(() => {\n if (doi) {\n setFormData(convertDoiToFormData(doi))\n }\n // If there is no DOI, then pre-fill the form.\n if (currentUser && entityBundle?.entity && doi === null) {\n const newFormData = {\n titles: [entityBundle.entity.name],\n creators: new Array<string>(),\n resourceTypeGeneral: getSuggestedResourceTypeGeneral(\n entityBundle.entityType,\n ),\n publicationYear: new Date().getFullYear(),\n } satisfies DoiFormData\n if (currentUser.lastName && currentUser.firstName) {\n newFormData.creators.push(\n `${currentUser.lastName}, ${currentUser.firstName}`,\n )\n }\n setFormData(newFormData)\n }\n }, [currentUser, doi, entityBundle])\n\n function onSave() {\n if (formRef.current && formRef.current.validateForm()) {\n const requestDoi: V2Doi = convertFormDataToDoi(formData)\n requestDoi.objectType = objectType\n requestDoi.objectId = objectId\n requestDoi.objectVersion = selectedVersionNumber\n requestDoi.etag = doi?.etag\n requestDoi.portalId = portalId\n createOrUpdateDoi({\n doi: requestDoi,\n concreteType: 'org.sagebionetworks.repo.model.doi.v2.DoiRequest',\n })\n }\n }\n\n const dialogContent = (\n <>\n <Typography variant={'body1'} gutterBottom>\n Minting a DOI allows you to credit contributors and makes it easy to\n cite your work.\n </Typography>\n <Typography variant={'body1'} gutterBottom sx={{ mb: 2 }}>\n Note that while the DOI and its associated metadata will be publicly\n visible outside of Synapse, your data will still adhere to its existing\n access conditions. If your data is private, it will remain restricted,\n but the DOI will still be listed. Resources with DOIs may be added to\n the{' '}\n <Link\n href={`${getEndpoint(\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )}${DATA_CATALOG_PATH_SEGMENT}`}\n target=\"_blank\"\n rel=\"noopener\"\n >\n Synapse Data Catalog\n </Link>\n .\n </Typography>\n {portalId && (\n <TextField\n label={'Publisher'}\n fullWidth\n value={portal?.name || ''}\n disabled\n />\n )}\n {doiCanBeAppliedToVersion && (\n <StyledFormControl className=\"limit-type\" fullWidth sx={{ my: 2 }}>\n <InputLabel\n id=\"doi-version-select\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n }}\n >\n <span>Version</span>\n <MarkdownPopover\n contentProps={{ markdown: versionHelpMarkdown }}\n maxWidth=\"350px\"\n >\n <HelpTwoTone className={`HelpButton`} />\n </MarkdownPopover>\n </InputLabel>\n <Select\n labelId=\"doi-version-select\"\n value={selectedVersionNumber ?? -1}\n onChange={e => {\n if (e.target.value === -1) {\n setSelectedVersionNumber(undefined)\n } else {\n setSelectedVersionNumber(e.target.value)\n }\n }}\n >\n <MenuItem value={-1}>No version</MenuItem>\n {entityVersions &&\n entityVersions.results.map(version => (\n <MenuItem\n key={version.versionNumber}\n value={version.versionNumber}\n >\n Version {version.versionNumber}\n {/* display the version label if it exists & is different from the number itself */}\n {version.versionLabel &&\n version.versionLabel !== String(version.versionNumber)\n ? ` / ${version.versionLabel}`\n : ''}\n </MenuItem>\n ))}\n </Select>\n </StyledFormControl>\n )}\n <div className=\"JsonSchemaFormContainer\">\n <JsonSchemaForm\n formRef={formRef}\n disabled={isLoading || wasModifiedViaAPI}\n schema={doiFormSchema}\n formData={formData}\n onChange={e => {\n setFormData(e.formData)\n }}\n uiSchema={doiFormUiSchema}\n showErrorList={false}\n />\n </div>\n {doi && (\n <Alert severity={'warning'}>\n <Typography variant={'body1'}>\n A DOI has already been created. Updating the DOI information will\n cause old information to be lost!\n </Typography>\n </Alert>\n )}\n {wasModifiedViaAPI && (\n <Alert severity={'warning'} sx={{ my: 1 }}>\n <Typography variant={'body1'}>\n The metadata for this DOI was modified using a programmatic client,\n so data may be hidden from this view. Any changes may result in\n metadata being lost.\n </Typography>\n </Alert>\n )}\n {updateDoiError && (\n <Alert severity={'error'} sx={{ mt: 1 }}>\n <Typography variant={'body1'}>{updateDoiError.message}</Typography>\n </Alert>\n )}\n </>\n )\n\n const dialogActions = (\n <>\n <Button variant=\"outlined\" disabled={isLoading} onClick={handleClose}>\n Cancel\n </Button>\n <Button\n variant=\"contained\"\n disabled={isLoading}\n onClick={\n currentStep === 'warning'\n ? () => setCurrentStep('form')\n : e => {\n // SWC-7055 - The default action may trigger `beforeunload` and erroneously warn the user about leaving the page.\n e.preventDefault()\n onSave()\n }\n }\n >\n {currentStep === 'warning' ? 'Continue' : 'Save'}\n </Button>\n </>\n )\n\n return (\n <>\n <ConfirmCloseWithoutSavingDialog\n open={showConfirmCloseModal}\n onCancel={() => {\n setShowConfirmCloseDialog(false)\n }}\n onConfirm={() => {\n setShowConfirmCloseDialog(false)\n onClose()\n }}\n />\n <DialogBase\n open={open}\n onCancel={handleClose}\n title={\n currentStep === 'warning'\n ? 'This page is private'\n : 'Create or Update a DOI'\n }\n content={\n !currentStep ? (\n <SynapseSpinner />\n ) : (\n <>\n {currentStep === 'warning' && <PrivateEntityDoiWarning />}\n {currentStep === 'form' && dialogContent}\n </>\n )\n }\n actions={dialogActions}\n />\n </>\n )\n}\n\nexport default CreateOrUpdateDoiModal\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CreateOrUpdateDoiModal.js","names":[],"sources":["../../../src/components/doi/CreateOrUpdateDoiModal.tsx"],"sourcesContent":["import ConfirmCloseWithoutSavingDialog from '@/components/Dialog/ConfirmCloseWithoutSavingDialog'\nimport { DialogBase } from '@/components/DialogBase'\nimport { doiFormSchema, doiFormUiSchema } from '@/components/doi/DoiFormSchemas'\nimport { PrivateEntityDoiWarning } from '@/components/doi/PrivateEntityDoiWarning'\nimport { JsonSchemaForm } from '@/components/JsonSchemaForm/JsonSchemaForm'\nimport { MarkdownPopover } from '@/components/Markdown/MarkdownPopover'\nimport { StyledFormControl } from '@/components/styled/StyledFormControl'\nimport { displayToast } from '@/components/ToastMessage/ToastMessage'\nimport { useCreateOrUpdateDOI, useGetDOI } from '@/synapse-queries/doi/useDOI'\nimport { useGetVersions } from '@/synapse-queries/entity/useEntity'\nimport { useGetEntityBundle } from '@/synapse-queries/entity/useEntityBundle'\nimport { useGetPortal } from '@/synapse-queries/portal/usePortal'\nimport { useGetRealmPrincipals } from '@/synapse-queries/realm/useRealmPrincipals'\nimport { useGetCurrentUserProfile } from '@/synapse-queries/user/useUserBundle'\nimport { useGlobalIsEditingContext } from '@/utils/context/GlobalIsEditingContext'\nimport { isEntityPublic } from '@/utils/functions/AccessControlListUtils'\nimport {\n entityTypeToFriendlyName,\n isDataset,\n isTable,\n isVersionableEntity,\n} from '@/utils/functions/EntityTypeUtils'\nimport {\n BackendDestinationEnum,\n getEndpoint,\n} from '@/utils/functions/getEndpoint'\nimport { DATA_CATALOG_PATH_SEGMENT } from '@/utils/SynapseConstants'\nimport { HelpTwoTone } from '@mui/icons-material'\nimport {\n Alert,\n Button,\n InputLabel,\n Link,\n MenuItem,\n Select,\n TextField,\n Typography,\n} from '@mui/material'\nimport RJSF from '@rjsf/core'\nimport {\n DoiObjectType,\n DoiResourceTypeGeneral,\n DoiResourceTypeResourceTypeGeneralEnum,\n EntityType,\n V2Doi,\n} from '@sage-bionetworks/synapse-client'\nimport { isEmpty } from 'lodash-es'\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\n\ntype CreateOrUpdateDoiModalStep = 'warning' | 'form'\n\nexport type CreateOrUpdateDoiModalProps = {\n /** Whether the dialog is open */\n open: boolean\n /** Callback to call when the dialog is closed */\n onClose: () => void\n /** The type of object */\n objectType: DoiObjectType\n /** The ID of the object */\n objectId: string\n /** The optional version number of the object used to populate the form. */\n defaultVersionNumber?: number\n /** If minting a DOI for a portal, the ID of the portal object in Synapse */\n portalId?: string\n}\n\ntype DoiFormData = {\n titles?: string[]\n creators?: string[]\n resourceTypeGeneral?: DoiResourceTypeResourceTypeGeneralEnum\n publicationYear?: number\n}\n\nfunction getSuggestedResourceTypeGeneral(\n type: EntityType,\n): DoiResourceTypeGeneral {\n if (type === EntityType.project || type === EntityType.folder) {\n return DoiResourceTypeGeneral.Collection\n } else {\n return DoiResourceTypeGeneral.Dataset\n }\n}\n\nfunction convertDoiToFormData(doi: V2Doi): DoiFormData {\n return {\n titles: (doi.titles || []).map(title => title.title!),\n creators: (doi.creators || []).map(creator => creator.creatorName!),\n resourceTypeGeneral: doi.resourceType?.resourceTypeGeneral,\n publicationYear: doi.publicationYear,\n }\n}\n\n/**\n * Returns true if the DOI has fields that are not exposed in the UI, so we can let the user know that any changes\n * may be destructive to hidden fields.\n */\nfunction getWasModifiedViaAPI(doi: V2Doi) {\n if (doi.creators?.some(creator => !isEmpty(creator.nameIdentifiers))) {\n return true\n }\n return false\n}\n\nfunction convertFormDataToDoi(formData: DoiFormData): V2Doi {\n return {\n titles: formData.titles?.map(title => ({ title })) || [],\n creators:\n formData.creators?.map(creator => ({ creatorName: creator })) || [],\n resourceType: {\n resourceTypeGeneral: formData.resourceTypeGeneral,\n },\n publicationYear: formData.publicationYear,\n }\n}\n\nexport function CreateOrUpdateDoiModal(props: CreateOrUpdateDoiModalProps) {\n const {\n open,\n onClose,\n objectType,\n objectId,\n defaultVersionNumber,\n portalId,\n } = props\n\n const [showConfirmCloseModal, setShowConfirmCloseDialog] = useState(false)\n const [currentStep, setCurrentStep] =\n useState<CreateOrUpdateDoiModalStep | null>(null)\n const hasSetInitialStepForThisSession = useRef(false)\n const { isEditing, setIsEditing } = useGlobalIsEditingContext()\n useEffect(() => {\n setIsEditing(open)\n\n return () => {\n setIsEditing(false)\n }\n }, [open, setIsEditing])\n\n function handleClose() {\n if (isEditing) {\n setShowConfirmCloseDialog(true)\n } else {\n onClose()\n }\n }\n\n const [selectedVersionNumber, setSelectedVersionNumber] =\n useState(defaultVersionNumber)\n\n const { data: portal } = useGetPortal(portalId!, {\n enabled: Boolean(portalId),\n })\n\n const [formData, setFormData] = useState<DoiFormData>({\n titles: [''],\n creators: [''],\n })\n const { data: currentUser, isLoading: isLoadingCurrentUser } =\n useGetCurrentUserProfile()\n const { data: entityBundle, isLoading: isLoadingEntity } = useGetEntityBundle(\n objectId,\n selectedVersionNumber,\n {\n includeEntity: true,\n includeBenefactorACL: true,\n },\n {\n enabled: objectType === DoiObjectType.ENTITY,\n staleTime: Infinity,\n throwOnError: true,\n },\n )\n const { data: realmPrincipals, isLoading: isLoadingRealmPrincipals } =\n useGetRealmPrincipals()\n const { data: doi, isLoading: isLoadingDoi } = useGetDOI(\n {\n id: objectId,\n version: selectedVersionNumber,\n type: objectType,\n portalId: portalId,\n },\n {\n staleTime: Infinity,\n throwOnError: true,\n },\n )\n\n const shouldShowWarning = useMemo(() => {\n if (objectType !== DoiObjectType.ENTITY) {\n return false\n }\n return (\n open &&\n doi === null && // Creating new DOI\n entityBundle?.benefactorAcl &&\n realmPrincipals &&\n !isEntityPublic(\n entityBundle.benefactorAcl.resourceAccess,\n realmPrincipals,\n )\n )\n }, [open, doi, entityBundle, realmPrincipals, objectType])\n\n useEffect(() => {\n if (\n open &&\n !hasSetInitialStepForThisSession.current &&\n doi !== undefined && // Wait for DOI query to resolve before determining step\n shouldShowWarning !== undefined\n ) {\n const newStep = shouldShowWarning ? 'warning' : 'form'\n setCurrentStep(newStep)\n hasSetInitialStepForThisSession.current = true\n } else if (!open) {\n setCurrentStep(null)\n hasSetInitialStepForThisSession.current = false\n }\n }, [shouldShowWarning, open, doi])\n\n const doiCanBeAppliedToVersion =\n objectType === DoiObjectType.ENTITY &&\n entityBundle?.entity &&\n isVersionableEntity(entityBundle.entity)\n\n const { data: entityVersions } = useGetVersions(\n objectId,\n undefined,\n undefined,\n {\n enabled: doiCanBeAppliedToVersion,\n },\n )\n const formRef = useRef<RJSF>(null)\n\n const entityType = entityBundle?.entityType ?? EntityType.file\n const entityTypeDisplay = entityTypeToFriendlyName(entityType)\n let versionHelpMarkdown = `A DOI can be associated with a specific version of this ${entityTypeDisplay}.\n \n Versioned DOIs will link to the specified version of the ${entityTypeDisplay}.\n \n A DOI without a version will always link to the newest version of this ${entityTypeDisplay},\n so the data that someone retrieves using the DOI may change over time.`\n if (entityBundle?.entity && isTable(entityBundle.entity)) {\n const tableVersionCopy = isDataset(entityBundle.entity)\n ? 'version'\n : 'snapshot'\n versionHelpMarkdown += `\\n\\nTo create a DOI that will always link to the current set of data in the ${entityTypeDisplay},\n create a new ${tableVersionCopy} and mint a DOI for that ${tableVersionCopy}.`\n }\n\n const {\n mutate: createOrUpdateDoi,\n isPending: updateIsPending,\n error: updateDoiError,\n } = useCreateOrUpdateDOI({\n onSuccess: () => {\n displayToast('The DOI was successfully updated.', 'success')\n onClose()\n },\n })\n\n const isLoading =\n updateIsPending ||\n isLoadingCurrentUser ||\n isLoadingEntity ||\n isLoadingDoi ||\n isLoadingRealmPrincipals\n\n const wasModifiedViaAPI = Boolean(doi && getWasModifiedViaAPI(doi))\n\n useEffect(() => {\n if (doi) {\n setFormData(convertDoiToFormData(doi))\n }\n // If there is no DOI, then pre-fill the form.\n if (currentUser && entityBundle?.entity && doi === null) {\n const newFormData = {\n titles: [entityBundle.entity.name],\n creators: new Array<string>(),\n resourceTypeGeneral: getSuggestedResourceTypeGeneral(\n entityBundle.entityType,\n ),\n publicationYear: new Date().getFullYear(),\n } satisfies DoiFormData\n if (currentUser.lastName && currentUser.firstName) {\n newFormData.creators.push(\n `${currentUser.lastName}, ${currentUser.firstName}`,\n )\n }\n setFormData(newFormData)\n }\n }, [currentUser, doi, entityBundle])\n\n function onSave() {\n if (formRef.current && formRef.current.validateForm()) {\n const requestDoi: V2Doi = convertFormDataToDoi(formData)\n requestDoi.objectType = objectType\n requestDoi.objectId = objectId\n requestDoi.objectVersion = selectedVersionNumber\n requestDoi.etag = doi?.etag\n requestDoi.portalId = portalId\n createOrUpdateDoi({\n doi: requestDoi,\n concreteType: 'org.sagebionetworks.repo.model.doi.v2.DoiRequest',\n })\n }\n }\n\n const dialogContent = (\n <>\n <Typography variant={'body1'} gutterBottom>\n Minting a DOI allows you to credit contributors and makes it easy to\n cite your work.\n </Typography>\n <Typography variant={'body1'} gutterBottom sx={{ mb: 2 }}>\n Note that while the DOI and its associated metadata will be publicly\n visible outside of Synapse, your data will still adhere to its existing\n access conditions. If your data is private, it will remain restricted,\n but the DOI will still be listed. Resources with DOIs may be added to\n the{' '}\n <Link\n href={`${getEndpoint(\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )}${DATA_CATALOG_PATH_SEGMENT}`}\n target=\"_blank\"\n rel=\"noopener\"\n >\n Synapse Data Catalog\n </Link>\n .\n </Typography>\n {portalId && (\n <TextField\n label={'Publisher'}\n fullWidth\n value={portal?.name || ''}\n disabled\n />\n )}\n {doiCanBeAppliedToVersion && (\n <StyledFormControl className=\"limit-type\" fullWidth sx={{ my: 2 }}>\n <InputLabel\n id=\"doi-version-select\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n }}\n >\n <span>Version</span>\n <MarkdownPopover\n contentProps={{ markdown: versionHelpMarkdown }}\n maxWidth=\"350px\"\n >\n <HelpTwoTone className={`HelpButton`} />\n </MarkdownPopover>\n </InputLabel>\n <Select\n labelId=\"doi-version-select\"\n value={selectedVersionNumber ?? -1}\n onChange={e => {\n if (e.target.value === -1) {\n setSelectedVersionNumber(undefined)\n } else {\n setSelectedVersionNumber(e.target.value)\n }\n }}\n >\n <MenuItem value={-1}>No version</MenuItem>\n {entityVersions &&\n entityVersions.results.map(version => (\n <MenuItem\n key={version.versionNumber}\n value={version.versionNumber}\n >\n Version {version.versionNumber}\n {/* display the version label if it exists & is different from the number itself */}\n {version.versionLabel &&\n version.versionLabel !== String(version.versionNumber)\n ? ` / ${version.versionLabel}`\n : ''}\n </MenuItem>\n ))}\n </Select>\n </StyledFormControl>\n )}\n <JsonSchemaForm\n formRef={formRef}\n disabled={isLoading || wasModifiedViaAPI}\n schema={doiFormSchema}\n formData={formData}\n onChange={e => {\n setFormData(e.formData)\n }}\n uiSchema={doiFormUiSchema}\n showErrorList={false}\n />\n {doi && (\n <Alert severity={'warning'}>\n <Typography variant={'body1'}>\n A DOI has already been created. Updating the DOI information will\n cause old information to be lost!\n </Typography>\n </Alert>\n )}\n {wasModifiedViaAPI && (\n <Alert severity={'warning'} sx={{ my: 1 }}>\n <Typography variant={'body1'}>\n The metadata for this DOI was modified using a programmatic client,\n so data may be hidden from this view. Any changes may result in\n metadata being lost.\n </Typography>\n </Alert>\n )}\n {updateDoiError && (\n <Alert severity={'error'} sx={{ mt: 1 }}>\n <Typography variant={'body1'}>{updateDoiError.message}</Typography>\n </Alert>\n )}\n </>\n )\n\n const dialogActions = (\n <>\n <Button variant=\"outlined\" disabled={isLoading} onClick={handleClose}>\n Cancel\n </Button>\n <Button\n variant=\"contained\"\n disabled={isLoading}\n onClick={\n currentStep === 'warning'\n ? () => setCurrentStep('form')\n : e => {\n // SWC-7055 - The default action may trigger `beforeunload` and erroneously warn the user about leaving the page.\n e.preventDefault()\n onSave()\n }\n }\n >\n {currentStep === 'warning' ? 'Continue' : 'Save'}\n </Button>\n </>\n )\n\n return (\n <>\n <ConfirmCloseWithoutSavingDialog\n open={showConfirmCloseModal}\n onCancel={() => {\n setShowConfirmCloseDialog(false)\n }}\n onConfirm={() => {\n setShowConfirmCloseDialog(false)\n onClose()\n }}\n />\n <DialogBase\n open={open}\n onCancel={handleClose}\n title={\n currentStep === 'warning'\n ? 'This page is private'\n : 'Create or Update a DOI'\n }\n content={\n !currentStep ? (\n <SynapseSpinner />\n ) : (\n <>\n {currentStep === 'warning' && <PrivateEntityDoiWarning />}\n {currentStep === 'form' && dialogContent}\n </>\n )\n }\n actions={dialogActions}\n />\n </>\n )\n}\n\nexport default CreateOrUpdateDoiModal\n"],"mappings":"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"}
|
|
@@ -94,6 +94,7 @@ export * from './HelpPopover';
|
|
|
94
94
|
export * from './MuiContainer';
|
|
95
95
|
export * from './JsonLdScript';
|
|
96
96
|
export * from './DatasetJsonLdScript';
|
|
97
|
+
export * from './DatasetHosting';
|
|
97
98
|
export * from './SageResourcesPopover';
|
|
98
99
|
export * from './RecentPublicationsGrid';
|
|
99
100
|
export * from './ImageCardGridWithLinks';
|