web/satellite: use pinia object browser module instead of old vuex module

Start using object browser pinia module instead of old files vuex module.
Also removed vuex related code.

Note: dependency will be removed in a follow-up change

Change-Id: I78cfb62a1ecc32bd86381bd3bfd3be4bd0f38e14
This commit is contained in:
Vitalii 2023-04-13 16:27:28 +03:00
parent 2405bc8f3b
commit 8d31e13db6
37 changed files with 297 additions and 1130 deletions

View File

@ -64,7 +64,7 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { Download } from '@/utils/download';
import { AnalyticsHttpApi } from '@/api/analytics';
@ -83,7 +83,6 @@ const props = defineProps<{
onContinue: () => void;
}>();
const store = useStore();
const notify = useNotify();
const router = useRouter();

View File

@ -45,7 +45,6 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useStore } from '@/utils/hooks';
import { LocalData } from '@/utils/localData';
import { AnalyticsHttpApi } from '@/api/analytics';
@ -58,8 +57,6 @@ const props = defineProps<{
onContinue: () => void;
}>();
const store = useStore();
const isDontShow = ref<boolean>(false);
const analytics: AnalyticsHttpApi = new AnalyticsHttpApi();

View File

@ -48,8 +48,6 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { useStore } from '@/utils/hooks';
import ButtonsContainer from '@/components/accessGrants/createFlow/components/ButtonsContainer.vue';
import Toggle from '@/components/accessGrants/createFlow/components/Toggle.vue';
import VButton from '@/components/common/VButton.vue';
@ -64,8 +62,6 @@ const props = defineProps<{
onContinue: () => void;
}>();
const store = useStore();
const isPassphraseSaved = ref<boolean>(false);
/**

View File

@ -75,7 +75,7 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { useNotify, useStore } from '@/utils/hooks';
import { useNotify } from '@/utils/hooks';
import { Download } from '@/utils/download';
import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { AnalyticsHttpApi } from '@/api/analytics';
@ -92,7 +92,6 @@ const props = defineProps<{
onContinue: () => void;
}>();
const store = useStore();
const notify = useNotify();
const isPassphraseSaved = ref<boolean>(false);

View File

@ -77,7 +77,7 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { Download } from '@/utils/download';
import { AnalyticsHttpApi } from '@/api/analytics';
@ -94,7 +94,6 @@ const props = defineProps<{
credentials: EdgeCredentials;
}>();
const store = useStore();
const notify = useNotify();
const router = useRouter();

View File

@ -31,7 +31,7 @@ import {
PaymentsHistoryItemType,
} from '@/types/payments';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import { useNotify, useStore } from '@/utils/hooks';
import { useNotify } from '@/utils/hooks';
import { useBillingStore } from '@/store/modules/billingStore';
import BillingHistoryHeader
@ -41,7 +41,6 @@ import BillingHistoryItem
import VTable from '@/components/common/VTable.vue';
const billingStore = useBillingStore();
const store = useStore();
const notify = useNotify();
async function fetchHistory(): Promise<void> {

View File

@ -35,8 +35,6 @@
import { computed } from 'vue';
import { CreditCard } from '@/types/payments';
import { useStore } from '@/utils/hooks';
import { useBillingStore } from '@/store/modules/billingStore';
import AmericanExpressIcon from '@/../static/images/payments/cardIcons/americanexpress.svg';
import DefaultIcon from '@/../static/images/payments/cardIcons/default.svg';
@ -63,9 +61,6 @@ const props = withDefaults(defineProps<{
creditCard: () => new CreditCard(),
});
const billingStore = useBillingStore();
const store = useStore();
const emit = defineEmits(['edit', 'remove']);
const cardIcon = computed(() => {
@ -79,13 +74,6 @@ function edit(): void {
function remove(): void {
emit('remove', props.creditCard);
}
/**
* Toggle card selection dialog.
*/
function toggleSelection(): void {
billingStore.toggleCardSelection(props.creditCard.id);
}
</script>
<style scoped lang="scss">

View File

@ -50,9 +50,10 @@
<script setup lang="ts">
import { computed } from 'vue';
import { useRouter, useStore } from '@/utils/hooks';
import { useRouter } from '@/utils/hooks';
import { useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
const store = useStore();
const obStore = useObjectBrowserStore();
const router = useRouter();
const emit = defineEmits(['onUpdate', 'bucketClick']);
@ -61,14 +62,14 @@ const emit = defineEmits(['onUpdate', 'bucketClick']);
* Retrieves the current bucket name from the store.
*/
const bucketName = computed((): string => {
return store.state.files.bucket;
return obStore.state.bucket;
});
/**
* Retrieves the current path from the store and creates an array of folders for the bread crumbs that the user can click on.
*/
const crumbs = computed((): string[] => {
let path: string[] = store.state.files.path.split('/');
let path: string[] = obStore.state.path.split('/');
path =
path.length > 1
? [bucketName.value, ...path.slice(0, path.length - 1)]
@ -84,7 +85,7 @@ function bucketClick() {
* Redirects to partial upload to bucket buckets path.
*/
async function redirectToCrumb(idx: number): Promise<void> {
await router.push(link(idx)).catch(err => {});
await router.push(link(idx)).catch(_ => {});
emit('onUpdate');
}
@ -96,7 +97,7 @@ function link(idx: number): string {
if (idx > 0) path = crumbs.value.slice(1, idx + 1).join('/') + '/';
return store.state.files.browserRoot + path;
return obStore.state.browserRoot + path;
}
/**

View File

@ -203,10 +203,10 @@ import BreadCrumbs from './BreadCrumbs.vue';
import { AnalyticsHttpApi } from '@/api/analytics';
import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { RouteConfig } from '@/router';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import { Bucket } from '@/types/buckets';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { BrowserObject } from '@/store/modules/files';
import { BrowserObject, useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import { useAppStore } from '@/store/modules/appStore';
import { useBucketsStore } from '@/store/modules/bucketsStore';
@ -222,7 +222,8 @@ import UploadIcon from '@/../static/images/browser/upload.svg';
const bucketsStore = useBucketsStore();
const appStore = useAppStore();
const store = useStore();
const obStore = useObjectBrowserStore();
const nativeRouter = useRouter();
const router = reactive(nativeRouter);
const notify = useNotify();
@ -241,35 +242,35 @@ const analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
* Check if the s3 client has been initialized in the store.
*/
const isInitialized = computed((): boolean => {
return store.getters['files/isInitialized'];
return obStore.isInitialized;
});
/**
* Retrieve the current path from the store.
*/
const path = computed((): string => {
return store.state.files.path;
return obStore.state.path;
});
/**
* Return files that are currently being uploaded from the store.
*/
const filesUploading = computed((): BrowserObject[] => {
return store.state.files.uploading;
return obStore.state.uploading;
});
/**
* Return file browser path from store.
*/
const currentPath = computed((): string => {
return store.state.files.path;
return obStore.state.path;
});
/**
* Return locked files number.
*/
const lockedFilesNumber = computed((): number => {
const ownObjectsCount = store.state.files.objectsCount;
const ownObjectsCount = obStore.state.objectsCount;
return objectsCount.value - ownObjectsCount;
});
@ -278,7 +279,7 @@ const lockedFilesNumber = computed((): number => {
* Returns bucket objects count from store.
*/
const objectsCount = computed((): number => {
const name: string = store.state.files.bucket;
const name: string = obStore.state.bucket;
const data: Bucket | undefined = bucketsStore.state.page.buckets.find((bucket: Bucket) => bucket.name === name);
return data?.objectCount || 0;
@ -319,7 +320,7 @@ const formattedFilesWaitingToBeUploaded = computed((): string => {
});
const bucketName = computed((): string => {
return store.state.files.bucket;
return obStore.state.bucket;
});
/**
@ -329,9 +330,9 @@ const allFilesSelected = computed((): boolean => {
if (files.value.length === 0) {
return false;
}
const shiftSelectedFiles = store.state.files.shiftSelectedFiles;
const selectedFiles = store.state.files.selectedFiles;
const selectedAnchorFile = store.state.files.selectedAnchorFile;
const shiftSelectedFiles = obStore.state.shiftSelectedFiles;
const selectedFiles = obStore.state.selectedFiles;
const selectedAnchorFile = obStore.state.selectedAnchorFile;
const allSelectedFiles = [
...selectedFiles,
...shiftSelectedFiles,
@ -344,7 +345,7 @@ const allFilesSelected = computed((): boolean => {
});
const files = computed((): BrowserObject[] => {
return store.getters['files/sortedFiles'];
return obStore.sortedFiles;
});
/**
@ -395,7 +396,7 @@ async function onBack(): Promise<void> {
async function onRouteChange(): Promise<void> {
routePath.value = calculateRoutePath();
await store.dispatch('files/closeDropdown');
obStore.closeDropdown();
await list(routePath.value);
}
@ -403,11 +404,11 @@ async function onRouteChange(): Promise<void> {
* Close modal, file share modal, dropdown, and remove all selected files from the store.
*/
function closeModalDropdown(): void {
if (store.state.files.openedDropdown) {
store.dispatch('files/closeDropdown');
if (obStore.state.openedDropdown) {
obStore.closeDropdown();
}
store.dispatch('files/clearAllSelectedFiles');
obStore.clearAllSelectedFiles();
}
/**
@ -430,7 +431,7 @@ function filename(file: BrowserObject): string {
* Upload the current selected or dragged-and-dropped file.
*/
async function upload(e: Event): Promise<void> {
await store.dispatch('files/upload', { e });
await obStore.upload({ e });
await analytics.eventTriggered(AnalyticsEvent.OBJECT_UPLOADED);
const target = e.target as HTMLInputElement;
target.value = '';
@ -440,7 +441,7 @@ async function upload(e: Event): Promise<void> {
* Cancel the upload of the current file that's passed in as an argument.
*/
function cancelUpload(fileName: string): void {
store.dispatch('files/cancelUpload', fileName);
obStore.cancelUpload(fileName);
}
/**
@ -448,9 +449,7 @@ function cancelUpload(fileName: string): void {
*/
async function list(path: string): Promise<void> {
try {
await store.dispatch('files/list', path, {
root: true,
});
await obStore.list(path);
} catch (error) {
notify.error(error.message, AnalyticsErrorEventSource.FILE_BROWSER_LIST_CALL);
}
@ -503,16 +502,17 @@ async function goToBuckets(): Promise<void> {
/**
* Toggles the selection of all files.
* */
async function toggleSelectAllFiles(): Promise<void> {
function toggleSelectAllFiles(): void {
if (files.value.length === 0) {
return;
}
if (allFilesSelected.value) {
await store.dispatch('files/clearAllSelectedFiles');
obStore.clearAllSelectedFiles();
} else {
await store.dispatch('files/clearAllSelectedFiles');
store.commit('files/setSelectedAnchorFile', files.value[0]);
await store.dispatch('files/updateSelectedFiles', files.value.slice(1, files.value.length));
obStore.clearAllSelectedFiles();
obStore.setSelectedAnchorFile(files.value[0]);
obStore.updateSelectedFiles(files.value.slice(1, files.value.length));
}
}
@ -531,7 +531,7 @@ onBeforeMount(async () => {
}
// clear previous file selections.
store.dispatch('files/clearAllSelectedFiles');
obStore.clearAllSelectedFiles();
// display the spinner while files are being fetched
fetchingFilesSpinner.value = true;
@ -539,7 +539,7 @@ onBeforeMount(async () => {
try {
await Promise.all([
list(''),
store.dispatch('files/getObjectCount'),
obStore.getObjectCount(),
]);
} catch (err) {
await notify.error(err.message, AnalyticsErrorEventSource.FILE_BROWSER_LIST_CALL);

View File

@ -93,37 +93,38 @@
import { Fragment } from 'vue-fragment';
import { computed, ref } from 'vue';
import { useStore } from '@/utils/hooks';
import { useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import AscIcon from '@/../static/images/objects/asc.svg';
import CloseIcon from '@/../static/images/common/closeCross.svg';
import DescIcon from '@/../static/images/objects/desc.svg';
import DeleteIcon from '@/../static/images/objects/delete.svg';
const store = useStore();
const obStore = useObjectBrowserStore();
const hover = ref('');
function fromFilesStore(prop: string): string {
return store.state.files[prop];
}
/**
* Check if the trashcan to delete selected files/folder should be displayed.
*/
const filesToDelete = computed((): boolean => {
return (!!store.state.files.selectedAnchorFile || (
!!store.state.files.unselectedAnchorFile &&
(store.state.files.selectedFiles.length > 0 ||
store.state.files.shiftSelectedFiles.length > 0)
));
return (
!!obStore.state.selectedAnchorFile ||
(
!!obStore.state.unselectedAnchorFile &&
(
obStore.state.selectedFiles.length > 0 ||
obStore.state.shiftSelectedFiles.length > 0
)
)
);
});
/**
* Check if the files/folders deletion dropdown should be displayed.
*/
const isDropdownDisplayed = computed((): boolean => {
return store.state.files.openedDropdown === 'FileBrowser';
return obStore.state.openedDropdown === 'FileBrowser';
});
const nameSortData = computed((): { isHidden: boolean, isDesc: boolean } => {
@ -151,14 +152,14 @@ const dateSortData = computed((): { isHidden: boolean, isDesc: boolean } => {
* Check if a heading is sorted in descending order.
*/
function isDesc(heading: string): boolean {
return fromFilesStore('headingSorted') === heading && fromFilesStore('orderBy') === 'desc';
return obStore.state.headingSorted === heading && obStore.state.orderBy === 'desc';
}
/**
* Check if sorting arrow should be displayed.
*/
function showArrow(heading: string): boolean {
return fromFilesStore('headingSorted') === heading || hover.value === heading;
return obStore.state.headingSorted === heading || hover.value === heading;
}
/**
@ -172,7 +173,7 @@ function mouseOver(heading: string): void {
* Set the heading for files/folders to be sorted by in the store.
*/
function sortBy(heading: string): void {
store.commit('files/sort', heading);
obStore.sort(heading);
}
/**
@ -186,22 +187,22 @@ function mouseLeave(): void {
* Open the deletion of files/folders dropdown.
*/
function deleteSelectedDropdown(): void {
store.dispatch('files/openFileBrowserDropdown');
obStore.openFileBrowserDropdown();
}
/**
* Delete the selected files/folders.
*/
function confirmDeleteSelection(): void {
store.dispatch('files/deleteSelected');
store.dispatch('files/closeDropdown');
obStore.deleteSelected();
obStore.closeDropdown();
}
/**
* Abort files/folder selected for deletion.
*/
function cancelDeleteSelection(): void {
store.dispatch('files/closeDropdown');
obStore.closeDropdown();
}
</script>

View File

@ -112,10 +112,10 @@
import { computed, ref } from 'vue';
import prettyBytes from 'pretty-bytes';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { BrowserObject } from '@/store/modules/files';
import { BrowserObject, useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import { useAppStore } from '@/store/modules/appStore';
import TableItem from '@/components/common/TableItem.vue';
@ -128,7 +128,7 @@ import DotsIcon from '@/../static/images/objects/dots.svg';
import CloseIcon from '@/../static/images/common/closeCross.svg';
const appStore = useAppStore();
const store = useStore();
const obStore = useObjectBrowserStore();
const notify = useNotify();
const router = useRouter();
@ -189,15 +189,15 @@ const uploadDate = computed((): string => {
* Check with the store to see if the dropdown is open for the current file/folder.
*/
const dropdownOpen = computed((): boolean => {
return store.state.files.openedDropdown === props.file.Key;
return obStore.state.openedDropdown === props.file.Key;
});
/**
* Return a link to the current folder for navigation.
*/
const link = computed((): string => {
const browserRoot = store.state.files.browserRoot;
const uriParts = (store.state.files.path + props.file.Key).split('/');
const browserRoot = obStore.state.browserRoot;
const uriParts = (obStore.state.path + props.file.Key).split('/');
const pathAndKey = uriParts.map(part => encodeURIComponent(part)).join('/');
return pathAndKey.length > 0
? browserRoot + pathAndKey + '/'
@ -209,13 +209,13 @@ const link = computed((): string => {
*/
const isFileSelected = computed((): boolean => {
return Boolean(
store.state.files.selectedAnchorFile === props.file ||
store.state.files.selectedFiles.find(
(file) => file === props.file,
) ||
store.state.files.shiftSelectedFiles.find(
(file) => file === props.file,
),
obStore.state.selectedAnchorFile === props.file ||
obStore.state.selectedFiles.find(
(file) => file === props.file,
) ||
obStore.state.shiftSelectedFiles.find(
(file) => file === props.file,
),
);
});
@ -237,16 +237,16 @@ const fileTypeIsFile = computed((): boolean => {
* Open the modal for the current file.
*/
function openModal(): void {
store.commit('files/setObjectPathForModal', props.path + props.file.Key);
obStore.setObjectPathForModal(props.path + props.file.Key);
appStore.updateActiveModal(MODALS.objectDetails);
store.dispatch('files/closeDropdown');
obStore.closeDropdown();
}
/**
* Return a boolean signifying whether the current file/folder is in the process of being deleted, therefore a spinner shoud be shown.
*/
function loadingSpinner(): boolean {
return Boolean(store.state.files.filesToBeDeleted.find(
return Boolean(obStore.state.filesToBeDeleted.find(
(file) => file === props.file,
));
}
@ -255,8 +255,8 @@ function loadingSpinner(): boolean {
* Select the current file/folder whether it be a click, click + shiftKey, click + metaKey or ctrlKey, or unselect the rest.
*/
function selectFile(event: KeyboardEvent): void {
if (store.state.files.openedDropdown) {
store.dispatch('files/closeDropdown');
if (obStore.state.openedDropdown) {
obStore.closeDropdown();
}
if (event.shiftKey) {
@ -270,9 +270,9 @@ function selectFile(event: KeyboardEvent): void {
setSelectedFile(isSelectedFile);
}
async function openFolder(): Promise<void> {
await router.push(link.value);
store.dispatch('files/clearAllSelectedFiles');
function openFolder(): void {
router.push(link.value);
obStore.clearAllSelectedFiles();
emit('onUpdate');
}
@ -281,70 +281,51 @@ async function openFolder(): Promise<void> {
*/
function setSelectedFile(command: boolean): void {
/* this function is responsible for selecting and unselecting a file on file click or [CMD + click] AKA command. */
const shiftSelectedFiles =
store.state.files.shiftSelectedFiles;
const selectedFiles = store.state.files.selectedFiles;
const shiftSelectedFiles = obStore.state.shiftSelectedFiles;
const selectedFiles = obStore.state.selectedFiles;
const files = [
...selectedFiles,
...shiftSelectedFiles,
];
const selectedAnchorFile =
store.state.files.selectedAnchorFile;
const selectedAnchorFile = obStore.state.selectedAnchorFile;
if (command && props.file === selectedAnchorFile) {
/* if it's [CMD + click] and the file selected is the actual selectedAnchorFile, then unselect the file but store it under unselectedAnchorFile in case the user decides to do a [shift + click] right after this action. */
store.commit('files/setUnselectedAnchorFile', props.file);
store.commit('files/setSelectedAnchorFile', null);
/* if it's [CMD + click] and the file selected is the actual selectedAnchorFile, then unselect the file but store it under unselectedAnchorFile in case the user decides to do a [shift + click] right after this action. */
obStore.setUnselectedAnchorFile(props.file);
obStore.setSelectedAnchorFile(null);
} else if (command && files.includes(props.file)) {
/* if it's [CMD + click] and the file selected is a file that has already been selected in selectedFiles and shiftSelectedFiles, then unselect it by filtering it out. */
store.dispatch(
'files/updateSelectedFiles',
selectedFiles.filter(
(fileSelected) => fileSelected !== props.file,
),
);
store.dispatch(
'files/updateShiftSelectedFiles',
shiftSelectedFiles.filter(
(fileSelected) => fileSelected !== props.file,
),
);
/* if it's [CMD + click] and the file selected is a file that has already been selected in selectedFiles and shiftSelectedFiles, then unselect it by filtering it out. */
obStore.updateSelectedFiles(selectedFiles.filter((fileSelected) => fileSelected !== props.file));
obStore.updateShiftSelectedFiles(shiftSelectedFiles.filter((fileSelected) => fileSelected !== props.file));
} else if (command && selectedAnchorFile) {
/* if it's [CMD + click] and there is already a selectedAnchorFile, then add the selectedAnchorFile and shiftSelectedFiles into the array of selectedFiles, set selectedAnchorFile to the file that was clicked, set unselectedAnchorFile to null, and set shiftSelectedFiles to an empty array. */
/* if it's [CMD + click] and there is already a selectedAnchorFile, then add the selectedAnchorFile and shiftSelectedFiles into the array of selectedFiles, set selectedAnchorFile to the file that was clicked, set unselectedAnchorFile to null, and set shiftSelectedFiles to an empty array. */
const filesSelected = [...selectedFiles];
if (!filesSelected.includes(selectedAnchorFile)) {
filesSelected.push(selectedAnchorFile);
}
store.dispatch('files/updateSelectedFiles', [
obStore.updateSelectedFiles([
...filesSelected,
...shiftSelectedFiles.filter(
(file) => !filesSelected.includes(file),
),
]);
store.commit('files/setSelectedAnchorFile', props.file);
store.commit('files/setUnselectedAnchorFile', null);
store.dispatch('files/updateShiftSelectedFiles', []);
obStore.setSelectedAnchorFile(props.file);
obStore.setUnselectedAnchorFile(null);
obStore.updateShiftSelectedFiles([]);
} else if (command) {
/* if it's [CMD + click] and it has not met any of the above conditions, then set selectedAnchorFile to file and set unselectedAnchorfile to null, update the selectedFiles, and update the shiftSelectedFiles */
store.commit('files/setSelectedAnchorFile', props.file);
store.commit('files/setUnselectedAnchorFile', null);
store.dispatch('files/updateSelectedFiles', [
/* if it's [CMD + click] and it has not met any of the above conditions, then set selectedAnchorFile to file and set unselectedAnchorfile to null, update the selectedFiles, and update the shiftSelectedFiles */
obStore.setSelectedAnchorFile(props.file);
obStore.setUnselectedAnchorFile(null);
obStore.updateSelectedFiles([
...selectedFiles,
...shiftSelectedFiles,
]);
store.dispatch('files/updateShiftSelectedFiles', []);
obStore.updateShiftSelectedFiles([]);
} else {
/* if it's just a file click without any modifier ... */
const newSelection = [...files];
@ -356,20 +337,21 @@ function setSelectedFile(command: boolean): void {
break;
case selectedAnchorFile === props.file:
// this file is already selected, deselect.
store.commit('files/setSelectedAnchorFile', null);
store.commit('files/setUnselectedAnchorFile', props.file);
obStore.setSelectedAnchorFile(null);
obStore.setUnselectedAnchorFile(props.file);
break;
case !!selectedAnchorFile:
// there's an anchor file, but not this file.
// add the anchor file to the selection arr and make this file the anchor file.
newSelection.push(selectedAnchorFile as BrowserObject);
store.commit('files/setSelectedAnchorFile', props.file);
obStore.setSelectedAnchorFile(props.file);
break;
default:
store.commit('files/setSelectedAnchorFile', props.file);
obStore.setSelectedAnchorFile(props.file);
}
store.dispatch('files/updateShiftSelectedFiles', []);
store.dispatch('files/updateSelectedFiles', newSelection);
obStore.updateShiftSelectedFiles([]);
obStore.updateSelectedFiles(newSelection);
}
}
@ -378,25 +360,18 @@ function setSelectedFile(command: boolean): void {
*/
function setShiftSelectedFiles(): void {
/* this function is responsible for selecting all files from selectedAnchorFile to the file that was selected with [shift + click] */
const files = store.getters['files/sortedFiles'];
const unselectedAnchorFile =
store.state.files.unselectedAnchorFile;
const files = obStore.sortedFiles;
const unselectedAnchorFile = obStore.state.unselectedAnchorFile;
if (unselectedAnchorFile) {
/* if there is an unselectedAnchorFile, meaning that in the previous action the user unselected the anchor file but is now chosing to do a [shift + click] on another file, then reset the selectedAnchorFile, the achor file, to unselectedAnchorFile. */
store.commit(
'files/setSelectedAnchorFile',
unselectedAnchorFile,
);
store.commit('files/setUnselectedAnchorFile', null);
/* if there is an unselectedAnchorFile, meaning that in the previous action the user unselected the anchor file but is now chosing to do a [shift + click] on another file, then reset the selectedAnchorFile, the achor file, to unselectedAnchorFile. */
obStore.setSelectedAnchorFile(unselectedAnchorFile);
obStore.setUnselectedAnchorFile(null);
}
const selectedAnchorFile = store.state.files.selectedAnchorFile;
const selectedAnchorFile = obStore.state.selectedAnchorFile;
if (!selectedAnchorFile) {
store.commit('files/setSelectedAnchorFile', props.file);
obStore.setSelectedAnchorFile(props.file);
return;
}
@ -409,16 +384,10 @@ function setShiftSelectedFiles(): void {
const start = Math.min(anchorIdx, shiftIdx);
const end = Math.max(anchorIdx, shiftIdx) + 1;
store.dispatch(
'files/updateShiftSelectedFiles',
obStore.updateShiftSelectedFiles(
files
.slice(start, end)
.filter(
(file) =>
!store.state.files.selectedFiles.includes(
file,
) && file !== selectedAnchorFile,
),
.filter((file) => !obStore.state.selectedFiles.includes(file) && file !== selectedAnchorFile),
);
}
@ -426,8 +395,8 @@ function setShiftSelectedFiles(): void {
* Open the share modal for the current file.
*/
function share(): void {
store.dispatch('files/closeDropdown');
store.commit('files/setObjectPathForModal', props.path + props.file.Key);
obStore.closeDropdown();
obStore.setObjectPathForModal(props.path + props.file.Key);
appStore.updateActiveModal(MODALS.shareObject);
}
@ -435,7 +404,7 @@ function share(): void {
* Close the dropdown.
*/
function closeDropdown(): void {
store.dispatch('files/closeDropdown');
obStore.closeDropdown();
// remove the dropdown delete confirmation
deleteConfirmation.value = false;
@ -445,7 +414,7 @@ function closeDropdown(): void {
* Open the dropdown for the current file/folder.
*/
function openDropdown(): void {
store.dispatch('files/openDropdown', props.file.Key);
obStore.openDropdown(props.file.Key);
// remove the dropdown delete confirmation
deleteConfirmation.value = false;
@ -456,14 +425,13 @@ function openDropdown(): void {
*/
function download(): void {
try {
store.dispatch('files/download', props.file);
obStore.download(props.file);
notify.warning('Do not share download link with other people. If you want to share this data better use "Share" option.');
} catch (error) {
notify.error('Can not download your file', AnalyticsErrorEventSource.FILE_BROWSER_ENTRY);
}
store.dispatch('files/closeDropdown');
deleteConfirmation.value = false;
closeDropdown();
}
/**
@ -477,21 +445,21 @@ function confirmDeletion(): void {
* Delete the selected file/folder.
*/
async function finalDelete(): Promise<void> {
store.dispatch('files/closeDropdown');
store.dispatch('files/addFileToBeDeleted', props.file);
obStore.closeDropdown();
obStore.addFileToBeDeleted(props.file);
const params = { ...props };
(props.file.type === 'file') ? await store.dispatch('files/delete', params) : store.dispatch('files/deleteFolder', params);
props.file.type === 'file' ?
await obStore.deleteObject(props.path, props.file) :
await obStore.deleteFolder(props.file, props.path);
// refresh the files displayed
try {
await store.dispatch('files/list');
await obStore.list();
} catch (error) {
notify.error(error.message, AnalyticsErrorEventSource.FILE_BROWSER_ENTRY);
}
store.dispatch('files/removeFileFromToBeDeleted', props.file);
obStore.removeFileFromToBeDeleted(props.file);
deleteConfirmation.value = false;
}
@ -499,7 +467,7 @@ async function finalDelete(): Promise<void> {
* Abort the deletion of the current file/folder.
*/
function cancelDeletion(): void {
store.dispatch('files/closeDropdown');
obStore.closeDropdown();
deleteConfirmation.value = false;
}
</script>

View File

@ -34,11 +34,11 @@
import { computed } from 'vue';
import { Bucket } from '@/types/buckets';
import { useStore } from '@/utils/hooks';
import { ManageProjectPassphraseStep } from '@/types/managePassphrase';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { useAppStore } from '@/store/modules/appStore';
import { useBucketsStore } from '@/store/modules/bucketsStore';
import { useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import LockedIcon from '@/../static/images/browser/locked.svg';
import CloseIcon from '@/../static/images/browser/close.svg';
@ -51,7 +51,7 @@ const props = withDefaults(defineProps<{
const appStore = useAppStore();
const bucketsStore = useBucketsStore();
const store = useStore();
const obStore = useObjectBrowserStore();
const NUMBER_OF_DISPLAYED_OBJECTS = 1000;
@ -59,7 +59,7 @@ const NUMBER_OF_DISPLAYED_OBJECTS = 1000;
* Returns locked files number.
*/
const lockedFilesNumber = computed((): number => {
const ownObjectsCount = store.state.files.objectsCount;
const ownObjectsCount = obStore.state.objectsCount;
return objectsCount.value - ownObjectsCount;
});
@ -68,7 +68,7 @@ const lockedFilesNumber = computed((): number => {
* Returns bucket objects count from store.
*/
const objectsCount = computed((): number => {
const name: string = store.state.files.bucket;
const name: string = obStore.state.bucket;
const data: Bucket | undefined = bucketsStore.state.page.buckets.find((bucket: Bucket) => bucket.name === name);
return data?.objectCount || 0;

View File

@ -69,7 +69,7 @@ import { computed, reactive, ref } from 'vue';
import { RouteConfig } from '@/router';
import { AnalyticsHttpApi } from '@/api/analytics';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import { useRouter, useStore } from '@/utils/hooks';
import { useRouter } from '@/utils/hooks';
import { useBillingStore } from '@/store/modules/billingStore';
import VInput from '@/components/common/VInput.vue';
@ -79,7 +79,6 @@ import VButton from '@/components/common/VButton.vue';
import CheckIcon from '@/../static/images/common/validCheck.svg';
const billingStore = useBillingStore();
const store = useStore();
const nativeRouter = useRouter();
const router = reactive(nativeRouter);

View File

@ -33,7 +33,7 @@ import { ref } from 'vue';
import { AnalyticsHttpApi } from '@/api/analytics';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import { useNotify, useStore } from '@/utils/hooks';
import { useNotify } from '@/utils/hooks';
import { useLoading } from '@/composables/useLoading';
import { useBillingStore } from '@/store/modules/billingStore';
@ -42,7 +42,6 @@ import ValidationMessage from '@/components/common/ValidationMessage.vue';
import VButton from '@/components/common/VButton.vue';
const billingStore = useBillingStore();
const store = useStore();
const notify = useNotify();
const { isLoading, withLoading } = useLoading();

View File

@ -49,11 +49,11 @@
</template>
<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue';
import { AuthHttpApi } from '@/api/auth';
import { RouteConfig } from '@/router';
import { useNotify, useRoute } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import VButton from '@/components/common/VButton.vue';
@ -68,7 +68,8 @@ const props = withDefaults(defineProps<{
showManualActivationMsg: true,
});
const route = useRoute();
const nativeRouter = useRouter();
const router = reactive(nativeRouter);
const notify = useNotify();
const auth: AuthHttpApi = new AuthHttpApi();
@ -78,14 +79,7 @@ const secondsToWait = ref<number>(30);
const intervalId = ref<ReturnType<typeof setInterval>>();
const userEmail = computed((): string => {
return props.email || route.query.email.toString();
});
/**
* Checks if page is inside iframe.
*/
const isInsideIframe = computed((): boolean => {
return window.self !== window.top;
return props.email || router.currentRoute.query.email.toString();
});
/**

View File

@ -46,7 +46,7 @@ import { ref } from 'vue';
import { DisableMFARequest } from '@/types/users';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { useNotify, useStore } from '@/utils/hooks';
import { useNotify } from '@/utils/hooks';
import { useUsersStore } from '@/store/modules/usersStore';
import { useAppStore } from '@/store/modules/appStore';
@ -60,7 +60,6 @@ interface ClearInput {
const appStore = useAppStore();
const usersStore = useUsersStore();
const store = useStore();
const notify = useNotify();
const isError = ref<boolean>(false);

View File

@ -40,19 +40,19 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { BrowserFile } from '@/types/browser';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { useNotify, useStore } from '@/utils/hooks';
import { useNotify } from '@/utils/hooks';
import { useAppStore } from '@/store/modules/appStore';
import { BrowserObject, useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import VModal from '@/components/common/VModal.vue';
import VButton from '@/components/common/VButton.vue';
import VLoader from '@/components/common/VLoader.vue';
import VInput from '@/components/common/VInput.vue';
const obStore = useObjectBrowserStore();
const appStore = useAppStore();
const store = useStore();
const notify = useNotify();
const createFolderName = ref<string>('');
@ -62,8 +62,8 @@ const isLoading = ref<boolean>(false);
/**
* Retrieve all the files sorted from the store.
*/
const files = computed((): BrowserFile[] => {
return store.getters['files/sortedFiles'];
const files = computed((): BrowserObject[] => {
return obStore.sortedFiles;
});
/**
@ -123,7 +123,7 @@ async function createFolder(): Promise<void> {
isLoading.value = true;
try {
await store.dispatch('files/createFolder', createFolderName.value.trim());
await obStore.createFolder(createFolderName.value.trim());
} catch (error) {
await notify.error(error.message, AnalyticsErrorEventSource.CREATE_FOLDER_MODAL);
}

View File

@ -119,8 +119,8 @@ import prettyBytes from 'pretty-bytes';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { useNotify, useStore } from '@/utils/hooks';
import { BrowserObject } from '@/store/modules/files';
import { useNotify } from '@/utils/hooks';
import { BrowserObject, useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import { useAppStore } from '@/store/modules/appStore';
import VModal from '@/components/common/VModal.vue';
@ -130,7 +130,7 @@ import VLoader from '@/components/common/VLoader.vue';
import PlaceholderImage from '@/../static/images/browser/placeholder.svg';
const appStore = useAppStore();
const store = useStore();
const obStore = useObjectBrowserStore();
const notify = useNotify();
const isLoading = ref<boolean>(false);
@ -144,7 +144,7 @@ const copyText = ref<string>('Copy Link');
* Retrieve the file object that the modal is set to from the store.
*/
const file = computed((): BrowserObject | undefined => {
return store.state.files.files.find(
return obStore.state.files.find(
(file) => file.Key === filePath.value.split('/').slice(-1)[0],
);
});
@ -153,7 +153,7 @@ const file = computed((): BrowserObject | undefined => {
* Retrieve the filepath of the modal from the store.
*/
const filePath = computed((): string => {
return store.state.files.objectPathForModal;
return obStore.state.objectPathForModal;
});
/**
@ -161,7 +161,7 @@ const filePath = computed((): string => {
*/
const size = computed((): string => {
return prettyBytes(
store.state.files.files.find((f) => f.Key === file.value?.Key)?.Size || 0,
obStore.state.files.find((f) => f.Key === file.value?.Key)?.Size || 0,
);
});
@ -233,7 +233,7 @@ const placeHolderDisplayable = computed((): boolean => {
async function fetchPreviewAndMapUrl(): Promise<void> {
isLoading.value = true;
const url: string = await store.state.files.fetchPreviewAndMapUrl(
const url: string = await obStore.state.fetchPreviewAndMapUrl(
filePath.value,
);
@ -263,7 +263,7 @@ async function fetchPreviewAndMapUrl(): Promise<void> {
*/
function download(): void {
try {
store.dispatch('files/download', file.value);
obStore.download(file.value);
notify.warning('Do not share download link with other people. If you want to share this data better use "Share" option.');
} catch (error) {
notify.error('Can not download your file', AnalyticsErrorEventSource.OBJECT_DETAILS_MODAL);
@ -294,7 +294,7 @@ async function copy(): Promise<void> {
* Get the share link of the current opened file.
*/
async function getSharedLink(): Promise<void> {
objectLink.value = await store.state.files.fetchSharedLink(
objectLink.value = await obStore.state.fetchSharedLink(
filePath.value,
);
}

View File

@ -43,8 +43,9 @@
import { computed, onMounted, ref } from 'vue';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { useNotify, useStore } from '@/utils/hooks';
import { useNotify } from '@/utils/hooks';
import { useAppStore } from '@/store/modules/appStore';
import { useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import VModal from '@/components/common/VModal.vue';
import VButton from '@/components/common/VButton.vue';
@ -59,7 +60,7 @@ enum ButtonStates {
}
const appStore = useAppStore();
const store = useStore();
const obStore = useObjectBrowserStore();
const notify = useNotify();
const isLoading = ref<boolean>(true);
@ -70,7 +71,7 @@ const copyButtonState = ref<ButtonStates>(ButtonStates.Copy);
* Retrieve the path to the current file that has the fileShareModal opened from the store.
*/
const filePath = computed((): string => {
return store.state.files.objectPathForModal;
return obStore.state.objectPathForModal;
});
/**
@ -101,7 +102,7 @@ function closeModal(): void {
* Sets share link.
*/
onMounted(async (): Promise<void> => {
link.value = await store.state.files.fetchSharedLink(
link.value = await obStore.state.fetchSharedLink(
filePath.value,
);

View File

@ -56,7 +56,7 @@ import { AuthHttpApi } from '@/api/auth';
import { AnalyticsHttpApi } from '@/api/analytics';
import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { APP_STATE_DROPDOWNS } from '@/utils/constants/appStatePopUps';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import { useABTestingStore } from '@/store/modules/abTestingStore';
import { useUsersStore } from '@/store/modules/usersStore';
import { useProjectMembersStore } from '@/store/modules/projectMembersStore';
@ -66,6 +66,7 @@ import { useAccessGrantsStore } from '@/store/modules/accessGrantsStore';
import { useBucketsStore } from '@/store/modules/bucketsStore';
import { useProjectsStore } from '@/store/modules/projectsStore';
import { useNotificationsStore } from '@/store/modules/notificationsStore';
import { useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import BillingIcon from '@/../static/images/navigation/billing.svg';
import InfoIcon from '@/../static/images/navigation/info.svg';
@ -77,14 +78,14 @@ import LogoutIcon from '@/../static/images/navigation/logout.svg';
import TierBadgeFree from '@/../static/images/navigation/tierBadgeFree.svg';
import TierBadgePro from '@/../static/images/navigation/tierBadgePro.svg';
const router = useRouter();
const notify = useNotify();
const obStore = useObjectBrowserStore();
const projectsStore = useProjectsStore();
const bucketsStore = useBucketsStore();
const appStore = useAppStore();
const agStore = useAccessGrantsStore();
const store = useStore();
const router = useRouter();
const notify = useNotify();
const billingStore = useBillingStore();
const usersStore = useUsersStore();
const abTestingStore = useABTestingStore();
@ -165,7 +166,7 @@ async function onLogout(): Promise<void> {
appStore.clear(),
billingStore.clear(),
abTestingStore.reset(),
store.dispatch('files/clear'),
obStore.clear(),
]);
try {

View File

@ -170,7 +170,7 @@ import { User } from '@/types/users';
import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { LocalData } from '@/utils/localData';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import { useABTestingStore } from '@/store/modules/abTestingStore';
import { useUsersStore } from '@/store/modules/usersStore';
import { useProjectMembersStore } from '@/store/modules/projectMembersStore';
@ -180,6 +180,7 @@ import { useAccessGrantsStore } from '@/store/modules/accessGrantsStore';
import { useBucketsStore } from '@/store/modules/bucketsStore';
import { useProjectsStore } from '@/store/modules/projectsStore';
import { useNotificationsStore } from '@/store/modules/notificationsStore';
import { useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import ResourcesLinks from '@/components/navigation/ResourcesLinks.vue';
import QuickStartLinks from '@/components/navigation/QuickStartLinks.vue';
@ -226,7 +227,8 @@ const usersStore = useUsersStore();
const abTestingStore = useABTestingStore();
const notificationsStore = useNotificationsStore();
const projectsStore = useProjectsStore();
const store = useStore();
const obStore = useObjectBrowserStore();
const router = useRouter();
const notify = useNotify();
@ -477,7 +479,7 @@ async function onLogout(): Promise<void> {
appStore.clear(),
billingStore.clear(),
abTestingStore.reset(),
store.dispatch('files/clear'),
obStore.clear(),
]);
try {

View File

@ -30,17 +30,18 @@
import { computed, reactive, ref } from 'vue';
import { RouteConfig } from '@/router';
import { useRouter, useStore } from '@/utils/hooks';
import { useRouter } from '@/utils/hooks';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { useAppStore } from '@/store/modules/appStore';
import { useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import ArrowDownIcon from '@/../static/images/common/dropIcon.svg';
import DetailsIcon from '@/../static/images/objects/details.svg';
import ShareIcon from '@/../static/images/objects/share.svg';
import GearIcon from '@/../static/images/common/gearIcon.svg';
const obStore = useObjectBrowserStore();
const appStore = useAppStore();
const store = useStore();
const nativeRouter = useRouter();
const router = reactive(nativeRouter);
@ -55,7 +56,7 @@ const isHoveredOver = ref(false);
* Returns files amount from store.
*/
const filesCount = computed((): number => {
return store.getters['files/sortedFiles'].length;
return obStore.sortedFiles.length;
});
function closeDropdown(): void {

View File

@ -72,7 +72,7 @@ import { computed, onBeforeUnmount, ref } from 'vue';
import { BucketPage } from '@/types/buckets';
import { RouteConfig } from '@/router';
import { AnalyticsHttpApi } from '@/api/analytics';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { EdgeCredentials } from '@/types/accessGrants';

View File

@ -19,20 +19,21 @@ import { AccessGrant, EdgeCredentials } from '@/types/accessGrants';
import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { BucketPage } from '@/types/buckets';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import { useAppStore } from '@/store/modules/appStore';
import { useAccessGrantsStore } from '@/store/modules/accessGrantsStore';
import { useBucketsStore } from '@/store/modules/bucketsStore';
import { useProjectsStore } from '@/store/modules/projectsStore';
import { useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import FileBrowser from '@/components/browser/FileBrowser.vue';
import UploadCancelPopup from '@/components/objects/UploadCancelPopup.vue';
const obStore = useObjectBrowserStore();
const bucketsStore = useBucketsStore();
const appStore = useAppStore();
const agStore = useAccessGrantsStore();
const projectsStore = useProjectsStore();
const store = useStore();
const router = useRouter();
const notify = useNotify();
@ -215,7 +216,7 @@ async function generateCredentials(cleanApiKey: string, path: string, areEndless
onBeforeMount(() => {
setWorker();
store.commit('files/init', {
obStore.init({
endpoint: edgeCredentials.value.endpoint,
accessKey: edgeCredentials.value.accessKeyId,
secretKey: edgeCredentials.value.secretKey,
@ -241,17 +242,18 @@ watch(passphrase, async () => {
return;
}
await router.push(RouteConfig.Buckets.with(RouteConfig.UploadFile).path).catch(() => {return;});
store.commit('files/reinit', {
router.push(RouteConfig.Buckets.with(RouteConfig.UploadFile).path).catch(() => {return;});
obStore.reinit({
endpoint: edgeCredentials.value.endpoint,
accessKey: edgeCredentials.value.accessKeyId,
secretKey: edgeCredentials.value.secretKey,
});
try {
await Promise.all([
bucketsStore.getBuckets(bucketPage.value.currentPage, projectID),
store.dispatch('files/list', ''),
store.dispatch('files/getObjectCount'),
obStore.list(''),
obStore.getObjectCount(),
]);
} catch (error) {
await notify.error(error.message, AnalyticsErrorEventSource.UPLOAD_FILE_VIEW);

View File

@ -45,7 +45,6 @@
import { computed, ref } from 'vue';
import { APP_STATE_DROPDOWNS } from '@/utils/constants/appStatePopUps';
import { useStore } from '@/utils/hooks';
import { useAppStore } from '@/store/modules/appStore';
import { useAccessGrantsStore } from '@/store/modules/accessGrantsStore';
@ -53,7 +52,6 @@ import ExpandIcon from '@/../static/images/common/BlackArrowExpand.svg';
const appStore = useAppStore();
const agStore = useAccessGrantsStore();
const store = useStore();
const isLoading = ref<boolean>(true);

View File

@ -33,7 +33,7 @@
import { RouteConfig } from '@/router';
import { AnalyticsHttpApi } from '@/api/analytics';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import { useUsersStore } from '@/store/modules/usersStore';
import VButton from '@/components/common/VButton.vue';
@ -41,7 +41,6 @@ import VButton from '@/components/common/VButton.vue';
import Icon from '@/../static/images/onboardingTour/successStep.svg';
const usersStore = useUsersStore();
const store = useStore();
const notify = useNotify();
const router = useRouter();

View File

@ -7,7 +7,6 @@ import { createPinia, setActivePinia, PiniaVuePlugin } from 'pinia';
import App from './App.vue';
import { router } from './router';
import { store } from './store';
import { Size } from '@/utils/bytesSize';
import { NotificatorPlugin } from '@/utils/plugins/notificator';
@ -95,7 +94,6 @@ Vue.filter('leadingZero', (value: number): string => {
new Vue({
router,
store,
pinia,
render: (h) => h(App),
}).$mount('#app');

View File

@ -1,22 +0,0 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
import Vue from 'vue';
import Vuex from 'vuex';
import { FilesState, makeFilesModule } from '@/store/modules/files';
Vue.use(Vuex);
export interface ModulesState {
files: FilesState;
}
// Satellite store (vuex)
export const store = new Vuex.Store<ModulesState>({
modules: {
files: makeFilesModule(),
},
});
export default store;

View File

@ -1,781 +0,0 @@
// Copyright (C) 2021 Storj Labs, Inc.
// See LICENSE for copying information.
import S3, { CommonPrefix } from 'aws-sdk/clients/s3';
import { StoreModule } from '@/types/store';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { useAppStore } from '@/store/modules/appStore';
const listCache = new Map();
type Promisable<T> = T | PromiseLike<T>;
export type BrowserObject = {
Key: string;
Size: number;
LastModified: number;
type?: 'file' | 'folder';
progress?: number;
upload?: {
abort: () => void;
};
path?: string;
};
export type FilesState = {
s3: S3 | null;
accessKey: null | string;
path: string;
bucket: string;
browserRoot: string;
files: BrowserObject[];
uploadChain: Promise<void>;
uploading: BrowserObject[];
selectedAnchorFile: BrowserObject | null;
unselectedAnchorFile: null | string;
selectedFiles: BrowserObject[];
shiftSelectedFiles: BrowserObject[];
filesToBeDeleted: BrowserObject[];
fetchSharedLink: (arg0: string) => Promisable<string>;
fetchPreviewAndMapUrl: (arg0: string) => Promisable<string>;
openedDropdown: null | string;
headingSorted: string;
orderBy: 'asc' | 'desc';
openModalOnFirstUpload: boolean;
objectPathForModal: string;
objectsCount: number;
};
type InitializedFilesState = FilesState & {
s3: S3;
};
function assertIsInitialized(
state: FilesState,
): asserts state is InitializedFilesState {
if (state.s3 === null) {
throw new Error(
'FilesModule: S3 Client is uninitialized. "state.s3" is null.',
);
}
}
interface FilesContext {
state: FilesState;
commit: (string, ...unknown) => void;
dispatch: (string, ...unknown) => Promise<any>; // eslint-disable-line @typescript-eslint/no-explicit-any
rootState: {
files: FilesState;
};
}
declare global {
interface FileSystemEntry {
// https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileEntry/file
file: (
successCallback: (arg0: File) => void,
errorCallback?: (arg0: Error) => void
) => void;
createReader: () => FileSystemDirectoryReader;
}
}
type FilesModule = StoreModule<FilesState, FilesContext> & { namespaced: true };
export const makeFilesModule = (): FilesModule => ({
namespaced: true,
state: {
s3: null,
accessKey: null,
path: '',
bucket: '',
browserRoot: '/',
files: [],
uploadChain: Promise.resolve(),
uploading: [],
selectedAnchorFile: null,
unselectedAnchorFile: null,
selectedFiles: [],
shiftSelectedFiles: [],
filesToBeDeleted: [],
fetchSharedLink: () => 'javascript:null',
fetchPreviewAndMapUrl: () => 'javascript:null',
openedDropdown: null,
headingSorted: 'name',
orderBy: 'asc',
openModalOnFirstUpload: false,
objectPathForModal: '',
objectsCount: 0,
},
getters: {
sortedFiles: (state: FilesState) => {
// key-specific sort cases
const fns = {
date: (a: BrowserObject, b: BrowserObject): number =>
new Date(a.LastModified).getTime() - new Date(b.LastModified).getTime(),
name: (a: BrowserObject, b: BrowserObject): number =>
a.Key.localeCompare(b.Key),
size: (a: BrowserObject, b: BrowserObject): number => a.Size - b.Size,
};
// TODO(performance): avoid several passes over the slice.
// sort by appropriate function
const sortedFiles = state.files.slice();
sortedFiles.sort(fns[state.headingSorted]);
// reverse if descending order
if (state.orderBy !== 'asc') {
sortedFiles.reverse();
}
// display folders and then files
const groupedFiles = [
...sortedFiles.filter((file) => file.type === 'folder'),
...sortedFiles.filter((file) => file.type === 'file'),
];
return groupedFiles;
},
isInitialized: (state: FilesState): boolean => state.s3 !== null,
uploadingLength: (state: FilesState): number => state.uploading.length,
},
mutations: {
init(
state: FilesState,
{
accessKey,
secretKey,
bucket,
endpoint,
browserRoot,
openModalOnFirstUpload = true,
fetchSharedLink = () => 'javascript:null',
fetchPreviewAndMapUrl = () => 'javascript:null',
}: {
accessKey: string;
secretKey: string;
bucket: string;
endpoint: string;
browserRoot: string;
openModalOnFirstUpload: boolean;
fetchSharedLink: (arg0: string) => Promisable<string>;
fetchPreviewAndMapUrl: (arg0: string) => Promisable<string>;
},
) {
const s3Config = {
accessKeyId: accessKey,
secretAccessKey: secretKey,
endpoint,
s3ForcePathStyle: true,
signatureVersion: 'v4',
connectTimeout: 0,
httpOptions: { timeout: 0 },
};
state.s3 = new S3(s3Config);
state.accessKey = accessKey;
state.bucket = bucket;
state.browserRoot = browserRoot;
state.openModalOnFirstUpload = openModalOnFirstUpload;
state.fetchSharedLink = fetchSharedLink;
state.fetchPreviewAndMapUrl = fetchPreviewAndMapUrl;
state.path = '';
state.files = [];
},
reinit(state: FilesState, {
accessKey,
secretKey,
endpoint,
}: {
accessKey: string;
secretKey: string;
endpoint: string;
}) {
const s3Config = {
accessKeyId: accessKey,
secretAccessKey: secretKey,
endpoint,
s3ForcePathStyle: true,
signatureVersion: 'v4',
connectTimeout: 0,
httpOptions: { timeout: 0 },
};
state.files = [];
state.s3 = new S3(s3Config);
state.accessKey = accessKey;
},
updateFiles(state: FilesState, { path, files }) {
state.path = path;
state.files = files;
},
setSelectedFiles(state: FilesState, files) {
state.selectedFiles = files;
},
setSelectedAnchorFile(state: FilesState, file) {
state.selectedAnchorFile = file;
},
setUnselectedAnchorFile(state: FilesState, file) {
state.unselectedAnchorFile = file;
},
setFilesToBeDeleted(state: FilesState, files) {
state.filesToBeDeleted = [...state.filesToBeDeleted, ...files];
},
removeFileToBeDeleted(state: FilesState, file) {
state.filesToBeDeleted = state.filesToBeDeleted.filter(
(singleFile) => singleFile.Key !== file.Key,
);
},
removeAllFilesToBeDeleted(state: FilesState) {
state.filesToBeDeleted = [];
},
removeAllSelectedFiles(state: FilesState) {
state.selectedAnchorFile = null;
state.unselectedAnchorFile = null;
state.shiftSelectedFiles = [];
state.selectedFiles = [];
},
setShiftSelectedFiles(state: FilesState, files) {
state.shiftSelectedFiles = files;
},
pushUpload(state: FilesState, file) {
state.uploading.push(file);
},
setProgress(state: FilesState, { Key, progress }) {
const file = state.uploading.find((file) => file.Key === Key);
if (file === undefined) {
throw new Error(`No file found with key ${JSON.stringify(Key)}`);
}
file.progress = progress;
},
finishUpload(state: FilesState, Key) {
state.uploading = state.uploading.filter((file) => file.Key !== Key);
},
setOpenedDropdown(state: FilesState, id) {
state.openedDropdown = id;
},
sort(state: FilesState, headingSorted) {
const flip = (orderBy) => (orderBy === 'asc' ? 'desc' : 'asc');
state.orderBy = state.headingSorted === headingSorted ? flip(state.orderBy) : 'asc';
state.headingSorted = headingSorted;
},
setObjectPathForModal(state: FilesState, path) {
state.objectPathForModal = path;
},
setObjectsCount(state: FilesState, count: number) {
state.objectsCount = count;
},
addUploadToChain(state: FilesState, fn) {
state.uploadChain = state.uploadChain.then(fn);
},
clear(state: FilesState) {
state.s3 = null;
state.accessKey = null;
state.path = '';
state.bucket = '';
state.browserRoot = '/';
state.files = [];
state.uploadChain = Promise.resolve();
state.uploading = [];
state.selectedAnchorFile = null;
state.unselectedAnchorFile = null;
state.selectedFiles = [];
state.shiftSelectedFiles = [];
state.filesToBeDeleted = [];
state.fetchSharedLink = () => 'javascript:null';
state.fetchPreviewAndMapUrl = () => 'javascript:null';
state.openedDropdown = null;
state.headingSorted = 'name';
state.orderBy = 'asc';
state.openModalOnFirstUpload = false;
state.objectPathForModal = '';
},
},
actions: {
async list({ commit, state, dispatch }, path = state.path) {
if (listCache.has(path)) {
commit('updateFiles', {
path,
files: listCache.get(path),
});
}
assertIsInitialized(state);
const response = await state.s3
.listObjects({
Bucket: state.bucket,
Delimiter: '/',
Prefix: path,
})
.promise();
const { Contents, CommonPrefixes } = response;
if (Contents === undefined) {
throw new Error('Bad S3 listObjects() response: "Contents" undefined');
}
if (CommonPrefixes === undefined) {
throw new Error(
'Bad S3 listObjects() response: "CommonPrefixes" undefined',
);
}
Contents.sort((a, b) => {
if (
a === undefined ||
a.LastModified === undefined ||
b === undefined ||
b.LastModified === undefined ||
a.LastModified === b.LastModified
) {
return 0;
}
return a.LastModified < b.LastModified ? -1 : 1;
});
type DefinedCommonPrefix = CommonPrefix & {
Prefix: string;
};
const isPrefixDefined = (
value: CommonPrefix,
): value is DefinedCommonPrefix => value.Prefix !== undefined;
const prefixToFolder = ({
Prefix,
}: {
Prefix: string;
}): BrowserObject => ({
Key: Prefix.slice(path.length, -1),
LastModified: 0,
Size: 0,
type: 'folder',
});
const makeFileRelative = (file) => ({
...file,
Key: file.Key.slice(path.length),
type: 'file',
});
const isFileVisible = (file) =>
file.Key.length > 0 && file.Key !== '.file_placeholder';
const files = [
...CommonPrefixes.filter(isPrefixDefined).map(prefixToFolder),
...Contents.map(makeFileRelative).filter(isFileVisible),
];
listCache.set(path, files);
commit('updateFiles', {
path,
files,
});
},
async back({ state, dispatch }) {
const getParentDirectory = (path) => {
let i = path.length - 2;
while (path[i - 1] !== '/' && i > 0) {
i--;
}
return path.slice(0, i);
};
dispatch('list', getParentDirectory(state.path));
},
async getObjectCount({ commit, state }) {
assertIsInitialized(state);
const responseV2 = await state.s3
.listObjectsV2({
Bucket: state.bucket,
})
.promise();
commit('setObjectsCount', responseV2.KeyCount === undefined ? 0 : responseV2.KeyCount);
},
async upload({ commit, state, dispatch }, { e }: { e: DragEvent }) {
assertIsInitialized(state);
type Item = DataTransferItem | FileSystemEntry;
const items: Item[] = e.dataTransfer
? [...e.dataTransfer.items]
: e.target !== null
? ((e.target as unknown) as { files: FileSystemEntry[] }).files
: [];
async function* traverse(item: Item | Item[], path = '') {
if ('isFile' in item && item.isFile === true) {
const file = await new Promise(item.file.bind(item));
yield { path, file };
} else if (item instanceof File) {
let relativePath = '';
// on Firefox mobile, item.webkitRelativePath might be `undefined`
if (item.webkitRelativePath) {
relativePath = item.webkitRelativePath
.split('/')
.slice(0, -1)
.join('/');
}
if (relativePath.length) {
relativePath += '/';
}
yield { path: relativePath, file: item };
} else if ('isFile' in item && item.isDirectory) {
const dirReader = item.createReader();
const entries = await new Promise(
dirReader.readEntries.bind(dirReader),
);
for (const entry of entries) {
yield* traverse(
(entry as FileSystemEntry) as Item,
path + item.name + '/',
);
}
} else if ('length' in item && typeof item.length === 'number') {
for (const i of item) {
yield* traverse(i);
}
} else {
throw new Error('Item is not directory or file');
}
}
const isFileSystemEntry = (
a: FileSystemEntry | null,
): a is FileSystemEntry => a !== null;
const iterator = [...items]
.map((item) =>
'webkitGetAsEntry' in item ? item.webkitGetAsEntry() : item,
)
.filter(isFileSystemEntry) as FileSystemEntry[];
const fileNames = state.files.map((file) => file.Key);
function getUniqueFileName(fileName) {
for (let count = 1; fileNames.includes(fileName); count++) {
if (count > 1) {
fileName = fileName.replace(/\((\d+)\)(.*)/, `(${count})$2`);
} else {
fileName = fileName.replace(/([^.]*)(.*)/, `$1 (${count})$2`);
}
}
return fileName;
}
for await (const { path, file } of traverse(iterator)) {
const directories = path.split('/');
directories[0] = getUniqueFileName(directories[0]);
const fileName = getUniqueFileName(directories.join('/') + file.name);
const params = {
Bucket: state.bucket,
Key: state.path + fileName,
Body: file,
};
// If file size exceeds 1 GB, show warning notification
if (file.size > (1024 * 1024 * 1024)) {
const appStore = useAppStore();
appStore.setLargeUploadWarningNotification(true);
}
const upload = state.s3.upload(
{ ...params },
{ partSize: 64 * 1024 * 1024 },
);
upload.on('httpUploadProgress', async (progress) => {
commit('setProgress', {
Key: params.Key,
progress: Math.round((progress.loaded / progress.total) * 100),
});
});
commit('pushUpload', {
...params,
upload,
progress: 0,
});
commit('addUploadToChain', async () => {
if (
state.uploading.findIndex((file) => file.Key === params.Key) === -1
) {
// upload cancelled or removed
return -1;
}
try {
await upload.promise();
} catch (error) {
const limitExceededError = 'storage limit exceeded';
if (error.message.includes(limitExceededError)) {
dispatch('error', { message: `Error: ${limitExceededError}`, source: AnalyticsErrorEventSource.OBJECT_UPLOAD_ERROR }, { root: true });
} else {
dispatch('error', { message: error.message, source: AnalyticsErrorEventSource.OBJECT_UPLOAD_ERROR }, { root: true });
}
}
await dispatch('list');
const uploadedFiles = state.files.filter(
(file) => file.type === 'file',
);
if (uploadedFiles.length === 1 && !path && state.openModalOnFirstUpload) {
commit('setObjectPathForModal', params.Key);
const appStore = useAppStore();
appStore.updateActiveModal(MODALS.objectDetails);
}
commit('finishUpload', params.Key);
});
}
},
async createFolder({ state, dispatch }, name) {
assertIsInitialized(state);
await state.s3
.putObject({
Bucket: state.bucket,
Key: state.path + name + '/.file_placeholder',
})
.promise();
dispatch('list');
},
async delete(
{ commit, dispatch, state }: FilesContext,
{ path, file, folder },
) {
assertIsInitialized(state);
await state.s3
.deleteObject({
Bucket: state.bucket,
Key: path + file.Key,
})
.promise();
if (!folder) {
await dispatch('list');
commit('removeFileToBeDeleted', file);
}
},
async deleteFolder({ commit, dispatch, state }: FilesContext, { file, path }) {
assertIsInitialized(state);
async function recurse(filePath) {
assertIsInitialized(state);
const { Contents, CommonPrefixes } = await state.s3
.listObjects({
Bucket: state.bucket,
Delimiter: '/',
Prefix: filePath,
})
.promise();
if (Contents === undefined) {
throw new Error(
'Bad S3 listObjects() response: "Contents" undefined',
);
}
if (CommonPrefixes === undefined) {
throw new Error(
'Bad S3 listObjects() response: "CommonPrefixes" undefined',
);
}
async function thread() {
if (Contents === undefined) {
throw new Error(
'Bad S3 listObjects() response: "Contents" undefined',
);
}
while (Contents.length) {
const file = Contents.pop();
await dispatch('delete', {
path: '',
file,
folder: true,
});
}
}
await Promise.all([thread(), thread(), thread()]);
for (const { Prefix } of CommonPrefixes) {
await recurse(Prefix);
}
}
await recurse(path.length > 0 ? path + file.Key : file.Key + '/');
commit('removeFileToBeDeleted', file);
await dispatch('list');
},
async deleteSelected({ state, dispatch, commit }) {
const filesToDelete = [
...state.selectedFiles,
...state.shiftSelectedFiles,
];
if (state.selectedAnchorFile) {
filesToDelete.push(state.selectedAnchorFile);
}
commit('setFilesToBeDeleted', filesToDelete);
await Promise.all(
filesToDelete.map(async (file) => {
if (file.type === 'file')
await dispatch('delete', {
file,
path: state.path,
});
else
await dispatch('deleteFolder', {
file,
path: state.path,
});
}),
);
dispatch('clearAllSelectedFiles');
},
async download({ state }, file) {
assertIsInitialized(state);
const url = state.s3.getSignedUrl('getObject', {
Bucket: state.bucket,
Key: state.path + file.Key,
});
const downloadURL = function(data, fileName) {
const a = document.createElement('a');
a.href = data;
a.download = fileName;
a.click();
};
downloadURL(url, file.Key);
},
updateSelectedFiles({ commit }, files) {
commit('setSelectedFiles', [...files]);
},
updateShiftSelectedFiles({ commit }, files) {
commit('setShiftSelectedFiles', files);
},
addFileToBeDeleted({ commit }, file) {
commit('setFilesToBeDeleted', [file]);
},
removeFileFromToBeDeleted({ commit }, file) {
commit('removeFileToBeDeleted', file);
},
clearAllSelectedFiles({ commit, state }) {
if (state.selectedAnchorFile || state.unselectedAnchorFile) {
commit('removeAllSelectedFiles');
}
},
openDropdown({ commit, dispatch }, id) {
dispatch('clearAllSelectedFiles');
commit('setOpenedDropdown', id);
},
closeDropdown({ commit }) {
commit('setOpenedDropdown', null);
},
openFileBrowserDropdown({ commit }) {
commit('setOpenedDropdown', 'FileBrowser');
},
cancelUpload({ commit, state }, key) {
const file = state.uploading.find((file) => file.Key === key);
if (typeof file === 'object') {
if (file.progress !== undefined && file.upload && file.progress > 0) {
file.upload.abort();
}
commit('finishUpload', key);
} else {
throw new Error(`File ${JSON.stringify(key)} not found`);
}
},
closeAllInteractions({ state, dispatch }) {
if (state.openedDropdown) {
dispatch('closeDropdown');
}
if (state.selectedAnchorFile) {
dispatch('clearAllSelectedFiles');
}
},
clear({ commit }) {
commit('clear');
},
},
});

View File

@ -36,7 +36,7 @@ export class FilesState {
uploadChain: Promise<void> = Promise.resolve();
uploading: BrowserObject[] = [];
selectedAnchorFile: BrowserObject | null = null;
unselectedAnchorFile: null | string = null;
unselectedAnchorFile: BrowserObject | null = null;
selectedFiles: BrowserObject[] = [];
shiftSelectedFiles: BrowserObject[] = [];
filesToBeDeleted: BrowserObject[] = [];
@ -75,7 +75,7 @@ declare global {
}
}
export const useFilesStore = defineStore('files', () => {
export const useObjectBrowserStore = defineStore('objectBrowser', () => {
const state = reactive<FilesState>(new FilesState());
const sortedFiles = computed(() => {
@ -128,7 +128,7 @@ export const useFilesStore = defineStore('files', () => {
bucket: string;
endpoint: string;
browserRoot: string;
openModalOnFirstUpload: boolean;
openModalOnFirstUpload?: boolean;
fetchSharedLink: (arg0: string) => Promisable<string>;
fetchPreviewAndMapUrl: (arg0: string) => Promisable<string>;
}): void {
@ -182,7 +182,7 @@ export const useFilesStore = defineStore('files', () => {
state.files = files;
}
async function list(path = state.path) {
async function list(path = state.path): Promise<void> {
if (listCache.has(path)) {
updateFiles(path, listCache.get(path));
}
@ -274,7 +274,7 @@ export const useFilesStore = defineStore('files', () => {
list(getParentDirectory(state.path));
}
async function getObjectCount() {
async function getObjectCount(): Promise<void> {
assertIsInitialized(state);
const responseV2 = await state.s3
@ -286,12 +286,12 @@ export const useFilesStore = defineStore('files', () => {
state.objectsCount = responseV2.KeyCount === undefined ? 0 : responseV2.KeyCount;
}
async function upload({ e }: { e: DragEvent }) {
async function upload({ e }: { e: DragEvent | Event }): Promise<void> {
assertIsInitialized(state);
type Item = DataTransferItem | FileSystemEntry;
const items: Item[] = e.dataTransfer
const items: Item[] = 'dataTransfer' in e && e.dataTransfer
? [...e.dataTransfer.items]
: e.target !== null
? ((e.target as unknown) as { files: FileSystemEntry[] }).files
@ -362,6 +362,8 @@ export const useFilesStore = defineStore('files', () => {
return fileName;
}
const appStore = useAppStore();
for await (const { path, file } of traverse(iterator)) {
const directories = path.split('/');
directories[0] = getUniqueFileName(directories[0]);
@ -374,6 +376,11 @@ export const useFilesStore = defineStore('files', () => {
Body: file,
};
// If file size exceeds 1 GB, show warning notification
if (file.size > (1024 * 1024 * 1024)) {
appStore.setLargeUploadWarningNotification(true);
}
const upload = state.s3.upload(
{ ...params },
{ partSize: 64 * 1024 * 1024 },
@ -425,7 +432,6 @@ export const useFilesStore = defineStore('files', () => {
if (uploadedFiles.length === 1 && !path && state.openModalOnFirstUpload) {
state.objectPathForModal = params.Key;
const appStore = useAppStore();
appStore.updateActiveModal(MODALS.objectDetails);
}
@ -434,7 +440,7 @@ export const useFilesStore = defineStore('files', () => {
}
}
async function createFolder(name) {
async function createFolder(name): Promise<void> {
assertIsInitialized(state);
await state.s3
@ -447,7 +453,7 @@ export const useFilesStore = defineStore('files', () => {
list();
}
async function deleteObject(path: string, file?: S3.Object | BrowserObject, isFolder = false) {
async function deleteObject(path: string, file?: S3.Object | BrowserObject, isFolder = false): Promise<void> {
if (!file) {
return;
}
@ -467,7 +473,7 @@ export const useFilesStore = defineStore('files', () => {
}
}
async function deleteFolder(file: BrowserObject, path: string) {
async function deleteFolder(file: BrowserObject, path: string): Promise<void> {
assertIsInitialized(state);
async function recurse(filePath) {
@ -520,7 +526,7 @@ export const useFilesStore = defineStore('files', () => {
await list();
}
async function deleteSelected() {
async function deleteSelected(): Promise<void> {
const filesToDelete = [
...state.selectedFiles,
...state.shiftSelectedFiles,
@ -545,7 +551,7 @@ export const useFilesStore = defineStore('files', () => {
clearAllSelectedFiles();
}
async function download(file) {
function download(file): void {
assertIsInitialized(state);
const url = state.s3.getSignedUrl('getObject', {
@ -562,25 +568,25 @@ export const useFilesStore = defineStore('files', () => {
downloadURL(url, file.Key);
}
function updateSelectedFiles(files) {
function updateSelectedFiles(files): void {
state.selectedFiles = [...files];
}
function updateShiftSelectedFiles(files) {
function updateShiftSelectedFiles(files): void {
state.shiftSelectedFiles = files;
}
function addFileToBeDeleted(file) {
function addFileToBeDeleted(file): void {
state.filesToBeDeleted = [...state.filesToBeDeleted, file];
}
function removeFileFromToBeDeleted(file) {
function removeFileFromToBeDeleted(file): void {
state.filesToBeDeleted = state.filesToBeDeleted.filter(
(singleFile) => singleFile.Key !== file.Key,
);
}
function clearAllSelectedFiles() {
function clearAllSelectedFiles(): void {
if (state.selectedAnchorFile || state.unselectedAnchorFile) {
state.selectedAnchorFile = null;
state.unselectedAnchorFile = null;
@ -589,20 +595,20 @@ export const useFilesStore = defineStore('files', () => {
}
}
function openDropdown(id) {
function openDropdown(id): void {
clearAllSelectedFiles();
state.openedDropdown = id;
}
function closeDropdown() {
function closeDropdown(): void {
state.openedDropdown = null;
}
function openFileBrowserDropdown() {
function openFileBrowserDropdown(): void {
state.openedDropdown = 'FileBrowser';
}
function cancelUpload(key) {
function cancelUpload(key): void {
const file = state.uploading.find((file) => file.Key === key);
if (typeof file === 'object') {
@ -616,7 +622,26 @@ export const useFilesStore = defineStore('files', () => {
}
}
function closeAllInteractions() {
function sort(headingSorted: string): void {
const flip = (orderBy) => (orderBy === 'asc' ? 'desc' : 'asc');
state.orderBy = state.headingSorted === headingSorted ? flip(state.orderBy) : 'asc';
state.headingSorted = headingSorted;
}
function setObjectPathForModal(path: string): void {
state.objectPathForModal = path;
}
function setSelectedAnchorFile(file: BrowserObject | null): void {
state.selectedAnchorFile = file;
}
function setUnselectedAnchorFile(file: BrowserObject | null): void {
state.unselectedAnchorFile = file;
}
function closeAllInteractions(): void {
if (state.openedDropdown) {
closeDropdown();
}
@ -626,7 +651,7 @@ export const useFilesStore = defineStore('files', () => {
}
}
function clear() {
function clear(): void {
state.s3 = null;
state.accessKey = null;
state.path = '';
@ -650,6 +675,36 @@ export const useFilesStore = defineStore('files', () => {
}
return {
filesState: state,
state,
sortedFiles,
isInitialized,
uploadingLength,
init,
reinit,
updateFiles,
list,
back,
sort,
getObjectCount,
upload,
createFolder,
deleteObject,
deleteFolder,
deleteSelected,
download,
updateSelectedFiles,
updateShiftSelectedFiles,
addFileToBeDeleted,
removeFileFromToBeDeleted,
clearAllSelectedFiles,
setObjectPathForModal,
openDropdown,
closeDropdown,
openFileBrowserDropdown,
setSelectedAnchorFile,
setUnselectedAnchorFile,
cancelUpload,
closeAllInteractions,
clear,
};
});

View File

@ -1,21 +0,0 @@
// Copyright (C) 2022 Storj Labs, Inc.
// See LICENSE for copying information.
type Mutation<State> =
(state: State, ...args: any[]) => any; // eslint-disable-line @typescript-eslint/no-explicit-any
type Action<Context> =
(context: Context, ...args: any[]) => (Promise<any> | void | any); // eslint-disable-line @typescript-eslint/no-explicit-any
type Getter<State, Context> =
Context extends {rootGetters: any} ? ( // eslint-disable-line @typescript-eslint/no-explicit-any
((state: State) => any) | // eslint-disable-line @typescript-eslint/no-explicit-any
((state: State, rootGetters: Context['rootGetters']) => any) // eslint-disable-line @typescript-eslint/no-explicit-any
) : ((state: State) => any); // eslint-disable-line @typescript-eslint/no-explicit-any
export interface StoreModule<State, Context> { // eslint-disable-line @typescript-eslint/no-unused-vars
state: State;
mutations: Record<string, Mutation<State>>
actions: Record<string, Action<Context>>
getters?: Record<string, Getter<State, Context>>
}

View File

@ -2,24 +2,15 @@
// See LICENSE for copying information.
import { getCurrentInstance } from 'vue';
import VueRouter, { Route } from 'vue-router';
import VueRouter from 'vue-router';
import { store } from '@/store';
import { Notificator } from '@/utils/plugins/notificator';
// TODO: remove after updating router and store deps.
export function useRoute() {
return getCurrentInstance()?.proxy.$route || {} as Route;
}
export function useRouter() {
return getCurrentInstance()?.proxy.$router || {} as VueRouter;
}
export function useStore() {
return (getCurrentInstance()?.proxy.$store || {}) as typeof store;
}
export function useNotify() {
return getCurrentInstance()?.proxy.$notify || {} as Notificator;
}

View File

@ -139,7 +139,7 @@ import { User } from '@/types/users';
import { AuthHttpApi } from '@/api/auth';
import { AnalyticsHttpApi } from '@/api/analytics';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { useABTestingStore } from '@/store/modules/abTestingStore';
import { useUsersStore } from '@/store/modules/usersStore';
@ -150,6 +150,7 @@ import { useAccessGrantsStore } from '@/store/modules/accessGrantsStore';
import { useBucketsStore } from '@/store/modules/bucketsStore';
import { useProjectsStore } from '@/store/modules/projectsStore';
import { useNotificationsStore } from '@/store/modules/notificationsStore';
import { useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import UploadNotification from '@/components/notifications/UploadNotification.vue';
import NavigationArea from '@/components/navigation/NavigationArea.vue';
@ -177,7 +178,8 @@ const usersStore = useUsersStore();
const abTestingStore = useABTestingStore();
const projectsStore = useProjectsStore();
const notificationsStore = useNotificationsStore();
const store = useStore();
const obStore = useObjectBrowserStore();
const notify = useNotify();
const nativeRouter = useRouter();
const router = reactive(nativeRouter);
@ -493,7 +495,7 @@ function restartSessionTimers(): void {
}, sessionRefreshInterval.value);
inactivityTimerId.value = setTimeout(async () => {
if (store.getters['files/uploadingLength']) {
if (obStore.uploadingLength) {
await refreshSession();
return;
}
@ -584,7 +586,7 @@ async function handleInactive(): Promise<void> {
appStore.clear(),
billingStore.clear(),
abTestingStore.reset(),
store.dispatch('files/clear'),
obStore.clear(),
]);
resetActivityEvents.forEach((eventName: string) => {

View File

@ -161,7 +161,7 @@
<script setup lang="ts">
import VueRecaptcha from 'vue-recaptcha';
import VueHcaptcha from '@hcaptcha/vue-hcaptcha';
import { computed, onMounted, ref } from 'vue';
import { computed, onMounted, reactive, ref } from 'vue';
import { AuthHttpApi } from '@/api/auth';
import { ErrorMFARequired } from '@/api/errors/ErrorMFARequired';
@ -173,7 +173,7 @@ import { ErrorBadRequest } from '@/api/errors/ErrorBadRequest';
import { AnalyticsHttpApi } from '@/api/analytics';
import { TokenInfo } from '@/types/users';
import { LocalData } from '@/utils/localData';
import { useNotify, useRoute, useRouter, useStore } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import { useUsersStore } from '@/store/modules/usersStore';
import { useAppStore } from '@/store/modules/appStore';
import { MultiCaptchaConfig, PartneredSatellite } from '@/types/config';
@ -224,9 +224,9 @@ const analytics = new AnalyticsHttpApi();
const appStore = useAppStore();
const usersStore = useUsersStore();
const router = useRouter();
const notify = useNotify();
const route = useRoute();
const nativeRouter = useRouter();
const router = reactive(nativeRouter);
/**
* Name of the current satellite.
@ -254,14 +254,14 @@ const captchaConfig = computed((): MultiCaptchaConfig => {
* Makes activated banner visible on successful account activation.
*/
onMounted(() => {
isActivatedBannerShown.value = !!route.query.activated;
isActivatedError.value = route.query.activated === 'false';
isActivatedBannerShown.value = !!router.currentRoute.query.activated;
isActivatedError.value = router.currentRoute.query.activated === 'false';
if (appStore.state.config.allProjectsDashboard) {
returnURL.value = RouteConfig.AllProjectsDashboard.path;
}
returnURL.value = route.query.return_url as string || returnURL.value;
returnURL.value = router.currentRoute.query.return_url as string || returnURL.value;
});
/**

View File

@ -121,7 +121,7 @@ import {
AnalyticsErrorEventSource,
} from '@/utils/constants/analyticsEventNames';
import { AnalyticsHttpApi } from '@/api/analytics';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import { RouteConfig } from '@/router';
import { ErrorUnauthorized } from '@/api/errors/ErrorUnauthorized';
import { FetchState } from '@/utils/constants/fetchStateEnum';
@ -138,6 +138,7 @@ import { useAccessGrantsStore } from '@/store/modules/accessGrantsStore';
import { useBucketsStore } from '@/store/modules/bucketsStore';
import { useProjectsStore } from '@/store/modules/projectsStore';
import { useNotificationsStore } from '@/store/modules/notificationsStore';
import { useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import InactivityModal from '@/components/modals/InactivityModal.vue';
import BetaSatBar from '@/components/infoBars/BetaSatBar.vue';
@ -152,7 +153,6 @@ import LoaderImage from '@/../static/images/common/loadIcon.svg';
const nativeRouter = useRouter();
const router = reactive(nativeRouter);
const store = useStore();
const notify = useNotify();
const bucketsStore = useBucketsStore();
@ -164,6 +164,7 @@ const agStore = useAccessGrantsStore();
const appStore = useAppStore();
const projectsStore = useProjectsStore();
const notificationsStore = useNotificationsStore();
const obStore = useObjectBrowserStore();
const analytics = new AnalyticsHttpApi();
const auth: AuthHttpApi = new AuthHttpApi();
@ -387,7 +388,7 @@ async function handleInactive(): Promise<void> {
appStore.clear(),
billingStore.clear(),
abTestingStore.reset(),
store.dispatch('files/clear'),
obStore.clear(),
]);
resetActivityEvents.forEach((eventName: string) => {
@ -482,7 +483,7 @@ function restartSessionTimers(): void {
}, sessionRefreshInterval.value);
inactivityTimerId.value = setTimeout(async () => {
if (store.getters['files/uploadingLength']) {
if (obStore.uploadingLength) {
await refreshSession();
return;
}

View File

@ -93,7 +93,7 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import MyAccountButton from '@/views/all-dashboard/components/MyAccountButton.vue';
import {
AnalyticsErrorEventSource,
@ -112,6 +112,7 @@ import { useAccessGrantsStore } from '@/store/modules/accessGrantsStore';
import { useBucketsStore } from '@/store/modules/bucketsStore';
import { useProjectsStore } from '@/store/modules/projectsStore';
import { useNotificationsStore } from '@/store/modules/notificationsStore';
import { useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import VButton from '@/components/common/VButton.vue';
@ -129,7 +130,6 @@ import ArrowIcon from '@/../static/images/navigation/arrowExpandRight.svg';
import CrossIcon from '@/../static/images/common/closeCross.svg';
import MenuIcon from '@/../static/images/navigation/menu.svg';
const store = useStore();
const router = useRouter();
const notify = useNotify();
@ -142,6 +142,7 @@ const abTestingStore = useABTestingStore();
const billingStore = useBillingStore();
const projectsStore = useProjectsStore();
const notificationsStore = useNotificationsStore();
const obStore = useObjectBrowserStore();
const analytics = new AnalyticsHttpApi();
const auth = new AuthHttpApi();
@ -242,7 +243,7 @@ async function onLogout(): Promise<void> {
appStore.clear(),
billingStore.clear(),
abTestingStore.reset(),
store.dispatch('files/clear'),
obStore.clear(),
]);
try {

View File

@ -52,7 +52,7 @@
import { computed, ref } from 'vue';
import { RouteConfig } from '@/router';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import { useNotify, useRouter } from '@/utils/hooks';
import {
AnalyticsErrorEventSource,
AnalyticsEvent,
@ -69,6 +69,7 @@ import { useAccessGrantsStore } from '@/store/modules/accessGrantsStore';
import { useBucketsStore } from '@/store/modules/bucketsStore';
import { useProjectsStore } from '@/store/modules/projectsStore';
import { useNotificationsStore } from '@/store/modules/notificationsStore';
import { useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import AccountIcon from '@/../static/images/navigation/account.svg';
import ArrowDownIcon from '@/../static/images/common/dropIcon.svg';
@ -79,7 +80,6 @@ import BillingIcon from '@/../static/images/navigation/billing.svg';
import SettingsIcon from '@/../static/images/navigation/settings.svg';
const router = useRouter();
const store = useStore();
const notify = useNotify();
const analytics = new AnalyticsHttpApi();
@ -94,6 +94,7 @@ const billingStore = useBillingStore();
const usersStore = useUsersStore();
const abTestingStore = useABTestingStore();
const notificationsStore = useNotificationsStore();
const obStore = useObjectBrowserStore();
const isHoveredOver = ref(false);
@ -167,7 +168,7 @@ async function onLogout(): Promise<void> {
appStore.clear(),
billingStore.clear(),
abTestingStore.reset(),
store.dispatch('files/clear'),
obStore.clear(),
]);
try {