diff --git a/app/assets/images/favicons/android-icon-144x144.png b/app/assets/images/favicons/android-icon-144x144.png new file mode 100644 index 0000000000..7197b4bab6 Binary files /dev/null and b/app/assets/images/favicons/android-icon-144x144.png differ diff --git a/app/assets/images/favicons/android-icon-192x192.png b/app/assets/images/favicons/android-icon-192x192.png new file mode 100644 index 0000000000..ccded1e6ae Binary files /dev/null and b/app/assets/images/favicons/android-icon-192x192.png differ diff --git a/app/assets/images/favicons/android-icon-36x36.png b/app/assets/images/favicons/android-icon-36x36.png new file mode 100644 index 0000000000..8b742ddd2e Binary files /dev/null and b/app/assets/images/favicons/android-icon-36x36.png differ diff --git a/app/assets/images/favicons/android-icon-48x48.png b/app/assets/images/favicons/android-icon-48x48.png new file mode 100644 index 0000000000..9fcc0a7761 Binary files /dev/null and b/app/assets/images/favicons/android-icon-48x48.png differ diff --git a/app/assets/images/favicons/android-icon-72x72.png b/app/assets/images/favicons/android-icon-72x72.png new file mode 100644 index 0000000000..93cd8e3c14 Binary files /dev/null and b/app/assets/images/favicons/android-icon-72x72.png differ diff --git a/app/assets/images/favicons/android-icon-96x96.png b/app/assets/images/favicons/android-icon-96x96.png new file mode 100644 index 0000000000..9733deceba Binary files /dev/null and b/app/assets/images/favicons/android-icon-96x96.png differ diff --git a/app/assets/images/favicons/apple-icon-114x114.png b/app/assets/images/favicons/apple-icon-114x114.png new file mode 100644 index 0000000000..d3292e3e73 Binary files /dev/null and b/app/assets/images/favicons/apple-icon-114x114.png differ diff --git a/app/assets/images/favicons/apple-icon-120x120.png b/app/assets/images/favicons/apple-icon-120x120.png new file mode 100644 index 0000000000..18d208412a Binary files /dev/null and b/app/assets/images/favicons/apple-icon-120x120.png differ diff --git a/app/assets/images/favicons/apple-icon-144x144.png b/app/assets/images/favicons/apple-icon-144x144.png new file mode 100644 index 0000000000..7197b4bab6 Binary files /dev/null and b/app/assets/images/favicons/apple-icon-144x144.png differ diff --git a/app/assets/images/favicons/apple-icon-152x152.png b/app/assets/images/favicons/apple-icon-152x152.png new file mode 100644 index 0000000000..77d9a08cd1 Binary files /dev/null and b/app/assets/images/favicons/apple-icon-152x152.png differ diff --git a/app/assets/images/favicons/apple-icon-180x180.png b/app/assets/images/favicons/apple-icon-180x180.png new file mode 100644 index 0000000000..0cb3afe82f Binary files /dev/null and b/app/assets/images/favicons/apple-icon-180x180.png differ diff --git a/app/assets/images/favicons/apple-icon-57x57.png b/app/assets/images/favicons/apple-icon-57x57.png new file mode 100644 index 0000000000..002fde242b Binary files /dev/null and b/app/assets/images/favicons/apple-icon-57x57.png differ diff --git a/app/assets/images/favicons/apple-icon-60x60.png b/app/assets/images/favicons/apple-icon-60x60.png new file mode 100644 index 0000000000..cc50646d94 Binary files /dev/null and b/app/assets/images/favicons/apple-icon-60x60.png differ diff --git a/app/assets/images/favicons/apple-icon-72x72.png b/app/assets/images/favicons/apple-icon-72x72.png new file mode 100644 index 0000000000..93cd8e3c14 Binary files /dev/null and b/app/assets/images/favicons/apple-icon-72x72.png differ diff --git a/app/assets/images/favicons/apple-icon-76x76.png b/app/assets/images/favicons/apple-icon-76x76.png new file mode 100644 index 0000000000..a54f0e48ab Binary files /dev/null and b/app/assets/images/favicons/apple-icon-76x76.png differ diff --git a/app/assets/images/favicons/apple-icon-precomposed.png b/app/assets/images/favicons/apple-icon-precomposed.png new file mode 100644 index 0000000000..a3131ad2aa Binary files /dev/null and b/app/assets/images/favicons/apple-icon-precomposed.png differ diff --git a/app/assets/images/favicons/apple-icon.png b/app/assets/images/favicons/apple-icon.png new file mode 100644 index 0000000000..a3131ad2aa Binary files /dev/null and b/app/assets/images/favicons/apple-icon.png differ diff --git a/app/assets/images/favicons/browserconfig.xml b/app/assets/images/favicons/browserconfig.xml new file mode 100644 index 0000000000..c554148223 --- /dev/null +++ b/app/assets/images/favicons/browserconfig.xml @@ -0,0 +1,2 @@ + +#ffffff \ No newline at end of file diff --git a/app/assets/images/favicons/favicon-16x16.png b/app/assets/images/favicons/favicon-16x16.png new file mode 100644 index 0000000000..2021247dba Binary files /dev/null and b/app/assets/images/favicons/favicon-16x16.png differ diff --git a/app/assets/images/favicons/favicon-32x32.png b/app/assets/images/favicons/favicon-32x32.png new file mode 100644 index 0000000000..3a4be98322 Binary files /dev/null and b/app/assets/images/favicons/favicon-32x32.png differ diff --git a/app/assets/images/favicons/favicon-96x96.png b/app/assets/images/favicons/favicon-96x96.png new file mode 100644 index 0000000000..9733deceba Binary files /dev/null and b/app/assets/images/favicons/favicon-96x96.png differ diff --git a/app/assets/images/favicons/favicon.ico b/app/assets/images/favicons/favicon.ico new file mode 100644 index 0000000000..e195eee8f7 Binary files /dev/null and b/app/assets/images/favicons/favicon.ico differ diff --git a/app/assets/images/favicons/manifest.json b/app/assets/images/favicons/manifest.json new file mode 100644 index 0000000000..013d4a6a53 --- /dev/null +++ b/app/assets/images/favicons/manifest.json @@ -0,0 +1,41 @@ +{ + "name": "App", + "icons": [ + { + "src": "\/android-icon-36x36.png", + "sizes": "36x36", + "type": "image\/png", + "density": "0.75" + }, + { + "src": "\/android-icon-48x48.png", + "sizes": "48x48", + "type": "image\/png", + "density": "1.0" + }, + { + "src": "\/android-icon-72x72.png", + "sizes": "72x72", + "type": "image\/png", + "density": "1.5" + }, + { + "src": "\/android-icon-96x96.png", + "sizes": "96x96", + "type": "image\/png", + "density": "2.0" + }, + { + "src": "\/android-icon-144x144.png", + "sizes": "144x144", + "type": "image\/png", + "density": "3.0" + }, + { + "src": "\/android-icon-192x192.png", + "sizes": "192x192", + "type": "image\/png", + "density": "4.0" + } + ] +} \ No newline at end of file diff --git a/app/assets/images/favicons/ms-icon-144x144.png b/app/assets/images/favicons/ms-icon-144x144.png new file mode 100644 index 0000000000..7197b4bab6 Binary files /dev/null and b/app/assets/images/favicons/ms-icon-144x144.png differ diff --git a/app/assets/images/favicons/ms-icon-150x150.png b/app/assets/images/favicons/ms-icon-150x150.png new file mode 100644 index 0000000000..ab0549c5e9 Binary files /dev/null and b/app/assets/images/favicons/ms-icon-150x150.png differ diff --git a/app/assets/images/favicons/ms-icon-310x310.png b/app/assets/images/favicons/ms-icon-310x310.png new file mode 100644 index 0000000000..78121eece6 Binary files /dev/null and b/app/assets/images/favicons/ms-icon-310x310.png differ diff --git a/app/assets/images/favicons/ms-icon-70x70.png b/app/assets/images/favicons/ms-icon-70x70.png new file mode 100644 index 0000000000..44f12a3c27 Binary files /dev/null and b/app/assets/images/favicons/ms-icon-70x70.png differ diff --git a/app/controllers/api/v1/ndcs_controller.rb b/app/controllers/api/v1/ndcs_controller.rb index d4f400696b..db78d45bc0 100644 --- a/app/controllers/api/v1/ndcs_controller.rb +++ b/app/controllers/api/v1/ndcs_controller.rb @@ -21,12 +21,43 @@ module V1 class NdcsController < ApiController def index - categories = ::Indc::Category.all - sectors = ::Indc::Sector.all + sectors = ::Indc::Sector. + all + + categories = ::Indc::Category. + includes(:category_type) if params[:filter] categories = categories.where( - category_type: params[:filter] + indc_category_types: { name: params[:filter] }, + ) + end + + if params[:category] + parent = ::Indc::Category. + includes(:category_type). + where( + indc_category_types: { name: 'global' }, + slug: params[:category] + ) + + categories = categories + .where( + parent_id: parent.map(&:id) + ) + end + + + indicators = ::Indc::Indicator. + includes( + :labels, :source, :categories, + values: [:sector, :label, :location] + ). + where(id: categories.flat_map(&:indicator_ids).uniq) + + if location_list + indicators = indicators.where( + values: {locations: {iso_code3: location_list}} ) end @@ -62,50 +93,6 @@ def content_overview private - def indicators - indicators = ::Indc::Indicator.includes( - :labels, - :categories, - values: [:location] - ) - - if location_list - indicators = indicators.where( - values: {locations: {iso_code3: location_list}} - ) - end - - if params[:filter] - indicators = indicators.where( - indc_categories: {category_type: params[:filter]} - ) - end - - if params[:category] - indicator_ids = ::GlobalIndc::Category. - includes(:indicators, children: :indicators). - where( - parent_id: nil, - slug: params[:category] - ). - flat_map(&:children). - flat_map(&:indicators). - map do |indicator| - if indicator.wb_indicator_id - "wb#{indicator.wb_indicator_id}" - elsif indicator.cait_indicator_id - "cait#{indicator.cait_indicator_id}" - end - end - - indicators = indicators.where( - id: indicator_ids - ) - end - - indicators - end - def location_list if params[:location].blank? nil diff --git a/app/javascript/app/components/accordion/accordion-component.jsx b/app/javascript/app/components/accordion/accordion-component.jsx index fa8db02904..d849d2493b 100644 --- a/app/javascript/app/components/accordion/accordion-component.jsx +++ b/app/javascript/app/components/accordion/accordion-component.jsx @@ -14,78 +14,57 @@ class Accordion extends PureComponent { className, data, handleOnClick, - activeSection, - compare + openSlug, + children, + isChild } = this.props; return (
- {data.map((section, index) => { - let isOpen = index === 0; - if (activeSection) { - if (activeSection !== 'none') { - const isActiveInResults = data.some( - d => d.slug === activeSection - ); - isOpen = - activeSection === section.slug || - (index === 0 && !isActiveInResults); - } else { - isOpen = false; + {data && + data.length > 0 && + data.map((section, index) => { + let isOpen = index === 0; + if (openSlug) { + if (openSlug !== 'none') { + const isActiveInResults = data.some(d => d.slug === openSlug); + isOpen = + openSlug === section.slug || + (index === 0 && !isActiveInResults); + } else { + isOpen = false; + } } - } - return section.definitions.length ? ( -
- - -
+
-
-
- ) : null; - })} + + +
+ {React.Children.map(children, (child, i) => { + if (i === index) return child; + return null; + })} + + + ); + })}
); } @@ -93,16 +72,17 @@ class Accordion extends PureComponent { Accordion.propTypes = { className: PropTypes.string, - activeSection: PropTypes.string, + openSlug: PropTypes.string, handleOnClick: PropTypes.func, data: PropTypes.arrayOf( PropTypes.shape({ title: PropTypes.string, slug: PropTypes.string, - definitions: PropTypes.array.isRequired + definitions: PropTypes.array }) ), - compare: PropTypes.bool + children: PropTypes.node, + isChild: PropTypes.bool }; Accordion.defaultProps = { diff --git a/app/javascript/app/components/accordion/accordion-styles.scss b/app/javascript/app/components/accordion/accordion-styles.scss index c8e8c461fa..b42f12f8d4 100644 --- a/app/javascript/app/components/accordion/accordion-styles.scss +++ b/app/javascript/app/components/accordion/accordion-styles.scss @@ -26,6 +26,17 @@ } } +.subHeader { + background-color: rgba($light-gray, 0.5); + padding-top: 10px; + padding-bottom: 10px; + font-size: $font-size-m; + + .title { + padding-left: 15px; + } +} + .iconArrow { transition: transform 0.25s ease-in-out; position: absolute; @@ -37,56 +48,3 @@ } } -.accordionContent { - background-color: $light-gray; - border-bottom: solid 1px rgba($theme-color, 0.3); -} - -.definitionCompare { - @extend %grid; - - @include msGridColumns(1fr, 1fr, 1fr, 1fr); - - grid-template-columns: repeat(4, 1fr); - padding: 30px 0; - border-bottom: solid 1px rgba(#9090b2, 0.15); - - &:last-child { - border-bottom: 0; - } -} - -.definition { - @extend %grid; - - @include msGridColumns(1fr, 3fr); - - grid-template-columns: 1fr 3fr; - padding: 20px 0; - border-bottom: solid 1px rgba(#9090b2, 0.15); - - &:last-child { - border-bottom: 0; - } -} - -.definitionTitle { - margin-right: 40px; - color: $theme-color; - font-weight: $font-weight-bold; - font-family: $font-family-1; -} - -.definitionDesc { - color: $theme-color; - font-family: $font-family-1; - line-height: 1.4em; -} - -.loader { - min-height: 400px; - position: absolute; - top: 0; - left: 0; - right: 0; -} diff --git a/app/javascript/app/components/accordion/accordion.js b/app/javascript/app/components/accordion/accordion.js index f1f81c0b19..0f01e4ca56 100644 --- a/app/javascript/app/components/accordion/accordion.js +++ b/app/javascript/app/components/accordion/accordion.js @@ -1,41 +1,45 @@ -import { createElement } from 'react'; +import { createElement, PureComponent } from 'react'; import { withRouter } from 'react-router'; import Proptypes from 'prop-types'; import { connect } from 'react-redux'; import qs from 'query-string'; +import { getLocationParamUpdated } from 'utils/navigation'; + import AccordionComponent from './accordion-component'; -const mapStateToProps = (state, { location }) => { +const mapStateToProps = (state, { location, param }) => { const search = qs.parse(location.search); - const activeSection = search.activeSection ? search.activeSection : null; + const openSlug = search[param] || null; return { - activeSection + openSlug }; }; -const AccordionContainer = props => { - const handleOnClick = slug => { - const { location, history } = props; +class AccordionContainer extends PureComponent { + handleOnClick = slug => { + const { param, location } = this.props; const search = qs.parse(location.search); - const newSlug = - search.activeSection === slug || !search.activeSection ? 'none' : slug; - const newSearch = { ...search, activeSection: newSlug }; + const newSlug = search[param] === slug || !search[param] ? 'none' : slug; + this.updateUrlParam({ name: param, value: newSlug }); + }; - history.replace({ - pathname: location.pathname, - search: qs.stringify(newSearch) - }); + updateUrlParam = (params, clear) => { + const { history, location } = this.props; + history.replace(getLocationParamUpdated(location, params, clear)); }; - return createElement(AccordionComponent, { - ...props, - handleOnClick - }); -}; + render() { + return createElement(AccordionComponent, { + handleOnClick: this.handleOnClick, + ...this.props + }); + } +} AccordionContainer.propTypes = { location: Proptypes.object, - history: Proptypes.object + history: Proptypes.object, + param: Proptypes.string }; export default withRouter(connect(mapStateToProps, null)(AccordionContainer)); diff --git a/app/javascript/app/components/charts/tooltip-chart/tooltip-chart-component.jsx b/app/javascript/app/components/charts/tooltip-chart/tooltip-chart-component.jsx index da29a073e1..4af0eee732 100644 --- a/app/javascript/app/components/charts/tooltip-chart/tooltip-chart-component.jsx +++ b/app/javascript/app/components/charts/tooltip-chart/tooltip-chart-component.jsx @@ -20,7 +20,10 @@ class TooltipChart extends PureComponent { const unit = config.axes && config.axes.yLeft && config.axes.yLeft.unit; return (
- {unit} + {showTotal && (

TOTAL

diff --git a/app/javascript/app/components/country-ghg-emissions/country-ghg-emissions-selectors.js b/app/javascript/app/components/country-ghg-emissions/country-ghg-emissions-selectors.js index 5b8ef826ff..48c3a6b6f6 100644 --- a/app/javascript/app/components/country-ghg-emissions/country-ghg-emissions-selectors.js +++ b/app/javascript/app/components/country-ghg-emissions/country-ghg-emissions-selectors.js @@ -27,7 +27,7 @@ const AXES_CONFIG = { }, yLeft: { name: 'Emissions', - unit: 'CO2e', + unit: 'CO2e', format: 'number' } }; diff --git a/app/javascript/app/components/definition-list/definition-list-component.jsx b/app/javascript/app/components/definition-list/definition-list-component.jsx new file mode 100644 index 0000000000..de837927e8 --- /dev/null +++ b/app/javascript/app/components/definition-list/definition-list-component.jsx @@ -0,0 +1,47 @@ +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import cx from 'classnames'; + +import styles from './definition-list-styles.scss'; + +class DefinitionList extends PureComponent { + // eslint-disable-line react/prefer-stateless-function + render() { + const { definitions, compare, className } = this.props; + return ( +
+ {definitions && + definitions.length > 0 && + definitions.map(def => ( +
+
{def.title}
+ {def.descriptions && + def.descriptions.map(desc => ( +
+
+
+ ))} +
+ ))} +
+ ); + } +} + +DefinitionList.propTypes = { + className: PropTypes.string, + definitions: PropTypes.array, + compare: PropTypes.bool +}; + +export default DefinitionList; diff --git a/app/javascript/app/components/definition-list/definition-list-styles.scss b/app/javascript/app/components/definition-list/definition-list-styles.scss new file mode 100644 index 0000000000..32d5f62996 --- /dev/null +++ b/app/javascript/app/components/definition-list/definition-list-styles.scss @@ -0,0 +1,45 @@ +@import '~styles/layout.scss'; + +.definitionCompare { + @extend %grid; + + @include msGridColumns(1fr, 1fr, 1fr, 1fr); + + grid-template-columns: repeat(4, 1fr); + padding: 20px 0; + margin-left: 30px; + border-bottom: solid 1px rgba(#9090b2, 0.15); + + &:last-child { + border-bottom: 0; + } +} + +.definition { + @extend %grid; + + @include msGridColumns(1fr, 3fr); + + grid-template-columns: 1fr 3fr; + padding: 20px 0; + margin: 0 30px; + border-bottom: solid 1px rgba(#9090b2, 0.15); + + &:last-child { + border-bottom: 0; + } +} + +.definitionTitle { + margin-right: 40px; + color: $theme-color; + font-weight: $font-weight-bold; + font-family: $font-family-1; +} + +.definitionDesc { + color: $theme-color; + font-family: $font-family-1; + line-height: 1.4em; + word-break: break-word; +} \ No newline at end of file diff --git a/app/javascript/app/components/definition-list/definition-list.js b/app/javascript/app/components/definition-list/definition-list.js new file mode 100644 index 0000000000..a75fff6614 --- /dev/null +++ b/app/javascript/app/components/definition-list/definition-list.js @@ -0,0 +1,3 @@ +import Component from './definition-list-component'; + +export default Component; diff --git a/app/javascript/app/components/dropdown/dropdown-component.jsx b/app/javascript/app/components/dropdown/dropdown-component.jsx index 1cf3043531..ec8ebb440a 100644 --- a/app/javascript/app/components/dropdown/dropdown-component.jsx +++ b/app/javascript/app/components/dropdown/dropdown-component.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { PureComponent } from 'react'; import { ReactSelectize, SimpleSelect } from 'react-selectize'; // eslint-disable-line import PropTypes from 'prop-types'; import Icon from 'components/icon'; @@ -11,31 +11,41 @@ import dropdownArrowWhite from 'assets/icons/dropdown-arrow-white.svg'; import theme from 'styles/themes/dropdown/react-selectize.scss'; import styles from './dropdown-styles.scss'; -const Dropdown = props => { - const arrow = props.white ? dropdownArrowWhite : dropdownArrow; +class Dropdown extends PureComponent { + componentDidUpdate() { + this.selectorElement.highlightFirstSelectableOption(); + } - return ( -
- {props.label && {props.label}} -
+ {this.props.label && ( + {this.props.label} )} - > - } - {...props} - /> +
+ { + this.selectorElement = el; + }} + className={cx(this.props.className, this.props.disabled)} + renderToggleButton={() => } + {...this.props} + /> +
-
- ); -}; + ); + } +} Dropdown.propTypes = { label: PropTypes.string, @@ -48,7 +58,8 @@ Dropdown.propTypes = { theme: PropTypes.object, hasSearch: PropTypes.bool, disabled: PropTypes.bool, - blueBorder: PropTypes.bool + blueBorder: PropTypes.bool, + selectorRef: PropTypes.func }; export default themr('Dropdown', styles)(Dropdown); diff --git a/app/javascript/app/components/ghg-emissions/ghg-emissions-selectors.js b/app/javascript/app/components/ghg-emissions/ghg-emissions-selectors.js index 4c0d53b00e..0fa1b2c2f2 100644 --- a/app/javascript/app/components/ghg-emissions/ghg-emissions-selectors.js +++ b/app/javascript/app/components/ghg-emissions/ghg-emissions-selectors.js @@ -64,7 +64,7 @@ const AXES_CONFIG = { }, yLeft: { name: 'Emissions', - unit: 'CO2e', + unit: 'CO2e', format: 'number' } }; diff --git a/app/javascript/app/components/multiselect/multiselect-component.jsx b/app/javascript/app/components/multiselect/multiselect-component.jsx index 34af1904db..f7cd2be646 100644 --- a/app/javascript/app/components/multiselect/multiselect-component.jsx +++ b/app/javascript/app/components/multiselect/multiselect-component.jsx @@ -18,6 +18,10 @@ class Multiselect extends Component { }; } + componentDidUpdate() { + this.selectorElement.highlightFirstSelectableOption(); + } + getSelectorValue() { const { values, options } = this.props; const { search } = this.state; @@ -45,6 +49,9 @@ class Multiselect extends Component {
{this.getSelectorValue()}
{ + this.selectorElement = el; + }} filterOptions={filterOptions} renderValue={() => } renderOption={option => { diff --git a/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-actions.js b/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-actions.js index c689453426..a8c9a0e776 100644 --- a/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-actions.js +++ b/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-actions.js @@ -13,11 +13,13 @@ const fetchNdcsCountryAccordionFailed = createAction( const fetchNdcsCountryAccordion = createThunkAction( 'fetchNdcsCountryAccordion', - (locations, category) => dispatch => { + (locations, category, compare) => dispatch => { if (locations) { dispatch(fetchNdcsCountryAccordionInit()); fetch( - `/api/v1/ndcs?location=${locations}&category=${category}&filter=overview` + `/api/v1/ndcs?location=${locations}&category=${category}${!compare + ? '&filter=overview' + : ''}` ) .then(response => { if (response.ok) return response.json(); diff --git a/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-component.jsx b/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-component.jsx index 9a2d27a4d5..7262c108d1 100644 --- a/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-component.jsx +++ b/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-component.jsx @@ -3,29 +3,86 @@ import PropTypes from 'prop-types'; import Accordion from 'components/accordion'; import NoContent from 'components/no-content'; import Loading from 'components/loading'; +import DefinitionList from 'components/definition-list'; +import layout from 'styles/layout.scss'; import styles from './ndcs-country-accordion-styles.scss'; class NdcsCountryAccordion extends PureComponent { // eslint-disable-line react/prefer-stateless-function render() { - const { ndcsData, loading, compare, locations } = this.props; + const { ndcsData, loading, compare, locations, category } = this.props; return (
{loading && } - {!ndcsData.length && !loading && ( + {!loading && (!ndcsData || !ndcsData.length) && ( )} - {ndcsData && ndcsData.length > 0 && ( - + {!loading && ndcsData && ndcsData.length > 0 && ( +
+ {ndcsData && ndcsData.length && + category === 'sectoral_information' ? ( + + {ndcsData && ndcsData.length > 0 && + ndcsData.map( + section => + (section.indicators.length > 0 ? ( + + {section.indicators.map(desc => ( +
+ +
+ ))} +
+ ) : null) + )} +
+ ) : ( + + {ndcsData && + ndcsData.map(section => ( +
+ +
+ ))} +
+ )} +
)}
); @@ -36,7 +93,8 @@ NdcsCountryAccordion.propTypes = { ndcsData: PropTypes.array, loading: PropTypes.bool, compare: PropTypes.bool, - locations: PropTypes.array + locations: PropTypes.array, + category: PropTypes.string }; export default NdcsCountryAccordion; diff --git a/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-selectors.js b/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-selectors.js index 2871253964..7c0fd485fe 100644 --- a/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-selectors.js +++ b/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-selectors.js @@ -4,16 +4,17 @@ import { deburrUpper } from 'app/utils'; const getCountries = state => state.countries; const getAllIndicators = state => (state.data ? state.data.indicators : {}); const getCategories = state => (state.data ? state.data.categories : {}); +const getSectors = state => (state.data ? state.data.sectors : {}); const getSearch = state => deburrUpper(state.search); export const parseIndicatorsDefs = createSelector( [getAllIndicators, getCategories, getCountries], (indicators, categories, countries) => { - if (!indicators || !categories || !countries) return {}; + if (!indicators || !categories || !countries) return null; const parsedIndicators = {}; Object.keys(categories).forEach(category => { const categoryIndicators = indicators.filter( - indicator => indicator.category_ids.indexOf(category) > -1 + indicator => indicator.category_ids.indexOf(parseInt(category, 10)) > -1 ); const parsedDefinitions = categoryIndicators.map(def => { const descriptions = countries.map(country => ({ @@ -32,10 +33,66 @@ export const parseIndicatorsDefs = createSelector( } ); +export const parseIndicatorsDefsWithSectors = createSelector( + [getAllIndicators, getCategories, getCountries, getSectors], + (indicators, categories, countries, sectors) => { + if (!indicators || !categories || !countries || !sectors) return null; + const parsedIndicators = []; + Object.keys(categories).forEach(category => { + const indicatorsWithCategory = indicators.filter( + indicator => indicator.category_ids.indexOf(parseInt(category, 10)) > -1 + ); + const parsedDefinitions = indicatorsWithCategory.map(indicator => { + const sectorIds = []; + let descriptions = []; + Object.keys(indicator.locations).forEach(location => { + indicator.locations[location].forEach(def => + sectorIds.push(def.sector_id) + ); + }); + if (sectorIds && sectorIds.length && sectorIds[0]) { + sectorIds.forEach(sector => { + const descriptionsBySector = countries.map(country => { + const value = indicator.locations[country] + ? indicator.locations[country].find( + indicValue => indicValue.sector_id === sector + ) + : ''; + return { + iso: country, + value: value ? value.value : null + }; + }); + descriptions.push({ + title: sectors[sector].name, + slug: sector, + descriptions: descriptionsBySector + }); + }); + } else { + descriptions = countries.map(country => ({ + iso: country, + values: indicator.locations[country] + ? indicator.locations[country] + : null + })); + } + return { + title: indicator.name, + slug: indicator.slug, + descriptions + }; + }); + parsedIndicators[category] = parsedDefinitions; + }); + return parsedIndicators; + } +); + export const getNDCs = createSelector( [getCategories, parseIndicatorsDefs], (categories, indicators) => { - if (!categories) return []; + if (!categories) return null; const ndcs = Object.keys(categories).map(category => ({ title: categories[category].name, slug: categories[category].slug, @@ -45,10 +102,23 @@ export const getNDCs = createSelector( } ); +export const getSectoralNDCs = createSelector( + [getCategories, parseIndicatorsDefsWithSectors], + (categories, indicators) => { + if (!categories || !indicators) return null; + const ndcs = Object.keys(categories).map(category => ({ + title: categories[category].name, + slug: categories[category].slug, + indicators: indicators[category] ? indicators[category] : [] + })); + return ndcs; + } +); + export const filterNDCs = createSelector( [getNDCs, getSearch], (ndcs, search) => { - if (!ndcs) return []; + if (!ndcs) return null; const filteredNDCs = ndcs.map(ndc => { const defs = ndc.definitions.filter( def => @@ -66,6 +136,39 @@ export const filterNDCs = createSelector( } ); +export const filterSectoralNDCs = createSelector( + [getSectoralNDCs, getSearch], + (ndcs, search) => { + if (!ndcs) return null; + const reducedNDCs = ndcs.filter( + ndc => ndc.indicators && ndc.indicators.length + ); + const filteredNDCs = reducedNDCs.map(ndc => { + const defs = []; + ndc.indicators.forEach(def => { + const descs = def.descriptions.filter( + desc => + deburrUpper(desc.title).indexOf(search) > -1 || + deburrUpper(desc.descriptions[0].value).indexOf(search) > -1 + ); + if (descs && descs.length) { + defs.push({ + ...def, + descriptions: descs + }); + } + }); + + return { + ...ndc, + indicators: defs + }; + }); + return filteredNDCs; + } +); + export default { - filterNDCs + filterNDCs, + filterSectoralNDCs }; diff --git a/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-styles.scss b/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-styles.scss index b3c518b0fc..e8349a7ddc 100644 --- a/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-styles.scss +++ b/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion-styles.scss @@ -30,3 +30,8 @@ $min-height: 450px; align-items: center; min-height: $min-height; } + +.definitionList { + background-color: $light-gray; + border-bottom: solid 1px rgba($theme-color, 0.3); +} diff --git a/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion.js b/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion.js index 4d2d60f958..e7eef91903 100644 --- a/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion.js +++ b/app/javascript/app/components/ndcs-country-accordion/ndcs-country-accordion.js @@ -8,23 +8,27 @@ import actions from './ndcs-country-accordion-actions'; import reducers, { initialState } from './ndcs-country-accordion-reducers'; import NdcsCountryAccordionComponent from './ndcs-country-accordion-component'; -import { filterNDCs } from './ndcs-country-accordion-selectors'; +import { + filterNDCs, + filterSectoralNDCs +} from './ndcs-country-accordion-selectors'; -const mapStateToProps = (state, { match, location }) => { +const mapStateToProps = (state, { match, location, category }) => { const { iso } = match.params; const search = qs.parse(location.search); const locations = search.locations ? search.locations.split(',') : null; const ndcsData = { data: state.ndcCountryAccordion.data, search: search.search, - countries: match.params.iso - ? [match.params.iso] - : locations + countries: match.params.iso ? [match.params.iso] : locations }; return { loading: state.ndcCountryAccordion.loading, + ndcsData: + category === 'sectoral_information' + ? filterSectoralNDCs(ndcsData) + : filterNDCs(ndcsData), search, - ndcsData: filterNDCs(ndcsData), iso, locations }; @@ -32,17 +36,23 @@ const mapStateToProps = (state, { match, location }) => { class NdcsCountryAccordionContainer extends PureComponent { componentWillMount() { - const { iso, fetchNdcsCountryAccordion, category, search } = this.props; + const { + iso, + fetchNdcsCountryAccordion, + category, + search, + compare + } = this.props; const locations = iso || search.locations; - fetchNdcsCountryAccordion(locations, category); + fetchNdcsCountryAccordion(locations, category, compare); } componentWillReceiveProps(nextProps) { - const { fetchNdcsCountryAccordion } = this.props; + const { fetchNdcsCountryAccordion, compare } = this.props; const newLocations = qs.parse(nextProps.location.search).locations; const oldLocations = qs.parse(this.props.location.search).locations; if (newLocations !== oldLocations) { - fetchNdcsCountryAccordion(newLocations, nextProps.category); + fetchNdcsCountryAccordion(newLocations, nextProps.category, compare); } } @@ -58,7 +68,8 @@ NdcsCountryAccordionContainer.propTypes = { iso: PropTypes.string, category: PropTypes.string, search: PropTypes.object, - location: PropTypes.object + location: PropTypes.object, + compare: PropTypes.bool }; export { actions, reducers, initialState }; diff --git a/app/javascript/app/components/ndcs-map/ndcs-map-selectors.js b/app/javascript/app/components/ndcs-map/ndcs-map-selectors.js index 1e5c956655..d31b97b711 100644 --- a/app/javascript/app/components/ndcs-map/ndcs-map-selectors.js +++ b/app/javascript/app/components/ndcs-map/ndcs-map-selectors.js @@ -47,7 +47,8 @@ export const getSelectedCategory = createSelector( } const firstCategorywithIndicators = categories.find(category => indicators.some( - indicator => indicator.category_ids.indexOf(category.id) > -1 + indicator => + indicator.category_ids.indexOf(parseInt(category.id, 10)) > -1 ) ); return firstCategorywithIndicators || categories[0]; @@ -59,9 +60,8 @@ export const getSelectedCategory = createSelector( export const getCategoryIndicators = createSelector( [getIndicatorsParsed, getSelectedCategory], (indicatorsParsed, category) => { - const categoryId = category.id; const categoryIndicators = indicatorsParsed.filter( - indicator => indicator.categoryIds.indexOf(categoryId) > -1 + indicator => indicator.categoryIds.indexOf(parseInt(category.id, 10)) > -1 ); return categoryIndicators; } @@ -121,7 +121,7 @@ export const getPathsWithStyles = createSelector( ? locations[europeSlug] : locations[iso]; - if (countryData) { + if (countryData && countryData.label_id) { const legendData = legendBuckets[countryData.label_id]; const color = getColorByIndex(legendBuckets, legendData.index); const style = { diff --git a/app/javascript/app/components/ndcs-table/ndcs-table-selectors.js b/app/javascript/app/components/ndcs-table/ndcs-table-selectors.js index eb1cfd05e6..47384425b6 100644 --- a/app/javascript/app/components/ndcs-table/ndcs-table-selectors.js +++ b/app/javascript/app/components/ndcs-table/ndcs-table-selectors.js @@ -42,7 +42,8 @@ export const getSelectedCategory = createSelector( } const firstCategorywithIndicators = categories.find(category => indicators.some( - indicator => indicator.category_ids.indexOf(category.id) > -1 + indicator => + indicator.category_ids.indexOf(parseInt(category.id, 10)) > -1 ) ); return firstCategorywithIndicators || categories[0]; @@ -54,9 +55,8 @@ export const getSelectedCategory = createSelector( export const getCategoryIndicators = createSelector( [getindicatorsParsed, getSelectedCategory], (indicatorsParsed, category) => { - const categoryId = category.id; const categoryIndicators = indicatorsParsed.filter( - indicator => indicator.categoryIds.indexOf(categoryId) > -1 + indicator => indicator.categoryIds.indexOf(parseInt(category.id, 10)) > -1 ); return categoryIndicators; } diff --git a/app/javascript/app/pages/ndc-compare/ndc-compare-actions.js b/app/javascript/app/pages/ndc-compare/ndc-compare-actions.js deleted file mode 100644 index 78486efe60..0000000000 --- a/app/javascript/app/pages/ndc-compare/ndc-compare-actions.js +++ /dev/null @@ -1,36 +0,0 @@ -import { createAction } from 'redux-actions'; -import { createThunkAction } from 'utils/redux'; - -/* @tmpfix: remove usage of indcTransform */ -import indcTransform from 'utils/indctransform'; - -const fetchCompareNDCInit = createAction('fetchCompareNDCInit'); -const fetchCompareNDCReady = createAction('fetchCompareNDCReady'); -const fetchCompareNDCFailed = createAction('fetchCompareNDCFailed'); - -const fetchCompareNDC = createThunkAction( - 'fetchCompareNDC', - isos => dispatch => { - dispatch(fetchCompareNDCInit()); - fetch(`/api/v1/ndcs?location=${isos}`) - .then(response => { - if (response.ok) return response.json(); - throw Error(response.statusText); - }) - .then(data => indcTransform(data)) - .then(data => { - dispatch(fetchCompareNDCReady(data)); - }) - .catch(error => { - dispatch(fetchCompareNDCFailed()); - console.info(error); - }); - } -); - -export default { - fetchCompareNDC, - fetchCompareNDCInit, - fetchCompareNDCReady, - fetchCompareNDCFailed -}; diff --git a/app/javascript/app/pages/ndc-compare/ndc-compare-reducers.js b/app/javascript/app/pages/ndc-compare/ndc-compare-reducers.js deleted file mode 100644 index a8a5e1e210..0000000000 --- a/app/javascript/app/pages/ndc-compare/ndc-compare-reducers.js +++ /dev/null @@ -1,27 +0,0 @@ -export const initialState = { - loading: false, - loaded: false, - data: {} -}; - -const setLoading = (loading, state) => ({ ...state, loading }); -const setLoaded = (loaded, state) => ({ ...state, loaded }); - -export default { - fetchCompareNDCInit: state => setLoading(true, state), - fetchCompareNDCReady: (state, { payload }) => { - const data = { ...state, data: payload }; - - return setLoaded(true, setLoading(false, data)); - }, - fetchCompareNDCFailed: state => { - const data = { - ...state, - data: { - fetched: true - } - }; - - return setLoaded(true, setLoading(false, data)); - } -}; diff --git a/app/javascript/app/pages/ndc-compare/ndc-compare-selectors.js b/app/javascript/app/pages/ndc-compare/ndc-compare-selectors.js index bd8838e54f..999961afb5 100644 --- a/app/javascript/app/pages/ndc-compare/ndc-compare-selectors.js +++ b/app/javascript/app/pages/ndc-compare/ndc-compare-selectors.js @@ -4,8 +4,6 @@ import compact from 'lodash/compact'; const getCountries = state => state.data || null; const getLocations = state => state.locations || null; const getIso = state => state.iso; -const getAllIndicators = state => state.data.indicators || null; -const getCategories = state => state.data.categories || null; const getCountryByIso = (countries, iso) => countries.find(country => country.iso_code3 === iso); @@ -47,45 +45,6 @@ export const getCountriesOptionsFiltered = createSelector( } ); -export const parseIndicatorsDefs = createSelector( - [getAllIndicators, getCategories, getLocations], - (indicators, categories, countries) => { - if (!indicators || !categories || !countries) return {}; - const parsedIndicators = {}; - Object.keys(categories).forEach(category => { - const categoryIndicators = indicators.filter( - indicator => indicator.category_ids.indexOf(category) > -1 - ); - const parsedDefinitions = categoryIndicators.map(def => { - const descriptions = countries.map(country => ({ - iso: country, - value: def.locations[country] ? def.locations[country].value : null - })); - return { - title: def.name, - slug: def.slug, - descriptions - }; - }); - parsedIndicators[category] = parsedDefinitions; - }); - return parsedIndicators; - } -); - -export const getNDCs = createSelector( - [getCategories, parseIndicatorsDefs], - (categories, indicators) => { - if (!categories) return []; - const ndcs = Object.keys(categories).map(category => ({ - title: categories[category].name, - slug: categories[category].slug, - definitions: indicators[category] ? indicators[category] : [] - })); - return ndcs; - } -); - export const getCountry = createSelector( [getCountries, getIso], getCountryByIso @@ -106,6 +65,5 @@ export default { getCountriesOptions, getCountriesOptionsFiltered, getActiveCountries, - getNDCs, getAnchorLinks }; diff --git a/app/javascript/app/pages/ndc-compare/ndc-compare.js b/app/javascript/app/pages/ndc-compare/ndc-compare.js index 9259c1018e..f28f27b421 100644 --- a/app/javascript/app/pages/ndc-compare/ndc-compare.js +++ b/app/javascript/app/pages/ndc-compare/ndc-compare.js @@ -3,15 +3,10 @@ import { connect } from 'react-redux'; import { withRouter } from 'react-router-dom'; import Proptypes from 'prop-types'; import qs from 'query-string'; -import isEmpty from 'lodash/isEmpty'; import { getLocationParamUpdated } from 'utils/navigation'; -import actions from './ndc-compare-actions'; -import reducers, { initialState } from './ndc-compare-reducers'; - import NDCCompareComponent from './ndc-compare-component'; import { - getNDCs, getCountriesOptionsFiltered, getActiveCountries, getAnchorLinks @@ -20,10 +15,6 @@ import { const mapStateToProps = (state, { location, route }) => { const search = qs.parse(location.search); const locations = search.locations ? search.locations.split(',') : []; - const ndcsData = { - data: state.NDCCompare.data, - locations - }; const activeCountriesData = { data: state.countries.data, locations @@ -37,9 +28,6 @@ const mapStateToProps = (state, { location, route }) => { route }; return { - fetched: !isEmpty(state.NDCCompare.data), - loading: state.NDCCompare.loading, - ndcsData: getNDCs(ndcsData), locations, countriesOptions: getCountriesOptionsFiltered(countriesOptionsData), activeCountriesOptions: getActiveCountries(activeCountriesData), @@ -74,8 +62,4 @@ NDCCompareContainer.propTypes = { locations: Proptypes.array }; -export { actions, reducers, initialState }; - -export default withRouter( - connect(mapStateToProps, actions)(NDCCompareContainer) -); +export default withRouter(connect(mapStateToProps, null)(NDCCompareContainer)); diff --git a/app/javascript/app/pages/ndc-country-full/ndc-country-full-component.jsx b/app/javascript/app/pages/ndc-country-full/ndc-country-full-component.jsx index 259a22268b..9022cd8c5a 100644 --- a/app/javascript/app/pages/ndc-country-full/ndc-country-full-component.jsx +++ b/app/javascript/app/pages/ndc-country-full/ndc-country-full-component.jsx @@ -9,6 +9,7 @@ import NoContent from 'components/no-content'; import isEmpty from 'lodash/isEmpty'; import ScrollToHighlightIndex from 'components/scroll-to-highlight-index'; import Sticky from 'react-stickynode'; +import Button from 'components/button'; import layout from 'styles/layout.scss'; import contentStyles from 'styles/themes/content.scss'; @@ -45,17 +46,21 @@ class NDCCountryFull extends PureComponent { contentOptions, contentOptionSelected, route, - fetchCountryNDCFull + fetchCountryNDCFull, + iso } = this.props; return (
-
+
{country && ( )}
+
@@ -94,7 +99,8 @@ NDCCountryFull.propTypes = { contentOptionSelected: PropTypes.object, loaded: PropTypes.bool, search: PropTypes.object, - fetchCountryNDCFull: PropTypes.func + fetchCountryNDCFull: PropTypes.func, + iso: PropTypes.string }; export default NDCCountryFull; diff --git a/app/javascript/app/pages/ndc-country-full/ndc-country-full-styles.scss b/app/javascript/app/pages/ndc-country-full/ndc-country-full-styles.scss index 6f36e015f3..62d906e1d2 100644 --- a/app/javascript/app/pages/ndc-country-full/ndc-country-full-styles.scss +++ b/app/javascript/app/pages/ndc-country-full/ndc-country-full-styles.scss @@ -3,27 +3,9 @@ .twoFold { @extend %grid; - @include msGridColumns(7fr, 5fr); + @include msGridColumns(3fr, 1fr); - grid-template-columns: 7fr 5fr; -} - -.twoFoldReversed { - @extend %grid; - - @include msGridColumns(5fr, 7fr); - - grid-template-columns: 5fr 7fr; -} - -.backButton { - margin-right: 20px; -} - -.backIcon { - fill: $white; - width: 60px; - height: 60px; + grid-template-columns: 3fr 1fr; } .actionsWrapper { diff --git a/app/javascript/app/pages/ndc-country-full/ndc-country-full.js b/app/javascript/app/pages/ndc-country-full/ndc-country-full.js index 87e490e245..f3d28b17b1 100644 --- a/app/javascript/app/pages/ndc-country-full/ndc-country-full.js +++ b/app/javascript/app/pages/ndc-country-full/ndc-country-full.js @@ -31,7 +31,8 @@ const mapStateToProps = (state, { match }) => { content: getSelectedContent(contentData), contentOptions: getContentOptions(contentData), contentOptionSelected: getContentOptionSelected(contentData), - search + search, + iso }; }; diff --git a/app/javascript/app/pages/ndc-country/ndc-country-actions.js b/app/javascript/app/pages/ndc-country/ndc-country-actions.js deleted file mode 100644 index 52802273a8..0000000000 --- a/app/javascript/app/pages/ndc-country/ndc-country-actions.js +++ /dev/null @@ -1,36 +0,0 @@ -import { createAction } from 'redux-actions'; -import { createThunkAction } from 'utils/redux'; - -const fetchCountryNDCInit = createAction('fetchCountryNDCInit'); -const fetchCountryNDCReady = createAction('fetchCountryNDCReady'); -const fetchCountryNDCFailed = createAction('fetchCountryNDCFailed'); - -const fetchCountryNDC = createThunkAction( - 'fetchCountryNDC', - iso => dispatch => { - dispatch(fetchCountryNDCInit()); - fetch(`/api/v1/ndcs?location=${iso}&filter=overview`) - .then(response => { - if (response.ok) return response.json(); - throw Error(response.statusText); - }) - .then(data => { - const dataWithIso = { - iso, - data - }; - dispatch(fetchCountryNDCReady(dataWithIso)); - }) - .catch(error => { - dispatch(fetchCountryNDCFailed(iso)); - console.info(error); - }); - } -); - -export default { - fetchCountryNDC, - fetchCountryNDCInit, - fetchCountryNDCReady, - fetchCountryNDCFailed -}; diff --git a/app/javascript/app/pages/ndc-country/ndc-country-component.jsx b/app/javascript/app/pages/ndc-country/ndc-country-component.jsx index 3222686340..7c00a075fd 100644 --- a/app/javascript/app/pages/ndc-country/ndc-country-component.jsx +++ b/app/javascript/app/pages/ndc-country/ndc-country-component.jsx @@ -8,7 +8,10 @@ import Search from 'components/search'; import cx from 'classnames'; import Sticky from 'react-stickynode'; import AnchorNav from 'components/anchor-nav'; +import NdcsDocumentsMetaProvider from 'providers/ndcs-documents-meta-provider'; +import Dropdown from 'components/dropdown'; +import theme from 'styles/themes/dropdown/dropdown-links.scss'; import lightSearch from 'styles/themes/search/search-light.scss'; import layout from 'styles/layout.scss'; import styles from './ndc-country-styles.scss'; @@ -21,10 +24,13 @@ class NDCCountry extends PureComponent { onSearchChange, search, route, - anchorLinks + anchorLinks, + documentsOptions, + handleDropDownChange } = this.props; return (
+ {country && (
- + + -
@@ -76,7 +84,9 @@ NDCCountry.propTypes = { country: PropTypes.object, onSearchChange: PropTypes.func.isRequired, search: PropTypes.string, - anchorLinks: PropTypes.array + anchorLinks: PropTypes.array, + documentsOptions: PropTypes.array, + handleDropDownChange: PropTypes.func }; export default NDCCountry; diff --git a/app/javascript/app/pages/ndc-country/ndc-country-reducers.js b/app/javascript/app/pages/ndc-country/ndc-country-reducers.js deleted file mode 100644 index c6620781e9..0000000000 --- a/app/javascript/app/pages/ndc-country/ndc-country-reducers.js +++ /dev/null @@ -1,34 +0,0 @@ -export const initialState = { - loading: false, - loaded: false, - data: {} -}; - -const setLoading = (loading, state) => ({ ...state, loading }); -const setLoaded = (loaded, state) => ({ ...state, loaded }); - -export default { - fetchCountryNDCInit: state => setLoading(true, state), - fetchCountryNDCReady: (state, { payload }) => { - const newState = { - ...state, - data: { - ...state.data, - [payload.iso]: payload.data - } - }; - - return setLoaded(true, setLoading(false, newState)); - }, - fetchCountryNDCFailed: (state, { payload }) => { - const newState = { - ...state, - data: { - ...state.data, - [payload]: [] - } - }; - - return setLoaded(true, setLoading(false, newState)); - } -}; diff --git a/app/javascript/app/pages/ndc-country/ndc-country-selectors.js b/app/javascript/app/pages/ndc-country/ndc-country-selectors.js index d541ac72ee..5ee88c639b 100644 --- a/app/javascript/app/pages/ndc-country/ndc-country-selectors.js +++ b/app/javascript/app/pages/ndc-country/ndc-country-selectors.js @@ -1,7 +1,10 @@ import { createSelector } from 'reselect'; +import isEmpty from 'lodash/isEmpty'; +import upperCase from 'lodash/upperCase'; -const getCountries = state => state.countries; -const getIso = state => state.iso; +const getCountries = state => state.countries || null; +const getIso = state => state.iso || null; +const getDocuments = state => state.data || null; const getCountryByIso = (countries, iso) => countries.find(country => country.iso_code3 === iso); @@ -25,7 +28,20 @@ export const getAnchorLinks = createSelector( })) ); +export const getDocumentsOptions = createSelector( + [getDocuments, getIso], + (documents, iso) => { + if (isEmpty(documents) || !iso) return null; + return documents[iso].map(doc => ({ + label: `${upperCase(doc.document_type)}(${doc.language})`, + value: `${doc.document_type}(${doc.language})`, + path: `/ndcs/country/${iso}/full?document=${doc.document_type}-${doc.language}` + })); + } +); + export default { getCountry, - getAnchorLinks + getAnchorLinks, + getDocumentsOptions }; diff --git a/app/javascript/app/pages/ndc-country/ndc-country-styles.scss b/app/javascript/app/pages/ndc-country/ndc-country-styles.scss index 0212190467..e6eb961428 100644 --- a/app/javascript/app/pages/ndc-country/ndc-country-styles.scss +++ b/app/javascript/app/pages/ndc-country/ndc-country-styles.scss @@ -3,17 +3,17 @@ .doubleFold { @extend %grid; - @include msGridColumns(1fr, 1fr); + @include msGridColumns(5fr, 7fr); - grid-template-columns: repeat(2, 1fr); + grid-template-columns: 5fr 7fr; } .threeFold { @extend %grid; - @include msGridColumns(1fr, 1fr, 1fr); + @include msGridColumns(3fr, 2fr, 2fr); - grid-template-columns: repeat(3, 1fr); + grid-template-columns: 3fr 2fr 2fr; } .backButton { diff --git a/app/javascript/app/pages/ndc-country/ndc-country.js b/app/javascript/app/pages/ndc-country/ndc-country.js index 6459b7094b..57c40f8a76 100644 --- a/app/javascript/app/pages/ndc-country/ndc-country.js +++ b/app/javascript/app/pages/ndc-country/ndc-country.js @@ -5,11 +5,12 @@ import { withRouter } from 'react-router-dom'; import qs from 'query-string'; import { getLocationParamUpdated } from 'utils/navigation'; -import actions from './ndc-country-actions'; -import reducers, { initialState } from './ndc-country-reducers'; - import NDCCountryComponent from './ndc-country-component'; -import { getCountry, getAnchorLinks } from './ndc-country-selectors'; +import { + getCountry, + getAnchorLinks, + getDocumentsOptions +} from './ndc-country-selectors'; const mapStateToProps = (state, { match, location, route }) => { const { iso } = match.params; @@ -23,10 +24,15 @@ const mapStateToProps = (state, { match, location, route }) => { location, route }; + const documentsData = { + iso, + data: state.ndcsDocumentsMeta.data + }; return { country: getCountry(countryData), search: search.search, - anchorLinks: getAnchorLinks(routeData) + anchorLinks: getAnchorLinks(routeData), + documentsOptions: getDocumentsOptions(documentsData) }; }; @@ -40,10 +46,15 @@ class NDCCountryContainer extends PureComponent { history.replace(getLocationParamUpdated(location, params, clear)); }; + handleDropDownChange = selected => { + this.props.history.push(selected.path); + }; + render() { return createElement(NDCCountryComponent, { ...this.props, - onSearchChange: this.onSearchChange + onSearchChange: this.onSearchChange, + handleDropDownChange: this.handleDropDownChange }); } } @@ -53,8 +64,4 @@ NDCCountryContainer.propTypes = { location: Proptypes.object.isRequired }; -export { actions, reducers, initialState }; - -export default withRouter( - connect(mapStateToProps, actions)(NDCCountryContainer) -); +export default withRouter(connect(mapStateToProps, null)(NDCCountryContainer)); diff --git a/app/javascript/app/providers/ndcs-documents-meta-provider/ndcs-documents-meta-provider-actions.js b/app/javascript/app/providers/ndcs-documents-meta-provider/ndcs-documents-meta-provider-actions.js new file mode 100644 index 0000000000..ee3709fb69 --- /dev/null +++ b/app/javascript/app/providers/ndcs-documents-meta-provider/ndcs-documents-meta-provider-actions.js @@ -0,0 +1,34 @@ +import { createAction } from 'redux-actions'; +import { createThunkAction } from 'utils/redux'; + +const fetchNdcsDocumentsMetaInit = createAction('fetchNdcsDocumentsMetaInit'); +const fetchNdcsDocumentsMetaReady = createAction('fetchNdcsDocumentsMetaReady'); +const fetchNdcsDocumentsMetaFailed = createAction( + 'fetchNdcsDocumentsMetaFailed' +); + +const fetchNdcsDocumentsMeta = createThunkAction( + 'fetchNdcsDocumentsMeta', + () => dispatch => { + dispatch(fetchNdcsDocumentsMetaInit()); + fetch('/api/v1/ndcs/text') + .then(response => { + if (response.ok) return response.json(); + throw Error(response.statusText); + }) + .then(data => { + dispatch(fetchNdcsDocumentsMetaReady(data)); + }) + .catch(error => { + dispatch(fetchNdcsDocumentsMetaFailed()); + console.info(error); + }); + } +); + +export default { + fetchNdcsDocumentsMeta, + fetchNdcsDocumentsMetaInit, + fetchNdcsDocumentsMetaReady, + fetchNdcsDocumentsMetaFailed +}; diff --git a/app/javascript/app/providers/ndcs-documents-meta-provider/ndcs-documents-meta-provider-reducers.js b/app/javascript/app/providers/ndcs-documents-meta-provider/ndcs-documents-meta-provider-reducers.js new file mode 100644 index 0000000000..e90badff07 --- /dev/null +++ b/app/javascript/app/providers/ndcs-documents-meta-provider/ndcs-documents-meta-provider-reducers.js @@ -0,0 +1,22 @@ +import groupBy from 'lodash/groupBy'; + +export const initialState = { + loading: false, + loaded: false, + data: {} +}; + +const setLoading = (loading, state) => ({ ...state, loading }); +const setLoaded = (loaded, state) => ({ ...state, loaded }); + +export default { + fetchNdcsDocumentsMetaInit: state => setLoading(true, state), + fetchNdcsDocumentsMetaReady: (state, { payload }) => { + const newState = { + ...state, + data: groupBy(payload, 'location.iso_code3') + }; + + return setLoaded(true, setLoading(false, newState)); + } +}; diff --git a/app/javascript/app/providers/ndcs-documents-meta-provider/ndcs-documents-meta-provider.js b/app/javascript/app/providers/ndcs-documents-meta-provider/ndcs-documents-meta-provider.js new file mode 100644 index 0000000000..da8c53aba8 --- /dev/null +++ b/app/javascript/app/providers/ndcs-documents-meta-provider/ndcs-documents-meta-provider.js @@ -0,0 +1,27 @@ +import { PureComponent } from 'react'; +import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; +import { withRouter } from 'react-router'; + +import actions from './ndcs-documents-meta-provider-actions'; +import reducers, { + initialState +} from './ndcs-documents-meta-provider-reducers'; + +class NdcsDocumentsMetaProvider extends PureComponent { + componentDidMount() { + const { fetchNdcsDocumentsMeta } = this.props; + fetchNdcsDocumentsMeta(); + } + + render() { + return null; + } +} + +NdcsDocumentsMetaProvider.propTypes = { + fetchNdcsDocumentsMeta: PropTypes.func.isRequired +}; + +export { actions, reducers, initialState }; +export default withRouter(connect(null, actions)(NdcsDocumentsMetaProvider)); diff --git a/app/javascript/app/reducers.js b/app/javascript/app/reducers.js index c907630831..6c49dbe2a2 100644 --- a/app/javascript/app/reducers.js +++ b/app/javascript/app/reducers.js @@ -13,6 +13,7 @@ import * as geoLocationProvider from 'providers/geolocation-provider'; import * as wbCountryProvider from 'providers/wb-country-data-provider'; import * as timelineProvider from 'providers/timeline-provider'; import * as socioeconomicsProvider from 'providers/socioeconomics-provider'; +import * as ndcsDocumentsMetaProvider from 'providers/ndcs-documents-meta-provider'; const providersReducers = { countries: handleActions(countriesProvider), @@ -24,21 +25,20 @@ const providersReducers = { geoLocation: handleActions(geoLocationProvider), wbCountryData: handleActions(wbCountryProvider), socioeconomics: handleActions(socioeconomicsProvider), - timeline: handleActions(timelineProvider) + timeline: handleActions(timelineProvider), + ndcsDocumentsMeta: handleActions(ndcsDocumentsMetaProvider) }; // Pages import * as NDCSPage from 'pages/ndcs'; import * as countryNDCFullPage from 'pages/ndc-country-full'; -import * as NDCComparePage from 'pages/ndc-compare'; import * as ndcSearchPage from 'pages/ndc-search'; import * as ndcSdgPage from 'pages/ndc-sdg'; const pagesReducers = { ndcs: handleActions(NDCSPage), countryNDCFull: handleActions(countryNDCFullPage), - NDCCompare: handleActions(NDCComparePage), ndcSearch: handleActions(ndcSearchPage), ndcSdg: handleActions(ndcSdgPage) }; diff --git a/app/javascript/app/routes.js b/app/javascript/app/routes.js index bd4bfe40e5..75c217faf7 100644 --- a/app/javascript/app/routes.js +++ b/app/javascript/app/routes.js @@ -82,8 +82,7 @@ export default [ path: '/ndcs/country/:iso/mitigation', component: () => createElement(NDCCountryAccordion, { - category: 'mitigation', - type: 'overview' + category: 'mitigation' }), exact: true, anchor: true, @@ -94,14 +93,24 @@ export default [ path: '/ndcs/country/:iso/adaptation', component: () => createElement(NDCCountryAccordion, { - category: 'adaptation', - type: 'overview' + category: 'adaptation' }), exact: true, anchor: true, label: 'Adaptation', param: 'adaptation' }, + { + path: '/ndcs/country/:iso/sectoral-information', + component: () => + createElement(NDCCountryAccordion, { + category: 'sectoral_information' + }), + exact: true, + anchor: false, + label: 'Sectoral Information', + param: 'sectoral-information' + }, { path: '/ndcs/country/:iso', component: () => createElement(Redirect, { to: '/ndcs' }) @@ -137,6 +146,18 @@ export default [ label: 'Adaptation', param: 'adaptation' }, + { + path: '/ndcs/compare/sectoral-information', + component: () => + createElement(NDCCountryAccordion, { + category: 'sectoral_information', + compare: true + }), + exact: true, + anchor: false, + label: 'Sectoral Information', + param: 'sectoral-information' + }, { path: '/ndcs/compare', component: () => diff --git a/app/models/cait_indc.rb b/app/models/cait_indc.rb deleted file mode 100644 index 63f61a3751..0000000000 --- a/app/models/cait_indc.rb +++ /dev/null @@ -1,5 +0,0 @@ -module CaitIndc - def self.table_name_prefix - 'cait_indc_' - end -end diff --git a/app/models/cait_indc/category.rb b/app/models/cait_indc/category.rb deleted file mode 100644 index c1f4cf4453..0000000000 --- a/app/models/cait_indc/category.rb +++ /dev/null @@ -1,8 +0,0 @@ -module CaitIndc - class Category < ApplicationRecord - has_and_belongs_to_many :indicators, - join_table: :cait_indc_indicators_categories - validates :name, presence: true - validates :category_type, inclusion: {in: %w(map overview)} - end -end diff --git a/app/models/cait_indc/chart.rb b/app/models/cait_indc/chart.rb deleted file mode 100644 index c37794ae75..0000000000 --- a/app/models/cait_indc/chart.rb +++ /dev/null @@ -1,6 +0,0 @@ -module CaitIndc - class Chart < ApplicationRecord - has_many :indicators, class_name: 'CaitIndc::Indicator' - validates :name, presence: true - end -end diff --git a/app/models/cait_indc/indicator.rb b/app/models/cait_indc/indicator.rb deleted file mode 100644 index f5f4f93a68..0000000000 --- a/app/models/cait_indc/indicator.rb +++ /dev/null @@ -1,11 +0,0 @@ -module CaitIndc - class Indicator < ApplicationRecord - belongs_to :chart, class_name: 'CaitIndc::Chart', optional: true - has_and_belongs_to_many :categories, - join_table: :cait_indc_indicators_categories - has_many :labels, class_name: 'CaitIndc::Label' - has_many :values, class_name: 'CaitIndc::Value' - - validates :name, presence: true - end -end diff --git a/app/models/cait_indc/label.rb b/app/models/cait_indc/label.rb deleted file mode 100644 index 49c9b7a727..0000000000 --- a/app/models/cait_indc/label.rb +++ /dev/null @@ -1,6 +0,0 @@ -module CaitIndc - class Label < ApplicationRecord - belongs_to :indicator, class_name: 'CaitIndc::Indicator' - validates :name, presence: true - end -end diff --git a/app/models/cait_indc/value.rb b/app/models/cait_indc/value.rb deleted file mode 100644 index fa639ddd94..0000000000 --- a/app/models/cait_indc/value.rb +++ /dev/null @@ -1,7 +0,0 @@ -module CaitIndc - class Value < ApplicationRecord - belongs_to :location - belongs_to :indicator, class_name: 'CaitIndc::Indicator' - belongs_to :label, class_name: 'CaitIndc::Label', optional: true - end -end diff --git a/app/models/global_indc.rb b/app/models/global_indc.rb deleted file mode 100644 index 590fb2f1cf..0000000000 --- a/app/models/global_indc.rb +++ /dev/null @@ -1,5 +0,0 @@ -module GlobalIndc - def self.table_name_prefix - 'global_indc_' - end -end diff --git a/app/models/global_indc/category.rb b/app/models/global_indc/category.rb deleted file mode 100644 index aaf35cc334..0000000000 --- a/app/models/global_indc/category.rb +++ /dev/null @@ -1,16 +0,0 @@ -module GlobalIndc - class Category < ApplicationRecord - has_and_belongs_to_many :indicators, - join_table: :global_indc_indicators_categories - belongs_to :parent, - class_name: 'GlobalIndc::Category', - foreign_key: 'parent_id', - required: false - has_many :children, - class_name: 'GlobalIndc::Category', - foreign_key: 'parent_id' - - validates :name, presence: true - validates :slug, presence: true - end -end diff --git a/app/models/global_indc/indicator.rb b/app/models/global_indc/indicator.rb deleted file mode 100644 index fab114cbb3..0000000000 --- a/app/models/global_indc/indicator.rb +++ /dev/null @@ -1,23 +0,0 @@ -module GlobalIndc - class Indicator < ApplicationRecord - has_and_belongs_to_many :categories, - join_table: :global_indc_indicators_categories - belongs_to :cait_indicator, - class_name: 'CaitIndc::Indicator', - required: false - belongs_to :wb_indicator, - class_name: 'WbIndc::Indicator', - required: false - - validate :cait_xor_wb_indicator_presence - - def cait_xor_wb_indicator_presence - return if cait_indicator.blank? ^ wb_indicator.blank? - - errors.add( - :base, - 'Reference either a cait or wb indicator, never both or none' - ) - end - end -end diff --git a/app/models/indc/category.rb b/app/models/indc/category.rb index 20a9a6da24..90c0477120 100644 --- a/app/models/indc/category.rb +++ b/app/models/indc/category.rb @@ -1,12 +1,16 @@ module Indc class Category < ApplicationRecord - self.primary_key = :id - + belongs_to :category_type, class_name: 'Indc::CategoryType' + belongs_to :parent, class_name: 'Indc::Category', + foreign_key: :parent_id, + required: false + has_many :children, class_name: 'Indc::Category', + foreign_key: :parent_id has_and_belongs_to_many :indicators, join_table: :indc_indicators_categories - def readonly? - true - end + validates :slug, presence: true + validates :name, presence: true + validates :slug, uniqueness: {scope: :category_type} end end diff --git a/app/models/indc/category_type.rb b/app/models/indc/category_type.rb new file mode 100644 index 0000000000..b44fde4c71 --- /dev/null +++ b/app/models/indc/category_type.rb @@ -0,0 +1,8 @@ +module Indc + class CategoryType < ApplicationRecord + has_many :categories, class_name: 'Indc::Category' + + validates :name, uniqueness: true + validates :name, presence: true + end +end diff --git a/app/models/indc/indicator.rb b/app/models/indc/indicator.rb index 69a2595a8d..eec0d6732f 100644 --- a/app/models/indc/indicator.rb +++ b/app/models/indc/indicator.rb @@ -1,14 +1,13 @@ module Indc class Indicator < ApplicationRecord - self.primary_key = :id - + belongs_to :source, class_name: 'Indc::Source' has_many :values, class_name: 'Indc::Value' has_many :labels, class_name: 'Indc::Label' has_and_belongs_to_many :categories, join_table: :indc_indicators_categories - def readonly? - true - end + validates :slug, presence: true + validates :name, presence: true + validates :slug, uniqueness: true end end diff --git a/app/models/indc/label.rb b/app/models/indc/label.rb index 6e67c814b9..e4d466fbd9 100644 --- a/app/models/indc/label.rb +++ b/app/models/indc/label.rb @@ -1,11 +1,8 @@ module Indc class Label < ApplicationRecord - self.primary_key = :id - belongs_to :indicator, class_name: 'Indc::Indicator' - def readonly? - true - end + validates :value, presence: true + validates :index, presence: true end end diff --git a/app/models/indc/sector.rb b/app/models/indc/sector.rb index 372000ba9f..9e4dcd5964 100644 --- a/app/models/indc/sector.rb +++ b/app/models/indc/sector.rb @@ -1,11 +1,8 @@ module Indc class Sector < ApplicationRecord - self.primary_key = :id belongs_to :parent, class_name: 'Indc::Sector', optional: true has_many :values, class_name: 'Indc::Value' - def readonly? - true - end + validates :name, presence: true end end diff --git a/app/models/indc/source.rb b/app/models/indc/source.rb new file mode 100644 index 0000000000..5b22cd2cbb --- /dev/null +++ b/app/models/indc/source.rb @@ -0,0 +1,6 @@ +module Indc + class Source < ApplicationRecord + validates :name, presence: true + validates :name, uniqueness: true + end +end diff --git a/app/models/cait_indc/submission.rb b/app/models/indc/submission.rb similarity index 96% rename from app/models/cait_indc/submission.rb rename to app/models/indc/submission.rb index 5d509d60c1..c5c6604531 100644 --- a/app/models/cait_indc/submission.rb +++ b/app/models/indc/submission.rb @@ -1,6 +1,7 @@ -module CaitIndc +module Indc class Submission < ApplicationRecord belongs_to :location + validates :submission_type, presence: true validates :language, presence: true validates :submission_date, presence: true diff --git a/app/models/indc/value.rb b/app/models/indc/value.rb index 9d0edd03b4..69db920088 100644 --- a/app/models/indc/value.rb +++ b/app/models/indc/value.rb @@ -1,14 +1,10 @@ module Indc class Value < ApplicationRecord - self.primary_key = :id - belongs_to :location belongs_to :indicator, class_name: 'Indc::Indicator' belongs_to :label, class_name: 'Indc::Label', optional: true belongs_to :sector, class_name: 'Indc::Sector', optional: true - def readonly? - true - end + validates :value, presence: true end end diff --git a/app/models/location.rb b/app/models/location.rb index 240e3b8b83..fd7eaf4b57 100644 --- a/app/models/location.rb +++ b/app/models/location.rb @@ -5,9 +5,9 @@ class Location < ApplicationRecord has_many :historical_emissions, class_name: 'HistoricalEmissions::Record', dependent: :destroy - has_many :values, class_name: 'CaitIndc::Value' + has_many :values, class_name: 'Indc::Value' has_many :indicators, - class_name: 'CaitIndc::Indicator', + class_name: 'Indc::Indicator', through: :values validates :iso_code3, presence: true, uniqueness: true diff --git a/app/models/wb_indc.rb b/app/models/wb_indc.rb deleted file mode 100644 index 556d870edc..0000000000 --- a/app/models/wb_indc.rb +++ /dev/null @@ -1,5 +0,0 @@ -module WbIndc - def self.table_name_prefix - 'wb_indc_' - end -end diff --git a/app/models/wb_indc/category.rb b/app/models/wb_indc/category.rb deleted file mode 100644 index 5193a025d5..0000000000 --- a/app/models/wb_indc/category.rb +++ /dev/null @@ -1,7 +0,0 @@ -module WbIndc - class Category < ApplicationRecord - has_and_belongs_to_many :indicators, - join_table: :wb_indc_indicators_categories - validates :name, presence: true - end -end diff --git a/app/models/wb_indc/indicator.rb b/app/models/wb_indc/indicator.rb deleted file mode 100644 index eed4dd2dc9..0000000000 --- a/app/models/wb_indc/indicator.rb +++ /dev/null @@ -1,10 +0,0 @@ -module WbIndc - class Indicator < ApplicationRecord - belongs_to :indicator_type, class_name: 'WbIndc::IndicatorType' - has_many :values, class_name: 'WbIndc::Value' - has_and_belongs_to_many :categories, - join_table: :wb_indc_indicators_categories - validates :name, presence: true - validates :code, presence: true - end -end diff --git a/app/models/wb_indc/indicator_type.rb b/app/models/wb_indc/indicator_type.rb deleted file mode 100644 index 62541255df..0000000000 --- a/app/models/wb_indc/indicator_type.rb +++ /dev/null @@ -1,6 +0,0 @@ -module WbIndc - class IndicatorType < ApplicationRecord - has_many :indicators, class_name: 'WbIndc::Indicator' - validates :name, presence: true - end -end diff --git a/app/models/wb_indc/sector.rb b/app/models/wb_indc/sector.rb deleted file mode 100644 index 6a7a27c46f..0000000000 --- a/app/models/wb_indc/sector.rb +++ /dev/null @@ -1,6 +0,0 @@ -module WbIndc - class Sector < ApplicationRecord - belongs_to :parent, class_name: 'WbIndc::Sector', optional: true - validates :name, presence: true - end -end diff --git a/app/models/wb_indc/value.rb b/app/models/wb_indc/value.rb deleted file mode 100644 index 387b3f2782..0000000000 --- a/app/models/wb_indc/value.rb +++ /dev/null @@ -1,7 +0,0 @@ -module WbIndc - class Value < ApplicationRecord - belongs_to :location - belongs_to :sector, class_name: 'WbIndc::Sector', optional: true - belongs_to :indicator, class_name: 'WbIndc::Indicator' - end -end diff --git a/app/serializers/api/v1/indc/category_serializer.rb b/app/serializers/api/v1/indc/category_serializer.rb index 665e5bdb51..a33d7649ea 100644 --- a/app/serializers/api/v1/indc/category_serializer.rb +++ b/app/serializers/api/v1/indc/category_serializer.rb @@ -3,9 +3,12 @@ module V1 module Indc class CategorySerializer < ActiveModel::Serializer attribute :name - attribute :source attribute :slug attribute :category_type, key: :type + + def category_type + object.category_type.name + end end end end diff --git a/app/serializers/api/v1/indc/indicator_serializer.rb b/app/serializers/api/v1/indc/indicator_serializer.rb index bc43d071af..571614871d 100644 --- a/app/serializers/api/v1/indc/indicator_serializer.rb +++ b/app/serializers/api/v1/indc/indicator_serializer.rb @@ -11,6 +11,10 @@ class IndicatorSerializer < ActiveModel::Serializer attribute :labels attribute :locations + def source + object.source.name + end + def labels IndexedSerializer.serialize( object.labels, diff --git a/app/serializers/api/v1/indc/label_serializer.rb b/app/serializers/api/v1/indc/label_serializer.rb index 58733ab700..3f1c152423 100644 --- a/app/serializers/api/v1/indc/label_serializer.rb +++ b/app/serializers/api/v1/indc/label_serializer.rb @@ -2,8 +2,8 @@ module Api module V1 module Indc class LabelSerializer < ActiveModel::Serializer - attributes :name - attributes :index + attribute :value, key: :name + attribute :index end end end diff --git a/app/services/import_cait_indc.rb b/app/services/import_cait_indc.rb deleted file mode 100644 index 72bcbf586e..0000000000 --- a/app/services/import_cait_indc.rb +++ /dev/null @@ -1,231 +0,0 @@ -class ImportCaitIndc - # rubocop:disable LineLength - META_INDICATORS_FILEPATH = "#{CW_FILES_PREFIX}cait_indc/CW_NDC_CAIT_metadata.csv".freeze - META_LEGEND_FILEPATH = "#{CW_FILES_PREFIX}cait_indc/CW_NDC_CAIT_legend.csv".freeze - META_MAP_FILEPATH = "#{CW_FILES_PREFIX}cait_indc/CW_NDC_map.csv".freeze - DATA_FILEPATH = "#{CW_FILES_PREFIX}cait_indc/CW_NDC_CAIT_data.csv".freeze - SUBMISSIONS_FILEPATH = "#{CW_FILES_PREFIX}cait_indc/CW_NDC_Submission_URL.csv".freeze - # rubocop:enable LineLength - - def call - cleanup - - load_csvs - - import_categories(@indicators, 'overview') - import_categories(@map, 'map') - import_charts - import_indicators - import_association_indicators_categories - - load_indicator_keys - import_labels - update_label_indexes - import_values - import_submissions - - refresh_materialized_views - end - - private - - def load_csvs - @indicators = S3CSVReader.read(META_INDICATORS_FILEPATH).map(&:to_h) - @legend = S3CSVReader.read(META_LEGEND_FILEPATH).map(&:to_h) - @data = S3CSVReader.read(DATA_FILEPATH).map(&:to_h) - @map = S3CSVReader.read(META_MAP_FILEPATH).map(&:to_h) - @submissions = S3CSVReader.read(SUBMISSIONS_FILEPATH).map(&:to_h) - end - - def load_indicator_keys - @indicator_keys = CaitIndc::Indicator.all.map do |i| - i.slug.to_sym - end - end - - def cleanup - CaitIndc::Value.delete_all - CaitIndc::Label.delete_all - CaitIndc::Indicator.delete_all - CaitIndc::Chart.delete_all - CaitIndc::Category.delete_all - CaitIndc::Submission.delete_all - end - - def chart(indicator) - chart_name = @legend. - detect { |l| l[:indicator_name] == indicator[:column_name] }&. - fetch(:chart_title, nil) - - CaitIndc::Chart.find_by(name: chart_name) if chart_name - end - - def indicator_attributes(indicator) - { - chart: chart(indicator), - name: indicator[:long_name], - slug: indicator[:column_name] - } - end - - def label_attributes(label) - { - indicator: CaitIndc::Indicator. - find_by!(slug: label[:indicator_name]), - name: label[:legend_item_name] - } - end - - def value_attributes(datum, location, indicator_key) - indicator = CaitIndc::Indicator.find_by(slug: indicator_key) - - { - location: location, - indicator: indicator, - label: CaitIndc::Label.find_by( - name: datum[:"#{indicator_key}_label"], - indicator: indicator - ), - value: datum[indicator_key] - } - end - - def category_attributes(category_name, category_type) - { - name: category_name, - slug: Slug.create(category_name), - category_type: category_type - } - end - - def submission_attributes(submission) - { - location: Location.find_by(iso_code3: submission[:iso]), - submission_type: submission[:type], - language: submission[:language], - submission_date: submission[:date_of_submission], - url: submission[:url] - } - end - - def select_categories(dataset, indicator_key, indicator, category_type) - dataset.select { |r| r[indicator_key] == indicator.slug }. - map do |r| - CaitIndc::Category.where( - name: r[:category], - category_type: category_type - ).first - end.uniq - end - - def import_categories(dataset, category_type) - dataset. - map { |r| r[:category].strip }. - uniq. - select(&:itself). - each do |cat| - CaitIndc::Category.create!(category_attributes(cat, category_type)) - end - end - - def import_charts - @legend. - map { |r| r[:chart_title].strip }. - uniq. - select(&:itself). - each { |chart_t| CaitIndc::Chart.create!(name: chart_t) } - end - - def import_indicators - @indicators. - reject { |ind| ind[:column_name].match(/_label$/) }. - each do |ind| - CaitIndc::Indicator.create!(indicator_attributes(ind)) - end - end - - def import_association_indicators_categories - CaitIndc::Indicator.all.each do |indicator| - overview_categories = select_categories( - @indicators, :column_name, indicator, 'overview' - ) - - map_categories = select_categories( - @map, :indicator, indicator, 'map' - ) - - indicator.categories = overview_categories + map_categories - end - end - - def import_labels - label_fields = @data.first.keys.grep(/_label$/). - map { |l| l.to_s.gsub(/_label$/, '') } - - label_accumulator = [] - label_fields.each do |lf| - @data.each do |d| - next if d[:"#{lf}_label"].nil? - - label_accumulator << { - indicator_name: lf.to_s, - legend_item_name: d[:"#{lf}_label"] - } - end - end - - label_accumulator.uniq.each do |l| - CaitIndc::Label.create!(label_attributes(l)) - end - end - - def import_values - ind_keys_no_label = @indicator_keys - @indicator_keys.grep(/_label$/) - @data.each do |d| - location = Location.find_by(iso_code3: d[:iso]) - unless location - Rails.logger.error "location #{d[:country]} not found. Skipping." - next - end - - ind_keys_no_label.select { |ind_k| d[ind_k] }.each do |ind_k| - CaitIndc::Value.create!(value_attributes(d, location, ind_k)) - end - end - end - - def import_submissions - @submissions.each do |sub| - CaitIndc::Submission.create!(submission_attributes(sub)) - end - end - - def update_label_indexes - sql = <<~END - WITH indexes AS ( - SELECT l.id, l.indicator_id, - ROW_NUMBER() OVER ( - PARTITION BY l.indicator_id - ORDER BY l.id asc - ) AS index - FROM cait_indc_labels l - ) - UPDATE cait_indc_labels l - SET index = indexes.index - FROM indexes - WHERE indexes.id = l.id - END - - ActiveRecord::Base.connection.execute(sql) - end - - def refresh_materialized_views - MaterializedView.refresh( - 'indc_categories', - 'indc_indicators', - 'indc_indicators_categories', - 'indc_labels', - 'indc_values' - ) - end -end diff --git a/app/services/import_global_indc.rb b/app/services/import_global_indc.rb deleted file mode 100644 index d2fc3028ea..0000000000 --- a/app/services/import_global_indc.rb +++ /dev/null @@ -1,81 +0,0 @@ -class ImportGlobalIndc - GLOBAL_METADATA_FILEPATH = - "#{CW_FILES_PREFIX}global_indc/CW_NDC_metadata_combined.csv".freeze - - def call - cleanup - - load_csvs - - import_categories - import_indicators - end - - private - - def load_csvs - @metadata = S3CSVReader.read(GLOBAL_METADATA_FILEPATH).map(&:to_h) - @categories_index = {} - end - - def cleanup - GlobalIndc::Category.delete_all - GlobalIndc::Indicator.delete_all - end - - def import_categories - categories.map(&:first).uniq.each do |category| - @categories_index[category] = GlobalIndc::Category.create!( - name: category, - slug: Slug.create(category) - ) - end - - categories.map.uniq(&:second).each do |category| - next if category.second.nil? - @categories_index[category.second] = GlobalIndc::Category.create!( - name: category.second, - slug: Slug.create(category.second), - parent: @categories_index[category.first] - ) - end - end - - def import_indicators - @metadata.each do |row| - next if row[:column_name].nil? || row[:source].nil? || - row[:category_2] == 'NULL' - - indicator = GlobalIndc::Indicator.find_or_create_by!( - indicator(row[:column_name], row[:source]) - ) - - indicator.categories << - if row[:category_2].nil? - @categories_index[row[:category]] - else - @categories_index[row[:category_2]] - end - end - end - - def categories - categories = @metadata.map do |row| - [row[:category], row[:category_2]] - end - - categories = categories.reject do |category| - category.second == 'NULL' - end - - categories.uniq - end - - def indicator(code, source) - if source.casecmp('CAIT').zero? - {cait_indicator: CaitIndc::Indicator.find_by(slug: code)} - elsif source.casecmp('WB').zero? - {wb_indicator: WbIndc::Indicator.find_by(code: code)} - end - end -end diff --git a/app/services/import_indc.rb b/app/services/import_indc.rb new file mode 100644 index 0000000000..4604cd89b0 --- /dev/null +++ b/app/services/import_indc.rb @@ -0,0 +1,309 @@ +class ImportIndc + DATA_CAIT_FILEPATH = + "#{CW_FILES_PREFIX}indc/NDC_CAIT_data.csv".freeze + LEGEND_CAIT_FILEPATH = + "#{CW_FILES_PREFIX}indc/NDC_CAIT_legend.csv".freeze + DATA_WB_WIDE_FILEPATH = + "#{CW_FILES_PREFIX}indc/NDC_WB_data_wide.csv".freeze + DATA_WB_SECTORAL_FILEPATH = + "#{CW_FILES_PREFIX}indc/NDC_WB_data_sectoral.csv".freeze + SUBMISSIONS_FILEPATH = + "#{CW_FILES_PREFIX}indc/NDC_submission.csv".freeze + METADATA_FILEPATH = + "#{CW_FILES_PREFIX}indc/NDC_metadata.csv".freeze + + def call + cleanup + + load_csvs + load_locations + + import_sources + import_category_types + import_categories + import_category_relations + import_indicators + import_indicators_categories + import_labels + import_values_cait + import_sectors + import_values_wb + import_submissions + end + + private + + def cleanup + Indc::Value.delete_all + Indc::Category.delete_all + Indc::CategoryType.delete_all + Indc::Sector.delete_all + Indc::Label.delete_all + Indc::Indicator.delete_all + Indc::Source.delete_all + Indc::Submission.delete_all + end + + def load_csvs + @cait_data = S3CSVReader.read(DATA_CAIT_FILEPATH).map(&:to_h) + @cait_labels = S3CSVReader.read(LEGEND_CAIT_FILEPATH).map(&:to_h) + @wb_wide_data = S3CSVReader.read(DATA_WB_WIDE_FILEPATH).map(&:to_h) + @wb_sectoral_data = S3CSVReader.read(DATA_WB_SECTORAL_FILEPATH).map(&:to_h) + @metadata = S3CSVReader.read(METADATA_FILEPATH).map(&:to_h) + @submissions = S3CSVReader.read(SUBMISSIONS_FILEPATH).map(&:to_h) + end + + def load_locations + @locations_by_iso3 = Location.all. + group_by(&:iso_code3). + map { |key, value| [key, value.first] }. + to_h + + @locations_by_iso2 = Location.all. + group_by(&:iso_code2). + map { |key, value| [key, value.first] }. + to_h + end + + def category_attributes(name, category_type) + { + name: name, + slug: Slug.create(name), + category_type: category_type + } + end + + def indicator_attributes(indicator) + { + name: indicator[:long_name], + slug: indicator[:column_name], + description: indicator[:definition], + source: @sources_index[indicator[:source]] + } + end + + def value_cait_attributes(row, location, indicator) + { + location: location, + indicator: indicator, + label: Indc::Label.find_by( + value: row[:"#{indicator.slug}_label"], + indicator: indicator + ), + value: row[:"#{indicator.slug}"] + } + end + + def value_wb_attributes(row, location, indicator) + { + location: location, + indicator: indicator, + sector: @sectors_index[row[:subsector]], + value: row[:responsetext] + } + end + + def submission_attributes(submission) + { + location: Location.find_by!(iso_code3: submission[:iso]), + submission_type: submission[:type], + language: submission[:language], + submission_date: submission[:date_of_submission], + url: submission[:url] + } + end + + def import_categories_of(category_type) + @metadata. + map { |m| m[:"#{category_type.name}_category"] }. + select(&:itself). + uniq. + each do |name| + Indc::Category.create!(category_attributes(name, category_type)) + end + end + + def import_sources + @sources_index = @metadata. + map { |r| r[:source] }. + uniq. + each_with_object({}) do |source, memo| + memo[source] = Indc::Source.create!(name: source) + end + end + + def import_category_types + @category_types_index = @metadata.first.keys. + select { |key| key.match(/_category$/) }. + map { |c| c.to_s.gsub(/_category$/, '') }. + each_with_object({}) do |category_type, memo| + memo[category_type] = Indc::CategoryType.create!(name: category_type) + end + end + + def import_categories + Indc::CategoryType.all. + each do |category_type| + import_categories_of(category_type) + end + end + + def import_category_relations + @metadata.each do |r| + global_category = Indc::Category. + includes(:category_type). + find_by( + slug: Slug.create(r[:global_category]), + indc_category_types: { name: 'global' } + ) or next + + overview_category = Indc::Category. + includes(:category_type). + find_by( + slug: Slug.create(r[:overview_category]), + indc_category_types: { name: 'overview' } + ) if r[:overview_category] + + map_category = Indc::Category. + includes(:category_type). + find_by( + slug: Slug.create(r[:map_category]), + indc_category_types: { name: 'map' } + ) if r[:map_category] + + global_category.children << [ + overview_category, map_category + ].select(&:itself) + end + end + + def import_indicators + @metadata. + map { |r| [[r[:column_name], r[:source]], r] }. + uniq(&:first). + map(&:second). + each do |indicator| + Indc::Indicator.create!(indicator_attributes(indicator)) + end + end + + def import_indicators_categories + @metadata.each do |r| + indicator = Indc::Indicator. + includes(:categories). + find_by!( + slug: r[:column_name], + source: @sources_index[r[:source]] + ) + + categories = r.keys. + select { |key| key.match(/_category$/) }. + map { |c| c.to_s.gsub(/_category$/, '') }. + map do |category_type| + next if r[:"#{category_type}_category"].nil? + + Indc::Category.find_by!( + name: r[:"#{category_type}_category"], + category_type: @category_types_index[category_type] + ) + end + + categories = categories. + select(&:itself). + reject do |category| + indicator.categories.include?(category) + end + + indicator.categories << categories + end + end + + def import_labels + indicators = @cait_labels. + group_by { |l| l[:indicator_name] }. + map { |k, v| [k, v.map { |i| i[:legend_item] }] }. + to_h + + indicators.each do |indicator_name, labels| + indicator = Indc::Indicator.find_by!(slug: indicator_name) + labels.each_with_index do |label, index| + Indc::Label.create!( + indicator: indicator, + value: label, + index: index + 1 + ) + end + end + end + + def import_values_cait + Indc::Indicator.where(source: @sources_index['CAIT']).each do |indicator| + @cait_data.each do |r| + location = @locations_by_iso3[r[:iso]] + unless location + Rails.logger.error "location #{r[:country]} not found. Skipping." + next + end + + next unless r[:"#{indicator.slug}"] + + Indc::Value.create!( + value_cait_attributes(r, location, indicator) + ) + end + end + end + + def import_sectors + sectors = @wb_sectoral_data.map do |d| + d.slice(:sector, :subsector) + end + + @sectors_index = {} + sectors.uniq.each do |d| + parent = Indc::Sector.find_or_create_by( + name: d[:sector] + ) + sector = Indc::Sector.create!( + name: d[:subsector], + parent: parent + ) + + @sectors_index[d[:subsector]] = sector + end + end + + def import_values_wb + indicator_index = Indc::Indicator. + where(source: @sources_index['WB']). + group_by(&:slug). + map { |k, v| [k, v.first] }. + to_h + + (@wb_wide_data + @wb_sectoral_data).each do |r| + location = @locations_by_iso2[r[:countrycode]] + unless location + Rails.logger.error "location #{r[:countrycode]} not found. Skipping." + next + end + + indicator = indicator_index[r[:questioncode]] + unless indicator + Rails.logger.error "indicator #{r[:questioncode]} not found. Skipping." + next + end + + next unless r[:responsetext] + + Indc::Value.create!( + value_wb_attributes(r, location, indicator) + ) + end + end + + def import_submissions + @submissions.each do |sub| + Indc::Submission.create!(submission_attributes(sub)) + end + end +end diff --git a/app/services/import_wb_indc.rb b/app/services/import_wb_indc.rb deleted file mode 100644 index 19526f970a..0000000000 --- a/app/services/import_wb_indc.rb +++ /dev/null @@ -1,159 +0,0 @@ -class ImportWbIndc - META_INDICATORS_FILEPATH = - "#{CW_FILES_PREFIX}wb_indc/CW_NDC_WB_metadata_w_definitions.csv".freeze - DATA_SECTORIAL_FILEPATH = - "#{CW_FILES_PREFIX}wb_indc/CW_NDC_WB_sectoral.csv".freeze - DATA_ECONOMY_WIDE_FILEPATH = - "#{CW_FILES_PREFIX}wb_indc/CW_NDC_WB_economy_wide.csv".freeze - - def call - cleanup - - load_csvs - - import_indicator_types - import_categories - import_indicators - import_sectors - import_values - - refresh_materialized_views - end - - private - - def load_csvs - @indicators = S3CSVReader.read(META_INDICATORS_FILEPATH).map(&:to_h) - @data_sectorial = S3CSVReader.read(DATA_SECTORIAL_FILEPATH).map(&:to_h) - @data_economy_wide = S3CSVReader.read(DATA_ECONOMY_WIDE_FILEPATH). - map(&:to_h) - @location_index = {} - @indicator_index = {} - @sector_index = {} - @ignored_indicators = [] - end - - def cleanup - WbIndc::Value.delete_all - WbIndc::Sector.delete_all - WbIndc::Category.delete_all - WbIndc::Indicator.delete_all - WbIndc::IndicatorType.delete_all - end - - def cached_location(countrycode) - if @location_index[countrycode] - @location_index[countrycode] - else - location = Location.where(iso_code2: countrycode).first - @location_index[countrycode] = location - location - end - end - - def indicator_attributes(i) - { - indicator_type: WbIndc::IndicatorType.find_by(name: i[:questiontype]), - code: i[:questioncode], - name: i[:questiontext], - description: i[:definition] - } - end - - def value_attributes(d, indicator, location) - unless location - Rails.logger.error "Location not found: #{d[:countrycode]}" and return - end - - unless indicator - unless @ignored_indicators.include?(d[:questioncode]) - Rails.logger.error "Indicator not found: #{d[:questioncode]}" - end or return - end - - { - indicator: indicator, - location: location, - sector: @sector_index[d[:subsector]], - value: d[:responsetext] - } - end - - def import_indicator_types - @indicators.map { |i| i[:questiontype] }.uniq.each do |t| - WbIndc::IndicatorType.create(name: t) - end - end - - def import_categories - indicators = @indicators.map do |i| - [i[:category], i[:category_2]] - end - - indicators = indicators.flatten.uniq.reject do |c| - c == 'NULL' - end - - indicators.each do |c| - WbIndc::Category.create( - name: c, - slug: Slug.create(c) - ) - end - end - - def import_indicators - @indicators.each do |i| - if i[:category_2] == 'NULL' - @ignored_indicators << i[:questioncode] - next - end - - indicator = WbIndc::Indicator.create( - indicator_attributes(i) - ) - - indicator.categories = WbIndc::Category.where( - name: [i[:category], i[:category_2]] - ) - - @indicator_index[i[:questioncode]] = indicator - end - end - - def import_sectors - sectors = @data_sectorial.map do |d| - d.slice(:sector, :subsector) - end - - sectors.uniq.each do |d| - parent = WbIndc::Sector.find_or_create_by(name: d[:sector]) - sector = WbIndc::Sector.create( - name: d[:subsector], - parent: parent - ) - - @sector_index[d[:subsector]] = sector - end - end - - def import_values - (@data_sectorial + @data_economy_wide).each do |d| - location = cached_location(d[:countrycode]) - indicator = @indicator_index[d[:questioncode]] - attributes = value_attributes(d, indicator, location) - next unless attributes - WbIndc::Value.create(attributes) - end - end - - def refresh_materialized_views - MaterializedView.refresh( - 'indc_categories', - 'indc_indicators', - 'indc_indicators_categories', - 'indc_sectors', - 'indc_values' - ) - end -end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index f88def0924..0bc26fdde7 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -2,6 +2,28 @@ Climate Watch: Data for Climate Action + <%= favicon_link_tag asset_path('favicons/apple-icon-57x57.png'), rel: 'apple-touch-icon', type: 'image/png' %> + <%= favicon_link_tag asset_path('favicons/apple-icon-60x60.png'), rel: 'apple-touch-icon', type: 'image/png' %> + <%= favicon_link_tag asset_path('favicons/apple-icon-72x72.png'), rel: 'apple-touch-icon', type: 'image/png' %> + <%= favicon_link_tag asset_path('favicons/apple-icon-76x76.png'), rel: 'apple-touch-icon', type: 'image/png' %> + <%= favicon_link_tag asset_path('favicons/apple-icon-114x114.png'), rel: 'apple-touch-icon', type: 'image/png' %> + <%= favicon_link_tag asset_path('favicons/apple-icon-120x120.png'), rel: 'apple-touch-icon', type: 'image/png' %> + <%= favicon_link_tag asset_path('favicons/apple-icon-144x144.png'), rel: 'apple-touch-icon', type: 'image/png' %> + <%= favicon_link_tag asset_path('favicons/apple-icon-152x152.png'), rel: 'apple-touch-icon', type: 'image/png' %> + <%= favicon_link_tag asset_path('favicons/apple-icon-180x180.png'), rel: 'apple-touch-icon', type: 'image/png' %> + <%= favicon_link_tag asset_path('favicons/android-icon-192x192.png'), rel: 'icon', type: 'image/png' %> + <%= favicon_link_tag asset_path('favicons/android-icon-144x144.png'), rel: 'icon', type: 'image/png' %> + <%= favicon_link_tag asset_path('favicons/android-icon-96x96.png'), rel: 'icon', type: 'image/png' %> + <%= favicon_link_tag asset_path('favicons/android-icon-72x72.png'), rel: 'icon', type: 'image/png' %> + <%= favicon_link_tag asset_path('favicons/android-icon-48x48.png'), rel: 'icon', type: 'image/png' %> + <%= favicon_link_tag asset_path('favicons/android-icon-36x36.png'), rel: 'icon', type: 'image/png' %> + + <%= favicon_link_tag asset_path('favicons/manifest.json'), rel: 'manifest' %> + + + + + <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all', diff --git a/db/migrate/20171027155954_drop_old_indc_tables_and_views.rb b/db/migrate/20171027155954_drop_old_indc_tables_and_views.rb new file mode 100644 index 0000000000..c262b8da4d --- /dev/null +++ b/db/migrate/20171027155954_drop_old_indc_tables_and_views.rb @@ -0,0 +1,29 @@ +class DropOldIndcTablesAndViews < ActiveRecord::Migration[5.1] + def change + drop_view :indc_values, materialized: true + drop_view :indc_sectors, materialized: true + drop_view :indc_labels, materialized: true + drop_view :indc_indicators_categories, materialized: true + drop_view :indc_indicators, materialized: true + drop_view :indc_categories, materialized: true + + drop_table :global_indc_indicators_categories + drop_table :global_indc_categories + drop_table :global_indc_indicators + + drop_table :cait_indc_values + drop_table :cait_indc_labels + drop_table :cait_indc_indicators_categories + drop_table :cait_indc_categories + drop_table :cait_indc_indicators + drop_table :cait_indc_submissions + drop_table :cait_indc_charts + + drop_table :wb_indc_values + drop_table :wb_indc_indicators_categories + drop_table :wb_indc_categories + drop_table :wb_indc_indicators + drop_table :wb_indc_indicator_types + drop_table :wb_indc_sectors + end +end diff --git a/db/migrate/20171027164649_create_new_indc_category_types.rb b/db/migrate/20171027164649_create_new_indc_category_types.rb new file mode 100644 index 0000000000..adddbf7a81 --- /dev/null +++ b/db/migrate/20171027164649_create_new_indc_category_types.rb @@ -0,0 +1,10 @@ +class CreateNewIndcCategoryTypes < ActiveRecord::Migration[5.1] + def change + create_table :indc_category_types do |t| + t.text :name, null: false + t.timestamps + end + + add_index :indc_category_types, :name, unique: true + end +end diff --git a/db/migrate/20171027164650_create_new_indc_sources.rb b/db/migrate/20171027164650_create_new_indc_sources.rb new file mode 100644 index 0000000000..08eb1e0191 --- /dev/null +++ b/db/migrate/20171027164650_create_new_indc_sources.rb @@ -0,0 +1,10 @@ +class CreateNewIndcSources < ActiveRecord::Migration[5.1] + def change + create_table :indc_sources do |t| + t.text :name, null: false + t.timestamps + end + + add_index :indc_sources, :name, unique: true + end +end diff --git a/db/migrate/20171027164651_create_new_indc_indicators.rb b/db/migrate/20171027164651_create_new_indc_indicators.rb new file mode 100644 index 0000000000..cb60ad74e5 --- /dev/null +++ b/db/migrate/20171027164651_create_new_indc_indicators.rb @@ -0,0 +1,16 @@ +class CreateNewIndcIndicators < ActiveRecord::Migration[5.1] + def change + create_table :indc_indicators do |t| + t.references :source, foreign_key: { + to_table: :indc_sources, + on_delete: :cascade + }, null: false + t.text :slug, null: false + t.text :name, null: false + t.text :description + t.timestamps + end + + add_index :indc_indicators, :slug, unique: true + end +end diff --git a/db/migrate/20171027164658_create_new_indc_categories.rb b/db/migrate/20171027164658_create_new_indc_categories.rb new file mode 100644 index 0000000000..ce2ac0bd7d --- /dev/null +++ b/db/migrate/20171027164658_create_new_indc_categories.rb @@ -0,0 +1,18 @@ +class CreateNewIndcCategories < ActiveRecord::Migration[5.1] + def change + create_table :indc_categories do |t| + t.references :category_type, foreign_key: { + to_table: :indc_category_types, + on_delete: :cascade + }, null: false + t.references :parent, foreign_key: { + to_table: :indc_categories, + on_delete: :cascade + } + t.text :slug, null: false + t.text :name, null: false + t.timestamps + end + add_index :indc_categories, [:slug, :category_type_id], unique: true + end +end diff --git a/db/migrate/20171027164702_create_new_indc_indicators_categories.rb b/db/migrate/20171027164702_create_new_indc_indicators_categories.rb new file mode 100644 index 0000000000..161a49790e --- /dev/null +++ b/db/migrate/20171027164702_create_new_indc_indicators_categories.rb @@ -0,0 +1,20 @@ +class CreateNewIndcIndicatorsCategories < ActiveRecord::Migration[5.1] + def change + create_table :indc_indicators_categories do |t| + t.references :indicator, foreign_key: { + to_table: :indc_indicators, + on_delete: :cascade + }, null: false + t.references :category, foreign_key: { + to_table: :indc_categories, + on_delete: :cascade + }, null: false + t.timestamps + end + + add_index :indc_indicators_categories, [ + :indicator_id, + :category_id + ], unique: true, name: :indc_indicators_categories_uniq + end +end diff --git a/db/migrate/20171027164708_create_new_indc_sectors.rb b/db/migrate/20171027164708_create_new_indc_sectors.rb new file mode 100644 index 0000000000..4ddedc15e8 --- /dev/null +++ b/db/migrate/20171027164708_create_new_indc_sectors.rb @@ -0,0 +1,12 @@ +class CreateNewIndcSectors < ActiveRecord::Migration[5.1] + def change + create_table :indc_sectors do |t| + t.references :parent, foreign_key: { + to_table: :indc_sectors, + on_delete: :cascade + } + t.text :name, null: false + t.timestamps + end + end +end diff --git a/db/migrate/20171027164714_create_new_indc_labels.rb b/db/migrate/20171027164714_create_new_indc_labels.rb new file mode 100644 index 0000000000..d546f039ff --- /dev/null +++ b/db/migrate/20171027164714_create_new_indc_labels.rb @@ -0,0 +1,13 @@ +class CreateNewIndcLabels < ActiveRecord::Migration[5.1] + def change + create_table :indc_labels do |t| + t.references :indicator, foreign_key: { + to_table: :indc_indicators, + on_delete: :cascade + }, null: false + t.text :value, null: false + t.integer :index, null: false + t.timestamps + end + end +end diff --git a/db/migrate/20171027164736_create_new_indc_values.rb b/db/migrate/20171027164736_create_new_indc_values.rb new file mode 100644 index 0000000000..19416cd9bb --- /dev/null +++ b/db/migrate/20171027164736_create_new_indc_values.rb @@ -0,0 +1,24 @@ +class CreateNewIndcValues < ActiveRecord::Migration[5.1] + def change + create_table :indc_values do |t| + t.references :indicator, foreign_key: { + to_table: :indc_indicators, + on_delete: :cascade + }, null: false + t.references :location, foreign_key: { + to_table: :locations, + on_delete: :cascade + }, null: false + t.references :sector, foreign_key: { + to_table: :indc_sectors, + on_delete: :cascade + } + t.references :label, foreign_key: { + to_table: :indc_labels, + on_delete: :cascade + } + t.text :value, null: false + t.timestamps + end + end +end diff --git a/db/migrate/20171027170320_create_new_indc_submissions.rb b/db/migrate/20171027170320_create_new_indc_submissions.rb new file mode 100644 index 0000000000..a56e0b86dd --- /dev/null +++ b/db/migrate/20171027170320_create_new_indc_submissions.rb @@ -0,0 +1,15 @@ +class CreateNewIndcSubmissions < ActiveRecord::Migration[5.1] + def change + create_table :indc_submissions do |t| + t.references :location, foreign_key: { + to_table: :locations, + on_delete: :cascade + }, null: false + t.text :submission_type, null: false + t.text :language, null: false + t.date :submission_date, null: false + t.text :url, null: false + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 4b6c0c2156..3bf885435f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -37,128 +37,136 @@ t.index ["slug"], name: "index_adaptation_variables_on_slug", unique: true end - create_table "cait_indc_categories", force: :cascade do |t| - t.text "name", null: false - t.text "slug", null: false - t.text "category_type" - t.index ["category_type"], name: "index_cait_indc_categories_on_category_type" + create_table "historical_emissions_data_sources", force: :cascade do |t| + t.text "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "cait_indc_charts", force: :cascade do |t| - t.text "name", null: false + create_table "historical_emissions_gases", force: :cascade do |t| + t.text "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "cait_indc_indicators", force: :cascade do |t| - t.bigint "chart_id" - t.text "name", null: false - t.text "slug", null: false + create_table "historical_emissions_gwps", force: :cascade do |t| + t.text "name" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index ["chart_id"], name: "index_cait_indc_indicators_on_chart_id" end - create_table "cait_indc_indicators_categories", force: :cascade do |t| - t.bigint "indicator_id" - t.bigint "category_id" - t.index ["category_id"], name: "index_cait_indc_indicators_categories_on_category_id" - t.index ["indicator_id", "category_id"], name: "indicator_id_category_id_index", unique: true - t.index ["indicator_id"], name: "index_cait_indc_indicators_categories_on_indicator_id" + create_table "historical_emissions_records", force: :cascade do |t| + t.bigint "location_id" + t.bigint "data_source_id" + t.bigint "sector_id" + t.bigint "gas_id" + t.jsonb "emissions" + t.bigint "gwp_id" + t.index ["data_source_id"], name: "index_historical_emissions_records_on_data_source_id" + t.index ["gas_id"], name: "index_historical_emissions_records_on_gas_id" + t.index ["gwp_id"], name: "index_historical_emissions_records_on_gwp_id" + t.index ["location_id"], name: "index_historical_emissions_records_on_location_id" + t.index ["sector_id"], name: "index_historical_emissions_records_on_sector_id" end - create_table "cait_indc_labels", force: :cascade do |t| - t.bigint "indicator_id" - t.text "name", null: false + create_table "historical_emissions_sectors", force: :cascade do |t| + t.bigint "parent_id" + t.bigint "data_source_id" + t.text "name" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.integer "index" - t.index ["indicator_id"], name: "index_cait_indc_labels_on_indicator_id" + t.text "annex_type" + t.index ["data_source_id"], name: "index_historical_emissions_sectors_on_data_source_id" + t.index ["parent_id"], name: "index_historical_emissions_sectors_on_parent_id" end - create_table "cait_indc_submissions", force: :cascade do |t| - t.bigint "location_id" - t.text "submission_type", null: false - t.text "language", null: false - t.date "submission_date", null: false - t.text "url", null: false + create_table "indc_categories", force: :cascade do |t| + t.bigint "category_type_id", null: false + t.bigint "parent_id" + t.text "slug", null: false + t.text "name", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index ["location_id"], name: "index_cait_indc_submissions_on_location_id" + t.index ["category_type_id"], name: "index_indc_categories_on_category_type_id" + t.index ["parent_id"], name: "index_indc_categories_on_parent_id" + t.index ["slug", "category_type_id"], name: "index_indc_categories_on_slug_and_category_type_id", unique: true end - create_table "cait_indc_values", force: :cascade do |t| - t.bigint "location_id" - t.bigint "indicator_id" - t.bigint "label_id" - t.text "value", null: false - t.index ["indicator_id"], name: "index_cait_indc_values_on_indicator_id" - t.index ["label_id"], name: "index_cait_indc_values_on_label_id" - t.index ["location_id"], name: "index_cait_indc_values_on_location_id" + create_table "indc_category_types", force: :cascade do |t| + t.text "name", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "index_indc_category_types_on_name", unique: true end - create_table "global_indc_categories", force: :cascade do |t| - t.text "name" - t.text "slug" - t.bigint "parent_id" + create_table "indc_indicators", force: :cascade do |t| + t.bigint "source_id", null: false + t.text "slug", null: false + t.text "name", null: false + t.text "description" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index ["parent_id"], name: "index_global_indc_categories_on_parent_id" + t.index ["slug"], name: "index_indc_indicators_on_slug", unique: true + t.index ["source_id"], name: "index_indc_indicators_on_source_id" end - create_table "global_indc_indicators", force: :cascade do |t| - t.bigint "cait_indicator_id" - t.bigint "wb_indicator_id" - t.index ["cait_indicator_id"], name: "index_global_indc_indicators_on_cait_indicator_id" - t.index ["wb_indicator_id"], name: "index_global_indc_indicators_on_wb_indicator_id" + create_table "indc_indicators_categories", force: :cascade do |t| + t.bigint "indicator_id", null: false + t.bigint "category_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["category_id"], name: "index_indc_indicators_categories_on_category_id" + t.index ["indicator_id", "category_id"], name: "indc_indicators_categories_uniq", unique: true + t.index ["indicator_id"], name: "index_indc_indicators_categories_on_indicator_id" end - create_table "global_indc_indicators_categories", force: :cascade do |t| - t.bigint "indicator_id" - t.bigint "category_id" - t.index ["category_id"], name: "index_global_indc_indicators_categories_on_category_id" - t.index ["indicator_id"], name: "index_global_indc_indicators_categories_on_indicator_id" + create_table "indc_labels", force: :cascade do |t| + t.bigint "indicator_id", null: false + t.text "value", null: false + t.integer "index", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["indicator_id"], name: "index_indc_labels_on_indicator_id" end - create_table "historical_emissions_data_sources", force: :cascade do |t| - t.text "name" + create_table "indc_sectors", force: :cascade do |t| + t.bigint "parent_id" + t.text "name", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["parent_id"], name: "index_indc_sectors_on_parent_id" end - create_table "historical_emissions_gases", force: :cascade do |t| - t.text "name" + create_table "indc_sources", force: :cascade do |t| + t.text "name", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["name"], name: "index_indc_sources_on_name", unique: true end - create_table "historical_emissions_gwps", force: :cascade do |t| - t.text "name" + create_table "indc_submissions", force: :cascade do |t| + t.bigint "location_id", null: false + t.text "submission_type", null: false + t.text "language", null: false + t.date "submission_date", null: false + t.text "url", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["location_id"], name: "index_indc_submissions_on_location_id" end - create_table "historical_emissions_records", force: :cascade do |t| - t.bigint "location_id" - t.bigint "data_source_id" + create_table "indc_values", force: :cascade do |t| + t.bigint "indicator_id", null: false + t.bigint "location_id", null: false t.bigint "sector_id" - t.bigint "gas_id" - t.jsonb "emissions" - t.bigint "gwp_id" - t.index ["data_source_id"], name: "index_historical_emissions_records_on_data_source_id" - t.index ["gas_id"], name: "index_historical_emissions_records_on_gas_id" - t.index ["gwp_id"], name: "index_historical_emissions_records_on_gwp_id" - t.index ["location_id"], name: "index_historical_emissions_records_on_location_id" - t.index ["sector_id"], name: "index_historical_emissions_records_on_sector_id" - end - - create_table "historical_emissions_sectors", force: :cascade do |t| - t.bigint "parent_id" - t.bigint "data_source_id" - t.text "name" + t.bigint "label_id" + t.text "value", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.text "annex_type" - t.index ["data_source_id"], name: "index_historical_emissions_sectors_on_data_source_id" - t.index ["parent_id"], name: "index_historical_emissions_sectors_on_parent_id" + t.index ["indicator_id"], name: "index_indc_values_on_indicator_id" + t.index ["label_id"], name: "index_indc_values_on_label_id" + t.index ["location_id"], name: "index_indc_values_on_location_id" + t.index ["sector_id"], name: "index_indc_values_on_sector_id" end create_table "location_members", force: :cascade do |t| @@ -319,56 +327,6 @@ t.index ["location_id"], name: "index_wb_extra_country_data_on_location_id" end - create_table "wb_indc_categories", force: :cascade do |t| - t.text "name", null: false - t.text "slug", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "wb_indc_indicator_types", force: :cascade do |t| - t.text "name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "wb_indc_indicators", force: :cascade do |t| - t.bigint "indicator_type_id" - t.text "code", null: false - t.text "name", null: false - t.text "description" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["indicator_type_id"], name: "index_wb_indc_indicators_on_indicator_type_id" - end - - create_table "wb_indc_indicators_categories", force: :cascade do |t| - t.bigint "indicator_id" - t.bigint "category_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["category_id"], name: "index_wb_indc_indicators_categories_on_category_id" - t.index ["indicator_id"], name: "index_wb_indc_indicators_categories_on_indicator_id" - end - - create_table "wb_indc_sectors", force: :cascade do |t| - t.bigint "parent_id" - t.text "name", null: false - t.index ["parent_id"], name: "index_wb_indc_sectors_on_parent_id" - end - - create_table "wb_indc_values", force: :cascade do |t| - t.bigint "indicator_id" - t.bigint "location_id" - t.bigint "sector_id" - t.text "value" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["indicator_id"], name: "index_wb_indc_values_on_indicator_id" - t.index ["location_id"], name: "index_wb_indc_values_on_location_id" - t.index ["sector_id"], name: "index_wb_indc_values_on_sector_id" - end - create_table "wri_metadata_acronyms", force: :cascade do |t| t.text "acronym" t.text "definition" @@ -404,19 +362,6 @@ add_foreign_key "adaptation_values", "adaptation_variables", column: "variable_id", on_delete: :cascade add_foreign_key "adaptation_values", "locations", on_delete: :cascade - add_foreign_key "cait_indc_indicators", "cait_indc_charts", column: "chart_id", on_delete: :cascade - add_foreign_key "cait_indc_indicators_categories", "cait_indc_categories", column: "category_id", on_delete: :cascade - add_foreign_key "cait_indc_indicators_categories", "cait_indc_indicators", column: "indicator_id", on_delete: :cascade - add_foreign_key "cait_indc_labels", "cait_indc_indicators", column: "indicator_id", on_delete: :cascade - add_foreign_key "cait_indc_submissions", "locations", on_delete: :cascade - add_foreign_key "cait_indc_values", "cait_indc_indicators", column: "indicator_id", on_delete: :cascade - add_foreign_key "cait_indc_values", "cait_indc_labels", column: "label_id", on_delete: :cascade - add_foreign_key "cait_indc_values", "locations", on_delete: :cascade - add_foreign_key "global_indc_categories", "global_indc_categories", column: "parent_id", on_delete: :cascade - add_foreign_key "global_indc_indicators", "cait_indc_indicators", column: "cait_indicator_id", on_delete: :cascade - add_foreign_key "global_indc_indicators", "wb_indc_indicators", column: "wb_indicator_id", on_delete: :cascade - add_foreign_key "global_indc_indicators_categories", "global_indc_categories", column: "category_id", on_delete: :cascade - add_foreign_key "global_indc_indicators_categories", "global_indc_indicators", column: "indicator_id", on_delete: :cascade add_foreign_key "historical_emissions_records", "historical_emissions_data_sources", column: "data_source_id", on_delete: :cascade add_foreign_key "historical_emissions_records", "historical_emissions_gases", column: "gas_id", on_delete: :cascade add_foreign_key "historical_emissions_records", "historical_emissions_gwps", column: "gwp_id" @@ -424,6 +369,18 @@ add_foreign_key "historical_emissions_records", "locations", on_delete: :cascade add_foreign_key "historical_emissions_sectors", "historical_emissions_data_sources", column: "data_source_id", on_delete: :cascade add_foreign_key "historical_emissions_sectors", "historical_emissions_sectors", column: "parent_id", on_delete: :cascade + add_foreign_key "indc_categories", "indc_categories", column: "parent_id", on_delete: :cascade + add_foreign_key "indc_categories", "indc_category_types", column: "category_type_id", on_delete: :cascade + add_foreign_key "indc_indicators", "indc_sources", column: "source_id", on_delete: :cascade + add_foreign_key "indc_indicators_categories", "indc_categories", column: "category_id", on_delete: :cascade + add_foreign_key "indc_indicators_categories", "indc_indicators", column: "indicator_id", on_delete: :cascade + add_foreign_key "indc_labels", "indc_indicators", column: "indicator_id", on_delete: :cascade + add_foreign_key "indc_sectors", "indc_sectors", column: "parent_id", on_delete: :cascade + add_foreign_key "indc_submissions", "locations", on_delete: :cascade + add_foreign_key "indc_values", "indc_indicators", column: "indicator_id", on_delete: :cascade + add_foreign_key "indc_values", "indc_labels", column: "label_id", on_delete: :cascade + add_foreign_key "indc_values", "indc_sectors", column: "sector_id", on_delete: :cascade + add_foreign_key "indc_values", "locations", on_delete: :cascade add_foreign_key "location_members", "locations", column: "member_id", on_delete: :cascade add_foreign_key "location_members", "locations", on_delete: :cascade add_foreign_key "ndc_sdg_ndc_target_sectors", "ndc_sdg_ndc_targets", column: "ndc_target_id", on_delete: :cascade @@ -439,111 +396,6 @@ add_foreign_key "timeline_documents", "timeline_sources", column: "source_id", on_delete: :cascade add_foreign_key "timeline_notes", "timeline_documents", column: "document_id", on_delete: :cascade add_foreign_key "wb_extra_country_data", "locations", on_delete: :cascade - add_foreign_key "wb_indc_indicators", "wb_indc_indicator_types", column: "indicator_type_id", on_delete: :cascade - add_foreign_key "wb_indc_indicators_categories", "wb_indc_categories", column: "category_id", on_delete: :cascade - add_foreign_key "wb_indc_indicators_categories", "wb_indc_indicators", column: "indicator_id", on_delete: :cascade - add_foreign_key "wb_indc_sectors", "wb_indc_sectors", column: "parent_id", on_delete: :cascade - add_foreign_key "wb_indc_values", "locations", on_delete: :cascade - add_foreign_key "wb_indc_values", "wb_indc_indicators", column: "indicator_id", on_delete: :cascade - add_foreign_key "wb_indc_values", "wb_indc_sectors", column: "sector_id", on_delete: :cascade add_foreign_key "wri_metadata_values", "wri_metadata_properties", column: "property_id", on_delete: :cascade add_foreign_key "wri_metadata_values", "wri_metadata_sources", column: "source_id", on_delete: :cascade - - create_view "indc_indicators", materialized: true, sql_definition: <<-SQL - SELECT ('cait'::text || cait_indc_indicators.id) AS id, - 'cait'::text AS source, - cait_indc_indicators.name, - cait_indc_indicators.slug, - NULL::text AS description - FROM cait_indc_indicators - UNION ALL - SELECT ('wb'::text || wb_indc_indicators.id) AS id, - 'wb'::text AS source, - wb_indc_indicators.name, - wb_indc_indicators.code AS slug, - wb_indc_indicators.description - FROM wb_indc_indicators; - SQL - - add_index "indc_indicators", ["id"], name: "index_indc_indicators_on_id" - - create_view "indc_categories", materialized: true, sql_definition: <<-SQL - SELECT ('cait'::text || cait_indc_categories.id) AS id, - 'cait'::text AS source, - cait_indc_categories.name, - cait_indc_categories.slug, - cait_indc_categories.category_type - FROM cait_indc_categories - UNION ALL - SELECT ('wb'::text || wb_indc_categories.id) AS id, - 'wb'::text AS source, - wb_indc_categories.name, - wb_indc_categories.slug, - 'overview'::text AS category_type - FROM wb_indc_categories; - SQL - - add_index "indc_categories", ["id"], name: "index_indc_categories_on_id" - - create_view "indc_values", materialized: true, sql_definition: <<-SQL - SELECT ('cait'::text || cait_indc_values.id) AS id, - 'cait'::text AS source, - cait_indc_values.location_id, - ('cait'::text || cait_indc_values.indicator_id) AS indicator_id, - ('cait'::text || cait_indc_values.label_id) AS label_id, - NULL::text AS sector_id, - cait_indc_values.value - FROM cait_indc_values - UNION ALL - SELECT ('wb'::text || wb_indc_values.id) AS id, - 'wb'::text AS source, - wb_indc_values.location_id, - ('wb'::text || wb_indc_values.indicator_id) AS indicator_id, - NULL::text AS label_id, - ('wb'::text || wb_indc_values.sector_id) AS sector_id, - wb_indc_values.value - FROM wb_indc_values; - SQL - - add_index "indc_values", ["indicator_id"], name: "index_indc_values_on_indicator_id" - add_index "indc_values", ["label_id"], name: "index_indc_values_on_label_id" - - create_view "indc_indicators_categories", materialized: true, sql_definition: <<-SQL - SELECT ('cait'::text || cait_indc_indicators_categories.id) AS id, - ('cait'::text || cait_indc_indicators_categories.indicator_id) AS indicator_id, - ('cait'::text || cait_indc_indicators_categories.category_id) AS category_id, - 'cait'::text AS source - FROM cait_indc_indicators_categories - UNION ALL - SELECT ('wb'::text || wb_indc_indicators_categories.id) AS id, - ('wb'::text || wb_indc_indicators_categories.indicator_id) AS indicator_id, - ('wb'::text || wb_indc_indicators_categories.category_id) AS category_id, - 'wb'::text AS source - FROM wb_indc_indicators_categories; - SQL - - add_index "indc_indicators_categories", ["category_id"], name: "index_indc_indicators_categories_on_category_id" - add_index "indc_indicators_categories", ["indicator_id"], name: "index_indc_indicators_categories_on_indicator_id" - - create_view "indc_labels", materialized: true, sql_definition: <<-SQL - SELECT ('cait'::text || cait_indc_labels.id) AS id, - 'cait'::text AS source, - ('cait'::text || cait_indc_labels.indicator_id) AS indicator_id, - cait_indc_labels.name, - cait_indc_labels.index - FROM cait_indc_labels; - SQL - - add_index "indc_labels", ["id"], name: "index_indc_labels_on_id" - add_index "indc_labels", ["indicator_id"], name: "index_indc_labels_on_indicator_id" - - create_view "indc_sectors", materialized: true, sql_definition: <<-SQL - SELECT ('wb'::text || child.id) AS id, - child.name, - ('wb'::text || parent.id) AS parent_id, - parent.name AS parent_name - FROM (wb_indc_sectors child - LEFT JOIN wb_indc_sectors parent ON ((child.parent_id = parent.id))); - SQL - end diff --git a/lib/tasks/cait_indc.rake b/lib/tasks/cait_indc.rake deleted file mode 100644 index 54259ae573..0000000000 --- a/lib/tasks/cait_indc.rake +++ /dev/null @@ -1,10 +0,0 @@ -namespace :cait_indc do - desc 'Imports the CAIT INDC dataset from the csv sources' - task import: :environment do - puts "######################################" - puts "# Starting to import CaitIndc data #" - puts "######################################" - ImportCaitIndc.new.call - puts "############## ENDED #################" - end -end diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake index cb8fe25c81..0b1af3d592 100644 --- a/lib/tasks/db.rake +++ b/lib/tasks/db.rake @@ -7,14 +7,12 @@ namespace :db do 'ndcs:full:index', 'sdgs:import', 'ndc_sdg_targets:import', + 'indc:import', 'historical_emissions:import', - 'cait_indc:import', - 'wb_indc:import', 'adaptation:import', 'wri_metadata:import', 'wb_extra:import', 'timeline:import', - 'global_indc:import', 'quantifications:import', 'socioeconomics:import' ] diff --git a/lib/tasks/global_indc.rake b/lib/tasks/global_indc.rake deleted file mode 100644 index f2ed7102c3..0000000000 --- a/lib/tasks/global_indc.rake +++ /dev/null @@ -1,10 +0,0 @@ -namespace :global_indc do - desc 'Imports the WB/CAIT global dataset from the csv sources' - task import: :environment do - puts "######################################" - puts "# Starting to import GlobalIndc data#" - puts "######################################" - ImportGlobalIndc.new.call - puts "############## ENDED #################" - end -end diff --git a/lib/tasks/indc.rake b/lib/tasks/indc.rake new file mode 100644 index 0000000000..1772f98933 --- /dev/null +++ b/lib/tasks/indc.rake @@ -0,0 +1,6 @@ +namespace :indc do + desc 'Imports the INDC dataset from the csv sources' + task import: :environment do + ImportIndc.new.call + end +end diff --git a/lib/tasks/wb_indc.rake b/lib/tasks/wb_indc.rake deleted file mode 100644 index 94902c4f0f..0000000000 --- a/lib/tasks/wb_indc.rake +++ /dev/null @@ -1,10 +0,0 @@ -namespace :wb_indc do - desc 'Imports the WB INDC dataset from the csv sources' - task import: :environment do - puts "####################################" - puts "# Starting to import WbIndc data #" - puts "####################################" - ImportWbIndc.new.call - puts "############## ENDED #################" - end -end diff --git a/spec/controllers/api/v1/ndcs_controller_spec.rb b/spec/controllers/api/v1/ndcs_controller_spec.rb index 31dca0ad59..64739dfd55 100644 --- a/spec/controllers/api/v1/ndcs_controller_spec.rb +++ b/spec/controllers/api/v1/ndcs_controller_spec.rb @@ -5,17 +5,12 @@ let(:parsed_body) { JSON.parse(response.body) } - let!(:some_cait_indc_values) { - list = FactoryGirl.create_list(:cait_indc_indicator_with_dependants, 3) - MaterializedView.refresh( - 'indc_categories', - 'indc_indicators', - 'indc_indicators_categories', - 'indc_labels', - 'indc_sectors', - 'indc_values' + let!(:some_indc_values) { + FactoryGirl.create_list( + :indc_indicator, + 3, + :with_dependants ) - list } describe 'GET index' do @@ -24,7 +19,7 @@ expect(response).to be_success end - it 'lists all cait indc indicators' do + it 'lists all indc indicators' do get :index expect(parsed_body['indicators'].length).to eq(3) end @@ -32,7 +27,7 @@ describe 'GET content_overview' do it 'returns a successful 200 response' do - code = some_cait_indc_values.first.values.first.location.iso_code3 + code = some_indc_values.first.values.first.location.iso_code3 get :content_overview, params: {code: code} expect(response).to be_success end diff --git a/spec/factories/cait_indc_categories.rb b/spec/factories/cait_indc_categories.rb deleted file mode 100644 index 3a283222da..0000000000 --- a/spec/factories/cait_indc_categories.rb +++ /dev/null @@ -1,7 +0,0 @@ -FactoryGirl.define do - factory :cait_indc_category, class: 'CaitIndc::Category' do - name 'MyText' - slug 'my-text' - category_type 'overview' - end -end diff --git a/spec/factories/cait_indc_charts.rb b/spec/factories/cait_indc_charts.rb deleted file mode 100644 index 595640a13b..0000000000 --- a/spec/factories/cait_indc_charts.rb +++ /dev/null @@ -1,5 +0,0 @@ -FactoryGirl.define do - factory :cait_indc_chart, class: 'CaitIndc::Chart' do - name 'MyText' - end -end diff --git a/spec/factories/cait_indc_labels.rb b/spec/factories/cait_indc_labels.rb deleted file mode 100644 index 3c227a6f3e..0000000000 --- a/spec/factories/cait_indc_labels.rb +++ /dev/null @@ -1,6 +0,0 @@ -FactoryGirl.define do - factory :cait_indc_label, class: 'CaitIndc::Label' do - association :indicator, factory: :cait_indc_indicator - name 'MyText' - end -end diff --git a/spec/factories/cait_indc_values.rb b/spec/factories/cait_indc_values.rb deleted file mode 100644 index 5c8ca05215..0000000000 --- a/spec/factories/cait_indc_values.rb +++ /dev/null @@ -1,8 +0,0 @@ -FactoryGirl.define do - factory :cait_indc_value, class: 'CaitIndc::Value' do - location - association :indicator, factory: :cait_indc_indicator - association :label, factory: :cait_indc_label - value 'MyText' - end -end diff --git a/spec/factories/global_indc_categories.rb b/spec/factories/global_indc_categories.rb deleted file mode 100644 index fe20a0bccb..0000000000 --- a/spec/factories/global_indc_categories.rb +++ /dev/null @@ -1,6 +0,0 @@ -FactoryGirl.define do - factory :global_indc_category, class: 'GlobalIndc::Category' do - name 'MyText' - slug 'my-text' - end -end diff --git a/spec/factories/global_indc_indicators.rb b/spec/factories/global_indc_indicators.rb deleted file mode 100644 index e2175ff71e..0000000000 --- a/spec/factories/global_indc_indicators.rb +++ /dev/null @@ -1,15 +0,0 @@ -FactoryGirl.define do - factory :global_indc_indicator, class: 'GlobalIndc::Indicator' do - trait :with_cait_reference do - after(:create) do |indicator| - indicator.cait_indicator = create(:cait_indc_indicator) - end - end - - trait :with_wb_reference do - after(:create) do |indicator| - indicator.wb_indicator = create(:wb_indc_indicator) - end - end - end -end diff --git a/spec/factories/indc_categories.rb b/spec/factories/indc_categories.rb new file mode 100644 index 0000000000..3b2d5c4848 --- /dev/null +++ b/spec/factories/indc_categories.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :indc_category, class: 'Indc::Category' do + name 'MyName' + sequence :slug { |n| 'my-slug-' + ('AA'..'ZZ').to_a[n] } + association :category_type, factory: :indc_category_type + end +end diff --git a/spec/factories/indc_category_types.rb b/spec/factories/indc_category_types.rb new file mode 100644 index 0000000000..23dba56bb2 --- /dev/null +++ b/spec/factories/indc_category_types.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory :indc_category_type, class: 'Indc::CategoryType' do + sequence :name { |n| 'My Name ' + ('AA'..'ZZ').to_a[n] } + end +end diff --git a/spec/factories/cait_indc_indicators.rb b/spec/factories/indc_indicators.rb similarity index 51% rename from spec/factories/cait_indc_indicators.rb rename to spec/factories/indc_indicators.rb index 46480a32dc..f66b90dcd6 100644 --- a/spec/factories/cait_indc_indicators.rb +++ b/spec/factories/indc_indicators.rb @@ -1,34 +1,40 @@ FactoryGirl.define do - factory :cait_indc_indicator, class: 'CaitIndc::Indicator' do - association :chart, factory: :cait_indc_chart - name 'MyText' - slug 'my-text' + factory :indc_indicator, class: 'Indc::Indicator' do + name 'MyName' + association :source, factory: :indc_source + sequence :slug { |n| 'my-slug-' + ('AA'..'ZZ').to_a[n] } - factory :cait_indc_indicator_with_dependants, - class: 'CaitIndc::Indicator' do + trait :with_dependants do transient do values_count 3 labels_count 2 + sectors_count 2 categories_count 2 end after(:create) do |indicator, evaluator| labels = create_list( - :cait_indc_label, + :indc_label, evaluator.labels_count, indicator: indicator ) + sector = create( + :indc_sector, + parent: create(:indc_sector) + ) + indicator.categories = create_list( - :cait_indc_category, + :indc_category, evaluator.categories_count ) create_list( - :cait_indc_value, + :indc_value, evaluator.values_count, indicator: indicator, - label: labels.sample + label: labels.sample, + sector: sector ) end end diff --git a/spec/factories/indc_labels.rb b/spec/factories/indc_labels.rb new file mode 100644 index 0000000000..18c8cdab9e --- /dev/null +++ b/spec/factories/indc_labels.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :indc_label, class: 'Indc::Label' do + association :indicator, factory: :indc_indicator + value 'MyLabel' + sequence :index { |n| (0..99).to_a[n] } + end +end diff --git a/spec/factories/indc_sectors.rb b/spec/factories/indc_sectors.rb new file mode 100644 index 0000000000..6f4af6dc8b --- /dev/null +++ b/spec/factories/indc_sectors.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory :indc_sector, class: 'Indc::Sector' do + name 'MyName' + end +end diff --git a/spec/factories/indc_sources.rb b/spec/factories/indc_sources.rb new file mode 100644 index 0000000000..8e4d029050 --- /dev/null +++ b/spec/factories/indc_sources.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory :indc_source, class: 'Indc::Source' do + sequence :name { |n| 'My Name ' + ('AA'..'ZZ').to_a[n] } + end +end diff --git a/spec/factories/indc_submissions.rb b/spec/factories/indc_submissions.rb new file mode 100644 index 0000000000..0449b40ef2 --- /dev/null +++ b/spec/factories/indc_submissions.rb @@ -0,0 +1,8 @@ +FactoryGirl.define do + factory :indc_submission, class: 'Indc::Submission' do + location + submission_type 'MySubmissionType' + language 'my-lang' + url 'http://internet.tld/path/file.ext' + end +end diff --git a/spec/factories/indc_values.rb b/spec/factories/indc_values.rb new file mode 100644 index 0000000000..190e2e2254 --- /dev/null +++ b/spec/factories/indc_values.rb @@ -0,0 +1,9 @@ +FactoryGirl.define do + factory :indc_value, class: 'Indc::Value' do + location + association :indicator, factory: :indc_indicator + association :label, factory: :indc_label + association :sector, factory: :indc_sector + value 'myvalue' + end +end diff --git a/spec/factories/wb_indc_categories.rb b/spec/factories/wb_indc_categories.rb deleted file mode 100644 index c8af415ed6..0000000000 --- a/spec/factories/wb_indc_categories.rb +++ /dev/null @@ -1,5 +0,0 @@ -FactoryGirl.define do - factory :wb_indc_category, class: 'WbIndc::Category' do - name 'MyText' - end -end diff --git a/spec/factories/wb_indc_indicator_types.rb b/spec/factories/wb_indc_indicator_types.rb deleted file mode 100644 index b06683df3a..0000000000 --- a/spec/factories/wb_indc_indicator_types.rb +++ /dev/null @@ -1,5 +0,0 @@ -FactoryGirl.define do - factory :wb_indc_indicator_type, class: 'WbIndc::IndicatorType' do - name 'MyText' - end -end diff --git a/spec/factories/wb_indc_indicators.rb b/spec/factories/wb_indc_indicators.rb deleted file mode 100644 index 3da9c90f7b..0000000000 --- a/spec/factories/wb_indc_indicators.rb +++ /dev/null @@ -1,21 +0,0 @@ -FactoryGirl.define do - factory :wb_indc_indicator, class: 'WbIndc::Indicator' do - association :indicator_type, factory: :wb_indc_indicator_type - name 'MyText' - code 'mytext' - - factory :wb_indc_indicator_with_dependants, - class: 'WbIndc::Indicator' do - transient do - categories_count 2 - end - - after(:create) do |indicator, evaluator| - indicator.categories = create_list( - :wb_indc_category, - evaluator.categories_count - ) - end - end - end -end diff --git a/spec/factories/wb_indc_sectors.rb b/spec/factories/wb_indc_sectors.rb deleted file mode 100644 index bd96c58866..0000000000 --- a/spec/factories/wb_indc_sectors.rb +++ /dev/null @@ -1,5 +0,0 @@ -FactoryGirl.define do - factory :wb_indc_sector, class: 'WbIndc::Sector' do - name 'MyText' - end -end diff --git a/spec/factories/wb_indc_values.rb b/spec/factories/wb_indc_values.rb deleted file mode 100644 index 812d3db1a9..0000000000 --- a/spec/factories/wb_indc_values.rb +++ /dev/null @@ -1,7 +0,0 @@ -FactoryGirl.define do - factory :wb_indc_value, class: 'WbIndc::Value' do - association :indicator, factory: :wb_indc_indicator - location - value 'MyText' - end -end diff --git a/spec/models/cait_indc/chart_spec.rb b/spec/models/cait_indc/chart_spec.rb deleted file mode 100644 index 07f3764690..0000000000 --- a/spec/models/cait_indc/chart_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'rails_helper' - -RSpec.describe CaitIndc::Chart, type: :model do - it 'should be invalid when name not present' do - expect( - FactoryGirl.build(:cait_indc_chart, name: nil) - ).to have(1).errors_on(:name) - end -end diff --git a/spec/models/cait_indc/indicator_spec.rb b/spec/models/cait_indc/indicator_spec.rb deleted file mode 100644 index de83c512b4..0000000000 --- a/spec/models/cait_indc/indicator_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'rails_helper' - -RSpec.describe CaitIndc::Indicator, type: :model do - it 'should be invalid when name not present' do - expect( - FactoryGirl.build(:cait_indc_indicator, name: nil) - ).to have(1).errors_on(:name) - end -end diff --git a/spec/models/cait_indc/label_spec.rb b/spec/models/cait_indc/label_spec.rb deleted file mode 100644 index 61e726593f..0000000000 --- a/spec/models/cait_indc/label_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'rails_helper' - -RSpec.describe CaitIndc::Label, type: :model do - it 'should be invalid when indicator not present' do - expect( - FactoryGirl.build(:cait_indc_label, indicator: nil) - ).to have(1).errors_on(:indicator) - end - - it 'should be invalid when name not present' do - expect( - FactoryGirl.build(:cait_indc_label, name: nil) - ).to have(1).errors_on(:name) - end -end diff --git a/spec/models/cait_indc/value_spec.rb b/spec/models/cait_indc/value_spec.rb deleted file mode 100644 index 3b0fbf6bfc..0000000000 --- a/spec/models/cait_indc/value_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'rails_helper' - -RSpec.describe CaitIndc::Value, type: :model do - it 'should be invalid when location not present' do - expect( - FactoryGirl.build(:cait_indc_value, location: nil) - ).to have(1).errors_on(:location) - end - - it 'should be invalid when indicator not present' do - expect( - FactoryGirl.build(:cait_indc_value, indicator: nil) - ).to have(1).errors_on(:indicator) - end -end diff --git a/spec/models/global_indc/indicator_spec.rb b/spec/models/global_indc/indicator_spec.rb deleted file mode 100644 index 7ad8a69d4e..0000000000 --- a/spec/models/global_indc/indicator_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'rails_helper' - -RSpec.describe GlobalIndc::Indicator, type: :model do - it 'should be invalid when referencing both cait and wb indicators' do - expect( - FactoryGirl.build( - :global_indc_indicator, - :with_cait_reference, - :with_wb_reference - ) - ).to have(1).errors_on(:base) - end -end diff --git a/spec/models/global_indc/category_spec.rb b/spec/models/indc/category_spec.rb similarity index 57% rename from spec/models/global_indc/category_spec.rb rename to spec/models/indc/category_spec.rb index 3d35a04798..ae89db92c2 100644 --- a/spec/models/global_indc/category_spec.rb +++ b/spec/models/indc/category_spec.rb @@ -1,15 +1,15 @@ require 'rails_helper' -RSpec.describe GlobalIndc::Category, type: :model do +RSpec.describe Indc::Category, type: :model do it 'should be invalid when name not present' do expect( - FactoryGirl.build(:global_indc_category, name: nil) + FactoryGirl.build(:indc_category, name: nil) ).to have(1).errors_on(:name) end it 'should be invalid when slug not present' do expect( - FactoryGirl.build(:global_indc_category, slug: nil) + FactoryGirl.build(:indc_category, slug: nil) ).to have(1).errors_on(:slug) end end diff --git a/spec/models/cait_indc/category_spec.rb b/spec/models/indc/category_type_spec.rb similarity index 54% rename from spec/models/cait_indc/category_spec.rb rename to spec/models/indc/category_type_spec.rb index 461973f65f..749bf62fba 100644 --- a/spec/models/cait_indc/category_spec.rb +++ b/spec/models/indc/category_type_spec.rb @@ -1,9 +1,9 @@ require 'rails_helper' -RSpec.describe CaitIndc::Category, type: :model do +RSpec.describe Indc::CategoryType, type: :model do it 'should be invalid when name not present' do expect( - FactoryGirl.build(:cait_indc_category, name: nil) + FactoryGirl.build(:indc_category_type, name: nil) ).to have(1).errors_on(:name) end end diff --git a/spec/models/indc/indicator_spec.rb b/spec/models/indc/indicator_spec.rb new file mode 100644 index 0000000000..484d64dc5c --- /dev/null +++ b/spec/models/indc/indicator_spec.rb @@ -0,0 +1,27 @@ +require 'rails_helper' + +describe Indc::Indicator, type: :model do + it 'should be invalid when name not present' do + expect( + FactoryGirl.build(:indc_indicator, name: nil) + ).to have(1).errors_on(:name) + end + + it 'should be invalid when slug not present' do + expect( + FactoryGirl.build(:indc_indicator, slug: nil) + ).to have(1).errors_on(:slug) + end + + it 'should be invalid when source not present' do + expect( + FactoryGirl.build(:indc_indicator, source: nil) + ).to have(1).errors_on(:source) + end + + it 'should be able to create indicator with all dependant records' do + expect( + FactoryGirl.build(:indc_indicator, :with_dependants) + ).to be_valid + end +end diff --git a/spec/models/indc/label_spec.rb b/spec/models/indc/label_spec.rb new file mode 100644 index 0000000000..44b386e726 --- /dev/null +++ b/spec/models/indc/label_spec.rb @@ -0,0 +1,21 @@ +require 'rails_helper' + +RSpec.describe Indc::Label, type: :model do + it 'should be invalid when indicator not present' do + expect( + FactoryGirl.build(:indc_label, indicator: nil) + ).to have(1).errors_on(:indicator) + end + + it 'should be invalid when value not present' do + expect( + FactoryGirl.build(:indc_label, value: nil) + ).to have(1).errors_on(:value) + end + + it 'should be invalid when index not present' do + expect( + FactoryGirl.build(:indc_label, index: nil) + ).to have(1).errors_on(:index) + end +end diff --git a/spec/models/wb_indc/sector_spec.rb b/spec/models/indc/sector_spec.rb similarity index 58% rename from spec/models/wb_indc/sector_spec.rb rename to spec/models/indc/sector_spec.rb index 6bc31e5535..b3597a4902 100644 --- a/spec/models/wb_indc/sector_spec.rb +++ b/spec/models/indc/sector_spec.rb @@ -1,9 +1,9 @@ require 'rails_helper' -describe WbIndc::Sector, type: :model do +describe Indc::Sector, type: :model do it 'should be invalid when name not present' do expect( - FactoryGirl.build(:wb_indc_sector, name: nil) + FactoryGirl.build(:indc_sector, name: nil) ).to have(1).errors_on(:name) end end diff --git a/spec/models/wb_indc/category_spec.rb b/spec/models/indc/source_spec.rb similarity index 57% rename from spec/models/wb_indc/category_spec.rb rename to spec/models/indc/source_spec.rb index 482f90a9c3..dfa7bc47ab 100644 --- a/spec/models/wb_indc/category_spec.rb +++ b/spec/models/indc/source_spec.rb @@ -1,9 +1,9 @@ require 'rails_helper' -describe WbIndc::Category, type: :model do +describe Indc::Source, type: :model do it 'should be invalid when name not present' do expect( - FactoryGirl.build(:wb_indc_category, name: nil) + FactoryGirl.build(:indc_source, name: nil) ).to have(1).errors_on(:name) end end diff --git a/spec/models/indc/submission_spec.rb b/spec/models/indc/submission_spec.rb new file mode 100644 index 0000000000..80642cbbeb --- /dev/null +++ b/spec/models/indc/submission_spec.rb @@ -0,0 +1,33 @@ +require 'rails_helper' + +describe Indc::Submission, type: :model do + it 'should be invalid when location not present' do + expect( + FactoryGirl.build(:indc_submission, location: nil) + ).to have(1).errors_on(:location) + end + + it 'should be invalid when submission_type not present' do + expect( + FactoryGirl.build(:indc_submission, submission_type: nil) + ).to have(1).errors_on(:submission_type) + end + + it 'should be invalid when language not present' do + expect( + FactoryGirl.build(:indc_submission, language: nil) + ).to have(1).errors_on(:language) + end + + it 'should be invalid when url not present' do + expect( + FactoryGirl.build(:indc_submission, url: nil) + ).to have(2).errors_on(:url) + end + + it 'should be invalid when url present but invalid' do + expect( + FactoryGirl.build(:indc_submission, url: 'not an url') + ).to have(1).errors_on(:url) + end +end diff --git a/spec/models/wb_indc/value_spec.rb b/spec/models/indc/value_spec.rb similarity index 51% rename from spec/models/wb_indc/value_spec.rb rename to spec/models/indc/value_spec.rb index bcc85fadd4..fb0ca7f9eb 100644 --- a/spec/models/wb_indc/value_spec.rb +++ b/spec/models/indc/value_spec.rb @@ -1,21 +1,27 @@ require 'rails_helper' -describe WbIndc::Value, type: :model do +describe Indc::Value, type: :model do it 'should be invalid when indicator not present' do expect( - FactoryGirl.build(:wb_indc_value, indicator: nil) + FactoryGirl.build(:indc_value, indicator: nil) ).to have(1).errors_on(:indicator) end it 'should be invalid when location not present' do expect( - FactoryGirl.build(:wb_indc_value, location: nil) + FactoryGirl.build(:indc_value, location: nil) ).to have(1).errors_on(:location) end + it 'should be invalid when value not present' do + expect( + FactoryGirl.build(:indc_value, value: nil) + ).to have(1).errors_on(:value) + end + it 'should not be invalid when sector not present' do expect( - FactoryGirl.build(:wb_indc_value, sector: nil) + FactoryGirl.build(:indc_value, sector: nil) ).to have(0).errors_on(:sector) end end diff --git a/spec/models/wb_indc/indicator_spec.rb b/spec/models/wb_indc/indicator_spec.rb deleted file mode 100644 index 853b62bfdf..0000000000 --- a/spec/models/wb_indc/indicator_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'rails_helper' - -describe WbIndc::Indicator, type: :model do - it 'should be invalid when name not present' do - expect( - FactoryGirl.build(:wb_indc_indicator, name: nil) - ).to have(1).errors_on(:name) - end - - it 'should be invalid when indicator_type not present' do - expect( - FactoryGirl.build(:wb_indc_indicator, indicator_type: nil) - ).to have(1).errors_on(:indicator_type) - end - - it 'should be able to create indicator with all dependant records' do - expect( - FactoryGirl.build(:wb_indc_indicator_with_dependants) - ).to be_valid - end -end diff --git a/spec/models/wb_indc/indicator_type_spec.rb b/spec/models/wb_indc/indicator_type_spec.rb deleted file mode 100644 index deebc466d2..0000000000 --- a/spec/models/wb_indc/indicator_type_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'rails_helper' - -describe WbIndc::IndicatorType, type: :model do - it 'should be invalid when name not present' do - expect( - FactoryGirl.build(:wb_indc_indicator_type, name: nil) - ).to have(1).errors_on(:name) - end -end diff --git a/spec/services/import_cait_indc_spec.rb b/spec/services/import_cait_indc_spec.rb deleted file mode 100644 index 0fc0e951d6..0000000000 --- a/spec/services/import_cait_indc_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -require 'rails_helper' - -object_contents = { - "#{CW_FILES_PREFIX}cait_indc/CW_NDC_CAIT_metadata.csv" => <<~END, - category,column_name,long_name - General,domestic_approval,Domestic Approval Processes Category - END - "#{CW_FILES_PREFIX}cait_indc/CW_NDC_CAIT_legend.csv" => <<~END, - indicator_name,legend_item,chart_title - domestic_approval,Executive,Domestic Approval Process - domestic_approval,Executive + notify legislature,Domestic Approval Process - domestic_approval,Executive + majority of one legislative body,Domestic Approval Process - domestic_approval,Executive + majority of two legislative bodies/super-majority of one legislative body,Domestic Approval Process - domestic_approval,Multiple executive and legislative bodies,Domestic Approval Process - domestic_approval,Not yet included in analysis,Domestic Approval Process - END - "#{CW_FILES_PREFIX}cait_indc/CW_NDC_CAIT_data.csv" => <<~END, - country,ISO,domestic_approval,domestic_approval_label - Afghanistan,AFG,Executive + majority of two legislative bodies,Executive + majority of two legislative bodies/super-majority of one legislative body - Algeria,DZA,Executive,Executive - Andorra,AND,Not yet included in analysis - END - "#{CW_FILES_PREFIX}cait_indc/CW_NDC_Submission_URL.csv" => <<~END - ISO,Country,Type,Language,Date_of_Submission,URL - AFG,Afghanistan,INDC,English,10/13/2015,http://www4.unfccc.int/Submissions/INDC/Published Documents/Afghanistan/1/INDC_AFG_Paper_En_20150927_.docx FINAL.pdf - END -} - -RSpec.describe ImportCaitIndc do - subject { ImportCaitIndc.new.call } - - before :all do - Aws.config[:s3] = { - stub_responses: { - get_object: lambda { |context| - {body: object_contents[context.params[:key]]} - } - } - } - end - - before :each do - [{ - iso_code3: 'AFG', - wri_standard_name: 'Afghanistan' - }, { - iso_code3: 'DZA', - wri_standard_name: 'Algeria' - }, { - iso_code3: 'AND', - wri_standard_name: 'Andorra' - }].each do |c| - FactoryGirl.create(:location, c) - end - end - - after :all do - Aws.config[:s3] = { - stub_responses: nil - } - end - - it 'Creates new CAIT INDC records' do - expect { subject }.to change { CaitIndc::Value.count }.by(3) - end - - it 'Creates new INDC submission records' do - expect { subject }.to change { CaitIndc::Submission.count }.by(1) - end -end diff --git a/spec/services/import_global_indc_spec.rb b/spec/services/import_global_indc_spec.rb deleted file mode 100644 index 8f45dd74d7..0000000000 --- a/spec/services/import_global_indc_spec.rb +++ /dev/null @@ -1,104 +0,0 @@ -require 'rails_helper' - -object_contents = { - "#{CW_FILES_PREFIX}cait_indc/CW_NDC_CAIT_metadata.csv" => <<~END, - category,column_name,long_name - General,domestic_approval,Domestic Approval Processes Category - END - "#{CW_FILES_PREFIX}cait_indc/CW_NDC_CAIT_legend.csv" => <<~END, - indicator_name,legend_item,chart_title - domestic_approval,Executive,Domestic Approval Process - domestic_approval,Executive + notify legislature,Domestic Approval Process - domestic_approval,Executive + majority of one legislative body,Domestic Approval Process - domestic_approval,Executive + majority of two legislative bodies/super-majority of one legislative body,Domestic Approval Process - domestic_approval,Multiple executive and legislative bodies,Domestic Approval Process - domestic_approval,Not yet included in analysis,Domestic Approval Process - END - "#{CW_FILES_PREFIX}cait_indc/CW_NDC_CAIT_data.csv" => <<~END, - country,ISO,domestic_approval,domestic_approval_label - Afghanistan,AFG,Executive + majority of two legislative bodies,Executive + majority of two legislative bodies/super-majority of one legislative body - Algeria,DZA,Executive,Executive - Andorra,AND,Not yet included in analysis - END - "#{CW_FILES_PREFIX}cait_indc/CW_NDC_Submission_URL.csv" => <<~END, - ISO,Country,Type,Language,Date_of_Submission,URL - AFG,Afghanistan,INDC,English,10/13/2015,http://www4.unfccc.int/Submissions/INDC/Published Documents/Afghanistan/1/INDC_AFG_Paper_En_20150927_.docx FINAL.pdf - END - "#{CW_FILES_PREFIX}wb_indc/CW_NDC_WB_metadata_w_definitions.csv" => <<~END, - QuestionType,category,category_2,QuestionCode,QuestionText,Definition - Adaptation,General Information,Adaptation Target,A_Tg_AdInclu,Adaptation Included in INDC (Yes/No),Whether or not the NDC includes adaptation - Adaptation,General Information,Adaptation Target,A_Tg_TarYr,Target Year for Adaptation,The year by which adaptation objectives are expected to be achieved - Adaptation,Sectoral Information,Sectoral Commitments,A_Sc_CapBud,Capacity Building Needs for Sectorial Implementation - Adaptation,Sectoral Information,Sectoral Commitments,A_Sc_ConAct,Sectorial Conditional Actions - Mitigation,Economy-wide Information,Target,M_TarYr,Target year - END - "#{CW_FILES_PREFIX}wb_indc/CW_NDC_WB_sectoral.csv" => <<~END, - CountryCode,Sector,SubSector,QuestionCode,ResponseText - AF,Water,Water Infrastructure,A_Sc_CapBud,Ecological engineering and spatial planning for water resources - AF,Water,Water Infrastructure,A_Sc_ConAct,"Development of water resources through rehabilitation and reconstruction of small-, medium-, and large-scale infrastructure" - END - "#{CW_FILES_PREFIX}wb_indc/CW_NDC_WB_economy_wide.csv" => <<~END, - CountryCode,QuestionCode,ResponseText - AF,A_Tg_AdInclu,Yes - AF,A_Tg_TarYr,2030 - AF,M_TarYr,2030 - DZ,A_Tg_AdInclu,Yes - DZ,A_Tg_TarYr,2030 - DZ,M_TarYr,2030 - END - "#{CW_FILES_PREFIX}global_indc/CW_NDC_metadata_combined.csv" => <<~END - category,category_2,column_name,long_name,Definition,Source - Overview,NDC,domestic_approval,,,CAIT - Mitigation,Target,A_Tg_AdInclu,,,WB - Mitigation,Target,M_TarYr,,,WB - END -} - -RSpec.describe ImportGlobalIndc do - subject { ImportGlobalIndc.new.call } - - before :all do - Aws.config[:s3] = { - stub_responses: { - get_object: lambda { |context| - {body: object_contents[context.params[:key]]} - } - } - } - end - - before :each do - [{ - iso_code3: 'AFG', - iso_code2: 'AF', - wri_standard_name: 'Afghanistan' - }, { - iso_code3: 'DZA', - iso_code2: 'DZ', - wri_standard_name: 'Algeria' - }, { - iso_code3: 'AND', - iso_code2: 'AD', - wri_standard_name: 'Andorra' - }].each do |c| - FactoryGirl.create(:location, c) - end - - ImportCaitIndc.new.call - ImportWbIndc.new.call - end - - after :all do - Aws.config[:s3] = { - stub_responses: nil - } - end - - it 'Creates new global INDC categories' do - expect { subject }.to change { GlobalIndc::Category.count }.by(4) - end - - it 'Creates new global INDC indicator links' do - expect { subject }.to change { GlobalIndc::Indicator.count }.by(3) - end -end diff --git a/spec/services/import_indc.rb b/spec/services/import_indc.rb new file mode 100644 index 0000000000..d51894d125 --- /dev/null +++ b/spec/services/import_indc.rb @@ -0,0 +1,120 @@ +require 'rails_helper' + +object_contents = { + "#{CW_FILES_PREFIX}indc/NDC_metadata.csv" => <<~END, + global_category,main_category,map_category,column_name,long_name,Definition,Source + Overview,UNFCCC Process,Other,domestic_approval,Domestic Approval Processes Category,,CAIT + Mitigation,Target,,M_TarYr,Target year,The year by which mitigation objectives are expected to be achieved,WB + Mitigation,Target,,M_TarYr_2,Second target year,Whether the NDC has a second-year target,WB + Adaptation,Adaptation Target,,A_Tg_AdInclu,Adaptation Included in INDC (Yes/No),Whether or not the NDC includes adaptation,WB + Adaptation,Adaptation Target,,A_Tg_TarYr,Target Year for Adaptation,The year by which adaptation objectives are expected to be achieved,WB + Sectoral Information,Sectoral Adaptation Commitments,,A_Sc_ConAct,Sectorial Conditional Actions,Condition actions of the sectoral level,WB + Sectoral Information,Sectoral Adaptation Commitments,,A_Sc_ConActP,Page Number for Sectorial Conditional Actions,Link to the page reference for the sectoral condition actions,WB + Sectoral Information,Sectoral Adaptation Commitments,,A_Sc_ConActImp,Implementing Agency for Sectorial Conditonal Actions,The agency responsible for implementing the sectoral conditional action,WB + Sectoral Information,Sectoral Adaptation Commitments,,A_Sc_ConActDon,Funders for Sectorial Conditional Actions,The funders for sectoral conditional actions,WB + Sectoral Information,Sectoral Adaptation Commitments,,A_Sc_ConActCost,Estimated Cost for Sectorial Conditional Actions ,The estimated costs for sectoral conditional actions,WB + Sectoral Information,,,A_Sc_ConActCostH,Estimated Cost for Sectorial Conditional Actions (Harmonized in Million USD),,WB + Sectoral Information,Sectoral Adaptation Commitments,,A_Sc_CapBud,Capacity Building Needs for Sectorial Implementation,Capacity building needs for sectorial implementation,WB + END + + "#{CW_FILES_PREFIX}indc/NDC_submission.csv" => <<~END, + ISO,Country,Type,Language,Date_of_Submission,URL + AFG,Afghanistan,INDC,English,10/13/2015,http://www4.unfccc.int/Submissions/INDC/Published Documents/Afghanistan/1/INDC_AFG_Paper_En_20150927_.docx FINAL.pdf + END + + "#{CW_FILES_PREFIX}indc/NDC_CAIT_data.csv" => <<~END, + country,ISO,domestic_approval,domestic_approval_label + Afghanistan,AFG,Executive + majority of two legislative bodies,Executive + majority of two legislative bodies/super-majority of one legislative body + Algeria,DZA,Executive,Executive + Andorra,AND,Not yet included in analysis + END + + "#{CW_FILES_PREFIX}indc/NDC_CAIT_legend.csv" => <<~END, + indicator_name,legend_item,chart_title + domestic_approval,Executive,Domestic Approval Process + domestic_approval,Executive + notify legislature,Domestic Approval Process + domestic_approval,Executive + majority of one legislative body,Domestic Approval Process + domestic_approval,Executive + majority of two legislative bodies/super-majority of one legislative body,Domestic Approval Process + domestic_approval,Multiple executive and legislative bodies,Domestic Approval Process + domestic_approval,Not yet included in analysis,Domestic Approval Process + END + + "#{CW_FILES_PREFIX}indc/NDC_WB_data_sectoral.csv" => <<~END, + CountryCode,Sector,SubSector,QuestionCode,ResponseText + AF,Water,Water Infrastructure,A_Sc_CapBud,Ecological engineering and spatial planning for water resources + AF,Water,Water Infrastructure,A_Sc_ConAct,"Development of water resources through rehabilitation and reconstruction of small-, medium-, and large-scale infrastructure" + END + + "#{CW_FILES_PREFIX}indc/NDC_WB_data_wide.csv" => <<~END, + CountryCode,QuestionCode,ResponseText + AF,A_Tg_AdInclu,Yes + AF,A_Tg_TarYr,2030 + AF,M_TarYr,2030 + DZ,A_Tg_AdInclu,Yes + DZ,A_Tg_TarYr,2030 + DZ,M_TarYr,2030 + END + +} + +describe ImportIndc do + subject { ImportIndc.new.call } + + before :all do + Aws.config[:s3] = { + stub_responses: { + get_object: lambda { |context| + {body: object_contents[context.params[:key]]} + } + } + } + end + + before :each do + [{ + iso_code3: 'AFG', + iso_code2: 'AF', + wri_standard_name: 'Afghanistan' + }, { + iso_code3: 'DZA', + iso_code2: 'DZ', + wri_standard_name: 'Algeria' + }, { + iso_code3: 'AND', + iso_code2: 'AD', + wri_standard_name: 'Andorra' + }].each do |c| + FactoryGirl.create(:location, c) + end + end + + after :all do + Aws.config[:s3] = { + stub_responses: nil + } + end + + it 'Creates new INDC source records' do + expect { subject }.to change { Indc::Source.count }.by(2) + end + + it 'Creates new INDC category records' do + expect { subject }.to change { Indc::Category.count }.by(9) + end + + it 'Creates new INDC indicator records' do + expect { subject }.to change { Indc::Indicator.count }.by(12) + end + + it 'Creates new INDC sector records' do + expect { subject }.to change { Indc::Sector.count }.by(2) + end + + it 'Creates new INDC value records' do + expect { subject }.to change { Indc::Value.count }.by(11) + end + + it 'Creates new INDC submission records' do + expect { subject }.to change { Indc::Submission.count }.by(1) + end +end diff --git a/spec/services/import_wb_indc_spec.rb b/spec/services/import_wb_indc_spec.rb deleted file mode 100644 index c4efb9e0d9..0000000000 --- a/spec/services/import_wb_indc_spec.rb +++ /dev/null @@ -1,62 +0,0 @@ -require 'rails_helper' - -object_contents = { - "#{CW_FILES_PREFIX}wb_indc/CW_NDC_WB_metadata_w_definitions.csv" => <<~END, - QuestionType,category,category_2,QuestionCode,QuestionText,Definition - Adaptation,General Information,Adaptation Target,A_Tg_AdInclu,Adaptation Included in INDC (Yes/No),Whether or not the NDC includes adaptation - Adaptation,General Information,Adaptation Target,A_Tg_TarYr,Target Year for Adaptation,The year by which adaptation objectives are expected to be achieved - Adaptation,Sectoral Information,Sectoral Commitments,A_Sc_CapBud,Capacity Building Needs for Sectorial Implementation - Adaptation,Sectoral Information,Sectoral Commitments,A_Sc_ConAct,Sectorial Conditional Actions - Mitigation,Economy-wide Information,Target,M_TarYr,Target year - END - "#{CW_FILES_PREFIX}wb_indc/CW_NDC_WB_sectoral.csv" => <<~END, - CountryCode,Sector,SubSector,QuestionCode,ResponseText - AF,Water,Water Infrastructure,A_Sc_CapBud,Ecological engineering and spatial planning for water resources - AF,Water,Water Infrastructure,A_Sc_ConAct,"Development of water resources through rehabilitation and reconstruction of small-, medium-, and large-scale infrastructure" - END - "#{CW_FILES_PREFIX}wb_indc/CW_NDC_WB_economy_wide.csv" => <<~END - CountryCode,QuestionCode,ResponseText - AF,A_Tg_AdInclu,Yes - AF,A_Tg_TarYr,2030 - AF,M_TarYr,2030 - DZ,A_Tg_AdInclu,Yes - DZ,A_Tg_TarYr,2030 - DZ,M_TarYr,2030 - END -} - -describe ImportWbIndc do - subject { ImportWbIndc.new.call } - - before :all do - Aws.config[:s3] = { - stub_responses: { - get_object: lambda { |context| - {body: object_contents[context.params[:key]]} - } - } - } - end - - before :each do - [{ - iso_code2: 'AF', - wri_standard_name: 'Afghanistan' - }, { - iso_code2: 'DZ', - wri_standard_name: 'Algeria' - }].each do |c| - FactoryGirl.create(:location, c) - end - end - - after :all do - Aws.config[:s3] = { - stub_responses: nil - } - end - - it 'Creates new WB INDC records' do - expect { subject }.to change { WbIndc::Value.count }.by(8) - end -end