Add restore functionality for template management and enhance related components
ci / build-backend (push) Successful in 2m47s
ci / build-frontend (push) Successful in 1m8s
ci / tests (push) Successful in 2m28s
ci / sonar (push) Successful in 6m49s

Implemented a new endpoint for restoring templates to their last applied state, allowing users to revert changes made since the last application. Updated the ScheduleTemplate class to include a snapshot of the last applied state, enabling rollback capabilities. Enhanced the frontend with a restore button in the ChannelDetail component, providing users with a confirmation prompt before executing the restore action. Localization updates were made to support new UI strings in both English and Russian, improving the overall user experience in template management.
This commit is contained in:
Leonid Pershin
2026-07-27 08:43:53 +03:00
parent a302750de6
commit 0fd4e762f4
21 changed files with 2227 additions and 133 deletions
@@ -34,6 +34,14 @@ public class ScheduleTemplate
/// <summary>Ревизия, по которой собрано текущее будущее расписание.</summary>
public int AppliedRevision { get; private set; }
/// <summary>
/// Состояние шаблона на момент последнего применения (JSON) — то, по чему идёт эфир прямо
/// сейчас. Нужно, чтобы правки можно было откатить: слои и слоты правятся на месте, и без
/// снимка «как было» взять неоткуда. Домен его не разбирает — схема живёт в Application, как
/// у правил и стратегий.
/// </summary>
public string? AppliedSnapshotJson { get; private set; }
public DateTimeOffset CreatedAt { get; private set; }
public IReadOnlyList<GridLayer> Layers => _layers;
@@ -80,8 +88,16 @@ public class ScheduleTemplate
/// <summary>Отметить, что правила изменились — эфир пойдёт по старым до применения.</summary>
public void MarkChanged() => Revision++;
/// <summary>Отметить, что хвост пересобран по текущей ревизии.</summary>
public void MarkApplied() => AppliedRevision = Revision;
/// <summary>
/// Отметить, что хвост пересобран по текущей ревизии. Снимок — состояние, по которому собран
/// эфир; он же станет точкой отката для последующих правок.
/// </summary>
public void MarkApplied(string? snapshotJson = null)
{
AppliedRevision = Revision;
if (!string.IsNullOrWhiteSpace(snapshotJson))
AppliedSnapshotJson = snapshotJson;
}
public GridLayer? FindLayer(Guid layerId) => _layers.FirstOrDefault(l => l.Id == layerId);