✨ Sort files chronologically + infinite scroll (#535)
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { ToasterService } from '@features/global/services/toaster-service';
|
||||
import useRouterCompany from '@features/router/hooks/use-router-company';
|
||||
import { useCallback } from 'react';
|
||||
import { useRecoilValue, useRecoilCallback } from 'recoil';
|
||||
import { useRecoilValue, useRecoilCallback, useRecoilState } from 'recoil';
|
||||
import { DriveApiClient } from '../api-client/api-client';
|
||||
import { DriveItemAtom, DriveItemChildrenAtom } from '../state/store';
|
||||
import { DriveItemAtom, DriveItemChildrenAtom, DriveItemPagination, DriveItemSort } from '../state/store';
|
||||
import { BrowseFilter, DriveItem, DriveItemVersion } from '../types';
|
||||
import { SharedWithMeFilterState } from '../state/shared-with-me-filter';
|
||||
import Languages from 'features/global/services/languages-service';
|
||||
@@ -16,18 +16,26 @@ import { useUserQuota } from 'features/users/hooks/use-user-quota';
|
||||
export const useDriveActions = () => {
|
||||
const companyId = useRouterCompany();
|
||||
const sharedFilter = useRecoilValue(SharedWithMeFilterState);
|
||||
const sortItem = useRecoilValue(DriveItemSort);
|
||||
const [paginateItem, _] = useRecoilState(DriveItemPagination);
|
||||
const { getQuota } = useUserQuota();
|
||||
|
||||
const refresh = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
async (parentId: string) => {
|
||||
async (parentId: string, resetPagination?: boolean) => {
|
||||
if (parentId) {
|
||||
const filter: BrowseFilter = {
|
||||
company_id: companyId,
|
||||
mime_type: sharedFilter.mimeType.value,
|
||||
};
|
||||
let pagination = await snapshot.getPromise(DriveItemPagination);
|
||||
|
||||
if (resetPagination) {
|
||||
pagination = { page: 0, limit: pagination.limit };
|
||||
set(DriveItemPagination, pagination);
|
||||
}
|
||||
try {
|
||||
const details = await DriveApiClient.browse(companyId, parentId, filter);
|
||||
const details = await DriveApiClient.browse(companyId, parentId, filter, sortItem, pagination);
|
||||
set(DriveItemChildrenAtom(parentId), details.children);
|
||||
set(DriveItemAtom(parentId), details);
|
||||
for (const child of details.children) {
|
||||
@@ -40,10 +48,12 @@ export const useDriveActions = () => {
|
||||
return details;
|
||||
} catch (e) {
|
||||
ToasterService.error(Languages.t('hooks.use-drive-actions.unable_load_file'));
|
||||
} finally {
|
||||
set(DriveItemPagination, { page: pagination.limit, limit: pagination.limit });
|
||||
}
|
||||
}
|
||||
},
|
||||
[companyId],
|
||||
[companyId, sortItem],
|
||||
);
|
||||
|
||||
const create = useCallback(
|
||||
@@ -54,7 +64,7 @@ export const useDriveActions = () => {
|
||||
try {
|
||||
const driveFile = await DriveApiClient.create(companyId, { item, version });
|
||||
|
||||
await refresh(driveFile.parent_id);
|
||||
await refresh(driveFile.parent_id, true);
|
||||
await getQuota();
|
||||
|
||||
return driveFile;
|
||||
@@ -89,9 +99,9 @@ export const useDriveActions = () => {
|
||||
);
|
||||
|
||||
const downloadZip = useCallback(
|
||||
async (ids: string[]) => {
|
||||
async (ids: string[], isDirectory?: boolean) => {
|
||||
try {
|
||||
const url = await DriveApiClient.getDownloadZipUrl(companyId, ids);
|
||||
const url = await DriveApiClient.getDownloadZipUrl(companyId, ids, isDirectory);
|
||||
(window as any).open(url, '_blank').focus();
|
||||
} catch (e) {
|
||||
ToasterService.error(Languages.t('hooks.use-drive-actions.unable_download_file'));
|
||||
@@ -129,9 +139,9 @@ export const useDriveActions = () => {
|
||||
async (update: Partial<DriveItem>, id: string, parentId: string) => {
|
||||
try {
|
||||
await DriveApiClient.update(companyId, id, update);
|
||||
await refresh(id || '');
|
||||
await refresh(parentId || '');
|
||||
if (update?.parent_id !== parentId) await refresh(update?.parent_id || '');
|
||||
await refresh(id || '', true);
|
||||
await refresh(parentId || '', true);
|
||||
if (update?.parent_id !== parentId) await refresh(update?.parent_id || '', true);
|
||||
} catch (e) {
|
||||
ToasterService.error(Languages.t('hooks.use-drive-actions.unable_update_file'));
|
||||
}
|
||||
@@ -156,5 +166,25 @@ export const useDriveActions = () => {
|
||||
[refresh],
|
||||
);
|
||||
|
||||
return { create, refresh, download, downloadZip, remove, restore, update, updateLevel };
|
||||
const nextPage = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
async (parentId: string) => {
|
||||
const filter: BrowseFilter = {
|
||||
company_id: companyId,
|
||||
mime_type: sharedFilter.mimeType.value,
|
||||
};
|
||||
const pagination = await snapshot.getPromise(DriveItemPagination);
|
||||
const details = await DriveApiClient.browse(
|
||||
companyId,
|
||||
parentId,
|
||||
filter,
|
||||
sortItem,
|
||||
pagination
|
||||
);
|
||||
return details;
|
||||
},
|
||||
[paginateItem, refresh],
|
||||
);
|
||||
|
||||
return { create, refresh, download, downloadZip, remove, restore, update, updateLevel, nextPage };
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { ToasterService } from '@features/global/services/toaster-service';
|
||||
import { LoadingStateInitTrue } from '@features/global/state/atoms/Loading';
|
||||
import useRouterCompany from '@features/router/hooks/use-router-company';
|
||||
import { useCallback } from 'react';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { DriveItemAtom, DriveItemChildrenAtom } from '../state/store';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { DriveItemAtom, DriveItemChildrenAtom, DriveItemPagination } from '../state/store';
|
||||
import { DriveItem } from '../types';
|
||||
import { useDriveActions } from './use-drive-actions';
|
||||
import { useDriveUpload } from './use-drive-upload';
|
||||
@@ -17,8 +17,10 @@ import short from 'short-uuid';
|
||||
export const useDriveItem = (id: string) => {
|
||||
const companyId = useRouterCompany();
|
||||
const item = useRecoilValue(DriveItemAtom(id));
|
||||
const children = useRecoilValue(DriveItemChildrenAtom(id));
|
||||
// const children = useRecoilValue(DriveItemChildrenAtom(id));
|
||||
const [children, setChildren] = useRecoilState(DriveItemChildrenAtom(id));
|
||||
const [loading, setLoading] = useRecoilState(LoadingStateInitTrue('useDriveItem-' + id));
|
||||
const [_, setPaginateItem] = useRecoilState(DriveItemPagination);
|
||||
const {
|
||||
refresh: refreshItem,
|
||||
create,
|
||||
@@ -26,19 +28,20 @@ export const useDriveItem = (id: string) => {
|
||||
updateLevel: _updateLevel,
|
||||
remove: _remove,
|
||||
restore: _restore,
|
||||
nextPage,
|
||||
} = useDriveActions();
|
||||
const { uploadVersion: _uploadVersion } = useDriveUpload();
|
||||
|
||||
const refresh = useCallback(
|
||||
async (parentId: string) => {
|
||||
async (parentId: string, resetPagination?: boolean) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
await refreshItem(parentId);
|
||||
setPaginateItem(prev => ({ ...prev, page: 0 }));
|
||||
await refreshItem(parentId, resetPagination);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[setLoading, refreshItem],
|
||||
[id, setLoading, refreshItem],
|
||||
);
|
||||
|
||||
const remove = useCallback(async () => {
|
||||
@@ -100,6 +103,51 @@ export const useDriveItem = (id: string) => {
|
||||
[companyId, id, setLoading, refresh, item?.item?.parent_id],
|
||||
);
|
||||
|
||||
const loadNextPage = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
async (id: string) => {
|
||||
// get current pagination state
|
||||
const pagination = await snapshot.getPromise(DriveItemPagination);
|
||||
|
||||
// if end is true, do not load more
|
||||
if (pagination.lastPage === true) return;
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
const details = await nextPage(id);
|
||||
if (details.children.length === 0) {
|
||||
set(DriveItemPagination, prev => ({
|
||||
...prev,
|
||||
lastPage: true,
|
||||
}));
|
||||
}
|
||||
// set children and remove duplicates
|
||||
setChildren(prev => [
|
||||
...prev,
|
||||
...details.children.filter(
|
||||
(item, index, self) =>
|
||||
index === self.findIndex(t => t.id === item.id),
|
||||
),
|
||||
]);
|
||||
} catch (e) {
|
||||
// set pagination end to true
|
||||
set(DriveItemPagination, prev => ({
|
||||
...prev,
|
||||
lastPage: true,
|
||||
}));
|
||||
console.log('error loading next page: ', e);
|
||||
ToasterService.error('Unable to load more items.');
|
||||
} finally {
|
||||
set(DriveItemPagination, prev => ({
|
||||
...prev,
|
||||
page: (prev.page + prev.limit),
|
||||
}));
|
||||
}
|
||||
setLoading(false);
|
||||
},
|
||||
[id, nextPage],
|
||||
);
|
||||
|
||||
const inTrash =
|
||||
id.includes('trash') ||
|
||||
item?.path?.some(i => i?.parent_id?.includes('trash')) ||
|
||||
@@ -123,6 +171,7 @@ export const useDriveItem = (id: string) => {
|
||||
updateLevel,
|
||||
remove,
|
||||
refresh,
|
||||
loadNextPage,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -29,11 +29,17 @@ export const useDrivePreviewModal = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const openWithId: (id: string) => void = (id: string) => {
|
||||
DriveApiClient.get(company, id).then((item) => {
|
||||
open(item?.item);
|
||||
});
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
setStatus({ item: null, loading: true });
|
||||
}
|
||||
|
||||
return { open, close, isOpen: !!status.item };
|
||||
return { open, close, isOpen: !!status.item, openWithId };
|
||||
};
|
||||
|
||||
export const useDrivePreview = () => {
|
||||
|
||||
@@ -50,7 +50,7 @@ export const useDriveUpload = () => {
|
||||
// Create all directories
|
||||
logger.debug("Start creating directories ...");
|
||||
const filesPerParentId = await FileUploadService.createDirectories(tree.tree, context);
|
||||
await refresh(context.parentId);
|
||||
await refresh(context.parentId, true);
|
||||
logger.debug("All directories created");
|
||||
|
||||
// Upload files into directories
|
||||
@@ -90,7 +90,7 @@ export const useDriveUpload = () => {
|
||||
},
|
||||
});
|
||||
}
|
||||
await refresh(context.parentId);
|
||||
await refresh(context.parentId, true);
|
||||
};
|
||||
|
||||
const uploadFromUrl = (
|
||||
|
||||
Reference in New Issue
Block a user