UNPKG

decap-cms-core

Version:

Decap CMS core application, see decap-cms package for the main distribution.

178 lines (160 loc) 5.58 kB
import PropTypes from 'prop-types'; import { Component } from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import styled from '@emotion/styled'; import { OrderedMap } from 'immutable'; import { translate } from 'react-polyglot'; import { connect } from 'react-redux'; import { Dropdown, DropdownItem, StyledDropdownButton, Loader, lengths, components, shadows, } from 'decap-cms-ui-default'; import { createNewEntry } from '../../actions/collections'; import { loadUnpublishedEntries, updateUnpublishedEntryStatus, publishUnpublishedEntry, deleteUnpublishedEntry, } from '../../actions/editorialWorkflow'; import { selectCanCreateNewEntry, selectUnpublishedEntriesByStatus } from '../../reducers'; import { EDITORIAL_WORKFLOW, status } from '../../constants/publishModes'; import WorkflowList from './WorkflowList'; const WorkflowContainer = styled.div` height: 100vh; margin: ${lengths.pageMarginMobile}; @media (min-width: 500px) { margin: ${lengths.pageMargin}; } `; const WorkflowTop = styled.div` ${components.cardTop}; `; const WorkflowTopRow = styled.div` display: flex; flex-wrap: wrap; gap: 8px; align-items: center; justify-content: space-between; span[role='button'] { ${shadows.dropDeep}; } `; const WorkflowTopHeading = styled.h1` ${components.cardTopHeading}; `; const WorkflowTopDescription = styled.p` ${components.cardTopDescription}; `; class Workflow extends Component { static propTypes = { collections: ImmutablePropTypes.map.isRequired, creatableCollections: ImmutablePropTypes.list.isRequired, isEditorialWorkflow: PropTypes.bool.isRequired, isOpenAuthoring: PropTypes.bool, isFetching: PropTypes.bool, unpublishedEntries: ImmutablePropTypes.map, loadUnpublishedEntries: PropTypes.func.isRequired, updateUnpublishedEntryStatus: PropTypes.func.isRequired, publishUnpublishedEntry: PropTypes.func.isRequired, deleteUnpublishedEntry: PropTypes.func.isRequired, t: PropTypes.func.isRequired, }; componentDidMount() { // Manually validate PropTypes - React 19 breaking change PropTypes.checkPropTypes(Workflow.propTypes, this.props, 'prop', 'Workflow'); const { loadUnpublishedEntries, isEditorialWorkflow, collections } = this.props; if (isEditorialWorkflow) { loadUnpublishedEntries(collections); } } render() { const { isEditorialWorkflow, isOpenAuthoring, isFetching, unpublishedEntries, updateUnpublishedEntryStatus, publishUnpublishedEntry, deleteUnpublishedEntry, collections, creatableCollections, t, } = this.props; if (!isEditorialWorkflow) return null; if (isFetching) return <Loader active>{t('workflow.workflow.loading')}</Loader>; const reviewCount = unpublishedEntries.get('pending_review').size; const readyCount = unpublishedEntries.get('pending_publish').size; return ( <WorkflowContainer> <WorkflowTop> <WorkflowTopRow> <WorkflowTopHeading>{t('workflow.workflow.workflowHeading')}</WorkflowTopHeading> <Dropdown dropdownWidth="160px" dropdownPosition="left" dropdownTopOverlap="40px" renderButton={() => ( <StyledDropdownButton>{t('workflow.workflow.newPost')}</StyledDropdownButton> )} > {creatableCollections.map(collection => ( <DropdownItem key={collection.get('name')} label={collection.get('label')} onClick={() => createNewEntry(collection.get('name'))} /> ))} </Dropdown> </WorkflowTopRow> <WorkflowTopDescription> {t('workflow.workflow.description', { smart_count: reviewCount, readyCount, })} </WorkflowTopDescription> </WorkflowTop> <WorkflowList entries={unpublishedEntries} handleChangeStatus={updateUnpublishedEntryStatus} handlePublish={publishUnpublishedEntry} handleDelete={deleteUnpublishedEntry} isOpenAuthoring={isOpenAuthoring} collections={collections} /> </WorkflowContainer> ); } } function mapStateToProps(state) { const { collections, config, globalUI } = state; const isEditorialWorkflow = config.publish_mode === EDITORIAL_WORKFLOW; const isOpenAuthoring = globalUI.useOpenAuthoring; const creatableCollections = collections .filter(collection => selectCanCreateNewEntry(state, collection.get('name'))) .toList(); const returnObj = { collections, creatableCollections, isEditorialWorkflow, isOpenAuthoring }; if (isEditorialWorkflow) { returnObj.isFetching = state.editorialWorkflow.getIn(['pages', 'isFetching'], false); /* * Generates an ordered Map of the available status as keys. * Each key containing a Sequence of available unpubhlished entries * Eg.: OrderedMap{'draft':Seq(), 'pending_review':Seq(), 'pending_publish':Seq()} */ returnObj.unpublishedEntries = status.reduce((acc, currStatus) => { const entries = selectUnpublishedEntriesByStatus(state, currStatus); return acc.set(currStatus, entries); }, OrderedMap()); } return returnObj; } export default connect(mapStateToProps, { loadUnpublishedEntries, updateUnpublishedEntryStatus, publishUnpublishedEntry, deleteUnpublishedEntry, })(translate()(Workflow));