Skip to content

Commit

Permalink
feat(website): support HTML custom display of table entries (#3576)
Browse files Browse the repository at this point in the history
  • Loading branch information
chaoran-chen authored Jan 27, 2025
1 parent 2c5e9a1 commit 0dc400a
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 0 deletions.
3 changes: 3 additions & 0 deletions kubernetes/loculus/templates/_common-metadata.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ organisms:
{{- if .customDisplay.displayGroup }}
displayGroup: {{ quote .customDisplay.displayGroup }}
{{- end }}
{{- if .customDisplay.html }}
html: {{ .customDisplay.html }}
{{- end }}
{{- end }}
{{- end }}

Expand Down
114 changes: 114 additions & 0 deletions website/package-lock.json

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

2 changes: 2 additions & 0 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"@svgr/core": "^8.1.0",
"@svgr/plugin-jsx": "^8.1.0",
"@tanstack/react-query": "^4.36.1",
"@types/sanitize-html": "^2.13.0",
"@zodios/core": "^10.9.6",
"@zodios/react": "^10.4.5",
"astro": "^5.1.8",
Expand All @@ -53,6 +54,7 @@
"react-toastify": "^11.0.3",
"react-tooltip": "^5.28.0",
"rsuite": "^5.77.0",
"sanitize-html": "^2.14.0",
"unplugin-icons": "^22.0.0",
"winston": "^3.17.0",
"xlsx": "^0.18.5",
Expand Down
17 changes: 17 additions & 0 deletions website/src/components/SequenceDetailsPage/DataTableEntryValue.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import sanitizeHtml from 'sanitize-html';

import { DataUseTermsHistoryModal } from './DataUseTermsHistoryModal';
import { SubstitutionsContainers } from './MutationBadge';
Expand Down Expand Up @@ -45,6 +46,13 @@ const CustomDisplayComponent: React.FC<Props> = ({ data, dataUseTermsHistory })
{value}
</a>
)}
{customDisplay?.type === 'htmlTemplate' && customDisplay.html !== undefined && (
/* eslint-disable @typescript-eslint/naming-convention */
<div
dangerouslySetInnerHTML={{ __html: generateCleanHtml(customDisplay.html, value.toString()) }}
/>
/* eslint-enable @typescript-eslint/naming-convention */
)}
{customDisplay?.type === 'dataUseTerms' && (
<>
{value} <DataUseTermsHistoryModal dataUseTermsHistory={dataUseTermsHistory} />
Expand All @@ -70,4 +78,13 @@ const PlainValueDisplay: React.FC<{ value: TableDataEntry['value'] }> = ({ value
return <span className='italic'>None</span>;
};

const generateCleanHtml = (trustedHtml: string, userValue: string): string => {
const cleanedValue = sanitizeHtml(userValue, {
allowedTags: [],
allowedAttributes: {},
disallowedTagsMode: 'escape',
});
return trustedHtml.replace('__value__', cleanedValue);
};

export default CustomDisplayComponent;
1 change: 1 addition & 0 deletions website/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const segmentedMutations = z.object({
export const customDisplay = z.object({
type: z.string(),
url: z.string().optional(),
html: z.string().optional(),
value: z.array(segmentedMutations).optional(),
displayGroup: z.string().optional(),
});
Expand Down

0 comments on commit 0dc400a

Please sign in to comment.