@genspectrum/dashboard-components 0.8.3 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +3 -3
- package/dist/dashboard-components.js +170 -165
- package/dist/dashboard-components.js.map +1 -1
- package/dist/genspectrum-components.d.ts +17 -16
- package/dist/style.css +20 -31
- package/package.json +1 -1
- package/src/preact/mutationFilter/mutation-filter.stories.tsx +95 -11
- package/src/preact/mutationFilter/mutation-filter.tsx +178 -175
- package/src/preact/mutationFilter/parseAndValidateMutation.ts +1 -1
- package/src/web-components/input/gs-mutation-filter.stories.ts +12 -2
- package/src/web-components/input/gs-mutation-filter.tsx +3 -2
- package/standalone-bundle/dashboard-components.js +8591 -8600
- package/standalone-bundle/dashboard-components.js.map +1 -1
package/custom-elements.json
CHANGED
|
@@ -903,7 +903,7 @@
|
|
|
903
903
|
"type": {
|
|
904
904
|
"text": "StoryObj<MutationFilterProps>"
|
|
905
905
|
},
|
|
906
|
-
"default": "{ ...Template, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter'); const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false }); const
|
|
906
|
+
"default": "{ ...Template, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter'); const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false }); const listenerMock = fn(); await step('Setup event listener mock', async () => { canvasElement.addEventListener('gs-mutation-filter-changed', listenerMock); }); await step('wait until data is loaded', async () => { await waitFor(() => { return expect(inputField()).toBeEnabled(); }); }); await step('Enter a valid mutation', async () => { await userEvent.type(inputField(), 'A123T'); const option = await canvas.findByRole('option'); await userEvent.click(option); await waitFor(() => expect(listenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { nucleotideMutations: ['A123T'], aminoAcidMutations: [], nucleotideInsertions: [], aminoAcidInsertions: [], }, }), ), ); }); }, }"
|
|
907
907
|
},
|
|
908
908
|
{
|
|
909
909
|
"kind": "variable",
|
|
@@ -911,7 +911,7 @@
|
|
|
911
911
|
"type": {
|
|
912
912
|
"text": "StoryObj<MutationFilterProps>"
|
|
913
913
|
},
|
|
914
|
-
"default": "{ ...Template, args: { initialValue: ['seg1:123T', 'gene2:56', 'ins_seg2:78:AAA'], }, parameters: { fetchMock: { mocks: [ { matcher: { name: 'referenceGenome', url: REFERENCE_GENOME_ENDPOINT, }, response: { status: 200, body: { nucleotideSequences: [ { name: 'seg1', sequence: 'dummy', }, { name: 'seg2', sequence: 'dummy', }, ], genes: [ { name: 'gene1', sequence: 'dummy', }, { name: 'gene2', sequence: 'dummy', }, ], }, }, options: { overwriteRoutes: false, }, }, ], }, }, play: async ({ canvasElement }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter'); await waitFor(() => { expect(canvas.getByText('seg1:123T')).toBeVisible(); expect(canvas.getByText('gene2:56')).toBeVisible(); return expect(canvas.getByText('ins_seg2:78:AAA')).toBeVisible(); }); }, }"
|
|
914
|
+
"default": "{ ...Template, args: { initialValue: ['seg1:123T', 'gene2:56', 'ins_seg2:78:AAA'], }, parameters: { fetchMock: { mocks: [ { matcher: { name: 'referenceGenome', url: REFERENCE_GENOME_ENDPOINT, }, response: { status: 200, body: { nucleotideSequences: [ { name: 'seg1', sequence: 'dummy', }, { name: 'seg2', sequence: 'dummy', }, ], genes: [ { name: 'gene1', sequence: 'dummy', }, { name: 'gene2', sequence: 'dummy', }, ], }, }, options: { overwriteRoutes: false, }, }, ], }, }, play: async ({ canvasElement }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter'); const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false }); await waitFor(() => { const placeholderText = inputField().getAttribute('placeholder'); expect(placeholderText).toEqual( 'Enter a mutation (e.g. seg1:A123T, ins_seg1:123:AT, gene1:M123E, ins_gene1:123:ME)', ); }); await waitFor(() => { expect(canvas.getByText('seg1:123T')).toBeVisible(); expect(canvas.getByText('gene2:56')).toBeVisible(); return expect(canvas.getByText('ins_seg2:78:AAA')).toBeVisible(); }); }, }"
|
|
915
915
|
}
|
|
916
916
|
],
|
|
917
917
|
"exports": [
|
|
@@ -955,7 +955,7 @@
|
|
|
955
955
|
"declarations": [
|
|
956
956
|
{
|
|
957
957
|
"kind": "class",
|
|
958
|
-
"description": "## Context\nThis component provides an input field to specify filters for nucleotide and amino acid mutations and insertions.\n\nInput values have to be provided one at a time and submitted by pressing the Enter key or by
|
|
958
|
+
"description": "## Context\nThis component provides an input field to specify filters for nucleotide and amino acid mutations and insertions.\n\nInput values have to be provided one at a time and submitted by pressing the Enter key or by selecting an option from the dropdown.\nAlternatively, they can be provided as a string of comma-separated values, which will be directly parsed and validated.\nAfter submission (after pressing Enter or pasting a comma-separated string) an event is fired with the selected mutations.\nAll previously selected mutations are displayed at the input field and added to the event.\nUsers can remove a mutation by clicking the 'x' button next to the mutation.\n\n## Input Validation\n\nValidation of the input is performed according to the following rules:\n\n### Mutations\n\nMutations have to conform to the following format: `<gene/segment>:<symbol at reference><position><Substituted symbol/Deletion>`\n- Gene/segment: The gene or segment where the mutation occurs. Must be contained in the reference genome.\n (Optional for elements with only one gene/segment)\n- Symbol at reference: The symbol at the reference position. (Optional)\n- Position: The position of the mutation. (Required)\n- Substituted symbol/Deletion: The substituted symbol or '-' for a deletion. (Required)\n\nExamples: `S:614G`, `614G`, `614-`, `614G`\n\n### Insertions\n\nInsertions have to conform to the following format: `ins_<gene/segment>:<position>:<Inserted symbols>`\n- Gene/segment: The gene or segment where the insertion occurs. Must be contained in the reference genome.\n (Optional for elements with only one gene/segment)\n- Position: The position of the insertion. (Required)\n- Inserted symbols: The symbols that are inserted. (Required)\n\nExamples: `ins_S:614:G`, `ins_614:G`",
|
|
959
959
|
"name": "MutationFilterComponent",
|
|
960
960
|
"members": [
|
|
961
961
|
{
|
|
@@ -4741,15 +4741,15 @@ input.tab:checked + .tab-content,
|
|
|
4741
4741
|
.mt-4 {
|
|
4742
4742
|
margin-top: 1rem;
|
|
4743
4743
|
}
|
|
4744
|
-
.inline-block {
|
|
4745
|
-
display: inline-block;
|
|
4746
|
-
}
|
|
4747
4744
|
.inline {
|
|
4748
4745
|
display: inline;
|
|
4749
4746
|
}
|
|
4750
4747
|
.flex {
|
|
4751
4748
|
display: flex;
|
|
4752
4749
|
}
|
|
4750
|
+
.inline-flex {
|
|
4751
|
+
display: inline-flex;
|
|
4752
|
+
}
|
|
4753
4753
|
.table {
|
|
4754
4754
|
display: table;
|
|
4755
4755
|
}
|
|
@@ -4819,6 +4819,9 @@ input.tab:checked + .tab-content,
|
|
|
4819
4819
|
--tw-translate-y: -50%;
|
|
4820
4820
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
4821
4821
|
}
|
|
4822
|
+
.cursor-pointer {
|
|
4823
|
+
cursor: pointer;
|
|
4824
|
+
}
|
|
4822
4825
|
.resize {
|
|
4823
4826
|
resize: both;
|
|
4824
4827
|
}
|
|
@@ -4867,9 +4870,6 @@ input.tab:checked + .tab-content,
|
|
|
4867
4870
|
.break-words {
|
|
4868
4871
|
overflow-wrap: break-word;
|
|
4869
4872
|
}
|
|
4870
|
-
.rounded-full {
|
|
4871
|
-
border-radius: 9999px;
|
|
4872
|
-
}
|
|
4873
4873
|
.rounded-lg {
|
|
4874
4874
|
border-radius: 0.5rem;
|
|
4875
4875
|
}
|
|
@@ -4898,12 +4898,6 @@ input.tab:checked + .tab-content,
|
|
|
4898
4898
|
.border-b-2 {
|
|
4899
4899
|
border-bottom-width: 2px;
|
|
4900
4900
|
}
|
|
4901
|
-
.border-solid {
|
|
4902
|
-
border-style: solid;
|
|
4903
|
-
}
|
|
4904
|
-
.border-none {
|
|
4905
|
-
border-style: none;
|
|
4906
|
-
}
|
|
4907
4901
|
.border-error {
|
|
4908
4902
|
--tw-border-opacity: 1;
|
|
4909
4903
|
border-color: var(--fallback-er,oklch(var(--er)/var(--tw-border-opacity, 1)));
|
|
@@ -4924,14 +4918,18 @@ input.tab:checked + .tab-content,
|
|
|
4924
4918
|
--tw-border-opacity: 1;
|
|
4925
4919
|
border-color: rgb(156 163 175 / var(--tw-border-opacity, 1));
|
|
4926
4920
|
}
|
|
4927
|
-
.border-
|
|
4921
|
+
.border-slate-500 {
|
|
4928
4922
|
--tw-border-opacity: 1;
|
|
4929
|
-
border-color: rgb(
|
|
4923
|
+
border-color: rgb(100 116 139 / var(--tw-border-opacity, 1));
|
|
4930
4924
|
}
|
|
4931
4925
|
.bg-red-200 {
|
|
4932
4926
|
--tw-bg-opacity: 1;
|
|
4933
4927
|
background-color: rgb(254 202 202 / var(--tw-bg-opacity, 1));
|
|
4934
4928
|
}
|
|
4929
|
+
.bg-slate-200 {
|
|
4930
|
+
--tw-bg-opacity: 1;
|
|
4931
|
+
background-color: rgb(226 232 240 / var(--tw-bg-opacity, 1));
|
|
4932
|
+
}
|
|
4935
4933
|
.bg-white {
|
|
4936
4934
|
--tw-bg-opacity: 1;
|
|
4937
4935
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
|
|
@@ -4945,10 +4943,6 @@ input.tab:checked + .tab-content,
|
|
|
4945
4943
|
.p-4 {
|
|
4946
4944
|
padding: 1rem;
|
|
4947
4945
|
}
|
|
4948
|
-
.px-2 {
|
|
4949
|
-
padding-left: 0.5rem;
|
|
4950
|
-
padding-right: 0.5rem;
|
|
4951
|
-
}
|
|
4952
4946
|
.px-4 {
|
|
4953
4947
|
padding-left: 1rem;
|
|
4954
4948
|
padding-right: 1rem;
|
|
@@ -5015,6 +5009,10 @@ input.tab:checked + .tab-content,
|
|
|
5015
5009
|
--tw-text-opacity: 1;
|
|
5016
5010
|
color: rgb(96 96 96 / var(--tw-text-opacity, 1));
|
|
5017
5011
|
}
|
|
5012
|
+
.text-black {
|
|
5013
|
+
--tw-text-opacity: 1;
|
|
5014
|
+
color: rgb(0 0 0 / var(--tw-text-opacity, 1));
|
|
5015
|
+
}
|
|
5018
5016
|
.text-blue-600 {
|
|
5019
5017
|
--tw-text-opacity: 1;
|
|
5020
5018
|
color: rgb(37 99 235 / var(--tw-text-opacity, 1));
|
|
@@ -5090,10 +5088,6 @@ input.tab:checked + .tab-content,
|
|
|
5090
5088
|
border-bottom-left-radius: var(--rounded-box, 1rem);
|
|
5091
5089
|
}
|
|
5092
5090
|
}
|
|
5093
|
-
.focus-within\\:border-gray-400:focus-within {
|
|
5094
|
-
--tw-border-opacity: 1;
|
|
5095
|
-
border-color: rgb(156 163 175 / var(--tw-border-opacity, 1));
|
|
5096
|
-
}
|
|
5097
5091
|
.hover\\:scale-110:hover {
|
|
5098
5092
|
--tw-scale-x: 1.1;
|
|
5099
5093
|
--tw-scale-y: 1.1;
|
|
@@ -5108,6 +5102,10 @@ input.tab:checked + .tab-content,
|
|
|
5108
5102
|
--tw-bg-opacity: 1;
|
|
5109
5103
|
background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
|
|
5110
5104
|
}
|
|
5105
|
+
.hover\\:bg-gray-300:hover {
|
|
5106
|
+
--tw-bg-opacity: 1;
|
|
5107
|
+
background-color: rgb(209 213 219 / var(--tw-bg-opacity, 1));
|
|
5108
|
+
}
|
|
5111
5109
|
.hover\\:font-bold:hover {
|
|
5112
5110
|
font-weight: 700;
|
|
5113
5111
|
}
|
|
@@ -5127,15 +5125,6 @@ input.tab:checked + .tab-content,
|
|
|
5127
5125
|
--tw-text-opacity: 1;
|
|
5128
5126
|
color: rgb(55 65 81 / var(--tw-text-opacity, 1));
|
|
5129
5127
|
}
|
|
5130
|
-
.focus\\:outline-none:focus {
|
|
5131
|
-
outline: 2px solid transparent;
|
|
5132
|
-
outline-offset: 2px;
|
|
5133
|
-
}
|
|
5134
|
-
.focus\\:ring-0:focus {
|
|
5135
|
-
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
5136
|
-
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
5137
|
-
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
5138
|
-
}
|
|
5139
5128
|
.peer:hover ~ .peer-hover\\:visible {
|
|
5140
5129
|
visibility: visible;
|
|
5141
5130
|
}
|
|
@@ -10001,31 +9990,19 @@ const MutationFilterInner = ({ initialValue }) => {
|
|
|
10001
9990
|
const [selectedFilters, setSelectedFilters] = h(
|
|
10002
9991
|
getInitialState(initialValue, referenceGenome)
|
|
10003
9992
|
);
|
|
10004
|
-
const
|
|
10005
|
-
const
|
|
10006
|
-
|
|
10007
|
-
const handleSubmit = (event) => {
|
|
10008
|
-
event.preventDefault();
|
|
10009
|
-
if (inputValue === "") {
|
|
10010
|
-
return;
|
|
10011
|
-
}
|
|
10012
|
-
const parsedMutation = parseAndValidateMutation(inputValue, referenceGenome);
|
|
10013
|
-
if (parsedMutation === null) {
|
|
10014
|
-
setIsError(true);
|
|
10015
|
-
return;
|
|
10016
|
-
}
|
|
10017
|
-
const newSelectedValues = {
|
|
9993
|
+
const filterRef = A(null);
|
|
9994
|
+
const handleRemoveValue = (option) => {
|
|
9995
|
+
const newSelectedFilters = {
|
|
10018
9996
|
...selectedFilters,
|
|
10019
|
-
[
|
|
9997
|
+
[option.type]: selectedFilters[option.type].filter((i2) => option.value.toString() != i2.toString())
|
|
10020
9998
|
};
|
|
10021
|
-
setSelectedFilters(
|
|
10022
|
-
fireChangeEvent(
|
|
10023
|
-
setInputValue("");
|
|
9999
|
+
setSelectedFilters(newSelectedFilters);
|
|
10000
|
+
fireChangeEvent(newSelectedFilters);
|
|
10024
10001
|
};
|
|
10025
10002
|
const fireChangeEvent = (selectedFilters2) => {
|
|
10026
10003
|
var _a;
|
|
10027
10004
|
const detail = mapToMutationFilterStrings(selectedFilters2);
|
|
10028
|
-
(_a =
|
|
10005
|
+
(_a = filterRef.current) == null ? void 0 : _a.dispatchEvent(
|
|
10029
10006
|
new CustomEvent("gs-mutation-filter-changed", {
|
|
10030
10007
|
detail,
|
|
10031
10008
|
bubbles: true,
|
|
@@ -10033,38 +10010,25 @@ const MutationFilterInner = ({ initialValue }) => {
|
|
|
10033
10010
|
})
|
|
10034
10011
|
);
|
|
10035
10012
|
};
|
|
10036
|
-
|
|
10037
|
-
|
|
10038
|
-
|
|
10039
|
-
};
|
|
10040
|
-
return /* @__PURE__ */ u$1("form", { className: "w-full border boder-gray-300 rounded-md relative", onSubmit: handleSubmit, ref: formRef, children: [
|
|
10041
|
-
/* @__PURE__ */ u$1("div", { className: "absolute -top-3 -right-3", children: /* @__PURE__ */ u$1(MutationFilterInfo, {}) }),
|
|
10042
|
-
/* @__PURE__ */ u$1("div", { className: "w-full flex p-2 flex-wrap items-center", children: [
|
|
10013
|
+
return /* @__PURE__ */ u$1("div", { className: "w-full border border-gray-300 rounded-md relative", ref: filterRef, children: [
|
|
10014
|
+
/* @__PURE__ */ u$1("div", { className: "absolute -top-3 -right-3 z-10", children: /* @__PURE__ */ u$1(MutationFilterInfo, {}) }),
|
|
10015
|
+
/* @__PURE__ */ u$1("div", { className: "relative w-full p-1", children: [
|
|
10043
10016
|
/* @__PURE__ */ u$1(
|
|
10044
|
-
|
|
10017
|
+
MutationFilterSelector,
|
|
10045
10018
|
{
|
|
10046
|
-
|
|
10047
|
-
setSelectedFilters
|
|
10048
|
-
|
|
10019
|
+
referenceGenome,
|
|
10020
|
+
setSelectedFilters: (newSelectedFilters) => {
|
|
10021
|
+
setSelectedFilters(newSelectedFilters);
|
|
10022
|
+
fireChangeEvent(newSelectedFilters);
|
|
10023
|
+
},
|
|
10024
|
+
selectedFilters
|
|
10049
10025
|
}
|
|
10050
10026
|
),
|
|
10051
10027
|
/* @__PURE__ */ u$1(
|
|
10052
|
-
|
|
10028
|
+
SelectedMutationFilterDisplay,
|
|
10053
10029
|
{
|
|
10054
|
-
|
|
10055
|
-
|
|
10056
|
-
/* @__PURE__ */ u$1(
|
|
10057
|
-
"input",
|
|
10058
|
-
{
|
|
10059
|
-
className: "grow flex-1 p-1 border-none focus:outline-none focus:ring-0",
|
|
10060
|
-
type: "text",
|
|
10061
|
-
value: inputValue,
|
|
10062
|
-
onInput: handleInputChange,
|
|
10063
|
-
placeholder: getPlaceholder(referenceGenome)
|
|
10064
|
-
}
|
|
10065
|
-
),
|
|
10066
|
-
/* @__PURE__ */ u$1("button", { type: "submit", className: "btn btn-xs m-1", children: "+" })
|
|
10067
|
-
]
|
|
10030
|
+
selectedFilters,
|
|
10031
|
+
handleRemoveValue
|
|
10068
10032
|
}
|
|
10069
10033
|
)
|
|
10070
10034
|
] })
|
|
@@ -10099,123 +10063,164 @@ function getInitialState(initialValue, referenceGenome) {
|
|
|
10099
10063
|
}
|
|
10100
10064
|
);
|
|
10101
10065
|
}
|
|
10066
|
+
const MutationFilterSelector = ({ referenceGenome, setSelectedFilters, selectedFilters }) => {
|
|
10067
|
+
const [option, setOption] = h(null);
|
|
10068
|
+
const [inputValue, setInputValue] = h("");
|
|
10069
|
+
const selectorRef = A(null);
|
|
10070
|
+
const handleInputChange = (newValue) => {
|
|
10071
|
+
if (newValue.includes(",") || newValue.includes(";")) {
|
|
10072
|
+
handleCommaSeparatedInput(newValue);
|
|
10073
|
+
} else {
|
|
10074
|
+
setInputValue(newValue);
|
|
10075
|
+
const result = parseAndValidateMutation(newValue, referenceGenome);
|
|
10076
|
+
setOption(result);
|
|
10077
|
+
}
|
|
10078
|
+
};
|
|
10079
|
+
const handleCommaSeparatedInput = (inputValue2) => {
|
|
10080
|
+
const inputValues = inputValue2.split(/[,;]/);
|
|
10081
|
+
let newSelectedOptions = selectedFilters;
|
|
10082
|
+
let updated = false;
|
|
10083
|
+
const invalidQueries = [];
|
|
10084
|
+
for (const value of inputValues) {
|
|
10085
|
+
const trimmedValue = value.trim();
|
|
10086
|
+
const parsedMutation = parseAndValidateMutation(trimmedValue, referenceGenome);
|
|
10087
|
+
if (parsedMutation) {
|
|
10088
|
+
const type = parsedMutation.type;
|
|
10089
|
+
if (!selectedFilters[type].some((i2) => parsedMutation.value.toString() === i2.toString())) {
|
|
10090
|
+
newSelectedOptions = {
|
|
10091
|
+
...newSelectedOptions,
|
|
10092
|
+
[parsedMutation.type]: [...newSelectedOptions[parsedMutation.type], parsedMutation.value]
|
|
10093
|
+
};
|
|
10094
|
+
updated = true;
|
|
10095
|
+
}
|
|
10096
|
+
} else {
|
|
10097
|
+
invalidQueries.push(trimmedValue);
|
|
10098
|
+
}
|
|
10099
|
+
}
|
|
10100
|
+
setInputValue(invalidQueries.join(","));
|
|
10101
|
+
if (updated) {
|
|
10102
|
+
setSelectedFilters(newSelectedOptions);
|
|
10103
|
+
setOption(null);
|
|
10104
|
+
}
|
|
10105
|
+
};
|
|
10106
|
+
const handleOptionClick = () => {
|
|
10107
|
+
if (option === null) {
|
|
10108
|
+
return;
|
|
10109
|
+
}
|
|
10110
|
+
const type = option.type;
|
|
10111
|
+
if (!selectedFilters[type].some((i2) => option.value.toString() === i2.toString())) {
|
|
10112
|
+
const newSelectedValues = {
|
|
10113
|
+
...selectedFilters,
|
|
10114
|
+
[option == null ? void 0 : option.type]: [...selectedFilters[option == null ? void 0 : option.type], option == null ? void 0 : option.value]
|
|
10115
|
+
};
|
|
10116
|
+
setSelectedFilters(newSelectedValues);
|
|
10117
|
+
}
|
|
10118
|
+
setInputValue("");
|
|
10119
|
+
setOption(null);
|
|
10120
|
+
};
|
|
10121
|
+
const handleEnterPress = (event) => {
|
|
10122
|
+
if (event.key === "Enter" && option !== null) {
|
|
10123
|
+
handleOptionClick();
|
|
10124
|
+
}
|
|
10125
|
+
};
|
|
10126
|
+
const handleBlur = (event) => {
|
|
10127
|
+
var _a;
|
|
10128
|
+
if (!((_a = selectorRef.current) == null ? void 0 : _a.contains(event.relatedTarget))) {
|
|
10129
|
+
setOption(null);
|
|
10130
|
+
}
|
|
10131
|
+
};
|
|
10132
|
+
return /* @__PURE__ */ u$1("div", { ref: selectorRef, tabIndex: -1, children: [
|
|
10133
|
+
/* @__PURE__ */ u$1(
|
|
10134
|
+
"input",
|
|
10135
|
+
{
|
|
10136
|
+
type: "text",
|
|
10137
|
+
className: "w-full p-2 border-gray-300 border rounded-md",
|
|
10138
|
+
placeholder: getPlaceholder(referenceGenome),
|
|
10139
|
+
value: inputValue,
|
|
10140
|
+
onInput: (e2) => {
|
|
10141
|
+
handleInputChange(e2.target.value);
|
|
10142
|
+
},
|
|
10143
|
+
onKeyDown: (e2) => handleEnterPress(e2),
|
|
10144
|
+
onFocus: () => handleInputChange(inputValue),
|
|
10145
|
+
onBlur: handleBlur
|
|
10146
|
+
}
|
|
10147
|
+
),
|
|
10148
|
+
option != null && /* @__PURE__ */ u$1(
|
|
10149
|
+
"div",
|
|
10150
|
+
{
|
|
10151
|
+
role: "option",
|
|
10152
|
+
className: "hover:bg-gray-300 absolute cursor-pointer p-2 border-1 border-slate-500 bg-slate-200",
|
|
10153
|
+
onClick: () => handleOptionClick(),
|
|
10154
|
+
children: option.value.toString()
|
|
10155
|
+
}
|
|
10156
|
+
)
|
|
10157
|
+
] });
|
|
10158
|
+
};
|
|
10102
10159
|
function getPlaceholder(referenceGenome) {
|
|
10103
10160
|
const segmentPrefix = referenceGenome.nucleotideSequences.length > 1 ? `${referenceGenome.nucleotideSequences[0].name}:` : "";
|
|
10104
10161
|
const firstGene = referenceGenome.genes[0].name;
|
|
10105
10162
|
return `Enter a mutation (e.g. ${segmentPrefix}A123T, ins_${segmentPrefix}123:AT, ${firstGene}:M123E, ins_${firstGene}:123:ME)`;
|
|
10106
10163
|
}
|
|
10107
|
-
const
|
|
10108
|
-
|
|
10109
|
-
|
|
10110
|
-
|
|
10111
|
-
|
|
10112
|
-
|
|
10113
|
-
|
|
10114
|
-
|
|
10115
|
-
|
|
10116
|
-
|
|
10164
|
+
const backgroundColor = {
|
|
10165
|
+
aminoAcidMutations: singleGraphColorRGBByName("teal", 0.4),
|
|
10166
|
+
nucleotideMutations: singleGraphColorRGBByName("green", 0.4),
|
|
10167
|
+
aminoAcidInsertions: singleGraphColorRGBByName("purple", 0.4),
|
|
10168
|
+
nucleotideInsertions: singleGraphColorRGBByName("indigo", 0.4)
|
|
10169
|
+
};
|
|
10170
|
+
const backgroundColorMap = (data) => {
|
|
10171
|
+
return backgroundColor[data.type] || "lightgray";
|
|
10172
|
+
};
|
|
10173
|
+
const SelectedMutationFilterDisplay = ({ selectedFilters, handleRemoveValue }) => {
|
|
10174
|
+
return /* @__PURE__ */ u$1("div", { className: "flex flex-wrap", children: [
|
|
10117
10175
|
selectedFilters.nucleotideMutations.map((mutation) => /* @__PURE__ */ u$1(
|
|
10118
|
-
|
|
10176
|
+
SelectedFilter,
|
|
10119
10177
|
{
|
|
10120
|
-
|
|
10121
|
-
|
|
10178
|
+
handleRemoveValue,
|
|
10179
|
+
mutationFilter: { type: "nucleotideMutations", value: mutation }
|
|
10122
10180
|
},
|
|
10123
10181
|
mutation.toString()
|
|
10124
10182
|
)),
|
|
10125
10183
|
selectedFilters.aminoAcidMutations.map((mutation) => /* @__PURE__ */ u$1(
|
|
10126
|
-
|
|
10184
|
+
SelectedFilter,
|
|
10127
10185
|
{
|
|
10128
|
-
|
|
10129
|
-
|
|
10186
|
+
handleRemoveValue,
|
|
10187
|
+
mutationFilter: { type: "aminoAcidMutations", value: mutation }
|
|
10130
10188
|
},
|
|
10131
10189
|
mutation.toString()
|
|
10132
10190
|
)),
|
|
10133
|
-
selectedFilters.nucleotideInsertions.map((
|
|
10134
|
-
|
|
10191
|
+
selectedFilters.nucleotideInsertions.map((mutation) => /* @__PURE__ */ u$1(
|
|
10192
|
+
SelectedFilter,
|
|
10135
10193
|
{
|
|
10136
|
-
|
|
10137
|
-
|
|
10194
|
+
handleRemoveValue,
|
|
10195
|
+
mutationFilter: { type: "nucleotideInsertions", value: mutation }
|
|
10138
10196
|
},
|
|
10139
|
-
|
|
10197
|
+
mutation.toString()
|
|
10140
10198
|
)),
|
|
10141
|
-
selectedFilters.aminoAcidInsertions.map((
|
|
10142
|
-
|
|
10199
|
+
selectedFilters.aminoAcidInsertions.map((mutation) => /* @__PURE__ */ u$1(
|
|
10200
|
+
SelectedFilter,
|
|
10143
10201
|
{
|
|
10144
|
-
|
|
10145
|
-
|
|
10202
|
+
handleRemoveValue,
|
|
10203
|
+
mutationFilter: { type: "aminoAcidInsertions", value: mutation }
|
|
10146
10204
|
},
|
|
10147
|
-
|
|
10205
|
+
mutation.toString()
|
|
10148
10206
|
))
|
|
10149
10207
|
] });
|
|
10150
10208
|
};
|
|
10151
|
-
const
|
|
10152
|
-
const backgroundColor = singleGraphColorRGBByName("teal", 0.3);
|
|
10153
|
-
const textColor = singleGraphColorRGBByName("teal", 1);
|
|
10154
|
-
return /* @__PURE__ */ u$1(
|
|
10155
|
-
SelectedFilter,
|
|
10156
|
-
{
|
|
10157
|
-
mutation: insertion,
|
|
10158
|
-
onDelete,
|
|
10159
|
-
backgroundColor,
|
|
10160
|
-
textColor
|
|
10161
|
-
}
|
|
10162
|
-
);
|
|
10163
|
-
};
|
|
10164
|
-
const SelectedAminoAcidMutation = ({ mutation, onDelete }) => {
|
|
10165
|
-
const backgroundColor = singleGraphColorRGBByName("rose", 0.3);
|
|
10166
|
-
const textColor = singleGraphColorRGBByName("rose", 1);
|
|
10167
|
-
return /* @__PURE__ */ u$1(
|
|
10168
|
-
SelectedFilter,
|
|
10169
|
-
{
|
|
10170
|
-
mutation,
|
|
10171
|
-
onDelete,
|
|
10172
|
-
backgroundColor,
|
|
10173
|
-
textColor
|
|
10174
|
-
}
|
|
10175
|
-
);
|
|
10176
|
-
};
|
|
10177
|
-
const SelectedNucleotideMutation = ({ mutation, onDelete }) => {
|
|
10178
|
-
const backgroundColor = singleGraphColorRGBByName("indigo", 0.3);
|
|
10179
|
-
const textColor = singleGraphColorRGBByName("indigo", 1);
|
|
10180
|
-
return /* @__PURE__ */ u$1(
|
|
10181
|
-
SelectedFilter,
|
|
10182
|
-
{
|
|
10183
|
-
mutation,
|
|
10184
|
-
onDelete,
|
|
10185
|
-
backgroundColor,
|
|
10186
|
-
textColor
|
|
10187
|
-
}
|
|
10188
|
-
);
|
|
10189
|
-
};
|
|
10190
|
-
const SelectedNucleotideInsertion = ({ insertion, onDelete }) => {
|
|
10191
|
-
const backgroundColor = singleGraphColorRGBByName("green", 0.3);
|
|
10192
|
-
const textColor = singleGraphColorRGBByName("green", 1);
|
|
10193
|
-
return /* @__PURE__ */ u$1(
|
|
10194
|
-
SelectedFilter,
|
|
10195
|
-
{
|
|
10196
|
-
mutation: insertion,
|
|
10197
|
-
onDelete,
|
|
10198
|
-
backgroundColor,
|
|
10199
|
-
textColor
|
|
10200
|
-
}
|
|
10201
|
-
);
|
|
10202
|
-
};
|
|
10203
|
-
const SelectedFilter = ({
|
|
10204
|
-
mutation,
|
|
10205
|
-
onDelete,
|
|
10206
|
-
backgroundColor,
|
|
10207
|
-
textColor
|
|
10208
|
-
}) => {
|
|
10209
|
+
const SelectedFilter = ({ handleRemoveValue, mutationFilter }) => {
|
|
10209
10210
|
return /* @__PURE__ */ u$1(
|
|
10210
10211
|
"span",
|
|
10211
10212
|
{
|
|
10212
|
-
|
|
10213
|
-
|
|
10213
|
+
name: mutationFilter.value.toString(),
|
|
10214
|
+
className: "center p-2 m-1 inline-flex text-black rounded-md",
|
|
10215
|
+
style: {
|
|
10216
|
+
backgroundColor: backgroundColorMap(mutationFilter)
|
|
10217
|
+
},
|
|
10214
10218
|
children: [
|
|
10215
|
-
|
|
10216
|
-
/* @__PURE__ */ u$1("button", { className: "ml-1",
|
|
10219
|
+
mutationFilter.value.toString(),
|
|
10220
|
+
/* @__PURE__ */ u$1("button", { className: "ml-1", onClick: () => handleRemoveValue(mutationFilter), children: "×" })
|
|
10217
10221
|
]
|
|
10218
|
-
}
|
|
10222
|
+
},
|
|
10223
|
+
mutationFilter.value.toString()
|
|
10219
10224
|
);
|
|
10220
10225
|
};
|
|
10221
10226
|
function mapToMutationFilterStrings(selectedFilters) {
|