Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions applications/virtual-fly-brain/frontend/src/components/Layout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { removeAllInstances } from './../reducers/actions/instances';
import { Box, Button,Modal, useMediaQuery, useTheme, Typography, CircularProgress, Link } from "@mui/material";
import { activateCircuits, activateImages } from "../reducers/actions/layout";
import { widgetsIDs } from "./layout/widgets";
import { bottomNavClearAll, bottomNavDownload, bottomNavLayers, bottomNavQuery, bottomNavSearch, bottomNavSnapshot, bottomNavUpload } from "../utils/constants";

const {
secondaryBg,
Expand Down Expand Up @@ -80,14 +81,14 @@ const MainLayout = ({ bottomNav, setBottomNav }) => {
const queryComponentOpened = useSelector( state => state.globalInfo?.queryComponentOpened );

useEffect( () => {
if ( queryComponentOpened && bottomNav !== 2 ){
setBottomNav(2)
if ( queryComponentOpened && bottomNav !== bottomNavQuery ){
setBottomNav(bottomNavQuery)
}
}, [bottomNav, queryComponentOpened, setBottomNav]);

// Handle Clear All functionality
useEffect(() => {
if (bottomNav === 4) {
if (bottomNav === bottomNavClearAll) {
if (allLoadedInstances?.length > 1) {
removeAllInstances();
}
Expand All @@ -97,7 +98,7 @@ const MainLayout = ({ bottomNav, setBottomNav }) => {
}, [bottomNav, allLoadedInstances?.length, setBottomNav]);

useEffect( () => {
if ( bottomNav === 3 ){
if ( bottomNav === bottomNavLayers ){
const layoutManager = getLayoutManagerInstance();
if (!layoutManager.model.getNodeById("listViewerWidget").isVisible()) {
const newWidget = { ...widgets[widgetsIDs.listViewerWidgetID] }
Expand Down Expand Up @@ -252,22 +253,22 @@ const MainLayout = ({ bottomNav, setBottomNav }) => {
{desktopScreen ? (
<>
{tabContent}
{bottomNav === 0 && < VFBSnapshot open={true} setBottomNav={setBottomNav} />}
{bottomNav === 1 && < VFBUploader open={true} setBottomNav={setBottomNav} />}
{bottomNav === 2 && <VFBDownloadContents open={true} setBottomNav={setBottomNav} />}
{bottomNav === 3 && <QueryBuilder setBottomNav={setBottomNav} fullWidth={sidebarOpen} tabSelected={0}/>}
{bottomNav === 6 && <QueryBuilder setBottomNav={setBottomNav} fullWidth={sidebarOpen} tabSelected={1}/>}
{bottomNav === bottomNavSnapshot && < VFBSnapshot open={true} setBottomNav={setBottomNav} />}
{bottomNav === bottomNavUpload && < VFBUploader open={true} setBottomNav={setBottomNav} />}
{bottomNav === bottomNavDownload && <VFBDownloadContents open={true} setBottomNav={setBottomNav} />}
{bottomNav === bottomNavQuery && <QueryBuilder setBottomNav={setBottomNav} fullWidth={sidebarOpen} tabSelected={0}/>}
{bottomNav === bottomNavSearch && <QueryBuilder setBottomNav={setBottomNav} fullWidth={sidebarOpen} tabSelected={1}/>}
</>
) : (
<>
{
bottomNav != 3 && tabContent
bottomNav != bottomNavQuery && tabContent
}
{bottomNav === 0 && <VFBSnapshot open={true} setBottomNav={setBottomNav} />}
{bottomNav === 1 && <VFBUploader open={true} setBottomNav={setBottomNav} />}
{bottomNav === 2 && <VFBDownloadContents open={true} setBottomNav={setBottomNav} />}
{bottomNav === 3 && <QueryBuilder setBottomNav={setBottomNav} fullWidth={sidebarOpen} tabSelected={0}/>}
{bottomNav === 6 && <QueryBuilder setBottomNav={setBottomNav} fullWidth={sidebarOpen} tabSelected={1}/>}
{bottomNav === bottomNavSnapshot && <VFBSnapshot open={true} setBottomNav={setBottomNav} />}
{bottomNav === bottomNavUpload && <VFBUploader open={true} setBottomNav={setBottomNav} />}
{bottomNav === bottomNavDownload && <VFBDownloadContents open={true} setBottomNav={setBottomNav} />}
{bottomNav === bottomNavQuery && <QueryBuilder setBottomNav={setBottomNav} fullWidth={sidebarOpen} tabSelected={0}/>}
{bottomNav === bottomNavSearch && <QueryBuilder setBottomNav={setBottomNav} fullWidth={sidebarOpen} tabSelected={1}/>}
</>
)}
</Box>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import vars from "../../../theme/variables";
import { widgets } from "../../layout/widgets";
import { bottomNavDownload, bottomNavQuery, bottomNavSearch, bottomNavUpload } from '../../../utils/constants';
const { primaryFont, whiteColor, tabActiveColor, primaryBg } = vars;

const ACTIONS = {
Expand Down Expand Up @@ -199,15 +200,15 @@ export const toolbarMenu = (autoSaveLayout) => { return {
icon: "fa fa-search",
action: {
handlerAction: ACTIONS.SHOW_COMPONENT,
parameters: [5]
parameters: [bottomNavSearch]
}
},
{
label: "Query",
icon: "fa fa-clipboard-question",
action: {
handlerAction: ACTIONS.SHOW_COMPONENT,
parameters: [2]
parameters: [bottomNavQuery]
}
},
{
Expand Down Expand Up @@ -279,15 +280,15 @@ export const toolbarMenu = (autoSaveLayout) => { return {
icon: "fa fa-download",
action: {
handlerAction: ACTIONS.SHOW_COMPONENT,
parameters: [1]
parameters: [bottomNavDownload]
}
},
{
label: "NBLAST Uploader",
icon: "fa fa-upload",
action: {
handlerAction: ACTIONS.SHOW_COMPONENT,
parameters: [0]
parameters: [bottomNavUpload]
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ const getQueries = (newQueries, searchTerm) => {
if (!newQueries || newQueries.length === 0) return [];

let updatedQueries = [];
const term = searchTerm ? searchTerm.toLowerCase() : undefined;
const term = searchTerm ? searchTerm.toLowerCase() : "";

newQueries.forEach((query) => {
if (query.queries) {
Object.keys(query.queries).forEach((key) => {
if (query.queries[key]?.active) {
let rows = query.queries[key]?.rows || [];
let rows = query.queries[key]?.rows || query.queries[key]?.preview_results?.rows || [];

if (term) {
if (term != undefined) {
rows = rows.filter(row => {
// Cache the string conversion for performance
const values = Object.values(row);
Expand Down Expand Up @@ -95,20 +95,41 @@ const Query = forwardRef(({ fullWidth, queries, searchTerm }, ref) => {
const [sortDirection, setSortDirection] = useState(1); // 1 for ascending, -1 for descending

// Memoize filtered searches
const filteredSearches = useMemo(() => getQueries(queries, searchTerm), [queries, searchTerm]);
const filteredSearches = useMemo(() => {
return getQueries(queries, searchTerm);
}, [queries, searchTerm]);

const getRows = (item) => {
if (item?.rows?.length > 0) {
return item.rows;
}

if (item?.preview_results?.rows?.length > 0) {
return item.preview_results.rows;
}

return null;
};

// Memoize the final filtered results based on both search term and active chip tags
const finalFilteredResults = useMemo(() => {
if (!filteredSearches || filteredSearches.length === 0) return [];

const activeChipLabels = chipTags.filter(f => f.active).map(tag => tag.label);
const rows = filteredSearches.flatMap(item => {
const nestedRows = getRows(item);
return nestedRows || [item];
});

// Filter by active chip tags
const activeChipLabels = chipTags
.filter(f => f.active)
.map(tag => tag.label);

let filtered;

if (activeChipLabels.length === 0) {
filtered = filteredSearches;
filtered = rows;
} else {
filtered = filteredSearches.filter(row => {
filtered = rows.filter(row => {
const tags = getTags(row.tags);
return activeChipLabels.some(label => tags.includes(label));
});
Expand Down Expand Up @@ -146,13 +167,22 @@ const Query = forwardRef(({ fullWidth, queries, searchTerm }, ref) => {
if (!queries || queries.length === 0) return [];

const tagMap = new Map();

queries.forEach(query => {
if (query.queries) {
Object.keys(query.queries).forEach(q => {
if (query.queries[q]?.active) {
query.queries[q]?.rows?.forEach(row => {
const currentQuery = query.queries[q];

if (currentQuery?.active) {
const rows =
currentQuery?.rows?.length > 0
? currentQuery.rows
: currentQuery?.preview_results?.rows || [];

rows.forEach(row => {
if (row.tags) {
const rowTags = getTags(row.tags);

rowTags.forEach(rowTag => {
if (!tagMap.has(rowTag)) {
tagMap.set(rowTag, { label: rowTag, active: true });
Expand Down Expand Up @@ -343,7 +373,7 @@ const Query = forwardRef(({ fullWidth, queries, searchTerm }, ref) => {
onClick={() => null}
disabled={!tag.active}
onDelete={() => handleChipDelete(tag.label)}
key={tag}
key={tag?.label}
deleteIcon={
<Cross
size={12}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Box, Button } from "@mui/material";
import React from "react";
import { ClearAll, Download, Query, Upload, Layers } from "../../icons";
import vars from "../../theme/variables";
import { bottomNavClearAll, bottomNavDownload, bottomNavQuery, bottomNavSnapshot } from "../../utils/constants";

const {
whiteColor,
Expand All @@ -12,22 +13,22 @@ const {

const navArr = [
{
id: 0,
id: bottomNavSnapshot,
icon: Upload,
name: 'Upload'
},
{
id: 1,
id: bottomNavDownload,
Comment thread
jrmartin marked this conversation as resolved.
icon: Download,
name: 'Download'
},
{
id: 2,
id: bottomNavQuery,
icon: Query,
name: 'Query'
},
{
id: 3,
id: bottomNavClearAll,
icon: ClearAll,
name: 'Clear all'
Comment thread
jrmartin marked this conversation as resolved.
},
Expand Down Expand Up @@ -72,7 +73,7 @@ const BottomNav = ({ setBottomNav, bottomNav }) => {
flexWrap='wrap'
sx={classes.root}
>
{navArr.map((item, index) => (
{navArr.map((item) => (
<Button
sx={{
height: '100%',
Expand All @@ -83,7 +84,7 @@ const BottomNav = ({ setBottomNav, bottomNav }) => {
flexDirection: 'column',
}}

onClick={() => setBottomNav(index)}
onClick={() => setBottomNav(item?.id)}
key={item.id}
>
<item.icon color={item?.id === bottomNav ? tabActiveColor : 'white'} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import layout3 from "../../components/layout/layout3";
import { WidgetStatus } from "@metacell/geppetto-meta-client/common/layout/model";
import { getLayoutManagerInstance } from "@metacell/geppetto-meta-client/common/layout/LayoutManager";
import { bottomNavQuery } from "../../utils/constants";

const { primaryBg, headerBoxShadow } = vars;

Expand Down Expand Up @@ -68,7 +69,7 @@
}

// Open the query component panel
setBottomNav(2);
setBottomNav(bottomNavQuery);
}
}

Expand Down Expand Up @@ -140,13 +141,13 @@
Object.keys(query.queries)?.forEach(q => query.queries[q].active = false);
}
});
if (matchQuery?.queries?.[action?.parameters[1]]) {
matchQuery.queries[action.parameters[1]].active = true;
if (matchQuery?.short_form == action?.parameters[0]) {
Object.keys(matchQuery.queries)?.forEach(q => matchQuery.queries[q].active = true);
updateQueries(updatedQueries);
Comment thread
jrmartin marked this conversation as resolved.
setBottomNav(2)
setBottomNav(bottomNavQuery)
Comment thread
jrmartin marked this conversation as resolved.
} else {
getQueries(action.parameters[0], action.parameters[1])
setBottomNav(2)
setBottomNav(bottomNavQuery)
}
break;
}
Expand Down Expand Up @@ -208,7 +209,7 @@
}

useEffect(() => {
menuConfig = toolbarMenu(autoSaveLayout);

Check warning on line 212 in applications/virtual-fly-brain/frontend/src/shared/header/index.jsx

View workflow job for this annotation

GitHub Actions / eslint

Assignments to the 'menuConfig' variable from inside React Hook useEffect will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside useEffect
}, [autoSaveLayout]);

return (
Expand Down Expand Up @@ -310,7 +311,7 @@
<MediaQuery minWidth={1200}>
{focusedInstance?.metadata?.Id && (focusedInstance?.metadata?.Queries?.length > 0 || queries?.find(q => q.short_form === focusedInstance.metadata.Id)) && (
<Button
onClick={() => setBottomNav((prev) => prev === 2 ? null : 2)}
onClick={() => setBottomNav((prev) => prev === bottomNavQuery ? null : bottomNavQuery)}
variant="outlined"
>
<QueryStats size={16} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,26 @@ export const QueriesSelectionDropdown = ({option, selectedOption, goBackToInitia
setPopoverAnchorEl(null);
}

const handleSelect = (option, query) => {
const handleSelect = (option, query, selection) => {
let count = 0;
if ( !selectedOption[query.short_form]) {
count = option.count;
}

let updatedQueries = [...queries];
let matchQuery = updatedQueries?.find( q => q.short_form === query.short_form );
if ( matchQuery.queries?.[option.query] ){
matchQuery.active = true
matchQuery.queries[option.query].active = true;
let matchQuery = updatedQueries?.find(q => q.short_form === query.short_form);

if (matchQuery?.queries) {
matchQuery.active = true;

// Loop through matchQuery.queries keys
Object.keys(matchQuery.queries).forEach(key => {
if (matchQuery.queries[key]?.label === selection) {
matchQuery.queries[key].active = true;
} else if (matchQuery.queries[key]?.active) {
matchQuery.queries[key].active = false;
}
});
}
updateQueries(updatedQueries);
Object.keys(selectedOption)?.forEach( o => {
Expand Down Expand Up @@ -162,7 +171,9 @@ export const QueriesSelectionDropdown = ({option, selectedOption, goBackToInitia
</ListItem>
}
{ Object.keys(option.queries)?.length && Object.keys(option.queries)?.map((query, index) => (<ListItem key={query.short_form+index}>
<ListItemButton onClick={() => handleSelect(option.queries[query], option)}>
<ListItemButton onClick={() => {
handleSelect(option.queries[query], option, option.queries[query].label);
}}>
<ListItemText primary={option.queries[query].label} />
</ListItemButton>
</ListItem>) )}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import { getQueries, deleteQuery, updateQueries } from '../../reducers/actions/queries';
import { getUpdatedTags } from '../../utils/utils';
import { debounce } from '@mui/material';
import { bottomNavQuery } from '../../utils/constants';

const QUERIES = "Queries";
const SEARCH_DEBOUNCE = 500;
Expand Down Expand Up @@ -165,21 +166,14 @@

const checkResults = () => {
// getQueriesStarted();
props.setBottomNav(2)
props.setBottomNav(bottomNavQuery)
setIsOpen(false)
props.setFocused(false);
let updatedQueries = [];
queries.length > 0 ? updatedQueries = [...queries] : []
updatedQueries.forEach( q => {
let match = value?.find( v => v.short_form === q.short_form );
if ( match !== undefined ) {
Object.keys(q.queries)?.forEach( key => {
q.queries[key].active = true;
if ( q.queries[key].rows === undefined ) {
getQueries(q.short_form, key)
}
})
} else {
if ( match === undefined ) {
Object.keys(q.queries)?.forEach( key => {
q.queries[key].active = false
})
Expand Down Expand Up @@ -266,7 +260,7 @@

const debouncedResults = React.useMemo(() => {
return debounce(handleSearch, SEARCH_DEBOUNCE);
}, []);

Check warning on line 263 in applications/virtual-fly-brain/frontend/src/shared/subHeader/SearchBuilder.jsx

View workflow job for this annotation

GitHub Actions / eslint

React Hook React.useMemo has a missing dependency: 'handleSearch'. Either include it or remove the dependency array

const handleFocused = (focused) => {
props.setFocused(focused);
Expand All @@ -291,11 +285,11 @@

React.useEffect(() => {
handleFocused(focused);
}, [focused])

Check warning on line 288 in applications/virtual-fly-brain/frontend/src/shared/subHeader/SearchBuilder.jsx

View workflow job for this annotation

GitHub Actions / eslint

React Hook React.useEffect has a missing dependency: 'handleFocused'. Either include it or remove the dependency array

React.useEffect(() => {
handleFocused(props.filterOpened);
}, [props.filterOpened])

Check warning on line 292 in applications/virtual-fly-brain/frontend/src/shared/subHeader/SearchBuilder.jsx

View workflow job for this annotation

GitHub Actions / eslint

React Hook React.useEffect has a missing dependency: 'handleFocused'. Either include it or remove the dependency array

React.useEffect( () => {
let values = [...value];
Expand All @@ -303,7 +297,7 @@
values = values.filter( v => v.id != queriesErrorID );
}
setValue(values)
}, [queriesErrorID])

Check warning on line 300 in applications/virtual-fly-brain/frontend/src/shared/subHeader/SearchBuilder.jsx

View workflow job for this annotation

GitHub Actions / eslint

React Hook React.useEffect has a missing dependency: 'value'. Either include it or remove the dependency array

return (
<Box flexGrow={1}>
Expand Down
Loading
Loading