UNPKG

cspace-ui

Version:
253 lines (198 loc) 7.02 kB
import React from 'react'; import PropTypes from 'prop-types'; import { defineMessages, intlShape, FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; import Immutable from 'immutable'; import TitleBar from '../sections/TitleBar'; import { canCreate } from '../../helpers/permissionHelpers'; import { isLocked } from '../../helpers/workflowStateHelpers'; import styles from '../../../styles/cspace-ui/CreatePage.css'; import panelStyles from '../../../styles/cspace-ui/CreatePagePanel.css'; const serviceTypes = ['object', 'procedure', 'authority']; const messages = defineMessages({ title: { id: 'createPage.title', defaultMessage: 'Create New', }, object: { id: 'createPage.object', defaultMessage: 'Objects', }, procedure: { id: 'createPage.procedure', defaultMessage: 'Procedures', }, authority: { id: 'createPage.authority', defaultMessage: 'Authorities', }, }); const getRecordTypesByServiceType = (recordTypes, perms, intl) => { const recordTypesByServiceType = {}; serviceTypes.forEach((serviceType) => { const recordTypeNames = Object.keys(recordTypes) .filter((recordTypeName) => { const recordTypeConfig = recordTypes[recordTypeName]; return ( recordTypeConfig.serviceConfig.serviceType === serviceType && !recordTypeConfig.disabled && canCreate(recordTypeName, perms) ); }) .sort((nameA, nameB) => { const configA = recordTypes[nameA]; const configB = recordTypes[nameB]; // Primary sort by sortOrder let sortOrderA = configA.sortOrder; let sortOrderB = configB.sortOrder; if (typeof sortOrderA !== 'number') { sortOrderA = Number.MAX_VALUE; } if (typeof sortOrderB !== 'number') { sortOrderB = Number.MAX_VALUE; } if (sortOrderA !== sortOrderB) { return (sortOrderA > sortOrderB ? 1 : -1); } // Secondary sort by label const labelA = intl.formatMessage(configA.messages.record.name); const labelB = intl.formatMessage(configB.messages.record.name); // FIXME: This should be locale aware return labelA.localeCompare(labelB); }); recordTypesByServiceType[serviceType] = recordTypeNames; }); return recordTypesByServiceType; }; const getVocabularies = (recordTypeConfig, intl, getAuthorityVocabWorkflowState) => { const recordTypeName = recordTypeConfig.name; const { vocabularies } = recordTypeConfig; let vocabularyNames; if (vocabularies) { vocabularyNames = Object.keys(vocabularies) .filter((vocabularyName) => { // Filter out vocabularies that don't exist in the services layer, vocabularies that are // locked, and vocabularies that are disabled. Always include the 'all' vocabulary. const workflowState = getAuthorityVocabWorkflowState(recordTypeName, vocabularyName); return ( vocabularyName !== 'all' && workflowState && // Empty workflow state means vocab doesn't exist. !isLocked(workflowState) && !vocabularies[vocabularyName].disabled ); }) .sort((nameA, nameB) => { const configA = vocabularies[nameA]; const configB = vocabularies[nameB]; // Primary sort by sortOrder let sortOrderA = configA.sortOrder; let sortOrderB = configB.sortOrder; if (typeof sortOrderA !== 'number') { sortOrderA = Number.MAX_VALUE; } if (typeof sortOrderB !== 'number') { sortOrderB = Number.MAX_VALUE; } if (sortOrderA !== sortOrderB) { return (sortOrderA > sortOrderB ? 1 : -1); } // Secondary sort by label const labelA = intl.formatMessage(configA.messages.name); const labelB = intl.formatMessage(configB.messages.name); // FIXME: This should be locale aware return labelA.localeCompare(labelB); }); } return vocabularyNames; }; const contextTypes = { config: PropTypes.object, }; const propTypes = { intl: intlShape, perms: PropTypes.instanceOf(Immutable.Map), getAuthorityVocabWorkflowState: PropTypes.func, }; const defaultProps = { getAuthorityVocabWorkflowState: () => null, }; export default function CreatePage(props, context) { const { intl, perms, getAuthorityVocabWorkflowState, } = props; const { config, } = context; const { recordTypes, } = config; const itemsByServiceType = {}; const lists = []; if (recordTypes) { const recordTypesByServiceType = getRecordTypesByServiceType(recordTypes, perms, intl); serviceTypes.forEach((serviceType) => { itemsByServiceType[serviceType] = recordTypesByServiceType[serviceType].map((recordType) => { const recordTypeConfig = recordTypes[recordType]; const vocabularies = getVocabularies( recordTypeConfig, intl, getAuthorityVocabWorkflowState ); let vocabularyList; if (vocabularies && vocabularies.length > 0) { const vocabularyItems = vocabularies.map(vocabulary => <li key={vocabulary}> <Link id={`${recordType}/${vocabulary}`} to={`/record/${recordType}/${vocabulary}`}> <FormattedMessage {...recordTypeConfig.vocabularies[vocabulary].messages.name} /> </Link> </li> ); vocabularyList = <ul>{vocabularyItems}</ul>; } if (recordTypeConfig.vocabularies && !vocabularyList) { // The record type is an authority, but no vocabularies are enabled. Don't render // anything. return null; } const recordDisplayName = <FormattedMessage {...recordTypeConfig.messages.record.name} />; let recordLink; if (vocabularyList) { recordLink = <h3 id={recordType}>{recordDisplayName}</h3>; } else { recordLink = <Link id={recordType} to={`/record/${recordType}`}>{recordDisplayName}</Link>; } return ( <li key={recordType}> {recordLink} {vocabularyList} </li> ); }); }); serviceTypes.forEach((serviceType) => { const items = itemsByServiceType[serviceType].filter(item => !!item); if (items && items.length > 0) { lists.push( <div className={panelStyles[serviceType]} key={serviceType}> <h2><FormattedMessage {...messages[serviceType]} /></h2> <ul> {items} </ul> </div> ); } }); } const title = <FormattedMessage {...messages.title} />; return ( <div className={styles.common}> <TitleBar title={title} updateDocumentTitle /> <div> {lists} </div> </div> ); } CreatePage.propTypes = propTypes; CreatePage.defaultProps = defaultProps; CreatePage.contextTypes = contextTypes;