From 98c76b9d0e7f78ef04ee9a2c0af1738817f709f8 Mon Sep 17 00:00:00 2001 From: Fran McDade Date: Tue, 14 May 2024 16:03:14 +1000 Subject: [PATCH] feat: add download manifest under a feature flag (#4032) (#4033) Co-authored-by: Fran McDade --- .../ExportMethod/exportMethod.tsx | 23 ++++ .../ManifestDownload/manifestDownload.tsx | 29 +++++ .../common/MDXContent/anvil-cmg/index.tsx | 2 + .../anvil-cmg/manifestDownloadStart.mdx | 3 + .../anvil-cmg/manifestDownloadSuccess.mdx | 3 + explorer/app/components/index.tsx | 2 + .../anvil-cmg/common/viewModelBuilders.ts | 101 ++++++++++++++++-- .../app/viewModelBuilders/common/contants.ts | 1 + .../anvil-cmg/dev/export/constants.ts | 1 + .../anvil-cmg/dev/export/export.ts | 31 +++++- 10 files changed, 185 insertions(+), 11 deletions(-) create mode 100644 explorer/app/components/Export/components/AnVILExplorer/ExportMethod/exportMethod.tsx create mode 100644 explorer/app/components/Export/components/AnVILExplorer/ManifestDownload/manifestDownload.tsx create mode 100644 explorer/app/components/common/MDXContent/anvil-cmg/manifestDownloadStart.mdx create mode 100644 explorer/app/components/common/MDXContent/anvil-cmg/manifestDownloadSuccess.mdx diff --git a/explorer/app/components/Export/components/AnVILExplorer/ExportMethod/exportMethod.tsx b/explorer/app/components/Export/components/AnVILExplorer/ExportMethod/exportMethod.tsx new file mode 100644 index 000000000..97ee1c7de --- /dev/null +++ b/explorer/app/components/Export/components/AnVILExplorer/ExportMethod/exportMethod.tsx @@ -0,0 +1,23 @@ +"use client"; +import { + ExportMethod as DXExportMethod, + ExportMethodProps, +} from "@databiosphere/findable-ui/lib/components/Export/components/ExportMethod/exportMethod"; +import { useExploreState } from "@databiosphere/findable-ui/lib/hooks/useExploreState"; +import React, { Fragment, useEffect, useState } from "react"; +import { FEATURE_FLAGS } from "../../../../../viewModelBuilders/common/contants"; + +export const ExportMethod = ({ ...props }: ExportMethodProps): JSX.Element => { + const { + exploreState: { featureFlagState }, + } = useExploreState(); + const [showMethod, setShowMethod] = useState(false); + + useEffect(() => { + if (featureFlagState) { + setShowMethod(featureFlagState === FEATURE_FLAGS.MANIFEST); + } + }, [featureFlagState]); + + return showMethod ? : ; +}; diff --git a/explorer/app/components/Export/components/AnVILExplorer/ManifestDownload/manifestDownload.tsx b/explorer/app/components/Export/components/AnVILExplorer/ManifestDownload/manifestDownload.tsx new file mode 100644 index 000000000..5670f9ddf --- /dev/null +++ b/explorer/app/components/Export/components/AnVILExplorer/ManifestDownload/manifestDownload.tsx @@ -0,0 +1,29 @@ +import { Alert } from "@databiosphere/findable-ui/lib/components/common/Alert/alert"; +import { + ManifestDownload as DXManifestDownload, + ManifestDownloadProps, +} from "@databiosphere/findable-ui/lib/components/Export/components/ManifestDownload/manifestDownload"; +import { useExploreState } from "@databiosphere/findable-ui/lib/hooks/useExploreState"; +import { useEffect, useState } from "react"; +import { FEATURE_FLAGS } from "../../../../../viewModelBuilders/common/contants"; + +export const ManifestDownload = ({ + ...props +}: ManifestDownloadProps): JSX.Element => { + const { + exploreState: { featureFlagState }, + } = useExploreState(); + const [showExport, setShowExport] = useState(false); + + useEffect(() => { + if (featureFlagState) { + setShowExport(featureFlagState === FEATURE_FLAGS.MANIFEST); + } + }, [featureFlagState]); + + return showExport ? ( + + ) : ( + + ); +}; diff --git a/explorer/app/components/common/MDXContent/anvil-cmg/index.tsx b/explorer/app/components/common/MDXContent/anvil-cmg/index.tsx index e2e23df30..fcf8eb74b 100644 --- a/explorer/app/components/common/MDXContent/anvil-cmg/index.tsx +++ b/explorer/app/components/common/MDXContent/anvil-cmg/index.tsx @@ -8,3 +8,5 @@ export { default as LoginReminder } from "./loginReminder.mdx"; export { default as LoginTermsOfService } from "./loginTermsOfService.mdx"; export { default as LoginText } from "./loginText.mdx"; export { default as LoginWarning } from "./loginWarning.mdx"; +export { default as ManifestDownloadStart } from "./manifestDownloadStart.mdx"; +export { default as ManifestDownloadSuccess } from "./manifestDownloadSuccess.mdx"; diff --git a/explorer/app/components/common/MDXContent/anvil-cmg/manifestDownloadStart.mdx b/explorer/app/components/common/MDXContent/anvil-cmg/manifestDownloadStart.mdx new file mode 100644 index 000000000..08ed10402 --- /dev/null +++ b/explorer/app/components/common/MDXContent/anvil-cmg/manifestDownloadStart.mdx @@ -0,0 +1,3 @@ +### Confirm Organism Type and Manifest File Formats + +Please explicitly select at least one organism type and file format for inclusion in the manifest. diff --git a/explorer/app/components/common/MDXContent/anvil-cmg/manifestDownloadSuccess.mdx b/explorer/app/components/common/MDXContent/anvil-cmg/manifestDownloadSuccess.mdx new file mode 100644 index 000000000..bd5ecf11b --- /dev/null +++ b/explorer/app/components/common/MDXContent/anvil-cmg/manifestDownloadSuccess.mdx @@ -0,0 +1,3 @@ +### Your File Manifest is Ready + +This link expires in 7 days. diff --git a/explorer/app/components/index.tsx b/explorer/app/components/index.tsx index 6cdf2c892..d91e185d8 100644 --- a/explorer/app/components/index.tsx +++ b/explorer/app/components/index.tsx @@ -89,6 +89,8 @@ export { FileLocationCopy } from "./Detail/components/GeneratedMatricesTables/co export { FileLocationDownload } from "./Detail/components/GeneratedMatricesTables/components/FileLocationDownload/fileLocationDownload"; export { FileNameCell } from "./Detail/components/GeneratedMatricesTables/components/FileNameCell/fileNameCell"; export { GeneratedMatricesTables } from "./Detail/components/GeneratedMatricesTables/generatedMatricesTables"; +export { ExportMethod as AnVILExportMethod } from "./Export/components/AnVILExplorer/ExportMethod/exportMethod"; +export { ManifestDownload as AnVILManifestDownload } from "./Export/components/AnVILExplorer/ManifestDownload/manifestDownload"; export { ConsentCodesCell } from "./Index/components/ConsentCodesCell/consentCodesCell"; export { CopyCell } from "./Index/components/CopyCell/copyCell"; export { ANVILBranding } from "./Layout/components/Footer/components/Branding/components/ANVILBranding/anvilBranding"; diff --git a/explorer/app/viewModelBuilders/azul/anvil-cmg/common/viewModelBuilders.ts b/explorer/app/viewModelBuilders/azul/anvil-cmg/common/viewModelBuilders.ts index ffce53bda..525ab58df 100644 --- a/explorer/app/viewModelBuilders/azul/anvil-cmg/common/viewModelBuilders.ts +++ b/explorer/app/viewModelBuilders/azul/anvil-cmg/common/viewModelBuilders.ts @@ -43,7 +43,10 @@ import { ANVIL_CMG_CATEGORY_KEY, ANVIL_CMG_CATEGORY_LABEL, } from "../../../../../site-config/anvil-cmg/category"; -import { ROUTE_EXPORT_TO_TERRA } from "../../../../../site-config/anvil-cmg/dev/export/constants"; +import { + ROUTE_EXPORT_TO_TERRA, + ROUTE_MANIFEST_DOWNLOAD, +} from "../../../../../site-config/anvil-cmg/dev/export/constants"; import { URL_DATASETS } from "../../../../../site-config/anvil/dev/config"; import { AggregatedBioSampleResponse, @@ -482,6 +485,23 @@ export function buildExportHero( }; } +/** + * Build props for manifest download Hero component. + * @param _ - Unused. + * @param viewContext - View context. + * @returns model to be used as props for the Hero component. + */ +export const buildExportMethodHeroManifestDownload = ( + _: Unused, + viewContext: ViewContext +): React.ComponentProps => { + const title = "Request File Manifest"; + const { + exploreState: { tabValue }, + } = viewContext; + return getExportMethodHero(tabValue, title); +}; + /** * Build props for export to terra Hero component. * @param _ - Unused. @@ -499,6 +519,26 @@ export const buildExportMethodHeroTerra = ( return getExportMethodHero(tabValue, title); }; +/** + * Build props for ExportMethod component for display of the manifest download section. + * @param _ - Unused. + * @param viewContext - View context. + * @returns model to be used as props for the ExportMethod component. + */ +export const buildExportMethodManifestDownload = ( + _: Unused, + viewContext: ViewContext +): React.ComponentProps => { + return { + ...getExportMethodAccessibility(viewContext), + buttonLabel: "Request File Manifest", + description: + "Request a file manifest for the current query containing the full list of selected files and the metadata for each file.", + route: ROUTE_MANIFEST_DOWNLOAD, + title: "Download a File Manifest with Metadata for the Selected Data", + }; +}; + /** * Build props for ExportMethod component for display of the export to terra metadata section. * @param _ - Unused. @@ -509,19 +549,11 @@ export const buildExportMethodTerra = ( _: Unused, viewContext: ViewContext ): React.ComponentProps => { - const { fileManifestState } = viewContext; - const { isFacetsSuccess } = fileManifestState; - const isAccessible = isFileManifestAccessible(fileManifestState); return { + ...getExportMethodAccessibility(viewContext), buttonLabel: "Analyze in Terra", description: "Terra is a biomedical research platform to analyze data using workflows, Jupyter Notebooks, RStudio, and Galaxy.", - footnote: isFacetsSuccess - ? isAccessible - ? null - : "You currently don’t have access to any files matching the query." - : null, - isAccessible: isFacetsSuccess && isAccessible, route: ROUTE_EXPORT_TO_TERRA, title: "Export Study Data and Metadata to Terra Workspace", }; @@ -695,6 +727,34 @@ export const buildListWarning = ( }; }; +/** + * Build props for ManifestDownload component. + * @param _ - Unused. + * @param viewContext - View context. + * @returns model to be used as props for the ManifestDownload component. + */ +export const buildManifestDownload = ( + _: Unused, + viewContext: ViewContext +): React.ComponentProps => { + const { + exploreState: { filterState }, + fileManifestState, + } = viewContext; + // Get the form facets. + const formFacet = getFormFacets(fileManifestState); + return { + ManifestDownloadForm: C.ManifestDownloadForm, + ManifestDownloadStart: MDX.ManifestDownloadStart, + ManifestDownloadSuccess: MDX.ManifestDownloadSuccess, + fileManifestState, + fileManifestType: FILE_MANIFEST_TYPE.DOWNLOAD_MANIFEST, + fileSummaryFacetName: ANVIL_CMG_CATEGORY_KEY.FILE_FILE_FORMAT, + filters: filterState, + formFacet, + }; +}; + /** * Build props for organism type cell component from the given donors response. * @param response - Response model return from index/donors API endpoint. @@ -929,6 +989,27 @@ function getExportEntityFilters(datasetsResponse: DatasetsResponse): Filters { ]; } +/** + * Returns the export method accessibility. + * @param viewContext - View context. + * @returns export method accessibility. + */ +function getExportMethodAccessibility( + viewContext: ViewContext +): Partial { + const { fileManifestState } = viewContext; + const { isFacetsSuccess } = fileManifestState; + const isAccessible = isFileManifestAccessible(fileManifestState); + return { + footnote: isFacetsSuccess + ? isAccessible + ? null + : "You currently don’t have access to any files matching the query." + : null, + isAccessible: isFacetsSuccess && isAccessible, + }; +} + /** * Returns breadcrumbs and title for export method Hero component. * @param explorePath - Explore path. diff --git a/explorer/app/viewModelBuilders/common/contants.ts b/explorer/app/viewModelBuilders/common/contants.ts index f3b2b5b8b..618c41357 100644 --- a/explorer/app/viewModelBuilders/common/contants.ts +++ b/explorer/app/viewModelBuilders/common/contants.ts @@ -6,5 +6,6 @@ export const DATE_TIME_FORMAT_OPTIONS: Intl.DateTimeFormatOptions = { }; export const DATE_TIME_LOCALES = "en-US"; export const FEATURE_FLAGS = { + MANIFEST: "manifest", VERBATIM: "verbatim", }; diff --git a/explorer/site-config/anvil-cmg/dev/export/constants.ts b/explorer/site-config/anvil-cmg/dev/export/constants.ts index 2d42fa078..1af8b4659 100644 --- a/explorer/site-config/anvil-cmg/dev/export/constants.ts +++ b/explorer/site-config/anvil-cmg/dev/export/constants.ts @@ -1 +1,2 @@ export const ROUTE_EXPORT_TO_TERRA = "/export/export-to-terra"; +export const ROUTE_MANIFEST_DOWNLOAD = "/export/download-manifest"; diff --git a/explorer/site-config/anvil-cmg/dev/export/export.ts b/explorer/site-config/anvil-cmg/dev/export/export.ts index 9392a4aeb..1e77e2ff2 100644 --- a/explorer/site-config/anvil-cmg/dev/export/export.ts +++ b/explorer/site-config/anvil-cmg/dev/export/export.ts @@ -4,7 +4,7 @@ import { } from "@databiosphere/findable-ui/lib/config/entities"; import * as C from "../../../../app/components"; import * as V from "../../../../app/viewModelBuilders/azul/anvil-cmg/common/viewModelBuilders"; -import { ROUTE_EXPORT_TO_TERRA } from "./constants"; +import { ROUTE_EXPORT_TO_TERRA, ROUTE_MANIFEST_DOWNLOAD } from "./constants"; import { mainColumn as exportMainColumn } from "./exportMainColumn"; import { sideColumn as exportSideColumn } from "./exportSideColumn"; @@ -35,6 +35,31 @@ export const exportConfig: ExportConfig = { } as ComponentConfig, ], }, + { + mainColumn: [ + /* mainColumn - top section - warning - some datasets are not available */ + ...exportMainColumn, + /* mainColumn */ + { + children: [ + { + component: C.AnVILManifestDownload, // TODO update component to ManifestDownload when feature flag is no longer required. + viewBuilder: V.buildManifestDownload, + } as ComponentConfig, + ], + component: C.BackPageContentMainColumn, + } as ComponentConfig, + /* sideColumn */ + ...exportSideColumn, + ], + route: ROUTE_MANIFEST_DOWNLOAD, + top: [ + { + component: C.BackPageHero, + viewBuilder: V.buildExportMethodHeroManifestDownload, + } as ComponentConfig, + ], + }, ], staticLoad: true, //TODO is this correct? tabs: [ @@ -50,6 +75,10 @@ export const exportConfig: ExportConfig = { component: C.ExportMethod, viewBuilder: V.buildExportMethodTerra, } as ComponentConfig, + { + component: C.AnVILExportMethod, // TODO update component to ExportMethod when feature flag is no longer required. + viewBuilder: V.buildExportMethodManifestDownload, + } as ComponentConfig, ], component: C.BackPageContentMainColumn, } as ComponentConfig,