@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmUser", @class = "sax-form", @onSubmit = "return false;" }))
{
- @Html.HiddenFor(model => model.UserAccountId, new { @class = "UserAccountId" })
+ @Html.HiddenFor(model => model.UserId, new { @class = "UserId" })
@* User email *@
@@ -181,7 +181,7 @@
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmUserEmails", @class = "sax-form", @onSubmit = "return false;" }))
{
- @Html.HiddenFor(model => model.UserAccountId, new { @class = "UserAccountId" })
+ @Html.HiddenFor(model => model.UserId, new { @class = "UserId" })
@Localiser["user.emails.intro"]
diff --git a/SaxoniteCoreWebAdmin/wwwroot/css/sax-main.css b/SaxoniteCoreWebAdmin/wwwroot/css/sax-main.css
index 0684bb4..f9ce95d 100644
--- a/SaxoniteCoreWebAdmin/wwwroot/css/sax-main.css
+++ b/SaxoniteCoreWebAdmin/wwwroot/css/sax-main.css
@@ -346,6 +346,8 @@ a:focus
.ui-dialog.ui-widget.ui-widget-content.ui-corner-all
{
border-radius: 6px;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
}
.ui-dialog.ui-widget .ui-widget-header
@@ -375,11 +377,14 @@ a:focus
.ui-dialog .ui-dialog-buttonpane
{
+ padding: 4px 8px;
border-color: #d4af37;
}
.ui-dialog .ui-dialog-buttonpane button
{
+ min-width:80px;
+ margin:4px 8px 4px 0;
color: #fff;
background-color: #d4af37;
border-color: #d4af37;
diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-home.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-home.js
index 3e456c7..6717ee4 100644
--- a/SaxoniteCoreWebAdmin/wwwroot/js/sax-home.js
+++ b/SaxoniteCoreWebAdmin/wwwroot/js/sax-home.js
@@ -5,68 +5,84 @@
(function (win, doc, undef)
{
"use strict";
- let $pnl = sax.$pnl, $dlg = sax.$dlg, $frm = sax.$frm;
+ let ah = sax.adminHome = {};
+ let $pnl = ah.$pnl = {}, $dlg = ah.$dlg = {}, $frm = ah.$frm = {};
sax.itemIdPrefix = 'Itm_';
//--------------------------------------------------------------
- sax.refreshAwaitActivate = function (delay)
+ ah.refreshApplicationStats = function (delay)
{
+ clearTimeout(ah.toStats);
if (sax.awaitingLogin) return;
- if (!sax.awaitingRefreshResponse)
+ if (!ah.awaitingStatsResponse)
{
- var $items = $('.sax-panel-item-list', $pnl.awaitAct).fadeOut(200).empty();
- var $msgs = $('.sax-panel-messages', $pnl.awaitAct).hide().empty().append($('
' + sax.msg.dataQuerying + '
')).fadeIn(200);
+ var $items = $('.sax-panel-item-list', $pnl.appStats).fadeOut(200).empty();
+ var $msgs = $('.sax-panel-messages', $pnl.appStats).hide().empty().append($('
' + sax.msg.dataQuerying + '
')).fadeIn(200);
}
- sax.ajax.awaitAct = sax.ajax.awaitAct || { url: sax.url.base + 'Home/Ajax/GetItemsAwaitingActivation', formId: 'frmNavigate', callbackFn: sax.handleAwaitActivateResponse, noWaitIcon: true };
+ sax.ajax.awaitAct = sax.ajax.awaitAct || { url: sax.url.base + 'Home/Ajax/GetApplicationStats', formId: 'frmNavigate', callbackFn: ah.handleStatsResponse, noWaitIcon: true };
sax.doAjaxRequest(sax.ajax.awaitAct, delay || 50);
- sax.awaitingRefreshResponse = true;
+ ah.awaitingStatsResponse = true;
}
- sax.handleAwaitActivateResponse = function (response)
+ ah.handleStatsResponse = function (response)
{
//sax.debug('handleAwaitActivateResponse', response);
- delete sax.awaitingRefreshResponse;
- var $msgs = $('.sax-panel-messages', $pnl.awaitAct).hide().empty();
- var $items = $('.sax-panel-item-list', $pnl.awaitAct).hide().empty();
- var $tmpl = $('.sax-panel-item-template .sax-panel-item.AwaitActivateItem', $pnl.awaitAct);
+ delete ah.awaitingStatsResponse;
+ var $msgs = $('.sax-panel-messages', $pnl.appStats).hide().empty();
+ var $items = $('.sax-panel-item-list', $pnl.appStats).hide().empty();
+ ah.toStats = setTimeout(ah.refreshApplicationStats, 60000);
if (!response.success) return;
- // Items.
- var items = response.items;
- if (!items.length)
- return $msgs.append($('
' + sax.msg.noItemsAwaitAct + '
')).fadeIn(500);
- for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
- $items.append(sax.populateAwaitActivateItem($tmpl.clone(), items[itemIdx]));
+ //return $msgs.append($('
' + sax.msg.noItemsAwaitAct + '
')).fadeIn(500);
+ // Users.
+ let user = response.stats.user;
+ let $user = sax.getAppStatItemTemplate();
+ $('.sax-header .sax-caption', $user).text(user.caption||'Users');
+ ah.populateAppStat($user, user.awaiting.label, user.awaiting.value, user.awaitingLink)
+ for (let item of user.onlineStats)
+ ah.populateAppStat($user, item.label, item.value, user.onlineLink)
+ $items.append($user);
+ // Organisations.
+ let org = response.stats.organisation;
+ let $org = sax.getAppStatItemTemplate();
+ $('.sax-header .sax-caption', $org).text(org.caption||'Organisations');
+ ah.populateAppStat($org, org.awaiting.label, org.awaiting.value, org.awaitingLink)
+ $items.append($org);
$items.slideDown(750);
}
- sax.populateAwaitActivateItem = function ($item, item)
+ ah.populateAppStat = function ($item, label, value, link)
{
- if (!item) return;
- if (item.viewLink)$('.sax-action.sax-view', $item).on('click', function () { sax.goToPage(item.viewLink); });
- $('.AwaitActivateItemType', $item).text(item.itemTypeDescPlural);
- $('.AwaitActivateItemCount', $item).text(item.itemCount);
+ let $stat = sax.getAppStatStatTemplate();
+ $stat.on('click', function () { win.location = link; });
+ $('.sax-label', $stat).text(label + ':');
+ $('.sax-value', $stat).text(value);
+ $('table.sax-item-stats', $item).append($stat);
return $item;
}
- sax.getAwaitActivateItemTemplate = function ()
+ sax.getAppStatItemTemplate = function ()
{
- return $('.sax-panel-item-template .sax-panel-item.AwaitActivateItem', $pnl.results).clone();
+ return $('.sax-panel-item-template .sax-panel-item.sax-item-stats', $pnl.appStats).clone();
+ }
+ sax.getAppStatStatTemplate = function ()
+ {
+ return $('.sax-panel-item-template .sax-item-stat', $pnl.appStats).clone();
}
//--------------------------------------------------------------
sax.refreshDbSchema = function (delay)
{
if (sax.awaitingLogin) return;
- if (!sax.awaitingRefreshResponse)
+ if (!ah.awaitingSchemaResponse)
{
var $items = $('.sax-panel-item-list', $pnl.dbSchema).fadeOut(200).empty();
var $msgs = $('.sax-panel-messages', $pnl.dbSchema).hide().empty().append($('
' + sax.msg.dataQuerying + '
')).fadeIn(200);
}
sax.ajax.dbSchema = sax.ajax.dbSchema || { url: sax.url.base + 'System/Ajax/ValidateDatabaseSchema', formId: 'frmNavigate', callbackFn: sax.handleDbSchemaResponse, noWaitIcon: true };
sax.doAjaxRequest(sax.ajax.dbSchema, delay || 50);
- sax.awaitingRefreshResponse = true;
+ ah.awaitingSchemaResponse = true;
}
sax.handleDbSchemaResponse = function (response)
{
//sax.debug('handleDbSchemaResponse', response);
- delete sax.awaitingRefreshResponse;
+ delete ah.awaitingSchemaResponse;
var $msgs = $('.sax-panel-messages', $pnl.dbSchema).hide().empty();
var $items = $('.sax-panel-item-list', $pnl.dbSchema).hide().empty();
var $tmpl = $('.sax-panel-item-template .sax-panel-item.DbSchemaItem', $pnl.dbSchema);
@@ -95,11 +111,11 @@
//--------------------------------------------------------------
$(function ()
{
- $pnl.awaitAct = $('.sax-panel-results.AwaitActivate');
+ $pnl.appStats = $('.sax-panel-results.ApplicationStats');
$pnl.dbSchema = $('.sax-panel-results.DbSchema');
- setTimeout(sax.refreshAwaitActivate, 250);
- setTimeout(sax.refreshDbSchema, 250);
+ ah.toStats = setTimeout(ah.refreshApplicationStats, 400);
+ ah.toSchema = setTimeout(sax.refreshDbSchema, 600);
});
}(window, window.document));
diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-main.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-main.js
index e47f127..05c9257 100644
--- a/SaxoniteCoreWebAdmin/wwwroot/js/sax-main.js
+++ b/SaxoniteCoreWebAdmin/wwwroot/js/sax-main.js
@@ -359,18 +359,18 @@
// Session.
sax.configureKeepLoggedIn = function (single)
{
- sax.debug('KeepLoggedIn Configuring');
+ //sax.debug('KeepLoggedIn Configuring');
let kli = sax.kli;
if (!kli.timeout) kli.timeout = setTimeout(function () { sax.doKeepLoggedIn(single); }, Math.max(30000, kli.interval || 300000));
}
sax.doKeepLoggedIn = function (single)
{
- sax.debug('KeepLoggedIn Calling');
+ //sax.debug('KeepLoggedIn Calling');
let kli = sax.kli;
delete kli.timeout;
var onKeepLoggedIn = function (response)
{
- sax.debug('KeepLoggedIn Responded', response);
+ //sax.debug('KeepLoggedIn Responded', response);
kli.lastAt = sax.getTime();
if (!single) sax.configureKeepLoggedIn();
}
@@ -378,13 +378,13 @@
}
sax.configureSessionRefresh = function ()
{
- sax.debug('SessionRefresh Configuring');
+ //sax.debug('SessionRefresh Configuring');
$(document).on('mousedown mousemove touchstart scroll keydown', sax.triggeRefreshSession);
}
sax.triggeRefreshSession = function ()
{
if (sax.kli.timeout) return;
- sax.debug('SessionRefresh Triggering');
+ //sax.debug('SessionRefresh Triggering');
sax.configureKeepLoggedIn(1);
}
diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-organisation.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-organisation.js
index db669fd..ef33f60 100644
--- a/SaxoniteCoreWebAdmin/wwwroot/js/sax-organisation.js
+++ b/SaxoniteCoreWebAdmin/wwwroot/js/sax-organisation.js
@@ -23,7 +23,7 @@
}
op.getItemTemplate = function ()
{
- return $('.sax-panel-item-template .sax-panel-item.Organisation', $pnl.results);
+ return $('.sax-panel-item-template .sax-panel-item.Organisation', $pnl.results).clone();
}
op.getDropdownItemTemplate = function ()
{
@@ -36,7 +36,6 @@
sax.refreshControlValues(response.controlValues);
var $msgs = $('.sax-panel-messages', $pnl.results).hide().empty();
var $items = $('.sax-panel-item-list', $pnl.results).hide().empty();
- var $tmpl = op.getItemTemplate();
sax.refreshPaging(response, '#frmOrganisationFilter', sax.refreshResults);
if (!response.success) return;
// Reference data - Statuses.
@@ -48,12 +47,7 @@
if (!items.length)
return $msgs.append($('
' + sax.msg.dataNoneFound + '
')).fadeIn(500);
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
- {
- let item = items[itemIdx];
- let $item = $tmpl.clone();
- op.populateItem($item, item);
- $items.append($item);
- }
+ $items.append(op.populateItem(op.getItemTemplate(), items[itemIdx]));
$items.fadeIn(50);
}
op.populateItem = function ($item, item)
@@ -65,17 +59,17 @@
$('.OrganisationCategory', $item).text(item.categoryDesc);
$('.OrganisationSport', $item).text(item.sportName);
$('.OrganisationRegion', $item).text(item.regionName);
- $('.OrganisationMemberCount', $item).on('click', function () { sax.onClickMemberCount(item.id); }).find('.MemberCount').text(item.memberCount);
+ $('.OrganisationMemberCount', $item).on('click', function () { op.onClickMemberCount(item.id); }).find('.MemberCount').text(item.memberCount);
$('.StatusDesc', $item).text(item.statusDesc).addClass('sax-status-' + item.statusCode.toLowerCase());
$('.sax-caption .sax-action').toggleClass('sax-action', !item.deleted);
if (!item.deleted)
{
let $mnu = $('ul.sax-dropdown-menu', $item);
- $mnu.append(op.getDropdownItemTemplate().clone().find('div.sax-label').text(sax.lbl.edit).end().on('click', function () { sax.updateItem(item.id) }));
+ $mnu.append(op.getDropdownItemTemplate().clone().find('div.sax-label').text(sax.lbl.edit).end().on('click', function () { op.updateItem(item, $item) }));
if (item.awaiting)
- $mnu.append(op.getDropdownItemTemplate().clone().find('div.sax-label').text(sax.lbl.activate).end().on('click', function () { sax.activateItem(item.id) }));
- $('.sax-header .sax-action.sax-item-update', $item).off('click').on('click', function () { sax.updateItem(item.id) });
- $item.off('dblclick').on('dblclick', function () { sax.updateItem(item.id) });
+ $mnu.append(op.getDropdownItemTemplate().clone().find('div.sax-label').text(sax.lbl.activate).end().on('click', function () { op.activateItem(item) }));
+ $('.sax-header .sax-action.sax-item-update', $item).off('click').on('click', function () { op.updateItem(item, $item) });
+ $item.off('dblclick').on('dblclick', function () { op.updateItem(item, $item) });
}
$('.sax-burger', $item).toggle(!!$('.sax-burger .sax-dropdown-menu .sax-dropdown-item', $item).length);
$('.sax-panel-messages', $pnl.results).hide().empty();
@@ -118,22 +112,26 @@
}
//--------------------------------------------------------------
- sax.selectSport = function ()
+ op.selectOrgSport = function ()
{
if (!op.data.sports)
- op.populateSports(sax.showSelectSport);
- else sax.showSelectSport();
+ op.populateSports(op.showSelectOrgSport);
+ else op.showSelectOrgSport();
}
- sax.showSelectSport = function ()
+ op.showSelectOrgSport = function ()
{
- sax.data.selectItem.fn.selectItem({ caption: sax.dlg.title.selectSport, items: op.data.sports, fnCallback: sax.onSportSelected });
+ sax.data.selectItem.fn.selectItem({ caption: sax.dlg.title.selectSport, items: op.data.sports, fnCallback: op.onOrgSportSelected });
}
- sax.onSportSelected = function (spt)
+ op.onOrgSportSelected = function (spt)
{
let frm = $frm.org;
$('.OrganisationSportId', frm).val(spt.id);
$('.OrganisationSportCaption', frm).val(spt.name);
- sax.clearControlError($('.OrganisationSportCaption', frm));
+ sax.clearControlError($('.OrganisationSportId', frm));
+ }
+ op.clearOrgSport = function ()
+ {
+ $('.OrganisationSportId,.OrganisationSportCaption', $frm.org).val('');
}
//--------------------------------------------------------------
@@ -173,17 +171,17 @@
}
//--------------------------------------------------------------
- sax.selectRegion = function ()
+ op.selectOrgRegion = function ()
{
if (!op.data.regions)
- op.populateRegions(sax.showSelectRegion);
- else sax.showSelectRegion();
+ op.populateRegions(op.showSelectOrgRegion);
+ else op.showSelectOrgRegion();
}
- sax.showSelectRegion = function ()
+ op.showSelectOrgRegion = function ()
{
- sax.data.selectItem.fn.selectItem({ caption: sax.dlg.title.selectRegion, items: op.data.regions, fnCallback: sax.onRegionSelected });
+ sax.data.selectItem.fn.selectItem({ caption: sax.dlg.title.selectRegion, items: op.data.regions, fnCallback: op.onOrgRegionSelected });
}
- sax.onRegionSelected = function (rgn)
+ op.onOrgRegionSelected = function (rgn)
{
//sax.debug('onRegionSelected', rgn);
let frm = $frm.org;
@@ -193,30 +191,34 @@
}
//--------------------------------------------------------------
- sax.createItem = function ()
+ op.createItem = function ()
+ {
+ op.clearItem();
+ $dlg.organisation.dialog('option', 'title', sax.dlg.title.createOrganisation);
+ sax.openDialog($dlg.organisation, 600, 480);
+ }
+ op.clearItem = function ()
{
let frm = $frm.org;
$('.OrganisationId,.OrganisationSportId,.OrganisationRegionIdCountry,input[type="text"],textarea,select', frm).val('');
$('.OrganisationStatus', frm).val(sax.data.defaultStatusCode);
sax.clearControlErrors();
- $dlg.organisation.dialog('option', 'title', sax.dlg.title.createOrganisation);
- sax.openDialog($dlg.organisation, 600, 480);
}
//--------------------------------------------------------------
- sax.updateItem = function (id)
+ op.updateItem = function (item, $item)
{
- $('.OrganisationId', $frm.orgId).val(id);
- op.ajax.updateItem = op.ajax.updateItem || { url: sax.url.base + 'Organisation/Ajax/GetItem', formId: 'frmOrganisationId', callbackFn: sax.onUpdateItem };
+ $('.OrganisationId', $frm.orgId).val(item.id);
+ op.ajax.updateItem = op.ajax.updateItem || { url: sax.url.base + 'Organisation/Ajax/GetItem', formId: 'frmOrganisationId', callbackFn: op.onUpdateItem };
sax.doAjaxRequest(op.ajax.updateItem, 50);
}
- sax.onUpdateItem = function (response)
+ op.onUpdateItem = function (response)
{
//sax.debug('onUpdateItem', response);
- let frm = $frm.org;
- $('.OrganisationId,input[type="text"],textarea,select', frm).val('');
+ op.clearItem();
if (!response.success) return;
let item = response.organisation;
+ let frm = $frm.org;
$('.OrganisationId', frm).val(item.id);
$('.OrganisationName', frm).val(item.name);
$('.OrganisationType', frm).val(item.typeCode);
@@ -232,20 +234,20 @@
}
//--------------------------------------------------------------
- sax.storeItem = function ()
+ op.storeItem = function ()
{
- op.ajax.storeItem = op.ajax.storeItem || { url: sax.url.base + 'Organisation/Ajax/StoreItem', formId: 'frmOrganisation', callbackFn: sax.onStoreItem };
+ op.ajax.storeItem = op.ajax.storeItem || { url: sax.url.base + 'Organisation/Ajax/StoreItem', formId: 'frmOrganisation', callbackFn: op.onStoreItem };
sax.doAjaxRequest(op.ajax.storeItem, 50);
}
- sax.onStoreItem = function (response)
+ op.onStoreItem = function (response)
{
//sax.debug('onStoreItem', response);
sax.refreshControlValues(response.controlValues);
if (!response.success) return;
$dlg.organisation.dialog('close');
- sax.refreshItem(response.organisation);
+ op.refreshItem(response.organisation);
}
- sax.refreshItem = function (item)
+ op.refreshItem = function (item)
{
var $item = $('#' + sax.itemIdPrefix + item.id);
if (!$item.length)
@@ -257,16 +259,16 @@
}
//--------------------------------------------------------------
- sax.activateItem = function (id)
+ op.activateItem = function (item)
{
- //sax.debug('activateItem(' + id + ')')
- $('.OrganisationId', $frm.orgId).val(id);
- op.ajax.getActivationInfo = op.ajax.getActivationInfo || { url: sax.url.base + 'Organisation/Ajax/GetActivationInfo', formId: 'frmOrganisationId', callbackFn: sax.showActivationInfo };
+ //sax.debug('activateItem(' + item.id + ')')
+ $('.OrganisationId', $frm.orgId).val(item.id);
+ op.ajax.getActivationInfo = op.ajax.getActivationInfo || { url: sax.url.base + 'Organisation/Ajax/GetActivationInfo', formId: 'frmOrganisationId', callbackFn: op.showActivationInfo };
sax.doAjaxRequest(op.ajax.getActivationInfo, 50);
}
- sax.showActivationInfo = function (response)
+ op.showActivationInfo = function (response)
{
- sax.debug('showActivationInfo', response);
+ //sax.debug('showActivationInfo', response);
if (!response.success || !response.organisation) return;
let item = response.organisation;
let frm = $('#frmOrganisationActivation');
@@ -282,36 +284,38 @@
popItemValue('.OrganisationAddress', item.addressSummary);
let $orgMbrs = $('.OrganisationMembers', $dlg.activate).empty();
let $mbrTmpl = $('.sax-panel-item-template tr.sax-item.Member');
- sax.debug(response.members, $orgMbrs, $mbrTmpl);
- for (let idx = 0; idx < response.members.length; idx++)
+ let members = response.members;
+ //sax.debug(members, $orgMbrs, $mbrTmpl);
+ for (let idx = 0; idx < members.length; idx++)
{
- let item = response.members[idx];
+ let item = members[idx];
let $item = $mbrTmpl.clone();
$('.MemberId', $item).val(item.id);
$('.MemberActivate', $item).prop('name', 'MemberActivate_' + item.id)
$('.MemberEmail', $item).text(item.emailAddress);
$('.MemberName', $item).text(item.displayName);
$orgMbrs.append($item);
- sax.debug($item);
+ //sax.debug($item);
}
+ $('.MembersAwaitingActivation', $dlg.activate).toggle(!!members.length);
sax.openDialog($dlg.activate, 480, 420);
}
- sax.activateOrganisation = function ()
+ op.activateOrganisation = function ()
{
let frm = $('#frmOrganisationActivation');
- op.ajax.activateOrganisation = op.ajax.activateOrganisation || { url: sax.url.base + 'Organisation/Ajax/Activate', formId: frm.prop('id'), callbackFn: sax.handleAtivateResponse };
+ op.ajax.activateOrganisation = op.ajax.activateOrganisation || { url: sax.url.base + 'Organisation/Ajax/Activate', formId: frm.prop('id'), callbackFn: op.handleAtivateResponse };
sax.doAjaxRequest(op.ajax.activateOrganisation, 50);
}
- sax.handleAtivateResponse = function (response)
+ op.handleAtivateResponse = function (response)
{
- sax.debug('handleAtivateResponse', response);
+ //sax.debug('handleAtivateResponse', response);
if (!response.success) return;
$dlg.activate.dialog('close');
- sax.refreshItem(response.organisation);
+ op.refreshItem(response.organisation);
}
//--------------------------------------------------------------
- sax.onClickMemberCount = function (id)
+ op.onClickMemberCount = function (id)
{
if (!(id * 1)) return;
sax.doPleaseWait();
@@ -327,7 +331,7 @@
$pnl.filter = $('.sax-panel-filter', $pnl.orgs);
$pnl.results = $('.sax-panel-results', $pnl.orgs);
- $('.sax-action.sax-item-create', $pnl.filter).on('click', function () { sax.createItem(); });
+ $('.sax-action.sax-item-create', $pnl.filter).on('click', function () { op.createItem(); });
$('.sax-action.sax-results-refresh', $pnl.filter).on('click', function () { sax.refreshResults(); });
$frm.filter = $('#frmOrganisationFilter');
@@ -337,16 +341,17 @@
$frm.filter.on('dblclick', '.FilterOrganisationRegionCaption', op.selectFilterRegion).on('click', '.FilterRegionSelect', op.selectFilterRegion).on('click', '.FilterRegionClear', op.clearFilterRegion);
$frm.orgId = $('#frmOrganisationId');
$frm.org = $('#frmOrganisation');
- $('.sax-input, .sax-textarea', $frm.org).on('input', function () { sax.clearControlError(this); });
- $('.sax-select', $frm.org).on('change', function () { sax.clearControlError(this); });
+ $frm.org.on('input', '.sax-input, .sax-textarea', function () { sax.clearControlError(this); }).on('change', '.sax-select', function () { sax.clearControlError(this); });
+ $frm.org.on('dblclick', '.OrganisationSportCaption', op.selectOrgSport).on('click', '#pbSelectSport', op.selectOrgSport).on('click', '.OrganisationSportClear', op.clearOrgSport);
+ $frm.org.on('dblclick', '.OrganisationRegionCaptionCountry', op.selectOrgRegion).on('click', '#pbSelectRegion', op.selectOrgRegion);
var opt = sax.dlgOpts();
- opt.buttons[sax.dlg.btn.ok] = function () { sax.storeItem(); };
+ opt.buttons[sax.dlg.btn.ok] = function () { op.storeItem(); };
opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); };
$dlg.organisation = $('#dlgOrganisation').dialog(opt);
var opt = sax.dlgOpts();
- opt.buttons[sax.dlg.btn.ok] = function () { sax.activateOrganisation(); };
+ opt.buttons[sax.dlg.btn.ok] = function () { op.activateOrganisation(); };
opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); };
$dlg.activate = $('#dlgOrganisationActivation').dialog(opt);
diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-user.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-user.js
index 8e5d42d..bea6543 100644
--- a/SaxoniteCoreWebAdmin/wwwroot/js/sax-user.js
+++ b/SaxoniteCoreWebAdmin/wwwroot/js/sax-user.js
@@ -264,14 +264,14 @@
//--------------------------------------------------------------
sax.createItem = function ()
{
- sax.clearUserData();
+ sax.clearItemData();
$dlg.user.dialog('option', 'title', sax.dlg.title.createUser);
sax.openDialog($dlg.user, 600, 480);
}
- sax.clearUserData = function ()
+ sax.clearItemData = function ()
{
let frm = $frm.user;
- $('.UserAccountId,.UserRegionIdCountry,.UserRegionIdProvince,.UserRoleCodes,input[type="text"],textarea,select', frm).val('');
+ $('.UserId,.UserRegionIdCountry,.UserRegionIdProvince,.UserRoleCodes,input[type="text"],textarea,select', frm).val('');
$('.UserStatus', frm).val(sax.data.defaultStatusCode);
sax.clearControlErrors();
sax.userAccount = { userRoleCodes: [] };
@@ -280,7 +280,7 @@
//--------------------------------------------------------------
sax.updateItem = function (item)
{
- $('.UserAccountId', $frm.userId).val(item.id);
+ $('.UserId', $frm.userId).val(item.id);
sax.ajax.updateItem = sax.ajax.updateItem || { url: sax.url.base + 'User/Ajax/GetItem', formId: 'frmUserId', callbackFn: sax.onUpdateItem };
sax.doAjaxRequest(sax.ajax.updateItem, 50);
}
@@ -288,10 +288,10 @@
{
//sax.debug('onUpdateItem', response);
if (!response.success) return;
- sax.clearUserData();
+ sax.clearItemData();
let item = sax.userAccount = response.user;
let frm = $frm.user;
- $('.UserAccountId', frm).val(item.id);
+ $('.UserId', frm).val(item.id);
$('.UserEmailAddress', frm).val(item.emailAddress);
$('.UserTitle', frm).val(item.title);
$('.UserFirstName', frm).val(item.firstName);
@@ -333,9 +333,9 @@
//--------------------------------------------------------------
sax.userEmails = function (item)
{
- sax.debug('userEmails', item);
+ //sax.debug('userEmails', item);
let frm = $frm.emailsl
- $('.UserAccountId', frm).val(item.id);
+ $('.UserId', frm).val(item.id);
$('.UserEmailAddress', frm).val(item.emailAddress);
$('.UserDisplayName', frm).val(item.displayName);
$('.RequestPasswordAdminOption', frm).toggle(item.systemAdmin);
diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-usr-onl.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-usr-onl.js
index 06292f7..5e0799e 100644
--- a/SaxoniteCoreWebAdmin/wwwroot/js/sax-usr-onl.js
+++ b/SaxoniteCoreWebAdmin/wwwroot/js/sax-usr-onl.js
@@ -198,20 +198,24 @@
//--------------------------------------------------------------
sax.createItem = function ()
+ {
+ sax.clearItemData();
+ $dlg.user.dialog('option', 'title', sax.dlg.title.createUser);
+ sax.openDialog($dlg.user, 600, 480);
+ }
+ sax.clearItemData = function ()
{
let frm = $frm.user;
- $('.UserAccountId,.UserRoleCodes,input[type="text"],textarea,select', frm).val('');
+ $('.UserId,.UserRoleCodes,input[type="text"],textarea,select', frm).val('');
$('.UserStatus', frm).val(sax.data.defaultStatusCode);
sax.clearControlErrors();
sax.userAccount = { userRoleCodes: [] };
- $dlg.user.dialog('option', 'title', sax.dlg.title.createUser);
- sax.openDialog($dlg.user, 600, 480);
}
//--------------------------------------------------------------
sax.updateItem = function (item)
{
- $('.UserAccountId', $frm.userId).val(item.id);
+ $('.UserId', $frm.userId).val(item.id);
sax.ajax.updateItem = sax.ajax.updateItem || { url: sax.url.base + 'User/Ajax/GetItem', formId: 'frmUserId', callbackFn: sax.onUpdateItem };
sax.doAjaxRequest(sax.ajax.updateItem, 50);
}
@@ -219,11 +223,10 @@
{
//sax.debug('onUpdateItem', response);
let frm = $frm.user;
- $('.UserAccountId,input[type="text"],textarea,select', frm).val('');
- sax.clearControlErrors();
+ sax.clearItemData();
if (!response.success) return;
let item = sax.userAccount = response.user;
- $('.UserAccountId', frm).val(item.id);
+ $('.UserId', frm).val(item.id);
$('.UserEmailAddress', frm).val(item.emailAddress);
$('.UserTitle', frm).val(item.title);
$('.UserFirstName', frm).val(item.firstName);
@@ -263,7 +266,7 @@
{
sax.debug('userEmails', item);
let frm = $frm.emailsl
- $('.UserAccountId', frm).val(item.id);
+ $('.UserId', frm).val(item.id);
$('.UserEmailAddress', frm).val(item.emailAddress);
$('.UserDisplayName', frm).val(item.displayName);
$('.RequestPasswordAdminOption', frm).toggle(item.systemAdmin);
diff --git a/SaxoniteCoreWebOnline/Online/Controllers/ActivityController-Ajax.cs b/SaxoniteCoreWebOnline/Online/Controllers/ActivityController-Ajax.cs
index 0ae7747..d65f303 100644
--- a/SaxoniteCoreWebOnline/Online/Controllers/ActivityController-Ajax.cs
+++ b/SaxoniteCoreWebOnline/Online/Controllers/ActivityController-Ajax.cs
@@ -173,6 +173,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
SysId userAccountId = UserAccountId;
SaxActivityConsole.IndexContext indexContext = new SaxActivityConsole.IndexContext(userAccountId);
+ // Period.
+ indexContext.EffectiveTo = DateTime.Today;
+
// Regions.
if (SysId.IsValid(sessionData.User.RegionIdProvince))
indexContext.RegionIds.Add(sessionData.User.RegionIdProvince);
diff --git a/SaxoniteCoreWebOnline/Online/Controllers/ArticleController-Ajax.cs b/SaxoniteCoreWebOnline/Online/Controllers/ArticleController-Ajax.cs
index 6066df2..f38cf2b 100644
--- a/SaxoniteCoreWebOnline/Online/Controllers/ArticleController-Ajax.cs
+++ b/SaxoniteCoreWebOnline/Online/Controllers/ArticleController-Ajax.cs
@@ -67,7 +67,8 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
{
public String RegionIdPrimary { get; set; }
public String SportIdPrimary { get; set; }
- public bool Published { get; set; }
+ public bool? Published { get; set; } = null;
+ public bool? PublishedInFuture { get; set; } = null;
public String PublishedOn_YYYYMMDD { get; set; }
public String PublishedOn_Calendar { get; set; }
public ArticleContentData Content { get; } = new ArticleContentData();
@@ -90,7 +91,8 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
PopulateArticleResponseData(model, article, data as ArticleData_List);
data.RegionIdPrimary = model.GetEncryptedRegionId(article.RegionIdPrimary);
data.SportIdPrimary = model.GetEncryptedSportId(article.SportIdPrimary);
- data.Published = DateUtil.IsValid(article.PublishedAt);
+ data.Published = DateUtil.IsValid(article.PublishedAt) ? true : (bool?)null;
+ data.PublishedInFuture = (data.Published == true && article.PublishedAt.CompareTo(DateTime.Today) >= 0) ? true : (bool?)null;
data.PublishedOn_YYYYMMDD = DateUtil.Format(article.PublishedAt, "yyyyMMdd");
data.PublishedOn_Calendar = model.FormatDateForForm(article.PublishedAt);
@@ -126,6 +128,8 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
public List
Articles { get; } = new List();
/// Organisations that the user has rights to author articles for.
public List Organisations { get; set; }
+ public ItemIdName defaultSport { get; set; }
+ public ItemIdName defaultRegion { get; set; }
}
//-------------------------------------------------------------------
[HttpPost]
@@ -144,88 +148,120 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
SysId userAccountId = UserAccountId;
RefreshModel(model);
- // Organisations that the user has rights to author articles for.
- foreach (SaxAccountMgr.OrganisationIdName organisation in AccountMgr.GetOrganisationsForAnyUserRole(userAccountId, new [] { Sax.OrganisationRole.Admin, Sax.OrganisationRole.ArticleAdmin }))
+ // Record disposable items as they are created so all can be disposed when needed.
+ using (DisposableCollection disposableItems = new DisposableCollection())
{
- if (responseData.Organisations == null) responseData.Organisations = new List();
- OrganisationData organisationData = new OrganisationData()
+ // User account.
+ SaxUserAccount userAccount = AccountMgr.GetUserAccountById(UserAccountId);
+ disposableItems.Add(userAccount);
+
+ // Organisations that the user has rights to author articles for.
+ foreach (SaxAccountMgr.OrganisationIdName articleOrganisation in AccountMgr.GetOrganisationsForAnyUserRole(userAccountId, new[] { Sax.OrganisationRole.Admin, Sax.OrganisationRole.ArticleAdmin }))
{
- Id = model.EncryptId(organisation.Id),
- Name = organisation.Name
- };
- responseData.Organisations.Add(organisationData);
- }
-
- // User must either be a journalist or allowed to author organisation articles.
- if (!UserIsJournalist && responseData.Organisations == null) return GetAjaxResult_GoHome(responseData);
- if (UserIsJournalist && responseData.Organisations != null)
- {
- OrganisationData organisationData = new OrganisationData()
- {
- Id = "",
- Name = "No Organisation - Journalist Articles"
- };
- responseData.Organisations.Insert(0, organisationData);
- }
-
- // Filter organisation.
- SysId organisationIdFilter = model.ExtractSysId(model.Filter.OrganisationId);
-
- // Item filter.
- SaxArticle.Params prmArticle = new SaxArticle.Params();
- prmArticle.UserAccountIdsAuthorIncluded.Add(sessionData.User.UserAccountId);
- if (SysId.IsValid(organisationIdFilter))
- prmArticle.OrganisationIdsIncluded.Add(organisationIdFilter);
- prmArticle.ArticleFilter = model.Filter.Article;
- prmArticle.StatusCat = SaxArticle.StatusCat.NotDeleted;
- model.Paging.ItemTotal = (ulong)ActivityMgr.GetArticleCount(prmArticle);
- model.PopulatePagingTo(prmArticle.ResultsPaging);
-
- // Item columns.
- ColumnDfn colId = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Id);
- ColumnDfn colOrganisationId = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.OrganisationId);
- ColumnDfn colHeadline = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Headline);
- ColumnDfn colSummary = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Summary);
- ColumnDfn colRegionIdPrimary = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.RegionIdPrimary);
- ColumnDfn colSportIdPrimary = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.SportIdPrimary);
- ColumnDfn colPublishedOn = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.PublishedAt_Date);
- ColumnDfn colStatus = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Status);
- ColumnDfn colCreatedOn = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.CreateOn_Date);
- List columns = new List()
- {
- colId, colOrganisationId, colHeadline, colSummary,
- colRegionIdPrimary, colSportIdPrimary, colPublishedOn,
- colStatus, colCreatedOn
- };
-
- // Sort columns.
- colCreatedOn.SortAscending = false;
- prmArticle.SortColumns.Add(colCreatedOn);
-
- // Query items.
- using (DbResultSet resultSet = ActivityMgr.ExecuteArticleQuery(columns, prmArticle))
- {
- while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
- {
- NamedValue.Map values = resultSet.GetRecordValues();
- ArticleData_List articleData = new ArticleData_List()
+ if (responseData.Organisations == null) responseData.Organisations = new List();
+ OrganisationData organisationData = new OrganisationData()
{
- Id = values.GetString(colId.DataName),
- OrganisationId = values.GetString(colOrganisationId.DataName),
- Headline = values.GetString(colHeadline.DataName),
- Summary = values.GetString(colSummary.DataName),
- RegionCaptionPrimary = model.GetRegionCaption(values.GetString(colRegionIdPrimary.DataName).ToSysId()),
- SportCaptionPrimary = model.GetSportCaption(values.GetString(colSportIdPrimary.DataName).ToSysId()),
- CreatedOnFmt = DateUtil.Format(values.GetDateTime(colCreatedOn.DataName), "d-MMM-yyyy"),
- PublishedOnFmt = DateUtil.Format(values.GetDateTime(colPublishedOn.DataName), "d-MMM-yyyy"),
- StatusCode = values.GetString(colStatus.DataName),
- StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName))
+ Id = model.EncryptId(articleOrganisation.Id),
+ Name = articleOrganisation.Name
};
- responseData.Articles.Add(articleData);
+ responseData.Organisations.Add(organisationData);
}
+
+ // User must either be a journalist or allowed to author organisation articles.
+ if (!UserIsJournalist && responseData.Organisations == null) return GetAjaxResult_GoHome(responseData);
+ if (UserIsJournalist && responseData.Organisations != null)
+ {
+ OrganisationData organisationData = new OrganisationData()
+ {
+ Id = "",
+ Name = "No Organisation - Journalist Articles"
+ };
+ responseData.Organisations.Insert(0, organisationData);
+ }
+
+ // Filter organisation.
+ SysId organisationIdFilter = model.ExtractSysId(model.Filter.OrganisationId);
+ SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationIdFilter);
+ disposableItems.Add(organisation);
+
+ // Default Sport - defined by organisation if selected.
+ SysId defaultSportId = organisation?.SportIdPrimary ?? null;
+ if (SysId.IsValid(defaultSportId))
+ {
+ responseData.defaultSport = new AjaxResponse_Data.ItemIdName()
+ {
+ Id = model.GetEncryptedSportId(defaultSportId),
+ Name = model.GetSportCaption(defaultSportId)
+ };
+ }
+
+ // Default region - defined by organisation (if selected) otherwise user themselves.
+ SysId defaultRegionId = organisation?.RegionIdPrimary ?? userAccount?.RegionIdCountry ?? null;
+ if (SysId.IsValid(defaultRegionId))
+ {
+ responseData.defaultRegion = new AjaxResponse_Data.ItemIdName()
+ {
+ Id = model.GetEncryptedRegionId(defaultRegionId),
+ Name = model.GetRegionCaption(defaultRegionId)
+ };
+ }
+
+ // Item filter.
+ SaxArticle.Params prmArticle = new SaxArticle.Params();
+ prmArticle.UserAccountIdsAuthorIncluded.Add(sessionData.User.UserAccountId);
+ if (SysId.IsValid(organisationIdFilter))
+ prmArticle.OrganisationIdsIncluded.Add(organisationIdFilter);
+ prmArticle.ArticleFilter = model.Filter.Article;
+ prmArticle.StatusCat = SaxArticle.StatusCat.NotDeleted;
+ model.Paging.ItemTotal = (ulong)ActivityMgr.GetArticleCount(prmArticle);
+ model.PopulatePagingTo(prmArticle.ResultsPaging);
+
+ // Item columns.
+ ColumnDfn colId = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Id);
+ ColumnDfn colOrganisationId = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.OrganisationId);
+ ColumnDfn colHeadline = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Headline);
+ ColumnDfn colSummary = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Summary);
+ ColumnDfn colRegionIdPrimary = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.RegionIdPrimary);
+ ColumnDfn colSportIdPrimary = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.SportIdPrimary);
+ ColumnDfn colPublishedOn = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.PublishedAt_Date);
+ ColumnDfn colStatus = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Status);
+ ColumnDfn colCreatedOn = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.CreateOn_Date);
+ List columns = new List()
+ {
+ colId, colOrganisationId, colHeadline, colSummary,
+ colRegionIdPrimary, colSportIdPrimary, colPublishedOn,
+ colStatus, colCreatedOn
+ };
+
+ // Sort columns.
+ colCreatedOn.SortAscending = false;
+ prmArticle.SortColumns.Add(colCreatedOn);
+
+ // Query items.
+ using (DbResultSet resultSet = ActivityMgr.ExecuteArticleQuery(columns, prmArticle))
+ {
+ while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
+ {
+ NamedValue.Map values = resultSet.GetRecordValues();
+ ArticleData_List articleData = new ArticleData_List()
+ {
+ Id = values.GetString(colId.DataName),
+ OrganisationId = values.GetString(colOrganisationId.DataName),
+ Headline = values.GetString(colHeadline.DataName),
+ Summary = values.GetString(colSummary.DataName),
+ RegionCaptionPrimary = model.GetRegionCaption(values.GetString(colRegionIdPrimary.DataName).ToSysId()),
+ SportCaptionPrimary = model.GetSportCaption(values.GetString(colSportIdPrimary.DataName).ToSysId()),
+ CreatedOnFmt = DateUtil.Format(values.GetDateTime(colCreatedOn.DataName), "d-MMM-yyyy"),
+ PublishedOnFmt = DateUtil.Format(values.GetDateTime(colPublishedOn.DataName), "d-MMM-yyyy"),
+ StatusCode = values.GetString(colStatus.DataName),
+ StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName))
+ };
+ responseData.Articles.Add(articleData);
+ }
+ }
+ if (model.Paging.IsPaged)
+ model.Paging.ItemCount = (ushort)responseData.Articles.Count;
}
- if (model.Paging.IsPaged)
- model.Paging.ItemCount = (ushort)responseData.Articles.Count;
// Complete response.
responseData.SetPaging(model);
@@ -260,39 +296,46 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
SysId userAccountId = UserAccountId;
RefreshModel(model);
- // Identify item.
- SysId articleId = model.ExtractSysId(model.ArticleId);
- if (!SysId.IsValid(articleId))
- return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
-
- // Retrieve item.
- SaxArticle article = ActivityMgr.GetArticleById(articleId);
- if (article == null)
+ // Record disposable items as they are created so all can be disposed when needed.
+ using (DisposableCollection disposableItems = new DisposableCollection())
{
- SaLogger.Warn(fn + " Failed to retrieve Article for Id: '" + model.ArticleId + "'");
- return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
- }
- if (!article.UserAccountIdAuthor.Equals(userAccountId))
- {
- SaLogger.Warn(fn + " Inconsistent Article Author. Expected: " + userAccountId + ". Found: " + article.UserAccountIdAuthor);
- return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
- }
- // Delete upload images.
- SaxItemImage.Params prmItemImage = new SaxItemImage.Params();
- prmItemImage.ItemIdsIncluded.Add(new ItemId((short)Sax.DataItemType.Article, articleId));
- prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.ArticleUpload);
- prmItemImage.StatusCat = SaxItemImage.StatusCat.NotDeleted;
- foreach (SaxItemImage itemImage in ItemDataMgr.GetItemImageList(prmItemImage))
- {
- itemImage.SessionUid = 0;
- itemImage.ImageUid = 0;
- itemImage.Status = SaStatus.Deleted;
- ItemDataMgr.UpdateItemImage(itemImage, DbUpdateInfo);
- }
+ // Identify item.
+ SysId articleId = model.ExtractSysId(model.ArticleId);
+ if (!SysId.IsValid(articleId))
+ return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
- // Construct response.
- PopulateArticleResponseData(model, article, responseData.Article);
+ // Retrieve item.
+ SaxArticle article = ActivityMgr.GetArticleById(articleId);
+ disposableItems.Add(article);
+ if (article == null)
+ {
+ SaLogger.Warn(fn + " Failed to retrieve Article for Id: '" + model.ArticleId + "'");
+ return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
+ }
+ if (!article.UserAccountIdAuthor.Equals(userAccountId))
+ {
+ SaLogger.Warn(fn + " Inconsistent Article Author. Expected: " + userAccountId + ". Found: " + article.UserAccountIdAuthor);
+ return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
+ }
+
+ // Delete upload images.
+ SaxItemImage.Params prmItemImage = new SaxItemImage.Params();
+ prmItemImage.ItemIdsIncluded.Add(new ItemId((short)Sax.DataItemType.Article, articleId));
+ prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.ArticleUpload);
+ prmItemImage.StatusCat = SaxItemImage.StatusCat.NotDeleted;
+ foreach (SaxItemImage itemImage in ItemDataMgr.GetItemImageList(prmItemImage))
+ {
+ disposableItems.Add(itemImage);
+ itemImage.SessionUid = 0;
+ itemImage.ImageUid = 0;
+ itemImage.Status = SaStatus.Deleted;
+ ItemDataMgr.UpdateItemImage(itemImage, DbUpdateInfo);
+ }
+
+ // Construct response.
+ PopulateArticleResponseData(model, article, responseData.Article);
+ }
responseData.Success = true;
return Json(responseData);
}
@@ -311,9 +354,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
// Ajax request.
[HttpPost]
[Route("Article/Ajax/UploadImage")]
- public IActionResult UploadArticleImage(Model_Article model)
+ public IActionResult Ajax_UploadArticleImage(Model_Article model)
{
- String fn = GetType().Name + ".UploadArticleImage";
+ String fn = GetType().Name + ".Ajax_UploadArticleImage";
AjaxResponse_UploadArticleImage responseData = new AjaxResponse_UploadArticleImage(model);
String messageTitle = Localiser["article.caption.article"];
@@ -323,85 +366,91 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
SaxSessionData_Online sessionData = SessionData_Online;
RefreshModel(model);
- // Validate number of images.
- if (model.ArticleImage.IsEmpty())
+ // Record disposable items as they are created so all can be disposed when needed.
+ using (DisposableCollection disposableItems = new DisposableCollection())
{
- SaLogger.Warn(fn + " No image file supplied for upload");
- return Json(responseData);
- }
- if (model.ArticleImage.Count != 1)
- {
- SaLogger.Warn(fn + " Invalid number of image files uploaded: " + model.ArticleImage.Count);
- return Json(responseData.SetControlError("ArticleImage", Localiser["msg.upload.image.single"]));
- }
- IFormFile file = model.ArticleImage[0];
- // Image properties.
- byte[] imageData = null;
- using (MemoryStream fileStream = new MemoryStream())
- {
- file.CopyTo(fileStream);
- imageData = fileStream.ToArray();
- }
-
- // Validate the image.
- ImageUtils.ImageConfig imageConfig = ImageUtils.VerifyImageData(imageData);
- if (!imageConfig.ValidImage)
- return Json(responseData.SetControlError("ArticleImage", Localiser["msg.upload.image.invalid"]));
-
- // Image belongs to the article.
- // If the article doesn't yet exist, it will need to be uploaded to the user first and later transferred.
- SysId articleId = model.ExtractSysId(model.ArticleId);
- ItemId articleItemId = new ItemId((short)Sax.DataItemType.Article, articleId);
- ItemId userItemId = new ItemId((short)Sax.DataItemType.UserAccount, sessionData.User.UserAccountId);
- ItemId imageItemId = SysId.IsValid(articleId) ? articleItemId : userItemId;
-
- // Store uploaded image as 'Upload' - awaiting confirmation that the article details are to be saved.
- // NB Reuse any existing deleted article upload image to avoid creating new images unless necessary.
- SaxItemImage.Params prmItemImage = new SaxItemImage.Params();
- prmItemImage.ItemIdsIncluded.Add(imageItemId);
- prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.Article);
- prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.ArticleUpload);
- prmItemImage.StatusCat = SaxItemImage.StatusCat.DeletedOnly;
- prmItemImage.ResultsPaging.PageLength = 1;
- prmItemImage.ResultsPaging.PageNo = 1;
- List itemImages = ItemDataMgr.GetItemImageList(prmItemImage);
- SaxItemImage itemImage = !itemImages.IsEmpty() ? itemImages[0] : null;
- if (itemImage == null)
- itemImage = ItemDataMgr.CreateItemImage(imageItemId, Sax.ImageType.ArticleUpload);
- itemImage.ImageType = Sax.ImageType.ArticleUpload;
- itemImage.Filename = file.FileName;
- itemImage.Mime = SacsContentTypeHelper.GetMimeTypeFromContentType(file.ContentType).ToString().ToLower();
- itemImage.ContentType = file.ContentType;
- itemImage.Width = imageConfig.Width;
- itemImage.Height = imageConfig.Height;
- itemImage.ImageData = imageData;
- itemImage.SessionUid = sessionData.SessionIdx;
- itemImage.ImageUid = sessionData.NextItemIdx;
- itemImage.Status = SaxItemImage.DefaultStatus;
-
- if (!SysId.IsValid(itemImage.Id))
- {
- if (!ItemDataMgr.InsertItemImage(itemImage, DbUpdateInfo))
+ // Validate number of images.
+ if (model.ArticleImage.IsEmpty())
{
- SaLogger.Warn(fn + " Failed to insert uploaded image - " + ItemDataMgr.ErrorStateMessage);
- return Json(responseData.SetControlError("ArticleImage", Localiser["msg.error.item.insert.failed"]));
+ SaLogger.Warn(fn + " No image file supplied for upload");
+ return Json(responseData);
}
- }
- else
- {
- if (!ItemDataMgr.UpdateItemImage(itemImage, DbUpdateInfo))
+ if (model.ArticleImage.Count != 1)
{
- SaLogger.Warn(fn + " Failed to update uploaded image - " + ItemDataMgr.ErrorStateMessage);
- return Json(responseData.SetControlError("ArticleImage", Localiser["msg.error.item.insert.failed"]));
+ SaLogger.Warn(fn + " Invalid number of image files uploaded: " + model.ArticleImage.Count);
+ return Json(responseData.SetControlError("ArticleImage", Localiser["msg.upload.image.single"]));
}
- }
+ IFormFile file = model.ArticleImage[0];
- // Segment image info.
- responseData.Segment = new ArticleContentSegmentData();
- responseData.Segment.Image = new ArticleContentSegmentImageData();
- responseData.Segment.Image.ImageLink = GetArticleImageLink(itemImage.Id);
- responseData.Segment.Image.ImageIdx = itemImage.ImageUid;
+ // Image properties.
+ byte[] imageData = null;
+ using (MemoryStream fileStream = new MemoryStream())
+ {
+ file.CopyTo(fileStream);
+ imageData = fileStream.ToArray();
+ }
+
+ // Validate the image.
+ ImageUtils.ImageConfig imageConfig = ImageUtils.VerifyImageData(imageData);
+ if (!imageConfig.ValidImage)
+ return Json(responseData.SetControlError("ArticleImage", Localiser["msg.upload.image.invalid"]));
+
+ // Image belongs to the article.
+ // If the article doesn't yet exist, it will need to be uploaded to the user first and later transferred.
+ SysId articleId = model.ExtractSysId(model.ArticleId);
+ ItemId articleItemId = new ItemId((short)Sax.DataItemType.Article, articleId);
+ ItemId userItemId = new ItemId((short)Sax.DataItemType.UserAccount, sessionData.User.UserAccountId);
+ ItemId imageItemId = SysId.IsValid(articleId) ? articleItemId : userItemId;
+
+ // Store uploaded image as 'Upload' - awaiting confirmation that the article details are to be saved.
+ // NB Reuse any existing deleted article upload image to avoid creating new images unless necessary.
+ SaxItemImage.Params prmItemImage = new SaxItemImage.Params();
+ prmItemImage.ItemIdsIncluded.Add(imageItemId);
+ prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.Article);
+ prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.ArticleUpload);
+ prmItemImage.StatusCat = SaxItemImage.StatusCat.DeletedOnly;
+ prmItemImage.ResultsPaging.PageLength = 1;
+ prmItemImage.ResultsPaging.PageNo = 1;
+ List itemImages = ItemDataMgr.GetItemImageList(prmItemImage);
+ SaxItemImage itemImage = !itemImages.IsEmpty() ? itemImages[0] : null;
+ if (itemImage == null)
+ itemImage = ItemDataMgr.CreateItemImage(imageItemId, Sax.ImageType.ArticleUpload);
+ disposableItems.Add(itemImage);
+ itemImage.ImageType = Sax.ImageType.ArticleUpload;
+ itemImage.Filename = file.FileName;
+ itemImage.Mime = SacsContentTypeHelper.GetMimeTypeFromContentType(file.ContentType).ToString().ToLower();
+ itemImage.ContentType = file.ContentType;
+ itemImage.Width = imageConfig.Width;
+ itemImage.Height = imageConfig.Height;
+ itemImage.ImageData = imageData;
+ itemImage.SessionUid = sessionData.SessionIdx;
+ itemImage.ImageUid = sessionData.NextItemIdx;
+ itemImage.Status = SaxItemImage.DefaultStatus;
+
+ if (!SysId.IsValid(itemImage.Id))
+ {
+ if (!ItemDataMgr.InsertItemImage(itemImage, DbUpdateInfo))
+ {
+ SaLogger.Warn(fn + " Failed to insert uploaded image - " + ItemDataMgr.ErrorStateMessage);
+ return Json(responseData.SetControlError("ArticleImage", Localiser["msg.error.item.insert.failed"]));
+ }
+ }
+ else
+ {
+ if (!ItemDataMgr.UpdateItemImage(itemImage, DbUpdateInfo))
+ {
+ SaLogger.Warn(fn + " Failed to update uploaded image - " + ItemDataMgr.ErrorStateMessage);
+ return Json(responseData.SetControlError("ArticleImage", Localiser["msg.error.item.insert.failed"]));
+ }
+ }
+
+ // Segment image info.
+ responseData.Segment = new ArticleContentSegmentData();
+ responseData.Segment.Image = new ArticleContentSegmentImageData();
+ responseData.Segment.Image.ImageLink = GetArticleImageLink(itemImage.Id);
+ responseData.Segment.Image.ImageIdx = itemImage.ImageUid;
+ }
// Complete response.
//responseData.SetNotification(messageTitle, "Image uploaded.");
@@ -450,7 +499,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
if (SysId.IsValid(organisationId))
{
// Organisation specified - User must have Article Admin role.
- if (!AccountMgr.UserHasAnyOrganisationRole(userAccountId, organisationId, new [] { Sax.OrganisationRole.Admin, 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());
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
@@ -515,8 +564,13 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
article.Headline = model.ArticleHeadline;
if (model.ArticleSummary != null)
article.Summary = model.ArticleSummary;
- if (model.ArticlePublish)
- article.PublishedAt = model.GetArticlePublishOn();
+ if (!model.ArticlePublished.ToBool())
+ {
+ if (model.ArticlePublish)
+ article.PublishedAt = model.GetArticlePublishOn();
+ else
+ article.PublishedAt = DateTime.MinValue;
+ }
if (model.ArticleStatusCode != null)
article.Status = model.ArticleStatus;
diff --git a/SaxoniteCoreWebOnline/Online/Models/Model_Article.cs b/SaxoniteCoreWebOnline/Online/Models/Model_Article.cs
index e599b82..32f7037 100644
--- a/SaxoniteCoreWebOnline/Online/Models/Model_Article.cs
+++ b/SaxoniteCoreWebOnline/Online/Models/Model_Article.cs
@@ -73,6 +73,7 @@ namespace Saxonite.Net.Core.Web.Online.Models
// Article images.
public List ArticleImage { get; set; }
// Article publication.
+ public String ArticlePublished { get; set; }
public bool ArticlePublish { get; set; }
public String ArticlePublishOn { get; set; }
public DateTime GetArticlePublishOn()
@@ -123,7 +124,8 @@ namespace Saxonite.Net.Core.Web.Online.Models
}
// Article publication.
- if (ArticlePublish)
+ // Only relevant when the article hasn't yet been published and user has selected 'Publish'.
+ if (!ArticlePublished.ToBool() && ArticlePublish)
{
String controlName = "ArticlePublication";
DateTime publishedOn = GetArticlePublishOn();
diff --git a/SaxoniteCoreWebOnline/Views/Article/Index.cshtml b/SaxoniteCoreWebOnline/Views/Article/Index.cshtml
index 166bac3..940bd20 100644
--- a/SaxoniteCoreWebOnline/Views/Article/Index.cshtml
+++ b/SaxoniteCoreWebOnline/Views/Article/Index.cshtml
@@ -7,7 +7,7 @@
diff --git a/SaxoniteCoreWebOnline/Views/Article/Panel-ArticleDialog.cshtml b/SaxoniteCoreWebOnline/Views/Article/Panel-ArticleDialog.cshtml
index 558f57b..62f079c 100644
--- a/SaxoniteCoreWebOnline/Views/Article/Panel-ArticleDialog.cshtml
+++ b/SaxoniteCoreWebOnline/Views/Article/Panel-ArticleDialog.cshtml
@@ -118,6 +118,7 @@
+ @Html.HiddenFor(model => model.ArticlePublished, new { @id = "ifArticlePublished" })
@Html.CheckBoxFor(model => model.ArticlePublish, new { @id = "chkArticlePublish", @class = "ArticlePublish" }) @Localiser["label.publish"]
@Html.TextBoxFor(model => model.ArticlePublishOn, new { @id = "ifArticlePublishOn", @class = "sax-input sax-calendar ArticlePublishOn", @readonly = "readonly" })
diff --git a/SaxoniteCoreWebOnline/wwwroot/js/sax-art.js b/SaxoniteCoreWebOnline/wwwroot/js/sax-art.js
index 668e685..2592b40 100644
--- a/SaxoniteCoreWebOnline/wwwroot/js/sax-art.js
+++ b/SaxoniteCoreWebOnline/wwwroot/js/sax-art.js
@@ -32,6 +32,8 @@
var $items = $('.sax-panel-item-list', $pnl.results).hide().empty();
if (!response.success) return;
sax.data.articleOrganisations = response.organisations;
+ sax.data.defaultSport = response.defaultSport;
+ sax.data.defaultRegion = response.defaultRegion;
sax.refreshPaging(response, '#frmArticleFilter', sax.refreshResults);
// Menu.
let $mnu = $('.sax-burger ul.sax-dropdown-menu', $pnl.filter).empty();
@@ -129,6 +131,17 @@
sax.createItem = function ()
{
sax.clearItem();
+ let $frmA = $frm.article;
+ if (sax.data.defaultSport)
+ {
+ $('#ifArticleSportId', $frmA).val(sax.data.defaultSport.id);
+ $('#ifArticleSportCaption', $frmA).val(sax.data.defaultSport.name);
+ }
+ if (sax.data.defaultRegion)
+ {
+ $('#ifArticleRegionId', $frmA).val(sax.data.defaultRegion.id);
+ $('#ifArticleRegionCaption', $frmA).val(sax.data.defaultRegion.name);
+ }
sax.populateArticleContent({});
sax.openArticleDialog(sax.dlg.title.createArticle);
}
@@ -136,7 +149,7 @@
{
let $frmF = $frm.filter;
let $frmA = $frm.article;
- $('#ifArticleId,#ifArticleExists,#ifArticleOrganisationId,#ifArticleRegionId,#ifArticleSportId,input[type="text"],textarea,select', $frmA).val('');
+ $('#ifArticleId,#ifArticleExists,#ifArticleOrganisationId,#ifArticleRegionId,#ifArticleSportId,#ifArticlePublish,input[type="text"],textarea,select', $frmA).val('');
let orgId = $('#ifFilterOrganisationId', $frmF).val();
$('#ifArticleOrganisationId', $frmA).val(orgId);
$('#ifArticleOrganisation', $frmA).val($('#ifFilterOrganisation', $frmF).val());
@@ -177,10 +190,12 @@
$('#ifArticleRegionCaption', $frmA).val(item.regionCaptionPrimary);
$('#ifArticleSportId', $frmA).val(item.sportIdPrimary);
$('#ifArticleSportCaption', $frmA).val(item.sportCaptionPrimary);
- if (item.published)
- $('span.ArticlePublishedOn', $frmA).text(item.publishedOnFmt);
- $('div.ArticlePublish', $frmA).toggle(!item.published);
- $('div.ArticlePublished', $frmA).toggle(!!item.published);
+ $('#ifArticlePublished', $frmA).val(item.published && !item.publishedInFuture ? 1 : 0);
+ $('#chkArticlePublish', $frmA).prop("checked", item.published);
+ $('.sax-input.sax-calendar.ArticlePublishOn', $frmA).datepicker('setDate', item.published ? item.publishedOn_Calendar : 'today');
+ $('span.ArticlePublishedOn', $frmA).text(item.publishedOnFmt);
+ $('div.ArticlePublish', $frmA).toggle(!item.published || item.publishedInFuture);
+ $('div.ArticlePublished', $frmA).toggle(!!item.published && !item.publishedInFuture);
$('#cbArticleStatusCode', $frmA).val(item.statusCode);
sax.populateArticleContent(item.content);
sax.openArticleDialog(sax.dlg.title.updateArticle);
@@ -453,7 +468,7 @@
$(function ()
{
$pnl.filter = $('.sax-panel-filter');
- $pnl.results= $('.sax-panel-results');
+ $pnl.results = $('.sax-panel-results');
$frm.filter = $('#frmArticleFilter');
$('.sax-action.sax-item-create', $pnl.filter).on('click', function () { sax.createItem(); });
@@ -475,7 +490,7 @@
ac.$content = $('.sax-article-panel.sax-article-content');
ac.$segList = $('.sax-article-segment-list', ac.$content);
- sax.initCalendars('.sax-input.sax-calendar').datepicker('option', { maxDate: '+' + (sax.maxPublishDaysAhead||'0') });
+ sax.initCalendars('.sax-input.sax-calendar', { minDate: '-' + (sax.articlePublish.maxDaysBefore || '7'), maxDate: '+' + (sax.articlePublish.maxDaysAhead || '7') });
var opt = sax.dlgOpts();
opt.buttons[sax.dlg.btn.ok] = function () { sax.uploadArticleImage(); };
diff --git a/SaxoniteCoreWebOnline/wwwroot/js/sax-home.js b/SaxoniteCoreWebOnline/wwwroot/js/sax-home.js
index 920f73d..7c40189 100644
--- a/SaxoniteCoreWebOnline/wwwroot/js/sax-home.js
+++ b/SaxoniteCoreWebOnline/wwwroot/js/sax-home.js
@@ -145,7 +145,7 @@
}
sax.setActivityReaction = function (r)
{
- sax.debug('setActivityReaction', r, $('.sax-dialog-activity button.ActivityReaction' + r));
+ //sax.debug('setActivityReaction', r, $('.sax-dialog-activity button.ActivityReaction' + r));
if ($('.sax-dialog-activity button.ActivityReaction' + r).hasClass(selectedClass)) r = 0;
sax.clearActivityReactionButton();
let fn = function (response)
diff --git a/SaxoniteCoreWebOnline/wwwroot/js/sax-org-evt.js b/SaxoniteCoreWebOnline/wwwroot/js/sax-org-evt.js
index 6b2c422..fecf73a 100644
--- a/SaxoniteCoreWebOnline/wwwroot/js/sax-org-evt.js
+++ b/SaxoniteCoreWebOnline/wwwroot/js/sax-org-evt.js
@@ -253,7 +253,7 @@
$frm.evtId = $('#frmEventId');
$frm.evt = $('#frmEvent');
$('.sax-input', $frm.evt).on('input', function () { sax.clearControlError(this); });
- sax.initCalendars('#frmEvent .sax-input.sax-calendar').datepicker('option', { maxDate: '+700' });
+ sax.initCalendars('#frmEvent .sax-input.sax-calendar', { maxDate: '+700' });
$frm.evt.on('dblclick', 'input.EventSportCaptionPrimary', oe.selectSportPrimary).on('click', 'button.SelectEventSportPrimary', oe.selectSportPrimary);
$frm.evt.on('dblclick', 'input.EventRegionCaptionCountry', oe.selectRegionCountry).on('click', 'button.SelectEventRegionCountry', oe.selectRegionCountry);
diff --git a/SaxoniteStandardBase/Base/App/Sax-Config.cs b/SaxoniteStandardBase/Base/App/Sax-Config.cs
index 9992d1c..73d913f 100644
--- a/SaxoniteStandardBase/Base/App/Sax-Config.cs
+++ b/SaxoniteStandardBase/Base/App/Sax-Config.cs
@@ -75,7 +75,8 @@ namespace Saxonite.Net.Standard.Base.App
}
public static class Articles
{
- public static ushort PublishMaxDaysAhead { get; } = 14;
+ public static ushort PublishMaxDaysBefore { get; } = 7;
+ public static ushort PublishMaxDaysAhead { get; } = 10;
}
public static class Search
{
diff --git a/SaxoniteStandardBase/Base/App/Sax-Version.cs b/SaxoniteStandardBase/Base/App/Sax-Version.cs
index 65d1c1c..4b72964 100644
--- a/SaxoniteStandardBase/Base/App/Sax-Version.cs
+++ b/SaxoniteStandardBase/Base/App/Sax-Version.cs
@@ -18,7 +18,7 @@ namespace Saxonite.Net.Standard.Base.App
//-------------------------------------------------------------------
public static class Version
{
- private static String version { get; } = "1.2.3.1";
+ private static String version { get; } = "1.2.3.2";
// Retrieve version.
public static String GetFullVersion () { return version; }
public static String GetAppVersion ()
diff --git a/SaxoniteStandardBase/Base/Consoles/SaxActivityConsole.cs b/SaxoniteStandardBase/Base/Consoles/SaxActivityConsole.cs
index c3a545c..f3d0a63 100644
--- a/SaxoniteStandardBase/Base/Consoles/SaxActivityConsole.cs
+++ b/SaxoniteStandardBase/Base/Consoles/SaxActivityConsole.cs
@@ -25,16 +25,16 @@ namespace Saxonite.Net.Standard.Base.Consoles
public class IndexContext
{
// ToDo Include Localiser.
- public IndexContext (SysId userAccountId)
+ public IndexContext(SysId userAccountId)
{
UserAccountId = userAccountId;
}
public SysId UserAccountId { get; }
public List
SportIds { get; } = new List();
public List RegionIds { get; } = new List();
- // Default period is ~12 months ago up to ~3 months in the future.
- public DateTime EffectiveFrom { get; } = DateUtil.IncrementDate(DateTime.Today, -365);
- public DateTime EffectiveTo { get; } = DateUtil.IncrementDate(DateTime.Today, 30);
+ // Todo: Default period is ~12 months ago up to ~3 months in the future.
+ public DateTime EffectiveFrom { get; set; } = DateUtil.IncrementDate(DateTime.Today, -365);
+ public DateTime EffectiveTo { get; set; } = DateUtil.IncrementDate(DateTime.Today, 30);
public bool IsValid()
{
// Context must contain at least a sport, a region and a valid effective period.