Skip to content

Circuit metada update contributor published in registration date #367

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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
2 changes: 1 addition & 1 deletion public/circuits/ALL_CIRCUITS.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@ import ParameterBox from '../global/ParameterBox';

export default function CircuitMetadata({ content }: { content: CircuitSchemaProps }) {
return (
<div className="relative mr-24 flex w-[480px] flex-col">
<div className="relative mr-24 flex w-[480px] flex-col gap-y-4">
<div>
<ParameterBox name="Description" value={content.description} />
</div>
<div className="mt-4 grid grid-cols-2 gap-4">
<ParameterBox name="Contributors" value={content.metadata.contributorSimple || '–'} />

<ParameterBox name="Creation date" value={content.metadata.creationDate} />
<div>
<ParameterBox name="Contributors" value={content.metadata.contributors || '–'} />
</div>
<div>
<ParameterBox
name="Contributing institution"
value={content.metadata.contributingInstitution || '–'}
/>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default function CircuitParameters({ content }: { content: CircuitSchemaP

return (
<div className="relative grid grid-cols-3 gap-12">
{/* COLUMN 1 */}
<div className="relative flex flex-col gap-y-4">
<ParameterBox name="Brain Region" value={content.brainRegion} />
<ParameterBox name="Subcircuit of" value={content.parent ?? '–'} link={parentCircuitLink} />
Expand All @@ -19,6 +20,7 @@ export default function CircuitParameters({ content }: { content: CircuitSchemaP
link={licenseLink}
/>
</div>
{/* COLUMN 2 */}
<div className="relative flex flex-col gap-y-4">
<ParameterBox
name="Number of neurons"
Expand All @@ -33,6 +35,12 @@ export default function CircuitParameters({ content }: { content: CircuitSchemaP
value={formatNumberWithComma(content.numberOfSynapses)}
/>
</div>
{/* COLUMN 3 */}
<div className="relative flex flex-col gap-y-4">
<ParameterBox name="Published in" value={content.metadata.publishedIn ?? '–'} />
<ParameterBox name="Registration date" value={content.metadata.registrationDate ?? '–'} />
<ParameterBox name="Contact" value={content.metadata.contact ?? '–'} />
</div>
</div>
);
}
8 changes: 5 additions & 3 deletions src/components/explore-section/Circuit/global/Columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,13 @@ const columns = (
),
},
{
title: 'Contributor',
key: 'contributorSimple',
title: 'Contributors',
key: 'contributors',
width: 150,
render: (_value: any, record: CircuitSchemaProps, _index: number) => (
<div className="whitespace-nowrap font-normal">{record.metadata.contributorSimple}</div>
<div className="whitespace-nowrap font-normal">
{record.metadata.contributors === 'None' ? '–' : record.metadata.contributors}
</div>
),
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,7 @@ export default function CircuitTable({
// DATA
const cleanedData = useMemo(() => {
const result = data.map((circuit: CircuitSchemaProps) => {
const numberOfNeurons =
typeof circuit.numberOfNeurons === 'number' && !Number.isNaN(circuit.numberOfNeurons)
? circuit.numberOfNeurons
: 0;
const { numberOfNeurons } = circuit;
if (numberOfNeurons === 0) {
throw new Error('Number of neurons is not a number or is NaN');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export function DownloadChildrenItem({
return (
<div className="flex w-full flex-row justify-between">
<div className="w-3/4 hyphens-auto">
<div className="text-base font-bold text-white">{childrenItem.name}</div>
<p className="hyphens-auto text-sm font-light leading-normal text-primary-2">
<div className="text-lg font-bold text-white">{childrenItem.name}</div>
<p className="hyphens-auto text-base font-light leading-normal text-primary-2">
{childrenItem.description}
</p>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default function HeaderDownloadModal({
return (
<header className="mb-8 flex w-full flex-row justify-between">
<div className="flex flex-row gap-x-2 text-base text-primary-4">
<div className="font-bold">Download Files</div>
<div className="font-bold">Download files</div>
<div className="font-light">Total files: {calculateTotalDownloadableItems(content)}</div>
</div>
<button
Expand Down
3 changes: 2 additions & 1 deletion src/components/explore-section/Circuit/type/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export type CircuitSchemaProps = {
numberOfSynapses: number;
metadata: {
contributorSimple?: string;
contributor?: string | null;
contributors?: string;
contributingInstitution?: string;
publishedIn?: string;
registrationDate?: string;
Expand All @@ -50,6 +50,7 @@ export type CircuitSchemaProps = {
name: string;
url: string;
} | null;
contact: string | null;
};
files: DownloadItemProps[];
subcircuits: CircuitSchemaProps[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function circuitMatchFilter(
}

let searchMatch = true;
if (searchQuery && searchQuery.trim()) {
if (searchQuery) {
const query = searchQuery.toLowerCase().trim();
searchMatch =
circuit.name?.toLowerCase().includes(query) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const fileTypeDescriptions: FileTypeHeaderProps[] = [
extension: 'h5',
},
{
name: 'Morphology',
name: 'Morphologies',
description: (
<p className="w-3/4 text-base font-light text-primary-1">
The neuronal morphologies used in the circuit grouped in h5 containers.{' '}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ export default function StatItem({
const [, setCurrentExplorerArtifact] = useCurrentExplorerArtifact();
const selectedBrainRegion = useAtomValue(selectedBrainRegionAtom);
const onClick = async () => {
if (!(await userJourneyTracker.getCurrentTuple())) {
const current = await userJourneyTracker.getCurrentTuple();

if (!current) {
await userJourneyTracker.handleBrainRegionClick(selectedBrainRegion?.title!);
}
const artifact = ensureString(title, 'Morphology');

setCurrentExplorerArtifact(artifact);
await userJourneyTracker.handleClick('artifact', artifact);
};
Expand Down
54 changes: 48 additions & 6 deletions src/components/explore-section/Literature/user-journey/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,48 @@
import isNil from 'lodash/isNil';

import { db, ClickTuple, ClickType } from '@/components/explore-section/Literature/user-journey/db';
import GenericEvent from '@/util/generic-event';

const DEFAULT_COUNT = 10;

function sortTuples(tuples: ClickTuple[]) {
return tuples.sort((a, b) => {
const aTimestamp = a.clicks.find((c) => c.type === 'brain_region')?.timestamp || 0;
const bTimestamp = b.clicks.find((c) => c.type === 'brain_region')?.timestamp || 0;
return bTimestamp - aTimestamp;
});
}

class ClickContextTracker {
public readonly eventChange = new GenericEvent<ClickContextTracker>();

constructor(private dbInstance = db) {}

async saveTuple(): Promise<void> {
const currentTuple = await this.getCurrentTuple();

if (!currentTuple) return;

await this.dbInstance.clickTuples.add(currentTuple);
await this.dbInstance.activeSession.delete('current');
try {
await this.dbInstance.clickTuples.add(currentTuple);
const allTuplesFromDB = await this.dbInstance.clickTuples.toArray();
const sortedAllTuples = sortTuples([...allTuplesFromDB]);
if (sortedAllTuples.length > DEFAULT_COUNT) {
const tuplesToDelete = sortedAllTuples.slice(DEFAULT_COUNT);
const idsToDelete = tuplesToDelete
.map((tuple) => tuple.id)
.filter((id): id is number => typeof id === 'number' && !isNil(id));

if (idsToDelete.length > 0) {
await this.dbInstance.clickTuples.bulkDelete(idsToDelete);
}
}

await this.dbInstance.activeSession.delete('current');
} catch (error) {
// eslint-disable-next-line no-console
console.error('Error in save user journey tuple:', error);
}
}

async getCurrentTuple(): Promise<ClickTuple | null> {
Expand All @@ -30,25 +61,36 @@ class ClickContextTracker {
const newTuple: ClickTuple = {
clicks: [{ type: 'brain_region', data, timestamp: Date.now() }],
};

await this.updateCurrentTuple(newTuple);
}

async handleClick(type: ClickType, data: string): Promise<void> {
const currentTuple = await this.getCurrentTuple();

if (!currentTuple) {
// eslint-disable-next-line no-console
console.warn(`${type} clicked without a starting brain region.`);
return;
}

currentTuple.clicks.push({ type, data, timestamp: Date.now() });

await this.updateCurrentTuple(currentTuple);
}

async getLastTuples(count: number = 10): Promise<Array<Array<[ClickType, string]>>> {
const tuples = await this.dbInstance.clickTuples.orderBy('id').reverse().limit(count).toArray();
return tuples.map((tuple) => tuple.clicks.map((click) => [click.type, click.data]));
async getLastTuples(count: number = DEFAULT_COUNT): Promise<Array<Array<[ClickType, string]>>> {
const tuples = await this.dbInstance.clickTuples.orderBy('id').toArray();
const currentActiveTuple = await this.getCurrentTuple();
const sortedClicks = sortTuples([
...tuples,
...(currentActiveTuple ? [currentActiveTuple] : []),
])
.slice(0, count)
.reverse();

return sortedClicks.map((tuple: ClickTuple) =>
tuple.clicks.map((click: ClickTuple['clicks'][number]) => [click.type, click.data])
);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/services/ai-agent/api/suggestion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export const serviceAiAgentSuggestionFromUserJourney = asyncCreateSquash(
}
): Promise<string[]> => {
const { threadId = null, virtualLabId = null, projectId = null } = options ?? {};
await userJourneyTracker.saveTuple();
const journey = await userJourneyTracker.getLastTuples();

const data = await fetchJSON({
accessToken,
path: 'qa/question_suggestions',
Expand Down
1 change: 1 addition & 0 deletions src/services/ai-agent/hooks/suggestion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export function useServiceAiAgentSuggestionFromUserJourney(
};
action();
}, [threadId, count, accessToken, projectId, virtualLabId]);

React.useEffect(fetchSuggestions, [fetchSuggestions]);
useGenericEventListener(userJourneyTracker.eventChange, fetchSuggestions);
return [suggestions, () => setSuggestions([])];
Expand Down