Skip to content

Commit

Permalink
feat(website): Display submitting group as clickable link on sequence…
Browse files Browse the repository at this point in the history
… details page (#2501)

* Display group as clickable link

* update

* Update DataTableEntryValue.tsx
  • Loading branch information
theosanderson authored Aug 22, 2024
1 parent 5164d31 commit 2144375
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 3 deletions.
12 changes: 10 additions & 2 deletions kubernetes/loculus/templates/_common-metadata.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,19 @@ fields:
type: int
autocomplete: true
header: Submission details
displayName: Submitting group
customDisplay:
type: link
url: {{ include "loculus.websiteUrl" $ -}} /group/__value__
type: submittingGroup
displayGroup: group
- name: groupName
type: string
generateIndex: true
autocomplete: true
header: Submission details
displayName: Submitting group
customDisplay:
type: submittingGroup
displayGroup: group
- name: submittedAtTimestamp
type: timestamp
displayName: Date submitted (timestamp)
Expand Down Expand Up @@ -183,6 +188,9 @@ organisms:
customDisplay:
type: {{ quote .customDisplay.type }}
url: {{ .customDisplay.url }}
{{- if .customDisplay.displayGroup }}
displayGroup: {{ quote .customDisplay.displayGroup }}
{{- end }}
{{- end }}
{{- end }}

Expand Down
15 changes: 15 additions & 0 deletions website/src/components/SequenceDetailsPage/DataTableEntryValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ interface Props {
dataUseTermsHistory: DataUseTermsHistoryEntry[];
}

const GroupComponent: React.FC<{ jsonString: string }> = ({ jsonString }) => {
const values = JSON.parse(jsonString) as TableDataEntry[];
const groupId = values.find((value) => value.name === 'groupId')?.value;
const groupName = values.find((value) => value.name === 'groupName')?.value;

return (
<a href={`/group/${groupId}`} className='underline'>
{groupName}
</a>
);
};

const CustomDisplayComponent: React.FC<Props> = ({ data, dataUseTermsHistory }) => {
const { value, customDisplay } = data;

Expand Down Expand Up @@ -38,6 +50,9 @@ const CustomDisplayComponent: React.FC<Props> = ({ data, dataUseTermsHistory })
{value} <DataUseTermsHistoryModal dataUseTermsHistory={dataUseTermsHistory} />
</>
)}
{customDisplay?.type === 'submittingGroup' && typeof value == 'string' && (
<GroupComponent jsonString={value} />
)}
</div>
</div>
);
Expand Down
42 changes: 41 additions & 1 deletion website/src/components/SequenceDetailsPage/getDataTableData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,44 @@ export type DataTableData = {
rows: TableDataEntry[];
}[];
};
function grouping(listTableDataEntries: TableDataEntry[]): TableDataEntry[] {
const result: TableDataEntry[] = [];
const groupedEntries = new Map<string, TableDataEntry[]>();

for (const entry of listTableDataEntries) {
if (entry.customDisplay?.displayGroup !== undefined) {
if (!groupedEntries.has(entry.customDisplay.displayGroup)) {
groupedEntries.set(entry.customDisplay.displayGroup, []);
// Add a placeholder for the grouped entry
result.push({
name: entry.customDisplay.displayGroup,
type: {
kind: 'metadata',
metadataType: 'string',
},
value: '[]',
header: entry.header,
customDisplay: entry.customDisplay,
label: entry.label,
});
}
groupedEntries.get(entry.customDisplay.displayGroup)!.push(entry);
} else {
result.push(entry);
}
}

// Replace placeholders with actual grouped entries
return result.map((entry) => {
if (groupedEntries.has(entry.name)) {
return {
...entry,
value: JSON.stringify(groupedEntries.get(entry.name)),
};
}
return entry;
});
}

export function getDataTableData(listTableDataEntries: TableDataEntry[]): DataTableData {
const result: DataTableData = {
Expand All @@ -20,8 +58,10 @@ export function getDataTableData(listTableDataEntries: TableDataEntry[]): DataTa
table: [],
};

const listTableDataEntriesAfterGrouping = grouping(listTableDataEntries);

const tableHeaderMap = new Map<string, TableDataEntry[]>();
for (const entry of listTableDataEntries) {
for (const entry of listTableDataEntriesAfterGrouping) {
// Move the first entry with type authors to the topmatter
if (
result.topmatter.authors === undefined &&
Expand Down
1 change: 1 addition & 0 deletions website/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const customDisplay = z.object({
type: z.string(),
url: z.string().optional(),
value: z.array(segmentedMutations).optional(),
displayGroup: z.string().optional(),
});

export const metadata = z.object({
Expand Down

0 comments on commit 2144375

Please sign in to comment.