mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-22 11:45:59 +01:00
Create initial 'Members' tab
This commit is contained in:
parent
f878fb0cb6
commit
24bb775a4c
@ -28,24 +28,24 @@ import { FrontendLayoutComponent } from "../layouts/frontend-layout.component";
|
|||||||
import { NavbarComponent } from "../layouts/navbar.component";
|
import { NavbarComponent } from "../layouts/navbar.component";
|
||||||
import { UserLayoutComponent } from "../layouts/user-layout.component";
|
import { UserLayoutComponent } from "../layouts/user-layout.component";
|
||||||
import { OrganizationLayoutComponent } from "../organizations/layouts/organization-layout.component";
|
import { OrganizationLayoutComponent } from "../organizations/layouts/organization-layout.component";
|
||||||
import { BulkConfirmComponent as OrgBulkConfirmComponent } from "../organizations/manage/bulk/bulk-confirm.component";
|
|
||||||
import { BulkDeactivateComponent as OrgBulkDeactivateomponent } from "../organizations/manage/bulk/bulk-deactivate.component";
|
|
||||||
import { BulkRemoveComponent as OrgBulkRemoveComponent } from "../organizations/manage/bulk/bulk-remove.component";
|
|
||||||
import { BulkStatusComponent as OrgBulkStatusComponent } from "../organizations/manage/bulk/bulk-status.component";
|
|
||||||
import { CollectionAddEditComponent as OrgCollectionAddEditComponent } from "../organizations/manage/collection-add-edit.component";
|
import { CollectionAddEditComponent as OrgCollectionAddEditComponent } from "../organizations/manage/collection-add-edit.component";
|
||||||
import { CollectionsComponent as OrgManageCollectionsComponent } from "../organizations/manage/collections.component";
|
import { CollectionsComponent as OrgManageCollectionsComponent } from "../organizations/manage/collections.component";
|
||||||
import { EntityEventsComponent as OrgEntityEventsComponent } from "../organizations/manage/entity-events.component";
|
|
||||||
import { EventsComponent as OrgEventsComponent } from "../organizations/manage/events.component";
|
import { EventsComponent as OrgEventsComponent } from "../organizations/manage/events.component";
|
||||||
import { GroupAddEditComponent as OrgGroupAddEditComponent } from "../organizations/manage/group-add-edit.component";
|
import { GroupAddEditComponent as OrgGroupAddEditComponent } from "../organizations/manage/group-add-edit.component";
|
||||||
import { GroupsComponent as OrgGroupsComponent } from "../organizations/manage/groups.component";
|
import { GroupsComponent as OrgGroupsComponent } from "../organizations/manage/groups.component";
|
||||||
import { ManageComponent as OrgManageComponent } from "../organizations/manage/manage.component";
|
import { ManageComponent as OrgManageComponent } from "../organizations/manage/manage.component";
|
||||||
import { PeopleComponent as OrgPeopleComponent } from "../organizations/manage/people.component";
|
|
||||||
import { PoliciesComponent as OrgPoliciesComponent } from "../organizations/manage/policies.component";
|
import { PoliciesComponent as OrgPoliciesComponent } from "../organizations/manage/policies.component";
|
||||||
import { PolicyEditComponent as OrgPolicyEditComponent } from "../organizations/manage/policy-edit.component";
|
import { PolicyEditComponent as OrgPolicyEditComponent } from "../organizations/manage/policy-edit.component";
|
||||||
import { ResetPasswordComponent as OrgResetPasswordComponent } from "../organizations/manage/reset-password.component";
|
|
||||||
import { UserAddEditComponent as OrgUserAddEditComponent } from "../organizations/manage/user-add-edit.component";
|
|
||||||
import { UserConfirmComponent as OrgUserConfirmComponent } from "../organizations/manage/user-confirm.component";
|
import { UserConfirmComponent as OrgUserConfirmComponent } from "../organizations/manage/user-confirm.component";
|
||||||
import { UserGroupsComponent as OrgUserGroupsComponent } from "../organizations/manage/user-groups.component";
|
import { BulkConfirmComponent as OrgBulkConfirmComponent } from "../organizations/members/bulk/bulk-confirm.component";
|
||||||
|
import { BulkDeactivateComponent as OrgBulkDeactivateomponent } from "../organizations/members/bulk/bulk-deactivate.component";
|
||||||
|
import { BulkRemoveComponent as OrgBulkRemoveComponent } from "../organizations/members/bulk/bulk-remove.component";
|
||||||
|
import { BulkStatusComponent as OrgBulkStatusComponent } from "../organizations/members/bulk/bulk-status.component";
|
||||||
|
import { EntityEventsComponent as OrgEntityEventsComponent } from "../organizations/members/entity-events.component";
|
||||||
|
import { MembersComponent as OrgPeopleComponent } from "../organizations/members/members.component";
|
||||||
|
import { ResetPasswordComponent as OrgResetPasswordComponent } from "../organizations/members/reset-password.component";
|
||||||
|
import { UserAddEditComponent as OrgUserAddEditComponent } from "../organizations/members/user-add-edit.component";
|
||||||
|
import { UserGroupsComponent as OrgUserGroupsComponent } from "../organizations/members/user-groups.component";
|
||||||
import { DisableSendPolicyComponent } from "../organizations/policies/disable-send.component";
|
import { DisableSendPolicyComponent } from "../organizations/policies/disable-send.component";
|
||||||
import { MasterPasswordPolicyComponent } from "../organizations/policies/master-password.component";
|
import { MasterPasswordPolicyComponent } from "../organizations/policies/master-password.component";
|
||||||
import { PasswordGeneratorPolicyComponent } from "../organizations/policies/password-generator.component";
|
import { PasswordGeneratorPolicyComponent } from "../organizations/policies/password-generator.component";
|
||||||
|
@ -24,7 +24,7 @@ import { CipherType } from "@bitwarden/common/enums/cipherType";
|
|||||||
import { Organization } from "@bitwarden/common/models/domain/organization";
|
import { Organization } from "@bitwarden/common/models/domain/organization";
|
||||||
import { CipherView } from "@bitwarden/common/models/view/cipherView";
|
import { CipherView } from "@bitwarden/common/models/view/cipherView";
|
||||||
|
|
||||||
import { EntityEventsComponent } from "../../../../organizations/manage/entity-events.component";
|
import { EntityEventsComponent } from "../../../../organizations/members/entity-events.component";
|
||||||
import { AddEditComponent } from "../../../../organizations/vault/add-edit.component";
|
import { AddEditComponent } from "../../../../organizations/vault/add-edit.component";
|
||||||
import { AttachmentsComponent } from "../../../../organizations/vault/attachments.component";
|
import { AttachmentsComponent } from "../../../../organizations/vault/attachments.component";
|
||||||
import { CiphersComponent } from "../../../../organizations/vault/ciphers.component";
|
import { CiphersComponent } from "../../../../organizations/vault/ciphers.component";
|
||||||
|
@ -1,293 +0,0 @@
|
|||||||
<div class="page-header">
|
|
||||||
<h1>{{ "people" | i18n }}</h1>
|
|
||||||
<div class="mt-2 d-flex">
|
|
||||||
<div class="btn-group btn-group-sm" role="group">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-outline-secondary"
|
|
||||||
[ngClass]="{ active: status == null }"
|
|
||||||
(click)="filter(null)"
|
|
||||||
>
|
|
||||||
{{ "all" | i18n }}
|
|
||||||
<span bitBadge badgeType="info" *ngIf="allCount">{{ allCount }}</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-outline-secondary"
|
|
||||||
[ngClass]="{ active: status == userStatusType.Invited }"
|
|
||||||
(click)="filter(userStatusType.Invited)"
|
|
||||||
>
|
|
||||||
{{ "invited" | i18n }}
|
|
||||||
<span bitBadge badgeType="info" *ngIf="invitedCount">{{ invitedCount }}</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-outline-secondary"
|
|
||||||
[ngClass]="{ active: status == userStatusType.Accepted }"
|
|
||||||
(click)="filter(userStatusType.Accepted)"
|
|
||||||
>
|
|
||||||
{{ "accepted" | i18n }}
|
|
||||||
<span bitBadge badgeType="warning" *ngIf="acceptedCount">{{ acceptedCount }}</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-outline-secondary"
|
|
||||||
[ngClass]="{ active: status == userStatusType.Deactivated }"
|
|
||||||
(click)="filter(userStatusType.Deactivated)"
|
|
||||||
>
|
|
||||||
{{ "deactivated" | i18n }}
|
|
||||||
<span bitBadge badgeType="info" *ngIf="deactivatedCount">{{ deactivatedCount }}</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="ml-3">
|
|
||||||
<label class="sr-only" for="search">{{ "search" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
type="search"
|
|
||||||
class="form-control form-control-sm"
|
|
||||||
id="search"
|
|
||||||
placeholder="{{ 'search' | i18n }}"
|
|
||||||
[(ngModel)]="searchText"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="dropdown ml-3" appListDropdown>
|
|
||||||
<button
|
|
||||||
class="btn btn-sm btn-outline-secondary dropdown-toggle"
|
|
||||||
type="button"
|
|
||||||
id="bulkActionsButton"
|
|
||||||
data-toggle="dropdown"
|
|
||||||
aria-haspopup="true"
|
|
||||||
aria-expanded="false"
|
|
||||||
appA11yTitle="{{ 'options' | i18n }}"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-cog" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="bulkActionsButton">
|
|
||||||
<button class="dropdown-item" appStopClick (click)="bulkReinvite()">
|
|
||||||
<i class="bwi bwi-fw bwi-envelope" aria-hidden="true"></i>
|
|
||||||
{{ "reinviteSelected" | i18n }}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="dropdown-item text-success"
|
|
||||||
appStopClick
|
|
||||||
(click)="bulkConfirm()"
|
|
||||||
*ngIf="showBulkConfirmUsers"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-fw bwi-check" aria-hidden="true"></i>
|
|
||||||
{{ "confirmSelected" | i18n }}
|
|
||||||
</button>
|
|
||||||
<button class="dropdown-item" appStopClick (click)="bulkActivate()">
|
|
||||||
<i class="bwi bwi-fw bwi-plus-circle" aria-hidden="true"></i>
|
|
||||||
{{ "activate" | i18n }}
|
|
||||||
</button>
|
|
||||||
<button class="dropdown-item" appStopClick (click)="bulkDeactivate()">
|
|
||||||
<i class="bwi bwi-fw bwi-minus-circle" aria-hidden="true"></i>
|
|
||||||
{{ "deactivate" | i18n }}
|
|
||||||
</button>
|
|
||||||
<button class="dropdown-item text-danger" appStopClick (click)="bulkRemove()">
|
|
||||||
<i class="bwi bwi-fw bwi-close" aria-hidden="true"></i>
|
|
||||||
{{ "remove" | i18n }}
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<button class="dropdown-item" appStopClick (click)="selectAll(true)">
|
|
||||||
<i class="bwi bwi-fw bwi-check-square" aria-hidden="true"></i>
|
|
||||||
{{ "selectAll" | i18n }}
|
|
||||||
</button>
|
|
||||||
<button class="dropdown-item" appStopClick (click)="selectAll(false)">
|
|
||||||
<i class="bwi bwi-fw bwi-minus-square" aria-hidden="true"></i>
|
|
||||||
{{ "unselectAll" | i18n }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button type="button" class="btn btn-sm btn-outline-primary ml-3" (click)="invite()">
|
|
||||||
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
|
|
||||||
{{ "inviteUser" | i18n }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ng-container *ngIf="loading">
|
|
||||||
<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="
|
|
||||||
!loading &&
|
|
||||||
(isPaging() ? pagedUsers : (users | search: searchText:'name':'email':'id')) as searchedUsers
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<p *ngIf="!searchedUsers.length">{{ "noUsersInList" | i18n }}</p>
|
|
||||||
<ng-container *ngIf="searchedUsers.length">
|
|
||||||
<app-callout
|
|
||||||
type="info"
|
|
||||||
title="{{ 'confirmUsers' | i18n }}"
|
|
||||||
icon="bwi bwi-check-circle"
|
|
||||||
*ngIf="showConfirmUsers"
|
|
||||||
>
|
|
||||||
{{ "usersNeedConfirmed" | i18n }}
|
|
||||||
</app-callout>
|
|
||||||
<table
|
|
||||||
class="table table-hover table-list"
|
|
||||||
infiniteScroll
|
|
||||||
[infiniteScrollDistance]="1"
|
|
||||||
[infiniteScrollDisabled]="!isPaging()"
|
|
||||||
(scrolled)="loadMore()"
|
|
||||||
>
|
|
||||||
<tbody>
|
|
||||||
<tr *ngFor="let u of searchedUsers">
|
|
||||||
<td (click)="checkUser(u)" class="table-list-checkbox">
|
|
||||||
<input type="checkbox" [(ngModel)]="u.checked" appStopProp />
|
|
||||||
</td>
|
|
||||||
<td width="30">
|
|
||||||
<app-avatar
|
|
||||||
[data]="u | userName"
|
|
||||||
[email]="u.email"
|
|
||||||
size="25"
|
|
||||||
[circle]="true"
|
|
||||||
[fontSize]="14"
|
|
||||||
>
|
|
||||||
</app-avatar>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href="#" appStopClick (click)="edit(u)">{{ u.email }}</a>
|
|
||||||
<span bitBadge badgeType="secondary" *ngIf="u.status === userStatusType.Invited">{{
|
|
||||||
"invited" | i18n
|
|
||||||
}}</span>
|
|
||||||
<span bitBadge badgeType="warning" *ngIf="u.status === userStatusType.Accepted">{{
|
|
||||||
"accepted" | i18n
|
|
||||||
}}</span>
|
|
||||||
<span bitBadge badgeType="secondary" *ngIf="u.status === userStatusType.Deactivated">{{
|
|
||||||
"deactivated" | i18n
|
|
||||||
}}</span>
|
|
||||||
<small class="text-muted d-block" *ngIf="u.name">{{ u.name }}</small>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<ng-container *ngIf="u.twoFactorEnabled">
|
|
||||||
<i
|
|
||||||
class="bwi bwi-lock"
|
|
||||||
title="{{ 'userUsingTwoStep' | i18n }}"
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
<span class="sr-only">{{ "userUsingTwoStep" | i18n }}</span>
|
|
||||||
</ng-container>
|
|
||||||
<ng-container *ngIf="showEnrolledStatus(u)">
|
|
||||||
<i
|
|
||||||
class="bwi bwi-key"
|
|
||||||
title="{{ 'enrolledPasswordReset' | i18n }}"
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
<span class="sr-only">{{ "enrolledPasswordReset" | i18n }}</span>
|
|
||||||
</ng-container>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span *ngIf="u.type === userType.Owner">{{ "owner" | i18n }}</span>
|
|
||||||
<span *ngIf="u.type === userType.Admin">{{ "admin" | i18n }}</span>
|
|
||||||
<span *ngIf="u.type === userType.Manager">{{ "manager" | i18n }}</span>
|
|
||||||
<span *ngIf="u.type === userType.User">{{ "user" | i18n }}</span>
|
|
||||||
<span *ngIf="u.type === userType.Custom">{{ "custom" | i18n }}</span>
|
|
||||||
</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>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu dropdown-menu-right">
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
appStopClick
|
|
||||||
(click)="reinvite(u)"
|
|
||||||
*ngIf="u.status === userStatusType.Invited"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-fw bwi-envelope" aria-hidden="true"></i>
|
|
||||||
{{ "resendInvitation" | i18n }}
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item text-success"
|
|
||||||
href="#"
|
|
||||||
appStopClick
|
|
||||||
(click)="confirm(u)"
|
|
||||||
*ngIf="u.status === userStatusType.Accepted"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-fw bwi-check" aria-hidden="true"></i>
|
|
||||||
{{ "confirm" | i18n }}
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
appStopClick
|
|
||||||
(click)="groups(u)"
|
|
||||||
*ngIf="accessGroups"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-fw bwi-sitemap" aria-hidden="true"></i>
|
|
||||||
{{ "groups" | i18n }}
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
appStopClick
|
|
||||||
(click)="events(u)"
|
|
||||||
*ngIf="accessEvents && u.status === userStatusType.Confirmed"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-fw bwi-file-text" aria-hidden="true"></i>
|
|
||||||
{{ "eventLogs" | i18n }}
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
appStopClick
|
|
||||||
(click)="resetPassword(u)"
|
|
||||||
*ngIf="allowResetPassword(u)"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-fw bwi-key" aria-hidden="true"></i>
|
|
||||||
{{ "resetPassword" | i18n }}
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
appStopClick
|
|
||||||
(click)="activate(u)"
|
|
||||||
*ngIf="u.status === userStatusType.Deactivated"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-fw bwi-plus-circle" aria-hidden="true"></i>
|
|
||||||
{{ "activate" | i18n }}
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
appStopClick
|
|
||||||
(click)="deactivate(u)"
|
|
||||||
*ngIf="u.status !== userStatusType.Deactivated"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-fw bwi-minus-circle" aria-hidden="true"></i>
|
|
||||||
{{ "deactivate" | i18n }}
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-item text-danger" href="#" appStopClick (click)="remove(u)">
|
|
||||||
<i class="bwi bwi-fw bwi-close" aria-hidden="true"></i>
|
|
||||||
{{ "remove" | i18n }}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</ng-container>
|
|
||||||
</ng-container>
|
|
||||||
<ng-template #addEdit></ng-template>
|
|
||||||
<ng-template #groupsTemplate></ng-template>
|
|
||||||
<ng-template #eventsTemplate></ng-template>
|
|
||||||
<ng-template #confirmTemplate></ng-template>
|
|
||||||
<ng-template #resetPasswordTemplate></ng-template>
|
|
||||||
<ng-template #bulkStatusTemplate></ng-template>
|
|
||||||
<ng-template #bulkConfirmTemplate></ng-template>
|
|
||||||
<ng-template #bulkRemoveTemplate></ng-template>
|
|
298
apps/web/src/app/organizations/members/members.component.html
Normal file
298
apps/web/src/app/organizations/members/members.component.html
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
<div class="container page-content">
|
||||||
|
<div class="page-header d-flex">
|
||||||
|
<h1>{{ "members" | i18n }}</h1>
|
||||||
|
<div class="mt-2 d-flex ml-auto">
|
||||||
|
<div class="btn-group btn-group-sm" role="group">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-outline-secondary"
|
||||||
|
[ngClass]="{ active: status == null }"
|
||||||
|
(click)="filter(null)"
|
||||||
|
>
|
||||||
|
{{ "all" | i18n }}
|
||||||
|
<span bitBadge badgeType="info" *ngIf="allCount">{{ allCount }}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-outline-secondary"
|
||||||
|
[ngClass]="{ active: status == userStatusType.Invited }"
|
||||||
|
(click)="filter(userStatusType.Invited)"
|
||||||
|
>
|
||||||
|
{{ "invited" | i18n }}
|
||||||
|
<span bitBadge badgeType="info" *ngIf="invitedCount">{{ invitedCount }}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-outline-secondary"
|
||||||
|
[ngClass]="{ active: status == userStatusType.Accepted }"
|
||||||
|
(click)="filter(userStatusType.Accepted)"
|
||||||
|
>
|
||||||
|
{{ "accepted" | i18n }}
|
||||||
|
<span bitBadge badgeType="warning" *ngIf="acceptedCount">{{ acceptedCount }}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-outline-secondary"
|
||||||
|
[ngClass]="{ active: status == userStatusType.Deactivated }"
|
||||||
|
(click)="filter(userStatusType.Deactivated)"
|
||||||
|
>
|
||||||
|
{{ "deactivated" | i18n }}
|
||||||
|
<span bitBadge badgeType="info" *ngIf="deactivatedCount">{{ deactivatedCount }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="ml-3">
|
||||||
|
<label class="sr-only" for="search">{{ "search" | i18n }}</label>
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
class="form-control form-control-sm"
|
||||||
|
id="search"
|
||||||
|
placeholder="{{ 'search' | i18n }}"
|
||||||
|
[(ngModel)]="searchText"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="dropdown ml-3" appListDropdown>
|
||||||
|
<button
|
||||||
|
class="btn btn-sm btn-outline-secondary dropdown-toggle"
|
||||||
|
type="button"
|
||||||
|
id="bulkActionsButton"
|
||||||
|
data-toggle="dropdown"
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-expanded="false"
|
||||||
|
appA11yTitle="{{ 'options' | i18n }}"
|
||||||
|
>
|
||||||
|
<i class="bwi bwi-cog" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="bulkActionsButton">
|
||||||
|
<button class="dropdown-item" appStopClick (click)="bulkReinvite()">
|
||||||
|
<i class="bwi bwi-fw bwi-envelope" aria-hidden="true"></i>
|
||||||
|
{{ "reinviteSelected" | i18n }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="dropdown-item text-success"
|
||||||
|
appStopClick
|
||||||
|
(click)="bulkConfirm()"
|
||||||
|
*ngIf="showBulkConfirmUsers"
|
||||||
|
>
|
||||||
|
<i class="bwi bwi-fw bwi-check" aria-hidden="true"></i>
|
||||||
|
{{ "confirmSelected" | i18n }}
|
||||||
|
</button>
|
||||||
|
<button class="dropdown-item" appStopClick (click)="bulkActivate()">
|
||||||
|
<i class="bwi bwi-fw bwi-plus-circle" aria-hidden="true"></i>
|
||||||
|
{{ "activate" | i18n }}
|
||||||
|
</button>
|
||||||
|
<button class="dropdown-item" appStopClick (click)="bulkDeactivate()">
|
||||||
|
<i class="bwi bwi-fw bwi-minus-circle" aria-hidden="true"></i>
|
||||||
|
{{ "deactivate" | i18n }}
|
||||||
|
</button>
|
||||||
|
<button class="dropdown-item text-danger" appStopClick (click)="bulkRemove()">
|
||||||
|
<i class="bwi bwi-fw bwi-close" aria-hidden="true"></i>
|
||||||
|
{{ "remove" | i18n }}
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<button class="dropdown-item" appStopClick (click)="selectAll(true)">
|
||||||
|
<i class="bwi bwi-fw bwi-check-square" aria-hidden="true"></i>
|
||||||
|
{{ "selectAll" | i18n }}
|
||||||
|
</button>
|
||||||
|
<button class="dropdown-item" appStopClick (click)="selectAll(false)">
|
||||||
|
<i class="bwi bwi-fw bwi-minus-square" aria-hidden="true"></i>
|
||||||
|
{{ "unselectAll" | i18n }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-primary ml-3" (click)="invite()">
|
||||||
|
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
|
||||||
|
{{ "inviteUser" | i18n }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ng-container *ngIf="loading">
|
||||||
|
<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="
|
||||||
|
!loading &&
|
||||||
|
(isPaging() ? pagedUsers : (users | search: searchText:'name':'email':'id')) as searchedUsers
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<p *ngIf="!searchedUsers.length">{{ "noUsersInList" | i18n }}</p>
|
||||||
|
<ng-container *ngIf="searchedUsers.length">
|
||||||
|
<app-callout
|
||||||
|
type="info"
|
||||||
|
title="{{ 'confirmUsers' | i18n }}"
|
||||||
|
icon="bwi bwi-check-circle"
|
||||||
|
*ngIf="showConfirmUsers"
|
||||||
|
>
|
||||||
|
{{ "usersNeedConfirmed" | i18n }}
|
||||||
|
</app-callout>
|
||||||
|
<table
|
||||||
|
class="table table-hover table-list"
|
||||||
|
infiniteScroll
|
||||||
|
[infiniteScrollDistance]="1"
|
||||||
|
[infiniteScrollDisabled]="!isPaging()"
|
||||||
|
(scrolled)="loadMore()"
|
||||||
|
>
|
||||||
|
<tbody>
|
||||||
|
<tr *ngFor="let u of searchedUsers">
|
||||||
|
<td (click)="checkUser(u)" class="table-list-checkbox">
|
||||||
|
<input type="checkbox" [(ngModel)]="u.checked" appStopProp />
|
||||||
|
</td>
|
||||||
|
<td width="30">
|
||||||
|
<app-avatar
|
||||||
|
[data]="u | userName"
|
||||||
|
[email]="u.email"
|
||||||
|
size="25"
|
||||||
|
[circle]="true"
|
||||||
|
[fontSize]="14"
|
||||||
|
>
|
||||||
|
</app-avatar>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="#" appStopClick (click)="edit(u)">{{ u.email }}</a>
|
||||||
|
<span bitBadge badgeType="secondary" *ngIf="u.status === userStatusType.Invited">{{
|
||||||
|
"invited" | i18n
|
||||||
|
}}</span>
|
||||||
|
<span bitBadge badgeType="warning" *ngIf="u.status === userStatusType.Accepted">{{
|
||||||
|
"accepted" | i18n
|
||||||
|
}}</span>
|
||||||
|
<span
|
||||||
|
bitBadge
|
||||||
|
badgeType="secondary"
|
||||||
|
*ngIf="u.status === userStatusType.Deactivated"
|
||||||
|
>{{ "deactivated" | i18n }}</span
|
||||||
|
>
|
||||||
|
<small class="text-muted d-block" *ngIf="u.name">{{ u.name }}</small>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ng-container *ngIf="u.twoFactorEnabled">
|
||||||
|
<i
|
||||||
|
class="bwi bwi-lock"
|
||||||
|
title="{{ 'userUsingTwoStep' | i18n }}"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
<span class="sr-only">{{ "userUsingTwoStep" | i18n }}</span>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="showEnrolledStatus(u)">
|
||||||
|
<i
|
||||||
|
class="bwi bwi-key"
|
||||||
|
title="{{ 'enrolledPasswordReset' | i18n }}"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
<span class="sr-only">{{ "enrolledPasswordReset" | i18n }}</span>
|
||||||
|
</ng-container>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span *ngIf="u.type === userType.Owner">{{ "owner" | i18n }}</span>
|
||||||
|
<span *ngIf="u.type === userType.Admin">{{ "admin" | i18n }}</span>
|
||||||
|
<span *ngIf="u.type === userType.Manager">{{ "manager" | i18n }}</span>
|
||||||
|
<span *ngIf="u.type === userType.User">{{ "user" | i18n }}</span>
|
||||||
|
<span *ngIf="u.type === userType.Custom">{{ "custom" | i18n }}</span>
|
||||||
|
</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>
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right">
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
appStopClick
|
||||||
|
(click)="reinvite(u)"
|
||||||
|
*ngIf="u.status === userStatusType.Invited"
|
||||||
|
>
|
||||||
|
<i class="bwi bwi-fw bwi-envelope" aria-hidden="true"></i>
|
||||||
|
{{ "resendInvitation" | i18n }}
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="dropdown-item text-success"
|
||||||
|
href="#"
|
||||||
|
appStopClick
|
||||||
|
(click)="confirm(u)"
|
||||||
|
*ngIf="u.status === userStatusType.Accepted"
|
||||||
|
>
|
||||||
|
<i class="bwi bwi-fw bwi-check" aria-hidden="true"></i>
|
||||||
|
{{ "confirm" | i18n }}
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
appStopClick
|
||||||
|
(click)="groups(u)"
|
||||||
|
*ngIf="accessGroups"
|
||||||
|
>
|
||||||
|
<i class="bwi bwi-fw bwi-sitemap" aria-hidden="true"></i>
|
||||||
|
{{ "groups" | i18n }}
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
appStopClick
|
||||||
|
(click)="events(u)"
|
||||||
|
*ngIf="accessEvents && u.status === userStatusType.Confirmed"
|
||||||
|
>
|
||||||
|
<i class="bwi bwi-fw bwi-file-text" aria-hidden="true"></i>
|
||||||
|
{{ "eventLogs" | i18n }}
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
appStopClick
|
||||||
|
(click)="resetPassword(u)"
|
||||||
|
*ngIf="allowResetPassword(u)"
|
||||||
|
>
|
||||||
|
<i class="bwi bwi-fw bwi-key" aria-hidden="true"></i>
|
||||||
|
{{ "resetPassword" | i18n }}
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
appStopClick
|
||||||
|
(click)="activate(u)"
|
||||||
|
*ngIf="u.status === userStatusType.Deactivated"
|
||||||
|
>
|
||||||
|
<i class="bwi bwi-fw bwi-plus-circle" aria-hidden="true"></i>
|
||||||
|
{{ "activate" | i18n }}
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
appStopClick
|
||||||
|
(click)="deactivate(u)"
|
||||||
|
*ngIf="u.status !== userStatusType.Deactivated"
|
||||||
|
>
|
||||||
|
<i class="bwi bwi-fw bwi-minus-circle" aria-hidden="true"></i>
|
||||||
|
{{ "deactivate" | i18n }}
|
||||||
|
</a>
|
||||||
|
<a class="dropdown-item text-danger" href="#" appStopClick (click)="remove(u)">
|
||||||
|
<i class="bwi bwi-fw bwi-close" aria-hidden="true"></i>
|
||||||
|
{{ "remove" | i18n }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
<ng-template #addEdit></ng-template>
|
||||||
|
<ng-template #groupsTemplate></ng-template>
|
||||||
|
<ng-template #eventsTemplate></ng-template>
|
||||||
|
<ng-template #confirmTemplate></ng-template>
|
||||||
|
<ng-template #resetPasswordTemplate></ng-template>
|
||||||
|
<ng-template #bulkStatusTemplate></ng-template>
|
||||||
|
<ng-template #bulkConfirmTemplate></ng-template>
|
||||||
|
<ng-template #bulkRemoveTemplate></ng-template>
|
||||||
|
</div>
|
@ -38,10 +38,10 @@ import { UserAddEditComponent } from "./user-add-edit.component";
|
|||||||
import { UserGroupsComponent } from "./user-groups.component";
|
import { UserGroupsComponent } from "./user-groups.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-org-people",
|
selector: "app-org-members",
|
||||||
templateUrl: "people.component.html",
|
templateUrl: "members.component.html",
|
||||||
})
|
})
|
||||||
export class PeopleComponent
|
export class MembersComponent
|
||||||
extends BasePeopleComponent<OrganizationUserUserDetailsResponse>
|
extends BasePeopleComponent<OrganizationUserUserDetailsResponse>
|
||||||
implements OnInit
|
implements OnInit
|
||||||
{
|
{
|
||||||
@ -108,7 +108,7 @@ export class PeopleComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.route.parent.parent.params.subscribe(async (params) => {
|
this.route.parent.params.subscribe(async (params) => {
|
||||||
this.organizationId = params.organizationId;
|
this.organizationId = params.organizationId;
|
||||||
const organization = await this.organizationService.get(this.organizationId);
|
const organization = await this.organizationService.get(this.organizationId);
|
||||||
if (!organization.canManageUsers) {
|
if (!organization.canManageUsers) {
|
@ -12,8 +12,8 @@ import { CollectionsComponent } from "./manage/collections.component";
|
|||||||
import { EventsComponent } from "./manage/events.component";
|
import { EventsComponent } from "./manage/events.component";
|
||||||
import { GroupsComponent } from "./manage/groups.component";
|
import { GroupsComponent } from "./manage/groups.component";
|
||||||
import { ManageComponent } from "./manage/manage.component";
|
import { ManageComponent } from "./manage/manage.component";
|
||||||
import { PeopleComponent } from "./manage/people.component";
|
|
||||||
import { PoliciesComponent } from "./manage/policies.component";
|
import { PoliciesComponent } from "./manage/policies.component";
|
||||||
|
import { MembersComponent } from "./members/members.component";
|
||||||
import { NavigationPermissionsService } from "./services/navigation-permissions.service";
|
import { NavigationPermissionsService } from "./services/navigation-permissions.service";
|
||||||
import { AccountComponent } from "./settings/account.component";
|
import { AccountComponent } from "./settings/account.component";
|
||||||
import { OrganizationBillingComponent } from "./settings/organization-billing.component";
|
import { OrganizationBillingComponent } from "./settings/organization-billing.component";
|
||||||
@ -117,7 +117,7 @@ const routes: Routes = [
|
|||||||
{
|
{
|
||||||
path: "",
|
path: "",
|
||||||
pathMatch: "full",
|
pathMatch: "full",
|
||||||
redirectTo: "people",
|
redirectTo: "collections",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "collections",
|
path: "collections",
|
||||||
@ -152,15 +152,6 @@ const routes: Routes = [
|
|||||||
permissions: [Permissions.ManageGroups],
|
permissions: [Permissions.ManageGroups],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "people",
|
|
||||||
component: PeopleComponent,
|
|
||||||
canActivate: [PermissionsGuard],
|
|
||||||
data: {
|
|
||||||
titleId: "people",
|
|
||||||
permissions: [Permissions.ManageUsers, Permissions.ManageUsersPassword],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "policies",
|
path: "policies",
|
||||||
component: PoliciesComponent,
|
component: PoliciesComponent,
|
||||||
@ -198,6 +189,15 @@ const routes: Routes = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "members",
|
||||||
|
component: MembersComponent,
|
||||||
|
canActivate: [PermissionsGuard],
|
||||||
|
data: {
|
||||||
|
titleId: "members",
|
||||||
|
permissions: [Permissions.ManageUsers, Permissions.ManageUsersPassword],
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -4,12 +4,12 @@ import { ProviderUserStatusType } from "@bitwarden/common/enums/providerUserStat
|
|||||||
import { ProviderUserBulkConfirmRequest } from "@bitwarden/common/models/request/provider/providerUserBulkConfirmRequest";
|
import { ProviderUserBulkConfirmRequest } from "@bitwarden/common/models/request/provider/providerUserBulkConfirmRequest";
|
||||||
import { ProviderUserBulkRequest } from "@bitwarden/common/models/request/provider/providerUserBulkRequest";
|
import { ProviderUserBulkRequest } from "@bitwarden/common/models/request/provider/providerUserBulkRequest";
|
||||||
|
|
||||||
import { BulkConfirmComponent as OrganizationBulkConfirmComponent } from "src/app/organizations/manage/bulk/bulk-confirm.component";
|
import { BulkConfirmComponent as OrganizationBulkConfirmComponent } from "src/app/organizations/members/bulk/bulk-confirm.component";
|
||||||
import { BulkUserDetails } from "src/app/organizations/manage/bulk/bulk-status.component";
|
import { BulkUserDetails } from "src/app/organizations/members/bulk/bulk-status.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl:
|
templateUrl:
|
||||||
"../../../../../../../apps/web/src/app/organizations/manage/bulk/bulk-confirm.component.html",
|
"../../../../../../../apps/web/src/app/organizations/members/bulk/bulk-confirm.component.html",
|
||||||
})
|
})
|
||||||
export class BulkConfirmComponent extends OrganizationBulkConfirmComponent {
|
export class BulkConfirmComponent extends OrganizationBulkConfirmComponent {
|
||||||
@Input() providerId: string;
|
@Input() providerId: string;
|
||||||
|
@ -2,11 +2,11 @@ import { Component, Input } from "@angular/core";
|
|||||||
|
|
||||||
import { ProviderUserBulkRequest } from "@bitwarden/common/models/request/provider/providerUserBulkRequest";
|
import { ProviderUserBulkRequest } from "@bitwarden/common/models/request/provider/providerUserBulkRequest";
|
||||||
|
|
||||||
import { BulkRemoveComponent as OrganizationBulkRemoveComponent } from "src/app/organizations/manage/bulk/bulk-remove.component";
|
import { BulkRemoveComponent as OrganizationBulkRemoveComponent } from "src/app/organizations/members/bulk/bulk-remove.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl:
|
templateUrl:
|
||||||
"../../../../../../../apps/web/src/app/organizations/manage/bulk/bulk-remove.component.html",
|
"../../../../../../../apps/web/src/app/organizations/members/bulk/bulk-remove.component.html",
|
||||||
})
|
})
|
||||||
export class BulkRemoveComponent extends OrganizationBulkRemoveComponent {
|
export class BulkRemoveComponent extends OrganizationBulkRemoveComponent {
|
||||||
@Input() providerId: string;
|
@Input() providerId: string;
|
||||||
|
@ -23,8 +23,8 @@ import { ProviderUserBulkResponse } from "@bitwarden/common/models/response/prov
|
|||||||
import { ProviderUserUserDetailsResponse } from "@bitwarden/common/models/response/provider/providerUserResponse";
|
import { ProviderUserUserDetailsResponse } from "@bitwarden/common/models/response/provider/providerUserResponse";
|
||||||
|
|
||||||
import { BasePeopleComponent } from "src/app/common/base.people.component";
|
import { BasePeopleComponent } from "src/app/common/base.people.component";
|
||||||
import { BulkStatusComponent } from "src/app/organizations/manage/bulk/bulk-status.component";
|
import { BulkStatusComponent } from "src/app/organizations/members/bulk/bulk-status.component";
|
||||||
import { EntityEventsComponent } from "src/app/organizations/manage/entity-events.component";
|
import { EntityEventsComponent } from "src/app/organizations/members/entity-events.component";
|
||||||
|
|
||||||
import { BulkConfirmComponent } from "./bulk/bulk-confirm.component";
|
import { BulkConfirmComponent } from "./bulk/bulk-confirm.component";
|
||||||
import { BulkRemoveComponent } from "./bulk/bulk-remove.component";
|
import { BulkRemoveComponent } from "./bulk/bulk-remove.component";
|
||||||
|
Loading…
Reference in New Issue
Block a user