diff --git a/client/src/api/histories.archived.ts b/client/src/api/histories.archived.ts index 518ab55a72a7..bb1ed89599f1 100644 --- a/client/src/api/histories.archived.ts +++ b/client/src/api/histories.archived.ts @@ -1,13 +1,14 @@ -import type { FetchArgType } from "openapi-typescript-fetch"; - -import { type components, fetcher } from "@/api/schema"; +import { client, type components, GalaxyApiPaths } from "@/api/schema"; +import { rethrowSimple } from "@/utils/simple-error"; export type ArchivedHistorySummary = components["schemas"]["ArchivedHistorySummary"]; export type ArchivedHistoryDetailed = components["schemas"]["ArchivedHistoryDetailed"]; +export type AnyArchivedHistory = ArchivedHistorySummary | ArchivedHistoryDetailed; export type AsyncTaskResultSummary = components["schemas"]["AsyncTaskResultSummary"]; -type GetArchivedHistoriesParams = FetchArgType; -type SerializationOptions = Pick; +type MaybeArchivedHistoriesQueryParams = GalaxyApiPaths["/api/histories/archived"]["get"]["parameters"]["query"]; +type ArchivedHistoriesQueryParams = Exclude; +type SerializationOptions = Pick; interface FilterOptions { query?: string; @@ -26,97 +27,44 @@ interface SortingOptions { interface GetArchivedHistoriesOptions extends FilterOptions, PaginationOptions, SortingOptions, SerializationOptions {} interface ArchivedHistoriesResult { - histories: ArchivedHistorySummary[] | ArchivedHistoryDetailed[]; + histories: AnyArchivedHistory[]; totalMatches: number; } const DEFAULT_PAGE_SIZE = 10; -const getArchivedHistories = fetcher.path("/api/histories/archived").method("get").create(); - /** * Get a list of archived histories. */ -export async function fetchArchivedHistories( - options: GetArchivedHistoriesOptions = {} -): Promise { +export async function fetchArchivedHistories(options: GetArchivedHistoriesOptions): Promise { const params = optionsToApiParams(options); - const { data, headers } = await getArchivedHistories(params); - const totalMatches = parseInt(headers.get("total_matches") ?? "0"); + + const { response, data, error } = await client.GET("/api/histories/archived", { + params: { + query: params, + }, + }); + + if (error) { + rethrowSimple(error); + } + + const totalMatches = parseInt(response.headers.get("total_matches") ?? "0"); if (params.view === "detailed") { return { histories: data as ArchivedHistoryDetailed[], totalMatches, }; } + return { histories: data as ArchivedHistorySummary[], totalMatches, }; } -const postArchiveHistory = fetcher.path("/api/histories/{history_id}/archive").method("post").create(); - -/** - * Archive a history. - * @param historyId The history to archive - * @param archiveExportId The optional archive export record to associate. This can be used to restore a snapshot copy of the history in the future. - * @param purgeHistory Whether to purge the history after archiving. Can only be used in combination with an archive export record. - * @returns The archived history summary. - */ -export async function archiveHistory( - historyId: string, - archiveExportId?: string, - purgeHistory?: boolean -): Promise { - const { data } = await postArchiveHistory({ - history_id: historyId, - archive_export_id: archiveExportId, - purge_history: purgeHistory, - }); - return data as ArchivedHistorySummary; -} - -const putUnarchiveHistory = fetcher - .path("/api/histories/{history_id}/archive/restore") - .method("put") - // @ts-ignore: workaround for optional query parameters in PUT. More info here https://github.com/ajaishankar/openapi-typescript-fetch/pull/55 - .create({ force: undefined }); - -/** - * Unarchive/restore a history. - * @param historyId The history to unarchive. - * @param force Whether to force un-archiving for purged histories. - * @returns The restored history summary. - */ -export async function unarchiveHistory(historyId: string, force?: boolean): Promise { - const { data } = await putUnarchiveHistory({ history_id: historyId, force }); - return data as ArchivedHistorySummary; -} - -const reimportHistoryFromStore = fetcher.path("/api/histories/from_store_async").method("post").create(); - -/** - * Reimport an archived history as a new copy from the associated export record. - * - * @param archivedHistory The archived history to reimport. It must have an associated export record. - * @returns The async task result summary to track the reimport progress. - */ -export async function reimportArchivedHistoryFromExportRecord( - archivedHistory: ArchivedHistorySummary -): Promise { - if (!archivedHistory.export_record_data) { - throw new Error("The archived history does not have an associated export record."); - } - const { data } = await reimportHistoryFromStore({ - model_store_format: archivedHistory.export_record_data.model_store_format, - store_content_uri: archivedHistory.export_record_data.target_uri, - }); - return data as AsyncTaskResultSummary; -} - -function optionsToApiParams(options: GetArchivedHistoriesOptions): GetArchivedHistoriesParams { - const params: GetArchivedHistoriesParams = {}; +function optionsToApiParams(options: GetArchivedHistoriesOptions): ArchivedHistoriesQueryParams { + const params: ArchivedHistoriesQueryParams = {}; if (options.query) { params.q = ["name-contains"]; params.qv = [options.query]; diff --git a/client/src/components/History/Archiving/HistoryArchive.vue b/client/src/components/History/Archiving/HistoryArchive.vue index 24c3cd4ed417..c7780e2641eb 100644 --- a/client/src/components/History/Archiving/HistoryArchive.vue +++ b/client/src/components/History/Archiving/HistoryArchive.vue @@ -3,15 +3,13 @@ import { BAlert, BListGroup, BListGroupItem, BPagination } from "bootstrap-vue"; import { computed, onMounted, ref, watch } from "vue"; import { useRouter } from "vue-router/composables"; -import { - ArchivedHistorySummary, - fetchArchivedHistories, - reimportArchivedHistoryFromExportRecord, -} from "@/api/histories.archived"; +import { client } from "@/api"; +import { type ArchivedHistorySummary, fetchArchivedHistories } from "@/api/histories.archived"; import { useConfirmDialog } from "@/composables/confirmDialog"; import { useToast } from "@/composables/toast"; import { useHistoryStore } from "@/stores/historyStore"; import localize from "@/utils/localization"; +import { errorMessageAsString } from "@/utils/simple-error"; import DelayedInput from "@/components/Common/DelayedInput.vue"; import ArchivedHistoryCard from "@/components/History/Archiving/ArchivedHistoryCard.vue"; @@ -50,16 +48,24 @@ async function updateSearchQuery(query: string) { async function loadArchivedHistories() { isLoading.value = true; - const result = await fetchArchivedHistories({ - query: searchText.value, - currentPage: currentPage.value, - pageSize: perPage.value, - sortBy: sortBy.value, - sortDesc: sortDesc.value, - }); - totalRows.value = result.totalMatches; - archivedHistories.value = result.histories; - isLoading.value = false; + try { + const result = await fetchArchivedHistories({ + query: searchText.value, + currentPage: currentPage.value, + pageSize: perPage.value, + sortBy: sortBy.value, + sortDesc: sortDesc.value, + }); + totalRows.value = result.totalMatches; + archivedHistories.value = result.histories; + } catch (error) { + toast.error( + localize(`Failed to load archived histories with reason: ${errorMessageAsString(error)}`), + localize("Loading Failed") + ); + } finally { + isLoading.value = false; + } } function onViewHistoryInCenterPanel(history: ArchivedHistorySummary) { @@ -110,20 +116,35 @@ async function onImportCopy(history: ArchivedHistorySummary) { return; } - try { - await reimportArchivedHistoryFromExportRecord(history); - toast.success( - localize( - `The History '${history.name}' it's being imported. This process may take a while. Check your histories list after a few minutes.` - ), - localize("Importing History in background...") + if (!history.export_record_data) { + toast.error( + localize(`Failed to import history '${history.name}' because it does not have an export record.`), + localize("History Import Failed") ); - } catch (error) { + return; + } + + const { error } = await client.POST("/api/histories/from_store_async", { + body: { + model_store_format: history.export_record_data?.model_store_format, + store_content_uri: history.export_record_data?.target_uri, + }, + }); + + if (error) { toast.error( localize(`Failed to import history '${history.name}' with reason: ${error}`), localize("History Import Failed") ); + return; } + + toast.success( + localize( + `The History '${history.name}' it's being imported. This process may take a while. Check your histories list after a few minutes.` + ), + localize("Importing History in background...") + ); }