@ynput/ayon-frontend-shared 0.1.0

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 (248) hide show
  1. package/dist/EmptyPlaceholderFlex.styled-C3tjIk5V.mjs +121 -0
  2. package/dist/EmptyPlaceholderFlex.styled-C3tjIk5V.mjs.map +1 -0
  3. package/dist/EmptyPlaceholderFlex.styled-D_9k5mMH.js +78 -0
  4. package/dist/EmptyPlaceholderFlex.styled-D_9k5mMH.js.map +1 -0
  5. package/dist/ThumbnailSimple-DbSmXCNa.js +34 -0
  6. package/dist/ThumbnailSimple-DbSmXCNa.js.map +1 -0
  7. package/dist/ThumbnailSimple-DotCInch.mjs +78 -0
  8. package/dist/ThumbnailSimple-DotCInch.mjs.map +1 -0
  9. package/dist/ayon-frontend-shared.css +1 -0
  10. package/dist/confirmDelete-BSaFL2RH.mjs +6279 -0
  11. package/dist/confirmDelete-BSaFL2RH.mjs.map +1 -0
  12. package/dist/confirmDelete-BoRH88hw.js +43 -0
  13. package/dist/confirmDelete-BoRH88hw.js.map +1 -0
  14. package/dist/csstransition.esm-CzUZfsIt.mjs +3101 -0
  15. package/dist/csstransition.esm-CzUZfsIt.mjs.map +1 -0
  16. package/dist/csstransition.esm-Riwtyc4r.js +32 -0
  17. package/dist/csstransition.esm-Riwtyc4r.js.map +1 -0
  18. package/dist/format-DUCu0Y-3.mjs +1289 -0
  19. package/dist/format-DUCu0Y-3.mjs.map +1 -0
  20. package/dist/format-v4Hpvya-.js +2 -0
  21. package/dist/format-v4Hpvya-.js.map +1 -0
  22. package/dist/getEntityTypeIcon-BvwosBHR.js +2 -0
  23. package/dist/getEntityTypeIcon-BvwosBHR.js.map +1 -0
  24. package/dist/getEntityTypeIcon-BxTCKGSi.mjs +50 -0
  25. package/dist/getEntityTypeIcon-BxTCKGSi.mjs.map +1 -0
  26. package/dist/index.cjs.js +2 -0
  27. package/dist/index.cjs.js.map +1 -0
  28. package/dist/index.cjs2.js +2 -0
  29. package/dist/index.cjs2.js.map +1 -0
  30. package/dist/index.cjs3.js +2 -0
  31. package/dist/index.cjs3.js.map +1 -0
  32. package/dist/index.cjs4.js +2 -0
  33. package/dist/index.cjs4.js.map +1 -0
  34. package/dist/index.cjs5.js +2 -0
  35. package/dist/index.cjs5.js.map +1 -0
  36. package/dist/index.cjs6.js +2 -0
  37. package/dist/index.cjs6.js.map +1 -0
  38. package/dist/index.cjs7.js +29 -0
  39. package/dist/index.cjs7.js.map +1 -0
  40. package/dist/index.cjs8.js +549 -0
  41. package/dist/index.cjs8.js.map +1 -0
  42. package/dist/index.cjs9.js +1753 -0
  43. package/dist/index.cjs9.js.map +1 -0
  44. package/dist/index.es.js +8 -0
  45. package/dist/index.es.js.map +1 -0
  46. package/dist/index.es2.js +11 -0
  47. package/dist/index.es2.js.map +1 -0
  48. package/dist/index.es3.js +12 -0
  49. package/dist/index.es3.js.map +1 -0
  50. package/dist/index.es4.js +5 -0
  51. package/dist/index.es4.js.map +1 -0
  52. package/dist/index.es5.js +5 -0
  53. package/dist/index.es5.js.map +1 -0
  54. package/dist/index.es6.js +37 -0
  55. package/dist/index.es6.js.map +1 -0
  56. package/dist/index.es7.js +361 -0
  57. package/dist/index.es7.js.map +1 -0
  58. package/dist/index.es8.js +4340 -0
  59. package/dist/index.es8.js.map +1 -0
  60. package/dist/index.es9.js +56950 -0
  61. package/dist/index.es9.js.map +1 -0
  62. package/dist/jsx-runtime-Drh4NO5G.mjs +634 -0
  63. package/dist/jsx-runtime-Drh4NO5G.mjs.map +1 -0
  64. package/dist/jsx-runtime-qcKc-DpB.js +31 -0
  65. package/dist/jsx-runtime-qcKc-DpB.js.map +1 -0
  66. package/dist/platform-C5rgawOb.js +2 -0
  67. package/dist/platform-C5rgawOb.js.map +1 -0
  68. package/dist/platform-DNAvZtra.mjs +36 -0
  69. package/dist/platform-DNAvZtra.mjs.map +1 -0
  70. package/dist/types/ContextMenu.d.ts +1 -0
  71. package/dist/types/Feed.d.ts +1 -0
  72. package/dist/types/ProjectTreeTable.d.ts +1 -0
  73. package/dist/types/Slicer.d.ts +1 -0
  74. package/dist/types/api/activities/index.d.ts +1 -0
  75. package/dist/types/api/activities/transformations.d.ts +0 -0
  76. package/dist/types/api/activities/types.d.ts +10 -0
  77. package/dist/types/api/graphql.d.ts +2096 -0
  78. package/dist/types/api/index.d.ts +2 -0
  79. package/dist/types/api.d.ts +1 -0
  80. package/dist/types/components/EmptyPlaceholder/EmptyPlaceholder.d.ts +11 -0
  81. package/dist/types/components/EmptyPlaceholder/EmptyPlaceholderFlex.styled.d.ts +2 -0
  82. package/dist/types/components/EmptyPlaceholder/index.d.ts +4 -0
  83. package/dist/types/components/ThumbnailSimple/ThumbnailSimple.d.ts +15 -0
  84. package/dist/types/components/ThumbnailSimple/index.d.ts +3 -0
  85. package/dist/types/components/UserImage/UserImage.d.ts +11 -0
  86. package/dist/types/components/UserImage/index.d.ts +3 -0
  87. package/dist/types/components/index.d.ts +3 -0
  88. package/dist/types/components.d.ts +1 -0
  89. package/dist/types/containers/ContextMenu/ContextMenuContext.d.ts +21 -0
  90. package/dist/types/containers/ContextMenu/ContextMenuItem.d.ts +27 -0
  91. package/dist/types/containers/ContextMenu/GlobalContextMenu.d.ts +1 -0
  92. package/dist/types/containers/ContextMenu/index.d.ts +4 -0
  93. package/dist/types/containers/ContextMenu/useCreateContextMenu.d.ts +17 -0
  94. package/dist/types/containers/Feed/Feed.d.ts +10 -0
  95. package/dist/types/containers/Feed/Feed.styled.d.ts +5 -0
  96. package/dist/types/containers/Feed/components/ActivityAssigneeChange/ActivityAssigneeChange.d.ts +15 -0
  97. package/dist/types/containers/Feed/components/ActivityAssigneeChange/ActivityAssigneeChange.styled.d.ts +3 -0
  98. package/dist/types/containers/Feed/components/ActivityAssigneeChange/index.d.ts +3 -0
  99. package/dist/types/containers/Feed/components/ActivityCheckbox/ActivityCheckbox.d.ts +6 -0
  100. package/dist/types/containers/Feed/components/ActivityCheckbox/ActivityCheckbox.styled.d.ts +1 -0
  101. package/dist/types/containers/Feed/components/ActivityCheckbox/index.d.ts +3 -0
  102. package/dist/types/containers/Feed/components/ActivityComment/ActivityComment.d.ts +24 -0
  103. package/dist/types/containers/Feed/components/ActivityComment/ActivityComment.styled.d.ts +14 -0
  104. package/dist/types/containers/Feed/components/ActivityComment/ActivityMarkdownComponents.d.ts +43 -0
  105. package/dist/types/containers/Feed/components/ActivityComment/CommentWrapper.d.ts +5 -0
  106. package/dist/types/containers/Feed/components/ActivityComment/mappers.d.ts +9 -0
  107. package/dist/types/containers/Feed/components/ActivityDate.d.ts +7 -0
  108. package/dist/types/containers/Feed/components/ActivityGroup/ActivityGroup.d.ts +9 -0
  109. package/dist/types/containers/Feed/components/ActivityGroup/ActivityGroup.styled.d.ts +2 -0
  110. package/dist/types/containers/Feed/components/ActivityHeader/ActivityHeader.d.ts +40 -0
  111. package/dist/types/containers/Feed/components/ActivityHeader/ActivityHeader.styled.d.ts +4 -0
  112. package/dist/types/containers/Feed/components/ActivityItem.d.ts +27 -0
  113. package/dist/types/containers/Feed/components/ActivityReference/ActivityReference.d.ts +14 -0
  114. package/dist/types/containers/Feed/components/ActivityReference/ActivityReference.styled.d.ts +3 -0
  115. package/dist/types/containers/Feed/components/ActivityReferenceTooltip/ActivityReferenceTooltip.d.ts +4 -0
  116. package/dist/types/containers/Feed/components/ActivityReferenceTooltip/index.d.ts +2 -0
  117. package/dist/types/containers/Feed/components/ActivityStatus/ActivityStatus.d.ts +9 -0
  118. package/dist/types/containers/Feed/components/ActivityStatusChange/ActivityStatusChange.d.ts +18 -0
  119. package/dist/types/containers/Feed/components/ActivityStatusChange/ActivityStatusChange.styled.d.ts +3 -0
  120. package/dist/types/containers/Feed/components/ActivityStatusChange/hooks/getContextParents.d.ts +2 -0
  121. package/dist/types/containers/Feed/components/ActivityVersions/ActivityVersions.d.ts +24 -0
  122. package/dist/types/containers/Feed/components/ActivityVersions/ActivityVersions.styled.d.ts +6 -0
  123. package/dist/types/containers/Feed/components/CommentInput/CommentInput.d.ts +26 -0
  124. package/dist/types/containers/Feed/components/CommentInput/CommentInput.styled.d.ts +7 -0
  125. package/dist/types/containers/Feed/components/CommentInput/InputMarkdownConvert.d.ts +11 -0
  126. package/dist/types/containers/Feed/components/CommentInput/helpers.d.ts +4 -0
  127. package/dist/types/containers/Feed/components/CommentInput/hooks/useAnnotationsSync.d.ts +14 -0
  128. package/dist/types/containers/Feed/components/CommentInput/hooks/useAnnotationsUpload.d.ts +6 -0
  129. package/dist/types/containers/Feed/components/CommentInput/hooks/useInitialValue.d.ts +11 -0
  130. package/dist/types/containers/Feed/components/CommentInput/hooks/useMentionLink.d.ts +7 -0
  131. package/dist/types/containers/Feed/components/CommentInput/hooks/useSetCursorEnd.d.ts +7 -0
  132. package/dist/types/containers/Feed/components/CommentInput/index.d.ts +0 -0
  133. package/dist/types/containers/Feed/components/CommentInput/modules/ImageUploader.d.ts +8 -0
  134. package/dist/types/containers/Feed/components/CommentInput/modules/index.d.ts +12 -0
  135. package/dist/types/containers/Feed/components/CommentInput/quillToMarkdown.d.ts +5 -0
  136. package/dist/types/containers/Feed/components/CommentMentionSelect/CommentMentionSelect.d.ts +28 -0
  137. package/dist/types/containers/Feed/components/CommentMentionSelect/CommentMentionSelect.styled.d.ts +6 -0
  138. package/dist/types/containers/Feed/components/FileUploadCard/FileUploadCard.d.ts +14 -0
  139. package/dist/types/containers/Feed/components/FileUploadCard/FileUploadCard.styled.d.ts +4 -0
  140. package/dist/types/containers/Feed/components/FileUploadCard/index.d.ts +3 -0
  141. package/dist/types/containers/Feed/components/FileUploadPreview/FileUploadPreview.d.ts +22 -0
  142. package/dist/types/containers/Feed/components/FileUploadPreview/FileUploadPreview.styled.d.ts +4 -0
  143. package/dist/types/containers/Feed/components/FileUploadPreview/Mimes/ImageMime.d.ts +9 -0
  144. package/dist/types/containers/Feed/components/FileUploadPreview/Mimes/TextMime.d.ts +10 -0
  145. package/dist/types/containers/Feed/components/FileUploadPreview/hooks/useAttachmentNavigation.d.ts +19 -0
  146. package/dist/types/containers/Feed/components/FileUploadPreview/index.d.ts +3 -0
  147. package/dist/types/containers/Feed/components/FilesGrid/FilesGrid.d.ts +17 -0
  148. package/dist/types/containers/Feed/components/FilesGrid/FilesGrid.styled.d.ts +1 -0
  149. package/dist/types/containers/Feed/components/FilesGrid/index.d.ts +3 -0
  150. package/dist/types/containers/Feed/components/ReactionContainer/ExistingReactions.d.ts +7 -0
  151. package/dist/types/containers/Feed/components/ReactionContainer/Reaction.d.ts +10 -0
  152. package/dist/types/containers/Feed/components/ReactionContainer/ReactionPanelOpener.d.ts +7 -0
  153. package/dist/types/containers/Feed/components/ReactionContainer/Reactions.d.ts +8 -0
  154. package/dist/types/containers/Feed/components/ReactionContainer/Reactions.styled.d.ts +7 -0
  155. package/dist/types/containers/Feed/components/ReactionContainer/helpers.d.ts +11 -0
  156. package/dist/types/containers/Feed/components/ReactionContainer/types.d.ts +8 -0
  157. package/dist/types/containers/Feed/components/Tooltips/EntityTooltip/EntityTooltip.d.ts +12 -0
  158. package/dist/types/containers/Feed/components/Tooltips/EntityTooltip/EntityTooltip.styled.d.ts +3 -0
  159. package/dist/types/containers/Feed/components/Tooltips/UserTooltip/UserTooltip.d.ts +10 -0
  160. package/dist/types/containers/Feed/components/Tooltips/UserTooltip/UserTooltip.styled.d.ts +2 -0
  161. package/dist/types/containers/Feed/context/FeedContext.d.ts +58 -0
  162. package/dist/types/containers/Feed/feedHelpers.d.ts +1 -0
  163. package/dist/types/containers/Feed/helpers/groupActivityVersions.d.ts +2 -0
  164. package/dist/types/containers/Feed/helpers/groupMinorActivities.d.ts +2 -0
  165. package/dist/types/containers/Feed/helpers/mergeSimilarActivities.d.ts +2 -0
  166. package/dist/types/containers/Feed/hooks/useCommentMutations.d.ts +30 -0
  167. package/dist/types/containers/Feed/hooks/useReferenceTooltip.d.ts +3 -0
  168. package/dist/types/containers/Feed/hooks/useSaveScrollPos.d.ts +13 -0
  169. package/dist/types/containers/Feed/hooks/useScrollOnInputOpen.d.ts +8 -0
  170. package/dist/types/containers/Feed/hooks/useScrollToHighlighted.d.ts +10 -0
  171. package/dist/types/containers/Feed/hooks/useTableKeyboardNavigation.d.ts +22 -0
  172. package/dist/types/containers/Feed/hooks/useTransformActivities.d.ts +4 -0
  173. package/dist/types/containers/Feed/index.d.ts +7 -0
  174. package/dist/types/containers/Feed/mentionHelpers/getMentionOptions.d.ts +2 -0
  175. package/dist/types/containers/Feed/mentionHelpers/getMentionTasks.d.ts +10 -0
  176. package/dist/types/containers/Feed/mentionHelpers/getMentionUsers.d.ts +8 -0
  177. package/dist/types/containers/Feed/mentionHelpers/getMentionVersions.d.ts +12 -0
  178. package/dist/types/containers/ProjectTreeTable/ProjectTreeTable.d.ts +15 -0
  179. package/dist/types/containers/ProjectTreeTable/ProjectTreeTable.styled.d.ts +14 -0
  180. package/dist/types/containers/ProjectTreeTable/ProjectTreeTableColumns.d.ts +16 -0
  181. package/dist/types/containers/ProjectTreeTable/components/HeaderActionButton.d.ts +6 -0
  182. package/dist/types/containers/ProjectTreeTable/components/RowSelectionHeader.d.ts +3 -0
  183. package/dist/types/containers/ProjectTreeTable/components/SelectionCell.d.ts +5 -0
  184. package/dist/types/containers/ProjectTreeTable/context/CellEditingContext.d.ts +18 -0
  185. package/dist/types/containers/ProjectTreeTable/context/ClipboardContext.d.ts +4 -0
  186. package/dist/types/containers/ProjectTreeTable/context/ColumnSettingsContext.d.ts +30 -0
  187. package/dist/types/containers/ProjectTreeTable/context/ProjectTableContext.d.ts +76 -0
  188. package/dist/types/containers/ProjectTreeTable/context/ProjectTableQueriesContext.d.ts +21 -0
  189. package/dist/types/containers/ProjectTreeTable/context/SelectedRowsContext.d.ts +15 -0
  190. package/dist/types/containers/ProjectTreeTable/context/SelectionContext.d.ts +35 -0
  191. package/dist/types/containers/ProjectTreeTable/context/clipboard/clipboardTypes.d.ts +27 -0
  192. package/dist/types/containers/ProjectTreeTable/context/clipboard/clipboardUtils.d.ts +6 -0
  193. package/dist/types/containers/ProjectTreeTable/context/clipboard/clipboardValidation.d.ts +12 -0
  194. package/dist/types/containers/ProjectTreeTable/context/clipboard/index.d.ts +3 -0
  195. package/dist/types/containers/ProjectTreeTable/context/index.d.ts +8 -0
  196. package/dist/types/containers/ProjectTreeTable/hooks/useCellContextMenu.d.ts +10 -0
  197. package/dist/types/containers/ProjectTreeTable/hooks/useColumnVirtualization.d.ts +17 -0
  198. package/dist/types/containers/ProjectTreeTable/hooks/useCustomColumnWidthVars.d.ts +6 -0
  199. package/dist/types/containers/ProjectTreeTable/hooks/useDeleteEntities.d.ts +5 -0
  200. package/dist/types/containers/ProjectTreeTable/hooks/useFolderRelationships.d.ts +29 -0
  201. package/dist/types/containers/ProjectTreeTable/hooks/useHistory.d.ts +17 -0
  202. package/dist/types/containers/ProjectTreeTable/hooks/useKeyboardNavigation.d.ts +10 -0
  203. package/dist/types/containers/ProjectTreeTable/hooks/useOverviewTable.d.ts +32 -0
  204. package/dist/types/containers/ProjectTreeTable/hooks/usePrefetchFolderTasks.d.ts +4 -0
  205. package/dist/types/containers/ProjectTreeTable/hooks/useUpdateOverview.d.ts +30 -0
  206. package/dist/types/containers/ProjectTreeTable/hooks/useValidateUpdates.d.ts +3 -0
  207. package/dist/types/containers/ProjectTreeTable/index.d.ts +14 -0
  208. package/dist/types/containers/ProjectTreeTable/types/folders.d.ts +14 -0
  209. package/dist/types/containers/ProjectTreeTable/types/index.d.ts +62 -0
  210. package/dist/types/containers/ProjectTreeTable/types/operations.d.ts +99 -0
  211. package/dist/types/containers/ProjectTreeTable/types/project.d.ts +223 -0
  212. package/dist/types/containers/ProjectTreeTable/types/table.d.ts +83 -0
  213. package/dist/types/containers/ProjectTreeTable/utils/cellUtils.d.ts +42 -0
  214. package/dist/types/containers/ProjectTreeTable/utils/clientFilterToQueryFilter.d.ts +4 -0
  215. package/dist/types/containers/ProjectTreeTable/utils/index.d.ts +3 -0
  216. package/dist/types/containers/ProjectTreeTable/utils/loadingUtils.d.ts +36 -0
  217. package/dist/types/containers/ProjectTreeTable/widgets/BooleanWidget.d.ts +7 -0
  218. package/dist/types/containers/ProjectTreeTable/widgets/CellWidget.d.ts +24 -0
  219. package/dist/types/containers/ProjectTreeTable/widgets/CollapsedWidget.d.ts +5 -0
  220. package/dist/types/containers/ProjectTreeTable/widgets/DateWidget.d.ts +8 -0
  221. package/dist/types/containers/ProjectTreeTable/widgets/DateWidgetInput.d.ts +8 -0
  222. package/dist/types/containers/ProjectTreeTable/widgets/EntityNameWidget.d.ts +14 -0
  223. package/dist/types/containers/ProjectTreeTable/widgets/EnumWidget.d.ts +28 -0
  224. package/dist/types/containers/ProjectTreeTable/widgets/TextWidget.d.ts +10 -0
  225. package/dist/types/containers/ProjectTreeTable/widgets/TextWidgetInput.d.ts +9 -0
  226. package/dist/types/containers/ProjectTreeTable/widgets/index.d.ts +7 -0
  227. package/dist/types/containers/Slicer/createFilterFromSlicer.d.ts +6 -0
  228. package/dist/types/containers/Slicer/index.d.ts +2 -0
  229. package/dist/types/containers/Slicer/types.d.ts +18 -0
  230. package/dist/types/hooks/index.d.ts +1 -0
  231. package/dist/types/hooks/useLocalStorage.d.ts +1 -0
  232. package/dist/types/hooks.d.ts +1 -0
  233. package/dist/types/index.d.ts +2 -0
  234. package/dist/types/util/confirmDelete.d.ts +13 -0
  235. package/dist/types/util/getEntityTypeIcon.d.ts +1 -0
  236. package/dist/types/util/index.d.ts +5 -0
  237. package/dist/types/util/platform.d.ts +8 -0
  238. package/dist/types/util/productTypes.d.ts +8 -0
  239. package/dist/types/util.d.ts +1 -0
  240. package/dist/useCreateContextMenu-CDRv1ybg.js +2 -0
  241. package/dist/useCreateContextMenu-CDRv1ybg.js.map +1 -0
  242. package/dist/useCreateContextMenu-DvOhPycB.mjs +118 -0
  243. package/dist/useCreateContextMenu-DvOhPycB.mjs.map +1 -0
  244. package/dist/useLocalStorage-BQSzWJ4Q.mjs +39 -0
  245. package/dist/useLocalStorage-BQSzWJ4Q.mjs.map +1 -0
  246. package/dist/useLocalStorage-BRHTBlxR.js +2 -0
  247. package/dist/useLocalStorage-BRHTBlxR.js.map +1 -0
  248. package/package.json +91 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs8.js","sources":["../node_modules/date-fns/parseISO.js","../node_modules/@tanstack/virtual-core/dist/esm/utils.js","../node_modules/@tanstack/virtual-core/dist/esm/index.js","../node_modules/@tanstack/react-virtual/dist/esm/index.js","../src/containers/ProjectTreeTable/widgets/CollapsedWidget.tsx","../src/containers/ProjectTreeTable/widgets/DateWidgetInput.tsx","../src/containers/ProjectTreeTable/widgets/DateWidget.tsx","../src/containers/ProjectTreeTable/widgets/EnumWidget.tsx","../src/containers/ProjectTreeTable/widgets/TextWidgetInput.tsx","../src/containers/ProjectTreeTable/widgets/TextWidget.tsx","../src/containers/ProjectTreeTable/widgets/BooleanWidget.tsx","../src/containers/ProjectTreeTable/context/ProjectTableQueriesContext.tsx","../src/containers/ProjectTreeTable/utils/loadingUtils.ts","../src/containers/ProjectTreeTable/hooks/useOverviewTable.ts","../src/containers/ProjectTreeTable/hooks/useFolderRelationships.ts","../src/containers/ProjectTreeTable/context/ProjectTableContext.tsx","../src/containers/ProjectTreeTable/hooks/useUpdateOverview.ts","../src/containers/ProjectTreeTable/context/clipboard/clipboardTypes.ts","../src/containers/ProjectTreeTable/context/clipboard/clipboardUtils.ts","../src/containers/ProjectTreeTable/context/clipboard/clipboardValidation.ts","../src/containers/ProjectTreeTable/utils/cellUtils.ts","../src/containers/ProjectTreeTable/context/SelectionContext.tsx","../src/containers/ProjectTreeTable/context/ClipboardContext.tsx","../src/containers/ProjectTreeTable/context/ColumnSettingsContext.tsx","../src/containers/ProjectTreeTable/context/SelectedRowsContext.tsx","../src/containers/ProjectTreeTable/hooks/useValidateUpdates.ts","../src/containers/ProjectTreeTable/hooks/useHistory.ts","../src/containers/ProjectTreeTable/context/CellEditingContext.tsx","../src/containers/ProjectTreeTable/widgets/CellWidget.tsx","../src/containers/ProjectTreeTable/widgets/EntityNameWidget.tsx","../src/containers/ProjectTreeTable/ProjectTreeTable.styled.ts","../src/containers/ProjectTreeTable/components/SelectionCell.tsx","../src/containers/ProjectTreeTable/components/RowSelectionHeader.tsx","../src/containers/ProjectTreeTable/ProjectTreeTableColumns.tsx","../src/containers/ProjectTreeTable/components/HeaderActionButton.tsx","../src/containers/ProjectTreeTable/hooks/useCustomColumnWidthVars.ts","../src/containers/ProjectTreeTable/hooks/usePrefetchFolderTasks.ts","../src/containers/ProjectTreeTable/hooks/useDeleteEntities.ts","../src/containers/ProjectTreeTable/hooks/useCellContextMenu.ts","../src/containers/ProjectTreeTable/hooks/useColumnVirtualization.tsx","../src/containers/ProjectTreeTable/hooks/useKeyboardNavigation.ts","../src/containers/ProjectTreeTable/ProjectTreeTable.tsx","../src/containers/ProjectTreeTable/utils/clientFilterToQueryFilter.ts"],"sourcesContent":["import {\n millisecondsInHour,\n millisecondsInMinute,\n} from \"./constants.js\";\nimport { constructFrom } from \"./constructFrom.js\";\nimport { toDate } from \"./toDate.js\";\n\n/**\n * The {@link parseISO} function options.\n */\n\n/**\n * @name parseISO\n * @category Common Helpers\n * @summary Parse ISO string\n *\n * @description\n * Parse the given string in ISO 8601 format and return an instance of Date.\n *\n * Function accepts complete ISO 8601 formats as well as partial implementations.\n * ISO 8601: http://en.wikipedia.org/wiki/ISO_8601\n *\n * If the argument isn't a string, the function cannot parse the string or\n * the values are invalid, it returns Invalid Date.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param argument - The value to convert\n * @param options - An object with options\n *\n * @returns The parsed date in the local time zone\n *\n * @example\n * // Convert string '2014-02-11T11:30:30' to date:\n * const result = parseISO('2014-02-11T11:30:30')\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert string '+02014101' to date,\n * // if the additional number of digits in the extended year format is 1:\n * const result = parseISO('+02014101', { additionalDigits: 1 })\n * //=> Fri Apr 11 2014 00:00:00\n */\nexport function parseISO(argument, options) {\n const invalidDate = () => constructFrom(options?.in, NaN);\n\n const additionalDigits = options?.additionalDigits ?? 2;\n const dateStrings = splitDateString(argument);\n\n let date;\n if (dateStrings.date) {\n const parseYearResult = parseYear(dateStrings.date, additionalDigits);\n date = parseDate(parseYearResult.restDateString, parseYearResult.year);\n }\n\n if (!date || isNaN(+date)) return invalidDate();\n\n const timestamp = +date;\n let time = 0;\n let offset;\n\n if (dateStrings.time) {\n time = parseTime(dateStrings.time);\n if (isNaN(time)) return invalidDate();\n }\n\n if (dateStrings.timezone) {\n offset = parseTimezone(dateStrings.timezone);\n if (isNaN(offset)) return invalidDate();\n } else {\n const tmpDate = new Date(timestamp + time);\n const result = toDate(0, options?.in);\n result.setFullYear(\n tmpDate.getUTCFullYear(),\n tmpDate.getUTCMonth(),\n tmpDate.getUTCDate(),\n );\n result.setHours(\n tmpDate.getUTCHours(),\n tmpDate.getUTCMinutes(),\n tmpDate.getUTCSeconds(),\n tmpDate.getUTCMilliseconds(),\n );\n return result;\n }\n\n return toDate(timestamp + time + offset, options?.in);\n}\n\nconst patterns = {\n dateTimeDelimiter: /[T ]/,\n timeZoneDelimiter: /[Z ]/i,\n timezone: /([Z+-].*)$/,\n};\n\nconst dateRegex =\n /^-?(?:(\\d{3})|(\\d{2})(?:-?(\\d{2}))?|W(\\d{2})(?:-?(\\d{1}))?|)$/;\nconst timeRegex =\n /^(\\d{2}(?:[.,]\\d*)?)(?::?(\\d{2}(?:[.,]\\d*)?))?(?::?(\\d{2}(?:[.,]\\d*)?))?$/;\nconst timezoneRegex = /^([+-])(\\d{2})(?::?(\\d{2}))?$/;\n\nfunction splitDateString(dateString) {\n const dateStrings = {};\n const array = dateString.split(patterns.dateTimeDelimiter);\n let timeString;\n\n // The regex match should only return at maximum two array elements.\n // [date], [time], or [date, time].\n if (array.length > 2) {\n return dateStrings;\n }\n\n if (/:/.test(array[0])) {\n timeString = array[0];\n } else {\n dateStrings.date = array[0];\n timeString = array[1];\n if (patterns.timeZoneDelimiter.test(dateStrings.date)) {\n dateStrings.date = dateString.split(patterns.timeZoneDelimiter)[0];\n timeString = dateString.substr(\n dateStrings.date.length,\n dateString.length,\n );\n }\n }\n\n if (timeString) {\n const token = patterns.timezone.exec(timeString);\n if (token) {\n dateStrings.time = timeString.replace(token[1], \"\");\n dateStrings.timezone = token[1];\n } else {\n dateStrings.time = timeString;\n }\n }\n\n return dateStrings;\n}\n\nfunction parseYear(dateString, additionalDigits) {\n const regex = new RegExp(\n \"^(?:(\\\\d{4}|[+-]\\\\d{\" +\n (4 + additionalDigits) +\n \"})|(\\\\d{2}|[+-]\\\\d{\" +\n (2 + additionalDigits) +\n \"})$)\",\n );\n\n const captures = dateString.match(regex);\n // Invalid ISO-formatted year\n if (!captures) return { year: NaN, restDateString: \"\" };\n\n const year = captures[1] ? parseInt(captures[1]) : null;\n const century = captures[2] ? parseInt(captures[2]) : null;\n\n // either year or century is null, not both\n return {\n year: century === null ? year : century * 100,\n restDateString: dateString.slice((captures[1] || captures[2]).length),\n };\n}\n\nfunction parseDate(dateString, year) {\n // Invalid ISO-formatted year\n if (year === null) return new Date(NaN);\n\n const captures = dateString.match(dateRegex);\n // Invalid ISO-formatted string\n if (!captures) return new Date(NaN);\n\n const isWeekDate = !!captures[4];\n const dayOfYear = parseDateUnit(captures[1]);\n const month = parseDateUnit(captures[2]) - 1;\n const day = parseDateUnit(captures[3]);\n const week = parseDateUnit(captures[4]);\n const dayOfWeek = parseDateUnit(captures[5]) - 1;\n\n if (isWeekDate) {\n if (!validateWeekDate(year, week, dayOfWeek)) {\n return new Date(NaN);\n }\n return dayOfISOWeekYear(year, week, dayOfWeek);\n } else {\n const date = new Date(0);\n if (\n !validateDate(year, month, day) ||\n !validateDayOfYearDate(year, dayOfYear)\n ) {\n return new Date(NaN);\n }\n date.setUTCFullYear(year, month, Math.max(dayOfYear, day));\n return date;\n }\n}\n\nfunction parseDateUnit(value) {\n return value ? parseInt(value) : 1;\n}\n\nfunction parseTime(timeString) {\n const captures = timeString.match(timeRegex);\n if (!captures) return NaN; // Invalid ISO-formatted time\n\n const hours = parseTimeUnit(captures[1]);\n const minutes = parseTimeUnit(captures[2]);\n const seconds = parseTimeUnit(captures[3]);\n\n if (!validateTime(hours, minutes, seconds)) {\n return NaN;\n }\n\n return (\n hours * millisecondsInHour + minutes * millisecondsInMinute + seconds * 1000\n );\n}\n\nfunction parseTimeUnit(value) {\n return (value && parseFloat(value.replace(\",\", \".\"))) || 0;\n}\n\nfunction parseTimezone(timezoneString) {\n if (timezoneString === \"Z\") return 0;\n\n const captures = timezoneString.match(timezoneRegex);\n if (!captures) return 0;\n\n const sign = captures[1] === \"+\" ? -1 : 1;\n const hours = parseInt(captures[2]);\n const minutes = (captures[3] && parseInt(captures[3])) || 0;\n\n if (!validateTimezone(hours, minutes)) {\n return NaN;\n }\n\n return sign * (hours * millisecondsInHour + minutes * millisecondsInMinute);\n}\n\nfunction dayOfISOWeekYear(isoWeekYear, week, day) {\n const date = new Date(0);\n date.setUTCFullYear(isoWeekYear, 0, 4);\n const fourthOfJanuaryDay = date.getUTCDay() || 7;\n const diff = (week - 1) * 7 + day + 1 - fourthOfJanuaryDay;\n date.setUTCDate(date.getUTCDate() + diff);\n return date;\n}\n\n// Validation functions\n\n// February is null to handle the leap year (using ||)\nconst daysInMonths = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\nfunction isLeapYearIndex(year) {\n return year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0);\n}\n\nfunction validateDate(year, month, date) {\n return (\n month >= 0 &&\n month <= 11 &&\n date >= 1 &&\n date <= (daysInMonths[month] || (isLeapYearIndex(year) ? 29 : 28))\n );\n}\n\nfunction validateDayOfYearDate(year, dayOfYear) {\n return dayOfYear >= 1 && dayOfYear <= (isLeapYearIndex(year) ? 366 : 365);\n}\n\nfunction validateWeekDate(_year, week, day) {\n return week >= 1 && week <= 53 && day >= 0 && day <= 6;\n}\n\nfunction validateTime(hours, minutes, seconds) {\n if (hours === 24) {\n return minutes === 0 && seconds === 0;\n }\n\n return (\n seconds >= 0 &&\n seconds < 60 &&\n minutes >= 0 &&\n minutes < 60 &&\n hours >= 0 &&\n hours < 25\n );\n}\n\nfunction validateTimezone(_hours, minutes) {\n return minutes >= 0 && minutes <= 59;\n}\n\n// Fallback for modularized imports:\nexport default parseISO;\n","function memo(getDeps, fn, opts) {\n let deps = opts.initialDeps ?? [];\n let result;\n function memoizedFunction() {\n var _a, _b, _c, _d;\n let depTime;\n if (opts.key && ((_a = opts.debug) == null ? void 0 : _a.call(opts))) depTime = Date.now();\n const newDeps = getDeps();\n const depsChanged = newDeps.length !== deps.length || newDeps.some((dep, index) => deps[index] !== dep);\n if (!depsChanged) {\n return result;\n }\n deps = newDeps;\n let resultTime;\n if (opts.key && ((_b = opts.debug) == null ? void 0 : _b.call(opts))) resultTime = Date.now();\n result = fn(...newDeps);\n if (opts.key && ((_c = opts.debug) == null ? void 0 : _c.call(opts))) {\n const depEndTime = Math.round((Date.now() - depTime) * 100) / 100;\n const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100;\n const resultFpsPercentage = resultEndTime / 16;\n const pad = (str, num) => {\n str = String(str);\n while (str.length < num) {\n str = \" \" + str;\n }\n return str;\n };\n console.info(\n `%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`,\n `\n font-size: .6rem;\n font-weight: bold;\n color: hsl(${Math.max(\n 0,\n Math.min(120 - 120 * resultFpsPercentage, 120)\n )}deg 100% 31%);`,\n opts == null ? void 0 : opts.key\n );\n }\n (_d = opts == null ? void 0 : opts.onChange) == null ? void 0 : _d.call(opts, result);\n return result;\n }\n memoizedFunction.updateDeps = (newDeps) => {\n deps = newDeps;\n };\n return memoizedFunction;\n}\nfunction notUndefined(value, msg) {\n if (value === void 0) {\n throw new Error(`Unexpected undefined${msg ? `: ${msg}` : \"\"}`);\n } else {\n return value;\n }\n}\nconst approxEqual = (a, b) => Math.abs(a - b) < 1;\nconst debounce = (targetWindow, fn, ms) => {\n let timeoutId;\n return function(...args) {\n targetWindow.clearTimeout(timeoutId);\n timeoutId = targetWindow.setTimeout(() => fn.apply(this, args), ms);\n };\n};\nexport {\n approxEqual,\n debounce,\n memo,\n notUndefined\n};\n//# sourceMappingURL=utils.js.map\n","import { debounce, memo, notUndefined, approxEqual } from \"./utils.js\";\nconst defaultKeyExtractor = (index) => index;\nconst defaultRangeExtractor = (range) => {\n const start = Math.max(range.startIndex - range.overscan, 0);\n const end = Math.min(range.endIndex + range.overscan, range.count - 1);\n const arr = [];\n for (let i = start; i <= end; i++) {\n arr.push(i);\n }\n return arr;\n};\nconst observeElementRect = (instance, cb) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const targetWindow = instance.targetWindow;\n if (!targetWindow) {\n return;\n }\n const handler = (rect) => {\n const { width, height } = rect;\n cb({ width: Math.round(width), height: Math.round(height) });\n };\n handler(element.getBoundingClientRect());\n if (!targetWindow.ResizeObserver) {\n return () => {\n };\n }\n const observer = new targetWindow.ResizeObserver((entries) => {\n const run = () => {\n const entry = entries[0];\n if (entry == null ? void 0 : entry.borderBoxSize) {\n const box = entry.borderBoxSize[0];\n if (box) {\n handler({ width: box.inlineSize, height: box.blockSize });\n return;\n }\n }\n handler(element.getBoundingClientRect());\n };\n instance.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();\n });\n observer.observe(element, { box: \"border-box\" });\n return () => {\n observer.unobserve(element);\n };\n};\nconst addEventListenerOptions = {\n passive: true\n};\nconst observeWindowRect = (instance, cb) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const handler = () => {\n cb({ width: element.innerWidth, height: element.innerHeight });\n };\n handler();\n element.addEventListener(\"resize\", handler, addEventListenerOptions);\n return () => {\n element.removeEventListener(\"resize\", handler);\n };\n};\nconst supportsScrollend = typeof window == \"undefined\" ? true : \"onscrollend\" in window;\nconst observeElementOffset = (instance, cb) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const targetWindow = instance.targetWindow;\n if (!targetWindow) {\n return;\n }\n let offset = 0;\n const fallback = instance.options.useScrollendEvent && supportsScrollend ? () => void 0 : debounce(\n targetWindow,\n () => {\n cb(offset, false);\n },\n instance.options.isScrollingResetDelay\n );\n const createHandler = (isScrolling) => () => {\n const { horizontal, isRtl } = instance.options;\n offset = horizontal ? element[\"scrollLeft\"] * (isRtl && -1 || 1) : element[\"scrollTop\"];\n fallback();\n cb(offset, isScrolling);\n };\n const handler = createHandler(true);\n const endHandler = createHandler(false);\n endHandler();\n element.addEventListener(\"scroll\", handler, addEventListenerOptions);\n const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;\n if (registerScrollendEvent) {\n element.addEventListener(\"scrollend\", endHandler, addEventListenerOptions);\n }\n return () => {\n element.removeEventListener(\"scroll\", handler);\n if (registerScrollendEvent) {\n element.removeEventListener(\"scrollend\", endHandler);\n }\n };\n};\nconst observeWindowOffset = (instance, cb) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const targetWindow = instance.targetWindow;\n if (!targetWindow) {\n return;\n }\n let offset = 0;\n const fallback = instance.options.useScrollendEvent && supportsScrollend ? () => void 0 : debounce(\n targetWindow,\n () => {\n cb(offset, false);\n },\n instance.options.isScrollingResetDelay\n );\n const createHandler = (isScrolling) => () => {\n offset = element[instance.options.horizontal ? \"scrollX\" : \"scrollY\"];\n fallback();\n cb(offset, isScrolling);\n };\n const handler = createHandler(true);\n const endHandler = createHandler(false);\n endHandler();\n element.addEventListener(\"scroll\", handler, addEventListenerOptions);\n const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;\n if (registerScrollendEvent) {\n element.addEventListener(\"scrollend\", endHandler, addEventListenerOptions);\n }\n return () => {\n element.removeEventListener(\"scroll\", handler);\n if (registerScrollendEvent) {\n element.removeEventListener(\"scrollend\", endHandler);\n }\n };\n};\nconst measureElement = (element, entry, instance) => {\n if (entry == null ? void 0 : entry.borderBoxSize) {\n const box = entry.borderBoxSize[0];\n if (box) {\n const size = Math.round(\n box[instance.options.horizontal ? \"inlineSize\" : \"blockSize\"]\n );\n return size;\n }\n }\n return Math.round(\n element.getBoundingClientRect()[instance.options.horizontal ? \"width\" : \"height\"]\n );\n};\nconst windowScroll = (offset, {\n adjustments = 0,\n behavior\n}, instance) => {\n var _a, _b;\n const toOffset = offset + adjustments;\n (_b = (_a = instance.scrollElement) == null ? void 0 : _a.scrollTo) == null ? void 0 : _b.call(_a, {\n [instance.options.horizontal ? \"left\" : \"top\"]: toOffset,\n behavior\n });\n};\nconst elementScroll = (offset, {\n adjustments = 0,\n behavior\n}, instance) => {\n var _a, _b;\n const toOffset = offset + adjustments;\n (_b = (_a = instance.scrollElement) == null ? void 0 : _a.scrollTo) == null ? void 0 : _b.call(_a, {\n [instance.options.horizontal ? \"left\" : \"top\"]: toOffset,\n behavior\n });\n};\nclass Virtualizer {\n constructor(opts) {\n this.unsubs = [];\n this.scrollElement = null;\n this.targetWindow = null;\n this.isScrolling = false;\n this.scrollToIndexTimeoutId = null;\n this.measurementsCache = [];\n this.itemSizeCache = /* @__PURE__ */ new Map();\n this.pendingMeasuredCacheIndexes = [];\n this.scrollRect = null;\n this.scrollOffset = null;\n this.scrollDirection = null;\n this.scrollAdjustments = 0;\n this.elementsCache = /* @__PURE__ */ new Map();\n this.observer = /* @__PURE__ */ (() => {\n let _ro = null;\n const get = () => {\n if (_ro) {\n return _ro;\n }\n if (!this.targetWindow || !this.targetWindow.ResizeObserver) {\n return null;\n }\n return _ro = new this.targetWindow.ResizeObserver((entries) => {\n entries.forEach((entry) => {\n const run = () => {\n this._measureElement(entry.target, entry);\n };\n this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();\n });\n });\n };\n return {\n disconnect: () => {\n var _a;\n (_a = get()) == null ? void 0 : _a.disconnect();\n _ro = null;\n },\n observe: (target) => {\n var _a;\n return (_a = get()) == null ? void 0 : _a.observe(target, { box: \"border-box\" });\n },\n unobserve: (target) => {\n var _a;\n return (_a = get()) == null ? void 0 : _a.unobserve(target);\n }\n };\n })();\n this.range = null;\n this.setOptions = (opts2) => {\n Object.entries(opts2).forEach(([key, value]) => {\n if (typeof value === \"undefined\") delete opts2[key];\n });\n this.options = {\n debug: false,\n initialOffset: 0,\n overscan: 1,\n paddingStart: 0,\n paddingEnd: 0,\n scrollPaddingStart: 0,\n scrollPaddingEnd: 0,\n horizontal: false,\n getItemKey: defaultKeyExtractor,\n rangeExtractor: defaultRangeExtractor,\n onChange: () => {\n },\n measureElement,\n initialRect: { width: 0, height: 0 },\n scrollMargin: 0,\n gap: 0,\n indexAttribute: \"data-index\",\n initialMeasurementsCache: [],\n lanes: 1,\n isScrollingResetDelay: 150,\n enabled: true,\n isRtl: false,\n useScrollendEvent: false,\n useAnimationFrameWithResizeObserver: false,\n ...opts2\n };\n };\n this.notify = (sync) => {\n var _a, _b;\n (_b = (_a = this.options).onChange) == null ? void 0 : _b.call(_a, this, sync);\n };\n this.maybeNotify = memo(\n () => {\n this.calculateRange();\n return [\n this.isScrolling,\n this.range ? this.range.startIndex : null,\n this.range ? this.range.endIndex : null\n ];\n },\n (isScrolling) => {\n this.notify(isScrolling);\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"maybeNotify\",\n debug: () => this.options.debug,\n initialDeps: [\n this.isScrolling,\n this.range ? this.range.startIndex : null,\n this.range ? this.range.endIndex : null\n ]\n }\n );\n this.cleanup = () => {\n this.unsubs.filter(Boolean).forEach((d) => d());\n this.unsubs = [];\n this.observer.disconnect();\n this.scrollElement = null;\n this.targetWindow = null;\n };\n this._didMount = () => {\n return () => {\n this.cleanup();\n };\n };\n this._willUpdate = () => {\n var _a;\n const scrollElement = this.options.enabled ? this.options.getScrollElement() : null;\n if (this.scrollElement !== scrollElement) {\n this.cleanup();\n if (!scrollElement) {\n this.maybeNotify();\n return;\n }\n this.scrollElement = scrollElement;\n if (this.scrollElement && \"ownerDocument\" in this.scrollElement) {\n this.targetWindow = this.scrollElement.ownerDocument.defaultView;\n } else {\n this.targetWindow = ((_a = this.scrollElement) == null ? void 0 : _a.window) ?? null;\n }\n this.elementsCache.forEach((cached) => {\n this.observer.observe(cached);\n });\n this._scrollToOffset(this.getScrollOffset(), {\n adjustments: void 0,\n behavior: void 0\n });\n this.unsubs.push(\n this.options.observeElementRect(this, (rect) => {\n this.scrollRect = rect;\n this.maybeNotify();\n })\n );\n this.unsubs.push(\n this.options.observeElementOffset(this, (offset, isScrolling) => {\n this.scrollAdjustments = 0;\n this.scrollDirection = isScrolling ? this.getScrollOffset() < offset ? \"forward\" : \"backward\" : null;\n this.scrollOffset = offset;\n this.isScrolling = isScrolling;\n this.maybeNotify();\n })\n );\n }\n };\n this.getSize = () => {\n if (!this.options.enabled) {\n this.scrollRect = null;\n return 0;\n }\n this.scrollRect = this.scrollRect ?? this.options.initialRect;\n return this.scrollRect[this.options.horizontal ? \"width\" : \"height\"];\n };\n this.getScrollOffset = () => {\n if (!this.options.enabled) {\n this.scrollOffset = null;\n return 0;\n }\n this.scrollOffset = this.scrollOffset ?? (typeof this.options.initialOffset === \"function\" ? this.options.initialOffset() : this.options.initialOffset);\n return this.scrollOffset;\n };\n this.getFurthestMeasurement = (measurements, index) => {\n const furthestMeasurementsFound = /* @__PURE__ */ new Map();\n const furthestMeasurements = /* @__PURE__ */ new Map();\n for (let m = index - 1; m >= 0; m--) {\n const measurement = measurements[m];\n if (furthestMeasurementsFound.has(measurement.lane)) {\n continue;\n }\n const previousFurthestMeasurement = furthestMeasurements.get(\n measurement.lane\n );\n if (previousFurthestMeasurement == null || measurement.end > previousFurthestMeasurement.end) {\n furthestMeasurements.set(measurement.lane, measurement);\n } else if (measurement.end < previousFurthestMeasurement.end) {\n furthestMeasurementsFound.set(measurement.lane, true);\n }\n if (furthestMeasurementsFound.size === this.options.lanes) {\n break;\n }\n }\n return furthestMeasurements.size === this.options.lanes ? Array.from(furthestMeasurements.values()).sort((a, b) => {\n if (a.end === b.end) {\n return a.index - b.index;\n }\n return a.end - b.end;\n })[0] : void 0;\n };\n this.getMeasurementOptions = memo(\n () => [\n this.options.count,\n this.options.paddingStart,\n this.options.scrollMargin,\n this.options.getItemKey,\n this.options.enabled\n ],\n (count, paddingStart, scrollMargin, getItemKey, enabled) => {\n this.pendingMeasuredCacheIndexes = [];\n return {\n count,\n paddingStart,\n scrollMargin,\n getItemKey,\n enabled\n };\n },\n {\n key: false\n }\n );\n this.getMeasurements = memo(\n () => [this.getMeasurementOptions(), this.itemSizeCache],\n ({ count, paddingStart, scrollMargin, getItemKey, enabled }, itemSizeCache) => {\n if (!enabled) {\n this.measurementsCache = [];\n this.itemSizeCache.clear();\n return [];\n }\n if (this.measurementsCache.length === 0) {\n this.measurementsCache = this.options.initialMeasurementsCache;\n this.measurementsCache.forEach((item) => {\n this.itemSizeCache.set(item.key, item.size);\n });\n }\n const min = this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0;\n this.pendingMeasuredCacheIndexes = [];\n const measurements = this.measurementsCache.slice(0, min);\n for (let i = min; i < count; i++) {\n const key = getItemKey(i);\n const furthestMeasurement = this.options.lanes === 1 ? measurements[i - 1] : this.getFurthestMeasurement(measurements, i);\n const start = furthestMeasurement ? furthestMeasurement.end + this.options.gap : paddingStart + scrollMargin;\n const measuredSize = itemSizeCache.get(key);\n const size = typeof measuredSize === \"number\" ? measuredSize : this.options.estimateSize(i);\n const end = start + size;\n const lane = furthestMeasurement ? furthestMeasurement.lane : i % this.options.lanes;\n measurements[i] = {\n index: i,\n start,\n size,\n end,\n key,\n lane\n };\n }\n this.measurementsCache = measurements;\n return measurements;\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"getMeasurements\",\n debug: () => this.options.debug\n }\n );\n this.calculateRange = memo(\n () => [\n this.getMeasurements(),\n this.getSize(),\n this.getScrollOffset(),\n this.options.lanes\n ],\n (measurements, outerSize, scrollOffset, lanes) => {\n return this.range = measurements.length > 0 && outerSize > 0 ? calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n lanes\n }) : null;\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"calculateRange\",\n debug: () => this.options.debug\n }\n );\n this.getVirtualIndexes = memo(\n () => {\n let startIndex = null;\n let endIndex = null;\n const range = this.calculateRange();\n if (range) {\n startIndex = range.startIndex;\n endIndex = range.endIndex;\n }\n this.maybeNotify.updateDeps([this.isScrolling, startIndex, endIndex]);\n return [\n this.options.rangeExtractor,\n this.options.overscan,\n this.options.count,\n startIndex,\n endIndex\n ];\n },\n (rangeExtractor, overscan, count, startIndex, endIndex) => {\n return startIndex === null || endIndex === null ? [] : rangeExtractor({\n startIndex,\n endIndex,\n overscan,\n count\n });\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"getVirtualIndexes\",\n debug: () => this.options.debug\n }\n );\n this.indexFromElement = (node) => {\n const attributeName = this.options.indexAttribute;\n const indexStr = node.getAttribute(attributeName);\n if (!indexStr) {\n console.warn(\n `Missing attribute name '${attributeName}={index}' on measured element.`\n );\n return -1;\n }\n return parseInt(indexStr, 10);\n };\n this._measureElement = (node, entry) => {\n const index = this.indexFromElement(node);\n const item = this.measurementsCache[index];\n if (!item) {\n return;\n }\n const key = item.key;\n const prevNode = this.elementsCache.get(key);\n if (prevNode !== node) {\n if (prevNode) {\n this.observer.unobserve(prevNode);\n }\n this.observer.observe(node);\n this.elementsCache.set(key, node);\n }\n if (node.isConnected) {\n this.resizeItem(index, this.options.measureElement(node, entry, this));\n }\n };\n this.resizeItem = (index, size) => {\n const item = this.measurementsCache[index];\n if (!item) {\n return;\n }\n const itemSize = this.itemSizeCache.get(item.key) ?? item.size;\n const delta = size - itemSize;\n if (delta !== 0) {\n if (this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(item, delta, this) : item.start < this.getScrollOffset() + this.scrollAdjustments) {\n if (process.env.NODE_ENV !== \"production\" && this.options.debug) {\n console.info(\"correction\", delta);\n }\n this._scrollToOffset(this.getScrollOffset(), {\n adjustments: this.scrollAdjustments += delta,\n behavior: void 0\n });\n }\n this.pendingMeasuredCacheIndexes.push(item.index);\n this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size));\n this.notify(false);\n }\n };\n this.measureElement = (node) => {\n if (!node) {\n this.elementsCache.forEach((cached, key) => {\n if (!cached.isConnected) {\n this.observer.unobserve(cached);\n this.elementsCache.delete(key);\n }\n });\n return;\n }\n this._measureElement(node, void 0);\n };\n this.getVirtualItems = memo(\n () => [this.getVirtualIndexes(), this.getMeasurements()],\n (indexes, measurements) => {\n const virtualItems = [];\n for (let k = 0, len = indexes.length; k < len; k++) {\n const i = indexes[k];\n const measurement = measurements[i];\n virtualItems.push(measurement);\n }\n return virtualItems;\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"getVirtualItems\",\n debug: () => this.options.debug\n }\n );\n this.getVirtualItemForOffset = (offset) => {\n const measurements = this.getMeasurements();\n if (measurements.length === 0) {\n return void 0;\n }\n return notUndefined(\n measurements[findNearestBinarySearch(\n 0,\n measurements.length - 1,\n (index) => notUndefined(measurements[index]).start,\n offset\n )]\n );\n };\n this.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {\n const size = this.getSize();\n const scrollOffset = this.getScrollOffset();\n if (align === \"auto\") {\n align = toOffset >= scrollOffset + size ? \"end\" : \"start\";\n }\n if (align === \"center\") {\n toOffset += (itemSize - size) / 2;\n } else if (align === \"end\") {\n toOffset -= size;\n }\n const scrollSizeProp = this.options.horizontal ? \"scrollWidth\" : \"scrollHeight\";\n const scrollSize = this.scrollElement ? \"document\" in this.scrollElement ? this.scrollElement.document.documentElement[scrollSizeProp] : this.scrollElement[scrollSizeProp] : 0;\n const maxOffset = scrollSize - size;\n return Math.max(Math.min(maxOffset, toOffset), 0);\n };\n this.getOffsetForIndex = (index, align = \"auto\") => {\n index = Math.max(0, Math.min(index, this.options.count - 1));\n const item = this.measurementsCache[index];\n if (!item) {\n return void 0;\n }\n const size = this.getSize();\n const scrollOffset = this.getScrollOffset();\n if (align === \"auto\") {\n if (item.end >= scrollOffset + size - this.options.scrollPaddingEnd) {\n align = \"end\";\n } else if (item.start <= scrollOffset + this.options.scrollPaddingStart) {\n align = \"start\";\n } else {\n return [scrollOffset, align];\n }\n }\n const toOffset = align === \"end\" ? item.end + this.options.scrollPaddingEnd : item.start - this.options.scrollPaddingStart;\n return [\n this.getOffsetForAlignment(toOffset, align, item.size),\n align\n ];\n };\n this.isDynamicMode = () => this.elementsCache.size > 0;\n this.cancelScrollToIndex = () => {\n if (this.scrollToIndexTimeoutId !== null && this.targetWindow) {\n this.targetWindow.clearTimeout(this.scrollToIndexTimeoutId);\n this.scrollToIndexTimeoutId = null;\n }\n };\n this.scrollToOffset = (toOffset, { align = \"start\", behavior } = {}) => {\n this.cancelScrollToIndex();\n if (behavior === \"smooth\" && this.isDynamicMode()) {\n console.warn(\n \"The `smooth` scroll behavior is not fully supported with dynamic size.\"\n );\n }\n this._scrollToOffset(this.getOffsetForAlignment(toOffset, align), {\n adjustments: void 0,\n behavior\n });\n };\n this.scrollToIndex = (index, { align: initialAlign = \"auto\", behavior } = {}) => {\n index = Math.max(0, Math.min(index, this.options.count - 1));\n this.cancelScrollToIndex();\n if (behavior === \"smooth\" && this.isDynamicMode()) {\n console.warn(\n \"The `smooth` scroll behavior is not fully supported with dynamic size.\"\n );\n }\n const offsetAndAlign = this.getOffsetForIndex(index, initialAlign);\n if (!offsetAndAlign) return;\n const [offset, align] = offsetAndAlign;\n this._scrollToOffset(offset, { adjustments: void 0, behavior });\n if (behavior !== \"smooth\" && this.isDynamicMode() && this.targetWindow) {\n this.scrollToIndexTimeoutId = this.targetWindow.setTimeout(() => {\n this.scrollToIndexTimeoutId = null;\n const elementInDOM = this.elementsCache.has(\n this.options.getItemKey(index)\n );\n if (elementInDOM) {\n const [latestOffset] = notUndefined(\n this.getOffsetForIndex(index, align)\n );\n if (!approxEqual(latestOffset, this.getScrollOffset())) {\n this.scrollToIndex(index, { align, behavior });\n }\n } else {\n this.scrollToIndex(index, { align, behavior });\n }\n });\n }\n };\n this.scrollBy = (delta, { behavior } = {}) => {\n this.cancelScrollToIndex();\n if (behavior === \"smooth\" && this.isDynamicMode()) {\n console.warn(\n \"The `smooth` scroll behavior is not fully supported with dynamic size.\"\n );\n }\n this._scrollToOffset(this.getScrollOffset() + delta, {\n adjustments: void 0,\n behavior\n });\n };\n this.getTotalSize = () => {\n var _a;\n const measurements = this.getMeasurements();\n let end;\n if (measurements.length === 0) {\n end = this.options.paddingStart;\n } else if (this.options.lanes === 1) {\n end = ((_a = measurements[measurements.length - 1]) == null ? void 0 : _a.end) ?? 0;\n } else {\n const endByLane = Array(this.options.lanes).fill(null);\n let endIndex = measurements.length - 1;\n while (endIndex >= 0 && endByLane.some((val) => val === null)) {\n const item = measurements[endIndex];\n if (endByLane[item.lane] === null) {\n endByLane[item.lane] = item.end;\n }\n endIndex--;\n }\n end = Math.max(...endByLane.filter((val) => val !== null));\n }\n return Math.max(\n end - this.options.scrollMargin + this.options.paddingEnd,\n 0\n );\n };\n this._scrollToOffset = (offset, {\n adjustments,\n behavior\n }) => {\n this.options.scrollToFn(offset, { behavior, adjustments }, this);\n };\n this.measure = () => {\n this.itemSizeCache = /* @__PURE__ */ new Map();\n this.notify(false);\n };\n this.setOptions(opts);\n }\n}\nconst findNearestBinarySearch = (low, high, getCurrentValue, value) => {\n while (low <= high) {\n const middle = (low + high) / 2 | 0;\n const currentValue = getCurrentValue(middle);\n if (currentValue < value) {\n low = middle + 1;\n } else if (currentValue > value) {\n high = middle - 1;\n } else {\n return middle;\n }\n }\n if (low > 0) {\n return low - 1;\n } else {\n return 0;\n }\n};\nfunction calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n lanes\n}) {\n const lastIndex = measurements.length - 1;\n const getOffset = (index) => measurements[index].start;\n if (measurements.length <= lanes) {\n return {\n startIndex: 0,\n endIndex: lastIndex\n };\n }\n let startIndex = findNearestBinarySearch(\n 0,\n lastIndex,\n getOffset,\n scrollOffset\n );\n let endIndex = startIndex;\n if (lanes === 1) {\n while (endIndex < lastIndex && measurements[endIndex].end < scrollOffset + outerSize) {\n endIndex++;\n }\n } else if (lanes > 1) {\n const endPerLane = Array(lanes).fill(0);\n while (endIndex < lastIndex && endPerLane.some((pos) => pos < scrollOffset + outerSize)) {\n const item = measurements[endIndex];\n endPerLane[item.lane] = item.end;\n endIndex++;\n }\n const startPerLane = Array(lanes).fill(scrollOffset + outerSize);\n while (startIndex >= 0 && startPerLane.some((pos) => pos >= scrollOffset)) {\n const item = measurements[startIndex];\n startPerLane[item.lane] = item.start;\n startIndex--;\n }\n startIndex = Math.max(0, startIndex - startIndex % lanes);\n endIndex = Math.min(lastIndex, endIndex + (lanes - 1 - endIndex % lanes));\n }\n return { startIndex, endIndex };\n}\nexport {\n Virtualizer,\n approxEqual,\n debounce,\n defaultKeyExtractor,\n defaultRangeExtractor,\n elementScroll,\n measureElement,\n memo,\n notUndefined,\n observeElementOffset,\n observeElementRect,\n observeWindowOffset,\n observeWindowRect,\n windowScroll\n};\n//# sourceMappingURL=index.js.map\n","import * as React from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { Virtualizer, elementScroll, observeElementOffset, observeElementRect, windowScroll, observeWindowOffset, observeWindowRect } from \"@tanstack/virtual-core\";\nexport * from \"@tanstack/virtual-core\";\nconst useIsomorphicLayoutEffect = typeof document !== \"undefined\" ? React.useLayoutEffect : React.useEffect;\nfunction useVirtualizerBase(options) {\n const rerender = React.useReducer(() => ({}), {})[1];\n const resolvedOptions = {\n ...options,\n onChange: (instance2, sync) => {\n var _a;\n if (sync) {\n flushSync(rerender);\n } else {\n rerender();\n }\n (_a = options.onChange) == null ? void 0 : _a.call(options, instance2, sync);\n }\n };\n const [instance] = React.useState(\n () => new Virtualizer(resolvedOptions)\n );\n instance.setOptions(resolvedOptions);\n useIsomorphicLayoutEffect(() => {\n return instance._didMount();\n }, []);\n useIsomorphicLayoutEffect(() => {\n return instance._willUpdate();\n });\n return instance;\n}\nfunction useVirtualizer(options) {\n return useVirtualizerBase({\n observeElementRect,\n observeElementOffset,\n scrollToFn: elementScroll,\n ...options\n });\n}\nfunction useWindowVirtualizer(options) {\n return useVirtualizerBase({\n getScrollElement: () => typeof document !== \"undefined\" ? window : null,\n observeElementRect: observeWindowRect,\n observeElementOffset: observeWindowOffset,\n scrollToFn: windowScroll,\n initialOffset: () => typeof document !== \"undefined\" ? window.scrollY : 0,\n ...options\n });\n}\nexport {\n useVirtualizer,\n useWindowVirtualizer\n};\n//# sourceMappingURL=index.js.map\n","import { forwardRef } from 'react'\nimport styled from 'styled-components'\n\nconst StyledDot = styled.div`\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background-color: #ffffff;\n\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n`\n\ninterface CollapsedWidgetProps extends React.HTMLAttributes<HTMLDivElement> {\n color?: string\n}\n\nexport const CollapsedWidget = forwardRef<HTMLDivElement, CollapsedWidgetProps>(\n ({ color, ...props }, ref) => {\n return <StyledDot style={{ backgroundColor: color }} {...props} ref={ref}></StyledDot>\n },\n)\n","import { forwardRef, useState, useEffect, useRef } from 'react'\nimport styled from 'styled-components'\nimport { format, isValid, parseISO } from 'date-fns'\nimport { WidgetBaseProps } from './CellWidget'\n\ninterface DateWidgetInputProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'>,\n WidgetBaseProps {\n value: string\n onCancel?: () => void\n autoFocus?: boolean\n}\n\nconst StyledInput = styled.input`\n z-index: 10;\n border: none;\n outline: none;\n padding: 0;\n padding-left: 1px;\n margin: 0;\n cursor: text;\n font-size: inherit;\n font-family: inherit;\n font-weight: inherit;\n background-color: transparent;\n width: 100%;\n box-sizing: border-box;\n`\n\nexport const DateWidgetInput = forwardRef<HTMLInputElement, DateWidgetInputProps>(\n ({ value: initialValue, onChange, onCancel, autoFocus = true, ...props }, _) => {\n const [value, setValue] = useState(() => {\n if (initialValue) {\n const parsedDate = parseISO(initialValue)\n if (isValid(parsedDate)) {\n return format(parsedDate, 'yyyy-MM-dd')\n }\n }\n return ''\n })\n\n useEffect(() => {\n if (initialValue) {\n const parsedDate = parseISO(initialValue)\n if (isValid(parsedDate)) {\n setValue(format(parsedDate, 'yyyy-MM-dd'))\n } else {\n setValue('')\n }\n }\n }, [initialValue])\n\n const inputRef = useRef<HTMLInputElement>(null)\n\n useEffect(() => {\n if (autoFocus && inputRef.current) {\n inputRef.current.focus()\n // Delay showPicker call until after focus to ensure it's tied to user interaction\n setTimeout(() => {\n try {\n inputRef.current?.showPicker()\n } catch (error) {\n console.debug('Date picker could not be shown automatically:', error)\n }\n }, 100)\n }\n }, [autoFocus])\n\n // Ensure the picker opens when clicked directly\n const handleClick = (e: React.MouseEvent<HTMLInputElement>) => {\n e.preventDefault() // Prevent default to ensure our handler takes precedence\n try {\n inputRef.current?.showPicker()\n } catch (error) {\n console.debug('Date picker could not be shown on click:', error)\n }\n }\n\n const handleDateSubmit = (event?: 'Click' | 'Enter') => {\n if (value) {\n const parsed = Date.parse(value)\n if (isValid(parsed)) {\n const dateWithZeroTime = new Date(parsed)\n dateWithZeroTime.setUTCHours(0, 0, 0, 0)\n onChange(dateWithZeroTime.toISOString(), event)\n return true\n }\n }\n return false\n }\n\n const handleBlur = () => {\n if (!handleDateSubmit('Click')) {\n onCancel?.()\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n handleDateSubmit('Enter')\n inputRef.current?.blur()\n } else if (e.key === 'Escape') {\n e.preventDefault()\n onCancel?.()\n }\n }\n\n return (\n <StyledInput\n {...props}\n ref={inputRef}\n type=\"date\"\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n onClick={handleClick}\n />\n )\n },\n)\n","import { format } from 'date-fns'\nimport { forwardRef } from 'react'\nimport { DateWidgetInput } from './DateWidgetInput'\nimport { WidgetBaseProps } from './CellWidget'\n\ninterface DateWidgetProps\n extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'onChange'>,\n WidgetBaseProps {\n value: string\n isReadOnly?: boolean\n isInherited?: boolean\n}\n\nexport const DateWidget = forwardRef<HTMLSpanElement, DateWidgetProps>(\n ({ value, isEditing, isReadOnly, isInherited, onChange, onCancelEdit, ...props }, ref) => {\n let dateString = ''\n try {\n dateString = format(new Date(value), 'dd-MM-yyyy')\n } catch (error) {\n console.error('Invalid date value:', value)\n dateString = 'Invalid Date'\n }\n\n if (isEditing) {\n return (\n <DateWidgetInput\n value={value}\n onChange={onChange}\n onCancel={onCancelEdit}\n readOnly={isReadOnly}\n disabled={isReadOnly}\n {...(props as any)}\n />\n )\n }\n\n return (\n <span {...props} ref={ref}>\n {dateString}\n </span>\n )\n },\n)\n","import { Dropdown, DropdownProps, DropdownRef, Icon } from '@ynput/ayon-react-components'\nimport clsx from 'clsx'\nimport { forwardRef, useEffect, useRef, useState } from 'react'\nimport styled from 'styled-components'\nimport { WidgetBaseProps } from './CellWidget'\nimport { AttributeData, AttributeEnumItem } from '../types'\n\nconst StyledWidget = styled.div`\n display: flex;\n gap: var(--base-gap-small);\n align-items: center;\n width: 100%;\n height: 100%;\n overflow: hidden;\n border-radius: var(--border-radius-m);\n padding: 0 2px;\n cursor: pointer;\n\n &:hover {\n background-color: var(--md-sys-color-surface-container-high-hover);\n }\n\n &.item {\n padding: 4px 2px;\n border-radius: 0;\n\n &:hover {\n background-color: var(--md-sys-color-surface-container-hover);\n }\n }\n\n &.selected {\n background-color: var(--md-sys-color-primary-container);\n\n &:hover {\n background-color: var(--md-sys-color-primary-container-hover);\n }\n }\n`\n\nconst StyledValuesContainer = styled.div`\n display: flex;\n gap: var(--base-gap-small);\n align-items: center;\n overflow: hidden;\n border-radius: var(--border-radius-m);\n`\n\nconst StyledValueWrapper = styled.div`\n display: flex;\n gap: var(--base-gap-small);\n align-items: center;\n\n overflow: hidden;\n max-width: 100%;\n min-width: 20px;\n`\n\nconst StyledValue = styled.span`\n /* push expand icon to the end */\n flex: 1;\n overflow: hidden;\n white-space: nowrap;\n width: 100%;\n text-overflow: ellipsis;\n text-align: left;\n border-radius: var(--border-radius-m);\n padding: 0px 2px;\n text-align: center;\n\n &.placeholder {\n color: var(--md-sys-color-outline);\n }\n`\n\nconst StyledImg = styled.img`\n width: 20px;\n height: 20px;\n object-fit: cover;\n\n &.avatar {\n border-radius: 50%;\n }\n`\n\nconst StyledExpandIcon = styled(Icon)`\n margin-left: auto;\n transition: rotate 0.2s;\n`\n\nconst StyledDropdown = styled(Dropdown)`\n height: 100%;\n width: 100%;\n`\n\ninterface EnumWidgetProps extends Omit<DropdownProps, 'onChange' | 'value'>, WidgetBaseProps {\n value: (string | number | boolean)[]\n options: AttributeEnumItem[]\n type?: AttributeData['type']\n autoOpen?: boolean\n isReadOnly?: boolean\n enableCustomValues?: boolean\n pt?: {\n template?: Partial<EnumTemplateProps>\n }\n onOpen?: () => void\n onNext?: () => void\n}\n\nconst checkForImgSrc = (icon: string | undefined = ''): boolean => {\n return (\n icon.startsWith('/') ||\n icon.startsWith('./') ||\n icon.startsWith('../') ||\n icon.startsWith('http://') ||\n icon.startsWith('https://')\n )\n}\n\nconst checkAvatarImg = (src: string): boolean => src.includes('avatar')\n\nexport const EnumWidget = forwardRef<HTMLDivElement, EnumWidgetProps>(\n (\n {\n value,\n isEditing,\n options,\n type,\n autoOpen = true,\n isReadOnly,\n enableCustomValues,\n onOpen,\n onChange,\n onCancelEdit,\n onNext,\n pt,\n ...dropdownProps\n },\n _ref,\n ) => {\n // convert value to string array\n const valueAsStrings = value.map((v) => v?.toString()).filter((v) => !!v)\n let selectedOptions = options.filter((option) =>\n valueAsStrings.includes(option.value.toString()),\n )\n\n // Check if all values are present in options, if not, add a warning\n valueAsStrings.forEach((val) => {\n if (!options.find((option) => option.value === val)) {\n selectedOptions = [\n ...selectedOptions,\n {\n label: val,\n value: val,\n color: enableCustomValues\n ? 'var(--md-sys-color-surface-container)'\n : 'var(--md-sys-color-error)',\n icon: enableCustomValues ? undefined : 'warning',\n },\n ]\n }\n })\n const hasMultipleValues = selectedOptions.length > 1\n\n const dropdownRef = useRef<DropdownRef>(null)\n\n const handleClosedClick = (e: React.MouseEvent<HTMLSpanElement>) => {\n // if we click on the chevron icon, then we open the dropdown spright away (put it into editing mode)\n if (e.target instanceof HTMLElement && e.target.closest('.expand') && onOpen && !isReadOnly) {\n onOpen()\n // stop the event from propagating to the parent element because a single click on the cell would close the dropdown\n e.stopPropagation()\n }\n }\n\n const [dropdownOpen, setDropdownOpen] = useState(false)\n useEffect(() => {\n if (isEditing && dropdownRef.current && autoOpen) {\n !dropdownRef.current.isOpen && dropdownRef.current?.open()\n setDropdownOpen(true)\n } else {\n setDropdownOpen(false)\n }\n }, [isEditing, dropdownRef.current, autoOpen])\n\n // when the dropdown is open, focus the first item\n useEffect(() => {\n if (dropdownOpen) {\n const optionsUlEl = dropdownRef.current?.getOptions() as HTMLUListElement\n const firstItem = optionsUlEl?.querySelector('li')\n if (firstItem) {\n firstItem.focus()\n // set style of li to have no outline (no focus ring)\n firstItem.style.outline = 'none'\n }\n }\n }, [dropdownOpen])\n\n const isMultiSelect = !!type?.includes('list')\n\n const handleChange = (value: string[]) => {\n const filteredValue = enableCustomValues\n ? value\n : value.filter((v) => options.find((o) => o.value === v))\n\n if (type?.includes('list')) {\n onChange(filteredValue, 'Click')\n } else {\n // take first value as the type is not list]\n onChange(filteredValue[0], 'Click')\n }\n }\n\n if (isEditing) {\n return (\n <StyledDropdown\n options={options}\n value={valueAsStrings}\n ref={dropdownRef}\n valueTemplate={(_value, selected, isOpen) => (\n <EnumCellValue\n selectedOptions={selectedOptions}\n hasMultipleValues={selected.length > 1}\n isOpen={isOpen}\n isReadOnly={isReadOnly}\n isMultiSelect={isMultiSelect}\n {...pt?.template}\n placeholder={dropdownProps.placeholder}\n className={clsx('enum-dropdown-value', pt?.template?.className)}\n />\n )}\n itemTemplate={(option, _isActive, isSelected) => (\n <EnumCellValue\n selectedOptions={[option]}\n hasMultipleValues={false}\n isOpen={false}\n isItem\n isSelected={isSelected}\n {...pt?.template}\n className={clsx('enum-dropdown-item', pt?.template?.className)}\n />\n )}\n widthExpand\n multiSelect={isMultiSelect}\n disableOpen={isReadOnly}\n disabled={isReadOnly}\n sortBySelected\n {...dropdownProps}\n onChange={handleChange}\n onClose={onCancelEdit}\n />\n )\n }\n\n return (\n <EnumCellValue\n selectedOptions={selectedOptions}\n hasMultipleValues={hasMultipleValues}\n onClick={handleClosedClick}\n isMultiSelect={isMultiSelect}\n isReadOnly={isReadOnly}\n {...pt?.template}\n placeholder={dropdownProps.placeholder}\n className={clsx('enum-value', pt?.template?.className, dropdownProps.className)}\n />\n )\n },\n)\n\ninterface EnumTemplateProps extends React.HTMLAttributes<HTMLSpanElement> {\n selectedOptions: AttributeEnumItem[]\n placeholder?: string\n hasMultipleValues: boolean\n isMultiSelect?: boolean\n isOpen?: boolean\n isItem?: boolean\n isSelected?: boolean\n isReadOnly?: boolean\n}\n\nconst EnumCellValue = ({\n selectedOptions,\n placeholder,\n hasMultipleValues,\n isMultiSelect,\n isOpen,\n isItem,\n isSelected,\n isReadOnly,\n className,\n ...props\n}: EnumTemplateProps) => {\n // Check if all options have icons\n const allOptionsHaveIcon = selectedOptions.every((option) => option.icon)\n\n // Determine if we should show labels based on the requirements\n const showLabels = !hasMultipleValues || !allOptionsHaveIcon\n // Show the colors be backgrounds instead of the text\n const backgroundColor = !allOptionsHaveIcon && isMultiSelect && !isItem\n\n const isPlaceholder = !selectedOptions.length && placeholder\n if (isPlaceholder) {\n selectedOptions = [\n {\n label: placeholder,\n value: '',\n },\n ]\n }\n\n return (\n <StyledWidget className={clsx(className, { selected: isSelected, item: isItem })} {...props}>\n <StyledValuesContainer>\n {selectedOptions.map((option, i) => (\n <StyledValueWrapper key={option.value.toString() + i}>\n {option.icon && checkForImgSrc(option.icon) ? (\n <StyledImg\n src={option.icon}\n className={clsx({ avatar: checkAvatarImg(option.icon) })}\n />\n ) : option.icon ? (\n <Icon icon={option.icon} style={{ color: option.color }} />\n ) : null}\n\n {(showLabels || !option.icon) && (\n <StyledValue\n style={{\n color: backgroundColor ? 'inherit' : option.color,\n backgroundColor: backgroundColor\n ? option.color || 'var(--md-sys-color-surface-container)'\n : 'transparent',\n }}\n className={clsx({ placeholder: isPlaceholder })}\n >\n {option.label}\n </StyledValue>\n )}\n </StyledValueWrapper>\n ))}\n </StyledValuesContainer>\n {!isItem && !isReadOnly && (\n <StyledExpandIcon\n className=\"expand\"\n icon=\"expand_more\"\n style={{ rotate: isOpen ? '180deg' : '0' }}\n />\n )}\n </StyledWidget>\n )\n}\n","import { forwardRef, KeyboardEvent, useState, useEffect, useRef } from 'react'\nimport styled from 'styled-components'\nimport { WidgetBaseProps } from './CellWidget'\n\ninterface TextWidgetInputProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'> {\n value: string\n onCancel?: () => void\n onChange: WidgetBaseProps['onChange']\n autoFocus?: boolean\n}\n\nconst StyledInput = styled.input`\n z-index: 10;\n border: none;\n outline: none;\n padding: 0;\n padding-left: 1px;\n margin: 0;\n cursor: text;\n font-size: inherit;\n font-family: inherit;\n font-weight: inherit;\n background-color: transparent;\n width: 100%;\n box-sizing: border-box;\n`\n\nexport const TextWidgetInput = forwardRef<HTMLInputElement, TextWidgetInputProps>(\n ({ value: initialValue, onChange, onCancel, autoFocus = true, ...props }, _) => {\n // Local state to manage input value\n const [value, setValue] = useState(initialValue)\n const inputRef = useRef<HTMLInputElement>(null)\n const escapePressed = useRef(false)\n\n // Set focus on the input when component mounts\n useEffect(() => {\n if (autoFocus && inputRef && inputRef.current) {\n inputRef.current.focus()\n // position cursor at the end of text\n inputRef.current.select()\n }\n }, [autoFocus])\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n onChange(value, 'Enter')\n } else if (e.key === 'Escape') {\n e.preventDefault()\n e.stopPropagation()\n escapePressed.current = true\n onCancel?.()\n }\n }\n\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n if (e.relatedTarget?.tagName === 'INPUT') {\n return\n }\n\n if (!escapePressed.current) {\n onChange(value, 'Click')\n }\n\n // Reset the flag\n escapePressed.current = false\n }\n\n return (\n <StyledInput\n {...props}\n ref={inputRef}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n />\n )\n },\n)\n","import { forwardRef } from 'react'\nimport { TextWidgetInput } from './TextWidgetInput'\nimport { WidgetBaseProps } from './CellWidget'\nimport styled from 'styled-components'\nimport { AttributeData } from '../types'\n\nconst StyledBaseTextWidget = styled.span`\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n`\n\ntype AttributeType = AttributeData['type']\nexport type TextWidgetType = Extract<AttributeType, 'string' | 'integer' | 'float'>\n\ninterface TextWidgetProps\n extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'onChange'>,\n WidgetBaseProps {\n value: string\n isInherited?: boolean\n}\n\nexport const TextWidget = forwardRef<HTMLSpanElement, TextWidgetProps>(\n ({ value, isEditing, isInherited, onChange, onCancelEdit, ...props }, ref) => {\n if (isEditing) {\n return (\n <TextWidgetInput value={value} onChange={onChange} onCancel={onCancelEdit} type={'text'} />\n )\n }\n\n return (\n <StyledBaseTextWidget {...props} ref={ref}>\n {value}\n </StyledBaseTextWidget>\n )\n },\n)\n","import { forwardRef } from 'react'\nimport styled from 'styled-components'\nimport { WidgetBaseProps } from './CellWidget'\n\nconst StyledCheckbox = styled.input`\n margin: auto;\n z-index: 1;\n cursor: pointer;\n\n width: 16px;\n height: 16px;\n background-color: transparent;\n border: 1px solid var(--md-sys-color-outline);\n appearance: none;\n border-radius: 2px;\n\n &:hover {\n border-color: hsl(212.31deg 16.83% 74.65%);\n }\n\n &:checked {\n background-color: var(--md-sys-color-primary);\n border-color: var(--md-sys-color-primary);\n appearance: auto;\n }\n`\n\ninterface BooleanWidgetProps\n extends Omit<React.HTMLAttributes<HTMLInputElement>, 'onChange'>,\n WidgetBaseProps {\n value: boolean\n isReadOnly?: boolean\n}\n\nexport const BooleanWidget = forwardRef<HTMLInputElement, BooleanWidgetProps>(\n ({ value, onChange, isReadOnly, isEditing, onCancelEdit, ...props }, ref) => {\n return (\n <StyledCheckbox\n {...props}\n checked={value}\n onChange={(e) => onChange((e.target as HTMLInputElement).checked)}\n ref={ref}\n type=\"checkbox\"\n disabled={isReadOnly}\n readOnly={isReadOnly}\n />\n )\n },\n)\n","import { createContext, ReactNode, useContext } from 'react'\nimport { OperationModel, OperationsRequestModel } from '../types/operations'\nimport { PatchOperation } from '../types'\n\nexport interface ProjectTableQueriesContextProps {\n updateEntities: ProjectTableQueriesProviderProps['updateEntities']\n getFoldersTasks: ProjectTableQueriesProviderProps['getFoldersTasks']\n}\n\nconst ProjectTableQueriesContext = createContext<ProjectTableQueriesContextProps | undefined>(\n undefined,\n)\n\nexport interface ProjectTableQueriesProviderProps {\n children: ReactNode\n\n updateEntities: ({\n operations,\n }: {\n operations: OperationModel[]\n patchOperations?: PatchOperation[]\n }) => Promise<OperationsRequestModel | undefined>\n\n getFoldersTasks: (\n args: {\n parentIds: string[]\n filter?: string\n search?: string\n },\n force?: boolean,\n ) => Promise<any>\n}\n\nexport const ProjectTableQueriesProvider = ({\n children,\n updateEntities,\n getFoldersTasks,\n}: ProjectTableQueriesProviderProps) => {\n return (\n <ProjectTableQueriesContext.Provider\n value={{\n updateEntities,\n getFoldersTasks,\n }}\n >\n {children}\n </ProjectTableQueriesContext.Provider>\n )\n}\n\nexport const useProjectTableQueriesContext = () => {\n const context = useContext(ProjectTableQueriesContext)\n if (!context) {\n throw new Error(\n 'useProjectTableQueriesContext must be used within a ProjectTableQueriesProvider',\n )\n }\n return context\n}\n","import { TableRow } from '../types/table'\nimport { FolderNodeMap } from '../types/table'\nimport { AttributeModel, LoadingTasks } from '../types'\n\n/**\n * Generates an array of placeholder rows for loading state\n * @param attribs - Attribute models used to populate empty attribute fields\n * @param count - Number of loading rows to generate (default: 50)\n * @returns Array of TableRow objects with loading state\n */\nexport const generateLoadingRows = (\n attribs: { name: string }[],\n count = 50,\n { type = 'folder', parentId }: { type?: string; parentId?: string } = {},\n): TableRow[] => {\n return new Array(count).fill(0).map(\n (_, index): TableRow => ({\n id: `loading-${type}-${index}-${parentId}`,\n name: 'Loading...',\n parentId: parentId,\n isLoading: true,\n label: 'Loading...',\n color: null,\n icon: null,\n img: null,\n entityType: type,\n ownAttrib: [],\n tags: [],\n subRows: [],\n path: '',\n attrib: attribs.reduce((acc: { [key: string]: null }, attrib) => {\n acc[attrib.name] = null\n return acc\n }, {}),\n }),\n )\n}\n\n/**\n * Generates an array of dummy attribute models for loading states\n * @param count - Number of dummy attributes to generate (default: 10)\n * @returns Array of AttributeModel objects\n */\nexport const generateDummyAttributes = (count = 10): AttributeModel[] => {\n return Array(count)\n .fill(null)\n .map((_, i): AttributeModel => {\n return {\n name: `loading-attribute${i}`,\n scope: ['folder', 'task'],\n data: {\n type: 'string',\n },\n position: i,\n }\n })\n}\n\n/**\n * Parameters for determineLoadingTaskFolders function\n */\nexport type DetermineLoadingTaskFoldersParams = {\n expandedFoldersTasks: { folderId: string | null }[]\n expandedParentIds: string[]\n foldersMap: FolderNodeMap\n}\n\n/**\n * Determines which folders are currently loading tasks\n * @param params - Object containing parameters for determining loading folders\n * @returns Array of folder IDs that are in loading state\n */\nexport const determineLoadingTaskFolders = ({\n expandedFoldersTasks,\n expandedParentIds,\n foldersMap,\n}: DetermineLoadingTaskFoldersParams): LoadingTasks => {\n // find the folderIds that are being fetched (not the ones that are already loaded)\n const folderIds = expandedFoldersTasks.map((task) => task.folderId)\n const expandedParentIdsThatHaveTasks = expandedParentIds.filter(\n (id) => foldersMap.get(id)?.hasTasks,\n )\n const folderIdsSet = new Set(folderIds)\n const loadingParentIds = new Set<string>()\n for (const folderId of expandedParentIdsThatHaveTasks) {\n if (!folderIdsSet.has(folderId)) {\n loadingParentIds.add(folderId)\n }\n }\n\n const loadingTasks: LoadingTasks = {}\n for (const folderId of loadingParentIds) {\n // find the folder by id\n const folder = foldersMap.get(folderId)\n if (folder) {\n loadingTasks[folderId] = folder.taskNames?.length || 0\n }\n }\n\n return loadingTasks\n}\n","import { useMemo } from 'react'\nimport {\n EditorTaskNode,\n FolderNodeMap,\n TableRow,\n TaskNodeMap,\n TasksByFolderMap,\n} from '../types/table'\nimport { ExpandedState } from '@tanstack/react-table'\nimport { generateLoadingRows } from '../utils/loadingUtils'\nconst TASKS_INFINITE_QUERY_COUNT = 100\nimport { LoadingTasks } from '../types'\nimport { FolderType, TaskType } from '../types/project'\n\ntype Params = {\n foldersMap: FolderNodeMap\n tasksMap: TaskNodeMap\n tasksByFolderMap: TasksByFolderMap\n expanded: ExpandedState\n folderTypes?: FolderType[]\n taskTypes?: TaskType[]\n showHierarchy: boolean\n loadingTasks: LoadingTasks\n isLoadingMore?: boolean\n}\n\n/**\n * React hook that creates a hierarchical tree structure from folders and tasks for use with TanStack Table\n * Uses memoization to avoid unnecessary recalculations on re-render\n *\n * @param foldersMap - Map of folders organized by folder ID\n * @param tasksMap - Map of tasks organized by task ID\n * @param tasksByFolderMap - Map of tasks organized by folder ID\n * @param expanded - Object with folder IDs as keys to indicate expanded folders\n * @param folderTypes - Array of folder types for to add things like folder icon\n * @param taskTypes - Array of task types for to add things like task icon\n * @param showHierarchy - Boolean to indicate if the hierarchy should be shown\n * @param loadingTasks - Object with folder IDs as keys to indicate loading tasks\n * @param isLoadingMore - Boolean to indicate if more tasks are being loaded\n * @returns An array of TableRow objects with nested subRows suitable for TanStack Table\n */\nexport default function useOverviewTable({\n foldersMap,\n tasksMap,\n tasksByFolderMap,\n expanded,\n folderTypes = [],\n taskTypes = [],\n showHierarchy,\n loadingTasks = {},\n isLoadingMore = false,\n}: Params): TableRow[] {\n // create a map of folder types by name for efficient lookups\n const folderTypesByName = useMemo(() => {\n const map: Map<string, FolderType> = new Map()\n for (const folderType of folderTypes) {\n map.set(folderType.name, folderType)\n }\n return map\n }, [folderTypes])\n\n // create a map of task types by name for efficient lookups\n const taskTypesByName = useMemo(() => {\n const map: Map<string, TaskType> = new Map()\n for (const taskType of taskTypes) {\n map.set(taskType.name, taskType)\n }\n return map\n }, [taskTypes])\n\n // Convert expanded object to a stable string for memoization comparison\n const expandedKey = useMemo(() => JSON.stringify(expanded), [expanded])\n\n // Memoize expandedFolderIds set for efficient lookups\n const expandedFolderIds = useMemo(() => {\n return new Set(\n Object.entries(expanded)\n .filter(([_, isExpanded]) => isExpanded)\n .map(([id]) => id),\n )\n }, [expandedKey])\n\n // Memoize relationship maps to avoid rebuilding them on every render\n const { childToParentMap, parentToChildrenMap } = useMemo(() => {\n const childToParent = new Map<string, string>()\n const parentToChildren = new Map<string, Set<string>>()\n\n // Construct relationship maps in a single pass\n for (const folder of foldersMap.values()) {\n if (!folder.id) continue\n\n const parentId = folder.parentId\n if (parentId) {\n childToParent.set(folder.id, parentId)\n\n let children = parentToChildren.get(parentId)\n if (!children) {\n children = new Set<string>()\n parentToChildren.set(parentId, children)\n }\n children.add(folder.id)\n }\n }\n\n return { childToParentMap: childToParent, parentToChildrenMap: parentToChildren }\n }, [foldersMap])\n\n // Memoize visible folders calculation\n const visibleFolders = useMemo(() => {\n const visible = new Set<string>()\n\n // Start with root folders and folders with non-existent parents\n const queue: string[] = []\n for (const folder of foldersMap.values()) {\n if (!folder.id) continue\n\n // Include folders with no parent OR with a parent that doesn't exist\n if (!folder.parentId || !foldersMap.has(folder.parentId)) {\n visible.add(folder.id)\n queue.push(folder.id)\n }\n }\n\n // Process queue to identify visible folders (BFS)\n while (queue.length > 0) {\n const folderId = queue.shift()!\n const isParentExpanded = expandedFolderIds.has(folderId)\n\n if (!isParentExpanded) continue\n\n // Add children of expanded folders to visible set\n const childrenIds = parentToChildrenMap.get(folderId)\n if (childrenIds) {\n for (const childId of childrenIds) {\n if (!visible.has(childId)) {\n visible.add(childId)\n queue.push(childId)\n }\n }\n }\n }\n\n return visible\n }, [foldersMap, parentToChildrenMap, expandedFolderIds])\n\n // Final memoized result - build the table tree\n return useMemo(() => {\n // Helper function to create a task row\n const createTaskRow = (task: EditorTaskNode, parentId?: string): TableRow => {\n return {\n id: task.id,\n entityType: 'task',\n parentId: parentId || task.folderId,\n name: task.name || '',\n label: task.label || task.name || '',\n icon: taskTypesByName.get(task.taskType)?.icon || null,\n color: taskTypesByName.get(task.taskType)?.color || null,\n status: task.status,\n assignees: task.assignees,\n tags: task.tags,\n img: null,\n subRows: [],\n subType: task.taskType || null,\n attrib: task.attrib,\n ownAttrib: task.ownAttrib,\n path: task.folder.path,\n }\n }\n\n // If showHierarchy is false, create a flat list of task rows\n if (!showHierarchy) {\n const flatTaskRows: TableRow[] = []\n\n // Loop through all tasks\n for (const task of tasksMap.values()) {\n if (!task.id) continue\n flatTaskRows.push(createTaskRow(task))\n }\n\n // Sort all tasks by name\n if (flatTaskRows.length > 1) {\n flatTaskRows.sort((a, b) => {\n if (a.name < b.name) return -1\n if (a.name > b.name) return 1\n return 0\n })\n }\n\n // if we are loading more tasks, add loading rows\n if (isLoadingMore) {\n const firstTaskAttrib = tasksMap.entries().next()?.value?.[1]?.attrib || {}\n const loadingAttribs = Object.keys(firstTaskAttrib).map((key) => ({\n name: key,\n }))\n // number of tasks we loading with the infinite query\n const count = TASKS_INFINITE_QUERY_COUNT\n if (count > 0) {\n const loadingTaskRows = generateLoadingRows(loadingAttribs, count, {\n type: 'task',\n })\n\n flatTaskRows.push(...loadingTaskRows)\n }\n }\n\n return flatTaskRows\n }\n\n // Use Map for O(1) lookups\n const rowsById = new Map<string, TableRow>()\n const rootRows: TableRow[] = []\n\n // Create minimal rows for only visible folders\n for (const folderId of visibleFolders) {\n const folder = foldersMap.get(folderId)\n if (!folder) continue\n\n // Create row with minimal required properties\n const row: TableRow = {\n id: folderId,\n entityType: 'folder',\n parentId: folder.parentId || undefined,\n name: folder.name || '',\n label: folder.label || folder.name || '',\n icon: folderTypesByName.get(folder.folderType)?.icon || null,\n color: null,\n img: null,\n subRows: [],\n status: folder.status,\n tags: folder.tags || [],\n subType: folder.folderType || null,\n ownAttrib: folder.ownAttrib || [],\n path: folder.path,\n attrib: folder.attrib || {},\n childOnlyMatch: folder.childOnlyMatch || false,\n }\n\n rowsById.set(folderId, row)\n\n // Add root rows directly to the rootRows array\n if (!folder.parentId || !foldersMap.has(folder.parentId)) {\n rootRows.push(row)\n }\n\n // Process tasks immediately if folder is expanded\n if (expandedFolderIds.has(folderId)) {\n // because tasksByFolderMap is a map of tasks by folder ID\n // we can directly get the tasks for the current folder\n const folderTaskIds = tasksByFolderMap.get(folderId) || []\n const folderTasks = folderTaskIds.flatMap((taskId) => tasksMap.get(taskId) || [])\n\n if (folderTasks.length || loadingTasks[folderId]) {\n // Use array literal with known length for better performance\n const taskRows = new Array<TableRow>(folderTasks.length)\n\n // Direct array assignment is faster than push operations\n for (let i = 0; i < folderTasks.length; i++) {\n taskRows[i] = createTaskRow(folderTasks[i], folderId)\n }\n\n // Add loading rows if applicable\n if (loadingTasks[folderId]) {\n const firstTaskAttrib = tasksMap.entries().next()?.value?.[1]?.attrib || {}\n const loadingAttribs = Object.keys(firstTaskAttrib).map((key) => ({\n name: key,\n }))\n const count = loadingTasks[folderId]\n if (count > 0) {\n const loadingTaskRows = generateLoadingRows(loadingAttribs, count, {\n type: 'task',\n parentId: folderId,\n })\n\n taskRows.push(...loadingTaskRows)\n }\n }\n // Only sort if we have multiple items\n if (taskRows.length > 1) {\n // Use a more efficient string comparison for sorting\n taskRows.sort((a, b) => {\n if (a.name < b.name) return -1\n if (a.name > b.name) return 1\n return 0\n })\n }\n\n row.subRows = taskRows\n }\n }\n }\n\n // Build the folder hierarchy efficiently\n for (const folderId of visibleFolders) {\n const parentId = childToParentMap.get(folderId)\n if (!parentId || !expandedFolderIds.has(parentId)) continue\n\n const childRow = rowsById.get(folderId)\n const parentRow = rowsById.get(parentId)\n\n if (!childRow || !parentRow) continue\n\n // Add folder to its parent's subRows\n parentRow.subRows.push(childRow)\n }\n\n // Sort subRows for expanded folders in a single pass\n for (const folderId of expandedFolderIds) {\n const row = rowsById.get(folderId)\n if (!row || row.subRows.length <= 1) continue\n\n // Process only folders that have both task rows and folder children\n const hasTasksAndFolders =\n row.subRows.some((r) => r.entityType === 'task') &&\n row.subRows.some((r) => r.entityType === 'folder')\n\n if (hasTasksAndFolders) {\n // More efficient sort using type as primary key to reduce comparisons\n row.subRows.sort((a, b) => {\n // Type first (tasks before folders)\n const typeA = a.entityType === 'task' ? 0 : 1\n const typeB = b.entityType === 'task' ? 0 : 1\n\n if (typeA !== typeB) return typeA - typeB\n\n // Then by name using more efficient string comparison\n if (a.name < b.name) return -1\n if (a.name > b.name) return 1\n return 0\n })\n }\n }\n\n // Sort root rows\n if (rootRows.length > 1) {\n rootRows.sort((a, b) => {\n if (a.name < b.name) return -1\n if (a.name > b.name) return 1\n return 0\n })\n }\n\n return rootRows\n }, [\n foldersMap,\n tasksMap,\n visibleFolders,\n childToParentMap,\n expandedFolderIds,\n showHierarchy,\n taskTypesByName,\n loadingTasks,\n isLoadingMore,\n ])\n}\n","import { useCallback, useMemo } from 'react'\nimport { EditorTaskNode, FolderNodeMap, MatchingFolder, TaskNodeMap } from '../types/table'\nimport { ProjectAttribModel2 } from '../types/project'\nimport { AttributeWithPermissions } from '../types'\n\nexport interface InheritedDependent {\n entityId: string\n entityType: 'task' | 'folder'\n attrib: Record<string, any> // all attribs that are inherited from the parent and their new value\n}\nexport type GetInheritedDependents = (entities: InheritedDependent[]) => InheritedDependent[]\nexport type FindInheritedValueFromAncestors = (\n entityId: string,\n entityType: 'folder' | 'task',\n attribName: string,\n) => any\nexport type FindNonInheritedValues = (\n folderId: string,\n attribNames: string[],\n) => Record<string, any>\nexport type GetAncestorsOf = (id: string) => string[]\ninterface UseFolderRelationshipsProps {\n foldersMap: FolderNodeMap\n tasksMap: TaskNodeMap\n tasksByFolderMap: Map<string, string[]>\n getEntityById: (id: string) => any\n projectAttrib: ProjectAttribModel2 | undefined\n attribFields: AttributeWithPermissions[] | undefined\n}\n\nexport default function useFolderRelationships({\n foldersMap,\n tasksMap,\n tasksByFolderMap,\n getEntityById,\n projectAttrib,\n attribFields,\n}: UseFolderRelationshipsProps) {\n // Pre-compute folder-children relationships\n const folderChildrenMap = useMemo(() => {\n const map = new Map<string, string[]>()\n for (const folder of foldersMap.values()) {\n const parentId = folder.parentId\n if (!parentId) continue\n\n if (!map.has(parentId)) {\n map.set(parentId, [])\n }\n map.get(parentId)!.push(folder.id)\n }\n return map\n }, [foldersMap])\n\n const getChildrenEntities = useCallback(\n (id: string) => {\n const descendants: (MatchingFolder | EditorTaskNode)[] = []\n const queue: string[] = [id]\n const visited = new Set<string>()\n\n while (queue.length > 0) {\n const currentId = queue.shift()!\n\n if (visited.has(currentId)) continue\n visited.add(currentId)\n\n // Skip adding the root folder to descendants\n if (currentId !== id) {\n const folder = foldersMap.get(currentId)\n if (folder) descendants.push({ ...folder, entityType: 'folder' })\n }\n\n // Add tasks efficiently with a single lookup\n const taskIds = tasksByFolderMap.get(currentId)\n if (taskIds?.length) {\n for (const taskId of taskIds) {\n const task = tasksMap.get(taskId)\n if (task) descendants.push({ ...task, entityType: 'task' })\n }\n }\n\n // Add folder children to queue\n const childFolderIds = folderChildrenMap.get(currentId)\n if (childFolderIds?.length) {\n queue.push(...childFolderIds)\n }\n }\n\n return descendants\n },\n [foldersMap, tasksByFolderMap, tasksMap, folderChildrenMap],\n )\n\n // Helper function to get ancestors of a folder\n const getAncestorsOf: GetAncestorsOf = useCallback(\n (id) => {\n const ancestors: string[] = []\n let currentId = id\n\n while (true) {\n const entity = foldersMap.get(currentId)\n if (!entity || !entity.parentId) break\n\n ancestors.push(entity.parentId)\n currentId = entity.parentId\n }\n\n return ancestors\n },\n [foldersMap],\n )\n\n // Helper function to get all folder ancestors of a task\n const getTaskAncestors = useCallback(\n (taskId: string): string[] => {\n const task = tasksMap.get(taskId)\n if (!task || !task.folderId) return []\n\n // Start with the direct parent folder\n const ancestors = [task.folderId]\n\n // Add all ancestors of the parent folder\n const folderAncestors = getAncestorsOf(task.folderId)\n ancestors.push(...folderAncestors)\n\n return ancestors\n },\n [tasksMap, getAncestorsOf],\n )\n\n // Helper function to find non-inherited values for multiple attributes from ancestors\n const findNonInheritedValues: FindNonInheritedValues = useCallback(\n (folderId, attribNames) => {\n if (!attribNames.length) return {}\n\n const result: Record<string, any> = {}\n const pendingAttribs = new Set(attribNames)\n\n // Start with the provided folder and traverse upward\n let currentId = folderId\n\n // Traverse up the folder hierarchy until we've found values for all attributes\n // or we've reached the root folder\n while (pendingAttribs.size > 0) {\n const folder = getEntityById(currentId)\n if (!folder || !currentId) {\n // use the project attrib\n for (const attribName of pendingAttribs) {\n if (projectAttrib && attribName in projectAttrib) {\n // @ts-ignore\n result[attribName] = projectAttrib[attribName]\n pendingAttribs.delete(attribName)\n }\n }\n\n // end search\n break\n }\n\n // Check if this folder has non-inherited values for any of our pending attributes\n for (const attribName of Array.from(pendingAttribs)) {\n if (\n folder.ownAttrib?.includes(attribName) &&\n folder.attrib &&\n attribName in folder.attrib\n ) {\n // Found a non-inherited value, add to result and remove from pending\n result[attribName] = folder.attrib[attribName]\n pendingAttribs.delete(attribName)\n }\n }\n\n // Move up to the parent folder\n currentId = folder.parentId\n }\n\n // For any attributes without non-inherited values found, set to null\n for (const attribName of pendingAttribs) {\n result[attribName] = null\n }\n\n return result\n },\n [getEntityById],\n )\n\n // Optimized implementation of getInheritedDependents\n const getInheritedDependents: GetInheritedDependents = useCallback(\n (entities) => {\n // console.time('getInheritedDependents') // 40ms - TODO improve this\n if (!entities.length) return []\n\n // Process all entities in one batch for efficiency\n const result: InheritedDependent[] = []\n\n // Track attributes that are owned (not inherited) to block inheritance\n const blockedInheritanceMap = new Map<string, Set<string>>()\n\n for (const entity of entities) {\n // check entity is folder\n if (entity.entityType !== 'folder') continue\n\n const attribEntries = Object.entries(entity.attrib)\n if (!attribEntries.length) continue\n\n const children = getChildrenEntities(entity.entityId)\n\n // filter out children that are in entities as they are already processed\n const filteredChildren = children.filter(\n (child) => !entities.find((e) => e.entityId === child.id),\n )\n\n if (!filteredChildren.length) continue\n\n for (const child of filteredChildren) {\n // Find which attributes would be inherited by this child\n const inheritedAttribs = attribEntries.filter(\n ([attribName]) =>\n !child.ownAttrib?.includes(attribName) &&\n attribFields?.find((a) => a.name === attribName)?.data?.inherit,\n )\n\n // Record attributes that child owns (has its own value for)\n const ownedAttribs = attribEntries.filter(([attribName]) =>\n child.ownAttrib?.includes(attribName),\n )\n\n // If the child has its own value for some attributes, block inheritance for its descendants\n if (ownedAttribs.length) {\n if (!blockedInheritanceMap.has(child.id)) {\n blockedInheritanceMap.set(child.id, new Set())\n }\n ownedAttribs.forEach(([attribName]) => {\n blockedInheritanceMap.get(child.id)!.add(attribName)\n })\n }\n\n // Filter out attributes blocked by ancestors\n const filteredInheritedAttribs = inheritedAttribs.filter(([attribName]) => {\n // Get ancestors based on entity type\n const ancestors =\n child.entityType === 'task' ? getTaskAncestors(child.id) : getAncestorsOf(child.id)\n\n // Check if any ancestor blocks this attribute\n for (const ancestor of ancestors) {\n if (\n blockedInheritanceMap.has(ancestor) &&\n blockedInheritanceMap.get(ancestor)!.has(attribName)\n ) {\n return false\n }\n }\n return true\n })\n\n if (filteredInheritedAttribs.length) {\n // Check if entity already exists in the result\n const existingEntityIndex = result.findIndex((item) => item.entityId === child.id)\n\n if (existingEntityIndex !== -1) {\n // Merge attributes with existing entry\n result[existingEntityIndex].attrib = {\n ...result[existingEntityIndex].attrib,\n ...Object.fromEntries(filteredInheritedAttribs),\n }\n } else {\n // Add new entity\n result.push({\n entityId: child.id,\n entityType: child.entityType || ('parentId' in child ? 'folder' : 'task'),\n attrib: Object.fromEntries(filteredInheritedAttribs),\n })\n }\n }\n }\n }\n\n // console.timeEnd('getInheritedDependents')\n\n return result\n },\n [getChildrenEntities, tasksMap, getTaskAncestors, getAncestorsOf],\n )\n\n // Helper function to find the inherited value for an attribute from ancestors\n const findInheritedValueFromAncestors = useCallback<FindInheritedValueFromAncestors>(\n (entityId, entityType, attribName) => {\n const entity = getEntityById(entityId)\n if (!entity) return null\n\n // For tasks, start with their parent folder\n let currentId = entityType === 'task' ? entity.folderId : entity.parentId\n\n // Traverse up the folder hierarchy\n while (currentId) {\n const ancestor = getEntityById(currentId)\n if (!ancestor) break\n\n // If the ancestor has its own value for this attribute, return it\n if (\n ancestor.ownAttrib?.includes(attribName) &&\n ancestor.attrib &&\n attribName in ancestor.attrib\n ) {\n return ancestor.attrib[attribName]\n }\n\n // Move up to the next parent\n currentId = ancestor.parentId\n }\n\n // If no ancestor has its own value, return null (will use the default)\n return null\n },\n [getEntityById],\n )\n\n return {\n folderChildrenMap,\n getChildrenEntities,\n getInheritedDependents,\n findInheritedValueFromAncestors,\n findNonInheritedValues,\n getAncestorsOf,\n }\n}\n","import { createContext, ReactNode, useCallback, useContext } from 'react'\nimport { ExpandedState, OnChangeFn, SortingState } from '@tanstack/react-table'\nimport useOverviewTable from '../hooks/useOverviewTable'\nimport { Filter } from '@ynput/ayon-react-components'\nimport {\n EditorTaskNode,\n FolderNodeMap,\n MatchingFolder,\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 { AttributeWithPermissions, LoadingTasks } from '../types'\nimport { QueryFilter } from '../types/folders'\n\ntype User = {\n name: string\n fullName?: string\n}\n\nexport interface ProjectTableContextProps {\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\n // Data\n tableData: TableRow[]\n tasksMap: ProjectTableProviderProps['tasksMap']\n foldersMap: ProjectTableProviderProps['foldersMap']\n fetchNextPage: ProjectTableProviderProps['fetchNextPage']\n reloadTableData: ProjectTableProviderProps['reloadTableData']\n getEntityById: (id: string) => MatchingFolder | EditorTaskNode | undefined\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: (rowId: RowId[], expand?: boolean) => void\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\nconst ProjectTableContext = createContext<ProjectTableContextProps | undefined>(undefined)\n\nexport interface ProjectTableProviderProps {\n children: ReactNode\n isInitialized: boolean\n\n // loading\n isLoading: boolean\n isLoadingMore: boolean\n loadingTasks: LoadingTasks\n // Project Info\n projectInfo?: ProjectModel\n projectName: string\n users: User[]\n // Attributes\n attribFields: AttributeWithPermissions[]\n\n // data\n tasksMap: TaskNodeMap\n foldersMap: FolderNodeMap\n tasksByFolderMap: TasksByFolderMap\n // data functions\n fetchNextPage: () => 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\nexport const ProjectTableProvider = ({\n children,\n foldersMap,\n tasksMap,\n tasksByFolderMap,\n expanded,\n projectInfo,\n showHierarchy,\n loadingTasks,\n isLoadingMore,\n isLoading,\n isInitialized,\n projectName,\n users,\n attribFields,\n filters,\n setFilters,\n queryFilters,\n updateShowHierarchy,\n toggleExpanded,\n updateExpanded,\n sorting,\n updateSorting,\n fetchNextPage,\n reloadTableData,\n setExpanded,\n}: ProjectTableProviderProps) => {\n const { folderTypes, taskTypes } = projectInfo || {}\n\n // DATA TO TABLE\n const tableData = useOverviewTable({\n foldersMap,\n tasksMap,\n tasksByFolderMap,\n expanded,\n folderTypes,\n taskTypes,\n showHierarchy,\n loadingTasks,\n isLoadingMore,\n })\n\n const getEntityById = useCallback(\n (id: string): MatchingFolder | EditorTaskNode | undefined => {\n // Check if it's a folder\n if (foldersMap.has(id)) {\n return { ...foldersMap.get(id), entityType: 'folder' } as MatchingFolder\n }\n // Check if it's a task\n if (tasksMap.has(id)) {\n return { ...tasksMap.get(id), entityType: 'task' } as EditorTaskNode\n }\n // Return undefined if not found\n return undefined\n },\n [foldersMap, tasksMap],\n )\n\n // get folder relationship functions\n const {\n getInheritedDependents,\n getChildrenEntities,\n findInheritedValueFromAncestors,\n findNonInheritedValues,\n getAncestorsOf,\n } = useFolderRelationships({\n foldersMap,\n tasksMap,\n tasksByFolderMap,\n getEntityById,\n projectAttrib: projectInfo?.attrib,\n attribFields: attribFields,\n })\n\n const toggleExpandAll: ProjectTableContextProps['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 return (\n <ProjectTableContext.Provider\n value={{\n // from this context\n tableData,\n // forwarded on\n isInitialized,\n isLoading,\n projectInfo,\n attribFields,\n users,\n projectName,\n tasksMap,\n foldersMap,\n fetchNextPage,\n reloadTableData,\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 // sorting\n sorting,\n updateSorting,\n getEntityById,\n // folder relationships\n getInheritedDependents,\n findInheritedValueFromAncestors,\n findNonInheritedValues,\n getAncestorsOf,\n }}\n >\n {children}\n </ProjectTableContext.Provider>\n )\n}\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","import { CellId } from '../utils/cellUtils'\nimport { CellValue } from '../widgets/CellWidget'\nimport { toast } from 'react-toastify'\nimport { useProjectTableQueriesContext } from '../context/ProjectTableQueriesContext'\nimport { useCallback } from 'react'\nimport { InheritedDependent } from './useFolderRelationships'\nimport { useProjectTableContext } from '../context/ProjectTableContext'\nimport { OperationModel } from '../types/operations'\nimport { PatchOperation } from '../types'\nimport { HistoryEntityUpdate, UseHistoryReturn } from './useHistory'\n\nexport type EntityUpdate = {\n id: string\n type: string\n field: string\n value: CellValue | CellValue[] | null\n isAttrib?: boolean\n}\nexport type UpdateTableEntities = (entities: EntityUpdate[], pushHistory?: boolean) => Promise<void>\n\nexport type InheritFromParentEntity = {\n entityId: string\n entityType: string\n attribs: string[]\n ownAttrib: string[]\n folderId: string\n}\nexport type InheritFromParent = (\n entities: InheritFromParentEntity[],\n pushHistory?: boolean,\n) => Promise<void>\n\nexport type UpdateTableEntity = (\n cellId: CellId,\n value: string,\n { includeSelection }: { includeSelection: boolean },\n) => Promise<void>\n\ninterface UseUpdateOverviewProps {\n pushHistory?: UseHistoryReturn['pushHistory']\n}\n\nconst useUpdateOverview = (props?: UseUpdateOverviewProps) => {\n const { pushHistory } = props || {}\n const {\n getEntityById,\n projectName,\n getInheritedDependents,\n findInheritedValueFromAncestors,\n findNonInheritedValues,\n } = useProjectTableContext()\n const { updateEntities } = useProjectTableQueriesContext()\n\n const handleUpdateEntities = useCallback<UpdateTableEntities>(\n async (entities = [], pushToHistory = true) => {\n if (!entities.length || !projectName) {\n return\n }\n\n // Record history of previous values before applying update\n if (pushHistory && pushToHistory) {\n const inverseEntities: HistoryEntityUpdate[] = entities.map(\n ({ id, type, field, isAttrib }) => {\n const entityData = getEntityById(id) as Record<string, any>\n const oldValue = isAttrib\n ? (entityData.attrib as Record<string, any>)?.[field] ?? null\n : entityData[field] ?? null\n\n // Check if the field was inherited (not in ownAttrib)\n const ownAttrib = entityData?.ownAttrib || []\n const wasInherited = isAttrib && !ownAttrib.includes(field)\n\n return {\n id,\n type,\n field,\n value: oldValue,\n isAttrib,\n wasInherited, // Track inheritance status for undo\n ownAttrib: ownAttrib,\n folderId: entityData?.folderId,\n }\n },\n )\n const historyEntities: HistoryEntityUpdate[] = entities.flatMap(\n ({ id, type, field, value, isAttrib }) => {\n const entityData = getEntityById(id)\n if (!entityData) return []\n\n return {\n id,\n type,\n field,\n value,\n isAttrib,\n ownAttrib: entityData?.ownAttrib || [],\n folderId: 'folderId' in entityData ? entityData.folderId : entityData?.parentId,\n }\n },\n )\n pushHistory(inverseEntities, historyEntities)\n }\n\n const supportedEntityTypes: OperationModel['entityType'][] = ['task', 'folder']\n // Group operations by entity type for bulk processing\n let operations: OperationModel[] = []\n for (const entity of entities) {\n let { id, type, field, value, isAttrib } = entity\n // Skip unsupported entity types\n let entityType = type as OperationModel['entityType']\n if (!supportedEntityTypes.includes(entityType)) {\n continue\n }\n\n // create data object for change, taking into account if it's an attribute change\n const data: Record<string, any> = isAttrib\n ? { attrib: { [field]: value } }\n : { [field]: value }\n\n // if the entity is an attribute get the entity data\n // then update ownAttrib to include the new value\n if (isAttrib) {\n const entityData = getEntityById(id)\n const ownAttrib = [...(entityData?.ownAttrib || [])]\n // add the new value to the ownAttrib if it doesn't already exist\n if (!ownAttrib.includes(field)) {\n ownAttrib.push(field)\n }\n // update the data object with the new ownAttrib\n data.ownAttrib = ownAttrib\n }\n\n const existingOperationIndex = operations.findIndex(\n (op) => op.entityId === entity.id && op.entityType === entityType,\n )\n\n if (existingOperationIndex !== -1) {\n // Merge data with existing operation\n const existingOperation = operations[existingOperationIndex]\n let newData = { ...existingOperation.data, ...data }\n\n // @ts-ignore\n if (existingOperation.data?.attrib && data.attrib) {\n // @ts-ignore\n newData = { ...newData, attrib: { ...existingOperation.data.attrib, ...data.attrib } }\n }\n\n operations[existingOperationIndex] = {\n ...existingOperation,\n data: newData,\n }\n } else {\n // Add new operation\n operations.push({\n entityType: entityType,\n entityId: entity.id,\n type: 'update',\n data: data,\n })\n }\n }\n\n const folderAttribEntities: InheritedDependent[] = operations\n .filter((op) => !!op.entityId && op.type === 'update' && op.data && 'attrib' in op.data)\n .map((op) => ({\n entityId: op.entityId as string,\n entityType: op.entityType as 'folder' | 'task',\n attrib:\n op.data && 'attrib' in op.data ? (op.data?.attrib as InheritedDependent['attrib']) : {},\n }))\n\n const inheritedDependents = getInheritedDependents(folderAttribEntities)\n\n // convert to operations\n const inheritedDependentsOperations: PatchOperation[] = inheritedDependents.map((op) => ({\n entityId: op.entityId,\n entityType: op.entityType,\n data: {\n attrib: op.attrib,\n },\n }))\n\n // now make api call to update all entities\n try {\n await updateEntities({\n operations,\n patchOperations: inheritedDependentsOperations,\n })\n } catch (error) {\n toast.error('Failed to update entities')\n }\n },\n [projectName, updateEntities, getEntityById, getInheritedDependents, pushHistory],\n )\n\n // set the attrib fields to be inherited from the parent\n // (remove the field from the ownAttrib array)\n // invalidate the cache for the folder/task so that it can be re-fetched with inherited values\n const inheritFromParent = useCallback<InheritFromParent>(\n async (entities, pushToHistory = true) => {\n if (!entities.length || !projectName) {\n return\n }\n\n // Record history for the inheritance operation\n if (pushToHistory && pushHistory) {\n // Create undo entities (restore explicit values)\n const undoEntities: HistoryEntityUpdate[] = []\n\n // For each entity and attribute being inherited, record current values\n for (const entity of entities) {\n const entityData = getEntityById(entity.entityId) as Record<string, any>\n\n // For each attribute that will be inherited, record its current value\n for (const attrib of entity.attribs) {\n if (entityData?.attrib && attrib in entityData.attrib) {\n undoEntities.push({\n id: entity.entityId,\n type: entity.entityType,\n field: attrib,\n value: (entityData.attrib as Record<string, any>)[attrib],\n isAttrib: true,\n wasInherited: false, // Mark as not inherited\n ownAttrib: entityData?.ownAttrib || [],\n folderId: entityData?.folderId,\n })\n }\n }\n }\n\n // Create redo entities (to re-inherit)\n const redoEntities: HistoryEntityUpdate[] = entities.flatMap((entity) =>\n entity.attribs.map((attrib) => ({\n id: entity.entityId,\n type: entity.entityType,\n field: attrib,\n value: null,\n isAttrib: true,\n wasInherited: true, // Mark as inherited\n ownAttrib: entity.ownAttrib,\n folderId: entity.folderId,\n })),\n )\n\n // Push to history if we have changes to record\n if (undoEntities.length > 0) {\n pushHistory(undoEntities, redoEntities)\n }\n }\n\n const supportedEntityTypes: OperationModel['entityType'][] = ['task', 'folder']\n // Group operations by entity type for bulk processing\n const operations: OperationModel[] = [] // operations sent to the server\n const entitiesToPatch: InheritFromParentEntity[] = []\n for (const entity of entities) {\n // Skip unsupported entity types\n let entityType = entity.entityType as OperationModel['entityType']\n if (!supportedEntityTypes.includes(entityType)) {\n continue\n }\n entityType = entityType as 'task' | 'folder'\n\n // Create data object with null values for each attrib to inherit\n const attribData: Record<string, null> = {}\n entity.attribs.forEach((attrib) => {\n attribData[attrib] = null\n })\n\n // Add new operation this is what's sent to the server and is actually updated in the DB\n operations.push({\n entityType: entityType,\n entityId: entity.entityId,\n type: 'update',\n data: {\n attrib: attribData,\n },\n })\n\n // check if this entity has a folderId that is in entities\n // if so we check their intersection attrib names\n const findTopFolder = () => {\n // For each entity, we need to find the top-most folder in the hierarchy\n const folderId = entity.folderId\n\n // Find all ancestor folders that are in our entities list\n const ancestorChain: InheritFromParentEntity[] = []\n let currentFolderId = folderId\n let currentFolder = entities.find((e) => e.entityId === currentFolderId)\n\n // Climb up the folder hierarchy to build the chain of ancestors\n while (currentFolder) {\n ancestorChain.push(currentFolder)\n currentFolderId = currentFolder.folderId\n currentFolder = entities.find((e) => e.entityId === currentFolderId)\n }\n\n // The top folder is the last one in our ancestor chain (if any)\n const topFolder =\n ancestorChain.length > 0 ? ancestorChain[ancestorChain.length - 1] : null\n\n return topFolder\n }\n\n const topFolder = findTopFolder()\n const folderAttribs = topFolder?.attribs || []\n const entityAttribsIntersection = entity.attribs.filter((attrib) =>\n folderAttribs.includes(attrib),\n )\n const entityAttribsRemoved = entity.attribs.filter(\n (attrib) => !folderAttribs.includes(attrib),\n )\n\n // only add to patch operations if there are attribs left\n if (entityAttribsRemoved.length > 0)\n entitiesToPatch.push({\n ...entity,\n attribs: entityAttribsRemoved,\n })\n\n if (topFolder && entityAttribsIntersection.length > 0) {\n entitiesToPatch.push({\n ...entity,\n attribs: entityAttribsIntersection,\n folderId: topFolder.folderId,\n })\n }\n }\n\n const patchOperations: PatchOperation[] = [] // operations only for patching the cache\n for (const entity of entitiesToPatch) {\n const entityType = entity.entityType as 'task' | 'folder'\n // we also need to update ownAttrib to remove the inherited attribs\n const ownAttrib = [...(entity.ownAttrib || [])].filter(\n (attrib) => !entity.attribs.includes(attrib),\n )\n\n // now we must calculate all the entities that need to be updated in the cache\n // first we need to find the the ancestor folder to inherit from\n const ancestorAttrib = findNonInheritedValues(entity.folderId, entity.attribs)\n\n const entityPatch = {\n entityId: entity.entityId,\n entityType: entityType,\n data: {\n attrib: ancestorAttrib,\n ownAttrib: ownAttrib,\n },\n }\n\n // create new patch operation for the entity\n patchOperations.push(entityPatch)\n\n // now find any dependent that also need updating\n const inheritedDependents = getInheritedDependents([\n { entityId: entity.entityId, entityType: entityType, attrib: ancestorAttrib },\n ])\n\n // convert to operations\n const inheritedDependentsOperations: PatchOperation[] = inheritedDependents.map((op) => ({\n entityId: op.entityId,\n entityType: op.entityType,\n data: {\n attrib: op.attrib,\n },\n }))\n\n // try to add to patch operations\n // if it already exists then merge the attribs\n for (const inheritedDependent of inheritedDependentsOperations) {\n const existingOperationIndex = patchOperations.findIndex(\n (op) => op.entityId === inheritedDependent.entityId,\n )\n\n if (existingOperationIndex !== -1) {\n // Merge attribs with existing operation\n const existingOperation = patchOperations[existingOperationIndex]\n let newAttrib = {\n // @ts-ignore\n ...(existingOperation.data?.attrib || {}),\n // @ts-ignore\n ...(inheritedDependent.data?.attrib || {}),\n }\n\n patchOperations[existingOperationIndex] = {\n ...existingOperation,\n data: { attrib: newAttrib },\n }\n } else {\n // Add new operation\n patchOperations.push({\n entityId: inheritedDependent.entityId,\n entityType: inheritedDependent.entityType,\n data: inheritedDependent.data,\n })\n }\n }\n }\n\n // now make api call to update all entities\n try {\n await updateEntities({\n operations,\n patchOperations,\n })\n } catch (error) {\n toast.error('Failed to update entities')\n }\n },\n [\n projectName,\n updateEntities,\n getInheritedDependents,\n findInheritedValueFromAncestors,\n pushHistory,\n ],\n )\n\n return { updateEntities: handleUpdateEntities, inheritFromParent }\n}\n\nexport default useUpdateOverview\n","import { ReactNode } from 'react'\nimport { FolderNodeMap, TaskNodeMap } from '../../types/table'\nimport { AttributeEnumItem, BuiltInFieldOptions } from '../../types'\n\n// Constants for field mappings\nexport const builtInFieldMappings = {\n status: 'statuses',\n folderType: 'folderTypes',\n taskType: 'taskTypes',\n}\n\nexport interface ColumnEnums extends BuiltInFieldOptions {\n [attrib: string]: AttributeEnumItem[]\n}\n\nexport interface ClipboardContextType {\n copyToClipboard: (selected?: string[], fullRow?: boolean) => Promise<void>\n pasteFromClipboard: (selected?: string[]) => Promise<void>\n exportCSV: (selected: string[], projectName: string, fullRow?: boolean) => void\n}\n\nexport interface ClipboardProviderProps {\n children: ReactNode\n foldersMap: FolderNodeMap\n tasksMap: TaskNodeMap\n columnEnums: ColumnEnums\n columnReadOnly: string[]\n}\n\nexport interface ParsedClipboardData {\n values: string[]\n colIds: string[]\n}\n","import { toast } from 'react-toastify'\nimport { FolderNodeMap, TaskNodeMap } from '../../types/table'\nimport { ParsedClipboardData } from './clipboardTypes'\n\nexport const clipboardError = (error: string) => toast.error(error)\n\n// Parse clipboard text into rows and columns\nexport const parseClipboardText = (clipboardText: string): ParsedClipboardData[] => {\n const rows = clipboardText.trim().split('\\n')\n const parsedData: ParsedClipboardData[] = []\n\n // Store original column order for validation\n const origColumnOrder: string[] = []\n\n // Parse each row into values\n rows.forEach((row) => {\n const rowValues = row.split('\\t')\n parsedData.push({ values: rowValues, colIds: origColumnOrder })\n })\n\n return parsedData\n}\n\n// Get the full path for an entity\nexport const getEntityPath = (\n entityId: string,\n isFolder: boolean,\n foldersMap: FolderNodeMap,\n tasksMap: TaskNodeMap,\n): string => {\n const entity = isFolder ? foldersMap.get(entityId) : tasksMap.get(entityId)\n if (!entity) return ''\n\n const name = entity.name || ''\n // @ts-ignore\n const parentId = entity.folderId || entity.parentId\n\n // If no parent, return just the name\n if (!parentId) return name\n\n // If has parent, get parent path (parents are always folders)\n const parentPath = getEntityPath(parentId, true, foldersMap, tasksMap)\n\n // Combine paths with \" / \" separator\n return parentPath ? `${parentPath} / ${name}` : name\n}\n\n// Process a field value based on its type\nexport const processFieldValue = (\n value: string,\n fieldValueType: 'string' | 'number' | 'boolean' | 'array',\n): any => {\n if (fieldValueType === 'array') {\n try {\n // Try to parse as JSON first (for copied arrays)\n try {\n const parsed = JSON.parse(value)\n return Array.isArray(parsed) ? parsed : [parsed]\n } catch {\n // If not valid JSON, treat as comma-separated values\n return value.includes(',') ? value.split(',').map((v) => v.trim()) : [value]\n }\n } catch {\n // Fallback to single-item array if parsing fails\n return [value]\n }\n } else if (fieldValueType === 'number') {\n return Number(value) || 0\n } else if (fieldValueType === 'boolean') {\n return value.toLowerCase() === 'true' || value === '1' || value.toLowerCase() === 'yes'\n }\n\n // Default string handling\n return value\n}\n","import { ColumnEnums, builtInFieldMappings, ParsedClipboardData } from './clipboardTypes'\nimport { clipboardError } from './clipboardUtils'\n\n// Validate clipboard data for enum fields and handle special cases\nexport const validateClipboardData = (params: {\n colId: string\n isFolder: boolean\n pasteValue: string\n parsedData: ParsedClipboardData[]\n columnEnums: ColumnEnums\n columnReadOnly: string[]\n rowIndex: number\n colIndex: number\n isSingleCellValue: boolean\n}): boolean => {\n const {\n colId,\n isFolder,\n pasteValue,\n parsedData,\n columnEnums,\n columnReadOnly,\n rowIndex,\n colIndex,\n isSingleCellValue,\n } = params\n\n // Skip validation for empty values\n if (!pasteValue) return true\n\n // Check if the column is read-only\n if (colId.startsWith('attrib_') && columnReadOnly.includes(colId.replace('attrib_', ''))) {\n clipboardError(`This column is read-only: \"${colId}\". Paste operation cancelled.`)\n return false\n }\n\n // Special handling for assignees - filter out invalid values instead of canceling\n if (colId === 'assignees') {\n // Split assignees by comma\n const assigneeValues = pasteValue.split(',').map((v) => v.trim())\n\n // Get assignee options from columnEnums\n const assigneeOptions = columnEnums['assignees'] || []\n\n // Filter to keep only valid assignees\n const validAssignees = assigneeValues.filter((v) =>\n assigneeOptions.some((opt) => opt.value === v || opt.label === v),\n )\n\n // Update the paste value in the parsed data\n if (isSingleCellValue) {\n parsedData[0].values[0] = validAssignees.join(', ')\n } else {\n const pasteRowIndex = rowIndex % parsedData.length\n const pasteColIndex = colIndex % parsedData[pasteRowIndex].values.length\n parsedData[pasteRowIndex].values[pasteColIndex] = validAssignees.join(', ')\n }\n\n return true\n }\n\n // Map subType to the actual field name\n let fieldId = colId === 'subType' ? (isFolder ? 'folderType' : 'taskType') : colId\n // Check if fieldId has a mapping to plural enum\n fieldId = builtInFieldMappings[fieldId as keyof typeof builtInFieldMappings] || fieldId\n\n // Skip validation for fields that don't have enums\n if (!(fieldId in columnEnums)) return true\n\n // Get the enum values for this field\n const enumOptions = columnEnums[fieldId as keyof typeof columnEnums]\n\n // Skip if no enum options are available\n if (!Array.isArray(enumOptions) || enumOptions.length === 0) return true\n\n // Check if the pasted value exists in the enum options\n const enumValues = pasteValue.split(',').map((v) => v.trim())\n const valueExists = enumValues.every((v) =>\n enumOptions.some((opt) => opt.value === v || opt.label === v),\n )\n\n if (!valueExists) {\n // Get a display name for the field (folderType/taskType → Type)\n const displayName =\n fieldId === 'folderType' || fieldId === 'taskType'\n ? `${isFolder ? 'folder' : 'task'} type`\n : fieldId\n\n clipboardError(`Invalid ${displayName} value: \"${pasteValue}\". Paste operation cancelled.`)\n return false\n }\n\n return true\n}\n","/**\n * Shared cell utilities for table operations\n */\n\n// Type definitions for cell identifiers\nexport type CellId = string\nexport type RowId = string\nexport type ColId = string\n\n// Cell position in the grid\nexport interface CellPosition {\n rowId: RowId\n colId: ColId\n}\n\n// Cell border position flags - used for determining which borders to show\nexport enum BorderPosition {\n None = 0,\n Top = 1 << 0,\n Right = 1 << 1,\n Bottom = 1 << 2,\n Left = 1 << 3,\n All = Top | Right | Bottom | Left,\n}\n\n/**\n * Create a standardized cell ID from row and column IDs\n */\nexport const getCellId = (rowId: RowId, colId: ColId): CellId => `cell-${rowId}-${colId}`\n\n/**\n * Parse a cell ID to extract row and column IDs\n * @returns CellPosition or null if invalid format\n */\nexport const parseCellId = (cellId: CellId): CellPosition | null => {\n const match = cellId.match(/^cell-(.+)-(.+)$/)\n if (!match) return null\n return { rowId: match[1], colId: match[2] }\n}\n\nexport const getCellValue = (obj: any, path: string): any => {\n if (!obj || !path) return undefined\n\n const parts = path.split('_')\n let current = obj\n\n for (const part of parts) {\n if (current && typeof current === 'object' && part in current) {\n current = current[part]\n } else {\n return undefined // Return undefined if any part of the path is invalid\n }\n }\n\n return current\n}\n\n/**\n * Determines which borders to display for a selected cell\n * based on its position within the selection grid\n *\n * @param rowIndex Current cell's row index\n * @param colIndex Current cell's column index\n * @param selectedCells 2D array representing selection state (true = selected)\n * @returns BorderPosition flags indicating which borders to display\n */\nexport const getCellBorders = (\n rowIndex: number,\n colIndex: number,\n selectedCells: boolean[][],\n): BorderPosition => {\n if (!selectedCells[rowIndex]?.[colIndex]) {\n return BorderPosition.None\n }\n\n let borders = BorderPosition.None\n\n // Check top border\n if (rowIndex === 0 || !selectedCells[rowIndex - 1]?.[colIndex]) {\n borders |= BorderPosition.Top\n }\n\n // Check right border\n if (!selectedCells[rowIndex]?.[colIndex + 1]) {\n borders |= BorderPosition.Right\n }\n\n // Check bottom border\n if (!selectedCells[rowIndex + 1]?.[colIndex]) {\n borders |= BorderPosition.Bottom\n }\n\n // Check left border\n if (colIndex === 0 || !selectedCells[rowIndex]?.[colIndex - 1]) {\n borders |= BorderPosition.Left\n }\n\n return borders\n}\n\n/**\n * Converts border position flags to CSS classes for shadow styling\n */\nexport const getBorderClasses = (borders: BorderPosition): string[] => {\n const classes: string[] = []\n\n if (borders & BorderPosition.Top) classes.push('shadow-top')\n if (borders & BorderPosition.Right) classes.push('shadow-right')\n if (borders & BorderPosition.Bottom) classes.push('shadow-bottom')\n if (borders & BorderPosition.Left) classes.push('shadow-left')\n\n return classes\n}\n","import React, {\n createContext,\n useContext,\n useState,\n useCallback,\n useMemo,\n ReactNode,\n useRef,\n} from 'react'\nimport {\n CellId,\n RowId,\n ColId,\n CellPosition,\n getCellId,\n parseCellId,\n BorderPosition,\n getBorderClasses,\n} from '../utils/cellUtils'\n\nexport const ROW_SELECTION_COLUMN_ID = '__row_selection__' // ID for the row selection column\n\n// Cell range for selections\n\n// Structure to map row/column IDs to their positions in the grid\nexport interface GridMap {\n rowIdToIndex: Map<RowId, number>\n colIdToIndex: Map<ColId, number>\n indexToRowId: Map<number, RowId>\n indexToColId: Map<number, ColId>\n}\n\nexport interface SelectionContextType {\n // Selected cells\n selectedCells: Set<CellId>\n // Focused cell (single cell that has focus)\n focusedCellId: CellId | null\n // Selection in progress state\n selectionInProgress: boolean\n // Anchor point for range selections\n anchorCell: CellPosition | null\n // Grid mapping for coordinate lookups\n gridMap: GridMap\n\n selectedRows: string[] // Array of selected row IDs\n\n // State setters\n setSelectedCells: React.Dispatch<React.SetStateAction<Set<CellId>>>\n setFocusedCellId: React.Dispatch<React.SetStateAction<CellId | null>>\n setAnchorCell: React.Dispatch<React.SetStateAction<CellPosition | null>>\n // Methods\n registerGrid: (rows: RowId[], columns: ColId[]) => void\n selectCell: (cellId: CellId, additive: boolean, range: boolean) => void\n startSelection: (cellId: CellId, additive: boolean) => void\n extendSelection: (cellId: CellId, isRowSelectionColumn?: boolean) => void\n endSelection: (cellId: CellId) => void\n focusCell: (cellId: CellId | null) => void\n clearSelection: () => void\n isCellSelected: (cellId: CellId) => boolean\n isCellFocused: (cellId: CellId) => boolean\n getCellPositionFromId: (cellId: CellId) => CellPosition | null\n getCellBorderClasses: (cellId: CellId) => string[]\n}\n\n// Create the context\nconst SelectionContext = createContext<SelectionContextType | undefined>(undefined)\n\nexport const SelectionProvider: React.FC<{ children: ReactNode }> = ({ children }) => {\n const [selectedCells, setSelectedCells] = useState<Set<CellId>>(new Set())\n const [focusedCellId, setFocusedCellId] = useState<CellId | null>(null)\n const [selectionInProgress, setSelectionInProgress] = useState<boolean>(false)\n const [anchorCell, setAnchorCell] = useState<CellPosition | null>(null)\n const [gridMap, setGridMap] = useState<GridMap>({\n rowIdToIndex: new Map(),\n colIdToIndex: new Map(),\n indexToRowId: new Map(),\n indexToColId: new Map(),\n })\n const mapToString = (map: Map<any, any>) => {\n return JSON.stringify(Array.from(map.entries()))\n }\n\n const stableGridMap = useMemo(\n () => gridMap,\n [\n mapToString(gridMap.rowIdToIndex),\n mapToString(gridMap.colIdToIndex),\n mapToString(gridMap.indexToRowId),\n mapToString(gridMap.indexToColId),\n ],\n )\n // Track whether we're selecting or unselecting during drag\n const initialCellSelected = useRef<boolean>(false)\n\n const selectedRows = useMemo(\n () =>\n Array.from(selectedCells)\n .filter(\n (cellId) =>\n parseCellId(cellId)?.colId === ROW_SELECTION_COLUMN_ID && parseCellId(cellId)?.rowId,\n )\n .map((cellId) => parseCellId(cellId)?.rowId) as string[],\n [selectedCells],\n )\n\n // Register grid structure for range selections\n const registerGrid = useCallback((rows: RowId[], columns: ColId[]) => {\n const rowIdToIndex = new Map<RowId, number>()\n const colIdToIndex = new Map<ColId, number>()\n const indexToRowId = new Map<number, RowId>()\n const indexToColId = new Map<number, ColId>()\n\n rows.forEach((rowId, index) => {\n rowIdToIndex.set(rowId, index)\n indexToRowId.set(index, rowId)\n })\n\n columns.forEach((colId, index) => {\n colIdToIndex.set(colId, index)\n indexToColId.set(index, colId)\n })\n\n setGridMap({ rowIdToIndex, colIdToIndex, indexToRowId, indexToColId })\n }, [])\n\n // update the selection whilst properly handling the row-selection column\n const updateSelection = useCallback((selection: Set<CellId>, position: CellPosition) => {\n setSelectedCells((prevSelectedCells) => {\n let newSelection = new Set(selection)\n if (position.colId !== ROW_SELECTION_COLUMN_ID) {\n const rowSelection = Array.from(prevSelectedCells).filter(\n (id) => parseCellId(id)?.colId === ROW_SELECTION_COLUMN_ID,\n )\n if (rowSelection.length) {\n newSelection = new Set([...newSelection, ...rowSelection])\n }\n }\n return newSelection\n })\n }, [])\n\n // Select cells between two points in the grid\n const selectCellRange = useCallback(\n (start: CellPosition, end: CellPosition, additive: boolean): Set<CellId> => {\n if (!additive) {\n // Clear existing selection if not additive\n updateSelection(new Set(), start)\n }\n\n const startRowIdx = stableGridMap.rowIdToIndex.get(start.rowId) ?? 0\n const startColIdx = stableGridMap.colIdToIndex.get(start.colId) ?? 0\n const endRowIdx = stableGridMap.rowIdToIndex.get(end.rowId) ?? 0\n const endColIdx = stableGridMap.colIdToIndex.get(end.colId) ?? 0\n\n const minRowIdx = Math.min(startRowIdx, endRowIdx)\n const maxRowIdx = Math.max(startRowIdx, endRowIdx)\n const minColIdx = Math.min(startColIdx, endColIdx)\n const maxColIdx = Math.max(startColIdx, endColIdx)\n\n const newSelection = new Set(additive ? selectedCells : [])\n\n for (let r = minRowIdx; r <= maxRowIdx; r++) {\n const rowId = stableGridMap.indexToRowId.get(r)\n if (!rowId) continue\n\n for (let c = minColIdx; c <= maxColIdx; c++) {\n const colId = stableGridMap.indexToColId.get(c)\n if (!colId) continue\n\n newSelection.add(getCellId(rowId, colId))\n }\n }\n\n return newSelection\n },\n [stableGridMap, selectedCells],\n )\n\n // Start a selection operation\n const startSelection = useCallback(\n (cellId: CellId, additive: boolean) => {\n const position = parseCellId(cellId)\n if (!position) return\n\n setSelectionInProgress(true)\n // Store whether the initial cell was selected to determine drag behavior\n initialCellSelected.current = selectedCells.has(cellId)\n\n if (additive) {\n // Toggle this cell in multi-select mode\n setSelectedCells((prev) => {\n const newSelection = new Set(prev)\n if (newSelection.has(cellId)) {\n newSelection.delete(cellId)\n // If this was the focused cell, set focus to another cell in the selection or null\n if (focusedCellId === cellId) {\n if (newSelection.size > 0) {\n setFocusedCellId(Array.from(newSelection)[Array.from(newSelection).length - 1])\n } else {\n setFocusedCellId(null)\n }\n }\n } else {\n newSelection.add(cellId)\n setFocusedCellId(cellId)\n setAnchorCell(position)\n }\n return newSelection\n })\n } else {\n // Single cell selection\n // If this cell is already the only selected cell, deselect it\n // and it is from name column\n if (\n selectedCells.size === 1 &&\n selectedCells.has(cellId) &&\n [ROW_SELECTION_COLUMN_ID, 'name'].includes(position.colId)\n ) {\n setSelectedCells(new Set())\n setAnchorCell(null)\n setFocusedCellId(null)\n } else {\n updateSelection(new Set([cellId]), position)\n setAnchorCell(position)\n setFocusedCellId(cellId)\n }\n }\n },\n [selectedCells, focusedCellId],\n )\n\n // Extend the current selection during drag\n const extendSelection = useCallback(\n (cellId: CellId, isRowSelectionColumn?: boolean) => {\n if (!selectionInProgress || !anchorCell) return\n\n const currentPosition = parseCellId(cellId)\n if (!currentPosition) return\n\n if (isRowSelectionColumn) {\n // Handle row selection column differently during drag\n setSelectedCells((prev) => {\n const newSelection = new Set(prev)\n const position = parseCellId(cellId)\n\n if (!position) return newSelection\n\n // We're either selecting or unselecting based on the initial cell's state\n if (initialCellSelected.current) {\n // If we started on a selected cell, we're removing cells during drag\n newSelection.delete(cellId)\n } else {\n // If we started on an unselected cell, we're adding cells during drag\n newSelection.add(cellId)\n }\n\n return newSelection\n })\n } else {\n // For normal cells, use the range selection behavior\n const newSelection = selectCellRange(anchorCell, currentPosition, false)\n updateSelection(newSelection, currentPosition)\n }\n },\n [selectionInProgress, anchorCell, selectCellRange],\n )\n\n // End a selection operation\n const endSelection = useCallback(() => {\n setSelectionInProgress(false)\n }, [])\n\n // Select a cell (click or programmatically)\n const selectCell = useCallback(\n (cellId: CellId, additive: boolean, range: boolean) => {\n const position = parseCellId(cellId)\n if (!position) return\n\n if (range && anchorCell) {\n // Shift+click for range selection - select cells between anchor and current\n const newSelection = selectCellRange(anchorCell, position, additive)\n updateSelection(newSelection, position)\n } else if (additive) {\n // Ctrl/Cmd+click for toggling selection\n setSelectedCells((prev) => {\n const newSelection = new Set(prev)\n if (newSelection.has(cellId)) {\n newSelection.delete(cellId)\n } else {\n newSelection.add(cellId)\n }\n return newSelection\n })\n } else {\n // Normal click - select just this cell and set as new anchor\n updateSelection(new Set([cellId]), position)\n setAnchorCell(position)\n }\n },\n [anchorCell, selectCellRange],\n )\n\n // Focus a cell without changing selection\n const focusCell = useCallback((cellId: CellId | null) => {\n setFocusedCellId(cellId)\n }, [])\n\n // Clear all selections\n const clearSelection = useCallback(() => {\n setSelectedCells(new Set())\n setAnchorCell(null)\n }, [])\n\n // Check if a cell is selected\n const isCellSelected = useCallback((cellId: CellId) => selectedCells.has(cellId), [selectedCells])\n\n // Check if a cell is focused\n const isCellFocused = useCallback((cellId: CellId) => cellId === focusedCellId, [focusedCellId])\n\n // Get position from cell ID - using shared utility\n const getCellPositionFromId = useCallback((cellId: CellId) => parseCellId(cellId), [])\n\n // Get border classes for a cell based on its selection state and neighbors\n const getCellBorderClasses = useCallback(\n (cellId: CellId): string[] => {\n if (!isCellSelected(cellId)) return []\n\n const position = parseCellId(cellId)\n if (!position) return []\n\n const rowIndex = stableGridMap.rowIdToIndex.get(position.rowId)\n const colIndex = stableGridMap.colIdToIndex.get(position.colId)\n\n if (rowIndex === undefined || colIndex === undefined) return []\n\n // Check if the cell's neighbors in all four directions are selected\n const top = stableGridMap.indexToRowId.get(rowIndex - 1)\n const right = stableGridMap.indexToColId.get(colIndex + 1)\n const bottom = stableGridMap.indexToRowId.get(rowIndex + 1)\n const left = stableGridMap.indexToColId.get(colIndex - 1)\n\n // Default to no borders\n let borderPos = BorderPosition.None\n\n // Top edge check: show border if we're at the top of the grid or the cell above is not selected\n if (!top || !selectedCells.has(getCellId(top, position.colId))) {\n borderPos |= BorderPosition.Top\n }\n\n // Right edge check: show border if we're at the right edge of the grid or the cell to the right is not selected\n if (!right || !selectedCells.has(getCellId(position.rowId, right))) {\n borderPos |= BorderPosition.Right\n }\n\n // Bottom edge check: show border if we're at the bottom of the grid or the cell below is not selected\n if (!bottom || !selectedCells.has(getCellId(bottom, position.colId))) {\n borderPos |= BorderPosition.Bottom\n }\n\n // Left edge check: show border if we're at the left edge of the grid or the cell to the left is not selected\n if (!left || !selectedCells.has(getCellId(position.rowId, left))) {\n borderPos |= BorderPosition.Left\n }\n\n return getBorderClasses(borderPos)\n },\n [selectedCells, stableGridMap, isCellSelected],\n )\n\n // Memoize context value to prevent unnecessary re-renders\n const value = useMemo(\n () => ({\n selectedCells,\n selectedRows,\n focusedCellId,\n selectionInProgress,\n anchorCell,\n gridMap: stableGridMap,\n setSelectedCells,\n setFocusedCellId,\n setAnchorCell,\n registerGrid,\n selectCell,\n startSelection,\n extendSelection,\n endSelection,\n focusCell,\n clearSelection,\n isCellSelected,\n isCellFocused,\n getCellPositionFromId,\n getCellBorderClasses,\n }),\n [\n selectedCells,\n selectedRows,\n focusedCellId,\n selectionInProgress,\n anchorCell,\n stableGridMap,\n // setSelectedCells,\n // setFocusedCellId,\n // setAnchorCell,\n // registerGrid,\n // selectCell,\n // startSelection,\n // extendSelection,\n // endSelection,\n // focusCell,\n // clearSelection,\n // isCellSelected,\n // isCellFocused,\n // getCellPositionFromId,\n // getCellBorderClasses,\n ],\n )\n\n return <SelectionContext.Provider value={value}>{children}</SelectionContext.Provider>\n}\n\nexport const useSelectionContext = (): SelectionContextType => {\n const context = useContext(SelectionContext)\n if (context === undefined) {\n throw new Error('useSelectionContext must be used within a SelectionProvider')\n }\n return context\n}\n","import React, { createContext, useContext, useCallback, useMemo, useEffect } from 'react'\n\n// Contexts\nimport { ROW_SELECTION_COLUMN_ID, useSelectionContext } from './SelectionContext'\nimport { useCellEditing } from './CellEditingContext'\n\n// Utils\nimport { getCellValue, parseCellId } from '../utils/cellUtils'\n\n// Types\nimport { EntityUpdate } from '../hooks/useUpdateOverview'\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'\n\nconst ClipboardContext = createContext<ClipboardContextType | undefined>(undefined)\n\nexport const ClipboardProvider: React.FC<ClipboardProviderProps> = ({\n children,\n foldersMap,\n tasksMap,\n columnEnums,\n columnReadOnly,\n}) => {\n // Get selection information from SelectionContext\n const { selectedCells, gridMap, focusedCellId } = useSelectionContext()\n const { updateEntities } = useCellEditing()\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 isFolder = foldersMap.has(rowId)\n const entity = isFolder ? foldersMap.get(rowId) : tasksMap.get(rowId)\n\n if (!entity) continue\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(rowId, isFolder, foldersMap, tasksMap)\n }\n\n if (colId === 'subType') {\n // get folderType or taskType\n // @ts-ignore\n cellValue = entity[isFolder ? 'folderType' : 'taskType'] || ''\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, foldersMap, tasksMap],\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) 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 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, foldersMap, tasksMap, 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, foldersMap, tasksMap, 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 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 = foldersMap.has(rowId)\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 entitiesMap = new Map<\n string,\n {\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 isFolder = foldersMap.has(firstRowId)\n const entity = isFolder ? foldersMap.get(firstRowId) : tasksMap.get(firstRowId)\n\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 isFolder = foldersMap.has(rowId)\n const entityType = isFolder ? 'folder' : 'task'\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 (!entitiesMap.has(entityKey)) {\n entitiesMap.set(entityKey, {\n id: rowId,\n type: entityType,\n fields: {},\n attrib: {},\n })\n }\n\n const entityData = entitiesMap.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 entitiesMap.forEach((entity) => {\n // For regular fields, create one update per field\n Object.entries(entity.fields).forEach(([field, value]) => {\n allEntityUpdates.push({\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 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, foldersMap, tasksMap, updateEntities, columnEnums],\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","import React, { createContext, useContext, ReactNode, useMemo } from 'react'\nimport {\n ColumnOrderState,\n ColumnPinningState,\n functionalUpdate,\n OnChangeFn,\n VisibilityState,\n} from '@tanstack/react-table'\n\nexport interface ColumnSettingsContextType {\n // Column Visibility\n columnVisibility: VisibilityState\n setColumnVisibility: (columnVisibility: VisibilityState) => void\n updateColumnVisibility: (columnVisibility: VisibilityState) => void\n columnVisibilityUpdater: OnChangeFn<VisibilityState>\n\n // Column Pinning\n columnPinning: ColumnPinningState\n setColumnPinning: (columnPinning: ColumnPinningState) => void\n updateColumnPinning: (columnPinning: ColumnPinningState) => void\n columnPinningUpdater: OnChangeFn<ColumnPinningState>\n\n // Column Order\n columnOrder: ColumnOrderState\n setColumnOrder: (columnOrder: ColumnOrderState) => void\n updateColumnOrder: (columnOrder: ColumnOrderState) => void\n columnOrderUpdater: OnChangeFn<ColumnOrderState>\n\n // Global change\n setColumnsConfig: (config: ColumnsConfig) => void\n}\n\nconst ColumnSettingsContext = createContext<ColumnSettingsContextType | undefined>(undefined)\n\nexport type ColumnsConfig = {\n columnVisibility: VisibilityState\n columnOrder: ColumnOrderState\n columnPinning: ColumnPinningState\n}\n\ninterface ColumnSettingsProviderProps {\n children: ReactNode\n config: Record<string, any>\n onChange: (config: ColumnsConfig) => void\n}\n\nexport const ColumnSettingsProvider: React.FC<ColumnSettingsProviderProps> = ({\n children,\n config,\n onChange,\n}) => {\n const columnsConfig = config as ColumnsConfig\n const { columnOrder = [], columnPinning = {}, columnVisibility = {} } = columnsConfig\n\n // DIRECT STATE UPDATES - no side effects\n const setColumnVisibility = (visibility: VisibilityState) => {\n onChange({\n ...columnsConfig,\n columnVisibility: visibility,\n })\n }\n\n const setColumnOrder = (order: ColumnOrderState) => {\n onChange({\n ...columnsConfig,\n columnOrder: order,\n })\n }\n\n const setColumnPinning = (pinning: ColumnPinningState) => {\n onChange({\n ...columnsConfig,\n columnPinning: pinning,\n })\n }\n\n // SIDE EFFECT UTILITIES\n const togglePinningOnVisibilityChange = (visibility: VisibilityState) => {\n // ensure that any columns that are now hidden are removed from the pinning\n const newPinning = { ...columnPinning }\n const pinnedColumns = newPinning.left || []\n const hiddenColumns = Object.keys(visibility).filter((col) => visibility[col] === false)\n const newPinnedColumns = pinnedColumns.filter((col) => !hiddenColumns.includes(col))\n\n return {\n ...newPinning,\n left: newPinnedColumns,\n }\n }\n\n const updatePinningOrderOnOrderChange = (order: ColumnOrderState) => {\n // ensure that the column pinning is in the order of the column order\n const newPinning = { ...columnPinning }\n const pinnedColumns = newPinning.left || []\n const pinnedColumnsOrder = order.filter((col) => pinnedColumns.includes(col))\n\n return {\n ...newPinning,\n left: pinnedColumnsOrder,\n }\n }\n\n const updateOrderOnPinningChange = (pinning: ColumnPinningState) => {\n // we resort the column order based on the pinning\n return [...columnOrder].sort((a, b) => {\n const aPinned = pinning.left?.includes(a) ? 1 : 0\n const bPinned = pinning.left?.includes(b) ? 1 : 0\n return bPinned - aPinned\n })\n }\n\n // UPDATE METHODS WITH SIDE EFFECTS\n const updateColumnVisibility = (visibility: VisibilityState) => {\n const newPinning = togglePinningOnVisibilityChange(visibility)\n onChange({\n ...columnsConfig,\n columnVisibility: visibility,\n columnPinning: newPinning,\n })\n }\n\n const updateColumnOrder = (order: ColumnOrderState) => {\n const newPinning = updatePinningOrderOnOrderChange(order)\n onChange({\n ...columnsConfig,\n columnOrder: order,\n columnPinning: newPinning,\n })\n }\n\n const updateColumnPinning = (pinning: ColumnPinningState) => {\n const newOrder = updateOrderOnPinningChange(pinning)\n onChange({\n ...columnsConfig,\n columnOrder: newOrder,\n columnPinning: pinning,\n })\n }\n\n // UPDATER FUNCTIONS\n const columnVisibilityUpdater: OnChangeFn<VisibilityState> = (columnVisibilityUpdater) => {\n const newVisibility = functionalUpdate(columnVisibilityUpdater, columnVisibility)\n updateColumnVisibility(newVisibility)\n }\n\n const columnOrderUpdater: OnChangeFn<ColumnOrderState> = (columnOrderUpdater) => {\n const newOrder = functionalUpdate(columnOrderUpdater, columnOrder)\n updateColumnOrder(newOrder)\n }\n\n const columnPinningUpdater: OnChangeFn<ColumnPinningState> = (columnPinningUpdater) => {\n const newPinning = functionalUpdate(columnPinningUpdater, columnPinning)\n updateColumnPinning(newPinning)\n }\n\n return (\n <ColumnSettingsContext.Provider\n value={{\n // column visibility\n columnVisibility,\n setColumnVisibility,\n updateColumnVisibility,\n columnVisibilityUpdater,\n // column pinning\n columnPinning,\n setColumnPinning,\n updateColumnPinning,\n columnPinningUpdater,\n // column order\n columnOrder,\n setColumnOrder,\n updateColumnOrder,\n columnOrderUpdater,\n // global change\n setColumnsConfig: onChange,\n }}\n >\n {children}\n </ColumnSettingsContext.Provider>\n )\n}\n\nexport const useColumnSettings = (): ColumnSettingsContextType => {\n const context = useContext(ColumnSettingsContext)\n if (!context) {\n throw new Error('useColumnSettings must be used within a ColumnSettingsProvider')\n }\n return context\n}\n","import { createContext, ReactNode, useCallback, useContext, useMemo, useRef } from 'react'\nimport { ROW_SELECTION_COLUMN_ID, useSelectionContext } from './SelectionContext'\nimport { CellId, getCellId, parseCellId, RowId } from '../utils/cellUtils'\n\nexport interface SelectedRowsContextProps {\n selectedRows: string[]\n isRowSelected: (rowId: string) => boolean\n clearRowsSelection: () => void\n selectAllRows: () => void\n areAllRowsSelected: () => boolean\n areSomeRowsSelected: () => boolean\n}\n\nconst SelectedRowsContext = createContext<SelectedRowsContextProps | undefined>(undefined)\n\ninterface SelectedRowsProviderProps {\n children: ReactNode\n}\n\nexport const SelectedRowsProvider = ({ children }: SelectedRowsProviderProps) => {\n const { selectedCells, gridMap, setSelectedCells, setFocusedCellId, setAnchorCell } =\n useSelectionContext()\n const prevSelectedRowsRef = useRef<string[]>([])\n\n // Calculate the current selected rows\n const currentSelectedRows = useMemo(\n () =>\n Array.from(selectedCells)\n .filter(\n (cellId) =>\n parseCellId(cellId)?.colId === ROW_SELECTION_COLUMN_ID && parseCellId(cellId)?.rowId,\n )\n .map((cellId) => parseCellId(cellId)?.rowId) as string[],\n [selectedCells],\n )\n\n // Memoize the selected rows with a stable reference\n const selectedRows = useMemo(() => {\n // Sort for consistent comparison\n const sortedCurrent = [...currentSelectedRows].sort()\n const sortedPrev = [...prevSelectedRowsRef.current].sort()\n\n // Check if the arrays are different\n const hasChanged =\n sortedCurrent.length !== sortedPrev.length ||\n sortedCurrent.some((id, index) => id !== sortedPrev[index])\n\n // Update ref and return new array only if changed\n if (hasChanged) {\n prevSelectedRowsRef.current = currentSelectedRows\n return currentSelectedRows\n }\n\n // Return the previous reference if no change\n return prevSelectedRowsRef.current\n }, [currentSelectedRows])\n\n // Select all rows in the grid\n const selectAllRows = useCallback(() => {\n const allRowIds = Array.from(gridMap.rowIdToIndex.keys())\n const newSelection = new Set<CellId>()\n\n // Create cells for each row with the row selection column ID\n allRowIds.forEach((rowId) => {\n newSelection.add(getCellId(rowId, ROW_SELECTION_COLUMN_ID))\n })\n\n setSelectedCells(newSelection)\n // If there are rows, set focus to the first one\n if (allRowIds.length > 0) {\n const firstCellId = getCellId(allRowIds[0], ROW_SELECTION_COLUMN_ID)\n setFocusedCellId(firstCellId)\n setAnchorCell(parseCellId(firstCellId))\n }\n }, [gridMap])\n\n // clear rows selection\n const clearRowsSelection = useCallback(() => {\n setSelectedCells((prev) => {\n const newSelection = new Set(prev)\n Array.from(newSelection).forEach((cellId) => {\n if (parseCellId(cellId)?.colId === ROW_SELECTION_COLUMN_ID) {\n newSelection.delete(cellId)\n }\n })\n return newSelection\n })\n }, [setSelectedCells])\n\n // check if a row is selected (using selectedRows array)\n const isRowSelected = useCallback(\n (rowId: RowId) => {\n return selectedRows.includes(rowId)\n },\n [selectedRows],\n )\n\n // Check if all rows are selected\n const areAllRowsSelected = useCallback(() => {\n const totalRows = gridMap.rowIdToIndex.size\n return totalRows > 0 && selectedRows.length === totalRows\n }, [gridMap, selectedRows])\n\n // Check if some but not all rows are selected\n const areSomeRowsSelected = useCallback(() => {\n return selectedRows.length > 0 && !areAllRowsSelected()\n }, [selectedRows, areAllRowsSelected])\n\n const value = useMemo(() => {\n return {\n selectedRows,\n selectAllRows,\n clearRowsSelection,\n isRowSelected,\n areAllRowsSelected,\n areSomeRowsSelected,\n }\n }, [selectedRows, selectAllRows, areAllRowsSelected, areSomeRowsSelected, clearRowsSelection])\n\n return <SelectedRowsContext.Provider value={value}>{children}</SelectedRowsContext.Provider>\n}\n\nexport const useSelectedRowsContext = () => {\n const context = useContext(SelectedRowsContext)\n if (!context) {\n throw new Error('useSelectedRowsContext must be used within a SelectedRowsProvider')\n }\n return context\n}\n","import { toast } from 'react-toastify'\nimport { useProjectTableContext } from '../context'\nimport { AttributeData } from '../types'\nimport { EntityUpdate } from './useUpdateOverview'\n\nconst useValidateUpdates = () => {\n const { attribFields } = useProjectTableContext()\n\n const validateUpdateEntities = (entities: EntityUpdate[] = []) => {\n // first validate the values are correct\n for (const { isAttrib, value: rawValue, field } of entities) {\n if (!isAttrib) continue\n const attribute = attribFields.find((attr) => attr.name === field)\n if (!attribute) continue\n\n // coerce numeric strings into numbers for integer/float types or fail\n let value: any = rawValue\n const { type } = attribute.data\n if (type === 'integer' || type === 'float') {\n if (typeof rawValue === 'string') {\n // empty or non‑numeric strings are invalid\n if (rawValue.trim() === '' || isNaN(Number(rawValue))) {\n throw new Error(`“${field}” must be a valid number`)\n }\n value = type === 'integer' ? parseInt(rawValue, 10) : parseFloat(rawValue)\n } else if (typeof rawValue !== 'number') {\n // any other type is invalid\n throw new Error(`“${field}” must be a valid number`)\n }\n }\n\n // collect numeric rules from attribute.data\n const validationKeys: (keyof AttributeData)[] = [\n 'ge',\n 'gt',\n 'le',\n 'lt',\n 'minLength',\n 'maxLength',\n 'minItems',\n 'maxItems',\n ]\n const validationValues = (\n Object.entries(attribute.data) as [keyof AttributeData, any][]\n ).reduce((acc, [key, v]) => {\n if (validationKeys.includes(key)) acc[key] = v as number\n return acc\n }, {} as Record<keyof AttributeData, number>)\n\n const { ge, gt, le, lt, minLength, maxLength, minItems, maxItems } = validationValues\n const pattern = attribute.data.regex\n\n if (typeof value === 'number') {\n if (ge != null && value < ge) throw new Error(`“${field}” must be ≥ ${ge}`)\n if (gt != null && value <= gt) throw new Error(`“${field}” must be > ${gt}`)\n if (le != null && value > le) throw new Error(`“${field}” must be ≤ ${le}`)\n if (lt != null && value >= lt) throw new Error(`“${field}” must be < ${lt}`)\n } else if (typeof value === 'string') {\n if (minLength != null && value.length < minLength)\n throw new Error(`“${field}” length must be ≥ ${minLength}`)\n if (maxLength != null && value.length > maxLength)\n throw new Error(`“${field}” length must be ≤ ${maxLength}`)\n if (pattern && !new RegExp(pattern).test(value))\n throw new Error(`“${field}” must match pattern ${pattern}`)\n } else if (Array.isArray(value)) {\n if (minItems != null && value.length < minItems)\n throw new Error(`“${field}” items must be ≥ ${minItems}`)\n if (maxItems != null && value.length > maxItems)\n throw new Error(`“${field}” items must be ≤ ${maxItems}`)\n }\n }\n }\n\n return validateUpdateEntities\n}\n\nexport default useValidateUpdates\n","import { useState, useCallback } from 'react'\nimport { EntityUpdate, InheritFromParentEntity } from './useUpdateOverview'\n\nexport interface HistoryEntityUpdate extends EntityUpdate {\n ownAttrib: string[]\n folderId?: string\n wasInherited?: boolean\n}\n\ninterface HistoryEntry {\n undo: HistoryEntityUpdate[]\n redo: HistoryEntityUpdate[]\n timestamp: number\n}\n\ntype SplitEntitiesByInherited = [EntityUpdate[], InheritFromParentEntity[]]\n\nexport interface UseHistoryReturn {\n pushHistory: (undo: HistoryEntityUpdate[], redo: HistoryEntityUpdate[]) => void\n undo: () => SplitEntitiesByInherited | null\n redo: () => SplitEntitiesByInherited | null\n canUndo: boolean\n canRedo: boolean\n clearHistory: () => void\n}\n\nconst useHistory = (maxHistorySize = 50): UseHistoryReturn => {\n const [past, setPast] = useState<HistoryEntry[]>([])\n const [future, setFuture] = useState<HistoryEntry[]>([])\n\n const pushHistory: UseHistoryReturn['pushHistory'] = useCallback(\n (undo, redo) => {\n if (!undo.length) return\n setPast((prev) => {\n const updated = [...prev, { undo, redo, timestamp: Date.now() }]\n return updated.length > maxHistorySize\n ? updated.slice(updated.length - maxHistorySize)\n : updated\n })\n setFuture([])\n },\n [maxHistorySize],\n )\n\n // undoing back to inherited uses a different update function\n const splitActionsByInherited = (entities: HistoryEntityUpdate[]): SplitEntitiesByInherited => {\n return entities.reduce(\n (acc, entity) => {\n if (entity.wasInherited && entity.folderId) {\n acc[1].push({\n entityId: entity.id,\n entityType: entity.type,\n folderId: entity.folderId,\n attribs: [entity.field],\n ownAttrib: entity.ownAttrib,\n })\n } else {\n acc[0].push(entity)\n }\n return acc\n },\n [[], []] as SplitEntitiesByInherited,\n )\n }\n\n const undo = useCallback(() => {\n if (past.length === 0) return null\n const newPast = [...past]\n const last = newPast.pop()!\n setPast(newPast)\n setFuture((f) => [...f, last])\n\n return splitActionsByInherited(last.undo)\n }, [past])\n\n const redo = useCallback(() => {\n if (future.length === 0) return null\n const newFuture = [...future]\n const next = newFuture.pop()!\n setFuture(newFuture)\n setPast((p) => [...p, next])\n return splitActionsByInherited(next.redo)\n }, [future])\n\n const clearHistory = useCallback(() => {\n setPast([])\n setFuture([])\n }, [])\n\n return {\n pushHistory,\n undo,\n redo,\n canUndo: past.length > 0,\n canRedo: future.length > 0,\n clearHistory,\n }\n}\n\nexport default useHistory\n","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 useUpdateOverview, {\n InheritFromParent,\n UpdateTableEntities,\n} from '../hooks/useUpdateOverview'\nimport { toast } from 'react-toastify'\nimport useValidateUpdates from '../hooks/useValidateUpdates'\nimport useHistory from '../hooks/useHistory'\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 undo: () => Promise<void>\n redo: () => Promise<void>\n canUndo: boolean\n canRedo: boolean\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 { pushHistory, undo: undoHistory, redo: redoHistory, canUndo, canRedo } = useHistory()\n\n const { updateEntities: updateOverviewEntities, inheritFromParent } = useUpdateOverview({\n pushHistory,\n })\n\n const validateUpdateEntities = useValidateUpdates()\n\n const handleUpdateEntities: UpdateTableEntities = async (entities = [], pushToHistory = true) => {\n try {\n // validate the entities before updating\n validateUpdateEntities(entities)\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\n // Handle undo\n const handleUndo = async () => {\n const [entitiesToUndo, entitiesToInherit] = 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 }\n\n // Handle redo\n const handleRedo = async () => {\n const [entitiesToRedo, entitiesToInherit] = redoHistory() || []\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 }\n\n const value = useMemo(\n () => ({\n editingCellId,\n setEditingCellId,\n isEditing,\n updateEntities: handleUpdateEntities,\n inheritFromParent,\n undo: handleUndo,\n redo: handleRedo,\n canUndo,\n canRedo,\n }),\n [\n editingCellId,\n isEditing,\n handleUpdateEntities,\n inheritFromParent,\n handleUndo,\n handleRedo,\n canUndo,\n canRedo,\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","import { useMemo, memo, useCallback, useRef, FC } from 'react'\nimport styled from 'styled-components'\n\n// Widgets\nimport { BooleanWidget } from './BooleanWidget'\nimport { CollapsedWidget } from './CollapsedWidget'\nimport { DateWidget } from './DateWidget'\nimport { EnumWidget } from './EnumWidget'\nimport { TextWidget, TextWidgetType } from './TextWidget'\n\n// Contexts\nimport { useCellEditing } from '../context/CellEditingContext'\n\n// Utils\nimport { getCellId } from '../utils/cellUtils'\nimport clsx from 'clsx'\nimport { useSelectionContext } from '../context/SelectionContext'\nimport { AttributeData, AttributeEnumItem } from '../types'\n\nconst Cell = styled.div`\n position: absolute;\n inset: 0;\n padding: 4px 8px;\n display: flex;\n align-items: center;\n\n &:focus-visible {\n outline: none;\n }\n\n &.inherited {\n opacity: 0.6;\n font-style: italic;\n }\n\n &.loading {\n inset: 4px;\n border-radius: 4px;\n opacity: 1;\n }\n`\n\ntype WidgetAttributeData = Pick<AttributeData, 'type'>\n\nexport type CellValue = string | number | boolean\n\ninterface EditorCellProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n rowId: string\n columnId: string\n value: CellValue | CellValue[]\n attributeData?: WidgetAttributeData\n options?: AttributeEnumItem[]\n isCollapsed?: boolean\n isInherited?: boolean\n isPlaceholder?: boolean\n isFocused?: boolean\n isReadOnly?: boolean\n enableCustomValues?: boolean\n onChange?: (value: CellValue | CellValue[], key?: 'Enter' | 'Click' | 'Escape') => void\n}\n\nexport interface WidgetBaseProps {\n isEditing?: boolean\n onChange: Required<EditorCellProps>['onChange']\n onCancelEdit?: () => void\n}\n\nconst EditorCellComponent: FC<EditorCellProps> = ({\n rowId,\n columnId,\n value,\n attributeData,\n options = [],\n isCollapsed,\n isInherited,\n isPlaceholder,\n isReadOnly,\n enableCustomValues,\n onChange,\n ...props\n}) => {\n const ref = useRef<HTMLDivElement>(null)\n const type = attributeData?.type\n\n const { isEditing, setEditingCellId } = useCellEditing()\n const { isCellFocused, gridMap, selectCell, focusCell } = useSelectionContext()\n const cellId = getCellId(rowId, columnId)\n\n const isCurrentCellEditing = isEditing(cellId)\n const isCurrentCellFocused = isCellFocused(cellId)\n\n const handleDoubleClick = useCallback(() => {\n if (isPlaceholder || isReadOnly) return\n setEditingCellId(cellId)\n }, [cellId, setEditingCellId, isPlaceholder])\n\n const handleSingleClick = () => {\n // clicking a cell that is not editing will close the editor on this cell\n if (!isCurrentCellEditing) {\n setEditingCellId(null)\n }\n }\n\n const moveToNextRow = () => {\n const rowIndex = gridMap.rowIdToIndex.get(rowId)\n if (rowIndex === undefined) return\n const newRowId = gridMap.indexToRowId.get(rowIndex + 1)\n if (newRowId) {\n const newCellId = getCellId(newRowId, columnId)\n selectCell(newCellId, false, false)\n focusCell(newCellId)\n setEditingCellId(newCellId)\n }\n }\n\n const handleOnChange: WidgetBaseProps['onChange'] = (newValue, key) => {\n setEditingCellId(null)\n if (isReadOnly) return\n // move to the next cell row\n key === 'Enter' && moveToNextRow()\n // make change if the value is different or if the key is 'Enter'\n if (newValue !== value || key === 'Enter') {\n onChange?.(newValue, key)\n }\n }\n\n const handleCancel = () => {\n setEditingCellId(null)\n }\n\n const widget = useMemo(() => {\n // Common props shared across all widgets\n const sharedProps: WidgetBaseProps = {\n onChange: handleOnChange,\n onCancelEdit: handleCancel,\n isEditing: isCurrentCellEditing,\n }\n\n const textTypes: TextWidgetType[] = ['string', 'integer', 'float']\n\n // Determine widget type based on attribute type\n switch (true) {\n // this is showing the collapsed widget (dot)\n case isCollapsed: {\n // if enum, find the first selected option and get its color\n const firstSelectedOption = type?.includes('list')\n ? options.find((option) =>\n Array.isArray(value) ? value.includes(option.value) : value === option.value,\n )\n : undefined\n const color = firstSelectedOption?.color\n return <CollapsedWidget color={color} />\n }\n\n case !!options.length: {\n const enumValue = Array.isArray(value) ? value : [value]\n return (\n <EnumWidget\n value={enumValue}\n options={options}\n type={type}\n onOpen={() => !isReadOnly && setEditingCellId(cellId)}\n enableCustomValues={enableCustomValues}\n {...sharedProps}\n />\n )\n }\n\n case textTypes.includes(type as TextWidgetType):\n return <TextWidget value={value as string} isInherited={isInherited} {...sharedProps} />\n\n case type === 'datetime' && value !== null && value !== undefined:\n return <DateWidget value={value as string} isInherited={isInherited} {...sharedProps} />\n\n case type === 'boolean':\n return <BooleanWidget value={value as boolean} {...sharedProps} />\n\n case isPlaceholder:\n return null\n\n default:\n // if the type is not recognized, fall back to the TextWidget\n return <TextWidget value={value as string} {...sharedProps} />\n }\n }, [cellId, value, type, isCurrentCellEditing, options, isCollapsed])\n\n return (\n <Cell\n {...props}\n className={clsx(props.className, { inherited: isInherited && !isCurrentCellEditing })}\n ref={ref}\n onDoubleClick={handleDoubleClick}\n onClick={handleSingleClick}\n id={cellId}\n data-tooltip={\n isInherited && !isCurrentCellEditing && isCurrentCellFocused ? 'Inherited' : undefined\n }\n data-tooltip-delay={200}\n >\n {widget}\n </Cell>\n )\n}\n\n// Custom comparison function for memo\nfunction arePropsEqual(prevProps: EditorCellProps, nextProps: EditorCellProps) {\n // Only re-render if these props change\n return (\n prevProps.rowId === nextProps.rowId &&\n prevProps.columnId === nextProps.columnId &&\n prevProps.isCollapsed === nextProps.isCollapsed &&\n JSON.stringify(prevProps.value) === JSON.stringify(nextProps.value) &&\n prevProps?.attributeData?.type === nextProps?.attributeData?.type &&\n // Only check options length for list types to avoid deep comparison\n ((!prevProps?.attributeData?.type.includes('list') &&\n !nextProps?.attributeData?.type.includes('list')) ||\n prevProps.options?.length === nextProps.options?.length) &&\n prevProps.isInherited === nextProps.isInherited &&\n prevProps.enableCustomValues === nextProps.enableCustomValues &&\n prevProps.isReadOnly === nextProps.isReadOnly &&\n prevProps.isPlaceholder === nextProps.isPlaceholder &&\n prevProps.isFocused === nextProps.isFocused &&\n prevProps.isCollapsed === nextProps.isCollapsed\n )\n}\n\nexport const CellWidget = memo(EditorCellComponent, arePropsEqual)\n","import { Button, Icon, theme } from '@ynput/ayon-react-components'\nimport styled from 'styled-components'\n\nconst Expander = styled(Button)`\n background-color: unset;\n padding: 2px !important;\n cursor: pointer;\n`\n\nconst StyledEntityNameWidget = styled.div`\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--base-gap-small);\n height: 100%;\n width: 100%;\n padding-right: 8px;\n`\n\nconst StyledContentWrapper = styled.div`\n width: 100%;\n height: 24px;\n overflow: hidden;\n position: relative;\n`\n\nconst StyledContentAbsolute = styled.div`\n position: absolute;\n inset: 0;\n`\n\nconst StyledContent = styled.div`\n display: flex;\n align-items: center;\n gap: var(--base-gap-large);\n padding: 2px 4px;\n border-radius: var(--border-radius-m);\n cursor: pointer;\n overflow: hidden;\n width: fit-content;\n max-width: 100%;\n height: 100%;\n\n /* &:hover {\n &,\n .icon,\n .path {\n color: var(--md-sys-color-primary);\n }\n } */\n`\n\nconst StyledTextContent = styled.div`\n display: flex;\n flex-direction: column;\n overflow: hidden;\n\n .path {\n ${theme.labelSmall}\n margin-bottom: -4px;\n color: var(--md-sys-color-outline);\n }\n\n span {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n`\n\ntype EntityNameWidgetProps = {\n id: string\n label: string\n name: string\n path?: string | null\n showHierarchy?: boolean\n icon: string | null\n type: string\n isExpanded: boolean\n toggleExpandAll: (id: string) => void\n toggleExpanded: () => void\n}\n\nexport const EntityNameWidget = ({\n id,\n label,\n name,\n path,\n showHierarchy,\n icon,\n type,\n isExpanded,\n toggleExpandAll,\n toggleExpanded,\n}: EntityNameWidgetProps) => {\n return (\n <StyledEntityNameWidget>\n {showHierarchy ? (\n type === 'folder' ? (\n <Expander\n onClick={(e) => {\n e.stopPropagation()\n if (e.altKey) {\n // expand/collapse all children\n toggleExpandAll(id)\n } else {\n // use built-in toggleExpanded function\n toggleExpanded()\n }\n }}\n className=\"expander\"\n icon={isExpanded ? 'expand_more' : 'chevron_right'}\n />\n ) : (\n <div style={{ display: 'inline-block', minWidth: 24 }} />\n )\n ) : null}\n <StyledContentWrapper style={{ height: path ? 32 : 24 }}>\n <StyledContentAbsolute>\n <StyledContent>\n {icon && <Icon icon={icon} />}\n <StyledTextContent>\n {path && <span className=\"path\">{path}</span>}\n <span className=\"label\">{label || name}</span>\n </StyledTextContent>\n </StyledContent>\n </StyledContentAbsolute>\n </StyledContentWrapper>\n </StyledEntityNameWidget>\n )\n}\n","import styled from 'styled-components'\n\n// Create shadow mixins to make combinations work properly\nconst topShadow = `inset 0 1px 0 0 var(--md-sys-color-primary)`\nconst rightShadow = `inset -1px 0 0 0 var(--md-sys-color-primary)`\nconst bottomShadow = `inset 0 -1px 0 0 var(--md-sys-color-primary)`\nconst leftShadow = `inset 1px 0 0 0 var(--md-sys-color-primary)`\n\nconst getDefaultShadow = (isLastPinned: boolean) => {\n const defaultShadow = `inset 1px -1px 0 0 var(--md-sys-color-surface-container)`\n const defaultShadowLastPinned = `inset -2px -1px 0 0 var(--md-sys-color-surface-container), inset 1px 0 0 0 var(--md-sys-color-surface-container)`\n return isLastPinned ? defaultShadowLastPinned : defaultShadow\n}\n\nexport const TR = styled.tr`\n display: flex;\n position: absolute;\n width: 100%;\n`\n\nconst cellMinWidth = 50\n\nexport const TableCellContent = styled.div`\n display: flex;\n align-items: center;\n gap: var(--base-gap-small);\n height: 100%;\n width: 100%;\n padding: 0px 8px;\n border-radius: var(--border-radius-m);\n user-select: none;\n padding-right: 0;\n\n min-width: ${cellMinWidth}px;\n &.bold {\n font-weight: 600;\n }\n\n &.loading {\n margin: 0px 5px;\n padding: 0 !important;\n width: calc(100% - 10px);\n height: 28px;\n margin-top: 3px;\n\n &:not(.hierarchy) {\n height: 32px;\n }\n }\n\n &:focus-visible {\n outline: none;\n }\n`\n\nexport const ResizedHandler = styled.div`\n position: absolute;\n right: -1px;\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: col-resize;\n background-color: var(--md-sys-color-surface-container-high);\n\n opacity: 0;\n\n &.resizing {\n background-color: var(--md-sys-color-primary);\n opacity: 1;\n }\n`\n\nexport const ColumnHeader = styled.tr`\n background-color: var(--md-sys-color-surface-container-low);\n`\n\nexport const HeaderCell = styled.th`\n position: relative;\n background-color: var(--md-sys-color-surface-container-lowest);\n box-shadow: inset 1px -1px 0 0 var(--md-sys-color-surface-container);\n display: flex;\n align-items: center;\n min-height: fit-content;\n min-width: ${cellMinWidth}px;\n &.large {\n min-width: 300px;\n }\n &:hover {\n .resize-handle {\n opacity: 1;\n }\n }\n\n /* show action button */\n &:hover {\n .action {\n display: flex;\n }\n }\n\n /* Styling for the last pinned left column */\n &.last-pinned-left {\n box-shadow: inset 1px -1px 0 0 var(--md-sys-color-surface-container),\n inset -2px 0 0 0 var(--md-sys-color-surface-container);\n }\n\n /* special styles for the left selection column */\n &.__row_selection__ {\n min-width: unset;\n width: 20px !important;\n\n .actions {\n display: none;\n }\n }\n`\n\nexport const HeaderButtons = styled.div`\n display: flex;\n gap: var(--base-gap-small);\n\n position: absolute;\n z-index: 10;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n`\n\ntype TableCellProps = {\n $isLastPinned?: boolean\n}\n\nexport const TableCell = styled.td<TableCellProps>`\n position: relative;\n box-shadow: ${getDefaultShadow(false)};\n min-width: ${cellMinWidth}px;\n background-color: var(--md-sys-color-surface-container-low);\n\n &.task {\n background-color: hsl(216 15% 11.5% / 1);\n }\n\n &.selected-row {\n background-color: var(--md-sys-color-surface-container-high);\n }\n\n &.selected {\n background-color: var(--md-sys-color-secondary-container);\n position: relative;\n z-index: 1;\n }\n\n /* remove default focus style */\n &:focus-visible {\n outline: none;\n }\n\n /* Styling for the last pinned left column */\n /* extra border on the right */\n &.last-pinned-left {\n box-shadow: inset 1px -1px 0 0 var(--md-sys-color-surface-container),\n inset -2px 0 0 0 var(--md-sys-color-surface-container);\n }\n\n /* Shadow combinations - single side */\n &.shadow-top:not(.shadow-right):not(.shadow-bottom):not(.shadow-left) {\n box-shadow: ${topShadow}, ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n &.shadow-right:not(.shadow-top):not(.shadow-bottom):not(.shadow-left) {\n box-shadow: ${rightShadow}, ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n &.shadow-bottom:not(.shadow-top):not(.shadow-right):not(.shadow-left) {\n box-shadow: ${bottomShadow}, ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n &.shadow-left:not(.shadow-top):not(.shadow-right):not(.shadow-bottom) {\n box-shadow: ${leftShadow}, ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n /* Two sides */\n &.shadow-top.shadow-right:not(.shadow-bottom):not(.shadow-left) {\n box-shadow: ${topShadow}, ${rightShadow},\n ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n &.shadow-top.shadow-bottom:not(.shadow-right):not(.shadow-left) {\n box-shadow: ${topShadow}, ${bottomShadow},\n ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n &.shadow-top.shadow-left:not(.shadow-right):not(.shadow-bottom) {\n box-shadow: ${topShadow}, ${leftShadow},\n ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n &.shadow-right.shadow-bottom:not(.shadow-top):not(.shadow-left) {\n box-shadow: ${rightShadow}, ${bottomShadow},\n ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n &.shadow-right.shadow-left:not(.shadow-top):not(.shadow-bottom) {\n box-shadow: ${rightShadow}, ${leftShadow},\n ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n &.shadow-bottom.shadow-left:not(.shadow-top):not(.shadow-right) {\n box-shadow: ${bottomShadow}, ${leftShadow},\n ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n /* Three sides */\n &.shadow-top.shadow-right.shadow-bottom:not(.shadow-left) {\n box-shadow: ${topShadow}, ${rightShadow}, ${bottomShadow},\n ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n &.shadow-top.shadow-right.shadow-left:not(.shadow-bottom) {\n box-shadow: ${topShadow}, ${rightShadow}, ${leftShadow},\n ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n &.shadow-top.shadow-bottom.shadow-left:not(.shadow-right) {\n box-shadow: ${topShadow}, ${bottomShadow}, ${leftShadow},\n ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n &.shadow-right.shadow-bottom.shadow-left:not(.shadow-top) {\n box-shadow: ${rightShadow}, ${bottomShadow}, ${leftShadow},\n ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n /* All four sides */\n &.shadow-top.shadow-right.shadow-bottom.shadow-left {\n box-shadow: ${topShadow}, ${rightShadow}, ${bottomShadow}, ${leftShadow},\n ${({ $isLastPinned }) => getDefaultShadow($isLastPinned || false)};\n }\n\n /* Focus styling */\n &.focused {\n position: relative;\n z-index: 2;\n }\n\n /* Use pseudo-element for focused outline to avoid box-shadow conflicts */\n &.focused::after {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid var(--md-sys-color-primary);\n pointer-events: none;\n }\n\n &.editing {\n z-index: 10 !important;\n /* light border around the outside */\n &::before {\n content: '';\n position: absolute;\n inset: 2px;\n border: 2px solid var(--md-sys-color-surface-container-low);\n }\n }\n\n /* special styles for selection bar cells */\n &.__row_selection__ {\n width: 20px !important;\n min-width: unset;\n\n &.selected {\n background-color: var(--md-sys-color-primary-container) !important;\n box-shadow: none !important;\n /* reveal the check mark */\n [icon='check'] {\n display: block;\n }\n }\n }\n`\n\nexport const TableHeader = styled.thead`\n display: grid !important;\n position: sticky;\n top: 0;\n min-height: 34px;\n z-index: 10;\n background-color: var(--md-sys-color-surface-container-lowest);\n`\n\nexport const TableWrapper = styled.div`\n overflow: hidden;\n position: absolute;\n inset: 0;\n border-radius: var(--border-radius-m);\n\n background-color: var(--md-sys-color-surface-container-low);\n`\n\nexport const TableContainer = styled.div`\n display: flex;\n\n height: 100%;\n width: 100%;\n overflow: auto;\n padding: 4px;\n padding-top: 0;\n\n &.isLoading {\n overflow: hidden;\n }\n\n table {\n height: fit-content;\n width: 100%;\n display: grid;\n }\n\n thead {\n display: none;\n }\n\n tbody {\n position: relative;\n display: grid;\n }\n\n td {\n height: 34px;\n padding: 1px 0px;\n width: 100%;\n }\n`\n","import { Icon } from '@ynput/ayon-react-components'\nimport { forwardRef } from 'react'\nimport styled from 'styled-components'\n\nconst StyledSelectionCell = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n /* This is super important as it prevents onMouseOver incorrectly firing when Icon is added/removed */\n pointer-events: none;\n height: 100%;\n\n /* default hidden. Shown with styles in ProjectTreeTable.styled */\n [icon='check'] {\n display: none;\n }\n`\n\ninterface SelectionCellProps extends React.HTMLAttributes<HTMLDivElement> {\n isSelected?: boolean\n}\n\nexport const SelectionCell = forwardRef<HTMLDivElement, SelectionCellProps>(\n ({ isSelected, ...props }, ref) => {\n return (\n <StyledSelectionCell {...props} ref={ref}>\n <Icon icon=\"check\" />\n </StyledSelectionCell>\n )\n },\n)\n","import React, { memo } from 'react'\nimport styled from 'styled-components'\nimport { Icon } from '@ynput/ayon-react-components'\nimport { useSelectedRowsContext } from '../context/SelectedRowsContext'\n\nconst SelectionHeaderCell = styled.div`\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n\n &:hover {\n background-color: var(--md-sys-color-surface-container-high);\n }\n`\n\nconst RowSelectionHeader: React.FC = () => {\n const { areAllRowsSelected, areSomeRowsSelected, selectAllRows, clearRowsSelection } =\n useSelectedRowsContext()\n\n const allSelected = areAllRowsSelected()\n const someSelected = areSomeRowsSelected()\n\n const handleClick = () => {\n if (allSelected || someSelected) {\n // If all or some rows are selected, clear selection\n clearRowsSelection()\n } else {\n // Otherwise select all rows\n selectAllRows()\n }\n }\n\n return (\n <SelectionHeaderCell onClick={handleClick}>\n {allSelected ? (\n // Show double check mark when all rows are selected\n <Icon icon=\"done_all\" />\n ) : someSelected ? (\n // Show minimize icon when some (but not all) rows are selected\n <Icon icon=\"remove\" />\n ) : // Show nothing when no rows are selected\n null}\n </SelectionHeaderCell>\n )\n}\n\nexport default memo(RowSelectionHeader)\n","import { useMemo } from 'react'\nimport {\n ColumnDef,\n ColumnSizingState,\n FilterFnOption,\n Row,\n SortingFn,\n sortingFns,\n} from '@tanstack/react-table'\nimport { TableRow } from './types/table'\nimport { AttributeData, AttributeWithPermissions, BuiltInFieldOptions } from './types'\nimport { CellWidget, EntityNameWidget } from './widgets'\nimport { useCellEditing } from './context/CellEditingContext'\nimport { getCellId, getCellValue } from './utils/cellUtils'\nimport { TableCellContent } from './ProjectTreeTable.styled'\nimport clsx from 'clsx'\nimport { SelectionCell } from './components/SelectionCell'\nimport RowSelectionHeader from './components/RowSelectionHeader'\nimport { ROW_SELECTION_COLUMN_ID } from './context/SelectionContext'\n\n// Wrapper function for sorting that pushes isLoading rows to the bottom\nconst withLoadingStateSort = (sortFn: SortingFn<any>): SortingFn<any> => {\n return (rowA, rowB, ...args) => {\n // If row loading states differ, prioritize non-loading rows\n if (rowA.original.isLoading !== rowB.original.isLoading) {\n return rowA.original.isLoading ? 1 : -1\n }\n // Otherwise, use the original sort function\n return sortFn(rowA, rowB, ...args)\n }\n}\n\nconst nameSort: SortingFn<any> = (rowA, rowB) => {\n const labelA = rowA.original.label || rowA.original.name\n const labelB = rowB.original.label || rowB.original.name\n // sort alphabetically by label\n return labelA.localeCompare(labelB)\n}\nconst pathSort: SortingFn<any> = (rowA, rowB) => {\n const labelA = rowA.original.path || rowA.original.name\n const labelB = rowB.original.path || rowB.original.name\n // sort alphabetically by label\n return labelA.localeCompare(labelB)\n}\n\ntype AttribSortingFn = (rowA: any, rowB: any, columnId: string, attribute?: AttributeData) => number\n// sort by the order of the enum options\nconst attribSort: AttribSortingFn = (rowA, rowB, columnId, attrib) => {\n const valueA = getCellValue(rowA.original, columnId)\n const valueB = getCellValue(rowB.original, columnId)\n // if attrib is defined and has enum options, use them\n if (attrib && attrib.enum) {\n const indexA = attrib.enum.findIndex((o) => o.value === valueA)\n const indexB = attrib.enum.findIndex((o) => o.value === valueB)\n return indexA - indexB < 0 ? 1 : -1\n } else if (attrib?.type === 'datetime') {\n return sortingFns.datetime(rowA, rowB, columnId)\n } else if (attrib?.type === 'boolean') {\n const boolA = valueA === true ? 1 : 0\n const boolB = valueB === true ? 1 : 0\n return boolA - boolB\n } else {\n // default sorting\n return sortingFns.alphanumeric(rowA, rowB, columnId)\n }\n}\n\ntype Props = {\n tableData: TableRow[]\n attribs: AttributeWithPermissions[]\n columnSizing: ColumnSizingState\n isLoading: boolean\n showHierarchy: boolean\n sliceId: string\n options: BuiltInFieldOptions\n toggleExpandAll: (id: string) => void\n toggleExpanded: (id: string) => void\n}\n\nconst ProjectTreeTableColumns = ({\n tableData,\n attribs,\n columnSizing = {},\n showHierarchy,\n isLoading,\n sliceId,\n options,\n toggleExpandAll,\n toggleExpanded,\n}: Props) => {\n const { updateEntities } = useCellEditing()\n\n return useMemo<ColumnDef<TableRow, any>[]>(() => {\n const staticColumns: ColumnDef<TableRow>[] = [\n {\n id: ROW_SELECTION_COLUMN_ID,\n header: () => <RowSelectionHeader />,\n cell: () => <SelectionCell />,\n size: 20,\n },\n {\n accessorKey: 'name',\n header: () => 'Folder / Task',\n sortingFn: withLoadingStateSort(showHierarchy ? nameSort : pathSort),\n cell: ({ row, column }) => {\n const cellId = getCellId(row.id, column.id)\n return (\n <TableCellContent\n id={cellId}\n className={clsx('large', row.original.entityType, {\n loading: row.original.isLoading,\n hierarchy: showHierarchy,\n })}\n style={{\n paddingLeft: `calc(${row.depth * 1}rem + 8px)`,\n }}\n tabIndex={0}\n >\n <EntityNameWidget\n id={row.id}\n label={row.original.label}\n name={row.original.name}\n path={!showHierarchy ? row.original.path : undefined}\n showHierarchy={showHierarchy}\n icon={row.original.icon}\n type={row.original.entityType}\n isExpanded={row.getIsExpanded()}\n toggleExpandAll={toggleExpandAll}\n toggleExpanded={() => toggleExpanded(row.id)}\n />\n </TableCellContent>\n )\n },\n },\n {\n accessorKey: 'status',\n header: () => 'Status',\n sortingFn: withLoadingStateSort((a, b, c) =>\n attribSort(a, b, c, { enum: options.statuses, type: 'string' }),\n ),\n sortDescFirst: true,\n size: columnSizing['status'] || 150,\n cell: ({ row, column }) => {\n const { value, id, type } = getValueIdType(row, column.id)\n\n return (\n <CellWidget\n rowId={id}\n className={clsx('status', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: 'string' }}\n options={options.statuses.filter((s) => s.scope?.includes(type))}\n isCollapsed={!!row.original.childOnlyMatch}\n onChange={(value) => updateEntities([{ field: column.id, value, id, type }])}\n />\n )\n },\n },\n {\n accessorKey: 'subType',\n header: () => 'Type',\n size: columnSizing['type'] || 150,\n cell: ({ row, column }) => {\n const { value, id, type } = getValueIdType(row, column.id)\n const fieldId = type === 'folder' ? 'folderType' : 'taskType'\n return (\n <CellWidget\n rowId={id}\n className={clsx('subType', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: 'string' }}\n options={type === 'folder' ? options.folderTypes : options.taskTypes}\n isCollapsed={!!row.original.childOnlyMatch}\n onChange={(value) => updateEntities([{ field: fieldId, value, id, type }])}\n />\n )\n },\n },\n {\n accessorKey: 'assignees',\n header: () => 'Assignees',\n size: columnSizing['assignees'] || 150,\n cell: ({ row, column }) => {\n const { value, id, type } = getValueIdType(row, column.id)\n if (type === 'folder')\n return (\n <CellWidget\n rowId={id}\n className={clsx('assignees', { loading: row.original.isLoading })}\n columnId={column.id}\n value=\"\"\n isPlaceholder\n />\n )\n return (\n <CellWidget\n rowId={id}\n className={clsx('assignees', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: 'list_of_strings' }}\n options={options.assignees}\n isCollapsed={!!row.original.childOnlyMatch}\n onChange={(value) => updateEntities([{ field: column.id, value, id, type }])}\n />\n )\n },\n },\n {\n accessorKey: 'tags',\n header: () => 'Tags',\n size: columnSizing['tags'] || 150,\n cell: ({ row, column }) => {\n const { value, id, type } = getValueIdType(row, column.id)\n return (\n <CellWidget\n rowId={id}\n className={clsx('tags', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: 'list_of_strings' }}\n options={options.tags}\n isCollapsed={!!row.original.childOnlyMatch}\n onChange={(value) => updateEntities([{ field: column.id, value, id, type }])}\n enableCustomValues\n />\n )\n },\n },\n ]\n\n const attributeColumns = attribs.map((attrib) => {\n const attribColumn: ColumnDef<TableRow> = {\n accessorKey: 'attrib.' + attrib.name,\n header: () => attrib.data.title || attrib.name,\n filterFn: 'fuzzy' as FilterFnOption<TableRow>,\n sortingFn: withLoadingStateSort((a, b, c) => attribSort(a, b, c, attrib.data)),\n cell: ({ row, column }) => {\n const columnIdParsed = column.id.replace('attrib_', '')\n const { value, id, type } = getValueIdType(row, columnIdParsed, 'attrib')\n const isInherited = !row.original.ownAttrib.includes(columnIdParsed)\n\n return (\n <CellWidget\n rowId={id}\n className={clsx('attrib', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: attrib.data.type || 'string' }}\n options={attrib.data.enum || []}\n isCollapsed={!!row.original.childOnlyMatch}\n isInherited={isInherited}\n isReadOnly={attrib.readOnly}\n onChange={(value) =>\n updateEntities([{ field: columnIdParsed, value, id, type, isAttrib: true }])\n }\n />\n )\n },\n }\n return attribColumn\n })\n\n return [...staticColumns, ...attributeColumns]\n }, [isLoading, sliceId, tableData, options, attribs, showHierarchy, updateEntities])\n}\n\nexport default ProjectTreeTableColumns\n\nconst getValueIdType = (\n row: Row<TableRow>,\n field: string,\n nestedField?: keyof TableRow,\n): {\n value: any\n id: string\n type: string\n} => ({\n value: nestedField\n ? (row.original[nestedField as keyof TableRow] as any)?.[field]\n : (row.original[field as keyof TableRow] as any),\n id: row.id,\n type: row.original.entityType,\n})\n","import { Button, ButtonProps } from '@ynput/ayon-react-components'\nimport clsx from 'clsx'\nimport { FC } from 'react'\nimport styled from 'styled-components'\n\nconst ActionButton = styled(Button)`\n padding: 0px !important;\n display: none;\n background-color: var(--md-sys-color-surface-container-lowest);\n\n &.selected {\n display: flex;\n }\n`\n\ninterface HeaderActionButtonProps extends ButtonProps {}\n\nconst HeaderActionButton: FC<HeaderActionButtonProps> = ({ selected, style, ...props }) => {\n return (\n <ActionButton\n {...props}\n selected={selected}\n className={clsx(props.className, 'action', { selected })}\n variant=\"text\"\n style={{ ...style }}\n />\n )\n}\n\nexport default HeaderActionButton\n","import { ColumnSizingState, Table } from '@tanstack/react-table'\nimport { useMemo } from 'react'\nimport { TableRow } from '../types/table'\n\n// convert column sizing state to CSS variables\nconst useCustomColumnWidthVars = (table: Table<TableRow>, columnSizing: ColumnSizingState) => {\n const headers = table.getFlatHeaders()\n const columnSizingInfo = table.getState().columnSizingInfo\n\n const columnSizeVars = useMemo(() => {\n const colSizes: { [key: string]: number } = {}\n for (let i = 0; i < headers.length; i++) {\n const header = headers[i]!\n colSizes[`--header-${header.id}-size`] = header.getSize()\n colSizes[`--col-${header.column.id}-size`] = header.column.getSize()\n }\n return colSizes\n }, [columnSizingInfo, columnSizing, headers])\n\n return columnSizeVars\n}\n\nexport default useCustomColumnWidthVars\n","import { useState } from 'react'\nimport { parseCellId } from '../utils/cellUtils'\nimport { useProjectTableQueriesContext } from '../context/ProjectTableQueriesContext'\nimport { useProjectTableContext } from '../context/ProjectTableContext'\n\nexport const usePrefetchFolderTasks = () => {\n const { getFoldersTasks } = useProjectTableQueriesContext()\n\n const [prefetchedIds, setPrefetchedIds] = useState<string[]>([])\n\n const { projectName, queryFilters } = useProjectTableContext()\n\n const handlePreFetchTasks = (e: React.MouseEvent<HTMLTableSectionElement>) => {\n const target = e.target as HTMLTableCellElement\n // hovering the expander and td?\n const td = target.closest('td')\n if (!target.closest('.expander') || !td) return\n // first div child of td id\n const cell = td.firstElementChild as HTMLDivElement\n const cellId = cell?.id\n if (!cellId) return\n // cell colId is name\n const { colId, rowId } = parseCellId(cellId) || {}\n if (colId !== 'name' || !rowId) return\n // check if the cell is a folder (classname contains folder)\n const isFolder = cell.className.includes('folder')\n if (!isFolder) return\n\n // check if the rowId is already in the prefetchedIds\n if (prefetchedIds.includes(rowId)) return\n setPrefetchedIds((prev) => [...prev, rowId])\n\n getFoldersTasks(\n {\n parentIds: [rowId],\n filter: queryFilters.filterString,\n search: queryFilters.search,\n },\n true,\n )\n }\n\n return { handlePreFetchTasks }\n}\n\nexport default usePrefetchFolderTasks\n","import { useCallback } from 'react'\nimport { useProjectTableQueriesContext } from '../context/ProjectTableQueriesContext'\nimport { parseCellId } from '../utils/cellUtils'\n// TODO: confirmDelete uses prime react, so we should find a different solution\nimport { confirmDelete } from '../../../util'\nimport { useProjectTableContext } from '../context/ProjectTableContext'\nimport { OperationModel } from '../types/operations'\n\ntype UseDeleteEntitiesProps = {\n onSuccess?: () => void\n}\n\nconst useDeleteEntities = ({ onSuccess }: UseDeleteEntitiesProps) => {\n const { updateEntities } = useProjectTableQueriesContext()\n\n const { getEntityById } = useProjectTableContext()\n\n const handleDeleteEntities = useCallback(\n async (entityIds: string[]) => {\n if (!entityIds || entityIds.length === 0) {\n return\n }\n\n const fullEntities = entityIds\n .map((id) => getEntityById(parseCellId(id)?.rowId || ''))\n .filter(Boolean)\n\n if (fullEntities.length === 0) return\n\n const deleteEntities = async (force = false) => {\n const operations: OperationModel[] = []\n for (const e of fullEntities) {\n if (!e) continue\n operations.push({\n entityType: 'folderId' in e ? 'task' : 'folder',\n type: 'delete',\n entityId: e.id,\n force,\n })\n }\n try {\n await updateEntities?.({ operations })\n if (onSuccess) {\n onSuccess()\n }\n } catch (error: any) {\n const message = error?.error || 'Failed to delete entities'\n console.error(`Failed to delete entities:`, error)\n throw { message, ...error }\n }\n }\n\n confirmDelete({\n label: 'folders and tasks',\n message: `Are you sure you want to delete ${entityIds.length} entities? This action cannot be undone.`,\n accept: deleteEntities,\n onError: (error: any) => {\n const FOLDER_WITH_CHILDREN_CODE = 'delete-folder-with-children'\n // check if the error is because of child tasks, products\n if (error?.errorCodes?.includes(FOLDER_WITH_CHILDREN_CODE)) {\n // try again but with force\n confirmDelete({\n label: 'folders and tasks',\n message: `This folder has child tasks or products that will also be deleted. Are you sure you want to delete ${entityIds.length} entities and all of it's dependencies?`,\n accept: () => deleteEntities(true),\n deleteLabel: 'Delete all (dangerous)',\n })\n }\n },\n deleteLabel: 'Delete forever',\n })\n },\n [getEntityById, updateEntities, onSuccess],\n )\n\n return handleDeleteEntities\n}\n\nexport default useDeleteEntities\n","import { useCreateContextMenu } from '../../ContextMenu/useCreateContextMenu'\nimport useDeleteEntities from './useDeleteEntities'\nimport { getPlatformShortcutKey, KeyMode } from '../../../util/platform'\nimport { getCellId, parseCellId } from '../utils/cellUtils'\nimport { useClipboard } from '../context/ClipboardContext'\nimport { ROW_SELECTION_COLUMN_ID, useSelectionContext } from '../context/SelectionContext'\nimport { useProjectTableContext } from '../context/ProjectTableContext'\nimport { useCellEditing } from '../context/CellEditingContext'\nimport { InheritFromParentEntity } from './useUpdateOverview'\nimport { AttributeWithPermissions } from '../types'\n\ntype ContextEvent = React.MouseEvent<HTMLTableSectionElement, MouseEvent>\n\ntype CellContextMenuProps = {\n attribs: AttributeWithPermissions[]\n onOpenNew?: (type: 'folder' | 'task') => void\n}\n\nconst useCellContextMenu = ({ attribs, onOpenNew }: CellContextMenuProps) => {\n // context hooks\n const { projectName, showHierarchy, getEntityById, toggleExpandAll } = useProjectTableContext()\n const { copyToClipboard, exportCSV, pasteFromClipboard } = useClipboard()\n const { isCellSelected, selectedCells, clearSelection, selectCell } = useSelectionContext()\n const { inheritFromParent } = useCellEditing()\n\n // update entity context\n\n // data mutations\n const deleteEntities = useDeleteEntities({})\n\n const [cellContextMenuShow] = useCreateContextMenu()\n\n const cellContextMenuItems = (_e: ContextEvent, id: string, selected: string[]) => {\n // Define menu item type with condition\n type MenuItem = {\n label: string\n icon: string\n shortcut?: string\n danger?: boolean\n command: () => void\n shouldShow: boolean\n disabled?: boolean\n }\n\n // Parse cell info\n const { rowId: entityId, colId } = parseCellId(id) || {}\n // get full attrib details\n const attrib = attribs.find((attrib) => attrib.name === colId?.replace('attrib_', ''))\n\n if (!entityId)\n return [\n {\n label: 'Copy',\n icon: 'content_copy',\n shortcut: getPlatformShortcutKey('c', [KeyMode.Ctrl]),\n command: () => copyToClipboard(selected),\n shouldShow: true,\n },\n ]\n\n // Define conditions\n const isNameColumn = colId === 'name'\n const isSingleSelection = selected.length === 1\n const entitiesToInherit = getEntitiesToInherit(selected)\n\n // from the selected cells, get the rows they are selected in\n const selectedCellRows = new Set<string>()\n const selectedCellColumns = new Set<string>()\n\n for (const cellId of selected) {\n const parsed = parseCellId(cellId)\n if (parsed) {\n if (parsed.rowId) selectedCellRows.add(parsed.rowId)\n if (parsed.colId) selectedCellColumns.add(parsed.colId)\n }\n }\n\n const selectedCellRowsArray = Array.from(selectedCellRows)\n // get selected rows ids\n const selectedRowCells = Array.from(selectedCells).filter(\n (cellId) => parseCellId(cellId)?.colId === ROW_SELECTION_COLUMN_ID,\n )\n // is the selection a grid (multiple rows and columns)\n const isMultipleRows = selectedCellRows.size > 1\n const isMultipleColumns = selectedCellColumns.size > 1\n const isGridSelection = isMultipleRows && isMultipleColumns\n\n const canInheritFromParent = entitiesToInherit.length > 0 && showHierarchy && !isGridSelection\n\n // Define all possible menu items with their conditions\n const allMenuItems: MenuItem[] = [\n // Clipboard operations\n {\n label: 'Copy',\n icon: 'content_copy',\n shortcut: getPlatformShortcutKey('c', [KeyMode.Ctrl]),\n command: () => copyToClipboard(selected),\n shouldShow: true, // Always shown\n },\n {\n label: `Copy row${selectedRowCells.length > 1 ? 's' : ''}`,\n icon: 'content_copy',\n command: () => copyToClipboard(selectedRowCells, true),\n shouldShow:\n isNameColumn &&\n selectedRowCells.some((cellId) => parseCellId(cellId)?.rowId === parseCellId(id)?.rowId),\n },\n {\n label: 'Paste',\n icon: 'content_paste',\n shortcut: getPlatformShortcutKey('v', [KeyMode.Ctrl]),\n command: () => pasteFromClipboard(selected),\n shouldShow: !isNameColumn,\n disabled: attrib?.readOnly,\n },\n // Entity operations\n {\n label: 'Show details',\n icon: 'dock_to_left',\n shortcut: 'Double click',\n command: () => {\n const rowSelectionCellId = getCellId(entityId, ROW_SELECTION_COLUMN_ID)\n selectCell(rowSelectionCellId, false, false)\n },\n shouldShow: isNameColumn && isSingleSelection,\n },\n\n // Expand/collapse (all) operations - only for name column\n {\n label: 'Expand all',\n icon: 'expand_all',\n shortcut: 'Alt + click',\n command: () => toggleExpandAll(selectedCellRowsArray, true),\n shouldShow: isNameColumn,\n },\n {\n label: 'Collapse all',\n icon: 'collapse_all',\n shortcut: 'Alt + click',\n command: () => toggleExpandAll(selectedCellRowsArray, false),\n shouldShow: isNameColumn,\n },\n\n // Attribute operations\n {\n label: 'Inherit from parent',\n icon: 'disabled_by_default',\n command: () => inheritFromParent(entitiesToInherit),\n shouldShow: canInheritFromParent,\n },\n\n // Export operations\n {\n label: 'Export selection',\n icon: 'download',\n command: () => exportCSV(selected, projectName),\n shouldShow: true, // Always shown\n },\n\n // Creation operations (only in name column and hierarchy mode)\n {\n label: 'Create folder',\n icon: 'create_new_folder',\n command: () => onOpenNew?.('folder'),\n shouldShow: isNameColumn && showHierarchy && !!onOpenNew,\n },\n {\n label: 'Create root folder',\n icon: 'create_new_folder',\n command: () => {\n clearSelection()\n onOpenNew?.('folder')\n },\n shouldShow: isNameColumn && showHierarchy && !!onOpenNew,\n },\n {\n label: 'Create task',\n icon: 'add_task',\n command: () => onOpenNew?.('task'),\n shouldShow: isNameColumn && showHierarchy && !!onOpenNew,\n },\n\n // Destructive operations\n {\n label: 'Delete',\n icon: 'delete',\n danger: true,\n command: () => deleteEntities(selected),\n shouldShow: isNameColumn,\n },\n ]\n\n // Filter items based on their conditions\n return allMenuItems.filter((item) => item.shouldShow).map(({ shouldShow, ...item }) => item)\n }\n\n // Helper function to identify attributes that can be inherited\n const getEntitiesToInherit = (selected: string[]): InheritFromParentEntity[] => {\n return selected.reduce((acc, cellId) => {\n const { rowId, colId } = parseCellId(cellId) || {}\n if (!rowId || !colId || !colId.startsWith('attrib_')) return acc\n\n const entity = getEntityById(rowId)\n if (!entity) return acc\n\n const attribName = colId.replace('attrib_', '')\n // get attrib model\n const attribModel = attribs.find((attrib) => attrib.name === attribName)\n // is the attrib inheritable?\n const isInheritable = attribModel?.data.inherit\n\n // Check if this attribute is owned by the entity (not inherited)\n if (entity.ownAttrib?.includes(attribName) && isInheritable) {\n // Find existing entry or create new one\n const existingIndex = acc.findIndex((item) => item.entityId === rowId)\n\n if (existingIndex >= 0) {\n // Add to existing entity's attribs if not already there\n if (!acc[existingIndex].attribs.includes(attribName)) {\n acc[existingIndex].attribs.push(attribName)\n }\n } else {\n // Create new entity entry\n acc.push({\n entityId: rowId,\n entityType: 'folderId' in entity ? 'task' : 'folder',\n attribs: [attribName],\n ownAttrib: entity.ownAttrib || [],\n // @ts-ignore\n folderId: entity.parentId ?? entity.folderId,\n })\n }\n }\n\n return acc\n }, [] as InheritFromParentEntity[])\n }\n\n const handleTableBodyContextMenu = (e: ContextEvent) => {\n const target = e.target as HTMLElement\n const tdEl = target.closest('td')\n // get id of first child of td\n const cellId = tdEl?.firstElementChild?.id\n\n if (cellId) {\n let currentSelectedCells = Array.from(selectedCells)\n if (!isCellSelected(cellId)) {\n currentSelectedCells = [cellId]\n }\n cellContextMenuShow(e, cellContextMenuItems(e, cellId, currentSelectedCells))\n }\n }\n\n return { handleTableBodyContextMenu }\n}\n\nexport default useCellContextMenu\n","import { useMemo } from 'react'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport { Column } from '@tanstack/react-table'\nimport { TableRow } from '../types/table'\n\ninterface UseColumnVirtualizationProps {\n visibleColumns: Column<TableRow, unknown>[]\n tableContainerRef: React.RefObject<HTMLDivElement>\n columnPinning: {\n left?: string[]\n }\n}\n\ninterface UseColumnVirtualizationResult {\n columnVirtualizer: ReturnType<typeof useVirtualizer<HTMLDivElement, HTMLTableCellElement>>\n virtualPaddingLeft: number | undefined\n virtualPaddingRight: number | undefined\n}\n\nconst useColumnVirtualization = ({\n visibleColumns,\n tableContainerRef,\n columnPinning,\n}: UseColumnVirtualizationProps): UseColumnVirtualizationResult => {\n // Extract pinned column indexes for virtualization\n const leftPinnedIndexes = useMemo(() => {\n return visibleColumns.filter((col) => col.getIsPinned() === 'left').map((col) => col.getIndex())\n }, [visibleColumns, columnPinning])\n\n // Find highest pinned index and include all columns between 0 and that index\n const pinnedColumnIndexes: number[] = []\n if (leftPinnedIndexes.length > 0) {\n const maxPinnedIndex = Math.max(...leftPinnedIndexes)\n // Include all indexes from 0 to maxPinnedIndex to maintain continuity\n for (let i = 0; i <= maxPinnedIndex; i++) {\n pinnedColumnIndexes.push(i)\n }\n }\n\n const columnVirtualizer = useVirtualizer<HTMLDivElement, HTMLTableCellElement>({\n count: visibleColumns.length,\n estimateSize: (index) => visibleColumns[index].getSize(), //estimate width of each column for accurate scrollbar dragging\n getScrollElement: () => tableContainerRef.current,\n horizontal: true,\n overscan: 0, //how many columns to render on each side off screen each way (adjust this for performance)\n rangeExtractor: (range) => {\n const start = range.startIndex\n const end = range.endIndex\n const overscan = range.overscan\n\n // Calculate the base visible range with overscan\n const baseIndexes = []\n for (let i = start - overscan; i <= end + overscan; i++) {\n if (i >= 0 && i < visibleColumns.length) {\n baseIndexes.push(i)\n }\n }\n\n // Create a Set of all unique indexes we need to render\n const allIndexes = new Set([\n ...pinnedColumnIndexes, // All columns up to the highest pinned column\n ...baseIndexes, // Visible columns in the current range\n ])\n\n // Sort indexes to maintain column order\n return Array.from(allIndexes).sort((a, b) => a - b)\n },\n })\n\n const virtualColumnsResult = columnVirtualizer.getVirtualItems()\n\n // Calculate virtual padding differently for pinned columns\n let virtualPaddingLeft: number | undefined\n let virtualPaddingRight: number | undefined\n\n if (columnVirtualizer && virtualColumnsResult.length) {\n const totalSize = columnVirtualizer.getTotalSize()\n\n // Find the first non-pinned visible column\n const firstNonPinnedIndex = virtualColumnsResult.findIndex(\n (vc) => !pinnedColumnIndexes.includes(vc.index),\n )\n\n if (firstNonPinnedIndex !== -1) {\n // Calculate left padding by finding the start of the first non-pinned column\n // minus the total width of all pinned columns that come before it\n const firstNonPinnedStart = virtualColumnsResult[firstNonPinnedIndex].start\n const totalPinnedWidth = pinnedColumnIndexes.reduce((width, index) => {\n const col = visibleColumns[index]\n return width + col.getSize()\n }, 0)\n\n // Adjust left padding to account for pinned columns\n virtualPaddingLeft = Math.max(0, firstNonPinnedStart - totalPinnedWidth)\n } else {\n virtualPaddingLeft = 0\n }\n\n // Last column's end position\n const lastVisibleColumnEnd = virtualColumnsResult[virtualColumnsResult.length - 1]?.end ?? 0\n\n // Calculate right padding\n virtualPaddingRight = Math.max(0, totalSize - lastVisibleColumnEnd)\n }\n\n return {\n columnVirtualizer,\n virtualPaddingLeft,\n virtualPaddingRight,\n }\n}\n\nexport default useColumnVirtualization\n","import { useCallback, useEffect } from 'react'\nimport { useSelectionContext } from '../context/SelectionContext'\nimport { useCellEditing } from '../context/CellEditingContext' // keep for editingCellId/setEditingCellId\nimport { parseCellId, getCellId } from '../utils/cellUtils'\nimport { useProjectTableContext } from '../context/ProjectTableContext'\n\nexport default function useKeyboardNavigation() {\n const { attribFields } = useProjectTableContext()\n\n const { focusedCellId, gridMap, selectCell, focusCell, clearSelection, setFocusedCellId } =\n useSelectionContext()\n\n const { setEditingCellId, editingCellId } = useCellEditing()\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n const target = e.target as HTMLElement\n if (!target?.closest('table')) return\n\n // Skip if event target is an input element or contentEditable\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 if (editingCellId) return\n\n // Don't handle keyboard events if we don't have a focused cell\n if (!focusedCellId) return\n\n const position = parseCellId(focusedCellId)\n if (!position) return\n\n const { rowId, colId } = position\n const rowIndex = gridMap.rowIdToIndex.get(rowId)\n const colIndex = gridMap.colIdToIndex.get(colId)\n\n if (rowIndex === undefined || colIndex === undefined) return\n\n const isReadOnly =\n colId.startsWith('attrib_') &&\n attribFields.find((a) => a.name === colId.replace('attrib_', ''))?.readOnly\n\n // Handle different keys\n switch (e.key) {\n case 'ArrowUp': {\n e.preventDefault()\n if (rowIndex > 0) {\n const newRowId = gridMap.indexToRowId.get(rowIndex - 1)\n if (newRowId) {\n const newCellId = getCellId(newRowId, colId)\n selectCell(newCellId, e.shiftKey, e.shiftKey)\n focusCell(newCellId)\n }\n }\n break\n }\n case 'ArrowDown': {\n e.preventDefault()\n const newRowId = gridMap.indexToRowId.get(rowIndex + 1)\n if (newRowId) {\n const newCellId = getCellId(newRowId, colId)\n selectCell(newCellId, e.shiftKey, e.shiftKey)\n focusCell(newCellId)\n }\n break\n }\n case 'ArrowLeft': {\n e.preventDefault()\n if (colIndex > 0) {\n const newColId = gridMap.indexToColId.get(colIndex - 1)\n if (newColId) {\n const newCellId = getCellId(rowId, newColId)\n selectCell(newCellId, e.shiftKey, e.shiftKey)\n focusCell(newCellId)\n }\n }\n break\n }\n case 'ArrowRight': {\n e.preventDefault()\n const newColId = gridMap.indexToColId.get(colIndex + 1)\n if (newColId) {\n const newCellId = getCellId(rowId, newColId)\n selectCell(newCellId, e.shiftKey, e.shiftKey)\n focusCell(newCellId)\n }\n break\n }\n case 'Enter': {\n e.preventDefault()\n if (isReadOnly) return\n // Start editing the currently focused cell\n setEditingCellId(focusedCellId)\n break\n }\n case 'Escape': {\n e.preventDefault()\n // Clear selection and stop editing\n clearSelection()\n setEditingCellId(null)\n setFocusedCellId(null)\n break\n }\n case 'Tab': {\n e.preventDefault()\n // Move to next cell (right if no shift, left if shift)\n const nextColIndex = e.shiftKey ? colIndex - 1 : colIndex + 1\n const nextColId = gridMap.indexToColId.get(nextColIndex)\n\n if (nextColId) {\n // Move to next/prev column in same row\n const newCellId = getCellId(rowId, nextColId)\n selectCell(newCellId, false, false)\n focusCell(newCellId)\n } else if (!e.shiftKey && rowIndex < gridMap.rowIdToIndex.size - 1) {\n // Move to first column of next row\n const newRowId = gridMap.indexToRowId.get(rowIndex + 1)\n const firstColId = gridMap.indexToColId.get(0)\n if (newRowId && firstColId) {\n const newCellId = getCellId(newRowId, firstColId)\n selectCell(newCellId, false, false)\n focusCell(newCellId)\n }\n } else if (e.shiftKey && rowIndex > 0) {\n // Move to last column of previous row\n const newRowId = gridMap.indexToRowId.get(rowIndex - 1)\n const lastColId = gridMap.indexToColId.get(gridMap.colIdToIndex.size - 1)\n if (newRowId && lastColId) {\n const newCellId = getCellId(newRowId, lastColId)\n selectCell(newCellId, false, false)\n focusCell(newCellId)\n }\n }\n break\n }\n }\n },\n [\n focusedCellId,\n gridMap,\n selectCell,\n focusCell,\n clearSelection,\n setEditingCellId,\n editingCellId,\n ],\n )\n\n // Attach the keydown event handler to the document\n useEffect(() => {\n document.addEventListener('keydown', handleKeyDown)\n\n // Cleanup the event listener on component unmount\n return () => {\n document.removeEventListener('keydown', handleKeyDown)\n }\n }, [\n handleKeyDown,\n focusedCellId,\n gridMap,\n selectCell,\n focusCell,\n clearSelection,\n setEditingCellId,\n editingCellId,\n ])\n return {\n handleKeyDown,\n focusedCellId,\n gridMap,\n selectCell,\n focusCell,\n clearSelection,\n setEditingCellId,\n editingCellId,\n }\n}\n","import { useMemo, useRef, useEffect, memo, CSSProperties } from 'react'\nimport { useVirtualizer, VirtualItem, Virtualizer } from '@tanstack/react-virtual'\n// TanStack Table imports\nimport {\n useReactTable,\n getCoreRowModel,\n getFilteredRowModel,\n getExpandedRowModel,\n filterFns,\n flexRender,\n Row,\n OnChangeFn,\n getSortedRowModel,\n Cell,\n Column,\n functionalUpdate,\n ColumnSizingState,\n Table,\n Header,\n HeaderGroup,\n ExpandedState,\n SortingState,\n} from '@tanstack/react-table'\n\n// Utility imports\nimport clsx from 'clsx'\n\n// Type imports\nimport type { FolderNodeMap, TableRow, TaskNodeMap } from './types/table'\n\n// Component imports\nimport ProjectTreeTableColumns from './ProjectTreeTableColumns'\nimport * as Styled from './ProjectTreeTable.styled'\nimport HeaderActionButton from './components/HeaderActionButton'\nimport EmptyPlaceholder from '../../components/EmptyPlaceholder'\n\n// Context imports\nimport { CellEditingProvider, useCellEditing } from './context/CellEditingContext'\nimport { ROW_SELECTION_COLUMN_ID, useSelectionContext } from './context/SelectionContext'\nimport { ClipboardProvider } from './context/ClipboardContext'\nimport { useSelectedRowsContext } from './context/SelectedRowsContext'\nimport { useColumnSettings } from './context/ColumnSettingsContext'\n\n// Hook imports\nimport useCustomColumnWidthVars from './hooks/useCustomColumnWidthVars'\nimport usePrefetchFolderTasks from './hooks/usePrefetchFolderTasks'\nimport { useLocalStorage } from '../../hooks'\nimport useCellContextMenu from './hooks/useCellContextMenu'\nimport useColumnVirtualization from './hooks/useColumnVirtualization'\nimport useKeyboardNavigation from './hooks/useKeyboardNavigation'\n\n// Utility function imports\nimport { getCellId } from './utils/cellUtils'\nimport { generateLoadingRows, generateDummyAttributes } from './utils/loadingUtils'\nimport { createPortal } from 'react-dom'\nimport { Icon } from '@ynput/ayon-react-components'\nimport { AttributeEnumItem, AttributeWithPermissions, BuiltInFieldOptions } from './types'\nimport { useProjectTableContext } from './context/ProjectTableContext'\n\n//These are the important styles to make sticky column pinning work!\n//Apply styles like this using your CSS strategy of choice with this kind of logic to head cells, data cells, footer cells, etc.\n//View the index.css file for more needed styles such as border-collapse: separate\nconst getCommonPinningStyles = (column: Column<TableRow, unknown>): CSSProperties => {\n const isPinned = column.getIsPinned()\n\n return {\n left: isPinned === 'left' ? `${column.getStart('left')}px` : undefined,\n right: isPinned === 'right' ? `${column.getAfter('right')}px` : undefined,\n position: isPinned ? 'sticky' : 'relative',\n width: column.getSize(),\n zIndex: isPinned ? 100 : 0,\n }\n}\n\ntype Props = {\n projectName: string\n scope: string\n options: BuiltInFieldOptions\n attribs: AttributeWithPermissions[]\n sliceId: string\n // metadata\n tasksMap: TaskNodeMap\n foldersMap: FolderNodeMap\n fetchMoreOnBottomReached: (element: HTMLDivElement | null) => void\n onOpenNew?: (type: 'folder' | 'task') => void\n}\n\n// Component to wrap with all providers\nconst FlexTableWithProviders = (props: Props) => {\n // convert attribs to object\n const attribByField = useMemo(() => {\n return props.attribs.reduce((acc: Record<string, AttributeEnumItem[]>, attrib) => {\n if (attrib.data?.enum?.length) {\n acc[attrib.name] = attrib.data?.enum\n }\n return acc\n }, {})\n }, [props.attribs])\n\n return (\n <ClipboardProvider\n foldersMap={props.foldersMap}\n tasksMap={props.tasksMap}\n columnEnums={{ ...props.options, ...attribByField }}\n columnReadOnly={props.attribs\n .filter((attrib) => attrib.readOnly)\n .map((attrib) => attrib.name)}\n >\n <FlexTable {...props} />\n </ClipboardProvider>\n )\n}\n\nconst FlexTable = ({\n scope,\n attribs,\n options,\n sliceId,\n fetchMoreOnBottomReached,\n onOpenNew,\n}: Props) => {\n const {\n columnVisibility,\n columnVisibilityUpdater,\n columnPinning,\n columnPinningUpdater,\n columnOrder,\n columnOrderUpdater,\n } = useColumnSettings()\n\n const {\n tableData,\n isLoading,\n isInitialized,\n expanded,\n updateExpanded,\n toggleExpandAll,\n toggleExpanded,\n sorting,\n updateSorting,\n showHierarchy,\n } = useProjectTableContext()\n\n //The virtualizer needs to know the scrollable container element\n const tableContainerRef = useRef<HTMLDivElement>(null)\n\n // Selection context\n const { registerGrid } = useSelectionContext()\n\n // COLUMN SIZING\n const [columnSizing, setColumnSizing] = useLocalStorage<ColumnSizingState>(\n `column-widths-${scope}`,\n {},\n )\n\n const updateColumnSizing: OnChangeFn<ColumnSizingState> = (columnSizingUpdater) => {\n setColumnSizing(functionalUpdate(columnSizingUpdater, columnSizing))\n }\n\n //a check on mount and after a fetch to see if the table is already scrolled to the bottom and immediately needs to fetch more data\n useEffect(() => {\n fetchMoreOnBottomReached(tableContainerRef.current)\n }, [fetchMoreOnBottomReached])\n\n // generate loading attrib and rows\n const { loadingAttrib, loadingRows } = useMemo(() => {\n // count the number of children in tbody\n const tableRowsCount = tableContainerRef.current?.querySelectorAll('tbody tr').length || 0\n const loadingAttrib = generateDummyAttributes()\n const loadingRows = generateLoadingRows(\n attribs,\n showHierarchy && tableData.length > 0 ? Math.min(tableRowsCount, 50) : 50,\n )\n return { loadingAttrib, loadingRows }\n }, [attribs, tableData, showHierarchy, tableContainerRef.current])\n\n const showLoadingRows = !isInitialized || isLoading\n\n const columns = ProjectTreeTableColumns({\n tableData: showLoadingRows ? loadingRows : tableData,\n columnSizing,\n attribs: isInitialized ? attribs : loadingAttrib,\n isLoading: !isInitialized,\n showHierarchy,\n sliceId,\n options,\n toggleExpandAll: (id: string) => toggleExpandAll([id]),\n toggleExpanded: (id: string) => toggleExpanded(id),\n })\n\n const table = useReactTable({\n data: showLoadingRows ? loadingRows : tableData,\n columns,\n enableRowSelection: true, //enable row selection for all rows\n getRowId: (row) => row.id,\n enableSubRowSelection: false, //disable sub row selection\n getSubRows: (row) => row.subRows,\n getRowCanExpand: () => true,\n getCoreRowModel: getCoreRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getExpandedRowModel: getExpandedRowModel(),\n filterFromLeafRows: true,\n // EXPANDABLE\n onExpandedChange: updateExpanded,\n // SORTING\n getSortedRowModel: getSortedRowModel(),\n onSortingChange: updateSorting,\n columnResizeMode: 'onChange',\n onColumnPinningChange: columnPinningUpdater,\n onColumnSizingChange: updateColumnSizing,\n onColumnVisibilityChange: columnVisibilityUpdater,\n onColumnOrderChange: columnOrderUpdater,\n // @ts-ignore\n filterFns,\n state: {\n expanded,\n sorting,\n columnPinning: {\n left: [ROW_SELECTION_COLUMN_ID, ...(columnPinning.left || [])],\n right: columnPinning.right,\n },\n columnSizing,\n columnVisibility,\n columnOrder,\n },\n enableSorting: true,\n })\n\n const { rows } = table.getRowModel()\n\n // Register grid structure with selection context when rows or columns change\n useEffect(() => {\n const rowIds = rows.map((row) => row.id)\n const colIds = table.getAllLeafColumns().map((col) => col.id)\n const colIdsSortedByPinning = [...colIds].sort((a, b) => {\n if (ROW_SELECTION_COLUMN_ID === b) return 1\n const colA = columnPinning.left?.includes(a) ? 0 : 1\n const colB = columnPinning.left?.includes(b) ? 0 : 1\n return colA - colB\n })\n\n registerGrid(rowIds, colIdsSortedByPinning)\n }, [rows, table.getAllLeafColumns(), columnPinning, ROW_SELECTION_COLUMN_ID, registerGrid])\n\n const visibleColumns = table.getVisibleLeafColumns()\n\n // Use the column virtualization hook\n const { columnVirtualizer, virtualPaddingLeft, virtualPaddingRight } = useColumnVirtualization({\n visibleColumns,\n tableContainerRef,\n columnPinning,\n })\n\n const columnSizeVars = useCustomColumnWidthVars(table, columnSizing)\n const readOnlyColumns = useMemo(\n () => attribs.filter((attrib) => attrib.readOnly).map((attrib) => 'attrib_' + attrib.name),\n [attribs],\n )\n\n return (\n <Styled.TableWrapper>\n <Styled.TableContainer\n ref={tableContainerRef}\n style={{ height: '100%', padding: 0 }}\n onScroll={(e) => fetchMoreOnBottomReached(e.currentTarget)}\n className=\"table-container\"\n >\n <table\n style={{\n display: 'grid',\n borderCollapse: 'collapse',\n userSelect: 'none',\n ...columnSizeVars,\n width: table.getTotalSize(),\n }}\n >\n <TableHead\n columnVirtualizer={columnVirtualizer}\n table={table}\n virtualPaddingLeft={virtualPaddingLeft}\n virtualPaddingRight={virtualPaddingRight}\n isLoading={isLoading}\n readOnlyColumns={readOnlyColumns}\n />\n <TableBody\n columnVirtualizer={columnVirtualizer}\n table={table}\n tableContainerRef={tableContainerRef}\n virtualPaddingLeft={virtualPaddingLeft}\n virtualPaddingRight={virtualPaddingRight}\n showHierarchy={showHierarchy}\n attribs={attribs}\n onOpenNew={onOpenNew}\n />\n </table>\n </Styled.TableContainer>\n </Styled.TableWrapper>\n )\n}\n\ninterface TableHeadProps {\n columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>\n table: Table<TableRow>\n virtualPaddingLeft: number | undefined\n virtualPaddingRight: number | undefined\n isLoading: boolean\n readOnlyColumns?: string[]\n}\n\nconst TableHead = ({\n columnVirtualizer,\n table,\n virtualPaddingLeft,\n virtualPaddingRight,\n isLoading,\n readOnlyColumns,\n}: TableHeadProps) => {\n return (\n <Styled.TableHeader>\n {table.getHeaderGroups().map((headerGroup) => (\n <TableHeadRow\n key={headerGroup.id}\n columnVirtualizer={columnVirtualizer}\n headerGroup={headerGroup}\n virtualPaddingLeft={virtualPaddingLeft}\n virtualPaddingRight={virtualPaddingRight}\n isLoading={isLoading}\n readOnlyColumns={readOnlyColumns}\n />\n ))}\n </Styled.TableHeader>\n )\n}\n\ninterface TableHeadRowProps {\n columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>\n headerGroup: HeaderGroup<TableRow>\n virtualPaddingLeft: number | undefined\n virtualPaddingRight: number | undefined\n isLoading: boolean\n readOnlyColumns?: string[]\n}\n\nconst TableHeadRow = ({\n columnVirtualizer,\n headerGroup,\n virtualPaddingLeft,\n virtualPaddingRight,\n isLoading,\n readOnlyColumns,\n}: TableHeadRowProps) => {\n const virtualColumns = columnVirtualizer.getVirtualItems()\n return (\n <Styled.ColumnHeader key={headerGroup.id} style={{ display: 'flex' }}>\n {virtualPaddingLeft ? (\n //fake empty column to the left for virtualization scroll padding\n <th style={{ display: 'flex', width: virtualPaddingLeft }} />\n ) : null}\n {virtualColumns.map((virtualColumn) => {\n const header = headerGroup.headers[virtualColumn.index]\n return (\n <TableHeadCell\n key={header.id}\n header={header}\n isLoading={isLoading}\n isReadOnly={readOnlyColumns?.includes(header.id)}\n />\n )\n })}\n {virtualPaddingRight ? (\n //fake empty column to the right for virtualization scroll padding\n <th style={{ display: 'flex', width: virtualPaddingRight }} />\n ) : null}\n </Styled.ColumnHeader>\n )\n}\n\ninterface TableHeadCellProps {\n header: Header<TableRow, unknown>\n isLoading: boolean\n isReadOnly?: boolean\n}\n\nconst TableHeadCell = ({ header, isLoading, isReadOnly }: TableHeadCellProps) => {\n const { column } = header\n const isRowSelectionColumn = column.id === ROW_SELECTION_COLUMN_ID\n\n return (\n <Styled.HeaderCell\n className={clsx(header.id, 'shimmer-dark', {\n loading: isLoading,\n large: column.id === 'folderType',\n 'last-pinned-left': column.getIsPinned() === 'left' && column.getIsLastColumn('left'),\n })}\n key={header.id}\n style={{\n ...getCommonPinningStyles(column),\n width: `calc(var(--header-${header?.id}-size) * 1px)`,\n }}\n >\n {header.isPlaceholder ? null : (\n <Styled.TableCellContent\n className={clsx('bold', {\n large: column.id === 'folderType',\n })}\n >\n {flexRender(column.columnDef.header, header.getContext())}\n {isReadOnly && (\n <Icon icon=\"lock\" data-tooltip={'You only have permission to read this column.'} />\n )}\n\n <Styled.HeaderButtons className=\"actions\">\n {/* COLUMN HIDING */}\n <HeaderActionButton\n icon=\"visibility_off\"\n selected={!column.getIsVisible()}\n onClick={column.getToggleVisibilityHandler()}\n />\n {/* COLUMN SORTING */}\n <HeaderActionButton\n icon=\"push_pin\"\n selected={header.column.getIsPinned() === 'left'}\n onClick={() => {\n if (header.column.getIsPinned() === 'left') {\n header.column.pin(false)\n } else {\n header.column.pin('left')\n }\n }}\n />\n {/* COLUMN PINNING */}\n <HeaderActionButton\n icon={'sort'}\n style={{\n transform: (column.getIsSorted() as string) === 'asc' ? 'scaleY(-1)' : undefined,\n }}\n onClick={column.getToggleSortingHandler()}\n selected={!!column.getIsSorted()}\n />\n </Styled.HeaderButtons>\n {!isRowSelectionColumn && (\n <Styled.ResizedHandler\n {...{\n onDoubleClick: () => column.resetSize(),\n onMouseDown: header.getResizeHandler(),\n onTouchStart: header.getResizeHandler(),\n className: clsx('resize-handle', {\n resizing: column.getIsResizing(),\n }),\n }}\n />\n )}\n </Styled.TableCellContent>\n )}\n </Styled.HeaderCell>\n )\n}\n\ninterface TableBodyProps {\n columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>\n table: Table<TableRow>\n tableContainerRef: React.RefObject<HTMLDivElement>\n showHierarchy: boolean\n virtualPaddingLeft: number | undefined\n virtualPaddingRight: number | undefined\n attribs: AttributeWithPermissions[]\n onOpenNew?: (type: 'folder' | 'task') => void\n}\n\nconst TableBody = ({\n columnVirtualizer,\n table,\n tableContainerRef,\n showHierarchy,\n virtualPaddingLeft,\n virtualPaddingRight,\n attribs,\n onOpenNew,\n}: TableBodyProps) => {\n const { handleTableBodyContextMenu } = useCellContextMenu({ attribs, onOpenNew })\n\n const { handlePreFetchTasks } = usePrefetchFolderTasks()\n\n const { rows } = table.getRowModel()\n\n const rowVirtualizer = useVirtualizer<HTMLDivElement, HTMLTableRowElement>({\n count: rows.length,\n estimateSize: () => (showHierarchy ? 36 : 40), //estimate row height for accurate scrollbar dragging\n getScrollElement: () => tableContainerRef.current,\n //measure dynamic row height, except in firefox because it measures table border height incorrectly\n measureElement:\n typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1\n ? (element) => element?.getBoundingClientRect().height\n : undefined,\n overscan: 5,\n })\n\n const virtualRows = rowVirtualizer.getVirtualItems()\n\n useKeyboardNavigation()\n\n return virtualRows.length ? (\n <tbody\n style={{\n height: `${rowVirtualizer.getTotalSize()}px`,\n position: 'relative',\n display: 'grid',\n }}\n onContextMenu={handleTableBodyContextMenu}\n onMouseOver={(e) => {\n handlePreFetchTasks(e)\n }}\n >\n {virtualRows.map((virtualRow) => {\n const row = rows[virtualRow.index] as Row<TableRow>\n return (\n <TableBodyRow\n key={row.id}\n columnVirtualizer={columnVirtualizer}\n row={row}\n rowVirtualizer={rowVirtualizer}\n virtualPaddingLeft={virtualPaddingLeft}\n virtualPaddingRight={virtualPaddingRight}\n virtualRow={virtualRow}\n showHierarchy={showHierarchy}\n />\n )\n })}\n </tbody>\n ) : (\n tableContainerRef.current &&\n createPortal(\n <EmptyPlaceholder message=\"No folders or tasks found\" />,\n tableContainerRef.current,\n )\n )\n}\n\ninterface TableBodyRowProps {\n columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>\n row: Row<TableRow>\n rowVirtualizer: Virtualizer<HTMLDivElement, HTMLTableRowElement>\n virtualPaddingLeft: number | undefined\n virtualPaddingRight: number | undefined\n virtualRow: VirtualItem\n showHierarchy: boolean\n}\n\nconst TableBodyRow = ({\n columnVirtualizer,\n row,\n rowVirtualizer,\n virtualPaddingLeft,\n virtualPaddingRight,\n virtualRow,\n showHierarchy,\n}: TableBodyRowProps) => {\n // We should do this so that we don't re-render every time anything in projectTableContext changes\n const visibleCells = row.getVisibleCells()\n const virtualColumns = columnVirtualizer.getVirtualItems()\n\n return (\n <Styled.TR\n data-index={virtualRow.index} //needed for dynamic row height measurement\n ref={(node) => rowVirtualizer.measureElement(node)} //measure dynamic row height\n key={row.id}\n style={{\n transform: `translateY(${virtualRow.start}px)`, //this should always be a `style` as it changes on scroll\n }}\n >\n {virtualPaddingLeft ? (\n //fake empty column to the left for virtualization scroll padding\n <td style={{ display: 'flex', width: virtualPaddingLeft }} />\n ) : null}\n {virtualColumns.map((vc) => {\n const cell = visibleCells[vc.index]\n const cellId = getCellId(row.id, cell.column.id)\n return (\n <TableCellMemo\n cell={cell}\n cellId={cellId}\n rowId={row.id}\n key={cell.id}\n showHierarchy={showHierarchy}\n />\n )\n })}\n\n {virtualPaddingRight ? (\n //fake empty column to the right for virtualization scroll padding\n <td style={{ display: 'flex', width: virtualPaddingRight }} />\n ) : null}\n </Styled.TR>\n )\n}\n\ninterface TableCellProps {\n cell: Cell<TableRow, unknown>\n cellId: string\n rowId: string\n className?: string\n showHierarchy: boolean\n}\n\nconst TableCell = ({ cell, rowId, cellId, className, showHierarchy, ...props }: TableCellProps) => {\n const {\n isCellSelected,\n isCellFocused,\n startSelection,\n extendSelection,\n endSelection,\n selectCell,\n getCellBorderClasses,\n } = useSelectionContext()\n\n const { isRowSelected } = useSelectedRowsContext()\n\n const { isEditing } = useCellEditing()\n\n const borderClasses = getCellBorderClasses(cellId)\n\n const isPinned = cell.column.getIsPinned()\n const isLastLeftPinnedColumn = isPinned === 'left' && cell.column.getIsLastColumn('left')\n const isRowSelectionColumn = cell.column.id === ROW_SELECTION_COLUMN_ID\n\n return (\n <Styled.TableCell\n {...props}\n tabIndex={0}\n key={cell.id}\n $isLastPinned={isLastLeftPinnedColumn} // is this column the last pinned column? Custom styling for borders.\n className={clsx(\n cell.column.id,\n cell.column.id === 'folderType' ? 'large' : '',\n {\n selected: isCellSelected(cellId),\n focused: isCellFocused(cellId),\n editing: isEditing(cellId),\n 'last-pinned-left': isLastLeftPinnedColumn,\n 'selected-row': isRowSelected(rowId),\n task: cell.row.original.entityType === 'task',\n },\n className,\n ...borderClasses,\n )}\n style={{\n ...getCommonPinningStyles(cell.column),\n width: `calc(var(--col-${cell.column.id}-size) * 1px)`,\n height: showHierarchy ? 36 : 40,\n }}\n onMouseDown={(e) => {\n // Only process left clicks (button 0), ignore right clicks\n if (e.button !== 0) return\n\n // check we are not clicking on expander\n if ((e.target as HTMLElement).closest('.expander')) return\n const additive = e.metaKey || e.ctrlKey || isRowSelectionColumn\n if (e.shiftKey) {\n // Shift+click extends selection from anchor cell\n selectCell(cellId, additive, true) // true for range selection\n } else {\n // Normal click starts a new selection\n startSelection(cellId, additive)\n }\n }}\n onMouseOver={(e) => {\n if (e.buttons === 1) {\n // Left button is pressed during mouse move - drag selection\n extendSelection(cellId, isRowSelectionColumn)\n }\n }}\n onMouseUp={() => {\n endSelection(cellId)\n }}\n onDoubleClick={(e) => {\n if (cell.column.id === 'name') {\n // select the row by selecting the row-selection cell\n const rowSelectionCellId = getCellId(cell.row.id, ROW_SELECTION_COLUMN_ID)\n if (!isCellSelected(rowSelectionCellId)) {\n const additive = e.metaKey || e.ctrlKey\n selectCell(rowSelectionCellId, additive, false)\n }\n }\n }}\n onContextMenu={(e) => {\n e.preventDefault()\n // if the cell is not selected, select it and deselect all others\n if (!isCellSelected(cellId)) {\n selectCell(cellId, false, false)\n }\n }}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </Styled.TableCell>\n )\n}\n\nconst TableCellMemo = memo(TableCell)\n\nexport { FlexTableWithProviders as ProjectTreeTable }\n","import { Filter } from '@ynput/ayon-react-components'\nimport { QueryCondition, QueryFilter } from '../types/operations'\n\nconst NO_DATE = 'no_date'\nexport const clientFilterToQueryFilter = (filters: Filter[]): QueryFilter => {\n // If there are no filters, return an empty filter\n if (!filters || filters.length === 0) {\n return {}\n }\n\n // Process each filter as its own condition\n const conditions: (QueryCondition | QueryFilter)[] = filters\n .filter((f) => !!f.values?.length)\n .filter((f) => !f.id.includes('text')) // remove text search filters as they are handled separately\n .filter((f) => f.id !== 'hierarchy') // remove hierarchy filter as it is handled separately\n .flatMap((filter) => convertFilterToCondition(filter))\n\n console.log(conditions)\n\n // Return the QueryFilter with all conditions combined with AND\n return {\n conditions,\n operator: 'and',\n }\n}\n\n// Helper function to convert a single Filter to a QueryCondition\nconst convertFilterToCondition = (filter: Filter): QueryCondition => {\n // Extract key from filter ID (split by underscore if needed)\n const key = filter.id.split('_')[0]\n\n // Handle values based on filter type\n let value: QueryCondition['value']\n\n // there is any value\n const hasSomeValue =\n Array.isArray(filter.values) && filter.values.map((v) => v.id)?.includes('hasValue')\n const hasNoValue =\n Array.isArray(filter.values) && filter.values.map((v) => v.id)?.includes('noValue')\n\n if (filter.values && filter.values.length > 0) {\n if (filter.singleSelect) {\n // @ts-expect-error\n value = convertValueByType(filter.values[0].id, filter.type)\n } else {\n // @ts-expect-error\n value = filter.values.map((v) => convertValueByType(v.id, filter.type))\n }\n }\n\n // Determine if this is likely a list field based on filter type\n const isListField =\n filter.type?.startsWith('list_of_') || key.includes('tags') || key.includes('assignees')\n const isDateField = filter.type === 'datetime'\n\n // Determine the appropriate operator based on filter properties and type\n let operator: QueryCondition['operator'] = 'eq'\n\n // Handling NULL values\n if (value === undefined) {\n operator = filter.inverted ? 'notnull' : 'isnull'\n return { key, operator }\n }\n\n // Handle different filter types\n if (hasSomeValue) {\n // we set the value to the empty state and then say it should not be that\n value = isListField ? [] : undefined\n operator = isListField\n ? filter.inverted\n ? 'eq'\n : 'ne'\n : filter.inverted\n ? 'isnull'\n : 'notnull'\n } else if (hasNoValue) {\n // we set the value to the empty state and then say it should be that\n value = isListField ? [] : undefined\n operator = isListField\n ? filter.inverted\n ? 'ne'\n : 'eq'\n : filter.inverted\n ? 'notnull'\n : 'isnull'\n } else if (isListField) {\n if (filter.inverted) {\n operator = filter.operator === 'AND' ? 'excludesall' : 'excludesany'\n } else {\n operator = filter.operator === 'AND' ? 'includesall' : 'includesany'\n }\n } else if (isDateField) {\n // For date filters, we need to return a complete query filter with conditions\n if (filter.values && filter.values.length > 0) {\n // Create a flat list of all date conditions from all filter values\n const dateConditions: QueryCondition[] = filter.values.flatMap((filterValue: Filter) => {\n const conditions: QueryCondition[] = []\n const dateValues = filterValue.values\n\n // First value is greater than (start date)\n if (dateValues?.[0] !== undefined && dateValues?.[0].id !== NO_DATE) {\n conditions.push({\n key,\n operator: filter.inverted ? 'lte' : 'gte',\n value: dateValues[0].id,\n })\n }\n\n // Second value is less than (end date)\n if (dateValues?.[1] !== undefined && dateValues?.[1].id !== NO_DATE) {\n conditions.push({\n key,\n operator: filter.inverted ? 'gte' : 'lte',\n value: dateValues[1].id,\n })\n }\n\n return conditions\n })\n\n // If we have date conditions, return them as a nested filter instead of continuing\n if (dateConditions.length > 0) {\n // @ts-expect-error\n return {\n conditions: dateConditions,\n operator: filter.inverted ? 'or' : 'and',\n } as QueryFilter\n }\n }\n\n // If no date conditions were created, fall back to a basic equality check\n operator = filter.inverted ? 'ne' : 'eq'\n } else {\n // DEFAULT\n // For scalar fields\n operator = filter.inverted ? 'notin' : 'in'\n }\n\n return { key, value, operator }\n}\n\n// Helper function to convert values based on the filter type\nconst convertValueByType = (value: string, type?: string): string | number | boolean => {\n if (!type) return value\n\n switch (type) {\n case 'integer':\n return parseInt(value, 10)\n case 'float':\n return parseFloat(value)\n case 'boolean':\n return value.toLowerCase() === 'true'\n default:\n return value\n }\n}\n\nexport default clientFilterToQueryFilter\n"],"names":["parseISO","argument","options","invalidDate","constructFrom","dateStrings","splitDateString","date","parseYearResult","parseYear","parseDate","timestamp","time","offset","parseTime","parseTimezone","tmpDate","result","toDate","patterns","dateRegex","timeRegex","timezoneRegex","dateString","array","timeString","token","additionalDigits","regex","captures","year","century","isWeekDate","dayOfYear","parseDateUnit","month","day","week","dayOfWeek","validateWeekDate","dayOfISOWeekYear","validateDate","validateDayOfYearDate","value","hours","parseTimeUnit","minutes","seconds","validateTime","millisecondsInHour","millisecondsInMinute","timezoneString","sign","validateTimezone","isoWeekYear","fourthOfJanuaryDay","diff","daysInMonths","isLeapYearIndex","_year","_hours","memo","getDeps","fn","opts","deps","memoizedFunction","_a","_b","_c","_d","depTime","newDeps","dep","index","resultTime","depEndTime","resultEndTime","resultFpsPercentage","pad","str","num","notUndefined","msg","approxEqual","a","b","debounce","targetWindow","ms","timeoutId","args","defaultKeyExtractor","defaultRangeExtractor","range","start","end","arr","i","observeElementRect","instance","cb","element","handler","rect","width","height","observer","entries","run","entry","box","addEventListenerOptions","supportsScrollend","observeElementOffset","fallback","createHandler","isScrolling","horizontal","isRtl","endHandler","registerScrollendEvent","measureElement","elementScroll","adjustments","behavior","toOffset","Virtualizer","_ro","get","target","opts2","key","sync","d","scrollElement","cached","measurements","furthestMeasurementsFound","furthestMeasurements","m","measurement","previousFurthestMeasurement","count","paddingStart","scrollMargin","getItemKey","enabled","itemSizeCache","item","min","furthestMeasurement","measuredSize","size","lane","outerSize","scrollOffset","lanes","calculateRange","startIndex","endIndex","rangeExtractor","overscan","node","attributeName","indexStr","prevNode","itemSize","delta","indexes","virtualItems","k","len","findNearestBinarySearch","align","scrollSizeProp","maxOffset","initialAlign","offsetAndAlign","latestOffset","endByLane","val","low","high","getCurrentValue","middle","currentValue","lastIndex","getOffset","endPerLane","pos","startPerLane","useIsomorphicLayoutEffect","React","useVirtualizerBase","rerender","resolvedOptions","instance2","flushSync","useVirtualizer","StyledDot","styled","CollapsedWidget","forwardRef","color","props","ref","jsx","StyledInput","DateWidgetInput","initialValue","onChange","onCancel","autoFocus","_","setValue","useState","parsedDate","isValid","format","useEffect","inputRef","useRef","error","handleClick","e","handleDateSubmit","event","parsed","dateWithZeroTime","handleBlur","handleKeyDown","DateWidget","isEditing","isReadOnly","isInherited","onCancelEdit","StyledWidget","StyledValuesContainer","StyledValueWrapper","StyledValue","StyledImg","StyledExpandIcon","Icon","StyledDropdown","Dropdown","checkForImgSrc","icon","checkAvatarImg","src","EnumWidget","type","autoOpen","enableCustomValues","onOpen","onNext","pt","dropdownProps","_ref","valueAsStrings","v","selectedOptions","option","hasMultipleValues","dropdownRef","handleClosedClick","dropdownOpen","setDropdownOpen","optionsUlEl","firstItem","isMultiSelect","handleChange","filteredValue","o","_value","selected","isOpen","EnumCellValue","clsx","_isActive","isSelected","placeholder","isItem","className","allOptionsHaveIcon","showLabels","backgroundColor","isPlaceholder","jsxs","TextWidgetInput","escapePressed","StyledBaseTextWidget","TextWidget","StyledCheckbox","BooleanWidget","ProjectTableQueriesContext","createContext","ProjectTableQueriesProvider","children","updateEntities","getFoldersTasks","useProjectTableQueriesContext","context","useContext","generateLoadingRows","attribs","parentId","acc","attrib","generateDummyAttributes","determineLoadingTaskFolders","expandedFoldersTasks","expandedParentIds","foldersMap","folderIds","task","expandedParentIdsThatHaveTasks","id","folderIdsSet","loadingParentIds","folderId","loadingTasks","folder","TASKS_INFINITE_QUERY_COUNT","useOverviewTable","tasksMap","tasksByFolderMap","expanded","folderTypes","taskTypes","showHierarchy","isLoadingMore","folderTypesByName","useMemo","map","folderType","taskTypesByName","taskType","expandedKey","expandedFolderIds","isExpanded","childToParentMap","parentToChildrenMap","childToParent","parentToChildren","visibleFolders","visible","queue","childrenIds","childId","createTaskRow","flatTaskRows","firstTaskAttrib","loadingAttribs","loadingTaskRows","rowsById","rootRows","row","folderTasks","taskId","taskRows","_g","_f","_e","childRow","parentRow","r","typeA","typeB","useFolderRelationships","getEntityById","projectAttrib","attribFields","folderChildrenMap","getChildrenEntities","useCallback","descendants","visited","currentId","taskIds","childFolderIds","getAncestorsOf","ancestors","entity","getTaskAncestors","folderAncestors","findNonInheritedValues","attribNames","pendingAttribs","attribName","getInheritedDependents","entities","blockedInheritanceMap","attribEntries","filteredChildren","child","inheritedAttribs","ownedAttribs","filteredInheritedAttribs","ancestor","existingEntityIndex","findInheritedValueFromAncestors","entityId","entityType","ProjectTableContext","ProjectTableProvider","projectInfo","isLoading","isInitialized","projectName","users","filters","setFilters","queryFilters","updateShowHierarchy","toggleExpanded","updateExpanded","sorting","updateSorting","fetchNextPage","reloadTableData","setExpanded","tableData","toggleExpandAll","rowIds","expandAll","expandedState","newExpandedState","rowId","childIds","useProjectTableContext","useUpdateOverview","pushHistory","handleUpdateEntities","pushToHistory","inverseEntities","field","isAttrib","entityData","oldValue","ownAttrib","wasInherited","historyEntities","supportedEntityTypes","operations","data","existingOperationIndex","op","existingOperation","newData","folderAttribEntities","inheritedDependentsOperations","toast","inheritFromParent","undoEntities","redoEntities","entitiesToPatch","attribData","topFolder","ancestorChain","currentFolderId","currentFolder","folderAttribs","entityAttribsIntersection","entityAttribsRemoved","patchOperations","ancestorAttrib","entityPatch","inheritedDependent","newAttrib","builtInFieldMappings","clipboardError","parseClipboardText","clipboardText","rows","parsedData","origColumnOrder","rowValues","getEntityPath","isFolder","name","parentPath","processFieldValue","fieldValueType","validateClipboardData","params","colId","pasteValue","columnEnums","columnReadOnly","rowIndex","colIndex","isSingleCellValue","assigneeValues","assigneeOptions","validAssignees","opt","pasteRowIndex","pasteColIndex","fieldId","enumOptions","BorderPosition","getCellId","parseCellId","cellId","match","getCellValue","obj","path","parts","current","part","getBorderClasses","borders","classes","ROW_SELECTION_COLUMN_ID","SelectionContext","SelectionProvider","selectedCells","setSelectedCells","focusedCellId","setFocusedCellId","selectionInProgress","setSelectionInProgress","anchorCell","setAnchorCell","gridMap","setGridMap","mapToString","stableGridMap","initialCellSelected","selectedRows","registerGrid","columns","rowIdToIndex","colIdToIndex","indexToRowId","indexToColId","updateSelection","selection","position","prevSelectedCells","newSelection","rowSelection","selectCellRange","additive","startRowIdx","startColIdx","endRowIdx","endColIdx","minRowIdx","maxRowIdx","minColIdx","maxColIdx","c","startSelection","prev","extendSelection","isRowSelectionColumn","currentPosition","endSelection","selectCell","focusCell","clearSelection","isCellSelected","isCellFocused","getCellPositionFromId","getCellBorderClasses","top","right","bottom","left","borderPos","useSelectionContext","ClipboardContext","ClipboardProvider","useCellEditing","getSelectionData","config","headers","fullRow","cellsByRow","sortedRows","indexA","indexB","firstRowId","colIds","headerValues","columnName","filteredColIds","cellValue","foundValue","copyToClipboard","exportCSV","blob","url","selectedCount","pasteFromClipboard","firstRow","selectedColIds","entitiesMap","fieldValue","fieldToUpdate","processedValue","entityKey","allEntityUpdates","useClipboard","ColumnSettingsContext","ColumnSettingsProvider","columnsConfig","columnOrder","columnPinning","columnVisibility","setColumnVisibility","visibility","setColumnOrder","order","setColumnPinning","pinning","togglePinningOnVisibilityChange","newPinning","pinnedColumns","hiddenColumns","col","newPinnedColumns","updatePinningOrderOnOrderChange","pinnedColumnsOrder","updateOrderOnPinningChange","aPinned","updateColumnVisibility","updateColumnOrder","updateColumnPinning","newOrder","columnVisibilityUpdater","newVisibility","functionalUpdate","columnOrderUpdater","columnPinningUpdater","useColumnSettings","SelectedRowsContext","SelectedRowsProvider","prevSelectedRowsRef","currentSelectedRows","sortedCurrent","sortedPrev","selectAllRows","allRowIds","firstCellId","clearRowsSelection","isRowSelected","areAllRowsSelected","totalRows","areSomeRowsSelected","useSelectedRowsContext","useValidateUpdates","rawValue","attribute","attr","validationKeys","validationValues","ge","gt","le","lt","minLength","maxLength","minItems","maxItems","pattern","useHistory","maxHistorySize","past","setPast","future","setFuture","undo","redo","updated","splitActionsByInherited","newPast","last","f","newFuture","next","p","clearHistory","CellEditingContext","CellEditingProvider","editingCellId","setEditingCellId","undoHistory","redoHistory","canUndo","canRedo","updateOverviewEntities","validateUpdateEntities","handleUndo","entitiesToUndo","entitiesToInherit","handleRedo","entitiesToRedo","onKeyDown","ctrlKey","Cell","EditorCellComponent","columnId","attributeData","isCollapsed","isCurrentCellEditing","isCurrentCellFocused","handleDoubleClick","handleSingleClick","moveToNextRow","newRowId","newCellId","handleOnChange","newValue","handleCancel","widget","sharedProps","textTypes","firstSelectedOption","enumValue","arePropsEqual","prevProps","nextProps","CellWidget","Expander","Button","StyledEntityNameWidget","StyledContentWrapper","StyledContentAbsolute","StyledContent","StyledTextContent","theme","EntityNameWidget","label","topShadow","rightShadow","bottomShadow","leftShadow","getDefaultShadow","isLastPinned","TR","cellMinWidth","TableCellContent","ResizedHandler","ColumnHeader","HeaderCell","HeaderButtons","TableCell","$isLastPinned","TableHeader","TableWrapper","TableContainer","StyledSelectionCell","SelectionCell","SelectionHeaderCell","RowSelectionHeader","allSelected","someSelected","withLoadingStateSort","sortFn","rowA","rowB","nameSort","labelA","labelB","pathSort","attribSort","valueA","valueB","sortingFns","ProjectTreeTableColumns","columnSizing","sliceId","staticColumns","column","getValueIdType","s","attributeColumns","columnIdParsed","nestedField","ActionButton","HeaderActionButton","style","useCustomColumnWidthVars","table","columnSizingInfo","colSizes","header","usePrefetchFolderTasks","prefetchedIds","setPrefetchedIds","td","cell","useDeleteEntities","onSuccess","entityIds","fullEntities","deleteEntities","force","message","confirmDelete","useCellContextMenu","onOpenNew","cellContextMenuShow","useCreateContextMenu","cellContextMenuItems","getPlatformShortcutKey","KeyMode","isNameColumn","isSingleSelection","getEntitiesToInherit","selectedCellRows","selectedCellColumns","selectedCellRowsArray","selectedRowCells","isMultipleRows","isMultipleColumns","isGridSelection","canInheritFromParent","rowSelectionCellId","shouldShow","attribModel","isInheritable","existingIndex","tdEl","currentSelectedCells","useColumnVirtualization","visibleColumns","tableContainerRef","leftPinnedIndexes","pinnedColumnIndexes","maxPinnedIndex","columnVirtualizer","baseIndexes","allIndexes","virtualColumnsResult","virtualPaddingLeft","virtualPaddingRight","totalSize","firstNonPinnedIndex","vc","firstNonPinnedStart","totalPinnedWidth","lastVisibleColumnEnd","useKeyboardNavigation","newColId","nextColIndex","nextColId","firstColId","lastColId","getCommonPinningStyles","isPinned","FlexTableWithProviders","attribByField","FlexTable","scope","fetchMoreOnBottomReached","setColumnSizing","useLocalStorage","updateColumnSizing","columnSizingUpdater","loadingAttrib","loadingRows","tableRowsCount","showLoadingRows","useReactTable","getCoreRowModel","getFilteredRowModel","getExpandedRowModel","getSortedRowModel","filterFns","colIdsSortedByPinning","colA","colB","columnSizeVars","readOnlyColumns","Styled.TableWrapper","Styled.TableContainer","TableHead","TableBody","Styled.TableHeader","headerGroup","TableHeadRow","virtualColumns","Styled.ColumnHeader","virtualColumn","TableHeadCell","Styled.HeaderCell","Styled.TableCellContent","flexRender","Styled.HeaderButtons","Styled.ResizedHandler","handleTableBodyContextMenu","handlePreFetchTasks","rowVirtualizer","virtualRows","virtualRow","TableBodyRow","createPortal","EmptyPlaceholder","visibleCells","Styled.TR","TableCellMemo","borderClasses","isLastLeftPinnedColumn","createElement","Styled.TableCell","NO_DATE","clientFilterToQueryFilter","conditions","filter","convertFilterToCondition","hasSomeValue","hasNoValue","convertValueByType","isListField","isDateField","operator","dateConditions","filterValue","dateValues"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}