Many updates
This commit is contained in:
		| @@ -7,7 +7,6 @@ namespace Seenginx.Models | |||||||
| 		public string FullPath { get; set; } | 		public string FullPath { get; set; } | ||||||
| 		public string Folder { get; set; } | 		public string Folder { get; set; } | ||||||
| 		public string Name { get; set; } | 		public string Name { get; set; } | ||||||
| 		public string DraftName { get; set; } |  | ||||||
| 		public string Body { get; set; } | 		public string Body { get; set; } | ||||||
| 		public string DraftBody { get; set; } | 		public string DraftBody { get; set; } | ||||||
| 		public string Permissions { get; set; } | 		public string Permissions { get; set; } | ||||||
| @@ -15,7 +14,7 @@ namespace Seenginx.Models | |||||||
| 		public string[] Owners { get; set; } | 		public string[] Owners { get; set; } | ||||||
| 		public string IsVisible { get; set; } = string.Empty; | 		public string IsVisible { get; set; } = string.Empty; | ||||||
| 		public string IsSelected { 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 bool CanBeDeleted { get; set; } = true; | ||||||
|  |  | ||||||
| 		public void Hide() { IsVisible = "is-hidden"; } | 		public void Hide() { IsVisible = "is-hidden"; } | ||||||
|   | |||||||
| @@ -17,11 +17,19 @@ | |||||||
| 		@if (IsAnyFileSelected) | 		@if (IsAnyFileSelected) | ||||||
| 		{ | 		{ | ||||||
| 			<div class="field is-grouped"> | 			<div class="field is-grouped"> | ||||||
| 				<div class="control is-expanded borderRBig neoInput has-text-centered"> | 				<div class="control is-expanded borderRBig neoInput has-text-centered has-icons-left"> | ||||||
| 					<input class="input is-5 is-rounded is-small neoInput" | 					<input class="input is-5 is-rounded is-small neoInput" type="text" placeholder="Search..." | ||||||
| 								 type="text" placeholder="Search..." | 								 disabled="@(SelectedFile.CanBeDeleted ? null : "disabled")" @bind-value="SelectedFile.Name"> | ||||||
| 								 value="@SelectedFile.Name" disabled="@(SelectedFile.CanBeDeleted ? null : "disabled")" | 					<span class="icon is-small is-left @(ConfigHasChanged ? "has-text-danger" : "has-text-dark")"> | ||||||
| 								 @onchange="e => SelectedFile.DraftName = e.Value.ToString()"> | 						<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> | ||||||
| 				<div class="control"> | 				<div class="control"> | ||||||
| 					<button class="button is-small is-rounded neoBtnSmall" @onclick="OnFileCloseClick"> | 					<button class="button is-small is-rounded neoBtnSmall" @onclick="OnFileCloseClick"> | ||||||
| @@ -44,7 +52,7 @@ | |||||||
| 		<div class="filesList"> | 		<div class="filesList"> | ||||||
| 			@foreach (var file in Files) | 			@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> | 					<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> | 				</div> | ||||||
| 			} | 			} | ||||||
| @@ -61,7 +69,7 @@ | |||||||
|  |  | ||||||
| 	<div class="filesActions"> | 	<div class="filesActions"> | ||||||
| 		<div class="buttons is-centered"> | 		<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"> | 				<span class="icon is-small has-text-success"> | ||||||
| 					<i class="mdi mdi-plus"></i> | 					<i class="mdi mdi-plus"></i> | ||||||
| 				</span> | 				</span> | ||||||
| @@ -80,10 +88,13 @@ | |||||||
| 		@if (IsAnyFileSelected) | 		@if (IsAnyFileSelected) | ||||||
| 		{ | 		{ | ||||||
| 			<div class="buttons is-centered"> | 			<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> | 				<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> | ||||||
| 				<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> | 				@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="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> | ||||||
| 			</div> | 			</div> | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
|   | |||||||
| @@ -22,13 +22,18 @@ namespace Seenginx.Components | |||||||
|  |  | ||||||
| 		[Parameter] public RenderFragment<CFile> Editor { get; set; } = null; | 		[Parameter] public RenderFragment<CFile> Editor { get; set; } = null; | ||||||
|  |  | ||||||
|  | 		[Parameter] public bool HasTesting { get; set; } = false; | ||||||
| 		[Parameter] public EventCallback TestConfiguration { get; set; } | 		[Parameter] public EventCallback TestConfiguration { get; set; } | ||||||
| 		[Parameter] public EventCallback ShowAddFileModal { get; set; } | 		[Parameter] public EventCallback ShowAddFileModal { get; set; } | ||||||
| 		[Parameter] public EventCallback DeleteFileCallback { 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 EventCallback<CFile> SelectedFileChanged { get; set; } | ||||||
| 		[Parameter] public CFile SelectedFile { get; set; } = default; | 		[Parameter] public CFile SelectedFile { get; set; } = default; | ||||||
|  |  | ||||||
| 		protected string SearchInput { get; set; } | 		protected string SearchInput { get; set; } | ||||||
|  | 		private bool ConfigHasChanged => (string.IsNullOrEmpty(SelectedFile.DraftBody) ? false : SelectedFile.Body != SelectedFile.DraftBody); | ||||||
|  |  | ||||||
| 		protected bool IsAnyFileSelected => SelectedFile != default; | 		protected bool IsAnyFileSelected => SelectedFile != default; | ||||||
| 		protected string IsSelectedFileDeletable | 		protected string IsSelectedFileDeletable | ||||||
| @@ -80,6 +85,11 @@ namespace Seenginx.Components | |||||||
| 			await SelectedFileChanged.InvokeAsync(file); | 			await SelectedFileChanged.InvokeAsync(file); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		protected async Task OnFileRenameClick(MouseEventArgs e) | ||||||
|  | 		{ | ||||||
|  | 			await RenameFileCallback.InvokeAsync(null); | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		protected async Task OnFileCloseClick(MouseEventArgs e) | 		protected async Task OnFileCloseClick(MouseEventArgs e) | ||||||
| 		{ | 		{ | ||||||
| 			Files.ForEach(f => f.Deselect()); | 			Files.ForEach(f => f.Deselect()); | ||||||
| @@ -91,18 +101,19 @@ namespace Seenginx.Components | |||||||
| 		{ | 		{ | ||||||
| 			var draftCode = await JsRuntime.InvokeAsync<string>("GetEditorCode"); | 			var draftCode = await JsRuntime.InvokeAsync<string>("GetEditorCode"); | ||||||
| 			SelectedFile.DraftBody = draftCode; | 			SelectedFile.DraftBody = draftCode; | ||||||
| 		} | 			await SaveDraftFileCallback.InvokeAsync(null); | ||||||
|  |  | ||||||
| 		protected async Task OnUndoChanges(MouseEventArgs e) |  | ||||||
| 		{ |  | ||||||
| 			SelectedFile.DraftBody = SelectedFile.Body; |  | ||||||
| 			await JsRuntime.InvokeVoidAsync("UpdateEditor", SelectedFile.Body); |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		protected async Task OnSave(MouseEventArgs e) | 		protected async Task OnSave(MouseEventArgs e) | ||||||
| 		{ | 		{ | ||||||
| 			var draftCode = await JsRuntime.InvokeAsync<string>("GetEditorCode"); | 			var currentCode = await JsRuntime.InvokeAsync<string>("GetEditorCode"); | ||||||
| 			SelectedFile.Body = draftCode; | 			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) | 		protected async Task OnTest(MouseEventArgs e) | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| @inherits NginxBase | @inherits NginxBase | ||||||
| @page "/nginx" | @page "/nginx" | ||||||
| <FilesWithEditor CFile="ConfigFile" Files="ConfigFiles" SelectedFile="SelectedFile" SelectedFileChanged="SelectedFileChanged" | <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> | </FilesWithEditor> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
| using Blazored.Modal.Services; | using Blazored.Modal.Services; | ||||||
| using Blazorise; | using Blazorise; | ||||||
| using Microsoft.AspNetCore.Components; | using Microsoft.AspNetCore.Components; | ||||||
|  | using Microsoft.JSInterop; | ||||||
| using Seenginx.Models; | using Seenginx.Models; | ||||||
| using Seenginx.Services; | using Seenginx.Services; | ||||||
| using Seenginx.Shared; | using Seenginx.Shared; | ||||||
| @@ -23,24 +24,15 @@ namespace Seenginx.Pages | |||||||
|  |  | ||||||
| 		public List<ConfigFile> ConfigFiles { get; set; } = new List<ConfigFile>(); | 		public List<ConfigFile> ConfigFiles { get; set; } = new List<ConfigFile>(); | ||||||
| 		public ConfigFile SelectedFile { get; set; } | 		public ConfigFile SelectedFile { get; set; } | ||||||
| 		public List<string> Filters { get; set; } = new List<string>(); |  | ||||||
| 		public List<int> FilteredOutFiles { get; set; } = new List<int>(); | 		public List<int> FilteredOutFiles { get; set; } = new List<int>(); | ||||||
| 		public NotificationSettings GeneralNotificationSettings { get; set; } = null; | 		public NotificationSettings GeneralNotificationSettings { get; set; } = null; | ||||||
| 		public List<Template> Templates { get; set; } = new List<Template>(); | 		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() | 		protected override async Task OnParametersSetAsync() | ||||||
| 		{ | 		{ | ||||||
| 			try | 			try | ||||||
| 			{ | 			{ | ||||||
| 				ConfigFiles.AddRange(await NginxService.GetFilesAsync()); | 				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()); | 				Templates.AddRange(await NginxService.GetTemplates()); | ||||||
| 			} | 			} | ||||||
| 			catch (Exception ex) | 			catch (Exception ex) | ||||||
| @@ -85,14 +77,14 @@ namespace Seenginx.Pages | |||||||
| 			SelectedFile.Select(); | 			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() | 		public async Task TestConfiguration() | ||||||
| @@ -108,7 +100,7 @@ namespace Seenginx.Pages | |||||||
| 			var result = await resultAwait.Result; | 			var result = await resultAwait.Result; | ||||||
| 			if ((PopupAnswer)result.Data == PopupAnswer.No) return; | 			if ((PopupAnswer)result.Data == PopupAnswer.No) return; | ||||||
|  |  | ||||||
| 			var deleteFileResult = await NginxService.DeleteConfigurationFileAsync(SelectedFile); | 			var deleteFileResult = await NginxService.DeleteFileAsync(SelectedFile); | ||||||
|  |  | ||||||
| 			if (!deleteFileResult.AllOk) | 			if (!deleteFileResult.AllOk) | ||||||
| 			{ | 			{ | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ namespace Seenginx.Services | |||||||
| { | { | ||||||
| 	public class FileManager : IFileManager | 	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); | 			var result = new Result<ConfigFile>(configFile); | ||||||
| 			try | 			try | ||||||
| @@ -24,11 +24,11 @@ namespace Seenginx.Services | |||||||
| 			} | 			} | ||||||
| 			catch (Exception ex) | 			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); | 			var result = new Result<ConfigFile>(configFile); | ||||||
| 			try | 			try | ||||||
| @@ -43,7 +43,7 @@ namespace Seenginx.Services | |||||||
| 			} | 			} | ||||||
| 			catch (Exception ex) | 			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 | 	public interface IFileManager | ||||||
| 	{ | 	{ | ||||||
| 		Task<Result<ConfigFile>> SaveUpdateFileAsync(ConfigFile configFile); | 		Task<Result<ConfigFile>> SaveFileAsync(ConfigFile configFile); | ||||||
| 		Task<Result<ConfigFile>> SaveUpdateDraftFileAsync(ConfigFile configFile); | 		Task<Result<ConfigFile>> SaveDraftFileAsync(ConfigFile configFile); | ||||||
| 		Result<bool> DeleteFile(ConfigFile configFile); | 		Result<bool> DeleteFile(ConfigFile configFile); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,10 +7,13 @@ namespace Seenginx.Services | |||||||
| 	public interface INginxService | 	public interface INginxService | ||||||
| 	{ | 	{ | ||||||
| 		Task<IEnumerable<ConfigFile>> GetFilesAsync(); | 		Task<IEnumerable<ConfigFile>> GetFilesAsync(); | ||||||
| 		Task<Result<string>> TestNginxConfigurations(ConfigFile configFile); |  | ||||||
| 		Task<Result<ConfigFile>> AddFileAsync(NewFileForm newFileForm); |  | ||||||
| 		Task<IEnumerable<Template>> GetTemplates(); | 		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); | 		Task<Result<bool>> ValidateNewConfigurationAsync(NewFileForm newFileForm); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -43,13 +43,13 @@ namespace Seenginx.Services | |||||||
| 			var addResult = new Result<ConfigFile>(); | 			var addResult = new Result<ConfigFile>(); | ||||||
| 			try | 			try | ||||||
| 			{ | 			{ | ||||||
|  |  | ||||||
| 				var newFile = new ConfigFile(); | 				var newFile = new ConfigFile(); | ||||||
| 				newFile.Name = $"{newFileForm.Name}.conf"; | 				newFile.Name = $"{newFileForm.Name}.conf"; | ||||||
| 				newFile.Folder = "/conf.d"; | 				newFile.Folder = "/conf.d"; | ||||||
| 				newFile.FullPath = Path.Combine(ConfigPaths.NginxPath, "conf.d", newFile.Name); | 				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.Body = newFileForm.SelectedTemplate == 0.ToString() ? string.Empty : (await GetTemplates()).SingleOrDefault(t => t.Name == newFileForm.SelectedTemplate)?.Code; | ||||||
| 				newFile.LastUpdated = DateTime.UtcNow; | 				newFile.LastUpdated = DateTime.UtcNow; | ||||||
|  | 				newFile.DraftBody = newFile.Body; | ||||||
|  |  | ||||||
| 				await File.WriteAllTextAsync(newFile.FullPath, newFile.Body, Encoding.UTF8); | 				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() | 		public async Task<IEnumerable<ConfigFile>> GetFilesAsync() | ||||||
| 		{ | 		{ | ||||||
| 			await Task.Run(() => { }); | 			await Task.Run(() => { }); | ||||||
| 			var rootConfigs = Directory.GetFiles(ConfigPaths.NginxPath, "*.conf"); | 			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 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 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 rootConfigFiles = rootConfigs.Select(fp => | ||||||
| 			{ | 			{ | ||||||
| 				var fileName = Path.GetFileName(fp); | 				var fileName = Path.GetFileName(fp); | ||||||
| 				var configFile = new ConfigFile(); | 				var configFile = new ConfigFile(); | ||||||
| 				configFile.CanBeDeleted = fileName != "nginx.conf"; | 				configFile.CanBeDeleted = false; | ||||||
| 				configFile.Folder = "/"; | 				configFile.Folder = string.Empty; | ||||||
| 				configFile.LastUpdated = File.GetLastWriteTime(fp); | 				configFile.LastUpdated = File.GetLastWriteTime(fp); | ||||||
| 				configFile.Name = fileName; | 				configFile.Name = fileName; | ||||||
| 				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Name); | 				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Name); | ||||||
| 				configFile.Body = File.ReadAllText(fp); | 				configFile.Body = File.ReadAllText(fp); | ||||||
|  | 				if (rootDraftConfigs.Any(cfp => cfp.Contains(fileName))) | ||||||
|  | 					configFile.DraftBody = File.ReadAllText(rootDraftConfigs.First(cfp => cfp.Contains(fileName))); | ||||||
|  |  | ||||||
| 				return configFile; | 				return configFile; | ||||||
| 			}); | 			}); | ||||||
| 			var confdConfigFiles = confdConfigs.Select(fp => | 			var confdConfigFiles = confdConfigs.Select(fp => | ||||||
| @@ -88,11 +156,14 @@ namespace Seenginx.Services | |||||||
| 				var fileName = Path.GetFileName(fp); | 				var fileName = Path.GetFileName(fp); | ||||||
| 				var configFile = new ConfigFile(); | 				var configFile = new ConfigFile(); | ||||||
| 				configFile.CanBeDeleted = true; | 				configFile.CanBeDeleted = true; | ||||||
| 				configFile.Folder = "/conf.d"; | 				configFile.Folder = "conf.d"; | ||||||
| 				configFile.LastUpdated = File.GetLastWriteTime(fp); | 				configFile.LastUpdated = File.GetLastWriteTime(fp); | ||||||
| 				configFile.Name = fileName; | 				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); | 				configFile.Body = File.ReadAllText(fp); | ||||||
|  | 				if (confDraftConfigs.Any(cfp => cfp.Contains(fileName))) | ||||||
|  | 					configFile.DraftBody = File.ReadAllText(confDraftConfigs.First(cfp => cfp.Contains(fileName))); | ||||||
|  |  | ||||||
| 				return configFile; | 				return configFile; | ||||||
| 			}); | 			}); | ||||||
| 			var sitesAvailableConfigFiles = sitesAvailableConfigs.Select(fp => | 			var sitesAvailableConfigFiles = sitesAvailableConfigs.Select(fp => | ||||||
| @@ -100,30 +171,42 @@ namespace Seenginx.Services | |||||||
| 				var fileName = Path.GetFileName(fp); | 				var fileName = Path.GetFileName(fp); | ||||||
| 				var configFile = new ConfigFile(); | 				var configFile = new ConfigFile(); | ||||||
| 				configFile.CanBeDeleted = true; | 				configFile.CanBeDeleted = true; | ||||||
| 				configFile.Folder = "/sites-available"; | 				configFile.Folder = "sites-available"; | ||||||
| 				configFile.LastUpdated = File.GetLastWriteTime(fp); | 				configFile.LastUpdated = File.GetLastWriteTime(fp); | ||||||
| 				configFile.Name = fileName; | 				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); |  | ||||||
| 				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.Body = File.ReadAllText(fp); | ||||||
|  | 				if (sitesAvailableDraftConfigs.Any(cfp => cfp.Contains(fileName))) | ||||||
|  | 					configFile.DraftBody = File.ReadAllText(sitesAvailableDraftConfigs.First(cfp => cfp.Contains(fileName))); | ||||||
|  |  | ||||||
| 				return configFile; | 				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>(); | 			var finalList = new List<ConfigFile>(); | ||||||
| 			finalList.AddRange(rootConfigFiles); | 			finalList.AddRange(rootConfigFiles); | ||||||
| 			finalList.AddRange(confdConfigFiles); | 			finalList.AddRange(confdConfigFiles); | ||||||
| 			finalList.AddRange(sitesAvailableConfigFiles); | 			finalList.AddRange(sitesAvailableConfigFiles); | ||||||
| 			finalList.AddRange(sitesEnabledConfigFiles); | 			//finalList.AddRange(sitesEnabledConfigFiles); | ||||||
|  |  | ||||||
|  | 			finalList = finalList.OrderBy(cf => cf.Name).ToList(); | ||||||
|  |  | ||||||
| 			return finalList; | 			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, | 		enableLiveAutocompletion: true, | ||||||
| 		//enableSnippets: true | 		//enableSnippets: true | ||||||
| 	}) | 	}) | ||||||
|  | 	window.editor.session.on('change', function (delta) { | ||||||
|  | 		// delta.start, delta.end, delta.lines, delta.action | ||||||
|  | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
| window.GetEditorCode = () => { | window.GetEditorCode = () => { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user