| 
					
				 | 
			
			
				@@ -12,8 +12,10 @@ using InABox.Configuration; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using InABox.Core; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using InABox.Mobile.Shared; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using JetBrains.Annotations; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using Syncfusion.SfDataGrid.XForms; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using Xamarin.CommunityToolkit.ObjectModel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using Xamarin.Forms; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using Columns = InABox.Core.Columns; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 namespace InABox.Mobile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -30,14 +32,31 @@ namespace InABox.Mobile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public delegate void CoreRepositoryItemCreatedEvent<TShell>(object sender, CoreRepositoryItemCreatedArgs<TShell> args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public class CoreRepository 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public abstract class CoreRepository 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public static string CacheFileName<T>() => typeof(T).EntityName().Split('.').Last(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public static string CacheFileName<T>(string postfix) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var result = CacheFileName<T>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!string.IsNullOrWhiteSpace(postfix)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                result = $"{result}_{postfix}"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        [CanBeNull] public abstract string FileName(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public bool IsCached() => CoreRepository.IsCached(FileName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public static bool IsCached(string filename) =>  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             !String.IsNullOrWhiteSpace(filename)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             && File.Exists(CacheFileName(filename)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				          
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public static string CacheFileName(string filename) => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Path.Combine(CacheFolder(), filename); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Path.Combine(CacheFolder(), $"{filename}.cache"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public static string CacheFolder() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -68,10 +87,9 @@ namespace InABox.Mobile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				          
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public DateTime LastUpdated { get; protected set; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				          
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        public String FileName { get; set; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        [CanBeNull] private Func<string> _cacheFileName { get; set; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				          
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        protected CoreRepository(IModelHost host, Func<Filter<TEntity>> filter) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        protected CoreRepository(IModelHost host, [CanBeNull] Func<Filter<TEntity>> filter = null, [CanBeNull] Func<string> cachefilename = null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             AllItems = new ObservableRangeCollection<TItem>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             AllItems.CollectionChanged += (sender, args) => ItemsChanged(AllItems); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -86,8 +104,12 @@ namespace InABox.Mobile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             Reset(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             Host = host; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             Filter = filter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _cacheFileName = cachefilename; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        [CanBeNull] public override string FileName() => _cacheFileName?.Invoke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         protected virtual void ItemsChanged(IEnumerable<TItem> items) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -152,9 +174,15 @@ namespace InABox.Mobile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				          
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public CoreFilterDefinitions AvailableFilters() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return string.IsNullOrWhiteSpace(FilterTag) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ? new CoreFilterDefinitions() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                : new GlobalConfiguration<CoreFilterDefinitions>(FilterTag).Load(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var result = new CoreFilterDefinitions(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!string.IsNullOrWhiteSpace(FilterTag)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var mobile = new GlobalConfiguration<CoreFilterDefinitions>(FilterTag) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .Load() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .Where(x => x.Visibility == CoreFilterDefinitionVisibility.DesktopAndMobile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                result.AddRange(mobile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         protected Filter<TEntity> SelectedFilter; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -200,7 +228,7 @@ namespace InABox.Mobile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             Items.Clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             SelectedItems.Clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!Loaded && CoreRepository.IsCached(FileName)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!Loaded && IsCached(FileName())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 DoBeforeLoad(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (LoadFromStorage()) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -505,13 +533,14 @@ namespace InABox.Mobile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				          
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         protected bool LoadFromStorage() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (String.IsNullOrWhiteSpace(FileName)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (String.IsNullOrWhiteSpace(FileName())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 InitializeTables(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				              
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var file = CacheFileName(FileName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var file = CacheFileName(FileName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (File.Exists(file)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 LastUpdated = File.GetLastWriteTime(file); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -551,7 +580,7 @@ namespace InABox.Mobile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         protected void SaveToStorage() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (String.IsNullOrWhiteSpace(FileName)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (String.IsNullOrWhiteSpace(FileName())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				              
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             QueryStorage storage = new QueryStorage(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -561,8 +590,9 @@ namespace InABox.Mobile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var data = storage.WriteBinary(BinarySerializationSettings.Latest); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var file = CacheFileName(FileName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                File.WriteAllBytes(file,data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var file = $"{CacheFileName(FileName())}"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (!string.IsNullOrWhiteSpace(file)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    File.WriteAllBytes(file,data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             catch (Exception e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 |