Files
ss-tools/frontend/src/components/git/GitMergeDialog.svelte
busya cf7b3556f7 refactor(frontend): enforce semantic tokens + extract 3 Screen Models
Color tokens: 3658→0 violations across 186 .svelte/.svelte.ts files.
All raw Tailwind colors (bg-blue-*, text-gray-*, border-red-*, etc.)
replaced with semantic tokens from tailwind.config.js in 5 perl passes.

Model extraction (11→8 oversized pages):
- LLMReportModel.svelte.ts: LLM report page 413→221 lines
- DatasetDetailModel.svelte.ts: dataset detail page 416→218 lines
- DatasetsHubModel.svelte.ts: datasets hub page 468→246 lines

Tests: 14 assertions updated (color classes + model refs).
Build: 1 duplicate class:text-primary fix in ValidationTaskForm.
All 699/699 tests pass.
2026-06-02 17:58:36 +03:00

132 lines
5.1 KiB
Svelte

<!-- #region GitMergeDialog [C:3] [TYPE Component] [SEMANTICS git, merge, conflict, dialog, recovery] -->
<!-- @BRIEF Unfinished merge recovery dialog: abort, continue, resolve conflicts. -->
<!-- @LAYER UI -->
<!-- @RELATION DEPENDS_ON -> [GitUtils] -->
<!-- @RELATION CALLS -> [EXT:frontend:gitService] -->
<!-- @UX_STATE Open -> Dialog with merge context, status, and action buttons. -->
<!-- @UX_STATE Loading -> Recovery state loading spinner. -->
<script lang="ts">
import { t } from "$lib/i18n/index.svelte.js";
import { Button } from "$lib/ui";
let {
show = $bindable(false),
unfinishedMergeContext,
mergeRecoveryLoading,
mergeResolveInProgress,
mergeAbortInProgress,
mergeContinueInProgress,
copyingUnfinishedMergeCommands,
onRefresh,
onCopyCommands,
onOpenConflictResolver,
onAbortMerge,
onContinueMerge,
onClose,
} = $props();
</script>
{#if show && unfinishedMergeContext}
<div
class="absolute inset-0 z-20 flex items-center justify-center bg-black bg-opacity-40 p-4"
role="dialog"
aria-modal="true"
aria-label={$t.git?.unfinished_merge?.title || 'Repository has an unfinished merge'}
>
<div class="max-h-[85vh] w-full max-w-2xl overflow-y-auto rounded-lg border border-warning bg-surface-card p-5 shadow-2xl">
<div class="mb-3 text-lg font-semibold text-amber-900">
{$t.git?.unfinished_merge?.title || 'Repository has an unfinished merge'}
</div>
<p class="mb-4 text-sm text-text">
{unfinishedMergeContext.message || ($t.git?.unfinished_merge?.default_message || 'An unfinished merge was detected in this repository.')}
</p>
<div class="grid grid-cols-1 gap-2 text-sm md:grid-cols-2">
<div class="rounded border border-border bg-surface-page p-2">
<div class="text-xs text-text-muted">{$t.git?.unfinished_merge?.repository_path || 'Repository path'}</div>
<div class="break-all font-mono text-text">{unfinishedMergeContext.repositoryPath || '—'}</div>
</div>
<div class="rounded border border-border bg-surface-page p-2">
<div class="text-xs text-text-muted">{$t.git?.unfinished_merge?.branch || 'Current branch'}</div>
<div class="font-mono text-text">{unfinishedMergeContext.currentBranch || '—'}</div>
</div>
{#if unfinishedMergeContext.mergeHead}
<div class="rounded border border-border bg-surface-page p-2 md:col-span-2">
<div class="text-xs text-text-muted">MERGE_HEAD</div>
<div class="break-all font-mono text-text">{unfinishedMergeContext.mergeHead}</div>
</div>
{/if}
</div>
{#if unfinishedMergeContext.nextSteps?.length}
<div class="mt-4">
<div class="mb-1 text-sm font-semibold text-text">
{$t.git?.unfinished_merge?.next_steps || 'Recommended steps'}
</div>
<ol class="list-decimal space-y-1 pl-5 text-sm text-text">
{#each unfinishedMergeContext.nextSteps as step}
<li>{step}</li>
{/each}
</ol>
</div>
{/if}
{#if unfinishedMergeContext.commands?.length}
<div class="mt-4">
<div class="mb-1 text-sm font-semibold text-text">
{$t.git?.unfinished_merge?.manual_commands || 'Manual recovery commands'}
</div>
<pre class="overflow-auto rounded border border-border bg-surface-page p-3 text-xs text-text">{unfinishedMergeContext.commands.join('\n')}</pre>
</div>
{/if}
<div class="mt-5 flex flex-wrap justify-end gap-2">
<Button
variant="ghost"
onclick={onRefresh}
disabled={mergeRecoveryLoading}
isLoading={mergeRecoveryLoading}
>
{$t.common?.refresh || 'Refresh'}
</Button>
<Button
variant="secondary"
onclick={onCopyCommands}
disabled={copyingUnfinishedMergeCommands}
isLoading={copyingUnfinishedMergeCommands}
>
{$t.git?.unfinished_merge?.copy_commands || 'Copy commands'}
</Button>
<Button
variant="ghost"
onclick={onOpenConflictResolver}
disabled={mergeRecoveryLoading || mergeResolveInProgress}
isLoading={mergeResolveInProgress}
>
{$t.git?.unfinished_merge?.open_resolver || 'Open conflict resolver'}
</Button>
<Button
variant="ghost"
onclick={onAbortMerge}
disabled={mergeAbortInProgress}
isLoading={mergeAbortInProgress}
class="border border-destructive-ring text-destructive hover:bg-destructive-light"
>
{$t.git?.unfinished_merge?.abort_merge || 'Abort merge'}
</Button>
<Button
onclick={onContinueMerge}
disabled={mergeContinueInProgress}
isLoading={mergeContinueInProgress}
>
{$t.git?.unfinished_merge?.continue_merge || 'Continue merge'}
</Button>
<Button onclick={onClose}>
{$t.common?.close || 'Close'}
</Button>
</div>
</div>
</div>
{/if}
<!-- #endregion GitMergeDialog -->