Add manual "Sync Columbia" action and status to powder catalog admin
Phase 3: SuperAdmin-triggered sync. Adds a SyncColumbia POST action that runs a full catalog sync on demand (bypassing the schedule) and reports the result via TempData. The catalog index header gains a "Sync Columbia" button (with a syncing spinner) and a status line showing the scheduled-sync on/off state, last-synced time, and last-run summary, read from the platform settings. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using PowderCoating.Application.Constants;
|
||||
using PowderCoating.Application.DTOs.Common;
|
||||
using PowderCoating.Application.DTOs.Inventory;
|
||||
using PowderCoating.Application.Interfaces;
|
||||
@@ -19,15 +20,21 @@ public class PowderCatalogController : Controller
|
||||
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly IInventoryAiLookupService _aiLookupService;
|
||||
private readonly IColumbiaCatalogSyncService _columbiaSyncService;
|
||||
private readonly IPlatformSettingsService _platformSettings;
|
||||
private readonly ILogger<PowderCatalogController> _logger;
|
||||
|
||||
public PowderCatalogController(
|
||||
IUnitOfWork unitOfWork,
|
||||
IInventoryAiLookupService aiLookupService,
|
||||
IColumbiaCatalogSyncService columbiaSyncService,
|
||||
IPlatformSettingsService platformSettings,
|
||||
ILogger<PowderCatalogController> logger)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_aiLookupService = aiLookupService;
|
||||
_columbiaSyncService = columbiaSyncService;
|
||||
_platformSettings = platformSettings;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -135,6 +142,11 @@ public class PowderCatalogController : Controller
|
||||
}
|
||||
};
|
||||
|
||||
// Columbia sync status for the admin panel (last run + master switch).
|
||||
ViewBag.ColumbiaSyncEnabled = await _platformSettings.GetBoolAsync(ColumbiaIntegrationConstants.SettingEnabled);
|
||||
ViewBag.ColumbiaLastSyncedAt = await _platformSettings.GetAsync(ColumbiaIntegrationConstants.SettingLastSyncedAt);
|
||||
ViewBag.ColumbiaLastResult = await _platformSettings.GetAsync(ColumbiaIntegrationConstants.SettingLastResult);
|
||||
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
@@ -422,6 +434,24 @@ public class PowderCatalogController : Controller
|
||||
return Json(results);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manually triggers a full Columbia Coatings catalog sync (SuperAdmin only). Bypasses the
|
||||
/// scheduled interval. Reports the run outcome via TempData on the catalog index.
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> SyncColumbia(CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await _columbiaSyncService.RunSyncAsync(cancellationToken);
|
||||
|
||||
if (result.Success)
|
||||
TempData["Success"] = $"Columbia sync complete — {result.Summary}";
|
||||
else
|
||||
TempData["Error"] = $"Columbia sync failed: {result.ErrorMessage}";
|
||||
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
||||
// Private helpers
|
||||
|
||||
private async Task ApplyTdsCureFallbackAsync(InventoryAiLookupResult result, string? colorName)
|
||||
|
||||
@@ -110,12 +110,42 @@
|
||||
<div class="text-muted small">Platform-level lookup library for inventory autofill, SDS/TDS links, and curing specs.</div>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<form asp-action="SyncColumbia" method="post" class="d-inline"
|
||||
onsubmit="this.querySelector('button').disabled=true;this.querySelector('button').innerHTML='<span class=\'spinner-border spinner-border-sm me-1\'></span>Syncing…';">
|
||||
@Html.AntiForgeryToken()
|
||||
<button type="submit" class="btn btn-outline-primary" title="Pull the latest Columbia Coatings catalog now">
|
||||
<i class="bi bi-cloud-download me-1"></i>Sync Columbia
|
||||
</button>
|
||||
</form>
|
||||
<a asp-action="Create" class="btn btn-primary">
|
||||
<i class="bi bi-plus-circle me-1"></i>Add Powder
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@{
|
||||
var columbiaLastSynced = ViewBag.ColumbiaLastSyncedAt as string;
|
||||
var columbiaLastResult = ViewBag.ColumbiaLastResult as string;
|
||||
var columbiaEnabled = ViewBag.ColumbiaSyncEnabled is true;
|
||||
}
|
||||
<div class="alert alert-light border d-flex flex-wrap align-items-center gap-2 small mb-4 alert-permanent">
|
||||
<span class="badge @(columbiaEnabled ? "bg-success" : "bg-secondary")">
|
||||
Scheduled sync @(columbiaEnabled ? "on" : "off")
|
||||
</span>
|
||||
@if (!string.IsNullOrWhiteSpace(columbiaLastSynced) && DateTime.TryParse(columbiaLastSynced, out var lastSyncedAt))
|
||||
{
|
||||
<span class="text-muted">Last synced @lastSyncedAt.ToLocalTime().ToString("MMM d, yyyy h:mm tt")</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="text-muted">Never synced</span>
|
||||
}
|
||||
@if (!string.IsNullOrWhiteSpace(columbiaLastResult))
|
||||
{
|
||||
<span class="text-muted">— @columbiaLastResult</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="row g-3 mb-4 powder-catalog-summary">
|
||||
<div class="col-sm-6 col-xl-2">
|
||||
<div class="card h-100">
|
||||
|
||||
Reference in New Issue
Block a user