mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-24 12:06:15 +01: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:
parent
342871a216
commit
9685f2c2b3
15
package-lock.json
generated
15
package-lock.json
generated
@ -407,6 +407,15 @@
|
|||||||
"tslib": "^1.9.0"
|
"tslib": "^1.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@angular/cdk": {
|
||||||
|
"version": "7.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-7.2.1.tgz",
|
||||||
|
"integrity": "sha512-oU1Pjq3JkDtkXquLxWK84A2jOCeYRf352dVGbQCxWoSOQ5KBtMAd42huGidPiOSHN6/f7xZwL3n4fq3fVIut8A==",
|
||||||
|
"requires": {
|
||||||
|
"parse5": "^5.0.0",
|
||||||
|
"tslib": "^1.7.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@angular/common": {
|
"@angular/common": {
|
||||||
"version": "7.2.1",
|
"version": "7.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.1.tgz",
|
||||||
@ -8338,6 +8347,12 @@
|
|||||||
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
|
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"parse5": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"parseurl": {
|
"parseurl": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "7.2.1",
|
"@angular/animations": "7.2.1",
|
||||||
|
"@angular/cdk": "7.2.1",
|
||||||
"@angular/common": "7.2.1",
|
"@angular/common": "7.2.1",
|
||||||
"@angular/compiler": "7.2.1",
|
"@angular/compiler": "7.2.1",
|
||||||
"@angular/core": "7.2.1",
|
"@angular/core": "7.2.1",
|
||||||
|
@ -7,6 +7,7 @@ import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
|||||||
|
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
|
|
||||||
|
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
@ -228,6 +229,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
|
|||||||
}),
|
}),
|
||||||
ToasterModule.forRoot(),
|
ToasterModule.forRoot(),
|
||||||
InfiniteScrollModule,
|
InfiniteScrollModule,
|
||||||
|
DragDropModule,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AcceptOrganizationComponent,
|
AcceptOrganizationComponent,
|
||||||
|
@ -362,60 +362,66 @@
|
|||||||
</div>
|
</div>
|
||||||
<h3 class="mt-4">{{'customFields' | i18n}}</h3>
|
<h3 class="mt-4">{{'customFields' | i18n}}</h3>
|
||||||
<ng-container *ngIf="cipher.hasFields">
|
<ng-container *ngIf="cipher.hasFields">
|
||||||
<div class="row" appBoxRow *ngFor="let f of cipher.fields; let i = index; trackBy:trackByFunction">
|
<div cdkDropList (cdkDropListDropped)="drop($event)">
|
||||||
<div class="col-5 form-group">
|
<div class="row" appBoxRow cdkDrag
|
||||||
<div class="d-flex">
|
*ngFor="let f of cipher.fields; let i = index; trackBy:trackByFunction" >
|
||||||
<label for="fieldName{{i}}">{{'name' | i18n}}</label>
|
<div class="col-5 form-group">
|
||||||
<a class="ml-auto" href="https://help.bitwarden.com/article/custom-fields/"
|
<div class="d-flex">
|
||||||
target="_blank" rel="noopener" title="{{'learnMore' | i18n}}">
|
<label for="fieldName{{i}}">{{'name' | i18n}}</label>
|
||||||
<i class="fa fa-question-circle-o"></i>
|
<a class="ml-auto" href="https://help.bitwarden.com/article/custom-fields/"
|
||||||
</a>
|
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>
|
</div>
|
||||||
<input id="fieldName{{i}}" type="text" name="Field.Name{{i}}" [(ngModel)]="f.name"
|
<div class="col-7 form-group">
|
||||||
class="form-control" appInputVerbatim>
|
<label for="fieldValue{{i}}">{{'value' | i18n}}</label>
|
||||||
</div>
|
<div class="d-flex align-items-center">
|
||||||
<div class="col-7 form-group">
|
<div class="input-group" *ngIf="f.type === fieldType.Text">
|
||||||
<label for="fieldValue{{i}}">{{'value' | i18n}}</label>
|
<input id="fieldValue{{i}}" class="form-control" type="text" name="Field.Value{{i}}"
|
||||||
<div class="d-flex align-items-center">
|
[(ngModel)]="f.value" appInputVerbatim>
|
||||||
<div class="input-group" *ngIf="f.type === fieldType.Text">
|
<div class="input-group-append">
|
||||||
<input id="fieldValue{{i}}" class="form-control" type="text" name="Field.Value{{i}}"
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
[(ngModel)]="f.value" appInputVerbatim>
|
title="{{'copyValue' | i18n}}" (click)="copy(f.value, 'value', 'Field')"
|
||||||
<div class="input-group-append">
|
tabindex="-1">
|
||||||
<button type="button" class="btn btn-outline-secondary"
|
<i class="fa fa-lg fa-clipboard"></i>
|
||||||
title="{{'copyValue' | i18n}}" (click)="copy(f.value, 'value', 'Field')"
|
</button>
|
||||||
tabindex="-1">
|
</div>
|
||||||
<i class="fa fa-lg fa-clipboard"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="input-group" *ngIf="f.type === fieldType.Hidden">
|
||||||
<div class="input-group" *ngIf="f.type === fieldType.Hidden">
|
<input id="fieldValue{{i}}" type="{{f.showValue ? 'text' : 'password'}}"
|
||||||
<input id="fieldValue{{i}}" type="{{f.showValue ? 'text' : 'password'}}"
|
name="Field.Value{{i}}" [(ngModel)]="f.value"
|
||||||
name="Field.Value{{i}}" [(ngModel)]="f.value"
|
class="form-control text-monospace" appInputVerbatim
|
||||||
class="form-control text-monospace" appInputVerbatim
|
autocomplete="new-password">
|
||||||
autocomplete="new-password">
|
<div class="input-group-append">
|
||||||
<div class="input-group-append">
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
<button type="button" class="btn btn-outline-secondary"
|
title="{{'toggleVisibility' | i18n}}" (click)="toggleFieldValue(f)"
|
||||||
title="{{'toggleVisibility' | i18n}}" (click)="toggleFieldValue(f)"
|
tabindex="-1">
|
||||||
tabindex="-1">
|
<i class="fa fa-lg"
|
||||||
<i class="fa fa-lg"
|
[ngClass]="{'fa-eye': !f.showValue, 'fa-eye-slash': f.showValue}"></i>
|
||||||
[ngClass]="{'fa-eye': !f.showValue, 'fa-eye-slash': f.showValue}"></i>
|
</button>
|
||||||
</button>
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
<button type="button" class="btn btn-outline-secondary"
|
title="{{'copyValue' | i18n}}" (click)="copy(f.value, 'value', 'Field')"
|
||||||
title="{{'copyValue' | i18n}}" (click)="copy(f.value, 'value', 'Field')"
|
tabindex="-1">
|
||||||
tabindex="-1">
|
<i class="fa fa-lg fa-clipboard"></i>
|
||||||
<i class="fa fa-lg fa-clipboard"></i>
|
</button>
|
||||||
</button>
|
</div>
|
||||||
</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>
|
||||||
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -785,3 +785,15 @@ img.logo {
|
|||||||
.overflow-hidden {
|
.overflow-hidden {
|
||||||
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;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user