mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 15:53:27 +00:00
* Remove tabindex from modal component templates * Remove tabindex from modal component templates * Update jslib
262 lines
16 KiB
HTML
262 lines
16 KiB
HTML
<div class="modal fade" role="dialog" aria-modal="true" aria-labelledby="userAddEditTitle">
|
|
<div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
|
|
<form class="modal-content" #form (ngSubmit)="submit()" [appApiAction]="formPromise" ngNativeValidate>
|
|
<div class="modal-header">
|
|
<h2 class="modal-title" id="userAddEditTitle">
|
|
{{title}}
|
|
<small class="text-muted" *ngIf="name">{{name}}</small>
|
|
</h2>
|
|
<button type="button" class="close" data-dismiss="modal" appA11yTitle="{{'close' | i18n}}">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body" *ngIf="loading">
|
|
<i class="fa fa-spinner fa-spin text-muted" title="{{'loading' | i18n}}" aria-hidden="true"></i>
|
|
<span class="sr-only">{{'loading' | i18n}}</span>
|
|
</div>
|
|
<div class="modal-body" *ngIf="!loading">
|
|
<ng-container *ngIf="!editMode">
|
|
<p>{{'inviteUserDesc' | i18n}}</p>
|
|
<div class="form-group mb-4">
|
|
<label for="emails">{{'email' | i18n}}</label>
|
|
<input id="emails" class="form-control" type="text" name="Emails" [(ngModel)]="emails" required
|
|
appAutoFocus>
|
|
<small class="text-muted">{{'inviteMultipleEmailDesc' | i18n : '20'}}</small>
|
|
</div>
|
|
</ng-container>
|
|
<h3>
|
|
{{'userType' | i18n}}
|
|
<a target="_blank" rel="noopener" appA11yTitle="{{'learnMore' | i18n}}"
|
|
href="https://bitwarden.com/help/article/user-types-access-control/#user-types">
|
|
<i class="fa fa-question-circle-o" aria-hidden="true"></i>
|
|
</a>
|
|
</h3>
|
|
<div class="form-check mt-2 form-check-block">
|
|
<input class="form-check-input" type="radio" name="userType" id="userTypeUser"
|
|
[value]="organizationUserType.User" [(ngModel)]="type">
|
|
<label class="form-check-label" for="userTypeUser">
|
|
{{'user' | i18n}}
|
|
<small>{{'userDesc' | i18n}}</small>
|
|
</label>
|
|
</div>
|
|
<div class="form-check mt-2 form-check-block">
|
|
<input class="form-check-input" type="radio" name="userType" id="userTypeManager"
|
|
[value]="organizationUserType.Manager" [(ngModel)]="type">
|
|
<label class="form-check-label" for="userTypeManager">
|
|
{{'manager' | i18n}}
|
|
<small>{{'managerDesc' | i18n}}</small>
|
|
</label>
|
|
</div>
|
|
<div class="form-check mt-2 form-check-block">
|
|
<input class="form-check-input" type="radio" name="userType" id="userTypeAdmin"
|
|
[value]="organizationUserType.Admin" [(ngModel)]="type">
|
|
<label class="form-check-label" for="userTypeAdmin">
|
|
{{'admin' | i18n}}
|
|
<small>{{'adminDesc' | i18n}}</small>
|
|
</label>
|
|
</div>
|
|
<div class="form-check mt-2 form-check-block">
|
|
<input class="form-check-input" type="radio" name="userType" id="userTypeOwner"
|
|
[value]="organizationUserType.Owner" [(ngModel)]="type">
|
|
<label class="form-check-label" for="userTypeOwner">
|
|
{{'owner' | i18n}}
|
|
<small>{{'ownerDesc' | i18n}}</small>
|
|
</label>
|
|
</div>
|
|
<div class="form-check mt-2 form-check-block">
|
|
<input class="form-check-input" type="radio" name="userType" id="userTypeCustom"
|
|
[value]="organizationUserType.Custom" [(ngModel)]="type">
|
|
<label class="form-check-label" for="userTypeCustom">
|
|
{{'custom' | i18n}}
|
|
<small>{{'customDesc' | i18n}}</small>
|
|
</label>
|
|
</div>
|
|
<ng-container *ngIf="customUserTypeSelected">
|
|
<h3 class="mt-4 d-flex">
|
|
{{'permissions' | i18n}}
|
|
</h3>
|
|
<div class="row">
|
|
<div class="col-6">
|
|
<div class="mb-3">
|
|
<label class="font-weight-bold mb-0">Manager Permissions</label>
|
|
<hr class="my-0 mr-2" />
|
|
<app-nested-checkbox parentId="manageAssignedCollections"
|
|
[checkboxes]="manageAssignedCollectionsCheckboxes">
|
|
</app-nested-checkbox>
|
|
</div>
|
|
</div>
|
|
<div class="col-6">
|
|
<div class="mb-3">
|
|
<label class="font-weight-bold mb-0">Admin Permissions</label>
|
|
<hr class="my-0 mr-2" />
|
|
<div class="form-group mb-0">
|
|
<div class="form-check mt-1 form-check-block">
|
|
<input class="form-check-input" type="checkbox" name="accessEventLogs"
|
|
id="accessEventLogs" [(ngModel)]="permissions.accessEventLogs">
|
|
<label class="form-check-label font-weight-normal" for="accessEventLogs">
|
|
{{'accessEventLogs' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group mb-0">
|
|
<div class="form-check mt-1 form-check-block">
|
|
<input class="form-check-input" type="checkbox" name="accessImportExport"
|
|
id="accessImportExport" [(ngModel)]="permissions.accessImportExport">
|
|
<label class="form-check-label font-weight-normal" for="accessImportExport">
|
|
{{'accessImportExport' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group mb-0">
|
|
<div class="form-check mt-1 form-check-block">
|
|
<input class="form-check-input" type="checkbox" name="accessReports"
|
|
id="accessReports" [(ngModel)]="permissions.accessReports">
|
|
<label class="form-check-label font-weight-normal" for="accessReports">
|
|
{{'accessReports' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<app-nested-checkbox parentId="manageAllCollections"
|
|
[checkboxes]="manageAllCollectionsCheckboxes">
|
|
</app-nested-checkbox>
|
|
<div class="form-group mb-0">
|
|
<div class="form-check mt-1 form-check-block">
|
|
<input class="form-check-input" type="checkbox" name="manageGroups"
|
|
id="manageGroups" [(ngModel)]="permissions.manageGroups">
|
|
<label class="form-check-label font-weight-normal" for="manageGroups">
|
|
{{'manageGroups' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group mb-0">
|
|
<div class="form-check mt-1 form-check-block">
|
|
<input class="form-check-input" type="checkbox" name="manageSso"
|
|
id="managePolicies" [(ngModel)]="permissions.manageSso">
|
|
<label class="form-check-label font-weight-normal" for="manageSso">
|
|
{{'manageSso' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group mb-0">
|
|
<div class="form-check mt-1 form-check-block">
|
|
<input class="form-check-input" type="checkbox" name="managePolicies"
|
|
id="managePolicies" [(ngModel)]="permissions.managePolicies">
|
|
<label class="form-check-label font-weight-normal" for="managePolicies">
|
|
{{'managePolicies' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group mb-0">
|
|
<div class="form-check mt-1 form-check-block">
|
|
<input class="form-check-input" type="checkbox" name="manageUsers"
|
|
id="manageUsers" [(ngModel)]="permissions.manageUsers"
|
|
(change)="handleDependentPermissions()">
|
|
<label class="form-check-label font-weight-normal" for="manageUsers">
|
|
{{'manageUsers' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group mb-0">
|
|
<div class="form-check mt-1 form-check-block">
|
|
<input class="form-check-input" type="checkbox" name="manageResetPassword"
|
|
id="manageResetPassword" [(ngModel)]="permissions.manageResetPassword"
|
|
(change)="handleDependentPermissions()">
|
|
<label class="form-check-label font-weight-normal" for="manageResetPassword">
|
|
{{'manageResetPassword' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</ng-container>
|
|
<h3 class="mt-4 d-flex">
|
|
<div class="mb-3">
|
|
{{'accessControl' | i18n}}
|
|
<a target="_blank" rel="noopener" appA11yTitle="{{'learnMore' | i18n}}"
|
|
href="https://bitwarden.com/help/article/user-types-access-control/#access-control">
|
|
<i class="fa fa-question-circle-o" aria-hidden="true"></i>
|
|
</a>
|
|
</div>
|
|
<div class="ml-auto" *ngIf="access === 'selected' && collections && collections.length">
|
|
<button type="button" (click)="selectAll(true)" class="btn btn-link btn-sm py-0">
|
|
{{'selectAll' | i18n}}
|
|
</button>
|
|
<button type="button" (click)="selectAll(false)" class="btn btn-link btn-sm py-0">
|
|
{{'unselectAll' | i18n}}
|
|
</button>
|
|
</div>
|
|
</h3>
|
|
<div class="form-group" [ngClass]="{'mb-0': access !== 'selected'}">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="radio" name="access" id="accessAll" value="all"
|
|
[(ngModel)]="access">
|
|
<label class="form-check-label" for="accessAll">
|
|
{{'userAccessAllItems' | i18n}}
|
|
</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="radio" name="access" id="accessSelected" value="selected"
|
|
[(ngModel)]="access">
|
|
<label class="form-check-label" for="accessSelected">
|
|
{{'userAccessSelectedCollections' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<ng-container *ngIf="access === 'selected'">
|
|
<div *ngIf="!collections || !collections.length">
|
|
{{'noCollectionsInList' | i18n}}
|
|
</div>
|
|
<table class="table table-hover table-list mb-0" *ngIf="collections && collections.length">
|
|
<thead>
|
|
<tr>
|
|
<th> </th>
|
|
<th>{{'name' | i18n}}</th>
|
|
<th width="100" class="text-center">{{'hidePasswords' | i18n}}</th>
|
|
<th width="100" class="text-center">{{'readOnly' | i18n}}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr *ngFor="let c of collections; let i = index">
|
|
<td class="table-list-checkbox" (click)="check(c)">
|
|
<input type="checkbox" [(ngModel)]="c.checked" name="Collection[{{i}}].Checked"
|
|
appStopProp>
|
|
</td>
|
|
<td (click)="check(c)">
|
|
{{c.name}}
|
|
</td>
|
|
<td class="text-center">
|
|
<input type="checkbox" [(ngModel)]="c.hidePasswords"
|
|
name="Collection[{{i}}].HidePasswords" [disabled]="!c.checked">
|
|
</td>
|
|
<td class="text-center">
|
|
<input type="checkbox" [(ngModel)]="c.readOnly" name="Collection[{{i}}].ReadOnly"
|
|
[disabled]="!c.checked">
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</ng-container>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="submit" class="btn btn-primary btn-submit" [disabled]="form.loading">
|
|
<i class="fa fa-spinner fa-spin" title="{{'loading' | i18n}}" aria-hidden="true"></i>
|
|
<span>{{'save' | i18n}}</span>
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">
|
|
{{'cancel' | i18n}}
|
|
</button>
|
|
<div class="ml-auto">
|
|
<button #deleteBtn type="button" (click)="delete()" class="btn btn-outline-danger"
|
|
appA11yTitle="{{'delete' | i18n}}" *ngIf="editMode" [disabled]="deleteBtn.loading"
|
|
[appApiAction]="deletePromise">
|
|
<i class="fa fa-trash-o fa-lg fa-fw" [hidden]="deleteBtn.loading" aria-hidden="true"></i>
|
|
<i class="fa fa-spinner fa-spin fa-lg fa-fw" [hidden]="!deleteBtn.loading"
|
|
title="{{'loading' | i18n}}" aria-hidden="true"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|