@grackle-ai/web-components 0.115.1 → 0.116.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 (55) hide show
  1. package/.rush/temp/chunked-rush-logs/web-components._phase_build.chunks.jsonl +6 -6
  2. package/.rush/temp/chunked-rush-logs/web-components._phase_test.chunks.jsonl +26 -28
  3. package/.rush/temp/{689afee5625b24607e65ba3a6d3b279d5895784d.tar.log → f238c174d295031bec7f186733732e0fd7e4b9a5.tar.log} +55 -60
  4. package/.rush/temp/{689afee5625b24607e65ba3a6d3b279d5895784d.untar.log → f238c174d295031bec7f186733732e0fd7e4b9a5.untar.log} +2 -2
  5. package/.rush/temp/{e12a67384bc67b4cba24253105ba33ed0945c91d.tar.log → f5301e6a84109dcec06242d178df01e555a83456.tar.log} +2 -2
  6. package/.rush/temp/{e12a67384bc67b4cba24253105ba33ed0945c91d.untar.log → f5301e6a84109dcec06242d178df01e555a83456.untar.log} +2 -2
  7. package/.rush/temp/operation/_phase_build/all.log +6 -6
  8. package/.rush/temp/operation/_phase_build/log-chunks.jsonl +6 -6
  9. package/.rush/temp/operation/_phase_build/state.json +1 -1
  10. package/.rush/temp/operation/_phase_test/all.log +26 -28
  11. package/.rush/temp/operation/_phase_test/log-chunks.jsonl +26 -28
  12. package/.rush/temp/operation/_phase_test/state.json +1 -1
  13. package/.rush/temp/shrinkwrap-deps.json +3 -3
  14. package/README.md +2 -2
  15. package/dist/index.css +1 -1
  16. package/dist/index.js +9055 -9498
  17. package/package.json +2 -2
  18. package/rush-logs/web-components._phase_build.cache.log +1 -1
  19. package/rush-logs/web-components._phase_build.log +6 -6
  20. package/rush-logs/web-components._phase_test.cache.log +1 -1
  21. package/rush-logs/web-components._phase_test.log +26 -28
  22. package/src/components/index.ts +0 -3
  23. package/src/components/knowledge/KnowledgeDetailPanel.tsx +1 -4
  24. package/src/components/layout/AppNav.stories.tsx +3 -6
  25. package/src/components/layout/AppNav.tsx +3 -7
  26. package/src/components/layout/BottomStatusBar.tsx +4 -6
  27. package/src/components/lists/index.ts +0 -1
  28. package/src/components/panels/KeyboardShortcutsPanel.tsx +0 -1
  29. package/src/components/panels/index.ts +0 -1
  30. package/src/components/personas/McpToolSelector.stories.tsx +12 -12
  31. package/src/components/tools/ToolCard.stories.tsx +0 -26
  32. package/src/components/tools/ToolCard.tsx +0 -3
  33. package/src/components/tools/ToolSearchCard.stories.tsx +8 -8
  34. package/src/components/tools/WorkpadCard.stories.tsx +5 -5
  35. package/src/components/tools/classifyTool.test.ts +0 -1
  36. package/src/components/tools/classifyTool.ts +2 -7
  37. package/src/context/GrackleContextTypes.ts +1 -3
  38. package/src/hooks/types.ts +1 -44
  39. package/src/index.ts +4 -8
  40. package/src/mocks/MockGrackleProvider.tsx +0 -75
  41. package/src/mocks/mockData.ts +8 -99
  42. package/src/test-utils/storybook-helpers.ts +0 -19
  43. package/src/utils/breadcrumbs.test.ts +0 -43
  44. package/src/utils/breadcrumbs.ts +1 -37
  45. package/src/utils/navigation.ts +1 -20
  46. package/src/utils/route-config.test.ts +0 -31
  47. package/temp/build/lint/_eslint-5eVG3S6w.json +30 -54
  48. package/src/components/lists/FindingsNav.module.scss +0 -126
  49. package/src/components/lists/FindingsNav.tsx +0 -146
  50. package/src/components/panels/FindingsPanel.module.scss +0 -94
  51. package/src/components/panels/FindingsPanel.stories.tsx +0 -109
  52. package/src/components/panels/FindingsPanel.tsx +0 -76
  53. package/src/components/tools/FindingCard.stories.tsx +0 -124
  54. package/src/components/tools/FindingCard.tsx +0 -178
  55. package/src/utils/findingCategory.ts +0 -33
@@ -7,7 +7,7 @@
7
7
  ],
8
8
  [
9
9
  "hooks/types.ts",
10
- "6V+IhDV8stiaMzUcKy7VtyKchXU=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
10
+ "m51Zk1lQIpucGwfVy6FR3h3fgY0=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
11
11
  ],
12
12
  [
13
13
  "components/chat/ChatInput.tsx",
@@ -35,7 +35,7 @@
35
35
  ],
36
36
  [
37
37
  "utils/navigation.ts",
38
- "Jp9ePlbyKrjkctBaIHNfJR9ed74=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
38
+ "r2wxMfWBuP8JC+9+KsOa4gFpBh0=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
39
39
  ],
40
40
  [
41
41
  "components/dag/DagView.tsx",
@@ -43,7 +43,7 @@
43
43
  ],
44
44
  [
45
45
  "utils/breadcrumbs.ts",
46
- "01B7Zp4kSimlDCt8An2/wIsBcf4=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
46
+ "jDuViJdxWc1LDntrlzNGst9v+9I=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
47
47
  ],
48
48
  [
49
49
  "components/display/Breadcrumbs.tsx",
@@ -75,7 +75,7 @@
75
75
  ],
76
76
  [
77
77
  "components/tools/classifyTool.ts",
78
- "zCwKeypyCXtFIwOKhrIckvsUVxg=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
78
+ "UHgIZJpS1KQqxMilnwj6B1wQndA=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
79
79
  ],
80
80
  [
81
81
  "components/tools/FileReadCard.tsx",
@@ -109,10 +109,6 @@
109
109
  "components/tools/MetadataCard.tsx",
110
110
  "NWbJyX3bfP3OG3+9jOe1+HFbi3Q=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
111
111
  ],
112
- [
113
- "components/tools/FindingCard.tsx",
114
- "2FRwWXuVFOXIse89rzwIVbfymzg=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
115
- ],
116
112
  [
117
113
  "components/tools/TaskCard.tsx",
118
114
  "sqVc0GEvYwSr3DRu+QDV0pnmVuY=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
@@ -143,7 +139,7 @@
143
139
  ],
144
140
  [
145
141
  "components/tools/ToolCard.tsx",
146
- "daOT8+qSG8CTNk+//LXtKNBcFfE=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
142
+ "F25/LsYEd4Um0ztO1SQd1flsOnM=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
147
143
  ],
148
144
  [
149
145
  "utils/grackleHostStyleVariables.ts",
@@ -259,7 +255,7 @@
259
255
  ],
260
256
  [
261
257
  "components/knowledge/KnowledgeDetailPanel.tsx",
262
- "UE+3S8FQQtfPUeKzeUKaXmtFIS0=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
258
+ "EGtOsnPHegxpLvSdtgMkOkdIU94=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
263
259
  ],
264
260
  [
265
261
  "components/knowledge/KnowledgeNav.tsx",
@@ -275,7 +271,7 @@
275
271
  ],
276
272
  [
277
273
  "components/layout/AppNav.tsx",
278
- "tBAiCk8HnPO62b+sMkZudZfg/2A=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
274
+ "j3p0ostGvUwNVMPupwlC87jNqQk=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
279
275
  ],
280
276
  [
281
277
  "components/layout/Sidebar.tsx",
@@ -283,7 +279,7 @@
283
279
  ],
284
280
  [
285
281
  "components/layout/BottomStatusBar.tsx",
286
- "abR/RzTFR2XA3tcqlvqFVk4zABY=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
282
+ "UTSBNPQ6O4hP+NPF6Edw7+cL9vo=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
287
283
  ],
288
284
  [
289
285
  "components/layout/index.ts",
@@ -293,21 +289,9 @@
293
289
  "components/lists/EnvironmentNav.tsx",
294
290
  "oRRUApaILNNGm4fUsKKmx0IjxPM=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
295
291
  ],
296
- [
297
- "utils/time.ts",
298
- "Wl8r+fTBmY94R5H8jpq6p/iZGT4=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
299
- ],
300
- [
301
- "utils/findingCategory.ts",
302
- "dnjMhy9xXLIJxv1iXaqVWr4DChw=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
303
- ],
304
- [
305
- "components/lists/FindingsNav.tsx",
306
- "GhfB/mO1OTCe2uRpEioAxjgumrs=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
307
- ],
308
292
  [
309
293
  "components/lists/index.ts",
310
- "XWUWhgrdOwgqeWQfDmTPrUmo3bc=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
294
+ "nJ8++kbLc+jEt5SHZd/iHSq4r6Y=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
311
295
  ],
312
296
  [
313
297
  "components/lists/listHelpers.tsx",
@@ -337,10 +321,6 @@
337
321
  "components/notifications/UpdateBanner.tsx",
338
322
  "NjuDHYKNwbBHBUKnWPHbKEFKWdo=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
339
323
  ],
340
- [
341
- "components/panels/FindingsPanel.tsx",
342
- "rpT1J0GpABaL/SVjldvaWFeZaig=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
343
- ],
344
324
  [
345
325
  "components/panels/TokensPanel.tsx",
346
326
  "uLI+oG5pRRIhXQhxEftAwRp2RVk=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
@@ -383,7 +363,7 @@
383
363
  ],
384
364
  [
385
365
  "components/panels/index.ts",
386
- "LFZBuksQXheLIU1oaqlGwqgEE9Y=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
366
+ "+ygaeB4lLymCdVVMWmWP1dPEEdg=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
387
367
  ],
388
368
  [
389
369
  "components/panels/EnvironmentEditPanel.tsx",
@@ -391,7 +371,7 @@
391
371
  ],
392
372
  [
393
373
  "components/panels/KeyboardShortcutsPanel.tsx",
394
- "3edi7irlbtgRuyn2M7Xd0UxNLlM=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
374
+ "MkxfEvXLMNhjozpfLvcosnceWAk=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
395
375
  ],
396
376
  [
397
377
  "components/panels/CredentialProvidersPanel.tsx",
@@ -405,6 +385,10 @@
405
385
  "components/personas/McpToolSelector.tsx",
406
386
  "g3vgkMg/8+hg5YDL8N+KNx4ULjY=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
407
387
  ],
388
+ [
389
+ "utils/time.ts",
390
+ "Wl8r+fTBmY94R5H8jpq6p/iZGT4=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
391
+ ],
408
392
  [
409
393
  "components/schedules/ScheduleManager.tsx",
410
394
  "vNCWOw1/b1O6LoeQg7PjIGMeuZk=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
@@ -455,7 +439,7 @@
455
439
  ],
456
440
  [
457
441
  "context/GrackleContextTypes.ts",
458
- "YPk7fC3htfEM7PBKcJ/pyZ6Ydyg=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
442
+ "Hu+mWE0mWLjoZJgcc6kH0rJnmU4=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
459
443
  ],
460
444
  [
461
445
  "context/GrackleContext.ts",
@@ -475,11 +459,11 @@
475
459
  ],
476
460
  [
477
461
  "mocks/mockData.ts",
478
- "rwiDVF97QNZ5XtbVvMH8/1e4gBI=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
462
+ "kbhREjA6iPR+RFsk6TyHECbjFN8=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
479
463
  ],
480
464
  [
481
465
  "mocks/MockGrackleProvider.tsx",
482
- "B09K0oXwGXuyVoPp09f6MYqwzBI=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
466
+ "to2SSz5PviiRBVcdKxmv/VGf45g=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
483
467
  ],
484
468
  [
485
469
  "test-utils/storybook-decorators.tsx",
@@ -487,15 +471,15 @@
487
471
  ],
488
472
  [
489
473
  "test-utils/storybook-helpers.ts",
490
- "n+nWufF72PECxUJTNB8tBG0GaNA=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
474
+ "oubEwNVh66jQ7FJ1dV+bmv0sckk=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
491
475
  ],
492
476
  [
493
477
  "index.ts",
494
- "GBCOSyIvbIWfMykHVFwaig0ddkA=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
478
+ "UyNF82ITEot6wdXX5ij47791vLU=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
495
479
  ],
496
480
  [
497
481
  "components/index.ts",
498
- "rpuVn1SoksaOjODFImQLVYs3P5s=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
482
+ "PN012bsoYDEVz6kTpWsvyTbbHL0=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
499
483
  ],
500
484
  [
501
485
  "components/chat/ChatInput.stories.tsx",
@@ -619,7 +603,7 @@
619
603
  ],
620
604
  [
621
605
  "components/layout/AppNav.stories.tsx",
622
- "Bb31+Z83wts8nmmIRRCzUDj0/q8=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
606
+ "D7HPXDgc0BQ8COtYXhyGKVwFYHQ=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
623
607
  ],
624
608
  [
625
609
  "components/layout/BottomStatusBar.stories.tsx",
@@ -677,10 +661,6 @@
677
661
  "components/panels/EnvironmentEditPanel.stories.tsx",
678
662
  "7eyIsxLgurTbwPgfstBJ5vnYQZc=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
679
663
  ],
680
- [
681
- "components/panels/FindingsPanel.stories.tsx",
682
- "JeX09IZVdp/1qHuJ6nKifaTFvLs=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
683
- ],
684
664
  [
685
665
  "components/panels/KeyboardShortcutsPanel.stories.tsx",
686
666
  "V+OspyHv+PfL/AcNDfxj2yloCzE=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
@@ -707,7 +687,7 @@
707
687
  ],
708
688
  [
709
689
  "components/personas/McpToolSelector.stories.tsx",
710
- "+rD/vgosc2KifD++DqwK+vY57Rc=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
690
+ "jpY49BU8PnYAqwbgHP3B/dqAjMo=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
711
691
  ],
712
692
  [
713
693
  "components/personas/PersonaManager.stories.tsx",
@@ -741,10 +721,6 @@
741
721
  "components/tools/FileReadCard.stories.tsx",
742
722
  "m9vw0TsKsYz8uQgJCqMsox6v2CA=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
743
723
  ],
744
- [
745
- "components/tools/FindingCard.stories.tsx",
746
- "Bce8Y5ir7/4IlXaeCL5BZI1lbkI=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
747
- ],
748
724
  [
749
725
  "components/tools/GenericToolCard.stories.tsx",
750
726
  "VtI6ToSe0HLvcpPLPs0sKVjCfGQ=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
@@ -779,19 +755,19 @@
779
755
  ],
780
756
  [
781
757
  "components/tools/ToolCard.stories.tsx",
782
- "/9ImA/Bi+Ct9rEpT2o89JXKSYZE=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
758
+ "XCnIgt1ct6KkokCRqGZabxJDaWo=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
783
759
  ],
784
760
  [
785
761
  "components/tools/ToolSearchCard.stories.tsx",
786
- "EvEKRb56X6saO9bHpMgb+K4EkRs=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
762
+ "ICmGA9WrDcdJYeZPcBv1d6p1oto=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
787
763
  ],
788
764
  [
789
765
  "components/tools/WorkpadCard.stories.tsx",
790
- "Aws84vcAkLKPhm65P6w3Dm/cgMs=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
766
+ "ATPmSpytLvX4hs+MRSaOSd3hT1k=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
791
767
  ],
792
768
  [
793
769
  "components/tools/classifyTool.test.ts",
794
- "4HueSOEwOC1E1BIjRfTTLw2Cw5c=_orHdc0vDZqoYfD6TIDl1Za3EAL4="
770
+ "U+AU8RQjQebvb2VvTAS+9dXXEwY=_orHdc0vDZqoYfD6TIDl1Za3EAL4="
795
771
  ],
796
772
  [
797
773
  "components/tools/toolCardHelpers.test.ts",
@@ -815,7 +791,7 @@
815
791
  ],
816
792
  [
817
793
  "utils/breadcrumbs.test.ts",
818
- "uvtwd3hxobqtDMQ8hessqUzyrmc=_orHdc0vDZqoYfD6TIDl1Za3EAL4="
794
+ "r1JW41nRuiw/35Qz5p9rGyJdWrg=_orHdc0vDZqoYfD6TIDl1Za3EAL4="
819
795
  ],
820
796
  [
821
797
  "utils/dashboard.test.ts",
@@ -831,7 +807,7 @@
831
807
  ],
832
808
  [
833
809
  "utils/route-config.test.ts",
834
- "AX9zgQvqbwSvAfHCmWgQWq6HiZY=_orHdc0vDZqoYfD6TIDl1Za3EAL4="
810
+ "VAfF7TfoNkwyw47S3L0ebUBE0CM=_orHdc0vDZqoYfD6TIDl1Za3EAL4="
835
811
  ],
836
812
  [
837
813
  "utils/scrollUtils.test.ts",
@@ -846,5 +822,5 @@
846
822
  "tcFLEiIFvYYLO/1jT41tcJ4CIX4=_orHdc0vDZqoYfD6TIDl1Za3EAL4="
847
823
  ]
848
824
  ],
849
- "filesHash": "350HaaMGlV7A3LVA-PY0sQ"
825
+ "filesHash": "fdzO9hSTLfwPLjMg24UcAg"
850
826
  }
@@ -1,126 +0,0 @@
1
- @use '../../styles/mixins' as *;
2
-
3
- .nav {
4
- display: flex;
5
- flex-direction: column;
6
- gap: var(--space-xs);
7
- width: 100%;
8
- padding: var(--space-md);
9
- overflow-y: auto;
10
-
11
- @include mobile {
12
- flex-direction: row;
13
- width: 100%;
14
- min-width: unset;
15
- border-right: none;
16
- border-bottom: 1px solid var(--border-subtle);
17
- overflow-x: auto;
18
- overflow-y: hidden;
19
- padding: var(--space-xs) var(--space-sm);
20
- gap: 0;
21
- flex-wrap: nowrap;
22
- }
23
- }
24
-
25
- .categoryPills {
26
- display: flex;
27
- gap: var(--space-xs);
28
- flex-wrap: wrap;
29
- padding-bottom: var(--space-sm);
30
- border-bottom: 1px solid var(--border-subtle);
31
- margin-bottom: var(--space-xs);
32
- }
33
-
34
- .categoryPill {
35
- font-size: 10px;
36
- font-weight: var(--font-weight-bold);
37
- text-transform: uppercase;
38
- padding: 1px var(--space-xs);
39
- border-radius: var(--radius-full);
40
- background: var(--bg-elevated);
41
- }
42
-
43
- .tab {
44
- display: flex;
45
- align-items: flex-start;
46
- gap: var(--space-sm);
47
- padding: var(--space-sm) var(--space-md);
48
- border: none;
49
- border-left: 3px solid transparent;
50
- border-radius: var(--radius-md);
51
- background: transparent;
52
- color: var(--text-secondary);
53
- font-size: var(--font-size-sm);
54
- font-family: var(--font-ui);
55
- cursor: pointer;
56
- transition: background var(--transition-fast),
57
- color var(--transition-fast),
58
- border-color var(--transition-fast);
59
- text-align: left;
60
- width: 100%;
61
-
62
- &:hover {
63
- background: var(--bg-overlay);
64
- color: var(--text-primary);
65
- }
66
-
67
- &:focus-visible {
68
- outline: 2px solid var(--accent-blue);
69
- outline-offset: -2px;
70
- }
71
-
72
- @include mobile {
73
- border-left: none;
74
- border-bottom: 2px solid transparent;
75
- white-space: nowrap;
76
- flex-shrink: 0;
77
- padding: var(--space-xs) var(--space-sm);
78
- font-size: var(--font-size-xs);
79
- width: auto;
80
- border-radius: 0;
81
- }
82
- }
83
-
84
- .tabActive {
85
- border-left-color: var(--accent-blue);
86
- background: var(--bg-overlay);
87
- color: var(--text-primary);
88
- font-weight: var(--font-weight-medium);
89
-
90
- @include mobile {
91
- border-left-color: transparent;
92
- border-bottom-color: var(--accent-blue);
93
- }
94
- }
95
-
96
- .tabContent {
97
- display: flex;
98
- flex-direction: column;
99
- gap: 2px;
100
- min-width: 0;
101
- }
102
-
103
- .tabLabel {
104
- overflow: hidden;
105
- text-overflow: ellipsis;
106
- white-space: nowrap;
107
- }
108
-
109
- .tabMeta {
110
- font-size: var(--font-size-xs);
111
- color: var(--text-tertiary);
112
- }
113
-
114
- .categoryDot {
115
- flex-shrink: 0;
116
- font-size: var(--font-size-xs);
117
- line-height: 1;
118
- margin-top: 3px;
119
- }
120
-
121
- .empty {
122
- padding: var(--space-md);
123
- font-size: var(--font-size-sm);
124
- color: var(--text-tertiary);
125
- text-align: center;
126
- }
@@ -1,146 +0,0 @@
1
- /**
2
- * Sidebar navigation for the Findings pages.
3
- *
4
- * Displays a list of findings with category pills and relative timestamps.
5
- *
6
- * @module
7
- */
8
-
9
- import { useCallback, useMemo, useRef, type JSX, type KeyboardEvent } from "react";
10
- import { Circle } from "lucide-react";
11
- import { ICON_XS } from "../../utils/iconSize.js";
12
- import { useMatch } from "react-router";
13
- import type { FindingData } from "../../hooks/types.js";
14
- import { findingUrl, useAppNavigate } from "../../utils/navigation.js";
15
- import { formatRelativeTime } from "../../utils/time.js";
16
- import { getCategoryColor } from "../../utils/findingCategory.js";
17
- import styles from "./FindingsNav.module.scss";
18
-
19
- /** Props for the FindingsNav component. */
20
- interface FindingsNavProps {
21
- /** All loaded findings to display. */
22
- findings: FindingData[];
23
- /** Optional workspace ID for scoped navigation. */
24
- workspaceId?: string;
25
- /** Optional environment ID for scoped navigation. */
26
- environmentId?: string;
27
- }
28
-
29
- /** Sidebar nav listing findings with category badges and relative timestamps. */
30
- export function FindingsNav({ findings, workspaceId, environmentId }: FindingsNavProps): JSX.Element {
31
- const navigate = useAppNavigate();
32
- const tabListRef = useRef<HTMLElement>(null);
33
-
34
- // Match both global and workspace-scoped finding detail routes.
35
- const globalMatch = useMatch("/findings/:findingId");
36
- const scopedMatch = useMatch("/environments/:environmentId/workspaces/:workspaceId/findings/:findingId");
37
- const activeFindingId = globalMatch?.params.findingId ?? scopedMatch?.params.findingId;
38
-
39
- /** Unique categories derived from the current findings list. */
40
- const categories = useMemo(() => {
41
- const cats = new Set(findings.map((f) => f.category).filter(Boolean));
42
- return Array.from(cats).sort();
43
- }, [findings]);
44
-
45
- const handleClick = useCallback((findingId: string) => {
46
- navigate(findingUrl(findingId, workspaceId, environmentId));
47
- }, [navigate, workspaceId, environmentId]);
48
-
49
- const handleKeyDown = useCallback((e: KeyboardEvent<HTMLElement>) => {
50
- const buttons = tabListRef.current?.querySelectorAll<HTMLButtonElement>('[role="tab"]');
51
- if (!buttons || buttons.length === 0) {
52
- return;
53
- }
54
- const focusedIndex = Array.from(buttons).findIndex((b) => b === document.activeElement);
55
- const currentIndex = focusedIndex >= 0 ? focusedIndex : findings.findIndex((f) => f.id === activeFindingId);
56
- let nextIndex = currentIndex;
57
-
58
- if (e.key === "ArrowDown" || e.key === "j" || e.key === "J") {
59
- e.preventDefault();
60
- nextIndex = (currentIndex + 1) % buttons.length;
61
- } else if (e.key === "ArrowUp" || e.key === "k" || e.key === "K") {
62
- e.preventDefault();
63
- nextIndex = (currentIndex - 1 + buttons.length) % buttons.length;
64
- } else if (e.key === "Home") {
65
- e.preventDefault();
66
- nextIndex = 0;
67
- } else if (e.key === "End") {
68
- e.preventDefault();
69
- nextIndex = buttons.length - 1;
70
- } else {
71
- return;
72
- }
73
-
74
- if (nextIndex < findings.length) {
75
- navigate(findingUrl(findings[nextIndex].id, workspaceId, environmentId));
76
- }
77
- buttons[nextIndex].focus();
78
- }, [activeFindingId, findings, navigate, workspaceId, environmentId]);
79
-
80
- const focusableId = activeFindingId ?? (findings.length > 0 ? findings[0].id : undefined);
81
-
82
- return (
83
- <div className={styles.nav} data-testid="findings-nav">
84
- {categories.length > 1 && (
85
- <div className={styles.categoryPills} data-testid="findings-nav-categories">
86
- {categories.map((cat) => (
87
- <span
88
- key={cat}
89
- className={styles.categoryPill}
90
- style={{ color: getCategoryColor(cat).text }}
91
- >
92
- {cat}
93
- </span>
94
- ))}
95
- </div>
96
- )}
97
-
98
- <nav
99
- ref={tabListRef}
100
- role="tablist"
101
- aria-orientation="vertical"
102
- aria-label="Findings"
103
- onKeyDown={handleKeyDown}
104
- >
105
- {findings.map((f) => {
106
- const isActive = f.id === activeFindingId;
107
- const isFocusable = f.id === focusableId;
108
- return (
109
- <button
110
- key={f.id}
111
- role="tab"
112
- type="button"
113
- aria-selected={isActive}
114
- tabIndex={isFocusable ? 0 : -1}
115
- className={`${styles.tab} ${isActive ? styles.tabActive : ""}`}
116
- onClick={() => handleClick(f.id)}
117
- data-testid="finding-nav-item"
118
- >
119
- <span
120
- className={styles.categoryDot}
121
- style={{ color: getCategoryColor(f.category).text }}
122
- aria-hidden="true"
123
- >
124
- <Circle size={ICON_XS} fill="currentColor" />
125
- </span>
126
- <span className={styles.tabContent}>
127
- <span className={styles.tabLabel} title={f.title}>
128
- {f.title}
129
- </span>
130
- <span className={styles.tabMeta} title={f.createdAt}>
131
- {formatRelativeTime(f.createdAt)}
132
- </span>
133
- </span>
134
- </button>
135
- );
136
- })}
137
- </nav>
138
-
139
- {findings.length === 0 && (
140
- <div className={styles.empty}>
141
- No findings yet. Agents will post discoveries here.
142
- </div>
143
- )}
144
- </div>
145
- );
146
- }
@@ -1,94 +0,0 @@
1
- @use '../../styles/mixins' as *;
2
-
3
- // =============================================================================
4
- // Findings Panel — workspace findings cards with staggered animation
5
- // =============================================================================
6
-
7
- .container {
8
- padding: var(--space-md);
9
- display: flex;
10
- flex-direction: column;
11
- gap: var(--space-sm);
12
- }
13
-
14
- .emptyState {
15
- padding: var(--space-xl);
16
- color: var(--text-tertiary);
17
- text-align: center;
18
- }
19
-
20
- .card {
21
- @include surface-card;
22
- @include card-hover;
23
- padding: var(--space-md);
24
- }
25
-
26
- .cardClickable {
27
- cursor: pointer;
28
-
29
- &:focus-visible {
30
- outline: 2px solid var(--accent-blue);
31
- outline-offset: 2px;
32
- }
33
- }
34
-
35
- .cardHeader {
36
- display: flex;
37
- align-items: center;
38
- gap: var(--space-sm);
39
- margin-bottom: var(--space-xs);
40
-
41
- @include mobile {
42
- flex-wrap: wrap;
43
- }
44
- }
45
-
46
- .categoryBadge {
47
- border-radius: var(--radius-full);
48
- padding: 2px var(--space-md);
49
- font-size: var(--font-size-xs);
50
- font-weight: var(--font-weight-bold);
51
- text-transform: uppercase;
52
- }
53
-
54
- .findingTitle {
55
- font-weight: var(--font-weight-bold);
56
- color: var(--text-primary);
57
- font-size: var(--font-size-md);
58
- }
59
-
60
- .findingDate {
61
- margin-left: auto;
62
- font-size: var(--font-size-xs);
63
- color: var(--text-tertiary);
64
-
65
- @include mobile {
66
- margin-left: 0;
67
- width: 100%;
68
- }
69
- }
70
-
71
- .findingContent {
72
- font-size: var(--font-size-sm);
73
- color: var(--text-secondary);
74
- white-space: pre-wrap;
75
- }
76
-
77
- .tags {
78
- margin-top: var(--space-xs);
79
- display: flex;
80
- gap: var(--space-xs);
81
-
82
- @include mobile {
83
- flex-wrap: wrap;
84
- }
85
- }
86
-
87
- // Frosted inset chip for tags — third glass tier with category-tinted border
88
- .tag {
89
- @include surface-inset;
90
- font-size: 10px;
91
- padding: 1px var(--space-xs);
92
- border-radius: var(--radius-full);
93
- color: var(--text-secondary);
94
- }