Skip to content

Commit 8e9d59c

Browse files
committed
moved tree to assemblies tab; select first taxon on taxon picker
1 parent d702348 commit 8e9d59c

File tree

13 files changed

+134
-151
lines changed

13 files changed

+134
-151
lines changed

flask-backend/src/modules/analyses.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,7 @@ def fetchAnalysesByAssemblyID(assemblyID):
955955
# fetches busco analyses for specific assembly
956956
def fetchBuscoAnalysesByAssemblyID(assemblyID):
957957
"""
958-
Fetches all analyses for specific assembly.
958+
Fetches all busco analyses for specific assembly.
959959
"""
960960
try:
961961
connection, cursor, error = connect()

flask-backend/src/modules/assemblies.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,7 @@ def updateAssemblyLabel(assembly_id: int, label: str, userID: int):
790790
# fetches all assemblies for specific taxon
791791
def fetchAssembliesByTaxonID(taxonID):
792792
"""
793-
Fetches all assemblies for specific taxon from database.
793+
Fetches all assemblies for specific taxon by internal taxon ID.
794794
"""
795795
try:
796796
connection, cursor, error = connect()
@@ -817,7 +817,7 @@ def fetchAssembliesByTaxonID(taxonID):
817817
# FETCHES MULTIPLE ASSEMBLIES BY NCBI TAXON IDS
818818
def fetchAssembliesByTaxonIDs(taxonIDs):
819819
"""
820-
Fetches assemblies by multiple taxon ID
820+
Fetches all assemblies for multiple (internal) taxon IDs.
821821
"""
822822
try:
823823
connection, cursor, error = connect()
@@ -934,7 +934,7 @@ def fetchAssemblyTagsByAssemblyID(assemblyID):
934934
# FETCH ALL GENERAL INFOS OF SPECIFIC LEVEL
935935
def fetchAssemblyGeneralInformationByAssemblyID(assemblyID):
936936
"""
937-
Gets all general information by specific taxon ID
937+
Fetches all general information for a specific assembly ID (level: assembly)
938938
"""
939939

940940
generalInfos = []
@@ -956,7 +956,7 @@ def fetchAssemblyGeneralInformationByAssemblyID(assemblyID):
956956
# ADD GENERAL INFO
957957
def addAssemblyGeneralInformation(assemblyID, key, value):
958958
"""
959-
add general info by level and id
959+
Add general info by level and id
960960
"""
961961

962962
try:

flask-backend/src/modules/combined_imports.py

+3
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ def __getSupportedFiles(file_info, type):
146146

147147

148148
def validateFileInfo(file_info, forceType=""):
149+
"""
150+
Validates files for import!
151+
"""
149152
datasets = {}
150153
if not forceType or forceType not in FILE_PATTERN_DICT:
151154
for type in FILE_PATTERN_DICT:

flask-backend/src/modules/producer.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def __check_consumer_count(channel, route):
9494
if route == "worker":
9595
if consumer_count < int(getenv("RABBIT_WORKER_COUNT")):
9696
while consumer_count < int(getenv("RABBIT_WORKER_COUNT")):
97-
run("python3 src/worker.py &", shell=True)
97+
run("python3 worker.py &", shell=True, cwd="/flask-backend/src")
9898
consumer_count += 1
9999
elif consumer_count == int(getenv("RABBIT_WORKER_COUNT")):
100100
return 1, []

flask-backend/src/modules/taxa.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@ def fetchTaxonByTaxonID(taxonID):
321321

322322

323323
def fetchTaxonImageByTaxonID(taxonID):
324+
"""
325+
Fetches taxon image by taxon ID.
326+
"""
324327
try:
325328
connection, cursor, error = connect()
326329
cursor.execute("SELECT imagePath FROM taxa WHERE id=%s", (taxonID,))
@@ -334,7 +337,7 @@ def fetchTaxonImageByTaxonID(taxonID):
334337
# FETCH TAXA BY SEARCH STRING
335338
def fetchTaxonBySearch(search):
336339
"""
337-
Fetches taxon by taxon ID
340+
Fetches taxon by search value.
338341
"""
339342
connection, cursor, error = connect()
340343

@@ -359,7 +362,7 @@ def fetchTaxonBySearch(search):
359362
# FETCH ONE TAXON BY NCBI TAXON ID
360363
def fetchTaxonByNCBITaxonID(ncbiTaxonID):
361364
"""
362-
Fetches taxon by NCBI taxon id
365+
Fetches taxon by NCBI taxon id.
363366
"""
364367
connection, cursor, error = connect()
365368

@@ -380,7 +383,7 @@ def fetchTaxonByNCBITaxonID(ncbiTaxonID):
380383
# FETCH ALL TAXA WITH AT LEAST ONE ASSEMBLY
381384
def fetchTaxaWithAssemblies():
382385
"""
383-
Fetches taxa with at least one assembly
386+
Fetches taxa with at least one assembly.
384387
"""
385388
connection, cursor, error = connect()
386389

@@ -403,7 +406,7 @@ def fetchTaxaWithAssemblies():
403406
# FETCH ALL GENERAL INFOS OF SPECIFIC LEVEL
404407
def fetchTaxonGeneralInformationByTaxonID(taxonID):
405408
"""
406-
Gets all general information by specific taxon ID
409+
Gets all general information by specific taxon ID.
407410
"""
408411

409412
generalInfos = []

flask-backend/src/modules/users.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def validateActiveToken(userID, token):
150150
# ADD NEW USER
151151
def addUser(username, password, role):
152152
"""
153-
Add a user to db
153+
Add a user to db.
154154
"""
155155
try:
156156
connection, cursor, error = connect()

react-frontend/src/screens/MainRouter/components/AssembliesList/components/AssembliesFilterForm/index.tsx

+39-34
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ const AssembliesFilterForm = ({
2222
setFilter,
2323
isFilterOpen,
2424
}: {
25-
viewType: "grid" | "list";
26-
setViewType: Dispatch<SetStateAction<"grid" | "list">>;
25+
viewType: "grid" | "list" | "tree";
26+
setViewType: Dispatch<SetStateAction<"grid" | "list" | "tree">>;
2727
setSearch: (search: string) => void;
2828
search: string;
2929
setFilter: Dispatch<SetStateAction<Filter>>;
@@ -250,7 +250,7 @@ const AssembliesFilterForm = ({
250250
<span className="text-sm px-2">View type:</span>
251251
<select
252252
className="w-32 text-gray-700 text-center rounded-lg shadow border border-gray-300 text-sm"
253-
onChange={(e) => setViewType(e.target.value as "list" | "grid")}
253+
onChange={(e) => setViewType(e.target.value as "list" | "grid" | "tree")}
254254
value={viewType}
255255
>
256256
<option className="text-sm py-1" value="list">
@@ -259,6 +259,9 @@ const AssembliesFilterForm = ({
259259
<option className="text-sm py-1" value="grid">
260260
Grid
261261
</option>
262+
<option className="text-sm py-1" value="tree">
263+
Tree
264+
</option>
262265
</select>
263266
</label>
264267
<div className="w-96 flex items-center">
@@ -299,38 +302,40 @@ const AssembliesFilterForm = ({
299302
{toggleFilterSelection && <hr className="shadow my-6 border-gray-300 animate-grow-y" />}
300303
{toggleFilterSelection && (
301304
<div className="px-4 animate-grow-y pb-4 flex justify-around items-start">
302-
<div>
303-
Taxon
304-
<hr className="shadow border-gray-300 -mx-2" />
305-
<div className="mt-2 w-48">
306-
<Input
307-
size="sm"
308-
placeholder="Search..."
309-
onChange={(e) => handleChangeTaxaSearch(e.target.value)}
310-
value={taxonFilterSearch}
311-
/>
305+
{viewType !== "tree" && (
306+
<div className="animate-fade-in">
307+
Taxon
308+
<hr className="shadow border-gray-300 -mx-2" />
309+
<div className="mt-2 w-48">
310+
<Input
311+
size="sm"
312+
placeholder="Search..."
313+
onChange={(e) => handleChangeTaxaSearch(e.target.value)}
314+
value={taxonFilterSearch}
315+
/>
316+
</div>
317+
<select
318+
multiple
319+
className="mt-2 text-gray-700 text-sm min-h-1/4 max-h-50 w-48 border-2 border-gray-300 px-1 rounded-lg"
320+
onChange={(e) => handleSelectTaxa(e.target.options)}
321+
>
322+
<option value={-1} className="px-4 py-1 border-b text-sm font-semibold">
323+
All
324+
</option>
325+
{filteredTaxa &&
326+
filteredTaxa.length > 0 &&
327+
filteredTaxa.map((taxon) => (
328+
<option
329+
key={taxon.id}
330+
value={taxon.id}
331+
className="px-4 py-1 border-b text-sm font-semibold truncate"
332+
>
333+
{taxon.scientificName}
334+
</option>
335+
))}
336+
</select>
312337
</div>
313-
<select
314-
multiple
315-
className="mt-2 text-gray-700 text-sm min-h-1/4 max-h-50 w-48 border-2 border-gray-300 px-1 rounded-lg"
316-
onChange={(e) => handleSelectTaxa(e.target.options)}
317-
>
318-
<option value={-1} className="px-4 py-1 border-b text-sm font-semibold">
319-
All
320-
</option>
321-
{filteredTaxa &&
322-
filteredTaxa.length > 0 &&
323-
filteredTaxa.map((taxon) => (
324-
<option
325-
key={taxon.id}
326-
value={taxon.id}
327-
className="px-4 py-1 border-b text-sm font-semibold truncate"
328-
>
329-
{taxon.scientificName}
330-
</option>
331-
))}
332-
</select>
333-
</div>
338+
)}
334339

335340
<div>
336341
Users

react-frontend/src/screens/MainRouter/components/AssembliesTreeViewer/index.js renamed to react-frontend/src/screens/MainRouter/components/AssembliesList/components/AssembliesTreeViewer/index.js

+35-69
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
11
import { useEffect, useState, useRef } from "react";
22
import classNames from "classnames";
3-
import "../../../../App.css";
4-
import { useNotification } from "../../../../components/NotificationProvider";
5-
import { fetchAssembliesByTaxonIDs, fetchTaxonTree } from "../../../../api";
6-
import SpeciesProfilePictureViewer from "../../../../components/SpeciesProfilePictureViewer";
3+
import "../../../../../../App.css";
4+
import { useNotification } from "../../../../../../components/NotificationProvider";
5+
import { fetchTaxonTree } from "../../../../../../api";
6+
import SpeciesProfilePictureViewer from "../../../../../../components/SpeciesProfilePictureViewer";
77
import { Expand, Vulnerability } from "grommet-icons";
88

99
import Tree from "react-d3-tree";
10-
import LoadingSpinner from "../../../../components/LoadingSpinner";
11-
import Button from "../../../../components/Button";
12-
import AssembliesGridElement from "../AssembliesList/components/AssembliesGridElement";
10+
import LoadingSpinner from "../../../../../../components/LoadingSpinner";
11+
import Button from "../../../../../../components/Button";
12+
import AssembliesGridElement from "../AssembliesGridElement";
1313

14-
const AssembliesTreeViewer = () => {
14+
const AssembliesTreeViewer = ({ filter, setFilter, assemblies, loading }) => {
1515
const [tree, setTree] = useState({});
1616
const [fullTree, setFullTree] = useState({});
17-
const [taxa, setTaxa] = useState([]);
1817
const [height, setHeight] = useState(0);
1918
const [width, setWidth] = useState(0);
2019
const [expandTree, setExpandTree] = useState(false);
2120
const [loadingTree, setLoadingTree] = useState(false);
22-
const [showElements, setShowElements] = useState(10);
23-
const [currentNode, setCurrentNode] = useState("");
21+
const [currentNode, setCurrentNode] = useState("root");
2422
const ref = useRef(null);
2523
const cardsRef = useRef(null);
2624

@@ -31,6 +29,12 @@ const AssembliesTreeViewer = () => {
3129
// eslint-disable-next-line react-hooks/exhaustive-deps
3230
}, []);
3331

32+
useEffect(() => {
33+
if (!filter || !filter.taxonIDs) {
34+
setCurrentNode("root");
35+
}
36+
}, [filter]);
37+
3438
// notifications
3539
const dispatch = useNotification();
3640

@@ -83,18 +87,9 @@ const AssembliesTreeViewer = () => {
8387
};
8488

8589
const loadTaxa = async (nodeDatum) => {
86-
const userID = JSON.parse(sessionStorage.getItem("userID") || "");
87-
const token = JSON.parse(sessionStorage.getItem("token") || "");
88-
89-
const response = await fetchAssembliesByTaxonIDs(getChildrenTaxIds(nodeDatum), userID, token);
90-
91-
if (response && response.payload) {
92-
setTaxa(response.payload);
93-
}
94-
95-
if (response && response.notification && response.notification.length > 0) {
96-
response.notification.map((not) => handleNewNotification(not));
97-
}
90+
setFilter((prevState) => {
91+
return { ...prevState, taxonIDs: getChildrenTaxIds(nodeDatum).sort() };
92+
});
9893
};
9994

10095
const getChildrenTaxIds = (nodeDatum) => {
@@ -139,7 +134,6 @@ const AssembliesTreeViewer = () => {
139134
onClick={() => {
140135
loadTaxa(nodeDatum);
141136
executeScroll();
142-
setShowElements(10);
143137
setCurrentNode(nodeDatum.name);
144138
// toggleNode();
145139
}}
@@ -231,65 +225,37 @@ const AssembliesTreeViewer = () => {
231225
</div>
232226
<div className="mt-8 min-h-1/2" ref={cardsRef}>
233227
<div className="flex">
234-
<div className="w-full bg-gray-500 rounded-lg px-4 p-2 text-white font-bold mb-4">
228+
<div className="w-full bg-gray-500 rounded-lg px-4 p-2 text-white font-bold mb-4 flex">
235229
Results:
230+
{loading && (
231+
<div className="px-4">
232+
<LoadingSpinner label="Loading..." />
233+
</div>
234+
)}
236235
</div>
237236
<div className="w-32 ml-4">
238237
<Button label="Scroll to top" color="secondary" onClick={() => executeScrollTree()} />
239238
</div>
240239
</div>
241-
{taxa && taxa.length > 0 ? (
240+
{assemblies && assemblies.length > 0 ? (
242241
<div>
243242
<div className="ml-12">
244243
<span>Last common ancestor:</span>
245244
<span className="font-bold text-xl ml-2">{currentNode}</span>
246245
</div>
247246
<hr className="m-8 mt-2 shadow" />
248247
<div className="animate-grow-y rounded-lg grid gap-8 grid-cols-2 mt-8 px-8">
249-
{taxa.map((assembly, index) => {
250-
if (index < showElements) {
251-
return (
252-
<div key={assembly.id} className="animate-fade-in">
253-
<AssembliesGridElement
254-
assembly={assembly}
255-
fcatMode={1}
256-
renderDelay={index + 1}
257-
/>
258-
</div>
259-
);
260-
} else {
261-
return <div key={assembly.id} />;
262-
}
263-
})}
264-
</div>
265-
<hr className="m-8 shadow" />
266-
<div className="flex justify-around">
267-
{showElements > 10 && (
268-
<div className="mt-2">
269-
<div className="flex justify-center">
270-
<div className="w-32">
271-
<Button
272-
color="nav"
273-
label="View less..."
274-
onClick={() => setShowElements((prevState) => prevState - 10)}
275-
/>
276-
</div>
277-
</div>
278-
</div>
279-
)}
280-
{showElements < taxa.length && (
281-
<div className="mt-2">
282-
<div className="flex justify-center">
283-
<div className="w-32">
284-
<Button
285-
color="nav"
286-
label="View more..."
287-
onClick={() => setShowElements((prevState) => prevState + 10)}
288-
/>
289-
</div>
248+
{assemblies.map((assembly, index) => {
249+
return (
250+
<div key={assembly.id} className="animate-fade-in">
251+
<AssembliesGridElement
252+
assembly={assembly}
253+
fcatMode={1}
254+
renderDelay={index + 1}
255+
/>
290256
</div>
291-
</div>
292-
)}
257+
);
258+
})}
293259
</div>
294260
</div>
295261
) : (

0 commit comments

Comments
 (0)