Skip to content

Commit

Permalink
[PM-11903] - add file send component (#11132)
Browse files Browse the repository at this point in the history
* wip - send file details

* wip - file send

* send file details

* fix click on send list container

* remove popup code

* remove popup code

* finalize send file details

* address PR feedback. add base form to send form

* revert changes to send list items container

* revert changes to send list items container

---------

Co-authored-by: Daniel James Smith <2670567+djsmith85@users.noreply.github.com>
  • Loading branch information
jaasen-livefront and djsmith85 authored Sep 18, 2024
1 parent 2b85392 commit 00f2317
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 15 deletions.
3 changes: 3 additions & 0 deletions apps/browser/src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,9 @@
"file": {
"message": "File"
},
"fileToShare": {
"message": "File to share"
},
"selectFile": {
"message": "Select a file"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,25 +117,18 @@ export class SendAddEditComponent {
)
.subscribe((config) => {
this.config = config;
this.headerText = this.getHeaderText(config.mode, config.sendType);
this.headerText = this.getHeaderText(config.mode);
});
}

/**
* Gets the header text based on the mode and type.
* Gets the header text based on the mode.
* @param mode The mode of the send form.
* @param type The type of the send form.
* @returns The header text.
*/
private getHeaderText(mode: SendFormMode, type: SendType) {
const headerKey =
mode === "edit" || mode === "partial-edit" ? "editItemHeader" : "newItemHeader";

switch (type) {
case SendType.Text:
return this.i18nService.t(headerKey, this.i18nService.t("sendTypeText"));
case SendType.File:
return this.i18nService.t(headerKey, this.i18nService.t("sendTypeFile"));
}
private getHeaderText(mode: SendFormMode) {
return this.i18nService.t(
mode === "edit" || mode === "partial-edit" ? "editSend" : "createSend",
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export class BaseSendDetailsComponent implements OnInit {
} as SendView);
});
});

this.sendFormContainer.registerChildForm("sendDetailsForm", this.sendDetailsForm);
}

async ngOnInit() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ <h2 bitTypography="h5">{{ "sendDetails" | i18n }}</h2>
[sendDetailsForm]="sendDetailsForm"
></tools-send-text-details>

<tools-send-file-details
*ngIf="config.sendType === FileSendType"
[config]="config"
[originalSendView]="originalSendView"
[sendDetailsForm]="sendDetailsForm"
></tools-send-file-details>

<bit-form-field>
<bit-label>{{ "deletionDate" | i18n }}</bit-label>
<bit-select
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
import { SendFormContainer } from "../../send-form-container";

import { BaseSendDetailsComponent } from "./base-send-details.component";
import { SendFileDetailsComponent } from "./send-file-details.component";
import { SendTextDetailsComponent } from "./send-text-details.component";

@Component({
Expand All @@ -34,6 +35,7 @@ import { SendTextDetailsComponent } from "./send-text-details.component";
FormFieldModule,
ReactiveFormsModule,
SendTextDetailsComponent,
SendFileDetailsComponent,
IconButtonModule,
CheckboxModule,
CommonModule,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<bit-section [formGroup]="sendFileDetailsForm">
<div *ngIf="config.mode === 'edit'">
<div class="tw-text-muted">{{ "file" | i18n }}</div>
<div>{{ originalSendView.file.fileName }}</div>
<div class="tw-text-muted">{{ originalSendView.file.sizeName }}</div>
</div>
<bit-form-field *ngIf="config.mode !== 'edit'">
<bit-label for="file">{{ "fileToShare" | i18n }}</bit-label>
<button bitButton type="button" buttonType="primary" (click)="fileSelector.click()">
{{ "chooseFile" | i18n }}
</button>
<span
class="tw-flex tw-items-center tw-pl-3"
[ngClass]="fileName ? 'tw-text-main' : 'tw-text-muted'"
>
{{ fileName || ("noFileChosen" | i18n) }}</span
>
<input
bitInput
#fileSelector
type="file"
formControlName="file"
hidden
(change)="onFileSelected($event)"
/>
<bit-hint>
{{ "maxFileSize" | i18n }}
</bit-hint>
</bit-form-field>
</bit-section>
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { CommonModule } from "@angular/common";
import { Component, Input, OnInit } from "@angular/core";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import {
FormBuilder,
FormControl,
FormGroup,
Validators,
ReactiveFormsModule,
FormsModule,
} from "@angular/forms";

import { JslibModule } from "@bitwarden/angular/jslib.module";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendFileView } from "@bitwarden/common/tools/send/models/view/send-file.view";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { ButtonModule, FormFieldModule, SectionComponent } from "@bitwarden/components";

import { SendFormConfig } from "../../abstractions/send-form-config.service";
import { SendFormContainer } from "../../send-form-container";

import { BaseSendDetailsForm } from "./base-send-details.component";

type BaseSendFileDetailsForm = FormGroup<{
file: FormControl<SendFileView | null>;
}>;

export type SendFileDetailsForm = BaseSendFileDetailsForm & BaseSendDetailsForm;

@Component({
selector: "tools-send-file-details",
templateUrl: "./send-file-details.component.html",
standalone: true,
imports: [
ButtonModule,
CommonModule,
JslibModule,
ReactiveFormsModule,
FormFieldModule,
SectionComponent,
FormsModule,
],
})
export class SendFileDetailsComponent implements OnInit {
@Input() config: SendFormConfig;
@Input() originalSendView?: SendView;
@Input() sendDetailsForm: BaseSendDetailsForm;

baseSendFileDetailsForm: BaseSendFileDetailsForm;
sendFileDetailsForm: SendFileDetailsForm;

FileSendType = SendType.File;
fileName = "";

constructor(
private formBuilder: FormBuilder,
protected sendFormContainer: SendFormContainer,
) {
this.baseSendFileDetailsForm = this.formBuilder.group({
file: this.formBuilder.control<SendFileView | null>(null, Validators.required),
});

this.sendFileDetailsForm = Object.assign(this.baseSendFileDetailsForm, this.sendDetailsForm);

this.sendFormContainer.registerChildForm("sendFileDetailsForm", this.sendFileDetailsForm);

this.sendFileDetailsForm.valueChanges.pipe(takeUntilDestroyed()).subscribe((value) => {
this.sendFormContainer.patchSend((send) => {
return Object.assign(send, {
file: value.file,
});
});
});
}

onFileSelected = (event: Event): void => {
const file = (event.target as HTMLInputElement).files?.[0];
if (!file) {
return;
}
this.fileName = file.name;
this.sendFormContainer.onFileSelected(file);
};

ngOnInit() {
if (this.originalSendView) {
this.sendFileDetailsForm.patchValue({
file: this.originalSendView.file,
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export class SendFormComponent implements AfterViewInit, OnInit, OnChanges, Send
private bitSubmit: BitSubmitDirective;
private destroyRef = inject(DestroyRef);
private _firstInitialized = false;
private file: File | null = null;

/**
* The form ID to use for the form. Used to connect it to a submit button.
Expand Down Expand Up @@ -188,14 +189,17 @@ export class SendFormComponent implements AfterViewInit, OnInit, OnChanges, Send
private i18nService: I18nService,
) {}

onFileSelected(file: File): void {
this.file = file;
}

submit = async () => {
if (this.sendForm.invalid) {
this.sendForm.markAllAsTouched();
return;
}

// TODO: Add file handling
await this.addEditFormService.saveSend(this.updatedSendView, null, this.config);
await this.addEditFormService.saveSend(this.updatedSendView, this.file, this.config);

this.toastService.showToast({
variant: "success",
Expand Down
4 changes: 4 additions & 0 deletions libs/tools/send/send-ui/src/send-form/send-form-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";

import { SendFormConfig } from "./abstractions/send-form-config.service";
import { SendDetailsComponent } from "./components/send-details/send-details.component";
import { SendFileDetailsForm } from "./components/send-details/send-file-details.component";
import { SendTextDetailsForm } from "./components/send-details/send-text-details.component";
/**
* The complete form for a send. Includes all the sub-forms from their respective section components.
Expand All @@ -10,6 +11,7 @@ import { SendTextDetailsForm } from "./components/send-details/send-text-details
export type SendForm = {
sendDetailsForm?: SendDetailsComponent["sendDetailsForm"];
sendTextDetailsForm?: SendTextDetailsForm;
sendFileDetailsForm?: SendFileDetailsForm;
};

/**
Expand Down Expand Up @@ -37,5 +39,7 @@ export abstract class SendFormContainer {
group: Exclude<SendForm[K], undefined>,
): void;

abstract onFileSelected(file: File): void;

abstract patchSend(updateFn: (current: SendView) => SendView): void;
}

0 comments on commit 00f2317

Please sign in to comment.