SF-74: Server — CustomImagesController (GET /api/CustomImages), DI registration, appsettings logo config, App.razor
This commit is contained in:
@@ -10,15 +10,58 @@
|
||||
<link rel="stylesheet" href="css/envelope-viewer.css" />
|
||||
<link rel="stylesheet" href="EnvelopeGenerator.Server.styles.css" />
|
||||
<HeadOutlet />
|
||||
<!-- Apply saved theme immediately on page load — before WASM boots.
|
||||
Reads localStorage["signflow.theme"] to avoid flash of default theme. -->
|
||||
<script>
|
||||
(function () {
|
||||
var allowed = { 'blazing-dark': true, 'blazing-berry': true, 'purple': true };
|
||||
var theme = localStorage.getItem('signflow.theme');
|
||||
if (!theme || !allowed[theme]) theme = 'blazing-berry';
|
||||
var bsTheme = theme === 'blazing-dark' ? 'dark' : 'light';
|
||||
document.documentElement.setAttribute('data-sf-theme', theme);
|
||||
document.documentElement.setAttribute('data-bs-theme', bsTheme);
|
||||
var link = document.createElement('link');
|
||||
link.id = 'dx-theme-link';
|
||||
link.rel = 'stylesheet';
|
||||
link.href = '_content/DevExpress.Blazor.Themes/' + theme + '.bs5.min.css';
|
||||
document.head.appendChild(link);
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- WASM boot loading overlay — hidden once Blazor circuit connects -->
|
||||
<div id="sf-boot-overlay">
|
||||
<div class="sf-boot-spinner">
|
||||
<div class="sf-boot-ring"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Routes />
|
||||
<script src="_content/DevExpress.Blazor.Resources/js/preload-script.js"></script>
|
||||
<script src="js/typed.umd.js"></script>
|
||||
<script src="js/receiver-signature.js?v=9"></script>
|
||||
<script src="js/signflow-theme.js"></script>
|
||||
<script src="_framework/blazor.web.js"></script>
|
||||
<script>
|
||||
// Remove the boot overlay once Blazor has started and enhanced navigation is active.
|
||||
Blazor.addEventListener('enhancedload', function onFirstLoad() {
|
||||
var overlay = document.getElementById('sf-boot-overlay');
|
||||
if (overlay) overlay.style.opacity = '0';
|
||||
setTimeout(function () { if (overlay) overlay.remove(); }, 250);
|
||||
Blazor.removeEventListener('enhancedload', onFirstLoad);
|
||||
});
|
||||
// Also remove when WASM circuit is ready (for non-enhanced pages like /sender)
|
||||
document.addEventListener('blazor-circuit-connected', function () {
|
||||
var overlay = document.getElementById('sf-boot-overlay');
|
||||
if (overlay) { overlay.style.opacity = '0'; setTimeout(function () { if (overlay) overlay.remove(); }, 250); }
|
||||
}, { once: true });
|
||||
// Fallback: remove after 4s regardless
|
||||
setTimeout(function () {
|
||||
var overlay = document.getElementById('sf-boot-overlay');
|
||||
if (overlay) overlay.remove();
|
||||
}, 4000);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.Server.Models;
|
||||
|
||||
namespace EnvelopeGenerator.Server.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the CustomImages configuration (signFLOW logo + company logo) to WASM clients.
|
||||
/// Values are sourced from appsettings.json "CustomImages" section via Options Pattern.
|
||||
///
|
||||
/// To change logos per deployment: update "CustomImages.App.Src", "App.Height",
|
||||
/// "Company.Src", "Company.Height" in appsettings.json — no code change required.
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
[Authorize(Policy = AuthPolicy.SenderOrReceiver)]
|
||||
public class CustomImagesController(IOptions<CustomImagesOptions> options) : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the signFLOW app logo and company logo configuration.
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public ActionResult<CustomImagesOptions> Get() => Ok(options.Value);
|
||||
}
|
||||
@@ -326,12 +326,17 @@ try
|
||||
// User Preferences (theme, dark mode, grid layouts — stored in TBDD_CACHE)
|
||||
// Registration handled by Infrastructure DependencyInjection (AddEnvelopeGeneratorInfrastructureServices)
|
||||
|
||||
// CustomImages — logo sources and heights, configurable per deployment via appsettings.json
|
||||
builder.Services.Configure<EnvelopeGenerator.Server.Models.CustomImagesOptions>(
|
||||
config.GetSection(EnvelopeGenerator.Server.Models.CustomImagesOptions.SectionName));
|
||||
|
||||
// Client-side services that MainLayout depends on must also be registered here
|
||||
// so that Blazor Auto prerender (SSR pass) can resolve them on the server.
|
||||
// ThemeService.InitializeAsync() uses IJSRuntime but is only called in OnAfterRenderAsync
|
||||
// (never during prerender), so registering it server-side is safe.
|
||||
builder.Services.AddScoped<EnvelopeGenerator.Server.Client.Services.UserPreferencesService>();
|
||||
builder.Services.AddScoped<EnvelopeGenerator.Server.Client.Services.ThemeService>();
|
||||
builder.Services.AddScoped<EnvelopeGenerator.Server.Client.Services.CustomImagesService>();
|
||||
|
||||
// Business Services (Server specific)
|
||||
builder.Services.AddScoped<DocumentService>();
|
||||
|
||||
@@ -145,15 +145,17 @@
|
||||
"CustomImages": {
|
||||
"App": {
|
||||
"Src": "/img/DD_signFLOW_LOGO.png",
|
||||
"Height": "28px",
|
||||
"Classes": {
|
||||
"Main": "signFlow-logo"
|
||||
"Main": "signflow-app-logo"
|
||||
}
|
||||
},
|
||||
"Company": {
|
||||
"Src": "/img/digital_data.svg",
|
||||
"Height": "33px",
|
||||
"Classes": {
|
||||
"Show": "dd-show-logo",
|
||||
"Locked": "dd-locked-logo"
|
||||
"Show": "signflow-company-logo",
|
||||
"Locked": "signflow-company-logo"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user