@industry-theme/file-city-panel 0.2.11 → 0.2.13

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.
@@ -106,7 +106,7 @@ const createLucideIcon = (iconName, iconNode) => {
106
106
  * This source code is licensed under the ISC license.
107
107
  * See the LICENSE file in the root directory of this source tree.
108
108
  */
109
- const __iconNode$6 = [
109
+ const __iconNode$5 = [
110
110
  [
111
111
  "path",
112
112
  {
@@ -115,14 +115,14 @@ const __iconNode$6 = [
115
115
  }
116
116
  ]
117
117
  ];
118
- const Activity = createLucideIcon("activity", __iconNode$6);
118
+ const Activity = createLucideIcon("activity", __iconNode$5);
119
119
  /**
120
120
  * @license lucide-react v0.552.0 - ISC
121
121
  *
122
122
  * This source code is licensed under the ISC license.
123
123
  * See the LICENSE file in the root directory of this source tree.
124
124
  */
125
- const __iconNode$5 = [
125
+ const __iconNode$4 = [
126
126
  ["path", { d: "M10 12h4", key: "a56b0p" }],
127
127
  ["path", { d: "M10 8h4", key: "1sr2af" }],
128
128
  ["path", { d: "M14 21v-3a2 2 0 0 0-4 0v3", key: "1rgiei" }],
@@ -135,28 +135,20 @@ const __iconNode$5 = [
135
135
  ],
136
136
  ["path", { d: "M6 21V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v16", key: "16ra0t" }]
137
137
  ];
138
- const Building2 = createLucideIcon("building-2", __iconNode$5);
138
+ const Building2 = createLucideIcon("building-2", __iconNode$4);
139
139
  /**
140
140
  * @license lucide-react v0.552.0 - ISC
141
141
  *
142
142
  * This source code is licensed under the ISC license.
143
143
  * See the LICENSE file in the root directory of this source tree.
144
144
  */
145
- const __iconNode$4 = [
145
+ const __iconNode$3 = [
146
146
  ["path", { d: "M3 3v16a2 2 0 0 0 2 2h16", key: "c24i48" }],
147
147
  ["path", { d: "M18 17V9", key: "2bz60n" }],
148
148
  ["path", { d: "M13 17V5", key: "1frdt8" }],
149
149
  ["path", { d: "M8 17v-3", key: "17ska0" }]
150
150
  ];
151
- const ChartColumn = createLucideIcon("chart-column", __iconNode$4);
152
- /**
153
- * @license lucide-react v0.552.0 - ISC
154
- *
155
- * This source code is licensed under the ISC license.
156
- * See the LICENSE file in the root directory of this source tree.
157
- */
158
- const __iconNode$3 = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
159
- const ChevronDown = createLucideIcon("chevron-down", __iconNode$3);
151
+ const ChartColumn = createLucideIcon("chart-column", __iconNode$3);
160
152
  /**
161
153
  * @license lucide-react v0.552.0 - ISC
162
154
  *
@@ -14280,18 +14272,12 @@ function normalizePath(path) {
14280
14272
  function createCoverageHighlightLayers(buildings, fileCoverage) {
14281
14273
  const buildingsByPath = new Map(buildings.map((b) => [b.path, b]));
14282
14274
  const layerGroups = {
14283
- high: [],
14284
- // 80-100%
14285
- medium: [],
14286
- // 50-79%
14287
- low: [],
14288
- // 20-49%
14289
- veryLow: [],
14290
- // 1-19%
14291
- zero: [],
14292
- // 0%
14275
+ covered: [],
14276
+ // > 0% coverage - green
14277
+ uncovered: [],
14278
+ // 0% coverage - red
14293
14279
  noData: []
14294
- // No coverage data
14280
+ // No coverage data (not applicable) - gray
14295
14281
  };
14296
14282
  for (const [path, building] of buildingsByPath) {
14297
14283
  const normalizedPath = normalizePath(path);
@@ -14302,32 +14288,201 @@ function createCoverageHighlightLayers(buildings, fileCoverage) {
14302
14288
  type: "file",
14303
14289
  renderStrategy: "fill"
14304
14290
  });
14305
- } else if (coverage >= 80) {
14306
- layerGroups.high.push({
14291
+ } else if (coverage > 0) {
14292
+ layerGroups.covered.push({
14307
14293
  path: building.path,
14308
14294
  type: "file",
14309
14295
  renderStrategy: "fill"
14310
14296
  });
14311
- } else if (coverage >= 50) {
14312
- layerGroups.medium.push({
14297
+ } else {
14298
+ layerGroups.uncovered.push({
14299
+ path: building.path,
14300
+ type: "file",
14301
+ renderStrategy: "fill"
14302
+ });
14303
+ }
14304
+ }
14305
+ const layers = [];
14306
+ if (layerGroups.covered.length > 0) {
14307
+ layers.push({
14308
+ id: "coverage-covered",
14309
+ name: "Covered",
14310
+ enabled: true,
14311
+ color: "#22c55e",
14312
+ // green
14313
+ priority: 50,
14314
+ items: layerGroups.covered
14315
+ });
14316
+ }
14317
+ if (layerGroups.uncovered.length > 0) {
14318
+ layers.push({
14319
+ id: "coverage-uncovered",
14320
+ name: "Not covered",
14321
+ enabled: true,
14322
+ color: "#ef4444",
14323
+ // red
14324
+ priority: 50,
14325
+ items: layerGroups.uncovered
14326
+ });
14327
+ }
14328
+ if (layerGroups.noData.length > 0) {
14329
+ layers.push({
14330
+ id: "coverage-nodata",
14331
+ name: "No data",
14332
+ enabled: true,
14333
+ color: "#6b7280",
14334
+ // gray
14335
+ priority: 40,
14336
+ items: layerGroups.noData
14337
+ });
14338
+ }
14339
+ return layers;
14340
+ }
14341
+ function createEslintHighlightLayers(buildings, eslintMetrics) {
14342
+ const buildingsByPath = new Map(buildings.map((b) => [b.path, b]));
14343
+ const metricsByPath = new Map(eslintMetrics.map((m) => [normalizePath(m.file), m]));
14344
+ const layerGroups = {
14345
+ clean: [],
14346
+ // 0 issues - green
14347
+ minor: [],
14348
+ // 1-3 issues - orange
14349
+ moderate: [],
14350
+ // 4-10 issues - orange-red
14351
+ significant: [],
14352
+ // 11-25 issues - red
14353
+ severe: [],
14354
+ // 26+ issues - dark red
14355
+ noData: []
14356
+ // No metric data
14357
+ };
14358
+ for (const [path, building] of buildingsByPath) {
14359
+ const normalizedPath = normalizePath(path);
14360
+ const metric = metricsByPath.get(normalizedPath);
14361
+ if (!metric) {
14362
+ layerGroups.noData.push({
14313
14363
  path: building.path,
14314
14364
  type: "file",
14315
14365
  renderStrategy: "fill"
14316
14366
  });
14317
- } else if (coverage >= 20) {
14318
- layerGroups.low.push({
14367
+ } else {
14368
+ const issues = metric.issueCount;
14369
+ let bucket;
14370
+ if (issues === 0) bucket = "clean";
14371
+ else if (issues <= 3) bucket = "minor";
14372
+ else if (issues <= 10) bucket = "moderate";
14373
+ else if (issues <= 25) bucket = "significant";
14374
+ else bucket = "severe";
14375
+ layerGroups[bucket].push({
14319
14376
  path: building.path,
14320
14377
  type: "file",
14321
14378
  renderStrategy: "fill"
14322
14379
  });
14323
- } else if (coverage > 0) {
14324
- layerGroups.veryLow.push({
14380
+ }
14381
+ }
14382
+ const layers = [];
14383
+ if (layerGroups.clean.length > 0) {
14384
+ layers.push({
14385
+ id: "eslint-clean",
14386
+ name: "0 issues",
14387
+ enabled: true,
14388
+ color: "#22c55e",
14389
+ // green - only for no lint issues
14390
+ priority: 50,
14391
+ items: layerGroups.clean
14392
+ });
14393
+ }
14394
+ if (layerGroups.minor.length > 0) {
14395
+ layers.push({
14396
+ id: "eslint-minor",
14397
+ name: "1-3 issues",
14398
+ enabled: true,
14399
+ color: "#f97316",
14400
+ // orange
14401
+ priority: 50,
14402
+ items: layerGroups.minor
14403
+ });
14404
+ }
14405
+ if (layerGroups.moderate.length > 0) {
14406
+ layers.push({
14407
+ id: "eslint-moderate",
14408
+ name: "4-10 issues",
14409
+ enabled: true,
14410
+ color: "#ea580c",
14411
+ // orange-600 (darker orange)
14412
+ priority: 50,
14413
+ items: layerGroups.moderate
14414
+ });
14415
+ }
14416
+ if (layerGroups.significant.length > 0) {
14417
+ layers.push({
14418
+ id: "eslint-significant",
14419
+ name: "11-25 issues",
14420
+ enabled: true,
14421
+ color: "#ef4444",
14422
+ // red
14423
+ priority: 50,
14424
+ items: layerGroups.significant
14425
+ });
14426
+ }
14427
+ if (layerGroups.severe.length > 0) {
14428
+ layers.push({
14429
+ id: "eslint-severe",
14430
+ name: "26+ issues",
14431
+ enabled: true,
14432
+ color: "#991b1b",
14433
+ // dark red
14434
+ priority: 50,
14435
+ items: layerGroups.severe
14436
+ });
14437
+ }
14438
+ if (layerGroups.noData.length > 0) {
14439
+ layers.push({
14440
+ id: "eslint-nodata",
14441
+ name: "No data",
14442
+ enabled: true,
14443
+ color: "#6b7280",
14444
+ // gray
14445
+ priority: 40,
14446
+ items: layerGroups.noData
14447
+ });
14448
+ }
14449
+ return layers;
14450
+ }
14451
+ function createTypescriptHighlightLayers(buildings, typescriptMetrics) {
14452
+ const buildingsByPath = new Map(buildings.map((b) => [b.path, b]));
14453
+ const metricsByPath = new Map(typescriptMetrics.map((m) => [normalizePath(m.file), m]));
14454
+ const layerGroups = {
14455
+ clean: [],
14456
+ // 0 issues - green
14457
+ minor: [],
14458
+ // 1-3 issues - orange
14459
+ moderate: [],
14460
+ // 4-10 issues - orange-red
14461
+ significant: [],
14462
+ // 11-25 issues - red
14463
+ severe: [],
14464
+ // 26+ issues - dark red
14465
+ noData: []
14466
+ // No metric data
14467
+ };
14468
+ for (const [path, building] of buildingsByPath) {
14469
+ const normalizedPath = normalizePath(path);
14470
+ const metric = metricsByPath.get(normalizedPath);
14471
+ if (!metric) {
14472
+ layerGroups.noData.push({
14325
14473
  path: building.path,
14326
14474
  type: "file",
14327
14475
  renderStrategy: "fill"
14328
14476
  });
14329
14477
  } else {
14330
- layerGroups.zero.push({
14478
+ const issues = metric.issueCount;
14479
+ let bucket;
14480
+ if (issues === 0) bucket = "clean";
14481
+ else if (issues <= 3) bucket = "minor";
14482
+ else if (issues <= 10) bucket = "moderate";
14483
+ else if (issues <= 25) bucket = "significant";
14484
+ else bucket = "severe";
14485
+ layerGroups[bucket].push({
14331
14486
  path: building.path,
14332
14487
  type: "file",
14333
14488
  renderStrategy: "fill"
@@ -14335,82 +14490,88 @@ function createCoverageHighlightLayers(buildings, fileCoverage) {
14335
14490
  }
14336
14491
  }
14337
14492
  const layers = [];
14338
- if (layerGroups.high.length > 0) {
14493
+ if (layerGroups.clean.length > 0) {
14339
14494
  layers.push({
14340
- id: "coverage-high",
14341
- name: "80-100%",
14495
+ id: "typescript-clean",
14496
+ name: "0 errors",
14342
14497
  enabled: true,
14343
14498
  color: "#22c55e",
14499
+ // green - only for no type errors
14344
14500
  priority: 50,
14345
- items: layerGroups.high
14501
+ items: layerGroups.clean
14346
14502
  });
14347
14503
  }
14348
- if (layerGroups.medium.length > 0) {
14504
+ if (layerGroups.minor.length > 0) {
14349
14505
  layers.push({
14350
- id: "coverage-medium",
14351
- name: "50-79%",
14506
+ id: "typescript-minor",
14507
+ name: "1-3 errors",
14352
14508
  enabled: true,
14353
- color: "#eab308",
14509
+ color: "#f97316",
14510
+ // orange
14354
14511
  priority: 50,
14355
- items: layerGroups.medium
14512
+ items: layerGroups.minor
14356
14513
  });
14357
14514
  }
14358
- if (layerGroups.low.length > 0) {
14515
+ if (layerGroups.moderate.length > 0) {
14359
14516
  layers.push({
14360
- id: "coverage-low",
14361
- name: "20-49%",
14517
+ id: "typescript-moderate",
14518
+ name: "4-10 errors",
14362
14519
  enabled: true,
14363
- color: "#f97316",
14520
+ color: "#ea580c",
14521
+ // orange-600 (darker orange)
14364
14522
  priority: 50,
14365
- items: layerGroups.low
14523
+ items: layerGroups.moderate
14366
14524
  });
14367
14525
  }
14368
- if (layerGroups.veryLow.length > 0) {
14526
+ if (layerGroups.significant.length > 0) {
14369
14527
  layers.push({
14370
- id: "coverage-verylow",
14371
- name: "1-19%",
14528
+ id: "typescript-significant",
14529
+ name: "11-25 errors",
14372
14530
  enabled: true,
14373
14531
  color: "#ef4444",
14532
+ // red
14374
14533
  priority: 50,
14375
- items: layerGroups.veryLow
14534
+ items: layerGroups.significant
14376
14535
  });
14377
14536
  }
14378
- if (layerGroups.zero.length > 0) {
14537
+ if (layerGroups.severe.length > 0) {
14379
14538
  layers.push({
14380
- id: "coverage-zero",
14381
- name: "0%",
14539
+ id: "typescript-severe",
14540
+ name: "26+ errors",
14382
14541
  enabled: true,
14383
14542
  color: "#991b1b",
14543
+ // dark red
14384
14544
  priority: 50,
14385
- items: layerGroups.zero
14545
+ items: layerGroups.severe
14386
14546
  });
14387
14547
  }
14388
14548
  if (layerGroups.noData.length > 0) {
14389
14549
  layers.push({
14390
- id: "coverage-nodata",
14550
+ id: "typescript-nodata",
14391
14551
  name: "No data",
14392
14552
  enabled: true,
14393
14553
  color: "#6b7280",
14554
+ // gray
14394
14555
  priority: 40,
14395
14556
  items: layerGroups.noData
14396
14557
  });
14397
14558
  }
14398
14559
  return layers;
14399
14560
  }
14400
- function createMetricHighlightLayers(buildings, metrics, metricId, _metricName) {
14561
+ function createPrettierHighlightLayers(buildings, prettierMetrics) {
14401
14562
  const buildingsByPath = new Map(buildings.map((b) => [b.path, b]));
14402
- const metricsByPath = new Map(metrics.map((m) => [normalizePath(m.file), m]));
14563
+ const metricsByPath = new Map(prettierMetrics.map((m) => [normalizePath(m.file), m]));
14403
14564
  const layerGroups = {
14404
14565
  clean: [],
14405
- // 0 issues
14566
+ // 0 issues - green
14406
14567
  minor: [],
14407
- // 1-3 issues
14568
+ // 1-3 issues - orange
14408
14569
  moderate: [],
14409
- // 4-10 issues
14570
+ // 4-10 issues - orange-red
14410
14571
  significant: [],
14411
- // 11-25 issues
14572
+ // 11-25 issues - red
14412
14573
  severe: [],
14413
- // 26+ issues
14574
+ // 26+ issues - dark red
14414
14575
  noData: []
14415
14576
  // No metric data
14416
14577
  };
@@ -14441,80 +14602,251 @@ function createMetricHighlightLayers(buildings, metrics, metricId, _metricName)
14441
14602
  const layers = [];
14442
14603
  if (layerGroups.clean.length > 0) {
14443
14604
  layers.push({
14444
- id: `${metricId}-clean`,
14605
+ id: "prettier-clean",
14445
14606
  name: "0 issues",
14446
14607
  enabled: true,
14447
14608
  color: "#22c55e",
14609
+ // green - only for perfect formatting
14448
14610
  priority: 50,
14449
14611
  items: layerGroups.clean
14450
14612
  });
14451
14613
  }
14452
14614
  if (layerGroups.minor.length > 0) {
14453
14615
  layers.push({
14454
- id: `${metricId}-minor`,
14616
+ id: "prettier-minor",
14455
14617
  name: "1-3 issues",
14456
14618
  enabled: true,
14457
- color: "#84cc16",
14619
+ color: "#f97316",
14620
+ // orange
14458
14621
  priority: 50,
14459
14622
  items: layerGroups.minor
14460
14623
  });
14461
14624
  }
14462
14625
  if (layerGroups.moderate.length > 0) {
14463
14626
  layers.push({
14464
- id: `${metricId}-moderate`,
14627
+ id: "prettier-moderate",
14465
14628
  name: "4-10 issues",
14466
14629
  enabled: true,
14467
- color: "#eab308",
14630
+ color: "#ea580c",
14631
+ // orange-600 (darker orange)
14468
14632
  priority: 50,
14469
14633
  items: layerGroups.moderate
14470
14634
  });
14471
14635
  }
14472
14636
  if (layerGroups.significant.length > 0) {
14473
14637
  layers.push({
14474
- id: `${metricId}-significant`,
14638
+ id: "prettier-significant",
14475
14639
  name: "11-25 issues",
14476
14640
  enabled: true,
14477
- color: "#f97316",
14641
+ color: "#ef4444",
14642
+ // red
14478
14643
  priority: 50,
14479
14644
  items: layerGroups.significant
14480
14645
  });
14481
14646
  }
14482
14647
  if (layerGroups.severe.length > 0) {
14483
14648
  layers.push({
14484
- id: `${metricId}-severe`,
14649
+ id: "prettier-severe",
14485
14650
  name: "26+ issues",
14486
14651
  enabled: true,
14487
- color: "#ef4444",
14652
+ color: "#991b1b",
14653
+ // dark red
14488
14654
  priority: 50,
14489
14655
  items: layerGroups.severe
14490
14656
  });
14491
14657
  }
14492
14658
  if (layerGroups.noData.length > 0) {
14493
14659
  layers.push({
14494
- id: `${metricId}-nodata`,
14660
+ id: "prettier-nodata",
14495
14661
  name: "No data",
14496
14662
  enabled: true,
14497
14663
  color: "#6b7280",
14664
+ // gray
14498
14665
  priority: 40,
14499
14666
  items: layerGroups.noData
14500
14667
  });
14501
14668
  }
14502
14669
  return layers;
14503
14670
  }
14504
- function createEslintHighlightLayers(buildings, eslintMetrics) {
14505
- return createMetricHighlightLayers(buildings, eslintMetrics, "eslint");
14506
- }
14507
- function createTypescriptHighlightLayers(buildings, typescriptMetrics) {
14508
- return createMetricHighlightLayers(buildings, typescriptMetrics, "typescript");
14509
- }
14510
- function createPrettierHighlightLayers(buildings, prettierMetrics) {
14511
- return createMetricHighlightLayers(buildings, prettierMetrics, "prettier");
14512
- }
14513
14671
  function createKnipHighlightLayers(buildings, knipMetrics) {
14514
- return createMetricHighlightLayers(buildings, knipMetrics, "knip");
14672
+ const buildingsByPath = new Map(buildings.map((b) => [b.path, b]));
14673
+ const metricsByPath = new Map(knipMetrics.map((m) => [normalizePath(m.file), m]));
14674
+ const layerGroups = {
14675
+ clean: [],
14676
+ // 0 issues - green
14677
+ minor: [],
14678
+ // 1-3 issues - orange
14679
+ moderate: [],
14680
+ // 4-10 issues - orange-red
14681
+ significant: [],
14682
+ // 11-25 issues - red
14683
+ severe: [],
14684
+ // 26+ issues - dark red
14685
+ noData: []
14686
+ // No metric data
14687
+ };
14688
+ for (const [path, building] of buildingsByPath) {
14689
+ const normalizedPath = normalizePath(path);
14690
+ const metric = metricsByPath.get(normalizedPath);
14691
+ if (!metric) {
14692
+ layerGroups.noData.push({
14693
+ path: building.path,
14694
+ type: "file",
14695
+ renderStrategy: "fill"
14696
+ });
14697
+ } else {
14698
+ const issues = metric.issueCount;
14699
+ let bucket;
14700
+ if (issues === 0) bucket = "clean";
14701
+ else if (issues <= 3) bucket = "minor";
14702
+ else if (issues <= 10) bucket = "moderate";
14703
+ else if (issues <= 25) bucket = "significant";
14704
+ else bucket = "severe";
14705
+ layerGroups[bucket].push({
14706
+ path: building.path,
14707
+ type: "file",
14708
+ renderStrategy: "fill"
14709
+ });
14710
+ }
14711
+ }
14712
+ const layers = [];
14713
+ if (layerGroups.clean.length > 0) {
14714
+ layers.push({
14715
+ id: "knip-clean",
14716
+ name: "0 unused",
14717
+ enabled: true,
14718
+ color: "#22c55e",
14719
+ // green - only for no dead code
14720
+ priority: 50,
14721
+ items: layerGroups.clean
14722
+ });
14723
+ }
14724
+ if (layerGroups.minor.length > 0) {
14725
+ layers.push({
14726
+ id: "knip-minor",
14727
+ name: "1-3 unused",
14728
+ enabled: true,
14729
+ color: "#f97316",
14730
+ // orange
14731
+ priority: 50,
14732
+ items: layerGroups.minor
14733
+ });
14734
+ }
14735
+ if (layerGroups.moderate.length > 0) {
14736
+ layers.push({
14737
+ id: "knip-moderate",
14738
+ name: "4-10 unused",
14739
+ enabled: true,
14740
+ color: "#ea580c",
14741
+ // orange-600 (darker orange)
14742
+ priority: 50,
14743
+ items: layerGroups.moderate
14744
+ });
14745
+ }
14746
+ if (layerGroups.significant.length > 0) {
14747
+ layers.push({
14748
+ id: "knip-significant",
14749
+ name: "11-25 unused",
14750
+ enabled: true,
14751
+ color: "#ef4444",
14752
+ // red
14753
+ priority: 50,
14754
+ items: layerGroups.significant
14755
+ });
14756
+ }
14757
+ if (layerGroups.severe.length > 0) {
14758
+ layers.push({
14759
+ id: "knip-severe",
14760
+ name: "26+ unused",
14761
+ enabled: true,
14762
+ color: "#991b1b",
14763
+ // dark red
14764
+ priority: 50,
14765
+ items: layerGroups.severe
14766
+ });
14767
+ }
14768
+ if (layerGroups.noData.length > 0) {
14769
+ layers.push({
14770
+ id: "knip-nodata",
14771
+ name: "No data",
14772
+ enabled: true,
14773
+ color: "#6b7280",
14774
+ // gray
14775
+ priority: 40,
14776
+ items: layerGroups.noData
14777
+ });
14778
+ }
14779
+ return layers;
14515
14780
  }
14516
14781
  function createAlexandriaHighlightLayers(buildings, alexandriaMetrics) {
14517
- return createMetricHighlightLayers(buildings, alexandriaMetrics, "alexandria");
14782
+ const buildingsByPath = new Map(buildings.map((b) => [b.path, b]));
14783
+ const metricsByPath = new Map(alexandriaMetrics.map((m) => [normalizePath(m.file), m]));
14784
+ const layerGroups = {
14785
+ documented: [],
14786
+ // 0 issues - fully documented
14787
+ needsDocs: [],
14788
+ // > 0 issues - needs documentation
14789
+ noData: []
14790
+ // No data (not applicable)
14791
+ };
14792
+ for (const [path, building] of buildingsByPath) {
14793
+ const normalizedPath = normalizePath(path);
14794
+ const metric = metricsByPath.get(normalizedPath);
14795
+ if (!metric) {
14796
+ layerGroups.noData.push({
14797
+ path: building.path,
14798
+ type: "file",
14799
+ renderStrategy: "fill"
14800
+ });
14801
+ } else if (metric.issueCount === 0) {
14802
+ layerGroups.documented.push({
14803
+ path: building.path,
14804
+ type: "file",
14805
+ renderStrategy: "fill"
14806
+ });
14807
+ } else {
14808
+ layerGroups.needsDocs.push({
14809
+ path: building.path,
14810
+ type: "file",
14811
+ renderStrategy: "fill"
14812
+ });
14813
+ }
14814
+ }
14815
+ const layers = [];
14816
+ if (layerGroups.documented.length > 0) {
14817
+ layers.push({
14818
+ id: "alexandria-documented",
14819
+ name: "Documented",
14820
+ enabled: true,
14821
+ color: "#22c55e",
14822
+ // green
14823
+ priority: 50,
14824
+ items: layerGroups.documented
14825
+ });
14826
+ }
14827
+ if (layerGroups.needsDocs.length > 0) {
14828
+ layers.push({
14829
+ id: "alexandria-needsdocs",
14830
+ name: "Needs docs",
14831
+ enabled: true,
14832
+ color: "#ef4444",
14833
+ // red
14834
+ priority: 50,
14835
+ items: layerGroups.needsDocs
14836
+ });
14837
+ }
14838
+ if (layerGroups.noData.length > 0) {
14839
+ layers.push({
14840
+ id: "alexandria-nodata",
14841
+ name: "No data",
14842
+ enabled: true,
14843
+ color: "#6b7280",
14844
+ // gray
14845
+ priority: 40,
14846
+ items: layerGroups.noData
14847
+ });
14848
+ }
14849
+ return layers;
14518
14850
  }
14519
14851
  function getLayersForColorMode(mode, buildings, qualityData, fileColorLayers, gitLayers) {
14520
14852
  var _a, _b, _c, _d, _e;
@@ -14582,9 +14914,8 @@ const CodeCityPanelContent = ({
14582
14914
  const [loading, setLoading] = useState(false);
14583
14915
  const [containerSize, setContainerSize] = useState(null);
14584
14916
  const contentContainerRef = useRef(null);
14585
- const [colorMode, setColorMode] = useState("fileTypes");
14586
- const [showColorModeDropdown, setShowColorModeDropdown] = useState(false);
14587
- const colorModeDropdownRef = useRef(null);
14917
+ const sliceSelectedColorMode = (_b = (_a = context.getSlice("fileCityColorModes")) == null ? void 0 : _a.data) == null ? void 0 : _b.selectedColorMode;
14918
+ const colorMode = sliceSelectedColorMode || "fileTypes";
14588
14919
  const [hoveredPackagePath, setHoveredPackagePath] = useState(null);
14589
14920
  const [selectedPackagePath, setSelectedPackagePath] = useState(null);
14590
14921
  useEffect(() => {
@@ -14625,12 +14956,12 @@ const CodeCityPanelContent = ({
14625
14956
  const gitSlice = context.getSlice("git");
14626
14957
  const agentHighlightLayersSlice = context.getSlice("agentHighlightLayers");
14627
14958
  const colorModesSlice = context.getSlice("fileCityColorModes");
14628
- const qualityData = (_a = colorModesSlice == null ? void 0 : colorModesSlice.data) == null ? void 0 : _a.qualityData;
14959
+ const qualityData = (_c = colorModesSlice == null ? void 0 : colorModesSlice.data) == null ? void 0 : _c.qualityData;
14629
14960
  const fileColorLayersRegistered = useRef(false);
14630
14961
  const gitLayersRegistered = useRef(false);
14631
14962
  const agentLayersRegistered = useRef(false);
14632
14963
  const lastHasGitOrAgentLayers = useRef(null);
14633
- const currentRepoPath = (_b = context.currentScope.repository) == null ? void 0 : _b.path;
14964
+ const currentRepoPath = (_d = context.currentScope.repository) == null ? void 0 : _d.path;
14634
14965
  const lastRepoPath = useRef(currentRepoPath);
14635
14966
  useEffect(() => {
14636
14967
  if (lastRepoPath.current !== currentRepoPath) {
@@ -14640,20 +14971,8 @@ const CodeCityPanelContent = ({
14640
14971
  agentLayersRegistered.current = false;
14641
14972
  lastHasGitOrAgentLayers.current = null;
14642
14973
  lastRepoPath.current = currentRepoPath;
14643
- setColorMode("fileTypes");
14644
14974
  }
14645
14975
  }, [currentRepoPath]);
14646
- useEffect(() => {
14647
- const handleClickOutside = (event) => {
14648
- if (colorModeDropdownRef.current && !colorModeDropdownRef.current.contains(event.target)) {
14649
- setShowColorModeDropdown(false);
14650
- }
14651
- };
14652
- if (showColorModeDropdown) {
14653
- document.addEventListener("mousedown", handleClickOutside);
14654
- return () => document.removeEventListener("mousedown", handleClickOutside);
14655
- }
14656
- }, [showColorModeDropdown]);
14657
14976
  useEffect(() => {
14658
14977
  if (!events) return;
14659
14978
  const cleanupHover = events.on("package:hover", (event) => {
@@ -14669,30 +14988,6 @@ const CodeCityPanelContent = ({
14669
14988
  cleanupSelect == null ? void 0 : cleanupSelect();
14670
14989
  };
14671
14990
  }, [events]);
14672
- const sliceSelectedColorMode = (_c = colorModesSlice == null ? void 0 : colorModesSlice.data) == null ? void 0 : _c.selectedColorMode;
14673
- useEffect(() => {
14674
- if (sliceSelectedColorMode) {
14675
- setColorMode(sliceSelectedColorMode);
14676
- }
14677
- }, [sliceSelectedColorMode]);
14678
- const availableColorModes = useMemo(() => {
14679
- var _a2;
14680
- const hasGitData = (gitSlice == null ? void 0 : gitSlice.data) && (gitSlice.data.staged.length > 0 || gitSlice.data.unstaged.length > 0 || gitSlice.data.untracked.length > 0 || gitSlice.data.deleted.length > 0);
14681
- const enabledModes = (_a2 = colorModesSlice == null ? void 0 : colorModesSlice.data) == null ? void 0 : _a2.enabledModes;
14682
- return COLOR_MODES.filter((mode) => {
14683
- if (mode.id === "fileTypes") return true;
14684
- if (mode.id === "git") return hasGitData;
14685
- if (sliceSelectedColorMode === mode.id) return true;
14686
- return (enabledModes == null ? void 0 : enabledModes.includes(mode.id)) ?? false;
14687
- });
14688
- }, [gitSlice == null ? void 0 : gitSlice.data, (_d = colorModesSlice == null ? void 0 : colorModesSlice.data) == null ? void 0 : _d.enabledModes, qualityData, sliceSelectedColorMode]);
14689
- useEffect(() => {
14690
- const currentModeAvailable = availableColorModes.some((m) => m.id === colorMode);
14691
- const selectedModeAvailable = sliceSelectedColorMode && availableColorModes.some((m) => m.id === sliceSelectedColorMode);
14692
- if (!currentModeAvailable && !selectedModeAvailable) {
14693
- setColorMode("fileTypes");
14694
- }
14695
- }, [availableColorModes, colorMode, sliceSelectedColorMode]);
14696
14991
  const currentColorModeConfig = useMemo(() => {
14697
14992
  return COLOR_MODES.find((m) => m.id === colorMode) || COLOR_MODES[0];
14698
14993
  }, [colorMode]);
@@ -14907,30 +15202,39 @@ const CodeCityPanelContent = ({
14907
15202
  groupedByExt.forEach((group, ext) => {
14908
15203
  var _a2;
14909
15204
  if (group.primary) {
15205
+ const highlightLayer = highlightLayers.find(
15206
+ (l) => l.id === `ext-${ext}-primary` || l.id === `ext-${ext}-primary-package-focus`
15207
+ );
15208
+ const isEnabled = (highlightLayer == null ? void 0 : highlightLayer.enabled) ?? group.primary.enabled;
14910
15209
  fileTypes.push({
14911
15210
  id: ext,
14912
15211
  name: group.primary.name,
14913
15212
  fillColor: group.primary.color,
14914
15213
  borderColor: (_a2 = group.secondary) == null ? void 0 : _a2.color,
14915
15214
  count: group.primary.items.length,
14916
- enabled: group.primary.enabled
15215
+ enabled: isEnabled
14917
15216
  });
14918
15217
  }
14919
15218
  });
14920
15219
  return fileTypes.sort((a, b) => b.count - a.count);
14921
- }, [baseLayers]);
15220
+ }, [baseLayers, highlightLayers]);
14922
15221
  const legendGitStatus = useMemo(() => {
14923
15222
  const gitLayers = baseLayers.filter(
14924
15223
  (layer) => layer.id.startsWith("git-highlight-")
14925
15224
  );
14926
- return gitLayers.map((layer) => ({
14927
- id: layer.id,
14928
- name: layer.name,
14929
- color: layer.color,
14930
- count: layer.items.length,
14931
- enabled: layer.enabled
14932
- }));
14933
- }, [baseLayers]);
15225
+ return gitLayers.map((layer) => {
15226
+ const highlightLayer = highlightLayers.find(
15227
+ (l) => l.id === layer.id || l.id === `${layer.id}-package-focus`
15228
+ );
15229
+ return {
15230
+ id: layer.id,
15231
+ name: layer.name,
15232
+ color: layer.color,
15233
+ count: layer.items.length,
15234
+ enabled: (highlightLayer == null ? void 0 : highlightLayer.enabled) ?? layer.enabled
15235
+ };
15236
+ });
15237
+ }, [baseLayers, highlightLayers]);
14934
15238
  const legendAgentLayers = useMemo(() => {
14935
15239
  const agentLayers = highlightLayers.filter(
14936
15240
  (layer) => layer.id.startsWith("event-highlight")
@@ -14961,33 +15265,54 @@ const CodeCityPanelContent = ({
14961
15265
  const relevantLayers = baseLayers.filter(
14962
15266
  (layer) => layer.id.startsWith(prefix)
14963
15267
  );
14964
- return relevantLayers.map((layer) => ({
14965
- id: layer.id,
14966
- name: layer.name,
14967
- color: layer.color,
14968
- count: layer.items.length,
14969
- enabled: layer.enabled
14970
- }));
14971
- }, [baseLayers, colorMode]);
15268
+ return relevantLayers.map((layer) => {
15269
+ const highlightLayer = highlightLayers.find(
15270
+ (l) => l.id === layer.id || l.id === `${layer.id}-package-focus`
15271
+ );
15272
+ return {
15273
+ id: layer.id,
15274
+ name: layer.name,
15275
+ color: layer.color,
15276
+ count: layer.items.length,
15277
+ enabled: (highlightLayer == null ? void 0 : highlightLayer.enabled) ?? layer.enabled
15278
+ };
15279
+ });
15280
+ }, [baseLayers, highlightLayers, colorMode]);
14972
15281
  const toggleGitStatus = useCallback((id2) => {
14973
- setHighlightLayers(
14974
- (prev) => prev.map((layer) => {
14975
- if (layer.id === id2) {
14976
- return { ...layer, enabled: !layer.enabled };
15282
+ setHighlightLayers((prev) => {
15283
+ const gitLayers = prev.filter((l) => l.id.startsWith("git-highlight-"));
15284
+ const clickedLayer = gitLayers.find((l) => l.id === id2);
15285
+ const otherGitLayers = gitLayers.filter((l) => l.id !== id2);
15286
+ const isAlreadyIsolated = (clickedLayer == null ? void 0 : clickedLayer.enabled) && otherGitLayers.every((l) => !l.enabled);
15287
+ return prev.map((layer) => {
15288
+ if (!layer.id.startsWith("git-highlight-")) {
15289
+ return layer;
14977
15290
  }
14978
- return layer;
14979
- })
14980
- );
15291
+ if (isAlreadyIsolated) {
15292
+ return { ...layer, enabled: true };
15293
+ } else {
15294
+ return { ...layer, enabled: layer.id === id2 };
15295
+ }
15296
+ });
15297
+ });
14981
15298
  }, []);
14982
15299
  const toggleAgentLayer = useCallback((id2) => {
14983
- setHighlightLayers(
14984
- (prev) => prev.map((layer) => {
14985
- if (layer.id === id2) {
14986
- return { ...layer, enabled: !layer.enabled };
15300
+ setHighlightLayers((prev) => {
15301
+ const agentLayers = prev.filter((l) => l.id.startsWith("event-highlight"));
15302
+ const clickedLayer = agentLayers.find((l) => l.id === id2);
15303
+ const otherAgentLayers = agentLayers.filter((l) => l.id !== id2);
15304
+ const isAlreadyIsolated = (clickedLayer == null ? void 0 : clickedLayer.enabled) && otherAgentLayers.every((l) => !l.enabled);
15305
+ return prev.map((layer) => {
15306
+ if (!layer.id.startsWith("event-highlight")) {
15307
+ return layer;
14987
15308
  }
14988
- return layer;
14989
- })
14990
- );
15309
+ if (isAlreadyIsolated) {
15310
+ return { ...layer, enabled: true };
15311
+ } else {
15312
+ return { ...layer, enabled: layer.id === id2 };
15313
+ }
15314
+ });
15315
+ });
14991
15316
  }, []);
14992
15317
  const clearAgentLayers = useCallback(() => {
14993
15318
  setHighlightLayers(
@@ -14996,24 +15321,52 @@ const CodeCityPanelContent = ({
14996
15321
  agentLayersRegistered.current = false;
14997
15322
  }, []);
14998
15323
  const toggleQualityMetric = useCallback((id2) => {
14999
- setHighlightLayers(
15000
- (prev) => prev.map((layer) => {
15001
- if (layer.id === id2) {
15002
- return { ...layer, enabled: !layer.enabled };
15324
+ setHighlightLayers((prev) => {
15325
+ const qualityPrefixes = ["coverage-", "eslint-", "typescript-", "prettier-", "knip-", "alexandria-"];
15326
+ const isQualityLayer = (layerId) => qualityPrefixes.some((p) => layerId.startsWith(p));
15327
+ const qualityLayers2 = prev.filter((l) => isQualityLayer(l.id));
15328
+ const clickedLayer = qualityLayers2.find((l) => l.id === id2);
15329
+ const otherQualityLayers = qualityLayers2.filter((l) => l.id !== id2);
15330
+ const isAlreadyIsolated = (clickedLayer == null ? void 0 : clickedLayer.enabled) && otherQualityLayers.every((l) => !l.enabled);
15331
+ return prev.map((layer) => {
15332
+ if (!isQualityLayer(layer.id)) {
15333
+ return layer;
15003
15334
  }
15004
- return layer;
15005
- })
15006
- );
15335
+ if (isAlreadyIsolated) {
15336
+ return { ...layer, enabled: true };
15337
+ } else {
15338
+ return { ...layer, enabled: layer.id === id2 };
15339
+ }
15340
+ });
15341
+ });
15007
15342
  }, []);
15008
15343
  const toggleFileType = useCallback((ext) => {
15009
15344
  setHighlightLayers((prev) => {
15010
- const primaryLayer = prev.find((l) => l.id === `ext-${ext}-primary`);
15011
- const newEnabled = primaryLayer ? !primaryLayer.enabled : true;
15345
+ const isFileTypeLayer = (id2) => id2.startsWith("ext-") && (id2.endsWith("-primary") || id2.endsWith("-secondary"));
15346
+ const fileTypeLayers = prev.filter((l) => isFileTypeLayer(l.id));
15347
+ const extStates = /* @__PURE__ */ new Map();
15348
+ fileTypeLayers.forEach((l) => {
15349
+ const match = l.id.match(/^ext-(\w+)-(primary|secondary)$/);
15350
+ if (match && match[2] === "primary") {
15351
+ extStates.set(match[1], l.enabled);
15352
+ }
15353
+ });
15354
+ const clickedEnabled = extStates.get(ext) ?? false;
15355
+ const otherExts = Array.from(extStates.keys()).filter((e) => e !== ext);
15356
+ const othersAllDisabled = otherExts.every((e) => !extStates.get(e));
15357
+ const isAlreadyIsolated = clickedEnabled && othersAllDisabled;
15012
15358
  return prev.map((layer) => {
15013
- if (layer.id === `ext-${ext}-primary` || layer.id === `ext-${ext}-secondary`) {
15014
- return { ...layer, enabled: newEnabled };
15359
+ if (!isFileTypeLayer(layer.id)) {
15360
+ return layer;
15361
+ }
15362
+ const match = layer.id.match(/^ext-(\w+)-(primary|secondary)$/);
15363
+ if (!match) return layer;
15364
+ const layerExt = match[1];
15365
+ if (isAlreadyIsolated) {
15366
+ return { ...layer, enabled: true };
15367
+ } else {
15368
+ return { ...layer, enabled: layerExt === ext };
15015
15369
  }
15016
- return layer;
15017
15370
  });
15018
15371
  });
15019
15372
  }, []);
@@ -15185,117 +15538,18 @@ const CodeCityPanelContent = ({
15185
15538
  }
15186
15539
  )
15187
15540
  ] }) }),
15188
- availableColorModes.length > 1 && /* @__PURE__ */ jsxs(
15189
- "div",
15541
+ colorMode !== "fileTypes" && /* @__PURE__ */ jsx(
15542
+ "span",
15190
15543
  {
15191
- ref: colorModeDropdownRef,
15192
- style: { position: "relative" },
15193
- children: [
15194
- /* @__PURE__ */ jsxs(
15195
- "button",
15196
- {
15197
- onClick: () => setShowColorModeDropdown(!showColorModeDropdown),
15198
- style: {
15199
- display: "flex",
15200
- alignItems: "center",
15201
- gap: "6px",
15202
- padding: "4px 10px",
15203
- fontSize: theme2.fontSizes[0],
15204
- fontFamily: theme2.fonts.body,
15205
- color: theme2.colors.text,
15206
- backgroundColor: theme2.colors.background,
15207
- border: `1px solid ${theme2.colors.border}`,
15208
- borderRadius: "4px",
15209
- cursor: "pointer",
15210
- transition: "all 0.15s ease",
15211
- minWidth: "120px"
15212
- },
15213
- title: "Change color mode",
15214
- children: [
15215
- /* @__PURE__ */ jsx("span", { style: { flex: 1, textAlign: "left" }, children: currentColorModeConfig.name }),
15216
- /* @__PURE__ */ jsx(
15217
- ChevronDown,
15218
- {
15219
- size: 14,
15220
- style: {
15221
- transform: showColorModeDropdown ? "rotate(180deg)" : "rotate(0deg)",
15222
- transition: "transform 0.15s ease"
15223
- }
15224
- }
15225
- )
15226
- ]
15227
- }
15228
- ),
15229
- showColorModeDropdown && /* @__PURE__ */ jsx(
15230
- "div",
15231
- {
15232
- style: {
15233
- position: "absolute",
15234
- top: "100%",
15235
- left: 0,
15236
- right: 0,
15237
- marginTop: "4px",
15238
- backgroundColor: theme2.colors.background,
15239
- border: `1px solid ${theme2.colors.border}`,
15240
- borderRadius: "4px",
15241
- boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
15242
- zIndex: 100,
15243
- overflow: "hidden",
15244
- minWidth: "160px"
15245
- },
15246
- children: availableColorModes.map((mode) => /* @__PURE__ */ jsxs(
15247
- "button",
15248
- {
15249
- onClick: () => {
15250
- setColorMode(mode.id);
15251
- setShowColorModeDropdown(false);
15252
- },
15253
- style: {
15254
- display: "flex",
15255
- flexDirection: "column",
15256
- alignItems: "flex-start",
15257
- width: "100%",
15258
- padding: "8px 12px",
15259
- fontSize: theme2.fontSizes[0],
15260
- fontFamily: theme2.fonts.body,
15261
- color: mode.id === colorMode ? theme2.colors.primary : theme2.colors.text,
15262
- backgroundColor: mode.id === colorMode ? theme2.colors.primary + "15" : "transparent",
15263
- border: "none",
15264
- cursor: "pointer",
15265
- transition: "background-color 0.15s ease",
15266
- textAlign: "left"
15267
- },
15268
- onMouseEnter: (e) => {
15269
- if (mode.id !== colorMode) {
15270
- e.currentTarget.style.backgroundColor = theme2.colors.backgroundLight;
15271
- }
15272
- },
15273
- onMouseLeave: (e) => {
15274
- if (mode.id !== colorMode) {
15275
- e.currentTarget.style.backgroundColor = "transparent";
15276
- }
15277
- },
15278
- children: [
15279
- /* @__PURE__ */ jsx("span", { style: { fontWeight: mode.id === colorMode ? 600 : 400 }, children: mode.name }),
15280
- /* @__PURE__ */ jsx(
15281
- "span",
15282
- {
15283
- style: {
15284
- fontSize: theme2.fontSizes[0],
15285
- fontFamily: theme2.fonts.body,
15286
- color: theme2.colors.textSecondary,
15287
- marginTop: "2px"
15288
- },
15289
- children: mode.description
15290
- }
15291
- )
15292
- ]
15293
- },
15294
- mode.id
15295
- ))
15296
- }
15297
- )
15298
- ]
15544
+ style: {
15545
+ padding: "4px 10px",
15546
+ fontSize: theme2.fontSizes[0],
15547
+ fontFamily: theme2.fonts.body,
15548
+ color: theme2.colors.primary,
15549
+ backgroundColor: theme2.colors.primary + "15",
15550
+ borderRadius: "4px"
15551
+ },
15552
+ children: currentColorModeConfig.name
15299
15553
  }
15300
15554
  ),
15301
15555
  (legendFileTypes.length > 0 || legendGitStatus.length > 0 || legendQualityMetrics.length > 0) && /* @__PURE__ */ jsx(