1
0
mirror of https://github.com/bitwarden/web synced 2025-12-22 19:23:42 +00:00

[End User Vault Refresh] Vault - remove Org and Provider cards (#1529)

This commit is contained in:
Thomas Rittson
2022-03-23 06:32:13 +10:00
committed by GitHub
parent 9b742ed0d7
commit f8ff75aa1b
6 changed files with 141 additions and 245 deletions

View File

@@ -1,58 +1,33 @@
<ng-container *ngIf="vault"> <app-navbar></app-navbar>
<div class="container page-content">
<div class="page-header d-flex">
<h1>{{ "providers" | i18n }}</h1>
</div>
<p *ngIf="!loaded" class="text-muted"> <p *ngIf="!loaded" class="text-muted">
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i> <i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
<span class="sr-only">{{ "loading" | i18n }}</span> <span class="sr-only">{{ "loading" | i18n }}</span>
</p> </p>
<ng-container *ngIf="loaded"> <ng-container *ngIf="loaded">
<ul class="bwi-ul card-ul carets" *ngIf="providers && providers.length"> <table class="table table-hover table-list" *ngIf="providers && providers.length">
<li *ngFor="let p of providers"> <tbody>
<a [routerLink]="['/providers', p.id]" class="text-body"> <tr *ngFor="let p of providers">
<i class="bwi bwi-li bwi-caret-right" aria-hidden="true"></i> {{ p.name }} <td width="30">
<ng-container *ngIf="!p.enabled"> <app-avatar [data]="p.name" size="25" [circle]="true" [fontSize]="14"></app-avatar>
<i </td>
class="bwi bwi-exclamation-triangle text-danger" <td>
title="{{ 'providerIsDisabled' | i18n }}" <a href="#" [routerLink]="['/providers', p.id]">{{ p.name }}</a>
aria-hidden="true" <ng-container *ngIf="!p.enabled">
></i> <i
<span class="sr-only">{{ "providerIsDisabled" | i18n }}</span> class="bwi bwi-exclamation-triangle text-danger"
</ng-container> title="{{ 'providerIsDisabled' | i18n }}"
</a> aria-hidden="true"
</li> ></i>
</ul> <span class="sr-only">{{ "providerIsDisabled" | i18n }}</span>
</ng-container>
</td>
</tr>
</tbody>
</table>
</ng-container> </ng-container>
</ng-container> </div>
<ng-container *ngIf="!vault"> <app-footer></app-footer>
<app-navbar></app-navbar>
<div class="container page-content">
<div class="page-header d-flex">
<h1>{{ "providers" | i18n }}</h1>
</div>
<p *ngIf="!loaded" class="text-muted">
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
<span class="sr-only">{{ "loading" | i18n }}</span>
</p>
<ng-container *ngIf="loaded">
<table class="table table-hover table-list" *ngIf="providers && providers.length">
<tbody>
<tr *ngFor="let p of providers">
<td width="30">
<app-avatar [data]="p.name" size="25" [circle]="true" [fontSize]="14"></app-avatar>
</td>
<td>
<a href="#" [routerLink]="['/providers', p.id]">{{ p.name }}</a>
<ng-container *ngIf="!p.enabled">
<i
class="bwi bwi-exclamation-triangle text-danger"
title="{{ 'providerIsDisabled' | i18n }}"
aria-hidden="true"
></i>
<span class="sr-only">{{ "providerIsDisabled" | i18n }}</span>
</ng-container>
</td>
</tr>
</tbody>
</table>
</ng-container>
</div>
<app-footer></app-footer>
</ng-container>

View File

@@ -1,4 +1,4 @@
import { Component, Input, OnInit } from "@angular/core"; import { Component, OnInit } from "@angular/core";
import { I18nService } from "jslib-common/abstractions/i18n.service"; import { I18nService } from "jslib-common/abstractions/i18n.service";
import { ProviderService } from "jslib-common/abstractions/provider.service"; import { ProviderService } from "jslib-common/abstractions/provider.service";
@@ -10,8 +10,6 @@ import { Provider } from "jslib-common/models/domain/provider";
templateUrl: "providers.component.html", templateUrl: "providers.component.html",
}) })
export class ProvidersComponent implements OnInit { export class ProvidersComponent implements OnInit {
@Input() vault = false;
providers: Provider[]; providers: Provider[];
loaded = false; loaded = false;
actionPromise: Promise<any>; actionPromise: Promise<any>;

View File

@@ -1,13 +1,51 @@
<ng-container *ngIf="vault"> <div class="page-header d-flex">
<p *ngIf="!loaded" class="text-muted"> <h1>
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i> {{ "organizations" | i18n }}
<span class="sr-only">{{ "loading" | i18n }}</span> <small [appApiAction]="actionPromise" #action>
</p> <ng-container *ngIf="action.loading">
<ng-container *ngIf="loaded"> <i
<ul class="bwi-ul card-ul carets" *ngIf="organizations && organizations.length"> class="bwi bwi-spinner bwi-spin text-muted"
<li *ngFor="let o of organizations"> title="{{ 'loading' | i18n }}"
<a [routerLink]="['/organizations', o.id]" class="text-body"> aria-hidden="true"
<i class="bwi bwi-li bwi-caret-right" aria-hidden="true"></i> {{ o.name }} ></i>
<span class="sr-only">{{ "loading" | i18n }}</span>
</ng-container>
</small>
</h1>
<a
href="#"
routerLink="/settings/create-organization"
class="btn btn-sm btn-outline-primary ml-auto"
*ngIf="!loaded || (organizations && organizations.length)"
>
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
{{ "newOrganization" | i18n }}
</a>
</div>
<ng-container *ngIf="!loaded">
<i
class="bwi bwi-spinner bwi-spin text-muted"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>
<span class="sr-only">{{ "loading" | i18n }}</span>
</ng-container>
<ng-container *ngIf="loaded">
<ng-container *ngIf="!organizations || !organizations.length">
<p>{{ "noOrganizationsList" | i18n }}</p>
<a href="#" routerLink="/settings/create-organization" class="btn btn-outline-primary">
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
{{ "newOrganization" | i18n }}
</a>
</ng-container>
<table class="table table-hover table-list" *ngIf="organizations && organizations.length">
<tbody>
<tr *ngFor="let o of organizations">
<td width="30">
<app-avatar [data]="o.name" size="25" [circle]="true" [fontSize]="14"></app-avatar>
</td>
<td>
<a href="#" [routerLink]="['/organizations', o.id]">{{ o.name }}</a>
<ng-container *ngIf="!o.enabled"> <ng-container *ngIf="!o.enabled">
<i <i
class="bwi bwi-exclamation-triangle text-danger" class="bwi bwi-exclamation-triangle text-danger"
@@ -16,140 +54,72 @@
></i> ></i>
<span class="sr-only">{{ "organizationIsDisabled" | i18n }}</span> <span class="sr-only">{{ "organizationIsDisabled" | i18n }}</span>
</ng-container> </ng-container>
</a> <ng-container *ngIf="showEnrolledStatus(o)">
</li> <i
</ul> class="bwi bwi-key"
<p *ngIf="!organizations || !organizations.length">{{ "noOrganizationsList" | i18n }}</p> appStopProp
</ng-container> title="{{ 'enrolledPasswordReset' | i18n }}"
<a href="#" routerLink="/settings/create-organization" class="btn btn-block btn-outline-primary"> aria-hidden="true"
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i> ></i>
{{ "newOrganization" | i18n }} <span class="sr-only">{{ "enrolledPasswordReset" | i18n }}</span>
</a> </ng-container>
</ng-container> </td>
<ng-container *ngIf="!vault"> <td class="table-list-options">
<div class="page-header d-flex"> <div class="dropdown" appListDropdown>
<h1> <button
{{ "organizations" | i18n }} class="btn btn-outline-secondary dropdown-toggle"
<small [appApiAction]="actionPromise" #action> type="button"
<ng-container *ngIf="action.loading"> data-toggle="dropdown"
<i aria-haspopup="true"
class="bwi bwi-spinner bwi-spin text-muted" aria-expanded="false"
title="{{ 'loading' | i18n }}" appA11yTitle="{{ 'options' | i18n }}"
aria-hidden="true" >
></i> <i class="bwi bwi-cog bwi-lg" aria-hidden="true"></i>
<span class="sr-only">{{ "loading" | i18n }}</span> </button>
</ng-container> <div class="dropdown-menu dropdown-menu-right">
</small> <a
</h1> *ngIf="allowEnrollmentChanges(o) && !o.resetPasswordEnrolled"
<a class="dropdown-item"
href="#" href="#"
routerLink="/settings/create-organization" appStopClick
class="btn btn-sm btn-outline-primary ml-auto" (click)="toggleResetPasswordEnrollment(o)"
*ngIf="!loaded || (organizations && organizations.length)"
>
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
{{ "newOrganization" | i18n }}
</a>
</div>
<ng-container *ngIf="!loaded">
<i
class="bwi bwi-spinner bwi-spin text-muted"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>
<span class="sr-only">{{ "loading" | i18n }}</span>
</ng-container>
<ng-container *ngIf="loaded">
<ng-container *ngIf="!organizations || !organizations.length">
<p>{{ "noOrganizationsList" | i18n }}</p>
<a href="#" routerLink="/settings/create-organization" class="btn btn-outline-primary">
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
{{ "newOrganization" | i18n }}
</a>
</ng-container>
<table class="table table-hover table-list" *ngIf="organizations && organizations.length">
<tbody>
<tr *ngFor="let o of organizations">
<td width="30">
<app-avatar [data]="o.name" size="25" [circle]="true" [fontSize]="14"></app-avatar>
</td>
<td>
<a href="#" [routerLink]="['/organizations', o.id]">{{ o.name }}</a>
<ng-container *ngIf="!o.enabled">
<i
class="bwi bwi-exclamation-triangle text-danger"
title="{{ 'organizationIsDisabled' | i18n }}"
aria-hidden="true"
></i>
<span class="sr-only">{{ "organizationIsDisabled" | i18n }}</span>
</ng-container>
<ng-container *ngIf="showEnrolledStatus(o)">
<i
class="bwi bwi-key"
appStopProp
title="{{ 'enrolledPasswordReset' | i18n }}"
aria-hidden="true"
></i>
<span class="sr-only">{{ "enrolledPasswordReset" | i18n }}</span>
</ng-container>
</td>
<td class="table-list-options">
<div class="dropdown" appListDropdown>
<button
class="btn btn-outline-secondary dropdown-toggle"
type="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
appA11yTitle="{{ 'options' | i18n }}"
> >
<i class="bwi bwi-cog bwi-lg" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-key" aria-hidden="true"></i>
</button> {{ "enrollPasswordReset" | i18n }}
<div class="dropdown-menu dropdown-menu-right"> </a>
<a
*ngIf="allowEnrollmentChanges(o) && o.resetPasswordEnrolled"
class="dropdown-item"
href="#"
appStopClick
(click)="toggleResetPasswordEnrollment(o)"
>
<i class="bwi bwi-fw bwi-undo" aria-hidden="true"></i>
{{ "withdrawPasswordReset" | i18n }}
</a>
<ng-container *ngIf="o.useSso && o.identifier">
<a <a
*ngIf="allowEnrollmentChanges(o) && !o.resetPasswordEnrolled" *ngIf="o.ssoBound; else linkSso"
class="dropdown-item" class="dropdown-item"
href="#" href="#"
appStopClick appStopClick
(click)="toggleResetPasswordEnrollment(o)" (click)="unlinkSso(o)"
> >
<i class="bwi bwi-fw bwi-key" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-chain-broken" aria-hidden="true"></i>
{{ "enrollPasswordReset" | i18n }} {{ "unlinkSso" | i18n }}
</a> </a>
<a <ng-template #linkSso>
*ngIf="allowEnrollmentChanges(o) && o.resetPasswordEnrolled" <app-link-sso [organization]="o"> </app-link-sso>
class="dropdown-item" </ng-template>
href="#" </ng-container>
appStopClick <a class="dropdown-item text-danger" href="#" appStopClick (click)="leave(o)">
(click)="toggleResetPasswordEnrollment(o)" <i class="bwi bwi-fw bwi-sign-out" aria-hidden="true"></i>
> {{ "leave" | i18n }}
<i class="bwi bwi-fw bwi-undo" aria-hidden="true"></i> </a>
{{ "withdrawPasswordReset" | i18n }}
</a>
<ng-container *ngIf="o.useSso && o.identifier">
<a
*ngIf="o.ssoBound; else linkSso"
class="dropdown-item"
href="#"
appStopClick
(click)="unlinkSso(o)"
>
<i class="bwi bwi-fw bwi-chain-broken" aria-hidden="true"></i>
{{ "unlinkSso" | i18n }}
</a>
<ng-template #linkSso>
<app-link-sso [organization]="o"> </app-link-sso>
</ng-template>
</ng-container>
<a class="dropdown-item text-danger" href="#" appStopClick (click)="leave(o)">
<i class="bwi bwi-fw bwi-sign-out" aria-hidden="true"></i>
{{ "leave" | i18n }}
</a>
</div>
</div> </div>
</td> </div>
</tr> </td>
</tbody> </tr>
</table> </tbody>
</ng-container> </table>
</ng-container> </ng-container>

View File

@@ -1,4 +1,4 @@
import { Component, Input, OnInit } from "@angular/core"; import { Component, OnInit } from "@angular/core";
import { ApiService } from "jslib-common/abstractions/api.service"; import { ApiService } from "jslib-common/abstractions/api.service";
import { CryptoService } from "jslib-common/abstractions/crypto.service"; import { CryptoService } from "jslib-common/abstractions/crypto.service";
@@ -19,8 +19,6 @@ import { OrganizationUserResetPasswordEnrollmentRequest } from "jslib-common/mod
templateUrl: "organizations.component.html", templateUrl: "organizations.component.html",
}) })
export class OrganizationsComponent implements OnInit { export class OrganizationsComponent implements OnInit {
@Input() vault = false;
organizations: Organization[]; organizations: Organization[];
policies: Policy[]; policies: Policy[];
loaded = false; loaded = false;
@@ -38,10 +36,8 @@ export class OrganizationsComponent implements OnInit {
) {} ) {}
async ngOnInit() { async ngOnInit() {
if (!this.vault) { await this.syncService.fullSync(true);
await this.syncService.fullSync(true); await this.load();
await this.load();
}
} }
async load() { async load() {

View File

@@ -97,40 +97,6 @@
</a> </a>
</div> </div>
</div> </div>
<div class="card mb-4">
<div class="card-header d-flex">
{{ "organizations" | i18n }}
<a
class="ml-auto"
href="https://bitwarden.com/help/about-organizations/"
target="_blank"
rel="noopener"
appA11yTitle="{{ 'learnMore' | i18n }}"
>
<i class="bwi bwi-question-circle" aria-hidden="true"></i>
</a>
</div>
<div class="card-body">
<app-organizations [vault]="true"></app-organizations>
</div>
</div>
<div class="card mt-4" *ngIf="showProviders">
<div class="card-header d-flex">
{{ "providers" | i18n }}
<a
class="ml-auto"
href="https://bitwarden.com/help/providers/"
target="_blank"
rel="noopener"
appA11yTitle="{{ 'learnMore' | i18n }}"
>
<i class="bwi bwi-question-circle" aria-hidden="true"></i>
</a>
</div>
<div class="card-body">
<app-providers vault="true"></app-providers>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -17,14 +17,12 @@ import { I18nService } from "jslib-common/abstractions/i18n.service";
import { MessagingService } from "jslib-common/abstractions/messaging.service"; import { MessagingService } from "jslib-common/abstractions/messaging.service";
import { OrganizationService } from "jslib-common/abstractions/organization.service"; import { OrganizationService } from "jslib-common/abstractions/organization.service";
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service"; import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
import { ProviderService } from "jslib-common/abstractions/provider.service";
import { StateService } from "jslib-common/abstractions/state.service"; import { StateService } from "jslib-common/abstractions/state.service";
import { SyncService } from "jslib-common/abstractions/sync.service"; import { SyncService } from "jslib-common/abstractions/sync.service";
import { TokenService } from "jslib-common/abstractions/token.service"; import { TokenService } from "jslib-common/abstractions/token.service";
import { CipherType } from "jslib-common/enums/cipherType"; import { CipherType } from "jslib-common/enums/cipherType";
import { CipherView } from "jslib-common/models/view/cipherView"; import { CipherView } from "jslib-common/models/view/cipherView";
import { OrganizationsComponent } from "../settings/organizations.component";
import { UpdateKeyComponent } from "../settings/update-key.component"; import { UpdateKeyComponent } from "../settings/update-key.component";
import { AddEditComponent } from "./add-edit.component"; import { AddEditComponent } from "./add-edit.component";
@@ -44,8 +42,6 @@ const BroadcasterSubscriptionId = "VaultComponent";
export class VaultComponent implements OnInit, OnDestroy { export class VaultComponent implements OnInit, OnDestroy {
@ViewChild(GroupingsComponent, { static: true }) groupingsComponent: GroupingsComponent; @ViewChild(GroupingsComponent, { static: true }) groupingsComponent: GroupingsComponent;
@ViewChild(CiphersComponent, { static: true }) ciphersComponent: CiphersComponent; @ViewChild(CiphersComponent, { static: true }) ciphersComponent: CiphersComponent;
@ViewChild(OrganizationsComponent, { static: true })
organizationsComponent: OrganizationsComponent;
@ViewChild("attachments", { read: ViewContainerRef, static: true }) @ViewChild("attachments", { read: ViewContainerRef, static: true })
attachmentsModalRef: ViewContainerRef; attachmentsModalRef: ViewContainerRef;
@ViewChild("folderAddEdit", { read: ViewContainerRef, static: true }) @ViewChild("folderAddEdit", { read: ViewContainerRef, static: true })
@@ -66,7 +62,6 @@ export class VaultComponent implements OnInit, OnDestroy {
showBrowserOutdated = false; showBrowserOutdated = false;
showUpdateKey = false; showUpdateKey = false;
showPremiumCallout = false; showPremiumCallout = false;
showProviders = false;
deleted = false; deleted = false;
trashCleanupWarning: string = null; trashCleanupWarning: string = null;
@@ -84,8 +79,7 @@ export class VaultComponent implements OnInit, OnDestroy {
private broadcasterService: BroadcasterService, private broadcasterService: BroadcasterService,
private ngZone: NgZone, private ngZone: NgZone,
private stateService: StateService, private stateService: StateService,
private organizationService: OrganizationService, private organizationService: OrganizationService
private providerService: ProviderService
) {} ) {}
async ngOnInit() { async ngOnInit() {
@@ -104,9 +98,7 @@ export class VaultComponent implements OnInit, OnDestroy {
this.showPremiumCallout = this.showPremiumCallout =
!this.showVerifyEmail && !canAccessPremium && !this.platformUtilsService.isSelfHost(); !this.showVerifyEmail && !canAccessPremium && !this.platformUtilsService.isSelfHost();
this.showProviders = (await this.providerService.getAll()).length > 0; await this.groupingsComponent.load();
await Promise.all([this.groupingsComponent.load(), this.organizationsComponent.load()]);
this.showUpdateKey = !(await this.cryptoService.hasEncKey()); this.showUpdateKey = !(await this.cryptoService.hasEncKey());
if (params == null) { if (params == null) {
@@ -143,7 +135,6 @@ export class VaultComponent implements OnInit, OnDestroy {
if (message.successfully) { if (message.successfully) {
await Promise.all([ await Promise.all([
this.groupingsComponent.load(), this.groupingsComponent.load(),
this.organizationsComponent.load(),
this.ciphersComponent.load(this.ciphersComponent.filter), this.ciphersComponent.load(this.ciphersComponent.filter),
]); ]);
this.changeDetectorRef.detectChanges(); this.changeDetectorRef.detectChanges();