Skip to content

Commit

Permalink
rework cancelling coverages so logic is contained inside coverages field
Browse files Browse the repository at this point in the history
  • Loading branch information
tomaskikutis committed Dec 11, 2024
1 parent 248c01b commit 9a6946c
Show file tree
Hide file tree
Showing 17 changed files with 106 additions and 260 deletions.
38 changes: 0 additions & 38 deletions client/actions/planning/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -567,42 +567,6 @@ const addNewCoverageToPlanning = (coverageType, item) => (
})))
);

const openCancelCoverageModal = (planning, coverage, index, onSubmit, onCancel,
scheduledUpdate, scheduledUpdateIndex) => (
(dispatch, getState) =>
dispatch(showModal({
modalType: MODALS.ITEM_ACTIONS_MODAL,
modalProps: {
original: planning,
actionType: COVERAGES.ITEM_ACTIONS.CANCEL_COVERAGE.actionName,
coverage: coverage,
index: index,
onSubmit: onSubmit,
onCancel: onCancel,
scheduledUpdate: scheduledUpdate,
scheduledUpdateIndex: scheduledUpdateIndex,
},
}))
);

const cancelCoverage = (original, updatedCoverage, index, scheduledUpdate, scheduledUpdateIndex) => (
(dispatch, getState, {notify}) => {
let updates = {coverages: cloneDeep(original.coverages)};

if (!scheduledUpdate) {
updates.coverages[index] = cloneDeep(updatedCoverage);
} else {
updates.coverages[index].scheduled_updates[scheduledUpdateIndex] = cloneDeep(scheduledUpdate);
}

return dispatch(planningApis.save(original, updates))
.then((savedItem) => {
notify.success(gettext('Coverage cancelled.'));
return dispatch(self.updateItemOnSave(savedItem));
});
}
);

// eslint-disable-next-line consistent-this
const self = {
spike,
Expand Down Expand Up @@ -633,8 +597,6 @@ const self = {
openFeaturedPlanningModal,
updateItemOnSave,
addNewCoverageToPlanning,
openCancelCoverageModal,
cancelCoverage,
addScheduledUpdateToWorkflow,
};

Expand Down
66 changes: 64 additions & 2 deletions client/api/coverages.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,73 @@
import {IPlanningAPI} from '../interfaces';
import {PLANNING, WORKFLOW_STATE} from '../constants';
import {ICoverageScheduledUpdate, IPlanningAPI, IPlanningCoverageItem} from '../interfaces';
import {coverageProfile} from '../selectors/forms';
import {planningApi} from '../superdeskApi';
import {planningApi, superdeskApi} from '../superdeskApi';

function getCoverageEditorProfile() {
return coverageProfile(planningApi.redux.store.getState());
}

function cancelCoverageOrScheduledUpdate<T extends IPlanningCoverageItem | ICoverageScheduledUpdate>(
item: T,
cancellationReason: string,
): T {
const nextItem: T = {...item};

nextItem.news_coverage_status = PLANNING.NEWS_COVERAGE_CANCELLED_STATUS;
nextItem.planning.workflow_status_reason = cancellationReason;
nextItem.workflow_status = WORKFLOW_STATE.CANCELLED;

if (nextItem.assigned_to?.state != null) {
nextItem.assigned_to.state = WORKFLOW_STATE.CANCELLED;
}

return nextItem;
}

function cancelCoverage(
items: Array<IPlanningCoverageItem>,
itemToCancel: IPlanningCoverageItem,
): Promise<Array<IPlanningCoverageItem>> {
const {gettext} = superdeskApi.localization;

return superdeskApi.ui.prompt({
inputLabel: gettext('Reason for cancelling the coverage'),
okButtonText: gettext('Confirm'),
cancelButtonText: gettext('Cancel'),
}).then((reason) => {
return items.map((item) => {
if (item.coverage_id === itemToCancel.coverage_id) {
return cancelCoverageOrScheduledUpdate(item, reason);
} else {
return item;
}
});
});
}

function cancelScheduledUpdate(
items: Array<ICoverageScheduledUpdate>,
itemToCancel: ICoverageScheduledUpdate,
): Promise<Array<ICoverageScheduledUpdate>> {
const {gettext} = superdeskApi.localization;

return superdeskApi.ui.prompt({
inputLabel: gettext('Reason for cancelling the scheduled update'),
okButtonText: gettext('Confirm'),
cancelButtonText: gettext('Cancel'),
}).then((reason) => {
return items.map((item) => {
if (item.scheduled_update_id === itemToCancel.scheduled_update_id) {
return cancelCoverageOrScheduledUpdate(item, reason);
} else {
return item;
}
});
});
}

export const coverages: IPlanningAPI['coverages'] = {
getEditorProfile: getCoverageEditorProfile,
cancelCoverage: cancelCoverage,
cancelScheduledUpdate: cancelScheduledUpdate,
};
7 changes: 1 addition & 6 deletions client/components/Coverages/CoverageArrayInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,6 @@ interface IProps {
setCoverageDefaultDesk(coverage: IPlanningCoverageItem): void;
setCoverageAddAdvancedMode(enabled: boolean): Promise<void>;
createUploadLink(file: IFile): void;
onCancelCoverage(
coverage: IPlanningCoverageItem,
index: number,
scheduledUpdate?: ICoverageScheduledUpdate,
scheduledUpdateIndex?: number,
): void;
onAddCoverageToWorkflow(coverage: IPlanningCoverageItem, index: number): void;
onAddScheduledUpdateToWorkflow(
coverage: IPlanningCoverageItem,
Expand Down Expand Up @@ -211,6 +205,7 @@ class CoverageArrayInputComponent extends React.Component<IProps, IState> {
labelClassName="side-panel__heading side-panel__heading--big"
field={field}
value={value}
coverages={value}
onChange={onChange}
addButtonText={addButtonText}
addButtonComponent={CoverageAddButton}
Expand Down
7 changes: 0 additions & 7 deletions client/components/Coverages/CoverageEditor/CoverageForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,6 @@ interface IProps {
scheduledUpdate: any,
scheduledUpdateIndex: number
): void;
onCancelCoverage(
coverage: IPlanningCoverageItem,
index: number,
scheduledUpdate?: ICoverageScheduledUpdate,
scheduledUpdateIndex?: number
): void;
uploadFiles(files: Array<Array<File>>): Promise<Array<IFile>>;
createUploadLink(file: IFile): void;
removeFile(file: IFile): Promise<void>;
Expand Down Expand Up @@ -440,7 +434,6 @@ export class CoverageFormComponent extends React.Component<IProps, IState> {
this.props.addNewsItemToPlanning == null &&
!get(this.props.diff, `${this.props.field}.flags.no_content_linking`)
),
onCancelCoverage: this.props.onCancelCoverage,
index: this.props.index,
openScheduledUpdates: this.state.openScheduledUpdates,
planning: this.props.diff,
Expand Down
29 changes: 20 additions & 9 deletions client/components/Coverages/CoverageEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,22 @@ import {CoverageFormHeader} from './CoverageFormHeader';
import {planningUtils, gettext, editorMenuUtils} from '../../../utils';
import {getVocabularyItemFieldTranslated} from '../../../utils/vocabularies';
import {getUserInterfaceLanguageFromCV} from '../../../utils/users';
import {COVERAGES} from '../../../constants';
import {getRelatedEventIdsForPlanning} from '../../../utils/planning';
import {planningApi} from '../../../superdeskApi';
import {planningApis} from '../../../api';

interface IProps {
testId?: string;
field: string;
value: IPlanningCoverageItem;

/**
* List of coverages that current coverage (`IProps['value']`) is a part of.
* It is needed, because `IProps['onChange']` requires to pass all coverages
* even if only a single one is being modified.
*/
coverages: Array<IPlanningCoverageItem>;

users: Array<IUser>;
desks: Array<IDesk>;
newsCoverageStatus: Array<IPlanningNewsCoverageStatus>;
Expand All @@ -56,7 +64,6 @@ interface IProps {

onChange(field: string, value: any): void;
remove(): void;
onCancelCoverage?(): void;
onAddCoverageToWorkflow?(): void;
onRemoveAssignment?(coverage: IPlanningCoverageItem): void;
popupContainer(): void;
Expand Down Expand Up @@ -124,7 +131,6 @@ export class CoverageEditor extends React.PureComponent<IProps> {
coverageProviders,
priorities,
keywords,
onCancelCoverage,
onAddCoverageToWorkflow,
onRemoveAssignment,
readOnly,
Expand Down Expand Up @@ -154,7 +160,7 @@ export class CoverageEditor extends React.PureComponent<IProps> {
icon: 'icon-copy',
callback: () => {
this.props.onChange(
'coverages',
field,
duplicateCoverage({
planning: diff,
coverage: value,
Expand All @@ -177,7 +183,7 @@ export class CoverageEditor extends React.PureComponent<IProps> {
),
callback: () => {
this.props.onChange(
'coverages',
field,
duplicateCoverage({
planning: diff,
coverage: value,
Expand All @@ -189,10 +195,16 @@ export class CoverageEditor extends React.PureComponent<IProps> {
},
];

if (onCancelCoverage != null && planningUtils.canCancelCoverage(value, diff)) {
if (planningUtils.canCancelCoverage(value, diff)) {
itemActions.push({
...COVERAGES.ITEM_ACTIONS.CANCEL_COVERAGE,
callback: onCancelCoverage.bind(null, value, index),
label: gettext('Cancel coverage'),
icon: 'icon-close-small',
callback: () => {
planningApis.coverages.cancelCoverage(this.props.coverages, value)
.then((nextCoverages) => {
this.props.onChange(field, nextCoverages);
});
},
});
}

Expand Down Expand Up @@ -289,7 +301,6 @@ export class CoverageEditor extends React.PureComponent<IProps> {
desks={desks}
coverageProviders={coverageProviders}
priorities={priorities}
onCancelCoverage={onCancelCoverage}
includeScheduledUpdates={includeScheduledUpdates}
{...props}
/>
Expand Down
24 changes: 5 additions & 19 deletions client/components/Coverages/ScheduledUpdate/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,13 @@ interface IProps {
onScheduleChanged(field: string, value: moment.Moment | undefined, coverage: ICoverageScheduledUpdate): void;
onOpen?(coverage: ICoverageScheduledUpdate): void;
onClose?(coverage: ICoverageScheduledUpdate): void;
onCancelScheduledUpdate?(): void;
onAddScheduledUpdateToWorkflow(
coverage: IPlanningCoverageItem,
coverageIndex: number,
scheduledUpdate: ICoverageScheduledUpdate,
scheduledIndex: number
): void;
onCancelCoverage(
coverage: IPlanningCoverageItem,
coverageIndex: number,
scheduledUpdate: ICoverageScheduledUpdate,
scheduledIndex: number
): void;
}

export class ScheduledUpdate extends React.PureComponent<IProps> {
Expand All @@ -85,21 +80,11 @@ export class ScheduledUpdate extends React.PureComponent<IProps> {
constructor(props: IProps) {
super(props);

this.cancelCoverage = this.cancelCoverage.bind(this);
this.addScheduledUpdateToWorkflow = this.addScheduledUpdateToWorkflow.bind(this);
this.onOpen = this.onOpen.bind(this);
this.onClose = this.onClose.bind(this);
}

cancelCoverage() {
this.props.onCancelCoverage(
this.props.diff,
this.props.coverageIndex,
this.props.value,
this.props.index
);
}

addScheduledUpdateToWorkflow() {
this.props.onAddScheduledUpdateToWorkflow(
this.props.diff,
Expand Down Expand Up @@ -151,7 +136,6 @@ export class ScheduledUpdate extends React.PureComponent<IProps> {
onClose,
message,
onAddScheduledUpdateToWorkflow,
onCancelCoverage,
testId,
...props
} = this.props;
Expand All @@ -163,9 +147,11 @@ export class ScheduledUpdate extends React.PureComponent<IProps> {
// To be done in the next iteration
if (planningUtils.canCancelCoverage(value, planning, 'scheduled_update_id')) {
itemActions.push({
...COVERAGES.ITEM_ACTIONS.CANCEL_COVERAGE,
label: gettext('Cancel Scheduled Update'),
callback: this.cancelCoverage,
icon: 'icon-close-small',
callback: () => {
this.props.onCancelScheduledUpdate();
},
});
}

Expand Down
8 changes: 0 additions & 8 deletions client/components/ItemActionConfirmation/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,6 @@ export class ItemActionConfirmationModal extends React.Component {
},
form: CancelPlanningCoveragesForm,
},
[COVERAGES.ITEM_ACTIONS.CANCEL_COVERAGE.actionName]: {
title: modalProps.scheduledUpdate ?
gettext('Cancel Scheduled Update') :
COVERAGES.ITEM_ACTIONS.CANCEL_COVERAGE.label,
saveText: modalProps.scheduledUpdate ? gettext('Cancel Scheduled Update') :
gettext('Cancel Coverage'),
form: CancelCoverageForm,
},
[ASSIGNMENTS.ITEM_ACTIONS.REASSIGN.actionName]: {
title: ASSIGNMENTS.ITEM_ACTIONS.REASSIGN.label,
form: UpdateAssignmentForm,
Expand Down
14 changes: 0 additions & 14 deletions client/components/Main/ItemEditor/ItemManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ export class ItemManager {
this.addCoverageToWorkflow = this.addCoverageToWorkflow.bind(this);
this.addScheduledUpdateToWorkflow = this.addScheduledUpdateToWorkflow.bind(this);
this.removeAssignment = this.removeAssignment.bind(this);
this.cancelCoverage = this.cancelCoverage.bind(this);
this.finaliseCancelCoverage = this.finaliseCancelCoverage.bind(this);
this.setStateForPartialSave = this.setStateForPartialSave.bind(this);

this.editorApi = planningApi.editor(this.props.inModalView ? EDITOR_TYPE.POPUP : EDITOR_TYPE.INLINE);
Expand Down Expand Up @@ -899,18 +897,6 @@ export class ItemManager {
.then((updates) => this.finalisePartialSave(this.getCoverageAfterPartialSave(updates, index)));
}

cancelCoverage(planning, coverage, index, scheduledUpdate, scheduledUpdateIndex) {
return this.dispatch<any>(actions.planning.ui.openCancelCoverageModal(planning,
coverage, index, this.finaliseCancelCoverage, this.setStateForPartialSave,
scheduledUpdate, scheduledUpdateIndex));
}

finaliseCancelCoverage(planning, updatedCoverage, index, scheduledUpdate, scheduledUpdateIndex) {
return this.dispatch<any>(actions.planning.ui.cancelCoverage(planning, updatedCoverage, index,
scheduledUpdate, scheduledUpdateIndex)).then((updates) =>
this.finalisePartialSave(this.getCoverageAfterPartialSave(updates, index)));
}

getCoverageAfterPartialSave(updates, index) {
return {
_etag: updates._etag,
Expand Down
Loading

0 comments on commit 9a6946c

Please sign in to comment.