Merge pull request #1955 from bitwarden/SafariDateTimeWoes

Resolved Safari Date/Time Issues In Send
This commit is contained in:
Addison Beck 2021-07-16 14:31:43 -04:00 committed by GitHub
commit 829fb237c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 173 additions and 113 deletions

2
jslib

@ -1 +1 @@
Subproject commit f711c48696b5abc07998bb12b782b600bf7d53e6
Subproject commit 58be5796b0c2b19aacf52d4a1c179aeb80924443

View File

@ -6,7 +6,7 @@ import { AppRoutingModule } from './app-routing.module';
import { ServicesModule } from './services/services.module';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@ -47,6 +47,7 @@ import { PasswordHistoryComponent } from './vault/password-history.component';
import { ShareComponent } from './vault/share.component';
import { ViewComponent } from './vault/view.component';
import { EffluxDatesComponent as SendEffluxDatesComponent } from './send/efflux-dates.component';
import { SendAddEditComponent } from './send/send-add-edit.component';
import { SendGroupingsComponent } from './send/send-groupings.component';
import { SendTypeComponent } from './send/send-type.component';
@ -168,14 +169,15 @@ registerLocaleData(localeZhTw, 'zh-TW');
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
AppRoutingModule,
BrowserAnimationsModule,
BrowserModule,
DragDropModule,
FormsModule,
ReactiveFormsModule,
ScrollingModule,
ServicesModule,
ToasterModule.forRoot(),
DragDropModule,
ScrollingModule,
],
declarations: [
A11yTitleDirective,
@ -218,6 +220,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
SearchCiphersPipe,
SelectCopyDirective,
SendAddEditComponent,
SendEffluxDatesComponent,
SendGroupingsComponent,
SendListComponent,
SendTypeComponent,

View File

@ -0,0 +1,129 @@
<ng-container [formGroup]="datesForm">
<div class="box">
<div class="box-content">
<ng-container *ngIf="!editMode">
<div class="box-content-row" appBoxRow>
<label for="deletionDate">{{'deletionDate' | i18n}}</label>
<select id="deletionDate" name="DeletionDateSelect" formControlName="selectedDeletionDatePreset" required>
<option *ngFor="let o of deletionDatePresets" [ngValue]="o.value">{{o.name}}
</option>
</select>
</div>
<div class="box-content-row" appBoxRow *ngIf="selectedDeletionDatePreset.value === 0">
<ng-container *ngTemplateOutlet="deletionDateCustom"></ng-container>
</div>
</ng-container>
<div class="box-content-row" appBoxRow *ngIf="editMode">
<label for="deletionDate">{{'deletionDate' | i18n}}</label>
<ng-container *ngTemplateOutlet="deletionDateCustom"></ng-container>
</div>
</div>
<div class="box-footer">
{{'deletionDateDesc' | i18n}}
<ng-container
*ngIf="(!inPopout && browserPath == 'firefox') && (editMode || (selectedDeletionDatePreset.value === 0 && !editMode))">
<br>{{'sendFirefoxCustomDatePopoutMessage1' | i18n}} <a
(click)="popOutWindow.emit()">{{'sendFirefoxCustomDatePopoutMessage2' | i18n}}</a>
{{'sendFirefoxCustomDatePopoutMessage3' | i18n}}
</ng-container>
</div>
</div>
<div class="box">
<div class="box-content">
<ng-container *ngIf="!editMode">
<div class="box-content-row" *ngIf="!editMode" appBoxRow>
<label for="editExpirationDate">{{'expirationDate' | i18n}}</label>
<select id="expirationDate" name="ExpirationDateSelect"
formControlName="selectedExpirationDatePreset" required>
<option *ngFor="let o of expirationDatePresets" [ngValue]="o.value">{{o.name}}
</option>
</select>
</div>
<div class="box-content-row" *ngIf="selectedExpirationDatePreset.value === 0" appBoxRow>
<ng-container *ngTemplateOutlet="expirationDateCustom"></ng-container>
</div>
</ng-container>
<div class="box-content-row" *ngIf="editMode" appBoxRow>
<div class="flex-label">
<label>{{'expirationDate' | i18n}}</label>
<a *ngIf="!disabled" href="#" appStopClick (click)="clearExpiration()">
{{'clear' | i18n}}
</a>
</div>
<ng-container *ngTemplateOutlet="expirationDateCustom"></ng-container>
</div>
</div>
<div class="box-footer">
{{'expirationDateDesc' | i18n}}
<ng-container
*ngIf="(!inPopout && browserPath == 'firefox') && (editMode || (selectedExpirationDatePreset.value === 0 && !editMode))">
<br>{{'sendFirefoxCustomDatePopoutMessage1' | i18n}} <a
(click)="popOutWindow.emit()">{{'sendFirefoxCustomDatePopoutMessage2' | i18n}}</a>
{{'sendFirefoxCustomDatePopoutMessage3' | i18n}}
</ng-container>
</div>
</div>
<ng-template #deletionDateCustom>
<ng-container [ngSwitch]="browserPath">
<ng-container *ngSwitchCase="'firefox'">
<div class="flex flex-grow">
<input id="deletionDateCustomFallback" type="date" name="DeletionDateFallback"
formControlName="fallbackDeletionDate" required placeholder="MM/DD/YYYY"
[readOnly]="disabled" data-date-format="mm/dd/yyyy">
<input id="deletionTimeCustomFallback" type="time" name="DeletionTimeDate"
formControlName="fallbackDeletionTime" required placeholder="HH:MM AM/PM"
[readOnly]="disabled">
</div>
</ng-container>
<ng-container *ngSwitchCase="'safari'">
<div class="flex flex-grow">
<input id="deletionDateCustomFallback" type="date" name="DeletionDateFallback"
formControlName="fallbackDeletionDate" required placeholder="MM/DD/YYYY"
[readOnly]="disabled" data-date-format="mm/dd/yyyy">
<select id="deletionTimeCustomFallback" formControlName="fallbackDeletionTime"
name="SafariDeletionTime">
<option *ngFor="let o of safariDeletionTimePresetOptions" [ngValue]="o.twentyFourHour">{{o.twelveHour}}
</option>
</select>
</div>
</ng-container>
<ng-container *ngSwitchDefault>
<input id="deletionDateCustom" type="datetime-local" name="DeletionDate"
formControlName="defaultDeletionDateTime" required placeholder="MM/DD/YYYY HH:MM AM/PM">
</ng-container>
</ng-container>
</ng-template>
<ng-template #expirationDateCustom>
<ng-container [ngSwitch]="browserPath">
<ng-container *ngSwitchCase="'firefox'">
<div class="flex flex-grow">
<input id="expirationDateCustomFallback" type="date" name="ExpirationDateFallback"
formControlName="fallbackExpirationDate" [required]="!editMode" placeholder="MM/DD/YYYY"
[readOnly]="disabled" data-date-format="mm/dd/yyyy">
<input id="expirationTimeCustomFallback" type="time"
name="ExpirationTimeFallback" formControlName="fallbackExpirationTime"
[required]="!editMode" placeholder="HH:MM AM/PM" [readOnly]="disabled">
</div>
</ng-container>
<ng-container *ngSwitchCase="'safari'">
<div class="flex flex-grow">
<input id="expirationDateCustomFallback" type="date" name="ExpirationDateFallback"
formControlName="fallbackExpirationDate" [required]="!editMode" placeholder="MM/DD/YYYY"
[readOnly]="disabled" data-date-format="mm/dd/yyyy">
<select id="expirationTimeCustomFallback"
formControlName="fallbackExpirationTime" name="SafariExpirationTime">
<option *ngFor="let o of safariExpirationTimePresetOptions" [ngValue]="o.twentyFourHour">
{{o.twelveHour}}
</option>
</select>
</div>
</ng-container>
<ng-container *ngSwitchDefault>
<input id="expirationDateCustom" type="datetime-local" name="ExpirationDate"
formControlName="defaultExpirationDateTime" required placeholder="MM/DD/YYYY HH:MM AM/PM"
[readOnly]="disabled">
</ng-container>
</ng-container>
</ng-template>
</ng-container>

View File

@ -0,0 +1,30 @@
import { DatePipe } from '@angular/common';
import {
Component,
EventEmitter,
Input,
Output,
} from '@angular/core';
import { ControlContainer, NgForm } from '@angular/forms';
import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { EffluxDatesComponent as BaseEffluxDatesComponent } from 'jslib-angular/components/send/efflux-dates.component';
@Component({
selector: 'app-send-efflux-dates',
templateUrl: 'efflux-dates.component.html',
viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],
})
export class EffluxDatesComponent extends BaseEffluxDatesComponent {
@Input() readonly inPopout: boolean;
@Output() popOutWindow = new EventEmitter();
constructor(protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService,
protected datePipe: DatePipe) {
super(i18nService, platformUtilsService, datePipe);
}
}

View File

@ -117,112 +117,10 @@
</div>
</div>
<ng-container *ngIf="showOptions">
<!-- Deletion Date -->
<div class="box">
<div class="box-content">
<ng-template #deletionDateCustom>
<ng-container *ngIf="isDateTimeLocalSupported">
<input id="deletionDateCustom" type="datetime-local" name="DeletionDate"
[(ngModel)]="deletionDate" required placeholder="MM/DD/YYYY HH:MM AM/PM">
</ng-container>
<div class="flex flex-grow" *ngIf="!isDateTimeLocalSupported">
<input id="deletionDateCustomFallback" type="date" name="DeletionDateFallback"
[(ngModel)]="deletionDateFallback" required placeholder="MM/DD/YYYY"
[readOnly]="disableSend" data-date-format="mm/dd/yyyy">
<input *ngIf="!isSafari" id="deletionTimeCustomFallback" type="time" name="DeletionTimeDate"
[(ngModel)]="deletionTimeFallback" required placeholder="HH:MM AM/PM"
[readOnly]="disableSend">
<select *ngIf="isSafari" id="deletionTimeCustomFallback" [(ngModel)]="safariDeletionTime"
name="SafariDeletionTime">
<option *ngFor="let o of safariDeletionTimeOptions" [value]="o.military">{{o.standard}}
</option>
</select>
</div>
</ng-template>
<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>
<ng-container *ngIf="deletionDateSelect === 0 && !editMode">
<div class="box-content-row">
<ng-container *ngTemplateOutlet="deletionDateCustom"></ng-container>
</div>
</ng-container>
<ng-container *ngIf="editMode">
<div class="box-content-row" appBoxRow>
<label for="editDeletionDate">{{'deletionDate' | i18n}}</label>
<ng-container *ngTemplateOutlet="deletionDateCustom"></ng-container>
</div>
</ng-container>
</div>
<div class="box-footer">
{{'deletionDateDesc' | i18n}}
<ng-container
*ngIf="(!inPopout && isFirefox) && (this.editMode || (deletionDateSelect === 0 && !editMode))">
<br>{{'sendFirefoxCustomDatePopoutMessage1' | i18n}} <a
(click)="popOutWindow()">{{'sendFirefoxCustomDatePopoutMessage2' | i18n}}</a>
{{'sendFirefoxCustomDatePopoutMessage3' | i18n}}
</ng-container>
</div>
</div>
<!-- Expiration Date -->
<div class="box">
<div class="box-content">
<ng-template #expirationDateCustom>
<ng-container *ngIf="isDateTimeLocalSupported">
<input id="expirationDateCustom" type="datetime-local" name="ExpirationDate"
[(ngModel)]="expirationDate" required placeholder="MM/DD/YYYY HH:MM AM/PM"
[readOnly]="disableSend">
</ng-container>
<div class="flex flex-grow" *ngIf="!isDateTimeLocalSupported">
<input id="expirationDateCustomFallback" type="date" name="ExpirationDateFallback"
[(ngModel)]="expirationDateFallback" [required]="!editMode" placeholder="MM/DD/YYYY"
[readOnly]="disableSend" (change)="expirationDateFallbackChanged()"
data-date-format="mm/dd/yyyy">
<input *ngIf="!isSafari" id="expirationTimeCustomFallback" type="time"
name="ExpirationTimeFallback" [(ngModel)]="expirationTimeFallback"
[required]="!editMode" placeholder="HH:MM AM/PM" [readOnly]="disableSend">
<select *ngIf="isSafari" id="expirationTimeCustomFallback"
[(ngModel)]="safariExpirationTime" name="SafariExpirationTime">
<option *ngFor="let o of safariExpirationTimeOptions" [value]="o.military">
{{o.standard}}</option>
</select>
</div>
</ng-template>
<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">
<ng-container *ngTemplateOutlet="expirationDateCustom"></ng-container>
</div>
<div class="box-content-row" *ngIf="editMode" appBoxRow>
<div class="flex-label">
<label for="editExpirationDate">{{'expirationDate' | i18n}}</label>
<a *ngIf="!disableSend" href="#" appStopClick (click)="clearExpiration()">
{{'clear' | i18n}}
</a>
</div>
<ng-container *ngTemplateOutlet="expirationDateCustom"></ng-container>
</div>
</div>
<div class="box-footer">
{{'expirationDateDesc' | i18n}}
<ng-container
*ngIf="(!inPopout && isFirefox) && (this.editMode || (deletionDateSelect === 0 && !editMode))">
<br>{{'sendFirefoxCustomDatePopoutMessage1' | i18n}} <a
(click)="popOutWindow()">{{'sendFirefoxCustomDatePopoutMessage2' | i18n}}</a>
{{'sendFirefoxCustomDatePopoutMessage3' | i18n}}
</ng-container>
</div>
</div>
<app-send-efflux-dates
[initialDeletionDate]="send.deletionDate" [initialExpirationDate]="send.expirationDate"
[editMode]="editMode" [disabled]="disableSend" (datesChanged)="setDates($event)" (popOutWindow)="popOutWindow()">
</app-send-efflux-dates>
<!-- Maximum Access Count -->
<div class="box">
<div class="box-content">