moduleDefintions - profiles validation changes
This commit is contained in:
		@ -10,67 +10,71 @@
 | 
			
		||||
 | 
			
		||||
@if (_templates != null)
 | 
			
		||||
{
 | 
			
		||||
    <div class="container">
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="owner" HelpText="Enter the name of the organization who is developing this module. It should not contain spaces or punctuation." ResourceKey="OwnerName">Owner Name: </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <input id="owner" class="form-control" @bind="@_owner" />
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="module" HelpText="Enter a name for this module. It should not contain spaces or punctuation." ResourceKey="ModuleName">Module Name: </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <input id="module" class="form-control" @bind="@_module" />
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="description" HelpText="Enter a short description for the module" ResourceKey="Description">Description: </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <textarea id="description" class="form-control" @bind="@_description" rows="3"></textarea>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="template" HelpText="Select a module template. Templates are located in the wwwroot/Modules/Templates folder on the server." ResourceKey="Template">Template: </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <select id="template" class="form-select" @onchange="(e => TemplateChanged(e))">
 | 
			
		||||
                    <option value="-"><@Localizer["Template.Select"]></option>
 | 
			
		||||
                    @foreach (Template template in _templates)
 | 
			
		||||
                    {
 | 
			
		||||
                        <option value="@template.Name">@template.Title</option>
 | 
			
		||||
                    }
 | 
			
		||||
                </select>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="reference" HelpText="Select a framework reference version" ResourceKey="FrameworkReference">Framework Reference: </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <select id="reference" class="form-select" @bind="@_reference">
 | 
			
		||||
                    @foreach (string version in _versions)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (Version.Parse(version).CompareTo(Version.Parse(_minversion)) >= 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            <option value="@(version)">@(version)</option>
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    <option value="local">@SharedLocalizer["LocalVersion"]</option>
 | 
			
		||||
                </select>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        @if (!string.IsNullOrEmpty(_location))
 | 
			
		||||
        {
 | 
			
		||||
    <form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
 | 
			
		||||
        <div class="container">
 | 
			
		||||
            <div class="row mb-1 align-items-center">
 | 
			
		||||
                <Label Class="col-sm-3" For="location" HelpText="Location where the module will be created" ResourceKey="Location">Location: </Label>
 | 
			
		||||
                <Label Class="col-sm-3" For="owner" HelpText="Enter the name of the organization who is developing this module. It should not contain spaces or punctuation." ResourceKey="OwnerName">Owner Name: </Label>
 | 
			
		||||
                <div class="col-sm-9">
 | 
			
		||||
                    <input id="module" class="form-control" @bind="@_location" readonly />
 | 
			
		||||
                    <input id="owner" class="form-control" @bind="@_owner" maxlength="256" required />
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        }
 | 
			
		||||
    </div>
 | 
			
		||||
    <button type="button" class="btn btn-success" @onclick="CreateModule">@Localizer["CreateModule"]</button>
 | 
			
		||||
    <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
 | 
			
		||||
            <div class="row mb-1 align-items-center">
 | 
			
		||||
                <Label Class="col-sm-3" For="module" HelpText="Enter a name for this module. It should not contain spaces or punctuation." ResourceKey="ModuleName">Module Name: </Label>
 | 
			
		||||
                <div class="col-sm-9">
 | 
			
		||||
                    <input id="module" class="form-control" @bind="@_module" maxlength="256" required />
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row mb-1 align-items-center">
 | 
			
		||||
                <Label Class="col-sm-3" For="description" HelpText="Enter a short description for the module" ResourceKey="Description">Description: </Label>
 | 
			
		||||
                <div class="col-sm-9">
 | 
			
		||||
                    <textarea id="description" class="form-control" @bind="@_description" rows="3" required></textarea>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row mb-1 align-items-center">
 | 
			
		||||
                <Label Class="col-sm-3" For="template" HelpText="Select a module template. Templates are located in the wwwroot/Modules/Templates folder on the server." ResourceKey="Template">Template: </Label>
 | 
			
		||||
                <div class="col-sm-9">
 | 
			
		||||
                    <select id="template" class="form-select" @onchange="(e => TemplateChanged(e))" required>
 | 
			
		||||
                        <option value="-"><@Localizer["Template.Select"]></option>
 | 
			
		||||
                        @foreach (Template template in _templates)
 | 
			
		||||
                        {
 | 
			
		||||
                            <option value="@template.Name">@template.Title</option>
 | 
			
		||||
                        }
 | 
			
		||||
                    </select>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row mb-1 align-items-center">
 | 
			
		||||
                <Label Class="col-sm-3" For="reference" HelpText="Select a framework reference version" ResourceKey="FrameworkReference">Framework Reference: </Label>
 | 
			
		||||
                <div class="col-sm-9">
 | 
			
		||||
                    <select id="reference" class="form-select" @bind="@_reference" required>
 | 
			
		||||
                        @foreach (string version in _versions)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (Version.Parse(version).CompareTo(Version.Parse(_minversion)) >= 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                <option value="@(version)">@(version)</option>
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        <option value="local">@SharedLocalizer["LocalVersion"]</option>
 | 
			
		||||
                    </select>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            @if (!string.IsNullOrEmpty(_location))
 | 
			
		||||
            {
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="location" HelpText="Location where the module will be created" ResourceKey="Location">Location: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <input id="module" class="form-control" @bind="@_location" readonly />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            }
 | 
			
		||||
        </div>
 | 
			
		||||
        <button type="button" class="btn btn-success" @onclick="CreateModule">@Localizer["CreateModule"]</button>
 | 
			
		||||
        <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
 | 
			
		||||
    </form>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
    private ElementReference form;
 | 
			
		||||
    private bool validated = false;
 | 
			
		||||
    private string _owner = string.Empty;
 | 
			
		||||
    private string _module = string.Empty;
 | 
			
		||||
    private string _description = string.Empty;
 | 
			
		||||
@ -99,23 +103,32 @@
 | 
			
		||||
 | 
			
		||||
    private async Task CreateModule()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        validated = true;
 | 
			
		||||
        var interop = new Interop(JSRuntime);
 | 
			
		||||
        if (await interop.FormValid(form))
 | 
			
		||||
        {
 | 
			
		||||
            if (IsValid(_owner) && IsValid(_module) && _owner != _module && _template != "-")
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference };
 | 
			
		||||
                moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition);
 | 
			
		||||
                GetLocation();
 | 
			
		||||
                AddModuleMessage(string.Format(Localizer["Success.Module.Create"], NavigateUrl("admin/system")), MessageType.Success);
 | 
			
		||||
                if (IsValid(_owner) && IsValid(_module) && _owner != _module && _template != "-")
 | 
			
		||||
                {
 | 
			
		||||
                    var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference };
 | 
			
		||||
                    moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition);
 | 
			
		||||
                    GetLocation();
 | 
			
		||||
                    AddModuleMessage(string.Format(Localizer["Success.Module.Create"], NavigateUrl("admin/system")), MessageType.Success);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    AddModuleMessage(Localizer["Message.Require.ValidName"], MessageType.Warning);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                AddModuleMessage(Localizer["Message.Require.ValidName"], MessageType.Warning);
 | 
			
		||||
                await logger.LogError(ex, "Error Creating Module");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            await logger.LogError(ex, "Error Creating Module");
 | 
			
		||||
            AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -5,90 +5,94 @@
 | 
			
		||||
@inject IStringLocalizer<Edit> Localizer
 | 
			
		||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
 | 
			
		||||
 | 
			
		||||
<TabStrip>
 | 
			
		||||
    <TabPanel Name="Definition" ResourceKey="Definition">
 | 
			
		||||
        <div class="container">
 | 
			
		||||
            <div class="row mb-1 align-items-center">
 | 
			
		||||
                <Label Class="col-sm-3" For="name" HelpText="The name of the module" ResourceKey="Name">Name: </Label>
 | 
			
		||||
                <div class="col-sm-9">
 | 
			
		||||
                    <input id="name" class="form-control" @bind="@_name" />
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row mb-1 align-items-center">
 | 
			
		||||
                <Label Class="col-sm-3" For="description" HelpText="The description of the module" ResourceKey="Description">Description: </Label>
 | 
			
		||||
                <div class="col-sm-9">
 | 
			
		||||
                    <textarea id="description" class="form-control" @bind="@_description" rows="2"></textarea>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row mb-1 align-items-center">
 | 
			
		||||
                <Label Class="col-sm-3" For="categories" HelpText="Comma delimited list of module categories" ResourceKey="Categories">Categories: </Label>
 | 
			
		||||
                <div class="col-sm-9">
 | 
			
		||||
                    <input id="categories" class="form-control" @bind="@_categories" />
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <Section Name="Information" ResourceKey="Information">
 | 
			
		||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
 | 
			
		||||
    <TabStrip>
 | 
			
		||||
        <TabPanel Name="Definition" ResourceKey="Definition">
 | 
			
		||||
            <div class="container">
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="moduledefinitionname" HelpText="The internal name of the module" ResourceKey="InternalName">Internal Name: </Label>
 | 
			
		||||
                    <Label Class="col-sm-3" For="name" HelpText="The name of the module" ResourceKey="Name">Name: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <input id="moduledefinitionname" class="form-control" @bind="@_moduledefinitionname" disabled />
 | 
			
		||||
                        <input id="name" class="form-control" @bind="@_name" maxlength="256" required />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="version" HelpText="The version of the module" ResourceKey="Version">Version: </Label>
 | 
			
		||||
                    <Label Class="col-sm-3" For="description" HelpText="The description of the module" ResourceKey="Description">Description: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <input id="version" class="form-control" @bind="@_version" disabled />
 | 
			
		||||
                        <textarea id="description" class="form-control" @bind="@_description" rows="2" required></textarea>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="owner" HelpText="The owner or creator of the module" ResourceKey="Owner">Owner: </Label>
 | 
			
		||||
                    <Label Class="col-sm-3" For="categories" HelpText="Comma delimited list of module categories" ResourceKey="Categories">Categories: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <input id="owner" class="form-control" @bind="@_owner" disabled />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="url" HelpText="The reference url of the module" ResourceKey="ReferenceUrl">Reference Url: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <input id="url" class="form-control" @bind="@_url" disabled />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="contact" HelpText="The contact for the module" ResourceKey="Contact">Contact: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <input id="contact" class="form-control" @bind="@_contact" disabled />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="license" HelpText="The module license terms" ResourceKey="License">License: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="runtimes" HelpText="The Blazor runtimes which this module supports" ResourceKey="Runtimes">Runtimes: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <input id="runtimes" class="form-control" @bind="@_runtimes" disabled />
 | 
			
		||||
                        <input id="categories" class="form-control" @bind="@_categories" required />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </Section>
 | 
			
		||||
    </TabPanel>
 | 
			
		||||
    <TabPanel Name="Permissions" ResourceKey="Permissions">
 | 
			
		||||
        <div class="container">
 | 
			
		||||
            <div class="row mb-1 align-items-center">
 | 
			
		||||
                <PermissionGrid EntityName="@EntityNames.ModuleDefinition" PermissionNames="@PermissionNames.Utilize" Permissions="@_permissions" @ref="_permissionGrid" />
 | 
			
		||||
            <Section Name="Information" ResourceKey="Information">
 | 
			
		||||
                <div class="container">
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="moduledefinitionname" HelpText="The internal name of the module" ResourceKey="InternalName">Internal Name: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="moduledefinitionname" class="form-control" @bind="@_moduledefinitionname" disabled />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="version" HelpText="The version of the module" ResourceKey="Version">Version: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="version" class="form-control" @bind="@_version" disabled />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="owner" HelpText="The owner or creator of the module" ResourceKey="Owner">Owner: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="owner" class="form-control" @bind="@_owner" disabled />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="url" HelpText="The reference url of the module" ResourceKey="ReferenceUrl">Reference Url: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="url" class="form-control" @bind="@_url" disabled />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="contact" HelpText="The contact for the module" ResourceKey="Contact">Contact: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="contact" class="form-control" @bind="@_contact" disabled />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="license" HelpText="The module license terms" ResourceKey="License">License: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="runtimes" HelpText="The Blazor runtimes which this module supports" ResourceKey="Runtimes">Runtimes: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="runtimes" class="form-control" @bind="@_runtimes" disabled />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </Section>
 | 
			
		||||
        </TabPanel>
 | 
			
		||||
        <TabPanel Name="Permissions" ResourceKey="Permissions">
 | 
			
		||||
            <div class="container">
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <PermissionGrid EntityName="@EntityNames.ModuleDefinition" PermissionNames="@PermissionNames.Utilize" Permissions="@_permissions" @ref="_permissionGrid" />
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </TabPanel>
 | 
			
		||||
</TabStrip>
 | 
			
		||||
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@SharedLocalizer["Save"]</button>
 | 
			
		||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
 | 
			
		||||
<br />
 | 
			
		||||
<br />
 | 
			
		||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
 | 
			
		||||
        </TabPanel>
 | 
			
		||||
    </TabStrip>
 | 
			
		||||
    <button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@SharedLocalizer["Save"]</button>
 | 
			
		||||
    <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
 | 
			
		||||
    <br />
 | 
			
		||||
    <br />
 | 
			
		||||
    <AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
    private ElementReference form;
 | 
			
		||||
    private bool validated = false;
 | 
			
		||||
    private int _moduleDefinitionId;
 | 
			
		||||
    private string _name;
 | 
			
		||||
    private string _version;
 | 
			
		||||
@ -146,30 +150,39 @@
 | 
			
		||||
 | 
			
		||||
    private async Task SaveModuleDefinition()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        validated = true;
 | 
			
		||||
        var interop = new Interop(JSRuntime);
 | 
			
		||||
        if (await interop.FormValid(form))
 | 
			
		||||
        {
 | 
			
		||||
            var moduledefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId);
 | 
			
		||||
            if (moduledefinition.Name != _name)
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                moduledefinition.Name = _name;
 | 
			
		||||
                var moduledefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId);
 | 
			
		||||
                if (moduledefinition.Name != _name)
 | 
			
		||||
                {
 | 
			
		||||
                    moduledefinition.Name = _name;
 | 
			
		||||
                }
 | 
			
		||||
                if (moduledefinition.Description != _description)
 | 
			
		||||
                {
 | 
			
		||||
                    moduledefinition.Description = _description;
 | 
			
		||||
                }
 | 
			
		||||
                if (moduledefinition.Categories != _categories)
 | 
			
		||||
                {
 | 
			
		||||
                    moduledefinition.Categories = _categories;
 | 
			
		||||
                }
 | 
			
		||||
                moduledefinition.Permissions = _permissionGrid.GetPermissions();
 | 
			
		||||
                await ModuleDefinitionService.UpdateModuleDefinitionAsync(moduledefinition);
 | 
			
		||||
                await logger.LogInformation("ModuleDefinition Saved {ModuleDefinition}", moduledefinition);
 | 
			
		||||
                NavigationManager.NavigateTo(NavigateUrl());
 | 
			
		||||
            }
 | 
			
		||||
            if (moduledefinition.Description != _description)
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                moduledefinition.Description = _description;
 | 
			
		||||
                await logger.LogError(ex, "Error Saving ModuleDefinition {ModuleDefinitionId} {Error}", _moduleDefinitionId, ex.Message);
 | 
			
		||||
                AddModuleMessage(Localizer["Error.Module.Save"], MessageType.Error);
 | 
			
		||||
            }
 | 
			
		||||
            if (moduledefinition.Categories != _categories)
 | 
			
		||||
            {
 | 
			
		||||
                moduledefinition.Categories = _categories;
 | 
			
		||||
            }
 | 
			
		||||
            moduledefinition.Permissions = _permissionGrid.GetPermissions();
 | 
			
		||||
            await ModuleDefinitionService.UpdateModuleDefinitionAsync(moduledefinition);
 | 
			
		||||
            await logger.LogInformation("ModuleDefinition Saved {ModuleDefinition}", moduledefinition);
 | 
			
		||||
            NavigationManager.NavigateTo(NavigateUrl());
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            await logger.LogError(ex, "Error Saving ModuleDefinition {ModuleDefinitionId} {Error}", _moduleDefinitionId, ex.Message);
 | 
			
		||||
            AddModuleMessage(Localizer["Error.Module.Save"], MessageType.Error);
 | 
			
		||||
            AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,28 +5,39 @@
 | 
			
		||||
@inject IStringLocalizer<Export> Localizer
 | 
			
		||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
 | 
			
		||||
 | 
			
		||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
 | 
			
		||||
    <div class="container">
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="content" HelpText="Enter the module content" ResourceKey="Content">Content: </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <textarea id="content" class="form-control" @bind="@_content" rows="5"></textarea>
 | 
			
		||||
                <textarea id="content" class="form-control" @bind="@_content" rows="5" required></textarea>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <button type="button" class="btn btn-success" @onclick="ExportModule">@Localizer["Export"]</button>
 | 
			
		||||
    <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
    private ElementReference form;
 | 
			
		||||
    private bool validated = false;
 | 
			
		||||
    private string _content = string.Empty;
 | 
			
		||||
    public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
 | 
			
		||||
    public override string Title => "Export Content";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @code {
 | 
			
		||||
        private string _content = string.Empty;
 | 
			
		||||
 | 
			
		||||
        public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
 | 
			
		||||
        public override string Title => "Export Content";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        private async Task ExportModule()
 | 
			
		||||
    private async Task ExportModule()
 | 
			
		||||
    {
 | 
			
		||||
        validated = true;
 | 
			
		||||
        var interop = new Interop(JSRuntime);
 | 
			
		||||
        if (await interop.FormValid(form))
 | 
			
		||||
        {
 | 
			
		||||
            _content = await ModuleService.ExportModuleAsync(ModuleState.ModuleId);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@
 | 
			
		||||
@inject IStringLocalizer<Import> Localizer
 | 
			
		||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
 | 
			
		||||
 | 
			
		||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
 | 
			
		||||
    <div class="container">
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="content" HelpText="Enter the module content" ResourceKey="Content">Content: </Label>
 | 
			
		||||
@ -17,15 +18,21 @@
 | 
			
		||||
 | 
			
		||||
    <button type="button" class="btn btn-success" @onclick="ImportModule">@Localizer["Import"]</button>
 | 
			
		||||
    <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
    private string _content = string.Empty;
 | 
			
		||||
    private ElementReference form;
 | 
			
		||||
    private bool validated = false;
 | 
			
		||||
 | 
			
		||||
    @code {
 | 
			
		||||
        private string _content = string.Empty;
 | 
			
		||||
    public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
 | 
			
		||||
    public override string Title => "Import Content";
 | 
			
		||||
 | 
			
		||||
        public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
 | 
			
		||||
        public override string Title => "Import Content";
 | 
			
		||||
 | 
			
		||||
        private async Task ImportModule()
 | 
			
		||||
    private async Task ImportModule()
 | 
			
		||||
    {
 | 
			
		||||
        validated = true;
 | 
			
		||||
        var interop = new Interop(JSRuntime);
 | 
			
		||||
        if (await interop.FormValid(form))
 | 
			
		||||
        {
 | 
			
		||||
            if (_content != string.Empty)
 | 
			
		||||
            {
 | 
			
		||||
@ -52,4 +59,9 @@
 | 
			
		||||
                AddModuleMessage(Localizer["Message.Required.ImportContent"], MessageType.Warning);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -8,88 +8,92 @@
 | 
			
		||||
@inject IStringLocalizer<Settings> Localizer
 | 
			
		||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
 | 
			
		||||
 | 
			
		||||
<TabStrip>
 | 
			
		||||
    <TabPanel Name="Settings" Heading="Settings" ResourceKey="Settings">
 | 
			
		||||
        @if (_containers != null)
 | 
			
		||||
        {
 | 
			
		||||
        <div class="container">
 | 
			
		||||
            <div class="row mb-1 align-items-center">
 | 
			
		||||
                <Label Class="col-sm-3" For="title" HelpText="Enter the title of the module" ResourceKey="Title">Title: </Label>
 | 
			
		||||
                <div class="col-sm-9">
 | 
			
		||||
                    <input id="title" type="text" name="Title" class="form-control" @bind="@_title" />
 | 
			
		||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
 | 
			
		||||
    <TabStrip>
 | 
			
		||||
        <TabPanel Name="Settings" Heading="Settings" ResourceKey="Settings">
 | 
			
		||||
            @if (_containers != null)
 | 
			
		||||
            {
 | 
			
		||||
                <div class="container">
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="title" HelpText="Enter the title of the module" ResourceKey="Title">Title: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="title" type="text" name="Title" class="form-control" @bind="@_title" required />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="container" HelpText="Select the module's container" ResourceKey="Container">Container: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <select id="container" class="form-select" @bind="@_containerType" required>
 | 
			
		||||
                                @foreach (var container in _containers)
 | 
			
		||||
                                {
 | 
			
		||||
                                    <option value="@container.TypeName">@container.Name</option>
 | 
			
		||||
                                }
 | 
			
		||||
                            </select>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="allpages" HelpText="Indicate if this module should be displayed on all pages" ResourceKey="DisplayOnAllPages">Display On All Pages? </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <select id="allpages" class="form-select" @bind="@_allPages" required>
 | 
			
		||||
                                <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                                <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
                            </select>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="page" HelpText="The page that the module is located on" ResourceKey="Page">Page: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <select id="page" class="form-select" @bind="@_pageId" required>
 | 
			
		||||
                                @foreach (Page p in PageState.Pages)
 | 
			
		||||
                                {
 | 
			
		||||
                                    if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
 | 
			
		||||
                                    {
 | 
			
		||||
                                        <option value="@p.PageId">@(new string('-', p.Level * 2))@(p.Name)</option>
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            </select>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row mb-1 align-items-center">
 | 
			
		||||
                <Label Class="col-sm-3" For="container" HelpText="Select the module's container" ResourceKey="Container">Container: </Label>
 | 
			
		||||
                <div class="col-sm-9">
 | 
			
		||||
                    <select id="container" class="form-select" @bind="@_containerType">
 | 
			
		||||
                        @foreach (var container in _containers)
 | 
			
		||||
                        {
 | 
			
		||||
                            <option value="@container.TypeName">@container.Name</option>
 | 
			
		||||
                        }
 | 
			
		||||
                    </select>
 | 
			
		||||
            }
 | 
			
		||||
        </TabPanel>
 | 
			
		||||
        <TabPanel Name="Permissions" ResourceKey="Permissions">
 | 
			
		||||
            @if (_permissions != null)
 | 
			
		||||
            {
 | 
			
		||||
                <div class="container">
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <PermissionGrid EntityName="@EntityNames.Module" PermissionNames="@_permissionNames" Permissions="@_permissions" @ref="_permissionGrid" />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row mb-1 align-items-center">
 | 
			
		||||
                <Label Class="col-sm-3" For="allpages" HelpText="Indicate if this module should be displayed on all pages" ResourceKey="DisplayOnAllPages">Display On All Pages? </Label>
 | 
			
		||||
                <div class="col-sm-9">
 | 
			
		||||
                    <select id="allpages" class="form-select" @bind="@_allPages">
 | 
			
		||||
                        <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                        <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
                    </select>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row mb-1 align-items-center">
 | 
			
		||||
                <Label Class="col-sm-3" For="page" HelpText="The page that the module is located on" ResourceKey="Page">Page: </Label>
 | 
			
		||||
                <div class="col-sm-9">
 | 
			
		||||
                    <select id="page" class="form-select" @bind="@_pageId">
 | 
			
		||||
                        @foreach (Page p in PageState.Pages)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
 | 
			
		||||
                            {
 | 
			
		||||
                                <option value="@p.PageId">@(new string('-', p.Level * 2))@(p.Name)</option>
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    </select>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        }
 | 
			
		||||
    </TabPanel>
 | 
			
		||||
    <TabPanel Name="Permissions" ResourceKey="Permissions">
 | 
			
		||||
        @if (_permissions != null)
 | 
			
		||||
        {
 | 
			
		||||
            <div class="container">
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <PermissionGrid EntityName="@EntityNames.Module" PermissionNames="@_permissionNames" Permissions="@_permissions" @ref="_permissionGrid" />
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        </TabPanel>
 | 
			
		||||
        @if (_moduleSettingsType != null)
 | 
			
		||||
        {
 | 
			
		||||
            <TabPanel Name="ModuleSettings" Heading="@_moduleSettingsTitle" ResourceKey="ModuleSettings">
 | 
			
		||||
                @ModuleSettingsComponent
 | 
			
		||||
            </TabPanel>
 | 
			
		||||
        }
 | 
			
		||||
    </TabPanel>
 | 
			
		||||
    @if (_moduleSettingsType != null)
 | 
			
		||||
    {
 | 
			
		||||
        <TabPanel Name="ModuleSettings" Heading="@_moduleSettingsTitle" ResourceKey="ModuleSettings">
 | 
			
		||||
            @ModuleSettingsComponent
 | 
			
		||||
        </TabPanel>
 | 
			
		||||
    }
 | 
			
		||||
    @if (_containerSettingsType != null)
 | 
			
		||||
    {
 | 
			
		||||
        <TabPanel Name="ContainerSettings" Heading="Container Settings" ResourceKey="ContainerSettings">
 | 
			
		||||
            @ContainerSettingsComponent
 | 
			
		||||
        </TabPanel>
 | 
			
		||||
    }
 | 
			
		||||
</TabStrip>
 | 
			
		||||
<button type="button" class="btn btn-success" @onclick="SaveModule">@SharedLocalizer["Save"]</button>
 | 
			
		||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
 | 
			
		||||
<br />
 | 
			
		||||
<br />
 | 
			
		||||
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
 | 
			
		||||
        @if (_containerSettingsType != null)
 | 
			
		||||
        {
 | 
			
		||||
            <TabPanel Name="ContainerSettings" Heading="Container Settings" ResourceKey="ContainerSettings">
 | 
			
		||||
                @ContainerSettingsComponent
 | 
			
		||||
            </TabPanel>
 | 
			
		||||
        }
 | 
			
		||||
    </TabStrip>
 | 
			
		||||
    <button type="button" class="btn btn-success" @onclick="SaveModule">@SharedLocalizer["Save"]</button>
 | 
			
		||||
    <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
 | 
			
		||||
    <br />
 | 
			
		||||
    <br />
 | 
			
		||||
    <AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
    public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
 | 
			
		||||
    public override string Title => "Module Settings";
 | 
			
		||||
 | 
			
		||||
    private ElementReference form;
 | 
			
		||||
    private bool validated = false;
 | 
			
		||||
    private List<Theme> _themes;
 | 
			
		||||
    private List<ThemeControl> _containers = new List<ThemeControl>();
 | 
			
		||||
    private string _title;
 | 
			
		||||
@ -170,52 +174,61 @@
 | 
			
		||||
 | 
			
		||||
    private async Task SaveModule()
 | 
			
		||||
    {
 | 
			
		||||
        if (!string.IsNullOrEmpty(_title))
 | 
			
		||||
        validated = true;
 | 
			
		||||
        var interop = new Interop(JSRuntime);
 | 
			
		||||
        if (await interop.FormValid(form))
 | 
			
		||||
        {
 | 
			
		||||
            var pagemodule = await PageModuleService.GetPageModuleAsync(ModuleState.PageModuleId);
 | 
			
		||||
            pagemodule.PageId = int.Parse(_pageId);
 | 
			
		||||
            pagemodule.Title = _title;
 | 
			
		||||
            pagemodule.ContainerType = (_containerType != "-") ? _containerType : string.Empty;
 | 
			
		||||
            if (!string.IsNullOrEmpty(pagemodule.ContainerType) && pagemodule.ContainerType == PageState.Page.DefaultContainerType)
 | 
			
		||||
            if (!string.IsNullOrEmpty(_title))
 | 
			
		||||
            {
 | 
			
		||||
                pagemodule.ContainerType = string.Empty;
 | 
			
		||||
            }
 | 
			
		||||
            if (!string.IsNullOrEmpty(pagemodule.ContainerType) && pagemodule.ContainerType == PageState.Site.DefaultContainerType)
 | 
			
		||||
            {
 | 
			
		||||
                pagemodule.ContainerType = string.Empty;
 | 
			
		||||
            }
 | 
			
		||||
            await PageModuleService.UpdatePageModuleAsync(pagemodule);
 | 
			
		||||
            await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, pagemodule.Pane);
 | 
			
		||||
 | 
			
		||||
            var module = ModuleState;
 | 
			
		||||
            module.AllPages = bool.Parse(_allPages);
 | 
			
		||||
            module.Permissions = _permissionGrid.GetPermissions();
 | 
			
		||||
            await ModuleService.UpdateModuleAsync(module);
 | 
			
		||||
 | 
			
		||||
            if (_moduleSettingsType != null)
 | 
			
		||||
            {
 | 
			
		||||
                if (_moduleSettings is ISettingsControl moduleSettingsControl)
 | 
			
		||||
                var pagemodule = await PageModuleService.GetPageModuleAsync(ModuleState.PageModuleId);
 | 
			
		||||
                pagemodule.PageId = int.Parse(_pageId);
 | 
			
		||||
                pagemodule.Title = _title;
 | 
			
		||||
                pagemodule.ContainerType = (_containerType != "-") ? _containerType : string.Empty;
 | 
			
		||||
                if (!string.IsNullOrEmpty(pagemodule.ContainerType) && pagemodule.ContainerType == PageState.Page.DefaultContainerType)
 | 
			
		||||
                {
 | 
			
		||||
                    // module settings updated using explicit interface
 | 
			
		||||
                    await moduleSettingsControl.UpdateSettings();
 | 
			
		||||
                    pagemodule.ContainerType = string.Empty;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                if (!string.IsNullOrEmpty(pagemodule.ContainerType) && pagemodule.ContainerType == PageState.Site.DefaultContainerType)
 | 
			
		||||
                {
 | 
			
		||||
                    // legacy support - module settings updated by convention ( ie. by calling a public method named "UpdateSettings" in settings component )
 | 
			
		||||
                    _moduleSettings?.GetType().GetMethod("UpdateSettings")?.Invoke(_moduleSettings, null);
 | 
			
		||||
                    pagemodule.ContainerType = string.Empty;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
                await PageModuleService.UpdatePageModuleAsync(pagemodule);
 | 
			
		||||
                await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, pagemodule.Pane);
 | 
			
		||||
 | 
			
		||||
            if (_containerSettingsType != null && _containerSettings is ISettingsControl containerSettingsControl)
 | 
			
		||||
                var module = ModuleState;
 | 
			
		||||
                module.AllPages = bool.Parse(_allPages);
 | 
			
		||||
                module.Permissions = _permissionGrid.GetPermissions();
 | 
			
		||||
                await ModuleService.UpdateModuleAsync(module);
 | 
			
		||||
 | 
			
		||||
                if (_moduleSettingsType != null)
 | 
			
		||||
                {
 | 
			
		||||
                    if (_moduleSettings is ISettingsControl moduleSettingsControl)
 | 
			
		||||
                    {
 | 
			
		||||
                        // module settings updated using explicit interface
 | 
			
		||||
                        await moduleSettingsControl.UpdateSettings();
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        // legacy support - module settings updated by convention ( ie. by calling a public method named "UpdateSettings" in settings component )
 | 
			
		||||
                        _moduleSettings?.GetType().GetMethod("UpdateSettings")?.Invoke(_moduleSettings, null);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (_containerSettingsType != null && _containerSettings is ISettingsControl containerSettingsControl)
 | 
			
		||||
                {
 | 
			
		||||
                    await containerSettingsControl.UpdateSettings();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                NavigationManager.NavigateTo(NavigateUrl());
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                await containerSettingsControl.UpdateSettings();
 | 
			
		||||
                AddModuleMessage(Localizer["Message.Required.Title"], MessageType.Warning);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            NavigationManager.NavigateTo(NavigateUrl());
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            AddModuleMessage(Localizer["Message.Required.Title"], MessageType.Warning);
 | 
			
		||||
            AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,151 +6,154 @@
 | 
			
		||||
@inject IStringLocalizer<Add> Localizer
 | 
			
		||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
 | 
			
		||||
 | 
			
		||||
<TabStrip Refresh="@_refresh">
 | 
			
		||||
    <TabPanel Name="Settings" ResourceKey="Settings">
 | 
			
		||||
        @if (_themeList != null)
 | 
			
		||||
        {
 | 
			
		||||
            <div class="container">
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="Name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <input id="Name" class="form-control" @bind="@_name" />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="Parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <select id="Parent" class="form-select" @onchange="(e => ParentChanged(e))">
 | 
			
		||||
                            <option value="-1"><@Localizer["SiteRoot"]></option>
 | 
			
		||||
                            @foreach (Page page in _pageList)
 | 
			
		||||
                            {
 | 
			
		||||
                                <option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
 | 
			
		||||
                            }
 | 
			
		||||
                        </select>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="Insert" HelpText="Select the location where you would like the page to be inserted in relation to other pages" ResourceKey="Insert">Insert: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <select id="Insert" class="form-select" @bind="@_insert">
 | 
			
		||||
                            <option value="<<">@Localizer["AtBeginning"]</option>
 | 
			
		||||
                            @if (_children != null && _children.Count > 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                <option value="<">@Localizer["Before"]</option>
 | 
			
		||||
                                <option value=">">@Localizer["After"]</option>
 | 
			
		||||
                            }
 | 
			
		||||
                            <option value=">>">@Localizer["AtEnd"]</option>
 | 
			
		||||
                        </select>
 | 
			
		||||
                        @if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">"))
 | 
			
		||||
                        {
 | 
			
		||||
                            <select class="form-select" @bind="@_childid">
 | 
			
		||||
                                <option value="-1"><@Localizer["Page.Select"]></option>
 | 
			
		||||
                                @foreach (Page page in _children)
 | 
			
		||||
                                {
 | 
			
		||||
                                    <option value="@(page.PageId)">@(page.Name)</option>
 | 
			
		||||
                                }
 | 
			
		||||
                            </select>
 | 
			
		||||
                        }
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <select id="navigation" class="form-select" @bind="@_isnavigation">
 | 
			
		||||
                            <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                            <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
                        </select>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="clickable" HelpText="Select whether the link in the site navigation is enabled or disabled" ResourceKey="Clickable">Clickable? </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <select id="clickable" class="form-select" @bind="@_isclickable">
 | 
			
		||||
                            <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                            <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
                        </select>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="Path" HelpText="Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used." ResourceKey="UrlPath">Url Path: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <input id="Path" class="form-control" @bind="@_path" />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="Url" HelpText="Optionally enter a url which this page should redirect to when a user navigates to it" ResourceKey="Redirect">Redirect: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <input id="Url" class="form-control" @bind="@_url" />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <Section Name="Appearance" ResourceKey="Appearance">
 | 
			
		||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
 | 
			
		||||
    <TabStrip Refresh="@_refresh">
 | 
			
		||||
        <TabPanel Name="Settings" ResourceKey="Settings">
 | 
			
		||||
            @if (_themeList != null)
 | 
			
		||||
            {
 | 
			
		||||
                <div class="container">
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="Title" HelpText="Optionally enter the page title. If you do not provide a page title, the page name will be used." ResourceKey="Title">Title: </Label>
 | 
			
		||||
                        <Label Class="col-sm-3" For="Name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="Title" class="form-control" @bind="@_title" />
 | 
			
		||||
                            <input id="Name" class="form-control" @bind="@_name" required />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="Theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
 | 
			
		||||
                        <Label Class="col-sm-3" For="Parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <select id="Theme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))">
 | 
			
		||||
                                @foreach (var theme in _themes)
 | 
			
		||||
                            <select id="Parent" class="form-select" @onchange="(e => ParentChanged(e))" required>
 | 
			
		||||
                                <option value="-1"><@Localizer["SiteRoot"]></option>
 | 
			
		||||
                                @foreach (Page page in _pageList)
 | 
			
		||||
                                {
 | 
			
		||||
                                    <option value="@theme.TypeName">@theme.Name</option>
 | 
			
		||||
                                    <option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
 | 
			
		||||
                                }
 | 
			
		||||
                            </select>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="defaultContainer" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
 | 
			
		||||
                        <Label Class="col-sm-3" For="Insert" HelpText="Select the location where you would like the page to be inserted in relation to other pages" ResourceKey="Insert">Insert: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <select id="defaultContainer" class="form-select" @bind="@_containertype">
 | 
			
		||||
                                <option value="-"><@Localizer["Container.Select"]></option>
 | 
			
		||||
                                @foreach (var container in _containers)
 | 
			
		||||
                            <select id="Insert" class="form-select" @bind="@_insert" required>
 | 
			
		||||
                                <option value="<<">@Localizer["AtBeginning"]</option>
 | 
			
		||||
                                @if (_children != null && _children.Count > 0)
 | 
			
		||||
                                {
 | 
			
		||||
                                    <option value="@container.TypeName">@container.Name</option>
 | 
			
		||||
                                    <option value="<">@Localizer["Before"]</option>
 | 
			
		||||
                                    <option value=">">@Localizer["After"]</option>
 | 
			
		||||
                                }
 | 
			
		||||
                                <option value=">>">@Localizer["AtEnd"]</option>
 | 
			
		||||
                            </select>
 | 
			
		||||
                            @if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">"))
 | 
			
		||||
                            {
 | 
			
		||||
                                <select class="form-select" @bind="@_childid">
 | 
			
		||||
                                    <option value="-1"><@Localizer["Page.Select"]></option>
 | 
			
		||||
                                    @foreach (Page page in _children)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        <option value="@(page.PageId)">@(page.Name)</option>
 | 
			
		||||
                                    }
 | 
			
		||||
                                </select>
 | 
			
		||||
                            }
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="Icon" HelpText="Optionally provide an icon class name for this page which will be displayed in the site navigation" ResourceKey="Icon">Icon: </Label>
 | 
			
		||||
                        <Label Class="col-sm-3" For="navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="Icon" class="form-control" @bind="@_icon" />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content" ResourceKey="Personalizable">Personalizable? </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <select id="Personalizable" class="form-select" @bind="@_ispersonalizable">
 | 
			
		||||
                            <select id="navigation" class="form-select" @bind="@_isnavigation" required>
 | 
			
		||||
                                <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                                <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
                            </select>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="clickable" HelpText="Select whether the link in the site navigation is enabled or disabled" ResourceKey="Clickable">Clickable? </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <select id="clickable" class="form-select" @bind="@_isclickable" required>
 | 
			
		||||
                                <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                                <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
                            </select>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="Path" HelpText="Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used." ResourceKey="UrlPath">Url Path: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="Path" class="form-control" @bind="@_path" />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="Url" HelpText="Optionally enter a url which this page should redirect to when a user navigates to it" ResourceKey="Redirect">Redirect: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="Url" class="form-control" @bind="@_url" />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </Section>
 | 
			
		||||
        }
 | 
			
		||||
    </TabPanel>
 | 
			
		||||
    <TabPanel Name="Permissions" ResourceKey="Permissions">
 | 
			
		||||
        <div class="container">
 | 
			
		||||
            <div class="row mb-1 align-items-center">
 | 
			
		||||
                <PermissionGrid EntityName="@EntityNames.Page" Permissions="@_permissions" @ref="_permissionGrid" />
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </TabPanel>
 | 
			
		||||
    @if (_themeSettingsType != null)
 | 
			
		||||
    {
 | 
			
		||||
        <TabPanel Name="ThemeSettings" Heading="Theme Settings" ResourceKey="ThemeSettings">
 | 
			
		||||
            @ThemeSettingsComponent
 | 
			
		||||
 | 
			
		||||
                <Section Name="Appearance" ResourceKey="Appearance">
 | 
			
		||||
                    <div class="container">
 | 
			
		||||
                        <div class="row mb-1 align-items-center">
 | 
			
		||||
                            <Label Class="col-sm-3" For="Title" HelpText="Optionally enter the page title. If you do not provide a page title, the page name will be used." ResourceKey="Title">Title: </Label>
 | 
			
		||||
                            <div class="col-sm-9">
 | 
			
		||||
                                <input id="Title" class="form-control" @bind="@_title" />
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="row mb-1 align-items-center">
 | 
			
		||||
                            <Label Class="col-sm-3" For="Theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
 | 
			
		||||
                            <div class="col-sm-9">
 | 
			
		||||
                                <select id="Theme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))" required>
 | 
			
		||||
                                    @foreach (var theme in _themes)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        <option value="@theme.TypeName">@theme.Name</option>
 | 
			
		||||
                                    }
 | 
			
		||||
                                </select>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="row mb-1 align-items-center">
 | 
			
		||||
                            <Label Class="col-sm-3" For="defaultContainer" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
 | 
			
		||||
                            <div class="col-sm-9">
 | 
			
		||||
                                <select id="defaultContainer" class="form-select" @bind="@_containertype" required>
 | 
			
		||||
                                    <option value="-"><@Localizer["Container.Select"]></option>
 | 
			
		||||
                                    @foreach (var container in _containers)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        <option value="@container.TypeName">@container.Name</option>
 | 
			
		||||
                                    }
 | 
			
		||||
                                </select>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="row mb-1 align-items-center">
 | 
			
		||||
                            <Label Class="col-sm-3" For="Icon" HelpText="Optionally provide an icon class name for this page which will be displayed in the site navigation" ResourceKey="Icon">Icon: </Label>
 | 
			
		||||
                            <div class="col-sm-9">
 | 
			
		||||
                                <input id="Icon" class="form-control" @bind="@_icon" />
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="row mb-1 align-items-center">
 | 
			
		||||
                            <Label Class="col-sm-3" For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content" ResourceKey="Personalizable">Personalizable? </Label>
 | 
			
		||||
                            <div class="col-sm-9">
 | 
			
		||||
                                <select id="Personalizable" class="form-select" @bind="@_ispersonalizable" required>
 | 
			
		||||
                                    <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                                    <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
                                </select>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </Section>
 | 
			
		||||
            }
 | 
			
		||||
        </TabPanel>
 | 
			
		||||
    }
 | 
			
		||||
</TabStrip>
 | 
			
		||||
<button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button>
 | 
			
		||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
 | 
			
		||||
        <TabPanel Name="Permissions" ResourceKey="Permissions">
 | 
			
		||||
            <div class="container">
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <PermissionGrid EntityName="@EntityNames.Page" Permissions="@_permissions" @ref="_permissionGrid" />
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </TabPanel>
 | 
			
		||||
        @if (_themeSettingsType != null)
 | 
			
		||||
        {
 | 
			
		||||
            <TabPanel Name="ThemeSettings" Heading="Theme Settings" ResourceKey="ThemeSettings">
 | 
			
		||||
                @ThemeSettingsComponent
 | 
			
		||||
            </TabPanel>
 | 
			
		||||
        }
 | 
			
		||||
    </TabStrip>
 | 
			
		||||
    <button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button>
 | 
			
		||||
    <button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
    public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
 | 
			
		||||
@ -179,6 +182,8 @@
 | 
			
		||||
    private object _themeSettings;
 | 
			
		||||
    private RenderFragment ThemeSettingsComponent { get; set; }
 | 
			
		||||
    private bool _refresh = false;
 | 
			
		||||
    private ElementReference form;
 | 
			
		||||
    private bool validated = false;
 | 
			
		||||
 | 
			
		||||
    protected override async Task OnInitializedAsync()
 | 
			
		||||
    {
 | 
			
		||||
@ -275,110 +280,119 @@
 | 
			
		||||
 | 
			
		||||
    private async Task SavePage()
 | 
			
		||||
    {
 | 
			
		||||
        Page page = null;
 | 
			
		||||
        try
 | 
			
		||||
        validated = true;
 | 
			
		||||
        var interop = new Interop(JSRuntime);
 | 
			
		||||
        if (await interop.FormValid(form))
 | 
			
		||||
        {
 | 
			
		||||
            if (!string.IsNullOrEmpty(_name) && !string.IsNullOrEmpty(_themetype) && _containertype != "-")
 | 
			
		||||
            Page page = null;
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                page = new Page();
 | 
			
		||||
                page.SiteId = PageState.Page.SiteId;
 | 
			
		||||
                page.Name = _name;
 | 
			
		||||
                page.Title = _title;
 | 
			
		||||
                if (_path == "")
 | 
			
		||||
                if (!string.IsNullOrEmpty(_name) && !string.IsNullOrEmpty(_themetype) && _containertype != "-")
 | 
			
		||||
                {
 | 
			
		||||
                    _path = _name;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (_path.Contains("/"))
 | 
			
		||||
                {
 | 
			
		||||
                    _path = _path.Substring(_path.LastIndexOf("/") + 1);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (string.IsNullOrEmpty(_parentid))
 | 
			
		||||
                {
 | 
			
		||||
                    page.ParentId = null;
 | 
			
		||||
                    page.Path = Utilities.GetFriendlyUrl(_path);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    page.ParentId = Int32.Parse(_parentid);
 | 
			
		||||
                    var parent = PageState.Pages.Where(item => item.PageId == page.ParentId).FirstOrDefault();
 | 
			
		||||
                    if (parent.Path == string.Empty)
 | 
			
		||||
                    page = new Page();
 | 
			
		||||
                    page.SiteId = PageState.Page.SiteId;
 | 
			
		||||
                    page.Name = _name;
 | 
			
		||||
                    page.Title = _title;
 | 
			
		||||
                    if (_path == "")
 | 
			
		||||
                    {
 | 
			
		||||
                        page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path);
 | 
			
		||||
                        _path = _name;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (_path.Contains("/"))
 | 
			
		||||
                    {
 | 
			
		||||
                        _path = _path.Substring(_path.LastIndexOf("/") + 1);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (string.IsNullOrEmpty(_parentid))
 | 
			
		||||
                    {
 | 
			
		||||
                        page.ParentId = null;
 | 
			
		||||
                        page.Path = Utilities.GetFriendlyUrl(_path);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
 | 
			
		||||
                        page.ParentId = Int32.Parse(_parentid);
 | 
			
		||||
                        var parent = PageState.Pages.Where(item => item.PageId == page.ParentId).FirstOrDefault();
 | 
			
		||||
                        if (parent.Path == string.Empty)
 | 
			
		||||
                        {
 | 
			
		||||
                            page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path);
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (!PagePathIsUnique(page.Path, page.SiteId, _pageList))
 | 
			
		||||
                {
 | 
			
		||||
                    AddModuleMessage(string.Format(Localizer["Message.Page.Exists"], _path), MessageType.Warning);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                    if (!PagePathIsUnique(page.Path, page.SiteId, _pageList))
 | 
			
		||||
                    {
 | 
			
		||||
                        AddModuleMessage(string.Format(Localizer["Message.Page.Exists"], _path), MessageType.Warning);
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                Page child;
 | 
			
		||||
                switch (_insert)
 | 
			
		||||
                {
 | 
			
		||||
                    case "<<":
 | 
			
		||||
                        page.Order = 0;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case "<":
 | 
			
		||||
                        child = PageState.Pages.Where(item => item.PageId == _childid).FirstOrDefault();
 | 
			
		||||
                        page.Order = child.Order - 1;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case ">":
 | 
			
		||||
                        child = PageState.Pages.Where(item => item.PageId == _childid).FirstOrDefault();
 | 
			
		||||
                        page.Order = child.Order + 1;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case ">>":
 | 
			
		||||
                        page.Order = int.MaxValue;
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
                    Page child;
 | 
			
		||||
                    switch (_insert)
 | 
			
		||||
                    {
 | 
			
		||||
                        case "<<":
 | 
			
		||||
                            page.Order = 0;
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "<":
 | 
			
		||||
                            child = PageState.Pages.Where(item => item.PageId == _childid).FirstOrDefault();
 | 
			
		||||
                            page.Order = child.Order - 1;
 | 
			
		||||
                            break;
 | 
			
		||||
                        case ">":
 | 
			
		||||
                            child = PageState.Pages.Where(item => item.PageId == _childid).FirstOrDefault();
 | 
			
		||||
                            page.Order = child.Order + 1;
 | 
			
		||||
                            break;
 | 
			
		||||
                        case ">>":
 | 
			
		||||
                            page.Order = int.MaxValue;
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
 | 
			
		||||
                page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
 | 
			
		||||
                page.Url = _url;
 | 
			
		||||
                page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
 | 
			
		||||
                if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
 | 
			
		||||
                {
 | 
			
		||||
                    page.ThemeType = string.Empty;
 | 
			
		||||
                }
 | 
			
		||||
                page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty;
 | 
			
		||||
                if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType)
 | 
			
		||||
                {
 | 
			
		||||
                    page.DefaultContainerType = string.Empty;
 | 
			
		||||
                }
 | 
			
		||||
                page.Icon = (_icon == null ? string.Empty : _icon);
 | 
			
		||||
                page.Permissions = _permissionGrid.GetPermissions();
 | 
			
		||||
                page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable));
 | 
			
		||||
                page.UserId = null;
 | 
			
		||||
                    page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
 | 
			
		||||
                    page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
 | 
			
		||||
                    page.Url = _url;
 | 
			
		||||
                    page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
 | 
			
		||||
                    if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
 | 
			
		||||
                    {
 | 
			
		||||
                        page.ThemeType = string.Empty;
 | 
			
		||||
                    }
 | 
			
		||||
                    page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty;
 | 
			
		||||
                    if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType)
 | 
			
		||||
                    {
 | 
			
		||||
                        page.DefaultContainerType = string.Empty;
 | 
			
		||||
                    }
 | 
			
		||||
                    page.Icon = (_icon == null ? string.Empty : _icon);
 | 
			
		||||
                    page.Permissions = _permissionGrid.GetPermissions();
 | 
			
		||||
                    page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable));
 | 
			
		||||
                    page.UserId = null;
 | 
			
		||||
 | 
			
		||||
                page = await PageService.AddPageAsync(page);
 | 
			
		||||
                await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
 | 
			
		||||
                    page = await PageService.AddPageAsync(page);
 | 
			
		||||
                    await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
 | 
			
		||||
 | 
			
		||||
                await logger.LogInformation("Page Added {Page}", page);
 | 
			
		||||
                if (PageState.QueryString.ContainsKey("cp"))
 | 
			
		||||
                {
 | 
			
		||||
                    NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path));
 | 
			
		||||
                    await logger.LogInformation("Page Added {Page}", page);
 | 
			
		||||
                    if (PageState.QueryString.ContainsKey("cp"))
 | 
			
		||||
                    {
 | 
			
		||||
                        NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path));
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        NavigationManager.NavigateTo(NavigateUrl(page.Path));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    NavigationManager.NavigateTo(NavigateUrl(page.Path));
 | 
			
		||||
                    AddModuleMessage(Localizer["Message.Required.PageInfo"], MessageType.Warning);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                AddModuleMessage(Localizer["Message.Required.PageInfo"], MessageType.Warning);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                await logger.LogError(ex, "Error Saving Page {Page} {Error}", page, ex.Message);
 | 
			
		||||
                AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            await logger.LogError(ex, "Error Saving Page {Page} {Error}", page, ex.Message);
 | 
			
		||||
            AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
 | 
			
		||||
            AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -7,168 +7,172 @@
 | 
			
		||||
@inject IStringLocalizer<Edit> Localizer
 | 
			
		||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
 | 
			
		||||
 | 
			
		||||
<TabStrip Refresh="@_refresh">
 | 
			
		||||
    <TabPanel Name="Settings" ResourceKey="Settings">
 | 
			
		||||
        @if (_themeList != null)
 | 
			
		||||
        {
 | 
			
		||||
            <div class="container">
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="Name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <input id="Name" class="form-control" @bind="@_name" />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="Parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <select id="Parent" class="form-select" value="@_parentid" @onchange="(e => ParentChanged(e))">
 | 
			
		||||
                            <option value="-1"><@Localizer["SiteRoot"]></option>
 | 
			
		||||
                            @foreach (Page page in _pageList)
 | 
			
		||||
                            {
 | 
			
		||||
                                if (page.PageId != _pageId)
 | 
			
		||||
                                {
 | 
			
		||||
                                    <option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        </select>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="Move" HelpText="Select the location where you would like the page to be moved in relation to other pages" ResourceKey="Move">Move: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <select id="Move" class="form-select" @bind="@_insert">
 | 
			
		||||
                            @if (_parentid == _currentparentid)
 | 
			
		||||
                            {
 | 
			
		||||
                                <option value="="><@Localizer["ThisLocation.Keep"]></option>
 | 
			
		||||
                            }
 | 
			
		||||
                            <option value="<<">@Localizer["ToBeginning"]</option>
 | 
			
		||||
                            @if (_children != null && _children.Count > 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                <option value="<">@Localizer["Before"]</option>
 | 
			
		||||
                                <option value=">">@Localizer["After"]</option>
 | 
			
		||||
                            }
 | 
			
		||||
                            <option value=">>">@Localizer["ToEnd"]</option>
 | 
			
		||||
                        </select>
 | 
			
		||||
                        @if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">"))
 | 
			
		||||
                        {
 | 
			
		||||
                            <select class="form-select" @bind="@_childid">
 | 
			
		||||
                                <option value="-1"><@Localizer["Page.Select"]></option>
 | 
			
		||||
                                @foreach (Page page in _children)
 | 
			
		||||
                                {
 | 
			
		||||
                                    <option value="@(page.PageId)">@(page.Name)</option>
 | 
			
		||||
                                }
 | 
			
		||||
                            </select>
 | 
			
		||||
                        }
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="Navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <select id="Navigation" class="form-select" @bind="@_isnavigation">
 | 
			
		||||
                            <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                            <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
                        </select>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="Clickablen" HelpText="Select whether the link in the site navigation is enabled or disabled" ResourceKey="Clickable">Clickable? </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <select id="Navigation" class="form-select" @bind="@_isclickable">
 | 
			
		||||
                            <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                            <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
                        </select>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="Path" HelpText="Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used." ResourceKey="UrlPath">Url Path: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <input id="Path" class="form-control" @bind="@_path" />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <Label Class="col-sm-3" For="Url" HelpText="Optionally enter a url which this page should redirect to when a user navigates to it" ResourceKey="Redirect">Redirect: </Label>
 | 
			
		||||
                    <div class="col-sm-9">
 | 
			
		||||
                        <input id="Url" class="form-control" @bind="@_url" />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <Section Name="Appearance" ResourceKey="Appearance">
 | 
			
		||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
 | 
			
		||||
    <TabStrip Refresh="@_refresh">
 | 
			
		||||
        <TabPanel Name="Settings" ResourceKey="Settings">
 | 
			
		||||
            @if (_themeList != null)
 | 
			
		||||
            {
 | 
			
		||||
                <div class="container">
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="Title" HelpText="Optionally enter the page title. If you do not provide a page title, the page name will be used." ResourceKey="Title">Title: </Label>
 | 
			
		||||
                        <Label Class="col-sm-3" For="Name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="Title" class="form-control" @bind="@_title" />
 | 
			
		||||
                            <input id="Name" class="form-control" @bind="@_name" required />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="Theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
 | 
			
		||||
                        <Label Class="col-sm-3" For="Parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <select id="Theme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))">
 | 
			
		||||
                                @foreach (var theme in _themes)
 | 
			
		||||
                            <select id="Parent" class="form-select" value="@_parentid" @onchange="(e => ParentChanged(e))" required>
 | 
			
		||||
                                <option value="-1"><@Localizer["SiteRoot"]></option>
 | 
			
		||||
                                @foreach (Page page in _pageList)
 | 
			
		||||
                                {
 | 
			
		||||
                                    <option value="@theme.TypeName">@theme.Name</option>
 | 
			
		||||
                                    if (page.PageId != _pageId)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        <option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            </select>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="defaultContainer" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
 | 
			
		||||
                        <Label Class="col-sm-3" For="Move" HelpText="Select the location where you would like the page to be moved in relation to other pages" ResourceKey="Move">Move: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <select id="defaultContainer" class="form-select" @bind="@_containertype">
 | 
			
		||||
                                <option value="-"><@Localizer["Container.Select"]></option>
 | 
			
		||||
                                @foreach (var container in _containers)
 | 
			
		||||
                            <select id="Move" class="form-select" @bind="@_insert" required>
 | 
			
		||||
                                @if (_parentid == _currentparentid)
 | 
			
		||||
                                {
 | 
			
		||||
                                    <option value="@container.TypeName">@container.Name</option>
 | 
			
		||||
                                    <option value="="><@Localizer["ThisLocation.Keep"]></option>
 | 
			
		||||
                                }
 | 
			
		||||
                                <option value="<<">@Localizer["ToBeginning"]</option>
 | 
			
		||||
                                @if (_children != null && _children.Count > 0)
 | 
			
		||||
                                {
 | 
			
		||||
                                    <option value="<">@Localizer["Before"]</option>
 | 
			
		||||
                                    <option value=">">@Localizer["After"]</option>
 | 
			
		||||
                                }
 | 
			
		||||
                                <option value=">>">@Localizer["ToEnd"]</option>
 | 
			
		||||
                            </select>
 | 
			
		||||
                            @if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">"))
 | 
			
		||||
                            {
 | 
			
		||||
                                <select class="form-select" @bind="@_childid">
 | 
			
		||||
                                    <option value="-1"><@Localizer["Page.Select"]></option>
 | 
			
		||||
                                    @foreach (Page page in _children)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        <option value="@(page.PageId)">@(page.Name)</option>
 | 
			
		||||
                                    }
 | 
			
		||||
                                </select>
 | 
			
		||||
                            }
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="Icon" HelpText="Optionally provide an icon class name for this page which will be displayed in the site navigation" ResourceKey="Icon">Icon: </Label>
 | 
			
		||||
                        <Label Class="col-sm-3" For="Navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="Icon" class="form-control" @bind="@_icon" />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content" ResourceKey="Personalizable">Personalizable? </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <select id="Personalizable" class="form-select" @bind="@_ispersonalizable">
 | 
			
		||||
                            <select id="Navigation" class="form-select" @bind="@_isnavigation" required>
 | 
			
		||||
                                <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                                <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
                            </select>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="Clickablen" HelpText="Select whether the link in the site navigation is enabled or disabled" ResourceKey="Clickable">Clickable? </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <select id="Navigation" class="form-select" @bind="@_isclickable" required>
 | 
			
		||||
                                <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                                <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
                            </select>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="Path" HelpText="Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used." ResourceKey="UrlPath">Url Path: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="Path" class="form-control" @bind="@_path" />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <Label Class="col-sm-3" For="Url" HelpText="Optionally enter a url which this page should redirect to when a user navigates to it" ResourceKey="Redirect">Redirect: </Label>
 | 
			
		||||
                        <div class="col-sm-9">
 | 
			
		||||
                            <input id="Url" class="form-control" @bind="@_url" />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </Section>
 | 
			
		||||
            <br /><br />
 | 
			
		||||
            <AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon" DeletedBy="@_deletedby" DeletedOn="@_deletedon"></AuditInfo>
 | 
			
		||||
        }
 | 
			
		||||
    </TabPanel>
 | 
			
		||||
    <TabPanel Name="Permissions" ResourceKey="Permissions">
 | 
			
		||||
        @if (_permissions != null)
 | 
			
		||||
        {
 | 
			
		||||
            <div class="container">
 | 
			
		||||
                <div class="row mb-1 align-items-center">
 | 
			
		||||
                    <PermissionGrid EntityName="@EntityNames.Page" Permissions="@_permissions" @ref="_permissionGrid" />
 | 
			
		||||
       
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 
 | 
			
		||||
        }
 | 
			
		||||
    </TabPanel>
 | 
			
		||||
    @if (_themeSettingsType != null)
 | 
			
		||||
    {
 | 
			
		||||
        <TabPanel Name="ThemeSettings" Heading="Theme Settings" ResourceKey="ThemeSettings">
 | 
			
		||||
            @ThemeSettingsComponent
 | 
			
		||||
                <Section Name="Appearance" ResourceKey="Appearance">
 | 
			
		||||
                    <div class="container">
 | 
			
		||||
                        <div class="row mb-1 align-items-center">
 | 
			
		||||
                            <Label Class="col-sm-3" For="Title" HelpText="Optionally enter the page title. If you do not provide a page title, the page name will be used." ResourceKey="Title">Title: </Label>
 | 
			
		||||
                            <div class="col-sm-9">
 | 
			
		||||
                                <input id="Title" class="form-control" @bind="@_title" />
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="row mb-1 align-items-center">
 | 
			
		||||
                            <Label Class="col-sm-3" For="Theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
 | 
			
		||||
                            <div class="col-sm-9">
 | 
			
		||||
                                <select id="Theme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))" required>
 | 
			
		||||
                                    @foreach (var theme in _themes)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        <option value="@theme.TypeName">@theme.Name</option>
 | 
			
		||||
                                    }
 | 
			
		||||
                                </select>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="row mb-1 align-items-center">
 | 
			
		||||
                            <Label Class="col-sm-3" For="defaultContainer" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
 | 
			
		||||
                            <div class="col-sm-9">
 | 
			
		||||
                                <select id="defaultContainer" class="form-select" @bind="@_containertype" required>
 | 
			
		||||
                                    <option value="-"><@Localizer["Container.Select"]></option>
 | 
			
		||||
                                    @foreach (var container in _containers)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        <option value="@container.TypeName">@container.Name</option>
 | 
			
		||||
                                    }
 | 
			
		||||
                                </select>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="row mb-1 align-items-center">
 | 
			
		||||
                            <Label Class="col-sm-3" For="Icon" HelpText="Optionally provide an icon class name for this page which will be displayed in the site navigation" ResourceKey="Icon">Icon: </Label>
 | 
			
		||||
                            <div class="col-sm-9">
 | 
			
		||||
                                <input id="Icon" class="form-control" @bind="@_icon" />
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="row mb-1 align-items-center">
 | 
			
		||||
                            <Label Class="col-sm-3" For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content" ResourceKey="Personalizable">Personalizable? </Label>
 | 
			
		||||
                            <div class="col-sm-9">
 | 
			
		||||
                                <select id="Personalizable" class="form-select" @bind="@_ispersonalizable" required>
 | 
			
		||||
                                    <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                                    <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
                                </select>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </Section>
 | 
			
		||||
                <br /><br />
 | 
			
		||||
                <AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon" DeletedBy="@_deletedby" DeletedOn="@_deletedon"></AuditInfo>
 | 
			
		||||
            }
 | 
			
		||||
        </TabPanel>
 | 
			
		||||
    }
 | 
			
		||||
</TabStrip>
 | 
			
		||||
<button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button>
 | 
			
		||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
 | 
			
		||||
        <TabPanel Name="Permissions" ResourceKey="Permissions">
 | 
			
		||||
            @if (_permissions != null)
 | 
			
		||||
            {
 | 
			
		||||
                <div class="container">
 | 
			
		||||
                    <div class="row mb-1 align-items-center">
 | 
			
		||||
                        <PermissionGrid EntityName="@EntityNames.Page" Permissions="@_permissions" @ref="_permissionGrid" />
 | 
			
		||||
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        </TabPanel>
 | 
			
		||||
        @if (_themeSettingsType != null)
 | 
			
		||||
        {
 | 
			
		||||
            <TabPanel Name="ThemeSettings" Heading="Theme Settings" ResourceKey="ThemeSettings">
 | 
			
		||||
                @ThemeSettingsComponent
 | 
			
		||||
            </TabPanel>
 | 
			
		||||
        }
 | 
			
		||||
    </TabStrip>
 | 
			
		||||
    <button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button>
 | 
			
		||||
    <button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
    public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
 | 
			
		||||
 | 
			
		||||
    private ElementReference form;
 | 
			
		||||
    private bool validated = false;
 | 
			
		||||
    private List<Theme> _themeList;
 | 
			
		||||
    private List<ThemeControl> _themes = new List<ThemeControl>();
 | 
			
		||||
    private List<ThemeControl> _containers = new List<ThemeControl>();
 | 
			
		||||
@ -351,134 +355,143 @@
 | 
			
		||||
 | 
			
		||||
    private async Task SavePage()
 | 
			
		||||
    {
 | 
			
		||||
        Page page = null;
 | 
			
		||||
        try
 | 
			
		||||
        validated = true;
 | 
			
		||||
        var interop = new Interop(JSRuntime);
 | 
			
		||||
        if (await interop.FormValid(form))
 | 
			
		||||
        {
 | 
			
		||||
            if (_name != string.Empty && !string.IsNullOrEmpty(_themetype) && _containertype != "-")
 | 
			
		||||
            Page page = null;
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
 | 
			
		||||
                string currentPath = page.Path;
 | 
			
		||||
                if (_name != string.Empty && !string.IsNullOrEmpty(_themetype) && _containertype != "-")
 | 
			
		||||
                {
 | 
			
		||||
                    page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
 | 
			
		||||
                    string currentPath = page.Path;
 | 
			
		||||
 | 
			
		||||
                page.Name = _name;
 | 
			
		||||
                page.Title = _title;
 | 
			
		||||
                if (_path == "" && _name.ToLower() != "home")
 | 
			
		||||
                    if (_path == string.Empty && _name.ToLower() != "home")
 | 
			
		||||
                    page.Name = _name;
 | 
			
		||||
                    page.Title = _title;
 | 
			
		||||
                    if (_path == "" && _name.ToLower() != "home")
 | 
			
		||||
                        if (_path == string.Empty && _name.ToLower() != "home")
 | 
			
		||||
                        {
 | 
			
		||||
                            _path = _name;
 | 
			
		||||
                        }
 | 
			
		||||
                    if (_path.Contains("/"))
 | 
			
		||||
                    {
 | 
			
		||||
                        _path = _name;
 | 
			
		||||
                        _path = _path.Substring(_path.LastIndexOf("/") + 1);
 | 
			
		||||
                    }
 | 
			
		||||
                if (_path.Contains("/"))
 | 
			
		||||
                {
 | 
			
		||||
                    _path = _path.Substring(_path.LastIndexOf("/") + 1);
 | 
			
		||||
                }
 | 
			
		||||
                if (string.IsNullOrEmpty(_parentid) || _parentid == "-1")
 | 
			
		||||
                {
 | 
			
		||||
                    page.ParentId = null;
 | 
			
		||||
                    page.Path = Utilities.GetFriendlyUrl(_path);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    page.ParentId = Int32.Parse(_parentid);
 | 
			
		||||
                    Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == page.ParentId);
 | 
			
		||||
                    if (parent.Path == string.Empty)
 | 
			
		||||
                    if (string.IsNullOrEmpty(_parentid) || _parentid == "-1")
 | 
			
		||||
                    {
 | 
			
		||||
                        page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path);
 | 
			
		||||
                        page.ParentId = null;
 | 
			
		||||
                        page.Path = Utilities.GetFriendlyUrl(_path);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
 | 
			
		||||
                        page.ParentId = Int32.Parse(_parentid);
 | 
			
		||||
                        Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == page.ParentId);
 | 
			
		||||
                        if (parent.Path == string.Empty)
 | 
			
		||||
                        {
 | 
			
		||||
                            page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path);
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (!PagePathIsUnique(page.Path, page.SiteId, page.PageId, _pageList))
 | 
			
		||||
                {
 | 
			
		||||
                    AddModuleMessage(string.Format(Localizer["Mesage.Page.PathExists"], _path), MessageType.Warning);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (_insert != "=")
 | 
			
		||||
                {
 | 
			
		||||
                    Page child;
 | 
			
		||||
                    switch (_insert)
 | 
			
		||||
                    if (!PagePathIsUnique(page.Path, page.SiteId, page.PageId, _pageList))
 | 
			
		||||
                    {
 | 
			
		||||
                        case "<<":
 | 
			
		||||
                            page.Order = 0;
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "<":
 | 
			
		||||
                            child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
 | 
			
		||||
                            if (child != null) page.Order = child.Order - 1;
 | 
			
		||||
                            break;
 | 
			
		||||
                        case ">":
 | 
			
		||||
                            child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
 | 
			
		||||
                            if (child != null) page.Order = child.Order + 1;
 | 
			
		||||
                            break;
 | 
			
		||||
                        case ">>":
 | 
			
		||||
                            page.Order = int.MaxValue;
 | 
			
		||||
                            break;
 | 
			
		||||
                        AddModuleMessage(string.Format(Localizer["Mesage.Page.PathExists"], _path), MessageType.Warning);
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
 | 
			
		||||
                page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
 | 
			
		||||
                page.Url = _url;
 | 
			
		||||
                page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
 | 
			
		||||
                if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
 | 
			
		||||
                {
 | 
			
		||||
                    page.ThemeType = string.Empty;
 | 
			
		||||
                }
 | 
			
		||||
                page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty;
 | 
			
		||||
                if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType)
 | 
			
		||||
                {
 | 
			
		||||
                    page.DefaultContainerType = string.Empty;
 | 
			
		||||
                }
 | 
			
		||||
                page.Icon = _icon ?? string.Empty;
 | 
			
		||||
                page.Permissions = _permissionGrid.GetPermissions();
 | 
			
		||||
                page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable));
 | 
			
		||||
                page.UserId = null;
 | 
			
		||||
 | 
			
		||||
                page = await PageService.UpdatePageAsync(page);
 | 
			
		||||
                await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
 | 
			
		||||
                if (_currentparentid == string.Empty)
 | 
			
		||||
                {
 | 
			
		||||
                    await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, null);
 | 
			
		||||
                    if (_insert != "=")
 | 
			
		||||
                    {
 | 
			
		||||
                        Page child;
 | 
			
		||||
                        switch (_insert)
 | 
			
		||||
                        {
 | 
			
		||||
                            case "<<":
 | 
			
		||||
                                page.Order = 0;
 | 
			
		||||
                                break;
 | 
			
		||||
                            case "<":
 | 
			
		||||
                                child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
 | 
			
		||||
                                if (child != null) page.Order = child.Order - 1;
 | 
			
		||||
                                break;
 | 
			
		||||
                            case ">":
 | 
			
		||||
                                child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
 | 
			
		||||
                                if (child != null) page.Order = child.Order + 1;
 | 
			
		||||
                                break;
 | 
			
		||||
                            case ">>":
 | 
			
		||||
                                page.Order = int.MaxValue;
 | 
			
		||||
                                break;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
 | 
			
		||||
                    page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
 | 
			
		||||
                    page.Url = _url;
 | 
			
		||||
                    page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
 | 
			
		||||
                    if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
 | 
			
		||||
                    {
 | 
			
		||||
                        page.ThemeType = string.Empty;
 | 
			
		||||
                    }
 | 
			
		||||
                    page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty;
 | 
			
		||||
                    if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType)
 | 
			
		||||
                    {
 | 
			
		||||
                        page.DefaultContainerType = string.Empty;
 | 
			
		||||
                    }
 | 
			
		||||
                    page.Icon = _icon ?? string.Empty;
 | 
			
		||||
                    page.Permissions = _permissionGrid.GetPermissions();
 | 
			
		||||
                    page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable));
 | 
			
		||||
                    page.UserId = null;
 | 
			
		||||
 | 
			
		||||
                    page = await PageService.UpdatePageAsync(page);
 | 
			
		||||
                    await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
 | 
			
		||||
                    if (_currentparentid == string.Empty)
 | 
			
		||||
                    {
 | 
			
		||||
                        await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, null);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, int.Parse(_currentparentid));
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // update child paths
 | 
			
		||||
                    if (_parentid != _currentparentid)
 | 
			
		||||
                    {
 | 
			
		||||
                        foreach (Page p in PageState.Pages.Where(item => item.Path.StartsWith(currentPath)))
 | 
			
		||||
                        {
 | 
			
		||||
                            p.Path = p.Path.Replace(currentPath, page.Path);
 | 
			
		||||
                            await PageService.UpdatePageAsync(p);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (_themeSettingsType != null && _themeSettings is ISettingsControl themeSettingsControl)
 | 
			
		||||
                    {
 | 
			
		||||
                        await themeSettingsControl.UpdateSettings();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    await logger.LogInformation("Page Saved {Page}", page);
 | 
			
		||||
                    if (PageState.QueryString.ContainsKey("cp"))
 | 
			
		||||
                    {
 | 
			
		||||
                        NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path));
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        NavigationManager.NavigateTo(NavigateUrl(page.Path));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, int.Parse(_currentparentid));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // update child paths
 | 
			
		||||
                if (_parentid != _currentparentid)
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (Page p in PageState.Pages.Where(item => item.Path.StartsWith(currentPath)))
 | 
			
		||||
                    {
 | 
			
		||||
                        p.Path = p.Path.Replace(currentPath, page.Path);
 | 
			
		||||
                        await PageService.UpdatePageAsync(p);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (_themeSettingsType != null && _themeSettings is ISettingsControl themeSettingsControl)
 | 
			
		||||
                {
 | 
			
		||||
                    await themeSettingsControl.UpdateSettings();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                await logger.LogInformation("Page Saved {Page}", page);
 | 
			
		||||
                if (PageState.QueryString.ContainsKey("cp"))
 | 
			
		||||
                {
 | 
			
		||||
                    NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path));
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    NavigationManager.NavigateTo(NavigateUrl(page.Path));
 | 
			
		||||
                    AddModuleMessage(Localizer["Message.Required.PageInfo"], MessageType.Warning);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                AddModuleMessage(Localizer["Message.Required.PageInfo"], MessageType.Warning);
 | 
			
		||||
                await logger.LogError(ex, "Error Saving Page {Page} {Error}", page, ex.Message);
 | 
			
		||||
                AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            await logger.LogError(ex, "Error Saving Page {Page} {Error}", page, ex.Message);
 | 
			
		||||
            AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
 | 
			
		||||
            AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -5,86 +5,90 @@
 | 
			
		||||
@inject IStringLocalizer<Edit> Localizer
 | 
			
		||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
 | 
			
		||||
 | 
			
		||||
<div class="container">
 | 
			
		||||
    <div class="row mb-1 align-items-center">
 | 
			
		||||
        <Label Class="col-sm-3" For="name" HelpText="The name of this profile item" ResourceKey="Name">Name: </Label>
 | 
			
		||||
        <div class="col-sm-9">
 | 
			
		||||
            <input id="name" class="form-control" @bind="@_name" />
 | 
			
		||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
 | 
			
		||||
    <div class="container">
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="name" HelpText="The name of this profile item" ResourceKey="Name">Name: </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <input id="name" class="form-control" @bind="@_name" required />
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="title" HelpText="The title of the profile item to display to the user" ResourceKey="Title">Title: </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <input id="title" class="form-control" @bind="@_title" required />
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="description" HelpText="The help text displayed to the user for this profile item" ResourceKey="Description">Description: </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <textarea id="description" class="form-control" @bind="@_description" rows="5" required></textarea>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="category" HelpText="The category of this profile item (for grouping)" ResourceKey="Category">Category: </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <input id="category" class="form-control" @bind="@_category" required />
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="order" HelpText="The index order of where this profile item should be displayed" ResourceKey="Order">Order: </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <input id="order" class="form-control" @bind="@_vieworder" required />
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="length" HelpText="The max number of characters this profile item should accept (enter zero for unlimited)" ResourceKey="Length">Length: </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <input id="length" class="form-control" @bind="@_maxlength" required />
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="defaultVal" HelpText="The default value for this profile item" ResourceKey="DefaultValue">Default Value: </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <input id="defaultVal" class="form-control" @bind="@_defaultvalue" required />
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="options" HelpText="A comma delimited list of options the user can select from" ResourceKey="Options">Options: </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <input id="options" class="form-control" @bind="@_options" required />
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="required" HelpText="Should a user be required to provide a value for this profile item?" ResourceKey="Required">Required? </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <select id="required" class="form-select" @bind="@_isrequired" required>
 | 
			
		||||
                    <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                    <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
                </select>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row mb-1 align-items-center">
 | 
			
		||||
            <Label Class="col-sm-3" For="private" HelpText="Should this profile item be visible to all users?" ResourceKey="Private">Private? </Label>
 | 
			
		||||
            <div class="col-sm-9">
 | 
			
		||||
                <select id="private" class="form-select" @bind="@_isprivate" required>
 | 
			
		||||
                    <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                    <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
                </select>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="row mb-1 align-items-center">
 | 
			
		||||
        <Label Class="col-sm-3" For="title" HelpText="The title of the profile item to display to the user" ResourceKey="Title">Title: </Label>
 | 
			
		||||
        <div class="col-sm-9">
 | 
			
		||||
            <input id="title" class="form-control" @bind="@_title" />
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="row mb-1 align-items-center">
 | 
			
		||||
        <Label Class="col-sm-3" For="description" HelpText="The help text displayed to the user for this profile item" ResourceKey="Description">Description: </Label>
 | 
			
		||||
        <div class="col-sm-9">
 | 
			
		||||
            <textarea id="description" class="form-control" @bind="@_description" rows="5"></textarea>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="row mb-1 align-items-center">
 | 
			
		||||
        <Label Class="col-sm-3" For="category" HelpText="The category of this profile item (for grouping)" ResourceKey="Category">Category: </Label>
 | 
			
		||||
        <div class="col-sm-9">
 | 
			
		||||
            <input id="category" class="form-control" @bind="@_category" />
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="row mb-1 align-items-center">
 | 
			
		||||
        <Label Class="col-sm-3" For="order" HelpText="The index order of where this profile item should be displayed" ResourceKey="Order">Order: </Label>
 | 
			
		||||
        <div class="col-sm-9">
 | 
			
		||||
            <input id="order" class="form-control" @bind="@_vieworder" />
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="row mb-1 align-items-center">
 | 
			
		||||
        <Label Class="col-sm-3" For="length" HelpText="The max number of characters this profile item should accept (enter zero for unlimited)" ResourceKey="Length">Length: </Label>
 | 
			
		||||
        <div class="col-sm-9">
 | 
			
		||||
            <input id="length" class="form-control" @bind="@_maxlength" />
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="row mb-1 align-items-center">
 | 
			
		||||
        <Label Class="col-sm-3" For="defaultVal" HelpText="The default value for this profile item" ResourceKey="DefaultValue">Default Value: </Label>
 | 
			
		||||
        <div class="col-sm-9">
 | 
			
		||||
            <input id="defaultVal" class="form-control" @bind="@_defaultvalue" />
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="row mb-1 align-items-center">
 | 
			
		||||
        <Label Class="col-sm-3" For="options" HelpText="A comma delimited list of options the user can select from" ResourceKey="Options">Options: </Label>
 | 
			
		||||
        <div class="col-sm-9">
 | 
			
		||||
            <input id="options" class="form-control" @bind="@_options" />
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="row mb-1 align-items-center">
 | 
			
		||||
        <Label Class="col-sm-3" For="required" HelpText="Should a user be required to provide a value for this profile item?" ResourceKey="Required">Required? </Label>
 | 
			
		||||
        <div class="col-sm-9">
 | 
			
		||||
            <select id="required" class="form-select" @bind="@_isrequired">
 | 
			
		||||
                <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
            </select>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="row mb-1 align-items-center">
 | 
			
		||||
        <Label Class="col-sm-3" For="private" HelpText="Should this profile item be visible to all users?" ResourceKey="Private">Private? </Label>
 | 
			
		||||
        <div class="col-sm-9">
 | 
			
		||||
            <select id="private" class="form-select" @bind="@_isprivate">
 | 
			
		||||
                <option value="True">@SharedLocalizer["Yes"]</option>
 | 
			
		||||
                <option value="False">@SharedLocalizer["No"]</option>
 | 
			
		||||
            </select>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
<br />
 | 
			
		||||
<button type="button" class="btn btn-success" @onclick="SaveProfile">@SharedLocalizer["Save"]</button>
 | 
			
		||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
 | 
			
		||||
@if (PageState.QueryString.ContainsKey("id"))
 | 
			
		||||
{
 | 
			
		||||
    <br />
 | 
			
		||||
    <br />
 | 
			
		||||
    <AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
 | 
			
		||||
}
 | 
			
		||||
    <button type="button" class="btn btn-success" @onclick="SaveProfile">@SharedLocalizer["Save"]</button>
 | 
			
		||||
    <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
 | 
			
		||||
    @if (PageState.QueryString.ContainsKey("id"))
 | 
			
		||||
    {
 | 
			
		||||
        <br />
 | 
			
		||||
        <br />
 | 
			
		||||
        <AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
 | 
			
		||||
    }
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
    private int _profileid = -1;
 | 
			
		||||
    private ElementReference form;
 | 
			
		||||
    private bool validated = false;
 | 
			
		||||
    private string _name = string.Empty;
 | 
			
		||||
    private string _title = string.Empty;
 | 
			
		||||
    private string _description = string.Empty;
 | 
			
		||||
@ -140,45 +144,54 @@
 | 
			
		||||
 | 
			
		||||
    private async Task SaveProfile()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        validated = true;
 | 
			
		||||
        var interop = new Interop(JSRuntime);
 | 
			
		||||
        if (await interop.FormValid(form))
 | 
			
		||||
        {
 | 
			
		||||
            Profile profile;
 | 
			
		||||
            if (_profileid != -1)
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                profile = await ProfileService.GetProfileAsync(_profileid);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                profile = new Profile();
 | 
			
		||||
            }
 | 
			
		||||
                Profile profile;
 | 
			
		||||
                if (_profileid != -1)
 | 
			
		||||
                {
 | 
			
		||||
                    profile = await ProfileService.GetProfileAsync(_profileid);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    profile = new Profile();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            profile.SiteId = PageState.Site.SiteId;
 | 
			
		||||
            profile.Name = _name;
 | 
			
		||||
            profile.Title = _title;
 | 
			
		||||
            profile.Description = _description;
 | 
			
		||||
            profile.Category = _category;
 | 
			
		||||
            profile.ViewOrder = int.Parse(_vieworder);
 | 
			
		||||
            profile.MaxLength = int.Parse(_maxlength);
 | 
			
		||||
            profile.DefaultValue = _defaultvalue;
 | 
			
		||||
            profile.Options = _options;
 | 
			
		||||
            profile.IsRequired = (_isrequired == null ? false : Boolean.Parse(_isrequired));
 | 
			
		||||
            profile.IsPrivate = (_isprivate == null ? false : Boolean.Parse(_isprivate));
 | 
			
		||||
            if (_profileid != -1)
 | 
			
		||||
            {
 | 
			
		||||
                profile = await ProfileService.UpdateProfileAsync(profile);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                profile = await ProfileService.AddProfileAsync(profile);
 | 
			
		||||
            }
 | 
			
		||||
                profile.SiteId = PageState.Site.SiteId;
 | 
			
		||||
                profile.Name = _name;
 | 
			
		||||
                profile.Title = _title;
 | 
			
		||||
                profile.Description = _description;
 | 
			
		||||
                profile.Category = _category;
 | 
			
		||||
                profile.ViewOrder = int.Parse(_vieworder);
 | 
			
		||||
                profile.MaxLength = int.Parse(_maxlength);
 | 
			
		||||
                profile.DefaultValue = _defaultvalue;
 | 
			
		||||
                profile.Options = _options;
 | 
			
		||||
                profile.IsRequired = (_isrequired == null ? false : Boolean.Parse(_isrequired));
 | 
			
		||||
                profile.IsPrivate = (_isprivate == null ? false : Boolean.Parse(_isprivate));
 | 
			
		||||
                if (_profileid != -1)
 | 
			
		||||
                {
 | 
			
		||||
                    profile = await ProfileService.UpdateProfileAsync(profile);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    profile = await ProfileService.AddProfileAsync(profile);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            await logger.LogInformation("Profile Saved {Profile}", profile);
 | 
			
		||||
            NavigationManager.NavigateTo(NavigateUrl());
 | 
			
		||||
                await logger.LogInformation("Profile Saved {Profile}", profile);
 | 
			
		||||
                NavigationManager.NavigateTo(NavigateUrl());
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                await logger.LogError(ex, "Error Saving Profile {ProfleId} {Error}", _profileid, ex.Message);
 | 
			
		||||
                AddModuleMessage(Localizer["Error.Profile.Save"], MessageType.Error);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            await logger.LogError(ex, "Error Saving Profile {ProfleId} {Error}", _profileid, ex.Message);
 | 
			
		||||
            AddModuleMessage(Localizer["Error.Profile.Save"], MessageType.Error);
 | 
			
		||||
            AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user