mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 15:53:27 +00:00
[AC-974] [Technical Dependency] Refactor Vault Tables (#4967)
* [EC-974] feat: scaffold new vault-items component * [EC-974] feat: add basic mocked data to story * [EC-974] feat: add initial table version * [EC-974] chore: split rows into separate components * [EC-974] chore: rename item row to cipher row * [EC-974] feat: create common vault item interface * [EC-974] feat: use cdk virtual scrolling * [EC-974] fix: tweak `itemSize` * [EC-974] chore: move vault-items component to app/vault folder * [EC-974] feat: initial support for extra column * [EC-974] feat: start adding org badge Having issues with modules import * [EC-974] feat: add working owner column on collections row * [EC-974] feat: add owner to ciphers * [EC-974] fix: org name badge bugs when reused * [EC-974] feat: fix and translate columns * [EC-974] feat: allow collections to be non-editable * [EC-974] feat: use data source * [EC-974] fix: remove profile name from vault items * [EC-974] feat: add events * [EC-974] feat: add support for copy event * [EC-974] feat: add support for collections column * [EC-974] feat: add support for group badges * [EC-974] chore: rename for consistency * [EC-974] feat: change story to use template * [EC-974] feat: add support for launching * [EC-974] feat: add support for attachements * [EC-974] feat: add stories for all use-cases * [EC-974] feat: add support for cloning * [EC-974] feat: add support for moving to organization * [EC-974] feat: add support for editing cipher collections * [EC-974] feat: add support for event logs * [EC-974] feat: add support for trash/delete/restore * [EC-974] feat: add support for editing collections * [EC-974] feat: add support for access and delete collections * [EC-974] feat: don't show menu if it's empty * [EC-974] feat: initial buggy implementation of selection * [EC-974] feat: implement bulk move * [EC-974] feat: add support for bulk moving to org * [EC-974] feat: add support for bulk restore * [EC-974] feat: add support for bulk delete * [EC-974] feat: add ability to disable the table * [EC-974] feat: create new filter function based on routed model * [EC-974] wip: start replacing vault items component * [EC-974] feat: add support for fetching ciphers * [EC-974] feat: hide trash by default * [EC-974] feat: add support for the rest of the data * [EC-974] feat: implement organization filtering using org badge * [EC-974] feat: fix navigation to "my vault" * [EC-974] feat: don't show bulk move options when filtering on org items * [EC-974] feat: prepare for disabling table * [EC-974] fix: add missing router link to collections * [EC-974] feat: connect all outputs * [EC-974] fix: list not properly refreshing after delete * [EC-974] feat: limit selection to top 500 items * [EC-974] feat: implement refresh tracker * [EC-974] feat: use refresh tracker to disable vault items * [EC-974] feat: add empty list message * [AC-974] feat: add initial load with spinner and fix empty -> show list bug * [EC-974] feat: replace action promise with simple loading boolean * [EC-974] feat: refactor individual vault header * [EC-974] feat: cache and make observables long lived * [EC-974] feat: implement searching * [EC-974] feat: add support for showing collections * [EC-974] feat: add ciphers to org vault list * [EC-974] feat: show group column * [EC-974] feat: tweak settings for org vault * [EC-974] feat: implement search using query params * [EC-974] feat: add support for events that are common with individual vault * [EC-974] feat: add support for all events * [EC-974] feat: add support for empty list message and no permission message * [EC-974] feat: always show table * [EC-974] feat: fix layout issues due to incorrect row height * [EC-974] feat: disable list if empty * [EC-974] feat: improve sync handling * [EC-974] feat: improve initial loading sequence * [EC-974] feat: improve initial load sequence in org vault * [EC-974] refactor: simplify and optimize data fetching * [EC-974] feat: use observables from org service * [EC-974] feat: refactor org vault header * [EC-974] fix: data not refreshing properly * [EC-974] fix: avoid collection double fetching * [EC-974] chore: clean up refresh tracker * [EC-974] chore: clean up old vault-items components * [EC-974] chore: clean up old code in vault component * [EC-974] fix: reduce rows in story The story ends up too big for chromatic. * [EC-974] docs: tweak and typo fixes of asyncToObservable docs comment * [EC-974] fix: `attachements` typo * [EC-974] chore: remove review question comment * [EC-974] chore: remove unused `securityCode` if statement * [EC-974] fix: use `takeUntill` for legacy dialogs * [EC-974] fix: use CollectionDialogTabType instead of custom strings * [EC-974] fix: copy implementation * [EC-974] fix: use `useTotp` to check for premium features * [EC-974] fix: use `tw-sr-only` * [EC-974] chore: remove unecessary eslint disable * [EC-974] fix: clarify vault item event naming * [EC-974] fix: remove `new` from `app-new-vault-items` * [EC-974] fix: collection row not disabled during loading * [EC-974] chore: simplify router links without path changes * [EC-974] feat: invert filter function to get rid of `cipherPassesFilter` * [EC-974] fix: move `NestingDelimiter` to collection view Nesting is currently only a presentational construct, and the concept does not exist in our domain. * [EC-974] fix: org vault header not updating when switching org * [EC-974] fix: table sizing jumping around * [EC-974] fix: list not refreshing after restoring item * [EC-974] fix: re-add missing unassigned collection * [EC-974] fix don't show new item button in unassigned collection * [EC-974] fix: navigations always leading to individual vault * [EC-974] fix: remove checkbox when collections are not editable * [EC-974] fix: null reference blocking collections from refreshing after delete * [EC-974] fix: don't show checbox for collections that user does not have permissions to delete * [EC-974] fix: navigate away from deleted folder * [EC-974] chore: clean up un-used output * [EC-974] fix: org badge changing color randomly * [EC-974] fix: lint issues after merge * [EC-974] fix: lower amount of ciphers in story chromatic doesn't like large snapshots * [EC-974] fix: "all collections" not taking `organizationId` filter into account * [EC-974] fix: make sure unassigned appears in table too * [EC-974] feat: add unassigned to storybook * [EC-974] fix: forced row height not being applied properly * [EC-974] fix: hopefully fix table jumping once and for all * [EC-974] fix: attachemnts getting hidden * [EC-974] feat: extract collection editable logic to parent component * [EC-974] feat: separately track editable items * [EC-974] feat: optimize permission checks * [EC-974] fix: bulk menu hidden on chrome :lolcry: * [EC-974] fix: don't show groups column if org doesnt use groups * [EC-974] feat: make entire row clickable * [EC-974] fix: typo resulting in non-editable collections
This commit is contained in:
@@ -3,6 +3,8 @@ import { View } from "../../../models/view/view";
|
||||
import { Collection } from "../domain/collection";
|
||||
import { CollectionAccessDetailsResponse } from "../response/collection.response";
|
||||
|
||||
export const NestingDelimiter = "/";
|
||||
|
||||
export class CollectionView implements View, ITreeNodeObject {
|
||||
id: string = null;
|
||||
organizationId: string = null;
|
||||
|
||||
@@ -94,14 +94,14 @@ export class ServiceUtils {
|
||||
|
||||
/**
|
||||
* 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 {TreeNode<T>} 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`
|
||||
* @returns {TreeNode<T>} The node with a matching `id`
|
||||
*/
|
||||
static getTreeNodeObjectFromList(
|
||||
nodeTree: TreeNode<ITreeNodeObject>[],
|
||||
static getTreeNodeObjectFromList<T extends ITreeNodeObject>(
|
||||
nodeTree: TreeNode<T>[],
|
||||
id: string
|
||||
): TreeNode<ITreeNodeObject> {
|
||||
): TreeNode<T> {
|
||||
for (let i = 0; i < nodeTree.length; i++) {
|
||||
if (nodeTree[i].node.id === id) {
|
||||
return nodeTree[i];
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable no-useless-escape */
|
||||
import * as path from "path";
|
||||
|
||||
import { Observable, of, switchMap } from "rxjs";
|
||||
import { getHostname, parse } from "tldts";
|
||||
import { Merge } from "type-fest";
|
||||
|
||||
@@ -526,6 +527,17 @@ export class Utils {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an observable from a function that returns a promise.
|
||||
* Similar to the rxjs function {@link from} with one big exception:
|
||||
* {@link from} will not re-execute the function when observers resubscribe.
|
||||
* {@link Util.asyncToObservable} will execute `generator` for every
|
||||
* subscribe, making it ideal if the value ever needs to be refreshed.
|
||||
* */
|
||||
static asyncToObservable<T>(generator: () => Promise<T>): Observable<T> {
|
||||
return of(undefined).pipe(switchMap(() => generator()));
|
||||
}
|
||||
|
||||
private static isAppleMobile(win: Window) {
|
||||
return (
|
||||
win.navigator.userAgent.match(/iPhone/i) != null ||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Component, EventEmitter, Input, Output, TemplateRef, ViewChild } from "@angular/core";
|
||||
import { QueryParamsHandling } from "@angular/router";
|
||||
|
||||
@Component({
|
||||
selector: "bit-breadcrumb",
|
||||
@@ -14,6 +15,9 @@ export class BreadcrumbComponent {
|
||||
@Input()
|
||||
queryParams?: Record<string, string> = {};
|
||||
|
||||
@Input()
|
||||
queryParamsHandling?: QueryParamsHandling;
|
||||
|
||||
@Output()
|
||||
click = new EventEmitter();
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
class="tw-my-2 tw-inline-block"
|
||||
[routerLink]="breadcrumb.route"
|
||||
[queryParams]="breadcrumb.queryParams"
|
||||
[queryParamsHandling]="breadcrumb.queryParamsHandling"
|
||||
>
|
||||
<ng-container [ngTemplateOutlet]="breadcrumb.content"></ng-container>
|
||||
</a>
|
||||
@@ -43,6 +44,7 @@
|
||||
linkType="primary"
|
||||
[routerLink]="breadcrumb.route"
|
||||
[queryParams]="breadcrumb.queryParams"
|
||||
[queryParamsHandling]="breadcrumb.queryParamsHandling"
|
||||
>
|
||||
<ng-container [ngTemplateOutlet]="breadcrumb.content"></ng-container>
|
||||
</a>
|
||||
@@ -64,6 +66,7 @@
|
||||
class="tw-my-2 tw-inline-block"
|
||||
[routerLink]="breadcrumb.route"
|
||||
[queryParams]="breadcrumb.queryParams"
|
||||
[queryParamsHandling]="breadcrumb.queryParamsHandling"
|
||||
>
|
||||
<ng-container [ngTemplateOutlet]="breadcrumb.content"></ng-container>
|
||||
</a>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!-- Please remove this disable statement when editing this file! -->
|
||||
<!-- eslint-disable tailwindcss/no-custom-classname -->
|
||||
<table class="tw-w-full tw-table-auto tw-leading-normal tw-text-main">
|
||||
<table [ngClass]="tableClass">
|
||||
<thead
|
||||
class="tw-text-bold tw-border-0 tw-border-b-2 tw-border-solid tw-border-secondary-300 tw-text-muted"
|
||||
>
|
||||
|
||||
@@ -26,6 +26,7 @@ export class TableBodyDirective {
|
||||
})
|
||||
export class TableComponent implements OnDestroy, AfterContentChecked {
|
||||
@Input() dataSource: TableDataSource<any>;
|
||||
@Input() layout: "auto" | "fixed" = "auto";
|
||||
|
||||
@ContentChild(TableBodyDirective) templateVariable: TableBodyDirective;
|
||||
|
||||
@@ -33,6 +34,15 @@ export class TableComponent implements OnDestroy, AfterContentChecked {
|
||||
|
||||
private _initialized = false;
|
||||
|
||||
get tableClass() {
|
||||
return [
|
||||
"tw-w-full",
|
||||
"tw-leading-normal",
|
||||
"tw-text-main",
|
||||
this.layout === "auto" ? "tw-table-auto" : "tw-table-fixed",
|
||||
];
|
||||
}
|
||||
|
||||
ngAfterContentChecked(): void {
|
||||
if (!this._initialized && isDataSource(this.dataSource)) {
|
||||
this._initialized = true;
|
||||
|
||||
Reference in New Issue
Block a user