Remove FF 'AC-1607_present-user-offboarding-survey' and old cancel functionality (#8322)

This commit is contained in:
Alex Morask 2024-03-21 15:04:29 -04:00 committed by GitHub
parent 9a70e63e73
commit c4c275604b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 22 additions and 140 deletions

View File

@ -145,7 +145,7 @@
type="button"
buttonType="danger"
class="btn-submit tw-ml-auto"
(click)="cancel()"
(click)="cancelSubscription()"
[appApiAction]="cancelPromise"
[disabled]="$any(cancelBtn).loading"
*ngIf="subscription && !subscription.cancelled && !subscriptionMarkedForCancel"

View File

@ -1,12 +1,10 @@
import { Component, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import { firstValueFrom, lastValueFrom, Observable } from "rxjs";
import { firstValueFrom, lastValueFrom } from "rxjs";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
import { SubscriptionResponse } from "@bitwarden/common/billing/models/response/subscription.response";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigServiceAbstraction as ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@ -34,7 +32,6 @@ export class UserSubscriptionComponent implements OnInit {
cancelPromise: Promise<any>;
reinstatePromise: Promise<any>;
presentUserWithOffboardingSurvey$: Observable<boolean>;
constructor(
private apiService: ApiService,
@ -45,7 +42,6 @@ export class UserSubscriptionComponent implements OnInit {
private fileDownloadService: FileDownloadService,
private dialogService: DialogService,
private environmentService: EnvironmentService,
private configService: ConfigService,
private billingAccountProfileStateService: BillingAccountProfileStateService,
) {
this.selfHosted = platformUtilsService.isSelfHost();
@ -53,9 +49,6 @@ export class UserSubscriptionComponent implements OnInit {
async ngOnInit() {
this.cloudWebVaultUrl = await firstValueFrom(this.environmentService.cloudWebVaultUrl$);
this.presentUserWithOffboardingSurvey$ = this.configService.getFeatureFlag$<boolean>(
FeatureFlag.AC1607_PresentUserOffboardingSurvey,
);
await this.load();
this.firstLoaded = true;
}
@ -105,16 +98,22 @@ export class UserSubscriptionComponent implements OnInit {
}
}
cancel = async () => {
const presentUserWithOffboardingSurvey = await this.configService.getFeatureFlag<boolean>(
FeatureFlag.AC1607_PresentUserOffboardingSurvey,
);
cancelSubscription = async () => {
const reference = openOffboardingSurvey(this.dialogService, {
data: {
type: "User",
},
});
if (presentUserWithOffboardingSurvey) {
await this.cancelWithOffboardingSurvey();
} else {
await this.cancelWithWarning();
this.cancelPromise = lastValueFrom(reference.closed);
const result = await this.cancelPromise;
if (result === OffboardingSurveyDialogResultType.Closed) {
return;
}
await this.load();
};
downloadLicense() {
@ -159,55 +158,6 @@ export class UserSubscriptionComponent implements OnInit {
}
}
private cancelWithOffboardingSurvey = async () => {
const reference = openOffboardingSurvey(this.dialogService, {
data: {
type: "User",
},
});
this.cancelPromise = lastValueFrom(reference.closed);
const result = await this.cancelPromise;
if (result === OffboardingSurveyDialogResultType.Closed) {
return;
}
await this.load();
};
private async cancelWithWarning() {
if (this.loading) {
return;
}
const confirmed = await this.dialogService.openSimpleDialog({
title: { key: "cancelSubscription" },
content: { key: "cancelConfirmation" },
type: "warning",
});
if (!confirmed) {
return;
}
try {
this.cancelPromise = this.apiService.postCancelPremium();
await this.cancelPromise;
this.platformUtilsService.showToast(
"success",
null,
this.i18nService.t("canceledSubscription"),
);
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.load();
} catch (e) {
this.logService.error(e);
}
}
get subscriptionMarkedForCancel() {
return (
this.subscription != null && !this.subscription.cancelled && this.subscription.cancelAtEndDate

View File

@ -232,28 +232,9 @@
<button
bitButton
buttonType="danger"
[bitAction]="cancelWithWarning"
(click)="cancelSubscription()"
type="button"
*ngIf="
subscription &&
!subscription.cancelled &&
!subscriptionMarkedForCancel &&
!(presentUserWithOffboardingSurvey$ | async)
"
>
{{ "cancelSubscription" | i18n }}
</button>
<button
bitButton
buttonType="danger"
(click)="cancelWithOffboardingSurvey()"
type="button"
*ngIf="
subscription &&
!subscription.cancelled &&
!subscriptionMarkedForCancel &&
(presentUserWithOffboardingSurvey$ | async)
"
*ngIf="subscription && !subscription.cancelled && !subscriptionMarkedForCancel"
>
{{ "cancelSubscription" | i18n }}
</button>

View File

@ -1,6 +1,6 @@
import { Component, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { concatMap, firstValueFrom, lastValueFrom, Observable, Subject, takeUntil } from "rxjs";
import { concatMap, firstValueFrom, lastValueFrom, Subject, takeUntil } from "rxjs";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
@ -11,8 +11,6 @@ import { PlanType } from "@bitwarden/common/billing/enums";
import { OrganizationSubscriptionResponse } from "@bitwarden/common/billing/models/response/organization-subscription.response";
import { BillingSubscriptionItemResponse } from "@bitwarden/common/billing/models/response/subscription.response";
import { ProductType } from "@bitwarden/common/enums";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigServiceAbstraction as ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@ -43,7 +41,6 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy
showSecretsManagerSubscribe = false;
firstLoaded = false;
loading: boolean;
presentUserWithOffboardingSurvey$: Observable<boolean>;
protected readonly teamsStarter = ProductType.TeamsStarter;
@ -58,7 +55,6 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy
private organizationApiService: OrganizationApiServiceAbstraction,
private route: ActivatedRoute,
private dialogService: DialogService,
private configService: ConfigService,
) {}
async ngOnInit() {
@ -78,10 +74,6 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy
takeUntil(this.destroy$),
)
.subscribe();
this.presentUserWithOffboardingSurvey$ = this.configService.getFeatureFlag$<boolean>(
FeatureFlag.AC1607_PresentUserOffboardingSurvey,
);
}
ngOnDestroy() {
@ -278,7 +270,7 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy
);
}
cancelWithOffboardingSurvey = async () => {
cancelSubscription = async () => {
const reference = openOffboardingSurvey(this.dialogService, {
data: {
type: "Organization",
@ -295,36 +287,6 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy
await this.load();
};
cancelWithWarning = async () => {
if (this.loading) {
return;
}
const confirmed = await this.dialogService.openSimpleDialog({
title: { key: "cancelSubscription" },
content: { key: "cancelConfirmation" },
type: "warning",
});
if (!confirmed) {
return;
}
try {
await this.organizationApiService.cancel(this.organizationId);
this.platformUtilsService.showToast(
"success",
null,
this.i18nService.t("canceledSubscription"),
);
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.load();
} catch (e) {
this.logService.error(e);
}
};
reinstate = async () => {
if (this.loading) {
return;

View File

@ -170,7 +170,6 @@ export abstract class ApiService {
postRegister: (request: RegisterRequest) => Promise<RegisterResponse>;
postPremium: (data: FormData) => Promise<PaymentResponse>;
postReinstatePremium: () => Promise<any>;
postCancelPremium: () => Promise<any>;
postAccountStorage: (request: StorageRequest) => Promise<PaymentResponse>;
postAccountPayment: (request: PaymentRequest) => Promise<void>;
postAccountLicense: (data: FormData) => Promise<any>;

View File

@ -51,7 +51,6 @@ export class OrganizationApiServiceAbstraction {
updateSeats: (id: string, request: SeatRequest) => Promise<PaymentResponse>;
updateStorage: (id: string, request: StorageRequest) => Promise<PaymentResponse>;
verifyBank: (id: string, request: VerifyBankRequest) => Promise<void>;
cancel: (id: string) => Promise<void>;
reinstate: (id: string) => Promise<void>;
leave: (id: string) => Promise<void>;
delete: (id: string, request: SecretVerificationRequest) => Promise<void>;

View File

@ -184,10 +184,6 @@ export class OrganizationApiService implements OrganizationApiServiceAbstraction
);
}
async cancel(id: string): Promise<void> {
return this.apiService.send("POST", "/organizations/" + id + "/cancel", null, true, false);
}
async reinstate(id: string): Promise<void> {
return this.apiService.send("POST", "/organizations/" + id + "/reinstate", null, true, false);
}

View File

@ -12,7 +12,7 @@ export class BillingApiService implements BillingApiServiceAbstraction {
): Promise<void> {
return this.apiService.send(
"POST",
"/organizations/" + organizationId + "/churn",
"/organizations/" + organizationId + "/cancel",
request,
true,
false,
@ -20,7 +20,7 @@ export class BillingApiService implements BillingApiServiceAbstraction {
}
cancelPremiumUserSubscription(request: SubscriptionCancellationRequest): Promise<void> {
return this.apiService.send("POST", "/accounts/churn-premium", request, true, false);
return this.apiService.send("POST", "/accounts/cancel", request, true, false);
}
async getBillingStatus(id: string): Promise<OrganizationBillingStatusResponse> {

View File

@ -7,7 +7,6 @@ export enum FeatureFlag {
GeneratorToolsModernization = "generator-tools-modernization",
KeyRotationImprovements = "key-rotation-improvements",
FlexibleCollectionsMigration = "flexible-collections-migration",
AC1607_PresentUserOffboardingSurvey = "AC-1607_present-user-offboarding-survey",
ShowPaymentMethodWarningBanners = "show-payment-method-warning-banners",
}

View File

@ -394,10 +394,6 @@ export class ApiService implements ApiServiceAbstraction {
return this.send("POST", "/accounts/reinstate-premium", null, true, false);
}
postCancelPremium(): Promise<any> {
return this.send("POST", "/accounts/cancel-premium", null, true, false);
}
async postAccountStorage(request: StorageRequest): Promise<PaymentResponse> {
const r = await this.send("POST", "/accounts/storage", request, true, true);
return new PaymentResponse(r);