This commit is contained in:
2021-11-01 18:14:21 +00:00
parent ea61d37840
commit 806ebb4024
34 changed files with 766 additions and 411 deletions
+1 -1
View File
@@ -55,7 +55,7 @@ namespace Saxonite.Net.Core.Web.Base.App
try try
{ {
if (StringUtil.IsEmpty(ComputerName)) if (StringUtil.IsEmpty(ComputerName))
ComputerName = Environment.GetEnvironmentVariable("CUMPUTERNAME") ?? Environment.GetEnvironmentVariable("HOSTNAME"); ComputerName = Environment.GetEnvironmentVariable("COMPUTERNAME") ?? Environment.GetEnvironmentVariable("HOSTNAME");
} }
catch (Exception exc) catch (Exception exc)
{ {
@@ -69,6 +69,7 @@ namespace Saxonite.Net.Core.Web.Admin.App
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Properties. // Properties.
public static SaxApplication_Admin AppInstance { get; private set; } public static SaxApplication_Admin AppInstance { get; private set; }
public List<String> Messages { get; } = new List<String>();
public override ISacsDatabase GetCoreDatabase(SaxSessionContext sessionContext) public override ISacsDatabase GetCoreDatabase(SaxSessionContext sessionContext)
{ {
return sessionContexts.GetValue(sessionContext.Index, null)?.CoreDatabase; return sessionContexts.GetValue(sessionContext.Index, null)?.CoreDatabase;
@@ -106,6 +107,9 @@ namespace Saxonite.Net.Core.Web.Admin.App
.AddEnvironmentVariables(); .AddEnvironmentVariables();
SaxConfiguration = builder.Build(); SaxConfiguration = builder.Build();
//Messages.Add($"Host: {SaxSystem.ComputerName}");
//Messages.Add($"Config file: appsettings.machine.{SaxSystem.ComputerName}.json");
// Application configuration. // Application configuration.
appConfigs = SaxAppConfigHelper.ExtractAppConfigs(SaxConfiguration.GetSection("AppConfigs")); appConfigs = SaxAppConfigHelper.ExtractAppConfigs(SaxConfiguration.GetSection("AppConfigs"));
emailConfigs = SaxEmailConfigHelper.ExtractEmailConfigs(SaxConfiguration.GetSection("EmailConfigs")); emailConfigs = SaxEmailConfigHelper.ExtractEmailConfigs(SaxConfiguration.GetSection("EmailConfigs"));
@@ -127,6 +131,9 @@ namespace Saxonite.Net.Core.Web.Admin.App
SaLogger.LogFolder = LoggingRootFolder; SaLogger.LogFolder = LoggingRootFolder;
LogApplicationStart(fn); LogApplicationStart(fn);
//Messages.Add($"Database location: {AppConfig.CoreDatabase.Location}");
//Messages.Add($"LoggingRootFolder: {SaLogger.LogFolder}");
// Configure database connection. // Configure database connection.
SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig(); SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig();
config.location = AppConfig.CoreDatabase.Location; config.location = AppConfig.CoreDatabase.Location;
@@ -136,6 +143,11 @@ namespace Saxonite.Net.Core.Web.Admin.App
if (coreDatabase.HasErrorState()) if (coreDatabase.HasErrorState())
SaLogger.Warn(fn + " Database initialisation error: " + coreDatabase.ErrorStateMessage); SaLogger.Warn(fn + " Database initialisation error: " + coreDatabase.ErrorStateMessage);
//Messages.Add($"Database location: {AppConfig.CoreDatabase.Location}");
//Messages.Add($"LoggingRootFolder: {SaLogger.LogFolder}");
//Messages.Add($"OdbcDrivers: {OdbcUtil.GetOdbcDriverNames().Concat(", ")}");
//Messages.Add($"DbConnection: {coreDatabase.ConnectionString}");
// Session context - only one context available/necessary (for now). // Session context - only one context available/necessary (for now).
SessionContextData sessionContextData = new SessionContextData(new SaxSessionContext_Web(100, Sax.Application.Admin)); SessionContextData sessionContextData = new SessionContextData(new SaxSessionContext_Web(100, Sax.Application.Admin));
sessionContextData.CoreDatabase = coreDatabase; sessionContextData.CoreDatabase = coreDatabase;
@@ -181,9 +181,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
// Activate awaiting members and send welcome email to each. // Activate awaiting members and send welcome email to each.
foreach (OrganisationMemberData organisationMember in organisationMembersToActivate) foreach (OrganisationMemberData organisationMember in organisationMembersToActivate)
{ {
// Ensure that User Organisation has 'Member Admin' role.
if (organisationMember.UserOrganisation == null) continue; if (organisationMember.UserOrganisation == null) continue;
organisationMember.UserOrganisation.AddOrganisationRole(Sax.OrganisationRole.MemberAdmin);
if (AccountMgr.UpdateUserOrganisation(organisationMember.UserOrganisation, DbUpdateInfo)) if (AccountMgr.UpdateUserOrganisation(organisationMember.UserOrganisation, DbUpdateInfo))
{ {
if (organisationMember.UserAccount == null) continue; if (organisationMember.UserAccount == null) continue;
@@ -159,6 +159,12 @@
<data name="label.any" xml:space="preserve"> <data name="label.any" xml:space="preserve">
<value>Any</value> <value>Any</value>
</data> </data>
<data name="label.assigned" xml:space="preserve">
<value>Assigned</value>
</data>
<data name="label.available" xml:space="preserve">
<value>Available</value>
</data>
<data name="label.cancel" xml:space="preserve"> <data name="label.cancel" xml:space="preserve">
<value>Cancel</value> <value>Cancel</value>
</data> </data>
@@ -0,0 +1,113 @@
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_dependencyType": "appService.windows"
},
"parameters": {
"resourceGroupName": {
"type": "string",
"defaultValue": "Sportierre",
"metadata": {
"description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking."
}
},
"resourceGroupLocation": {
"type": "string",
"defaultValue": "westeurope",
"metadata": {
"description": "Location of the resource group. Resource groups could have different location than resources, however by default we use API versions from latest hybrid profile which support all locations for resource types we support."
}
},
"resourceName": {
"type": "string",
"defaultValue": "SportierreAdmin",
"metadata": {
"description": "Name of the main resource to be created by this template."
}
},
"resourceLocation": {
"type": "string",
"defaultValue": "[parameters('resourceGroupLocation')]",
"metadata": {
"description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there."
}
}
},
"variables": {
"appServicePlan_name": "[concat('Plan', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]",
"appServicePlan_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/serverFarms/', variables('appServicePlan_name'))]"
},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"name": "[parameters('resourceGroupName')]",
"location": "[parameters('resourceGroupLocation')]",
"apiVersion": "2019-10-01"
},
{
"type": "Microsoft.Resources/deployments",
"name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]",
"resourceGroup": "[parameters('resourceGroupName')]",
"apiVersion": "2019-10-01",
"dependsOn": [
"[parameters('resourceGroupName')]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"location": "[parameters('resourceLocation')]",
"name": "[parameters('resourceName')]",
"type": "Microsoft.Web/sites",
"apiVersion": "2015-08-01",
"tags": {
"[concat('hidden-related:', variables('appServicePlan_ResourceId'))]": "empty"
},
"dependsOn": [
"[variables('appServicePlan_ResourceId')]"
],
"kind": "app",
"properties": {
"name": "[parameters('resourceName')]",
"kind": "app",
"httpsOnly": true,
"reserved": false,
"serverFarmId": "[variables('appServicePlan_ResourceId')]",
"siteConfig": {
"metadata": [
{
"name": "CURRENT_STACK",
"value": "dotnetcore"
}
]
}
},
"identity": {
"type": "SystemAssigned"
}
},
{
"location": "[parameters('resourceLocation')]",
"name": "[variables('appServicePlan_name')]",
"type": "Microsoft.Web/serverFarms",
"apiVersion": "2015-08-01",
"sku": {
"name": "S1",
"tier": "Standard",
"family": "S",
"size": "S1"
},
"properties": {
"name": "[variables('appServicePlan_name')]"
}
}
]
}
}
}
]
}
@@ -1,60 +1,65 @@
@model SaxModel_Admin @model SaxModel_Admin
@inject SaxLocaliser Localiser @inject SaxLocaliser Localiser
<link rel="stylesheet" href="~/css/sax-selectCode.css?@Model.HrefVersion" /> <link rel="stylesheet" href="~/css/sax-selectCode.css?@Model.HrefVersion" />
<script src="~/js/sax-selectCode.js?@Model.HrefVersion"></script> <script src="~/js/sax-selectCode.js?@Model.HrefVersion"></script>
<script type="text/javascript"> <script type="text/javascript">
</script> </script>
<div id="dlgSelectCode" class="sax-dialog sax-form"> <div id="dlgSelectCode" class="sax-dialog sax-form">
@* Filter *@ @* Filter *@
<div class=""> <div class="">
</div> </div>
<div class="row h-100"> <div class="row h-100">
@* Available codes *@ @* Available codes *@
<div class="col-sm-5"> <div class="col-sm-5">
<div class="h-100 sax-selectCode-codes AvailableCodes"> <div class="h-100 d-flex flex-column">
<div class="">@Localiser["label.available"]:</div>
</div> <div class="spacer"></div>
<div class="sax-selectCode-codes AvailableCodes flex-grow-1 mr-1"></div>
</div>
@* Code selection *@
<div class="col-sm-2">
<div class="row">
<div class="col-sx-6 col-sm-12 center">
<button class="sax-button Select">@Localiser["label.select"]</button>
</div>
<div class="col-sx-6 col-sm-12 center">
<button class="sax-button Remove">@Localiser["label.remove"]</button>
</div>
</div>
</div>
@* Selected codes *@
<div class="col-sm-5">
<div class="h-100 sax-selectCode-codes SelectedCodes">
</div>
</div> </div>
</div> </div>
<div class="sax-panel-item-template"> @* Code selection *@
<div class="sax-panel-item Code"> <div class="col-sm-2">
<div class="CodeDesc"></div>
<div class="spacer8"></div>
<div class="row">
<div class="col-sx-6 col-sm-12 center">
<button class="sax-button Select">@Localiser["label.select"]</button>
</div>
<div class="col-sx-6 col-sm-12 center">
<button class="sax-button Remove">@Localiser["label.remove"]</button>
</div>
</div>
</div>
@* Selected codes *@
<div class="col-sm-5">
<div class="h-100 d-flex flex-column">
<div class="">@Localiser["label.assigned"]:</div>
<div class="spacer"></div>
<div class="sax-selectCode-codes SelectedCodes flex-grow-1 ml-1"></div>
</div> </div>
</div> </div>
</div> </div>
<div class="sax-panel-item-template">
<div class="sax-panel-item Code">
<div class="CodeDesc"></div>
</div>
</div>
</div>
@@ -16,12 +16,13 @@
{ {
@Html.HiddenFor(model => model.UserOrganisationId, new { @id = "", @class = "UserOrganisationId" }) @Html.HiddenFor(model => model.UserOrganisationId, new { @id = "", @class = "UserOrganisationId" })
} }
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmUserEmail"})) @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmUserEmail" }))
{ {
<input type="hidden" id="" class="UserEmailAddress" name="UserEmailAddress" /> <input type="hidden" id="" class="UserEmailAddress" name="UserEmailAddress" />
} }
<div id="dlgMember" class="sax-dialog" title=""> <div id="dlgMember" class="sax-dialog" title="">
<div class="spacer"></div>
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmMember", @class = "sax-form", @onSubmit = "return false;" })) @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmMember", @class = "sax-form", @onSubmit = "return false;" }))
{ {
@Html.HiddenFor(model => model.UserOrganisationId, new { @id = "", @class = "UserOrganisationId" }) @Html.HiddenFor(model => model.UserOrganisationId, new { @id = "", @class = "UserOrganisationId" })
@@ -29,52 +30,77 @@
@* User email *@ @* User email *@
<div class="sax-form-control UserEmailAddress"> <div class="sax-form-control UserEmailAddress">
<div class="sax-label"> <div class="row">
<label for="ifMemberUserEmailAddress"><span><span class="required">*</span> @Localiser["label.email.address"]</span></label> <div class="col-sm-4">
<div class="sax-label">
<label for="ifMemberUserEmailAddress"><span>@Localiser["label.email.address"]</span>&nbsp;<span class="required">*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control">
@Html.TextBoxFor(model => model.MemberUserEmailAddress, new { @id = "ifMemberUserEmailAddress", @class = "MemberUserEmailAddress sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_EmailAddress) })
</div>
<div class="sax-message"></div>
</div>
</div> </div>
<div class="sax-control">
@Html.TextBoxFor(model => model.MemberUserEmailAddress, new { @id = "ifMemberUserEmailAddress", @class = "MemberUserEmailAddress sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_EmailAddress) })
</div>
<div class="sax-message"></div>
</div> </div>
@* User email *@ @* User email *@
<div class="sax-form-control UserName"> <div class="sax-form-control UserName">
<div class="sax-label"> <div class="row">
<label for="ifMemberUserName"><span>@Localiser["label.name"]</span></label> <div class="col-sm-4">
<div class="sax-label">
<label for="ifMemberUserName"><span>@Localiser["label.name"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control">
<input type="text" id="ifMemberUserName" class="MemberUserName sax-input" readonly="readonly" />
</div>
<div class="sax-message"></div>
</div>
</div> </div>
<div class="sax-control">
<input type="text" id="ifMemberUserName" class="MemberUserName sax-input" readonly="readonly" />
</div>
<div class="sax-message"></div>
</div> </div>
@* Member roles *@ @* Member roles *@
<div class="sax-form-control MemberRoleCodes"> <div class="sax-form-control MemberRoleCodes">
<div class="sax-label"> <div class="row">
<label for="ifMemberRoles"><span>@Localiser["label.roles"]</span></label> <div class="col-sm-4">
<div class="sax-label">
<label for="ifMemberRoles"><span>@Localiser["label.roles"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
@Html.HiddenFor(model => model.MemberRoleCodes, new { @id = "ifMemberRoleCodes", @class = "MemberRoleCodes sax-input" })
<div class="col"><textarea id="ifMemberRoles" class="MemberRoles sax-input" rows="6" readonly="readonly" ondblclick="sax.selectMemberRoles()"></textarea></div>
<div class="fixed"><button id="" class="sax-button" style="min-width:auto;margin-left:4px;padding:4px 6px" onclick="sax.selectMemberRoles()">@Localiser["label.select"]</button></div>
</div>
<div class="sax-message"></div>
</div>
</div> </div>
<div class="sax-control row">
@Html.HiddenFor(model => model.MemberRoleCodes, new { @id = "ifMemberRoleCodes", @class = "MemberRoleCodes sax-input" })
<div class="col"><textarea id="ifMemberRoles" class="MemberRoles sax-input" rows="6" readonly="readonly" ondblclick="sax.selectMemberRoles()"></textarea></div>
<div class="fixed"><button id="" class="sax-button" style="min-width:auto;margin-left:4px;padding:4px 6px" onclick="sax.selectMemberRoles()">@Localiser["label.select"]</button></div>
</div>
<div class="sax-message"></div>
</div> </div>
@* Member status *@ @* Member status *@
<div class="sax-form-control MemberStatus"> <div class="sax-form-control MemberStatus">
<div class="sax-label"> <div class="row">
<label for="cbMemberStatus"><span><span class="required">*</span> @Localiser["label.status"]</span></label> <div class="col-sm-4">
<div class="sax-label">
<label for="cbMemberStatus"><span>@Localiser["label.status"]</span>&nbsp;<span class="required">*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control">
<select id="cbMemberStatus" class="sax-select MemberStatus" name="MemberStatusCode"></select>
</div>
<div class="sax-message"></div>
</div>
</div> </div>
<div class="sax-control">
<select id="cbMemberStatus" class="sax-select MemberStatus" name="MemberStatusCode"></select>
</div>
<div class="sax-message"></div>
</div> </div>
} }
<div class="spacer"></div>
<partial name="~/Views/Common/SelectCode.cshtml" />
</div> </div>
<partial name="~/Views/Common/SelectCode.cshtml" />
@@ -41,7 +41,7 @@
<div class="row"> <div class="row">
<div class="col-sm-4"></div> <div class="col-sm-4"></div>
<div class="col-sm"> <div class="col-sm-4">
@* Organisation category *@ @* Organisation category *@
<div class="sax-form-control OrganisationCategory pr4"> <div class="sax-form-control OrganisationCategory pr4">
@@ -56,7 +56,7 @@
</div> </div>
<div class="col-sm-6"> <div class="col-sm-4">
@* Organisation type *@ @* Organisation type *@
<div class="sax-form-control OrganisationType"> <div class="sax-form-control OrganisationType">
@@ -24,9 +24,9 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
@if (Model.ProhibitCache) @if (Model.ProhibitCache)
{ {
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" /> <meta http-equiv="Expires" content="0" />
} }
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Script-Type" content="application/javascript" /> <meta http-equiv="Content-Script-Type" content="application/javascript" />
@@ -50,7 +50,7 @@
<link rel="stylesheet" href="~/css/sax-form.css?@Model.HrefVersion" /> <link rel="stylesheet" href="~/css/sax-form.css?@Model.HrefVersion" />
@foreach (var cssFile in Model.AdditionalFiles_CSS) @foreach (var cssFile in Model.AdditionalFiles_CSS)
{ {
<link rel="stylesheet" href="~/@cssFile?@Model.HrefVersion" /> <link rel="stylesheet" href="~/@cssFile?@Model.HrefVersion" />
} }
@* Scripts *@ @* Scripts *@
@@ -109,52 +109,52 @@
*@ *@
@if (Model.AwaitingLogin) @if (Model.AwaitingLogin)
{ {
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Policies" asp-action="Privacy">@Localiser["policies.caption.privacy"]</a> <a class="nav-link text-dark" asp-area="" asp-controller="Policies" asp-action="Privacy">@Localiser["policies.caption.privacy"]</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Security" asp-action="">@Localiser["security.caption.signin"]</a> <a class="nav-link text-dark" asp-area="" asp-controller="Security" asp-action="">@Localiser["security.caption.signin"]</a>
</li> </li>
} }
else else
{ {
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@Localiser["label.reference"] @Localiser["label.reference"]
</a> </a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown"> <div class="dropdown-menu" aria-labelledby="navbarDropdown">
<div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('Sport');">@Localiser["sport.caption.sports"]</div> <div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('Sport');">@Localiser["sport.caption.sports"]</div>
<div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('Region');">@Localiser["region.caption.regions"]</div> <div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('Region');">@Localiser["region.caption.regions"]</div>
</div> </div>
</li> </li>
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@Localiser["label.accounts"] @Localiser["label.accounts"]
</a> </a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown"> <div class="dropdown-menu" aria-labelledby="navbarDropdown">
<div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('User');">@Localiser["user.caption.users"]</div> <div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('User');">@Localiser["user.caption.users"]</div>
<div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('Organisation');">@Localiser["organisation.caption.organisations"]</div> <div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('Organisation');">@Localiser["organisation.caption.organisations"]</div>
</div> </div>
</li> </li>
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@Localiser["label.system"] @Localiser["label.system"]
</a> </a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown"> <div class="dropdown-menu" aria-labelledby="navbarDropdown">
<div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('System/Database');">@Localiser["label.database"]</div> <div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('System/Database');">@Localiser["label.database"]</div>
<div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('System/Logs');">@Localiser["label.logs"]</div> <div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('System/Logs');">@Localiser["label.logs"]</div>
</div> </div>
</li> </li>
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@Localiser["label.security"] @Localiser["label.security"]
</a> </a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown"> <div class="dropdown-menu" aria-labelledby="navbarDropdown">
<div class="dropdown-item text-dark sax-action" onclick="sax.navigateTo('Security/ChangePassword');">@Localiser["security.caption.change.password"]</div> <div class="dropdown-item text-dark sax-action" onclick="sax.navigateTo('Security/ChangePassword');">@Localiser["security.caption.change.password"]</div>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<div class="dropdown-item text-dark sax-action" onclick="sax.onSignOut();">@Localiser["security.caption.signout"]</div> <div class="dropdown-item text-dark sax-action" onclick="sax.onSignOut();">@Localiser["security.caption.signout"]</div>
</div> </div>
</li> </li>
} }
</ul> </ul>
</div> </div>
@@ -164,9 +164,9 @@
@* Page caption *@ @* Page caption *@
@if (!StringUtil.IsEmpty(Model.PageCaption)) @if (!StringUtil.IsEmpty(Model.PageCaption))
{ {
<div class="container"> <div class="container">
<div class="sax-page-caption">@(Model.PageCaption)</div> <div class="sax-page-caption">@(Model.PageCaption)</div>
</div> </div>
} }
</header> </header>
@@ -181,7 +181,15 @@
@* Footer *@ @* Footer *@
<footer id="sax-page-footer" class="border-top footer text-muted"> <footer id="sax-page-footer" class="border-top footer text-muted">
<div class="container"> <div class="container">
@(Model.CopyrightNotice) - @Localiser["company.name"] @(Model.InstanceVersion) <div class="row">
<div class="col-sm">@(Model.CopyrightNotice) - @Localiser["company.name"] @(Model.InstanceVersion)</div>
<div class="fixed-sm">
<div style="padding-top:4px;font-size:.8rem;line-height:1.2;">
@* Application messages - for debugging. *@
@(new Microsoft.AspNetCore.Html.HtmlString(Saxonite.Net.Core.Web.Admin.App.SaxApplication_Admin.AppInstance.Messages.Concat("<br/>")))
</div>
</div>
</div>
</div> </div>
</footer> </footer>
@@ -212,11 +220,11 @@
<script src="~/js/sax-main.js?@Model.HrefVersion"></script> <script src="~/js/sax-main.js?@Model.HrefVersion"></script>
@foreach (var jsFile in Model.AdditionalFiles_JS) @foreach (var jsFile in Model.AdditionalFiles_JS)
{ {
<script src="~/@jsFile?@Model.HrefVersion"></script> <script src="~/@jsFile?@Model.HrefVersion"></script>
} }
@if (Model.IncludeGoogleAnalytics) @if (Model.IncludeGoogleAnalytics)
{ {
<partial name="~/Views/Shared/_GoogleAnalytics.cshtml" /> <partial name="~/Views/Shared/_GoogleAnalytics.cshtml" />
} }
@RenderSection("Scripts", required: false) @RenderSection("Scripts", required: false)
@@ -0,0 +1,55 @@
{
"AppConfigs": {
"SAX-Prod": {
"Environments": [ "Production" ],
"Instance": "",
"URLs": {
"Online": {
"Root": "https://sportierre.com/"
}
},
"CoreDatabase": {
"Location": "MsSql:sportierre.database.windows.net\\Saxonite_Core_Demo",
"User": "dbadmin",
"Password": "azdb-sport-1970!"
},
"Security": {
"Password": {
"MinLength": 9
},
"SignIn": {
"KeepLoggedIn": {
"Allowed": true,
"CookieExpiresDays": 5
},
"PasswordRequest": {
"LinkExpiresMins": 30
}
}
},
"Email": {
"Context": "SAX-SF-Prod",
"ContactUs": {
"AddressesTo": [],
"AddressesBcc": [ "info@sportierre.com" ]
},
"Signup": {
"Activate": {
"AddressesBcc": [ "info@sportierre.com" ]
},
"Welcome": {
"AddressesBcc": [ "info@sportierre.com" ]
}
}
},
"Documents": {
"RootFolder": "D:\\Home\\Logfiles\\Application\\Saxonite\\Admin\\Docs"
},
"Logging": {
"RootFolder": "D:\\Home\\Logfiles\\Application\\Saxonite\\Admin\\Logs"
},
"Variants": [
]
}
}
}
@@ -28,7 +28,7 @@ html
{ {
html html
{ {
font-size: 16px; font-size: 14px;
} }
} }
@@ -6,7 +6,7 @@
{ {
"use strict"; "use strict";
let op = sax.mdl.organisations = sax.mdl.organisations || { data: {}, ajax: {} }; let op = sax.mdl.organisations = sax.mdl.organisations || { data: {}, ajax: {} };
let $pnl = sax.$pnl, $frm = sax.$frm, $dlg = sax.$dlg; let $pnl = op.$pnl = {}, $frm = op.$frm = {}, $dlg = op.$dlg = {};
sax.itemIdPrefix = 'Itm_'; sax.itemIdPrefix = 'Itm_';
//-------------------------------------------------------------- //--------------------------------------------------------------
@@ -200,7 +200,7 @@
$('.OrganisationStatus', frm).val(sax.data.defaultStatusCode); $('.OrganisationStatus', frm).val(sax.data.defaultStatusCode);
sax.clearControlErrors(); sax.clearControlErrors();
$dlg.organisation.dialog('option', 'title', sax.dlg.title.createOrganisation); $dlg.organisation.dialog('option', 'title', sax.dlg.title.createOrganisation);
sax.openDialog($dlg.organisation, 600, 600); sax.openDialog($dlg.organisation, 600, 480);
} }
//-------------------------------------------------------------- //--------------------------------------------------------------
@@ -228,7 +228,7 @@
$('.OrganisationStatus', frm).val(item.statusCode); $('.OrganisationStatus', frm).val(item.statusCode);
sax.clearControlErrors(); sax.clearControlErrors();
$dlg.organisation.dialog('option', 'title', sax.dlg.title.updateOrganisation); $dlg.organisation.dialog('option', 'title', sax.dlg.title.updateOrganisation);
sax.openDialog($dlg.organisation, 600, 600); sax.openDialog($dlg.organisation, 600, 480);
} }
//-------------------------------------------------------------- //--------------------------------------------------------------
@@ -269,7 +269,6 @@
sax.debug('showActivationInfo', response); sax.debug('showActivationInfo', response);
if (!response.success || !response.organisation) return; if (!response.success || !response.organisation) return;
let item = response.organisation; let item = response.organisation;
let $dlg = $dlg.activate;
let frm = $('#frmOrganisationActivation'); let frm = $('#frmOrganisationActivation');
$('.OrganisationId', frm).val($('.OrganisationId', $frm.orgId).val()); $('.OrganisationId', frm).val($('.OrganisationId', $frm.orgId).val());
let popItemValue = function (sel, val) let popItemValue = function (sel, val)
@@ -281,7 +280,7 @@
popItemValue('.OrganisationRegion', item.regionNameCountry); popItemValue('.OrganisationRegion', item.regionNameCountry);
popItemValue('.OrganisationCategory', item.categoryDesc); popItemValue('.OrganisationCategory', item.categoryDesc);
popItemValue('.OrganisationAddress', item.addressSummary); popItemValue('.OrganisationAddress', item.addressSummary);
let $orgMbrs = $('.OrganisationMembers', $dlg).empty(); let $orgMbrs = $('.OrganisationMembers', $dlg.activate).empty();
let $mbrTmpl = $('.sax-panel-item-template tr.sax-item.Member'); let $mbrTmpl = $('.sax-panel-item-template tr.sax-item.Member');
sax.debug(response.members, $orgMbrs, $mbrTmpl); sax.debug(response.members, $orgMbrs, $mbrTmpl);
for (let idx = 0; idx < response.members.length; idx++) for (let idx = 0; idx < response.members.length; idx++)
@@ -295,7 +294,7 @@
$orgMbrs.append($item); $orgMbrs.append($item);
sax.debug($item); sax.debug($item);
} }
sax.openDialog($dlg, 480, 640); sax.openDialog($dlg.activate, 480, 420);
} }
sax.activateOrganisation = function () sax.activateOrganisation = function ()
{ {
@@ -135,11 +135,7 @@
sax.clearControlErrors(); sax.clearControlErrors();
sax.member = { roleCodes: [] }; sax.member = { roleCodes: [] };
sax.$dlg.member.dialog('option', 'title', sax.dlg.title.createMember); sax.$dlg.member.dialog('option', 'title', sax.dlg.title.createMember);
sax.openDialog(sax.$dlg.member, 600, 600); sax.openDialog(sax.$dlg.member, 600, 480);
}
sax.doCreateItem = function ()
{
sax.storeItem();
} }
//-------------------------------------------------------------- //--------------------------------------------------------------
@@ -165,11 +161,7 @@
$('.MemberStatus', $frm).val(item.statusCode); $('.MemberStatus', $frm).val(item.statusCode);
sax.clearControlErrors(); sax.clearControlErrors();
sax.$dlg.member.dialog('option', 'title', sax.dlg.title.updateMember); sax.$dlg.member.dialog('option', 'title', sax.dlg.title.updateMember);
sax.openDialog(sax.$dlg.member, 600, 600); sax.openDialog(sax.$dlg.member, 600, 480);
}
sax.doUpdateItem = function ()
{
sax.storeItem();
} }
//-------------------------------------------------------------- //--------------------------------------------------------------
@@ -208,7 +200,7 @@
$('#ifMemberUserEmailAddress', sax.$frm.member).on('change', function () { sax.onChangeEmail(); }); $('#ifMemberUserEmailAddress', sax.$frm.member).on('change', function () { sax.onChangeEmail(); });
var opt = sax.dlgOpts(); var opt = sax.dlgOpts();
opt.buttons[sax.dlg.btn.ok] = function () { sax.doCreateItem(); }; opt.buttons[sax.dlg.btn.ok] = function () { sax.storeItem(); };
opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); }; opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); };
sax.$dlg.member = $('#dlgMember').dialog(opt); sax.$dlg.member = $('#dlgMember').dialog(opt);
@@ -101,10 +101,6 @@
sax.$dlg.region.dialog('option', 'title', sax.dlg.title.createRegion); sax.$dlg.region.dialog('option', 'title', sax.dlg.title.createRegion);
sax.openDialog(sax.$dlg.region, 600, 600); sax.openDialog(sax.$dlg.region, 600, 600);
} }
sax.doCreateItem = function ()
{
sax.storeItem();
}
//-------------------------------------------------------------- //--------------------------------------------------------------
sax.updateItem = function (id) sax.updateItem = function (id)
@@ -131,10 +127,6 @@
sax.$dlg.region.dialog('option', 'title', sax.dlg.title.updateRegion); sax.$dlg.region.dialog('option', 'title', sax.dlg.title.updateRegion);
sax.openDialog(sax.$dlg.region, 600, 600); sax.openDialog(sax.$dlg.region, 600, 600);
} }
sax.doUpdateItem = function ()
{
sax.storeItem();
}
//-------------------------------------------------------------- //--------------------------------------------------------------
sax.storeItem = function () sax.storeItem = function ()
@@ -174,7 +166,7 @@
sax.$frm.region = $('#frmRegion'); sax.$frm.region = $('#frmRegion');
var opt = sax.dlgOpts(); var opt = sax.dlgOpts();
opt.buttons[sax.dlg.btn.ok] = function () { sax.doCreateItem(); }; opt.buttons[sax.dlg.btn.ok] = function () { sax.storeItem(); };
opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); }; opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); };
sax.$dlg.region = $('#dlgRegion').dialog(opt); sax.$dlg.region = $('#dlgRegion').dialog(opt);
@@ -75,10 +75,6 @@
sax.$dlg.dbTable.dialog('option', 'title', sax.dlg.title.viewDatabaseTable); sax.$dlg.dbTable.dialog('option', 'title', sax.dlg.title.viewDatabaseTable);
sax.openDialog(sax.$dlg.dbTable, 600, 600); sax.openDialog(sax.$dlg.dbTable, 600, 600);
} }
sax.doUpdateItem = function ()
{
sax.storeItem();
}
//-------------------------------------------------------------- //--------------------------------------------------------------
$(function () $(function ()
@@ -92,7 +88,7 @@
sax.$frm.dbTable = $('#frmDatabaseTable'); sax.$frm.dbTable = $('#frmDatabaseTable');
var opt = sax.dlgOpts(); var opt = sax.dlgOpts();
opt.buttons[sax.dlg.btn.ok] = function () { sax.doCreateItem(); }; opt.buttons[sax.dlg.btn.ok] = function () { sax.storeItem(); };
opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); }; opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); };
sax.$dlg.dbTable = $('#dlgDatabaseTable').dialog(opt); sax.$dlg.dbTable = $('#dlgDatabaseTable').dialog(opt);
+3 -3
View File
@@ -210,7 +210,7 @@
sax.clearControlErrors(); sax.clearControlErrors();
sax.userAccount = { userRoleCodes: [] }; sax.userAccount = { userRoleCodes: [] };
$dlg.user.dialog('option', 'title', sax.dlg.title.createUser); $dlg.user.dialog('option', 'title', sax.dlg.title.createUser);
sax.openDialog($dlg.user, 600, 600); sax.openDialog($dlg.user, 600, 480);
} }
//-------------------------------------------------------------- //--------------------------------------------------------------
@@ -237,7 +237,7 @@
$('#ifUserRoleCodes').val(item.userRoleCodes.join(sax.data.userRoleCodeDelim)); $('#ifUserRoleCodes').val(item.userRoleCodes.join(sax.data.userRoleCodeDelim));
$('.UserStatus', frm).val(item.statusCode); $('.UserStatus', frm).val(item.statusCode);
$dlg.user.dialog('option', 'title', sax.dlg.title.updateUser); $dlg.user.dialog('option', 'title', sax.dlg.title.updateUser);
sax.openDialog($dlg.user, 600, 600); sax.openDialog($dlg.user, 600, 480);
} }
//-------------------------------------------------------------- //--------------------------------------------------------------
@@ -274,7 +274,7 @@
$('.RequestPasswordAdminOption', frm).toggle(item.systemAdmin); $('.RequestPasswordAdminOption', frm).toggle(item.systemAdmin);
$('input[type="checkbox"]', frm).prop('checked', false); $('input[type="checkbox"]', frm).prop('checked', false);
$dlg.emails.dialog('option', { 'title': sax.dlg.title.selectUserEmails }); $dlg.emails.dialog('option', { 'title': sax.dlg.title.selectUserEmails });
sax.openDialog($dlg.emails, 600, 600); sax.openDialog($dlg.emails, 600, 360);
} }
sax.sendUserEmails = function () sax.sendUserEmails = function ()
{ {
@@ -14,6 +14,7 @@ using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Base.Utils;
using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas; using Sarand.Net.Standard.Base.Dbas;
using Saxonite.Net.Standard.Base.App;
namespace Saxonite.Net.Core.Web.Online.Controllers namespace Saxonite.Net.Core.Web.Online.Controllers
{ {
@@ -35,6 +36,11 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
public String RegionName { get; set; } public String RegionName { get; set; }
public long MemberCount { get; set; } public long MemberCount { get; set; }
public long OpportunityCount { get; set; } public long OpportunityCount { get; set; }
public bool? Admin { get; set; } = null;
public bool? MemberAdmin { get; set; } = null;
public bool? OpportunitiyAdmin { get; set; } = null;
public bool? ScheduleAdmin { get; set; } = null;
public bool? ArticleAdmin { get; set; } = null;
} }
private class AjaxResponse_ProfileOrganisationsData : AjaxResponse_Data private class AjaxResponse_ProfileOrganisationsData : AjaxResponse_Data
{ {
@@ -78,13 +84,15 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
ColumnDfn colOpportunityCount = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.Organisation_Opportunity_Count); ColumnDfn colOpportunityCount = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.Organisation_Opportunity_Count);
ColumnDfn colStatus = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.Status); ColumnDfn colStatus = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.Status);
ColumnDfn colCreatedOn = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.CreateOn_Date); ColumnDfn colCreatedOn = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.CreateOn_Date);
ColumnDfn colRoleCodes = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.OrganisationRoleCodes);
List<ColumnDfn> columns = new List<ColumnDfn>() List<ColumnDfn> columns = new List<ColumnDfn>()
{ {
colId, colOrganisationId , colOrganisationName, colId, colOrganisationId , colOrganisationName,
colOrganisationSportId, colOrganisationSportName, colOrganisationSportId, colOrganisationSportName,
colOrganisationRegionId, colOrganisationRegionName, colOrganisationRegionId, colOrganisationRegionName,
colMemberCount, colOpportunityCount, colMemberCount, colOpportunityCount,
colStatus, colStatus, colCreatedOn colStatus, colStatus, colCreatedOn,
colRoleCodes
}; };
// Sort columns. // Sort columns.
@@ -97,6 +105,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord()) while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
{ {
NamedValue.Map values = resultSet.GetRecordValues(); NamedValue.Map values = resultSet.GetRecordValues();
List<String> roleCodes = StringListUtil.Split(values.GetString(colRoleCodes.DataName), ",");
ProfileOrganisationData organisationData = new ProfileOrganisationData() ProfileOrganisationData organisationData = new ProfileOrganisationData()
{ {
Id = values.GetLong(colId.DataName), Id = values.GetLong(colId.DataName),
@@ -108,6 +117,16 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
MemberCount = values.GetLong(colMemberCount.DataName), MemberCount = values.GetLong(colMemberCount.DataName),
OpportunityCount = values.GetLong(colOpportunityCount.DataName) OpportunityCount = values.GetLong(colOpportunityCount.DataName)
}; };
if (roleCodes.ContainsCI(OrganisationRoleCodes.GetCodeForType(Sax.OrganisationRole.Admin)))
organisationData.Admin = true;
if (roleCodes.ContainsCI(OrganisationRoleCodes.GetCodeForType(Sax.OrganisationRole.MemberAdmin)))
organisationData.MemberAdmin = true;
if (roleCodes.ContainsCI(OrganisationRoleCodes.GetCodeForType(Sax.OrganisationRole.OpportunityAdmin)))
organisationData.OpportunitiyAdmin = true;
if (roleCodes.ContainsCI(OrganisationRoleCodes.GetCodeForType(Sax.OrganisationRole.ScheduleAdmin)))
organisationData.ScheduleAdmin = true;
if (roleCodes.ContainsCI(OrganisationRoleCodes.GetCodeForType(Sax.OrganisationRole.ArticleAdmin)))
organisationData.ArticleAdmin = true;
responseData.Organisations.Add(organisationData); responseData.Organisations.Add(organisationData);
} }
} }
@@ -145,7 +145,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
RefreshModel(model); RefreshModel(model);
// Organisations that the user has rights to author articles for. // Organisations that the user has rights to author articles for.
foreach (SaxAccountMgr.OrganisationIdName organisation in AccountMgr.GetOrganisationsForUserRole(userAccountId, Sax.OrganisationRole.ArticleAdmin)) foreach (SaxAccountMgr.OrganisationIdName organisation in AccountMgr.GetOrganisationsForAnyUserRole(userAccountId, new [] { Sax.OrganisationRole.Admin, Sax.OrganisationRole.ArticleAdmin }))
{ {
if (responseData.Organisations == null) responseData.Organisations = new List<OrganisationData>(); if (responseData.Organisations == null) responseData.Organisations = new List<OrganisationData>();
OrganisationData organisationData = new OrganisationData() OrganisationData organisationData = new OrganisationData()
@@ -450,7 +450,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
if (SysId.IsValid(organisationId)) if (SysId.IsValid(organisationId))
{ {
// Organisation specified - User must have Article Admin role. // Organisation specified - User must have Article Admin role.
if (!AccountMgr.UserHasOrganisationRole(userAccountId, organisationId, Sax.OrganisationRole.ArticleAdmin)) if (!AccountMgr.UserHasAnyOrganisationRole(userAccountId, organisationId, new [] { Sax.OrganisationRole.Admin, Sax.OrganisationRole.ArticleAdmin }))
{ {
SaLogger.Warn(fn + " User does not have Article Admin role for organisation." + GetLogSuffix()); SaLogger.Warn(fn + " User does not have Article Admin role for organisation." + GetLogSuffix());
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
@@ -34,7 +34,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
return RedirectToAction("", ""); return RedirectToAction("", "");
// User must either be a Journalist or have Article Admin rights with at least one organisation. // User must either be a Journalist or have Article Admin rights with at least one organisation.
List<SaxAccountMgr.OrganisationIdName> organisations = AccountMgr.GetOrganisationsForUserRole(SessionData.User.UserAccountId, Sax.OrganisationRole.ArticleAdmin); List<SaxAccountMgr.OrganisationIdName> organisations = AccountMgr.GetOrganisationsForAnyUserRole(SessionData.User.UserAccountId, new [] { Sax.OrganisationRole.Admin, Sax.OrganisationRole.ArticleAdmin });
if (organisations.Count < 1 && !UserIsJournalist) if (organisations.Count < 1 && !UserIsJournalist)
return RedirectToAction("", ""); return RedirectToAction("", "");
@@ -104,17 +104,20 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
RefreshModel(model); RefreshModel(model);
// Organisation. // Record disposable items as they are created so all can be disposed when needed.
SysId organisationId = model.ExtractSysId(model.Filter.OrganisationId); using (DisposableCollection<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId);
if (organisation == null || !organisation.IsStatusActive)
{ {
SaLogger.Warn(fn + " " + (organisation == null ? "Invalid" : "Inactive") + " organisation for Member list. OrganisationId: '" + model.Filter.OrganisationId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
if (organisation != null) // Organisation.
{ SysId organisationId = model.ExtractSysId(model.Filter.OrganisationId);
SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId);
disposableItems.Add(organisation);
if (organisation == null || !organisation.IsStatusActive)
{
SaLogger.Warn(fn + " " + (organisation == null ? "Invalid" : "Inactive") + " organisation for Member list. OrganisationId: '" + model.Filter.OrganisationId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
// Store filter data. // Store filter data.
SessionData_Online.Filter.SetMemberOrganisation(organisation); SessionData_Online.Filter.SetMemberOrganisation(organisation);
@@ -124,11 +127,11 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
responseData.Titles.Add(title.Code, title.Desc); responseData.Titles.Add(title.Code, title.Desc);
// Reference data - member roles. // Reference data - member roles.
foreach (TypeCodeDesc memberRole in OrganisationRoleCodes.FindAll( item => item.Type != (int)Sax.OrganisationRole.Member)) foreach (TypeCodeDesc memberRole in OrganisationRoleCodes.FindAll(item => item.Type != (int)Sax.OrganisationRole.Member))
responseData.MemberRoles.Add(memberRole.Code, Localiser.GetOrganisationRoleCaption((Sax.OrganisationRole)memberRole.Type)); responseData.MemberRoles.Add(memberRole.Code, Localiser.GetOrganisationRoleCaption((Sax.OrganisationRole)memberRole.Type));
// Session User roles. // Session User roles.
responseData.User.CanManage = AccountMgr.UserHasOrganisationRole(SessionData.User.UserAccountId, organisationId, Sax.OrganisationRole.MemberAdmin); responseData.User.CanManage = AccountMgr.UserHasAnyOrganisationRole(SessionData.User.UserAccountId, organisation.Id, new List<Sax.OrganisationRole> { Sax.OrganisationRole.Admin, Sax.OrganisationRole.MemberAdmin });
// Item filter. // Item filter.
SaxUserOrganisation.Params prmMember = new SaxUserOrganisation.Params(); SaxUserOrganisation.Params prmMember = new SaxUserOrganisation.Params();
@@ -150,11 +153,11 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
ColumnDfn colAdminComment = responseData.User.CanManage ? AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.AdminComment) : new ColumnDfn(-1, ""); ColumnDfn colAdminComment = responseData.User.CanManage ? AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.AdminComment) : new ColumnDfn(-1, "");
ColumnDfn colCreatedOn = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.CreateOn_Date); ColumnDfn colCreatedOn = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.CreateOn_Date);
List<ColumnDfn> columns = new List<ColumnDfn>() List<ColumnDfn> columns = new List<ColumnDfn>()
{ {
colId, colUserAccountId , colEmailAddress, colDisplayName, colId, colUserAccountId , colEmailAddress, colDisplayName,
colOrganisationRoleCodes, colUserStatus, colOrganisationRoleCodes, colUserStatus,
colAdminComment, colCreatedOn colAdminComment, colCreatedOn
}; };
// Sort columns. // Sort columns.
colCreatedOn.SortAscending = false; colCreatedOn.SortAscending = false;
@@ -230,9 +233,13 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
if (!SysId.IsValid(memberId)) if (!SysId.IsValid(memberId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
// Retrieve item. // Record disposable items as they are created so all can be disposed when needed.
using (SaxUserOrganisation userOrganisation = AccountMgr.GetUserOrganisationById(memberId)) using (DisposableCollection<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
{ {
// Retrieve item.
SaxUserOrganisation userOrganisation = AccountMgr.GetUserOrganisationById(memberId);
disposableItems.Add(userOrganisation);
if (userOrganisation == null) if (userOrganisation == null)
{ {
SaLogger.Warn(fn + " Failed to retrieve Organisation Member for Id: '" + model.MemberId + "'"); SaLogger.Warn(fn + " Failed to retrieve Organisation Member for Id: '" + model.MemberId + "'");
@@ -240,33 +247,31 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
} }
// Validate organisation. // Validate organisation.
using (SaxOrganisation organisation = AccountMgr.GetOrganisationById(userOrganisation.OrganisationId)) SaxOrganisation organisation = AccountMgr.GetOrganisationById(userOrganisation.OrganisationId);
disposableItems.Add(organisation);
if (organisation == null || !organisation.IsStatusActive)
{ {
if (organisation == null || !organisation.IsStatusActive) SaLogger.Warn(fn + " " + (organisation == null ? "Invalid" : "Inactive") + " Organisation for Member. Id: '" + userOrganisation.OrganisationId + "'");
{ return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
SaLogger.Warn(fn + " " + (organisation == null ? "Invalid" : "Inactive") + " Organisation for Member. Id: '" + userOrganisation.OrganisationId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
// Session User roles.
bool userCanManageMembers = AccountMgr.UserHasOrganisationRole(SessionData.User.UserAccountId, organisation.Id, Sax.OrganisationRole.MemberAdmin);
// Validate user account.
using (SaxUserAccount userAccount = AccountMgr.GetUserAccountById(userOrganisation.UserAccountId))
{
bool userActive = userAccount.IsStatusActive || (userAccount.IsStatusAwaiting && userCanManageMembers);
if (userAccount == null || !userActive)
{
SaLogger.Warn(fn + " " + (organisation == null ? "Invalid" : "Inactive") + " User Account for Member. Id: '" + userOrganisation.UserAccountId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
// Make a note of the selected Organisation.
SessionData_Online.Filter.SetMemberOrganisation(organisation);
PopulateMemberResponseData(model, userOrganisation, userAccount, organisation, responseData.Member);
}
} }
// Session User roles.
bool userCanManageMembers = AccountMgr.UserHasAnyOrganisationRole(SessionData.User.UserAccountId, organisation.Id, new List<Sax.OrganisationRole> { Sax.OrganisationRole.Admin, Sax.OrganisationRole.MemberAdmin });
// Validate user account.
SaxUserAccount userAccount = AccountMgr.GetUserAccountById(userOrganisation.UserAccountId);
disposableItems.Add(userAccount);
bool userActive = userAccount.IsStatusActive || (userAccount.IsStatusAwaiting && userCanManageMembers);
if (userAccount == null || !userActive)
{
SaLogger.Warn(fn + " " + (organisation == null ? "Invalid" : "Inactive") + " User Account for Member. Id: '" + userOrganisation.UserAccountId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
// Make a note of the selected Organisation.
SessionData_Online.Filter.SetMemberOrganisation(organisation);
PopulateMemberResponseData(model, userOrganisation, userAccount, organisation, responseData.Member);
} }
// Construct response. // Construct response.
@@ -361,7 +366,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
} }
// Ensure that the user has the correct role to update Members for this organisation. // Ensure that the user has the correct role to update Members for this organisation.
bool userCanManageMembers = AccountMgr.UserHasOrganisationRole(SessionData.User.UserAccountId, organisationId, Sax.OrganisationRole.MemberAdmin); bool userCanManageMembers = AccountMgr.UserHasAnyOrganisationRole(SessionData.User.UserAccountId, organisationId, new List<Sax.OrganisationRole> { Sax.OrganisationRole.Admin, Sax.OrganisationRole.MemberAdmin });
if (!userCanManageMembers) if (!userCanManageMembers)
{ {
SaLogger.Warn(fn + " User doesn't have 'Member Admin' role for Organisation Id: " + organisationId); SaLogger.Warn(fn + " User doesn't have 'Member Admin' role for Organisation Id: " + organisationId);
@@ -385,6 +390,23 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
SaLogger.Warn(fn + " Inconsistent User Account Id specified for User Organisation. Expected: " + userOrganisation.UserAccountId + ". Found: " + userAccount.Id); SaLogger.Warn(fn + " Inconsistent User Account Id specified for User Organisation. Expected: " + userOrganisation.UserAccountId + ". Found: " + userAccount.Id);
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
} }
// Validate roles for current user.
if (userOrganisation.UserAccountId.Equals(SessionData.User.UserAccountId))
{
// User is modifying their own organisation member.
if (userOrganisation.CanManageOrganisation && !model.OrganisationRoleCodes.Any(item => item.Type == (int)Sax.OrganisationRole.Admin))
{
// User has removed their own 'Admin' role.
SaLogger.Warn(fn + " Unable to store member - user is attempting to remove their own 'Admin' role.");
return Json(responseData.SetMessage(messageTitle, Localiser["organisation.members.msg.remove.own.admin.role"]));
}
if (!userOrganisation.CanManageMembers)
{
SaLogger.Warn(fn + " Unable to store member - user is attempting to remove their own 'Admin' and/or 'Member Admin' role.");
return Json(responseData.SetMessage(messageTitle, Localiser["organisation.members.msg.remove.own.admin.role"]));
}
}
} }
// New member - Lookup user by email and create new account if needed. // New member - Lookup user by email and create new account if needed.
@@ -458,17 +480,6 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
// Ensure user has member role. // Ensure user has member role.
userOrganisation.AddOrganisationRole(Sax.OrganisationRole.Member); userOrganisation.AddOrganisationRole(Sax.OrganisationRole.Member);
// Validate roles.
if (userOrganisation.UserAccountId.Equals(SessionData.User.UserAccountId))
{
// User is modifying their own member.
if (!userOrganisation.HasOrganisationRole(Sax.OrganisationRole.MemberAdmin))
{
SaLogger.Warn(fn + " Unable to store member - user is attempting to remove their own 'Member Admin' role.");
return Json(responseData.SetMessage(messageTitle, Localiser["organisation.members.msg.remove.own.admin.role"]));
}
}
// User organisation properties. // User organisation properties.
if (model.MemberAdminComment != null) if (model.MemberAdminComment != null)
userOrganisation.AdminComment = model.MemberAdminComment; userOrganisation.AdminComment = model.MemberAdminComment;
@@ -548,7 +559,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
} }
// Ensure that the user has the correct role to update Members for this organisation. // Ensure that the user has the correct role to update Members for this organisation.
bool userCanManageMembers = AccountMgr.UserHasOrganisationRole(SessionData.User.UserAccountId, organisation.Id, Sax.OrganisationRole.MemberAdmin); bool userCanManageMembers = AccountMgr.UserHasAnyOrganisationRole(SessionData.User.UserAccountId, organisation.Id, new List<Sax.OrganisationRole> { Sax.OrganisationRole.Admin, Sax.OrganisationRole.MemberAdmin });
if (!userCanManageMembers) if (!userCanManageMembers)
{ {
SaLogger.Warn(fn + " User doesn't have 'Member Admin' role for Organisation Id: " + organisation.Id); SaLogger.Warn(fn + " User doesn't have 'Member Admin' role for Organisation Id: " + organisation.Id);
@@ -664,7 +675,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
} }
// Ensure that the user has the correct role to update Members for this organisation. // Ensure that the user has the correct role to update Members for this organisation.
bool userCanManageMembers = AccountMgr.UserHasOrganisationRole(SessionData.User.UserAccountId, organisation.Id, Sax.OrganisationRole.MemberAdmin); bool userCanManageMembers = AccountMgr.UserHasAnyOrganisationRole(SessionData.User.UserAccountId, organisation.Id, new List<Sax.OrganisationRole> { Sax.OrganisationRole.Admin, Sax.OrganisationRole.MemberAdmin });
if (!userCanManageMembers) if (!userCanManageMembers)
{ {
SaLogger.Warn(fn + " User doesn't have 'Member Admin' role for Organisation Id: " + organisation.Id); SaLogger.Warn(fn + " User doesn't have 'Member Admin' role for Organisation Id: " + organisation.Id);
@@ -154,7 +154,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
responseData.Organisation.RegionName = model.GetRegionCaption(organisation.RegionIdPrimary); responseData.Organisation.RegionName = model.GetRegionCaption(organisation.RegionIdPrimary);
// User details. // User details.
responseData.User.CanManage = userOrganisation?.HasOrganisationRole(Sax.OrganisationRole.OpportunityAdmin) ?? false; responseData.User.CanManage = userOrganisation.CanManageOpportunities;
// Item filter. // Item filter.
SaxOrganisationOpportunity.Params prmOpportunity = new SaxOrganisationOpportunity.Params(); SaxOrganisationOpportunity.Params prmOpportunity = new SaxOrganisationOpportunity.Params();
@@ -354,7 +354,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
} }
// Ensure that the user has the correct role to update Opportunities for this organisation. // Ensure that the user has the correct role to update Opportunities for this organisation.
if (!AccountMgr.UserHasOrganisationRole(SessionData.User.UserAccountId, organisationId, Sax.OrganisationRole.OpportunityAdmin)) if (!AccountMgr.UserHasAnyOrganisationRole(SessionData.User.UserAccountId, organisationId, new [] { Sax.OrganisationRole.Admin, Sax.OrganisationRole.OpportunityAdmin }))
{ {
SaLogger.Warn(fn + " User doesn't have 'Opportunity Admin' role for Organisation Id: " + organisationId); SaLogger.Warn(fn + " User doesn't have 'Opportunity Admin' role for Organisation Id: " + organisationId);
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
@@ -152,7 +152,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
// Add user as member of organisation. // Add user as member of organisation.
SaxUserOrganisation userOrganisation = AccountMgr.CreateUserOrganisation(userAccount.Id, organisation.Id); SaxUserOrganisation userOrganisation = AccountMgr.CreateUserOrganisation(userAccount.Id, organisation.Id);
userOrganisation.OrganisationRoles = new List<Sax.OrganisationRole>() { Sax.OrganisationRole.Member, Sax.OrganisationRole.MemberAdmin }; userOrganisation.OrganisationRoles = new [] { Sax.OrganisationRole.Member, Sax.OrganisationRole.Admin };
if (!AccountMgr.InsertUserOrganisation(userOrganisation, DbUpdateInfo)) if (!AccountMgr.InsertUserOrganisation(userOrganisation, DbUpdateInfo))
{ {
SaLogger.Warn(fn + " Failed to insert user organisation - " + AccountMgr.ErrorStateMessage); SaLogger.Warn(fn + " Failed to insert user organisation - " + AccountMgr.ErrorStateMessage);
@@ -181,7 +181,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
} }
// Complete response. // Complete response.
responseData.SetMessage(messageTitle, Localiser["msg.organisation.request.success"].ToString().ReplaceAll("\n", "<br>")); responseData.SetMessage(messageTitle, Localiser["msg.organisation.request.success"].ToString().ReplaceAll("\n", "<br/><br/>"));
responseData.Success = true; responseData.Success = true;
return Json(responseData); return Json(responseData);
} }
@@ -22,8 +22,9 @@ namespace Saxonite.Net.Core.Web.Online.Models
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Data members. // Data members.
private bool? userCanManageOrganisationMembers = null; private bool? userCanManageOrganisationMembers = null;
private bool? userCanManageOrganisationArticles = null;
private bool? userCanManageOrganisationOpportunities = null; private bool? userCanManageOrganisationOpportunities = null;
private bool? userCanManageOrganisationSchedule = null;
private bool? userCanManageOrganisationArticles = null;
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Protected construction. // Protected construction.
@@ -51,29 +52,14 @@ namespace Saxonite.Net.Core.Web.Online.Models
SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params(); SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params();
prmUserOrganisation.UserAccountIdsIncluded.Add(SessionData.User.UserAccountId); prmUserOrganisation.UserAccountIdsIncluded.Add(SessionData.User.UserAccountId);
prmUserOrganisation.OrganisationMembersOnly = true; prmUserOrganisation.OrganisationMembersOnly = true;
prmUserOrganisation.OrganisationRoles.Add(Sax.OrganisationRole.OpportunityAdmin); prmUserOrganisation.OrganisationRolesAny.Add(Sax.OrganisationRole.Admin);
prmUserOrganisation.OrganisationRolesAny.Add(Sax.OrganisationRole.MemberAdmin);
prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly; prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly;
userCanManageOrganisationMembers = (AccountMgr.GetUserOrganisationCount(prmUserOrganisation) > 0); userCanManageOrganisationMembers = (AccountMgr.GetUserOrganisationCount(prmUserOrganisation) > 0);
} }
return userCanManageOrganisationMembers == true ? true : false; return userCanManageOrganisationMembers == true ? true : false;
} }
} }
public bool UserCanManageOrganisationArticles
{
get
{
if (userCanManageOrganisationArticles == null && ValidUserSession)
{
SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params();
prmUserOrganisation.UserAccountIdsIncluded.Add(SessionData.User.UserAccountId);
prmUserOrganisation.OrganisationMembersOnly = true;
prmUserOrganisation.OrganisationRoles.Add(Sax.OrganisationRole.ArticleAdmin);
prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly;
userCanManageOrganisationArticles = (AccountMgr.GetUserOrganisationCount(prmUserOrganisation) > 0);
}
return userCanManageOrganisationArticles == true ? true : false;
}
}
public bool UserCanManageOrganisationOpportunities public bool UserCanManageOrganisationOpportunities
{ {
get get
@@ -83,13 +69,48 @@ namespace Saxonite.Net.Core.Web.Online.Models
SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params(); SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params();
prmUserOrganisation.UserAccountIdsIncluded.Add(SessionData.User.UserAccountId); prmUserOrganisation.UserAccountIdsIncluded.Add(SessionData.User.UserAccountId);
prmUserOrganisation.OrganisationMembersOnly = true; prmUserOrganisation.OrganisationMembersOnly = true;
prmUserOrganisation.OrganisationRoles.Add(Sax.OrganisationRole.OpportunityAdmin); prmUserOrganisation.OrganisationRolesAny.Add(Sax.OrganisationRole.Admin);
prmUserOrganisation.OrganisationRolesAny.Add(Sax.OrganisationRole.OpportunityAdmin);
prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly; prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly;
userCanManageOrganisationOpportunities = (AccountMgr.GetUserOrganisationCount(prmUserOrganisation) > 0); userCanManageOrganisationOpportunities = (AccountMgr.GetUserOrganisationCount(prmUserOrganisation) > 0);
} }
return userCanManageOrganisationOpportunities == true ? true : false; return userCanManageOrganisationOpportunities == true ? true : false;
} }
} }
public bool UserCanManageOrganisationSchedule
{
get
{
if (userCanManageOrganisationSchedule == null && ValidUserSession)
{
SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params();
prmUserOrganisation.UserAccountIdsIncluded.Add(SessionData.User.UserAccountId);
prmUserOrganisation.OrganisationMembersOnly = true;
prmUserOrganisation.OrganisationRolesAny.Add(Sax.OrganisationRole.Admin);
prmUserOrganisation.OrganisationRolesAny.Add(Sax.OrganisationRole.ScheduleAdmin);
prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly;
userCanManageOrganisationSchedule = (AccountMgr.GetUserOrganisationCount(prmUserOrganisation) > 0);
}
return userCanManageOrganisationSchedule == true ? true : false;
}
}
public bool UserCanManageOrganisationArticles
{
get
{
if (userCanManageOrganisationArticles == null && ValidUserSession)
{
SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params();
prmUserOrganisation.UserAccountIdsIncluded.Add(SessionData.User.UserAccountId);
prmUserOrganisation.OrganisationMembersOnly = true;
prmUserOrganisation.OrganisationRolesAny.Add(Sax.OrganisationRole.Admin);
prmUserOrganisation.OrganisationRolesAny.Add(Sax.OrganisationRole.ArticleAdmin);
prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly;
userCanManageOrganisationArticles = (AccountMgr.GetUserOrganisationCount(prmUserOrganisation) > 0);
}
return userCanManageOrganisationArticles == true ? true : false;
}
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Item Id Obfuscation. // Item Id Obfuscation.
@@ -1,13 +1,13 @@
@model SaxModel_Online @model SaxModel_Online
@inject SaxLocaliser Localiser @inject SaxLocaliser Localiser
@{ @{
int regionIdCountry = Model.ValidUserSession ? Model.SessionData.User.RegionIdCountry.ToInt() : 0; String regionIdCountry = Model.ValidUserSession ? Model.SessionData.User.RegionIdCountry.ToString() : "";
String regionNameCountry = Model.ValidUserSession ? Localiser.EscapeJavascriptText(Model.GetRegionCaption(Model.SessionData.User.RegionIdCountry)) : ""; String regionNameCountry = Model.ValidUserSession ? Localiser.EscapeJavascriptText(Model.GetRegionCaption(Model.SessionData.User.RegionIdCountry)) : "";
} }
<script type="text/javascript"> <script type="text/javascript">
let or = sax.orgReq = {}; let or = sax.orgReq = {};
or.dlgTitleRequestOrganisation = '@Localiser.GetJavascriptText("organisation.caption.organisation.request")'; or.dlgTitleRequestOrganisation = '@Localiser.GetJavascriptText("organisation.caption.organisation.request")';
sax.data.regionIdCountryDefault = @regionIdCountry; sax.data.regionIdCountryDefault = '@regionIdCountry';
sax.data.regionNameCountryDefault = '@regionNameCountry'; sax.data.regionNameCountryDefault = '@regionNameCountry';
</script> </script>
@@ -28,47 +28,52 @@
@* Contact Email Address *@ @* Contact Email Address *@
<div class="sax-form-control ContactEmailAddress"> <div class="sax-form-control ContactEmailAddress">
<div class="sax-label"> <div class="row">
<label for="ifContactEmailAddress"><span>@Localiser["label.email"]</span><span class="required">&nbsp;*</span></label> <div class="col-sm-4">
<div class="sax-label">
<label for="ifContactEmailAddress"><span>@Localiser["label.email"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control">
<input type="text" id="ifContactEmailAddress" name="ContactEmailAddress" class="ContactEmailAddress sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_EmailAddress)" />
</div>
<div class="sax-message"></div>
</div>
</div> </div>
<div class="sax-control">
<input type="text" id="ifContactEmailAddress" name="ContactEmailAddress" class="ContactEmailAddress sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_EmailAddress)" />
</div>
<div class="sax-message"></div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-sm-4">@* No label. *@</div>
<div class="col-sm-6"> <div class="col-sm row">
@* Contact First Name *@ @* Contact First Name *@
<div class="sax-form-control ContactFirstName pr4"> <div class="col-sm-6">
<div class="sax-label"> <div class="sax-form-control ContactFirstName pr4">
<label for="cbContactFirstName"><span>@Localiser["label.first.name"]</span><span class="required">&nbsp;*</span></label> <div class="sax-label">
<label for="cbContactFirstName"><span>@Localiser["label.first.name"]</span><span class="required">&nbsp;*</span></label>
</div>
<div class="sax-control">
<input type="text" id="ifContactFirstName" name="ContactFirstName" class="ContactFirstName sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_FirstName)" />
</div>
<div class="sax-message"></div>
</div> </div>
<div class="sax-control">
<input type="text" id="ifContactFirstName" name="ContactFirstName" class="ContactFirstName sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_FirstName)" />
</div>
<div class="sax-message"></div>
</div> </div>
</div>
<div class="col-sm-6">
@* Contact Last Name *@ @* Contact Last Name *@
<div class="sax-form-control ContactLastName pr4"> <div class="col-sm-6">
<div class="sax-label"> <div class="sax-form-control ContactLastName">
<label for="cbContactLastName"><span>@Localiser["label.last.name"]</span><span class="required">&nbsp;*</span></label> <div class="sax-label">
<label for="cbContactLastName"><span>@Localiser["label.last.name"]</span><span class="required">&nbsp;*</span></label>
</div>
<div class="sax-control">
<input type="text" id="ifContactLastName" name="ContactLastName" class="ContactLastName sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_LastName)" />
</div>
<div class="sax-message"></div>
</div> </div>
<div class="sax-control">
<input type="text" id="ifContactLastName" name="ContactLastName" class="ContactLastName sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_LastName)" />
</div>
<div class="sax-message"></div>
</div> </div>
</div> </div>
</div> </div>
} }
@@ -81,147 +86,202 @@
@* Organisation name *@ @* Organisation name *@
<div class="sax-form-control OrganisationName"> <div class="sax-form-control OrganisationName">
<div class="sax-label"> <div class="row">
<label for="ifOrganisationName"><span>@Localiser["label.name"]</span><span class="required">&nbsp;*</span></label> <div class="col-sm-4">
<div class="sax-label">
<label for="ifOrganisationName"><span>@Localiser["label.name"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control">
<input type="text" id="ifOrganisationName" name="OrganisationName" class="OrganisationName sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Organisation_Name)" />
</div>
<div class="sax-message"></div>
</div>
</div> </div>
<div class="sax-control">
<input type="text" id="ifOrganisationName" name="OrganisationName" class="OrganisationName sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Organisation_Name)" />
</div>
<div class="sax-message"></div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-sm-4"></div>
<div class="col-sm-6"> <div class="col-sm row">
@* Organisation category *@ @* Organisation category *@
<div class="sax-form-control OrganisationCategory pr4"> <div class="col-sm-6">
<div class="sax-label"> <div class="sax-form-control OrganisationCategory pr4">
<label for="cbOrganisationCategory"><span>@Localiser["label.category"]</span><span class="required">&nbsp;*</span></label> <div class="sax-label">
<label for="cbOrganisationCategory"><span>@Localiser["label.category"]</span><span class="required">&nbsp;*</span></label>
</div>
<div class="sax-control">
@Html.DropDownList("", Model.OrganisationCategoriesForSelect, Localiser["label.select"], new { @id = "cbOrganisationCategory", @name = "OrganisationCategory", @class = "OrganisationCategory sax-select" })
</div>
<div class="sax-message"></div>
</div> </div>
<div class="sax-control">
@Html.DropDownList("", Model.OrganisationCategoriesForSelect, Localiser["label.select"], new { @id = "cbOrganisationCategory", @name = "OrganisationCategory", @class = "OrganisationCategory sax-select" })
</div>
<div class="sax-message"></div>
</div> </div>
</div>
<div class="col-sm-6">
@* Organisation type *@ @* Organisation type *@
<div class="sax-form-control OrganisationType"> <div class="col-sm-6">
<div class="sax-label"> <div class="sax-form-control OrganisationType">
<label for="cbOrganisationType"><span>@Localiser["label.type"]</span><span class="required">&nbsp;*</span></label> <div class="sax-label">
<label for="cbOrganisationType"><span>@Localiser["label.type"]</span><span class="required">&nbsp;*</span></label>
</div>
<div class="sax-control">
@Html.DropDownList("", Model.OrganisationTypesForSelect, Localiser["label.select"], new { @id = "cbOrganisationType", @name = "OrganisationType", @class = "OrganisationType sax-select" })
</div>
<div class="sax-message"></div>
</div> </div>
<div class="sax-control">
@Html.DropDownList("", Model.OrganisationTypesForSelect, Localiser["label.select"], new { @id = "cbOrganisationType", @name = "OrganisationType", @class = "OrganisationType sax-select" })
</div>
<div class="sax-message"></div>
</div> </div>
</div> </div>
</div> </div>
@* Organisation sport *@ @* Organisation sport *@
<div class="sax-form-control OrganisationSportId"> <div class="sax-form-control OrganisationSportId">
<div class="sax-label"> <div class="row">
<label for="ifOrganisationSportCaption"><span>@Localiser["label.sport"]</span><span class="required">&nbsp;*</span></label> <div class="col-sm-4">
<div class="sax-label">
<label for="ifOrganisationSportCaption"><span>@Localiser["label.sport"]</span><span class="required">&nbsp;(*)</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<input type="hidden" id="ifOrganisationSportId" name="OrganisationSportId" OrganisationSportId"" class="OrganisationSportId" />
<div class="col"><input type="text" id="ifOrganisationSportCaption" class="OrganisationSportCaption sax-input" readonly="readonly" ondblclick="sax.selectSport()" /> </div>
<div class="fixed"><button class="SelectSport sax-button" style="min-width:auto;margin-left:4px;padding:4px 6px" onclick="sax.selectOrgSport()">@Localiser["label.select"]</button></div>
</div>
<div class="sax-message"></div>
</div>
</div> </div>
<div class="sax-control row">
<input type="hidden" id="ifOrganisationSportId" name="OrganisationSportId" OrganisationSportId"" class="OrganisationSportId" />
<div class="col"><input type="text" id="ifOrganisationSportCaption" class="OrganisationSportCaption sax-input" readonly="readonly" ondblclick="sax.selectSport()" /> </div>
<div class="fixed"><button class="SelectSport sax-button" style="min-width:auto;margin-left:4px;padding:4px 6px" onclick="sax.selectOrgSport()">@Localiser["label.select"]</button></div>
</div>
<div class="sax-message"></div>
</div> </div>
@* Organisation country *@ @* Organisation country *@
<div class="sax-form-control OrganisationRegionIdCountry"> <div class="sax-form-control OrganisationRegionIdCountry">
<div class="sax-label"> <div class="row">
<label for="ifOrganisationRegionCaption"><span>@Localiser["label.country"]</span><span class="required">&nbsp;*</span></label> <div class="col-sm-4">
<div class="sax-label">
<label for="ifOrganisationRegionCaption"><span>@Localiser["label.country"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<input type="hidden" id="ifOrganisationRegionIdCountry" name="OrganisationRegionIdCountry" OrganisationRegionIdCountry"" class="OrganisationRegionIdCountry" />
<div class="col"><input type="text" id="ifOrganisationRegionCaptionCountry" class="OrganisationRegionCaptionCountry sax-input" readonly="readonly" ondblclick="sax.selectRegion()" /> </div>
<div class="fixed"><button class="SelectRegion sax-button" style="min-width:auto;margin-left:4px;padding:4px 6px" onclick="sax.selectOrgRegion()">@Localiser["label.select"]</button></div>
</div>
<div class="sax-message"></div>
</div>
</div> </div>
<div class="sax-control row">
<input type="hidden" id="ifOrganisationRegionIdCountry" name="OrganisationRegionIdCountry" OrganisationRegionIdCountry"" class="OrganisationRegionIdCountry" />
<div class="col"><input type="text" id="ifOrganisationRegionCaptionCountry" class="OrganisationRegionCaptionCountry sax-input" readonly="readonly" ondblclick="sax.selectRegion()" /> </div>
<div class="fixed"><button class="SelectRegion sax-button" style="min-width:auto;margin-left:4px;padding:4px 6px" onclick="sax.selectOrgRegion()">@Localiser["label.select"]</button></div>
</div>
<div class="sax-message"></div>
</div> </div>
@* Organisation address - Line 1 *@ @* Organisation address - Line 1 *@
<div class="sax-form-control OrganisationAddressLine1"> <div class="sax-form-control OrganisationAddressLine1">
<div class="sax-caption"> <div class="row">
<label for="ifOrganisationAddressLine1"><span>@Localiser["label.organisation.address"]</span><span class="required">&nbsp;*</span></label> <div class="col-sm-4">
<div class="sax-caption">
<label for="ifOrganisationAddressLine1"><span>@Localiser["label.organisation.address"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" id="ifOrganisationAddressLine1" name="OrganisationAddressLine1" class="OrganisationAddressLine1 sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line1)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div> </div>
<div class="sax-control row">
<div class="col"><input type="text" id="ifOrganisationAddressLine1" name="OrganisationAddressLine1" class="OrganisationAddressLine1 sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line1)" /> </div>
</div>
<div class="sax-message"></div>
</div> </div>
@* Organisation address - Line 2 *@ @* Organisation address - Line 2 *@
<div class="sax-form-control OrganisationAddressLine2"> <div class="sax-form-control OrganisationAddressLine2">
<div class="sax-control row"> <div class="row">
<div class="col"><input type="text" id="ifOrganisationAddressLine2" name="OrganisationAddressLine2" class="OrganisationAddressLine2 sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line2)" /> </div> <div class="col-sm-4"></div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" id="ifOrganisationAddressLine2" name="OrganisationAddressLine2" class="OrganisationAddressLine2 sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line2)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div> </div>
<div class="sax-message"></div>
</div> </div>
@* Organisation address - Line 3 *@ @* Organisation address - Line 3 *@
<div class="sax-form-control OrganisationAddressLine3"> <div class="sax-form-control OrganisationAddressLine3">
<div class="sax-control row"> <div class="row">
<div class="col"><input type="text" id="ifOrganisationAddressLine3" name="OrganisationAddressLine3" class="OrganisationAddressLine3 sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line3)" /> </div> <div class="col-sm-4"></div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" id="ifOrganisationAddressLine3" name="OrganisationAddressLine3" class="OrganisationAddressLine3 sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line3)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div> </div>
<div class="sax-message"></div>
</div> </div>
@* Organisation address - Town *@ @* Organisation address - Town *@
<div class="sax-form-control OrganisationAddressTown"> <div class="sax-form-control OrganisationAddressTown">
<div class="sax-label"> <div class="row">
<label for="ifOrganisationAddressTown"><span>@Localiser["label.town"]</span><span class="required">&nbsp;*</span></label> <div class="col-sm-4">
<div class="sax-label">
<label for="ifOrganisationAddressTown"><span>@Localiser["label.town"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" id="ifOrganisationAddressTown" name="OrganisationAddressTown" class="OrganisationAddressTown sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Town)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div> </div>
<div class="sax-control row">
<div class="col"><input type="text" id="ifOrganisationAddressTown" name="OrganisationAddressTown" class="OrganisationAddressTown sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Town)" /> </div>
</div>
<div class="sax-message"></div>
</div> </div>
@* Organisation address - Province *@ @* Organisation address - Province *@
<div class="sax-form-control OrganisationAddressProvince"> <div class="sax-form-control OrganisationAddressProvince">
<div class="sax-label"> <div class="row">
<label for="ifOrganisationAddressProvince"><span>@Localiser["label.province"]</span><span class="required">&nbsp;*</span></label> <div class="col-sm-4">
<div class="sax-label">
<label for="ifOrganisationAddressProvince"><span>@Localiser["label.province"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" id="ifOrganisationAddressProvince" name="OrganisationAddressProvince" class="OrganisationAddressProvince sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Province)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div> </div>
<div class="sax-control row">
<div class="col"><input type="text" id="ifOrganisationAddressProvince" name="OrganisationAddressProvince" class="OrganisationAddressProvince sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Province)" /> </div>
</div>
<div class="sax-message"></div>
</div> </div>
@* Organisation address - PostalCode *@ @* Organisation address - PostalCode *@
<div class="sax-form-control OrganisationAddressPostalCode"> <div class="sax-form-control OrganisationAddressPostalCode">
<div class="sax-label"> <div class="row">
<label for="ifOrganisationAddressPostalCode"><span>@Localiser["label.postalCode"]</span><span class="required">&nbsp;*</span></label> <div class="col-sm-4">
<div class="sax-label">
<label for="ifOrganisationAddressPostalCode"><span>@Localiser["label.postalCode"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" id="ifOrganisationAddressPostalCode" name="OrganisationAddressPostalCode" class="OrganisationAddressPostalCode sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_PostalCode)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div> </div>
<div class="sax-control row">
<div class="col"><input type="text" id="ifOrganisationAddressPostalCode" name="OrganisationAddressPostalCode" class="OrganisationAddressPostalCode sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_PostalCode)" /> </div>
</div>
<div class="sax-message"></div>
</div> </div>
@* Organisation PhoneMain *@ @* Organisation PhoneMain *@
@* <div class="sax-form-control OrganisationPhoneMain">
<div class="sax-form-control OrganisationPhoneMain"> <div class="row">
<div class="sax-label"> <div class="col-sm-4">
<label for="ifOrganisationPhoneMain"><span>@Localiser["label.phone"]</span></label> <div class="sax-label">
<label for="ifOrganisationPhoneMain"><span>@Localiser["label.phone"]</span></label>
</div>
</div> </div>
<div class="sax-control row"> <div class="col-sm">
<div class="col"><input type="text" id="ifOrganisationPhoneMain" name="OrganisationPhoneMain" class="OrganisationPhoneMain sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Item_PhoneMain)" /> </div> <div class="sax-control row">
<div class="col"><input type="text" id="ifOrganisationPhoneMain" name="OrganisationPhoneMain" class="OrganisationPhoneMain sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Organisation_PhoneMain)" /> </div>
</div>
<div class="sax-message"></div>
</div> </div>
<div class="sax-message"></div>
</div> </div>
*@ </div>
} }
@@ -205,18 +205,19 @@
.sax-form .sax-form-control .sax-message .sax-form .sax-form-control .sax-message
{ {
display: none; display: none;
margin-top: 8px; margin-top: 4px;
padding-left: 24px; padding-left: 24px;
font-size: 16px; font-size: 1.00Rem;
background-position: left top; background-position: left top;
background-repeat: no-repeat; background-repeat: no-repeat;
} }
.sax-form .sax-form-control.sax-error .sax-message .sax-form .sax-form-control.sax-error .sax-message
{ {
min-height:16px;
display: block; display: block;
color: #e3120b; color: #e3120b;
background-image: url("../img/icon/error-18.png"); background-image: url("../img/icon/error-16.png");
} }
/* Buttons */ /* Buttons */
Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

@@ -185,10 +185,6 @@
$('#ifOpportunityId,#ifOpportunityExists,#ifOpportunityRegionId,#ifOpportunitySportId,input[type="text"],textarea,select', $frm.opportunity).val(''); $('#ifOpportunityId,#ifOpportunityExists,#ifOpportunityRegionId,#ifOpportunitySportId,input[type="text"],textarea,select', $frm.opportunity).val('');
sax.clearControlErrors(); sax.clearControlErrors();
} }
sax.doCreateItem = function ()
{
sax.storeItem();
}
//-------------------------------------------------------------- //--------------------------------------------------------------
sax.updateItem = function (item) sax.updateItem = function (item)
@@ -219,10 +215,6 @@
$dlg.opportunity.dialog('option', 'title', sax.dlg.title.updateOpportunity); $dlg.opportunity.dialog('option', 'title', sax.dlg.title.updateOpportunity);
sax.openDialog($dlg.opportunity, 600, 600); sax.openDialog($dlg.opportunity, 600, 600);
} }
sax.doUpdateItem = function ()
{
sax.storeItem();
}
//-------------------------------------------------------------- //--------------------------------------------------------------
sax.storeItem = function () sax.storeItem = function ()
@@ -263,7 +255,7 @@
$('.sax-input', $frm.opportunity).on('input', function () { sax.clearControlError(this); }); $('.sax-input', $frm.opportunity).on('input', function () { sax.clearControlError(this); });
var opt = sax.dlgOpts(); var opt = sax.dlgOpts();
opt.buttons[sax.dlg.btn.ok] = function () { sax.doCreateItem(); }; opt.buttons[sax.dlg.btn.ok] = function () { sax.storeItem(); };
opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); }; opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); };
$dlg.opportunity = $('#dlgOpportunity').dialog(opt); $dlg.opportunity = $('#dlgOpportunity').dialog(opt);
+16 -14
View File
@@ -5,16 +5,16 @@
(function (win, doc, undef) (function (win, doc, undef)
{ {
"use strict"; "use strict";
let $pnl = sax.$pnl, $dlg = sax.$dlg, $frm = sax.$frm; let po = sax.mdl.profileOrganisations = sax.mdl.profileOrganisations || { $pnl: {}, $dlg: {}, $frm: {} };
let $pnl = po.$pnl, $dlg = po.$dlg, $frm = po.$frm;
//-------------------------------------------------------------- //--------------------------------------------------------------
sax.refreshProfileOrganisationsInfo = function (delay) sax.refreshProfileOrganisationsInfo = function (delay)
{ {
var $section = $('.sax-panel-section.ProfileOrganisations'); $pnl.section.removeClass('sax-edit').addClass('sax-populating');
$section.removeClass('sax-edit').addClass('sax-populating'); $('.sax-property', $pnl.section).hide();
$('.sax-property', $section).hide(); sax.showDataRefreshingMsg($pnl.section);
sax.showDataRefreshingMsg($section); sax.refreshProfileOrganisations(po.onRefreshProfileOrganisationsInfo);
sax.refreshProfileOrganisations(sax.onRefreshProfileOrganisationsInfo);
} }
sax.refreshProfileOrganisations = function (callbackFn) sax.refreshProfileOrganisations = function (callbackFn)
{ {
@@ -24,17 +24,16 @@
sax.ajax.profileOrganisations.callbackFn = callbackFn; sax.ajax.profileOrganisations.callbackFn = callbackFn;
sax.doAjaxRequest(sax.ajax.profileOrganisations, 50); sax.doAjaxRequest(sax.ajax.profileOrganisations, 50);
} }
sax.onRefreshProfileOrganisationsInfo = function (response) po.onRefreshProfileOrganisationsInfo = function (response)
{ {
//sax.debug('onRefreshProfileOrganisationsInfo', response); sax.debug('onRefreshProfileOrganisationsInfo', response);
if (!response || !response.success) return; if (!response || !response.success) return;
var $section = $('.sax-panel-section.ProfileOrganisations'); $('.sax-message', $pnl.section).stop(true, false).fadeOut(200).empty();
$('.sax-message', $section).stop(true, false).fadeOut(200).empty();
let items = response.organisations; let items = response.organisations;
if (!items) return; if (!items) return;
let $items = $('.sax-panel-results.Organisations', $section).empty(); let $items = $('.sax-panel-results.Organisations', $pnl.section).empty();
let $tmpl = $('.sax-panel-item-template .sax-panel-item.Organisation', $section); let $tmpl = $('.sax-panel-item-template .sax-panel-item.Organisation', $pnl.section);
for (let itemIdx = 0; itemIdx < items.length; itemIdx++) for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
{ {
let item = items[itemIdx]; let item = items[itemIdx];
@@ -47,13 +46,16 @@
$items.append($item); $items.append($item);
} }
$items.show(); $items.show();
sax.showNoInfoMsg($section); sax.showNoInfoMsg($pnl.section);
$section.removeClass('sax-populating'); $pnl.section.removeClass('sax-populating');
} }
//--------------------------------------------------------------
//-------------------------------------------------------------- //--------------------------------------------------------------
$(function () $(function ()
{ {
$pnl.section = $('.sax-panel-section.ProfileOrganisations');
}); });
//-------------------------------------------------------------- //--------------------------------------------------------------
+5 -2
View File
@@ -18,7 +18,7 @@ namespace Saxonite.Net.Standard.Base.App
//------------------------------------------------------------------- //-------------------------------------------------------------------
public static class Version public static class Version
{ {
private static String version { get; } = "1.1.8.0"; private static String version { get; } = "1.2.0.0";
// Retrieve version. // Retrieve version.
public static String GetFullVersion () { return version; } public static String GetFullVersion () { return version; }
public static String GetAppVersion () public static String GetAppVersion ()
@@ -40,8 +40,11 @@ namespace Saxonite.Net.Standard.Base.App
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Version history. // Version history.
//------------------------------------------------------------------- //-------------------------------------------------------------------
// 1.2.0 1-Nov-2021 'Admin' Organisation role
// - 'Admin' Organisation role
// - Azure App Service configuration.
// 1.1.8 21-Oct-2021 Online Users Search // 1.1.8 21-Oct-2021 Online Users Search
// - ONlien Search - Users. // - Online Search - Users.
// - Admin Account Users filter. // - Admin Account Users filter.
// 1.1.7 14-Oct-2021 Online Organisation Search // 1.1.7 14-Oct-2021 Online Organisation Search
// - Online Profile Sport About & snags. // - Online Profile Sport About & snags.
+1
View File
@@ -232,6 +232,7 @@ namespace Saxonite.Net.Standard.Base.App
Unknown = 0, Unknown = 0,
/* Do not change the values/codes - tied to database. */ /* Do not change the values/codes - tied to database. */
Member, Member,
Admin,
MemberAdmin, MemberAdmin,
ScheduleAdmin, ScheduleAdmin,
OpportunityAdmin, OpportunityAdmin,
@@ -144,10 +144,11 @@ namespace Saxonite.Net.Standard.Base.App
//--------------------------------------------------------------- //---------------------------------------------------------------
// Organisation roles. // Organisation roles.
organisationRoleCodes.Add(Sax.OrganisationRole.Member, "MBR", "Member"); organisationRoleCodes.Add(Sax.OrganisationRole.Member, "MBR", "Member");
organisationRoleCodes.Add(Sax.OrganisationRole.MemberAdmin, "MBA", "Member Admin"); organisationRoleCodes.Add(Sax.OrganisationRole.Admin, "ADM", "Admin");
organisationRoleCodes.Add(Sax.OrganisationRole.ScheduleAdmin, "SCA", "Schedule Admin"); organisationRoleCodes.Add(Sax.OrganisationRole.MemberAdmin, "MBA", "Members");
organisationRoleCodes.Add(Sax.OrganisationRole.OpportunityAdmin, "OPA", "Opportunity Admin"); organisationRoleCodes.Add(Sax.OrganisationRole.ScheduleAdmin, "SCA", "Schedule");
organisationRoleCodes.Add(Sax.OrganisationRole.ArticleAdmin, "ARA", "Article Admin"); organisationRoleCodes.Add(Sax.OrganisationRole.OpportunityAdmin, "OPA", "Opportunities");
organisationRoleCodes.Add(Sax.OrganisationRole.ArticleAdmin, "ARA", "Articles");
//--------------------------------------------------------------- //---------------------------------------------------------------
// Opportunity types. // Opportunity types.
@@ -101,9 +101,9 @@ namespace Saxonite.Net.Standard.Base.Bus
if (!Changed) Changed = !data.OrganisationRoles.IsEmpty(); if (!Changed) Changed = !data.OrganisationRoles.IsEmpty();
data.OrganisationRoles.Clear(); data.OrganisationRoles.Clear();
} }
public bool HasOrganisationRole(Sax.OrganisationRole organisationRole) public bool HasAnyOrganisationRole(IEnumerable<Sax.OrganisationRole> organisationRoles)
{ {
return data.OrganisationRoles.Contains(organisationRole); return data.OrganisationRoles.Any(item => organisationRoles.Contains(item));
} }
public void AddOrganisationRole(Sax.OrganisationRole organisationRole) public void AddOrganisationRole(Sax.OrganisationRole organisationRole)
{ {
@@ -114,7 +114,7 @@ namespace Saxonite.Net.Standard.Base.Bus
} }
} }
/// <summary>Store organisation roles.</summary> /// <summary>Store organisation roles.</summary>
public List<Sax.OrganisationRole> OrganisationRoles public IEnumerable<Sax.OrganisationRole> OrganisationRoles
{ {
set set
{ {
@@ -240,6 +240,16 @@ namespace Saxonite.Net.Standard.Base.Bus
{ {
return GetOrganisationRoleCodes().Concat(UserOrgnisationRoleDelim); return GetOrganisationRoleCodes().Concat(UserOrgnisationRoleDelim);
} }
// Query roles.
public bool CanManageOrganisation{ get { return HasAnyOrganisationRole(new [] { Sax.OrganisationRole.Admin }); } }
public bool CanManageMembers { get { return HasAnyOrganisationRole(new [] { Sax.OrganisationRole.Admin, Sax.OrganisationRole.MemberAdmin }); } }
public bool CanManageOpportunities { get { return HasAnyOrganisationRole(new [] { Sax.OrganisationRole.Admin, Sax.OrganisationRole.OpportunityAdmin }); } }
public bool CanManageSchedule { get { return HasAnyOrganisationRole(new [] { Sax.OrganisationRole.Admin, Sax.OrganisationRole.ScheduleAdmin }); } }
public bool CanManageArticles { get { return HasAnyOrganisationRole(new [] { Sax.OrganisationRole.Admin, Sax.OrganisationRole.ArticleAdmin }); } }
public bool HasAnyOrganisationRole(IEnumerable<Sax.OrganisationRole> organisationRoles)
{
return data.HasAnyOrganisationRole(organisationRoles);
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Properties. // Properties.
@@ -290,7 +300,7 @@ namespace Saxonite.Net.Standard.Base.Bus
return data.GetOrganisationRoles(); return data.GetOrganisationRoles();
} }
/// <summary>Store Organisation Roles.</summary> /// <summary>Store Organisation Roles.</summary>
public List<Sax.OrganisationRole> OrganisationRoles public IEnumerable<Sax.OrganisationRole> OrganisationRoles
{ {
set { data.OrganisationRoles = value; } set { data.OrganisationRoles = value; }
} }
@@ -298,10 +308,6 @@ namespace Saxonite.Net.Standard.Base.Bus
{ {
data.ClearOrganisationRoles(); data.ClearOrganisationRoles();
} }
public bool HasOrganisationRole(Sax.OrganisationRole organisationRole)
{
return data.HasOrganisationRole(organisationRole);
}
public void AddOrganisationRole(Sax.OrganisationRole organisationRole) public void AddOrganisationRole(Sax.OrganisationRole organisationRole)
{ {
data.AddOrganisationRole(organisationRole); data.AddOrganisationRole(organisationRole);
@@ -347,6 +353,7 @@ namespace Saxonite.Net.Standard.Base.Bus
/// <summary>Set true to restruct to User Organisations with at least one Organisation Role.</summary> /// <summary>Set true to restruct to User Organisations with at least one Organisation Role.</summary>
public bool OrganisationMembersOnly { get; set; } public bool OrganisationMembersOnly { get; set; }
public List<Sax.OrganisationRole> OrganisationRoles { get; } = new List<Sax.OrganisationRole>(); public List<Sax.OrganisationRole> OrganisationRoles { get; } = new List<Sax.OrganisationRole>();
public List<Sax.OrganisationRole> OrganisationRolesAny { get; } = new List<Sax.OrganisationRole>();
// Common properties. // Common properties.
public String NotesPartial { get; set; } public String NotesPartial { get; set; }
public StatusCat StatusCat { get; set; } = StatusCat.NotDeleted; public StatusCat StatusCat { get; set; } = StatusCat.NotDeleted;
@@ -39,8 +39,16 @@ namespace Saxonite.Net.Standard.Base.Mgr
/// </summary> /// </summary>
public bool UserHasOrganisationRole(SysId userAccountId, SysId organisationId, Sax.OrganisationRole organisationRole, SaxUserOrganisation.StatusCat statusCat = SaxUserOrganisation.StatusCat.ActiveOnly) public bool UserHasOrganisationRole(SysId userAccountId, SysId organisationId, Sax.OrganisationRole organisationRole, SaxUserOrganisation.StatusCat statusCat = SaxUserOrganisation.StatusCat.ActiveOnly)
{ {
if (!SysId.IsValid(userAccountId) || !SysId.IsValid(organisationId) || organisationRole <= 0) return false; return UserHasAnyOrganisationRole(userAccountId, organisationId, new [] { organisationRole }, statusCat);
return GetOrganisationRolesForUser(userAccountId, organisationId, statusCat).Contains(organisationRole); }
/// <summary>
/// Does the user have any of the specified roles with the organisation.
/// </summary>
public bool UserHasAnyOrganisationRole(SysId userAccountId, SysId organisationId, IEnumerable<Sax.OrganisationRole> organisationRoles, SaxUserOrganisation.StatusCat statusCat = SaxUserOrganisation.StatusCat.ActiveOnly)
{
if (!SysId.IsValid(userAccountId) || !SysId.IsValid(organisationId) || organisationRoles.IsEmpty() || !organisationRoles.Any(item => item > 0)) return false;
return GetOrganisationRolesForUser(userAccountId, organisationId, statusCat).Any(item => organisationRoles.Contains(item));
} }
/// <summary> /// <summary>
@@ -67,24 +75,40 @@ namespace Saxonite.Net.Standard.Base.Mgr
} }
/// <summary> /// <summary>
/// Get list of organisation Ids that the user has the specified role with. /// Get list of organisation Ids and names that the user has the specified role with.
/// </summary> /// </summary>
public List<OrganisationIdName> GetOrganisationsForUserRole(SysId userAccountId, Sax.OrganisationRole organisationRole, SaxUserOrganisation.StatusCat statusCat = SaxUserOrganisation.StatusCat.ActiveOnly) public List<OrganisationIdName> GetOrganisationsForUserRole(SysId userAccountId, Sax.OrganisationRole organisationRole, SaxUserOrganisation.StatusCat statusCat = SaxUserOrganisation.StatusCat.ActiveOnly)
{ {
List<OrganisationIdName> organisationsData = new List<OrganisationIdName>(); return GetOrganisationsForAnyUserRole(userAccountId, new [] { organisationRole }, statusCat);
String organisationRoleCode = Internals.OrganisationRoleCodes.GetCodeForType(organisationRole); }
if (!SysId.IsValid(userAccountId) || StringUtil.IsEmpty(organisationRoleCode)) return organisationsData;
// Columns. /// <summary>
ColumnDfn colOrganisationId = GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.OrganisationId); /// Get list of organisation Ids and names that the user has any of the specified roles with.
ColumnDfn colOrganisationName = GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.Organisation_Name); /// </summary>
public List<OrganisationIdName> GetOrganisationsForAnyUserRole(SysId userAccountId, IEnumerable<Sax.OrganisationRole> organisationRoles, SaxUserOrganisation.StatusCat statusCat = SaxUserOrganisation.StatusCat.ActiveOnly)
{
if (!SysId.IsValid(userAccountId) || organisationRoles.IsEmpty() || !organisationRoles.Any(item => item > 0)) return null;
// Filter. // Filter.
SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params(); SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params();
prmUserOrganisation.UserAccountIdsIncluded.Add(userAccountId); prmUserOrganisation.UserAccountIdsIncluded.Add(userAccountId);
prmUserOrganisation.OrganisationStatusCat = SaxOrganisation.StatusCat.ActiveOnly; prmUserOrganisation.OrganisationStatusCat = SaxOrganisation.StatusCat.ActiveOnly;
prmUserOrganisation.OrganisationMembersOnly = true; prmUserOrganisation.OrganisationMembersOnly = true;
prmUserOrganisation.OrganisationRoles.Add(organisationRole); prmUserOrganisation.OrganisationRolesAny.AddRange(organisationRoles);
prmUserOrganisation.StatusCat = statusCat; prmUserOrganisation.StatusCat = statusCat;
prmUserOrganisation.SortColumns.Add(colOrganisationName); return GetOrganisations(prmUserOrganisation);
}
/// <summary>
/// Get list of organisation Ids and names that matc the specified parameters.
/// </summary>
public List<OrganisationIdName> GetOrganisations(SaxUserOrganisation.Params prmUserOrganisation)
{
List<OrganisationIdName> organisationsData = new List<OrganisationIdName>();
// Columns.
ColumnDfn colOrganisationId = GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.OrganisationId);
ColumnDfn colOrganisationName = GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.Organisation_Name);
if (prmUserOrganisation.SortColumns.IsEmpty())
prmUserOrganisation.SortColumns.Add(colOrganisationName);
// Query. // Query.
using (DbResultSet resultSet = ExecuteUserOrganisationQuery(new List<ColumnDfn>() { colOrganisationId, colOrganisationName }, prmUserOrganisation)) using (DbResultSet resultSet = ExecuteUserOrganisationQuery(new List<ColumnDfn>() { colOrganisationId, colOrganisationName }, prmUserOrganisation))
{ {
@@ -488,7 +488,6 @@ namespace Saxonite.Net.Standard.Dbas.Mgr
filter.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.UserOrganisation_OrganisationRoleCount, aliasUserOrganisation) + ">0"); filter.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.UserOrganisation_OrganisationRoleCount, aliasUserOrganisation) + ">0");
if (!prm.OrganisationRoles.IsEmpty()) if (!prm.OrganisationRoles.IsEmpty())
{ {
List<String> organisationRoleCodes = new List<string>();
foreach (Sax.OrganisationRole organisationRole in prm.OrganisationRoles) foreach (Sax.OrganisationRole organisationRole in prm.OrganisationRoles)
{ {
String organisationRoleCode = OrganisationRoleCodes.GetCodeForType(organisationRole).TrimAll(); String organisationRoleCode = OrganisationRoleCodes.GetCodeForType(organisationRole).TrimAll();
@@ -496,6 +495,18 @@ namespace Saxonite.Net.Standard.Dbas.Mgr
filter.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.UserOrganisation_OrganisationRoleCodes, aliasUserOrganisation) + " LIKE '%" + DbQuery.FormatForLike(organisationRoleCode) + "%'"); filter.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.UserOrganisation_OrganisationRoleCodes, aliasUserOrganisation) + " LIKE '%" + DbQuery.FormatForLike(organisationRoleCode) + "%'");
} }
} }
if (!prm.OrganisationRolesAny.IsEmpty())
{
List<String> roleFilter = new List<string>();
foreach (Sax.OrganisationRole organisationRole in prm.OrganisationRolesAny)
{
String organisationRoleCode = OrganisationRoleCodes.GetCodeForType(organisationRole).TrimAll();
if (!StringUtil.IsEmpty(organisationRoleCode))
roleFilter.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.UserOrganisation_OrganisationRoleCodes, aliasUserOrganisation) + " LIKE '%" + DbQuery.FormatForLike(organisationRoleCode) + "%'");
}
if (!roleFilter.IsEmpty())
filter.Add(roleFilter.Concat(" OR "));
}
// Notes. // Notes.
if (!StringUtil.IsEmpty(prm.NotesPartial)) if (!StringUtil.IsEmpty(prm.NotesPartial))