diff --git a/src/client/components/document-management-components.js b/src/client/components/document-management-components.js index 5ed9a545..a1b427a4 100644 --- a/src/client/components/document-management-components.js +++ b/src/client/components/document-management-components.js @@ -19,8 +19,11 @@ import { const DOCUMENT_STATUS_FIELDS = Document.statusFields(); -const hasIssues = doc => _.values( doc.issues() ).some( i => !_.isNull( i ) ); -const hasIssue = ( doc, key ) => _.has( doc.issues(), key ) && !_.isNull( _.get( doc.issues(), key ) ); +const issuesPresent = e => _.values( e.issues() ).some( i => !_.isNull( i ) ); +const hasEntityIssues = doc => doc.entities().some( issuesPresent ); +const hasDocIssues = doc => issuesPresent( doc ); +const hasIssues = doc => hasEntityIssues( doc ) || hasDocIssues( doc ); +const hasIssue = ( e, key ) => _.has( e.issues(), key ) && !_.isNull( _.get( e.issues(), key ) ); /** * sendMail @@ -315,20 +318,9 @@ class DocumentManagementDocumentComponent extends React.Component { // Document Header & Footer const getDocumentHeader = doc => { return h( 'div.document-management-document-section.meta', [ - h( 'div.document-management-document-section-items', [ - h( 'div', [ - h( 'i.material-icons.hide-by-default.invalid', { - className: makeClassList({ 'show': hasIssues( doc ) }) - }, 'warning' ), - // h( 'i.material-icons.hide-by-default.complete', { - // className: makeClassList({ 'show': doc.submitted() || doc.isPublic() }) - // }, 'check_circle' ), - h( 'i.material-icons.hide-by-default.mute', { - className: makeClassList({ 'show': doc.trashed() }) - }, 'delete' ) - ]), - - ]) + h( 'i.material-icons.hide-by-default.invalid', { + className: makeClassList({ 'show': hasIssues( doc ) }) + }, 'warning' ) ]); }; @@ -362,9 +354,7 @@ class DocumentManagementDocumentComponent extends React.Component { if( hasIssue( doc, 'paperId' ) ){ const { paperId: paperIdIssue } = doc.issues(); - const err = h( 'div', { - className: makeClassList({ 'issue': true }) - }, `${paperIdIssue.error.name}: ${paperIdIssue.message}` ); + const err = h( 'div', `${paperIdIssue.error.name}: ${paperIdIssue.message}` ); items.push( err ); } @@ -401,6 +391,34 @@ class DocumentManagementDocumentComponent extends React.Component { ]); }; + // Entities + const getEntityInfo = doc => { + const numEntities = doc.entities().length; + let items = [ h('div', { key: 'total' }, `Total: ${numEntities}`)]; + const mixedOrganisms = doc.organisms().length > 1; + const hasIssue = hasEntityIssues( doc ); + const hasWarning = mixedOrganisms; // orphaned nodes + + if( hasIssue ){ + const issues = doc.entities().filter( issuesPresent ).map( e => e.issues() ); + const errors = _.flatten( issues ).map( i => i.error.name ); + const errorTypes = _.toPairs( _.countBy( errors ) ).map( ([ error, count ], key) => h('div', { key }, `${error}: ${count}`) ); + items.push( errorTypes ); + } + if( hasWarning ){ + if( mixedOrganisms ) items.push( h('div', { key: 'organism' }, 'Mixed organisms' ) ); + } + + return h( 'div.document-management-document-section', [ + h( 'div.document-management-document-section-label', { + className: makeClassList({'issue': hasIssue, 'warning': hasWarning}) + },[ + h( 'div.document-management-document-section-label-text', 'Entities') + ]), + h( 'div.document-management-document-section-items', items ) + ]); + }; + // Correspondence const getVerified = doc => { let radios = []; @@ -477,7 +495,7 @@ class DocumentManagementDocumentComponent extends React.Component { return h( 'div.document-management-document-section', [ h( 'div.document-management-document-section-label', { className: makeClassList({ 'issue': hasIssue( doc, 'authorEmail' ) }) - }, 'Correspondence:' ), + }, 'Correspondence' ), content ]); }; @@ -540,6 +558,7 @@ class DocumentManagementDocumentComponent extends React.Component { getDocumentHeader( doc ), getDocumentArticle( doc ), getDocumentInfo( doc ), + getEntityInfo( doc ), getDocumentCorrespondence( doc ), getDocumentStats( doc ) ]); diff --git a/src/model/element/complex.js b/src/model/element/complex.js index 0952fd99..1d78605c 100644 --- a/src/model/element/complex.js +++ b/src/model/element/complex.js @@ -92,6 +92,10 @@ class Complex extends Entity { return this.remove( ele, opts ); } + normalized(){ + return true; + } + json(){ return _.assign( {}, super.json(), _.pick( this.syncher.get(), _.keys(DEFAULTS) ) ); } diff --git a/src/model/element/entity.js b/src/model/element/entity.js index e91ae3c1..c9aac31d 100644 --- a/src/model/element/entity.js +++ b/src/model/element/entity.js @@ -165,6 +165,25 @@ class Entity extends Element { return update; } + normalized(){ + // normalized := has a name and is associated + const name = this.name(); + return name && this.associated() && this.completed(); + } + + issues(){ + const items = []; + if( !this.normalized() ){ + items.push({ + error: { + name: 'Normalization' + }, + message: `Entity with name "${this.name()}" is not normalized` + }); + } + return items; + } + organism(){ const assoc = this.association(); diff --git a/src/styles/document-management.css b/src/styles/document-management.css index cd0ad59d..fb706c84 100644 --- a/src/styles/document-management.css +++ b/src/styles/document-management.css @@ -29,6 +29,10 @@ & .issue { color: var(--invalidColor); } + + & .warning { + color: var(--brandColorDark); + } } .document-management-hidden {