synapse-react-client 4.0.10 → 4.0.12

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.
Files changed (210) hide show
  1. package/dist/SWC.index.d.ts +1 -1
  2. package/dist/SWC.index.js +1 -1
  3. package/dist/assets/icons/CloudWarning.d.ts +5 -0
  4. package/dist/assets/icons/CloudWarning.d.ts.map +1 -0
  5. package/dist/assets/icons/CloudWarning.js +47 -0
  6. package/dist/assets/icons/CloudWarning.js.map +1 -0
  7. package/dist/components/AdaptiveTwoColumnLayout/AdaptiveTwoColumnLayout.d.ts +44 -0
  8. package/dist/components/AdaptiveTwoColumnLayout/AdaptiveTwoColumnLayout.d.ts.map +1 -0
  9. package/dist/components/AdaptiveTwoColumnLayout/AdaptiveTwoColumnLayout.js +46 -0
  10. package/dist/components/AdaptiveTwoColumnLayout/AdaptiveTwoColumnLayout.js.map +1 -0
  11. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.d.ts.map +1 -1
  12. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.js +143 -140
  13. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.js.map +1 -1
  14. package/dist/components/DataGrid/columns/AutocompleteColumn.d.ts.map +1 -1
  15. package/dist/components/DataGrid/columns/AutocompleteColumn.js +66 -55
  16. package/dist/components/DataGrid/columns/AutocompleteColumn.js.map +1 -1
  17. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.d.ts.map +1 -1
  18. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.js +1 -1
  19. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.js.map +1 -1
  20. package/dist/components/DataGrid/utils/applyModelChange.d.ts +1 -1
  21. package/dist/components/DataGrid/utils/applyModelChange.d.ts.map +1 -1
  22. package/dist/components/DataGrid/utils/applyModelChange.js +27 -24
  23. package/dist/components/DataGrid/utils/applyModelChange.js.map +1 -1
  24. package/dist/components/DataGrid/utils/columnFactory.d.ts +8 -0
  25. package/dist/components/DataGrid/utils/columnFactory.d.ts.map +1 -1
  26. package/dist/components/DataGrid/utils/columnFactory.js +47 -44
  27. package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
  28. package/dist/components/DataGrid/utils/getEmptyValue.d.ts +2 -0
  29. package/dist/components/DataGrid/utils/getEmptyValue.d.ts.map +1 -0
  30. package/dist/components/DataGrid/utils/getEmptyValue.js +8 -0
  31. package/dist/components/DataGrid/utils/getEmptyValue.js.map +1 -0
  32. package/dist/components/DataGrid/utils/modelColsToGrid.d.ts.map +1 -1
  33. package/dist/components/DataGrid/utils/modelColsToGrid.js +2 -1
  34. package/dist/components/DataGrid/utils/modelColsToGrid.js.map +1 -1
  35. package/dist/components/DataGrid/utils/schemaAwarePasteValue.d.ts +32 -0
  36. package/dist/components/DataGrid/utils/schemaAwarePasteValue.d.ts.map +1 -0
  37. package/dist/components/DataGrid/utils/schemaAwarePasteValue.js +22 -0
  38. package/dist/components/DataGrid/utils/schemaAwarePasteValue.js.map +1 -0
  39. package/dist/components/DownloadCart/DownloadCartPage.d.ts.map +1 -1
  40. package/dist/components/DownloadCart/DownloadCartPage.js +183 -185
  41. package/dist/components/DownloadCart/DownloadCartPage.js.map +1 -1
  42. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.css +1 -0
  43. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.d.ts.map +1 -1
  44. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js +199 -132
  45. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js.map +1 -1
  46. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.js +22 -0
  47. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.js.map +1 -0
  48. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.scss +170 -0
  49. package/dist/components/EntityAclEditor/EntityAclEditor.js +8 -8
  50. package/dist/components/EntityAclEditor/EntityAclEditor.js.map +1 -1
  51. package/dist/components/EntityAclEditor/InheritanceMessage.d.ts.map +1 -1
  52. package/dist/components/EntityAclEditor/InheritanceMessage.js +1 -2
  53. package/dist/components/EntityAclEditor/InheritanceMessage.js.map +1 -1
  54. package/dist/components/EntityDownloadButton/EntityDownloadButton.d.ts.map +1 -1
  55. package/dist/components/EntityDownloadButton/EntityDownloadButton.js +1 -0
  56. package/dist/components/EntityDownloadButton/EntityDownloadButton.js.map +1 -1
  57. package/dist/components/EntityViewScopeEditor/EntityViewMaskEditor.d.ts.map +1 -1
  58. package/dist/components/EntityViewScopeEditor/EntityViewMaskEditor.js +15 -14
  59. package/dist/components/EntityViewScopeEditor/EntityViewMaskEditor.js.map +1 -1
  60. package/dist/components/Forum/DiscussionReply.d.ts +1 -0
  61. package/dist/components/Forum/DiscussionReply.d.ts.map +1 -1
  62. package/dist/components/Forum/DiscussionReply.js +19 -19
  63. package/dist/components/Forum/DiscussionReply.js.map +1 -1
  64. package/dist/components/Forum/DiscussionThread.d.ts +1 -0
  65. package/dist/components/Forum/DiscussionThread.d.ts.map +1 -1
  66. package/dist/components/Forum/DiscussionThread.js +73 -72
  67. package/dist/components/Forum/DiscussionThread.js.map +1 -1
  68. package/dist/components/FullTextSearch/FullTextSearch.d.ts.map +1 -1
  69. package/dist/components/FullTextSearch/FullTextSearch.js +86 -47
  70. package/dist/components/FullTextSearch/FullTextSearch.js.map +1 -1
  71. package/dist/components/GenericCard/BioregistryRules.d.ts.map +1 -1
  72. package/dist/components/GenericCard/BioregistryRules.js +7 -3
  73. package/dist/components/GenericCard/BioregistryRules.js.map +1 -1
  74. package/dist/components/GenericCard/TableRowGenericCard.d.ts.map +1 -1
  75. package/dist/components/GenericCard/TableRowGenericCard.js +157 -157
  76. package/dist/components/GenericCard/TableRowGenericCard.js.map +1 -1
  77. package/dist/components/HeaderCard.d.ts.map +1 -1
  78. package/dist/components/HeaderCard.js +131 -130
  79. package/dist/components/HeaderCard.js.map +1 -1
  80. package/dist/components/IconSvg/IconSvg.d.ts.map +1 -1
  81. package/dist/components/IconSvg/IconSvg.js +2 -1
  82. package/dist/components/IconSvg/IconSvg.js.map +1 -1
  83. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.d.ts +4 -1
  84. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.d.ts.map +1 -1
  85. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.js +3 -2
  86. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.js.map +1 -1
  87. package/dist/components/QueryContext/QueryContext.d.ts +6 -0
  88. package/dist/components/QueryContext/QueryContext.d.ts.map +1 -1
  89. package/dist/components/QueryContext/QueryContext.js.map +1 -1
  90. package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.d.ts.map +1 -1
  91. package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.js +12 -11
  92. package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.js.map +1 -1
  93. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts +5 -0
  94. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts.map +1 -1
  95. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js +32 -29
  96. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js.map +1 -1
  97. package/dist/components/QueryWrapperPlotNav/UseRowSet.d.ts.map +1 -1
  98. package/dist/components/QueryWrapperPlotNav/UseRowSet.js +4 -1
  99. package/dist/components/QueryWrapperPlotNav/UseRowSet.js.map +1 -1
  100. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts +59 -0
  101. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts.map +1 -0
  102. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js +174 -0
  103. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js.map +1 -0
  104. package/dist/components/SearchQueryWrapper/SearchQueryWrapper.d.ts +40 -0
  105. package/dist/components/SearchQueryWrapper/SearchQueryWrapper.d.ts.map +1 -0
  106. package/dist/components/SearchQueryWrapper/SearchQueryWrapper.js +100 -0
  107. package/dist/components/SearchQueryWrapper/SearchQueryWrapper.js.map +1 -0
  108. package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.d.ts +56 -0
  109. package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.d.ts.map +1 -0
  110. package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.js +73 -0
  111. package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.js.map +1 -0
  112. package/dist/components/ShareThisPage/ShareThisPage.js +1 -1
  113. package/dist/components/ShareThisPage/ShareThisPage.js.map +1 -1
  114. package/dist/components/SynapseChat/GridAgentChat.d.ts.map +1 -1
  115. package/dist/components/SynapseChat/GridAgentChat.js +20 -14
  116. package/dist/components/SynapseChat/GridAgentChat.js.map +1 -1
  117. package/dist/components/SynapseChat/SynapseChat.d.ts +3 -1
  118. package/dist/components/SynapseChat/SynapseChat.d.ts.map +1 -1
  119. package/dist/components/SynapseChat/SynapseChat.js +51 -36
  120. package/dist/components/SynapseChat/SynapseChat.js.map +1 -1
  121. package/dist/components/SynapseHomepageV2/HotdropsAndNews.css +1 -1
  122. package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.js +8 -7
  123. package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.js.map +1 -1
  124. package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.scss +16 -0
  125. package/dist/components/SynapseHomepageV2/WordPressNews.d.ts +3 -1
  126. package/dist/components/SynapseHomepageV2/WordPressNews.d.ts.map +1 -1
  127. package/dist/components/SynapseHomepageV2/WordPressNews.js +9 -8
  128. package/dist/components/SynapseHomepageV2/WordPressNews.js.map +1 -1
  129. package/dist/components/SynapseHomepageV2/WordPressNewsItem.d.ts +2 -1
  130. package/dist/components/SynapseHomepageV2/WordPressNewsItem.d.ts.map +1 -1
  131. package/dist/components/SynapseHomepageV2/WordPressNewsItem.js +2 -2
  132. package/dist/components/SynapseHomepageV2/WordPressNewsItem.js.map +1 -1
  133. package/dist/components/SynapseTable/SearchV2.d.ts +7 -0
  134. package/dist/components/SynapseTable/SearchV2.d.ts.map +1 -1
  135. package/dist/components/SynapseTable/SearchV2.js.map +1 -1
  136. package/dist/components/SynapseTable/SynapseTableRenderers.d.ts.map +1 -1
  137. package/dist/components/SynapseTable/SynapseTableRenderers.js +1 -1
  138. package/dist/components/SynapseTable/SynapseTableRenderers.js.map +1 -1
  139. package/dist/components/SynapseTable/usePrefetchTableData.d.ts.map +1 -1
  140. package/dist/components/SynapseTable/usePrefetchTableData.js +6 -5
  141. package/dist/components/SynapseTable/usePrefetchTableData.js.map +1 -1
  142. package/dist/components/ToastMessage/ToastMessage.d.ts +1 -1
  143. package/dist/components/ToastMessage/ToastMessage.d.ts.map +1 -1
  144. package/dist/components/ToastMessage/ToastMessage.js +2 -2
  145. package/dist/components/ToastMessage/ToastMessage.js.map +1 -1
  146. package/dist/components/dataaccess/SubmissionPage/SubmissionPage.d.ts.map +1 -1
  147. package/dist/components/dataaccess/SubmissionPage/SubmissionPage.js +157 -148
  148. package/dist/components/dataaccess/SubmissionPage/SubmissionPage.js.map +1 -1
  149. package/dist/components/doi/CreateOrUpdateDoiModal.d.ts.map +1 -1
  150. package/dist/components/doi/CreateOrUpdateDoiModal.js +20 -19
  151. package/dist/components/doi/CreateOrUpdateDoiModal.js.map +1 -1
  152. package/dist/components/error/ErrorPage.d.ts +0 -4
  153. package/dist/components/error/ErrorPage.d.ts.map +1 -1
  154. package/dist/components/error/ErrorPage.js +25 -30
  155. package/dist/components/error/ErrorPage.js.map +1 -1
  156. package/dist/components/index.d.ts +4 -0
  157. package/dist/components/index.d.ts.map +1 -1
  158. package/dist/components/index.js +41 -39
  159. package/dist/components/widgets/query-filter/FacetFilterControls.d.ts.map +1 -1
  160. package/dist/components/widgets/query-filter/FacetFilterControls.js +2 -2
  161. package/dist/components/widgets/query-filter/FacetFilterControls.js.map +1 -1
  162. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.d.ts.map +1 -1
  163. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js +1 -1
  164. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js.map +1 -1
  165. package/dist/index.js +52 -50
  166. package/dist/index.js.map +1 -1
  167. package/dist/mocks/entity/index.d.ts.map +1 -1
  168. package/dist/mocks/entity/index.js +18 -16
  169. package/dist/mocks/entity/index.js.map +1 -1
  170. package/dist/mocks/mockSearchQueryData.d.ts +14 -0
  171. package/dist/mocks/mockSearchQueryData.d.ts.map +1 -0
  172. package/dist/mocks/mockSearchQueryData.js +564 -0
  173. package/dist/mocks/mockSearchQueryData.js.map +1 -0
  174. package/dist/mocks/msw/handlers/searchQueryHandlers.d.ts +22 -0
  175. package/dist/mocks/msw/handlers/searchQueryHandlers.d.ts.map +1 -0
  176. package/dist/mocks/msw/handlers/searchQueryHandlers.js +63 -0
  177. package/dist/mocks/msw/handlers/searchQueryHandlers.js.map +1 -0
  178. package/dist/mocks/msw/handlers.d.ts.map +1 -1
  179. package/dist/mocks/msw/handlers.js +9 -7
  180. package/dist/mocks/msw/handlers.js.map +1 -1
  181. package/dist/style/components/_cards.scss +15 -0
  182. package/dist/style/main.css +1 -1
  183. package/dist/synapse-client/SynapseClient.d.ts +7 -1
  184. package/dist/synapse-client/SynapseClient.d.ts.map +1 -1
  185. package/dist/synapse-client/SynapseClient.js +422 -417
  186. package/dist/synapse-client/SynapseClient.js.map +1 -1
  187. package/dist/synapse-client/index.js +3 -3
  188. package/dist/synapse-queries/KeyFactory.d.ts +3 -0
  189. package/dist/synapse-queries/KeyFactory.d.ts.map +1 -1
  190. package/dist/synapse-queries/KeyFactory.js +6 -0
  191. package/dist/synapse-queries/KeyFactory.js.map +1 -1
  192. package/dist/synapse-queries/forum/useThread.d.ts +1 -0
  193. package/dist/synapse-queries/forum/useThread.d.ts.map +1 -1
  194. package/dist/synapse-queries/forum/useThread.js +19 -12
  195. package/dist/synapse-queries/forum/useThread.js.map +1 -1
  196. package/dist/tsconfig.build.tsbuildinfo +1 -1
  197. package/dist/utils/APIConstants.d.ts +3 -0
  198. package/dist/utils/APIConstants.d.ts.map +1 -1
  199. package/dist/utils/APIConstants.js +2 -2
  200. package/dist/utils/APIConstants.js.map +1 -1
  201. package/dist/utils/AppUtils/session/ApplicationSessionManager.d.ts.map +1 -1
  202. package/dist/utils/AppUtils/session/ApplicationSessionManager.js +7 -4
  203. package/dist/utils/AppUtils/session/ApplicationSessionManager.js.map +1 -1
  204. package/dist/utils/functions/EntityTypeUtils.d.ts.map +1 -1
  205. package/dist/utils/functions/EntityTypeUtils.js +15 -4
  206. package/dist/utils/functions/EntityTypeUtils.js.map +1 -1
  207. package/dist/utils/functions/calculateFriendlyFileSize.d.ts.map +1 -1
  208. package/dist/utils/functions/calculateFriendlyFileSize.js +3 -3
  209. package/dist/utils/functions/calculateFriendlyFileSize.js.map +1 -1
  210. package/package.json +3 -3
@@ -9,10 +9,10 @@ import { WarningDialog as a } from "../SynapseForm/WarningDialog.js";
9
9
  import { formatDate as o } from "../../utils/functions/DateFormatter.js";
10
10
  import { UserBadge as s } from "../UserCard/UserBadge.js";
11
11
  import { useGetRepliesInfinite as c } from "../../synapse-queries/forum/useReply.js";
12
- import { useDeleteThread as te, useGetThread as ne, useRestoreThread as re } from "../../synapse-queries/forum/useThread.js";
13
- import { useSubscription as ie } from "../../synapse-queries/subscription/useSubscription.js";
14
- import { ForumThreadEditor as l } from "./ForumThreadEditor.js";
15
- import { REPLY_ID_PARAM_KEY as u } from "./DiscussionConstants.js";
12
+ import { useDeleteThread as l, useGetThread as te, useRestoreThread as ne } from "../../synapse-queries/forum/useThread.js";
13
+ import { useSubscription as re } from "../../synapse-queries/subscription/useSubscription.js";
14
+ import { ForumThreadEditor as u } from "./ForumThreadEditor.js";
15
+ import { REPLY_ID_PARAM_KEY as ie } from "./DiscussionConstants.js";
16
16
  import { DiscussionReply as d } from "./DiscussionReply.js";
17
17
  import { SubscribersModal as f } from "./SubscribersModal.js";
18
18
  import { useGetModerators as p } from "../../synapse-queries/forum/useForum.js";
@@ -25,68 +25,70 @@ import se from "dayjs";
25
25
  //#region src/components/Forum/DiscussionThread.tsx
26
26
  var ce = "You are following this topic. Click to stop following.", le = "You are not following this topic. Click to follow.", D = "Write a reply...";
27
27
  function O(O) {
28
- let { threadId: k, limit: A } = O, j = "16px", [M, N] = g(!0), [P, F] = g(!1), [I, L] = g(!1), [R, z] = g(!1), [B, V] = g(!1), [H, U] = g(!1), [W, G] = g(!1), [ue, de] = g(!1), { threadData: K, threadBody: q, togglePin: fe } = ne(k), { data: J } = r(), { data: pe } = n(K?.projectId ?? "", void 0, ae, { enabled: !!K }), { subscription: Y, toggleSubscribed: me, isLoading: he } = ie(k, E.THREAD), { mutate: ge } = te({ onSuccess: () => {
29
- V(!1), e("A thread has been deleted.", "info");
30
- } }), { mutate: _e } = re({ onSuccess: () => {
28
+ let { threadId: k, limit: A, emptyBodyContent: j } = O, M = "16px", [N, P] = g(!0), [F, I] = g(!1), [L, R] = g(!1), [z, B] = g(!1), [V, H] = g(!1), [U, W] = g(!1), [ue, G] = g(!1), [de, fe] = g(!1), { threadData: K, threadBody: q, togglePin: pe } = te(k), { data: J } = r(), { data: me } = n(K?.projectId ?? "", void 0, ae, { enabled: !!K }), { subscription: Y, toggleSubscribed: he, isLoading: ge } = re(k, E.THREAD), { mutate: _e } = l({ onSuccess: () => {
29
+ H(!1), e("A thread has been deleted.", "info");
30
+ } }), { mutate: ve } = ne({ onSuccess: () => {
31
31
  G(!1), e("A thread has been restored.", "info");
32
- } }), ve = K?.createdBy == J?.ownerId;
33
- function ye() {
34
- if (J?.userName == "anonymous") U(!0);
32
+ } }), ye = K?.createdBy == J?.ownerId;
33
+ function be() {
34
+ if (J?.userName == "anonymous") W(!0);
35
35
  else try {
36
- me();
36
+ he();
37
37
  } catch (t) {
38
38
  e(t.reason, "danger");
39
39
  }
40
40
  }
41
- let { data: X, hasNextPage: be, fetchNextPage: xe } = c(k, M, A), { data: Z } = p(K?.forumId ?? "", { enabled: !!K?.forumId }), Se = Z?.includes(K?.createdBy ?? ""), [Q, Ce] = t(u), $ = h(() => {
41
+ let { data: X, hasNextPage: xe, fetchNextPage: Se } = c(k, N, A), { data: Z } = p(K?.forumId ?? "", { enabled: !!K?.forumId }), Ce = Z?.includes(K?.createdBy ?? ""), [Q, we] = t(ie), $ = h(() => {
42
42
  let e = X?.pages.flatMap((e) => e.results) ?? [];
43
43
  return Q ? e.filter((e) => e.id === Q) : e;
44
- }, [X, Q]);
44
+ }, [X, Q]), Te = () => {
45
+ we(null);
46
+ }, Ee = Z?.includes(J?.ownerId ?? "");
45
47
  return /* @__PURE__ */ T("div", {
46
48
  className: "DiscussionThread",
47
49
  role: "article",
48
50
  children: [
49
- K && q ? /* @__PURE__ */ T(C, { children: [
50
- /* @__PURE__ */ T(_, {
51
- sx: {
52
- mb: 2,
53
- textAlign: "right"
54
- },
55
- children: [/* @__PURE__ */ w(S, {
56
- component: "span",
57
- sx: { mr: 1 },
58
- children: "Sort:"
59
- }), /* @__PURE__ */ T(x, {
60
- color: "primary",
61
- exclusive: !0,
62
- value: M ? "datePosted" : "mostRecent",
63
- children: [/* @__PURE__ */ w(b, {
64
- value: "datePosted",
65
- onClick: () => N(!0),
66
- children: "Date Posted"
67
- }), /* @__PURE__ */ w(b, {
68
- value: "mostRecent",
69
- onClick: () => N(!1),
70
- children: "Most Recent"
71
- })]
51
+ K && /* @__PURE__ */ T(_, {
52
+ sx: {
53
+ mb: 2,
54
+ textAlign: "right"
55
+ },
56
+ children: [/* @__PURE__ */ w(S, {
57
+ component: "span",
58
+ sx: { mr: 1 },
59
+ children: "Sort:"
60
+ }), /* @__PURE__ */ T(x, {
61
+ color: "primary",
62
+ exclusive: !0,
63
+ value: N ? "datePosted" : "mostRecent",
64
+ children: [/* @__PURE__ */ w(b, {
65
+ value: "datePosted",
66
+ onClick: () => P(!0),
67
+ children: "Date Posted"
68
+ }), /* @__PURE__ */ w(b, {
69
+ value: "mostRecent",
70
+ onClick: () => P(!1),
71
+ children: "Most Recent"
72
72
  })]
73
- }),
73
+ })]
74
+ }),
75
+ K && (q !== void 0 || j) ? /* @__PURE__ */ T(C, { children: [
74
76
  /* @__PURE__ */ w(s, {
75
77
  userId: K.createdBy,
76
78
  withAvatar: !0,
77
79
  avatarSize: "MEDIUM",
78
80
  showCardOnHover: !0,
79
- showModeratorBadge: Se
81
+ showModeratorBadge: Ce
80
82
  }),
81
83
  /* @__PURE__ */ T(_, {
82
84
  sx: (e) => ({ [e.breakpoints.down("sm")]: {
83
85
  display: "flex",
84
86
  flexDirection: "column-reverse",
85
- marginBottom: j,
86
- marginTop: j,
87
+ marginBottom: M,
88
+ marginTop: M,
87
89
  ".SubscribersModal": {
88
90
  justifyContent: "flex-start",
89
- marginBottom: j
91
+ marginBottom: M
90
92
  }
91
93
  } }),
92
94
  children: [/* @__PURE__ */ w(S, {
@@ -96,12 +98,12 @@ function O(O) {
96
98
  }), /* @__PURE__ */ w(f, {
97
99
  id: k,
98
100
  objectType: E.THREAD,
99
- showModal: ue,
100
- handleModal: de
101
+ showModal: de,
102
+ handleModal: fe
101
103
  })]
102
104
  }),
103
105
  /* @__PURE__ */ w("div", { children: /* @__PURE__ */ w(ee, {
104
- markdown: q,
106
+ markdown: q || j,
105
107
  objectType: oe.THREAD
106
108
  }) }),
107
109
  /* @__PURE__ */ T("span", { children: [
@@ -109,14 +111,14 @@ function O(O) {
109
111
  o(se(K.createdOn), "M/D/YYYY"),
110
112
  K.isEdited ? /* @__PURE__ */ w("i", { children: " (Edited)" }) : null
111
113
  ] }),
112
- /* @__PURE__ */ w(l, {
114
+ /* @__PURE__ */ w(u, {
113
115
  isReply: !1,
114
116
  initialText: q,
115
- onClose: () => F(!1),
117
+ onClose: () => I(!1),
116
118
  initialTitle: K?.title,
117
119
  id: k,
118
120
  isDialog: !0,
119
- openDialog: P
121
+ openDialog: F
120
122
  })
121
123
  ] }) : /* @__PURE__ */ w(C, {}),
122
124
  /* @__PURE__ */ w(_, {
@@ -137,8 +139,8 @@ function O(O) {
137
139
  /* @__PURE__ */ w("span", { children: /* @__PURE__ */ w("button", {
138
140
  className: "follow-button",
139
141
  "aria-label": Y ? "Unfollow thread" : "Follow thread",
140
- disabled: he,
141
- onClick: () => ye(),
142
+ disabled: ge,
143
+ onClick: () => be(),
142
144
  children: Y ? /* @__PURE__ */ w(i, {
143
145
  icon: "visibility",
144
146
  label: ce
@@ -147,21 +149,21 @@ function O(O) {
147
149
  label: le
148
150
  })
149
151
  }) }),
150
- ve && /* @__PURE__ */ w("button", {
151
- onClick: () => F(!0),
152
+ ye && /* @__PURE__ */ w("button", {
153
+ onClick: () => I(!0),
152
154
  children: /* @__PURE__ */ w(i, {
153
155
  icon: "edit",
154
156
  label: "Edit thread"
155
157
  })
156
158
  }),
157
- pe?.permissions.canModerate ? /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ w("button", {
158
- onClick: () => V(!0),
159
+ me?.permissions.canModerate ? /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ w("button", {
160
+ onClick: () => H(!0),
159
161
  children: /* @__PURE__ */ w(i, {
160
162
  icon: "delete",
161
163
  label: "Delete thread"
162
164
  })
163
165
  }), /* @__PURE__ */ w("button", {
164
- onClick: () => fe(),
166
+ onClick: () => pe(),
165
167
  children: K?.isPinned ? /* @__PURE__ */ w(i, {
166
168
  icon: "pushpin",
167
169
  sx: { color: "error.main" },
@@ -178,24 +180,22 @@ function O(O) {
178
180
  mt: 2,
179
181
  mb: 3
180
182
  },
181
- children: I ? /* @__PURE__ */ w(l, {
183
+ children: L ? /* @__PURE__ */ w(u, {
182
184
  id: k,
183
185
  isReply: !0,
184
- onClose: () => L(!1),
186
+ onClose: () => R(!1),
185
187
  isDialog: !1
186
188
  }) : /* @__PURE__ */ w(y, {
187
189
  fullWidth: !0,
188
190
  placeholder: D,
189
191
  onClick: () => {
190
- J?.userName == "anonymous" ? U(!0) : L(!0);
192
+ J?.userName == "anonymous" ? W(!0) : R(!0);
191
193
  }
192
194
  })
193
195
  }),
194
196
  Q && /* @__PURE__ */ T(v, {
195
197
  variant: "outlined",
196
- onClick: () => {
197
- Ce(null);
198
- },
198
+ onClick: Te,
199
199
  sx: {
200
200
  display: "flex",
201
201
  alignItems: "center",
@@ -215,6 +215,7 @@ function O(O) {
215
215
  let t = Z?.includes(e.createdBy);
216
216
  return /* @__PURE__ */ w(d, {
217
217
  reply: e,
218
+ isForumModerator: Ee,
218
219
  isReplyAuthorModerator: t
219
220
  }, e.id);
220
221
  }) }),
@@ -224,47 +225,47 @@ function O(O) {
224
225
  mb: 3,
225
226
  [e.breakpoints.down("sm")]: { MarkdownEditor: { display: "block" } }
226
227
  }),
227
- children: R ? /* @__PURE__ */ w(l, {
228
+ children: z ? /* @__PURE__ */ w(u, {
228
229
  id: k,
229
230
  isReply: !0,
230
- onClose: () => z(!1),
231
+ onClose: () => B(!1),
231
232
  isDialog: !1
232
233
  }) : /* @__PURE__ */ w(y, {
233
234
  fullWidth: !0,
234
235
  placeholder: D,
235
236
  onClick: () => {
236
- J?.userName == "anonymous" ? U(!0) : z(!0);
237
+ J?.userName == "anonymous" ? W(!0) : B(!0);
237
238
  }
238
239
  })
239
240
  }),
240
- be ? /* @__PURE__ */ w(v, {
241
+ xe ? /* @__PURE__ */ w(v, {
241
242
  variant: "outlined",
242
243
  onClick: () => {
243
- xe();
244
+ Se();
244
245
  },
245
246
  children: "Show more results"
246
247
  }) : /* @__PURE__ */ w(C, {}),
247
248
  /* @__PURE__ */ w(a, {
248
- open: B,
249
+ open: V,
249
250
  title: "Confirm Deletion",
250
251
  content: "Are you sure you want to delete this thread?",
251
- onCancel: () => V(!1),
252
- onConfirm: () => K && ge(K),
252
+ onCancel: () => H(!1),
253
+ onConfirm: () => K && _e(K),
253
254
  confirmButtonColor: "error",
254
255
  confirmButtonText: "Delete"
255
256
  }),
256
257
  /* @__PURE__ */ w(a, {
257
- open: W,
258
+ open: ue,
258
259
  title: "Confirm Restoration",
259
260
  content: "Are you sure you want to restore this thread?",
260
261
  onCancel: () => G(!1),
261
- onConfirm: () => K && _e(K),
262
+ onConfirm: () => K && ve(K),
262
263
  confirmButtonColor: "info",
263
264
  confirmButtonText: "Restore"
264
265
  }),
265
266
  /* @__PURE__ */ w(m, {
266
- open: H,
267
- onHide: () => U(!1),
267
+ open: U,
268
+ onHide: () => W(!1),
268
269
  hasCancelButton: !1
269
270
  })
270
271
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"DiscussionThread.js","names":[],"sources":["../../../src/components/Forum/DiscussionThread.tsx"],"sourcesContent":["import { useGetCurrentUserProfile, useGetEntityBundle } from '@/synapse-queries'\nimport { useGetRepliesInfinite } from '@/synapse-queries/forum/useReply'\nimport {\n useDeleteThread,\n useGetThread,\n useRestoreThread,\n} from '@/synapse-queries/forum/useThread'\nimport { useSubscription } from '@/synapse-queries/subscription/useSubscription'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport {\n Box,\n Button,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n Typography,\n} from '@mui/material'\nimport {\n ALL_ENTITY_BUNDLE_FIELDS,\n ObjectType,\n SubscriptionObjectType,\n} from '@sage-bionetworks/synapse-types'\nimport dayjs from 'dayjs'\nimport { useMemo, useState } from 'react'\nimport IconSvg from '../IconSvg/IconSvg'\nimport MarkdownSynapse from '../Markdown/MarkdownSynapse'\nimport WarningDialog from '../SynapseForm/WarningDialog'\nimport { displayToast } from '../ToastMessage/ToastMessage'\nimport { UserBadge } from '../UserCard/UserBadge'\nimport { DiscussionReply } from './DiscussionReply'\nimport { ForumThreadEditor } from './ForumThreadEditor'\nimport { SubscribersModal } from './SubscribersModal'\nimport { useGetModerators } from '@/synapse-queries/forum/useForum'\nimport { useNativeSearchParams } from '@/utils/hooks/useNativeSearchParams'\nimport { REPLY_ID_PARAM_KEY } from './DiscussionConstants'\nimport { SignInRequiredModal } from '../SignInRequiredModal/SignInRequiredModal'\n\nexport type DiscussionThreadProps = {\n threadId: string\n limit: number\n}\n\nconst FOLLOWING_TEXT = 'You are following this topic. Click to stop following.'\nconst UNFOLLOWING_TEXT = 'You are not following this topic. Click to follow.'\nconst INPUT_PLACEHOLDER = 'Write a reply...'\n\nexport function DiscussionThread(props: DiscussionThreadProps) {\n const { threadId, limit } = props\n const defaultMargin = '16px'\n\n const [orderByDatePosted, setOrderByDatePosted] = useState(true)\n const [showThreadModal, setShowThreadModal] = useState(false)\n const [showReplyEditor1, setShowReplyEditor1] = useState(false)\n const [showReplyEditor2, setShowReplyEditor2] = useState(false)\n const [showDeleteModal, setShowDeleteModal] = useState(false)\n const [showSignInModal, setShowSignInModal] = useState(false)\n const [showRestoreModal, setShowRestoreModal] = useState(false)\n const [showSubscriberModal, setShowSubscriberModal] = useState(false)\n\n const { threadData, threadBody, togglePin } = useGetThread(threadId)\n const { data: currentUserProfile } = useGetCurrentUserProfile()\n const { data: entityBundle } = useGetEntityBundle(\n threadData?.projectId ?? '',\n undefined,\n ALL_ENTITY_BUNDLE_FIELDS,\n {\n enabled: !!threadData,\n },\n )\n\n const { subscription, toggleSubscribed, isLoading } = useSubscription(\n threadId,\n SubscriptionObjectType.THREAD,\n )\n const { mutate: deleteThread } = useDeleteThread({\n onSuccess: () => {\n setShowDeleteModal(false)\n displayToast('A thread has been deleted.', 'info')\n },\n })\n const { mutate: restoreThread } = useRestoreThread({\n onSuccess: () => {\n setShowRestoreModal(false)\n displayToast('A thread has been restored.', 'info')\n },\n })\n\n const isCurrentUserAuthor =\n threadData?.createdBy == currentUserProfile?.ownerId\n\n function handleFollowBtn() {\n if (currentUserProfile?.userName == 'anonymous') {\n setShowSignInModal(true)\n } else {\n try {\n toggleSubscribed()\n } catch (err: any) {\n displayToast(err.reason as string, 'danger')\n }\n }\n }\n\n const {\n data: replyData,\n hasNextPage,\n fetchNextPage,\n } = useGetRepliesInfinite(threadId, orderByDatePosted, limit)\n\n const { data: moderatorList } = useGetModerators(threadData?.forumId ?? '', {\n enabled: Boolean(threadData?.forumId),\n })\n\n const isAuthorModerator = moderatorList?.includes(threadData?.createdBy ?? '')\n\n const [replyId, setReplyIdParam] = useNativeSearchParams(REPLY_ID_PARAM_KEY)\n\n const replies = useMemo(() => {\n const allReplies = replyData?.pages.flatMap(page => page.results) ?? []\n if (replyId) {\n return allReplies.filter(reply => reply.id === replyId)\n } else {\n return allReplies\n }\n }, [replyData, replyId])\n\n const handleShowAllRepliesButton = () => {\n setReplyIdParam(null)\n }\n\n return (\n <div className=\"DiscussionThread\" role={'article'}>\n {threadData && threadBody ? (\n <>\n <Box sx={{ mb: 2, textAlign: 'right' }}>\n <Typography component={'span'} sx={{ mr: 1 }}>\n Sort:\n </Typography>\n <ToggleButtonGroup\n color={'primary'}\n exclusive\n value={orderByDatePosted ? 'datePosted' : 'mostRecent'}\n >\n <ToggleButton\n value={'datePosted'}\n onClick={() => setOrderByDatePosted(true)}\n >\n Date Posted\n </ToggleButton>\n <ToggleButton\n value={'mostRecent'}\n onClick={() => setOrderByDatePosted(false)}\n >\n Most Recent\n </ToggleButton>\n </ToggleButtonGroup>\n </Box>\n <UserBadge\n userId={threadData.createdBy}\n withAvatar={true}\n avatarSize=\"MEDIUM\"\n showCardOnHover={true}\n showModeratorBadge={isAuthorModerator}\n />\n <Box\n sx={theme => ({\n [theme.breakpoints.down('sm')]: {\n display: 'flex',\n flexDirection: 'column-reverse',\n marginBottom: defaultMargin,\n marginTop: defaultMargin,\n '.SubscribersModal': {\n justifyContent: 'flex-start',\n marginBottom: defaultMargin,\n },\n },\n })}\n >\n <Typography sx={{ marginTop: '4px' }} variant=\"headline2\">\n {threadData.title}\n </Typography>\n <SubscribersModal\n id={threadId}\n objectType={SubscriptionObjectType.THREAD}\n showModal={showSubscriberModal}\n handleModal={setShowSubscriberModal}\n />\n </Box>\n <div>\n <MarkdownSynapse\n markdown={threadBody}\n objectType={ObjectType.THREAD}\n />\n </div>\n <span>\n posted {formatDate(dayjs(threadData.createdOn), 'M/D/YYYY')}\n {threadData.isEdited ? <i>{' (Edited)'}</i> : null}\n </span>\n <ForumThreadEditor\n isReply={false}\n initialText={threadBody}\n onClose={() => setShowThreadModal(false)}\n initialTitle={threadData?.title}\n id={threadId}\n isDialog={true}\n openDialog={showThreadModal}\n />\n </>\n ) : (\n <></>\n )}\n <Box\n sx={{\n float: 'right',\n margin: { xs: '8px 0', sm: '0 24px 0 0' },\n }}\n >\n {threadData?.isDeleted ? (\n <button onClick={() => setShowRestoreModal(true)}>\n <IconSvg icon=\"restore\" label=\"Restore deleted thread\" />\n </button>\n ) : (\n <>\n <span>\n <button\n className=\"follow-button\"\n aria-label={subscription ? 'Unfollow thread' : 'Follow thread'}\n disabled={isLoading}\n onClick={() => handleFollowBtn()}\n >\n {subscription ? (\n <IconSvg icon=\"visibility\" label={FOLLOWING_TEXT} />\n ) : (\n <IconSvg icon=\"visibilityOff\" label={UNFOLLOWING_TEXT} />\n )}\n </button>\n </span>\n {isCurrentUserAuthor && (\n <button onClick={() => setShowThreadModal(true)}>\n <IconSvg icon=\"edit\" label=\"Edit thread\" />\n </button>\n )}\n\n {entityBundle?.permissions.canModerate ? (\n <>\n <button onClick={() => setShowDeleteModal(true)}>\n <IconSvg icon=\"delete\" label=\"Delete thread\" />\n </button>\n <button onClick={() => togglePin()}>\n {threadData?.isPinned ? (\n <IconSvg\n icon=\"pushpin\"\n sx={{ color: 'error.main' }}\n label=\"Unpin thread\"\n />\n ) : (\n <IconSvg icon=\"pushpin\" label=\"Pin thread\" />\n )}\n </button>\n </>\n ) : null}\n </>\n )}\n </Box>\n <Box sx={{ mt: 2, mb: 3 }}>\n {!showReplyEditor1 ? (\n <TextField\n fullWidth\n placeholder={INPUT_PLACEHOLDER}\n onClick={() => {\n if (currentUserProfile?.userName == 'anonymous') {\n setShowSignInModal(true)\n } else {\n setShowReplyEditor1(true)\n }\n }}\n />\n ) : (\n <ForumThreadEditor\n id={threadId}\n isReply={true}\n onClose={() => setShowReplyEditor1(false)}\n isDialog={false}\n />\n )}\n </Box>\n {replyId && (\n <Button\n variant=\"outlined\"\n onClick={handleShowAllRepliesButton}\n sx={{\n display: 'flex',\n alignItems: 'center',\n padding: '2px 8px',\n marginBottom: '12px',\n gap: '4px',\n }}\n >\n <IconSvg icon=\"arrowBack\" sx={{ width: '16px' }} />\n <Typography variant=\"smallText2\">Show all replies</Typography>\n </Button>\n )}\n <div>\n {replies.map(reply => {\n const isReplyAuthorModerator = moderatorList?.includes(\n reply.createdBy,\n )\n return (\n <DiscussionReply\n key={reply.id}\n reply={reply}\n isReplyAuthorModerator={isReplyAuthorModerator}\n />\n )\n })}\n </div>\n {replies.length > 0 && (\n <Box\n sx={theme => ({\n mt: 2,\n mb: 3,\n [theme.breakpoints.down('sm')]: {\n MarkdownEditor: {\n display: 'block',\n },\n },\n })}\n >\n {!showReplyEditor2 ? (\n <TextField\n fullWidth\n placeholder={INPUT_PLACEHOLDER}\n onClick={() => {\n if (currentUserProfile?.userName == 'anonymous') {\n setShowSignInModal(true)\n } else {\n setShowReplyEditor2(true)\n }\n }}\n />\n ) : (\n <ForumThreadEditor\n id={threadId}\n isReply={true}\n onClose={() => setShowReplyEditor2(false)}\n isDialog={false}\n />\n )}\n </Box>\n )}\n\n {hasNextPage ? (\n <Button\n variant=\"outlined\"\n onClick={() => {\n fetchNextPage()\n }}\n >\n Show more results\n </Button>\n ) : (\n <></>\n )}\n <WarningDialog\n open={showDeleteModal}\n title=\"Confirm Deletion\"\n content=\"Are you sure you want to delete this thread?\"\n onCancel={() => setShowDeleteModal(false)}\n onConfirm={() => threadData && deleteThread(threadData)}\n confirmButtonColor=\"error\"\n confirmButtonText=\"Delete\"\n />\n <WarningDialog\n open={showRestoreModal}\n title=\"Confirm Restoration\"\n content=\"Are you sure you want to restore this thread?\"\n onCancel={() => setShowRestoreModal(false)}\n onConfirm={() => threadData && restoreThread(threadData)}\n confirmButtonColor=\"info\"\n confirmButtonText=\"Restore\"\n />\n <SignInRequiredModal\n open={showSignInModal}\n onHide={() => setShowSignInModal(false)}\n hasCancelButton={false}\n />\n </div>\n )\n}\n\nexport default DiscussionThread\n"],"mappings":"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"}
1
+ {"version":3,"file":"DiscussionThread.js","names":[],"sources":["../../../src/components/Forum/DiscussionThread.tsx"],"sourcesContent":["import { useGetCurrentUserProfile, useGetEntityBundle } from '@/synapse-queries'\nimport { useGetRepliesInfinite } from '@/synapse-queries/forum/useReply'\nimport {\n useDeleteThread,\n useGetThread,\n useRestoreThread,\n} from '@/synapse-queries/forum/useThread'\nimport { useSubscription } from '@/synapse-queries/subscription/useSubscription'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport {\n Box,\n Button,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n Typography,\n} from '@mui/material'\nimport {\n ALL_ENTITY_BUNDLE_FIELDS,\n ObjectType,\n SubscriptionObjectType,\n} from '@sage-bionetworks/synapse-types'\nimport dayjs from 'dayjs'\nimport { useMemo, useState } from 'react'\nimport IconSvg from '../IconSvg/IconSvg'\nimport MarkdownSynapse from '../Markdown/MarkdownSynapse'\nimport WarningDialog from '../SynapseForm/WarningDialog'\nimport { displayToast } from '../ToastMessage/ToastMessage'\nimport { UserBadge } from '../UserCard/UserBadge'\nimport { DiscussionReply } from './DiscussionReply'\nimport { ForumThreadEditor } from './ForumThreadEditor'\nimport { SubscribersModal } from './SubscribersModal'\nimport { useGetModerators } from '@/synapse-queries/forum/useForum'\nimport { useNativeSearchParams } from '@/utils/hooks/useNativeSearchParams'\nimport { REPLY_ID_PARAM_KEY } from './DiscussionConstants'\nimport { SignInRequiredModal } from '../SignInRequiredModal/SignInRequiredModal'\n\nexport type DiscussionThreadProps = {\n threadId: string\n limit: number\n emptyBodyContent?: string\n}\n\nconst FOLLOWING_TEXT = 'You are following this topic. Click to stop following.'\nconst UNFOLLOWING_TEXT = 'You are not following this topic. Click to follow.'\nconst INPUT_PLACEHOLDER = 'Write a reply...'\n\nexport function DiscussionThread(props: DiscussionThreadProps) {\n const { threadId, limit, emptyBodyContent } = props\n const defaultMargin = '16px'\n\n const [orderByDatePosted, setOrderByDatePosted] = useState(true)\n const [showThreadModal, setShowThreadModal] = useState(false)\n const [showReplyEditor1, setShowReplyEditor1] = useState(false)\n const [showReplyEditor2, setShowReplyEditor2] = useState(false)\n const [showDeleteModal, setShowDeleteModal] = useState(false)\n const [showSignInModal, setShowSignInModal] = useState(false)\n const [showRestoreModal, setShowRestoreModal] = useState(false)\n const [showSubscriberModal, setShowSubscriberModal] = useState(false)\n\n const { threadData, threadBody, togglePin } = useGetThread(threadId)\n const { data: currentUserProfile } = useGetCurrentUserProfile()\n const { data: entityBundle } = useGetEntityBundle(\n threadData?.projectId ?? '',\n undefined,\n ALL_ENTITY_BUNDLE_FIELDS,\n {\n enabled: !!threadData,\n },\n )\n\n const { subscription, toggleSubscribed, isLoading } = useSubscription(\n threadId,\n SubscriptionObjectType.THREAD,\n )\n const { mutate: deleteThread } = useDeleteThread({\n onSuccess: () => {\n setShowDeleteModal(false)\n displayToast('A thread has been deleted.', 'info')\n },\n })\n const { mutate: restoreThread } = useRestoreThread({\n onSuccess: () => {\n setShowRestoreModal(false)\n displayToast('A thread has been restored.', 'info')\n },\n })\n\n const isCurrentUserAuthor =\n threadData?.createdBy == currentUserProfile?.ownerId\n\n function handleFollowBtn() {\n if (currentUserProfile?.userName == 'anonymous') {\n setShowSignInModal(true)\n } else {\n try {\n toggleSubscribed()\n } catch (err: any) {\n displayToast(err.reason as string, 'danger')\n }\n }\n }\n\n const {\n data: replyData,\n hasNextPage,\n fetchNextPage,\n } = useGetRepliesInfinite(threadId, orderByDatePosted, limit)\n\n const { data: moderatorList } = useGetModerators(threadData?.forumId ?? '', {\n enabled: Boolean(threadData?.forumId),\n })\n\n const isAuthorModerator = moderatorList?.includes(threadData?.createdBy ?? '')\n\n const [replyId, setReplyIdParam] = useNativeSearchParams(REPLY_ID_PARAM_KEY)\n\n const replies = useMemo(() => {\n const allReplies = replyData?.pages.flatMap(page => page.results) ?? []\n if (replyId) {\n return allReplies.filter(reply => reply.id === replyId)\n } else {\n return allReplies\n }\n }, [replyData, replyId])\n\n const handleShowAllRepliesButton = () => {\n setReplyIdParam(null)\n }\n\n const isForumModerator = moderatorList?.includes(\n currentUserProfile?.ownerId ?? '',\n )\n\n return (\n <div className=\"DiscussionThread\" role={'article'}>\n {threadData && (\n <Box sx={{ mb: 2, textAlign: 'right' }}>\n <Typography component={'span'} sx={{ mr: 1 }}>\n Sort:\n </Typography>\n <ToggleButtonGroup\n color={'primary'}\n exclusive\n value={orderByDatePosted ? 'datePosted' : 'mostRecent'}\n >\n <ToggleButton\n value={'datePosted'}\n onClick={() => setOrderByDatePosted(true)}\n >\n Date Posted\n </ToggleButton>\n <ToggleButton\n value={'mostRecent'}\n onClick={() => setOrderByDatePosted(false)}\n >\n Most Recent\n </ToggleButton>\n </ToggleButtonGroup>\n </Box>\n )}\n {threadData && (threadBody !== undefined || emptyBodyContent) ? (\n <>\n <UserBadge\n userId={threadData.createdBy}\n withAvatar={true}\n avatarSize=\"MEDIUM\"\n showCardOnHover={true}\n showModeratorBadge={isAuthorModerator}\n />\n <Box\n sx={theme => ({\n [theme.breakpoints.down('sm')]: {\n display: 'flex',\n flexDirection: 'column-reverse',\n marginBottom: defaultMargin,\n marginTop: defaultMargin,\n '.SubscribersModal': {\n justifyContent: 'flex-start',\n marginBottom: defaultMargin,\n },\n },\n })}\n >\n <Typography sx={{ marginTop: '4px' }} variant=\"headline2\">\n {threadData.title}\n </Typography>\n <SubscribersModal\n id={threadId}\n objectType={SubscriptionObjectType.THREAD}\n showModal={showSubscriberModal}\n handleModal={setShowSubscriberModal}\n />\n </Box>\n <div>\n <MarkdownSynapse\n markdown={threadBody || emptyBodyContent}\n objectType={ObjectType.THREAD}\n />\n </div>\n <span>\n posted {formatDate(dayjs(threadData.createdOn), 'M/D/YYYY')}\n {threadData.isEdited ? <i>{' (Edited)'}</i> : null}\n </span>\n <ForumThreadEditor\n isReply={false}\n initialText={threadBody}\n onClose={() => setShowThreadModal(false)}\n initialTitle={threadData?.title}\n id={threadId}\n isDialog={true}\n openDialog={showThreadModal}\n />\n </>\n ) : (\n <></>\n )}\n <Box\n sx={{\n float: 'right',\n margin: { xs: '8px 0', sm: '0 24px 0 0' },\n }}\n >\n {threadData?.isDeleted ? (\n <button onClick={() => setShowRestoreModal(true)}>\n <IconSvg icon=\"restore\" label=\"Restore deleted thread\" />\n </button>\n ) : (\n <>\n <span>\n <button\n className=\"follow-button\"\n aria-label={subscription ? 'Unfollow thread' : 'Follow thread'}\n disabled={isLoading}\n onClick={() => handleFollowBtn()}\n >\n {subscription ? (\n <IconSvg icon=\"visibility\" label={FOLLOWING_TEXT} />\n ) : (\n <IconSvg icon=\"visibilityOff\" label={UNFOLLOWING_TEXT} />\n )}\n </button>\n </span>\n {isCurrentUserAuthor && (\n <button onClick={() => setShowThreadModal(true)}>\n <IconSvg icon=\"edit\" label=\"Edit thread\" />\n </button>\n )}\n\n {entityBundle?.permissions.canModerate ? (\n <>\n <button onClick={() => setShowDeleteModal(true)}>\n <IconSvg icon=\"delete\" label=\"Delete thread\" />\n </button>\n <button onClick={() => togglePin()}>\n {threadData?.isPinned ? (\n <IconSvg\n icon=\"pushpin\"\n sx={{ color: 'error.main' }}\n label=\"Unpin thread\"\n />\n ) : (\n <IconSvg icon=\"pushpin\" label=\"Pin thread\" />\n )}\n </button>\n </>\n ) : null}\n </>\n )}\n </Box>\n <Box sx={{ mt: 2, mb: 3 }}>\n {!showReplyEditor1 ? (\n <TextField\n fullWidth\n placeholder={INPUT_PLACEHOLDER}\n onClick={() => {\n if (currentUserProfile?.userName == 'anonymous') {\n setShowSignInModal(true)\n } else {\n setShowReplyEditor1(true)\n }\n }}\n />\n ) : (\n <ForumThreadEditor\n id={threadId}\n isReply={true}\n onClose={() => setShowReplyEditor1(false)}\n isDialog={false}\n />\n )}\n </Box>\n {replyId && (\n <Button\n variant=\"outlined\"\n onClick={handleShowAllRepliesButton}\n sx={{\n display: 'flex',\n alignItems: 'center',\n padding: '2px 8px',\n marginBottom: '12px',\n gap: '4px',\n }}\n >\n <IconSvg icon=\"arrowBack\" sx={{ width: '16px' }} />\n <Typography variant=\"smallText2\">Show all replies</Typography>\n </Button>\n )}\n <div>\n {replies.map(reply => {\n const isReplyAuthorModerator = moderatorList?.includes(\n reply.createdBy,\n )\n return (\n <DiscussionReply\n key={reply.id}\n reply={reply}\n isForumModerator={isForumModerator}\n isReplyAuthorModerator={isReplyAuthorModerator}\n />\n )\n })}\n </div>\n {replies.length > 0 && (\n <Box\n sx={theme => ({\n mt: 2,\n mb: 3,\n [theme.breakpoints.down('sm')]: {\n MarkdownEditor: {\n display: 'block',\n },\n },\n })}\n >\n {!showReplyEditor2 ? (\n <TextField\n fullWidth\n placeholder={INPUT_PLACEHOLDER}\n onClick={() => {\n if (currentUserProfile?.userName == 'anonymous') {\n setShowSignInModal(true)\n } else {\n setShowReplyEditor2(true)\n }\n }}\n />\n ) : (\n <ForumThreadEditor\n id={threadId}\n isReply={true}\n onClose={() => setShowReplyEditor2(false)}\n isDialog={false}\n />\n )}\n </Box>\n )}\n\n {hasNextPage ? (\n <Button\n variant=\"outlined\"\n onClick={() => {\n fetchNextPage()\n }}\n >\n Show more results\n </Button>\n ) : (\n <></>\n )}\n <WarningDialog\n open={showDeleteModal}\n title=\"Confirm Deletion\"\n content=\"Are you sure you want to delete this thread?\"\n onCancel={() => setShowDeleteModal(false)}\n onConfirm={() => threadData && deleteThread(threadData)}\n confirmButtonColor=\"error\"\n confirmButtonText=\"Delete\"\n />\n <WarningDialog\n open={showRestoreModal}\n title=\"Confirm Restoration\"\n content=\"Are you sure you want to restore this thread?\"\n onCancel={() => setShowRestoreModal(false)}\n onConfirm={() => threadData && restoreThread(threadData)}\n confirmButtonColor=\"info\"\n confirmButtonText=\"Restore\"\n />\n <SignInRequiredModal\n open={showSignInModal}\n onHide={() => setShowSignInModal(false)}\n hasCancelButton={false}\n />\n </div>\n )\n}\n\nexport default DiscussionThread\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FullTextSearch.d.ts","sourceRoot":"","sources":["../../../src/components/FullTextSearch/FullTextSearch.tsx"],"names":[],"mappings":"AACA,OAAO,KAAwD,MAAM,OAAO,CAAA;AAQ5E,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAKpD,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB,CAAA;AAED,wBAAgB,cAAc,CAAC,EAC7B,SAAS,GACV,EAAE,mBAAmB,GAAG,KAAK,CAAC,SAAS,CA2FvC;AAED,eAAe,cAAc,CAAA"}
1
+ {"version":3,"file":"FullTextSearch.d.ts","sourceRoot":"","sources":["../../../src/components/FullTextSearch/FullTextSearch.tsx"],"names":[],"mappings":"AACA,OAAO,KAMN,MAAM,OAAO,CAAA;AASd,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAMpD,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB,CAAA;AAED,wBAAgB,cAAc,CAAC,EAC7B,SAAS,GACV,EAAE,mBAAmB,GAAG,KAAK,CAAC,SAAS,CA2KvC;AAED,eAAe,cAAc,CAAA"}
@@ -1,64 +1,103 @@
1
- import { HelpPopover as e } from "../HelpPopover/HelpPopover.js";
2
- import t from "../IconSvg/IconSvg.js";
3
- import { useQueryContext as n } from "../QueryContext/QueryContext.js";
1
+ import { useDebouncedEffect as e } from "../../utils/hooks/useDebouncedEffect.js";
2
+ import "../../utils/hooks/index.js";
3
+ import { HelpPopover as t } from "../HelpPopover/HelpPopover.js";
4
+ import n from "../IconSvg/IconSvg.js";
5
+ import { useQueryContext as r } from "../QueryContext/QueryContext.js";
4
6
  import "../QueryContext/index.js";
5
- import { useGetQueryMetadata as r } from "../QueryWrapper/useGetQueryMetadata.js";
6
- import { useQueryVisualizationContext as i } from "../QueryVisualizationWrapper/QueryVisualizationContext.js";
7
+ import { useGetQueryMetadata as i } from "../QueryWrapper/useGetQueryMetadata.js";
8
+ import { useQueryVisualizationContext as a } from "../QueryVisualizationWrapper/QueryVisualizationContext.js";
7
9
  import "../QueryVisualizationWrapper/index.js";
8
- import { updateQueryUsingSearchTerm as a } from "./FullTextSearchUtils.js";
9
- import { IconSvgButton as o } from "../IconSvgButton.js";
10
- import { useRef as s, useState as c } from "react";
11
- import { Collapse as l, TextField as u } from "@mui/material";
12
- import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
10
+ import { updateQueryUsingSearchTerm as o } from "./FullTextSearchUtils.js";
11
+ import { IconSvgButton as s } from "../IconSvgButton.js";
12
+ import { useEffect as c, useRef as l, useState as u } from "react";
13
+ import { Autocomplete as d, Collapse as f, TextField as p } from "@mui/material";
14
+ import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
13
15
  //#region src/components/FullTextSearch/FullTextSearch.tsx
14
- var m = 3;
15
- function h({ ftsConfig: h }) {
16
- let { executeQueryRequest: g } = n(), { showSearchBar: _ } = i(), [v, y] = c(""), b = s(null), { data: x } = r(), S = x?.columnModels;
17
- return /* @__PURE__ */ f("div", {
16
+ var _ = 3, v = 300;
17
+ function y({ ftsConfig: y }) {
18
+ let { executeQueryRequest: b } = r(), { showSearchBar: x } = a(), [S, C] = u(""), [w, T] = u([]), E = l(null), { data: D } = i(), O = D?.columnModels;
19
+ c(() => {
20
+ (!y?.getSuggestions || S.trim().length < _) && T([]);
21
+ }, [y?.getSuggestions, S]), e(() => {
22
+ !y?.getSuggestions || S.trim().length < _ || y.getSuggestions(S).then(T).catch(() => T([]));
23
+ }, [S, y], v);
24
+ let k = (e) => {
25
+ b((t) => o(t, O, e, y)), C(""), T([]);
26
+ }, A = (e) => {
27
+ e.preventDefault(), S.trim().length < _ ? E.current?.setCustomValidity(`Search term must have a minimum of ${_} characters`) : k(S);
28
+ }, j = (e) => {
29
+ E.current?.setCustomValidity(""), C(e.currentTarget.value);
30
+ }, M = /* @__PURE__ */ h(n, {
31
+ icon: "search",
32
+ wrap: !1,
33
+ sx: {
34
+ mr: 1,
35
+ color: "grey.600"
36
+ }
37
+ }), N = /* @__PURE__ */ g(m, { children: [S.length > 0 && /* @__PURE__ */ h(s, {
38
+ icon: "close",
39
+ size: "small",
40
+ onClick: () => {
41
+ C(""), T([]);
42
+ }
43
+ }), y?.searchHelpURL && /* @__PURE__ */ h(t, {
44
+ markdownText: "This search bar is powered by MySQL Full Text Search.",
45
+ helpUrl: y.searchHelpURL,
46
+ placement: "left"
47
+ })] });
48
+ return /* @__PURE__ */ h("div", {
18
49
  className: "QueryWrapperFullTextSearchInput",
19
- children: /* @__PURE__ */ f(l, {
20
- in: _,
50
+ children: /* @__PURE__ */ h(f, {
51
+ in: x,
21
52
  timeout: {
22
53
  enter: 300,
23
54
  exit: 300
24
55
  },
25
- children: /* @__PURE__ */ f("form", {
26
- onSubmit: (e) => {
27
- e.preventDefault(), v.trim().length < m ? b.current?.setCustomValidity(`Search term must have a minimum of ${m} characters`) : (g((e) => a(e, S, v, h)), y(""));
28
- },
29
- children: /* @__PURE__ */ f(u, {
30
- sx: { width: "100%" },
31
- onChange: (e) => {
32
- b.current?.setCustomValidity(""), y(e.currentTarget.value);
56
+ children: /* @__PURE__ */ h("form", {
57
+ onSubmit: A,
58
+ children: y?.getSuggestions ? /* @__PURE__ */ h(d, {
59
+ freeSolo: !0,
60
+ disableClearable: !0,
61
+ options: w,
62
+ inputValue: S,
63
+ onInputChange: (e, t, n) => {
64
+ n === "input" && (E.current?.setCustomValidity(""), C(t));
65
+ },
66
+ onChange: (e, t) => {
67
+ typeof t == "string" && t.trim().length >= _ && k(t);
33
68
  },
69
+ renderInput: (e) => /* @__PURE__ */ h(p, {
70
+ ...e,
71
+ inputRef: E,
72
+ sx: { width: "100%" },
73
+ placeholder: "Enter Search Terms",
74
+ type: "text",
75
+ slotProps: {
76
+ input: {
77
+ ...e.InputProps,
78
+ startAdornment: M,
79
+ endAdornment: N
80
+ },
81
+ htmlInput: {
82
+ ...e.inputProps,
83
+ minLength: _
84
+ }
85
+ }
86
+ })
87
+ }) : /* @__PURE__ */ h(p, {
88
+ sx: { width: "100%" },
89
+ onChange: j,
34
90
  placeholder: "Enter Search Terms",
35
- value: v,
91
+ value: S,
36
92
  type: "text",
37
93
  slotProps: {
38
94
  input: {
39
- startAdornment: /* @__PURE__ */ f(t, {
40
- icon: "search",
41
- wrap: !1,
42
- sx: {
43
- mr: 1,
44
- color: "grey.600"
45
- }
46
- }),
47
- endAdornment: /* @__PURE__ */ p(d, { children: [v.length > 0 && /* @__PURE__ */ f(o, {
48
- icon: "close",
49
- size: "small",
50
- onClick: () => {
51
- y("");
52
- }
53
- }), /* @__PURE__ */ f(e, {
54
- markdownText: "This search bar is powered by MySQL Full Text Search.",
55
- helpUrl: h?.searchHelpURL,
56
- placement: "left"
57
- })] })
95
+ startAdornment: M,
96
+ endAdornment: N
58
97
  },
59
98
  htmlInput: {
60
- minLength: m,
61
- ref: b
99
+ minLength: _,
100
+ ref: E
62
101
  }
63
102
  }
64
103
  })
@@ -67,6 +106,6 @@ function h({ ftsConfig: h }) {
67
106
  });
68
107
  }
69
108
  //#endregion
70
- export { h as FullTextSearch, h as default };
109
+ export { y as FullTextSearch, y as default };
71
110
 
72
111
  //# sourceMappingURL=FullTextSearch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FullTextSearch.js","names":[],"sources":["../../../src/components/FullTextSearch/FullTextSearch.tsx"],"sourcesContent":["import { Collapse, TextField } from '@mui/material'\nimport React, { ChangeEvent, SyntheticEvent, useRef, useState } from 'react'\nimport { HelpPopover } from '../HelpPopover/HelpPopover'\nimport IconSvg from '../IconSvg/IconSvg'\nimport { IconSvgButton } from '../IconSvgButton'\nimport { useQueryContext } from '../QueryContext'\nimport { useQueryVisualizationContext } from '../QueryVisualizationWrapper'\nimport { useGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata'\nimport { updateQueryUsingSearchTerm } from './FullTextSearchUtils'\nimport { FTSConfig } from '../SynapseTable/SearchV2'\n\n// See PLFM-7011\nconst MIN_SEARCH_QUERY_LENGTH = 3\n\nexport type FullTextSearchProps = {\n ftsConfig?: FTSConfig\n}\n\nexport function FullTextSearch({\n ftsConfig,\n}: FullTextSearchProps): React.ReactNode {\n const { executeQueryRequest } = useQueryContext()\n const { showSearchBar } = useQueryVisualizationContext()\n const [searchText, setSearchText] = useState('')\n const searchInputRef = useRef<HTMLInputElement>(null)\n\n const { data } = useGetQueryMetadata()\n const columnModels = data?.columnModels\n\n const search = (event: SyntheticEvent<HTMLFormElement>) => {\n event.preventDefault()\n\n // The HTML validation doesn't trim the string, so we add an extra check.\n // We don't auto-trim the form text ourselves because the user may still be focused on the input.\n if (searchText.trim().length < MIN_SEARCH_QUERY_LENGTH) {\n searchInputRef.current?.setCustomValidity(\n `Search term must have a minimum of ${MIN_SEARCH_QUERY_LENGTH} characters`,\n )\n } else {\n executeQueryRequest(queryBundleRequest =>\n updateQueryUsingSearchTerm(\n queryBundleRequest,\n columnModels,\n searchText,\n ftsConfig,\n ),\n )\n // Reset the search text after adding the filter\n setSearchText('')\n }\n }\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n searchInputRef.current?.setCustomValidity('')\n setSearchText(event.currentTarget.value)\n }\n\n return (\n <div className={`QueryWrapperFullTextSearchInput`}>\n <Collapse in={showSearchBar} timeout={{ enter: 300, exit: 300 }}>\n <form onSubmit={search}>\n <TextField\n sx={{ width: '100%' }}\n onChange={handleChange}\n placeholder=\"Enter Search Terms\"\n value={searchText}\n type=\"text\"\n slotProps={{\n input: {\n startAdornment: (\n <IconSvg\n icon=\"search\"\n wrap={false}\n sx={{\n mr: 1,\n color: 'grey.600',\n }}\n />\n ),\n endAdornment: (\n <>\n {searchText.length > 0 && (\n <IconSvgButton\n icon=\"close\"\n size=\"small\"\n onClick={() => {\n setSearchText('')\n }}\n />\n )}\n <HelpPopover\n markdownText={\n 'This search bar is powered by MySQL Full Text Search.'\n }\n helpUrl={ftsConfig?.searchHelpURL}\n placement=\"left\"\n />\n </>\n ),\n },\n\n htmlInput: {\n minLength: MIN_SEARCH_QUERY_LENGTH,\n ref: searchInputRef,\n },\n }}\n />\n </form>\n </Collapse>\n </div>\n )\n}\n\nexport default FullTextSearch\n"],"mappings":";;;;;;;;;;;;;AAYA,IAAM,IAA0B;AAMhC,SAAgB,EAAe,EAC7B,gBACuC;CACvC,IAAM,EAAE,2BAAwB,GAAiB,EAC3C,EAAE,qBAAkB,GAA8B,EAClD,CAAC,GAAY,KAAiB,EAAS,GAAG,EAC1C,IAAiB,EAAyB,KAAK,EAE/C,EAAE,YAAS,GAAqB,EAChC,IAAe,GAAM;AA8B3B,QACE,kBAAC,OAAD;EAAK,WAAW;YACd,kBAAC,GAAD;GAAU,IAAI;GAAe,SAAS;IAAE,OAAO;IAAK,MAAM;IAAK;aAC7D,kBAAC,QAAD;IAAM,WA/BI,MAA2C;AAKzD,KAJA,EAAM,gBAAgB,EAIlB,EAAW,MAAM,CAAC,SAAS,IAC7B,EAAe,SAAS,kBACtB,sCAAsC,EAAwB,aAC/D,IAED,GAAoB,MAClB,EACE,GACA,GACA,GACA,EACD,CACF,EAED,EAAc,GAAG;;cAab,kBAAC,GAAD;KACE,IAAI,EAAE,OAAO,QAAQ;KACrB,WAXY,MAAyC;AAE7D,MADA,EAAe,SAAS,kBAAkB,GAAG,EAC7C,EAAc,EAAM,cAAc,MAAM;;KAUhC,aAAY;KACZ,OAAO;KACP,MAAK;KACL,WAAW;MACT,OAAO;OACL,gBACE,kBAAC,GAAD;QACE,MAAK;QACL,MAAM;QACN,IAAI;SACF,IAAI;SACJ,OAAO;SACR;QACD,CAAA;OAEJ,cACE,kBAAA,GAAA,EAAA,UAAA,CACG,EAAW,SAAS,KACnB,kBAAC,GAAD;QACE,MAAK;QACL,MAAK;QACL,eAAe;AACb,WAAc,GAAG;;QAEnB,CAAA,EAEJ,kBAAC,GAAD;QACE,cACE;QAEF,SAAS,GAAW;QACpB,WAAU;QACV,CAAA,CACD,EAAA,CAAA;OAEN;MAED,WAAW;OACT,WAAW;OACX,KAAK;OACN;MACF;KACD,CAAA;IACG,CAAA;GACE,CAAA;EACP,CAAA"}
1
+ {"version":3,"file":"FullTextSearch.js","names":[],"sources":["../../../src/components/FullTextSearch/FullTextSearch.tsx"],"sourcesContent":["import { Autocomplete, Collapse, TextField } from '@mui/material'\nimport React, {\n ChangeEvent,\n SyntheticEvent,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport { useDebouncedEffect } from '@/utils/hooks'\nimport { HelpPopover } from '../HelpPopover/HelpPopover'\nimport IconSvg from '../IconSvg/IconSvg'\nimport { IconSvgButton } from '../IconSvgButton'\nimport { useQueryContext } from '../QueryContext'\nimport { useQueryVisualizationContext } from '../QueryVisualizationWrapper'\nimport { useGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata'\nimport { updateQueryUsingSearchTerm } from './FullTextSearchUtils'\nimport { FTSConfig } from '../SynapseTable/SearchV2'\n\n// See PLFM-7011\nconst MIN_SEARCH_QUERY_LENGTH = 3\nconst SUGGESTION_DEBOUNCE_MS = 300\n\nexport type FullTextSearchProps = {\n ftsConfig?: FTSConfig\n}\n\nexport function FullTextSearch({\n ftsConfig,\n}: FullTextSearchProps): React.ReactNode {\n const { executeQueryRequest } = useQueryContext()\n const { showSearchBar } = useQueryVisualizationContext()\n const [searchText, setSearchText] = useState('')\n const [suggestions, setSuggestions] = useState<string[]>([])\n const searchInputRef = useRef<HTMLInputElement>(null)\n\n const { data } = useGetQueryMetadata()\n const columnModels = data?.columnModels\n\n // Clear suggestions immediately when the search text is too short\n useEffect(() => {\n if (\n !ftsConfig?.getSuggestions ||\n searchText.trim().length < MIN_SEARCH_QUERY_LENGTH\n ) {\n setSuggestions([])\n }\n }, [ftsConfig?.getSuggestions, searchText])\n\n // Fetch autocomplete suggestions whenever searchText changes (debounced)\n useDebouncedEffect(\n () => {\n if (\n !ftsConfig?.getSuggestions ||\n searchText.trim().length < MIN_SEARCH_QUERY_LENGTH\n ) {\n return\n }\n ftsConfig\n .getSuggestions(searchText)\n .then(setSuggestions)\n .catch(() => setSuggestions([]))\n },\n [searchText, ftsConfig],\n SUGGESTION_DEBOUNCE_MS,\n )\n\n const executeSearch = (text: string) => {\n executeQueryRequest(queryBundleRequest =>\n updateQueryUsingSearchTerm(\n queryBundleRequest,\n columnModels,\n text,\n ftsConfig,\n ),\n )\n setSearchText('')\n setSuggestions([])\n }\n\n const search = (event: SyntheticEvent<HTMLFormElement>) => {\n event.preventDefault()\n\n // The HTML validation doesn't trim the string, so we add an extra check.\n // We don't auto-trim the form text ourselves because the user may still be focused on the input.\n if (searchText.trim().length < MIN_SEARCH_QUERY_LENGTH) {\n searchInputRef.current?.setCustomValidity(\n `Search term must have a minimum of ${MIN_SEARCH_QUERY_LENGTH} characters`,\n )\n } else {\n executeSearch(searchText)\n }\n }\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n searchInputRef.current?.setCustomValidity('')\n setSearchText(event.currentTarget.value)\n }\n\n const startAdornment = (\n <IconSvg\n icon=\"search\"\n wrap={false}\n sx={{\n mr: 1,\n color: 'grey.600',\n }}\n />\n )\n\n const endAdornment = (\n <>\n {searchText.length > 0 && (\n <IconSvgButton\n icon=\"close\"\n size=\"small\"\n onClick={() => {\n setSearchText('')\n setSuggestions([])\n }}\n />\n )}\n {ftsConfig?.searchHelpURL && (\n <HelpPopover\n markdownText={'This search bar is powered by MySQL Full Text Search.'}\n helpUrl={ftsConfig.searchHelpURL}\n placement=\"left\"\n />\n )}\n </>\n )\n\n return (\n <div className={`QueryWrapperFullTextSearchInput`}>\n <Collapse in={showSearchBar} timeout={{ enter: 300, exit: 300 }}>\n <form onSubmit={search}>\n {ftsConfig?.getSuggestions ? (\n <Autocomplete\n freeSolo\n disableClearable\n options={suggestions}\n inputValue={searchText}\n onInputChange={(_, newValue, reason) => {\n if (reason !== 'input') return\n searchInputRef.current?.setCustomValidity('')\n setSearchText(newValue)\n }}\n onChange={(_, newValue) => {\n // Auto-execute search when a suggestion is selected from the dropdown\n if (\n typeof newValue === 'string' &&\n newValue.trim().length >= MIN_SEARCH_QUERY_LENGTH\n ) {\n executeSearch(newValue)\n }\n }}\n renderInput={params => (\n <TextField\n {...params}\n inputRef={searchInputRef}\n sx={{ width: '100%' }}\n placeholder=\"Enter Search Terms\"\n type=\"text\"\n slotProps={{\n input: {\n ...params.InputProps,\n startAdornment,\n endAdornment,\n },\n htmlInput: {\n ...params.inputProps,\n minLength: MIN_SEARCH_QUERY_LENGTH,\n },\n }}\n />\n )}\n />\n ) : (\n <TextField\n sx={{ width: '100%' }}\n onChange={handleChange}\n placeholder=\"Enter Search Terms\"\n value={searchText}\n type=\"text\"\n slotProps={{\n input: {\n startAdornment,\n endAdornment,\n },\n htmlInput: {\n minLength: MIN_SEARCH_QUERY_LENGTH,\n ref: searchInputRef,\n },\n }}\n />\n )}\n </form>\n </Collapse>\n </div>\n )\n}\n\nexport default FullTextSearch\n"],"mappings":";;;;;;;;;;;;;;;AAmBA,IAAM,IAA0B,GAC1B,IAAyB;AAM/B,SAAgB,EAAe,EAC7B,gBACuC;CACvC,IAAM,EAAE,2BAAwB,GAAiB,EAC3C,EAAE,qBAAkB,GAA8B,EAClD,CAAC,GAAY,KAAiB,EAAS,GAAG,EAC1C,CAAC,GAAa,KAAkB,EAAmB,EAAE,CAAC,EACtD,IAAiB,EAAyB,KAAK,EAE/C,EAAE,YAAS,GAAqB,EAChC,IAAe,GAAM;AAa3B,CAVA,QAAgB;AACd,GACE,CAAC,GAAW,kBACZ,EAAW,MAAM,CAAC,SAAS,MAE3B,EAAe,EAAE,CAAC;IAEnB,CAAC,GAAW,gBAAgB,EAAW,CAAC,EAG3C,QACQ;AAEF,GAAC,GAAW,kBACZ,EAAW,MAAM,CAAC,SAAS,KAI7B,EACG,eAAe,EAAW,CAC1B,KAAK,EAAe,CACpB,YAAY,EAAe,EAAE,CAAC,CAAC;IAEpC,CAAC,GAAY,EAAU,EACvB,EACD;CAED,IAAM,KAAiB,MAAiB;AAUtC,EATA,GAAoB,MAClB,EACE,GACA,GACA,GACA,EACD,CACF,EACD,EAAc,GAAG,EACjB,EAAe,EAAE,CAAC;IAGd,KAAU,MAA2C;AAKzD,EAJA,EAAM,gBAAgB,EAIlB,EAAW,MAAM,CAAC,SAAS,IAC7B,EAAe,SAAS,kBACtB,sCAAsC,EAAwB,aAC/D,GAED,EAAc,EAAW;IAIvB,KAAgB,MAAyC;AAE7D,EADA,EAAe,SAAS,kBAAkB,GAAG,EAC7C,EAAc,EAAM,cAAc,MAAM;IAGpC,IACJ,kBAAC,GAAD;EACE,MAAK;EACL,MAAM;EACN,IAAI;GACF,IAAI;GACJ,OAAO;GACR;EACD,CAAA,EAGE,IACJ,kBAAA,GAAA,EAAA,UAAA,CACG,EAAW,SAAS,KACnB,kBAAC,GAAD;EACE,MAAK;EACL,MAAK;EACL,eAAe;AAEb,GADA,EAAc,GAAG,EACjB,EAAe,EAAE,CAAC;;EAEpB,CAAA,EAEH,GAAW,iBACV,kBAAC,GAAD;EACE,cAAc;EACd,SAAS,EAAU;EACnB,WAAU;EACV,CAAA,CAEH,EAAA,CAAA;AAGL,QACE,kBAAC,OAAD;EAAK,WAAW;YACd,kBAAC,GAAD;GAAU,IAAI;GAAe,SAAS;IAAE,OAAO;IAAK,MAAM;IAAK;aAC7D,kBAAC,QAAD;IAAM,UAAU;cACb,GAAW,iBACV,kBAAC,GAAD;KACE,UAAA;KACA,kBAAA;KACA,SAAS;KACT,YAAY;KACZ,gBAAgB,GAAG,GAAU,MAAW;AAClC,YAAW,YACf,EAAe,SAAS,kBAAkB,GAAG,EAC7C,EAAc,EAAS;;KAEzB,WAAW,GAAG,MAAa;AAEzB,MACE,OAAO,KAAa,YACpB,EAAS,MAAM,CAAC,UAAU,KAE1B,EAAc,EAAS;;KAG3B,cAAa,MACX,kBAAC,GAAD;MACE,GAAI;MACJ,UAAU;MACV,IAAI,EAAE,OAAO,QAAQ;MACrB,aAAY;MACZ,MAAK;MACL,WAAW;OACT,OAAO;QACL,GAAG,EAAO;QACV;QACA;QACD;OACD,WAAW;QACT,GAAG,EAAO;QACV,WAAW;QACZ;OACF;MACD,CAAA;KAEJ,CAAA,GAEF,kBAAC,GAAD;KACE,IAAI,EAAE,OAAO,QAAQ;KACrB,UAAU;KACV,aAAY;KACZ,OAAO;KACP,MAAK;KACL,WAAW;MACT,OAAO;OACL;OACA;OACD;MACD,WAAW;OACT,WAAW;OACX,KAAK;OACN;MACF;KACD,CAAA;IAEC,CAAA;GACE,CAAA;EACP,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"BioregistryRules.d.ts","sourceRoot":"","sources":["../../../src/components/GenericCard/BioregistryRules.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,gBAAgB;;qBAFL,MAAM;GA+yB7B,CAAA"}
1
+ {"version":3,"file":"BioregistryRules.d.ts","sourceRoot":"","sources":["../../../src/components/GenericCard/BioregistryRules.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,gBAAgB;;qBAFL,MAAM;GAi0B7B,CAAA"}
@@ -481,11 +481,11 @@ var e = (e) => `https://bioregistry.io/${e}`, t = [
481
481
  onMatch: e
482
482
  },
483
483
  {
484
- regex: /(mesh:(?:C|D|M)\d{6,9})/,
484
+ regex: /(mesh:(?:C|D|Q)\d+)/,
485
485
  onMatch: e
486
486
  },
487
487
  {
488
- regex: /(metabolights:MTBLS\d+)/,
488
+ regex: /(metabolights:MTBL[CS]\d+)/,
489
489
  onMatch: e
490
490
  },
491
491
  {
@@ -752,6 +752,10 @@ var e = (e) => `https://bioregistry.io/${e}`, t = [
752
752
  regex: /(tcdb:\d+(?:\.[A-Z])?(?:\.\d+)?(?:\.\d+)?(?:\.\d+)?)/,
753
753
  onMatch: e
754
754
  },
755
+ {
756
+ regex: /(tcia.collection:[A-Za-z0-9][A-Za-z0-9_\-\.]*[A-Za-z0-9])/,
757
+ onMatch: e
758
+ },
755
759
  {
756
760
  regex: /(uberon:\d+)/,
757
761
  onMatch: e
@@ -765,7 +769,7 @@ var e = (e) => `https://bioregistry.io/${e}`, t = [
765
769
  onMatch: e
766
770
  },
767
771
  {
768
- regex: /(uniprot:(?:(?:[A-N,R-Z][0-9](?:[A-Z][A-Z, 0-9][A-Z, 0-9][0-9]){1,2})|(?:[O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(?:\.\d+)?))/,
772
+ regex: /(uniprot:(?:(?:[A-N,R-Z][0-9](?:[A-Z][A-Z, 0-9][A-Z, 0-9][0-9]){1,2})|(?:[O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(?:\.\d+)?(?:-\d+)?(?:#PRO_\d+)?))/,
769
773
  onMatch: e
770
774
  },
771
775
  {