{{ item.slugline }}+ +
{{ item.headline }}
+{{ _('By:') }} {{ item.byline }} {{ _('On:') }} {{ item.versioncreated|datetime_long }}
+ +diff --git a/.github/workflows/tests-py38.yml b/.github/workflows/tests-py38.yml new file mode 100644 index 000000000..afa638535 --- /dev/null +++ b/.github/workflows/tests-py38.yml @@ -0,0 +1,75 @@ +name: "CI" + +on: + [push, pull_request] + +jobs: + + server-py-38: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: setup python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: docker-compose + run: docker-compose -f .actions-docker-compose.yml up -d + + - name: cache pip + uses: actions/cache@v2 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('dev-requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip + ${{ runner.os }}- + + - name: pip install + run: | + python -m pip install --upgrade pip wheel setuptools + pip install -r dev-requirements.txt + + - name: flake8 + run: flake8 + + - name: pytest + run: pytest --ignore=tests/aap/ --disable-pytest-warnings --cov=newsroom + + - name: behave + run: behave --format progress2 --logging-level=ERROR + + client-node-14: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: setup node + uses: actions/setup-node@v1 + with: + node-version: 14.x + + - name: cache npm + uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }} + restore-keys: | + ${{ runner.os }}-npm + ${{ runner.os }}- + + - name: npm ci + run: npm ci + + - name: lint + run: npm run lint + + - name: test + run: npm run test + + - name: build + run: npm run build diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3f580afe4..2427ff764 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,8 +5,8 @@ on: jobs: - server: - runs-on: ubuntu-latest + server-py-36: + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 @@ -19,6 +19,10 @@ jobs: - name: docker-compose run: docker-compose -f .actions-docker-compose.yml up -d + - run: | + sudo apt-get update + sudo apt-get install pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl + - name: cache pip uses: actions/cache@v2 with: @@ -42,7 +46,7 @@ jobs: - name: behave run: behave --format progress2 --logging-level=ERROR - client: + client-node-12: runs-on: ubuntu-latest steps: diff --git a/assets/companies/actions.js b/assets/companies/actions.js index a568e31c1..157e3a9c0 100644 --- a/assets/companies/actions.js +++ b/assets/companies/actions.js @@ -116,7 +116,17 @@ export function postCompany() { }; } - +export function savePermissions(company, permissions) { + return function (dispatch) { + return server.postWithCsrfToken(`/companies/${company._id}/permissions`, permissions) + .then(() => { + notify.success(gettext('Company updated successfully')); + dispatch(fetchProducts()); + dispatch(fetchCompanies()); + }) + .catch((error) => errorHandler(error, dispatch, setError)); + }; +} /** * Fetches products @@ -137,19 +147,6 @@ export function fetchProducts() { * Save permissions for a company * */ -export function savePermissions(company, permissions) { - return function (dispatch) { - return server.post(`/companies/${company._id}/permissions`, permissions) - .then(() => { - notify.success(gettext('Company updated successfully')); - dispatch(fetchProducts()); - dispatch(fetchCompanies()); - }) - .catch((error) => errorHandler(error, dispatch, setError)); - }; -} - - /** * Deletes a company * diff --git a/assets/companies/components/CompanyPermissions.jsx b/assets/companies/components/CompanyPermissions.jsx index 0b6b16622..7c21aba71 100644 --- a/assets/companies/components/CompanyPermissions.jsx +++ b/assets/companies/components/CompanyPermissions.jsx @@ -1,41 +1,50 @@ -import React from 'react'; +import React, {Component} from 'react'; import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; -import { gettext } from 'utils'; -import { get } from 'lodash'; +import {connect} from 'react-redux'; +import {gettext} from 'utils'; +import {get} from 'lodash'; import CheckboxInput from 'components/CheckboxInput'; import {savePermissions} from '../actions'; -class CompanyPermissions extends React.Component { - +class CompanyPermissions extends Component { constructor(props) { super(props); this.state = this.setup(); + this.handleSubmit = this.handleSubmit.bind(this); + this.handleChange = this.handleChange.bind(this); + this.togglePermission = this.togglePermission.bind(this); } setup() { - const products = {}; - - this.props.products.forEach((product) => { - products[product._id] = get(product, 'companies', []).includes(this.props.company._id); - }); - - const sections = {}; - - if (this.props.company.sections) { - Object.assign(sections, this.props.company.sections); - } else { - this.props.sections.forEach((section) => { - sections[section._id] = true; - }); - } + const {company, sections, products} = this.props; - const archive_access = !!this.props.company.archive_access; - const events_only = !!this.props.company.events_only; + const permissions = { + sections: company.sections || sections.reduce((acc, section) => ({...acc, [section._id]: true}), {}), + products: products.reduce((acc, product) => ({ + ...acc, + [product._id]: get(product, 'companies', []).includes(company._id) + }), {}), + archive_access: company.archive_access || false, + events_only: company.events_only || false, + embedded: { + social_media_display: get(company, 'embedded.social_media_display', false), + video_display: get(company, 'embedded.video_display', false), + audio_display: get(company, 'embedded.audio_display', false), + images_display: get(company, 'embedded.images_display', false), + all_display: get(company, 'embedded.all_display', false), + social_media_download: get(company, 'embedded.social_media_download', false), + video_download: get(company, 'embedded.video_download', false), + audio_download: get(company, 'embedded.audio_download', false), + images_download: get(company, 'embedded.images_download', false), + all_download: get(company, 'embedded.all_download', false), + sdpermit_display: get(company, 'embedded.sdpermit_display', false), + sdpermit_download: get(company, 'embedded.sdpermit_download', false), + }, + }; - return {sections, products, archive_access, events_only}; + return permissions; } componentDidUpdate(prevProps) { @@ -44,20 +53,57 @@ class CompanyPermissions extends React.Component { } } - toggle(key, _id) { - const field = this.state[key]; - field[_id] = !field[_id]; - this.setState({[key]: field}); + handleSubmit(event) { + event.preventDefault(); + this.props.savePermissions(this.props.company, this.state); + } + + handleChange(key, value) { + this.setState((prevState) => { + if (key.startsWith('embedded.')) { + const [, embeddedKey] = key.split('.'); + return { + ...prevState, + embedded: { + ...prevState.embedded, + [embeddedKey]: value, + }, + }; + } else { + return { + ...prevState, + [key]: value, + }; + } + }); + } + + togglePermission(key, _id, value) { + this.setState((prevState) => ({ + ...prevState, + [key]: { + ...prevState[key], + [_id]: value, + }, + })); } render() { + const {sections, products} = this.props; + const { + archive_access, + events_only, + embedded = {}, + } = this.state; + + const optionLabels = { + Display: 'Allow Visualization', + Download: 'Allow Download' + }; return ( -
{{ item.slugline }}+ +
{{ _('By:') }} {{ item.byline }} {{ _('On:') }} {{ item.versioncreated|datetime_long }}
+ +diff --git a/newsroom/templates/download_embed.html b/newsroom/templates/download_embed.html new file mode 100644 index 000000000..e872156ad --- /dev/null +++ b/newsroom/templates/download_embed.html @@ -0,0 +1,52 @@ + + +
+ + + +
+ + + + + {{ javascript_tag('common') | safe }} + {{ javascript_tag('newsroom_css') | safe }} + + +
+