|  | @@ -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)
 | 
	
		
			
				|  |  |              {
 |