From ed50875f5b4a7fa385e8add0348e7e4cdf24679e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1rbara=20Chaves?= Date: Mon, 28 Oct 2024 18:08:02 +0100 Subject: [PATCH 1/3] Fix styles and add download form --- app/assets/images/tpi/icons/download.svg | 5 + app/assets/stylesheets/tpi.scss | 1 + app/assets/stylesheets/tpi/_base-tooltip.scss | 3 + app/assets/stylesheets/tpi/_bubble-chart.scss | 33 +- .../stylesheets/tpi/_download-form-modal.scss | 136 ++++++++ .../stylesheets/tpi/_mq_beta_scores.scss | 79 +++-- app/assets/stylesheets/tpi/buttons.scss | 10 + .../tpi/charts/companies_accordion.scss | 2 +- .../tpi/charts/mq-sector-pie-chart.scss | 2 +- app/assets/stylesheets/tpi/pages/sector.scss | 30 +- .../stylesheets/tpi/pages/sectors-index.scss | 5 +- .../components/tpi/DownloadFormModal.jsx | 294 ++++++++++++++++++ app/javascript/components/tpi/InfoTooltip.js | 4 +- app/javascript/components/tpi/Select.js | 31 +- .../components/tpi/charts/bubble/Chart.js | 37 ++- .../tpi/charts/bubble/SingleCell.js | 2 +- .../tpi/charts/mq-sector-bar/Bar.js | 4 +- .../tpi/charts/mq-sector-pie/Chart.js | 5 +- app/views/tpi/sectors/index.html.erb | 6 +- app/views/tpi/sectors/show.html.erb | 18 +- package.json | 1 + yarn.lock | 5 + 22 files changed, 614 insertions(+), 99 deletions(-) create mode 100644 app/assets/images/tpi/icons/download.svg create mode 100644 app/assets/stylesheets/tpi/_download-form-modal.scss create mode 100644 app/javascript/components/tpi/DownloadFormModal.jsx diff --git a/app/assets/images/tpi/icons/download.svg b/app/assets/images/tpi/icons/download.svg new file mode 100644 index 000000000..caeef0de1 --- /dev/null +++ b/app/assets/images/tpi/icons/download.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/assets/stylesheets/tpi.scss b/app/assets/stylesheets/tpi.scss index 5ad486cab..904bb7d6f 100644 --- a/app/assets/stylesheets/tpi.scss +++ b/app/assets/stylesheets/tpi.scss @@ -44,6 +44,7 @@ @import "tpi/mq_beta_scores"; @import "tpi/mq-beta-modal"; @import "tpi/selector"; +@import "tpi/download-form-modal"; @import "tpi/emissions-chart"; @import "tpi/ascor-benchmarks"; @import "tpi/pages/*"; diff --git a/app/assets/stylesheets/tpi/_base-tooltip.scss b/app/assets/stylesheets/tpi/_base-tooltip.scss index c2c9eacce..c2a9cc3ef 100644 --- a/app/assets/stylesheets/tpi/_base-tooltip.scss +++ b/app/assets/stylesheets/tpi/_base-tooltip.scss @@ -9,6 +9,9 @@ div[data-react-class=BaseTooltip] { .base-tooltip { position: relative; + >div:first-child { + height: auto; + } &__default-trigger { font-family: $font-family-bold; diff --git a/app/assets/stylesheets/tpi/_bubble-chart.scss b/app/assets/stylesheets/tpi/_bubble-chart.scss index 5eadb3e46..72ac7593c 100644 --- a/app/assets/stylesheets/tpi/_bubble-chart.scss +++ b/app/assets/stylesheets/tpi/_bubble-chart.scss @@ -1,9 +1,9 @@ @import "colors"; @import "typography"; -$tape-height: 8px; +$tape-height: 1px; $tape-color: rgba(25, 25, 25, 0.1); -$cell-height: 80px; +$cell-height: 60px; $cell-height-banks: 100px; $legend-image-width: 60px; @@ -13,18 +13,18 @@ $legend-image-width: 60px; color: $blue-darker; margin-top: 28px; line-height: 20px; + margin-bottom: 20px; } .bubble-chart__container { width: 100%; - padding: 50px 0; /* CSS GRID */ display: grid; grid-row-gap: 4px; align-items: center; &--sectors { - grid-template-rows: 150px auto; + grid-template-rows: 144px auto; .last { border-right: none; @@ -46,14 +46,13 @@ $legend-image-width: 60px; height: $cell-height; display: flex; align-items: center; - border-right: calc(#{$tape-height / 2}) dotted $tape-color; & > *:first-child { margin: auto; z-index: 1; } - &::before { + &::after { background-color: $tape-color; content: ""; position: absolute; @@ -72,13 +71,13 @@ $legend-image-width: 60px; .bubble-chart_circle { circle:hover { stroke-width: 2; - stroke: #FFDD49; + stroke: $yellow; } } .bubble-chart_tooltip { z-index: 10; background-color: $white; - border: 1.5px solid $black; + border: 1.25px solid $black; padding: 20px; font-size: 14px; width: max-content; @@ -98,15 +97,15 @@ $legend-image-width: 60px; margin-block: 8px 20px; } &_text { - display: grid; - grid-template-columns: repeat(2, 1fr); + columns: 2; margin-block: 12px; font-size: 16px; max-height: 200px; overflow-y: auto; - gap: 12px 20px; - + column-gap: 40px; + .bubble-chart_tooltip_list_item { + margin-top: 12px; margin-left: 20px; a { text-decoration: underline; @@ -115,11 +114,12 @@ $legend-image-width: 60px; } } - button { + .button.is-secondary.is-small { float: right; margin-top: 20px; height: 40px !important; width: 62px !important; + min-width: auto; } } @@ -214,14 +214,15 @@ $legend-image-width: 60px; .bubble-chart__level { border-right: calc(#{$tape-height / 2}) dotted $tape-color; position: relative; - height: 100%; - padding-left: 20px; + height: 20%; + } .bubble-chart__container--sectors { .bubble-chart__level-container { position: absolute; top: 20%; + padding-inline: 16px 10px; } .bubble-chart__level-title { @@ -259,5 +260,5 @@ $legend-image-width: 60px; .bubble-chart__row-link { color: $blue-dark; text-align: right; - padding-right: 50px; + padding-right: 16px; } diff --git a/app/assets/stylesheets/tpi/_download-form-modal.scss b/app/assets/stylesheets/tpi/_download-form-modal.scss new file mode 100644 index 000000000..f5a433ff5 --- /dev/null +++ b/app/assets/stylesheets/tpi/_download-form-modal.scss @@ -0,0 +1,136 @@ +@import "colors"; +@import "typography"; + +.download { + button { + margin-right: 10px; + } +} +.download-form { + > * { + margin-bottom: 20px; + } + h2 { + font-size: 20px !important; + font-weight: bold; + } + .--mandatory { + color: $red; + } + .content { + input[type="text"] { + height: 40px; + width: 100%; + padding-inline: 10px; + border-radius: 0; + border: 1px solid #191919; + &::placeholder { + color: #595b5d; + font-size: 12px; + } + } + .text-inputs { + margin-bottom: 20px; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 20px; + @include until($breakpoint-desktop) { + grid-template-columns: 1fr; + } + label { + display: block; + line-height: 24px; + margin-bottom: 9px; + } + .selector__container { + list-style: none; + margin: 0; + .selector__header { + height: 40px; + } + .selector__input { + border: 0; + background-color: $white !important; + } + .selector__value { + font-size: 14px; + } + .selector__options { + margin: 0; + transform: translateY(-4px); + list-style: none; + max-height: 300px; + overflow-y: auto; + .selector__option { + font-size: 14px; + padding-block: 5px; + } + } + } + &.--full { + .content__input { + column-span: 2; + } + } + } + .checkbox-inputs { + display: flex; + flex-wrap: wrap; + gap: 16px 20px; + margin-bottom: 16px; + .content__input { + display: flex; + flex-direction: row-reverse; + align-items: center; + gap: 12px; + + input { + width: 24px; + height: 24px; + border-radius: 0; + display: flex; + justify-content: center; + align-items: center; + border: 2px solid $grey-dark; + appearance: none; + -webkit-appearance: none; + &::before { + content: ""; + width: 12px; + height: 12px; + display: block; + transform: scale(0); + background-color: $blue; + } + &:checked { + &::before { + transform: scale(1); + } + } + } + } + } + } + .other-purposes-text { + &.hidden { + display: none; + } + } + .error { + color: $red; + font-size: 12px; + margin-top: 10px; + } + .form-buttons { + margin-top: 20px; + width: 50%; + display: flex; + gap: 8px; + button { + min-width: auto !important; + } + .is-primary { + flex-grow: 1; + } + } +} diff --git a/app/assets/stylesheets/tpi/_mq_beta_scores.scss b/app/assets/stylesheets/tpi/_mq_beta_scores.scss index b550309c9..b668ee5d3 100644 --- a/app/assets/stylesheets/tpi/_mq_beta_scores.scss +++ b/app/assets/stylesheets/tpi/_mq_beta_scores.scss @@ -3,20 +3,26 @@ flex-wrap: wrap; flex-direction: row; - @include until($desktop) { - flex-direction: column; - } - &__container { display: flex; - border: 1px solid $white; padding: 4px 4px 4px 14px; + flex-wrap: wrap; + @include until($desktop) { + padding: 0; + width: 100%; + margin-inline: 12px; + } } &__text { color: $white; line-height: 40px; margin-right: 10px; + @include until($desktop) { + flex-direction: column; + width: 100%; + // padding-inline: 12px; + } } &__divider { @@ -27,13 +33,34 @@ } } + a { + padding: 10px 12px; + &.button:not(.active):hover { + text-decoration: underline; + background-color: transparent; + } + &:first-of-type { + order: 3; + margin-right: 12px; + } + } + .button { - background-color: rgba($white ,0.2); - + @include until($desktop) { + width: 50%; + height: 40px; + margin-right: 0; + } &.active { - background-color: $white; - color: $blue-dark; + background-color: $blue-dark; + transform: translateY(1px); + color: $white; + @include until($desktop) { + background-color: $white; + color: $blue; + border-color: transparent; + } } &:last-child { @@ -42,6 +69,7 @@ } &__beta-button { + order: 2; &.disabled { opacity: 0.5; cursor: not-allowed; @@ -49,18 +77,6 @@ } } - &__beta-button:before { - content: ""; - width: 9px; - height: 9px; - border-radius: 50%; - margin-right: 5px; - display: inline-block; - background-color: $tpi-level5-background-color; - vertical-align: middle; - border: 1px solid $white; - } - &__download-button { flex-grow: 4; text-align: right; @@ -73,7 +89,26 @@ } @include until($desktop) { - margin-bottom: 10px; + background-color: #fff; + padding-inline: 12px; + padding-block: 40px; + flex-direction: column; + .button { + background-color: $white; + color: $blue !important; + border-color: $blue !important; + width: 100%; + &::before { + content: ' '; + width: 16px; + height: 16px; + background-image: image-url("tpi/icons/download.svg"); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + } + + } } } } diff --git a/app/assets/stylesheets/tpi/buttons.scss b/app/assets/stylesheets/tpi/buttons.scss index d8e3dbfeb..12d8384c5 100644 --- a/app/assets/stylesheets/tpi/buttons.scss +++ b/app/assets/stylesheets/tpi/buttons.scss @@ -95,6 +95,16 @@ $button-border-width: 4px; justify-content: center; align-items: center; + &.is-info { + height: 20px; + width: 20px; + min-width: auto; + padding: 0; + background-color: transparent; + border-width: 2px; + margin-top: 2px; + } + &.is-small { border-radius: 0; height: 30px; diff --git a/app/assets/stylesheets/tpi/charts/companies_accordion.scss b/app/assets/stylesheets/tpi/charts/companies_accordion.scss index e336446e6..3713a8f9e 100644 --- a/app/assets/stylesheets/tpi/charts/companies_accordion.scss +++ b/app/assets/stylesheets/tpi/charts/companies_accordion.scss @@ -4,7 +4,7 @@ $tpi-level-chart-colors: #86A9F9 #5587F7 #2465F5 #0A4BDC #083AAB #9747FF; .mobile_bubble-chart__container { - margin: 0 -0.75rem; + margin: 0 -0.75rem 70px; padding: 0; .mq-sector-pie-chart-title { diff --git a/app/assets/stylesheets/tpi/charts/mq-sector-pie-chart.scss b/app/assets/stylesheets/tpi/charts/mq-sector-pie-chart.scss index 41a96d68d..59bb25773 100644 --- a/app/assets/stylesheets/tpi/charts/mq-sector-pie-chart.scss +++ b/app/assets/stylesheets/tpi/charts/mq-sector-pie-chart.scss @@ -101,7 +101,7 @@ $tpi-pie-chart-colors: #86a9f9 #5587f7 #2465f5 #0a4bdc #083aab #9747ff; row-gap: 20px; @include until($desktop) { column-gap: 32px; - width: auto; + width: 100%; } .chart-legend-item { display: flex; diff --git a/app/assets/stylesheets/tpi/pages/sector.scss b/app/assets/stylesheets/tpi/pages/sector.scss index baf4ea746..065f50c91 100644 --- a/app/assets/stylesheets/tpi/pages/sector.scss +++ b/app/assets/stylesheets/tpi/pages/sector.scss @@ -23,13 +23,18 @@ $tape-color: rgba(25, 25, 25, 0.1); color: white; line-height: 40px; margin-right: 10px; + @include until($desktop) { + margin-right: 0; + } } @include until($desktop) { - padding-inline: 0 0.75rem; + padding-inline: 0 !important; font-size: $size-7; - height: 60px; + height: auto; + padding-top: 40px; font-family: $font-family-regular; + } } @@ -89,13 +94,10 @@ $tape-color: rgba(25, 25, 25, 0.1); &__companies { line-height: 1.25; - // height: 150px; - color: white; - display: flex; align-items: end; - + > div:first-child { width: 100%; text-align: center; @@ -103,6 +105,9 @@ $tape-color: rgba(25, 25, 25, 0.1); font-size: 32px; font-weight: 700; cursor: pointer; + &:hover { + border: 2px solid $yellow; + } } @@ -145,6 +150,7 @@ $tape-color: rgba(25, 25, 25, 0.1); display: flex; justify-content: space-between; margin-bottom: 15px; + padding-top: 50px; > p { display: none; @@ -190,7 +196,7 @@ $tape-color: rgba(25, 25, 25, 0.1); .sector-level__popover { z-index: 10; background-color: $white; - border: 1.5px solid $black; + border: 1.25px solid $black; padding: 20px; font-size: 14px; width: 430px; @@ -216,25 +222,25 @@ $tape-color: rgba(25, 25, 25, 0.1); margin-block: 8px 20px; } &_text { - display: grid; - grid-template-columns: repeat(2, 1fr); + columns: 2; margin-block: 12px; font-size: 16px; max-height: 200px; overflow-y: auto; - gap: 12px 20px; - padding-left: 2rem; + column-gap: 40px; } &_list_item { + margin-left: 20px; a { text-decoration: underline; color: black; } } - button { + .button.is-secondary.is-small { float: right; margin-top: 20px; height: 40px !important; width: 62px !important; + min-width: auto; } } diff --git a/app/assets/stylesheets/tpi/pages/sectors-index.scss b/app/assets/stylesheets/tpi/pages/sectors-index.scss index dcdbb9415..925f25037 100644 --- a/app/assets/stylesheets/tpi/pages/sectors-index.scss +++ b/app/assets/stylesheets/tpi/pages/sectors-index.scss @@ -22,10 +22,11 @@ } @include until($desktop) { - padding: 0 0.75rem; + padding: 0; font-size: $size-7; min-height: 60px; font-family: $font-family-regular; + // transform: translateY(-1px); } } @@ -33,7 +34,7 @@ margin-top: 70px; @include until($desktop) { - margin-top: 40px; + margin-top: 0px; padding: 0 0.75rem; } } diff --git a/app/javascript/components/tpi/DownloadFormModal.jsx b/app/javascript/components/tpi/DownloadFormModal.jsx new file mode 100644 index 000000000..5ed068794 --- /dev/null +++ b/app/javascript/components/tpi/DownloadFormModal.jsx @@ -0,0 +1,294 @@ +import React, { useState, useRef, useEffect, useMemo } from 'react'; + +import PropTypes from 'prop-types'; +import { getNames } from 'country-list'; +import { Modal } from './Modal'; +import { OverlayProvider } from '@react-aria/overlays'; +import Select from './Select'; +import classNames from 'classnames'; + +const Field = ({ label, name, value, onChange, type, required, error, placeholder, children }) => { + const ref = useRef(null); + + useEffect(() => { + if (error) { + ref.current.focus(); + } + }, [error]); + + return ( +
+ + {children || ( + + )} + {error && {error}} +
+ ); +}; + +Field.propTypes = { + label: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + type: PropTypes.string, + value: PropTypes.string, + onChange: PropTypes.func, + error: PropTypes.string, + required: PropTypes.bool, + placeholder: PropTypes.string, + children: PropTypes.node +}; + +Field.defaultProps = { + error: null, + type: 'text', + onChange: () => {}, + value: undefined, + required: false, + placeholder: '', + children: null +}; + +const checkboxInputs = [ + 'diligence_research', + 'engagement', + 'voting', + 'academic_research', + 'content_creation', + 'investment', + 'other_purpose_checkbox' +]; + +const initialFormValues = { + email: '', + job_title: '', + forename: '', + surname: '', + location: '', + organisation: '', + purposes: [], + other_purpose: '' +}; + +function DownloadFormModal() { + const [showModal, setShowModal] = useState(false); + const [error, setError] = useState(null); + const [formValues, setFormValues] = useState(initialFormValues); + + const downloadLinkRef = useRef(null); + const countryOptions = useMemo(() => getNames()?.map((name) => ({label: name, value: name})), []); + + const handleSubmit = (e) => { + e.preventDefault(); + + if (formValues.purposes.length === 0) { + setError('Please select at least one purpose'); + return; + } + if (formValues.purposes.includes('other_purpose_checkbox') && !formValues.other_purpose) { + setError('Please specify other purposes'); + return; + } + + fetch('/sectors/send_download_file_info_email', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRF-Token': document.querySelector('[name="csrf-token"]').content + }, + body: JSON.stringify(formValues) + }).then(() => { + downloadLinkRef.current.click(); + setShowModal(false); + setFormValues(initialFormValues); + }, () => { + setError('Something went wrong. Please try again later.'); + }); + }; + + const handleChange = (e) => { + setFormValues({ ...formValues, [e.target.name]: e.target.value }); + if (checkboxInputs.includes(e.target.name)) { + if (e.target.checked) { + setFormValues({ + ...formValues, + purposes: [...formValues.purposes, e.target.name] + }); + setError(null); + } else { + setFormValues({ + ...formValues, + other_purpose: e.target.name === 'other_purpose_checkbox' ? '' : formValues.other_purpose, + purposes: formValues.purposes.filter((item) => item !== e.target.name) + }); + } + } + }; + + return ( +
+ + + + setShowModal(false)} + > +
+

Data Disclaimer

+

+ I have read the Use of TPI Centre Data and will not use the data for + commercial purposes unless I have sought prior permission. +

+

All + fields below are mandatory. +

+
+
+
+ + + + + + + {error && {error}} +
+ + +
+ +
+
+ + +
+ ); +} + +export default DownloadFormModal; diff --git a/app/javascript/components/tpi/InfoTooltip.js b/app/javascript/components/tpi/InfoTooltip.js index 4629c7a7d..c1d840178 100644 --- a/app/javascript/components/tpi/InfoTooltip.js +++ b/app/javascript/components/tpi/InfoTooltip.js @@ -3,10 +3,10 @@ import PropTypes from 'prop-types'; import ReactTooltip from 'react-tooltip'; const InfoTooltip = ({ trigger, content, html }) => ( - +
{html ?
:
{trigger}
} - +
); InfoTooltip.propTypes = { diff --git a/app/javascript/components/tpi/Select.js b/app/javascript/components/tpi/Select.js index abca539e0..f2e1405e5 100644 --- a/app/javascript/components/tpi/Select.js +++ b/app/javascript/components/tpi/Select.js @@ -20,7 +20,7 @@ const Select = ({ value, allowSearch, placeholder, - label + required }) => { const [searchValue, setSearchValue] = useState(''); const [isOpen, setIsOpen] = useState(false); @@ -59,6 +59,7 @@ const Select = ({ const handleOptionClick = (opt) => { setIsOpen(false); + setSearchValue(opt.value); onSelect({ name, value: opt.value, label: opt.label }); }; @@ -144,18 +145,15 @@ const Select = ({ role="button" aria-label={isOpen ? 'Close dropdown' : 'Open dropdown'} > - {isOpen && allowSearch ? ( - setSearchValue(e.target.value)} - placeholder="Type or select" - /> - ) : ( - - {value || placeholder} - - )} + setSearchValue(e.target.value)} + placeholder={placeholder} + required={required} + name={name} + value={isOpen && allowSearch ? searchValue : value} + /> isOpen && handleCloseDropdown()} className={cx('chevron-icon', { @@ -215,14 +213,15 @@ Select.propTypes = { value: PropTypes.string, allowSearch: PropTypes.bool, placeholder: PropTypes.string, - label: PropTypes.string.isRequired, - name: PropTypes.string.isRequired + name: PropTypes.string.isRequired, + required: PropTypes.bool }; Select.defaultProps = { value: '', allowSearch: false, - placeholder: '' + placeholder: '', + required: false }; export default Select; diff --git a/app/javascript/components/tpi/charts/bubble/Chart.js b/app/javascript/components/tpi/charts/bubble/Chart.js index 7c604688d..7a16db5e0 100644 --- a/app/javascript/components/tpi/charts/bubble/Chart.js +++ b/app/javascript/components/tpi/charts/bubble/Chart.js @@ -13,8 +13,8 @@ const COMPANIES_MARKET_CAP_GROUPS = { '1-10': 3 * SCALE }; -const SINGLE_CELL_SVG_WIDTH = 120 * SCALE; -const SINGLE_CELL_SVG_HEIGHT = 80 * SCALE; +const SINGLE_CELL_SVG_WIDTH = 144; +const SINGLE_CELL_SVG_HEIGHT = 60; const LEVELS_COLORS = [ '#86A9F9', @@ -109,6 +109,8 @@ const BubbleChart = ({ levels, sectors }) => { const levelsSignature = levels && Object.keys(levels[Object.keys(levels)[0]]); + const GRID_HEIGHT = parsedData.length * SINGLE_CELL_SVG_HEIGHT + 150; + return (
@@ -121,7 +123,7 @@ const BubbleChart = ({ levels, sectors }) => {
@@ -162,6 +164,19 @@ const BubbleChart = ({ levels, sectors }) => { {LEVELS_SUBTITLES[el]}
+ { i > 0 + && + + }
))} {parsedData.map((dataRow) => ( @@ -172,6 +187,22 @@ const BubbleChart = ({ levels, sectors }) => { key={dataRow.sector} /> ))} + {/*
+ {levelsSignature.map((dataRow) => ( + + + + ))} +
*/}
); diff --git a/app/javascript/components/tpi/charts/bubble/SingleCell.js b/app/javascript/components/tpi/charts/bubble/SingleCell.js index 2e211dccf..766db80ae 100644 --- a/app/javascript/components/tpi/charts/bubble/SingleCell.js +++ b/app/javascript/components/tpi/charts/bubble/SingleCell.js @@ -65,7 +65,7 @@ const SingleCell = ({ width, height, data, uniqueKey }) => { transform={`translate(${width / 2}, ${height / 2})`} > - + {data.value} diff --git a/app/javascript/components/tpi/charts/mq-sector-bar/Bar.js b/app/javascript/components/tpi/charts/mq-sector-bar/Bar.js index ca3815c5c..729661ca4 100644 --- a/app/javascript/components/tpi/charts/mq-sector-bar/Bar.js +++ b/app/javascript/components/tpi/charts/mq-sector-bar/Bar.js @@ -86,7 +86,7 @@ function Bar({ level, companies, sector, height }) {
{isOpen && ( - +
diff --git a/app/javascript/components/tpi/charts/mq-sector-pie/Chart.js b/app/javascript/components/tpi/charts/mq-sector-pie/Chart.js index c10065c07..2bce7ebf3 100644 --- a/app/javascript/components/tpi/charts/mq-sector-pie/Chart.js +++ b/app/javascript/components/tpi/charts/mq-sector-pie/Chart.js @@ -76,7 +76,10 @@ function MQSectorChart({ dataUrl }) { style={{ backgroundColor: options.colors[index] }} />

Level {item.name}

- + ?} + />

{item.value} {item.value === 1 ? 'company' : 'companies'} - {item.percentage}% diff --git a/app/views/tpi/sectors/index.html.erb b/app/views/tpi/sectors/index.html.erb index 0d07715c9..efaa8fe71 100644 --- a/app/views/tpi/sectors/index.html.erb +++ b/app/views/tpi/sectors/index.html.erb @@ -15,14 +15,12 @@

<%= render 'tpi/shared/mq_beta_scores', has_data: true %>
+ <%= react_component('DownloadFormModal') %> <%= link_to user_download_methodology_tpi_sectors_path, class: 'button is-primary is-pulled-right with-icon with-border' do %> download icon Download Methodology <% end %> - <%= link_to user_download_all_tpi_sectors_path, class: 'button is-primary with-icon with-border' do %> - download icon - Download CP & MQ Data - <% end %> +
diff --git a/app/views/tpi/sectors/show.html.erb b/app/views/tpi/sectors/show.html.erb index 88e2140e7..5a8d09473 100644 --- a/app/views/tpi/sectors/show.html.erb +++ b/app/views/tpi/sectors/show.html.erb @@ -15,30 +15,17 @@
<%= render 'tpi/shared/mq_beta_scores', has_data: true %>
+ <%= react_component('DownloadFormModal') %> <%= link_to user_download_methodology_tpi_sectors_path, class: 'button is-primary is-pulled-right with-icon with-border' do %> download icon Download Methodology <% end %> - <%= link_to user_download_tpi_sector_path(@sector), class: 'button is-primary is-pulled-right with-icon with-border' do %> - download icon - Download CP & MQ Data - <% end %>
@@ -52,9 +39,8 @@ <%= react_component('charts/mq-sector-pie', { dataUrl: levels_chart_data_tpi_sector_path(@sector.id) }) %> - <%= react_component("charts/bubble/CompaniesAccordion", { levels: @companies_by_levels, by_sector: false }) %> -

Number and Detailed Companies Lists by Management Quality

+ <%= react_component("charts/bubble/CompaniesAccordion", { levels: @companies_by_levels, by_sector: false }) %> <%= react_component('charts/mq-sector-bar', { data: @companies_by_levels, sector: @sector.name }) %> diff --git a/package.json b/package.json index d2b90c9bc..d038fd648 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "bulma": "^0.8.0", "classnames": "^2.2.6", + "country-list": "^2.3.0", "d3-array": "^2.5.0", "d3-force": "^2.0.1", "d3-format": "^1.4.3", diff --git a/yarn.lock b/yarn.lock index 123865687..4b674802e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2875,6 +2875,11 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" +country-list@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/country-list/-/country-list-2.3.0.tgz#1e7ceaf9834c1d1210054301eabf4dc445ab978c" + integrity sha512-qZk66RlmQm7fQjMYWku1AyjlKPogjPEorAZJG88owPExoPV8EsyCcuFLvO2afTXHEhi9liVOoyd+5A6ZS5QwaA== + create-ecdh@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" From ce41571e291c662a4da0f937bb2081a6d62ad487 Mon Sep 17 00:00:00 2001 From: martintomas Date: Tue, 29 Oct 2024 10:02:34 +0100 Subject: [PATCH 2/3] fix: Adding downloadUrl to DownloadFormModal component --- app/controllers/tpi/sectors_controller.rb | 2 +- app/javascript/components/tpi/DownloadFormModal.jsx | 8 ++++++-- .../send_download_file_info_email.html.erb | 6 +++++- app/views/tpi/companies/show.html.erb | 7 +++---- app/views/tpi/sectors/index.html.erb | 4 +++- app/views/tpi/sectors/show.html.erb | 4 +++- spec/mailers/data_download_mailer_spec.rb | 4 +++- 7 files changed, 24 insertions(+), 11 deletions(-) diff --git a/app/controllers/tpi/sectors_controller.rb b/app/controllers/tpi/sectors_controller.rb index 086105b29..adecdf8f0 100644 --- a/app/controllers/tpi/sectors_controller.rb +++ b/app/controllers/tpi/sectors_controller.rb @@ -170,7 +170,7 @@ def companies_scope(params) end def permitted_email_params - params.permit(:email, :job_title, :forename, :surname, :location, :organisation, purposes: []) + params.permit(:email, :job_title, :forename, :surname, :location, :organisation, :other_purpose, purposes: []) end end end diff --git a/app/javascript/components/tpi/DownloadFormModal.jsx b/app/javascript/components/tpi/DownloadFormModal.jsx index 5ed068794..90bf7f58d 100644 --- a/app/javascript/components/tpi/DownloadFormModal.jsx +++ b/app/javascript/components/tpi/DownloadFormModal.jsx @@ -80,7 +80,7 @@ const initialFormValues = { other_purpose: '' }; -function DownloadFormModal() { +function DownloadFormModal({ downloadUrl }) { const [showModal, setShowModal] = useState(false); const [error, setError] = useState(null); const [formValues, setFormValues] = useState(initialFormValues); @@ -271,7 +271,7 @@ function DownloadFormModal() { onChange={handleChange} /> - @@ -291,4 +291,8 @@ function DownloadFormModal() { ); } +DownloadFormModal.propTypes = { + downloadUrl: PropTypes.string.isRequired +}; + export default DownloadFormModal; diff --git a/app/views/data_download_mailer/send_download_file_info_email.html.erb b/app/views/data_download_mailer/send_download_file_info_email.html.erb index 3fd2a9a18..6e05995b2 100644 --- a/app/views/data_download_mailer/send_download_file_info_email.html.erb +++ b/app/views/data_download_mailer/send_download_file_info_email.html.erb @@ -10,6 +10,10 @@

Purposes

    <% Array.wrap(@data[:purposes]).each do |purpose| %> -
  • <%= purpose %>
  • + <% if purpose == "other_purpose_checkbox" %> +
  • Other: <%= @data[:other_purpose] %>
  • + <% else %> +
  • <%= purpose %>
  • + <% end %> <% end %>
diff --git a/app/views/tpi/companies/show.html.erb b/app/views/tpi/companies/show.html.erb index af7c13109..7060500cf 100644 --- a/app/views/tpi/companies/show.html.erb +++ b/app/views/tpi/companies/show.html.erb @@ -12,14 +12,13 @@
<%= render 'tpi/shared/mq_beta_scores', has_data: @company.beta_mq_assessments? %>
+ <%= react_component('DownloadFormModal', { + downloadUrl: user_download_all_tpi_sectors_path + }) %> <%= link_to user_download_methodology_tpi_sectors_path, class: 'button is-primary is-pulled-right with-icon with-border' do %> download icon Download Methodology <% end %> - <%= link_to user_download_all_tpi_sectors_path, class: 'button is-primary is-pulled-right with-icon with-border' do %> - download icon - Download CP & MQ Data - <% end %>
diff --git a/app/views/tpi/sectors/index.html.erb b/app/views/tpi/sectors/index.html.erb index efaa8fe71..048728362 100644 --- a/app/views/tpi/sectors/index.html.erb +++ b/app/views/tpi/sectors/index.html.erb @@ -15,7 +15,9 @@
<%= render 'tpi/shared/mq_beta_scores', has_data: true %>
- <%= react_component('DownloadFormModal') %> + <%= react_component('DownloadFormModal', { + downloadUrl: user_download_all_tpi_sectors_path + }) %> <%= link_to user_download_methodology_tpi_sectors_path, class: 'button is-primary is-pulled-right with-icon with-border' do %> download icon Download Methodology diff --git a/app/views/tpi/sectors/show.html.erb b/app/views/tpi/sectors/show.html.erb index 5a8d09473..395a64c3d 100644 --- a/app/views/tpi/sectors/show.html.erb +++ b/app/views/tpi/sectors/show.html.erb @@ -15,7 +15,9 @@
<%= render 'tpi/shared/mq_beta_scores', has_data: true %>
- <%= react_component('DownloadFormModal') %> + <%= react_component('DownloadFormModal', { + downloadUrl: user_download_tpi_sector_path(@sector) + }) %> <%= link_to user_download_methodology_tpi_sectors_path, class: 'button is-primary is-pulled-right with-icon with-border' do %> download icon Download Methodology diff --git a/spec/mailers/data_download_mailer_spec.rb b/spec/mailers/data_download_mailer_spec.rb index 357f3fa74..11334c3b5 100644 --- a/spec/mailers/data_download_mailer_spec.rb +++ b/spec/mailers/data_download_mailer_spec.rb @@ -10,7 +10,8 @@ surname: 'surname', location: 'location', organisation: 'organisation', - purposes: %w[purpose1 purpose2] + purposes: %w[purpose1 purpose2 other_purpose_checkbox], + other_purpose: 'other_purpose' } } let(:mail) { DataDownloadMailer.send_download_file_info_email data } @@ -28,6 +29,7 @@ expect(mail.body.encoded).to include('organisation') expect(mail.body.encoded).to include('purpose1') expect(mail.body.encoded).to include('purpose2') + expect(mail.body.encoded).to include('other_purpose') end end end From c70a536ed45b255d8e2b1d12fb29a3cfc38a89e3 Mon Sep 17 00:00:00 2001 From: martintomas Date: Tue, 29 Oct 2024 10:04:02 +0100 Subject: [PATCH 3/3] chore: upgrade of rexml gem --- Gemfile.lock | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 397d68a14..12ed4677f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -412,8 +412,7 @@ GEM actionpack (>= 5.2) railties (>= 5.2) retriable (3.1.2) - rexml (3.3.6) - strscan + rexml (3.3.9) roo (2.10.0) nokogiri (~> 1) rubyzip (>= 1.3.0, < 3.0.0) @@ -505,7 +504,6 @@ GEM sshkit (1.21.2) net-scp (>= 1.1.2) net-ssh (>= 2.8.0) - strscan (3.1.0) super_diff (0.9.0) attr_extras (>= 6.2.4) diff-lcs