Introduced a new TimeController with a POST endpoint to insert and retrieve the latest time record. Added ITimeRepository, TimeRepository, and TimeRecord entity. Implemented MediatR command and handler for time insertion. Updated ApplicationDbContext and DI configuration to support the new feature.
181 lines
7.1 KiB
C#
181 lines
7.1 KiB
C#
using DbFirst.API.Middleware;
|
|
using DbFirst.API.Dashboards;
|
|
using DbFirst.API.Hubs;
|
|
using DbFirst.Application;
|
|
using DbFirst.Application.Repositories;
|
|
using DbFirst.Domain;
|
|
using DbFirst.Domain.Entities;
|
|
using DbFirst.Infrastructure;
|
|
using DbFirst.Infrastructure.Repositories;
|
|
using DevExpress.AspNetCore;
|
|
using DevExpress.DashboardAspNetCore;
|
|
using DevExpress.DashboardCommon;
|
|
using DevExpress.DashboardWeb;
|
|
using DevExpress.DataAccess.Json;
|
|
using System.Xml.Linq;
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
// Add services to the container.
|
|
builder.Services.AddControllers();
|
|
builder.Services.AddEndpointsApiExplorer();
|
|
builder.Services.AddSwaggerGen();
|
|
|
|
// TODO: allow listed origins configured in appsettings.json
|
|
// In any case, dont let them to free to use without cors. if there is no origin specified, block all.
|
|
// In development you can keep it easy.
|
|
builder.Services.AddCors(options =>
|
|
{
|
|
options.AddDefaultPolicy(policy =>
|
|
{
|
|
if (builder.Environment.IsDevelopment())
|
|
{
|
|
policy.AllowAnyOrigin()
|
|
.AllowAnyHeader()
|
|
.AllowAnyMethod();
|
|
}
|
|
else
|
|
{
|
|
var origins = builder.Configuration.GetSection("Cors:AllowedOrigins").Get<string[]>() ?? Array.Empty<string>();
|
|
if (origins.Length > 0)
|
|
{
|
|
policy.WithOrigins(origins)
|
|
.AllowAnyHeader()
|
|
.AllowAnyMethod();
|
|
}
|
|
// if no origins configured, deny all by leaving policy without allowances
|
|
}
|
|
});
|
|
});
|
|
|
|
builder.Services.AddInfrastructure(builder.Configuration);
|
|
builder.Services.AddApplication();
|
|
|
|
builder.Services.AddScoped<ICatalogRepository, CatalogRepository>();
|
|
builder.Services.AddScoped<IMassDataRepository, MassDataRepository>();
|
|
builder.Services.AddScoped<ILayoutRepository, LayoutRepository>();
|
|
builder.Services.AddScoped<ITimeRepository, TimeRepository>();
|
|
|
|
builder.Services.AddDevExpressControls();
|
|
builder.Services.AddSignalR();
|
|
builder.Services.AddSingleton<IDashboardChangeNotifier, DashboardChangeNotifier>();
|
|
builder.Services.AddScoped<DashboardConfigurator>((IServiceProvider serviceProvider) => {
|
|
var dashboardsPath = Path.Combine(builder.Environment.ContentRootPath, "Data", "Dashboards");
|
|
Directory.CreateDirectory(dashboardsPath);
|
|
|
|
var defaultDashboardPath = Path.Combine(dashboardsPath, "DefaultDashboard.xml");
|
|
if (!File.Exists(defaultDashboardPath))
|
|
{
|
|
var defaultDashboard = new Dashboard();
|
|
defaultDashboard.Title.Text = "Default Dashboard";
|
|
defaultDashboard.SaveToXml(defaultDashboardPath);
|
|
}
|
|
|
|
var dashboardBaseUrl = builder.Configuration["Dashboard:BaseUrl"]
|
|
?? builder.Configuration["ApiBaseUrl"]
|
|
?? builder.Configuration["ASPNETCORE_URLS"]?.Split(';', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault()
|
|
?? "https://localhost:7204";
|
|
|
|
dashboardBaseUrl = dashboardBaseUrl.TrimEnd('/');
|
|
|
|
var catalogsGridDashboardPath = Path.Combine(dashboardsPath, "CatalogsGrid.xml");
|
|
if (!File.Exists(catalogsGridDashboardPath))
|
|
{
|
|
var dashboard = new Dashboard();
|
|
dashboard.Title.Text = "Catalogs (Dashboard Grid)";
|
|
|
|
var catalogDataSource = new DashboardJsonDataSource("Catalogs (API)")
|
|
{
|
|
ComponentName = "catalogsDataSource",
|
|
JsonSource = new UriJsonSource(new Uri($"{dashboardBaseUrl}/api/catalogs"))
|
|
};
|
|
|
|
dashboard.DataSources.Add(catalogDataSource);
|
|
|
|
var grid = new GridDashboardItem
|
|
{
|
|
DataSource = catalogDataSource,
|
|
Name = "Catalogs"
|
|
};
|
|
|
|
grid.Columns.Add(new GridDimensionColumn(new Dimension(nameof(VwmyCatalog.Guid))) { Name = "Id" });
|
|
grid.Columns.Add(new GridDimensionColumn(new Dimension(nameof(VwmyCatalog.CatTitle))) { Name = "Titel" });
|
|
grid.Columns.Add(new GridDimensionColumn(new Dimension(nameof(VwmyCatalog.CatString))) { Name = "String" });
|
|
grid.Columns.Add(new GridDimensionColumn(new Dimension(nameof(VwmyCatalog.AddedWho))) { Name = "Angelegt von" });
|
|
grid.Columns.Add(new GridDimensionColumn(new Dimension(nameof(VwmyCatalog.AddedWhen))) { Name = "Angelegt am" });
|
|
grid.Columns.Add(new GridDimensionColumn(new Dimension(nameof(VwmyCatalog.ChangedWho))) { Name = "Geändert von" });
|
|
grid.Columns.Add(new GridDimensionColumn(new Dimension(nameof(VwmyCatalog.ChangedWhen))) { Name = "Geändert am" });
|
|
|
|
dashboard.Items.Add(grid);
|
|
|
|
var layoutGroup = new DashboardLayoutGroup { Orientation = DashboardLayoutGroupOrientation.Vertical };
|
|
layoutGroup.ChildNodes.Add(new DashboardLayoutItem(grid));
|
|
dashboard.LayoutRoot = layoutGroup;
|
|
|
|
dashboard.SaveToXml(catalogsGridDashboardPath);
|
|
}
|
|
|
|
DashboardConfigurator configurator = new DashboardConfigurator();
|
|
|
|
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? string.Empty;
|
|
var notifier = serviceProvider.GetRequiredService<IDashboardChangeNotifier>();
|
|
var dashboardStorage = new SqlDashboardStorage(connectionString, "TBDD_SMF_CONFIG", notifier: notifier);
|
|
configurator.SetDashboardStorage(dashboardStorage);
|
|
|
|
DataSourceInMemoryStorage dataSourceStorage = new DataSourceInMemoryStorage();
|
|
DashboardJsonDataSource jsonDataSourceUrl = new DashboardJsonDataSource("JSON Data Source (URL)");
|
|
jsonDataSourceUrl.JsonSource = new UriJsonSource(
|
|
new Uri("https://raw.githubusercontent.com/DevExpress-Examples/DataSources/master/JSON/customers.json"));
|
|
jsonDataSourceUrl.RootElement = "Customers";
|
|
dataSourceStorage.RegisterDataSource("jsonDataSourceUrl", jsonDataSourceUrl.SaveToXml());
|
|
|
|
var catalogsJsonDataSource = new DashboardJsonDataSource("Catalogs (API)")
|
|
{
|
|
ComponentName = "catalogsDataSource",
|
|
JsonSource = new UriJsonSource(new Uri($"{dashboardBaseUrl}/api/catalogs"))
|
|
};
|
|
dataSourceStorage.RegisterDataSource(catalogsJsonDataSource.ComponentName, catalogsJsonDataSource.SaveToXml());
|
|
dataSourceStorage.RegisterDataSource(catalogsJsonDataSource.Name, catalogsJsonDataSource.SaveToXml());
|
|
|
|
configurator.SetDataSourceStorage(dataSourceStorage);
|
|
|
|
EnsureDashboardInStorage(dashboardStorage, "DefaultDashboard", defaultDashboardPath);
|
|
EnsureDashboardInStorage(dashboardStorage, "CatalogsGrid", catalogsGridDashboardPath);
|
|
|
|
return configurator;
|
|
});
|
|
|
|
var app = builder.Build();
|
|
|
|
// Configure the HTTP request pipeline.
|
|
if (app.Environment.IsDevelopment())
|
|
{
|
|
app.UseSwagger();
|
|
app.UseSwaggerUI();
|
|
}
|
|
|
|
app.UseMiddleware<ExceptionHandlingMiddleware>();
|
|
|
|
app.UseDevExpressControls();
|
|
app.UseHttpsRedirection();
|
|
app.UseCors();
|
|
app.UseAuthorization();
|
|
|
|
app.MapDashboardRoute("api/dashboard", "DefaultDashboard");
|
|
app.MapHub<DashboardsHub>("/hubs/dashboards");
|
|
app.MapControllers();
|
|
|
|
app.Run();
|
|
|
|
static void EnsureDashboardInStorage(IEditableDashboardStorage storage, string id, string filePath)
|
|
{
|
|
var exists = storage.GetAvailableDashboardsInfo().Any(info => string.Equals(info.ID, id, StringComparison.OrdinalIgnoreCase));
|
|
if (exists || !File.Exists(filePath))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var doc = XDocument.Load(filePath);
|
|
storage.AddDashboard(doc, id);
|
|
}
|