mirror of
https://github.com/bitwarden/browser
synced 2026-01-28 15:23:53 +00:00
Changes attachment modal to remove choose file button and changes upload button to close button if the user doesn't have edit rights to the cipher.
This commit is contained in:
@@ -496,6 +496,7 @@ export class VaultV2Component<C extends CipherViewLike>
|
||||
}
|
||||
const dialogRef = AttachmentsV2Component.open(this.dialogService, {
|
||||
cipherId: this.cipherId as CipherId,
|
||||
canEditCipher: this.cipher().edit,
|
||||
});
|
||||
const result = await firstValueFrom(dialogRef.closed).catch((): any => null);
|
||||
if (
|
||||
|
||||
@@ -925,6 +925,7 @@ export class VaultComponent<C extends CipherViewLike> implements OnInit, OnDestr
|
||||
const dialogRef = AttachmentsV2Component.open(this.dialogService, {
|
||||
cipherId: cipher.id as CipherId,
|
||||
organizationId: cipher.organizationId as OrganizationId,
|
||||
canEditCipher: cipher.edit,
|
||||
});
|
||||
|
||||
const result: AttachmentDialogCloseResult = await lastValueFrom(dialogRef.closed);
|
||||
|
||||
@@ -38,14 +38,16 @@
|
||||
</button>
|
||||
}
|
||||
</bit-item-action>
|
||||
<bit-item-action>
|
||||
<app-delete-attachment
|
||||
[admin]="admin() && organization()?.canEditAllCiphers"
|
||||
[cipherId]="cipher().id"
|
||||
[attachment]="attachment"
|
||||
(onDeletionSuccess)="removeAttachment(attachment)"
|
||||
></app-delete-attachment>
|
||||
</bit-item-action>
|
||||
@if (cipher().edit) {
|
||||
<bit-item-action>
|
||||
<app-delete-attachment
|
||||
[admin]="admin() && organization()?.canEditAllCiphers"
|
||||
[cipherId]="cipher().id"
|
||||
[attachment]="attachment"
|
||||
(onDeletionSuccess)="removeAttachment(attachment)"
|
||||
></app-delete-attachment>
|
||||
</bit-item-action>
|
||||
}
|
||||
</ng-container>
|
||||
</bit-item>
|
||||
</li>
|
||||
@@ -54,46 +56,48 @@
|
||||
}
|
||||
|
||||
<form [id]="attachmentFormId" [formGroup]="attachmentForm" [bitSubmit]="submit">
|
||||
<bit-card>
|
||||
<label for="file" bitTypography="body2" class="tw-block tw-text-muted tw-px-1 tw-pb-1.5">
|
||||
{{ "addAttachment" | i18n }}
|
||||
</label>
|
||||
<div class="tw-relative">
|
||||
<!-- Input elements are notoriously difficult to style, --->
|
||||
<!-- The native `<input>` will be used for screen readers -->
|
||||
<!-- Visual & keyboard users will interact with the styled button element -->
|
||||
<input
|
||||
#fileInput
|
||||
class="tw-sr-only"
|
||||
type="file"
|
||||
id="file"
|
||||
name="file"
|
||||
aria-describedby="fileHelp"
|
||||
tabindex="-1"
|
||||
required
|
||||
(change)="onFileChange($event)"
|
||||
/>
|
||||
<div class="tw-flex tw-gap-2 tw-items-center" aria-hidden="true">
|
||||
<button
|
||||
bitButton
|
||||
buttonType="secondary"
|
||||
type="button"
|
||||
(click)="fileInput.click()"
|
||||
class="tw-whitespace-nowrap"
|
||||
>
|
||||
{{ "chooseFile" | i18n }}
|
||||
</button>
|
||||
<p bitTypography="body2" class="tw-text-muted tw-mb-0">
|
||||
{{
|
||||
this.attachmentForm.controls.file?.value
|
||||
? this.attachmentForm.controls.file.value.name
|
||||
: ("noFileChosen" | i18n)
|
||||
}}
|
||||
</p>
|
||||
@if (cipher()?.edit) {
|
||||
<bit-card>
|
||||
<label for="file" bitTypography="body2" class="tw-block tw-text-muted tw-px-1 tw-pb-1.5">
|
||||
{{ "addAttachment" | i18n }}
|
||||
</label>
|
||||
<div class="tw-relative">
|
||||
<!-- Input elements are notoriously difficult to style, --->
|
||||
<!-- The native `<input>` will be used for screen readers -->
|
||||
<!-- Visual & keyboard users will interact with the styled button element -->
|
||||
<input
|
||||
#fileInput
|
||||
class="tw-sr-only"
|
||||
type="file"
|
||||
id="file"
|
||||
name="file"
|
||||
aria-describedby="fileHelp"
|
||||
tabindex="-1"
|
||||
required
|
||||
(change)="onFileChange($event)"
|
||||
/>
|
||||
<div class="tw-flex tw-gap-2 tw-items-center" aria-hidden="true">
|
||||
<button
|
||||
bitButton
|
||||
buttonType="secondary"
|
||||
type="button"
|
||||
(click)="fileInput.click()"
|
||||
class="tw-whitespace-nowrap"
|
||||
>
|
||||
{{ "chooseFile" | i18n }}
|
||||
</button>
|
||||
<p bitTypography="body2" class="tw-text-muted tw-mb-0">
|
||||
{{
|
||||
this.attachmentForm.controls.file?.value
|
||||
? this.attachmentForm.controls.file.value.name
|
||||
: ("noFileChosen" | i18n)
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p id="fileHelp" bitTypography="helper" class="tw-text-muted tw-px-1 tw-pt-1 tw-mb-0">
|
||||
{{ "maxFileSizeSansPunctuation" | i18n }}
|
||||
</p>
|
||||
</bit-card>
|
||||
<p id="fileHelp" bitTypography="helper" class="tw-text-muted tw-px-1 tw-pt-1 tw-mb-0">
|
||||
{{ "maxFileSizeSansPunctuation" | i18n }}
|
||||
</p>
|
||||
</bit-card>
|
||||
}
|
||||
</form>
|
||||
|
||||
@@ -105,6 +105,8 @@ export class CipherAttachmentsComponent {
|
||||
/** Emits after a file has been successfully removed */
|
||||
readonly onRemoveSuccess = output<void>();
|
||||
|
||||
readonly onCloseButtonPress = output<void>();
|
||||
|
||||
protected readonly organization = signal<Organization | null>(null);
|
||||
protected readonly cipher = signal<CipherView | null>(null);
|
||||
|
||||
@@ -154,7 +156,7 @@ export class CipherAttachmentsComponent {
|
||||
// Update the initial state of the submit button
|
||||
const btn = this.submitBtn();
|
||||
if (btn) {
|
||||
btn.disabled.set(!this.attachmentForm.valid);
|
||||
btn.disabled.set(!this.attachmentForm.valid && this.cipher().edit);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -192,6 +194,12 @@ export class CipherAttachmentsComponent {
|
||||
|
||||
/** Save the attachments to the cipher */
|
||||
submit = async () => {
|
||||
//user can't edit cipher and will close the bit-dialog
|
||||
if (!this.cipher().edit) {
|
||||
this.onCloseButtonPress.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
this.onUploadStarted.emit();
|
||||
|
||||
const file = this.attachmentForm.value.file;
|
||||
|
||||
@@ -13,11 +13,12 @@
|
||||
(onUploadSuccess)="uploadSuccessful()"
|
||||
(onUploadFailed)="uploadFailed()"
|
||||
(onRemoveSuccess)="removalSuccessful()"
|
||||
(onCloseButtonPress)="closeButtonPressed()"
|
||||
></app-cipher-attachments>
|
||||
</ng-container>
|
||||
<ng-container bitDialogFooter>
|
||||
<button bitButton type="submit" buttonType="primary" [attr.form]="attachmentFormId" #submitBtn>
|
||||
{{ "upload" | i18n }}
|
||||
{{ buttonText }}
|
||||
</button>
|
||||
</ng-container>
|
||||
</bit-dialog>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, HostListener, Inject } from "@angular/core";
|
||||
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { CipherId, OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { UnionOfValues } from "@bitwarden/common/vault/types/union-of-values";
|
||||
import {
|
||||
@@ -18,6 +19,7 @@ import { CipherAttachmentsComponent } from "../../cipher-form/components/attachm
|
||||
|
||||
export interface AttachmentsDialogParams {
|
||||
cipherId: CipherId;
|
||||
canEditCipher?: boolean;
|
||||
admin?: boolean;
|
||||
organizationId?: OrganizationId;
|
||||
}
|
||||
@@ -51,7 +53,9 @@ export class AttachmentsV2Component {
|
||||
cipherId: CipherId;
|
||||
admin: boolean = false;
|
||||
organizationId?: OrganizationId;
|
||||
canEditCipher: boolean;
|
||||
attachmentFormId = CipherAttachmentsComponent.attachmentFormID;
|
||||
buttonText: string;
|
||||
private isUploading = false;
|
||||
|
||||
/**
|
||||
@@ -62,10 +66,14 @@ export class AttachmentsV2Component {
|
||||
constructor(
|
||||
private dialogRef: DialogRef<AttachmentDialogCloseResult>,
|
||||
@Inject(DIALOG_DATA) public params: AttachmentsDialogParams,
|
||||
private i18nService: I18nService,
|
||||
) {
|
||||
this.cipherId = params.cipherId;
|
||||
this.organizationId = params.organizationId;
|
||||
this.admin = params.admin ?? false;
|
||||
this.canEditCipher = params?.canEditCipher ?? false;
|
||||
this.buttonText =
|
||||
this.canEditCipher || this.admin ? this.i18nService.t("upload") : this.i18nService.t("close");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,4 +148,10 @@ export class AttachmentsV2Component {
|
||||
action: AttachmentDialogResult.Removed,
|
||||
});
|
||||
}
|
||||
|
||||
closeButtonPressed() {
|
||||
this.dialogRef.close({
|
||||
action: AttachmentDialogResult.Closed,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user