Skip to content

Commit f5b3967

Browse files
authored
Merge pull request #3 from opensource-observer/kenyiu/hotfix-dropbox
Refactor notebooks with select dropdowns and update CI deployment
2 parents bcb583a + c1ada4a commit f5b3967

6 files changed

Lines changed: 501 additions & 712 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,16 @@ jobs:
2020
- name: Install Python deps
2121
run: uv sync
2222

23-
- name: Check if notebooks changed
24-
id: changed
25-
run: |
26-
git diff --name-only HEAD~1 HEAD 2>/dev/null | grep -q '^notebooks/' \
27-
&& echo "notebooks=true" >> $GITHUB_OUTPUT \
28-
|| echo "notebooks=false" >> $GITHUB_OUTPUT
29-
3023
- name: Export notebooks
31-
if: steps.changed.outputs.notebooks == 'true' || github.event_name != 'push'
3224
env:
3325
OSO_API_KEY: ${{ secrets.OSO_API_KEY }}
3426
run: uv run python scripts/export_notebooks.py
3527

36-
- uses: pnpm/action-setup@v4
37-
with:
38-
version: 10
39-
40-
- uses: actions/setup-node@v4
41-
with:
42-
node-version: '20'
43-
cache: 'pnpm'
44-
cache-dependency-path: app/pnpm-lock.yaml
45-
46-
- name: Install Node deps
47-
run: cd app && pnpm install
48-
49-
- name: Build Next.js
50-
run: cd app && pnpm build
28+
- name: Push to deploy branch
29+
run: |
30+
git config user.name "github-actions[bot]"
31+
git config user.email "github-actions[bot]@users.noreply.github.com"
32+
git add --force app/public/notebooks/
33+
git checkout -B deploy
34+
git commit -m "chore: deploy with exported notebooks" --allow-empty
35+
git push origin deploy --force

notebooks/insights/defi-developer-journeys.py

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2344,28 +2344,21 @@ def _render_list(df_top, color):
23442344

23452345
_djs_safe = _json.dumps(_states).replace('</', '<\\/')
23462346
_opts_js = _json.dumps(_opts)
2347-
_btn_html = ''.join(f'<button class="tab-btn" data-idx="{i}">{o}</button>' for i, o in enumerate(_opts))
2347+
_sel_html = '<div style="margin-bottom:8px"><span style="font-size:11px;color:#6b7280;display:block;margin-bottom:2px">Project</span><select id="sel" style="padding:4px 8px;border:1px solid #d1d5db;border-radius:6px;font-size:13px;color:#374151;background:#fff;cursor:pointer">' + ''.join(f'<option value="{i}">{o}</option>' for i, o in enumerate(_opts)) + '</select></div>'
23482348

23492349
_inner = (
23502350
'<!DOCTYPE html><html><head><meta charset="utf-8">'
23512351
'<style>'
23522352
'*{box-sizing:border-box;margin:0;padding:0}'
23532353
'body{font-family:Arial,sans-serif;font-size:13px;padding:4px}'
2354-
'.tab-btn{padding:6px 14px;border:none;background:none;border-radius:6px;font-size:13px;cursor:pointer;color:#6b7280}'
2355-
'.tab-btn:hover{background:#f3f4f6;color:#111}'
2356-
'.tab-btn.active{background:#eff6ff;color:#2563eb;font-weight:600}'
2357-
'.tab-bar{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:12px;border-bottom:1px solid #e5e7eb;padding-bottom:8px}'
23582354
'</style></head><body>'
2359-
f'<div class="tab-bar">{_btn_html}</div>'
2355+
f'{_sel_html}'
23602356
'<div id="content"></div>'
23612357
f'<script>var D={_djs_safe};var O={_opts_js};'
2362-
'document.querySelectorAll(".tab-btn").forEach(function(btn,i){'
2363-
'btn.addEventListener("click",function(){'
2364-
'document.querySelectorAll(".tab-btn").forEach(function(b){b.classList.remove("active")});'
2365-
'btn.classList.add("active");'
2366-
'document.getElementById("content").innerHTML=D[O[i]].content;'
2367-
'});});'
2368-
'var _b=document.querySelectorAll(".tab-btn");if(_b.length)_b[0].click();'
2358+
'var sel=document.getElementById("sel");'
2359+
'function show(i){document.getElementById("content").innerHTML=D[O[i]].content;}'
2360+
'sel.addEventListener("change",function(){show(parseInt(this.value))});'
2361+
'show(0);'
23692362
'</script></body></html>'
23702363
)
23712364
_src = _html_mod.escape(_inner, quote=True)
@@ -2598,28 +2591,21 @@ def main_dashboard(
25982591

25992592
_djs_safe = _json.dumps(_states).replace('</', '<\\/')
26002593
_opts_js = _json.dumps(_opts)
2601-
_btn_html = ''.join(f'<button class="tab-btn" data-idx="{i}">{o}</button>' for i, o in enumerate(_opts))
2594+
_sel_html = '<div style="margin-bottom:8px"><span style="font-size:11px;color:#6b7280;display:block;margin-bottom:2px">View</span><select id="sel" style="padding:4px 8px;border:1px solid #d1d5db;border-radius:6px;font-size:13px;color:#374151;background:#fff;cursor:pointer">' + ''.join(f'<option value="{i}">{o}</option>' for i, o in enumerate(_opts)) + '</select></div>'
26022595

26032596
_inner = (
26042597
'<!DOCTYPE html><html><head><meta charset="utf-8">'
26052598
'<style>'
26062599
'*{box-sizing:border-box;margin:0;padding:0}'
26072600
'body{font-family:Arial,sans-serif;font-size:13px;padding:4px}'
2608-
'.tab-btn{padding:6px 14px;border:none;background:none;border-radius:6px;font-size:13px;cursor:pointer;color:#6b7280}'
2609-
'.tab-btn:hover{background:#f3f4f6;color:#111}'
2610-
'.tab-btn.active{background:#eff6ff;color:#2563eb;font-weight:600}'
2611-
'.tab-bar{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:12px;border-bottom:1px solid #e5e7eb;padding-bottom:8px}'
26122601
'</style></head><body>'
2613-
f'<div class="tab-bar">{_btn_html}</div>'
2602+
f'{_sel_html}'
26142603
'<div id="content"></div>'
26152604
f'<script>var D={_djs_safe};var O={_opts_js};'
2616-
'document.querySelectorAll(".tab-btn").forEach(function(btn,i){'
2617-
'btn.addEventListener("click",function(){'
2618-
'document.querySelectorAll(".tab-btn").forEach(function(b){b.classList.remove("active")});'
2619-
'btn.classList.add("active");'
2620-
'document.getElementById("content").innerHTML=D[O[i]].content;'
2621-
'});});'
2622-
'var _b=document.querySelectorAll(".tab-btn");if(_b.length)_b[0].click();'
2605+
'var sel=document.getElementById("sel");'
2606+
'function show(i){document.getElementById("content").innerHTML=D[O[i]].content;}'
2607+
'sel.addEventListener("change",function(){show(parseInt(this.value))});'
2608+
'show(0);'
26232609
'</script></body></html>'
26242610
)
26252611
_src = _html_mod.escape(_inner, quote=True)

notebooks/insights/developer-lifecycle.py

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -193,31 +193,24 @@ def _categorize(label):
193193
_opts = [o for o in _ECOSYSTEMS if o in _states]
194194
_djs_safe = _json.dumps(_states).replace('</', '<\\/')
195195
_opts_js = _json.dumps(_opts)
196-
_btn_html = ''.join(f'<button class="tab-btn" data-idx="{i}">{o}</button>' for i, o in enumerate(_opts))
196+
_sel_html = '<div style="margin-bottom:8px"><span style="font-size:11px;color:#6b7280;display:block;margin-bottom:2px">Ecosystem</span><select id="sel" style="padding:4px 8px;border:1px solid #d1d5db;border-radius:6px;font-size:13px;color:#374151;background:#fff;cursor:pointer">' + ''.join(f'<option value="{i}">{o}</option>' for i, o in enumerate(_opts)) + '</select></div>'
197197

198198
_inner = (
199199
'<!DOCTYPE html><html><head><meta charset="utf-8">'
200200
'<script src="https://cdn.plot.ly/plotly-2.35.2.min.js"></script>'
201201
'<style>'
202202
'*{box-sizing:border-box;margin:0;padding:0}'
203203
'body{font-family:Arial,sans-serif;font-size:13px;padding:4px}'
204-
'.tab-btn{padding:6px 14px;border:none;background:none;border-radius:6px;font-size:13px;cursor:pointer;color:#6b7280}'
205-
'.tab-btn:hover{background:#f3f4f6;color:#111}'
206-
'.tab-btn.active{background:#eff6ff;color:#2563eb;font-weight:600}'
207-
'.tab-bar{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:12px;border-bottom:1px solid #e5e7eb;padding-bottom:8px}'
208204
'</style></head><body>'
209-
f'<div class="tab-bar">{_btn_html}</div>'
205+
f'{_sel_html}'
210206
'<div id="stats" style="margin-bottom:12px"></div>'
211207
'<div id="chart"></div>'
212208
f'<script>var D={_djs_safe};var O={_opts_js};'
213-
'document.querySelectorAll(".tab-btn").forEach(function(btn,i){'
214-
'btn.addEventListener("click",function(){'
215-
'document.querySelectorAll(".tab-btn").forEach(function(b){b.classList.remove("active")});'
216-
'btn.classList.add("active");'
217-
'document.getElementById("stats").innerHTML=D[O[i]].stats||"";'
218-
'Plotly.react("chart",D[O[i]].chart.data,D[O[i]].chart.layout,{responsive:true});'
219-
'});});'
220-
'var _b=document.querySelectorAll(".tab-btn");if(_b.length)_b[0].click();'
209+
'var sel=document.getElementById("sel");'
210+
'function show(i){document.getElementById("stats").innerHTML=D[O[i]].stats||"";'
211+
'Plotly.react("chart",D[O[i]].chart.data,D[O[i]].chart.layout,{responsive:true});}'
212+
'sel.addEventListener("change",function(){show(parseInt(this.value))});'
213+
'show(0);'
221214
'</script></body></html>'
222215
)
223216
_src = _html_mod.escape(_inner, quote=True)
@@ -297,29 +290,22 @@ def ecosystem_comparison_tabs(ACTIVE_LABELS, CHURNED_LABELS, DORMANT_LABELS, FT_
297290
_opts = [m for m in _METRICS if m in _states]
298291
_djs_safe = _json.dumps(_states).replace('</', '<\\/')
299292
_opts_js = _json.dumps(_opts)
300-
_btn_html = ''.join(f'<button class="tab-btn" data-idx="{i}">{o}</button>' for i, o in enumerate(_opts))
293+
_sel_html = '<div style="margin-bottom:8px"><span style="font-size:11px;color:#6b7280;display:block;margin-bottom:2px">Metric</span><select id="sel" style="padding:4px 8px;border:1px solid #d1d5db;border-radius:6px;font-size:13px;color:#374151;background:#fff;cursor:pointer">' + ''.join(f'<option value="{i}">{o}</option>' for i, o in enumerate(_opts)) + '</select></div>'
301294

302295
_inner = (
303296
'<!DOCTYPE html><html><head><meta charset="utf-8">'
304297
'<script src="https://cdn.plot.ly/plotly-2.35.2.min.js"></script>'
305298
'<style>'
306299
'*{box-sizing:border-box;margin:0;padding:0}'
307300
'body{font-family:Arial,sans-serif;font-size:13px;padding:4px}'
308-
'.tab-btn{padding:6px 14px;border:none;background:none;border-radius:6px;font-size:13px;cursor:pointer;color:#6b7280}'
309-
'.tab-btn:hover{background:#f3f4f6;color:#111}'
310-
'.tab-btn.active{background:#eff6ff;color:#2563eb;font-weight:600}'
311-
'.tab-bar{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:12px;border-bottom:1px solid #e5e7eb;padding-bottom:8px}'
312301
'</style></head><body>'
313-
f'<div class="tab-bar">{_btn_html}</div>'
302+
f'{_sel_html}'
314303
'<div id="chart"></div>'
315304
f'<script>var D={_djs_safe};var O={_opts_js};'
316-
'document.querySelectorAll(".tab-btn").forEach(function(btn,i){'
317-
'btn.addEventListener("click",function(){'
318-
'document.querySelectorAll(".tab-btn").forEach(function(b){b.classList.remove("active")});'
319-
'btn.classList.add("active");'
320-
'Plotly.react("chart",D[O[i]].chart.data,D[O[i]].chart.layout,{responsive:true});'
321-
'});});'
322-
'var _b=document.querySelectorAll(".tab-btn");if(_b.length)_b[0].click();'
305+
'var sel=document.getElementById("sel");'
306+
'function show(i){Plotly.react("chart",D[O[i]].chart.data,D[O[i]].chart.layout,{responsive:true});}'
307+
'sel.addEventListener("change",function(){show(parseInt(this.value))});'
308+
'show(0);'
323309
'</script></body></html>'
324310
)
325311
_src = _html_mod.escape(_inner, quote=True)

0 commit comments

Comments
 (0)