mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 08:43:33 +00:00
groupings and content
This commit is contained in:
@@ -1052,5 +1052,8 @@
|
|||||||
},
|
},
|
||||||
"loading": {
|
"loading": {
|
||||||
"message": "Loading..."
|
"message": "Loading..."
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"message": "Types"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
<content>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-header">
|
<div class="box-header">
|
||||||
{{'selfHostedEnvironment' | i18n}}
|
{{'selfHostedEnvironment' | i18n}}
|
||||||
@@ -54,4 +55,5 @@
|
|||||||
{{'customEnvironmentFooter' | i18n}}
|
{{'customEnvironmentFooter' | i18n}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</content>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
<content>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-content">
|
<div class="box-content">
|
||||||
<div class="box-content-row" appBoxRow>
|
<div class="box-content-row" appBoxRow>
|
||||||
@@ -24,4 +25,5 @@
|
|||||||
{{'enterEmailToGetHint' | i18n}}
|
{{'enterEmailToGetHint' | i18n}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</content>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<button type="submit" appBlurClick>{{'submit' | i18n}}</button>
|
<button type="submit" appBlurClick>{{'submit' | i18n}}</button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
<content>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-content">
|
<div class="box-content">
|
||||||
<div class="box-content-row box-content-row-flex" appBoxRow>
|
<div class="box-content-row box-content-row-flex" appBoxRow>
|
||||||
@@ -29,4 +30,5 @@
|
|||||||
<p class="text-center">
|
<p class="text-center">
|
||||||
<a href="#" appStopClick (click)="logOut()">{{'logOut' | i18n}}</a>
|
<a href="#" appStopClick (click)="logOut()">{{'logOut' | i18n}}</a>
|
||||||
</p>
|
</p>
|
||||||
|
</content>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
<content>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-content">
|
<div class="box-content">
|
||||||
<div class="box-content-row" appBoxRow>
|
<div class="box-content-row" appBoxRow>
|
||||||
@@ -39,4 +40,5 @@
|
|||||||
<p class="text-center">
|
<p class="text-center">
|
||||||
<a routerLink="/hint">{{'getMasterPasswordHint' | i18n}}</a>
|
<a routerLink="/hint">{{'getMasterPasswordHint' | i18n}}</a>
|
||||||
</p>
|
</p>
|
||||||
|
</content>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
<content>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-content">
|
<div class="box-content">
|
||||||
<div class="box-content-row" appBoxRow>
|
<div class="box-content-row" appBoxRow>
|
||||||
@@ -65,4 +66,5 @@
|
|||||||
{{'masterPassHintDesc' | i18n}}
|
{{'masterPassHintDesc' | i18n}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</content>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="right"></div>
|
<div class="right"></div>
|
||||||
</header>
|
</header>
|
||||||
|
<content>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-content">
|
<div class="box-content">
|
||||||
<a href="#" appStopClick *ngFor="let p of providers" class="box-content-row"
|
<a href="#" appStopClick *ngFor="let p of providers" class="box-content-row"
|
||||||
@@ -20,3 +21,4 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</content>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
<content>
|
||||||
<ng-container *ngIf="selectedProviderType === providerType.Authenticator ||
|
<ng-container *ngIf="selectedProviderType === providerType.Authenticator ||
|
||||||
selectedProviderType === providerType.Email">
|
selectedProviderType === providerType.Email">
|
||||||
<div class="content text-center">
|
<div class="content text-center">
|
||||||
@@ -102,5 +103,6 @@
|
|||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
</content>
|
||||||
</form>
|
</form>
|
||||||
<iframe id="u2f_iframe" hidden></iframe>
|
<iframe id="u2f_iframe" hidden></iframe>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { Router } from '@angular/router';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-tabs',
|
selector: 'app-tabs',
|
||||||
template: `
|
template: `
|
||||||
|
<div class="tab-page">
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
<nav class="tabs">
|
<nav class="tabs">
|
||||||
<ul>
|
<ul>
|
||||||
@@ -37,6 +38,7 @@ import { Router } from '@angular/router';
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>`,
|
</nav>
|
||||||
|
</div>`,
|
||||||
})
|
})
|
||||||
export class TabsComponent { }
|
export class TabsComponent { }
|
||||||
|
|||||||
73
src/popup2/vault/groupings.component.html
Normal file
73
src/popup2/vault/groupings.component.html
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<header>
|
||||||
|
<div class="left">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="center">
|
||||||
|
<span class="title">{{'myVault' | i18n}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<content>
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header">
|
||||||
|
{{'favorites' | i18n}}
|
||||||
|
</div>
|
||||||
|
<div class="box-content">
|
||||||
|
<a *ngFor="let c of favoriteCiphers" href="#" class="box-content-row" appStopClick appBlurClick>
|
||||||
|
{{c.name}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header">
|
||||||
|
{{'types' | i18n}}
|
||||||
|
</div>
|
||||||
|
<div class="box-content">
|
||||||
|
<a href="#" class="box-content-row" appStopClick appBlurClick (click)="selectType(cipherType.Login)">
|
||||||
|
{{'typeLogin' | i18n}}
|
||||||
|
<span>{{typeCounts.get(cipherType.Login) || 0}}</span>
|
||||||
|
</a>
|
||||||
|
<a href="#" class="box-content-row" appStopClick appBlurClick (click)="selectType(cipherType.Card)">
|
||||||
|
{{'typeCard' | i18n}}
|
||||||
|
<span>{{typeCounts.get(cipherType.Card) || 0}}</span>
|
||||||
|
</a>
|
||||||
|
<a href="#" class="box-content-row" appStopClick appBlurClick (click)="selectType(cipherType.Identity)">
|
||||||
|
{{'typeIdentity' | i18n}}
|
||||||
|
<span>{{typeCounts.get(cipherType.Identity) || 0}}</span>
|
||||||
|
</a>
|
||||||
|
<a href="#" class="box-content-row" appStopClick appBlurClick (click)="selectType(cipherType.SecureNote)">
|
||||||
|
{{'typeSecureNote' | i18n}}
|
||||||
|
<span>{{typeCounts.get(cipherType.SecureNote) || 0}}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p *ngIf="!loaded" class="text-muted">{{'loading' | i18n}}</p>
|
||||||
|
<ng-container *ngIf="loaded">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header">
|
||||||
|
{{'folders' | i18n}}
|
||||||
|
</div>
|
||||||
|
<div class="box-content">
|
||||||
|
<a *ngFor="let f of folders" href="#" class="box-content-row" appStopClick appBlurClick
|
||||||
|
(click)="selectFolder(f)">
|
||||||
|
{{f.name}}
|
||||||
|
<span>{{folderCounts.get(f.id) || 0}}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header">
|
||||||
|
{{'collections' | i18n}}
|
||||||
|
</div>
|
||||||
|
<div class="box-content">
|
||||||
|
<a *ngFor="let c of collections" href="#" class="box-content-row" appStopClick appBlurClick
|
||||||
|
(click)="selectCollection(f)">
|
||||||
|
{{c.name}}
|
||||||
|
<span>{{collectionCounts.get(c.id) || 0}}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</content>
|
||||||
@@ -1,22 +1,74 @@
|
|||||||
|
import * as template from './groupings.component.html';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
ComponentFactoryResolver,
|
|
||||||
NgZone,
|
|
||||||
OnDestroy,
|
|
||||||
OnInit,
|
OnInit,
|
||||||
Type,
|
|
||||||
ViewChild,
|
|
||||||
ViewContainerRef,
|
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
|
||||||
|
import { CipherType } from 'jslib/enums/cipherType';
|
||||||
|
|
||||||
|
import { CipherView } from 'jslib/models/view/cipherView';
|
||||||
|
|
||||||
|
import { CollectionService } from 'jslib/abstractions/collection.service';
|
||||||
|
import { CipherService } from 'jslib/abstractions/cipher.service';
|
||||||
|
import { FolderService } from 'jslib/abstractions/folder.service';
|
||||||
|
|
||||||
|
import { GroupingsComponent as BaseGroupingsComponent } from 'jslib/angular/components/groupings.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-vault-groupings',
|
selector: 'app-vault-groupings',
|
||||||
styles: [],
|
template: template,
|
||||||
template: `Groupings`,
|
|
||||||
})
|
})
|
||||||
export class GroupingsComponent {
|
export class GroupingsComponent extends BaseGroupingsComponent implements OnInit {
|
||||||
constructor() {
|
ciphers: CipherView[];
|
||||||
|
favoriteCiphers: CipherView[];
|
||||||
|
folderCounts = new Map<string, number>();
|
||||||
|
collectionCounts = new Map<string, number>();
|
||||||
|
typeCounts = new Map<CipherType, number>();
|
||||||
|
|
||||||
|
constructor(collectionService: CollectionService, folderService: FolderService,
|
||||||
|
private cipherService: CipherService) {
|
||||||
|
super(collectionService, folderService);
|
||||||
|
}
|
||||||
|
|
||||||
|
async ngOnInit() {
|
||||||
|
this.load();
|
||||||
|
this.loaded = false;
|
||||||
|
await this.loadCiphers();
|
||||||
|
this.loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async loadCiphers() {
|
||||||
|
this.ciphers = await this.cipherService.getAllDecrypted();
|
||||||
|
this.ciphers.forEach((c) => {
|
||||||
|
if (c.favorite) {
|
||||||
|
if (this.favoriteCiphers == null) {
|
||||||
|
this.favoriteCiphers = [];
|
||||||
|
}
|
||||||
|
this.favoriteCiphers.push(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.typeCounts.has(c.type)) {
|
||||||
|
this.typeCounts.set(c.type, this.typeCounts.get(c.type) + 1);
|
||||||
|
} else {
|
||||||
|
this.typeCounts.set(c.type, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.folderCounts.has(c.folderId)) {
|
||||||
|
this.folderCounts.set(c.folderId, this.folderCounts.get(c.folderId) + 1);
|
||||||
|
} else {
|
||||||
|
this.folderCounts.set(c.folderId, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.collectionIds != null) {
|
||||||
|
c.collectionIds.forEach((colId) => {
|
||||||
|
if (this.collectionCounts.has(colId)) {
|
||||||
|
this.collectionCounts.set(colId, this.collectionCounts.get(colId) + 1);
|
||||||
|
} else {
|
||||||
|
this.collectionCounts.set(colId, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
background-color: $background-color-alt2;
|
background-color: $background-color;
|
||||||
font-family: $font-family-sans-serif;
|
font-family: $font-family-sans-serif;
|
||||||
font-size: $font-size-base;
|
font-size: $font-size-base;
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
@@ -71,16 +71,16 @@ textarea {
|
|||||||
resize: vertical;
|
resize: vertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
div::-webkit-scrollbar {
|
content::-webkit-scrollbar {
|
||||||
width: 10px;
|
width: 10px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div::-webkit-scrollbar-track {
|
content::-webkit-scrollbar-track {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
div::-webkit-scrollbar-thumb {
|
content::-webkit-scrollbar-thumb {
|
||||||
background-color: rgba(100,100,100,.2);
|
background-color: rgba(100,100,100,.2);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin-right: 1px;
|
margin-right: 1px;
|
||||||
@@ -196,3 +196,29 @@ header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app-root {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 980;
|
||||||
|
}
|
||||||
|
|
||||||
|
content {
|
||||||
|
position: absolute;
|
||||||
|
top: 44px;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
&.no-header {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-page {
|
||||||
|
content {
|
||||||
|
bottom: 55px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,11 +23,10 @@ $brand-info: #555555;
|
|||||||
$brand-warning: #bf7e16;
|
$brand-warning: #bf7e16;
|
||||||
$brand-primary-accent: #286090;
|
$brand-primary-accent: #286090;
|
||||||
|
|
||||||
$background-color: white;
|
$background-color: #f9fafc;
|
||||||
$background-color-alt: #f9fafc;
|
$background-color-alt: #ecf0f5;
|
||||||
$background-color-alt2: #ecf0f5;
|
|
||||||
|
|
||||||
$box-background-color: $background-color;
|
$box-background-color: white;
|
||||||
$box-background-hover-color: $list-item-hover;
|
$box-background-hover-color: $list-item-hover;
|
||||||
$box-border-color: $border-color;
|
$box-border-color: $border-color;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user