mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-24 12:06:15 +01:00
[Send] Add/Edit functionality (#1622)
* Update jslib (0951424
->1968dbf
) * [Send] Browser integration initial commit * Update jslib (1968dbf
->8a3b551
) * Cleaned up integration * added radio button style support // updated warning UI/UX * Update jslib (8a3b551
->42348e2)
This commit is contained in:
parent
2ac9f92267
commit
4853fb3e29
2
jslib
2
jslib
@ -1 +1 @@
|
||||
Subproject commit b0ae1bfa4cb3bc2642e1ecb14c6c1f0eceb06cb6
|
||||
Subproject commit 42348e2fdc6206157d68d8a9f496eaa70520ab01
|
@ -1506,7 +1506,7 @@
|
||||
"message": "Password protected"
|
||||
},
|
||||
"copySendLink": {
|
||||
"message": "Copy Send Link",
|
||||
"message": "Copy Send link",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"removePassword": {
|
||||
@ -1523,7 +1523,7 @@
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendLink": {
|
||||
"message": "Send Link",
|
||||
"message": "Send link",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"disabled": {
|
||||
@ -1539,5 +1539,110 @@
|
||||
"deleteSendConfirmation": {
|
||||
"message": "Are you sure you want to delete this Send?",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"editSend": {
|
||||
"message": "Edit Send",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendTypeHeader": {
|
||||
"message": "What type of Send is this?",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendNameDesc": {
|
||||
"message": "A friendly name to describe this Send.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendFileDesc": {
|
||||
"message": "The file you want to send."
|
||||
},
|
||||
"deletionDate": {
|
||||
"message": "Deletion Date"
|
||||
},
|
||||
"deletionDateDesc": {
|
||||
"message": "The Send will be permanently deleted on the specified date and time.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"expirationDate": {
|
||||
"message": "Expiration Date"
|
||||
},
|
||||
"expirationDateDesc": {
|
||||
"message": "If set, access to this Send will expire on the specified date and time.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"oneDay": {
|
||||
"message": "1 day"
|
||||
},
|
||||
"days": {
|
||||
"message": "$DAYS$ days",
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"content": "$1",
|
||||
"example": "2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom": {
|
||||
"message": "Custom"
|
||||
},
|
||||
"maximumAccessCount": {
|
||||
"message": "Maximum Access Count"
|
||||
},
|
||||
"maximumAccessCountDesc": {
|
||||
"message": "If set, users will no longer be able to access this Send once the maximum access count is reached.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendPasswordDesc": {
|
||||
"message": "Optionally require a password for users to access this Send.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendNotesDesc": {
|
||||
"message": "Private notes about this Send.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendDisableDesc": {
|
||||
"message": "Disable this Send so that no one can access it.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendShareDesc": {
|
||||
"message": "Copy this Send's link to clipboard upon save.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendTextDesc": {
|
||||
"message": "The text you want to send."
|
||||
},
|
||||
"sendHideText": {
|
||||
"message": "Hide this Send's text by default.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"currentAccessCount": {
|
||||
"message": "Current Access Count"
|
||||
},
|
||||
"createSend": {
|
||||
"message": "Create New Send",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "New Password"
|
||||
},
|
||||
"sendDisabledWarning": {
|
||||
"message": "Due to an enterprise policy, you are only able to delete an existing Send.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"createdSend": {
|
||||
"message": "Created Send",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"editedSend": {
|
||||
"message": "Edited Send",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendFirefoxFileWarning": {
|
||||
"message": "In order to choose a file using Firefox, open the extension in the sidebar or pop out to a new window by clicking this banner."
|
||||
},
|
||||
"sendSafariFileWarning": {
|
||||
"message": "In order to choose a file using Safari, pop out to a new window by clicking this banner."
|
||||
},
|
||||
"sendFileCalloutHeader": {
|
||||
"message": "Before you start"
|
||||
}
|
||||
}
|
||||
|
@ -190,4 +190,10 @@ export const routerTransition = trigger('routerTransition', [
|
||||
|
||||
transition('tabs => send-type', inSlideLeft),
|
||||
transition('send-type => tabs', outSlideRight),
|
||||
|
||||
transition('tabs => add-send, send-type => add-send', inSlideUp),
|
||||
transition('add-send => tabs, add-send => send-type', outSlideDown),
|
||||
|
||||
transition('tabs => edit-send, send-type => edit-send', inSlideUp),
|
||||
transition('edit-send => tabs, edit-send => send-type', outSlideDown),
|
||||
]);
|
||||
|
@ -46,6 +46,7 @@ import { PasswordHistoryComponent } from './vault/password-history.component';
|
||||
import { ShareComponent } from './vault/share.component';
|
||||
import { ViewComponent } from './vault/view.component';
|
||||
|
||||
import { SendAddEditComponent } from './send/send-add-edit.component';
|
||||
import { SendGroupingsComponent } from './send/send-groupings.component';
|
||||
import { SendTypeComponent } from './send/send-type.component';
|
||||
|
||||
@ -243,6 +244,18 @@ const routes: Routes = [
|
||||
canActivate: [AuthGuardService],
|
||||
data: { state: 'send-type' },
|
||||
},
|
||||
{
|
||||
path: 'add-send',
|
||||
component: SendAddEditComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
data: { state: 'add-send' },
|
||||
},
|
||||
{
|
||||
path: 'edit-send',
|
||||
component: SendAddEditComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
data: { state: 'edit-send' },
|
||||
},
|
||||
{
|
||||
path: 'tabs',
|
||||
component: TabsComponent,
|
||||
|
@ -145,6 +145,7 @@ export class AppComponent implements OnInit {
|
||||
if (url.startsWith('/tabs/') && (window as any).previousPopupUrl != null &&
|
||||
(window as any).previousPopupUrl.startsWith('/tabs/')) {
|
||||
this.stateService.remove('GroupingsComponent');
|
||||
this.stateService.remove('GroupingsComponentScope');
|
||||
this.stateService.remove('CiphersComponent');
|
||||
this.stateService.remove('SendGroupingsComponent');
|
||||
this.stateService.remove('SendGroupingsComponentScope');
|
||||
@ -152,7 +153,6 @@ export class AppComponent implements OnInit {
|
||||
}
|
||||
if (url.startsWith('/tabs/')) {
|
||||
this.stateService.remove('addEditCipherInfo');
|
||||
// TODO Remove any Send add/edit state information (?)
|
||||
}
|
||||
(window as any).previousPopupUrl = url;
|
||||
|
||||
|
@ -52,6 +52,7 @@ import { PasswordHistoryComponent } from './vault/password-history.component';
|
||||
import { ShareComponent } from './vault/share.component';
|
||||
import { ViewComponent } from './vault/view.component';
|
||||
|
||||
import { SendAddEditComponent } from './send/send-add-edit.component';
|
||||
import { SendGroupingsComponent } from './send/send-groupings.component';
|
||||
import { SendTypeComponent } from './send/send-type.component';
|
||||
|
||||
@ -81,6 +82,7 @@ import { IconComponent } from 'jslib/angular/components/icon.component';
|
||||
|
||||
import {
|
||||
CurrencyPipe,
|
||||
DatePipe,
|
||||
registerLocaleData,
|
||||
} from '@angular/common';
|
||||
import localeBe from '@angular/common/locales/be';
|
||||
@ -213,6 +215,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
|
||||
RegisterComponent,
|
||||
SearchCiphersPipe,
|
||||
SelectCopyDirective,
|
||||
SendAddEditComponent,
|
||||
SendGroupingsComponent,
|
||||
SendListComponent,
|
||||
SendTypeComponent,
|
||||
@ -232,6 +235,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
|
||||
entryComponents: [],
|
||||
providers: [
|
||||
CurrencyPipe,
|
||||
DatePipe,
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
|
@ -19,6 +19,32 @@
|
||||
}
|
||||
}
|
||||
|
||||
.box-header-expandable {
|
||||
margin: 0 10px 5px 10px;
|
||||
text-transform: uppercase;
|
||||
display: flex;
|
||||
|
||||
@include themify($themes) {
|
||||
color: themed('headingColor');
|
||||
}
|
||||
|
||||
&:hover, &:focus, &.active {
|
||||
@include themify($themes) {
|
||||
background-color: themed('boxBackgroundHoverColor');
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 5px;
|
||||
|
||||
@include themify($themes) {
|
||||
color: themed('headingColor');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.box-content {
|
||||
border-top: 1px solid #000000;
|
||||
border-bottom: 1px solid #000000;
|
||||
@ -202,6 +228,21 @@
|
||||
}
|
||||
}
|
||||
|
||||
.flex-label {
|
||||
font-size: $font-size-small;
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
margin-bottom: 5px;
|
||||
|
||||
@include themify($themes) {
|
||||
color: themed('mutedColor');
|
||||
}
|
||||
|
||||
> a {
|
||||
flex-grow: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.text, .detail {
|
||||
display: block;
|
||||
|
||||
@ -329,7 +370,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
input:not([type="checkbox"]), textarea {
|
||||
input:not([type="checkbox"]):not([type="radio"]), textarea {
|
||||
border: none;
|
||||
width: 100%;
|
||||
background-color: transparent !important;
|
||||
@ -546,4 +587,27 @@
|
||||
background-color: $brand-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.radio-group {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-bottom: 5px;
|
||||
|
||||
input {
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
margin: 0 0 0 5px;
|
||||
flex-grow: 1;
|
||||
font-size: $font-size-base;
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
||||
@include themify($themes) {
|
||||
color: themed('textColor');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -302,6 +302,14 @@ app-vault-icon {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.clickable {
|
||||
&:hover, &:focus, &.active {
|
||||
@include themify($themes) {
|
||||
background-color: themed('boxBackgroundHoverColor');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input[type="password"]::-ms-reveal {
|
||||
|
246
src/popup/send/send-add-edit.component.html
Normal file
246
src/popup/send/send-add-edit.component.html
Normal file
@ -0,0 +1,246 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<header>
|
||||
<div class="left">
|
||||
<button type="button" appBlurClick (click)="cancel()">{{'cancel' | i18n}}</button>
|
||||
</div>
|
||||
<div class="center">
|
||||
<span class="title">{{title}}</span>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick [disabled]="form.loading">
|
||||
<span [hidden]="form.loading">{{'save' | i18n}}</span>
|
||||
<i class="fa fa-spinner fa-lg fa-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<content *ngIf="send">
|
||||
<!-- File Warning -->
|
||||
<app-callout type="warning" icon="fa fa-external-link fa-rotate-270 fa-fw" [clickable]="true"
|
||||
title="{{'sendFileCalloutHeader' | i18n}}" *ngIf="showFilePopoutMessage && send.type === sendType.File"
|
||||
(click)="popOutWindow()">
|
||||
<div *ngIf="showFirefoxFileWarning">{{'sendFirefoxFileWarning' | i18n}}</div>
|
||||
<div *ngIf="showSafariFileWarning">{{'sendSafariFileWarning' | i18n}}</div>
|
||||
</app-callout>
|
||||
<!-- Name -->
|
||||
<div class="box">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="name">{{'name' | i18n}}</label>
|
||||
<input id="name" type="text" name="Name" [(ngModel)]="send.name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{{'sendNameDesc' | i18n}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Type Options -->
|
||||
<div class="box" *ngIf="!editMode">
|
||||
<div class="box-content no-hover">
|
||||
<div class="box-content-row">
|
||||
<label for="sendTypeOptions">{{'sendTypeHeader' | i18n}}</label>
|
||||
<div class="radio-group text-default" appBoxRow name="SendTypeOptions"
|
||||
*ngFor="let o of typeOptions">
|
||||
<input type="radio" [(ngModel)]="send.type" name="Type_{{o.value}}" id="type_{{o.value}}"
|
||||
[value]="o.value" (change)="typeChanged()" [checked]="send.type === o.value">
|
||||
<label for="type_{{o.value}}">
|
||||
{{o.name}}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- File -->
|
||||
<div class="box" *ngIf="send.type === sendType.File && (editMode || showFileSelector)">
|
||||
<div class="box-content no-hover">
|
||||
<div class="box-content-row" *ngIf="editMode">
|
||||
<label for="file">{{'file' | i18n}}</label>
|
||||
<div class="row-main">{{send.file.fileName}} ({{send.file.sizeName}})</div>
|
||||
</div>
|
||||
<div class="box-content-row" *ngIf="showFileSelector">
|
||||
<label for="file">{{'file' | i18n}}</label>
|
||||
<input type="file" id="file" name="file" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer" *ngIf="showFileSelector">
|
||||
{{'sendFileDesc' | i18n}} {{'maxFileSize' | i18n}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Text -->
|
||||
<div class="box" *ngIf="send.type === sendType.Text">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="text">{{'sendTypeText' | i18n}}</label>
|
||||
<textarea id="text" name="Text" rows="6" [(ngModel)]="send.text.text"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{{'sendTextDesc' | i18n}}
|
||||
</div>
|
||||
<div class="box-content">
|
||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
||||
<label for="hideText">{{'sendHideText' | i18n}}</label>
|
||||
<input id="hideText" type="checkbox" name="HideText" [(ngModel)]="send.text.hidden">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Share -->
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
{{'share' | i18n}}
|
||||
</div>
|
||||
<div class="box-content">
|
||||
<!-- Copy Link on Save -->
|
||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
||||
<label for="copyOnSave">{{'sendShareDesc' | i18n}}</label>
|
||||
<input id="copyOnSave" type="checkbox" name="CopyOnSave" [(ngModel)]="copyLink">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Options -->
|
||||
<div class="box">
|
||||
<div class="box-header-expandable" (click)="showOptions = !showOptions">
|
||||
{{'options' | i18n}}
|
||||
<i *ngIf="!showOptions" class="fa fa-chevron-down fa-sm icon"></i>
|
||||
<i *ngIf="showOptions" class="fa fa-chevron-up fa-sm icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
<ng-container *ngIf="showOptions">
|
||||
<!-- Deletion Date -->
|
||||
<div class="box">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row" *ngIf="!editMode">
|
||||
<label for="deletionDate">{{'deletionDate' | i18n}}</label>
|
||||
<select id="deletionDate" name="DeletionDateSelect" [(ngModel)]="deletionDateSelect" required>
|
||||
<option *ngFor="let o of deletionDateOptions" [ngValue]="o.value">{{o.name}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="box-content-row" *ngIf="deletionDateSelect === 0 && !editMode">
|
||||
<input id="deletionDateCustom" type="datetime-local" name="DeletionDate"
|
||||
[(ngModel)]="deletionDate" required placeholder="MM/DD/YYYY HH:MM AM/PM">
|
||||
</div>
|
||||
<div class="box-content-row" *ngIf="editMode" appBoxRow>
|
||||
<label for="editDeletionDate">{{'deletionDate' | i18n}}</label>
|
||||
<input id="editDeletionDate" type="datetime-local" name="EditDeletionDate"
|
||||
[(ngModel)]="deletionDate" required placeholder="MM/DD/YYYY HH:MM AM/PM">
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{{'deletionDateDesc' | i18n}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Expiration Date -->
|
||||
<div class="box">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row" *ngIf="!editMode">
|
||||
<label for="expirationDate">{{'expirationDate' | i18n}}</label>
|
||||
<select id="expirationDate" name="ExpirationDateSelect" [(ngModel)]="expirationDateSelect"
|
||||
required>
|
||||
<option *ngFor="let o of expirationDateOptions" [ngValue]="o.value">{{o.name}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="box-content-row" *ngIf="expirationDateSelect === 0 && !editMode">
|
||||
<input id="expirationDateCustom" type="datetime-local" name="ExpirationDate"
|
||||
[(ngModel)]="expirationDate" required placeholder="MM/DD/YYYY HH:MM AM/PM">
|
||||
</div>
|
||||
<div class="box-content-row" *ngIf="editMode" appBoxRow>
|
||||
<div class="flex-label">
|
||||
<label for="editExpirationDate">{{'expirationDate' | i18n}}</label>
|
||||
<a href="#" appStopClick (click)="clearExpiration()">
|
||||
{{'clear' | i18n}}
|
||||
</a>
|
||||
</div>
|
||||
<input id="editExpirationDate" type="datetime-local" name="EditExpirationDate"
|
||||
[(ngModel)]="expirationDate" placeholder="MM/DD/YYYY HH:MM AM/PM">
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{{'expirationDateDesc' | i18n}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Maximum Access Count -->
|
||||
<div class="box">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="maximumAccessCount">{{'maximumAccessCount' | i18n}}</label>
|
||||
<input id="maximumAccessCount" min="1" type="number" name="MaximumAccessCount"
|
||||
[(ngModel)]="send.maxAccessCount">
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{{'maximumAccessCountDesc' | i18n}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Current Access Count -->
|
||||
<div class="box" *ngIf="editMode">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="currentAccessCount">{{'currentAccessCount' | i18n}}</label>
|
||||
<input id="currentAccessCount" readonly type="number" name="CurrentAccessCount"
|
||||
[(ngModel)]="send.accessCount">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Password -->
|
||||
<div class="box">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row box-content-row-flex" appBoxRow>
|
||||
<div class="row-main">
|
||||
<label for="password" *ngIf="hasPassword">{{'newPassword' | i18n}}</label>
|
||||
<label for="password" *ngIf="!hasPassword">{{'password' | i18n}}</label>
|
||||
<input id="password" type="{{showPassword ? 'text' : 'password'}}" name="Password"
|
||||
class="monospaced" [(ngModel)]="password" appInputVerbatim>
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<a class="row-btn" href="#" appStopClick appBlurClick
|
||||
appA11yTitle="{{'toggleVisibility' | i18n}}" (click)="togglePasswordVisible()">
|
||||
<i class="fa fa-lg" [ngClass]="{'fa-eye': !showPassword, 'fa-eye-slash': showPassword}"
|
||||
aria-hidden="true"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{{'sendPasswordDesc' | i18n}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Notes -->
|
||||
<div class="box">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="notes">{{'notes' | i18n}}</label>
|
||||
<textarea id="notes" name="Notes" rows="6" [(ngModel)]="send.notes"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{{'sendNotesDesc' | i18n}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Disable Send -->
|
||||
<div class="box">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
||||
<label for="disableSend">{{'sendDisableDesc' | i18n}}</label>
|
||||
<input id="disableSend" type="checkbox" name="DisableSend" [(ngModel)]="send.disabled">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
<!-- Delete -->
|
||||
<div class="box list" *ngIf="editMode">
|
||||
<div class="box-content single-line">
|
||||
<a class="box-content-row" href="#" appStopClick appBlurClick (click)="delete()"
|
||||
[appApiAction]="deletePromise" #deleteBtn>
|
||||
<div class="row-main text-danger">
|
||||
<div class="icon text-danger" aria-hidden="true">
|
||||
<i class="fa fa-trash-o fa-lg fa-fw" [hidden]="deleteBtn.loading"></i>
|
||||
<i class="fa fa-spinner fa-spin fa-lg fa-fw" [hidden]="!deleteBtn.loading"></i>
|
||||
</div>
|
||||
<span>{{'deleteSend' | i18n}}</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</content>
|
||||
</form>
|
124
src/popup/send/send-add-edit.component.ts
Normal file
124
src/popup/send/send-add-edit.component.ts
Normal file
@ -0,0 +1,124 @@
|
||||
import {
|
||||
DatePipe,
|
||||
Location,
|
||||
} from '@angular/common';
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import {
|
||||
ActivatedRoute,
|
||||
Router,
|
||||
} from '@angular/router';
|
||||
|
||||
import { EnvironmentService } from 'jslib/abstractions/environment.service';
|
||||
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||
import { MessagingService } from 'jslib/abstractions/messaging.service';
|
||||
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
|
||||
import { PolicyService } from 'jslib/abstractions/policy.service';
|
||||
import { SendService } from 'jslib/abstractions/send.service';
|
||||
import { UserService } from 'jslib/abstractions/user.service';
|
||||
|
||||
import { PopupUtilsService } from '../services/popup-utils.service';
|
||||
|
||||
import { AddEditComponent as BaseAddEditComponent } from 'jslib/angular/components/send/add-edit.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-send-add-edit',
|
||||
templateUrl: 'send-add-edit.component.html',
|
||||
})
|
||||
export class SendAddEditComponent extends BaseAddEditComponent {
|
||||
// Options header
|
||||
showOptions = false;
|
||||
// File visibility
|
||||
isFirefox = false;
|
||||
isSafari = false;
|
||||
inPopout = false;
|
||||
inSidebar = false;
|
||||
|
||||
constructor(i18nService: I18nService, platformUtilsService: PlatformUtilsService,
|
||||
userService: UserService, messagingService: MessagingService, policyService: PolicyService,
|
||||
environmentService: EnvironmentService, datePipe: DatePipe, sendService: SendService,
|
||||
private route: ActivatedRoute, private router: Router, private location: Location,
|
||||
private popupUtilsService: PopupUtilsService) {
|
||||
super(i18nService, platformUtilsService, environmentService, datePipe, sendService, userService,
|
||||
messagingService, policyService);
|
||||
}
|
||||
|
||||
get showFileSelector(): boolean {
|
||||
return !this.editMode && (!this.isFirefox && !this.isSafari) ||
|
||||
(this.isFirefox && (this.inSidebar || this.inPopout)) ||
|
||||
(this.isSafari && this.inPopout);
|
||||
}
|
||||
|
||||
get showFilePopoutMessage(): boolean {
|
||||
return !this.editMode && (this.showFirefoxFileWarning || this.showSafariFileWarning);
|
||||
}
|
||||
|
||||
get showFirefoxFileWarning(): boolean {
|
||||
return this.isFirefox && !(this.inSidebar || this.inPopout);
|
||||
}
|
||||
|
||||
get showSafariFileWarning(): boolean {
|
||||
return this.isSafari && !this.inPopout;
|
||||
}
|
||||
|
||||
popOutWindow() {
|
||||
this.popupUtilsService.popOut(window);
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
// File visilibity
|
||||
this.isFirefox = this.platformUtilsService.isFirefox();
|
||||
this.isSafari = this.platformUtilsService.isSafari();
|
||||
this.inPopout = this.popupUtilsService.inPopout(window);
|
||||
this.inSidebar = this.popupUtilsService.inSidebar(window);
|
||||
|
||||
const queryParamsSub = this.route.queryParams.subscribe(async (params) => {
|
||||
if (params.sendId) {
|
||||
this.sendId = params.sendId;
|
||||
}
|
||||
if (params.type) {
|
||||
const type = parseInt(params.type, null);
|
||||
this.type = type;
|
||||
}
|
||||
await this.load();
|
||||
|
||||
if (queryParamsSub != null) {
|
||||
queryParamsSub.unsubscribe();
|
||||
}
|
||||
});
|
||||
|
||||
window.setTimeout(() => {
|
||||
if (!this.editMode) {
|
||||
document.getElementById('name').focus();
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
|
||||
async submit(): Promise<boolean> {
|
||||
if (await super.submit()) {
|
||||
this.cancel();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
async delete(): Promise<boolean> {
|
||||
if (await super.delete()) {
|
||||
this.cancel();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
cancel() {
|
||||
// If true, the window was pop'd out on the add-send page. location.back will not work
|
||||
if ((window as any).previousPopupUrl.startsWith('/add-send')) {
|
||||
this.router.navigate(['tabs/send']);
|
||||
} else {
|
||||
this.location.back();
|
||||
}
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ import {
|
||||
} from '@angular/core';
|
||||
|
||||
import {
|
||||
ActivatedRoute,
|
||||
Router,
|
||||
} from '@angular/router';
|
||||
|
||||
@ -50,7 +49,7 @@ export class SendGroupingsComponent extends BaseSendComponent {
|
||||
platformUtilsService: PlatformUtilsService, environmentService: EnvironmentService, ngZone: NgZone,
|
||||
policyService: PolicyService, userService: UserService, searchService: SearchService,
|
||||
private popupUtils: PopupUtilsService, private stateService: StateService,
|
||||
private route: ActivatedRoute, private router: Router, private syncService: SyncService,
|
||||
private router: Router, private syncService: SyncService,
|
||||
private changeDetectorRef: ChangeDetectorRef, private broadcasterService: BroadcasterService) {
|
||||
super(sendService, i18nService, platformUtilsService, environmentService, ngZone, searchService,
|
||||
policyService, userService);
|
||||
@ -122,11 +121,11 @@ export class SendGroupingsComponent extends BaseSendComponent {
|
||||
}
|
||||
|
||||
async selectSend(s: SendView) {
|
||||
// TODO -> Route to edit send
|
||||
this.router.navigate(['/edit-send'], { queryParams: { sendId: s.id } });
|
||||
}
|
||||
|
||||
async addSend() {
|
||||
// TODO -> Route to create send
|
||||
this.router.navigate(['/add-send']);
|
||||
}
|
||||
|
||||
showSearching() {
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
|
||||
import {
|
||||
ActivatedRoute,
|
||||
Router,
|
||||
} from '@angular/router';
|
||||
|
||||
import { Location } from '@angular/common';
|
||||
@ -47,7 +48,7 @@ export class SendTypeComponent extends BaseSendComponent {
|
||||
policyService: PolicyService, userService: UserService, searchService: SearchService,
|
||||
private popupUtils: PopupUtilsService, private stateService: StateService,
|
||||
private route: ActivatedRoute, private location: Location, private changeDetectorRef: ChangeDetectorRef,
|
||||
private broadcasterService: BroadcasterService) {
|
||||
private broadcasterService: BroadcasterService, private router: Router) {
|
||||
super(sendService, i18nService, platformUtilsService, environmentService, ngZone, searchService,
|
||||
policyService, userService);
|
||||
super.onSuccessfulLoad = async () => {
|
||||
@ -127,11 +128,11 @@ export class SendTypeComponent extends BaseSendComponent {
|
||||
}
|
||||
|
||||
async selectSend(s: SendView) {
|
||||
// TODO -> Route to edit send
|
||||
this.router.navigate(['/edit-send'], { queryParams: { sendId: s.id } });
|
||||
}
|
||||
|
||||
async addSend() {
|
||||
// TODO -> Route to create send
|
||||
this.router.navigate(['/add-send'], { queryParams: { type: this.type } });
|
||||
}
|
||||
|
||||
back() {
|
||||
|
Loading…
Reference in New Issue
Block a user