only show top level groupings on main vault page

This commit is contained in:
Kyle Spearrin 2018-12-05 17:26:16 -05:00
parent c0eb84b7b1
commit 5cc1e2bb29
4 changed files with 41 additions and 26 deletions

View file

@ -24,7 +24,7 @@ namespace Bit.App.Controls
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)), FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
HorizontalOptions = LayoutOptions.StartAndExpand HorizontalOptions = LayoutOptions.StartAndExpand
}; };
Label.SetBinding(Label.TextProperty, string.Format("{0}.{1}", Label.SetBinding(Label.TextProperty, string.Format("{0}.Node.{1}",
nameof(VaultListPageModel.GroupingOrCipher.Grouping), nameof(VaultListPageModel.Grouping.Name))); nameof(VaultListPageModel.GroupingOrCipher.Grouping), nameof(VaultListPageModel.Grouping.Name)));
CountLabel = new Label CountLabel = new Label
@ -34,7 +34,7 @@ namespace Bit.App.Controls
Style = (Style)Application.Current.Resources["text-muted"], Style = (Style)Application.Current.Resources["text-muted"],
HorizontalOptions = LayoutOptions.End HorizontalOptions = LayoutOptions.End
}; };
CountLabel.SetBinding(Label.TextProperty, string.Format("{0}.{1}", CountLabel.SetBinding(Label.TextProperty, string.Format("{0}.Node.{1}",
nameof(VaultListPageModel.GroupingOrCipher.Grouping), nameof(VaultListPageModel.Grouping.Count))); nameof(VaultListPageModel.GroupingOrCipher.Grouping), nameof(VaultListPageModel.Grouping.Count)));
var stackLayout = new StackLayout var stackLayout = new StackLayout
@ -62,8 +62,8 @@ namespace Bit.App.Controls
{ {
if(BindingContext is VaultListPageModel.GroupingOrCipher model) if(BindingContext is VaultListPageModel.GroupingOrCipher model)
{ {
Icon.Source = model.Grouping.Folder ? Icon.Source = model.Grouping.Node.Folder ?
$"folder{(model.Grouping.Id == null ? "_o" : string.Empty)}.png" : "cube.png"; $"folder{(model.Grouping.Node.Id == null ? "_o" : string.Empty)}.png" : "cube.png";
} }
base.OnBindingContextChanged(); base.OnBindingContextChanged();

View file

@ -191,7 +191,7 @@ namespace Bit.App.Models.Page
public class GroupingOrCipher public class GroupingOrCipher
{ {
public GroupingOrCipher(Grouping grouping) public GroupingOrCipher(TreeNode<Grouping> grouping)
{ {
Grouping = grouping; Grouping = grouping;
Cipher = null; Cipher = null;
@ -203,11 +203,11 @@ namespace Bit.App.Models.Page
Grouping = null; Grouping = null;
} }
public Grouping Grouping { get; set; } public TreeNode<Grouping> Grouping { get; set; }
public Cipher Cipher { get; set; } public Cipher Cipher { get; set; }
} }
public class Grouping public class Grouping : ITreeNodeObject
{ {
public Grouping(string name, int count) public Grouping(string name, int count)
{ {

View file

@ -235,15 +235,18 @@ namespace Bit.App.Pages
var folders = await _folderService.GetAllAsync(); var folders = await _folderService.GetAllAsync();
var collections = await _collectionService.GetAllAsync(); var collections = await _collectionService.GetAllAsync();
var folderGroupings = folders var fGroupings = folders
.Select(f => new GroupingOrCipher( .Select(f => new Grouping(f, folderCounts.ContainsKey(f.Id) ? folderCounts[f.Id] : 0))
new Grouping(f, folderCounts.ContainsKey(f.Id) ? folderCounts[f.Id] : 0))) .OrderBy(g => g.Name);
.OrderBy(g => g.Grouping.Name).ToList(); var folderGroupings = Helpers.GetAllNested(fGroupings)
.Select(n => new GroupingOrCipher(n)).ToList();
if(collections.Any() || noFolderCipherGroupings.Count >= 100) if(collections.Any() || noFolderCipherGroupings.Count >= 100)
{ {
folderGroupings.Add(new GroupingOrCipher(new Grouping(AppResources.FolderNone, var noneFolderGrouping = new Grouping(AppResources.FolderNone, noFolderCipherGroupings.Count);
noFolderCipherGroupings.Count))); var noneFolderNode = new Bit.App.Models.TreeNode<Grouping>(noneFolderGrouping,
noneFolderGrouping.Name, null);
folderGroupings.Add(new GroupingOrCipher(noneFolderNode));
} }
if(folderGroupings.Any()) if(folderGroupings.Any())
@ -251,10 +254,12 @@ namespace Bit.App.Pages
sections.Add(new Section<GroupingOrCipher>(folderGroupings, AppResources.Folders)); sections.Add(new Section<GroupingOrCipher>(folderGroupings, AppResources.Folders));
} }
var collectionGroupings = collections.Select(c => var cGroupings = collections
new GroupingOrCipher(new Grouping( .Select(c => new Grouping(c, collectionsDict.ContainsKey(c.Id) ? collectionsDict[c.Id].Count() : 0))
c, collectionsDict.ContainsKey(c.Id) ? collectionsDict[c.Id].Count() : 0))) .OrderBy(g => g.Name);
.OrderBy(g => g.Grouping.Name).ToList(); var collectionGroupings = Helpers.GetAllNested(cGroupings)
.Select(n => new GroupingOrCipher(n)).ToList();
if(collectionGroupings.Any()) if(collectionGroupings.Any())
{ {
sections.Add(new Section<GroupingOrCipher>(collectionGroupings, AppResources.Collections)); sections.Add(new Section<GroupingOrCipher>(collectionGroupings, AppResources.Collections));
@ -299,15 +304,15 @@ namespace Bit.App.Pages
if(groupingOrCipher.Grouping != null) if(groupingOrCipher.Grouping != null)
{ {
Page page; Page page;
if(groupingOrCipher.Grouping.Folder) if(groupingOrCipher.Grouping.Node.Folder)
{ {
page = new VaultListCiphersPage(folder: true, page = new VaultListCiphersPage(folder: true,
folderId: groupingOrCipher.Grouping.Id, groupingName: groupingOrCipher.Grouping.Name); folderId: groupingOrCipher.Grouping.Node.Id, groupingName: groupingOrCipher.Grouping.Node.Name);
} }
else else
{ {
page = new VaultListCiphersPage(collectionId: groupingOrCipher.Grouping.Id, page = new VaultListCiphersPage(collectionId: groupingOrCipher.Grouping.Node.Id,
groupingName: groupingOrCipher.Grouping.Name); groupingName: groupingOrCipher.Grouping.Node.Name);
} }
await Navigation.PushAsync(page); await Navigation.PushAsync(page);

View file

@ -570,8 +570,8 @@ namespace Bit.App.Utilities
return appSettingsService?.OrganizationGivesPremium ?? false; return appSettingsService?.OrganizationGivesPremium ?? false;
} }
public static void NestedTraverse(List<TreeNode<ITreeNodeObject>> nodeTree, int partIndex, string[] parts, public static void NestedTraverse<T>(List<TreeNode<T>> nodeTree, int partIndex, string[] parts,
ITreeNodeObject obj, ITreeNodeObject parent, string delimiter) T obj, T parent, string delimiter) where T : ITreeNodeObject
{ {
if(parts.Length <= partIndex) if(parts.Length <= partIndex)
{ {
@ -590,7 +590,7 @@ namespace Bit.App.Utilities
if(end && n.Node.Id != obj.Id) if(end && n.Node.Id != obj.Id)
{ {
// Another node with the same name. // Another node with the same name.
nodeTree.Add(new TreeNode<ITreeNodeObject>(obj, partName, parent)); nodeTree.Add(new TreeNode<T>(obj, partName, parent));
return; return;
} }
NestedTraverse(n.Children, partIndex + 1, parts, obj, n.Node, delimiter); NestedTraverse(n.Children, partIndex + 1, parts, obj, n.Node, delimiter);
@ -601,7 +601,7 @@ namespace Bit.App.Utilities
{ {
if(end) if(end)
{ {
nodeTree.Add(new TreeNode<ITreeNodeObject>(obj, partName, parent)); nodeTree.Add(new TreeNode<T>(obj, partName, parent));
return; return;
} }
var newPartName = string.Concat(parts[partIndex], delimiter, parts[partIndex + 1]); var newPartName = string.Concat(parts[partIndex], delimiter, parts[partIndex + 1]);
@ -612,7 +612,7 @@ namespace Bit.App.Utilities
} }
} }
public static TreeNode<ITreeNodeObject> GetTreeNodeObject(List<TreeNode<ITreeNodeObject>> nodeTree, string id) public static TreeNode<T> GetTreeNodeObject<T>(List<TreeNode<T>> nodeTree, string id) where T : ITreeNodeObject
{ {
foreach(var n in nodeTree) foreach(var n in nodeTree)
{ {
@ -631,5 +631,15 @@ namespace Bit.App.Utilities
} }
return null; return null;
} }
public static List<TreeNode<T>> GetAllNested<T>(IEnumerable<T> objs) where T : ITreeNodeObject
{
var nodes = new List<TreeNode<T>>();
foreach(var o in objs)
{
NestedTraverse(nodes, 0, o.Name.Split('/'), o, default(T), "/");
}
return nodes;
}
} }
} }