mirror of
https://github.com/bitwarden/browser.git
synced 2025-12-05 09:14:28 +01:00
Merge eed7edcbd8 into d32365fbba
This commit is contained in:
commit
4015cd8cfb
@ -1,6 +1,6 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, Input } from "@angular/core";
|
||||
import { firstValueFrom, Observable, of, switchMap } from "rxjs";
|
||||
import { firstValueFrom, Observable, of, switchMap, lastValueFrom } from "rxjs";
|
||||
|
||||
import { PremiumBadgeComponent } from "@bitwarden/angular/billing/components/premium-badge";
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
@ -8,7 +8,13 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions";
|
||||
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
|
||||
import { ButtonModule, DialogService, MenuModule } from "@bitwarden/components";
|
||||
import { DefaultSendFormConfigService, SendAddEditDialogComponent } from "@bitwarden/send-ui";
|
||||
import {
|
||||
DefaultSendFormConfigService,
|
||||
SendAddEditDialogComponent,
|
||||
SendItemDialogResult,
|
||||
} from "@bitwarden/send-ui";
|
||||
|
||||
import { SendSuccessDrawerDialogComponent } from "../shared";
|
||||
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
|
||||
@ -57,9 +63,15 @@ export class NewSendDropdownComponent {
|
||||
if (!(await firstValueFrom(this.canAccessPremium$)) && type === SendType.File) {
|
||||
return;
|
||||
}
|
||||
|
||||
const formConfig = await this.addEditFormConfigService.buildConfig("add", undefined, type);
|
||||
|
||||
SendAddEditDialogComponent.open(this.dialogService, { formConfig });
|
||||
const dialogRef = SendAddEditDialogComponent.open(this.dialogService, { formConfig });
|
||||
const result = await lastValueFrom(dialogRef.closed);
|
||||
|
||||
if (typeof result === "object" && result.result === SendItemDialogResult.Saved && result.send) {
|
||||
this.dialogService.openDrawer(SendSuccessDrawerDialogComponent, {
|
||||
data: result.send,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ import { HeaderModule } from "../../layouts/header/header.module";
|
||||
import { SharedModule } from "../../shared";
|
||||
|
||||
import { NewSendDropdownComponent } from "./new-send/new-send-dropdown.component";
|
||||
import { SendSuccessDrawerDialogComponent } from "./shared";
|
||||
|
||||
const BroadcasterSubscriptionId = "SendComponent";
|
||||
|
||||
@ -160,5 +161,11 @@ export class SendComponent extends BaseSendComponent implements OnInit, OnDestro
|
||||
if (result === SendItemDialogResult.Deleted || result === SendItemDialogResult.Saved) {
|
||||
await this.load();
|
||||
}
|
||||
|
||||
if (typeof result === "object" && result.result === SendItemDialogResult.Saved && result.send) {
|
||||
this.dialogService.openDrawer(SendSuccessDrawerDialogComponent, {
|
||||
data: result.send,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
apps/web/src/app/tools/send/shared/index.ts
Normal file
1
apps/web/src/app/tools/send/shared/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { SendSuccessDrawerDialogComponent } from "./send-success-drawer-dialog.component";
|
||||
@ -0,0 +1,45 @@
|
||||
<bit-dialog dialogSize="large" disablePadding="false" background="alt">
|
||||
<ng-container bitDialogTitle>
|
||||
<span>{{ dialogTitle() | i18n }}</span>
|
||||
</ng-container>
|
||||
<ng-container bitDialogContent>
|
||||
<div
|
||||
class="tw-flex tw-flex-col tw-items-center tw-justify-center tw-text-center tw-h-full tw-px-4 tw-pt-20"
|
||||
>
|
||||
<div class="tw-mb-6 tw-mt-8">
|
||||
<div class="tw-size-[95px] tw-content-center">
|
||||
<bit-icon [icon]="activeSendIcon"></bit-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 bitTypography="h3" class="tw-mb-2 tw-font-bold">
|
||||
{{ "sendCreatedSuccessfully" | i18n }}
|
||||
</h3>
|
||||
|
||||
<p bitTypography="body1" class="tw-mb-6 tw-max-w-sm">
|
||||
{{ "sendCreatedDescription" | i18n }}
|
||||
</p>
|
||||
|
||||
<bit-form-field class="tw-w-full tw-max-w-sm tw-mb-4">
|
||||
<bit-label>{{ "sendLink" | i18n }}</bit-label>
|
||||
<input bitInput disabled type="text" [value]="sendLink()" />
|
||||
<button
|
||||
type="button"
|
||||
bitIconButton="bwi-clone"
|
||||
bitSuffix
|
||||
[label]="'copyLink' | i18n"
|
||||
(click)="copyLink()"
|
||||
></button>
|
||||
</bit-form-field>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container bitDialogFooter>
|
||||
<button type="button" bitButton buttonType="primary" (click)="copyLink()">
|
||||
{{ "copyLink" | i18n }}
|
||||
</button>
|
||||
<button type="button" bitButton buttonType="secondary" bitDialogClose>
|
||||
{{ "close" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
</bit-dialog>
|
||||
@ -0,0 +1,54 @@
|
||||
import { Component, ChangeDetectionStrategy, Inject, signal, computed } from "@angular/core";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { ActiveSendIcon } from "@bitwarden/assets/svg";
|
||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
|
||||
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
|
||||
import { DIALOG_DATA, DialogModule, ToastService, TypographyModule } from "@bitwarden/components";
|
||||
import { SharedModule } from "@bitwarden/web-vault/app/shared";
|
||||
|
||||
@Component({
|
||||
imports: [SharedModule, DialogModule, TypographyModule],
|
||||
templateUrl: "./send-success-drawer-dialog.component.html",
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class SendSuccessDrawerDialogComponent {
|
||||
readonly sendLink = signal<string>("");
|
||||
activeSendIcon = ActiveSendIcon;
|
||||
|
||||
// Computed property to get the dialog title based on send type
|
||||
readonly dialogTitle = computed(() => {
|
||||
return this.send.type === SendType.Text ? "newTextSend" : "newFileSend";
|
||||
});
|
||||
|
||||
constructor(
|
||||
@Inject(DIALOG_DATA) public send: SendView,
|
||||
private environmentService: EnvironmentService,
|
||||
private i18nService: I18nService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private toastService: ToastService,
|
||||
) {
|
||||
void this.initLink();
|
||||
}
|
||||
|
||||
async initLink() {
|
||||
const env = await firstValueFrom(this.environmentService.environment$);
|
||||
this.sendLink.set(env.getSendUrl() + this.send.accessId + "/" + this.send.urlB64Key);
|
||||
}
|
||||
|
||||
copyLink() {
|
||||
const link = this.sendLink();
|
||||
if (!link) {
|
||||
return;
|
||||
}
|
||||
this.platformUtilsService.copyToClipboard(link);
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
title: null,
|
||||
message: this.i18nService.t("valueCopied", this.i18nService.t("sendLink")),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -3265,7 +3265,7 @@
|
||||
"nextChargeHeader": {
|
||||
"message": "Next Charge"
|
||||
},
|
||||
"plan": {
|
||||
"plan": {
|
||||
"message": "Plan"
|
||||
},
|
||||
"details": {
|
||||
@ -4481,7 +4481,6 @@
|
||||
"updateBrowser": {
|
||||
"message": "Update browser"
|
||||
},
|
||||
|
||||
"generatingYourAccessIntelligence": {
|
||||
"message": "Generating your Access Intelligence..."
|
||||
},
|
||||
@ -5583,6 +5582,22 @@
|
||||
"message": "Send saved",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendCreatedSuccessfully": {
|
||||
"message": "Send created successfully!",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendCreatedDescription": {
|
||||
"message": "Copy and share this Send link. It can be viewed by the people you specified for the next N days.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"newTextSend": {
|
||||
"message": "New Text Send",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"newFileSend": {
|
||||
"message": "New File Send",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"editedSend": {
|
||||
"message": "Send saved",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
@ -5857,22 +5872,22 @@
|
||||
"message": "credential lifecycle",
|
||||
"description": "This will be used as a hyperlink"
|
||||
},
|
||||
"organizationDataOwnershipWarningTitle":{
|
||||
"organizationDataOwnershipWarningTitle": {
|
||||
"message": "Are you sure you want to proceed?"
|
||||
},
|
||||
"organizationDataOwnershipWarning1":{
|
||||
"organizationDataOwnershipWarning1": {
|
||||
"message": "will remain accessible to members"
|
||||
},
|
||||
"organizationDataOwnershipWarning2":{
|
||||
"organizationDataOwnershipWarning2": {
|
||||
"message": "will not be automatically selected when creating new items"
|
||||
},
|
||||
"organizationDataOwnershipWarning3":{
|
||||
"organizationDataOwnershipWarning3": {
|
||||
"message": "cannot be managed from the Admin Console until the user is offboarded"
|
||||
},
|
||||
"organizationDataOwnershipWarningContentTop":{
|
||||
"organizationDataOwnershipWarningContentTop": {
|
||||
"message": "By turning this policy off, the default collection: "
|
||||
},
|
||||
"organizationDataOwnershipWarningContentBottom":{
|
||||
"organizationDataOwnershipWarningContentBottom": {
|
||||
"message": "Learn more about the ",
|
||||
"description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more about the credential lifecycle.'"
|
||||
},
|
||||
@ -5996,7 +6011,7 @@
|
||||
"uriMatchDetectionOptionsLabel": {
|
||||
"message": "Default URI match detection"
|
||||
},
|
||||
"invalidUriMatchDefaultPolicySetting": {
|
||||
"invalidUriMatchDefaultPolicySetting": {
|
||||
"message": "Please select a valid URI match detection option.",
|
||||
"description": "Error message displayed when a user attempts to save URI match detection policy settings with an invalid selection."
|
||||
},
|
||||
@ -8886,7 +8901,7 @@
|
||||
}
|
||||
},
|
||||
"accessedSecret": {
|
||||
"message": "Accessed secret $SECRET_ID$.",
|
||||
"message": "Accessed secret $SECRET_ID$.",
|
||||
"placeholders": {
|
||||
"secret_id": {
|
||||
"content": "$1",
|
||||
@ -8894,7 +8909,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"editedSecretWithId": {
|
||||
"editedSecretWithId": {
|
||||
"message": "Edited a secret with identifier: $SECRET_ID$",
|
||||
"placeholders": {
|
||||
"secret_id": {
|
||||
@ -8903,7 +8918,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"deletedSecretWithId": {
|
||||
"deletedSecretWithId": {
|
||||
"message": "Deleted a secret with identifier: $SECRET_ID$",
|
||||
"placeholders": {
|
||||
"secret_id": {
|
||||
@ -8921,7 +8936,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"restoredSecretWithId": {
|
||||
"restoredSecretWithId": {
|
||||
"message": "Restored a secret with identifier: $SECRET_ID$",
|
||||
"placeholders": {
|
||||
"secret_id": {
|
||||
@ -8930,7 +8945,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"createdSecretWithId": {
|
||||
"createdSecretWithId": {
|
||||
"message": "Created a new secret with identifier: $SECRET_ID$",
|
||||
"placeholders": {
|
||||
"secret_id": {
|
||||
@ -8940,7 +8955,7 @@
|
||||
}
|
||||
},
|
||||
"accessedProjectWithIdentifier": {
|
||||
"message": "Accessed a project with identifier: $PROJECT_ID$.",
|
||||
"message": "Accessed a project with identifier: $PROJECT_ID$.",
|
||||
"placeholders": {
|
||||
"project_id": {
|
||||
"content": "$1",
|
||||
@ -8949,7 +8964,7 @@
|
||||
}
|
||||
},
|
||||
"nameUnavailableProjectDeleted": {
|
||||
"message": "Deleted project Id: $PROJECT_ID$",
|
||||
"message": "Deleted project Id: $PROJECT_ID$",
|
||||
"placeholders": {
|
||||
"project_id": {
|
||||
"content": "$1",
|
||||
@ -8958,7 +8973,7 @@
|
||||
}
|
||||
},
|
||||
"nameUnavailableSecretDeleted": {
|
||||
"message": "Deleted secret Id: $SECRET_ID$",
|
||||
"message": "Deleted secret Id: $SECRET_ID$",
|
||||
"placeholders": {
|
||||
"secret_id": {
|
||||
"content": "$1",
|
||||
@ -8967,7 +8982,7 @@
|
||||
}
|
||||
},
|
||||
"nameUnavailableServiceAccountDeleted": {
|
||||
"message": "Deleted machine account Id: $SERVICE_ACCOUNT_ID$",
|
||||
"message": "Deleted machine account Id: $SERVICE_ACCOUNT_ID$",
|
||||
"placeholders": {
|
||||
"service_account_id": {
|
||||
"content": "$1",
|
||||
@ -8975,7 +8990,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"editedProjectWithId": {
|
||||
"editedProjectWithId": {
|
||||
"message": "Edited a project with identifier: $PROJECT_ID$",
|
||||
"placeholders": {
|
||||
"project_id": {
|
||||
@ -9054,7 +9069,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"deletedProjectWithId": {
|
||||
"deletedProjectWithId": {
|
||||
"message": "Deleted a project with identifier: $PROJECT_ID$",
|
||||
"placeholders": {
|
||||
"project_id": {
|
||||
@ -9063,7 +9078,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"createdProjectWithId": {
|
||||
"createdProjectWithId": {
|
||||
"message": "Created a new project with identifier: $PROJECT_ID$",
|
||||
"placeholders": {
|
||||
"project_id": {
|
||||
@ -9778,15 +9793,15 @@
|
||||
"message": "Common formats",
|
||||
"description": "Label indicating the most common import formats"
|
||||
},
|
||||
"uriMatchDefaultStrategyHint": {
|
||||
"uriMatchDefaultStrategyHint": {
|
||||
"message": "URI match detection is how Bitwarden identifies autofill suggestions.",
|
||||
"description": "Explains to the user that URI match detection determines how Bitwarden suggests autofill options, and clarifies that this default strategy applies when no specific match detection is set for a login item."
|
||||
},
|
||||
"regExAdvancedOptionWarning": {
|
||||
"regExAdvancedOptionWarning": {
|
||||
"message": "\"Regular expression\" is an advanced option with increased risk of exposing credentials.",
|
||||
"description": "Content for dialog which warns a user when selecting 'regular expression' matching strategy as a cipher match strategy"
|
||||
},
|
||||
"startsWithAdvancedOptionWarning": {
|
||||
"startsWithAdvancedOptionWarning": {
|
||||
"message": "\"Starts with\" is an advanced option with increased risk of exposing credentials.",
|
||||
"description": "Content for dialog which warns a user when selecting 'starts with' matching strategy as a cipher match strategy"
|
||||
},
|
||||
@ -9794,11 +9809,11 @@
|
||||
"message": "More about match detection",
|
||||
"description": "Link to match detection docs on warning dialog for advance match strategy"
|
||||
},
|
||||
"uriAdvancedOption":{
|
||||
"uriAdvancedOption": {
|
||||
"message": "Advanced options",
|
||||
"description": "Advanced option placeholder for uri option component"
|
||||
},
|
||||
"warningCapitalized": {
|
||||
"warningCapitalized": {
|
||||
"message": "Warning",
|
||||
"description": "Warning (should maintain locale-relevant capitalization)"
|
||||
},
|
||||
@ -12215,4 +12230,4 @@
|
||||
"userVerificationFailed": {
|
||||
"message": "User verification failed."
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,3 +3,4 @@ export * from "./drawer.component";
|
||||
export * from "./drawer-body.component";
|
||||
export * from "./drawer-close.directive";
|
||||
export * from "./drawer-header.component";
|
||||
export * from "./drawer.service";
|
||||
|
||||
@ -44,8 +44,9 @@ export const SendItemDialogResult = Object.freeze({
|
||||
} as const);
|
||||
|
||||
/** A result of the Send add/edit dialog. */
|
||||
export type SendItemDialogResult = (typeof SendItemDialogResult)[keyof typeof SendItemDialogResult];
|
||||
|
||||
export type SendItemDialogResult =
|
||||
| (typeof SendItemDialogResult)[keyof typeof SendItemDialogResult]
|
||||
| { result: typeof SendItemDialogResult.Saved; send: SendView };
|
||||
/**
|
||||
* Component for adding or editing a send item.
|
||||
*/
|
||||
@ -93,7 +94,7 @@ export class SendAddEditDialogComponent {
|
||||
*/
|
||||
async onSendCreated(send: SendView) {
|
||||
// FIXME Add dialogService.open send-created dialog
|
||||
this.dialogRef.close(SendItemDialogResult.Saved);
|
||||
this.dialogRef.close({ result: SendItemDialogResult.Saved, send });
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user