1268 lines
46 KiB
Plaintext
1268 lines
46 KiB
Plaintext
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.ComponentModel;
|
|
using System.ComponentModel.Composition;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using ChannelCodes.Model;
|
|
using DTS.Common.Enums;
|
|
using DTS.Common.Enums.Channels;
|
|
using DTS.Common.Events;
|
|
using DTS.Common.Events.ChannelCodes;
|
|
using DTS.Common.Interface.Channels.ChannelCodes;
|
|
using DTS.Common.Utilities.Logging;
|
|
using Prism.Events;
|
|
using Prism.Regions;
|
|
using Unity;
|
|
using DTS.Common.Interactivity;
|
|
|
|
// ReSharper disable CheckNamespace
|
|
// ReSharper disable MemberCanBePrivate.Global
|
|
// ReSharper disable InconsistentNaming
|
|
|
|
namespace ChannelCodes
|
|
{
|
|
/// <inheritdoc />
|
|
/// <summary>
|
|
/// this class handles ChannelCodesList functionality
|
|
/// </summary>
|
|
[PartCreationPolicy(CreationPolicy.Shared)]
|
|
public class ChannelCodesListViewModel : IChannelCodesListViewModel
|
|
{
|
|
/// <summary>
|
|
/// The ChannelCodeList view
|
|
/// </summary>
|
|
public IChannelCodesListView View { get; set; }
|
|
|
|
private IEventAggregator _eventAggregator { get; }
|
|
private IUnityContainer UnityContainer { get; }
|
|
|
|
public InteractionRequest<Notification> NotificationRequest { get; }
|
|
public InteractionRequest<Confirmation> ConfirmationRequest { get; }
|
|
|
|
/// <inheritdoc />
|
|
/// <summary>
|
|
/// Occurs when a property value changes.
|
|
/// </summary>
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
|
|
public void OnPropertyChanged(string propertyName)
|
|
{
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
}
|
|
|
|
#region constructors and initializers
|
|
private static bool _bAddListeners = false;
|
|
/// <summary>
|
|
/// Creates a new instance of the ChannelCodesListViewModel
|
|
/// </summary>
|
|
/// <param name="view"></param>
|
|
/// <param name="regionManager">The logical placeholder defined within the application's UI (in the shell or within views) into which views are displayed.</param>
|
|
/// <param name="eventAggregator">The EventAggregator which allows different components to publish/subscribe to events without being coupled to each other.</param>
|
|
/// <param name="unityContainer">The unityContainer.</param>
|
|
public ChannelCodesListViewModel(IChannelCodesListView view, IRegionManager regionManager,
|
|
IEventAggregator eventAggregator, IUnityContainer unityContainer)
|
|
{
|
|
ChannelCodesFunc = new Func<IList<IChannelCode>>(GetAllChannels);
|
|
View = view;
|
|
View.DataContext = this;
|
|
|
|
NotificationRequest = new InteractionRequest<Notification>();
|
|
ConfirmationRequest = new InteractionRequest<Confirmation>();
|
|
|
|
_eventAggregator = eventAggregator;
|
|
UnityContainer = unityContainer;
|
|
_eventAggregator.GetEvent<RaiseNotification>().Subscribe(OnRaiseNotification);
|
|
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>()
|
|
.Subscribe(OnBusyIndicatorNotification, ThreadOption.PublisherThread, true);
|
|
//this is a hack, the app startup is calling this, then the app itself, we only want the
|
|
//app itself to be handling the listeners
|
|
if (_bAddListeners)
|
|
{
|
|
_eventAggregator.GetEvent<TextPastedEvent>().Subscribe(OnTextPasted);
|
|
_eventAggregator.GetEvent<ChannelCodeCommittedEvent>()
|
|
.Subscribe(OnChannelCodesCommitted, ThreadOption.PublisherThread, true);
|
|
}
|
|
_bAddListeners = true;
|
|
}
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
private void OnChannelCodesCommitted(ChannelCodeCommittedEventArgs[] args)
|
|
{
|
|
//if there are no can args that the user can commit anyhow, we are done
|
|
if (!Array.Exists(args, a => a.CanUserCommitChannelCodes)) { return; }
|
|
|
|
var lookup = ChannelCodeType.GetChannelCodeTypeLookup();
|
|
var lookup2 = new Dictionary<ChannelEnumsAndConstants.ChannelCodeType, short>();
|
|
using (var e = lookup.GetEnumerator())
|
|
{
|
|
while (e.MoveNext())
|
|
{
|
|
switch (e.Current.Value)
|
|
{
|
|
case ChannelEnumsAndConstants.IsoCodeTypeString:
|
|
lookup2[ChannelEnumsAndConstants.ChannelCodeType.ISO] = e.Current.Key;
|
|
break;
|
|
case ChannelEnumsAndConstants.UserCodeTypeString:
|
|
lookup2[ChannelEnumsAndConstants.ChannelCodeType.User] = e.Current.Key;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
var codes = ChannelCode.ChannelCodes;
|
|
var isoLookup = new Dictionary<string, HashSet<string>>();
|
|
var userLookup = new Dictionary<string, HashSet<string>>();
|
|
foreach (var code in codes)
|
|
{
|
|
switch (code.CodeType)
|
|
{
|
|
case ChannelEnumsAndConstants.ChannelCodeType.ISO:
|
|
if (!isoLookup.ContainsKey(code.Code))
|
|
{
|
|
isoLookup[code.Code] = new HashSet<string>();
|
|
}
|
|
isoLookup[code.Code].Add(code.Name);
|
|
break;
|
|
case ChannelEnumsAndConstants.ChannelCodeType.User:
|
|
if (!userLookup.ContainsKey(code.Code))
|
|
{
|
|
userLookup[code.Code] = new HashSet<string>();
|
|
}
|
|
userLookup[code.Code].Add(code.Name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
foreach (var arg in args)
|
|
{
|
|
if (!arg.CanUserCommitChannelCodes) { continue; }
|
|
if (string.IsNullOrWhiteSpace(arg.Code) || string.IsNullOrWhiteSpace(arg.Name)) { continue; }
|
|
var newCode = new ChannelCode() { Code = arg.Code, CodeType = arg.ChannelCodeType, Name = arg.Name };
|
|
switch (arg.ChannelCodeType)
|
|
{
|
|
case ChannelEnumsAndConstants.ChannelCodeType.ISO:
|
|
if (!isoLookup.ContainsKey(arg.Code))
|
|
{
|
|
isoLookup[arg.Code] = new HashSet<string>();
|
|
}
|
|
if (!isoLookup[arg.Code].Contains(arg.Name))
|
|
{
|
|
newCode.Insert(lookup2);
|
|
isoLookup[arg.Code].Add(arg.Name);
|
|
}
|
|
break;
|
|
case ChannelEnumsAndConstants.ChannelCodeType.User:
|
|
if (!userLookup.ContainsKey(arg.Code))
|
|
{
|
|
userLookup[arg.Code] = new HashSet<string>();
|
|
}
|
|
if (!userLookup[arg.Code].Contains(arg.Name))
|
|
{
|
|
newCode.Insert(lookup2);
|
|
userLookup[arg.Code].Add(arg.Name);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
private void OnTextPasted(ITextPastedEventArgs args)
|
|
{
|
|
if (args.Id != ChannelCode.PASTE_ID) { return; }
|
|
|
|
if (!(args.Sender is IChannelCode channelCode))
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch (ViewMode)
|
|
{
|
|
case ViewModes.ISO:
|
|
{
|
|
PasteIso(channelCode, args.Text, args.Tag);
|
|
var last = ISOChannelCodes.Last();
|
|
if (!string.IsNullOrWhiteSpace(last.Code) || !string.IsNullOrWhiteSpace(last.Name))
|
|
{
|
|
MarkModifiedISO(last);
|
|
}
|
|
}
|
|
break;
|
|
case ViewModes.User:
|
|
{
|
|
PasteUser(channelCode, args.Text, args.Tag);
|
|
var last = UserChannelCodes.Last();
|
|
if (!string.IsNullOrWhiteSpace(last.Code) || !string.IsNullOrWhiteSpace(last.Name))
|
|
{
|
|
MarkModifiedUser(last);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
_eventAggregator.GetEvent<PageModifiedEvent>()
|
|
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page));
|
|
}
|
|
|
|
private void PasteIso(IChannelCode channelCode, string text, object tag)
|
|
{
|
|
bool bCode = tag.Equals("ISOCode");
|
|
|
|
var channelCodes = ParseText(text, true, bCode, out var oneColumn);
|
|
var index = ISOChannelCodes.IndexOf(channelCode);
|
|
|
|
foreach (var code in channelCodes)
|
|
{
|
|
if (index > (ISOChannelCodes.Count - 1))
|
|
{
|
|
AllISOChannelCodes.Add(code);
|
|
index++;
|
|
}
|
|
else
|
|
{
|
|
var ch = ISOChannelCodes[index++];
|
|
if (oneColumn)
|
|
{
|
|
ch.Code = bCode ? code.Code : ch.Code;
|
|
ch.Name = bCode ? ch.Name : code.Name;
|
|
}
|
|
else
|
|
{
|
|
ch.Code = code.Code;
|
|
ch.Name = code.Name;
|
|
}
|
|
}
|
|
}
|
|
SortIso(_isoSortField, false);
|
|
FilterIso();
|
|
}
|
|
private void FilterIso()
|
|
{
|
|
ISOChannelCodes.Clear();
|
|
foreach (var channel in AllISOChannelCodes)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(channel.Code) && string.IsNullOrWhiteSpace(channel.Name))
|
|
{
|
|
ISOChannelCodes.Add(channel);
|
|
continue;
|
|
}
|
|
if (_searchTermForField.ContainsKey(Fields.IsoChannelName))
|
|
{
|
|
var term = _searchTermForField[Fields.IsoChannelName];
|
|
if (!string.IsNullOrEmpty(term))
|
|
{
|
|
if (channel.Name.IndexOf(term, StringComparison.CurrentCultureIgnoreCase) < 0)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
if (_searchTermForField.ContainsKey(Fields.IsoCode))
|
|
{
|
|
var term = _searchTermForField[Fields.IsoCode];
|
|
if (!string.IsNullOrWhiteSpace(term))
|
|
{
|
|
if (channel.Code.IndexOf(term, StringComparison.CurrentCultureIgnoreCase) < 0)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
ISOChannelCodes.Add(channel);
|
|
}
|
|
}
|
|
private void FilterUser()
|
|
{
|
|
UserChannelCodes.Clear();
|
|
foreach (var channel in AllUserChannelCodes)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(channel.Code) && string.IsNullOrWhiteSpace(channel.Name))
|
|
{
|
|
UserChannelCodes.Add(channel);
|
|
continue;
|
|
}
|
|
if (_searchTermForField.ContainsKey(Fields.UserChannelName))
|
|
{
|
|
var term = _searchTermForField[Fields.UserChannelName];
|
|
if (!string.IsNullOrEmpty(term))
|
|
{
|
|
if (channel.Name.IndexOf(term, StringComparison.CurrentCultureIgnoreCase) < 0)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
if (_searchTermForField.ContainsKey(Fields.UserCode))
|
|
{
|
|
var term = _searchTermForField[Fields.UserCode];
|
|
if (!string.IsNullOrWhiteSpace(term))
|
|
{
|
|
if (channel.Code.IndexOf(term, StringComparison.CurrentCultureIgnoreCase) < 0)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
UserChannelCodes.Add(channel);
|
|
}
|
|
}
|
|
public class ChannelComparer : IComparer<IChannelCode>
|
|
{
|
|
public Fields SortField { get; set; }
|
|
public bool SortAscending { get; set; }
|
|
public int Compare(IChannelCode left, IChannelCode right)
|
|
{
|
|
if (left == right)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
var a = left; var b = right;
|
|
|
|
if (string.IsNullOrWhiteSpace(a.Code) && string.IsNullOrWhiteSpace(a.Name))
|
|
{
|
|
return 1;
|
|
}
|
|
if (string.IsNullOrWhiteSpace(b.Code) && string.IsNullOrWhiteSpace(b.Name))
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if (!SortAscending) { a = right; b = left; }
|
|
if (null == a)
|
|
{
|
|
return -1;
|
|
}
|
|
if (null == b)
|
|
{
|
|
return 1;
|
|
}
|
|
switch (SortField)
|
|
{
|
|
case Fields.IsoCode:
|
|
case Fields.UserCode:
|
|
return DTS.Common.Utilities.NaturalStringComparer.StaticCompare(a.Code.ToUpper(), b.Code.ToUpper());
|
|
case Fields.IsoChannelName:
|
|
case Fields.UserChannelName:
|
|
return DTS.Common.Utilities.NaturalStringComparer.StaticCompare(a.Name.ToUpper(), b.Name.ToUpper());
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
}
|
|
}
|
|
private void SortIso(Fields field, bool bColumnClick)
|
|
{
|
|
if (bColumnClick)
|
|
{
|
|
if (field != _isoSortField)
|
|
{
|
|
_isoSortField = field;
|
|
_isoSortAscending = true;
|
|
}
|
|
else
|
|
{
|
|
_isoSortAscending = !_isoSortAscending;
|
|
}
|
|
}
|
|
var comparer = new ChannelComparer();
|
|
comparer.SortField = _isoSortField;
|
|
comparer.SortAscending = _isoSortAscending;
|
|
AllISOChannelCodes.Sort(comparer);
|
|
}
|
|
private void SortUser(Fields field, bool bColumnClick)
|
|
{
|
|
if (bColumnClick)
|
|
{
|
|
if (field != _userSortField)
|
|
{
|
|
_userSortField = field;
|
|
_userSortAscending = true;
|
|
}
|
|
else
|
|
{
|
|
_userSortAscending = !_userSortAscending;
|
|
}
|
|
}
|
|
var comparer = new ChannelComparer();
|
|
comparer.SortField = _userSortField;
|
|
comparer.SortAscending = _userSortAscending;
|
|
AllUserChannelCodes.Sort(comparer);
|
|
}
|
|
private void PasteUser(IChannelCode channelCode, string text, object tag)
|
|
{
|
|
bool bCode = tag.Equals("UserCode");
|
|
var channelCodes = ParseText(text, true, bCode, out var oneColumn);
|
|
int index = UserChannelCodes.IndexOf(channelCode);
|
|
|
|
foreach (var code in channelCodes)
|
|
{
|
|
if (index > (UserChannelCodes.Count - 1))
|
|
{
|
|
AllUserChannelCodes.Add(code);
|
|
index++;
|
|
}
|
|
else
|
|
{
|
|
var ch = UserChannelCodes[index++];
|
|
if (oneColumn)
|
|
{
|
|
ch.Code = bCode ? code.Code : ch.Code;
|
|
ch.Name = bCode ? ch.Name : code.Name;
|
|
}
|
|
else
|
|
{
|
|
ch.Code = code.Code;
|
|
ch.Name = code.Name;
|
|
}
|
|
}
|
|
}
|
|
|
|
SortUser(_userSortField, false);
|
|
FilterUser();
|
|
}
|
|
|
|
|
|
private IChannelCode[] ParseText(string text, bool bIso, bool bCode, out bool oneColumn)
|
|
{
|
|
oneColumn = false;
|
|
var list = new List<IChannelCode>();
|
|
var errors = new List<string>();
|
|
var lines = text.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
|
|
for (var i = 0; i < lines.Length; i++)
|
|
{
|
|
var line = lines[i];
|
|
if (string.IsNullOrWhiteSpace(line))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var tokens = line.Split(',');
|
|
if (tokens.Length != 2)
|
|
{
|
|
tokens = line.Split('\t');
|
|
}
|
|
if (tokens.Length != 2)
|
|
{
|
|
tokens = line.Split(';');
|
|
}
|
|
|
|
var newCode = new ChannelCode();
|
|
newCode.CodeType = bIso ? ChannelEnumsAndConstants.ChannelCodeType.ISO : ChannelEnumsAndConstants.ChannelCodeType.User;
|
|
if (tokens.Length == 1)
|
|
{
|
|
oneColumn = true;
|
|
if (bCode)
|
|
{
|
|
newCode.Code = tokens[0];
|
|
newCode.Name = "";
|
|
}
|
|
else
|
|
{
|
|
newCode.Name = tokens[0];
|
|
newCode.Code = "";
|
|
}
|
|
}
|
|
else if (tokens.Length == 2)
|
|
{
|
|
newCode.Code = tokens[0];
|
|
newCode.Name = tokens[1];
|
|
}
|
|
else
|
|
{
|
|
errors.Add(string.Format(Resources.StringResources.InvalidLine, 1 + i));
|
|
continue;
|
|
}
|
|
|
|
if (bIso)
|
|
{
|
|
if (newCode.Code.Length > 16)
|
|
{
|
|
newCode.Code = newCode.Code.Substring(0, 16);
|
|
}
|
|
}
|
|
list.Add(newCode);
|
|
}
|
|
|
|
return list.ToArray();
|
|
}
|
|
public void Remove(IChannelCode channel)
|
|
{
|
|
if (channel.CodeType == ChannelEnumsAndConstants.ChannelCodeType.ISO)
|
|
{
|
|
RemoveISOChannel(channel);
|
|
}
|
|
else
|
|
{
|
|
RemoveUserChannel(channel);
|
|
}
|
|
_eventAggregator.GetEvent<PageModifiedEvent>()
|
|
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page));
|
|
}
|
|
private void RemoveUserChannel(IChannelCode channel)
|
|
{
|
|
if (UserChannelCodes.ToList().Last() == channel)
|
|
{
|
|
var newCh = new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.User };
|
|
UserChannelCodes.Add(newCh);
|
|
AllUserChannelCodes.Add(newCh);
|
|
}
|
|
AllUserChannelCodes.Remove(channel);
|
|
UserChannelCodes.Remove(channel);
|
|
OnPropertyChanged("UserChannelCodes");
|
|
|
|
}
|
|
private void RemoveISOChannel(IChannelCode channel)
|
|
{
|
|
if (ISOChannelCodes.ToList().Last() == channel)
|
|
{
|
|
var newCh = new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.ISO };
|
|
AllISOChannelCodes.Add(newCh);
|
|
ISOChannelCodes.Add(newCh);
|
|
}
|
|
ISOChannelCodes.Remove(channel);
|
|
AllISOChannelCodes.Remove(channel);
|
|
OnPropertyChanged("ISOChannelCodes");
|
|
}
|
|
public void MarkModified(IChannelCode channel)
|
|
{
|
|
if (channel.CodeType == ChannelEnumsAndConstants.ChannelCodeType.ISO)
|
|
{
|
|
MarkModifiedISO(channel);
|
|
}
|
|
else
|
|
{
|
|
MarkModifiedUser(channel);
|
|
}
|
|
_eventAggregator.GetEvent<PageModifiedEvent>()
|
|
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page));
|
|
}
|
|
|
|
private void MarkModifiedISO(IChannelCode channel)
|
|
{
|
|
if (ISOChannelCodes.ToList().Last() == channel)
|
|
{
|
|
var newCh = new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.ISO };
|
|
ISOChannelCodes.Add(newCh);
|
|
AllISOChannelCodes.Add(newCh);
|
|
OnPropertyChanged("ISOChannelCodes");
|
|
}
|
|
}
|
|
private void MarkModifiedUser(IChannelCode channel)
|
|
{
|
|
if (UserChannelCodes.ToList().Last() == channel)
|
|
{
|
|
var newCh = new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.User };
|
|
UserChannelCodes.Add(newCh);
|
|
AllUserChannelCodes.Add(newCh);
|
|
OnPropertyChanged("UserChannelCodes");
|
|
}
|
|
}
|
|
public void Unset()
|
|
{
|
|
AllISOChannelCodes.Clear();
|
|
AllUserChannelCodes.Clear();
|
|
UserChannelCodes.Clear();
|
|
ISOChannelCodes.Clear();
|
|
OnPropertyChanged("UserChannelCodes");
|
|
OnPropertyChanged("ISOChannelCodes");
|
|
}
|
|
/// <summary>
|
|
/// sets the page this vm is in, this is used in some notifications to identify to consumers
|
|
/// which consumer should process the event
|
|
/// </summary>
|
|
/// <param name="page"></param>
|
|
public void SetPage(object page)
|
|
{
|
|
Page = page;
|
|
}
|
|
|
|
public void OnSetActive()
|
|
{
|
|
AllUserChannelCodes.Clear();
|
|
AllISOChannelCodes.Clear();
|
|
|
|
try
|
|
{
|
|
var lookup = ChannelCodeType.GetChannelCodeTypeLookup();
|
|
|
|
var existingChannelCodes = ChannelCode.GetExistingChannelCodes(lookup);
|
|
|
|
foreach (var existingChannelCode in existingChannelCodes)
|
|
{
|
|
if (existingChannelCode.CodeType == ChannelEnumsAndConstants.ChannelCodeType.ISO)
|
|
{
|
|
AllISOChannelCodes.Add(existingChannelCode);
|
|
}
|
|
else
|
|
{
|
|
AllUserChannelCodes.Add(existingChannelCode);
|
|
}
|
|
}
|
|
|
|
|
|
AllISOChannelCodes.Add(new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.ISO });
|
|
AllUserChannelCodes.Add(new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.User });
|
|
SortIso(_isoSortField, false);
|
|
SortUser(_userSortField, false);
|
|
FilterIso();
|
|
FilterUser();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log(ex);
|
|
ReportErrors(new[] { ex.Message });
|
|
}
|
|
}
|
|
|
|
public void Cleanup()
|
|
{
|
|
}
|
|
|
|
public Task CleanupAsync()
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public void Initialize()
|
|
{
|
|
}
|
|
|
|
public void Initialize(object parameter)
|
|
{
|
|
}
|
|
|
|
public void Initialize(object parameter, object model)
|
|
{
|
|
}
|
|
|
|
public Task InitializeAsync()
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task InitializeAsync(object parameter)
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public void Activated()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Private Event handler for RaiseNotification event.
|
|
/// </summary>
|
|
private void OnBusyIndicatorNotification(bool eventArg)
|
|
{
|
|
IsBusy = eventArg;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Private Event handler for RaiseNotification event.
|
|
/// </summary>
|
|
private void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)
|
|
{
|
|
// The NotificationRequest.Raise triggers the Invoke() method of the PopupWindowAction object to show the NotificationWindow window
|
|
// Notification object expects a NotificationContentEventArgsWithoutTitle object and a Title string.
|
|
var eventArgsWithoutTitle = new NotificationContentEventArgs(eventArgsWithTitle.Message, "",
|
|
eventArgsWithTitle.Image, string.Empty);
|
|
|
|
NotificationRequest.Raise(new Notification
|
|
{
|
|
Content = eventArgsWithoutTitle,
|
|
Title = eventArgsWithTitle.Title
|
|
});
|
|
}
|
|
|
|
public void ReportErrors(string[] errors)
|
|
{
|
|
_eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(errors, Page));
|
|
}
|
|
|
|
public bool Save()
|
|
{
|
|
try
|
|
{
|
|
//note we use multiple steps here to avoid name conflicts between existing/new/deleted channel codes
|
|
//step 1, delete any channels not needed anymore
|
|
var lookup = ChannelCodeType.GetChannelCodeTypeLookup();
|
|
var lookup2 = new Dictionary<ChannelEnumsAndConstants.ChannelCodeType, short>();
|
|
using (var e = lookup.GetEnumerator())
|
|
{
|
|
while (e.MoveNext())
|
|
{
|
|
switch (e.Current.Value)
|
|
{
|
|
case ChannelEnumsAndConstants.IsoCodeTypeString:
|
|
lookup2[ChannelEnumsAndConstants.ChannelCodeType.ISO] = e.Current.Key;
|
|
break;
|
|
case ChannelEnumsAndConstants.UserCodeTypeString:
|
|
lookup2[ChannelEnumsAndConstants.ChannelCodeType.User] = e.Current.Key;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
var channelCodes = new List<IChannelCode>();
|
|
channelCodes.AddRange(AllISOChannelCodes);
|
|
channelCodes.AddRange(AllUserChannelCodes);
|
|
var existingChannelCodes = ChannelCode.GetExistingChannelCodes(lookup);
|
|
var keptIds = new HashSet<int>();
|
|
foreach (var channelCode in channelCodes)
|
|
{
|
|
if (!(channelCode is ChannelCode cc)) { continue; }
|
|
|
|
if (cc.HasValidId())
|
|
{
|
|
keptIds.Add(cc.Id);
|
|
}
|
|
}
|
|
var toDelete = (from channelCode in existingChannelCodes where !keptIds.Contains(channelCode.Id) select channelCode).ToList();
|
|
if (toDelete.Any())
|
|
{
|
|
foreach (var cc in toDelete)
|
|
{
|
|
if (cc.HasValidId())
|
|
{
|
|
cc.Delete();
|
|
}
|
|
}
|
|
}
|
|
//step 2, update any existing new channels
|
|
|
|
foreach (var channelCode in channelCodes)
|
|
{
|
|
if (!(channelCode is ChannelCode cc)) { continue; }
|
|
if (cc.HasValidId())
|
|
{
|
|
cc.Save(lookup2);
|
|
}
|
|
}
|
|
//step 3, add new channels
|
|
foreach (var channelCode in channelCodes)
|
|
{
|
|
if (!(channelCode is ChannelCode cc))
|
|
{
|
|
continue;
|
|
}
|
|
if (!cc.HasValidId() && !cc.IsBlank())
|
|
{
|
|
cc.Insert(lookup2);
|
|
}
|
|
}
|
|
//step 4, update list ? not really necessary since we've updated the ids already in the insert function above.
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(new[] { ex.Message }, Page));
|
|
return false;
|
|
}
|
|
_eventAggregator.GetEvent<PageModifiedEvent>()
|
|
.Publish(new PageModifiedArg(PageModifiedArg.Status.Saved, Page));
|
|
return true;
|
|
}
|
|
#endregion
|
|
|
|
#region Properties
|
|
public List<IChannelCode> AllISOChannelCodes { get; set; } = new List<IChannelCode>();
|
|
public List<IChannelCode> AllUserChannelCodes { get; set; } = new List<IChannelCode>();
|
|
|
|
public ObservableCollection<IChannelCode> ISOChannelCodes { get; set; } =
|
|
new ObservableCollection<IChannelCode>();
|
|
|
|
public ObservableCollection<IChannelCode> UserChannelCodes { get; set; } =
|
|
new ObservableCollection<IChannelCode>();
|
|
|
|
private IReadOnlyDictionary<string, List<IChannelCode>> GetDictionary(IChannelCode[] channels)
|
|
{
|
|
var dictionary = new Dictionary<string, List<IChannelCode>>();
|
|
|
|
foreach (var channelCode in channels)
|
|
{
|
|
var code = channelCode.Code;
|
|
var name = channelCode.Name;
|
|
if (string.IsNullOrWhiteSpace(code) || string.IsNullOrWhiteSpace(name))
|
|
{
|
|
continue;
|
|
}
|
|
if (!dictionary.ContainsKey(code)) { dictionary[code] = new List<IChannelCode>(); }
|
|
dictionary[code].Add(channelCode);
|
|
}
|
|
return dictionary;
|
|
}
|
|
public void ValidateISO(ref List<string> errors, ref List<string> warnings)
|
|
{
|
|
var codeToChannels = GetDictionary(AllISOChannelCodes.ToArray());
|
|
if (!codeToChannels.Any()) return;
|
|
foreach (var channelCode in AllISOChannelCodes)
|
|
{
|
|
CheckChannelCode(ref errors, ref warnings, channelCode, true, codeToChannels);
|
|
}
|
|
}
|
|
public void ValidateUser(ref List<string> errors, ref List<string> warnings)
|
|
{
|
|
var codeToChannels = GetDictionary(AllUserChannelCodes.ToArray());
|
|
foreach (var channelCode in AllUserChannelCodes)
|
|
{
|
|
CheckChannelCode(ref errors, ref warnings, channelCode, false, codeToChannels);
|
|
}
|
|
}
|
|
public bool Validate(bool bDisplayWindow)
|
|
{
|
|
var errors = new List<string>();
|
|
var warnings = new List<string>();
|
|
|
|
ValidateISO(ref errors, ref warnings);
|
|
|
|
ValidateUser(ref errors, ref warnings);
|
|
if (bDisplayWindow && (errors.Any() || warnings.Any()))
|
|
{
|
|
var list = new List<string>(errors.ToArray());
|
|
list.AddRange(warnings.ToArray());
|
|
_eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(list.ToArray(), Page));
|
|
}
|
|
return 0 == errors.Count;
|
|
}
|
|
|
|
public void CopySelected()
|
|
{
|
|
switch (ViewMode)
|
|
{
|
|
case ViewModes.ISO:
|
|
CopySelectedISOCodes();
|
|
break;
|
|
case ViewModes.User:
|
|
CopySelectedUserCodes();
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
_eventAggregator.GetEvent<PageModifiedEvent>()
|
|
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page));
|
|
}
|
|
|
|
private void CopySelectedUserCodes()
|
|
{
|
|
if (null == _selectedUserItems) { return; }
|
|
|
|
foreach (var item in _selectedUserItems)
|
|
{
|
|
AllUserChannelCodes.Insert(AllUserChannelCodes.Count - 1, new ChannelCode(item));
|
|
}
|
|
SortUser(_userSortField, false);
|
|
FilterUser();
|
|
}
|
|
|
|
private void CopySelectedISOCodes()
|
|
{
|
|
if (null == _selectedISOItems) { return; }
|
|
|
|
foreach (var item in _selectedISOItems)
|
|
{
|
|
var newCh = new ChannelCode(item);
|
|
AllISOChannelCodes.Insert(AllISOChannelCodes.Count - 1, newCh);
|
|
}
|
|
SortIso(_isoSortField, false);
|
|
FilterIso();
|
|
}
|
|
|
|
public IChannelCode[] SelectedCodes
|
|
{
|
|
get
|
|
{
|
|
switch (ViewMode)
|
|
{
|
|
case ViewModes.ISO:
|
|
return GetSelectedISOCodes();
|
|
case ViewModes.User:
|
|
return GetSelectedUserCodes();
|
|
default:
|
|
throw new InvalidEnumArgumentException($"Unknown viewmode: SelectedCodes-{ViewMode}");
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
private IChannelCode[] GetSelectedISOCodes()
|
|
{
|
|
//FB 18906 Prevent exception when there is no selection
|
|
return _selectedISOItems?.ToArray();
|
|
}
|
|
|
|
private IChannelCode[] GetSelectedUserCodes()
|
|
{
|
|
return _selectedUserItems?.ToArray();
|
|
}
|
|
public void DeleteSelected()
|
|
{
|
|
switch (ViewMode)
|
|
{
|
|
case ViewModes.ISO:
|
|
DeleteSelectedISOCodes();
|
|
break;
|
|
case ViewModes.User:
|
|
DeleteSelectedUserCodes();
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
_eventAggregator.GetEvent<PageModifiedEvent>()
|
|
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page));
|
|
}
|
|
|
|
private void DeleteSelectedUserCodes()
|
|
{
|
|
if (null == _selectedUserItems) { return; }
|
|
bool bAddLast = false;
|
|
|
|
foreach (var code in _selectedUserItems)
|
|
{
|
|
if (UserChannelCodes.Last() == code)
|
|
{
|
|
bAddLast = true;
|
|
}
|
|
UserChannelCodes.Remove(code);
|
|
AllUserChannelCodes.Remove(code);
|
|
}
|
|
|
|
if (bAddLast)
|
|
{
|
|
var newCh = new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.User };
|
|
UserChannelCodes.Add(newCh);
|
|
AllUserChannelCodes.Add(newCh);
|
|
}
|
|
_selectedUserItems = null;
|
|
OnPropertyChanged("UserChannelCodes");
|
|
}
|
|
|
|
private void DeleteSelectedISOCodes()
|
|
{
|
|
if (null == _selectedISOItems) { return; }
|
|
bool bAddLast = false;
|
|
|
|
foreach (var code in _selectedISOItems)
|
|
{
|
|
if (ISOChannelCodes.Last() == code)
|
|
{
|
|
bAddLast = true;
|
|
}
|
|
ISOChannelCodes.Remove(code);
|
|
AllISOChannelCodes.Remove(code);
|
|
}
|
|
|
|
if (bAddLast)
|
|
{
|
|
var newCh = new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.ISO };
|
|
ISOChannelCodes.Add(newCh);
|
|
AllISOChannelCodes.Add(newCh);
|
|
}
|
|
_selectedISOItems = null;
|
|
OnPropertyChanged("ISOChannelCodes");
|
|
}
|
|
|
|
public void SetISOSelection(IChannelCode[] channelCodes)
|
|
{
|
|
//FB 18906 if the the list is empty, do not set _selectedISOItems
|
|
if (!channelCodes.Any())
|
|
{
|
|
return;
|
|
}
|
|
_selectedISOItems = channelCodes;
|
|
if (ViewMode == ViewModes.ISO)
|
|
{
|
|
var count = 0;
|
|
if (null != channelCodes)
|
|
{
|
|
count = channelCodes.Length;
|
|
}
|
|
NotifySelectionChanged(count);
|
|
}
|
|
}
|
|
|
|
private void NotifySelectionChanged(int count)
|
|
{
|
|
_eventAggregator.GetEvent<PageSelectionChanged>().Publish(new PageSelectionChangedArg(count, Page));
|
|
}
|
|
public void SetUserSelection(IChannelCode[] channelCodes)
|
|
{
|
|
//FB 18906 if the the list is empty, do not set _selectedISOItems
|
|
if (!channelCodes.Any())
|
|
{
|
|
return;
|
|
}
|
|
|
|
_selectedUserItems = channelCodes;
|
|
if (ViewMode == ViewModes.User)
|
|
{
|
|
var count = 0;
|
|
if (null != channelCodes)
|
|
{
|
|
count = channelCodes.Length;
|
|
}
|
|
NotifySelectionChanged(count);
|
|
}
|
|
}
|
|
private static void CheckChannelCode(ref List<string> errors,
|
|
ref List<string> warnings,
|
|
IChannelCode channelCode,
|
|
bool iso,
|
|
IReadOnlyDictionary<string, List<IChannelCode>> channelCodeToChannels)
|
|
{
|
|
var channelCodeEmpty = string.IsNullOrWhiteSpace(channelCode.Code);
|
|
var channelNameEmpty = string.IsNullOrWhiteSpace(channelCode.Name);
|
|
var itemStatus = UIItemStatus.None;
|
|
if (channelCodeEmpty && channelNameEmpty)
|
|
{
|
|
channelCode.ItemStatus = UIItemStatus.None;
|
|
return;
|
|
}
|
|
|
|
if (channelCodeEmpty)
|
|
{
|
|
var msg = iso ? Resources.StringResources.MissingISOCode : Resources.StringResources.MissingUserCode;
|
|
msg = string.Format(msg, channelCode.Name);
|
|
if (!errors.Contains(msg))
|
|
{
|
|
errors.Add(msg);
|
|
itemStatus = UIItemStatus.Error;
|
|
}
|
|
}
|
|
else if (channelNameEmpty)
|
|
{
|
|
var msg = iso
|
|
? Resources.StringResources.MissingISOChannelName
|
|
: Resources.StringResources.MissingUserChannelName;
|
|
msg = string.Format(msg, channelCode.Code);
|
|
if (!errors.Contains(msg))
|
|
{
|
|
itemStatus = UIItemStatus.Error;
|
|
errors.Add(msg);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var list = channelCodeToChannels[channelCode.Code];
|
|
if (list.Count > 1)
|
|
{
|
|
//either duplicated code or duplicated everything
|
|
var matches = from ch in list where ch.Name == channelCode.Name && ch != channelCode select ch;
|
|
if (matches.Any())
|
|
{
|
|
var msg = iso ? Resources.StringResources.DuplicateISOChannelCode : Resources.StringResources.DuplicateUserChannelCode;
|
|
if (!string.IsNullOrWhiteSpace(channelCode.Name))
|
|
{
|
|
msg = string.Format(msg, channelCode.Name);
|
|
}
|
|
else
|
|
{
|
|
msg = string.Format(msg, channelCode.Code);
|
|
}
|
|
if (!errors.Contains(msg)) { errors.Add(msg); }
|
|
itemStatus = UIItemStatus.Error;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
channelCode.ItemStatus = itemStatus;
|
|
}
|
|
|
|
public void Filter(object columnTag, string searchTerm)
|
|
{
|
|
if (!(columnTag is string s))
|
|
{
|
|
return;
|
|
}
|
|
switch (s)
|
|
{
|
|
case "ISOCode":
|
|
_searchTermForField[Fields.IsoCode] = searchTerm;
|
|
FilterIso();
|
|
break;
|
|
case "ISOChannelName":
|
|
_searchTermForField[Fields.IsoChannelName] = searchTerm;
|
|
FilterIso();
|
|
break;
|
|
case "UserCode":
|
|
_searchTermForField[Fields.UserCode] = searchTerm;
|
|
FilterUser();
|
|
break;
|
|
case "UserChannelName":
|
|
_searchTermForField[Fields.UserChannelName] = searchTerm;
|
|
FilterUser();
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void Sort(object columnTag, bool bColumnClick)
|
|
{
|
|
if (!(columnTag is string s)) { return; }
|
|
switch (s)
|
|
{
|
|
case "ISOCode":
|
|
SortIso(Fields.IsoCode, true);
|
|
FilterIso();
|
|
break;
|
|
case "ISOChannelName":
|
|
SortIso(Fields.IsoChannelName, true);
|
|
FilterIso();
|
|
break;
|
|
case "UserCode":
|
|
SortUser(Fields.UserCode, true);
|
|
FilterUser();
|
|
break;
|
|
case "UserChannelName":
|
|
SortUser(Fields.UserChannelName, true);
|
|
FilterUser();
|
|
break;
|
|
}
|
|
}
|
|
public enum Fields
|
|
{
|
|
IsoCode,
|
|
IsoChannelName,
|
|
UserCode,
|
|
UserChannelName
|
|
}
|
|
private Fields _isoSortField = Fields.IsoCode;
|
|
private bool _isoSortAscending = true;
|
|
private Fields _userSortField = Fields.UserCode;
|
|
private bool _userSortAscending = true;
|
|
private readonly Dictionary<Fields, string> _searchTermForField = new Dictionary<Fields, string>();
|
|
|
|
private IChannelCode[] _selectedISOItems = null;
|
|
private IChannelCode[] _selectedUserItems = null;
|
|
public object Page { get; private set; }
|
|
public bool IsDirty { get; private set; }
|
|
private bool _isBusy = false;
|
|
public bool IsBusy
|
|
{
|
|
get => _isBusy;
|
|
set
|
|
{
|
|
_isBusy = value;
|
|
OnPropertyChanged("IsBusy");
|
|
}
|
|
}
|
|
|
|
private bool _isMenuIncluded;
|
|
public bool IsMenuIncluded
|
|
{
|
|
get => _isMenuIncluded;
|
|
set
|
|
{
|
|
_isMenuIncluded = value;
|
|
OnPropertyChanged("IsMenuIncluded");
|
|
}
|
|
}
|
|
|
|
private bool _isNavigationIncluded;
|
|
public bool IsNavigationIncluded
|
|
{
|
|
get => _isNavigationIncluded;
|
|
set
|
|
{
|
|
_isNavigationIncluded = value;
|
|
OnPropertyChanged("IsNavigationIncluded");
|
|
}
|
|
}
|
|
|
|
//FB14098: Ability to disable editing View if user doesn't have the permissions, but still view current data
|
|
private bool _isReadOnly;
|
|
public bool IsReadOnly
|
|
{
|
|
get => _isReadOnly;
|
|
set
|
|
{
|
|
_isReadOnly = value;
|
|
OnPropertyChanged("IsReadOnly");
|
|
}
|
|
}
|
|
#endregion Properties
|
|
|
|
public enum ViewModes
|
|
{
|
|
ISO,
|
|
User
|
|
}
|
|
|
|
private ViewModes _viewMode = ViewModes.ISO;
|
|
|
|
public ViewModes ViewMode
|
|
{
|
|
get => _viewMode;
|
|
set
|
|
{
|
|
_viewMode = value;
|
|
OnPropertyChanged("ISOVisibility");
|
|
OnPropertyChanged("UserVisibility");
|
|
var count = 0;
|
|
switch (value)
|
|
{
|
|
case ViewModes.ISO:
|
|
if (null != _selectedISOItems) { count = _selectedISOItems.Length; }
|
|
NotifySelectionChanged(count);
|
|
break;
|
|
case ViewModes.User:
|
|
if (null != _selectedUserItems) { count = _selectedUserItems.Length; }
|
|
NotifySelectionChanged(count);
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
|
}
|
|
}
|
|
}
|
|
|
|
public Visibility ISOVisibility => ViewMode == ViewModes.ISO ? Visibility.Visible : Visibility.Collapsed;
|
|
|
|
public Visibility UserVisibility => ViewMode == ViewModes.User ? Visibility.Visible : Visibility.Collapsed;
|
|
|
|
private IList<IChannelCode> GetAllChannels()
|
|
{
|
|
return ChannelCode.ChannelCodes;
|
|
}
|
|
|
|
public Func<IList<IChannelCode>> ChannelCodesFunc { get; }
|
|
|
|
private bool _showISOStringBuilder = true;
|
|
public bool ShowISOStringBuilder
|
|
{
|
|
get => _showISOStringBuilder;
|
|
set
|
|
{
|
|
_showISOStringBuilder = value;
|
|
OnPropertyChanged("ShowISOStringBuilder");
|
|
}
|
|
}
|
|
|
|
private bool _uniqueISOCodesRequired;
|
|
|
|
public bool UniqueISOCodesRequired
|
|
{
|
|
get => _uniqueISOCodesRequired;
|
|
set
|
|
{
|
|
_uniqueISOCodesRequired = value;
|
|
OnPropertyChanged("UniqueISOCodesRequired");
|
|
}
|
|
}
|
|
|
|
private bool _showChannelCodeLookupHelper = true;
|
|
public bool ShowChannelCodeLookupHelper
|
|
{
|
|
get => _showChannelCodeLookupHelper;
|
|
set
|
|
{
|
|
_showChannelCodeLookupHelper = value;
|
|
OnPropertyChanged("ShowChannelCodeLookupHelper");
|
|
}
|
|
}
|
|
#region Commands
|
|
|
|
#endregion
|
|
}
|
|
}
|