150 lines
4.7 KiB
Text
150 lines
4.7 KiB
Text
|
|
@inject IJSRuntime JS
|
||
|
|
@inject ISettingsService SettingsService
|
||
|
|
@inject IProjectService ProjectService
|
||
|
|
|
||
|
|
<div class="copy-create-toolbar">
|
||
|
|
<button class="btn btn-sm" @onclick="CopyToClipboard" title="In Zwischenablage kopieren">📋 Kopieren</button>
|
||
|
|
<button class="btn btn-sm" @onclick="ShowCreateDialog" title="Als neue .md Datei speichern">📄 Als MD speichern</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
@if (showCreateDialog)
|
||
|
|
{
|
||
|
|
<div class="modal-overlay">
|
||
|
|
<div class="modal-dialog">
|
||
|
|
<div class="modal-title">Neue .md Datei erstellen</div>
|
||
|
|
<div class="modal-body">
|
||
|
|
@if (!string.IsNullOrEmpty(_projectPath))
|
||
|
|
{
|
||
|
|
<div class="form-group">
|
||
|
|
<label>Zielverzeichnis:</label>
|
||
|
|
<span style="font-size:11px;color:var(--border-color);word-break:break-all;">@_projectPath</span>
|
||
|
|
</div>
|
||
|
|
}
|
||
|
|
<div class="form-group">
|
||
|
|
<label>Dateiname:</label>
|
||
|
|
<input @bind="newFileName" placeholder="Dateiname (ohne .md)" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="modal-actions">
|
||
|
|
<button @onclick="CancelCreate">Abbrechen</button>
|
||
|
|
<button @onclick="CreateFile" class="primary" disabled="@(string.IsNullOrWhiteSpace(newFileName))">Erstellen</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
}
|
||
|
|
|
||
|
|
<style>
|
||
|
|
.copy-create-toolbar {
|
||
|
|
display: inline-flex;
|
||
|
|
gap: 4px;
|
||
|
|
margin-left: 8px;
|
||
|
|
vertical-align: middle;
|
||
|
|
}
|
||
|
|
.copy-create-toolbar .btn-sm {
|
||
|
|
font-size: 11px;
|
||
|
|
padding: 2px 8px;
|
||
|
|
line-height: 1.4;
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
|
||
|
|
@code {
|
||
|
|
[Parameter] public string Text { get; set; } = string.Empty;
|
||
|
|
[Parameter] public string? DefaultFileName { get; set; }
|
||
|
|
[Parameter] public EventCallback<string> OnFileCreated { get; set; }
|
||
|
|
|
||
|
|
private bool showCreateDialog;
|
||
|
|
private string newFileName = string.Empty;
|
||
|
|
private int? _projectId;
|
||
|
|
private string? _projectPath;
|
||
|
|
private bool _isCopyDisabled;
|
||
|
|
|
||
|
|
protected override async Task OnInitializedAsync()
|
||
|
|
{
|
||
|
|
_projectId = SettingsService.CurrentProjectId;
|
||
|
|
if (_projectId.HasValue && _projectId > 0)
|
||
|
|
{
|
||
|
|
var project = await ProjectService.GetProjectAsync(_projectId.Value);
|
||
|
|
_projectPath = project?.RootPath;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!string.IsNullOrEmpty(DefaultFileName))
|
||
|
|
newFileName = DefaultFileName;
|
||
|
|
}
|
||
|
|
|
||
|
|
private async Task CopyToClipboard()
|
||
|
|
{
|
||
|
|
if (string.IsNullOrEmpty(Text) || _isCopyDisabled) return;
|
||
|
|
_isCopyDisabled = true;
|
||
|
|
try
|
||
|
|
{
|
||
|
|
await JS.InvokeVoidAsync("navigator.clipboard.writeText", Text);
|
||
|
|
}
|
||
|
|
catch
|
||
|
|
{
|
||
|
|
// Fallback for older browsers
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var textArea = System.Text.Encodings.Web.JavaScriptEncoder.Default.Encode(Text);
|
||
|
|
await JS.InvokeVoidAsync("eval", $"navigator.clipboard.writeText('{textArea}')");
|
||
|
|
}
|
||
|
|
catch { }
|
||
|
|
}
|
||
|
|
finally
|
||
|
|
{
|
||
|
|
_isCopyDisabled = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void ShowCreateDialog()
|
||
|
|
{
|
||
|
|
newFileName = DefaultFileName ?? string.Empty;
|
||
|
|
showCreateDialog = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void CancelCreate()
|
||
|
|
{
|
||
|
|
showCreateDialog = false;
|
||
|
|
newFileName = string.Empty;
|
||
|
|
}
|
||
|
|
|
||
|
|
private async Task CreateFile()
|
||
|
|
{
|
||
|
|
if (string.IsNullOrWhiteSpace(newFileName) || string.IsNullOrEmpty(Text)) return;
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var fileName = newFileName.Trim();
|
||
|
|
if (!fileName.EndsWith(".md", StringComparison.OrdinalIgnoreCase))
|
||
|
|
fileName += ".md";
|
||
|
|
|
||
|
|
string savePath;
|
||
|
|
if (!string.IsNullOrEmpty(_projectPath) && Directory.Exists(_projectPath))
|
||
|
|
{
|
||
|
|
savePath = Path.Combine(_projectPath, fileName);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
savePath = Path.Combine(Directory.GetCurrentDirectory(), fileName);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (File.Exists(savePath))
|
||
|
|
{
|
||
|
|
var dir = Path.GetDirectoryName(savePath)!;
|
||
|
|
var name = Path.GetFileNameWithoutExtension(savePath);
|
||
|
|
var ext = Path.GetExtension(savePath);
|
||
|
|
var counter = 1;
|
||
|
|
do
|
||
|
|
{
|
||
|
|
savePath = Path.Combine(dir, $"{name}_{counter}{ext}");
|
||
|
|
counter++;
|
||
|
|
} while (File.Exists(savePath));
|
||
|
|
}
|
||
|
|
|
||
|
|
await File.WriteAllTextAsync(savePath, Text);
|
||
|
|
showCreateDialog = false;
|
||
|
|
await OnFileCreated.InvokeAsync(Path.GetFileName(savePath));
|
||
|
|
}
|
||
|
|
catch { }
|
||
|
|
}
|
||
|
|
}
|