diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 69d86eb83..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,95 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -// -// const prettierOptions = JSON.parse( -// fs.readFileSync(path.resolve(__dirname, '.prettierrc'), 'utf8'), -// ); - -module.exports = { - "parser": "babel-eslint", - "extends": "airbnb", - "env": { - "browser": true, - "node": true, - "jest": true, - "es6": true - }, - "plugins": [ - "redux-saga", - "react", - "jsx-a11y" - ], - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module", - "ecmaFeatures": { - "jsx": true - } - }, - "rules": { - "arrow-parens": [ - "error", - "always" - ], - "arrow-body-style": [ - 2, - "as-needed" - ], - "camelcase": 0, - "comma-dangle": [ - 2, - "always-multiline" - ], - "import/imports-first": 0, - "import/newline-after-import": 0, - "import/no-dynamic-require": 0, - "import/no-extraneous-dependencies": 0, - "import/no-named-as-default": 0, - "import/no-unresolved": 2, - "import/prefer-default-export": 0, - "indent": [ - 2, - 2, - { - "SwitchCase": 1 - } - ], - "jsx-a11y/aria-props": 2, - "jsx-a11y/heading-has-content": 0, - "jsx-a11y/label-has-for": 2, - "jsx-a11y/mouse-events-have-key-events": 2, - "jsx-a11y/role-has-required-aria-props": 2, - "jsx-a11y/role-supports-aria-props": 2, - "max-len": 0, - "newline-per-chained-call": 0, - "no-confusing-arrow": 0, - "no-console": 1, - "no-use-before-define": 0, - "prefer-template": 2, - "class-methods-use-this": 0, - "react/forbid-prop-types": 0, - "react/jsx-first-prop-new-line": [ - 2, - "multiline" - ], - "react/jsx-filename-extension": 0, - "react/jsx-no-target-blank": 0, - "react/no-array-index-key": 0, - "react/require-default-props": 0, - "react/require-extension": 0, - "react/destructuring-assignment": 0, - "react/self-closing-comp": 0, - "react/sort-comp": 0, - "redux-saga/no-yield-in-race": 2, - "redux-saga/yield-effects": 2, - "require-yield": 0, - "import/no-webpack-loader-syntax": 0 - }, - "settings": { - "import/resolver": { - "webpack": { - "config": "./internals/webpack/webpack.prod.babel.js" - } - } - } -}; diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..e9ee3cb4d --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +legacy-peer-deps=true \ No newline at end of file diff --git a/.stylelintrc b/.stylelintrc index 9e72e47c6..422a606f5 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -1,7 +1,26 @@ -{ - "processors": ["stylelint-processor-styled-components"], - "extends": [ - "stylelint-config-recommended", - "stylelint-config-styled-components" - ] +{ + "extends": [ + "stylelint-config-standard" + ], + "customSyntax": "postcss-styled-syntax", + "rules":{ + "at-rule-empty-line-before": null, + "media-query-no-invalid": null, + "alpha-value-notation": null, + "rule-empty-line-before": null, + "length-zero-no-unit": null, + "declaration-empty-line-before": "never", + "selector-class-pattern": null, + "no-empty-source": null, + "declaration-block-no-redundant-longhand-properties": null, + "color-function-notation": null, + "media-feature-range-notation": null, + "comment-empty-line-before": null, + "color-hex-length": null, + "number-max-precision": null, + "no-descending-specificity": null, + "custom-property-empty-line-before": null, + "shorthand-property-no-redundant-values": null, + "property-no-vendor-prefix": null + } } diff --git a/app/app.js b/app/app.js index 89063c746..11e2f6a26 100644 --- a/app/app.js +++ b/app/app.js @@ -6,15 +6,17 @@ */ // Needed for redux-saga es6 generator support -import '@babel/polyfill'; +import 'core-js/stable'; +import 'regenerator-runtime/runtime'; // Import all the third party stuff import React from 'react'; -import ReactDOM from 'react-dom'; +import { createRoot } from 'react-dom/client'; import { Provider } from 'react-redux'; import { Router, browserHistory } from 'react-router'; import { syncHistoryWithStore } from 'react-router-redux'; import 'sanitize.css/sanitize.css'; +import './fonts.css'; // Import root app import App from 'containers/App'; @@ -27,22 +29,13 @@ import LanguageProvider from 'containers/LanguageProvider'; // Import ThemeProvider import { Grommet } from 'grommet'; + +import { StyleSheetManager } from 'styled-components'; +import isPropValid from '@emotion/is-prop-valid'; + import theme from 'themes/theme-nz'; import './fonts/fonts.css'; -// Load the favicon, and the .htaccess file -/* eslint-disable import/no-unresolved, import/extensions */ -import '!file-loader?name=[name].[ext]!./favicon.ico'; -import '!file-loader?name=[name].[ext]!./favicon-16x16.png'; -import '!file-loader?name=[name].[ext]!./favicon-32x32.png'; -import '!file-loader?name=[name].[ext]!./android-chrome-192x192.png'; -import '!file-loader?name=[name].[ext]!./android-chrome-256x256.png'; -import '!file-loader?name=[name].[ext]!./mstile-150x150.png'; -import '!file-loader?name=[name].[ext]!./apple-touch-icon.png'; -import '!file-loader?name=[name].[ext]!./safari-pinned-tab.svg'; -import 'file-loader?name=[name].[ext]!./.htaccess'; -/* eslint-enable import/no-unresolved, import/extensions */ - import configureStore from './store'; // Import i18n messages @@ -71,20 +64,32 @@ const rootRoute = { childRoutes: createRoutes(store), }; -// console.log(this.props.location) +const container = document.getElementById('app'); +const root = createRoot(container); const render = (messages) => { - ReactDOM.render( + root.render( - - - + { + if (typeof target === "string") { + // For HTML elements, forward the prop if it is a valid HTML attribute + return isPropValid(propName); + } + // For other elements, forward all props + return true; + }} + > + + + + - , - document.getElementById('app'), + ); }; @@ -98,6 +103,7 @@ if (module.hot) { } // Chunked polyfill for browsers without Intl support +/* eslint-disable import/extensions */ if (!window.Intl) { new Promise((resolve) => { resolve(import('intl')); @@ -110,7 +116,7 @@ if (!window.Intl) { } else { render(translationMessages); } - +/* // Install ServiceWorker and AppCache in the end since // it's not most important operation and if main code fails, // we do not want it installed @@ -123,4 +129,4 @@ if (process.env.NODE_ENV === 'production') { runtime.applyUpdate(); }, }); -} +}*/ diff --git a/app/components/ContentNarrow/index.js b/app/components/ContentNarrow/index.js index 82c550bee..561433552 100644 --- a/app/components/ContentNarrow/index.js +++ b/app/components/ContentNarrow/index.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; -import Grid from 'grid-styled'; +import { Box } from 'grommet'; import Content from 'components/Content'; import Row from 'components/styled/Row'; @@ -10,40 +10,58 @@ import Row from 'components/styled/Row'; const RowStyled = styled(Row)` margin: 0; + display: flex; @media (min-width: ${(props) => props.theme.breakpoints.small}) { margin-right: -${(props) => props.theme.gutter}px; margin-left: -${(props) => props.theme.gutter}px; } `; -const GridSpace = styled(Grid)` - display: none !important; - @media (min-width: ${(props) => props.theme.breakpoints.small}) { +const GridSpace = styled((p) => )` + @media (min-width: 0px) { + display: none !important; + } + @media (min-width: ${({ theme }) => theme.breakpoints.small}) { + display: inline-block !important; + flex-basis: 25%; + } + @media (min-width: ${({ theme }) => theme.breakpoints.medium}) { + display: inline-block !important; + flex-basis: 33%; + } + @media (min-width: ${({ theme }) => theme.breakpoints.large}) { display: inline-block !important; + flex-basis: 33%; } `; -const GridMain = styled(Grid)` +const GridMain = styled((p) => )` padding-right: 0 !important; padding-left: 0 !important; - @media (min-width: ${(props) => props.theme.breakpoints.small}) { - padding-right: ${(props) => props.theme.gutter}px !important; - padding-left: ${(props) => props.theme.gutter}px !important; + @media (min-width: 0px) { + flex-basis: 100%; + } + @media (min-width: ${({ theme }) => theme.breakpoints.small}) { + padding-right: ${({ theme }) => theme.gutter}px !important; + padding-left: ${({ theme }) => theme.gutter}px !important; + flex-basis: 50%; + } + @media (min-width: ${({ theme }) => theme.breakpoints.medium}) { + flex-basis: 40%; + } + @media (min-width: ${({ theme }) => theme.breakpoints.large}) { + flex-basis: 33%; } `; -class ContentNarrow extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function - render() { - return ( - - - - - {this.props.children} - - - - ); - } -} +const ContentNarrow = ({ children }) => ( + + + + + {children} + + + +); ContentNarrow.propTypes = { children: PropTypes.node, diff --git a/app/components/EntityListDownload/CsvDownloadHandler.js b/app/components/EntityListDownload/CsvDownloadHandler.js new file mode 100644 index 000000000..5dce280a1 --- /dev/null +++ b/app/components/EntityListDownload/CsvDownloadHandler.js @@ -0,0 +1,12 @@ +import React from 'react'; +import { useCSVDownloader } from 'react-papaparse'; + +const CsvDownloadHandler = ({ children, ...props }) => { + const { CSVDownloader } = useCSVDownloader(); + return ( + + {children} + + ); +}; +export default CsvDownloadHandler; \ No newline at end of file diff --git a/app/components/EntityListDownload/OptionGroupToggle.js b/app/components/EntityListDownload/OptionGroupToggle.js index 40b76fbf4..55321bb04 100644 --- a/app/components/EntityListDownload/OptionGroupToggle.js +++ b/app/components/EntityListDownload/OptionGroupToggle.js @@ -6,7 +6,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { injectIntl, intlShape } from 'react-intl'; +import { useIntl } from 'react-intl'; import styled from 'styled-components'; import { palette } from 'styled-theme'; import { Button, Box, Text } from 'grommet'; @@ -35,8 +35,9 @@ const Count = styled((p) => )` `; export function OptionGroupToggle({ - label, onToggle, expanded, activeCount, optionCount, intl, + label, onToggle, expanded, activeCount, optionCount, }) { + const intl = useIntl(); return ( onClose()}> - - + )} @@ -480,7 +481,6 @@ EntityListDownload.propTypes = { entityIdsSelected: PropTypes.object, hasUserRole: PropTypes.object, entityTitle: PropTypes.object, - intl: intlShape, }; -export default injectIntl(EntityListDownload); +export default EntityListDownload; diff --git a/app/components/EntityListItem/EntityListItemExpandable.js b/app/components/EntityListItem/EntityListItemExpandable.js index 4c1c7d0a9..c91c4a585 100644 --- a/app/components/EntityListItem/EntityListItemExpandable.js +++ b/app/components/EntityListItem/EntityListItemExpandable.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import { palette } from 'styled-theme'; +import { injectIntl } from 'react-intl'; import Component from 'components/styled/Component'; import Icon from 'components/Icon'; @@ -57,9 +58,9 @@ class EntityListItemExpandable extends React.PureComponent { // eslint-disable-l dates, colWidth, column, + intl, } = this.props; const { type, icon } = column; - const { intl } = this.context; const info = []; if (dates) { if (dates.due) { @@ -94,13 +95,11 @@ EntityListItemExpandable.propTypes = { onClick: PropTypes.func, colWidth: PropTypes.number, dates: PropTypes.object, + intl: PropTypes.object.isRequired, }; EntityListItemExpandable.defaultProps = { count: 0, }; -EntityListItemExpandable.contextTypes = { - intl: PropTypes.object, -}; -export default EntityListItemExpandable; +export default injectIntl(EntityListItemExpandable); diff --git a/app/components/EntityListItem/EntityListItemMain/EntityListItemMainBottom/ConnectionPopup.js b/app/components/EntityListItem/EntityListItemMain/EntityListItemMainBottom/ConnectionPopup.js index 47fed899c..ec0396f38 100644 --- a/app/components/EntityListItem/EntityListItemMain/EntityListItemMainBottom/ConnectionPopup.js +++ b/app/components/EntityListItem/EntityListItemMain/EntityListItemMainBottom/ConnectionPopup.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import { palette } from 'styled-theme'; +import { injectIntl } from 'react-intl'; // import Link from 'containers/Link'; import { TEXT_TRUNCATE } from 'themes/config'; @@ -92,7 +93,7 @@ const TriangleBottom = styled.div` }}%; margin-left: -10px; - &:after { + &::after { content: ""; position: absolute; width: 20px; @@ -186,9 +187,8 @@ export class ConnectionPopup extends React.PureComponent { // eslint-disable-lin render() { const { - entities, option, wrapper, draft, + entities, option, wrapper, draft, intl, } = this.props; - const { intl } = this.context; const entitiesTotal = entities ? entities.size : 0; return ( { - const { intl } = this.context; - return intl + getSmartTitle = (title, isSmart, intl) => + intl ? `${title}: ${intl.formatMessage(isSmart ? appMessages.labels.smart.met : appMessages.labels.smart.notMet)}` : title; - }; - getEntitySmartTags = (categories, smartTaxonomy, onClick) => { + getEntitySmartTags = (categories, smartTaxonomy, onClick, intl) => { const tags = []; smartTaxonomy .get('categories') @@ -79,7 +79,7 @@ class EntityListItemMainTaxonomies extends React.PureComponent { // eslint-disab const isSmart = categories && categories.includes(parseInt(catId, 10)); tags.push({ taxId: smartTaxonomy.get('id'), - title: this.getSmartTitle(category.getIn(['attributes', 'title']), isSmart), + title: this.getSmartTitle(category.getIn(['attributes', 'title']), isSmart, intl), isSmart, label: truncateText(label, TEXT_TRUNCATE.ENTITY_TAG, false), onClick: () => onClick(catId, 'category'), @@ -90,7 +90,7 @@ class EntityListItemMainTaxonomies extends React.PureComponent { // eslint-disab render() { - const { categories, taxonomies, onEntityClick } = this.props; + const { categories, taxonomies, onEntityClick, intl } = this.props; const smartTaxonomy = taxonomies && taxonomies.find((tax) => tax.getIn(['attributes', 'is_smart'])); const entityTags = categories && this.getEntityTags(categories, taxonomies, onEntityClick); @@ -98,7 +98,7 @@ class EntityListItemMainTaxonomies extends React.PureComponent { // eslint-disab {smartTaxonomy && ( 0}> - { this.getEntitySmartTags(categories, smartTaxonomy, onEntityClick).map((tag, i) => ( + {this.getEntitySmartTags(categories, smartTaxonomy, onEntityClick, intl).map((tag, i) => ( { - const { intl } = this.context; - return reduce(connectionOptions, (memo, option) => { + getConnections = (entity, connectionOptions, connections, intl) => + reduce(connectionOptions, (memo, option) => { // console.log(memo, option, entity.toJS()) let memoX = memo; if ( @@ -158,17 +159,15 @@ class EntityListItemMain extends React.PureComponent { // eslint-disable-line re } return memoX; }, []); - }; getRole = (entityRoles, roles) => { const role = roles.find((r) => parseInt(r.get('id'), 10) === entityRoles.first()); // console.log('roles entityRoles.first()', entityRoles.first()) // console.log('roles role', role) return role ? parseInt(role.get('id'), 10) : USER_ROLES.DEFAULT.value; - } + }; - getReference = (entity) => { - const { intl } = this.context; + getReference = (entity, intl) => { const reference = entity.getIn(['attributes', 'reference']) || entity.get('id'); let type = entity.get('type'); if (entity.getIn(['attributes', 'framework_id'])) { @@ -181,7 +180,7 @@ class EntityListItemMain extends React.PureComponent { // eslint-disable-line re return `${intl.formatMessage(appMessages.entities[type].singleShort)}: ${reference}`; } return reference; - } + }; getProgressTaxonomy = (taxonomies) => taxonomies && taxonomies.find((tax) => qe(tax.get('id'), PROGRESS_TAXONOMY_ID)); @@ -193,7 +192,7 @@ class EntityListItemMain extends React.PureComponent { // eslint-disable-line re (cat) => categoryIds.includes(parseInt(cat.get('id'), 10)) ); return progressCategory && progressCategory.toJS(); - } + }; getWithoutProgressCategories = (taxonomies, categoryIds) => { const progressTaxonomy = taxonomies && this.getProgressTaxonomy(taxonomies); @@ -207,7 +206,7 @@ class EntityListItemMain extends React.PureComponent { // eslint-disable-line re } ) : categoryIds; - } + }; mapToEntityListItem = ({ config, @@ -216,8 +215,8 @@ class EntityListItemMain extends React.PureComponent { // eslint-disable-line re entityPath, connections, taxonomies, + intl, }) => { - const { intl } = this.context; let path = ''; if (entityPath) { path = entityPath; @@ -237,7 +236,7 @@ class EntityListItemMain extends React.PureComponent { // eslint-disable-line re id: entity.get('id'), title: entity.getIn(['attributes', 'name']) || entity.getIn(['attributes', 'title']), subtitle: config && config.sublabel && entity.getIn(['attributes', config.sublabel]), - reference: this.getReference(entity), + reference: this.getReference(entity, intl), draft: entity.getIn(['attributes', 'draft']), is_archive: entity.getIn(['attributes', 'is_archive']), is_current: entity.getIn(['attributes', 'is_current']), @@ -246,7 +245,7 @@ class EntityListItemMain extends React.PureComponent { // eslint-disable-line re support: supportLevel, categories: taxonomies && this.getWithoutProgressCategories(taxonomies, entity.get('categories')), connectedCounts: config && config.connections - ? this.getConnections(entity, config.connections.options, connections) + ? this.getConnections(entity, config.connections.options, connections, intl) : [], assignedUser: entity.get('manager') && ({ name: entity.getIn(['manager', 'attributes', 'name']) }), targetDate: entity.getIn(['attributes', 'target_date']) @@ -254,7 +253,7 @@ class EntityListItemMain extends React.PureComponent { // eslint-disable-line re && intl.formatDate(entity.getIn(['attributes', 'target_date'])), progressCategory: taxonomies && this.getProgressCategory(taxonomies, entity.get('categories')), }); - } + }; render() { const { @@ -330,9 +329,7 @@ EntityListItemMain.propTypes = { isManager: PropTypes.bool, isFocus: PropTypes.bool, skipTargetId: PropTypes.string, -}; -EntityListItemMain.contextTypes = { - intl: PropTypes.object, + intl: PropTypes.object.isRequired, }; -export default EntityListItemMain; +export default injectIntl(EntityListItemMain); diff --git a/app/components/EntityListItem/index.js b/app/components/EntityListItem/index.js index 9b89111cd..3b37b9909 100644 --- a/app/components/EntityListItem/index.js +++ b/app/components/EntityListItem/index.js @@ -4,7 +4,10 @@ import styled from 'styled-components'; import { palette } from 'styled-theme'; import { find } from 'lodash/collection'; import { Map, List } from 'immutable'; +import { injectIntl } from 'react-intl'; + import asList from 'utils/as-list'; + import { COLUMN_WIDTHS } from 'themes/config'; import Messages from 'components/Messages'; @@ -65,8 +68,7 @@ class EntityListItem extends React.Component { // eslint-disable-line react/pref || this.props.expandNo !== nextProps.expandNo; } - transformMessage = (type, msg) => { - const { intl } = this.context; + transformMessage = (type, msg, intl) => { if (type === 'delete') { return intl ? intl.formatMessage(messages.associationNotExistent) @@ -78,7 +80,7 @@ class EntityListItem extends React.Component { // eslint-disable-line react/pref : msg; } return msg; - } + }; render() { const { @@ -98,8 +100,8 @@ class EntityListItem extends React.Component { // eslint-disable-line react/pref isConnection, isFocus, skipTargetId, + intl, } = this.props; - const { intl } = this.context; return ( 0}> { error && error.map((updateError, i) => ( @@ -109,7 +111,7 @@ class EntityListItem extends React.Component { // eslint-disable-line react/pref messages={ updateError .getIn(['error', 'messages']) - .map((msg) => this.transformMessage(updateError.get('type'), msg)) + .map((msg) => this.transformMessage(updateError.get('type'), msg, intl)) .valueSeq() .toArray() } @@ -188,6 +190,7 @@ EntityListItem.propTypes = { onDismissError: PropTypes.func, wrapper: PropTypes.object, skipTargetId: PropTypes.string, + intl: PropTypes.object.isRequired, }; EntityListItem.defaultProps = { @@ -195,8 +198,4 @@ EntityListItem.defaultProps = { expandNo: 0, }; -EntityListItem.contextTypes = { - intl: PropTypes.object, -}; - -export default EntityListItem; +export default injectIntl(EntityListItem); diff --git a/app/components/EntityListMain/EntityListGroups/EntityListFooter/index.js b/app/components/EntityListMain/EntityListGroups/EntityListFooter/index.js index 0f4535fe6..3506db554 100644 --- a/app/components/EntityListMain/EntityListGroups/EntityListFooter/index.js +++ b/app/components/EntityListMain/EntityListGroups/EntityListFooter/index.js @@ -7,6 +7,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import { palette } from 'styled-theme'; +import { injectIntl } from 'react-intl'; import { isEqual } from 'lodash/lang'; @@ -104,12 +105,12 @@ export class EntityListFooter extends React.Component { // eslint-disable-line r render() { // console.log('EntityListOptions.render') - const { intl } = this.context; const { pager, onPageSelect, onPageItemsSelect, pageSize, + intl, } = this.props; const perPageOptions = PAGE_ITEM_OPTIONS.map((option) => ({ @@ -157,7 +158,7 @@ export class EntityListFooter extends React.Component { // eslint-disable-line r onPageSelect(1); }} > - 1 + 1 ) @@ -165,7 +166,7 @@ export class EntityListFooter extends React.Component { // eslint-disable-line r { pager.pages.indexOf(2) < 0 && ( - ... + ... ) } @@ -196,7 +197,7 @@ export class EntityListFooter extends React.Component { // eslint-disable-line r { pager.pages.indexOf(pager.totalPages - 1) < 0 && ( - ... + ... ) } @@ -261,11 +262,7 @@ EntityListFooter.propTypes = { pager: PropTypes.object, onPageSelect: PropTypes.func, onPageItemsSelect: PropTypes.func, -}; - -EntityListFooter.contextTypes = { intl: PropTypes.object.isRequired, }; - -export default EntityListFooter; +export default injectIntl(EntityListFooter); diff --git a/app/components/EntityListMain/EntityListGroups/EntityListGroupHeader.js b/app/components/EntityListMain/EntityListGroups/EntityListGroupHeader.js index 250c93fc8..492be1f66 100644 --- a/app/components/EntityListMain/EntityListGroups/EntityListGroupHeader.js +++ b/app/components/EntityListMain/EntityListGroups/EntityListGroupHeader.js @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { injectIntl } from 'react-intl'; import styled from 'styled-components'; import { palette } from 'styled-theme'; @@ -57,9 +58,8 @@ const Divider = styled.div` `; export class EntityListGroupHeader extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function render() { - const { intl } = this.context; const { - group, level, expanded, groupTypeTitle, + group, level, expanded, groupTypeTitle, intl, } = this.props; if (group.get('id') === 'without') { @@ -117,8 +117,7 @@ EntityListGroupHeader.propTypes = { level: PropTypes.number, expanded: PropTypes.bool, groupTypeTitle: PropTypes.string, -}; -EntityListGroupHeader.contextTypes = { intl: PropTypes.object.isRequired, }; -export default EntityListGroupHeader; + +export default injectIntl(EntityListGroupHeader); diff --git a/app/components/EntityListMain/EntityListGroups/EntityListHeader/ColumnExpand/index.js b/app/components/EntityListMain/EntityListGroups/EntityListHeader/ColumnExpand/index.js index 5169e5677..e1d00270f 100644 --- a/app/components/EntityListMain/EntityListGroups/EntityListHeader/ColumnExpand/index.js +++ b/app/components/EntityListMain/EntityListGroups/EntityListHeader/ColumnExpand/index.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; +import { injectIntl } from 'react-intl'; import Icon from 'components/Icon'; import ColumnHeader from 'components/styled/ColumnHeader'; @@ -51,9 +52,8 @@ const ExpandButton = styled(ButtonFlatIconOnly)` class ColumnExpand extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function render() { const { - isExpand, label, width, onExpand, + isExpand, label, width, onExpand, intl, } = this.props; - const { intl } = this.context; return ( @@ -80,12 +80,10 @@ ColumnExpand.propTypes = { onExpand: PropTypes.func, label: PropTypes.string, width: PropTypes.number, + intl: PropTypes.object.isRequired, }; ColumnExpand.defaultProps = { label: 'label', }; -ColumnExpand.contextTypes = { - intl: PropTypes.object.isRequired, -}; -export default ColumnExpand; +export default injectIntl(ColumnExpand); diff --git a/app/components/EntityListMain/EntityListGroups/EntityListHeader/ColumnSelect/index.js b/app/components/EntityListMain/EntityListGroups/EntityListHeader/ColumnSelect/index.js index 1971fe708..bfd55ba31 100644 --- a/app/components/EntityListMain/EntityListGroups/EntityListHeader/ColumnSelect/index.js +++ b/app/components/EntityListMain/EntityListGroups/EntityListHeader/ColumnSelect/index.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, injectIntl } from 'react-intl'; import IndeterminateCheckbox from 'components/forms/IndeterminateCheckbox'; import SelectReset from 'components/SelectReset'; @@ -65,9 +65,8 @@ const SelectAll = styled(A)` class ColumnSelect extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function render() { const { - isSelect, isSelected, onSelect, width, label, hasSelectAll, onSelectAll, entitiesTotal, + isSelect, isSelected, onSelect, width, label, hasSelectAll, onSelectAll, entitiesTotal, intl, } = this.props; - const { intl } = this.context; const sortOptions = this.props.sortOptions && this.props.sortOptions.map((option) => ({ value: option.attribute, label: intl.formatMessage(messages.sortAttributes[option.attribute]), @@ -172,12 +171,10 @@ ColumnSelect.propTypes = { label: PropTypes.string, entitiesTotal: PropTypes.number, width: PropTypes.number, + intl: PropTypes.object.isRequired, }; ColumnSelect.defaultProps = { label: 'label', }; -ColumnSelect.contextTypes = { - intl: PropTypes.object.isRequired, -}; -export default ColumnSelect; +export default injectIntl(ColumnSelect); diff --git a/app/components/EntityListMain/EntityListGroups/EntityListHeader/index.js b/app/components/EntityListMain/EntityListGroups/EntityListHeader/index.js index 94f2cb6aa..3f3b496a7 100644 --- a/app/components/EntityListMain/EntityListGroups/EntityListHeader/index.js +++ b/app/components/EntityListMain/EntityListGroups/EntityListHeader/index.js @@ -1,7 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { injectIntl } from 'react-intl'; + import styled from 'styled-components'; import { palette } from 'styled-theme'; + import { getSortOption } from 'utils/sort'; import appMessage from 'utils/app-message'; @@ -22,8 +25,7 @@ const Styled = styled.div` `; class EntityListHeader extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function - getListHeaderLabel = (entityTitle, selectedTotal, pageTotal, entitiesTotal, allSelected, allSelectedOnPage) => { - const { intl } = this.context; + getListHeaderLabel = (entityTitle, selectedTotal, pageTotal, entitiesTotal, allSelected, allSelectedOnPage, intl) => { if (selectedTotal > 0) { if (allSelected) { // return `All ${selectedTotal} ${selectedTotal === 1 ? entityTitle.single : entityTitle.plural} selected. `; @@ -57,7 +59,7 @@ class EntityListHeader extends React.PureComponent { // eslint-disable-line reac entitiesTotal, type: (entitiesTotal === 1) ? entityTitle.single : entityTitle.plural, }); - } + }; getSelectedState = (selectedTotal, allSelected) => { if (selectedTotal === 0) { @@ -67,7 +69,7 @@ class EntityListHeader extends React.PureComponent { // eslint-disable-line reac return CHECKBOX_STATES.CHECKED; } return CHECKBOX_STATES.INDETERMINATE; - } + }; getFirstColumnWidth = (expandableColumns, expandNo) => { // TODO figure out a betterway to determine column widths. @@ -81,7 +83,7 @@ class EntityListHeader extends React.PureComponent { // eslint-disable-line reac return COLUMN_WIDTHS.MAIN; } return COLUMN_WIDTHS.HALF; - } + }; // TODO figure out a betterway to determine column widths getExpandableColumnWidth = (i, total, expandNo) => { @@ -105,7 +107,6 @@ class EntityListHeader extends React.PureComponent { // eslint-disable-line reac }; render() { - const { intl } = this.context; const { selectedTotal, pageTotal, @@ -120,6 +121,7 @@ class EntityListHeader extends React.PureComponent { // eslint-disable-line reac onSelect, onSelectAll, sortOptions, + intl, } = this.props; const firstColumnWidth = this.getFirstColumnWidth(expandableColumns, expandNo); @@ -132,7 +134,7 @@ class EntityListHeader extends React.PureComponent { // eslint-disable-line reac width={firstColumnWidth} isSelect={isManager} isSelected={this.getSelectedState(selectedTotal, allSelected || allSelectedOnPage)} - label={this.getListHeaderLabel(entityTitle, selectedTotal, pageTotal, entitiesTotal, allSelected, allSelectedOnPage)} + label={this.getListHeaderLabel(entityTitle, selectedTotal, pageTotal, entitiesTotal, allSelected, allSelectedOnPage, intl)} onSelect={onSelect} hasSelectAll={allSelectedOnPage && !allSelected} onSelectAll={onSelectAll} @@ -181,10 +183,7 @@ EntityListHeader.propTypes = { onSelectAll: PropTypes.func, onSortBy: PropTypes.func, onSortOrder: PropTypes.func, -}; - -EntityListHeader.contextTypes = { intl: PropTypes.object.isRequired, }; -export default EntityListHeader; +export default injectIntl(EntityListHeader); diff --git a/app/components/EntityListMain/EntityListGroups/index.js b/app/components/EntityListMain/EntityListGroups/index.js index ecfc4b654..40e3c43e2 100644 --- a/app/components/EntityListMain/EntityListGroups/index.js +++ b/app/components/EntityListMain/EntityListGroups/index.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, injectIntl } from 'react-intl'; import styled from 'styled-components'; @@ -120,12 +120,10 @@ const pageEntityGroups = (entityGroups, pager, formatMessage) => { export class EntityListGroups extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function - transformMessage = (msg, entityId) => { - const { intl } = this.context; - return intl + transformMessage = (msg, entityId, intl) => + intl ? intl.formatMessage(messages.entityNoLongerPresent, { entityId }) : msg; - }; hasLocationQueryFilters = (locationQuery) => locationQuery.reduce((hasFilters, value, arg) => hasFilters || ['items', 'page', 'group', 'subgroup', 'sort', 'order'].indexOf(arg) === -1, false); @@ -152,8 +150,8 @@ export class EntityListGroups extends React.PureComponent { // eslint-disable-li entities, errors, entityGroups, + intl, } = this.props; - const { intl } = this.context; let pageSize = PAGE_SIZE_MAX; if (locationQuery.get('items')) { if (locationQuery.get('items') === 'all') { @@ -270,7 +268,7 @@ export class EntityListGroups extends React.PureComponent { // eslint-disable-li type="error" messages={updateError .getIn(['error', 'messages']) - .map((msg) => this.transformMessage(msg, entityId)) + .map((msg) => this.transformMessage(msg, entityId, intl)) .valueSeq() .toArray() } @@ -394,11 +392,7 @@ EntityListGroups.propTypes = { subgroupSelectValue: PropTypes.string, groupTaxonomyTitle: PropTypes.string, subgroupTaxonomyTitle: PropTypes.string, + intl: PropTypes.object.isRequired, }; -EntityListGroups.contextTypes = { - intl: PropTypes.object, -}; - - -export default EntityListGroups; +export default injectIntl(EntityListGroups); diff --git a/app/components/EntityListMain/EntityListOptions/EntityListGroupBy/index.js b/app/components/EntityListMain/EntityListOptions/EntityListGroupBy/index.js index 242c903b5..277df45da 100644 --- a/app/components/EntityListMain/EntityListOptions/EntityListGroupBy/index.js +++ b/app/components/EntityListMain/EntityListOptions/EntityListGroupBy/index.js @@ -5,6 +5,7 @@ */ import React from 'react'; import PropTypes from 'prop-types'; +import { injectIntl } from 'react-intl'; import styled from 'styled-components'; @@ -25,8 +26,7 @@ const Styled = styled.div` export class EntityListGroupBy extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function render() { - const { intl } = this.context; - const { onChange, isSubgroup } = this.props; + const { onChange, isSubgroup, intl } = this.props; const value = this.props.value || PARAMS.GROUP_RESET; const options = value !== PARAMS.GROUP_RESET ? this.props.options @@ -63,14 +63,11 @@ EntityListGroupBy.propTypes = { options: PropTypes.array, onChange: PropTypes.func, isSubgroup: PropTypes.bool, + intl: PropTypes.object.isRequired, }; EntityListGroupBy.defaultProps = { value: PARAMS.GROUP_RESET, }; -EntityListGroupBy.contextTypes = { - intl: PropTypes.object.isRequired, -}; - -export default EntityListGroupBy; +export default injectIntl(EntityListGroupBy); diff --git a/app/components/EntityListMain/EntityListOptions/index.js b/app/components/EntityListMain/EntityListOptions/index.js index 0687de50a..7ba8ff7fb 100644 --- a/app/components/EntityListMain/EntityListOptions/index.js +++ b/app/components/EntityListMain/EntityListOptions/index.js @@ -5,7 +5,7 @@ */ import React from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, injectIntl } from 'react-intl'; import styled from 'styled-components'; import { palette } from 'styled-theme'; import { List } from 'immutable'; @@ -73,8 +73,8 @@ export class EntityListOptions extends React.Component { // eslint-disable-line expandable, groupOptions, subgroupOptions, + intl, } = this.props; - const { intl } = this.context; return ( {groupOptions.size > 0 @@ -129,10 +129,7 @@ EntityListOptions.propTypes = { onExpand: PropTypes.func, expanded: PropTypes.bool, expandable: PropTypes.bool, -}; - -EntityListOptions.contextTypes = { intl: PropTypes.object.isRequired, }; -export default EntityListOptions; +export default injectIntl(EntityListOptions); diff --git a/app/components/EntityListMain/index.js b/app/components/EntityListMain/index.js index 21854f2fd..9a587eca8 100644 --- a/app/components/EntityListMain/index.js +++ b/app/components/EntityListMain/index.js @@ -7,7 +7,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Map, List } from 'immutable'; import styled from 'styled-components'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, injectIntl } from 'react-intl'; import { jumpToComponent } from 'utils/scroll-to-component'; import { lowerCase } from 'utils/string'; @@ -85,7 +85,7 @@ class EntityListMain extends React.Component { // eslint-disable-line react/pref this.ScrollReference.current, this.ScrollContainer.current ); - } + }; render() { const { @@ -111,8 +111,8 @@ class EntityListMain extends React.Component { // eslint-disable-line react/pref errors, frameworks, onDismissAllErrors, + intl, } = this.props; - const { intl } = this.context; const expandNo = config.expandableColumns && locationQuery.get('expand') ? parseInt(locationQuery.get('expand'), 10) : 0; @@ -255,7 +255,7 @@ class EntityListMain extends React.Component { // eslint-disable-line react/pref /> {intl && intl.formatMessage(messages.nestedListEmpty[type])} @@ -35,10 +35,7 @@ class EntityListNestedNoItem extends React.PureComponent { // eslint-disable-lin EntityListNestedNoItem.propTypes = { type: PropTypes.string, nestLevel: PropTypes.number, + intl: PropTypes.object.isRequired, }; -EntityListNestedNoItem.contextTypes = { - intl: PropTypes.object, -}; - -export default EntityListNestedNoItem; +export default injectIntl(EntityListNestedNoItem); diff --git a/app/components/EntityListNestedList/EntityListNestedItem/EntityListNestedReportDateItem.js b/app/components/EntityListNestedList/EntityListNestedItem/EntityListNestedReportDateItem.js index 52a9ba7f8..3888c4f74 100644 --- a/app/components/EntityListNestedList/EntityListNestedItem/EntityListNestedReportDateItem.js +++ b/app/components/EntityListNestedList/EntityListNestedItem/EntityListNestedReportDateItem.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import { Map } from 'immutable'; import styled from 'styled-components'; import { palette } from 'styled-theme'; +import { injectIntl } from 'react-intl'; import Icon from 'components/Icon'; @@ -56,11 +57,10 @@ const IconWrapUnscheduled = styled(IconWrap)` class EntityListNestedReportDateItem extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function static propTypes = { dates: PropTypes.instanceOf(Map), - } + }; render() { - const { dates } = this.props; - const { intl } = this.context; + const { dates, intl } = this.props; const date = dates.get('scheduled'); const scheduled = !!date; const overdue = scheduled && date.getIn(['attributes', 'overdue']); @@ -120,8 +120,8 @@ class EntityListNestedReportDateItem extends React.PureComponent { // eslint-dis } } -EntityListNestedReportDateItem.contextTypes = { - intl: PropTypes.object, +EntityListNestedReportDateItem.propTypes = { + intl: PropTypes.object.isRequired, }; -export default EntityListNestedReportDateItem; +export default injectIntl(EntityListNestedReportDateItem); diff --git a/app/components/EntityListNestedList/EntityListNestedItem/EntityListNestedReportItem.js b/app/components/EntityListNestedList/EntityListNestedItem/EntityListNestedReportItem.js index d2edea3a3..eb9843a46 100644 --- a/app/components/EntityListNestedList/EntityListNestedItem/EntityListNestedReportItem.js +++ b/app/components/EntityListNestedList/EntityListNestedItem/EntityListNestedReportItem.js @@ -1,6 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { injectIntl } from 'react-intl'; + import { ROUTES } from 'containers/App/constants'; + import ItemStatus from 'components/ItemStatus'; import Label from 'components/styled/Label'; import Component from 'components/styled/Component'; @@ -74,12 +77,13 @@ const EntityListItemMainTopWrap = styled.div` right: 0; padding-top: 4px; padding-right: 6px; - @media (min-width: ${(props) => props.theme && props.theme.breakpoints ? props.theme.breakpoints.small : '769px'}) { + @media (min-width: ${(props) => props.theme && props.theme.breakpoints ? props.theme.breakpoints.small : '769px'}){ padding-top: ${(props) => props.theme.sizes && props.theme.sizes.mainListItem.paddingTop}px; padding-right: ${(props) => (!props.theme.sizes) ? 0 : props.theme.sizes.mainListItem.paddingHorizontal }px; + } `; const Reference = styled(Label)` @@ -97,8 +101,7 @@ const Title = styled.div` class EntityListNestedReportItem extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function render() { - const { report, onEntityClick } = this.props; - const { intl } = this.context; + const { report, onEntityClick, intl } = this.props; return ( @@ -162,11 +165,7 @@ class EntityListNestedReportItem extends React.PureComponent { // eslint-disable EntityListNestedReportItem.propTypes = { report: PropTypes.object.isRequired, onEntityClick: PropTypes.func, + intl: PropTypes.object.isRequired, }; - -EntityListNestedReportItem.contextTypes = { - intl: PropTypes.object, -}; - -export default EntityListNestedReportItem; +export default injectIntl(EntityListNestedReportItem); diff --git a/app/components/EntityListNestedList/EntityListNestedReportList.js b/app/components/EntityListNestedList/EntityListNestedReportList.js index aad1970d8..9ea8c3523 100644 --- a/app/components/EntityListNestedList/EntityListNestedReportList.js +++ b/app/components/EntityListNestedList/EntityListNestedReportList.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; +import { injectIntl } from 'react-intl'; import { Map, List } from 'immutable'; import A from 'components/styled/A'; @@ -42,9 +43,8 @@ class EntityListNestedReportList extends React.PureComponent { // eslint-disable }; render() { - const { intl } = this.context; const { - reports, dates, onEntityClick, isContributor, nestLevel, + reports, dates, onEntityClick, isContributor, nestLevel, intl, } = this.props; return ( @@ -96,10 +96,7 @@ EntityListNestedReportList.propTypes = { onEntityClick: PropTypes.func, isContributor: PropTypes.bool, nestLevel: PropTypes.number, + intl: PropTypes.object.isRequired, }; -EntityListNestedReportList.contextTypes = { - intl: PropTypes.object, -}; - -export default EntityListNestedReportList; +export default injectIntl(EntityListNestedReportList); diff --git a/app/components/EntityListPrintKey/index.js b/app/components/EntityListPrintKey/index.js index d0d7d879e..ad66bdf42 100644 --- a/app/components/EntityListPrintKey/index.js +++ b/app/components/EntityListPrintKey/index.js @@ -126,8 +126,4 @@ EntityListPrintKey.propTypes = { config: PropTypes.object, }; -EntityListPrintKey.contextTypes = { - intl: PropTypes.object.isRequired, -}; - export default EntityListPrintKey; diff --git a/app/components/EntityListSidebar/EntityListSidebarGroupLabel.js b/app/components/EntityListSidebar/EntityListSidebarGroupLabel.js index 81de6416c..234a19f6b 100644 --- a/app/components/EntityListSidebar/EntityListSidebarGroupLabel.js +++ b/app/components/EntityListSidebar/EntityListSidebarGroupLabel.js @@ -6,6 +6,7 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { injectIntl } from 'react-intl'; import styled from 'styled-components'; import { palette } from 'styled-theme'; @@ -53,9 +54,9 @@ const GroupIcon = styled.div` class EntityListSidebarGroupLabel extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function render() { const { - label, icon, onToggle, expanded, + label, icon, onToggle, expanded, intl, } = this.props; - const { intl } = this.context; + return ( { this.setState({ activeOption: null }); @@ -201,9 +201,8 @@ export class EntityListSidebar extends React.Component { // eslint-disable-line this.setState({ visible: false }); }; - getSidebarButtons = () => { - const { intl } = this.context; - return ([ + getSidebarButtons = (intl) => + ([ { label: intl.formatMessage(messages.header.filterButton), panel: FILTERS_PANEL, @@ -215,10 +214,8 @@ export class EntityListSidebar extends React.Component { // eslint-disable-line icon: 'edit', }, ]); - } - getFormButtons = (activeOption) => { - const { intl } = this.context; + getFormButtons = (activeOption, intl) => { const { onCreateOption } = this.props; return [ activeOption.create @@ -277,8 +274,8 @@ export class EntityListSidebar extends React.Component { // eslint-disable-line entityIdsSelected, frameworks, globalSettings, + intl, } = this.props; - const { intl } = this.context; const { activeOption } = this.state; const hasSelected = entityIdsSelected && entityIdsSelected.size > 0; @@ -303,7 +300,7 @@ export class EntityListSidebar extends React.Component { // eslint-disable-line attributes: intl.formatMessage(messages.filterGroupLabel.attributes), taxonomyGroup: intl.formatMessage(messages.filterGroupLabel.taxonomies), taxonomyGroupByFw: - (fw) => this.context.intl.formatMessage( + (fw) => intl.formatMessage( messages.filterGroupLabel.taxonomiesByFw, { fw: intl.formatMessage(appMessages.frameworks_short[fw]), @@ -312,7 +309,7 @@ export class EntityListSidebar extends React.Component { // eslint-disable-line frameworksGroup: intl.formatMessage(messages.filterGroupLabel.frameworks), connections: intl.formatMessage(messages.filterGroupLabel.connections), connectedTaxonomies: intl.formatMessage(messages.filterGroupLabel.connectedTaxonomies), - taxonomies: (taxId) => this.context.intl.formatMessage(appMessages.entities.taxonomies[taxId].plural), + taxonomies: (taxId) => intl.formatMessage(appMessages.entities.taxonomies[taxId].plural), frameworks: intl.formatMessage(appMessages.frameworks.plural), }, frameworks, @@ -328,7 +325,7 @@ export class EntityListSidebar extends React.Component { // eslint-disable-line attributes: intl.formatMessage(messages.editGroupLabel.attributes), taxonomyGroup: intl.formatMessage(messages.editGroupLabel.taxonomies), connections: intl.formatMessage(messages.editGroupLabel.connections), - taxonomies: (taxId) => this.context.intl.formatMessage(appMessages.entities.taxonomies[taxId].plural), + taxonomies: (taxId) => intl.formatMessage(appMessages.entities.taxonomies[taxId].plural), }, frameworks, selectedFrameworkIds: entitiesSelected.groupBy((e) => e.getIn(['attributes', 'framework_id'])).keySeq(), @@ -394,7 +391,7 @@ export class EntityListSidebar extends React.Component { // eslint-disable-line {canEdit && ( @@ -424,7 +421,7 @@ export class EntityListSidebar extends React.Component { // eslint-disable-line activeOptionId={activeOption.optionId} formOptions={formOptions} buttons={activePanel === EDIT_PANEL - ? this.getFormButtons(activeOption) + ? this.getFormButtons(activeOption, intl) : null } onCancel={this.onHideForm} @@ -470,7 +467,7 @@ export class EntityListSidebar extends React.Component { // eslint-disable-line } { if (activePanel === EDIT_PANEL) { this.setState({ activeOption: null }); @@ -505,10 +502,7 @@ EntityListSidebar.propTypes = { onCreateOption: PropTypes.func.isRequired, listUpdating: PropTypes.bool, theme: PropTypes.object, -}; - -EntityListSidebar.contextTypes = { intl: PropTypes.object.isRequired, }; -export default withTheme(EntityListSidebar); +export default injectIntl(withTheme(EntityListSidebar)); diff --git a/app/components/EntityView/index.js b/app/components/EntityView/index.js index c29cf2e24..be95b8360 100644 --- a/app/components/EntityView/index.js +++ b/app/components/EntityView/index.js @@ -113,7 +113,5 @@ EntityView.propTypes = { fields: PropTypes.object, seamless: PropTypes.bool, }; -EntityView.contextTypes = { - intl: PropTypes.object.isRequired, -}; + export default EntityView; diff --git a/app/components/Header/Brand.js b/app/components/Header/Brand.js index d6431cc7a..56f9c43a9 100644 --- a/app/components/Header/Brand.js +++ b/app/components/Header/Brand.js @@ -7,17 +7,14 @@ export default styled.a` left: 0; text-decoration: none; color: ${palette('headerBrand', 0)}; - - &:hover { - color: ${palette('headerBrandHover', 0)}; - opacity: 0.75; - } - z-index: 110; overflow: hidden; - padding-right: 46px; height: ${(props) => props.theme.sizes.header.banner.heightMobile}px; + &:hover { + color: ${palette('headerBrandHover', 0)}; + opacity: 0.75; + } @media (min-width: ${(props) => props.theme.breakpoints.small}) { padding-right: 46px; height: ${(props) => props.theme.sizes.header.banner.height}px; diff --git a/app/components/Header/LinkAccount.js b/app/components/Header/LinkAccount.js index cc1502117..1c14a7be7 100644 --- a/app/components/Header/LinkAccount.js +++ b/app/components/Header/LinkAccount.js @@ -11,5 +11,4 @@ export default styled(LinkSecondary)` color: ${(props) => props.active ? palette('headerNavAccountItemHover', 1) : palette('headerNavAccountItemHover', 0)}; text-decoration: ${(props) => props.active ? 'none' : 'underline'}; } -} `; diff --git a/app/components/Header/index.js b/app/components/Header/index.js index 15f33203d..b7e664e92 100644 --- a/app/components/Header/index.js +++ b/app/components/Header/index.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, injectIntl } from 'react-intl'; import styled, { withTheme } from 'styled-components'; import { palette } from 'styled-theme'; import { filter } from 'lodash/collection'; @@ -421,8 +421,8 @@ class Header extends React.PureComponent { // eslint-disable-line react/prefer-s brandPath, onShowSettings, hasSettings, + intl, } = this.props; - const { intl } = this.context; const navItems = filter(this.props.navItems, (item) => !item.isAdmin); const navItemsAdmin = filter(this.props.navItems, (item) => item.isAdmin); @@ -561,10 +561,6 @@ class Header extends React.PureComponent { // eslint-disable-line react/prefer-s } } -Header.contextTypes = { - intl: PropTypes.object.isRequired, -}; - Header.propTypes = { isSignedIn: PropTypes.bool, user: PropTypes.object, @@ -581,6 +577,7 @@ Header.propTypes = { frameworkOptions: PropTypes.array, brandPath: PropTypes.string, hasSettings: PropTypes.bool, + intl: PropTypes.object.isRequired, }; Header.defaultProps = { @@ -588,4 +585,4 @@ Header.defaultProps = { brandPath: '/', }; -export default withTheme(Header); +export default injectIntl(withTheme(Header)); diff --git a/app/components/Img/index.js b/app/components/Img/index.js index d41ebb6f7..553fd811a 100644 --- a/app/components/Img/index.js +++ b/app/components/Img/index.js @@ -1,24 +1,27 @@ /** * - * Img.react.js + * Img * * Renders an image, enforcing the usage of the alt="" tag - * - * see https://github.com/KyleAMathews/react-retina-image + * */ import React from 'react'; import PropTypes from 'prop-types'; -import RetinaImage from 'react-retina-image'; -function Img(props) { +const generateSrcSet = (srcArray) => + srcArray.slice(1).map((src, index) => `${src} ${index + 2}x`).join(', '); +function Img({ + src, + alt, + className, +}) { return ( - ); } @@ -31,13 +34,6 @@ Img.propTypes = { ]).isRequired, alt: PropTypes.string.isRequired, className: PropTypes.string, - forceOriginalDimensions: PropTypes.bool, - checkIfRetinaImgExists: PropTypes.bool, -}; - -Img.defaultProps = { - checkIfRetinaImgExists: true, - forceOriginalDimensions: false, }; export default Img; diff --git a/app/components/InfoOverlay/Overlay.js b/app/components/InfoOverlay/Overlay.js index 14d1f5e46..e74aac871 100644 --- a/app/components/InfoOverlay/Overlay.js +++ b/app/components/InfoOverlay/Overlay.js @@ -1,12 +1,13 @@ +/* eslint-disable react/no-children-prop */ /* * * Overlay * */ - import React from 'react'; import PropTypes from 'prop-types'; import ReactMarkdown from 'react-markdown'; +import rehypeExternalLinks from 'rehype-external-links'; import styled from 'styled-components'; import { @@ -65,7 +66,11 @@ function Overlay({
{markdown && ( - + )} {!markdown && content}
diff --git a/app/components/InfoOverlay/index.js b/app/components/InfoOverlay/index.js index fd87e9af3..a5a8e7364 100644 --- a/app/components/InfoOverlay/index.js +++ b/app/components/InfoOverlay/index.js @@ -1,12 +1,13 @@ +/* eslint-disable react/no-children-prop */ /* * * InfoOverlay * */ - import React, { useRef, useState } from 'react'; import PropTypes from 'prop-types'; import ReactMarkdown from 'react-markdown'; +import rehypeExternalLinks from 'rehype-external-links'; import styled from 'styled-components'; import { @@ -98,7 +99,11 @@ function InfoOverlay({ {markdown && (
- +
)} {!markdown && content} diff --git a/app/components/ItemRole/index.js b/app/components/ItemRole/index.js index 37b06dfe5..5be5bea87 100644 --- a/app/components/ItemRole/index.js +++ b/app/components/ItemRole/index.js @@ -2,12 +2,14 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import appMessage from 'utils/app-message'; +import { injectIntl } from 'react-intl'; import Label from 'components/styled/Label'; import { find } from 'lodash/collection'; import { USER_ROLES } from 'themes/config'; + const Role = styled(Label)` float: right; padding-left: 1em; @@ -19,7 +21,7 @@ const Role = styled(Label)` class ItemRole extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function render() { - const { intl } = this.context; + const { intl } = this.props; const role = this.props.role && parseInt(this.props.role, 10) !== USER_ROLES.DEFAULT.value && find(USER_ROLES, { value: parseInt(this.props.role, 10) }); @@ -38,6 +40,7 @@ class ItemRole extends React.PureComponent { // eslint-disable-line react/prefer ItemRole.propTypes = { role: PropTypes.number, + intl: PropTypes.object.isRequired, }; -export default ItemRole; +export default injectIntl(ItemRole); diff --git a/app/components/ItemStatus/index.js b/app/components/ItemStatus/index.js index 1ba9c549c..bdee3fb51 100644 --- a/app/components/ItemStatus/index.js +++ b/app/components/ItemStatus/index.js @@ -2,6 +2,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import { palette } from 'styled-theme'; +import { injectIntl } from 'react-intl'; + import Label from 'components/styled/Label'; import qe from 'utils/quasi-equals'; import appMessage from 'utils/app-message'; @@ -24,6 +26,7 @@ const Status = styled(Label)` class ItemStatus extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function render() { const { + draft, // deprecated top, float, @@ -31,8 +34,9 @@ class ItemStatus extends React.PureComponent { // eslint-disable-line react/pref attribute, options, value, + intl, } = this.props; - const { intl } = this.context; + if (draft) { return ( @@ -63,10 +67,7 @@ ItemStatus.propTypes = { value: PropTypes.string, entity: PropTypes.object, options: PropTypes.array, + intl: PropTypes.object.isRequired, }; -ItemStatus.contextTypes = { - intl: PropTypes.object, -}; - -export default ItemStatus; +export default injectIntl(ItemStatus); diff --git a/app/components/ItemSupport/index.js b/app/components/ItemSupport/index.js index ce32fa187..acb6d1c01 100644 --- a/app/components/ItemSupport/index.js +++ b/app/components/ItemSupport/index.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; -import { injectIntl, intlShape } from 'react-intl'; +import { injectIntl } from 'react-intl'; import appMessage from 'utils/app-message'; @@ -30,7 +30,7 @@ class ItemSupport extends React.PureComponent { // eslint-disable-line react/pre ItemSupport.propTypes = { supportLevel: PropTypes.object, - intl: intlShape, + intl: PropTypes.object.isRequired, }; export default injectIntl(ItemSupport); diff --git a/app/components/Messages/index.js b/app/components/Messages/index.js index 697dc33cd..f2cca698c 100644 --- a/app/components/Messages/index.js +++ b/app/components/Messages/index.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import { palette } from 'styled-theme'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, injectIntl } from 'react-intl'; import { reduce } from 'lodash/collection'; @@ -70,7 +70,7 @@ class Messages extends React.PureComponent { // eslint-disable-line react/prefer null); translateMessage = (message) => { - const { intl } = this.context; + const { intl } = this.props; if (message === SERVER_ERRORS.RECORD_OUTDATED) { return intl && intl.formatMessage(appMessages.forms.outdatedError); } @@ -93,7 +93,7 @@ class Messages extends React.PureComponent { // eslint-disable-line react/prefer return intl && intl.formatMessage(appMessages.forms.referenceRequiredError); } return message; - } + }; render() { const { @@ -181,13 +181,11 @@ Messages.propTypes = { preMessage: PropTypes.bool, details: PropTypes.bool, autoDismiss: PropTypes.number, + intl: PropTypes.object.isRequired, }; Messages.defaultProps = { preMessage: true, }; -Messages.contextTypes = { - intl: PropTypes.object, -}; -export default Messages; +export default injectIntl(Messages); diff --git a/app/components/SelectReset/index.js b/app/components/SelectReset/index.js index 026d4b61e..7d7f63f21 100644 --- a/app/components/SelectReset/index.js +++ b/app/components/SelectReset/index.js @@ -6,6 +6,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { find } from 'lodash/collection'; +import { injectIntl } from 'react-intl'; import styled from 'styled-components'; import { palette } from 'styled-theme'; @@ -42,7 +43,6 @@ const Select = styled.select` } @media print { appearance: none; - text-overflow: ''; text-indent: 0.01px; /* Removes default arrow from firefox */ text-overflow: ""; /* Removes default arrow from firefox */ font-size: ${(props) => props.theme.sizes.print.small}; @@ -83,8 +83,8 @@ export class SelectReset extends React.PureComponent { // eslint-disable-line re index, hidePrint, labelScreenreaderOnly, + intl, } = this.props; - const { intl } = this.context; const optionActive = find(options, (option) => option.value === value); return ( @@ -143,10 +143,7 @@ SelectReset.propTypes = { onChange: PropTypes.func, isReset: PropTypes.bool, hidePrint: PropTypes.bool, -}; - -SelectReset.contextTypes = { intl: PropTypes.object.isRequired, }; -export default SelectReset; +export default injectIntl(SelectReset); diff --git a/app/components/TagSearch/index.js b/app/components/TagSearch/index.js index c320d7c2b..11d92446a 100644 --- a/app/components/TagSearch/index.js +++ b/app/components/TagSearch/index.js @@ -5,7 +5,7 @@ */ import React from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, injectIntl } from 'react-intl'; import styled from 'styled-components'; import { palette } from 'styled-theme'; @@ -126,13 +126,13 @@ export class TagSearch extends React.Component { // eslint-disable-line react/pr getLabels = (labels) => reduce(labels, (memo, label) => { if (!label.label) return memo; - let labelValue = label.appMessage ? appMessage(this.context.intl, label.label) : label.label; + let labelValue = label.appMessage ? appMessage(this.props.intl, label.label) : label.label; labelValue = label.postfix ? `${labelValue}${label.postfix}` : labelValue; return `${memo}${label.lowerCase ? lowerCase(labelValue) : labelValue} `; }, '').trim(); getFilterLabel = (filter) => { - const { intl } = this.context; + const { intl } = this.props; // not used I think? if (filter.message) { return filter.messagePrefix @@ -152,7 +152,7 @@ export class TagSearch extends React.Component { // eslint-disable-line react/pr } else { title = filter.title || this.getFilterLabel(filter); } - return this.context.intl.formatMessage(messages.removeTag, { title }); + return this.props.intl.formatMessage(messages.removeTag, { title }); }; focusLastFilter = () => { @@ -169,8 +169,8 @@ export class TagSearch extends React.Component { // eslint-disable-line react/pr resultsId, searchAttributes, placeholderMessageId, + intl, } = this.props; - const { intl } = this.context; const searchHasFilters = (searchQuery || filters.length > 0); let inputPlaceholder; if (placeholder) { @@ -314,7 +314,7 @@ export class TagSearch extends React.Component { // eslint-disable-line react/pr @@ -332,7 +332,7 @@ export class TagSearch extends React.Component { // eslint-disable-line react/pr @@ -360,10 +360,7 @@ TagSearch.propTypes = { onClear: PropTypes.func, multiselect: PropTypes.bool, focusOnMount: PropTypes.bool, -}; - -TagSearch.contextTypes = { intl: PropTypes.object.isRequired, }; -export default TagSearch; +export default injectIntl(TagSearch); diff --git a/app/components/buttons/ButtonCancel.js b/app/components/buttons/ButtonCancel.js index eabd3a0f6..f9bda7ded 100644 --- a/app/components/buttons/ButtonCancel.js +++ b/app/components/buttons/ButtonCancel.js @@ -5,7 +5,7 @@ import ButtonForm from './ButtonForm'; const ButtonCancel = styled(ButtonForm)` color: ${palette('buttonCancel', 0)}; - &:hover, &:hover { + &:hover { color: ${palette('buttonCancelHover', 0)}; } `; diff --git a/app/components/buttons/ButtonDefaultWithIcon/index.js b/app/components/buttons/ButtonDefaultWithIcon/index.js index 60a312ed7..2fe127617 100644 --- a/app/components/buttons/ButtonDefaultWithIcon/index.js +++ b/app/components/buttons/ButtonDefaultWithIcon/index.js @@ -51,10 +51,7 @@ const Word = styled.span` return 'inline'; }}; } - ${(props) => props.iconRight - ? '&:after { content: " "; }' - : '&:before { content: " "; }' -} + ${(props) => props.iconRight ? '&::after { content: " "; }' : '&::before { content: " "; }'} `; class ButtonDefaultWithIcon extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function diff --git a/app/components/buttons/ButtonFactory/index.js b/app/components/buttons/ButtonFactory/index.js index 6938df650..d7110c759 100644 --- a/app/components/buttons/ButtonFactory/index.js +++ b/app/components/buttons/ButtonFactory/index.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { injectIntl, intlShape } from 'react-intl'; +import { useIntl } from 'react-intl'; import Icon from 'components/Icon'; import ScreenReaderHide from 'components/styled/ScreenReaderHide'; @@ -15,7 +15,8 @@ import ButtonDefaultIconOnly from '../ButtonDefaultIconOnly'; import ButtonFlatIconOnly from '../ButtonFlatIconOnly'; import Bookmarker from '../../../containers/Bookmarker'; -const ButtonFactory = ({ button, intl }) => { +const ButtonFactory = ({ button }) => { + const intl = useIntl(); let { title } = button; switch (button.type) { case 'primary': @@ -172,7 +173,6 @@ const ButtonFactory = ({ button, intl }) => { ButtonFactory.propTypes = { button: PropTypes.object.isRequired, - intl: intlShape.isRequired, }; -export default injectIntl(ButtonFactory); +export default ButtonFactory; diff --git a/app/components/buttons/ButtonTagCategory/index.js b/app/components/buttons/ButtonTagCategory/index.js index b1d6a8cd2..29d637233 100644 --- a/app/components/buttons/ButtonTagCategory/index.js +++ b/app/components/buttons/ButtonTagCategory/index.js @@ -22,7 +22,7 @@ const getColor = (props, isHover = false) => { // eslint-disable no-nested-ternary const ButtonTagCategory = styled(Button)` - color: ${(props) => palette('taxonomiesTextColor', props.taxId)}}; + color: ${(props) => palette('taxonomiesTextColor', props.taxId)}; background-color: ${(props) => getColor(props)}; margin-right: 2px; border-radius: ${(props) => props.isSmartTag ? 9999 : 3}px; @@ -31,7 +31,7 @@ const ButtonTagCategory = styled(Button)` cursor:${(props) => props.disabled ? 'default' : 'pointer'}; border: 1px solid ${(props) => getColor(props)}; &:hover, &:focus-visible { - color: ${(props) => palette('taxonomiesTextColor', props.taxId)}}; + color: ${(props) => palette('taxonomiesTextColor', props.taxId)}; background-color: ${(props) => getColor(props, true)}; border-color: ${(props) => getColor(props, true)}; } diff --git a/app/components/buttons/ButtonTagCategoryInverse/index.js b/app/components/buttons/ButtonTagCategoryInverse/index.js index 5f5c4dba9..954a46f3e 100644 --- a/app/components/buttons/ButtonTagCategoryInverse/index.js +++ b/app/components/buttons/ButtonTagCategoryInverse/index.js @@ -51,6 +51,7 @@ const ButtonTagCategoryInverse = styled(Button)` : palette('taxonomiesHover', props.taxId || 0) }; } + } `; export default ButtonTagCategoryInverse; diff --git a/app/components/categoryList/CategoryListItem/index.js b/app/components/categoryList/CategoryListItem/index.js index c33e5b4af..3821a69d7 100644 --- a/app/components/categoryList/CategoryListItem/index.js +++ b/app/components/categoryList/CategoryListItem/index.js @@ -82,7 +82,7 @@ const Bar = styled.div` } @media print { z-index: 0; - &:before { + &::before { content: ''; display: block; position: absolute; @@ -365,8 +365,4 @@ CategoryListItem.propTypes = { frameworkId: PropTypes.string, }; -CategoryListItem.contextTypes = { - intl: PropTypes.object.isRequired, -}; - export default CategoryListItem; diff --git a/app/components/categoryList/CategoryListItems/index.js b/app/components/categoryList/CategoryListItems/index.js index 3fbbbd49d..9c4dfb65b 100644 --- a/app/components/categoryList/CategoryListItems/index.js +++ b/app/components/categoryList/CategoryListItems/index.js @@ -2,6 +2,8 @@ import React from 'react'; import Link from 'containers/Link'; import PropTypes from 'prop-types'; import { List } from 'immutable'; +import { injectIntl } from 'react-intl'; + import styled from 'styled-components'; import { palette } from 'styled-theme'; @@ -14,6 +16,7 @@ import CategoryListItem from 'components/categoryList/CategoryListItem'; import { SORT_ORDER_OPTIONS } from 'containers/App/constants'; import appMessages from 'containers/App/messages'; import messages from '../messages'; + const Styled = styled.div` position: relative; `; @@ -56,8 +59,7 @@ class CategoryListItems extends React.PureComponent { // eslint-disable-line rea ) ); - getHeaderAttributes = (taxonomy, frameworkId) => { - const { intl } = this.context; + getHeaderAttributes = (taxonomy, frameworkId, intl) => { // figure out if tagged directly or via child category const tagsRecs = this.getTagsTax(taxonomy, 'tags_recommendations'); const tagsMeasures = this.getTagsTax(taxonomy, 'tags_measures'); @@ -101,7 +103,7 @@ class CategoryListItems extends React.PureComponent { // eslint-disable-line rea }); } return attributes; - } + }; getListHeaderColumns = ({ taxonomy, @@ -112,13 +114,13 @@ class CategoryListItems extends React.PureComponent { // eslint-disable-line rea onSort, userOnly, isGrouped, + intl, }) => { - const { intl } = this.context; const sortOptionActive = getSortOption(sortOptions, sortBy, 'query'); const titleColumnSortOption = sortOptions.find((option) => option.query === 'title'); const titleColumnActive = titleColumnSortOption.query === sortOptionActive.query; const titleColumnSortOrderOption = SORT_ORDER_OPTIONS.find((option) => (sortOrder || titleColumnSortOption.order) === option.value); - const headerAttributes = this.getHeaderAttributes(taxonomy, frameworkId); + const headerAttributes = this.getHeaderAttributes(taxonomy, frameworkId, intl); let titleColumnSortTitle = intl.formatMessage(messages.titleColumnSortTitle); if (titleColumnActive) { titleColumnSortTitle = intl.formatMessage(messages.titleColumnSortTitleSorted); @@ -197,7 +199,7 @@ class CategoryListItems extends React.PureComponent { // eslint-disable-line rea getCategoryMaxCount = (categoryGroups, attribute) => { const isList = !!attribute.frameworkIds; const allCategories = categoryGroups.reduce((memo, group) => memo.concat(group.get('categories')), - List(),); + List()); return allCategories.reduce( (countsMemo, cat) => { if (isList) { @@ -248,7 +250,7 @@ class CategoryListItems extends React.PureComponent { // eslint-disable-line rea }); } return attributes; - } + }; getListColumns = ({ taxonomy, @@ -288,6 +290,7 @@ class CategoryListItems extends React.PureComponent { // eslint-disable-line rea userOnly, frameworks, frameworkId, + intl, } = this.props; const headerColumns = this.getListHeaderColumns({ @@ -299,6 +302,8 @@ class CategoryListItems extends React.PureComponent { // eslint-disable-line rea onSort, userOnly, isGrouped: categoryGroups.size > 0 && !!taxonomy.get('parent'), + frameworks, + intl, }); const columns = this.getListColumns({ @@ -356,10 +361,7 @@ CategoryListItems.propTypes = { sortOrder: PropTypes.string, userOnly: PropTypes.bool, frameworkId: PropTypes.string, -}; - -CategoryListItems.contextTypes = { intl: PropTypes.object.isRequired, }; -export default CategoryListItems; +export default injectIntl(CategoryListItems); diff --git a/app/components/categoryList/TaxonomySidebar/index.js b/app/components/categoryList/TaxonomySidebar/index.js index 35c2f5260..2ca56362e 100644 --- a/app/components/categoryList/TaxonomySidebar/index.js +++ b/app/components/categoryList/TaxonomySidebar/index.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, injectIntl } from 'react-intl'; + import styled, { withTheme } from 'styled-components'; import { map } from 'lodash/collection'; @@ -114,6 +115,7 @@ class TaxonomySidebar extends React.PureComponent { // eslint-disable-line react onTaxonomyOver, frameworkId, frameworks, + intl, } = this.props; const taxonomyGroups = frameworks && taxonomies && prepareTaxonomyGroups( taxonomies, @@ -122,7 +124,6 @@ class TaxonomySidebar extends React.PureComponent { // eslint-disable-line react frameworkId, frameworks, ); - const { intl } = this.context; return ( { (!this.state.visible && this.state.viewport < VIEWPORTS.SMALL) @@ -196,7 +197,7 @@ class TaxonomySidebar extends React.PureComponent { // eslint-disable-line react @@ -217,8 +218,7 @@ TaxonomySidebar.propTypes = { onTaxonomyOver: PropTypes.func, active: PropTypes.string, theme: PropTypes.object, -}; -TaxonomySidebar.contextTypes = { intl: PropTypes.object.isRequired, }; -export default withTheme(TaxonomySidebar); + +export default injectIntl(withTheme(TaxonomySidebar)); diff --git a/app/components/categoryList/TaxonomySidebarItem/index.js b/app/components/categoryList/TaxonomySidebarItem/index.js index 370d83bd3..c6cbac1ad 100644 --- a/app/components/categoryList/TaxonomySidebarItem/index.js +++ b/app/components/categoryList/TaxonomySidebarItem/index.js @@ -93,8 +93,4 @@ TaxonomySidebarItem.propTypes = { onTaxonomyOver: PropTypes.func, }; -TaxonomySidebarItem.contextTypes = { - intl: PropTypes.object.isRequired, -}; - export default TaxonomySidebarItem; diff --git a/app/components/fields/ConnectionGroupsField/Group.js b/app/components/fields/ConnectionGroupsField/Group.js index 7fc0d7bc2..a8c341aab 100644 --- a/app/components/fields/ConnectionGroupsField/Group.js +++ b/app/components/fields/ConnectionGroupsField/Group.js @@ -98,8 +98,5 @@ Group.propTypes = { field: PropTypes.object.isRequired, group: PropTypes.object.isRequired, }; -Group.contextTypes = { - intl: PropTypes.object.isRequired, -}; export default Group; diff --git a/app/components/fields/ConnectionGroupsField/index.js b/app/components/fields/ConnectionGroupsField/index.js index 4e85a1a04..7070c90e3 100644 --- a/app/components/fields/ConnectionGroupsField/index.js +++ b/app/components/fields/ConnectionGroupsField/index.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; +import { injectIntl } from 'react-intl'; import appMessages from 'containers/App/messages'; @@ -17,8 +18,7 @@ const StyledFieldWrap = styled(FieldWrap)` class ConnectionGroupsField extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function render() { - const { field } = this.props; - const { intl } = this.context; + const { field, intl } = this.props; const size = field.groups && field.groups.reduce((sum, group) => group.get(field.entityPath) ? sum + group.get(field.entityPath).size @@ -58,9 +58,7 @@ class ConnectionGroupsField extends React.PureComponent { // eslint-disable-line ConnectionGroupsField.propTypes = { field: PropTypes.object.isRequired, -}; -ConnectionGroupsField.contextTypes = { intl: PropTypes.object.isRequired, }; -export default ConnectionGroupsField; +export default injectIntl(ConnectionGroupsField); diff --git a/app/components/fields/ConnectionsField/index.js b/app/components/fields/ConnectionsField/index.js index 412423ea2..8837a7918 100644 --- a/app/components/fields/ConnectionsField/index.js +++ b/app/components/fields/ConnectionsField/index.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, injectIntl } from 'react-intl'; import styled from 'styled-components'; import appMessages from 'containers/App/messages'; @@ -37,7 +37,7 @@ class ConnectionsField extends React.PureComponent { // eslint-disable-line reac getItemIdAt = (items, index) => { const itemsSliced = items.slice(index - 1, index); return itemsSliced ? itemsSliced.first().get('id') : null; - } + }; toggleAllItems = (evt) => { if (evt !== undefined && evt.preventDefault) evt.preventDefault(); @@ -47,11 +47,11 @@ class ConnectionsField extends React.PureComponent { // eslint-disable-line reac focusItem: !prevState.showAllConnections ? CONNECTIONMAX + 1 : null, }), ); - } + }; render() { - const { field } = this.props; - const { intl } = this.context; + const { field, intl } = this.props; + const label = `${field.values.size} ${intl.formatMessage( field.values.size === 1 ? appMessages.entities[field.entityType].single @@ -121,9 +121,7 @@ class ConnectionsField extends React.PureComponent { // eslint-disable-line reac ConnectionsField.propTypes = { field: PropTypes.object.isRequired, -}; -ConnectionsField.contextTypes = { intl: PropTypes.object.isRequired, }; -export default ConnectionsField; +export default injectIntl(ConnectionsField); diff --git a/app/components/fields/DownloadField/index.js b/app/components/fields/DownloadField/index.js index 332866ab0..4351d6201 100644 --- a/app/components/fields/DownloadField/index.js +++ b/app/components/fields/DownloadField/index.js @@ -40,7 +40,5 @@ class DownloadField extends React.PureComponent { // eslint-disable-line react/p DownloadField.propTypes = { field: PropTypes.object.isRequired, }; -DownloadField.contextTypes = { - intl: PropTypes.object.isRequired, -}; + export default DownloadField; diff --git a/app/components/fields/EmailField/index.js b/app/components/fields/EmailField/index.js index f91d212ee..9d46683bb 100644 --- a/app/components/fields/EmailField/index.js +++ b/app/components/fields/EmailField/index.js @@ -30,8 +30,5 @@ class EmailField extends React.PureComponent { // eslint-disable-line react/pref EmailField.propTypes = { field: PropTypes.object.isRequired, }; -EmailField.contextTypes = { - intl: PropTypes.object.isRequired, -}; export default EmailField; diff --git a/app/components/fields/MarkdownField/index.js b/app/components/fields/MarkdownField/index.js index b73d7d949..feb6af2d8 100644 --- a/app/components/fields/MarkdownField/index.js +++ b/app/components/fields/MarkdownField/index.js @@ -1,8 +1,10 @@ +/* eslint-disable react/no-children-prop */ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import ReactMarkdown from 'react-markdown'; import { FormattedMessage } from 'react-intl'; +import rehypeExternalLinks from 'rehype-external-links'; import FieldWrap from 'components/fields/FieldWrap'; import Label from 'components/fields/Label'; @@ -44,9 +46,9 @@ function MarkdownField({ field }) { ) } ); diff --git a/app/components/fields/MetaField/index.js b/app/components/fields/MetaField/index.js index 420cb9b11..cc1a03a56 100644 --- a/app/components/fields/MetaField/index.js +++ b/app/components/fields/MetaField/index.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, injectIntl } from 'react-intl'; import appMessages from 'containers/App/messages'; @@ -10,8 +10,7 @@ import Meta from 'components/fields/Meta'; class MetaField extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function render() { - const { field } = this.props; - const { intl } = this.context; + const { field, intl } = this.props; return (