1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-15 15:53:27 +00:00

[EC-14] Refactor vault filter (#3440)

* [EC-14] initial refactoring of vault filter

* [EC-14] return observable trees for all filters with head node

* [EC-14] Remove bindings on callbacks

* [EC-14] fix formatting on disabled orgs

* [EC-14] hide MyVault if personal org policy

* [EC-14] add check for single org policy

* [EC-14] add policies to org and change node constructor

* [EC-14] don't show options if personal vault policy

* [EC-14] default to all vaults

* [EC-14] add default selection to filters

* [EC-14] finish filter model callbacks

* [EC-14] finish filter functionality and begin cleaning up

* [EC-14] clean up old components and start on org vault

* [EC-14] loop through filters for presentation

* [EC-14] refactor VaultFilterService and put filter presentation data back into Vault Filter component. Remove VaultService

* [EC-14] begin refactoring org vault

* [EC-14] Refactor Vault Filter Service to use observables

* [EC-14] finish org vault filter

* [EC-14] fix vault model tests

* [EC-14] fix org service calls

* [EC-14] pull refactor out of shared code

* [EC-14] include head node for collections even if collections aren't loaded yet

* [EC-14] fix url params for vaults

* [EC-14] remove comments

* [EC-14] Remove unnecesary getter for org on vault filter

* [EC-14] fix linter

* [EC-14] fix prettier

* [EC-14] add deprecated methods to collection service for desktop and browser

* [EC-14] simplify cipher type node check

* [EC-14] add getters to vault filter model

* [EC-14] refactor how we build the filter list into methods

* [EC-14] add getters to build filter method

* [EC-14] remove param ids if false

* [EC-14] fix collapsing nodes

* [EC-14] add specific type to search placeholder

* [EC-14] remove extra constructor and comment from org vault filter

* [EC-14] extract subscription callback to methods

* [EC-14] Remove unecessary await

* [EC-14] Remove ternary operators while building org filter

* [EC-14] remove unnecessary deps array in vault filter service declaration

* [EC-14] consolidate new models into one file

* [EC-14] initialize nested observable inside of service

Signed-off-by: Jacob Fink <jfink@bitwarden.com>

* [EC-14] change how we load orgs into the vault filter and select the default filter

* [EC-14] remove get from getters name

* [EC-14] remove eslint-disable comment

* [EC-14] move vault filter service abstraction to angular folder and separate

* [EC-14] rename filter types and delete VaultFilterLabel

* [EC-14] remove changes to workspace file

* [EC-14] remove deprecated service from jslib module

* [EC-14] remove any remaining files from common code

* [EC-14] consolidate vault filter components into components folder

* [EC-14] simplify method call

* [EC-14] refactor the vault filter service
- orgs now have observable property
- BehaviorSubjects have been migrated to ReplaySubjects if they don't need starting value
- added unit tests
- fix small error when selecting org badge of personal vault
- renamed some properties

* [EC-14] replace mergeMap with switchMap in vault filter service

* [EC-14] early return to prevent nesting

* [EC-14] clean up filterCollections method

* [EC-14] use isDeleted helper in html

* [EC-14] add jsdoc comments to ServiceUtils

* [EC-14] fix linter

* [EC-14] use array.slice instead of setting length

* Update apps/web/src/app/vault/vault-filter/services/vault-filter.service.ts

Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>

* [EC-14] add missing high level jsdoc description

* [EC-14] fix storybook absolute imports

* [EC-14] delete vault-shared.module

* [EC-14] change search placeholder text to getter and add missing strings

* [EC-14] remove two way binding from search text in vault filter

* [EC-14] removed all binding from search text and just use input event

* [EC-14] remove async from apply vault filter

* [EC-14] remove circular observable calls in vault filter service

Co-authored-by: Thomas Rittson <eliykat@users.noreply.github.com>

* [EC-14] move collapsed nodes to vault filter section

* [EC-14] deconstruct filter section inside component

* [EC-14] fix merge conflicts and introduce refactored organization service to vault filter service

* [EC-14] remove mutation from filter builders

* [EC-14] fix styling on buildFolderTree

* [EC-14] remove leftover folder-filters reference and use ternary for collapse icon

* [EC-14] remove unecessary checks

* [EC-14] stop rebuilding filters when the organization changes

* [EC-14] Move subscription out of setter in vault filter section

* [EC-14] remove extra policy service methods from vault filter service

* [EC-14] remove new methods from old vault-filter.service

* [EC-14] Use vault filter service in vault components

* [EC-14] reload collections from vault now that we have vault filter service

* [EC-14] remove currentFilterCollections in vault filter component

* [EC-14] change VaultFilterType to more specific OrganizationFilter in organization-options

* [EC-14] include org check in isNodeSelected

* [EC-14] add getters to filter function, fix storybook, and add test for All Collections

* [EC-14] show org options even if there's a personal vault policy

* [EC-14] use !"AllCollections" instead of just !null

* [EC-14] Remove extra org Subject in vault filter service

* [EC-14] remove null check from vault search text

* [EC-14] replace store/build names with set/get. Remove extra call to setOrganizationFilter

* [EC-14] add take(1) to subscribe in test

* [EC-14] move init logic in org vault filter component to ngOnInit

* [EC-14] Fix linter

* [EC-14] revert change to vault filter model

* [EC-14] be specific about ignoring All Collections

* [EC-14] move observable init logic to beforeEach in test

* [EC-14] make buildAllFilters return something to reduce side effects

Signed-off-by: Jacob Fink <jfink@bitwarden.com>
Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
Co-authored-by: Thomas Rittson <eliykat@users.noreply.github.com>
This commit is contained in:
Jake Fink
2022-10-05 21:21:37 -04:00
committed by GitHub
parent dc0ea9a48f
commit 4d83b81d82
57 changed files with 2174 additions and 1000 deletions

View File

@@ -1,6 +1,15 @@
import { ITreeNodeObject, TreeNode } from "../models/domain/treeNode";
export class ServiceUtils {
/**
* Recursively adds a node to nodeTree
* @param {TreeNode<ITreeNodeObject>[]} nodeTree - An array of TreeNodes that the node will be added to
* @param {number} partIndex - Index of the `parts` array that is being processed
* @param {string[]} parts - Array of strings that represent the path to the `obj` node
* @param {ITreeNodeObject} obj - The node to be added to the tree
* @param {ITreeNodeObject} parent - The parent node of the `obj` node
* @param {string} delimiter - The delimiter used to split the path string
*/
static nestedTraverse(
nodeTree: TreeNode<ITreeNodeObject>[],
partIndex: number,
@@ -22,7 +31,7 @@ export class ServiceUtils {
}
if (end && nodeTree[i].node.id !== obj.id) {
// Another node with the same name.
nodeTree.push(new TreeNode(obj, partName, parent));
nodeTree.push(new TreeNode(obj, parent, partName));
return;
}
ServiceUtils.nestedTraverse(
@@ -38,7 +47,7 @@ export class ServiceUtils {
if (nodeTree.filter((n) => n.node.name === partName).length === 0) {
if (end) {
nodeTree.push(new TreeNode(obj, partName, parent));
nodeTree.push(new TreeNode(obj, parent, partName));
return;
}
const newPartName = parts[partIndex] + delimiter + parts[partIndex + 1];
@@ -53,7 +62,37 @@ export class ServiceUtils {
}
}
/**
* Searches a tree for a node with a matching `id`
* @param {TreeNode<ITreeNodeObject>} nodeTree - A single TreeNode branch that will be searched
* @param {string} id - The id of the node to be found
* @returns {TreeNode<ITreeNodeObject>} The node with a matching `id`
*/
static getTreeNodeObject(
nodeTree: TreeNode<ITreeNodeObject>,
id: string
): TreeNode<ITreeNodeObject> {
if (nodeTree.node.id === id) {
return nodeTree;
}
for (let i = 0; i < nodeTree.children.length; i++) {
if (nodeTree.children[i].children != null) {
const node = ServiceUtils.getTreeNodeObject(nodeTree.children[i], id);
if (node !== null) {
return node;
}
}
}
return null;
}
/**
* Searches an array of tree nodes for a node with a matching `id`
* @param {TreeNode<ITreeNodeObject>} nodeTree - An array of TreeNode branches that will be searched
* @param {string} id - The id of the node to be found
* @returns {TreeNode<ITreeNodeObject>} The node with a matching `id`
*/
static getTreeNodeObjectFromList(
nodeTree: TreeNode<ITreeNodeObject>[],
id: string
): TreeNode<ITreeNodeObject> {
@@ -61,7 +100,7 @@ export class ServiceUtils {
if (nodeTree[i].node.id === id) {
return nodeTree[i];
} else if (nodeTree[i].children != null) {
const node = ServiceUtils.getTreeNodeObject(nodeTree[i].children, id);
const node = ServiceUtils.getTreeNodeObjectFromList(nodeTree[i].children, id);
if (node !== null) {
return node;
}

View File

@@ -137,6 +137,10 @@ export class Organization {
);
}
get canUseAdminCollections() {
return this.canEditAnyCollection;
}
get canDeleteAnyCollection() {
return (
this.isAdmin ||

View File

@@ -3,10 +3,15 @@ export class TreeNode<T extends ITreeNodeObject> {
node: T;
children: TreeNode<T>[] = [];
constructor(node: T, name: string, parent: T) {
constructor(node: T, parent: T, name?: string, id?: string) {
this.parent = parent;
this.node = node;
this.node.name = name;
if (name) {
this.node.name = name;
}
if (id) {
this.node.id = id;
}
}
}

View File

@@ -91,6 +91,10 @@ export class CollectionService implements CollectionServiceAbstraction {
return decryptedCollections;
}
/**
* @deprecated August 30 2022: Moved to new Vault Filter Service
* Remove when Desktop and Browser are updated
*/
async getAllNested(collections: CollectionView[] = null): Promise<TreeNode<CollectionView>[]> {
if (collections == null) {
collections = await this.getAllDecrypted();
@@ -106,9 +110,13 @@ export class CollectionService implements CollectionServiceAbstraction {
return nodes;
}
/**
* @deprecated August 30 2022: Moved to new Vault Filter Service
* Remove when Desktop and Browser are updated
*/
async getNested(id: string): Promise<TreeNode<CollectionView>> {
const collections = await this.getAllNested();
return ServiceUtils.getTreeNodeObject(collections, id) as TreeNode<CollectionView>;
return ServiceUtils.getTreeNodeObjectFromList(collections, id) as TreeNode<CollectionView>;
}
async upsert(collection: CollectionData | CollectionData[]): Promise<any> {