|
6 | 6 | let _modules = []; |
7 | 7 | let _outcomes = []; |
8 | 8 | let _activeOutcome = null; |
9 | | - let _activeModule = null; |
10 | 9 | let _activeDiff = null; |
11 | 10 | let _activeTrack = null; |
12 | 11 | let _query = ''; |
|
21 | 20 | _outcomes = data.outcomes || []; |
22 | 21 |
|
23 | 22 | buildOutcomeChips(); |
24 | | - buildModuleChips(); |
25 | 23 | buildDiffChips(); |
26 | 24 | initSearch(); |
27 | 25 | applyUrlState(); |
|
30 | 28 |
|
31 | 29 | const DIFFS = ['beginner', 'intermediate', 'advanced']; |
32 | 30 |
|
33 | | - /* Seed filter state from the URL query string (?module=&difficulty=&q=) and |
| 31 | + /* Seed filter state from the URL query string (?outcome=&difficulty=&q=) and |
34 | 32 | reflect it on the chips + search input before the first render. Invalid |
35 | 33 | values are ignored rather than applied. */ |
36 | 34 | function applyUrlState() { |
37 | | - const mod = FP.qp('module'); |
38 | | - if (mod && _modules.some((m) => m.id === mod)) _activeModule = mod; |
39 | | - |
40 | 35 | const outcome = FP.qp('outcome'); |
41 | 36 | if (outcome && _outcomes.some((o) => o.id === outcome)) _activeOutcome = outcome; |
42 | 37 |
|
|
54 | 49 | syncUrl(); |
55 | 50 | } |
56 | 51 |
|
57 | | - /* Reflect _activeModule / _activeDiff onto the rendered chips. */ |
| 52 | + /* Reflect the active filters onto the rendered chips. */ |
58 | 53 | function syncChipState() { |
59 | | - document.querySelectorAll('#moduleChips .chip').forEach((b) => { |
60 | | - const on = b.dataset.module === _activeModule; |
61 | | - b.classList.toggle('active', on); |
62 | | - b.setAttribute('aria-pressed', String(on)); |
63 | | - }); |
64 | 54 | document.querySelectorAll('#outcomeChips .chip').forEach((b) => { |
65 | 55 | const on = b.dataset.outcome === _activeOutcome; |
66 | 56 | b.classList.toggle('active', on); |
|
77 | 67 | shareable. replaceState avoids polluting back/forward history. */ |
78 | 68 | function syncUrl() { |
79 | 69 | const q = new URLSearchParams(); |
80 | | - if (_activeModule) q.set('module', _activeModule); |
81 | 70 | if (_activeOutcome) q.set('outcome', _activeOutcome); |
82 | 71 | if (_activeDiff) q.set('difficulty', _activeDiff); |
83 | 72 | if (_query) q.set('q', _query); |
|
86 | 75 | window.history.replaceState(null, '', url); |
87 | 76 | } |
88 | 77 |
|
89 | | - function buildModuleChips() { |
90 | | - const container = document.getElementById('moduleChips'); |
91 | | - if (!container) return; |
92 | | - |
93 | | - container.innerHTML = _modules.map((m) => |
94 | | - `<button class="chip" data-module="${FP.esc(m.id)}" |
95 | | - aria-pressed="false" type="button" |
96 | | - style="--mod-color:${FP.moduleColor(m.id)}"> |
97 | | - ${FP.esc(m.name.replace('GitHub ', ''))} |
98 | | - </button>` |
99 | | - ).join(''); |
100 | | - |
101 | | - container.querySelectorAll('.chip').forEach((btn) => { |
102 | | - btn.addEventListener('click', () => { |
103 | | - const id = btn.dataset.module; |
104 | | - _activeModule = _activeModule === id ? null : id; |
105 | | - container.querySelectorAll('.chip').forEach((b) => { |
106 | | - b.classList.toggle('active', b.dataset.module === _activeModule); |
107 | | - b.setAttribute('aria-pressed', String(b.dataset.module === _activeModule)); |
108 | | - }); |
109 | | - syncUrl(); |
110 | | - render(); |
111 | | - }); |
112 | | - }); |
113 | | - } |
114 | | - |
115 | 78 | function buildOutcomeChips() { |
116 | 79 | const container = document.getElementById('outcomeChips'); |
117 | 80 | if (!container) return; |
118 | 81 | container.innerHTML = _outcomes.map((o) => |
119 | 82 | `<button class="chip chip-outcome" data-outcome="${FP.esc(o.id)}" |
120 | | - aria-pressed="false" type="button"> |
| 83 | + aria-pressed="false" type="button" |
| 84 | + style="--outcome-color:${FP.moduleColor(outcomeModule(o.id))}"> |
121 | 85 | ${FP.esc(o.name)} |
122 | 86 | </button>` |
123 | 87 | ).join(''); |
|
133 | 97 | }); |
134 | 98 | } |
135 | 99 |
|
| 100 | + function outcomeModule(outcomeId) { |
| 101 | + const moduleByOutcome = { |
| 102 | + 'github-adoption': 'ghec', |
| 103 | + 'platform-migration': 'ghec', |
| 104 | + 'ghas-adoption': 'ghas', |
| 105 | + 'agentic-workflows': 'ghaw', |
| 106 | + 'agentic-devops-cloud': 'sre-agent', |
| 107 | + }; |
| 108 | + return moduleByOutcome[outcomeId]; |
| 109 | + } |
| 110 | + |
136 | 111 | function buildDiffChips() { |
137 | 112 | const container = document.getElementById('diffChips'); |
138 | 113 | if (!container) return; |
|
170 | 145 | _query = ''; |
171 | 146 | input.value = ''; |
172 | 147 | _activeOutcome = null; |
173 | | - _activeModule = null; |
174 | 148 | _activeDiff = null; |
175 | 149 | document.querySelectorAll('.chip').forEach((b) => { |
176 | 150 | b.classList.remove('active'); |
|
184 | 158 |
|
185 | 159 | function filtered() { |
186 | 160 | return _all.filter((c) => { |
187 | | - if (_activeModule && c.module !== _activeModule) return false; |
188 | 161 | if (_activeOutcome && !(c.outcomes || []).includes(_activeOutcome)) return false; |
189 | 162 | if (_activeDiff && c.difficulty !== _activeDiff) return false; |
190 | 163 | if (_query) { |
|
0 commit comments