• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

teableio / teable / 8388153768

22 Mar 2024 09:25AM CUT coverage: 28.048% (-0.2%) from 28.208%
8388153768

Pull #484

github

web-flow
Merge 27e748d45 into a06c6afb1
Pull Request #484: feat: support increment import

2099 of 3215 branches covered (65.29%)

24 of 738 new or added lines in 21 files covered. (3.25%)

4 existing lines in 3 files now uncovered.

25814 of 92035 relevant lines covered (28.05%)

5.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/packages/sdk/src/components/editor/attachment/upload-attachment/uploadManage.ts
1
import type { INotifyVo, UploadType } from '@teable/openapi';
×
2
import { getSignature, notify } from '@teable/openapi';
×
3
import axios from 'axios';
×
4
import { noop } from 'lodash';
×
5

×
6
interface IUploadTask {
×
7
  file: IFile;
×
8
  status: Status;
×
9
  progress: number;
×
10
  type: UploadType;
×
11
  successCallback: ISuccessCallback;
×
12
  errorCallback: IErrorCallback;
×
13
  progressCallback: IProgressCallback;
×
14
}
×
15

×
16
export interface IFile {
×
17
  id: string;
×
18
  instance: File;
×
19
}
×
20

×
21
type ISuccessCallback = (file: IFile, attachment: INotifyVo) => void;
×
22

×
23
type IErrorCallback = (file: IFile, error?: string) => void;
×
24

×
25
type IProgressCallback = (file: IFile, progress: number) => void;
×
26

×
27
export enum Status {
×
28
  Pending,
×
29
  Uploading,
×
30
  Completed,
×
31
}
×
32

×
33
export class AttachmentManager {
×
34
  limit: number;
×
35
  uploadQueue: IUploadTask[];
×
36
  shareId?: string;
×
37

×
38
  constructor(limit: number) {
×
39
    this.limit = limit;
×
40
    this.uploadQueue = [];
×
41
  }
×
42

×
43
  upload(
×
44
    files: IFile[],
×
45
    type: UploadType,
×
46
    callbackFn: {
×
47
      successCallback?: ISuccessCallback;
×
48
      errorCallback?: IErrorCallback;
×
49
      progressCallback?: IProgressCallback;
×
50
    }
×
51
  ) {
×
52
    const { successCallback = noop, errorCallback = noop, progressCallback = noop } = callbackFn;
×
53
    for (let i = 0; i < files.length; i++) {
×
54
      const file = files[i];
×
55

×
56
      const uploadTask: IUploadTask = {
×
57
        file,
×
58
        status: Status.Pending,
×
59
        progress: 0,
×
60
        type,
×
61
        successCallback: successCallback,
×
62
        errorCallback: errorCallback,
×
63
        progressCallback: progressCallback,
×
64
      };
×
65

×
66
      if (this.uploadQueue.length < this.limit) {
×
67
        this.executeUpload(uploadTask);
×
68
      } else {
×
69
        this.uploadQueue.push(uploadTask);
×
70
      }
×
71
    }
×
72
  }
×
73

×
74
  async executeUpload(uploadTask: IUploadTask) {
×
75
    uploadTask.status = Status.Uploading;
×
76

×
77
    try {
×
78
      const fileInstance = uploadTask.file.instance;
×
79
      const res = await getSignature(
×
80
        {
×
81
          type: uploadTask.type,
×
82
          contentLength: fileInstance.size,
×
83
          contentType: fileInstance.type,
×
84
        },
×
85
        this.shareId
×
86
      ); // Assuming you have an AttachmentApi that provides the upload URL
×
87
      if (!res.data) {
×
88
        uploadTask.errorCallback(uploadTask.file, 'Failed to get upload URL');
×
89
        return;
×
90
      }
×
91
      const { url, uploadMethod, token, requestHeaders } = res.data;
×
NEW
92
      delete requestHeaders['Content-Length'];
×
93
      await axios(url, {
×
94
        method: uploadMethod,
×
95
        data: fileInstance,
×
96
        onUploadProgress: (progressEvent) => {
×
97
          const progress = Math.round((progressEvent.loaded * 100) / (progressEvent.total || 0));
×
98
          uploadTask.progress = progress;
×
99
          uploadTask.progressCallback(uploadTask.file, progress); // Update progress
×
100
        },
×
101
        headers: {
×
102
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
×
103
          ...(requestHeaders as any),
×
104
        },
×
105
      });
×
106

×
107
      const notifyRes = await notify(token, this.shareId);
×
108
      if (!notifyRes.data) {
×
109
        uploadTask.errorCallback(uploadTask.file);
×
110
        return;
×
111
      }
×
112
      this.completeUpload(uploadTask, notifyRes.data);
×
113
    } catch (error) {
×
114
      uploadTask.errorCallback(uploadTask.file);
×
115
    }
×
116
  }
×
117

×
118
  completeUpload(uploadTask: IUploadTask, attachment: INotifyVo) {
×
119
    uploadTask.status = Status.Completed;
×
120
    uploadTask.successCallback(uploadTask.file, attachment);
×
121

×
122
    // Check if there are pending upload tasks
×
123
    if (this.uploadQueue.length > 0) {
×
124
      const nextTask = this.uploadQueue.shift();
×
125
      nextTask && this.executeUpload(nextTask);
×
126
    }
×
127
  }
×
128
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc