Many updates
This commit is contained in:
		@@ -7,7 +7,6 @@ namespace Seenginx.Models
 | 
			
		||||
		public string FullPath { get; set; }
 | 
			
		||||
		public string Folder { get; set; }
 | 
			
		||||
		public string Name { get; set; }
 | 
			
		||||
		public string DraftName { get; set; }
 | 
			
		||||
		public string Body { get; set; }
 | 
			
		||||
		public string DraftBody { get; set; }
 | 
			
		||||
		public string Permissions { get; set; }
 | 
			
		||||
@@ -15,7 +14,7 @@ namespace Seenginx.Models
 | 
			
		||||
		public string[] Owners { get; set; }
 | 
			
		||||
		public string IsVisible { get; set; } = string.Empty;
 | 
			
		||||
		public string IsSelected { get; set; } = string.Empty;
 | 
			
		||||
		public bool HasDraft => !string.IsNullOrEmpty(DraftName);
 | 
			
		||||
		public bool HasDraft => !string.IsNullOrEmpty(DraftBody);
 | 
			
		||||
		public bool CanBeDeleted { get; set; } = true;
 | 
			
		||||
 | 
			
		||||
		public void Hide() { IsVisible = "is-hidden"; }
 | 
			
		||||
 
 | 
			
		||||
@@ -17,11 +17,19 @@
 | 
			
		||||
		@if (IsAnyFileSelected)
 | 
			
		||||
		{
 | 
			
		||||
			<div class="field is-grouped">
 | 
			
		||||
				<div class="control is-expanded borderRBig neoInput has-text-centered">
 | 
			
		||||
					<input class="input is-5 is-rounded is-small neoInput"
 | 
			
		||||
								 type="text" placeholder="Search..."
 | 
			
		||||
								 value="@SelectedFile.Name" disabled="@(SelectedFile.CanBeDeleted ? null : "disabled")"
 | 
			
		||||
								 @onchange="e => SelectedFile.DraftName = e.Value.ToString()">
 | 
			
		||||
				<div class="control is-expanded borderRBig neoInput has-text-centered has-icons-left">
 | 
			
		||||
					<input class="input is-5 is-rounded is-small neoInput" type="text" placeholder="Search..."
 | 
			
		||||
								 disabled="@(SelectedFile.CanBeDeleted ? null : "disabled")" @bind-value="SelectedFile.Name">
 | 
			
		||||
					<span class="icon is-small is-left @(ConfigHasChanged ? "has-text-danger" : "has-text-dark")">
 | 
			
		||||
						<i class="mdi @(ConfigHasChanged ? "mdi-not-equal" : "mdi-equal")"></i>
 | 
			
		||||
					</span>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="control">
 | 
			
		||||
					<button class="button is-small is-rounded neoBtnSmall" @onclick="OnFileRenameClick">
 | 
			
		||||
						<span class="icon is-medium">
 | 
			
		||||
							<i class="mdi mdi-pencil-outline"></i>
 | 
			
		||||
						</span>
 | 
			
		||||
					</button>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="control">
 | 
			
		||||
					<button class="button is-small is-rounded neoBtnSmall" @onclick="OnFileCloseClick">
 | 
			
		||||
@@ -44,7 +52,7 @@
 | 
			
		||||
		<div class="filesList">
 | 
			
		||||
			@foreach (var file in Files)
 | 
			
		||||
			{
 | 
			
		||||
				<div @onclick="async e => await OnFileClick(e,file)" title="@(file.Folder=="/" ? $"{file.Folder}{file.Name}" : $"{file.Folder}/{file.Name}")" @key="file" class="confFile borderRSmall isFinger neoFile @file.IsVisible @file.IsSelected">
 | 
			
		||||
				<div @onclick="async e => await OnFileClick(e,file)" title="@(string.IsNullOrEmpty(file.Folder) ? $"/{file.Name}" : $"/{file.Folder}/{file.Name}")" @key="file" class="confFile borderRSmall isFinger neoFile @file.IsVisible @file.IsSelected">
 | 
			
		||||
					<p class="has-text-weight-bold ellipsis"><span class="icon @(file.CanBeDeleted ? null : "has-text-danger")"><i class="mdi mdi-file-cog-outline"></i></span> @file.Name</p>
 | 
			
		||||
				</div>
 | 
			
		||||
			}
 | 
			
		||||
@@ -61,7 +69,7 @@
 | 
			
		||||
 | 
			
		||||
	<div class="filesActions">
 | 
			
		||||
		<div class="buttons is-centered">
 | 
			
		||||
			<button class="button is-rounded neoBtnSmall is-small noBottomMargin" @onclick="async () => await OnAddDialog()">
 | 
			
		||||
			<button class="button is-rounded neoBtnSmall is-small noBottomMargin" @onclick="OnAddDialog">
 | 
			
		||||
				<span class="icon is-small has-text-success">
 | 
			
		||||
					<i class="mdi mdi-plus"></i>
 | 
			
		||||
				</span>
 | 
			
		||||
@@ -80,10 +88,13 @@
 | 
			
		||||
		@if (IsAnyFileSelected)
 | 
			
		||||
		{
 | 
			
		||||
			<div class="buttons is-centered">
 | 
			
		||||
				<button @onclick="OnSaveDraft" class="button is-rounded neoBtnSmall is-small has-icon-left noBottomMargin"><span class="icon is-left has-text-light"><i class="mdi mdi-content-save-outline"></i></span> <span>Save draft</span></button>
 | 
			
		||||
				<button @onclick="OnUndoChanges" class="button is-rounded neoBtnSmall is-small has-icon-left noBottomMargin"><span class="icon is-left has-text-dark"><i class="mdi mdi-undo-variant"></i></span> <span>Undo changes</span></button>
 | 
			
		||||
				@if (HasTesting)
 | 
			
		||||
				{
 | 
			
		||||
					<button @onclick="OnTest" class="button is-rounded neoBtnSmall is-small has-icon-left noBottomMargin"><span class="icon is-left has-text-danger"><i class="mdi mdi-alert-outline"></i></span> <span>Test</span></button>
 | 
			
		||||
				}
 | 
			
		||||
				<button @onclick="OnSaveDraft" class="button is-rounded neoBtnSmall is-small has-icon-left noBottomMargin"><span class="icon is-left has-text-light"><i class="mdi mdi-content-save-outline"></i></span> <span>@(string.IsNullOrEmpty(SelectedFile.DraftBody) ? "Create" : "Save") draft</span></button>
 | 
			
		||||
				<button @onclick="OnSave" class="button is-rounded neoBtnSmall is-small has-icon-left noBottomMargin"><span class="icon is-left has-text-success"><i class="mdi mdi-content-save-all-outline"></i></span> <span>Save</span></button>
 | 
			
		||||
				<button @onclick="OnTest" class="button is-rounded neoBtnSmall is-small has-icon-left noBottomMargin"><span class="icon is-left has-text-danger"><i class="mdi mdi-alert-outline"></i></span> <span>Test</span></button>
 | 
			
		||||
			</div>
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
 
 | 
			
		||||
@@ -22,13 +22,18 @@ namespace Seenginx.Components
 | 
			
		||||
 | 
			
		||||
		[Parameter] public RenderFragment<CFile> Editor { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
		[Parameter] public bool HasTesting { get; set; } = false;
 | 
			
		||||
		[Parameter] public EventCallback TestConfiguration { get; set; }
 | 
			
		||||
		[Parameter] public EventCallback ShowAddFileModal { get; set; }
 | 
			
		||||
		[Parameter] public EventCallback DeleteFileCallback { get; set; }
 | 
			
		||||
		[Parameter] public EventCallback RenameFileCallback { get; set; }
 | 
			
		||||
		[Parameter] public EventCallback SaveFileCallback { get; set; }
 | 
			
		||||
		[Parameter] public EventCallback SaveDraftFileCallback { get; set; }
 | 
			
		||||
		[Parameter] public EventCallback<CFile> SelectedFileChanged { get; set; }
 | 
			
		||||
		[Parameter] public CFile SelectedFile { get; set; } = default;
 | 
			
		||||
 | 
			
		||||
		protected string SearchInput { get; set; }
 | 
			
		||||
		private bool ConfigHasChanged => (string.IsNullOrEmpty(SelectedFile.DraftBody) ? false : SelectedFile.Body != SelectedFile.DraftBody);
 | 
			
		||||
 | 
			
		||||
		protected bool IsAnyFileSelected => SelectedFile != default;
 | 
			
		||||
		protected string IsSelectedFileDeletable
 | 
			
		||||
@@ -80,6 +85,11 @@ namespace Seenginx.Components
 | 
			
		||||
			await SelectedFileChanged.InvokeAsync(file);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected async Task OnFileRenameClick(MouseEventArgs e)
 | 
			
		||||
		{
 | 
			
		||||
			await RenameFileCallback.InvokeAsync(null);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected async Task OnFileCloseClick(MouseEventArgs e)
 | 
			
		||||
		{
 | 
			
		||||
			Files.ForEach(f => f.Deselect());
 | 
			
		||||
@@ -91,18 +101,19 @@ namespace Seenginx.Components
 | 
			
		||||
		{
 | 
			
		||||
			var draftCode = await JsRuntime.InvokeAsync<string>("GetEditorCode");
 | 
			
		||||
			SelectedFile.DraftBody = draftCode;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected async Task OnUndoChanges(MouseEventArgs e)
 | 
			
		||||
		{
 | 
			
		||||
			SelectedFile.DraftBody = SelectedFile.Body;
 | 
			
		||||
			await JsRuntime.InvokeVoidAsync("UpdateEditor", SelectedFile.Body);
 | 
			
		||||
			await SaveDraftFileCallback.InvokeAsync(null);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected async Task OnSave(MouseEventArgs e)
 | 
			
		||||
		{
 | 
			
		||||
			var draftCode = await JsRuntime.InvokeAsync<string>("GetEditorCode");
 | 
			
		||||
			SelectedFile.Body = draftCode;
 | 
			
		||||
			var currentCode = await JsRuntime.InvokeAsync<string>("GetEditorCode");
 | 
			
		||||
			SelectedFile.Body = currentCode;
 | 
			
		||||
			await SaveFileCallback.InvokeAsync(null);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected async Task OnUndoChanges(MouseEventArgs e)
 | 
			
		||||
		{
 | 
			
		||||
			await JsRuntime.InvokeVoidAsync("UpdateEditor", SelectedFile.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected async Task OnTest(MouseEventArgs e)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
@inherits NginxBase
 | 
			
		||||
@page "/nginx"
 | 
			
		||||
<FilesWithEditor CFile="ConfigFile" Files="ConfigFiles" SelectedFile="SelectedFile" SelectedFileChanged="SelectedFileChanged"
 | 
			
		||||
								 TestConfiguration="TestConfiguration" DeleteFileCallback="DeleteFile" ShowAddFileModal="ShowAddFileModal">
 | 
			
		||||
								 TestConfiguration="TestConfiguration" DeleteFileCallback="DeleteFile" ShowAddFileModal="ShowAddFileModal"
 | 
			
		||||
								 HasTesting="true" SaveFileCallback="SaveFileAsync" SaveDraftFileCallback="SaveDraftFileAsync">
 | 
			
		||||
</FilesWithEditor>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
using Blazored.Modal.Services;
 | 
			
		||||
using Blazorise;
 | 
			
		||||
using Microsoft.AspNetCore.Components;
 | 
			
		||||
using Microsoft.JSInterop;
 | 
			
		||||
using Seenginx.Models;
 | 
			
		||||
using Seenginx.Services;
 | 
			
		||||
using Seenginx.Shared;
 | 
			
		||||
@@ -23,24 +24,15 @@ namespace Seenginx.Pages
 | 
			
		||||
 | 
			
		||||
		public List<ConfigFile> ConfigFiles { get; set; } = new List<ConfigFile>();
 | 
			
		||||
		public ConfigFile SelectedFile { get; set; }
 | 
			
		||||
		public List<string> Filters { get; set; } = new List<string>();
 | 
			
		||||
		public List<int> FilteredOutFiles { get; set; } = new List<int>();
 | 
			
		||||
		public NotificationSettings GeneralNotificationSettings { get; set; } = null;
 | 
			
		||||
		public List<Template> Templates { get; set; } = new List<Template>();
 | 
			
		||||
 | 
			
		||||
		public Dictionary<string, string> FilterFolder { get; set; } = new Dictionary<string, string>();
 | 
			
		||||
 | 
			
		||||
		protected override async Task OnParametersSetAsync()
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				ConfigFiles.AddRange(await NginxService.GetFilesAsync());
 | 
			
		||||
				Filters.AddRange(new List<string> { "All", "Root", "Conf.d", "Available", "Enabled" });
 | 
			
		||||
				FilterFolder.Add("All", null);
 | 
			
		||||
				FilterFolder.Add("Root", "/");
 | 
			
		||||
				FilterFolder.Add("Conf.d", "/conf.d");
 | 
			
		||||
				FilterFolder.Add("Available", "/sites-available");
 | 
			
		||||
				FilterFolder.Add("Enabled", "/sites-enabled");
 | 
			
		||||
				Templates.AddRange(await NginxService.GetTemplates());
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception ex)
 | 
			
		||||
@@ -85,14 +77,14 @@ namespace Seenginx.Pages
 | 
			
		||||
			SelectedFile.Select();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task SaveUpdateDraftFileAsync()
 | 
			
		||||
		public async Task SaveFileAsync()
 | 
			
		||||
		{
 | 
			
		||||
			var saveUpdateDraftResult = await FileService.SaveUpdateDraftFileAsync(SelectedFile);
 | 
			
		||||
			var saveUpdateResult = await FileService.SaveFileAsync(SelectedFile);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task SaveUpdateFileAsync()
 | 
			
		||||
		public async Task SaveDraftFileAsync()
 | 
			
		||||
		{
 | 
			
		||||
			var saveUpdateResult = await FileService.SaveUpdateFileAsync(SelectedFile);
 | 
			
		||||
			var saveUpdateDraftResult = await FileService.SaveDraftFileAsync(SelectedFile);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task TestConfiguration()
 | 
			
		||||
@@ -108,7 +100,7 @@ namespace Seenginx.Pages
 | 
			
		||||
			var result = await resultAwait.Result;
 | 
			
		||||
			if ((PopupAnswer)result.Data == PopupAnswer.No) return;
 | 
			
		||||
 | 
			
		||||
			var deleteFileResult = await NginxService.DeleteConfigurationFileAsync(SelectedFile);
 | 
			
		||||
			var deleteFileResult = await NginxService.DeleteFileAsync(SelectedFile);
 | 
			
		||||
 | 
			
		||||
			if (!deleteFileResult.AllOk)
 | 
			
		||||
			{
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ namespace Seenginx.Services
 | 
			
		||||
{
 | 
			
		||||
	public class FileManager : IFileManager
 | 
			
		||||
	{
 | 
			
		||||
		public async Task<Result<ConfigFile>> SaveUpdateFileAsync(ConfigFile configFile)
 | 
			
		||||
		public async Task<Result<ConfigFile>> SaveFileAsync(ConfigFile configFile)
 | 
			
		||||
		{
 | 
			
		||||
			var result = new Result<ConfigFile>(configFile);
 | 
			
		||||
			try
 | 
			
		||||
@@ -24,11 +24,11 @@ namespace Seenginx.Services
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception ex)
 | 
			
		||||
			{
 | 
			
		||||
				return result.Invalidate($"Exception at {nameof(SaveUpdateFileAsync)}(), with {nameof(ConfigFile.Name)}=[{nameof(configFile.Name)}]", ex);
 | 
			
		||||
				return result.Invalidate($"Exception at {nameof(SaveFileAsync)}(), with {nameof(ConfigFile.Name)}=[{nameof(configFile.Name)}]", ex);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<Result<ConfigFile>> SaveUpdateDraftFileAsync(ConfigFile configFile)
 | 
			
		||||
		public async Task<Result<ConfigFile>> SaveDraftFileAsync(ConfigFile configFile)
 | 
			
		||||
		{
 | 
			
		||||
			var result = new Result<ConfigFile>(configFile);
 | 
			
		||||
			try
 | 
			
		||||
@@ -43,7 +43,7 @@ namespace Seenginx.Services
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception ex)
 | 
			
		||||
			{
 | 
			
		||||
				return result.Invalidate($"Exception at {nameof(SaveUpdateDraftFileAsync)}(), with {nameof(ConfigFile.Name)}=[{nameof(configFile.Name)}]", ex);
 | 
			
		||||
				return result.Invalidate($"Exception at {nameof(SaveDraftFileAsync)}(), with {nameof(ConfigFile.Name)}=[{nameof(configFile.Name)}]", ex);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,8 +8,8 @@ namespace Seenginx.Services
 | 
			
		||||
{
 | 
			
		||||
	public interface IFileManager
 | 
			
		||||
	{
 | 
			
		||||
		Task<Result<ConfigFile>> SaveUpdateFileAsync(ConfigFile configFile);
 | 
			
		||||
		Task<Result<ConfigFile>> SaveUpdateDraftFileAsync(ConfigFile configFile);
 | 
			
		||||
		Task<Result<ConfigFile>> SaveFileAsync(ConfigFile configFile);
 | 
			
		||||
		Task<Result<ConfigFile>> SaveDraftFileAsync(ConfigFile configFile);
 | 
			
		||||
		Result<bool> DeleteFile(ConfigFile configFile);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,10 +7,13 @@ namespace Seenginx.Services
 | 
			
		||||
	public interface INginxService
 | 
			
		||||
	{
 | 
			
		||||
		Task<IEnumerable<ConfigFile>> GetFilesAsync();
 | 
			
		||||
		Task<Result<string>> TestNginxConfigurations(ConfigFile configFile);
 | 
			
		||||
		Task<Result<ConfigFile>> AddFileAsync(NewFileForm newFileForm);
 | 
			
		||||
		Task<IEnumerable<Template>> GetTemplates();
 | 
			
		||||
		Task<Result<bool>> DeleteConfigurationFileAsync(ConfigFile configFile);
 | 
			
		||||
		Task<Result<string>> TestFileAsync(ConfigFile configFile);
 | 
			
		||||
		Task<Result<ConfigFile>> AddFileAsync(NewFileForm newFileForm);
 | 
			
		||||
		Task<Result<ConfigFile>> SaveFileAsync(ConfigFile configFile);
 | 
			
		||||
		Task<Result<ConfigFile>> SaveDraftFileAsync(ConfigFile configFile);
 | 
			
		||||
		Task<Result<bool>> RenameFileAsync(ConfigFile configFile);
 | 
			
		||||
		Task<Result<bool>> DeleteFileAsync(ConfigFile configFile);
 | 
			
		||||
		Task<Result<bool>> ValidateNewConfigurationAsync(NewFileForm newFileForm);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -36,20 +36,20 @@ namespace Seenginx.Services
 | 
			
		||||
			{
 | 
			
		||||
				return validationResult.Invalidate($"Exception at {nameof(ValidateNewConfigurationAsync)}()", ex);
 | 
			
		||||
			}
 | 
			
		||||
		} 
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<Result<ConfigFile>> AddFileAsync(NewFileForm newFileForm)
 | 
			
		||||
		{
 | 
			
		||||
			var addResult = new Result<ConfigFile>();
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
 | 
			
		||||
				var newFile = new ConfigFile();
 | 
			
		||||
				newFile.Name = $"{newFileForm.Name}.conf";
 | 
			
		||||
				newFile.Folder = "/conf.d";
 | 
			
		||||
				newFile.FullPath = Path.Combine(ConfigPaths.NginxPath, "conf.d", newFile.Name);
 | 
			
		||||
				newFile.Body = newFileForm.SelectedTemplate == 0.ToString() ? string.Empty : (await GetTemplates()).SingleOrDefault(t => t.Name == newFileForm.SelectedTemplate)?.Code;
 | 
			
		||||
				newFile.LastUpdated = DateTime.UtcNow;
 | 
			
		||||
				newFile.DraftBody = newFile.Body;
 | 
			
		||||
 | 
			
		||||
				await File.WriteAllTextAsync(newFile.FullPath, newFile.Body, Encoding.UTF8);
 | 
			
		||||
 | 
			
		||||
@@ -63,24 +63,92 @@ namespace Seenginx.Services
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<Result<bool>> DeleteFileAsync(ConfigFile configFile)
 | 
			
		||||
		{
 | 
			
		||||
			var result = new Result<bool>(true);
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				if (!File.Exists(configFile.FullPath))
 | 
			
		||||
					return result.Invalidate($"File '{configFile.FullPath}' not found.");
 | 
			
		||||
 | 
			
		||||
				File.Delete(configFile.FullPath);
 | 
			
		||||
 | 
			
		||||
				return result;
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception ex)
 | 
			
		||||
			{
 | 
			
		||||
				return result.Invalidate(ex.Message, ex);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<Result<string>> TestFileAsync(ConfigFile configFile)
 | 
			
		||||
		{
 | 
			
		||||
			await Task.Run(() => { });
 | 
			
		||||
			var result = new Result<string>();
 | 
			
		||||
			result.SetData("Uhu");
 | 
			
		||||
			return result;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<Result<ConfigFile>> SaveFileAsync(ConfigFile configFile)
 | 
			
		||||
		{
 | 
			
		||||
			var saveResult = new Result<ConfigFile>();
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				await File.WriteAllTextAsync(Path.Combine(ConfigPaths.NginxPath, configFile.Folder, configFile.Name), configFile.Body, Encoding.UTF8);
 | 
			
		||||
 | 
			
		||||
				return saveResult;
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception ex)
 | 
			
		||||
			{
 | 
			
		||||
				return saveResult.Invalidate(ex.Message, ex);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<Result<ConfigFile>> SaveDraftFileAsync(ConfigFile configFile)
 | 
			
		||||
		{
 | 
			
		||||
			var saveDraftResult = new Result<ConfigFile>();
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				await File.WriteAllTextAsync(Path.Combine(ConfigPaths.NginxPath, configFile.Folder, $"{configFile.Name}.draft"), configFile.DraftBody, Encoding.UTF8);
 | 
			
		||||
 | 
			
		||||
				return saveDraftResult;
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception ex)
 | 
			
		||||
			{
 | 
			
		||||
				return saveDraftResult.Invalidate(ex.Message, ex);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<Result<bool>> RenameFileAsync(ConfigFile configFile, string newName)
 | 
			
		||||
		{
 | 
			
		||||
			File.Move()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<IEnumerable<ConfigFile>> GetFilesAsync()
 | 
			
		||||
		{
 | 
			
		||||
			await Task.Run(() => { });
 | 
			
		||||
			var rootConfigs = Directory.GetFiles(ConfigPaths.NginxPath, "*.conf");
 | 
			
		||||
			var rootDraftConfigs = Directory.GetFiles(ConfigPaths.NginxPath, "*.conf.draft");
 | 
			
		||||
 | 
			
		||||
			var confdConfigs = Directory.GetFiles(Path.Combine(ConfigPaths.NginxPath, "conf.d"), "*.conf");
 | 
			
		||||
			var confDraftConfigs = Directory.GetFiles(Path.Combine(ConfigPaths.NginxPath, "conf.d"), "*.conf.draft");
 | 
			
		||||
 | 
			
		||||
			var sitesAvailableConfigs = Directory.GetFiles(Path.Combine(ConfigPaths.NginxPath, "sites-available"), "*.conf");
 | 
			
		||||
			var sitesEnabledConfigs = Directory.GetFiles(Path.Combine(ConfigPaths.NginxPath, "sites-enabled"), "*.conf");
 | 
			
		||||
			var sitesAvailableDraftConfigs = Directory.GetFiles(Path.Combine(ConfigPaths.NginxPath, "sites-available"), "*.conf.draft");
 | 
			
		||||
 | 
			
		||||
			var rootConfigFiles = rootConfigs.Select(fp =>
 | 
			
		||||
			{
 | 
			
		||||
				var fileName = Path.GetFileName(fp);
 | 
			
		||||
				var configFile = new ConfigFile();
 | 
			
		||||
				configFile.CanBeDeleted = fileName != "nginx.conf";
 | 
			
		||||
				configFile.Folder = "/";
 | 
			
		||||
				configFile.CanBeDeleted = false;
 | 
			
		||||
				configFile.Folder = string.Empty;
 | 
			
		||||
				configFile.LastUpdated = File.GetLastWriteTime(fp);
 | 
			
		||||
				configFile.Name = fileName;
 | 
			
		||||
				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Name);
 | 
			
		||||
				configFile.Body = File.ReadAllText(fp);
 | 
			
		||||
				if (rootDraftConfigs.Any(cfp => cfp.Contains(fileName)))
 | 
			
		||||
					configFile.DraftBody = File.ReadAllText(rootDraftConfigs.First(cfp => cfp.Contains(fileName)));
 | 
			
		||||
 | 
			
		||||
				return configFile;
 | 
			
		||||
			});
 | 
			
		||||
			var confdConfigFiles = confdConfigs.Select(fp =>
 | 
			
		||||
@@ -88,11 +156,14 @@ namespace Seenginx.Services
 | 
			
		||||
				var fileName = Path.GetFileName(fp);
 | 
			
		||||
				var configFile = new ConfigFile();
 | 
			
		||||
				configFile.CanBeDeleted = true;
 | 
			
		||||
				configFile.Folder = "/conf.d";
 | 
			
		||||
				configFile.Folder = "conf.d";
 | 
			
		||||
				configFile.LastUpdated = File.GetLastWriteTime(fp);
 | 
			
		||||
				configFile.Name = fileName;
 | 
			
		||||
				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder.Replace("/", string.Empty), configFile.Name);
 | 
			
		||||
				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder, configFile.Name);
 | 
			
		||||
				configFile.Body = File.ReadAllText(fp);
 | 
			
		||||
				if (confDraftConfigs.Any(cfp => cfp.Contains(fileName)))
 | 
			
		||||
					configFile.DraftBody = File.ReadAllText(confDraftConfigs.First(cfp => cfp.Contains(fileName)));
 | 
			
		||||
 | 
			
		||||
				return configFile;
 | 
			
		||||
			});
 | 
			
		||||
			var sitesAvailableConfigFiles = sitesAvailableConfigs.Select(fp =>
 | 
			
		||||
@@ -100,30 +171,42 @@ namespace Seenginx.Services
 | 
			
		||||
				var fileName = Path.GetFileName(fp);
 | 
			
		||||
				var configFile = new ConfigFile();
 | 
			
		||||
				configFile.CanBeDeleted = true;
 | 
			
		||||
				configFile.Folder = "/sites-available";
 | 
			
		||||
				configFile.Folder = "sites-available";
 | 
			
		||||
				configFile.LastUpdated = File.GetLastWriteTime(fp);
 | 
			
		||||
				configFile.Name = fileName;
 | 
			
		||||
				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder.Replace("/", string.Empty), configFile.Name);
 | 
			
		||||
				configFile.Body = File.ReadAllText(fp);
 | 
			
		||||
				return configFile;
 | 
			
		||||
			});
 | 
			
		||||
			var sitesEnabledConfigFiles = sitesEnabledConfigs.Select(fp =>
 | 
			
		||||
			{
 | 
			
		||||
				var fileName = Path.GetFileName(fp);
 | 
			
		||||
				var configFile = new ConfigFile();
 | 
			
		||||
				configFile.CanBeDeleted = true;
 | 
			
		||||
				configFile.Folder = "/sites-enabled";
 | 
			
		||||
				configFile.LastUpdated = File.GetLastWriteTime(fp);
 | 
			
		||||
				configFile.Name = fileName;
 | 
			
		||||
				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder.Replace("/", string.Empty), configFile.Name);
 | 
			
		||||
				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder, configFile.Name);
 | 
			
		||||
				configFile.Body = File.ReadAllText(fp);
 | 
			
		||||
				if (sitesAvailableDraftConfigs.Any(cfp => cfp.Contains(fileName)))
 | 
			
		||||
					configFile.DraftBody = File.ReadAllText(sitesAvailableDraftConfigs.First(cfp => cfp.Contains(fileName)));
 | 
			
		||||
 | 
			
		||||
				return configFile;
 | 
			
		||||
			});
 | 
			
		||||
			//var sitesEnabledConfigFiles = sitesEnabledConfigs.Select(fp =>
 | 
			
		||||
			//{
 | 
			
		||||
			//	var fileName = Path.GetFileName(fp);
 | 
			
		||||
			//	var configFile = new ConfigFile();
 | 
			
		||||
			//	configFile.CanBeDeleted = true;
 | 
			
		||||
			//	configFile.Folder = "/sites-enabled";
 | 
			
		||||
			//	configFile.LastUpdated = File.GetLastWriteTime(fp);
 | 
			
		||||
			//	configFile.Name = fileName;
 | 
			
		||||
			//	configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder.Replace("/", string.Empty), configFile.Name);
 | 
			
		||||
			//	configFile.Body = File.ReadAllText(fp);
 | 
			
		||||
			//	configFile.DraftName = fileName;
 | 
			
		||||
			//	configFile.DraftBody = configFile.Body;
 | 
			
		||||
			//	if (confDraftConfigs.Any(cfp => cfp.Contains(fileName)))
 | 
			
		||||
			//	{
 | 
			
		||||
			//		configFile.DraftName = Path.GetFileName(confDraftConfigs.First(cfp => cfp.Contains(fileName)));
 | 
			
		||||
			//		configFile.DraftBody = File.ReadAllText(confDraftConfigs.First(cfp => cfp.Contains(fileName)));
 | 
			
		||||
			//	}
 | 
			
		||||
			//	return configFile;
 | 
			
		||||
			//});
 | 
			
		||||
			var finalList = new List<ConfigFile>();
 | 
			
		||||
			finalList.AddRange(rootConfigFiles);
 | 
			
		||||
			finalList.AddRange(confdConfigFiles);
 | 
			
		||||
			finalList.AddRange(sitesAvailableConfigFiles);
 | 
			
		||||
			finalList.AddRange(sitesEnabledConfigFiles);
 | 
			
		||||
			//finalList.AddRange(sitesEnabledConfigFiles);
 | 
			
		||||
 | 
			
		||||
			finalList = finalList.OrderBy(cf => cf.Name).ToList();
 | 
			
		||||
 | 
			
		||||
			return finalList;
 | 
			
		||||
		}
 | 
			
		||||
@@ -153,31 +236,6 @@ namespace Seenginx.Services
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<Result<string>> TestNginxConfigurations(ConfigFile configFile)
 | 
			
		||||
		{
 | 
			
		||||
			await Task.Run(() => { });
 | 
			
		||||
			var result = new Result<string>();
 | 
			
		||||
			result.SetData("Uhu");
 | 
			
		||||
			return result;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<Result<bool>> DeleteConfigurationFileAsync(ConfigFile configFile)
 | 
			
		||||
		{
 | 
			
		||||
			var result = new Result<bool>(true);
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				if (!File.Exists(configFile.FullPath))
 | 
			
		||||
					return result.Invalidate($"File '{configFile.FullPath}' not found.");
 | 
			
		||||
 | 
			
		||||
				File.Delete(configFile.FullPath);
 | 
			
		||||
 | 
			
		||||
				return result;
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception ex)
 | 
			
		||||
			{
 | 
			
		||||
				return result.Invalidate(ex.Message, ex);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,9 @@ window.InitEditor = () => {
 | 
			
		||||
		enableLiveAutocompletion: true,
 | 
			
		||||
		//enableSnippets: true
 | 
			
		||||
	})
 | 
			
		||||
	window.editor.session.on('change', function (delta) {
 | 
			
		||||
		// delta.start, delta.end, delta.lines, delta.action
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
window.GetEditorCode = () => {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user