synapse-react-client 3.3.6 → 3.3.7

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.
@@ -20,7 +20,7 @@ var __privateWrapper = (obj, member, setter, getter) => ({
20
20
  return __privateGet(obj, member, getter);
21
21
  }
22
22
  });
23
- /*! SRC v3.3.6 */
23
+ /*! SRC v3.3.7 */
24
24
 
25
25
  var _focused, _cleanup, _setup, _a2, _online, _cleanup2, _setup2, _b, _gcTimeout, _c, _initialState, _revertState, _cache, _promise, _retryer, _observers, _defaultOptions, _abortSignalConsumed, _Query_instances, setOptions_fn, dispatch_fn, _d, _queries, _e2, _observers2, _defaultOptions2, _mutationCache, _retryer2, _Mutation_instances, dispatch_fn2, _f, _mutations, _mutationId, _resuming, _g, _queryCache, _mutationCache2, _defaultOptions3, _queryDefaults, _mutationDefaults, _mountCount, _unsubscribeFocus, _unsubscribeOnline, _h, _client, _currentQuery, _currentQueryInitialState, _currentResult, _currentResultState, _currentResultOptions, _selectError, _selectFn, _selectResult, _lastQueryWithDefinedData, _staleTimeoutId, _refetchIntervalId, _currentRefetchInterval, _trackedProps, _QueryObserver_instances, executeFetch_fn, updateStaleTimeout_fn, computeRefetchInterval_fn, updateRefetchInterval_fn, updateTimers_fn, clearStaleTimeout_fn, clearRefetchInterval_fn, updateQuery_fn, notify_fn, _i, _client2, _result, _queries2, _observers3, _options, _combinedResult, _QueriesObserver_instances, setResult_fn, combineResult_fn, findMatchingObservers_fn, onUpdate_fn, notify_fn2, _j, _client3, _currentResult2, _currentMutation, _mutateOptions, _MutationObserver_instances, updateResult_fn, notify_fn3, _k, _l;
26
26
  function _interopNamespaceDefault(e2) {
@@ -7647,7 +7647,7 @@ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_liter
7647
7647
  const functionName = getFunctionComponentName(innerType);
7648
7648
  return outerType.displayName || (functionName !== "" ? `${wrapperName}(${functionName})` : wrapperName);
7649
7649
  }
7650
- function getDisplayName$2(Component) {
7650
+ function getDisplayName$3(Component) {
7651
7651
  if (Component == null) {
7652
7652
  return void 0;
7653
7653
  }
@@ -7669,9 +7669,9 @@ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_liter
7669
7669
  }
7670
7670
  return void 0;
7671
7671
  }
7672
- const getDisplayName$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
7672
+ const getDisplayName$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
7673
7673
  __proto__: null,
7674
- default: getDisplayName$2,
7674
+ default: getDisplayName$3,
7675
7675
  getFunctionName
7676
7676
  }, Symbol.toStringTag, { value: "Module" }));
7677
7677
  const _excluded$24 = ["ownerState"], _excluded2$k = ["variants"], _excluded3$8 = ["name", "slot", "skipVariantsResolver", "skipSx", "overridesResolver"];
@@ -7866,7 +7866,7 @@ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_liter
7866
7866
  displayName = `${componentName}${capitalize$1(componentSlot || "")}`;
7867
7867
  }
7868
7868
  if (displayName === void 0) {
7869
- displayName = `Styled(${getDisplayName$2(tag)})`;
7869
+ displayName = `Styled(${getDisplayName$3(tag)})`;
7870
7870
  }
7871
7871
  Component.displayName = displayName;
7872
7872
  }
@@ -9872,7 +9872,7 @@ Please use another name.` : formatMuiErrorMessage$1(18));
9872
9872
  const require$$1 = /* @__PURE__ */ getAugmentedNamespace(styledEngine);
9873
9873
  const require$$4 = /* @__PURE__ */ getAugmentedNamespace(deepmerge);
9874
9874
  const require$$5 = /* @__PURE__ */ getAugmentedNamespace(capitalize);
9875
- const require$$6 = /* @__PURE__ */ getAugmentedNamespace(getDisplayName$1);
9875
+ const require$$6 = /* @__PURE__ */ getAugmentedNamespace(getDisplayName$2);
9876
9876
  const require$$7 = /* @__PURE__ */ getAugmentedNamespace(createTheme$2);
9877
9877
  const require$$8 = /* @__PURE__ */ getAugmentedNamespace(styleFunctionSx);
9878
9878
  var _interopRequireDefault$c = interopRequireDefaultExports;
@@ -39915,6 +39915,7 @@ Please use another name.` : formatMuiErrorMessage$1(18));
39915
39915
  }) => {
39916
39916
  return result.isError && !errorResetBoundary.isReset() && !result.isFetching && query && shouldThrowError(throwOnError, [result.error, query]);
39917
39917
  };
39918
+ var defaultThrowOnError = (_error, query) => typeof query.state.data === "undefined";
39918
39919
  var ensureStaleTime = (defaultedOptions) => {
39919
39920
  if (defaultedOptions.suspense) {
39920
39921
  if (typeof defaultedOptions.staleTime !== "number") {
@@ -40063,6 +40064,17 @@ Please use another name.` : formatMuiErrorMessage$1(18));
40063
40064
  function useQuery(options2, queryClient) {
40064
40065
  return useBaseQuery(options2, QueryObserver);
40065
40066
  }
40067
+ function useSuspenseQuery(options2, queryClient) {
40068
+ return useBaseQuery(
40069
+ {
40070
+ ...options2,
40071
+ enabled: true,
40072
+ suspense: true,
40073
+ throwOnError: defaultThrowOnError
40074
+ },
40075
+ QueryObserver
40076
+ );
40077
+ }
40066
40078
  function useMutation(options2, queryClient) {
40067
40079
  const client = useQueryClient();
40068
40080
  const [observer] = React__namespace.useState(
@@ -40705,6 +40717,7 @@ Please use another name.` : formatMuiErrorMessage$1(18));
40705
40717
  FeatureFlagEnum2["DESCRIPTION_FIELD"] = "DESCRIPTION_FIELD";
40706
40718
  FeatureFlagEnum2["VIRTUALTABLE_SUPPORT"] = "VIRTUALTABLE_SUPPORT";
40707
40719
  FeatureFlagEnum2["JSONSCHEMA_VALIDATION_STATUS"] = "JSONSCHEMA_VALIDATION_STATUS";
40720
+ FeatureFlagEnum2["REACT_ENTITY_ACL_EDITOR"] = "REACT_ENTITY_ACL_EDITOR";
40708
40721
  return FeatureFlagEnum2;
40709
40722
  })(FeatureFlagEnum || {});
40710
40723
  var S3_FILE_HANDLE_CONCRETE_TYPE_VALUE = "org.sagebionetworks.repo.model.file.S3FileHandle";
@@ -46405,7 +46418,7 @@ Please use another name.` : formatMuiErrorMessage$1(18));
46405
46418
  lightPrimary: { ...generatePalette("#f8f9fa"), contrastText: "#164B6E" },
46406
46419
  light: { ...generatePalette("#f8f9fa"), contrastText: "#22252a" },
46407
46420
  // grey-1000
46408
- success: { main: "#32a330" },
46421
+ success: { main: "#32a330", contrastText: "#ffffff" },
46409
46422
  info: { main: "#017fa5" },
46410
46423
  warning: { main: "#cc9f00" },
46411
46424
  error: { main: "#c13415" },
@@ -49514,6 +49527,44 @@ Please use another name.` : formatMuiErrorMessage$1(18));
49514
49527
  } else return void 0;
49515
49528
  }
49516
49529
  }
49530
+ function useGetEntityBundleQueryOptions(entityId, version2, bundleRequest = ALL_ENTITY_BUNDLE_FIELDS) {
49531
+ const { accessToken, keyFactory } = useSynapseContext();
49532
+ return {
49533
+ queryKey: keyFactory.getEntityBundleQueryKey(
49534
+ entityId,
49535
+ version2,
49536
+ bundleRequest
49537
+ ),
49538
+ queryFn: () => SynapseClient.getEntityBundleV2(
49539
+ entityId,
49540
+ bundleRequest,
49541
+ version2,
49542
+ accessToken
49543
+ )
49544
+ };
49545
+ }
49546
+ function useGetEntityBundle(entityId, version2, bundleRequest = ALL_ENTITY_BUNDLE_FIELDS, options2) {
49547
+ const queryOptions = useGetEntityBundleQueryOptions(
49548
+ entityId,
49549
+ version2,
49550
+ bundleRequest
49551
+ );
49552
+ return useQuery({
49553
+ ...options2,
49554
+ ...queryOptions
49555
+ });
49556
+ }
49557
+ function useSuspenseGetEntityBundle(entityId, version2, bundleRequest = ALL_ENTITY_BUNDLE_FIELDS, options2) {
49558
+ const queryOptions = useGetEntityBundleQueryOptions(
49559
+ entityId,
49560
+ version2,
49561
+ bundleRequest
49562
+ );
49563
+ return useSuspenseQuery({
49564
+ ...options2,
49565
+ ...queryOptions
49566
+ });
49567
+ }
49517
49568
  function useGetEntity(entityId, versionNumber, options2) {
49518
49569
  const { accessToken, keyFactory } = useSynapseContext();
49519
49570
  return useQuery({
@@ -49735,6 +49786,37 @@ Please use another name.` : formatMuiErrorMessage$1(18));
49735
49786
  queryFn: () => SynapseClient.getEntityPermissions(entityId, accessToken)
49736
49787
  });
49737
49788
  }
49789
+ const onMutateEntityAclSuccess = async (entityId, updatedACL, queryClient, keyFactory) => {
49790
+ const entityAclQueryKey = keyFactory.getEntityACLQueryKey(entityId);
49791
+ if (updatedACL) {
49792
+ queryClient.setQueryData(entityAclQueryKey, updatedACL);
49793
+ }
49794
+ await invalidateAllQueriesForEntity(
49795
+ queryClient,
49796
+ keyFactory,
49797
+ entityId,
49798
+ entityAclQueryKey
49799
+ );
49800
+ };
49801
+ function useCreateEntityACL(options2) {
49802
+ const queryClient = useQueryClient();
49803
+ const { accessToken, keyFactory } = useSynapseContext();
49804
+ return useMutation({
49805
+ ...options2,
49806
+ mutationFn: (acl) => SynapseClient.createEntityACL(acl, accessToken),
49807
+ onSuccess: async (updatedACL, variables, ctx) => {
49808
+ await onMutateEntityAclSuccess(
49809
+ updatedACL.id,
49810
+ updatedACL,
49811
+ queryClient,
49812
+ keyFactory
49813
+ );
49814
+ if (options2 == null ? void 0 : options2.onSuccess) {
49815
+ await options2.onSuccess(updatedACL, variables, ctx);
49816
+ }
49817
+ }
49818
+ });
49819
+ }
49738
49820
  function useUpdateEntityACL(options2) {
49739
49821
  const queryClient = useQueryClient();
49740
49822
  const { accessToken, keyFactory } = useSynapseContext();
@@ -49742,13 +49824,11 @@ Please use another name.` : formatMuiErrorMessage$1(18));
49742
49824
  ...options2,
49743
49825
  mutationFn: (acl) => SynapseClient.updateEntityACL(acl, accessToken),
49744
49826
  onSuccess: async (updatedACL, variables, ctx) => {
49745
- const entityAclQueryKey = keyFactory.getEntityACLQueryKey(updatedACL.id);
49746
- queryClient.setQueryData(entityAclQueryKey, updatedACL);
49747
- await invalidateAllQueriesForEntity(
49748
- queryClient,
49749
- keyFactory,
49827
+ await onMutateEntityAclSuccess(
49750
49828
  updatedACL.id,
49751
- entityAclQueryKey
49829
+ updatedACL,
49830
+ queryClient,
49831
+ keyFactory
49752
49832
  );
49753
49833
  if (options2 == null ? void 0 : options2.onSuccess) {
49754
49834
  await options2.onSuccess(updatedACL, variables, ctx);
@@ -49756,6 +49836,40 @@ Please use another name.` : formatMuiErrorMessage$1(18));
49756
49836
  }
49757
49837
  });
49758
49838
  }
49839
+ function useDeleteEntityACL(options2) {
49840
+ const queryClient = useQueryClient();
49841
+ const { accessToken, keyFactory } = useSynapseContext();
49842
+ return useMutation({
49843
+ ...options2,
49844
+ mutationFn: (entityId) => SynapseClient.deleteEntityACL(entityId, accessToken),
49845
+ onSuccess: async (result, entityId, ctx) => {
49846
+ await onMutateEntityAclSuccess(entityId, null, queryClient, keyFactory);
49847
+ if (options2 == null ? void 0 : options2.onSuccess) {
49848
+ await options2.onSuccess(result, entityId, ctx);
49849
+ }
49850
+ }
49851
+ });
49852
+ }
49853
+ function useGetEntityBenefactorACLQueryOptions(entityId) {
49854
+ const opts = useGetEntityBundleQueryOptions(
49855
+ entityId,
49856
+ void 0,
49857
+ {
49858
+ includeBenefactorACL: true
49859
+ }
49860
+ );
49861
+ return {
49862
+ ...opts,
49863
+ select: (data) => data.benefactorAcl
49864
+ };
49865
+ }
49866
+ function useSuspenseGetEntityBenefactorACL(entityId, options2) {
49867
+ const queryOptions = useGetEntityBenefactorACLQueryOptions(entityId);
49868
+ return useSuspenseQuery({
49869
+ ...options2,
49870
+ ...queryOptions
49871
+ });
49872
+ }
49759
49873
  function useUpdateTableColumns(options2) {
49760
49874
  const queryClient = useQueryClient();
49761
49875
  const { accessToken, keyFactory } = useSynapseContext();
@@ -49798,23 +49912,6 @@ Please use another name.` : formatMuiErrorMessage$1(18));
49798
49912
  queryFn: () => SynapseClient.getSchemaValidationResults(entityId, accessToken)
49799
49913
  });
49800
49914
  }
49801
- function useGetEntityBundle(entityId, version2, bundleRequest = ALL_ENTITY_BUNDLE_FIELDS, options2) {
49802
- const { accessToken, keyFactory } = useSynapseContext();
49803
- return useQuery({
49804
- ...options2,
49805
- queryKey: keyFactory.getEntityBundleQueryKey(
49806
- entityId,
49807
- version2,
49808
- bundleRequest
49809
- ),
49810
- queryFn: () => SynapseClient.getEntityBundleV2(
49811
- entityId,
49812
- bundleRequest,
49813
- version2,
49814
- accessToken
49815
- )
49816
- });
49817
- }
49818
49915
  function useGetEntityActionsRequired(entityId, options2) {
49819
49916
  const { accessToken, keyFactory } = useSynapseContext();
49820
49917
  return useQuery({
@@ -50982,12 +51079,14 @@ Please use another name.` : formatMuiErrorMessage$1(18));
50982
51079
  useCreateAccessRequirement,
50983
51080
  useCreateAccessRequirementACL,
50984
51081
  useCreateEntity,
51082
+ useCreateEntityACL,
50985
51083
  useCreateLockAccessRequirement,
50986
51084
  useCreateOAuthClient,
50987
51085
  useCreateTeam,
50988
51086
  useCreateWikiPage,
50989
51087
  useDeleteAccessRequirementACL,
50990
51088
  useDeleteEntity,
51089
+ useDeleteEntityACL,
50991
51090
  useDeleteOAuthClient,
50992
51091
  useDeleteTeamMembership,
50993
51092
  useDisableTwoFactorAuth,
@@ -51018,6 +51117,7 @@ Please use another name.` : formatMuiErrorMessage$1(18));
51018
51117
  useGetEntityActionsRequired,
51019
51118
  useGetEntityAlias,
51020
51119
  useGetEntityBundle,
51120
+ useGetEntityBundleQueryOptions,
51021
51121
  useGetEntityChallenge,
51022
51122
  useGetEntityChildren,
51023
51123
  useGetEntityChildrenInfinite,
@@ -51091,6 +51191,9 @@ Please use another name.` : formatMuiErrorMessage$1(18));
51091
51191
  useSortAccessRequirementIdsByCompletion,
51092
51192
  useStartTwoFactorEnrollment,
51093
51193
  useSubmitDataAccessRequest,
51194
+ useSuspenseGetCurrentUserProfile,
51195
+ useSuspenseGetEntityBenefactorACL,
51196
+ useSuspenseGetEntityBundle,
51094
51197
  useUpdateAccessRequirement,
51095
51198
  useUpdateAccessRequirementACL,
51096
51199
  useUpdateDataAccessRequest,
@@ -53864,6 +53967,14 @@ Please use another name.` : formatMuiErrorMessage$1(18));
53864
53967
  );
53865
53968
  return batchResult.results[0];
53866
53969
  };
53970
+ const createEntityACL = (acl, accessToken = void 0) => {
53971
+ return doPost(
53972
+ ENTITY_ACL(acl.id),
53973
+ acl,
53974
+ accessToken,
53975
+ BackendDestinationEnum.REPO_ENDPOINT
53976
+ );
53977
+ };
53867
53978
  const updateEntityACL = (acl, accessToken = void 0) => {
53868
53979
  return doPut(
53869
53980
  ENTITY_ACL(acl.id),
@@ -53872,6 +53983,13 @@ Please use another name.` : formatMuiErrorMessage$1(18));
53872
53983
  BackendDestinationEnum.REPO_ENDPOINT
53873
53984
  );
53874
53985
  };
53986
+ const deleteEntityACL = (id2, accessToken = void 0) => {
53987
+ return doDelete(
53988
+ ENTITY_ACL(id2),
53989
+ accessToken,
53990
+ BackendDestinationEnum.REPO_ENDPOINT
53991
+ );
53992
+ };
53875
53993
  const updateEntity = (entity2, accessToken = void 0, newVersion) => {
53876
53994
  let url = `/repo/v1/entity/${entity2.id}`;
53877
53995
  if (newVersion) url += "?newVersion=true";
@@ -56020,6 +56138,7 @@ Please use another name.` : formatMuiErrorMessage$1(18));
56020
56138
  createAccessRequirementAcl,
56021
56139
  createColumnModels,
56022
56140
  createEntity,
56141
+ createEntityACL,
56023
56142
  createEvaluation,
56024
56143
  createEvaluationRound,
56025
56144
  createFormData,
@@ -56043,6 +56162,7 @@ Please use another name.` : formatMuiErrorMessage$1(18));
56043
56162
  deleteDownloadListFiles,
56044
56163
  deleteEmail,
56045
56164
  deleteEntity,
56165
+ deleteEntityACL,
56046
56166
  deleteEvaluation,
56047
56167
  deleteEvaluationRound,
56048
56168
  deleteFormData,
@@ -56269,13 +56389,26 @@ Please use another name.` : formatMuiErrorMessage$1(18));
56269
56389
  queryFn: () => SynapseClient.getNotificationEmail(accessToken)
56270
56390
  });
56271
56391
  }
56272
- function useGetCurrentUserProfile(options2) {
56392
+ function useGetCurrentUserProfileQueryOptions() {
56273
56393
  const { accessToken, keyFactory } = useSynapseContext();
56274
56394
  const queryKey = keyFactory.getCurrentUserProfileQueryKey();
56275
- return useQuery({
56276
- ...options2,
56395
+ return {
56277
56396
  queryKey,
56278
56397
  queryFn: () => SynapseClient.getUserProfile(accessToken)
56398
+ };
56399
+ }
56400
+ function useGetCurrentUserProfile(options2) {
56401
+ const queryOptions = useGetCurrentUserProfileQueryOptions();
56402
+ return useQuery({
56403
+ ...options2,
56404
+ ...queryOptions
56405
+ });
56406
+ }
56407
+ function useSuspenseGetCurrentUserProfile(options2) {
56408
+ const queryOptions = useGetCurrentUserProfileQueryOptions();
56409
+ return useSuspenseQuery({
56410
+ ...options2,
56411
+ ...queryOptions
56279
56412
  });
56280
56413
  }
56281
56414
  const ALL_USER_BUNDLE_FIELDS = USER_BUNDLE_MASK_USER_PROFILE | USER_BUNDLE_MASK_ORCID | USER_BUNDLE_MASK_VERIFICATION_SUBMISSION | USER_BUNDLE_MASK_IS_CERTIFIED | USER_BUNDLE_MASK_IS_VERIFIED | USER_BUNDLE_MASK_IS_ACT_MEMBER | USER_BUNDLE_MASK_IS_AR_REVIEWER;
@@ -93763,11 +93896,16 @@ ${e2.message}`);
93763
93896
  return queryRequestClone;
93764
93897
  }
93765
93898
  function useTableQueryReducer(initQueryRequest, requireConfirmationOnChange, onQueryChange) {
93899
+ const [resetDebounceCounter, setResetDebounceCounter] = React$2.useState(0);
93766
93900
  const [commitAfterDebounce, setCommitAfterDebounce] = React$2.useState(false);
93767
93901
  const [state, dispatch2] = React$2.useReducer(
93768
93902
  (prevState, action) => {
93769
93903
  let updatedNextQueryRequest = prevState.nextQueryRequest;
93770
93904
  switch (action.type) {
93905
+ case "resetDebounce": {
93906
+ setResetDebounceCounter((v2) => v2 + 1);
93907
+ return prevState;
93908
+ }
93771
93909
  case "setQuery": {
93772
93910
  updatedNextQueryRequest = getQueryFromSetStateAction(
93773
93911
  action,
@@ -93896,15 +94034,27 @@ ${e2.message}`);
93896
94034
  }
93897
94035
  },
93898
94036
  // nextQueryRequest MUST be included in the dependencies to ensure the debounce resets when it changes
93899
- [state.nextQueryRequest, commitAfterDebounce, setCommitAfterDebounce],
94037
+ [
94038
+ state.nextQueryRequest,
94039
+ commitAfterDebounce,
94040
+ setCommitAfterDebounce,
94041
+ resetDebounceCounter
94042
+ ],
93900
94043
  DEBOUNCE_DELAY_MS
93901
94044
  );
93902
- return {
93903
- currentQueryRequest: state.currentQueryRequest,
93904
- nextQueryRequest: state.nextQueryRequest,
93905
- isConfirmingChange: state.isConfirmingChange,
93906
- dispatch: dispatch2
93907
- };
94045
+ return React$2.useMemo(
94046
+ () => ({
94047
+ currentQueryRequest: state.currentQueryRequest,
94048
+ nextQueryRequest: state.nextQueryRequest,
94049
+ isConfirmingChange: state.isConfirmingChange,
94050
+ dispatch: dispatch2
94051
+ }),
94052
+ [
94053
+ state.currentQueryRequest,
94054
+ state.isConfirmingChange,
94055
+ state.nextQueryRequest
94056
+ ]
94057
+ );
93908
94058
  }
93909
94059
  const DEBOUNCE_DELAY_MS = 750;
93910
94060
  function useImmutableTableQuery(options2) {
@@ -94081,9 +94231,13 @@ ${e2.message}`);
94081
94231
  const commitChanges = React$2.useCallback(() => {
94082
94232
  dispatch2({ type: "commitChanges" });
94083
94233
  }, [dispatch2]);
94234
+ const resetDebounceTimer = React$2.useCallback(() => {
94235
+ dispatch2({ type: "resetDebounce" });
94236
+ }, [dispatch2]);
94084
94237
  return {
94085
94238
  entityId,
94086
94239
  commitChanges,
94240
+ resetDebounceTimer,
94087
94241
  currentQueryRequest,
94088
94242
  nextQueryRequest,
94089
94243
  versionNumber,
@@ -94335,7 +94489,8 @@ ${e2.message}`);
94335
94489
  nextQueryRequest,
94336
94490
  currentQueryRequest,
94337
94491
  addValueToSelectedFacet: addValueToSelectedFacet2,
94338
- setRangeFacetValue: setRangeFacetValue2
94492
+ setRangeFacetValue: setRangeFacetValue2,
94493
+ resetDebounceTimer
94339
94494
  } = immutableTableQueryResult;
94340
94495
  const lastQueryRequest = React$2.useMemo(() => {
94341
94496
  return getCurrentQueryRequest();
@@ -94437,6 +94592,7 @@ ${e2.message}`);
94437
94592
  addValueToSelectedFacet: addValueToSelectedFacet2,
94438
94593
  combineRangeFacetConfig,
94439
94594
  setRangeFacetValue: setRangeFacetValue2,
94595
+ resetDebounceTimer,
94440
94596
  ...paginationControls
94441
94597
  });
94442
94598
  const { children: children2 } = props;
@@ -104575,23 +104731,25 @@ ${e2.message}`);
104575
104731
  }, baseSelectProps));
104576
104732
  });
104577
104733
  var StateManagedSelect$1 = StateManagedSelect;
104734
+ const AUTHENTICATED_GROUP_DISPLAY_TEXT = "All registered Synapse users";
104735
+ const PUBLIC_GROUP_DISPLAY_TEXT = "Anyone on the web";
104578
104736
  function TeamBadge(props) {
104579
104737
  const { teamId } = props;
104580
104738
  let { teamName, disableHref } = props;
104581
104739
  let icon = "team";
104582
104740
  if (teamId == AUTHENTICATED_PRINCIPAL_ID) {
104583
104741
  icon = "public";
104584
- teamName = "All registered Synapse users";
104742
+ teamName = AUTHENTICATED_GROUP_DISPLAY_TEXT;
104585
104743
  disableHref = true;
104586
104744
  }
104587
104745
  if (teamId == PUBLIC_PRINCIPAL_ID) {
104588
104746
  icon = "public";
104589
- teamName = "Anyone on the web";
104747
+ teamName = PUBLIC_GROUP_DISPLAY_TEXT;
104590
104748
  disableHref = true;
104591
104749
  }
104592
- const Tag = disableHref ? "span" : "a";
104593
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
104594
- /* @__PURE__ */ jsxRuntimeExports.jsx(IconSvg, { icon }),
104750
+ const Tag = disableHref ? "span" : Link;
104751
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { component: "span", display: "inline-flex", alignItems: "center", children: [
104752
+ /* @__PURE__ */ jsxRuntimeExports.jsx(IconSvg, { icon, fontSize: "small" }),
104595
104753
  /* @__PURE__ */ jsxRuntimeExports.jsx(
104596
104754
  Tag,
104597
104755
  {
@@ -109449,7 +109607,7 @@ ${e2.message}`);
109449
109607
  addValueToSelectedFacet: addValueToSelectedFacet2,
109450
109608
  removeSelectedFacet: removeSelectedFacet2,
109451
109609
  removeValueFromSelectedFacet: removeValueFromSelectedFacet2,
109452
- executeQueryRequest
109610
+ resetDebounceTimer
109453
109611
  } = useQueryContext();
109454
109612
  const data = useAtomValue(tableQueryDataAtom);
109455
109613
  const { getColumnDisplayName } = useQueryVisualizationContext();
@@ -109534,12 +109692,7 @@ ${e2.message}`);
109534
109692
  dropdownType,
109535
109693
  hideCollapsible,
109536
109694
  onHoverOverValue: () => {
109537
- executeQueryRequest(
109538
- (request) => {
109539
- return cloneDeep$3(request);
109540
- },
109541
- { debounce: true }
109542
- );
109695
+ resetDebounceTimer();
109543
109696
  },
109544
109697
  onAddValueToSelection: (value) => {
109545
109698
  addValueToSelectedFacet2(
@@ -115981,6 +116134,948 @@ ${e2.message}`);
115981
116134
  )
115982
116135
  ] });
115983
116136
  };
116137
+ const OpenDataContainer = styled(Box, {
116138
+ label: "OpenDataContainer"
116139
+ })(({ theme: theme3 }) => ({
116140
+ background: theme3.palette.grey[100],
116141
+ padding: `${theme3.spacing(2.5)} ${theme3.spacing(4)}`,
116142
+ border: `1px solid ${theme3.palette.grey[300]}`,
116143
+ borderRadius: "3px",
116144
+ marginBottom: theme3.spacing(2)
116145
+ }));
116146
+ function OpenData(props) {
116147
+ const { isOpenData, isPublic: isPublic2, currentUserCanUpdateSharingSettings } = props;
116148
+ if (isOpenData && isPublic2) {
116149
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(OpenDataContainer, { display: "flex", gap: 1, children: [
116150
+ /* @__PURE__ */ jsxRuntimeExports.jsx(IconSvg, { icon: "checkCircle", color: "success", wrap: false }),
116151
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
116152
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body1", color: "text.secondary", children: /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "This is anonymous access data." }) }),
116153
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body1", color: "text.secondary", children: "Anyone can download it, even if they aren’t logged in to Synapse." })
116154
+ ] })
116155
+ ] });
116156
+ } else if (isOpenData && !isPublic2 && currentUserCanUpdateSharingSettings) {
116157
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(OpenDataContainer, { children: [
116158
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body1", color: "text.secondary", children: /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "This is not anonymous access data." }) }),
116159
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body1", color: "text.secondary", children: "You must grant public access for all users to be able to anonymously download it." })
116160
+ ] });
116161
+ } else if (!isOpenData && isPublic2 && currentUserCanUpdateSharingSettings) {
116162
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(OpenDataContainer, { children: [
116163
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body1", color: "text.secondary", children: /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Users must be logged in to download public access data." }) }),
116164
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body1", color: "text.secondary", children: "This data is publicly viewable, but only registered and logged-in users can download it." })
116165
+ ] });
116166
+ }
116167
+ return null;
116168
+ }
116169
+ const CUSTOM_VALUE = "CUSTOM";
116170
+ const CUSTOM_TEXT = "Custom";
116171
+ const PermissionLevelMenu = (props) => {
116172
+ const { currentAccessType, availablePermissionLevels: availablePermissionLevels2, onChange } = props;
116173
+ const selectedPermissionLevel = getPermissionLevelFromAccessType(currentAccessType);
116174
+ const isCustomPermissionSelected = selectedPermissionLevel == null;
116175
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
116176
+ TextField$1,
116177
+ {
116178
+ value: isCustomPermissionSelected ? CUSTOM_VALUE : selectedPermissionLevel,
116179
+ onChange: (e2) => {
116180
+ const accessType = getAccessTypeFromPermissionLevel(
116181
+ e2.target.value
116182
+ );
116183
+ onChange(accessType || currentAccessType);
116184
+ },
116185
+ fullWidth: true,
116186
+ select: true,
116187
+ SelectProps: {
116188
+ renderValue: (selected) => {
116189
+ if (selected == CUSTOM_VALUE) {
116190
+ return CUSTOM_TEXT;
116191
+ }
116192
+ return permissionLevelToLabel[selected];
116193
+ }
116194
+ },
116195
+ size: "small",
116196
+ children: [
116197
+ Object.values(availablePermissionLevels2).map((permissionLevel) => {
116198
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(MenuItem, { value: permissionLevel, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "smallText1", noWrap: true, children: permissionLevelToLabel[permissionLevel] }) }, permissionLevel);
116199
+ }),
116200
+ isCustomPermissionSelected && /* @__PURE__ */ jsxRuntimeExports.jsx(MenuItem, { value: CUSTOM_VALUE, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "smallText1", noWrap: true, children: CUSTOM_TEXT }) })
116201
+ ]
116202
+ }
116203
+ );
116204
+ };
116205
+ function ReadOnlyPermissionLevel(props) {
116206
+ const { accessType } = props;
116207
+ return permissionLevelToLabel[getPermissionLevelFromAccessType(accessType)] || "Custom";
116208
+ }
116209
+ const REMOVE_BUTTON_LABEL = "Remove from AR Permissions";
116210
+ const ResourceAccessItem = (props) => {
116211
+ const {
116212
+ resourceAccess,
116213
+ availablePermissionLevels: availablePermissionLevels2,
116214
+ canChangePermission,
116215
+ showDeleteButton,
116216
+ onChange,
116217
+ onRemove: onRemove2,
116218
+ displayedPermissionLevelOverride
116219
+ } = props;
116220
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
116221
+ Stack$6,
116222
+ {
116223
+ direction: "row",
116224
+ justifyContent: "space-between",
116225
+ alignItems: "center",
116226
+ gap: "10px",
116227
+ py: "6px",
116228
+ role: "row",
116229
+ children: [
116230
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { fontSize: "16px", lineHeight: "20px", children: /* @__PURE__ */ jsxRuntimeExports.jsx(UserOrTeamBadge, { principalId: resourceAccess.principalId }) }),
116231
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
116232
+ Stack$6,
116233
+ {
116234
+ direction: "row",
116235
+ gap: "10px",
116236
+ alignItems: "center",
116237
+ width: "200px",
116238
+ flexShrink: 0,
116239
+ children: [
116240
+ canChangePermission ? /* @__PURE__ */ jsxRuntimeExports.jsx(
116241
+ PermissionLevelMenu,
116242
+ {
116243
+ currentAccessType: resourceAccess.accessType,
116244
+ availablePermissionLevels: availablePermissionLevels2,
116245
+ onChange
116246
+ }
116247
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "smallText1", flexGrow: 1, children: displayedPermissionLevelOverride ?? /* @__PURE__ */ jsxRuntimeExports.jsx(
116248
+ ReadOnlyPermissionLevel,
116249
+ {
116250
+ accessType: resourceAccess.accessType
116251
+ }
116252
+ ) }),
116253
+ showDeleteButton && /* @__PURE__ */ jsxRuntimeExports.jsx(
116254
+ IconSvgButton,
116255
+ {
116256
+ "aria-label": REMOVE_BUTTON_LABEL,
116257
+ onClick: () => onRemove2(),
116258
+ icon: "delete",
116259
+ sx: {
116260
+ "&:hover": {
116261
+ color: "error.main"
116262
+ }
116263
+ }
116264
+ }
116265
+ )
116266
+ ]
116267
+ }
116268
+ )
116269
+ ]
116270
+ }
116271
+ ) });
116272
+ };
116273
+ const SkeletonParagraph = ({
116274
+ numRows = 5,
116275
+ rowHeight,
116276
+ className
116277
+ }) => {
116278
+ const [skeletons, setSkeletons] = React$2.useState([]);
116279
+ React$2.useEffect(() => {
116280
+ const elements = [];
116281
+ times$2(numRows, (i2) => {
116282
+ elements.push(
116283
+ /* @__PURE__ */ jsxRuntimeExports.jsx(React$2.Fragment, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
116284
+ Skeleton,
116285
+ {
116286
+ height: rowHeight,
116287
+ width: i2 === numRows - 1 ? "35%" : "100%"
116288
+ }
116289
+ ) }, i2)
116290
+ );
116291
+ });
116292
+ setSkeletons(elements);
116293
+ }, [numRows, rowHeight]);
116294
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className, children: skeletons });
116295
+ };
116296
+ function AclEditorSkeleton() {
116297
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(Stack$6, { gap: 2, role: "progressbar", children: [
116298
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { height: 50, width: 200 }),
116299
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SkeletonParagraph, { numRows: 2 }),
116300
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SkeletonTable, { numCols: 2, numRows: 4, rowHeight: "30px" }),
116301
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { height: 50, width: 100 }),
116302
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SkeletonParagraph, { numRows: 2 })
116303
+ ] });
116304
+ }
116305
+ const ADD_PRINCIPAL_TO_ACL_COMBOBOX_LABEL = "Add a user or team";
116306
+ const ADD_PUBLIC_PRINCIPALS_BUTTON_TEXT = "Make Public";
116307
+ const REMOVE_PUBLIC_PRINCIPALS_BUTTON_TEXT = "Remove Public Access";
116308
+ const NOTIFY_NEW_ACL_USERS_CHECKBOX_LABEL = "Notify people via email";
116309
+ function AclEditor(props) {
116310
+ const {
116311
+ resourceAccessList,
116312
+ availablePermissionLevels: availablePermissionLevels2,
116313
+ canEdit,
116314
+ canRemoveEntry = canEdit,
116315
+ isLoading = false,
116316
+ emptyText,
116317
+ onAddPrincipalToAcl,
116318
+ updateResourceAccessItem,
116319
+ removeResourceAccessItem,
116320
+ showAddRemovePublicButton,
116321
+ showNotifyCheckbox,
116322
+ notifyCheckboxValue,
116323
+ onNotifyCheckboxChange = noop$9,
116324
+ displayedPermissionLevelOverride
116325
+ } = props;
116326
+ if (isLoading) {
116327
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(AclEditorSkeleton, {});
116328
+ }
116329
+ const resourceAccessListCurrentlyIncludesPublic = Boolean(
116330
+ resourceAccessList.find(
116331
+ (resourceAccess) => PUBLIC_PRINCIPAL_IDS.includes(resourceAccess.principalId)
116332
+ )
116333
+ );
116334
+ const addOrRemovePublicButtonProps = resourceAccessListCurrentlyIncludesPublic ? {
116335
+ startIcon: /* @__PURE__ */ jsxRuntimeExports.jsx(IconSvg, { icon: "close", wrap: false }),
116336
+ children: REMOVE_PUBLIC_PRINCIPALS_BUTTON_TEXT,
116337
+ onClick: () => {
116338
+ PUBLIC_PRINCIPAL_IDS.forEach((publicId) => {
116339
+ removeResourceAccessItem(publicId);
116340
+ });
116341
+ }
116342
+ } : {
116343
+ startIcon: /* @__PURE__ */ jsxRuntimeExports.jsx(IconSvg, { icon: "public", wrap: false }),
116344
+ children: ADD_PUBLIC_PRINCIPALS_BUTTON_TEXT,
116345
+ onClick: () => {
116346
+ onAddPrincipalToAcl(PUBLIC_PRINCIPAL_ID);
116347
+ onAddPrincipalToAcl(AUTHENTICATED_PRINCIPAL_ID);
116348
+ }
116349
+ };
116350
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { children: [
116351
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { mb: "30px", children: [
116352
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "headline3", mb: "10px", children: "Users and Teams with Permissions" }),
116353
+ resourceAccessList.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body1Italic", children: emptyText }) : /* @__PURE__ */ jsxRuntimeExports.jsx(TransitionGroup, { children: resourceAccessList.map((resourceAccess) => {
116354
+ const canChangePermission = typeof canEdit === "function" ? canEdit(resourceAccess) : canEdit;
116355
+ const canDelete = typeof canRemoveEntry === "function" ? canRemoveEntry(resourceAccess) : canRemoveEntry;
116356
+ const permissionLevelOverride = displayedPermissionLevelOverride ? displayedPermissionLevelOverride(resourceAccess) : void 0;
116357
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapse$1, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
116358
+ ResourceAccessItem,
116359
+ {
116360
+ resourceAccess,
116361
+ availablePermissionLevels: availablePermissionLevels2,
116362
+ canChangePermission,
116363
+ displayedPermissionLevelOverride: permissionLevelOverride,
116364
+ showDeleteButton: canDelete,
116365
+ onChange: (accessType) => updateResourceAccessItem(
116366
+ resourceAccess.principalId,
116367
+ accessType
116368
+ ),
116369
+ onRemove: () => removeResourceAccessItem(resourceAccess.principalId)
116370
+ },
116371
+ resourceAccess.principalId
116372
+ ) }, resourceAccess.principalId);
116373
+ }) })
116374
+ ] }),
116375
+ canEdit && /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { children: [
116376
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "headline3", mb: "10px", children: "Add More" }),
116377
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
116378
+ Typography,
116379
+ {
116380
+ sx: {
116381
+ variant: "body1",
116382
+ lineHeight: "20px",
116383
+ fontStyle: "italic",
116384
+ color: "text.secondary"
116385
+ },
116386
+ mb: "20px",
116387
+ children: "Search for a username or team to add. You can search by username, first or last names, or team name."
116388
+ }
116389
+ ),
116390
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { children: [
116391
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
116392
+ Typography,
116393
+ {
116394
+ component: "label",
116395
+ variant: "smallText2",
116396
+ htmlFor: "reviewer-search",
116397
+ children: ADD_PRINCIPAL_TO_ACL_COMBOBOX_LABEL
116398
+ }
116399
+ ),
116400
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
116401
+ UserSearchBoxV2,
116402
+ {
116403
+ value: null,
116404
+ inputId: "reviewer-search",
116405
+ placeholder: "Username, name (first and last) or team name.",
116406
+ onChange: (id2) => {
116407
+ const parsedId = parseInt(id2 || "");
116408
+ if (parsedId) {
116409
+ onAddPrincipalToAcl(parsedId);
116410
+ }
116411
+ }
116412
+ }
116413
+ )
116414
+ ] }),
116415
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { display: "flex", justifyContent: "space-between", gap: 2, children: [
116416
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { children: showAddRemovePublicButton && /* @__PURE__ */ jsxRuntimeExports.jsx(
116417
+ Button,
116418
+ {
116419
+ size: "small",
116420
+ variant: "outlined",
116421
+ ...addOrRemovePublicButtonProps
116422
+ }
116423
+ ) }),
116424
+ showNotifyCheckbox && /* @__PURE__ */ jsxRuntimeExports.jsx(
116425
+ Tooltip,
116426
+ {
116427
+ title: "Select to notify newly added people that this item has been shared with them",
116428
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
116429
+ FormControlLabel,
116430
+ {
116431
+ sx: { mr: 0 },
116432
+ control: /* @__PURE__ */ jsxRuntimeExports.jsx(
116433
+ Checkbox$1,
116434
+ {
116435
+ value: notifyCheckboxValue,
116436
+ onChange: () => onNotifyCheckboxChange(!notifyCheckboxValue)
116437
+ }
116438
+ ),
116439
+ label: /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "smallText1", children: NOTIFY_NEW_ACL_USERS_CHECKBOX_LABEL })
116440
+ }
116441
+ )
116442
+ }
116443
+ )
116444
+ ] })
116445
+ ] }),
116446
+ !canEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body1", children: "You do not have sufficient privileges to modify the sharing settings." })
116447
+ ] });
116448
+ }
116449
+ function compareResourceAccessAndUserGroupHeader(a2, b2) {
116450
+ let CompareResult;
116451
+ ((CompareResult2) => {
116452
+ CompareResult2[CompareResult2["A_FIRST"] = -1] = "A_FIRST";
116453
+ CompareResult2[CompareResult2["B_FIRST"] = 1] = "B_FIRST";
116454
+ })(CompareResult || (CompareResult = {}));
116455
+ const hasChangePermissionA = a2.resourceAccess.accessType.includes(
116456
+ ACCESS_TYPE.CHANGE_PERMISSIONS
116457
+ );
116458
+ const hasChangePermissionB = b2.resourceAccess.accessType.includes(
116459
+ ACCESS_TYPE.CHANGE_PERMISSIONS
116460
+ );
116461
+ if (hasChangePermissionA && !hasChangePermissionB)
116462
+ return -1;
116463
+ if (!hasChangePermissionA && hasChangePermissionB)
116464
+ return 1;
116465
+ if (a2.resourceAccess.principalId === AUTHENTICATED_PRINCIPAL_ID && b2.resourceAccess.principalId !== AUTHENTICATED_PRINCIPAL_ID)
116466
+ return -1;
116467
+ if (a2.resourceAccess.principalId !== AUTHENTICATED_PRINCIPAL_ID && b2.resourceAccess.principalId === AUTHENTICATED_PRINCIPAL_ID)
116468
+ return 1;
116469
+ if (a2.resourceAccess.principalId === PUBLIC_PRINCIPAL_ID && b2.resourceAccess.principalId !== PUBLIC_PRINCIPAL_ID)
116470
+ return -1;
116471
+ if (a2.resourceAccess.principalId !== PUBLIC_PRINCIPAL_ID && b2.resourceAccess.principalId === PUBLIC_PRINCIPAL_ID)
116472
+ return 1;
116473
+ return a2.userGroupHeader.userName.localeCompare(b2.userGroupHeader.userName);
116474
+ }
116475
+ function useSortResourceAccessList(resourceAccessList) {
116476
+ const principalIdsOnResourceAccessList = React$2.useMemo(
116477
+ () => resourceAccessList.map((ra) => ra.principalId),
116478
+ [resourceAccessList]
116479
+ );
116480
+ const {
116481
+ data: userGroupHeadersOnResourceAccessList,
116482
+ isLoading,
116483
+ error: error2
116484
+ } = useGetUserGroupHeaders(principalIdsOnResourceAccessList.map(String), {
116485
+ enabled: principalIdsOnResourceAccessList.length > 0
116486
+ });
116487
+ React$2.useEffect(() => {
116488
+ if (error2) {
116489
+ console.error("Error fetching user group headers: ", error2);
116490
+ }
116491
+ }, [error2]);
116492
+ const sortedResourceAccessList = React$2.useMemo(() => {
116493
+ if (!userGroupHeadersOnResourceAccessList) {
116494
+ return null;
116495
+ }
116496
+ const joinedWithUserGroupHeaders = resourceAccessList.map(
116497
+ (ral) => ({
116498
+ resourceAccess: ral,
116499
+ userGroupHeader: userGroupHeadersOnResourceAccessList.find(
116500
+ (ugh) => String(ugh.ownerId) === String(ral.principalId)
116501
+ )
116502
+ })
116503
+ );
116504
+ const allEntriesHaveUserGroupHeader = joinedWithUserGroupHeaders.every(
116505
+ (obj) => Boolean(obj.userGroupHeader)
116506
+ );
116507
+ if (!allEntriesHaveUserGroupHeader) {
116508
+ console.warn(
116509
+ "Some ACL entries do not have a corresponding UserGroupHeader. The ResourceAccess list will not be sorted. Missing entries: ",
116510
+ joinedWithUserGroupHeaders.filter((obj) => !obj.userGroupHeader)
116511
+ );
116512
+ return null;
116513
+ }
116514
+ return joinedWithUserGroupHeaders.toSorted(compareResourceAccessAndUserGroupHeader).map((obj) => obj.resourceAccess);
116515
+ }, [resourceAccessList, userGroupHeadersOnResourceAccessList]);
116516
+ return {
116517
+ sortedResourceAccessList,
116518
+ isLoading
116519
+ };
116520
+ }
116521
+ const PRINCIPAL_ALREADY_ADDED_ERROR_MESSAGE = "User or team already has permissions.";
116522
+ function useUpdateAcl(options2 = {}) {
116523
+ const { onChange = noop$9, onError = noop$9 } = options2;
116524
+ const [isDirty2, setIsDirty] = React$2.useState(false);
116525
+ const [resourceAccessList, setResourceAccessList] = React$2.useState([]);
116526
+ const [hasSorted, setHasSorted] = React$2.useState(false);
116527
+ const { sortedResourceAccessList, isLoading: isLoadingSortedList } = useSortResourceAccessList(resourceAccessList);
116528
+ React$2.useEffect(() => {
116529
+ if (!isDirty2 && !isLoadingSortedList && !hasSorted && sortedResourceAccessList != null) {
116530
+ setResourceAccessList(sortedResourceAccessList);
116531
+ setHasSorted(true);
116532
+ }
116533
+ }, [hasSorted, isDirty2, isLoadingSortedList, sortedResourceAccessList]);
116534
+ React$2.useEffect(() => {
116535
+ onChange(resourceAccessList);
116536
+ }, [resourceAccessList]);
116537
+ const addResourceAccessItem = React$2.useCallback(
116538
+ (principalId, accessTypes) => {
116539
+ setIsDirty(true);
116540
+ if (principalId) {
116541
+ setResourceAccessList((resourceAccessList2) => {
116542
+ const alreadyReviewer = resourceAccessList2.some(
116543
+ (resourceAccess) => resourceAccess.principalId === principalId
116544
+ );
116545
+ if (alreadyReviewer) {
116546
+ onError(PRINCIPAL_ALREADY_ADDED_ERROR_MESSAGE);
116547
+ } else {
116548
+ const newResourceAccess = {
116549
+ principalId,
116550
+ accessType: accessTypes
116551
+ };
116552
+ return [...resourceAccessList2, newResourceAccess];
116553
+ }
116554
+ return resourceAccessList2;
116555
+ });
116556
+ }
116557
+ },
116558
+ [onError]
116559
+ );
116560
+ const updateResourceAccessItem = React$2.useCallback(
116561
+ (principalId, accessType) => {
116562
+ setIsDirty(true);
116563
+ setResourceAccessList(
116564
+ (resourceAccessList2) => resourceAccessList2.map((resourceAccess) => {
116565
+ return resourceAccess.principalId === principalId ? { ...resourceAccess, accessType } : resourceAccess;
116566
+ })
116567
+ );
116568
+ },
116569
+ []
116570
+ );
116571
+ const removeResourceAccessItem = React$2.useCallback((principalId) => {
116572
+ setIsDirty(true);
116573
+ setResourceAccessList(
116574
+ (resourceAccessList2) => resourceAccessList2.filter(
116575
+ (raListItem) => raListItem.principalId !== principalId
116576
+ )
116577
+ );
116578
+ }, []);
116579
+ const resetDirtyState = React$2.useCallback(() => {
116580
+ setIsDirty(false);
116581
+ }, []);
116582
+ return {
116583
+ resourceAccessList,
116584
+ setResourceAccessList,
116585
+ addResourceAccessItem,
116586
+ updateResourceAccessItem,
116587
+ removeResourceAccessItem,
116588
+ resetDirtyState
116589
+ };
116590
+ }
116591
+ function InheritanceMessage(props) {
116592
+ const { isProject, isInherited, benefactorId } = props;
116593
+ let content2 = "";
116594
+ if (isProject) {
116595
+ content2 = /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: "The sharing settings shown below apply to this project and are inherited by all project contents unless local sharing settings have been set." });
116596
+ }
116597
+ if (isInherited) {
116598
+ content2 = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
116599
+ "The sharing settings shown below are currently being inherited",
116600
+ " ",
116601
+ benefactorId ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
116602
+ "from ",
116603
+ /* @__PURE__ */ jsxRuntimeExports.jsx(EntityLink, { entity: benefactorId }),
116604
+ " "
116605
+ ] }) : "",
116606
+ "and cannot be modified here."
116607
+ ] });
116608
+ } else {
116609
+ content2 = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
116610
+ "The local sharing settings shown below are ",
116611
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "not" }),
116612
+ " being inherited from a parent resource."
116613
+ ] });
116614
+ }
116615
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body1", fontStyle: "italic", color: "text.secondary", children: content2 });
116616
+ }
116617
+ const CREATE_LOCAL_SHARING_SETTINGS = "Create local sharing settings";
116618
+ const DELETE_LOCAL_SHARING_SETTINGS = "Delete local sharing settings";
116619
+ function CreateOrDeleteLocalSharingSettingsButton(props) {
116620
+ const { isInherited, setIsInherited } = props;
116621
+ if (!isInherited) {
116622
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
116623
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body1", mt: 2, mb: 1, children: "The sharing settings will be inherited from the parent folder or project if local sharing settings are deleted." }),
116624
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
116625
+ Button,
116626
+ {
116627
+ variant: "outlined",
116628
+ size: "small",
116629
+ color: "error",
116630
+ onClick: () => setIsInherited(true),
116631
+ children: DELETE_LOCAL_SHARING_SETTINGS
116632
+ }
116633
+ )
116634
+ ] });
116635
+ }
116636
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
116637
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body1", mt: 2, mb: 1, children: "Sharing settings are initially inherited from the parent folder or project by default. To customize settings for a specific file, folder, or table, you must create and adjust local sharing settings." }),
116638
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
116639
+ Button,
116640
+ {
116641
+ variant: "contained",
116642
+ size: "small",
116643
+ color: "success",
116644
+ startIcon: /* @__PURE__ */ jsxRuntimeExports.jsx(IconSvg, { icon: "add", wrap: false }),
116645
+ onClick: () => setIsInherited(false),
116646
+ children: CREATE_LOCAL_SHARING_SETTINGS
116647
+ }
116648
+ )
116649
+ ] });
116650
+ }
116651
+ function sortResourceAccessList(resourceAccessList) {
116652
+ const clone = cloneDeep$3(resourceAccessList);
116653
+ clone.sort((a2, b2) => b2.principalId - a2.principalId);
116654
+ clone.forEach((ra) => ra.accessType.sort());
116655
+ return clone;
116656
+ }
116657
+ function resourceAccessListIsEqual(a2, b2) {
116658
+ const aSorted = sortResourceAccessList(a2);
116659
+ const bSorted = sortResourceAccessList(b2);
116660
+ return isEqual$6(aSorted, bSorted);
116661
+ }
116662
+ function shouldNotifyUserInNewResourceAccess(principalId, initialResourceAccessList, userGroupHeader, currentUserId) {
116663
+ const isInInitialResourceAccess = initialResourceAccessList.some(
116664
+ (initialResourceAccess) => principalId === initialResourceAccess.principalId
116665
+ );
116666
+ const isIndividual = userGroupHeader.isIndividual;
116667
+ const isCurrentUser = String(principalId) === currentUserId;
116668
+ const isPublic2 = PUBLIC_PRINCIPAL_IDS.includes(principalId);
116669
+ return !isInInitialResourceAccess && // Is not in the initial list
116670
+ isIndividual && // Is an individual, not a team (SWC-1195)
116671
+ !isCurrentUser && // do not notify the current user (SWC-5576)
116672
+ !isPublic2;
116673
+ }
116674
+ function useNotifyNewACLUsers(options2) {
116675
+ const { subject, body, initialResourceAccessList, newResourceAccessList } = options2;
116676
+ const { data: currentUserProfile, isLoading: isLoadingCurrentUserProfile } = useGetCurrentUserProfile();
116677
+ const { data: userGroupHeaders, isLoading: isLoadingUserGroupHeaders } = useGetUserGroupHeaders(
116678
+ newResourceAccessList.map((ra) => String(ra.principalId))
116679
+ );
116680
+ const isLoading = isLoadingCurrentUserProfile || isLoadingUserGroupHeaders;
116681
+ const { mutate: sendMessage2, isPending } = useSendMessage({
116682
+ onError: (error2) => {
116683
+ displayToast(`New users couldn't be notified: ${error2.reason}`);
116684
+ }
116685
+ });
116686
+ const sendNotification = React$2.useCallback(() => {
116687
+ if (isLoading) {
116688
+ console.error(
116689
+ "Attempted to send notification before user profile or user group headers were loaded. This should never happen."
116690
+ );
116691
+ return;
116692
+ }
116693
+ const usersToNotify = newResourceAccessList.filter((newResourceAccess) => {
116694
+ const userGroupHeader = userGroupHeaders.find(
116695
+ (ugh) => ugh.ownerId === String(newResourceAccess.principalId)
116696
+ );
116697
+ return shouldNotifyUserInNewResourceAccess(
116698
+ newResourceAccess.principalId,
116699
+ initialResourceAccessList,
116700
+ userGroupHeader,
116701
+ currentUserProfile.ownerId
116702
+ );
116703
+ }).map((ra) => String(ra.principalId));
116704
+ if (usersToNotify.length > 0) {
116705
+ sendMessage2({
116706
+ subject,
116707
+ body,
116708
+ recipients: usersToNotify
116709
+ });
116710
+ }
116711
+ }, [
116712
+ body,
116713
+ currentUserProfile,
116714
+ initialResourceAccessList,
116715
+ isLoading,
116716
+ newResourceAccessList,
116717
+ sendMessage2,
116718
+ subject,
116719
+ userGroupHeaders
116720
+ ]);
116721
+ return {
116722
+ sendNotification,
116723
+ isPending,
116724
+ isLoading
116725
+ };
116726
+ }
116727
+ function getUserName(userName, inParens) {
116728
+ if (userName != null) {
116729
+ if (inParens) {
116730
+ return ` (${userName})`;
116731
+ }
116732
+ return userName;
116733
+ }
116734
+ return "";
116735
+ }
116736
+ function getDisplayName$1(firstName, lastName, userName) {
116737
+ let displayName = "";
116738
+ let hasDisplayName = false;
116739
+ if (firstName) {
116740
+ displayName += firstName.trim();
116741
+ hasDisplayName = true;
116742
+ }
116743
+ if (lastName) {
116744
+ displayName += " " + lastName.trim();
116745
+ hasDisplayName = true;
116746
+ }
116747
+ displayName += getUserName(userName, hasDisplayName);
116748
+ return displayName;
116749
+ }
116750
+ function getDisplayNameFromProfile(userProfile) {
116751
+ return getDisplayName$1(
116752
+ userProfile.firstName,
116753
+ userProfile.lastName,
116754
+ userProfile.userName
116755
+ );
116756
+ }
116757
+ const availablePermissionLevels$1 = [
116758
+ "CAN_VIEW",
116759
+ "CAN_DOWNLOAD",
116760
+ "CAN_EDIT",
116761
+ "CAN_EDIT_DELETE",
116762
+ "CAN_ADMINISTER"
116763
+ ];
116764
+ function getSubject(entityName) {
116765
+ return `${entityName} (shared on Synapse)`;
116766
+ }
116767
+ function getBody(profile, entityId) {
116768
+ return `${getDisplayNameFromProfile(
116769
+ profile
116770
+ )} has shared an item with you on Synapse:
116771
+ ${getEndpoint(
116772
+ BackendDestinationEnum.PORTAL_ENDPOINT
116773
+ )}Synapse:${entityId}`;
116774
+ }
116775
+ function getCanEditResourceAccess(canEdit, isInherited, ownProfile) {
116776
+ if (!canEdit || isInherited) {
116777
+ return false;
116778
+ }
116779
+ return (resourceAccess) => {
116780
+ const isSelf = ownProfile.ownerId === String(resourceAccess.principalId);
116781
+ const isPublicGroup = resourceAccess.principalId === PUBLIC_PRINCIPAL_ID;
116782
+ if (isSelf || isPublicGroup) {
116783
+ return false;
116784
+ }
116785
+ return true;
116786
+ };
116787
+ }
116788
+ function getCanDeleteResourceAccess(canEdit, isInherited, ownProfile) {
116789
+ if (!canEdit || isInherited) {
116790
+ return false;
116791
+ }
116792
+ return (resourceAccess) => {
116793
+ const isSelf = ownProfile.ownerId === String(resourceAccess.principalId);
116794
+ if (isSelf) {
116795
+ return false;
116796
+ }
116797
+ return canEdit;
116798
+ };
116799
+ }
116800
+ function getDisplayedPermissionLevelOverride(isOpenData) {
116801
+ return (resourceAccess) => {
116802
+ if (resourceAccess.principalId === PUBLIC_PRINCIPAL_ID) {
116803
+ return isOpenData ? permissionLevelToLabel["CAN_DOWNLOAD"] : permissionLevelToLabel["CAN_VIEW"];
116804
+ }
116805
+ return void 0;
116806
+ };
116807
+ }
116808
+ const EntityAclEditor = React$2.forwardRef(function EntityAclEditor2(props, ref2) {
116809
+ const { entityId, onCanSaveChange, onUpdateSuccess } = props;
116810
+ const { data: ownProfile } = useSuspenseGetCurrentUserProfile();
116811
+ const { data: entityBundle } = useSuspenseGetEntityBundle(
116812
+ entityId,
116813
+ void 0,
116814
+ ALL_ENTITY_BUNDLE_FIELDS,
116815
+ { staleTime: Infinity }
116816
+ );
116817
+ const isProject = EntityType.PROJECT == entityBundle.entityType;
116818
+ const { data: parentAcl } = useSuspenseGetEntityBenefactorACL(
116819
+ entityBundle.entity.parentId,
116820
+ {
116821
+ staleTime: Infinity
116822
+ }
116823
+ );
116824
+ const originalResourceAccess = entityBundle.benefactorAcl.resourceAccess;
116825
+ const parentResourceAccess = React$2.useMemo(
116826
+ () => (parentAcl == null ? void 0 : parentAcl.resourceAccess) ?? [],
116827
+ [parentAcl]
116828
+ );
116829
+ const canEdit = entityBundle.permissions.canChangePermissions;
116830
+ const isOpenData = entityBundle.permissions.isEntityOpenData;
116831
+ const originalIsInherited = !(entityBundle.benefactorAcl.id == entityId);
116832
+ const [updatedIsInherited, setUpdatedIsInherited] = React$2.useState(originalIsInherited);
116833
+ const [notifyNewAdditions, setNotifyNewAdditions] = React$2.useState(false);
116834
+ const [error2, setError] = React$2.useState();
116835
+ const {
116836
+ resourceAccessList: updatedResourceAccessList,
116837
+ setResourceAccessList,
116838
+ addResourceAccessItem,
116839
+ updateResourceAccessItem,
116840
+ removeResourceAccessItem,
116841
+ resetDirtyState
116842
+ } = useUpdateAcl();
116843
+ React$2.useEffect(() => {
116844
+ if (originalResourceAccess) {
116845
+ resetDirtyState();
116846
+ setResourceAccessList(originalResourceAccess);
116847
+ }
116848
+ }, [originalResourceAccess, resetDirtyState, setResourceAccessList]);
116849
+ React$2.useEffect(() => {
116850
+ resetDirtyState();
116851
+ setUpdatedIsInherited(originalIsInherited);
116852
+ }, [originalIsInherited, resetDirtyState]);
116853
+ React$2.useEffect(() => {
116854
+ if (originalIsInherited == updatedIsInherited) {
116855
+ setResourceAccessList(originalResourceAccess);
116856
+ } else if (updatedIsInherited) {
116857
+ setResourceAccessList(parentResourceAccess);
116858
+ } else ;
116859
+ resetDirtyState();
116860
+ }, [
116861
+ originalIsInherited,
116862
+ originalResourceAccess,
116863
+ parentResourceAccess,
116864
+ resetDirtyState,
116865
+ setResourceAccessList,
116866
+ updatedIsInherited
116867
+ ]);
116868
+ const isPublic2 = updatedResourceAccessList.some(
116869
+ (ra) => [
116870
+ AUTHENTICATED_PRINCIPAL_ID,
116871
+ PUBLIC_PRINCIPAL_ID,
116872
+ ANONYMOUS_PRINCIPAL_ID
116873
+ ].includes(ra.principalId)
116874
+ );
116875
+ const {
116876
+ sendNotification,
116877
+ isLoading: isLoadingSendMessageToNewACLUsers,
116878
+ isPending: isPendingSendMessageToNewACLUsers
116879
+ } = useNotifyNewACLUsers({
116880
+ subject: getSubject(entityBundle.entity.name || ""),
116881
+ body: getBody(ownProfile, entityId),
116882
+ initialResourceAccessList: originalResourceAccess,
116883
+ newResourceAccessList: updatedResourceAccessList
116884
+ });
116885
+ const mutationOptions = {
116886
+ onSuccess: () => {
116887
+ if (notifyNewAdditions) {
116888
+ sendNotification();
116889
+ }
116890
+ onUpdateSuccess();
116891
+ },
116892
+ onError: (e2) => {
116893
+ setError(e2);
116894
+ }
116895
+ };
116896
+ const { mutate: createAcl, isPending: isPendingCreateAcl } = useCreateEntityACL(mutationOptions);
116897
+ const { mutate: updateAcl, isPending: isPendingUpdateAcl } = useUpdateEntityACL(mutationOptions);
116898
+ const { mutate: deleteAcl, isPending: isPendingDeleteAcl } = useDeleteEntityACL(mutationOptions);
116899
+ const isPending = isPendingCreateAcl || isPendingUpdateAcl || isPendingDeleteAcl || isPendingSendMessageToNewACLUsers;
116900
+ const hasAclChanged = React$2.useMemo(() => {
116901
+ return originalIsInherited != updatedIsInherited || !resourceAccessListIsEqual(
116902
+ originalResourceAccess,
116903
+ updatedResourceAccessList
116904
+ );
116905
+ }, [
116906
+ originalResourceAccess,
116907
+ originalIsInherited,
116908
+ updatedIsInherited,
116909
+ updatedResourceAccessList
116910
+ ]);
116911
+ const canSave = hasAclChanged || isLoadingSendMessageToNewACLUsers || isPending;
116912
+ React$2.useEffect(() => {
116913
+ onCanSaveChange(canSave);
116914
+ }, [onCanSaveChange, canSave]);
116915
+ React$2.useImperativeHandle(
116916
+ ref2,
116917
+ () => {
116918
+ return {
116919
+ save() {
116920
+ if (canSave) {
116921
+ if (originalIsInherited != updatedIsInherited) {
116922
+ if (updatedIsInherited) {
116923
+ deleteAcl(entityId);
116924
+ } else {
116925
+ createAcl({
116926
+ id: entityId,
116927
+ resourceAccess: updatedResourceAccessList
116928
+ });
116929
+ }
116930
+ } else {
116931
+ updateAcl({
116932
+ // ensure we get all fields from the original ACL, including the etag
116933
+ ...entityBundle.accessControlList,
116934
+ resourceAccess: updatedResourceAccessList
116935
+ });
116936
+ }
116937
+ } else {
116938
+ console.error("EntityAclEditor: save() called but canSave is false");
116939
+ }
116940
+ }
116941
+ };
116942
+ },
116943
+ [
116944
+ canSave,
116945
+ createAcl,
116946
+ deleteAcl,
116947
+ entityBundle,
116948
+ entityId,
116949
+ originalIsInherited,
116950
+ updateAcl,
116951
+ updatedIsInherited,
116952
+ updatedResourceAccessList
116953
+ ]
116954
+ );
116955
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(Stack$6, { gap: 2, children: [
116956
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
116957
+ OpenData,
116958
+ {
116959
+ isOpenData,
116960
+ isPublic: isPublic2,
116961
+ currentUserCanUpdateSharingSettings: canEdit
116962
+ }
116963
+ ),
116964
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
116965
+ InheritanceMessage,
116966
+ {
116967
+ isProject,
116968
+ isInherited: updatedIsInherited,
116969
+ benefactorId: updatedIsInherited ? parentAcl == null ? void 0 : parentAcl.id : entityId
116970
+ }
116971
+ ),
116972
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
116973
+ AclEditor,
116974
+ {
116975
+ canEdit: getCanEditResourceAccess(
116976
+ canEdit,
116977
+ updatedIsInherited,
116978
+ ownProfile
116979
+ ),
116980
+ canRemoveEntry: getCanDeleteResourceAccess(
116981
+ canEdit,
116982
+ updatedIsInherited,
116983
+ ownProfile
116984
+ ),
116985
+ resourceAccessList: updatedResourceAccessList,
116986
+ availablePermissionLevels: availablePermissionLevels$1,
116987
+ emptyText: (
116988
+ /* This should never happen */
116989
+ ""
116990
+ ),
116991
+ displayedPermissionLevelOverride: getDisplayedPermissionLevelOverride(
116992
+ isOpenData
116993
+ ),
116994
+ onAddPrincipalToAcl: (id2) => {
116995
+ if (id2 === PUBLIC_PRINCIPAL_ID) {
116996
+ addResourceAccessItem(
116997
+ id2,
116998
+ getAccessTypeFromPermissionLevel("CAN_VIEW")
116999
+ );
117000
+ } else {
117001
+ addResourceAccessItem(
117002
+ id2,
117003
+ getAccessTypeFromPermissionLevel("CAN_DOWNLOAD")
117004
+ );
117005
+ }
117006
+ },
117007
+ updateResourceAccessItem,
117008
+ removeResourceAccessItem,
117009
+ showNotifyCheckbox: true,
117010
+ notifyCheckboxValue: notifyNewAdditions,
117011
+ onNotifyCheckboxChange: setNotifyNewAdditions,
117012
+ showAddRemovePublicButton: true
117013
+ }
117014
+ ),
117015
+ !isProject && entityBundle.permissions.canEnableInheritance && /* @__PURE__ */ jsxRuntimeExports.jsx(
117016
+ CreateOrDeleteLocalSharingSettingsButton,
117017
+ {
117018
+ isInherited: updatedIsInherited,
117019
+ setIsInherited: setUpdatedIsInherited
117020
+ }
117021
+ ),
117022
+ error2 && /* @__PURE__ */ jsxRuntimeExports.jsx(Alert, { severity: "error", children: error2.message })
117023
+ ] });
117024
+ });
117025
+ const EntityAclEditorWithSuspense = React$2.forwardRef(
117026
+ function EntityAclEditorWithSuspense2(props, ref2) {
117027
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(SynapseErrorBoundary, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(React$2.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(AclEditorSkeleton, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(EntityAclEditor, { ...props, ref: ref2 }) }) });
117028
+ }
117029
+ );
117030
+ const ENTITY_SHARING_SETTINGS_HELP_MARKDOWN = `Sharing settings determine who can access your content, and what kind of access they have. Choose people/teams and define their level of access below.
117031
+
117032
+ _Only Administrators can add, delete, or change access levels for other people._`;
117033
+ const ENTITY_SHARING_SETTINGS_HELP_URL = "https://help.synapse.org/docs/Sharing-Settings,-Permissions,-and-Conditions-for-Use.2024276030.html";
117034
+ function EntityAclEditorModal(props) {
117035
+ var _a3;
117036
+ const { entityId, open, onUpdateSuccess = noop$9, onClose } = props;
117037
+ const [isDirty2, setIsDirty] = React$2.useState(false);
117038
+ const entityAclEditorRef = React$2.useRef(null);
117039
+ const { data: entityBundle } = useGetEntityBundle(entityId);
117040
+ const entityTypeDisplay = (entityBundle == null ? void 0 : entityBundle.entityType) ? entityTypeToFriendlyName(entityBundle == null ? void 0 : entityBundle.entityType) : "";
117041
+ const canEdit = (_a3 = entityBundle == null ? void 0 : entityBundle.permissions) == null ? void 0 : _a3.canChangePermissions;
117042
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
117043
+ ConfirmationDialog,
117044
+ {
117045
+ title: `${entityTypeDisplay} Sharing Settings`.trim(),
117046
+ onCancel: onClose,
117047
+ open,
117048
+ maxWidth: "md",
117049
+ titleHelpPopoverProps: {
117050
+ markdownText: ENTITY_SHARING_SETTINGS_HELP_MARKDOWN,
117051
+ helpUrl: ENTITY_SHARING_SETTINGS_HELP_URL
117052
+ },
117053
+ content: /* @__PURE__ */ jsxRuntimeExports.jsx(
117054
+ EntityAclEditorWithSuspense,
117055
+ {
117056
+ ref: entityAclEditorRef,
117057
+ entityId,
117058
+ onCanSaveChange: (isDirty22) => setIsDirty(isDirty22),
117059
+ onUpdateSuccess: () => {
117060
+ displayToast(
117061
+ "Permissions were successfully saved to Synapse",
117062
+ "info"
117063
+ );
117064
+ onUpdateSuccess();
117065
+ onClose();
117066
+ }
117067
+ }
117068
+ ),
117069
+ onConfirm: () => {
117070
+ entityAclEditorRef.current.save();
117071
+ },
117072
+ confirmButtonProps: {
117073
+ children: canEdit ? "Save" : "OK",
117074
+ disabled: !isDirty2
117075
+ }
117076
+ }
117077
+ );
117078
+ }
115984
117079
  const DEFAULT_ON_VIEW_SHARING_SETTINGS_CLICKED = (benefactorEntityId) => window.open(
115985
117080
  `https://www.synapse.org/Synapse:${benefactorEntityId}`,
115986
117081
  "_blank"
@@ -116000,7 +117095,11 @@ ${e2.message}`);
116000
117095
  includeEntity: true,
116001
117096
  includePermissions: true
116002
117097
  });
117098
+ const [showSharingSettings, setShowSharingSettings] = React$2.useState(false);
116003
117099
  const hasDownloadPermission = Boolean(entityBundle == null ? void 0 : entityBundle.permissions.canDownload);
117100
+ const useReactACLEditor = useGetFeatureFlag(
117101
+ FeatureFlagEnum.REACT_ENTITY_ACL_EDITOR
117102
+ );
116004
117103
  if (isError) {
116005
117104
  return /* @__PURE__ */ jsxRuntimeExports.jsx(Alert, { severity: "error", children: error2.reason });
116006
117105
  }
@@ -116019,12 +117118,20 @@ ${e2.message}`);
116019
117118
  count: count2,
116020
117119
  actionNode: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
116021
117120
  /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "smallText1", sx: { mb: 1, color: "grey.700" }, children: "Contact an administrator to request download permission" }),
117121
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
117122
+ EntityAclEditorModal,
117123
+ {
117124
+ entityId,
117125
+ open: showSharingSettings,
117126
+ onClose: () => setShowSharingSettings(false)
117127
+ }
117128
+ ),
116022
117129
  /* @__PURE__ */ jsxRuntimeExports.jsx(
116023
117130
  Button,
116024
117131
  {
116025
117132
  variant: "outlined",
116026
117133
  onClick: () => {
116027
- onViewSharingSettingsClicked(entityId);
117134
+ useReactACLEditor ? setShowSharingSettings(true) : onViewSharingSettingsClicked(entityId);
116028
117135
  },
116029
117136
  disabled: hasDownloadPermission,
116030
117137
  children: hasDownloadPermission ? "Complete" : "View Sharing Settings"
@@ -117296,29 +118403,6 @@ query = syn.tableQuery("${clientSql}")${"\n"}query.asDataFrame()`
117296
118403
  }
117297
118404
  );
117298
118405
  }
117299
- const SkeletonParagraph = ({
117300
- numRows = 5,
117301
- rowHeight,
117302
- className
117303
- }) => {
117304
- const [skeletons, setSkeletons] = React$2.useState([]);
117305
- React$2.useEffect(() => {
117306
- const elements = [];
117307
- times$2(numRows, (i2) => {
117308
- elements.push(
117309
- /* @__PURE__ */ jsxRuntimeExports.jsx(React$2.Fragment, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
117310
- Skeleton,
117311
- {
117312
- height: rowHeight,
117313
- width: i2 === numRows - 1 ? "35%" : "100%"
117314
- }
117315
- ) }, i2)
117316
- );
117317
- });
117318
- setSkeletons(elements);
117319
- }, [numRows, rowHeight]);
117320
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className, children: skeletons });
117321
- };
117322
118406
  function useExportToCavatica(queryBundleRequest, selectColumns, fileIdColumnName = "id", fileNameColumnName = "name", fileVersionColumnName = "currentVersion") {
117323
118407
  const { accessToken } = useSynapseContext();
117324
118408
  const separator = ",";
@@ -123241,7 +124325,7 @@ query = syn.tableQuery("${clientSql}")${"\n"}query.asDataFrame()`
123241
124325
  } = props;
123242
124326
  return /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Stack$6, { direction: "row", alignItems: "center", gap: "5px", children: [
123243
124327
  title2,
123244
- titleHelpPopoverProps && /* @__PURE__ */ jsxRuntimeExports.jsx(HelpPopover, { ...titleHelpPopoverProps }),
124328
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { component: "span", fontSize: "14px", children: titleHelpPopoverProps && /* @__PURE__ */ jsxRuntimeExports.jsx(HelpPopover, { ...titleHelpPopoverProps }) }),
123245
124329
  /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { flexGrow: 1 } }),
123246
124330
  hasCloseButton && /* @__PURE__ */ jsxRuntimeExports.jsx(CloseButton, { onClick: () => onCancel() })
123247
124331
  ] }) });
@@ -162047,38 +163131,7 @@ dl_list_file_entities = syn.get_download_list()`;
162047
163131
  }
162048
163132
  );
162049
163133
  };
162050
- const calculateOpacity = (rect) => {
162051
- const viewportHeight = window.innerHeight;
162052
- const elementCenterY = rect.top + rect.height / 2;
162053
- const middleRangeStart = viewportHeight * 0.4;
162054
- const middleRangeEnd = viewportHeight * 0.6;
162055
- if (elementCenterY <= middleRangeEnd) {
162056
- return 1;
162057
- } else {
162058
- const distanceToMiddle = Math.min(
162059
- Math.abs(elementCenterY - middleRangeStart),
162060
- Math.abs(elementCenterY - middleRangeEnd)
162061
- );
162062
- const maxDistance = viewportHeight / 4;
162063
- return Math.max(0, 1 - distanceToMiddle / maxDistance);
162064
- }
162065
- };
162066
- function useScrollFadeTransition() {
162067
- const ref2 = React$2.useRef(null);
162068
- const [opacity, setOpacity] = React$2.useState(1);
162069
- React$2.useEffect(() => {
162070
- const handleScroll = () => {
162071
- const rect = ref2.current.getBoundingClientRect();
162072
- setOpacity(calculateOpacity(rect));
162073
- };
162074
- if (ref2) {
162075
- window.addEventListener("scroll", handleScroll);
162076
- handleScroll();
162077
- }
162078
- return () => window.removeEventListener("scroll", handleScroll);
162079
- }, [ref2]);
162080
- return { ref: ref2, opacity };
162081
- }
163134
+ const transitionTimeoutMs = 320;
162082
163135
  const mobileViewSxProps = {
162083
163136
  display: "flex",
162084
163137
  justifyContent: "center",
@@ -162099,7 +163152,7 @@ dl_list_file_entities = syn.get_download_list()`;
162099
163152
  }) => {
162100
163153
  const theme3 = useTheme$1();
162101
163154
  const isMobileView = useMediaQuery(theme3.breakpoints.down("sm"));
162102
- const { ref: ref2, opacity } = useScrollFadeTransition();
163155
+ const [ref2, inView] = useInView({ threshold: 0.3, triggerOnce: true });
162103
163156
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
162104
163157
  Box,
162105
163158
  {
@@ -162212,16 +163265,15 @@ dl_list_file_entities = syn.get_download_list()`;
162212
163265
  sx: {
162213
163266
  display: { xs: "none", md: "block" },
162214
163267
  justifySelf: "end",
162215
- alignSelf: "end",
162216
- opacity
163268
+ alignSelf: "end"
162217
163269
  },
162218
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(
163270
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Fade, { in: inView, timeout: transitionTimeoutMs, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Slide, { direction: "left", timeout: transitionTimeoutMs, in: inView, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
162219
163271
  ImageFromSynapseTable,
162220
163272
  {
162221
163273
  tableId,
162222
163274
  fileHandleId: imageFileHandleId
162223
163275
  }
162224
- )
163276
+ ) }) }) }) })
162225
163277
  }
162226
163278
  )
162227
163279
  ]
@@ -162538,11 +163590,7 @@ dl_list_file_entities = syn.get_download_list()`;
162538
163590
  SynapsePlanContent,
162539
163591
  {
162540
163592
  category: "Explore Data",
162541
- items: [
162542
- "<100 GB of content",
162543
- "Sage Managed Individual Storage",
162544
- "4TB/year of data egress"
162545
- ]
163593
+ items: ["<100 GB of content", "Sage Managed Individual Storage"]
162546
163594
  }
162547
163595
  ),
162548
163596
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -162574,11 +163622,7 @@ dl_list_file_entities = syn.get_download_list()`;
162574
163622
  SynapsePlanContent,
162575
163623
  {
162576
163624
  category: "Explore More Data",
162577
- items: [
162578
- "<500 GB of content",
162579
- "Secure cloud storage",
162580
- "<20 TB/year of data egress"
162581
- ]
163625
+ items: ["<500 GB of content", "Secure cloud storage"]
162582
163626
  }
162583
163627
  ),
162584
163628
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -163439,90 +164483,99 @@ dl_list_file_entities = syn.get_download_list()`;
163439
164483
  })
163440
164484
  }
163441
164485
  ),
163442
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
164486
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
163443
164487
  Box,
163444
164488
  {
163445
164489
  sx: {
163446
- display: { xs: "relative", lg: "grid" },
163447
- gridTemplateColumns: "50% 50%",
163448
164490
  backgroundColor: "#F5F9F9",
163449
- mt: { xs: "50px", md: "100px" },
163450
- height: { lg: "608px" }
163451
- //force container to the same height as the image
164491
+ mt: { xs: "50px", md: "100px" }
163452
164492
  },
163453
- children: [
163454
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
163455
- Box,
163456
- {
163457
- sx: {
163458
- p: { xs: "25px", lg: "70px 0px 25px 60px" },
163459
- svg: {
163460
- maxWidth: "100%"
163461
- },
163462
- display: "flex",
163463
- flexDirection: "column",
163464
- alignItems: {
163465
- xs: "center",
163466
- md: "flex-start"
163467
- }
163468
- },
163469
- ref: ref2,
163470
- children: [
163471
- /* @__PURE__ */ jsxRuntimeExports.jsx(SageFullLogo, { width: 350 }),
163472
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
163473
- Typography,
163474
- {
163475
- variant: "headline2",
163476
- sx: {
163477
- ...defaultHomepageText,
163478
- fontSize: {
163479
- xs: "24px",
163480
- md: "40px"
163481
- },
163482
- lineHeight: {
163483
- xs: "140%",
163484
- md: "60px"
163485
- },
163486
- maxWidth: "600px",
163487
- color: "secondary.600",
163488
- mt: "20px",
163489
- fontWeight: 400,
163490
- mb: "35px",
163491
- textAlign: {
163492
- xs: "center",
163493
- md: "left"
163494
- }
164493
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
164494
+ Box,
164495
+ {
164496
+ sx: {
164497
+ display: { xs: "relative", lg: "grid" },
164498
+ maxWidth: "1500px",
164499
+ gridTemplateColumns: "50% 50%",
164500
+ margin: "auto",
164501
+ height: { lg: "608px" }
164502
+ //force container to the same height as the image
164503
+ },
164504
+ children: [
164505
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
164506
+ Box,
164507
+ {
164508
+ sx: {
164509
+ p: { xs: "25px", lg: "70px 0px 25px 60px" },
164510
+ svg: {
164511
+ maxWidth: "100%"
163495
164512
  },
163496
- children: [
163497
- "Created by ",
163498
- /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Sage Bionetworks" }),
163499
- ", Synapse empowers biomedical researchers with tools for open science and collaboration, forging a path to optimal human health."
163500
- ]
163501
- }
163502
- ),
163503
- /* @__PURE__ */ jsxRuntimeExports.jsx(
163504
- Button,
163505
- {
163506
- size: "large",
163507
- variant: "contained",
163508
- color: "secondary",
163509
- href: "https://www.sagebionetworks.org",
163510
- target: "_blank",
163511
- sx: {
163512
- p: "5px 25px",
163513
- width: {
163514
- xs: "100%",
163515
- md: "auto"
164513
+ display: "flex",
164514
+ flexDirection: "column",
164515
+ alignItems: {
164516
+ xs: "center",
164517
+ md: "flex-start"
164518
+ }
164519
+ },
164520
+ ref: ref2,
164521
+ children: [
164522
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SageFullLogo, { width: 350 }),
164523
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
164524
+ Typography,
164525
+ {
164526
+ variant: "headline2",
164527
+ sx: {
164528
+ ...defaultHomepageText,
164529
+ fontSize: {
164530
+ xs: "24px",
164531
+ md: "40px"
164532
+ },
164533
+ lineHeight: {
164534
+ xs: "140%",
164535
+ md: "60px"
164536
+ },
164537
+ maxWidth: "600px",
164538
+ color: "secondary.600",
164539
+ mt: "20px",
164540
+ fontWeight: 400,
164541
+ mb: "35px",
164542
+ textAlign: {
164543
+ xs: "center",
164544
+ md: "left"
164545
+ }
164546
+ },
164547
+ children: [
164548
+ "Created by ",
164549
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Sage Bionetworks" }),
164550
+ ", Synapse empowers biomedical researchers with tools for open science and collaboration, forging a path to optimal human health."
164551
+ ]
163516
164552
  }
163517
- },
163518
- children: "About Sage Bionetworks"
163519
- }
163520
- )
163521
- ]
163522
- }
163523
- ),
163524
- isDesktopView && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { height: "100%", justifySelf: "end" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ForwardRef$w, {}) })
163525
- ]
164553
+ ),
164554
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
164555
+ Button,
164556
+ {
164557
+ size: "large",
164558
+ variant: "contained",
164559
+ color: "secondary",
164560
+ href: "https://www.sagebionetworks.org",
164561
+ target: "_blank",
164562
+ sx: {
164563
+ p: "5px 25px",
164564
+ width: {
164565
+ xs: "100%",
164566
+ md: "auto"
164567
+ }
164568
+ },
164569
+ children: "About Sage Bionetworks"
164570
+ }
164571
+ )
164572
+ ]
164573
+ }
164574
+ ),
164575
+ isDesktopView && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { height: "100%", justifySelf: "end" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ForwardRef$w, {}) })
164576
+ ]
164577
+ }
164578
+ )
163526
164579
  }
163527
164580
  ),
163528
164581
  inView && /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { children: [
@@ -163569,7 +164622,7 @@ dl_list_file_entities = syn.get_download_list()`;
163569
164622
  }
163570
164623
  }
163571
164624
  ),
163572
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
164625
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
163573
164626
  Box,
163574
164627
  {
163575
164628
  sx: {
@@ -163585,62 +164638,71 @@ dl_list_file_entities = syn.get_download_list()`;
163585
164638
  },
163586
164639
  pb: "5px"
163587
164640
  },
163588
- children: [
163589
- /* @__PURE__ */ jsxRuntimeExports.jsx(
163590
- Typography,
163591
- {
163592
- variant: "headline1",
163593
- sx: {
163594
- ...h2Sx,
163595
- textAlign: "center",
163596
- mt: "100px",
163597
- mb: "10px",
163598
- color: "white"
163599
- },
163600
- children: "Synapse by the numbers"
163601
- }
163602
- ),
163603
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
163604
- Typography,
163605
- {
163606
- variant: "body1",
163607
- sx: {
163608
- ...homepageBodyText,
163609
- textAlign: "center",
163610
- mb: "70px",
163611
- color: "white"
163612
- },
163613
- children: [
163614
- /* @__PURE__ */ jsxRuntimeExports.jsx(BlinkingLiveIcon, { sx: { pt: "7px" } }),
163615
- " Live"
163616
- ]
163617
- }
163618
- ),
163619
- /* @__PURE__ */ jsxRuntimeExports.jsx(SynapseByTheNumbers, { metricsTable: generalStatsMetricsTable }),
163620
- /* @__PURE__ */ jsxRuntimeExports.jsx(
163621
- Typography,
163622
- {
163623
- variant: "headline2",
163624
- sx: {
163625
- ...defaultHomepageText,
163626
- textAlign: "center",
163627
- fontSize: "36px",
163628
- lineHeight: "40px",
163629
- mt: "60px",
163630
- mb: "25px",
163631
- color: "white",
163632
- fontWeight: 400
163633
- },
163634
- children: "Projects trending this month"
163635
- }
163636
- ),
163637
- /* @__PURE__ */ jsxRuntimeExports.jsx(
163638
- SynapseTrendingProjects,
163639
- {
163640
- past30DaysDownloadMetricsTable
163641
- }
163642
- )
163643
- ]
164641
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
164642
+ Box,
164643
+ {
164644
+ sx: {
164645
+ margin: "auto",
164646
+ maxWidth: "1500px"
164647
+ },
164648
+ children: [
164649
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
164650
+ Typography,
164651
+ {
164652
+ variant: "headline1",
164653
+ sx: {
164654
+ ...h2Sx,
164655
+ textAlign: "center",
164656
+ mt: "100px",
164657
+ mb: "10px",
164658
+ color: "white"
164659
+ },
164660
+ children: "Synapse by the numbers"
164661
+ }
164662
+ ),
164663
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
164664
+ Typography,
164665
+ {
164666
+ variant: "body1",
164667
+ sx: {
164668
+ ...homepageBodyText,
164669
+ textAlign: "center",
164670
+ mb: "70px",
164671
+ color: "white"
164672
+ },
164673
+ children: [
164674
+ /* @__PURE__ */ jsxRuntimeExports.jsx(BlinkingLiveIcon, { sx: { pt: "7px" } }),
164675
+ " Live"
164676
+ ]
164677
+ }
164678
+ ),
164679
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SynapseByTheNumbers, { metricsTable: generalStatsMetricsTable }),
164680
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
164681
+ Typography,
164682
+ {
164683
+ variant: "headline2",
164684
+ sx: {
164685
+ ...defaultHomepageText,
164686
+ textAlign: "center",
164687
+ fontSize: "36px",
164688
+ lineHeight: "40px",
164689
+ mt: "60px",
164690
+ mb: "25px",
164691
+ color: "white",
164692
+ fontWeight: 400
164693
+ },
164694
+ children: "Projects trending this month"
164695
+ }
164696
+ ),
164697
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
164698
+ SynapseTrendingProjects,
164699
+ {
164700
+ past30DaysDownloadMetricsTable
164701
+ }
164702
+ )
164703
+ ]
164704
+ }
164705
+ )
163644
164706
  }
163645
164707
  ),
163646
164708
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -176751,294 +177813,6 @@ dl_list_file_entities = syn.get_download_list()`;
176751
177813
  }
176752
177814
  );
176753
177815
  }
176754
- function compareResourceAccessAndUserGroupHeader(a2, b2) {
176755
- let CompareResult;
176756
- ((CompareResult2) => {
176757
- CompareResult2[CompareResult2["A_FIRST"] = -1] = "A_FIRST";
176758
- CompareResult2[CompareResult2["B_FIRST"] = 1] = "B_FIRST";
176759
- })(CompareResult || (CompareResult = {}));
176760
- const hasChangePermissionA = a2.resourceAccess.accessType.includes(
176761
- ACCESS_TYPE.CHANGE_PERMISSIONS
176762
- );
176763
- const hasChangePermissionB = b2.resourceAccess.accessType.includes(
176764
- ACCESS_TYPE.CHANGE_PERMISSIONS
176765
- );
176766
- if (hasChangePermissionA && !hasChangePermissionB)
176767
- return -1;
176768
- if (!hasChangePermissionA && hasChangePermissionB)
176769
- return 1;
176770
- if (a2.resourceAccess.principalId === AUTHENTICATED_PRINCIPAL_ID && b2.resourceAccess.principalId !== AUTHENTICATED_PRINCIPAL_ID)
176771
- return -1;
176772
- if (a2.resourceAccess.principalId !== AUTHENTICATED_PRINCIPAL_ID && b2.resourceAccess.principalId === AUTHENTICATED_PRINCIPAL_ID)
176773
- return 1;
176774
- if (a2.resourceAccess.principalId === PUBLIC_PRINCIPAL_ID && b2.resourceAccess.principalId !== PUBLIC_PRINCIPAL_ID)
176775
- return -1;
176776
- if (a2.resourceAccess.principalId !== PUBLIC_PRINCIPAL_ID && b2.resourceAccess.principalId === PUBLIC_PRINCIPAL_ID)
176777
- return 1;
176778
- return a2.userGroupHeader.userName.localeCompare(b2.userGroupHeader.userName);
176779
- }
176780
- function useSortResourceAccessList(resourceAccessList) {
176781
- const principalIdsOnResourceAccessList = React$2.useMemo(
176782
- () => resourceAccessList.map((ra) => ra.principalId),
176783
- [resourceAccessList]
176784
- );
176785
- const {
176786
- data: userGroupHeadersOnResourceAccessList,
176787
- isLoading,
176788
- error: error2
176789
- } = useGetUserGroupHeaders(principalIdsOnResourceAccessList.map(String));
176790
- React$2.useEffect(() => {
176791
- if (error2) {
176792
- console.error("Error fetching user group headers: ", error2);
176793
- }
176794
- }, [error2]);
176795
- const sortedResourceAccessList = React$2.useMemo(() => {
176796
- if (!userGroupHeadersOnResourceAccessList) {
176797
- return resourceAccessList;
176798
- }
176799
- const joinedWithUserGroupHeaders = resourceAccessList.map(
176800
- (ral) => ({
176801
- resourceAccess: ral,
176802
- userGroupHeader: userGroupHeadersOnResourceAccessList.find(
176803
- (ugh) => String(ugh.ownerId) === String(ral.principalId)
176804
- )
176805
- })
176806
- );
176807
- const allEntriesHaveUserGroupHeader = joinedWithUserGroupHeaders.every(
176808
- (obj) => Boolean(obj.userGroupHeader)
176809
- );
176810
- if (!allEntriesHaveUserGroupHeader) {
176811
- console.warn(
176812
- "Some ACL entries do not have a corresponding UserGroupHeader. The ResourceAccess list will not be sorted. Missing entries: ",
176813
- joinedWithUserGroupHeaders.filter((obj) => !obj.userGroupHeader)
176814
- );
176815
- return resourceAccessList;
176816
- }
176817
- return joinedWithUserGroupHeaders.toSorted(compareResourceAccessAndUserGroupHeader).map((obj) => obj.resourceAccess);
176818
- }, [resourceAccessList, userGroupHeadersOnResourceAccessList]);
176819
- return {
176820
- sortedResourceAccessList,
176821
- isLoading
176822
- };
176823
- }
176824
- const PRINCIPAL_ALREADY_ADDED_ERROR_MESSAGE = "User or team already has permissions.";
176825
- function useUpdateAcl(options2) {
176826
- const { onChange = noop$9, onError = noop$9 } = options2;
176827
- const [isDirty2, setIsDirty] = React$2.useState(false);
176828
- const [resourceAccessList, setResourceAccessList] = React$2.useState([]);
176829
- const [hasSorted, setHasSorted] = React$2.useState(false);
176830
- const { sortedResourceAccessList, isLoading: isLoadingSortedList } = useSortResourceAccessList(resourceAccessList);
176831
- React$2.useEffect(() => {
176832
- if (!isDirty2 && !isLoadingSortedList && !hasSorted) {
176833
- setResourceAccessList(sortedResourceAccessList);
176834
- setHasSorted(true);
176835
- }
176836
- }, [hasSorted, isDirty2, isLoadingSortedList, sortedResourceAccessList]);
176837
- React$2.useEffect(() => {
176838
- onChange(resourceAccessList);
176839
- }, [resourceAccessList]);
176840
- const addResourceAccessItem = (newReviewerId, accessTypes) => {
176841
- setIsDirty(true);
176842
- if (newReviewerId) {
176843
- const alreadyReviewer = resourceAccessList.some(
176844
- (resourceAccess) => resourceAccess.principalId === Number(newReviewerId)
176845
- );
176846
- if (alreadyReviewer) {
176847
- onError(PRINCIPAL_ALREADY_ADDED_ERROR_MESSAGE);
176848
- } else {
176849
- const newResourceAccess = {
176850
- principalId: Number(newReviewerId),
176851
- accessType: accessTypes
176852
- };
176853
- const updatedResourceAccessList = [
176854
- ...resourceAccessList,
176855
- newResourceAccess
176856
- ];
176857
- setResourceAccessList(updatedResourceAccessList);
176858
- }
176859
- }
176860
- };
176861
- const updateResourceAccessItem = (principalId, accessType) => {
176862
- setIsDirty(true);
176863
- const updatedResourceAccessList = resourceAccessList.map((resourceAccess) => {
176864
- return resourceAccess.principalId === principalId ? { ...resourceAccess, accessType } : resourceAccess;
176865
- });
176866
- setResourceAccessList(updatedResourceAccessList);
176867
- };
176868
- const removeResourceAccessItem = (principalId) => {
176869
- setIsDirty(true);
176870
- const updatedResourceAccessList = resourceAccessList.filter(
176871
- (raListItem) => raListItem.principalId !== principalId
176872
- );
176873
- setResourceAccessList(updatedResourceAccessList);
176874
- };
176875
- return {
176876
- resourceAccessList,
176877
- setResourceAccessList,
176878
- addResourceAccessItem,
176879
- updateResourceAccessItem,
176880
- removeResourceAccessItem
176881
- };
176882
- }
176883
- const PermissionLevelMenu = (props) => {
176884
- const { currentAccessType, availablePermissionLevels: availablePermissionLevels2, onChange } = props;
176885
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
176886
- TextField$1,
176887
- {
176888
- value: getPermissionLevelFromAccessType(currentAccessType) || null,
176889
- onChange: (e2) => {
176890
- const accessType = getAccessTypeFromPermissionLevel(
176891
- e2.target.value
176892
- );
176893
- if (!accessType) {
176894
- console.error(
176895
- `ACCESS_TYPE[] not found for PermissionLevel: ${e2.target.value}`
176896
- );
176897
- }
176898
- onChange(accessType || null);
176899
- },
176900
- fullWidth: true,
176901
- select: true,
176902
- SelectProps: {
176903
- renderValue: (selected) => permissionLevelToLabel[selected]
176904
- },
176905
- size: "small",
176906
- children: Object.values(availablePermissionLevels2).map((permissionLevel) => {
176907
- return /* @__PURE__ */ jsxRuntimeExports.jsx(MenuItem, { value: permissionLevel, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "smallText1", noWrap: true, children: permissionLevelToLabel[permissionLevel] }) }, permissionLevel);
176908
- })
176909
- }
176910
- );
176911
- };
176912
- function ReadOnlyPermissionLevel(props) {
176913
- const { accessType } = props;
176914
- return permissionLevelToLabel[getPermissionLevelFromAccessType(accessType)];
176915
- }
176916
- const REMOVE_BUTTON_LABEL = "Remove from AR Permissions";
176917
- const ResourceAccessItem = (props) => {
176918
- const {
176919
- resourceAccess,
176920
- availablePermissionLevels: availablePermissionLevels2,
176921
- isInEditMode,
176922
- onChange,
176923
- onRemove: onRemove2
176924
- } = props;
176925
- return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
176926
- Stack$6,
176927
- {
176928
- direction: "row",
176929
- justifyContent: "space-between",
176930
- alignItems: "center",
176931
- gap: "10px",
176932
- py: "6px",
176933
- role: "row",
176934
- children: [
176935
- /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { fontSize: "16px", lineHeight: "20px", children: /* @__PURE__ */ jsxRuntimeExports.jsx(UserOrTeamBadge, { principalId: resourceAccess.principalId }) }),
176936
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Stack$6, { direction: "row", gap: "10px", alignItems: "center", width: "225px", children: [
176937
- !isInEditMode && /* @__PURE__ */ jsxRuntimeExports.jsx(ReadOnlyPermissionLevel, { accessType: resourceAccess.accessType }),
176938
- isInEditMode && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
176939
- /* @__PURE__ */ jsxRuntimeExports.jsx(
176940
- PermissionLevelMenu,
176941
- {
176942
- currentAccessType: resourceAccess.accessType,
176943
- availablePermissionLevels: availablePermissionLevels2,
176944
- onChange
176945
- }
176946
- ),
176947
- /* @__PURE__ */ jsxRuntimeExports.jsx(
176948
- IconSvgButton,
176949
- {
176950
- "aria-label": REMOVE_BUTTON_LABEL,
176951
- onClick: () => onRemove2(),
176952
- icon: "delete",
176953
- sx: {
176954
- "&:hover": {
176955
- color: "error.main"
176956
- }
176957
- }
176958
- }
176959
- )
176960
- ] })
176961
- ] })
176962
- ]
176963
- }
176964
- ) });
176965
- };
176966
- function AclEditor(props) {
176967
- const {
176968
- isInEditMode,
176969
- isLoading,
176970
- resourceAccessList,
176971
- availablePermissionLevels: availablePermissionLevels2,
176972
- emptyText,
176973
- onAddPrincipalToAcl,
176974
- updateResourceAccessItem,
176975
- removeResourceAccessItem
176976
- } = props;
176977
- if (isLoading) {
176978
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { display: "flex", justifyContent: "center", height: "150px", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SynapseSpinner, { size: 50 }) });
176979
- }
176980
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { children: [
176981
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { mb: "30px", children: [
176982
- /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "headline3", mb: "10px", children: "Users and Teams with Permissions" }),
176983
- resourceAccessList.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body1Italic", children: emptyText }) : /* @__PURE__ */ jsxRuntimeExports.jsx(TransitionGroup, { children: resourceAccessList.map((resourceAccess) => {
176984
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapse$1, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
176985
- ResourceAccessItem,
176986
- {
176987
- resourceAccess,
176988
- availablePermissionLevels: availablePermissionLevels2,
176989
- isInEditMode,
176990
- onChange: (accessType) => updateResourceAccessItem(
176991
- resourceAccess.principalId,
176992
- accessType
176993
- ),
176994
- onRemove: () => removeResourceAccessItem(resourceAccess.principalId)
176995
- },
176996
- resourceAccess.principalId
176997
- ) }, resourceAccess.principalId);
176998
- }) })
176999
- ] }),
177000
- isInEditMode && /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { children: [
177001
- /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "headline3", mb: "10px", children: "Add More" }),
177002
- /* @__PURE__ */ jsxRuntimeExports.jsx(
177003
- Typography,
177004
- {
177005
- sx: {
177006
- variant: "body1",
177007
- lineHeight: "20px",
177008
- fontStyle: "italic",
177009
- color: "grey.900"
177010
- },
177011
- mb: "20px",
177012
- children: "Search for a username or team to add. You can search by username, first or last names, or team name"
177013
- }
177014
- ),
177015
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { children: [
177016
- /* @__PURE__ */ jsxRuntimeExports.jsx(
177017
- Typography,
177018
- {
177019
- component: "label",
177020
- variant: "smallText2",
177021
- htmlFor: "reviewer-search",
177022
- children: "Add a user or team"
177023
- }
177024
- ),
177025
- /* @__PURE__ */ jsxRuntimeExports.jsx(
177026
- UserSearchBoxV2,
177027
- {
177028
- value: null,
177029
- inputId: "reviewer-search",
177030
- placeholder: "Username, name (first and last) or team name.",
177031
- onChange: (id2) => {
177032
- if (id2) {
177033
- onAddPrincipalToAcl(id2);
177034
- }
177035
- }
177036
- }
177037
- )
177038
- ] })
177039
- ] })
177040
- ] });
177041
- }
177042
177816
  const textSx = {
177043
177817
  variant: "body1",
177044
177818
  lineHeight: "20px",
@@ -177071,13 +177845,15 @@ dl_list_file_entities = syn.get_download_list()`;
177071
177845
  setResourceAccessList,
177072
177846
  addResourceAccessItem,
177073
177847
  updateResourceAccessItem,
177074
- removeResourceAccessItem
177848
+ removeResourceAccessItem,
177849
+ resetDirtyState
177075
177850
  } = useUpdateAcl({
177076
177851
  onChange: () => setError(null),
177077
177852
  onError: setError
177078
177853
  });
177079
177854
  React$2.useEffect(() => {
177080
177855
  if (originalAcl) {
177856
+ resetDirtyState();
177081
177857
  setResourceAccessList(originalAcl.resourceAccess);
177082
177858
  }
177083
177859
  }, [originalAcl, setResourceAccessList]);
@@ -177146,11 +177922,13 @@ dl_list_file_entities = syn.get_download_list()`;
177146
177922
  resourceAccessList,
177147
177923
  availablePermissionLevels,
177148
177924
  isLoading: isLoadingOriginalAcl,
177149
- isInEditMode: true,
177925
+ canEdit: true,
177150
177926
  emptyText: EMPTY_RESOURCE_ACCESS_LIST_TEXT,
177151
177927
  onAddPrincipalToAcl: (id2) => addResourceAccessItem(id2, [ACCESS_TYPE.REVIEW_SUBMISSIONS]),
177152
177928
  updateResourceAccessItem,
177153
- removeResourceAccessItem
177929
+ removeResourceAccessItem,
177930
+ showAddRemovePublicButton: false,
177931
+ showNotifyCheckbox: false
177154
177932
  }
177155
177933
  ),
177156
177934
  error2 && /* @__PURE__ */ jsxRuntimeExports.jsx(Alert, { severity: "error", children: error2 })
@@ -178757,8 +179535,7 @@ dl_list_file_entities = syn.get_download_list()`;
178757
179535
  portalVersion,
178758
179536
  srcVersion,
178759
179537
  repoVersion,
178760
- gotoPlace,
178761
- reportViolationCallback
179538
+ gotoPlace
178762
179539
  }) => {
178763
179540
  const { accessToken } = useSynapseContext();
178764
179541
  const registrationUrl = useOneSageURL("/register1");
@@ -178901,10 +179678,12 @@ dl_list_file_entities = syn.get_download_list()`;
178901
179678
  },
178902
179679
  {
178903
179680
  text: "Report Violations",
178904
- props: { onClick: reportViolationCallback }
179681
+ props: {
179682
+ href: "https://sagebionetworks.jira.com/servicedesk/customer/portal/20"
179683
+ }
178905
179684
  },
178906
179685
  {
178907
- text: "Privacy & Terms of Service",
179686
+ text: "Trust Center",
178908
179687
  props: { href: "https://sagebionetworks.org/trust-center" }
178909
179688
  }
178910
179689
  ]
@@ -179304,7 +180083,7 @@ dl_list_file_entities = syn.get_download_list()`;
179304
180083
  )
179305
180084
  ] });
179306
180085
  };
179307
- const version = "3.3.6";
180086
+ const version = "3.3.7";
179308
180087
  const SynapseEnums = {
179309
180088
  BackendDestinationEnum
179310
180089
  };
@@ -179388,7 +180167,8 @@ dl_list_file_entities = syn.get_download_list()`;
179388
180167
  CreateOrUpdateAccessRequirementWizard,
179389
180168
  GoogleAnalytics,
179390
180169
  CookiesNotification,
179391
- getCurrentCookiePreferences
180170
+ getCurrentCookiePreferences,
180171
+ EntityAclEditorModal
179392
180172
  };
179393
180173
  const SynapseReactClientVersion = version;
179394
180174
  exports2.HttpClient = HttpClient;