diff --git a/app/components/TaskRow.tsx b/app/components/TaskRow.tsx
index 10d1b5a..db07607 100644
--- a/app/components/TaskRow.tsx
+++ b/app/components/TaskRow.tsx
@@ -142,7 +142,7 @@ const ErrorList = ({ errors }: any) => {
color="error"
/>
@@ -155,7 +155,7 @@ const ErrorList = ({ errors }: any) => {
);
};
-const TaskTableRow = ({ validation }: any) => {
+const TaskTableRow = ({ session, name: taskName, validation }: any) => {
const { name, status, valid, errors } = validation;
const [open, setOpen] = React.useState(false);
@@ -265,7 +265,7 @@ const TaskRow = ({ session, task }: TaskRowProps) => {
- { validations.map(v => ) }
+ { validations.map(v => ) }
diff --git a/app/components/ValidationConfig.tsx b/app/components/ValidationConfig.tsx
index 3800aaf..121f8bb 100644
--- a/app/components/ValidationConfig.tsx
+++ b/app/components/ValidationConfig.tsx
@@ -52,7 +52,7 @@ const ruleOptions = [
label: 'Every stop place is referenced',
},
{
- value: 'everyStopPointHaveAnArrivalAndDepartureTime',
+ value: 'everyStopPointHaveArrivalAndDepartureTime',
label: 'Every stop point have an arrival and departure time',
},
{
@@ -90,14 +90,14 @@ type ValidationConfigProps = {
const ValidationConfig = (props: ValidationConfigProps) => {
const { session, onValidate } = props;
- const [schema, setSchema] = React.useState('netex');
+ const [schema, setSchema] = React.useState('netex@1.2');
const [rules, setRules] = React.useState([
'everyLineIsReferenced',
'everyScheduledStopPointHasAName',
'everyStopPlaceHasACorrectStopPlaceType',
'everyStopPlaceHasAName',
'everyStopPlaceIsReferenced',
- 'everyStopPointHaveAnArrivalAndDepartureTime',
+ 'everyStopPointHaveArrivalAndDepartureTime',
'frameDefaultsHaveALocaleAndTimeZone',
'locationsAreReferencingTheSamePoint',
'passingTimesHaveIncreasingTimes',
@@ -180,6 +180,12 @@ const ValidationConfig = (props: ValidationConfigProps) => {
}
}
+ React.useState(() => {
+ if (session.files.length) {
+ setCanValidate(true);
+ }
+ }, [session, setCanValidate]);
+
return (
@@ -204,9 +210,10 @@ const ValidationConfig = (props: ValidationConfigProps) => {
value={schema}
onChange={handleSelectChange}
>
-
-
-
+
+
+
+
diff --git a/app/components/ValidationResult.tsx b/app/components/ValidationResult.tsx
index 6209c3a..192aba7 100644
--- a/app/components/ValidationResult.tsx
+++ b/app/components/ValidationResult.tsx
@@ -1,5 +1,5 @@
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
-import { Box, Button, ButtonGroup, Grid, Menu, MenuItem, Skeleton, Stack, Typography } from '@mui/material';
+import { Box, Button, ButtonGroup, Divider, Grid, Menu, MenuItem, Skeleton, Stack, Typography } from '@mui/material';
import Link from 'next/link';
import { useRouter } from 'next/router';
import React from 'react';
@@ -32,7 +32,7 @@ type ValidationResultProps = {
const ValidationResult = (props: ValidationResultProps) => {
const { session } = props;
const router = useRouter();
- const message = useSubscription(session ? `progress/${session.id}` : '');
+ const documentStatus = useSubscription(session ? `sessions/${session.id}/documents/+` : '');
const [tasks, setTasks] = React.useState([]);
const { setSession } = useSessionStore();
const [ errorOpen, setErrorOpen ] = React.useState(false);
@@ -41,6 +41,28 @@ const ValidationResult = (props: ValidationResultProps) => {
const [anchorEl, setAnchorEl] = React.useState(null);
const open = Boolean(anchorEl);
+ React.useEffect(() => {
+ if (!documentStatus) {
+ return;
+ }
+
+ const data = documentStatus.d;
+ const taskIndex = tasks.findIndex(t => t.originalName === data.document);
+
+ if (taskIndex === -1) {
+ setTasks([
+ ...tasks,
+ {
+ name: truncName(data.document),
+ originalName: data.document,
+ valid: false,
+ status: documentStatus.t === 'VALIDATE_DOCUMENT_START' ? 'running' : 'complete',
+ validations: [],
+ }
+ ].sort((a: any, b: any) => a.name > b.name ? 1 : -1));
+ }
+ }, [documentStatus]);
+
const handleValidateAnother = () => {
apiClient.createSession()
.then(session => {
@@ -65,47 +87,30 @@ const ValidationResult = (props: ValidationResultProps) => {
};
React.useEffect(() => {
- if (!session) {
+ if (!session || !session.results) {
return;
}
- if (session.status !== 'running') {
- const tasks = session.results.map(v => {
- return {
- name: truncName(v.name),
- originalName: v.name,
+ const tasks = session.results.map(v => {
+ const running = v.validations.find(v => !v.valid && !v.errors);
+
+ return {
+ name: truncName(v.name),
+ originalName: v.name,
+ valid: v.valid,
+ status: running ? 'running' : 'complete',
+ validations: v.validations.map((v: any) => ({
+ name: v.name,
valid: v.valid,
- status: 'complete',
- validations: v.validations.map((v: any) => ({
- name: v.name,
- valid: v.valid,
- errors: v.errors || [],
- })),
- }
- })
- .sort((a, b) => a.name > b.name ? 1 : -1);
-
- setTasks(tasks);
- } else if (message) {
- const tasks = message.map((p: any) => {
- return {
- name: truncName(p.name),
- originalName: p.name,
- valid: p.status === 'valid',
- status: p.status === 'running' ? 'running' : 'complete',
- validations: Object.keys(p.jobStatus).map((k) => ({
- name: k,
- valid: p.jobStatus[k] === 'valid',
- status: p.jobStatus[k],
- errors: [],
- })),
- };
- })
- .sort((a: any, b: any) => a.name > b.name ? 1 : -1)
+ status: running ? 'running' : 'complete',
+ errors: v.errors || [],
+ })),
+ }
+ })
+ .sort((a, b) => a.name > b.name ? 1 : -1);
- setTasks(tasks);
- }
- }, [message, session]);
+ setTasks(tasks);
+ }, [session]);
return (
@@ -135,6 +140,7 @@ const ValidationResult = (props: ValidationResultProps) => {
>
)}
+
diff --git a/app/hooks/useMqttClient.ts b/app/hooks/useMqttClient.ts
index 9a300a2..b46a448 100644
--- a/app/hooks/useMqttClient.ts
+++ b/app/hooks/useMqttClient.ts
@@ -11,8 +11,13 @@ const useMqttClient = () => {
export const useSubscription = (topic: string) => {
const [message, setMessage] = React.useState(null);
+ const pattern = new RegExp(`^${topic.replace(/[+]/g, '[^\\/]+').replace(/[#]/g, '.+')}$`);
const handler = React.useCallback((topic: string, payload: any) => {
+ if (!topic.match(pattern)) {
+ return;
+ }
+
try {
setMessage(JSON.parse(payload.toString()));
} catch (err) {
@@ -21,7 +26,7 @@ export const useSubscription = (topic: string) => {
}, [topic]);
React.useEffect(() => {
- mqttClient.subscribe(topic); // TODO unsubscribe
+ mqttClient.subscribe(topic);
mqttClient.on('message', handler);
return () => {
diff --git a/app/pages/index.tsx b/app/pages/index.tsx
index caedb37..47d0227 100644
--- a/app/pages/index.tsx
+++ b/app/pages/index.tsx
@@ -49,7 +49,7 @@ const Home: NextPage = () => {
return (
- Greenlight | NeTEx validation
+ NeTEx validation | Greenlight