From c6d57e29e6529d76276e5f3423be4cfce4aab908 Mon Sep 17 00:00:00 2001 From: Christopher Sunkel Date: Mon, 22 Jan 2024 17:31:55 +0000 Subject: [PATCH] Migrate company export tabs to React Router --- .../apps/exports/__test__/controller.test.js | 38 ---- .../exports/client/ExportsHistory/index.jsx | 91 --------- .../apps/exports/client/ExportsIndex.jsx | 192 ------------------ .../companies/apps/exports/controllers.js | 46 ----- src/apps/companies/apps/exports/router.js | 21 -- .../companies/apps/exports/transformer.js | 39 ---- .../apps/exports/views/full-history.njk | 13 -- .../companies/apps/exports/views/index.njk | 13 -- src/apps/companies/labels.js | 35 ---- src/apps/companies/router.js | 2 - src/apps/routers.js | 3 + src/client/index.jsx | 8 - .../Companies/CollectionList/labels.js | 35 ---- .../ExportCountriesEdit/index.jsx | 2 +- .../ExportHistory}/group-history-items.js | 0 .../CompanyExports/ExportHistory/index.jsx | 115 +++++++++++ .../CompanyExports/ExportHistory}/reducer.js | 2 +- .../CompanyExports/ExportHistory}/state.js | 0 .../CompanyExports/ExportHistory}/tasks.js | 14 +- .../CompanyExports}/ExportWins/index.jsx | 6 +- .../CompanyExports}/ExportWins/reducer.js | 2 +- .../CompanyExports}/ExportWins/state.js | 0 .../CompanyExports}/ExportWins/tasks.js | 6 +- .../Companies/CompanyExports/ExportsEdit.jsx | 12 +- .../Companies/CompanyExports/ExportsIndex.jsx | 185 +++++++++++++++++ .../CompanyExports}/GreatProfile.jsx | 4 +- .../Companies/CompanyExports/labels.js | 32 +++ .../Companies/CompanyExports}/tasks.js | 2 +- .../Companies/CompanyExports/transformers.js | 38 +++- .../TableCards/ExportStatusCard.jsx | 2 +- .../CompanyOverview/TableCards/tasks.js | 2 +- src/client/reducers.js | 8 +- src/client/routes.js | 17 ++ src/client/tasks.js | 6 +- .../cypress/specs/DA/permission-spec.js | 2 +- .../specs/companies/export/history-spec.js | 16 +- .../specs/companies/export/index-spec.js | 16 +- 37 files changed, 432 insertions(+), 593 deletions(-) delete mode 100644 src/apps/companies/apps/exports/__test__/controller.test.js delete mode 100644 src/apps/companies/apps/exports/client/ExportsHistory/index.jsx delete mode 100644 src/apps/companies/apps/exports/client/ExportsIndex.jsx delete mode 100644 src/apps/companies/apps/exports/controllers.js delete mode 100644 src/apps/companies/apps/exports/router.js delete mode 100644 src/apps/companies/apps/exports/transformer.js delete mode 100644 src/apps/companies/apps/exports/views/full-history.njk delete mode 100644 src/apps/companies/apps/exports/views/index.njk rename src/{apps/companies/apps/exports/client => client/modules/Companies/CompanyExports/ExportHistory}/group-history-items.js (100%) create mode 100644 src/client/modules/Companies/CompanyExports/ExportHistory/index.jsx rename src/{apps/companies/apps/exports/client/ExportsHistory => client/modules/Companies/CompanyExports/ExportHistory}/reducer.js (92%) rename src/{apps/companies/apps/exports/client/ExportsHistory => client/modules/Companies/CompanyExports/ExportHistory}/state.js (100%) rename src/{apps/companies/apps/exports/client/ExportsHistory => client/modules/Companies/CompanyExports/ExportHistory}/tasks.js (88%) rename src/{apps/companies/apps/exports/client => client/modules/Companies/CompanyExports}/ExportWins/index.jsx (85%) rename src/{apps/companies/apps/exports/client => client/modules/Companies/CompanyExports}/ExportWins/reducer.js (94%) rename src/{apps/companies/apps/exports/client => client/modules/Companies/CompanyExports}/ExportWins/state.js (100%) rename src/{apps/companies/apps/exports/client => client/modules/Companies/CompanyExports}/ExportWins/tasks.js (91%) create mode 100644 src/client/modules/Companies/CompanyExports/ExportsIndex.jsx rename src/{apps/companies/apps/exports/client => client/modules/Companies/CompanyExports}/GreatProfile.jsx (75%) create mode 100644 src/client/modules/Companies/CompanyExports/labels.js rename src/{apps/companies/apps/exports/client => client/modules/Companies/CompanyExports}/tasks.js (77%) diff --git a/src/apps/companies/apps/exports/__test__/controller.test.js b/src/apps/companies/apps/exports/__test__/controller.test.js deleted file mode 100644 index 96baca271f4..00000000000 --- a/src/apps/companies/apps/exports/__test__/controller.test.js +++ /dev/null @@ -1,38 +0,0 @@ -const buildMiddlewareParameters = require('../../../../../../test/unit/helpers/middleware-parameters-builder') - -const companyMock = require('../../../../../../test/unit/data/companies/company-v4.json') - -describe('Company export controller', () => { - let middlewareParameters - let controller - - beforeEach(() => { - controller = require('../controllers') - }) - - describe('#renderExports', () => { - beforeEach(() => { - middlewareParameters = buildMiddlewareParameters({ - company: companyMock, - }) - - controller.renderExports( - middlewareParameters.reqMock, - middlewareParameters.resMock - ) - }) - - it('should render the correct view', () => { - expect(middlewareParameters.resMock.render.args[0][0]).to.equal( - 'companies/apps/exports/views/index' - ) - expect(middlewareParameters.resMock.render).to.have.been.calledOnce - }) - - it('should exports to view', () => { - expect(middlewareParameters.resMock.render.args[0][1]).to.have.property( - 'props' - ) - }) - }) -}) diff --git a/src/apps/companies/apps/exports/client/ExportsHistory/index.jsx b/src/apps/companies/apps/exports/client/ExportsHistory/index.jsx deleted file mode 100644 index 93cfbe14df7..00000000000 --- a/src/apps/companies/apps/exports/client/ExportsHistory/index.jsx +++ /dev/null @@ -1,91 +0,0 @@ -import React from 'react' -import styled from 'styled-components' -import Details from '@govuk-react/details' -import { H2 } from '@govuk-react/heading' -import { SPACING, LEVEL_SIZE } from '@govuk-react/constants' -import InsetText from '@govuk-react/inset-text' -import { connect } from 'react-redux' - -import { CollectionList, Metadata } from '../../../../../../client/components/' -import { state2props } from './state' -import { - EXPORTS_HISTORY__LOADED, - EXPORTS_HISTORY__SELECT_PAGE, -} from '../../../../../../client/actions' -import { CompanyResource } from '../../../../../../client/components/Resource' -import CompanyLayout from '../../../../../../client/components/Layout/CompanyLayout' -import urls from '../../../../../../lib/urls' - -const StyledDetails = styled(Details)` - margin: ${SPACING.SCALE_3} 0 0 0; -` - -const metadataRenderer = (metadata) => { - return metadata && metadata.length > 4 ? ( - - - - ) : ( - - ) -} - -function ExportsHistory({ - count, - results, - onPageClick, - activePage, - companyId, - countryId, - pageTitle, - isComplete, - returnUrl, -}) { - const collectionListTask = { - name: 'Exports history', - id: 'exportsHistory', - progressMessage: 'loading Exports History', - startOnRender: { - payload: { companyId, countryId, activePage }, - onSuccessDispatch: EXPORTS_HISTORY__LOADED, - }, - } - return ( - - {(company) => ( - - - You can only see the history of countries that were added or edited - after 6th February 2020 - -

{pageTitle}

- -
- )} -
- ) -} - -export default connect(state2props, (dispatch) => ({ - onPageClick: (page) => { - dispatch({ - type: EXPORTS_HISTORY__SELECT_PAGE, - page, - }) - }, -}))(ExportsHistory) diff --git a/src/apps/companies/apps/exports/client/ExportsIndex.jsx b/src/apps/companies/apps/exports/client/ExportsIndex.jsx deleted file mode 100644 index a3b88a9b43e..00000000000 --- a/src/apps/companies/apps/exports/client/ExportsIndex.jsx +++ /dev/null @@ -1,192 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import styled from 'styled-components' -import Details from '@govuk-react/details' -import Link from '@govuk-react/link' -import { H3 } from '@govuk-react/heading' -import { SPACING } from '@govuk-react/constants' -import WarningText from '@govuk-react/warning-text' - -import { SummaryTable } from '../../../../../client/components/' -import urls from '../../../../../lib/urls' -import ExportWins from './ExportWins/' -import GreatProfile from './GreatProfile' -import { CompanyResource } from '../../../../../client/components/Resource' -import CompanyLayout from '../../../../../client/components/Layout/CompanyLayout' -import { exportDetailsLabels, exportPotentialLabels } from '../../../labels' -import { transformExportCountries } from '../transformer' - -const StyledSummaryTable = styled(SummaryTable)` - margin-top: 0; -` - -const StyledLink = styled(Link)` - display: inline-block; - margin-bottom: ${SPACING.SCALE_5}; -` - -const ExportsIndex = ({ companyId, returnUrl }) => { - return ( - - {(company) => ( - - - Edit - - ) - } - > - - {company.exportExperienceCategory - ? company.exportExperienceCategory.name - : 'None'} - - - - - - Unavailable - - - - - The export potential value is unavailable. This is because the - previous values were out of date. We are working to fix this. - - -
- The export potential score is a prediction of a company's likelihood - of exporting, and was originally created for the{' '} - - Find Exporters tool - - . DBT's data science team compared all HMRC export information with - the features of all UK companies to find patterns; they then - repeatedly tested their model against a subset of known-good data to - improve it. The scores are as follows: -
    - {Object.values(exportPotentialLabels).map((category, index) => ( -
  1. - {category.text} - {category.description} -
  2. - ))} -
-
- We are continuing to improve the algorithm so please do share your - feedback or let us know of any anomalies through the{' '} - support channel. -
- - - Edit - - ) - } - > - {transformExportCountries(company.exportCountries).map( - ({ name, values }) => ( - - <> - {values?.length - ? values.map(({ id, name }, i) => { - const isLastItem = i === values.length - 1 - return ( - - - {name} - - {isLastItem ? null : ', '} - - ) - }) - : 'None'} - - - ) - )} - - - - View full export countries history - - -

Export wins

-

- - Record your win - {' '} - on our Export Wins site -

-
-

- Export wins capture the export deals that Department for Business - and Trade (DBT) support and quantify their expected export value. - If applicable, they also quantify the non-export and outward - direct investment (ODI) value, up to a 5-year period. They give a - picture of DBT support for business. -

-

- The export win metric is currently the only way the department - measures export activity. -

-
- -
- )} -
- ) -} - -ExportsIndex.propTypes = { - companyId: PropTypes.string.isRequired, -} - -export default ExportsIndex diff --git a/src/apps/companies/apps/exports/controllers.js b/src/apps/companies/apps/exports/controllers.js deleted file mode 100644 index 38b18e8d344..00000000000 --- a/src/apps/companies/apps/exports/controllers.js +++ /dev/null @@ -1,46 +0,0 @@ -const metadataRepo = require('../../../../lib/metadata') - -function getCountry(id) { - return metadataRepo.countryOptions.find((country) => country.id === id) -} - -function renderExports(req, res) { - const { company, returnUrl, dnbRelatedCompaniesCount } = res.locals - - res.locals.title = `Export - ${company.name} - Companies` - - res.render('companies/apps/exports/views/index', { - props: { - companyId: company.id, - localNavItems: res.locals.localNavItems, - returnUrl, - dnbRelatedCompaniesCount, - }, - }) -} - -function renderExportHistory(req, res) { - const { company, dnbRelatedCompaniesCount, returnUrl } = res.locals - - const { countryId } = req.params - - const pageTitle = countryId - ? `${getCountry(countryId).name} exports history` - : 'Export countries history' - - res.render('companies/apps/exports/views/full-history', { - props: { - companyId: company.id, - pageTitle, - countryId, - returnUrl, - dnbRelatedCompaniesCount, - localNavItems: res.locals.localNavItems, - }, - }) -} - -module.exports = { - renderExports, - renderExportHistory, -} diff --git a/src/apps/companies/apps/exports/router.js b/src/apps/companies/apps/exports/router.js deleted file mode 100644 index bea36408da8..00000000000 --- a/src/apps/companies/apps/exports/router.js +++ /dev/null @@ -1,21 +0,0 @@ -const router = require('express').Router() - -const urls = require('../../../../lib/urls') -const setReturnUrl = require('../../middleware/set-return-url') - -const { renderExports, renderExportHistory } = require('./controllers') - -router.get(urls.companies.exports.index.route, setReturnUrl, renderExports) - -router.get( - urls.companies.exports.history.index.route, - setReturnUrl, - renderExportHistory -) -router.get( - urls.companies.exports.history.country.route, - setReturnUrl, - renderExportHistory -) - -module.exports = router diff --git a/src/apps/companies/apps/exports/transformer.js b/src/apps/companies/apps/exports/transformer.js deleted file mode 100644 index c6eb8e1470f..00000000000 --- a/src/apps/companies/apps/exports/transformer.js +++ /dev/null @@ -1,39 +0,0 @@ -/* eslint-disable camelcase */ -const groupExportCountries = require('../../../../lib/group-export-countries') -const { exportDetailsLabels } = require('../../labels') -const { EXPORT_INTEREST_STATUS } = require('../../../../common/constants') - -function getCountriesFields(companyExportCountries) { - const groupedExportCountries = groupExportCountries(companyExportCountries) - - return { - exportToCountries: - groupedExportCountries[EXPORT_INTEREST_STATUS.EXPORTING_TO], - futureInterestCountries: - groupedExportCountries[EXPORT_INTEREST_STATUS.FUTURE_INTEREST], - noInterestCountries: - groupedExportCountries[EXPORT_INTEREST_STATUS.NOT_INTERESTED], - } -} - -module.exports = { - transformExportCountries: (companyExportCountries) => { - const { exportToCountries, futureInterestCountries, noInterestCountries } = - getCountriesFields(companyExportCountries) - - return [ - { - name: exportDetailsLabels.exportToCountries, - values: exportToCountries, - }, - { - name: exportDetailsLabels.futureInterestCountries, - values: futureInterestCountries, - }, - { - name: exportDetailsLabels.noInterestCountries, - values: noInterestCountries, - }, - ] - }, -} diff --git a/src/apps/companies/apps/exports/views/full-history.njk b/src/apps/companies/apps/exports/views/full-history.njk deleted file mode 100644 index 7914d1ef8e3..00000000000 --- a/src/apps/companies/apps/exports/views/full-history.njk +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "_layouts/template-no-local-header.njk" %} - -{% block body %} - -
- {% component 'react-slot', { - id: 'company-export-full-history', - props: props - } - %} -
- -{% endblock %} diff --git a/src/apps/companies/apps/exports/views/index.njk b/src/apps/companies/apps/exports/views/index.njk deleted file mode 100644 index 6f6cd35c697..00000000000 --- a/src/apps/companies/apps/exports/views/index.njk +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "_layouts/template-no-local-header.njk" %} - -{% block body %} - -
- {% component 'react-slot', { - id: 'company-export-index-page', - props: props - } - %} -
- -{% endblock %} diff --git a/src/apps/companies/labels.js b/src/apps/companies/labels.js index 1ae0e12a5b9..666a839a984 100644 --- a/src/apps/companies/labels.js +++ b/src/apps/companies/labels.js @@ -52,15 +52,6 @@ const accountManagementDisplayLabels = { one_list_group_global_account_manager: 'Global Account Manager', } -const exportDetailsLabels = { - exportExperienceCategory: 'Export win category', - exportToCountries: 'Currently exporting to', - futureInterestCountries: 'Future countries of interest', - noInterestCountries: 'Countries of no interest', - greatProfile: 'great.gov.uk business profile', - exportPotential: 'Export potential', -} - const aboutLabels = { business_type: 'Business type', trading_names: 'Trading names', @@ -79,38 +70,12 @@ const businessHierarchyLabels = { global_headquarters: 'Global HQ', } -const exportPotentialLabels = { - very_high: { - text: 'Very High', - description: 'Most companies like this one are exporters', - }, - high: { - text: 'High', - description: 'This business shares some features with successful exporters', - }, - medium: { - text: 'Medium', - description: "Some businesses that look like this one export, others don't", - }, - low: { - text: 'Low', - description: - 'This business shares many features with companies that do not export', - }, - very_low: { - text: 'Very Low', - description: "Most of the businesses like this aren't exporters", - }, -} - module.exports = { companyDetailsLabels, companyTypeOptions, hqLabels, accountManagementDisplayLabels, - exportDetailsLabels, address, aboutLabels, businessHierarchyLabels, - exportPotentialLabels, } diff --git a/src/apps/companies/router.js b/src/apps/companies/router.js index 423966f97cb..cd3e51a17c8 100644 --- a/src/apps/companies/router.js +++ b/src/apps/companies/router.js @@ -36,7 +36,6 @@ const activityFeedRouter = require('./apps/activity-feed/router') const dnbHierarchyRouter = require('./apps/dnb-hierarchy/router') const editHistoryRouter = require('./apps/edit-history/router') const matchCompanyRouter = require('./apps/match-company/router') -const exportsRouter = require('./apps/exports/router') const interactionsRouter = require('../interactions/router.sub-app') const companyListsRouter = require('../company-lists/router') const referralsRouter = require('./apps/referrals/router') @@ -93,7 +92,6 @@ router.get(urls.companies.subsidiaries.index.route, renderSubsidiaries) router.use(activityFeedRouter) router.use(dnbHierarchyRouter) router.use(matchCompanyRouter) -router.use(exportsRouter) router.use(referralsRouter) router.use(accountManagementRouter) diff --git a/src/apps/routers.js b/src/apps/routers.js index 3de2d849391..7450f6f4a86 100644 --- a/src/apps/routers.js +++ b/src/apps/routers.js @@ -120,6 +120,9 @@ const reactRoutes = [ '/companies/:companyId/investments', '/companies/:companyId/investments/projects', '/companies/:companyId/investments/large-capital-profile', + '/companies/:companyId/exports', + '/companies/:companyId/exports/history', + '/companies/:companyId/exports/history/:countryId', ] reactRoutes.forEach((path) => { diff --git a/src/client/index.jsx b/src/client/index.jsx index 924ecf187a3..58932ab0d6e 100644 --- a/src/client/index.jsx +++ b/src/client/index.jsx @@ -20,8 +20,6 @@ import CannotFindMatch from '../apps/companies/apps/match-company/client/CannotF import EditCompanyList from '../apps/company-lists/client/EditCompanyList' import CreateListForm from '../apps/company-lists/client/CreateListForm' import ManageAdviser from '../apps/companies/apps/advisers/client/ManageAdviser' -import ExportsIndex from '../apps/companies/apps/exports/client/ExportsIndex' -import ExportsHistory from '../apps/companies/apps/exports/client/ExportsHistory/' import ReferralDetails from '../apps/companies/apps/referrals/details/client/ReferralDetails' import SendReferralForm from '../apps/companies/apps/referrals/send-referral/client/SendReferralForm' import InteractionReferralDetails from './modules/Interactions/InteractionDetails/InteractionReferralDetails.jsx' @@ -181,17 +179,11 @@ function App() { )} - - {(props) => } - {(props) => ( )} - - {(props) => } - {(props) => } diff --git a/src/client/modules/Companies/CollectionList/labels.js b/src/client/modules/Companies/CollectionList/labels.js index fe6baf37bcd..3b01c5e24b0 100644 --- a/src/client/modules/Companies/CollectionList/labels.js +++ b/src/client/modules/Companies/CollectionList/labels.js @@ -52,15 +52,6 @@ const accountManagementDisplayLabels = { one_list_group_global_account_manager: 'Global Account Manager', } -const exportDetailsLabels = { - exportExperienceCategory: 'Export win category', - exportToCountries: 'Currently exporting to', - futureInterestCountries: 'Future countries of interest', - noInterestCountries: 'Countries of no interest', - greatProfile: 'great.gov.uk business profile', - exportPotential: 'Export potential', -} - const coreTeamLabels = { region: 'Region', country: 'Country', @@ -88,39 +79,13 @@ const businessHierarchyLabels = { global_headquarters: 'Global HQ', } -const exportPotentialLabels = { - very_high: { - text: 'Very High', - description: 'Most companies like this one are exporters', - }, - high: { - text: 'High', - description: 'This business shares some features with successful exporters', - }, - medium: { - text: 'Medium', - description: "Some businesses that look like this one export, others don't", - }, - low: { - text: 'Low', - description: - 'This business shares many features with companies that do not export', - }, - very_low: { - text: 'Very Low', - description: "Most of the businesses like this aren't exporters", - }, -} - export default { companyDetailsLabels, companyTypeOptions, hqLabels, accountManagementDisplayLabels, - exportDetailsLabels, address, coreTeamLabels, aboutLabels, businessHierarchyLabels, - exportPotentialLabels, } diff --git a/src/client/modules/Companies/CompanyExports/ExportCountriesEdit/index.jsx b/src/client/modules/Companies/CompanyExports/ExportCountriesEdit/index.jsx index 66962330e4f..681c524ef98 100644 --- a/src/client/modules/Companies/CompanyExports/ExportCountriesEdit/index.jsx +++ b/src/client/modules/Companies/CompanyExports/ExportCountriesEdit/index.jsx @@ -4,12 +4,12 @@ import { useParams } from 'react-router-dom' import { ERROR_COLOUR } from '../../../../utils/colours' import Task from '../../../../components/Task' -import Form from '../../../../components/Form' import { ID as TASK_ID, TASK_NAME, API_ERROR, API_WARN } from './state' import urls from '../../../../../lib/urls' import { StatusMessage, FieldTypeahead, + Form, FormLayout, DefaultLayout, } from '../../../../components' diff --git a/src/apps/companies/apps/exports/client/group-history-items.js b/src/client/modules/Companies/CompanyExports/ExportHistory/group-history-items.js similarity index 100% rename from src/apps/companies/apps/exports/client/group-history-items.js rename to src/client/modules/Companies/CompanyExports/ExportHistory/group-history-items.js diff --git a/src/client/modules/Companies/CompanyExports/ExportHistory/index.jsx b/src/client/modules/Companies/CompanyExports/ExportHistory/index.jsx new file mode 100644 index 00000000000..4375fae4578 --- /dev/null +++ b/src/client/modules/Companies/CompanyExports/ExportHistory/index.jsx @@ -0,0 +1,115 @@ +import React from 'react' +import styled from 'styled-components' +import Details from '@govuk-react/details' +import { H2 } from '@govuk-react/heading' +import { SPACING, LEVEL_SIZE } from '@govuk-react/constants' +import InsetText from '@govuk-react/inset-text' +import { connect } from 'react-redux' +import { useParams } from 'react-router-dom' + +import { CollectionList, Metadata } from '../../../../components' +import { state2props } from './state' +import { + EXPORTS_HISTORY__LOADED, + EXPORTS_HISTORY__SELECT_PAGE, +} from '../../../../actions' +import { + CompanyResource, + CountriesResource, +} from '../../../../components/Resource' +import CompanyLayout from '../../../../components/Layout/CompanyLayout' +import urls from '../../../../../lib/urls' +import DefaultLayoutBase from '../../../../components/Layout/DefaultLayoutBase' +import { listSkeletonPlaceholder } from '../../../../components/SkeletonPlaceholder' + +const StyledDetails = styled(Details)` + margin: ${SPACING.SCALE_3} 0 0 0; +` + +const metadataRenderer = (metadata) => { + return metadata && metadata.length > 4 ? ( + + + + ) : ( + + ) +} + +const getCountry = (id) => ( + + {(countries) => { + const country = countries.find((country) => country.id === id) + return `${country.name} exports history` + }} + +) + +const ExportsHistory = ({ + count, + results, + onPageClick, + activePage, + isComplete, +}) => { + const { companyId, countryId } = useParams() + + const collectionListTask = { + name: 'Exports history', + id: 'exportsHistory', + progressMessage: 'loading Exports History', + renderProgress: listSkeletonPlaceholder(), + startOnRender: { + payload: { companyId, countryId, activePage }, + onSuccessDispatch: EXPORTS_HISTORY__LOADED, + }, + } + + const countryName = countryId + ? getCountry(countryId) + : 'Export countries history' + + return ( + + + {(company) => ( + + + You can only see the history of countries that were added or + edited after 6th February 2020 + +

{countryName}

+ +
+ )} +
+
+ ) +} + +export default connect(state2props, (dispatch) => ({ + onPageClick: (page) => { + dispatch({ + type: EXPORTS_HISTORY__SELECT_PAGE, + page, + }) + }, +}))(ExportsHistory) diff --git a/src/apps/companies/apps/exports/client/ExportsHistory/reducer.js b/src/client/modules/Companies/CompanyExports/ExportHistory/reducer.js similarity index 92% rename from src/apps/companies/apps/exports/client/ExportsHistory/reducer.js rename to src/client/modules/Companies/CompanyExports/ExportHistory/reducer.js index 5068b456831..e74480683c7 100644 --- a/src/apps/companies/apps/exports/client/ExportsHistory/reducer.js +++ b/src/client/modules/Companies/CompanyExports/ExportHistory/reducer.js @@ -1,7 +1,7 @@ import { EXPORTS_HISTORY__LOADED, EXPORTS_HISTORY__SELECT_PAGE, -} from '../../../../../../client/actions' +} from '../../../../actions' const initialState = { count: 0, diff --git a/src/apps/companies/apps/exports/client/ExportsHistory/state.js b/src/client/modules/Companies/CompanyExports/ExportHistory/state.js similarity index 100% rename from src/apps/companies/apps/exports/client/ExportsHistory/state.js rename to src/client/modules/Companies/CompanyExports/ExportHistory/state.js diff --git a/src/apps/companies/apps/exports/client/ExportsHistory/tasks.js b/src/client/modules/Companies/CompanyExports/ExportHistory/tasks.js similarity index 88% rename from src/apps/companies/apps/exports/client/ExportsHistory/tasks.js rename to src/client/modules/Companies/CompanyExports/ExportHistory/tasks.js index 5dc97fa0a44..36f58748f99 100644 --- a/src/apps/companies/apps/exports/client/ExportsHistory/tasks.js +++ b/src/client/modules/Companies/CompanyExports/ExportHistory/tasks.js @@ -1,13 +1,13 @@ -import { formatMediumDateTime } from '../../../../../../client/utils/date' -import { GREEN } from '../../../../../../client/utils/colours' -import urls from '../../../../../../lib/urls' -import groupExportCountries from '../../../../../../lib/group-export-countries' +import { formatMediumDateTime } from '../../../../utils/date' +import { GREEN } from '../../../../utils/colours' +import urls from '../../../../../lib/urls' +import groupExportCountries from '../../../../../lib/group-export-countries' import { EXPORT_INTEREST_STATUS, EXPORT_INTEREST_STATUS_VALUES, -} from '../../../../../../common/constants' -import { groupHistoryItems } from '../group-history-items' -import { apiProxyAxios } from '../../../../../../client/components/Task/utils' +} from '../../../../../common/constants' +import { groupHistoryItems } from './group-history-items' +import { apiProxyAxios } from '../../../../components/Task/utils' const ALLOWLISTED_HISTORY_TYPES = ['insert', 'delete', 'update'] diff --git a/src/apps/companies/apps/exports/client/ExportWins/index.jsx b/src/client/modules/Companies/CompanyExports/ExportWins/index.jsx similarity index 85% rename from src/apps/companies/apps/exports/client/ExportWins/index.jsx rename to src/client/modules/Companies/CompanyExports/ExportWins/index.jsx index b12c5dabc5c..d78bdd354e1 100644 --- a/src/apps/companies/apps/exports/client/ExportWins/index.jsx +++ b/src/client/modules/Companies/CompanyExports/ExportWins/index.jsx @@ -3,12 +3,13 @@ import styled from 'styled-components' import { SPACING } from '@govuk-react/constants' import { connect } from 'react-redux' -import { CollectionList } from '../../../../../../client/components/' +import { CollectionList } from '../../../../components' import { state2props, NOT_IMPLEMENTED } from './state' +import { listSkeletonPlaceholder } from '../../../../components/SkeletonPlaceholder' import { EXPORT_WINS__LOADED, EXPORT_WINS__SELECT_PAGE, -} from '../../../../../../client/actions' +} from '../../../../actions' const Wrapper = styled('div')` margin-top: ${SPACING.SCALE_3}; @@ -33,6 +34,7 @@ function ExportWins(state) { name: 'Export wins', id: 'exportWins', progressMessage: 'Loading Exports Wins...', + renderProgress: listSkeletonPlaceholder(), startOnRender: { payload: { companyId, companyName, activePage }, onSuccessDispatch: EXPORT_WINS__LOADED, diff --git a/src/apps/companies/apps/exports/client/ExportWins/reducer.js b/src/client/modules/Companies/CompanyExports/ExportWins/reducer.js similarity index 94% rename from src/apps/companies/apps/exports/client/ExportWins/reducer.js rename to src/client/modules/Companies/CompanyExports/ExportWins/reducer.js index 35e8a024eea..18480348b00 100644 --- a/src/apps/companies/apps/exports/client/ExportWins/reducer.js +++ b/src/client/modules/Companies/CompanyExports/ExportWins/reducer.js @@ -1,7 +1,7 @@ import { EXPORT_WINS__LOADED, EXPORT_WINS__SELECT_PAGE, -} from '../../../../../../client/actions' +} from '../../../../actions' import { NOT_IMPLEMENTED } from './state' diff --git a/src/apps/companies/apps/exports/client/ExportWins/state.js b/src/client/modules/Companies/CompanyExports/ExportWins/state.js similarity index 100% rename from src/apps/companies/apps/exports/client/ExportWins/state.js rename to src/client/modules/Companies/CompanyExports/ExportWins/state.js diff --git a/src/apps/companies/apps/exports/client/ExportWins/tasks.js b/src/client/modules/Companies/CompanyExports/ExportWins/tasks.js similarity index 91% rename from src/apps/companies/apps/exports/client/ExportWins/tasks.js rename to src/client/modules/Companies/CompanyExports/ExportWins/tasks.js index 83762463a64..de3e83075cb 100644 --- a/src/apps/companies/apps/exports/client/ExportWins/tasks.js +++ b/src/client/modules/Companies/CompanyExports/ExportWins/tasks.js @@ -1,11 +1,11 @@ import axios from 'axios' -import { currencyGBP } from '../../../../../../client/utils/number-utils' -import { GREEN, BLUE } from '../../../../../../client/utils/colours' +import { currencyGBP } from '../../../../utils/number-utils' +import { GREEN, BLUE } from '../../../../utils/colours' import { NOT_IMPLEMENTED } from './state' -const { format } = require('../../../../../../client/utils/date') +const { format } = require('../../../../utils/date') function getBadges(win) { const badges = [] diff --git a/src/client/modules/Companies/CompanyExports/ExportsEdit.jsx b/src/client/modules/Companies/CompanyExports/ExportsEdit.jsx index 915f1586c89..72d8ba57dc4 100644 --- a/src/client/modules/Companies/CompanyExports/ExportsEdit.jsx +++ b/src/client/modules/Companies/CompanyExports/ExportsEdit.jsx @@ -3,16 +3,20 @@ import styled from 'styled-components' import { useParams } from 'react-router-dom' import { SPACING_POINTS } from '@govuk-react/constants' -import { DefaultLayout, FieldInput, FieldSelect } from '../../../components' -import GreatProfile from '../../../../apps/companies/apps/exports/client/GreatProfile' +import { + DefaultLayout, + FieldInput, + FieldSelect, + Form, +} from '../../../components' +import GreatProfile from './GreatProfile' import urls from '../../../../lib/urls' -import Form from '../../../components/Form' import { CompanyResource, ExportExperienceCategoriesResource, } from '../../../components/Resource' import { transformArrayIdNameToValueLabel } from '../../../transformers' -import { exportDetailsLabels } from '../../../../apps/companies/labels' +import { exportDetailsLabels } from './labels' import { buildCompanyBreadcrumbs } from '../utils' const StyledDt = styled.dt` diff --git a/src/client/modules/Companies/CompanyExports/ExportsIndex.jsx b/src/client/modules/Companies/CompanyExports/ExportsIndex.jsx new file mode 100644 index 00000000000..7982f19376c --- /dev/null +++ b/src/client/modules/Companies/CompanyExports/ExportsIndex.jsx @@ -0,0 +1,185 @@ +import React from 'react' +import styled from 'styled-components' +import Details from '@govuk-react/details' +import Link from '@govuk-react/link' +import { H3 } from '@govuk-react/heading' +import { SPACING } from '@govuk-react/constants' +import WarningText from '@govuk-react/warning-text' +import { useParams } from 'react-router-dom' + +import { SummaryTable } from '../../../components' +import urls from '../../../../lib/urls' +import ExportWins from './ExportWins' +import GreatProfile from './GreatProfile' +import { CompanyResource } from '../../../components/Resource' +import CompanyLayout from '../../../components/Layout/CompanyLayout' +import { exportDetailsLabels, exportPotentialLabels } from './labels' +import { transformExportCountries } from './transformers' +import DefaultLayoutBase from '../../../components/Layout/DefaultLayoutBase' + +const StyledSummaryTable = styled(SummaryTable)` + margin-top: 0; +` + +const StyledLink = styled(Link)` + display: inline-block; + margin-bottom: ${SPACING.SCALE_5}; +` + +const ExportsIndex = () => { + const { companyId } = useParams() + return ( + + + {(company) => ( + + + Edit + + ) + } + > + + {company.exportExperienceCategory + ? company.exportExperienceCategory.name + : 'None'} + + + + + + Unavailable + + + + + The export potential value is unavailable. This is because the + previous values were out of date. We are working to fix this. + + +
+ The export potential score is a prediction of a company's + likelihood of exporting, and was originally created for the{' '} + + Find Exporters tool + + . DBT's data science team compared all HMRC export information + with the features of all UK companies to find patterns; they then + 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. + {category.text} - {category.description} +
  2. + ))} +
+
+ We are continuing to improve the algorithm so please do share your + feedback or let us know of any anomalies through the{' '} + support channel. +
+ + + Edit + + ) + } + > + {transformExportCountries(company.exportCountries).map( + ({ name, values }) => ( + + <> + {values?.length + ? values.map(({ id, name }, i) => { + const isLastItem = i === values.length - 1 + return ( + + + {name} + + {isLastItem ? null : ', '} + + ) + }) + : 'None'} + + + ) + )} + + + + View full export countries history + + +

Export wins

+

+ + Record your win + {' '} + on our Export Wins site +

+
+

+ Export wins capture the export deals that Department for + Business and Trade (DBT) support and quantify their expected + export value. If applicable, they also quantify the non-export + and outward direct investment (ODI) value, up to a 5-year + period. They give a picture of DBT support for business. +

+

+ The export win metric is currently the only way the department + measures export activity. +

+
+ +
+ )} +
+
+ ) +} + +export default ExportsIndex diff --git a/src/apps/companies/apps/exports/client/GreatProfile.jsx b/src/client/modules/Companies/CompanyExports/GreatProfile.jsx similarity index 75% rename from src/apps/companies/apps/exports/client/GreatProfile.jsx rename to src/client/modules/Companies/CompanyExports/GreatProfile.jsx index d0794a9a808..1c4c710c330 100644 --- a/src/apps/companies/apps/exports/client/GreatProfile.jsx +++ b/src/client/modules/Companies/CompanyExports/GreatProfile.jsx @@ -1,7 +1,7 @@ import React from 'react' -import urls from '../../../../../lib/urls' -import { NewWindowLink } from '../../../../../client/components/' +import urls from '../../../../lib/urls' +import { NewWindowLink } from '../../../components' export default ({ profileStatus, companyNumber }) => profileStatus === 'published' ? ( diff --git a/src/client/modules/Companies/CompanyExports/labels.js b/src/client/modules/Companies/CompanyExports/labels.js new file mode 100644 index 00000000000..a2c86669fa4 --- /dev/null +++ b/src/client/modules/Companies/CompanyExports/labels.js @@ -0,0 +1,32 @@ +export const exportDetailsLabels = { + exportExperienceCategory: 'Export win category', + exportToCountries: 'Currently exporting to', + futureInterestCountries: 'Future countries of interest', + noInterestCountries: 'Countries of no interest', + greatProfile: 'great.gov.uk business profile', + exportPotential: 'Export potential', +} + +export const exportPotentialLabels = { + very_high: { + text: 'Very High', + description: 'Most companies like this one are exporters', + }, + high: { + text: 'High', + description: 'This business shares some features with successful exporters', + }, + medium: { + text: 'Medium', + description: "Some businesses that look like this one export, others don't", + }, + low: { + text: 'Low', + description: + 'This business shares many features with companies that do not export', + }, + very_low: { + text: 'Very Low', + description: "Most of the businesses like this aren't exporters", + }, +} diff --git a/src/apps/companies/apps/exports/client/tasks.js b/src/client/modules/Companies/CompanyExports/tasks.js similarity index 77% rename from src/apps/companies/apps/exports/client/tasks.js rename to src/client/modules/Companies/CompanyExports/tasks.js index 0847d4ee4bd..e313f8b9f56 100644 --- a/src/apps/companies/apps/exports/client/tasks.js +++ b/src/client/modules/Companies/CompanyExports/tasks.js @@ -1,4 +1,4 @@ -import { apiProxyAxios } from '../../../../../client/components/Task/utils' +import { apiProxyAxios } from '../../../components/Task/utils' export const saveWinCategory = ({ companyId, export_experience_category }) => { return apiProxyAxios diff --git a/src/client/modules/Companies/CompanyExports/transformers.js b/src/client/modules/Companies/CompanyExports/transformers.js index 8ffa9cdc851..58788d6ec9b 100644 --- a/src/client/modules/Companies/CompanyExports/transformers.js +++ b/src/client/modules/Companies/CompanyExports/transformers.js @@ -1,7 +1,4 @@ -import { - exportDetailsLabels, - exportPotentialLabels, -} from '../../../../apps/companies/labels' +import { exportDetailsLabels, exportPotentialLabels } from './labels' import groupExportCountries from '../../../../lib/group-export-countries' import { EXPORT_INTEREST_STATUS } from '../../../../common/constants' import { transformArrayIdNameToValueLabel } from '../../../transformers' @@ -39,3 +36,36 @@ export const transformCountriesForTypeahead = (exportCountries) => { }, ] } + +const getCountriesFields = (companyExportCountries) => { + const groupedExportCountries = groupExportCountries(companyExportCountries) + + return { + exportToCountries: + groupedExportCountries[EXPORT_INTEREST_STATUS.EXPORTING_TO], + futureInterestCountries: + groupedExportCountries[EXPORT_INTEREST_STATUS.FUTURE_INTEREST], + noInterestCountries: + groupedExportCountries[EXPORT_INTEREST_STATUS.NOT_INTERESTED], + } +} + +export const transformExportCountries = (companyExportCountries) => { + const { exportToCountries, futureInterestCountries, noInterestCountries } = + getCountriesFields(companyExportCountries) + + return [ + { + name: exportDetailsLabels.exportToCountries, + values: exportToCountries, + }, + { + name: exportDetailsLabels.futureInterestCountries, + values: futureInterestCountries, + }, + { + name: exportDetailsLabels.noInterestCountries, + values: noInterestCountries, + }, + ] +} diff --git a/src/client/modules/Companies/CompanyOverview/TableCards/ExportStatusCard.jsx b/src/client/modules/Companies/CompanyOverview/TableCards/ExportStatusCard.jsx index cb2286d3eda..f55a83fcaf8 100644 --- a/src/client/modules/Companies/CompanyOverview/TableCards/ExportStatusCard.jsx +++ b/src/client/modules/Companies/CompanyOverview/TableCards/ExportStatusCard.jsx @@ -14,7 +14,7 @@ import { } from './state' import { OVERVIEW__EXPORT_WINS_SUMMARY } from '../../../../actions' import { format } from '../../../../utils/date' -import { transformExportCountries } from '../../../../../apps/companies/apps/exports/transformer' +import { transformExportCountries } from '../../CompanyExports/transformers' import { companies } from '../../../../../lib/urls' import { buildCellContents } from './transformers' import { diff --git a/src/client/modules/Companies/CompanyOverview/TableCards/tasks.js b/src/client/modules/Companies/CompanyOverview/TableCards/tasks.js index 1f366da3d18..d1b602d3b47 100644 --- a/src/client/modules/Companies/CompanyOverview/TableCards/tasks.js +++ b/src/client/modules/Companies/CompanyOverview/TableCards/tasks.js @@ -1,7 +1,7 @@ import axios from 'axios' import { apiProxyAxios } from '../../../../components/Task/utils' -import { NOT_IMPLEMENTED } from '../../../../../apps/companies/apps/exports/client/ExportWins/state' +import { NOT_IMPLEMENTED } from '../../CompanyExports/ExportWins/state' export const getProjectsWon = async ({ companyId }) => { return await apiProxyAxios diff --git a/src/client/reducers.js b/src/client/reducers.js index c24425e0ffa..67881741e4e 100644 --- a/src/client/reducers.js +++ b/src/client/reducers.js @@ -10,8 +10,8 @@ import referralsReducer from '../apps/companies/apps/referrals/details/client/re import { ID as REFERRALS_SEND_ID } from '../apps/companies/apps/referrals/send-referral/client/state' import referralsSendReducer from '../apps/companies/apps/referrals/send-referral/client/reducer' -import { ID as EXPORTS_HISTORY_ID } from '../apps/companies/apps/exports/client/ExportsHistory/state' -import exportsHistoryReducer from '../apps/companies/apps/exports/client/ExportsHistory/reducer' +import { ID as EXPORTS_HISTORY_ID } from './modules/Companies/CompanyExports/ExportHistory/state.js' +import exportsHistoryReducer from './modules/Companies/CompanyExports/ExportHistory/reducer.js' import TabNav from './components/TabNav' @@ -23,8 +23,8 @@ import Typeahead from './components/Typeahead/Typeahead' import FieldAddAnother from './components/Form/elements/FieldAddAnother/FieldAddAnother' -import { ID as EXPORTS_WINS_ID } from '../apps/companies/apps/exports/client/ExportWins/state' -import exportWinsReducer from '../apps/companies/apps/exports/client/ExportWins/reducer' +import { ID as EXPORTS_WINS_ID } from './modules/Companies/CompanyExports/ExportWins/state.js' +import exportWinsReducer from './modules/Companies/CompanyExports/ExportWins/reducer.js' import * as addCompanyState from '../apps/companies/apps/add-company/client/state' import addCompanyPostcodeToRegionReducer from '../apps/companies/apps/add-company/client/reducer' diff --git a/src/client/routes.js b/src/client/routes.js index fe85a6515aa..d62954585f6 100644 --- a/src/client/routes.js +++ b/src/client/routes.js @@ -91,6 +91,8 @@ import CompanyOrdersCollection from './modules/Omis/CollectionList/CompanyOrders import AccountManagement from './modules/Companies/AccountManagement' import CompanyProjectsCollection from './modules/Companies/CompanyInvestments/CompanyProjectsCollection' import LargeCapitalProfile from './modules/Companies/CompanyInvestments/LargeCapitalProfile' +import ExportsIndex from './modules/Companies/CompanyExports/ExportsIndex' +import ExportsHistory from './modules/Companies/CompanyExports/ExportHistory' const routes = { companies: [ @@ -229,6 +231,21 @@ const routes = { module: 'datahub:companies', component: LargeCapitalProfile, }, + { + path: '/companies/:companyId/exports', + module: 'datahub:companies', + component: ExportsIndex, + }, + { + path: '/companies/:companyId/exports/history', + module: 'datahub:companies', + component: ExportsHistory, + }, + { + path: '/companies/:companyId/exports/history/:countryId', + module: 'datahub:companies', + component: ExportsHistory, + }, ], contacts: [ { diff --git a/src/client/tasks.js b/src/client/tasks.js index 2d3d287ecbe..62276fca1e0 100644 --- a/src/client/tasks.js +++ b/src/client/tasks.js @@ -1,10 +1,10 @@ import * as companyListsTasks from './components/CompanyLists/tasks' import * as referralTasks from '../apps/companies/apps/referrals/details/client/tasks' -import * as exportsHistoryTasks from '../apps/companies/apps/exports/client/ExportsHistory/tasks' +import * as exportsHistoryTasks from './modules/Companies/CompanyExports/ExportHistory/tasks.js' import referralListTask from './components/ReferralList/tasks' import { TASK_SAVE_REFERRAL } from '../apps/companies/apps/referrals/send-referral/client/state' import * as referralsSendTasks from '../apps/companies/apps/referrals/send-referral/client/tasks' -import * as exportWinsTasks from '../apps/companies/apps/exports/client/ExportWins/tasks' +import * as exportWinsTasks from './modules/Companies/CompanyExports/ExportWins/tasks.js' import { TASK_NAME as EXPORT_COUNTRIES_EDIT_NAME } from './modules/Companies/CompanyExports/ExportCountriesEdit/state' import * as exportCountriesEditTasks from './modules/Companies/CompanyExports/ExportCountriesEdit/tasks' import addCompanyPostcodeToRegionTask, { @@ -142,7 +142,7 @@ import { TASK_GET_REMINDER_SUMMARY } from './components/NotificationAlert/state' import { TASK_GET_TYPEAHEAD_OPTIONS } from './components/Typeahead/state' -import * as exportsEdit from '../apps/companies/apps/exports/client/tasks' +import * as exportsEdit from './modules/Companies/CompanyExports/tasks.js' import { saveContact, diff --git a/test/end-to-end/cypress/specs/DA/permission-spec.js b/test/end-to-end/cypress/specs/DA/permission-spec.js index a5f95aef6ee..5e3d9148e77 100644 --- a/test/end-to-end/cypress/specs/DA/permission-spec.js +++ b/test/end-to-end/cypress/specs/DA/permission-spec.js @@ -18,7 +18,7 @@ describe('DA Permission', () => { before(() => { cy.loadFixture([company]) - cy.visit(companies.exports.index(company), { + cy.visit(companies.exports.index(company.pk), { failOnStatusCode: false, }) }) diff --git a/test/functional/cypress/specs/companies/export/history-spec.js b/test/functional/cypress/specs/companies/export/history-spec.js index 5294d70508d..e4805292a3a 100644 --- a/test/functional/cypress/specs/companies/export/history-spec.js +++ b/test/functional/cypress/specs/companies/export/history-spec.js @@ -124,15 +124,11 @@ describe('Company Export tab - Export countries history', () => { }) it('should display the next button', () => { - cy.get('#company-export-full-history').within(() => { - cy.get('ul:last li a:last').should('have.text', 'Next') - }) + cy.get('[data-test="next"]').should('have.text', 'Next') }) it('should not display the previous button', () => { - cy.get('#company-export-full-history').within(() => { - cy.get('ul:last li a:first').should('not.have.text', 'Previous') - }) + cy.get('[data-test="prev"]').should('not.exist') }) it('the second page renders the collection list with 2 of the 12 results', () => { @@ -155,15 +151,11 @@ describe('Company Export tab - Export countries history', () => { }) it('should not display the next button', () => { - cy.get('#company-export-full-history').within(() => { - cy.get('ul:last li a:last').should('not.have.text', 'Next') - }) + cy.get('[data-test="next"]').should('not.exist') }) it('should display the previous button', () => { - cy.get('#company-export-full-history').within(() => { - cy.get('ul:last li a:first').should('have.text', 'Previous') - }) + cy.get('[data-test="prev"]').should('have.text', 'Previous') }) }) diff --git a/test/functional/cypress/specs/companies/export/index-spec.js b/test/functional/cypress/specs/companies/export/index-spec.js index 112d4379b3f..b63f96569b6 100644 --- a/test/functional/cypress/specs/companies/export/index-spec.js +++ b/test/functional/cypress/specs/companies/export/index-spec.js @@ -384,15 +384,11 @@ describe('Company Export tab', () => { }) it('should display the next button', () => { - cy.get('#company-export-index-page').within(() => { - cy.get('ul:last li a:last').should('have.text', 'Next') - }) + cy.get('[data-test="next"]').should('have.text', 'Next') }) it('should not display the previous button', () => { - cy.get('#company-export-index-page').within(() => { - cy.get('ul:last li a:first').should('not.have.text', 'Previous') - }) + cy.get('[data-test="prev"]').should('not.exist') }) it('the second page renders the collection list with 6 of the 15 results', () => { @@ -411,15 +407,11 @@ describe('Company Export tab', () => { }) it('should not display the next button', () => { - cy.get('#company-export-index-page').within(() => { - cy.get('ul:last li a:last').should('not.have.text', 'Next') - }) + cy.get('[data-test="next"]').should('not.exist') }) it('should display the previous button', () => { - cy.get('#company-export-index-page').within(() => { - cy.get('ul:last li a:first').should('have.text', 'Previous') - }) + cy.get('[data-test="prev"]').should('have.text', 'Previous') }) }) })