From df4dc00abacffba872b90cc6d934faf0885ffec0 Mon Sep 17 00:00:00 2001 From: jaasen-livefront Date: Wed, 11 Sep 2024 13:54:51 -0700 Subject: [PATCH] send text details --- apps/browser/src/_locales/en/messages.json | 8 ++- .../services/send-api.service.abstraction.ts | 2 +- .../tools/send/services/send-api.service.ts | 8 +-- .../abstractions/send-form.service.ts | 2 +- .../options/options-section.component.html | 2 +- .../send-text-details.component.html | 5 +- .../send-text-details.component.ts | 65 +++++++++++-------- .../src/send-form/send-form.stories.ts | 3 +- .../services/default-send-form.service.ts | 9 +-- 9 files changed, 54 insertions(+), 50 deletions(-) diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index e5f3a606f54..3e96c8417fd 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -2214,6 +2214,10 @@ "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendDetails": { + "message": "Send details", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "searchSends": { "message": "Search Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2246,14 +2250,14 @@ "message": "Limit views" }, "limitSendViewsHint": { - "message": "No one can view this Send after the limit is reached. $ACCESSCOUNT$ views", + "message": "No one can view this Send after the limit is reached.", "description": "Displayed under the limit views field on Send" }, "limitSendViewsHintWithCount": { "message": "No one can view this Send after the limit is reached. $ACCESSCOUNT$ views left", "description": "Displayed under the limit views field on Send", "placeholders": { - "days": { + "accessCount": { "content": "$1", "example": "2" } diff --git a/libs/common/src/tools/send/services/send-api.service.abstraction.ts b/libs/common/src/tools/send/services/send-api.service.abstraction.ts index 4109df19680..e2a44880286 100644 --- a/libs/common/src/tools/send/services/send-api.service.abstraction.ts +++ b/libs/common/src/tools/send/services/send-api.service.abstraction.ts @@ -36,5 +36,5 @@ export abstract class SendApiService { renewSendFileUploadUrl: (sendId: string, fileId: string) => Promise; removePassword: (id: string) => Promise; delete: (id: string) => Promise; - save: (sendData: [Send, EncArrayBuffer]) => Promise; + save: (sendData: [Send, EncArrayBuffer]) => Promise; } diff --git a/libs/common/src/tools/send/services/send-api.service.ts b/libs/common/src/tools/send/services/send-api.service.ts index 9ab6fb8827f..a7cb7468791 100644 --- a/libs/common/src/tools/send/services/send-api.service.ts +++ b/libs/common/src/tools/send/services/send-api.service.ts @@ -1,5 +1,3 @@ -import { SendId } from "@bitwarden/common/types/guid"; - import { ApiService } from "../../../abstractions/api.service"; import { ErrorResponse } from "../../../models/response/error.response"; import { ListResponse } from "../../../models/response/list.response"; @@ -137,13 +135,11 @@ export class SendApiService implements SendApiServiceAbstraction { return this.apiService.send("DELETE", "/sends/" + id, null, true, false); } - async save(sendData: [Send, EncArrayBuffer]): Promise { + async save(sendData: [Send, EncArrayBuffer]): Promise { const response = await this.upload(sendData); const data = new SendData(response); - const updated = await this.sendService.upsert(data); - // No local data for new Sends - return new Send(updated[response.id as SendId]); + await this.sendService.upsert(data); } async delete(id: string): Promise { diff --git a/libs/tools/send/send-ui/src/send-form/abstractions/send-form.service.ts b/libs/tools/send/send-ui/src/send-form/abstractions/send-form.service.ts index b851db927b4..a8b84540838 100644 --- a/libs/tools/send/send-ui/src/send-form/abstractions/send-form.service.ts +++ b/libs/tools/send/send-ui/src/send-form/abstractions/send-form.service.ts @@ -22,5 +22,5 @@ export abstract class SendFormService { send: SendView, file: File | ArrayBuffer, config: SendFormConfig, - ): Promise; + ): Promise; } diff --git a/libs/tools/send/send-ui/src/send-form/components/options/options-section.component.html b/libs/tools/send/send-ui/src/send-form/components/options/options-section.component.html index 87e9adcc471..8fccba6c0a8 100644 --- a/libs/tools/send/send-ui/src/send-form/components/options/options-section.component.html +++ b/libs/tools/send/send-ui/src/send-form/components/options/options-section.component.html @@ -8,7 +8,7 @@ {{ "limitSendViews" | i18n }} {{ "limitSendViewsHint" | i18n }} - {{ "limitSendViewsHintWithCount" | i18n }} + diff --git a/libs/tools/send/send-ui/src/send-form/components/send-details/send-text-details.component.html b/libs/tools/send/send-ui/src/send-form/components/send-details/send-text-details.component.html index 83242d5db30..7167208fdc9 100644 --- a/libs/tools/send/send-ui/src/send-form/components/send-details/send-text-details.component.html +++ b/libs/tools/send/send-ui/src/send-form/components/send-details/send-text-details.component.html @@ -1,7 +1,6 @@ - -

Send details

+

{{ "sendDetails" | i18n }}

@@ -28,7 +27,7 @@ formControlName="selectedDeletionDatePreset" > diff --git a/libs/tools/send/send-ui/src/send-form/components/send-details/send-text-details.component.ts b/libs/tools/send/send-ui/src/send-form/components/send-details/send-text-details.component.ts index b34b1aa319a..573f3f44629 100644 --- a/libs/tools/send/send-ui/src/send-form/components/send-details/send-text-details.component.ts +++ b/libs/tools/send/send-ui/src/send-form/components/send-details/send-text-details.component.ts @@ -65,25 +65,11 @@ export class SendTextDetailsComponent implements OnInit { name: ["", [Validators.required]], textToShare: [""], hideTextByDefault: [false], - // sendLink: [null as string], - selectedDeletionDatePreset: [DatePreset.SevenDays, Validators.required], + selectedDeletionDatePreset: [DatePreset.SevenDays || "", Validators.required], }); - get deletionDatePresets(): DatePresetSelectOption[] { - const defaultSelections = [ - { name: this.i18nService.t("oneHour"), value: DatePreset.OneHour }, - { name: this.i18nService.t("oneDay"), value: DatePreset.OneDay }, - { name: this.i18nService.t("days", "2"), value: DatePreset.TwoDays }, - { name: this.i18nService.t("days", "3"), value: DatePreset.ThreeDays }, - { name: this.i18nService.t("days", "7"), value: DatePreset.SevenDays }, - { name: this.i18nService.t("days", "14"), value: DatePreset.FourteenDays }, - { name: this.i18nService.t("days", "30"), value: DatePreset.ThirtyDays }, - ]; - if (!this.originalSendView.deletionDate) { - return defaultSelections; - } - return [{ name: null, value: this.formattedDeletionDate }, ...defaultSelections]; - } + customDeletionDateOption: DatePresetSelectOption | null = null; + datePresetOptions: DatePresetSelectOption[] = []; constructor( private sendFormContainer: SendFormContainer, @@ -95,37 +81,62 @@ export class SendTextDetailsComponent implements OnInit { this.sendTextDetailsForm.valueChanges.pipe(takeUntilDestroyed()).subscribe((value) => { this.sendFormContainer.patchSend((send) => { - Object.assign(send, { + return Object.assign(send, { name: value.name, text: { text: value.textToShare, hidden: value.hideTextByDefault }, deletionDate: new Date(this.formattedDeletionDate), expirationDate: new Date(this.formattedDeletionDate), } as SendView); - return send; }); }); } async ngOnInit() { + this.setupDeletionDatePresets(); + if (this.originalSendView) { this.sendTextDetailsForm.patchValue({ name: this.originalSendView.name, textToShare: this.originalSendView.text.text, hideTextByDefault: this.originalSendView.text.hidden, - selectedDeletionDatePreset: DatePreset.SevenDays, + selectedDeletionDatePreset: this.originalSendView.deletionDate.toString(), }); + + // If existing deletion date exists, calculate it once and store it + if (this.originalSendView.deletionDate) { + this.customDeletionDateOption = { + name: this.datePipe.transform(this.originalSendView.deletionDate, "MM/dd/yyyy, hh:mm a"), + value: this.originalSendView.deletionDate.toString(), + }; + this.datePresetOptions.unshift(this.customDeletionDateOption); + } } } + setupDeletionDatePresets() { + const defaultSelections: DatePresetSelectOption[] = [ + { name: this.i18nService.t("oneHour"), value: DatePreset.OneHour }, + { name: this.i18nService.t("oneDay"), value: DatePreset.OneDay }, + { name: this.i18nService.t("days", "2"), value: DatePreset.TwoDays }, + { name: this.i18nService.t("days", "3"), value: DatePreset.ThreeDays }, + { name: this.i18nService.t("days", "7"), value: DatePreset.SevenDays }, + { name: this.i18nService.t("days", "14"), value: DatePreset.FourteenDays }, + { name: this.i18nService.t("days", "30"), value: DatePreset.ThirtyDays }, + ]; + + this.datePresetOptions = defaultSelections; + } + get formattedDeletionDate(): string { const now = new Date(); - const milliseconds = now.setTime( - now.getTime() + - (this.sendTextDetailsForm.controls.selectedDeletionDatePreset.value as number) * - 60 * - 60 * - 1000, - ); + const selectedValue = this.sendTextDetailsForm.controls.selectedDeletionDatePreset.value; + + // If existing deletion date is selected, return it as is + if (typeof selectedValue === "string") { + return selectedValue; + } + + const milliseconds = now.setTime(now.getTime() + (selectedValue as number) * 60 * 60 * 1000); return new Date(milliseconds).toString(); } } diff --git a/libs/tools/send/send-ui/src/send-form/send-form.stories.ts b/libs/tools/send/send-ui/src/send-form/send-form.stories.ts index 2c47bd62626..f5f0e0521e9 100644 --- a/libs/tools/send/send-ui/src/send-form/send-form.stories.ts +++ b/libs/tools/send/send-ui/src/send-form/send-form.stories.ts @@ -36,9 +36,8 @@ class TestAddEditFormService implements SendFormService { decryptSend(): Promise { return Promise.resolve(defaultConfig.originalSend as any); } - async saveSend(send: SendView, file: File | ArrayBuffer): Promise { + async saveSend(send: SendView, file: File | ArrayBuffer): Promise { await new Promise((resolve) => setTimeout(resolve, 1000)); - return send; } } diff --git a/libs/tools/send/send-ui/src/send-form/services/default-send-form.service.ts b/libs/tools/send/send-ui/src/send-form/services/default-send-form.service.ts index a94fadc708f..7af4403dde1 100644 --- a/libs/tools/send/send-ui/src/send-form/services/default-send-form.service.ts +++ b/libs/tools/send/send-ui/src/send-form/services/default-send-form.service.ts @@ -17,13 +17,8 @@ export class DefaultSendFormService implements SendFormService { return await send.decrypt(); } - async saveSend( - send: SendView, - file: File | ArrayBuffer, - config: SendFormConfig, - ): Promise { + async saveSend(send: SendView, file: File | ArrayBuffer, config: SendFormConfig) { const sendData = await this.sendService.encrypt(send, file, send.password, null); - const savedSend = await this.sendApiService.save(sendData); - return await savedSend.decrypt(); + await this.sendApiService.save(sendData); } }