From 99dfa32cc523f14af0cae7b106ecce263ec3ec92 Mon Sep 17 00:00:00 2001 From: Marijn Kampf Date: Wed, 3 Jan 2024 14:54:14 +0000 Subject: [PATCH 1/2] fix frontend console errors --- .../add-company/client/CompanySearchStep.jsx | 4 +- .../business-details/client/SectionAbout.jsx | 6 +- .../client/SectionAddresses.jsx | 5 +- .../client/SectionHierarchy.jsx | 5 +- .../client/SectionOneList.jsx | 9 +- .../business-details/client/SectionRegion.jsx | 5 +- .../business-details/client/SectionSector.jsx | 7 +- .../AccountManagementCard.jsx | 4 +- .../ActiveInvestmentProjectsCard.jsx | 6 +- .../overview-table-cards/ActivityCard.jsx | 80 ++++----- .../apps/exports/client/ExportsIndex.jsx | 12 +- .../client/InteractionDetailsForm.jsx | 1 - .../ActivityFeed/CollectionList/filters.js | 2 +- .../ActivityOverviewSummary.jsx | 5 +- .../CollectionList/CollectionItem.jsx | 2 +- .../components/CollectionList/index.jsx | 41 +++-- .../CompanyInvestmentTab.jsx | 6 +- .../components/EntityList/EntityListItem.jsx | 4 +- .../FilteredCollectionList/index.jsx | 33 ++-- .../elements/FieldAdvisersTypeahead/index.jsx | 4 +- .../Form/elements/FieldCheckboxes/index.jsx | 7 +- .../Form/elements/FieldCurrency/index.jsx | 4 +- .../Form/elements/FieldUneditable/index.jsx | 2 +- src/client/components/Form/index.jsx | 2 +- .../components/Layout/CompanyLayout.jsx | 5 +- .../components/Layout/ContactLayout.jsx | 5 +- .../components/Layout/DefaultLayout.jsx | 2 +- src/client/components/Layout/FormLayout.jsx | 7 +- .../components/Layout/ProjectLayout.jsx | 7 +- .../components/Layout/ProjectLayoutNew.jsx | 170 ++++++++++++++++++ src/client/components/LocalNav/index.jsx | 4 +- src/client/components/NewWindowLink/index.jsx | 2 +- .../RoutedCheckboxGroupField/index.jsx | 49 ++--- .../Filter.jsx | 2 +- .../CollectionListPlaceholder.jsx | 3 +- src/client/components/SummaryTable/index.jsx | 12 +- src/client/components/Typeahead/index.jsx | 16 +- .../modules/Companies/CoreTeam/CoreTeam.jsx | 2 +- .../CompanyContactsCollection.jsx | 4 +- .../ContactAuditHistory.jsx | 53 +++--- .../ContactDetails/ContactDetails.jsx | 12 +- .../modules/Events/EventDetails/index.jsx | 6 +- .../Interactions/InteractionDetails/index.jsx | 54 +++--- .../Investments/Opportunities/Opportunity.jsx | 1 - .../OpportunityDetailsHeader.jsx | 2 +- .../Investments/Profiles/transformers.js | 2 +- .../Details/EditProjectRequirements.jsx | 10 +- .../Projects/Details/EditProjectSummary.jsx | 2 +- .../Projects/Details/EditProjectValue.jsx | 8 +- .../Projects/Details/ProjectDetails.jsx | 41 ++--- .../Projects/Evidence/ProjectEvidence.jsx | 12 +- .../Projects/InvestmentFormFields.jsx | 20 +-- .../Investments/Projects/Team/ProjectTeam.jsx | 6 +- .../Investments/Projects/transformers.js | 9 +- src/client/modules/Omis/AssigneeTime.jsx | 8 +- .../CompanyOrdersCollection.jsx | 4 +- src/client/modules/Omis/CompleteOrder.jsx | 2 +- .../modules/Omis/CreateOrder/CreateOrder.jsx | 4 +- .../modules/Omis/EditInvoiceDetails.jsx | 4 +- src/client/modules/Omis/OMISLocalHeader.jsx | 2 +- .../Omis/WorkOrderTables/AssigneesTable.jsx | 4 +- .../Omis/WorkOrderTables/ContactTable.jsx | 1 + .../Omis/WorkOrderTables/InternalUseTable.jsx | 1 + .../WorkOrderTables/InvoiceDetailsTable.jsx | 1 + .../WorkOrderTables/QuoteInformationTable.jsx | 1 + .../Omis/WorkOrderTables/SubscribersTable.jsx | 3 +- ...ExportNoRecentInteractionsItemRenderer.jsx | 1 + .../Investments/InvestmentItemRenderer.jsx | 1 + .../Tasks/MyTasksItemRenderer.jsx | 1 + .../modules/Tasks/TaskForm/TaskFormFields.jsx | 2 - .../cypress/fakers/investment-projects.js | 4 + .../project-edit-project-management-spec.js | 4 +- .../fixtures/v3/investment/projects.json | 3 +- 73 files changed, 546 insertions(+), 289 deletions(-) create mode 100644 src/client/components/Layout/ProjectLayoutNew.jsx diff --git a/src/apps/companies/apps/add-company/client/CompanySearchStep.jsx b/src/apps/companies/apps/add-company/client/CompanySearchStep.jsx index efb24638e57..85e2e046bd9 100644 --- a/src/apps/companies/apps/add-company/client/CompanySearchStep.jsx +++ b/src/apps/companies/apps/add-company/client/CompanySearchStep.jsx @@ -88,8 +88,8 @@ function CompanySearchStep({ } CompanySearchStep.propTypes = { - countryName: PropTypes.string.isRequired, - countryIsoCode: PropTypes.string.isRequired, + countryName: PropTypes.string, + countryIsoCode: PropTypes.string, csrfToken: PropTypes.string.isRequired, } diff --git a/src/apps/companies/apps/business-details/client/SectionAbout.jsx b/src/apps/companies/apps/business-details/client/SectionAbout.jsx index 5e33778bf78..d442f0bbb60 100644 --- a/src/apps/companies/apps/business-details/client/SectionAbout.jsx +++ b/src/apps/companies/apps/business-details/client/SectionAbout.jsx @@ -36,7 +36,11 @@ const SectionAbout = ({ company, isDnbCompany, isArchived }) => ( caption={`About ${company.name}`} data-test="aboutDetailsContainer" actions={ - !isArchived && Edit + !isArchived && ( + + Edit + + ) } > diff --git a/src/apps/companies/apps/business-details/client/SectionAddresses.jsx b/src/apps/companies/apps/business-details/client/SectionAddresses.jsx index 011724bd742..de633a1cdac 100644 --- a/src/apps/companies/apps/business-details/client/SectionAddresses.jsx +++ b/src/apps/companies/apps/business-details/client/SectionAddresses.jsx @@ -54,7 +54,10 @@ const SectionAddresses = ({ company, isDnbCompany, isArchived }) => { actions={ !isDnbCompany && !isArchived && ( - + Edit ) diff --git a/src/apps/companies/apps/business-details/client/SectionHierarchy.jsx b/src/apps/companies/apps/business-details/client/SectionHierarchy.jsx index 85af6764d2d..55e320d746c 100644 --- a/src/apps/companies/apps/business-details/client/SectionHierarchy.jsx +++ b/src/apps/companies/apps/business-details/client/SectionHierarchy.jsx @@ -210,7 +210,10 @@ const SectionHierarchy = ({ actions={ !isArchived && showDataHubHierarchy && ( - + Edit ) diff --git a/src/apps/companies/apps/business-details/client/SectionOneList.jsx b/src/apps/companies/apps/business-details/client/SectionOneList.jsx index ed4291e01a0..a88c148ee71 100644 --- a/src/apps/companies/apps/business-details/client/SectionOneList.jsx +++ b/src/apps/companies/apps/business-details/client/SectionOneList.jsx @@ -1,3 +1,4 @@ +/* eslint-disable prettier/prettier */ import React from 'react' import PropTypes from 'prop-types' import Link from '@govuk-react/link' @@ -20,8 +21,8 @@ const getLocation = (manager) => { return manager.ditTeam.ukRegion ? manager.ditTeam.ukRegion.name : manager.ditTeam.country - ? manager.ditTeam.country.name - : '-' + ? manager.ditTeam.country.name + : '-' } const SectionOneList = ({ company, isArchived, isDnbCompany }) => @@ -33,7 +34,9 @@ const SectionOneList = ({ company, isArchived, isDnbCompany }) => actions={ !isArchived && !isDnbCompany && ( - Edit + + Edit + ) } > diff --git a/src/apps/companies/apps/business-details/client/SectionRegion.jsx b/src/apps/companies/apps/business-details/client/SectionRegion.jsx index 8fd9b0f6eab..8cb70a2031f 100644 --- a/src/apps/companies/apps/business-details/client/SectionRegion.jsx +++ b/src/apps/companies/apps/business-details/client/SectionRegion.jsx @@ -12,7 +12,10 @@ const SectionRegion = ({ company, isArchived }) => data-test="regionDetailsContainer" actions={ !isArchived && ( - + Edit ) diff --git a/src/apps/companies/apps/business-details/client/SectionSector.jsx b/src/apps/companies/apps/business-details/client/SectionSector.jsx index bbcd054570e..768b57d1428 100644 --- a/src/apps/companies/apps/business-details/client/SectionSector.jsx +++ b/src/apps/companies/apps/business-details/client/SectionSector.jsx @@ -11,7 +11,12 @@ const SectionSector = ({ company, isArchived }) => ( data-test="sectorDetailsContainer" actions={ !isArchived && ( - Edit + + Edit + ) } > diff --git a/src/apps/companies/apps/company-overview/overview-table-cards/AccountManagementCard.jsx b/src/apps/companies/apps/company-overview/overview-table-cards/AccountManagementCard.jsx index d7a90ab8bf6..98881c50285 100644 --- a/src/apps/companies/apps/company-overview/overview-table-cards/AccountManagementCard.jsx +++ b/src/apps/companies/apps/company-overview/overview-table-cards/AccountManagementCard.jsx @@ -94,8 +94,8 @@ const AccountManagementCard = ({ company }) => { {buildCellContents( viewablePrimaryContacts.length > 0, - {viewablePrimaryContacts.map((contact) => ( -
  • + {viewablePrimaryContacts.map((contact, index) => ( +
  • ( const ActiveInvestmentList = ({ upcomingActiveInvestments, companyId }) => upcomingActiveInvestments.map((activeInvestment) => ( - <> + @@ -175,7 +175,7 @@ const ActiveInvestmentList = ({ upcomingActiveInvestments, companyId }) => )} - + )) const ActiveInvestmentProjectsCard = ({ diff --git a/src/apps/companies/apps/company-overview/overview-table-cards/ActivityCard.jsx b/src/apps/companies/apps/company-overview/overview-table-cards/ActivityCard.jsx index 89889bf46df..73bd6dd3798 100644 --- a/src/apps/companies/apps/company-overview/overview-table-cards/ActivityCard.jsx +++ b/src/apps/companies/apps/company-overview/overview-table-cards/ActivityCard.jsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Fragment } from 'react' import { Link } from 'govuk-react' import PropTypes from 'prop-types' import camelCase from 'camelcase' @@ -31,47 +31,43 @@ const ActivityCard = (props) => { const feedTypeText = camelCase(feedType, { pascalCase: true }) return ( -
    - - {feedTypeText} activity - - Add interaction - - - } - data-test={`${feedTypeText} activityCardContainer`} - > - - - - - - - - - View all activities - - - - -
    + + {feedTypeText} activity + + Add interaction + + + } + data-test={`${feedTypeText} activityCardContainer`} + > + + + + + + + + + View all activities + + + + ) } diff --git a/src/apps/companies/apps/exports/client/ExportsIndex.jsx b/src/apps/companies/apps/exports/client/ExportsIndex.jsx index 7d5aa097d0d..a3b88a9b43e 100644 --- a/src/apps/companies/apps/exports/client/ExportsIndex.jsx +++ b/src/apps/companies/apps/exports/client/ExportsIndex.jsx @@ -38,7 +38,12 @@ const ExportsIndex = ({ companyId, returnUrl }) => { caption="Exports" actions={ !company.archived && ( - Edit + + Edit + ) } > @@ -87,8 +92,8 @@ const ExportsIndex = ({ companyId, returnUrl }) => { repeatedly tested their model against a subset of known-good data to improve it. The scores are as follows:
      - {Object.values(exportPotentialLabels).map((category) => ( -
    1. + {Object.values(exportPotentialLabels).map((category, index) => ( +
    2. {category.text} - {category.description}
    3. ))} @@ -106,6 +111,7 @@ const ExportsIndex = ({ companyId, returnUrl }) => { Edit diff --git a/src/apps/interactions/apps/details-form/client/InteractionDetailsForm.jsx b/src/apps/interactions/apps/details-form/client/InteractionDetailsForm.jsx index 85b17d97c0d..f9e52c012b1 100644 --- a/src/apps/interactions/apps/details-form/client/InteractionDetailsForm.jsx +++ b/src/apps/interactions/apps/details-form/client/InteractionDetailsForm.jsx @@ -194,7 +194,6 @@ InteractionDetailsForm.propTypes = { contactId: PropTypes.string, interactionId: PropTypes.string, user: PropTypes.object, - ...StepInteractionDetails.propTypes, } export default connect(({ values, ...state }) => ({ diff --git a/src/client/components/ActivityFeed/CollectionList/filters.js b/src/client/components/ActivityFeed/CollectionList/filters.js index e724cacc335..e09532a1d15 100644 --- a/src/client/components/ActivityFeed/CollectionList/filters.js +++ b/src/client/components/ActivityFeed/CollectionList/filters.js @@ -26,7 +26,7 @@ export const buildSelectedFilters = ( })), }, createdByOthers: { - queryParams: 'createdByOthers', + queryParam: 'createdByOthers', options: buildOptionsFilter({ options: [ { diff --git a/src/client/components/ActivityFeed/activities/card/item-renderers/ActivityOverviewSummary.jsx b/src/client/components/ActivityFeed/activities/card/item-renderers/ActivityOverviewSummary.jsx index 9a89b61f28c..ffc6aae0265 100644 --- a/src/client/components/ActivityFeed/activities/card/item-renderers/ActivityOverviewSummary.jsx +++ b/src/client/components/ActivityFeed/activities/card/item-renderers/ActivityOverviewSummary.jsx @@ -10,7 +10,10 @@ export default class ActivityOverviewSummary extends React.PureComponent { date: PropTypes.string, kind: PropTypes.string, subject: PropTypes.node, - summary: PropTypes.string, + summary: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.arrayOf(PropTypes.any), + ]), } render() { diff --git a/src/client/components/CollectionList/CollectionItem.jsx b/src/client/components/CollectionList/CollectionItem.jsx index 7bbbc9160fc..1fa82ec0bd2 100644 --- a/src/client/components/CollectionList/CollectionItem.jsx +++ b/src/client/components/CollectionList/CollectionItem.jsx @@ -138,7 +138,7 @@ const CollectionItem = ({ CollectionItem.propTypes = { headingUrl: PropTypes.string, headingText: PropTypes.string.isRequired, - subheading: PropTypes.string, + subheading: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), badges: PropTypes.arrayOf( PropTypes.shape({ text: PropTypes.string, diff --git a/src/client/components/CollectionList/index.jsx b/src/client/components/CollectionList/index.jsx index 648c3d00a1b..47af0db42fb 100644 --- a/src/client/components/CollectionList/index.jsx +++ b/src/client/components/CollectionList/index.jsx @@ -93,24 +93,27 @@ const CollectionList = ({ ) )}
    - - {() => - isComplete && ( - <> -
      - {results.map((item, i) => ( - - ))} -
    - - - ) - } -
    + {taskProps && ( + + {() => + isComplete && ( + <> +
      + {results.map((item, i) => ( + + ))} +
    + + + ) + } +
    + )} + {/* )} */} @@ -142,7 +145,7 @@ CollectionList.propTypes = { }), maxItemsToPaginate: PropTypes.number, maxItemsToDownload: PropTypes.number, - onPageClick: PropTypes.func.isRequired, + onPageClick: PropTypes.func, addItemUrl: PropTypes.string, metadataRenderer: PropTypes.func, footerRenderer: PropTypes.func, diff --git a/src/client/components/CompanyTabbedLocalNavigation/CompanyInvestmentTab.jsx b/src/client/components/CompanyTabbedLocalNavigation/CompanyInvestmentTab.jsx index ba6b63f2265..a1512c023dc 100644 --- a/src/client/components/CompanyTabbedLocalNavigation/CompanyInvestmentTab.jsx +++ b/src/client/components/CompanyTabbedLocalNavigation/CompanyInvestmentTab.jsx @@ -66,9 +66,9 @@ const investmentNavItems = (companyId, isLCP) => [ }, ] -const CompanyInvestmentTab = ({ navItem, index }) => +const CompanyInvestmentTab = ({ navItem }) => navItem && ( - + ( > {investmentNavItems(companyId, isLCP).map((t, index) => ( - + ))} diff --git a/src/client/components/EntityList/EntityListItem.jsx b/src/client/components/EntityList/EntityListItem.jsx index cae2b133d78..71edb0e0f6f 100644 --- a/src/client/components/EntityList/EntityListItem.jsx +++ b/src/client/components/EntityList/EntityListItem.jsx @@ -64,8 +64,8 @@ const EntityListItem = ({ id, onEntityClick, data, text, heading, meta }) => { return ( isClickable && onEntityClick(data)} onKeyDown={(e) => isClickable && e.keyCode === KEY_ENTER && onEntityClick(data) diff --git a/src/client/components/FilteredCollectionList/index.jsx b/src/client/components/FilteredCollectionList/index.jsx index fe18ab9d834..55d0621d509 100644 --- a/src/client/components/FilteredCollectionList/index.jsx +++ b/src/client/components/FilteredCollectionList/index.jsx @@ -1,9 +1,9 @@ /* eslint-disable react/no-array-index-key */ // this is because there isn't necessarily a unique id to use as the key -import React from 'react' +import React, { useEffect } from 'react' import PropTypes from 'prop-types' -import { Route } from 'react-router-dom' +import { Route, useHistory, useLocation } from 'react-router-dom' import { GridRow, GridCol } from 'govuk-react' import { isEmpty } from 'lodash' import qs from 'qs' @@ -93,21 +93,28 @@ const FilteredCollectionList = ({ useReactRouter = false, collectionItemTemplate = collectionItemTemplateDefault, }) => { + const history = useHistory() + const location = useLocation() + const totalPages = Math.ceil( Math.min(count, maxItemsToPaginate) / itemsPerPage ) + const qsParams = qs.parse(location.search.slice(1)) + + useEffect(() => { + if (defaultQueryParams && isEmpty(qsParams)) { + history.push({ + search: qs.stringify({ + ...defaultQueryParams, + }), + }) + } + }, []) + return ( - {({ history, location }) => { - const qsParams = qs.parse(location.search.slice(1)) + {() => { const initialPage = getPageNumber(qsParams) - if (defaultQueryParams && isEmpty(qsParams)) { - history.push({ - search: qs.stringify({ - ...defaultQueryParams, - }), - }) - } return ( {children} @@ -144,8 +151,8 @@ const FilteredCollectionList = ({ {() => isComplete && (
      - {results.map((item) => ( - + {results.map((item, index) => ( + {(pushAnalytics) => collectionItemTemplate( item, diff --git a/src/client/components/Form/elements/FieldAdvisersTypeahead/index.jsx b/src/client/components/Form/elements/FieldAdvisersTypeahead/index.jsx index 8a3f05a282c..707cee40c90 100644 --- a/src/client/components/Form/elements/FieldAdvisersTypeahead/index.jsx +++ b/src/client/components/Form/elements/FieldAdvisersTypeahead/index.jsx @@ -47,5 +47,7 @@ FieldAdvisersTypeahead.propTypes = { isMulti: PropTypes.bool, placeholder: PropTypes.string, } - +FieldAdvisersTypeahead.defaultProps = { + label: '', +} export default FieldAdvisersTypeahead diff --git a/src/client/components/Form/elements/FieldCheckboxes/index.jsx b/src/client/components/Form/elements/FieldCheckboxes/index.jsx index 087dd0402c8..297c3447604 100644 --- a/src/client/components/Form/elements/FieldCheckboxes/index.jsx +++ b/src/client/components/Form/elements/FieldCheckboxes/index.jsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Fragment } from 'react' import PropTypes from 'prop-types' import MultiChoice from '@govuk-react/multi-choice' import styled from 'styled-components' @@ -96,12 +96,11 @@ const FieldCheckboxes = ({ }, index ) => ( - <> + {exclusive && index === options.length - 1 && ( or )} {value.includes(optionValue) && !!children ? children : null} - + ) )} diff --git a/src/client/components/Form/elements/FieldCurrency/index.jsx b/src/client/components/Form/elements/FieldCurrency/index.jsx index 93789a66b02..8f54ae4d77a 100644 --- a/src/client/components/Form/elements/FieldCurrency/index.jsx +++ b/src/client/components/Form/elements/FieldCurrency/index.jsx @@ -98,8 +98,8 @@ const FieldCurrency = ({ initialValue, }) - const [displayValue, setDisplayValue] = useState() - const [rawValue, setRawValue] = useState() + const [displayValue, setDisplayValue] = useState('') + const [rawValue, setRawValue] = useState('') const [editing, setEditing] = useState(false) useEffect(() => { diff --git a/src/client/components/Form/elements/FieldUneditable/index.jsx b/src/client/components/Form/elements/FieldUneditable/index.jsx index 9e6d1ebdf52..eeab92c1eff 100644 --- a/src/client/components/Form/elements/FieldUneditable/index.jsx +++ b/src/client/components/Form/elements/FieldUneditable/index.jsx @@ -17,7 +17,7 @@ const FieldUneditable = ({ {children}{' '} {onChangeClick && ( - + Change {label || legend} )} diff --git a/src/client/components/Form/index.jsx b/src/client/components/Form/index.jsx index 3362277d81d..7cbd79fac43 100644 --- a/src/client/components/Form/index.jsx +++ b/src/client/components/Form/index.jsx @@ -571,7 +571,7 @@ Form.propTypes = { id: PropTypes.string.isRequired, analyticsFormName: PropTypes.string.isRequired, analyticsData: PropTypes.func, - cancelRedirectTo: PropTypes.func.isRequired, + cancelRedirectTo: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]), cancelButtonLabel: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), submissionTaskName: PropTypes.string.isRequired, submitButtonLabel: PropTypes.string, diff --git a/src/client/components/Layout/CompanyLayout.jsx b/src/client/components/Layout/CompanyLayout.jsx index 03f2d07b338..26566bb2eb4 100644 --- a/src/client/components/Layout/CompanyLayout.jsx +++ b/src/client/components/Layout/CompanyLayout.jsx @@ -36,7 +36,10 @@ const CompanyLayout = ({ CompanyLayout.propTypes = { company: PropTypes.object.isRequired, - children: PropTypes.element.isRequired, + children: PropTypes.oneOfType([ + PropTypes.element, + PropTypes.arrayOf(PropTypes.element), + ]).isRequired, isInvestment: PropTypes.bool, isLCP: PropTypes.bool, } diff --git a/src/client/components/Layout/ContactLayout.jsx b/src/client/components/Layout/ContactLayout.jsx index 41ae473df9f..56801eed8e1 100644 --- a/src/client/components/Layout/ContactLayout.jsx +++ b/src/client/components/Layout/ContactLayout.jsx @@ -62,7 +62,10 @@ const ContactLayout = ({ contact, flashMessages, permissions, children }) => { ContactLayout.propTypes = { contact: PropTypes.object.isRequired, permissions: PropTypes.array.isRequired, - children: PropTypes.element.isRequired, + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.element), + PropTypes.element, + ]).isRequired, } export default ContactLayout diff --git a/src/client/components/Layout/DefaultLayout.jsx b/src/client/components/Layout/DefaultLayout.jsx index a6c6c3f028a..e7113cb1a5f 100644 --- a/src/client/components/Layout/DefaultLayout.jsx +++ b/src/client/components/Layout/DefaultLayout.jsx @@ -60,7 +60,7 @@ const DefaultLayout = ({ } DefaultLayout.propTypes = { - heading: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired, + heading: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), headingLink: PropTypes.shape({ url: PropTypes.string.isRequired, text: PropTypes.string.isRequired, diff --git a/src/client/components/Layout/FormLayout.jsx b/src/client/components/Layout/FormLayout.jsx index 8f21d08815e..b6283a90664 100644 --- a/src/client/components/Layout/FormLayout.jsx +++ b/src/client/components/Layout/FormLayout.jsx @@ -10,8 +10,11 @@ const FormLayout = ({ setWidth, children }) => ( ) FormLayout.propTypes = { - setWidth: PropTypes.string, - children: PropTypes.element.isRequired, + setWidth: PropTypes.string.isRequired, + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.element), + PropTypes.element, + ]).isRequired, } export default FormLayout diff --git a/src/client/components/Layout/ProjectLayout.jsx b/src/client/components/Layout/ProjectLayout.jsx index d54c586832c..cce2d6049dc 100644 --- a/src/client/components/Layout/ProjectLayout.jsx +++ b/src/client/components/Layout/ProjectLayout.jsx @@ -152,10 +152,13 @@ export const ProjectLayout = ({ ) ProjectLayout.propTypes = { - project: PropTypes.object.isRequired, + project: PropTypes.object, breadcrumbs: PropTypes.array.isRequired, pageTitle: PropTypes.string.isRequired, - children: PropTypes.array.isRequired, + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.element), + PropTypes.element, + ]).isRequired, userPermissions: PropTypes.array.isRequired, flashMessages: PropTypes.shape({ type: PropTypes.oneOfType([ diff --git a/src/client/components/Layout/ProjectLayoutNew.jsx b/src/client/components/Layout/ProjectLayoutNew.jsx new file mode 100644 index 00000000000..edbcffbbc78 --- /dev/null +++ b/src/client/components/Layout/ProjectLayoutNew.jsx @@ -0,0 +1,170 @@ +import React from 'react' +import PropTypes from 'prop-types' +import styled from 'styled-components' +import GridCol from '@govuk-react/grid-col' +import GridRow from '@govuk-react/grid-row' +import { SPACING } from '@govuk-react/constants' +import { connect } from 'react-redux' + +import { + DefaultLayout, + InvestmentProjectLocalHeader, + LocalNav, + LocalNavLink, +} from '../../components' +import urls from '../../../lib/urls' +import { state2props } from './state' +import { buildProjectBreadcrumbs } from '../../modules/Investments/utils' + +const StyledNavWrapper = styled('div')` + margin-bottom: ${SPACING.SCALE_5}; +` + +const userCanViewInteractions = (permissions) => + permissions.includes( + 'interaction.view_associated_investmentproject_interaction' + ) || permissions.includes('interaction.view_all_interaction') + +const userCanViewPropositions = (permissions) => + permissions.includes('proposition.view_all_proposition') || + permissions.includes('proposition.view_associated_proposition') + +const userCanViewAdmin = (permissions) => + permissions.includes('investment.change_to_any_stage_investmentproject') + +const localProjectUrl = (url, project) => project && url(project.id) + +export const ProjectLayoutNew = ({ + project, + breadcrumbs, + pageTitle, + children, + userPermissions, +}) => { + console.log('*********************') + console.log(project) + return ( + + } + > + + + + + + Project details + + + Project team + + + Tasks + + {userCanViewInteractions(userPermissions) && ( + + Interactions + + )} + {userCanViewPropositions(userPermissions) && ( + + Propositions + + )} + + Evaluations + + + Edit history + + + Evidence + + {userCanViewAdmin(userPermissions) && ( + + Admin + + )} + + + + {children} + + + ) +} + +ProjectLayoutNew.propTypes = { + project: PropTypes.object.isRequired, + breadcrumbs: PropTypes.array.isRequired, + pageTitle: PropTypes.string.isRequired, + children: PropTypes.array.isRequired, + userPermissions: PropTypes.array.isRequired, +} + +export default connect(state2props)(ProjectLayoutNew) diff --git a/src/client/components/LocalNav/index.jsx b/src/client/components/LocalNav/index.jsx index 53e3bd27a31..d15b649bf5f 100644 --- a/src/client/components/LocalNav/index.jsx +++ b/src/client/components/LocalNav/index.jsx @@ -43,8 +43,8 @@ export const LocalNav = ({ children, dataTest = 'local-nav' }) => { return ( diff --git a/src/client/components/NewWindowLink/index.jsx b/src/client/components/NewWindowLink/index.jsx index 84c8764827e..68c1c20ff33 100644 --- a/src/client/components/NewWindowLink/index.jsx +++ b/src/client/components/NewWindowLink/index.jsx @@ -37,7 +37,7 @@ const NewWindowLink = ({ href, children, showWarning = true, ...rest }) => ( NewWindowLink.propTypes = { href: PropTypes.string.isRequired, - children: PropTypes.node.isRequired, + children: PropTypes.node, showWarning: PropTypes.bool, } diff --git a/src/client/components/RoutedCheckboxGroupField/index.jsx b/src/client/components/RoutedCheckboxGroupField/index.jsx index 3c9b409c402..183f79ddd91 100644 --- a/src/client/components/RoutedCheckboxGroupField/index.jsx +++ b/src/client/components/RoutedCheckboxGroupField/index.jsx @@ -5,27 +5,34 @@ import qs from 'qs' import CheckboxGroupField from '../CheckboxGroupField' -const RoutedCheckboxGroupField = ({ qsParam, ...props }) => ( - - {({ history, location }) => { - const qsParams = qs.parse(location.search.slice(1)) - return ( - - history.push({ - search: qs.stringify({ - ...qsParams, - [qsParam]: pickedOptions.map(({ value }) => value), - page: 1, - }), - }) - } - /> - ) - }} - -) +const RoutedCheckboxGroupField = ({ qsParam, ...props }) => { + // Don't render component if there are no options. + if (props.options === undefined) { + return null + } + + return ( + + {({ history, location }) => { + const qsParams = qs.parse(location.search.slice(1)) + return ( + + history.push({ + search: qs.stringify({ + ...qsParams, + [qsParam]: pickedOptions.map(({ value }) => value), + page: 1, + }), + }) + } + /> + ) + }} + + ) +} RoutedCheckboxGroupField.propTypes = { name: PropTypes.string.isRequired, diff --git a/src/client/components/RoutedRelatedCompaniesCheckboxGroup/Filter.jsx b/src/client/components/RoutedRelatedCompaniesCheckboxGroup/Filter.jsx index de835b388ff..2dd4f1081a4 100644 --- a/src/client/components/RoutedRelatedCompaniesCheckboxGroup/Filter.jsx +++ b/src/client/components/RoutedRelatedCompaniesCheckboxGroup/Filter.jsx @@ -48,7 +48,7 @@ const RoutedRelatedCompaniesCheckboxGroup = ({ company, selectedOptions }) => ( } selectedOptions={selectedOptions} data-test="include-related-companies-filter" - aria-description={ + aria-describedby={ relatedCompaniesCountResponse.reducedTree ? SUBSIDIARIES_LIMITED_LABEL : undefined diff --git a/src/client/components/SkeletonPlaceholder/CollectionListPlaceholder.jsx b/src/client/components/SkeletonPlaceholder/CollectionListPlaceholder.jsx index d5d60dc6d28..c825e94af72 100644 --- a/src/client/components/SkeletonPlaceholder/CollectionListPlaceholder.jsx +++ b/src/client/components/SkeletonPlaceholder/CollectionListPlaceholder.jsx @@ -26,9 +26,10 @@ const collectionList = () => ( {Array.from(Array(listItems).keys()).map((i) => ( - + {Array.from(Array(listItemFields).keys()).map((j) => ( { {children .filter((c) => c) - .map((c) => ( -
    1. {c}
    2. + .map((c, index) => ( +
    3. {c}
    4. ))}
      ) @@ -122,7 +122,7 @@ SummaryTable.ListRow = ({ heading, value, emptyValue, ...rest }) => ( ) SummaryTable.propTypes = { - caption: PropTypes.string, + caption: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), actions: PropTypes.node, children: PropTypes.node, } @@ -145,7 +145,11 @@ SummaryTable.Row.defaultProps = { SummaryTable.TextRow.propTypes = { heading: PropTypes.string, - value: PropTypes.string, + value: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.element, + PropTypes.arrayOf(PropTypes.element), + ]), } SummaryTable.TextRow.defaultProps = { diff --git a/src/client/components/Typeahead/index.jsx b/src/client/components/Typeahead/index.jsx index 1ea32487b80..10b20732db6 100644 --- a/src/client/components/Typeahead/index.jsx +++ b/src/client/components/Typeahead/index.jsx @@ -2,12 +2,14 @@ import React from 'react' import MultiInstanceTypeahead from './Typeahead' -const Typeahead = ({ id, name, ...props }) => ( - -) +const Typeahead = ({ id, name, ...props }) => { + return ( + + ) +} export default Typeahead diff --git a/src/client/modules/Companies/CoreTeam/CoreTeam.jsx b/src/client/modules/Companies/CoreTeam/CoreTeam.jsx index 6a827bf05e6..6dccd8e0370 100644 --- a/src/client/modules/Companies/CoreTeam/CoreTeam.jsx +++ b/src/client/modules/Companies/CoreTeam/CoreTeam.jsx @@ -19,7 +19,7 @@ const getSubheadingText = (company) => { const buildRow = (transformedAdvisers) => transformedAdvisers.map(({ team, location, name, email }) => ( - + {team} {location} {name} diff --git a/src/client/modules/Contacts/CollectionList/CompanyContactsCollection.jsx b/src/client/modules/Contacts/CollectionList/CompanyContactsCollection.jsx index 992258f605b..1d04ab20cf4 100644 --- a/src/client/modules/Contacts/CollectionList/CompanyContactsCollection.jsx +++ b/src/client/modules/Contacts/CollectionList/CompanyContactsCollection.jsx @@ -42,7 +42,7 @@ const CompanyContactsCollection = ({ breadcrumbs={[{ text: 'Contacts' }]} returnUrl={returnUrl} > - {company.archived && ( + {company.archived ? (
      - )} + ) : null} ( <> - Audit history - - {contactAuditHistory.count > 0 && ( - + Audit history + - )} + {contactAuditHistory.count > 0 ? ( + + ) : null} - - + {}} + /> + + )} diff --git a/src/client/modules/Contacts/ContactDetails/ContactDetails.jsx b/src/client/modules/Contacts/ContactDetails/ContactDetails.jsx index 63141ddfc08..370267917c6 100644 --- a/src/client/modules/Contacts/ContactDetails/ContactDetails.jsx +++ b/src/client/modules/Contacts/ContactDetails/ContactDetails.jsx @@ -51,13 +51,13 @@ const ContactDetails = ({ contactId, companyAddress, permissions }) => ( {(contact) => ( <> - {contact.validEmail === false && ( + {contact.validEmail === false ? ( - )} + ) : null} ( children={contact.email} flag={contact.validEmail === false} /> - {contact.notes && ( + {contact.notes ? ( - )} + ) : null} ( } /> - {!contact.archived && ( + {!contact.archived ? ( - )} + ) : null} { heading="Contact(s)" children={transformContacts(interaction.contacts)} /> - {interaction.service && ( + {interaction.service ? ( - )} - {interaction.serviceDeliveryStatus && ( + ) : null} + {interaction.serviceDeliveryStatus ? ( - )} - {interaction.grantAmountOffered && ( + ) : null} + {interaction.grantAmountOffered ? ( - )} - {interaction.netCompanyReceipt && ( + ) : null} + {interaction.netCompanyReceipt ? ( - )} - {interaction.notes && ( + ) : null} + {interaction.notes ? ( - )} + ) : null} - {interaction.ditParticipants && ( + {interaction.ditParticipants ? ( - )} - {interaction.investmentProject && ( + ) : null} + {interaction.investmentProject ? ( { } /> - )} - {interaction.kind === 'service_delivery' && ( + ) : null} + {interaction.kind === 'service_delivery' ? ( { ) } /> - )} - {interaction.communicationChannel && ( + ) : null} + {interaction.communicationChannel ? ( - )} - {interaction.policyFeedbackNotes && ( + ) : null} + {interaction.policyFeedbackNotes ? ( - )} + ) : null} {interaction.exportCountries?.length > 0 && transformExportCountries(interaction.exportCountries)} - {interaction.relatedTradeAgreements?.length > 0 && ( + {interaction.relatedTradeAgreements?.length > 0 ? ( - )} - {interaction.largeCapitalOpportunity && ( + ) : null} + {interaction.largeCapitalOpportunity ? ( { } /> - )} - {interaction.theme === EXPORT && ( + ) : null} + {interaction.theme === EXPORT ? ( <> { /> )} - )} + ) : null}