synapse-react-client 4.0.5 → 4.0.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.
Files changed (212) hide show
  1. package/dist/SWC.index.d.ts +2 -0
  2. package/dist/SWC.index.d.ts.map +1 -1
  3. package/dist/SWC.index.js +47 -41
  4. package/dist/SWC.index.js.map +1 -1
  5. package/dist/assets/DefaultColorfulPortalCardBackground.svg +50 -12
  6. package/dist/assets/DefaultColorfulPortalCardBackground.svg.js +4 -4
  7. package/dist/assets/DefaultColorfulPortalCardBackground.svg.js.map +1 -1
  8. package/dist/components/CardDeck/TableQueryCardDeck.js +3 -4
  9. package/dist/components/CardDeck/TableQueryCardDeck.js.map +1 -1
  10. package/dist/components/ChangePassword/useChangePasswordFormState.js +2 -3
  11. package/dist/components/ChangePassword/useChangePasswordFormState.js.map +1 -1
  12. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.css +1 -0
  13. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.d.ts +8 -0
  14. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.d.ts.map +1 -0
  15. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.js +21 -0
  16. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.js.map +1 -0
  17. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.module.scss +32 -0
  18. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.module.scss.js +14 -0
  19. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.module.scss.js.map +1 -0
  20. package/dist/components/ColoredBulletListItem/index.d.ts +5 -0
  21. package/dist/components/ColoredBulletListItem/index.d.ts.map +1 -0
  22. package/dist/components/ColoredBulletListItem/index.js +6 -0
  23. package/dist/components/ColoredBulletListItem/index.js.map +1 -0
  24. package/dist/components/CreateOrUpdateAccessRequirementWizard/CreateOrUpdateAccessRequirementWizard.js +3 -4
  25. package/dist/components/CreateOrUpdateAccessRequirementWizard/CreateOrUpdateAccessRequirementWizard.js.map +1 -1
  26. package/dist/components/CreateProjectModal/CreateProjectModal.d.ts +2 -1
  27. package/dist/components/CreateProjectModal/CreateProjectModal.d.ts.map +1 -1
  28. package/dist/components/CreateProjectModal/CreateProjectModal.js +122 -43
  29. package/dist/components/CreateProjectModal/CreateProjectModal.js.map +1 -1
  30. package/dist/components/CreateProjectModal/ProjectVisibilityRadioGroup.d.ts +7 -0
  31. package/dist/components/CreateProjectModal/ProjectVisibilityRadioGroup.d.ts.map +1 -0
  32. package/dist/components/CreateProjectModal/ProjectVisibilityRadioGroup.js +132 -0
  33. package/dist/components/CreateProjectModal/ProjectVisibilityRadioGroup.js.map +1 -0
  34. package/dist/components/DataGrid/DataGrid.d.ts +2 -0
  35. package/dist/components/DataGrid/DataGrid.d.ts.map +1 -1
  36. package/dist/components/DataGrid/DataGrid.js +69 -67
  37. package/dist/components/DataGrid/DataGrid.js.map +1 -1
  38. package/dist/components/DataGrid/DataGridWebSocket.d.ts +4 -0
  39. package/dist/components/DataGrid/DataGridWebSocket.d.ts.map +1 -1
  40. package/dist/components/DataGrid/DataGridWebSocket.js +47 -37
  41. package/dist/components/DataGrid/DataGridWebSocket.js.map +1 -1
  42. package/dist/components/DataGrid/MergeGridWithSourceTableButton.js +2 -3
  43. package/dist/components/DataGrid/MergeGridWithSourceTableButton.js.map +1 -1
  44. package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
  45. package/dist/components/DataGrid/SynapseGrid.js +209 -162
  46. package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
  47. package/dist/components/DataGrid/components/UploadCsvToGridDialog.js +2 -3
  48. package/dist/components/DataGrid/components/UploadCsvToGridDialog.js.map +1 -1
  49. package/dist/components/DataGrid/hooks/useRemoteSelections.d.ts +16 -0
  50. package/dist/components/DataGrid/hooks/useRemoteSelections.d.ts.map +1 -0
  51. package/dist/components/DataGrid/hooks/useRemoteSelections.js +30 -0
  52. package/dist/components/DataGrid/hooks/useRemoteSelections.js.map +1 -0
  53. package/dist/components/DataGrid/useDataGridWebsocket.d.ts +6 -1
  54. package/dist/components/DataGrid/useDataGridWebsocket.d.ts.map +1 -1
  55. package/dist/components/DataGrid/useDataGridWebsocket.js +78 -69
  56. package/dist/components/DataGrid/useDataGridWebsocket.js.map +1 -1
  57. package/dist/components/DataGrid/utils/getCellClassName.d.ts +3 -0
  58. package/dist/components/DataGrid/utils/getCellClassName.d.ts.map +1 -1
  59. package/dist/components/DataGrid/utils/getCellClassName.js +21 -12
  60. package/dist/components/DataGrid/utils/getCellClassName.js.map +1 -1
  61. package/dist/components/DataGrid/utils/replicaSelectionToGridSelection.d.ts +15 -0
  62. package/dist/components/DataGrid/utils/replicaSelectionToGridSelection.d.ts.map +1 -0
  63. package/dist/components/DataGrid/utils/replicaSelectionToGridSelection.js +43 -0
  64. package/dist/components/DataGrid/utils/replicaSelectionToGridSelection.js.map +1 -0
  65. package/dist/components/DialogBase.d.ts +3 -1
  66. package/dist/components/DialogBase.d.ts.map +1 -1
  67. package/dist/components/DialogBase.js +75 -56
  68. package/dist/components/DialogBase.js.map +1 -1
  69. package/dist/components/Ecosystem/EcosystemSkeleton.js +2 -3
  70. package/dist/components/Ecosystem/EcosystemSkeleton.js.map +1 -1
  71. package/dist/components/FeaturedDataTabs/FacetPlotsCard.js +2 -3
  72. package/dist/components/FeaturedDataTabs/FacetPlotsCard.js.map +1 -1
  73. package/dist/components/FeaturedDataTabs/FeaturedDataTabs.js +2 -3
  74. package/dist/components/FeaturedDataTabs/FeaturedDataTabs.js.map +1 -1
  75. package/dist/components/GenericCard/GenericCard.js +3 -4
  76. package/dist/components/GenericCard/GenericCard.js.map +1 -1
  77. package/dist/components/HeaderCard.js +2 -3
  78. package/dist/components/HeaderCard.js.map +1 -1
  79. package/dist/components/IconSvg/IconSvg.d.ts +1 -1
  80. package/dist/components/IconSvg/IconSvg.d.ts.map +1 -1
  81. package/dist/components/IconSvg/IconSvg.js +168 -165
  82. package/dist/components/IconSvg/IconSvg.js.map +1 -1
  83. package/dist/components/StorybookComponentWrapper.js +3 -4
  84. package/dist/components/StorybookComponentWrapper.js.map +1 -1
  85. package/dist/components/SynapseForm/SynapseFormSubmissionGrid.d.ts +1 -0
  86. package/dist/components/SynapseForm/SynapseFormSubmissionGrid.d.ts.map +1 -1
  87. package/dist/components/SynapseForm/SynapseFormSubmissionGrid.js +23 -16
  88. package/dist/components/SynapseForm/SynapseFormSubmissionGrid.js.map +1 -1
  89. package/dist/components/SynapseTable/SynapseTable.d.ts +6 -1
  90. package/dist/components/SynapseTable/SynapseTable.d.ts.map +1 -1
  91. package/dist/components/SynapseTable/SynapseTable.js +123 -93
  92. package/dist/components/SynapseTable/SynapseTable.js.map +1 -1
  93. package/dist/components/TextField/TextField.css +1 -0
  94. package/dist/components/TextField/TextField.d.ts +2 -1
  95. package/dist/components/TextField/TextField.d.ts.map +1 -1
  96. package/dist/components/TextField/TextField.js +42 -28
  97. package/dist/components/TextField/TextField.js.map +1 -1
  98. package/dist/components/TextField/TextField.module.scss +25 -0
  99. package/dist/components/TextField/TextField.module.scss.js +14 -0
  100. package/dist/components/TextField/TextField.module.scss.js.map +1 -0
  101. package/dist/components/download_list/AddToDownloadListConfirmationAlert/AddToDownloadListConfirmationAlert.js +2 -3
  102. package/dist/components/download_list/AddToDownloadListConfirmationAlert/AddToDownloadListConfirmationAlert.js.map +1 -1
  103. package/dist/components/index.d.ts +1 -0
  104. package/dist/components/index.d.ts.map +1 -1
  105. package/dist/components/index.js +242 -240
  106. package/dist/components/index.js.map +1 -1
  107. package/dist/components/styled/HoverPopover.css +1 -1
  108. package/dist/components/styled/HoverPopover.d.ts.map +1 -1
  109. package/dist/components/styled/HoverPopover.js +6 -5
  110. package/dist/components/styled/HoverPopover.js.map +1 -1
  111. package/dist/components/styled/HoverPopover.module.scss +2 -1
  112. package/dist/components/styled/HoverPopover.module.scss.js +1 -1
  113. package/dist/components/styled/StyledFormControl.js +1 -1
  114. package/dist/components/styled/StyledFormControl.js.map +1 -1
  115. package/dist/components/table/CsvPreview/CsvPreview.js +2 -3
  116. package/dist/components/table/CsvPreview/CsvPreview.js.map +1 -1
  117. package/dist/components/table/CsvPreview/CsvPreviewDialog.js +2 -3
  118. package/dist/components/table/CsvPreview/CsvPreviewDialog.js.map +1 -1
  119. package/dist/features/curator/GridPage/GridPage.js +2 -3
  120. package/dist/features/curator/GridPage/GridPage.js.map +1 -1
  121. package/dist/features/curator/GridPage/components/GridPageTitle.js +2 -3
  122. package/dist/features/curator/GridPage/components/GridPageTitle.js.map +1 -1
  123. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.d.ts +5 -2
  124. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.d.ts.map +1 -1
  125. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js +46 -33
  126. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js.map +1 -1
  127. package/dist/features/entity/metadata-task/components/MetadataTasksPage.d.ts.map +1 -1
  128. package/dist/features/entity/metadata-task/components/MetadataTasksPage.js +52 -27
  129. package/dist/features/entity/metadata-task/components/MetadataTasksPage.js.map +1 -1
  130. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.d.ts +7 -0
  131. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.d.ts.map +1 -0
  132. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js +322 -0
  133. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js.map +1 -0
  134. package/dist/features/entity/metadata-task/hooks/useGetOrCreateGridSessionForSource.d.ts +7 -1
  135. package/dist/features/entity/metadata-task/hooks/useGetOrCreateGridSessionForSource.d.ts.map +1 -1
  136. package/dist/features/entity/metadata-task/hooks/useGetOrCreateGridSessionForSource.js +7 -7
  137. package/dist/features/entity/metadata-task/hooks/useGetOrCreateGridSessionForSource.js.map +1 -1
  138. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask.d.ts +9 -5
  139. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask.d.ts.map +1 -1
  140. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask.js +79 -16
  141. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask.js.map +1 -1
  142. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask_legacy.d.ts +12 -0
  143. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask_legacy.d.ts.map +1 -0
  144. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask_legacy.js +20 -0
  145. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask_legacy.js.map +1 -0
  146. package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.d.ts +3 -3
  147. package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.d.ts.map +1 -1
  148. package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.js +54 -41
  149. package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.js.map +1 -1
  150. package/dist/features/entity/metadata-task/utils/getCreateGridRequestForMetadataTask.d.ts +2 -2
  151. package/dist/features/entity/metadata-task/utils/getCreateGridRequestForMetadataTask.d.ts.map +1 -1
  152. package/dist/features/entity/metadata-task/utils/getCreateGridRequestForMetadataTask.js +11 -4
  153. package/dist/features/entity/metadata-task/utils/getCreateGridRequestForMetadataTask.js.map +1 -1
  154. package/dist/features/entity/metadata-task/utils/taskHasAssignee.d.ts +3 -0
  155. package/dist/features/entity/metadata-task/utils/taskHasAssignee.d.ts.map +1 -0
  156. package/dist/features/entity/metadata-task/utils/taskHasAssignee.js +7 -0
  157. package/dist/features/entity/metadata-task/utils/taskHasAssignee.js.map +1 -0
  158. package/dist/index.js +306 -304
  159. package/dist/index.js.map +1 -1
  160. package/dist/mocks/curation/mockCurationTask.d.ts +10 -0
  161. package/dist/mocks/curation/mockCurationTask.d.ts.map +1 -0
  162. package/dist/mocks/curation/mockCurationTask.js +24 -0
  163. package/dist/mocks/curation/mockCurationTask.js.map +1 -0
  164. package/dist/style/components/_data-grid-extra.css +1 -1
  165. package/dist/style/components/_data-grid-extra.scss +16 -0
  166. package/dist/synapse-client/SynapseClient.d.ts +1 -1
  167. package/dist/synapse-client/SynapseClient.d.ts.map +1 -1
  168. package/dist/synapse-client/SynapseClient.js +3 -2
  169. package/dist/synapse-client/SynapseClient.js.map +1 -1
  170. package/dist/synapse-queries/KeyFactory.d.ts +8 -3
  171. package/dist/synapse-queries/KeyFactory.d.ts.map +1 -1
  172. package/dist/synapse-queries/KeyFactory.js +22 -7
  173. package/dist/synapse-queries/KeyFactory.js.map +1 -1
  174. package/dist/synapse-queries/curation/task/useCurationTask.d.ts +6 -3
  175. package/dist/synapse-queries/curation/task/useCurationTask.d.ts.map +1 -1
  176. package/dist/synapse-queries/curation/task/useCurationTask.js +62 -18
  177. package/dist/synapse-queries/curation/task/useCurationTask.js.map +1 -1
  178. package/dist/synapse-queries/grid/useEstablishWebsocketConnection.d.ts +2 -0
  179. package/dist/synapse-queries/grid/useEstablishWebsocketConnection.d.ts.map +1 -1
  180. package/dist/synapse-queries/grid/useEstablishWebsocketConnection.js.map +1 -1
  181. package/dist/synapse-queries/grid/useGridSession.d.ts +17 -2
  182. package/dist/synapse-queries/grid/useGridSession.d.ts.map +1 -1
  183. package/dist/synapse-queries/grid/useGridSession.js +63 -30
  184. package/dist/synapse-queries/grid/useGridSession.js.map +1 -1
  185. package/dist/synapse-queries/index.js +103 -99
  186. package/dist/synapse-queries/team/index.js +18 -15
  187. package/dist/synapse-queries/team/useTeamMembers.d.ts +34 -0
  188. package/dist/synapse-queries/team/useTeamMembers.d.ts.map +1 -1
  189. package/dist/synapse-queries/team/useTeamMembers.js +110 -69
  190. package/dist/synapse-queries/team/useTeamMembers.js.map +1 -1
  191. package/dist/synapse-queries/types.d.ts +13 -0
  192. package/dist/synapse-queries/types.d.ts.map +1 -0
  193. package/dist/synapse-queries/types.js +2 -0
  194. package/dist/synapse-queries/types.js.map +1 -0
  195. package/dist/synapse-queries/user/index.js +12 -11
  196. package/dist/synapse-queries/user/useUserGroupHeader.d.ts +5 -0
  197. package/dist/synapse-queries/user/useUserGroupHeader.d.ts.map +1 -1
  198. package/dist/synapse-queries/user/useUserGroupHeader.js +28 -21
  199. package/dist/synapse-queries/user/useUserGroupHeader.js.map +1 -1
  200. package/dist/theme/palette/Palettes.d.ts +2 -0
  201. package/dist/theme/palette/Palettes.d.ts.map +1 -1
  202. package/dist/theme/palette/Palettes.js +46 -40
  203. package/dist/theme/palette/Palettes.js.map +1 -1
  204. package/dist/tsconfig.build.tsbuildinfo +1 -1
  205. package/dist/utils/hooks/useOverlay.d.ts +2 -2
  206. package/dist/utils/hooks/useOverlay.d.ts.map +1 -1
  207. package/dist/utils/hooks/useOverlay.js +41 -41
  208. package/dist/utils/hooks/useOverlay.js.map +1 -1
  209. package/package.json +4 -4
  210. package/dist/assets/ArcusBioIcon.svg +0 -1
  211. package/dist/assets/ArcusBioIcon.svg.js +0 -7
  212. package/dist/assets/ArcusBioIcon.svg.js.map +0 -1
@@ -1,16 +1,16 @@
1
- import { jsx as A } from "react/jsx-runtime";
2
- import { modelColsToGrid as Y } from "./utils/modelColsToGrid.js";
3
- import B from "classnames";
4
- import { useState as h, useEffect as H, useCallback as s, useMemo as f, useRef as D } from "react";
5
- import { DynamicDataSheetGrid as q } from "@sage-bionetworks/react-datasheet-grid";
1
+ import { jsx as D } from "react/jsx-runtime";
2
+ import { modelColsToGrid as B } from "./utils/modelColsToGrid.js";
3
+ import H from "classnames";
4
+ import { useState as h, useEffect as q, useCallback as s, useMemo as f, useRef as E } from "react";
5
+ import { DynamicDataSheetGrid as F } from "@sage-bionetworks/react-datasheet-grid";
6
6
  import "@sage-bionetworks/react-datasheet-grid/dist/style.css";
7
7
  import '../../style/components/_data-grid-extra.css';/* empty css */
8
- import { renderViewContextMenu as F, renderRecordSetContextMenu as J, renderAddRowsComponent as L } from "./components/contextMenu.js";
9
- import { GRID_ROW_REACT_KEY_PROPERTY as Q } from "./utils/DataGridUtils.js";
10
- import { getCellClassName as X } from "./utils/getCellClassName.js";
11
- import { useColumnResizeHandles as Z } from "./hooks/useColumnResizeHandles.js";
12
- import { calculateDefaultColumnWidth as $ } from "./utils/calculateColumnWidth.js";
13
- function me(E) {
8
+ import { renderViewContextMenu as J, renderRecordSetContextMenu as L, renderAddRowsComponent as Q } from "./components/contextMenu.js";
9
+ import { GRID_ROW_REACT_KEY_PROPERTY as X } from "./utils/DataGridUtils.js";
10
+ import { getCellClassName as Z } from "./utils/getCellClassName.js";
11
+ import { useColumnResizeHandles as $ } from "./hooks/useColumnResizeHandles.js";
12
+ import { calculateDefaultColumnWidth as ee } from "./utils/calculateColumnWidth.js";
13
+ function fe(N) {
14
14
  const {
15
15
  gridRef: a,
16
16
  rowValues: C,
@@ -20,134 +20,136 @@ function me(E) {
20
20
  entityIsView: i,
21
21
  jsonSchema: d,
22
22
  lastSelection: R,
23
- handleChange: N,
24
- handleSelectionChange: W,
25
- onSelectedRowChange: p
26
- } = E, [S, g] = h({}), [v, x] = h(!1);
27
- H(() => {
28
- !r || !o || g((e) => {
23
+ handleChange: W,
24
+ handleSelectionChange: x,
25
+ onSelectedRowChange: p,
26
+ remoteSelections: S
27
+ } = N, [g, v] = h({}), [_, z] = h(!1);
28
+ q(() => {
29
+ !r || !o || v((e) => {
29
30
  const n = o.map((l) => r[l]);
30
31
  if (!n.some((l) => !e[l]))
31
32
  return e;
32
33
  const w = { ...e };
33
- return n.forEach((l, K) => {
34
+ return n.forEach((l, U) => {
34
35
  if (!w[l]) {
35
- const k = c[l], U = {
36
- showPinIcon: K === 0,
37
- hasDescription: !!k?.description
36
+ const A = c[l], Y = {
37
+ showPinIcon: U === 0,
38
+ hasDescription: !!A?.description
38
39
  };
39
- w[l] = $(
40
+ w[l] = ee(
40
41
  l,
41
- k,
42
- U
42
+ A,
43
+ Y
43
44
  );
44
45
  }
45
46
  }), w;
46
47
  });
47
48
  }, [r, o, c]);
48
- const _ = s(
49
+ const P = s(
49
50
  (e) => {
50
- typeof e != "number" || e < 0 || !o || e >= o.length || e === 0 && x((n) => !n);
51
+ typeof e != "number" || e < 0 || !o || e >= o.length || e === 0 && z((n) => !n);
51
52
  },
52
53
  [o]
53
- ), P = f(() => v ? /* @__PURE__ */ new Set([0]) : /* @__PURE__ */ new Set(), [v]), u = f(
54
- () => Y(
54
+ ), b = f(() => _ ? /* @__PURE__ */ new Set([0]) : /* @__PURE__ */ new Set(), [_]), u = f(
55
+ () => B(
55
56
  r,
56
57
  o,
57
58
  c,
58
- S,
59
- P,
60
- _
59
+ g,
60
+ b,
61
+ P
61
62
  ),
62
63
  [
63
64
  r,
64
65
  o,
65
66
  c,
66
- S,
67
- P,
68
- _
67
+ g,
68
+ b,
69
+ P
69
70
  ]
70
- ), [m, b] = h(null), z = f(
71
- () => i ? F : J,
71
+ ), [m, y] = h(null), G = f(
72
+ () => i ? J : L,
72
73
  [i]
73
- ), G = f(
74
- () => i ? !1 : L,
74
+ ), M = f(
75
+ () => i ? !1 : Q,
75
76
  [i]
76
- ), M = s(
77
- ({ rowData: e, rowIndex: n }) => B({
77
+ ), O = s(
78
+ ({ rowData: e, rowIndex: n }) => H({
78
79
  "row-valid": !!d && e.__validationStatus === "valid",
79
80
  "row-invalid": !!d && e.__validationStatus === "invalid",
80
81
  "row-unknown": !!d && e.__validationStatus === "pending",
81
82
  "row-selected": m === n
82
83
  }),
83
84
  [d, m]
84
- ), O = s(
85
+ ), T = s(
85
86
  ({
86
87
  rowData: e,
87
88
  rowIndex: n,
88
89
  columnId: t
89
- }) => X({
90
+ }) => Z({
90
91
  rowData: e,
91
92
  rowIndex: n,
92
93
  columnId: t || "",
93
94
  selectedRowIndex: m,
94
95
  lastSelection: R,
95
- colValues: u
96
+ colValues: u,
97
+ remoteSelections: S
96
98
  }),
97
- [m, R, u]
98
- ), T = s(
99
+ [m, R, u, S]
100
+ ), V = s(
99
101
  ({ rowData: e }) => ({
100
102
  ...e
101
103
  }),
102
104
  []
103
- ), V = s(
105
+ ), j = s(
104
106
  ({ cell: e }) => {
105
- e ? (b(e.row), p?.(e.row, C[e.row])) : (b(null), p?.(null, null));
107
+ e ? (y(e.row), p?.(e.row, C[e.row])) : (y(null), p?.(null, null));
106
108
  },
107
109
  [p, C]
108
- ), y = D(null), I = D(
110
+ ), I = E(null), k = E(
109
111
  null
110
- ), j = s(
112
+ ), K = s(
111
113
  (e, n) => {
112
114
  if (a.current) {
113
115
  const t = a.current.activeCell;
114
- t ? I.current = {
116
+ t ? k.current = {
115
117
  col: t.col,
116
118
  row: t.row
117
- } : I.current = null;
119
+ } : k.current = null;
118
120
  }
119
- g((t) => ({
121
+ v((t) => ({
120
122
  ...t,
121
123
  [e]: n
122
124
  }));
123
125
  },
124
126
  [a]
125
127
  );
126
- return Z({
127
- wrapperRef: y,
128
+ return $({
129
+ wrapperRef: I,
128
130
  colValues: u,
129
- onColumnResize: j
130
- }), /* @__PURE__ */ A("div", { ref: y, style: { position: "relative", width: "100%" }, children: /* @__PURE__ */ A(
131
- q,
131
+ onColumnResize: K
132
+ }), /* @__PURE__ */ D("div", { ref: I, style: { position: "relative", width: "100%" }, children: /* @__PURE__ */ D(
133
+ F,
132
134
  {
133
135
  ref: a,
134
136
  value: C,
135
137
  columns: u,
136
138
  autoAddRow: !i,
137
139
  disableSmartDelete: !0,
138
- addRowsComponent: G,
139
- contextMenuComponent: z,
140
- rowKey: Q,
141
- rowClassName: M,
142
- cellClassName: O,
143
- duplicateRow: T,
144
- onChange: N,
145
- onActiveCellChange: V,
146
- onSelectionChange: W
140
+ addRowsComponent: M,
141
+ contextMenuComponent: G,
142
+ rowKey: X,
143
+ rowClassName: O,
144
+ cellClassName: T,
145
+ duplicateRow: V,
146
+ onChange: W,
147
+ onActiveCellChange: j,
148
+ onSelectionChange: x
147
149
  }
148
150
  ) });
149
151
  }
150
152
  export {
151
- me as default
153
+ fe as default
152
154
  };
153
155
  //# sourceMappingURL=DataGrid.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataGrid.js","sources":["../../../src/components/DataGrid/DataGrid.tsx"],"sourcesContent":["import { modelColsToGrid } from '@/components/DataGrid/utils/modelColsToGrid'\nimport { SchemaPropertiesMap } from '@/utils/jsonschema/getSchemaPropertyInfo'\nimport classNames from 'classnames'\nimport { JSONSchema7 } from 'json-schema'\nimport { useEffect, useMemo, useState, useRef, useCallback } from 'react'\nimport {\n DynamicDataSheetGrid,\n DataSheetGridRef,\n} from '@sage-bionetworks/react-datasheet-grid'\nimport '@sage-bionetworks/react-datasheet-grid/dist/style.css'\nimport '../../style/components/_data-grid-extra.scss'\nimport { SelectionWithId } from '@sage-bionetworks/react-datasheet-grid'\nimport {\n renderAddRowsComponent,\n renderRecordSetContextMenu,\n renderViewContextMenu,\n} from './components/contextMenu'\nimport { DataGridRow, Operation } from './DataGridTypes'\nimport { GRID_ROW_REACT_KEY_PROPERTY } from './utils/DataGridUtils'\nimport { getCellClassName } from './utils/getCellClassName'\nimport { useColumnResizeHandles } from './hooks/useColumnResizeHandles'\nimport {\n calculateDefaultColumnWidth,\n HeaderOptions,\n} from './utils/calculateColumnWidth'\n\ntype DataGridProps = {\n gridRef: React.RefObject<DataSheetGridRef | null>\n columnNames: string[]\n columnOrder: number[]\n schemaPropertiesInfo: SchemaPropertiesMap\n rowValues: DataGridRow[]\n entityIsView: boolean\n jsonSchema: JSONSchema7 | undefined\n lastSelection: SelectionWithId | null\n handleChange: (newValue: DataGridRow[], operations: Operation[]) => void\n handleSelectionChange: (opts: { selection: SelectionWithId | null }) => void\n onSelectedRowChange?: (\n rowIndex: number | null,\n row: DataGridRow | null,\n ) => void\n}\n\n/**\n * Component that renders a data grid/spreadsheet using react-datasheet-grid.\n * @param props\n * @constructor\n */\nexport default function DataGrid(props: DataGridProps) {\n const {\n gridRef,\n rowValues,\n columnNames,\n columnOrder,\n schemaPropertiesInfo,\n entityIsView,\n jsonSchema,\n lastSelection,\n handleChange,\n handleSelectionChange,\n onSelectedRowChange,\n } = props\n\n // Move columnWidths state into DataGrid\n const [columnWidths, setColumnWidths] = useState<Record<string, number>>({})\n\n // Pin state management for first column\n const [isPinned, setIsPinned] = useState(false)\n\n // Initialize column widths with defaults when columns first become available\n useEffect(() => {\n if (!columnNames || !columnOrder) {\n return\n }\n\n // Initialize widths for any columns that don't have them yet\n setColumnWidths(prev => {\n const modelColumnNames = columnOrder.map(idx => columnNames[idx])\n\n // Check if any columns need initialization\n const needsUpdate = modelColumnNames.some(name => !prev[name])\n\n if (!needsUpdate) {\n return prev // Return same reference to avoid triggering updates\n }\n\n const newWidths = { ...prev }\n modelColumnNames.forEach((columnName, arrayIndex) => {\n if (!newWidths[columnName]) {\n // Calculate default width using centralized function\n const propertyInfo = schemaPropertiesInfo[columnName]\n const headerOptions: HeaderOptions = {\n showPinIcon: arrayIndex === 0,\n hasDescription: !!propertyInfo?.description,\n }\n newWidths[columnName] = calculateDefaultColumnWidth(\n columnName,\n propertyInfo,\n headerOptions,\n )\n }\n })\n return newWidths\n })\n }, [columnNames, columnOrder, schemaPropertiesInfo])\n\n // Handler to toggle pin state for the first column only\n const handleTogglePin = useCallback(\n (columnIndex: number) => {\n // Validate columnIndex\n if (\n typeof columnIndex !== 'number' ||\n columnIndex < 0 ||\n !columnOrder ||\n columnIndex >= columnOrder.length\n ) {\n return\n }\n\n if (columnIndex !== 0) return // Only allow first column pinning\n\n setIsPinned(prev => !prev)\n },\n [columnOrder],\n )\n\n // Memoize the pinned columns set to prevent recalculation during scroll\n const pinnedColumnsSet = useMemo<Set<number>>(() => {\n return isPinned ? new Set([0]) : new Set()\n }, [isPinned])\n\n const colValues = useMemo(\n () =>\n modelColsToGrid(\n columnNames,\n columnOrder,\n schemaPropertiesInfo,\n columnWidths,\n pinnedColumnsSet,\n handleTogglePin,\n ),\n [\n columnNames,\n columnOrder,\n schemaPropertiesInfo,\n columnWidths,\n pinnedColumnsSet,\n handleTogglePin,\n ],\n )\n const [selectedRowIndex, setSelectedRowIndex] = useState<number | null>(null)\n\n // Memoize contextMenuComponent\n const contextMenuComponent = useMemo(\n () => (entityIsView ? renderViewContextMenu : renderRecordSetContextMenu),\n [entityIsView],\n )\n\n // Memoize addRowsComponent\n const addRowsComponent = useMemo(\n () => (entityIsView ? false : renderAddRowsComponent),\n [entityIsView],\n )\n\n // Wrap rowClassName in useCallback\n const rowClassNameCallback = useCallback(\n ({ rowData, rowIndex }: { rowData: DataGridRow; rowIndex: number }) =>\n classNames({\n 'row-valid': !!jsonSchema && rowData.__validationStatus === 'valid',\n 'row-invalid': !!jsonSchema && rowData.__validationStatus === 'invalid',\n 'row-unknown': !!jsonSchema && rowData.__validationStatus === 'pending',\n 'row-selected': selectedRowIndex === rowIndex,\n }),\n [jsonSchema, selectedRowIndex],\n )\n\n // Wrap cellClassName in useCallback\n const cellClassNameCallback = useCallback(\n ({\n rowData,\n rowIndex,\n columnId,\n }: {\n rowData: unknown\n rowIndex: number\n columnId?: string\n }) => {\n return getCellClassName({\n rowData: rowData as DataGridRow,\n rowIndex,\n columnId: columnId || '',\n selectedRowIndex,\n lastSelection,\n colValues,\n })\n },\n [selectedRowIndex, lastSelection, colValues],\n )\n\n // Wrap duplicateRow in useCallback\n const duplicateRowCallback = useCallback(\n ({ rowData }: { rowData: DataGridRow }) => ({\n ...rowData,\n }),\n [],\n )\n\n // Wrap onActiveCellChange in useCallback\n const handleActiveCellChange = useCallback(\n ({ cell }: { cell: { row: number; col: number } | null }) => {\n if (cell) {\n setSelectedRowIndex(cell.row)\n onSelectedRowChange?.(cell.row, rowValues[cell.row])\n } else {\n setSelectedRowIndex(null)\n onSelectedRowChange?.(null, null)\n }\n },\n [onSelectedRowChange, rowValues],\n )\n\n // Wrapper ref for the grid container\n const wrapperRef = useRef<HTMLDivElement | null>(null)\n\n // Store the active cell before column resize so we can restore it\n const activeCellBeforeResizeRef = useRef<{ col: number; row: number } | null>(\n null,\n )\n\n // Handle column resize callback\n const handleColumnResize = useCallback(\n (columnName: string, newWidth: number) => {\n // Save the current active cell before updating widths (which will trigger remount)\n if (gridRef.current) {\n const activeCell = gridRef.current.activeCell\n if (activeCell) {\n activeCellBeforeResizeRef.current = {\n col: activeCell.col,\n row: activeCell.row,\n }\n } else {\n // Explicitly clear the ref if there's no active cell\n activeCellBeforeResizeRef.current = null\n }\n }\n\n setColumnWidths(prev => ({\n ...prev,\n [columnName]: newWidth,\n }))\n },\n [gridRef],\n )\n\n // Setup column resize handles\n useColumnResizeHandles({\n wrapperRef,\n colValues,\n onColumnResize: handleColumnResize,\n })\n\n return (\n <div ref={wrapperRef} style={{ position: 'relative', width: '100%' }}>\n <DynamicDataSheetGrid\n ref={gridRef}\n value={rowValues}\n columns={colValues}\n autoAddRow={!entityIsView}\n disableSmartDelete\n addRowsComponent={addRowsComponent}\n contextMenuComponent={contextMenuComponent}\n rowKey={GRID_ROW_REACT_KEY_PROPERTY}\n rowClassName={rowClassNameCallback}\n cellClassName={cellClassNameCallback}\n duplicateRow={duplicateRowCallback}\n onChange={handleChange}\n onActiveCellChange={handleActiveCellChange}\n onSelectionChange={handleSelectionChange}\n />\n </div>\n )\n}\n"],"names":["DataGrid","props","gridRef","rowValues","columnNames","columnOrder","schemaPropertiesInfo","entityIsView","jsonSchema","lastSelection","handleChange","handleSelectionChange","onSelectedRowChange","columnWidths","setColumnWidths","useState","isPinned","setIsPinned","useEffect","prev","modelColumnNames","idx","name","newWidths","columnName","arrayIndex","propertyInfo","headerOptions","calculateDefaultColumnWidth","handleTogglePin","useCallback","columnIndex","pinnedColumnsSet","useMemo","colValues","modelColsToGrid","selectedRowIndex","setSelectedRowIndex","contextMenuComponent","renderViewContextMenu","renderRecordSetContextMenu","addRowsComponent","renderAddRowsComponent","rowClassNameCallback","rowData","rowIndex","classNames","cellClassNameCallback","columnId","getCellClassName","duplicateRowCallback","handleActiveCellChange","cell","wrapperRef","useRef","activeCellBeforeResizeRef","handleColumnResize","newWidth","activeCell","useColumnResizeHandles","jsx","DynamicDataSheetGrid","GRID_ROW_REACT_KEY_PROPERTY"],"mappings":"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"}
1
+ {"version":3,"file":"DataGrid.js","sources":["../../../src/components/DataGrid/DataGrid.tsx"],"sourcesContent":["import { modelColsToGrid } from '@/components/DataGrid/utils/modelColsToGrid'\nimport { SchemaPropertiesMap } from '@/utils/jsonschema/getSchemaPropertyInfo'\nimport classNames from 'classnames'\nimport { JSONSchema7 } from 'json-schema'\nimport { useEffect, useMemo, useState, useRef, useCallback } from 'react'\nimport {\n DynamicDataSheetGrid,\n DataSheetGridRef,\n} from '@sage-bionetworks/react-datasheet-grid'\nimport '@sage-bionetworks/react-datasheet-grid/dist/style.css'\nimport '../../style/components/_data-grid-extra.scss'\nimport { SelectionWithId } from '@sage-bionetworks/react-datasheet-grid'\nimport {\n renderAddRowsComponent,\n renderRecordSetContextMenu,\n renderViewContextMenu,\n} from './components/contextMenu'\nimport { DataGridRow, Operation } from './DataGridTypes'\nimport { GRID_ROW_REACT_KEY_PROPERTY } from './utils/DataGridUtils'\nimport { getCellClassName } from './utils/getCellClassName'\nimport { useColumnResizeHandles } from './hooks/useColumnResizeHandles'\nimport {\n calculateDefaultColumnWidth,\n HeaderOptions,\n} from './utils/calculateColumnWidth'\nimport type { RemoteSelection } from './hooks/useRemoteSelections'\n\ntype DataGridProps = {\n gridRef: React.RefObject<DataSheetGridRef | null>\n columnNames: string[]\n columnOrder: number[]\n schemaPropertiesInfo: SchemaPropertiesMap\n rowValues: DataGridRow[]\n entityIsView: boolean\n jsonSchema: JSONSchema7 | undefined\n lastSelection: SelectionWithId | null\n handleChange: (newValue: DataGridRow[], operations: Operation[]) => void\n handleSelectionChange: (opts: { selection: SelectionWithId | null }) => void\n onSelectedRowChange?: (\n rowIndex: number | null,\n row: DataGridRow | null,\n ) => void\n remoteSelections?: readonly RemoteSelection[]\n}\n\n/**\n * Component that renders a data grid/spreadsheet using react-datasheet-grid.\n * @param props\n * @constructor\n */\nexport default function DataGrid(props: DataGridProps) {\n const {\n gridRef,\n rowValues,\n columnNames,\n columnOrder,\n schemaPropertiesInfo,\n entityIsView,\n jsonSchema,\n lastSelection,\n handleChange,\n handleSelectionChange,\n onSelectedRowChange,\n remoteSelections,\n } = props\n\n // Move columnWidths state into DataGrid\n const [columnWidths, setColumnWidths] = useState<Record<string, number>>({})\n\n // Pin state management for first column\n const [isPinned, setIsPinned] = useState(false)\n\n // Initialize column widths with defaults when columns first become available\n useEffect(() => {\n if (!columnNames || !columnOrder) {\n return\n }\n\n // Initialize widths for any columns that don't have them yet\n setColumnWidths(prev => {\n const modelColumnNames = columnOrder.map(idx => columnNames[idx])\n\n // Check if any columns need initialization\n const needsUpdate = modelColumnNames.some(name => !prev[name])\n\n if (!needsUpdate) {\n return prev // Return same reference to avoid triggering updates\n }\n\n const newWidths = { ...prev }\n modelColumnNames.forEach((columnName, arrayIndex) => {\n if (!newWidths[columnName]) {\n // Calculate default width using centralized function\n const propertyInfo = schemaPropertiesInfo[columnName]\n const headerOptions: HeaderOptions = {\n showPinIcon: arrayIndex === 0,\n hasDescription: !!propertyInfo?.description,\n }\n newWidths[columnName] = calculateDefaultColumnWidth(\n columnName,\n propertyInfo,\n headerOptions,\n )\n }\n })\n return newWidths\n })\n }, [columnNames, columnOrder, schemaPropertiesInfo])\n\n // Handler to toggle pin state for the first column only\n const handleTogglePin = useCallback(\n (columnIndex: number) => {\n // Validate columnIndex\n if (\n typeof columnIndex !== 'number' ||\n columnIndex < 0 ||\n !columnOrder ||\n columnIndex >= columnOrder.length\n ) {\n return\n }\n\n if (columnIndex !== 0) return // Only allow first column pinning\n\n setIsPinned(prev => !prev)\n },\n [columnOrder],\n )\n\n // Memoize the pinned columns set to prevent recalculation during scroll\n const pinnedColumnsSet = useMemo<Set<number>>(() => {\n return isPinned ? new Set([0]) : new Set()\n }, [isPinned])\n\n const colValues = useMemo(\n () =>\n modelColsToGrid(\n columnNames,\n columnOrder,\n schemaPropertiesInfo,\n columnWidths,\n pinnedColumnsSet,\n handleTogglePin,\n ),\n [\n columnNames,\n columnOrder,\n schemaPropertiesInfo,\n columnWidths,\n pinnedColumnsSet,\n handleTogglePin,\n ],\n )\n const [selectedRowIndex, setSelectedRowIndex] = useState<number | null>(null)\n\n // Memoize contextMenuComponent\n const contextMenuComponent = useMemo(\n () => (entityIsView ? renderViewContextMenu : renderRecordSetContextMenu),\n [entityIsView],\n )\n\n // Memoize addRowsComponent\n const addRowsComponent = useMemo(\n () => (entityIsView ? false : renderAddRowsComponent),\n [entityIsView],\n )\n\n // Wrap rowClassName in useCallback\n const rowClassNameCallback = useCallback(\n ({ rowData, rowIndex }: { rowData: DataGridRow; rowIndex: number }) =>\n classNames({\n 'row-valid': !!jsonSchema && rowData.__validationStatus === 'valid',\n 'row-invalid': !!jsonSchema && rowData.__validationStatus === 'invalid',\n 'row-unknown': !!jsonSchema && rowData.__validationStatus === 'pending',\n 'row-selected': selectedRowIndex === rowIndex,\n }),\n [jsonSchema, selectedRowIndex],\n )\n\n // Wrap cellClassName in useCallback\n const cellClassNameCallback = useCallback(\n ({\n rowData,\n rowIndex,\n columnId,\n }: {\n rowData: unknown\n rowIndex: number\n columnId?: string\n }) => {\n return getCellClassName({\n rowData: rowData as DataGridRow,\n rowIndex,\n columnId: columnId || '',\n selectedRowIndex,\n lastSelection,\n colValues,\n remoteSelections,\n })\n },\n [selectedRowIndex, lastSelection, colValues, remoteSelections],\n )\n\n // Wrap duplicateRow in useCallback\n const duplicateRowCallback = useCallback(\n ({ rowData }: { rowData: DataGridRow }) => ({\n ...rowData,\n }),\n [],\n )\n\n // Wrap onActiveCellChange in useCallback\n const handleActiveCellChange = useCallback(\n ({ cell }: { cell: { row: number; col: number } | null }) => {\n if (cell) {\n setSelectedRowIndex(cell.row)\n onSelectedRowChange?.(cell.row, rowValues[cell.row])\n } else {\n setSelectedRowIndex(null)\n onSelectedRowChange?.(null, null)\n }\n },\n [onSelectedRowChange, rowValues],\n )\n\n // Wrapper ref for the grid container\n const wrapperRef = useRef<HTMLDivElement | null>(null)\n\n // Store the active cell before column resize so we can restore it\n const activeCellBeforeResizeRef = useRef<{ col: number; row: number } | null>(\n null,\n )\n\n // Handle column resize callback\n const handleColumnResize = useCallback(\n (columnName: string, newWidth: number) => {\n // Save the current active cell before updating widths (which will trigger remount)\n if (gridRef.current) {\n const activeCell = gridRef.current.activeCell\n if (activeCell) {\n activeCellBeforeResizeRef.current = {\n col: activeCell.col,\n row: activeCell.row,\n }\n } else {\n // Explicitly clear the ref if there's no active cell\n activeCellBeforeResizeRef.current = null\n }\n }\n\n setColumnWidths(prev => ({\n ...prev,\n [columnName]: newWidth,\n }))\n },\n [gridRef],\n )\n\n // Setup column resize handles\n useColumnResizeHandles({\n wrapperRef,\n colValues,\n onColumnResize: handleColumnResize,\n })\n\n return (\n <div ref={wrapperRef} style={{ position: 'relative', width: '100%' }}>\n <DynamicDataSheetGrid\n ref={gridRef}\n value={rowValues}\n columns={colValues}\n autoAddRow={!entityIsView}\n disableSmartDelete\n addRowsComponent={addRowsComponent}\n contextMenuComponent={contextMenuComponent}\n rowKey={GRID_ROW_REACT_KEY_PROPERTY}\n rowClassName={rowClassNameCallback}\n cellClassName={cellClassNameCallback}\n duplicateRow={duplicateRowCallback}\n onChange={handleChange}\n onActiveCellChange={handleActiveCellChange}\n onSelectionChange={handleSelectionChange}\n />\n </div>\n )\n}\n"],"names":["DataGrid","props","gridRef","rowValues","columnNames","columnOrder","schemaPropertiesInfo","entityIsView","jsonSchema","lastSelection","handleChange","handleSelectionChange","onSelectedRowChange","remoteSelections","columnWidths","setColumnWidths","useState","isPinned","setIsPinned","useEffect","prev","modelColumnNames","idx","name","newWidths","columnName","arrayIndex","propertyInfo","headerOptions","calculateDefaultColumnWidth","handleTogglePin","useCallback","columnIndex","pinnedColumnsSet","useMemo","colValues","modelColsToGrid","selectedRowIndex","setSelectedRowIndex","contextMenuComponent","renderViewContextMenu","renderRecordSetContextMenu","addRowsComponent","renderAddRowsComponent","rowClassNameCallback","rowData","rowIndex","classNames","cellClassNameCallback","columnId","getCellClassName","duplicateRowCallback","handleActiveCellChange","cell","wrapperRef","useRef","activeCellBeforeResizeRef","handleColumnResize","newWidth","activeCell","useColumnResizeHandles","jsx","DynamicDataSheetGrid","GRID_ROW_REACT_KEY_PROPERTY"],"mappings":"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"}
@@ -5,6 +5,8 @@ type DataGridWebSocketConstructorArgs = {
5
5
  onGridReady?: () => void;
6
6
  onStatusChange?: (isOpen: boolean, instance: DataGridWebSocket) => void;
7
7
  onModelCreate?: (model: GridModel) => void;
8
+ onReplicaConnected?: () => void;
9
+ onReplicaDisconnected?: () => void;
8
10
  maxPayloadSizeBytes?: number;
9
11
  socket?: WebSocket;
10
12
  model?: GridModel | null;
@@ -22,6 +24,8 @@ export declare class DataGridWebSocket {
22
24
  private onModelCreate;
23
25
  private onGridReady;
24
26
  private onStatusChange;
27
+ private onReplicaConnected;
28
+ private onReplicaDisconnected;
25
29
  constructor(args: DataGridWebSocketConstructorArgs);
26
30
  private attachSocketHandlers;
27
31
  disconnect(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"DataGridWebSocket.d.ts","sourceRoot":"","sources":["../../../src/components/DataGrid/DataGridWebSocket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAyC/D,KAAK,gCAAgC,GAAG;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACvE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAA;IAC1C,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAQD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,mBAAmB,CAAQ;IACnC,OAAO,CAAC,kBAAkB,CAA2B;IACrD,OAAO,CAAC,eAAe,CAAwB;IAE/C,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,WAAW,CAAY;IAC/B,OAAO,CAAC,cAAc,CAAqD;gBAE/D,IAAI,EAAE,gCAAgC;IAqClD,OAAO,CAAC,oBAAoB;IAwBrB,UAAU;IAWjB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,kBAAkB;YAiBZ,qBAAqB;IAYnC,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,kBAAkB;IA6C1B,OAAO,CAAC,WAAW;IAWZ,SAAS;IAIhB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA0B1B,OAAO,CAAC,eAAe;YAST,sBAAsB;CAYrC"}
1
+ {"version":3,"file":"DataGridWebSocket.d.ts","sourceRoot":"","sources":["../../../src/components/DataGrid/DataGridWebSocket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAyC/D,KAAK,gCAAgC,GAAG;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACvE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAA;IAC1C,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC/B,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAA;IAClC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAQD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,mBAAmB,CAAQ;IACnC,OAAO,CAAC,kBAAkB,CAA2B;IACrD,OAAO,CAAC,eAAe,CAAwB;IAE/C,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,WAAW,CAAY;IAC/B,OAAO,CAAC,cAAc,CAAqD;IAC3E,OAAO,CAAC,kBAAkB,CAAY;IACtC,OAAO,CAAC,qBAAqB,CAAY;gBAE7B,IAAI,EAAE,gCAAgC;IAyClD,OAAO,CAAC,oBAAoB;IAwBrB,UAAU;IAWjB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,kBAAkB;YAiBZ,qBAAqB;IAYnC,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,kBAAkB;IAuD1B,OAAO,CAAC,WAAW;IAWZ,SAAS;IAIhB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA0B1B,OAAO,CAAC,eAAe;YAST,sBAAsB;CAYrC"}
@@ -1,46 +1,50 @@
1
- import m from "./utils/json-rx/JsonRx.js";
2
- import p from "./utils/json-rx/JsonRxNotification.js";
3
- import a from "./utils/json-rx/JsonRxRequestComplete.js";
4
- import f from "./utils/json-rx/JsonRxResponse.js";
5
- import g from "./utils/json-rx/JsonRxResponseComplete.js";
6
- import y from "./utils/MessageCounter.js";
7
- import { splitPatch as b } from "./utils/splitPatch.js";
8
- import { Model as S } from "json-joy/lib/json-crdt";
9
- import { decode as k } from "json-joy/lib/json-crdt-patch/codec/compact";
10
- import { Encoder as u } from "json-joy/lib/json-crdt/codec/structural/verbose/Encoder";
11
- import c from "lodash-es/noop";
12
- import C from "lodash-es/throttle";
13
- import { Decoder as M } from "json-joy/lib/json-crdt/codec/indexed/binary/Decoder";
14
- import { decode as P } from "cbor2";
15
- import { fetchWithExponentialTimeout as w } from "@sage-bionetworks/synapse-client";
16
- const v = 30 * 1024, R = 250;
17
- class L {
1
+ import f from "./utils/json-rx/JsonRx.js";
2
+ import g from "./utils/json-rx/JsonRxNotification.js";
3
+ import c from "./utils/json-rx/JsonRxRequestComplete.js";
4
+ import b from "./utils/json-rx/JsonRxResponse.js";
5
+ import y from "./utils/json-rx/JsonRxResponseComplete.js";
6
+ import k from "./utils/MessageCounter.js";
7
+ import { splitPatch as S } from "./utils/splitPatch.js";
8
+ import { Model as u } from "json-joy/lib/json-crdt";
9
+ import { decode as C } from "json-joy/lib/json-crdt-patch/codec/compact";
10
+ import { Encoder as R } from "json-joy/lib/json-crdt/codec/structural/verbose/Encoder";
11
+ import a from "lodash-es/noop";
12
+ import M from "lodash-es/throttle";
13
+ import { Decoder as P } from "json-joy/lib/json-crdt/codec/indexed/binary/Decoder";
14
+ import { decode as w } from "cbor2";
15
+ import { fetchWithExponentialTimeout as v } from "@sage-bionetworks/synapse-client";
16
+ const x = 30 * 1024, D = 250;
17
+ class q {
18
18
  socket;
19
19
  model = null;
20
20
  messageCounter;
21
21
  replicaId;
22
- verboseEncoder = new u();
22
+ verboseEncoder = new R();
23
23
  maxPayloadSizeBytes;
24
24
  throttledSendPatch;
25
- snapshotDecoder = new M();
25
+ snapshotDecoder = new P();
26
26
  onModelCreate;
27
27
  onGridReady;
28
28
  onStatusChange;
29
+ onReplicaConnected;
30
+ onReplicaDisconnected;
29
31
  constructor(o) {
30
32
  const {
31
33
  replicaId: e,
32
34
  url: s,
33
35
  onGridReady: t,
34
36
  onStatusChange: n,
35
- onModelCreate: r,
36
- maxPayloadSizeBytes: d,
37
- socket: h,
38
- model: i,
39
- patchThrottleMs: l
37
+ onModelCreate: i,
38
+ onReplicaConnected: d,
39
+ onReplicaDisconnected: h,
40
+ maxPayloadSizeBytes: l,
41
+ socket: m,
42
+ model: r,
43
+ patchThrottleMs: p
40
44
  } = o;
41
- this.messageCounter = new y(), this.replicaId = e, this.maxPayloadSizeBytes = d ?? v, this.socket = h ?? new WebSocket(s), this.onModelCreate = r ?? c, this.onGridReady = t ?? c, this.onStatusChange = n ?? c, i && (this.model = i), this.attachSocketHandlers(), this.throttledSendPatch = C(
45
+ this.messageCounter = new k(), this.replicaId = e, this.maxPayloadSizeBytes = l ?? x, this.socket = m ?? new WebSocket(s), this.onModelCreate = i ?? a, this.onGridReady = t ?? a, this.onStatusChange = n ?? a, this.onReplicaConnected = d ?? a, this.onReplicaDisconnected = h ?? a, r && (this.model = r), this.attachSocketHandlers(), this.throttledSendPatch = M(
42
46
  () => this.sendPatchImmediate(),
43
- l ?? R,
47
+ p ?? D,
44
48
  { leading: !1, trailing: !0 }
45
49
  );
46
50
  }
@@ -73,10 +77,10 @@ class L {
73
77
  }
74
78
  }
75
79
  handleMessage(o) {
76
- const e = m.fromJson(JSON.parse(o));
77
- e instanceof f ? this.handleResponse(
80
+ const e = f.fromJson(JSON.parse(o));
81
+ e instanceof b ? this.handleResponse(
78
82
  e
79
- ) : e instanceof g ? this.handleResponseComplete() : e instanceof p ? this.handleNotification(e) : console.warn("Unexpected WebSocket message format:", e);
83
+ ) : e instanceof y ? this.handleResponseComplete() : e instanceof g ? this.handleNotification(e) : console.warn("Unexpected WebSocket message format:", e);
80
84
  }
81
85
  handleResponse(o) {
82
86
  const e = o.getPayload();
@@ -97,8 +101,8 @@ class L {
97
101
  }
98
102
  handlePatchPayload(o) {
99
103
  try {
100
- const e = o.map(k);
101
- this.model ? this.model.applyBatch(e) : (this.model = S.fromPatches(e).fork(
104
+ const e = o.map(C);
105
+ this.model ? this.model.applyBatch(e) : (this.model = u.fromPatches(e).fork(
102
106
  this.replicaId
103
107
  ), this.onModelCreate(this.model)), this.sendClockSync();
104
108
  } catch (e) {
@@ -143,7 +147,7 @@ class L {
143
147
  {
144
148
  const s = this.verboseEncoder.encode(this.model);
145
149
  console.debug("New patch received, syncing data:", s.time);
146
- const t = new a(
150
+ const t = new c(
147
151
  this.messageCounter.getNext(),
148
152
  "synchronize-clock",
149
153
  s.time
@@ -151,6 +155,12 @@ class L {
151
155
  this.sendMessage(t);
152
156
  }
153
157
  break;
158
+ case "replica-connected":
159
+ console.debug("A replica connected to the grid session"), this.onReplicaConnected();
160
+ break;
161
+ case "replica-disconnected":
162
+ console.debug("A replica disconnected from the grid session"), this.onReplicaDisconnected();
163
+ break;
154
164
  default:
155
165
  console.warn("Unknown notification method:", e);
156
166
  break;
@@ -172,9 +182,9 @@ class L {
172
182
  if (!this.model)
173
183
  return console.warn("Model is not initialized. Cannot send patch."), !1;
174
184
  const o = this.model.api.flush(), e = o.ops.length > 0;
175
- return e && b(o, this.maxPayloadSizeBytes).forEach((t) => {
185
+ return e && S(o, this.maxPayloadSizeBytes).forEach((t) => {
176
186
  console.debug("Sending patch to server:", t);
177
- const n = new a(
187
+ const n = new c(
178
188
  this.messageCounter.getNext(),
179
189
  "patch",
180
190
  t
@@ -183,7 +193,7 @@ class L {
183
193
  }), e;
184
194
  }
185
195
  sendSyncMessage(o) {
186
- const e = new a(
196
+ const e = new c(
187
197
  this.messageCounter.getNext(),
188
198
  "synchronize-clock",
189
199
  o ?? []
@@ -191,13 +201,13 @@ class L {
191
201
  this.sendMessage(e);
192
202
  }
193
203
  async fetchAndDecodeSnapshot(o) {
194
- const t = await (await (await w(o)).blob()).arrayBuffer(), n = P(new Uint8Array(t));
204
+ const t = await (await (await v(o)).blob()).arrayBuffer(), n = w(new Uint8Array(t));
195
205
  return this.snapshotDecoder.decode(
196
206
  n
197
207
  );
198
208
  }
199
209
  }
200
210
  export {
201
- L as DataGridWebSocket
211
+ q as DataGridWebSocket
202
212
  };
203
213
  //# sourceMappingURL=DataGridWebSocket.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataGridWebSocket.js","sources":["../../../src/components/DataGrid/DataGridWebSocket.ts"],"sourcesContent":["import { GridModel } from '@/components/DataGrid/DataGridTypes'\nimport JsonRx from '@/components/DataGrid/utils/json-rx/JsonRx'\nimport JsonRxMessage from '@/components/DataGrid/utils/json-rx/JsonRxMessage'\nimport JsonRxNotification from '@/components/DataGrid/utils/json-rx/JsonRxNotification'\nimport JsonRxRequestComplete from '@/components/DataGrid/utils/json-rx/JsonRxRequestComplete'\nimport JsonRxResponse from '@/components/DataGrid/utils/json-rx/JsonRxResponse'\nimport JsonRxResponseComplete from '@/components/DataGrid/utils/json-rx/JsonRxResponseComplete'\nimport MessageCounter from '@/components/DataGrid/utils/MessageCounter'\nimport { splitPatch } from '@/components/DataGrid/utils/splitPatch'\nimport { Model } from 'json-joy/lib/json-crdt'\nimport {\n CompactCodecPatch,\n decode,\n} from 'json-joy/lib/json-crdt-patch/codec/compact'\nimport { Encoder as VerboseEncoder } from 'json-joy/lib/json-crdt/codec/structural/verbose/Encoder'\nimport { JsonCrdtVerboseLogicalTimestamp } from 'json-joy/lib/json-crdt/codec/structural/verbose/types'\nimport noop from 'lodash-es/noop'\nimport throttle from 'lodash-es/throttle'\nimport { type DebouncedFunc } from 'lodash-es'\nimport { Decoder as SnapshotDecoder } from 'json-joy/lib/json-crdt/codec/indexed/binary/Decoder'\nimport { decode as decodeCbor } from 'cbor2'\nimport type { IndexedFields } from 'json-joy/lib/json-crdt/codec/indexed/binary'\nimport { fetchWithExponentialTimeout } from '@sage-bionetworks/synapse-client'\n\nenum SynapseGridWebSocketMessagePayloadType {\n PATCH = 'patch',\n SNAPSHOT = 'snapshot',\n PATCHES = 'patches',\n}\n\ntype SynapseGridWebSocketMessagePayload =\n | {\n type: SynapseGridWebSocketMessagePayloadType.PATCH\n body: CompactCodecPatch\n }\n | {\n type: SynapseGridWebSocketMessagePayloadType.PATCHES\n body: CompactCodecPatch[]\n }\n | { type: SynapseGridWebSocketMessagePayloadType.SNAPSHOT; body: string }\n\ntype DataGridWebSocketConstructorArgs = {\n replicaId: number\n url: string\n onGridReady?: () => void\n onStatusChange?: (isOpen: boolean, instance: DataGridWebSocket) => void\n onModelCreate?: (model: GridModel) => void\n maxPayloadSizeBytes?: number\n socket?: WebSocket\n model?: GridModel | null\n patchThrottleMs?: number\n}\n\n// API Gateway WebSocket payload size limit is 32 KB per message\n// There is some overhead we aren't computing in our utility, namely the size of the patch header and the communication protocol itself\n// So add some buffer\nconst DEFAULT_MAX_PAYLOAD_SIZE_BYTES = 30 * 1024 // 30 KB\nconst DEFAULT_PATCH_THROTTLE_MS = 250\n\nexport class DataGridWebSocket {\n private socket: WebSocket\n private model: GridModel | null = null\n private messageCounter: MessageCounter\n private replicaId: number\n private verboseEncoder = new VerboseEncoder()\n private maxPayloadSizeBytes: number\n private throttledSendPatch: DebouncedFunc<() => void>\n private snapshotDecoder = new SnapshotDecoder()\n\n private onModelCreate: (model: GridModel) => void\n private onGridReady: () => void\n private onStatusChange: (isOpen: boolean, _this: DataGridWebSocket) => void\n\n constructor(args: DataGridWebSocketConstructorArgs) {\n const {\n replicaId,\n url,\n onGridReady,\n onStatusChange,\n onModelCreate,\n maxPayloadSizeBytes,\n socket,\n model,\n patchThrottleMs,\n } = args\n this.messageCounter = new MessageCounter()\n this.replicaId = replicaId\n this.maxPayloadSizeBytes =\n maxPayloadSizeBytes ?? DEFAULT_MAX_PAYLOAD_SIZE_BYTES\n this.socket = socket ?? new WebSocket(url)\n\n // Assign callbacks, falling back to no-ops\n this.onModelCreate = onModelCreate ?? noop\n this.onGridReady = onGridReady ?? noop\n this.onStatusChange = onStatusChange ?? noop\n\n // Restore existing model if provided\n if (model) {\n this.model = model\n }\n\n this.attachSocketHandlers()\n\n this.throttledSendPatch = throttle(\n () => this.sendPatchImmediate(),\n patchThrottleMs ?? DEFAULT_PATCH_THROTTLE_MS,\n { leading: false, trailing: true },\n )\n }\n\n private attachSocketHandlers() {\n this.socket.onopen = () => {\n console.debug('Connected to the WebSocket server')\n this.onStatusChange(true, this)\n }\n\n this.socket.onmessage = (event: MessageEvent) => {\n if (typeof event.data === 'string') {\n this.handleMessage(event.data)\n } else {\n console.error('Received non-string message data:', event.data)\n }\n }\n\n this.socket.onclose = () => {\n console.debug('Disconnected from the WebSocket server')\n this.onStatusChange(false, this)\n }\n\n this.socket.onerror = (error: Event) => {\n console.error('WebSocket error:', error)\n }\n }\n\n public disconnect() {\n this.throttledSendPatch.flush()\n this.throttledSendPatch.cancel()\n if (this.socket.readyState === WebSocket.OPEN) {\n this.socket.close()\n console.debug('WebSocket connection closed')\n } else {\n console.warn('WebSocket is not open. No action taken.')\n }\n }\n\n /**\n * Flushes the local model clock and sends the resulting patch (or a clock-sync\n * message) to the server so that both sides converge.\n */\n private sendClockSync() {\n if (!this.model) {\n console.error('Model is not initialized. Cannot sync model.')\n return\n }\n\n const patchesWereSent = this.sendPatchImmediate()\n if (!patchesWereSent) {\n // We've flushed all of our changes, so now we can receive changes from the server\n const verbModel = this.verboseEncoder.encode(this.model)\n this.sendSyncMessage(verbModel.time)\n }\n }\n\n private handleMessage(rawMessage: string) {\n const message = JsonRx.fromJson(JSON.parse(rawMessage))\n if (message instanceof JsonRxResponse) {\n this.handleResponse(\n message as JsonRxResponse<SynapseGridWebSocketMessagePayload>,\n )\n } else if (message instanceof JsonRxResponseComplete) {\n this.handleResponseComplete()\n } else if (message instanceof JsonRxNotification) {\n this.handleNotification(message)\n } else {\n console.warn('Unexpected WebSocket message format:', message)\n }\n }\n\n private handleResponse(\n message: JsonRxResponse<SynapseGridWebSocketMessagePayload>,\n ) {\n const payload = message.getPayload()\n\n switch (payload.type) {\n case SynapseGridWebSocketMessagePayloadType.PATCH:\n this.handlePatchPayload([payload.body])\n break\n\n case SynapseGridWebSocketMessagePayloadType.PATCHES:\n void this.handlePatchPayload(payload.body)\n break\n\n case SynapseGridWebSocketMessagePayloadType.SNAPSHOT:\n void this.handleSnapshotPayload(payload.body)\n break\n\n default:\n console.warn('Unknown payload type:', payload)\n break\n }\n }\n\n private handlePatchPayload(encodedPatch: CompactCodecPatch[]) {\n try {\n const patches = encodedPatch.map(decode)\n if (!this.model) {\n this.model = Model.fromPatches(patches).fork(\n this.replicaId,\n ) as unknown as GridModel\n this.onModelCreate(this.model)\n } else {\n this.model.applyBatch(patches)\n }\n this.sendClockSync()\n } catch (err) {\n console.error('Failed to apply patches or send clock:', err)\n }\n }\n\n private async handleSnapshotPayload(snapshotUrl: string) {\n console.debug('Received snapshot URL from server:', snapshotUrl)\n try {\n const decodedModel = await this.fetchAndDecodeSnapshot(snapshotUrl)\n this.model = decodedModel.fork(this.replicaId) as unknown as GridModel\n this.onModelCreate(this.model)\n this.sendClockSync()\n } catch (err) {\n console.error('Failed to fetch or decode snapshot', err)\n }\n }\n\n private handleResponseComplete() {\n // Clocks are in sync, no further action needed\n this.onGridReady()\n console.debug(\n 'Clocks synchronized with server. Incrementing sequence number.',\n )\n }\n\n private handleNotification(message: JsonRxNotification) {\n const methodName = message.getMethodName()\n console.debug('Notification received from server:', methodName)\n\n switch (methodName) {\n case 'ping':\n console.debug('Received ping from server')\n break\n\n case 'connected':\n console.debug('Server ready to receive patches')\n this.sendSyncMessage(\n this.model ? this.verboseEncoder.encode(this.model).time : undefined,\n )\n break\n\n case 'error':\n console.warn('Error from server:', message.getPayload())\n break\n\n case 'new-patch':\n if (!this.model) {\n console.warn(\n \"Model is not initialized. Cannot handle 'new-patch' message.\",\n )\n break\n }\n {\n const verbModel = this.verboseEncoder.encode(this.model)\n console.debug('New patch received, syncing data:', verbModel.time)\n const msg = new JsonRxRequestComplete(\n this.messageCounter.getNext(),\n 'synchronize-clock',\n verbModel.time,\n )\n this.sendMessage(msg)\n }\n break\n\n default:\n console.warn('Unknown notification method:', methodName)\n break\n }\n }\n\n private sendMessage(message: JsonRxMessage) {\n if (this.socket.readyState === WebSocket.OPEN) {\n this.socket.send(JSON.stringify(message.getJson()))\n } else {\n console.error(\n 'WebSocket is not open. Unable to send message. Current state:',\n this.socket.readyState,\n )\n }\n }\n\n public sendPatch() {\n this.throttledSendPatch()\n }\n\n /**\n * @returns true if one or more patches were sent\n */\n private sendPatchImmediate(): boolean {\n if (!this.model) {\n console.warn('Model is not initialized. Cannot send patch.')\n return false\n }\n\n const patch = this.model.api.flush()\n const hasOperationsToDispatch = patch.ops.length > 0\n\n if (hasOperationsToDispatch) {\n // Split the patch if it exceeds the maximum size we can send in a single frame\n const patches = splitPatch(patch, this.maxPayloadSizeBytes)\n patches.forEach(compactEncodedPatch => {\n console.debug('Sending patch to server:', compactEncodedPatch)\n const msg = new JsonRxRequestComplete(\n this.messageCounter.getNext(),\n 'patch',\n compactEncodedPatch,\n )\n this.sendMessage(msg)\n })\n }\n\n return hasOperationsToDispatch\n }\n\n private sendSyncMessage(clock?: number | JsonCrdtVerboseLogicalTimestamp[]) {\n const message = new JsonRxRequestComplete(\n this.messageCounter.getNext(),\n 'synchronize-clock',\n clock ?? [],\n )\n this.sendMessage(message)\n }\n\n private async fetchAndDecodeSnapshot(\n snapshotUrl: string,\n ): Promise<GridModel> {\n const response = await fetchWithExponentialTimeout(snapshotUrl)\n const blob = await response.blob()\n const buffer = await blob.arrayBuffer()\n const decodedFromCbor = decodeCbor(new Uint8Array(buffer))\n const decodedModel = this.snapshotDecoder.decode(\n decodedFromCbor as IndexedFields,\n ) as unknown as GridModel\n return decodedModel\n }\n}\n"],"names":["DEFAULT_MAX_PAYLOAD_SIZE_BYTES","DEFAULT_PATCH_THROTTLE_MS","DataGridWebSocket","VerboseEncoder","SnapshotDecoder","args","replicaId","url","onGridReady","onStatusChange","onModelCreate","maxPayloadSizeBytes","socket","model","patchThrottleMs","MessageCounter","noop","throttle","event","error","verbModel","rawMessage","message","JsonRx","JsonRxResponse","JsonRxResponseComplete","JsonRxNotification","payload","encodedPatch","patches","decode","Model","err","snapshotUrl","decodedModel","methodName","msg","JsonRxRequestComplete","patch","hasOperationsToDispatch","splitPatch","compactEncodedPatch","clock","buffer","fetchWithExponentialTimeout","decodedFromCbor","decodeCbor"],"mappings":"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"}
1
+ {"version":3,"file":"DataGridWebSocket.js","sources":["../../../src/components/DataGrid/DataGridWebSocket.ts"],"sourcesContent":["import { GridModel } from '@/components/DataGrid/DataGridTypes'\nimport JsonRx from '@/components/DataGrid/utils/json-rx/JsonRx'\nimport JsonRxMessage from '@/components/DataGrid/utils/json-rx/JsonRxMessage'\nimport JsonRxNotification from '@/components/DataGrid/utils/json-rx/JsonRxNotification'\nimport JsonRxRequestComplete from '@/components/DataGrid/utils/json-rx/JsonRxRequestComplete'\nimport JsonRxResponse from '@/components/DataGrid/utils/json-rx/JsonRxResponse'\nimport JsonRxResponseComplete from '@/components/DataGrid/utils/json-rx/JsonRxResponseComplete'\nimport MessageCounter from '@/components/DataGrid/utils/MessageCounter'\nimport { splitPatch } from '@/components/DataGrid/utils/splitPatch'\nimport { Model } from 'json-joy/lib/json-crdt'\nimport {\n CompactCodecPatch,\n decode,\n} from 'json-joy/lib/json-crdt-patch/codec/compact'\nimport { Encoder as VerboseEncoder } from 'json-joy/lib/json-crdt/codec/structural/verbose/Encoder'\nimport { JsonCrdtVerboseLogicalTimestamp } from 'json-joy/lib/json-crdt/codec/structural/verbose/types'\nimport noop from 'lodash-es/noop'\nimport throttle from 'lodash-es/throttle'\nimport { type DebouncedFunc } from 'lodash-es'\nimport { Decoder as SnapshotDecoder } from 'json-joy/lib/json-crdt/codec/indexed/binary/Decoder'\nimport { decode as decodeCbor } from 'cbor2'\nimport type { IndexedFields } from 'json-joy/lib/json-crdt/codec/indexed/binary'\nimport { fetchWithExponentialTimeout } from '@sage-bionetworks/synapse-client'\n\nenum SynapseGridWebSocketMessagePayloadType {\n PATCH = 'patch',\n SNAPSHOT = 'snapshot',\n PATCHES = 'patches',\n}\n\ntype SynapseGridWebSocketMessagePayload =\n | {\n type: SynapseGridWebSocketMessagePayloadType.PATCH\n body: CompactCodecPatch\n }\n | {\n type: SynapseGridWebSocketMessagePayloadType.PATCHES\n body: CompactCodecPatch[]\n }\n | { type: SynapseGridWebSocketMessagePayloadType.SNAPSHOT; body: string }\n\ntype DataGridWebSocketConstructorArgs = {\n replicaId: number\n url: string\n onGridReady?: () => void\n onStatusChange?: (isOpen: boolean, instance: DataGridWebSocket) => void\n onModelCreate?: (model: GridModel) => void\n onReplicaConnected?: () => void\n onReplicaDisconnected?: () => void\n maxPayloadSizeBytes?: number\n socket?: WebSocket\n model?: GridModel | null\n patchThrottleMs?: number\n}\n\n// API Gateway WebSocket payload size limit is 32 KB per message\n// There is some overhead we aren't computing in our utility, namely the size of the patch header and the communication protocol itself\n// So add some buffer\nconst DEFAULT_MAX_PAYLOAD_SIZE_BYTES = 30 * 1024 // 30 KB\nconst DEFAULT_PATCH_THROTTLE_MS = 250\n\nexport class DataGridWebSocket {\n private socket: WebSocket\n private model: GridModel | null = null\n private messageCounter: MessageCounter\n private replicaId: number\n private verboseEncoder = new VerboseEncoder()\n private maxPayloadSizeBytes: number\n private throttledSendPatch: DebouncedFunc<() => void>\n private snapshotDecoder = new SnapshotDecoder()\n\n private onModelCreate: (model: GridModel) => void\n private onGridReady: () => void\n private onStatusChange: (isOpen: boolean, _this: DataGridWebSocket) => void\n private onReplicaConnected: () => void\n private onReplicaDisconnected: () => void\n\n constructor(args: DataGridWebSocketConstructorArgs) {\n const {\n replicaId,\n url,\n onGridReady,\n onStatusChange,\n onModelCreate,\n onReplicaConnected,\n onReplicaDisconnected,\n maxPayloadSizeBytes,\n socket,\n model,\n patchThrottleMs,\n } = args\n this.messageCounter = new MessageCounter()\n this.replicaId = replicaId\n this.maxPayloadSizeBytes =\n maxPayloadSizeBytes ?? DEFAULT_MAX_PAYLOAD_SIZE_BYTES\n this.socket = socket ?? new WebSocket(url)\n\n // Assign callbacks, falling back to no-ops\n this.onModelCreate = onModelCreate ?? noop\n this.onGridReady = onGridReady ?? noop\n this.onStatusChange = onStatusChange ?? noop\n this.onReplicaConnected = onReplicaConnected ?? noop\n this.onReplicaDisconnected = onReplicaDisconnected ?? noop\n\n // Restore existing model if provided\n if (model) {\n this.model = model\n }\n\n this.attachSocketHandlers()\n\n this.throttledSendPatch = throttle(\n () => this.sendPatchImmediate(),\n patchThrottleMs ?? DEFAULT_PATCH_THROTTLE_MS,\n { leading: false, trailing: true },\n )\n }\n\n private attachSocketHandlers() {\n this.socket.onopen = () => {\n console.debug('Connected to the WebSocket server')\n this.onStatusChange(true, this)\n }\n\n this.socket.onmessage = (event: MessageEvent) => {\n if (typeof event.data === 'string') {\n this.handleMessage(event.data)\n } else {\n console.error('Received non-string message data:', event.data)\n }\n }\n\n this.socket.onclose = () => {\n console.debug('Disconnected from the WebSocket server')\n this.onStatusChange(false, this)\n }\n\n this.socket.onerror = (error: Event) => {\n console.error('WebSocket error:', error)\n }\n }\n\n public disconnect() {\n this.throttledSendPatch.flush()\n this.throttledSendPatch.cancel()\n if (this.socket.readyState === WebSocket.OPEN) {\n this.socket.close()\n console.debug('WebSocket connection closed')\n } else {\n console.warn('WebSocket is not open. No action taken.')\n }\n }\n\n /**\n * Flushes the local model clock and sends the resulting patch (or a clock-sync\n * message) to the server so that both sides converge.\n */\n private sendClockSync() {\n if (!this.model) {\n console.error('Model is not initialized. Cannot sync model.')\n return\n }\n\n const patchesWereSent = this.sendPatchImmediate()\n if (!patchesWereSent) {\n // We've flushed all of our changes, so now we can receive changes from the server\n const verbModel = this.verboseEncoder.encode(this.model)\n this.sendSyncMessage(verbModel.time)\n }\n }\n\n private handleMessage(rawMessage: string) {\n const message = JsonRx.fromJson(JSON.parse(rawMessage))\n if (message instanceof JsonRxResponse) {\n this.handleResponse(\n message as JsonRxResponse<SynapseGridWebSocketMessagePayload>,\n )\n } else if (message instanceof JsonRxResponseComplete) {\n this.handleResponseComplete()\n } else if (message instanceof JsonRxNotification) {\n this.handleNotification(message)\n } else {\n console.warn('Unexpected WebSocket message format:', message)\n }\n }\n\n private handleResponse(\n message: JsonRxResponse<SynapseGridWebSocketMessagePayload>,\n ) {\n const payload = message.getPayload()\n\n switch (payload.type) {\n case SynapseGridWebSocketMessagePayloadType.PATCH:\n this.handlePatchPayload([payload.body])\n break\n\n case SynapseGridWebSocketMessagePayloadType.PATCHES:\n void this.handlePatchPayload(payload.body)\n break\n\n case SynapseGridWebSocketMessagePayloadType.SNAPSHOT:\n void this.handleSnapshotPayload(payload.body)\n break\n\n default:\n console.warn('Unknown payload type:', payload)\n break\n }\n }\n\n private handlePatchPayload(encodedPatch: CompactCodecPatch[]) {\n try {\n const patches = encodedPatch.map(decode)\n if (!this.model) {\n this.model = Model.fromPatches(patches).fork(\n this.replicaId,\n ) as unknown as GridModel\n this.onModelCreate(this.model)\n } else {\n this.model.applyBatch(patches)\n }\n this.sendClockSync()\n } catch (err) {\n console.error('Failed to apply patches or send clock:', err)\n }\n }\n\n private async handleSnapshotPayload(snapshotUrl: string) {\n console.debug('Received snapshot URL from server:', snapshotUrl)\n try {\n const decodedModel = await this.fetchAndDecodeSnapshot(snapshotUrl)\n this.model = decodedModel.fork(this.replicaId) as unknown as GridModel\n this.onModelCreate(this.model)\n this.sendClockSync()\n } catch (err) {\n console.error('Failed to fetch or decode snapshot', err)\n }\n }\n\n private handleResponseComplete() {\n // Clocks are in sync, no further action needed\n this.onGridReady()\n console.debug(\n 'Clocks synchronized with server. Incrementing sequence number.',\n )\n }\n\n private handleNotification(message: JsonRxNotification) {\n const methodName = message.getMethodName()\n console.debug('Notification received from server:', methodName)\n\n switch (methodName) {\n case 'ping':\n console.debug('Received ping from server')\n break\n\n case 'connected':\n console.debug('Server ready to receive patches')\n this.sendSyncMessage(\n this.model ? this.verboseEncoder.encode(this.model).time : undefined,\n )\n break\n\n case 'error':\n console.warn('Error from server:', message.getPayload())\n break\n\n case 'new-patch':\n if (!this.model) {\n console.warn(\n \"Model is not initialized. Cannot handle 'new-patch' message.\",\n )\n break\n }\n {\n const verbModel = this.verboseEncoder.encode(this.model)\n console.debug('New patch received, syncing data:', verbModel.time)\n const msg = new JsonRxRequestComplete(\n this.messageCounter.getNext(),\n 'synchronize-clock',\n verbModel.time,\n )\n this.sendMessage(msg)\n }\n break\n\n case 'replica-connected':\n console.debug('A replica connected to the grid session')\n this.onReplicaConnected()\n break\n\n case 'replica-disconnected':\n console.debug('A replica disconnected from the grid session')\n this.onReplicaDisconnected()\n break\n\n default:\n console.warn('Unknown notification method:', methodName)\n break\n }\n }\n\n private sendMessage(message: JsonRxMessage) {\n if (this.socket.readyState === WebSocket.OPEN) {\n this.socket.send(JSON.stringify(message.getJson()))\n } else {\n console.error(\n 'WebSocket is not open. Unable to send message. Current state:',\n this.socket.readyState,\n )\n }\n }\n\n public sendPatch() {\n this.throttledSendPatch()\n }\n\n /**\n * @returns true if one or more patches were sent\n */\n private sendPatchImmediate(): boolean {\n if (!this.model) {\n console.warn('Model is not initialized. Cannot send patch.')\n return false\n }\n\n const patch = this.model.api.flush()\n const hasOperationsToDispatch = patch.ops.length > 0\n\n if (hasOperationsToDispatch) {\n // Split the patch if it exceeds the maximum size we can send in a single frame\n const patches = splitPatch(patch, this.maxPayloadSizeBytes)\n patches.forEach(compactEncodedPatch => {\n console.debug('Sending patch to server:', compactEncodedPatch)\n const msg = new JsonRxRequestComplete(\n this.messageCounter.getNext(),\n 'patch',\n compactEncodedPatch,\n )\n this.sendMessage(msg)\n })\n }\n\n return hasOperationsToDispatch\n }\n\n private sendSyncMessage(clock?: number | JsonCrdtVerboseLogicalTimestamp[]) {\n const message = new JsonRxRequestComplete(\n this.messageCounter.getNext(),\n 'synchronize-clock',\n clock ?? [],\n )\n this.sendMessage(message)\n }\n\n private async fetchAndDecodeSnapshot(\n snapshotUrl: string,\n ): Promise<GridModel> {\n const response = await fetchWithExponentialTimeout(snapshotUrl)\n const blob = await response.blob()\n const buffer = await blob.arrayBuffer()\n const decodedFromCbor = decodeCbor(new Uint8Array(buffer))\n const decodedModel = this.snapshotDecoder.decode(\n decodedFromCbor as IndexedFields,\n ) as unknown as GridModel\n return decodedModel\n }\n}\n"],"names":["DEFAULT_MAX_PAYLOAD_SIZE_BYTES","DEFAULT_PATCH_THROTTLE_MS","DataGridWebSocket","VerboseEncoder","SnapshotDecoder","args","replicaId","url","onGridReady","onStatusChange","onModelCreate","onReplicaConnected","onReplicaDisconnected","maxPayloadSizeBytes","socket","model","patchThrottleMs","MessageCounter","noop","throttle","event","error","verbModel","rawMessage","message","JsonRx","JsonRxResponse","JsonRxResponseComplete","JsonRxNotification","payload","encodedPatch","patches","decode","Model","err","snapshotUrl","decodedModel","methodName","msg","JsonRxRequestComplete","patch","hasOperationsToDispatch","splitPatch","compactEncodedPatch","clock","buffer","fetchWithExponentialTimeout","decodedFromCbor","decodeCbor"],"mappings":"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"}
@@ -51,7 +51,6 @@ import "../../assets/icons/account-validated.svg.js";
51
51
  import "../../utils/functions/DateFormatter.js";
52
52
  import "@react-hookz/web";
53
53
  import "dayjs";
54
- import "../../assets/ArcusBioIcon.svg.js";
55
54
  import "@mui/material/SvgIcon";
56
55
  import "../../assets/icons/AccessPending.svg.js";
57
56
  import "../../assets/icons/AccessPendingCloud.svg.js";
@@ -217,7 +216,7 @@ import "@mui/material/Grid";
217
216
  import "@mui/icons-material/ArrowForwardIos";
218
217
  import "../PortalAclEditor/PortalAclEditor.js";
219
218
  import "../SynapseHomepageV2/HomepageStyles.js";
220
- function vr(o) {
219
+ function Rr(o) {
221
220
  const { sourceEntityId: t, gridSessionId: i } = o, { data: e, isLoading: n } = y(t), s = e?.concreteType ? l(e.concreteType) : void 0, { mutate: c, isPending: a } = u({
222
221
  onSuccess: (p) => {
223
222
  p.type === "entityview" ? S(p.data) : p.type === "table" ? h(p.data) : r("Successfully updated RecordSet.", "success");
@@ -267,6 +266,6 @@ function T(o) {
267
266
  ) ?? [];
268
267
  }
269
268
  export {
270
- vr as default
269
+ Rr as default
271
270
  };
272
271
  //# sourceMappingURL=MergeGridWithSourceTableButton.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MergeGridWithSourceTableButton.js","sources":["../../../src/components/DataGrid/MergeGridWithSourceTableButton.tsx"],"sourcesContent":["import GridMenuButton from '@/components/DataGrid/components/GridMenuButton/GridMenuButton'\nimport useMergeGridWithSource from '@/components/DataGrid/useMergeGridWithSource'\nimport { displayToast } from '@/components/index'\nimport { useGetEntity } from '@/synapse-queries'\nimport { convertToEntityType } from '@/utils/functions/EntityTypeUtils'\nimport {\n EntityType,\n EntityUpdateResults,\n instanceOfEntityUpdateResults,\n instanceOfUploadToTableResult,\n SynchronizeGridResponse,\n TableUpdateTransactionResponse,\n} from '@sage-bionetworks/synapse-client'\n\nexport type MergeGridWithSourceTableButtonProps = {\n sourceEntityId: string\n gridSessionId: string\n sourceEntityType?: EntityType\n}\n\nexport default function MergeGridWithSourceTableButton(\n props: MergeGridWithSourceTableButtonProps,\n) {\n const { sourceEntityId, gridSessionId } = props\n\n const { data: entity, isLoading: entityLoading } =\n useGetEntity(sourceEntityId)\n\n const sourceEntityType = entity?.concreteType\n ? convertToEntityType(entity.concreteType)\n : undefined\n\n const { mutate: mergeGrid, isPending } = useMergeGridWithSource({\n onSuccess: result => {\n if (result.type === 'entityview') {\n onSynchronizeSuccess(result.data)\n } else if (result.type === 'table') {\n onMergeTableSuccess(result.data)\n } else {\n displayToast('Successfully updated RecordSet.', 'success')\n }\n },\n onError: e => displayToast(e.message, 'danger'),\n })\n\n const buttonText =\n sourceEntityType === 'entityview' ? 'Sync changes' : 'Apply changes'\n\n return (\n <GridMenuButton\n loading={isPending}\n disabled={entityLoading}\n onClick={() => {\n mergeGrid({ gridSessionId, sourceEntityId, sourceEntityType })\n }}\n variant=\"contained\"\n >\n {buttonText}\n </GridMenuButton>\n )\n}\n\nfunction onSynchronizeSuccess(result: SynchronizeGridResponse) {\n if (result.errorMessages == null || result.errorMessages.length === 0) {\n displayToast('Successfully synchronized metadata.', 'success')\n } else {\n displayToast(\n <ul>\n {result.errorMessages.map((msg, index) => (\n <li key={index}>{msg}</li>\n ))}\n </ul>,\n 'warning',\n { title: 'Some changes could not be applied' },\n )\n }\n}\n\nfunction onMergeTableSuccess(result: TableUpdateTransactionResponse) {\n if (result.results?.length) {\n // There should only be one result since the CSV upload is done in one step\n const updateResult = result.results[0]\n if (instanceOfEntityUpdateResults(updateResult)) {\n // This is an update to the contents of a View\n const failureMessages =\n getEntityUpdateResultsErrorMessages(updateResult).join('\\n')\n\n if (failureMessages) {\n displayToast(\n `Some changes could not be applied:\\n${failureMessages}`,\n 'danger',\n )\n } else {\n displayToast('Changes applied successfully', 'success')\n }\n } else if (instanceOfUploadToTableResult(updateResult)) {\n // This is an update to a TableEntity\n const rowsUpdatedStr = updateResult.rowsProcessed?.toLocaleString()\n displayToast(`Successfully updated ${rowsUpdatedStr} rows.`, 'success')\n }\n }\n}\n\nfunction getEntityUpdateResultsErrorMessages(\n results: EntityUpdateResults,\n): string[] {\n return (\n results.updateResults\n ?.filter(e => !!e.failureCode)\n .map(\n r => `${r.entityId}: ${r.failureMessage} (code: ${r.failureCode})`,\n ) ?? []\n )\n}\n"],"names":["MergeGridWithSourceTableButton","props","sourceEntityId","gridSessionId","entity","entityLoading","useGetEntity","sourceEntityType","convertToEntityType","mergeGrid","isPending","useMergeGridWithSource","result","onSynchronizeSuccess","onMergeTableSuccess","displayToast","e","jsx","GridMenuButton","msg","index","updateResult","instanceOfEntityUpdateResults","failureMessages","getEntityUpdateResultsErrorMessages","instanceOfUploadToTableResult","rowsUpdatedStr","results","r"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,SAAwBA,GACtBC,GACA;AACA,QAAM,EAAE,gBAAAC,GAAgB,eAAAC,EAAA,IAAkBF,GAEpC,EAAE,MAAMG,GAAQ,WAAWC,EAAA,IAC/BC,EAAaJ,CAAc,GAEvBK,IAAmBH,GAAQ,eAC7BI,EAAoBJ,EAAO,YAAY,IACvC,QAEE,EAAE,QAAQK,GAAW,WAAAC,EAAA,IAAcC,EAAuB;AAAA,IAC9D,WAAW,CAAAC,MAAU;AACnB,MAAIA,EAAO,SAAS,eAClBC,EAAqBD,EAAO,IAAI,IACvBA,EAAO,SAAS,UACzBE,EAAoBF,EAAO,IAAI,IAE/BG,EAAa,mCAAmC,SAAS;AAAA,IAE7D;AAAA,IACA,SAAS,CAAAC,MAAKD,EAAaC,EAAE,SAAS,QAAQ;AAAA,EAAA,CAC/C;AAKD,SACE,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,SAASR;AAAA,MACT,UAAUL;AAAA,MACV,SAAS,MAAM;AACb,QAAAI,EAAU,EAAE,eAAAN,GAAe,gBAAAD,GAAgB,kBAAAK,EAAA,CAAkB;AAAA,MAC/D;AAAA,MACA,SAAQ;AAAA,MAEP,UAXHA,MAAqB,eAAe,iBAAiB;AAAA,IAWlD;AAAA,EAAA;AAGP;AAEA,SAASM,EAAqBD,GAAiC;AAC7D,EAAIA,EAAO,iBAAiB,QAAQA,EAAO,cAAc,WAAW,IAClEG,EAAa,uCAAuC,SAAS,IAE7DA;AAAA,IACE,gBAAAE,EAAC,MAAA,EACE,UAAAL,EAAO,cAAc,IAAI,CAACO,GAAKC,MAC9B,gBAAAH,EAAC,MAAA,EAAgB,UAAAE,EAAA,GAARC,CAAY,CACtB,GACH;AAAA,IACA;AAAA,IACA,EAAE,OAAO,oCAAA;AAAA,EAAoC;AAGnD;AAEA,SAASN,EAAoBF,GAAwC;AACnE,MAAIA,EAAO,SAAS,QAAQ;AAE1B,UAAMS,IAAeT,EAAO,QAAQ,CAAC;AACrC,QAAIU,EAA8BD,CAAY,GAAG;AAE/C,YAAME,IACJC,EAAoCH,CAAY,EAAE,KAAK;AAAA,CAAI;AAE7D,MAAIE,IACFR;AAAA,QACE;AAAA,EAAuCQ,CAAe;AAAA,QACtD;AAAA,MAAA,IAGFR,EAAa,gCAAgC,SAAS;AAAA,IAE1D,WAAWU,EAA8BJ,CAAY,GAAG;AAEtD,YAAMK,IAAiBL,EAAa,eAAe,eAAA;AACnD,MAAAN,EAAa,wBAAwBW,CAAc,UAAU,SAAS;AAAA,IACxE;AAAA,EACF;AACF;AAEA,SAASF,EACPG,GACU;AACV,SACEA,EAAQ,eACJ,OAAO,CAAAX,MAAK,CAAC,CAACA,EAAE,WAAW,EAC5B;AAAA,IACC,CAAAY,MAAK,GAAGA,EAAE,QAAQ,KAAKA,EAAE,cAAc,WAAWA,EAAE,WAAW;AAAA,EAAA,KAC5D,CAAA;AAEX;"}
1
+ {"version":3,"file":"MergeGridWithSourceTableButton.js","sources":["../../../src/components/DataGrid/MergeGridWithSourceTableButton.tsx"],"sourcesContent":["import GridMenuButton from '@/components/DataGrid/components/GridMenuButton/GridMenuButton'\nimport useMergeGridWithSource from '@/components/DataGrid/useMergeGridWithSource'\nimport { displayToast } from '@/components/index'\nimport { useGetEntity } from '@/synapse-queries'\nimport { convertToEntityType } from '@/utils/functions/EntityTypeUtils'\nimport {\n EntityType,\n EntityUpdateResults,\n instanceOfEntityUpdateResults,\n instanceOfUploadToTableResult,\n SynchronizeGridResponse,\n TableUpdateTransactionResponse,\n} from '@sage-bionetworks/synapse-client'\n\nexport type MergeGridWithSourceTableButtonProps = {\n sourceEntityId: string\n gridSessionId: string\n sourceEntityType?: EntityType\n}\n\nexport default function MergeGridWithSourceTableButton(\n props: MergeGridWithSourceTableButtonProps,\n) {\n const { sourceEntityId, gridSessionId } = props\n\n const { data: entity, isLoading: entityLoading } =\n useGetEntity(sourceEntityId)\n\n const sourceEntityType = entity?.concreteType\n ? convertToEntityType(entity.concreteType)\n : undefined\n\n const { mutate: mergeGrid, isPending } = useMergeGridWithSource({\n onSuccess: result => {\n if (result.type === 'entityview') {\n onSynchronizeSuccess(result.data)\n } else if (result.type === 'table') {\n onMergeTableSuccess(result.data)\n } else {\n displayToast('Successfully updated RecordSet.', 'success')\n }\n },\n onError: e => displayToast(e.message, 'danger'),\n })\n\n const buttonText =\n sourceEntityType === 'entityview' ? 'Sync changes' : 'Apply changes'\n\n return (\n <GridMenuButton\n loading={isPending}\n disabled={entityLoading}\n onClick={() => {\n mergeGrid({ gridSessionId, sourceEntityId, sourceEntityType })\n }}\n variant=\"contained\"\n >\n {buttonText}\n </GridMenuButton>\n )\n}\n\nfunction onSynchronizeSuccess(result: SynchronizeGridResponse) {\n if (result.errorMessages == null || result.errorMessages.length === 0) {\n displayToast('Successfully synchronized metadata.', 'success')\n } else {\n displayToast(\n <ul>\n {result.errorMessages.map((msg, index) => (\n <li key={index}>{msg}</li>\n ))}\n </ul>,\n 'warning',\n { title: 'Some changes could not be applied' },\n )\n }\n}\n\nfunction onMergeTableSuccess(result: TableUpdateTransactionResponse) {\n if (result.results?.length) {\n // There should only be one result since the CSV upload is done in one step\n const updateResult = result.results[0]\n if (instanceOfEntityUpdateResults(updateResult)) {\n // This is an update to the contents of a View\n const failureMessages =\n getEntityUpdateResultsErrorMessages(updateResult).join('\\n')\n\n if (failureMessages) {\n displayToast(\n `Some changes could not be applied:\\n${failureMessages}`,\n 'danger',\n )\n } else {\n displayToast('Changes applied successfully', 'success')\n }\n } else if (instanceOfUploadToTableResult(updateResult)) {\n // This is an update to a TableEntity\n const rowsUpdatedStr = updateResult.rowsProcessed?.toLocaleString()\n displayToast(`Successfully updated ${rowsUpdatedStr} rows.`, 'success')\n }\n }\n}\n\nfunction getEntityUpdateResultsErrorMessages(\n results: EntityUpdateResults,\n): string[] {\n return (\n results.updateResults\n ?.filter(e => !!e.failureCode)\n .map(\n r => `${r.entityId}: ${r.failureMessage} (code: ${r.failureCode})`,\n ) ?? []\n )\n}\n"],"names":["MergeGridWithSourceTableButton","props","sourceEntityId","gridSessionId","entity","entityLoading","useGetEntity","sourceEntityType","convertToEntityType","mergeGrid","isPending","useMergeGridWithSource","result","onSynchronizeSuccess","onMergeTableSuccess","displayToast","e","jsx","GridMenuButton","msg","index","updateResult","instanceOfEntityUpdateResults","failureMessages","getEntityUpdateResultsErrorMessages","instanceOfUploadToTableResult","rowsUpdatedStr","results","r"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,SAAwBA,GACtBC,GACA;AACA,QAAM,EAAE,gBAAAC,GAAgB,eAAAC,EAAA,IAAkBF,GAEpC,EAAE,MAAMG,GAAQ,WAAWC,EAAA,IAC/BC,EAAaJ,CAAc,GAEvBK,IAAmBH,GAAQ,eAC7BI,EAAoBJ,EAAO,YAAY,IACvC,QAEE,EAAE,QAAQK,GAAW,WAAAC,EAAA,IAAcC,EAAuB;AAAA,IAC9D,WAAW,CAAAC,MAAU;AACnB,MAAIA,EAAO,SAAS,eAClBC,EAAqBD,EAAO,IAAI,IACvBA,EAAO,SAAS,UACzBE,EAAoBF,EAAO,IAAI,IAE/BG,EAAa,mCAAmC,SAAS;AAAA,IAE7D;AAAA,IACA,SAAS,CAAAC,MAAKD,EAAaC,EAAE,SAAS,QAAQ;AAAA,EAAA,CAC/C;AAKD,SACE,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,SAASR;AAAA,MACT,UAAUL;AAAA,MACV,SAAS,MAAM;AACb,QAAAI,EAAU,EAAE,eAAAN,GAAe,gBAAAD,GAAgB,kBAAAK,EAAA,CAAkB;AAAA,MAC/D;AAAA,MACA,SAAQ;AAAA,MAEP,UAXHA,MAAqB,eAAe,iBAAiB;AAAA,IAWlD;AAAA,EAAA;AAGP;AAEA,SAASM,EAAqBD,GAAiC;AAC7D,EAAIA,EAAO,iBAAiB,QAAQA,EAAO,cAAc,WAAW,IAClEG,EAAa,uCAAuC,SAAS,IAE7DA;AAAA,IACE,gBAAAE,EAAC,MAAA,EACE,UAAAL,EAAO,cAAc,IAAI,CAACO,GAAKC,MAC9B,gBAAAH,EAAC,MAAA,EAAgB,UAAAE,EAAA,GAARC,CAAY,CACtB,GACH;AAAA,IACA;AAAA,IACA,EAAE,OAAO,oCAAA;AAAA,EAAoC;AAGnD;AAEA,SAASN,EAAoBF,GAAwC;AACnE,MAAIA,EAAO,SAAS,QAAQ;AAE1B,UAAMS,IAAeT,EAAO,QAAQ,CAAC;AACrC,QAAIU,EAA8BD,CAAY,GAAG;AAE/C,YAAME,IACJC,EAAoCH,CAAY,EAAE,KAAK;AAAA,CAAI;AAE7D,MAAIE,IACFR;AAAA,QACE;AAAA,EAAuCQ,CAAe;AAAA,QACtD;AAAA,MAAA,IAGFR,EAAa,gCAAgC,SAAS;AAAA,IAE1D,WAAWU,EAA8BJ,CAAY,GAAG;AAEtD,YAAMK,IAAiBL,EAAa,eAAe,eAAA;AACnD,MAAAN,EAAa,wBAAwBW,CAAc,UAAU,SAAS;AAAA,IACxE;AAAA,EACF;AACF;AAEA,SAASF,EACPG,GACU;AACV,SACEA,EAAQ,eACJ,OAAO,CAAAX,MAAK,CAAC,CAACA,EAAE,WAAW,EAC5B;AAAA,IACC,CAAAY,MAAK,GAAGA,EAAE,QAAQ,KAAKA,EAAE,cAAc,WAAWA,EAAE,WAAW;AAAA,EAAA,KAC5D,CAAA;AAEX;"}
@@ -1 +1 @@
1
- {"version":3,"file":"SynapseGrid.d.ts","sourceRoot":"","sources":["../../../src/components/DataGrid/SynapseGrid.tsx"],"names":[],"mappings":"AAaA,OAAO,EACL,iBAAiB,EAElB,MAAM,kCAAkC,CAAA;AA0BzC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,cAAc,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACpD,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;CACjD,CAAA;AAED,QAAA,MAAM,WAAW,gHAiahB,CAAA;AAED,eAAe,WAAW,CAAA"}
1
+ {"version":3,"file":"SynapseGrid.d.ts","sourceRoot":"","sources":["../../../src/components/DataGrid/SynapseGrid.tsx"],"names":[],"mappings":"AAaA,OAAO,EACL,iBAAiB,EAElB,MAAM,kCAAkC,CAAA;AA4BzC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,cAAc,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACpD,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;CACjD,CAAA;AAED,QAAA,MAAM,WAAW,gHAudhB,CAAA;AAED,eAAe,WAAW,CAAA"}