@openneuro/app 4.11.0 → 4.12.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -5
- package/src/scripts/apm.js +0 -2
- package/src/scripts/dataset/__tests__/__snapshots__/snapshot-container.spec.tsx.snap +48 -68
- package/src/scripts/dataset/download/download-native.js +77 -30
- package/src/scripts/dataset/download/download-query.js +3 -1
- package/src/scripts/dataset/download/native-file-toast.jsx +24 -6
- package/src/scripts/dataset/files/__tests__/file-tree-unloaded-directory.spec.jsx +4 -16
- package/src/scripts/dataset/files/__tests__/file-tree.spec.jsx +104 -33
- package/src/scripts/dataset/files/file-tree-unloaded-directory.jsx +26 -31
- package/src/scripts/dataset/files/file-tree.tsx +158 -0
- package/src/scripts/dataset/files/file.tsx +2 -2
- package/src/scripts/dataset/files/{files.jsx → files.tsx} +21 -12
- package/src/scripts/types/dataset-file.ts +11 -0
- package/src/scripts/dataset/files/__tests__/file-tree-loading.spec.jsx +0 -18
- package/src/scripts/dataset/files/__tests__/flat-to-tree.spec.js +0 -55
- package/src/scripts/dataset/files/file-tree-loading.jsx +0 -65
- package/src/scripts/dataset/files/file-tree.jsx +0 -126
- package/src/scripts/dataset/files/flat-to-tree.js +0 -49
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openneuro/app",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.12.0-alpha.0",
|
|
4
4
|
"description": "React JS web frontend for the OpenNeuro platform.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "public/client.js",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"@emotion/react": "11.6.0",
|
|
21
21
|
"@emotion/styled": "11.6.0",
|
|
22
22
|
"@niivue/niivue": "0.23.1",
|
|
23
|
-
"@openneuro/client": "^4.
|
|
24
|
-
"@openneuro/components": "^4.
|
|
23
|
+
"@openneuro/client": "^4.12.0-alpha.0",
|
|
24
|
+
"@openneuro/components": "^4.12.0-alpha.0",
|
|
25
25
|
"bids-validator": "1.9.9",
|
|
26
26
|
"bytes": "^3.0.0",
|
|
27
27
|
"comlink": "^4.0.5",
|
|
@@ -39,7 +39,6 @@
|
|
|
39
39
|
"react-dom": "^17.0.1",
|
|
40
40
|
"react-helmet": "6.1.0",
|
|
41
41
|
"react-router-dom": "6.3.0",
|
|
42
|
-
"react-spring": "^8.0.27",
|
|
43
42
|
"react-toastify": "6.0.9",
|
|
44
43
|
"react-usestateref": "^1.0.5",
|
|
45
44
|
"react-virtualized": "remorses/react-virtualized-fixed-import.git#9.22.3",
|
|
@@ -105,5 +104,5 @@
|
|
|
105
104
|
"publishConfig": {
|
|
106
105
|
"access": "public"
|
|
107
106
|
},
|
|
108
|
-
"gitHead": "
|
|
107
|
+
"gitHead": "3d8f7524b2233605f2da66f05de90b2e96e7a127"
|
|
109
108
|
}
|
package/src/scripts/apm.js
CHANGED
|
@@ -624,13 +624,13 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
624
624
|
aria-label=""
|
|
625
625
|
class=" on-icon "
|
|
626
626
|
role="img"
|
|
627
|
-
style="color:
|
|
627
|
+
style="color: deepskyblue;"
|
|
628
628
|
>
|
|
629
629
|
<i
|
|
630
|
-
class="fab fa-
|
|
630
|
+
class="fab fa-markdown"
|
|
631
631
|
/>
|
|
632
632
|
</span>
|
|
633
|
-
|
|
633
|
+
README
|
|
634
634
|
<span
|
|
635
635
|
class="filetree-editfile"
|
|
636
636
|
>
|
|
@@ -647,7 +647,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
647
647
|
>
|
|
648
648
|
<a
|
|
649
649
|
aria-label="view file"
|
|
650
|
-
href="/datasets/ds001032/versions/1.0.0/file-display/
|
|
650
|
+
href="/datasets/ds001032/versions/1.0.0/file-display/README"
|
|
651
651
|
>
|
|
652
652
|
<i
|
|
653
653
|
class="fa fa-eye"
|
|
@@ -664,13 +664,13 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
664
664
|
aria-label=""
|
|
665
665
|
class=" on-icon "
|
|
666
666
|
role="img"
|
|
667
|
-
style="color:
|
|
667
|
+
style="color: limegreen;"
|
|
668
668
|
>
|
|
669
669
|
<i
|
|
670
|
-
class="
|
|
670
|
+
class="fab fa-node-js"
|
|
671
671
|
/>
|
|
672
672
|
</span>
|
|
673
|
-
|
|
673
|
+
T1w.json
|
|
674
674
|
<span
|
|
675
675
|
class="filetree-editfile"
|
|
676
676
|
>
|
|
@@ -687,7 +687,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
687
687
|
>
|
|
688
688
|
<a
|
|
689
689
|
aria-label="view file"
|
|
690
|
-
href="/datasets/ds001032/versions/1.0.0/file-display/
|
|
690
|
+
href="/datasets/ds001032/versions/1.0.0/file-display/T1w.json"
|
|
691
691
|
>
|
|
692
692
|
<i
|
|
693
693
|
class="fa fa-eye"
|
|
@@ -704,13 +704,13 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
704
704
|
aria-label=""
|
|
705
705
|
class=" on-icon "
|
|
706
706
|
role="img"
|
|
707
|
-
style="color:
|
|
707
|
+
style="color: limegreen;"
|
|
708
708
|
>
|
|
709
709
|
<i
|
|
710
|
-
class="fab fa-
|
|
710
|
+
class="fab fa-node-js"
|
|
711
711
|
/>
|
|
712
712
|
</span>
|
|
713
|
-
|
|
713
|
+
dataset_description.json
|
|
714
714
|
<span
|
|
715
715
|
class="filetree-editfile"
|
|
716
716
|
>
|
|
@@ -727,7 +727,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
727
727
|
>
|
|
728
728
|
<a
|
|
729
729
|
aria-label="view file"
|
|
730
|
-
href="/datasets/ds001032/versions/1.0.0/file-display/
|
|
730
|
+
href="/datasets/ds001032/versions/1.0.0/file-display/dataset_description.json"
|
|
731
731
|
>
|
|
732
732
|
<i
|
|
733
733
|
class="fa fa-eye"
|
|
@@ -744,13 +744,13 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
744
744
|
aria-label=""
|
|
745
745
|
class=" on-icon "
|
|
746
746
|
role="img"
|
|
747
|
-
style="color:
|
|
747
|
+
style="color: lightgreen;"
|
|
748
748
|
>
|
|
749
749
|
<i
|
|
750
|
-
class="
|
|
750
|
+
class="fas fa-file-excel"
|
|
751
751
|
/>
|
|
752
752
|
</span>
|
|
753
|
-
|
|
753
|
+
participants.tsv
|
|
754
754
|
<span
|
|
755
755
|
class="filetree-editfile"
|
|
756
756
|
>
|
|
@@ -767,7 +767,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
767
767
|
>
|
|
768
768
|
<a
|
|
769
769
|
aria-label="view file"
|
|
770
|
-
href="/datasets/ds001032/versions/1.0.0/file-display/
|
|
770
|
+
href="/datasets/ds001032/versions/1.0.0/file-display/participants.tsv"
|
|
771
771
|
>
|
|
772
772
|
<i
|
|
773
773
|
class="fa fa-eye"
|
|
@@ -803,13 +803,8 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
803
803
|
<div
|
|
804
804
|
class="accordion-content"
|
|
805
805
|
>
|
|
806
|
-
<div
|
|
807
|
-
|
|
808
|
-
>
|
|
809
|
-
<div
|
|
810
|
-
class="css-b1x83q"
|
|
811
|
-
style="width: 0%;"
|
|
812
|
-
/>
|
|
806
|
+
<div>
|
|
807
|
+
Loading...
|
|
813
808
|
</div>
|
|
814
809
|
</div>
|
|
815
810
|
</div>
|
|
@@ -841,13 +836,8 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
841
836
|
<div
|
|
842
837
|
class="accordion-content"
|
|
843
838
|
>
|
|
844
|
-
<div
|
|
845
|
-
|
|
846
|
-
>
|
|
847
|
-
<div
|
|
848
|
-
class="css-b1x83q"
|
|
849
|
-
style="width: 0%;"
|
|
850
|
-
/>
|
|
839
|
+
<div>
|
|
840
|
+
Loading...
|
|
851
841
|
</div>
|
|
852
842
|
</div>
|
|
853
843
|
</div>
|
|
@@ -974,13 +964,13 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
974
964
|
aria-label=""
|
|
975
965
|
class=" on-icon "
|
|
976
966
|
role="img"
|
|
977
|
-
style="color:
|
|
967
|
+
style="color: deepskyblue;"
|
|
978
968
|
>
|
|
979
969
|
<i
|
|
980
|
-
class="fab fa-
|
|
970
|
+
class="fab fa-markdown"
|
|
981
971
|
/>
|
|
982
972
|
</span>
|
|
983
|
-
|
|
973
|
+
README
|
|
984
974
|
<span
|
|
985
975
|
class="filetree-editfile"
|
|
986
976
|
>
|
|
@@ -990,7 +980,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
990
980
|
<span
|
|
991
981
|
class=" "
|
|
992
982
|
data-flow="up"
|
|
993
|
-
data-tooltip="Download:
|
|
983
|
+
data-tooltip="Download: 709B"
|
|
994
984
|
>
|
|
995
985
|
<span
|
|
996
986
|
class="edit-file download-file"
|
|
@@ -998,7 +988,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
998
988
|
<a
|
|
999
989
|
aria-label="download file"
|
|
1000
990
|
download=""
|
|
1001
|
-
href="/crn/datasets/ds001032/snapshots/1.0.0/files/
|
|
991
|
+
href="/crn/datasets/ds001032/snapshots/1.0.0/files/README"
|
|
1002
992
|
>
|
|
1003
993
|
<i
|
|
1004
994
|
class="fa fa-download"
|
|
@@ -1017,7 +1007,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1017
1007
|
>
|
|
1018
1008
|
<a
|
|
1019
1009
|
aria-label="view file"
|
|
1020
|
-
href="/datasets/ds001032/versions/1.0.0/file-display/
|
|
1010
|
+
href="/datasets/ds001032/versions/1.0.0/file-display/README"
|
|
1021
1011
|
>
|
|
1022
1012
|
<i
|
|
1023
1013
|
class="fa fa-eye"
|
|
@@ -1034,13 +1024,13 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1034
1024
|
aria-label=""
|
|
1035
1025
|
class=" on-icon "
|
|
1036
1026
|
role="img"
|
|
1037
|
-
style="color:
|
|
1027
|
+
style="color: limegreen;"
|
|
1038
1028
|
>
|
|
1039
1029
|
<i
|
|
1040
|
-
class="
|
|
1030
|
+
class="fab fa-node-js"
|
|
1041
1031
|
/>
|
|
1042
1032
|
</span>
|
|
1043
|
-
|
|
1033
|
+
T1w.json
|
|
1044
1034
|
<span
|
|
1045
1035
|
class="filetree-editfile"
|
|
1046
1036
|
>
|
|
@@ -1050,7 +1040,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1050
1040
|
<span
|
|
1051
1041
|
class=" "
|
|
1052
1042
|
data-flow="up"
|
|
1053
|
-
data-tooltip="Download:
|
|
1043
|
+
data-tooltip="Download: 196B"
|
|
1054
1044
|
>
|
|
1055
1045
|
<span
|
|
1056
1046
|
class="edit-file download-file"
|
|
@@ -1058,7 +1048,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1058
1048
|
<a
|
|
1059
1049
|
aria-label="download file"
|
|
1060
1050
|
download=""
|
|
1061
|
-
href="/crn/datasets/ds001032/snapshots/1.0.0/files/
|
|
1051
|
+
href="/crn/datasets/ds001032/snapshots/1.0.0/files/T1w.json"
|
|
1062
1052
|
>
|
|
1063
1053
|
<i
|
|
1064
1054
|
class="fa fa-download"
|
|
@@ -1077,7 +1067,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1077
1067
|
>
|
|
1078
1068
|
<a
|
|
1079
1069
|
aria-label="view file"
|
|
1080
|
-
href="/datasets/ds001032/versions/1.0.0/file-display/
|
|
1070
|
+
href="/datasets/ds001032/versions/1.0.0/file-display/T1w.json"
|
|
1081
1071
|
>
|
|
1082
1072
|
<i
|
|
1083
1073
|
class="fa fa-eye"
|
|
@@ -1094,13 +1084,13 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1094
1084
|
aria-label=""
|
|
1095
1085
|
class=" on-icon "
|
|
1096
1086
|
role="img"
|
|
1097
|
-
style="color:
|
|
1087
|
+
style="color: limegreen;"
|
|
1098
1088
|
>
|
|
1099
1089
|
<i
|
|
1100
|
-
class="fab fa-
|
|
1090
|
+
class="fab fa-node-js"
|
|
1101
1091
|
/>
|
|
1102
1092
|
</span>
|
|
1103
|
-
|
|
1093
|
+
dataset_description.json
|
|
1104
1094
|
<span
|
|
1105
1095
|
class="filetree-editfile"
|
|
1106
1096
|
>
|
|
@@ -1110,7 +1100,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1110
1100
|
<span
|
|
1111
1101
|
class=" "
|
|
1112
1102
|
data-flow="up"
|
|
1113
|
-
data-tooltip="Download:
|
|
1103
|
+
data-tooltip="Download: 172B"
|
|
1114
1104
|
>
|
|
1115
1105
|
<span
|
|
1116
1106
|
class="edit-file download-file"
|
|
@@ -1118,7 +1108,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1118
1108
|
<a
|
|
1119
1109
|
aria-label="download file"
|
|
1120
1110
|
download=""
|
|
1121
|
-
href="/crn/datasets/ds001032/snapshots/1.0.0/files/
|
|
1111
|
+
href="/crn/datasets/ds001032/snapshots/1.0.0/files/dataset_description.json"
|
|
1122
1112
|
>
|
|
1123
1113
|
<i
|
|
1124
1114
|
class="fa fa-download"
|
|
@@ -1137,7 +1127,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1137
1127
|
>
|
|
1138
1128
|
<a
|
|
1139
1129
|
aria-label="view file"
|
|
1140
|
-
href="/datasets/ds001032/versions/1.0.0/file-display/
|
|
1130
|
+
href="/datasets/ds001032/versions/1.0.0/file-display/dataset_description.json"
|
|
1141
1131
|
>
|
|
1142
1132
|
<i
|
|
1143
1133
|
class="fa fa-eye"
|
|
@@ -1154,13 +1144,13 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1154
1144
|
aria-label=""
|
|
1155
1145
|
class=" on-icon "
|
|
1156
1146
|
role="img"
|
|
1157
|
-
style="color:
|
|
1147
|
+
style="color: lightgreen;"
|
|
1158
1148
|
>
|
|
1159
1149
|
<i
|
|
1160
|
-
class="
|
|
1150
|
+
class="fas fa-file-excel"
|
|
1161
1151
|
/>
|
|
1162
1152
|
</span>
|
|
1163
|
-
|
|
1153
|
+
participants.tsv
|
|
1164
1154
|
<span
|
|
1165
1155
|
class="filetree-editfile"
|
|
1166
1156
|
>
|
|
@@ -1170,7 +1160,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1170
1160
|
<span
|
|
1171
1161
|
class=" "
|
|
1172
1162
|
data-flow="up"
|
|
1173
|
-
data-tooltip="Download:
|
|
1163
|
+
data-tooltip="Download: 36B"
|
|
1174
1164
|
>
|
|
1175
1165
|
<span
|
|
1176
1166
|
class="edit-file download-file"
|
|
@@ -1178,7 +1168,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1178
1168
|
<a
|
|
1179
1169
|
aria-label="download file"
|
|
1180
1170
|
download=""
|
|
1181
|
-
href="/crn/datasets/ds001032/snapshots/1.0.0/files/
|
|
1171
|
+
href="/crn/datasets/ds001032/snapshots/1.0.0/files/participants.tsv"
|
|
1182
1172
|
>
|
|
1183
1173
|
<i
|
|
1184
1174
|
class="fa fa-download"
|
|
@@ -1197,7 +1187,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1197
1187
|
>
|
|
1198
1188
|
<a
|
|
1199
1189
|
aria-label="view file"
|
|
1200
|
-
href="/datasets/ds001032/versions/1.0.0/file-display/
|
|
1190
|
+
href="/datasets/ds001032/versions/1.0.0/file-display/participants.tsv"
|
|
1201
1191
|
>
|
|
1202
1192
|
<i
|
|
1203
1193
|
class="fa fa-eye"
|
|
@@ -1233,13 +1223,8 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1233
1223
|
<div
|
|
1234
1224
|
class="accordion-content"
|
|
1235
1225
|
>
|
|
1236
|
-
<div
|
|
1237
|
-
|
|
1238
|
-
>
|
|
1239
|
-
<div
|
|
1240
|
-
class="css-b1x83q"
|
|
1241
|
-
style="width: 0%;"
|
|
1242
|
-
/>
|
|
1226
|
+
<div>
|
|
1227
|
+
Loading...
|
|
1243
1228
|
</div>
|
|
1244
1229
|
</div>
|
|
1245
1230
|
</div>
|
|
@@ -1271,13 +1256,8 @@ OCI-1131441 (R. Poldrack, PI) in any publications.
|
|
|
1271
1256
|
<div
|
|
1272
1257
|
class="accordion-content"
|
|
1273
1258
|
>
|
|
1274
|
-
<div
|
|
1275
|
-
|
|
1276
|
-
>
|
|
1277
|
-
<div
|
|
1278
|
-
class="css-b1x83q"
|
|
1279
|
-
style="width: 0%;"
|
|
1280
|
-
/>
|
|
1259
|
+
<div>
|
|
1260
|
+
Loading...
|
|
1281
1261
|
</div>
|
|
1282
1262
|
</div>
|
|
1283
1263
|
</div>
|
|
@@ -40,30 +40,90 @@ class DownloadAbortError extends Error {
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
let downloadCanceled
|
|
44
|
+
|
|
43
45
|
/**
|
|
44
|
-
*
|
|
45
|
-
* @param {string} datasetId Accession number string for a dataset
|
|
46
|
-
* @param {string} snapshotTag Snapshot tag name
|
|
46
|
+
* Recursive download for file trees via browser file access API
|
|
47
47
|
*/
|
|
48
|
-
|
|
48
|
+
const downloadTree = async (
|
|
49
|
+
{ datasetId, snapshotTag, client, apmTransaction, dirHandle, toastId },
|
|
50
|
+
path = '',
|
|
51
|
+
tree = null,
|
|
52
|
+
) => {
|
|
49
53
|
const filesToDownload = await downloadDataset(client)({
|
|
50
54
|
datasetId,
|
|
51
55
|
snapshotTag,
|
|
56
|
+
tree,
|
|
52
57
|
})
|
|
58
|
+
for (const [index, file] of filesToDownload.entries()) {
|
|
59
|
+
const downloadPath = path ? `${path}/${file.filename}` : file.filename
|
|
60
|
+
if (file.directory) {
|
|
61
|
+
// Next tree level
|
|
62
|
+
await downloadTree(
|
|
63
|
+
{
|
|
64
|
+
datasetId,
|
|
65
|
+
snapshotTag,
|
|
66
|
+
client,
|
|
67
|
+
apmTransaction,
|
|
68
|
+
dirHandle,
|
|
69
|
+
toastId,
|
|
70
|
+
},
|
|
71
|
+
downloadPath,
|
|
72
|
+
file.id,
|
|
73
|
+
)
|
|
74
|
+
} else {
|
|
75
|
+
// Regular file
|
|
76
|
+
if (downloadCanceled) {
|
|
77
|
+
throw new DownloadAbortError('Download canceled by user request')
|
|
78
|
+
}
|
|
79
|
+
const fileHandle = await openFileTree(
|
|
80
|
+
dirHandle,
|
|
81
|
+
path ? `${path}/${file.filename}` : file.filename,
|
|
82
|
+
)
|
|
83
|
+
// Skip files which are already complete
|
|
84
|
+
if (fileHandle.size == file.size) continue
|
|
85
|
+
const writable = await fileHandle.createWritable()
|
|
86
|
+
const { body, status, statusText } = await fetch(file.urls.pop())
|
|
87
|
+
let loaded = 0
|
|
88
|
+
const progress = new TransformStream({
|
|
89
|
+
transform(chunk, controller) {
|
|
90
|
+
downloadToastUpdate(toastId, loaded / file.size, {
|
|
91
|
+
datasetId,
|
|
92
|
+
snapshotTag,
|
|
93
|
+
downloadPath,
|
|
94
|
+
dirName: dirHandle.name,
|
|
95
|
+
})
|
|
96
|
+
loaded += chunk.length
|
|
97
|
+
controller.enqueue(chunk)
|
|
98
|
+
},
|
|
99
|
+
})
|
|
100
|
+
if (status === 200) {
|
|
101
|
+
await body.pipeThrough(progress).pipeTo(writable)
|
|
102
|
+
} else {
|
|
103
|
+
apmTransaction.captureError(statusText)
|
|
104
|
+
return requestFailureToast(file.filename)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
53
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Downloads a dataset via the native file API, skipping expensive compression if the browser supports it
|
|
112
|
+
* @param {string} datasetId Accession number string for a dataset
|
|
113
|
+
* @param {string} snapshotTag Snapshot tag name
|
|
114
|
+
*/
|
|
115
|
+
export const downloadNative = (datasetId, snapshotTag, client) => async () => {
|
|
54
116
|
// Try trackDownload but don't worry if it fails
|
|
55
117
|
try {
|
|
56
118
|
trackDownload(client, datasetId, snapshotTag)
|
|
57
119
|
} catch (err) {
|
|
58
120
|
apm.captureError(err)
|
|
59
121
|
}
|
|
60
|
-
const apmTransaction =
|
|
61
|
-
`download:${datasetId}`,
|
|
62
|
-
'download',
|
|
63
|
-
)
|
|
122
|
+
const apmTransaction =
|
|
123
|
+
apm && apm.startTransaction(`download:${datasetId}`, 'download')
|
|
64
124
|
if (apmTransaction)
|
|
65
125
|
apmTransaction.addLabels({ datasetId, snapshot: snapshotTag })
|
|
66
|
-
|
|
126
|
+
downloadCanceled = false
|
|
67
127
|
let toastId
|
|
68
128
|
try {
|
|
69
129
|
const apmSelect =
|
|
@@ -77,27 +137,14 @@ export const downloadNative = (datasetId, snapshotTag, client) => async () => {
|
|
|
77
137
|
() => (downloadCanceled = true),
|
|
78
138
|
)
|
|
79
139
|
apmSelect && apmSelect.end()
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
// Skip files which are already complete
|
|
89
|
-
if (fileHandle.size == file.size) continue
|
|
90
|
-
const writable = await fileHandle.createWritable()
|
|
91
|
-
const { body, status, statusText } = await fetch(file.urls.pop())
|
|
92
|
-
if (status === 200) {
|
|
93
|
-
await body.pipeTo(writable)
|
|
94
|
-
} else {
|
|
95
|
-
apmDownload && apmDownload.captureError(statusText)
|
|
96
|
-
return requestFailureToast()
|
|
97
|
-
}
|
|
98
|
-
apmDownload && apmDownload.end()
|
|
99
|
-
downloadToastUpdate(toastId, index / filesToDownload.length)
|
|
100
|
-
}
|
|
140
|
+
await downloadTree({
|
|
141
|
+
datasetId,
|
|
142
|
+
snapshotTag,
|
|
143
|
+
client,
|
|
144
|
+
apmTransaction,
|
|
145
|
+
dirHandle,
|
|
146
|
+
toastId,
|
|
147
|
+
})
|
|
101
148
|
downloadCompleteToast(dirHandle.name)
|
|
102
149
|
} catch (err) {
|
|
103
150
|
if (err.name === 'AbortError') {
|
|
@@ -2,13 +2,14 @@ import { datasets } from '@openneuro/client'
|
|
|
2
2
|
|
|
3
3
|
export const downloadDataset =
|
|
4
4
|
client =>
|
|
5
|
-
async ({ datasetId, snapshotTag }) => {
|
|
5
|
+
async ({ datasetId, snapshotTag, tree = null }) => {
|
|
6
6
|
if (snapshotTag) {
|
|
7
7
|
const { data } = await client.query({
|
|
8
8
|
query: datasets.downloadSnapshot,
|
|
9
9
|
variables: {
|
|
10
10
|
datasetId,
|
|
11
11
|
tag: snapshotTag,
|
|
12
|
+
tree: tree,
|
|
12
13
|
},
|
|
13
14
|
})
|
|
14
15
|
return data.snapshot.files
|
|
@@ -17,6 +18,7 @@ export const downloadDataset =
|
|
|
17
18
|
query: datasets.downloadDataset,
|
|
18
19
|
variables: {
|
|
19
20
|
datasetId,
|
|
21
|
+
tree,
|
|
20
22
|
},
|
|
21
23
|
})
|
|
22
24
|
return data.dataset.draft.files
|
|
@@ -41,10 +41,13 @@ export const nativeErrorToast = () => {
|
|
|
41
41
|
)
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export const requestFailureToast =
|
|
44
|
+
export const requestFailureToast = filename => {
|
|
45
45
|
toast.error(
|
|
46
46
|
<ToastContent title="Download Error" body="A file failed to download">
|
|
47
|
-
<p>
|
|
47
|
+
<p>
|
|
48
|
+
{filename} failed. Retry your download to reattempt downloading this
|
|
49
|
+
file.
|
|
50
|
+
</p>
|
|
48
51
|
</ToastContent>,
|
|
49
52
|
)
|
|
50
53
|
}
|
|
@@ -70,8 +73,8 @@ export const downloadCompleteToast = dirName => {
|
|
|
70
73
|
*/
|
|
71
74
|
export const downloadToast = (dirName, datasetId, snapshotId, onClose) => {
|
|
72
75
|
const downloadMessage = snapshotId
|
|
73
|
-
?
|
|
74
|
-
:
|
|
76
|
+
? `${datasetId} snapshot ${snapshotId} to local folder ${dirName}`
|
|
77
|
+
: `${datasetId} to local folder ${dirName}`
|
|
75
78
|
return toast(
|
|
76
79
|
<ToastContent title={'Downloading'} body={downloadMessage}></ToastContent>,
|
|
77
80
|
{
|
|
@@ -84,7 +87,22 @@ export const downloadToast = (dirName, datasetId, snapshotId, onClose) => {
|
|
|
84
87
|
)
|
|
85
88
|
}
|
|
86
89
|
|
|
87
|
-
export const downloadToastUpdate = (
|
|
88
|
-
|
|
90
|
+
export const downloadToastUpdate = (
|
|
91
|
+
toastId,
|
|
92
|
+
progress,
|
|
93
|
+
{ datasetId, snapshotTag, downloadPath, dirName },
|
|
94
|
+
) => {
|
|
95
|
+
const downloadMessage = snapshotTag
|
|
96
|
+
? `${datasetId} snapshot ${snapshotTag} to local folder ${dirName}`
|
|
97
|
+
: `${datasetId} to local folder ${dirName}`
|
|
98
|
+
toast.update(toastId, {
|
|
99
|
+
render: (
|
|
100
|
+
<ToastContent title={'Downloading'} body={downloadMessage}>
|
|
101
|
+
{downloadPath}
|
|
102
|
+
</ToastContent>
|
|
103
|
+
),
|
|
104
|
+
progress,
|
|
105
|
+
})
|
|
106
|
+
}
|
|
89
107
|
|
|
90
108
|
export const downloadToastDone = toastId => toast.done(toastId)
|
|
@@ -32,37 +32,25 @@ describe('FileTreeUnloadedDirectory component', () => {
|
|
|
32
32
|
const dir = { filename: 'sub-01', directory: true }
|
|
33
33
|
const a = { id: '1234', filename: 'a', directory: false }
|
|
34
34
|
const b = { id: '5678', filename: 'b', directory: false }
|
|
35
|
-
const c = { id: '91011', filename: '
|
|
35
|
+
const c = { id: '91011', filename: 'c', directory: false }
|
|
36
36
|
const defaultObj = { dataset: { draft: { files: [a, b] } } }
|
|
37
37
|
const updatedObj = { dataset: { draft: { files: [c] } } }
|
|
38
38
|
expect(
|
|
39
39
|
mergeNewFiles(dir)(defaultObj, { fetchMoreResult: updatedObj }).dataset
|
|
40
40
|
.draft.files,
|
|
41
|
-
).toEqual([a, b, c])
|
|
42
|
-
})
|
|
43
|
-
it('removes the existing directory facade when merging lists', () => {
|
|
44
|
-
const dir = { filename: 'sub-01', directory: true }
|
|
45
|
-
const a = { id: '1234', filename: 'a', directory: false }
|
|
46
|
-
const b = { id: '5678', filename: 'b', directory: false }
|
|
47
|
-
const c = { id: '91011', filename: 'sub-01/c', directory: false }
|
|
48
|
-
const defaultObj = { dataset: { draft: { files: [dir, a, b] } } }
|
|
49
|
-
const updatedObj = { dataset: { draft: { files: [c] } } }
|
|
50
|
-
expect(
|
|
51
|
-
mergeNewFiles(dir)(defaultObj, { fetchMoreResult: updatedObj }).dataset
|
|
52
|
-
.draft.files,
|
|
53
|
-
).toEqual([a, b, c])
|
|
41
|
+
).toEqual([a, b, { ...c, filename: 'sub-01:c' }])
|
|
54
42
|
})
|
|
55
43
|
it('works with snapshots', () => {
|
|
56
44
|
const dir = { filename: 'sub-01', directory: true }
|
|
57
45
|
const a = { id: '1234', filename: 'a', directory: false }
|
|
58
46
|
const b = { id: '5678', filename: 'b', directory: false }
|
|
59
|
-
const c = { id: '91011', filename: '
|
|
47
|
+
const c = { id: '91011', filename: 'c', directory: false }
|
|
60
48
|
const defaultObj = { snapshot: { files: [dir, a, b] } }
|
|
61
49
|
const updatedObj = { snapshot: { files: [c] } }
|
|
62
50
|
expect(
|
|
63
51
|
mergeNewFiles(dir, '1.0.0')(defaultObj, { fetchMoreResult: updatedObj })
|
|
64
52
|
.snapshot.files,
|
|
65
|
-
).toEqual([a, b, c])
|
|
53
|
+
).toEqual([dir, a, b, { ...c, filename: 'sub-01:c' }])
|
|
66
54
|
})
|
|
67
55
|
})
|
|
68
56
|
})
|