mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2026-03-03 04:29:40 +00:00
Add Vue.js module for polling and downloading stored objects
- Created `waiting_download` module with main `App.vue` component. - Integrated polling logic to check stored object status using the `/is-ready` endpoint. - Displayed messages for pending, stopped, failure, and ready states with a "Download" button for ready objects. - Added `StoredObjectReady` type and updated types for improved type safety. - Dynamically mounted the module using dataset attributes.
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
||||
import { StoredObject, StoredObjectStatus, StoredObjectReady } from "../../types";
|
||||
import WaitingScreen from "ChillMainAssets/vuejs/_components/WaitingScreen.vue";
|
||||
import DownloadButton from "../../vuejs/StoredObjectButton/DownloadButton.vue";
|
||||
import { WaitingScreenState } from "ChillMainAssets/types";
|
||||
|
||||
interface AppProps {
|
||||
storedObjectUuid: string;
|
||||
waitingText: string;
|
||||
stoppedText: string;
|
||||
failureText: string;
|
||||
readyText: string;
|
||||
}
|
||||
|
||||
const props = defineProps<AppProps>();
|
||||
|
||||
const storedObject = ref<StoredObject | null>(null);
|
||||
const currentStatus = ref<StoredObjectStatus>("pending");
|
||||
|
||||
const state = computed<WaitingScreenState>((): WaitingScreenState => {
|
||||
if (currentStatus.value === "empty") {
|
||||
return "pending";
|
||||
}
|
||||
if (currentStatus.value === "pending" && tries >= maxTries) {
|
||||
return "stopped";
|
||||
}
|
||||
return currentStatus.value;
|
||||
});
|
||||
|
||||
let tries = 0;
|
||||
const maxTries = 120; // 120 * 10s = 20 minutes
|
||||
|
||||
const pollStatus = async (): Promise<void> => {
|
||||
if (
|
||||
currentStatus.value === "ready" ||
|
||||
currentStatus.value === "failure" ||
|
||||
tries >= maxTries
|
||||
) {
|
||||
if (tries >= maxTries && currentStatus.value === "pending") {
|
||||
currentStatus.value = "failure";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const result: StoredObjectReady = await makeFetch(
|
||||
"GET",
|
||||
`/api/1.0/doc-store/stored-object/${props.storedObjectUuid}/is-ready`,
|
||||
null
|
||||
);
|
||||
|
||||
currentStatus.value = result.status;
|
||||
|
||||
if (currentStatus.value === "ready") {
|
||||
// Fetch full object to have currentVersion and links for DownloadButton
|
||||
storedObject.value = await makeFetch(
|
||||
"GET",
|
||||
`/api/1.0/doc-store/stored-object/${props.storedObjectUuid}`,
|
||||
null
|
||||
);
|
||||
} else {
|
||||
tries++;
|
||||
setTimeout(pollStatus, 10000);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error polling status", e);
|
||||
currentStatus.value = "failure";
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
pollStatus();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<WaitingScreen :state="state">
|
||||
<template v-slot:pending>
|
||||
<p>{{ props.waitingText }}</p>
|
||||
</template>
|
||||
|
||||
<template v-slot:stopped>
|
||||
<p>{{ props.stoppedText }}</p>
|
||||
</template>
|
||||
|
||||
<template v-slot:failure>
|
||||
<p>{{ props.failureText }}</p>
|
||||
</template>
|
||||
|
||||
<template v-slot:ready>
|
||||
<p>{{ props.readyText }}</p>
|
||||
|
||||
<p v-if="storedObject !== null && storedObject.currentVersion !== null">
|
||||
<download-button
|
||||
:stored-object="storedObject"
|
||||
:at-version="storedObject.currentVersion"
|
||||
:classes="{ 'btn btn-primary': true }"
|
||||
:display-action-string-in-button="true"
|
||||
:direct-download="true"
|
||||
></download-button>
|
||||
</p>
|
||||
</template>
|
||||
</WaitingScreen>
|
||||
</template>
|
||||
@@ -0,0 +1,22 @@
|
||||
import { createApp } from "vue";
|
||||
import App from "./App.vue";
|
||||
|
||||
const elements = document.querySelectorAll<HTMLElement>(
|
||||
"[data-wait-download-stored-object]"
|
||||
);
|
||||
|
||||
elements.forEach((el) => {
|
||||
const storedObjectUuid = el.dataset.storedObjectUuid as string;
|
||||
const waitingText = el.dataset.waitingText as string;
|
||||
const stoppedText = el.dataset.stoppedText as string;
|
||||
const failureText = el.dataset.failureText as string;
|
||||
const readyText = el.dataset.readyText as string;
|
||||
|
||||
createApp(App, {
|
||||
storedObjectUuid,
|
||||
waitingText,
|
||||
stoppedText,
|
||||
failureText,
|
||||
readyText,
|
||||
}).mount(el);
|
||||
});
|
||||
@@ -3,6 +3,13 @@ import { SignedUrlGet } from "ChillDocStoreAssets/vuejs/StoredObjectButton/helpe
|
||||
|
||||
export type StoredObjectStatus = "empty" | "ready" | "failure" | "pending";
|
||||
|
||||
export interface StoredObjectReady {
|
||||
id: number;
|
||||
title: string;
|
||||
status: StoredObjectStatus;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface StoredObject {
|
||||
id: number;
|
||||
title: string | null;
|
||||
|
||||
@@ -18,4 +18,8 @@ module.exports = function (encore) {
|
||||
"vue_document_signature",
|
||||
__dirname + "/Resources/public/vuejs/DocumentSignature/index",
|
||||
);
|
||||
encore.addEntry(
|
||||
"page_wait_download_stored_object",
|
||||
__dirname + "/Resources/public/module/waiting_download/index.ts",
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user