@opencloning/ui 1.9.2 → 2.0.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/CHANGELOG.md +61 -0
- package/package.json +5 -6
- package/src/components/CloningSpeedDial.jsx +3 -5
- package/src/components/EditSequenceNameDialog.jsx +3 -5
- package/src/components/ExternalServicesStatusCheck.jsx +3 -5
- package/src/components/LoadCloningHistoryWrapper.jsx +5 -7
- package/src/components/assembler/Assembler.jsx +4 -6
- package/src/components/assembler/ExistingSyntaxDialog.jsx +2 -2
- package/src/components/assembler/useAssembler.js +6 -8
- package/src/components/domesticate/DomesticateDialog.jsx +3 -5
- package/src/components/form/EnzymeMultiSelect.jsx +3 -5
- package/src/components/navigation/MainAppBar.jsx +4 -2
- package/src/components/navigation/SelectTemplateDialog.jsx +4 -2
- package/src/components/primers/primer_design/SequenceTabComponents/hooks/useDesignPrimers.js +4 -6
- package/src/components/primers/primer_details/usePrimerDetailsEndpoints.js +4 -6
- package/src/components/sources/CollectionSource.jsx +2 -2
- package/src/components/sources/Source.jsx +32 -32
- package/src/components/sources/SourceAnnotation.jsx +2 -2
- package/src/components/sources/SourceAssembly.jsx +7 -7
- package/src/components/sources/SourceDatabase.jsx +2 -2
- package/src/components/sources/SourceFile.jsx +2 -2
- package/src/components/sources/SourceGenomeRegion.cy.jsx +46 -0
- package/src/components/sources/SourceGenomeRegion.jsx +29 -15
- package/src/components/sources/SourceHomologousRecombination.jsx +3 -3
- package/src/components/sources/SourceKnownGenomeRegion.jsx +3 -3
- package/src/components/sources/SourceManuallyTyped.jsx +2 -2
- package/src/components/sources/SourcePCRorHybridization.jsx +3 -3
- package/src/components/sources/SourcePolymeraseExtension.jsx +2 -2
- package/src/components/sources/SourceRepositoryId.jsx +4 -4
- package/src/components/sources/SourceRestriction.jsx +2 -2
- package/src/components/sources/SourceReverseComplement.jsx +2 -2
- package/src/components/sources/SourceServerStaticFile.jsx +3 -3
- package/src/components/verification/VerificationFileDialog.cy.jsx +17 -21
- package/src/components/verification/VerificationFileDialog.jsx +12 -11
- package/src/hooks/index.js +1 -2
- package/src/hooks/useBackendHttpClient.js +17 -0
- package/src/hooks/useCloningHistoryLoader.js +5 -7
- package/src/hooks/useGatewaySites.js +3 -5
- package/src/hooks/useInitializeApp.js +3 -4
- package/src/hooks/useLoadDatabaseFile.js +2 -2
- package/src/hooks/useSequencingAlignment.js +4 -6
- package/src/hooks/useServerStaticFiles.js +2 -2
- package/src/hooks/{useBackendAPI.js → useSourceRequest.js} +6 -8
- package/src/hooks/useStoreEditor.js +2 -1
- package/src/hooks/useUrlParamsLoader.js +8 -5
- package/src/hooks/useValidateState.js +4 -6
- package/src/version.js +1 -1
- package/src/hooks/useBackendRoute.js +0 -23
- package/src/hooks/useHttpClient.js +0 -20
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,66 @@
|
|
|
1
1
|
# @opencloning/ui
|
|
2
2
|
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#778](https://github.com/OpenCloning/OpenCloning_frontend/pull/778) [`fe1d81c`](https://github.com/OpenCloning/OpenCloning_frontend/commit/fe1d81c6f4b85f6317a2a9e46cc68c571c79c394) Thanks [@manulera](https://github.com/manulera)! - Only send the auth token to the backend, and rename the http client APIs.
|
|
8
|
+
|
|
9
|
+
- `@opencloning/utils`: `@opencloning/utils/httpClients` exports `getBackendHttpClient(backendUrl, { authenticated })`, a client that can only reach the backend (`allowAbsoluteUrls: false`) and is the only one carrying the auth token, and `getExternalHttpClient()` for whitelisted external urls. Replaces `@opencloning/utils/getHttpClient` (`getHttpClient`, `getAuthenticatedHttpClient`). `attachAuthInterceptors` refuses clients that could send the token elsewhere.
|
|
10
|
+
- `@opencloning/ui` (breaking): `useHttpClient` is renamed `useBackendHttpClient` and takes urls relative to `backendUrl`; `useBackendRoute` is removed; `useBackendAPI` is renamed `useSourceRequest` and `sendPostRequest` is renamed `sendSourceRequest`.
|
|
11
|
+
- `@opencloning/opencloningdb`, `@opencloning/opencloning-elabftw`: clients can no longer be pointed at other hosts.
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [#778](https://github.com/OpenCloning/OpenCloning_frontend/pull/778) [`fe1d81c`](https://github.com/OpenCloning/OpenCloning_frontend/commit/fe1d81c6f4b85f6317a2a9e46cc68c571c79c394) Thanks [@manulera](https://github.com/manulera)! - Encode values interpolated into request URL paths to prevent client-side path traversal. A sample UID such as `../workspaces/1/users/5` could make a user's own request hit a different endpoint, e.g. "delete UID" removing a workspace member.
|
|
16
|
+
|
|
17
|
+
- `@opencloning/utils`: new `encodePathSegment` (`@opencloning/utils/urlUtils`), which applies `encodeURIComponent` and rejects `.` and `..`.
|
|
18
|
+
- `@opencloning/opencloningdb`: all path parameters in `endpoints.js` are encoded.
|
|
19
|
+
- `@opencloning/opencloning-elabftw`: eLabFTW item and upload paths are encoded.
|
|
20
|
+
- `@opencloning/ui`: the `example`, `key` and `template` URL parameters are encoded when loading examples and templates.
|
|
21
|
+
|
|
22
|
+
- Updated dependencies [[`fe1d81c`](https://github.com/OpenCloning/OpenCloning_frontend/commit/fe1d81c6f4b85f6317a2a9e46cc68c571c79c394), [`fe1d81c`](https://github.com/OpenCloning/OpenCloning_frontend/commit/fe1d81c6f4b85f6317a2a9e46cc68c571c79c394), [`fe1d81c`](https://github.com/OpenCloning/OpenCloning_frontend/commit/fe1d81c6f4b85f6317a2a9e46cc68c571c79c394)]:
|
|
23
|
+
- @opencloning/utils@2.0.0
|
|
24
|
+
- @opencloning/store@2.0.0
|
|
25
|
+
|
|
26
|
+
## 1.10.0
|
|
27
|
+
|
|
28
|
+
### Minor Changes
|
|
29
|
+
|
|
30
|
+
- [#773](https://github.com/OpenCloning/OpenCloning_frontend/pull/773) [`f7f376e`](https://github.com/OpenCloning/OpenCloning_frontend/commit/f7f376ee351d9b2da52413700836dc55ba54b5ea) Thanks [@manulera](https://github.com/manulera)! - Handle failed NCBI request to `dataset_report` in `SourceGenomeRegion`.
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- Updated dependencies []:
|
|
35
|
+
- @opencloning/store@1.10.0
|
|
36
|
+
- @opencloning/utils@1.10.0
|
|
37
|
+
|
|
38
|
+
## 1.9.5
|
|
39
|
+
|
|
40
|
+
### Patch Changes
|
|
41
|
+
|
|
42
|
+
- Updated dependencies [[`73363e7`](https://github.com/OpenCloning/OpenCloning_frontend/commit/73363e7a7f7e494e20a54bd87e5dba97f8a9197e)]:
|
|
43
|
+
- @opencloning/utils@1.9.5
|
|
44
|
+
- @opencloning/store@1.9.5
|
|
45
|
+
|
|
46
|
+
## 1.9.4
|
|
47
|
+
|
|
48
|
+
### Patch Changes
|
|
49
|
+
|
|
50
|
+
- Updated dependencies []:
|
|
51
|
+
- @opencloning/store@1.9.4
|
|
52
|
+
- @opencloning/utils@1.9.4
|
|
53
|
+
|
|
54
|
+
## 1.9.3
|
|
55
|
+
|
|
56
|
+
### Patch Changes
|
|
57
|
+
|
|
58
|
+
- [#762](https://github.com/OpenCloning/OpenCloning_frontend/pull/762) [`df69a1b`](https://github.com/OpenCloning/OpenCloning_frontend/commit/df69a1bfb3b3128e93d89eef48a29f81a54ebb82) Thanks [@manulera](https://github.com/manulera)! - Fix QuotaExceededError when adding more than ~10 AB1/sequencing files (OpenCloning/OpenCloning#82). The raw contents of the verification files used to be persisted in Web Storage (localStorage, later sessionStorage), which has a quota of ~5 MB, so submitting around 10+ AB1 files failed with `QuotaExceededError` and the files/alignments disappeared. The contents are now kept in an in-memory store for the duration of the tab session, which has no quota.
|
|
59
|
+
|
|
60
|
+
- Updated dependencies [[`df69a1b`](https://github.com/OpenCloning/OpenCloning_frontend/commit/df69a1bfb3b3128e93d89eef48a29f81a54ebb82)]:
|
|
61
|
+
- @opencloning/utils@1.9.3
|
|
62
|
+
- @opencloning/store@1.9.3
|
|
63
|
+
|
|
3
64
|
## 1.9.2
|
|
4
65
|
|
|
5
66
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"license": "MIT",
|
|
3
3
|
"name": "@opencloning/ui",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
7
7
|
"scripts": {
|
|
@@ -25,8 +25,7 @@
|
|
|
25
25
|
"./hooks/useAlerts": "./src/hooks/useAlerts.js",
|
|
26
26
|
"./hooks/useCloningAlerts": "./src/hooks/useCloningAlerts.js",
|
|
27
27
|
"./hooks/useSequencingAlignment": "./src/hooks/useSequencingAlignment.js",
|
|
28
|
-
"./hooks/
|
|
29
|
-
"./hooks/useHttpClient": "./src/hooks/useHttpClient.js",
|
|
28
|
+
"./hooks/useBackendHttpClient": "./src/hooks/useBackendHttpClient.js",
|
|
30
29
|
"./components/SequenceViewer": "./src/components/SequenceViewer.jsx",
|
|
31
30
|
"./standalone": "./src/StandAloneOpenCloning.js"
|
|
32
31
|
},
|
|
@@ -41,14 +40,14 @@
|
|
|
41
40
|
"@mui/icons-material": "^5.18.0",
|
|
42
41
|
"@mui/material": "^5.18.0",
|
|
43
42
|
"@mui/x-data-grid": "^8.28.5",
|
|
44
|
-
"@opencloning/store": "
|
|
45
|
-
"@opencloning/utils": "
|
|
43
|
+
"@opencloning/store": "2.0.0",
|
|
44
|
+
"@opencloning/utils": "2.0.0",
|
|
46
45
|
"@teselagen/bio-parsers": "^0.4.38",
|
|
47
46
|
"@teselagen/ove": "^0.8.42",
|
|
48
47
|
"@teselagen/range-utils": "^0.3.20",
|
|
49
48
|
"@teselagen/sequence-utils": "^0.3.42",
|
|
50
49
|
"@zip.js/zip.js": "^2.8.26",
|
|
51
|
-
"axios": "^1.
|
|
50
|
+
"axios": "^1.20.0",
|
|
52
51
|
"lodash-es": "^4.18.1",
|
|
53
52
|
"react-draggable": "^4.5.0"
|
|
54
53
|
},
|
|
@@ -7,8 +7,7 @@ import { getSequencesNotInDatabase } from '@opencloning/utils/network';
|
|
|
7
7
|
import { cloningActions } from '@opencloning/store/cloning';
|
|
8
8
|
import useCloningAlerts from '../hooks/useCloningAlerts';
|
|
9
9
|
import { cloneDeep } from 'lodash-es';
|
|
10
|
-
import
|
|
11
|
-
import useHttpClient from '../hooks/useHttpClient';
|
|
10
|
+
import useBackendHttpClient from '../hooks/useBackendHttpClient';
|
|
12
11
|
|
|
13
12
|
const { setState: setCloningState } = cloningActions;
|
|
14
13
|
|
|
@@ -17,9 +16,8 @@ function useLocateSequencesInDatabaseAction() {
|
|
|
17
16
|
const database = useDatabase();
|
|
18
17
|
const store = useStore();
|
|
19
18
|
const dispatch = useDispatch();
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const url = backendRoute('normalize_cloning_strategy');
|
|
19
|
+
const httpClient = useBackendHttpClient();
|
|
20
|
+
const url = 'normalize_cloning_strategy';
|
|
23
21
|
|
|
24
22
|
const { addAlert } = useCloningAlerts();
|
|
25
23
|
const main = React.useCallback(async () => {
|
|
@@ -4,16 +4,14 @@ import { useDispatch, useSelector, useStore } from 'react-redux';
|
|
|
4
4
|
import { isEqual } from 'lodash-es';
|
|
5
5
|
import { cloningActions } from '@opencloning/store/cloning';
|
|
6
6
|
import error2String from '@opencloning/utils/error2String';
|
|
7
|
-
import
|
|
8
|
-
import useHttpClient from '../hooks/useHttpClient';
|
|
7
|
+
import useBackendHttpClient from '../hooks/useBackendHttpClient';
|
|
9
8
|
|
|
10
9
|
function EditSequenceNameDialog({ id, dialogOpen, setDialogOpen }) {
|
|
11
10
|
const [name, setName] = React.useState('');
|
|
12
11
|
const [originalName, setOriginalName] = React.useState('');
|
|
13
12
|
const [error, setError] = React.useState('');
|
|
14
13
|
const store = useStore();
|
|
15
|
-
const
|
|
16
|
-
const httpClient = useHttpClient();
|
|
14
|
+
const httpClient = useBackendHttpClient();
|
|
17
15
|
|
|
18
16
|
const { updateSequenceAndItsSource } = cloningActions;
|
|
19
17
|
const dispatch = useDispatch();
|
|
@@ -23,7 +21,7 @@ function EditSequenceNameDialog({ id, dialogOpen, setDialogOpen }) {
|
|
|
23
21
|
const source = sources.find((s) => s.id === id);
|
|
24
22
|
const sequence = sequences.find((s) => s.id === id);
|
|
25
23
|
setError('');
|
|
26
|
-
const url =
|
|
24
|
+
const url = 'rename_sequence';
|
|
27
25
|
try {
|
|
28
26
|
const { data: newSequence } = await httpClient.post(url, sequence, { params: { name } });
|
|
29
27
|
const newSource = { ...source, output_name: newName };
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Alert, Button, CircularProgress } from '@mui/material';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { useDispatch } from 'react-redux';
|
|
4
|
-
import
|
|
5
|
-
import useHttpClient from '../hooks/useHttpClient';
|
|
4
|
+
import useBackendHttpClient from '../hooks/useBackendHttpClient';
|
|
6
5
|
import { cloningActions } from '@opencloning/store/cloning';
|
|
7
6
|
import { version } from '../index';
|
|
8
7
|
|
|
@@ -14,8 +13,7 @@ function ExternalServicesStatusCheck() {
|
|
|
14
13
|
const [loading, setLoading] = React.useState(false);
|
|
15
14
|
const [successMessage, setSuccessMessage] = React.useState('');
|
|
16
15
|
const dispatch = useDispatch();
|
|
17
|
-
const
|
|
18
|
-
const httpClient = useHttpClient();
|
|
16
|
+
const httpClient = useBackendHttpClient();
|
|
19
17
|
React.useEffect(() => {
|
|
20
18
|
dispatch(updateAppInfo({ frontendVersion: version }));
|
|
21
19
|
setLoading(true);
|
|
@@ -23,7 +21,7 @@ function ExternalServicesStatusCheck() {
|
|
|
23
21
|
const services = [
|
|
24
22
|
{
|
|
25
23
|
message: 'Backend server is down',
|
|
26
|
-
url:
|
|
24
|
+
url: 'version',
|
|
27
25
|
check: (resp) => {
|
|
28
26
|
if (resp.status === 200) {
|
|
29
27
|
const { backend_version: backendVersion, schema_version: schemaVersion } = resp.data;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { batch, useDispatch, useStore } from 'react-redux';
|
|
3
3
|
import useCloningAlerts from '../hooks/useCloningAlerts';
|
|
4
|
-
import useBackendRoute from '../hooks/useBackendRoute';
|
|
5
4
|
import useCloningHistoryLoader from '../hooks/useCloningHistoryLoader';
|
|
6
5
|
import { getEmptyPlaceholderSource } from '@opencloning/store/cloning_utils';
|
|
7
6
|
import { cloningActions } from '@opencloning/store/cloning';
|
|
8
7
|
import HistoryLoadedDialog from './HistoryLoadedDialog';
|
|
9
|
-
import
|
|
8
|
+
import useBackendHttpClient from '../hooks/useBackendHttpClient';
|
|
10
9
|
|
|
11
10
|
const { deleteSourceAndItsChildren, addSourceAndItsOutputSequence } = cloningActions;
|
|
12
11
|
|
|
13
|
-
async function processSequenceFiles(files,
|
|
12
|
+
async function processSequenceFiles(files, httpClient) {
|
|
14
13
|
const allSources = [];
|
|
15
14
|
const allSequences = [];
|
|
16
15
|
const allWarnings = [];
|
|
@@ -27,7 +26,7 @@ async function processSequenceFiles(files, backendRoute, httpClient) {
|
|
|
27
26
|
'content-type': 'multipart/form-data',
|
|
28
27
|
},
|
|
29
28
|
};
|
|
30
|
-
const url =
|
|
29
|
+
const url = 'read_from_file';
|
|
31
30
|
try {
|
|
32
31
|
const { data: { sources, sequences }, headers } = await httpClient.post(url, formData, config);
|
|
33
32
|
// If there are warnings, add them to the list of warnings
|
|
@@ -57,9 +56,8 @@ async function processSequenceFiles(files, backendRoute, httpClient) {
|
|
|
57
56
|
function LoadCloningHistoryWrapper({ fileList, clearFiles, children }) {
|
|
58
57
|
const { addAlert } = useCloningAlerts();
|
|
59
58
|
const dispatch = useDispatch();
|
|
60
|
-
const backendRoute = useBackendRoute();
|
|
61
59
|
const store = useStore();
|
|
62
|
-
const httpClient =
|
|
60
|
+
const httpClient = useBackendHttpClient();
|
|
63
61
|
const { loadHistoryFromFile, loadSnapgeneHistory } = useCloningHistoryLoader();
|
|
64
62
|
const [fileLoaderFunctions, setFileLoaderFunctions] = React.useState(null);
|
|
65
63
|
|
|
@@ -117,7 +115,7 @@ function LoadCloningHistoryWrapper({ fileList, clearFiles, children }) {
|
|
|
117
115
|
}
|
|
118
116
|
}
|
|
119
117
|
try {
|
|
120
|
-
const { sources, sequences, warnings } = await processSequenceFiles(files,
|
|
118
|
+
const { sources, sequences, warnings } = await processSequenceFiles(files, httpClient);
|
|
121
119
|
batch(() => {
|
|
122
120
|
// If there is only one source and it is empty, delete it
|
|
123
121
|
const emptyPlaceholder = getEmptyPlaceholderSource(cloningState.sources);
|
|
@@ -19,8 +19,7 @@ import useCombinatorialAssembly from './useCombinatorialAssembly';
|
|
|
19
19
|
import ExistingSyntaxDialog from './ExistingSyntaxDialog';
|
|
20
20
|
import error2String from '@opencloning/utils/error2String';
|
|
21
21
|
import { categoryFilter, downloadAssemblerFilesAsZip, getFilesToExportFromAssembler, getDefaultAssemblyOutputName, MAX_OUTPUT_NAME_LENGTH, sanitizeOutputName } from './assembler_utils';
|
|
22
|
-
import
|
|
23
|
-
import useHttpClient from '../../hooks/useHttpClient';
|
|
22
|
+
import useBackendHttpClient from '../../hooks/useBackendHttpClient';
|
|
24
23
|
import useCloningAlerts from '../../hooks/useCloningAlerts';
|
|
25
24
|
import UploadPlasmidsButton from './UploadPlasmidsButton';
|
|
26
25
|
import { useConfig } from '../../providers';
|
|
@@ -376,12 +375,11 @@ function categoriesFromSyntaxAndPlasmids(syntax, plasmids) {
|
|
|
376
375
|
|
|
377
376
|
function LoadSyntaxButton({ setSyntax, addPlasmids, clearPlasmids }) {
|
|
378
377
|
const [existingSyntaxDialogOpen, setExistingSyntaxDialogOpen] = React.useState(false)
|
|
379
|
-
const httpClient =
|
|
378
|
+
const httpClient = useBackendHttpClient();
|
|
380
379
|
const { staticContentPath } = useConfig();
|
|
381
|
-
const backendRoute = useBackendRoute();
|
|
382
380
|
const { addAlert } = useCloningAlerts();
|
|
383
381
|
const onSyntaxSelect = React.useCallback(async (syntax, plasmids) => {
|
|
384
|
-
const url =
|
|
382
|
+
const url = 'validate_syntax';
|
|
385
383
|
try {
|
|
386
384
|
await httpClient.post(url, syntax);
|
|
387
385
|
setSyntax(syntax)
|
|
@@ -393,7 +391,7 @@ function LoadSyntaxButton({ setSyntax, addPlasmids, clearPlasmids }) {
|
|
|
393
391
|
severity: 'error',
|
|
394
392
|
});
|
|
395
393
|
}
|
|
396
|
-
}, [setSyntax, addPlasmids, clearPlasmids, httpClient,
|
|
394
|
+
}, [setSyntax, addPlasmids, clearPlasmids, httpClient, addAlert])
|
|
397
395
|
return <>
|
|
398
396
|
<Button color="success" onClick={() => setExistingSyntaxDialogOpen(true)}>Load Syntax</Button>
|
|
399
397
|
{existingSyntaxDialogOpen && <ExistingSyntaxDialog
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { Dialog, DialogTitle, DialogContent, List, ListItem, ListItemText, ListItemButton, Alert, Button, Box, ButtonGroup, Accordion, AccordionSummary, AccordionDetails } from '@mui/material'
|
|
3
|
-
import
|
|
3
|
+
import { getExternalHttpClient } from '@opencloning/utils/httpClients';
|
|
4
4
|
import RequestStatusWrapper from '../form/RequestStatusWrapper';
|
|
5
5
|
import ServerStaticFileSelect from '../form/ServerStaticFileSelect';
|
|
6
6
|
import { readSubmittedTextFile } from '@opencloning/utils/readNwrite';
|
|
7
7
|
import { normalizeSyntaxEnzymes } from '@opencloning/utils/normalizeSyntax';
|
|
8
8
|
import { ExpandMore as ExpandMoreIcon } from '@mui/icons-material';
|
|
9
9
|
|
|
10
|
-
const httpClient =
|
|
10
|
+
const httpClient = getExternalHttpClient();
|
|
11
11
|
const baseURL = 'https://assets.opencloning.org/syntaxes/syntaxes/';
|
|
12
12
|
httpClient.defaults.baseURL = baseURL;
|
|
13
13
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { useCallback } from 'react'
|
|
2
2
|
import { classNameToEndPointMap } from '@opencloning/utils/sourceFunctions'
|
|
3
|
-
import
|
|
4
|
-
import useHttpClient from '../../hooks/useHttpClient'
|
|
3
|
+
import useBackendHttpClient from '../../hooks/useBackendHttpClient'
|
|
5
4
|
import { arrayCombinations } from './assembler_utils'
|
|
6
5
|
|
|
7
6
|
|
|
@@ -28,8 +27,7 @@ function formatLoadedFile(plasmid, id) {
|
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
export const useAssembler = () => {
|
|
31
|
-
const httpClient =
|
|
32
|
-
const backendRoute = useBackendRoute();
|
|
30
|
+
const httpClient = useBackendHttpClient();
|
|
33
31
|
|
|
34
32
|
const requestSources = useCallback(async (assemblerOutput) => {
|
|
35
33
|
const processedOutput = []
|
|
@@ -41,7 +39,7 @@ export const useAssembler = () => {
|
|
|
41
39
|
processedOutput[pos].push(formatLoadedFile(plasmid, pos + 1))
|
|
42
40
|
} else {
|
|
43
41
|
const { source } = plasmid;
|
|
44
|
-
const url =
|
|
42
|
+
const url = classNameToEndPointMap[source.type]
|
|
45
43
|
const {data} = await httpClient.post(url, source)
|
|
46
44
|
if (data.sources.length !== 1) {
|
|
47
45
|
console.error('Expected 1 source, got ' + data.sources.length)
|
|
@@ -59,7 +57,7 @@ export const useAssembler = () => {
|
|
|
59
57
|
}
|
|
60
58
|
}
|
|
61
59
|
return processedOutput
|
|
62
|
-
}, [ httpClient
|
|
60
|
+
}, [ httpClient ])
|
|
63
61
|
|
|
64
62
|
|
|
65
63
|
const requestAssemblies = useCallback(async (requestedSources, enzymes=['BsaI']) => {
|
|
@@ -67,7 +65,7 @@ export const useAssembler = () => {
|
|
|
67
65
|
const assemblies = arrayCombinations(requestedSources);
|
|
68
66
|
const output = []
|
|
69
67
|
for (let assembly of assemblies) {
|
|
70
|
-
const url =
|
|
68
|
+
const url = 'restriction_and_ligation'
|
|
71
69
|
const config = {
|
|
72
70
|
params: {
|
|
73
71
|
circular_only: true,
|
|
@@ -102,7 +100,7 @@ export const useAssembler = () => {
|
|
|
102
100
|
}
|
|
103
101
|
}
|
|
104
102
|
return output;
|
|
105
|
-
}, [ httpClient
|
|
103
|
+
}, [ httpClient ])
|
|
106
104
|
|
|
107
105
|
return { requestSources, requestAssemblies }
|
|
108
106
|
}
|
|
@@ -19,8 +19,7 @@ import {
|
|
|
19
19
|
TextField,
|
|
20
20
|
} from '@mui/material';
|
|
21
21
|
import error2String from '@opencloning/utils/error2String';
|
|
22
|
-
import
|
|
23
|
-
import useHttpClient from '../../hooks/useHttpClient';
|
|
22
|
+
import useBackendHttpClient from '../../hooks/useBackendHttpClient';
|
|
24
23
|
import { featureToGenbankLocationString, mergeStates } from '@opencloning/utils';
|
|
25
24
|
import { useDispatch, useStore } from 'react-redux';
|
|
26
25
|
import { cloningActions } from '@opencloning/store/cloning';
|
|
@@ -77,8 +76,7 @@ function categoryPrefixSuffixValid(category, prefix, suffix) {
|
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
export default function DomesticateDialog({ open, onClose, initialContext, mainSequenceId }) {
|
|
80
|
-
const httpClient =
|
|
81
|
-
const backendRoute = useBackendRoute();
|
|
79
|
+
const httpClient = useBackendHttpClient();
|
|
82
80
|
const store = useStore();
|
|
83
81
|
|
|
84
82
|
const location = React.useMemo(() => featureToGenbankLocationString(initialContext.annotation), [initialContext]);
|
|
@@ -131,7 +129,7 @@ export default function DomesticateDialog({ open, onClose, initialContext, mainS
|
|
|
131
129
|
enzymes,
|
|
132
130
|
};
|
|
133
131
|
try {
|
|
134
|
-
const url =
|
|
132
|
+
const url = 'batch_cloning/domesticate';
|
|
135
133
|
const { data } = await httpClient.post(url, body);
|
|
136
134
|
|
|
137
135
|
const { mergedState, idShift } = mergeStates(data, store.getState().cloning);
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import GetRequestMultiSelect from './GetRequestMultiSelect';
|
|
3
|
-
import
|
|
4
|
-
import useHttpClient from '../../hooks/useHttpClient';
|
|
3
|
+
import useBackendHttpClient from '../../hooks/useBackendHttpClient';
|
|
5
4
|
|
|
6
5
|
function EnzymeMultiSelect({ setEnzymes, label = 'Enzymes used', multiple = true }) {
|
|
7
|
-
const
|
|
8
|
-
const url = backendRoute('restriction_enzyme_list');
|
|
6
|
+
const url = 'restriction_enzyme_list';
|
|
9
7
|
const getOptionsFromResponse = React.useCallback((data) => data.enzyme_names, []);
|
|
10
8
|
const messages = React.useMemo(() => ({
|
|
11
9
|
loadingMessage: 'retrieving enzymes...',
|
|
12
10
|
errorMessage: 'Could not retrieve enzymes from server',
|
|
13
11
|
}), []);
|
|
14
12
|
const onChange = React.useCallback((value) => setEnzymes(value), [setEnzymes]);
|
|
15
|
-
const httpClient =
|
|
13
|
+
const httpClient = useBackendHttpClient();
|
|
16
14
|
|
|
17
15
|
return (
|
|
18
16
|
|
|
@@ -15,7 +15,10 @@ import DownloadCloningStrategyDialog from '../DownloadCloningStrategyDialog';
|
|
|
15
15
|
import LoadCloningHistoryWrapper from '../LoadCloningHistoryWrapper';
|
|
16
16
|
import useCloningHistoryLoader from '../../hooks/useCloningHistoryLoader';
|
|
17
17
|
import GithubCornerRight from './GithubCornerRight';
|
|
18
|
-
import
|
|
18
|
+
import { getExternalHttpClient } from '@opencloning/utils/httpClients';
|
|
19
|
+
|
|
20
|
+
// External urls (not the backend): no auth token, only whitelisted urls
|
|
21
|
+
const httpClient = getExternalHttpClient();
|
|
19
22
|
|
|
20
23
|
const { setCurrentTab } = cloningActions;
|
|
21
24
|
|
|
@@ -28,7 +31,6 @@ function MainAppBar() {
|
|
|
28
31
|
const [openVersionDialog, setOpenVersionDialog] = React.useState(false);
|
|
29
32
|
const [anchorEl, setAnchorEl] = React.useState(null);
|
|
30
33
|
const openMenu = Boolean(anchorEl);
|
|
31
|
-
const httpClient = useHttpClient();
|
|
32
34
|
|
|
33
35
|
const dispatch = useDispatch();
|
|
34
36
|
const { addAlert } = useCloningAlerts();
|
|
@@ -2,14 +2,16 @@ import { Accordion, AccordionDetails, AccordionSummary, Alert, Button, CircularP
|
|
|
2
2
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { ExpandMore as ExpandMoreIcon } from '@mui/icons-material';
|
|
5
|
-
import
|
|
5
|
+
import { getExternalHttpClient } from '@opencloning/utils/httpClients';
|
|
6
|
+
|
|
7
|
+
// External urls (not the backend): no auth token, only whitelisted urls
|
|
8
|
+
const httpClient = getExternalHttpClient();
|
|
6
9
|
|
|
7
10
|
function SelectTemplateDialog({ onClose, open }) {
|
|
8
11
|
const [templates, setTemplates] = React.useState(null);
|
|
9
12
|
const [connectAttempt, setConnectAttemp] = React.useState(0);
|
|
10
13
|
const [error, setError] = React.useState(null);
|
|
11
14
|
const baseUrl = 'https://assets.opencloning.org/OpenCloning-submission';
|
|
12
|
-
const httpClient = useHttpClient();
|
|
13
15
|
|
|
14
16
|
React.useEffect(() => {
|
|
15
17
|
const fetchData = async () => {
|
package/src/components/primers/primer_design/SequenceTabComponents/hooks/useDesignPrimers.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { useState, useCallback } from 'react';
|
|
2
2
|
import { batch, useDispatch, useStore } from 'react-redux';
|
|
3
|
-
import
|
|
4
|
-
import useHttpClient from '../../../../../hooks/useHttpClient';
|
|
3
|
+
import useBackendHttpClient from '../../../../../hooks/useBackendHttpClient';
|
|
5
4
|
import useStoreEditor from '../../../../../hooks/useStoreEditor';
|
|
6
5
|
import error2String from '@opencloning/utils/error2String';
|
|
7
6
|
import { cloningActions } from '@opencloning/store/cloning';
|
|
@@ -19,8 +18,7 @@ export default function useDesignPrimers({
|
|
|
19
18
|
|
|
20
19
|
const store = useStore();
|
|
21
20
|
const dispatch = useDispatch();
|
|
22
|
-
const
|
|
23
|
-
const httpClient = useHttpClient();
|
|
21
|
+
const httpClient = useBackendHttpClient();
|
|
24
22
|
const { updateStoreEditor } = useStoreEditor();
|
|
25
23
|
|
|
26
24
|
const designPrimers = useCallback(async () => {
|
|
@@ -43,7 +41,7 @@ export default function useDesignPrimers({
|
|
|
43
41
|
});
|
|
44
42
|
|
|
45
43
|
requestData.settings = globalPrimerSettings;
|
|
46
|
-
const url =
|
|
44
|
+
const url = `primer_design/${endpoint}`;
|
|
47
45
|
|
|
48
46
|
try {
|
|
49
47
|
const resp = await httpClient.post(url, requestData, { params });
|
|
@@ -55,7 +53,7 @@ export default function useDesignPrimers({
|
|
|
55
53
|
setError(error2String(thrownError));
|
|
56
54
|
return true;
|
|
57
55
|
}
|
|
58
|
-
}, [fragmentOrientations, rois, sequenceIds, templateSequenceIds, designType, circularAssembly, primerDesignSettings, spacers, store, httpClient,
|
|
56
|
+
}, [fragmentOrientations, rois, sequenceIds, templateSequenceIds, designType, circularAssembly, primerDesignSettings, spacers, store, httpClient, handleNext, isAmplified]);
|
|
59
57
|
|
|
60
58
|
const addPrimers = useCallback(() => {
|
|
61
59
|
const pcrSources = store.getState().cloning.sources.filter((source) => source.type === 'PCRSource');
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useCallback } from 'react';
|
|
2
|
-
import
|
|
3
|
-
import useHttpClient from '../../../hooks/useHttpClient';
|
|
2
|
+
import useBackendHttpClient from '../../../hooks/useBackendHttpClient';
|
|
4
3
|
import { isEqual } from 'lodash-es';
|
|
5
4
|
import { useSelector } from 'react-redux';
|
|
6
5
|
|
|
@@ -16,15 +15,14 @@ export function makeHeterodimerCacheKey(sequence1, sequence2, globalPrimerSettin
|
|
|
16
15
|
return `${pairKey}::${settingsKey}`;
|
|
17
16
|
}
|
|
18
17
|
export function usePrimerDetailsEndpoints() {
|
|
19
|
-
const
|
|
20
|
-
const httpClient = useHttpClient();
|
|
18
|
+
const httpClient = useBackendHttpClient();
|
|
21
19
|
const globalPrimerSettings = useSelector((state) => state.cloning.globalPrimerSettings, isEqual);
|
|
22
20
|
|
|
23
21
|
// Caches are keyed by both the input sequence(s) and the current globalPrimerSettings,
|
|
24
22
|
// so we don't need to clear them on settings change.
|
|
25
23
|
|
|
26
|
-
const url =
|
|
27
|
-
const heterodimerUrl =
|
|
24
|
+
const url = 'primer_details';
|
|
25
|
+
const heterodimerUrl = 'primer_heterodimer';
|
|
28
26
|
|
|
29
27
|
const getPrimerDetails = useCallback(async (sequence) => {
|
|
30
28
|
const cacheKey = makePrimerDetailsCacheKey(sequence, globalPrimerSettings);
|
|
@@ -7,7 +7,7 @@ import { classNameToEndPointMap } from '@opencloning/utils/sourceFunctions';
|
|
|
7
7
|
import ObjectTable from '../ObjectTable';
|
|
8
8
|
import { cloningActions } from '@opencloning/store/cloning';
|
|
9
9
|
|
|
10
|
-
function CollectionSource({ source, requestStatus,
|
|
10
|
+
function CollectionSource({ source, requestStatus, sendSourceRequest }) {
|
|
11
11
|
const { id: sourceId, options, image: imageInfo, title, description } = source;
|
|
12
12
|
const [image, imageWidth] = imageInfo || [null, null];
|
|
13
13
|
const [selectedOption, setSelectedOption] = React.useState(null);
|
|
@@ -34,7 +34,7 @@ function CollectionSource({ source, requestStatus, sendPostRequest }) {
|
|
|
34
34
|
const reverseOligo = primers.find((primer) => primer.id === selectedSource.input[1].sequence);
|
|
35
35
|
requestData = { source: { id: sourceId, ...selectedSource }, primers: [forwardOligo, reverseOligo] };
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
sendSourceRequest({ endpoint, requestData, source, modifySource });
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
const onChange = (event) => {
|
|
@@ -14,7 +14,7 @@ import SourceAnnotation from './SourceAnnotation';
|
|
|
14
14
|
import SourceDatabase from './SourceDatabase';
|
|
15
15
|
import SourcePolymeraseExtension from './SourcePolymeraseExtension';
|
|
16
16
|
import CollectionSource from './CollectionSource';
|
|
17
|
-
import
|
|
17
|
+
import useSourceRequest from '../../hooks/useSourceRequest';
|
|
18
18
|
import MultipleOutputsSelector from './MultipleOutputsSelector';
|
|
19
19
|
import { cloningActions } from '@opencloning/store/cloning';
|
|
20
20
|
import SourceCopySequence from './SourceCopySequence';
|
|
@@ -31,7 +31,7 @@ function Source({ sourceId }) {
|
|
|
31
31
|
const { type: sourceType } = source;
|
|
32
32
|
let specificSource = null;
|
|
33
33
|
const templateOnlySources = ['CollectionSource', 'KnownGenomeCoordinatesSource'];
|
|
34
|
-
const { requestStatus,
|
|
34
|
+
const { requestStatus, sendSourceRequest, sources, sequences } = useSourceRequest();
|
|
35
35
|
const { addSequenceAndUpdateItsSource, updateSequenceAndItsSource } = cloningActions;
|
|
36
36
|
const [chosenFragment, setChosenFragment] = React.useState(null);
|
|
37
37
|
const dispatch = useDispatch();
|
|
@@ -49,67 +49,67 @@ function Source({ sourceId }) {
|
|
|
49
49
|
switch (sourceType) {
|
|
50
50
|
/* eslint-disable */
|
|
51
51
|
case 'UploadedFileSource':
|
|
52
|
-
specificSource = <SourceFile {...{ source, requestStatus,
|
|
52
|
+
specificSource = <SourceFile {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
53
53
|
case 'LocalFileSource':
|
|
54
|
-
specificSource = <SourceServerStaticFile {...{ source, requestStatus,
|
|
54
|
+
specificSource = <SourceServerStaticFile {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
55
55
|
case 'RestrictionEnzymeDigestionSource':
|
|
56
|
-
specificSource = <SourceRestriction {...{ source, requestStatus,
|
|
56
|
+
specificSource = <SourceRestriction {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
57
57
|
case 'RepositoryIdSource':
|
|
58
|
-
specificSource = <SourceRepositoryId {...{ source, requestStatus,
|
|
58
|
+
specificSource = <SourceRepositoryId {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
59
59
|
case 'AddgeneIdSource':
|
|
60
|
-
specificSource = <SourceRepositoryId {...{ source, requestStatus,
|
|
60
|
+
specificSource = <SourceRepositoryId {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
61
61
|
case 'SnapGenePlasmidSource':
|
|
62
|
-
specificSource = <SourceRepositoryId {...{ source, requestStatus,
|
|
62
|
+
specificSource = <SourceRepositoryId {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
63
63
|
case 'EuroscarfSource':
|
|
64
|
-
specificSource = <SourceRepositoryId {...{ source, requestStatus,
|
|
64
|
+
specificSource = <SourceRepositoryId {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
65
65
|
case 'WekWikGeneIdSource':
|
|
66
|
-
specificSource = <SourceRepositoryId {...{ source, requestStatus,
|
|
66
|
+
specificSource = <SourceRepositoryId {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
67
67
|
case 'OpenDNACollectionsSource':
|
|
68
|
-
specificSource = <SourceRepositoryId {...{ source, requestStatus,
|
|
68
|
+
specificSource = <SourceRepositoryId {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
69
69
|
case 'LigationSource':
|
|
70
|
-
specificSource = <SourceAssembly {...{ source, requestStatus,
|
|
70
|
+
specificSource = <SourceAssembly {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
71
71
|
case 'GibsonAssemblySource':
|
|
72
|
-
specificSource = <SourceAssembly {...{ source, requestStatus,
|
|
72
|
+
specificSource = <SourceAssembly {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
73
73
|
case 'OverlapExtensionPCRLigationSource':
|
|
74
|
-
specificSource = <SourceAssembly {...{ source, requestStatus,
|
|
74
|
+
specificSource = <SourceAssembly {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
75
75
|
case 'InFusionSource':
|
|
76
|
-
specificSource = <SourceAssembly {...{ source, requestStatus,
|
|
76
|
+
specificSource = <SourceAssembly {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
77
77
|
case 'InVivoAssemblySource':
|
|
78
|
-
specificSource = <SourceAssembly {...{ source, requestStatus,
|
|
78
|
+
specificSource = <SourceAssembly {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
79
79
|
case 'GatewaySource':
|
|
80
|
-
specificSource = <SourceAssembly {...{ source, requestStatus,
|
|
80
|
+
specificSource = <SourceAssembly {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
81
81
|
case 'CreLoxRecombinationSource':
|
|
82
|
-
specificSource = <SourceAssembly {...{ source, requestStatus,
|
|
82
|
+
specificSource = <SourceAssembly {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
83
83
|
case 'RecombinaseSource':
|
|
84
|
-
specificSource = <SourceAssembly {...{ source, requestStatus,
|
|
84
|
+
specificSource = <SourceAssembly {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
85
85
|
case 'HomologousRecombinationSource':
|
|
86
|
-
specificSource = <SourceHomologousRecombination {...{ source, requestStatus,
|
|
86
|
+
specificSource = <SourceHomologousRecombination {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
87
87
|
case 'PCRSource':
|
|
88
|
-
specificSource = <SourcePCRorHybridization {...{ source, requestStatus,
|
|
88
|
+
specificSource = <SourcePCRorHybridization {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
89
89
|
case 'RestrictionAndLigationSource':
|
|
90
|
-
specificSource = <SourceAssembly {...{ source, requestStatus,
|
|
90
|
+
specificSource = <SourceAssembly {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
91
91
|
case 'GenomeCoordinatesSource':
|
|
92
|
-
specificSource = <SourceGenomeRegion {...{ source, requestStatus,
|
|
92
|
+
specificSource = <SourceGenomeRegion {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
93
93
|
case 'KnownGenomeCoordinatesSource':
|
|
94
|
-
specificSource = <SourceKnownGenomeRegion {...{ source, requestStatus,
|
|
94
|
+
specificSource = <SourceKnownGenomeRegion {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
95
95
|
case 'ManuallyTypedSource':
|
|
96
|
-
specificSource = <SourceManuallyTyped {...{ source, requestStatus,
|
|
96
|
+
specificSource = <SourceManuallyTyped {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
97
97
|
case 'CRISPRSource':
|
|
98
|
-
specificSource = <SourceHomologousRecombination {...{ source, requestStatus,
|
|
98
|
+
specificSource = <SourceHomologousRecombination {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
99
99
|
case 'OligoHybridizationSource':
|
|
100
|
-
specificSource = <SourcePCRorHybridization {...{ source, requestStatus,
|
|
100
|
+
specificSource = <SourcePCRorHybridization {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
101
101
|
case 'PolymeraseExtensionSource':
|
|
102
|
-
specificSource = <SourcePolymeraseExtension {...{ source, requestStatus,
|
|
102
|
+
specificSource = <SourcePolymeraseExtension {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
103
103
|
case 'DatabaseSource':
|
|
104
|
-
specificSource = <SourceDatabase {...{ source, requestStatus,
|
|
104
|
+
specificSource = <SourceDatabase {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
105
105
|
case 'CollectionSource':
|
|
106
|
-
specificSource = <CollectionSource {...{ source, requestStatus,
|
|
106
|
+
specificSource = <CollectionSource {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
107
107
|
case 'CopySequence':
|
|
108
108
|
specificSource = <SourceCopySequence {...{ source }} />; break;
|
|
109
109
|
case 'AnnotationSource':
|
|
110
|
-
specificSource = <SourceAnnotation {...{ source, requestStatus,
|
|
110
|
+
specificSource = <SourceAnnotation {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
111
111
|
case 'ReverseComplementSource':
|
|
112
|
-
specificSource = <SourceReverseComplement {...{ source, requestStatus,
|
|
112
|
+
specificSource = <SourceReverseComplement {...{ source, requestStatus, sendSourceRequest }} />; break;
|
|
113
113
|
default:
|
|
114
114
|
break;
|
|
115
115
|
/* eslint-enable */
|