@using RackPeek.Domain.Git @using RackPeek.Domain.Git.UseCases @inject InitRepoUseCase InitRepo @inject CommitAllUseCase CommitAll @inject RestoreAllUseCase RestoreAll @inject PushUseCase PushUseCase @inject PullUseCase PullUseCase @inject AddRemoteUseCase AddRemoteUseCase @inject IGitRepository GitRepo @implements IDisposable @if (_status == GitRepoStatus.NotAvailable) {
@if (_confirmInit) { Enable git tracking? } else { } @if (_errorMessage is not null) { @_errorMessage }
} else {
@if (!string.IsNullOrEmpty(_branch) && _hasRemote) { } @if (_status == GitRepoStatus.Clean && _hasRemote) { Saved } else if (_status == GitRepoStatus.Dirty && _hasRemote) {
@if (_showDropdown) {
@if (!_confirmDiscard) { } else {
Sure?
}
}
} @if (!_hasRemote) {
@if (_showAddRemote) { } else { } Connect a remote repository to enable saving and sync.
} else {
@if (_showSyncDropdown) {
}
} @if (_errorMessage is not null) { @_errorMessage }
} @code { private GitRepoStatus _status = GitRepoStatus.NotAvailable; private string _branch = ""; private bool _isCommitting; private bool _isRestoring; private bool _confirmDiscard; private bool _showDropdown; private bool _showAddRemote; private bool _showSyncDropdown; private bool _showHistory; private bool _hasRemote; private bool _isFetching; private bool _isPushing; private bool _isPulling; private bool _isInitializing; private bool _confirmInit; private string? _errorMessage; private string _remoteUrl = ""; private string _diffContent = ""; private string[] _changedFiles = []; private GitLogEntry[] _logEntries = []; private PeriodicTimer? _timer; private CancellationTokenSource? _cts; private GitSyncStatus _syncStatus = new(0,0,false); private bool _isBusy => _isCommitting || _isRestoring || _isSyncing; private bool _isSyncing => _isPushing || _isPulling || _isFetching; protected override async Task OnInitializedAsync() { _status = GitRepo.GetStatus(); if (_status == GitRepoStatus.NotAvailable) return; _branch = GitRepo.GetCurrentBranch(); _hasRemote = GitRepo.HasRemote(); _cts = new CancellationTokenSource(); _timer = new PeriodicTimer(TimeSpan.FromSeconds(15)); _ = PollStatusAsync(_cts.Token); await Task.CompletedTask; } private async Task PollStatusAsync(CancellationToken ct) { try { while (_timer != null && await _timer.WaitForNextTickAsync(ct)) { if (_isBusy) continue; var newStatus = GitRepo.GetStatus(); if (newStatus != _status) { _status = newStatus; await InvokeAsync(StateHasChanged); } } } catch (OperationCanceledException) {} } private async Task InitRepoAsync() { _errorMessage = null; _isInitializing = true; try { var error = await InitRepo.ExecuteAsync(); if (error != null) { _errorMessage = error; return; } _status = GitRepo.GetStatus(); _branch = GitRepo.GetCurrentBranch(); _hasRemote = GitRepo.HasRemote(); } catch (Exception ex) { _errorMessage = $"Init error: {ex.Message}"; } finally { _isInitializing = false; } } private void CancelAddRemote() { _showAddRemote = false; _remoteUrl = ""; } private async Task AddRemoteAsync() { _errorMessage = null; try { var error = await AddRemoteUseCase.ExecuteAsync(_remoteUrl); if (error != null) { _errorMessage = error; return; } _hasRemote = true; _showAddRemote = false; _remoteUrl = ""; _syncStatus = GitRepo.FetchAndGetSyncStatus(); if (_syncStatus.Behind > 0) await PullAsync(); } catch (Exception ex) { _errorMessage = $"Remote error: {ex.Message}"; } } private async Task CommitAsync() { if (!_hasRemote) { _errorMessage = "Add a remote repository before saving."; return; } _errorMessage = null; _isCommitting = true; try { var error = await CommitAll.ExecuteAsync( $"rackpeek: save config {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} UTC"); if (error != null) _errorMessage = error; _status = GitRepo.GetStatus(); } catch (Exception ex) { _errorMessage = $"Commit error: {ex.Message}"; } finally { _isCommitting = false; } } private void ToggleDropdown() { _showDropdown = !_showDropdown; _showSyncDropdown = false; } private void ToggleSyncAsync() { _showSyncDropdown = !_showSyncDropdown; _showDropdown = false; if (_showSyncDropdown) { _isFetching = true; try { _syncStatus = GitRepo.FetchAndGetSyncStatus(); } finally { _isFetching = false; } } } private async Task PushAsync() { if (!_hasRemote) { _errorMessage = "Add a remote first."; return; } _errorMessage = null; _isPushing = true; try { var error = await PushUseCase.ExecuteAsync(); if (error != null) _errorMessage = error; _syncStatus = GitRepo.FetchAndGetSyncStatus(); } catch (Exception ex) { _errorMessage = $"Push error: {ex.Message}"; } finally { _isPushing = false; } } private async Task PullAsync() { _errorMessage = null; _isPulling = true; try { var error = await PullUseCase.ExecuteAsync(); if (error != null) _errorMessage = error; _syncStatus = GitRepo.FetchAndGetSyncStatus(); _status = GitRepo.GetStatus(); } catch (Exception ex) { _errorMessage = $"Pull error: {ex.Message}"; } finally { _isPulling = false; } } public void Dispose() { _cts?.Cancel(); _cts?.Dispose(); _timer?.Dispose(); } private void OpenDiffAsync() { _showDropdown = false; try { _changedFiles = GitRepo.GetChangedFiles(); _diffContent = GitRepo.GetDiff(); } catch (Exception ex) { _errorMessage = $"Diff error: {ex.Message}"; } } private async Task DiscardAsync() { _errorMessage = null; _isRestoring = true; _confirmDiscard = false; _showDropdown = false; try { var error = await RestoreAll.ExecuteAsync(); if (error != null) _errorMessage = error; _status = GitRepo.GetStatus(); } catch (Exception ex) { _errorMessage = $"Discard error: {ex.Message}"; } finally { _isRestoring = false; } } private void ToggleHistoryAsync() { if (_showHistory) { _showHistory = false; return; } try { _logEntries = GitRepo.GetLog(20); _showHistory = true; } catch (Exception ex) { _errorMessage = $"History error: {ex.Message}"; } } }