diff --git a/src/controllers/ReviewController.ts b/src/controllers/ReviewController.ts index bd6e5ff..a9a981c 100644 --- a/src/controllers/ReviewController.ts +++ b/src/controllers/ReviewController.ts @@ -68,21 +68,36 @@ export class ReviewController { return Object.prototype.hasOwnProperty.call(obj, 'persistentID'); } - // ... (rest of the code) if (errors.length > 0) { - console.log('Validation Errors: ', errors); - res.status(500).send( - errors.map((error: ValidationError) => { - let persistentID = 'missing id'; - if (error.target && typeof error.target === 'object' && hasPersistentID(error.target)) { - persistentID = error.target.persistentID; - } - return { - persistentID: persistentID, - constraints: error.constraints, - }; - }), + const processed_errors = errors.map((error: ValidationError) => { + let persistentID = 'missing id'; + if (error.target && typeof error.target === 'object' && hasPersistentID(error.target)) { + persistentID = error.target.persistentID; + } + const richConstraints = {}; + if (error.constraints) { + Object.entries(error.constraints).forEach(([key, message]) => { + const context = error.contexts ? error.contexts[key] : undefined; + const severity = context?.severity || 'error'; + richConstraints[key] = { + message: message, + severity: severity + }; + }); + } + return { + persistentID: persistentID, + property: error.property, + constraints: richConstraints, + }; + }); + console.log('Validation Errors: ', processed_errors); + return res.status(500).render('pages/review', + { + title: "Review Dashboard", + errors: processed_errors, + } ); } else { res.status(200).send(`successfully saved ${saves} entries`); diff --git a/src/db/entities/SLCItemCatalog.ts b/src/db/entities/SLCItemCatalog.ts index 1e207e6..dc01f3e 100644 --- a/src/db/entities/SLCItemCatalog.ts +++ b/src/db/entities/SLCItemCatalog.ts @@ -29,7 +29,7 @@ export class slc_item_catalog extends BaseEntity implements CatalogInterface { @IsNotEmpty() @IsString() @IsUrl() - @Reachable() + @Reachable({ context: { severity: 'warn'} }) iframe_url!: string; @Column() diff --git a/src/views/pages/review-dashboard.ejs b/src/views/pages/review-dashboard.ejs deleted file mode 100644 index 5a0fb36..0000000 --- a/src/views/pages/review-dashboard.ejs +++ /dev/null @@ -1,230 +0,0 @@ - - -<%- include('../partials/head') -%> -<%- include('../partials/header') -%> -
-Total Submissions: <%= totalSubmissions %>
-Successful Verifications: <%= successfulVerifications %>
-Submissions with Issues: <%= issues.length %>
-Total Categorized Items: <%= categorizationResults.length %>
-URLs Checked: <%= urlsChecked %>
-Successful URLs: <%= successfulUrls %>
-Unsuccessful URLs: <%= unsuccessfulUrls %>
-Matched Class: <%= result.matchedClass %>
-Status: <%= result.status %>
-Validation Errors:
-Recommendations:
-Resources:
- - - - -No issues found!
- <% } %> - <% if (validationResults && validationResults.length > 0) { %> -| Exercise Name | -URL | -Metadata Issues | -URL Valid | -iFrame URL | -Categorization (keywords) | -LTI Launchable | -
|---|---|---|---|---|---|---|
| <%= result.user %> | -<%= result.item.url %> | -
- <% if (result.metadataIssues === 'no issues') { %>
- Success - <% } else if (result.metadataIssues) { %> -failure <%= result.metadataIssues %> - <% } else { %> - Pending - <% } %> - |
-
- <% if (result.isUrlValid === true) { %>
- Success - <% } else if (result.isUrlValid === false) { %> -failure - <% } else { %> - N/A - <% } %> - |
- <% const iframeMessage = result.iframeValidation?.message; %>
-
- <% if (iframeMessage === 'Iframe validation failed' || iframeMessage == null) { %>
- Failure - <% } else { %> -Success - <% } %> - |
-
- <% if (result.categorizationResults?.startsWith('Success')) { %>
- Success - <% } else if (result.categorizationResults) { %> -failure -Categorization failed: No matching ontology class for keywords - <% } else { %> -failure -Categorization failed: No matching ontology class for keywords - <% } %> - |
- - <% if (result.ltiValidationStatus === 'Launchable') { %> - Launchable - <% } else if (result.ltiValidationStatus === 'Not Launchable' || result.ltiValidationStatus === 'Validation Failed') { %> - <%= result.ltiValidationStatus %> - <% } else { %> - N/A - <% } %> - | -
No validation results available yet.
- <% } %> - - - - - - <%- include('../partials/footer') -%> - - - diff --git a/src/views/pages/review.ejs b/src/views/pages/review.ejs new file mode 100644 index 0000000..ce9c621 --- /dev/null +++ b/src/views/pages/review.ejs @@ -0,0 +1,30 @@ + + +<%- include('../partials/head') -%> +<%- include('../partials/header') -%> + + +Persistent ID: <%= item.persistentID %>
+Property: <%= item.property %>
+ <% for (const constraint in item.constraints) {%> + <% + const message = item.constraints[constraint].message; + const color = (item.constraints[constraint].severity === 'warn') ? 'orange' : 'red'; + %> ++ <%= constraint %> - <%= message %> +
+ <% } %> +