@emeryld/rrroutes-export 1.0.17 → 1.0.19
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/package.json +1 -1
- package/tools/finalized-leaves-viewer.html +583 -249
package/package.json
CHANGED
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
|
|
25
25
|
body {
|
|
26
26
|
margin: 0;
|
|
27
|
-
font-family:
|
|
27
|
+
font-family:
|
|
28
|
+
'Iosevka Web', 'SFMono-Regular', Menlo, Consolas, monospace;
|
|
28
29
|
color: var(--text);
|
|
29
30
|
background: var(--bg);
|
|
30
31
|
}
|
|
@@ -61,7 +62,10 @@
|
|
|
61
62
|
.primary-row {
|
|
62
63
|
display: grid;
|
|
63
64
|
gap: 10px;
|
|
64
|
-
grid-template-columns: minmax(220px, 0.9fr) minmax(300px, 1.4fr) minmax(
|
|
65
|
+
grid-template-columns: minmax(220px, 0.9fr) minmax(300px, 1.4fr) minmax(
|
|
66
|
+
220px,
|
|
67
|
+
1fr
|
|
68
|
+
);
|
|
65
69
|
align-items: end;
|
|
66
70
|
}
|
|
67
71
|
|
|
@@ -374,6 +378,31 @@
|
|
|
374
378
|
gap: 4px;
|
|
375
379
|
}
|
|
376
380
|
|
|
381
|
+
.changelog-diff-line {
|
|
382
|
+
display: flex;
|
|
383
|
+
flex-wrap: wrap;
|
|
384
|
+
gap: 6px;
|
|
385
|
+
align-items: baseline;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.changelog-op.added {
|
|
389
|
+
font-weight: 700;
|
|
390
|
+
color: var(--ok);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.changelog-op.changed {
|
|
394
|
+
font-weight: 700;
|
|
395
|
+
color: var(--accent);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.changelog-op.removed {
|
|
399
|
+
color: var(--danger);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.changelog-schema-type {
|
|
403
|
+
color: var(--schema-accent);
|
|
404
|
+
}
|
|
405
|
+
|
|
377
406
|
.schema-block {
|
|
378
407
|
border-top: 1px solid var(--border);
|
|
379
408
|
padding: 8px 0 2px;
|
|
@@ -497,15 +526,29 @@
|
|
|
497
526
|
</label>
|
|
498
527
|
<label class="control-block">
|
|
499
528
|
<span class="control-label">Search text</span>
|
|
500
|
-
<input
|
|
529
|
+
<input
|
|
530
|
+
id="searchInput"
|
|
531
|
+
type="text"
|
|
532
|
+
placeholder="Type to search..."
|
|
533
|
+
/>
|
|
501
534
|
</label>
|
|
502
535
|
<div class="control-block">
|
|
503
536
|
<span class="control-label">Quick filters</span>
|
|
504
537
|
<div class="quick-toggles">
|
|
505
|
-
<button
|
|
538
|
+
<button
|
|
539
|
+
id="caseSensitive"
|
|
540
|
+
class="pill-toggle"
|
|
541
|
+
type="button"
|
|
542
|
+
aria-pressed="false"
|
|
543
|
+
>
|
|
506
544
|
Case sensitive
|
|
507
545
|
</button>
|
|
508
|
-
<button
|
|
546
|
+
<button
|
|
547
|
+
id="regexSearch"
|
|
548
|
+
class="pill-toggle"
|
|
549
|
+
type="button"
|
|
550
|
+
aria-pressed="false"
|
|
551
|
+
>
|
|
509
552
|
Regex
|
|
510
553
|
</button>
|
|
511
554
|
</div>
|
|
@@ -514,11 +557,21 @@
|
|
|
514
557
|
|
|
515
558
|
<div class="scope-row">
|
|
516
559
|
<div class="scope-actions">
|
|
517
|
-
<button id="selectAllFields" class="scope-action" type="button">
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
<button id="
|
|
521
|
-
|
|
560
|
+
<button id="selectAllFields" class="scope-action" type="button">
|
|
561
|
+
All
|
|
562
|
+
</button>
|
|
563
|
+
<button id="clearAllFields" class="scope-action" type="button">
|
|
564
|
+
None
|
|
565
|
+
</button>
|
|
566
|
+
<button id="coreFields" class="scope-action" type="button">
|
|
567
|
+
Core
|
|
568
|
+
</button>
|
|
569
|
+
<button id="schemasOnlyFields" class="scope-action" type="button">
|
|
570
|
+
Schema
|
|
571
|
+
</button>
|
|
572
|
+
<button id="sourceOnlyFields" class="scope-action" type="button">
|
|
573
|
+
Source
|
|
574
|
+
</button>
|
|
522
575
|
</div>
|
|
523
576
|
<div id="fieldChipGroups" class="scope-groups"></div>
|
|
524
577
|
</div>
|
|
@@ -549,15 +602,22 @@
|
|
|
549
602
|
<div class="scope-group">
|
|
550
603
|
<div class="scope-group-title">Views</div>
|
|
551
604
|
<div class="scope-group-chips">
|
|
552
|
-
<button
|
|
605
|
+
<button
|
|
606
|
+
id="tabLeaves"
|
|
607
|
+
class="field-chip"
|
|
608
|
+
type="button"
|
|
609
|
+
aria-pressed="true"
|
|
610
|
+
>
|
|
553
611
|
Leaves
|
|
554
612
|
</button>
|
|
555
|
-
<button
|
|
613
|
+
<button
|
|
614
|
+
id="tabChangelog"
|
|
615
|
+
class="field-chip"
|
|
616
|
+
type="button"
|
|
617
|
+
aria-pressed="false"
|
|
618
|
+
>
|
|
556
619
|
Changelog
|
|
557
620
|
</button>
|
|
558
|
-
<button id="tabChangelogSource" class="field-chip" type="button" aria-pressed="false">
|
|
559
|
-
Changelog / By Source
|
|
560
|
-
</button>
|
|
561
621
|
</div>
|
|
562
622
|
</div>
|
|
563
623
|
</div>
|
|
@@ -567,7 +627,10 @@
|
|
|
567
627
|
<div id="activeFilterChips" class="chips filters"></div>
|
|
568
628
|
</div>
|
|
569
629
|
|
|
570
|
-
<div id="status" class="meta">
|
|
630
|
+
<div id="status" class="meta">
|
|
631
|
+
Load a leaves export, changelog export, or unified bundle JSON to
|
|
632
|
+
begin.
|
|
633
|
+
</div>
|
|
571
634
|
</div>
|
|
572
635
|
|
|
573
636
|
<div id="results"></div>
|
|
@@ -585,10 +648,22 @@
|
|
|
585
648
|
label: 'description',
|
|
586
649
|
get: (leaf) => [leaf.cfg?.description],
|
|
587
650
|
},
|
|
588
|
-
{
|
|
651
|
+
{
|
|
652
|
+
id: 'docsGroup',
|
|
653
|
+
label: 'docsGroup',
|
|
654
|
+
get: (leaf) => [leaf.cfg?.docsGroup],
|
|
655
|
+
},
|
|
589
656
|
{ id: 'tags', label: 'tags', get: (leaf) => leaf.cfg?.tags || [] },
|
|
590
|
-
{
|
|
591
|
-
|
|
657
|
+
{
|
|
658
|
+
id: 'stability',
|
|
659
|
+
label: 'stability',
|
|
660
|
+
get: (leaf) => [leaf.cfg?.stability],
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
id: 'docsMeta',
|
|
664
|
+
label: 'docsMeta',
|
|
665
|
+
get: (leaf) => [leaf.cfg?.docsMeta],
|
|
666
|
+
},
|
|
592
667
|
{
|
|
593
668
|
id: 'sourceDefinition',
|
|
594
669
|
label: 'source definition',
|
|
@@ -617,7 +692,8 @@
|
|
|
617
692
|
{
|
|
618
693
|
id: 'types',
|
|
619
694
|
label: 'types',
|
|
620
|
-
get: (leaf, schemaFlatByLeaf) =>
|
|
695
|
+
get: (leaf, schemaFlatByLeaf) =>
|
|
696
|
+
schemaTypeTokens(schemaFlatByLeaf?.[leaf.key]),
|
|
621
697
|
},
|
|
622
698
|
{
|
|
623
699
|
id: 'params',
|
|
@@ -694,35 +770,6 @@
|
|
|
694
770
|
},
|
|
695
771
|
]
|
|
696
772
|
|
|
697
|
-
const CHANGELOG_SOURCE_FIELDS = [
|
|
698
|
-
{
|
|
699
|
-
id: 'sourceObject',
|
|
700
|
-
label: 'source object',
|
|
701
|
-
get: (item) => [item.sourceId, item.displayName],
|
|
702
|
-
},
|
|
703
|
-
{
|
|
704
|
-
id: 'eventType',
|
|
705
|
-
label: 'event type',
|
|
706
|
-
get: (item) => item.events.map((event) => event.type),
|
|
707
|
-
},
|
|
708
|
-
{
|
|
709
|
-
id: 'impactedRoutes',
|
|
710
|
-
label: 'impacted routes',
|
|
711
|
-
get: (item) =>
|
|
712
|
-
item.events.flatMap((event) => (Array.isArray(event.impactedRoutes) ? event.impactedRoutes : [])),
|
|
713
|
-
},
|
|
714
|
-
{
|
|
715
|
-
id: 'schemaDiff',
|
|
716
|
-
label: 'schema diff',
|
|
717
|
-
get: (item) =>
|
|
718
|
-
item.events.flatMap((event) =>
|
|
719
|
-
Array.isArray(event.schemaDiff)
|
|
720
|
-
? event.schemaDiff.map((delta) => JSON.stringify(delta))
|
|
721
|
-
: [],
|
|
722
|
-
),
|
|
723
|
-
},
|
|
724
|
-
]
|
|
725
|
-
|
|
726
773
|
const SCHEMA_SECTIONS = ['params', 'query', 'body', 'output']
|
|
727
774
|
const SCHEMA_FIELD_IDS = new Set(SCHEMA_SECTIONS)
|
|
728
775
|
const SOURCE_FIELD_IDS = new Set(['sourceDefinition', 'sourceSchemas'])
|
|
@@ -736,30 +783,29 @@
|
|
|
736
783
|
{
|
|
737
784
|
id: 'core',
|
|
738
785
|
label: 'Core fields',
|
|
739
|
-
fieldIds: SEARCH_FIELDS.filter((field) =>
|
|
740
|
-
(field
|
|
741
|
-
),
|
|
786
|
+
fieldIds: SEARCH_FIELDS.filter((field) =>
|
|
787
|
+
CORE_FIELD_IDS.has(field.id),
|
|
788
|
+
).map((field) => field.id),
|
|
742
789
|
},
|
|
743
790
|
{
|
|
744
791
|
id: 'schema',
|
|
745
792
|
label: 'Schema fields',
|
|
746
|
-
fieldIds: SEARCH_FIELDS.filter((field) =>
|
|
747
|
-
(field
|
|
748
|
-
),
|
|
793
|
+
fieldIds: SEARCH_FIELDS.filter((field) =>
|
|
794
|
+
SCHEMA_SCOPE_FIELD_IDS.has(field.id),
|
|
795
|
+
).map((field) => field.id),
|
|
749
796
|
},
|
|
750
797
|
{
|
|
751
798
|
id: 'source',
|
|
752
799
|
label: 'Source fields',
|
|
753
|
-
fieldIds: SEARCH_FIELDS.filter((field) =>
|
|
754
|
-
(field
|
|
755
|
-
),
|
|
800
|
+
fieldIds: SEARCH_FIELDS.filter((field) =>
|
|
801
|
+
SOURCE_FIELD_IDS.has(field.id),
|
|
802
|
+
).map((field) => field.id),
|
|
756
803
|
},
|
|
757
804
|
]
|
|
758
805
|
|
|
759
806
|
const VIEW_IDS = {
|
|
760
807
|
leaves: 'leaves',
|
|
761
808
|
changelog: 'changelog',
|
|
762
|
-
changelogSource: 'changelogSource',
|
|
763
809
|
}
|
|
764
810
|
|
|
765
811
|
const VIEWER_MODE = {
|
|
@@ -790,11 +836,9 @@
|
|
|
790
836
|
},
|
|
791
837
|
[VIEW_IDS.changelog]: {
|
|
792
838
|
fieldDefs: CHANGELOG_TIMELINE_FIELDS,
|
|
793
|
-
defaultSelected: new Set(
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
fieldDefs: CHANGELOG_SOURCE_FIELDS,
|
|
797
|
-
defaultSelected: new Set(CHANGELOG_SOURCE_FIELDS.map((field) => field.id)),
|
|
839
|
+
defaultSelected: new Set(
|
|
840
|
+
CHANGELOG_TIMELINE_FIELDS.map((field) => field.id),
|
|
841
|
+
),
|
|
798
842
|
},
|
|
799
843
|
}
|
|
800
844
|
|
|
@@ -807,9 +851,12 @@
|
|
|
807
851
|
viewerMode: VIEWER_MODE.leaves,
|
|
808
852
|
availableTabs: new Set([VIEW_IDS.leaves]),
|
|
809
853
|
selectedFieldIdsByTab: {
|
|
810
|
-
[VIEW_IDS.leaves]: new Set(
|
|
811
|
-
|
|
812
|
-
|
|
854
|
+
[VIEW_IDS.leaves]: new Set(
|
|
855
|
+
TAB_CONFIG[VIEW_IDS.leaves].defaultSelected,
|
|
856
|
+
),
|
|
857
|
+
[VIEW_IDS.changelog]: new Set(
|
|
858
|
+
TAB_CONFIG[VIEW_IDS.changelog].defaultSelected,
|
|
859
|
+
),
|
|
813
860
|
},
|
|
814
861
|
}
|
|
815
862
|
|
|
@@ -818,7 +865,9 @@
|
|
|
818
865
|
const caseSensitiveToggle = document.getElementById('caseSensitive')
|
|
819
866
|
const regexSearchToggle = document.getElementById('regexSearch')
|
|
820
867
|
const typeMatchModeInput = document.getElementById('typeMatchMode')
|
|
821
|
-
const schemaRowsMatchOnlyToggle = document.getElementById(
|
|
868
|
+
const schemaRowsMatchOnlyToggle = document.getElementById(
|
|
869
|
+
'schemaRowsMatchOnly',
|
|
870
|
+
)
|
|
822
871
|
const fieldChipGroups = document.getElementById('fieldChipGroups')
|
|
823
872
|
const activeFilterChips = document.getElementById('activeFilterChips')
|
|
824
873
|
const selectAllFieldsBtn = document.getElementById('selectAllFields')
|
|
@@ -833,7 +882,6 @@
|
|
|
833
882
|
const controlsEl = document.querySelector('.controls')
|
|
834
883
|
const tabLeavesBtn = document.getElementById('tabLeaves')
|
|
835
884
|
const tabChangelogBtn = document.getElementById('tabChangelog')
|
|
836
|
-
const tabChangelogSourceBtn = document.getElementById('tabChangelogSource')
|
|
837
885
|
|
|
838
886
|
const URL_PARAM_KEY = 'filters'
|
|
839
887
|
let isHydratingFromUrl = false
|
|
@@ -846,7 +894,9 @@
|
|
|
846
894
|
}
|
|
847
895
|
|
|
848
896
|
function applyViewerModeMeta() {
|
|
849
|
-
const meta =
|
|
897
|
+
const meta =
|
|
898
|
+
VIEWER_MODE_META[state.viewerMode] ||
|
|
899
|
+
VIEWER_MODE_META[VIEWER_MODE.leaves]
|
|
850
900
|
document.title = meta.title
|
|
851
901
|
if (viewerHeadingEl) viewerHeadingEl.textContent = meta.heading
|
|
852
902
|
}
|
|
@@ -958,7 +1008,8 @@
|
|
|
958
1008
|
function toTokens(value) {
|
|
959
1009
|
if (value === null || value === undefined) return []
|
|
960
1010
|
if (typeof value === 'string') return [value]
|
|
961
|
-
if (typeof value === 'number' || typeof value === 'boolean')
|
|
1011
|
+
if (typeof value === 'number' || typeof value === 'boolean')
|
|
1012
|
+
return [String(value)]
|
|
962
1013
|
if (Array.isArray(value)) return value.flatMap((item) => toTokens(item))
|
|
963
1014
|
if (typeof value === 'object') return [JSON.stringify(value)]
|
|
964
1015
|
return []
|
|
@@ -997,7 +1048,8 @@
|
|
|
997
1048
|
function schemaSectionToSearchTokens(flatSchema, sectionName) {
|
|
998
1049
|
if (!flatSchema || typeof flatSchema !== 'object') return []
|
|
999
1050
|
const sectionEntries = Object.entries(flatSchema).filter(
|
|
1000
|
-
([path]) =>
|
|
1051
|
+
([path]) =>
|
|
1052
|
+
path === sectionName || path.startsWith(`${sectionName}.`),
|
|
1001
1053
|
)
|
|
1002
1054
|
|
|
1003
1055
|
if (sectionEntries.length === 0) return []
|
|
@@ -1045,12 +1097,20 @@
|
|
|
1045
1097
|
return Array.from(tokens)
|
|
1046
1098
|
}
|
|
1047
1099
|
|
|
1048
|
-
function schemaEntryMatchesActiveFilter(
|
|
1100
|
+
function schemaEntryMatchesActiveFilter(
|
|
1101
|
+
sectionName,
|
|
1102
|
+
fullPath,
|
|
1103
|
+
info,
|
|
1104
|
+
engine,
|
|
1105
|
+
selectedIds,
|
|
1106
|
+
) {
|
|
1049
1107
|
if (!engine.active) return true
|
|
1050
1108
|
|
|
1051
1109
|
let matched = false
|
|
1052
1110
|
if (selectedIds.includes(sectionName)) {
|
|
1053
|
-
matched = schemaEntryTokens(fullPath, info).some((token) =>
|
|
1111
|
+
matched = schemaEntryTokens(fullPath, info).some((token) =>
|
|
1112
|
+
engine.test(token),
|
|
1113
|
+
)
|
|
1054
1114
|
}
|
|
1055
1115
|
|
|
1056
1116
|
if (!matched && selectedIds.includes('types')) {
|
|
@@ -1064,7 +1124,9 @@
|
|
|
1064
1124
|
}
|
|
1065
1125
|
|
|
1066
1126
|
if (typeMatchModeInput.value === 'exact' && !engine.regex) {
|
|
1067
|
-
const needle = engine.caseSensitive
|
|
1127
|
+
const needle = engine.caseSensitive
|
|
1128
|
+
? engine.query
|
|
1129
|
+
: engine.query.toLowerCase()
|
|
1068
1130
|
const normalized = engine.caseSensitive
|
|
1069
1131
|
? typeTokens
|
|
1070
1132
|
: typeTokens.map((token) => token.toLowerCase())
|
|
@@ -1086,8 +1148,14 @@
|
|
|
1086
1148
|
return SEARCH_FIELDS.some((field) => {
|
|
1087
1149
|
if (!selectedIds.includes(field.id)) return false
|
|
1088
1150
|
const tokens = toTokens(field.get(leaf, schemaFlatByLeaf, payload))
|
|
1089
|
-
if (
|
|
1090
|
-
|
|
1151
|
+
if (
|
|
1152
|
+
field.id === 'types' &&
|
|
1153
|
+
typeMatchModeInput.value === 'exact' &&
|
|
1154
|
+
!engine.regex
|
|
1155
|
+
) {
|
|
1156
|
+
const needle = engine.caseSensitive
|
|
1157
|
+
? engine.query
|
|
1158
|
+
: engine.query.toLowerCase()
|
|
1091
1159
|
const normalized = engine.caseSensitive
|
|
1092
1160
|
? tokens
|
|
1093
1161
|
: tokens.map((token) => String(token).toLowerCase())
|
|
@@ -1125,14 +1193,25 @@
|
|
|
1125
1193
|
}
|
|
1126
1194
|
|
|
1127
1195
|
function setHighlighted(node, text, engine, selectedIds, fieldIds) {
|
|
1128
|
-
node.innerHTML = highlightWithFieldScope(
|
|
1196
|
+
node.innerHTML = highlightWithFieldScope(
|
|
1197
|
+
text,
|
|
1198
|
+
engine,
|
|
1199
|
+
selectedIds,
|
|
1200
|
+
fieldIds,
|
|
1201
|
+
)
|
|
1129
1202
|
}
|
|
1130
1203
|
|
|
1131
1204
|
function kv(key, value, engine, selectedIds, fieldIds) {
|
|
1132
1205
|
const box = el('div', 'kv')
|
|
1133
1206
|
box.appendChild(el('div', 'k', key))
|
|
1134
1207
|
const valueNode = el('div', 'v mono')
|
|
1135
|
-
setHighlighted(
|
|
1208
|
+
setHighlighted(
|
|
1209
|
+
valueNode,
|
|
1210
|
+
value === undefined ? '—' : String(value),
|
|
1211
|
+
engine,
|
|
1212
|
+
selectedIds,
|
|
1213
|
+
fieldIds,
|
|
1214
|
+
)
|
|
1136
1215
|
box.appendChild(valueNode)
|
|
1137
1216
|
return box
|
|
1138
1217
|
}
|
|
@@ -1197,7 +1276,12 @@
|
|
|
1197
1276
|
link.href = href
|
|
1198
1277
|
link.target = '_blank'
|
|
1199
1278
|
link.rel = 'noopener noreferrer'
|
|
1200
|
-
link.innerHTML = highlightWithFieldScope(
|
|
1279
|
+
link.innerHTML = highlightWithFieldScope(
|
|
1280
|
+
label,
|
|
1281
|
+
engine,
|
|
1282
|
+
selectedIds,
|
|
1283
|
+
fieldIds,
|
|
1284
|
+
)
|
|
1201
1285
|
labelNode.appendChild(link)
|
|
1202
1286
|
box.appendChild(labelNode)
|
|
1203
1287
|
return box
|
|
@@ -1233,7 +1317,11 @@
|
|
|
1233
1317
|
|
|
1234
1318
|
function getSchemaSource(source, sectionName) {
|
|
1235
1319
|
const schemaKey = SCHEMA_SOURCE_KEYS_BY_SECTION[sectionName]
|
|
1236
|
-
if (
|
|
1320
|
+
if (
|
|
1321
|
+
!schemaKey ||
|
|
1322
|
+
!source?.schemas ||
|
|
1323
|
+
typeof source.schemas !== 'object'
|
|
1324
|
+
) {
|
|
1237
1325
|
return {
|
|
1238
1326
|
schemaKey,
|
|
1239
1327
|
sourceValue: undefined,
|
|
@@ -1247,8 +1335,11 @@
|
|
|
1247
1335
|
}
|
|
1248
1336
|
|
|
1249
1337
|
function resolveSchemaSourceLabel(schemaKey, sourceValue) {
|
|
1250
|
-
if (!sourceValue || typeof sourceValue !== 'object')
|
|
1251
|
-
|
|
1338
|
+
if (!sourceValue || typeof sourceValue !== 'object')
|
|
1339
|
+
return schemaKey || 'schema'
|
|
1340
|
+
return (
|
|
1341
|
+
sourceValue.sourceName || sourceValue.tag || schemaKey || 'schema'
|
|
1342
|
+
)
|
|
1252
1343
|
}
|
|
1253
1344
|
|
|
1254
1345
|
function createTreeNode(name = '') {
|
|
@@ -1265,7 +1356,10 @@
|
|
|
1265
1356
|
Object.entries(entries)
|
|
1266
1357
|
.sort(([a], [b]) => a.localeCompare(b))
|
|
1267
1358
|
.forEach(([fullPath, info]) => {
|
|
1268
|
-
const trimmed =
|
|
1359
|
+
const trimmed =
|
|
1360
|
+
fullPath === sectionName
|
|
1361
|
+
? ''
|
|
1362
|
+
: fullPath.slice(sectionName.length + 1)
|
|
1269
1363
|
const segments = trimmed ? trimmed.split('.') : []
|
|
1270
1364
|
|
|
1271
1365
|
let current = root
|
|
@@ -1307,10 +1401,13 @@
|
|
|
1307
1401
|
|
|
1308
1402
|
const appendTypeCell = (row, info) => {
|
|
1309
1403
|
const type = el('span', 'tree-pill')
|
|
1310
|
-
setHighlighted(
|
|
1311
|
-
|
|
1312
|
-
'
|
|
1313
|
-
|
|
1404
|
+
setHighlighted(
|
|
1405
|
+
type,
|
|
1406
|
+
info?.type || info?.kind || '—',
|
|
1407
|
+
engine,
|
|
1408
|
+
selectedIds,
|
|
1409
|
+
[sectionName, 'types'],
|
|
1410
|
+
)
|
|
1314
1411
|
row.appendChild(type)
|
|
1315
1412
|
}
|
|
1316
1413
|
|
|
@@ -1331,7 +1428,13 @@
|
|
|
1331
1428
|
.sort((a, b) => a.localeCompare(b))
|
|
1332
1429
|
.forEach((key) =>
|
|
1333
1430
|
container.appendChild(
|
|
1334
|
-
renderTreeNode(
|
|
1431
|
+
renderTreeNode(
|
|
1432
|
+
node.children[key],
|
|
1433
|
+
engine,
|
|
1434
|
+
selectedIds,
|
|
1435
|
+
sectionName,
|
|
1436
|
+
false,
|
|
1437
|
+
),
|
|
1335
1438
|
),
|
|
1336
1439
|
)
|
|
1337
1440
|
details.appendChild(container)
|
|
@@ -1352,7 +1455,8 @@
|
|
|
1352
1455
|
|
|
1353
1456
|
const grouped = splitFlatSchemaBySection(flatSchema)
|
|
1354
1457
|
let hasAnySchemaEntries = false
|
|
1355
|
-
const limitToMatchedRows =
|
|
1458
|
+
const limitToMatchedRows =
|
|
1459
|
+
isPressed(schemaRowsMatchOnlyToggle) && engine.active
|
|
1356
1460
|
|
|
1357
1461
|
SCHEMA_SECTIONS.forEach((sectionName) => {
|
|
1358
1462
|
const rawEntries = grouped[sectionName]
|
|
@@ -1361,7 +1465,13 @@
|
|
|
1361
1465
|
const entries = limitToMatchedRows
|
|
1362
1466
|
? Object.fromEntries(
|
|
1363
1467
|
Object.entries(rawEntries).filter(([fullPath, info]) =>
|
|
1364
|
-
schemaEntryMatchesActiveFilter(
|
|
1468
|
+
schemaEntryMatchesActiveFilter(
|
|
1469
|
+
sectionName,
|
|
1470
|
+
fullPath,
|
|
1471
|
+
info,
|
|
1472
|
+
engine,
|
|
1473
|
+
selectedIds,
|
|
1474
|
+
),
|
|
1365
1475
|
),
|
|
1366
1476
|
)
|
|
1367
1477
|
: rawEntries
|
|
@@ -1390,7 +1500,9 @@
|
|
|
1390
1500
|
}
|
|
1391
1501
|
|
|
1392
1502
|
const tree = buildSchemaTree(entries, sectionName)
|
|
1393
|
-
block.appendChild(
|
|
1503
|
+
block.appendChild(
|
|
1504
|
+
renderTreeNode(tree, engine, selectedIds, sectionName, true),
|
|
1505
|
+
)
|
|
1394
1506
|
|
|
1395
1507
|
section.appendChild(block)
|
|
1396
1508
|
})
|
|
@@ -1417,7 +1529,9 @@
|
|
|
1417
1529
|
const overview = el('div', 'section')
|
|
1418
1530
|
overview.appendChild(el('h3', '', 'Overview'))
|
|
1419
1531
|
const topGrid = el('div', 'grid-3')
|
|
1420
|
-
topGrid.appendChild(
|
|
1532
|
+
topGrid.appendChild(
|
|
1533
|
+
kv('group', cfg.docsGroup, engine, selectedIds, 'docsGroup'),
|
|
1534
|
+
)
|
|
1421
1535
|
topGrid.appendChild(
|
|
1422
1536
|
kv(
|
|
1423
1537
|
'tags',
|
|
@@ -1427,10 +1541,22 @@
|
|
|
1427
1541
|
'tags',
|
|
1428
1542
|
),
|
|
1429
1543
|
)
|
|
1430
|
-
topGrid.appendChild(
|
|
1544
|
+
topGrid.appendChild(
|
|
1545
|
+
kv('stability', cfg.stability, engine, selectedIds, 'stability'),
|
|
1546
|
+
)
|
|
1431
1547
|
overview.appendChild(topGrid)
|
|
1432
|
-
overview.appendChild(
|
|
1433
|
-
|
|
1548
|
+
overview.appendChild(
|
|
1549
|
+
kv('summary', cfg.summary, engine, selectedIds, 'summary'),
|
|
1550
|
+
)
|
|
1551
|
+
overview.appendChild(
|
|
1552
|
+
kv(
|
|
1553
|
+
'description',
|
|
1554
|
+
cfg.description,
|
|
1555
|
+
engine,
|
|
1556
|
+
selectedIds,
|
|
1557
|
+
'description',
|
|
1558
|
+
),
|
|
1559
|
+
)
|
|
1434
1560
|
|
|
1435
1561
|
const iconRow = el('div', 'icon-row')
|
|
1436
1562
|
if (cfg.feed) {
|
|
@@ -1473,11 +1599,22 @@
|
|
|
1473
1599
|
const source = sourceByLeaf[leaf.key]
|
|
1474
1600
|
if (source?.definition) {
|
|
1475
1601
|
overview.appendChild(
|
|
1476
|
-
createSourceRow(
|
|
1602
|
+
createSourceRow(
|
|
1603
|
+
'definition',
|
|
1604
|
+
source.definition,
|
|
1605
|
+
engine,
|
|
1606
|
+
selectedIds,
|
|
1607
|
+
'sourceDefinition',
|
|
1608
|
+
),
|
|
1477
1609
|
)
|
|
1478
1610
|
}
|
|
1479
1611
|
|
|
1480
|
-
const separatedSchemas = renderSeparatedSchemas(
|
|
1612
|
+
const separatedSchemas = renderSeparatedSchemas(
|
|
1613
|
+
flatSchema,
|
|
1614
|
+
engine,
|
|
1615
|
+
selectedIds,
|
|
1616
|
+
source,
|
|
1617
|
+
)
|
|
1481
1618
|
if (separatedSchemas) {
|
|
1482
1619
|
content.appendChild(separatedSchemas)
|
|
1483
1620
|
}
|
|
@@ -1485,7 +1622,21 @@
|
|
|
1485
1622
|
const routeHistory = state.changelogPayload?.byRoute?.[leaf.key]
|
|
1486
1623
|
if (Array.isArray(routeHistory) && routeHistory.length > 0) {
|
|
1487
1624
|
const commitBySha = new Map(
|
|
1488
|
-
(state.changelogPayload?.commits || []).map((commit) => [
|
|
1625
|
+
(state.changelogPayload?.commits || []).map((commit) => [
|
|
1626
|
+
commit.sha,
|
|
1627
|
+
commit,
|
|
1628
|
+
]),
|
|
1629
|
+
)
|
|
1630
|
+
const commitOrder = new Map(
|
|
1631
|
+
(state.changelogPayload?.commits || []).map((commit, index) => [
|
|
1632
|
+
commit.sha,
|
|
1633
|
+
index,
|
|
1634
|
+
]),
|
|
1635
|
+
)
|
|
1636
|
+
const routeHistoryNewestFirst = sortEventsNewestFirst(
|
|
1637
|
+
routeHistory,
|
|
1638
|
+
commitBySha,
|
|
1639
|
+
commitOrder,
|
|
1489
1640
|
)
|
|
1490
1641
|
const routeChangelogSection = el('div', 'section')
|
|
1491
1642
|
const routeChangelogDetails = el('details')
|
|
@@ -1500,7 +1651,7 @@
|
|
|
1500
1651
|
routeChangelogDetails.appendChild(routeChangelogSummary)
|
|
1501
1652
|
|
|
1502
1653
|
const routeChangelogBody = el('div', 'leaf-content')
|
|
1503
|
-
|
|
1654
|
+
routeHistoryNewestFirst.forEach((event) => {
|
|
1504
1655
|
routeChangelogBody.appendChild(renderEventCard(event, commitBySha))
|
|
1505
1656
|
})
|
|
1506
1657
|
routeChangelogDetails.appendChild(routeChangelogBody)
|
|
@@ -1553,18 +1704,134 @@
|
|
|
1553
1704
|
return parts.join(', ')
|
|
1554
1705
|
}
|
|
1555
1706
|
|
|
1707
|
+
function schemaFlags(nullable, optional) {
|
|
1708
|
+
return `${nullable ? '-' : ''}${optional ? '?' : ''}`
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
function formatEntryTypeLabel(entry) {
|
|
1712
|
+
if (!entry || typeof entry !== 'object') return null
|
|
1713
|
+
const type = typeof entry.type === 'string' ? entry.type : 'unknown'
|
|
1714
|
+
return `${type}${schemaFlags(Boolean(entry.nullable), Boolean(entry.optional))}`
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
function formatPathLabel(path, entry) {
|
|
1718
|
+
const basePath = typeof path === 'string' ? path : ''
|
|
1719
|
+
return `${basePath}${schemaFlags(Boolean(entry?.nullable), Boolean(entry?.optional))}`
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
function parseSignatureTypeLabel(signature) {
|
|
1723
|
+
if (typeof signature !== 'string') return null
|
|
1724
|
+
const typeMatch = signature.match(/(?:^|,\s*)type=([^,]+)/)
|
|
1725
|
+
const nullableMatch = signature.match(/(?:^|,\s*)nullable=(true|false)/)
|
|
1726
|
+
const optionalMatch = signature.match(/(?:^|,\s*)optional=(true|false)/)
|
|
1727
|
+
if (!typeMatch) return null
|
|
1728
|
+
const type = typeMatch[1]
|
|
1729
|
+
const nullable = nullableMatch?.[1] === 'true'
|
|
1730
|
+
const optional = optionalMatch?.[1] === 'true'
|
|
1731
|
+
return `${type}${schemaFlags(nullable, optional)}`
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
function formatSourceTypeLabel(signatures) {
|
|
1735
|
+
if (!Array.isArray(signatures) || signatures.length === 0) return null
|
|
1736
|
+
const labels = signatures
|
|
1737
|
+
.map((item) => parseSignatureTypeLabel(item))
|
|
1738
|
+
.filter(Boolean)
|
|
1739
|
+
if (labels.length === 0) return null
|
|
1740
|
+
return labels.join(' | ')
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
function schemaDiffOperation(op) {
|
|
1744
|
+
if (op === 'added') {
|
|
1745
|
+
return { symbol: '+', word: 'added', className: 'added' }
|
|
1746
|
+
}
|
|
1747
|
+
if (op === 'removed') {
|
|
1748
|
+
return { symbol: '-', word: 'removed', className: 'removed' }
|
|
1749
|
+
}
|
|
1750
|
+
return { symbol: '*', word: 'changed', className: 'changed' }
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
function buildSchemaDiffLine(op, beforeType, pathLabel, afterType) {
|
|
1754
|
+
if (!pathLabel) return null
|
|
1755
|
+
const line = el('div', 'meta mono changelog-diff-line')
|
|
1756
|
+
const operation = schemaDiffOperation(op)
|
|
1757
|
+
line.appendChild(
|
|
1758
|
+
el(
|
|
1759
|
+
'span',
|
|
1760
|
+
`changelog-op ${operation.className}`,
|
|
1761
|
+
`${operation.symbol} ${operation.word}`,
|
|
1762
|
+
),
|
|
1763
|
+
)
|
|
1764
|
+
if (beforeType) {
|
|
1765
|
+
line.appendChild(el('span', 'changelog-schema-type', beforeType))
|
|
1766
|
+
}
|
|
1767
|
+
line.appendChild(el('span', '', pathLabel))
|
|
1768
|
+
if (operation.className === 'changed' && afterType) {
|
|
1769
|
+
line.appendChild(el('span', '', '->'))
|
|
1770
|
+
line.appendChild(el('span', 'changelog-schema-type', afterType))
|
|
1771
|
+
}
|
|
1772
|
+
return line
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
function buildLegacySchemaDiffLine(text) {
|
|
1776
|
+
return el('div', 'meta mono', text)
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1556
1779
|
function formatSchemaDiffLine(delta) {
|
|
1557
1780
|
if (!delta || typeof delta !== 'object') return null
|
|
1558
1781
|
if ('section' in delta) {
|
|
1559
1782
|
const location = `${delta.section}.${delta.path}`
|
|
1560
|
-
if (delta.op === 'added')
|
|
1561
|
-
|
|
1562
|
-
|
|
1783
|
+
if (delta.op === 'added') {
|
|
1784
|
+
const afterType = formatSourceTypeLabel(delta.after)
|
|
1785
|
+
if (afterType) return buildSchemaDiffLine(delta.op, afterType, location)
|
|
1786
|
+
return buildLegacySchemaDiffLine(
|
|
1787
|
+
`added ${location}: ${JSON.stringify(delta.after || [])}`,
|
|
1788
|
+
)
|
|
1789
|
+
}
|
|
1790
|
+
if (delta.op === 'removed') {
|
|
1791
|
+
const beforeType = formatSourceTypeLabel(delta.before)
|
|
1792
|
+
if (beforeType)
|
|
1793
|
+
return buildSchemaDiffLine(delta.op, beforeType, location)
|
|
1794
|
+
return buildLegacySchemaDiffLine(
|
|
1795
|
+
`removed ${location}: ${JSON.stringify(delta.before || [])}`,
|
|
1796
|
+
)
|
|
1797
|
+
}
|
|
1798
|
+
const beforeType = formatSourceTypeLabel(delta.before)
|
|
1799
|
+
const afterType = formatSourceTypeLabel(delta.after)
|
|
1800
|
+
if (beforeType || afterType) {
|
|
1801
|
+
return buildSchemaDiffLine(
|
|
1802
|
+
delta.op,
|
|
1803
|
+
beforeType || 'unknown',
|
|
1804
|
+
location,
|
|
1805
|
+
afterType || 'unknown',
|
|
1806
|
+
)
|
|
1807
|
+
}
|
|
1808
|
+
return buildLegacySchemaDiffLine(
|
|
1809
|
+
`changed ${location}: ${JSON.stringify(delta.before || [])} -> ${JSON.stringify(delta.after || [])}`,
|
|
1810
|
+
)
|
|
1563
1811
|
}
|
|
1564
1812
|
if ('path' in delta) {
|
|
1565
|
-
if (delta.op === 'added')
|
|
1566
|
-
|
|
1567
|
-
|
|
1813
|
+
if (delta.op === 'added') {
|
|
1814
|
+
const afterType = formatEntryTypeLabel(delta.after)
|
|
1815
|
+
const pathLabel = formatPathLabel(delta.path, delta.after)
|
|
1816
|
+
if (afterType) return buildSchemaDiffLine(delta.op, afterType, pathLabel)
|
|
1817
|
+
return buildLegacySchemaDiffLine(
|
|
1818
|
+
`added ${delta.path}: ${formatRouteSchemaEntry(delta.after)}`,
|
|
1819
|
+
)
|
|
1820
|
+
}
|
|
1821
|
+
if (delta.op === 'removed') {
|
|
1822
|
+
const beforeType = formatEntryTypeLabel(delta.before)
|
|
1823
|
+
const pathLabel = formatPathLabel(delta.path, delta.before)
|
|
1824
|
+
if (beforeType)
|
|
1825
|
+
return buildSchemaDiffLine(delta.op, beforeType, pathLabel)
|
|
1826
|
+
return buildLegacySchemaDiffLine(
|
|
1827
|
+
`removed ${delta.path}: ${formatRouteSchemaEntry(delta.before)}`,
|
|
1828
|
+
)
|
|
1829
|
+
}
|
|
1830
|
+
const beforeType = formatEntryTypeLabel(delta.before) || 'unknown'
|
|
1831
|
+
const afterType = formatEntryTypeLabel(delta.after) || 'unknown'
|
|
1832
|
+
const pathLabel =
|
|
1833
|
+
formatPathLabel(delta.path, delta.after || delta.before) || delta.path
|
|
1834
|
+
return buildSchemaDiffLine(delta.op, beforeType, pathLabel, afterType)
|
|
1568
1835
|
}
|
|
1569
1836
|
return null
|
|
1570
1837
|
}
|
|
@@ -1589,17 +1856,21 @@
|
|
|
1589
1856
|
card.appendChild(el('div', 'meta', commitMeta))
|
|
1590
1857
|
card.appendChild(el('div', 'mono', event.type))
|
|
1591
1858
|
if (Array.isArray(event.schemaDiff) && event.schemaDiff.length > 0) {
|
|
1592
|
-
card.appendChild(
|
|
1859
|
+
card.appendChild(
|
|
1860
|
+
el('div', 'meta', `schema changes: ${event.schemaDiff.length}`),
|
|
1861
|
+
)
|
|
1593
1862
|
const schemaChanges = el('div')
|
|
1594
1863
|
event.schemaDiff.forEach((delta) => {
|
|
1595
|
-
const
|
|
1596
|
-
if (!
|
|
1597
|
-
schemaChanges.appendChild(
|
|
1864
|
+
const lineNode = formatSchemaDiffLine(delta)
|
|
1865
|
+
if (!lineNode) return
|
|
1866
|
+
schemaChanges.appendChild(lineNode)
|
|
1598
1867
|
})
|
|
1599
1868
|
card.appendChild(schemaChanges)
|
|
1600
1869
|
}
|
|
1601
1870
|
if (Array.isArray(event.cfgDiff) && event.cfgDiff.length > 0) {
|
|
1602
|
-
card.appendChild(
|
|
1871
|
+
card.appendChild(
|
|
1872
|
+
el('div', 'meta', `cfg changes: ${event.cfgDiff.length}`),
|
|
1873
|
+
)
|
|
1603
1874
|
const cfgChanges = el('div')
|
|
1604
1875
|
event.cfgDiff.forEach((diff) => {
|
|
1605
1876
|
const line = formatCfgDiffLine(diff)
|
|
@@ -1608,8 +1879,17 @@
|
|
|
1608
1879
|
})
|
|
1609
1880
|
card.appendChild(cfgChanges)
|
|
1610
1881
|
}
|
|
1611
|
-
if (
|
|
1612
|
-
|
|
1882
|
+
if (
|
|
1883
|
+
Array.isArray(event.impactedRoutes) &&
|
|
1884
|
+
event.impactedRoutes.length > 0
|
|
1885
|
+
) {
|
|
1886
|
+
card.appendChild(
|
|
1887
|
+
el(
|
|
1888
|
+
'div',
|
|
1889
|
+
'meta',
|
|
1890
|
+
`impacted routes: ${event.impactedRoutes.length}`,
|
|
1891
|
+
),
|
|
1892
|
+
)
|
|
1613
1893
|
}
|
|
1614
1894
|
return card
|
|
1615
1895
|
}
|
|
@@ -1629,14 +1909,16 @@
|
|
|
1629
1909
|
|
|
1630
1910
|
function renderChangelogEventLines(event, commitBySha, contextLabel) {
|
|
1631
1911
|
const row = el('div', 'changelog-line-item')
|
|
1632
|
-
row.appendChild(
|
|
1912
|
+
row.appendChild(
|
|
1913
|
+
el('div', 'meta', buildCommitMetaLine(event, commitBySha)),
|
|
1914
|
+
)
|
|
1633
1915
|
row.appendChild(el('div', 'mono', `${contextLabel} (${event.type})`))
|
|
1634
1916
|
|
|
1635
1917
|
if (Array.isArray(event.schemaDiff) && event.schemaDiff.length > 0) {
|
|
1636
1918
|
event.schemaDiff.forEach((delta) => {
|
|
1637
|
-
const
|
|
1638
|
-
if (!
|
|
1639
|
-
row.appendChild(
|
|
1919
|
+
const lineNode = formatSchemaDiffLine(delta)
|
|
1920
|
+
if (!lineNode) return
|
|
1921
|
+
row.appendChild(lineNode)
|
|
1640
1922
|
})
|
|
1641
1923
|
}
|
|
1642
1924
|
if (Array.isArray(event.cfgDiff) && event.cfgDiff.length > 0) {
|
|
@@ -1646,19 +1928,57 @@
|
|
|
1646
1928
|
row.appendChild(el('div', 'meta mono', line))
|
|
1647
1929
|
})
|
|
1648
1930
|
}
|
|
1649
|
-
if (
|
|
1931
|
+
if (
|
|
1932
|
+
Array.isArray(event.impactedRoutes) &&
|
|
1933
|
+
event.impactedRoutes.length > 0
|
|
1934
|
+
) {
|
|
1650
1935
|
row.appendChild(
|
|
1651
|
-
el(
|
|
1936
|
+
el(
|
|
1937
|
+
'div',
|
|
1938
|
+
'meta mono',
|
|
1939
|
+
`impacted routes: ${event.impactedRoutes.join(', ')}`,
|
|
1940
|
+
),
|
|
1652
1941
|
)
|
|
1653
1942
|
}
|
|
1654
1943
|
|
|
1655
1944
|
return row
|
|
1656
1945
|
}
|
|
1657
1946
|
|
|
1947
|
+
function commitTimestamp(commit) {
|
|
1948
|
+
if (!commit?.authorDate) return Number.NEGATIVE_INFINITY
|
|
1949
|
+
const parsed = Date.parse(commit.authorDate)
|
|
1950
|
+
return Number.isNaN(parsed) ? Number.NEGATIVE_INFINITY : parsed
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
function compareEventsNewestFirst(a, b, commitBySha, commitOrder) {
|
|
1954
|
+
const commitA = commitBySha.get(a?.commitSha)
|
|
1955
|
+
const commitB = commitBySha.get(b?.commitSha)
|
|
1956
|
+
const timeDelta = commitTimestamp(commitB) - commitTimestamp(commitA)
|
|
1957
|
+
if (timeDelta !== 0) return timeDelta
|
|
1958
|
+
|
|
1959
|
+
const indexA = commitOrder.get(a?.commitSha) ?? -1
|
|
1960
|
+
const indexB = commitOrder.get(b?.commitSha) ?? -1
|
|
1961
|
+
if (indexA !== indexB) return indexB - indexA
|
|
1962
|
+
|
|
1963
|
+
return String(b?.commitSha || '').localeCompare(
|
|
1964
|
+
String(a?.commitSha || ''),
|
|
1965
|
+
)
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1968
|
+
function sortEventsNewestFirst(events, commitBySha, commitOrder) {
|
|
1969
|
+
return [...(events || [])].sort((a, b) =>
|
|
1970
|
+
compareEventsNewestFirst(a, b, commitBySha, commitOrder),
|
|
1971
|
+
)
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1658
1974
|
function buildChronologicalEvents(payload) {
|
|
1659
1975
|
if (!payload) return []
|
|
1660
|
-
const commitBySha = new Map(
|
|
1661
|
-
|
|
1976
|
+
const commitBySha = new Map(
|
|
1977
|
+
(payload.commits || []).map((commit) => [commit.sha, commit]),
|
|
1978
|
+
)
|
|
1979
|
+
const commitOrder = new Map(
|
|
1980
|
+
(payload.commits || []).map((commit, index) => [commit.sha, index]),
|
|
1981
|
+
)
|
|
1662
1982
|
const rows = []
|
|
1663
1983
|
let sequence = 0
|
|
1664
1984
|
|
|
@@ -1669,28 +1989,34 @@
|
|
|
1669
1989
|
routeKey,
|
|
1670
1990
|
event,
|
|
1671
1991
|
commit: commitBySha.get(event.commitSha),
|
|
1992
|
+
commitSort: commitTimestamp(commitBySha.get(event.commitSha)),
|
|
1672
1993
|
commitIndex: commitOrder.get(event.commitSha) ?? -1,
|
|
1673
1994
|
eventIndex: sequence++,
|
|
1674
1995
|
})
|
|
1675
1996
|
})
|
|
1676
1997
|
})
|
|
1677
1998
|
|
|
1678
|
-
Object.entries(payload.bySourceObject || {}).forEach(
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1999
|
+
Object.entries(payload.bySourceObject || {}).forEach(
|
|
2000
|
+
([sourceObjectId, events]) => {
|
|
2001
|
+
;(events || []).forEach((event) => {
|
|
2002
|
+
rows.push({
|
|
2003
|
+
eventKind: 'source',
|
|
2004
|
+
sourceObjectId,
|
|
2005
|
+
displayName: event.displayName || sourceObjectId,
|
|
2006
|
+
event,
|
|
2007
|
+
commit: commitBySha.get(event.commitSha),
|
|
2008
|
+
commitSort: commitTimestamp(commitBySha.get(event.commitSha)),
|
|
2009
|
+
commitIndex: commitOrder.get(event.commitSha) ?? -1,
|
|
2010
|
+
eventIndex: sequence++,
|
|
2011
|
+
})
|
|
1688
2012
|
})
|
|
1689
|
-
}
|
|
1690
|
-
|
|
2013
|
+
},
|
|
2014
|
+
)
|
|
1691
2015
|
|
|
1692
2016
|
rows.sort((a, b) => {
|
|
1693
|
-
if (a.
|
|
2017
|
+
if (a.commitSort !== b.commitSort) return b.commitSort - a.commitSort
|
|
2018
|
+
if (a.commitIndex !== b.commitIndex)
|
|
2019
|
+
return b.commitIndex - a.commitIndex
|
|
1694
2020
|
return b.eventIndex - a.eventIndex
|
|
1695
2021
|
})
|
|
1696
2022
|
|
|
@@ -1703,43 +2029,14 @@
|
|
|
1703
2029
|
if (tabId === VIEW_IDS.changelog) {
|
|
1704
2030
|
return buildChronologicalEvents(payload)
|
|
1705
2031
|
}
|
|
1706
|
-
if (tabId === VIEW_IDS.changelogSource) {
|
|
1707
|
-
const commitOrder = new Map((payload.commits || []).map((commit, index) => [commit.sha, index]))
|
|
1708
|
-
const sortEventsNewestFirst = (events) =>
|
|
1709
|
-
[...(events || [])].sort((a, b) => {
|
|
1710
|
-
const aIndex = commitOrder.get(a?.commitSha) ?? -1
|
|
1711
|
-
const bIndex = commitOrder.get(b?.commitSha) ?? -1
|
|
1712
|
-
if (aIndex !== bIndex) return bIndex - aIndex
|
|
1713
|
-
return String(b?.commitSha || '').localeCompare(String(a?.commitSha || ''))
|
|
1714
|
-
})
|
|
1715
|
-
|
|
1716
|
-
return Object.entries(payload.bySourceObject || {})
|
|
1717
|
-
.map(([sourceId, events]) => {
|
|
1718
|
-
const sortedEvents = sortEventsNewestFirst(events)
|
|
1719
|
-
const latestCommitIndex = sortedEvents.length
|
|
1720
|
-
? commitOrder.get(sortedEvents[0]?.commitSha) ?? -1
|
|
1721
|
-
: -1
|
|
1722
|
-
return {
|
|
1723
|
-
sourceId,
|
|
1724
|
-
events: sortedEvents,
|
|
1725
|
-
displayName: sortedEvents[0]?.displayName || sourceId,
|
|
1726
|
-
latestCommitIndex,
|
|
1727
|
-
}
|
|
1728
|
-
})
|
|
1729
|
-
.sort((a, b) => {
|
|
1730
|
-
if (a.latestCommitIndex !== b.latestCommitIndex) {
|
|
1731
|
-
return b.latestCommitIndex - a.latestCommitIndex
|
|
1732
|
-
}
|
|
1733
|
-
return a.displayName.localeCompare(b.displayName)
|
|
1734
|
-
})
|
|
1735
|
-
}
|
|
1736
2032
|
return []
|
|
1737
2033
|
}
|
|
1738
2034
|
|
|
1739
2035
|
function matchesGenericItem(item, fieldDefs, engine, selectedIds) {
|
|
1740
2036
|
if (!engine.active) return true
|
|
1741
2037
|
return fieldDefs.some((field) => {
|
|
1742
|
-
if (selectedIds.length > 0 && !selectedIds.includes(field.id))
|
|
2038
|
+
if (selectedIds.length > 0 && !selectedIds.includes(field.id))
|
|
2039
|
+
return false
|
|
1743
2040
|
const tokens = toTokens(field.get(item))
|
|
1744
2041
|
return tokens.some((token) => engine.test(token))
|
|
1745
2042
|
})
|
|
@@ -1758,10 +2055,14 @@
|
|
|
1758
2055
|
function renderTabButtons() {
|
|
1759
2056
|
setPressed(tabLeavesBtn, state.activeTab === VIEW_IDS.leaves)
|
|
1760
2057
|
setPressed(tabChangelogBtn, state.activeTab === VIEW_IDS.changelog)
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
2058
|
+
tabLeavesBtn.style.display = state.availableTabs.has(VIEW_IDS.leaves)
|
|
2059
|
+
? ''
|
|
2060
|
+
: 'none'
|
|
2061
|
+
tabChangelogBtn.style.display = state.availableTabs.has(
|
|
2062
|
+
VIEW_IDS.changelog,
|
|
2063
|
+
)
|
|
2064
|
+
? ''
|
|
2065
|
+
: 'none'
|
|
1765
2066
|
const isLeavesTab = state.activeTab === VIEW_IDS.leaves
|
|
1766
2067
|
coreFieldsBtn.style.display = isLeavesTab ? '' : 'none'
|
|
1767
2068
|
schemasOnlyFieldsBtn.style.display = isLeavesTab ? '' : 'none'
|
|
@@ -1777,7 +2078,9 @@
|
|
|
1777
2078
|
if (engine.error) {
|
|
1778
2079
|
statusEl.textContent = `Invalid regex: ${engine.error}`
|
|
1779
2080
|
resultsEl.innerHTML = ''
|
|
1780
|
-
resultsEl.appendChild(
|
|
2081
|
+
resultsEl.appendChild(
|
|
2082
|
+
el('div', 'empty', 'Fix the regex to continue.'),
|
|
2083
|
+
)
|
|
1781
2084
|
renderActiveFilterChips({
|
|
1782
2085
|
selectedIds: selectedFieldIds(),
|
|
1783
2086
|
hasRegexError: true,
|
|
@@ -1790,43 +2093,41 @@
|
|
|
1790
2093
|
renderTabButtons()
|
|
1791
2094
|
renderActiveFilterChips({ selectedIds, hasRegexError: false })
|
|
1792
2095
|
if (state.activeTab === VIEW_IDS.leaves) {
|
|
1793
|
-
const filtered = state.leaves.filter((leaf) =>
|
|
2096
|
+
const filtered = state.leaves.filter((leaf) =>
|
|
2097
|
+
matchesLeaf(leaf, engine, selectedIds),
|
|
2098
|
+
)
|
|
1794
2099
|
statusEl.textContent = `${filtered.length} / ${state.leaves.length} routes matched.`
|
|
1795
|
-
renderCollection(
|
|
2100
|
+
renderCollection(
|
|
2101
|
+
filtered,
|
|
2102
|
+
(leaf) => renderLeaf(leaf, engine, selectedIds),
|
|
2103
|
+
'No matches.',
|
|
2104
|
+
)
|
|
1796
2105
|
} else {
|
|
1797
2106
|
const fieldDefs = currentFieldDefs()
|
|
1798
2107
|
const items = changelogItemsByTab(state.activeTab)
|
|
1799
|
-
const filtered = items.filter((item) =>
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
: `${filtered.length} / ${items.length} source changelog groups matched.`
|
|
2108
|
+
const filtered = items.filter((item) =>
|
|
2109
|
+
matchesGenericItem(item, fieldDefs, engine, selectedIds),
|
|
2110
|
+
)
|
|
2111
|
+
statusEl.textContent = `${filtered.length} / ${items.length} changelog events matched.`
|
|
1804
2112
|
const commitBySha = new Map(
|
|
1805
|
-
(state.changelogPayload?.commits || []).map((commit) => [
|
|
2113
|
+
(state.changelogPayload?.commits || []).map((commit) => [
|
|
2114
|
+
commit.sha,
|
|
2115
|
+
commit,
|
|
2116
|
+
]),
|
|
1806
2117
|
)
|
|
1807
2118
|
if (state.viewerMode === VIEWER_MODE.changelog) {
|
|
1808
2119
|
renderCollection(
|
|
1809
2120
|
filtered,
|
|
1810
2121
|
(item) => {
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
item.
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
;(item.events || []).forEach((event) => {
|
|
1821
|
-
lines.appendChild(
|
|
1822
|
-
renderChangelogEventLines(
|
|
1823
|
-
event,
|
|
1824
|
-
commitBySha,
|
|
1825
|
-
`Source: ${item.displayName || item.sourceId}`,
|
|
1826
|
-
),
|
|
1827
|
-
)
|
|
1828
|
-
})
|
|
1829
|
-
return lines
|
|
2122
|
+
const contextLabel =
|
|
2123
|
+
item.eventKind === 'route'
|
|
2124
|
+
? `Route: ${item.routeKey}`
|
|
2125
|
+
: `Source: ${item.displayName || item.sourceObjectId}`
|
|
2126
|
+
return renderChangelogEventLines(
|
|
2127
|
+
item.event,
|
|
2128
|
+
commitBySha,
|
|
2129
|
+
contextLabel,
|
|
2130
|
+
)
|
|
1830
2131
|
},
|
|
1831
2132
|
'No matches.',
|
|
1832
2133
|
)
|
|
@@ -1835,16 +2136,9 @@
|
|
|
1835
2136
|
filtered,
|
|
1836
2137
|
(item) => {
|
|
1837
2138
|
const details = el('details', 'leaf')
|
|
1838
|
-
const title =
|
|
1839
|
-
state.activeTab === VIEW_IDS.changelog
|
|
1840
|
-
? `${item.eventKind === 'route' ? `Route: ${item.routeKey}` : `Source: ${item.displayName || item.sourceObjectId}`} (${item.event.type})`
|
|
1841
|
-
: `${item.displayName} (${item.events.length})`
|
|
2139
|
+
const title = `${item.eventKind === 'route' ? `Route: ${item.routeKey}` : `Source: ${item.displayName || item.sourceObjectId}`} (${item.event.type})`
|
|
1842
2140
|
details.appendChild(el('summary', '', title))
|
|
1843
|
-
|
|
1844
|
-
details.appendChild(renderEventCard(item.event, commitBySha))
|
|
1845
|
-
} else {
|
|
1846
|
-
item.events.forEach((event) => details.appendChild(renderEventCard(event, commitBySha)))
|
|
1847
|
-
}
|
|
2141
|
+
details.appendChild(renderEventCard(item.event, commitBySha))
|
|
1848
2142
|
return details
|
|
1849
2143
|
},
|
|
1850
2144
|
'No matches.',
|
|
@@ -1855,15 +2149,17 @@
|
|
|
1855
2149
|
}
|
|
1856
2150
|
|
|
1857
2151
|
function selectedFieldIds() {
|
|
1858
|
-
const selected =
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
2152
|
+
const selected =
|
|
2153
|
+
state.selectedFieldIdsByTab[state.activeTab] || new Set()
|
|
2154
|
+
return currentFieldDefs()
|
|
2155
|
+
.filter((field) => selected.has(field.id))
|
|
2156
|
+
.map((field) => field.id)
|
|
1862
2157
|
}
|
|
1863
2158
|
|
|
1864
2159
|
function renderFieldChips() {
|
|
1865
2160
|
const fieldDefs = currentFieldDefs()
|
|
1866
|
-
const selected =
|
|
2161
|
+
const selected =
|
|
2162
|
+
state.selectedFieldIdsByTab[state.activeTab] || new Set()
|
|
1867
2163
|
fieldChipGroups.innerHTML = ''
|
|
1868
2164
|
const groups =
|
|
1869
2165
|
state.activeTab === VIEW_IDS.leaves
|
|
@@ -1871,7 +2167,10 @@
|
|
|
1871
2167
|
: [
|
|
1872
2168
|
{
|
|
1873
2169
|
id: 'tabFields',
|
|
1874
|
-
label:
|
|
2170
|
+
label:
|
|
2171
|
+
state.activeTab === VIEW_IDS.changelog
|
|
2172
|
+
? 'Changelog fields'
|
|
2173
|
+
: 'Source fields',
|
|
1875
2174
|
fieldIds: fieldDefs.map((field) => field.id),
|
|
1876
2175
|
},
|
|
1877
2176
|
]
|
|
@@ -1910,7 +2209,9 @@
|
|
|
1910
2209
|
function setFieldSelection(allowedIds, options = {}) {
|
|
1911
2210
|
const { rerender = true } = options
|
|
1912
2211
|
state.selectedFieldIdsByTab[state.activeTab] = new Set(
|
|
1913
|
-
currentFieldDefs()
|
|
2212
|
+
currentFieldDefs()
|
|
2213
|
+
.map((field) => field.id)
|
|
2214
|
+
.filter((id) => allowedIds.has(id)),
|
|
1914
2215
|
)
|
|
1915
2216
|
renderFieldChips()
|
|
1916
2217
|
if (rerender) renderResults()
|
|
@@ -1922,7 +2223,10 @@
|
|
|
1922
2223
|
setPressed(regexSearchToggle, false)
|
|
1923
2224
|
typeMatchModeInput.value = 'contains'
|
|
1924
2225
|
setPressed(schemaRowsMatchOnlyToggle, false)
|
|
1925
|
-
setFieldSelection(
|
|
2226
|
+
setFieldSelection(
|
|
2227
|
+
new Set(currentFieldDefs().map((field) => field.id)),
|
|
2228
|
+
{ rerender: false },
|
|
2229
|
+
)
|
|
1926
2230
|
renderResults()
|
|
1927
2231
|
}
|
|
1928
2232
|
|
|
@@ -1987,12 +2291,16 @@
|
|
|
1987
2291
|
}
|
|
1988
2292
|
|
|
1989
2293
|
if (chipModels.length === 0) {
|
|
1990
|
-
activeFilterChips.appendChild(
|
|
2294
|
+
activeFilterChips.appendChild(
|
|
2295
|
+
el('span', 'empty', 'No active filters'),
|
|
2296
|
+
)
|
|
1991
2297
|
return
|
|
1992
2298
|
}
|
|
1993
2299
|
|
|
1994
2300
|
chipModels.forEach((chipModel) => {
|
|
1995
|
-
const chip = document.createElement(
|
|
2301
|
+
const chip = document.createElement(
|
|
2302
|
+
chipModel.onClick ? 'button' : 'span',
|
|
2303
|
+
)
|
|
1996
2304
|
chip.className = chipModel.onClick ? 'chip chip-btn' : 'chip'
|
|
1997
2305
|
chip.textContent = chipModel.text
|
|
1998
2306
|
if (chipModel.onClick) {
|
|
@@ -2009,10 +2317,14 @@
|
|
|
2009
2317
|
search: searchInput.value,
|
|
2010
2318
|
caseSensitive: isPressed(caseSensitiveToggle),
|
|
2011
2319
|
regex: isPressed(regexSearchToggle),
|
|
2012
|
-
typeMatchMode:
|
|
2320
|
+
typeMatchMode:
|
|
2321
|
+
typeMatchModeInput.value === 'exact' ? 'exact' : 'contains',
|
|
2013
2322
|
schemaRowsMatchOnly: isPressed(schemaRowsMatchOnlyToggle),
|
|
2014
2323
|
selectedFieldsByTab: Object.fromEntries(
|
|
2015
|
-
Object.entries(state.selectedFieldIdsByTab).map(([key, value]) => [
|
|
2324
|
+
Object.entries(state.selectedFieldIdsByTab).map(([key, value]) => [
|
|
2325
|
+
key,
|
|
2326
|
+
Array.from(value),
|
|
2327
|
+
]),
|
|
2016
2328
|
),
|
|
2017
2329
|
}
|
|
2018
2330
|
}
|
|
@@ -2021,7 +2333,9 @@
|
|
|
2021
2333
|
if (isHydratingFromUrl) return
|
|
2022
2334
|
|
|
2023
2335
|
const data = collectFilterState()
|
|
2024
|
-
const params = new URLSearchParams(
|
|
2336
|
+
const params = new URLSearchParams(
|
|
2337
|
+
window.location.hash.replace(/^#/, ''),
|
|
2338
|
+
)
|
|
2025
2339
|
const serialized = encodeURIComponent(JSON.stringify(data))
|
|
2026
2340
|
params.set(URL_PARAM_KEY, serialized)
|
|
2027
2341
|
const nextHash = params.toString()
|
|
@@ -2031,7 +2345,9 @@
|
|
|
2031
2345
|
}
|
|
2032
2346
|
|
|
2033
2347
|
function hydrateFilterStateFromUrl() {
|
|
2034
|
-
const params = new URLSearchParams(
|
|
2348
|
+
const params = new URLSearchParams(
|
|
2349
|
+
window.location.hash.replace(/^#/, ''),
|
|
2350
|
+
)
|
|
2035
2351
|
const raw = params.get(URL_PARAM_KEY)
|
|
2036
2352
|
if (!raw) return
|
|
2037
2353
|
|
|
@@ -2040,28 +2356,39 @@
|
|
|
2040
2356
|
isHydratingFromUrl = true
|
|
2041
2357
|
if (
|
|
2042
2358
|
parsed.activeTab === VIEW_IDS.leaves ||
|
|
2043
|
-
parsed.activeTab === VIEW_IDS.changelog
|
|
2044
|
-
parsed.activeTab === VIEW_IDS.changelogSource
|
|
2359
|
+
parsed.activeTab === VIEW_IDS.changelog
|
|
2045
2360
|
) {
|
|
2046
2361
|
state.activeTab = parsed.activeTab
|
|
2047
2362
|
}
|
|
2048
2363
|
if (parsed.activeTab === 'changelogRoute') {
|
|
2049
2364
|
state.activeTab = VIEW_IDS.changelog
|
|
2050
2365
|
}
|
|
2051
|
-
if (typeof parsed.search === 'string')
|
|
2366
|
+
if (typeof parsed.search === 'string')
|
|
2367
|
+
searchInput.value = parsed.search
|
|
2052
2368
|
setPressed(caseSensitiveToggle, Boolean(parsed.caseSensitive))
|
|
2053
2369
|
setPressed(regexSearchToggle, Boolean(parsed.regex))
|
|
2054
|
-
if (
|
|
2370
|
+
if (
|
|
2371
|
+
parsed.typeMatchMode === 'exact' ||
|
|
2372
|
+
parsed.typeMatchMode === 'contains'
|
|
2373
|
+
) {
|
|
2055
2374
|
typeMatchModeInput.value = parsed.typeMatchMode
|
|
2056
2375
|
}
|
|
2057
|
-
setPressed(
|
|
2376
|
+
setPressed(
|
|
2377
|
+
schemaRowsMatchOnlyToggle,
|
|
2378
|
+
Boolean(parsed.schemaRowsMatchOnly),
|
|
2379
|
+
)
|
|
2058
2380
|
|
|
2059
|
-
if (
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2381
|
+
if (
|
|
2382
|
+
parsed.selectedFieldsByTab &&
|
|
2383
|
+
typeof parsed.selectedFieldsByTab === 'object'
|
|
2384
|
+
) {
|
|
2385
|
+
Object.entries(parsed.selectedFieldsByTab).forEach(
|
|
2386
|
+
([tabId, ids]) => {
|
|
2387
|
+
if (!Array.isArray(ids)) return
|
|
2388
|
+
if (!state.selectedFieldIdsByTab[tabId]) return
|
|
2389
|
+
state.selectedFieldIdsByTab[tabId] = new Set(ids)
|
|
2390
|
+
},
|
|
2391
|
+
)
|
|
2065
2392
|
}
|
|
2066
2393
|
} catch (error) {
|
|
2067
2394
|
// Ignore malformed hash state.
|
|
@@ -2118,27 +2445,22 @@
|
|
|
2118
2445
|
}
|
|
2119
2446
|
if (state.changelogPayload) {
|
|
2120
2447
|
state.availableTabs.add(VIEW_IDS.changelog)
|
|
2121
|
-
state.availableTabs.add(VIEW_IDS.changelogSource)
|
|
2122
2448
|
}
|
|
2123
2449
|
|
|
2124
2450
|
if (!state.availableTabs.has(state.activeTab)) {
|
|
2125
2451
|
state.activeTab = state.availableTabs.has(VIEW_IDS.leaves)
|
|
2126
2452
|
? VIEW_IDS.leaves
|
|
2127
|
-
:
|
|
2128
|
-
? VIEW_IDS.changelog
|
|
2129
|
-
: VIEW_IDS.changelogSource
|
|
2453
|
+
: VIEW_IDS.changelog
|
|
2130
2454
|
}
|
|
2131
2455
|
|
|
2132
2456
|
if (state.leavesPayload && state.changelogPayload) {
|
|
2133
|
-
statusEl.textContent =
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
} commits.`
|
|
2457
|
+
statusEl.textContent = `Loaded unified bundle with ${state.leaves.length} routes and ${
|
|
2458
|
+
state.changelogPayload.commits?.length || 0
|
|
2459
|
+
} commits.`
|
|
2137
2460
|
} else if (state.leavesPayload) {
|
|
2138
2461
|
statusEl.textContent = `Loaded payload with ${state.leaves.length} routes.`
|
|
2139
2462
|
} else if (state.changelogPayload) {
|
|
2140
|
-
statusEl.textContent =
|
|
2141
|
-
`Loaded changelog payload with ${state.changelogPayload.commits?.length || 0} commits.`
|
|
2463
|
+
statusEl.textContent = `Loaded changelog payload with ${state.changelogPayload.commits?.length || 0} commits.`
|
|
2142
2464
|
} else {
|
|
2143
2465
|
statusEl.textContent = 'No payload loaded.'
|
|
2144
2466
|
}
|
|
@@ -2164,7 +2486,8 @@
|
|
|
2164
2486
|
try {
|
|
2165
2487
|
await handleFile(file)
|
|
2166
2488
|
} catch (error) {
|
|
2167
|
-
statusEl.textContent =
|
|
2489
|
+
statusEl.textContent =
|
|
2490
|
+
error instanceof Error ? error.message : String(error)
|
|
2168
2491
|
resultsEl.innerHTML = ''
|
|
2169
2492
|
}
|
|
2170
2493
|
})
|
|
@@ -2184,17 +2507,28 @@
|
|
|
2184
2507
|
renderResults()
|
|
2185
2508
|
})
|
|
2186
2509
|
|
|
2187
|
-
tabLeavesBtn.addEventListener('click', () =>
|
|
2188
|
-
|
|
2189
|
-
|
|
2510
|
+
tabLeavesBtn.addEventListener('click', () =>
|
|
2511
|
+
setActiveTab(VIEW_IDS.leaves),
|
|
2512
|
+
)
|
|
2513
|
+
tabChangelogBtn.addEventListener('click', () =>
|
|
2514
|
+
setActiveTab(VIEW_IDS.changelog),
|
|
2515
|
+
)
|
|
2190
2516
|
|
|
2191
2517
|
selectAllFieldsBtn.addEventListener('click', () =>
|
|
2192
2518
|
setFieldSelection(new Set(currentFieldDefs().map((field) => field.id))),
|
|
2193
2519
|
)
|
|
2194
|
-
clearAllFieldsBtn.addEventListener('click', () =>
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2520
|
+
clearAllFieldsBtn.addEventListener('click', () =>
|
|
2521
|
+
setFieldSelection(new Set()),
|
|
2522
|
+
)
|
|
2523
|
+
coreFieldsBtn.addEventListener('click', () =>
|
|
2524
|
+
setFieldSelection(CORE_FIELD_IDS),
|
|
2525
|
+
)
|
|
2526
|
+
schemasOnlyFieldsBtn.addEventListener('click', () =>
|
|
2527
|
+
setFieldSelection(SCHEMA_SCOPE_FIELD_IDS),
|
|
2528
|
+
)
|
|
2529
|
+
sourceOnlyFieldsBtn.addEventListener('click', () =>
|
|
2530
|
+
setFieldSelection(SOURCE_FIELD_IDS),
|
|
2531
|
+
)
|
|
2198
2532
|
resetFiltersBtn.addEventListener('click', resetFiltersToDefault)
|
|
2199
2533
|
|
|
2200
2534
|
renderFieldChips()
|