@shepai/cli 1.172.0-pr529.f145dce → 1.173.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 (280) hide show
  1. package/dist/src/presentation/web/app/features/feature-tree-page-client.d.ts.map +1 -1
  2. package/dist/src/presentation/web/app/features/feature-tree-page-client.js +3 -142
  3. package/dist/src/presentation/web/app/features/get-feature-tree-data.d.ts.map +1 -1
  4. package/dist/src/presentation/web/app/features/get-feature-tree-data.js +1 -4
  5. package/dist/src/presentation/web/components/common/repo-group/repo-group.js +1 -1
  6. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.d.ts +5 -19
  7. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.d.ts.map +1 -1
  8. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.js +87 -169
  9. package/dist/src/presentation/web/components/features/feature-tree-table/index.d.ts +1 -1
  10. package/dist/src/presentation/web/components/features/feature-tree-table/index.d.ts.map +1 -1
  11. package/dist/tsconfig.build.tsbuildinfo +1 -1
  12. package/package.json +1 -1
  13. package/web/.next/BUILD_ID +1 -1
  14. package/web/.next/build-manifest.json +4 -4
  15. package/web/.next/fallback-build-manifest.json +2 -2
  16. package/web/.next/prerender-manifest.json +3 -3
  17. package/web/.next/required-server-files.js +2 -2
  18. package/web/.next/required-server-files.json +2 -2
  19. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/build-manifest.json +2 -2
  20. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
  21. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  22. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  23. package/web/.next/server/app/(dashboard)/@drawer/chat/page/build-manifest.json +2 -2
  24. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
  25. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  26. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  27. package/web/.next/server/app/(dashboard)/@drawer/create/page/build-manifest.json +2 -2
  28. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +30 -30
  29. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  30. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  31. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/build-manifest.json +2 -2
  32. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +38 -38
  33. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  34. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  35. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/build-manifest.json +2 -2
  36. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +38 -38
  37. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  38. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  39. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/build-manifest.json +2 -2
  40. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  41. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  42. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  43. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/build-manifest.json +2 -2
  44. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  45. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  46. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  47. package/web/.next/server/app/(dashboard)/chat/page/build-manifest.json +2 -2
  48. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
  49. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  50. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  51. package/web/.next/server/app/(dashboard)/create/page/build-manifest.json +2 -2
  52. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +30 -30
  53. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  54. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  55. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/build-manifest.json +2 -2
  56. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +38 -38
  57. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  58. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  59. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/build-manifest.json +2 -2
  60. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +38 -38
  61. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  62. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  63. package/web/.next/server/app/(dashboard)/page/build-manifest.json +2 -2
  64. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
  65. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  66. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  67. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/build-manifest.json +2 -2
  68. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  69. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  70. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  71. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/build-manifest.json +2 -2
  72. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  73. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  74. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  75. package/web/.next/server/app/_global-error/page/build-manifest.json +2 -2
  76. package/web/.next/server/app/_global-error.html +2 -2
  77. package/web/.next/server/app/_global-error.rsc +1 -1
  78. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  79. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  80. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  81. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  82. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  83. package/web/.next/server/app/_not-found/page/build-manifest.json +2 -2
  84. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
  85. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  86. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  87. package/web/.next/server/app/features/page/build-manifest.json +2 -2
  88. package/web/.next/server/app/features/page/server-reference-manifest.json +6 -6
  89. package/web/.next/server/app/features/page.js.nft.json +1 -1
  90. package/web/.next/server/app/features/page_client-reference-manifest.js +1 -1
  91. package/web/.next/server/app/settings/page/build-manifest.json +2 -2
  92. package/web/.next/server/app/settings/page/server-reference-manifest.json +9 -9
  93. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  94. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  95. package/web/.next/server/app/skills/page/build-manifest.json +2 -2
  96. package/web/.next/server/app/skills/page/server-reference-manifest.json +13 -13
  97. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  98. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  99. package/web/.next/server/app/tools/page/build-manifest.json +2 -2
  100. package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
  101. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  102. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  103. package/web/.next/server/app/version/page/build-manifest.json +2 -2
  104. package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
  105. package/web/.next/server/app/version/page.js.nft.json +1 -1
  106. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  107. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  108. package/web/.next/server/chunks/ssr/403f9_next_dist_a53cb908._.js +1 -1
  109. package/web/.next/server/chunks/ssr/403f9_next_dist_esm_ceb2fa1e._.js +1 -1
  110. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  111. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  112. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +2 -2
  113. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
  114. package/web/.next/server/chunks/ssr/[root-of-the-server]__08c912ab._.js +1 -1
  115. package/web/.next/server/chunks/ssr/[root-of-the-server]__08c912ab._.js.map +1 -1
  116. package/web/.next/server/chunks/ssr/[root-of-the-server]__0c5452c3._.js +1 -1
  117. package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js +1 -1
  118. package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js.map +1 -1
  119. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js +1 -1
  120. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js.map +1 -1
  121. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  122. package/web/.next/server/chunks/ssr/[root-of-the-server]__4fb81977._.js +1 -1
  123. package/web/.next/server/chunks/ssr/[root-of-the-server]__4fb81977._.js.map +1 -1
  124. package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js +1 -1
  125. package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js.map +1 -1
  126. package/web/.next/server/chunks/ssr/[root-of-the-server]__7dcd0917._.js +1 -1
  127. package/web/.next/server/chunks/ssr/[root-of-the-server]__7dcd0917._.js.map +1 -1
  128. package/web/.next/server/chunks/ssr/[root-of-the-server]__851f6adb._.js +1 -1
  129. package/web/.next/server/chunks/ssr/[root-of-the-server]__86ff0bc5._.js +2 -2
  130. package/web/.next/server/chunks/ssr/[root-of-the-server]__92ffd5ee._.js +2 -2
  131. package/web/.next/server/chunks/ssr/[root-of-the-server]__92ffd5ee._.js.map +1 -1
  132. package/web/.next/server/chunks/ssr/[root-of-the-server]__b020c17d._.js +2 -2
  133. package/web/.next/server/chunks/ssr/[root-of-the-server]__b020c17d._.js.map +1 -1
  134. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js +1 -1
  135. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js.map +1 -1
  136. package/web/.next/server/chunks/ssr/[root-of-the-server]__ba7f5873._.js +1 -1
  137. package/web/.next/server/chunks/ssr/[root-of-the-server]__ba7f5873._.js.map +1 -1
  138. package/web/.next/server/chunks/ssr/[root-of-the-server]__c5e09f6f._.js +1 -1
  139. package/web/.next/server/chunks/ssr/[root-of-the-server]__c5e09f6f._.js.map +1 -1
  140. package/web/.next/server/chunks/ssr/[root-of-the-server]__fa525872._.js +3 -0
  141. package/web/.next/server/chunks/ssr/[root-of-the-server]__fa525872._.js.map +1 -0
  142. package/web/.next/server/chunks/ssr/{_d9c0a97a._.js → _0020fddd._.js} +3 -3
  143. package/web/.next/server/chunks/ssr/_0020fddd._.js.map +1 -0
  144. package/web/.next/server/chunks/ssr/_02e01240._.js +1 -1
  145. package/web/.next/server/chunks/ssr/_02e01240._.js.map +1 -1
  146. package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
  147. package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
  148. package/web/.next/server/chunks/ssr/_068492bf._.js +3 -0
  149. package/web/.next/server/chunks/ssr/_068492bf._.js.map +1 -0
  150. package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
  151. package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
  152. package/web/.next/server/chunks/ssr/_1879404a._.js +1 -1
  153. package/web/.next/server/chunks/ssr/_18886033._.js +1 -1
  154. package/web/.next/server/chunks/ssr/_18886033._.js.map +1 -1
  155. package/web/.next/server/chunks/ssr/_1b7dae9a._.js +1 -1
  156. package/web/.next/server/chunks/ssr/_22e00a14._.js +1 -1
  157. package/web/.next/server/chunks/ssr/_22e00a14._.js.map +1 -1
  158. package/web/.next/server/chunks/ssr/_43ba79e7._.js +1 -1
  159. package/web/.next/server/chunks/ssr/_4cbb7f95._.js +1 -1
  160. package/web/.next/server/chunks/ssr/_4cbb7f95._.js.map +1 -1
  161. package/web/.next/server/chunks/ssr/{_295fffde._.js → _5119a3df._.js} +2 -2
  162. package/web/.next/server/chunks/ssr/_5119a3df._.js.map +1 -0
  163. package/web/.next/server/chunks/ssr/_560f2971._.js +3 -0
  164. package/web/.next/server/chunks/ssr/_560f2971._.js.map +1 -0
  165. package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
  166. package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
  167. package/web/.next/server/chunks/ssr/{_49b8d085._.js → _6f35fb9a._.js} +2 -2
  168. package/web/.next/server/chunks/ssr/{_49b8d085._.js.map → _6f35fb9a._.js.map} +1 -1
  169. package/web/.next/server/chunks/ssr/{_a7c67d12._.js → _817ddf8a._.js} +3 -3
  170. package/web/.next/server/chunks/ssr/{_a7c67d12._.js.map → _817ddf8a._.js.map} +1 -1
  171. package/web/.next/server/chunks/ssr/_a5a5901d._.js +1 -1
  172. package/web/.next/server/chunks/ssr/_a5a5901d._.js.map +1 -1
  173. package/web/.next/server/chunks/ssr/_a963dd3c._.js +3 -0
  174. package/web/.next/server/chunks/ssr/_a963dd3c._.js.map +1 -0
  175. package/web/.next/server/chunks/ssr/_ad09f271._.js +1 -1
  176. package/web/.next/server/chunks/ssr/_ad09f271._.js.map +1 -1
  177. package/web/.next/server/chunks/ssr/_bb09579b._.js +1 -1
  178. package/web/.next/server/chunks/ssr/_c3f595c6._.js +1 -1
  179. package/web/.next/server/chunks/ssr/_c3f595c6._.js.map +1 -1
  180. package/web/.next/server/chunks/ssr/{_33914ed8._.js → _cd92091d._.js} +3 -3
  181. package/web/.next/server/chunks/ssr/{_33914ed8._.js.map → _cd92091d._.js.map} +1 -1
  182. package/web/.next/server/chunks/ssr/_df737cce._.js +3 -0
  183. package/web/.next/server/chunks/ssr/_df737cce._.js.map +1 -0
  184. package/web/.next/server/chunks/ssr/_e3f14907._.js +9 -0
  185. package/web/.next/server/chunks/ssr/_e3f14907._.js.map +1 -0
  186. package/web/.next/server/chunks/ssr/_ea9e1556._.js +1 -1
  187. package/web/.next/server/chunks/ssr/_ea9e1556._.js.map +1 -1
  188. package/web/.next/server/chunks/ssr/_f1ba9be6._.js +2 -2
  189. package/web/.next/server/chunks/ssr/_f1ba9be6._.js.map +1 -1
  190. package/web/.next/server/chunks/ssr/_f33cd07e._.js +2 -2
  191. package/web/.next/server/chunks/ssr/_f33cd07e._.js.map +1 -1
  192. package/web/.next/server/chunks/ssr/_f535d854._.js +3 -0
  193. package/web/.next/server/chunks/ssr/_f535d854._.js.map +1 -0
  194. package/web/.next/server/chunks/ssr/_f8b45233._.js +1 -1
  195. package/web/.next/server/chunks/ssr/_f8b45233._.js.map +1 -1
  196. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  197. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  198. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_global-chat-drawer-client_tsx_158c4b12._.js +1 -1
  199. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +1 -1
  200. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js.map +1 -1
  201. package/web/.next/server/chunks/ssr/node_modules__pnpm_1300ae39._.js +3 -0
  202. package/web/.next/server/chunks/ssr/node_modules__pnpm_1300ae39._.js.map +1 -0
  203. package/web/.next/server/chunks/ssr/node_modules__pnpm_ef15a0bd._.js +1 -1
  204. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  205. package/web/.next/server/chunks/ssr/src_presentation_web_app_features_feature-tree-page-client_tsx_34c5cbbf._.js +2 -2
  206. package/web/.next/server/chunks/ssr/src_presentation_web_app_features_feature-tree-page-client_tsx_34c5cbbf._.js.map +1 -1
  207. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js +1 -1
  208. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js.map +1 -1
  209. package/web/.next/server/chunks/ssr/src_presentation_web_components_a5e6c910._.js +1 -1
  210. package/web/.next/server/chunks/ssr/src_presentation_web_components_common_page-header_index_ts_bdf4db0b._.js +3 -0
  211. package/web/.next/server/chunks/ssr/src_presentation_web_components_common_page-header_index_ts_bdf4db0b._.js.map +1 -0
  212. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  213. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  214. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js +1 -1
  215. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js.map +1 -1
  216. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_3d0aa70c._.js +1 -1
  217. package/web/.next/server/chunks/ssr/src_presentation_web_components_ui_select_tsx_45d6b8ae._.js +1 -1
  218. package/web/.next/server/middleware-build-manifest.js +2 -2
  219. package/web/.next/server/pages/500.html +2 -2
  220. package/web/.next/server/server-reference-manifest.js +1 -1
  221. package/web/.next/server/server-reference-manifest.json +50 -50
  222. package/web/.next/static/chunks/{340211816c5ccbf2.js → 0658f5f58d5b60c5.js} +1 -1
  223. package/web/.next/static/chunks/{eb1ca1b0a34166f5.js → 185e4f36cb6efb24.js} +1 -1
  224. package/web/.next/static/chunks/3e393d6a78b2ade4.js +1 -0
  225. package/web/.next/static/chunks/{0adeadd9c2efe8b8.js → 4161d4663009140f.js} +1 -1
  226. package/web/.next/static/chunks/{f4dfbddf21c51466.js → 453ad57269a1004f.js} +1 -1
  227. package/web/.next/static/chunks/4559a403ee40dd19.js +7 -0
  228. package/web/.next/static/chunks/4855528484f00bd6.js +1 -0
  229. package/web/.next/static/chunks/4bacc77e3952f063.js +3 -0
  230. package/web/.next/static/chunks/{9b06cff6369a2770.js → 51bb2fb93740d2cb.js} +2 -2
  231. package/web/.next/static/chunks/5ed47e998707b519.js +8 -0
  232. package/web/.next/static/chunks/641583aadf11b219.js +1 -0
  233. package/web/.next/static/chunks/{0882a91d7ba15dd1.js → 819d8097ac0ca319.js} +1 -1
  234. package/web/.next/static/chunks/{c924cd415dd202cd.js → 96b63a24ad83be21.js} +1 -1
  235. package/web/.next/static/chunks/9f59ea29d6034111.js +1 -0
  236. package/web/.next/static/chunks/{d4a4c939efe5a616.js → a1f976e9c8b07306.js} +1 -1
  237. package/web/.next/static/chunks/{8a6dd3c312b18598.js → ab5970241b29b648.js} +2 -2
  238. package/web/.next/static/chunks/{c3422228c37e20f4.js → bb5400da64270df6.js} +1 -1
  239. package/web/.next/static/chunks/cc5fe8d1d9e1e519.js +5 -0
  240. package/web/.next/static/chunks/d5366257d6b9f855.js +1 -0
  241. package/web/.next/static/chunks/dcf8bb4389557a76.css +1 -0
  242. package/web/.next/static/chunks/{daec84bc4ab71d84.js → e5c06df7f30a05b9.js} +1 -1
  243. package/web/.next/static/chunks/f37a5e031a5d0f75.js +1 -0
  244. package/web/.next/static/chunks/f998b42b5cddafd6.js +1 -0
  245. package/web/.next/static/chunks/{turbopack-fa58b7ea4a4b26e7.js → turbopack-b38a68b1b1c41a87.js} +1 -1
  246. package/web/.next/server/chunks/ssr/[root-of-the-server]__22d17c66._.js +0 -3
  247. package/web/.next/server/chunks/ssr/[root-of-the-server]__22d17c66._.js.map +0 -1
  248. package/web/.next/server/chunks/ssr/_073183f4._.js +0 -3
  249. package/web/.next/server/chunks/ssr/_073183f4._.js.map +0 -1
  250. package/web/.next/server/chunks/ssr/_0a8bc99c._.js +0 -3
  251. package/web/.next/server/chunks/ssr/_0a8bc99c._.js.map +0 -1
  252. package/web/.next/server/chunks/ssr/_295fffde._.js.map +0 -1
  253. package/web/.next/server/chunks/ssr/_6abfa39e._.js +0 -3
  254. package/web/.next/server/chunks/ssr/_6abfa39e._.js.map +0 -1
  255. package/web/.next/server/chunks/ssr/_7476c702._.js +0 -3
  256. package/web/.next/server/chunks/ssr/_7476c702._.js.map +0 -1
  257. package/web/.next/server/chunks/ssr/_7cb0396e._.js +0 -3
  258. package/web/.next/server/chunks/ssr/_7cb0396e._.js.map +0 -1
  259. package/web/.next/server/chunks/ssr/_d9c0a97a._.js.map +0 -1
  260. package/web/.next/server/chunks/ssr/_e680c57c._.js +0 -9
  261. package/web/.next/server/chunks/ssr/_e680c57c._.js.map +0 -1
  262. package/web/.next/server/chunks/ssr/node_modules__pnpm_63d47a3e._.js +0 -3
  263. package/web/.next/server/chunks/ssr/node_modules__pnpm_63d47a3e._.js.map +0 -1
  264. package/web/.next/server/chunks/ssr/node_modules__pnpm_747b43ac._.js +0 -3
  265. package/web/.next/server/chunks/ssr/node_modules__pnpm_747b43ac._.js.map +0 -1
  266. package/web/.next/static/chunks/46e2693dbc9262fd.js +0 -5
  267. package/web/.next/static/chunks/48aad27b4caaec7e.js +0 -1
  268. package/web/.next/static/chunks/5e00cdbc3e259537.js +0 -8
  269. package/web/.next/static/chunks/8492d8e0b5f9a4e8.js +0 -1
  270. package/web/.next/static/chunks/8cc2ce29be4b44c0.js +0 -1
  271. package/web/.next/static/chunks/98e3a7cf58fc912a.js +0 -1
  272. package/web/.next/static/chunks/aa4f9c4e34b15656.js +0 -7
  273. package/web/.next/static/chunks/b49ab0b290e9342d.js +0 -1
  274. package/web/.next/static/chunks/b5ffb52613747895.js +0 -3
  275. package/web/.next/static/chunks/bcbeb2f3b9727bb4.css +0 -1
  276. package/web/.next/static/chunks/c10c0d6d458453bc.js +0 -1
  277. package/web/.next/static/chunks/fc0232384ec2b48d.js +0 -1
  278. /package/web/.next/static/{BzRZgPVuPJ46QDI4VQ3Q8 → 1awQPFeGEuNwpeu1Kgpxd}/_buildManifest.js +0 -0
  279. /package/web/.next/static/{BzRZgPVuPJ46QDI4VQ3Q8 → 1awQPFeGEuNwpeu1Kgpxd}/_clientMiddlewareManifest.json +0 -0
  280. /package/web/.next/static/{BzRZgPVuPJ46QDI4VQ3Q8 → 1awQPFeGEuNwpeu1Kgpxd}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"feature-tree-page-client.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/features/feature-tree-page-client.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAGd,MAAM,0CAA0C,CAAC;AAelD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAoDD,wBAAgB,qBAAqB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,0BAA0B,2CAuWpF"}
1
+ {"version":3,"file":"feature-tree-page-client.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/features/feature-tree-page-client.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAC;AAG9F,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAED,wBAAgB,qBAAqB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,0BAA0B,2CAkBpF"}
@@ -1,152 +1,13 @@
1
1
  'use client';
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useRouter } from 'next/navigation';
4
- import { useCallback, useState, useMemo } from 'react';
5
- import { Search, SlidersHorizontal, Archive, Inbox, X, ArrowDownAZ, ArrowUpAZ } from 'lucide-react';
4
+ import { useCallback } from 'react';
6
5
  import { FeatureTreeTable } from '../../components/features/feature-tree-table/index.js';
7
6
  import { PageHeader } from '../../components/common/page-header/index.js';
8
- import { EmptyState } from '../../components/common/empty-state/index.js';
9
- import { Input } from '../../components/ui/input.js';
10
- import { Button } from '../../components/ui/button.js';
11
- import { Badge } from '../../components/ui/badge.js';
12
- import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../../components/ui/select.js';
13
- const STATUS_LABELS = {
14
- 'action-needed': 'Action Needed',
15
- 'in-progress': 'In Progress',
16
- pending: 'Pending',
17
- blocked: 'Blocked',
18
- error: 'Error',
19
- done: 'Done',
20
- };
21
- const STATUS_COLORS = {
22
- 'action-needed': 'bg-amber-500/15 text-amber-700 dark:text-amber-400 border-amber-500/20',
23
- 'in-progress': 'bg-blue-500/15 text-blue-700 dark:text-blue-400 border-blue-500/20',
24
- pending: 'bg-slate-500/15 text-slate-700 dark:text-slate-400 border-slate-500/20',
25
- blocked: 'bg-gray-500/15 text-gray-700 dark:text-gray-400 border-gray-500/20',
26
- error: 'bg-red-500/15 text-red-700 dark:text-red-400 border-red-500/20',
27
- done: 'bg-emerald-500/15 text-emerald-700 dark:text-emerald-400 border-emerald-500/20',
28
- };
29
- const GROUP_BY_LABELS = {
30
- repositoryName: 'Repository',
31
- status: 'Status',
32
- lifecycle: 'Lifecycle',
33
- };
34
- const GROUP_BY_OPTIONS = [
35
- { value: '__none__', label: 'No grouping' },
36
- { value: 'repositoryName', label: 'Repository' },
37
- { value: 'status', label: 'Status' },
38
- { value: 'lifecycle', label: 'Lifecycle' },
39
- ];
40
- /** Item sort fields change based on groupBy — exclude the grouped field. */
41
- function getItemSortOptions(groupBy) {
42
- const all = [
43
- { value: 'name', label: 'Name' },
44
- { value: 'repositoryName', label: 'Repository' },
45
- { value: 'status', label: 'Status' },
46
- { value: 'lifecycle', label: 'Lifecycle' },
47
- { value: 'branch', label: 'Branch' },
48
- ];
49
- if (!groupBy)
50
- return all;
51
- return all.filter((o) => o.value !== groupBy);
52
- }
53
- function isArchived(feature) {
54
- return feature.lifecycle === 'Archived';
55
- }
56
7
  export function FeatureTreePageClient({ features, repos }) {
57
8
  const router = useRouter();
58
- // Filter state
59
- const [searchQuery, setSearchQuery] = useState('');
60
- const [statusFilter, setStatusFilter] = useState(null);
61
- const [archiveFilter, setArchiveFilter] = useState('active');
62
- const [repoFilter, setRepoFilter] = useState(null);
63
- const [showAdvanced, setShowAdvanced] = useState(false);
64
- // Group + sort state
65
- const [groupBy, setGroupBy] = useState('repositoryName');
66
- const [groupSortDir, setGroupSortDir] = useState('asc');
67
- const [itemSortField, setItemSortField] = useState('name');
68
- const [itemSortDir, setItemSortDir] = useState('asc');
69
9
  const handleFeatureClick = useCallback((featureId) => {
70
10
  router.push(`/feature/${featureId}/overview`);
71
11
  }, [router]);
72
- const handleGroupByChange = (value) => {
73
- const next = value === '__none__' ? null : value;
74
- setGroupBy(next);
75
- // Reset item sort if current field matches the new groupBy
76
- if (next && itemSortField === next) {
77
- setItemSortField('name');
78
- }
79
- };
80
- // Compute status counts for pills
81
- const statusCounts = useMemo(() => {
82
- const counts = {
83
- 'action-needed': 0,
84
- 'in-progress': 0,
85
- pending: 0,
86
- blocked: 0,
87
- error: 0,
88
- done: 0,
89
- };
90
- for (const f of features) {
91
- counts[f.status]++;
92
- }
93
- return counts;
94
- }, [features]);
95
- // Unique repo names for advanced filter
96
- const repoNames = useMemo(() => {
97
- const names = new Set();
98
- for (const f of features) {
99
- names.add(f.repositoryName);
100
- }
101
- return Array.from(names).sort();
102
- }, [features]);
103
- // Filtered features (sorting handled by table)
104
- const filteredFeatures = useMemo(() => {
105
- const query = searchQuery.toLowerCase();
106
- return features.filter((feature) => {
107
- if (archiveFilter === 'active' && isArchived(feature))
108
- return false;
109
- if (archiveFilter === 'archived' && !isArchived(feature))
110
- return false;
111
- if (statusFilter && feature.status !== statusFilter)
112
- return false;
113
- if (repoFilter && feature.repositoryName !== repoFilter)
114
- return false;
115
- if (query) {
116
- const matchesName = feature.name.toLowerCase().includes(query);
117
- const matchesBranch = feature.branch.toLowerCase().includes(query);
118
- const matchesRepo = feature.repositoryName.toLowerCase().includes(query);
119
- if (!matchesName && !matchesBranch && !matchesRepo)
120
- return false;
121
- }
122
- return true;
123
- });
124
- }, [features, searchQuery, statusFilter, archiveFilter, repoFilter]);
125
- const hasActiveFilters = searchQuery !== '' ||
126
- statusFilter !== null ||
127
- archiveFilter !== 'active' ||
128
- repoFilter !== null;
129
- const clearFilters = () => {
130
- setSearchQuery('');
131
- setStatusFilter(null);
132
- setArchiveFilter('active');
133
- setRepoFilter(null);
134
- };
135
- const archivedCount = useMemo(() => features.filter(isArchived).length, [features]);
136
- const activeCount = features.length - archivedCount;
137
- const itemSortOptions = useMemo(() => getItemSortOptions(groupBy), [groupBy]);
138
- return (_jsxs("div", { "data-testid": "feature-tree-page", className: "flex h-full flex-col gap-4", children: [_jsx(PageHeader, { title: "Inventory", description: "All repositories and features" }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("div", { className: "relative flex-1", children: [_jsx(Search, { className: "text-muted-foreground absolute top-1/2 left-3 size-4 -translate-y-1/2" }), _jsx(Input, { placeholder: "Search by name, branch, or repository...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "ps-9" }), searchQuery ? (_jsx("button", { onClick: () => setSearchQuery(''), className: "text-muted-foreground hover:text-foreground absolute top-1/2 right-3 -translate-y-1/2", children: _jsx(X, { className: "size-4" }) })) : null] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium whitespace-nowrap", children: "Group by:" }), _jsxs(Select, { value: groupBy ?? '__none__', onValueChange: handleGroupByChange, children: [_jsx(SelectTrigger, { className: "w-[150px]", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: GROUP_BY_OPTIONS.map((opt) => (_jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value))) })] })] }), _jsxs(Button, { variant: showAdvanced ? 'secondary' : 'outline', size: "sm", onClick: () => setShowAdvanced((v) => !v), className: "shrink-0", children: [_jsx(SlidersHorizontal, { className: "mr-1.5 size-3.5" }), "Filters"] })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("div", { className: "border-input flex items-center rounded-md border", children: [_jsxs("button", { onClick: () => setArchiveFilter('active'), className: `flex items-center gap-1.5 rounded-l-md px-3 py-1.5 text-xs font-medium transition-colors ${archiveFilter === 'active' ? 'bg-primary text-primary-foreground' : 'hover:bg-muted'}`, children: [_jsx(Inbox, { className: "size-3.5" }), "Active", _jsxs("span", { className: "opacity-70", children: ["(", activeCount, ")"] })] }), _jsxs("button", { onClick: () => setArchiveFilter('archived'), className: `flex items-center gap-1.5 border-x px-3 py-1.5 text-xs font-medium transition-colors ${archiveFilter === 'archived'
139
- ? 'bg-primary text-primary-foreground'
140
- : 'hover:bg-muted'}`, children: [_jsx(Archive, { className: "size-3.5" }), "Archived", _jsxs("span", { className: "opacity-70", children: ["(", archivedCount, ")"] })] }), _jsx("button", { onClick: () => setArchiveFilter('all'), className: `rounded-r-md px-3 py-1.5 text-xs font-medium transition-colors ${archiveFilter === 'all' ? 'bg-primary text-primary-foreground' : 'hover:bg-muted'}`, children: "All" })] }), _jsx("div", { className: "bg-border h-6 w-px" }), _jsx("button", { onClick: () => setStatusFilter(null), className: `rounded-full px-2.5 py-1 text-xs font-medium transition-colors ${statusFilter === null
141
- ? 'bg-foreground text-background'
142
- : 'bg-muted text-muted-foreground hover:bg-muted/80'}`, children: "All Status" }), Object.entries(STATUS_LABELS).map(([status, label]) => {
143
- const count = statusCounts[status];
144
- if (count === 0)
145
- return null;
146
- return (_jsxs("button", { onClick: () => setStatusFilter(statusFilter === status ? null : status), className: `rounded-full px-2.5 py-1 text-xs font-medium transition-colors ${statusFilter === status
147
- ? STATUS_COLORS[status]
148
- : 'bg-muted text-muted-foreground hover:bg-muted/80'}`, children: [label, _jsx("span", { className: "ml-1 opacity-70", children: count })] }, status));
149
- }), hasActiveFilters ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "bg-border h-6 w-px" }), _jsxs(Button, { variant: "ghost", size: "sm", onClick: clearFilters, className: "h-7 text-xs", children: [_jsx(X, { className: "mr-1 size-3" }), "Clear"] })] })) : null] }), groupBy ? (_jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: GROUP_BY_LABELS[groupBy] }), _jsxs(Button, { variant: "outline", size: "sm", className: "h-7 gap-1 text-xs", onClick: () => setGroupSortDir((d) => (d === 'asc' ? 'desc' : 'asc')), children: [groupSortDir === 'asc' ? (_jsx(ArrowDownAZ, { className: "size-3.5" })) : (_jsx(ArrowUpAZ, { className: "size-3.5" })), groupSortDir === 'asc' ? 'A-Z' : 'Z-A'] })] }), _jsx("div", { className: "bg-border h-5 w-px" }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Sort by" }), _jsxs(Select, { value: itemSortField, onValueChange: setItemSortField, children: [_jsx(SelectTrigger, { className: "h-7 w-[120px] text-xs", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: itemSortOptions.map((opt) => (_jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value))) })] }), _jsxs(Button, { variant: "outline", size: "sm", className: "h-7 gap-1 text-xs", onClick: () => setItemSortDir((d) => (d === 'asc' ? 'desc' : 'asc')), children: [itemSortDir === 'asc' ? (_jsx(ArrowDownAZ, { className: "size-3.5" })) : (_jsx(ArrowUpAZ, { className: "size-3.5" })), itemSortDir === 'asc' ? 'A-Z' : 'Z-A'] })] })] })) : null, showAdvanced ? (_jsx("div", { className: "bg-muted/50 flex flex-wrap items-center gap-3 rounded-lg border p-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Repository" }), _jsxs(Select, { value: repoFilter ?? '__all__', onValueChange: (v) => setRepoFilter(v === '__all__' ? null : v), children: [_jsx(SelectTrigger, { className: "h-8 w-[200px] text-xs", children: _jsx(SelectValue, { placeholder: "All repositories" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "__all__", children: "All repositories" }), repoNames.map((name) => (_jsx(SelectItem, { value: name, children: name }, name)))] })] })] }) })) : null] }), _jsxs("div", { className: "text-muted-foreground flex items-center gap-2 text-xs", children: [_jsxs("span", { children: [filteredFeatures.length, " feature", filteredFeatures.length !== 1 ? 's' : ''] }), hasActiveFilters ? (_jsx(Badge, { variant: "secondary", className: "text-xs", children: "filtered" })) : null] }), _jsx("div", { className: "min-h-0 flex-1", children: filteredFeatures.length > 0 ? (_jsx(FeatureTreeTable, { data: filteredFeatures, repos: repos, onFeatureClick: handleFeatureClick, groupBy: groupBy, groupSortDir: groupSortDir, itemSortField: itemSortField, itemSortDir: itemSortDir })) : (_jsx(EmptyState, { icon: _jsx(Search, { className: "size-10" }), title: "No matching features", description: hasActiveFilters
150
- ? 'No features match your current filters. Try adjusting your search or filters.'
151
- : 'No features found in any repository.', action: hasActiveFilters ? (_jsx(Button, { variant: "outline", onClick: clearFilters, children: "Clear all filters" })) : undefined })) })] }));
12
+ return (_jsxs("div", { "data-testid": "feature-tree-page", className: "flex h-full flex-col gap-4", children: [_jsx(PageHeader, { title: "Inventory", description: "All repositories and features" }), _jsx("div", { className: "min-h-0 flex-1", children: _jsx(FeatureTreeTable, { data: features, repos: repos, onFeatureClick: handleFeatureClick }) })] }));
152
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"get-feature-tree-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/features/get-feature-tree-data.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAI/E,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsBD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC;IAClD,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB,CAAC,CAmCD"}
1
+ {"version":3,"file":"get-feature-tree-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/features/get-feature-tree-data.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAI/E,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsBD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC;IAClD,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB,CAAC,CAgCD"}
@@ -21,10 +21,7 @@ function lifecycleToStatus(lifecycle) {
21
21
  export async function getFeatureTreeData() {
22
22
  const listFeatures = resolve('ListFeaturesUseCase');
23
23
  const listRepos = resolve('ListRepositoriesUseCase');
24
- const [features, repositories] = await Promise.all([
25
- listFeatures.execute({ includeArchived: true }),
26
- listRepos.execute(),
27
- ]);
24
+ const [features, repositories] = await Promise.all([listFeatures.execute(), listRepos.execute()]);
28
25
  const repoByPath = new Map();
29
26
  for (const repo of repositories) {
30
27
  repoByPath.set(repo.path, { name: repo.name, remoteUrl: repo.remoteUrl });
@@ -8,5 +8,5 @@ export function RepoGroup({ repoName, featureCount, children, defaultOpen = true
8
8
  return (_jsxs("div", { "data-testid": "repo-group", className: "group/repo mb-1", children: [_jsxs("div", { className: "flex items-center", children: [_jsxs("button", { type: "button", onClick: () => setOpen(!open), className: cn('text-sidebar-foreground hover:bg-sidebar-accent flex min-w-0 flex-1 items-center gap-1.5 rounded-md px-2 py-1.5 text-left text-xs font-semibold', 'transition-colors duration-100'), "aria-expanded": open, children: [_jsx(ChevronDown, { className: cn('text-muted-foreground h-3.5 w-3.5 shrink-0 transition-transform duration-200', !open && '-rotate-90') }), _jsx(GitFork, { className: "text-muted-foreground h-3.5 w-3.5 shrink-0" }), _jsx("span", { className: "min-w-0 flex-1 truncate", children: repoName }), _jsx("span", { "aria-label": `${featureCount} features`, className: "bg-sidebar-accent text-sidebar-accent-foreground ml-auto inline-flex h-4 min-w-4 shrink-0 items-center justify-center rounded-full px-1 text-[0.6rem] font-medium tabular-nums", role: "img", children: featureCount })] }), onAddFeature ? (_jsx("button", { type: "button", "data-testid": "repo-add-feature", onClick: (e) => {
9
9
  e.stopPropagation();
10
10
  onAddFeature();
11
- }, className: cn('text-muted-foreground hover:text-sidebar-foreground hover:bg-sidebar-accent shrink-0 rounded-md p-1 opacity-0 transition-all duration-100 group-hover/repo:opacity-100', 'focus-visible:ring-ring focus-visible:opacity-100 focus-visible:ring-1 focus-visible:outline-none'), "aria-label": `Add feature to ${repoName}`, children: _jsx(Plus, { className: "h-3.5 w-3.5" }) })) : null] }), open ? _jsx("div", { className: "pl-2", children: children }) : null] }));
11
+ }, className: cn('text-muted-foreground hover:text-sidebar-foreground hover:bg-sidebar-accent mr-2 shrink-0 rounded-md p-1 opacity-0 transition-all duration-100 group-hover/repo:opacity-100', 'focus-visible:ring-ring focus-visible:opacity-100 focus-visible:ring-1 focus-visible:outline-none'), "aria-label": `Add feature to ${repoName}`, children: _jsx(Plus, { className: "h-3.5 w-3.5" }) })) : null] }), open ? _jsx("div", { className: "pl-2", children: children }) : null] }));
12
12
  }
@@ -9,42 +9,28 @@ export interface FeatureTreeRow {
9
9
  repositoryName: string;
10
10
  remoteUrl?: string;
11
11
  parentId?: string;
12
- /** Internal: child rows for tree hierarchy */
12
+ /** Child rows for tree hierarchy */
13
13
  _children?: FeatureTreeRow[];
14
- /** Internal: whether this row is a group header */
15
- _isGroupHeader?: boolean;
16
- /** Internal: number of features in this group */
17
- _groupCount?: number;
18
- /** Internal: whether this row is a repository group header (legacy tree) */
14
+ /** Whether this row is a repository group header */
19
15
  _isRepoGroup?: boolean;
20
- /** Internal: number of features in this repo group (legacy tree) */
16
+ /** Number of features in this repo group */
21
17
  _featureCount?: number;
22
18
  }
23
19
  export interface InventoryRepo {
24
20
  name: string;
25
21
  remoteUrl?: string;
26
22
  }
27
- export type GroupByField = 'repositoryName' | 'status' | 'lifecycle';
28
- export type SortDir = 'asc' | 'desc';
29
23
  export interface FeatureTreeTableProps {
30
24
  data: FeatureTreeRow[];
31
25
  repos?: InventoryRepo[];
32
26
  className?: string;
33
27
  onFeatureClick?: (featureId: string) => void;
34
- /** When set, features are grouped into a tree by this field. */
35
- groupBy?: GroupByField | null;
36
- /** Sort direction for group headers. */
37
- groupSortDir?: SortDir;
38
- /** Field to sort items within each group (or globally in flat mode). */
39
- itemSortField?: string;
40
- /** Sort direction for items. */
41
- itemSortDir?: SortDir;
42
28
  }
43
29
  /**
44
- * Build tree-structured data grouped by repository (legacy format).
30
+ * Build tree-structured data grouped by repository.
45
31
  * Each repository becomes a parent node with its features as children.
46
32
  * Repos without features are included as empty groups.
47
33
  */
48
34
  export declare function buildTreeData(flatData: FeatureTreeRow[], repos?: InventoryRepo[]): FeatureTreeRow[];
49
- export declare function FeatureTreeTable({ data, className, onFeatureClick, groupBy, groupSortDir, itemSortField, itemSortDir, }: FeatureTreeTableProps): import("react/jsx-runtime").JSX.Element;
35
+ export declare function FeatureTreeTable({ data, repos, className, onFeatureClick, }: FeatureTreeTableProps): import("react/jsx-runtime").JSX.Element;
50
36
  //# sourceMappingURL=feature-tree-table.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature-tree-table.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/feature-tree-table/feature-tree-table.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAC/E,OAAO,0BAA0B,CAAC;AAElC,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,mDAAmD;IACnD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,QAAQ,GAAG,WAAW,CAAC;AACrE,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAErC,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,gEAAgE;IAChE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,wCAAwC;IACxC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gCAAgC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAsJD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,cAAc,EAAE,EAC1B,KAAK,CAAC,EAAE,aAAa,EAAE,GACtB,cAAc,EAAE,CAkDlB;AA0DD,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,SAAS,EACT,cAAc,EACd,OAAc,EACd,YAAoB,EACpB,aAAsB,EACtB,WAAmB,GACpB,EAAE,qBAAqB,2CAyDvB"}
1
+ {"version":3,"file":"feature-tree-table.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/feature-tree-table/feature-tree-table.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAC/E,OAAO,0BAA0B,CAAC;AAElC,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,oDAAoD;IACpD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,4CAA4C;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AA+FD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,cAAc,EAAE,EAC1B,KAAK,CAAC,EAAE,aAAa,EAAE,GACtB,cAAc,EAAE,CAmElB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,KAAK,EACL,SAAS,EACT,cAAc,GACf,EAAE,qBAAqB,2CAgDvB"}
@@ -4,7 +4,6 @@ import { useEffect, useRef, useCallback } from 'react';
4
4
  import { TabulatorFull as Tabulator } from 'tabulator-tables';
5
5
  import { cn } from '../../../lib/utils.js';
6
6
  import './feature-tree-table.css';
7
- // ── Constants ────────────────────────────────────────────────
8
7
  const STATUS_LABELS = {
9
8
  'action-needed': 'Action Needed',
10
9
  'in-progress': 'In Progress',
@@ -13,155 +12,119 @@ const STATUS_LABELS = {
13
12
  error: 'Error',
14
13
  done: 'Done',
15
14
  };
16
- /** SVG repo icon — lucide FolderGit2 (16px) */
17
- const REPO_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"/><circle cx="12" cy="13" r="2"/><path d="M14 13h3"/><path d="M7 13h3"/></svg>`;
18
- /** SVG group icon — lucide Layers (16px) */
19
- const GROUP_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z"/><path d="m22.54 12.43-1.42-.65-8.28 3.78a2 2 0 0 1-1.66 0l-8.28-3.78-1.42.65a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z"/></svg>`;
20
- // ── Formatters ───────────────────────────────────────────────
21
- function escapeHtml(text) {
22
- const div = typeof document !== 'undefined' ? document.createElement('div') : null;
23
- if (div) {
24
- div.textContent = text;
25
- return div.innerHTML;
26
- }
27
- return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
28
- }
15
+ /** SVG repo icon — lucide FolderGit2 */
16
+ const REPO_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"/><circle cx="12" cy="13" r="2"/><path d="M14 13h3"/><path d="M7 13h3"/></svg>`;
29
17
  function statusFormatter(cell) {
30
18
  const row = cell.getRow().getData();
31
- if (row._isGroupHeader)
19
+ if (row._isRepoGroup)
32
20
  return '';
33
21
  const value = cell.getValue();
34
22
  const label = STATUS_LABELS[value] ?? value;
35
23
  return `<span class="status-pill status-pill--${value}"><span class="status-dot"></span>${label}</span>`;
36
24
  }
37
- function branchFormatter(cell) {
25
+ function nameFormatter(cell) {
38
26
  const row = cell.getRow().getData();
39
- if (row._isGroupHeader)
40
- return '';
41
- const val = cell.getValue();
42
- if (!val)
43
- return '';
44
- return `<code style="font-size:12px;color:var(--color-muted-foreground,#64748b);font-family:var(--font-mono)">${escapeHtml(val)}</code>`;
45
- }
46
- function lifecycleFormatter(cell) {
47
- const row = cell.getRow().getData();
48
- if (row._isGroupHeader)
49
- return '';
27
+ if (row._isRepoGroup) {
28
+ const count = row._featureCount ?? 0;
29
+ const countLabel = count === 0 ? 'No features' : count === 1 ? '1 Feature' : `${count} Features`;
30
+ const remoteLabel = row.remoteUrl
31
+ ? `<span class="repo-remote-url">${escapeHtml(row.remoteUrl)}</span>`
32
+ : '';
33
+ return `<span class="repo-name-cell">${REPO_ICON_SVG}<span class="repo-name-text"><span class="repo-name-primary"><span class="repo-name-title">${escapeHtml(row.name)}</span><span class="repo-feature-count">${countLabel}</span></span>${remoteLabel}</span></span>`;
34
+ }
50
35
  return escapeHtml(cell.getValue());
51
36
  }
52
- function repoFormatter(cell) {
53
- const row = cell.getRow().getData();
54
- if (row._isGroupHeader)
55
- return '';
56
- const val = cell.getValue();
57
- return `<span style="display:inline-flex;align-items:center;gap:6px">${REPO_ICON_SVG}<span>${escapeHtml(val)}</span></span>`;
58
- }
59
- function groupHeaderNameFormatter(groupBy) {
60
- return (cell) => {
61
- const row = cell.getRow().getData();
62
- if (!row._isGroupHeader)
63
- return escapeHtml(cell.getValue());
64
- const icon = groupBy === 'repositoryName' ? REPO_ICON_SVG : GROUP_ICON_SVG;
65
- const count = row._groupCount ?? 0;
66
- const countLabel = count === 1 ? '1 feature' : `${count} features`;
67
- return `<span style="display:inline-flex;align-items:center;gap:8px;font-weight:600">${icon}<span>${escapeHtml(row.name)}</span><span style="font-weight:400;color:var(--color-muted-foreground,#64748b);font-size:12px">${countLabel}</span></span>`;
68
- };
37
+ function escapeHtml(text) {
38
+ const div = typeof document !== 'undefined' ? document.createElement('div') : null;
39
+ if (div) {
40
+ div.textContent = text;
41
+ return div.innerHTML;
42
+ }
43
+ return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
69
44
  }
70
- /** All possible columns. We'll filter out the grouped-by column in tree mode. */
71
- function buildColumns({ onFeatureClick, groupBy }) {
72
- const clickProps = onFeatureClick
73
- ? {
74
- cellClick: (_e, cell) => {
75
- const data = cell.getRow().getData();
76
- if (data._isGroupHeader)
77
- return;
78
- onFeatureClick(data.id);
79
- },
80
- cssClass: 'cursor-pointer',
81
- }
82
- : {};
83
- const isGrouped = !!groupBy;
84
- const cols = [
45
+ function buildColumns(onFeatureClick) {
46
+ return [
85
47
  {
86
48
  title: 'Name',
87
49
  field: 'name',
88
50
  widthGrow: 3,
89
- headerSort: !isGrouped,
90
- formatter: isGrouped
91
- ? groupHeaderNameFormatter(groupBy)
92
- : (cell) => escapeHtml(cell.getValue()),
93
- ...clickProps,
51
+ formatter: nameFormatter,
52
+ ...(onFeatureClick && {
53
+ cellClick: (_e, cell) => {
54
+ const data = cell.getRow().getData();
55
+ if (data._isRepoGroup)
56
+ return;
57
+ onFeatureClick(data.id);
58
+ },
59
+ cssClass: 'cursor-pointer',
60
+ }),
61
+ },
62
+ {
63
+ title: 'Status',
64
+ field: 'status',
65
+ widthGrow: 1.5,
66
+ formatter: statusFormatter,
67
+ },
68
+ {
69
+ title: 'Lifecycle',
70
+ field: 'lifecycle',
71
+ widthGrow: 1.5,
72
+ formatter: (cell) => {
73
+ const row = cell.getRow().getData();
74
+ if (row._isRepoGroup)
75
+ return '';
76
+ return cell.getValue();
77
+ },
94
78
  },
95
- groupBy !== 'repositoryName'
96
- ? {
97
- title: 'Repository',
98
- field: 'repositoryName',
99
- widthGrow: 2,
100
- headerSort: !isGrouped,
101
- formatter: repoFormatter,
102
- }
103
- : null,
104
- groupBy !== 'status'
105
- ? {
106
- title: 'Status',
107
- field: 'status',
108
- widthGrow: 1.5,
109
- headerSort: !isGrouped,
110
- formatter: statusFormatter,
111
- }
112
- : null,
113
- groupBy !== 'lifecycle'
114
- ? {
115
- title: 'Lifecycle',
116
- field: 'lifecycle',
117
- widthGrow: 1.5,
118
- headerSort: !isGrouped,
119
- formatter: lifecycleFormatter,
120
- }
121
- : null,
122
79
  {
123
80
  title: 'Branch',
124
81
  field: 'branch',
125
82
  widthGrow: 2,
126
- headerSort: !isGrouped,
127
- formatter: branchFormatter,
83
+ formatter: (cell) => {
84
+ const row = cell.getRow().getData();
85
+ if (row._isRepoGroup)
86
+ return '';
87
+ const val = cell.getValue();
88
+ if (!val)
89
+ return '';
90
+ return `<code style="font-size:12px;color:var(--color-muted-foreground,#64748b);font-family:var(--font-mono)">${escapeHtml(val)}</code>`;
91
+ },
128
92
  },
129
93
  ];
130
- return cols.filter(Boolean);
131
- }
132
- // ── Tree builder ─────────────────────────────────────────────
133
- function displayLabel(groupBy, value) {
134
- if (groupBy === 'status')
135
- return STATUS_LABELS[value] ?? value;
136
- return value;
137
94
  }
138
95
  /**
139
- * Build tree-structured data grouped by repository (legacy format).
96
+ * Build tree-structured data grouped by repository.
140
97
  * Each repository becomes a parent node with its features as children.
141
98
  * Repos without features are included as empty groups.
142
99
  */
143
100
  export function buildTreeData(flatData, repos) {
101
+ // Group features by repository
144
102
  const byRepo = new Map();
145
103
  for (const item of flatData) {
146
104
  const repoName = item.repositoryName || 'Unknown';
147
- if (!byRepo.has(repoName))
105
+ if (!byRepo.has(repoName)) {
148
106
  byRepo.set(repoName, []);
107
+ }
149
108
  byRepo.get(repoName).push(item);
150
109
  }
110
+ // Ensure all known repos are represented (even without features)
151
111
  const repoMeta = new Map();
152
112
  if (repos) {
153
113
  for (const repo of repos) {
154
114
  repoMeta.set(repo.name, { remoteUrl: repo.remoteUrl });
155
- if (!byRepo.has(repo.name))
115
+ if (!byRepo.has(repo.name)) {
156
116
  byRepo.set(repo.name, []);
117
+ }
157
118
  }
158
119
  }
159
120
  const roots = [];
160
121
  for (const [repoName, features] of byRepo) {
122
+ // Build parent-child relationships within this repo group
161
123
  const lookup = new Map();
162
124
  const repoChildren = [];
163
- for (const item of features)
125
+ for (const item of features) {
164
126
  lookup.set(item.id, { ...item, _children: [] });
127
+ }
165
128
  for (const item of features) {
166
129
  const node = lookup.get(item.id);
167
130
  if (item.parentId && lookup.has(item.parentId)) {
@@ -171,12 +134,14 @@ export function buildTreeData(flatData, repos) {
171
134
  repoChildren.push(node);
172
135
  }
173
136
  }
137
+ // Clean up empty _children arrays
174
138
  for (const node of lookup.values()) {
175
- if (node._children?.length === 0)
139
+ if (node._children?.length === 0) {
176
140
  delete node._children;
141
+ }
177
142
  }
178
143
  const remoteUrl = repoMeta.get(repoName)?.remoteUrl ?? features[0]?.remoteUrl;
179
- roots.push({
144
+ const repoGroup = {
180
145
  id: `repo-${repoName}`,
181
146
  name: repoName,
182
147
  status: 'pending',
@@ -187,51 +152,12 @@ export function buildTreeData(flatData, repos) {
187
152
  _isRepoGroup: true,
188
153
  _featureCount: features.length,
189
154
  ...(repoChildren.length > 0 ? { _children: repoChildren } : {}),
190
- });
191
- }
192
- return roots;
193
- }
194
- function buildGroupedTree(flatData, groupBy, groupSortDir, itemSortField, itemSortDir) {
195
- // Group features by field value
196
- const groups = new Map();
197
- for (const item of flatData) {
198
- const key = item[groupBy] ?? 'Unknown';
199
- if (!groups.has(key))
200
- groups.set(key, []);
201
- groups.get(key).push(item);
202
- }
203
- // Sort items within each group
204
- const sortItems = (items) => [...items].sort((a, b) => {
205
- const aVal = String(a[itemSortField] ?? '').toLowerCase();
206
- const bVal = String(b[itemSortField] ?? '').toLowerCase();
207
- const cmp = aVal.localeCompare(bVal);
208
- return itemSortDir === 'asc' ? cmp : -cmp;
209
- });
210
- // Build group header rows
211
- const roots = [];
212
- for (const [key, features] of groups) {
213
- const sortedChildren = sortItems(features);
214
- roots.push({
215
- id: `group-${groupBy}-${key}`,
216
- name: displayLabel(groupBy, key),
217
- status: 'pending',
218
- lifecycle: '',
219
- branch: '',
220
- repositoryName: '',
221
- _isGroupHeader: true,
222
- _groupCount: features.length,
223
- _children: sortedChildren,
224
- });
155
+ };
156
+ roots.push(repoGroup);
225
157
  }
226
- // Sort groups
227
- roots.sort((a, b) => {
228
- const cmp = a.name.localeCompare(b.name);
229
- return groupSortDir === 'asc' ? cmp : -cmp;
230
- });
231
158
  return roots;
232
159
  }
233
- // ── Component ────────────────────────────────────────────────
234
- export function FeatureTreeTable({ data, className, onFeatureClick, groupBy = null, groupSortDir = 'asc', itemSortField = 'name', itemSortDir = 'asc', }) {
160
+ export function FeatureTreeTable({ data, repos, className, onFeatureClick, }) {
235
161
  const containerRef = useRef(null);
236
162
  const tabulatorRef = useRef(null);
237
163
  const onFeatureClickRef = useRef(onFeatureClick);
@@ -242,37 +168,29 @@ export function FeatureTreeTable({ data, className, onFeatureClick, groupBy = nu
242
168
  useEffect(() => {
243
169
  if (!containerRef.current)
244
170
  return;
245
- const isGrouped = !!groupBy;
246
- const columns = buildColumns({ onFeatureClick: stableOnFeatureClick, groupBy });
247
- const tableData = isGrouped
248
- ? buildGroupedTree(data, groupBy, groupSortDir, itemSortField, itemSortDir)
249
- : data;
171
+ const treeData = buildTreeData(data, repos);
172
+ const columns = buildColumns(stableOnFeatureClick);
250
173
  const table = new Tabulator(containerRef.current, {
251
- data: tableData,
174
+ data: treeData,
252
175
  columns,
176
+ dataTree: true,
177
+ dataTreeStartExpanded: true,
253
178
  layout: 'fitColumns',
254
179
  height: '100%',
255
- placeholder: 'No features found',
256
- ...(isGrouped
257
- ? {
258
- dataTree: true,
259
- dataTreeStartExpanded: true,
260
- rowFormatter: (row) => {
261
- const rowData = row.getData();
262
- if (rowData._isGroupHeader) {
263
- row.getElement().classList.add('tabulator-row-repo-group');
264
- }
265
- },
180
+ placeholder: 'No repositories found',
181
+ headerSortClickElement: 'icon',
182
+ rowFormatter: (row) => {
183
+ const rowData = row.getData();
184
+ if (rowData._isRepoGroup) {
185
+ row.getElement().classList.add('tabulator-row-repo-group');
266
186
  }
267
- : {
268
- initialSort: [{ column: 'repositoryName', dir: 'asc' }],
269
- }),
187
+ },
270
188
  });
271
189
  tabulatorRef.current = table;
272
190
  return () => {
273
191
  table.destroy();
274
192
  tabulatorRef.current = null;
275
193
  };
276
- }, [data, stableOnFeatureClick, groupBy, groupSortDir, itemSortField, itemSortDir]);
194
+ }, [data, repos, stableOnFeatureClick]);
277
195
  return (_jsx("div", { "data-testid": "feature-tree-table", className: cn('h-full w-full', className), ref: containerRef }));
278
196
  }
@@ -1,3 +1,3 @@
1
1
  export { FeatureTreeTable, buildTreeData } from './feature-tree-table.js';
2
- export type { FeatureTreeTableProps, FeatureTreeRow, InventoryRepo, GroupByField, SortDir, } from './feature-tree-table.js';
2
+ export type { FeatureTreeTableProps, FeatureTreeRow, InventoryRepo } from './feature-tree-table.js';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/feature-tree-table/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACvE,YAAY,EACV,qBAAqB,EACrB,cAAc,EACd,aAAa,EACb,YAAY,EACZ,OAAO,GACR,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/feature-tree-table/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACvE,YAAY,EAAE,qBAAqB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}