Skip to content

Commit

Permalink
Merging master into cp (#1031)
Browse files Browse the repository at this point in the history
* [SDAN-639] Notifications dropdown was not fully visible (#941)

* [SDAN-628] Improve email subject when watching ad-hoc planning item (#942)

* [SDAN-628] Improve email subject when watching ad-hoc planning item

* added to default slugline

* [SDAN-586] Make the 'Superdesk Subscriber Id' column visibility configurable in the Company list (#944)

* [SDAN-631] The 'PRINT REPORT' action produces a page without any report data (#945)

* [SDAN-624] Display Take Key when Downloading, Copying, Printing and Sharing wire items (#943)

* [SDAN-624] Display Take Key when Downloading, Copying, Printing and Sharing wire items

* added helper comments

* removed unwanted test code

* [SDAN-630] Use base class for Web and NewsAPI apps (#950)

* [SDAN-630] Use base class for Web and NewsAPI apps

* * Fix bootstrapping unit and behave test apps

* * Raise exception on NewsroomNewsAPI.run if NEWS_API_ENABLED=False

* [SDAN-606] (fix): API token expiry stored as string instead of datetime (#946)

* fix(push): Exception raised when receiving new completed coverages (#948)

* [SDAN-544][SDAN-561] IP whitelisting feature for News API (#947)

* [SDAN-544][SDAN-561] IP whitelisting feature for News API

* UI component changes

* restore original news_api_enabled setting

* UX changes

* restore News API default setting

* fix(coverage-href): Catch all exceptions when generating coverage href (#949)

* [SDAN-630] (fix): incorrect app import for manage.py (#953)

* [SDAN-630] (fix): incorrect app import for manage.py

* * Fix installing google-chrome-stable

* [SDAN-560] Rate Limiting for News API (#951)

* [SDAN-560] Rate Limiting for News API

* corrected test cases

* behave test cases

* [SDAN-563] News API Audit (#952)

* [SDAN-632] ContentActivity report (#954)

* [SDAN-632] ContentActivity report

* * Fix flake8 errors

* [SDAN-562] Company API Usage report (#955)

* [SDAN-562] COmpany API Usage report

* changes to elastic query

* fixed test case

* changed schema

* [SDAN-633] Formatting monitoring outputs for alerts, exports, share and print (#957)

* [SDAN-633] Formatting monitoring outputs for alerts, exports, share and print

* added package installation

* added test case assertions

* fix(build): Add PyRTF and xhtml2pdf to setup.py (#959)

* build fix while using _expand_contact_info in json_event formatter (#963)

* build fix while using _expand_contact_info in json_event formatter

* modified planning branch

* [SDAN-635] Break words meaningfully on location display in Agenda (#962)

* [SDAN-638] Show 'View Content' to Graphic coverges (#961)

* Customizing RTF and PDF files to monitoring. (#960)

* [SDAN-633] Allow customisation of monitoring logo (#964)

* [SDAN-643][SDAN-644]'Reason for' not being displayed for Cancelled Coverages in Agenda, Coverage ednote not seen (#966)

* fix(pytest): Cyclic import error when running single test file (#967)

* [SDAN-636] Advertise Scheduled Updates in Newsroom Agenda (#968)

* [SDAN-634] Changes to Agenda tiles displayed on Newsroom wire stories (#965)

* [SDAN-634] Changes to Agenda tiles displayed on Newsroom wire stories

* minor changes to UI

* UI style change

* [SDAN-647] Add a 'Layout' dropdown option when downloading items from monitoring (#969)

* [SDAN-655] Previewing an agenda item with a coverage crashes react (#970)

* [SDAN-655] Previewing an agenda item with a coverage crashes react

* refactor

* fix(tests): Use same werkzeug version as eve 0.7.8 (#973)

* [SDAN-648] Bug fixes around Monitoring (#971)

* [SDAN-634] Show only other coverages in Agenda tile on wire items (#972)

* [SDAN-648] Minor style changes to PDF reports in Monitoring (#975)

* [SDAN-649] Share/delete icons not showing in my topic pages (#976)

* [SDAN-654] ContentActivity should report on all versions (#977)

* Add 'Take Key' column to the output

* [SDAN-651] Reduce size of heading in Agenda Watch email (#978)

* [SDAN-650][SDAN-656] Story updates are not triggering emails for watched coverages, 'Forbidden' error raised when unwatching certain coverages (#979)

* [SDAN-648] Line spacings for monitoring PDF report (#980)

* [SDAN-656] Coverage update repeated in watched coverage email (#981)

* [SDAN-658] fix duplicate take key in slugline view elements (#982)

* [SDAN-654] Add 'anpa_take_key' to elastic query response for ContentActivity (#984)

* [SDAN-663] Agenda information not shown on Wire Preview/Detail (#985)

* [SDAN-663] Agenda information not shown on Wire Preview/Detail

* changed to elastic query

* [SDAN-662] Change the way attachments are send to Celery tasks for Monitoring (#986)

* [SDAN-663] Agenda Tile not opening Agenda item on click (#987)

* [SDAN-665] Wire previews text width becomes too narrow if related coverage slugline is too long (#988)

* [SDAN-665] Wire previews text width becomes too narrow if related coverage slugline is too long

* removed text ellipsis around slugline

* [SDAN-653] Improve product query generation for endpoint services (#974)

* [SDAN-558] News API NewsFeed endpoint (#990)

* fix generating renditions for png images (#994)

it's not possible to save rgba picture as jpg via PIL

* [SDAN-659] Hourly monitoring alerts should send emails on the hour (#991)

* [SDAN-659] Hourly monitoring alerts should send emails on the hour

* fixed test case

* [SDAN-652] View and manage Watched Coverages (#993)

* [SDAN-660] Cannot set News API expiry to 'Never' (#995)

* [SDAN-661] Use Newsroom.Resource|Service for resource classes (#997)

* [SDAN-661] Use Newsroom.Resource|Service for resource classes
* Fixed monitoring server unit tests

* [SDAN-667]  Cannot unwatch coverages/Agenda for historic data (#1000)

* [SDAN-666] Use 'must' instead of 'should' for Agenda date queries (#999)

* [SDAN-666] Sort field for agenda should be dates.start (#1002)

* [SD-149] - image downloads for stories (#1011)

[SD-149] - image downloads for stories

* [SDCP-201] - Removing image if the update doesn't have it (#1025)

* [SDCP-201] - Removing image if the update doesn't have it

* TBC Planning Items were shown in wrong order when Feature/Top story filter was ON (#1022)

* [SDAN-668] (fix): Attribute error when accessing app.settings (#1026)

Co-authored-by: vikas <[email protected]>
Co-authored-by: MarkLark86 <[email protected]>
Co-authored-by: Petr Jašek <[email protected]>
  • Loading branch information
4 people authored Apr 6, 2020
1 parent f59bf8e commit 34c173d
Show file tree
Hide file tree
Showing 169 changed files with 7,114 additions and 2,221 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ addons:
- google-chrome
packages:
- elasticsearch
- google-chrome-stable

cache:
- pip
Expand All @@ -24,6 +23,7 @@ cache:
before_install:
- sudo apt-get purge elasticsearch
- sudo apt-get install -y -t stable --allow-unauthenticated elasticsearch
- sudo apt-get install -y --allow-unauthenticated google-chrome-stable
- sudo service elasticsearch restart

install:
Expand Down
4 changes: 2 additions & 2 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import os

from newsroom import Newsroom
from newsroom.web import NewsroomWebApp

app = Newsroom(__name__)
app = NewsroomWebApp(__name__)

if __name__ == '__main__':
host = '0.0.0.0'
Expand Down
35 changes: 8 additions & 27 deletions assets/agenda/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
import {noNavigationSelected, getNavigationUrlParam} from 'search/utils';

import { markItemAsRead, toggleFeaturedOnlyParam } from 'local-store';
import { renderModal, closeModal, setSavedItemsCount } from 'actions';
import { renderModal, setSavedItemsCount } from 'actions';
import {
getCalendars,
getDateInputDate,
Expand Down Expand Up @@ -79,7 +79,7 @@ export function previewItem(item, group, plan) {
};
}

function fetchWireItemsForAgenda(item) {
export function fetchWireItemsForAgenda(item) {
return (dispatch) => {
let wireIds = [];
(get(item, 'coverages') || []).forEach((c) => {
Expand Down Expand Up @@ -349,7 +349,7 @@ export function watchEvents(ids) {
export const STOP_WATCHING_EVENTS = 'STOP_WATCHING_EVENTS';
export function stopWatchingEvents(items) {
return (dispatch, getState) => {
server.del(WATCH_URL, {items})
server.del(getState().bookmarks ? `${WATCH_URL}?bookmarks=true` : WATCH_URL, {items})
.then(() => {
notify.success(gettext('Stopped watching items successfully.'));
if (getState().bookmarks) {
Expand Down Expand Up @@ -458,22 +458,6 @@ export function downloadItems(items) {
return renderModal('downloadItems', {items});
}

/**
* Start download - open download view in new window.
*
* @param {Array} items
* @param {String} format
*/
export function submitDownloadItems(items, format) {
return (dispatch, getState) => {
window.open(`/download/${items.join(',')}?format=${format}&type=${getState().context}`, '_blank');
dispatch(setDownloadItems(items));
dispatch(closeModal());
multiItemEvent('download', items, getState());
};
}


export const REMOVE_NEW_ITEMS = 'REMOVE_NEW_ITEMS';
export function removeNewItems(data) {
return {type: REMOVE_NEW_ITEMS, data};
Expand Down Expand Up @@ -653,13 +637,6 @@ export function loadMyAgendaTopic(topicId) {
};
}

function multiItemEvent(event, items, state) {
items.forEach((itemId) => {
const item = state.itemsById[itemId];
item && analytics.itemEvent(event, item);
});
}

export const TOGGLE_FEATURED_FILTER = 'TOGGLE_FEATURED_FILTER';
export function toggleFeaturedFilter(fetch = true) {
return (dispatch) => {
Expand Down Expand Up @@ -698,7 +675,7 @@ export function watchCoverage(coverage, item) {

export const STOP_WATCHING_COVERAGE = 'STOP_WATCHING_COVERAGE';
export function stopWatchingCoverage(coverage, item) {
return (dispatch) => {
return (dispatch, getState) => {
server.del(WATCH_COVERAGE_URL, {
coverage_id: coverage.coverage_id,
item_id: item._id
Expand All @@ -710,6 +687,10 @@ export function stopWatchingCoverage(coverage, item) {
coverage,
item
});

if (getState().bookmarks) {
dispatch(fetchItems()); // item should get removed from the list in bookmarks view
}
}, (error) => { errorHandler(error, dispatch);});
};
}
4 changes: 2 additions & 2 deletions assets/agenda/components/AgendaApp.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class AgendaApp extends BaseApp {
(this.props.itemToOpen ? [<AgendaItemDetails key="itemDetails"
item={this.props.itemToOpen}
user={this.props.user}
actions={this.filterActions(this.props.itemToOpen, this.props.previewConfig)}
actions={this.filterActions(this.props.itemToOpen, this.props.previewConfig, true)}
onClose={onDetailClose}
requestCoverage={this.props.requestCoverage}
group={this.props.previewGroup}
Expand Down Expand Up @@ -268,7 +268,7 @@ class AgendaApp extends BaseApp {
<AgendaPreview
item={this.props.itemToPreview}
user={this.props.user}
actions={this.filterActions(this.props.itemToPreview, this.props.previewConfig)}
actions={this.filterActions(this.props.itemToPreview, this.props.previewConfig, true)}
coverageActions={this.props.coverageActions}
closePreview={this.props.closePreview}
openItemDetails={this.props.openItemDetails}
Expand Down
29 changes: 20 additions & 9 deletions assets/agenda/components/AgendaCoverages.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import { isEmpty } from 'lodash';
import { gettext } from 'utils';
import CoverageItemStatus from './CoverageItemStatus';
import {getCoverageDisplayName, getCoverageIcon, WORKFLOW_COLORS, WORKFLOW_STATUS, formatCoverageDate} from '../utils';
import {
getDataFromCoverages,
getCoverageDisplayName,
getCoverageIcon,
WORKFLOW_COLORS,
WORKFLOW_STATUS,
formatCoverageDate
} from '../utils';


export default function AgendaCoverages({item, coverages, wireItems, actions, user}) {
export default function AgendaCoverages({item, coverages, wireItems, actions, user, onClick, hideViewContentItems}) {
if (isEmpty(coverages)) {
return null;
}
Expand All @@ -18,13 +27,13 @@ export default function AgendaCoverages({item, coverages, wireItems, actions, us
};

return coverages.map((coverage) => (
<div className='coverage-item' key={coverage.coverage_id}>
<div className={classNames('coverage-item',
{'coverage-item--clickable': onClick})} key={coverage.coverage_id} onClick={onClick}
title={onClick ? gettext('Open Agenda in new tab') : onClick} >
<div className='coverage-item__row'>
<span className='d-flex coverage-item--element-grow text-overflow-ellipsis'>
<span className='d-flex coverage-item--element-grow'>
<i className={`icon-small--coverage-${getCoverageIcon(coverage.coverage_type)} ${WORKFLOW_COLORS[coverage.workflow_status]} mr-2`}></i>
<span className='text-overflow-ellipsis'>
{`${getCoverageDisplayName(coverage.coverage_type)}${getSlugline(coverage)}`}
</span>
<span>{`${getCoverageDisplayName(coverage.coverage_type)}${getSlugline(coverage)}`}</span>
</span>
{coverage.workflow_status !== WORKFLOW_STATUS.COMPLETED && <span className='d-flex text-nowrap'>
<i className='icon-small--clock icon--gray mr-1'></i>
Expand All @@ -41,7 +50,9 @@ export default function AgendaCoverages({item, coverages, wireItems, actions, us
item={item}
wireItems={wireItems}
actions={actions}
user={user} />
user={user}
coverageData={getDataFromCoverages(item)}
hideViewContentItems={hideViewContentItems} />
</div>
));
}
Expand All @@ -50,4 +61,4 @@ AgendaCoverages.propTypes = {
item: PropTypes.object,
coverages: PropTypes.arrayOf(PropTypes.object),
wireItems: PropTypes.array,
};
};
38 changes: 38 additions & 0 deletions assets/agenda/components/AgendaEventInfo.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { get, isEmpty } from 'lodash';

import {gettext} from 'utils';
import AgendaName from './AgendaName';
import AgendaMetaTime from './AgendaMetaTime';
import AgendaLocation from'./AgendaLocation';

const AgendaEventInfo = ({item, onClick}) => {
const event = get(item, 'event');
if (isEmpty(event)) {
return null;
}

return (
<div className={classNames('coverage-item mt-3', {'coverage-item--clickable': onClick})} onClick={onClick}
title={onClick ? gettext('Open Agenda in new tab') : onClick}>
<div className='coverage-item__row'>
<AgendaName item={item} noMargin small/>
</div>
<div className='coverage-item__row wire-articles__item__meta-info m-0'>
<AgendaMetaTime item={item} onlyDates />
</div>
<div className='coverage-item__row coverage-item__row--gray'>
<AgendaLocation item={item} />
</div>
</div>
);
};

AgendaEventInfo.propTypes = {
item: PropTypes.object,
onClick: PropTypes.func,
};

export default AgendaEventInfo;
15 changes: 13 additions & 2 deletions assets/agenda/components/AgendaList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ const itemsSelector = (state) => state.items.map((_id) => state.itemsById[_id]);
const activeDateSelector = (state) => get(state, 'agenda.activeDate');
const activeGroupingSelector = (state) => get(state, 'agenda.activeGrouping');
const itemsByIdSelector = (state) => get(state, 'itemsById', {});
const featuredOnlySelector = (state) => get(state, 'agenda.featuredOnly', false);

const groupedItemsSelector = createSelector(
[itemsSelector, activeDateSelector, activeGroupingSelector],
[itemsSelector, activeDateSelector, activeGroupingSelector, featuredOnlySelector],
groupItems);

/**
Expand Down Expand Up @@ -217,7 +218,15 @@ class AgendaList extends React.Component {
}

render() {
const {groupedItems, itemsById, activeView, selectedItems, readItems, refNode, onScroll} = this.props;
const {
groupedItems,
itemsById,
activeView,
selectedItems,
readItems,
refNode,
onScroll,
} = this.props;
const isExtended = activeView === EXTENDED_VIEW;
const articleGroups = groupedItems.map((group) =>
[
Expand Down Expand Up @@ -337,6 +346,7 @@ AgendaList.propTypes = {
onScroll: PropTypes.func,
refNode: PropTypes.func,
previewConfig: PropTypes.object,
featuredOnly: PropTypes.bool,
};

const mapStateToProps = (state) => ({
Expand All @@ -358,6 +368,7 @@ const mapStateToProps = (state) => ({
listItems: listItemsSelector(state),
isLoading: state.isLoading,
previewConfig: previewConfigSelector(state),
featuredOnly: get(state, 'agenda.featuredOnly'),
});

export default connect(mapStateToProps)(AgendaList);
23 changes: 2 additions & 21 deletions assets/agenda/components/AgendaListItemIcons.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@ import React from 'react';
import PropTypes from 'prop-types';
import {get, isEqual} from 'lodash';
import {bem} from 'ui/utils';
import classNames from 'classnames';
import {
hasCoverages,
isCoverageForExtraDay,
hasLocation,
getLocationString,
isRecurring,
getInternalNote,
getAttachments,
Expand All @@ -17,6 +14,7 @@ import AgendaListItemLabels from './AgendaListItemLabels';
import AgendaMetaTime from './AgendaMetaTime';
import AgendaInternalNote from './AgendaInternalNote';
import AgendaListCoverageItem from './AgendaListCoverageItem';
import AgendaLocation from './AgendaLocation';

import {gettext} from 'utils';

Expand Down Expand Up @@ -54,8 +52,6 @@ class AgendaListItemIcons extends React.Component {
),
attachments: (getAttachments(props.item)).length,
isRecurring: isRecurring(props.item),
hasLocation: hasLocation(props.item),
locationString: getLocationString(props.item),
};
}

Expand Down Expand Up @@ -98,22 +94,7 @@ class AgendaListItemIcons extends React.Component {
)}

<div className='wire-articles__item__meta-info flex-row align-items-start'>
{state.hasLocation && (
<React.Fragment>
<span className='mr-2'>
<i className='icon-small--location icon--gray' />
</span>

{props.isMobilePhone ? (
<span>{state.locationString}</span>
) : (
<span className={classNames('mr-2',
{'wire-articles__item__icons--dashed-border': state.internalNote})}>
{state.locationString}
</span>
)}
</React.Fragment>
)}
<AgendaLocation item={props.item} isMobilePhone={props.isMobilePhone} border={state.internalNote} />

{!props.isMobilePhone && (
<AgendaInternalNote internalNote={state.internalNote} onlyIcon={true}/>
Expand Down
5 changes: 3 additions & 2 deletions assets/agenda/components/AgendaListItemLabels.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ function AgendaListItemLabels({item, withDate, group, right}) {
return (<div><span className={classNames('label label--orange ml-2', {'pull-right': right})}>{labelText}</span></div>);

};
const dateGroup = group && moment(group, DATE_FORMAT);

if (!withDate || !dateGroup) {
if (!withDate) {
return getLabel();
}

const dateGroup = group ? moment(group, DATE_FORMAT) : moment(get(item, 'dates.start'));

return (<div className='wire-column__preview__date wire-column__preview__date--event p-0'>
{formatDate(dateGroup)}{getLabel()}
Expand Down
34 changes: 34 additions & 0 deletions assets/agenda/components/AgendaLocation.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React, {Fragment} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import {hasLocation, getLocationString} from '../utils';

export default function AgendaLocation({item, isMobilePhone, border}) {
if (!hasLocation(item)) {
return null;
}

return (
<Fragment>
<span className='mr-2'>
<i className='icon-small--location icon--gray' />
</span>

{isMobilePhone ? (
<span>{getLocationString(item)}</span>
) : (
<span className={classNames('mr-2',
{'wire-articles__item__icons--dashed-border': border})}>
{getLocationString(item)}
</span>
)}
</Fragment>
);
}

AgendaLocation.propTypes = {
item: PropTypes.object.isRequired,
isMobilePhone: PropTypes.bool,
border: PropTypes.bool,
};
Loading

0 comments on commit 34c173d

Please sign in to comment.