|
11 | 11 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513 |
12 | 12 | ********************************************************************************/ |
13 | 13 |
|
14 | | -import { useContext, useEffect, useState } from "react"; |
| 14 | +import { useContext, useMemo } from "react"; |
15 | 15 | import ediTDorContext from "../../../context/ediTDorContext"; |
16 | 16 | import { ImCheckmark, ImCross } from "react-icons/im"; |
17 | 17 | import { RotateCcw, RotateCw } from "react-feather"; |
18 | 18 | import BaseButton from "../base/BaseButton"; |
19 | 19 |
|
20 | | -type ValidationState = "passed" | "failed" | undefined; |
| 20 | +type ValidationState = "warning" | "passed" | "failed" | null; |
21 | 21 |
|
22 | 22 | type ValidationViewProps = { |
23 | 23 | onUndo: () => void; |
24 | 24 | onRedo: () => void; |
25 | 25 | }; |
26 | 26 |
|
| 27 | +const GLOBAL_ERROR_PARSING_JSON = |
| 28 | + "JSON validation failed: Parsed object is not valid JSON."; |
| 29 | +const DEFAULT_ERROR_SCHEMA = |
| 30 | + "JSON Schema validation failed: Unknown schema validation error."; |
| 31 | + |
27 | 32 | const ValidationView: React.FC<ValidationViewProps> = ({ |
28 | 33 | onUndo: handleUndo, |
29 | 34 | onRedo: handleRedo, |
30 | 35 | }) => { |
31 | 36 | const context = useContext(ediTDorContext); |
32 | 37 |
|
33 | | - const [jsonValidation, setJsonValidation] = |
34 | | - useState<ValidationState>(undefined); |
35 | | - const [jsonValidationError, setJsonValidationError] = useState< |
36 | | - string | null | undefined |
37 | | - >(undefined); |
38 | | - |
39 | | - const [jsonSchemaValidation, setJsonSchemaValidation] = |
40 | | - useState<ValidationState>(undefined); |
41 | | - const [jsonSchemaValidationError, setJsonSchemaValidationError] = useState< |
42 | | - string | null | undefined |
43 | | - >(undefined); |
44 | | - |
45 | | - useEffect(() => { |
46 | | - const validationMessage = context.validationMessage; |
47 | | - if (!validationMessage) { |
48 | | - return; |
| 38 | + // Object json errors |
| 39 | + const jsonValidation = useMemo<ValidationState>(() => { |
| 40 | + let r: ValidationState = null; |
| 41 | + try { |
| 42 | + r = |
| 43 | + context.validationMessage.report.json === "passed" || |
| 44 | + context.validationMessage.report.json === "warning" || |
| 45 | + context.validationMessage.report.jsonld === "passed" || |
| 46 | + context.validationMessage.report.jsonld === "warning" |
| 47 | + ? "passed" |
| 48 | + : "failed"; |
| 49 | + } catch (e) { |
| 50 | + return "failed"; |
49 | 51 | } |
50 | | - |
51 | | - if (validationMessage.report) { |
52 | | - setJsonValidation(validationMessage.report.json); |
53 | | - setJsonSchemaValidation(validationMessage.report.schema); |
| 52 | + return r; |
| 53 | + }, [context]); |
| 54 | + |
| 55 | + // Schenas validation |
| 56 | + const jsonSchemaValidation: ValidationState = useMemo<ValidationState>(() => { |
| 57 | + let s: ValidationState = null; |
| 58 | + try { |
| 59 | + s = context.validationMessage.report.schema; |
| 60 | + } catch (e) { |
| 61 | + return "failed"; |
54 | 62 | } |
55 | | - |
56 | | - if (!validationMessage.validationErrors) { |
57 | | - setJsonValidationError(undefined); |
58 | | - setJsonSchemaValidationError(undefined); |
59 | | - return; |
| 63 | + return s; |
| 64 | + }, [context]); |
| 65 | + |
| 66 | + // Additional report validation |
| 67 | + const reportValidation = useMemo< |
| 68 | + (keyof typeof context.validationMessage.details)[] |
| 69 | + >(() => { |
| 70 | + try { |
| 71 | + if (typeof context.validationMessage.details != "object") { |
| 72 | + return []; |
| 73 | + } |
| 74 | + const details = context.validationMessage.details; |
| 75 | + |
| 76 | + return (Object.keys(details) as (keyof typeof details)[]).filter( |
| 77 | + (key) => details[key] === "failed" |
| 78 | + ); |
| 79 | + } catch (e) { |
| 80 | + return []; |
60 | 81 | } |
| 82 | + }, [context]); |
61 | 83 |
|
62 | | - if (validationMessage.validationErrors) { |
63 | | - setJsonValidationError(validationMessage.validationErrors.json); |
64 | | - setJsonSchemaValidationError(validationMessage.validationErrors.schema); |
65 | | - |
66 | | - console.debug( |
67 | | - "JSON validation error", |
68 | | - validationMessage.validationErrors.json |
69 | | - ); |
70 | | - console.debug( |
71 | | - "JSON Schema validation error", |
72 | | - validationMessage.validationErrors.schema |
73 | | - ); |
| 84 | + const reportValidationError = useMemo<string[]>(() => { |
| 85 | + if (reportValidation.length === 0) { |
| 86 | + return []; |
| 87 | + } |
| 88 | + try { |
| 89 | + const comments = context.validationMessage.detailComments; |
| 90 | + return reportValidation |
| 91 | + .map((key) => comments[key]) |
| 92 | + .filter((v): v is string => typeof v === "string"); |
| 93 | + } catch (e) { |
| 94 | + return []; |
74 | 95 | } |
75 | | - }, [context, jsonValidationError, jsonSchemaValidationError]); |
| 96 | + }, [reportValidation]); |
76 | 97 |
|
77 | 98 | return ( |
78 | 99 | <> |
@@ -100,38 +121,57 @@ const ValidationView: React.FC<ValidationViewProps> = ({ |
100 | 121 | <div className="mb-4 w-full rounded-md bg-gray-600 p-4 text-white"> |
101 | 122 | <div className="flex items-center"> |
102 | 123 | <h2 className="mr-2">JSON Validation</h2> |
103 | | - {jsonValidation === "passed" && <ImCheckmark />} |
104 | | - {jsonValidation === "failed" && <ImCross />} |
| 124 | + {jsonValidation === "passed" && <ImCheckmark color="#32CD32" />} |
| 125 | + {jsonValidation === "failed" && <ImCross color="Red" />} |
105 | 126 | </div> |
106 | 127 |
|
107 | | - {jsonValidationError && ( |
| 128 | + {jsonValidation === "failed" && ( |
108 | 129 | <div className="bg-formRed border-formRed mb-4 mt-2 flex min-h-[2.5rem] w-full rounded-md border-2 bg-opacity-75 px-4"> |
109 | 130 | <div className="flex h-6 w-16 justify-center self-center rounded-md bg-white"> |
110 | | - <div className="text-formRed place-self-center px-4 text-center text-xs"> |
| 131 | + <div className="place-self-center px-4 text-center text-xs text-black"> |
111 | 132 | Error |
112 | 133 | </div> |
113 | 134 | </div> |
114 | 135 | <div className="place-self-center overflow-hidden pl-3 text-base"> |
115 | | - {jsonValidationError} |
| 136 | + {context.validationMessage?.validationErrors?.json ?? |
| 137 | + GLOBAL_ERROR_PARSING_JSON} |
116 | 138 | </div> |
117 | 139 | </div> |
118 | 140 | )} |
119 | 141 |
|
120 | 142 | <div className="flex items-center"> |
121 | 143 | <h2 className="mr-2">JSON Schema Validation </h2> |
122 | | - {jsonSchemaValidation === "passed" && <ImCheckmark />} |
123 | | - {jsonSchemaValidation === "failed" && <ImCross />} |
| 144 | + {jsonSchemaValidation === "passed" && <ImCheckmark color="#32CD32" />} |
| 145 | + {jsonSchemaValidation === "failed" && <ImCross color="Red" />} |
124 | 146 | </div> |
125 | 147 |
|
126 | | - {jsonSchemaValidationError && ( |
| 148 | + {jsonSchemaValidation === "failed" && ( |
| 149 | + <div className="bg-formRed border-formRed mt-2 flex min-h-[2.5rem] w-full rounded-md border-2 bg-opacity-75 px-4"> |
| 150 | + <div className="flex h-6 w-16 justify-center self-center rounded-md bg-white"> |
| 151 | + <div className="place-self-center px-4 text-center text-xs text-black"> |
| 152 | + Error |
| 153 | + </div> |
| 154 | + </div> |
| 155 | + <div className="place-self-center overflow-hidden pl-3 text-base"> |
| 156 | + {context.validationMessage?.validationErrors?.schema ?? |
| 157 | + DEFAULT_ERROR_SCHEMA} |
| 158 | + </div> |
| 159 | + </div> |
| 160 | + )} |
| 161 | + <div className="flex items-center"> |
| 162 | + <h2 className="mr-2">Additional Checks </h2> |
| 163 | + {reportValidation.length === 0 && <ImCheckmark color="#32CD32" />} |
| 164 | + {reportValidation.length > 0 && <ImCross color="Red" />} |
| 165 | + </div> |
| 166 | + {reportValidationError && reportValidationError.length > 0 && ( |
127 | 167 | <div className="bg-formRed border-formRed mt-2 flex min-h-[2.5rem] w-full rounded-md border-2 bg-opacity-75 px-4"> |
128 | 168 | <div className="flex h-6 w-16 justify-center self-center rounded-md bg-white"> |
129 | | - <div className="text-formRed place-self-center px-4 text-center text-xs"> |
| 169 | + <div className="place-self-center px-4 text-center text-xs text-black"> |
130 | 170 | Error |
131 | 171 | </div> |
132 | 172 | </div> |
133 | 173 | <div className="place-self-center overflow-hidden pl-3 text-base"> |
134 | | - {jsonSchemaValidationError} |
| 174 | + {reportValidationError.join(", ")} |
135 | 175 | </div> |
136 | 176 | </div> |
137 | 177 | )} |
|
0 commit comments