Skip to content

Commit

Permalink
Fix closing items from the bottom bar in planning module (#2070)
Browse files Browse the repository at this point in the history
  • Loading branch information
thecalcc authored Sep 12, 2024
1 parent 07d108b commit 55f1293
Show file tree
Hide file tree
Showing 18 changed files with 89 additions and 49 deletions.
3 changes: 2 additions & 1 deletion client/actions/agenda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {AGENDA, MODALS, EVENTS} from '../constants';
import {getErrorMessage, gettext, planningUtils} from '../utils';
import {planning, showModal, main} from './index';
import {convertStringFields} from '../utils/strings';
import planningApis from '../actions/planning/api';

const openAgenda = () => (
(dispatch) => (
Expand Down Expand Up @@ -302,7 +303,7 @@ const createPlanningFromEvent = (
newPlanningItem.agendas = newPlanningItem.agendas.concat(agendas);

return (dispatch) => (
dispatch(planning.api.save({}, newPlanningItem))
dispatch(planningApis.save({}, newPlanningItem))
);
};

Expand Down
4 changes: 2 additions & 2 deletions client/actions/assignments/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import {lockUtils, assignmentUtils, gettext, isExistingItem} from '../../utils';
import * as selectors from '../../selectors';
import assignments from './index';
import main from '../main';
import planning from '../planning';
import {hideModal, showModal} from '../index';
import * as actions from '../../actions';
import planningApis from '../planning/api';

const _notifyAssignmentEdited = (assignmentId) => (
(dispatch, getState, {notify}) => {
Expand Down Expand Up @@ -191,7 +191,7 @@ const _updatePlannigRelatedToAssignment = (data) => (
return Promise.resolve();
}

dispatch(planning.api.loadPlanningByIds([data.planning]));
dispatch(planningApis.loadPlanningByIds([data.planning]));
dispatch(main.fetchItemHistory(planningItem));
}
);
Expand Down
41 changes: 23 additions & 18 deletions client/actions/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import {get, isEmpty, isEqual, isNil, omit} from 'lodash';
import moment from 'moment';

import {appConfig} from 'appConfig';
import {appConfig as config} from 'appConfig';

const appConfig = config as IPlanningConfig;

import {IUser} from 'superdesk-api';
import {planningApi, superdeskApi} from '../superdeskApi';
import {
Expand All @@ -18,6 +21,7 @@ import {
ITEM_TYPE,
IEventTemplate,
IEventItem,
IPlanningConfig,
} from '../interfaces';

import {
Expand Down Expand Up @@ -68,6 +72,7 @@ import eventsPlanningUi from './eventsPlanning/ui';
import * as selectors from '../selectors';
import {validateItem} from '../validators';
import {searchParamsToOld} from '../utils/search';
import {searchAndStore} from '../api/combined';

function openForEdit(item: IEventOrPlanningItem, updateUrl: boolean = true, modal: boolean = false) {
return (dispatch, getState) => {
Expand Down Expand Up @@ -716,7 +721,7 @@ const openIgnoreCancelSaveModal = ({
const storedItems = itemType === ITEM_TYPE.EVENT ?
selectors.events.storedEvents(getState()) :
selectors.planning.storedPlannings(getState());
const item = get(storedItems, itemId) || {};
const item = storedItems[itemId] ?? {};

if (!isExistingItem(item)) {
delete item._id;
Expand All @@ -725,19 +730,17 @@ const openIgnoreCancelSaveModal = ({
let promise = Promise.resolve(item);

if (itemType === ITEM_TYPE.EVENT && eventUtils.isEventRecurring(item)) {
const originalEvent = get(storedItems, itemId, {});

promise = dispatch(eventsApi.query({
recurrenceId: originalEvent.recurrence_id,
maxResults: appConfig.max_recurrent_events,
onlyFuture: false,
}))
.then((relatedEvents) => ({
...item,
_recurring: relatedEvents || [item],
_events: [],
_originalEvent: originalEvent,
}));
promise = searchAndStore({
recurrence_id: item.recurrence_id,
max_results: appConfig.max_recurrent_events,
only_future: false,
include_associated_planning: true,
}).then((relatedEvents) => ({
...item,
_recurring: relatedEvents.filter((item) => item.type === 'event') ?? [item],
_events: [],
_originalEvent: item,
}));
}

return promise.then((itemWithAssociatedData) => (
Expand Down Expand Up @@ -1200,8 +1203,10 @@ const openFromLockActions = () => (
if (action) {
/* get the item we're operating on */
dispatch(self.fetchById(sessionLastLock.item_id, sessionLastLock.item_type)).then((item) => {
actionUtils.getActionDispatches({dispatch: dispatch, eventOnly: false,
planningOnly: false})[action[0].actionName](item, false, false);
actionUtils.getActionDispatches({
dispatch: dispatch, eventOnly: false,
planningOnly: false
})[action[0].actionName](item, false, false);
});
}
}
Expand Down Expand Up @@ -1460,7 +1465,7 @@ function onItemUnlocked(
}));

if (getItemType(item) === ITEM_TYPE.PLANNING && selectors.general.currentWorkspace(state)
=== WORKSPACE.AUTHORING) {
=== WORKSPACE.AUTHORING) {
dispatch(self.closePreviewAndEditorForItems([item]));
}
}
Expand Down
2 changes: 1 addition & 1 deletion client/actions/planning/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ const unpost = (original, updates) => (
* Also loads all the associated contacts (if any)
* @param {array, object} plannings - An array of planning item objects
*/
const receivePlannings = (plannings) => (
const receivePlannings = (plannings): any => (
(dispatch) => {
dispatch(actions.contacts.fetchContactsFromPlanning(plannings));
dispatch({
Expand Down
3 changes: 2 additions & 1 deletion client/actions/planning/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {events, fetchAgendas} from '../index';
import main from '../main';
import {showModal, hideModal} from '../index';
import eventsPlanning from '../eventsPlanning';
import planningApis from '../planning/api';

/**
* WS Action when a new Planning item is created
Expand Down Expand Up @@ -104,7 +105,7 @@ const onPlanningLocked = (e, data) => (

const sessionId = selectors.general.session(getState()).sessionId;

return dispatch(planning.api.getPlanning(data.item, false))
return dispatch(planningApis.getPlanning(data.item, false))
.then((planInStore) => {
let plan = {
...planInStore,
Expand Down
4 changes: 1 addition & 3 deletions client/actions/planning/tests/api_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ import {
restoreSinonStub,
convertEventDatesToMoment,
} from '../../../utils/testUtils';
import {createTestStore} from '../../../utils';
import {PLANNING, SPIKED_STATE, WORKFLOW_STATE} from '../../../constants';
import {PLANNING, SPIKED_STATE} from '../../../constants';
import {MAIN} from '../../../constants';
import * as selectors from '../../../selectors';
import contactsApi from '../../contacts';
import {planningApis} from '../../../api';

Expand Down
5 changes: 2 additions & 3 deletions client/actions/planning/tests/notifications_test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {planningApi} from '../../../superdeskApi';
import planningApis from '../api';
import planningApis from '../../planning/api';
import planningUi from '../ui';
import featuredPlanning from '../featuredPlanning';
import eventsPlanningUi from '../../eventsPlanning/ui';
Expand Down Expand Up @@ -197,7 +197,7 @@ describe('actions.planning.notifications', () => {
describe('onPlanningLocked', () => {
beforeEach(() => {
sinon.stub(planningApi.locks, 'setItemAsLocked').returns(undefined);
sinon.stub(planningApis, 'getPlanning').returns(Promise.resolve(data.plannings[0]));
sinon.stub(planningApis, 'getPlanning').returns(() => Promise.resolve(data.plannings[0]));
});

afterEach(() => {
Expand All @@ -219,7 +219,6 @@ describe('actions.planning.notifications', () => {
))
.then(() => {
expect(planningApi.locks.setItemAsLocked.callCount).toBe(1);
expect(planningApis.getPlanning.callCount).toBe(1);
expect(planningApis.getPlanning.args[0]).toEqual([
'p1',
false,
Expand Down
17 changes: 15 additions & 2 deletions client/api/combined.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import {
IEventOrPlanningItem,
} from '../interfaces';
import {IRestApiResponse} from 'superdesk-api';
import {searchRaw, searchRawGetAll, convertCommonParams, cvsToString, arrayToString} from './search';
import {searchRaw, searchRawGetAll, convertCommonParams, cvsToString, arrayToString, searchRawAndStore} from './search';
import {eventUtils, planningUtils} from '../utils';
import {planningApi} from '../superdeskApi';
import {combinedSearchProfile} from '../selectors/forms';
import {searchPlanningGetAll} from './planning';
import {searchPlanningGetAll, convertPlanningParams} from './planning';
import {searchEventsGetAll} from './events';

type IResponse = IRestApiResponse<IEventOrPlanningItem>;
Expand Down Expand Up @@ -67,6 +67,18 @@ export function searchCombinedGetAll(params: ISearchParams): Promise<Array<IEven
});
}

export function searchAndStore(params: ISearchParams) {
return searchRawAndStore<IEventOrPlanningItem>({
...convertCommonParams(params),
...convertPlanningParams(params),
repo: FILTER_TYPE.COMBINED,
}).then((res) => {
res._items.forEach(modifyItemForClient);

return res._items;
});
}

export function getEventsAndPlanning(params: ISearchParams): Promise<{
events: Array<IEventItem>;
plannings: Array<IPlanningItem>;
Expand Down Expand Up @@ -145,5 +157,6 @@ export const combined: IPlanningAPI['combined'] = {
getRecurringEventsAndPlanningItems: getRecurringEventsAndPlanningItems,
getEventsAndPlanning: getEventsAndPlanning,
getSearchProfile: getCombinedSearchProfile,
searchAndStore: searchAndStore,
};

6 changes: 3 additions & 3 deletions client/api/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {EVENTS, TEMP_ID_PREFIX} from '../constants';
import {arrayToString, convertCommonParams, cvsToString, searchRaw, searchRawGetAll} from './search';
import {eventUtils} from '../utils';
import {eventProfile, eventSearchProfile} from '../selectors/forms';
import * as actions from '../actions';
import planningApis from '../actions/planning/api';

const appConfig = config as IPlanningConfig;

Expand Down Expand Up @@ -161,7 +161,7 @@ function create(updates: Partial<IEventItem>): Promise<Array<IEventItem>> {
}).then((planningItems) => {
// Make sure to update the Redux Store with the latest Planning items
// So that the Editor can set the state with these latest items
planningApi.redux.store.dispatch<any>(actions.planning.api.receivePlannings(planningItems));
planningApi.redux.store.dispatch<any>(planningApis.receivePlannings(planningItems));

return events;
});
Expand Down Expand Up @@ -207,7 +207,7 @@ function update(original: IEventItem, updates: Partial<IEventItem>): Promise<Arr
}).then((planningItems) => {
// Make sure to update the Redux Store with the latest Planning items
// So that the Editor can set the state with these latest items
planningApi.redux.store.dispatch<any>(actions.planning.api.receivePlannings(planningItems));
planningApi.redux.store.dispatch<any>(planningApis.receivePlannings(planningItems));

return events;
});
Expand Down
10 changes: 5 additions & 5 deletions client/api/planning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ import {planningProfile, planningSearchProfile} from '../selectors/forms';
import {featured} from './featured';
import {PLANNING} from '../constants';
import * as selectors from '../selectors';
import * as actions from '../actions';
import planningApis from '../actions/planning/api';

const appConfig = config as IPlanningConfig;

function convertPlanningParams(params: ISearchParams): Partial<ISearchAPIParams> {
export function convertPlanningParams(params: ISearchParams): Partial<ISearchAPIParams> {
return {
agendas: arrayToString(params.agendas),
no_agenda_assigned: params.no_agenda_assigned,
Expand Down Expand Up @@ -90,7 +90,7 @@ export function getPlanningById(
.then(modifyItemForClient)
.then((item) => {
if (saveToStore) {
dispatch<any>(actions.planning.api.receivePlannings([item]));
dispatch<any>(planningApis.receivePlannings([item]));
}

return item;
Expand Down Expand Up @@ -215,7 +215,7 @@ function bulkAddCoverageToWorkflow(planningItems: Array<IPlanningItem>): Promise

return planning.update(plan, updates)
.then((updatedPlan) => {
dispatch<any>(actions.planning.api.receivePlannings([updatedPlan]));
dispatch<any>(planningApis.receivePlannings([updatedPlan]));

return updatedPlan;
});
Expand Down Expand Up @@ -254,7 +254,7 @@ function addCoverageToWorkflow(
return planning.update(plan, updates)
.then((updatedPlan) => {
notify.success(gettext('Coverage added to workflow.'));
dispatch<any>(actions.planning.api.receivePlannings([updatedPlan]));
dispatch<any>(planningApis.receivePlannings([updatedPlan]));

return updatedPlan;
})
Expand Down
28 changes: 25 additions & 3 deletions client/api/search.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {ISearchAPIParams, ISearchParams} from '../interfaces';
import {superdeskApi} from '../superdeskApi';
import {IEventOrPlanningItem, ISearchAPIParams, ISearchParams} from '../interfaces';
import {superdeskApi, planningApi as sdPlanningApi} from '../superdeskApi';
import {IRestApiResponse} from 'superdesk-api';
import {getDateTimeElasticFormat, getTimeZoneOffset} from '../utils';
import {default as timeUtils} from '../utils/time';
import {appConfig} from 'appConfig';

import planningApi from '../actions/planning/api';
import eventsApi from '../actions/events/api';
import {partition} from 'lodash';

export function cvsToString(items?: Array<{[key: string]: any}>, field: string = 'qcode'): string {
return arrayToString(
Expand Down Expand Up @@ -51,6 +53,7 @@ export function convertCommonParams(params: ISearchParams): Partial<ISearchAPIPa
sort_field: params.sort_field,
tz_offset: params.date_filter ? getTimeZoneOffset() : null,
time_zone: timeUtils.localTimeZone(),
include_associated_planning: params.include_associated_planning,
};
}

Expand All @@ -76,6 +79,25 @@ export function searchRaw<T>(args: ISearchAPIParams): Promise<IRestApiResponse<T
);
}

export const searchRawAndStore = <T>(args: ISearchAPIParams) => {
const {dispatch} = sdPlanningApi.redux.store;

return superdeskApi.dataApi.queryRawJson<IRestApiResponse<T>>(
'events_planning_search',
excludeNullParams(args)
).then((res) => {
const [relatedPlans, events] = partition(res._items, (item: IEventOrPlanningItem) => item.type === 'planning');

if (args.include_associated_planning) {
dispatch(planningApi.receivePlannings(relatedPlans));
}

dispatch(eventsApi.receiveEvents(events));

return res;
});
};

export function searchRawGetAll<T>(args: ISearchAPIParams): Promise<Array<T>> {
const params = excludeNullParams(args);
let items: Array<T> = [];
Expand Down
2 changes: 1 addition & 1 deletion client/components/GeoLookupInput/AddGeoLookupInput.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import Geolookup from 'react-geolookup';
import DebounceInput from 'react-debounce-input';
import {DebounceInput} from 'react-debounce-input';

import {appConfig} from 'appConfig';
import {IRestApiResponse} from 'superdesk-api';
Expand Down
2 changes: 1 addition & 1 deletion client/components/IgnoreCancelSaveModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export class IgnoreCancelSaveModalComponent extends React.Component<IProps, ISta
return (
<UpdateRecurringEventsForm
original={this.props.modalProps.item}
updates={this.props.modalProps.updates}
updates={this.props.modalProps.updates as Partial<IEventItem>}
onEventUpdateMethodChange={this.onEventUpdateMethodChange}
onPlanningUpdateMethodChange={this.onPlanningUpdateMethodChange}
modalProps={{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ function getRecurringPlanningToUpdate(
updates: Partial<IEventItem>,
plannings: {[planningId: string]: IPlanningItem}
): Array<IPlanningItem['_id']> {
const originalCoverages: IPlanningEmbeddedCoverageMap = (original.planning_ids || [])
const originalCoverages: IPlanningEmbeddedCoverageMap = (original.planning_ids ?? [])
.map((planningId) => plannings[planningId])
.reduce((planningItems, planningItem) => {
planningItems[planningItem._id] = (planningItem.coverages ?? []).reduce(
Expand Down
2 changes: 1 addition & 1 deletion client/components/UI/SearchBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import DebounceInput from 'react-debounce-input';
import {DebounceInput} from 'react-debounce-input';
import {isNil, uniqueId} from 'lodash';
import {gettext} from '../../../utils/gettext';
import './style.scss';
Expand Down
2 changes: 1 addition & 1 deletion client/components/UI/SearchField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import DebounceInput from 'react-debounce-input';
import {DebounceInput} from 'react-debounce-input';
import {uniqueId} from 'lodash';
import {KEYCODES} from '../constants';
import {onEventCapture} from '../utils';
Expand Down
1 change: 1 addition & 0 deletions client/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2207,6 +2207,7 @@ export interface IPlanningAPI {
getEditorProfile(): ICoverageFormProfile;
};
combined: {
searchAndStore(params: ISearchParams): Promise<IRestApiResponse<IEventOrPlanningItem>>;
search(params: ISearchParams): Promise<IRestApiResponse<IEventOrPlanningItem>>;
searchGetAll(params: ISearchParams): Promise<Array<IEventOrPlanningItem>>;
getRecurringEventsAndPlanningItems(
Expand Down
Loading

0 comments on commit 55f1293

Please sign in to comment.