mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
PM-22143 Refactor TS enums to be const objects (Send specific enums) (#16399)
This commit is contained in:
@@ -41,7 +41,12 @@ import { SendFilePopoutDialogContainerComponent } from "../send-file-popout-dial
|
||||
class QueryParams {
|
||||
constructor(params: Params) {
|
||||
this.sendId = params.sendId;
|
||||
this.type = parseInt(params.type, 10);
|
||||
const sendTypeValue = parseInt(params.type, 10);
|
||||
if (sendTypeValue === SendType.Text || sendTypeValue === SendType.File) {
|
||||
this.type = sendTypeValue;
|
||||
} else {
|
||||
throw new Error(`Invalid SendType: ${params.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,7 +37,7 @@ import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-heade
|
||||
import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component";
|
||||
import { PopupRouterCacheService } from "../../../platform/popup/view-cache/popup-router-cache.service";
|
||||
|
||||
import { SendV2Component, SendState } from "./send-v2.component";
|
||||
import { SendState, SendV2Component } from "./send-v2.component";
|
||||
|
||||
describe("SendV2Component", () => {
|
||||
let component: SendV2Component;
|
||||
|
||||
@@ -38,12 +38,16 @@ import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-heade
|
||||
import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component";
|
||||
import { VaultFadeInOutSkeletonComponent } from "../../../vault/popup/components/vault-fade-in-out-skeleton/vault-fade-in-out-skeleton.component";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum SendState {
|
||||
Empty,
|
||||
NoResults,
|
||||
}
|
||||
/** A state of the Send list UI. */
|
||||
export const SendState = Object.freeze({
|
||||
/** No sends exist for the current filter (file or text). */
|
||||
Empty: "Empty",
|
||||
/** Sends exist, but none match the current filter/search. */
|
||||
NoResults: "NoResults",
|
||||
} as const);
|
||||
|
||||
/** A state of the Send list UI. */
|
||||
export type SendState = (typeof SendState)[keyof typeof SendState];
|
||||
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
|
||||
@@ -114,6 +118,11 @@ export class SendV2Component implements OnDestroy {
|
||||
|
||||
protected sendsDisabled = false;
|
||||
|
||||
private readonly sendTypeTitles: Record<SendType, string> = {
|
||||
[SendType.File]: "fileSends",
|
||||
[SendType.Text]: "textSends",
|
||||
};
|
||||
|
||||
constructor(
|
||||
protected sendItemsService: SendItemsService,
|
||||
protected sendListFiltersService: SendListFiltersService,
|
||||
@@ -130,7 +139,7 @@ export class SendV2Component implements OnDestroy {
|
||||
.pipe(takeUntilDestroyed())
|
||||
.subscribe(([emptyList, noFilteredResults, currentFilter]) => {
|
||||
if (currentFilter?.sendType !== null) {
|
||||
this.title = `${this.sendType[currentFilter.sendType].toLowerCase()}Sends`;
|
||||
this.title = this.sendTypeTitles[currentFilter.sendType] ?? "allSends";
|
||||
} else {
|
||||
this.title = "allSends";
|
||||
}
|
||||
|
||||
@@ -308,7 +308,7 @@ export class SendProgram extends BaseProgram {
|
||||
let sendFile = null;
|
||||
let sendText = null;
|
||||
let name = Utils.newGuid();
|
||||
let type = SendType.Text;
|
||||
let type: SendType = SendType.Text;
|
||||
if (options.file != null) {
|
||||
data = path.resolve(data);
|
||||
if (!fs.existsSync(data)) {
|
||||
|
||||
@@ -25,13 +25,16 @@ import { SearchBarService } from "../../layout/search/search-bar.service";
|
||||
|
||||
import { AddEditComponent } from "./add-edit.component";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
enum Action {
|
||||
None = "",
|
||||
Add = "add",
|
||||
Edit = "edit",
|
||||
}
|
||||
const Action = Object.freeze({
|
||||
/** No action is currently active. */
|
||||
None: "",
|
||||
/** The user is adding a new Send. */
|
||||
Add: "add",
|
||||
/** The user is editing an existing Send. */
|
||||
Edit: "edit",
|
||||
} as const);
|
||||
|
||||
type Action = (typeof Action)[keyof typeof Action];
|
||||
|
||||
const BroadcasterSubscriptionId = "SendComponent";
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum SendType {
|
||||
Text = 0,
|
||||
File = 1,
|
||||
}
|
||||
/** A type of Send. */
|
||||
export const SendType = Object.freeze({
|
||||
/** Send contains plain text. */
|
||||
Text: 0,
|
||||
/** Send contains a file. */
|
||||
File: 1,
|
||||
} as const);
|
||||
|
||||
/** A type of Send. */
|
||||
export type SendType = (typeof SendType)[keyof typeof SendType];
|
||||
|
||||
@@ -35,19 +35,16 @@ export interface SendItemDialogParams {
|
||||
disableForm?: boolean;
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum SendItemDialogResult {
|
||||
/**
|
||||
* A Send was saved (created or updated).
|
||||
*/
|
||||
Saved = "saved",
|
||||
/** A result of the Send add/edit dialog. */
|
||||
export const SendItemDialogResult = Object.freeze({
|
||||
/** The send item was created or updated. */
|
||||
Saved: "saved",
|
||||
/** The send item was deleted. */
|
||||
Deleted: "deleted",
|
||||
} as const);
|
||||
|
||||
/**
|
||||
* A Send was deleted.
|
||||
*/
|
||||
Deleted = "deleted",
|
||||
}
|
||||
/** A result of the Send add/edit dialog. */
|
||||
export type SendItemDialogResult = (typeof SendItemDialogResult)[keyof typeof SendItemDialogResult];
|
||||
|
||||
/**
|
||||
* Component for adding or editing a send item.
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { DatePreset, isDatePreset, asDatePreset } from "./send-details.component";
|
||||
|
||||
describe("SendDetails DatePreset utilities", () => {
|
||||
it("accepts all defined numeric presets", () => {
|
||||
const presets: Array<any> = [
|
||||
DatePreset.OneHour,
|
||||
DatePreset.OneDay,
|
||||
DatePreset.TwoDays,
|
||||
DatePreset.ThreeDays,
|
||||
DatePreset.SevenDays,
|
||||
DatePreset.FourteenDays,
|
||||
DatePreset.ThirtyDays,
|
||||
];
|
||||
presets.forEach((p) => {
|
||||
expect(isDatePreset(p)).toBe(true);
|
||||
expect(asDatePreset(p)).toBe(p);
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects invalid numbers and non-numeric values", () => {
|
||||
const invalid: Array<any> = [5, -1, 0.5, 0, 9999, "never", "foo", null, undefined, {}, []];
|
||||
invalid.forEach((v) => {
|
||||
expect(isDatePreset(v)).toBe(false);
|
||||
expect(asDatePreset(v)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -29,24 +29,50 @@ import { SendOptionsComponent } from "../options/send-options.component";
|
||||
import { SendFileDetailsComponent } from "./send-file-details.component";
|
||||
import { SendTextDetailsComponent } from "./send-text-details.component";
|
||||
|
||||
// Value = hours
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum DatePreset {
|
||||
OneHour = 1,
|
||||
OneDay = 24,
|
||||
TwoDays = 48,
|
||||
ThreeDays = 72,
|
||||
SevenDays = 168,
|
||||
FourteenDays = 336,
|
||||
ThirtyDays = 720,
|
||||
}
|
||||
/** A preset duration (in hours) for deletion. */
|
||||
export const DatePreset = Object.freeze({
|
||||
/** One-hour duration. */
|
||||
OneHour: 1,
|
||||
/** One-day duration (24 hours). */
|
||||
OneDay: 24,
|
||||
/** Two-day duration (48 hours). */
|
||||
TwoDays: 48,
|
||||
/** Three-day duration (72 hours). */
|
||||
ThreeDays: 72,
|
||||
/** Seven-day duration (168 hours). */
|
||||
SevenDays: 168,
|
||||
/** Fourteen-day duration (336 hours). */
|
||||
FourteenDays: 336,
|
||||
/** Thirty-day duration (720 hours). */
|
||||
ThirtyDays: 720,
|
||||
} as const);
|
||||
|
||||
/** A preset duration (in hours) for deletion. */
|
||||
export type DatePreset = (typeof DatePreset)[keyof typeof DatePreset];
|
||||
|
||||
export interface DatePresetSelectOption {
|
||||
name: string;
|
||||
value: DatePreset | string;
|
||||
}
|
||||
|
||||
const namesByDatePreset = new Map<DatePreset, keyof typeof DatePreset>(
|
||||
Object.entries(DatePreset).map(([k, v]) => [v as DatePreset, k as keyof typeof DatePreset]),
|
||||
);
|
||||
|
||||
/**
|
||||
* Runtime type guard to verify a value is a valid DatePreset.
|
||||
*/
|
||||
export function isDatePreset(value: unknown): value is DatePreset {
|
||||
return namesByDatePreset.has(value as DatePreset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe converter to DatePreset (numeric preset), returns undefined for invalid inputs.
|
||||
*/
|
||||
export function asDatePreset(value: unknown): DatePreset | undefined {
|
||||
return isDatePreset(value) ? (value as DatePreset) : undefined;
|
||||
}
|
||||
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
|
||||
@Component({
|
||||
@@ -153,11 +179,18 @@ export class SendDetailsComponent implements OnInit {
|
||||
const now = new Date();
|
||||
const selectedValue = this.sendDetailsForm.controls.selectedDeletionDatePreset.value;
|
||||
|
||||
// The form allows for custom date strings, if such is used, return it without worrying about DatePreset validation
|
||||
if (typeof selectedValue === "string") {
|
||||
return selectedValue;
|
||||
}
|
||||
|
||||
const milliseconds = now.setTime(now.getTime() + (selectedValue as number) * 60 * 60 * 1000);
|
||||
// Otherwise, treat it as a preset and validate at runtime
|
||||
const preset = asDatePreset(selectedValue);
|
||||
if (!isDatePreset(preset)) {
|
||||
return new Date(now).toString();
|
||||
}
|
||||
|
||||
const milliseconds = now.setTime(now.getTime() + preset * 60 * 60 * 1000);
|
||||
return new Date(milliseconds).toString();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user