Skip to content

Commit

Permalink
Merge hotfix 2.6.3 develop (#1868)
Browse files Browse the repository at this point in the history
* [SDAAP-64] Fix null location crash in notifications (#1773)

* [SDESK-6873] fix: Backport moment-timezone upgrade

* fix(client): Change moment import to moment-timezone

* fix lint errors

* [SDNTB-804] feature: Add priority to Events, Planning and Coverages (#1772)

* ui: PlanningAPI updates

* api: Add priority to ContentProfiles

* ui: Add priority to ContentProfiles

* api/ui: Add priority to search

* ui: Default values

* ui: fix unit tests

* api: Add behave tests for search

* fix: Getting profiles by ID not working when using system default profiles

* change limit when calling onclusive api (#1783)

* change limit when calling onclusive api

use 1000 instead of 100 to do less pagination,
also fetch some extra items to avoid possible gaps.

SDCP-684

* fix date filtering for all day events (#1782)

* fix date filtering for all day events

when making a query also do a query for all_day events
using only date part of the given date, but it must be
first converted to local time using client timezone so
it will the date user sees in the UI.

also tweak the way the all_day events are assigned to
dates in the UI based on newsroom code.

SDCP-682

* avoid dynamic mapping for event calendars (#1784)

SDESK-6876

* [SDNTB-804] fix(ui): Load ContentProfiles using its name not _id (#1785)

* fix onclusive ingest (#1786)

- keep timestamp for next run based on current start
- look for timezone not only using name but also offset
- increase buffer when getting updates (not clear if the timestamps
  should be utc or local, so add some extra time
- for events with no end time set it to start time and not some fake
  end time which might make it go visible on a next day

SDCP-688 SDCP-690

* check all timezones when parsing onclusive (#1787)

SDCP-688

* fix events not visible in the UI (#1790)

mostly related to events with `no_end_time` flag
which have same end timestamp as start one.

SDCP-680

* there was an error in timezone detection (#1792)

when the event started during the hour when there was daylight
savings switch for a timezone, so rather work with utc date.

SDCP-688

* fix event date not visible in preview (#1791)

* fix event date not visible in preview

that was the case for events with no end time
and same timezone as local one for user.

SDCP-690

* add missing end date for multi day events with no end time

* Fix : Some events ingested from Onclusive do not contain the complete location info [SDCP-692] (#1794)

* fix : Some events ingested from Onclusive do not contain the complete location info [SDCP-692]

* update testcases

* parse location.location field

* fix black

* update logic

* set language for onclusive events based on product (#1796)

SDCP-696

* fix timestamps from onclusive (#1797)

those are currently using London timezone, not utc.

* use languages with -CA for onclusive events (#1798)

so it's consistent with manually created events

SDCP-696

* use /date api for initial import from onclusive (#1801)

use `/date` api instead of `/between`
and log imported events into a text file so we can
check that if needed.

SDCP-699

* [SDESK-6829] fix(ingest_rule): Skip autopost action if item is already posted (#1802)

Multiple posts will still occur if a Calendar or Agenda is to be added in the ingest rule (due to the separation of ingest, and executing routing rules)

* fix server requirements (#1804)

* fix server requirements

* fix e2e core server version

* release 2.6.2

* [SDESK-6972] fix(api): Allow Event dates.tz to have a null value (#1816)

* fix(api): Allow dates.tz to have a null value

* Add tests

* Update UIF (#1851)

* fix switch label param (#1855)

* update server requirements

* log each event id we process from onclusive (#1864)

so we can check logs in case some event is missing

CPCN-380

* fix missed conflict in package.json

* fix: add default values to util functions

* add missing import

* fix merge issues

* fix default planning language value

* fix(e2e): Select tree popover from body not dom parent

* fix(unit tests): Store utcnow before checking versionposted

---------

Co-authored-by: Andrew Marwood <[email protected]>
Co-authored-by: Petr Jašek <[email protected]>
Co-authored-by: devketanpro <[email protected]>
Co-authored-by: Konstantin Markov <[email protected]>
  • Loading branch information
5 people authored Oct 24, 2023
1 parent c5e89f0 commit b4b6421
Show file tree
Hide file tree
Showing 65 changed files with 1,626 additions and 679 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/lint-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- run: pip install black~=23.0
- run: black --check server

Expand All @@ -16,6 +18,8 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- run: pip install flake8
- run: flake8 server

Expand All @@ -24,5 +28,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- run: pip install -Ur server/mypy-requirements.txt
- run: mypy server
14 changes: 12 additions & 2 deletions client/actions/agenda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {cloneDeep, pick, get, sortBy, findIndex} from 'lodash';
import {Moment} from 'moment';

import {IEventItem, IPlanningItem, IAgenda} from '../interfaces';
import {planningApi} from '../superdeskApi';

import {AGENDA, MODALS, EVENTS} from '../constants';
import {getErrorMessage, gettext, planningUtils} from '../utils';
Expand Down Expand Up @@ -240,15 +241,20 @@ const addEventToCurrentAgenda = (
);

export function convertEventToPlanningItem(event: IEventItem): Partial<IPlanningItem> {
const defaultPlace = selectors.general.defaultPlaceList(planningApi.redux.store.getState());
const defaultValues = planningUtils.defaultPlanningValues(null, defaultPlace);

let newPlanningItem: Partial<IPlanningItem> = {
...defaultValues,
type: 'planning',
event_item: event._id,
planning_date: event._sortDate || event.dates?.start,
place: event.place,
place: event.place || defaultPlace,
subject: event.subject,
anpa_category: event.anpa_category,
agendas: [],
language: event.language,
language: event.language || defaultValues.language,
languages: event.languages || defaultValues.languages,
};

newPlanningItem = convertStringFields(
Expand All @@ -269,6 +275,10 @@ export function convertEventToPlanningItem(event: IEventItem): Partial<IPlanning
newPlanningItem.languages = event.languages;
}

if (event.priority != null) {
newPlanningItem.priority = event.priority;
}

return newPlanningItem;
}

Expand Down
8 changes: 6 additions & 2 deletions client/actions/events/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -741,15 +741,19 @@ const receiveEventHistory = (eventHistoryItems) => ({
*/
const createEventFromPlanning = (plan: IPlanningItem) => (
(dispatch, getState) => {
const defaultDurationOnChange = selectors.forms.defaultEventDuration(getState());
const occurStatuses = selectors.vocabs.eventOccurStatuses(getState());
const state = getState();
const defaultDurationOnChange = selectors.forms.defaultEventDuration(state);
const occurStatuses = selectors.vocabs.eventOccurStatuses(state);
const defaultCalendar = selectors.events.defaultCalendarValue(state);
const defaultPlace = selectors.general.defaultPlaceList(state);
const unplannedStatus = getItemInArrayById(occurStatuses, 'eocstat:eos0', 'qcode') || {
label: 'Unplanned event',
qcode: 'eocstat:eos0',
name: 'Unplanned event',
};
const eventProfile = selectors.forms.eventProfile(getState());
let newEvent: Partial<IEventItem> = {
...eventUtils.defaultEventValues(occurStatuses, defaultCalendar, defaultPlace),
dates: {
start: moment(plan.planning_date).clone(),
end: moment(plan.planning_date)
Expand Down
10 changes: 9 additions & 1 deletion client/actions/tests/agenda_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,15 @@ describe('agenda', () => {
{},
{
type: 'planning',
state: 'draft',
item_class: 'plinat:newscoverage',
language: 'en',
languages: ['en'],
flags: {
marked_for_not_publication: false,
overide_auto_assign_to_workflow: false,
},
coverages: [],
event_item: events[0]._id,
planning_date: events[0].dates.start,
slugline: events[0].slugline,
Expand All @@ -345,7 +354,6 @@ describe('agenda', () => {
}],
internal_note: 'internal note',
ednote: 'Editorial note about this Event',
language: undefined,
},
]);

Expand Down
1 change: 1 addition & 0 deletions client/api/combined.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ function convertCombinedParams(params: ISearchParams): Partial<ISearchAPIParams>
include_associated_planning: params.include_associated_planning,
source: cvsToString(params.source, 'id'),
coverage_user_id: params.coverage_user_id,
priority: arrayToString(params.priority),
};
}

Expand Down
49 changes: 49 additions & 0 deletions client/api/contentProfiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
IPlanningContentProfile,
IPlanningAPI,
IEventOrPlanningItem,
IPlanningCoverageItem,
IProfileMultilingualDetails,
IProfileSchemaTypeString,
} from '../interfaces';
Expand All @@ -30,11 +31,45 @@ function getAll(): Promise<Array<IPlanningContentProfile>> {
)
.then((response) => {
response._items.forEach(sortProfileGroups);
enablePriorityInSearchProfile(response._items);

return response._items;
});
}

function enablePriorityInSearchProfile(profiles: Array<IPlanningContentProfile>) {
// Hack to enable/disable priority field in search profiles based on the content profiles
// TODO: Remove this hack when we implement a solution for all searchable fields
const profilesById: {[id: string]: IPlanningContentProfile} = profiles.reduce((profileMap, profile) => {
profileMap[profile.name] = profile;

return profileMap;
}, {});
const searchProfile = profilesById.advanced_search.editor;
const priorityEnabled = {
event: profilesById.event.editor.priority?.enabled === true,
planning: profilesById.planning.editor.priority?.enabled === true,
};

const priorityField = {
enabled: true,
index: 5,
group: 'common',
search_enabled: true,
filter_enabled: true,
};

if (priorityEnabled.event) {
searchProfile.event.priority = priorityField;
if (priorityEnabled.planning) {
searchProfile.combined.priority = priorityField;
}
}
if (priorityEnabled.planning) {
searchProfile.planning.priority = priorityField;
}
}

function getProfile(contentType: string): IPlanningContentProfile {
const {getState} = planningApi.redux.store;

Expand Down Expand Up @@ -192,9 +227,23 @@ function updateProfilesInStore(): Promise<void> {
});
}

function getDefaultValues(profile: IPlanningContentProfile): DeepPartial<IEventOrPlanningItem | IPlanningCoverageItem> {
return Object.keys(profile?.schema ?? {}).reduce(
(defaults, field) => {
if (profile.schema[field]?.default_value != null) {
defaults[field] = profile.schema[field].default_value;
}

return defaults;
},
{}
);
}

export const contentProfiles: IPlanningAPI['contentProfiles'] = {
getAll: getAll,
get: getProfile,
getDefaultValues: getDefaultValues,
patch: patch,
showManagePlanningProfileModal: showManagePlanningProfileModal,
showManageEventProfileModal: showManageEventProfileModal,
Expand Down
3 changes: 2 additions & 1 deletion client/api/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {IRestApiResponse} from 'superdesk-api';
import {planningApi, superdeskApi} from '../superdeskApi';
import {EVENTS, TEMP_ID_PREFIX} from '../constants';

import {convertCommonParams, cvsToString, searchRaw, searchRawGetAll} from './search';
import {arrayToString, convertCommonParams, cvsToString, searchRaw, searchRawGetAll} from './search';
import {eventUtils, planningUtils} from '../utils';
import {eventProfile, eventSearchProfile} from '../selectors/forms';
import * as actions from '../actions';
Expand All @@ -23,6 +23,7 @@ function convertEventParams(params: ISearchParams): Partial<ISearchAPIParams> {
location: params.location?.qcode,
calendars: cvsToString(params.calendars),
no_calendar_assigned: params.no_calendar_assigned,
priority: arrayToString(params.priority),
};
}

Expand Down
3 changes: 2 additions & 1 deletion client/api/planning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ function convertPlanningParams(params: ISearchParams): Partial<ISearchAPIParams>
g2_content_type: params.g2_content_type?.qcode,
source: cvsToString(params.source, 'id'),
coverage_user_id: params.coverage_user_id,
coverage_assignment_status: params.coverage_assignment_status
coverage_assignment_status: params.coverage_assignment_status,
priority: arrayToString(params.priority),
};
}

Expand Down
4 changes: 3 additions & 1 deletion client/api/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {ISearchAPIParams, ISearchParams} from '../interfaces';
import {superdeskApi} from '../superdeskApi';
import {IRestApiResponse} from 'superdesk-api';
import {getDateTimeElasticFormat, getTimeZoneOffset} from '../utils';
import {default as timeUtils} from '../utils/time';


export function cvsToString(items?: Array<{[key: string]: any}>, field: string = 'qcode'): string {
Expand All @@ -11,7 +12,7 @@ export function cvsToString(items?: Array<{[key: string]: any}>, field: string =
);
}

export function arrayToString(items?: Array<string>): string {
export function arrayToString(items?: Array<string | number>): string {
return (items ?? [])
.join(',');
}
Expand Down Expand Up @@ -48,6 +49,7 @@ export function convertCommonParams(params: ISearchParams): Partial<ISearchAPIPa
sort_order: params.sort_order,
sort_field: params.sort_field,
tz_offset: params.date_filter ? getTimeZoneOffset() : null,
time_zone: timeUtils.localTimeZone(),
};
}

Expand Down
4 changes: 4 additions & 0 deletions client/components/AdvancedSearch/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ export class AdvancedSearch extends React.PureComponent<IProps> {
location: {
disableAddLocation: false,
},
priority: {
multiple: true,
defaultValue: [],
},
},
null,
this.props.enabledField
Expand Down
2 changes: 2 additions & 0 deletions client/components/ContentProfiles/FieldTab/FieldEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export class FieldEditor extends React.Component<IProps, IState> {
!['language', 'location'].includes(this.props.item.name)
)
)},
'schema.default_value': {enabled: this.props.item.name === 'priority'},
};
const noOptionsAvailable = !(
Object.values(fieldProps)
Expand Down Expand Up @@ -189,6 +190,7 @@ export class FieldEditor extends React.Component<IProps, IState> {
'schema.languages': {enabled: true, index: 12},
'schema.default_language': {enabled: true, index: 13},
'schema.planning_auto_publish': {enabled: true, index: 14},
'schema.default_value': {enabled: true, index: 11},
},
{
item: this.props.item,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ export class CoverageFormComponent extends React.Component<IProps, IState> {
this.props.value.planning?.g2_content_type === 'text'
),
},
priority: {field: 'planning.priority'},
};

const profile = editor.item.planning.getCoverageFields();
Expand Down
5 changes: 2 additions & 3 deletions client/components/Events/EventDateTime.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import moment from 'moment';

import {superdeskApi} from '../../superdeskApi';
import {IEventItem} from '../../interfaces';
Expand All @@ -20,8 +19,8 @@ export class EventDateTime extends React.PureComponent<IProps> {
render() {
const {gettext} = superdeskApi.localization;
const {item, ignoreAllDay, displayLocalTimezone} = this.props;
const start = moment(item.dates.start);
const end = moment(item.dates.end);
const start = eventUtils.getStartDate(item);
const end = eventUtils.getEndDate(item);
const isAllDay = eventUtils.isEventAllDay(start, end);
const multiDay = !eventUtils.isEventSameDay(start, end);
const isRemoteTimeZone = timeUtils.isEventInDifferentTimeZone(item);
Expand Down
3 changes: 2 additions & 1 deletion client/components/Events/EventScheduleSummary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ export const EventScheduleSummary = ({
forUpdating = false,
useEventTimezone = false
}: IProps) => {
if (!event)
if (!event) {
return null;
}

const eventSchedule: IEventItem['dates'] = get(event, 'dates', {});
const doesRepeat = get(eventSchedule, 'recurring_rule', null) !== null;
Expand Down
27 changes: 27 additions & 0 deletions client/components/fields/editor/ProfileFieldDefaultValue.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as React from 'react';

import {IEditorFieldProps, IProfileFieldEntry} from '../../../interfaces';

import {renderFieldsForPanel} from '../index';

interface IProps extends IEditorFieldProps {
item: IProfileFieldEntry;
onChange(field: string, value: string | number): void;
}

export function ProfileFieldDefaultValue({item, onChange, ...props}: IProps) {
return renderFieldsForPanel(
'editor',
{[item.name]: {enabled: true, index: 1}},
{
item: item,
onChange: onChange,
},
{
[item.name]: {
...props,
field: 'schema.default_value',
},
}
);
}
Loading

0 comments on commit b4b6421

Please sign in to comment.