Skip to content

Commit

Permalink
Merge pull request #367 from MetadataWorks/main
Browse files Browse the repository at this point in the history
Updated PR for merge from MetaDataWorks to main standard registry
  • Loading branch information
tejpowar authored Apr 8, 2024
2 parents 03ba1d5 + 241b656 commit 0b39088
Show file tree
Hide file tree
Showing 50 changed files with 2,833 additions and 370 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ typings/

# dotenv environment variables file
.env
.env.local

# OSX
.DS_Store
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Create a `.env` file containing the following content:

```
touch .env.local
echo "CKAN_URL=https://manage.test.standards.nhs.uk/api/action\nPAGES_CKAN_URL=https://manage.test.standards.nhs.uk/api/action" >> .env.local
echo "CKAN_URL=https://manage.test.standards.nhs.uk/api/action\nPAGES_CKAN_URL=https://manage.standards.nhs.uk/api/action" >> .env.local
```

### Running the server
Expand Down
1 change: 1 addition & 0 deletions ui/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module.exports = {
},
plugins: ['react'],
rules: {
'@next/next/no-document-import-in-page': 'off',
'react/prop-types': [0],
'react/react-in-jsx-scope': [0], // next puts react in global scope
'no-console': [2, { allow: ['warn', 'error'] }],
Expand Down
41 changes: 41 additions & 0 deletions ui/components/ActionLink/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import styles from './style.module.scss';

const ActionLink = ({ link = false, title = '' }) => {
return !link ? (
'Not available'
) : (
<>
<div className="nhsuk-action-link">
<a
className="nhsuk-action-link__link"
href={link}
rel="noreferrer"
target="_blank"
title={`Documentation for ${title}`}
>
<svg
className="nhsuk-icon nhsuk-icon__arrow-right-circle"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
aria-hidden="true"
width="36"
height="36"
>
<path d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 2a10 10 0 0 0-9.95 9h11.64L9.74 7.05a1 1 0 0 1 1.41-1.41l5.66 5.65a1 1 0 0 1 0 1.42l-5.66 5.65a1 1 0 0 1-1.41 0 1 1 0 0 1 0-1.41L13.69 13H2.05A10 10 0 1 0 12 2z"></path>
</svg>
<span className={`nhsuk-action-link__text ${styles.linkText}`}>
View documentation for this standard
</span>
</a>
</div>
<div>
<span className="nhsuk-u-visually-hidden">opens in a new tab</span>
<br />
(opens in new tab)
</div>
</>
);
};

export default ActionLink;
3 changes: 3 additions & 0 deletions ui/components/ActionLink/style.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.linkText {
font-size: 1.2em;
}
5 changes: 4 additions & 1 deletion ui/components/Cookies/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import { useEffect, useState } from 'react';
import { setCookie, hasCookie } from 'cookies-next';
import classnames from 'classnames';
import styles from './style.module.scss';
import { useContentContext } from '../../context/content';

export const Cookies = ({ choice }) => {
const [consentChoice, consentChoiceSet] = useState(choice);
const { content } = useContentContext();
const { title } = content;
useEffect(() => {
consentChoiceSet(hasCookie('localConsent'));
}, [choice]);
Expand All @@ -28,7 +31,7 @@ export const Cookies = ({ choice }) => {
>
<div className="nhsuk-width-container">
<p className="nhsuk-heading-s">
Cookies on the NHS Data Standards Directory
{`Cookies on the ${title} website`}
</p>
<p>
We use essential cookies to make this service work. We&lsquo;d
Expand Down
138 changes: 77 additions & 61 deletions ui/components/Dataset/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@ import DOMPurify from 'isomorphic-dompurify';
export const formatDate = (date, dateFormat = 'd MMM yyyy') =>
format(parseISO(date), dateFormat);

function escapeRegExp(text) {
return text && text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}

function Embolden({ children }) {
const { getSelections } = useQueryContext();
const { q } = getSelections();
const re = new RegExp(`(${q})`, 'ig');
const replaced = children.replace(re, '<strong>$1</strong>');
const escapedQuery = escapeRegExp(q);
const re = new RegExp(`(${escapedQuery})`, 'ig');
const replaced = children ? children.replace(re, '<strong>$1</strong>') : '';

return (
<span
Expand All @@ -27,17 +32,51 @@ function Embolden({ children }) {
);
}

function StandardTypeBadge({ isPublishedStandard }) {
return (
<div>
{isPublishedStandard ? (
<Tag type="active" classes="nhsuk-body-s">
Published standard
</Tag>
) : (
<Tag type="future" classes="nhsuk-body-s">
Future standard
</Tag>
)}
</div>
);
}

function Model({ model }) {
const { name, status, title, metadata_created, description } = model;
const {
name,
status,
title,
metadata_created,
description,
is_published_standard,
} = model;
const target = `/published-standards/${name}`;

<Tag type={status} classes="nhsuk-body-s">
{status}
</Tag>;

return (
<>
<Link href={target}>
<a>
<Embolden>{title}</Embolden>
</a>
</Link>
<div className={classnames(styles.standardHeader)}>
<div className={classnames(styles.standardTitle)}>
<Link href={target}>
<a>
<Embolden>{title}</Embolden>
</a>
</Link>
</div>
<div className={classnames(styles.standardFlag)}>
<StandardTypeBadge isPublishedStandard={is_published_standard} />
</div>
</div>
<p>
<Embolden>{description}</Embolden>
</p>
Expand Down Expand Up @@ -69,22 +108,23 @@ function SortMenu({ searchTerm }) {
label: 'Relevance',
value: 'score desc',
},
{
label: 'Added (newest)',
value: 'metadata_created desc',
},
{
label: 'Added (oldest)',
value: 'metadata_created asc',
},
{
label: 'Name (A to Z)',
value: 'name asc',
selected: 'selected',
},
{
label: 'Name (Z to A)',
value: 'name desc',
},
{
label: 'Added (newest)',
value: 'metadata_created desc',
},
{
label: 'Added (oldest)',
value: 'metadata_created asc',
},
];

const value = `${query.orderBy} ${query.order}`;
Expand All @@ -100,43 +140,6 @@ function SortMenu({ searchTerm }) {
);
}

const CheckBox = () => {
const { getSelections, updateQuery } = useQueryContext();
const toggleMandated = (event) => {
const selections = getSelections();
const { name, checked } = event.target;
delete selections[name];
if (checked) {
selections[name] = checked;
}
updateQuery(selections, { replace: true });
};

return (
<div
className={classnames(
'nhsuk-checkboxes__item nhsuk-u-margin-bottom-4',
styles.checkboxItem
)}
>
<input
className="nhsuk-checkboxes__input nhsuk-u-font-size-16"
id="mandated"
name="mandated"
type="checkbox"
value="nationally mandated"
onChange={toggleMandated}
/>
<label
className="nhsuk-label nhsuk-checkboxes__label nhsuk-u-font-size-16"
htmlFor="mandated"
>
National requirement
</label>
</div>
);
};

const NoResultsSummary = ({ searchTerm }) => (
<>
<h3>
Expand Down Expand Up @@ -164,8 +167,9 @@ export default function Dataset({
data: initialData = {},
includeType,
schema,
futureAndPublished = false,
}) {
const { query } = useQueryContext();
const { query, updateQuery } = useQueryContext();
const searchTerm = query.q;
const [data, setData] = useState(initialData);
const [loading, setLoading] = useState(false);
Expand All @@ -177,23 +181,38 @@ export default function Dataset({
async function getData() {
try {
setLoading(true);
const res = await axios.post('/api/refresh-list', query);
const res = await axios.post('/api/refresh-list', {
...query,
futureAndPublished,
});
setData(res.data);
} catch (err) {
console.error(err);
} finally {
setLoading(false);
}
}

// we dont want to fetch data on initial load.
if (pageLoaded) {
getData();
}

// we don't want pageLoaded in the dependency array
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [query]);

useEffect(() => setPageLoaded(true), []);
useEffect(() => {
let orderBy = null;
let order = null;
if (!searchTerm || searchTerm === '') {
orderBy = 'name';
order = 'asc';
}

updateQuery({ ...query, orderBy, order });
setPageLoaded(true);
}, []); // eslint-disable-line react-hooks/exhaustive-deps

return (
<>
Expand All @@ -209,14 +228,11 @@ export default function Dataset({
<div className="nhsuk-grid-column-one-half">
<SortMenu searchTerm={searchTerm} />
</div>
<div className="nhsuk-grid-column-one-half">
<CheckBox />
</div>
</div>
{count > 0 ? (
<ul className={styles.list} id="browse-results">
{results.map((model) => (
<li key={model.id} className={styles.listItem}>
{results.map((model, index) => (
<li key={model.id || index} className={styles.listItem}>
<Model model={model} includeType={includeType} />
</li>
))}
Expand Down
15 changes: 15 additions & 0 deletions ui/components/Dataset/style.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,18 @@
.right {
text-align: right;
}

.standardHeader {
display: flex;
justify-content: space-between;
}

.standardTitle {
flex: 6;
margin-bottom: 1.4em;
}

.standardFlag {
flex: 2;
text-align: right;
}
3 changes: 2 additions & 1 deletion ui/components/DatasetSchema/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,13 @@ export function DatasetSchema({
// Schema:description - Description
// Schema:url - defined url of page

export function WebPageSchema({ title, description, host }) {
export function WebPageSchema({ title, headerTitle, description, host }) {
const router = useRouter();
const data = {
'@context': 'https://schema.org/',
'@type': 'WebPage',
title,
headerTitle,
description,
url: [host, router.asPath].join(''),
contactPoint: {
Expand Down
2 changes: 1 addition & 1 deletion ui/components/FeedbackFooter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function FeedbackFooter() {
</h2>
<p className="nhsuk-u-font-size-16">
This is a new service — your{' '}
<Link newWindow={true} href="https://forms.gle/CKKi5nFzUjuxHB9N6">
<Link newWindow={true} href="https://forms.office.com/e/VQTTC04qxb">
feedback
<span className="nhsuk-u-visually-hidden">opens in a new window</span>
</Link>{' '}
Expand Down
16 changes: 16 additions & 0 deletions ui/components/FilterSummary/FilterWidget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import styles from './FilterSummary.module.scss';

function FilterWidget({ children, onClick }) {
return (
<button
type="button"
aria-label={`X, click to remove ${children}`}
onClick={onClick}
className={styles.widget}
>
X {children}
</button>
);
}

export default FilterWidget;
Loading

0 comments on commit 0b39088

Please sign in to comment.