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

IQSS / dataverse-frontend / 9501100703

11 Jun 2024 03:05PM UTC coverage: 97.537% (-0.3%) from 97.852%
9501100703

push

github

web-flow
Merge pull request #397 from ErykKul/366_file_upload

File Uploader

785 of 819 branches covered (95.85%)

Branch coverage included in aggregate %.

121 of 127 new or added lines in 6 files covered. (95.28%)

2185 of 2226 relevant lines covered (98.16%)

3282.52 hits per line

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

96.0
/src/sections/upload-dataset-files/UploadDatasetFiles.tsx
1
import { useEffect, useState } from 'react'
2
import { useTranslation } from 'react-i18next'
3
import { FileRepository } from '../../files/domain/repositories/FileRepository'
4
import { useLoading } from '../loading/LoadingContext'
5
import { useDataset } from '../dataset/DatasetContext'
6
import { PageNotFound } from '../page-not-found/PageNotFound'
7
import { BreadcrumbsGenerator } from '../shared/hierarchy/BreadcrumbsGenerator'
8
import { FileUploader } from './FileUploader'
9
import { FileUploadTools } from '../../files/domain/models/FileUploadState'
10
import { uploadFile } from '../../files/domain/useCases/uploadFile'
11

12
interface UploadDatasetFilesProps {
13
  fileRepository: FileRepository
14
}
15

16
export const UploadDatasetFiles = ({ fileRepository: fileRepository }: UploadDatasetFilesProps) => {
458✔
17
  const { setIsLoading } = useLoading()
458✔
18
  const { dataset, isLoading } = useDataset()
458✔
19
  const { t } = useTranslation('uploadDatasetFiles')
458✔
20
  const [fileUploaderState, setState] = useState(FileUploadTools.createNewState([]))
446✔
21
  const [uploadingToCancelMap, setUploadingToCancelMap] = useState(new Map<string, () => void>())
446✔
22
  const [uploadFinished, setUploadFinished] = useState(new Set<string>())
446✔
23
  const [semaphore, setSemaphore] = useState(new Set<string>())
446✔
24

25
  const sleep = (delay: number) => new Promise((res) => setTimeout(res, delay))
446✔
26
  const limit = 6
446✔
27

28
  const acquireSemaphore = async (file: File) => {
446✔
29
    const key = FileUploadTools.key(file)
105✔
30
    setSemaphore((x) => (x.size >= limit ? x : x.add(key)))
105✔
31
    while (!semaphore.has(key)) {
105✔
32
      await sleep(500)
40✔
33
      setSemaphore((x) => (x.size >= limit ? x : x.add(key)))
1!
34
    }
35
  }
36

37
  const releaseSemaphore = (file: File) => {
446✔
38
    setSemaphore((x) => {
47✔
39
      x.delete(FileUploadTools.key(file))
40✔
40
      return x
40✔
41
    })
42
  }
43

44
  const fileUploadFinished = (file: File) => {
446✔
45
    const key = FileUploadTools.key(file)
40✔
46
    setUploadFinished((x) => x.add(key))
40✔
47
    setUploadingToCancelMap((x) => {
40✔
48
      x.delete(key)
33✔
49
      return x
33✔
50
    })
51
    releaseSemaphore(file)
40✔
52
  }
53

54
  const uploadOneFile = (file: File) => {
446✔
55
    const key = FileUploadTools.key(file)
66✔
56
    if (uploadingToCancelMap.has(key) || uploadFinished.has(key)) {
66!
NEW
57
      return
×
58
    }
59
    setState(FileUploadTools.showProgressBar(file, fileUploaderState))
66✔
60
    const cancel = uploadFile(
66✔
61
      fileRepository,
62
      dataset?.persistentId as string,
63
      file,
64
      () => {
65
        setState(FileUploadTools.done(file, fileUploaderState))
29✔
66
        fileUploadFinished(file)
29✔
67
      },
68
      () => {
69
        setState(FileUploadTools.failed(file, fileUploaderState))
11✔
70
        fileUploadFinished(file)
11✔
71
      },
72
      (now) => setState(FileUploadTools.progress(file, now, fileUploaderState))
160✔
73
    )
74
    setUploadingToCancelMap((x) => x.set(key, cancel))
66✔
75
  }
76

77
  const upload = async (files: File[]) => {
446✔
78
    for (const file of files) {
422✔
79
      const key = FileUploadTools.key(file)
755✔
80
      if (!uploadingToCancelMap.has(key) && !uploadFinished.has(key)) {
755✔
81
        await acquireSemaphore(file)
105✔
82
        uploadOneFile(file)
66✔
83
      }
84
    }
85
  }
86

87
  const cancelUpload = (file: File) => {
446✔
88
    const key = FileUploadTools.key(file)
7✔
89
    const cancel = uploadingToCancelMap.get(key)
7✔
90
    if (cancel) {
7✔
91
      cancel()
7✔
92
      releaseSemaphore(file)
7✔
93
    }
94
    setUploadingToCancelMap((x) => {
7✔
95
      x.delete(key)
7✔
96
      return x
7✔
97
    })
98
    setState(FileUploadTools.removed(file, fileUploaderState))
7✔
99
  }
100

101
  useEffect(() => {
446✔
102
    setIsLoading(isLoading)
154✔
103
  }, [isLoading, setIsLoading])
104

105
  if (isLoading) {
446✔
106
    return <p>Temporary Loading until having shape of skeleton</p>
77✔
107
  }
108

109
  return (
369✔
110
    <>
111
      {!dataset ? (
369✔
112
        <PageNotFound />
113
      ) : (
114
        <>
115
          <BreadcrumbsGenerator
116
            hierarchy={dataset.hierarchy}
117
            withActionItem
118
            actionItemText={t('breadcrumbActionItem')}
119
          />
120
          <article>
121
            <FileUploader
122
              upload={upload}
123
              cancelTitle={t('cancel')}
124
              info={t('info')}
125
              selectText={t('select')}
126
              fileUploaderState={fileUploaderState}
127
              cancelUpload={cancelUpload}
128
            />
129
          </article>
130
        </>
131
      )}
132
    </>
133
  )
134
}
12✔
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