Skip to content

Commit

Permalink
feat: implement the first configuration stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
wgnf committed Nov 4, 2023
1 parent 4aa60d8 commit 542cc18
Show file tree
Hide file tree
Showing 11 changed files with 367 additions and 7 deletions.
10 changes: 10 additions & 0 deletions src/CsvProc9000.UI/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,14 @@ public App()

MainPage = new MainPage();
}

protected override Window CreateWindow(IActivationState activationState)
{
var window = base.CreateWindow(activationState);

window.Width = 800;
window.Height = 1000;

return window;
}
}
35 changes: 35 additions & 0 deletions src/CsvProc9000.UI/Components/FolderSelect.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@using CsvProc9000.UI.Dialogues
@inject IFolderPicker FolderPicker

<div class="input-with-button">
<InputText type="text" @bind-Value="@SelectedPath"></InputText>
<button class="btn btn-primary" @onclick="SelectFolderPath">Select</button>
</div>

@code {
private string _selectedPath = string.Empty;

[Parameter]
public string DialogueTitle { get; set; }

[Parameter]
public string SelectedPath
{
get => _selectedPath;
set
{
if (value == _selectedPath) return;
_selectedPath = value;
SelectedPathChanged.InvokeAsync(value);
}
}

[Parameter]
public EventCallback<string> SelectedPathChanged { get; set; }

private void SelectFolderPath()
{
var selectedPath = FolderPicker.Show(DialogueTitle);
SelectedPath = selectedPath;
}
}
10 changes: 6 additions & 4 deletions src/CsvProc9000.UI/CsvProc9000.UI.csproj
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<TargetFrameworks>net7.0-android;net7.0-ios;net7.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net7.0-windows10.0.19041.0</TargetFrameworks>
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
<!-- <TargetFrameworks>$(TargetFrameworks);net7.0-tizen</TargetFrameworks> -->
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
<OutputType>Exe</OutputType>
<RootNamespace>CsvProc9000.UI</RootNamespace>
<UseMaui>true</UseMaui>
Expand Down Expand Up @@ -50,6 +47,11 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="7.0.0"/>
<PackageReference Include="WindowsAPICodePackShell" Version="7.0.4" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\CsvProc9000.Model\CsvProc9000.Model.csproj" />
</ItemGroup>

</Project>
14 changes: 14 additions & 0 deletions src/CsvProc9000.UI/Dialogues/IFolderPicker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace CsvProc9000.UI.Dialogues;

/// <summary>
/// A dialogue to let the user pick a folder
/// </summary>
internal interface IFolderPicker
{
/// <summary>
/// Shows the dialogue and lets the user pick a folder
/// </summary>
/// <param name="title">A title for the dialogue</param>
/// <returns>The path to the folder that the user picked</returns>
string Show(string title);
}
13 changes: 12 additions & 1 deletion src/CsvProc9000.UI/MauiProgram.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Microsoft.Extensions.Logging;
using CsvProc9000.UI.Dialogues;
using CsvProc9000.UI.Platforms.Windows;
using CsvProc9000.UI.Settings;
using Microsoft.Extensions.Logging;

namespace CsvProc9000.UI;

Expand All @@ -18,6 +21,14 @@ public static MauiApp CreateMauiApp()
builder.Logging.AddDebug();
#endif

builder
.Services
.AddSingleton<IFolderPicker, WindowsFolderPicker>();

builder
.Services
.AddSingleton<ISettingsLoader, SettingsLoader>();

return builder.Build();
}
}
131 changes: 131 additions & 0 deletions src/CsvProc9000.UI/Pages/Configure.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
@page "/config"
@using CsvProc9000.Model.Configuration
@using CsvProc9000.UI.Settings
@using CsvProc9000.UI.Components
@inject ISettingsLoader SettingsLoader

<!-- TODO: GO BACK TO HOME link! -->

<h1>Configure</h1>

<p>
Here you can configure your <b>CsvProc9000</b> service to your needs.
</p>

<div class="load">
<div>
<div>
Where is the currently installed service located?
</div>
<div>
<FolderSelect DialogueTitle="Select the service installation location" @bind-SelectedPath="@_serviceInstallationPath"></FolderSelect>
</div>
</div>

<div class="mt-1">
<button class="btn btn-primary" disabled="@IsLoadButtonDisabled" @onclick="LoadSettings">Load settings</button>
</div>
</div>

@{
if (_settings != null)
{
<div class="settings mt-4">
<h2>Settings</h2>
<p>
Change the settings of your current service installation here:
</p>

<div class="mt-2">
<h3>Inbox</h3>

<div class="row">
<div>
Inbox directory:
</div>
<div>
<FolderSelect DialogueTitle="Select the Inbox" @bind-SelectedPath="@_settings.Inbox"></FolderSelect>
</div>
</div>

<div class="row">
<div>
Inbox delimiter:
</div>
<div>
<InputText type="text" @bind-Value="@_settings.InboxDelimiter"></InputText>
</div>
</div>

<div class="row">
<div>
Should the file in the Inbox be deleted?
</div>
<div>
<InputCheckbox @bind-Value="@_settings.DeleteInboxFile"></InputCheckbox>
</div>
</div>
</div>

<div class="mt-2">
<h3>Outbox</h3>

<div class="row">
<div>
Outbox directory:
</div>
<div>
<FolderSelect DialogueTitle="Select the Outbox" @bind-SelectedPath="@_settings.Outbox"></FolderSelect>
</div>
</div>

<div class="row">
<div>
Outbox delimiter:
</div>
<div>
<InputText type="text" @bind-Value="@_settings.OutboxDelimiter"></InputText>
</div>
</div>

<div class="row">
<div>
Outbox charset:
</div>
<div>
<InputText type="text" @bind-Value="@_settings.OutboxFileCharset"></InputText>
</div>
</div>

<div class="row">
<div>
Should the values in the Outbox-file be in quotes?
</div>
<div>
<InputCheckbox @bind-Value="@_settings.OutboxValuesInQuotes"></InputCheckbox>
</div>
</div>
</div>

<div class="mt-2">
<h3>Rules</h3>

<p>TODO...</p>
</div>
</div>
}
}

@code {

private string _serviceInstallationPath = string.Empty;
private bool IsLoadButtonDisabled => string.IsNullOrWhiteSpace(_serviceInstallationPath);
private CsvProcessorOptions _settings;

private void LoadSettings()
{
var settings = SettingsLoader.Load(_serviceInstallationPath);
_settings = settings;
}

}
50 changes: 48 additions & 2 deletions src/CsvProc9000.UI/Pages/Index.razor
Original file line number Diff line number Diff line change
@@ -1,5 +1,51 @@
@page "/"
@inject NavigationManager NavigationManager

<h1>Hello, world!</h1>
<h1>CsvProc900</h1>

Welcome to your new app.
<p>
Welcome to the UI application for the <b>CsvProc900!</b>
</p>
<p>
Here are some options you can use:
</p>
<div class="navigation">
<div class="row">
<div class="col-sm">
<button type="button" class="btn btn-primary btn-square" @onclick="NavigateToConfigPage">
<div class="oi oi-cog">
</div>
<div>
Config
</div>
</button>
</div>

<div class="col-sm">
<button type="button" class="btn btn-primary btn-square" disabled>
<div class="oi oi-clock">
</div>
<div>
Coming Soon™
</div>
</button>
</div>

<div class="col-sm">
<button type="button" class="btn btn-primary btn-square" disabled>
<div class="oi oi-clock">
</div>
<div>
Coming Soon™
</div>
</button>
</div>
</div>
</div>

@code {
private void NavigateToConfigPage()
{
NavigationManager.NavigateTo("config");
}
}
26 changes: 26 additions & 0 deletions src/CsvProc9000.UI/Platforms/Windows/WindowsFolderPicker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using CsvProc9000.UI.Dialogues;
using Microsoft.WindowsAPICodePack.Dialogs;

namespace CsvProc9000.UI.Platforms.Windows;

/// <summary>
/// A windows specific <see cref="IFolderPicker"/>
/// </summary>
internal sealed class WindowsFolderPicker : IFolderPicker
{
/// <inheritdoc />
public string Show(string title)
{
var dialog = new CommonOpenFileDialog(title);

dialog.IsFolderPicker = true;
dialog.Multiselect = false;
dialog.Title = title;

var result = dialog.ShowDialog();

return result == CommonFileDialogResult.Ok
? dialog.FileName
: string.Empty;
}
}
16 changes: 16 additions & 0 deletions src/CsvProc9000.UI/Settings/ISettingsLoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using CsvProc9000.Model.Configuration;

namespace CsvProc9000.UI.Settings;

/// <summary>
/// Loads the settings of the service from a given directory
/// </summary>
internal interface ISettingsLoader
{
/// <summary>
/// Loads the settings of the service from the given directory
/// </summary>
/// <param name="pathToDirectory">The directory to load the settings from</param>
/// <returns>The loaded settings</returns>
CsvProcessorOptions Load(string pathToDirectory);
}
39 changes: 39 additions & 0 deletions src/CsvProc9000.UI/Settings/SettingsLoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using CsvProc9000.Model.Configuration;
using Microsoft.Extensions.Configuration;

namespace CsvProc9000.UI.Settings;

/// <inheritdoc />
internal sealed class SettingsLoader : ISettingsLoader
{
/// <inheritdoc />
public CsvProcessorOptions Load(string pathToDirectory)
{
if (!Directory.Exists(pathToDirectory))
{
throw new DirectoryNotFoundException($"Unable to find directory '{pathToDirectory}'");
}

var pathToSettings = Path.Combine(pathToDirectory, "appsettings.json");
if (!File.Exists(pathToSettings))
{
throw new FileNotFoundException($"Expected a file at '{pathToSettings}' but couldn't find a file");
}

var settings = LoadSettingsFromFile(pathToSettings);
return settings;
}

private static CsvProcessorOptions LoadSettingsFromFile(string pathToSettingsFile)
{
var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonFile(pathToSettingsFile);

var configuration = configurationBuilder.Build();

var section = configuration.GetSection("CsvProcessor");
var settings = section.Get<CsvProcessorOptions>();

return settings;
}
}
Loading

0 comments on commit 542cc18

Please sign in to comment.