diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..ee8e76b --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,8 @@ +{ + "plugins": ["@trivago/prettier-plugin-sort-imports"], + "printWidth": 80, + "tabWidth": 4, + "importOrder": ["^react", "^gatsby", "^[^./]", "^[./]"], + "importOrderSeparation": true, + "importOrderSortSpecifiers": true +} diff --git a/gatsby-node.js b/gatsby-node.js index c44e6e6..1e4c534 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -18,7 +18,7 @@ const read = (p) => fs.readFileSync(path.join(__dirname, p), 'utf8') * They serve as single source of truth, can be added/edited via CMS, * and are referenced by other markdown files. */ -const DATA_ONLY_PAGES = ['software', 'dataset', 'allenite', 'program'] +const DATA_ONLY_PAGES = ["software", "dataset", "allenite", "program"]; exports.createSchemaCustomization = ({ actions, schema }) => { const { createTypes } = actions @@ -60,57 +60,55 @@ exports.createSchemaCustomization = ({ actions, schema }) => { * functions where possible */ exports.createResolvers = ({ createResolvers }) => { - createResolvers({ - MarkdownRemark: { - fields: { - resolve: (source) => ({ - slug: source.fields?.slug || '/', - }), - }, - }, - MarkdownRemark: { - fields: { - resolve: (source) => ({ - slug: source.fields?.slug || '/', - }), - }, - }, - Frontmatter: { - description: { - resolve: (source) => - stringWithDefault(source.description, 'No description provided.'), - }, - title: { - resolve: (source) => - stringWithDefault(source.title, 'No title provided.'), - }, - materialsAndMethods: { - resolve: (source) => { - const raw = source.materialsAndMethods - const current = { - dataset: null, - cellLines: [], - protocols: [], - software: [], - } - - if (!raw || typeof raw !== 'object') { - return current - } - - const resolvedDatasetSlug = resolveSlug(raw.dataset, DATASET_PATH) - current.dataset = resolvedDatasetSlug - current.cellLines = resolveToArray(raw.cellLines) - current.protocols = resolveToArray(raw.protocols) - current.software = resolveSoftwareTools(raw.software) - current.software = resolveSoftwareTools(raw.software) - - return current + createResolvers({ + MarkdownRemark: { + fields: { + resolve: (source) => ({ + slug: source.fields?.slug || "/", + }), + }, }, - }, - }, - }) -} + Frontmatter: { + description: { + resolve: (source) => + stringWithDefault( + source.description, + "No description provided.", + ), + }, + title: { + resolve: (source) => + stringWithDefault(source.title, "No title provided."), + }, + materialsAndMethods: { + resolve: (source) => { + const raw = source.materialsAndMethods; + const current = { + dataset: null, + cellLines: [], + protocols: [], + software: [], + }; + + if (!raw || typeof raw !== "object") { + return current; + } + + const resolvedDatasetSlug = resolveSlug( + raw.dataset, + DATASET_PATH, + ); + current.dataset = resolvedDatasetSlug; + current.cellLines = resolveToArray(raw.cellLines); + current.protocols = resolveToArray(raw.protocols); + current.software = resolveSoftwareTools(raw.software); + + return current; + }, + }, + }, + }); +}; /** * Create pages for markdown files based on their templateKey frontmatter. @@ -161,16 +159,18 @@ exports.createPages = ({ actions, graphql }) => { return } - createPage({ - path: edge.node.fields.slug, - tags: edge.node.frontmatter.tags, - component: path.resolve(`src/templates/${String(templateKey)}.tsx`), - // additional data can be passed via context - context: { - id, - }, - }) - }) + createPage({ + path: edge.node.fields.slug, + tags: edge.node.frontmatter.tags, + component: path.resolve( + `src/templates/${String(templateKey)}.tsx`, + ), + // additional data can be passed via context + context: { + id, + }, + }); + }); // Tag pages: let tags = [] diff --git a/gatsbyutils/constants.js b/gatsbyutils/constants.js index b29e5d7..c1d8290 100644 --- a/gatsbyutils/constants.js +++ b/gatsbyutils/constants.js @@ -4,4 +4,4 @@ const SOFTWARE_PATH = `software`; module.exports = { DATASET_PATH, SOFTWARE_PATH, -}; \ No newline at end of file +}; diff --git a/gatsbyutils/gatsby-resolver-utils.js b/gatsbyutils/gatsby-resolver-utils.js index 440feb0..b8f8434 100644 --- a/gatsbyutils/gatsby-resolver-utils.js +++ b/gatsbyutils/gatsby-resolver-utils.js @@ -45,7 +45,7 @@ const resolveSoftwareTools = (rawSoftware) => { softwareTool: resolveSlug(item.softwareTool, SOFTWARE_PATH), customDescription: stringWithDefault( item.customDescription, - null + null, ), }; } @@ -66,7 +66,7 @@ const resolveSlug = (id, directory) => { if (!id) return null; const slugPart = slugify(id, { lower: true, strict: true }).replace( /^\/+|\/+$/g, - "" + "", ); // Slugify and remove leading/trailing slashes return `/${directory}/${slugPart}/`; }; @@ -76,4 +76,4 @@ module.exports = { resolveToArray, resolveSlug, resolveSoftwareTools, -}; \ No newline at end of file +}; diff --git a/gatsbyutils/test/gatsby-resolver-utils.test.js b/gatsbyutils/test/gatsby-resolver-utils.test.js index 12a7640..d725571 100644 --- a/gatsbyutils/test/gatsby-resolver-utils.test.js +++ b/gatsbyutils/test/gatsby-resolver-utils.test.js @@ -1,109 +1,112 @@ -import { describe, it, expect } from 'vitest'; -import { resolveSlug, resolveSoftwareTools } from '../gatsby-resolver-utils'; -import { DATASET_PATH, SOFTWARE_PATH } from '../constants'; +import { describe, expect, it } from "vitest"; -describe('resolveSlug', () => { - it('should return null when id is falsy', () => { - expect(resolveSlug(null, 'software')).toBe(null); - expect(resolveSlug(undefined, 'software')).toBe(null); - expect(resolveSlug('', 'software')).toBe(null); +import { DATASET_PATH, SOFTWARE_PATH } from "../constants"; +import { resolveSlug, resolveSoftwareTools } from "../gatsby-resolver-utils"; + +describe("resolveSlug", () => { + it("should return null when id is falsy", () => { + expect(resolveSlug(null, "software")).toBe(null); + expect(resolveSlug(undefined, "software")).toBe(null); + expect(resolveSlug("", "software")).toBe(null); }); - it('should build a slug from id and directory', () => { + it("should build a slug from id and directory", () => { expect(resolveSlug("released-emt-dataset", DATASET_PATH)).toBe( - "/dataset/released-emt-dataset/" + "/dataset/released-emt-dataset/", ); }); - it('should slugify the id to lowercase', () => { + it("should slugify the id to lowercase", () => { expect(resolveSlug("UPPERCASE", DATASET_PATH)).toBe( - "/dataset/uppercase/" + "/dataset/uppercase/", ); }); - it('should handle special characters in id', () => { + it("should handle special characters in id", () => { expect(resolveSlug("Tool & Library", SOFTWARE_PATH)).toBe( - "/software/tool-and-library/" + "/software/tool-and-library/", ); expect(resolveSlug("Some/Path/Name", SOFTWARE_PATH)).toBe( - "/software/somepathname/" + "/software/somepathname/", ); }); - it('should handle ids with leading/trailing spaces', () => { - expect(resolveSlug(' trimmed ', 'software')).toBe('/software/trimmed/'); + it("should handle ids with leading/trailing spaces", () => { + expect(resolveSlug(" trimmed ", "software")).toBe( + "/software/trimmed/", + ); }); }); -describe('resolveSoftwareTools', () => { - it('should return empty array for non-array inputs', () => { +describe("resolveSoftwareTools", () => { + it("should return empty array for non-array inputs", () => { expect(resolveSoftwareTools(null)).toEqual([]); expect(resolveSoftwareTools(undefined)).toEqual([]); - expect(resolveSoftwareTools('string')).toEqual([]); + expect(resolveSoftwareTools("string")).toEqual([]); expect(resolveSoftwareTools({})).toEqual([]); expect(resolveSoftwareTools(123)).toEqual([]); }); - it('should return empty array for empty array', () => { + it("should return empty array for empty array", () => { expect(resolveSoftwareTools([])).toEqual([]); }); - it('should filter out invalid items', () => { - const input = [null, undefined, 'string', {}, { other: 'prop' }]; + it("should filter out invalid items", () => { + const input = [null, undefined, "string", {}, { other: "prop" }]; expect(resolveSoftwareTools(input)).toEqual([]); }); - it('should transform valid items with softwareTool', () => { - const input = [{ softwareTool: 'Simularium' }]; + it("should transform valid items with softwareTool", () => { + const input = [{ softwareTool: "Simularium" }]; expect(resolveSoftwareTools(input)).toEqual([ { - softwareTool: '/software/simularium/', + softwareTool: "/software/simularium/", customDescription: null, }, ]); }); - it('should preserve customDescription when provided', () => { + it("should preserve customDescription when provided", () => { const input = [ { - softwareTool: 'Simularium', - customDescription: 'Custom description here', + softwareTool: "Simularium", + customDescription: "Custom description here", }, ]; expect(resolveSoftwareTools(input)).toEqual([ { - softwareTool: '/software/simularium/', - customDescription: 'Custom description here', + softwareTool: "/software/simularium/", + customDescription: "Custom description here", }, ]); }); - it('should return null for empty customDescription', () => { - const input = [{ softwareTool: 'Simularium', customDescription: '' }]; + it("should return null for empty customDescription", () => { + const input = [{ softwareTool: "Simularium", customDescription: "" }]; expect(resolveSoftwareTools(input)).toEqual([ { - softwareTool: '/software/simularium/', + softwareTool: "/software/simularium/", customDescription: null, }, ]); }); - it('should handle mixed valid and invalid items', () => { + it("should handle mixed valid and invalid items", () => { const input = [ null, - { softwareTool: 'Simularium' }, - { other: 'invalid' }, - { softwareTool: 'TFE', customDescription: 'Time explorer' }, + { softwareTool: "Simularium" }, + { other: "invalid" }, + { softwareTool: "TFE", customDescription: "Time explorer" }, ]; expect(resolveSoftwareTools(input)).toEqual([ { - softwareTool: '/software/simularium/', + softwareTool: "/software/simularium/", customDescription: null, }, { - softwareTool: '/software/tfe/', - customDescription: 'Time explorer', + softwareTool: "/software/tfe/", + customDescription: "Time explorer", }, ]); }); -}); \ No newline at end of file +}); diff --git a/package.json b/package.json index df7204c..ab224ed 100644 --- a/package.json +++ b/package.json @@ -48,11 +48,13 @@ "build": "npm run clean && gatsby build", "develop": "npm run clean && gatsby develop", "serve": "gatsby serve", - "format": "prettier --trailing-comma es5 --no-semi --single-quote --write \"{gatsby-*.js,src/**/*.js}\"", + "format": "prettier \"{src,gatsbyutils,netlify}/**/*.{ts,tsx,js,jsx}\" gatsby-*.js --write", + "formatCheck": "prettier \"{src,gatsbyutils,netlify}/**/*.{ts,tsx,js,jsx}\" gatsby-*.js --check", "test": "vitest", "dev": "npx concurrently \"npx netlify-cms-proxy-server\" \"npm start -- --progress\"" }, "devDependencies": { + "@trivago/prettier-plugin-sort-imports": "^6.0.2", "@types/antd": "^1.0.0", "@types/node": "^20.11.20", "@types/react": "^18.2.59", @@ -62,7 +64,7 @@ "gatsby-plugin-postcss": "^6.13.1", "netlify-cli": "^17.15.7", "postcss": "^8.4.35", - "prettier": "^2.0.5", + "prettier": "^3.8.1", "typescript": "^5.3.3", "typescript-plugin-css-modules": "^5.1.0" }, diff --git a/src/cms/preview-templates/AboutPagePreview.js b/src/cms/preview-templates/AboutPagePreview.js index 413a6da..061ec90 100644 --- a/src/cms/preview-templates/AboutPagePreview.js +++ b/src/cms/preview-templates/AboutPagePreview.js @@ -1,19 +1,21 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { AboutPageTemplate } from '../../templates/about-page' +import React from "react"; + +import PropTypes from "prop-types"; + +import { AboutPageTemplate } from "../../templates/about-page"; const AboutPagePreview = ({ entry, widgetFor }) => ( - -) + +); AboutPagePreview.propTypes = { - entry: PropTypes.shape({ - getIn: PropTypes.func, - }), - widgetFor: PropTypes.func, -} + entry: PropTypes.shape({ + getIn: PropTypes.func, + }), + widgetFor: PropTypes.func, +}; -export default AboutPagePreview +export default AboutPagePreview; diff --git a/src/cms/preview-templates/IdeaPostPreview.js b/src/cms/preview-templates/IdeaPostPreview.js index d199a9c..8bcc83f 100644 --- a/src/cms/preview-templates/IdeaPostPreview.js +++ b/src/cms/preview-templates/IdeaPostPreview.js @@ -1,6 +1,8 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { IdeaPostTemplate } from '../../templates/idea-post' +import React from "react"; + +import PropTypes from "prop-types"; + +import { IdeaPostTemplate } from "../../templates/idea-post"; const IdeaPostPreview = ({ entry, widgetFor }) => { const tags = entry.getIn(['data', 'tags']) diff --git a/src/cms/preview-templates/IndexPagePreview.js b/src/cms/preview-templates/IndexPagePreview.js index 62211a3..eff66fc 100644 --- a/src/cms/preview-templates/IndexPagePreview.js +++ b/src/cms/preview-templates/IndexPagePreview.js @@ -1,32 +1,34 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { IndexPageTemplate } from '../../templates/index-page' +import React from "react"; + +import PropTypes from "prop-types"; + +import { IndexPageTemplate } from "../../templates/index-page"; const IndexPagePreview = ({ entry, getAsset }) => { - const data = entry.getIn(['data']).toJS() + const data = entry.getIn(["data"]).toJS(); - if (data) { - return ( - - ) - } else { - return
Loading...
- } -} + if (data) { + return ( + + ); + } else { + return
Loading...
; + } +}; IndexPagePreview.propTypes = { - entry: PropTypes.shape({ - getIn: PropTypes.func, - }), - getAsset: PropTypes.func, -} + entry: PropTypes.shape({ + getIn: PropTypes.func, + }), + getAsset: PropTypes.func, +}; -export default IndexPagePreview +export default IndexPagePreview; diff --git a/src/components/FullWidthImage.tsx b/src/components/FullWidthImage.tsx index 15de1fe..50de2eb 100644 --- a/src/components/FullWidthImage.tsx +++ b/src/components/FullWidthImage.tsx @@ -1,4 +1,5 @@ import React from "react"; + import { GatsbyImage, IGatsbyImageData } from "gatsby-plugin-image"; interface FullWidthImageProps { diff --git a/src/components/IconText.tsx b/src/components/IconText.tsx index 53bee6b..3a07850 100644 --- a/src/components/IconText.tsx +++ b/src/components/IconText.tsx @@ -1,4 +1,5 @@ import React from "react"; + import { Space } from "antd"; export const IconText = ({ icon, text }: { icon: React.FC; text: string }) => ( @@ -8,4 +9,4 @@ export const IconText = ({ icon, text }: { icon: React.FC; text: string }) => ( ); -export default IconText; \ No newline at end of file +export default IconText; diff --git a/src/components/IdeaRoll.tsx b/src/components/IdeaRoll.tsx index 6fbd84f..5ba8143 100644 --- a/src/components/IdeaRoll.tsx +++ b/src/components/IdeaRoll.tsx @@ -1,8 +1,11 @@ import React from "react"; -import { Link, graphql, StaticQuery } from "gatsby"; -import { Avatar, List, Space, Tag } from "antd"; + +import { Link, StaticQuery, graphql } from "gatsby"; + import { MessageOutlined, StarOutlined } from "@ant-design/icons"; import { useLocation } from "@reach/router"; +import { Avatar, List, Space, Tag } from "antd"; + import { MaterialsAndMethods } from "../types"; import { IconText } from "./IconText"; import { TagPopover } from "./TagPopover"; @@ -47,7 +50,9 @@ const IdeaRollTemplate = (props: { type: post.frontmatter.type, authors: post.frontmatter.authors || [], concerns: post.frontmatter.concerns || "", - dataset: { ...post.frontmatter.materialsAndMethods?.dataset?.frontmatter }, + dataset: { + ...post.frontmatter.materialsAndMethods?.dataset?.frontmatter, + }, })); if (props.count) { data.splice(props.count); @@ -85,7 +90,11 @@ const IdeaRollTemplate = (props: { key="list-vertical-message" />, ...item.tags.map((tag) => ( - + )), ]} // extra={ diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 5666287..719a253 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -1,12 +1,16 @@ import * as React from "react"; import { Helmet } from "react-helmet-async"; -import { ConfigProvider, Layout as AntLayout } from "antd"; + import { Script, withPrefix } from "gatsby"; -const { Content } = AntLayout; + +import { Layout as AntLayout, ConfigProvider } from "antd"; import "../style/index.sass"; -import useSiteMetadata from "./SiteMetadata"; import theme from "../style/theme"; +import useSiteMetadata from "./SiteMetadata"; + +const { Content } = AntLayout; + const { container } = require("../style/layout.module.css"); const TemplateWrapper = ({ children }: React.PropsWithChildren) => { diff --git a/src/components/MaterialsAndMethods.tsx b/src/components/MaterialsAndMethods.tsx index 8955e3e..4ea538a 100644 --- a/src/components/MaterialsAndMethods.tsx +++ b/src/components/MaterialsAndMethods.tsx @@ -1,6 +1,8 @@ import React from "react"; + import { Collapse } from "antd"; import type { CollapseProps } from "antd"; + import { CellLine, MaterialsAndMethods, SoftwareTool } from "../types"; const { section, sectionTitle } = require("../style/idea-post.module.css"); @@ -137,7 +139,7 @@ export const MaterialsAndMethodsComponent: React.FC = ({ children: (
{software.map((item, index) => - getSoftwareToolRender(item, index) + getSoftwareToolRender(item, index), )}
), diff --git a/src/components/PreviewCompatibleImage.tsx b/src/components/PreviewCompatibleImage.tsx index 87a2d13..56b92bc 100644 --- a/src/components/PreviewCompatibleImage.tsx +++ b/src/components/PreviewCompatibleImage.tsx @@ -1,4 +1,5 @@ import * as React from "react"; + import { GatsbyImage } from "gatsby-plugin-image"; interface PreviewCompatibleImageProps { diff --git a/src/components/SiteMetadata.tsx b/src/components/SiteMetadata.tsx index 88b3458..9a95b3a 100644 --- a/src/components/SiteMetadata.tsx +++ b/src/components/SiteMetadata.tsx @@ -1,18 +1,16 @@ import { graphql, useStaticQuery } from "gatsby"; const useSiteMetadata = () => { - const { site } = useStaticQuery( - graphql` - query SITE_METADATA_QUERY { - site { - siteMetadata { - title - description - } + const { site } = useStaticQuery(graphql` + query SITE_METADATA_QUERY { + site { + siteMetadata { + title + description } } - ` - ); + } + `); return site.siteMetadata; }; diff --git a/src/components/TagPopover.tsx b/src/components/TagPopover.tsx index 3d2db5c..37b976a 100644 --- a/src/components/TagPopover.tsx +++ b/src/components/TagPopover.tsx @@ -1,6 +1,8 @@ import React from "react"; -import { Tag, Popover } from "antd"; -import { Link, useStaticQuery, graphql } from "gatsby"; + +import { Link, graphql, useStaticQuery } from "gatsby"; + +import { Popover, Tag } from "antd"; import * as styles from "../style/tag-popover.module.css"; @@ -35,7 +37,7 @@ export const TagPopover: React.FC = ({ tag, currentSlug }) => { .filter( (edge) => edge.node.frontmatter.tags?.includes(tag) && - edge.node.fields.slug !== currentSlug + edge.node.fields.slug !== currentSlug, ) .map((post) => (
  • diff --git a/src/pages/ideas/index.tsx b/src/pages/ideas/index.tsx index c4a6cc5..6f1fa0f 100644 --- a/src/pages/ideas/index.tsx +++ b/src/pages/ideas/index.tsx @@ -1,8 +1,9 @@ import React from "react"; + import { Layout as AntdLayout, Flex } from "antd"; -import Layout from "../../components/Layout"; import IdeaRoll from "../../components/IdeaRoll"; +import Layout from "../../components/Layout"; const Header = AntdLayout.Header; @@ -14,7 +15,7 @@ export const IdeasIndexTemplate: React.FC = () => { Shared ideas - + ); }; diff --git a/src/pages/tags/index.js b/src/pages/tags/index.js index b4d83ba..ed4cc77 100644 --- a/src/pages/tags/index.js +++ b/src/pages/tags/index.js @@ -1,8 +1,11 @@ -import * as React from 'react' -import { kebabCase } from 'lodash' -import { Helmet } from 'react-helmet-async' -import { Link, graphql } from 'gatsby' -import Layout from '../../components/Layout' +import * as React from "react"; +import { Helmet } from "react-helmet-async"; + +import { Link, graphql } from "gatsby"; + +import { kebabCase } from "lodash"; + +import Layout from "../../components/Layout"; const TagsPage = ({ data: { @@ -12,31 +15,35 @@ const TagsPage = ({ }, }, }) => ( - -
    - -
    -
    -
    -

    Tags

    -
      - {group.map((tag) => ( -
    • - - {tag.fieldValue} ({tag.totalCount}) - -
    • - ))} -
    -
    -
    -
    -
    -
    -) + +
    + +
    +
    +
    +

    Tags

    +
      + {group.map((tag) => ( +
    • + + {tag.fieldValue} ({tag.totalCount}) + +
    • + ))} +
    +
    +
    +
    +
    +
    +); export default TagsPage diff --git a/src/templates/about-page.tsx b/src/templates/about-page.tsx index 6159589..767a660 100644 --- a/src/templates/about-page.tsx +++ b/src/templates/about-page.tsx @@ -1,7 +1,9 @@ import React from "react"; + import { graphql } from "gatsby"; -import Layout from "../components/Layout"; + import Content, { HTMLContent } from "../components/Content"; +import Layout from "../components/Layout"; interface QueryResult { data: { diff --git a/src/templates/allenite.tsx b/src/templates/allenite.tsx index 096ae31..1839f9b 100644 --- a/src/templates/allenite.tsx +++ b/src/templates/allenite.tsx @@ -1,5 +1,7 @@ import React from "react"; -import { graphql, StaticQuery } from "gatsby"; + +import { StaticQuery, graphql } from "gatsby"; + import Layout from "../components/Layout"; interface QueryResult { diff --git a/src/templates/dataset.tsx b/src/templates/dataset.tsx index b324cfc..c5f5a63 100644 --- a/src/templates/dataset.tsx +++ b/src/templates/dataset.tsx @@ -1,4 +1,5 @@ import React from "react"; + import { graphql } from "gatsby"; interface QueryResult { diff --git a/src/templates/idea-post.tsx b/src/templates/idea-post.tsx index 52f4a25..e7e0012 100644 --- a/src/templates/idea-post.tsx +++ b/src/templates/idea-post.tsx @@ -1,18 +1,20 @@ import React from "react"; import { Helmet } from "react-helmet-async"; -import { graphql, Link, PageProps } from "gatsby"; -import { Layout as AntdLayout, Card, Flex } from "antd"; + +import { Link, PageProps, graphql } from "gatsby"; + import { ArrowLeftOutlined, MessageOutlined, StarOutlined, } from "@ant-design/icons"; +import { Layout as AntdLayout, Card, Flex } from "antd"; -import Layout from "../components/Layout"; import IconText from "../components/IconText"; +import Layout from "../components/Layout"; import { MaterialsAndMethodsComponent } from "../components/MaterialsAndMethods"; -import { IdeaFields, IdeaFrontmatter, IdeaPostQuery } from "../types"; import { TagPopover } from "../components/TagPopover"; +import { IdeaFields, IdeaFrontmatter, IdeaPostQuery } from "../types"; const Header = AntdLayout.Header; @@ -31,7 +33,6 @@ export const IdeaPostTemplate: React.FC = ({ title, materialsAndMethods, }) => { - // TODO query the actual data const introduction = "PLACEHOLDER INTRODUCTION TEXT"; const nextSteps = "PLACEHOLDER NEXT STEPS TEXT"; @@ -113,7 +114,10 @@ const IdeaPost: React.FC> = ({ data }) => { - + ); }; diff --git a/src/templates/index-page.tsx b/src/templates/index-page.tsx index caabba6..d412a1e 100644 --- a/src/templates/index-page.tsx +++ b/src/templates/index-page.tsx @@ -1,12 +1,14 @@ import React from "react"; -import PropTypes from "prop-types"; + import { Link, graphql } from "gatsby"; import { getImage } from "gatsby-plugin-image"; + import { Layout as AntdLayout, Flex } from "antd"; +import PropTypes from "prop-types"; -import Layout from "../components/Layout"; -import IdeaRoll from "../components/IdeaRoll"; import FullWidthImage from "../components/FullWidthImage"; +import IdeaRoll from "../components/IdeaRoll"; +import Layout from "../components/Layout"; const { container, diff --git a/src/templates/program.tsx b/src/templates/program.tsx index 281126c..60ccb14 100644 --- a/src/templates/program.tsx +++ b/src/templates/program.tsx @@ -1,5 +1,7 @@ import React from "react"; -import { graphql, StaticQuery } from "gatsby"; + +import { StaticQuery, graphql } from "gatsby"; + import Layout from "../components/Layout"; interface QueryResult { diff --git a/src/templates/tags.tsx b/src/templates/tags.tsx index 7ee3a5a..16109b6 100644 --- a/src/templates/tags.tsx +++ b/src/templates/tags.tsx @@ -1,6 +1,8 @@ import * as React from "react"; import { Helmet } from "react-helmet-async"; + import { Link, graphql } from "gatsby"; + import Layout from "../components/Layout"; interface QueryResult { @@ -89,10 +91,7 @@ export const tagPageQuery = graphql` limit: 1000 sort: { frontmatter: { date: DESC } } filter: { - frontmatter: { - tags: { in: [$tag] } - draft: { ne: true } - } + frontmatter: { tags: { in: [$tag] }, draft: { ne: true } } } ) { totalCount diff --git a/src/types/index.ts b/src/types/index.ts index 492fa0f..3f91025 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -15,8 +15,11 @@ export type IdeaPostNode = NonNullable; export type IdeaFrontmatter = NonNullable; export type IdeaFields = NonNullable; -export type MaterialsAndMethods = NonNullable; +export type MaterialsAndMethods = NonNullable< + IdeaFrontmatter["materialsAndMethods"] +>; export type CellLine = MaterialsAndMethods["cellLines"][number]; export type SoftwareTool = MaterialsAndMethods["software"][number]; -export type IdeasForTags = Queries.AllIdeasForTagsQuery["allMarkdownRemark"]["edges"]; \ No newline at end of file +export type IdeasForTags = + Queries.AllIdeasForTagsQuery["allMarkdownRemark"]["edges"]; diff --git a/yarn.lock b/yarn.lock index 2e09a91..a039918 100644 --- a/yarn.lock +++ b/yarn.lock @@ -117,6 +117,15 @@ js-tokens "^4.0.0" picocolors "^1.1.1" +"@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c" + integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw== + dependencies: + "@babel/helper-validator-identifier" "^7.28.5" + js-tokens "^4.0.0" + picocolors "^1.1.1" + "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.27.2": version "7.27.2" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.27.2.tgz#4183f9e642fd84e74e3eea7ffa93a412e3b102c9" @@ -163,6 +172,17 @@ "@jridgewell/trace-mapping" "^0.3.25" jsesc "^3.0.2" +"@babel/generator@^7.28.0", "@babel/generator@^7.29.0": + version "7.29.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50" + integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw== + dependencies: + "@babel/parser" "^7.29.0" + "@babel/types" "^7.29.0" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + "@babel/helper-annotate-as-pure@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.1.tgz#4345d81a9a46a6486e24d069469f13e60445c05d" @@ -214,6 +234,11 @@ lodash.debounce "^4.0.8" resolve "^1.14.2" +"@babel/helper-globals@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674" + integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== + "@babel/helper-member-expression-to-functions@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz#ea1211276be93e798ce19037da6f06fbb994fa44" @@ -287,6 +312,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== +"@babel/helper-validator-identifier@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" + integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== + "@babel/helper-validator-option@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" @@ -326,6 +356,13 @@ dependencies: "@babel/types" "^7.27.1" +"@babel/parser@^7.28.0", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.0.tgz#669ef345add7d057e92b7ed15f0bac07611831b6" + integrity sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww== + dependencies: + "@babel/types" "^7.29.0" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz#61dd8a8e61f7eb568268d1b5f129da3eee364bf9" @@ -1071,6 +1108,15 @@ "@babel/parser" "^7.27.2" "@babel/types" "^7.27.1" +"@babel/template@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57" + integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ== + dependencies: + "@babel/code-frame" "^7.28.6" + "@babel/parser" "^7.28.6" + "@babel/types" "^7.28.6" + "@babel/traverse@^7.14.0", "@babel/traverse@^7.16.8", "@babel/traverse@^7.20.13", "@babel/traverse@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.27.1.tgz#4db772902b133bbddd1c4f7a7ee47761c1b9f291" @@ -1084,6 +1130,19 @@ debug "^4.3.1" globals "^11.1.0" +"@babel/traverse@^7.28.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a" + integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA== + dependencies: + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.0" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.29.0" + "@babel/template" "^7.28.6" + "@babel/types" "^7.29.0" + debug "^4.3.1" + "@babel/types@7.26.3": version "7.26.3" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.3.tgz#37e79830f04c2b5687acc77db97fbc75fb81f3c0" @@ -1100,6 +1159,14 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.27.1" +"@babel/types@^7.28.0", "@babel/types@^7.28.6", "@babel/types@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7" + integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + "@bugsnag/browser@^7.25.0": version "7.25.0" resolved "https://registry.yarnpkg.com/@bugsnag/browser/-/browser-7.25.0.tgz#aa56a8e138dfff268ac29c5fe374cfc3c9b42a76" @@ -2178,6 +2245,14 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" +"@jridgewell/gen-mapping@^0.3.12": + version "0.3.13" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" + integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/gen-mapping@^0.3.5": version "0.3.8" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" @@ -2210,7 +2285,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== -"@jridgewell/sourcemap-codec@^1.5.5": +"@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5": version "1.5.5" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== @@ -2231,6 +2306,14 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@jridgewell/trace-mapping@^0.3.28": + version "0.3.31" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" + integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@juggle/resize-observer@^3.4.0": version "3.4.0" resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60" @@ -3794,6 +3877,20 @@ resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== +"@trivago/prettier-plugin-sort-imports@^6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-6.0.2.tgz#b30948c4d22a84f00ae9133bcabd0603de3c0261" + integrity sha512-3DgfkukFyC/sE/VuYjaUUWoFfuVjPK55vOFDsxD56XXynFMCZDYFogH2l/hDfOsQAm1myoU/1xByJ3tWqtulXA== + dependencies: + "@babel/generator" "^7.28.0" + "@babel/parser" "^7.28.0" + "@babel/traverse" "^7.28.0" + "@babel/types" "^7.28.0" + javascript-natural-sort "^0.7.1" + lodash-es "^4.17.21" + minimatch "^9.0.0" + parse-imports-exports "^0.2.4" + "@trysound/sax@0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" @@ -12061,6 +12158,11 @@ jackspeak@^3.1.2: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" +javascript-natural-sort@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59" + integrity sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw== + javascript-stringify@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz#27c76539be14d8bd128219a2d731b09337904e79" @@ -14715,6 +14817,13 @@ parse-headers@^2.0.2: resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.6.tgz#7940f0abe5fe65df2dd25d4ce8800cb35b49d01c" integrity sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A== +parse-imports-exports@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/parse-imports-exports/-/parse-imports-exports-0.2.4.tgz#e3fb3b5e264cfb55c25b5dfcbe7f410f8dc4e7af" + integrity sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ== + dependencies: + parse-statements "1.0.11" + parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -14758,6 +14867,11 @@ parse-srcset@^1.0.2: resolved "https://registry.yarnpkg.com/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1" integrity sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q== +parse-statements@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/parse-statements/-/parse-statements-1.0.11.tgz#8787c5d383ae5746568571614be72b0689584344" + integrity sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA== + parse5-htmlparser2-tree-adapter@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz#b5a806548ed893a43e24ccb42fbb78069311e81b" @@ -15397,10 +15511,10 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier@^2.0.5: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +prettier@^3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.8.1.tgz#edf48977cf991558f4fcbd8a3ba6015ba2a3a173" + integrity sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg== pretty-bytes@^5.6.0: version "5.6.0"