Add automatic refresh of stored objects with interval support

- Introduced `refreshStoredObject` logic to periodically update stored objects using `get_stored_object` API.
- Updated `DocumentActionButtonsGroup.vue` and `IsCurrentlyEdited.vue` to emit refresh events and handle object updates.
- Added new props to configure auto-refresh behavior, including interval and maximum execution limits.
- Extended `helpers.ts` with new `get_stored_object` function for retrieving objects by UUID.
This commit is contained in:
2026-04-15 18:10:07 +02:00
parent d17d211429
commit fbb04eb783
4 changed files with 81 additions and 6 deletions

View File

@@ -46,7 +46,7 @@ window.addEventListener("DOMContentLoaded", function () {
};
},
template:
'<document-action-buttons-group :can-edit="canEdit" :filename="filename" :stored-object="storedObject" :small="small" :dav-link="davLink" :dav-link-expiration="davLinkExpiration" @on-stored-object-status-change="onStoredObjectStatusChange"></document-action-buttons-group>',
'<document-action-buttons-group :can-edit="canEdit" :filename="filename" :stored-object="storedObject" :small="small" :dav-link="davLink" :dav-link-expiration="davLinkExpiration" @on-stored-object-status-change="onStoredObjectStatusChange" @onStoredObjectRefresh="onStoredObjectRefresh"></document-action-buttons-group>',
methods: {
onStoredObjectStatusChange: function (
newStatus: StoredObjectStatusChange,
@@ -64,6 +64,9 @@ window.addEventListener("DOMContentLoaded", function () {
el.remove();
});
},
onStoredObjectRefresh: function (newStoredObject: StoredObject) {
this.$data.storedObject = newStoredObject;
}
},
});

View File

@@ -18,7 +18,7 @@
</button>
<ul class="dropdown-menu">
<li v-if="null !== props.storedObject.lock">
<is-currently-edited :stored-object="props.storedObject as StoredObject & {lock: StoredObjectLock}"></is-currently-edited>
<is-currently-edited :stored-object="props.storedObject as StoredObject & {lock: StoredObjectLock}" @require-refresh-stored-object="refreshStoredObject"></is-currently-edited>
</li>
<li v-if="null !== props.storedObject.lock"><hr class="dropdown-divider"></li>
<li v-if="isEditableOnline">
@@ -74,6 +74,7 @@ import ConvertButton from "./StoredObjectButton/ConvertButton.vue";
import DownloadButton from "./StoredObjectButton/DownloadButton.vue";
import WopiEditButton from "./StoredObjectButton/WopiEditButton.vue";
import {
get_stored_object,
is_extension_editable,
is_extension_viewable,
is_object_ready,
@@ -87,6 +88,7 @@ import DesktopEditButton from "ChillDocStoreAssets/vuejs/StoredObjectButton/Desk
import HistoryButton from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton.vue";
import CurrentlyEditingIcon from "ChillDocStoreAssets/vuejs/StoredObjectButton/CurrentlyEditingIcon.vue";
import IsCurrentlyEdited from "ChillDocStoreAssets/vuejs/StoredObjectButton/IsCurrentlyEdited.vue";
import {useIntervalFn} from "@vueuse/core";
interface DocumentActionButtonsGroupConfig {
storedObject: StoredObject;
@@ -118,14 +120,34 @@ interface DocumentActionButtonsGroupConfig {
* the expiration date of the download, as a unix timestamp
*/
davLinkExpiration?: number;
/**
* This module will trigger a refresh of the stored object on a given interval, if true.
*/
refreshStoredObjectAuto?: boolean;
/**
* When enabled, the refresh interval, in milliseconds.
*/
refreshStoredObjectInterval?: number;
/**
* When enable, the refresh will stop after a given number of executions.
*/
refreshStoredObjectMaxTimes?: number;
}
const emit =
defineEmits<
defineEmits<{
(
e: "onStoredObjectStatusChange",
newStatus: StoredObjectStatusChange,
) => void
): void
(
e: "onStoredObjectRefresh",
newStoredObject: StoredObject,
): void
}
>();
const props = withDefaults(defineProps<DocumentActionButtonsGroupConfig>(), {
@@ -135,6 +157,9 @@ const props = withDefaults(defineProps<DocumentActionButtonsGroupConfig>(), {
canConvertPdf: true,
returnPath:
window.location.pathname + window.location.search + window.location.hash,
refreshStoredObjectAuto: true,
refreshStoredObjectInterval: 60000,
refreshStoredObjectMaxTimes: 20,
});
/**
@@ -229,8 +254,33 @@ const onObjectNewStatusCallback = async function (): Promise<void> {
return Promise.resolve();
};
let numberOfRefresh = 0;
const refreshStoredObject = async () => {
if (!props.refreshStoredObjectAuto) {
interval.pause();
return;
}
numberOfRefresh++;
const n = await get_stored_object(props.storedObject.uuid);
emit("onStoredObjectRefresh", n);
if (numberOfRefresh >= props.refreshStoredObjectMaxTimes) {
interval.pause();
}
};
const interval = useIntervalFn(
refreshStoredObject,
props.refreshStoredObjectInterval,
{immediate: false, immediateCallback: false}
);
onMounted(() => {
checkForReady();
if (props.refreshStoredObjectAuto) {
interval.resume();
}
});
</script>

View File

@@ -1,6 +1,6 @@
<script setup lang="ts">
import {StoredObject, StoredObjectLock} from "ChillDocStoreAssets/types";
import {StoredObject, StoredObjectLock, StoredObjectStatusChange} from "ChillDocStoreAssets/types";
import CurrentlyEditingIcon from "ChillDocStoreAssets/vuejs/StoredObjectButton/CurrentlyEditingIcon.vue";
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
import {computed, reactive} from "vue";
@@ -27,6 +27,14 @@ interface IsCurrentlyEditedConfig {
storedObject: StoredObject & {lock: StoredObjectLock}
}
const emit =
defineEmits<{
(
e: "requireRefreshStoredObject",
): void
}
>();
const props = defineProps<IsCurrentlyEditedConfig>();
const state = reactive({
@@ -54,8 +62,8 @@ const removeLock = async function (): Promise<void> {
return Promise.reject(e);
}
emit('requireRefreshStoredObject');
toast.success(trans(STORED_OBJECT_LOCK_REMOVE_LOCK_SUCCESS));
return Promise.resolve();
} else {
console.log('User did not confirmed edit');

View File

@@ -279,6 +279,19 @@ async function remove_lock(storedObject: StoredObject): Promise<void> {
}
}
/**
* Retrieves a stored object by its unique identifier.
*
* @param {string} storedObjectUuid - The unique identifier of the stored object to retrieve.
* @return {Promise<StoredObject>} A promise that resolves to the retrieved stored object.
*/
async function get_stored_object(storedObjectUuid: string): Promise<StoredObject> {
return await makeFetch<null, StoredObject>(
'GET',
`/api/1.0/doc-store/stored-object/${storedObjectUuid}`,
);
}
export {
build_convert_link,
build_wopi_editor_link,
@@ -290,4 +303,5 @@ export {
is_extension_viewable,
is_object_ready,
remove_lock,
get_stored_object,
};