mirror of
https://github.com/bitwarden/browser
synced 2026-02-10 21:50:15 +00:00
[PM-30918] Migrate DIRT components to new Angular control flow syntax (#18416)
* dirt: migrate apps/web components to new control flow * dirt: update control flow bitwarden licensed code * consolidate @if statements, use @else where appropriate * more cleanup * consolidate conditionals * remove unnecessary conditional
This commit is contained in:
@@ -12,45 +12,54 @@
|
||||
{{ "checkBreaches" | i18n }}
|
||||
</button>
|
||||
</form>
|
||||
<div class="tw-mt-4" *ngIf="!loading && checkedUsername">
|
||||
<p *ngIf="error">{{ "reportError" | i18n }}...</p>
|
||||
<ng-container *ngIf="!error">
|
||||
<bit-callout type="success" title="{{ 'goodNews' | i18n }}" *ngIf="!breachedAccounts.length">
|
||||
{{ "breachUsernameNotFound" | i18n: checkedUsername }}
|
||||
</bit-callout>
|
||||
<bit-callout type="danger" title="{{ 'breachFound' | i18n }}" *ngIf="breachedAccounts.length">
|
||||
{{ "breachUsernameFound" | i18n: checkedUsername : breachedAccounts.length }}
|
||||
</bit-callout>
|
||||
<ul
|
||||
class="tw-list-none tw-flex-col tw-divide-x-0 tw-divide-y tw-divide-solid tw-divide-secondary-300 tw-rounded tw-border tw-border-solid tw-border-secondary-300 tw-p-0"
|
||||
*ngIf="breachedAccounts.length"
|
||||
>
|
||||
<li *ngFor="let a of breachedAccounts" class="tw-flex tw-gap-4 tw-p-4">
|
||||
<div class="tw-w-32 tw-flex-none">
|
||||
<img [src]="a.logoPath" alt="" class="tw-max-w-32 tw-items-stretch" />
|
||||
</div>
|
||||
<div class="tw-flex-auto">
|
||||
<h3 class="tw-text-lg">{{ a.title }}</h3>
|
||||
<p [innerHTML]="a.description"></p>
|
||||
<p class="tw-mb-1">{{ "compromisedData" | i18n }}:</p>
|
||||
<ul>
|
||||
<li *ngFor="let d of a.dataClasses">{{ d }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tw-w-48 tw-flex-none">
|
||||
<dl>
|
||||
<dt>{{ "website" | i18n }}</dt>
|
||||
<dd>{{ a.domain }}</dd>
|
||||
<dt>{{ "affectedUsers" | i18n }}</dt>
|
||||
<dd>{{ a.pwnCount | number }}</dd>
|
||||
<dt>{{ "breachOccurred" | i18n }}</dt>
|
||||
<dd>{{ a.breachDate | date: "mediumDate" }}</dd>
|
||||
<dt>{{ "breachReported" | i18n }}</dt>
|
||||
<dd>{{ a.addedDate | date: "mediumDate" }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</ng-container>
|
||||
</div>
|
||||
@if (!loading && checkedUsername) {
|
||||
<div class="tw-mt-4">
|
||||
@if (error) {
|
||||
<p>{{ "reportError" | i18n }}...</p>
|
||||
} @else {
|
||||
@if (!breachedAccounts.length) {
|
||||
<bit-callout type="success" title="{{ 'goodNews' | i18n }}">
|
||||
{{ "breachUsernameNotFound" | i18n: checkedUsername }}
|
||||
</bit-callout>
|
||||
} @else {
|
||||
<bit-callout type="danger" title="{{ 'breachFound' | i18n }}">
|
||||
{{ "breachUsernameFound" | i18n: checkedUsername : breachedAccounts.length }}
|
||||
</bit-callout>
|
||||
<ul
|
||||
class="tw-list-none tw-flex-col tw-divide-x-0 tw-divide-y tw-divide-solid tw-divide-secondary-300 tw-rounded tw-border tw-border-solid tw-border-secondary-300 tw-p-0"
|
||||
>
|
||||
@for (a of breachedAccounts; track a) {
|
||||
<li class="tw-flex tw-gap-4 tw-p-4">
|
||||
<div class="tw-w-32 tw-flex-none">
|
||||
<img [src]="a.logoPath" alt="" class="tw-max-w-32 tw-items-stretch" />
|
||||
</div>
|
||||
<div class="tw-flex-auto">
|
||||
<h3 class="tw-text-lg">{{ a.title }}</h3>
|
||||
<p [innerHTML]="a.description"></p>
|
||||
<p class="tw-mb-1">{{ "compromisedData" | i18n }}:</p>
|
||||
<ul>
|
||||
@for (d of a.dataClasses; track d) {
|
||||
<li>{{ d }}</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tw-w-48 tw-flex-none">
|
||||
<dl>
|
||||
<dt>{{ "website" | i18n }}</dt>
|
||||
<dd>{{ a.domain }}</dd>
|
||||
<dt>{{ "affectedUsers" | i18n }}</dt>
|
||||
<dd>{{ a.pwnCount | number }}</dd>
|
||||
<dt>{{ "breachOccurred" | i18n }}</dt>
|
||||
<dd>{{ a.breachDate | date: "mediumDate" }}</dd>
|
||||
<dt>{{ "breachReported" | i18n }}</dt>
|
||||
<dd>{{ a.addedDate | date: "mediumDate" }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</bit-container>
|
||||
|
||||
@@ -5,108 +5,119 @@
|
||||
<button type="submit" buttonType="primary" bitButton [loading]="loading" (click)="load()">
|
||||
{{ "checkExposedPasswords" | i18n }}
|
||||
</button>
|
||||
<div class="tw-mt-4" *ngIf="hasLoaded">
|
||||
<bit-callout type="success" title="{{ 'goodNews' | i18n }}" *ngIf="!ciphers.length">
|
||||
{{ "noExposedPasswords" | i18n }}
|
||||
</bit-callout>
|
||||
<ng-container *ngIf="ciphers.length">
|
||||
<bit-callout type="danger" title="{{ 'exposedPasswordsFound' | i18n }}" [useAlertRole]="true">
|
||||
{{ "exposedPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
|
||||
</bit-callout>
|
||||
|
||||
@if (showFilterToggle && !isAdminConsoleActive) {
|
||||
@if (canDisplayToggleGroup()) {
|
||||
<bit-toggle-group
|
||||
[selected]="filterOrgStatus$ | async"
|
||||
(selectedChange)="filterOrgToggle($event)"
|
||||
[attr.aria-label]="'addAccessFilter' | i18n"
|
||||
>
|
||||
<ng-container *ngFor="let status of filterStatus">
|
||||
<bit-toggle [value]="status">
|
||||
{{ getName(status) }}
|
||||
<span bitBadge variant="info"> {{ getCount(status) }} </span>
|
||||
</bit-toggle>
|
||||
</ng-container>
|
||||
</bit-toggle-group>
|
||||
} @else {
|
||||
<bit-chip-select
|
||||
[placeholderText]="chipSelectOptions[0].label"
|
||||
[options]="chipSelectOptions"
|
||||
[ngModel]="selectedFilterChip"
|
||||
(ngModelChange)="filterOrgToggleChipSelect($event)"
|
||||
fullWidth="true"
|
||||
></bit-chip-select>
|
||||
}
|
||||
}
|
||||
|
||||
<bit-table-scroll [dataSource]="dataSource" [rowSize]="75">
|
||||
<ng-container header>
|
||||
<th bitCell></th>
|
||||
<th bitCell bitSortable="name">{{ "name" | i18n }}</th>
|
||||
<th bitCell bitSortable="organizationId" *ngIf="!isAdminConsoleActive">
|
||||
{{ "owner" | i18n }}
|
||||
</th>
|
||||
<th bitCell class="tw-text-right" bitSortable="exposedXTimes">
|
||||
{{ "timesExposed" | i18n }}
|
||||
</th>
|
||||
</ng-container>
|
||||
<ng-template bitRowDef let-row>
|
||||
<td bitCell>
|
||||
<app-vault-icon [cipher]="row"></app-vault-icon>
|
||||
</td>
|
||||
<td bitCell>
|
||||
<ng-container *ngIf="!organization || canManageCipher(row); else cantManage">
|
||||
<a
|
||||
bitLink
|
||||
href="#"
|
||||
appStopClick
|
||||
(click)="selectCipher(row)"
|
||||
title="{{ 'editItemWithName' | i18n: row.name }}"
|
||||
>
|
||||
{{ row.name }}
|
||||
</a>
|
||||
</ng-container>
|
||||
<ng-template #cantManage>
|
||||
<span>{{ row.name }}</span>
|
||||
</ng-template>
|
||||
<ng-container *ngIf="!organization && row.organizationId">
|
||||
<i
|
||||
class="bwi bwi-collection-shared tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'shared' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "shared" | i18n }}</span>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="row.hasAttachments">
|
||||
<i
|
||||
class="bwi bwi-paperclip tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'attachments' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "attachments" | i18n }}</span>
|
||||
</ng-container>
|
||||
<br />
|
||||
<small>{{ row.subTitle }}</small>
|
||||
</td>
|
||||
<td bitCell *ngIf="!isAdminConsoleActive">
|
||||
<app-org-badge
|
||||
*ngIf="!organization"
|
||||
[disabled]="disabled"
|
||||
[organizationId]="row.organizationId"
|
||||
[organizationName]="row.organizationId | orgNameFromId: (organizations$ | async)"
|
||||
appStopProp
|
||||
@if (hasLoaded) {
|
||||
<div class="tw-mt-4">
|
||||
@if (!ciphers.length) {
|
||||
<bit-callout type="success" title="{{ 'goodNews' | i18n }}">
|
||||
{{ "noExposedPasswords" | i18n }}
|
||||
</bit-callout>
|
||||
} @else {
|
||||
<bit-callout
|
||||
type="danger"
|
||||
title="{{ 'exposedPasswordsFound' | i18n }}"
|
||||
[useAlertRole]="true"
|
||||
>
|
||||
{{ "exposedPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
|
||||
</bit-callout>
|
||||
@if (showFilterToggle && !isAdminConsoleActive) {
|
||||
@if (canDisplayToggleGroup()) {
|
||||
<bit-toggle-group
|
||||
[selected]="filterOrgStatus$ | async"
|
||||
(selectedChange)="filterOrgToggle($event)"
|
||||
[attr.aria-label]="'addAccessFilter' | i18n"
|
||||
>
|
||||
</app-org-badge>
|
||||
</td>
|
||||
<td bitCell class="tw-text-right">
|
||||
<span bitBadge variant="warning">
|
||||
{{ "exposedXTimes" | i18n: (row.exposedXTimes | number) }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-template>
|
||||
</bit-table-scroll>
|
||||
</ng-container>
|
||||
</div>
|
||||
@for (status of filterStatus; track status) {
|
||||
<bit-toggle [value]="status">
|
||||
{{ getName(status) }}
|
||||
<span bitBadge variant="info"> {{ getCount(status) }} </span>
|
||||
</bit-toggle>
|
||||
}
|
||||
</bit-toggle-group>
|
||||
} @else {
|
||||
<bit-chip-select
|
||||
[placeholderText]="chipSelectOptions[0].label"
|
||||
[options]="chipSelectOptions"
|
||||
[ngModel]="selectedFilterChip"
|
||||
(ngModelChange)="filterOrgToggleChipSelect($event)"
|
||||
fullWidth="true"
|
||||
></bit-chip-select>
|
||||
}
|
||||
}
|
||||
<bit-table-scroll [dataSource]="dataSource" [rowSize]="75">
|
||||
<ng-container header>
|
||||
<th bitCell></th>
|
||||
<th bitCell bitSortable="name">{{ "name" | i18n }}</th>
|
||||
@if (!isAdminConsoleActive) {
|
||||
<th bitCell bitSortable="organizationId">
|
||||
{{ "owner" | i18n }}
|
||||
</th>
|
||||
}
|
||||
<th bitCell class="tw-text-right" bitSortable="exposedXTimes">
|
||||
{{ "timesExposed" | i18n }}
|
||||
</th>
|
||||
</ng-container>
|
||||
<ng-template bitRowDef let-row>
|
||||
<td bitCell>
|
||||
<app-vault-icon [cipher]="row"></app-vault-icon>
|
||||
</td>
|
||||
<td bitCell>
|
||||
@if (!organization || canManageCipher(row)) {
|
||||
<a
|
||||
bitLink
|
||||
href="#"
|
||||
appStopClick
|
||||
(click)="selectCipher(row)"
|
||||
title="{{ 'editItemWithName' | i18n: row.name }}"
|
||||
>
|
||||
{{ row.name }}
|
||||
</a>
|
||||
} @else {
|
||||
<span>{{ row.name }}</span>
|
||||
}
|
||||
@if (!organization && row.organizationId) {
|
||||
<i
|
||||
class="bwi bwi-collection-shared tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'shared' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "shared" | i18n }}</span>
|
||||
}
|
||||
@if (row.hasAttachments) {
|
||||
<i
|
||||
class="bwi bwi-paperclip tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'attachments' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "attachments" | i18n }}</span>
|
||||
}
|
||||
<br />
|
||||
<small>{{ row.subTitle }}</small>
|
||||
</td>
|
||||
@if (!isAdminConsoleActive) {
|
||||
<td bitCell>
|
||||
@if (!organization) {
|
||||
<app-org-badge
|
||||
[disabled]="disabled"
|
||||
[organizationId]="row.organizationId"
|
||||
[organizationName]="
|
||||
row.organizationId | orgNameFromId: (organizations$ | async)
|
||||
"
|
||||
appStopProp
|
||||
>
|
||||
</app-org-badge>
|
||||
}
|
||||
</td>
|
||||
}
|
||||
<td bitCell class="tw-text-right">
|
||||
<span bitBadge variant="warning">
|
||||
{{ "exposedXTimes" | i18n: (row.exposedXTimes | number) }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-template>
|
||||
</bit-table-scroll>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</bit-container>
|
||||
|
||||
@@ -2,117 +2,124 @@
|
||||
|
||||
<bit-container>
|
||||
<p>{{ "inactive2faReportDesc" | i18n }}</p>
|
||||
<div *ngIf="!hasLoaded && loading">
|
||||
<i
|
||||
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||
title="{{ 'loading' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||
</div>
|
||||
<div class="tw-mt-4" *ngIf="hasLoaded">
|
||||
<bit-callout type="success" title="{{ 'goodNews' | i18n }}" *ngIf="!ciphers.length">
|
||||
{{ "noInactive2fa" | i18n }}
|
||||
</bit-callout>
|
||||
<ng-container *ngIf="ciphers.length">
|
||||
<bit-callout type="danger" title="{{ 'inactive2faFound' | i18n }}">
|
||||
{{ "inactive2faFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
|
||||
</bit-callout>
|
||||
|
||||
@if (showFilterToggle && !isAdminConsoleActive) {
|
||||
@if (canDisplayToggleGroup()) {
|
||||
<bit-toggle-group
|
||||
[selected]="filterOrgStatus$ | async"
|
||||
(selectedChange)="filterOrgToggle($event)"
|
||||
[attr.aria-label]="'addAccessFilter' | i18n"
|
||||
>
|
||||
<ng-container *ngFor="let status of filterStatus">
|
||||
<bit-toggle [value]="status">
|
||||
{{ getName(status) }}
|
||||
<span bitBadge variant="info"> {{ getCount(status) }} </span>
|
||||
</bit-toggle>
|
||||
</ng-container>
|
||||
</bit-toggle-group>
|
||||
} @else {
|
||||
<bit-chip-select
|
||||
[placeholderText]="chipSelectOptions[0].label"
|
||||
[options]="chipSelectOptions"
|
||||
[ngModel]="selectedFilterChip"
|
||||
(ngModelChange)="filterOrgToggleChipSelect($event)"
|
||||
fullWidth="true"
|
||||
></bit-chip-select>
|
||||
@if (!hasLoaded && loading) {
|
||||
<div>
|
||||
<i
|
||||
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||
title="{{ 'loading' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||
</div>
|
||||
} @else {
|
||||
<div class="tw-mt-4">
|
||||
@if (!ciphers.length) {
|
||||
<bit-callout type="success" title="{{ 'goodNews' | i18n }}">
|
||||
{{ "noInactive2fa" | i18n }}
|
||||
</bit-callout>
|
||||
} @else {
|
||||
<bit-callout type="danger" title="{{ 'inactive2faFound' | i18n }}">
|
||||
{{ "inactive2faFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
|
||||
</bit-callout>
|
||||
@if (showFilterToggle && !isAdminConsoleActive) {
|
||||
@if (canDisplayToggleGroup()) {
|
||||
<bit-toggle-group
|
||||
[selected]="filterOrgStatus$ | async"
|
||||
(selectedChange)="filterOrgToggle($event)"
|
||||
[attr.aria-label]="'addAccessFilter' | i18n"
|
||||
>
|
||||
@for (status of filterStatus; track status) {
|
||||
<bit-toggle [value]="status">
|
||||
{{ getName(status) }}
|
||||
<span bitBadge variant="info"> {{ getCount(status) }} </span>
|
||||
</bit-toggle>
|
||||
}
|
||||
</bit-toggle-group>
|
||||
} @else {
|
||||
<bit-chip-select
|
||||
[placeholderText]="chipSelectOptions[0].label"
|
||||
[options]="chipSelectOptions"
|
||||
[ngModel]="selectedFilterChip"
|
||||
(ngModelChange)="filterOrgToggleChipSelect($event)"
|
||||
fullWidth="true"
|
||||
></bit-chip-select>
|
||||
}
|
||||
}
|
||||
<bit-table-scroll [dataSource]="dataSource" [rowSize]="75">
|
||||
@if (!isAdminConsoleActive) {
|
||||
<ng-container header>
|
||||
<th bitCell></th>
|
||||
<th bitCell>{{ "name" | i18n }}</th>
|
||||
<th bitCell>{{ "owner" | i18n }}</th>
|
||||
<th bitCell></th>
|
||||
</ng-container>
|
||||
}
|
||||
<ng-template bitRowDef let-row>
|
||||
<td bitCell>
|
||||
<app-vault-icon [cipher]="row"></app-vault-icon>
|
||||
</td>
|
||||
<td bitCell>
|
||||
@if (!organization || canManageCipher(row)) {
|
||||
<ng-container>
|
||||
<a
|
||||
bitLink
|
||||
href="#"
|
||||
appStopClick
|
||||
(click)="selectCipher(row)"
|
||||
title="{{ 'editItemWithName' | i18n: row.name }}"
|
||||
>{{ row.name }}</a
|
||||
>
|
||||
</ng-container>
|
||||
} @else {
|
||||
<ng-template>
|
||||
<span>{{ row.name }}</span>
|
||||
</ng-template>
|
||||
}
|
||||
@if (!organization && row.organizationId) {
|
||||
<ng-container>
|
||||
<i
|
||||
class="bwi bwi-collection-shared tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'shared' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "shared" | i18n }}</span>
|
||||
</ng-container>
|
||||
}
|
||||
@if (row.hasAttachments) {
|
||||
<ng-container>
|
||||
<i
|
||||
class="bwi bwi-paperclip tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'attachments' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "attachments" | i18n }}</span>
|
||||
</ng-container>
|
||||
}
|
||||
<br />
|
||||
<small>{{ row.subTitle }}</small>
|
||||
</td>
|
||||
<td bitCell>
|
||||
@if (!organization) {
|
||||
<app-org-badge
|
||||
[disabled]="disabled"
|
||||
[organizationId]="row.organizationId"
|
||||
[organizationName]="row.organizationId | orgNameFromId: (organizations$ | async)"
|
||||
appStopProp
|
||||
/>
|
||||
}
|
||||
</td>
|
||||
<td bitCell class="tw-text-right">
|
||||
@if (cipherDocs.has(row.id)) {
|
||||
<a bitBadge href="{{ cipherDocs.get(row.id) }}" target="_blank" rel="noreferrer">
|
||||
{{ "instructions" | i18n }}</a
|
||||
>
|
||||
}
|
||||
</td>
|
||||
</ng-template>
|
||||
</bit-table-scroll>
|
||||
}
|
||||
|
||||
<bit-table-scroll [dataSource]="dataSource" [rowSize]="75">
|
||||
<ng-container header *ngIf="!isAdminConsoleActive">
|
||||
<th bitCell></th>
|
||||
<th bitCell>{{ "name" | i18n }}</th>
|
||||
<th bitCell>{{ "owner" | i18n }}</th>
|
||||
<th bitCell></th>
|
||||
</ng-container>
|
||||
<ng-template bitRowDef let-row>
|
||||
<td bitCell>
|
||||
<app-vault-icon [cipher]="row"></app-vault-icon>
|
||||
</td>
|
||||
<td bitCell>
|
||||
<ng-container *ngIf="!organization || canManageCipher(row); else cantManage">
|
||||
<a
|
||||
bitLink
|
||||
href="#"
|
||||
appStopClick
|
||||
(click)="selectCipher(row)"
|
||||
title="{{ 'editItemWithName' | i18n: row.name }}"
|
||||
>{{ row.name }}</a
|
||||
>
|
||||
</ng-container>
|
||||
<ng-template #cantManage>
|
||||
<span>{{ row.name }}</span>
|
||||
</ng-template>
|
||||
<ng-container *ngIf="!organization && row.organizationId">
|
||||
<i
|
||||
class="bwi bwi-collection-shared tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'shared' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "shared" | i18n }}</span>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="row.hasAttachments">
|
||||
<i
|
||||
class="bwi bwi-paperclip tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'attachments' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "attachments" | i18n }}</span>
|
||||
</ng-container>
|
||||
<br />
|
||||
<small>{{ row.subTitle }}</small>
|
||||
</td>
|
||||
<td bitCell>
|
||||
<app-org-badge
|
||||
*ngIf="!organization"
|
||||
[disabled]="disabled"
|
||||
[organizationId]="row.organizationId"
|
||||
[organizationName]="row.organizationId | orgNameFromId: (organizations$ | async)"
|
||||
appStopProp
|
||||
>
|
||||
</app-org-badge>
|
||||
</td>
|
||||
<td bitCell class="tw-text-right">
|
||||
<a
|
||||
bitBadge
|
||||
href="{{ cipherDocs.get(row.id) }}"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
*ngIf="cipherDocs.has(row.id)"
|
||||
>
|
||||
{{ "instructions" | i18n }}</a
|
||||
>
|
||||
</td>
|
||||
</ng-template>
|
||||
</bit-table-scroll>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</bit-container>
|
||||
|
||||
@@ -2,111 +2,115 @@
|
||||
|
||||
<bit-container>
|
||||
<p>{{ "reusedPasswordsReportDesc" | i18n }}</p>
|
||||
<div *ngIf="!hasLoaded && loading">
|
||||
<i
|
||||
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||
title="{{ 'loading' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||
</div>
|
||||
<div class="tw-mt-4" *ngIf="hasLoaded">
|
||||
<bit-callout type="success" title="{{ 'goodNews' | i18n }}" *ngIf="!ciphers.length">
|
||||
{{ "noReusedPasswords" | i18n }}
|
||||
</bit-callout>
|
||||
<ng-container *ngIf="ciphers.length">
|
||||
<bit-callout type="danger" title="{{ 'reusedPasswordsFound' | i18n }}">
|
||||
{{ "reusedPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
|
||||
</bit-callout>
|
||||
|
||||
@if (showFilterToggle && !isAdminConsoleActive) {
|
||||
@if (canDisplayToggleGroup()) {
|
||||
<bit-toggle-group
|
||||
[selected]="filterOrgStatus$ | async"
|
||||
(selectedChange)="filterOrgToggle($event)"
|
||||
[attr.aria-label]="'addAccessFilter' | i18n"
|
||||
>
|
||||
<ng-container *ngFor="let status of filterStatus">
|
||||
<bit-toggle [value]="status">
|
||||
{{ getName(status) }}
|
||||
<span bitBadge variant="info"> {{ getCount(status) }} </span>
|
||||
</bit-toggle>
|
||||
</ng-container>
|
||||
</bit-toggle-group>
|
||||
} @else {
|
||||
<bit-chip-select
|
||||
[placeholderText]="chipSelectOptions[0].label"
|
||||
[options]="chipSelectOptions"
|
||||
[ngModel]="selectedFilterChip"
|
||||
(ngModelChange)="filterOrgToggleChipSelect($event)"
|
||||
fullWidth="true"
|
||||
></bit-chip-select>
|
||||
}
|
||||
}
|
||||
|
||||
<bit-table-scroll [dataSource]="dataSource" [rowSize]="75">
|
||||
<ng-container header *ngIf="!isAdminConsoleActive">
|
||||
<th bitCell></th>
|
||||
<th bitCell>{{ "name" | i18n }}</th>
|
||||
<th bitCell>{{ "owner" | i18n }}</th>
|
||||
<th bitCell class="tw-text-right">{{ "timesReused" | i18n }}</th>
|
||||
</ng-container>
|
||||
<ng-template bitRowDef let-row>
|
||||
<td bitCell>
|
||||
<app-vault-icon [cipher]="row"></app-vault-icon>
|
||||
</td>
|
||||
<td bitCell>
|
||||
<ng-container *ngIf="!organization || canManageCipher(row); else cantManage">
|
||||
<a
|
||||
bitLink
|
||||
href="#"
|
||||
appStopClick
|
||||
(click)="selectCipher(row)"
|
||||
title="{{ 'editItemWithName' | i18n: row.name }}"
|
||||
>{{ row.name }}</a
|
||||
>
|
||||
</ng-container>
|
||||
<ng-template #cantManage>
|
||||
<span>{{ row.name }}</span>
|
||||
</ng-template>
|
||||
<ng-container *ngIf="!organization && row.organizationId">
|
||||
<i
|
||||
class="bwi bwi-collection-shared tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'shared' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "shared" | i18n }}</span>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="row.hasAttachments">
|
||||
<i
|
||||
class="bwi bwi-paperclip tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'attachments' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "attachments" | i18n }}</span>
|
||||
</ng-container>
|
||||
<br />
|
||||
<small>{{ row.subTitle }}</small>
|
||||
</td>
|
||||
<td bitCell>
|
||||
<app-org-badge
|
||||
*ngIf="!organization"
|
||||
[disabled]="disabled"
|
||||
[organizationId]="row.organizationId"
|
||||
[organizationName]="row.organizationId | orgNameFromId: (organizations$ | async)"
|
||||
appStopProp
|
||||
@if (!hasLoaded && loading) {
|
||||
<div>
|
||||
<i
|
||||
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||
title="{{ 'loading' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||
</div>
|
||||
} @else {
|
||||
<div class="tw-mt-4">
|
||||
@if (!ciphers.length) {
|
||||
<bit-callout type="success" title="{{ 'goodNews' | i18n }}">
|
||||
{{ "noReusedPasswords" | i18n }}
|
||||
</bit-callout>
|
||||
} @else {
|
||||
<bit-callout type="danger" title="{{ 'reusedPasswordsFound' | i18n }}">
|
||||
{{ "reusedPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
|
||||
</bit-callout>
|
||||
@if (showFilterToggle && !isAdminConsoleActive) {
|
||||
@if (canDisplayToggleGroup()) {
|
||||
<bit-toggle-group
|
||||
[selected]="filterOrgStatus$ | async"
|
||||
(selectedChange)="filterOrgToggle($event)"
|
||||
[attr.aria-label]="'addAccessFilter' | i18n"
|
||||
>
|
||||
</app-org-badge>
|
||||
</td>
|
||||
<td bitCell class="tw-text-right">
|
||||
<span bitBadge variant="warning">
|
||||
{{ "reusedXTimes" | i18n: passwordUseMap.get(row.login.password) }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-template>
|
||||
</bit-table-scroll>
|
||||
</ng-container>
|
||||
</div>
|
||||
@for (status of filterStatus; track status) {
|
||||
<bit-toggle [value]="status">
|
||||
{{ getName(status) }}
|
||||
<span bitBadge variant="info"> {{ getCount(status) }} </span>
|
||||
</bit-toggle>
|
||||
}
|
||||
</bit-toggle-group>
|
||||
} @else {
|
||||
<bit-chip-select
|
||||
[placeholderText]="chipSelectOptions[0].label"
|
||||
[options]="chipSelectOptions"
|
||||
[ngModel]="selectedFilterChip"
|
||||
(ngModelChange)="filterOrgToggleChipSelect($event)"
|
||||
fullWidth="true"
|
||||
></bit-chip-select>
|
||||
}
|
||||
}
|
||||
<bit-table-scroll [dataSource]="dataSource" [rowSize]="75">
|
||||
@if (!isAdminConsoleActive) {
|
||||
<ng-container header>
|
||||
<th bitCell></th>
|
||||
<th bitCell>{{ "name" | i18n }}</th>
|
||||
<th bitCell>{{ "owner" | i18n }}</th>
|
||||
<th bitCell class="tw-text-right">{{ "timesReused" | i18n }}</th>
|
||||
</ng-container>
|
||||
}
|
||||
<ng-template bitRowDef let-row>
|
||||
<td bitCell>
|
||||
<app-vault-icon [cipher]="row"></app-vault-icon>
|
||||
</td>
|
||||
<td bitCell>
|
||||
@if (!organization || canManageCipher(row)) {
|
||||
<a
|
||||
bitLink
|
||||
href="#"
|
||||
appStopClick
|
||||
(click)="selectCipher(row)"
|
||||
title="{{ 'editItemWithName' | i18n: row.name }}"
|
||||
>{{ row.name }}</a
|
||||
>
|
||||
} @else {
|
||||
<span>{{ row.name }}</span>
|
||||
}
|
||||
@if (!organization && row.organizationId) {
|
||||
<i
|
||||
class="bwi bwi-collection-shared tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'shared' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "shared" | i18n }}</span>
|
||||
}
|
||||
@if (row.hasAttachments) {
|
||||
<i
|
||||
class="bwi bwi-paperclip tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'attachments' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "attachments" | i18n }}</span>
|
||||
}
|
||||
<br />
|
||||
<small>{{ row.subTitle }}</small>
|
||||
</td>
|
||||
<td bitCell>
|
||||
@if (!organization) {
|
||||
<app-org-badge
|
||||
[disabled]="disabled"
|
||||
[organizationId]="row.organizationId"
|
||||
[organizationName]="row.organizationId | orgNameFromId: (organizations$ | async)"
|
||||
appStopProp
|
||||
>
|
||||
</app-org-badge>
|
||||
}
|
||||
</td>
|
||||
<td bitCell class="tw-text-right">
|
||||
<span bitBadge variant="warning">
|
||||
{{ "reusedXTimes" | i18n: passwordUseMap.get(row.login.password) }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-template>
|
||||
</bit-table-scroll>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</bit-container>
|
||||
|
||||
@@ -2,105 +2,109 @@
|
||||
|
||||
<bit-container>
|
||||
<p>{{ "unsecuredWebsitesReportDesc" | i18n }}</p>
|
||||
<div *ngIf="!hasLoaded && loading">
|
||||
<i
|
||||
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||
title="{{ 'loading' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||
</div>
|
||||
<div class="tw-mt-4" *ngIf="hasLoaded">
|
||||
<bit-callout type="success" title="{{ 'goodNews' | i18n }}" *ngIf="!ciphers.length">
|
||||
{{ "noUnsecuredWebsites" | i18n }}
|
||||
</bit-callout>
|
||||
<ng-container *ngIf="ciphers.length">
|
||||
<bit-callout type="danger" title="{{ 'unsecuredWebsitesFound' | i18n }}">
|
||||
{{ "unsecuredWebsitesFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
|
||||
</bit-callout>
|
||||
|
||||
@if (showFilterToggle && !isAdminConsoleActive) {
|
||||
@if (canDisplayToggleGroup()) {
|
||||
<bit-toggle-group
|
||||
[selected]="filterOrgStatus$ | async"
|
||||
(selectedChange)="filterOrgToggle($event)"
|
||||
[attr.aria-label]="'addAccessFilter' | i18n"
|
||||
>
|
||||
<ng-container *ngFor="let status of filterStatus">
|
||||
<bit-toggle [value]="status">
|
||||
{{ getName(status) }}
|
||||
<span bitBadge variant="info"> {{ getCount(status) }} </span>
|
||||
</bit-toggle>
|
||||
</ng-container>
|
||||
</bit-toggle-group>
|
||||
} @else {
|
||||
<bit-chip-select
|
||||
[placeholderText]="chipSelectOptions[0].label"
|
||||
[options]="chipSelectOptions"
|
||||
[ngModel]="selectedFilterChip"
|
||||
(ngModelChange)="filterOrgToggleChipSelect($event)"
|
||||
fullWidth="true"
|
||||
></bit-chip-select>
|
||||
}
|
||||
}
|
||||
|
||||
<bit-table-scroll [dataSource]="dataSource" [rowSize]="75">
|
||||
<ng-container header *ngIf="!isAdminConsoleActive">
|
||||
<th bitCell></th>
|
||||
<th bitCell>{{ "name" | i18n }}</th>
|
||||
<th bitCell>{{ "owner" | i18n }}</th>
|
||||
</ng-container>
|
||||
<ng-template bitRowDef let-row>
|
||||
<td bitCell>
|
||||
<app-vault-icon [cipher]="row"></app-vault-icon>
|
||||
</td>
|
||||
<td bitCell>
|
||||
<ng-container *ngIf="!organization || canManageCipher(row); else cantManage">
|
||||
<a
|
||||
bitLink
|
||||
href="#"
|
||||
appStopClick
|
||||
(click)="selectCipher(row)"
|
||||
title="{{ 'editItemWithName' | i18n: row.name }}"
|
||||
>{{ row.name }}</a
|
||||
>
|
||||
</ng-container>
|
||||
<ng-template #cantManage>
|
||||
<span>{{ row.name }}</span>
|
||||
</ng-template>
|
||||
<ng-container *ngIf="!organization && row.organizationId">
|
||||
<i
|
||||
class="bwi bwi-collection-shared tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'shared' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "shared" | i18n }}</span>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="row.hasAttachments">
|
||||
<i
|
||||
class="bwi bwi-paperclip tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'attachments' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "attachments" | i18n }}</span>
|
||||
</ng-container>
|
||||
<br />
|
||||
<small>{{ row.subTitle }}</small>
|
||||
</td>
|
||||
<td bitCell>
|
||||
<app-org-badge
|
||||
*ngIf="!organization"
|
||||
[disabled]="disabled"
|
||||
[organizationId]="row.organizationId"
|
||||
[organizationName]="row.organizationId | orgNameFromId: (organizations$ | async)"
|
||||
appStopProp
|
||||
@if (!hasLoaded && loading) {
|
||||
<div>
|
||||
<i
|
||||
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||
title="{{ 'loading' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||
</div>
|
||||
} @else {
|
||||
<div class="tw-mt-4">
|
||||
@if (!ciphers.length) {
|
||||
<bit-callout type="success" title="{{ 'goodNews' | i18n }}">
|
||||
{{ "noUnsecuredWebsites" | i18n }}
|
||||
</bit-callout>
|
||||
} @else {
|
||||
<bit-callout type="danger" title="{{ 'unsecuredWebsitesFound' | i18n }}">
|
||||
{{ "unsecuredWebsitesFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
|
||||
</bit-callout>
|
||||
@if (showFilterToggle && !isAdminConsoleActive) {
|
||||
@if (canDisplayToggleGroup()) {
|
||||
<bit-toggle-group
|
||||
[selected]="filterOrgStatus$ | async"
|
||||
(selectedChange)="filterOrgToggle($event)"
|
||||
[attr.aria-label]="'addAccessFilter' | i18n"
|
||||
>
|
||||
</app-org-badge>
|
||||
</td>
|
||||
</ng-template>
|
||||
</bit-table-scroll>
|
||||
</ng-container>
|
||||
</div>
|
||||
@for (status of filterStatus; track status) {
|
||||
<bit-toggle [value]="status">
|
||||
{{ getName(status) }}
|
||||
<span bitBadge variant="info"> {{ getCount(status) }} </span>
|
||||
</bit-toggle>
|
||||
}
|
||||
</bit-toggle-group>
|
||||
} @else {
|
||||
<bit-chip-select
|
||||
[placeholderText]="chipSelectOptions[0].label"
|
||||
[options]="chipSelectOptions"
|
||||
[ngModel]="selectedFilterChip"
|
||||
(ngModelChange)="filterOrgToggleChipSelect($event)"
|
||||
fullWidth="true"
|
||||
></bit-chip-select>
|
||||
}
|
||||
}
|
||||
<bit-table-scroll [dataSource]="dataSource" [rowSize]="75">
|
||||
@if (!isAdminConsoleActive) {
|
||||
<ng-container header>
|
||||
<th bitCell></th>
|
||||
<th bitCell>{{ "name" | i18n }}</th>
|
||||
<th bitCell>{{ "owner" | i18n }}</th>
|
||||
</ng-container>
|
||||
}
|
||||
<ng-template bitRowDef let-row>
|
||||
<td bitCell>
|
||||
<app-vault-icon [cipher]="row"></app-vault-icon>
|
||||
</td>
|
||||
<td bitCell>
|
||||
@if (!organization || canManageCipher(row)) {
|
||||
<a
|
||||
bitLink
|
||||
href="#"
|
||||
appStopClick
|
||||
(click)="selectCipher(row)"
|
||||
title="{{ 'editItemWithName' | i18n: row.name }}"
|
||||
>{{ row.name }}</a
|
||||
>
|
||||
} @else {
|
||||
<span>{{ row.name }}</span>
|
||||
}
|
||||
@if (!organization && row.organizationId) {
|
||||
<i
|
||||
class="bwi bwi-collection-shared tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'shared' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "shared" | i18n }}</span>
|
||||
}
|
||||
@if (row.hasAttachments) {
|
||||
<i
|
||||
class="bwi bwi-paperclip tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'attachments' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "attachments" | i18n }}</span>
|
||||
}
|
||||
<br />
|
||||
<small>{{ row.subTitle }}</small>
|
||||
</td>
|
||||
<td bitCell>
|
||||
@if (!organization) {
|
||||
<app-org-badge
|
||||
[disabled]="disabled"
|
||||
[organizationId]="row.organizationId"
|
||||
[organizationName]="row.organizationId | orgNameFromId: (organizations$ | async)"
|
||||
appStopProp
|
||||
>
|
||||
</app-org-badge>
|
||||
}
|
||||
</td>
|
||||
</ng-template>
|
||||
</bit-table-scroll>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</bit-container>
|
||||
|
||||
@@ -2,115 +2,123 @@
|
||||
|
||||
<bit-container>
|
||||
<p>{{ "weakPasswordsReportDesc" | i18n }}</p>
|
||||
<div *ngIf="!hasLoaded && loading">
|
||||
<i
|
||||
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||
title="{{ 'loading' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||
</div>
|
||||
<div class="tw-mt-4" *ngIf="hasLoaded">
|
||||
<bit-callout type="success" title="{{ 'goodNews' | i18n }}" *ngIf="!ciphers.length">
|
||||
{{ "noWeakPasswords" | i18n }}
|
||||
</bit-callout>
|
||||
<ng-container *ngIf="ciphers.length">
|
||||
<bit-callout type="danger" title="{{ 'weakPasswordsFound' | i18n }}">
|
||||
{{ "weakPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
|
||||
</bit-callout>
|
||||
|
||||
@if (showFilterToggle && !isAdminConsoleActive) {
|
||||
@if (canDisplayToggleGroup()) {
|
||||
<bit-toggle-group
|
||||
[selected]="filterOrgStatus$ | async"
|
||||
(selectedChange)="filterOrgToggle($event)"
|
||||
[attr.aria-label]="'addAccessFilter' | i18n"
|
||||
>
|
||||
<ng-container *ngFor="let status of filterStatus">
|
||||
<bit-toggle [value]="status">
|
||||
{{ getName(status) }}
|
||||
<span bitBadge variant="info"> {{ getCount(status) }} </span>
|
||||
</bit-toggle>
|
||||
</ng-container>
|
||||
</bit-toggle-group>
|
||||
} @else {
|
||||
<bit-chip-select
|
||||
[placeholderText]="chipSelectOptions[0].label"
|
||||
[options]="chipSelectOptions"
|
||||
[ngModel]="selectedFilterChip"
|
||||
(ngModelChange)="filterOrgToggleChipSelect($event)"
|
||||
fullWidth="true"
|
||||
></bit-chip-select>
|
||||
}
|
||||
}
|
||||
|
||||
<bit-table-scroll [dataSource]="dataSource" [rowSize]="75">
|
||||
<ng-container header>
|
||||
<th bitCell></th>
|
||||
<th bitCell bitSortable="name">{{ "name" | i18n }}</th>
|
||||
<th bitCell bitSortable="organizationId" *ngIf="!isAdminConsoleActive">
|
||||
{{ "owner" | i18n }}
|
||||
</th>
|
||||
<th bitCell class="tw-text-right" bitSortable="scoreKey" default>
|
||||
{{ "weakness" | i18n }}
|
||||
</th>
|
||||
</ng-container>
|
||||
<ng-template bitRowDef let-row>
|
||||
<td bitCell>
|
||||
<app-vault-icon [cipher]="row"></app-vault-icon>
|
||||
</td>
|
||||
<td bitCell>
|
||||
<ng-container *ngIf="!organization || canManageCipher(row); else cantManage">
|
||||
<a
|
||||
bitLink
|
||||
href="#"
|
||||
appStopClick
|
||||
(click)="selectCipher(row)"
|
||||
title="{{ 'editItemWithName' | i18n: row.name }}"
|
||||
>{{ row.name }}</a
|
||||
>
|
||||
</ng-container>
|
||||
<ng-template #cantManage>
|
||||
<span>{{ row.name }}</span>
|
||||
</ng-template>
|
||||
<ng-container *ngIf="!organization && row.organizationId">
|
||||
<i
|
||||
class="bwi bwi-collection-shared tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'shared' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "shared" | i18n }}</span>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="row.hasAttachments">
|
||||
<i
|
||||
class="bwi bwi-paperclip tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'attachments' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "attachments" | i18n }}</span>
|
||||
</ng-container>
|
||||
<br />
|
||||
<small>{{ row.subTitle }}</small>
|
||||
</td>
|
||||
<td bitCell *ngIf="!isAdminConsoleActive">
|
||||
<app-org-badge
|
||||
*ngIf="!organization"
|
||||
[disabled]="disabled"
|
||||
[organizationId]="row.organizationId"
|
||||
[organizationName]="row.organizationId | orgNameFromId: (organizations$ | async)"
|
||||
appStopProp
|
||||
@if (!hasLoaded && loading) {
|
||||
<div>
|
||||
<i
|
||||
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||
title="{{ 'loading' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||
</div>
|
||||
} @else {
|
||||
<div class="tw-mt-4">
|
||||
@if (!ciphers.length) {
|
||||
<bit-callout type="success" title="{{ 'goodNews' | i18n }}">
|
||||
{{ "noWeakPasswords" | i18n }}
|
||||
</bit-callout>
|
||||
} @else {
|
||||
<bit-callout type="danger" title="{{ 'weakPasswordsFound' | i18n }}">
|
||||
{{ "weakPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
|
||||
</bit-callout>
|
||||
@if (showFilterToggle && !isAdminConsoleActive) {
|
||||
@if (canDisplayToggleGroup()) {
|
||||
<bit-toggle-group
|
||||
[selected]="filterOrgStatus$ | async"
|
||||
(selectedChange)="filterOrgToggle($event)"
|
||||
[attr.aria-label]="'addAccessFilter' | i18n"
|
||||
>
|
||||
</app-org-badge>
|
||||
</td>
|
||||
<td bitCell class="tw-text-right">
|
||||
<span bitBadge [variant]="row.reportValue.badgeVariant">
|
||||
{{ row.reportValue.label | i18n }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-template>
|
||||
</bit-table-scroll>
|
||||
</ng-container>
|
||||
</div>
|
||||
@for (status of filterStatus; track status) {
|
||||
<bit-toggle [value]="status">
|
||||
{{ getName(status) }}
|
||||
<span bitBadge variant="info"> {{ getCount(status) }} </span>
|
||||
</bit-toggle>
|
||||
}
|
||||
</bit-toggle-group>
|
||||
} @else {
|
||||
<bit-chip-select
|
||||
[placeholderText]="chipSelectOptions[0].label"
|
||||
[options]="chipSelectOptions"
|
||||
[ngModel]="selectedFilterChip"
|
||||
(ngModelChange)="filterOrgToggleChipSelect($event)"
|
||||
fullWidth="true"
|
||||
></bit-chip-select>
|
||||
}
|
||||
}
|
||||
<bit-table-scroll [dataSource]="dataSource" [rowSize]="75">
|
||||
<ng-container header>
|
||||
<th bitCell></th>
|
||||
<th bitCell bitSortable="name">{{ "name" | i18n }}</th>
|
||||
@if (!isAdminConsoleActive) {
|
||||
<th bitCell bitSortable="organizationId">
|
||||
{{ "owner" | i18n }}
|
||||
</th>
|
||||
}
|
||||
<th bitCell class="tw-text-right" bitSortable="scoreKey" default>
|
||||
{{ "weakness" | i18n }}
|
||||
</th>
|
||||
</ng-container>
|
||||
<ng-template bitRowDef let-row>
|
||||
<td bitCell>
|
||||
<app-vault-icon [cipher]="row"></app-vault-icon>
|
||||
</td>
|
||||
<td bitCell>
|
||||
@if (!organization || canManageCipher(row)) {
|
||||
<a
|
||||
bitLink
|
||||
href="#"
|
||||
appStopClick
|
||||
(click)="selectCipher(row)"
|
||||
title="{{ 'editItemWithName' | i18n: row.name }}"
|
||||
>{{ row.name }}</a
|
||||
>
|
||||
} @else {
|
||||
<span>{{ row.name }}</span>
|
||||
}
|
||||
@if (!organization && row.organizationId) {
|
||||
<i
|
||||
class="bwi bwi-collection-shared tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'shared' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "shared" | i18n }}</span>
|
||||
}
|
||||
@if (row.hasAttachments) {
|
||||
<i
|
||||
class="bwi bwi-paperclip tw-ml-1"
|
||||
appStopProp
|
||||
title="{{ 'attachments' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "attachments" | i18n }}</span>
|
||||
}
|
||||
<br />
|
||||
<small>{{ row.subTitle }}</small>
|
||||
</td>
|
||||
@if (!isAdminConsoleActive) {
|
||||
<td bitCell>
|
||||
@if (!organization) {
|
||||
<app-org-badge
|
||||
[disabled]="disabled"
|
||||
[organizationId]="row.organizationId"
|
||||
[organizationName]="
|
||||
row.organizationId | orgNameFromId: (organizations$ | async)
|
||||
"
|
||||
appStopProp
|
||||
>
|
||||
</app-org-badge>
|
||||
}
|
||||
</td>
|
||||
}
|
||||
<td bitCell class="tw-text-right">
|
||||
<span bitBadge [variant]="row.reportValue.badgeVariant">
|
||||
{{ row.reportValue.label | i18n }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-template>
|
||||
</bit-table-scroll>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</bit-container>
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<div
|
||||
class="tw-inline-grid tw-place-items-stretch tw-place-content-center tw-grid-cols-1 @xl:tw-grid-cols-2 @4xl:tw-grid-cols-3 tw-gap-4 [&_a]:tw-max-w-none @5xl:[&_a]:tw-max-w-72"
|
||||
>
|
||||
<div *ngFor="let report of reports">
|
||||
<app-report-card
|
||||
[title]="report.title | i18n"
|
||||
[description]="report.description | i18n"
|
||||
[route]="report.route"
|
||||
[variant]="report.variant"
|
||||
[icon]="report.icon"
|
||||
></app-report-card>
|
||||
</div>
|
||||
@for (report of reports; track report) {
|
||||
<div>
|
||||
<app-report-card
|
||||
[title]="report.title | i18n"
|
||||
[description]="report.description | i18n"
|
||||
[route]="report.route"
|
||||
[variant]="report.variant"
|
||||
[icon]="report.icon"
|
||||
></app-report-card>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, EventEmitter, Input, Output } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
|
||||
@@ -10,7 +9,7 @@ import { ButtonModule, ButtonType, LinkModule, TypographyModule } from "@bitward
|
||||
@Component({
|
||||
selector: "dirt-activity-card",
|
||||
templateUrl: "./activity-card.component.html",
|
||||
imports: [CommonModule, TypographyModule, JslibModule, LinkModule, ButtonModule],
|
||||
imports: [TypographyModule, JslibModule, LinkModule, ButtonModule],
|
||||
host: {
|
||||
class:
|
||||
"tw-box-border tw-bg-background tw-block tw-text-main tw-border-solid tw-border tw-border-secondary-300 tw-border [&:not(bit-layout_*)]:tw-rounded-lg tw-rounded-lg tw-p-6 tw-min-h-56 tw-overflow-hidden",
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
@@ -44,7 +43,7 @@ export type PasswordChangeView = (typeof PasswordChangeView)[keyof typeof Passwo
|
||||
@Component({
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
selector: "dirt-password-change-metric",
|
||||
imports: [CommonModule, TypographyModule, JslibModule, ProgressModule, ButtonModule],
|
||||
imports: [TypographyModule, JslibModule, ProgressModule, ButtonModule],
|
||||
templateUrl: "./password-change-metric.component.html",
|
||||
})
|
||||
export class PasswordChangeMetricComponent implements OnInit {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { ChangeDetectionStrategy, Component, input } from "@angular/core";
|
||||
|
||||
import {
|
||||
@@ -25,7 +24,6 @@ import { DarkImageSourceDirective } from "@bitwarden/vault";
|
||||
selector: "dirt-assign-tasks-view",
|
||||
templateUrl: "./assign-tasks-view.component.html",
|
||||
imports: [
|
||||
CommonModule,
|
||||
ButtonModule,
|
||||
TypographyModule,
|
||||
I18nPipe,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
@@ -79,7 +78,6 @@ export type NewApplicationsDialogResultType =
|
||||
selector: "dirt-new-applications-dialog",
|
||||
templateUrl: "./new-applications-dialog.component.html",
|
||||
imports: [
|
||||
CommonModule,
|
||||
ButtonModule,
|
||||
DialogModule,
|
||||
TypographyModule,
|
||||
|
||||
@@ -6,12 +6,11 @@
|
||||
{{ title() }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="tw-text-main tw-text-sm sm:tw-text-base tw-font-normal tw-leading-normal"
|
||||
*ngIf="description()"
|
||||
>
|
||||
{{ description() }}
|
||||
</div>
|
||||
@if (description()) {
|
||||
<div class="tw-text-main tw-text-sm sm:tw-text-base tw-font-normal tw-leading-normal">
|
||||
{{ description() }}
|
||||
</div>
|
||||
}
|
||||
@if (benefits().length > 0) {
|
||||
<div class="tw-flex tw-flex-col tw-gap-4 sm:tw-gap-5">
|
||||
@for (benefit of benefits(); track $index) {
|
||||
@@ -38,69 +37,74 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="tw-flex tw-justify-start" *ngIf="buttonText() && buttonAction()">
|
||||
<button
|
||||
(click)="buttonAction()()"
|
||||
bitButton
|
||||
buttonType="primary"
|
||||
type="button"
|
||||
class="tw-px-3 tw-py-1.5 sm:tw-px-4 tw-rounded-full tw-text-sm sm:tw-text-base"
|
||||
>
|
||||
<i [class]="buttonIcon() + ' tw-mr-2'" *ngIf="buttonIcon()"></i>
|
||||
{{ buttonText() }}
|
||||
</button>
|
||||
</div>
|
||||
@if (buttonText() && buttonAction()) {
|
||||
<div class="tw-flex tw-justify-start">
|
||||
<button
|
||||
(click)="buttonAction()()"
|
||||
bitButton
|
||||
buttonType="primary"
|
||||
type="button"
|
||||
class="tw-px-3 tw-py-1.5 sm:tw-px-4 tw-rounded-full tw-text-sm sm:tw-text-base"
|
||||
>
|
||||
@if (buttonIcon()) {
|
||||
<i [class]="buttonIcon() + ' tw-mr-2'"></i>
|
||||
}
|
||||
{{ buttonText() }}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="tw-hidden lg:tw-block tw-flex-shrink-0" *ngIf="videoSrc() || icon()">
|
||||
<div class="tw-size-64 xl:tw-size-80 tw-relative">
|
||||
@if (videoSrc()) {
|
||||
<video
|
||||
class="tw-size-full tw-rounded-lg"
|
||||
[src]="videoSrc()"
|
||||
autoplay
|
||||
loop
|
||||
muted
|
||||
playsinline
|
||||
aria-hidden="true"
|
||||
></video>
|
||||
} @else if (icon()) {
|
||||
<div
|
||||
class="tw-size-full tw-flex tw-items-center tw-justify-center tw-bg-secondary-100 tw-rounded-lg"
|
||||
>
|
||||
<bit-svg
|
||||
[content]="icon()"
|
||||
class="tw-size-16 xl:tw-size-24 tw-text-muted"
|
||||
@if (videoSrc() || icon()) {
|
||||
<div class="tw-hidden lg:tw-block tw-flex-shrink-0">
|
||||
<div class="tw-size-64 xl:tw-size-80 tw-relative">
|
||||
@if (videoSrc()) {
|
||||
<video
|
||||
class="tw-size-full tw-rounded-lg"
|
||||
[src]="videoSrc()"
|
||||
autoplay
|
||||
loop
|
||||
muted
|
||||
playsinline
|
||||
aria-hidden="true"
|
||||
></bit-svg>
|
||||
</div>
|
||||
}
|
||||
></video>
|
||||
} @else if (icon()) {
|
||||
<div
|
||||
class="tw-size-full tw-flex tw-items-center tw-justify-center tw-bg-secondary-100 tw-rounded-lg"
|
||||
>
|
||||
<bit-svg
|
||||
[content]="icon()"
|
||||
class="tw-size-16 xl:tw-size-24 tw-text-muted"
|
||||
aria-hidden="true"
|
||||
></bit-svg>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tw-flex lg:tw-hidden tw-w-full tw-justify-center" *ngIf="videoSrc() || icon()">
|
||||
<div class="tw-size-48 sm:tw-size-64 tw-relative">
|
||||
@if (videoSrc()) {
|
||||
<video
|
||||
class="tw-size-full tw-rounded-lg"
|
||||
[src]="videoSrc()"
|
||||
autoplay
|
||||
loop
|
||||
muted
|
||||
playsinline
|
||||
aria-hidden="true"
|
||||
></video>
|
||||
} @else if (icon()) {
|
||||
<div
|
||||
class="tw-size-full tw-flex tw-items-center tw-justify-center tw-bg-secondary-100 tw-rounded-lg"
|
||||
>
|
||||
<bit-svg
|
||||
[content]="icon()"
|
||||
class="tw-size-12 sm:tw-size-16 tw-text-muted"
|
||||
<div class="tw-flex lg:tw-hidden tw-w-full tw-justify-center">
|
||||
<div class="tw-size-48 sm:tw-size-64 tw-relative">
|
||||
@if (videoSrc()) {
|
||||
<video
|
||||
class="tw-size-full tw-rounded-lg"
|
||||
[src]="videoSrc()"
|
||||
autoplay
|
||||
loop
|
||||
muted
|
||||
playsinline
|
||||
aria-hidden="true"
|
||||
></bit-svg>
|
||||
</div>
|
||||
}
|
||||
></video>
|
||||
} @else if (icon()) {
|
||||
<div
|
||||
class="tw-size-full tw-flex tw-items-center tw-justify-center tw-bg-secondary-100 tw-rounded-lg"
|
||||
>
|
||||
<bit-svg
|
||||
[content]="icon()"
|
||||
class="tw-size-12 sm:tw-size-16 tw-text-muted"
|
||||
aria-hidden="true"
|
||||
></bit-svg>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { ChangeDetectionStrategy, Component, input, isDevMode, OnInit } from "@angular/core";
|
||||
|
||||
import { BitSvg } from "@bitwarden/assets/svg";
|
||||
@@ -7,7 +6,7 @@ import { ButtonModule, SvgModule } from "@bitwarden/components";
|
||||
@Component({
|
||||
selector: "empty-state-card",
|
||||
templateUrl: "./empty-state-card.component.html",
|
||||
imports: [CommonModule, SvgModule, ButtonModule],
|
||||
imports: [SvgModule, ButtonModule],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class EmptyStateCardComponent implements OnInit {
|
||||
|
||||
@@ -44,10 +44,11 @@
|
||||
<!-- Show screen when there is report data OR when feature flag is disabled (show tabs even without data) -->
|
||||
<div @fadeIn class="tw-min-h-screen tw-flex tw-flex-col">
|
||||
<div>
|
||||
<div class="tw-text-main tw-max-w-4xl tw-mb-2" *ngIf="appsCount > 0">
|
||||
{{ "reviewAtRiskPasswords" | i18n }}
|
||||
</div>
|
||||
@let isRunningReport = dataService.isGeneratingReport$ | async;
|
||||
@if (appsCount > 0) {
|
||||
<div class="tw-text-main tw-max-w-4xl tw-mb-2">
|
||||
{{ "reviewAtRiskPasswords" | i18n }}
|
||||
</div>
|
||||
}
|
||||
<div
|
||||
class="tw-bg-primary-100 tw-rounded-lg tw-w-full tw-px-8 tw-py-4 tw-my-4 tw-flex tw-items-center"
|
||||
>
|
||||
@@ -62,7 +63,6 @@
|
||||
}
|
||||
<span class="tw-flex tw-justify-center">
|
||||
<button
|
||||
*ngIf="!isRunningReport"
|
||||
type="button"
|
||||
bitButton
|
||||
buttonType="secondary"
|
||||
@@ -72,13 +72,6 @@
|
||||
>
|
||||
{{ "riskInsightsRunReport" | i18n }}
|
||||
</button>
|
||||
<span>
|
||||
<i
|
||||
*ngIf="isRunningReport"
|
||||
class="bwi bwi-spinner bwi-spin tw-text-muted tw-text-[1.2rem]"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,28 +12,32 @@
|
||||
<th bitSortable="memberCount" bitCell tabindex="0">{{ "totalMembers" | i18n }}</th>
|
||||
</ng-container>
|
||||
<ng-template bitRowDef let-row>
|
||||
<td
|
||||
bitCell
|
||||
*ngIf="showRowCheckBox"
|
||||
[ngClass]="{ 'tw-bg-primary-100': row.applicationName === openApplication }"
|
||||
appStopProp
|
||||
>
|
||||
<input
|
||||
bitCheckbox
|
||||
type="checkbox"
|
||||
*ngIf="!row.isMarkedAsCritical"
|
||||
[checked]="selectedUrls.has(row.applicationName)"
|
||||
(change)="checkboxChange(row.applicationName, $event)"
|
||||
/>
|
||||
<i class="bwi bwi-star-f" *ngIf="row.isMarkedAsCritical"></i>
|
||||
</td>
|
||||
<td
|
||||
bitCell
|
||||
*ngIf="!showRowCheckBox"
|
||||
[ngClass]="{ 'tw-bg-primary-100': row.applicationName === openApplication }"
|
||||
>
|
||||
<i class="bwi bwi-star-f" *ngIf="row.isMarkedAsCritical"></i>
|
||||
</td>
|
||||
@if (showRowCheckBox) {
|
||||
<td
|
||||
bitCell
|
||||
[ngClass]="{ 'tw-bg-primary-100': row.applicationName === openApplication }"
|
||||
appStopProp
|
||||
>
|
||||
@if (!row.isMarkedAsCritical) {
|
||||
<input
|
||||
bitCheckbox
|
||||
type="checkbox"
|
||||
[checked]="selectedUrls.has(row.applicationName)"
|
||||
(change)="checkboxChange(row.applicationName, $event)"
|
||||
/>
|
||||
}
|
||||
@if (row.isMarkedAsCritical) {
|
||||
<i class="bwi bwi-star-f"></i>
|
||||
}
|
||||
</td>
|
||||
}
|
||||
@if (!showRowCheckBox) {
|
||||
<td bitCell [ngClass]="{ 'tw-bg-primary-100': row.applicationName === openApplication }">
|
||||
@if (row.isMarkedAsCritical) {
|
||||
<i class="bwi bwi-star-f"></i>
|
||||
}
|
||||
</td>
|
||||
}
|
||||
<td
|
||||
bitCell
|
||||
class="tw-cursor-pointer"
|
||||
@@ -45,11 +49,9 @@
|
||||
tabindex="0"
|
||||
[attr.aria-label]="'viewItem' | i18n"
|
||||
>
|
||||
<app-vault-icon
|
||||
*ngIf="row.iconCipher"
|
||||
[cipher]="row.iconCipher"
|
||||
[size]="24"
|
||||
></app-vault-icon>
|
||||
@if (row.iconCipher) {
|
||||
<app-vault-icon [cipher]="row.iconCipher" [size]="24"></app-vault-icon>
|
||||
}
|
||||
</td>
|
||||
<td
|
||||
class="tw-cursor-pointer"
|
||||
@@ -122,27 +124,27 @@
|
||||
>
|
||||
{{ row.memberCount }}
|
||||
</td>
|
||||
<td
|
||||
bitCell
|
||||
*ngIf="showRowMenuForCriticalApps"
|
||||
[ngClass]="{ 'tw-bg-primary-100': row.applicationName === openApplication }"
|
||||
appStopProp
|
||||
>
|
||||
<button
|
||||
[bitMenuTriggerFor]="rowMenu"
|
||||
type="button"
|
||||
bitIconButton="bwi-ellipsis-v"
|
||||
size="small"
|
||||
label="{{ 'options' | i18n }}"
|
||||
tabindex="0"
|
||||
></button>
|
||||
|
||||
<bit-menu #rowMenu>
|
||||
<button type="button" bitMenuItem (click)="unmarkAsCritical(row.applicationName)">
|
||||
{{ "unmarkAsCritical" | i18n }}
|
||||
</button>
|
||||
</bit-menu>
|
||||
</td>
|
||||
@if (showRowMenuForCriticalApps) {
|
||||
<td
|
||||
bitCell
|
||||
[ngClass]="{ 'tw-bg-primary-100': row.applicationName === openApplication }"
|
||||
appStopProp
|
||||
>
|
||||
<button
|
||||
[bitMenuTriggerFor]="rowMenu"
|
||||
type="button"
|
||||
bitIconButton="bwi-ellipsis-v"
|
||||
size="small"
|
||||
label="{{ 'options' | i18n }}"
|
||||
tabindex="0"
|
||||
></button>
|
||||
<bit-menu #rowMenu>
|
||||
<button type="button" bitMenuItem (click)="unmarkAsCritical(row.applicationName)">
|
||||
{{ "unmarkAsCritical" | i18n }}
|
||||
</button>
|
||||
</bit-menu>
|
||||
</td>
|
||||
}
|
||||
</ng-template>
|
||||
</bit-table-scroll>
|
||||
</ng-container>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, input } from "@angular/core";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
@@ -19,7 +18,7 @@ const ProgressStepConfig = Object.freeze({
|
||||
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
|
||||
@Component({
|
||||
selector: "dirt-report-loading",
|
||||
imports: [CommonModule, JslibModule, ProgressModule],
|
||||
imports: [JslibModule, ProgressModule],
|
||||
templateUrl: "./report-loading.component.html",
|
||||
})
|
||||
export class ReportLoadingComponent {
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
<ul
|
||||
class="tw-inline-grid tw-grid-cols-3 tw-gap-6 tw-m-0 tw-p-0 tw-w-full tw-auto-cols-auto tw-list-none lg:tw-grid-cols-4 lg:tw-gap-10 lg:tw-w-auto"
|
||||
>
|
||||
<li
|
||||
*ngFor="let integration of integrations"
|
||||
[title]="tooltipI18nKey | i18n: integration.name"
|
||||
[attr.aria-label]="ariaI18nKey | i18n: integration.name"
|
||||
>
|
||||
<app-integration-card
|
||||
[name]="integration.name"
|
||||
[linkURL]="integration.linkURL"
|
||||
[image]="integration.image"
|
||||
[imageDarkMode]="integration.imageDarkMode"
|
||||
[externalURL]="integration.type === IntegrationType.SDK"
|
||||
[newBadgeExpiration]="integration.newBadgeExpiration"
|
||||
[description]="integration.description | i18n"
|
||||
[canSetupConnection]="integration.canSetupConnection"
|
||||
[integrationSettings]="integration"
|
||||
></app-integration-card>
|
||||
</li>
|
||||
@for (integration of integrations; track integration) {
|
||||
<li
|
||||
[title]="tooltipI18nKey | i18n: integration.name"
|
||||
[attr.aria-label]="ariaI18nKey | i18n: integration.name"
|
||||
>
|
||||
<app-integration-card
|
||||
[name]="integration.name"
|
||||
[linkURL]="integration.linkURL"
|
||||
[image]="integration.image"
|
||||
[imageDarkMode]="integration.imageDarkMode"
|
||||
[externalURL]="integration.type === IntegrationType.SDK"
|
||||
[newBadgeExpiration]="integration.newBadgeExpiration"
|
||||
[description]="integration.description | i18n"
|
||||
[canSetupConnection]="integration.canSetupConnection"
|
||||
[integrationSettings]="integration"
|
||||
></app-integration-card>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
|
||||
@@ -24,28 +24,32 @@
|
||||
|
||||
@if (organization?.useScim || organization?.useDirectory) {
|
||||
<bit-tab [label]="'userProvisioning' | i18n">
|
||||
<section class="tw-mb-9" *ngIf="organization?.useScim">
|
||||
<h2 bitTypography="h2">
|
||||
{{ "scimIntegration" | i18n }}
|
||||
</h2>
|
||||
<p bitTypography="body1">
|
||||
{{ "scimIntegrationDescStart" | i18n }}
|
||||
<a bitLink routerLink="../settings/scim">{{ "scimIntegration" | i18n }}</a>
|
||||
{{ "scimIntegrationDescEnd" | i18n }}
|
||||
</p>
|
||||
<app-integration-grid
|
||||
[integrations]="integrationsList | filterIntegrations: IntegrationType.SCIM"
|
||||
></app-integration-grid>
|
||||
</section>
|
||||
<section class="tw-mb-9" *ngIf="organization?.useDirectory">
|
||||
<h2 bitTypography="h2">
|
||||
{{ "bwdc" | i18n }}
|
||||
</h2>
|
||||
<p bitTypography="body1">{{ "bwdcDesc" | i18n }}</p>
|
||||
<app-integration-grid
|
||||
[integrations]="integrationsList | filterIntegrations: IntegrationType.BWDC"
|
||||
></app-integration-grid>
|
||||
</section>
|
||||
@if (organization?.useScim) {
|
||||
<section class="tw-mb-9">
|
||||
<h2 bitTypography="h2">
|
||||
{{ "scimIntegration" | i18n }}
|
||||
</h2>
|
||||
<p bitTypography="body1">
|
||||
{{ "scimIntegrationDescStart" | i18n }}
|
||||
<a bitLink routerLink="../settings/scim">{{ "scimIntegration" | i18n }}</a>
|
||||
{{ "scimIntegrationDescEnd" | i18n }}
|
||||
</p>
|
||||
<app-integration-grid
|
||||
[integrations]="integrationsList | filterIntegrations: IntegrationType.SCIM"
|
||||
></app-integration-grid>
|
||||
</section>
|
||||
}
|
||||
@if (organization?.useDirectory) {
|
||||
<section class="tw-mb-9">
|
||||
<h2 bitTypography="h2">
|
||||
{{ "bwdc" | i18n }}
|
||||
</h2>
|
||||
<p bitTypography="body1">{{ "bwdcDesc" | i18n }}</p>
|
||||
<app-integration-grid
|
||||
[integrations]="integrationsList | filterIntegrations: IntegrationType.BWDC"
|
||||
></app-integration-grid>
|
||||
</section>
|
||||
}
|
||||
</bit-tab>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
<app-header>
|
||||
<bit-search
|
||||
[formControl]="searchControl"
|
||||
[placeholder]="'searchMembers' | i18n"
|
||||
class="tw-grow"
|
||||
*ngIf="!(isLoading$ | async)"
|
||||
></bit-search>
|
||||
@let isLoading = isLoading$ | async;
|
||||
|
||||
<button
|
||||
type="button"
|
||||
bitButton
|
||||
buttonType="primary"
|
||||
[bitAction]="exportReportAction"
|
||||
*ngIf="!(isLoading$ | async)"
|
||||
>
|
||||
<span>{{ "export" | i18n }}</span>
|
||||
<i class="bwi bwi-fw bwi-sign-in" aria-hidden="true"></i>
|
||||
</button>
|
||||
@if (!isLoading) {
|
||||
<bit-search
|
||||
[formControl]="searchControl"
|
||||
[placeholder]="'searchMembers' | i18n"
|
||||
class="tw-grow"
|
||||
></bit-search>
|
||||
<button type="button" bitButton buttonType="primary" [bitAction]="exportReportAction">
|
||||
<span>{{ "export" | i18n }}</span>
|
||||
<i class="bwi bwi-fw bwi-sign-in" aria-hidden="true"></i>
|
||||
</button>
|
||||
}
|
||||
</app-header>
|
||||
|
||||
<div class="tw-max-w-4xl">
|
||||
@@ -24,7 +20,7 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="isLoading$ | async">
|
||||
@if (isLoading) {
|
||||
<div class="tw-flex-col tw-flex tw-justify-center tw-items-center tw-gap-5 tw-mt-4">
|
||||
<i
|
||||
class="bwi bwi-2x bwi-spinner bwi-spin tw-text-primary-600"
|
||||
@@ -33,31 +29,33 @@
|
||||
></i>
|
||||
<h2 bitTypography="h1">{{ "loading" | i18n }}</h2>
|
||||
</div>
|
||||
</ng-container>
|
||||
<bit-table-scroll *ngIf="!(isLoading$ | async)" [dataSource]="dataSource" [rowSize]="53">
|
||||
<ng-container header>
|
||||
<th bitCell bitSortable="email" default>{{ "members" | i18n }}</th>
|
||||
<th bitCell bitSortable="groupsCount" class="tw-w-[278px]">{{ "groups" | i18n }}</th>
|
||||
<th bitCell bitSortable="collectionsCount" class="tw-w-[278px]">{{ "collections" | i18n }}</th>
|
||||
<th bitCell bitSortable="itemsCount" class="tw-w-[278px]">{{ "items" | i18n }}</th>
|
||||
</ng-container>
|
||||
<ng-template bitRowDef let-row>
|
||||
<td bitCell>
|
||||
<div class="tw-flex tw-items-center">
|
||||
<bit-avatar size="small" [text]="row.name" class="tw-mr-3"></bit-avatar>
|
||||
<div class="tw-flex tw-flex-col">
|
||||
<button type="button" bitLink (click)="edit(row)">
|
||||
{{ row.name }}
|
||||
</button>
|
||||
|
||||
<div class="tw-text-sm tw-mt-1 tw-text-muted">
|
||||
{{ row.email }}
|
||||
} @else {
|
||||
<bit-table-scroll [dataSource]="dataSource" [rowSize]="53">
|
||||
<ng-container header>
|
||||
<th bitCell bitSortable="email" default>{{ "members" | i18n }}</th>
|
||||
<th bitCell bitSortable="groupsCount" class="tw-w-[278px]">{{ "groups" | i18n }}</th>
|
||||
<th bitCell bitSortable="collectionsCount" class="tw-w-[278px]">
|
||||
{{ "collections" | i18n }}
|
||||
</th>
|
||||
<th bitCell bitSortable="itemsCount" class="tw-w-[278px]">{{ "items" | i18n }}</th>
|
||||
</ng-container>
|
||||
<ng-template bitRowDef let-row>
|
||||
<td bitCell>
|
||||
<div class="tw-flex tw-items-center">
|
||||
<bit-avatar size="small" [text]="row.name" class="tw-mr-3"></bit-avatar>
|
||||
<div class="tw-flex tw-flex-col">
|
||||
<button type="button" bitLink (click)="edit(row)">
|
||||
{{ row.name }}
|
||||
</button>
|
||||
<div class="tw-text-sm tw-mt-1 tw-text-muted">
|
||||
{{ row.email }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td bitCell class="tw-text-muted tw-w-[278px]">{{ row.groupsCount }}</td>
|
||||
<td bitCell class="tw-text-muted tw-w-[278px]">{{ row.collectionsCount }}</td>
|
||||
<td bitCell class="tw-text-muted tw-w-[278px]">{{ row.itemsCount }}</td>
|
||||
</ng-template>
|
||||
</bit-table-scroll>
|
||||
</td>
|
||||
<td bitCell class="tw-text-muted tw-w-[278px]">{{ row.groupsCount }}</td>
|
||||
<td bitCell class="tw-text-muted tw-w-[278px]">{{ row.collectionsCount }}</td>
|
||||
<td bitCell class="tw-text-muted tw-w-[278px]">{{ row.itemsCount }}</td>
|
||||
</ng-template>
|
||||
</bit-table-scroll>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user