diff --git a/src/components/explorer/Excluded.tsx b/src/components/explorer/Excluded.tsx
new file mode 100644
index 000000000..0b142a584
--- /dev/null
+++ b/src/components/explorer/Excluded.tsx
@@ -0,0 +1,35 @@
+import { LinkOutlined } from "@ant-design/icons";
+import type { ColumnFilterItem } from "antd/es/table/interface";
+
+type ExcludedProps = {
+ model: "phenotype" | "disease";
+};
+
+type ExcludedTableColumnFilterConfig = {
+ filters: ColumnFilterItem[];
+ onFilter: (value: "excluded" | "not_excluded", record: { excluded: boolean }) => boolean;
+};
+
+export const excludedTableColumnFilterConfig: ExcludedTableColumnFilterConfig = {
+ filters: [
+ { text: "Excluded", value: "excluded" },
+ { text: "Not Excluded", value: "not_excluded" },
+ ],
+ onFilter: (value, { excluded }) => (value === "excluded" ? excluded : !excluded),
+};
+
+const Excluded = ({ model }: ExcludedProps) => (
+
+ (Excluded: Found to be absent{" "}
+
+
+
+ )
+
+);
+
+export default Excluded;
diff --git a/src/components/explorer/IndividualDiseases.js b/src/components/explorer/IndividualDiseases.js
index 12bd1cd9d..bf203246b 100644
--- a/src/components/explorer/IndividualDiseases.js
+++ b/src/components/explorer/IndividualDiseases.js
@@ -2,12 +2,13 @@ import { Descriptions } from "antd";
import PropTypes from "prop-types";
import { diseasePropTypesShape, individualPropTypesShape } from "@/propTypes";
-import { booleanFieldSorter, ontologyTermSorter, renderBoolean, useIndividualPhenopacketDataIndex } from "./utils";
+import { ontologyTermSorter, useIndividualPhenopacketDataIndex } from "./utils";
import OntologyTerm, { OntologyTermList } from "./OntologyTerm";
import TimeElement from "./TimeElement";
import { RoutedIndividualContent, RoutedIndividualContentTable } from "./RoutedIndividualContent";
import ExtraProperties from "./ExtraProperties";
+import Excluded, { excludedTableColumnFilterConfig } from "@/components/explorer/Excluded";
// TODO: Only show diseases from the relevant dataset, if specified;
// highlight those found in search results, if specified
@@ -18,15 +19,15 @@ const DISEASES_COLUMNS = [
dataIndex: "term",
// Tag the ontology term with a data attribute holding the disease ID. This has no effect, but might
// help us debug diseases in production if we need it.
- render: (term, disease) => ,
+ // Render excluded beside ontology term with a link to the documentation, if this disease is excluded.
+ render: (term, { id, excluded }) => (
+ <>
+ {excluded ? : null}
+ >
+ ),
+ ...excludedTableColumnFilterConfig,
sorter: ontologyTermSorter("term"),
},
- {
- title: "Excluded",
- dataIndex: "excluded",
- render: renderBoolean("excluded"),
- sorter: booleanFieldSorter("excluded"),
- },
{
title: "Onset Age",
dataIndex: "onset",
diff --git a/src/components/explorer/IndividualPhenotypicFeatures.js b/src/components/explorer/IndividualPhenotypicFeatures.js
index f28baed30..bd92165da 100644
--- a/src/components/explorer/IndividualPhenotypicFeatures.js
+++ b/src/components/explorer/IndividualPhenotypicFeatures.js
@@ -7,12 +7,14 @@ import { EM_DASH } from "@/constants";
import { evidencePropTypesShape, individualPropTypesShape, phenotypicFeaturePropTypesShape } from "@/propTypes";
import { isValidUrl } from "@/utils/url";
+import Excluded, { excludedTableColumnFilterConfig } from "./Excluded";
+import ExtraProperties from "./ExtraProperties";
import OntologyTerm, { conditionalOntologyRender } from "./OntologyTerm";
-import { booleanFieldSorter, renderBoolean } from "./utils";
import TimeElement from "./TimeElement";
import { RoutedIndividualContent, RoutedIndividualContentTable } from "./RoutedIndividualContent";
-import ExtraProperties from "./ExtraProperties";
+import { ontologyTermSorter } from "@/components/explorer/utils";
+// noinspection JSUnusedGlobalSymbols
const PHENOTYPIC_FEATURES_COLUMNS = [
{
title: "Feature",
@@ -25,31 +27,14 @@ const PHENOTYPIC_FEATURES_COLUMNS = [
) : (
<>
- {" "}
- {excluded ? (
-
- (Excluded: Found to be absent{" "}
-
-
-
- )
-
- ) : null}
+ {excluded ? : null}
>
),
+ ...excludedTableColumnFilterConfig,
onCell: ({ header }) => ({
colSpan: header ? 2 : 1,
}),
- },
- {
- title: "Excluded",
- key: "excluded",
- render: renderBoolean("excluded"),
- sorter: booleanFieldSorter("excluded"),
+ sorter: ontologyTermSorter("type"),
},
{
title: "Severity",
diff --git a/src/components/explorer/utils.js b/src/components/explorer/utils.js
index 4076e001e..a5e90143f 100644
--- a/src/components/explorer/utils.js
+++ b/src/components/explorer/utils.js
@@ -1,7 +1,6 @@
import { useEffect, useMemo } from "react";
import { useDispatch, useSelector } from "react-redux";
import { fetchDatasetResourcesIfNecessary } from "@/modules/datasets/actions";
-import { EM_DASH } from "@/constants";
export const useDeduplicatedIndividualBiosamples = (individual) =>
useMemo(
@@ -136,21 +135,4 @@ export const ontologyTermSorter = (k) => (a, b) => {
return 0;
};
-export const booleanFieldSorter = (k) => (a, b) => {
- const aVal = a[k];
- const bVal = b[k];
- if (typeof aVal === "boolean" && typeof bVal === "boolean") {
- return aVal - bVal;
- }
- return 0;
-};
-
-export const renderBoolean = (k) => (_, record) => {
- const value = record[k];
- if (typeof value === "boolean") {
- return String(value);
- }
- return EM_DASH;
-};
-
export const explorerIndividualUrl = (individualID) => `/data/explorer/individuals/${individualID}`;