mirror of
https://github.com/svemagie/blog-eleventy-indiekit.git
synced 2026-05-14 22:48:50 +02:00
feat: add view mode toggle for changelog page
Add a "Group by: Repository | Change Type" segmented toggle to the changelog page. Users can now switch between repo-based tabs (Core, Endpoints, Syndicators, etc.) and commit-type tabs (Features, Fixes, Refactor, etc.) with reactive Alpine.js computed getters. Both views share the same commit data — only the grouping dimension and color scheme change. Tab counts and badge labels update reactively when switching view modes. Confab-Link: http://localhost:8080/sessions/5767023f-100b-4b9c-85fc-12d7e1ab248a
This commit is contained in:
+89
-8
@@ -13,9 +13,26 @@ withSidebar: false
|
|||||||
|
|
||||||
<div x-data="changelogApp()" x-init="init()">
|
<div x-data="changelogApp()" x-init="init()">
|
||||||
|
|
||||||
|
{# View mode toggle #}
|
||||||
|
<div class="flex items-center gap-2 mb-4">
|
||||||
|
<span class="text-sm text-surface-600 dark:text-surface-400">Group by:</span>
|
||||||
|
<div class="inline-flex rounded-lg border border-surface-200 dark:border-surface-700 overflow-hidden">
|
||||||
|
<button
|
||||||
|
@click="setViewMode('repo')"
|
||||||
|
:class="viewMode === 'repo' ? 'bg-accent-100 dark:bg-accent-900 text-accent-700 dark:text-accent-300' : 'text-surface-600 dark:text-surface-400 hover:bg-surface-50 dark:hover:bg-surface-800'"
|
||||||
|
class="px-3 py-1.5 text-xs font-medium transition-colors"
|
||||||
|
>Repository</button>
|
||||||
|
<button
|
||||||
|
@click="setViewMode('type')"
|
||||||
|
:class="viewMode === 'type' ? 'bg-accent-100 dark:bg-accent-900 text-accent-700 dark:text-accent-300' : 'text-surface-600 dark:text-surface-400 hover:bg-surface-50 dark:hover:bg-surface-800'"
|
||||||
|
class="px-3 py-1.5 text-xs font-medium transition-colors border-l border-surface-200 dark:border-surface-700"
|
||||||
|
>Change Type</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{# Tab navigation #}
|
{# Tab navigation #}
|
||||||
<div class="flex gap-1 mb-6 border-b border-surface-200 dark:border-surface-700 overflow-x-auto" role="tablist" aria-label="Changelog categories">
|
<div class="flex gap-1 mb-6 border-b border-surface-200 dark:border-surface-700 overflow-x-auto" role="tablist" aria-label="Changelog categories">
|
||||||
<template x-for="tab in tabs" :key="tab.key">
|
<template x-for="tab in activeTabs" :key="tab.key">
|
||||||
<button
|
<button
|
||||||
@click="activeTab = tab.key"
|
@click="activeTab = tab.key"
|
||||||
:class="activeTab === tab.key ? 'border-b-2 border-accent-500 text-accent-600 dark:text-accent-400' : 'text-surface-600 dark:text-surface-400 hover:text-surface-700 dark:hover:text-surface-300'"
|
:class="activeTab === tab.key ? 'border-b-2 border-accent-500 text-accent-600 dark:text-accent-400' : 'text-surface-600 dark:text-surface-400 hover:text-surface-700 dark:hover:text-surface-300'"
|
||||||
@@ -60,8 +77,8 @@ withSidebar: false
|
|||||||
<div class="flex flex-wrap items-center gap-2 mt-2">
|
<div class="flex flex-wrap items-center gap-2 mt-2">
|
||||||
<span
|
<span
|
||||||
class="text-xs px-2 py-0.5 rounded-full font-medium"
|
class="text-xs px-2 py-0.5 rounded-full font-medium"
|
||||||
:class="categoryColors[commit.category]"
|
:class="activeCategoryColors[activeCommitCategory(commit)]"
|
||||||
x-text="categoryLabels[commit.category] || commit.category"
|
x-text="activeCategoryLabels[activeCommitCategory(commit)] || activeCommitCategory(commit)"
|
||||||
></span>
|
></span>
|
||||||
<a :href="commit.repoUrl" target="_blank" rel="noopener"
|
<a :href="commit.repoUrl" target="_blank" rel="noopener"
|
||||||
class="text-xs px-2 py-0.5 rounded-full bg-surface-100 dark:bg-surface-800 text-surface-600 dark:text-surface-400 hover:text-accent-600 dark:hover:text-accent-400"
|
class="text-xs px-2 py-0.5 rounded-full bg-surface-100 dark:bg-surface-800 text-surface-600 dark:text-surface-400 hover:text-accent-600 dark:hover:text-accent-400"
|
||||||
@@ -109,14 +126,16 @@ withSidebar: false
|
|||||||
function changelogApp() {
|
function changelogApp() {
|
||||||
return {
|
return {
|
||||||
activeTab: 'all',
|
activeTab: 'all',
|
||||||
|
viewMode: 'repo',
|
||||||
loading: true,
|
loading: true,
|
||||||
loadingMore: false,
|
loadingMore: false,
|
||||||
commits: [],
|
commits: [],
|
||||||
categories: {},
|
categories: {},
|
||||||
|
commitCategories: {},
|
||||||
currentDays: 30,
|
currentDays: 30,
|
||||||
daysProgression: [30, 90, 180, 'all'],
|
daysProgression: [30, 90, 180, 'all'],
|
||||||
|
|
||||||
tabs: [
|
repoTabs: [
|
||||||
{ key: 'all', label: 'All' },
|
{ key: 'all', label: 'All' },
|
||||||
{ key: 'core', label: 'Core' },
|
{ key: 'core', label: 'Core' },
|
||||||
{ key: 'deployment', label: 'Deployment' },
|
{ key: 'deployment', label: 'Deployment' },
|
||||||
@@ -127,7 +146,19 @@ function changelogApp() {
|
|||||||
{ key: 'presets', label: 'Presets' },
|
{ key: 'presets', label: 'Presets' },
|
||||||
],
|
],
|
||||||
|
|
||||||
categoryLabels: {
|
typeTabs: [
|
||||||
|
{ key: 'all', label: 'All' },
|
||||||
|
{ key: 'features', label: 'Features' },
|
||||||
|
{ key: 'fixes', label: 'Fixes' },
|
||||||
|
{ key: 'refactor', label: 'Refactor' },
|
||||||
|
{ key: 'performance', label: 'Performance' },
|
||||||
|
{ key: 'accessibility', label: 'Accessibility' },
|
||||||
|
{ key: 'documentation', label: 'Docs' },
|
||||||
|
{ key: 'chores', label: 'Chores' },
|
||||||
|
{ key: 'tests', label: 'Tests' },
|
||||||
|
],
|
||||||
|
|
||||||
|
repoCategoryLabels: {
|
||||||
core: 'Core',
|
core: 'Core',
|
||||||
deployment: 'Deployment',
|
deployment: 'Deployment',
|
||||||
theme: 'Theme',
|
theme: 'Theme',
|
||||||
@@ -138,7 +169,20 @@ function changelogApp() {
|
|||||||
other: 'Other',
|
other: 'Other',
|
||||||
},
|
},
|
||||||
|
|
||||||
categoryColors: {
|
typeCategoryLabels: {
|
||||||
|
features: 'Feature',
|
||||||
|
fixes: 'Fix',
|
||||||
|
performance: 'Perf',
|
||||||
|
accessibility: 'A11y',
|
||||||
|
documentation: 'Docs',
|
||||||
|
refactor: 'Refactor',
|
||||||
|
chores: 'Chore',
|
||||||
|
style: 'Style',
|
||||||
|
tests: 'Test',
|
||||||
|
other: 'Other',
|
||||||
|
},
|
||||||
|
|
||||||
|
repoCategoryColors: {
|
||||||
core: 'bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-300',
|
core: 'bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-300',
|
||||||
deployment: 'bg-orange-100 dark:bg-orange-900 text-orange-700 dark:text-orange-300',
|
deployment: 'bg-orange-100 dark:bg-orange-900 text-orange-700 dark:text-orange-300',
|
||||||
theme: 'bg-purple-100 dark:bg-purple-900 text-purple-700 dark:text-purple-300',
|
theme: 'bg-purple-100 dark:bg-purple-900 text-purple-700 dark:text-purple-300',
|
||||||
@@ -149,11 +193,45 @@ function changelogApp() {
|
|||||||
other: 'bg-surface-100 dark:bg-surface-800 text-surface-700 dark:text-surface-300',
|
other: 'bg-surface-100 dark:bg-surface-800 text-surface-700 dark:text-surface-300',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
typeCategoryColors: {
|
||||||
|
features: 'bg-green-100 dark:bg-green-900 text-green-700 dark:text-green-300',
|
||||||
|
fixes: 'bg-red-100 dark:bg-red-900 text-red-700 dark:text-red-300',
|
||||||
|
performance: 'bg-yellow-100 dark:bg-yellow-900 text-yellow-700 dark:text-yellow-300',
|
||||||
|
accessibility: 'bg-purple-100 dark:bg-purple-900 text-purple-700 dark:text-purple-300',
|
||||||
|
documentation: 'bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-300',
|
||||||
|
refactor: 'bg-orange-100 dark:bg-orange-900 text-orange-700 dark:text-orange-300',
|
||||||
|
chores: 'bg-surface-200 dark:bg-surface-700 text-surface-700 dark:text-surface-300',
|
||||||
|
style: 'bg-pink-100 dark:bg-pink-900 text-pink-700 dark:text-pink-300',
|
||||||
|
tests: 'bg-teal-100 dark:bg-teal-900 text-teal-700 dark:text-teal-300',
|
||||||
|
other: 'bg-surface-100 dark:bg-surface-800 text-surface-700 dark:text-surface-300',
|
||||||
|
},
|
||||||
|
|
||||||
|
get activeTabs() {
|
||||||
|
return this.viewMode === 'repo' ? this.repoTabs : this.typeTabs;
|
||||||
|
},
|
||||||
|
|
||||||
|
get activeCategoryLabels() {
|
||||||
|
return this.viewMode === 'repo' ? this.repoCategoryLabels : this.typeCategoryLabels;
|
||||||
|
},
|
||||||
|
|
||||||
|
get activeCategoryColors() {
|
||||||
|
return this.viewMode === 'repo' ? this.repoCategoryColors : this.typeCategoryColors;
|
||||||
|
},
|
||||||
|
|
||||||
get canLoadMore() {
|
get canLoadMore() {
|
||||||
const idx = this.daysProgression.indexOf(this.currentDays);
|
const idx = this.daysProgression.indexOf(this.currentDays);
|
||||||
return idx >= 0 && idx < this.daysProgression.length - 1;
|
return idx >= 0 && idx < this.daysProgression.length - 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setViewMode(mode) {
|
||||||
|
this.viewMode = mode;
|
||||||
|
this.activeTab = 'all';
|
||||||
|
},
|
||||||
|
|
||||||
|
activeCommitCategory(commit) {
|
||||||
|
return this.viewMode === 'repo' ? commit.category : commit.commitCategory;
|
||||||
|
},
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
await this.fetchChangelog(30);
|
await this.fetchChangelog(30);
|
||||||
},
|
},
|
||||||
@@ -165,6 +243,7 @@ function changelogApp() {
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
this.commits = data.commits || [];
|
this.commits = data.commits || [];
|
||||||
this.categories = data.categories || {};
|
this.categories = data.categories || {};
|
||||||
|
this.commitCategories = data.commitCategories || {};
|
||||||
this.currentDays = data.days;
|
this.currentDays = data.days;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Changelog error:', err);
|
console.error('Changelog error:', err);
|
||||||
@@ -184,12 +263,14 @@ function changelogApp() {
|
|||||||
|
|
||||||
filteredCommits() {
|
filteredCommits() {
|
||||||
if (this.activeTab === 'all') return this.commits;
|
if (this.activeTab === 'all') return this.commits;
|
||||||
return this.commits.filter(c => c.category === this.activeTab);
|
const field = this.viewMode === 'repo' ? 'category' : 'commitCategory';
|
||||||
|
return this.commits.filter(c => c[field] === this.activeTab);
|
||||||
},
|
},
|
||||||
|
|
||||||
getCount(tabKey) {
|
getCount(tabKey) {
|
||||||
if (tabKey === 'all') return this.commits.length;
|
if (tabKey === 'all') return this.commits.length;
|
||||||
return this.commits.filter(c => c.category === tabKey).length;
|
const field = this.viewMode === 'repo' ? 'category' : 'commitCategory';
|
||||||
|
return this.commits.filter(c => c[field] === tabKey).length;
|
||||||
},
|
},
|
||||||
|
|
||||||
formatDate(dateStr) {
|
formatDate(dateStr) {
|
||||||
|
|||||||
Reference in New Issue
Block a user