Skip to content

Commit

Permalink
FAQ/About pages (#236)
Browse files Browse the repository at this point in the history
  • Loading branch information
dgading authored Sep 20, 2024
1 parent f682488 commit 8339277
Show file tree
Hide file tree
Showing 51 changed files with 2,285 additions and 1,491 deletions.
2,144 changes: 942 additions & 1,202 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@civicactions/cmsds-open-data-components",
"version": "3.5.1",
"version": "3.6.0",
"description": "Components for the open data catalog frontend using CMS Design System",
"main": "dist/main.js",
"source": "src/index.ts",
Expand Down
35 changes: 35 additions & 0 deletions src/components/CMSTopNav/cms-topnav.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.dkan-c-cms-topnav {
height: 51px;
}

.dkan-c-cms-topnav > div {
height: 100%;
}

.dkan-c-cms-topnav .dkan-c-cms-topnav-menu a {
display: inline-block;
margin: 3px 7px;
}

.dkan-c-cms-topnav--menu ul {
list-style: none;
margin: 0;
padding: 0;
}

.dkan-c-cms-topnav .dkan-c-cms-topnav--tagline {
height: 100%;
margin-left: 16px;
}

@media screen and (max-width: 544px) {
.dkan-c-cms-topnav {
display: none;
}
}

@media screen and (min-width: 1024px) {
.dkan-c-cms-topnav {
height: 85px;
}
}
46 changes: 46 additions & 0 deletions src/components/CMSTopNav/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import { NavLink } from 'react-router-dom';
import HeaderTagline from '../HeaderTagline';
import HeaderNavIconLink from '../HeaderNavIconLink';
import { OrgType, NavLinkArray } from '../../types/misc';
import './cms-topnav.scss';

export type CMSTopNavProps = {
org: OrgType
links: NavLinkArray[]
}

const CMSTopNav = (props: CMSTopNavProps) => {
const { links, org } = props;
const { urlTitle, logoAltText="", logoFilePath="", tagline, url} = org;
return (
<div className="dkan-c-cms-topnav ds-u-display--flex ds-u-padding-x--5 ds-u-align-items--center ds-u-justify-content--center ds-u-lg-justify-content--start">
<div className="ds-l-col--12 ds-l-md-col--5 ds-l-lg-col--7 ds-u-display--flex ds-u-align-items--center ds-u-justify-content--center ds-u-md-justify-content--start">
<HeaderNavIconLink
url={url}
urlTitle={urlTitle}
logoAltText={logoAltText}
logoFilePath={logoFilePath}
/>
<HeaderTagline tagline={tagline} />
</div>
<div className="ds-l-col--7 ds-l-lg-col--5 ds-u-display--none ds-u-md-display--inline-flex ds-u-align-items--center ds-u-justify-content--end">
<nav className="dkan-c-cms-topnav--menu">
<ul className="ds-u-justify-content--end ds-u-md-align-items--center ds-u-flex-direction--column ds-u-md-flex-direction--row">
{links.map((link: any) => {
return(
<li className="ds-u-margin-x--05 ds-u-font-size--sm">
<NavLink to={link.url}>
<span>{link.label}</span>
</NavLink>
</li>
)
})}
</ul>
</nav>
</div>
</div>
);
}

export default CMSTopNav;
4 changes: 2 additions & 2 deletions src/components/DataTableControls/DataTableControls.test.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from "react";
import { render, screen } from "@testing-library/react";
import DataTableControls from ".";
import { ManageColumnsContext } from "../DatasetTableTab/DataTableStateWrapper";
import { DataTableContext } from "../../templates/Dataset";
import ManageColumnsContext from '../ManageColumns/ManageColumnsContext';
import DataTableContext from "../../templates/Dataset/DataTableContext";
import * as resource from "../../tests/fixtures/resource.json";
import * as distribution from "../../tests/fixtures/distribution.json";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import FilteredResourceDescription from './FilteredResourceDescription';
import DatasetDescription from '.';
import * as dataset from "../../tests/fixtures/dataset.json";
import * as distributionWithTitle from "../../tests/fixtures/distributionWithTitle.json"

describe('<FilteredResourceDescription />', () => {
describe('<DatasetDescription />', () => {
test("Renders with distribution description over dataset description", () => {
render(
<FilteredResourceDescription
<DatasetDescription
dataset={dataset}
distribution={distributionWithTitle.distribution[0]}
/>
Expand All @@ -17,15 +17,25 @@ describe('<FilteredResourceDescription />', () => {
});
test("Renders dataset description", () => {
render(
<FilteredResourceDescription
<DatasetDescription
dataset={dataset}
distribution={dataset.distribution[0]}
/>
);
expect(screen.getByText("The data below contains newly reported, active covered outpatient drugs which were reported by participating drug manufacturers since the last quarterly update of the Drug Products in the Medicaid Drug Rebate Program (MDRP) database.")).toBeInTheDocument();
});
test("Doesn't render when no dataset or distribution is added", () => {
const { container } = render(<FilteredResourceDescription />);
const { container } = render(<DatasetDescription />);
expect(container.innerHTML).toBe("");
});
test("Render new description if customDescription", () => {
render(
<DatasetDescription
dataset={dataset}
distribution={distributionWithTitle.distribution[0]}
customDescription={() => "My custom description."}
/>
);
expect(screen.getByText("My custom description.")).toBeInTheDocument();
});
});
40 changes: 40 additions & 0 deletions src/components/DatasetDescription/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { useEffect, useState } from 'react';
import DOMPurify from 'dompurify';
import { DatasetDescriptionType } from '../../types/dataset';

const DatasetDescription = (
{distribution, dataset, resource, customDescription, updateAriaLive} : DatasetDescriptionType
) => {
const [description, setDescription] = useState("");

if(!distribution && !dataset?.identifier) {
return null;
}
useEffect(() => {
let newDescription = '';
if (customDescription) {
newDescription = customDescription(dataset, distribution, resource);
} else {
if(distribution.data && distribution.data.description) {
newDescription = distribution.data.description;
} else if(dataset.description) {
newDescription = dataset.description;
}
}
if (description !== newDescription && updateAriaLive) {
updateAriaLive(newDescription);
}
setDescription(newDescription);
}, [resource, distribution, dataset, customDescription]);

return (
<div className={'ds-u-measure--wide ds-u-margin-bottom--7'}>
<div
className="ds-u-margin-top--0 dc-c-metadata-description"
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(description) }}
/>
</div>
);
}

export default DatasetDescription;
5 changes: 2 additions & 3 deletions src/components/DatasetTableTab/DataTableStateWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React from "react";
import { createContext, useContext, useState } from "react";
import DatasetTable from ".";
import { DataTableContext } from "../../templates/Dataset";

export const ManageColumnsContext = createContext({})
import DataTableContext from "../../templates/Dataset/DataTableContext";
import ManageColumnsContext from '../ManageColumns/ManageColumnsContext';

const DataTableStateWrapper = () => {
const { id, datasetTableControls } = useContext(DataTableContext);
Expand Down
2 changes: 1 addition & 1 deletion src/components/DatasetTableTab/DatasetTableTab.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import '@testing-library/jest-dom';
import DataTableStateWrapper from './DataTableStateWrapper';
import * as resource from "../../tests/fixtures/resource.json";
import * as distribution from "../../tests/fixtures/distribution.json";
import { DataTableContext } from '../../templates/Dataset';
import DataTableContext from "../../templates/Dataset/DataTableContext";

describe('<DatasetTableTab />', () => {
window.scrollTo = jest.fn();
Expand Down
4 changes: 2 additions & 2 deletions src/components/DatasetTableTab/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { Pagination, Spinner, Alert } from '@cmsgov/design-system';
import DataTableHeader from '../DatatableHeader';
import QueryBuilder from '../QueryBuilder';
import { DistributionType, ColumnType, ResourceType } from '../../types/dataset';
import { DataTableContext } from '../../templates/Dataset';
import { ManageColumnsContext } from './DataTableStateWrapper';
import DataTableContext from "../../templates/Dataset/DataTableContext";
import ManageColumnsContext from '../ManageColumns/ManageColumnsContext';

export function prepareColumns(columns : any, schema : any) {
return columns.map((column : any) => ({
Expand Down
4 changes: 2 additions & 2 deletions src/components/Datatable/Datatable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import TruncatedResizeableTHead from "./TruncatedResizeableTHead";
import FixedSizeTHead from "./FixedSizeTHead";
import "./datatable.scss";
import DataTableControls from "../DataTableControls";
import { DataTableContext } from "../../templates/Dataset";
import { ManageColumnsContext } from "../DatasetTableTab/DataTableStateWrapper";
import DataTableContext from "../../templates/Dataset/DataTableContext";
import ManageColumnsContext from "../ManageColumns/ManageColumnsContext";

const DataTable = ({
columns,
Expand Down
1 change: 0 additions & 1 deletion src/components/DesktopHeader/index.jsx

This file was deleted.

69 changes: 69 additions & 0 deletions src/components/FAQAccordion/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from 'react';
import { FAQItemType } from '../../types/misc';
import { Accordion, AccordionItem, Button } from "@cmsgov/design-system";

type FAQProps = {
faqs: FAQItemType[]
}

const FAQAccordion = (props: FAQProps) => {
const { faqs } = props;
const [expanded, setExpanded] = React.useState(false);
const [faqItems, setFaqItems] = React.useState(faqs);

function toggleAll() {
if (expanded) {
const newFaqs = faqItems.map((item) => ({...item, open: false}));
setFaqItems(newFaqs);
setExpanded(false);
} else {
const newFaqs = faqItems.map((item) => ({...item, open: true}));
setFaqItems(newFaqs);
setExpanded(true);
}
}

function toggleAccordionItem(id: string) {
const currentFaqIndex = faqItems.findIndex((item) => item.id === id);
const updatedFaq = {
...faqItems[currentFaqIndex],
open: !faqItems[currentFaqIndex].open
}

const newFaqs = [
...faqItems.slice(0, currentFaqIndex),
updatedFaq,
...faqItems.slice(currentFaqIndex + 1)
]
setFaqItems(newFaqs);

const openCount = newFaqs.filter((item) => item.open === true).length;
if (openCount > 0 && openCount == newFaqs.length) {
setExpanded(true);
} else {
setExpanded(false);
}
}

return(
<div>
<Button className='ds-u-margin-y--2 ds-u-float--right' type="button" variation='ghost' onClick={() => toggleAll()}>
{`${expanded ? 'Collapse' : 'Expand'} all FAQs`}
</Button>
<Accordion>
{faqItems.map((faq) => (
<AccordionItem
key={faq.id}
heading={faq.title}
isControlledOpen={faq.open}
onChange={() => toggleAccordionItem(faq.id)}
>
{faq.body}
</AccordionItem>
))}
</Accordion>
</div>
);
};

export default FAQAccordion;
Loading

0 comments on commit 8339277

Please sign in to comment.