import { VariantFilters } from "./VariantFilters"; import { HtsFileMetadata, RecordParams } from "@molgenis/vip-report-api"; import { Component, createResource, Show } from "solid-js"; import { VariantType } from "../utils/variantType.ts"; import { useNavigate } from "@solidjs/router"; import { initConfig } from "../utils/config/config.ts"; import { createQuery } from "../utils/query/query.ts"; import { PageChangeEvent } from "./Pager"; import { InfoOrder, VariantRecords, writeVcf } from "@molgenis/vip-report-vcf"; import { fetchInfoOrder, fetchRecords, MetadataContainer, SampleContainer } from "../utils/api.ts"; import { createVcfDownloadFilename } from "../utils/download.ts"; import { RecordsPerPageChangeEvent } from "./RecordsPerPage"; import { SortChangeEvent } from "./Sort"; import { VariantTypeChangeEvent, VariantTypeSelect } from "./VariantTypeSelect"; import { Loader } from "./Loader"; import { VariantResults } from "./VariantResults"; import { FilterChangeEvent, FilterClearEvent } from "../types/filter"; import { VariantsContainerHeader } from "./VariantsContainerHeader"; import { href } from "../utils/utils.ts"; import { getPedigreeSamples } from "../utils/sample.ts"; import { ConfigJson } from "../types/config"; import { createSort } from "../utils/query/sort.ts"; import { VariantStore } from "../store/variants.ts"; export const VariantsContainer: Component<{ store: VariantStore; config: ConfigJson; metadata: MetadataContainer; variantType: VariantType; sample: SampleContainer | null; }> = (props) => { const navigate = useNavigate(); const config = () => initConfig(props.config, props.variantType, props.metadata, props.sample); const variantTypeIds = () => (props.sample !== null ? props.sample.variantTypeIds : props.metadata.variantTypeIds); const query = () => createQuery(config(), props.metadata, props.variantType, props.sample, props.store.getFilterValues()); const defaultSort = () => config().variants.sorts.find((configSort) => configSort.selected); const sort = () => createSort(props.store.getSort(), defaultSort()) || undefined; const defaultRecordsPerPage = () => config().variants.recordsPerPage.find((option) => option.selected)?.number || 10; const recordsPerPage = () => props.store.getPageSize() !== null ? props.store.getPageSize()! : defaultRecordsPerPage(); const sampleIds = () => { let sampleIds: number[] | undefined; if (props.sample !== null) { sampleIds = [props.sample.item.id]; if (props.sample.maternalSample !== null && props.sample.maternalSample !== undefined) { sampleIds.push(props.sample.maternalSample.id); } if (props.sample.paternalSample !== null && props.sample.paternalSample !== undefined) { sampleIds.push(props.sample.paternalSample.id); } } return sampleIds; }; const hasSvTypeField = () => { return Object.hasOwn(props.metadata.records.info, "SVTYPE"); }; const [records] = createResource( (): RecordParams => ({ query: query() || undefined, page: props.store.getPageNumber() || 0, size: recordsPerPage(), sort: sort(), sampleIds: sampleIds(), }), fetchRecords, ); const onFilterChange = (event: FilterChangeEvent) => { props.store.setFilterValue(event.id, event.value); }; const onFilterClear = (event: FilterClearEvent) => { props.store.clearFilter(event.id); }; const onPageChange = (event: PageChangeEvent) => { props.store.setPageNumber(event.page); }; const onRecordsDownload = async () => { const samples = props.sample ? getPedigreeSamples(props.sample) : []; const filter = samples ? { samples: samples.map((sample) => sample.data.person.individualId) } : undefined; const sampleIds = samples ? samples.map((sample) => sample.id) : ([] as number[]); // create vcf using all records that match filters, use default sort to ensure valid vcf ordering const records = await fetchRecords({ query: query() || undefined, page: 0, size: Number.MAX_SAFE_INTEGER, sampleIds: sampleIds, }); const infoOrder: InfoOrder = await fetchInfoOrder(); const vcf = writeVcf( { metadata: props.metadata.records, data: records.items.reduce((acc, item) => { acc[item.id] = item.data; return acc; }, {} as VariantRecords), infoOrder: infoOrder, }, filter, ); const url = window.URL.createObjectURL(new Blob([vcf])); const link = document.createElement("a"); link.href = url; link.setAttribute("download", createVcfDownloadFilename(props.metadata.app.htsFile as HtsFileMetadata)); document.body.appendChild(link); link.click(); document.body.removeChild(link); }; const onRecordsPerPageChange = (event: RecordsPerPageChangeEvent) => { props.store.setPageSize(event.number); }; const onSortChange = (event: SortChangeEvent) => { props.store.setSort(event.order); }; const onSortClear = () => { props.store.clearSort(); }; const onVariantTypeChange = (event: VariantTypeChangeEvent) => { const components = props.sample !== null ? ["samples", props.sample.item.id] : []; components.push("variants", event.id); navigate(href(components)); }; return ( <>