Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
5f31f82
Reusable barplot
tombch Mar 19, 2026
31f2dc8
Using BarPlot component for CitationPlot
tombch Mar 19, 2026
ee8a028
Updated seqset index page citations plot
tombch Mar 19, 2026
f9dd645
Added seqset id to tab title, moved author component into SeqSetItem
tombch Mar 19, 2026
4bddd90
Initial updates to SeqSet details page - added empty graphs, moved de…
tombch Mar 19, 2026
88798ad
Added graphs for collection date, countries and use terms
tombch Mar 20, 2026
adb17e6
Merge branch 'main' into seqset-details-update
tombch Mar 20, 2026
cc38702
Graph and seqset details updates
tombch Mar 20, 2026
e69d2ac
SeqSet records table css updates
tombch Mar 20, 2026
d374708
Merge branch 'main' into seqset-details-update
tombch Mar 20, 2026
d08dacf
Support multiple field options for the aggregate
tombch Mar 20, 2026
97a096a
Merge branch 'main' into seqset-details-update
tombch Mar 20, 2026
440346e
Added chartjs date adapter
tombch Mar 24, 2026
055f1f8
Cleaned up plots for dates, countries and use terms
tombch Mar 24, 2026
6d4f5e6
Updating seqset plots
tombch Mar 24, 2026
920981a
Removed responsive prop
tombch Mar 24, 2026
361861c
Fixing esbuild error
tombch Mar 24, 2026
e6e4923
Fixing formatting
tombch Mar 24, 2026
cc8386d
Merge branch 'main' into seqset-details-update
tombch Mar 24, 2026
f5179ea
Unit testing for seq set plot utils
tombch Mar 24, 2026
2c0a460
Removed hardcoded graph colours as these change between loculus insta…
tombch Mar 26, 2026
dbb6f94
fixed import of colors.ts by inlining the colors.cjs values at build …
tombch Mar 26, 2026
701736f
Updating integration tests
tombch Mar 26, 2026
6060951
Fixing integration tests
tombch Mar 26, 2026
c4e1d69
Use colors.json instead of CJS+Vite plugin for color imports (#6199)
theosanderson-agent Mar 26, 2026
2a9db6f
Loading fallback for barplot
tombch Mar 26, 2026
464fda7
Fixing up error handling
tombch Mar 26, 2026
a49e07f
Fixing integration tests
tombch Mar 26, 2026
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
28 changes: 20 additions & 8 deletions integration-tests/tests/pages/seqset.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class SeqSetPage {
}

getHeading(name: string) {
return this.page.getByRole('heading', { name });
return this.page.getByRole('heading').filter({ hasText: name });
}

async openCreateDialog() {
Expand All @@ -35,7 +35,7 @@ export class SeqSetPage {
async createSeqSet(input: SeqSetFormInput) {
await this.openCreateDialog();
await this.fillSeqSetForm(input);
await this.submitSeqSetForm(input.name);
await this.submitSeqSetForm();
}

async fillSeqSetForm(input: SeqSetFormInput) {
Expand All @@ -58,18 +58,23 @@ export class SeqSetPage {
}
}

async submitSeqSetForm(expectedName: string) {
async submitSeqSetForm() {
await this.page.getByRole('button', { name: 'Save' }).click();
await expect(this.getHeading(expectedName)).toBeVisible();
}

async expectDetailLayout(name: string) {
await expect(this.getHeading(name)).toBeVisible();
async expectDetailLayout(name: string, description: string) {
await this.expectAccessionMatchesUrl();
await expect(this.page.getByRole('button', { name: 'Export' })).toBeVisible();
await expect(this.page.getByRole('button', { name: 'Edit' })).toBeVisible();
await expect(this.page.getByRole('button', { name: 'Delete' })).toBeVisible();
await expect(this.page.getByText('Created date')).toBeVisible();
await expect(this.page.getByText('Name', { exact: true })).toBeVisible();
await expect(this.page.getByText(name, { exact: true })).toBeVisible();
await expect(this.page.getByText('Description', { exact: true })).toBeVisible();
await expect(this.page.getByText(description, { exact: true })).toBeVisible();
await expect(this.page.getByText('Version', { exact: true })).toBeVisible();
await expect(this.page.getByText('Created by', { exact: true })).toBeVisible();
await expect(this.page.getByText('Created date', { exact: true })).toBeVisible();
await expect(this.page.getByText('Size', { exact: true })).toBeVisible();
await expect(this.page.getByText('Accession', { exact: true })).toBeVisible();
}

Expand Down Expand Up @@ -111,12 +116,19 @@ export class SeqSetPage {
await this.page.waitForLoadState('networkidle');
}

async expectAccessionMatchesUrl() {
const url = this.page.url();
const accession = url.split('/seqsets/')[1];
await expect(this.getHeading(accession)).toBeVisible();
}

async editSeqSetName(newName: string) {
await this.page.getByRole('button', { name: 'Edit' }).click();
const nameField = this.page.locator('#seqSet-name');
await nameField.waitFor({ state: 'visible' });
await nameField.fill(newName);
await this.page.getByRole('button', { name: 'Save' }).click();
await expect(this.getHeading(newName)).toBeVisible();
await this.expectAccessionMatchesUrl();
await expect(this.page.getByText(newName, { exact: true })).toBeVisible();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ test.describe('SeqSet management', () => {
backgroundAccessions: [backgroundAccession],
});

await seqSetPage.expectDetailLayout(seqSetName);
await seqSetPage.expectDetailLayout(seqSetName, seqSetDescription);

const jsonDownload = await seqSetPage.exportSeqSet('json');
expect(jsonDownload.suggestedFilename()).toContain(seqSetName);
Expand Down
2 changes: 1 addition & 1 deletion website/.dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ src/**/*.spec.ts*
!package-lock.json
!astro.config.mjs
!tailwind.config.cjs
!colors.cjs
!colors.json
!tsconfig.json
!.env.docker
18 changes: 0 additions & 18 deletions website/colors.cjs

This file was deleted.

16 changes: 16 additions & 0 deletions website/colors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"mainTailwindColor": {
"50": "#f3f6fb",
"100": "#e4e9f5",
"200": "#cfdaee",
"300": "#aec1e2",
"400": "#88a1d2",
"500": "#6b84c6",
"600": "#586bb8",
"700": "#4d5ba8",
"800": "#3e467e",
"900": "#3a416e",
"950": "#272b44",
"1500": "#25396e"
}
}
30 changes: 30 additions & 0 deletions website/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"axios": "^1.13.6",
"change-case": "~5.3.0",
"chart.js": "^4.5.1",
"chartjs-adapter-date-fns": "^3.0.0",
"cookie": "^1.1.1",
"fflate": "^0.8.2",
"flowbite-react": "^0.10.2",
Expand Down
43 changes: 13 additions & 30 deletions website/src/components/SeqSetCitations/CitationPlot.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
import { Chart as ChartJS, CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend } from 'chart.js';
import { type FC, useState, useEffect } from 'react';
import { Bar } from 'react-chartjs-2';
import React from 'react';

import type { CitedByResult } from '../../types/seqSetCitation';
import { type CitedByResult } from '../../types/seqSetCitation';
import { BarPlot } from '../common/BarPlot';

type CitationPlotProps = {
citedByData: CitedByResult;
description?: string;
barColor?: string;
};

export const CitationPlot: FC<CitationPlotProps> = ({ citedByData }) => {
const [isRegistered, setIsRegistered] = useState(false);

useEffect(() => {
ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend);
setIsRegistered(true);
}, []);

if (!isRegistered) {
return null;
}

export const CitationPlot: React.FC<CitationPlotProps> = ({ citedByData, description, barColor }) => {
const emptyCitedByData = {
years: [2020, 2021, 2022, 2023, 2024],
citations: [0, 0, 0, 0, 0],
Expand All @@ -28,37 +18,30 @@ export const CitationPlot: FC<CitationPlotProps> = ({ citedByData }) => {
const renderData = citedByData.years.length > 0 ? citedByData : emptyCitedByData;

return (
<Bar
<BarPlot
data={{
labels: renderData.years,
datasets: [
{
data: renderData.citations,
label: 'Citation count',
backgroundColor: '#54858c',
backgroundColor: barColor,
},
],
}}
options={{
maintainAspectRatio: false,
responsive: false,
plugins: {
title: {
display: true,
},
legend: {
display: false,
},
},
scales: {
y: {
suggestedMax: 10,
x: {
grid: {
color: 'rgba(0, 0, 0, 0)',
},
},
y: {
suggestedMax: 10,
},
},
}}
description={description}
/>
);
};
Loading
Loading