@ynput/ayon-frontend-shared 0.2.18 → 0.2.19

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 (312) hide show
  1. package/dist/DetailsPanel.cjs.js +6 -6
  2. package/dist/DetailsPanel.es.js +7 -7
  3. package/dist/DetailsPanel.es.js.map +1 -1
  4. package/dist/ProjectTreeTable.cjs.js +6 -0
  5. package/dist/ProjectTreeTable.cjs.js.map +1 -1
  6. package/dist/ProjectTreeTable.es.js +6 -0
  7. package/dist/ProjectTreeTable.es.js.map +1 -1
  8. package/dist/api.cjs.js +6 -0
  9. package/dist/api.cjs.js.map +1 -1
  10. package/dist/api.es.js +10 -4
  11. package/dist/index.cjs.js +6 -5
  12. package/dist/index.cjs.js.map +1 -1
  13. package/dist/index.es.js +6 -5
  14. package/dist/index.es.js.map +1 -1
  15. package/dist/shared/src/api/generated/folders.cjs.js.map +1 -1
  16. package/dist/shared/src/api/generated/folders.es.js.map +1 -1
  17. package/dist/shared/src/api/generated/graphql.cjs.js +38 -0
  18. package/dist/shared/src/api/generated/graphql.cjs.js.map +1 -1
  19. package/dist/shared/src/api/generated/graphql.es.js +38 -0
  20. package/dist/shared/src/api/generated/graphql.es.js.map +1 -1
  21. package/dist/shared/src/api/queries/actions/getActions.cjs.js +9 -1
  22. package/dist/shared/src/api/queries/actions/getActions.cjs.js.map +1 -1
  23. package/dist/shared/src/api/queries/actions/getActions.es.js +9 -1
  24. package/dist/shared/src/api/queries/actions/getActions.es.js.map +1 -1
  25. package/dist/shared/src/api/queries/entities/getEntityPanel.cjs.js +2 -1
  26. package/dist/shared/src/api/queries/entities/getEntityPanel.cjs.js.map +1 -1
  27. package/dist/shared/src/api/queries/entities/getEntityPanel.es.js +2 -1
  28. package/dist/shared/src/api/queries/entities/getEntityPanel.es.js.map +1 -1
  29. package/dist/shared/src/api/queries/entities/transformDetailsPanelData.cjs.js +12 -8
  30. package/dist/shared/src/api/queries/entities/transformDetailsPanelData.cjs.js.map +1 -1
  31. package/dist/shared/src/api/queries/entities/transformDetailsPanelData.es.js +12 -8
  32. package/dist/shared/src/api/queries/entities/transformDetailsPanelData.es.js.map +1 -1
  33. package/dist/shared/src/api/queries/entityLists/getLists.cjs.js +67 -0
  34. package/dist/shared/src/api/queries/entityLists/getLists.cjs.js.map +1 -1
  35. package/dist/shared/src/api/queries/entityLists/getLists.es.js +68 -1
  36. package/dist/shared/src/api/queries/entityLists/getLists.es.js.map +1 -1
  37. package/dist/shared/src/api/queries/entityLists/updateLists.cjs.js +19 -3
  38. package/dist/shared/src/api/queries/entityLists/updateLists.cjs.js.map +1 -1
  39. package/dist/shared/src/api/queries/entityLists/updateLists.es.js +19 -3
  40. package/dist/shared/src/api/queries/entityLists/updateLists.es.js.map +1 -1
  41. package/dist/shared/src/api/queries/overview/updateOverview.cjs.js +13 -0
  42. package/dist/shared/src/api/queries/overview/updateOverview.cjs.js.map +1 -1
  43. package/dist/shared/src/api/queries/overview/updateOverview.es.js +13 -0
  44. package/dist/shared/src/api/queries/overview/updateOverview.es.js.map +1 -1
  45. package/dist/shared/src/api/queries/users/getUsers.cjs.js +2 -0
  46. package/dist/shared/src/api/queries/users/getUsers.cjs.js.map +1 -1
  47. package/dist/shared/src/api/queries/users/getUsers.es.js +2 -0
  48. package/dist/shared/src/api/queries/users/getUsers.es.js.map +1 -1
  49. package/dist/shared/src/api/queries/versions/updateVersions.cjs.js +3 -1
  50. package/dist/shared/src/api/queries/versions/updateVersions.cjs.js.map +1 -1
  51. package/dist/shared/src/api/queries/versions/updateVersions.es.js +3 -1
  52. package/dist/shared/src/api/queries/versions/updateVersions.es.js.map +1 -1
  53. package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributes.cjs.js +5 -5
  54. package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributes.cjs.js.map +1 -1
  55. package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributes.es.js +5 -5
  56. package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributes.es.js.map +1 -1
  57. package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributesEditor.cjs.js +1 -1
  58. package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributesEditor.cjs.js.map +1 -1
  59. package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributesEditor.es.js +1 -1
  60. package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributesEditor.es.js.map +1 -1
  61. package/dist/shared/src/components/DetailsPanelAttributes/components/RenderFieldWidget.cjs.js +2 -2
  62. package/dist/shared/src/components/DetailsPanelAttributes/components/RenderFieldWidget.cjs.js.map +1 -1
  63. package/dist/shared/src/components/DetailsPanelAttributes/components/RenderFieldWidget.es.js +2 -2
  64. package/dist/shared/src/components/DetailsPanelAttributes/components/RenderFieldWidget.es.js.map +1 -1
  65. package/dist/shared/src/components/EntityPanelUploader/EntityPanelUploader.cjs.js +15 -14
  66. package/dist/shared/src/components/EntityPanelUploader/EntityPanelUploader.cjs.js.map +1 -1
  67. package/dist/shared/src/components/EntityPanelUploader/EntityPanelUploader.es.js +15 -14
  68. package/dist/shared/src/components/EntityPanelUploader/EntityPanelUploader.es.js.map +1 -1
  69. package/dist/shared/src/components/PlayableIcon/PlayableIcon.cjs.js +43 -0
  70. package/dist/shared/src/components/PlayableIcon/PlayableIcon.cjs.js.map +1 -0
  71. package/dist/shared/src/components/PlayableIcon/PlayableIcon.es.js +43 -0
  72. package/dist/shared/src/components/PlayableIcon/PlayableIcon.es.js.map +1 -0
  73. package/dist/shared/src/components/Powerpack/PowerpackDialog.styled.cjs.js +1 -1
  74. package/dist/shared/src/components/Powerpack/PowerpackDialog.styled.cjs.js.map +1 -1
  75. package/dist/shared/src/components/Powerpack/PowerpackDialog.styled.es.js +1 -1
  76. package/dist/shared/src/components/Powerpack/PowerpackDialog.styled.es.js.map +1 -1
  77. package/dist/shared/src/components/ProjectTableSettings/ProjectTableSettings.cjs.js +15 -15
  78. package/dist/shared/src/components/ProjectTableSettings/ProjectTableSettings.es.js +15 -15
  79. package/dist/shared/src/components/ReviewablesList/ReviewablesList.cjs.js +6 -5
  80. package/dist/shared/src/components/ReviewablesList/ReviewablesList.cjs.js.map +1 -1
  81. package/dist/shared/src/components/ReviewablesList/ReviewablesList.es.js +6 -5
  82. package/dist/shared/src/components/ReviewablesList/ReviewablesList.es.js.map +1 -1
  83. package/dist/shared/src/components/ReviewablesList/ReviewablesUpload.cjs.js +6 -5
  84. package/dist/shared/src/components/ReviewablesList/ReviewablesUpload.cjs.js.map +1 -1
  85. package/dist/shared/src/components/ReviewablesList/ReviewablesUpload.es.js +6 -5
  86. package/dist/shared/src/components/ReviewablesList/ReviewablesUpload.es.js.map +1 -1
  87. package/dist/shared/src/components/ReviewablesList/SortableReviewableCard.cjs.js +6 -5
  88. package/dist/shared/src/components/ReviewablesList/SortableReviewableCard.cjs.js.map +1 -1
  89. package/dist/shared/src/components/ReviewablesList/SortableReviewableCard.es.js +6 -5
  90. package/dist/shared/src/components/ReviewablesList/SortableReviewableCard.es.js.map +1 -1
  91. package/dist/shared/src/components/SettingsPanel/SettingsPanelItemTemplate.cjs.js +2 -2
  92. package/dist/shared/src/components/SettingsPanel/SettingsPanelItemTemplate.cjs.js.map +1 -1
  93. package/dist/shared/src/components/SettingsPanel/SettingsPanelItemTemplate.es.js +2 -2
  94. package/dist/shared/src/components/SettingsPanel/SettingsPanelItemTemplate.es.js.map +1 -1
  95. package/dist/shared/src/components/SimpleFormDialog/SimpleFormDialog.cjs.js +6 -5
  96. package/dist/shared/src/components/SimpleFormDialog/SimpleFormDialog.cjs.js.map +1 -1
  97. package/dist/shared/src/components/SimpleFormDialog/SimpleFormDialog.es.js +6 -5
  98. package/dist/shared/src/components/SimpleFormDialog/SimpleFormDialog.es.js.map +1 -1
  99. package/dist/shared/src/components/VersionUploader/components/UploadVersionForm.cjs.js +6 -5
  100. package/dist/shared/src/components/VersionUploader/components/UploadVersionForm.cjs.js.map +1 -1
  101. package/dist/shared/src/components/VersionUploader/components/UploadVersionForm.es.js +6 -5
  102. package/dist/shared/src/components/VersionUploader/components/UploadVersionForm.es.js.map +1 -1
  103. package/dist/shared/src/containers/Actions/ActionConfigDialog.cjs.js +6 -5
  104. package/dist/shared/src/containers/Actions/ActionConfigDialog.cjs.js.map +1 -1
  105. package/dist/shared/src/containers/Actions/ActionConfigDialog.es.js +6 -5
  106. package/dist/shared/src/containers/Actions/ActionConfigDialog.es.js.map +1 -1
  107. package/dist/shared/src/containers/Actions/Actions.cjs.js +8 -2
  108. package/dist/shared/src/containers/Actions/Actions.cjs.js.map +1 -1
  109. package/dist/shared/src/containers/Actions/Actions.es.js +8 -2
  110. package/dist/shared/src/containers/Actions/Actions.es.js.map +1 -1
  111. package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.cjs.js +10 -3
  112. package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.cjs.js.map +1 -1
  113. package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.es.js +10 -3
  114. package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.es.js.map +1 -1
  115. package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.cjs.js +14 -0
  116. package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.cjs.js.map +1 -1
  117. package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.es.js +14 -0
  118. package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.es.js.map +1 -1
  119. package/dist/shared/src/containers/Actions/InteractiveActionDialog.cjs.js +6 -5
  120. package/dist/shared/src/containers/Actions/InteractiveActionDialog.cjs.js.map +1 -1
  121. package/dist/shared/src/containers/Actions/InteractiveActionDialog.es.js +6 -5
  122. package/dist/shared/src/containers/Actions/InteractiveActionDialog.es.js.map +1 -1
  123. package/dist/shared/src/containers/DetailsPanel/DetailsPanel.cjs.js +5 -5
  124. package/dist/shared/src/containers/DetailsPanel/DetailsPanel.es.js +5 -5
  125. package/dist/shared/src/containers/DetailsPanel/DetailsPanelFiles/DetailsPanelFiles.cjs.js +6 -5
  126. package/dist/shared/src/containers/DetailsPanel/DetailsPanelFiles/DetailsPanelFiles.cjs.js.map +1 -1
  127. package/dist/shared/src/containers/DetailsPanel/DetailsPanelFiles/DetailsPanelFiles.es.js +6 -5
  128. package/dist/shared/src/containers/DetailsPanel/DetailsPanelFiles/DetailsPanelFiles.es.js.map +1 -1
  129. package/dist/shared/src/containers/DetailsPanel/DetailsPanelFloating/DetailsPanelFloating.cjs.js +6 -5
  130. package/dist/shared/src/containers/DetailsPanel/DetailsPanelFloating/DetailsPanelFloating.cjs.js.map +1 -1
  131. package/dist/shared/src/containers/DetailsPanel/DetailsPanelFloating/DetailsPanelFloating.es.js +6 -5
  132. package/dist/shared/src/containers/DetailsPanel/DetailsPanelFloating/DetailsPanelFloating.es.js.map +1 -1
  133. package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.cjs.js +6 -4
  134. package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.cjs.js.map +1 -1
  135. package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.es.js +7 -5
  136. package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.es.js.map +1 -1
  137. package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.styled.cjs.js +1 -31
  138. package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.styled.cjs.js.map +1 -1
  139. package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.styled.es.js +1 -31
  140. package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.styled.es.js.map +1 -1
  141. package/dist/shared/src/containers/Feed/components/ActivityReference/ActivityReference.styled.cjs.js +2 -2
  142. package/dist/shared/src/containers/Feed/components/ActivityReference/ActivityReference.styled.cjs.js.map +1 -1
  143. package/dist/shared/src/containers/Feed/components/ActivityReference/ActivityReference.styled.es.js +2 -2
  144. package/dist/shared/src/containers/Feed/components/ActivityReference/ActivityReference.styled.es.js.map +1 -1
  145. package/dist/shared/src/containers/Feed/components/FileUploadPreview/FileUploadPreview.styled.cjs.js +1 -1
  146. package/dist/shared/src/containers/Feed/components/FileUploadPreview/FileUploadPreview.styled.cjs.js.map +1 -1
  147. package/dist/shared/src/containers/Feed/components/FileUploadPreview/FileUploadPreview.styled.es.js +1 -1
  148. package/dist/shared/src/containers/Feed/components/FileUploadPreview/FileUploadPreview.styled.es.js.map +1 -1
  149. package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.cjs.js +48 -4
  150. package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.cjs.js.map +1 -1
  151. package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.es.js +50 -6
  152. package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.es.js.map +1 -1
  153. package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.cjs.js +47 -11
  154. package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.cjs.js.map +1 -1
  155. package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.es.js +47 -11
  156. package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.es.js.map +1 -1
  157. package/dist/shared/src/containers/ProjectTreeTable/components/GroupSettingsFallback.cjs.js +5 -4
  158. package/dist/shared/src/containers/ProjectTreeTable/components/GroupSettingsFallback.cjs.js.map +1 -1
  159. package/dist/shared/src/containers/ProjectTreeTable/components/GroupSettingsFallback.es.js +5 -4
  160. package/dist/shared/src/containers/ProjectTreeTable/components/GroupSettingsFallback.es.js.map +1 -1
  161. package/dist/shared/src/containers/ProjectTreeTable/components/HeaderActionButton.cjs.js +5 -3
  162. package/dist/shared/src/containers/ProjectTreeTable/components/HeaderActionButton.cjs.js.map +1 -1
  163. package/dist/shared/src/containers/ProjectTreeTable/components/HeaderActionButton.es.js +5 -3
  164. package/dist/shared/src/containers/ProjectTreeTable/components/HeaderActionButton.es.js.map +1 -1
  165. package/dist/shared/src/containers/ProjectTreeTable/context/CellEditingContext.cjs.js +106 -2
  166. package/dist/shared/src/containers/ProjectTreeTable/context/CellEditingContext.cjs.js.map +1 -1
  167. package/dist/shared/src/containers/ProjectTreeTable/context/CellEditingContext.es.js +106 -2
  168. package/dist/shared/src/containers/ProjectTreeTable/context/CellEditingContext.es.js.map +1 -1
  169. package/dist/shared/src/containers/ProjectTreeTable/context/ClipboardContext.cjs.js +14 -2
  170. package/dist/shared/src/containers/ProjectTreeTable/context/ClipboardContext.cjs.js.map +1 -1
  171. package/dist/shared/src/containers/ProjectTreeTable/context/ClipboardContext.es.js +14 -2
  172. package/dist/shared/src/containers/ProjectTreeTable/context/ClipboardContext.es.js.map +1 -1
  173. package/dist/shared/src/containers/ProjectTreeTable/context/ProjectTableContext.cjs.js.map +1 -1
  174. package/dist/shared/src/containers/ProjectTreeTable/context/ProjectTableContext.es.js.map +1 -1
  175. package/dist/shared/src/containers/ProjectTreeTable/context/ProjectTableProvider.cjs.js +15 -3
  176. package/dist/shared/src/containers/ProjectTreeTable/context/ProjectTableProvider.cjs.js.map +1 -1
  177. package/dist/shared/src/containers/ProjectTreeTable/context/ProjectTableProvider.es.js +15 -3
  178. package/dist/shared/src/containers/ProjectTreeTable/context/ProjectTableProvider.es.js.map +1 -1
  179. package/dist/shared/src/containers/ProjectTreeTable/context/SelectionCellsProvider.cjs.js +106 -0
  180. package/dist/shared/src/containers/ProjectTreeTable/context/SelectionCellsProvider.cjs.js.map +1 -1
  181. package/dist/shared/src/containers/ProjectTreeTable/context/SelectionCellsProvider.es.js +106 -0
  182. package/dist/shared/src/containers/ProjectTreeTable/context/SelectionCellsProvider.es.js.map +1 -1
  183. package/dist/shared/src/containers/ProjectTreeTable/hooks/useBuildProjectDataTable.cjs.js +4 -2
  184. package/dist/shared/src/containers/ProjectTreeTable/hooks/useBuildProjectDataTable.cjs.js.map +1 -1
  185. package/dist/shared/src/containers/ProjectTreeTable/hooks/useBuildProjectDataTable.es.js +4 -2
  186. package/dist/shared/src/containers/ProjectTreeTable/hooks/useBuildProjectDataTable.es.js.map +1 -1
  187. package/dist/shared/src/containers/ProjectTreeTable/hooks/useCellContextMenu.cjs.js +26 -4
  188. package/dist/shared/src/containers/ProjectTreeTable/hooks/useCellContextMenu.cjs.js.map +1 -1
  189. package/dist/shared/src/containers/ProjectTreeTable/hooks/useCellContextMenu.es.js +26 -4
  190. package/dist/shared/src/containers/ProjectTreeTable/hooks/useCellContextMenu.es.js.map +1 -1
  191. package/dist/shared/src/containers/ProjectTreeTable/hooks/useCheckSelectedCellsVisible.cjs.js +135 -0
  192. package/dist/shared/src/containers/ProjectTreeTable/hooks/useCheckSelectedCellsVisible.cjs.js.map +1 -0
  193. package/dist/shared/src/containers/ProjectTreeTable/hooks/useCheckSelectedCellsVisible.es.js +135 -0
  194. package/dist/shared/src/containers/ProjectTreeTable/hooks/useCheckSelectedCellsVisible.es.js.map +1 -0
  195. package/dist/shared/src/containers/ProjectTreeTable/hooks/useDeleteEntities.cjs.js +8 -6
  196. package/dist/shared/src/containers/ProjectTreeTable/hooks/useDeleteEntities.cjs.js.map +1 -1
  197. package/dist/shared/src/containers/ProjectTreeTable/hooks/useDeleteEntities.es.js +8 -6
  198. package/dist/shared/src/containers/ProjectTreeTable/hooks/useDeleteEntities.es.js.map +1 -1
  199. package/dist/shared/src/containers/ProjectTreeTable/hooks/useFolderRelationships.cjs.js +1 -2
  200. package/dist/shared/src/containers/ProjectTreeTable/hooks/useFolderRelationships.cjs.js.map +1 -1
  201. package/dist/shared/src/containers/ProjectTreeTable/hooks/useFolderRelationships.es.js +1 -2
  202. package/dist/shared/src/containers/ProjectTreeTable/hooks/useFolderRelationships.es.js.map +1 -1
  203. package/dist/shared/src/containers/ProjectTreeTable/hooks/useGetGroupedFields.cjs.js +88 -0
  204. package/dist/shared/src/containers/ProjectTreeTable/hooks/useGetGroupedFields.cjs.js.map +1 -1
  205. package/dist/shared/src/containers/ProjectTreeTable/hooks/useGetGroupedFields.es.js +88 -0
  206. package/dist/shared/src/containers/ProjectTreeTable/hooks/useGetGroupedFields.es.js.map +1 -1
  207. package/dist/shared/src/containers/ProjectTreeTable/hooks/useHistory.cjs.js +1 -1
  208. package/dist/shared/src/containers/ProjectTreeTable/hooks/useHistory.cjs.js.map +1 -1
  209. package/dist/shared/src/containers/ProjectTreeTable/hooks/useHistory.es.js +1 -1
  210. package/dist/shared/src/containers/ProjectTreeTable/hooks/useHistory.es.js.map +1 -1
  211. package/dist/shared/src/containers/ProjectTreeTable/hooks/useKeyboardNavigation.cjs.js +35 -4
  212. package/dist/shared/src/containers/ProjectTreeTable/hooks/useKeyboardNavigation.cjs.js.map +1 -1
  213. package/dist/shared/src/containers/ProjectTreeTable/hooks/useKeyboardNavigation.es.js +35 -4
  214. package/dist/shared/src/containers/ProjectTreeTable/hooks/useKeyboardNavigation.es.js.map +1 -1
  215. package/dist/shared/src/containers/ProjectTreeTable/hooks/useQueryFilters.cjs.js +88 -0
  216. package/dist/shared/src/containers/ProjectTreeTable/hooks/useQueryFilters.cjs.js.map +1 -1
  217. package/dist/shared/src/containers/ProjectTreeTable/hooks/useQueryFilters.es.js +88 -0
  218. package/dist/shared/src/containers/ProjectTreeTable/hooks/useQueryFilters.es.js.map +1 -1
  219. package/dist/shared/src/containers/ProjectTreeTable/hooks/useUpdateTableData.cjs.js +1 -1
  220. package/dist/shared/src/containers/ProjectTreeTable/hooks/useUpdateTableData.cjs.js.map +1 -1
  221. package/dist/shared/src/containers/ProjectTreeTable/hooks/useUpdateTableData.es.js +1 -1
  222. package/dist/shared/src/containers/ProjectTreeTable/hooks/useUpdateTableData.es.js.map +1 -1
  223. package/dist/shared/src/containers/ProjectTreeTable/utils/cellUtils.cjs.js +90 -0
  224. package/dist/shared/src/containers/ProjectTreeTable/utils/cellUtils.cjs.js.map +1 -1
  225. package/dist/shared/src/containers/ProjectTreeTable/utils/cellUtils.es.js +90 -0
  226. package/dist/shared/src/containers/ProjectTreeTable/utils/cellUtils.es.js.map +1 -1
  227. package/dist/shared/src/containers/ProjectTreeTable/utils/getEntityViewerIds.cjs.js +19 -0
  228. package/dist/shared/src/containers/ProjectTreeTable/utils/getEntityViewerIds.cjs.js.map +1 -0
  229. package/dist/shared/src/containers/ProjectTreeTable/utils/getEntityViewerIds.es.js +19 -0
  230. package/dist/shared/src/containers/ProjectTreeTable/utils/getEntityViewerIds.es.js.map +1 -0
  231. package/dist/shared/src/containers/ProjectTreeTable/utils/getTypeDefaultValue.cjs.js +26 -0
  232. package/dist/shared/src/containers/ProjectTreeTable/utils/getTypeDefaultValue.cjs.js.map +1 -0
  233. package/dist/shared/src/containers/ProjectTreeTable/utils/getTypeDefaultValue.es.js +26 -0
  234. package/dist/shared/src/containers/ProjectTreeTable/utils/getTypeDefaultValue.es.js.map +1 -0
  235. package/dist/shared/src/containers/ProjectTreeTable/widgets/CellWidget.cjs.js +9 -8
  236. package/dist/shared/src/containers/ProjectTreeTable/widgets/CellWidget.cjs.js.map +1 -1
  237. package/dist/shared/src/containers/ProjectTreeTable/widgets/CellWidget.es.js +10 -9
  238. package/dist/shared/src/containers/ProjectTreeTable/widgets/CellWidget.es.js.map +1 -1
  239. package/dist/shared/src/containers/ProjectTreeTable/widgets/EntityNameWidget.cjs.js +8 -2
  240. package/dist/shared/src/containers/ProjectTreeTable/widgets/EntityNameWidget.cjs.js.map +1 -1
  241. package/dist/shared/src/containers/ProjectTreeTable/widgets/EntityNameWidget.es.js +8 -2
  242. package/dist/shared/src/containers/ProjectTreeTable/widgets/EntityNameWidget.es.js.map +1 -1
  243. package/dist/shared/src/containers/ProjectTreeTable/widgets/EnumCellValue.cjs.js +190 -0
  244. package/dist/shared/src/containers/ProjectTreeTable/widgets/EnumCellValue.cjs.js.map +1 -0
  245. package/dist/shared/src/containers/ProjectTreeTable/widgets/EnumCellValue.es.js +190 -0
  246. package/dist/shared/src/containers/ProjectTreeTable/widgets/EnumCellValue.es.js.map +1 -0
  247. package/dist/shared/src/containers/ProjectTreeTable/widgets/EnumWidget.cjs.js +4 -147
  248. package/dist/shared/src/containers/ProjectTreeTable/widgets/EnumWidget.cjs.js.map +1 -1
  249. package/dist/shared/src/containers/ProjectTreeTable/widgets/EnumWidget.es.js +2 -145
  250. package/dist/shared/src/containers/ProjectTreeTable/widgets/EnumWidget.es.js.map +1 -1
  251. package/dist/shared/src/containers/ProjectTreeTable/widgets/ThumbnailWidget.cjs.js +12 -2
  252. package/dist/shared/src/containers/ProjectTreeTable/widgets/ThumbnailWidget.cjs.js.map +1 -1
  253. package/dist/shared/src/containers/ProjectTreeTable/widgets/ThumbnailWidget.es.js +12 -2
  254. package/dist/shared/src/containers/ProjectTreeTable/widgets/ThumbnailWidget.es.js.map +1 -1
  255. package/dist/shared/src/containers/RepresentationsList/RepresentationsList.cjs.js +6 -5
  256. package/dist/shared/src/containers/RepresentationsList/RepresentationsList.cjs.js.map +1 -1
  257. package/dist/shared/src/containers/RepresentationsList/RepresentationsList.es.js +6 -5
  258. package/dist/shared/src/containers/RepresentationsList/RepresentationsList.es.js.map +1 -1
  259. package/dist/shared/src/context/DetailsPanelContext.cjs.js +5 -1
  260. package/dist/shared/src/context/DetailsPanelContext.cjs.js.map +1 -1
  261. package/dist/shared/src/context/DetailsPanelContext.es.js +5 -1
  262. package/dist/shared/src/context/DetailsPanelContext.es.js.map +1 -1
  263. package/dist/shared/src/util/confirmDelete.cjs.js +1 -0
  264. package/dist/shared/src/util/confirmDelete.cjs.js.map +1 -1
  265. package/dist/shared/src/util/confirmDelete.es.js +2 -0
  266. package/dist/shared/src/util/confirmDelete.es.js.map +1 -1
  267. package/dist/types/SimpleTable/SimpleTable.d.ts +1 -0
  268. package/dist/types/SimpleTable/SimpleTableRowTemplate.d.ts +1 -1
  269. package/dist/types/SimpleTable/context/SimpleTableContext.d.ts +5 -1
  270. package/dist/types/api/generated/folders.d.ts +1 -0
  271. package/dist/types/api/generated/graphql.d.ts +66 -5
  272. package/dist/types/api/queries/actions/getActions.d.ts +132 -1
  273. package/dist/types/api/queries/activities/getActivities.d.ts +6 -0
  274. package/dist/types/api/queries/activities/updateActivities.d.ts +12 -0
  275. package/dist/types/api/queries/entities/getEntity.d.ts +6 -0
  276. package/dist/types/api/queries/entities/getEntityPanel.d.ts +6 -0
  277. package/dist/types/api/queries/entities/transformDetailsPanelData.d.ts +1 -0
  278. package/dist/types/api/queries/entities/updateEntity.d.ts +6 -0
  279. package/dist/types/api/queries/entityLists/getLists.d.ts +1517 -2
  280. package/dist/types/api/queries/entityLists/types.d.ts +30 -1
  281. package/dist/types/api/queries/entityLists/updateLists.d.ts +166 -3
  282. package/dist/types/api/queries/overview/getOverview.d.ts +6 -0
  283. package/dist/types/api/queries/userDashboard/getUserDashboard.d.ts +6 -0
  284. package/dist/types/api/queries/users/getUsers.d.ts +6 -0
  285. package/dist/types/components/PlayableIcon/PlayableIcon.d.ts +4 -0
  286. package/dist/types/containers/Actions/Actions.d.ts +7 -1
  287. package/dist/types/containers/Actions/ActionsDropdown/ActionsDropdown.d.ts +5 -3
  288. package/dist/types/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.styled.d.ts +0 -1
  289. package/dist/types/containers/ProjectTreeTable/ProjectTreeTable.d.ts +6 -2
  290. package/dist/types/containers/ProjectTreeTable/context/ProjectTableContext.d.ts +4 -1
  291. package/dist/types/containers/ProjectTreeTable/context/ProjectTableProvider.d.ts +11 -2
  292. package/dist/types/containers/ProjectTreeTable/hooks/index.d.ts +1 -0
  293. package/dist/types/containers/ProjectTreeTable/hooks/useCellContextMenu.d.ts +1 -1
  294. package/dist/types/containers/ProjectTreeTable/hooks/useCheckSelectedCellsVisible.d.ts +9 -0
  295. package/dist/types/containers/ProjectTreeTable/hooks/useFolderRelationships.d.ts +2 -2
  296. package/dist/types/containers/ProjectTreeTable/hooks/useKeyboardNavigation.d.ts +3 -3
  297. package/dist/types/containers/ProjectTreeTable/hooks/useUpdateTableData.d.ts +1 -1
  298. package/dist/types/containers/ProjectTreeTable/types/table.d.ts +10 -1
  299. package/dist/types/containers/ProjectTreeTable/utils/getEntityViewerIds.d.ts +4 -0
  300. package/dist/types/containers/ProjectTreeTable/utils/getTypeDefaultValue.d.ts +2 -0
  301. package/dist/types/containers/ProjectTreeTable/utils/index.d.ts +2 -0
  302. package/dist/types/containers/ProjectTreeTable/widgets/CellWidget.d.ts +2 -1
  303. package/dist/types/containers/ProjectTreeTable/widgets/EnumCellValue.d.ts +20 -0
  304. package/dist/types/containers/ProjectTreeTable/widgets/EnumWidget.d.ts +1 -11
  305. package/dist/types/containers/ProjectTreeTable/widgets/ThumbnailWidget.d.ts +1 -0
  306. package/dist/types/context/DetailsPanelContext.d.ts +1 -0
  307. package/dist/types/util/confirmDelete.d.ts +2 -1
  308. package/dist/util.cjs.js +2 -0
  309. package/dist/util.cjs.js.map +1 -1
  310. package/dist/util.es.js +2 -0
  311. package/dist/util.es.js.map +1 -1
  312. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"CellEditingContext.es.js","sources":["../../../../../../src/containers/ProjectTreeTable/context/CellEditingContext.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n useState,\n useCallback,\n useMemo,\n useEffect,\n ReactNode,\n} from 'react'\nimport { CellId } from '../utils/cellUtils'\nimport useUpdateTableData, {\n InheritFromParent,\n UpdateTableEntities,\n} from '../hooks/useUpdateTableData'\nimport { toast } from 'react-toastify'\nimport useValidateUpdates from '../utils/validateUpdateEntities'\nimport useHistory, { UseHistoryReturn } from '../hooks/useHistory'\nimport validateUpdateEntities from '../utils/validateUpdateEntities'\nimport { useProjectTableContext } from './ProjectTableContext'\n\nexport interface CellEditingContextType {\n editingCellId: CellId | null\n setEditingCellId: (id: CellId | null) => void\n isEditing: (id: CellId) => boolean\n updateEntities: UpdateTableEntities\n inheritFromParent: InheritFromParent\n // Add history functions to context\n history: UseHistoryReturn\n undo: () => Promise<void>\n redo: () => Promise<void>\n}\n\nconst CellEditingContext = createContext<CellEditingContextType | undefined>(undefined)\n\nexport const CellEditingProvider: React.FC<{ children: ReactNode }> = ({ children }) => {\n const [editingCellId, setEditingCellId] = useState<CellId | null>(null)\n\n // Memoize these functions to prevent unnecessary re-renders\n const isEditing = useCallback((id: CellId) => id === editingCellId, [editingCellId])\n\n // Get history functions\n const history = useHistory()\n const { pushHistory, undo: undoHistory, redo: redoHistory, canUndo, canRedo } = history\n\n const { updateEntities: updateOverviewEntities, inheritFromParent } = useUpdateTableData({\n pushHistory,\n })\n const { attribFields } = useProjectTableContext()\n\n const handleUpdateEntities: UpdateTableEntities = useCallback(\n async (entities = [], pushToHistory = true) => {\n try {\n // validate the entities before updating\n validateUpdateEntities(entities, attribFields)\n\n // if validation passes, update the entities\n return await updateOverviewEntities(entities, pushToHistory)\n } catch (error: any) {\n // if validation fails, show a toast and return\n toast.error(error.message)\n\n return Promise.reject(error)\n }\n },\n [updateOverviewEntities, attribFields],\n )\n\n // Handle undo\n const handleUndo = async () => {\n const [entitiesToUndo, entitiesToInherit, callbacks] = undoHistory() || []\n\n if (entitiesToUndo && entitiesToUndo.length > 0) {\n try {\n await handleUpdateEntities(entitiesToUndo, false)\n } catch (error) {\n toast.error('Failed to undo changes')\n }\n }\n if (entitiesToInherit && entitiesToInherit.length > 0) {\n try {\n await inheritFromParent(entitiesToInherit, false)\n } catch (error) {\n toast.error('Failed to inherit changes')\n }\n }\n // Execute custom callbacks if any\n if (callbacks && callbacks.length > 0) {\n callbacks.forEach((callback) => {\n try {\n callback()\n } catch (error) {\n toast.error('Failed to execute custom undo action')\n }\n })\n }\n }\n\n // Handle redo\n const handleRedo = async () => {\n const [entitiesToRedo, entitiesToInherit, callbacks] = redoHistory() || []\n\n if (entitiesToRedo && entitiesToRedo.length > 0) {\n try {\n await handleUpdateEntities(entitiesToRedo, false)\n } catch (error) {\n toast.error('Failed to redo changes')\n }\n }\n if (entitiesToInherit && entitiesToInherit.length > 0) {\n try {\n await inheritFromParent(entitiesToInherit, false)\n } catch (error) {\n toast.error('Failed to inherit changes')\n }\n }\n // Execute custom callbacks if any\n if (callbacks && callbacks.length > 0) {\n callbacks.forEach((callback) => {\n try {\n callback()\n } catch (error) {\n toast.error('Failed to execute custom redo action')\n }\n })\n }\n }\n\n const value = useMemo(\n () => ({\n editingCellId,\n setEditingCellId,\n isEditing,\n updateEntities: handleUpdateEntities,\n inheritFromParent,\n undo: handleUndo,\n redo: handleRedo,\n history,\n }),\n [\n editingCellId,\n isEditing,\n handleUpdateEntities,\n inheritFromParent,\n handleUndo,\n handleRedo,\n history,\n ],\n )\n\n // Listen for global undo/redo shortcuts and invoke context handlers\n useEffect(() => {\n const onKeyDown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement\n if (\n target.tagName === 'INPUT' ||\n target.tagName === 'TEXTAREA' ||\n target.isContentEditable ||\n target.getAttribute('role') === 'textbox' ||\n target.tagName === 'LI'\n ) {\n return\n }\n\n const isMac =\n typeof navigator !== 'undefined' &&\n // @ts-expect-error\n ((navigator.userAgentData &&\n // @ts-expect-error\n navigator.userAgentData.platform.toUpperCase().includes('MAC')) ||\n navigator.userAgent.toUpperCase().includes('MAC'))\n const ctrlKey = isMac ? e.metaKey : e.ctrlKey\n\n if (ctrlKey && e.key === 'z') {\n e.preventDefault()\n if (canUndo) handleUndo()\n }\n if (\n (ctrlKey && e.key === 'y') ||\n (ctrlKey && e.shiftKey && e.key === 'z') ||\n (ctrlKey && e.key === 'Z')\n ) {\n e.preventDefault()\n if (canRedo) handleRedo()\n }\n }\n\n document.addEventListener('keydown', onKeyDown)\n return () => document.removeEventListener('keydown', onKeyDown)\n }, [canUndo, canRedo, handleUndo, handleRedo])\n\n return <CellEditingContext.Provider value={value}>{children}</CellEditingContext.Provider>\n}\n\nexport const useCellEditing = (): CellEditingContextType => {\n const context = useContext(CellEditingContext)\n if (context === undefined) {\n throw new Error('useCellEditing must be used within a CellEditingProvider')\n }\n return context\n}\n"],"names":["jsx"],"mappings":"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"}
1
+ {"version":3,"file":"CellEditingContext.es.js","sources":["../../../../../../src/containers/ProjectTreeTable/context/CellEditingContext.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n useState,\n useCallback,\n useMemo,\n useEffect,\n ReactNode,\n} from 'react'\nimport { CellId, parseCellId } from '../utils/cellUtils'\nimport useUpdateTableData, {\n EntityUpdate,\n InheritFromParent,\n InheritFromParentEntity,\n UpdateTableEntities,\n} from '../hooks/useUpdateTableData'\nimport { toast } from 'react-toastify'\nimport useHistory, { UseHistoryReturn } from '../hooks/useHistory'\nimport validateUpdateEntities from '../utils/validateUpdateEntities'\nimport { useProjectTableContext } from './ProjectTableContext'\nimport { useSelectionCellsContext } from './SelectionCellsContext'\nimport { getTypeDefaultValue } from '../utils'\n\nexport interface CellEditingContextType {\n editingCellId: CellId | null\n setEditingCellId: (id: CellId | null) => void\n isEditing: (id: CellId) => boolean\n updateEntities: UpdateTableEntities\n inheritFromParent: InheritFromParent\n // Add history functions to context\n history: UseHistoryReturn\n undo: () => Promise<void>\n redo: () => Promise<void>\n}\n\nconst CellEditingContext = createContext<CellEditingContextType | undefined>(undefined)\n\nexport const CellEditingProvider: React.FC<{ children: ReactNode }> = ({ children }) => {\n const [editingCellId, setEditingCellId] = useState<CellId | null>(null)\n\n // Memoize these functions to prevent unnecessary re-renders\n const isEditing = useCallback((id: CellId) => id === editingCellId, [editingCellId])\n\n // Get history functions\n const history = useHistory()\n const { pushHistory, undo: undoHistory, redo: redoHistory, canUndo, canRedo } = history\n\n const { selectedCells } = useSelectionCellsContext()\n const { updateEntities: updateOverviewEntities, inheritFromParent } = useUpdateTableData({\n pushHistory,\n })\n const { attribFields, getEntityById } = useProjectTableContext()\n\n const handleUpdateEntities: UpdateTableEntities = useCallback(\n async (entities = [], pushToHistory = true) => {\n try {\n // validate the entities before updating\n validateUpdateEntities(entities, attribFields)\n\n // if validation passes, update the entities\n return await updateOverviewEntities(entities, pushToHistory)\n } catch (error: any) {\n // if validation fails, show a toast and return\n toast.error(error.message)\n\n return Promise.reject(error)\n }\n },\n [updateOverviewEntities, attribFields],\n )\n\n // Handle undo\n const handleUndo = async () => {\n const [entitiesToUndo, entitiesToInherit, callbacks] = undoHistory() || []\n\n if (entitiesToUndo && entitiesToUndo.length > 0) {\n try {\n await handleUpdateEntities(entitiesToUndo, false)\n } catch (error) {\n toast.error('Failed to undo changes')\n }\n }\n if (entitiesToInherit && entitiesToInherit.length > 0) {\n try {\n await inheritFromParent(entitiesToInherit, false)\n } catch (error) {\n toast.error('Failed to inherit changes')\n }\n }\n // Execute custom callbacks if any\n if (callbacks && callbacks.length > 0) {\n callbacks.forEach((callback) => {\n try {\n callback()\n } catch (error) {\n toast.error('Failed to execute custom undo action')\n }\n })\n }\n }\n\n // Handle redo\n const handleRedo = async () => {\n const [entitiesToRedo, entitiesToInherit, callbacks] = redoHistory() || []\n\n if (entitiesToRedo && entitiesToRedo.length > 0) {\n try {\n await handleUpdateEntities(entitiesToRedo, false)\n } catch (error) {\n toast.error('Failed to redo changes')\n }\n }\n if (entitiesToInherit && entitiesToInherit.length > 0) {\n try {\n await inheritFromParent(entitiesToInherit, false)\n } catch (error) {\n toast.error('Failed to inherit changes')\n }\n }\n // Execute custom callbacks if any\n if (callbacks && callbacks.length > 0) {\n callbacks.forEach((callback) => {\n try {\n callback()\n } catch (error) {\n toast.error('Failed to execute custom redo action')\n }\n })\n }\n }\n\n // Handle clearing cells\n const handleClear = useCallback(\n async (cells: CellId[]) => {\n // we explicity update the value of the cells to their default values\n const entityUpdates: EntityUpdate[] = []\n // of if they are inheritable, we inherit from the parent entity\n const entityInheriting: InheritFromParentEntity[] = []\n\n for (const cellId of cells) {\n const { colId, rowId } = parseCellId(cellId) || {}\n if (!colId || !rowId) {\n console.warn(`Invalid cellId: ${cellId}`)\n continue\n }\n\n // get the entity from the rowId\n const entity = getEntityById(rowId)\n\n if (!entity) return\n\n // get the field name and check if it is an attribute\n const fieldName = colId.replace('attrib_', '')\n const isAttrib = colId.startsWith('attrib_')\n\n if (!fieldName) {\n console.warn(`Invalid column ID: ${colId}`)\n continue\n }\n\n let defaultValue: any = null\n if (isAttrib) {\n // find default value for the attribute\n const attribField = attribFields.find((f) => f.name === fieldName)\n if (!attribField) {\n console.warn(`Attribute field not found: ${fieldName}`)\n continue\n }\n // check if the attribute is inheritable\n if (attribField.data.inherit) {\n // inherit from parent entity\n // check if this entity has already been added to the inheriting list\n const existingInherit = entityInheriting.find((e) => e.entityId === entity.entityId)\n if (existingInherit) {\n // add the attrib to the existing entity\n existingInherit.attribs.push(fieldName)\n } else {\n // add a new entity to the inheriting list\n entityInheriting.push({\n entityId: entity.entityId,\n attribs: [fieldName],\n entityType: entity.entityType,\n ownAttrib: entity.ownAttrib || [],\n rowId: rowId,\n folderId:\n entity.entityType === 'folder'\n ? entity.parentId\n : entity.entityType === 'task'\n ? entity.folderId\n : undefined,\n })\n }\n continue\n } else {\n // set explicit default value\n defaultValue = attribField.data.default || getTypeDefaultValue(attribField.data.type)\n }\n } else if (fieldName === 'assignees') {\n // for assignees, we set it to an empty array\n defaultValue = getTypeDefaultValue('list_of_strings')\n } else if (fieldName === 'tags') {\n // for tags, we set it to an empty array\n defaultValue = getTypeDefaultValue('list_of_strings')\n } else {\n // we ignore other fields\n console.warn(`Field not editable: ${fieldName}`)\n continue\n }\n\n // create the entity update\n const update: EntityUpdate = {\n id: rowId,\n rowId: rowId,\n field: fieldName,\n value: defaultValue,\n isAttrib,\n type: entity.entityType,\n }\n\n entityUpdates.push(update)\n }\n\n // if we have updates, call the updateEntities function\n if (entityUpdates.length > 0) {\n try {\n await handleUpdateEntities(entityUpdates, true)\n } catch (error) {\n toast.error('Failed to clear selected cells')\n console.error('Error clearing selected cells:', error)\n }\n }\n\n // if we have inheritable attributes, call inheritFromParent\n if (entityInheriting.length > 0) {\n try {\n await inheritFromParent(entityInheriting, true)\n } catch (error) {\n toast.error('Failed to inherit parent values for cleared cells')\n console.error('Error clearing inherited cells:', error)\n }\n }\n\n // if nothing was done, warn the user\n if (entityUpdates.length === 0 && entityInheriting.length === 0) {\n toast.warn('No valid cells selected to clear')\n }\n },\n [attribFields, updateOverviewEntities],\n )\n\n const value = useMemo(\n () => ({\n editingCellId,\n setEditingCellId,\n isEditing,\n updateEntities: handleUpdateEntities,\n inheritFromParent,\n undo: handleUndo,\n redo: handleRedo,\n history,\n }),\n [\n editingCellId,\n isEditing,\n handleUpdateEntities,\n inheritFromParent,\n handleUndo,\n handleRedo,\n history,\n ],\n )\n\n // Listen for shortcuts\n // undo - ctrl + z\n // redo - ctrl + y or ctrl + shift + z\n // clear - backspace or delete\n useEffect(() => {\n const onKeyDown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement\n if (\n target.tagName === 'INPUT' ||\n target.tagName === 'TEXTAREA' ||\n target.isContentEditable ||\n target.getAttribute('role') === 'textbox' ||\n target.tagName === 'LI'\n ) {\n return\n }\n\n const isMac =\n typeof navigator !== 'undefined' &&\n // @ts-expect-error\n ((navigator.userAgentData &&\n // @ts-expect-error\n navigator.userAgentData.platform.toUpperCase().includes('MAC')) ||\n navigator.userAgent.toUpperCase().includes('MAC'))\n const ctrlKey = isMac ? e.metaKey : e.ctrlKey\n\n // undo\n if (ctrlKey && e.key === 'z') {\n e.preventDefault()\n if (canUndo) handleUndo()\n }\n // redo\n if (\n (ctrlKey && e.key === 'y') ||\n (ctrlKey && e.shiftKey && e.key === 'z') ||\n (ctrlKey && e.key === 'Z')\n ) {\n e.preventDefault()\n if (canRedo) handleRedo()\n }\n // clear\n if (e.key === 'Backspace' || e.key === 'Delete') {\n // check we have cells selected\n if (!selectedCells.size) return\n e.preventDefault()\n\n // find selected cells elements\n const selectedCellElements = Array.from(selectedCells).map((cellId) =>\n document.getElementById(cellId),\n )\n\n // check the cell is editable from the classnames\n const isEditable = (cell: HTMLElement | null) => cell?.classList.contains('editable')\n\n // filter out non-editable cells\n const editableCells = selectedCellElements.filter(isEditable)\n if (editableCells.length === 0) {\n toast.warn('No editable cells selected to clear')\n return\n }\n // clear the selected cells\n handleClear(editableCells.map((cell) => cell?.id).filter(Boolean) as CellId[])\n }\n }\n\n document.addEventListener('keydown', onKeyDown)\n return () => document.removeEventListener('keydown', onKeyDown)\n }, [canUndo, canRedo, handleUndo, handleRedo, selectedCells, handleClear])\n\n return <CellEditingContext.Provider value={value}>{children}</CellEditingContext.Provider>\n}\n\nexport const useCellEditing = (): CellEditingContextType => {\n const context = useContext(CellEditingContext)\n if (context === undefined) {\n throw new Error('useCellEditing must be used within a CellEditingProvider')\n }\n return context\n}\n"],"names":["jsx"],"mappings":"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"}
@@ -17,7 +17,7 @@ const ClipboardProvider = ({
17
17
  }) => {
18
18
  const { selectedCells, gridMap, focusedCellId } = SelectionCellsContext.useSelectionCellsContext();
19
19
  const { updateEntities } = CellEditingContext.useCellEditing();
20
- const { getEntityById } = ProjectTableContext.useProjectTableContext();
20
+ const { getEntityById, attribFields } = ProjectTableContext.useProjectTableContext();
21
21
  const getSelectionData = React.useCallback(
22
22
  async (selected, config) => {
23
23
  const { headers, fullRow } = config || {};
@@ -91,7 +91,15 @@ const ClipboardProvider = ({
91
91
  const rowValues = [];
92
92
  for (const colId of filteredColIds) {
93
93
  let cellValue = "";
94
- const foundValue = cellUtils.getCellValue(entity, colId);
94
+ let foundValue = cellUtils.getCellValue(entity, colId);
95
+ if (!foundValue) {
96
+ const field = attribFields.find((f) => f.name === colId.replace("attrib_", ""));
97
+ if (field && field.data.type === "boolean") {
98
+ foundValue = false;
99
+ } else if (field && field.data.type.includes("list_of")) {
100
+ foundValue = [];
101
+ }
102
+ }
95
103
  cellValue = foundValue !== void 0 && foundValue !== null ? String(foundValue) : "";
96
104
  if (colId === "name") {
97
105
  cellValue = clipboardUtils.getEntityPath(entity.entityId || entity.id, entitiesMap);
@@ -336,6 +344,10 @@ const ClipboardProvider = ({
336
344
  copyToClipboard();
337
345
  }
338
346
  if ((e.ctrlKey || e.metaKey) && e.key === "v") {
347
+ const activeEl = document.activeElement;
348
+ if (activeEl && (activeEl.tagName === "INPUT" || activeEl.tagName === "TEXTAREA" || activeEl.isContentEditable)) {
349
+ return;
350
+ }
339
351
  pasteFromClipboard();
340
352
  }
341
353
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ClipboardContext.cjs.js","sources":["../../../../../../src/containers/ProjectTreeTable/context/ClipboardContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useCallback, useMemo, useEffect } from 'react'\n\n// Contexts\nimport { ROW_SELECTION_COLUMN_ID, useSelectionCellsContext } from './SelectionCellsContext'\nimport { useCellEditing } from './CellEditingContext'\n\n// Utils\nimport { getCellValue, getEntityDataById, parseCellId } from '../utils/cellUtils'\n\n// Types\nimport { EntityUpdate } from '../hooks/useUpdateTableData'\n\n// Import from the new modular files\nimport {\n getEntityPath,\n parseClipboardText,\n clipboardError,\n processFieldValue,\n} from './clipboard/clipboardUtils'\nimport { validateClipboardData } from './clipboard/clipboardValidation'\nimport { ClipboardContextType, ClipboardProviderProps } from './clipboard/clipboardTypes'\nimport { useProjectTableContext } from './ProjectTableContext'\n\nconst ClipboardContext = createContext<ClipboardContextType | undefined>(undefined)\n\nexport const ClipboardProvider: React.FC<ClipboardProviderProps> = ({\n children,\n entitiesMap,\n columnEnums,\n columnReadOnly,\n}) => {\n // Get selection information from SelectionContext\n const { selectedCells, gridMap, focusedCellId } = useSelectionCellsContext()\n const { updateEntities } = useCellEditing()\n const { getEntityById } = useProjectTableContext()\n\n const getSelectionData = useCallback(\n async (selected: string[], config?: { headers?: boolean; fullRow?: boolean }) => {\n const { headers, fullRow } = config || {}\n try {\n // First, organize selected cells by row\n const cellsByRow = new Map<string, Set<string>>()\n\n // Parse all selected cells and organize by rowId and colId\n selected.forEach((cellId) => {\n const position = parseCellId(cellId)\n if (!position) return\n\n const { rowId, colId } = position\n\n // do not include row selection column\n if (colId === ROW_SELECTION_COLUMN_ID) return\n\n if (!cellsByRow.has(rowId)) {\n cellsByRow.set(rowId, new Set())\n }\n\n cellsByRow.get(rowId)?.add(colId)\n })\n\n if (fullRow) {\n const selectedRows = selected\n .filter(\n (cellId) =>\n parseCellId(cellId)?.rowId &&\n parseCellId(cellId)?.colId === ROW_SELECTION_COLUMN_ID,\n )\n .map((cellId) => parseCellId(cellId)?.rowId) as string[]\n\n // select the whole row\n // For rows with selection cells, add all available columns\n selectedRows.forEach((rowId) => {\n // add the rowId if it doesn't exist\n if (!cellsByRow.has(rowId)) {\n cellsByRow.set(rowId, new Set())\n }\n const allColumns = Array.from(gridMap.colIdToIndex.keys())\n allColumns.forEach((colId) => {\n cellsByRow.get(rowId)?.add(colId)\n })\n })\n }\n\n // Get sorted row IDs based on their index in the grid\n const sortedRows = Array.from(cellsByRow.keys()).sort((a, b) => {\n const indexA = gridMap.rowIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.rowIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // Build clipboard text\n let clipboardText = ''\n\n // Get the first row to determine columns\n const firstRowId = sortedRows[0]\n if (!firstRowId) return ''\n\n // Get all column IDs for the first row, sorted by their index in the grid\n const colIds = Array.from(cellsByRow.get(firstRowId) || []).sort((a, b) => {\n const indexA = gridMap.colIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.colIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // Include headers if requested\n if (headers && colIds.length > 0) {\n const headerValues: string[] = []\n\n for (const colId of colIds) {\n // Use colId as the column name since we don't have direct access to column names\n const columnName = colId\n headerValues.push(`${columnName.replace(/\"/g, '\"\"')}`)\n }\n\n clipboardText += headerValues.join('\\t') + '\\n'\n }\n\n for (const rowId of sortedRows) {\n // Determine if this is a folder or task by checking which map contains the ID\n const entity = getEntityById(rowId)\n\n if (!entity) {\n console.warn(`Entity not found for rowId: ${rowId}`)\n continue\n }\n\n // Get all column IDs for this row, sorted by their index in the grid\n const colIds = Array.from(cellsByRow.get(rowId) || []).sort((a, b) => {\n const indexA = gridMap.colIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.colIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // Filter out the row selection column from the copied data\n const filteredColIds = colIds.filter((colId) => colId !== ROW_SELECTION_COLUMN_ID)\n\n const rowValues: string[] = []\n\n // For each column in this row\n for (const colId of filteredColIds) {\n // Determine the value based on the column ID\n let cellValue = ''\n // @ts-ignore\n const foundValue = getCellValue(entity, colId)\n cellValue = foundValue !== undefined && foundValue !== null ? String(foundValue) : ''\n\n // Special handling for name field - include full path\n if (colId === 'name') {\n cellValue = getEntityPath(entity.entityId || entity.id, entitiesMap)\n }\n\n if (colId === 'subType') {\n // get folderType or taskType\n if ('folderType' in entity) {\n cellValue = entity.folderType || ''\n }\n if ('taskType' in entity) {\n cellValue = entity.taskType || ''\n }\n }\n\n // Escape double quotes in the cell value and wrap in quotes\n rowValues.push(`${cellValue.replace(/\"/g, '\"\"')}`)\n }\n\n // Add row to clipboard text\n clipboardText += rowValues.join('\\t') + '\\n'\n }\n\n return clipboardText\n } catch (error) {\n console.error('Failed to copy to clipboard:', error)\n }\n },\n [selectedCells, focusedCellId, gridMap, entitiesMap, getEntityById],\n )\n\n const copyToClipboard: ClipboardContextType['copyToClipboard'] = useCallback(\n async (selected, fullRow) => {\n selected = selected || Array.from(selectedCells)\n if (!selected.length) return\n const clipboardText = await getSelectionData(selected, { fullRow })\n if (!clipboardText) {\n clipboardError('No data to copy to clipboard.')\n return\n }\n if (!navigator.clipboard) {\n clipboardError('Clipboard API not supported in this browser.')\n return\n }\n if (!window.isSecureContext) {\n clipboardError('Clipboard operations require a secure HTTPS context.')\n return\n }\n try {\n await navigator.clipboard.writeText(clipboardText)\n console.log('Copied to clipboard successfully', clipboardText)\n } catch (error: any) {\n clipboardError(`Failed to copy to clipboard: ${error.message}`)\n }\n },\n [selectedCells, entitiesMap, gridMap],\n )\n\n const exportCSV: ClipboardContextType['exportCSV'] = useCallback(\n async (selected, projectName, fullRow) => {\n selected = selected || Array.from(selectedCells)\n if (!selected.length) return\n\n try {\n // Get clipboard text with headers included for CSV export\n const clipboardText = await getSelectionData(selected, { headers: true, fullRow })\n if (!clipboardText) return\n\n // create a csv file and download it\n const blob = new Blob([clipboardText], { type: 'text/csv' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n const selectedCount = selected.length\n a.download = `${projectName}-export-${selectedCount}_cells-${new Date()\n .toISOString()\n .slice(0, 10)}.csv`\n a.click()\n URL.revokeObjectURL(url)\n } catch (error) {\n console.error('Failed to copy to clipboard:', error)\n }\n },\n [selectedCells, entitiesMap, gridMap, getSelectionData],\n )\n\n const pasteFromClipboard: ClipboardContextType['pasteFromClipboard'] = useCallback(\n async (selected) => {\n selected = selected || Array.from(selectedCells)\n if (!selected.length) return\n if (!navigator.clipboard) {\n clipboardError('Clipboard API not supported in this browser.')\n return\n }\n if (!window.isSecureContext) {\n clipboardError('Clipboard operations require a secure HTTPS context.')\n return\n }\n let clipboardText: string\n try {\n clipboardText = await navigator.clipboard.readText()\n } catch (error: any) {\n clipboardError(`Failed to read from clipboard: ${error.message}`)\n return\n }\n\n // we can have empty text in the clipboard\n //if (!clipboardText.trim()) return\n\n // Parse the clipboard text\n const parsedData = parseClipboardText(clipboardText)\n if (!parsedData.length) return\n\n // Determine if we have a single value in the clipboard (one row, one column)\n const isSingleCellValue = parsedData.length === 1 && parsedData[0].values.length === 1\n\n // Organize selected cells by row\n const cellsByRow = new Map<string, Set<string>>()\n\n // Parse all selected cells and organize by rowId and colId\n Array.from(selected).forEach((cellId) => {\n const position = parseCellId(cellId)\n if (!position) return\n\n const { rowId, colId } = position\n\n if (!cellsByRow.has(rowId)) {\n cellsByRow.set(rowId, new Set())\n }\n cellsByRow.get(rowId)?.add(colId)\n })\n\n // Get sorted row IDs based on their index in the grid\n const sortedRows = Array.from(cellsByRow.keys()).sort((a, b) => {\n const indexA = gridMap.rowIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.rowIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // For each row, get the sorted column IDs\n const firstRow = sortedRows[0]\n const selectedColIds = Array.from(cellsByRow.get(firstRow) || []).sort((a, b) => {\n const indexA = gridMap.colIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.colIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // First pass: validate all values for status and subType\n for (let colIndex = 0; colIndex < selectedColIds.length; colIndex++) {\n const colId = selectedColIds[colIndex]\n\n for (let rowIndex = 0; rowIndex < sortedRows.length; rowIndex++) {\n const rowId = sortedRows[rowIndex]\n const isFolder = getEntityDataById<'folder'>(rowId, entitiesMap)?.entityType === 'folder'\n\n // Get the appropriate value from the clipboard data\n // If it's a single cell value, use it for all cells\n // Otherwise use the modulo approach to repeat values\n let pasteValue\n if (isSingleCellValue) {\n pasteValue = parsedData[0].values[0]\n } else {\n const pasteRowIndex = rowIndex % parsedData.length\n const pasteColIndex = colIndex % parsedData[pasteRowIndex].values.length\n pasteValue = parsedData[pasteRowIndex].values[pasteColIndex]\n }\n\n // Validate clipboard data for this cell\n const isValid = validateClipboardData({\n colId,\n isFolder,\n pasteValue,\n parsedData,\n columnEnums,\n columnReadOnly,\n rowIndex,\n colIndex,\n isSingleCellValue,\n })\n\n if (!isValid) return\n }\n }\n\n // Create a map to consolidate updates for the same entity\n const entitiesToUpdateMap = new Map<\n string,\n {\n rowId: string\n id: string\n type: string\n fields: Record<string, any>\n attrib: Record<string, any>\n }\n >()\n\n // For each column, prepare updates\n for (let colIndex = 0; colIndex < selectedColIds.length; colIndex++) {\n const colId = selectedColIds[colIndex]\n\n // Skip special handling for 'name' which we don't want to paste\n if (colId === 'name') continue\n\n // Check if this is an attribute field by examining the first entity\n let isAttrib = false\n // Check if the field potentially contains array values\n let fieldValueType: 'string' | 'number' | 'boolean' | 'array' = 'string'\n\n if (sortedRows.length > 0) {\n const firstRowId = sortedRows[0]\n const entity = getEntityById(firstRowId)\n if (entity) {\n isAttrib = colId.startsWith('attrib_')\n\n // Determine if field is an array and its value type\n // @ts-ignore - Check entity property or attribute\n const fieldValue = getCellValue(entity, colId)\n if (Array.isArray(fieldValue)) {\n fieldValueType = 'array'\n } else if (typeof fieldValue === 'number') {\n fieldValueType = 'number'\n } else if (typeof fieldValue === 'boolean') {\n fieldValueType = 'boolean'\n }\n\n // Special case for subType\n if (colId === 'subType') {\n isAttrib = false\n }\n }\n }\n\n // Process each row individually\n for (let rowIndex = 0; rowIndex < sortedRows.length; rowIndex++) {\n const rowId = sortedRows[rowIndex]\n const entityType = getEntityDataById(rowId, entitiesMap)?.entityType\n const isFolder = entityType === 'folder'\n\n // Get the appropriate value from the clipboard data\n let pasteValue\n if (isSingleCellValue) {\n pasteValue = parsedData[0].values[0]\n } else {\n const pasteRowIndex = rowIndex % parsedData.length\n const pasteColIndex = colIndex % parsedData[pasteRowIndex].values.length\n pasteValue = parsedData[pasteRowIndex].values[pasteColIndex]\n }\n\n let fieldToUpdate = colId.split('_').pop() || colId\n\n // Special handling for subType (convert to folderType or taskType)\n if (colId === 'subType') {\n fieldToUpdate = isFolder ? 'folderType' : 'taskType'\n isAttrib = false\n\n // Skip empty values for enum fields\n if (!pasteValue) continue\n }\n\n // Process the value based on its type\n const processedValue = processFieldValue(pasteValue, fieldValueType)\n\n // Get or create entity entry in the map\n const entityKey = `${rowId}-${entityType}`\n if (!entitiesToUpdateMap.has(entityKey) && entityType) {\n entitiesToUpdateMap.set(entityKey, {\n rowId,\n id: rowId,\n type: entityType,\n fields: {},\n attrib: {},\n })\n }\n\n const entityData = entitiesToUpdateMap.get(entityKey)!\n\n // Add the field to the appropriate place\n if (isAttrib) {\n entityData.attrib[fieldToUpdate] = processedValue\n } else {\n entityData.fields[fieldToUpdate] = processedValue\n }\n }\n }\n\n // Convert the consolidated map to EntityUpdate array\n const allEntityUpdates: EntityUpdate[] = []\n\n entitiesToUpdateMap.forEach((entity) => {\n // For regular fields, create one update per field\n Object.entries(entity.fields).forEach(([field, value]) => {\n allEntityUpdates.push({\n rowId: entity.rowId,\n id: entity.id,\n type: entity.type,\n field,\n value,\n })\n })\n\n // For attributes, create one update per attribute\n Object.entries(entity.attrib).forEach(([field, value]) => {\n allEntityUpdates.push({\n rowId: entity.rowId,\n id: entity.id,\n type: entity.type,\n field,\n value,\n isAttrib: true,\n })\n })\n })\n\n // Make a single call to update all entities\n if (allEntityUpdates.length > 0) {\n try {\n await updateEntities(allEntityUpdates)\n } catch (error) {\n console.error('Error updating entities:', error)\n clipboardError(\n `Failed to update: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n }\n },\n [selectedCells, gridMap, entitiesMap, updateEntities, columnEnums, getEntityById],\n )\n\n // Set up keyboard event listeners\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Copy functionality (Ctrl+C or Command+C)\n if ((e.ctrlKey || e.metaKey) && e.key === 'c') {\n copyToClipboard()\n }\n\n // Paste functionality (Ctrl+V or Command+V)\n if ((e.ctrlKey || e.metaKey) && e.key === 'v') {\n pasteFromClipboard()\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [copyToClipboard, pasteFromClipboard])\n\n const value = useMemo(\n () => ({\n copyToClipboard,\n pasteFromClipboard,\n exportCSV,\n }),\n [copyToClipboard, pasteFromClipboard],\n )\n\n return <ClipboardContext.Provider value={value}>{children}</ClipboardContext.Provider>\n}\n\nexport const useClipboard = (): ClipboardContextType => {\n const context = useContext(ClipboardContext)\n if (context === undefined) {\n throw new Error('useClipboard must be used within a ClipboardProvider')\n }\n return context\n}\n"],"names":["createContext","useSelectionCellsContext","useCellEditing","useProjectTableContext","useCallback","parseCellId","ROW_SELECTION_COLUMN_ID","colIds","getCellValue","getEntityPath","clipboardError","parseClipboardText","_a","getEntityDataById","validateClipboardData","processFieldValue","value","useEffect","useMemo","jsx","useContext"],"mappings":";;;;;;;;;;AAuBA,MAAM,mBAAmBA,oBAAgD,MAAS;AAE3E,MAAM,oBAAsD,CAAC;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AAEJ,QAAM,EAAE,eAAe,SAAS,cAAA,IAAkBC,sBAAAA,yBAAyB;AACrE,QAAA,EAAE,eAAe,IAAIC,kCAAe;AACpC,QAAA,EAAE,cAAc,IAAIC,2CAAuB;AAEjD,QAAM,mBAAmBC,MAAA;AAAA,IACvB,OAAO,UAAoB,WAAsD;AAC/E,YAAM,EAAE,SAAS,QAAQ,IAAI,UAAU,CAAC;AACpC,UAAA;AAEI,cAAA,iCAAiB,IAAyB;AAGvC,iBAAA,QAAQ,CAAC,WAAW;;AACrB,gBAAA,WAAWC,sBAAY,MAAM;AACnC,cAAI,CAAC,SAAU;AAET,gBAAA,EAAE,OAAO,MAAA,IAAU;AAGzB,cAAI,UAAUC,sBAAAA,wBAAyB;AAEvC,cAAI,CAAC,WAAW,IAAI,KAAK,GAAG;AAC1B,uBAAW,IAAI,OAAW,oBAAA,IAAA,CAAK;AAAA,UAAA;AAGjC,2BAAW,IAAI,KAAK,MAApB,mBAAuB,IAAI;AAAA,QAAK,CACjC;AAED,YAAI,SAAS;AACX,gBAAM,eAAe,SAClB;AAAA,YACC,CAAC;;AACCD,sCAAY,YAAA,MAAM,MAAlBA,mBAAqB,YACrBA,2BAAY,MAAM,MAAlBA,mBAAqB,WAAUC,sBAAAA;AAAAA;AAAAA,UAAA,EAElC,IAAI,CAAC;;AAAWD,mCAAY,YAAA,MAAM,MAAlBA,mBAAqB;AAAA,WAAK;AAIhC,uBAAA,QAAQ,CAAC,UAAU;AAE9B,gBAAI,CAAC,WAAW,IAAI,KAAK,GAAG;AAC1B,yBAAW,IAAI,OAAW,oBAAA,IAAA,CAAK;AAAA,YAAA;AAEjC,kBAAM,aAAa,MAAM,KAAK,QAAQ,aAAa,MAAM;AAC9C,uBAAA,QAAQ,CAAC,UAAU;;AAC5B,+BAAW,IAAI,KAAK,MAApB,mBAAuB,IAAI;AAAA,YAAK,CACjC;AAAA,UAAA,CACF;AAAA,QAAA;AAIG,cAAA,aAAa,MAAM,KAAK,WAAW,KAAM,CAAA,EAAE,KAAK,CAAC,GAAG,MAAM;AAC9D,gBAAM,SAAS,QAAQ,aAAa,IAAI,CAAC,KAAK;AAC9C,gBAAM,SAAS,QAAQ,aAAa,IAAI,CAAC,KAAK;AAC9C,iBAAO,SAAS;AAAA,QAAA,CACjB;AAGD,YAAI,gBAAgB;AAGd,cAAA,aAAa,WAAW,CAAC;AAC3B,YAAA,CAAC,WAAmB,QAAA;AAGxB,cAAM,SAAS,MAAM,KAAK,WAAW,IAAI,UAAU,KAAK,CAAE,CAAA,EAAE,KAAK,CAAC,GAAG,MAAM;AACzE,gBAAM,SAAS,QAAQ,aAAa,IAAI,CAAC,KAAK;AAC9C,gBAAM,SAAS,QAAQ,aAAa,IAAI,CAAC,KAAK;AAC9C,iBAAO,SAAS;AAAA,QAAA,CACjB;AAGG,YAAA,WAAW,OAAO,SAAS,GAAG;AAChC,gBAAM,eAAyB,CAAC;AAEhC,qBAAW,SAAS,QAAQ;AAE1B,kBAAM,aAAa;AACnB,yBAAa,KAAK,GAAG,WAAW,QAAQ,MAAM,IAAI,CAAC,EAAE;AAAA,UAAA;AAGtC,2BAAA,aAAa,KAAK,GAAI,IAAI;AAAA,QAAA;AAG7C,mBAAW,SAAS,YAAY;AAExB,gBAAA,SAAS,cAAc,KAAK;AAElC,cAAI,CAAC,QAAQ;AACH,oBAAA,KAAK,+BAA+B,KAAK,EAAE;AACnD;AAAA,UAAA;AAIF,gBAAME,UAAS,MAAM,KAAK,WAAW,IAAI,KAAK,KAAK,CAAE,CAAA,EAAE,KAAK,CAAC,GAAG,MAAM;AACpE,kBAAM,SAAS,QAAQ,aAAa,IAAI,CAAC,KAAK;AAC9C,kBAAM,SAAS,QAAQ,aAAa,IAAI,CAAC,KAAK;AAC9C,mBAAO,SAAS;AAAA,UAAA,CACjB;AAGD,gBAAM,iBAAiBA,QAAO,OAAO,CAAC,UAAU,UAAUD,6CAAuB;AAEjF,gBAAM,YAAsB,CAAC;AAG7B,qBAAW,SAAS,gBAAgB;AAElC,gBAAI,YAAY;AAEV,kBAAA,aAAaE,UAAAA,aAAa,QAAQ,KAAK;AAC7C,wBAAY,eAAe,UAAa,eAAe,OAAO,OAAO,UAAU,IAAI;AAGnF,gBAAI,UAAU,QAAQ;AACpB,0BAAYC,eAAc,cAAA,OAAO,YAAY,OAAO,IAAI,WAAW;AAAA,YAAA;AAGrE,gBAAI,UAAU,WAAW;AAEvB,kBAAI,gBAAgB,QAAQ;AAC1B,4BAAY,OAAO,cAAc;AAAA,cAAA;AAEnC,kBAAI,cAAc,QAAQ;AACxB,4BAAY,OAAO,YAAY;AAAA,cAAA;AAAA,YACjC;AAIF,sBAAU,KAAK,GAAG,UAAU,QAAQ,MAAM,IAAI,CAAC,EAAE;AAAA,UAAA;AAIlC,2BAAA,UAAU,KAAK,GAAI,IAAI;AAAA,QAAA;AAGnC,eAAA;AAAA,eACA,OAAO;AACN,gBAAA,MAAM,gCAAgC,KAAK;AAAA,MAAA;AAAA,IAEvD;AAAA,IACA,CAAC,eAAe,eAAe,SAAS,aAAa,aAAa;AAAA,EACpE;AAEA,QAAM,kBAA2DL,MAAA;AAAA,IAC/D,OAAO,UAAU,YAAY;AAChB,iBAAA,YAAY,MAAM,KAAK,aAAa;AAC3C,UAAA,CAAC,SAAS,OAAQ;AACtB,YAAM,gBAAgB,MAAM,iBAAiB,UAAU,EAAE,SAAS;AAClE,UAAI,CAAC,eAAe;AAClBM,uBAAAA,eAAe,+BAA+B;AAC9C;AAAA,MAAA;AAEE,UAAA,CAAC,UAAU,WAAW;AACxBA,uBAAAA,eAAe,8CAA8C;AAC7D;AAAA,MAAA;AAEE,UAAA,CAAC,OAAO,iBAAiB;AAC3BA,uBAAAA,eAAe,sDAAsD;AACrE;AAAA,MAAA;AAEE,UAAA;AACI,cAAA,UAAU,UAAU,UAAU,aAAa;AACzC,gBAAA,IAAI,oCAAoC,aAAa;AAAA,eACtD,OAAY;AACJA,uBAAAA,eAAA,gCAAgC,MAAM,OAAO,EAAE;AAAA,MAAA;AAAA,IAElE;AAAA,IACA,CAAC,eAAe,aAAa,OAAO;AAAA,EACtC;AAEA,QAAM,YAA+CN,MAAA;AAAA,IACnD,OAAO,UAAU,aAAa,YAAY;AAC7B,iBAAA,YAAY,MAAM,KAAK,aAAa;AAC3C,UAAA,CAAC,SAAS,OAAQ;AAElB,UAAA;AAEI,cAAA,gBAAgB,MAAM,iBAAiB,UAAU,EAAE,SAAS,MAAM,SAAS;AACjF,YAAI,CAAC,cAAe;AAGd,cAAA,OAAO,IAAI,KAAK,CAAC,aAAa,GAAG,EAAE,MAAM,YAAY;AACrD,cAAA,MAAM,IAAI,gBAAgB,IAAI;AAC9B,cAAA,IAAI,SAAS,cAAc,GAAG;AACpC,UAAE,OAAO;AACT,cAAM,gBAAgB,SAAS;AAC/B,UAAE,WAAW,GAAG,WAAW,WAAW,aAAa,WAAU,oBAAI,KAAK,GACnE,YAAY,EACZ,MAAM,GAAG,EAAE,CAAC;AACf,UAAE,MAAM;AACR,YAAI,gBAAgB,GAAG;AAAA,eAChB,OAAO;AACN,gBAAA,MAAM,gCAAgC,KAAK;AAAA,MAAA;AAAA,IAEvD;AAAA,IACA,CAAC,eAAe,aAAa,SAAS,gBAAgB;AAAA,EACxD;AAEA,QAAM,qBAAiEA,MAAA;AAAA,IACrE,OAAO,aAAa;;AACP,iBAAA,YAAY,MAAM,KAAK,aAAa;AAC3C,UAAA,CAAC,SAAS,OAAQ;AAClB,UAAA,CAAC,UAAU,WAAW;AACxBM,uBAAAA,eAAe,8CAA8C;AAC7D;AAAA,MAAA;AAEE,UAAA,CAAC,OAAO,iBAAiB;AAC3BA,uBAAAA,eAAe,sDAAsD;AACrE;AAAA,MAAA;AAEE,UAAA;AACA,UAAA;AACc,wBAAA,MAAM,UAAU,UAAU,SAAS;AAAA,eAC5C,OAAY;AACJA,uBAAAA,eAAA,kCAAkC,MAAM,OAAO,EAAE;AAChE;AAAA,MAAA;AAOI,YAAA,aAAaC,kCAAmB,aAAa;AAC/C,UAAA,CAAC,WAAW,OAAQ;AAGlB,YAAA,oBAAoB,WAAW,WAAW,KAAK,WAAW,CAAC,EAAE,OAAO,WAAW;AAG/E,YAAA,iCAAiB,IAAyB;AAGhD,YAAM,KAAK,QAAQ,EAAE,QAAQ,CAAC,WAAW;;AACjC,cAAA,WAAWN,sBAAY,MAAM;AACnC,YAAI,CAAC,SAAU;AAET,cAAA,EAAE,OAAO,MAAA,IAAU;AAEzB,YAAI,CAAC,WAAW,IAAI,KAAK,GAAG;AAC1B,qBAAW,IAAI,OAAW,oBAAA,IAAA,CAAK;AAAA,QAAA;AAEjC,SAAAO,MAAA,WAAW,IAAI,KAAK,MAApB,gBAAAA,IAAuB,IAAI;AAAA,MAAK,CACjC;AAGK,YAAA,aAAa,MAAM,KAAK,WAAW,KAAM,CAAA,EAAE,KAAK,CAAC,GAAG,MAAM;AAC9D,cAAM,SAAS,QAAQ,aAAa,IAAI,CAAC,KAAK;AAC9C,cAAM,SAAS,QAAQ,aAAa,IAAI,CAAC,KAAK;AAC9C,eAAO,SAAS;AAAA,MAAA,CACjB;AAGK,YAAA,WAAW,WAAW,CAAC;AAC7B,YAAM,iBAAiB,MAAM,KAAK,WAAW,IAAI,QAAQ,KAAK,CAAE,CAAA,EAAE,KAAK,CAAC,GAAG,MAAM;AAC/E,cAAM,SAAS,QAAQ,aAAa,IAAI,CAAC,KAAK;AAC9C,cAAM,SAAS,QAAQ,aAAa,IAAI,CAAC,KAAK;AAC9C,eAAO,SAAS;AAAA,MAAA,CACjB;AAGD,eAAS,WAAW,GAAG,WAAW,eAAe,QAAQ,YAAY;AAC7D,cAAA,QAAQ,eAAe,QAAQ;AAErC,iBAAS,WAAW,GAAG,WAAW,WAAW,QAAQ,YAAY;AACzD,gBAAA,QAAQ,WAAW,QAAQ;AACjC,gBAAM,aAAWC,eAAAA,kBAA4B,OAAO,WAAW,MAA9CA,mBAAiD,gBAAe;AAK7E,cAAA;AACJ,cAAI,mBAAmB;AACrB,yBAAa,WAAW,CAAC,EAAE,OAAO,CAAC;AAAA,UAAA,OAC9B;AACC,kBAAA,gBAAgB,WAAW,WAAW;AAC5C,kBAAM,gBAAgB,WAAW,WAAW,aAAa,EAAE,OAAO;AAClE,yBAAa,WAAW,aAAa,EAAE,OAAO,aAAa;AAAA,UAAA;AAI7D,gBAAM,UAAUC,oBAAAA,sBAAsB;AAAA,YACpC;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UAAA,CACD;AAED,cAAI,CAAC,QAAS;AAAA,QAAA;AAAA,MAChB;AAII,YAAA,0CAA0B,IAS9B;AAGF,eAAS,WAAW,GAAG,WAAW,eAAe,QAAQ,YAAY;AAC7D,cAAA,QAAQ,eAAe,QAAQ;AAGrC,YAAI,UAAU,OAAQ;AAGtB,YAAI,WAAW;AAEf,YAAI,iBAA4D;AAE5D,YAAA,WAAW,SAAS,GAAG;AACnB,gBAAA,aAAa,WAAW,CAAC;AACzB,gBAAA,SAAS,cAAc,UAAU;AACvC,cAAI,QAAQ;AACC,uBAAA,MAAM,WAAW,SAAS;AAI/B,kBAAA,aAAaN,UAAAA,aAAa,QAAQ,KAAK;AACzC,gBAAA,MAAM,QAAQ,UAAU,GAAG;AACZ,+BAAA;AAAA,YAAA,WACR,OAAO,eAAe,UAAU;AACxB,+BAAA;AAAA,YAAA,WACR,OAAO,eAAe,WAAW;AACzB,+BAAA;AAAA,YAAA;AAInB,gBAAI,UAAU,WAAW;AACZ,yBAAA;AAAA,YAAA;AAAA,UACb;AAAA,QACF;AAIF,iBAAS,WAAW,GAAG,WAAW,WAAW,QAAQ,YAAY;AACzD,gBAAA,QAAQ,WAAW,QAAQ;AACjC,gBAAM,cAAaK,eAAA,kBAAkB,OAAO,WAAW,MAApCA,mBAAuC;AAC1D,gBAAM,WAAW,eAAe;AAG5B,cAAA;AACJ,cAAI,mBAAmB;AACrB,yBAAa,WAAW,CAAC,EAAE,OAAO,CAAC;AAAA,UAAA,OAC9B;AACC,kBAAA,gBAAgB,WAAW,WAAW;AAC5C,kBAAM,gBAAgB,WAAW,WAAW,aAAa,EAAE,OAAO;AAClE,yBAAa,WAAW,aAAa,EAAE,OAAO,aAAa;AAAA,UAAA;AAG7D,cAAI,gBAAgB,MAAM,MAAM,GAAG,EAAE,SAAS;AAG9C,cAAI,UAAU,WAAW;AACvB,4BAAgB,WAAW,eAAe;AAC/B,uBAAA;AAGX,gBAAI,CAAC,WAAY;AAAA,UAAA;AAIb,gBAAA,iBAAiBE,eAAAA,kBAAkB,YAAY,cAAc;AAGnE,gBAAM,YAAY,GAAG,KAAK,IAAI,UAAU;AACxC,cAAI,CAAC,oBAAoB,IAAI,SAAS,KAAK,YAAY;AACrD,gCAAoB,IAAI,WAAW;AAAA,cACjC;AAAA,cACA,IAAI;AAAA,cACJ,MAAM;AAAA,cACN,QAAQ,CAAC;AAAA,cACT,QAAQ,CAAA;AAAA,YAAC,CACV;AAAA,UAAA;AAGG,gBAAA,aAAa,oBAAoB,IAAI,SAAS;AAGpD,cAAI,UAAU;AACD,uBAAA,OAAO,aAAa,IAAI;AAAA,UAAA,OAC9B;AACM,uBAAA,OAAO,aAAa,IAAI;AAAA,UAAA;AAAA,QACrC;AAAA,MACF;AAIF,YAAM,mBAAmC,CAAC;AAEtB,0BAAA,QAAQ,CAAC,WAAW;AAE/B,eAAA,QAAQ,OAAO,MAAM,EAAE,QAAQ,CAAC,CAAC,OAAOC,MAAK,MAAM;AACxD,2BAAiB,KAAK;AAAA,YACpB,OAAO,OAAO;AAAA,YACd,IAAI,OAAO;AAAA,YACX,MAAM,OAAO;AAAA,YACb;AAAA,YACA,OAAAA;AAAAA,UAAA,CACD;AAAA,QAAA,CACF;AAGM,eAAA,QAAQ,OAAO,MAAM,EAAE,QAAQ,CAAC,CAAC,OAAOA,MAAK,MAAM;AACxD,2BAAiB,KAAK;AAAA,YACpB,OAAO,OAAO;AAAA,YACd,IAAI,OAAO;AAAA,YACX,MAAM,OAAO;AAAA,YACb;AAAA,YACA,OAAAA;AAAAA,YACA,UAAU;AAAA,UAAA,CACX;AAAA,QAAA,CACF;AAAA,MAAA,CACF;AAGG,UAAA,iBAAiB,SAAS,GAAG;AAC3B,YAAA;AACF,gBAAM,eAAe,gBAAgB;AAAA,iBAC9B,OAAO;AACN,kBAAA,MAAM,4BAA4B,KAAK;AAC/CN,yBAAA;AAAA,YACE,qBAAqB,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UAC/E;AAAA,QAAA;AAAA,MACF;AAAA,IAEJ;AAAA,IACA,CAAC,eAAe,SAAS,aAAa,gBAAgB,aAAa,aAAa;AAAA,EAClF;AAGAO,QAAAA,UAAU,MAAM;AACR,UAAA,gBAAgB,CAAC,MAAqB;AAE1C,WAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,KAAK;AAC7B,wBAAA;AAAA,MAAA;AAIlB,WAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,KAAK;AAC1B,2BAAA;AAAA,MAAA;AAAA,IAEvB;AAEO,WAAA,iBAAiB,WAAW,aAAa;AAChD,WAAO,MAAM;AACJ,aAAA,oBAAoB,WAAW,aAAa;AAAA,IACrD;AAAA,EAAA,GACC,CAAC,iBAAiB,kBAAkB,CAAC;AAExC,QAAM,QAAQC,MAAA;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAEF,CAAC,iBAAiB,kBAAkB;AAAA,EACtC;AAEA,SAAQC,2BAAAA,kBAAAA,IAAA,iBAAiB,UAAjB,EAA0B,OAAe,SAAS,CAAA;AAC5D;AAEO,MAAM,eAAe,MAA4B;AAChD,QAAA,UAAUC,iBAAW,gBAAgB;AAC3C,MAAI,YAAY,QAAW;AACnB,UAAA,IAAI,MAAM,sDAAsD;AAAA,EAAA;AAEjE,SAAA;AACT;;;"}
1
+ {"version":3,"file":"ClipboardContext.cjs.js","sources":["../../../../../../src/containers/ProjectTreeTable/context/ClipboardContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useCallback, useMemo, useEffect } from 'react'\n\n// Contexts\nimport { ROW_SELECTION_COLUMN_ID, useSelectionCellsContext } from './SelectionCellsContext'\nimport { useCellEditing } from './CellEditingContext'\n\n// Utils\nimport { getCellValue, getEntityDataById, parseCellId } from '../utils/cellUtils'\n\n// Types\nimport { EntityUpdate } from '../hooks/useUpdateTableData'\n\n// Import from the new modular files\nimport {\n getEntityPath,\n parseClipboardText,\n clipboardError,\n processFieldValue,\n} from './clipboard/clipboardUtils'\nimport { validateClipboardData } from './clipboard/clipboardValidation'\nimport { ClipboardContextType, ClipboardProviderProps } from './clipboard/clipboardTypes'\nimport { useProjectTableContext } from './ProjectTableContext'\n\nconst ClipboardContext = createContext<ClipboardContextType | undefined>(undefined)\n\nexport const ClipboardProvider: React.FC<ClipboardProviderProps> = ({\n children,\n entitiesMap,\n columnEnums,\n columnReadOnly,\n}) => {\n // Get selection information from SelectionContext\n const { selectedCells, gridMap, focusedCellId } = useSelectionCellsContext()\n const { updateEntities } = useCellEditing()\n const { getEntityById, attribFields } = useProjectTableContext()\n\n const getSelectionData = useCallback(\n async (selected: string[], config?: { headers?: boolean; fullRow?: boolean }) => {\n const { headers, fullRow } = config || {}\n try {\n // First, organize selected cells by row\n const cellsByRow = new Map<string, Set<string>>()\n\n // Parse all selected cells and organize by rowId and colId\n selected.forEach((cellId) => {\n const position = parseCellId(cellId)\n if (!position) return\n\n const { rowId, colId } = position\n\n // do not include row selection column\n if (colId === ROW_SELECTION_COLUMN_ID) return\n\n if (!cellsByRow.has(rowId)) {\n cellsByRow.set(rowId, new Set())\n }\n\n cellsByRow.get(rowId)?.add(colId)\n })\n\n if (fullRow) {\n const selectedRows = selected\n .filter(\n (cellId) =>\n parseCellId(cellId)?.rowId &&\n parseCellId(cellId)?.colId === ROW_SELECTION_COLUMN_ID,\n )\n .map((cellId) => parseCellId(cellId)?.rowId) as string[]\n\n // select the whole row\n // For rows with selection cells, add all available columns\n selectedRows.forEach((rowId) => {\n // add the rowId if it doesn't exist\n if (!cellsByRow.has(rowId)) {\n cellsByRow.set(rowId, new Set())\n }\n const allColumns = Array.from(gridMap.colIdToIndex.keys())\n allColumns.forEach((colId) => {\n cellsByRow.get(rowId)?.add(colId)\n })\n })\n }\n\n // Get sorted row IDs based on their index in the grid\n const sortedRows = Array.from(cellsByRow.keys()).sort((a, b) => {\n const indexA = gridMap.rowIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.rowIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // Build clipboard text\n let clipboardText = ''\n\n // Get the first row to determine columns\n const firstRowId = sortedRows[0]\n if (!firstRowId) return ''\n\n // Get all column IDs for the first row, sorted by their index in the grid\n const colIds = Array.from(cellsByRow.get(firstRowId) || []).sort((a, b) => {\n const indexA = gridMap.colIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.colIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // Include headers if requested\n if (headers && colIds.length > 0) {\n const headerValues: string[] = []\n\n for (const colId of colIds) {\n // Use colId as the column name since we don't have direct access to column names\n const columnName = colId\n headerValues.push(`${columnName.replace(/\"/g, '\"\"')}`)\n }\n\n clipboardText += headerValues.join('\\t') + '\\n'\n }\n\n for (const rowId of sortedRows) {\n // Determine if this is a folder or task by checking which map contains the ID\n const entity = getEntityById(rowId)\n\n if (!entity) {\n console.warn(`Entity not found for rowId: ${rowId}`)\n continue\n }\n\n // Get all column IDs for this row, sorted by their index in the grid\n const colIds = Array.from(cellsByRow.get(rowId) || []).sort((a, b) => {\n const indexA = gridMap.colIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.colIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // Filter out the row selection column from the copied data\n const filteredColIds = colIds.filter((colId) => colId !== ROW_SELECTION_COLUMN_ID)\n\n const rowValues: string[] = []\n\n // For each column in this row\n for (const colId of filteredColIds) {\n // Determine the value based on the column ID\n let cellValue = ''\n // @ts-ignore\n let foundValue = getCellValue(entity, colId)\n\n if (!foundValue) {\n // we should look for the default value set out in attribFields\n const field = attribFields.find((f) => f.name === colId.replace('attrib_', ''))\n if (field && field.data.type === 'boolean') {\n foundValue = false // default boolean value\n } else if (field && field.data.type.includes('list_of')) {\n foundValue = [] // default list value\n }\n }\n\n // convert to string if foundValue is not undefined or null use empty string otherwise\n cellValue = foundValue !== undefined && foundValue !== null ? String(foundValue) : ''\n\n // Special handling for name field - include full path\n if (colId === 'name') {\n cellValue = getEntityPath(entity.entityId || entity.id, entitiesMap)\n }\n\n if (colId === 'subType') {\n // get folderType or taskType\n if ('folderType' in entity) {\n cellValue = entity.folderType || ''\n }\n if ('taskType' in entity) {\n cellValue = entity.taskType || ''\n }\n }\n\n // Escape double quotes in the cell value and wrap in quotes\n rowValues.push(`${cellValue.replace(/\"/g, '\"\"')}`)\n }\n\n // Add row to clipboard text\n clipboardText += rowValues.join('\\t') + '\\n'\n }\n\n return clipboardText\n } catch (error) {\n console.error('Failed to copy to clipboard:', error)\n }\n },\n [selectedCells, focusedCellId, gridMap, entitiesMap, getEntityById],\n )\n\n const copyToClipboard: ClipboardContextType['copyToClipboard'] = useCallback(\n async (selected, fullRow) => {\n selected = selected || Array.from(selectedCells)\n if (!selected.length) return\n const clipboardText = await getSelectionData(selected, { fullRow })\n if (!clipboardText) {\n clipboardError('No data to copy to clipboard.')\n return\n }\n if (!navigator.clipboard) {\n clipboardError('Clipboard API not supported in this browser.')\n return\n }\n if (!window.isSecureContext) {\n clipboardError('Clipboard operations require a secure HTTPS context.')\n return\n }\n try {\n await navigator.clipboard.writeText(clipboardText)\n console.log('Copied to clipboard successfully', clipboardText)\n } catch (error: any) {\n clipboardError(`Failed to copy to clipboard: ${error.message}`)\n }\n },\n [selectedCells, entitiesMap, gridMap],\n )\n\n const exportCSV: ClipboardContextType['exportCSV'] = useCallback(\n async (selected, projectName, fullRow) => {\n selected = selected || Array.from(selectedCells)\n if (!selected.length) return\n\n try {\n // Get clipboard text with headers included for CSV export\n const clipboardText = await getSelectionData(selected, { headers: true, fullRow })\n if (!clipboardText) return\n\n // create a csv file and download it\n const blob = new Blob([clipboardText], { type: 'text/csv' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n const selectedCount = selected.length\n a.download = `${projectName}-export-${selectedCount}_cells-${new Date()\n .toISOString()\n .slice(0, 10)}.csv`\n a.click()\n URL.revokeObjectURL(url)\n } catch (error) {\n console.error('Failed to copy to clipboard:', error)\n }\n },\n [selectedCells, entitiesMap, gridMap, getSelectionData],\n )\n\n const pasteFromClipboard: ClipboardContextType['pasteFromClipboard'] = useCallback(\n async (selected) => {\n selected = selected || Array.from(selectedCells)\n if (!selected.length) return\n if (!navigator.clipboard) {\n clipboardError('Clipboard API not supported in this browser.')\n return\n }\n if (!window.isSecureContext) {\n clipboardError('Clipboard operations require a secure HTTPS context.')\n return\n }\n let clipboardText: string\n try {\n clipboardText = await navigator.clipboard.readText()\n } catch (error: any) {\n clipboardError(`Failed to read from clipboard: ${error.message}`)\n return\n }\n\n // we can have empty text in the clipboard\n //if (!clipboardText.trim()) return\n\n // Parse the clipboard text\n const parsedData = parseClipboardText(clipboardText)\n if (!parsedData.length) return\n\n // Determine if we have a single value in the clipboard (one row, one column)\n const isSingleCellValue = parsedData.length === 1 && parsedData[0].values.length === 1\n\n // Organize selected cells by row\n const cellsByRow = new Map<string, Set<string>>()\n\n // Parse all selected cells and organize by rowId and colId\n Array.from(selected).forEach((cellId) => {\n const position = parseCellId(cellId)\n if (!position) return\n\n const { rowId, colId } = position\n\n if (!cellsByRow.has(rowId)) {\n cellsByRow.set(rowId, new Set())\n }\n cellsByRow.get(rowId)?.add(colId)\n })\n\n // Get sorted row IDs based on their index in the grid\n const sortedRows = Array.from(cellsByRow.keys()).sort((a, b) => {\n const indexA = gridMap.rowIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.rowIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // For each row, get the sorted column IDs\n const firstRow = sortedRows[0]\n const selectedColIds = Array.from(cellsByRow.get(firstRow) || []).sort((a, b) => {\n const indexA = gridMap.colIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.colIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // First pass: validate all values for status and subType\n for (let colIndex = 0; colIndex < selectedColIds.length; colIndex++) {\n const colId = selectedColIds[colIndex]\n\n for (let rowIndex = 0; rowIndex < sortedRows.length; rowIndex++) {\n const rowId = sortedRows[rowIndex]\n const isFolder = getEntityDataById<'folder'>(rowId, entitiesMap)?.entityType === 'folder'\n\n // Get the appropriate value from the clipboard data\n // If it's a single cell value, use it for all cells\n // Otherwise use the modulo approach to repeat values\n let pasteValue\n if (isSingleCellValue) {\n pasteValue = parsedData[0].values[0]\n } else {\n const pasteRowIndex = rowIndex % parsedData.length\n const pasteColIndex = colIndex % parsedData[pasteRowIndex].values.length\n pasteValue = parsedData[pasteRowIndex].values[pasteColIndex]\n }\n\n // Validate clipboard data for this cell\n const isValid = validateClipboardData({\n colId,\n isFolder,\n pasteValue,\n parsedData,\n columnEnums,\n columnReadOnly,\n rowIndex,\n colIndex,\n isSingleCellValue,\n })\n\n if (!isValid) return\n }\n }\n\n // Create a map to consolidate updates for the same entity\n const entitiesToUpdateMap = new Map<\n string,\n {\n rowId: string\n id: string\n type: string\n fields: Record<string, any>\n attrib: Record<string, any>\n }\n >()\n\n // For each column, prepare updates\n for (let colIndex = 0; colIndex < selectedColIds.length; colIndex++) {\n const colId = selectedColIds[colIndex]\n\n // Skip special handling for 'name' which we don't want to paste\n if (colId === 'name') continue\n\n // Check if this is an attribute field by examining the first entity\n let isAttrib = false\n // Check if the field potentially contains array values\n let fieldValueType: 'string' | 'number' | 'boolean' | 'array' = 'string'\n\n if (sortedRows.length > 0) {\n const firstRowId = sortedRows[0]\n const entity = getEntityById(firstRowId)\n if (entity) {\n isAttrib = colId.startsWith('attrib_')\n\n // Determine if field is an array and its value type\n // @ts-ignore - Check entity property or attribute\n const fieldValue = getCellValue(entity, colId)\n if (Array.isArray(fieldValue)) {\n fieldValueType = 'array'\n } else if (typeof fieldValue === 'number') {\n fieldValueType = 'number'\n } else if (typeof fieldValue === 'boolean') {\n fieldValueType = 'boolean'\n }\n\n // Special case for subType\n if (colId === 'subType') {\n isAttrib = false\n }\n }\n }\n\n // Process each row individually\n for (let rowIndex = 0; rowIndex < sortedRows.length; rowIndex++) {\n const rowId = sortedRows[rowIndex]\n const entityType = getEntityDataById(rowId, entitiesMap)?.entityType\n const isFolder = entityType === 'folder'\n\n // Get the appropriate value from the clipboard data\n let pasteValue\n if (isSingleCellValue) {\n pasteValue = parsedData[0].values[0]\n } else {\n const pasteRowIndex = rowIndex % parsedData.length\n const pasteColIndex = colIndex % parsedData[pasteRowIndex].values.length\n pasteValue = parsedData[pasteRowIndex].values[pasteColIndex]\n }\n\n let fieldToUpdate = colId.split('_').pop() || colId\n\n // Special handling for subType (convert to folderType or taskType)\n if (colId === 'subType') {\n fieldToUpdate = isFolder ? 'folderType' : 'taskType'\n isAttrib = false\n\n // Skip empty values for enum fields\n if (!pasteValue) continue\n }\n\n // Process the value based on its type\n const processedValue = processFieldValue(pasteValue, fieldValueType)\n\n // Get or create entity entry in the map\n const entityKey = `${rowId}-${entityType}`\n if (!entitiesToUpdateMap.has(entityKey) && entityType) {\n entitiesToUpdateMap.set(entityKey, {\n rowId,\n id: rowId,\n type: entityType,\n fields: {},\n attrib: {},\n })\n }\n\n const entityData = entitiesToUpdateMap.get(entityKey)!\n\n // Add the field to the appropriate place\n if (isAttrib) {\n entityData.attrib[fieldToUpdate] = processedValue\n } else {\n entityData.fields[fieldToUpdate] = processedValue\n }\n }\n }\n\n // Convert the consolidated map to EntityUpdate array\n const allEntityUpdates: EntityUpdate[] = []\n\n entitiesToUpdateMap.forEach((entity) => {\n // For regular fields, create one update per field\n Object.entries(entity.fields).forEach(([field, value]) => {\n allEntityUpdates.push({\n rowId: entity.rowId,\n id: entity.id,\n type: entity.type,\n field,\n value,\n })\n })\n\n // For attributes, create one update per attribute\n Object.entries(entity.attrib).forEach(([field, value]) => {\n allEntityUpdates.push({\n rowId: entity.rowId,\n id: entity.id,\n type: entity.type,\n field,\n value,\n isAttrib: true,\n })\n })\n })\n\n // Make a single call to update all entities\n if (allEntityUpdates.length > 0) {\n try {\n await updateEntities(allEntityUpdates)\n } catch (error) {\n console.error('Error updating entities:', error)\n clipboardError(\n `Failed to update: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n }\n },\n [selectedCells, gridMap, entitiesMap, updateEntities, columnEnums, getEntityById],\n )\n\n // Set up keyboard event listeners\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Copy functionality (Ctrl+C or Command+C)\n if ((e.ctrlKey || e.metaKey) && e.key === 'c') {\n copyToClipboard()\n }\n\n // Paste functionality (Ctrl+V or Command+V)\n if ((e.ctrlKey || e.metaKey) && e.key === 'v') {\n // don't execute paste if focus is inside an input, textarea, or content‐editable element\n const activeEl = document.activeElement as HTMLElement | null\n if (\n activeEl &&\n (activeEl.tagName === 'INPUT' ||\n activeEl.tagName === 'TEXTAREA' ||\n activeEl.isContentEditable)\n ) {\n return\n }\n pasteFromClipboard()\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [copyToClipboard, pasteFromClipboard])\n\n const value = useMemo(\n () => ({\n copyToClipboard,\n pasteFromClipboard,\n exportCSV,\n }),\n [copyToClipboard, pasteFromClipboard],\n )\n\n return <ClipboardContext.Provider value={value}>{children}</ClipboardContext.Provider>\n}\n\nexport const useClipboard = (): ClipboardContextType => {\n const context = useContext(ClipboardContext)\n if (context === undefined) {\n throw new Error('useClipboard must be used within a ClipboardProvider')\n }\n return context\n}\n"],"names":["createContext","useSelectionCellsContext","useCellEditing","useProjectTableContext","useCallback","parseCellId","ROW_SELECTION_COLUMN_ID","colIds","getCellValue","getEntityPath","clipboardError","parseClipboardText","_a","getEntityDataById","validateClipboardData","processFieldValue","value","useEffect","useMemo","jsx","useContext"],"mappings":"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"}
@@ -15,7 +15,7 @@ const ClipboardProvider = ({
15
15
  }) => {
16
16
  const { selectedCells, gridMap, focusedCellId } = useSelectionCellsContext();
17
17
  const { updateEntities } = useCellEditing();
18
- const { getEntityById } = useProjectTableContext();
18
+ const { getEntityById, attribFields } = useProjectTableContext();
19
19
  const getSelectionData = useCallback(
20
20
  async (selected, config) => {
21
21
  const { headers, fullRow } = config || {};
@@ -89,7 +89,15 @@ const ClipboardProvider = ({
89
89
  const rowValues = [];
90
90
  for (const colId of filteredColIds) {
91
91
  let cellValue = "";
92
- const foundValue = getCellValue(entity, colId);
92
+ let foundValue = getCellValue(entity, colId);
93
+ if (!foundValue) {
94
+ const field = attribFields.find((f) => f.name === colId.replace("attrib_", ""));
95
+ if (field && field.data.type === "boolean") {
96
+ foundValue = false;
97
+ } else if (field && field.data.type.includes("list_of")) {
98
+ foundValue = [];
99
+ }
100
+ }
93
101
  cellValue = foundValue !== void 0 && foundValue !== null ? String(foundValue) : "";
94
102
  if (colId === "name") {
95
103
  cellValue = getEntityPath(entity.entityId || entity.id, entitiesMap);
@@ -334,6 +342,10 @@ const ClipboardProvider = ({
334
342
  copyToClipboard();
335
343
  }
336
344
  if ((e.ctrlKey || e.metaKey) && e.key === "v") {
345
+ const activeEl = document.activeElement;
346
+ if (activeEl && (activeEl.tagName === "INPUT" || activeEl.tagName === "TEXTAREA" || activeEl.isContentEditable)) {
347
+ return;
348
+ }
337
349
  pasteFromClipboard();
338
350
  }
339
351
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ClipboardContext.es.js","sources":["../../../../../../src/containers/ProjectTreeTable/context/ClipboardContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useCallback, useMemo, useEffect } from 'react'\n\n// Contexts\nimport { ROW_SELECTION_COLUMN_ID, useSelectionCellsContext } from './SelectionCellsContext'\nimport { useCellEditing } from './CellEditingContext'\n\n// Utils\nimport { getCellValue, getEntityDataById, parseCellId } from '../utils/cellUtils'\n\n// Types\nimport { EntityUpdate } from '../hooks/useUpdateTableData'\n\n// Import from the new modular files\nimport {\n getEntityPath,\n parseClipboardText,\n clipboardError,\n processFieldValue,\n} from './clipboard/clipboardUtils'\nimport { validateClipboardData } from './clipboard/clipboardValidation'\nimport { ClipboardContextType, ClipboardProviderProps } from './clipboard/clipboardTypes'\nimport { useProjectTableContext } from './ProjectTableContext'\n\nconst ClipboardContext = createContext<ClipboardContextType | undefined>(undefined)\n\nexport const ClipboardProvider: React.FC<ClipboardProviderProps> = ({\n children,\n entitiesMap,\n columnEnums,\n columnReadOnly,\n}) => {\n // Get selection information from SelectionContext\n const { selectedCells, gridMap, focusedCellId } = useSelectionCellsContext()\n const { updateEntities } = useCellEditing()\n const { getEntityById } = useProjectTableContext()\n\n const getSelectionData = useCallback(\n async (selected: string[], config?: { headers?: boolean; fullRow?: boolean }) => {\n const { headers, fullRow } = config || {}\n try {\n // First, organize selected cells by row\n const cellsByRow = new Map<string, Set<string>>()\n\n // Parse all selected cells and organize by rowId and colId\n selected.forEach((cellId) => {\n const position = parseCellId(cellId)\n if (!position) return\n\n const { rowId, colId } = position\n\n // do not include row selection column\n if (colId === ROW_SELECTION_COLUMN_ID) return\n\n if (!cellsByRow.has(rowId)) {\n cellsByRow.set(rowId, new Set())\n }\n\n cellsByRow.get(rowId)?.add(colId)\n })\n\n if (fullRow) {\n const selectedRows = selected\n .filter(\n (cellId) =>\n parseCellId(cellId)?.rowId &&\n parseCellId(cellId)?.colId === ROW_SELECTION_COLUMN_ID,\n )\n .map((cellId) => parseCellId(cellId)?.rowId) as string[]\n\n // select the whole row\n // For rows with selection cells, add all available columns\n selectedRows.forEach((rowId) => {\n // add the rowId if it doesn't exist\n if (!cellsByRow.has(rowId)) {\n cellsByRow.set(rowId, new Set())\n }\n const allColumns = Array.from(gridMap.colIdToIndex.keys())\n allColumns.forEach((colId) => {\n cellsByRow.get(rowId)?.add(colId)\n })\n })\n }\n\n // Get sorted row IDs based on their index in the grid\n const sortedRows = Array.from(cellsByRow.keys()).sort((a, b) => {\n const indexA = gridMap.rowIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.rowIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // Build clipboard text\n let clipboardText = ''\n\n // Get the first row to determine columns\n const firstRowId = sortedRows[0]\n if (!firstRowId) return ''\n\n // Get all column IDs for the first row, sorted by their index in the grid\n const colIds = Array.from(cellsByRow.get(firstRowId) || []).sort((a, b) => {\n const indexA = gridMap.colIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.colIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // Include headers if requested\n if (headers && colIds.length > 0) {\n const headerValues: string[] = []\n\n for (const colId of colIds) {\n // Use colId as the column name since we don't have direct access to column names\n const columnName = colId\n headerValues.push(`${columnName.replace(/\"/g, '\"\"')}`)\n }\n\n clipboardText += headerValues.join('\\t') + '\\n'\n }\n\n for (const rowId of sortedRows) {\n // Determine if this is a folder or task by checking which map contains the ID\n const entity = getEntityById(rowId)\n\n if (!entity) {\n console.warn(`Entity not found for rowId: ${rowId}`)\n continue\n }\n\n // Get all column IDs for this row, sorted by their index in the grid\n const colIds = Array.from(cellsByRow.get(rowId) || []).sort((a, b) => {\n const indexA = gridMap.colIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.colIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // Filter out the row selection column from the copied data\n const filteredColIds = colIds.filter((colId) => colId !== ROW_SELECTION_COLUMN_ID)\n\n const rowValues: string[] = []\n\n // For each column in this row\n for (const colId of filteredColIds) {\n // Determine the value based on the column ID\n let cellValue = ''\n // @ts-ignore\n const foundValue = getCellValue(entity, colId)\n cellValue = foundValue !== undefined && foundValue !== null ? String(foundValue) : ''\n\n // Special handling for name field - include full path\n if (colId === 'name') {\n cellValue = getEntityPath(entity.entityId || entity.id, entitiesMap)\n }\n\n if (colId === 'subType') {\n // get folderType or taskType\n if ('folderType' in entity) {\n cellValue = entity.folderType || ''\n }\n if ('taskType' in entity) {\n cellValue = entity.taskType || ''\n }\n }\n\n // Escape double quotes in the cell value and wrap in quotes\n rowValues.push(`${cellValue.replace(/\"/g, '\"\"')}`)\n }\n\n // Add row to clipboard text\n clipboardText += rowValues.join('\\t') + '\\n'\n }\n\n return clipboardText\n } catch (error) {\n console.error('Failed to copy to clipboard:', error)\n }\n },\n [selectedCells, focusedCellId, gridMap, entitiesMap, getEntityById],\n )\n\n const copyToClipboard: ClipboardContextType['copyToClipboard'] = useCallback(\n async (selected, fullRow) => {\n selected = selected || Array.from(selectedCells)\n if (!selected.length) return\n const clipboardText = await getSelectionData(selected, { fullRow })\n if (!clipboardText) {\n clipboardError('No data to copy to clipboard.')\n return\n }\n if (!navigator.clipboard) {\n clipboardError('Clipboard API not supported in this browser.')\n return\n }\n if (!window.isSecureContext) {\n clipboardError('Clipboard operations require a secure HTTPS context.')\n return\n }\n try {\n await navigator.clipboard.writeText(clipboardText)\n console.log('Copied to clipboard successfully', clipboardText)\n } catch (error: any) {\n clipboardError(`Failed to copy to clipboard: ${error.message}`)\n }\n },\n [selectedCells, entitiesMap, gridMap],\n )\n\n const exportCSV: ClipboardContextType['exportCSV'] = useCallback(\n async (selected, projectName, fullRow) => {\n selected = selected || Array.from(selectedCells)\n if (!selected.length) return\n\n try {\n // Get clipboard text with headers included for CSV export\n const clipboardText = await getSelectionData(selected, { headers: true, fullRow })\n if (!clipboardText) return\n\n // create a csv file and download it\n const blob = new Blob([clipboardText], { type: 'text/csv' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n const selectedCount = selected.length\n a.download = `${projectName}-export-${selectedCount}_cells-${new Date()\n .toISOString()\n .slice(0, 10)}.csv`\n a.click()\n URL.revokeObjectURL(url)\n } catch (error) {\n console.error('Failed to copy to clipboard:', error)\n }\n },\n [selectedCells, entitiesMap, gridMap, getSelectionData],\n )\n\n const pasteFromClipboard: ClipboardContextType['pasteFromClipboard'] = useCallback(\n async (selected) => {\n selected = selected || Array.from(selectedCells)\n if (!selected.length) return\n if (!navigator.clipboard) {\n clipboardError('Clipboard API not supported in this browser.')\n return\n }\n if (!window.isSecureContext) {\n clipboardError('Clipboard operations require a secure HTTPS context.')\n return\n }\n let clipboardText: string\n try {\n clipboardText = await navigator.clipboard.readText()\n } catch (error: any) {\n clipboardError(`Failed to read from clipboard: ${error.message}`)\n return\n }\n\n // we can have empty text in the clipboard\n //if (!clipboardText.trim()) return\n\n // Parse the clipboard text\n const parsedData = parseClipboardText(clipboardText)\n if (!parsedData.length) return\n\n // Determine if we have a single value in the clipboard (one row, one column)\n const isSingleCellValue = parsedData.length === 1 && parsedData[0].values.length === 1\n\n // Organize selected cells by row\n const cellsByRow = new Map<string, Set<string>>()\n\n // Parse all selected cells and organize by rowId and colId\n Array.from(selected).forEach((cellId) => {\n const position = parseCellId(cellId)\n if (!position) return\n\n const { rowId, colId } = position\n\n if (!cellsByRow.has(rowId)) {\n cellsByRow.set(rowId, new Set())\n }\n cellsByRow.get(rowId)?.add(colId)\n })\n\n // Get sorted row IDs based on their index in the grid\n const sortedRows = Array.from(cellsByRow.keys()).sort((a, b) => {\n const indexA = gridMap.rowIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.rowIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // For each row, get the sorted column IDs\n const firstRow = sortedRows[0]\n const selectedColIds = Array.from(cellsByRow.get(firstRow) || []).sort((a, b) => {\n const indexA = gridMap.colIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.colIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // First pass: validate all values for status and subType\n for (let colIndex = 0; colIndex < selectedColIds.length; colIndex++) {\n const colId = selectedColIds[colIndex]\n\n for (let rowIndex = 0; rowIndex < sortedRows.length; rowIndex++) {\n const rowId = sortedRows[rowIndex]\n const isFolder = getEntityDataById<'folder'>(rowId, entitiesMap)?.entityType === 'folder'\n\n // Get the appropriate value from the clipboard data\n // If it's a single cell value, use it for all cells\n // Otherwise use the modulo approach to repeat values\n let pasteValue\n if (isSingleCellValue) {\n pasteValue = parsedData[0].values[0]\n } else {\n const pasteRowIndex = rowIndex % parsedData.length\n const pasteColIndex = colIndex % parsedData[pasteRowIndex].values.length\n pasteValue = parsedData[pasteRowIndex].values[pasteColIndex]\n }\n\n // Validate clipboard data for this cell\n const isValid = validateClipboardData({\n colId,\n isFolder,\n pasteValue,\n parsedData,\n columnEnums,\n columnReadOnly,\n rowIndex,\n colIndex,\n isSingleCellValue,\n })\n\n if (!isValid) return\n }\n }\n\n // Create a map to consolidate updates for the same entity\n const entitiesToUpdateMap = new Map<\n string,\n {\n rowId: string\n id: string\n type: string\n fields: Record<string, any>\n attrib: Record<string, any>\n }\n >()\n\n // For each column, prepare updates\n for (let colIndex = 0; colIndex < selectedColIds.length; colIndex++) {\n const colId = selectedColIds[colIndex]\n\n // Skip special handling for 'name' which we don't want to paste\n if (colId === 'name') continue\n\n // Check if this is an attribute field by examining the first entity\n let isAttrib = false\n // Check if the field potentially contains array values\n let fieldValueType: 'string' | 'number' | 'boolean' | 'array' = 'string'\n\n if (sortedRows.length > 0) {\n const firstRowId = sortedRows[0]\n const entity = getEntityById(firstRowId)\n if (entity) {\n isAttrib = colId.startsWith('attrib_')\n\n // Determine if field is an array and its value type\n // @ts-ignore - Check entity property or attribute\n const fieldValue = getCellValue(entity, colId)\n if (Array.isArray(fieldValue)) {\n fieldValueType = 'array'\n } else if (typeof fieldValue === 'number') {\n fieldValueType = 'number'\n } else if (typeof fieldValue === 'boolean') {\n fieldValueType = 'boolean'\n }\n\n // Special case for subType\n if (colId === 'subType') {\n isAttrib = false\n }\n }\n }\n\n // Process each row individually\n for (let rowIndex = 0; rowIndex < sortedRows.length; rowIndex++) {\n const rowId = sortedRows[rowIndex]\n const entityType = getEntityDataById(rowId, entitiesMap)?.entityType\n const isFolder = entityType === 'folder'\n\n // Get the appropriate value from the clipboard data\n let pasteValue\n if (isSingleCellValue) {\n pasteValue = parsedData[0].values[0]\n } else {\n const pasteRowIndex = rowIndex % parsedData.length\n const pasteColIndex = colIndex % parsedData[pasteRowIndex].values.length\n pasteValue = parsedData[pasteRowIndex].values[pasteColIndex]\n }\n\n let fieldToUpdate = colId.split('_').pop() || colId\n\n // Special handling for subType (convert to folderType or taskType)\n if (colId === 'subType') {\n fieldToUpdate = isFolder ? 'folderType' : 'taskType'\n isAttrib = false\n\n // Skip empty values for enum fields\n if (!pasteValue) continue\n }\n\n // Process the value based on its type\n const processedValue = processFieldValue(pasteValue, fieldValueType)\n\n // Get or create entity entry in the map\n const entityKey = `${rowId}-${entityType}`\n if (!entitiesToUpdateMap.has(entityKey) && entityType) {\n entitiesToUpdateMap.set(entityKey, {\n rowId,\n id: rowId,\n type: entityType,\n fields: {},\n attrib: {},\n })\n }\n\n const entityData = entitiesToUpdateMap.get(entityKey)!\n\n // Add the field to the appropriate place\n if (isAttrib) {\n entityData.attrib[fieldToUpdate] = processedValue\n } else {\n entityData.fields[fieldToUpdate] = processedValue\n }\n }\n }\n\n // Convert the consolidated map to EntityUpdate array\n const allEntityUpdates: EntityUpdate[] = []\n\n entitiesToUpdateMap.forEach((entity) => {\n // For regular fields, create one update per field\n Object.entries(entity.fields).forEach(([field, value]) => {\n allEntityUpdates.push({\n rowId: entity.rowId,\n id: entity.id,\n type: entity.type,\n field,\n value,\n })\n })\n\n // For attributes, create one update per attribute\n Object.entries(entity.attrib).forEach(([field, value]) => {\n allEntityUpdates.push({\n rowId: entity.rowId,\n id: entity.id,\n type: entity.type,\n field,\n value,\n isAttrib: true,\n })\n })\n })\n\n // Make a single call to update all entities\n if (allEntityUpdates.length > 0) {\n try {\n await updateEntities(allEntityUpdates)\n } catch (error) {\n console.error('Error updating entities:', error)\n clipboardError(\n `Failed to update: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n }\n },\n [selectedCells, gridMap, entitiesMap, updateEntities, columnEnums, getEntityById],\n )\n\n // Set up keyboard event listeners\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Copy functionality (Ctrl+C or Command+C)\n if ((e.ctrlKey || e.metaKey) && e.key === 'c') {\n copyToClipboard()\n }\n\n // Paste functionality (Ctrl+V or Command+V)\n if ((e.ctrlKey || e.metaKey) && e.key === 'v') {\n pasteFromClipboard()\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [copyToClipboard, pasteFromClipboard])\n\n const value = useMemo(\n () => ({\n copyToClipboard,\n pasteFromClipboard,\n exportCSV,\n }),\n [copyToClipboard, pasteFromClipboard],\n )\n\n return <ClipboardContext.Provider value={value}>{children}</ClipboardContext.Provider>\n}\n\nexport const useClipboard = (): ClipboardContextType => {\n const context = useContext(ClipboardContext)\n if (context === undefined) {\n throw new Error('useClipboard must be used within a ClipboardProvider')\n }\n return context\n}\n"],"names":["colIds","_a","value","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"ClipboardContext.es.js","sources":["../../../../../../src/containers/ProjectTreeTable/context/ClipboardContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useCallback, useMemo, useEffect } from 'react'\n\n// Contexts\nimport { ROW_SELECTION_COLUMN_ID, useSelectionCellsContext } from './SelectionCellsContext'\nimport { useCellEditing } from './CellEditingContext'\n\n// Utils\nimport { getCellValue, getEntityDataById, parseCellId } from '../utils/cellUtils'\n\n// Types\nimport { EntityUpdate } from '../hooks/useUpdateTableData'\n\n// Import from the new modular files\nimport {\n getEntityPath,\n parseClipboardText,\n clipboardError,\n processFieldValue,\n} from './clipboard/clipboardUtils'\nimport { validateClipboardData } from './clipboard/clipboardValidation'\nimport { ClipboardContextType, ClipboardProviderProps } from './clipboard/clipboardTypes'\nimport { useProjectTableContext } from './ProjectTableContext'\n\nconst ClipboardContext = createContext<ClipboardContextType | undefined>(undefined)\n\nexport const ClipboardProvider: React.FC<ClipboardProviderProps> = ({\n children,\n entitiesMap,\n columnEnums,\n columnReadOnly,\n}) => {\n // Get selection information from SelectionContext\n const { selectedCells, gridMap, focusedCellId } = useSelectionCellsContext()\n const { updateEntities } = useCellEditing()\n const { getEntityById, attribFields } = useProjectTableContext()\n\n const getSelectionData = useCallback(\n async (selected: string[], config?: { headers?: boolean; fullRow?: boolean }) => {\n const { headers, fullRow } = config || {}\n try {\n // First, organize selected cells by row\n const cellsByRow = new Map<string, Set<string>>()\n\n // Parse all selected cells and organize by rowId and colId\n selected.forEach((cellId) => {\n const position = parseCellId(cellId)\n if (!position) return\n\n const { rowId, colId } = position\n\n // do not include row selection column\n if (colId === ROW_SELECTION_COLUMN_ID) return\n\n if (!cellsByRow.has(rowId)) {\n cellsByRow.set(rowId, new Set())\n }\n\n cellsByRow.get(rowId)?.add(colId)\n })\n\n if (fullRow) {\n const selectedRows = selected\n .filter(\n (cellId) =>\n parseCellId(cellId)?.rowId &&\n parseCellId(cellId)?.colId === ROW_SELECTION_COLUMN_ID,\n )\n .map((cellId) => parseCellId(cellId)?.rowId) as string[]\n\n // select the whole row\n // For rows with selection cells, add all available columns\n selectedRows.forEach((rowId) => {\n // add the rowId if it doesn't exist\n if (!cellsByRow.has(rowId)) {\n cellsByRow.set(rowId, new Set())\n }\n const allColumns = Array.from(gridMap.colIdToIndex.keys())\n allColumns.forEach((colId) => {\n cellsByRow.get(rowId)?.add(colId)\n })\n })\n }\n\n // Get sorted row IDs based on their index in the grid\n const sortedRows = Array.from(cellsByRow.keys()).sort((a, b) => {\n const indexA = gridMap.rowIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.rowIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // Build clipboard text\n let clipboardText = ''\n\n // Get the first row to determine columns\n const firstRowId = sortedRows[0]\n if (!firstRowId) return ''\n\n // Get all column IDs for the first row, sorted by their index in the grid\n const colIds = Array.from(cellsByRow.get(firstRowId) || []).sort((a, b) => {\n const indexA = gridMap.colIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.colIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // Include headers if requested\n if (headers && colIds.length > 0) {\n const headerValues: string[] = []\n\n for (const colId of colIds) {\n // Use colId as the column name since we don't have direct access to column names\n const columnName = colId\n headerValues.push(`${columnName.replace(/\"/g, '\"\"')}`)\n }\n\n clipboardText += headerValues.join('\\t') + '\\n'\n }\n\n for (const rowId of sortedRows) {\n // Determine if this is a folder or task by checking which map contains the ID\n const entity = getEntityById(rowId)\n\n if (!entity) {\n console.warn(`Entity not found for rowId: ${rowId}`)\n continue\n }\n\n // Get all column IDs for this row, sorted by their index in the grid\n const colIds = Array.from(cellsByRow.get(rowId) || []).sort((a, b) => {\n const indexA = gridMap.colIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.colIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // Filter out the row selection column from the copied data\n const filteredColIds = colIds.filter((colId) => colId !== ROW_SELECTION_COLUMN_ID)\n\n const rowValues: string[] = []\n\n // For each column in this row\n for (const colId of filteredColIds) {\n // Determine the value based on the column ID\n let cellValue = ''\n // @ts-ignore\n let foundValue = getCellValue(entity, colId)\n\n if (!foundValue) {\n // we should look for the default value set out in attribFields\n const field = attribFields.find((f) => f.name === colId.replace('attrib_', ''))\n if (field && field.data.type === 'boolean') {\n foundValue = false // default boolean value\n } else if (field && field.data.type.includes('list_of')) {\n foundValue = [] // default list value\n }\n }\n\n // convert to string if foundValue is not undefined or null use empty string otherwise\n cellValue = foundValue !== undefined && foundValue !== null ? String(foundValue) : ''\n\n // Special handling for name field - include full path\n if (colId === 'name') {\n cellValue = getEntityPath(entity.entityId || entity.id, entitiesMap)\n }\n\n if (colId === 'subType') {\n // get folderType or taskType\n if ('folderType' in entity) {\n cellValue = entity.folderType || ''\n }\n if ('taskType' in entity) {\n cellValue = entity.taskType || ''\n }\n }\n\n // Escape double quotes in the cell value and wrap in quotes\n rowValues.push(`${cellValue.replace(/\"/g, '\"\"')}`)\n }\n\n // Add row to clipboard text\n clipboardText += rowValues.join('\\t') + '\\n'\n }\n\n return clipboardText\n } catch (error) {\n console.error('Failed to copy to clipboard:', error)\n }\n },\n [selectedCells, focusedCellId, gridMap, entitiesMap, getEntityById],\n )\n\n const copyToClipboard: ClipboardContextType['copyToClipboard'] = useCallback(\n async (selected, fullRow) => {\n selected = selected || Array.from(selectedCells)\n if (!selected.length) return\n const clipboardText = await getSelectionData(selected, { fullRow })\n if (!clipboardText) {\n clipboardError('No data to copy to clipboard.')\n return\n }\n if (!navigator.clipboard) {\n clipboardError('Clipboard API not supported in this browser.')\n return\n }\n if (!window.isSecureContext) {\n clipboardError('Clipboard operations require a secure HTTPS context.')\n return\n }\n try {\n await navigator.clipboard.writeText(clipboardText)\n console.log('Copied to clipboard successfully', clipboardText)\n } catch (error: any) {\n clipboardError(`Failed to copy to clipboard: ${error.message}`)\n }\n },\n [selectedCells, entitiesMap, gridMap],\n )\n\n const exportCSV: ClipboardContextType['exportCSV'] = useCallback(\n async (selected, projectName, fullRow) => {\n selected = selected || Array.from(selectedCells)\n if (!selected.length) return\n\n try {\n // Get clipboard text with headers included for CSV export\n const clipboardText = await getSelectionData(selected, { headers: true, fullRow })\n if (!clipboardText) return\n\n // create a csv file and download it\n const blob = new Blob([clipboardText], { type: 'text/csv' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n const selectedCount = selected.length\n a.download = `${projectName}-export-${selectedCount}_cells-${new Date()\n .toISOString()\n .slice(0, 10)}.csv`\n a.click()\n URL.revokeObjectURL(url)\n } catch (error) {\n console.error('Failed to copy to clipboard:', error)\n }\n },\n [selectedCells, entitiesMap, gridMap, getSelectionData],\n )\n\n const pasteFromClipboard: ClipboardContextType['pasteFromClipboard'] = useCallback(\n async (selected) => {\n selected = selected || Array.from(selectedCells)\n if (!selected.length) return\n if (!navigator.clipboard) {\n clipboardError('Clipboard API not supported in this browser.')\n return\n }\n if (!window.isSecureContext) {\n clipboardError('Clipboard operations require a secure HTTPS context.')\n return\n }\n let clipboardText: string\n try {\n clipboardText = await navigator.clipboard.readText()\n } catch (error: any) {\n clipboardError(`Failed to read from clipboard: ${error.message}`)\n return\n }\n\n // we can have empty text in the clipboard\n //if (!clipboardText.trim()) return\n\n // Parse the clipboard text\n const parsedData = parseClipboardText(clipboardText)\n if (!parsedData.length) return\n\n // Determine if we have a single value in the clipboard (one row, one column)\n const isSingleCellValue = parsedData.length === 1 && parsedData[0].values.length === 1\n\n // Organize selected cells by row\n const cellsByRow = new Map<string, Set<string>>()\n\n // Parse all selected cells and organize by rowId and colId\n Array.from(selected).forEach((cellId) => {\n const position = parseCellId(cellId)\n if (!position) return\n\n const { rowId, colId } = position\n\n if (!cellsByRow.has(rowId)) {\n cellsByRow.set(rowId, new Set())\n }\n cellsByRow.get(rowId)?.add(colId)\n })\n\n // Get sorted row IDs based on their index in the grid\n const sortedRows = Array.from(cellsByRow.keys()).sort((a, b) => {\n const indexA = gridMap.rowIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.rowIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // For each row, get the sorted column IDs\n const firstRow = sortedRows[0]\n const selectedColIds = Array.from(cellsByRow.get(firstRow) || []).sort((a, b) => {\n const indexA = gridMap.colIdToIndex.get(a) ?? Infinity\n const indexB = gridMap.colIdToIndex.get(b) ?? Infinity\n return indexA - indexB\n })\n\n // First pass: validate all values for status and subType\n for (let colIndex = 0; colIndex < selectedColIds.length; colIndex++) {\n const colId = selectedColIds[colIndex]\n\n for (let rowIndex = 0; rowIndex < sortedRows.length; rowIndex++) {\n const rowId = sortedRows[rowIndex]\n const isFolder = getEntityDataById<'folder'>(rowId, entitiesMap)?.entityType === 'folder'\n\n // Get the appropriate value from the clipboard data\n // If it's a single cell value, use it for all cells\n // Otherwise use the modulo approach to repeat values\n let pasteValue\n if (isSingleCellValue) {\n pasteValue = parsedData[0].values[0]\n } else {\n const pasteRowIndex = rowIndex % parsedData.length\n const pasteColIndex = colIndex % parsedData[pasteRowIndex].values.length\n pasteValue = parsedData[pasteRowIndex].values[pasteColIndex]\n }\n\n // Validate clipboard data for this cell\n const isValid = validateClipboardData({\n colId,\n isFolder,\n pasteValue,\n parsedData,\n columnEnums,\n columnReadOnly,\n rowIndex,\n colIndex,\n isSingleCellValue,\n })\n\n if (!isValid) return\n }\n }\n\n // Create a map to consolidate updates for the same entity\n const entitiesToUpdateMap = new Map<\n string,\n {\n rowId: string\n id: string\n type: string\n fields: Record<string, any>\n attrib: Record<string, any>\n }\n >()\n\n // For each column, prepare updates\n for (let colIndex = 0; colIndex < selectedColIds.length; colIndex++) {\n const colId = selectedColIds[colIndex]\n\n // Skip special handling for 'name' which we don't want to paste\n if (colId === 'name') continue\n\n // Check if this is an attribute field by examining the first entity\n let isAttrib = false\n // Check if the field potentially contains array values\n let fieldValueType: 'string' | 'number' | 'boolean' | 'array' = 'string'\n\n if (sortedRows.length > 0) {\n const firstRowId = sortedRows[0]\n const entity = getEntityById(firstRowId)\n if (entity) {\n isAttrib = colId.startsWith('attrib_')\n\n // Determine if field is an array and its value type\n // @ts-ignore - Check entity property or attribute\n const fieldValue = getCellValue(entity, colId)\n if (Array.isArray(fieldValue)) {\n fieldValueType = 'array'\n } else if (typeof fieldValue === 'number') {\n fieldValueType = 'number'\n } else if (typeof fieldValue === 'boolean') {\n fieldValueType = 'boolean'\n }\n\n // Special case for subType\n if (colId === 'subType') {\n isAttrib = false\n }\n }\n }\n\n // Process each row individually\n for (let rowIndex = 0; rowIndex < sortedRows.length; rowIndex++) {\n const rowId = sortedRows[rowIndex]\n const entityType = getEntityDataById(rowId, entitiesMap)?.entityType\n const isFolder = entityType === 'folder'\n\n // Get the appropriate value from the clipboard data\n let pasteValue\n if (isSingleCellValue) {\n pasteValue = parsedData[0].values[0]\n } else {\n const pasteRowIndex = rowIndex % parsedData.length\n const pasteColIndex = colIndex % parsedData[pasteRowIndex].values.length\n pasteValue = parsedData[pasteRowIndex].values[pasteColIndex]\n }\n\n let fieldToUpdate = colId.split('_').pop() || colId\n\n // Special handling for subType (convert to folderType or taskType)\n if (colId === 'subType') {\n fieldToUpdate = isFolder ? 'folderType' : 'taskType'\n isAttrib = false\n\n // Skip empty values for enum fields\n if (!pasteValue) continue\n }\n\n // Process the value based on its type\n const processedValue = processFieldValue(pasteValue, fieldValueType)\n\n // Get or create entity entry in the map\n const entityKey = `${rowId}-${entityType}`\n if (!entitiesToUpdateMap.has(entityKey) && entityType) {\n entitiesToUpdateMap.set(entityKey, {\n rowId,\n id: rowId,\n type: entityType,\n fields: {},\n attrib: {},\n })\n }\n\n const entityData = entitiesToUpdateMap.get(entityKey)!\n\n // Add the field to the appropriate place\n if (isAttrib) {\n entityData.attrib[fieldToUpdate] = processedValue\n } else {\n entityData.fields[fieldToUpdate] = processedValue\n }\n }\n }\n\n // Convert the consolidated map to EntityUpdate array\n const allEntityUpdates: EntityUpdate[] = []\n\n entitiesToUpdateMap.forEach((entity) => {\n // For regular fields, create one update per field\n Object.entries(entity.fields).forEach(([field, value]) => {\n allEntityUpdates.push({\n rowId: entity.rowId,\n id: entity.id,\n type: entity.type,\n field,\n value,\n })\n })\n\n // For attributes, create one update per attribute\n Object.entries(entity.attrib).forEach(([field, value]) => {\n allEntityUpdates.push({\n rowId: entity.rowId,\n id: entity.id,\n type: entity.type,\n field,\n value,\n isAttrib: true,\n })\n })\n })\n\n // Make a single call to update all entities\n if (allEntityUpdates.length > 0) {\n try {\n await updateEntities(allEntityUpdates)\n } catch (error) {\n console.error('Error updating entities:', error)\n clipboardError(\n `Failed to update: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n }\n },\n [selectedCells, gridMap, entitiesMap, updateEntities, columnEnums, getEntityById],\n )\n\n // Set up keyboard event listeners\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Copy functionality (Ctrl+C or Command+C)\n if ((e.ctrlKey || e.metaKey) && e.key === 'c') {\n copyToClipboard()\n }\n\n // Paste functionality (Ctrl+V or Command+V)\n if ((e.ctrlKey || e.metaKey) && e.key === 'v') {\n // don't execute paste if focus is inside an input, textarea, or content‐editable element\n const activeEl = document.activeElement as HTMLElement | null\n if (\n activeEl &&\n (activeEl.tagName === 'INPUT' ||\n activeEl.tagName === 'TEXTAREA' ||\n activeEl.isContentEditable)\n ) {\n return\n }\n pasteFromClipboard()\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [copyToClipboard, pasteFromClipboard])\n\n const value = useMemo(\n () => ({\n copyToClipboard,\n pasteFromClipboard,\n exportCSV,\n }),\n [copyToClipboard, pasteFromClipboard],\n )\n\n return <ClipboardContext.Provider value={value}>{children}</ClipboardContext.Provider>\n}\n\nexport const useClipboard = (): ClipboardContextType => {\n const context = useContext(ClipboardContext)\n if (context === undefined) {\n throw new Error('useClipboard must be used within a ClipboardProvider')\n }\n return context\n}\n"],"names":["colIds","_a","value","jsx"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectTableContext.cjs.js","sources":["../../../../../../src/containers/ProjectTreeTable/context/ProjectTableContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\nimport { EntityMap, TableRow } from '../types/table'\nimport {\n FindInheritedValueFromAncestors,\n GetAncestorsOf,\n GetInheritedDependents,\n FindNonInheritedValues,\n} from '../hooks/useFolderRelationships'\nimport { RowId } from '../utils/cellUtils'\n\nimport { ProjectTableProviderProps } from './ProjectTableProvider'\n\nexport type ToggleExpandAll = (rowIds: RowId[], expand?: boolean) => void\nexport type ToggleExpands = (rowIds: RowId[], expand?: boolean) => void\n\nexport interface ProjectTableContextType {\n isInitialized: ProjectTableProviderProps['isInitialized']\n isLoading: ProjectTableProviderProps['isLoading']\n // Project Info\n projectInfo: ProjectTableProviderProps['projectInfo']\n projectName: ProjectTableProviderProps['projectName']\n users: ProjectTableProviderProps['users']\n // Attributes\n attribFields: ProjectTableProviderProps['attribFields']\n error?: string\n scopes: ProjectTableProviderProps['scopes']\n\n // Data\n tableData: TableRow[]\n tasksMap: ProjectTableProviderProps['tasksMap']\n foldersMap: ProjectTableProviderProps['foldersMap']\n entitiesMap: ProjectTableProviderProps['entitiesMap']\n fetchNextPage: ProjectTableProviderProps['fetchNextPage']\n reloadTableData: ProjectTableProviderProps['reloadTableData']\n getEntityById: (id: string) => EntityMap | undefined\n\n // grouping\n taskGroups: ProjectTableProviderProps['taskGroups']\n\n // Filters\n filters: ProjectTableProviderProps['filters']\n setFilters: ProjectTableProviderProps['setFilters']\n queryFilters: ProjectTableProviderProps['queryFilters']\n\n // Hierarchy\n showHierarchy: ProjectTableProviderProps['showHierarchy']\n updateShowHierarchy: ProjectTableProviderProps['updateShowHierarchy']\n\n // Expanded state\n expanded: ProjectTableProviderProps['expanded']\n toggleExpanded: ProjectTableProviderProps['toggleExpanded']\n updateExpanded: ProjectTableProviderProps['updateExpanded']\n toggleExpandAll: ToggleExpandAll\n toggleExpands: ToggleExpands // expand/collapse multiple rows at once\n\n // Sorting\n sorting: ProjectTableProviderProps['sorting']\n updateSorting: ProjectTableProviderProps['updateSorting']\n\n // Folder Relationships\n getInheritedDependents: GetInheritedDependents\n findInheritedValueFromAncestors: FindInheritedValueFromAncestors\n findNonInheritedValues: FindNonInheritedValues\n getAncestorsOf: GetAncestorsOf\n\n // Context menu\n contextMenuItems: ProjectTableProviderProps['contextMenuItems']\n\n // Powerpack context\n powerpack?: ProjectTableProviderProps['powerpack']\n\n // remote modules\n modules: ProjectTableProviderProps['modules']\n}\n\nexport const ProjectTableContext = createContext<ProjectTableContextType | undefined>(undefined)\n\nexport const useProjectTableContext = () => {\n const context = useContext(ProjectTableContext)\n if (!context) {\n throw new Error('useProjectTableContext must be used within a ProjectTableProvider')\n }\n return context\n}\n"],"names":["createContext","useContext"],"mappings":";;;AA2Ea,MAAA,sBAAsBA,oBAAmD,MAAS;AAExF,MAAM,yBAAyB,MAAM;AACpC,QAAA,UAAUC,iBAAW,mBAAmB;AAC9C,MAAI,CAAC,SAAS;AACN,UAAA,IAAI,MAAM,mEAAmE;AAAA,EAAA;AAE9E,SAAA;AACT;;;"}
1
+ {"version":3,"file":"ProjectTableContext.cjs.js","sources":["../../../../../../src/containers/ProjectTreeTable/context/ProjectTableContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\nimport { EntityMap, TableRow } from '../types/table'\nimport {\n FindInheritedValueFromAncestors,\n GetAncestorsOf,\n GetInheritedDependents,\n FindNonInheritedValues,\n} from '../hooks/useFolderRelationships'\nimport { RowId } from '../utils/cellUtils'\n\nimport { ProjectTableProviderProps } from './ProjectTableProvider'\n\nexport type ToggleExpandAll = (rowIds: RowId[], expand?: boolean) => void\nexport type ToggleExpands = (rowIds: RowId[], expand?: boolean) => void\n\nexport interface ProjectTableContextType {\n isInitialized: ProjectTableProviderProps['isInitialized']\n isLoading: ProjectTableProviderProps['isLoading']\n // Project Info\n projectInfo: ProjectTableProviderProps['projectInfo']\n projectName: ProjectTableProviderProps['projectName']\n users: ProjectTableProviderProps['users']\n // Attributes\n attribFields: ProjectTableProviderProps['attribFields']\n error?: string\n scopes: ProjectTableProviderProps['scopes']\n\n // Data\n tableData: TableRow[]\n tasksMap: ProjectTableProviderProps['tasksMap']\n foldersMap: ProjectTableProviderProps['foldersMap']\n entitiesMap: ProjectTableProviderProps['entitiesMap']\n fetchNextPage: ProjectTableProviderProps['fetchNextPage']\n reloadTableData: ProjectTableProviderProps['reloadTableData']\n getEntityById: (id: string, field?: string) => EntityMap | undefined // if the entity is not found, we explicity search for the field\n\n // grouping\n taskGroups: ProjectTableProviderProps['taskGroups']\n\n // Filters\n filters: ProjectTableProviderProps['filters']\n setFilters: ProjectTableProviderProps['setFilters']\n queryFilters: ProjectTableProviderProps['queryFilters']\n\n // Hierarchy\n showHierarchy: ProjectTableProviderProps['showHierarchy']\n updateShowHierarchy: ProjectTableProviderProps['updateShowHierarchy']\n\n // Expanded state\n expanded: ProjectTableProviderProps['expanded']\n setExpanded: ProjectTableProviderProps['setExpanded']\n toggleExpanded: ProjectTableProviderProps['toggleExpanded']\n updateExpanded: ProjectTableProviderProps['updateExpanded']\n toggleExpandAll: ToggleExpandAll\n toggleExpands: ToggleExpands // expand/collapse multiple rows at once\n\n // Sorting\n sorting: ProjectTableProviderProps['sorting']\n updateSorting: ProjectTableProviderProps['updateSorting']\n\n // Folder Relationships\n getInheritedDependents: GetInheritedDependents\n findInheritedValueFromAncestors: FindInheritedValueFromAncestors\n findNonInheritedValues: FindNonInheritedValues\n getAncestorsOf: GetAncestorsOf\n\n // Context menu\n contextMenuItems: ProjectTableProviderProps['contextMenuItems']\n\n // Powerpack context\n powerpack?: ProjectTableProviderProps['powerpack']\n\n // remote modules\n modules: ProjectTableProviderProps['modules']\n\n // player\n playerOpen?: ProjectTableProviderProps['playerOpen']\n onOpenPlayer?: ProjectTableProviderProps['onOpenPlayer']\n}\n\nexport const ProjectTableContext = createContext<ProjectTableContextType | undefined>(undefined)\n\nexport const useProjectTableContext = () => {\n const context = useContext(ProjectTableContext)\n if (!context) {\n throw new Error('useProjectTableContext must be used within a ProjectTableProvider')\n }\n return context\n}\n"],"names":["createContext","useContext"],"mappings":";;;AAgFa,MAAA,sBAAsBA,oBAAmD,MAAS;AAExF,MAAM,yBAAyB,MAAM;AACpC,QAAA,UAAUC,iBAAW,mBAAmB;AAC9C,MAAI,CAAC,SAAS;AACN,UAAA,IAAI,MAAM,mEAAmE;AAAA,EAAA;AAE9E,SAAA;AACT;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectTableContext.es.js","sources":["../../../../../../src/containers/ProjectTreeTable/context/ProjectTableContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\nimport { EntityMap, TableRow } from '../types/table'\nimport {\n FindInheritedValueFromAncestors,\n GetAncestorsOf,\n GetInheritedDependents,\n FindNonInheritedValues,\n} from '../hooks/useFolderRelationships'\nimport { RowId } from '../utils/cellUtils'\n\nimport { ProjectTableProviderProps } from './ProjectTableProvider'\n\nexport type ToggleExpandAll = (rowIds: RowId[], expand?: boolean) => void\nexport type ToggleExpands = (rowIds: RowId[], expand?: boolean) => void\n\nexport interface ProjectTableContextType {\n isInitialized: ProjectTableProviderProps['isInitialized']\n isLoading: ProjectTableProviderProps['isLoading']\n // Project Info\n projectInfo: ProjectTableProviderProps['projectInfo']\n projectName: ProjectTableProviderProps['projectName']\n users: ProjectTableProviderProps['users']\n // Attributes\n attribFields: ProjectTableProviderProps['attribFields']\n error?: string\n scopes: ProjectTableProviderProps['scopes']\n\n // Data\n tableData: TableRow[]\n tasksMap: ProjectTableProviderProps['tasksMap']\n foldersMap: ProjectTableProviderProps['foldersMap']\n entitiesMap: ProjectTableProviderProps['entitiesMap']\n fetchNextPage: ProjectTableProviderProps['fetchNextPage']\n reloadTableData: ProjectTableProviderProps['reloadTableData']\n getEntityById: (id: string) => EntityMap | undefined\n\n // grouping\n taskGroups: ProjectTableProviderProps['taskGroups']\n\n // Filters\n filters: ProjectTableProviderProps['filters']\n setFilters: ProjectTableProviderProps['setFilters']\n queryFilters: ProjectTableProviderProps['queryFilters']\n\n // Hierarchy\n showHierarchy: ProjectTableProviderProps['showHierarchy']\n updateShowHierarchy: ProjectTableProviderProps['updateShowHierarchy']\n\n // Expanded state\n expanded: ProjectTableProviderProps['expanded']\n toggleExpanded: ProjectTableProviderProps['toggleExpanded']\n updateExpanded: ProjectTableProviderProps['updateExpanded']\n toggleExpandAll: ToggleExpandAll\n toggleExpands: ToggleExpands // expand/collapse multiple rows at once\n\n // Sorting\n sorting: ProjectTableProviderProps['sorting']\n updateSorting: ProjectTableProviderProps['updateSorting']\n\n // Folder Relationships\n getInheritedDependents: GetInheritedDependents\n findInheritedValueFromAncestors: FindInheritedValueFromAncestors\n findNonInheritedValues: FindNonInheritedValues\n getAncestorsOf: GetAncestorsOf\n\n // Context menu\n contextMenuItems: ProjectTableProviderProps['contextMenuItems']\n\n // Powerpack context\n powerpack?: ProjectTableProviderProps['powerpack']\n\n // remote modules\n modules: ProjectTableProviderProps['modules']\n}\n\nexport const ProjectTableContext = createContext<ProjectTableContextType | undefined>(undefined)\n\nexport const useProjectTableContext = () => {\n const context = useContext(ProjectTableContext)\n if (!context) {\n throw new Error('useProjectTableContext must be used within a ProjectTableProvider')\n }\n return context\n}\n"],"names":[],"mappings":";AA2Ea,MAAA,sBAAsB,cAAmD,MAAS;AAExF,MAAM,yBAAyB,MAAM;AACpC,QAAA,UAAU,WAAW,mBAAmB;AAC9C,MAAI,CAAC,SAAS;AACN,UAAA,IAAI,MAAM,mEAAmE;AAAA,EAAA;AAE9E,SAAA;AACT;"}
1
+ {"version":3,"file":"ProjectTableContext.es.js","sources":["../../../../../../src/containers/ProjectTreeTable/context/ProjectTableContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\nimport { EntityMap, TableRow } from '../types/table'\nimport {\n FindInheritedValueFromAncestors,\n GetAncestorsOf,\n GetInheritedDependents,\n FindNonInheritedValues,\n} from '../hooks/useFolderRelationships'\nimport { RowId } from '../utils/cellUtils'\n\nimport { ProjectTableProviderProps } from './ProjectTableProvider'\n\nexport type ToggleExpandAll = (rowIds: RowId[], expand?: boolean) => void\nexport type ToggleExpands = (rowIds: RowId[], expand?: boolean) => void\n\nexport interface ProjectTableContextType {\n isInitialized: ProjectTableProviderProps['isInitialized']\n isLoading: ProjectTableProviderProps['isLoading']\n // Project Info\n projectInfo: ProjectTableProviderProps['projectInfo']\n projectName: ProjectTableProviderProps['projectName']\n users: ProjectTableProviderProps['users']\n // Attributes\n attribFields: ProjectTableProviderProps['attribFields']\n error?: string\n scopes: ProjectTableProviderProps['scopes']\n\n // Data\n tableData: TableRow[]\n tasksMap: ProjectTableProviderProps['tasksMap']\n foldersMap: ProjectTableProviderProps['foldersMap']\n entitiesMap: ProjectTableProviderProps['entitiesMap']\n fetchNextPage: ProjectTableProviderProps['fetchNextPage']\n reloadTableData: ProjectTableProviderProps['reloadTableData']\n getEntityById: (id: string, field?: string) => EntityMap | undefined // if the entity is not found, we explicity search for the field\n\n // grouping\n taskGroups: ProjectTableProviderProps['taskGroups']\n\n // Filters\n filters: ProjectTableProviderProps['filters']\n setFilters: ProjectTableProviderProps['setFilters']\n queryFilters: ProjectTableProviderProps['queryFilters']\n\n // Hierarchy\n showHierarchy: ProjectTableProviderProps['showHierarchy']\n updateShowHierarchy: ProjectTableProviderProps['updateShowHierarchy']\n\n // Expanded state\n expanded: ProjectTableProviderProps['expanded']\n setExpanded: ProjectTableProviderProps['setExpanded']\n toggleExpanded: ProjectTableProviderProps['toggleExpanded']\n updateExpanded: ProjectTableProviderProps['updateExpanded']\n toggleExpandAll: ToggleExpandAll\n toggleExpands: ToggleExpands // expand/collapse multiple rows at once\n\n // Sorting\n sorting: ProjectTableProviderProps['sorting']\n updateSorting: ProjectTableProviderProps['updateSorting']\n\n // Folder Relationships\n getInheritedDependents: GetInheritedDependents\n findInheritedValueFromAncestors: FindInheritedValueFromAncestors\n findNonInheritedValues: FindNonInheritedValues\n getAncestorsOf: GetAncestorsOf\n\n // Context menu\n contextMenuItems: ProjectTableProviderProps['contextMenuItems']\n\n // Powerpack context\n powerpack?: ProjectTableProviderProps['powerpack']\n\n // remote modules\n modules: ProjectTableProviderProps['modules']\n\n // player\n playerOpen?: ProjectTableProviderProps['playerOpen']\n onOpenPlayer?: ProjectTableProviderProps['onOpenPlayer']\n}\n\nexport const ProjectTableContext = createContext<ProjectTableContextType | undefined>(undefined)\n\nexport const useProjectTableContext = () => {\n const context = useContext(ProjectTableContext)\n if (!context) {\n throw new Error('useProjectTableContext must be used within a ProjectTableProvider')\n }\n return context\n}\n"],"names":[],"mappings":";AAgFa,MAAA,sBAAsB,cAAmD,MAAS;AAExF,MAAM,yBAAyB,MAAM;AACpC,QAAA,UAAU,WAAW,mBAAmB;AAC9C,MAAI,CAAC,SAAS;AACN,UAAA,IAAI,MAAM,mEAAmE;AAAA,EAAA;AAE9E,SAAA;AACT;"}
@@ -42,7 +42,10 @@ const ProjectTableProvider = ({
42
42
  contextMenuItems,
43
43
  powerpack,
44
44
  modules,
45
- groupByConfig
45
+ groupByConfig,
46
+ // player
47
+ playerOpen,
48
+ onOpenPlayer
46
49
  }) => {
47
50
  const defaultTableData = useBuildProjectDataTable({
48
51
  foldersMap,
@@ -70,7 +73,7 @@ const ProjectTableProvider = ({
70
73
  );
71
74
  const tableData = groupBy && groupedTableData ? groupedTableData : defaultTableData;
72
75
  const getEntityById = React.useCallback(
73
- (id) => {
76
+ (id, field = "entityId") => {
74
77
  if (typeof id !== "string") {
75
78
  console.warn("getEntityById called with non-string id:", id);
76
79
  return void 0;
@@ -83,6 +86,11 @@ const ProjectTableProvider = ({
83
86
  } else if (entitiesMap.has(parsedId)) {
84
87
  return entitiesMap.get(parsedId);
85
88
  }
89
+ for (const [_, entity] of entitiesMap) {
90
+ if (entity[field] === parsedId) {
91
+ return entity;
92
+ }
93
+ }
86
94
  return void 0;
87
95
  },
88
96
  [foldersMap, tasksMap, entitiesMap]
@@ -169,6 +177,7 @@ const ProjectTableProvider = ({
169
177
  updateShowHierarchy,
170
178
  // expanded state
171
179
  expanded,
180
+ setExpanded,
172
181
  toggleExpanded,
173
182
  updateExpanded,
174
183
  toggleExpandAll,
@@ -186,7 +195,10 @@ const ProjectTableProvider = ({
186
195
  contextMenuItems,
187
196
  // powerpack context
188
197
  powerpack,
189
- modules
198
+ modules,
199
+ // player
200
+ playerOpen,
201
+ onOpenPlayer
190
202
  },
191
203
  children
192
204
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectTableProvider.cjs.js","sources":["../../../../../../src/containers/ProjectTreeTable/context/ProjectTableProvider.tsx"],"sourcesContent":["/**\n * Project Table Context\n *\n * This context serves as the central data management layer for the project table component.\n * It performs three main functions:\n *\n * 1. **Props Forwarding**: Acts as a bridge to forward essential props (project info, users,\n * attributes, filters, etc.) down to child components throughout the table hierarchy.\n *\n * 2. **Table Data Structure Building**: Transforms raw project data into structured table rows\n * that can be consumed by the table component. This includes processing folders, tasks,\n * and entities into a unified table format.\n *\n * 3. **Multi-Modal Data Presentation**: Supports three different data presentation modes:\n * - **Hierarchy Mode**: Builds nested folder/task relationships with expandable rows\n * - **Tasks List Mode**: Flattened view of tasks without hierarchical structure\n * - **Groups Mode**: Groups entities by specified criteria (entity type, custom groups)\n *\n * The context also provides utility functions for entity relationships, expansion state\n * management, filtering, sorting, and folder inheritance operations.\n */\nimport { ReactNode, useCallback, useMemo } from 'react'\nimport { ExpandedState, OnChangeFn, SortingState } from '@tanstack/react-table'\nimport useBuildProjectDataTable from '../hooks/useBuildProjectDataTable'\nimport { Filter } from '@ynput/ayon-react-components'\nimport {\n EntitiesMap,\n EntityMap,\n FolderNodeMap,\n TableRow,\n TaskNodeMap,\n TasksByFolderMap,\n} from '../types/table'\nimport useFolderRelationships, {\n FindInheritedValueFromAncestors,\n GetAncestorsOf,\n GetInheritedDependents,\n FindNonInheritedValues,\n} from '../hooks/useFolderRelationships'\nimport { RowId } from '../utils/cellUtils'\nimport { ProjectModel } from '../types/project'\nimport { ProjectTableAttribute, LoadingTasks } from '../types'\nimport { QueryFilter } from '../types/folders'\nimport { ContextMenuItemConstructors } from '../hooks/useCellContextMenu'\nimport { AttributeModel, EntityGroup } from '@shared/api'\nimport useBuildGroupByTableData, {\n GroupByEntityType,\n ROW_ID_SEPARATOR,\n} from '../hooks/useBuildGroupByTableData'\nimport { PowerpackContextType } from '@shared/context'\nimport { useColumnSettingsContext } from './ColumnSettingsContext'\nimport { ProjectTableModulesType } from '../hooks'\nimport { ProjectTableContext, ProjectTableContextType } from './ProjectTableContext'\n\nexport const parseRowId = (rowId: string) => rowId?.split(ROW_ID_SEPARATOR)[0] || rowId\n\nexport type TableUser = {\n name: string\n fullName?: string\n}\n\nexport interface ProjectTableProviderProps {\n children: ReactNode\n isInitialized: boolean\n\n // loading\n isLoading: boolean\n isLoadingMore: boolean\n loadingTasks?: LoadingTasks\n error?: string\n // Project Info\n projectInfo?: ProjectModel\n projectName: string\n users: TableUser[]\n // Attributes\n attribFields: ProjectTableAttribute[]\n scopes: string[]\n\n // data\n tasksMap: TaskNodeMap\n foldersMap: FolderNodeMap\n entitiesMap: EntitiesMap\n tasksByFolderMap: TasksByFolderMap\n tableRows?: TableRow[] // any extra rows that we want to add to the table\n\n // grouping\n taskGroups: EntityGroup[]\n\n // data functions\n fetchNextPage: (value?: string) => void\n reloadTableData: () => void\n\n // Filters\n filters: Filter[]\n setFilters: (filters: Filter[]) => void\n queryFilters: {\n filter: QueryFilter | undefined\n filterString?: string\n search: string | undefined\n }\n\n // Hierarchy\n showHierarchy: boolean\n updateShowHierarchy: (showHierarchy: boolean) => void\n\n // Expanded state\n expanded: ExpandedState\n toggleExpanded: (id: string) => void\n updateExpanded: OnChangeFn<ExpandedState>\n setExpanded: (expanded: ExpandedState) => void\n\n // Sorting\n sorting: SortingState\n updateSorting: OnChangeFn<SortingState>\n\n // context menu\n contextMenuItems: ContextMenuItemConstructors\n\n // powerpack context\n powerpack?: PowerpackContextType\n\n // remote modules\n modules: ProjectTableModulesType\n\n groupByConfig?: {\n entityType?: GroupByEntityType\n }\n}\n\nexport const ProjectTableProvider = ({\n children,\n foldersMap,\n tableRows,\n tasksMap,\n entitiesMap,\n tasksByFolderMap,\n expanded,\n projectInfo,\n showHierarchy,\n loadingTasks,\n isLoadingMore,\n isLoading,\n error,\n isInitialized,\n projectName,\n users,\n attribFields,\n scopes,\n taskGroups,\n filters,\n setFilters,\n queryFilters,\n updateShowHierarchy,\n toggleExpanded,\n updateExpanded,\n sorting,\n updateSorting,\n fetchNextPage,\n reloadTableData,\n setExpanded,\n contextMenuItems,\n powerpack,\n modules,\n groupByConfig,\n}: ProjectTableProviderProps) => {\n // DATA TO TABLE\n const defaultTableData = useBuildProjectDataTable({\n foldersMap,\n tasksMap,\n rows: tableRows,\n tasksByFolderMap,\n expanded,\n projectInfo,\n showHierarchy,\n loadingTasks,\n isLoadingMore,\n })\n const { groupBy, groupByConfig: { showEmpty: showEmptyGroups = false } = {} } =\n useColumnSettingsContext()\n\n const buildGroupByTableData = useBuildGroupByTableData({\n entities: entitiesMap,\n entityType: groupByConfig?.entityType,\n groups: taskGroups,\n project: projectInfo,\n attribFields,\n showEmpty: showEmptyGroups,\n })\n\n // if we are grouping by something, we ignore current tableData and format the data based on the groupBy\n const groupedTableData = useMemo(\n () => !!groupBy && buildGroupByTableData(groupBy),\n [groupBy, entitiesMap, taskGroups],\n )\n\n const tableData = groupBy && groupedTableData ? groupedTableData : defaultTableData\n\n const getEntityById = useCallback(\n (id: string): EntityMap | undefined => {\n // defensive check to ensure id is a string\n if (typeof id !== 'string') {\n console.warn('getEntityById called with non-string id:', id)\n return undefined\n }\n // always parse the id to remove any suffixes\n // this can happen if the id is a group by id (we need to make the row id unique)\n const parsedId = parseRowId(id)\n if (foldersMap.has(parsedId)) {\n return foldersMap.get(parsedId)\n } else if (tasksMap.has(parsedId)) {\n return tasksMap.get(parsedId)\n } else if (entitiesMap.has(parsedId)) {\n return entitiesMap.get(parsedId)\n }\n\n // Return undefined if not found\n return undefined\n },\n [foldersMap, tasksMap, entitiesMap],\n )\n\n // get folder relationship functions\n const {\n getInheritedDependents,\n getChildrenEntities,\n findInheritedValueFromAncestors,\n findNonInheritedValues,\n getAncestorsOf,\n } = useFolderRelationships({\n entitiesMap,\n tasksMap,\n tasksByFolderMap,\n getEntityById,\n projectAttrib: projectInfo?.attrib,\n attribFields: attribFields,\n })\n\n const toggleExpandAll: ProjectTableContextType['toggleExpandAll'] = useCallback(\n (rowIds, expandAll) => {\n const expandedState = typeof expanded === 'object' ? expanded : {}\n\n const newExpandedState = { ...expandedState }\n\n rowIds.forEach((rowId) => {\n // get all children of the rowId using tableData\n const childIds = getChildrenEntities(rowId).map((child) => child.id)\n // check if the rowId is expanded\n const isExpanded = expandedState[rowId] || false\n\n if (expandAll !== undefined ? !expandAll : isExpanded) {\n // collapse all children\n newExpandedState[rowId] = false\n childIds.forEach((id) => {\n newExpandedState[id] = false\n })\n } else {\n // expand all children\n newExpandedState[rowId] = true\n childIds.forEach((id) => {\n newExpandedState[id] = true\n })\n }\n })\n\n setExpanded(newExpandedState)\n },\n [expanded, getChildrenEntities, setExpanded],\n )\n\n const toggleExpands: ProjectTableContextType['toggleExpands'] = useCallback(\n (rowIds, expand) => {\n const expandedState = typeof expanded === 'object' ? expanded : {}\n const newExpandedState = { ...expandedState }\n\n rowIds.forEach((rowId) => {\n if (expand !== undefined) {\n // Use the provided expand parameter\n newExpandedState[rowId] = expand\n } else {\n // Toggle based on current state\n newExpandedState[rowId] = !expandedState[rowId]\n }\n })\n\n setExpanded(newExpandedState)\n },\n [expanded, setExpanded],\n )\n\n return (\n <ProjectTableContext.Provider\n value={{\n // from this context\n tableData,\n // forwarded on\n isInitialized,\n isLoading,\n error,\n projectInfo,\n attribFields,\n scopes,\n users,\n projectName,\n tasksMap,\n foldersMap,\n entitiesMap,\n fetchNextPage,\n reloadTableData,\n taskGroups,\n // filters\n filters,\n setFilters,\n queryFilters,\n // hierarchy\n showHierarchy,\n updateShowHierarchy,\n // expanded state\n expanded,\n toggleExpanded,\n updateExpanded,\n toggleExpandAll,\n toggleExpands,\n // sorting\n sorting,\n updateSorting,\n getEntityById,\n // folder relationships\n getInheritedDependents,\n findInheritedValueFromAncestors,\n findNonInheritedValues,\n getAncestorsOf,\n // context menu\n contextMenuItems,\n // powerpack context\n powerpack,\n modules,\n }}\n >\n {children}\n </ProjectTableContext.Provider>\n )\n}\n"],"names":["ROW_ID_SEPARATOR","useColumnSettingsContext","useBuildGroupByTableData","useMemo","useCallback","jsx","ProjectTableContext"],"mappings":"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"}
1
+ {"version":3,"file":"ProjectTableProvider.cjs.js","sources":["../../../../../../src/containers/ProjectTreeTable/context/ProjectTableProvider.tsx"],"sourcesContent":["/**\n * Project Table Context\n *\n * This context serves as the central data management layer for the project table component.\n * It performs three main functions:\n *\n * 1. **Props Forwarding**: Acts as a bridge to forward essential props (project info, users,\n * attributes, filters, etc.) down to child components throughout the table hierarchy.\n *\n * 2. **Table Data Structure Building**: Transforms raw project data into structured table rows\n * that can be consumed by the table component. This includes processing folders, tasks,\n * and entities into a unified table format.\n *\n * 3. **Multi-Modal Data Presentation**: Supports three different data presentation modes:\n * - **Hierarchy Mode**: Builds nested folder/task relationships with expandable rows\n * - **Tasks List Mode**: Flattened view of tasks without hierarchical structure\n * - **Groups Mode**: Groups entities by specified criteria (entity type, custom groups)\n *\n * The context also provides utility functions for entity relationships, expansion state\n * management, filtering, sorting, and folder inheritance operations.\n */\nimport { ReactNode, useCallback, useMemo } from 'react'\nimport { ExpandedState, OnChangeFn, SortingState } from '@tanstack/react-table'\nimport useBuildProjectDataTable from '../hooks/useBuildProjectDataTable'\nimport { Filter } from '@ynput/ayon-react-components'\nimport {\n EntitiesMap,\n EntityMap,\n FolderNodeMap,\n TableRow,\n TaskNodeMap,\n TasksByFolderMap,\n} from '../types/table'\nimport useFolderRelationships from '../hooks/useFolderRelationships'\nimport { ProjectModel } from '../types/project'\nimport { ProjectTableAttribute, LoadingTasks } from '../types'\nimport { QueryFilter } from '../types/folders'\nimport { ContextMenuItemConstructors } from '../hooks/useCellContextMenu'\nimport { EntityGroup } from '@shared/api'\nimport useBuildGroupByTableData, {\n GroupByEntityType,\n ROW_ID_SEPARATOR,\n} from '../hooks/useBuildGroupByTableData'\nimport { PowerpackContextType } from '@shared/context'\nimport { useColumnSettingsContext } from './ColumnSettingsContext'\nimport { ProjectTableModulesType } from '../hooks'\nimport { ProjectTableContext, ProjectTableContextType } from './ProjectTableContext'\n\nexport const parseRowId = (rowId: string) => rowId?.split(ROW_ID_SEPARATOR)[0] || rowId\n\nexport type TableUser = {\n name: string\n fullName?: string\n}\n\nexport interface ProjectTableProviderProps {\n children: ReactNode\n isInitialized: boolean\n\n // loading\n isLoading: boolean\n isLoadingMore: boolean\n loadingTasks?: LoadingTasks\n error?: string\n // Project Info\n projectInfo?: ProjectModel\n projectName: string\n users: TableUser[]\n // Attributes\n attribFields: ProjectTableAttribute[]\n scopes: string[]\n\n // data\n tasksMap: TaskNodeMap\n foldersMap: FolderNodeMap\n entitiesMap: EntitiesMap\n tasksByFolderMap: TasksByFolderMap\n tableRows?: TableRow[] // any extra rows that we want to add to the table\n\n // grouping\n taskGroups: EntityGroup[]\n\n // data functions\n fetchNextPage: (value?: string) => void\n reloadTableData: () => void\n\n // Filters\n filters: Filter[]\n setFilters: (filters: Filter[]) => void\n queryFilters: {\n filter: QueryFilter | undefined\n filterString?: string\n search: string | undefined\n }\n\n // Hierarchy\n showHierarchy: boolean\n updateShowHierarchy: (showHierarchy: boolean) => void\n\n // Expanded state\n expanded: ExpandedState\n toggleExpanded: (id: string) => void\n updateExpanded: OnChangeFn<ExpandedState>\n setExpanded: React.Dispatch<React.SetStateAction<ExpandedState>>\n\n // Sorting\n sorting: SortingState\n updateSorting: OnChangeFn<SortingState>\n\n // context menu\n contextMenuItems: ContextMenuItemConstructors\n\n // powerpack context\n powerpack?: PowerpackContextType\n\n // remote modules\n modules: ProjectTableModulesType\n\n groupByConfig?: {\n entityType?: GroupByEntityType\n }\n\n // player\n playerOpen?: boolean\n onOpenPlayer?: (\n targetIds: {\n taskId?: string\n folderId?: string\n productId?: string\n versionId?: string\n },\n config?: { quickView?: boolean },\n ) => void\n}\n\nexport const ProjectTableProvider = ({\n children,\n foldersMap,\n tableRows,\n tasksMap,\n entitiesMap,\n tasksByFolderMap,\n expanded,\n projectInfo,\n showHierarchy,\n loadingTasks,\n isLoadingMore,\n isLoading,\n error,\n isInitialized,\n projectName,\n users,\n attribFields,\n scopes,\n taskGroups,\n filters,\n setFilters,\n queryFilters,\n updateShowHierarchy,\n toggleExpanded,\n updateExpanded,\n sorting,\n updateSorting,\n fetchNextPage,\n reloadTableData,\n setExpanded,\n contextMenuItems,\n powerpack,\n modules,\n groupByConfig,\n // player\n playerOpen,\n onOpenPlayer,\n}: ProjectTableProviderProps) => {\n // DATA TO TABLE\n const defaultTableData = useBuildProjectDataTable({\n foldersMap,\n tasksMap,\n rows: tableRows,\n tasksByFolderMap,\n expanded,\n projectInfo,\n showHierarchy,\n loadingTasks,\n isLoadingMore,\n })\n const { groupBy, groupByConfig: { showEmpty: showEmptyGroups = false } = {} } =\n useColumnSettingsContext()\n\n const buildGroupByTableData = useBuildGroupByTableData({\n entities: entitiesMap,\n entityType: groupByConfig?.entityType,\n groups: taskGroups,\n project: projectInfo,\n attribFields,\n showEmpty: showEmptyGroups,\n })\n\n // if we are grouping by something, we ignore current tableData and format the data based on the groupBy\n const groupedTableData = useMemo(\n () => !!groupBy && buildGroupByTableData(groupBy),\n [groupBy, entitiesMap, taskGroups],\n )\n\n const tableData = groupBy && groupedTableData ? groupedTableData : defaultTableData\n\n const getEntityById = useCallback(\n (id: string, field: string = 'entityId'): EntityMap | undefined => {\n // defensive check to ensure id is a string\n if (typeof id !== 'string') {\n console.warn('getEntityById called with non-string id:', id)\n return undefined\n }\n // always parse the id to remove any suffixes\n // this can happen if the id is a group by id (we need to make the row id unique)\n const parsedId = parseRowId(id)\n if (foldersMap.has(parsedId)) {\n return foldersMap.get(parsedId)\n } else if (tasksMap.has(parsedId)) {\n return tasksMap.get(parsedId)\n } else if (entitiesMap.has(parsedId)) {\n return entitiesMap.get(parsedId)\n }\n\n // if we have not found the entity at all, double check through the maps using field (entityId)\n for (const [_, entity] of entitiesMap) {\n if (entity[field as keyof EntityMap] === parsedId) {\n return entity\n }\n }\n\n // Return undefined if not found\n return undefined\n },\n [foldersMap, tasksMap, entitiesMap],\n )\n\n // get folder relationship functions\n const {\n getInheritedDependents,\n getChildrenEntities,\n findInheritedValueFromAncestors,\n findNonInheritedValues,\n getAncestorsOf,\n } = useFolderRelationships({\n entitiesMap,\n tasksMap,\n tasksByFolderMap,\n getEntityById,\n projectAttrib: projectInfo?.attrib,\n attribFields: attribFields,\n })\n\n const toggleExpandAll: ProjectTableContextType['toggleExpandAll'] = useCallback(\n (rowIds, expandAll) => {\n const expandedState = typeof expanded === 'object' ? expanded : {}\n\n const newExpandedState = { ...expandedState }\n\n rowIds.forEach((rowId) => {\n // get all children of the rowId using tableData\n const childIds = getChildrenEntities(rowId).map((child) => child.id)\n // check if the rowId is expanded\n const isExpanded = expandedState[rowId] || false\n\n if (expandAll !== undefined ? !expandAll : isExpanded) {\n // collapse all children\n newExpandedState[rowId] = false\n childIds.forEach((id) => {\n newExpandedState[id] = false\n })\n } else {\n // expand all children\n newExpandedState[rowId] = true\n childIds.forEach((id) => {\n newExpandedState[id] = true\n })\n }\n })\n\n setExpanded(newExpandedState)\n },\n [expanded, getChildrenEntities, setExpanded],\n )\n\n const toggleExpands: ProjectTableContextType['toggleExpands'] = useCallback(\n (rowIds, expand) => {\n const expandedState = typeof expanded === 'object' ? expanded : {}\n const newExpandedState = { ...expandedState }\n\n rowIds.forEach((rowId) => {\n if (expand !== undefined) {\n // Use the provided expand parameter\n newExpandedState[rowId] = expand\n } else {\n // Toggle based on current state\n newExpandedState[rowId] = !expandedState[rowId]\n }\n })\n\n setExpanded(newExpandedState)\n },\n [expanded, setExpanded],\n )\n\n return (\n <ProjectTableContext.Provider\n value={{\n // from this context\n tableData,\n // forwarded on\n isInitialized,\n isLoading,\n error,\n projectInfo,\n attribFields,\n scopes,\n users,\n projectName,\n tasksMap,\n foldersMap,\n entitiesMap,\n fetchNextPage,\n reloadTableData,\n taskGroups,\n // filters\n filters,\n setFilters,\n queryFilters,\n // hierarchy\n showHierarchy,\n updateShowHierarchy,\n // expanded state\n expanded,\n setExpanded,\n toggleExpanded,\n updateExpanded,\n toggleExpandAll,\n toggleExpands,\n // sorting\n sorting,\n updateSorting,\n getEntityById,\n // folder relationships\n getInheritedDependents,\n findInheritedValueFromAncestors,\n findNonInheritedValues,\n getAncestorsOf,\n // context menu\n contextMenuItems,\n // powerpack context\n powerpack,\n modules,\n // player\n playerOpen,\n onOpenPlayer,\n }}\n >\n {children}\n </ProjectTableContext.Provider>\n )\n}\n"],"names":["ROW_ID_SEPARATOR","useColumnSettingsContext","useBuildGroupByTableData","useMemo","useCallback","jsx","ProjectTableContext"],"mappings":"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"}