diff --git a/explorer/app/components/common/Banner/banner.styles.ts b/explorer/app/components/common/Banner/banner.styles.ts
new file mode 100644
index 000000000..a16b12a98
--- /dev/null
+++ b/explorer/app/components/common/Banner/banner.styles.ts
@@ -0,0 +1,20 @@
+import { BannerPrimary as DXBannerPrimary } from "@clevercanary/data-explorer-ui/lib/components/common/Banner/components/BannerPrimary/bannerPrimary";
+import styled from "@emotion/styled";
+
+export const Banner = styled(DXBannerPrimary)`
+ .MuiAlert-message {
+ p {
+ font: inherit;
+ }
+
+ a,
+ .MuiLink-root {
+ color: inherit;
+ text-decoration: underline;
+
+ &:hover {
+ text-decoration: none;
+ }
+ }
+ }
+`;
diff --git a/explorer/app/components/common/MDXContent/anvil-cmg/betaAnnouncement.mdx b/explorer/app/components/common/MDXContent/anvil-cmg/betaAnnouncement.mdx
new file mode 100644
index 000000000..aaf9c9635
--- /dev/null
+++ b/explorer/app/components/common/MDXContent/anvil-cmg/betaAnnouncement.mdx
@@ -0,0 +1 @@
+Welcome to our BETA release. Please see the [Beta Announcement](/beta-announcement) to learn more.
diff --git a/explorer/app/components/common/MDXContent/anvil-cmg/index.tsx b/explorer/app/components/common/MDXContent/anvil-cmg/index.tsx
index 180870f0d..3649a1df1 100644
--- a/explorer/app/components/common/MDXContent/anvil-cmg/index.tsx
+++ b/explorer/app/components/common/MDXContent/anvil-cmg/index.tsx
@@ -2,6 +2,7 @@ export { RenderComponent } from "@clevercanary/data-explorer-ui/lib/components/C
export { Section } from "../../MDXMarkdown/components/Section/mdxSection.styles";
export { default as ExportToTerraStart } from "../common/exportToTerraStart.mdx";
export { default as ExportToTerraSuccess } from "../common/exportToTerraSuccess.mdx";
+export { default as BetaAnnouncement } from "./betaAnnouncement.mdx";
export { default as DataReleasePolicy } from "./dataReleasePolicy.mdx";
export { default as ExportWarning } from "./exportWarning.mdx";
export { default as LoginReminder } from "./loginReminder.mdx";
diff --git a/explorer/app/components/index.tsx b/explorer/app/components/index.tsx
index 1a4cbe7ea..1d382943e 100644
--- a/explorer/app/components/index.tsx
+++ b/explorer/app/components/index.tsx
@@ -76,6 +76,7 @@ export { Publications } from "@clevercanary/data-explorer-ui/lib/components/Proj
export { SupplementaryLinks } from "@clevercanary/data-explorer-ui/lib/components/Project/components/SupplementaryLinks/supplementaryLinks";
export { SupportRequest } from "@clevercanary/data-explorer-ui/lib/components/Support/components/SupportRequest/supportRequest";
export { ExportMethodView } from "@clevercanary/data-explorer-ui/lib/views/ExportMethodView/exportMethodView";
+export { Banner } from "./common/Banner/banner.styles";
export { ButtonOutline } from "./common/Button/components/ButtonOutline/buttonOutline";
export { MdxMarkdown } from "./common/MDXMarkdown/mdxMarkdown";
export { RenderComponents } from "./common/RenderComponents/renderComponents";
diff --git a/explorer/app/content/anvil-cmg/beta-announcement.mdx b/explorer/app/content/anvil-cmg/beta-announcement.mdx
new file mode 100644
index 000000000..2d954bf9b
--- /dev/null
+++ b/explorer/app/content/anvil-cmg/beta-announcement.mdx
@@ -0,0 +1,24 @@
+
+
+# General Announcement
+
+AnVIL is pleased to announce the public beta release of the AnVIL Data Explorer for Terra on Google Cloud Platform. The AnVIL Data Explorer is accessible at [https://explore.anvilproject.org/](https://explore.anvilproject.org).
+
+We are actively looking for your feedback! Please provide feedback via [https://help.anvilproject.org/](https://help.anvilproject.org).
+
+The AnVIL Data Explorer enables faceted searches of open and managed access datasets hosted in AnVIL, making it easier for researchers to find and custom-build cohorts. Documentation for using the AnVIL Data Explorer can be found [here](/guides).
+
+The AnVIL team is actively indexing more datasets, so the available datasets should grow every few weeks.
+
+At the time of this writing, known limitations of the AnVIL Data Explorer are:
+
+- Currently supports Terra on Google Cloud Platform. Support for Terra on Microsoft Azure is coming later this year.
+- Incomplete dataset descriptions and other supporting information. This information is limited and should be growing, which will increase the usefulness of the AnVIL Data Explorer.
+- Limited support for metadata export. This will evolve over time, but currently, some metadata is not handed off to Terra on GCP. We expect this to improve after the release.
+
+Currently, the General Availability release is targeted for around the middle of 2024. The timing will depend on the feedback and the nature of any issues discovered during this beta period.
diff --git a/explorer/mdx-components.tsx b/explorer/mdx-components.tsx
new file mode 100644
index 000000000..15b0a78bd
--- /dev/null
+++ b/explorer/mdx-components.tsx
@@ -0,0 +1,9 @@
+import { MDXComponents } from "mdx/types";
+import * as C from "./app/components";
+
+export function useMDXComponents(components: MDXComponents): MDXComponents {
+ return {
+ ...components,
+ a: ({ children, href }) => C.Link({ label: children, url: href ?? "" }),
+ };
+}
diff --git a/explorer/next.config.mjs b/explorer/next.config.mjs
index 79d552bda..da8d59284 100644
--- a/explorer/next.config.mjs
+++ b/explorer/next.config.mjs
@@ -1,95 +1,93 @@
-import withMDX from "@next/mdx";
+import nextMDX from "@next/mdx";
import withPlugins from "next-compose-plugins";
import path from "path";
-export default withPlugins([withMDX], {
- basePath: process.env.NEXT_PUBLIC_BASE_PATH || "",
- images: {
- unoptimized: true,
- },
- output: "export",
- reactStrictMode: true,
- staticPageGenerationTimeout: 120,
- webpack: (config) => {
- config.module = {
- ...config.module,
- rules: [
- ...config.module.rules,
- {
- test: /\.mdx?$/,
- use: [
- {
- loader: "@mdx-js/loader",
- },
- ],
- },
- ],
- };
- // Add the alias for the peer dependency
- config.resolve.alias["@emotion/react"] = path.resolve(
- process.cwd(),
- "node_modules/@emotion/react"
- );
- config.resolve.alias["@emotion/styled"] = path.resolve(
- process.cwd(),
- "node_modules/@emotion/styled"
- );
- config.resolve.alias["@mui/icons-material"] = path.resolve(
- process.cwd(),
- "node_modules/@mui/icons-material"
- );
- config.resolve.alias["@mui/material"] = path.resolve(
- process.cwd(),
- "node_modules/@mui/material"
- );
- config.resolve.alias["@tanstack/react-table"] = path.resolve(
- process.cwd(),
- "node_modules/@tanstack/react-table"
- );
- config.resolve.alias["axios"] = path.resolve(
- process.cwd(),
- "node_modules/axios"
- );
- config.resolve.alias["react-dropzone"] = path.resolve(
- process.cwd(),
- "node_modules/react-dropzone"
- );
- config.resolve.alias["isomorphic-dompurify"] = path.resolve(
- process.cwd(),
- "node_modules/isomorphic-dompurify"
- );
- config.resolve.alias["match-sorter"] = path.resolve(
- process.cwd(),
- "node_modules/match-sorter"
- );
- config.resolve.alias["next"] = path.resolve(
- process.cwd(),
- "node_modules/next"
- );
- config.resolve.alias["react"] = path.resolve(
- process.cwd(),
- "node_modules/react"
- );
- config.resolve.alias["react-dom"] = path.resolve(
- process.cwd(),
- "node_modules/react-dom"
- );
- config.resolve.alias["react-gtm-module"] = path.resolve(
- process.cwd(),
- "node_modules/react-gtm-module"
- );
- config.resolve.alias["react-window"] = path.resolve(
- process.cwd(),
- "node_modules/react-window"
- );
- config.resolve.alias["uuid"] = path.resolve(
- process.cwd(),
- "node_modules/uuid"
- );
- config.resolve.alias["validate.js"] = path.resolve(
- process.cwd(),
- "node_modules/validate.js"
- );
- return config;
- },
+const withMDX = nextMDX({
+ extension: /\.mdx?$/,
});
+
+export default withPlugins(
+ [
+ withMDX,
+ {
+ pageExtensions: ["md", "mdx", "ts", "tsx"],
+ },
+ ],
+ {
+ basePath: process.env.NEXT_PUBLIC_BASE_PATH || "",
+ images: {
+ unoptimized: true,
+ },
+ output: "export",
+ reactStrictMode: true,
+ staticPageGenerationTimeout: 120,
+ webpack: (config) => {
+ // Add the alias for the peer dependency
+ config.resolve.alias["@emotion/react"] = path.resolve(
+ process.cwd(),
+ "node_modules/@emotion/react"
+ );
+ config.resolve.alias["@emotion/styled"] = path.resolve(
+ process.cwd(),
+ "node_modules/@emotion/styled"
+ );
+ config.resolve.alias["@mui/icons-material"] = path.resolve(
+ process.cwd(),
+ "node_modules/@mui/icons-material"
+ );
+ config.resolve.alias["@mui/material"] = path.resolve(
+ process.cwd(),
+ "node_modules/@mui/material"
+ );
+ config.resolve.alias["@tanstack/react-table"] = path.resolve(
+ process.cwd(),
+ "node_modules/@tanstack/react-table"
+ );
+ config.resolve.alias["axios"] = path.resolve(
+ process.cwd(),
+ "node_modules/axios"
+ );
+ config.resolve.alias["react-dropzone"] = path.resolve(
+ process.cwd(),
+ "node_modules/react-dropzone"
+ );
+ config.resolve.alias["isomorphic-dompurify"] = path.resolve(
+ process.cwd(),
+ "node_modules/isomorphic-dompurify"
+ );
+ config.resolve.alias["match-sorter"] = path.resolve(
+ process.cwd(),
+ "node_modules/match-sorter"
+ );
+ config.resolve.alias["next"] = path.resolve(
+ process.cwd(),
+ "node_modules/next"
+ );
+ config.resolve.alias["react"] = path.resolve(
+ process.cwd(),
+ "node_modules/react"
+ );
+ config.resolve.alias["react-dom"] = path.resolve(
+ process.cwd(),
+ "node_modules/react-dom"
+ );
+ config.resolve.alias["react-gtm-module"] = path.resolve(
+ process.cwd(),
+ "node_modules/react-gtm-module"
+ );
+ config.resolve.alias["react-window"] = path.resolve(
+ process.cwd(),
+ "node_modules/react-window"
+ );
+ config.resolve.alias["uuid"] = path.resolve(
+ process.cwd(),
+ "node_modules/uuid"
+ );
+ config.resolve.alias["validate.js"] = path.resolve(
+ process.cwd(),
+ "node_modules/validate.js"
+ );
+ return config;
+ },
+ }
+);
diff --git a/explorer/pages/beta-announcement/index.tsx b/explorer/pages/beta-announcement/index.tsx
new file mode 100644
index 000000000..76e68c5e0
--- /dev/null
+++ b/explorer/pages/beta-announcement/index.tsx
@@ -0,0 +1,35 @@
+import { Main } from "@clevercanary/data-explorer-ui/lib/components/Layout/components/ContentLayout/components/Main/main";
+import { ContentView } from "@clevercanary/data-explorer-ui/lib/views/ContentView/contentView";
+import { GetStaticProps, InferGetStaticPropsType } from "next";
+import { MDXRemote } from "next-mdx-remote";
+import { ContentTheme } from "../../app/components/common/Content/components/ContentTheme/contentTheme";
+import { MDX_COMPONENTS } from "../../app/content/common/constants";
+import { getContentStaticProps } from "../../app/content/common/contentPages";
+import NotFoundPage from "../404";
+
+const slug = ["beta-announcement"];
+
+export const getStaticProps: GetStaticProps = async () => {
+ return getContentStaticProps({ params: { slug } }, "Beta Announcement");
+};
+
+const Page = ({
+ layoutStyle,
+ mdxSource,
+}: InferGetStaticPropsType): JSX.Element => {
+ if (!mdxSource) return ;
+ return (
+
+
+
+ }
+ layoutStyle={layoutStyle ?? undefined}
+ />
+ );
+};
+
+Page.Main = Main;
+
+export default Page;
diff --git a/explorer/site-config/anvil-cmg/dev/announcements/announcements.ts b/explorer/site-config/anvil-cmg/dev/announcements/announcements.ts
index e5c08e07b..a65bcac3c 100644
--- a/explorer/site-config/anvil-cmg/dev/announcements/announcements.ts
+++ b/explorer/site-config/anvil-cmg/dev/announcements/announcements.ts
@@ -3,9 +3,18 @@ import {
ComponentsConfig,
} from "@clevercanary/data-explorer-ui/lib/config/entities";
import * as C from "app/components";
+import * as MDX from "../../../../app/components/common/MDXContent/anvil-cmg";
export const announcements: ComponentsConfig = [
{
component: C.SessionTimeout,
} as ComponentConfig,
+ {
+ children: [
+ {
+ component: MDX.BetaAnnouncement,
+ } as ComponentConfig,
+ ],
+ component: C.Banner,
+ } as ComponentConfig,
];
diff --git a/explorer/site-config/anvil-cmg/dev/config.ts b/explorer/site-config/anvil-cmg/dev/config.ts
index f8c3950d0..0f81f94ac 100644
--- a/explorer/site-config/anvil-cmg/dev/config.ts
+++ b/explorer/site-config/anvil-cmg/dev/config.ts
@@ -141,6 +141,10 @@ export function makeConfig(
flatten: true,
label: "Help & Documentation",
menuItems: [
+ {
+ label: "Beta Announcement",
+ url: "/beta-announcement",
+ },
{
label: "Guides",
url: "/guides",