web/satellite: fix for object browser locked objects

This is a fix for locked objects count to not update after some action (upload, delete etc.)

Although the issue is still there if user deletes file, navigates outside object browser and navigates back to the same bucket.
In this case we would refetch objects count both from satellite API and our gateway.
So bucket tally wouldn't be triggered that fast and object browser would still show locked objects.
Anyway it's better than it is now.

Also reworked weird object browser initialization which triggered some routing error so this event would be displayed in hubspot as a UI error

Change-Id: I545ab925b135fe3ef2740d17aaece6d43b731c96
This commit is contained in:
Vitalii 2023-03-31 12:26:26 +03:00 committed by Storj Robot
parent 2966b70498
commit c95f552b72
6 changed files with 55 additions and 55 deletions

View File

@ -101,8 +101,8 @@
</template>
<template #body>
<tr
v-for="file in formattedFilesUploading"
:key="file.ETag"
v-for="(file, index) in formattedFilesUploading"
:key="index"
>
<!-- using <th> to comply with common Vtable.vue-->
<th
@ -191,7 +191,7 @@
</template>
<script setup lang="ts">
import { computed, onBeforeMount, ref } from 'vue';
import { computed, onBeforeMount, reactive, ref } from 'vue';
import FileBrowserHeader from './FileBrowserHeader.vue';
import FileEntry from './FileEntry.vue';
@ -206,6 +206,7 @@ import { useNotify, useRouter, useStore } from '@/utils/hooks';
import { Bucket } from '@/types/buckets';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { APP_STATE_MUTATIONS } from '@/store/mutationConstants';
import { BrowserObject } from '@/store/modules/files';
import VButton from '@/components/common/VButton.vue';
import BucketSettingsNav from '@/components/objects/BucketSettingsNav.vue';
@ -218,11 +219,12 @@ import BlackArrowExpand from '@/../static/images/common/BlackArrowExpand.svg';
import UploadIcon from '@/../static/images/browser/upload.svg';
const store = useStore();
const router = useRouter();
const nativeRouter = useRouter();
const router = reactive(nativeRouter);
const notify = useNotify();
const folderInput = ref<HTMLInputElement>(null);
const fileInput = ref<HTMLInputElement>(null);
const folderInput = ref<HTMLInputElement>();
const fileInput = ref<HTMLInputElement>();
const fetchingFilesSpinner = ref<boolean>(false);
const isUploadDropDownShown = ref<boolean>(false);
@ -248,7 +250,7 @@ const path = computed((): string => {
/**
* Return files that are currently being uploaded from the store.
*/
const filesUploading = computed((): string => {
const filesUploading = computed((): BrowserObject[] => {
return store.state.files.uploading;
});
@ -273,7 +275,7 @@ const lockedFilesNumber = computed((): number => {
*/
const objectsCount = computed((): number => {
const name: string = store.state.files.bucket;
const data: Bucket = store.state.bucketUsageModule.page.buckets.find((bucket: Bucket) => bucket.name === name);
const data: Bucket | undefined = store.state.bucketUsageModule.page.buckets.find((bucket: Bucket) => bucket.name === name);
return data?.objectCount || 0;
});
@ -291,7 +293,7 @@ const lockedFilesEntryDisplayed = computed((): boolean => {
/**
* Return up to five files currently being uploaded for display purposes.
*/
const formattedFilesUploading = computed((): string => {
const formattedFilesUploading = computed((): BrowserObject[] => {
if (filesUploading.value.length > 5) {
return filesUploading.value.slice(0, 5);
}
@ -354,7 +356,7 @@ function closeBanner(): void {
}
function calculateRoutePath(): string {
let pathMatch = router.history.current.params.pathMatch;
let pathMatch = router.currentRoute.params.pathMatch;
pathMatch = Array.isArray(pathMatch)
? pathMatch.join('/') + '/'
: pathMatch;
@ -372,39 +374,6 @@ async function onRouteChange(): Promise<void> {
await list(routePath.value);
}
/**
* Set spinner state. If routePath is not present navigate away.
* If there's some error then re-render the page with a call to list.
*/
onBeforeMount(async () => {
if (!bucket.value) {
const path = RouteConfig.Buckets.with(RouteConfig.BucketsManagement).path;
analytics.pageVisit(path);
await router.push(path);
return;
}
// display the spinner while files are being fetched
fetchingFilesSpinner.value = true;
if (!routePath.value) {
try {
await router.push({
path: `${store.state.files.browserRoot}${path.value}`,
});
analytics.pageVisit(`${store.state.files.browserRoot}${path.value}`);
} catch (err) {
await list('');
analytics.errorEventTriggered(AnalyticsErrorEventSource.FILE_BROWSER_CHANGE_ROUTE);
}
}
// remove the spinner after files have been fetched
fetchingFilesSpinner.value = false;
});
/**
* Close modal, file share modal, dropdown, and remove all selected files from the store.
*/
@ -428,7 +397,7 @@ function toggleFolderCreationModal(): void {
/**
* Return the file name of the passed in file argument formatted.
*/
function filename(file: BrowserFile): string {
function filename(file: BrowserObject): string {
return file.Key.length > 25
? file.Key.slice(0, 25) + '...'
: file.Key;
@ -507,6 +476,36 @@ async function goToBuckets(): Promise<void> {
analytics.pageVisit(RouteConfig.Buckets.with(RouteConfig.BucketsManagement).path);
await onRouteChange();
}
/**
* Set spinner state. If routePath is not present navigate away.
* If there's some error then re-render the page with a call to list.
*/
onBeforeMount(async () => {
if (!bucket.value) {
const path = RouteConfig.Buckets.with(RouteConfig.BucketsManagement).path;
analytics.pageVisit(path);
await router.push(path);
return;
}
// display the spinner while files are being fetched
fetchingFilesSpinner.value = true;
try {
await Promise.all([
list(''),
store.dispatch('files/getObjectCount'),
]);
} catch (err) {
await notify.error(err.message, AnalyticsErrorEventSource.FILE_BROWSER_LIST_CALL);
}
// remove the spinner after files have been fetched
fetchingFilesSpinner.value = false;
});
</script>
<style scoped lang="scss">

View File

@ -66,7 +66,7 @@ const lockedFilesNumber = computed((): number => {
*/
const objectsCount = computed((): number => {
const name: string = store.state.files.bucket;
const data: Bucket = store.state.bucketUsageModule.page.buckets.find((bucket: Bucket) => bucket.name === name);
const data: Bucket | undefined = store.state.bucketUsageModule.page.buckets.find((bucket: Bucket) => bucket.name === name);
return data?.objectCount || 0;
});

View File

@ -61,7 +61,7 @@ import LogoIcon from '@/../static/images/logo.svg';
import MailIcon from '@/../static/images/register/mail.svg';
const props = withDefaults(defineProps<{
email: string;
email?: string;
showManualActivationMsg?: boolean;
}>(), {
email: '',

View File

@ -239,8 +239,11 @@ watch(passphrase, async () => {
secretKey: edgeCredentials.value.secretKey,
});
try {
await store.dispatch(BUCKET_ACTIONS.FETCH, bucketPage.value.currentPage);
await store.dispatch('files/list', '');
await Promise.all([
store.dispatch(BUCKET_ACTIONS.FETCH, bucketPage.value.currentPage),
store.dispatch('files/list', ''),
store.dispatch('files/getObjectCount'),
]);
} catch (error) {
await notify.error(error.message, AnalyticsErrorEventSource.UPLOAD_FILE_VIEW);
}

View File

@ -12,7 +12,7 @@ const listCache = new Map();
type Promisable<T> = T | PromiseLike<T>;
type BrowserObject = {
export type BrowserObject = {
Key: string;
Size: number;
LastModified: number;
@ -331,14 +331,13 @@ export const makeFilesModule = (): FilesModule => ({
assertIsInitialized(state);
const [response] = await Promise.all([
state.s3.listObjects({
const response = await state.s3
.listObjects({
Bucket: state.bucket,
Delimiter: '/',
Prefix: path,
}).promise(),
path ? undefined : dispatch('getObjectCount'),
]);
})
.promise();
const { Contents, CommonPrefixes } = response;

View File

@ -81,7 +81,6 @@ export enum AnalyticsErrorEventSource {
CREATE_AG_MODAL = 'Create access grant modal',
CONFIRM_DELETE_AG_MODAL = 'Confirm delete access grant modal',
CREATE_AG_FORM = 'Create access grant form',
FILE_BROWSER_CHANGE_ROUTE = 'File browser - change route',
FILE_BROWSER_LIST_CALL = 'File browser - list API call',
FILE_BROWSER_ENTRY = 'File browser entry',
PROJECT_INFO_BAR = 'Project info bar',