updating nginx add and delete
This commit is contained in:
		@@ -6,6 +6,5 @@ namespace Seenginx.Models
 | 
			
		||||
	{
 | 
			
		||||
		public string Name { get; set; }
 | 
			
		||||
		public string SelectedTemplate { get; set; } = "0";
 | 
			
		||||
		public List<Template> Templates { get; set; } = new List<Template>();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,16 +7,12 @@ namespace Seenginx.Components
 | 
			
		||||
{
 | 
			
		||||
	public class FileItemBase : ComponentBase
 | 
			
		||||
	{
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public ConfigFile File { get; set; }
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public EventCallback<ConfigFile> SelectedFileChanged { get; set; }
 | 
			
		||||
		[Parameter] public ConfigFile File { get; set; }
 | 
			
		||||
		[Parameter] public EventCallback<ConfigFile> SelectedFileChanged { get; set; }
 | 
			
		||||
 | 
			
		||||
		public async Task SelectFile(MouseEventArgs e)
 | 
			
		||||
		{
 | 
			
		||||
			await SelectedFileChanged.InvokeAsync(File);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,17 +5,17 @@
 | 
			
		||||
	<div class="filterFiles">
 | 
			
		||||
		<div class="field has-addons">
 | 
			
		||||
			<div class="control has-icons-left is-expanded">
 | 
			
		||||
				<input formnovalidate @oninput="e => SearchInputChanged(e.Value.ToString())" class="input is-rounded is-small neoInput" type="text" placeholder="Search...">
 | 
			
		||||
				<input formnovalidate @oninput="e => SearchInputChanged(e.Value.ToString())" @bind-value="SearchInput" class="input is-rounded is-small neoInput" type="text" placeholder="Search...">
 | 
			
		||||
				<span class="icon is-small is-left has-text-dark">
 | 
			
		||||
					<i class="mdi mdi-search-web"></i>
 | 
			
		||||
				</span>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div class="control has-icons-left">
 | 
			
		||||
				<div class="select is-small is-rounded neoSelect">
 | 
			
		||||
					<select @onchange="e => OnFilterClick(e.Value.ToString())">
 | 
			
		||||
					<select @oninput="e => OnFilterClick(e.Value.ToString())" @bind="SelectedFilter">
 | 
			
		||||
						@foreach (var filter in Filters)
 | 
			
		||||
						{
 | 
			
		||||
							<option value="@filter">@filter</option>
 | 
			
		||||
							<option value="@filter" selected="@(SelectedFilter == filter ? "selected" : null)">@filter</option>
 | 
			
		||||
						}
 | 
			
		||||
					</select>
 | 
			
		||||
				</div>
 | 
			
		||||
@@ -75,7 +75,7 @@
 | 
			
		||||
 | 
			
		||||
	<div class="filesActions">
 | 
			
		||||
		<div class="buttons is-centered">
 | 
			
		||||
			<button class="button is-rounded neoBtnSmall is-small noBottomMargin" @onclick="OnAddDialog">
 | 
			
		||||
			<button class="button is-rounded neoBtnSmall is-small noBottomMargin" @onclick="async () => await OnAddDialog()">
 | 
			
		||||
				<span class="icon is-small has-text-success">
 | 
			
		||||
					<i class="mdi mdi-plus"></i>
 | 
			
		||||
				</span>
 | 
			
		||||
 
 | 
			
		||||
@@ -14,22 +14,23 @@ namespace Seenginx.Components
 | 
			
		||||
	public partial class FilesWithEditor<CFile> : ComponentBase
 | 
			
		||||
		where CFile : ConfigFile
 | 
			
		||||
	{
 | 
			
		||||
		[Inject]
 | 
			
		||||
		public IJSRuntime JsRuntime { get; set; }
 | 
			
		||||
		[Inject] public IJSRuntime JsRuntime { get; set; }
 | 
			
		||||
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public List<CFile> Files { get; set; } = new List<CFile>();
 | 
			
		||||
		[Parameter] public List<CFile> Files { get; set; } = new List<CFile>();
 | 
			
		||||
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public List<string> Filters { get; set; } = new List<string>();
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public Dictionary<string, string> FilterFolder { get; set; } = new Dictionary<string, string>();
 | 
			
		||||
		[Parameter] public List<string> Filters { get; set; } = new List<string>();
 | 
			
		||||
		[Parameter] public Dictionary<string, string> FilterFolder { get; set; } = new Dictionary<string, string>();
 | 
			
		||||
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public EventCallback<CFile> UpdateFile { get; set; }
 | 
			
		||||
		[Parameter] public EventCallback<CFile> UpdateFile { get; set; }
 | 
			
		||||
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public RenderFragment<CFile> Editor { get; set; } = null;
 | 
			
		||||
		[Parameter] public RenderFragment<CFile> Editor { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
		[Parameter] public EventCallback TestConfiguration { get; set; }
 | 
			
		||||
		[Parameter] public Result<string> TestResult { get; set; }
 | 
			
		||||
		[Parameter] public EventCallback ShowAddFileModal { get; set; }
 | 
			
		||||
		[Parameter] public EventCallback DeleteFileCallback { get; set; }
 | 
			
		||||
		[Parameter] public EventCallback<CFile> SelectedFileChanged { get; set; }
 | 
			
		||||
		[Parameter] public CFile SelectedFile { get; set; } = default;
 | 
			
		||||
 | 
			
		||||
		protected string SelectedFilter { get; set; }
 | 
			
		||||
		protected string SearchInput { get; set; }
 | 
			
		||||
@@ -46,11 +47,6 @@ namespace Seenginx.Components
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public EventCallback<CFile> SelectedFileChanged { get; set; }
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public CFile SelectedFile { get; set; } = default;
 | 
			
		||||
 | 
			
		||||
		protected override async Task OnParametersSetAsync()
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
@@ -96,6 +92,7 @@ namespace Seenginx.Components
 | 
			
		||||
				if (SelectedFilter == "All")
 | 
			
		||||
					Files.ForEach(f => f.Unhide());
 | 
			
		||||
				else if (SelectedFilter == "Root")
 | 
			
		||||
				{
 | 
			
		||||
					Files.ForEach(f =>
 | 
			
		||||
					{
 | 
			
		||||
						if (f.Folder == FilterFolder[SelectedFilter])
 | 
			
		||||
@@ -103,6 +100,7 @@ namespace Seenginx.Components
 | 
			
		||||
						else
 | 
			
		||||
							f.Hide();
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
					Files.ForEach(f =>
 | 
			
		||||
					{
 | 
			
		||||
@@ -121,7 +119,7 @@ namespace Seenginx.Components
 | 
			
		||||
					{
 | 
			
		||||
						if (SelectedFilter == "Root")
 | 
			
		||||
						{
 | 
			
		||||
							if (f.Folder == FilterFolder[SelectedFilter] && f.Folder.ToLower().Contains(SearchInput.ToLower()))
 | 
			
		||||
							if (f.Folder == FilterFolder[SelectedFilter] && f.Name.ToLower().Contains(SearchInput.ToLower()))
 | 
			
		||||
								f.Unhide();
 | 
			
		||||
							else
 | 
			
		||||
								f.Hide();
 | 
			
		||||
@@ -130,7 +128,7 @@ namespace Seenginx.Components
 | 
			
		||||
						{
 | 
			
		||||
							Files.ForEach(f =>
 | 
			
		||||
							{
 | 
			
		||||
								if (f.Folder.Contains(FilterFolder[SelectedFilter]) && f.Folder.ToLower().Contains(SearchInput.ToLower()))
 | 
			
		||||
								if (f.Folder.Contains(FilterFolder[SelectedFilter]) && f.Name.ToLower().Contains(SearchInput.ToLower()))
 | 
			
		||||
									f.Unhide();
 | 
			
		||||
								else
 | 
			
		||||
									f.Hide();
 | 
			
		||||
@@ -160,42 +158,44 @@ 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);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected async Task OnSave(MouseEventArgs e)
 | 
			
		||||
		{
 | 
			
		||||
			var draftCode = await JsRuntime.InvokeAsync<string>("GetEditorCode");
 | 
			
		||||
			SelectedFile.Body = draftCode;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public EventCallback TestConfiguration { get; set; }
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public Result<string> TestResult { get; set; }
 | 
			
		||||
		protected async Task OnTest(MouseEventArgs e)
 | 
			
		||||
		{
 | 
			
		||||
			await TestConfiguration.InvokeAsync(null);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public EventCallback AddFileModal { get; set; }
 | 
			
		||||
		protected async Task OnAddDialog()
 | 
			
		||||
		public async Task OnAddDialog()
 | 
			
		||||
		{
 | 
			
		||||
			await AddFileModal.InvokeAsync(null);
 | 
			
		||||
			await ShowAddFileModal.InvokeAsync(null);
 | 
			
		||||
			await JsRuntime.InvokeVoidAsync("ClearEditor");
 | 
			
		||||
			if (SelectedFile != null)
 | 
			
		||||
			{
 | 
			
		||||
				await JsRuntime.InvokeVoidAsync("UpdateEditor", SelectedFile.Body);
 | 
			
		||||
				SelectedFilter = "All";
 | 
			
		||||
				SearchInput = string.Empty;
 | 
			
		||||
				SearchFile();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public GeneralNotificationModalBase DeleteFileModal { get; set; }
 | 
			
		||||
		protected void OnDeleteDialog()
 | 
			
		||||
		protected async Task OnDeleteDialog()
 | 
			
		||||
		{
 | 
			
		||||
			DeleteFileModal.Show(new NotificationSettings
 | 
			
		||||
			{
 | 
			
		||||
				PopupType = PopupType.YesNo,
 | 
			
		||||
				Text = $"Do you want to delete '{SelectedFile.Name}' configuration file?"
 | 
			
		||||
			});
 | 
			
		||||
			await DeleteFileCallback.InvokeAsync(null);
 | 
			
		||||
			await JsRuntime.InvokeVoidAsync("ClearEditor");
 | 
			
		||||
			SelectedFilter = "All";
 | 
			
		||||
			SearchInput = string.Empty;
 | 
			
		||||
			SearchFile();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,105 +0,0 @@
 | 
			
		||||
@inherits GeneralNotificationModalBase
 | 
			
		||||
 | 
			
		||||
<Modal @ref="ModalReference">
 | 
			
		||||
	<ModalBackdrop />
 | 
			
		||||
	<ModalContent>
 | 
			
		||||
		<ModalBody>
 | 
			
		||||
			<p>@NotificationSettings.Text</p>
 | 
			
		||||
		</ModalBody>
 | 
			
		||||
		<ModalFooter>
 | 
			
		||||
			<div class="level fullwidth">
 | 
			
		||||
				@switch (NotificationSettings.PopupType)
 | 
			
		||||
				{
 | 
			
		||||
					case PopupType.Ok:
 | 
			
		||||
						<div class="level-right">
 | 
			
		||||
							<div class="level-item">
 | 
			
		||||
								<Blazorise.Bulma.Button Clicked="Ok" Class="is-rounded neoBtnSmall is-small has-text-dark">
 | 
			
		||||
									<span class="icon is-small has-text-success">
 | 
			
		||||
										<i class="mdi mdi-check"></i>
 | 
			
		||||
									</span>
 | 
			
		||||
									<span>Ok</span>
 | 
			
		||||
								</Blazorise.Bulma.Button>
 | 
			
		||||
							</div>
 | 
			
		||||
						</div>
 | 
			
		||||
						break;
 | 
			
		||||
					case PopupType.OkCancel:
 | 
			
		||||
						<div class="level-left">
 | 
			
		||||
							<div class="level-item">
 | 
			
		||||
								<Blazorise.Bulma.Button Clicked="Cancel" Class="is-rounded neoBtnSmall is-small has-text-dark">
 | 
			
		||||
									<span class="icon is-small">
 | 
			
		||||
										<i class="mdi mdi-close"></i>
 | 
			
		||||
									</span>
 | 
			
		||||
									<span>Cancel</span>
 | 
			
		||||
								</Blazorise.Bulma.Button>
 | 
			
		||||
							</div>
 | 
			
		||||
						</div>
 | 
			
		||||
						<div class="level-right">
 | 
			
		||||
							<div class="level-item">
 | 
			
		||||
								<Blazorise.Bulma.Button Clicked="Ok" Class="is-rounded neoBtnSmall is-small has-text-dark" Type="ButtonType.Submit">
 | 
			
		||||
									<span class="icon is-small has-text-success">
 | 
			
		||||
										<i class="mdi mdi-check"></i>
 | 
			
		||||
									</span>
 | 
			
		||||
									<span>Ok</span>
 | 
			
		||||
								</Blazorise.Bulma.Button>
 | 
			
		||||
							</div>
 | 
			
		||||
						</div>
 | 
			
		||||
						break;
 | 
			
		||||
					case PopupType.YesNo:
 | 
			
		||||
						<div class="level-left">
 | 
			
		||||
							<div class="level-item">
 | 
			
		||||
								<Blazorise.Bulma.Button Clicked="No" Class="is-rounded neoBtnSmall is-small has-text-dark">
 | 
			
		||||
									<span class="icon is-small has-text-danger">
 | 
			
		||||
										<i class="mdi mdi-close"></i>
 | 
			
		||||
									</span>
 | 
			
		||||
									<span>No</span>
 | 
			
		||||
								</Blazorise.Bulma.Button>
 | 
			
		||||
							</div>
 | 
			
		||||
						</div>
 | 
			
		||||
						<div class="level-right">
 | 
			
		||||
							<div class="level-item">
 | 
			
		||||
								<Blazorise.Bulma.Button Clicked="Yes" Class="is-rounded neoBtnSmall is-small has-text-dark" Type="ButtonType.Submit">
 | 
			
		||||
									<span class="icon is-small has-text-success">
 | 
			
		||||
										<i class="mdi mdi-check"></i>
 | 
			
		||||
									</span>
 | 
			
		||||
									<span>Yes</span>
 | 
			
		||||
								</Blazorise.Bulma.Button>
 | 
			
		||||
							</div>
 | 
			
		||||
						</div>
 | 
			
		||||
						break;
 | 
			
		||||
					case PopupType.YesNoCancel:
 | 
			
		||||
						<div class="level-left">
 | 
			
		||||
							<div class="level-item">
 | 
			
		||||
								<Blazorise.Bulma.Button Clicked="Cancel" Class="is-rounded neoBtnSmall is-small has-text-dark">
 | 
			
		||||
									<span class="icon is-small">
 | 
			
		||||
										<i class="mdi mdi-close"></i>
 | 
			
		||||
									</span>
 | 
			
		||||
									<span>Cancel</span>
 | 
			
		||||
								</Blazorise.Bulma.Button>
 | 
			
		||||
							</div>
 | 
			
		||||
						</div>
 | 
			
		||||
						<div class="level-right">
 | 
			
		||||
							<div class="level-item">
 | 
			
		||||
								<Blazorise.Bulma.Button Clicked="No" Class="is-rounded neoBtnSmall is-small has-text-dark">
 | 
			
		||||
									<span class="icon is-small has-text-danger">
 | 
			
		||||
										<i class="mdi mdi-close"></i>
 | 
			
		||||
									</span>
 | 
			
		||||
									<span>No</span>
 | 
			
		||||
								</Blazorise.Bulma.Button>
 | 
			
		||||
							</div>
 | 
			
		||||
							<div class="level-item">
 | 
			
		||||
								<Blazorise.Bulma.Button Clicked="Yes" Class="is-rounded neoBtnSmall is-small has-text-dark" Type="ButtonType.Submit">
 | 
			
		||||
									<span class="icon is-small has-text-success">
 | 
			
		||||
										<i class="mdi mdi-check"></i>
 | 
			
		||||
									</span>
 | 
			
		||||
									<span>Yes</span>
 | 
			
		||||
								</Blazorise.Bulma.Button>
 | 
			
		||||
							</div>
 | 
			
		||||
						</div>
 | 
			
		||||
						break;
 | 
			
		||||
					default:
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
			</div>
 | 
			
		||||
		</ModalFooter>
 | 
			
		||||
	</ModalContent>
 | 
			
		||||
</Modal>
 | 
			
		||||
@@ -1,29 +0,0 @@
 | 
			
		||||
using Blazorise;
 | 
			
		||||
using Microsoft.AspNetCore.Components;
 | 
			
		||||
using Seenginx.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Seenginx.Components
 | 
			
		||||
{
 | 
			
		||||
	public class GeneralNotificationModalBase : ComponentBase
 | 
			
		||||
	{
 | 
			
		||||
		public Modal ModalReference { get; set; } = new Modal();
 | 
			
		||||
		public NotificationSettings NotificationSettings { get; set; }
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public EventCallback<PopupAnswer> PopupCallback { get; set; }
 | 
			
		||||
 | 
			
		||||
		public void Show(NotificationSettings notificationSettings)
 | 
			
		||||
		{
 | 
			
		||||
			NotificationSettings = notificationSettings;
 | 
			
		||||
			ModalReference.Show();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task Ok() => await PopupCallback.InvokeAsync(PopupAnswer.Ok);
 | 
			
		||||
		public async Task Cancel() => await PopupCallback.InvokeAsync(PopupAnswer.Cancel);
 | 
			
		||||
		public async Task Yes() => await PopupCallback.InvokeAsync(PopupAnswer.Yes);
 | 
			
		||||
		public async Task No() => await PopupCallback.InvokeAsync(PopupAnswer.No);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -3,72 +3,6 @@
 | 
			
		||||
<FilesWithEditor CFile="ConfigFile" Filters="Filters" Files="ConfigFiles" FilterFolder="FilterFolder"
 | 
			
		||||
								 SelectedFile="SelectedFile" SelectedFileChanged="SelectedFileChanged"
 | 
			
		||||
								 TestConfiguration="TestConfiguration" TestResult="TestResult"
 | 
			
		||||
								 DeleteFileModal="DeleteNotificationModal" AddFileModal="ShowAddFileModal">
 | 
			
		||||
								 DeleteFileCallback="DeleteFile" ShowAddFileModal="ShowAddFileModal" >
 | 
			
		||||
</FilesWithEditor>
 | 
			
		||||
<Modal @ref="AddFileModal">
 | 
			
		||||
	<ModalBackdrop />
 | 
			
		||||
	<ModalContent Class="neomorph">
 | 
			
		||||
		<ModalHeader>
 | 
			
		||||
			<ModalTitle Class="has-text-centered">Add a new configuration for a service</ModalTitle>
 | 
			
		||||
		</ModalHeader>
 | 
			
		||||
		<ModalBody>
 | 
			
		||||
			<div class="field">
 | 
			
		||||
				<label class="label">Template</label>
 | 
			
		||||
				<div class="control has-icons-left">
 | 
			
		||||
					<div class="select is-small is-rounded neoSelect fullwidth">
 | 
			
		||||
						<select class="fullwidth" @bind="NewFileForm.SelectedTemplate">
 | 
			
		||||
							<option value="0">No template</option>
 | 
			
		||||
							@foreach (var template in NewFileForm.Templates)
 | 
			
		||||
							{
 | 
			
		||||
								<option value="@template.Name">@($"{template.Name.First().ToString().ToUpper()}{template.Name.Substring(1)}")</option>
 | 
			
		||||
							}
 | 
			
		||||
						</select>
 | 
			
		||||
					</div>
 | 
			
		||||
					<span class="icon is-small is-left has-text-dark">
 | 
			
		||||
						<i class="mdi mdi-puzzle-outline"></i>
 | 
			
		||||
					</span>
 | 
			
		||||
				</div>
 | 
			
		||||
				<p class="help">Any template to quick setup the configuration</p>
 | 
			
		||||
			</div>
 | 
			
		||||
 | 
			
		||||
			<div class="field">
 | 
			
		||||
				<label class="label">Configuration file name</label>
 | 
			
		||||
				<div class="control has-icons-left has-icons-right">
 | 
			
		||||
					<input class="input is-rounded is-small neoInput" type="text" @bind="NewFileForm.Name" placeholder="Name" />
 | 
			
		||||
					<span class="icon is-small is-left has-text-dark">
 | 
			
		||||
						<i class="mdi mdi-file-code-outline"></i>
 | 
			
		||||
					</span>
 | 
			
		||||
				</div>
 | 
			
		||||
				<p class="help">Name it the same as the service which is going to run behind</p>
 | 
			
		||||
			</div>
 | 
			
		||||
		</ModalBody>
 | 
			
		||||
		<ModalFooter>
 | 
			
		||||
			<div class="level fullwidth">
 | 
			
		||||
				<div class="level-left">
 | 
			
		||||
					<div class="level-item">
 | 
			
		||||
						<Blazorise.Bulma.Button Clicked="e => CloseModal(AddFileModal)"
 | 
			
		||||
																		Class="is-rounded neoBtnSmall is-small has-text-dark">
 | 
			
		||||
							<span class="icon is-small">
 | 
			
		||||
								<i class="mdi mdi-close"></i>
 | 
			
		||||
							</span>
 | 
			
		||||
							<span>Close</span>
 | 
			
		||||
						</Blazorise.Bulma.Button>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="level-right">
 | 
			
		||||
					<div class="level-item">
 | 
			
		||||
						<Blazorise.Bulma.Button Color="Color.Primary" Clicked="AddFileAsync"
 | 
			
		||||
																		Class="is-rounded neoBtnSmall is-small has-text-dark" Type="ButtonType.Submit">
 | 
			
		||||
							<span class="icon is-small has-text-success">
 | 
			
		||||
								<i class="mdi mdi-plus"></i>
 | 
			
		||||
							</span>
 | 
			
		||||
							<span>Add</span>
 | 
			
		||||
						</Blazorise.Bulma.Button>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</ModalFooter>
 | 
			
		||||
	</ModalContent>
 | 
			
		||||
</Modal>
 | 
			
		||||
<GeneralNotificationModal PopupCallback="DeleteFile"></GeneralNotificationModal>
 | 
			
		||||
@*<GeneralNotificationModal ></GeneralNotificationModal>*@
 | 
			
		||||
 
 | 
			
		||||
@@ -1,23 +1,23 @@
 | 
			
		||||
using Blazorise;
 | 
			
		||||
using Blazored.Modal;
 | 
			
		||||
using Blazored.Modal.Services;
 | 
			
		||||
using Blazorise;
 | 
			
		||||
using Microsoft.AspNetCore.Components;
 | 
			
		||||
using Microsoft.AspNetCore.Components.Web;
 | 
			
		||||
using Seenginx.Components;
 | 
			
		||||
using Seenginx.Models;
 | 
			
		||||
using Seenginx.Services;
 | 
			
		||||
using Seenginx.Shared;
 | 
			
		||||
using Seenginx.Utility;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Seenginx.Pages
 | 
			
		||||
{
 | 
			
		||||
	public class NginxBase : ComponentBase
 | 
			
		||||
	{
 | 
			
		||||
		[Inject]
 | 
			
		||||
		public INginxService NginxService { get; set; }
 | 
			
		||||
		[Inject]
 | 
			
		||||
		public IFileManager FileService { get; set; }
 | 
			
		||||
		[Inject] public INginxService NginxService { get; set; }
 | 
			
		||||
		[Inject] public IFileManager FileService { get; set; }
 | 
			
		||||
		[Inject] public IModalService Modal { get; set; }
 | 
			
		||||
 | 
			
		||||
		public string InputSearch { get; set; }
 | 
			
		||||
 | 
			
		||||
@@ -26,6 +26,7 @@ namespace Seenginx.Pages
 | 
			
		||||
		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>();
 | 
			
		||||
 | 
			
		||||
@@ -40,7 +41,7 @@ namespace Seenginx.Pages
 | 
			
		||||
				FilterFolder.Add("Conf.d", "/conf.d");
 | 
			
		||||
				FilterFolder.Add("Available", "/sites-available");
 | 
			
		||||
				FilterFolder.Add("Enabled", "/sites-enabled");
 | 
			
		||||
				NewFileForm.Templates.AddRange(await NginxService.GetTemplates());
 | 
			
		||||
				Templates.AddRange(await NginxService.GetTemplates());
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception ex)
 | 
			
		||||
			{
 | 
			
		||||
@@ -54,83 +55,71 @@ namespace Seenginx.Pages
 | 
			
		||||
			SelectedFile = configFile;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		protected Modal AddFileModal { get; set; }
 | 
			
		||||
		public void ShowAddFileModal()
 | 
			
		||||
		public async Task ShowAddFileModal()
 | 
			
		||||
		{
 | 
			
		||||
			AddFileModal.Show();
 | 
			
		||||
		}
 | 
			
		||||
			var parameters = new ModalParameters();
 | 
			
		||||
			parameters.Add(nameof(Templates), Templates);
 | 
			
		||||
 | 
			
		||||
		public NewFileForm NewFileForm { get; set; } = new NewFileForm();
 | 
			
		||||
		public async Task AddFileAsync()
 | 
			
		||||
		{
 | 
			
		||||
			var addFileResult = await NginxService.AddFileAsync(NewFileForm);
 | 
			
		||||
			var resultAwait = Modal.Show<NginxConfigForm>(string.Empty, parameters);
 | 
			
		||||
			var result = await resultAwait.Result;
 | 
			
		||||
			if (result.Cancelled) return;
 | 
			
		||||
 | 
			
		||||
			if (!addFileResult.AllOk)
 | 
			
		||||
				throw new Exception(":/");
 | 
			
		||||
 | 
			
		||||
			var validationResult = await NginxService.ValidateNewConfigurationAsync((NewFileForm)result.Data);
 | 
			
		||||
 | 
			
		||||
			if (!validationResult.AllOk)
 | 
			
		||||
			{
 | 
			
		||||
				var validationPopupParameters = new ModalParameters().Setup(PopupType.Ok, validationResult.ErrorMessage);
 | 
			
		||||
				var validationPopup = Modal.Show<GenericPopup>(string.Empty, validationPopupParameters);
 | 
			
		||||
				await validationPopup.Result;
 | 
			
		||||
				validationPopup.Close();
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var addFileResult = await NginxService.AddFileAsync((NewFileForm)result.Data);
 | 
			
		||||
			if (SelectedFile != null)
 | 
			
		||||
				SelectedFile.Deselect();
 | 
			
		||||
			ConfigFiles.Add(addFileResult.Data);
 | 
			
		||||
			ConfigFiles = ConfigFiles.OrderBy(cf => cf.Name).ToList();
 | 
			
		||||
			AddFileModal.Hide();
 | 
			
		||||
			//if (AddFileResult.AllOk)
 | 
			
		||||
			//	ConfigFiles.Add(AddFileResult.Data);
 | 
			
		||||
			//else
 | 
			
		||||
			//{
 | 
			
		||||
			//	GeneralNotificationSettings = new GeneralNotificationSettings
 | 
			
		||||
			//	{
 | 
			
		||||
			//		ButtonColor = Color.Danger,
 | 
			
		||||
			//		TitleClass = "mdi-error",
 | 
			
		||||
			//		Title = "Failure",
 | 
			
		||||
			//		Text = TestResult.ErrorMessage
 | 
			
		||||
			//	};
 | 
			
		||||
			//	GeneralNotificationModal.Show();
 | 
			
		||||
			//}
 | 
			
		||||
			SelectedFile = ConfigFiles.Find(cf => cf.Name == addFileResult.Data.Name);
 | 
			
		||||
			SelectedFile.Select();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Result<ConfigFile> SaveUpdateDraftResult { get; set; }
 | 
			
		||||
		public async Task SaveUpdateDraftFileAsync()
 | 
			
		||||
		{
 | 
			
		||||
			SaveUpdateDraftResult = await FileService.SaveUpdateDraftFileAsync(SelectedFile);
 | 
			
		||||
			var saveUpdateDraftResult = await FileService.SaveUpdateDraftFileAsync(SelectedFile);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Result<ConfigFile> SaveUpdateResult { get; set; }
 | 
			
		||||
		public async Task SaveUpdateFileAsync()
 | 
			
		||||
		{
 | 
			
		||||
			SaveUpdateResult = await FileService.SaveUpdateFileAsync(SelectedFile);
 | 
			
		||||
			var saveUpdateResult = await FileService.SaveUpdateFileAsync(SelectedFile);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Result<string> TestResult { get; set; }
 | 
			
		||||
		public Modal TestNotificationModal { get; set; } = new Modal();
 | 
			
		||||
		public async Task TestConfiguration()
 | 
			
		||||
		{
 | 
			
		||||
			TestResult = await NginxService.TestNginxConfigurations(SelectedFile);
 | 
			
		||||
			if (TestResult.AllOk)
 | 
			
		||||
				GeneralNotificationSettings = new NotificationSettings
 | 
			
		||||
				{
 | 
			
		||||
					Text = $"Test of config file '{SelectedFile.Name}' completed with success.",
 | 
			
		||||
					PopupType = PopupType.Ok
 | 
			
		||||
				};
 | 
			
		||||
			else
 | 
			
		||||
				GeneralNotificationSettings = new NotificationSettings
 | 
			
		||||
				{
 | 
			
		||||
					Text = TestResult.ErrorMessage,
 | 
			
		||||
					PopupType = PopupType.Ok
 | 
			
		||||
				};
 | 
			
		||||
			TestNotificationModal.Show();
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public GeneralNotificationModalBase DeleteNotificationModal { get; set; } = new GeneralNotificationModalBase();
 | 
			
		||||
		public void DeleteFile(PopupAnswer popupAnswer)
 | 
			
		||||
		public async Task DeleteFile()
 | 
			
		||||
		{
 | 
			
		||||
			if (popupAnswer == PopupAnswer.Yes)
 | 
			
		||||
			var parameters = new ModalParameters().Setup(PopupType.YesNo, $"Are you sure you want to delete '{SelectedFile.Name}'?");
 | 
			
		||||
 | 
			
		||||
			var resultAwait = Modal.Show<GenericPopup>(string.Empty, parameters);
 | 
			
		||||
			var result = await resultAwait.Result;
 | 
			
		||||
			if ((PopupAnswer)result.Data == PopupAnswer.No) return;
 | 
			
		||||
 | 
			
		||||
			var deleteFileResult = await NginxService.DeleteConfigurationFileAsync(SelectedFile);
 | 
			
		||||
 | 
			
		||||
			if (!deleteFileResult.AllOk)
 | 
			
		||||
			{
 | 
			
		||||
				var deleteResult = FileService.DeleteFile(SelectedFile);
 | 
			
		||||
				var errorParameters = new ModalParameters().Setup(PopupType.Ok, $"Something went wrong, here's the error message: '{deleteFileResult.ErrorMessage}'?");
 | 
			
		||||
				var errorReportModalAwait = Modal.Show<GenericPopup>(string.Empty, errorParameters);
 | 
			
		||||
				await errorReportModalAwait.Result;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void CloseModal(Modal modal)
 | 
			
		||||
		{
 | 
			
		||||
			modal.Hide();
 | 
			
		||||
			ConfigFiles.Remove(SelectedFile);
 | 
			
		||||
			SelectedFile = null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -53,9 +53,6 @@ html {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.modal- {
 | 
			
		||||
	&background {
 | 
			
		||||
		background: rgba($background,.9);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	&content {
 | 
			
		||||
		border-radius: $border-radius-b;
 | 
			
		||||
@@ -81,3 +78,22 @@ html {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.blazored {
 | 
			
		||||
	&-modal {
 | 
			
		||||
		background-color: transparent;
 | 
			
		||||
		border-radius: 0;
 | 
			
		||||
		border: none;
 | 
			
		||||
		padding: 0;
 | 
			
		||||
		box-shadow: none;
 | 
			
		||||
 | 
			
		||||
		&-container {
 | 
			
		||||
			left: 0;
 | 
			
		||||
			top: 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		&-overlay {
 | 
			
		||||
			background: $background
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -149,6 +149,16 @@
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.field.has-addons {
 | 
			
		||||
	& > .control.is-expanded > .neoInput {
 | 
			
		||||
		box-shadow: inset 2px 2px 4px rgba($dark-shadow, .5),inset 2px -2px 4px rgba($light-shadow, .5) !important;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	& > .control > .neoSelect > select {
 | 
			
		||||
		box-shadow: inset -2px 2px 4px rgba($dark-shadow, .5),inset -2px -2px 4px rgba($light-shadow, .5) !important;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.gradientBackground {
 | 
			
		||||
	background: linear-gradient(to right bottom,$background-light,$background-dark)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,5 +10,7 @@ namespace Seenginx.Services
 | 
			
		||||
		Task<Result<string>> TestNginxConfigurations(ConfigFile configFile);
 | 
			
		||||
		Task<Result<ConfigFile>> AddFileAsync(NewFileForm newFileForm);
 | 
			
		||||
		Task<IEnumerable<Template>> GetTemplates();
 | 
			
		||||
		Task<Result<bool>> DeleteConfigurationFileAsync(ConfigFile configFile);
 | 
			
		||||
		Task<Result<bool>> ValidateNewConfigurationAsync(NewFileForm newFileForm);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -5,6 +5,7 @@ using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Security.AccessControl;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
@@ -19,22 +20,47 @@ namespace Seenginx.Services
 | 
			
		||||
			ConfigPaths = configPaths;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<Result<bool>> ValidateNewConfigurationAsync(NewFileForm newFileForm)
 | 
			
		||||
		{
 | 
			
		||||
			var validationResult = new Result<bool>();
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				var filePath = Path.Combine(ConfigPaths.NginxPath, "conf.d", $"{newFileForm.Name}.conf");
 | 
			
		||||
 | 
			
		||||
				if (File.Exists(filePath))
 | 
			
		||||
					return validationResult.Invalidate($"There's already a file with the '{newFileForm.Name}.conf' name.");
 | 
			
		||||
 | 
			
		||||
				return validationResult;
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception ex)
 | 
			
		||||
			{
 | 
			
		||||
				return validationResult.Invalidate($"Exception at {nameof(ValidateNewConfigurationAsync)}()", ex);
 | 
			
		||||
			}
 | 
			
		||||
		} 
 | 
			
		||||
 | 
			
		||||
		public async Task<Result<ConfigFile>> AddFileAsync(NewFileForm newFileForm)
 | 
			
		||||
		{
 | 
			
		||||
			await Task.Run(() => { });
 | 
			
		||||
			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;
 | 
			
		||||
 | 
			
		||||
			await File.WriteAllTextAsync(newFile.FullPath, newFile.Body, Encoding.UTF8);
 | 
			
		||||
 | 
			
		||||
			var addResult = new Result<ConfigFile>();
 | 
			
		||||
			addResult.SetData(newFile);
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
 | 
			
		||||
			return addResult;
 | 
			
		||||
				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;
 | 
			
		||||
 | 
			
		||||
				await File.WriteAllTextAsync(newFile.FullPath, newFile.Body, Encoding.UTF8);
 | 
			
		||||
 | 
			
		||||
				addResult.SetData(newFile);
 | 
			
		||||
 | 
			
		||||
				return addResult;
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception ex)
 | 
			
		||||
			{
 | 
			
		||||
				return addResult.Invalidate(ex.Message, ex);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<IEnumerable<ConfigFile>> GetFilesAsync()
 | 
			
		||||
@@ -53,7 +79,7 @@ namespace Seenginx.Services
 | 
			
		||||
				configFile.Folder = "/";
 | 
			
		||||
				configFile.LastUpdated = File.GetLastWriteTime(fp);
 | 
			
		||||
				configFile.Name = fileName;
 | 
			
		||||
				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder, configFile.Name);
 | 
			
		||||
				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Name);
 | 
			
		||||
				configFile.Body = File.ReadAllText(fp);
 | 
			
		||||
				return configFile;
 | 
			
		||||
			});
 | 
			
		||||
@@ -65,7 +91,7 @@ namespace Seenginx.Services
 | 
			
		||||
				configFile.Folder = "/conf.d";
 | 
			
		||||
				configFile.LastUpdated = File.GetLastWriteTime(fp);
 | 
			
		||||
				configFile.Name = fileName;
 | 
			
		||||
				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder, configFile.Name);
 | 
			
		||||
				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder.Replace("/", string.Empty), configFile.Name);
 | 
			
		||||
				configFile.Body = File.ReadAllText(fp);
 | 
			
		||||
				return configFile;
 | 
			
		||||
			});
 | 
			
		||||
@@ -77,7 +103,7 @@ namespace Seenginx.Services
 | 
			
		||||
				configFile.Folder = "/sites-available";
 | 
			
		||||
				configFile.LastUpdated = File.GetLastWriteTime(fp);
 | 
			
		||||
				configFile.Name = fileName;
 | 
			
		||||
				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder, configFile.Name);
 | 
			
		||||
				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder.Replace("/", string.Empty), configFile.Name);
 | 
			
		||||
				configFile.Body = File.ReadAllText(fp);
 | 
			
		||||
				return configFile;
 | 
			
		||||
			});
 | 
			
		||||
@@ -89,7 +115,7 @@ namespace Seenginx.Services
 | 
			
		||||
				configFile.Folder = "/sites-enabled";
 | 
			
		||||
				configFile.LastUpdated = File.GetLastWriteTime(fp);
 | 
			
		||||
				configFile.Name = fileName;
 | 
			
		||||
				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder, configFile.Name);
 | 
			
		||||
				configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder.Replace("/", string.Empty), configFile.Name);
 | 
			
		||||
				configFile.Body = File.ReadAllText(fp);
 | 
			
		||||
				return configFile;
 | 
			
		||||
			});
 | 
			
		||||
@@ -108,9 +134,7 @@ namespace Seenginx.Services
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				var nginxTemplateDirectory = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "templates", "nginx");
 | 
			
		||||
				//var systemdTemplateDirectory = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "systemd");
 | 
			
		||||
				var nginxTemplateFiles = Directory.GetFiles(nginxTemplateDirectory, "*.template");
 | 
			
		||||
				//var systemdTemplateFiles = Directory.GetFiles(nginxTemplateDirectory, "*.template");
 | 
			
		||||
 | 
			
		||||
				foreach (var templateFilePath in nginxTemplateFiles)
 | 
			
		||||
				{
 | 
			
		||||
@@ -136,5 +160,38 @@ namespace Seenginx.Services
 | 
			
		||||
			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);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		//public async Task<Result<bool>> DeleteFileAsync(ConfigFile configFile)
 | 
			
		||||
		//{
 | 
			
		||||
		//	var result = new Result<bool>(true);
 | 
			
		||||
		//	try
 | 
			
		||||
		//	{
 | 
			
		||||
		//		return result;
 | 
			
		||||
		//	}
 | 
			
		||||
		//	catch (Exception ex)
 | 
			
		||||
		//	{
 | 
			
		||||
		//		return result.Invalidate(ex.Message, ex);
 | 
			
		||||
		//	}
 | 
			
		||||
		//}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										130
									
								
								Seenginx/Shared/GenericPopup.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								Seenginx/Shared/GenericPopup.razor
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
<div class="modal-content neomorph">
 | 
			
		||||
 | 
			
		||||
	@*<div class="modal-card-head">
 | 
			
		||||
			<h4 class="modal-card-title has-text-centered">
 | 
			
		||||
				Add a new configuration for a service
 | 
			
		||||
			</h4>
 | 
			
		||||
		</div>*@
 | 
			
		||||
 | 
			
		||||
	<div class="modal-card-body">
 | 
			
		||||
 | 
			
		||||
		<h1>@Message</h1>
 | 
			
		||||
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<div class="modal-card-foot">
 | 
			
		||||
 | 
			
		||||
		<div class="level fullwidth">
 | 
			
		||||
			@switch (PopupType)
 | 
			
		||||
			{
 | 
			
		||||
				case PopupType.Ok:
 | 
			
		||||
					<div class="level-left">
 | 
			
		||||
						<div class="level-item"></div>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="level-right">
 | 
			
		||||
						<div class="level-item">
 | 
			
		||||
							<Blazorise.Bulma.Button Clicked="Ok" Class="is-rounded neoBtnSmall is-small has-text-dark">
 | 
			
		||||
								<span class="icon is-small has-text-success">
 | 
			
		||||
									<i class="mdi mdi-check"></i>
 | 
			
		||||
								</span>
 | 
			
		||||
								<span>Ok</span>
 | 
			
		||||
							</Blazorise.Bulma.Button>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
					break;
 | 
			
		||||
				case PopupType.OkCancel:
 | 
			
		||||
					<div class="level-left">
 | 
			
		||||
						<div class="level-item">
 | 
			
		||||
							<Blazorise.Bulma.Button Clicked="Cancel" Class="is-rounded neoBtnSmall is-small has-text-dark">
 | 
			
		||||
								<span class="icon is-small">
 | 
			
		||||
									<i class="mdi mdi-close"></i>
 | 
			
		||||
								</span>
 | 
			
		||||
								<span>Cancel</span>
 | 
			
		||||
							</Blazorise.Bulma.Button>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="level-right">
 | 
			
		||||
						<div class="level-item">
 | 
			
		||||
							<Blazorise.Bulma.Button Clicked="Ok" Class="is-rounded neoBtnSmall is-small has-text-dark" Type="ButtonType.Submit">
 | 
			
		||||
								<span class="icon is-small has-text-success">
 | 
			
		||||
									<i class="mdi mdi-check"></i>
 | 
			
		||||
								</span>
 | 
			
		||||
								<span>Ok</span>
 | 
			
		||||
							</Blazorise.Bulma.Button>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
					break;
 | 
			
		||||
				case PopupType.YesNo:
 | 
			
		||||
					<div class="level-left">
 | 
			
		||||
						<div class="level-item">
 | 
			
		||||
							<Blazorise.Bulma.Button Clicked="No" Class="is-rounded neoBtnSmall is-small has-text-dark">
 | 
			
		||||
								<span class="icon is-small has-text-danger">
 | 
			
		||||
									<i class="mdi mdi-close"></i>
 | 
			
		||||
								</span>
 | 
			
		||||
								<span>No</span>
 | 
			
		||||
							</Blazorise.Bulma.Button>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="level-right">
 | 
			
		||||
						<div class="level-item">
 | 
			
		||||
							<Blazorise.Bulma.Button Clicked="Yes" Class="is-rounded neoBtnSmall is-small has-text-dark" Type="ButtonType.Submit">
 | 
			
		||||
								<span class="icon is-small has-text-success">
 | 
			
		||||
									<i class="mdi mdi-check"></i>
 | 
			
		||||
								</span>
 | 
			
		||||
								<span>Yes</span>
 | 
			
		||||
							</Blazorise.Bulma.Button>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
					break;
 | 
			
		||||
				case PopupType.YesNoCancel:
 | 
			
		||||
					<div class="level-left">
 | 
			
		||||
						<div class="level-item">
 | 
			
		||||
							<Blazorise.Bulma.Button Clicked="Cancel" Class="is-rounded neoBtnSmall is-small has-text-dark">
 | 
			
		||||
								<span class="icon is-small">
 | 
			
		||||
									<i class="mdi mdi-close"></i>
 | 
			
		||||
								</span>
 | 
			
		||||
								<span>Cancel</span>
 | 
			
		||||
							</Blazorise.Bulma.Button>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="level-right">
 | 
			
		||||
						<div class="level-item">
 | 
			
		||||
							<Blazorise.Bulma.Button Clicked="No" Class="is-rounded neoBtnSmall is-small has-text-dark">
 | 
			
		||||
								<span class="icon is-small has-text-danger">
 | 
			
		||||
									<i class="mdi mdi-close"></i>
 | 
			
		||||
								</span>
 | 
			
		||||
								<span>No</span>
 | 
			
		||||
							</Blazorise.Bulma.Button>
 | 
			
		||||
						</div>
 | 
			
		||||
						<div class="level-item">
 | 
			
		||||
							<Blazorise.Bulma.Button Clicked="Yes" Class="is-rounded neoBtnSmall is-small has-text-dark" Type="ButtonType.Submit">
 | 
			
		||||
								<span class="icon is-small has-text-success">
 | 
			
		||||
									<i class="mdi mdi-check"></i>
 | 
			
		||||
								</span>
 | 
			
		||||
								<span>Yes</span>
 | 
			
		||||
							</Blazorise.Bulma.Button>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
	[CascadingParameter]
 | 
			
		||||
	BlazoredModalInstance BlazoredModal { get; set; }
 | 
			
		||||
 | 
			
		||||
	[Parameter, Required]
 | 
			
		||||
	public string Message { get; set; }
 | 
			
		||||
	[Parameter, Required]
 | 
			
		||||
	public PopupType PopupType { get; set; }
 | 
			
		||||
 | 
			
		||||
	void Yes() => BlazoredModal.Close(ModalResult.Ok(PopupAnswer.Yes));
 | 
			
		||||
	void No() => BlazoredModal.Close(ModalResult.Ok(PopupAnswer.No));
 | 
			
		||||
	void Ok() => BlazoredModal.Close(ModalResult.Ok(PopupAnswer.Ok));
 | 
			
		||||
	void Cancel() => BlazoredModal.Close(ModalResult.Ok(PopupAnswer.Cancel));
 | 
			
		||||
}
 | 
			
		||||
@@ -10,5 +10,6 @@
 | 
			
		||||
		@Body
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
</section>
 | 
			
		||||
 | 
			
		||||
</section>
 | 
			
		||||
<BlazoredModal DisableBackgroundCancel="true" HideCloseButton="true" HideHeader="true" Position="ModalPosition.Center" />
 | 
			
		||||
							
								
								
									
										84
									
								
								Seenginx/Shared/NginxConfigForm.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								Seenginx/Shared/NginxConfigForm.razor
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
<div class="modal-content neomorph">
 | 
			
		||||
 | 
			
		||||
	<div class="modal-card-head">
 | 
			
		||||
		<h4 class="modal-card-title has-text-centered">
 | 
			
		||||
			Add a new configuration for a service
 | 
			
		||||
		</h4>
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<div class="modal-card-body">
 | 
			
		||||
 | 
			
		||||
		<div class="field">
 | 
			
		||||
			<label class="label">Template</label>
 | 
			
		||||
			<div class="control has-icons-left">
 | 
			
		||||
				<div class="select is-small is-rounded neoSelect fullwidth">
 | 
			
		||||
					<select class="fullwidth" @bind="SelectedTemplate">
 | 
			
		||||
						<option value="0">No template</option>
 | 
			
		||||
						@foreach (var template in Templates)
 | 
			
		||||
						{
 | 
			
		||||
							<option value="@template.Name">@($"{template.Name.First().ToString().ToUpper()}{template.Name.Substring(1)}")</option>
 | 
			
		||||
						}
 | 
			
		||||
					</select>
 | 
			
		||||
				</div>
 | 
			
		||||
				<span class="icon is-small is-left has-text-dark">
 | 
			
		||||
					<i class="mdi mdi-puzzle-outline"></i>
 | 
			
		||||
				</span>
 | 
			
		||||
			</div>
 | 
			
		||||
			<p class="help">Any template to quick setup the configuration</p>
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		<div class="field">
 | 
			
		||||
			<label class="label">Configuration file name</label>
 | 
			
		||||
			<div class="control has-icons-left">
 | 
			
		||||
				<input class="input is-rounded is-small neoInput" type="text" placeholder="Name" @bind="TemplateName">
 | 
			
		||||
				<span class="icon is-small is-left has-text-dark">
 | 
			
		||||
					<i class="mdi mdi-file-code-outline"></i>
 | 
			
		||||
				</span>
 | 
			
		||||
			</div>
 | 
			
		||||
			<p class="help">Name it the same as the service which is going to run behind</p>
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<div class="modal-card-foot">
 | 
			
		||||
 | 
			
		||||
		<div class="level fullwidth">
 | 
			
		||||
			<div class="level-left">
 | 
			
		||||
				<div class="level-item">
 | 
			
		||||
					<button type="button" class="button is-rounded neoBtnSmall is-small has-text-dark" @onclick="Cancel">
 | 
			
		||||
						<span class="icon is-small">
 | 
			
		||||
							<i class="mdi mdi-close"></i>
 | 
			
		||||
						</span>
 | 
			
		||||
						<span>Close</span>
 | 
			
		||||
					</button>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
 | 
			
		||||
			<div class="level-right">
 | 
			
		||||
				<div class="level-item">
 | 
			
		||||
					<button type="submit" class="button is-primary is-rounded neoBtnSmall is-small has-text-dark" @onclick="SubmitForm">
 | 
			
		||||
						<span class="icon is-small has-text-success">
 | 
			
		||||
							<i class="mdi mdi-plus"></i>
 | 
			
		||||
						</span>
 | 
			
		||||
						<span>Add</span>
 | 
			
		||||
					</button>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
	[CascadingParameter]
 | 
			
		||||
	BlazoredModalInstance BlazoredModal { get; set; }
 | 
			
		||||
 | 
			
		||||
	string SelectedTemplate { get; set; } = "0";
 | 
			
		||||
	[Required]
 | 
			
		||||
	string TemplateName { get; set; }
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public List<Template> Templates { get; set; } = new List<Template>();
 | 
			
		||||
 | 
			
		||||
	void SubmitForm() => BlazoredModal.Close(ModalResult.Ok(new NewFileForm { Name = TemplateName, SelectedTemplate = SelectedTemplate }));
 | 
			
		||||
	void Cancel() => BlazoredModal.Cancel();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								Seenginx/Utility/ModalUtility.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Seenginx/Utility/ModalUtility.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
using Blazored.Modal;
 | 
			
		||||
using Mono.Posix;
 | 
			
		||||
using Seenginx.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Seenginx.Utility
 | 
			
		||||
{
 | 
			
		||||
	public static class ModalUtility
 | 
			
		||||
	{
 | 
			
		||||
		public static ModalParameters Setup(this ModalParameters parameters, PopupType popupType, string message)
 | 
			
		||||
		{
 | 
			
		||||
			parameters.Add(nameof(PopupType), popupType);
 | 
			
		||||
			parameters.Add("Message", message);
 | 
			
		||||
			return parameters;
 | 
			
		||||
		} 
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
@using System.Net.Http
 | 
			
		||||
@using System.ComponentModel.DataAnnotations
 | 
			
		||||
@using Microsoft.AspNetCore.Authorization
 | 
			
		||||
@using Microsoft.AspNetCore.Components.Authorization
 | 
			
		||||
@using Microsoft.AspNetCore.Components.Forms
 | 
			
		||||
 
 | 
			
		||||
@@ -133,6 +133,12 @@ html {
 | 
			
		||||
  .neoSelect > select:focus {
 | 
			
		||||
    border: none !important; }
 | 
			
		||||
 | 
			
		||||
.field.has-addons > .control.is-expanded > .neoInput {
 | 
			
		||||
  box-shadow: inset 2px 2px 4px rgba(241, 185, 65, 0.5), inset 2px -2px 4px rgba(251, 238, 208, 0.5) !important; }
 | 
			
		||||
 | 
			
		||||
.field.has-addons > .control > .neoSelect > select {
 | 
			
		||||
  box-shadow: inset -2px 2px 4px rgba(241, 185, 65, 0.5), inset -2px -2px 4px rgba(251, 238, 208, 0.5) !important; }
 | 
			
		||||
 | 
			
		||||
.gradientBackground {
 | 
			
		||||
  background: linear-gradient(to right bottom, #f7d794, #f5cd79); }
 | 
			
		||||
 | 
			
		||||
@@ -197,9 +203,6 @@ html {
 | 
			
		||||
  .ace-solarized-light .ace_marker-layer .ace_active-line {
 | 
			
		||||
    border-radius: 0 50px 50px 0; }
 | 
			
		||||
 | 
			
		||||
.modal-background {
 | 
			
		||||
  background: rgba(246, 210, 135, 0.9); }
 | 
			
		||||
 | 
			
		||||
.modal-content {
 | 
			
		||||
  border-radius: 28px; }
 | 
			
		||||
 | 
			
		||||
@@ -217,6 +220,18 @@ html {
 | 
			
		||||
  border: none;
 | 
			
		||||
  border-radius: 0; }
 | 
			
		||||
 | 
			
		||||
.blazored-modal {
 | 
			
		||||
  background-color: transparent;
 | 
			
		||||
  border-radius: 0;
 | 
			
		||||
  border: none;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  box-shadow: none; }
 | 
			
		||||
  .blazored-modal-container {
 | 
			
		||||
    left: 0;
 | 
			
		||||
    top: 0; }
 | 
			
		||||
  .blazored-modal-overlay {
 | 
			
		||||
    background: #f6d287; }
 | 
			
		||||
 | 
			
		||||
:root {
 | 
			
		||||
  --stripe-size: 200px;
 | 
			
		||||
  --color1: #f6d287;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								Seenginx/wwwroot/css/main.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								Seenginx/wwwroot/css/main.min.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Reference in New Issue
	
	Block a user