import type { components } from "@/api/schema"; import { bytesToString } from "@/utils/utils"; import type { CleanableItem } from "./CleanupOperation"; export type StorageItemsCleanupResult = components["schemas"]["StorageItemsCleanupResult"]; /** * Associates the name of an item with the error message when failed. * Simplifies displaying information to the final user. */ export interface ItemError { /** Name of the item. */ name: string; /** The reason why it couldn't be cleaned. */ reason: string; } /** * Provides additional information about the result of the cleaning operation. */ export class CleanupResult { private _data: StorageItemsCleanupResult; private _item_id_map: Map; private _errorMessage?: string; /** * Creates a new CleanupResult. * @param data The server response data for a cleanup operation. * @param items The list of requested items to be cleaned. * @param errorMessage A possible error message if the request completely failed. */ constructor(data?: StorageItemsCleanupResult, items?: CleanableItem[], errorMessage?: string) { this._data = data ?? { total_item_count: 0, success_item_count: 0, total_free_bytes: 0, errors: [] }; items = items ?? []; this._item_id_map = new Map(); items.forEach((item) => { this._item_id_map.set(item.id, item); }); this._errorMessage = errorMessage; } /** * The total number of items requested to be cleaned. */ get totalItemCount(): number { return this._data.total_item_count; } /** * The total amount of space in bytes recovered after trying to cleanup all the requested items. */ get totalFreeBytes(): number { return this._data.total_free_bytes; } /** * List of error messages associated with a particular item ID. * When an item cannot be cleaned it will be registered in this list. */ get errors(): ItemError[] { return this._data.errors.map((e) => { return { name: this._item_id_map.get(e.item_id)?.name ?? "Unknown", reason: e.error }; }); } /** * A general error message, usually indicating that the whole cleanup operation failed with * no partial success. */ get errorMessage(): string | undefined { return this._errorMessage; } /** * Whether the cleanup operation could not success for every requested item. * It doesn't mean the operation completely failed, some items could have been successfully cleaned. */ get hasSomeErrors(): boolean { return this._data.errors.length > 0; } /** * Whether the cleanup operation completely failed. * This means not even partial cleaning was made. */ get hasFailed(): boolean { return Boolean(this._errorMessage); } /** * Whether the cleanup operation was executed without errors. */ get success(): boolean { return !this.hasSomeErrors && !this.hasFailed; } /** * The number of items successfully cleaned. */ get totalCleaned(): number { return this._data.success_item_count; } /** * Whether the cleanup operation managed to free some items but not all of them. */ get isPartialSuccess(): boolean { return this.hasSomeErrors && this._data.success_item_count > 0; } /** * Whether the cleanup operation managed to free some space or remove some items. * It can happen that only "copy" items were removed effectively recovering 0 bytes. */ get hasUpdatedResults(): boolean { return this.totalFreeBytes > 0 || this.totalCleaned > 0; } /** * The total amount of disk space freed by the cleanup operation. */ get niceTotalFreeBytes(): string { return bytesToString(this._data.total_free_bytes, true, undefined); } }