synapse-react-client 4.0.6 → 4.0.8

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 (160) hide show
  1. package/dist/SWC.index.js +1 -1
  2. package/dist/components/CardDeck/TableQueryCardDeck.js +3 -4
  3. package/dist/components/CardDeck/TableQueryCardDeck.js.map +1 -1
  4. package/dist/components/ChangePassword/useChangePasswordFormState.js +2 -3
  5. package/dist/components/ChangePassword/useChangePasswordFormState.js.map +1 -1
  6. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.css +1 -0
  7. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.d.ts +8 -0
  8. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.d.ts.map +1 -0
  9. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.js +21 -0
  10. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.js.map +1 -0
  11. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.module.scss +32 -0
  12. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.module.scss.js +14 -0
  13. package/dist/components/ColoredBulletListItem/ColoredBulletListItem.module.scss.js.map +1 -0
  14. package/dist/components/ColoredBulletListItem/index.d.ts +5 -0
  15. package/dist/components/ColoredBulletListItem/index.d.ts.map +1 -0
  16. package/dist/components/ColoredBulletListItem/index.js +6 -0
  17. package/dist/components/ColoredBulletListItem/index.js.map +1 -0
  18. package/dist/components/CreateOrUpdateAccessRequirementWizard/CreateOrUpdateAccessRequirementWizard.js +3 -4
  19. package/dist/components/CreateOrUpdateAccessRequirementWizard/CreateOrUpdateAccessRequirementWizard.js.map +1 -1
  20. package/dist/components/CreateProjectModal/CreateProjectModal.d.ts.map +1 -1
  21. package/dist/components/CreateProjectModal/CreateProjectModal.js +120 -46
  22. package/dist/components/CreateProjectModal/CreateProjectModal.js.map +1 -1
  23. package/dist/components/CreateProjectModal/ProjectVisibilityRadioGroup.d.ts +7 -0
  24. package/dist/components/CreateProjectModal/ProjectVisibilityRadioGroup.d.ts.map +1 -0
  25. package/dist/components/CreateProjectModal/ProjectVisibilityRadioGroup.js +132 -0
  26. package/dist/components/CreateProjectModal/ProjectVisibilityRadioGroup.js.map +1 -0
  27. package/dist/components/DataGrid/DataGrid.d.ts +2 -0
  28. package/dist/components/DataGrid/DataGrid.d.ts.map +1 -1
  29. package/dist/components/DataGrid/DataGrid.js +69 -67
  30. package/dist/components/DataGrid/DataGrid.js.map +1 -1
  31. package/dist/components/DataGrid/DataGridTypes.d.ts +8 -2
  32. package/dist/components/DataGrid/DataGridTypes.d.ts.map +1 -1
  33. package/dist/components/DataGrid/DataGridTypes.js.map +1 -1
  34. package/dist/components/DataGrid/MergeGridWithSourceTableButton.js +2 -3
  35. package/dist/components/DataGrid/MergeGridWithSourceTableButton.js.map +1 -1
  36. package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
  37. package/dist/components/DataGrid/SynapseGrid.js +184 -164
  38. package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
  39. package/dist/components/DataGrid/components/UploadCsvToGridDialog.js +2 -3
  40. package/dist/components/DataGrid/components/UploadCsvToGridDialog.js.map +1 -1
  41. package/dist/components/DataGrid/hooks/useGridReplicaUsers.d.ts +15 -0
  42. package/dist/components/DataGrid/hooks/useGridReplicaUsers.d.ts.map +1 -0
  43. package/dist/components/DataGrid/hooks/useGridReplicaUsers.js +55 -0
  44. package/dist/components/DataGrid/hooks/useGridReplicaUsers.js.map +1 -0
  45. package/dist/components/DataGrid/hooks/useRemoteSelections.d.ts +16 -0
  46. package/dist/components/DataGrid/hooks/useRemoteSelections.d.ts.map +1 -0
  47. package/dist/components/DataGrid/hooks/useRemoteSelections.js +30 -0
  48. package/dist/components/DataGrid/hooks/useRemoteSelections.js.map +1 -0
  49. package/dist/components/DataGrid/utils/DataGridUtils.js +31 -31
  50. package/dist/components/DataGrid/utils/DataGridUtils.js.map +1 -1
  51. package/dist/components/DataGrid/utils/applyModelChange.d.ts +1 -1
  52. package/dist/components/DataGrid/utils/applyModelChange.d.ts.map +1 -1
  53. package/dist/components/DataGrid/utils/applyModelChange.js +28 -23
  54. package/dist/components/DataGrid/utils/applyModelChange.js.map +1 -1
  55. package/dist/components/DataGrid/utils/columnFactory.d.ts.map +1 -1
  56. package/dist/components/DataGrid/utils/columnFactory.js +90 -49
  57. package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
  58. package/dist/components/DataGrid/utils/enrichRowsWithChangeInfo.d.ts +14 -0
  59. package/dist/components/DataGrid/utils/enrichRowsWithChangeInfo.d.ts.map +1 -0
  60. package/dist/components/DataGrid/utils/enrichRowsWithChangeInfo.js +24 -0
  61. package/dist/components/DataGrid/utils/enrichRowsWithChangeInfo.js.map +1 -0
  62. package/dist/components/DataGrid/utils/getCellAuthorSid.d.ts +7 -0
  63. package/dist/components/DataGrid/utils/getCellAuthorSid.d.ts.map +1 -0
  64. package/dist/components/DataGrid/utils/getCellAuthorSid.js +11 -0
  65. package/dist/components/DataGrid/utils/getCellAuthorSid.js.map +1 -0
  66. package/dist/components/DataGrid/utils/getCellClassName.d.ts +2 -0
  67. package/dist/components/DataGrid/utils/getCellClassName.d.ts.map +1 -1
  68. package/dist/components/DataGrid/utils/getCellClassName.js +23 -12
  69. package/dist/components/DataGrid/utils/getCellClassName.js.map +1 -1
  70. package/dist/components/DataGrid/utils/getChangeTooltipText.d.ts +7 -0
  71. package/dist/components/DataGrid/utils/getChangeTooltipText.d.ts.map +1 -0
  72. package/dist/components/DataGrid/utils/getChangeTooltipText.js +18 -0
  73. package/dist/components/DataGrid/utils/getChangeTooltipText.js.map +1 -0
  74. package/dist/components/DataGrid/utils/getReplicaCategory.d.ts +12 -0
  75. package/dist/components/DataGrid/utils/getReplicaCategory.d.ts.map +1 -0
  76. package/dist/components/DataGrid/utils/getReplicaCategory.js +13 -0
  77. package/dist/components/DataGrid/utils/getReplicaCategory.js.map +1 -0
  78. package/dist/components/DataGrid/utils/replicaSelectionToGridSelection.d.ts +15 -0
  79. package/dist/components/DataGrid/utils/replicaSelectionToGridSelection.d.ts.map +1 -0
  80. package/dist/components/DataGrid/utils/replicaSelectionToGridSelection.js +43 -0
  81. package/dist/components/DataGrid/utils/replicaSelectionToGridSelection.js.map +1 -0
  82. package/dist/components/DialogBase.d.ts +3 -1
  83. package/dist/components/DialogBase.d.ts.map +1 -1
  84. package/dist/components/DialogBase.js +75 -56
  85. package/dist/components/DialogBase.js.map +1 -1
  86. package/dist/components/Ecosystem/EcosystemSkeleton.js +2 -3
  87. package/dist/components/Ecosystem/EcosystemSkeleton.js.map +1 -1
  88. package/dist/components/FeaturedDataTabs/FacetPlotsCard.js +2 -3
  89. package/dist/components/FeaturedDataTabs/FacetPlotsCard.js.map +1 -1
  90. package/dist/components/FeaturedDataTabs/FeaturedDataTabs.js +2 -3
  91. package/dist/components/FeaturedDataTabs/FeaturedDataTabs.js.map +1 -1
  92. package/dist/components/GenericCard/GenericCard.js +3 -4
  93. package/dist/components/GenericCard/GenericCard.js.map +1 -1
  94. package/dist/components/HeaderCard.js +2 -3
  95. package/dist/components/HeaderCard.js.map +1 -1
  96. package/dist/components/IconSvg/IconSvg.d.ts +1 -1
  97. package/dist/components/IconSvg/IconSvg.d.ts.map +1 -1
  98. package/dist/components/IconSvg/IconSvg.js +168 -165
  99. package/dist/components/IconSvg/IconSvg.js.map +1 -1
  100. package/dist/components/StorybookComponentWrapper.js +3 -4
  101. package/dist/components/StorybookComponentWrapper.js.map +1 -1
  102. package/dist/components/SynapseForm/SynapseFormSubmissionGrid.d.ts +1 -0
  103. package/dist/components/SynapseForm/SynapseFormSubmissionGrid.d.ts.map +1 -1
  104. package/dist/components/SynapseForm/SynapseFormSubmissionGrid.js +23 -16
  105. package/dist/components/SynapseForm/SynapseFormSubmissionGrid.js.map +1 -1
  106. package/dist/components/TextField/TextField.css +1 -1
  107. package/dist/components/TextField/TextField.d.ts +1 -0
  108. package/dist/components/TextField/TextField.d.ts.map +1 -1
  109. package/dist/components/TextField/TextField.js +32 -20
  110. package/dist/components/TextField/TextField.js.map +1 -1
  111. package/dist/components/TextField/TextField.module.scss +7 -0
  112. package/dist/components/TextField/TextField.module.scss.js +5 -3
  113. package/dist/components/TextField/TextField.module.scss.js.map +1 -1
  114. package/dist/components/download_list/AddToDownloadListConfirmationAlert/AddToDownloadListConfirmationAlert.js +2 -3
  115. package/dist/components/download_list/AddToDownloadListConfirmationAlert/AddToDownloadListConfirmationAlert.js.map +1 -1
  116. package/dist/components/index.d.ts +1 -0
  117. package/dist/components/index.d.ts.map +1 -1
  118. package/dist/components/index.js +242 -240
  119. package/dist/components/index.js.map +1 -1
  120. package/dist/components/styled/StyledFormControl.js +1 -1
  121. package/dist/components/styled/StyledFormControl.js.map +1 -1
  122. package/dist/components/table/CsvPreview/CsvPreview.js +2 -3
  123. package/dist/components/table/CsvPreview/CsvPreview.js.map +1 -1
  124. package/dist/components/table/CsvPreview/CsvPreviewDialog.js +2 -3
  125. package/dist/components/table/CsvPreview/CsvPreviewDialog.js.map +1 -1
  126. package/dist/features/curator/GridPage/GridPage.js +2 -3
  127. package/dist/features/curator/GridPage/GridPage.js.map +1 -1
  128. package/dist/features/curator/GridPage/components/GridPageTitle.js +2 -3
  129. package/dist/features/curator/GridPage/components/GridPageTitle.js.map +1 -1
  130. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.d.ts.map +1 -1
  131. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js +49 -180
  132. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js.map +1 -1
  133. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js +2 -3
  134. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js.map +1 -1
  135. package/dist/features/entity/metadata-task/utils/getCreateGridRequestForMetadataTask.d.ts.map +1 -1
  136. package/dist/features/entity/metadata-task/utils/getCreateGridRequestForMetadataTask.js +4 -8
  137. package/dist/features/entity/metadata-task/utils/getCreateGridRequestForMetadataTask.js.map +1 -1
  138. package/dist/index.js +306 -304
  139. package/dist/index.js.map +1 -1
  140. package/dist/style/components/_data-grid-extra.css +1 -1
  141. package/dist/style/components/_data-grid-extra.scss +49 -0
  142. package/dist/synapse-client/SynapseClient.d.ts +1 -1
  143. package/dist/synapse-client/SynapseClient.d.ts.map +1 -1
  144. package/dist/synapse-client/SynapseClient.js +3 -2
  145. package/dist/synapse-client/SynapseClient.js.map +1 -1
  146. package/dist/synapse-queries/index.js +42 -41
  147. package/dist/synapse-queries/user/index.js +17 -16
  148. package/dist/synapse-queries/user/useUserBundle.d.ts +9 -0
  149. package/dist/synapse-queries/user/useUserBundle.d.ts.map +1 -1
  150. package/dist/synapse-queries/user/useUserBundle.js +45 -37
  151. package/dist/synapse-queries/user/useUserBundle.js.map +1 -1
  152. package/dist/theme/palette/Palettes.d.ts +2 -0
  153. package/dist/theme/palette/Palettes.d.ts.map +1 -1
  154. package/dist/theme/palette/Palettes.js +46 -40
  155. package/dist/theme/palette/Palettes.js.map +1 -1
  156. package/dist/tsconfig.build.tsbuildinfo +1 -1
  157. package/package.json +3 -3
  158. package/dist/assets/ArcusBioIcon.svg +0 -1
  159. package/dist/assets/ArcusBioIcon.svg.js +0 -7
  160. package/dist/assets/ArcusBioIcon.svg.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"SynapseGrid.js","sources":["../../../src/components/DataGrid/SynapseGrid.tsx"],"sourcesContent":["import GridMenuButton from '@/components/DataGrid/components/GridMenuButton/GridMenuButton'\nimport UploadCsvToGridButton from '@/components/DataGrid/components/UploadCsvToGridButton'\nimport ExportCsvFromGridButton from '@/components/DataGrid/components/ExportCsvFromGridButton'\nimport useGetSchemaForGrid from '@/components/DataGrid/hooks/useGetSchemaForGrid'\nimport MergeGridWithSourceTableButton from '@/components/DataGrid/MergeGridWithSourceTableButton'\nimport computeReplicaSelectionModel from '@/components/DataGrid/utils/computeReplicaSelectionModel'\nimport modelRowsToGrid from '@/components/DataGrid/utils/modelRowsToGrid'\nimport { SkeletonTable } from '@/components/index'\nimport { useGetEntity } from '@/synapse-queries/index'\nimport { getSchemaPropertiesInfo } from '@/utils/jsonschema/getSchemaPropertyInfo'\nimport { SmartToyTwoTone } from '@mui/icons-material'\nimport { Stack, Tooltip } from '@mui/material'\nimport Grid from '@mui/material/Grid'\nimport {\n CreateGridRequest,\n GridSession,\n} from '@sage-bionetworks/synapse-client'\nimport { ClickableJsonCrdt } from 'clickable-json'\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { DataSheetGridRef } from '@sage-bionetworks/react-datasheet-grid'\nimport { SelectionWithId } from '@sage-bionetworks/react-datasheet-grid'\nimport GridAgentChat from '../SynapseChat/GridAgentChat'\nimport DataGrid from './DataGrid'\nimport { DataGridRow, GridModel, Operation } from './DataGridTypes'\nimport { useGridUndoRedo } from './hooks/useGridUndoRedo'\nimport { StartGridSession, StartGridSessionHandle } from './StartGridSession'\nimport { useDataGridWebSocket } from './useDataGridWebsocket'\nimport { applyModelChange, ModelChange } from './utils/applyModelChange'\nimport { removeNoOpOperations } from './utils/DataGridUtils'\nimport { mapOperationsToModelChanges } from './utils/mapOperationsToModelChanges'\nimport { useGetCurrentUserBundle } from '@/synapse-queries'\nimport { useListGridReplicas } from '@/synapse-queries/grid/useGridSession'\nimport CertificationRequirement from '@/components/AccessRequirementList/RequirementItem/CertificationRequirement'\nimport { ValidationAlert } from './components/ValidationAlert'\n\nexport type SynapseGridProps = {\n agentRegistrationId?: string\n showDebugInfo?: boolean\n}\n\nexport type SynapseGridHandle = {\n initializeGrid: (request: CreateGridRequest) => void\n loadExistingSession: (sessionId: string) => void\n}\n\nconst SynapseGrid = forwardRef<SynapseGridHandle, SynapseGridProps>(\n ({ agentRegistrationId, showDebugInfo = false }, ref) => {\n const [session, setSession] = useState<GridSession | null>(null)\n const [replicaId, setReplicaId] = useState<number | null>(null)\n const [chatOpen, setChatOpen] = useState(false)\n const [lastSelection, setLastSelection] = useState<SelectionWithId | null>(\n null,\n )\n\n const startGridSessionRef = useRef<StartGridSessionHandle | null>(null)\n const gridRef = useRef<DataSheetGridRef | null>(null)\n\n const { data: userBundle, isLoading } = useGetCurrentUserBundle()\n\n const { data: replicas = [], refetch: refetchReplicas } =\n useListGridReplicas(session?.sessionId)\n\n const handleReplicaConnectionChange = useCallback(() => {\n void refetchReplicas()\n }, [refetchReplicas])\n\n useImperativeHandle(\n ref,\n () => ({\n initializeGrid: (request: CreateGridRequest) => {\n if (startGridSessionRef.current) {\n startGridSessionRef.current.handleStartSession(request)\n }\n },\n loadExistingSession: (sessionId: string) => {\n if (startGridSessionRef.current) {\n startGridSessionRef.current.handleLoadSession(sessionId)\n }\n },\n }),\n [],\n )\n\n // WebSocket state\n const {\n isConnected,\n websocketInstance,\n hasCompletedInitialSync,\n model,\n modelSnapshot,\n connect,\n presignedUrl,\n hasSufficientData,\n } = useDataGridWebSocket({\n onGridReady: handleReplicaConnectionChange,\n onReplicaConnected: handleReplicaConnectionChange,\n onReplicaDisconnected: handleReplicaConnectionChange,\n })\n\n const websocketInstanceRef = useRef<typeof websocketInstance | null>(null)\n\n useEffect(() => {\n websocketInstanceRef.current = websocketInstance\n }, [websocketInstance])\n\n // Track last connection parameters to avoid redundant connections\n const lastConnectParamsRef = useRef<{\n replicaId: number\n sessionId: string\n } | null>(null)\n\n useEffect(() => {\n if (\n replicaId === null ||\n replicaId === undefined ||\n !session?.sessionId\n ) {\n lastConnectParamsRef.current = null\n return\n }\n\n const nextParams = {\n replicaId,\n sessionId: session.sessionId,\n }\n\n const prevParams = lastConnectParamsRef.current\n\n if (\n prevParams &&\n prevParams.replicaId === nextParams.replicaId &&\n prevParams.sessionId === nextParams.sessionId\n ) {\n return\n }\n\n lastConnectParamsRef.current = nextParams\n connect(replicaId, session.sessionId)\n }, [replicaId, session?.sessionId, connect])\n\n // Reset grid state when model is reset (new session/replica)\n useEffect(() => {\n if (model === null) {\n // Clear any grid-specific state when starting a new session\n setLastSelection(null)\n // Clear active cell if grid exists\n if (gridRef.current) {\n gridRef.current.setActiveCell(null)\n }\n }\n }, [model])\n\n const jsonSchema = useGetSchemaForGrid(session)\n\n // Grid behaves differently for views vs recordSets\n // Note for future: can get modifiedOn to refresh grid when view changes\n const { data: entityData } = useGetEntity(\n session?.sourceEntityId,\n undefined,\n {\n enabled: !!session?.sourceEntityId,\n },\n )\n\n const entityIsView =\n entityData?.concreteType ===\n 'org.sagebionetworks.repo.model.table.EntityView'\n\n // Process schema properties once\n const schemaPropertiesInfo = useMemo(() => {\n return getSchemaPropertiesInfo(jsonSchema ?? null)\n }, [jsonSchema])\n\n const connectionStatus = isConnected ? 'Connected' : 'Disconnected'\n\n // Transform the model view rows and columns to DataSheetGrid format\n const rowValues = useMemo(\n () => (modelSnapshot ? modelRowsToGrid(model, modelSnapshot) : []),\n [model, modelSnapshot],\n )\n\n const commit = useCallback(() => {\n if (!isConnected || !websocketInstanceRef.current) {\n return\n }\n\n websocketInstanceRef.current.sendPatch()\n }, [isConnected, websocketInstanceRef])\n\n useEffect(() => {\n if (isConnected) {\n commit()\n }\n }, [isConnected, commit])\n\n const applyAndCommitChanges = useCallback(\n (model: GridModel, modelChanges: ModelChange[]) => {\n // Apply each change to the model\n modelChanges.forEach(change => {\n applyModelChange(model, change, schemaPropertiesInfo)\n })\n\n commit()\n },\n [commit, schemaPropertiesInfo],\n )\n\n const applyModelChangeFromUndoRedo = useCallback(\n (change: ModelChange) => {\n if (!model) {\n console.error('Model is not initialized')\n return\n }\n\n if (change.type === 'DELETE' && gridRef.current) {\n // The user may have set a cell as active that we are removing with an 'undo'. In that case, clear the active state\n gridRef.current.setActiveCell(null)\n }\n\n applyAndCommitChanges(model, [change])\n },\n [model, applyAndCommitChanges],\n )\n\n const { undoUI, redoUI, addOperationsToUndoStack, clearRedoStack } =\n useGridUndoRedo(applyModelChangeFromUndoRedo)\n\n const handleChange = useCallback(\n (newValue: DataGridRow[], operations: Operation[]) => {\n if (!model) {\n console.error('Model is not initialized')\n return\n }\n\n // Check that something changed before updating the model\n operations = removeNoOpOperations(newValue, rowValues, operations)\n\n if (operations.length > 0) {\n // Clear redo stack since new changes invalidate redo history\n clearRedoStack()\n\n // Track row creation, updates, and deletions to keep UI state and undo history in sync\n\n // Add all operations to the undo stack\n addOperationsToUndoStack(operations, rowValues, newValue)\n\n // Transform operations to model changes\n const modelChanges = mapOperationsToModelChanges(operations, newValue)\n\n applyAndCommitChanges(model, modelChanges)\n }\n },\n [\n model,\n rowValues,\n clearRedoStack,\n addOperationsToUndoStack,\n applyAndCommitChanges,\n ],\n )\n\n const handleSelectionChange = useCallback(\n (opts: { selection: SelectionWithId | null }) => {\n const { selection } = opts\n if (selection != null) {\n setLastSelection(selection)\n\n if (model != null && replicaId != null) {\n const replicaSelectionModel = computeReplicaSelectionModel(\n selection,\n model,\n )\n // insert it into the CRDT Model\n applyAndCommitChanges(model, [\n {\n type: 'SET_SELECTION',\n replicaId: replicaId.toString(),\n selection: replicaSelectionModel,\n },\n ])\n }\n }\n },\n [applyAndCommitChanges, model, replicaId],\n )\n\n // Track selected row index for validation display\n const selectedRowIndexRef = useRef<number | null>(null)\n const [, forceUpdate] = useState({})\n\n const handleSelectedRowChange = useCallback(\n (rowIndex: number | null, _row: DataGridRow | null) => {\n // Only update when a real row is selected — don't clear on blur/click-away\n // so the ValidationAlert stays open while the user interacts with it.\n if (rowIndex !== null) {\n selectedRowIndexRef.current = rowIndex\n forceUpdate({})\n }\n },\n [],\n )\n\n if (!isLoading && !userBundle?.isCertified) {\n return <CertificationRequirement />\n }\n\n return (\n <div>\n <Grid container spacing={2}>\n <Grid size={{ xs: 12, xl: 8 }}>\n <StartGridSession\n ref={startGridSessionRef}\n onSessionChange={setSession}\n onReplicaChange={setReplicaId}\n show={showDebugInfo}\n />\n </Grid>\n {/* Debug Information */}\n <Grid size={{ xs: 12, xl: 4 }}>\n {showDebugInfo && (\n <div>\n <p>Session ID: {session?.sessionId || 'No session created'}</p>\n <p>Replica ID: {replicaId || 'No replica created'}</p>\n <p>\n Source Entity ID:{' '}\n {session?.sourceEntityId || 'No source entity'}\n </p>\n <p>\n JSON Schema $id:{' '}\n {session?.gridJsonSchema$Id ||\n 'No schema attached to session'}\n </p>\n <p>\n Presigned URL:{' '}\n {presignedUrl\n ? presignedUrl.substring(0, 30) +\n (presignedUrl.length > 30\n ? ' ... ' +\n presignedUrl.substring(presignedUrl.length - 10)\n : '')\n : 'No URL generated'}\n </p>\n <p>\n WebSocket Status:{' '}\n <span style={{ color: isConnected ? 'green' : 'red' }}>\n {connectionStatus}\n </span>\n </p>\n <p>\n {(() => {\n const connectedReplicas = replicas.filter(\n r => r.isConnected,\n )\n return (\n <>\n Connected Replicas ({connectedReplicas.length} /{' '}\n {replicas.length} total):{' '}\n {connectedReplicas.length === 0\n ? 'none'\n : connectedReplicas.map((r, i) => (\n <Tooltip\n key={r.replicaId}\n title={\n <pre style={{ margin: 0, fontSize: '11px' }}>\n {JSON.stringify(r, null, 2)}\n </pre>\n }\n >\n <span\n style={{\n cursor: 'pointer',\n textDecoration: 'underline dotted',\n }}\n >\n {r.replicaId}\n {i < connectedReplicas.length - 1 ? ', ' : ''}\n </span>\n </Tooltip>\n ))}\n </>\n )\n })()}\n </p>\n </div>\n )}\n </Grid>\n\n {session && (\n <>\n {/* Grid Loading State */}\n {!hasSufficientData && (\n <Grid size={12}>\n <h3>Setting up grid...</h3>\n <div style={{ marginBottom: '10px' }}>\n {!session && <p>Creating grid session...</p>}\n {session && !replicaId && (\n <p>Setting up real-time sync...</p>\n )}\n {session && replicaId && !presignedUrl && (\n <p>Establishing secure connection...</p>\n )}\n {session && replicaId && presignedUrl && !isConnected && (\n <p>Connecting to server...</p>\n )}\n {isConnected && !hasCompletedInitialSync && (\n <p>Loading table data...</p>\n )}\n <SkeletonTable numRows={4} numCols={1} />\n </div>\n </Grid>\n )}\n {/* Grid */}\n {hasSufficientData && (\n <>\n <Grid size={12}>\n <Stack\n direction={'row'}\n spacing={1}\n sx={{ justifyContent: 'flex-end' }}\n >\n {undoUI}\n {redoUI}\n <GridMenuButton\n variant={'outlined'}\n onClick={() => setChatOpen(true)}\n startIcon={<SmartToyTwoTone />}\n >\n Open chat\n </GridMenuButton>\n <GridAgentChat\n agentRegistrationId={agentRegistrationId}\n open={chatOpen}\n onClose={() => setChatOpen(false)}\n gridSessionId={session.sessionId!}\n usersReplicaId={replicaId!}\n chatbotName=\"Grid Assistant\"\n />\n {session.sourceEntityId && (\n <UploadCsvToGridButton\n sourceEntityId={session.sourceEntityId}\n gridSessionId={session.sessionId!}\n />\n )}\n {session.sessionId && (\n <ExportCsvFromGridButton\n gridSessionId={session.sessionId}\n filename={\n 'grid-' + (session.sourceEntityId || 'export')\n }\n />\n )}\n {session.sourceEntityId && (\n <MergeGridWithSourceTableButton\n sourceEntityId={session.sourceEntityId}\n gridSessionId={session.sessionId!}\n />\n )}\n </Stack>\n </Grid>\n <Grid size={12}>\n <DataGrid\n gridRef={gridRef}\n rowValues={rowValues}\n columnNames={modelSnapshot?.columnNames ?? []}\n columnOrder={modelSnapshot?.columnOrder ?? []}\n schemaPropertiesInfo={schemaPropertiesInfo}\n entityIsView={entityIsView}\n jsonSchema={jsonSchema}\n lastSelection={lastSelection}\n handleChange={handleChange}\n handleSelectionChange={handleSelectionChange}\n onSelectedRowChange={handleSelectedRowChange}\n />\n </Grid>\n <Grid size={12}>\n <ValidationAlert\n selectedRowIndex={selectedRowIndexRef.current}\n rowValues={rowValues}\n />\n </Grid>\n </>\n )}\n {/* Debug Model Snapshot */}\n {showDebugInfo && (\n <Grid\n size={12}\n style={{\n margin: '10px 0',\n padding: '10px',\n border: '1px solid #ccc',\n maxHeight: '400px',\n overflowY: 'auto',\n }}\n >\n <h3>Model</h3>\n {model ? (\n <ClickableJsonCrdt model={model} />\n ) : (\n 'No model available'\n )}\n </Grid>\n )}\n </>\n )}\n </Grid>\n </div>\n )\n },\n)\n\nexport default SynapseGrid\n"],"names":["SynapseGrid","forwardRef","agentRegistrationId","showDebugInfo","ref","session","setSession","useState","replicaId","setReplicaId","chatOpen","setChatOpen","lastSelection","setLastSelection","startGridSessionRef","useRef","gridRef","userBundle","isLoading","useGetCurrentUserBundle","replicas","refetchReplicas","useListGridReplicas","handleReplicaConnectionChange","useCallback","useImperativeHandle","request","sessionId","isConnected","websocketInstance","hasCompletedInitialSync","model","modelSnapshot","connect","presignedUrl","hasSufficientData","useDataGridWebSocket","websocketInstanceRef","useEffect","lastConnectParamsRef","nextParams","prevParams","jsonSchema","useGetSchemaForGrid","entityData","useGetEntity","entityIsView","schemaPropertiesInfo","useMemo","getSchemaPropertiesInfo","connectionStatus","rowValues","modelRowsToGrid","commit","applyAndCommitChanges","modelChanges","change","applyModelChange","applyModelChangeFromUndoRedo","undoUI","redoUI","addOperationsToUndoStack","clearRedoStack","useGridUndoRedo","handleChange","newValue","operations","removeNoOpOperations","mapOperationsToModelChanges","handleSelectionChange","opts","selection","replicaSelectionModel","computeReplicaSelectionModel","selectedRowIndexRef","forceUpdate","handleSelectedRowChange","rowIndex","_row","CertificationRequirement","jsxs","Grid","jsx","StartGridSession","connectedReplicas","Fragment","i","Tooltip","SkeletonTable","Stack","GridMenuButton","SmartToyTwoTone","GridAgentChat","UploadCsvToGridButton","ExportCsvFromGridButton","MergeGridWithSourceTableButton","DataGrid","ValidationAlert","ClickableJsonCrdt"],"mappings":"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"}
1
+ {"version":3,"file":"SynapseGrid.js","sources":["../../../src/components/DataGrid/SynapseGrid.tsx"],"sourcesContent":["import GridMenuButton from '@/components/DataGrid/components/GridMenuButton/GridMenuButton'\nimport UploadCsvToGridButton from '@/components/DataGrid/components/UploadCsvToGridButton'\nimport ExportCsvFromGridButton from '@/components/DataGrid/components/ExportCsvFromGridButton'\nimport useGetSchemaForGrid from '@/components/DataGrid/hooks/useGetSchemaForGrid'\nimport MergeGridWithSourceTableButton from '@/components/DataGrid/MergeGridWithSourceTableButton'\nimport computeReplicaSelectionModel from '@/components/DataGrid/utils/computeReplicaSelectionModel'\nimport modelRowsToGrid from '@/components/DataGrid/utils/modelRowsToGrid'\nimport { SkeletonTable } from '@/components/index'\nimport { useGetEntity } from '@/synapse-queries/index'\nimport { getSchemaPropertiesInfo } from '@/utils/jsonschema/getSchemaPropertyInfo'\nimport { SmartToyTwoTone } from '@mui/icons-material'\nimport { Stack, Tooltip } from '@mui/material'\nimport Grid from '@mui/material/Grid'\nimport {\n CreateGridRequest,\n GridSession,\n} from '@sage-bionetworks/synapse-client'\nimport { ClickableJsonCrdt } from 'clickable-json'\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { DataSheetGridRef } from '@sage-bionetworks/react-datasheet-grid'\nimport { SelectionWithId } from '@sage-bionetworks/react-datasheet-grid'\nimport GridAgentChat from '../SynapseChat/GridAgentChat'\nimport DataGrid from './DataGrid'\nimport { DataGridRow, GridModel, Operation } from './DataGridTypes'\nimport { useGridUndoRedo } from './hooks/useGridUndoRedo'\nimport { StartGridSession, StartGridSessionHandle } from './StartGridSession'\nimport { useDataGridWebSocket } from './useDataGridWebsocket'\nimport { applyModelChange, ModelChange } from './utils/applyModelChange'\nimport { removeNoOpOperations } from './utils/DataGridUtils'\nimport { mapOperationsToModelChanges } from './utils/mapOperationsToModelChanges'\nimport { useGetCurrentUserBundle } from '@/synapse-queries'\nimport { useListGridReplicas } from '@/synapse-queries/grid/useGridSession'\nimport { useGridReplicaUsers } from './hooks/useGridReplicaUsers'\nimport { useRemoteSelections } from './hooks/useRemoteSelections'\nimport { enrichRowsWithChangeInfo } from './utils/enrichRowsWithChangeInfo'\nimport CertificationRequirement from '@/components/AccessRequirementList/RequirementItem/CertificationRequirement'\nimport { ValidationAlert } from './components/ValidationAlert'\n\nexport type SynapseGridProps = {\n agentRegistrationId?: string\n showDebugInfo?: boolean\n}\n\nexport type SynapseGridHandle = {\n initializeGrid: (request: CreateGridRequest) => void\n loadExistingSession: (sessionId: string) => void\n}\n\nconst SynapseGrid = forwardRef<SynapseGridHandle, SynapseGridProps>(\n ({ agentRegistrationId, showDebugInfo = false }, ref) => {\n const [session, setSession] = useState<GridSession | null>(null)\n const [replicaId, setReplicaId] = useState<number | null>(null)\n const [chatOpen, setChatOpen] = useState(false)\n const [lastSelection, setLastSelection] = useState<SelectionWithId | null>(\n null,\n )\n\n const startGridSessionRef = useRef<StartGridSessionHandle | null>(null)\n const gridRef = useRef<DataSheetGridRef | null>(null)\n\n const { data: userBundle, isLoading } = useGetCurrentUserBundle()\n\n const { data: replicas = [], refetch: refetchReplicas } =\n useListGridReplicas(session?.sessionId)\n\n const handleReplicaConnectionChange = useCallback(() => {\n void refetchReplicas()\n }, [refetchReplicas])\n\n // ── Attribution infrastructure ─────────────────────────────────────────\n const currentUserId =\n userBundle?.userId != null ? String(userBundle.userId) : undefined\n\n const replicaUserMap = useGridReplicaUsers(\n replicas,\n replicaId,\n currentUserId,\n )\n\n useImperativeHandle(\n ref,\n () => ({\n initializeGrid: (request: CreateGridRequest) => {\n if (startGridSessionRef.current) {\n startGridSessionRef.current.handleStartSession(request)\n }\n },\n loadExistingSession: (sessionId: string) => {\n if (startGridSessionRef.current) {\n startGridSessionRef.current.handleLoadSession(sessionId)\n }\n },\n }),\n [],\n )\n\n // WebSocket state\n const {\n isConnected,\n websocketInstance,\n hasCompletedInitialSync,\n model,\n modelSnapshot,\n connect,\n presignedUrl,\n hasSufficientData,\n } = useDataGridWebSocket({\n onGridReady: handleReplicaConnectionChange,\n onReplicaConnected: handleReplicaConnectionChange,\n onReplicaDisconnected: handleReplicaConnectionChange,\n })\n\n const websocketInstanceRef = useRef<typeof websocketInstance | null>(null)\n\n useEffect(() => {\n websocketInstanceRef.current = websocketInstance\n }, [websocketInstance])\n\n // Track last connection parameters to avoid redundant connections\n const lastConnectParamsRef = useRef<{\n replicaId: number\n sessionId: string\n } | null>(null)\n\n useEffect(() => {\n if (\n replicaId === null ||\n replicaId === undefined ||\n !session?.sessionId\n ) {\n lastConnectParamsRef.current = null\n return\n }\n\n const nextParams = {\n replicaId,\n sessionId: session.sessionId,\n }\n\n const prevParams = lastConnectParamsRef.current\n\n if (\n prevParams &&\n prevParams.replicaId === nextParams.replicaId &&\n prevParams.sessionId === nextParams.sessionId\n ) {\n return\n }\n\n lastConnectParamsRef.current = nextParams\n connect(replicaId, session.sessionId)\n }, [replicaId, session?.sessionId, connect])\n\n // Reset grid state when model is reset (new session/replica)\n useEffect(() => {\n if (model === null) {\n // Clear any grid-specific state when starting a new session\n setLastSelection(null)\n // Clear active cell if grid exists\n if (gridRef.current) {\n gridRef.current.setActiveCell(null)\n }\n }\n }, [model])\n\n const jsonSchema = useGetSchemaForGrid(session)\n\n // Grid behaves differently for views vs recordSets\n // Note for future: can get modifiedOn to refresh grid when view changes\n const { data: entityData } = useGetEntity(\n session?.sourceEntityId,\n undefined,\n {\n enabled: !!session?.sourceEntityId,\n },\n )\n\n const entityIsView =\n entityData?.concreteType ===\n 'org.sagebionetworks.repo.model.table.EntityView'\n\n // Process schema properties once\n const schemaPropertiesInfo = useMemo(() => {\n return getSchemaPropertiesInfo(jsonSchema ?? null)\n }, [jsonSchema])\n\n const connectionStatus = isConnected ? 'Connected' : 'Disconnected'\n\n const remoteSelections = useRemoteSelections(\n modelSnapshot,\n model,\n replicas,\n replicaId,\n )\n\n // Transform the model view rows and columns to DataSheetGrid format\n const rowValues = useMemo(\n () => (modelSnapshot ? modelRowsToGrid(model, modelSnapshot) : []),\n [model, modelSnapshot],\n )\n\n // Enrich rows with per-cell change attribution for CSS indicators and tooltips\n const enrichedRowValues = useMemo(\n () =>\n enrichRowsWithChangeInfo(\n rowValues,\n model,\n modelSnapshot,\n replicaUserMap,\n ),\n [rowValues, model, modelSnapshot, replicaUserMap],\n )\n\n const commit = useCallback(() => {\n if (!isConnected || !websocketInstanceRef.current) {\n return\n }\n\n websocketInstanceRef.current.sendPatch()\n }, [isConnected, websocketInstanceRef])\n\n useEffect(() => {\n if (isConnected) {\n commit()\n }\n }, [isConnected, commit])\n\n const applyAndCommitChanges = useCallback(\n (model: GridModel, modelChanges: ModelChange[]) => {\n // Apply each change to the model\n modelChanges.forEach(change => {\n applyModelChange(model, change, schemaPropertiesInfo)\n })\n\n commit()\n },\n [commit, schemaPropertiesInfo],\n )\n\n const applyModelChangeFromUndoRedo = useCallback(\n (change: ModelChange) => {\n if (!model) {\n console.error('Model is not initialized')\n return\n }\n\n if (change.type === 'DELETE' && gridRef.current) {\n // The user may have set a cell as active that we are removing with an 'undo'. In that case, clear the active state\n gridRef.current.setActiveCell(null)\n }\n\n applyAndCommitChanges(model, [change])\n },\n [model, applyAndCommitChanges],\n )\n\n const { undoUI, redoUI, addOperationsToUndoStack, clearRedoStack } =\n useGridUndoRedo(applyModelChangeFromUndoRedo)\n\n const handleChange = useCallback(\n (newValue: DataGridRow[], operations: Operation[]) => {\n if (!model) {\n console.error('Model is not initialized')\n return\n }\n\n // Check that something changed before updating the model\n operations = removeNoOpOperations(newValue, rowValues, operations)\n\n if (operations.length > 0) {\n // Clear redo stack since new changes invalidate redo history\n clearRedoStack()\n\n // Track row creation, updates, and deletions to keep UI state and undo history in sync\n\n // Add all operations to the undo stack\n addOperationsToUndoStack(operations, rowValues, newValue)\n\n // Transform operations to model changes\n const modelChanges = mapOperationsToModelChanges(operations, newValue)\n\n applyAndCommitChanges(model, modelChanges)\n }\n },\n [\n model,\n rowValues,\n clearRedoStack,\n addOperationsToUndoStack,\n applyAndCommitChanges,\n ],\n )\n\n const handleSelectionChange = useCallback(\n (opts: { selection: SelectionWithId | null }) => {\n const { selection } = opts\n if (selection != null) {\n setLastSelection(selection)\n\n if (model != null && replicaId != null) {\n const replicaSelectionModel = computeReplicaSelectionModel(\n selection,\n model,\n )\n // insert it into the CRDT Model\n applyAndCommitChanges(model, [\n {\n type: 'SET_SELECTION',\n replicaId: replicaId.toString(),\n selection: replicaSelectionModel,\n },\n ])\n }\n }\n },\n [applyAndCommitChanges, model, replicaId],\n )\n\n // Track selected row index for validation display\n const selectedRowIndexRef = useRef<number | null>(null)\n const [, forceUpdate] = useState({})\n\n const handleSelectedRowChange = useCallback(\n (rowIndex: number | null, _row: DataGridRow | null) => {\n // Only update when a real row is selected — don't clear on blur/click-away\n // so the ValidationAlert stays open while the user interacts with it.\n if (rowIndex !== null) {\n selectedRowIndexRef.current = rowIndex\n forceUpdate({})\n }\n },\n [],\n )\n\n if (!isLoading && !userBundle?.isCertified) {\n return <CertificationRequirement />\n }\n\n return (\n <div>\n <Grid container spacing={2}>\n <Grid size={{ xs: 12, xl: 8 }}>\n <StartGridSession\n ref={startGridSessionRef}\n onSessionChange={setSession}\n onReplicaChange={setReplicaId}\n show={showDebugInfo}\n />\n </Grid>\n {/* Debug Information */}\n <Grid size={{ xs: 12, xl: 4 }}>\n {showDebugInfo && (\n <div>\n <p>Session ID: {session?.sessionId || 'No session created'}</p>\n <p>Replica ID: {replicaId || 'No replica created'}</p>\n <p>\n Source Entity ID:{' '}\n {session?.sourceEntityId || 'No source entity'}\n </p>\n <p>\n JSON Schema $id:{' '}\n {session?.gridJsonSchema$Id ||\n 'No schema attached to session'}\n </p>\n <p>\n Presigned URL:{' '}\n {presignedUrl\n ? presignedUrl.substring(0, 30) +\n (presignedUrl.length > 30\n ? ' ... ' +\n presignedUrl.substring(presignedUrl.length - 10)\n : '')\n : 'No URL generated'}\n </p>\n <p>\n WebSocket Status:{' '}\n <span style={{ color: isConnected ? 'green' : 'red' }}>\n {connectionStatus}\n </span>\n </p>\n <p>\n {(() => {\n const connectedReplicas = replicas.filter(\n r => r.isConnected,\n )\n return (\n <>\n Connected Replicas ({connectedReplicas.length} /{' '}\n {replicas.length} total):{' '}\n {connectedReplicas.length === 0\n ? 'none'\n : connectedReplicas.map((r, i) => (\n <Tooltip\n key={r.replicaId}\n title={\n <pre style={{ margin: 0, fontSize: '11px' }}>\n {JSON.stringify(r, null, 2)}\n </pre>\n }\n >\n <span\n style={{\n cursor: 'pointer',\n textDecoration: 'underline dotted',\n }}\n >\n {r.replicaId}\n {i < connectedReplicas.length - 1 ? ', ' : ''}\n </span>\n </Tooltip>\n ))}\n </>\n )\n })()}\n </p>\n </div>\n )}\n </Grid>\n\n {session && (\n <>\n {/* Grid Loading State */}\n {!hasSufficientData && (\n <Grid size={12}>\n <h3>Setting up grid...</h3>\n <div style={{ marginBottom: '10px' }}>\n {!session && <p>Creating grid session...</p>}\n {session && !replicaId && (\n <p>Setting up real-time sync...</p>\n )}\n {session && replicaId && !presignedUrl && (\n <p>Establishing secure connection...</p>\n )}\n {session && replicaId && presignedUrl && !isConnected && (\n <p>Connecting to server...</p>\n )}\n {isConnected && !hasCompletedInitialSync && (\n <p>Loading table data...</p>\n )}\n <SkeletonTable numRows={4} numCols={1} />\n </div>\n </Grid>\n )}\n {/* Grid */}\n {hasSufficientData && (\n <>\n <Grid size={12}>\n <Stack\n direction={'row'}\n spacing={1}\n sx={{ justifyContent: 'flex-end' }}\n >\n {undoUI}\n {redoUI}\n <GridMenuButton\n variant={'outlined'}\n onClick={() => setChatOpen(true)}\n startIcon={<SmartToyTwoTone />}\n >\n Open chat\n </GridMenuButton>\n <GridAgentChat\n agentRegistrationId={agentRegistrationId}\n open={chatOpen}\n onClose={() => setChatOpen(false)}\n gridSessionId={session.sessionId!}\n usersReplicaId={replicaId!}\n chatbotName=\"Grid Assistant\"\n />\n {session.sourceEntityId && (\n <UploadCsvToGridButton\n sourceEntityId={session.sourceEntityId}\n gridSessionId={session.sessionId!}\n />\n )}\n {session.sessionId && (\n <ExportCsvFromGridButton\n gridSessionId={session.sessionId}\n filename={\n 'grid-' + (session.sourceEntityId || 'export')\n }\n />\n )}\n {session.sourceEntityId && (\n <MergeGridWithSourceTableButton\n sourceEntityId={session.sourceEntityId}\n gridSessionId={session.sessionId!}\n />\n )}\n </Stack>\n </Grid>\n <Grid size={12}>\n <DataGrid\n gridRef={gridRef}\n rowValues={enrichedRowValues}\n columnNames={modelSnapshot?.columnNames ?? []}\n columnOrder={modelSnapshot?.columnOrder ?? []}\n schemaPropertiesInfo={schemaPropertiesInfo}\n entityIsView={entityIsView}\n jsonSchema={jsonSchema}\n lastSelection={lastSelection}\n handleChange={handleChange}\n handleSelectionChange={handleSelectionChange}\n onSelectedRowChange={handleSelectedRowChange}\n remoteSelections={remoteSelections}\n />\n </Grid>\n <Grid size={12}>\n <ValidationAlert\n selectedRowIndex={selectedRowIndexRef.current}\n rowValues={rowValues}\n />\n </Grid>\n </>\n )}\n {/* Debug Model Snapshot */}\n {showDebugInfo && (\n <Grid\n size={12}\n style={{\n margin: '10px 0',\n padding: '10px',\n border: '1px solid #ccc',\n maxHeight: '400px',\n overflowY: 'auto',\n }}\n >\n <h3>Model</h3>\n {model ? (\n <ClickableJsonCrdt model={model} />\n ) : (\n 'No model available'\n )}\n </Grid>\n )}\n </>\n )}\n </Grid>\n </div>\n )\n },\n)\n\nexport default SynapseGrid\n"],"names":["SynapseGrid","forwardRef","agentRegistrationId","showDebugInfo","ref","session","setSession","useState","replicaId","setReplicaId","chatOpen","setChatOpen","lastSelection","setLastSelection","startGridSessionRef","useRef","gridRef","userBundle","isLoading","useGetCurrentUserBundle","replicas","refetchReplicas","useListGridReplicas","handleReplicaConnectionChange","useCallback","currentUserId","replicaUserMap","useGridReplicaUsers","useImperativeHandle","request","sessionId","isConnected","websocketInstance","hasCompletedInitialSync","model","modelSnapshot","connect","presignedUrl","hasSufficientData","useDataGridWebSocket","websocketInstanceRef","useEffect","lastConnectParamsRef","nextParams","prevParams","jsonSchema","useGetSchemaForGrid","entityData","useGetEntity","entityIsView","schemaPropertiesInfo","useMemo","getSchemaPropertiesInfo","connectionStatus","remoteSelections","useRemoteSelections","rowValues","modelRowsToGrid","enrichedRowValues","enrichRowsWithChangeInfo","commit","applyAndCommitChanges","modelChanges","change","applyModelChange","applyModelChangeFromUndoRedo","undoUI","redoUI","addOperationsToUndoStack","clearRedoStack","useGridUndoRedo","handleChange","newValue","operations","removeNoOpOperations","mapOperationsToModelChanges","handleSelectionChange","opts","selection","replicaSelectionModel","computeReplicaSelectionModel","selectedRowIndexRef","forceUpdate","handleSelectedRowChange","rowIndex","_row","CertificationRequirement","jsxs","Grid","jsx","StartGridSession","connectedReplicas","r","Fragment","i","Tooltip","SkeletonTable","Stack","GridMenuButton","SmartToyTwoTone","GridAgentChat","UploadCsvToGridButton","ExportCsvFromGridButton","MergeGridWithSourceTableButton","DataGrid","ValidationAlert","ClickableJsonCrdt"],"mappings":"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"}
@@ -48,7 +48,6 @@ import "../../../assets/icons/account-validated.svg.js";
48
48
  import "../../../utils/functions/DateFormatter.js";
49
49
  import "@react-hookz/web";
50
50
  import "dayjs";
51
- import "../../../assets/ArcusBioIcon.svg.js";
52
51
  import "@mui/material/SvgIcon";
53
52
  import "../../../assets/icons/AccessPending.svg.js";
54
53
  import "../../../assets/icons/AccessPendingCloud.svg.js";
@@ -224,7 +223,7 @@ function u({
224
223
  let o = "";
225
224
  return i > 0 && (o += `created ${i.toLocaleString()} rows`), i > 0 && r > 0 ? o += " and " : r == 0 && (o += "."), r > 0 && (o += `updated ${r.toLocaleString()} rows.`), I(o);
226
225
  }
227
- function yt(i) {
226
+ function St(i) {
228
227
  const { gridSessionId: r, open: o, onClose: m, onComplete: p } = i, {
229
228
  mutate: e,
230
229
  isPending: s,
@@ -256,7 +255,7 @@ function yt(i) {
256
255
  );
257
256
  }
258
257
  export {
259
- yt as default,
258
+ St as default,
260
259
  u as getUpdateMessage
261
260
  };
262
261
  //# sourceMappingURL=UploadCsvToGridDialog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UploadCsvToGridDialog.js","sources":["../../../../src/components/DataGrid/components/UploadCsvToGridDialog.tsx"],"sourcesContent":["import { displayToast } from '@/components/index'\nimport CsvPreviewDialog from '@/components/table/CsvPreview/CsvPreviewDialog'\nimport { useImportCsvIntoGrid } from '@/synapse-queries/grid/useImportCsvIntoGrid'\nimport { GridCsvImportResponse } from '@sage-bionetworks/synapse-client'\nimport upperFirst from 'lodash-es/upperFirst'\n\ntype UploadCsvToGridDialogProps = {\n gridSessionId: string\n open: boolean\n onClose: () => void\n onComplete: () => void\n}\n\nexport function getUpdateMessage({\n createdCount = 0,\n updatedCount = 0,\n}: GridCsvImportResponse): string {\n let message = ''\n if (createdCount > 0) {\n message += `created ${createdCount.toLocaleString()} rows`\n }\n if (createdCount > 0 && updatedCount > 0) {\n message += ' and '\n } else if (updatedCount == 0) {\n message += '.'\n }\n if (updatedCount > 0) {\n message += `updated ${updatedCount.toLocaleString()} rows.`\n }\n return upperFirst(message)\n}\n\nexport default function UploadCsvToGridDialog(\n props: UploadCsvToGridDialogProps,\n) {\n const { gridSessionId, open, onClose, onComplete } = props\n\n const {\n mutate: importCsvIntoGrid,\n isPending,\n error,\n } = useImportCsvIntoGrid({\n onSuccess: result => {\n displayToast(getUpdateMessage(result), 'success', {\n title: 'Data imported successfully',\n })\n onComplete()\n },\n })\n\n return (\n <CsvPreviewDialog\n open={open}\n onClose={onClose}\n onConfirm={(fileHandleId, schema, csvDescriptor) => {\n importCsvIntoGrid({\n concreteType:\n 'org.sagebionetworks.repo.model.grid.GridCsvImportRequest',\n sessionId: gridSessionId,\n fileHandleId,\n csvDescriptor,\n schema,\n })\n }}\n errorMessage={error?.message}\n confirmIsPending={isPending}\n />\n )\n}\n"],"names":["getUpdateMessage","createdCount","updatedCount","message","upperFirst","UploadCsvToGridDialog","props","gridSessionId","open","onClose","onComplete","importCsvIntoGrid","isPending","error","useImportCsvIntoGrid","result","displayToast","jsx","CsvPreviewDialog","fileHandleId","schema","csvDescriptor"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaO,SAASA,EAAiB;AAAA,EAC/B,cAAAC,IAAe;AAAA,EACf,cAAAC,IAAe;AACjB,GAAkC;AAChC,MAAIC,IAAU;AACd,SAAIF,IAAe,MACjBE,KAAW,WAAWF,EAAa,eAAA,CAAgB,UAEjDA,IAAe,KAAKC,IAAe,IACrCC,KAAW,UACFD,KAAgB,MACzBC,KAAW,MAETD,IAAe,MACjBC,KAAW,WAAWD,EAAa,eAAA,CAAgB,WAE9CE,EAAWD,CAAO;AAC3B;AAEA,SAAwBE,GACtBC,GACA;AACA,QAAM,EAAE,eAAAC,GAAe,MAAAC,GAAM,SAAAC,GAAS,YAAAC,MAAeJ,GAE/C;AAAA,IACJ,QAAQK;AAAA,IACR,WAAAC;AAAA,IACA,OAAAC;AAAA,EAAA,IACEC,EAAqB;AAAA,IACvB,WAAW,CAAAC,MAAU;AACnB,MAAAC,EAAahB,EAAiBe,CAAM,GAAG,WAAW;AAAA,QAChD,OAAO;AAAA,MAAA,CACR,GACDL,EAAA;AAAA,IACF;AAAA,EAAA,CACD;AAED,SACE,gBAAAO;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,MAAAV;AAAA,MACA,SAAAC;AAAA,MACA,WAAW,CAACU,GAAcC,GAAQC,MAAkB;AAClD,QAAAV,EAAkB;AAAA,UAChB,cACE;AAAA,UACF,WAAWJ;AAAA,UACX,cAAAY;AAAA,UACA,eAAAE;AAAA,UACA,QAAAD;AAAA,QAAA,CACD;AAAA,MACH;AAAA,MACA,cAAcP,GAAO;AAAA,MACrB,kBAAkBD;AAAA,IAAA;AAAA,EAAA;AAGxB;"}
1
+ {"version":3,"file":"UploadCsvToGridDialog.js","sources":["../../../../src/components/DataGrid/components/UploadCsvToGridDialog.tsx"],"sourcesContent":["import { displayToast } from '@/components/index'\nimport CsvPreviewDialog from '@/components/table/CsvPreview/CsvPreviewDialog'\nimport { useImportCsvIntoGrid } from '@/synapse-queries/grid/useImportCsvIntoGrid'\nimport { GridCsvImportResponse } from '@sage-bionetworks/synapse-client'\nimport upperFirst from 'lodash-es/upperFirst'\n\ntype UploadCsvToGridDialogProps = {\n gridSessionId: string\n open: boolean\n onClose: () => void\n onComplete: () => void\n}\n\nexport function getUpdateMessage({\n createdCount = 0,\n updatedCount = 0,\n}: GridCsvImportResponse): string {\n let message = ''\n if (createdCount > 0) {\n message += `created ${createdCount.toLocaleString()} rows`\n }\n if (createdCount > 0 && updatedCount > 0) {\n message += ' and '\n } else if (updatedCount == 0) {\n message += '.'\n }\n if (updatedCount > 0) {\n message += `updated ${updatedCount.toLocaleString()} rows.`\n }\n return upperFirst(message)\n}\n\nexport default function UploadCsvToGridDialog(\n props: UploadCsvToGridDialogProps,\n) {\n const { gridSessionId, open, onClose, onComplete } = props\n\n const {\n mutate: importCsvIntoGrid,\n isPending,\n error,\n } = useImportCsvIntoGrid({\n onSuccess: result => {\n displayToast(getUpdateMessage(result), 'success', {\n title: 'Data imported successfully',\n })\n onComplete()\n },\n })\n\n return (\n <CsvPreviewDialog\n open={open}\n onClose={onClose}\n onConfirm={(fileHandleId, schema, csvDescriptor) => {\n importCsvIntoGrid({\n concreteType:\n 'org.sagebionetworks.repo.model.grid.GridCsvImportRequest',\n sessionId: gridSessionId,\n fileHandleId,\n csvDescriptor,\n schema,\n })\n }}\n errorMessage={error?.message}\n confirmIsPending={isPending}\n />\n )\n}\n"],"names":["getUpdateMessage","createdCount","updatedCount","message","upperFirst","UploadCsvToGridDialog","props","gridSessionId","open","onClose","onComplete","importCsvIntoGrid","isPending","error","useImportCsvIntoGrid","result","displayToast","jsx","CsvPreviewDialog","fileHandleId","schema","csvDescriptor"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaO,SAASA,EAAiB;AAAA,EAC/B,cAAAC,IAAe;AAAA,EACf,cAAAC,IAAe;AACjB,GAAkC;AAChC,MAAIC,IAAU;AACd,SAAIF,IAAe,MACjBE,KAAW,WAAWF,EAAa,eAAA,CAAgB,UAEjDA,IAAe,KAAKC,IAAe,IACrCC,KAAW,UACFD,KAAgB,MACzBC,KAAW,MAETD,IAAe,MACjBC,KAAW,WAAWD,EAAa,eAAA,CAAgB,WAE9CE,EAAWD,CAAO;AAC3B;AAEA,SAAwBE,GACtBC,GACA;AACA,QAAM,EAAE,eAAAC,GAAe,MAAAC,GAAM,SAAAC,GAAS,YAAAC,MAAeJ,GAE/C;AAAA,IACJ,QAAQK;AAAA,IACR,WAAAC;AAAA,IACA,OAAAC;AAAA,EAAA,IACEC,EAAqB;AAAA,IACvB,WAAW,CAAAC,MAAU;AACnB,MAAAC,EAAahB,EAAiBe,CAAM,GAAG,WAAW;AAAA,QAChD,OAAO;AAAA,MAAA,CACR,GACDL,EAAA;AAAA,IACF;AAAA,EAAA,CACD;AAED,SACE,gBAAAO;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,MAAAV;AAAA,MACA,SAAAC;AAAA,MACA,WAAW,CAACU,GAAcC,GAAQC,MAAkB;AAClD,QAAAV,EAAkB;AAAA,UAChB,cACE;AAAA,UACF,WAAWJ;AAAA,UACX,cAAAY;AAAA,UACA,eAAAE;AAAA,UACA,QAAAD;AAAA,QAAA,CACD;AAAA,MACH;AAAA,MACA,cAAcP,GAAO;AAAA,MACrB,kBAAkBD;AAAA,IAAA;AAAA,EAAA;AAGxB;"}
@@ -0,0 +1,15 @@
1
+ import { type ReplicaCategory } from '@/components/DataGrid/utils/getReplicaCategory';
2
+ import type { GridReplicaInfo } from '@sage-bionetworks/synapse-client';
3
+ import type { UserProfile } from '@sage-bionetworks/synapse-types';
4
+ export interface ReplicaUserInfo {
5
+ replicaInfo: GridReplicaInfo;
6
+ category: ReplicaCategory;
7
+ profile: UserProfile | undefined;
8
+ }
9
+ /**
10
+ * Given the list of replicas in the current session and the local replica ID,
11
+ * fetches user profiles for each non-SERVICE replica and returns a map from
12
+ * replicaId → ReplicaUserInfo for use in attribution and coloring.
13
+ */
14
+ export declare function useGridReplicaUsers(replicas: GridReplicaInfo[], localReplicaId: number | null, currentUserId: string | undefined): Map<number, ReplicaUserInfo>;
15
+ //# sourceMappingURL=useGridReplicaUsers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGridReplicaUsers.d.ts","sourceRoot":"","sources":["../../../../src/components/DataGrid/hooks/useGridReplicaUsers.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,gDAAgD,CAAA;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAA;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAA;AAKlE,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,eAAe,CAAA;IAC5B,QAAQ,EAAE,eAAe,CAAA;IACzB,OAAO,EAAE,WAAW,GAAG,SAAS,CAAA;CACjC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EAAE,EAC3B,cAAc,EAAE,MAAM,GAAG,IAAI,EAC7B,aAAa,EAAE,MAAM,GAAG,SAAS,GAChC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CA8D9B"}
@@ -0,0 +1,55 @@
1
+ import { useSynapseContext as d } from "../../../utils/context/SynapseContext.js";
2
+ import { useQueries as g } from "@tanstack/react-query";
3
+ import { getReplicaCategory as B } from "../utils/getReplicaCategory.js";
4
+ import { getUserProfileQuery as C } from "../../../synapse-queries/user/useUserBundle.js";
5
+ import { useMemo as a } from "react";
6
+ import { useDeepCompareMemoize as M } from "use-deep-compare-effect";
7
+ function k(p, i, n) {
8
+ const { accessToken: u, keyFactory: m } = d(), o = a(
9
+ () => p.filter((e) => e.replicaType !== "SERVICE"),
10
+ [p]
11
+ ), s = a(
12
+ () => [
13
+ ...new Set(
14
+ o.map((e) => e.createdBy).filter(Boolean)
15
+ )
16
+ ],
17
+ [o]
18
+ ), y = g({
19
+ queries: s.map((e) => ({
20
+ ...C(e, { accessToken: u, keyFactory: m }),
21
+ staleTime: 300 * 1e3
22
+ // profiles are stable within a session
23
+ }))
24
+ }), l = M(
25
+ y.map((e) => e.data)
26
+ );
27
+ return a(() => {
28
+ const e = /* @__PURE__ */ new Map();
29
+ s.forEach((t, r) => {
30
+ const f = l[r];
31
+ f && e.set(t, f);
32
+ });
33
+ const c = /* @__PURE__ */ new Map();
34
+ for (const t of o) {
35
+ if (t.replicaId == null) continue;
36
+ const r = i != null && n != null ? B(t, n, i) : null;
37
+ r !== null && c.set(t.replicaId, {
38
+ replicaInfo: t,
39
+ category: r,
40
+ profile: t.createdBy ? e.get(t.createdBy) : void 0
41
+ });
42
+ }
43
+ return c;
44
+ }, [
45
+ o,
46
+ s,
47
+ l,
48
+ i,
49
+ n
50
+ ]);
51
+ }
52
+ export {
53
+ k as useGridReplicaUsers
54
+ };
55
+ //# sourceMappingURL=useGridReplicaUsers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGridReplicaUsers.js","sources":["../../../../src/components/DataGrid/hooks/useGridReplicaUsers.ts"],"sourcesContent":["import { useSynapseContext } from '@/utils/context/SynapseContext'\nimport { useQueries } from '@tanstack/react-query'\nimport {\n getReplicaCategory,\n type ReplicaCategory,\n} from '@/components/DataGrid/utils/getReplicaCategory'\nimport type { GridReplicaInfo } from '@sage-bionetworks/synapse-client'\nimport type { UserProfile } from '@sage-bionetworks/synapse-types'\nimport { getUserProfileQuery } from '@/synapse-queries/user/useUserBundle'\nimport { useMemo } from 'react'\nimport { useDeepCompareMemoize } from 'use-deep-compare-effect'\n\nexport interface ReplicaUserInfo {\n replicaInfo: GridReplicaInfo\n category: ReplicaCategory\n profile: UserProfile | undefined\n}\n\n/**\n * Given the list of replicas in the current session and the local replica ID,\n * fetches user profiles for each non-SERVICE replica and returns a map from\n * replicaId → ReplicaUserInfo for use in attribution and coloring.\n */\nexport function useGridReplicaUsers(\n replicas: GridReplicaInfo[],\n localReplicaId: number | null,\n currentUserId: string | undefined,\n): Map<number, ReplicaUserInfo> {\n const { accessToken, keyFactory } = useSynapseContext()\n\n // Only query non-SERVICE replicas (SERVICE replicas are ignored for attribution)\n const attributableReplicas = useMemo(\n () => replicas.filter(r => r.replicaType !== 'SERVICE'),\n [replicas],\n )\n\n // Deduplicate user IDs so we only fetch each profile once\n const uniqueUserIds = useMemo(\n () => [\n ...new Set(\n attributableReplicas.map(r => r.createdBy).filter(Boolean) as string[],\n ),\n ],\n [attributableReplicas],\n )\n\n const profileQueries = useQueries({\n queries: uniqueUserIds.map(userId => ({\n ...getUserProfileQuery(userId, { accessToken, keyFactory }),\n staleTime: 5 * 60 * 1000, // profiles are stable within a session\n })),\n })\n\n const stableProfileData = useDeepCompareMemoize(\n profileQueries.map(q => q.data),\n )\n\n return useMemo(() => {\n // Build userId → profile map from query results\n const profileByUserId = new Map<string, UserProfile>()\n uniqueUserIds.forEach((userId, i) => {\n const data = stableProfileData[i]\n if (data) profileByUserId.set(userId, data)\n })\n\n const result = new Map<number, ReplicaUserInfo>()\n for (const replica of attributableReplicas) {\n if (replica.replicaId == null) continue\n const category =\n localReplicaId != null && currentUserId != null\n ? getReplicaCategory(replica, currentUserId, localReplicaId)\n : null\n if (category === null) continue\n result.set(replica.replicaId, {\n replicaInfo: replica,\n category,\n profile: replica.createdBy\n ? profileByUserId.get(replica.createdBy)\n : undefined,\n })\n }\n return result\n }, [\n attributableReplicas,\n uniqueUserIds,\n stableProfileData,\n localReplicaId,\n currentUserId,\n ])\n}\n"],"names":["useGridReplicaUsers","replicas","localReplicaId","currentUserId","accessToken","keyFactory","useSynapseContext","attributableReplicas","useMemo","r","uniqueUserIds","profileQueries","useQueries","userId","getUserProfileQuery","stableProfileData","useDeepCompareMemoize","q","profileByUserId","i","data","result","replica","category","getReplicaCategory"],"mappings":";;;;;;AAuBO,SAASA,EACdC,GACAC,GACAC,GAC8B;AAC9B,QAAM,EAAE,aAAAC,GAAa,YAAAC,EAAA,IAAeC,EAAA,GAG9BC,IAAuBC;AAAA,IAC3B,MAAMP,EAAS,OAAO,CAAAQ,MAAKA,EAAE,gBAAgB,SAAS;AAAA,IACtD,CAACR,CAAQ;AAAA,EAAA,GAILS,IAAgBF;AAAA,IACpB,MAAM;AAAA,MACJ,GAAG,IAAI;AAAA,QACLD,EAAqB,IAAI,CAAAE,MAAKA,EAAE,SAAS,EAAE,OAAO,OAAO;AAAA,MAAA;AAAA,IAC3D;AAAA,IAEF,CAACF,CAAoB;AAAA,EAAA,GAGjBI,IAAiBC,EAAW;AAAA,IAChC,SAASF,EAAc,IAAI,CAAAG,OAAW;AAAA,MACpC,GAAGC,EAAoBD,GAAQ,EAAE,aAAAT,GAAa,YAAAC,GAAY;AAAA,MAC1D,WAAW,MAAS;AAAA;AAAA,IAAA,EACpB;AAAA,EAAA,CACH,GAEKU,IAAoBC;AAAA,IACxBL,EAAe,IAAI,CAAAM,MAAKA,EAAE,IAAI;AAAA,EAAA;AAGhC,SAAOT,EAAQ,MAAM;AAEnB,UAAMU,wBAAsB,IAAA;AAC5B,IAAAR,EAAc,QAAQ,CAACG,GAAQM,MAAM;AACnC,YAAMC,IAAOL,EAAkBI,CAAC;AAChC,MAAIC,KAAMF,EAAgB,IAAIL,GAAQO,CAAI;AAAA,IAC5C,CAAC;AAED,UAAMC,wBAAa,IAAA;AACnB,eAAWC,KAAWf,GAAsB;AAC1C,UAAIe,EAAQ,aAAa,KAAM;AAC/B,YAAMC,IACJrB,KAAkB,QAAQC,KAAiB,OACvCqB,EAAmBF,GAASnB,GAAeD,CAAc,IACzD;AACN,MAAIqB,MAAa,QACjBF,EAAO,IAAIC,EAAQ,WAAW;AAAA,QAC5B,aAAaA;AAAA,QACb,UAAAC;AAAA,QACA,SAASD,EAAQ,YACbJ,EAAgB,IAAII,EAAQ,SAAS,IACrC;AAAA,MAAA,CACL;AAAA,IACH;AACA,WAAOD;AAAA,EACT,GAAG;AAAA,IACDd;AAAA,IACAG;AAAA,IACAK;AAAA,IACAb;AAAA,IACAC;AAAA,EAAA,CACD;AACH;"}
@@ -0,0 +1,16 @@
1
+ import type { GridModel, GridModelSnapshot } from '../DataGridTypes';
2
+ import type { GridReplicaInfo } from '@sage-bionetworks/synapse-client';
3
+ import { type GridSelectionRange } from '../utils/replicaSelectionToGridSelection';
4
+ export interface RemoteSelection {
5
+ replicaId: number;
6
+ range: GridSelectionRange;
7
+ /** 0-7 color index, derived from replicaId for a stable per-session color. */
8
+ colorIndex: number;
9
+ }
10
+ /**
11
+ * Derives remote replica selection ranges from the CRDT model's selection map.
12
+ * The server mirrors each replica's selection into the model under
13
+ * `snapshot.selection[replicaId]`, so no extra API calls are needed.
14
+ */
15
+ export declare function useRemoteSelections(modelSnapshot: GridModelSnapshot | null | undefined, model: GridModel | null | undefined, replicas: GridReplicaInfo[], localReplicaId: number | null): RemoteSelection[];
16
+ //# sourceMappingURL=useRemoteSelections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRemoteSelections.d.ts","sourceRoot":"","sources":["../../../../src/components/DataGrid/hooks/useRemoteSelections.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,SAAS,EACT,iBAAiB,EAElB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAA;AACvE,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,0CAA0C,CAAA;AAEjD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,kBAAkB,CAAA;IACzB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,EACnD,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACnC,QAAQ,EAAE,eAAe,EAAE,EAC3B,cAAc,EAAE,MAAM,GAAG,IAAI,GAC5B,eAAe,EAAE,CAqCnB"}
@@ -0,0 +1,30 @@
1
+ import { useMemo as l } from "react";
2
+ import { replicaSelectionToGridSelection as p } from "../utils/replicaSelectionToGridSelection.js";
3
+ function M(n, t, r, o) {
4
+ return l(() => {
5
+ if (!n || !t) return [];
6
+ const c = n.selection;
7
+ if (!c) return [];
8
+ const u = [];
9
+ for (const i of r) {
10
+ const e = i.replicaId;
11
+ if (e == null || e === o || !i.isConnected || i.replicaType === "SERVICE") continue;
12
+ const s = c[String(e)];
13
+ if (s)
14
+ try {
15
+ const f = p(s, t);
16
+ f && u.push({
17
+ replicaId: e,
18
+ range: f,
19
+ colorIndex: e % 8
20
+ });
21
+ } catch {
22
+ }
23
+ }
24
+ return u;
25
+ }, [n, t, r, o]);
26
+ }
27
+ export {
28
+ M as useRemoteSelections
29
+ };
30
+ //# sourceMappingURL=useRemoteSelections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRemoteSelections.js","sources":["../../../../src/components/DataGrid/hooks/useRemoteSelections.ts"],"sourcesContent":["import { useMemo } from 'react'\nimport type {\n GridModel,\n GridModelSnapshot,\n ReplicaSelectionModel,\n} from '../DataGridTypes'\nimport type { GridReplicaInfo } from '@sage-bionetworks/synapse-client'\nimport {\n replicaSelectionToGridSelection,\n type GridSelectionRange,\n} from '../utils/replicaSelectionToGridSelection'\n\nexport interface RemoteSelection {\n replicaId: number\n range: GridSelectionRange\n /** 0-7 color index, derived from replicaId for a stable per-session color. */\n colorIndex: number\n}\n\n/**\n * Derives remote replica selection ranges from the CRDT model's selection map.\n * The server mirrors each replica's selection into the model under\n * `snapshot.selection[replicaId]`, so no extra API calls are needed.\n */\nexport function useRemoteSelections(\n modelSnapshot: GridModelSnapshot | null | undefined,\n model: GridModel | null | undefined,\n replicas: GridReplicaInfo[],\n localReplicaId: number | null,\n): RemoteSelection[] {\n return useMemo(() => {\n if (!modelSnapshot || !model) return []\n\n const selectionMap = modelSnapshot.selection as Record<\n string,\n ReplicaSelectionModel\n >\n if (!selectionMap) return []\n\n const results: RemoteSelection[] = []\n\n for (const replica of replicas) {\n const rid = replica.replicaId\n if (rid == null || rid === localReplicaId) continue\n if (!replica.isConnected) continue\n if (replica.replicaType === 'SERVICE') continue\n\n const selectionModel = selectionMap[String(rid)]\n if (!selectionModel) continue\n\n try {\n const range = replicaSelectionToGridSelection(selectionModel, model)\n if (range) {\n results.push({\n replicaId: rid,\n range,\n colorIndex: rid % 8,\n })\n }\n } catch {\n // Ignore stale/malformed selection data for a replica\n }\n }\n\n return results\n }, [modelSnapshot, model, replicas, localReplicaId])\n}\n"],"names":["useRemoteSelections","modelSnapshot","model","replicas","localReplicaId","useMemo","selectionMap","results","replica","rid","selectionModel","range","replicaSelectionToGridSelection"],"mappings":";;AAwBO,SAASA,EACdC,GACAC,GACAC,GACAC,GACmB;AACnB,SAAOC,EAAQ,MAAM;AACnB,QAAI,CAACJ,KAAiB,CAACC,UAAc,CAAA;AAErC,UAAMI,IAAeL,EAAc;AAInC,QAAI,CAACK,EAAc,QAAO,CAAA;AAE1B,UAAMC,IAA6B,CAAA;AAEnC,eAAWC,KAAWL,GAAU;AAC9B,YAAMM,IAAMD,EAAQ;AAGpB,UAFIC,KAAO,QAAQA,MAAQL,KACvB,CAACI,EAAQ,eACTA,EAAQ,gBAAgB,UAAW;AAEvC,YAAME,IAAiBJ,EAAa,OAAOG,CAAG,CAAC;AAC/C,UAAKC;AAEL,YAAI;AACF,gBAAMC,IAAQC,EAAgCF,GAAgBR,CAAK;AACnE,UAAIS,KACFJ,EAAQ,KAAK;AAAA,YACX,WAAWE;AAAA,YACX,OAAAE;AAAA,YACA,YAAYF,IAAM;AAAA,UAAA,CACnB;AAAA,QAEL,QAAQ;AAAA,QAER;AAAA,IACF;AAEA,WAAOF;AAAA,EACT,GAAG,CAACN,GAAeC,GAAOC,GAAUC,CAAc,CAAC;AACrD;"}
@@ -1,48 +1,48 @@
1
- import { SYNAPSE_ENTITY_ID_REGEX as p } from "../../../utils/functions/RegularExpressions.js";
2
- const a = "__rowKey", m = (n) => {
3
- const e = n.trim();
4
- if (e) {
5
- if (e.toUpperCase().startsWith("SELECT"))
6
- return { type: "sql", input: e };
7
- if (p.test(e))
8
- return { type: "recordSetId", input: e };
9
- if (/^[A-Za-z]\w*=+$/.test(e))
10
- return { type: "sessionId", input: e };
1
+ import { SYNAPSE_ENTITY_ID_REGEX as f } from "../../../utils/functions/RegularExpressions.js";
2
+ const y = "__rowKey", m = (n) => {
3
+ const t = n.trim();
4
+ if (t) {
5
+ if (t.toUpperCase().startsWith("SELECT"))
6
+ return { type: "sql", input: t };
7
+ if (f.test(t))
8
+ return { type: "recordSetId", input: t };
9
+ if (/^[A-Za-z]\w*=+$/.test(t))
10
+ return { type: "sessionId", input: t };
11
11
  } else return { type: "empty", input: "" };
12
- return { type: "unknown", input: e };
12
+ return { type: "unknown", input: t };
13
13
  };
14
- function f(n, e) {
15
- const r = Object.keys(n), u = Object.keys(e);
16
- if (r.length !== u.length) return !1;
17
- for (const t of r) {
18
- const o = n[t], i = e[t], l = (s) => s == null || s === "";
19
- if (!(l(o) && l(i)) && String(o) !== String(i))
14
+ function p(n, t) {
15
+ const o = (s) => !s.startsWith("__"), i = Object.keys(n).filter(o), e = Object.keys(t).filter(o);
16
+ if (i.length !== e.length) return !1;
17
+ for (const s of i) {
18
+ const u = n[s], c = t[s], l = (r) => r == null || r === "";
19
+ if (!(l(u) && l(c)) && String(u) !== String(c))
20
20
  return !1;
21
21
  }
22
22
  return !0;
23
23
  }
24
- function I(n, e, r) {
25
- function u(t) {
26
- if (t.type === "UPDATE") {
27
- const o = e.slice(
28
- t.fromRowIndex,
29
- t.toRowIndex
30
- ), i = n.slice(
31
- t.fromRowIndex,
32
- t.toRowIndex
24
+ function I(n, t, o) {
25
+ function i(e) {
26
+ if (e.type === "UPDATE") {
27
+ const s = t.slice(
28
+ e.fromRowIndex,
29
+ e.toRowIndex
30
+ ), u = n.slice(
31
+ e.fromRowIndex,
32
+ e.toRowIndex
33
33
  );
34
- return o.map(
35
- (s, c) => f(s, i[c])
34
+ return s.map(
35
+ (l, r) => p(l, u[r])
36
36
  ).every(Boolean);
37
37
  }
38
38
  return !1;
39
39
  }
40
- return r.filter((t) => !u(t));
40
+ return o.filter((e) => !i(e));
41
41
  }
42
42
  export {
43
- a as GRID_ROW_REACT_KEY_PROPERTY,
43
+ y as GRID_ROW_REACT_KEY_PROPERTY,
44
44
  m as parseQueryInput,
45
45
  I as removeNoOpOperations,
46
- f as rowsAreIdentical
46
+ p as rowsAreIdentical
47
47
  };
48
48
  //# sourceMappingURL=DataGridUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataGridUtils.js","sources":["../../../../src/components/DataGrid/utils/DataGridUtils.ts"],"sourcesContent":["import { SYNAPSE_ENTITY_ID_REGEX } from '@/utils/functions/RegularExpressions'\nimport { DataGridRow, Operation, QueryInput } from '../DataGridTypes'\n\n// We embed a value into the in row data passed to react-datasheet-grid for use as a render optimization\nexport const GRID_ROW_REACT_KEY_PROPERTY = '__rowKey'\n\n// Query Input can either be an empty string, a SQL query, or a session ID\nexport const parseQueryInput = (input: string): QueryInput => {\n const trimmedInput = input.trim()\n if (!trimmedInput) {\n return { type: 'empty', input: '' }\n } else if (trimmedInput.toUpperCase().startsWith('SELECT')) {\n return { type: 'sql', input: trimmedInput }\n } else if (SYNAPSE_ENTITY_ID_REGEX.test(trimmedInput)) {\n return { type: 'recordSetId', input: trimmedInput }\n } else if (/^[A-Za-z]\\w*=+$/.test(trimmedInput)) {\n return { type: 'sessionId', input: trimmedInput }\n }\n return { type: 'unknown', input: trimmedInput }\n}\n\nexport function rowsAreIdentical(a: DataGridRow, b: DataGridRow): boolean {\n const aKeys = Object.keys(a)\n const bKeys = Object.keys(b)\n if (aKeys.length !== bKeys.length) return false\n for (const key of aKeys) {\n const aVal = a[key]\n const bVal = b[key]\n // Treat null, undefined, and empty string as equivalent\n const isNullish = (v: string | number | boolean | null | undefined) =>\n v === null || v === undefined || v === ''\n if (isNullish(aVal) && isNullish(bVal)) continue\n if (String(aVal) !== String(bVal)) return false\n }\n return true\n}\n\n/**\n * Remove no-op operations created by react-datasheet-grid that would result in invalid or undesired changes to the json-joy CRDT model\n * @param newValue\n * @param rowValues\n * @param operations\n */\nexport function removeNoOpOperations(\n newValue: DataGridRow[],\n rowValues: DataGridRow[],\n operations: Operation[],\n) {\n function isNoop(operation: Operation): boolean {\n if (operation.type === 'UPDATE') {\n const oldVal = rowValues.slice(\n operation.fromRowIndex,\n operation.toRowIndex,\n )\n const newVal = newValue.slice(\n operation.fromRowIndex,\n operation.toRowIndex,\n )\n\n const comparisonResults = oldVal.map((oldItem, idx) =>\n rowsAreIdentical(oldItem, newVal[idx]),\n )\n return comparisonResults.every(Boolean)\n }\n return false\n }\n\n return operations.filter(op => !isNoop(op))\n}\n"],"names":["GRID_ROW_REACT_KEY_PROPERTY","parseQueryInput","input","trimmedInput","SYNAPSE_ENTITY_ID_REGEX","rowsAreIdentical","a","b","aKeys","bKeys","key","aVal","bVal","isNullish","v","removeNoOpOperations","newValue","rowValues","operations","isNoop","operation","oldVal","newVal","oldItem","idx","op"],"mappings":";AAIO,MAAMA,IAA8B,YAG9BC,IAAkB,CAACC,MAA8B;AAC5D,QAAMC,IAAeD,EAAM,KAAA;AAC3B,MAAKC;QAEMA,EAAa,YAAA,EAAc,WAAW,QAAQ;AACvD,aAAO,EAAE,MAAM,OAAO,OAAOA,EAAA;AAC/B,QAAWC,EAAwB,KAAKD,CAAY;AAClD,aAAO,EAAE,MAAM,eAAe,OAAOA,EAAA;AACvC,QAAW,kBAAkB,KAAKA,CAAY;AAC5C,aAAO,EAAE,MAAM,aAAa,OAAOA,EAAA;AAAA,QANnC,QAAO,EAAE,MAAM,SAAS,OAAO,GAAA;AAQjC,SAAO,EAAE,MAAM,WAAW,OAAOA,EAAA;AACnC;AAEO,SAASE,EAAiBC,GAAgBC,GAAyB;AACxE,QAAMC,IAAQ,OAAO,KAAKF,CAAC,GACrBG,IAAQ,OAAO,KAAKF,CAAC;AAC3B,MAAIC,EAAM,WAAWC,EAAM,OAAQ,QAAO;AAC1C,aAAWC,KAAOF,GAAO;AACvB,UAAMG,IAAOL,EAAEI,CAAG,GACZE,IAAOL,EAAEG,CAAG,GAEZG,IAAY,CAACC,MACjBA,KAAM,QAA2BA,MAAM;AACzC,QAAI,EAAAD,EAAUF,CAAI,KAAKE,EAAUD,CAAI,MACjC,OAAOD,CAAI,MAAM,OAAOC,CAAI;AAAG,aAAO;AAAA,EAC5C;AACA,SAAO;AACT;AAQO,SAASG,EACdC,GACAC,GACAC,GACA;AACA,WAASC,EAAOC,GAA+B;AAC7C,QAAIA,EAAU,SAAS,UAAU;AAC/B,YAAMC,IAASJ,EAAU;AAAA,QACvBG,EAAU;AAAA,QACVA,EAAU;AAAA,MAAA,GAENE,IAASN,EAAS;AAAA,QACtBI,EAAU;AAAA,QACVA,EAAU;AAAA,MAAA;AAMZ,aAH0BC,EAAO;AAAA,QAAI,CAACE,GAASC,MAC7CnB,EAAiBkB,GAASD,EAAOE,CAAG,CAAC;AAAA,MAAA,EAEd,MAAM,OAAO;AAAA,IACxC;AACA,WAAO;AAAA,EACT;AAEA,SAAON,EAAW,OAAO,CAAAO,MAAM,CAACN,EAAOM,CAAE,CAAC;AAC5C;"}
1
+ {"version":3,"file":"DataGridUtils.js","sources":["../../../../src/components/DataGrid/utils/DataGridUtils.ts"],"sourcesContent":["import { SYNAPSE_ENTITY_ID_REGEX } from '@/utils/functions/RegularExpressions'\nimport { DataGridRow, Operation, QueryInput } from '../DataGridTypes'\n\n// We embed a value into the in row data passed to react-datasheet-grid for use as a render optimization\nexport const GRID_ROW_REACT_KEY_PROPERTY = '__rowKey'\n\n// Query Input can either be an empty string, a SQL query, or a session ID\nexport const parseQueryInput = (input: string): QueryInput => {\n const trimmedInput = input.trim()\n if (!trimmedInput) {\n return { type: 'empty', input: '' }\n } else if (trimmedInput.toUpperCase().startsWith('SELECT')) {\n return { type: 'sql', input: trimmedInput }\n } else if (SYNAPSE_ENTITY_ID_REGEX.test(trimmedInput)) {\n return { type: 'recordSetId', input: trimmedInput }\n } else if (/^[A-Za-z]\\w*=+$/.test(trimmedInput)) {\n return { type: 'sessionId', input: trimmedInput }\n }\n return { type: 'unknown', input: trimmedInput }\n}\n\nexport function rowsAreIdentical(a: DataGridRow, b: DataGridRow): boolean {\n const isDataKey = (key: string) => !key.startsWith('__')\n const aKeys = Object.keys(a).filter(isDataKey)\n const bKeys = Object.keys(b).filter(isDataKey)\n if (aKeys.length !== bKeys.length) return false\n for (const key of aKeys) {\n const aVal = a[key] as string | number | boolean | null | undefined\n const bVal = b[key] as string | number | boolean | null | undefined\n // Treat null, undefined, and empty string as equivalent\n const isNullish = (v: unknown) => v === null || v === undefined || v === ''\n if (isNullish(aVal) && isNullish(bVal)) continue\n if (String(aVal) !== String(bVal)) return false\n }\n return true\n}\n\n/**\n * Remove no-op operations created by react-datasheet-grid that would result in invalid or undesired changes to the json-joy CRDT model\n * @param newValue\n * @param rowValues\n * @param operations\n */\nexport function removeNoOpOperations(\n newValue: DataGridRow[],\n rowValues: DataGridRow[],\n operations: Operation[],\n) {\n function isNoop(operation: Operation): boolean {\n if (operation.type === 'UPDATE') {\n const oldVal = rowValues.slice(\n operation.fromRowIndex,\n operation.toRowIndex,\n )\n const newVal = newValue.slice(\n operation.fromRowIndex,\n operation.toRowIndex,\n )\n\n const comparisonResults = oldVal.map((oldItem, idx) =>\n rowsAreIdentical(oldItem, newVal[idx]),\n )\n return comparisonResults.every(Boolean)\n }\n return false\n }\n\n return operations.filter(op => !isNoop(op))\n}\n"],"names":["GRID_ROW_REACT_KEY_PROPERTY","parseQueryInput","input","trimmedInput","SYNAPSE_ENTITY_ID_REGEX","rowsAreIdentical","a","b","isDataKey","key","aKeys","bKeys","aVal","bVal","isNullish","v","removeNoOpOperations","newValue","rowValues","operations","isNoop","operation","oldVal","newVal","oldItem","idx","op"],"mappings":";AAIO,MAAMA,IAA8B,YAG9BC,IAAkB,CAACC,MAA8B;AAC5D,QAAMC,IAAeD,EAAM,KAAA;AAC3B,MAAKC;QAEMA,EAAa,YAAA,EAAc,WAAW,QAAQ;AACvD,aAAO,EAAE,MAAM,OAAO,OAAOA,EAAA;AAC/B,QAAWC,EAAwB,KAAKD,CAAY;AAClD,aAAO,EAAE,MAAM,eAAe,OAAOA,EAAA;AACvC,QAAW,kBAAkB,KAAKA,CAAY;AAC5C,aAAO,EAAE,MAAM,aAAa,OAAOA,EAAA;AAAA,QANnC,QAAO,EAAE,MAAM,SAAS,OAAO,GAAA;AAQjC,SAAO,EAAE,MAAM,WAAW,OAAOA,EAAA;AACnC;AAEO,SAASE,EAAiBC,GAAgBC,GAAyB;AACxE,QAAMC,IAAY,CAACC,MAAgB,CAACA,EAAI,WAAW,IAAI,GACjDC,IAAQ,OAAO,KAAKJ,CAAC,EAAE,OAAOE,CAAS,GACvCG,IAAQ,OAAO,KAAKJ,CAAC,EAAE,OAAOC,CAAS;AAC7C,MAAIE,EAAM,WAAWC,EAAM,OAAQ,QAAO;AAC1C,aAAWF,KAAOC,GAAO;AACvB,UAAME,IAAON,EAAEG,CAAG,GACZI,IAAON,EAAEE,CAAG,GAEZK,IAAY,CAACC,MAAeA,KAAM,QAA2BA,MAAM;AACzE,QAAI,EAAAD,EAAUF,CAAI,KAAKE,EAAUD,CAAI,MACjC,OAAOD,CAAI,MAAM,OAAOC,CAAI;AAAG,aAAO;AAAA,EAC5C;AACA,SAAO;AACT;AAQO,SAASG,EACdC,GACAC,GACAC,GACA;AACA,WAASC,EAAOC,GAA+B;AAC7C,QAAIA,EAAU,SAAS,UAAU;AAC/B,YAAMC,IAASJ,EAAU;AAAA,QACvBG,EAAU;AAAA,QACVA,EAAU;AAAA,MAAA,GAENE,IAASN,EAAS;AAAA,QACtBI,EAAU;AAAA,QACVA,EAAU;AAAA,MAAA;AAMZ,aAH0BC,EAAO;AAAA,QAAI,CAACE,GAASC,MAC7CpB,EAAiBmB,GAASD,EAAOE,CAAG,CAAC;AAAA,MAAA,EAEd,MAAM,OAAO;AAAA,IACxC;AACA,WAAO;AAAA,EACT;AAEA,SAAON,EAAW,OAAO,CAAAO,MAAM,CAACN,EAAOM,CAAE,CAAC;AAC5C;"}
@@ -20,7 +20,7 @@ export type ModelChange = {
20
20
  replicaId: string;
21
21
  selection: ReplicaSelectionModel;
22
22
  };
23
- export declare function getDefaultValueForProperty(row: DataGridRow, property: string, schemaPropertyInfo: SchemaPropertiesMap): string | number | boolean | null | undefined;
23
+ export declare function getDefaultValueForProperty(row: DataGridRow, property: string, schemaPropertyInfo: SchemaPropertiesMap): string | number | boolean | import("@sage-bionetworks/synapse-types").ValidationResults | Map<string, string[]> | Record<string, import("@/components/DataGrid/DataGridTypes").CellChangeInfo> | null | undefined;
24
24
  /**
25
25
  * Applies a single change operation (create, delete, or update) to the GridModel.
26
26
  *
@@ -1 +1 @@
1
- {"version":3,"file":"applyModelChange.d.ts","sourceRoot":"","sources":["../../../../src/components/DataGrid/utils/applyModelChange.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,SAAS,EACT,qBAAqB,EACtB,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAA;AAG9E;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,GAC9D;IACE,IAAI,EAAE,eAAe,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,qBAAqB,CAAA;CACjC,CAAA;AAEL,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,MAAM,EAChB,kBAAkB,EAAE,mBAAmB,gDAexC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,WAAW,EACnB,kBAAkB,EAAE,mBAAmB,QAqDxC"}
1
+ {"version":3,"file":"applyModelChange.d.ts","sourceRoot":"","sources":["../../../../src/components/DataGrid/utils/applyModelChange.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,SAAS,EACT,qBAAqB,EACtB,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAA;AAI9E;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,GAC9D;IACE,IAAI,EAAE,eAAe,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,qBAAqB,CAAA;CACjC,CAAA;AAEL,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,MAAM,EAChB,kBAAkB,EAAE,mBAAmB,qNAexC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,WAAW,EACnB,kBAAkB,EAAE,mBAAmB,QAyDxC"}
@@ -1,45 +1,50 @@
1
1
  import { s as o } from "json-joy/lib/json-crdt-patch";
2
- function l(t, e, r) {
3
- let a;
4
- return Object.hasOwn(t, e) ? a = t[e] : r[e]?.isRequired ? a = null : a = void 0, a;
2
+ import u from "lodash-es/isEqual";
3
+ function w(a, t, s) {
4
+ let e;
5
+ return Object.hasOwn(a, t) ? e = a[t] : s[t]?.isRequired ? e = null : e = void 0, e;
5
6
  }
6
- function p(t, e, r) {
7
- const a = t.api.arr(["rows"]), { columnNames: n } = t.api.getSnapshot();
8
- switch (e.type) {
7
+ function l(a, t, s) {
8
+ const e = a.api.arr(["rows"]), { columnNames: c } = a.api.getSnapshot();
9
+ switch (t.type) {
9
10
  case "CREATE": {
10
- const s = n.map(
11
- (i) => o.con(
12
- l(e.rowData, i, r)
11
+ const i = c.map(
12
+ (r) => o.con(
13
+ w(t.rowData, r, s)
13
14
  )
14
15
  );
15
- a?.ins(e.rowIndex, [
16
- o.obj({ data: o.vec(...s), metadata: o.obj({}) })
16
+ e?.ins(t.rowIndex, [
17
+ o.obj({ data: o.vec(...i), metadata: o.obj({}) })
17
18
  ]);
18
19
  break;
19
20
  }
20
21
  case "DELETE":
21
- a?.del(e.rowIndex, e.count ?? 1);
22
+ e?.del(t.rowIndex, t.count ?? 1);
22
23
  break;
23
24
  case "UPDATE": {
24
- Object.entries(e.updatedData).forEach(([s, i]) => {
25
- if (s.startsWith("_")) return;
26
- const c = n.indexOf(s);
27
- c !== -1 && t.api.vec([
28
- "rows",
29
- String(e.rowIndex),
30
- "data"
31
- ])?.set([[c, o.con(i)]]);
25
+ const i = a.api.getSnapshot().rows[t.rowIndex]?.data;
26
+ Object.entries(t.updatedData).forEach(([r, p]) => {
27
+ if (r.startsWith("_")) return;
28
+ const n = c.indexOf(r);
29
+ if (n !== -1) {
30
+ if (u(i?.[n], p)) return;
31
+ a.api.vec([
32
+ "rows",
33
+ String(t.rowIndex),
34
+ "data"
35
+ ])?.set([[n, o.con(p)]]);
36
+ }
32
37
  });
33
38
  break;
34
39
  }
35
40
  case "SET_SELECTION": {
36
- t.api.obj().has("selection") || t.api.obj().add(["selection"], o.obj({})), t.api.obj(["selection"]).set({ [e.replicaId]: o.con(e.selection) });
41
+ a.api.obj().has("selection") || a.api.obj().add(["selection"], o.obj({})), a.api.obj(["selection"]).set({ [t.replicaId]: o.con(t.selection) });
37
42
  break;
38
43
  }
39
44
  }
40
45
  }
41
46
  export {
42
- p as applyModelChange,
43
- l as getDefaultValueForProperty
47
+ l as applyModelChange,
48
+ w as getDefaultValueForProperty
44
49
  };
45
50
  //# sourceMappingURL=applyModelChange.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"applyModelChange.js","sources":["../../../../src/components/DataGrid/utils/applyModelChange.ts"],"sourcesContent":["import {\n DataGridRow,\n GridModel,\n ReplicaSelectionModel,\n} from '@/components/DataGrid/DataGridTypes'\nimport { SchemaPropertiesMap } from '@/utils/jsonschema/getSchemaPropertyInfo'\nimport { s } from 'json-joy/lib/json-crdt-patch'\n\n/**\n * Represents a change operation on the GridModel.\n */\nexport type ModelChange =\n | { type: 'CREATE'; rowIndex: number; rowData: DataGridRow }\n | { type: 'DELETE'; rowIndex: number; count?: number }\n | { type: 'UPDATE'; rowIndex: number; updatedData: DataGridRow }\n | {\n type: 'SET_SELECTION'\n replicaId: string\n selection: ReplicaSelectionModel\n }\n\nexport function getDefaultValueForProperty(\n row: DataGridRow,\n property: string,\n schemaPropertyInfo: SchemaPropertiesMap,\n) {\n let value\n if (Object.hasOwn(row, property)) {\n value = row[property]\n } else {\n // Inspect the schema. If the property is required, it should be `null`\n // Otherwise, the property is optional. It should be undefined to be valid against the JSON Schema\n if (schemaPropertyInfo[property]?.isRequired) {\n value = null\n } else {\n value = undefined\n }\n }\n return value\n}\n\n/**\n * Applies a single change operation (create, delete, or update) to the GridModel.\n *\n * @param model - The grid model to modify\n * @param change - The change to apply\n */\nexport function applyModelChange(\n model: GridModel,\n change: ModelChange,\n schemaPropertyInfo: SchemaPropertiesMap,\n) {\n const rowsArr = model.api.arr(['rows'])\n const { columnNames } = model.api.getSnapshot()\n\n switch (change.type) {\n case 'CREATE': {\n // Convert rowData object into a CRDT vector\n const rowData = columnNames.map(name =>\n s.con(\n getDefaultValueForProperty(change.rowData, name, schemaPropertyInfo),\n ),\n )\n // Insert a new row object at the specified index\n rowsArr?.ins(change.rowIndex, [\n s.obj({ data: s.vec(...rowData), metadata: s.obj({}) }),\n ])\n break\n }\n\n case 'DELETE':\n rowsArr?.del(change.rowIndex, change.count ?? 1)\n break\n\n case 'UPDATE': {\n Object.entries(change.updatedData).forEach(([key, value]) => {\n if (key.startsWith('_')) return // Skip internal properties like _rowId\n const colIndex = columnNames.indexOf(key)\n if (colIndex !== -1) {\n // Get the CRDT array of cell values for this row\n const rowVec = model.api.vec([\n 'rows',\n String(change.rowIndex),\n 'data',\n ])\n // Update the specific column with the new value\n rowVec?.set([[colIndex, s.con(value)]])\n }\n })\n break\n }\n case 'SET_SELECTION': {\n if (!model.api.obj().has('selection')) {\n // Create if not exists\n model.api.obj().add(['selection'], s.obj({}))\n }\n model.api\n .obj(['selection'])\n .set({ [change.replicaId]: s.con(change.selection) })\n\n break\n }\n }\n}\n"],"names":["getDefaultValueForProperty","row","property","schemaPropertyInfo","value","applyModelChange","model","change","rowsArr","columnNames","rowData","s","name","key","colIndex"],"mappings":";AAqBO,SAASA,EACdC,GACAC,GACAC,GACA;AACA,MAAIC;AACJ,SAAI,OAAO,OAAOH,GAAKC,CAAQ,IAC7BE,IAAQH,EAAIC,CAAQ,IAIhBC,EAAmBD,CAAQ,GAAG,aAChCE,IAAQ,OAERA,IAAQ,QAGLA;AACT;AAQO,SAASC,EACdC,GACAC,GACAJ,GACA;AACA,QAAMK,IAAUF,EAAM,IAAI,IAAI,CAAC,MAAM,CAAC,GAChC,EAAE,aAAAG,EAAA,IAAgBH,EAAM,IAAI,YAAA;AAElC,UAAQC,EAAO,MAAA;AAAA,IACb,KAAK,UAAU;AAEb,YAAMG,IAAUD,EAAY;AAAA,QAAI,OAC9BE,EAAE;AAAA,UACAX,EAA2BO,EAAO,SAASK,GAAMT,CAAkB;AAAA,QAAA;AAAA,MACrE;AAGF,MAAAK,GAAS,IAAID,EAAO,UAAU;AAAA,QAC5BI,EAAE,IAAI,EAAE,MAAMA,EAAE,IAAI,GAAGD,CAAO,GAAG,UAAUC,EAAE,IAAI,CAAA,CAAE,GAAG;AAAA,MAAA,CACvD;AACD;AAAA,IACF;AAAA,IAEA,KAAK;AACH,MAAAH,GAAS,IAAID,EAAO,UAAUA,EAAO,SAAS,CAAC;AAC/C;AAAA,IAEF,KAAK,UAAU;AACb,aAAO,QAAQA,EAAO,WAAW,EAAE,QAAQ,CAAC,CAACM,GAAKT,CAAK,MAAM;AAC3D,YAAIS,EAAI,WAAW,GAAG,EAAG;AACzB,cAAMC,IAAWL,EAAY,QAAQI,CAAG;AACxC,QAAIC,MAAa,MAEAR,EAAM,IAAI,IAAI;AAAA,UAC3B;AAAA,UACA,OAAOC,EAAO,QAAQ;AAAA,UACtB;AAAA,QAAA,CACD,GAEO,IAAI,CAAC,CAACO,GAAUH,EAAE,IAAIP,CAAK,CAAC,CAAC,CAAC;AAAA,MAE1C,CAAC;AACD;AAAA,IACF;AAAA,IACA,KAAK,iBAAiB;AACpB,MAAKE,EAAM,IAAI,MAAM,IAAI,WAAW,KAElCA,EAAM,IAAI,IAAA,EAAM,IAAI,CAAC,WAAW,GAAGK,EAAE,IAAI,CAAA,CAAE,CAAC,GAE9CL,EAAM,IACH,IAAI,CAAC,WAAW,CAAC,EACjB,IAAI,EAAE,CAACC,EAAO,SAAS,GAAGI,EAAE,IAAIJ,EAAO,SAAS,GAAG;AAEtD;AAAA,IACF;AAAA,EAAA;AAEJ;"}
1
+ {"version":3,"file":"applyModelChange.js","sources":["../../../../src/components/DataGrid/utils/applyModelChange.ts"],"sourcesContent":["import {\n DataGridRow,\n GridModel,\n ReplicaSelectionModel,\n} from '@/components/DataGrid/DataGridTypes'\nimport { SchemaPropertiesMap } from '@/utils/jsonschema/getSchemaPropertyInfo'\nimport { s } from 'json-joy/lib/json-crdt-patch'\nimport isEqual from 'lodash-es/isEqual'\n\n/**\n * Represents a change operation on the GridModel.\n */\nexport type ModelChange =\n | { type: 'CREATE'; rowIndex: number; rowData: DataGridRow }\n | { type: 'DELETE'; rowIndex: number; count?: number }\n | { type: 'UPDATE'; rowIndex: number; updatedData: DataGridRow }\n | {\n type: 'SET_SELECTION'\n replicaId: string\n selection: ReplicaSelectionModel\n }\n\nexport function getDefaultValueForProperty(\n row: DataGridRow,\n property: string,\n schemaPropertyInfo: SchemaPropertiesMap,\n) {\n let value\n if (Object.hasOwn(row, property)) {\n value = row[property]\n } else {\n // Inspect the schema. If the property is required, it should be `null`\n // Otherwise, the property is optional. It should be undefined to be valid against the JSON Schema\n if (schemaPropertyInfo[property]?.isRequired) {\n value = null\n } else {\n value = undefined\n }\n }\n return value\n}\n\n/**\n * Applies a single change operation (create, delete, or update) to the GridModel.\n *\n * @param model - The grid model to modify\n * @param change - The change to apply\n */\nexport function applyModelChange(\n model: GridModel,\n change: ModelChange,\n schemaPropertyInfo: SchemaPropertiesMap,\n) {\n const rowsArr = model.api.arr(['rows'])\n const { columnNames } = model.api.getSnapshot()\n\n switch (change.type) {\n case 'CREATE': {\n // Convert rowData object into a CRDT vector\n const rowData = columnNames.map(name =>\n s.con(\n getDefaultValueForProperty(change.rowData, name, schemaPropertyInfo),\n ),\n )\n // Insert a new row object at the specified index\n rowsArr?.ins(change.rowIndex, [\n s.obj({ data: s.vec(...rowData), metadata: s.obj({}) }),\n ])\n break\n }\n\n case 'DELETE':\n rowsArr?.del(change.rowIndex, change.count ?? 1)\n break\n\n case 'UPDATE': {\n const currentRowData = model.api.getSnapshot().rows[change.rowIndex]?.data\n Object.entries(change.updatedData).forEach(([key, value]) => {\n if (key.startsWith('_')) return // Skip internal properties like _rowId\n const colIndex = columnNames.indexOf(key)\n if (colIndex !== -1) {\n // Only write cells whose value actually changed to avoid stamping\n // the local replica's SID on unmodified cells.\n if (isEqual(currentRowData?.[colIndex], value)) return\n // Get the CRDT array of cell values for this row\n const rowVec = model.api.vec([\n 'rows',\n String(change.rowIndex),\n 'data',\n ])\n // Update the specific column with the new value\n rowVec?.set([[colIndex, s.con(value)]])\n }\n })\n break\n }\n case 'SET_SELECTION': {\n if (!model.api.obj().has('selection')) {\n // Create if not exists\n model.api.obj().add(['selection'], s.obj({}))\n }\n model.api\n .obj(['selection'])\n .set({ [change.replicaId]: s.con(change.selection) })\n\n break\n }\n }\n}\n"],"names":["getDefaultValueForProperty","row","property","schemaPropertyInfo","value","applyModelChange","model","change","rowsArr","columnNames","rowData","s","name","currentRowData","key","colIndex","isEqual"],"mappings":";;AAsBO,SAASA,EACdC,GACAC,GACAC,GACA;AACA,MAAIC;AACJ,SAAI,OAAO,OAAOH,GAAKC,CAAQ,IAC7BE,IAAQH,EAAIC,CAAQ,IAIhBC,EAAmBD,CAAQ,GAAG,aAChCE,IAAQ,OAERA,IAAQ,QAGLA;AACT;AAQO,SAASC,EACdC,GACAC,GACAJ,GACA;AACA,QAAMK,IAAUF,EAAM,IAAI,IAAI,CAAC,MAAM,CAAC,GAChC,EAAE,aAAAG,EAAA,IAAgBH,EAAM,IAAI,YAAA;AAElC,UAAQC,EAAO,MAAA;AAAA,IACb,KAAK,UAAU;AAEb,YAAMG,IAAUD,EAAY;AAAA,QAAI,OAC9BE,EAAE;AAAA,UACAX,EAA2BO,EAAO,SAASK,GAAMT,CAAkB;AAAA,QAAA;AAAA,MACrE;AAGF,MAAAK,GAAS,IAAID,EAAO,UAAU;AAAA,QAC5BI,EAAE,IAAI,EAAE,MAAMA,EAAE,IAAI,GAAGD,CAAO,GAAG,UAAUC,EAAE,IAAI,CAAA,CAAE,GAAG;AAAA,MAAA,CACvD;AACD;AAAA,IACF;AAAA,IAEA,KAAK;AACH,MAAAH,GAAS,IAAID,EAAO,UAAUA,EAAO,SAAS,CAAC;AAC/C;AAAA,IAEF,KAAK,UAAU;AACb,YAAMM,IAAiBP,EAAM,IAAI,YAAA,EAAc,KAAKC,EAAO,QAAQ,GAAG;AACtE,aAAO,QAAQA,EAAO,WAAW,EAAE,QAAQ,CAAC,CAACO,GAAKV,CAAK,MAAM;AAC3D,YAAIU,EAAI,WAAW,GAAG,EAAG;AACzB,cAAMC,IAAWN,EAAY,QAAQK,CAAG;AACxC,YAAIC,MAAa,IAAI;AAGnB,cAAIC,EAAQH,IAAiBE,CAAQ,GAAGX,CAAK,EAAG;AAQhD,UANeE,EAAM,IAAI,IAAI;AAAA,YAC3B;AAAA,YACA,OAAOC,EAAO,QAAQ;AAAA,YACtB;AAAA,UAAA,CACD,GAEO,IAAI,CAAC,CAACQ,GAAUJ,EAAE,IAAIP,CAAK,CAAC,CAAC,CAAC;AAAA,QACxC;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAAA,IACA,KAAK,iBAAiB;AACpB,MAAKE,EAAM,IAAI,MAAM,IAAI,WAAW,KAElCA,EAAM,IAAI,IAAA,EAAM,IAAI,CAAC,WAAW,GAAGK,EAAE,IAAI,CAAA,CAAE,CAAC,GAE9CL,EAAM,IACH,IAAI,CAAC,WAAW,CAAC,EACjB,IAAI,EAAE,CAACC,EAAO,SAAS,GAAGI,EAAE,IAAIJ,EAAO,SAAS,GAAG;AAEtD;AAAA,IACF;AAAA,EAAA;AAEJ;"}
@@ -1 +1 @@
1
- {"version":3,"file":"columnFactory.d.ts","sourceRoot":"","sources":["../../../../src/components/DataGrid/utils/columnFactory.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,EACL,MAAM,EAIP,MAAM,wCAAwC,CAAA;AAS/C,KAAK,YAAY,GAAG;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;IAC7B,gBAAgB,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,CAAA;IACrD,UAAU,EAAE,OAAO,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;CACzB,CAAA;AAgLD,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAGzD"}
1
+ {"version":3,"file":"columnFactory.d.ts","sourceRoot":"","sources":["../../../../src/components/DataGrid/utils/columnFactory.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,EAGL,MAAM,EAIP,MAAM,wCAAwC,CAAA;AAqE/C,KAAK,YAAY,GAAG;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;IAC7B,gBAAgB,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,CAAA;IACrD,UAAU,EAAE,OAAO,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;CACzB,CAAA;AAkLD,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAGzD"}