Sprint 2 : moteur de documents + sanctuaire
Backend: - CRUD complet documents/items/versions (update, delete, accept, reject, reorder) - Service IPFS (upload/retrieve/pin via kubo HTTP API) - Service sanctuaire : pipeline SHA-256 + IPFS + on-chain (system.remark) - Verification integrite des entrees sanctuaire - Recherche par reference (document -> entrees sanctuaire) - Serialisation deterministe des documents pour archivage - 14 tests unitaires supplementaires (document service) Frontend: - 9 composants : StatusBadge, MarkdownRenderer, DiffView, ItemCard, ItemVersionDiff, DocumentList, SanctuaryEntry, IPFSLink, ChainAnchor - Page detail item avec historique des versions et diff - Page detail sanctuaire avec verification integrite - Modal de creation de document + proposition de version - Archivage document vers sanctuaire depuis la page detail Documentation: - API reference mise a jour (9 nouveaux endpoints) - Guides utilisateur documents et sanctuaire enrichis Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
51
frontend/app/components/common/DiffView.vue
Normal file
51
frontend/app/components/common/DiffView.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
diff: string
|
||||
}>()
|
||||
|
||||
interface DiffLine {
|
||||
text: string
|
||||
type: 'added' | 'removed' | 'header' | 'context'
|
||||
}
|
||||
|
||||
const parsedLines = computed((): DiffLine[] => {
|
||||
if (!props.diff) return []
|
||||
|
||||
return props.diff.split('\n').map((line) => {
|
||||
if (line.startsWith('@@')) {
|
||||
return { text: line, type: 'header' as const }
|
||||
}
|
||||
if (line.startsWith('+')) {
|
||||
return { text: line, type: 'added' as const }
|
||||
}
|
||||
if (line.startsWith('-')) {
|
||||
return { text: line, type: 'removed' as const }
|
||||
}
|
||||
return { text: line, type: 'context' as const }
|
||||
})
|
||||
})
|
||||
|
||||
function lineClass(type: DiffLine['type']): string {
|
||||
switch (type) {
|
||||
case 'added':
|
||||
return 'bg-green-50 dark:bg-green-900/20 text-green-800 dark:text-green-300'
|
||||
case 'removed':
|
||||
return 'bg-red-50 dark:bg-red-900/20 text-red-800 dark:text-red-300'
|
||||
case 'header':
|
||||
return 'bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300 font-semibold'
|
||||
default:
|
||||
return 'text-gray-700 dark:text-gray-300'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden">
|
||||
<pre class="text-xs font-mono leading-relaxed overflow-x-auto"><template
|
||||
v-for="(line, index) in parsedLines"
|
||||
:key="index"
|
||||
><div
|
||||
:class="['px-4 py-0.5', lineClass(line.type)]"
|
||||
>{{ line.text }}</div></template></pre>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user