From fda46d2400280ad67f859e3edad3a3257a25b13c Mon Sep 17 00:00:00 2001 From: Nayib Gloria <55710092+nayib-jose-gloria@users.noreply.github.com> Date: Fri, 4 Oct 2024 13:10:09 -0400 Subject: [PATCH 1/5] chore: update schema reference urls to use 'latest-schema' redirect url (#7347) --- backend/curation/api/curation-api.yml | 52 +++++++++---------- .../032__Contribute and Publish Data.mdx | 4 +- .../doc-site/03__Download Published Data.mdx | 4 +- .../4_2_2__Cell Type and Gene Ordering.mdx | 2 +- .../Content/components/DataFormat/index.tsx | 2 +- .../components/CopyCaption/index.tsx | 2 +- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/backend/curation/api/curation-api.yml b/backend/curation/api/curation-api.yml index 818581484ac89..ca16b07b5dbf5 100644 --- a/backend/curation/api/curation-api.yml +++ b/backend/curation/api/curation-api.yml @@ -762,7 +762,7 @@ components: batch_condition: description: | These keys define the batches that a normalization or integration algorithm should be aware of. - [batch condition schema](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#batch_condition) + [batch condition schema](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#batch_condition) type: array items: @@ -774,7 +774,7 @@ components: Citation that includes downloadable permalink to h5ad artifact for this dataset, a permalink to collection it belongs to in CZ CELLxGENE Discover, and--if applicable--the Publication DOI associated with the dataset. See details about the exact format in the - [schema definition](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#citation) + [schema definition](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#citation) type: string nullable: true collection_list: @@ -1027,7 +1027,7 @@ components: type: integer cell_type: description: | - [cell type label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#cell_type) + [cell type label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#cell_type) default: [] items: $ref: "#/components/schemas/ontology_element" @@ -1042,7 +1042,7 @@ components: $ref: "#/components/schemas/default_embedding" development_stage: description: | - [development stage label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#development_stage) + [development stage label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#development_stage) default: [] items: $ref: "#/components/schemas/ontology_element" @@ -1069,7 +1069,7 @@ components: type: number title: description: | - [title](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#title) + [title](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#title) nullable: true type: string organism: @@ -1096,14 +1096,14 @@ components: type: string self_reported_ethnicity: description: | - [self reported ethnicity label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#self_reported_ethnicity) + [self reported ethnicity label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#self_reported_ethnicity) default: [] items: $ref: "#/components/schemas/ontology_element" type: array sex: description: | - [sex label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#sex) + [sex label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#sex) default: [] items: $ref: "#/components/schemas/ontology_element" @@ -1135,7 +1135,7 @@ components: type: integer cell_type: description: | - [cell type label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#cell_type) + [cell type label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#cell_type) default: [] items: $ref: "#/components/schemas/ontology_element" @@ -1158,7 +1158,7 @@ components: $ref: "#/components/schemas/dataset_version_id" development_stage: description: | - [development stage label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#development_stage) + [development stage label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#development_stage) default: [] items: $ref: "#/components/schemas/ontology_element" @@ -1177,7 +1177,7 @@ components: type: number title: description: | - [title](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#title) + [title](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#title) nullable: true type: string organism: @@ -1205,14 +1205,14 @@ components: type: string self_reported_ethnicity: description: | - [self reported ethnicity label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#self_reported_ethnicity) + [self reported ethnicity label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#self_reported_ethnicity) default: [] items: $ref: "#/components/schemas/ontology_element" type: array sex: description: | - [sex label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#sex) + [sex label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#sex) default: [] items: $ref: "#/components/schemas/ontology_element" @@ -1246,7 +1246,7 @@ components: type: integer cell_type: description: | - [cell type label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#cell_type) + [cell type label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#cell_type) default: [] items: $ref: "#/components/schemas/ontology_element" @@ -1268,7 +1268,7 @@ components: $ref: "#/components/schemas/default_embedding" development_stage: description: | - [development stage label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#development_stage) + [development stage label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#development_stage) default: [] items: $ref: "#/components/schemas/ontology_element" @@ -1293,7 +1293,7 @@ components: type: number title: description: | - [title](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#title) + [title](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#title) nullable: true type: string organism: @@ -1310,14 +1310,14 @@ components: type: string self_reported_ethnicity: description: | - [self reported ethnicity label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#self_reported_ethnicity) + [self reported ethnicity label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#self_reported_ethnicity) default: [] items: $ref: "#/components/schemas/ontology_element" type: array sex: description: | - [sex label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#sex) + [sex label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#sex) default: [] items: $ref: "#/components/schemas/ontology_element" @@ -1333,21 +1333,21 @@ components: type: object dataset_assay: description: | - [assay label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#assay) + [assay label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#assay) default: [] items: $ref: "#/components/schemas/ontology_element" type: array dataset_disease: description: | - [disease label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#disease) + [disease label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#disease) default: [] items: $ref: "#/components/schemas/ontology_element" type: array dataset_organism: description: | - [organism label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#organism) + [organism label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#organism) default: [] items: $ref: "#/components/schemas/ontology_element" @@ -1360,7 +1360,7 @@ components: type: string dataset_tissue: description: | - [tissue label](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#tissue) + [tissue label](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#tissue) default: [] items: allOf: @@ -1421,7 +1421,7 @@ components: CELLxGENE Discover runs a heuristic to detect the approximate distribution of the data in X so that it can accurately calculate statistical properties of the data. This field enables the curator to override this heuristic and - specify the data distribution explicitly. [x_approximate_distribution](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#x_approximate_distribution) + specify the data distribution explicitly. [x_approximate_distribution](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#x_approximate_distribution) enum: - COUNT - NORMAL @@ -1482,7 +1482,7 @@ components: nullable: true is_primary_data: description: | - [is_primary_data](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#is_primary_data) + [is_primary_data](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#is_primary_data) Describes whether cellular observations for this Dataset are all canonical (True), all non-canonical (False), or contain a mixture (True, False). @@ -1603,21 +1603,21 @@ components: properties: is_single: description: | - [is_single](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#is_single) + [is_single](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#is_single) Flag indicating if a spatial dataset represents one Space Ranger output for a single tissue section or the output for a single array on a puck. type: boolean has_fullres: description: | - [has_fullres](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#spatiallibrary_idimagesfullres) + [has_fullres](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#spatiallibrary_idimagesfullres) Flag indicating if a spatial dataset's metadata includes a numpy.ndarray representing the full resolution image. type: boolean suspension_type: description: | - [suspension_type](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#suspension_type) + [suspension_type](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#suspension_type) List of unique suspension types represented in the dataset, corresponding to dataset's assay(s). Possible item values are 'nucleus', 'cell', and/or 'na'. diff --git a/frontend/doc-site/032__Contribute and Publish Data.mdx b/frontend/doc-site/032__Contribute and Publish Data.mdx index 07ca8651982ce..af24fb1fcd14a 100644 --- a/frontend/doc-site/032__Contribute and Publish Data.mdx +++ b/frontend/doc-site/032__Contribute and Publish Data.mdx @@ -40,7 +40,7 @@ We need the following collection metadata (i.e. details associated with your pub - URLs: any additional URLs for related data or resources, such as GEO or protocols.io - can be added later - Consortia: optional, and can be added later. Can be one or more of those listed [here](https://github.com/chanzuckerberg/single-cell-data-portal/blob/main/backend/layers/common/validation.py#L12). -Each dataset needs the following information added to a single h5ad (AnnData 0.8) format file: +Each dataset needs the following information added to a single h5ad (AnnData 0.10) format file: - **Dataset-level metadata in uns**: - title: title of the individual dataset @@ -61,7 +61,7 @@ Each dataset needs the following information added to a single h5ad (AnnData 0.8 - tissue_ontology_term_id: [UBERON](https://www.ebi.ac.uk/ols/ontologies/uberon) - cell_type_ontology_term_id: [CL](https://www.ebi.ac.uk/ols/ontologies/cl) - assay_ontology_term_id: [EFO](https://www.ebi.ac.uk/ols/ontologies/efo) - - suspension_type: `cell`, `nucleus`, or `na`, as corresponding to assay. Use [this table](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#suspension_type) defined in the data schema for guidance. If the assay does not appear in this table, the most appropriate value MUST be selected and the [curation team informed](mailto:cellxgene@chanzuckerberg.com) during submission so that the assay can be added to the table. + - suspension_type: `cell`, `nucleus`, or `na`, as corresponding to assay. Use [this table](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#suspension_type) defined in the data schema for guidance. If the assay does not appear in this table, the most appropriate value MUST be selected and the [curation team informed](mailto:cellxgene@chanzuckerberg.com) during submission so that the assay can be added to the table. - **Embeddings in obsm**: - One or more two-dimensional embeddings, prefixed with 'X\_' - **Features in var & raw.var (if present)**: diff --git a/frontend/doc-site/03__Download Published Data.mdx b/frontend/doc-site/03__Download Published Data.mdx index a4e47c44c3a32..94480673b9c7b 100644 --- a/frontend/doc-site/03__Download Published Data.mdx +++ b/frontend/doc-site/03__Download Published Data.mdx @@ -1,6 +1,6 @@ # Downloading Published Data on CZ CELLxGENE Discover -Clicking the download button launches a dialog that enables a dataset to be downloaded in h5ad (AnnData v0.8) and rds (Seurat v5) formats. All datasets adhere to the CELLxGENE single cell annotated data schema. +Clicking the download button launches a dialog that enables a dataset to be downloaded in h5ad (AnnData v0.10) and rds (Seurat v5) formats. All datasets adhere to the CELLxGENE single cell annotated data schema. @@ -8,4 +8,4 @@ Click the white Download button for the dataset that you wish to download. -Select either the h5ad (AnnData v0.8) or rds (Seurat v5) download format. Click the blue Download button to download the dataset via the browser. The permanent download link can also be copied, shared, and pasted into a browser address bar. +Select either the h5ad (AnnData v0.10) or rds (Seurat v5) download format. Click the blue Download button to download the dataset via the browser. The permanent download link can also be copied, shared, and pasted into a browser address bar. diff --git a/frontend/doc-site/04__Analyze Public Data/4_2__Gene Expression Documentation/4_2_2__Cell Type and Gene Ordering.mdx b/frontend/doc-site/04__Analyze Public Data/4_2__Gene Expression Documentation/4_2_2__Cell Type and Gene Ordering.mdx index c7b9565738a63..b18726a51d221 100644 --- a/frontend/doc-site/04__Analyze Public Data/4_2__Gene Expression Documentation/4_2_2__Cell Type and Gene Ordering.mdx +++ b/frontend/doc-site/04__Analyze Public Data/4_2__Gene Expression Documentation/4_2_2__Cell Type and Gene Ordering.mdx @@ -4,7 +4,7 @@ Cell types and genes shown in a dot plot can be arranged in different ways as de # Cell Type Ordering -Cell types are annotated by the original data contributors and mapped to the closest cell ontology (CL) term as defined in the [data schema](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/5.1.0/schema.md#cell_type_ontology_term_id). +Cell types are annotated by the original data contributors and mapped to the closest cell ontology (CL) term as defined in the [data schema](https://chanzuckerberg.github.io/single-cell-curation/latest-schema.html#cell_type_ontology_term_id). In some cases there are cell types annotated with a high-level term whereas in some other cases they can be very granularly annotated. For example, there are some cells annotated as "T cells" and others annotated with children terms like "effector CD8-positive, alpha-beta T cell". All of these cell types are shown in the dot plot and they should not be interpreted as one being a subset of the other. diff --git a/frontend/src/components/Collections/components/Dataset/components/DownloadDataset/components/Content/components/DataFormat/index.tsx b/frontend/src/components/Collections/components/Dataset/components/DownloadDataset/components/Content/components/DataFormat/index.tsx index 2720a8ad80b3d..252110e825a2a 100644 --- a/frontend/src/components/Collections/components/Dataset/components/DownloadDataset/components/Content/components/DataFormat/index.tsx +++ b/frontend/src/components/Collections/components/Dataset/components/DownloadDataset/components/Content/components/DataFormat/index.tsx @@ -40,7 +40,7 @@ const DataFormat: FC = ({ > Date: Mon, 7 Oct 2024 13:18:34 -0400 Subject: [PATCH 2/5] chore: Add newsletter to bottom banner (SCE-29) (#7344) --- backend/common/corpora_config.py | 1 + backend/portal/api/app/v1/authentication.py | 1 + .../landing-seoMetaTags-chromium-linux.txt | 2 +- .../landing-seoMetaTags-edge-linux.txt | 2 +- .../landing-seoMetaTags-firefox-linux.txt | 2 +- .../components/ModalContent/connect.ts | 30 ++++++++++++++- .../components/ModalContent/index.tsx | 3 +- .../src/components/BottomBanner/connect.ts | 23 ++++++++++-- .../src/components/BottomBanner/constants.ts | 5 +-- .../src/components/BottomBanner/index.tsx | 37 +++++++++++++++++-- frontend/src/components/BottomBanner/style.ts | 4 ++ frontend/src/components/BottomBanner/types.ts | 11 ++++++ .../src/components/LandingFooter/index.tsx | 1 + frontend/src/pages/_app.tsx | 6 +++ frontend/src/pages/privacy.tsx | 22 +++++------ .../features/wheresMyGene/landingPage.test.ts | 21 +++++++++++ 16 files changed, 144 insertions(+), 27 deletions(-) diff --git a/backend/common/corpora_config.py b/backend/common/corpora_config.py index 6e1196eaab94e..d4dffbb862615 100644 --- a/backend/common/corpora_config.py +++ b/backend/common/corpora_config.py @@ -88,6 +88,7 @@ def get_defaults_template(self): "internal_url": "{api_base_url}", "issuer": [], "retry_status_forcelist": [429, 500, 502, 503, 504], + "server_metadata_url": "{api_base_url}/.well-known/openid-configuration", } template["issuer"].append(self.api_base_url + "/" if not self.api_base_url.endswith("/") else self.api_base_url) template["issuer"].append("https://" + self.auth0_domain + "/") diff --git a/backend/portal/api/app/v1/authentication.py b/backend/portal/api/app/v1/authentication.py index 8bae005871878..0a5c3e54208ff 100644 --- a/backend/portal/api/app/v1/authentication.py +++ b/backend/portal/api/app/v1/authentication.py @@ -50,6 +50,7 @@ def get_oauth_client(config: CorporaAuthConfig) -> FlaskRemoteApp: authorize_url=config.api_authorize_url, client_kwargs={"scope": "openid profile email offline_access write:collections"}, authorize_params={"audience": config.api_audience}, + server_metadata_url=config.server_metadata_url, ) return oauth_client diff --git a/frontend/__snapshots__/tests/features/cellGuide/cellGuide.test.ts-snapshots/landing-seoMetaTags-chromium-linux.txt b/frontend/__snapshots__/tests/features/cellGuide/cellGuide.test.ts-snapshots/landing-seoMetaTags-chromium-linux.txt index dfcd7defacc25..851ce7f833f25 100644 --- a/frontend/__snapshots__/tests/features/cellGuide/cellGuide.test.ts-snapshots/landing-seoMetaTags-chromium-linux.txt +++ b/frontend/__snapshots__/tests/features/cellGuide/cellGuide.test.ts-snapshots/landing-seoMetaTags-chromium-linux.txt @@ -1 +1 @@ -["","","","","","","","","","","","","","","","","",""] \ No newline at end of file +["","","","","","","","","","","","","","","","","",""] \ No newline at end of file diff --git a/frontend/__snapshots__/tests/features/cellGuide/cellGuide.test.ts-snapshots/landing-seoMetaTags-edge-linux.txt b/frontend/__snapshots__/tests/features/cellGuide/cellGuide.test.ts-snapshots/landing-seoMetaTags-edge-linux.txt index dfcd7defacc25..851ce7f833f25 100644 --- a/frontend/__snapshots__/tests/features/cellGuide/cellGuide.test.ts-snapshots/landing-seoMetaTags-edge-linux.txt +++ b/frontend/__snapshots__/tests/features/cellGuide/cellGuide.test.ts-snapshots/landing-seoMetaTags-edge-linux.txt @@ -1 +1 @@ -["","","","","","","","","","","","","","","","","",""] \ No newline at end of file +["","","","","","","","","","","","","","","","","",""] \ No newline at end of file diff --git a/frontend/__snapshots__/tests/features/cellGuide/cellGuide.test.ts-snapshots/landing-seoMetaTags-firefox-linux.txt b/frontend/__snapshots__/tests/features/cellGuide/cellGuide.test.ts-snapshots/landing-seoMetaTags-firefox-linux.txt index dfcd7defacc25..851ce7f833f25 100644 --- a/frontend/__snapshots__/tests/features/cellGuide/cellGuide.test.ts-snapshots/landing-seoMetaTags-firefox-linux.txt +++ b/frontend/__snapshots__/tests/features/cellGuide/cellGuide.test.ts-snapshots/landing-seoMetaTags-firefox-linux.txt @@ -1 +1 @@ -["","","","","","","","","","","","","","","","","",""] \ No newline at end of file +["","","","","","","","","","","","","","","","","",""] \ No newline at end of file diff --git a/frontend/src/components/BottomBanner/components/ModalContent/connect.ts b/frontend/src/components/BottomBanner/components/ModalContent/connect.ts index 541b1b1a7e328..587a4d1d2cad0 100644 --- a/frontend/src/components/BottomBanner/components/ModalContent/connect.ts +++ b/frontend/src/components/BottomBanner/components/ModalContent/connect.ts @@ -9,10 +9,12 @@ import { export const useConnect = ({ id, + isHubSpotReady, email, setError, }: { id?: string; + isHubSpotReady: boolean; email: string; setError: (error: string) => void; }) => { @@ -83,18 +85,34 @@ export const useConnect = ({ * handles the submission success flow and email validation failure flow */ useEffect(() => { + if (!isHubSpotReady) return; + /** + * Observer to observe changes in the Hubspot embedded form, + * which is hidden from the user in order to use our own form view + */ const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { + /** + * Loop through all added nodes that were detected + */ for (let i = 0; i < mutation.addedNodes.length; i++) { const node = mutation.addedNodes.item(i); - + /** + * Submission success flow + */ if (node?.textContent?.includes(HIDDEN_NEWSLETTER_SUCCESS_MESSAGE)) { setIsSubmitted(true); setError(""); track(EVENTS.NEWSLETTER_SIGNUP_SUCCESS); } else if ( + /** + * Hubspot email validation failure flow + */ node?.textContent?.includes("Please enter a valid email address.") ) { + /** + * HTML email validation may pass, but may not pass validation for Hubspot + */ setError(FAILED_EMAIL_VALIDATION_STRING); track(EVENTS.NEWSLETTER_SIGNUP_FAILURE); } @@ -104,6 +122,14 @@ export const useConnect = ({ const form = document.querySelector(formContainerQueryId); + hbspt.forms.create({ + region: "na1", + portalId: "7272273", + formId: "eb65b811-0451-414d-8304-7b9b6f468ce5", + target: formContainerQueryId, + formInstanceId: id, + }); + if (form) { observer.observe(form, { childList: true, @@ -114,7 +140,7 @@ export const useConnect = ({ return () => { observer.disconnect(); }; - }, [formContainerQueryId, id, setError]); + }, [formContainerQueryId, id, setError, isHubSpotReady]); return { isSubmitted, diff --git a/frontend/src/components/BottomBanner/components/ModalContent/index.tsx b/frontend/src/components/BottomBanner/components/ModalContent/index.tsx index 48f6d777b99f2..9cd04dac09518 100644 --- a/frontend/src/components/BottomBanner/components/ModalContent/index.tsx +++ b/frontend/src/components/BottomBanner/components/ModalContent/index.tsx @@ -22,6 +22,7 @@ import { export default function BottomBannerModalContent({ id = "newsletter-banner", + isHubSpotReady = false, setEmail, setError, emailValidationError, @@ -33,7 +34,7 @@ export default function BottomBannerModalContent({ submitButtonEnabledOnce, setSubmitButtonEnabledOnce, emailRef, - } = useConnect({ id, setError, email }); + } = useConnect({ id, isHubSpotReady, setError, email }); return ( diff --git a/frontend/src/components/BottomBanner/connect.ts b/frontend/src/components/BottomBanner/connect.ts index d20ec8780a306..4b4d3e5e6e1d6 100644 --- a/frontend/src/components/BottomBanner/connect.ts +++ b/frontend/src/components/BottomBanner/connect.ts @@ -7,15 +7,28 @@ import { import { track } from "src/common/analytics"; import { EVENTS } from "src/common/analytics/events"; -export const useConnect = ({ asFooter }: { asFooter?: boolean }) => { +export const useConnect = ({ + isHubSpotReadyProp, + asFooter, +}: { + isHubSpotReadyProp: boolean; + asFooter?: boolean; +}) => { const [bottomBannerLastClosedTime, setBottomBannerLastClosedTime] = useLocalStorage(BOTTOM_BANNER_LAST_CLOSED_TIME_KEY, 0); const [newsletterModalIsOpen, setNewsletterModalIsOpen] = useState(false); + const [isHubSpotReady, setIsHubSpotReady] = useState(false); const [email, setEmail] = useState(""); const [emailValidationError, setError] = useState(""); const [isDirectLink, setIsDirectLink] = useState(false); + useEffect(() => { + if (!isHubSpotReadyProp) return; + + setIsHubSpotReady(true); + }, [isHubSpotReady, isHubSpotReadyProp]); + /** * useEffect * Reads a query parameter from the URL to auto open the newsletter signup modal @@ -24,6 +37,8 @@ export const useConnect = ({ asFooter }: { asFooter?: boolean }) => { * isDirectLink is tracked in setter function or else we get window not defined error */ useEffect(() => { + if (!isHubSpotReady) return; + if (!asFooter && window) { const openModalParam = new URLSearchParams(window.location.search).get( "newsletter_signup" @@ -39,7 +54,7 @@ export const useConnect = ({ asFooter }: { asFooter?: boolean }) => { }); } } - }, [asFooter, isDirectLink]); + }, [asFooter, isDirectLink, isHubSpotReady]); /** * showBanner @@ -63,8 +78,6 @@ export const useConnect = ({ asFooter }: { asFooter?: boolean }) => { /** * toggleNewsletterSignupModal * Toggles the newsletter signup modal - * (smcanny) 07/24 - not in use currently - * leaving it here incase a new newsletter modal is established * */ function toggleNewsletterSignupModal() { if (!newsletterModalIsOpen) { @@ -78,9 +91,11 @@ export const useConnect = ({ asFooter }: { asFooter?: boolean }) => { return { setBottomBannerLastClosedTime, newsletterModalIsOpen, + setIsHubSpotReady, isDirectLink, toggleNewsletterSignupModal, showBanner, + isHubSpotReady, email, setEmail, emailValidationError, diff --git a/frontend/src/components/BottomBanner/constants.ts b/frontend/src/components/BottomBanner/constants.ts index 9a39537ac93ce..cbbb353c21ef9 100644 --- a/frontend/src/components/BottomBanner/constants.ts +++ b/frontend/src/components/BottomBanner/constants.ts @@ -1,4 +1,4 @@ -export const FORM_CONTAINER_ID = "form-container"; +export const FORM_CONTAINER_ID = "hubspot-form-container"; export const FORM_CONTAINER_ID_QUERY = `#${FORM_CONTAINER_ID}`; export const BOTTOM_BANNER_EXPIRATION_TIME_MS = 30 * 24 * 60 * 60 * 1000; // 30 days @@ -6,8 +6,6 @@ export const BOTTOM_BANNER_LAST_CLOSED_TIME_KEY = "bottomBannerLastClosedTime"; export const BOTTOM_BANNER_SURVEY_LINK_TEXT = "quick survey."; export const BOTTOM_BANNER_SURVEY_TEXT = "Send us feedback with this"; -//(smcanny) 07/24 - Newsletter constants not currently in use -// leaving it here incase a new newsletter modal is established export const NEWSLETTER_SIGNUP_TITLE = "Join Our Newsletter"; export const NEWSLETTER_SIGNUP_MESSAGE = "Thanks for subscribing!"; export const NEWSLETTER_SIGNUP_SUCCESS_MESSAGE = @@ -22,3 +20,4 @@ export const FAILED_EMAIL_VALIDATION_STRING = "Please provide a valid email address."; export const HIDDEN_NEWSLETTER_SUCCESS_MESSAGE = "Thank you for joining our newsletter."; +export const HUBSPOT_URL = "https://js.hsforms.net/forms/v2.js"; diff --git a/frontend/src/components/BottomBanner/index.tsx b/frontend/src/components/BottomBanner/index.tsx index 351eeb77e4d8a..177717be6cb22 100644 --- a/frontend/src/components/BottomBanner/index.tsx +++ b/frontend/src/components/BottomBanner/index.tsx @@ -1,3 +1,4 @@ +import Script from "next/script"; import { memo } from "react"; import { BOTTOM_BANNER_ID, @@ -5,15 +6,20 @@ import { StyledBanner, StyledBottomBannerWrapper, StyledLink, + HeaderContainer, + HiddenHubSpotForm, FooterContentWrapper, StyledCloseButtonIcon, - HeaderContainer, } from "./style"; import CellxgeneLogoSvg from "src/common/images/CellxGene.svg"; +import Head from "next/head"; import { EXCLUDE_IN_SCREENSHOT_CLASS_NAME } from "src/views/WheresMyGeneV2/components/GeneSearchBar/components/SaveExport"; +import { noop } from "src/common/constants/utils"; import BottomBannerModalContent from "./components/ModalContent"; import { useConnect } from "./connect"; import { + FORM_CONTAINER_ID, + HUBSPOT_URL, BOTTOM_BANNER_SURVEY_LINK_TEXT, BOTTOM_BANNER_SURVEY_TEXT, NEWSLETTER_SIGNUP_BANNER_SUBSCRIBE_BUTTON_TEXT, @@ -23,29 +29,50 @@ import { Props } from "./types"; export default memo(function BottomBanner({ hasSurveyLink = true, - hasNewsletterSignup = false, + hasNewsletterSignup = true, asFooter = false, customSurveyLinkPrefix, analyticsHandler, surveyLink, id = "newsletter-banner", + isHubSpotReady: isHubSpotReadyProp = false, + onHubSpotReady = noop, }: Props): JSX.Element | null { const { setBottomBannerLastClosedTime, setEmail, setError, + setIsHubSpotReady, toggleNewsletterSignupModal, newsletterModalIsOpen, isDirectLink, showBanner, + isHubSpotReady, email, emailValidationError, - } = useConnect({ asFooter }); + } = useConnect({ isHubSpotReadyProp, asFooter }); if (!showBanner) return null; return ( <> + + {!asFooter && ( + + )} + + ); } diff --git a/frontend/src/pages/privacy.tsx b/frontend/src/pages/privacy.tsx index 3cb595284a414..59f11543627d8 100644 --- a/frontend/src/pages/privacy.tsx +++ b/frontend/src/pages/privacy.tsx @@ -148,17 +148,17 @@ const Privacy = (): JSX.Element => { legitimate interests in improving our Site.
  • -
    Cookies and Other Similar Technologies.
    For - certain users that need to log into CELLxGENE Discover to - publish data, we use essential cookies (small text files - sent by your computer each time you access the Site that - are unique to your account or your browser) to enable that - use. We also use local storage to save your preferences - (e.g., to remember that you blocked a pop-up). For web - analytics, we do not use Google Analytics. Instead, we use - the privacy-friendly Plausible as our website analytic - tool. Learn more about Plausible’s data and privacy - practices{" "} +
    Cookies and Other Similar Technologies.
    We, and + our form vendor Hubspot, use essential/necessary cookies + (small text files sent by your computer each time you + access the Site that are unique to your account or your + browser) to enable user logins and help prevent fraudulent + form submissions. We also use local storage to save your + preferences (e.g., to remember that you blocked a pop-up). + For web analytics, we do not use Google Analytics. + Instead, we use the privacy-friendly Plausible as our + website analytic tool. Learn more about Plausible’s data + and privacy practices{" "} { { page } ); }); + test("newsletter signup modal opens and closes", async ({ page }) => { + await goToWMG(page); + + await page.getByTestId("newsletter-modal-open-button").click(); + + await expect(page.getByTestId("newsletter-modal-content")).toBeVisible(); + + await page.getByTestId("newsletter-email-input").fill("test"); + + await page.getByTestId("newsletter-subscribe-button").click(); + + await expect( + page.getByText("Please provide a valid email address.") + ).toBeVisible(); + + await page.getByTestId("newsletter-modal-close-button").click(); + + await expect( + page.getByTestId("newsletter-modal-content") + ).not.toBeVisible(); + }); }); From 687686789103c729ef8bbd36a1738224fa21c850 Mon Sep 17 00:00:00 2001 From: Ronen Date: Mon, 7 Oct 2024 14:45:22 -0400 Subject: [PATCH 3/5] chore: remove sever metadata field from oauth.register() (#7355) --- backend/common/corpora_config.py | 1 - backend/portal/api/app/v1/authentication.py | 1 - 2 files changed, 2 deletions(-) diff --git a/backend/common/corpora_config.py b/backend/common/corpora_config.py index d4dffbb862615..6e1196eaab94e 100644 --- a/backend/common/corpora_config.py +++ b/backend/common/corpora_config.py @@ -88,7 +88,6 @@ def get_defaults_template(self): "internal_url": "{api_base_url}", "issuer": [], "retry_status_forcelist": [429, 500, 502, 503, 504], - "server_metadata_url": "{api_base_url}/.well-known/openid-configuration", } template["issuer"].append(self.api_base_url + "/" if not self.api_base_url.endswith("/") else self.api_base_url) template["issuer"].append("https://" + self.auth0_domain + "/") diff --git a/backend/portal/api/app/v1/authentication.py b/backend/portal/api/app/v1/authentication.py index 0a5c3e54208ff..8bae005871878 100644 --- a/backend/portal/api/app/v1/authentication.py +++ b/backend/portal/api/app/v1/authentication.py @@ -50,7 +50,6 @@ def get_oauth_client(config: CorporaAuthConfig) -> FlaskRemoteApp: authorize_url=config.api_authorize_url, client_kwargs={"scope": "openid profile email offline_access write:collections"}, authorize_params={"audience": config.api_audience}, - server_metadata_url=config.server_metadata_url, ) return oauth_client From c1002b845ab92bc253ed8fbfc2bd504e91a05a19 Mon Sep 17 00:00:00 2001 From: atarashansky Date: Tue, 8 Oct 2024 08:54:46 -0700 Subject: [PATCH 4/5] chore: update cellguide pipeline requirements to fix dependency conflicts with tiledb (#7357) --- .../cellguide_pipeline/requirements.txt | 31 +++---------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/python_dependencies/cellguide_pipeline/requirements.txt b/python_dependencies/cellguide_pipeline/requirements.txt index 0b8c89ff1de4e..6633df09a550e 100644 --- a/python_dependencies/cellguide_pipeline/requirements.txt +++ b/python_dependencies/cellguide_pipeline/requirements.txt @@ -1,39 +1,18 @@ -anndata==0.9.2 -annotated-types==0.5.0 -awscli==1.29.34 -boto3==1.28.25 -botocore==1.31.34 +anndata==0.8.0 +boto3==1.28.7 cellxgene-census>=1.10.0 cellxgene-ontology-guide~=1.0.0 -certifi==2023.7.22 -chardet==5.2.0 -charset-normalizer==3.2.0 ddtrace==2.1.4 -fastobo==0.12.2 -h5py==3.9.0 -idna==3.7 -jmespath==1.0.1 -llvmlite==0.42.0 -natsort==8.4.0 -networkx==3.1 -numba==0.59.1 -numpy==1.24.4 +numba>=0.58.0 +numpy>=1.24.0,<2.1.0 openai==0.27.7 -packaging==23.1 -pandas==2.0.3 +pandas==2.2.1 psutil==5.9.5 pydantic==2.6.4 -pydantic_core==2.16.3 -python-dateutil==2.8.2 -pytz==2023.3 requests==2.31.0 -s3transfer==0.6.1 scipy==1.11.1 -six==1.16.0 tiledb tiledbsoma>=1.7.0 -typing_extensions==4.11.0 -tzdata==2023.3 urllib3==1.26.16 pyarrow==12.0.0 dask==2023.8.1 From 0f6646b81728be7854ebed88a0911fc4979f45de Mon Sep 17 00:00:00 2001 From: MaximilianLombardo Date: Tue, 8 Oct 2024 22:46:04 +0200 Subject: [PATCH 5/5] docs: Update 4_1__Hosted Tutorials.mdx (#7356) --- .../4_1__Hosted Tutorials.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/doc-site/04__Analyze Public Data/4_1__Hosted Tutorials.mdx b/frontend/doc-site/04__Analyze Public Data/4_1__Hosted Tutorials.mdx index 9bbd5f7b2560e..2a8d426ab0111 100644 --- a/frontend/doc-site/04__Analyze Public Data/4_1__Hosted Tutorials.mdx +++ b/frontend/doc-site/04__Analyze Public Data/4_1__Hosted Tutorials.mdx @@ -14,7 +14,7 @@ CELLxGENE Explorer's user interface organizes single cell data similarly to how **Key Concepts**: User Interface Explanation - + ## Examining Categorical Metadata @@ -22,7 +22,7 @@ Categorical metadata (such as tissue of origin or cell type) can be used in a nu **Key Concepts**: Categorical Metadata, Selecting Cells by Category (i.e. cell type), Interaction Between Categorical Metadata Fields - + ## Find Cells Where a Gene is Expressed @@ -30,7 +30,7 @@ Numerical metadata (such gene expression features or QC metrics such as number o **Key Concepts**: Numerical Metadata, Cell Filtering and Selection, Interaction Between Numerical Metadata, Categorical Metadata Fields - + ## Selecting and Subsetting Cells @@ -38,7 +38,7 @@ Explorer allows for the complex selection of cells via selection directly on the **Key Concepts**: Categorical Metadata Selection, Numerical Metadata Selection, Complex Selection (combining selection methods) - + ## Compare Expression of Multiple Genes @@ -46,7 +46,7 @@ Explorer allows you to compare the expression of multiple genes via bivariate pl **Key Concepts**: Gene Expression, Co-expression, Cell Selection, Subsetting - + ## Using Gene Sets to Learn About Cell Population Functional Characteristics @@ -58,7 +58,7 @@ _Listed below is a comma separated gene set list for use with this tutorial._ ACAA1, ACAA2, ACADL, ACADM, ACADS, ACADSB, ACADVL, ACAT1, ACAT2, ACOX1, ACOX3, ACSL1, ACSL3, ACSL4, ACSL5, ACSL6, ADH1A, ADH1B, ADH1C, ADH4, ADH5, ADH6, ADH7, ALDH1B1, ALDH2, ALDH3A2, ALDH7A1, ALDH9A1, CPT1A, CPT1B, CPT1C, CPT2, CYP4A11, CYP4A22, ECHS1, ECI1, ECI2, EHHADH, GCDH, HADH, HADHA, HADHB - + ## Find Marker Genes @@ -66,6 +66,6 @@ Explorer allows you to find marker genes between selected cell populations. **Key Concepts**: Gene Expression, Differential Expression, Cell Selection, Subsetting - + Note: You can find more information here about how our differential expression is calculated. In brief, we use a Welch's t-test. While we are aware that single cell data does not always meet the assumptions imposed by this test, we utilize it because it performs well at identifying the _most_ differentially expressed genes, and this is what our feature returns.