From 8c339c6981dd2434310fc2d59405efcc3619c09c Mon Sep 17 00:00:00 2001 From: Jeffrey Wong Date: Tue, 23 Jul 2024 14:54:58 -0400 Subject: [PATCH 1/5] Remove redundant/nested trashed icon. --- .../document-management-components.js | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/client/components/document-management-components.js b/src/client/components/document-management-components.js index 5ed9a545..17fb25ae 100644 --- a/src/client/components/document-management-components.js +++ b/src/client/components/document-management-components.js @@ -315,20 +315,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' ) ]); }; From dda1d777c643ecb38f3aecaeaef99d1efff125de Mon Sep 17 00:00:00 2001 From: Jeffrey Wong Date: Tue, 23 Jul 2024 17:31:18 -0400 Subject: [PATCH 2/5] Getter for normalization status; Issues report not normalized entity (not complex) --- src/model/element/complex.js | 4 ++++ src/model/element/entity.js | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) 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..e95ebd5d 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.syncher.get('name'); + return name && this.associated(); + } + + 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(); From 419ea143da5e71555db07298145d533f1d9afcea Mon Sep 17 00:00:00 2001 From: Jeffrey Wong Date: Wed, 24 Jul 2024 10:46:36 -0400 Subject: [PATCH 3/5] Define normalized entity as: named and associated and complete. --- src/model/element/entity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model/element/entity.js b/src/model/element/entity.js index e95ebd5d..5c915e61 100644 --- a/src/model/element/entity.js +++ b/src/model/element/entity.js @@ -168,7 +168,7 @@ class Entity extends Element { normalized(){ // normalized := has a name and is associated const name = this.syncher.get('name'); - return name && this.associated(); + return name && this.associated() && this.completed(); } issues(){ From 4d59ce60f061f96ce293b6378a9bf3e405891c99 Mon Sep 17 00:00:00 2001 From: Jeffrey Wong Date: Wed, 24 Jul 2024 10:46:56 -0400 Subject: [PATCH 4/5] Display warnings and errors for entities. --- .../document-management-components.js | 42 ++++++++++++++++--- src/styles/document-management.css | 4 ++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/client/components/document-management-components.js b/src/client/components/document-management-components.js index 17fb25ae..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 @@ -351,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 ); } @@ -390,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 = []; @@ -466,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 ]); }; @@ -529,6 +558,7 @@ class DocumentManagementDocumentComponent extends React.Component { getDocumentHeader( doc ), getDocumentArticle( doc ), getDocumentInfo( doc ), + getEntityInfo( doc ), getDocumentCorrespondence( doc ), getDocumentStats( doc ) ]); 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 { From e93728a4bf684edacf028e96c7161b49b7daaa76 Mon Sep 17 00:00:00 2001 From: Jeffrey Wong Date: Wed, 24 Jul 2024 11:41:08 -0400 Subject: [PATCH 5/5] Use the name getter that already exists. --- src/model/element/entity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model/element/entity.js b/src/model/element/entity.js index 5c915e61..c9aac31d 100644 --- a/src/model/element/entity.js +++ b/src/model/element/entity.js @@ -167,7 +167,7 @@ class Entity extends Element { normalized(){ // normalized := has a name and is associated - const name = this.syncher.get('name'); + const name = this.name(); return name && this.associated() && this.completed(); }