1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-19 09:43:23 +00:00

Drag n drop sorting for custom fields (#370)

* Implement custom field ordering with new handle placement

* Update reference for jslib
This commit is contained in:
Kovah
2019-03-28 16:39:49 +01:00
committed by Kyle Spearrin
parent 342871a216
commit 9685f2c2b3
5 changed files with 86 additions and 50 deletions

View File

@@ -7,6 +7,7 @@ import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { AppRoutingModule } from './app-routing.module';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
@@ -228,6 +229,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
}),
ToasterModule.forRoot(),
InfiniteScrollModule,
DragDropModule,
],
declarations: [
AcceptOrganizationComponent,

View File

@@ -362,60 +362,66 @@
</div>
<h3 class="mt-4">{{'customFields' | i18n}}</h3>
<ng-container *ngIf="cipher.hasFields">
<div class="row" appBoxRow *ngFor="let f of cipher.fields; let i = index; trackBy:trackByFunction">
<div class="col-5 form-group">
<div class="d-flex">
<label for="fieldName{{i}}">{{'name' | i18n}}</label>
<a class="ml-auto" href="https://help.bitwarden.com/article/custom-fields/"
target="_blank" rel="noopener" title="{{'learnMore' | i18n}}">
<i class="fa fa-question-circle-o"></i>
</a>
<div cdkDropList (cdkDropListDropped)="drop($event)">
<div class="row" appBoxRow cdkDrag
*ngFor="let f of cipher.fields; let i = index; trackBy:trackByFunction" >
<div class="col-5 form-group">
<div class="d-flex">
<label for="fieldName{{i}}">{{'name' | i18n}}</label>
<a class="ml-auto" href="https://help.bitwarden.com/article/custom-fields/"
target="_blank" rel="noopener" title="{{'learnMore' | i18n}}">
<i class="fa fa-question-circle-o"></i>
</a>
</div>
<input id="fieldName{{i}}" type="text" name="Field.Name{{i}}" [(ngModel)]="f.name"
class="form-control" appInputVerbatim>
</div>
<input id="fieldName{{i}}" type="text" name="Field.Name{{i}}" [(ngModel)]="f.name"
class="form-control" appInputVerbatim>
</div>
<div class="col-7 form-group">
<label for="fieldValue{{i}}">{{'value' | i18n}}</label>
<div class="d-flex align-items-center">
<div class="input-group" *ngIf="f.type === fieldType.Text">
<input id="fieldValue{{i}}" class="form-control" type="text" name="Field.Value{{i}}"
[(ngModel)]="f.value" appInputVerbatim>
<div class="input-group-append">
<button type="button" class="btn btn-outline-secondary"
title="{{'copyValue' | i18n}}" (click)="copy(f.value, 'value', 'Field')"
tabindex="-1">
<i class="fa fa-lg fa-clipboard"></i>
</button>
<div class="col-7 form-group">
<label for="fieldValue{{i}}">{{'value' | i18n}}</label>
<div class="d-flex align-items-center">
<div class="input-group" *ngIf="f.type === fieldType.Text">
<input id="fieldValue{{i}}" class="form-control" type="text" name="Field.Value{{i}}"
[(ngModel)]="f.value" appInputVerbatim>
<div class="input-group-append">
<button type="button" class="btn btn-outline-secondary"
title="{{'copyValue' | i18n}}" (click)="copy(f.value, 'value', 'Field')"
tabindex="-1">
<i class="fa fa-lg fa-clipboard"></i>
</button>
</div>
</div>
</div>
<div class="input-group" *ngIf="f.type === fieldType.Hidden">
<input id="fieldValue{{i}}" type="{{f.showValue ? 'text' : 'password'}}"
name="Field.Value{{i}}" [(ngModel)]="f.value"
class="form-control text-monospace" appInputVerbatim
autocomplete="new-password">
<div class="input-group-append">
<button type="button" class="btn btn-outline-secondary"
title="{{'toggleVisibility' | i18n}}" (click)="toggleFieldValue(f)"
tabindex="-1">
<i class="fa fa-lg"
[ngClass]="{'fa-eye': !f.showValue, 'fa-eye-slash': f.showValue}"></i>
</button>
<button type="button" class="btn btn-outline-secondary"
title="{{'copyValue' | i18n}}" (click)="copy(f.value, 'value', 'Field')"
tabindex="-1">
<i class="fa fa-lg fa-clipboard"></i>
</button>
<div class="input-group" *ngIf="f.type === fieldType.Hidden">
<input id="fieldValue{{i}}" type="{{f.showValue ? 'text' : 'password'}}"
name="Field.Value{{i}}" [(ngModel)]="f.value"
class="form-control text-monospace" appInputVerbatim
autocomplete="new-password">
<div class="input-group-append">
<button type="button" class="btn btn-outline-secondary"
title="{{'toggleVisibility' | i18n}}" (click)="toggleFieldValue(f)"
tabindex="-1">
<i class="fa fa-lg"
[ngClass]="{'fa-eye': !f.showValue, 'fa-eye-slash': f.showValue}"></i>
</button>
<button type="button" class="btn btn-outline-secondary"
title="{{'copyValue' | i18n}}" (click)="copy(f.value, 'value', 'Field')"
tabindex="-1">
<i class="fa fa-lg fa-clipboard"></i>
</button>
</div>
</div>
<div class="flex-fill">
<input id="fieldValue{{i}}" name="Field.Value{{i}}" type="checkbox"
[(ngModel)]="f.value" *ngIf="f.type === fieldType.Boolean" appTrueFalseValue
trueValue="true" falseValue="false">
</div>
<button type="button" class="btn btn-link text-danger ml-2" (click)="removeField(f)"
title="{{'remove' | i18n}}">
<i class="fa fa-minus-circle fa-lg"></i>
</button>
<span class="text-muted cursor-move" title="{{'dragToSort' | i18n}}">
<i class="fa fa-bars"></i>
</span>
</div>
<div class="flex-fill">
<input id="fieldValue{{i}}" name="Field.Value{{i}}" type="checkbox"
[(ngModel)]="f.value" *ngIf="f.type === fieldType.Boolean" appTrueFalseValue
trueValue="true" falseValue="false">
</div>
<button type="button" class="btn btn-link text-danger ml-2" (click)="removeField(f)"
title="{{'remove' | i18n}}">
<i class="fa fa-minus-circle fa-lg"></i>
</button>
</div>
</div>
</div>

View File

@@ -785,3 +785,15 @@ img.logo {
.overflow-hidden {
overflow: hidden;
}
.cdk-drag-preview {
z-index: $zindex-tooltip !important;
padding: $spacer / 2;
opacity: .8;
background-color: $white;
border-radius: $border-radius;
}
.cursor-move {
cursor: move;
}