feat: discussion sub-tab navigation for annotation threads (#60) #63
@@ -333,46 +333,8 @@ $effect(() => {
|
|||||||
{m.history_compare_apply()}
|
{m.history_compare_apply()}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
|
||||||
<!-- Version list -->
|
|
||||||
<ul class="divide-y divide-brand-sand">
|
|
||||||
{#each versions as v, i (v.id)}
|
|
||||||
<li>
|
|
||||||
<button
|
|
||||||
onclick={() => selectVersion(v.id)}
|
|
||||||
data-testid="history-version"
|
|
||||||
class="w-full py-2 text-left transition hover:bg-brand-sand/30 {selectedVersionId ===
|
|
||||||
v.id
|
|
||||||
? 'border-l-2 border-brand-mint pl-2'
|
|
||||||
: 'pl-0'}"
|
|
||||||
>
|
|
||||||
<div class="flex items-baseline justify-between gap-2">
|
|
||||||
<span class="font-sans text-xs font-medium text-brand-navy">
|
|
||||||
Version {i + 1}
|
|
||||||
</span>
|
|
||||||
<span class="font-sans text-[10px] text-gray-400">
|
|
||||||
{formatDateTime(v.savedAt)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span class="font-sans text-[11px] text-gray-500">{v.editorName}</span>
|
|
||||||
{#if v.changedFields && v.changedFields.length > 0}
|
|
||||||
<div class="mt-1 flex flex-wrap gap-1">
|
|
||||||
{#each v.changedFields as field (field)}
|
|
||||||
<span
|
|
||||||
class="rounded bg-brand-sand/50 px-1.5 py-0.5 font-sans text-[10px] tracking-wide text-gray-500 uppercase"
|
|
||||||
>
|
|
||||||
{fieldLabels[field] ? fieldLabels[field]() : field}
|
|
||||||
</span>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
{/each}
|
|
||||||
</ul>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<!-- Diff panel -->
|
<!-- Diff panel for compare mode -->
|
||||||
{#if diffLoading}
|
{#if diffLoading}
|
||||||
<p class="font-sans text-xs text-gray-400">{m.history_loading()}</p>
|
<p class="font-sans text-xs text-gray-400">{m.history_loading()}</p>
|
||||||
{:else if noDiff}
|
{:else if noDiff}
|
||||||
@@ -442,5 +404,116 @@ $effect(() => {
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
{:else}
|
||||||
|
<!-- Version list with inline diff below each selected item -->
|
||||||
|
<ul class="divide-y divide-brand-sand">
|
||||||
|
{#each versions as v, i (v.id)}
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
onclick={() => selectVersion(v.id)}
|
||||||
|
data-testid="history-version"
|
||||||
|
class="w-full py-2 text-left transition hover:bg-brand-sand/30 {selectedVersionId ===
|
||||||
|
v.id
|
||||||
|
? 'border-l-2 border-brand-mint pl-2'
|
||||||
|
: 'pl-0'}"
|
||||||
|
>
|
||||||
|
<div class="flex items-baseline justify-between gap-2">
|
||||||
|
<span class="font-sans text-xs font-medium text-brand-navy">
|
||||||
|
Version {i + 1}
|
||||||
|
</span>
|
||||||
|
<span class="font-sans text-[10px] text-gray-400">
|
||||||
|
{formatDateTime(v.savedAt)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span class="font-sans text-[11px] text-gray-500">{v.editorName}</span>
|
||||||
|
{#if v.changedFields && v.changedFields.length > 0}
|
||||||
|
<div class="mt-1 flex flex-wrap gap-1">
|
||||||
|
{#each v.changedFields as field (field)}
|
||||||
|
<span
|
||||||
|
class="rounded bg-brand-sand/50 px-1.5 py-0.5 font-sans text-[10px] tracking-wide text-gray-500 uppercase"
|
||||||
|
>
|
||||||
|
{fieldLabels[field] ? fieldLabels[field]() : field}
|
||||||
|
</span>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Diff shown inline below the selected version -->
|
||||||
|
{#if selectedVersionId === v.id}
|
||||||
|
{#if diffLoading}
|
||||||
|
<p class="pb-3 pl-2 font-sans text-xs text-gray-400">{m.history_loading()}</p>
|
||||||
|
{:else if noDiff}
|
||||||
|
<div
|
||||||
|
data-testid="history-diff"
|
||||||
|
class="mb-2 rounded-sm border border-brand-sand bg-white p-4 font-serif text-sm text-gray-400 italic"
|
||||||
|
>
|
||||||
|
{m.history_diff_no_changes()}
|
||||||
|
</div>
|
||||||
|
{:else if diffEntries.length > 0}
|
||||||
|
<div
|
||||||
|
data-testid="history-diff"
|
||||||
|
class="mb-2 space-y-4 rounded-sm border border-brand-sand bg-white p-4"
|
||||||
|
>
|
||||||
|
{#each diffEntries as entry (entry.field)}
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="mb-1.5 block font-sans text-[10px] font-bold tracking-wide text-gray-400 uppercase"
|
||||||
|
>{entry.label}</span
|
||||||
|
>
|
||||||
|
{#if entry.kind === 'text'}
|
||||||
|
<p class="font-serif text-sm leading-relaxed">
|
||||||
|
{#each entry.parts as part, partIdx (partIdx)}
|
||||||
|
{#if part.added}
|
||||||
|
<span class="bg-green-50 text-green-700">{part.value}</span>
|
||||||
|
{:else if part.removed}
|
||||||
|
<span class="bg-red-50 text-red-600 line-through">{part.value}</span>
|
||||||
|
{:else}
|
||||||
|
<span>{part.value}</span>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</p>
|
||||||
|
{:else if entry.kind === 'scalar'}
|
||||||
|
<div class="flex items-center gap-2 font-serif text-sm">
|
||||||
|
<span class="text-red-600 line-through">{entry.oldVal || '—'}</span>
|
||||||
|
<svg
|
||||||
|
class="h-3 w-3 flex-shrink-0 text-gray-400"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<span class="text-green-700">{entry.newVal || '—'}</span>
|
||||||
|
</div>
|
||||||
|
{:else if entry.kind === 'relation'}
|
||||||
|
<div class="flex flex-wrap gap-1.5">
|
||||||
|
{#each entry.removed as item (item)}
|
||||||
|
<span
|
||||||
|
class="rounded bg-red-50 px-1.5 py-0.5 font-sans text-[11px] text-red-600 line-through"
|
||||||
|
>{item}</span
|
||||||
|
>
|
||||||
|
{/each}
|
||||||
|
{#each entry.added as item (item)}
|
||||||
|
<span
|
||||||
|
class="rounded bg-green-50 px-1.5 py-0.5 font-sans text-[11px] text-green-700"
|
||||||
|
>{item}</span
|
||||||
|
>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user