Работает создание коммитов и перенос в новый enviroment
This commit is contained in:
170
frontend/src/components/git/BranchSelector.svelte
Normal file
170
frontend/src/components/git/BranchSelector.svelte
Normal file
@@ -0,0 +1,170 @@
|
||||
<!-- [DEF:BranchSelector:Component] -->
|
||||
<!--
|
||||
@SEMANTICS: git, branch, selection, checkout
|
||||
@PURPOSE: UI для выбора и создания веток Git.
|
||||
@LAYER: Component
|
||||
@RELATION: CALLS -> gitService.getBranches
|
||||
@RELATION: CALLS -> gitService.checkoutBranch
|
||||
@RELATION: CALLS -> gitService.createBranch
|
||||
@RELATION: DISPATCHES -> change
|
||||
-->
|
||||
|
||||
<script>
|
||||
// [SECTION: IMPORTS]
|
||||
import { onMount, createEventDispatcher } from 'svelte';
|
||||
import { gitService } from '../../services/gitService';
|
||||
import { addToast as toast } from '../../lib/toasts.js';
|
||||
// [/SECTION]
|
||||
|
||||
// [SECTION: PROPS]
|
||||
export let dashboardId;
|
||||
export let currentBranch = 'main';
|
||||
// [/SECTION]
|
||||
|
||||
// [SECTION: STATE]
|
||||
let branches = [];
|
||||
let loading = false;
|
||||
let showCreate = false;
|
||||
let newBranchName = '';
|
||||
// [/SECTION]
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
// [DEF:onMount:Function]
|
||||
onMount(async () => {
|
||||
await loadBranches();
|
||||
});
|
||||
// [/DEF:onMount:Function]
|
||||
|
||||
// [DEF:loadBranches:Function]
|
||||
/**
|
||||
* @purpose Загружает список веток для дашборда.
|
||||
* @post branches обновлен.
|
||||
*/
|
||||
async function loadBranches() {
|
||||
console.log(`[BranchSelector][Action] Loading branches for dashboard ${dashboardId}`);
|
||||
loading = true;
|
||||
try {
|
||||
branches = await gitService.getBranches(dashboardId);
|
||||
console.log(`[BranchSelector][Coherence:OK] Loaded ${branches.length} branches`);
|
||||
} catch (e) {
|
||||
console.error(`[BranchSelector][Coherence:Failed] ${e.message}`);
|
||||
toast('Failed to load branches', 'error');
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
// [/DEF:loadBranches:Function]
|
||||
|
||||
// [DEF:handleSelect:Function]
|
||||
function handleSelect(event) {
|
||||
handleCheckout(event.target.value);
|
||||
}
|
||||
// [/DEF:handleSelect:Function]
|
||||
|
||||
// [DEF:handleCheckout:Function]
|
||||
/**
|
||||
* @purpose Переключает текущую ветку.
|
||||
* @param {string} branchName - Имя ветки.
|
||||
* @post currentBranch обновлен, событие отправлено.
|
||||
*/
|
||||
async function handleCheckout(branchName) {
|
||||
console.log(`[BranchSelector][Action] Checking out branch ${branchName}`);
|
||||
try {
|
||||
await gitService.checkoutBranch(dashboardId, branchName);
|
||||
currentBranch = branchName;
|
||||
dispatch('change', { branch: branchName });
|
||||
toast(`Switched to ${branchName}`, 'success');
|
||||
console.log(`[BranchSelector][Coherence:OK] Checked out ${branchName}`);
|
||||
} catch (e) {
|
||||
console.error(`[BranchSelector][Coherence:Failed] ${e.message}`);
|
||||
toast(e.message, 'error');
|
||||
}
|
||||
}
|
||||
// [/DEF:handleCheckout:Function]
|
||||
|
||||
// [DEF:handleCreate:Function]
|
||||
/**
|
||||
* @purpose Создает новую ветку.
|
||||
* @post Новая ветка создана и загружена.
|
||||
*/
|
||||
async function handleCreate() {
|
||||
if (!newBranchName) return;
|
||||
console.log(`[BranchSelector][Action] Creating branch ${newBranchName} from ${currentBranch}`);
|
||||
try {
|
||||
await gitService.createBranch(dashboardId, newBranchName, currentBranch);
|
||||
toast(`Created branch ${newBranchName}`, 'success');
|
||||
showCreate = false;
|
||||
newBranchName = '';
|
||||
await loadBranches();
|
||||
console.log(`[BranchSelector][Coherence:OK] Branch created`);
|
||||
} catch (e) {
|
||||
console.error(`[BranchSelector][Coherence:Failed] ${e.message}`);
|
||||
toast(e.message, 'error');
|
||||
}
|
||||
}
|
||||
// [/DEF:handleCreate:Function]
|
||||
</script>
|
||||
|
||||
<!-- [SECTION: TEMPLATE] -->
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center space-x-2">
|
||||
<div class="relative">
|
||||
<select
|
||||
value={currentBranch}
|
||||
on:change={handleSelect}
|
||||
disabled={loading}
|
||||
class="bg-white border rounded px-3 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
>
|
||||
{#each branches as branch}
|
||||
<option value={branch.name}>{branch.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
{#if loading}
|
||||
<span class="absolute -right-6 top-1">
|
||||
<svg class="animate-spin h-4 w-4 text-blue-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<button
|
||||
on:click={() => showCreate = !showCreate}
|
||||
disabled={loading}
|
||||
class="text-blue-600 hover:text-blue-800 text-sm font-medium disabled:opacity-50"
|
||||
>
|
||||
+ New Branch
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{#if showCreate}
|
||||
<div class="flex items-center space-x-1 bg-gray-50 p-2 rounded border border-dashed">
|
||||
<input
|
||||
type="text"
|
||||
bind:value={newBranchName}
|
||||
placeholder="branch-name"
|
||||
disabled={loading}
|
||||
class="border rounded px-2 py-1 text-sm w-full max-w-[150px]"
|
||||
/>
|
||||
<button
|
||||
on:click={handleCreate}
|
||||
disabled={loading || !newBranchName}
|
||||
class="bg-green-600 text-white px-3 py-1 rounded text-xs font-medium hover:bg-green-700 disabled:opacity-50"
|
||||
>
|
||||
{loading ? '...' : 'Create'}
|
||||
</button>
|
||||
<button
|
||||
on:click={() => showCreate = false}
|
||||
disabled={loading}
|
||||
class="text-gray-500 hover:text-gray-700 text-xs px-2 py-1 disabled:opacity-50"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<!-- [/SECTION] -->
|
||||
|
||||
<!-- [/DEF:BranchSelector:Component] -->
|
||||
Reference in New Issue
Block a user