🌟basic status, while uploading directories (#216)
* 🌟 basic status, while uploading directories * 🐛 fix the infinite redirection when the token always expired
This commit is contained in:
@@ -319,8 +319,11 @@ export class DocumentsService {
|
|||||||
driveItem.last_version_cache = driveItemVersion;
|
driveItem.last_version_cache = driveItemVersion;
|
||||||
|
|
||||||
await this.repository.save(driveItem);
|
await this.repository.save(driveItem);
|
||||||
|
|
||||||
|
//TODO[ASH] update item size only for files, there is not need to do during direcotry creation
|
||||||
await updateItemSize(driveItem.parent_id, this.repository, context);
|
await updateItemSize(driveItem.parent_id, this.repository, context);
|
||||||
|
|
||||||
|
//TODO[ASH] there is no need to notify websocket, until we implement user notification
|
||||||
await this.notifyWebsocket(driveItem.parent_id, context);
|
await this.notifyWebsocket(driveItem.parent_id, context);
|
||||||
|
|
||||||
await globalResolver.platformServices.messageQueue.publish<DocumentsMessageQueueRequest>(
|
await globalResolver.platformServices.messageQueue.publish<DocumentsMessageQueueRequest>(
|
||||||
@@ -459,6 +462,7 @@ export class DocumentsService {
|
|||||||
* deletes or moves to Trash a Drive Document and its children
|
* deletes or moves to Trash a Drive Document and its children
|
||||||
*
|
*
|
||||||
* @param {string} id - the item id
|
* @param {string} id - the item id
|
||||||
|
* @param item
|
||||||
* @param {DriveExecutionContext} context - the execution context
|
* @param {DriveExecutionContext} context - the execution context
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
@@ -569,10 +573,10 @@ export class DocumentsService {
|
|||||||
}
|
}
|
||||||
await updateItemSize(previousParentId, this.repository, context);
|
await updateItemSize(previousParentId, this.repository, context);
|
||||||
|
|
||||||
this.notifyWebsocket(previousParentId, context);
|
await this.notifyWebsocket(previousParentId, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.notifyWebsocket("trash", context);
|
await this.notifyWebsocket("trash", context);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+24
-1
@@ -67,7 +67,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Col className="small-left-margin" flex="auto" style={{ lineHeight: '16px' }}>
|
<Col className="small-left-margin" flex="auto" style={{ lineHeight: '16px' }}>
|
||||||
{pendingFile?.originalFile.name ? (
|
{pendingFile?.originalFile?.name ? (
|
||||||
<Row justify="start" align="middle" wrap={false}>
|
<Row justify="start" align="middle" wrap={false}>
|
||||||
<Text
|
<Text
|
||||||
ellipsis
|
ellipsis
|
||||||
@@ -96,6 +96,29 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{pendingFile?.label ? (
|
||||||
|
<Row justify="start" align="middle" wrap={false}>
|
||||||
|
<Text
|
||||||
|
ellipsis
|
||||||
|
style={{
|
||||||
|
maxWidth: isPendingFileStatusPause(pendingFile.status) ? 130 : 160,
|
||||||
|
verticalAlign: 'middle',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{pendingFile?.label}
|
||||||
|
</Text>
|
||||||
|
</Row>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
marginTop: 8,
|
||||||
|
height: 8,
|
||||||
|
maxWidth: 160,
|
||||||
|
borderRadius: 8,
|
||||||
|
backgroundColor: 'var(--grey-background)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
<Col
|
<Col
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
version: /* @VERSION */ '2023.Q3.011',
|
version: /* @VERSION */ '2023.Q3.012',
|
||||||
version_detail: /* @VERSION_DETAIL */ '2023.Q3.011',
|
version_detail: /* @VERSION_DETAIL */ '2023.Q3.012',
|
||||||
version_name: /* @VERSION_NAME */ 'Ghost-Dog',
|
version_name: /* @VERSION_NAME */ 'Ghost-Dog',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import Globals from '@features/global/services/globals-tdrive-app-service';
|
|||||||
import { Cookies } from 'react-cookie';
|
import { Cookies } from 'react-cookie';
|
||||||
|
|
||||||
type AccountType = 'remote' | 'internal';
|
type AccountType = 'remote' | 'internal';
|
||||||
export type LoginState = '' | 'app' | 'error' | 'signin' | 'logged_out' | 'logout';
|
|
||||||
type InitState = '' | 'initializing' | 'initialized';
|
type InitState = '' | 'initializing' | 'initialized';
|
||||||
|
|
||||||
@TdriveService('AuthService')
|
@TdriveService('AuthService')
|
||||||
@@ -131,11 +130,13 @@ class AuthService {
|
|||||||
|
|
||||||
onNewToken(token?: JWTDataType): void {
|
onNewToken(token?: JWTDataType): void {
|
||||||
if (token) {
|
if (token) {
|
||||||
console.log("Save auth token to storage and cookie")
|
this.logger.info("Save auth token to storage and cookie")
|
||||||
JWT.updateJWT(token);
|
JWT.updateJWT(token);
|
||||||
this.cookies.set(AuthService.AUTH_TOKEN_COOKIE, JWT.getJWT(), { path: "/" });
|
this.cookies.set(AuthService.AUTH_TOKEN_COOKIE, JWT.getJWT(), { path: "/" });
|
||||||
// TODO: Update the user from API?
|
// TODO: Update the user from API?
|
||||||
// this.updateUser();
|
// this.updateUser();
|
||||||
|
} else {
|
||||||
|
this.logger.warn("Try to initialize storage with empty access token")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-14
@@ -33,6 +33,7 @@ export default class InternalAuthProviderService
|
|||||||
private logger: Logger.Logger;
|
private logger: Logger.Logger;
|
||||||
private initialized = false;
|
private initialized = false;
|
||||||
private signinIn = false;
|
private signinIn = false;
|
||||||
|
private params?: InitParameters;
|
||||||
|
|
||||||
constructor(private configuration?: InternalConfiguration) {
|
constructor(private configuration?: InternalConfiguration) {
|
||||||
super();
|
super();
|
||||||
@@ -45,6 +46,7 @@ export default class InternalAuthProviderService
|
|||||||
this.logger.warn('Already initialized');
|
this.logger.warn('Already initialized');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
this.params = params;
|
||||||
|
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
params.onInitialized();
|
params.onInitialized();
|
||||||
@@ -56,26 +58,27 @@ export default class InternalAuthProviderService
|
|||||||
return Promise.reject('"username" and "password" are required');
|
return Promise.reject('"username" and "password" are required');
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise<void>((resolve, reject) => {
|
this.signinIn = true;
|
||||||
this.signinIn = true;
|
this.logger.log("Sign in in console");
|
||||||
this.logger.log("Sign in in console");
|
try {
|
||||||
ConsoleAPIClient.login(
|
const access_token = await ConsoleAPIClient.login(
|
||||||
{
|
{
|
||||||
email: params.username,
|
email: params.username,
|
||||||
password: params.password,
|
password: params.password,
|
||||||
remember_me: params.remember_me,
|
remember_me: params.remember_me,
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
)
|
);
|
||||||
.then(accessToken => (accessToken ? resolve() : reject(new Error('Can not login'))))
|
this.logger.debug("Got access token from server");
|
||||||
.catch(err => {
|
await this.params?.onNewToken(access_token);
|
||||||
this.logger.error('Error on login', err);
|
this.signinIn = true;
|
||||||
reject(new Error('Can not login'));
|
} catch (e) {
|
||||||
})
|
this.signinIn = false;
|
||||||
.finally(() => {
|
throw new Error('Can not login');
|
||||||
this.signinIn = false;
|
} finally {
|
||||||
});
|
this.signinIn = false;
|
||||||
});
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async signOut(params: SignOutParameters): Promise<void> {
|
async signOut(params: SignOutParameters): Promise<void> {
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ class ConsoleAPIClient {
|
|||||||
|
|
||||||
logger = Logger.getLogger('ConsoleAPIClient');
|
logger = Logger.getLogger('ConsoleAPIClient');
|
||||||
|
|
||||||
login(params: LoginParams, disableJWTAuthentication = false): Promise<string> {
|
login(params: LoginParams, disableJWTAuthentication = false): Promise<JWTDataType> {
|
||||||
return Api.post<LoginParams, { access_token: string }>(
|
return Api.post<LoginParams, AccessTokenResponse>(
|
||||||
'/internal/services/console/v1/login',
|
'/internal/services/console/v1/login',
|
||||||
{ ...params, ...{ device: {} } },
|
{ ...params, ...{ device: {} } },
|
||||||
undefined,
|
undefined,
|
||||||
@@ -90,7 +90,7 @@ class ConsoleAPIClient {
|
|||||||
response.access_token
|
response.access_token
|
||||||
? resolve(response.access_token)
|
? resolve(response.access_token)
|
||||||
: reject(new Error('Can not get access token'));
|
: reject(new Error('Can not get access token'));
|
||||||
});
|
}, false, {disableJWTAuthentication: true});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import Languages from 'features/global/services/languages-service';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the children of a drive item
|
* Returns the children of a drive item
|
||||||
* @param id
|
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const useDriveActions = () => {
|
export const useDriveActions = () => {
|
||||||
@@ -47,11 +46,12 @@ export const useDriveActions = () => {
|
|||||||
|
|
||||||
const create = useCallback(
|
const create = useCallback(
|
||||||
async (item: Partial<DriveItem>, version: Partial<DriveItemVersion>) => {
|
async (item: Partial<DriveItem>, version: Partial<DriveItemVersion>) => {
|
||||||
|
if (!item || !version) throw new Error("All ");
|
||||||
let driveFile = null;
|
let driveFile = null;
|
||||||
if (!item.company_id) item.company_id = companyId;
|
if (!item.company_id) item.company_id = companyId;
|
||||||
try {
|
try {
|
||||||
driveFile = await DriveApiClient.create(companyId, { item, version });
|
driveFile = await DriveApiClient.create(companyId, { item, version });
|
||||||
await refresh(item.parent_id!);
|
await refresh(driveFile.parent_id!);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ToasterService.error(Languages.t('hooks.use-drive-actions.unable_create_file'));
|
ToasterService.error(Languages.t('hooks.use-drive-actions.unable_create_file'));
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ export const useDriveActions = () => {
|
|||||||
const download = useCallback(
|
const download = useCallback(
|
||||||
async (id: string, versionId?: string) => {
|
async (id: string, versionId?: string) => {
|
||||||
try {
|
try {
|
||||||
const url = await DriveApiClient.getDownloadUrl(companyId, id, versionId);
|
const url = DriveApiClient.getDownloadUrl(companyId, id, versionId);
|
||||||
(window as any).open(url, '_blank').focus();
|
(window as any).open(url, '_blank').focus();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ToasterService.error(Languages.t('hooks.use-drive-actions.unable_download_file'));
|
ToasterService.error(Languages.t('hooks.use-drive-actions.unable_download_file'));
|
||||||
|
|||||||
@@ -3,14 +3,16 @@ import FileUploadService from '@features/files/services/file-upload-service';
|
|||||||
import { ToasterService } from '@features/global/services/toaster-service';
|
import { ToasterService } from '@features/global/services/toaster-service';
|
||||||
import { DriveApiClient } from '../api-client/api-client';
|
import { DriveApiClient } from '../api-client/api-client';
|
||||||
import { useDriveActions } from './use-drive-actions';
|
import { useDriveActions } from './use-drive-actions';
|
||||||
|
import Logger from '@features/global/framework/logger-service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the children of a drive item
|
* Returns the children of a drive item
|
||||||
* @param id
|
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const useDriveUpload = () => {
|
export const useDriveUpload = () => {
|
||||||
const { create } = useDriveActions();
|
const { create, refresh } = useDriveActions();
|
||||||
|
|
||||||
|
const logger = Logger.getLogger('useDriveUpload')
|
||||||
|
|
||||||
const uploadVersion = async (file: File, context: { companyId: string; id: string }) => {
|
const uploadVersion = async (file: File, context: { companyId: string; id: string }) => {
|
||||||
return new Promise(r => {
|
return new Promise(r => {
|
||||||
@@ -45,47 +47,23 @@ export const useDriveUpload = () => {
|
|||||||
tree: FileTreeObject,
|
tree: FileTreeObject,
|
||||||
context: { companyId: string; parentId: string },
|
context: { companyId: string; parentId: string },
|
||||||
) => {
|
) => {
|
||||||
const filesPerParentId: { [key: string]: File[] } = {};
|
|
||||||
|
|
||||||
// Create all directories
|
// Create all directories
|
||||||
console.debug("Start creating directories ...");
|
logger.debug("Start creating directories ...");
|
||||||
const createDirectories = async (tree: FileTreeObject['tree'], parentId: string) => {
|
const filesPerParentId = await FileUploadService.createDirectories(tree.tree, context);
|
||||||
for (const directory of Object.keys(tree)) {
|
await refresh(context.parentId);
|
||||||
if (tree[directory] instanceof File) {
|
logger.debug("All directories created");
|
||||||
if (!filesPerParentId[parentId]) filesPerParentId[parentId] = [];
|
|
||||||
filesPerParentId[parentId].push(tree[directory] as File);
|
|
||||||
} else {
|
|
||||||
console.debug(`Create directory ${directory}`);
|
|
||||||
const driveItem = await create(
|
|
||||||
{
|
|
||||||
company_id: context.companyId,
|
|
||||||
parent_id: parentId,
|
|
||||||
name: directory,
|
|
||||||
is_directory: true,
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
);
|
|
||||||
console.debug(`Directory ${directory} created`);
|
|
||||||
if (driveItem?.id) {
|
|
||||||
await createDirectories(tree[directory] as FileTreeObject['tree'], driveItem.id);
|
|
||||||
} else {
|
|
||||||
throw new Error('Could not create directory');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
await createDirectories(tree.tree, context.parentId);
|
|
||||||
console.debug("All directories created");
|
|
||||||
|
|
||||||
// Upload files into directories
|
// Upload files into directories
|
||||||
|
logger.debug("Start file uploading")
|
||||||
for (const parentId of Object.keys(filesPerParentId)) {
|
for (const parentId of Object.keys(filesPerParentId)) {
|
||||||
|
logger.debug(`Upload files for directory ${parentId}`);
|
||||||
await FileUploadService.upload(filesPerParentId[parentId], {
|
await FileUploadService.upload(filesPerParentId[parentId], {
|
||||||
context: {
|
context: {
|
||||||
companyId: context.companyId,
|
companyId: context.companyId,
|
||||||
parentId: parentId,
|
parentId: parentId,
|
||||||
},
|
},
|
||||||
callback: (file, context) => {
|
callback: (file, context) => {
|
||||||
console.log('created file: ', file);
|
logger.debug('created file: ', file);
|
||||||
if (file) {
|
if (file) {
|
||||||
create(
|
create(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import RouterServices from '@features/router/services/router-service';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import FileUploadAPIClient from '../api/file-upload-api-client';
|
import FileUploadAPIClient from '../api/file-upload-api-client';
|
||||||
import { isPendingFileStatusPending } from '../utils/pending-files';
|
import { isPendingFileStatusPending } from '../utils/pending-files';
|
||||||
|
import { FileTreeObject } from "components/uploads/file-tree-utils";
|
||||||
|
import { DriveApiClient } from "features/drive/api-client/api-client";
|
||||||
|
|
||||||
export enum Events {
|
export enum Events {
|
||||||
ON_CHANGE = 'notify',
|
ON_CHANGE = 'notify',
|
||||||
@@ -20,6 +22,7 @@ class FileUploadService {
|
|||||||
private pendingFiles: PendingFileType[] = [];
|
private pendingFiles: PendingFileType[] = [];
|
||||||
public currentTaskId = '';
|
public currentTaskId = '';
|
||||||
private recoilHandler: Function = () => undefined;
|
private recoilHandler: Function = () => undefined;
|
||||||
|
private logger: Logger.Logger = Logger.getLogger('FileUploadService');
|
||||||
|
|
||||||
setRecoilHandler(handler: Function) {
|
setRecoilHandler(handler: Function) {
|
||||||
this.recoilHandler = handler;
|
this.recoilHandler = handler;
|
||||||
@@ -37,6 +40,69 @@ class FileUploadService {
|
|||||||
this.recoilHandler(_.cloneDeep(updatedState));
|
this.recoilHandler(_.cloneDeep(updatedState));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async createDirectories(root: FileTreeObject['tree'], context: { companyId: string; parentId: string }) {
|
||||||
|
// Create all directories
|
||||||
|
const filesPerParentId: { [key: string]: File[] } = {};
|
||||||
|
filesPerParentId[context.parentId] = []
|
||||||
|
|
||||||
|
const traverserTreeLevel = async (tree: FileTreeObject['tree'], parentId: string) => {
|
||||||
|
for (const directory of Object.keys(tree)) {
|
||||||
|
if (tree[directory] instanceof File) {
|
||||||
|
logger.trace(`${directory} is a file, save it for future upload`);
|
||||||
|
filesPerParentId[parentId].push(tree[directory] as File);
|
||||||
|
} else {
|
||||||
|
logger.debug(`Create directory ${directory}`);
|
||||||
|
|
||||||
|
const item = {
|
||||||
|
company_id: context.companyId,
|
||||||
|
parent_id: parentId,
|
||||||
|
name: directory,
|
||||||
|
is_directory: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!this.pendingFiles.some(f => isPendingFileStatusPending(f.status))) {
|
||||||
|
//New upload task when all previous task is finished
|
||||||
|
this.currentTaskId = uuid();
|
||||||
|
}
|
||||||
|
const pendingFile: PendingFileType = {
|
||||||
|
id: uuid(),
|
||||||
|
status: 'pending',
|
||||||
|
progress: 0,
|
||||||
|
lastProgress: new Date().getTime(),
|
||||||
|
speed: 0,
|
||||||
|
uploadTaskId: this.currentTaskId,
|
||||||
|
originalFile: null,
|
||||||
|
backendFile: null,
|
||||||
|
resumable: null,
|
||||||
|
label: directory,
|
||||||
|
type: "file",
|
||||||
|
pausable: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.pendingFiles.push(pendingFile);
|
||||||
|
this.notify();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const driveItem = await DriveApiClient.create(context.companyId, { item: item, version: {}});
|
||||||
|
this.logger.debug(`Directory ${directory} created`);
|
||||||
|
pendingFile.status = 'success';
|
||||||
|
this.notify();
|
||||||
|
if (driveItem?.id) {
|
||||||
|
filesPerParentId[driveItem.id] = []
|
||||||
|
await traverserTreeLevel(tree[directory] as FileTreeObject['tree'], driveItem.id);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error(e);
|
||||||
|
throw new Error('Could not create directory');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await traverserTreeLevel(root, context.parentId);
|
||||||
|
return filesPerParentId;
|
||||||
|
}
|
||||||
|
|
||||||
public async upload(
|
public async upload(
|
||||||
fileList: File[],
|
fileList: File[],
|
||||||
options?: {
|
options?: {
|
||||||
@@ -47,7 +113,7 @@ class FileUploadService {
|
|||||||
const { companyId } = RouterServices.getStateFromRoute();
|
const { companyId } = RouterServices.getStateFromRoute();
|
||||||
|
|
||||||
if (!fileList || !companyId) {
|
if (!fileList || !companyId) {
|
||||||
logger.log('FileList or companyId is undefined', [fileList, companyId]);
|
this.logger.log('FileList or companyId is undefined', [fileList, companyId]);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +135,9 @@ class FileUploadService {
|
|||||||
originalFile: file,
|
originalFile: file,
|
||||||
backendFile: null,
|
backendFile: null,
|
||||||
resumable: null,
|
resumable: null,
|
||||||
|
type: "file",
|
||||||
|
label: null,
|
||||||
|
pausable: true
|
||||||
};
|
};
|
||||||
|
|
||||||
this.pendingFiles.push(pendingFile);
|
this.pendingFiles.push(pendingFile);
|
||||||
@@ -108,7 +177,7 @@ class FileUploadService {
|
|||||||
|
|
||||||
pendingFile.resumable.on('fileProgress', (f: any) => {
|
pendingFile.resumable.on('fileProgress', (f: any) => {
|
||||||
const bytesDelta =
|
const bytesDelta =
|
||||||
(f.progress() - pendingFile.progress) * (pendingFile?.originalFile.size || 0);
|
(f.progress() - pendingFile.progress) * (pendingFile?.originalFile?.size || 0);
|
||||||
const timeDelta = new Date().getTime() - pendingFile.lastProgress;
|
const timeDelta = new Date().getTime() - pendingFile.lastProgress;
|
||||||
|
|
||||||
// To avoid jumping time ?
|
// To avoid jumping time ?
|
||||||
@@ -167,14 +236,17 @@ class FileUploadService {
|
|||||||
const fileToCancel = this.pendingFiles.filter(f => f.id === id)[0];
|
const fileToCancel = this.pendingFiles.filter(f => f.id === id)[0];
|
||||||
|
|
||||||
fileToCancel.status = 'cancel';
|
fileToCancel.status = 'cancel';
|
||||||
fileToCancel.resumable.cancel();
|
|
||||||
this.notify();
|
|
||||||
|
|
||||||
if (fileToCancel.backendFile)
|
if (fileToCancel.resumable) {
|
||||||
this.deleteOneFile({
|
fileToCancel.resumable.cancel();
|
||||||
companyId: fileToCancel.backendFile.company_id,
|
this.notify();
|
||||||
fileId: fileToCancel.backendFile.id,
|
|
||||||
});
|
if (fileToCancel.backendFile)
|
||||||
|
this.deleteOneFile({
|
||||||
|
companyId: fileToCancel.backendFile.company_id,
|
||||||
|
fileId: fileToCancel.backendFile.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.pendingFiles = this.pendingFiles.filter(f => f.id !== id);
|
this.pendingFiles = this.pendingFiles.filter(f => f.id !== id);
|
||||||
|
|||||||
@@ -66,14 +66,20 @@ export type PendingFileRecoilType = {
|
|||||||
file: FileType | null;
|
file: FileType | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It could be not only a file, but also a task with creating folders
|
||||||
|
*/
|
||||||
export type PendingFileType = {
|
export type PendingFileType = {
|
||||||
|
type: "file" | "folder"
|
||||||
resumable: typeof Resumable | null; //Contain the resumable instance in charge of this file
|
resumable: typeof Resumable | null; //Contain the resumable instance in charge of this file
|
||||||
uploadTaskId: string;
|
uploadTaskId: string;
|
||||||
id: string;
|
id: string;
|
||||||
status: 'pending' | 'error' | 'success' | 'pause' | 'cancel';
|
status: 'pending' | 'error' | 'success' | 'pause' | 'cancel';
|
||||||
progress: number; //Between 0 and 1
|
progress: number; //Between 0 and 1
|
||||||
originalFile: File; //Will be used to get filename, temporary thumbnail
|
originalFile: File | null; //Will be used to get filename, temporary thumbnail
|
||||||
backendFile: FileType | null; //Will contain the final object returned by API
|
backendFile: FileType | null; //Will contain the final object returned by API
|
||||||
lastProgress: number;
|
lastProgress: number;
|
||||||
speed: number;
|
speed: number;
|
||||||
|
label: string | null;
|
||||||
|
pausable: boolean;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
import { PendingFileRecoilType } from '@features/files/types/file';
|
import { PendingFileRecoilType } from '@features/files/types/file';
|
||||||
|
|
||||||
export const isPendingFileStatusPause = (status: PendingFileRecoilType['status']): boolean => {
|
export const isPendingFileStatusPause = (status: PendingFileRecoilType['status']): boolean => {
|
||||||
return status === 'pause' ? true : false;
|
return status === 'pause';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isPendingFileStatusError = (status: PendingFileRecoilType['status']): boolean => {
|
export const isPendingFileStatusError = (status: PendingFileRecoilType['status']): boolean => {
|
||||||
return status === 'error' ? true : false;
|
return status === 'error';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isPendingFileStatusCancel = (status: PendingFileRecoilType['status']): boolean => {
|
export const isPendingFileStatusCancel = (status: PendingFileRecoilType['status']): boolean => {
|
||||||
return status === 'cancel' ? true : false;
|
return status === 'cancel';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isPendingFileStatusPending = (status: PendingFileRecoilType['status']): boolean => {
|
export const isPendingFileStatusPending = (status: PendingFileRecoilType['status']): boolean => {
|
||||||
return status === 'pending' ? true : false;
|
return status === 'pending';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isPendingFileStatusSuccess = (status: PendingFileRecoilType['status']): boolean => {
|
export const isPendingFileStatusSuccess = (status: PendingFileRecoilType['status']): boolean => {
|
||||||
return status === 'success' ? true : false;
|
return status === 'success';
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user