css refactor
This commit is contained in:
@@ -10,20 +10,23 @@
|
||||
|
||||
<script>
|
||||
// [SECTION: IMPORTS]
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { addToast as toast } from '../../lib/toasts.js';
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import { addToast as toast } from "../../lib/toasts.js";
|
||||
// [/SECTION]
|
||||
|
||||
// [SECTION: PROPS]
|
||||
/** @type {Array<{file_path: string, mine: string, theirs: string}>} */
|
||||
export let conflicts = [];
|
||||
export let show = false;
|
||||
let {
|
||||
conflicts = [],
|
||||
show = false,
|
||||
} = $props();
|
||||
|
||||
// [/SECTION]
|
||||
|
||||
// [SECTION: STATE]
|
||||
const dispatch = createEventDispatcher();
|
||||
/** @type {Object.<string, 'mine' | 'theirs' | 'manual'>} */
|
||||
let resolutions = {};
|
||||
let resolutions = {};
|
||||
// [/SECTION]
|
||||
|
||||
// [DEF:resolve:Function]
|
||||
@@ -36,7 +39,9 @@
|
||||
* @side_effect Updates resolutions state.
|
||||
*/
|
||||
function resolve(file, strategy) {
|
||||
console.log(`[ConflictResolver][Action] Resolving ${file} with ${strategy}`);
|
||||
console.log(
|
||||
`[ConflictResolver][Action] Resolving ${file} with ${strategy}`,
|
||||
);
|
||||
resolutions[file] = strategy;
|
||||
resolutions = { ...resolutions }; // Trigger update
|
||||
}
|
||||
@@ -51,16 +56,21 @@
|
||||
*/
|
||||
function handleSave() {
|
||||
// 1. Guard Clause (@PRE)
|
||||
const unresolved = conflicts.filter(c => !resolutions[c.file_path]);
|
||||
const unresolved = conflicts.filter((c) => !resolutions[c.file_path]);
|
||||
if (unresolved.length > 0) {
|
||||
console.warn(`[ConflictResolver][Coherence:Failed] ${unresolved.length} unresolved conflicts`);
|
||||
toast(`Please resolve all conflicts first. (${unresolved.length} remaining)`, 'error');
|
||||
console.warn(
|
||||
`[ConflictResolver][Coherence:Failed] ${unresolved.length} unresolved conflicts`,
|
||||
);
|
||||
toast(
|
||||
`Please resolve all conflicts first. (${unresolved.length} remaining)`,
|
||||
"error",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Implementation
|
||||
console.log(`[ConflictResolver][Coherence:OK] All conflicts resolved`);
|
||||
dispatch('resolve', resolutions);
|
||||
dispatch("resolve", resolutions);
|
||||
show = false;
|
||||
}
|
||||
// [/DEF:handleSave:Function]
|
||||
@@ -68,43 +78,78 @@
|
||||
|
||||
<!-- [SECTION: TEMPLATE] -->
|
||||
{#if show}
|
||||
<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
|
||||
<div class="bg-white p-6 rounded-lg shadow-xl w-full max-w-5xl max-h-[90vh] flex flex-col">
|
||||
<h2 class="text-xl font-bold mb-4 text-red-600">Merge Conflicts Detected</h2>
|
||||
<p class="text-gray-600 mb-4">The following files have conflicts. Please choose how to resolve them.</p>
|
||||
<div
|
||||
class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"
|
||||
>
|
||||
<div
|
||||
class="bg-white p-6 rounded-lg shadow-xl w-full max-w-5xl max-h-[90vh] flex flex-col"
|
||||
>
|
||||
<h2 class="text-xl font-bold mb-4 text-red-600">
|
||||
Merge Conflicts Detected
|
||||
</h2>
|
||||
<p class="text-gray-600 mb-4">
|
||||
The following files have conflicts. Please choose how to resolve
|
||||
them.
|
||||
</p>
|
||||
|
||||
<div class="flex-1 overflow-y-auto space-y-6 mb-4 pr-2">
|
||||
{#each conflicts as conflict}
|
||||
<div class="border rounded-lg overflow-hidden">
|
||||
<div class="bg-gray-100 px-4 py-2 font-medium border-b flex justify-between items-center">
|
||||
<div
|
||||
class="bg-gray-100 px-4 py-2 font-medium border-b flex justify-between items-center"
|
||||
>
|
||||
<span>{conflict.file_path}</span>
|
||||
{#if resolutions[conflict.file_path]}
|
||||
<span class="text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded-full uppercase font-bold">
|
||||
<span
|
||||
class="text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded-full uppercase font-bold"
|
||||
>
|
||||
Resolved: {resolutions[conflict.file_path]}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-0 divide-x">
|
||||
<div
|
||||
class="grid grid-cols-1 md:grid-cols-2 gap-0 divide-x"
|
||||
>
|
||||
<div class="p-0 flex flex-col">
|
||||
<div class="bg-blue-50 px-4 py-1 text-[10px] font-bold text-blue-600 uppercase border-b">Your Changes (Mine)</div>
|
||||
<div class="p-4 bg-white flex-1 overflow-auto">
|
||||
<pre class="text-xs font-mono whitespace-pre">{conflict.mine}</pre>
|
||||
<div
|
||||
class="bg-blue-50 px-4 py-1 text-[10px] font-bold text-blue-600 uppercase border-b"
|
||||
>
|
||||
Your Changes (Mine)
|
||||
</div>
|
||||
<button
|
||||
class="w-full py-2 text-sm font-medium border-t transition-colors {resolutions[conflict.file_path] === 'mine' ? 'bg-blue-600 text-white' : 'bg-gray-50 hover:bg-blue-50 text-blue-600'}"
|
||||
on:click={() => resolve(conflict.file_path, 'mine')}
|
||||
<div class="p-4 bg-white flex-1 overflow-auto">
|
||||
<pre
|
||||
class="text-xs font-mono whitespace-pre">{conflict.mine}</pre>
|
||||
</div>
|
||||
<button
|
||||
class="w-full py-2 text-sm font-medium border-t transition-colors {resolutions[
|
||||
conflict.file_path
|
||||
] === 'mine'
|
||||
? 'bg-blue-600 text-white'
|
||||
: 'bg-gray-50 hover:bg-blue-50 text-blue-600'}"
|
||||
on:click={() =>
|
||||
resolve(conflict.file_path, "mine")}
|
||||
>
|
||||
Keep Mine
|
||||
</button>
|
||||
</div>
|
||||
<div class="p-0 flex flex-col">
|
||||
<div class="bg-green-50 px-4 py-1 text-[10px] font-bold text-green-600 uppercase border-b">Remote Changes (Theirs)</div>
|
||||
<div class="p-4 bg-white flex-1 overflow-auto">
|
||||
<pre class="text-xs font-mono whitespace-pre">{conflict.theirs}</pre>
|
||||
<div
|
||||
class="bg-green-50 px-4 py-1 text-[10px] font-bold text-green-600 uppercase border-b"
|
||||
>
|
||||
Remote Changes (Theirs)
|
||||
</div>
|
||||
<button
|
||||
class="w-full py-2 text-sm font-medium border-t transition-colors {resolutions[conflict.file_path] === 'theirs' ? 'bg-green-600 text-white' : 'bg-gray-50 hover:bg-green-50 text-green-600'}"
|
||||
on:click={() => resolve(conflict.file_path, 'theirs')}
|
||||
<div class="p-4 bg-white flex-1 overflow-auto">
|
||||
<pre
|
||||
class="text-xs font-mono whitespace-pre">{conflict.theirs}</pre>
|
||||
</div>
|
||||
<button
|
||||
class="w-full py-2 text-sm font-medium border-t transition-colors {resolutions[
|
||||
conflict.file_path
|
||||
] === 'theirs'
|
||||
? 'bg-green-600 text-white'
|
||||
: 'bg-gray-50 hover:bg-green-50 text-green-600'}"
|
||||
on:click={() =>
|
||||
resolve(conflict.file_path, "theirs")}
|
||||
>
|
||||
Keep Theirs
|
||||
</button>
|
||||
@@ -115,13 +160,13 @@
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end space-x-3 pt-4 border-t">
|
||||
<button
|
||||
on:click={() => show = false}
|
||||
<button
|
||||
on:click={() => (show = false)}
|
||||
class="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded transition-colors"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
<button
|
||||
on:click={handleSave}
|
||||
class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors shadow-sm"
|
||||
>
|
||||
@@ -133,10 +178,4 @@
|
||||
{/if}
|
||||
<!-- [/SECTION] -->
|
||||
|
||||
<style>
|
||||
pre {
|
||||
tab-size: 4;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- [/DEF:ConflictResolver:Component] -->
|
||||
<!-- [/DEF:ConflictResolver:Component] -->
|
||||
|
||||
Reference in New Issue
Block a user