95 lines
3.1 KiB
Svelte
95 lines
3.1 KiB
Svelte
<!-- [DEF:CommitHistory:Component] -->
|
|
<!--
|
|
@SEMANTICS: git, history, commits, audit
|
|
@PURPOSE: Displays the commit history for a specific dashboard.
|
|
@LAYER: Component
|
|
@RELATION: CALLS -> gitService.getHistory
|
|
-->
|
|
|
|
<script>
|
|
// [SECTION: IMPORTS]
|
|
import { onMount } from 'svelte';
|
|
import { gitService } from '../../services/gitService';
|
|
import { addToast as toast } from '../../lib/toasts.js';
|
|
import { t } from '../../lib/i18n';
|
|
import { Button } from '../../lib/ui';
|
|
// [/SECTION]
|
|
|
|
// [SECTION: PROPS]
|
|
export let dashboardId;
|
|
// [/SECTION]
|
|
|
|
// [SECTION: STATE]
|
|
let history = [];
|
|
let loading = false;
|
|
// [/SECTION]
|
|
|
|
// [DEF:onMount:Function]
|
|
/**
|
|
* @purpose Load history when component is mounted.
|
|
* @pre Component is initialized with dashboardId.
|
|
* @post loadHistory is called.
|
|
*/
|
|
onMount(async () => {
|
|
await loadHistory();
|
|
});
|
|
// [/DEF:onMount:Function]
|
|
|
|
// [DEF:loadHistory:Function]
|
|
/**
|
|
* @purpose Fetch commit history from the backend.
|
|
* @pre dashboardId is valid.
|
|
* @post history state is updated.
|
|
*/
|
|
async function loadHistory() {
|
|
console.log(`[CommitHistory][Action] Loading history for dashboard ${dashboardId}`);
|
|
loading = true;
|
|
try {
|
|
history = await gitService.getHistory(dashboardId);
|
|
console.log(`[CommitHistory][Coherence:OK] Loaded ${history.length} commits`);
|
|
} catch (e) {
|
|
console.error(`[CommitHistory][Coherence:Failed] ${e.message}`);
|
|
toast('Failed to load commit history', 'error');
|
|
} finally {
|
|
loading = false;
|
|
}
|
|
}
|
|
// [/DEF:loadHistory:Function]
|
|
</script>
|
|
|
|
<!-- [SECTION: TEMPLATE] -->
|
|
<div class="mt-2">
|
|
<div class="flex justify-between items-center mb-6">
|
|
<h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider">
|
|
{$t.git.history}
|
|
</h3>
|
|
<Button variant="ghost" size="sm" on:click={loadHistory} class="text-blue-600">
|
|
{$t.git.refresh}
|
|
</Button>
|
|
</div>
|
|
|
|
{#if loading}
|
|
<div class="flex items-center justify-center py-12">
|
|
<div class="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600"></div>
|
|
</div>
|
|
{:else if history.length === 0}
|
|
<p class="text-gray-500 italic text-center py-12">{$t.git.no_commits}</p>
|
|
{:else}
|
|
<div class="space-y-3 max-h-96 overflow-y-auto pr-2">
|
|
{#each history as commit}
|
|
<div class="border-l-2 border-blue-500 pl-4 py-1">
|
|
<div class="flex justify-between items-start">
|
|
<span class="font-medium text-sm">{commit.message}</span>
|
|
<span class="text-xs text-gray-400 font-mono">{commit.hash.substring(0, 7)}</span>
|
|
</div>
|
|
<div class="text-xs text-gray-500 mt-1">
|
|
{commit.author} • {new Date(commit.timestamp).toLocaleString()}
|
|
</div>
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
<!-- [/SECTION] -->
|
|
|
|
<!-- [/DEF:CommitHistory:Component] --> |