@namespace Oqtane.UI @inject SiteState ComponentSiteState @inject IStringLocalizer Localizer @inject ILogService LoggingService @inherits ErrorBoundary @if (CurrentException is null) { @if (ModuleType != null) { @if (!string.IsNullOrEmpty(_messageContent) && _messagePosition == "top") { } @DynamicComponent @if (_progressIndicator) {
} @if (!string.IsNullOrEmpty(_messageContent) && _messagePosition == "bottom") { } } } else { @if (!string.IsNullOrEmpty(_error)) { } }
@code { // this component is on the interactive side of the render mode boundary // it receives state as serializable parameters so that the state can be made available to downstream components private Type ModuleType { get; set; } RenderFragment DynamicComponent { get; set; } private string _messageContent; private MessageType _messageType; private string _messagePosition; private bool _progressIndicator = false; private string _error; [Parameter] public SiteState SiteState { get; set; } [Parameter] public PageState PageState { get; set; } [Parameter] public Module ModuleState { get; set; } protected override bool ShouldRender() { return PageState?.RenderId == ModuleState?.RenderId; } protected override void OnParametersSet() { _messageContent = ""; if (ShouldRender()) { if (!string.IsNullOrEmpty(ModuleState.ModuleType)) { ModuleType = Type.GetType(ModuleState.ModuleType); if (ModuleType != null) { // repopulate the SiteState service based on the values passed in the SiteState parameter (this is how state is marshalled across the render mode boundary) ComponentSiteState.Hydrate(SiteState); DynamicComponent = builder => { builder.OpenComponent(0, ModuleType); builder.AddAttribute(1, "RenderModeBoundary", this); builder.CloseComponent(); }; } else { // module does not exist with typename specified _messageContent = string.Format(Localizer["Error.Module.InvalidName"], Utilities.GetTypeNameLastSegment(ModuleState.ModuleType, 0)); _messageType = MessageType.Error; _messagePosition = "top"; } } else { _messageContent = string.Format(Localizer["Error.Module.InvalidType"], ModuleState.ModuleDefinitionName); _messageType = MessageType.Error; _messagePosition = "top"; } } } public void AddModuleMessage(string message, MessageType type) { AddModuleMessage(message, type, "top"); } public void AddModuleMessage(string message, MessageType type, string position) { if(message != _messageContent || type != _messageType || position != _messagePosition) { _messageContent = message; _messageType = type; _messagePosition = position; _progressIndicator = false; StateHasChanged(); } } public void ShowProgressIndicator() { _progressIndicator = true; StateHasChanged(); } public void HideProgressIndicator() { _progressIndicator = false; StateHasChanged(); } public void DismissMessage() { _messageContent = ""; StateHasChanged(); } protected override async Task OnErrorAsync(Exception exception) { // retrieve friendly localized error _error = Localizer["Error.Module.Exception"]; // log error string category = GetType().AssemblyQualifiedName; string feature = Utilities.GetTypeNameLastSegment(category, 1); await LoggingService.Log(null, ModuleState.PageId, ModuleState.ModuleId, PageState.User?.UserId, category, feature, LogFunction.Other, LogLevel.Error, exception, "An Unexpected Error Has Occurred In {ModuleDefinitionName}: {Error}", ModuleState.ModuleDefinitionName, exception.Message); await base.OnErrorAsync(exception); return; } public new void Recover() { _error = ""; base.Recover(); } }