@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.
- package/dist/src/presentation/web/app/features/feature-tree-page-client.d.ts.map +1 -1
- package/dist/src/presentation/web/app/features/feature-tree-page-client.js +3 -142
- package/dist/src/presentation/web/app/features/get-feature-tree-data.d.ts.map +1 -1
- package/dist/src/presentation/web/app/features/get-feature-tree-data.js +1 -4
- package/dist/src/presentation/web/components/common/repo-group/repo-group.js +1 -1
- package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.d.ts +5 -19
- package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.js +87 -169
- package/dist/src/presentation/web/components/features/feature-tree-table/index.d.ts +1 -1
- package/dist/src/presentation/web/components/features/feature-tree-table/index.d.ts.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +4 -4
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +2 -2
- package/web/.next/required-server-files.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +30 -30
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +38 -38
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +38 -38
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/chat/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +30 -30
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +38 -38
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +38 -38
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error/page/build-manifest.json +2 -2
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/build-manifest.json +2 -2
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/features/page/build-manifest.json +2 -2
- package/web/.next/server/app/features/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/features/page.js.nft.json +1 -1
- package/web/.next/server/app/features/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/settings/page/build-manifest.json +2 -2
- package/web/.next/server/app/settings/page/server-reference-manifest.json +9 -9
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/build-manifest.json +2 -2
- package/web/.next/server/app/skills/page/server-reference-manifest.json +13 -13
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/build-manifest.json +2 -2
- package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/build-manifest.json +2 -2
- package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/ssr/403f9_next_dist_a53cb908._.js +1 -1
- package/web/.next/server/chunks/ssr/403f9_next_dist_esm_ceb2fa1e._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +2 -2
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__08c912ab._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__08c912ab._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0c5452c3._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__4fb81977._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__4fb81977._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7dcd0917._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7dcd0917._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__851f6adb._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__86ff0bc5._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__92ffd5ee._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__92ffd5ee._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b020c17d._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b020c17d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ba7f5873._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ba7f5873._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c5e09f6f._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c5e09f6f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fa525872._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fa525872._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{_d9c0a97a._.js → _0020fddd._.js} +3 -3
- package/web/.next/server/chunks/ssr/_0020fddd._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_02e01240._.js +1 -1
- package/web/.next/server/chunks/ssr/_02e01240._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
- package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_068492bf._.js +3 -0
- package/web/.next/server/chunks/ssr/_068492bf._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
- package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_1879404a._.js +1 -1
- package/web/.next/server/chunks/ssr/_18886033._.js +1 -1
- package/web/.next/server/chunks/ssr/_18886033._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_1b7dae9a._.js +1 -1
- package/web/.next/server/chunks/ssr/_22e00a14._.js +1 -1
- package/web/.next/server/chunks/ssr/_22e00a14._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_43ba79e7._.js +1 -1
- package/web/.next/server/chunks/ssr/_4cbb7f95._.js +1 -1
- package/web/.next/server/chunks/ssr/_4cbb7f95._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_295fffde._.js → _5119a3df._.js} +2 -2
- package/web/.next/server/chunks/ssr/_5119a3df._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_560f2971._.js +3 -0
- package/web/.next/server/chunks/ssr/_560f2971._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
- package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_49b8d085._.js → _6f35fb9a._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_49b8d085._.js.map → _6f35fb9a._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_a7c67d12._.js → _817ddf8a._.js} +3 -3
- package/web/.next/server/chunks/ssr/{_a7c67d12._.js.map → _817ddf8a._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_a5a5901d._.js +1 -1
- package/web/.next/server/chunks/ssr/_a5a5901d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_a963dd3c._.js +3 -0
- package/web/.next/server/chunks/ssr/_a963dd3c._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_ad09f271._.js +1 -1
- package/web/.next/server/chunks/ssr/_ad09f271._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_bb09579b._.js +1 -1
- package/web/.next/server/chunks/ssr/_c3f595c6._.js +1 -1
- package/web/.next/server/chunks/ssr/_c3f595c6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_33914ed8._.js → _cd92091d._.js} +3 -3
- package/web/.next/server/chunks/ssr/{_33914ed8._.js.map → _cd92091d._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_df737cce._.js +3 -0
- package/web/.next/server/chunks/ssr/_df737cce._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_e3f14907._.js +9 -0
- package/web/.next/server/chunks/ssr/_e3f14907._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_ea9e1556._.js +1 -1
- package/web/.next/server/chunks/ssr/_ea9e1556._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_f1ba9be6._.js +2 -2
- package/web/.next/server/chunks/ssr/_f1ba9be6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_f33cd07e._.js +2 -2
- package/web/.next/server/chunks/ssr/_f33cd07e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_f535d854._.js +3 -0
- package/web/.next/server/chunks/ssr/_f535d854._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_f8b45233._.js +1 -1
- package/web/.next/server/chunks/ssr/_f8b45233._.js.map +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_global-chat-drawer-client_tsx_158c4b12._.js +1 -1
- package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +1 -1
- package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js.map +1 -1
- package/web/.next/server/chunks/ssr/node_modules__pnpm_1300ae39._.js +3 -0
- package/web/.next/server/chunks/ssr/node_modules__pnpm_1300ae39._.js.map +1 -0
- package/web/.next/server/chunks/ssr/node_modules__pnpm_ef15a0bd._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_features_feature-tree-page-client_tsx_34c5cbbf._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_app_features_feature-tree-page-client_tsx_34c5cbbf._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_a5e6c910._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_common_page-header_index_ts_bdf4db0b._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_components_common_page-header_index_ts_bdf4db0b._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_3d0aa70c._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_ui_select_tsx_45d6b8ae._.js +1 -1
- package/web/.next/server/middleware-build-manifest.js +2 -2
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +50 -50
- package/web/.next/static/chunks/{340211816c5ccbf2.js → 0658f5f58d5b60c5.js} +1 -1
- package/web/.next/static/chunks/{eb1ca1b0a34166f5.js → 185e4f36cb6efb24.js} +1 -1
- package/web/.next/static/chunks/3e393d6a78b2ade4.js +1 -0
- package/web/.next/static/chunks/{0adeadd9c2efe8b8.js → 4161d4663009140f.js} +1 -1
- package/web/.next/static/chunks/{f4dfbddf21c51466.js → 453ad57269a1004f.js} +1 -1
- package/web/.next/static/chunks/4559a403ee40dd19.js +7 -0
- package/web/.next/static/chunks/4855528484f00bd6.js +1 -0
- package/web/.next/static/chunks/4bacc77e3952f063.js +3 -0
- package/web/.next/static/chunks/{9b06cff6369a2770.js → 51bb2fb93740d2cb.js} +2 -2
- package/web/.next/static/chunks/5ed47e998707b519.js +8 -0
- package/web/.next/static/chunks/641583aadf11b219.js +1 -0
- package/web/.next/static/chunks/{0882a91d7ba15dd1.js → 819d8097ac0ca319.js} +1 -1
- package/web/.next/static/chunks/{c924cd415dd202cd.js → 96b63a24ad83be21.js} +1 -1
- package/web/.next/static/chunks/9f59ea29d6034111.js +1 -0
- package/web/.next/static/chunks/{d4a4c939efe5a616.js → a1f976e9c8b07306.js} +1 -1
- package/web/.next/static/chunks/{8a6dd3c312b18598.js → ab5970241b29b648.js} +2 -2
- package/web/.next/static/chunks/{c3422228c37e20f4.js → bb5400da64270df6.js} +1 -1
- package/web/.next/static/chunks/cc5fe8d1d9e1e519.js +5 -0
- package/web/.next/static/chunks/d5366257d6b9f855.js +1 -0
- package/web/.next/static/chunks/dcf8bb4389557a76.css +1 -0
- package/web/.next/static/chunks/{daec84bc4ab71d84.js → e5c06df7f30a05b9.js} +1 -1
- package/web/.next/static/chunks/f37a5e031a5d0f75.js +1 -0
- package/web/.next/static/chunks/f998b42b5cddafd6.js +1 -0
- package/web/.next/static/chunks/{turbopack-fa58b7ea4a4b26e7.js → turbopack-b38a68b1b1c41a87.js} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__22d17c66._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__22d17c66._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_073183f4._.js +0 -3
- package/web/.next/server/chunks/ssr/_073183f4._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0a8bc99c._.js +0 -3
- package/web/.next/server/chunks/ssr/_0a8bc99c._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_295fffde._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_6abfa39e._.js +0 -3
- package/web/.next/server/chunks/ssr/_6abfa39e._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_7476c702._.js +0 -3
- package/web/.next/server/chunks/ssr/_7476c702._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_7cb0396e._.js +0 -3
- package/web/.next/server/chunks/ssr/_7cb0396e._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_d9c0a97a._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_e680c57c._.js +0 -9
- package/web/.next/server/chunks/ssr/_e680c57c._.js.map +0 -1
- package/web/.next/server/chunks/ssr/node_modules__pnpm_63d47a3e._.js +0 -3
- package/web/.next/server/chunks/ssr/node_modules__pnpm_63d47a3e._.js.map +0 -1
- package/web/.next/server/chunks/ssr/node_modules__pnpm_747b43ac._.js +0 -3
- package/web/.next/server/chunks/ssr/node_modules__pnpm_747b43ac._.js.map +0 -1
- package/web/.next/static/chunks/46e2693dbc9262fd.js +0 -5
- package/web/.next/static/chunks/48aad27b4caaec7e.js +0 -1
- package/web/.next/static/chunks/5e00cdbc3e259537.js +0 -8
- package/web/.next/static/chunks/8492d8e0b5f9a4e8.js +0 -1
- package/web/.next/static/chunks/8cc2ce29be4b44c0.js +0 -1
- package/web/.next/static/chunks/98e3a7cf58fc912a.js +0 -1
- package/web/.next/static/chunks/aa4f9c4e34b15656.js +0 -7
- package/web/.next/static/chunks/b49ab0b290e9342d.js +0 -1
- package/web/.next/static/chunks/b5ffb52613747895.js +0 -3
- package/web/.next/static/chunks/bcbeb2f3b9727bb4.css +0 -1
- package/web/.next/static/chunks/c10c0d6d458453bc.js +0 -1
- package/web/.next/static/chunks/fc0232384ec2b48d.js +0 -1
- /package/web/.next/static/{BzRZgPVuPJ46QDI4VQ3Q8 → 1awQPFeGEuNwpeu1Kgpxd}/_buildManifest.js +0 -0
- /package/web/.next/static/{BzRZgPVuPJ46QDI4VQ3Q8 → 1awQPFeGEuNwpeu1Kgpxd}/_clientMiddlewareManifest.json +0 -0
- /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":"
|
|
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
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useRouter } from 'next/navigation';
|
|
4
|
-
import { useCallback
|
|
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
|
-
|
|
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,
|
|
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
|
}
|
package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.d.ts
CHANGED
|
@@ -9,42 +9,28 @@ export interface FeatureTreeRow {
|
|
|
9
9
|
repositoryName: string;
|
|
10
10
|
remoteUrl?: string;
|
|
11
11
|
parentId?: string;
|
|
12
|
-
/**
|
|
12
|
+
/** Child rows for tree hierarchy */
|
|
13
13
|
_children?: FeatureTreeRow[];
|
|
14
|
-
/**
|
|
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
|
-
/**
|
|
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
|
|
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,
|
|
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
|
package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.d.ts.map
CHANGED
|
@@ -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,
|
|
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"}
|
package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.js
CHANGED
|
@@ -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
|
|
17
|
-
const REPO_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="
|
|
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, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
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.
|
|
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
|
|
25
|
+
function nameFormatter(cell) {
|
|
38
26
|
const row = cell.getRow().getData();
|
|
39
|
-
if (row.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
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
|
|
53
|
-
const
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
69
44
|
}
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
|
|
127
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
246
|
-
const columns = buildColumns(
|
|
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:
|
|
174
|
+
data: treeData,
|
|
252
175
|
columns,
|
|
176
|
+
dataTree: true,
|
|
177
|
+
dataTreeStartExpanded: true,
|
|
253
178
|
layout: 'fitColumns',
|
|
254
179
|
height: '100%',
|
|
255
|
-
placeholder: 'No
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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,
|
|
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
|
|
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,
|
|
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"}
|