superdesk/superdesk-client-core

View on GitHub
scripts/apps/search/controllers/get-bulk-actions.tsx

Summary

Maintainability
F
4 days
Test Coverage
import {IArticle} from 'superdesk-api';
import {sdApi} from 'api';
import {dispatchInternalEvent} from 'core/internal-events';
import ng from 'core/services/ng';
import {getArticleLabel, gettext} from 'core/utils';
import {canPrintPreview} from '../helpers';
import {ITEM_STATE} from 'apps/archive/constants';
import {IMultiActions} from './get-multi-actions';
import {IArticleActionBulkExtended} from 'apps/monitoring/MultiActionBarReact';
import {isOpenItemType} from '../directives/MultiActionBar';
import {showModal} from '@superdesk/common';
import {getModalForMultipleHighlights} from 'apps/highlights/components/SetHighlightsForMultipleArticlesModal';
import {dataApi} from 'core/helpers/CrudManager';
import {appConfig, authoringReactViewEnabled} from 'appConfig';
import {previewItems} from 'apps/authoring/preview/fullPreviewMultiple';
import React from 'react';
import {MultiEditModal} from 'apps/authoring-react/multi-edit-modal';
import {Modal} from 'superdesk-ui-framework/react';

export function getBulkActions(
    articles: Array<IArticle>,
    multiActions: IMultiActions,
    getSelectedItems: () => Array<IArticle>,
    unselectAll: () => void,
    scopeApply: () => void,
): Array<IArticleActionBulkExtended> {
    const actions: Array<IArticleActionBulkExtended> = [];
    const desks = ng.get('desks');
    const privileges = ng.get('privileges');

    const {isLockedInCurrentSession, isLocked, isLockedByOtherUser, isPublished, isEditable} = sdApi.article;

    const noneLocked = articles.every((article) => !isLocked(article));
    const nonePublished = articles.every((article) => !isPublished(article));
    const allAreEditable = articles.every((article) => isEditable(article));

    if (articles.every(({state}) => state === ITEM_STATE.INGESTED)) {
        actions.push({
            label: gettext('Fetch'),
            icon: 'icon-archive',
            onTrigger: () => {
                multiActions.fetch();
                scopeApply?.();
            },
            canAutocloseMultiActionBar: false,
        });
        actions.push({
            label: gettext('Fetch to'),
            icon: 'icon-fetch-as',
            onTrigger: () => {
                multiActions.fetch(true);
                scopeApply?.();
            },
            canAutocloseMultiActionBar: false,
        });

        if (multiActions.canRemoveIngestItems()) {
            actions.push({
                label: gettext('Remove'),
                icon: 'icon-trash',
                onTrigger: () => {
                    multiActions.removeIngestItems();
                    scopeApply?.();
                },
                canAutocloseMultiActionBar: false,
            });
        }
    } else if (articles.every(({_type}) => _type === 'externalsource')) {
        actions.push({
            label: gettext('Fetch'),
            icon: 'icon-archive',
            onTrigger: () => {
                multiActions.fetch();
                scopeApply?.();
            },
            canAutocloseMultiActionBar: false,
        }, {
            label: gettext('Fetch to'),
            icon: 'icon-fetch-as',
            onTrigger: () => {
                multiActions.fetch(true);
                scopeApply?.();
            },
            canAutocloseMultiActionBar: false,
        });
    } else if (noneLocked && articles.every((article) => article.state === ITEM_STATE.SPIKED)) {
        if (privileges.userHasPrivileges({unspike: 1})) {
            actions.push({
                label: gettext('Unspike'),
                icon: 'icon-unspike',
                onTrigger: () => {
                    multiActions.unspikeItems();
                    scopeApply?.();
                },
                canAutocloseMultiActionBar: false,
            });
        }
    } else {
        if (noneLocked && multiActions.canEditMetadata()) {
            actions.push({
                label: gettext('Edit metadata'),
                icon: 'icon-edit-line',
                onTrigger: () => {
                    multiActions.multiImageEdit();
                    scopeApply?.();
                },
                canAutocloseMultiActionBar: false,
            });
        }

        if (articles.every((article) => !isLockedByOtherUser(article))) {
            actions.push({
                label: gettext('Export'),
                icon: 'icon-download',
                onTrigger: () => {
                    dispatchInternalEvent('openExportView', getSelectedItems().map(({_id}) => _id));
                },
                canAutocloseMultiActionBar: false,
            });
        }

        if (allAreEditable) {
            actions.push({
                label: gettext('Multi-edit'),
                icon: 'icon-multiedit',
                onTrigger: () => {
                    if (authoringReactViewEnabled) {
                        Promise.all(getSelectedItems().map((article) => {
                            if (isLockedInCurrentSession(article)) {
                                /**
                                 * using article doesn't work because it is missing properties
                                 * (at least slugline)
                                 */
                                return sdApi.article.get(article._id);
                            } else {
                                return sdApi.article.lock(article._id);
                            }
                        })).then((articlesLocked) => {
                            showModal(({closeModal}) => (
                                <MultiEditModal
                                    initiallySelectedArticles={articlesLocked}
                                    onClose={closeModal}
                                />
                            ));
                        });
                    } else {
                        multiActions.multiedit();
                        scopeApply?.();
                    }
                },
                canAutocloseMultiActionBar: false,
            });
        } else {
            const modalHeadline = gettext('You can\'t multi-edit, because these articles can\'t be edited');

            actions.push({
                label: gettext('Multi-edit'),
                icon: 'icon-multiedit',
                onTrigger: () => {
                    showModal(({closeModal}) => (
                        <Modal
                            zIndex={1050}
                            size="medium"
                            visible
                            onHide={closeModal}
                            headerTemplate={modalHeadline}
                        >
                            {
                                getSelectedItems().filter((article) => {
                                    return !isEditable(article);
                                }).map((item) => (
                                    <div key={item._id}>{getArticleLabel(item)}</div>
                                ))
                            }
                        </Modal>
                    ));
                },
                canAutocloseMultiActionBar: false,
            });
        }

        if (
            articles.every((article) =>
                !isLockedByOtherUser(article)
                && article.state !== ITEM_STATE.SPIKED
                && !isPublished(article),
            )
        ) {
            actions.push({
                label: gettext('Spike'),
                icon: 'icon-trash',
                onTrigger: () => {
                    multiActions.spikeItems();
                    scopeApply?.();
                },
                canAutocloseMultiActionBar: false,
            });
        }

        if (noneLocked && nonePublished) {
            actions.push({
                label: gettext('Send to'),
                icon: 'icon-expand-thin',
                onTrigger: () => {
                    multiActions.sendTo();
                    scopeApply?.();
                },
                canAutocloseMultiActionBar: false,
            });

            if (multiActions.canPublishItem()) {
                actions.push({
                    label: gettext('Publish'),
                    icon: 'icon-ok',
                    onTrigger: () => {
                        multiActions.publish();
                        scopeApply?.();
                    },
                    canAutocloseMultiActionBar: false,
                });
            }
        }

        if (noneLocked) {
            actions.push({
                label: gettext('Duplicate To'),
                icon: 'icon-copy',
                group: {
                    label: gettext('Duplicate'),
                    icon: 'icon-copy',
                },
                onTrigger: () => {
                    multiActions.duplicateTo();
                    scopeApply?.();
                },
                canAutocloseMultiActionBar: false,
            });

            actions.push({
                label: gettext('Duplicate In Place'),
                icon: 'icon-copy',
                group: {
                    label: gettext('Duplicate'),
                    icon: 'icon-copy',
                },
                onTrigger: () => {
                    multiActions.duplicateInPlace();
                    scopeApply?.();
                },
                canAutocloseMultiActionBar: false,
            });
        }
    }

    if (multiActions.canPackageItems()) {
        if (!appConfig.features.hideCreatePackage) {
            actions.push({
                label: gettext('Create Package'),
                icon: 'icon-package-create',
                onTrigger: () => {
                    multiActions.createPackage();
                    scopeApply?.();
                },
                canAutocloseMultiActionBar: false,
            });

            if (isOpenItemType('composite')) {
                actions.push({
                    label: gettext('Add to Current Package'),
                    icon: 'icon-package-plus',
                    onTrigger: () => {
                        multiActions.addToPackage();
                        scopeApply?.();
                    },
                    canAutocloseMultiActionBar: false,
                });
            }
        }

        const currentDeskId = desks.getCurrentDeskId();

        if (currentDeskId != null && multiActions.canHighlightItems()) {
            actions.push({
                label: gettext('Add to highlight'),
                icon: 'icon-star',
                onTrigger: () => {
                    showModal(getModalForMultipleHighlights(articles, currentDeskId));
                    scopeApply?.();
                },
                canAutocloseMultiActionBar: true,
            });
        }
    }

    if (articles.every((item) => canPrintPreview(item))) {
        actions.push({
            label: gettext('Print'),
            icon: 'icon-print',
            onTrigger: () => {
                const ids: Array<string> = getSelectedItems().map(({_id}) => _id);

                unselectAll();

                // fetching to ensure that the latest saved version is being previewed
                Promise.all(
                    ids.map((id) => dataApi.findOne<IArticle>('archive', id)),
                ).then((res: Array<IArticle>) => {
                    previewItems(res);
                });
            },
            canAutocloseMultiActionBar: false,
        });
    }

    if (articles.some((article) => article?.schedule_settings?.utc_publish_schedule)) {
        actions.push({
            label: gettext('Deschedule'),
            icon: 'icon-calendar',
            onTrigger: () => {
                multiActions.deschedule();
            },
            canAutocloseMultiActionBar: false,
        });
    }

    return actions;
}