Skip to content

Commit

Permalink
Merge pull request #16003 from davelopez/add_history_archiving
Browse files Browse the repository at this point in the history
Add History Archival feature
  • Loading branch information
dannon committed Jun 19, 2023
2 parents 704e55d + 3583e8e commit a119c94
Show file tree
Hide file tree
Showing 37 changed files with 2,470 additions and 87 deletions.
1 change: 1 addition & 0 deletions client/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ module.exports = {
rules: {
...baseRules,
"@typescript-eslint/no-throw-literal": "error",
"@typescript-eslint/ban-ts-comment": "warn",
},
parser: "@typescript-eslint/parser",
parserOptions: {
Expand Down
62 changes: 51 additions & 11 deletions client/src/components/Common/models/exportRecordModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,58 @@ type ExportObjectRequestMetadata = components["schemas"]["ExportObjectRequestMet
export type StoreExportPayload = components["schemas"]["StoreExportPayload"];
export type ObjectExportTaskResponse = components["schemas"]["ObjectExportTaskResponse"];

export class ExportParamsModel {
export interface ExportParams {
readonly modelStoreFormat: string;
readonly includeFiles: boolean;
readonly includeDeleted: boolean;
readonly includeHidden: boolean;
}

export interface ExportRecord {
readonly id: string;
readonly isReady: boolean;
readonly isPreparing: boolean;
readonly isUpToDate: boolean;
readonly hasFailed: boolean;
readonly date: Date;
readonly elapsedTime: string;
readonly taskUUID: string;
readonly importUri?: string;
readonly canReimport: boolean;
readonly stsDownloadId?: string;
readonly isStsDownload: boolean;
readonly canDownload: boolean;
readonly modelStoreFormat: string;
readonly exportParams?: ExportParams;
readonly duration?: number;
readonly canExpire: boolean;
readonly isPermanent: boolean;
readonly expirationDate?: Date;
readonly expirationElapsedTime?: string;
readonly hasExpired: boolean;
readonly errorMessage?: string;
}

export class ExportParamsModel implements ExportParams {
private _params: StoreExportPayload;
constructor(data: StoreExportPayload = {}) {
this._params = data;
}

get modelStoreFormat() {
return this._params?.model_store_format;
return this._params?.model_store_format ?? "tgz";
}

get includeFiles() {
return this._params?.include_files;
return Boolean(this._params?.include_files);
}

get includeDeleted() {
return this._params?.include_deleted;
return Boolean(this._params?.include_deleted);
}

get includeHidden() {
return this._params?.include_hidden;
return Boolean(this._params?.include_hidden);
}

public equals(otherExportParams?: ExportParamsModel) {
Expand All @@ -41,9 +73,9 @@ export class ExportParamsModel {
}
}

export class ExportRecordModel {
export class ExportRecordModel implements ExportRecord {
private _data: ObjectExportTaskResponse;
private _expirationDate?: Date | null;
private _expirationDate?: Date;
private _requestMetadata?: ExportObjectRequestMetadata;
private _exportParameters?: ExportParamsModel;

Expand All @@ -56,6 +88,10 @@ export class ExportRecordModel {
: undefined;
}

get id() {
return this._data.id;
}

get isReady() {
return (this._data.ready && !this.hasExpired) ?? false;
}
Expand Down Expand Up @@ -109,7 +145,7 @@ export class ExportRecordModel {
}

get modelStoreFormat() {
return this.exportParams?.modelStoreFormat;
return this.exportParams?.modelStoreFormat ?? "tgz";
}

get exportParams() {
Expand All @@ -125,21 +161,25 @@ export class ExportRecordModel {
return this.isStsDownload && Boolean(this.duration);
}

get isPermanent() {
return !this.canExpire;
}

get expirationDate() {
if (this._expirationDate === undefined) {
this._expirationDate = this.duration ? new Date(this.date.getTime() + this.duration * 1000) : null;
this._expirationDate = this.duration ? new Date(this.date.getTime() + this.duration * 1000) : undefined;
}
return this._expirationDate;
}

get expirationElapsedTime() {
return this.canExpire && this.expirationDate
? formatDistanceToNow(this.expirationDate, { addSuffix: true })
: null;
: undefined;
}

get hasExpired() {
return this.canExpire && this.expirationDate && Date.now() > this.expirationDate.getTime();
return Boolean(this.canExpire && this.expirationDate && Date.now() > this.expirationDate.getTime());
}

get errorMessage() {
Expand Down
37 changes: 34 additions & 3 deletions client/src/components/Common/models/testData/exportData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ export const FAILED_DOWNLOAD_RESPONSE: ObjectExportTaskResponse = {
};

export const FILE_SOURCE_STORE_RESPONSE: ObjectExportTaskResponse = {
id: "FAKE_RECENT_DOWNLOAD_ID",
id: "FAKE_FILE_SOURCE_EXPORT_ID",
ready: true,
preparing: false,
up_to_date: true,
up_to_date: false,
task_uuid: "35563335-e275-4520-80e8-885793279095",
create_time: RECENT_EXPORT_DATE,
export_metadata: {
Expand All @@ -103,6 +103,37 @@ export const FILE_SOURCE_STORE_RESPONSE: ObjectExportTaskResponse = {
},
};

export const RECENT_FILE_SOURCE_STORE_RESPONSE: ObjectExportTaskResponse = {
...FILE_SOURCE_STORE_RESPONSE,
id: "FAKE_RECENT_FILE_SOURCE_EXPORT_ID",
up_to_date: true,
};

export const FAILED_FILE_SOURCE_STORE_RESPONSE: ObjectExportTaskResponse = {
...FILE_SOURCE_STORE_RESPONSE,
id: "FAKE_FAILED_FILE_SOURCE_EXPORT_ID",
export_metadata: {
request_data: FAKE_FILE_SOURCE_REQUEST_DATA,
result_data: FAILED_EXPORT_RESULT_DATA,
},
};

export const IN_PROGRESS_FILE_SOURCE_STORE_RESPONSE: ObjectExportTaskResponse = {
...FILE_SOURCE_STORE_RESPONSE,
id: "FAKE_IN_PROGRESS_FILE_SOURCE_EXPORT_ID",
ready: false,
preparing: true,
export_metadata: {
request_data: FAKE_FILE_SOURCE_REQUEST_DATA,
result_data: undefined,
},
};

export const EXPIRED_STS_DOWNLOAD_RECORD = new ExportRecordModel(EXPIRED_STS_DOWNLOAD_RESPONSE);
export const FILE_SOURCE_STORE_RECORD = new ExportRecordModel(FILE_SOURCE_STORE_RESPONSE);
export const RECENT_STS_DOWNLOAD_RECORD = new ExportRecordModel(RECENT_STS_DOWNLOAD_RESPONSE);
export const FAILED_DOWNLOAD_RECORD = new ExportRecordModel(FAILED_DOWNLOAD_RESPONSE);

export const FILE_SOURCE_STORE_RECORD = new ExportRecordModel(FILE_SOURCE_STORE_RESPONSE);
export const RECENT_FILE_SOURCE_STORE_RECORD = new ExportRecordModel(RECENT_FILE_SOURCE_STORE_RESPONSE);
export const FAILED_FILE_SOURCE_STORE_RECORD = new ExportRecordModel(FAILED_FILE_SOURCE_STORE_RESPONSE);
export const IN_PROGRESS_FILE_SOURCE_STORE_RECORD = new ExportRecordModel(IN_PROGRESS_FILE_SOURCE_STORE_RESPONSE);
24 changes: 24 additions & 0 deletions client/src/components/History/Archiving/ExportRecordCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script setup lang="ts">
import { BCard, BCardText } from "bootstrap-vue";
import IncludedBadge from "./IncludedBadge.vue";
import type { ExportRecord } from "@/components/Common/models/exportRecordModel";
const props = defineProps<{
exportRecord: ExportRecord;
}>();
</script>

<template>
<b-card id="export-record-ready">
<b-card-text>
<b>Exported {{ props.exportRecord.elapsedTime }}</b> on {{ props.exportRecord.date }}
</b-card-text>
<b-card-text v-if="props.exportRecord.exportParams">
<b>Contains datasets:</b>
<IncludedBadge item-name="active" :included="props.exportRecord.exportParams.includeFiles" />
<IncludedBadge item-name="hidden" :included="props.exportRecord.exportParams.includeHidden" />
<IncludedBadge item-name="deleted" :included="props.exportRecord.exportParams.includeDeleted" />
</b-card-text>
<b-card-text> <b>Stored in:</b> {{ props.exportRecord.importUri }} </b-card-text>
</b-card>
</template>
Loading

0 comments on commit a119c94

Please sign in to comment.