using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.Mobile; using Xamarin.Forms; using Xamarin.Forms.Xaml; using XF.Material.Forms.UI.Dialogs; namespace PRS.Mobile { public class ExistingFormStatusConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is IDigitalFormInstanceShell shell) { return !shell.Completed.IsEmpty() ? $"{shell.Completed:dd MMMM yy}" : !shell.Started.IsEmpty() ? $"{shell.Started:dd MMMM yy}" : $"{shell.Created:dd MMMM yy}"; } return ""; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } public class ExistingFormBackgroundColorConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is IDigitalFormInstanceShell shell) { return !shell.Completed.IsEmpty() ? Color.DimGray : !shell.Started.IsEmpty() ? Color.LightGreen : Color.Coral; } return Color.Transparent; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } public class ExistingFormForegroundColorConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is IDigitalFormInstanceShell shell) { return !shell.Completed.IsEmpty() ? Color.WhiteSmoke : !shell.Started.IsEmpty() ? Color.Black : Color.Black; } return Color.Transparent; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } public class ExistingFormRefreshEventArgs : CancelEventArgs { } public delegate void ExistingFormRefreshEvent(object sender, ExistingFormRefreshEventArgs args); public class ExistingFormSearchEventArgs : EventArgs { public IDigitalFormInstanceShell Shell { get; private set; } public ExistingFormSearchEventArgs(IDigitalFormInstanceShell shell) { Shell = shell; } } public delegate bool ExistingFormSearchEvent(object sender, ExistingFormSearchEventArgs args); public class ExistingFormTappedEventArgs : EventArgs { public IDigitalFormInstanceShell Shell { get; private set; } public ExistingFormTappedEventArgs(IDigitalFormInstanceShell shell) { Shell = shell; } } public delegate void ExistingFormTappedEvent(object sender, ExistingFormTappedEventArgs args); [XamlCompilation(XamlCompilationOptions.Compile)] public partial class ExistingForms { private String _currentfilter = ""; public ICoreRepository DataModel { get => _model.DataModel; set => _model.DataModel = value; } public String AppliesTo { get => _model.AppliesTo; set => _model.AppliesTo = value; } public Func Property { get => _model.Property; set => _model.Property = value; } public bool SeparateHistory { get => _model.SeparateHistory; set => _model.SeparateHistory = value; } public bool PullToRefresh { get => _model.PullToRefresh; set => _model.PullToRefresh = value; } public event ExistingFormRefreshEvent RefreshRequested; public event ExistingFormSearchEvent Search; public event ExistingFormTappedEvent FormTapped; // Event to handle new / existing form selection public ExistingForms() { InitializeComponent(); } public void RefreshData(bool force, bool async) { if (async) DataModel?.Refresh(force, Refresh); else { DataModel?.Refresh(force); Refresh(); } } public void Refresh() { var forms = Property(DataModel); Device.BeginInvokeOnMainThread(() => { _forms.LastUpdated = DataModel?.LastUpdated ?? DateTime.MinValue; _forms.ItemsSource = forms? .Where(FilterShell) .OrderByDescending(SortShell) .ToList(); }); } private DateTime SortShell(IDigitalFormInstanceShell shell) { return !shell.Completed.IsEmpty() ? shell.Completed : !shell.Started.IsEmpty() ? shell.Started : shell.Created; } private bool _showincomplete = true; private bool FilterShell(IDigitalFormInstanceShell shell) { if (_model.SeparateHistory) { bool shellincomplete = shell.Completed.IsEmpty(); if (shellincomplete != _showincomplete) return false; } bool bOK = String.IsNullOrWhiteSpace(_currentfilter) || (shell.FormCode.ToUpper().Contains(_currentfilter.ToUpper()) || shell.FormDescription.ToUpper().Contains(_currentfilter.ToUpper())); bOK = bOK && (Search?.Invoke(this, new ExistingFormSearchEventArgs(shell)) ?? true); return bOK; } private void _search_OnTextChanged(object sender, MobileSearchBarTextChangedArgs args) { _currentfilter = args.Text; Refresh(); } private void _digitalforms_OnRefresh(object sender, MobileListRefreshEventArgs args) { var newargs = new ExistingFormRefreshEventArgs() { Cancel = false }; RefreshRequested?.Invoke(this, newargs); if (!newargs.Cancel) RefreshData(true,false); } private void AddForm_Tapped(object sender, EventArgs e) { var selector = new NewForms() { AppliesTo = this.AppliesTo }; selector.ItemSelected += CreateNewForm; Navigation.PushAsync(selector); } private async void CreateNewForm(object sender, NewFormSelectedArgs args) { await MaterialDialog.Instance.AlertAsync("Not Implemented Yet!"); return; } private async void Form_Clicked(object sender, EventArgs e) { if ((sender is MobileCard card) && (card.BindingContext is IDigitalFormInstanceShell shell)) FormTapped?.Invoke(this, new ExistingFormTappedEventArgs(shell)); else await MaterialDialog.Instance.AlertAsync("Tapped Item is not a Digital Form", "ERROR"); } public void CreateNewForm(String appliesto, Func createform, Guid parentid, Action refresh) { var selector = new NewForms() { AppliesTo = appliesto }; selector.ItemSelected += (sender, args) => { var instance = createform(); instance.ParentID = parentid; instance.FormID = args.Form.ID; instance.FormCode = args.Form.Code; instance.FormDescription = args.Form.Description; instance.Save("Created on Mobile Device"); Dispatcher.BeginInvokeOnMainThread(refresh); }; Navigation.PushAsync(selector); } public void EditForm(IDigitalFormInstanceShell shell, TParent parent) where TParent : Entity, IRemotable, IPersistent, new() where TParentLink : EntityLink, new() where TForm : Entity, IRemotable, IPersistent, IDigitalFormInstance, new() { var table = new Client().Query( new Filter(x => x.ID).IsEqualTo(shell.ID), new Columns(ColumnTypeFlags.None).Add(x=>x.ID).Add(x=>x.Form.ID) ); var form = table.Rows .Select(x => x.ToObject()) .FirstOrDefault(); var model = new DigitalFormHostModel(); model.LoadItems( parent, form.Form.ID, form.ID, null); var host = new DigitalFormHost(model); host.OnClosing += (o, args) => { if (args.Changed) { RefreshData(true,true); //instance.Completed = !model.DigitalFormDataModel.Instance.FormCompleted.IsEmpty(); } }; Navigation.PushAsync(host); } public async void EditFormAsync(IDigitalFormInstanceShell shell, TParent parent) where TParent : Entity, IRemotable, IPersistent, new() where TParentLink : EntityLink, new() where TForm : Entity, IRemotable, IPersistent, IDigitalFormInstance, new() { using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading")) { var form = new Client() .Query( new Filter(x => x.ID).IsEqualTo(shell.ID), new Columns(ColumnTypeFlags.None).Add(x=>x.ID).Add(x=>x.Form.ID) ) .Rows .Select(x => x.ToObject()) .FirstOrDefault(); var model = new DigitalFormHostModel(); model.LoadItems(parent, form.Form.ID, form.ID, null); var host = new DigitalFormHost(model); host.OnClosing += (o, args) => { if (args.Changed) { RefreshData(true,true); //instance.Completed = !model.DigitalFormDataModel.Instance.FormCompleted.IsEmpty(); } }; Navigation.PushAsync(host); } } private void _tabStrip_OnSelectionChanged(object sender, EventArgs e) { _showincomplete = _tabStrip.SelectedItem?.Index == 0; _model.DataModel.SelectNone(); _selectionmenubutton.IsVisible = false; Refresh(); } private void _selectionmenu_OnAppearing(object sender, EventArgs e) { _completeform.IsVisible = _showincomplete; _reopenform.IsVisible = !_showincomplete; //bool anyselected = SelectedItems().Any(); //bool anyunselected = UnselectedItems().Any(); //_setstatus.IsVisible = anyselected; //_selectAll.IsVisible = anyunselected; //_selectNone.IsVisible = anyselected; //_separator.IsVisible = (_setstatus.IsVisible) && (_selectAll.IsVisible || _selectNone.IsVisible); } private IEnumerable SelectedItems() { return _model.DataModel.SelectedItems.OfType(); } private IEnumerable UnselectedItems() { return _model.DataModel.Items.OfType().Except(_model.DataModel.SelectedItems.OfType()); } private void _setstatus_OnClicked(object sender, EventArgs e) { } private void _selectAll_OnClicked(object sender, EventArgs e) { _model.DataModel.SelectAll(); RefreshData(false,false); } private void _selectNone_OnClicked(object sender, EventArgs e) { _model.DataModel.SelectNone(); RefreshData(false,false); } private void CheckBox_Changed(object sender, EventArgs e) { if ((sender as MobileCheckBox)?.BindingContext is IShell shell) _model.DataModel.ToggleSelection(shell); _selectionmenubutton.IsVisible = SelectedItems().Any(); } private void _completeform_OnClicked(object sender, EventArgs e) { var shells = _model.DataModel.SelectedItems.OfType().ToArray(); foreach (var shell in shells) { shell.Completed = DateTime.Now; shell.Save("Completed on Mobile Device"); } _model.DataModel.SelectNone(); _selectionmenubutton.IsVisible = false; RefreshData(true,false); } private void _reopenform_OnClicked(object sender, EventArgs e) { var shells = _model.DataModel.SelectedItems.OfType().ToArray(); foreach (var shell in shells) { shell.Completed = DateTime.MinValue; shell.Save("Re-Opened on Mobile Device"); } _model.DataModel.SelectNone(); _selectionmenubutton.IsVisible = false; RefreshData(true,false); } } }