Move custom fields to separate components (#2072)

* Move add-edit custom fields to own component

* Fix linting and mistakes

* Update directive

* Removed linked fields work

* Move view custom fields to own component

* Remove unnecessary imports

* Wrap template in ng-container

* Update jslib

* Fix imports
This commit is contained in:
Thomas Rittson 2021-09-21 10:49:05 +10:00 committed by GitHub
parent a848406ce0
commit 10734fc024
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 135 additions and 86 deletions

2
jslib

@ -1 +1 @@
Subproject commit 83548a6753a974c57cb373b529a4da3ea5c3b5c0
Subproject commit b7429b0c0cdca8783fd9fa304918ee91f23c6f76

View File

@ -40,6 +40,7 @@ import { SettingsComponent } from './settings/settings.component';
import { SyncComponent } from './settings/sync.component';
import { VaultTimeoutInputComponent } from './settings/vault-timeout-input.component';
import { AddEditCustomFieldsComponent } from './vault/add-edit-custom-fields.component';
import { AddEditComponent } from './vault/add-edit.component';
import { AttachmentsComponent } from './vault/attachments.component';
import { CiphersComponent } from './vault/ciphers.component';
@ -48,6 +49,7 @@ import { CurrentTabComponent } from './vault/current-tab.component';
import { GroupingsComponent } from './vault/groupings.component';
import { PasswordHistoryComponent } from './vault/password-history.component';
import { ShareComponent } from './vault/share.component';
import { ViewCustomFieldsComponent } from './vault/view-custom-fields.component';
import { ViewComponent } from './vault/view.component';
import { EffluxDatesComponent as SendEffluxDatesComponent } from './send/efflux-dates.component';
@ -248,6 +250,8 @@ registerLocaleData(localeZhTw, 'zh-TW');
PasswordRepromptComponent,
SetPinComponent,
VaultTimeoutInputComponent,
AddEditCustomFieldsComponent,
ViewCustomFieldsComponent,
],
entryComponents: [],
providers: [

View File

@ -0,0 +1,53 @@
<div class="box">
<div class="box-header">
{{'customFields' | i18n}}
</div>
<div class="box-content">
<!-- Current custom fields -->
<div cdkDropList (cdkDropListDropped)="drop($event)" *ngIf="cipher.hasFields">
<div class="box-content-row box-content-row-multi box-draggable-row" appBoxRow cdkDrag
*ngFor="let f of cipher.fields; let i = index; trackBy:trackByFunction"
[ngClass]="{'box-content-row-checkbox': f.type === fieldType.Boolean}">
<a href="#" appStopClick (click)="removeField(f)" appA11yTitle="{{'remove' | i18n}}">
<i class="fa fa-minus-circle fa-lg" aria-hidden="true"></i>
</a>
<label for="fieldName{{i}}" class="sr-only">{{'name' | i18n}}</label>
<label for="fieldValue{{i}}" class="sr-only">{{'value' | i18n}}</label>
<div class="row-main">
<input id="fieldName{{i}}" type="text" name="Field.Name{{i}}" [(ngModel)]="f.name" class="row-label"
placeholder="{{'name' | i18n}}" appInputVerbatim>
<!--Custom Field: Text-->
<input id="fieldValue{{i}}" type="text" name="Field.Value{{i}}" [(ngModel)]="f.value"
*ngIf="f.type === fieldType.Text" placeholder="{{'value' | i18n}}" appInputVerbatim>
<!--Custom Field: Hidden-->
<input id="fieldValue{{i}}" type="{{f.showValue ? 'text' : 'password'}}" name="Field.Value{{i}}"
[(ngModel)]="f.value" class="monospaced" appInputVerbatim *ngIf="f.type === fieldType.Hidden"
placeholder="{{'value' | i18n}}" [disabled]="!cipher.viewPassword && !f.newField">
</div>
<!--Custom Field: Boolean-->
<input id="fieldValue{{i}}" name="Field.Value{{i}}" type="checkbox" [(ngModel)]="f.value"
*ngIf="f.type === fieldType.Boolean" appTrueFalseValue trueValue="true" falseValue="false">
<div class="action-buttons" *ngIf="f.type === fieldType.Hidden && (cipher.viewPassword || f.newField)">
<a class="row-btn" href="#" appStopClick appBlurClick appA11yTitle="{{'toggleVisibility' | i18n}}"
(click)="toggleFieldValue(f)">
<i class="fa fa-lg" aria-hidden="true"
[ngClass]="{'fa-eye': !f.showValue, 'fa-eye-slash': f.showValue}"></i>
</a>
</div>
<div class="drag-handle" appA11yTitle="{{'dragToSort' | i18n}}" cdkDragHandle>
<i class="fa fa-bars" aria-hidden="true"></i>
</div>
</div>
</div>
<!-- Add new custom field -->
<div class="box-content-row box-content-row-newmulti" appBoxRow>
<a href="#" appStopClick (click)="addField()">
<i class="fa fa-plus-circle fa-fw fa-lg" aria-hidden="true"></i> {{'newCustomField' | i18n}}
</a>
<label for="addFieldType" class="sr-only">{{'type' | i18n}}</label>
<select id="addFieldType" name="AddFieldType" [(ngModel)]="addFieldType" class="field-type">
<option *ngFor="let o of addFieldTypeOptions" [ngValue]="o.value">{{o.name}}</option>
</select>
</div>
</div>
</div>

View File

@ -0,0 +1,18 @@
import { Component } from '@angular/core';
import {
AddEditCustomFieldsComponent as BaseAddEditCustomFieldsComponent
} from 'jslib-angular/components/add-edit-custom-fields.component';
import { EventService } from 'jslib-common/abstractions/event.service';
import { I18nService } from 'jslib-common/abstractions/i18n.service';
@Component({
selector: 'app-vault-add-edit-custom-fields',
templateUrl: 'add-edit-custom-fields.component.html',
})
export class AddEditCustomFieldsComponent extends BaseAddEditCustomFieldsComponent {
constructor(i18nService: I18nService, eventService: EventService) {
super(i18nService, eventService);
}
}

View File

@ -324,56 +324,7 @@
</div>
</div>
</div>
<div class="box">
<div class="box-header">
{{'customFields' | i18n}}
</div>
<div class="box-content">
<div cdkDropList (cdkDropListDropped)="drop($event)" *ngIf="cipher.hasFields">
<div class="box-content-row box-content-row-multi box-draggable-row" appBoxRow cdkDrag
*ngFor="let f of cipher.fields; let i = index; trackBy:trackByFunction"
[ngClass]="{'box-content-row-checkbox': f.type === fieldType.Boolean}">
<a href="#" appStopClick (click)="removeField(f)" appA11yTitle="{{'remove' | i18n}}">
<i class="fa fa-minus-circle fa-lg" aria-hidden="true"></i>
</a>
<label for="fieldName{{i}}" class="sr-only">{{'name' | i18n}}</label>
<label for="fieldValue{{i}}" class="sr-only">{{'value' | i18n}}</label>
<div class="row-main">
<input id="fieldName{{i}}" type="text" name="Field.Name{{i}}" [(ngModel)]="f.name"
class="row-label" placeholder="{{'name' | i18n}}" appInputVerbatim>
<input id="fieldValue{{i}}" type="text" name="Field.Value{{i}}" [(ngModel)]="f.value"
*ngIf="f.type === fieldType.Text" placeholder="{{'value' | i18n}}" appInputVerbatim>
<input id="fieldValue{{i}}" type="{{f.showValue ? 'text' : 'password'}}"
name="Field.Value{{i}}" [(ngModel)]="f.value" class="monospaced" appInputVerbatim
*ngIf="f.type === fieldType.Hidden" placeholder="{{'value' | i18n}}"
[disabled]="!cipher.viewPassword && !f.newField">
</div>
<input id="fieldValue{{i}}" name="Field.Value{{i}}" type="checkbox" [(ngModel)]="f.value"
*ngIf="f.type === fieldType.Boolean" appTrueFalseValue trueValue="true" falseValue="false">
<div class="action-buttons"
*ngIf="f.type === fieldType.Hidden && (cipher.viewPassword || f.newField)">
<a class="row-btn" href="#" appStopClick appBlurClick
appA11yTitle="{{'toggleVisibility' | i18n}}" (click)="toggleFieldValue(f)">
<i class="fa fa-lg" aria-hidden="true"
[ngClass]="{'fa-eye': !f.showValue, 'fa-eye-slash': f.showValue}"></i>
</a>
</div>
<div class="drag-handle" appA11yTitle="{{'dragToSort' | i18n}}" cdkDragHandle>
<i class="fa fa-bars" aria-hidden="true"></i>
</div>
</div>
</div>
<div class="box-content-row box-content-row-newmulti" appBoxRow>
<a href="#" appStopClick (click)="addField()">
<i class="fa fa-plus-circle fa-fw fa-lg" aria-hidden="true"></i> {{'newCustomField' | i18n}}
</a>
<label for="addFieldType" class="sr-only">{{'type' | i18n}}</label>
<select id="addFieldType" name="AddFieldType" [(ngModel)]="addFieldType" class="field-type">
<option *ngFor="let o of addFieldTypeOptions" [ngValue]="o.value">{{o.name}}</option>
</select>
</div>
</div>
</div>
<app-vault-add-edit-custom-fields [cipher]="cipher" [editMode]="editMode"></app-vault-add-edit-custom-fields>
<div class="box" *ngIf="allowOwnershipOptions()">
<div class="box-header">
{{'ownership' | i18n}}

View File

@ -0,0 +1,37 @@
<ng-container>
<div class="box-header">
{{'customFields' | i18n}}
</div>
<div class="box-content">
<div class="box-content-row box-content-row-flex" *ngFor="let field of cipher.fields">
<div class="row-main">
<span class="row-label">{{field.name}}</span>
<div *ngIf="field.type === fieldType.Text">
{{field.value || '&nbsp;'}}
</div>
<div *ngIf="field.type === fieldType.Hidden">
<span [hidden]="!field.showValue" class="monospaced show-whitespace">{{field.value}}</span>
<span [hidden]="field.showValue" class="monospaced">{{field.maskedValue}}</span>
</div>
<div *ngIf="field.type === fieldType.Boolean">
<i class="fa fa-check-square-o" *ngIf="field.value === 'true'" aria-hidden="true"></i>
<i class="fa fa-square-o" *ngIf="field.value !== 'true'" aria-hidden="true"></i>
<span class="sr-only">{{field.value}}</span>
</div>
</div>
<div class="action-buttons">
<a class="row-btn" href="#" appStopClick appA11yTitle="{{'toggleVisibility' | i18n}}"
*ngIf="field.type === fieldType.Hidden && cipher.viewPassword"
(click)="toggleFieldValue(field)">
<i class="fa fa-lg" aria-hidden="true"
[ngClass]="{'fa-eye': !field.showValue, 'fa-eye-slash': field.showValue}"></i>
</a>
<a class="row-btn" href="#" appStopClick appA11yTitle="{{'copyValue' | i18n}}"
*ngIf="field.value && field.type !== fieldType.Boolean && !(field.type === fieldType.Hidden && !cipher.viewPassword)"
(click)="copy(field.value, 'value', field.type === fieldType.Hidden ? 'H_Field' : 'Field')">
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
</a>
</div>
</div>
</div>
</ng-container>

View File

@ -0,0 +1,19 @@
import {
Component,
} from '@angular/core';
import { EventService } from 'jslib-common/abstractions/event.service';
import {
ViewCustomFieldsComponent as BaseViewCustomFieldsComponent
} from 'jslib-angular/components/view-custom-fields.component';
@Component({
selector: 'app-vault-view-custom-fields',
templateUrl: 'view-custom-fields.component.html',
})
export class ViewCustomFieldsComponent extends BaseViewCustomFieldsComponent {
constructor(eventService: EventService) {
super(eventService);
}
}

View File

@ -221,41 +221,8 @@
</div>
</div>
<div class="box" *ngIf="cipher.hasFields">
<div class="box-header">
{{'customFields' | i18n}}
</div>
<div class="box-content">
<div class="box-content-row box-content-row-flex" *ngFor="let field of cipher.fields">
<div class="row-main">
<span class="row-label">{{field.name}}</span>
<div *ngIf="field.type === fieldType.Text">
{{field.value || '&nbsp;'}}
</div>
<div *ngIf="field.type === fieldType.Hidden">
<span [hidden]="!field.showValue" class="monospaced show-whitespace">{{field.value}}</span>
<span [hidden]="field.showValue" class="monospaced">{{field.maskedValue}}</span>
</div>
<div *ngIf="field.type === fieldType.Boolean">
<i class="fa fa-check-square-o" *ngIf="field.value === 'true'" aria-hidden="true"></i>
<i class="fa fa-square-o" *ngIf="field.value !== 'true'" aria-hidden="true"></i>
<span class="sr-only">{{field.value}}</span>
</div>
</div>
<div class="action-buttons">
<a class="row-btn" href="#" appStopClick appA11yTitle="{{'toggleVisibility' | i18n}}"
*ngIf="field.type === fieldType.Hidden && cipher.viewPassword"
(click)="toggleFieldValue(field)">
<i class="fa fa-lg" aria-hidden="true"
[ngClass]="{'fa-eye': !field.showValue, 'fa-eye-slash': field.showValue}"></i>
</a>
<a class="row-btn" href="#" appStopClick appA11yTitle="{{'copyValue' | i18n}}"
*ngIf="field.value && field.type !== fieldType.Boolean && !(field.type === fieldType.Hidden && !cipher.viewPassword)"
(click)="copy(field.value, 'value', field.type === fieldType.Hidden ? 'H_Field' : 'Field')">
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
</a>
</div>
</div>
</div>
<app-vault-view-custom-fields [cipher]="cipher" [promptPassword]="promptPassword.bind(this)"
[copy]="copy.bind(this)"></app-vault-view-custom-fields>
</div>
<div class="box" *ngIf="cipher.hasAttachments && (canAccessPremium || cipher.organizationId) && showAttachments">
<div class="box-header">