From 51fe217ccb37f2e0a5036a3a37ec9e70772b6468 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Thu, 19 Sep 2024 15:05:25 +0300 Subject: [PATCH 01/35] MWB-798: remove unused code --- .../cypress/e2e/projects/projectSteps.js | 8 +- .../e2e/testDataSuites/testDataSuitesSteps.js | 4 +- .../src/pages/app/detailed-view-cm/index.js | 242 -------------- .../src/pages/app/fields-and-nodes-/index.js | 217 ------------ .../app/fields-and-nodes-mirror/index.js | 90 ----- .../pages/app/fields-and-nodes-plus/index.js | 194 ----------- .../pages/app/fields-overview/[id]/view.js | 147 --------- .../src/pages/app/fields-overview/import.js | 145 -------- .../src/pages/app/fields-overview/index.js | 244 -------------- .../pages/app/fields-registry/[id]/edit.js | 107 ------ .../pages/app/fields-registry/[id]/view.js | 160 --------- .../src/pages/app/fields-registry/create.js | 61 ---- .../app/fields-registry/elements/[id]/view.js | 149 --------- .../app/fields-registry/elements/import.js | 118 ------- .../app/fields-registry/elements/index.js | 168 ---------- .../src/pages/app/fields-registry/index.js | 182 ---------- .../app/fields-registry/tree-view/index.js | 95 ------ .../src/pages/app/ontology-files/index.js | 311 ------------------ .../pages/app/ontology-terms-x/[id]/edit.js | 107 ------ .../pages/app/ontology-terms-x/[id]/view.js | 149 --------- .../src/pages/app/ontology-terms-x/create.js | 59 ---- .../src/pages/app/ontology-terms-x/index.js | 204 ------------ .../frontend/src/pages/app/ontology/index.js | 145 -------- .../src/pages/app/schema-files/index.js | 293 ----------------- .../app/triple-map-fragments-x/[id]/edit.js | 109 ------ .../app/triple-map-fragments-x/[id]/view.js | 154 --------- .../app/triple-map-fragments-x/create.js | 61 ---- .../pages/app/triple-map-fragments-x/index.js | 185 ----------- .../app/triple-map-fragments-xx/[id]/edit.js | 107 ------ .../app/triple-map-fragments-xx/[id]/view.js | 154 --------- .../app/triple-map-fragments-xx/create.js | 59 ---- .../app/triple-map-fragments-xx/index.js | 183 ----------- .../app/ontology-namespace/list-table.js | 7 +- 33 files changed, 9 insertions(+), 4609 deletions(-) delete mode 100644 mapping_workbench/frontend/src/pages/app/detailed-view-cm/index.js delete mode 100644 mapping_workbench/frontend/src/pages/app/fields-and-nodes-/index.js delete mode 100644 mapping_workbench/frontend/src/pages/app/fields-and-nodes-mirror/index.js delete mode 100644 mapping_workbench/frontend/src/pages/app/fields-and-nodes-plus/index.js delete mode 100644 mapping_workbench/frontend/src/pages/app/fields-overview/[id]/view.js delete mode 100644 mapping_workbench/frontend/src/pages/app/fields-overview/import.js delete mode 100644 mapping_workbench/frontend/src/pages/app/fields-overview/index.js delete mode 100644 mapping_workbench/frontend/src/pages/app/fields-registry/[id]/edit.js delete mode 100644 mapping_workbench/frontend/src/pages/app/fields-registry/[id]/view.js delete mode 100644 mapping_workbench/frontend/src/pages/app/fields-registry/create.js delete mode 100644 mapping_workbench/frontend/src/pages/app/fields-registry/elements/[id]/view.js delete mode 100644 mapping_workbench/frontend/src/pages/app/fields-registry/elements/import.js delete mode 100644 mapping_workbench/frontend/src/pages/app/fields-registry/elements/index.js delete mode 100644 mapping_workbench/frontend/src/pages/app/fields-registry/index.js delete mode 100644 mapping_workbench/frontend/src/pages/app/fields-registry/tree-view/index.js delete mode 100644 mapping_workbench/frontend/src/pages/app/ontology-files/index.js delete mode 100644 mapping_workbench/frontend/src/pages/app/ontology-terms-x/[id]/edit.js delete mode 100644 mapping_workbench/frontend/src/pages/app/ontology-terms-x/[id]/view.js delete mode 100644 mapping_workbench/frontend/src/pages/app/ontology-terms-x/create.js delete mode 100644 mapping_workbench/frontend/src/pages/app/ontology-terms-x/index.js delete mode 100644 mapping_workbench/frontend/src/pages/app/ontology/index.js delete mode 100644 mapping_workbench/frontend/src/pages/app/schema-files/index.js delete mode 100644 mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/[id]/edit.js delete mode 100644 mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/[id]/view.js delete mode 100644 mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/create.js delete mode 100644 mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/index.js delete mode 100644 mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/[id]/edit.js delete mode 100644 mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/[id]/view.js delete mode 100644 mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/create.js delete mode 100644 mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/index.js diff --git a/mapping_workbench/frontend/cypress/e2e/projects/projectSteps.js b/mapping_workbench/frontend/cypress/e2e/projects/projectSteps.js index e867e3245..20d5b2941 100644 --- a/mapping_workbench/frontend/cypress/e2e/projects/projectSteps.js +++ b/mapping_workbench/frontend/cypress/e2e/projects/projectSteps.js @@ -1,6 +1,6 @@ import {Given, Then, When} from "cypress-cucumber-preprocessor/steps"; -const {username, password, homeURL, appURLPrefix, projectName} = Cypress.env() +const {username, password, homeURL, appURLPrefix, projectName, homePageLabel} = Cypress.env() const projectDescription = 'some description' @@ -11,13 +11,13 @@ Given('Session Login', () => { cy.get('[name=username]').clear().type(username) cy.get('[name=password]').clear().type(password) cy.get('button[type="submit"]').click() - cy.title().should('eq','App: Projects List | Mapping Workbench') + cy.title().should('eq',homePageLabel) }) }) Then('I get redirected to projects list page', () => { - cy.title().should('eq','App: Projects List | Mapping Workbench') + cy.title().should('eq',homePageLabel) }) When('I click on add project button', () => { @@ -87,7 +87,7 @@ Then('I update project description', () => { Then('I click on update button', () => { cy.intercept('PATCH', appURLPrefix + 'projects/*',).as('updateProject') - cy.get('#create_button').click() + cy.get('#create_button').click("right") }) Then('I receive update success', () => { diff --git a/mapping_workbench/frontend/cypress/e2e/testDataSuites/testDataSuitesSteps.js b/mapping_workbench/frontend/cypress/e2e/testDataSuites/testDataSuitesSteps.js index 8db7e3045..4cdb07916 100644 --- a/mapping_workbench/frontend/cypress/e2e/testDataSuites/testDataSuitesSteps.js +++ b/mapping_workbench/frontend/cypress/e2e/testDataSuites/testDataSuitesSteps.js @@ -1,6 +1,6 @@ import { Given, When, Then} from 'cypress-cucumber-preprocessor/steps' -const {username, password, homeURL, appURLPrefix, projectName} = Cypress.env() +const {username, password, homeURL, appURLPrefix, projectName, homePageLabel} = Cypress.env() const test_suite_name = 'test_suite' let sessionProject = '' @@ -12,7 +12,7 @@ Given('Session Login', () => { cy.get('[name=username]').clear().type(username) cy.get('[name=password]').clear().type(password) cy.get('button[type="submit"]').click() - cy.title().should('eq','Mapping Workbench') + cy.title().should('eq', homePageLabel) }) if(sessionProject) cy.window().then(win => win.sessionStorage.setItem('sessionProject',sessionProject)) }) diff --git a/mapping_workbench/frontend/src/pages/app/detailed-view-cm/index.js b/mapping_workbench/frontend/src/pages/app/detailed-view-cm/index.js deleted file mode 100644 index acfc3f681..000000000 --- a/mapping_workbench/frontend/src/pages/app/detailed-view-cm/index.js +++ /dev/null @@ -1,242 +0,0 @@ -import {useEffect, useState} from 'react'; - - -import Breadcrumbs from '@mui/material/Breadcrumbs'; -import Card from '@mui/material/Card'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import Typography from '@mui/material/Typography'; - -import {detailedViewCmApi as sectionApi} from 'src/api/detailed-view-cm'; -import {paths} from 'src/paths'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {BreadcrumbsSeparator} from 'src/components/breadcrumbs-separator'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {ListSearch} from 'src/sections/app/detailed-view-cm/list-search'; -import {ListTable} from 'src/sections/app/detailed-view-cm/list-table'; -import MenuItem from "@mui/material/MenuItem"; -import TextField from "@mui/material/TextField"; - -const useItemsSearch = (items) => { - const [state, setState] = useState({ - filters: {}, - sort: { - column: "", - direction: "desc" - }, - search: '', - searchColumns:["title","description"], - page: sectionApi.DEFAULT_PAGE, - rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE - }); - - const {show, ...filters} = state.filters - - const searchItems = state.search ? items.filter(item => { - let returnItem = null; - state.searchColumns.forEach(column => { - if(item[column]?.toLowerCase()?.includes(state.search.toLowerCase())) - returnItem = item - }) - return returnItem - }) : items - - const filteredItems = searchItems.filter((item) => { - let returnItem = item; - Object.entries(filters).forEach(filter=> { - const [key, value] = filter - if(value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) - returnItem = null - if(value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) - returnItem = null - }) - return returnItem - }) - - const sortedItems = () => { - const sortColumn = state.sort.column - if(!sortColumn) { - return filteredItems - } else { - return filteredItems.sort((a,b) => { - if (typeof a[sortColumn] === "string") - return state.sort.direction === "asc" ? - a[sortColumn]?.localeCompare(b[sortColumn]) : - b[sortColumn]?.localeCompare(a[sortColumn]) - else - return state.sort.direction === "asc" ? - a[sortColumn] - b[sortColumn] : - b[sortColumn] - a[sortColumn] - }) - } - } - - const pagedItems = sortedItems().filter((item, i) => { - const pageSize = state.page * state.rowsPerPage - if((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) - return item - }) - - const handleSearchItems = (filters) => { - setState(prevState => ({...prevState, search: filters.q, page: 0 })) - } - - const handleFiltersChange = (filters) => { - setState(prevState => ({ - ...prevState, - filters, - page: 0 - })); - } - - const handlePageChange = (event, page) => { - setState(prevState => ({ - ...prevState, - page - })); - } - - const handleSort = (column, desc) => { - setState(prevState=> ({ ...prevState, sort: {column, - direction: prevState.sort.column === column - ? prevState.sort.direction === "desc" - ? "asc" - : "desc" - : desc - ? "desc" - : "asc"}})) - - } - - const handleRowsPerPageChange = (event) => { - setState(prevState => ({ - ...prevState, - rowsPerPage: parseInt(event.target.value, 10) - })); - } - - return { - handleFiltersChange, - handlePageChange, - handleRowsPerPageChange, - handleSort, - handleSearchItems, - pagedItems, - count: filteredItems.length, - state - }; -}; - -export const Page = () => { - const [listState,setListState] = useState([]) - const [currentListItem, setCurrentListItem] = useState('') - const [itemsStore,setItemsStore] = useState({items:[]}) - useEffect(() => { - sectionApi.getList() - .then(res => { - if(res.items.length) { - setListState(res.items) - setCurrentListItem(res.items[0]) - } - }) - }, []); - - - useEffect(() => { - currentListItem && getItems() - }, [currentListItem]); - - const getItems = () => { - sectionApi.getItems({}) - .then(res => { - console.log(res) - setItemsStore(res) - }) - } - - - const itemsSearch = useItemsSearch(itemsStore.items); - - return ( - <> - - - - - - {sectionApi.SECTION_TITLE} - - }> - - App - - - {sectionApi.SECTION_TITLE} - - - List - - - - - - - setCurrentListItem(e.target.value) - } - select - value={currentListItem} - sx={{p:1}} - > - {listState.map(item => - - {item.ontology_fragment_name} - - )} - - - - - - - ) -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/fields-and-nodes-/index.js b/mapping_workbench/frontend/src/pages/app/fields-and-nodes-/index.js deleted file mode 100644 index 3fde78d2b..000000000 --- a/mapping_workbench/frontend/src/pages/app/fields-and-nodes-/index.js +++ /dev/null @@ -1,217 +0,0 @@ -import {useEffect, useState} from 'react'; -import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; - -import {parseString, Builder} from "xml2js"; - -import TextField from "@mui/material/TextField"; -import Button from "@mui/material/Button"; -import MenuItem from "@mui/material/MenuItem"; -import Typography from "@mui/material/Typography"; - -import {Layout as AppLayout} from 'src/layouts/app'; -import {schemaFileResourcesApi as schemaFiles} from 'src/api/schema-files/file-resources' -import {fieldsRegistryApi as fieldsRegistry} from 'src/api/fields-registry' -import CircularProgress from "@mui/material/CircularProgress"; -import {AlertTitle, Alert} from "@mui/material"; - -const Page = () => { - const [xPaths, setXPaths] = useState([]) - const [selectedLine, setSelectedLine] = useState(null); - const [xmlContent,setXmlContent] = useState('') - const [selectedNode, setSelectedNode] = useState('') - const [nodesList, setNodesList] = useState([]) - const [files,setFiles] = useState([]) - const [selectedFile, setSelectedFile] = useState('') - const [loadFile, setLoadFile] = useState({}) - - - useEffect(() => { - - // try { - // const schemaFilesRes = await schemaFiles.getItems() - // const fieldsRegistryRed = fieldsRegistry.getXpathsList() - // - // } - schemaFiles.getItems({}) - .then(res => setFiles(res)) - .catch(err => console.error(err)) - - fieldsRegistry.getXpathsList() - .then(res => { - console.log(res) - setXPaths(res) - }) - .catch(err => console.error(err)) - },[]) - - - useEffect(() => { - setLoadFile({load:true}) - setXmlContent('') - parseString(selectedFile.content, { explicitArray: false }, (err, result) => { - if (err) { - console.error('Error parsing XML:', err); - setLoadFile({error:true}) - } else { - setLoadFile({}) - console.log(result) - const builder = new Builder() - setXmlContent(builder.buildObject(result)) - } - }); - },[selectedFile]) - - console.log(xmlContent) - - - const findXPaths = (xmlString) => { - const lines = xmlString.split('\n'); - let xpaths = []; - let xpathStack = []; - - lines.forEach((line, index) => { - line = line.trim(); - if( line.startsWith('')) - //tags that are not used - xpaths.push('') - // xpaths.push({xpath:[]}) - else if (line.startsWith('<') && !line.startsWith(']+)/)[1]; - xpathStack.push(tagName); - xpaths.push(`${xpathStack.join('/')}`); - // xpaths.push({xpath:xpathStack.join('/')}) - // Self-closing tag - if (line.includes('{ - const res = e.split('/') - res.shift() - res.join('/') - return res - }); -} - - const findedXpath = findXPaths(xmlContent) - - - const handleLineClick = (lineNumber) => { - setSelectedNode(findedXpath[lineNumber - 1]); - setSelectedLine(lineNumber) - // const xpathForLine = findedXpath[lineNumber - 1].split('/') - // console.log(xpathForLine.shift()) -// console.log(xpathForLine.join('/')) - }; - const renderRow = (rows, css, highlight) => { - return rows.map((node, i) => { - const nodeCss = Object.assign({}, ...node.properties?.className.map(e=>css[e]).filter(e => e) ?? []) - const isTagNode = ['token','tag'].every(e =>node.properties?.className.includes(e)) - && !['punctuation','attr-name','attr-value'].some(e => node.properties?.className.includes(e)) - && node.children?.[0]?.value !== ' ' - return - {node.children ? renderRow(node.children, css, false) : node.value} - - }); - } - - return ( -
- setSelectedFile(event.target.value)} - value={files[0]} - select - > - {files.map((file) => ( - - - {file.filename} - - - ))} - - {loadFile.load && - } - {loadFile.error && - - Error - Error on load file. - } - {xmlContent && { - return rows.map((node, i) => { - - const nodeCss = Object.assign({}, ...node.properties?.className.map(e=>css[e]).filter(e => e) ?? []) - return - {renderRow(node.children, stylesheet, xPaths.some(e=>e.xpath.replace('/*/','').endsWith(findedXpath[i])))} - - })}} - lineProps={(lineNumber) => ({ - style: {cursor: 'pointer', backgroundColor: selectedLine === lineNumber ? '#e0e0e0' : 'inherit',hljsTag:'black'}, - onClick: () => handleLineClick(lineNumber), - })} - > - {xmlContent} - } - {
    - {xPaths.map(e =>
  • {e.xpath.replace('/*/','')}
  • )} -
} - - - {
    - {/*{findedXpath.map(e =>
  • {e.join('/')}
  • )}*/} -
} -
- ); -}; - - - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/fields-and-nodes-mirror/index.js b/mapping_workbench/frontend/src/pages/app/fields-and-nodes-mirror/index.js deleted file mode 100644 index 10af19c3c..000000000 --- a/mapping_workbench/frontend/src/pages/app/fields-and-nodes-mirror/index.js +++ /dev/null @@ -1,90 +0,0 @@ -import {Layout as AppLayout} from 'src/layouts/app'; -import React, { useEffect, useRef } from 'react'; -import { Controlled as CodeMirror } from 'react-codemirror2'; -import 'codemirror/lib/codemirror.css'; -// import 'codemirror/mode/xml/xml'; -import XMLData from 'cn_81' - - -const Page = () => { - const editorRef = useRef(); - - const handleEditorDidMount = (editor) => { - editorRef.current = editor; - - editor.on('mousedown', (instance, event) => { - console.log('md') - const pos = instance.coordsChar({ left: event.clientX, top: event.clientY }, 'window'); - const token = instance.getTokenAt(pos); - - console.log(token) - - if (token.type === 'attribute') { - const attributeName = token.string; - const elementPos = instance.coordsChar({ left: event.clientX - token.start, top: event.clientY }, 'window'); - const elementToken = instance.getTokenAt(elementPos); - - if (elementToken.type === 'tag') { - const elementName = elementToken.string; - const xpath = generateXPath(instance.getValue(), elementName, attributeName); - console.log(xpath); - } - } - }); - }; - - const generateXPath = (xml, elementName, attributeName) => { - const parser = new DOMParser(); - const xmlDoc = parser.parseFromString(xml, 'application/xml'); - - const xpathResult = xmlDoc.evaluate(`//${elementName}[@${attributeName}]`, xmlDoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); - if (xpathResult.singleNodeValue) { - const element = xpathResult.singleNodeValue; - return getElementXPath(element); - } - return null; - }; - - const getElementXPath = (element) => { - if (element.id !== '') { - return `id("${element.id}")`; - } - if (element === document.body) { - return element.tagName.toLowerCase(); - } - let ix = 0; - const siblings = element.parentNode.childNodes; - for (let i = 0; i < siblings.length; i++) { - const sibling = siblings[i]; - if (sibling === element) { - return `${getElementXPath(element.parentNode)}/${element.tagName.toLowerCase()}[${ix + 1}]`; - } - if (sibling.nodeType === 1 && sibling.tagName === element.tagName) { - ix++; - } - } - }; - - return ( - - ); -}; - - - - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/fields-and-nodes-plus/index.js b/mapping_workbench/frontend/src/pages/app/fields-and-nodes-plus/index.js deleted file mode 100644 index 916d897e1..000000000 --- a/mapping_workbench/frontend/src/pages/app/fields-and-nodes-plus/index.js +++ /dev/null @@ -1,194 +0,0 @@ -import {useEffect, useRef, useState} from 'react'; -import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; -// import { docco } from 'react-syntax-highlighter/dist/esm/styles/hljs'; -import { parseString } from 'xml2js'; -import {Layout as AppLayout} from 'src/layouts/app'; -const Page = () => { - const [xmlContent, setXmlContent] = useState(''); - const [parsedXml, setParsedXml] = useState(null); - const [nodes, setNodes] = useState([]); - const [noNodeRow,setNoNodeRow] = useState([]) - - const misNodes = useRef([]) - - - const handleFileUpload = (event) => { - const file = event.target.files[0]; - if (file) { - const reader = new FileReader(); - reader.onload = (e) => { - const xmlString = e.target.result; - // console.log('xmlString',xmlString) - parseString(xmlString, { explicitArray: false }, (err, result) => { - if (err) { - console.error('Error parsing XML:', err); - } else { - setXmlContent(xmlString); - setParsedXml(result); - console.log(xmlString) - const allTagLines = xmlString.split(' ') - .map((e,i)=>(e.includes('<'&&e.includes('>')) ? -1 : i)) - // .filter(e => e>=0) - console.log('allTagLines',allTagLines) - const allNodes = findAllNodes(result); - setNodes(allNodes); - } - }); - }; - reader.readAsText(file); - } - }; - - // Function to find all nodes and their XPaths - const findAllNodes = (node, path = '') => { - const result = []; - - const recursiveFind = (currentNode, currentPath) => { - if (typeof currentNode === 'object') { - let hasChildren = false; - let lastLevelNode = false - let outNode = false - - console.log('currentNode',currentNode,Object.keys(currentNode)) - // for (const key in currentNode) { - for (let i =0; i< Object.keys(currentNode).length; i++) { - const key = Object.keys(currentNode)[i] - - if (Object.hasOwnProperty.call(currentNode, key)) { - // Ignore attributes; attributes are typically denoted with '@' prefix - console.log(key, typeof key) - // if (key.startsWith('$')) continue; - - const value = currentNode[key]; - const newPath = `${currentPath}/${key}`; - - if (typeof value === 'object') { - hasChildren = true; - if(value._) lastLevelNode = true - result.push({ path: newPath, node: value }); - console.log(value,typeof value) - if(Array.isArray(value)) - value.map(e=>recursiveFind(e,newPath)) - else - recursiveFind(value, newPath); - } else if (value && typeof value === 'string') { - // Skip text nodes - // continue; - result.push({ path: newPath, node: value }); - } - } - if(i===Object.keys(currentNode).length - 1) - outNode=true - // result.push({ path: `${currentPath}`, node: {} }); - } - - // Include closing tag if the node has children - if ((hasChildren && lastLevelNode)) { - result.push({ path: `${currentPath}`, node: {} }); - } - } - }; - - recursiveFind(node, path); - return result.filter(e=> !['$','/_'].some(val => e.path.includes(val))); - }; - - - const collectNodeText = (node) => { - let haveTag = false - if(node?.children && ['token','tag'].some(e =>node.properties?.className.includes(e))) - haveTag = true - if(node?.children && ['token','tag'].every(e =>node.properties?.className.includes(e)) && !['punctuation','attr-name','attr-value'].some(e => node.properties?.className.includes(e)) ) - return node?.children.map(e=>e.value).join('').replace(' ','') - - if(node?.children) - return node.children.map(e=>collectNodeText(e)) - // return node.value - } - - const renderRow = (rows, css, highlight) => { - return rows.map((node, i) => { - const nodeCss = Object.assign({}, ...node.properties?.className.map(e=>css[e]).filter(e => e) ?? []) - return - {node.children ? renderRow(node.children, css, false) : node.value} - - }); - } - - let nnr =[] - - console.log(misNodes) - - return ( -
- - {xmlContent && ( - <> - { - console.log(rows) - return rows.map((node, i) => { - const nodeCss = Object.assign({}, ...node.properties?.className.map(e=>css[e]).filter(e => e) ?? []) - console.log('nnd',node,collectNodeText(node).join(''),!!collectNodeText(node).join('')) - - // if(!collectNodeText(node).join('')) { - // misNodes.current.push(i) - // } - // setrowsNoNodeRow(e=>([...e,i])) - // setNodes( [ - // ...nodes.slice(0, i), - // '', - // ...nodes.slice(i) - // ]); - return node.properties.onClick()} - style={ {...nodeCss, ...node.properties?.style}} - > - {renderRow(node.children, stylesheet)} - - })}} - lineProps={(lineNumber) => ({ - style: { display: "block", cursor: "pointer" }, - // onMouseEnter() { - // setHoveredLine(lineNumber) - // console.log(lineNumber) - // }, - onClick() { - console.log(nodes[lineNumber-4]) - // alert(`Line Number Clicked: ${lineNumber}`); - }, - })} - > - {xmlContent} - -

Nodes and XPaths

-
    - {nodes.map((item, index) => ( -
  • - {index} XPath: {item.path}
    - {/*Node: {JSON.stringify(item.node)}*/} -
  • - ))} -
- - )} -
- ); -}; - - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/fields-overview/[id]/view.js b/mapping_workbench/frontend/src/pages/app/fields-overview/[id]/view.js deleted file mode 100644 index d347ab420..000000000 --- a/mapping_workbench/frontend/src/pages/app/fields-overview/[id]/view.js +++ /dev/null @@ -1,147 +0,0 @@ -import {useEffect, useState} from 'react'; - -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import Divider from '@mui/material/Divider'; -import Grid from '@mui/material/Unstable_Grid2'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Tab from '@mui/material/Tab'; -import Tabs from '@mui/material/Tabs'; -import Typography from '@mui/material/Typography'; - -import {paths} from 'src/paths'; -import {Seo} from 'src/components/seo'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {fieldsOverviewApi as sectionApi} from 'src/api/fields-overview'; -import {BasicDetails} from 'src/sections/app/fields-registry/basic-details'; -import {RouterLink} from 'src/components/router-link'; -import {usePageView} from 'src/hooks/use-page-view'; -import {useRouter} from "src/hooks/use-router"; - -const tabs = [ - {label: 'Details', value: 'details'} -]; - -const Page = () => { - const [currentTab, setCurrentTab] = useState('details'); - const [item, setItem] = useState() - - const router = useRouter(); - - const {id} = router.query; - - useEffect(() => { - id && sectionApi.getItem(id) - .then(res => setItem(res)) - .catch(err => console.error(err)) - },[id]); - - usePageView(); - - const handleTabsChange = (event, value) => { - setCurrentTab(value); - } - - if (!item) { - return; - } - - return ( - <> - - - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
- - - - {item.name && - {item.name} - } - - {item.sdk_element_id} - - - - -
- - {tabs.map((tab) => ( - - ))} - - -
-
- {currentTab === 'details' && ( -
- - - - - -
- )} -
- - ) -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/fields-overview/import.js b/mapping_workbench/frontend/src/pages/app/fields-overview/import.js deleted file mode 100644 index 84600dfeb..000000000 --- a/mapping_workbench/frontend/src/pages/app/fields-overview/import.js +++ /dev/null @@ -1,145 +0,0 @@ -import {useState} from "react"; -import {useFormik} from "formik"; -import {useRouter} from "next/router"; -import * as Yup from "yup"; - -import Stack from '@mui/material/Stack'; -import CardHeader from "@mui/material/CardHeader"; -import CardContent from "@mui/material/CardContent"; -import Grid from "@mui/material/Unstable_Grid2"; -import Button from "@mui/material/Button"; -import Card from "@mui/material/Card"; - -import {paths} from "src/paths"; -import {sessionApi} from "src/api/session"; -import {Layout as AppLayout} from 'src/layouts/app'; -import {usePageView} from 'src/hooks/use-page-view'; -import {FormTextField} from "src/components/app/form/text-field"; -import {fieldsOverviewApi as sectionApi} from 'src/api/fields-overview'; -import {toastError, toastLoad, toastSuccess} from "src/components/app-toast"; -import Link from "@mui/material/Link"; -import {RouterLink} from "../../../components/router-link"; -import SvgIcon from "@mui/material/SvgIcon"; -import ArrowLeftIcon from "@untitled-ui/icons-react/build/esm/ArrowLeft"; -import Typography from "@mui/material/Typography"; - - -const Page = () => { - usePageView(); - const router = useRouter() - - const [isRunning, setIsRunning] = useState(false); - - const formik = useFormik({ - initialValues: { - github_repository_url: "", - branch_or_tag_name: "" - }, - validationSchema: Yup.object({ - github_repository_url: Yup - .string() - .max(1024) - .required('GitHub Repo URL is required'), - branch_or_tag_name: Yup - .string() - .max(20) - .required('Branch or Tag name is required') - }), - onSubmit: async (values, helpers) => { - setIsRunning(true) - values['project_id'] = sessionApi.getSessionProject(); - const toastId = toastLoad(`Importing eForm Fields ... `) - sectionApi.importEFormsFromGithub(values) - .then((res) => { - helpers.setStatus({success: true}); - toastSuccess(`${res.task_name} successfully started.`, toastId) - router.push({ - pathname: paths.app[sectionApi.section].index - }) - }) - .catch(err => { - console.log(err) - helpers.setStatus({success: false}); - helpers.setErrors({submit: err.message}); - toastError(`eForm Fields import failed: ${err.message}.`, toastId); - }) - .finally(setIsRunning(false)) - } - }); - - return ( - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
-
- - - - - - - - - - - - - - - - - - -
-
- ); -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/fields-overview/index.js b/mapping_workbench/frontend/src/pages/app/fields-overview/index.js deleted file mode 100644 index 4839643ff..000000000 --- a/mapping_workbench/frontend/src/pages/app/fields-overview/index.js +++ /dev/null @@ -1,244 +0,0 @@ -import {useEffect, useState} from 'react'; - -import Breadcrumbs from '@mui/material/Breadcrumbs'; -import Card from '@mui/material/Card'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import Typography from '@mui/material/Typography'; -import Button from "@mui/material/Button"; -import SvgIcon from "@mui/material/SvgIcon"; - -import {paths} from 'src/paths'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {Filter} from "src/sections/components/filter"; -import {RouterLink} from 'src/components/router-link'; -import {ListTable} from "src/sections/app/fields-registry/list-table"; -import {fieldsOverviewApi as sectionApi} from 'src/api/fields-overview'; -import {ListSearch} from "src/sections/app/fields-registry/list-search"; - -import {BreadcrumbsSeparator} from 'src/components/breadcrumbs-separator'; -import {Upload04 as ImportIcon} from '@untitled-ui/icons-react/build/esm'; - -const useItemsSearch = (items) => { - const [state, setState] = useState({ - filters: "", - sort: { - column: "", - direction: "desc" - }, - search: '', - searchColumns: ["sdk_element_id", "relative_xpath", "absolute_xpath"], - page: sectionApi.DEFAULT_PAGE, - rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE - }); - - const filterValues = [{label: 'All', value: ''}, - {label: 'Node', value: 'node'}, - {label: 'Field', value: 'field'}] - - - const searchItems = state.search ? items.filter(item => { - let returnItem = null; - state.searchColumns.forEach(column => { - if (item[column]?.toLowerCase()?.includes(state.search.toLowerCase())) - returnItem = item - }) - return returnItem - }) : items - - const filteredItems = searchItems.filter((item) => state.filters === "" || state.filters === item.element_type ? item : null) - - const sortedItems = () => { - const sortColumn = state.sort.column - if (!sortColumn) { - return filteredItems - } else { - return filteredItems.sort((a, b) => { - if (typeof a[sortColumn] === "string") - return state.sort.direction === "asc" ? - a[sortColumn]?.localeCompare(b[sortColumn]) : - b[sortColumn]?.localeCompare(a[sortColumn]) - else - return state.sort.direction === "asc" ? - a[sortColumn] - b[sortColumn] : - b[sortColumn] - a[sortColumn] - }) - } - } - - const pagedItems = sortedItems().filter((item, i) => { - const pageSize = state.page * state.rowsPerPage - if ((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) - return item - }) - - const handleSearchItems = (filters) => { - setState(prevState => ({...prevState, search: filters.q, page: 0})) - } - - const handleFiltersChange = filters => { - setState(prevState => ({ - ...prevState, - filters, - page: 0 - })); - } - - const handlePageChange = (event, page) => { - setState(prevState => ({ - ...prevState, - page - })); - } - - const handleSort = (column, desc) => { - setState(prevState => ({ - ...prevState, sort: { - column, - direction: prevState.sort.column === column - ? prevState.sort.direction === "desc" - ? "asc" - : "desc" - : desc - ? "desc" - : "asc" - } - })) - } - - const handleRowsPerPageChange = event => { - setState(prevState => ({ - ...prevState, - rowsPerPage: parseInt(event.target.value, 10) - })); - } - - return { - handleFiltersChange, - handlePageChange, - handleRowsPerPageChange, - handleSort, - handleSearchItems, - filterValues, - pagedItems, - count: filteredItems.length, - state - }; -}; - - -const useItemsStore = () => { - const [state, setState] = useState({ - items: [], - itemsCount: 0 - }); - - const handleItemsGet = () => { - sectionApi.getItems() - .then(res => setState({ - items: res.items, - itemsCount: res.count - })) - .catch(err => console.error(err)) - } - - useEffect(() => { - handleItemsGet(); - }, - // eslint-disable-next-line react-hooks/exhaustive-deps - []); - - return { - ...state - }; -}; - - -const Page = () => { - const itemsStore = useItemsStore(); - const itemsSearch = useItemsSearch(itemsStore.items); - - usePageView(); - - return ( - <> - - - - - - {sectionApi.SECTION_TITLE} - - }> - - App - - - {sectionApi.SECTION_TITLE} - - - - - - - - - - - - - - - - ); -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/fields-registry/[id]/edit.js b/mapping_workbench/frontend/src/pages/app/fields-registry/[id]/edit.js deleted file mode 100644 index daa2e1f0b..000000000 --- a/mapping_workbench/frontend/src/pages/app/fields-registry/[id]/edit.js +++ /dev/null @@ -1,107 +0,0 @@ -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import Chip from '@mui/material/Chip'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; - -import {fieldsRegistryApi as sectionApi} from 'src/api/fields-registry'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {EditForm} from 'src/sections/app/fields-registry/edit-form'; -import {ForItemEditForm} from "src/contexts/app/section/for-item-form"; -import {useItem} from "src/contexts/app/section/for-item-data-state"; -import {useRouter} from "src/hooks/use-router"; - - -const Page = () => { - const router = useRouter(); - if (!router.isReady) return; - - const {id} = router.query; - - if (!id) { - return; - } - - const formState = useItem(sectionApi, id); - const item = formState.item; - - usePageView(); - - if (!item) { - return; - } - - return ( - <> - - - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
- - - - - {item.prefix} - - - - - - - -
- -
- - ); -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/fields-registry/[id]/view.js b/mapping_workbench/frontend/src/pages/app/fields-registry/[id]/view.js deleted file mode 100644 index e4586f6ba..000000000 --- a/mapping_workbench/frontend/src/pages/app/fields-registry/[id]/view.js +++ /dev/null @@ -1,160 +0,0 @@ -import {useCallback, useState} from 'react'; -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import Box from '@mui/material/Box'; -import Chip from '@mui/material/Chip'; -import Container from '@mui/material/Container'; -import Divider from '@mui/material/Divider'; -import Grid from '@mui/material/Unstable_Grid2'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Tab from '@mui/material/Tab'; -import Tabs from '@mui/material/Tabs'; -import Typography from '@mui/material/Typography'; - -import {fieldsRegistryApi as sectionApi} from 'src/api/fields-registry'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {BasicDetails} from 'src/sections/app/fields-registry/basic-details'; -import {useRouter} from "src/hooks/use-router"; -import {useItem} from "src/contexts/app/section/for-item-data-state"; - -const tabs = [ - {label: 'Details', value: 'details'} -]; - -const Page = () => { - const router = useRouter(); - if (!router.isReady) return; - - const {id} = router.query; - - if (!id) { - return; - } - - const formState = useItem(sectionApi, id); - const item = formState.item; - - usePageView(); - const [currentTab, setCurrentTab] = useState('details'); - - const handleTabsChange = useCallback((event, value) => { - setCurrentTab(value); - }, []); - - if (!item) { - return; - } - - return ( - <> - - - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
- - - - - {item.prefix} - - - - - - - -
- - {tabs.map((tab) => ( - - ))} - - -
-
- {currentTab === 'details' && ( -
- - - - - -
- )} -
- - ) -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/fields-registry/create.js b/mapping_workbench/frontend/src/pages/app/fields-registry/create.js deleted file mode 100644 index 4612e6aa3..000000000 --- a/mapping_workbench/frontend/src/pages/app/fields-registry/create.js +++ /dev/null @@ -1,61 +0,0 @@ -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import Box from '@mui/material/Box'; -import Container from '@mui/material/Container'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; - -import {fieldsRegistryApi as sectionApi} from 'src/api/fields-registry'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {EditForm} from 'src/sections/app/fields-registry/edit-form'; -import {ForItemCreateForm} from "src/contexts/app/section/for-item-form"; - - -const Page = () => { - let item = {}; - - usePageView(); - - return ( - <> - - - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
-
- -
- - ); -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/fields-registry/elements/[id]/view.js b/mapping_workbench/frontend/src/pages/app/fields-registry/elements/[id]/view.js deleted file mode 100644 index 76c94d6ed..000000000 --- a/mapping_workbench/frontend/src/pages/app/fields-registry/elements/[id]/view.js +++ /dev/null @@ -1,149 +0,0 @@ -import {useState} from 'react'; - -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import Divider from '@mui/material/Divider'; -import Grid from '@mui/material/Unstable_Grid2'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Tab from '@mui/material/Tab'; -import Tabs from '@mui/material/Tabs'; -import Typography from '@mui/material/Typography'; - -import {paths} from 'src/paths'; -import {Seo} from 'src/components/seo'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {fieldsRegistryApi as sectionApi} from 'src/api/fields-registry'; -import {BasicDetails} from 'src/sections/app/fields-registry/basic-details'; -import {useItem} from "src/contexts/app/section/for-item-data-state"; -import {RouterLink} from 'src/components/router-link'; -import {usePageView} from 'src/hooks/use-page-view'; -import {useRouter} from "src/hooks/use-router"; - -const tabs = [ - {label: 'Details', value: 'details'} -]; - -const Page = () => { - const [currentTab, setCurrentTab] = useState('details'); - - const router = useRouter(); - if (!router.isReady) return; - - const {id} = router.query; - - if (!id) { - return; - } - - const formState = useItem(sectionApi, id, "element"); - const item = formState.item; - - usePageView(); - - const handleTabsChange = (event, value) => { - setCurrentTab(value); - } - - if (!item) { - return; - } - - return ( - <> - - - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
- - - - {item.name && - {item.name} - } - - {item.sdk_element_id} - - - - -
- - {tabs.map((tab) => ( - - ))} - - -
-
- {currentTab === 'details' && ( -
- - - - - -
- )} -
- - ) -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/fields-registry/elements/import.js b/mapping_workbench/frontend/src/pages/app/fields-registry/elements/import.js deleted file mode 100644 index 6a6395808..000000000 --- a/mapping_workbench/frontend/src/pages/app/fields-registry/elements/import.js +++ /dev/null @@ -1,118 +0,0 @@ -import {useState} from "react"; -import {useFormik} from "formik"; -import * as Yup from "yup"; -import {useRouter} from "next/router"; - -import Stack from '@mui/material/Stack'; -import CardHeader from "@mui/material/CardHeader"; -import CardContent from "@mui/material/CardContent"; -import Grid from "@mui/material/Unstable_Grid2"; -import Button from "@mui/material/Button"; -import Card from "@mui/material/Card"; - -import {usePageView} from 'src/hooks/use-page-view'; -import {FormTextField} from "src/components/app/form/text-field"; -import {Layout as AppLayout} from 'src/layouts/app'; -import {fieldsRegistryApi as sectionApi} from 'src/api/fields-registry'; -import {sessionApi} from "../../../../api/session"; -import {paths} from "../../../../paths"; -import {toastError, toastLoad, toastSuccess} from "../../../../components/app-toast"; - - -const Page = () => { - usePageView(); - const router = useRouter() - - const [isRunning, setIsRunning] = useState(false); - - const formik = useFormik({ - initialValues: { - github_repository_url: "", - branch_or_tag_name: "" - }, - validationSchema: Yup.object({ - github_repository_url: Yup - .string() - .max(1024) - .required('GitHub Repo URL is required'), - branch_or_tag_name: Yup - .string() - .max(20) - .required('Branch or Tag name is required') - }), - onSubmit: async (values, helpers) => { - setIsRunning(true) - values['project_id'] = sessionApi.getSessionProject(); - const toastId = toastLoad(`Importing eForm Fields ... `) - sectionApi.importEFormsFromGithub(values) - .then((res) => { - helpers.setStatus({success: true}); - toastSuccess(`${res.task_name} successfully started.`, toastId) - router.push({ - pathname: paths.app[sectionApi.section].elements.index - }) - }) - .catch(err => { - helpers.setStatus({success: false}); - helpers.setErrors({submit: err.message}); - toastError(`eForm Fields import failed: ${err.message}.`, toastId); - }) - .finally(setIsRunning(false)) - } - }); - - return ( -
- - - - - - - - - - - - - - - - - - -
- ); -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/fields-registry/elements/index.js b/mapping_workbench/frontend/src/pages/app/fields-registry/elements/index.js deleted file mode 100644 index 3a8cfb92e..000000000 --- a/mapping_workbench/frontend/src/pages/app/fields-registry/elements/index.js +++ /dev/null @@ -1,168 +0,0 @@ -import {useCallback, useEffect, useState} from 'react'; - -import Breadcrumbs from '@mui/material/Breadcrumbs'; -import Card from '@mui/material/Card'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import Typography from '@mui/material/Typography'; - -import {paths} from 'src/paths'; -import {Seo} from 'src/components/seo'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {fieldsRegistryApi as sectionApi} from 'src/api/fields-registry'; -import {BreadcrumbsSeparator} from 'src/components/breadcrumbs-separator'; -import {RouterLink} from 'src/components/router-link'; -import {usePageView} from 'src/hooks/use-page-view'; -import {ListSearch} from "src/sections/app/fields-registry/list-search"; -import {ListTable} from "src/sections/app/fields-registry/list-table"; -import {useMounted} from "src/hooks/use-mounted"; -import {useDialog} from "src/hooks/use-dialog"; - -const useItemsSearch = () => { - const [state, setState] = useState({ - filters: { - name: undefined, - category: [], - status: [], - inStock: undefined - }, - page: sectionApi.DEFAULT_PAGE, - rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE - }); - - const handleFiltersChange = useCallback((filters) => { - setState((prevState) => ({ - ...prevState, - filters, - page: 0 - })); - }, []); - - const handlePageChange = useCallback((event, page) => { - setState((prevState) => ({ - ...prevState, - page - })); - }, []); - - const handleRowsPerPageChange = useCallback((event) => { - setState((prevState) => ({ - ...prevState, - rowsPerPage: parseInt(event.target.value, 10) - })); - }, []); - - return { - handleFiltersChange, - handlePageChange, - handleRowsPerPageChange, - state - }; -}; - - -const useItemsStore = (searchState) => { - const isMounted = useMounted(); - const [state, setState] = useState({ - items: [], - itemsCount: 0 - }); - - const handleItemsGet = useCallback(async () => { - try { - const response = await sectionApi.getItems(searchState, 'elements'); - if (isMounted()) { - setState({ - items: response.items, - itemsCount: response.count - }); - } - } catch (err) { - console.error(err); - } - }, [searchState, isMounted]); - - useEffect(() => { - handleItemsGet(); - }, - // eslint-disable-next-line react-hooks/exhaustive-deps - [searchState]); - - return { - ...state - }; -}; - - -const Page = () => { - const itemsSearch = useItemsSearch(); - const itemsStore = useItemsStore(itemsSearch.state); - - const importDialog = useDialog(); - - usePageView(); - - return ( - <> - - - - - - {sectionApi.SECTION_TITLE} - - }> - - App - - - {sectionApi.SECTION_TITLE} - - - Elements - - - - - - - - - - - - ); -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/fields-registry/index.js b/mapping_workbench/frontend/src/pages/app/fields-registry/index.js deleted file mode 100644 index 122d7a45a..000000000 --- a/mapping_workbench/frontend/src/pages/app/fields-registry/index.js +++ /dev/null @@ -1,182 +0,0 @@ -import {useCallback, useEffect, useState} from 'react'; -import PlusIcon from '@untitled-ui/icons-react/build/esm/Plus'; -import Breadcrumbs from '@mui/material/Breadcrumbs'; -import Button from '@mui/material/Button'; -import Card from '@mui/material/Card'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; - -import {fieldsRegistryApi as sectionApi} from 'src/api/fields-registry'; -import {BreadcrumbsSeparator} from 'src/components/breadcrumbs-separator'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {useMounted} from 'src/hooks/use-mounted'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {ListSearch} from "../../../sections/app/fields-registry/list-search"; -import {ListTable} from "../../../sections/app/fields-registry/list-table"; - -const useItemsSearch = () => { - const [state, setState] = useState({ - filters: { - name: undefined, - category: [], - status: [], - inStock: undefined - }, - page: sectionApi.DEFAULT_PAGE, - rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE - }); - - const handleFiltersChange = useCallback((filters) => { - setState((prevState) => ({ - ...prevState, - filters, - page: 0 - })); - }, []); - - const handlePageChange = useCallback((event, page) => { - setState((prevState) => ({ - ...prevState, - page - })); - }, []); - - const handleRowsPerPageChange = useCallback((event) => { - setState((prevState) => ({ - ...prevState, - rowsPerPage: parseInt(event.target.value, 10) - })); - }, []); - - return { - handleFiltersChange, - handlePageChange, - handleRowsPerPageChange, - state - }; -}; - -const useItemsStore = (searchState) => { - const isMounted = useMounted(); - const [state, setState] = useState({ - items: [], - itemsCount: 0 - }); - - const handleItemsGet = useCallback(async () => { - try { - const response = await sectionApi.getItems(searchState); - if (isMounted()) { - setState({ - items: response.items, - itemsCount: response.count - }); - } - } catch (err) { - console.error(err); - } - }, [searchState, isMounted]); - - useEffect(() => { - handleItemsGet(); - }, - // eslint-disable-next-line react-hooks/exhaustive-deps - [searchState]); - - return { - ...state - }; -}; - -const Page = () => { - const itemsSearch = useItemsSearch(); - const itemsStore = useItemsStore(itemsSearch.state); - - usePageView(); - - return ( - <> - - - - - - {sectionApi.SECTION_TITLE} - - }> - - App - - - {sectionApi.SECTION_TITLE} - - - List - - - - - - - - - - - - - - ) -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/fields-registry/tree-view/index.js b/mapping_workbench/frontend/src/pages/app/fields-registry/tree-view/index.js deleted file mode 100644 index 240d44e9c..000000000 --- a/mapping_workbench/frontend/src/pages/app/fields-registry/tree-view/index.js +++ /dev/null @@ -1,95 +0,0 @@ -import Breadcrumbs from '@mui/material/Breadcrumbs'; -import Card from '@mui/material/Card'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import Typography from '@mui/material/Typography'; - -import {paths} from 'src/paths'; -import {fieldsRegistryApi as sectionApi} from 'src/api/fields-registry'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {BreadcrumbsSeparator} from 'src/components/breadcrumbs-separator'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import TreeView from "../../../../sections/app/tree-view/tree-view"; - - -export const Page = () => { - - return ( - <> - - - - - - {sectionApi.SECTION_TREE_TITLE} - - }> - - App - - - {sectionApi.SECTION_TREE_TITLE} - - - List - - - - {/**/} - {/* }*/} - {/* variant="contained"*/} - {/* onClick={handleItemsGet}*/} - {/* >*/} - {/* Refresh*/} - {/* */} - {/* }*/} - {/* variant="contained"*/} - {/* onClick={handleDeleteAllTasks}*/} - {/* >*/} - {/* Delete All Tasks*/} - {/* */} - {/**/} - - - - - - - ) -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/ontology-files/index.js b/mapping_workbench/frontend/src/pages/app/ontology-files/index.js deleted file mode 100644 index 7e5a3ed25..000000000 --- a/mapping_workbench/frontend/src/pages/app/ontology-files/index.js +++ /dev/null @@ -1,311 +0,0 @@ -import {useEffect, useState} from 'react'; - -import Upload01Icon from '@untitled-ui/icons-react/build/esm/Upload01'; -import Button from '@mui/material/Button'; -import Grid from '@mui/material/Unstable_Grid2'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; -import Dialog from "@mui/material/Dialog"; -import DialogTitle from "@mui/material/DialogTitle"; -import DialogContent from "@mui/material/DialogContent"; - -import {Seo} from 'src/components/seo'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {ontologyFilesApi as sectionApi} from 'src/api/ontology-files'; -import {ontologyTermsApi} from "../../../api/ontology-terms"; -import {useDialog} from 'src/hooks/use-dialog'; -import {usePageView} from 'src/hooks/use-page-view'; -import {FileUploader} from 'src/sections/app/files-form//file-uploader'; -import {ItemSearch} from 'src/sections/app/files-form//item-search'; -import {ontologyFileResourcesApi as fileResourcesApi} from "src/api/ontology-files/file-resources"; -import {ItemList} from "src/sections/app/files-form/item-list"; -import {sessionApi} from "src/api/session"; - -import {Prism as SyntaxHighlighter} from "react-syntax-highlighter"; -import CircularProgress from "@mui/material/CircularProgress"; -import {Box} from "@mui/system"; -import {toastError, toastLoad, toastSuccess} from "../../../components/app-toast"; - -const useItemsSearch = (items) => { - const [state, setState] = useState({ - filters: {}, - page: sectionApi.DEFAULT_PAGE, - rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE, - sort: { - column: "filename", - direction: "desc" - }, - search: '', - searchColumns: ["filename"], - }); - - const searchItems = state.search ? items.filter(item => { - let returnItem = null; - state.searchColumns.forEach(column => { - if (item[column]?.toLowerCase()?.includes(state.search.toLowerCase())) - returnItem = item - }) - return returnItem - }) : items - - - const filteredItems = searchItems.filter((item) => { - let returnItem = item; - Object.entries(state.filters).forEach(filter => { - const [key, value] = filter - if (value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) - returnItem = null - if (value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) - returnItem = null - }) - return returnItem - }) - - const sortedItems = () => { - const sortColumn = state.sort.column - if (!sortColumn) { - return searchItems - } else { - return searchItems.sort((a, b) => { - if (typeof a[sortColumn] === "string") - return state.sort.direction === "asc" ? - a[sortColumn]?.localeCompare(b[sortColumn]) : - b[sortColumn]?.localeCompare(a[sortColumn]) - else - return state.sort.direction === "asc" ? - a[sortColumn] - b[sortColumn] : - b[sortColumn] - a[sortColumn] - }) - } - } - - const pagedItems = sortedItems().filter((item, i) => { - const pageSize = state.page * state.rowsPerPage - if ((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) - return item - }) - - const handleSearchItems = (filters) => { - setState(prevState => ({...prevState, search: filters, page: 0 })) - } - - - const handleFiltersChange = filters => { - setState(prevState => ({ - ...prevState, - filters - })); - }; - - const handleSortChange = sortDir => { - setState(prevState => ({ - ...prevState, - sortDir - })); - } - - const handlePageChange = (event, page) => { - setState(prevState => ({ - ...prevState, - page - })); - } - - const handleSort = (column, desc) => { - setState(prevState => ({ - ...prevState, sort: { - column, - direction: prevState.sort.column === column - ? prevState.sort.direction === "desc" - ? "asc" - : "desc" - : desc - ? "desc" - : "asc" - } - })) - } - - const handleRowsPerPageChange = event => { - setState(prevState => ({ - ...prevState, - rowsPerPage: parseInt(event.target.value, 10) - })); - } - - return { - handleFiltersChange, - handleSortChange, - handlePageChange, - handleRowsPerPageChange, - handleSearchItems, - pagedItems, - count: filteredItems.length, - state - }; -}; - -const Page = () => { - const [view, setView] = useState('grid'); - const [state, setState] = useState([]) - - const uploadDialog = useDialog(); - const detailsDialog = useDialog(); - const itemsSearch = useItemsSearch(state); - - usePageView(); - - useEffect(() => { - handleItemsGet(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - const handleDiscover = () => { - const toastId = toastLoad('Discovering terms ...') - ontologyTermsApi.discoverTerms() - .then(res => { - toastSuccess(`${res.task_name} successfully started.`, toastId) - }) - .catch(err => toastError(`Discovering terms failed: ${err.message}.`, toastId)) - }; - - const handleItemsGet = () => { - sectionApi.getOntologyFiles() - .then(res => setState(res)) - .catch(err => console.error(err)); - } - - const afterFileUpload = () => { - handleItemsGet() - handleDiscover() - } - - const handleItemGet = (name) => { - detailsDialog.handleOpen({load: true, fileName: name}) - sectionApi.getOntologyFile(name) - .then(res => detailsDialog.handleOpen({content: res.content, fileName: res.filename})) - .catch(err => console.log(err)); - } - - return ( - <> - - - - - -
- - {sectionApi.SECTION_TITLE} - -
- - - -
-
- - - - - - -
- - - - {detailsDialog.data?.fileName} - - - { - detailsDialog.data?.load ? - - - : - - {detailsDialog.data?.content} - - } - - - - - ); -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/ontology-terms-x/[id]/edit.js b/mapping_workbench/frontend/src/pages/app/ontology-terms-x/[id]/edit.js deleted file mode 100644 index e4f61575b..000000000 --- a/mapping_workbench/frontend/src/pages/app/ontology-terms-x/[id]/edit.js +++ /dev/null @@ -1,107 +0,0 @@ -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import Chip from '@mui/material/Chip'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; - -import {ontologyTermsApi as sectionApi} from 'src/api/ontology-terms'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {EditForm} from 'src/sections/app/ontology-term/edit-form'; -import {ForItemEditForm} from "src/contexts/app/section/for-item-form"; -import {useItem} from "src/contexts/app/section/for-item-data-state"; -import {useRouter} from "src/hooks/use-router"; - - -const Page = () => { - const router = useRouter(); - if (!router.isReady) return; - - const {id} = router.query; - - if (!id) { - return; - } - - const formState = useItem(sectionApi, id); - const item = formState.item; - - usePageView(); - - if (!item) { - return; - } - - return ( - <> - - - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
- - - - - {item.term} - - - - - - - -
- -
- - ); -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/ontology-terms-x/[id]/view.js b/mapping_workbench/frontend/src/pages/app/ontology-terms-x/[id]/view.js deleted file mode 100644 index 92a58665e..000000000 --- a/mapping_workbench/frontend/src/pages/app/ontology-terms-x/[id]/view.js +++ /dev/null @@ -1,149 +0,0 @@ -import {useCallback, useState} from 'react'; -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import Chip from '@mui/material/Chip'; -import Divider from '@mui/material/Divider'; -import Grid from '@mui/material/Unstable_Grid2'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Tab from '@mui/material/Tab'; -import Tabs from '@mui/material/Tabs'; -import Typography from '@mui/material/Typography'; - -import {ontologyTermsApi as sectionApi} from 'src/api/ontology-terms'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {BasicDetails} from 'src/sections/app/ontology-term/basic-details'; -import {useRouter} from "src/hooks/use-router"; -import {useItem} from "src/contexts/app/section/for-item-data-state"; - -const tabs = [ - {label: 'Details', value: 'details'} -]; - -const Page = () => { - const router = useRouter(); - const [currentTab, setCurrentTab] = useState('details'); - const {id} = router.query; - const formState = useItem(sectionApi, id); - - const item = formState.item; - usePageView(); - - const handleTabsChange = (event, value) => setCurrentTab(value); - - if (!item) { - return; - } - - return ( - <> - - - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
- - - - - {item.term} - - - - - - - -
- - {tabs.map((tab) => ( - - ))} - - -
-
- {currentTab === 'details' && ( -
- - - - - -
- )} -
- - ) -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/ontology-terms-x/create.js b/mapping_workbench/frontend/src/pages/app/ontology-terms-x/create.js deleted file mode 100644 index 9341bb966..000000000 --- a/mapping_workbench/frontend/src/pages/app/ontology-terms-x/create.js +++ /dev/null @@ -1,59 +0,0 @@ -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; - -import {paths} from 'src/paths'; -import {Seo} from 'src/components/seo'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {ontologyTermsApi as sectionApi} from 'src/api/ontology-terms'; -import {RouterLink} from 'src/components/router-link'; -import {usePageView} from 'src/hooks/use-page-view'; -import {EditForm} from 'src/sections/app/ontology-term/edit-form'; -import {ForItemCreateForm} from "src/contexts/app/section/for-item-form"; - - -const Page = () => { - let item = {}; - - usePageView(); - - return ( - <> - - - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
-
- -
- - ); -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/ontology-terms-x/index.js b/mapping_workbench/frontend/src/pages/app/ontology-terms-x/index.js deleted file mode 100644 index 527c2109c..000000000 --- a/mapping_workbench/frontend/src/pages/app/ontology-terms-x/index.js +++ /dev/null @@ -1,204 +0,0 @@ -import {useEffect, useState} from 'react'; -import PlusIcon from '@untitled-ui/icons-react/build/esm/Plus'; -import SearchIcon from '@untitled-ui/icons-react/build/esm/SearchRefraction'; -import Breadcrumbs from '@mui/material/Breadcrumbs'; -import Button from '@mui/material/Button'; -import Card from '@mui/material/Card'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; - -import {ontologyTermsApi as sectionApi} from 'src/api/ontology-terms'; -import {BreadcrumbsSeparator} from 'src/components/breadcrumbs-separator'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {ListSearch} from "../../../sections/app/ontology-term/list-search"; -import {ListTable} from "../../../sections/app/ontology-term/list-table"; -import {useRouter} from "../../../hooks/use-router"; -import {toastError, toastLoad, toastSuccess} from "../../../components/app-toast"; - -const useItemsSearch = () => { - const [state, setState] = useState({ - filters: { - name: undefined, - category: [], - status: [], - inStock: undefined - }, - sortField: '', - sortDirection: undefined, - page: sectionApi.DEFAULT_PAGE, - rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE - }); - - const handleFiltersChange = filters => { - setState(prevState => ({ - ...prevState, - filters, - page: 0 - })); - } - - const handlePageChange = (event, page) => { - setState(prevState => ({ - ...prevState, - page - })); - } - - const handleRowsPerPageChange = event => { - setState((prevState) => ({ - ...prevState, - rowsPerPage: parseInt(event.target.value, 10) - })); - } - - return { - handleFiltersChange, - handlePageChange, - handleRowsPerPageChange, - state - }; -}; - -const useItemsStore = (searchState) => { - const [state, setState] = useState({ - items: [], - itemsCount: 0 - }); - - const handleItemsGet = () => { - sectionApi.getItems(searchState) - .then(res => setState({ - items: res.items, - itemsCount: res.count - })) - .catch(err => console.warn(err)) - } - - useEffect(() => { - handleItemsGet(); - }, - // eslint-disable-next-line react-hooks/exhaustive-deps - [searchState]); - - return { - ...state - }; -}; - -const Page = () => { - const router = useRouter(); - const itemsSearch = useItemsSearch(); - const itemsStore = useItemsStore(itemsSearch.state); - - usePageView(); - - const handleDiscover = () => { - const toastId = toastLoad('Discovering terms ...') - sectionApi.discoverTerms() - .then(res => { - toastSuccess(`${res.task_name} successfully started.`, toastId) - router.reload() - }) - .catch(err => toastError(`Discovering terms failed: ${err.message}.`, toastId)) - }; - - return ( - <> - - - - - - {sectionApi.SECTION_TITLE} - - }> - - App - - - {sectionApi.SECTION_TITLE} - - - List - - - - - - - - - - - - - - - ) -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/ontology/index.js b/mapping_workbench/frontend/src/pages/app/ontology/index.js deleted file mode 100644 index fb1830f29..000000000 --- a/mapping_workbench/frontend/src/pages/app/ontology/index.js +++ /dev/null @@ -1,145 +0,0 @@ -import PlusIcon from '@untitled-ui/icons-react/build/esm/Plus'; -import SearchIcon from "@untitled-ui/icons-react/build/esm/SearchRefraction"; - -import Link from '@mui/material/Link'; -import Grid from "@mui/material/Grid"; -import Stack from '@mui/material/Stack'; -import Button from '@mui/material/Button'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; -import Breadcrumbs from '@mui/material/Breadcrumbs'; - -import {paths} from 'src/paths'; -import {Seo} from 'src/components/seo'; -import {useRouter} from "src/hooks/use-router"; -import {Layout as AppLayout} from 'src/layouts/app'; -import {RouterLink} from 'src/components/router-link'; -import {usePageView} from 'src/hooks/use-page-view'; -import OntologyTerms from "src/sections/app/ontology/ontology-terms"; -import {ontologyTermsApi as sectionApi} from 'src/api/ontology-terms'; -import {BreadcrumbsSeparator} from 'src/components/breadcrumbs-separator'; -import {toastError, toastLoad, toastSuccess} from "src/components/app-toast"; -import OntologyNamespaces from "src/sections/app/ontology/ontology-namespaces"; -import OntologyNamespacesCustom from "src/sections/app/ontology/ontology-namespaces-custom"; - - -const Page = () => { - - const router = useRouter() - const handleDiscover = () => { - const toastId = toastLoad('Discovering terms ...') - sectionApi.discoverTerms() - .then(res => { - toastSuccess(`${res.task_name} successfully started.`, toastId) - // router.reload() - }) - .catch(err => toastError(`Discovering terms failed: ${err.message}.`, toastId)) - }; - - usePageView(); - - return ( - <> - - - - - - - {sectionApi.SECTION_TITLE} - - }> - - App - - - {sectionApi.SECTION_TITLE} - - - List - - - - - - - - - - - - - - - - - - - - - - - ) -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/schema-files/index.js b/mapping_workbench/frontend/src/pages/app/schema-files/index.js deleted file mode 100644 index d1b6ad834..000000000 --- a/mapping_workbench/frontend/src/pages/app/schema-files/index.js +++ /dev/null @@ -1,293 +0,0 @@ -import {useEffect, useMemo, useState} from 'react'; - -import Upload01Icon from '@untitled-ui/icons-react/build/esm/Upload01'; -import Button from '@mui/material/Button'; -import Grid from '@mui/material/Unstable_Grid2'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; - -import {Seo} from 'src/components/seo'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {schemaFilesApi as sectionApi} from 'src/api/schema-files'; -import {useDialog} from 'src/hooks/use-dialog'; -import {usePageView} from 'src/hooks/use-page-view'; -import {FileUploader} from 'src/sections/app/files-form//file-uploader'; -import {ItemDrawer} from 'src/sections/app/file-manager/item-drawer'; -import {ItemSearch} from 'src/sections/app/files-form//item-search'; -import {schemaFileResourcesApi as fileResourcesApi} from "src/api/schema-files/file-resources"; -import {ItemList} from "src/sections/app/files-form/item-list"; -import {sessionApi} from "src/api/session"; -import Dialog from "@mui/material/Dialog"; -import DialogTitle from "@mui/material/DialogTitle"; -import DialogContent from "@mui/material/DialogContent"; -import {Box} from "@mui/system"; -import CircularProgress from "@mui/material/CircularProgress"; -import {Prism as SyntaxHighlighter} from "react-syntax-highlighter"; - - -const useItemsSearch = (items) => { - const [state, setState] = useState({ - filters: {}, - page: sectionApi.DEFAULT_PAGE, - rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE, - sort: { - column: "filename", - direction: "desc" - }, - search: '', - searchColumns:["filename"], - }); - - const searchItems = state.search ? items.filter(item => { - let returnItem = null; - state.searchColumns.forEach(column => { - if(item[column]?.toLowerCase()?.includes(state.search.toLowerCase())) - returnItem = item - }) - return returnItem - }) : items - - - const filteredItems = searchItems.filter((item) => { - let returnItem = item; - Object.entries(state.filters).forEach(filter=> { - const [key, value] = filter - if(value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) - returnItem = null - if(value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) - returnItem = null - }) - return returnItem - }) - - const sortedItems = () => { - const sortColumn = state.sort.column - if(!sortColumn) { - return searchItems - } else { - return searchItems.sort((a,b) => { - if (typeof a[sortColumn] === "string") - return state.sort.direction === "asc" ? - a[sortColumn]?.localeCompare(b[sortColumn]) : - b[sortColumn]?.localeCompare(a[sortColumn]) - else - return state.sort.direction === "asc" ? - a[sortColumn] - b[sortColumn] : - b[sortColumn] - a[sortColumn] - }) - } - } - - const pagedItems = sortedItems().filter((item, i) => { - const pageSize = state.page * state.rowsPerPage - if((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) - return item - }) - - const handleSearchItems = (filters) => { - setState(prevState => ({...prevState, search: filters, page: 0 })) - } - - - const handleFiltersChange = filters => { - setState(prevState => ({ - ...prevState, - filters - })); - }; - - const handleSortChange = sortDir => { - setState(prevState => ({ - ...prevState, - sortDir - })); - } - - const handlePageChange = (event, page) => { - setState(prevState => ({ - ...prevState, - page - })); - } - - const handleSort = (column, desc) => { - setState(prevState=> ({ ...prevState, sort: {column, - direction: prevState.sort.column === column - ? prevState.sort.direction === "desc" - ? "asc" - : "desc" - : desc - ? "desc" - : "asc"}})) - } - - const handleRowsPerPageChange = event => { - setState(prevState => ({ - ...prevState, - rowsPerPage: parseInt(event.target.value, 10) - })); - } - - return { - handleFiltersChange, - handleSortChange, - handlePageChange, - handleRowsPerPageChange, - handleSearchItems, - pagedItems, - count: filteredItems.length, - state - }; -}; - -const Page = () => { - const [view, setView] = useState('grid'); - const [state, setState] = useState([]) - - const uploadDialog = useDialog(); - const detailsDialog = useDialog(); - const itemsSearch = useItemsSearch(state); - - - usePageView(); - - useEffect(() => { - handleItemsGet(); - // eslint-disable-next-line react-hooks/exhaustive-deps - },[]); - - const handleItemsGet = () => { - sectionApi.getXSDFiles() - .then(res => setState(res)) - .catch(err => console.error(err)); - } - - const handleItemGet = (name) => { - detailsDialog.handleOpen({load: true, fileName: name}) - sectionApi.getXSDFile(name) - .then(res => detailsDialog.handleOpen({content: res.content, fileName: res.filename})) - .catch(err => console.log(err)); - } - - return ( - <> - - - - - -
- - {sectionApi.SECTION_TITLE} - -
- - - -
-
- - - - - - -
- - - {detailsDialog.data?.fileName} - - - { - detailsDialog.data?.load ? - - - : - - {detailsDialog.data?.content} - - } - - - - - - ); -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/[id]/edit.js b/mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/[id]/edit.js deleted file mode 100644 index ce46f7ccd..000000000 --- a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/[id]/edit.js +++ /dev/null @@ -1,109 +0,0 @@ -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import Box from '@mui/material/Box'; -import Chip from '@mui/material/Chip'; -import Container from '@mui/material/Container'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; - -import {tripleMapFragmentsApi as sectionApi} from 'src/api/triple-map-fragments'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {ForItemEditForm} from "src/contexts/app/section/for-item-form"; -import {useItem} from "src/contexts/app/section/for-item-data-state"; -import {useRouter} from "src/hooks/use-router"; -import {EditForm} from "../../../../sections/app/triple-map-fragment/edit-form"; - - -const Page = () => { - const router = useRouter(); - if (!router.isReady) return; - - const {id} = router.query; - - if (!id) { - return; - } - - const formState = useItem(sectionApi, id); - const item = formState.item; - - usePageView(); - - if (!item) { - return; - } - - return ( - <> - - - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
- - - - - {item.triple_map_uri} - - - - - - - -
- -
- - ); -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/[id]/view.js b/mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/[id]/view.js deleted file mode 100644 index d36f1be47..000000000 --- a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/[id]/view.js +++ /dev/null @@ -1,154 +0,0 @@ -import {useCallback, useState} from 'react'; -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import Box from '@mui/material/Box'; -import Chip from '@mui/material/Chip'; -import Container from '@mui/material/Container'; -import Divider from '@mui/material/Divider'; -import Grid from '@mui/material/Unstable_Grid2'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Tab from '@mui/material/Tab'; -import Tabs from '@mui/material/Tabs'; -import Typography from '@mui/material/Typography'; - -import {tripleMapFragmentsApi as sectionApi} from 'src/api/triple-map-fragments'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {useRouter} from "src/hooks/use-router"; -import {useItem} from "src/contexts/app/section/for-item-data-state"; - -const tabs = [ - {label: 'Details', value: 'details'} -]; - -const Page = () => { - const router = useRouter(); - if (!router.isReady) return; - - const {id} = router.query; - - if (!id) { - return; - } - - const formState = useItem(sectionApi, id); - const item = formState.item; - - usePageView(); - const [currentTab, setCurrentTab] = useState('details'); - - const handleTabsChange = useCallback((event, value) => { - setCurrentTab(value); - }, []); - - if (!item) { - return; - } - - return ( - <> - - - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
- - - - - {item.title} - - - - - - - -
- - {tabs.map((tab) => ( - - ))} - - -
-
- {currentTab === 'details' && ( -
- - - - - -
- )} -
- - ) -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/create.js b/mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/create.js deleted file mode 100644 index 4de99368a..000000000 --- a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/create.js +++ /dev/null @@ -1,61 +0,0 @@ -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import Box from '@mui/material/Box'; -import Container from '@mui/material/Container'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; - -import {tripleMapFragmentsApi as sectionApi} from 'src/api/triple-map-fragments'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {EditForm} from 'src/sections/app/triple-map-fragment/edit-form'; -import {ForItemCreateForm} from "src/contexts/app/section/for-item-form"; - - -const Page = () => { - let item = {}; - - usePageView(); - - return ( - <> - - - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
-
- -
- - ); -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/index.js b/mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/index.js deleted file mode 100644 index 9141bf518..000000000 --- a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-x/index.js +++ /dev/null @@ -1,185 +0,0 @@ -import {useCallback, useEffect, useState} from 'react'; -import PlusIcon from '@untitled-ui/icons-react/build/esm/Plus'; -import Box from '@mui/material/Box'; -import Breadcrumbs from '@mui/material/Breadcrumbs'; -import Button from '@mui/material/Button'; -import Card from '@mui/material/Card'; -import Container from '@mui/material/Container'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; - -import {tripleMapFragmentsApi as sectionApi} from 'src/api/triple-map-fragments'; -import {BreadcrumbsSeparator} from 'src/components/breadcrumbs-separator'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {ListSearch} from "../../../sections/app/triple-map-fragment/list-search"; -import {ListTable} from "../../../sections/app/triple-map-fragment/list-table"; -import {useMounted} from "../../../hooks/use-mounted"; - -const useItemsSearch = () => { - const [state, setState] = useState({ - filters: { - name: undefined, - category: [], - status: [], - inStock: undefined - }, - page: 0, - rowsPerPage: 5 - }); - - const handleFiltersChange = useCallback((filters) => { - setState((prevState) => ({ - ...prevState, - filters - })); - }, []); - - const handlePageChange = useCallback((event, page) => { - setState((prevState) => ({ - ...prevState, - page - })); - }, []); - - const handleRowsPerPageChange = useCallback((event) => { - setState((prevState) => ({ - ...prevState, - rowsPerPage: parseInt(event.target.value, 10) - })); - }, []); - - return { - handleFiltersChange, - handlePageChange, - handleRowsPerPageChange, - state - }; -}; - - -const useItemsStore = (searchState) => { - const isMounted = useMounted(); - const [state, setState] = useState({ - items: [], - itemsCount: 0 - }); - - const handleItemsGet = useCallback(async () => { - try { - const response = await sectionApi.getItems(searchState); - if (isMounted()) { - setState({ - items: response.items, - itemsCount: response.count - }); - } - } catch (err) { - console.error(err); - } - }, [searchState, isMounted]); - - useEffect(() => { - handleItemsGet(); - }, - // eslint-disable-next-line react-hooks/exhaustive-deps - [searchState]); - - return { - ...state - }; -}; - - -const Page = () => { - const itemsSearch = useItemsSearch(); - const itemsStore = useItemsStore(itemsSearch.state); - - usePageView(); - - return ( - <> - - - - - - {sectionApi.SECTION_TITLE} - - }> - - App - - - {sectionApi.SECTION_TITLE} - - - List - - - - - - - - - - - - - - ) -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/[id]/edit.js b/mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/[id]/edit.js deleted file mode 100644 index 7c4538eff..000000000 --- a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/[id]/edit.js +++ /dev/null @@ -1,107 +0,0 @@ -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import Chip from '@mui/material/Chip'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; - -import {specificTripleMapFragmentsApi as sectionApi} from 'src/api/triple-map-fragments/specific'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {ForItemEditForm} from "src/contexts/app/section/for-item-form"; -import {useItem} from "src/contexts/app/section/for-item-data-state"; -import {useRouter} from "src/hooks/use-router"; -import {EditForm} from "../../../../sections/app/specific-triple-map-fragment/edit-form"; - - -const Page = () => { - const router = useRouter(); - if (!router.isReady) return; - - const {id} = router.query; - - if (!id) { - return; - } - - const formState = useItem(sectionApi, id); - const item = formState.item; - - usePageView(); - - if (!item) { - return; - } - - return ( - <> - - - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
- - - - - {item.triple_map_uri} - - - - - - - -
- -
- - ); -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/[id]/view.js b/mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/[id]/view.js deleted file mode 100644 index 34f9c284d..000000000 --- a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/[id]/view.js +++ /dev/null @@ -1,154 +0,0 @@ -import {useCallback, useState} from 'react'; -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import Box from '@mui/material/Box'; -import Chip from '@mui/material/Chip'; -import Container from '@mui/material/Container'; -import Divider from '@mui/material/Divider'; -import Grid from '@mui/material/Unstable_Grid2'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Tab from '@mui/material/Tab'; -import Tabs from '@mui/material/Tabs'; -import Typography from '@mui/material/Typography'; - -import {specificTripleMapFragmentsApi as sectionApi} from 'src/api/triple-map-fragments/specific'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {useRouter} from "src/hooks/use-router"; -import {useItem} from "src/contexts/app/section/for-item-data-state"; - -const tabs = [ - {label: 'Details', value: 'details'} -]; - -const Page = () => { - const router = useRouter(); - if (!router.isReady) return; - - const {id} = router.query; - - if (!id) { - return; - } - - const formState = useItem(sectionApi, id); - const item = formState.item; - - usePageView(); - const [currentTab, setCurrentTab] = useState('details'); - - const handleTabsChange = useCallback((event, value) => { - setCurrentTab(value); - }, []); - - if (!item) { - return; - } - - return ( - <> - - - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
- - - - - {item.title} - - - - - - - -
- - {tabs.map((tab) => ( - - ))} - - -
-
- {currentTab === 'details' && ( -
- - - - - -
- )} -
- - ) -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/create.js b/mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/create.js deleted file mode 100644 index 3154db0ba..000000000 --- a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/create.js +++ /dev/null @@ -1,59 +0,0 @@ -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; - -import {specificTripleMapFragmentsApi as sectionApi} from 'src/api/triple-map-fragments/specific'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {EditForm} from 'src/sections/app/specific-triple-map-fragment/edit-form'; -import {ForItemCreateForm} from "src/contexts/app/section/for-item-form"; - - -const Page = () => { - let item = {}; - - usePageView(); - - return ( - <> - - - -
- - - - - - {sectionApi.SECTION_TITLE} - - -
-
- -
- - ); -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/index.js b/mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/index.js deleted file mode 100644 index 6e8dcc581..000000000 --- a/mapping_workbench/frontend/src/pages/app/triple-map-fragments-xx/index.js +++ /dev/null @@ -1,183 +0,0 @@ -import {useEffect, useState} from 'react'; -import PlusIcon from '@untitled-ui/icons-react/build/esm/Plus'; -import Breadcrumbs from '@mui/material/Breadcrumbs'; -import Button from '@mui/material/Button'; -import Card from '@mui/material/Card'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; - -import {specificTripleMapFragmentsApi as sectionApi} from 'src/api/triple-map-fragments/specific'; -import {BreadcrumbsSeparator} from 'src/components/breadcrumbs-separator'; -import {RouterLink} from 'src/components/router-link'; -import {Seo} from 'src/components/seo'; -import {usePageView} from 'src/hooks/use-page-view'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {paths} from 'src/paths'; -import {ListSearch} from "../../../sections/app/specific-triple-map-fragment/list-search"; -import {ListTable} from "../../../sections/app/specific-triple-map-fragment/list-table"; - -const useItemsSearch = () => { - const [state, setState] = useState({ - filters: { - name: undefined, - category: [], - status: [], - inStock: undefined - }, - sortDirection: undefined, - sortField: '', - page: sectionApi.DEFAULT_PAGE, - rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE - }); - - const handleFiltersChange = filters => { - setState((prevState) => ({ - ...prevState, - filters, - page: 0 - })); - } - - const handlePageChange = (event, page) => { - setState((prevState) => ({ - ...prevState, - page - })); - } - - const handleRowsPerPageChange = event => { - setState((prevState) => ({ - ...prevState, - rowsPerPage: parseInt(event.target.value, 10) - })); - } - - const handleSorterChange = sortField => { - setState(prevState => ({ - ...prevState, - sortField, - sortDirection: state.sortField === sortField && prevState.sortDirection === -1 ? 1 : -1 - })) - } - - return { - handleSorterChange, - handleFiltersChange, - handlePageChange, - handleRowsPerPageChange, - state - }; -}; - - -const useItemsStore = searchState => { - const [state, setState] = useState({ - items: [], - itemsCount: 0 - }); - - const handleItemsGet = () => { - sectionApi.getItems(searchState) - .then(res => setState({ - items: res.items, - itemsCount: res.count - })) - .catch(err => console.error(err)) - } - - useEffect(() => { - handleItemsGet(); - }, - // eslint-disable-next-line react-hooks/exhaustive-deps - [searchState]); - - return { - ...state - }; -}; - - -const Page = () => { - const itemsSearch = useItemsSearch(); - const itemsStore = useItemsStore(itemsSearch.state); - - usePageView(); - - return ( - <> - - - - - - {sectionApi.SECTION_TITLE} - - }> - - App - - - {sectionApi.SECTION_TITLE} - - - - - - - - - - - - - - ) -}; - -Page.getLayout = (page) => ( - - {page} - -); - -export default Page; diff --git a/mapping_workbench/frontend/src/sections/app/ontology-namespace/list-table.js b/mapping_workbench/frontend/src/sections/app/ontology-namespace/list-table.js index 64300ae0c..17df00c67 100644 --- a/mapping_workbench/frontend/src/sections/app/ontology-namespace/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/ontology-namespace/list-table.js @@ -1,13 +1,12 @@ import PropTypes from 'prop-types'; + import Table from '@mui/material/Table'; +import Switch from "@mui/material/Switch"; +import TableRow from '@mui/material/TableRow'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; -import TableSortLabel from '@mui/material/TableSortLabel'; import TableHead from '@mui/material/TableHead'; -import TableRow from '@mui/material/TableRow'; import Typography from '@mui/material/Typography'; -import Tooltip from "@mui/material/Tooltip"; -import Switch from "@mui/material/Switch"; import {Scrollbar} from 'src/components/scrollbar'; import {ListItemActions} from 'src/components/app/list/list-item-actions'; From 016050fa83df8ef72393e6aa7fddb923e0510a11 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Fri, 20 Sep 2024 10:53:30 +0300 Subject: [PATCH 02/35] MWB-798: update projects tests --- mapping_workbench/frontend/cypress.config.js | 20 +++++------ .../frontend/cypress/e2e/projects.feature | 12 +++---- .../cypress/e2e/projects/projectSteps.js | 33 ++++++++++--------- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/mapping_workbench/frontend/cypress.config.js b/mapping_workbench/frontend/cypress.config.js index a86f0d0be..548533dbf 100644 --- a/mapping_workbench/frontend/cypress.config.js +++ b/mapping_workbench/frontend/cypress.config.js @@ -27,22 +27,22 @@ module.exports = defineConfig({ // "cypress/e2e/scenarioOne.feature", // "cypress/e2e/scenarioTwo.feature", // "cypress/e2e/cleanUp.feature", - // "cypress/e2e/projects.feature", - // "cypress/e2e/projectCreate.feature", + "cypress/e2e/projects.feature", + "cypress/e2e/projectCreate.feature", //Project Setup - // "cypress/e2e/ontologyFiles.feature", - // "cypress/e2e/testDataSuites.feature", + "cypress/e2e/ontologyFiles.feature", + "cypress/e2e/testDataSuites.feature", //Mapping Entities - // "cypress/e2e/ontologyTerms.feature", + "cypress/e2e/ontologyTerms.feature", "cypress/e2e/fieldsDevelop.feature", "cypress/e2e/fieldsTree.feature", - // "cypress/e2e/fieldsOverview.feature", + "cypress/e2e/fieldsOverview.feature", //Technical Mappings - // "cypress/e2e/valueMappingResources.feature", - // "cypress/e2e/tripleMapFragments.feature", + "cypress/e2e/valueMappingResources.feature", + "cypress/e2e/tripleMapFragments.feature", //Quality Control - // "cypress/e2e/sparqlTestSuites.feature", - // "cypress/e2e/shaclTestSuites.feature", + "cypress/e2e/sparqlTestSuites.feature", + "cypress/e2e/shaclTestSuites.feature", //Mapping Packages "cypress/e2e/mappingPackages.feature", //Activities diff --git a/mapping_workbench/frontend/cypress/e2e/projects.feature b/mapping_workbench/frontend/cypress/e2e/projects.feature index 0c50cebc4..72f277625 100644 --- a/mapping_workbench/frontend/cypress/e2e/projects.feature +++ b/mapping_workbench/frontend/cypress/e2e/projects.feature @@ -5,13 +5,12 @@ Feature: Entry Projects Scenario: Create Project Given Session Login Then Go Home - Then I click on projects + Then Visit Projects Then I get redirected to projects list page When I click on add project button Then I get redirected to projects create page Then I type project name -# Then I uncheck checkboxes When I click create button Then I get success created @@ -19,7 +18,7 @@ Feature: Entry Projects Given Session Login Then Go Home - When I click on projects + Then Visit Projects Then I get redirected to projects list page Then I search for project @@ -29,7 +28,8 @@ Feature: Entry Projects Scenario: Edit Project Given Session Login Then Go Home - Then I click on projects + + Then Visit Projects Then I get redirected to projects list page Then I search for project @@ -44,7 +44,7 @@ Feature: Entry Projects Given Session Login Then Go Home - Then I click on projects + Then Visit Projects Then I get redirected to projects list page Then I search for project @@ -57,7 +57,7 @@ Feature: Entry Projects Given Session Login Then Go Home - Then I click on projects + Then Visit Projects Then I get redirected to projects list page Then I search for project diff --git a/mapping_workbench/frontend/cypress/e2e/projects/projectSteps.js b/mapping_workbench/frontend/cypress/e2e/projects/projectSteps.js index e867e3245..03c46e69b 100644 --- a/mapping_workbench/frontend/cypress/e2e/projects/projectSteps.js +++ b/mapping_workbench/frontend/cypress/e2e/projects/projectSteps.js @@ -1,23 +1,26 @@ import {Given, Then, When} from "cypress-cucumber-preprocessor/steps"; -const {username, password, homeURL, appURLPrefix, projectName} = Cypress.env() +const {username, password, homeURL, appURLPrefix, projectName, homePageLabel} = Cypress.env() const projectDescription = 'some description' Given('Session Login', () => { // Caching session when logging in via page visit - cy.session([username,password], () => { + cy.session([username, password], () => { cy.visit(homeURL) cy.get('[name=username]').clear().type(username) cy.get('[name=password]').clear().type(password) cy.get('button[type="submit"]').click() - cy.title().should('eq','App: Projects List | Mapping Workbench') + cy.title().should('eq', homePageLabel) }) }) +Then('Visit Projects', () => { + cy.visit(homeURL + '/app/projects') +}) Then('I get redirected to projects list page', () => { - cy.title().should('eq','App: Projects List | Mapping Workbench') + cy.title().should('eq', 'App: Projects List | Mapping Workbench') }) When('I click on add project button', () => { @@ -26,7 +29,7 @@ When('I click on add project button', () => { Then('I get redirected to projects create page', () => { - cy.title().should('eq','App: Project Create | Mapping Workbench') + cy.title().should('eq', 'App: Project Create | Mapping Workbench') }) @@ -43,11 +46,11 @@ Then('I uncheck checkboxes', () => { When('I click create button', () => { cy.intercept('POST', appURLPrefix + 'projects').as('create') - cy.get('#create_button').click() + cy.get('#create_button').click('right') }) Then('I get success created', () => { - cy.wait('@create').its('response.statusCode').should('eq',201) + cy.wait('@create').its('response.statusCode').should('eq', 201) }) When('I click back to projects link', () => { @@ -60,7 +63,7 @@ Then('I search for project', () => { }) Then('I receive project', () => { - cy.wait('@get').its('response.statusCode').should('eq',200) + cy.wait('@get').its('response.statusCode').should('eq', 200) }) When('I select project', () => { @@ -69,7 +72,7 @@ When('I select project', () => { }) Then('I get success select', () => { - cy.wait('@select').its('response.statusCode').should('eq',200) + cy.wait('@select').its('response.statusCode').should('eq', 200) }) //edit project @@ -78,7 +81,7 @@ When('I click on edit button', () => { }) Then('I get redirected to project edit page', () => { - cy.url().should('include','/edit') + cy.url().should('include', '/edit') }) Then('I update project description', () => { @@ -87,11 +90,11 @@ Then('I update project description', () => { Then('I click on update button', () => { cy.intercept('PATCH', appURLPrefix + 'projects/*',).as('updateProject') - cy.get('#create_button').click() + cy.get('#create_button').click('right') }) Then('I receive update success', () => { - cy.wait('@updateProject').its('response.statusCode').should('eq',200) + cy.wait('@updateProject').its('response.statusCode').should('eq', 200) }) //edit project @@ -100,11 +103,11 @@ When('I click on view button', () => { }) Then('I get redirected to project view page', () => { - cy.url().should('include','/view') + cy.url().should('include', '/view') }) Then('I read description', () => { - cy.get('h6:contains("Description")').first().next().should('have.text', projectDescription+'\n') + cy.get('h6:contains("Description")').first().next().should('have.text', projectDescription + '\n') }) //delete project @@ -118,5 +121,5 @@ Then('I click yes button', () => { }) Then('I get success delete', () => { - cy.wait('@delete').its('response.statusCode').should('eq',200) + cy.wait('@delete').its('response.statusCode').should('eq', 200) }) From 1e82a8af46b61519c27736d2244db6573751ae84 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Fri, 20 Sep 2024 12:44:28 +0300 Subject: [PATCH 03/35] MWB-798: update ontology files and terms --- mapping_workbench/frontend/cypress.config.js | 2 +- .../cypress/e2e/ontologyTerms.feature | 45 +++++++++---------- .../e2e/ontologyTerms/ontologyTermsSteps.js | 4 +- .../cypress/e2e/projectCreate/projectSteps.js | 9 ++-- 4 files changed, 28 insertions(+), 32 deletions(-) diff --git a/mapping_workbench/frontend/cypress.config.js b/mapping_workbench/frontend/cypress.config.js index 548533dbf..15b766da8 100644 --- a/mapping_workbench/frontend/cypress.config.js +++ b/mapping_workbench/frontend/cypress.config.js @@ -31,9 +31,9 @@ module.exports = defineConfig({ "cypress/e2e/projectCreate.feature", //Project Setup "cypress/e2e/ontologyFiles.feature", + "cypress/e2e/ontologyTerms.feature", "cypress/e2e/testDataSuites.feature", //Mapping Entities - "cypress/e2e/ontologyTerms.feature", "cypress/e2e/fieldsDevelop.feature", "cypress/e2e/fieldsTree.feature", "cypress/e2e/fieldsOverview.feature", diff --git a/mapping_workbench/frontend/cypress/e2e/ontologyTerms.feature b/mapping_workbench/frontend/cypress/e2e/ontologyTerms.feature index 285f7a4b2..a81ecdda1 100644 --- a/mapping_workbench/frontend/cypress/e2e/ontologyTerms.feature +++ b/mapping_workbench/frontend/cypress/e2e/ontologyTerms.feature @@ -31,35 +31,32 @@ Feature: Ontology Terms Then I enter name of Ontology Term Then I successfully create Ontology Terms - Scenario: Update Ontology Term - When I click on Ontology Terms - Then I get redirected to Ontology Terms - - Then I search for Ontology Terms - Then I receive Ontology Terms - - Then I click edit button - Then I get redirected to edit page - - When I enter updated name - Then I get success update - - Scenario: View Ontology Term - When I click on Ontology Terms - Then I get redirected to Ontology Terms - - Then I search for updated Ontology Terms - Then I receive Ontology Terms +# Scenario: Update Ontology Term +# When I click on Ontology Terms +# Then I get redirected to Ontology Terms +# +# Then I search for Ontology Terms +# +# Then I click edit button +# Then I get redirected to edit page +# +# When I enter updated name +# Then I get success update - When I click on view button - Then I get redirected to view page - Then I receive Ontology Term data +# Scenario: View Ontology Term +# When I click on Ontology Terms +# Then I get redirected to Ontology Terms +# +# Then I search for updated Ontology Terms +# +# When I click on view button +# Then I get redirected to view page +# Then I receive Ontology Term data Scenario: Delete Ontology Term When I click on Ontology Terms Then I get redirected to Ontology Terms - Then I search for updated Ontology Terms - Then I receive Ontology Terms + Then I search for Ontology Terms Then I click delete button Then I get success delete \ No newline at end of file diff --git a/mapping_workbench/frontend/cypress/e2e/ontologyTerms/ontologyTermsSteps.js b/mapping_workbench/frontend/cypress/e2e/ontologyTerms/ontologyTermsSteps.js index 7c34426b5..42dcefbdb 100644 --- a/mapping_workbench/frontend/cypress/e2e/ontologyTerms/ontologyTermsSteps.js +++ b/mapping_workbench/frontend/cypress/e2e/ontologyTerms/ontologyTermsSteps.js @@ -24,13 +24,13 @@ Then('I get success select', () => { //DISCOVER Then('I get redirected to Ontology Terms', () => { - cy.url().should('include','ontology') + cy.url().should('include','ontology-terms') cy.wait('@get').its('response.statusCode').should('eq', 200) }) Then('I click on Ontology Terms', () => { cy.intercept('GET', appURLPrefix + 'ontology/terms*').as('get') - cy.get('#nav_mapping_entities').click() + cy.get('#nav_project_setup').click() cy.get('#nav_ontology_terms').click() }) diff --git a/mapping_workbench/frontend/cypress/e2e/projectCreate/projectSteps.js b/mapping_workbench/frontend/cypress/e2e/projectCreate/projectSteps.js index 0b8a96392..1e1bc427a 100644 --- a/mapping_workbench/frontend/cypress/e2e/projectCreate/projectSteps.js +++ b/mapping_workbench/frontend/cypress/e2e/projectCreate/projectSteps.js @@ -1,6 +1,6 @@ import {Given, Then, When} from "cypress-cucumber-preprocessor/steps"; -const {username, password, homeURL, appURLPrefix, projectName} = Cypress.env() +const {username, password, homeURL, appURLPrefix, projectName, homePageLabel} = Cypress.env() Given('Session Login', () => { // Caching session when logging in via page visit @@ -9,7 +9,7 @@ Given('Session Login', () => { cy.get('[name=username]').clear().type(username) cy.get('[name=password]').clear().type(password) cy.get('button[type="submit"]').click() - cy.title().should('eq','Mapping Workbench') + cy.title().should('eq', homePageLabel) }) }) @@ -19,7 +19,7 @@ Then('I get redirected to projects list page', () => { Then('I select create project from project switch', () => { cy.get('#project_switch').click() - cy.get('#create_project_button').click() + cy.get('#create_project_button').click('right') }) When('I click on add project button', () => { @@ -40,12 +40,11 @@ Then('I uncheck checkboxes', () => { cy.get('input[name=automatically_discover_namespaces]').uncheck() cy.get('input[name=add_specific_namespaces]').uncheck() cy.get('input[name="import_eform.checked"]').uncheck() - }) When('I click create button', () => { cy.intercept('POST', appURLPrefix + 'projects').as('create') - cy.get('#create_button').click() + cy.get('#create_button').click('right') }) Then('I get success created', () => { From 2b12877099757f1ccb74cf96e0a9605bd82f0d60 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Fri, 20 Sep 2024 14:03:51 +0300 Subject: [PATCH 04/35] MWB-798: fix fields overview tests --- mapping_workbench/frontend/cypress.config.js | 2 +- .../cypress/e2e/fieldsOverview/fieldsOverviewSteps.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mapping_workbench/frontend/cypress.config.js b/mapping_workbench/frontend/cypress.config.js index 15b766da8..9f99330c0 100644 --- a/mapping_workbench/frontend/cypress.config.js +++ b/mapping_workbench/frontend/cypress.config.js @@ -33,7 +33,7 @@ module.exports = defineConfig({ "cypress/e2e/ontologyFiles.feature", "cypress/e2e/ontologyTerms.feature", "cypress/e2e/testDataSuites.feature", - //Mapping Entities + //Fields & Nodes "cypress/e2e/fieldsDevelop.feature", "cypress/e2e/fieldsTree.feature", "cypress/e2e/fieldsOverview.feature", diff --git a/mapping_workbench/frontend/cypress/e2e/fieldsOverview/fieldsOverviewSteps.js b/mapping_workbench/frontend/cypress/e2e/fieldsOverview/fieldsOverviewSteps.js index acdf1b6e8..0a97ce48e 100644 --- a/mapping_workbench/frontend/cypress/e2e/fieldsOverview/fieldsOverviewSteps.js +++ b/mapping_workbench/frontend/cypress/e2e/fieldsOverview/fieldsOverviewSteps.js @@ -28,8 +28,8 @@ Then('Check home title', () => { Given('I click on Fields Overview', () => { cy.intercept('GET', appURLPrefix + 'fields_registry/elements*',).as('getFields') - cy.get('#nav_mapping_entities').click() - cy.get('#nav_fields_overview').click() + cy.get('#nav_fields_\\&_nodes').click() + cy.get(':nth-child(2) > #nav_overview').click() }) @@ -38,7 +38,7 @@ When('I click on import schema button', () => { }) Then('I get redirected to field registry import page', () => { - cy.url().should('include','fields-overview/import') + cy.url().should('include','fields-and-nodes/overview/import') }) Then('I type git url', () => { @@ -61,7 +61,7 @@ Then('I get success import', () => { Then('I get redirected to Fields Overview', () => { - cy.url().should('include','fields-overview') + cy.url().should('include','fields-and-nodes/overview') }) And('I receive fields', () => { From 654cdb31176c4dd21775bba531eb20b1b771e345 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Fri, 20 Sep 2024 15:19:52 +0300 Subject: [PATCH 05/35] MWB-798: add tests for CM --- mapping_workbench/frontend/cypress.config.js | 4 +++ .../e2e/conceptualMappingsDevelop.feature | 12 +++++++ .../conceptualMappingsDevelopSteps.js | 30 ++++++++++++++++++ .../e2e/conceptualMappingsOverview.feature | 12 +++++++ .../conceptualMappingsOverviewSteps.js | 31 +++++++++++++++++++ .../e2e/conceptualMappingsReview.feature | 12 +++++++ .../conceptualMappingsReviewSteps.js | 30 ++++++++++++++++++ 7 files changed, 131 insertions(+) create mode 100644 mapping_workbench/frontend/cypress/e2e/conceptualMappingsDevelop.feature create mode 100644 mapping_workbench/frontend/cypress/e2e/conceptualMappingsDevelop/conceptualMappingsDevelopSteps.js create mode 100644 mapping_workbench/frontend/cypress/e2e/conceptualMappingsOverview.feature create mode 100644 mapping_workbench/frontend/cypress/e2e/conceptualMappingsOverview/conceptualMappingsOverviewSteps.js create mode 100644 mapping_workbench/frontend/cypress/e2e/conceptualMappingsReview.feature create mode 100644 mapping_workbench/frontend/cypress/e2e/conceptualMappingsReview/conceptualMappingsReviewSteps.js diff --git a/mapping_workbench/frontend/cypress.config.js b/mapping_workbench/frontend/cypress.config.js index 9f99330c0..10ef01502 100644 --- a/mapping_workbench/frontend/cypress.config.js +++ b/mapping_workbench/frontend/cypress.config.js @@ -37,6 +37,10 @@ module.exports = defineConfig({ "cypress/e2e/fieldsDevelop.feature", "cypress/e2e/fieldsTree.feature", "cypress/e2e/fieldsOverview.feature", + //ConceptualMappings + "cypress/e2e/conceptualMappingsDevelop.feature", + "cypress/e2e/conceptualMappingsReview.feature", + "cypress/e2e/conceptualMappingsOverview.feature", //Technical Mappings "cypress/e2e/valueMappingResources.feature", "cypress/e2e/tripleMapFragments.feature", diff --git a/mapping_workbench/frontend/cypress/e2e/conceptualMappingsDevelop.feature b/mapping_workbench/frontend/cypress/e2e/conceptualMappingsDevelop.feature new file mode 100644 index 000000000..537d3be60 --- /dev/null +++ b/mapping_workbench/frontend/cypress/e2e/conceptualMappingsDevelop.feature @@ -0,0 +1,12 @@ +Feature: Conceptual Mappings Rules Develop + + As a valid use i want to see Conceptual Mappings Rules Develop + + Background: + Given Session Login + Then Go Home + Then I open side menu + + Scenario: View Conceptual Mapping + Then I click on CM Develop + Then I get Redirected to CM Develop \ No newline at end of file diff --git a/mapping_workbench/frontend/cypress/e2e/conceptualMappingsDevelop/conceptualMappingsDevelopSteps.js b/mapping_workbench/frontend/cypress/e2e/conceptualMappingsDevelop/conceptualMappingsDevelopSteps.js new file mode 100644 index 000000000..56eec7408 --- /dev/null +++ b/mapping_workbench/frontend/cypress/e2e/conceptualMappingsDevelop/conceptualMappingsDevelopSteps.js @@ -0,0 +1,30 @@ +import {Given, When, Then} from 'cypress-cucumber-preprocessor/steps' + +const {username, password, homeURL, appURLPrefix, projectName, gitUrl, branchVersion, homePageLabel} = Cypress.env() + +let sessionProject = '' + +Given('Session Login', () => { + // Caching session when logging in via page visit + cy.session([username, password], () => { + cy.visit(homeURL) + cy.get('[name=username]').clear().type(username) + cy.get('[name=password]').clear().type(password) + cy.get('button[type="submit"]').click() + cy.title().should('eq', homePageLabel) + }) + if (sessionProject) cy.window().then(win => win.sessionStorage.setItem('sessionProject', sessionProject)) +}) + + +When('I click on CM Develop', () => { + cy.intercept('GET', appURLPrefix + 'conceptual_mapping_rules*',).as('get') + cy.get('#nav_conceptual_mappings').click(); + cy.get(':nth-child(1) > #nav_develop').eq(1).click(); +}) + + +Then('I get Redirected to CM Develop', () => { + cy.wait('@get').its('response.statusCode').should('eq', 200) + cy.url().should('include', 'conceptual-mapping-rules/develop') +}) \ No newline at end of file diff --git a/mapping_workbench/frontend/cypress/e2e/conceptualMappingsOverview.feature b/mapping_workbench/frontend/cypress/e2e/conceptualMappingsOverview.feature new file mode 100644 index 000000000..579126dcc --- /dev/null +++ b/mapping_workbench/frontend/cypress/e2e/conceptualMappingsOverview.feature @@ -0,0 +1,12 @@ +Feature: Conceptual Mappings Rules Overview + + As a valid use i want to see Conceptual Mappings Rules Overview + + Background: + Given Session Login + Then Go Home + Then I open side menu + + Scenario: View Conceptual Mapping + Then I click on CM Overview + Then I get Redirected to CM Overview \ No newline at end of file diff --git a/mapping_workbench/frontend/cypress/e2e/conceptualMappingsOverview/conceptualMappingsOverviewSteps.js b/mapping_workbench/frontend/cypress/e2e/conceptualMappingsOverview/conceptualMappingsOverviewSteps.js new file mode 100644 index 000000000..139a0b2da --- /dev/null +++ b/mapping_workbench/frontend/cypress/e2e/conceptualMappingsOverview/conceptualMappingsOverviewSteps.js @@ -0,0 +1,31 @@ +import {Given, When, Then} from 'cypress-cucumber-preprocessor/steps' + +const {username, password, homeURL, appURLPrefix, projectName, gitUrl, branchVersion, homePageLabel} = Cypress.env() + +let sessionProject = '' + +Given('Session Login', () => { + // Caching session when logging in via page visit + cy.session([username, password], () => { + cy.visit(homeURL) + cy.get('[name=username]').clear().type(username) + cy.get('[name=password]').clear().type(password) + cy.get('button[type="submit"]').click() + cy.title().should('eq', homePageLabel) + }) + if (sessionProject) cy.window().then(win => win.sessionStorage.setItem('sessionProject', sessionProject)) +}) + + +When('I click on CM Overview', () => { + cy.intercept('GET', appURLPrefix + 'conceptual_mapping_rules*',).as('get') + cy.get('#nav_conceptual_mappings').click(); + cy.get(':nth-child(3) > #nav_overview').click(); +}) + + +Then('I get Redirected to CM Overview', () => { + cy.wait('@get').its('response.statusCode').should('eq', 200) + cy.url().should('include', 'conceptual-mapping-rules/overview') + +}) \ No newline at end of file diff --git a/mapping_workbench/frontend/cypress/e2e/conceptualMappingsReview.feature b/mapping_workbench/frontend/cypress/e2e/conceptualMappingsReview.feature new file mode 100644 index 000000000..bd1fcc5fc --- /dev/null +++ b/mapping_workbench/frontend/cypress/e2e/conceptualMappingsReview.feature @@ -0,0 +1,12 @@ +Feature: Conceptual Mappings Rules Review + + As a valid use i want to see Conceptual Mappings Rules Review + + Background: + Given Session Login + Then Go Home + Then I open side menu + + Scenario: View Conceptual Mapping + Then I click on CM Review + Then I get Redirected to CM Review \ No newline at end of file diff --git a/mapping_workbench/frontend/cypress/e2e/conceptualMappingsReview/conceptualMappingsReviewSteps.js b/mapping_workbench/frontend/cypress/e2e/conceptualMappingsReview/conceptualMappingsReviewSteps.js new file mode 100644 index 000000000..13d6f1b20 --- /dev/null +++ b/mapping_workbench/frontend/cypress/e2e/conceptualMappingsReview/conceptualMappingsReviewSteps.js @@ -0,0 +1,30 @@ +import {Given, When, Then} from 'cypress-cucumber-preprocessor/steps' + +const {username, password, homeURL, appURLPrefix, projectName, gitUrl, branchVersion, homePageLabel} = Cypress.env() + +let sessionProject = '' + +Given('Session Login', () => { + // Caching session when logging in via page visit + cy.session([username, password], () => { + cy.visit(homeURL) + cy.get('[name=username]').clear().type(username) + cy.get('[name=password]').clear().type(password) + cy.get('button[type="submit"]').click() + cy.title().should('eq', homePageLabel) + }) + if (sessionProject) cy.window().then(win => win.sessionStorage.setItem('sessionProject', sessionProject)) +}) + + +When('I click on CM Review', () => { + cy.intercept('GET', appURLPrefix + 'conceptual_mapping_rules*',).as('get') + cy.get('#nav_conceptual_mappings').click(); + cy.get('#nav_review').click(); +}) + + +Then('I get Redirected to CM Review', () => { + cy.wait('@get').its('response.statusCode').should('eq', 200) + cy.url().should('include', 'conceptual-mapping-rules/review') +}) \ No newline at end of file From c0c6f571a3ad6234b76e170ca536778323d5ee10 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Fri, 20 Sep 2024 15:24:07 +0300 Subject: [PATCH 06/35] MWB-798: fix triple map fragments --- .../frontend/cypress/e2e/tripleMapFragments.feature | 2 -- .../cypress/e2e/tripleMapFragments/tripleMapFragments.js | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/mapping_workbench/frontend/cypress/e2e/tripleMapFragments.feature b/mapping_workbench/frontend/cypress/e2e/tripleMapFragments.feature index ddf625f5b..4bd9c991c 100644 --- a/mapping_workbench/frontend/cypress/e2e/tripleMapFragments.feature +++ b/mapping_workbench/frontend/cypress/e2e/tripleMapFragments.feature @@ -29,7 +29,6 @@ Feature: Specific Triple Maps Then I get redirected to Specific Triple Maps Then I search for Specific Triple Map - Then I receive Specific Triple Maps Then I click edit button Then I get redirected to edit page @@ -41,6 +40,5 @@ Feature: Specific Triple Maps Then I get redirected to Specific Triple Maps Then I search for updated Specific Triple Map - Then I receive Specific Triple Maps Then I click delete button Then I get success delete \ No newline at end of file diff --git a/mapping_workbench/frontend/cypress/e2e/tripleMapFragments/tripleMapFragments.js b/mapping_workbench/frontend/cypress/e2e/tripleMapFragments/tripleMapFragments.js index 48bbecc7b..5c5b2655d 100644 --- a/mapping_workbench/frontend/cypress/e2e/tripleMapFragments/tripleMapFragments.js +++ b/mapping_workbench/frontend/cypress/e2e/tripleMapFragments/tripleMapFragments.js @@ -55,7 +55,7 @@ Then('I enter name', () => { cy.get("input[name=mapping_package_id]").parent().click() .get('ul.MuiList-root').click() cy.get("input[name=triple_map_uri]").clear().type(specificTripleMapName) - cy.get("button[type=submit]").click() + cy.get("button[type=submit]").click('right') }) From 17a22bc32a13410528a7ff9263c84852219a9b24 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Fri, 20 Sep 2024 15:25:49 +0300 Subject: [PATCH 07/35] MWB-798: fix sparql test suites --- .../sparqlTestSuites/sparqlTestSuitesSteps.js | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/mapping_workbench/frontend/cypress/e2e/sparqlTestSuites/sparqlTestSuitesSteps.js b/mapping_workbench/frontend/cypress/e2e/sparqlTestSuites/sparqlTestSuitesSteps.js index a869bb51a..af8bbb0ef 100644 --- a/mapping_workbench/frontend/cypress/e2e/sparqlTestSuites/sparqlTestSuitesSteps.js +++ b/mapping_workbench/frontend/cypress/e2e/sparqlTestSuites/sparqlTestSuitesSteps.js @@ -1,25 +1,25 @@ -import { Given, When, Then} from 'cypress-cucumber-preprocessor/steps' +import {Given, When, Then} from 'cypress-cucumber-preprocessor/steps' -const {username, password, homeURL, appURLPrefix, projectName} = Cypress.env() +const {username, password, homeURL, appURLPrefix, projectName, homePageLabel} = Cypress.env() const sparql_suite_name = 'test_suite' let sessionProject = '' Given('Session Login', () => { // Caching session when logging in via page visit - cy.session([username,password], () => { + cy.session([username, password], () => { cy.visit(homeURL) cy.get('[name=username]').clear().type(username) cy.get('[name=password]').clear().type(password) cy.get('button[type="submit"]').click() - cy.title().should('eq','Mapping Workbench') + cy.title().should('eq', homePageLabel) }) - if(sessionProject) cy.window().then(win => win.sessionStorage.setItem('sessionProject',sessionProject)) + if (sessionProject) cy.window().then(win => win.sessionStorage.setItem('sessionProject', sessionProject)) }) Then('I get success select', () => { - cy.wait('@select').its('response.statusCode').should('eq',200) + cy.wait('@select').its('response.statusCode').should('eq', 200) cy.window().then(win => sessionProject = win.sessionStorage.getItem('sessionProject')) }) @@ -32,7 +32,7 @@ Then('I click on Sparql Test Suites', () => { }) Then('I get redirected to Sparql Test Suites', () => { - cy.url().should('include','sparql-test-suites') + cy.url().should('include', 'sparql-test-suites') cy.wait('@get').its('response.statusCode').should('eq', 200) }) @@ -41,14 +41,14 @@ Then('I click on add button', () => { }) Then('I get redirected to create page', () => { - cy.url().should('include','sparql-test-suites/create') // => true + cy.url().should('include', 'sparql-test-suites/create') // => true }) Then('I enter name', () => { cy.intercept('POST', appURLPrefix + "sparql_test_suites").as('create') cy.get("input[name=title]").clear().type(sparql_suite_name) - cy.get("button[type=submit]").click() + cy.get("button[type=submit]").click('right') }) @@ -59,7 +59,7 @@ Then('I successfully create suite', () => { // update Then('I search for suite', () => { - cy.get('input[type=text]').clear().type(sparql_suite_name+'{enter}') + cy.get('input[type=text]').clear().type(sparql_suite_name + '{enter}') }) Then('I receive suite', () => { @@ -71,12 +71,12 @@ Then('I click edit button', () => { }) Then('I get redirected to edit page', () => { - cy.url().should('include','/edit') // => true + cy.url().should('include', '/edit') // => true }) Then('I enter updated name', () => { cy.intercept('PATCH', appURLPrefix + 'sparql_test_suites/*').as('update') - cy.get("input[name=title]").clear().type(sparql_suite_name + 1 +'{enter}') + cy.get("input[name=title]").clear().type(sparql_suite_name + 1 + '{enter}') }) Then('I get success update', () => { @@ -88,7 +88,7 @@ Then('I search for updated suite', () => { }) Then('I click delete button', () => { - cy.intercept('DELETE',appURLPrefix + 'sparql_test_suites/*').as('delete') + cy.intercept('DELETE', appURLPrefix + 'sparql_test_suites/*').as('delete') cy.get('#delete_button').click() cy.get('#yes_dialog_button').click() }) From 6422df5e78352654611adc2fe7bbe8de8f35fd3a Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Fri, 20 Sep 2024 15:28:18 +0300 Subject: [PATCH 08/35] MWB-798: fix shacl test suites --- .../cypress/e2e/shaclTestSuites/shaclTestSuitesSteps.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mapping_workbench/frontend/cypress/e2e/shaclTestSuites/shaclTestSuitesSteps.js b/mapping_workbench/frontend/cypress/e2e/shaclTestSuites/shaclTestSuitesSteps.js index fafc2eb8b..afa62800e 100644 --- a/mapping_workbench/frontend/cypress/e2e/shaclTestSuites/shaclTestSuitesSteps.js +++ b/mapping_workbench/frontend/cypress/e2e/shaclTestSuites/shaclTestSuitesSteps.js @@ -1,6 +1,6 @@ import { Given, When, Then} from 'cypress-cucumber-preprocessor/steps' -const {username, password, homeURL, appURLPrefix, projectName} = Cypress.env() +const {username, password, homeURL, appURLPrefix, projectName, homePageLabel} = Cypress.env() const shacl_suite_name = 'test_suite' let sessionProject = '' @@ -12,7 +12,7 @@ Given('Session Login', () => { cy.get('[name=username]').clear().type(username) cy.get('[name=password]').clear().type(password) cy.get('button[type="submit"]').click() - cy.title().should('eq','Mapping Workbench') + cy.title().should('eq',homePageLabel) }) if(sessionProject) cy.window().then(win => win.sessionStorage.setItem('sessionProject',sessionProject)) }) @@ -48,7 +48,7 @@ Then('I get redirected to create page', () => { Then('I enter name', () => { cy.intercept('POST', appURLPrefix + "shacl_test_suites").as('create') cy.get("input[name=title]").clear().type(shacl_suite_name) - cy.get("button[type=submit]").click() + cy.get("button[type=submit]").click('right') }) From ba87cc6fee16b02018710a08363d951541bfa667 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Mon, 23 Sep 2024 13:34:39 +0300 Subject: [PATCH 09/35] MWB-798: update files --- .../[id]/states/[sid]/view.js | 10 +- .../src/pages/app/ontology-files/index.js | 311 ++++++++++++++++++ .../frontend/src/pages/app/tasks/index.js | 4 +- .../app/fields-and-nodes/xpath-evaluator.js | 2 +- .../coverage_files.js | 10 +- .../list-table-file.js | 2 +- .../app/shacl-validation-report/list-table.js | 212 ++++++++++++ .../result-summary-table.js | 0 .../result-table.js | 0 .../shacl_validation_report_file.js | 0 .../shacl_validation_report_package_state.js | 0 .../shacl_validation_report_test_dataset.js | 0 .../shacl_validation_report_view.js | 0 .../utils.js | 4 +- .../app/shacl_validation_report/list-table.js | 207 ------------ .../coverage_files.js | 10 +- .../list-table-file.js | 0 .../list-table.js | 0 .../query-result-table.js | 0 .../result-summary-table.js | 0 .../sparql_validation_report_file.js | 0 .../sparql_validation_report_package_state.js | 0 .../sparql_validation_report_test_dataset.js | 0 .../sparql_validation_report_view.js | 4 +- .../utils.js | 14 +- .../src/sections/app/tree-view/tree-view.js | 2 +- .../coverage_files.js | 0 .../coverage_report.js | 0 .../list-table-file.js | 0 .../list-table.js | 0 .../utils.js | 0 .../xpath_validation_report_file.js | 0 .../xpath_validation_report_package_state.js | 0 .../xpath_validation_report_test_dataset.js | 0 .../xpath_validation_report_view.js | 0 35 files changed, 551 insertions(+), 241 deletions(-) create mode 100644 mapping_workbench/frontend/src/pages/app/ontology-files/index.js rename mapping_workbench/frontend/src/sections/app/{shacl_validation_report => shacl-validation-report}/coverage_files.js (99%) rename mapping_workbench/frontend/src/sections/app/{shacl_validation_report => shacl-validation-report}/list-table-file.js (100%) create mode 100644 mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js rename mapping_workbench/frontend/src/sections/app/{shacl_validation_report => shacl-validation-report}/result-summary-table.js (100%) rename mapping_workbench/frontend/src/sections/app/{shacl_validation_report => shacl-validation-report}/result-table.js (100%) rename mapping_workbench/frontend/src/sections/app/{shacl_validation_report => shacl-validation-report}/shacl_validation_report_file.js (100%) rename mapping_workbench/frontend/src/sections/app/{shacl_validation_report => shacl-validation-report}/shacl_validation_report_package_state.js (100%) rename mapping_workbench/frontend/src/sections/app/{shacl_validation_report => shacl-validation-report}/shacl_validation_report_test_dataset.js (100%) rename mapping_workbench/frontend/src/sections/app/{shacl_validation_report => shacl-validation-report}/shacl_validation_report_view.js (100%) rename mapping_workbench/frontend/src/sections/app/{shacl_validation_report => shacl-validation-report}/utils.js (100%) delete mode 100644 mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js rename mapping_workbench/frontend/src/sections/app/{xpath_validation_report => sparql-validation-report}/coverage_files.js (99%) rename mapping_workbench/frontend/src/sections/app/{sparql_validation_report => sparql-validation-report}/list-table-file.js (100%) rename mapping_workbench/frontend/src/sections/app/{sparql_validation_report => sparql-validation-report}/list-table.js (100%) rename mapping_workbench/frontend/src/sections/app/{sparql_validation_report => sparql-validation-report}/query-result-table.js (100%) rename mapping_workbench/frontend/src/sections/app/{sparql_validation_report => sparql-validation-report}/result-summary-table.js (100%) rename mapping_workbench/frontend/src/sections/app/{sparql_validation_report => sparql-validation-report}/sparql_validation_report_file.js (100%) rename mapping_workbench/frontend/src/sections/app/{sparql_validation_report => sparql-validation-report}/sparql_validation_report_package_state.js (100%) rename mapping_workbench/frontend/src/sections/app/{sparql_validation_report => sparql-validation-report}/sparql_validation_report_test_dataset.js (100%) rename mapping_workbench/frontend/src/sections/app/{sparql_validation_report => sparql-validation-report}/sparql_validation_report_view.js (100%) rename mapping_workbench/frontend/src/sections/app/{sparql_validation_report => sparql-validation-report}/utils.js (97%) rename mapping_workbench/frontend/src/sections/app/{sparql_validation_report => xpath-validation-report}/coverage_files.js (100%) rename mapping_workbench/frontend/src/sections/app/{xpath_validation_report => xpath-validation-report}/coverage_report.js (100%) rename mapping_workbench/frontend/src/sections/app/{xpath_validation_report => xpath-validation-report}/list-table-file.js (100%) rename mapping_workbench/frontend/src/sections/app/{xpath_validation_report => xpath-validation-report}/list-table.js (100%) rename mapping_workbench/frontend/src/sections/app/{xpath_validation_report => xpath-validation-report}/utils.js (100%) rename mapping_workbench/frontend/src/sections/app/{xpath_validation_report => xpath-validation-report}/xpath_validation_report_file.js (100%) rename mapping_workbench/frontend/src/sections/app/{xpath_validation_report => xpath-validation-report}/xpath_validation_report_package_state.js (100%) rename mapping_workbench/frontend/src/sections/app/{xpath_validation_report => xpath-validation-report}/xpath_validation_report_test_dataset.js (100%) rename mapping_workbench/frontend/src/sections/app/{xpath_validation_report => xpath-validation-report}/xpath_validation_report_view.js (100%) diff --git a/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js b/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js index 2cdf87f40..7672f360f 100644 --- a/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js +++ b/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js @@ -22,16 +22,16 @@ import {mappingPackageStatesApi as sectionApi} from 'src/api/mapping-packages/st import {mappingPackagesApi as previousSectionApi} from 'src/api/mapping-packages'; import {useRouter} from "src/hooks/use-router"; import {RouterLink} from 'src/components/router-link'; -import exportPackage from "../../../../../../utils/export-mapping-package"; +import exportPackage from "src/utils/export-mapping-package"; const StateDetails = - dynamic(() => import("../../../../../../sections/app/mapping-package/state/state-details")); + dynamic(() => import("src/sections/app/mapping-package/state/state-details")); const ShaclValidationReport = - dynamic(() => import("../../../../../../sections/app/shacl_validation_report/shacl_validation_report_view")); + dynamic(() => import("src/sections/app/shacl-validation-report/shacl_validation_report_view")); const SparqlValidationReport = - dynamic(() => import("../../../../../../sections/app/sparql_validation_report/sparql_validation_report_view")); + dynamic(() => import("src/sections/app/sparql-validation-report/sparql_validation_report_view")); const XpathValidationReportView = - dynamic(() => import("../../../../../../sections/app/xpath_validation_report/xpath_validation_report_view")); + dynamic(() => import("src/sections/app/xpath-validation-report/xpath_validation_report_view")); const tabs = [ {label: 'Details', value: 'details'}, diff --git a/mapping_workbench/frontend/src/pages/app/ontology-files/index.js b/mapping_workbench/frontend/src/pages/app/ontology-files/index.js new file mode 100644 index 000000000..a560812bc --- /dev/null +++ b/mapping_workbench/frontend/src/pages/app/ontology-files/index.js @@ -0,0 +1,311 @@ +import {useEffect, useState} from 'react'; + +import Upload01Icon from '@untitled-ui/icons-react/build/esm/Upload01'; +import Button from '@mui/material/Button'; +import Grid from '@mui/material/Unstable_Grid2'; +import Stack from '@mui/material/Stack'; +import SvgIcon from '@mui/material/SvgIcon'; +import Typography from '@mui/material/Typography'; +import Dialog from "@mui/material/Dialog"; +import DialogTitle from "@mui/material/DialogTitle"; +import DialogContent from "@mui/material/DialogContent"; + +import {Seo} from 'src/components/seo'; +import {Layout as AppLayout} from 'src/layouts/app'; +import {ontologyFilesApi as sectionApi} from 'src/api/ontology-files'; +import {ontologyTermsApi} from "../../../api/ontology-terms"; +import {useDialog} from 'src/hooks/use-dialog'; +import {usePageView} from 'src/hooks/use-page-view'; +import {FileUploader} from 'src/sections/app/files-form//file-uploader'; +import {ItemSearch} from 'src/sections/app/files-form//item-search'; +import {ontologyFileResourcesApi as fileResourcesApi} from "src/api/ontology-files/file-resources"; +import {ItemList} from "src/sections/app/files-form/item-list"; +import {sessionApi} from "src/api/session"; + +import {Prism as SyntaxHighlighter} from "react-syntax-highlighter"; +import CircularProgress from "@mui/material/CircularProgress"; +import {Box} from "@mui/system"; +import {toastError, toastLoad, toastSuccess} from "../../../components/app-toast"; + +const useItemsSearch = (items) => { + const [state, setState] = useState({ + filters: {}, + page: sectionApi.DEFAULT_PAGE, + rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE, + sort: { + column: "filename", + direction: "desc" + }, + search: '', + searchColumns: ["filename"], + }); + + const searchItems = state.search ? items.filter(item => { + let returnItem = null; + state.searchColumns.forEach(column => { + if (item[column]?.toLowerCase()?.includes(state.search.toLowerCase())) + returnItem = item + }) + return returnItem + }) : items + + + const filteredItems = searchItems.filter((item) => { + let returnItem = item; + Object.entries(state.filters).forEach(filter => { + const [key, value] = filter + if (value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) + returnItem = null + if (value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) + returnItem = null + }) + return returnItem + }) + + const sortedItems = () => { + const sortColumn = state.sort.column + if (!sortColumn) { + return searchItems + } else { + return searchItems.sort((a, b) => { + if (typeof a[sortColumn] === "string") + return state.sort.direction === "asc" ? + a[sortColumn]?.localeCompare(b[sortColumn]) : + b[sortColumn]?.localeCompare(a[sortColumn]) + else + return state.sort.direction === "asc" ? + a[sortColumn] - b[sortColumn] : + b[sortColumn] - a[sortColumn] + }) + } + } + + const pagedItems = sortedItems().filter((item, i) => { + const pageSize = state.page * state.rowsPerPage + if ((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) + return item + }) + + const handleSearchItems = (filters) => { + setState(prevState => ({...prevState, search: filters, page: 0 })) + } + + + const handleFiltersChange = filters => { + setState(prevState => ({ + ...prevState, + filters + })); + }; + + const handleSortChange = sortDir => { + setState(prevState => ({ + ...prevState, + sortDir + })); + } + + const handlePageChange = (event, page) => { + setState(prevState => ({ + ...prevState, + page + })); + } + + const handleSort = (column, desc) => { + setState(prevState => ({ + ...prevState, sort: { + column, + direction: prevState.sort.column === column + ? prevState.sort.direction === "desc" + ? "asc" + : "desc" + : desc + ? "desc" + : "asc" + } + })) + } + + const handleRowsPerPageChange = event => { + setState(prevState => ({ + ...prevState, + rowsPerPage: parseInt(event.target.value, 10) + })); + } + + return { + handleFiltersChange, + handleSortChange, + handlePageChange, + handleRowsPerPageChange, + handleSearchItems, + pagedItems, + count: filteredItems.length, + state + }; +}; + +const Page = () => { + const [view, setView] = useState('grid'); + const [state, setState] = useState([]) + + const uploadDialog = useDialog(); + const detailsDialog = useDialog(); + const itemsSearch = useItemsSearch(state); + + usePageView(); + + useEffect(() => { + handleItemsGet(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const handleDiscover = () => { + const toastId = toastLoad('Discovering terms ...') + ontologyTermsApi.discoverTerms() + .then(res => { + toastSuccess(`${res.task_name} successfully started.`, toastId) + }) + .catch(err => toastError(`Discovering terms failed: ${err.message}.`, toastId)) + }; + + const handleItemsGet = () => { + sectionApi.getOntologyFiles() + .then(res => setState(res)) + .catch(err => console.error(err)); + } + + const afterFileUpload = () => { + handleItemsGet() + handleDiscover() + } + + const handleItemGet = (name) => { + detailsDialog.handleOpen({load: true, fileName: name}) + sectionApi.getOntologyFile(name) + .then(res => detailsDialog.handleOpen({content: res.content, fileName: res.filename})) + .catch(err => console.log(err)); + } + + return ( + <> + + + + + +
+ + {sectionApi.SECTION_TITLE} + +
+ + + +
+
+ + + + + + +
+ + + + {detailsDialog.data?.fileName} + + + { + detailsDialog.data?.load ? + + + : + + {detailsDialog.data?.content} + + } + + + + + ); +}; + +Page.getLayout = (page) => ( + + {page} + +); + +export default Page; \ No newline at end of file diff --git a/mapping_workbench/frontend/src/pages/app/tasks/index.js b/mapping_workbench/frontend/src/pages/app/tasks/index.js index 7e31be002..9840834db 100644 --- a/mapping_workbench/frontend/src/pages/app/tasks/index.js +++ b/mapping_workbench/frontend/src/pages/app/tasks/index.js @@ -20,8 +20,8 @@ import {Seo} from 'src/components/seo'; import {ListSearch} from 'src/sections/app/tasks/list-search'; import {ListTable} from 'src/sections/app/tasks/list-table'; -import {TableLoadWrapper} from "../../../sections/app/shacl_validation_report/utils"; -import {toastError, toastLoad, toastSuccess} from "../../../components/app-toast"; +import {TableLoadWrapper} from "src/sections/app/shacl-validation-report/utils"; +import {toastError, toastLoad, toastSuccess} from "src/components/app-toast"; const useItemsSearch = (items) => { const [state, setState] = useState({ diff --git a/mapping_workbench/frontend/src/sections/app/fields-and-nodes/xpath-evaluator.js b/mapping_workbench/frontend/src/sections/app/fields-and-nodes/xpath-evaluator.js index 1c0248c76..f72623cc2 100644 --- a/mapping_workbench/frontend/src/sections/app/fields-and-nodes/xpath-evaluator.js +++ b/mapping_workbench/frontend/src/sections/app/fields-and-nodes/xpath-evaluator.js @@ -12,7 +12,7 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import AccordionSummary from "@mui/material/AccordionSummary"; import AccordionDetails from "@mui/material/AccordionDetails"; -import {TableNoData} from "../shacl_validation_report/utils"; +import {TableNoData} from "../shacl-validation-report/utils"; const XpathEvaluator = ({xmlDoc, absolute_xpath}) => { const [nodes, setNodes] = useState([]) diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/coverage_files.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/coverage_files.js similarity index 99% rename from mapping_workbench/frontend/src/sections/app/shacl_validation_report/coverage_files.js rename to mapping_workbench/frontend/src/sections/app/shacl-validation-report/coverage_files.js index 703cb7efe..fe59dd241 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/coverage_files.js +++ b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/coverage_files.js @@ -1,13 +1,11 @@ import List from "@mui/material/List"; import ListItem from "@mui/material/ListItem"; -import ListItemButton from "@mui/material/ListItemButton"; -import ListItemText from "@mui/material/ListItemText"; import Typography from "@mui/material/Typography"; - -import FolderIcon from '@mui/icons-material/FolderOpen'; -import FileIcon from '@mui/icons-material/Description'; - +import ListItemText from "@mui/material/ListItemText"; import ListItemIcon from "@mui/material/ListItemIcon"; +import FileIcon from '@mui/icons-material/Description'; +import FolderIcon from '@mui/icons-material/FolderOpen'; +import ListItemButton from "@mui/material/ListItemButton"; const CoverageFiles = ({files, fileIcon, onClick}) => { return ( diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table-file.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table-file.js rename to mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table-file.js index 5a9650d22..9469a92af 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table-file.js +++ b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table-file.js @@ -5,9 +5,9 @@ import PropTypes from 'prop-types'; import Table from '@mui/material/Table'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; - import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; + import {SorterHeader as UtilsSorterHeader} from "./utils"; import {Scrollbar} from 'src/components/scrollbar'; import TablePagination from '../../components/table-pagination'; diff --git a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js new file mode 100644 index 000000000..1049a7389 --- /dev/null +++ b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js @@ -0,0 +1,212 @@ +import {useState} from "react"; +import PropTypes from 'prop-types'; + +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; +import Button from "@mui/material/Button"; +import Dialog from '@mui/material/Dialog'; +import DialogTitle from "@mui/material/DialogTitle"; +import DialogContent from "@mui/material/DialogContent"; +import DialogActions from "@mui/material/DialogActions"; +import Stack from "@mui/material/Stack"; + +import {Scrollbar} from 'src/components/scrollbar'; +import {ResultChip, SorterHeader as UtilsSorterHeader} from "./utils"; +import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; +import TablePagination from "../../components/table-pagination"; + +export const ListTable = (props) => { + const [descriptionDialog, setDescriptionDialog] = useState({open: false, title: "", text: ""}) + + const { + count = 0, + items = [], + onPageChange, + onRowsPerPageChange, + page = 0, + rowsPerPage = 0, + sort, + onSort, + sectionApi + } = props; + + const mapNotices = (notices) => { + return ( +
    + {notices.map((notice, i) => +
  • + {`${notice.test_data_suite_id} / ${notice.test_data_id}`} +
  • )} +
+ ) + } + + const handleOpenDetails = ({title, notices}) => { + const description = mapNotices(notices) + setDescriptionDialog({open: true, title, description}); + } + + const handleClose = () => { + setDescriptionDialog(e => ({...e, open: false})); + }; + + const SorterHeader = (props) => + + const ResultCell = ({title, result, onClick}) => { + return + {result.count} + {!!result.count && } + + } + + return ( + <> + + + + + + + + + + + + + + + + + } + desc/> + + + } + desc/> + + + } + desc/> + + + } + desc/> + + + + + {items?.map((item, key) => { + return ( + + + {item.shacl_suite} + + + {0} + + + + {item.short_result_path} + + + + + + + + + + + + + + + + + ); + })} + +
+
+
+ + + {descriptionDialog.title} + + + {descriptionDialog.description} + + + + + + + ); +}; + +ListTable.propTypes = { + count: PropTypes.number, + items: PropTypes.array, + onPageChange: PropTypes.func, + onRowsPerPageChange: PropTypes.func, + page: PropTypes.number, + rowsPerPage: PropTypes.number +}; diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/result-summary-table.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/result-summary-table.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/shacl_validation_report/result-summary-table.js rename to mapping_workbench/frontend/src/sections/app/shacl-validation-report/result-summary-table.js diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/result-table.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/result-table.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/shacl_validation_report/result-table.js rename to mapping_workbench/frontend/src/sections/app/shacl-validation-report/result-table.js diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_file.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/shacl_validation_report_file.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_file.js rename to mapping_workbench/frontend/src/sections/app/shacl-validation-report/shacl_validation_report_file.js diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_package_state.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/shacl_validation_report_package_state.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_package_state.js rename to mapping_workbench/frontend/src/sections/app/shacl-validation-report/shacl_validation_report_package_state.js diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_test_dataset.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/shacl_validation_report_test_dataset.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_test_dataset.js rename to mapping_workbench/frontend/src/sections/app/shacl-validation-report/shacl_validation_report_test_dataset.js diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_view.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/shacl_validation_report_view.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_view.js rename to mapping_workbench/frontend/src/sections/app/shacl-validation-report/shacl_validation_report_view.js diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/utils.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/utils.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/shacl_validation_report/utils.js rename to mapping_workbench/frontend/src/sections/app/shacl-validation-report/utils.js index 5912fe005..1fff86367 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/utils.js +++ b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/utils.js @@ -1,9 +1,9 @@ import Chip from "@mui/material/Chip"; import Stack from "@mui/material/Stack"; +import Alert from "@mui/material/Alert"; import Tooltip from "@mui/material/Tooltip"; -import TableSortLabel from "@mui/material/TableSortLabel"; import Skeleton from "@mui/material/Skeleton"; -import Alert from "@mui/material/Alert"; +import TableSortLabel from "@mui/material/TableSortLabel"; export const resultColor = (result) => { switch (result.toLowerCase()) { diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js deleted file mode 100644 index 59dcbe168..000000000 --- a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js +++ /dev/null @@ -1,207 +0,0 @@ -import {useState} from "react"; -import PropTypes from 'prop-types'; - -import Table from '@mui/material/Table'; -import TableBody from '@mui/material/TableBody'; -import TableCell from '@mui/material/TableCell'; -import TableHead from '@mui/material/TableHead'; -import TableRow from '@mui/material/TableRow'; -import Button from "@mui/material/Button"; -import Dialog from '@mui/material/Dialog'; -import DialogTitle from "@mui/material/DialogTitle"; -import DialogContent from "@mui/material/DialogContent"; -import DialogActions from "@mui/material/DialogActions"; -import Stack from "@mui/material/Stack"; - -import {Scrollbar} from 'src/components/scrollbar'; -import {ResultChip, SorterHeader as UtilsSorterHeader} from "./utils"; -import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; -import TablePagination from "../../components/table-pagination"; - -export const ListTable = (props) => { - const [descriptionDialog, setDescriptionDialog] = useState({open:false, title:"", text:""}) - - const { - count = 0, - items = [], - onPageChange, - onRowsPerPageChange, - page = 0, - rowsPerPage = 0, - sort, - onSort, - sectionApi - } = props; - - const mapNotices = (notices) => { - return( -
    - {notices.map((notice,i) => -
  • - {`${notice.test_data_suite_id} / ${notice.test_data_id}`} -
  • )} -
- ) - } - - const handleOpenDetails = ({title, notices}) => { - const description = mapNotices(notices) - setDescriptionDialog({open: true, title, description}); - } - - const handleClose = () => { - setDescriptionDialog(e=>({...e, open: false})); - }; - - const SorterHeader = (props) => - - const ResultCell = ({title, result, onClick}) => { - return - {result.count} - {!!result.count && } - - } - - return ( - <> - - - - - - - - - - - - - - - - - } - desc/> - - - } - desc/> - - - } - desc/> - - - } - desc/> - - - - - {items?.map((item, key) => { - return ( - - - {item.shacl_suite} - - - {0} - - - - {item.short_result_path} - - - - - - - - - - - - - - - - - ); - })} - -
-
-
- - - {descriptionDialog.title} - - - {descriptionDialog.description} - - - - - - - ); -}; - -ListTable.propTypes = { - count: PropTypes.number, - items: PropTypes.array, - onPageChange: PropTypes.func, - onRowsPerPageChange: PropTypes.func, - page: PropTypes.number, - rowsPerPage: PropTypes.number -}; diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/coverage_files.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/coverage_files.js similarity index 99% rename from mapping_workbench/frontend/src/sections/app/xpath_validation_report/coverage_files.js rename to mapping_workbench/frontend/src/sections/app/sparql-validation-report/coverage_files.js index 3b7299f54..3f177e8bc 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/coverage_files.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/coverage_files.js @@ -1,13 +1,11 @@ import List from "@mui/material/List"; import ListItem from "@mui/material/ListItem"; -import ListItemButton from "@mui/material/ListItemButton"; -import ListItemText from "@mui/material/ListItemText"; import Typography from "@mui/material/Typography"; - -import FolderIcon from '@mui/icons-material/FolderOpen'; -import FileIcon from '@mui/icons-material/Description'; - +import ListItemText from "@mui/material/ListItemText"; import ListItemIcon from "@mui/material/ListItemIcon"; +import FileIcon from '@mui/icons-material/Description'; +import FolderIcon from '@mui/icons-material/FolderOpen'; +import ListItemButton from "@mui/material/ListItemButton"; const CoverageFiles = ({files, fileIcon, onClick}) => { return ( diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/sparql_validation_report/list-table-file.js rename to mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/list-table.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/sparql_validation_report/list-table.js rename to mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/query-result-table.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/query-result-table.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/sparql_validation_report/query-result-table.js rename to mapping_workbench/frontend/src/sections/app/sparql-validation-report/query-result-table.js diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/result-summary-table.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/result-summary-table.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/sparql_validation_report/result-summary-table.js rename to mapping_workbench/frontend/src/sections/app/sparql-validation-report/result-summary-table.js diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_file.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_file.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_file.js rename to mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_file.js diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_package_state.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_package_state.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_package_state.js rename to mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_package_state.js diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_test_dataset.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_test_dataset.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_test_dataset.js rename to mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_test_dataset.js diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_view.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js rename to mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_view.js index 21de8406d..23890ce59 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_view.js @@ -1,10 +1,10 @@ import {useState} from "react"; +import Link from "@mui/material/Link"; import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; import Breadcrumbs from "@mui/material/Breadcrumbs"; import KeyboardArrowRightIcon from "@mui/icons-material/KeyboardArrowRight"; -import Link from "@mui/material/Link"; -import Typography from "@mui/material/Typography"; import CoverageFiles from "./coverage_files"; import SparqlPackageStateReport from "./sparql_validation_report_package_state"; diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/utils.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/utils.js similarity index 97% rename from mapping_workbench/frontend/src/sections/app/sparql_validation_report/utils.js rename to mapping_workbench/frontend/src/sections/app/sparql-validation-report/utils.js index bd52253f6..c1e55efcd 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/utils.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/utils.js @@ -1,17 +1,15 @@ +import {Box} from "@mui/system"; import Chip from "@mui/material/Chip"; import Stack from "@mui/material/Stack"; -import Typography from "@mui/material/Typography"; -import {Box} from "@mui/system"; import Paper from "@mui/material/Paper"; -import FormControlLabel from "@mui/material/FormControlLabel"; import Radio from "@mui/material/Radio"; -import RadioGroup from "@mui/material/RadioGroup"; +import Alert from "@mui/material/Alert"; import Tooltip from "@mui/material/Tooltip"; -import TableSortLabel from "@mui/material/TableSortLabel"; import Skeleton from "@mui/material/Skeleton"; -import Alert from "@mui/material/Alert"; -import FormControl from "@mui/material/FormControl"; -import FormLabel from "@mui/material/FormLabel"; +import Typography from "@mui/material/Typography"; +import RadioGroup from "@mui/material/RadioGroup"; +import TableSortLabel from "@mui/material/TableSortLabel"; +import FormControlLabel from "@mui/material/FormControlLabel"; export const resultColor = (result) => { switch (result.toLowerCase()) { diff --git a/mapping_workbench/frontend/src/sections/app/tree-view/tree-view.js b/mapping_workbench/frontend/src/sections/app/tree-view/tree-view.js index 43b1afb64..2d7e94cf5 100644 --- a/mapping_workbench/frontend/src/sections/app/tree-view/tree-view.js +++ b/mapping_workbench/frontend/src/sections/app/tree-view/tree-view.js @@ -8,7 +8,7 @@ import Stack from "@mui/material/Stack"; import AlbumIcon from '@mui/icons-material/Album'; import AdjustIcon from '@mui/icons-material/Adjust'; import CircularProgress from "@mui/material/CircularProgress"; -import {TableErrorFetching, TableNoData} from "../shacl_validation_report/utils"; +import {TableErrorFetching, TableNoData} from "../shacl-validation-report/utils"; const TreeView = (props) => { const {sectionApi} = props; diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/coverage_files.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/coverage_files.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/sparql_validation_report/coverage_files.js rename to mapping_workbench/frontend/src/sections/app/xpath-validation-report/coverage_files.js diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/coverage_report.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/coverage_report.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/xpath_validation_report/coverage_report.js rename to mapping_workbench/frontend/src/sections/app/xpath-validation-report/coverage_report.js diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/xpath_validation_report/list-table-file.js rename to mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/list-table.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/xpath_validation_report/list-table.js rename to mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/utils.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/utils.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/xpath_validation_report/utils.js rename to mapping_workbench/frontend/src/sections/app/xpath-validation-report/utils.js diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_file.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_file.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_file.js rename to mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_file.js diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_package_state.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_package_state.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_package_state.js rename to mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_package_state.js diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_test_dataset.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_test_dataset.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_test_dataset.js rename to mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_test_dataset.js diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_view.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_view.js similarity index 100% rename from mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_view.js rename to mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_view.js From b7cc884ac82e71ace317c33c6b394cc4935f65cb Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Mon, 23 Sep 2024 16:01:44 +0300 Subject: [PATCH 10/35] MWB-801: add more codemirror --- .../src/pages/app/ontology-files/index.js | 23 ++++--- .../[id]/resource-manager/[fid]/edit.js | 65 ++++++++----------- .../generic-triple-map-fragment/list-table.js | 24 ++++--- 3 files changed, 54 insertions(+), 58 deletions(-) diff --git a/mapping_workbench/frontend/src/pages/app/ontology-files/index.js b/mapping_workbench/frontend/src/pages/app/ontology-files/index.js index 7e5a3ed25..a201d66d7 100644 --- a/mapping_workbench/frontend/src/pages/app/ontology-files/index.js +++ b/mapping_workbench/frontend/src/pages/app/ontology-files/index.js @@ -1,4 +1,7 @@ import {useEffect, useState} from 'react'; +import CodeMirror from '@uiw/react-codemirror'; +import {turtle} from 'codemirror-lang-turtle'; +import {githubDark, githubLight} from '@uiw/codemirror-themes-all'; import Upload01Icon from '@untitled-ui/icons-react/build/esm/Upload01'; import Button from '@mui/material/Button'; @@ -26,6 +29,8 @@ import {Prism as SyntaxHighlighter} from "react-syntax-highlighter"; import CircularProgress from "@mui/material/CircularProgress"; import {Box} from "@mui/system"; import {toastError, toastLoad, toastSuccess} from "../../../components/app-toast"; +import {xml} from "@codemirror/lang-xml"; +import {useTheme} from "@mui/material/styles"; const useItemsSearch = (items) => { const [state, setState] = useState({ @@ -87,7 +92,7 @@ const useItemsSearch = (items) => { }) const handleSearchItems = (filters) => { - setState(prevState => ({...prevState, search: filters, page: 0 })) + setState(prevState => ({...prevState, search: filters, page: 0})) } @@ -154,6 +159,8 @@ const Page = () => { const detailsDialog = useDialog(); const itemsSearch = useItemsSearch(state); + const theme = useTheme(); + usePageView(); useEffect(() => { @@ -281,13 +288,13 @@ const Page = () => { : - - {detailsDialog.data?.content} - - } + } { - const isMounted = useMounted(); const [item, setItem] = useState(null); - const handleItemGet = useCallback(async () => { - try { - const response = await sectionApi.getFileResource(id); - if (isMounted()) { - setItem(response); - } - } catch (err) { - console.error(err); - } - }, [isMounted]); + const handleItemGet = () => { + sectionApi.getFileResource(id) + .then(res => setItem(res)) + .catch(err => console.error(err)) + } useEffect(() => { - handleItemGet(); + id && handleItemGet(); }, // eslint-disable-next-line react-hooks/exhaustive-deps - []); + [id]); return new ForItemDataState(item, setItem); }; @@ -64,8 +57,12 @@ const ExtraForm = (props) => { return ( <> - - + + { const Page = () => { const router = useRouter(); - if (!router.isReady) return; - const {id, fid} = router.query; - if (!id || !fid) { - return; - } - const formState = useItem(sectionApi, fid); const item = formState.item; diff --git a/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/list-table.js b/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/list-table.js index fb19103b5..e08fef935 100644 --- a/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/list-table.js @@ -53,7 +53,7 @@ export const ListTable = (props) => { const SorterHeader = (props) => { const direction = props.fieldName === sort.column && sort.direction === 'desc' ? 'asc' : 'desc'; - return( + return ( { const [projectMappingPackagesMap, setProjectMappingPackagesMap] = useState({}); useEffect(() => { - setProjectMappingPackagesMap(projectMappingPackages.reduce((a, b) => { - a[b['id']] = b['title']; - return a - }, {})); + setProjectMappingPackagesMap(projectMappingPackages.reduce((a, b) => { + a[b['id']] = b['title']; + return a + }, {})); }, [projectMappingPackages]) return ( @@ -193,14 +193,12 @@ export const ListTable = (props) => { Content: { + extensions={[lng[item.format].extension()]} + editable={false} + style={{ + resize: 'vertical', + overflow: 'auto', + height: 600 }} /> From 6fc371d60f96e995e6b729fd8b88053ecf97833d Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Tue, 24 Sep 2024 10:20:37 +0300 Subject: [PATCH 11/35] MWB-801: add more supported languages for codemirror --- mapping_workbench/frontend/package.json | 2 + .../components/app/form/codeMirrorDefault.js | 62 +++++++++++++++++++ .../[id]/resource-manager/[fid]/edit.js | 19 +++--- .../app/triple-map-fragments/[id]/edit.js | 10 --- .../file-manager/file-resource-edit-form.js | 20 +++--- .../generic-triple-map-fragment/edit-form.js | 7 ++- .../generic-triple-map-fragment/list-table.js | 4 ++ 7 files changed, 93 insertions(+), 31 deletions(-) create mode 100644 mapping_workbench/frontend/src/components/app/form/codeMirrorDefault.js diff --git a/mapping_workbench/frontend/package.json b/mapping_workbench/frontend/package.json index 11001a6cf..73dff4770 100644 --- a/mapping_workbench/frontend/package.json +++ b/mapping_workbench/frontend/package.json @@ -22,6 +22,7 @@ "dependencies": { "@auth0/auth0-spa-js": "2.0.4", "@aws-amplify/auth": "5.3.6", + "@codemirror/lang-json": "^6.0.1", "@codemirror/lang-xml": "^6.1.0", "@codemirror/lang-yaml": "^6.1.1", "@emotion/cache": "11.11.0", @@ -54,6 +55,7 @@ "aws-amplify": "5.2.1", "axios": "^1.4.0", "classnames": "^2.5.1", + "codemirror-lang-sparql": "^1.0.0", "codemirror-lang-turtle": "^0.0.2", "date-fns": "2.30.0", "dotenv": "^16.3.1", diff --git a/mapping_workbench/frontend/src/components/app/form/codeMirrorDefault.js b/mapping_workbench/frontend/src/components/app/form/codeMirrorDefault.js new file mode 100644 index 000000000..755908b73 --- /dev/null +++ b/mapping_workbench/frontend/src/components/app/form/codeMirrorDefault.js @@ -0,0 +1,62 @@ +import CodeMirror from "@uiw/react-codemirror"; +import {githubDark, githubLight} from "@uiw/codemirror-themes-all"; +import {yaml} from '@codemirror/lang-yaml' +import {xml} from '@codemirror/lang-xml' +import {json} from '@codemirror/lang-json' +// import rdf from '@rdfjs-elements/rdf-editor' +import {turtle} from 'codemirror-lang-turtle'; +import { sparql } from 'codemirror-lang-sparql'; + + +import {useTheme} from "@mui/material/styles"; +import FormLabel from "@mui/material/FormLabel"; +import FormControl from "@mui/material/FormControl"; +import {Box} from "@mui/system"; + + +const languageSwitch = (lang) => { + switch (lang) { + case 'YAML': + return yaml + case 'XML' : + return xml + case 'JSON': + return json + case 'TTL': + case 'SHACL.TTL': + return turtle + case 'RQ': + return sparql + default: + return json + } +} + +const CodeMirrorDefault = ({value, onChange, lang, label, disabled, style}) => { + const theme = useTheme(); + + return ( + + + {label} + + + + + + ) +} + +export default CodeMirrorDefault \ No newline at end of file diff --git a/mapping_workbench/frontend/src/pages/app/test-data-suites/[id]/resource-manager/[fid]/edit.js b/mapping_workbench/frontend/src/pages/app/test-data-suites/[id]/resource-manager/[fid]/edit.js index e98718365..d157da54e 100644 --- a/mapping_workbench/frontend/src/pages/app/test-data-suites/[id]/resource-manager/[fid]/edit.js +++ b/mapping_workbench/frontend/src/pages/app/test-data-suites/[id]/resource-manager/[fid]/edit.js @@ -6,11 +6,11 @@ import Chip from '@mui/material/Chip'; import Link from '@mui/material/Link'; import Stack from '@mui/material/Stack'; import Paper from "@mui/material/Paper"; +import SvgIcon from '@mui/material/SvgIcon'; import Checkbox from "@mui/material/Checkbox"; import Grid from "@mui/material/Unstable_Grid2"; import Typography from '@mui/material/Typography'; import FormControlLabel from "@mui/material/FormControlLabel"; -import SvgIcon from '@mui/material/SvgIcon'; import {paths} from 'src/paths'; import {Seo} from 'src/components/seo'; @@ -20,7 +20,7 @@ import {Layout as AppLayout} from 'src/layouts/app'; import {RouterLink} from 'src/components/router-link'; import {FormTextField} from "src/components/app/form/text-field"; import {ForItemEditForm} from "src/contexts/app/section/for-item-form"; -import {FormCodeTextArea} from "src/components/app/form/code-text-area"; +import CodeMirrorDefault from "src/components/app/form/codeMirrorDefault"; import {ForItemDataState} from "src/contexts/app/section/for-item-data-state"; import {FileResourceEditForm} from 'src/sections/app/file-manager/file-resource-edit-form'; import {testDataFileResourcesApi as sectionApi} from 'src/api/test-data-suites/file-resources'; @@ -87,14 +87,15 @@ const ExtraForm = (props) => { value="" /> - - + + style={{resize: 'vertical', overflow: 'auto', height: 600}} + value={formik.values.rdf_manifestation} + onChange={value => formik.setValues('rdf_manifestation',value)} + lang={'TTL'} + /> ) diff --git a/mapping_workbench/frontend/src/pages/app/triple-map-fragments/[id]/edit.js b/mapping_workbench/frontend/src/pages/app/triple-map-fragments/[id]/edit.js index b3cbbe474..5bba65815 100644 --- a/mapping_workbench/frontend/src/pages/app/triple-map-fragments/[id]/edit.js +++ b/mapping_workbench/frontend/src/pages/app/triple-map-fragments/[id]/edit.js @@ -88,16 +88,6 @@ const Page = () => { {item.triple_map_uri} - {/**/} - {/* */} - {/**/} diff --git a/mapping_workbench/frontend/src/sections/app/file-manager/file-resource-edit-form.js b/mapping_workbench/frontend/src/sections/app/file-manager/file-resource-edit-form.js index b811f203a..fa1745f93 100644 --- a/mapping_workbench/frontend/src/sections/app/file-manager/file-resource-edit-form.js +++ b/mapping_workbench/frontend/src/sections/app/file-manager/file-resource-edit-form.js @@ -20,14 +20,17 @@ import {FormTextArea} from "src/components/app/form/text-area"; import {FormTextField} from "src/components/app/form/text-field"; import {FormCodeTextArea} from "src/components/app/form/code-text-area"; import {toastError, toastLoad, toastSuccess} from "src/components/app-toast"; +import CodeMirrorDefault from "../../../components/app/form/codeMirrorDefault"; export const FileResourceEditForm = (props) => { const router = useRouter(); - const {itemctx, collection_id, + const { + itemctx, collection_id, extra_form = null, extra_form_fields = {}, - ...other} = props; + ...other + } = props; const sectionApi = itemctx.api; const item = itemctx.data; @@ -198,13 +201,12 @@ export const FileResourceEditForm = (props) => { - + formik.setFieldValue('content', value)}/> diff --git a/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/edit-form.js b/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/edit-form.js index 0d76f6281..817da7f57 100644 --- a/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/edit-form.js +++ b/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/edit-form.js @@ -39,6 +39,7 @@ import Checkbox from "@mui/material/Checkbox"; import FormControlLabel from "@mui/material/FormControlLabel"; import Alert from "@mui/material/Alert"; import {AlertTitle} from "@mui/material"; +import CodeMirrorDefault from "../../../components/app/form/codeMirrorDefault"; export const EditForm = (props) => { const {itemctx, tree, ...other} = props; @@ -245,11 +246,11 @@ export const EditForm = (props) => { /> - formik.setFieldValue('triple_map_content', value)} // options={{ // mode: lng[formik.values.format].mode, diff --git a/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/list-table.js b/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/list-table.js index e08fef935..daa03eb56 100644 --- a/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/list-table.js @@ -28,6 +28,8 @@ import TablePagination from "src/sections/components/table-pagination"; import {ListItemActions} from 'src/components/app/list/list-item-actions'; import TableSorterHeader from "src/sections/components/table-sorter-header"; import {ForListItemAction} from 'src/contexts/app/section/for-list-item-action'; +import {githubDark, githubLight} from "@uiw/codemirror-themes-all"; +import {useTheme} from "@mui/material/styles"; export const ListTable = (props) => { const { @@ -47,6 +49,7 @@ export const ListTable = (props) => { const lng = {TTL: {mode: 'text/turtle', extension: turtle}, YAML: {mode: 'text/yaml', extension: yaml}} const [currentItem, setCurrentItem] = useState(null); + const theme = useTheme(); const {timeSetting} = useGlobalState() const handleItemToggle = itemId => setCurrentItem(prevItemId => prevItemId === itemId ? null : itemId); @@ -192,6 +195,7 @@ export const ListTable = (props) => { > Content: Date: Tue, 24 Sep 2024 15:55:39 +0300 Subject: [PATCH 12/35] MWB-806: update xpath report to have link to file --- .../[id]/states/[sid]/view.js | 18 ++-- .../xpath_validation_report/coverage_files.js | 11 +-- .../app/xpath_validation_report/list-table.js | 96 +++++++++++-------- .../xpath_validation_report_package_state.js | 3 +- .../xpath_validation_report_test_dataset.js | 3 +- .../xpath_validation_report_view.js | 71 ++++++++------ 6 files changed, 115 insertions(+), 87 deletions(-) diff --git a/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js b/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js index 2cdf87f40..2bec97b1f 100644 --- a/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js +++ b/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js @@ -23,15 +23,19 @@ import {mappingPackagesApi as previousSectionApi} from 'src/api/mapping-packages import {useRouter} from "src/hooks/use-router"; import {RouterLink} from 'src/components/router-link'; import exportPackage from "../../../../../../utils/export-mapping-package"; +import CircularProgress from "@mui/material/CircularProgress"; const StateDetails = dynamic(() => import("../../../../../../sections/app/mapping-package/state/state-details")); -const ShaclValidationReport = - dynamic(() => import("../../../../../../sections/app/shacl_validation_report/shacl_validation_report_view")); -const SparqlValidationReport = - dynamic(() => import("../../../../../../sections/app/sparql_validation_report/sparql_validation_report_view")); const XpathValidationReportView = - dynamic(() => import("../../../../../../sections/app/xpath_validation_report/xpath_validation_report_view")); + dynamic(() => import("../../../../../../sections/app/xpath_validation_report/xpath_validation_report_view"), + {loading: () => }); +const SparqlValidationReport = + dynamic(() => import("../../../../../../sections/app/sparql_validation_report/sparql_validation_report_view"), + {loading: () => }); +const ShaclValidationReport = + dynamic(() => import("../../../../../../sections/app/shacl_validation_report/shacl_validation_report_view"), + {loading: () => }); const tabs = [ {label: 'Details', value: 'details'}, @@ -43,7 +47,7 @@ const tabs = [ const Page = () => { const router = useRouter(); - const {id,sid} = router.query; + const {id, sid} = router.query; const [item, setItem] = useState({}) const [currentTab, setCurrentTab] = useState('details'); @@ -147,7 +151,7 @@ const Page = () => { )} + + - {item.is_covered ? : } + {item.is_covered ? : + } @@ -145,19 +158,20 @@ export const ListTable = (props) => { aria-describedby="alert-dialog-description" > - {descriptionDialog.title} + {descriptionDialog.title} - - {descriptionDialog.description} - + + {descriptionDialog.description} + - + - ); + ) + ; }; ListTable.propTypes = { diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_package_state.js b/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_package_state.js index b3a1ca785..708829b48 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_package_state.js +++ b/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_package_state.js @@ -111,7 +111,7 @@ const useItemsSearch = (items) => { }; }; -const XpathValidationReport = ({ sid, files, mappingSuiteIdentifier }) => { +const XpathValidationReport = ({ sid, files, mappingSuiteIdentifier, handleSelectFile }) => { const [validationReport, setValidationReport] = useState([]) const [dataState, setDataState] = useState({load: true, error: false}) @@ -169,6 +169,7 @@ const XpathValidationReport = ({ sid, files, mappingSuiteIdentifier }) => { rowsPerPage={itemsSearch.state.rowsPerPage} onSort={itemsSearch.handleSort} sort={itemsSearch.state.sort} + handleSelectFile={handleSelectFile} sectionApi={sectionApi} /> diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_test_dataset.js b/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_test_dataset.js index e0339062c..ac1dabd6c 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_test_dataset.js +++ b/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_test_dataset.js @@ -112,7 +112,7 @@ const useItemsSearch = (items) => { }; }; -const XpathValidationReportSuite = ({ sid, suiteId, files, mappingSuiteIdentifier }) => { +const XpathValidationReportSuite = ({ sid, suiteId, files, mappingSuiteIdentifier, handleSelectFile }) => { const [validationReport, setValidationReport] = useState([]) const [dataState, setDataState] = useState({load: true, error: false}) @@ -168,6 +168,7 @@ const XpathValidationReportSuite = ({ sid, suiteId, files, mappingSuiteIdentifi rowsPerPage={itemsSearch.state.rowsPerPage} onSort={itemsSearch.handleSort} sort={itemsSearch.state.sort} + handleSelectFile={handleSelectFile} sectionApi={sectionApi} /> diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_view.js b/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_view.js index 973006e3d..c43942abd 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_view.js +++ b/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_view.js @@ -1,36 +1,43 @@ import {useState} from "react"; -import Stack from "@mui/material/Stack"; -import Breadcrumbs from "@mui/material/Breadcrumbs"; import Link from "@mui/material/Link"; -import CoverageFiles from "./coverage_files"; +import Stack from "@mui/material/Stack"; import Typography from "@mui/material/Typography"; +import Breadcrumbs from "@mui/material/Breadcrumbs"; import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'; +import CoverageFiles from "./coverage_files"; import XpathValidationReport from "./xpath_validation_report_package_state"; import XpathValidationReportSuite from "./xpath_validation_report_test_dataset"; import XpathValidationReportTest from "./xpath_validation_report_file"; -const packageState = "package_state" -const packageStateLabel = "Package State XPath Coverage" -const testDataset = "test_dataset" -const testDatasetLabel = "Test Dataset XPath Coverage" -const fileCoverage = "file"; -const fileCoverageLabel = "File XPath Coverage" +const PACKAGE_STATE = "package_state" +const PACKAGE_STATE_LABEL = "Package State XPath Coverage" +const TEST_DATASET = "test_dataset" +const TEST_DATASET_LABEL = "Test Dataset XPath Coverage" +const FILE_COVERAGE = "file"; +const FILE_COVERAGE_LABEL = "File XPath Coverage" -const XpathValidationReportView = ({ sid, reportTree }) => { +const XpathValidationReportView = ({sid, reportTree}) => { + const [currentTab, setCurrentTab] = useState(PACKAGE_STATE) const [selectedPackageState, setSelectedPackageState] = useState(reportTree.test_data_suites[0]) const [selectedTestDataset, setSelectedTestDataset] = useState(reportTree.test_data_suites[0].test_data_states[0]) - const [currentTab, setCurrentTab] = useState(packageState) const handleSetPackageState = (file) => { setSelectedPackageState(file) - setCurrentTab(testDataset) + setCurrentTab(TEST_DATASET) } const handleSetTestDataset = (file) => { setSelectedTestDataset(file) - setCurrentTab(fileCoverage) + setCurrentTab(FILE_COVERAGE) + } + + const handleSetTestAndPackage = (testData, testDataSuite) => { + const packageState = reportTree.test_data_suites.find(tds => tds.oid === testDataSuite) + setSelectedTestDataset(packageState?.test_data_states.find(ps => ps.oid === testData)); + setSelectedPackageState(packageState); + setCurrentTab(FILE_COVERAGE) } return ( @@ -38,49 +45,51 @@ const XpathValidationReportView = ({ sid, reportTree }) => { }> setCurrentTab(packageState)} + color={currentTab !== PACKAGE_STATE ? "inherit" : "primary"} + onClick={() => setCurrentTab(PACKAGE_STATE)} > - {packageStateLabel} + {PACKAGE_STATE_LABEL} - {currentTab !== packageState && + {currentTab !== PACKAGE_STATE && setCurrentTab(testDataset)} + color={currentTab !== TEST_DATASET ? "inherit" : "primary"} + onClick={() => setCurrentTab(TEST_DATASET)} > - {fileCoverageLabel}: {{selectedPackageState.identifier}} + {FILE_COVERAGE_LABEL}: {{selectedPackageState.identifier}} } - {currentTab === fileCoverage && + {currentTab === FILE_COVERAGE && - {testDatasetLabel}: {{selectedTestDataset.identifier}} + {TEST_DATASET_LABEL}: {{selectedTestDataset.identifier}} } - {currentTab === packageState && + {currentTab === PACKAGE_STATE && <> } - {currentTab === testDataset && + {currentTab === TEST_DATASET && <> + suiteId={selectedPackageState.oid} + files={selectedPackageState?.test_data_states} + handleSelectFile={handleSetTestAndPackage} + mappingSuiteIdentifier={reportTree.identifier}/> } - {currentTab === fileCoverage && + {currentTab === FILE_COVERAGE && + suiteId={selectedPackageState.oid} + testId={selectedTestDataset.oid} + mappingSuiteIdentifier={reportTree.identifier}/> } ) From 327e62c06c660eff30c4ff73d4b40b0574536842 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Tue, 24 Sep 2024 16:02:44 +0300 Subject: [PATCH 13/35] MWB-806: update state view --- .../[id]/states/[sid]/view.js | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js b/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js index 2bec97b1f..1c1105f98 100644 --- a/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js +++ b/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js @@ -1,40 +1,41 @@ import {useEffect, useState} from 'react'; import dynamic from "next/dynamic"; -import ArrowLeftIcon from '@untitled-ui/icons-react/build/esm/ArrowLeft'; -import {Upload04 as ExportIcon} from "@untitled-ui/icons-react/build/esm"; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import DownloadingIcon from '@mui/icons-material/Downloading'; +import Tab from '@mui/material/Tab'; import Chip from '@mui/material/Chip'; -import Divider from '@mui/material/Divider'; +import Tabs from '@mui/material/Tabs'; import Link from '@mui/material/Link'; +import Card from "@mui/material/Card"; import Stack from '@mui/material/Stack'; +import Button from "@mui/material/Button"; +import Divider from '@mui/material/Divider'; import SvgIcon from '@mui/material/SvgIcon'; -import Tab from '@mui/material/Tab'; -import Tabs from '@mui/material/Tabs'; import Typography from '@mui/material/Typography'; -import Card from "@mui/material/Card"; import CardContent from "@mui/material/CardContent"; -import Button from "@mui/material/Button"; +import CircularProgress from "@mui/material/CircularProgress"; + import {paths} from 'src/paths'; import {Seo} from 'src/components/seo'; -import {Layout as AppLayout} from 'src/layouts/app'; -import {mappingPackageStatesApi as sectionApi} from 'src/api/mapping-packages/states'; -import {mappingPackagesApi as previousSectionApi} from 'src/api/mapping-packages'; import {useRouter} from "src/hooks/use-router"; +import {Layout as AppLayout} from 'src/layouts/app'; import {RouterLink} from 'src/components/router-link'; -import exportPackage from "../../../../../../utils/export-mapping-package"; -import CircularProgress from "@mui/material/CircularProgress"; +import exportPackage from "src/utils/export-mapping-package"; +import {mappingPackagesApi as previousSectionApi} from 'src/api/mapping-packages'; +import {mappingPackageStatesApi as sectionApi} from 'src/api/mapping-packages/states'; const StateDetails = - dynamic(() => import("../../../../../../sections/app/mapping-package/state/state-details")); + dynamic(() => import("src/sections/app/mapping-package/state/state-details")); const XpathValidationReportView = - dynamic(() => import("../../../../../../sections/app/xpath_validation_report/xpath_validation_report_view"), + dynamic(() => import("src/sections/app/xpath_validation_report/xpath_validation_report_view"), {loading: () => }); const SparqlValidationReport = - dynamic(() => import("../../../../../../sections/app/sparql_validation_report/sparql_validation_report_view"), + dynamic(() => import("src/sections/app/sparql_validation_report/sparql_validation_report_view"), {loading: () => }); const ShaclValidationReport = - dynamic(() => import("../../../../../../sections/app/shacl_validation_report/shacl_validation_report_view"), + dynamic(() => import("src/sections/app/shacl_validation_report/shacl_validation_report_view"), {loading: () => }); const tabs = [ @@ -98,7 +99,7 @@ const Page = () => { underline="hover" > - + {previousSectionApi.SECTION_TITLE} @@ -155,7 +156,7 @@ const Page = () => { disabled={isExporting} startIcon={( - + )} variant="contained" @@ -186,11 +187,11 @@ const Page = () => { {currentTab === 'details' && ( )} - {currentTab === 'shacl' && ( + {currentTab === 'xpath' && ( - + )} @@ -202,11 +203,11 @@ const Page = () => { )} - {currentTab === 'xpath' && ( + {currentTab === 'shacl' && ( - + )} From e9663fca1e1981f7e9fbbed924b872a575d2ff59 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Wed, 25 Sep 2024 10:22:11 +0300 Subject: [PATCH 14/35] MWB-806: update popover --- .../app/xpath_validation_report/list-table.js | 116 +++++++----------- 1 file changed, 47 insertions(+), 69 deletions(-) diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/list-table.js b/mapping_workbench/frontend/src/sections/app/xpath_validation_report/list-table.js index 68f950ed7..7698a0b24 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/xpath_validation_report/list-table.js @@ -1,33 +1,24 @@ import {useState} from "react"; +import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; + import PropTypes from 'prop-types'; +import CheckIcon from '@mui/icons-material/Check'; +import CloseIcon from '@mui/icons-material/Close'; -import Accordion from "@mui/material/Accordion"; import Table from '@mui/material/Table'; +import Button from "@mui/material/Button"; +import Popover from "@mui/material/Popover"; +import TableRow from '@mui/material/TableRow'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableHead from '@mui/material/TableHead'; -import TableRow from '@mui/material/TableRow'; import Typography from '@mui/material/Typography'; -import Tooltip from "@mui/material/Tooltip"; -import Button from "@mui/material/Button"; -import Dialog from '@mui/material/Dialog'; -import DialogTitle from "@mui/material/DialogTitle"; -import CheckIcon from '@mui/icons-material/Check'; -import CloseIcon from '@mui/icons-material/Close'; -import DialogContent from "@mui/material/DialogContent"; -import DialogActions from "@mui/material/DialogActions"; -import TableSortLabel from '@mui/material/TableSortLabel'; -import AccordionDetails from "@mui/material/AccordionDetails"; -import AccordionSummary from "@mui/material/AccordionSummary"; -import DialogContentText from "@mui/material/DialogContentText"; -import ExpandMoreIcon from '@mui/icons-material/ExpandMore' import {Scrollbar} from 'src/components/scrollbar'; -import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; -import TablePagination from "../../components/table-pagination"; +import TablePagination from "src/sections/components/table-pagination"; +import TableSorterHeader from "src/sections/components/table-sorter-header"; export const ListTable = (props) => { - const [descriptionDialog, setDescriptionDialog] = useState({open: false, title: "", text: ""}) const { count = 0, @@ -42,22 +33,20 @@ export const ListTable = (props) => { sort } = props; - const handleClose = () => { - setDescriptionDialog(e => ({...e, open: false})); - }; + const [popover, setPopover] = useState({}) + const setPopoverOpen = (item, anchor) => { + setPopover({data: item, anchor}) + } - const SorterHeader = ({fieldName, title}) => { - return - onSort(fieldName)}> - {title ?? fieldName} - - + const SorterHeader = (props) => { + const direction = props.fieldName === sort.column && sort.direction === 'desc' ? 'asc' : 'desc'; + return ( + + ) } return ( @@ -97,8 +86,6 @@ export const ListTable = (props) => { {items?.map((item, key) => { - // const notices = item.test_data_xpaths.map(e=> `"${e.test_data_id}":${e.xpaths.length}`) - const notices = item.test_data_xpaths.map(tdx => `"${tdx.test_data_id}11":${tdx.xpaths.length}`) return ( @@ -122,22 +109,11 @@ export const ListTable = (props) => { } - - }> - {item.notice_count} - - - {item.test_data_xpaths.map((e, i) => - )} - - + {item.is_covered ? : @@ -151,27 +127,29 @@ export const ListTable = (props) => { - setPopover({})} + anchorOrigin={{ + vertical: 'bottom', + horizontal: 'left', + }} + transformOrigin={{ + vertical: 'top', + horizontal: 'center', + }} > - - {descriptionDialog.title} - - - - {descriptionDialog.description} - - - - - - + {popover.data?.test_data_xpaths?.map((e, i) => + )} + - ) - ; + ); }; ListTable.propTypes = { From 7e5de885f38c729709e39c43a5bc1f06fcc91c11 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Wed, 25 Sep 2024 11:12:54 +0300 Subject: [PATCH 15/35] MWB-806: update sparql --- .../src/pages/app/sparql-test-suites/index.js | 10 +- .../coverage_files.js | 11 +- .../sparql_validation_report/list-table.js | 128 +++++++++--------- .../sparql_validation_report_file.js | 103 +++++++------- .../sparql_validation_report_package_state.js | 102 +++++++------- .../sparql_validation_report_test_dataset.js | 99 +++++++------- .../sparql_validation_report_view.js | 64 +++++---- 7 files changed, 269 insertions(+), 248 deletions(-) diff --git a/mapping_workbench/frontend/src/pages/app/sparql-test-suites/index.js b/mapping_workbench/frontend/src/pages/app/sparql-test-suites/index.js index f1877e789..841023b84 100644 --- a/mapping_workbench/frontend/src/pages/app/sparql-test-suites/index.js +++ b/mapping_workbench/frontend/src/pages/app/sparql-test-suites/index.js @@ -1,13 +1,13 @@ import {useEffect, useState} from 'react'; -import PlusIcon from '@untitled-ui/icons-react/build/esm/Plus'; -import Breadcrumbs from '@mui/material/Breadcrumbs'; -import Button from '@mui/material/Button'; +import AddIcon from '@mui/icons-material/Add'; import Card from '@mui/material/Card'; import Link from '@mui/material/Link'; import Stack from '@mui/material/Stack'; +import Button from '@mui/material/Button'; import SvgIcon from '@mui/material/SvgIcon'; import Typography from '@mui/material/Typography'; +import Breadcrumbs from '@mui/material/Breadcrumbs'; import {paths} from 'src/paths'; import {Seo} from 'src/components/seo'; @@ -16,8 +16,8 @@ import {RouterLink} from 'src/components/router-link'; import {usePageView} from 'src/hooks/use-page-view'; import {BreadcrumbsSeparator} from 'src/components/breadcrumbs-separator'; import {sparqlTestSuitesApi as sectionApi} from 'src/api/sparql-test-suites'; -import {FileCollectionListSearch} from 'src/sections/app/file-manager/file-collection-list-search'; import {FileCollectionListTable} from 'src/sections/app/file-manager/file-collection-list-table'; +import {FileCollectionListSearch} from 'src/sections/app/file-manager/file-collection-list-search'; import {sparqlTestFileResourcesApi as fileResourcesApi} from "../../../api/sparql-test-suites/file-resources"; const useItemsSearch = () => { @@ -140,7 +140,7 @@ const Page = () => { href={paths.app[sectionApi.section].create} startIcon={( - + )} variant="contained" diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/coverage_files.js b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/coverage_files.js index 3b7299f54..d48af4bd9 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/coverage_files.js +++ b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/coverage_files.js @@ -1,13 +1,12 @@ -import List from "@mui/material/List"; -import ListItem from "@mui/material/ListItem"; -import ListItemButton from "@mui/material/ListItemButton"; -import ListItemText from "@mui/material/ListItemText"; -import Typography from "@mui/material/Typography"; - import FolderIcon from '@mui/icons-material/FolderOpen'; import FileIcon from '@mui/icons-material/Description'; +import List from "@mui/material/List"; +import ListItem from "@mui/material/ListItem"; +import Typography from "@mui/material/Typography"; import ListItemIcon from "@mui/material/ListItemIcon"; +import ListItemText from "@mui/material/ListItemText"; +import ListItemButton from "@mui/material/ListItemButton"; const CoverageFiles = ({files, fileIcon, onClick}) => { return ( diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/list-table.js b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/list-table.js index cc6358c01..5c10d0379 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/list-table.js @@ -1,28 +1,27 @@ import {useState} from "react"; import PropTypes from 'prop-types'; +import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; import Table from '@mui/material/Table'; +import Stack from "@mui/material/Stack"; +import Button from "@mui/material/Button"; +import Dialog from '@mui/material/Dialog'; +import TableRow from '@mui/material/TableRow'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; -import TableSortLabel from '@mui/material/TableSortLabel'; import TableHead from '@mui/material/TableHead'; -import TableRow from '@mui/material/TableRow'; import Typography from '@mui/material/Typography'; -import Tooltip from "@mui/material/Tooltip"; -import Button from "@mui/material/Button"; -import Dialog from '@mui/material/Dialog'; import DialogTitle from "@mui/material/DialogTitle"; import DialogContent from "@mui/material/DialogContent"; import DialogActions from "@mui/material/DialogActions"; -import Stack from "@mui/material/Stack"; -import {Scrollbar} from 'src/components/scrollbar'; import {ResultChip} from "./utils"; -import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; -import TablePagination from "../../components/table-pagination"; +import {Scrollbar} from 'src/components/scrollbar'; +import TablePagination from "src/sections/components/table-pagination"; +import TableSorterHeader from "src/sections/components/table-sorter-header"; export const ListTable = (props) => { - const [descriptionDialog, setDescriptionDialog] = useState({open:false, title:"", description:""}) + const [descriptionDialog, setDescriptionDialog] = useState({open: false, title: "", description: ""}) const { count = 0, @@ -33,17 +32,18 @@ export const ListTable = (props) => { rowsPerPage = 0, sort, onSort, - sectionApi + sectionApi, + handleSelectFile } = props; const mapNotices = (notices) => { - return( -
    - {notices.map((notice,i) => -
  • - {`${notice.test_data_suite_id} / ${notice.test_data_id}`} -
  • )} -
+ return ( + notices.map((notice, i) => + ) ) } @@ -53,33 +53,30 @@ export const ListTable = (props) => { } const handleClose = () => { - setDescriptionDialog(e=>({...e, open: false})); + setDescriptionDialog(e => ({...e, open: false})); }; - const SorterHeader = ({fieldName, title, desc}) => { - return - onSort(fieldName, desc)}> - {title ?? fieldName} - - + const SorterHeader = (props) => { + const direction = props.fieldName === sort.column && sort.direction === 'desc' ? 'asc' : 'desc'; + return ( + + ) } const ResultCell = ({title, result, onClick}) => { return - {result.count} - {!!result.count && } - + alignItems="center" + justifyContent="start" + height={100}> + {result.count} + {!!result.count && } + } return ( @@ -104,12 +101,12 @@ export const ListTable = (props) => { title="Field"/>
- + - + { desc/> - } - desc/> + } + desc/> - - } - desc/> + + } + desc/> - - } - desc/> + + } + desc/> - - } - desc/> + + } + desc/>
@@ -165,7 +162,12 @@ export const ListTable = (props) => { + lineProps={{ + style: { + overflowWrap: 'break-word', + whiteSpace: 'pre-wrap' + } + }}> {item.query} diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_file.js b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_file.js index 361a09ec5..859fb2243 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_file.js +++ b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_file.js @@ -1,12 +1,11 @@ import {useEffect, useState} from "react"; -import {mappingPackageStatesApi as sectionApi} from "../../../api/mapping-packages/states"; - import Typography from "@mui/material/Typography"; -import ItemSearchInput from "../file-manager/item-search-input"; import {ListTableFile} from "./list-table-file"; import {QueryResultTable} from "./query-result-table"; import {ResultFilter, TableLoadWrapper} from "./utils"; +import ItemSearchInput from "../file-manager/item-search-input"; +import {mappingPackageStatesApi as sectionApi} from "../../../api/mapping-packages/states"; const useItemsSearch = (items) => { @@ -14,10 +13,9 @@ const useItemsSearch = (items) => { filters: { result: "" }, - sort: { - }, + sort: {}, search: [], - searchColumns: ["title","query"], + searchColumns: ["title", "query"], page: sectionApi.DEFAULT_PAGE, rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE }); @@ -28,7 +26,7 @@ const useItemsSearch = (items) => { let returnItem = null; state.searchColumns.forEach(column => { state.search.forEach(search => { - if(item[column]?.toLowerCase()?.includes(search.toLowerCase())) + if (item[column]?.toLowerCase()?.includes(search.toLowerCase())) returnItem = item }) }) @@ -37,11 +35,11 @@ const useItemsSearch = (items) => { const filteredItems = searchItems.filter((item) => { let returnItem = item; - Object.entries(filters).forEach(filter=> { + Object.entries(filters).forEach(filter => { const [key, value] = filter - if(value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) + if (value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) returnItem = null - if(value !== "" && value !== undefined && typeof item[key] === "string" && item[key] !== value.toLowerCase()) + if (value !== "" && value !== undefined && typeof item[key] === "string" && item[key] !== value.toLowerCase()) returnItem = null }) return returnItem @@ -49,10 +47,10 @@ const useItemsSearch = (items) => { const sortedItems = () => { const sortColumn = state.sort.column - if(!sortColumn) { + if (!sortColumn) { return filteredItems } else { - return filteredItems.sort((a,b) => { + return filteredItems.sort((a, b) => { if (typeof a[sortColumn] === "string") return state.sort.direction === "asc" ? a[sortColumn]?.localeCompare(b[sortColumn]) : @@ -61,22 +59,22 @@ const useItemsSearch = (items) => { return state.sort.direction === "asc" ? a[sortColumn] - b[sortColumn] : b[sortColumn] - a[sortColumn] - }) + }) } } const pagedItems = sortedItems().filter((item, i) => { const pageSize = state.page * state.rowsPerPage - if((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) + if ((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) return item }) const handleSearchItems = (filters) => { - setState(prevState=> ({...prevState, search: filters })) + setState(prevState => ({...prevState, search: filters})) } const handleFiltersChange = (filters) => { - setState(prevState=> ({ + setState(prevState => ({ ...prevState, filters, page: 0 @@ -91,8 +89,12 @@ const useItemsSearch = (items) => { } const handleSort = (column) => { - setState(prevState=> ({ ...prevState, sort: {column, - direction: prevState.sort.column === column && prevState.sort.direction === "asc" ? "desc" : "asc"}})) + setState(prevState => ({ + ...prevState, sort: { + column, + direction: prevState.sort.column === column && prevState.sort.direction === "asc" ? "desc" : "asc" + } + })) } const handleRowsPerPageChange = (event) => { setState(prevState => ({ @@ -113,29 +115,30 @@ const useItemsSearch = (items) => { }; }; -const SparqlFileReport = ({ sid, suiteId, testId, files, mappingSuiteIdentifier }) => { +const SparqlFileReport = ({sid, suiteId, testId, files, mappingSuiteIdentifier}) => { const [validationReport, setValidationReport] = useState([]) - const [dataState, setDataState] = useState({load:true, error:false}) + const [dataState, setDataState] = useState({load: true, error: false}) - useEffect(()=>{ + useEffect(() => { handleValidationReportsGet(sid, suiteId, testId) - },[]) + }, []) const handleValidationReportsGet = async (sid, suiteId, testId) => { - try { - setDataState({load:true, error:false}) - const result = await sectionApi.getSparqlReportsTest(sid, suiteId, testId) - setValidationReport(mapSparqlResults(result.results)) - setDataState(e=>({...e, load: false})) - } catch (err) { - console.error(err); - setDataState({load:false, error:true}) - } + setDataState({load: true, error: false}) + sectionApi.getSparqlReportsTest(sid, suiteId, testId) + .then(res => { + setValidationReport(mapSparqlResults(res.results)) + setDataState(e => ({...e, load: false})) + }) + .catch(err => { + console.error(err); + setDataState({load: false, error: true}) + }) } - const mapSparqlResults = (result) => result.map(e=> { + const mapSparqlResults = (result) => result.map(e => { const queryAsArray = e.query.content.split("\n") - const values = queryAsArray.slice(0,3) + const values = queryAsArray.slice(0, 3) const resultArray = {} values.forEach(e => { const res = e.split(": ") @@ -165,8 +168,8 @@ const SparqlFileReport = ({ sid, suiteId, testId, files, mappingSuiteIdentifier lines={6} data={validationReport}> + items={validationReport} + /> @@ -174,21 +177,21 @@ const SparqlFileReport = ({ sid, suiteId, testId, files, mappingSuiteIdentifier - - - + + + ) } -export default SparqlFileReport \ No newline at end of file +export default SparqlFileReport \ No newline at end of file diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_package_state.js b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_package_state.js index 19aeea354..b280ae2c4 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_package_state.js +++ b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_package_state.js @@ -14,10 +14,9 @@ const useItemsSearch = (items) => { filters: { is_covered: "" }, - sort: { - }, + sort: {}, search: [], - searchColumns:["sdk_element_id","sdk_element_xpath"], + searchColumns: ["sdk_element_id", "sdk_element_xpath"], page: sectionApi.DEFAULT_PAGE, rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE }); @@ -28,7 +27,7 @@ const useItemsSearch = (items) => { let returnItem = null; state.searchColumns.forEach(column => { state.search.forEach(search => { - if(item[column]?.toLowerCase()?.includes(search.toLowerCase())) + if (item[column]?.toLowerCase()?.includes(search.toLowerCase())) returnItem = item }) }) @@ -37,11 +36,11 @@ const useItemsSearch = (items) => { const filteredItems = searchItems.filter((item) => { let returnItem = item; - Object.entries(filters).forEach(filter=> { + Object.entries(filters).forEach(filter => { const [key, value] = filter - if(value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) + if (value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) returnItem = null - if(value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) + if (value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) returnItem = null }) return returnItem @@ -49,10 +48,10 @@ const useItemsSearch = (items) => { const sortedItems = () => { const sortColumn = state.sort.column - if(!sortColumn) { + if (!sortColumn) { return filteredItems } else { - return filteredItems.sort((a,b) => { + return filteredItems.sort((a, b) => { if (typeof a[sortColumn] === "string") return state.sort.direction === "asc" ? a[sortColumn]?.localeCompare(b[sortColumn]) : @@ -61,18 +60,18 @@ const useItemsSearch = (items) => { return state.sort.direction === "asc" ? a[sortColumn] - b[sortColumn] : b[sortColumn] - a[sortColumn] - }) + }) } } const pagedItems = sortedItems().filter((item, i) => { const pageSize = state.page * state.rowsPerPage - if((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) + if ((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) return item }) const handleSearchItems = (filters) => { - setState(prevState => ({...prevState, search: filters })) + setState(prevState => ({...prevState, search: filters})) } const handleFiltersChange = (filters) => { @@ -91,15 +90,18 @@ const useItemsSearch = (items) => { } const handleSort = (column, desc) => { - console.log(state.sort.column === column ? state.sort.direction === "asc" ? "desc" : "asc" : desc ? "desc" : "asc") - setState(prevState=> ({ ...prevState, sort: {column, - direction: prevState.sort.column === column - ? prevState.sort.direction === "desc" - ? "asc" - : "desc" - : desc - ? "desc" - : "asc"}})) + setState(prevState => ({ + ...prevState, sort: { + column, + direction: prevState.sort.column === column + ? prevState.sort.direction === "desc" + ? "asc" + : "desc" + : desc + ? "desc" + : "asc" + } + })) } @@ -122,29 +124,30 @@ const useItemsSearch = (items) => { }; }; -const SparqlValidationReport = ({ sid }) => { +const SparqlValidationReport = ({sid, handleSelectFile}) => { const [validationReport, setValidationReport] = useState([]) - const [dataState, setDataState] = useState({load:true, error:false}) + const [dataState, setDataState] = useState({load: true, error: false}) - useEffect(()=>{ + useEffect(() => { handleValidationReportsGet(sid) - },[]) - - const handleValidationReportsGet = async (sid) => { - try { - setDataState({load:true, error: false}) - const result = await sectionApi.getSparqlReports(sid) - setValidationReport(mapSparqlResults(result.summary)) - setDataState(e=> ({...e, load:false})) - } catch (err) { - console.error(err); - setDataState({load:false, error:true}) - } + }, []) + + const handleValidationReportsGet = (sid) => { + setDataState({load: true, error: false}) + sectionApi.getSparqlReports(sid) + .then(res => { + setValidationReport(mapSparqlResults(res.summary)) + setDataState(e => ({...e, load: false})) + }) + .catch(err => { + console.error(err); + setDataState({load: false, error: true}) + }) } const mapSparqlResults = (result) => result.map(e => { const queryAsArray = e.query.content.split("\n") - const values = queryAsArray.slice(0,3) + const values = queryAsArray.slice(0, 3) const resultArray = {} values.forEach(e => { const res = e.split(": ") @@ -155,7 +158,7 @@ const SparqlValidationReport = ({ sid }) => { resultArray["test_suite"] = e.query.filename resultArray["result"] = e.result Object.entries(e.result).forEach(entrie => { - const [key,value] = entrie + const [key, value] = entrie resultArray[`${key}Count`] = value.count }) return resultArray; @@ -166,7 +169,7 @@ const SparqlValidationReport = ({ sid }) => { return ( <> + variant="h4"> Results Summary { data={validationReport}> ) } -export default SparqlValidationReport \ No newline at end of file +export default SparqlValidationReport \ No newline at end of file diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_test_dataset.js b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_test_dataset.js index 170b5ef9b..889226bf2 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_test_dataset.js +++ b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_test_dataset.js @@ -1,21 +1,18 @@ import {useEffect, useState} from "react"; -import {mappingPackageStatesApi as sectionApi} from "../../../api/mapping-packages/states"; - import Typography from "@mui/material/Typography"; -import {TableLoadWrapper} from "./utils"; import {ListTable} from "./list-table"; +import {TableLoadWrapper} from "./utils"; import ResultSummaryTable from "./result-summary-table"; import ItemSearchInput from "../file-manager/item-search-input"; +import {mappingPackageStatesApi as sectionApi} from "../../../api/mapping-packages/states"; const useItemsSearch = (items) => { const [state, setState] = useState({ - filters: { - }, - sort: { - }, + filters: {}, + sort: {}, search: [], - searchColumns:["sdk_element_id","sdk_element_xpath"], + searchColumns: ["sdk_element_id", "sdk_element_xpath"], page: sectionApi.DEFAULT_PAGE, rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE }); @@ -26,7 +23,7 @@ const useItemsSearch = (items) => { let returnItem = null; state.searchColumns.forEach(column => { state.search.forEach(search => { - if(item[column]?.toLowerCase()?.includes(search.toLowerCase())) + if (item[column]?.toLowerCase()?.includes(search.toLowerCase())) returnItem = item }) }) @@ -35,11 +32,11 @@ const useItemsSearch = (items) => { const filteredItems = searchItems.filter((item) => { let returnItem = item; - Object.entries(filters).forEach(filter=> { + Object.entries(filters).forEach(filter => { const [key, value] = filter - if(value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) + if (value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) returnItem = null - if(value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) + if (value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) returnItem = null }) return returnItem @@ -47,10 +44,10 @@ const useItemsSearch = (items) => { const sortedItems = () => { const sortColumn = state.sort.column - if(!sortColumn) { + if (!sortColumn) { return filteredItems } else { - return filteredItems.sort((a,b) => { + return filteredItems.sort((a, b) => { if (typeof a[sortColumn] === "string") return state.sort.direction === "asc" ? a[sortColumn]?.localeCompare(b[sortColumn]) : @@ -59,18 +56,18 @@ const useItemsSearch = (items) => { return state.sort.direction === "asc" ? a[sortColumn] - b[sortColumn] : b[sortColumn] - a[sortColumn] - }) + }) } } const pagedItems = sortedItems().filter((item, i) => { const pageSize = state.page * state.rowsPerPage - if((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) + if ((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) return item }) const handleSearchItems = (filters) => { - setState(prevState => ({...prevState, search: filters })) + setState(prevState => ({...prevState, search: filters})) } const handleFiltersChange = (filters) => { @@ -89,8 +86,12 @@ const useItemsSearch = (items) => { } const handleSort = (column, desc) => { - setState(prevState=> ({ ...prevState, sort: {column, - direction: prevState.sort.column === column ? prevState.sort.direction === "asc" ? "desc" : "asc" : desc ? "desc" : "asc" }})) + setState(prevState => ({ + ...prevState, sort: { + column, + direction: prevState.sort.column === column ? prevState.sort.direction === "asc" ? "desc" : "asc" : desc ? "desc" : "asc" + } + })) } const handleRowsPerPageChange = (event) => { @@ -112,30 +113,31 @@ const useItemsSearch = (items) => { }; }; -const SparqlTestDatasetReport = ({ sid, suiteId }) => { +const SparqlTestDatasetReport = ({sid, suiteId, handleSelectFile}) => { const [validationReport, setValidationReport] = useState([]) - const [dataState, setDataState] = useState({load:true, error:false}) + const [dataState, setDataState] = useState({load: true, error: false}) - useEffect(()=>{ + useEffect(() => { handleValidationReportsGet(sid, suiteId) - },[]) + }, []) const handleValidationReportsGet = async (sid, suiteId) => { - try { - setDataState({load:true, error:false}) - const result = await sectionApi.getSparqlReportsSuite(sid, suiteId) - setValidationReport(mapSparqlResults(result.summary)) - setDataState(e=>({...e, load:false})) - } catch (err) { - console.error(err); - setDataState({load:false, error:true}) - } + setDataState({load: true, error: false}) + sectionApi.getSparqlReportsSuite(sid, suiteId) + .then(res => { + setValidationReport(mapSparqlResults(res.summary)) + setDataState(e => ({...e, load: false})) + }) + .catch(err => { + console.error(err); + setDataState({load: false, error: true}) + }) } - const mapSparqlResults = (result) => result.map(e=> { + const mapSparqlResults = (result) => result.map(e => { const queryAsArray = e.query.content.split("\n") - const values = queryAsArray.slice(0,3) + const values = queryAsArray.slice(0, 3) const resultArray = {} values.forEach(e => { const res = e.split(": ") @@ -146,7 +148,7 @@ const SparqlTestDatasetReport = ({ sid, suiteId }) => { resultArray["test_suite"] = e.query.filename resultArray["result"] = e.result Object.entries(e.result).forEach(entrie => { - const [key,value] = entrie + const [key, value] = entrie resultArray[`${key}Count`] = value.count }) return resultArray; @@ -157,7 +159,7 @@ const SparqlTestDatasetReport = ({ sid, suiteId }) => { return ( <> + variant="h4"> Results Summary { - - + + ) } diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js index 21de8406d..643ebdfdb 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js +++ b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js @@ -1,37 +1,45 @@ import {useState} from "react"; +import KeyboardArrowRightIcon from "@mui/icons-material/KeyboardArrowRight"; + import Stack from "@mui/material/Stack"; import Breadcrumbs from "@mui/material/Breadcrumbs"; -import KeyboardArrowRightIcon from "@mui/icons-material/KeyboardArrowRight"; import Link from "@mui/material/Link"; import Typography from "@mui/material/Typography"; import CoverageFiles from "./coverage_files"; -import SparqlPackageStateReport from "./sparql_validation_report_package_state"; -import SparqlTestDatasetReport from "./sparql_validation_report_test_dataset"; import SparqlFileReport from "./sparql_validation_report_file"; +import SparqlTestDatasetReport from "./sparql_validation_report_test_dataset"; +import SparqlPackageStateReport from "./sparql_validation_report_package_state"; -const packageState = "package_state"; -const packageStateLabel = "Package State SPARQL Coverage"; -const testDataset = "test_dataset"; -const testDatasetLabel = "Test Dataset SPARQL Coverage"; -const fileCoverage = "file_coverage"; -const fileCoverageLabel = "File SPARQL Coverage" +const PACKAGE_STATE = "package_state"; +const PACKAGE_STATE_LABEL = "Package State SPARQL Coverage"; +const TEST_DATASET = "test_dataset"; +const TEST_DATASET_LABEL = "Test Dataset SPARQL Coverage"; +const FILE_COVERAGE = "file_coverage"; +const FILE_COVERAGE_LABEL = "File SPARQL Coverage" -const SparqlValidationReportView = ({ sid, reportTree }) => { +const SparqlValidationReportView = ({sid, reportTree}) => { const [selectedPackageState, setSelectedPackageState] = useState(reportTree.test_data_suites[0]) const [selectedTestDataset, setSelectedTestDataset] = useState(reportTree.test_data_suites[0].test_data_states[0]) - const [currentTab, setCurrentTab] = useState(packageState) + const [currentTab, setCurrentTab] = useState(PACKAGE_STATE) const handleSetPackageState = (file) => { setSelectedPackageState(file) - setCurrentTab(testDataset) + setCurrentTab(TEST_DATASET) } const handleSetTestDataset = (file) => { setSelectedTestDataset(file) - setCurrentTab(fileCoverage) + setCurrentTab(FILE_COVERAGE) + } + + const handleSetTestAndPackage = (testData, testDataSuite) => { + const packageState = reportTree.test_data_suites.find(tds => tds.oid === testDataSuite) + setSelectedTestDataset(packageState?.test_data_states.find(ps => ps.oid === testData)); + setSelectedPackageState(packageState); + setCurrentTab(FILE_COVERAGE) } return ( @@ -39,42 +47,44 @@ const SparqlValidationReportView = ({ sid, reportTree }) => { }> setCurrentTab(packageState)} + color={currentTab !== PACKAGE_STATE ? "inherit" : "primary"} + onClick={() => setCurrentTab(PACKAGE_STATE)} > - {packageStateLabel} + {PACKAGE_STATE_LABEL} - {currentTab !== packageState && + {currentTab !== PACKAGE_STATE && setCurrentTab(testDataset)} + color={currentTab !== TEST_DATASET ? "inherit" : "primary"} + onClick={() => setCurrentTab(TEST_DATASET)} > - {testDatasetLabel}: {{selectedPackageState.identifier}} + {TEST_DATASET_LABEL}: {{selectedPackageState.identifier}} } - {currentTab === fileCoverage && + {currentTab === FILE_COVERAGE && - {fileCoverageLabel}: {{selectedTestDataset.identifier}} + {FILE_COVERAGE_LABEL}: {{selectedTestDataset.identifier}} } - {currentTab === packageState && + {currentTab === PACKAGE_STATE && <> + handleSelectFile={handleSetTestAndPackage} + files={reportTree.test_data_suites}/> } - {currentTab === testDataset && + {currentTab === TEST_DATASET && <> + handleSelectFile={handleSetTestAndPackage} + suiteId={selectedPackageState.oid}/> } - {currentTab === fileCoverage && + {currentTab === FILE_COVERAGE && From a19dc4bb990f3daf922a75131ccbf33091155bb2 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Wed, 25 Sep 2024 11:17:16 +0300 Subject: [PATCH 16/35] MWB-806: update xpath --- .../xpath_validation_report_file.js | 89 ++++++++--------- .../xpath_validation_report_test_dataset.js | 96 ++++++++++--------- 2 files changed, 96 insertions(+), 89 deletions(-) diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_file.js b/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_file.js index 5243e3b4e..7b6c0eee3 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_file.js +++ b/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_file.js @@ -10,12 +10,10 @@ import {mappingPackageStatesApi as sectionApi} from "../../../api/mapping-packag const useItemsSearch = (items) => { const [state, setState] = useState({ - filters: { - }, - sort: { - }, + filters: {}, + sort: {}, search: [], - searchColumns:["sdk_element_id", "test_data_xpath"], + searchColumns: ["sdk_element_id", "test_data_xpath"], page: sectionApi.DEFAULT_PAGE, rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE }); @@ -26,7 +24,7 @@ const useItemsSearch = (items) => { let returnItem = null; state.searchColumns.forEach(column => { state.search.forEach(search => { - if(item[column]?.toLowerCase()?.includes(search.toLowerCase())) + if (item[column]?.toLowerCase()?.includes(search.toLowerCase())) returnItem = item }) }) @@ -36,11 +34,11 @@ const useItemsSearch = (items) => { const filteredItems = searchItems.filter((item) => { let returnItem = item; - Object.entries(filters).forEach(e=> { + Object.entries(filters).forEach(e => { const [key, value] = e - if(value !== undefined && typeof item[key] === "boolean" && item[key]?.toString() != value) + if (value !== undefined && typeof item[key] === "boolean" && item[key]?.toString() != value) returnItem = null - if(value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) + if (value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) returnItem = null }) return returnItem @@ -48,10 +46,10 @@ const useItemsSearch = (items) => { const sortedItems = () => { const sortColumn = state.sort.column - if(!sortColumn) { + if (!sortColumn) { return filteredItems } else { - return filteredItems.sort((a,b) => { + return filteredItems.sort((a, b) => { if (typeof a[sortColumn] === "string") return state.sort.direction === "asc" ? a[sortColumn]?.localeCompare(b[sortColumn]) : @@ -60,18 +58,18 @@ const useItemsSearch = (items) => { return state.sort.direction === "asc" ? a[sortColumn] - b[sortColumn] : b[sortColumn] - a[sortColumn] - }) + }) } } const pagedItems = sortedItems().filter((item, i) => { const pageSize = state.page * state.rowsPerPage - if((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) + if ((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) return item }) const handleSearchItems = (filters) => { - setState(prevState => ({...prevState, search: filters })) + setState(prevState => ({...prevState, search: filters})) } const handleFiltersChange = (filters) => { @@ -90,8 +88,12 @@ const useItemsSearch = (items) => { } const handleSort = (column) => { - setState(prevState=> ({ ...prevState, sort: {column, - direction: prevState.sort.column === column && prevState.sort.direction === "asc" ? "desc" : "asc"}})) + setState(prevState => ({ + ...prevState, sort: { + column, + direction: prevState.sort.column === column && prevState.sort.direction === "asc" ? "desc" : "asc" + } + })) } const handleRowsPerPageChange = (event) => { setState(prevState => ({ @@ -112,24 +114,25 @@ const useItemsSearch = (items) => { }; }; -const XpathValidationReportTest= ({ sid, suiteId, testId, mappingSuiteIdentifier }) => { +const XpathValidationReportTest = ({sid, suiteId, testId, mappingSuiteIdentifier}) => { const [validationReport, setValidationReport] = useState([]) const [dataState, setDataState] = useState({load: true, error: false}) - useEffect(()=>{ + useEffect(() => { handleValidationReportsTestGet(sid, suiteId, testId) - },[testId]) + }, [testId]) const handleValidationReportsTestGet = async (sid, suiteId, testId) => { - try { - setDataState({load: true, error: false}) - const result = await sectionApi.getXpathReportsTest(sid, suiteId, testId) - setValidationReport(result.results) - setDataState(e=> ({...e, load: false})) - } catch (err) { - console.error(err); - setDataState({load: false, error: true}) - } + setDataState({load: true, error: false}) + sectionApi.getXpathReportsTest(sid, suiteId, testId) + .then(res => { + setValidationReport(res.results) + setDataState(e => ({...e, load: false})) + }) + .catch(err => { + console.error(err); + setDataState({load: false, error: true}) + }) } const itemsSearch = useItemsSearch(validationReport); @@ -144,28 +147,28 @@ const XpathValidationReportTest= ({ sid, suiteId, testId, mappingSuiteIdentifie data={validationReport} lines={3}> + mappingSuiteIdentifier={mappingSuiteIdentifier}/> - - Assertions - + + Assertions + ) } -export default XpathValidationReportTest \ No newline at end of file +export default XpathValidationReportTest \ No newline at end of file diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_test_dataset.js b/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_test_dataset.js index ac1dabd6c..ed4d09090 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_test_dataset.js +++ b/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_test_dataset.js @@ -13,10 +13,9 @@ const useItemsSearch = (items) => { filters: { is_covered: "" }, - sort: { - }, + sort: {}, search: [], - searchColumns:["sdk_element_id","sdk_element_xpath"], + searchColumns: ["sdk_element_id", "sdk_element_xpath"], page: sectionApi.DEFAULT_PAGE, rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE }); @@ -27,7 +26,7 @@ const useItemsSearch = (items) => { let returnItem = null; state.searchColumns.forEach(column => { state.search.forEach(search => { - if(item[column]?.toLowerCase()?.includes(search.toLowerCase())) + if (item[column]?.toLowerCase()?.includes(search.toLowerCase())) returnItem = item }) }) @@ -36,11 +35,11 @@ const useItemsSearch = (items) => { const filteredItems = searchItems.filter((item) => { let returnItem = item; - Object.entries(filters).forEach(filter=> { + Object.entries(filters).forEach(filter => { const [key, value] = filter - if(value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) + if (value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) returnItem = null - if(value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) + if (value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) returnItem = null }) return returnItem @@ -48,10 +47,10 @@ const useItemsSearch = (items) => { const sortedItems = () => { const sortColumn = state.sort.column - if(!sortColumn) { + if (!sortColumn) { return filteredItems } else { - return filteredItems.sort((a,b) => { + return filteredItems.sort((a, b) => { if (typeof a[sortColumn] === "string") return state.sort.direction === "asc" ? a[sortColumn]?.localeCompare(b[sortColumn]) : @@ -60,18 +59,18 @@ const useItemsSearch = (items) => { return state.sort.direction === "asc" ? a[sortColumn] - b[sortColumn] : b[sortColumn] - a[sortColumn] - }) + }) } } const pagedItems = sortedItems().filter((item, i) => { const pageSize = state.page * state.rowsPerPage - if((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) + if ((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) return item }) const handleSearchItems = (filters) => { - setState(prevState => ({...prevState, search: filters })) + setState(prevState => ({...prevState, search: filters})) } const handleFiltersChange = (filters) => { @@ -90,8 +89,12 @@ const useItemsSearch = (items) => { } const handleSort = (column) => { - setState(prevState=> ({ ...prevState, sort: {column, - direction: prevState.sort.column === column && prevState.sort.direction === "asc" ? "desc" : "asc"}})) + setState(prevState => ({ + ...prevState, sort: { + column, + direction: prevState.sort.column === column && prevState.sort.direction === "asc" ? "desc" : "asc" + } + })) } const handleRowsPerPageChange = (event) => { setState((prevState) => ({ @@ -112,24 +115,25 @@ const useItemsSearch = (items) => { }; }; -const XpathValidationReportSuite = ({ sid, suiteId, files, mappingSuiteIdentifier, handleSelectFile }) => { +const XpathValidationReportSuite = ({sid, suiteId, files, mappingSuiteIdentifier, handleSelectFile}) => { const [validationReport, setValidationReport] = useState([]) const [dataState, setDataState] = useState({load: true, error: false}) - useEffect(()=>{ - handleValidationReportsSuiteGet(sid,suiteId) - },[suiteId]) + useEffect(() => { + handleValidationReportsSuiteGet(sid, suiteId) + }, [suiteId]) const handleValidationReportsSuiteGet = async (sid, suiteId) => { - try { - setDataState({load: true, error: false}) - const result = await sectionApi.getXpathReportsSuite(sid, suiteId) - setValidationReport(result.results.map(e => ({...e, notice_count: e.test_data_xpaths.length}))) - setDataState(e=>({...e, load: false})) - } catch (err) { - console.error(err); - setDataState({load: false, error: true}) - } + setDataState({load: true, error: false}) + sectionApi.getXpathReportsSuite(sid, suiteId) + .then(res => { + setValidationReport(res.results.map(e => ({...e, notice_count: e.test_data_xpaths.length}))) + setDataState(e => ({...e, load: false})) + }) + .catch(err => { + console.error(err); + setDataState({load: false, error: true}) + }) } const itemsSearch = useItemsSearch(validationReport); @@ -140,8 +144,8 @@ const XpathValidationReportSuite = ({ sid, suiteId, files, mappingSuiteIdentifi return ( <> - + Summary - - Assertions - + + Assertions + - + ) } -export default XpathValidationReportSuite \ No newline at end of file +export default XpathValidationReportSuite \ No newline at end of file From a6da7da439b64fa7970c4a781ebcae6dfe5e221a Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Wed, 25 Sep 2024 11:40:46 +0300 Subject: [PATCH 17/35] MWB-806: update shacl --- .../app/shacl_validation_report/list-table.js | 212 +++++++++--------- .../shacl_validation_report_file.js | 94 ++++---- .../shacl_validation_report_package_state.js | 87 +++---- .../shacl_validation_report_test_dataset.js | 101 ++++----- .../shacl_validation_report_view.js | 70 +++--- .../sparql_validation_report_view.js | 8 +- .../xpath_validation_report_view.js | 7 +- 7 files changed, 295 insertions(+), 284 deletions(-) diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js index 59dcbe168..7d3ef81b8 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js @@ -1,25 +1,25 @@ import {useState} from "react"; import PropTypes from 'prop-types'; +import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; import Table from '@mui/material/Table'; +import Stack from "@mui/material/Stack"; +import Button from "@mui/material/Button"; +import Dialog from '@mui/material/Dialog'; +import TableRow from '@mui/material/TableRow'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableHead from '@mui/material/TableHead'; -import TableRow from '@mui/material/TableRow'; -import Button from "@mui/material/Button"; -import Dialog from '@mui/material/Dialog'; import DialogTitle from "@mui/material/DialogTitle"; import DialogContent from "@mui/material/DialogContent"; import DialogActions from "@mui/material/DialogActions"; -import Stack from "@mui/material/Stack"; import {Scrollbar} from 'src/components/scrollbar'; import {ResultChip, SorterHeader as UtilsSorterHeader} from "./utils"; -import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; -import TablePagination from "../../components/table-pagination"; +import TablePagination from "src/sections/components/table-pagination"; export const ListTable = (props) => { - const [descriptionDialog, setDescriptionDialog] = useState({open:false, title:"", text:""}) + const [descriptionDialog, setDescriptionDialog] = useState({open: false, title: "", text: ""}) const { count = 0, @@ -30,17 +30,18 @@ export const ListTable = (props) => { rowsPerPage = 0, sort, onSort, - sectionApi + sectionApi, + handleSelectFile } = props; const mapNotices = (notices) => { - return( -
    - {notices.map((notice,i) => -
  • - {`${notice.test_data_suite_id} / ${notice.test_data_id}`} -
  • )} -
+ return ( + notices.map((notice, i) => + ) ) } @@ -50,25 +51,25 @@ export const ListTable = (props) => { } const handleClose = () => { - setDescriptionDialog(e=>({...e, open: false})); + setDescriptionDialog(e => ({...e, open: false})); }; const SorterHeader = (props) => + /> const ResultCell = ({title, result, onClick}) => { return - {result.count} - {!!result.count && } - + alignItems="center" + justifyContent="start" + height={100}> + {result.count} + {!!result.count && } + } return ( @@ -89,87 +90,92 @@ export const ListTable = (props) => { - + - - - - - } - desc/> - - - } - desc/> - - - } - desc/> - - - } - desc/> - - - - - {items?.map((item, key) => { - return ( - - - {item.shacl_suite} - - + + + + + } + desc/> + + + } + desc/> + + + } + desc/> + + + } + desc/> + + + + + {items?.map((item, key) => { + return ( + + + {item.shacl_suite} + + {0} - - - - {item.short_result_path} - - - - - - - - - - - - - - - + + + + {item.short_result_path} + + + + + + + + + + + + + + + ); })} @@ -184,13 +190,13 @@ export const ListTable = (props) => { aria-describedby="alert-dialog-description" > - {descriptionDialog.title} + {descriptionDialog.title} - {descriptionDialog.description} + {descriptionDialog.description} - + diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_file.js b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_file.js index d81d4309d..4c117e7c2 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_file.js +++ b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_file.js @@ -1,12 +1,12 @@ import {useEffect, useState} from "react"; -import {mappingPackageStatesApi as sectionApi} from "../../../api/mapping-packages/states"; import Typography from "@mui/material/Typography"; -import ItemSearchInput from "../file-manager/item-search-input"; -import {ListTableFile} from "./list-table-file"; -import {ResultTable} from "./result-table"; import {TableLoadWrapper} from "./utils"; +import {ResultTable} from "./result-table"; +import {ListTableFile} from "./list-table-file"; +import ItemSearchInput from "../file-manager/item-search-input"; +import {mappingPackageStatesApi as sectionApi} from "src/api/mapping-packages/states"; const useItemsSearch = (items) => { @@ -19,7 +19,7 @@ const useItemsSearch = (items) => { direction: "desc" }, search: [], - searchColumns:["short_focus_node","message","short_result_path","short_result_severity","short_source_constraint_component"], + searchColumns: ["short_focus_node", "message", "short_result_path", "short_result_severity", "short_source_constraint_component"], page: sectionApi.DEFAULT_PAGE, rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE }); @@ -30,7 +30,7 @@ const useItemsSearch = (items) => { let returnItem = null; state.searchColumns.forEach(column => { state.search.forEach(search => { - if(item[column]?.toLowerCase()?.includes(search.toLowerCase())) + if (item[column]?.toLowerCase()?.includes(search.toLowerCase())) returnItem = item }) }) @@ -39,11 +39,11 @@ const useItemsSearch = (items) => { const filteredItems = searchItems.filter((item) => { let returnItem = item; - Object.entries(filters).forEach(filter=> { + Object.entries(filters).forEach(filter => { const [key, value] = filter - if(value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) + if (value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) returnItem = null - if(value !== "" && value !== undefined && typeof item[key] === "string" && item[key] !== value.toLowerCase()) + if (value !== "" && value !== undefined && typeof item[key] === "string" && item[key] !== value.toLowerCase()) returnItem = null }) return returnItem @@ -51,10 +51,10 @@ const useItemsSearch = (items) => { const sortedItems = () => { const sortColumn = state.sort.column - if(!sortColumn) { + if (!sortColumn) { return filteredItems } else { - return filteredItems.sort((a,b) => { + return filteredItems.sort((a, b) => { if (typeof a[sortColumn] === "string") return state.sort.direction === "asc" ? a[sortColumn]?.localeCompare(b[sortColumn]) : @@ -63,44 +63,38 @@ const useItemsSearch = (items) => { return state.sort.direction === "asc" ? a[sortColumn] - b[sortColumn] : b[sortColumn] - a[sortColumn] - }) + }) } } const pagedItems = sortedItems().filter((item, i) => { const pageSize = state.page * state.rowsPerPage - if((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) + if ((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) return item }) const handleSearchItems = (filters) => { - setState(prevState=> ({...prevState, search: filters })) + setState(prevState => ({...prevState, search: filters})) } const handleFiltersChange = (filters) => { - setState(prevState=> ({ - ...prevState, - filters, - page: 0 - })); + setState(prevState => ({...prevState, filters, page: 0})); } const handlePageChange = (event, page) => { - setState(prevState => ({ - ...prevState, - page - })); + setState(prevState => ({...prevState, page})); } const handleSort = (column) => { - setState(prevState=> ({ ...prevState, sort: {column, - direction: prevState.sort.column === column && prevState.sort.direction === "asc" ? "desc" : "asc"}})) + setState(prevState => ({ + ...prevState, sort: { + column, + direction: prevState.sort.column === column && prevState.sort.direction === "asc" ? "desc" : "asc" + } + })) } const handleRowsPerPageChange = (event) => { - setState(prevState => ({ - ...prevState, - rowsPerPage: parseInt(event.target.value, 10) - })); + setState(prevState => ({...prevState, rowsPerPage: parseInt(event.target.value, 10)})); } return { @@ -115,14 +109,14 @@ const useItemsSearch = (items) => { }; }; -const ShaclFileReport = ({ sid, suiteId, testId, files, mappingSuiteIdentifier }) => { +const ShaclFileReport = ({sid, suiteId, testId, files, mappingSuiteIdentifier}) => { const [validationReport, setValidationReport] = useState([]) const [validationResult, setValidationResult] = useState([]) - const [dataState, setDataState] = useState({load:true, error:false}) + const [dataState, setDataState] = useState({load: true, error: false}) - useEffect(()=>{ + useEffect(() => { handleValidationReportsGet(sid, suiteId, testId) - },[]) + }, []) const handleValidationReportsGet = async (sid, suiteId, testId) => { try { @@ -130,7 +124,7 @@ const ShaclFileReport = ({ sid, suiteId, testId, files, mappingSuiteIdentifier } const result = await sectionApi.getSparqlReportsFile(sid, suiteId, testId) setValidationReport(mapShaclFileResults(result.results?.[0]?.results?.[0]?.results) ?? []) setValidationResult(mapShaclFileStates(result.results?.[0]) ?? []); - setDataState(e=>({...e, load: false})) + setDataState(e => ({...e, load: false})) } catch (err) { console.error(err); setDataState({load: false, error: true}) @@ -143,13 +137,13 @@ const ShaclFileReport = ({ sid, suiteId, testId, files, mappingSuiteIdentifier } })) } - const mapShaclFileResults = (result) => result?.map(e=> ({...e.binding})) + const mapShaclFileResults = (result) => result?.map(e => ({...e.binding})) const itemsSearch = useItemsSearch(validationReport); return ( <> - Results @@ -157,7 +151,7 @@ const ShaclFileReport = ({ sid, suiteId, testId, files, mappingSuiteIdentifier } data={validationResult} lines={2}> + sectionApi={sectionApi}/> @@ -165,20 +159,20 @@ const ShaclFileReport = ({ sid, suiteId, testId, files, mappingSuiteIdentifier } - - + + ) } -export default ShaclFileReport \ No newline at end of file +export default ShaclFileReport \ No newline at end of file diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_package_state.js b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_package_state.js index 323d6f4c6..795fc5fb7 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_package_state.js +++ b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_package_state.js @@ -1,13 +1,12 @@ import {useEffect, useState} from "react"; -import {mappingPackageStatesApi as sectionApi} from "../../../api/mapping-packages/states"; import Typography from "@mui/material/Typography"; -import ItemSearchInput from "../file-manager/item-search-input"; import {ListTable} from "./list-table"; -import ResultSummaryTable from "./result-summary-table"; import {TableLoadWrapper} from "./utils"; - +import ResultSummaryTable from "./result-summary-table"; +import ItemSearchInput from "../file-manager/item-search-input"; +import {mappingPackageStatesApi as sectionApi} from "src/api/mapping-packages/states"; const useItemsSearch = (items) => { const [state, setState] = useState({ @@ -19,7 +18,7 @@ const useItemsSearch = (items) => { direction: "desc" }, search: [], - searchColumns:["test_suite","short_result_path"], + searchColumns: ["test_suite", "short_result_path"], page: sectionApi.DEFAULT_PAGE, rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE }); @@ -30,7 +29,7 @@ const useItemsSearch = (items) => { let returnItem = null; state.searchColumns.forEach(column => { state.search.forEach(search => { - if(item[column]?.toLowerCase()?.includes(search.toLowerCase())) + if (item[column]?.toLowerCase()?.includes(search.toLowerCase())) returnItem = item }) }) @@ -39,11 +38,11 @@ const useItemsSearch = (items) => { const filteredItems = searchItems.filter((item) => { let returnItem = item; - Object.entries(filters).forEach(filter=> { + Object.entries(filters).forEach(filter => { const [key, value] = filter - if(value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) + if (value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) returnItem = null - if(value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) + if (value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) returnItem = null }) return returnItem @@ -51,10 +50,10 @@ const useItemsSearch = (items) => { const sortedItems = () => { const sortColumn = state.sort.column - if(!sortColumn) { + if (!sortColumn) { return filteredItems } else { - return filteredItems.sort((a,b) => { + return filteredItems.sort((a, b) => { if (typeof a[sortColumn] === "string") return state.sort.direction === "asc" ? a[sortColumn]?.localeCompare(b[sortColumn]) : @@ -63,18 +62,18 @@ const useItemsSearch = (items) => { return state.sort.direction === "asc" ? a[sortColumn] - b[sortColumn] : b[sortColumn] - a[sortColumn] - }) + }) } } const pagedItems = sortedItems().filter((item, i) => { const pageSize = state.page * state.rowsPerPage - if((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) + if ((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) return item }) const handleSearchItems = (filters) => { - setState(prevState => ({...prevState, search: filters })) + setState(prevState => ({...prevState, search: filters})) } const handleFiltersChange = (filters) => { @@ -93,8 +92,12 @@ const useItemsSearch = (items) => { } const handleSort = (column, desc) => { - setState(prevState=> ({ ...prevState, sort: {column, - direction: prevState.sort.column === column ? prevState.sort.direction === "asc" ? "desc" : "asc" : desc ? "desc" : "asc" }})) + setState(prevState => ({ + ...prevState, sort: { + column, + direction: prevState.sort.column === column ? prevState.sort.direction === "asc" ? "desc" : "asc" : desc ? "desc" : "asc" + } + })) } @@ -117,25 +120,26 @@ const useItemsSearch = (items) => { }; }; -const ShaclPackageStateReport = ({ sid }) => { +const ShaclPackageStateReport = ({sid, handleSelectFile}) => { const [validationReport, setValidationReport] = useState([]) - const [dataState, setDataState] = useState({load:true, error:false}) + const [dataState, setDataState] = useState({load: true, error: false}) - useEffect(()=>{ + useEffect(() => { handleValidationReportsGet(sid) - },[]) - - const handleValidationReportsGet = async (sid) => { - try { - setDataState({load: true, error: false}) - const result = await sectionApi.getShaclReports(sid) - setValidationReport(mapShaclResults(result.summary)) - setDataState(e=>({...e, load: false})) - } catch (err) { - console.error(err); - setDataState({load: false, error: true}) - } + }, []) + + const handleValidationReportsGet = (sid) => { + setDataState({load: true, error: false}) + sectionApi.getShaclReports(sid) + .then(res => { + setValidationReport(mapShaclResults(res.summary)) + setDataState(e => ({...e, load: false})) + }) + .catch(err => { + console.error(err); + setDataState({load: false, error: true}) + }) } const mapShaclResults = (result) => { @@ -172,18 +176,19 @@ const ShaclPackageStateReport = ({ sid }) => { data={validationReport}> ) } -export default ShaclPackageStateReport \ No newline at end of file +export default ShaclPackageStateReport \ No newline at end of file diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_test_dataset.js b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_test_dataset.js index 349d1fc34..9f5b8566d 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_test_dataset.js +++ b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_test_dataset.js @@ -1,23 +1,22 @@ import {useEffect, useState} from "react"; -import {mappingPackageStatesApi as sectionApi} from "../../../api/mapping-packages/states"; import Typography from "@mui/material/Typography"; -import ItemSearchInput from "../file-manager/item-search-input"; import {ListTable} from "./list-table"; -import ResultSummaryTable from "./result-summary-table"; import {TableLoadWrapper} from "./utils"; +import ResultSummaryTable from "./result-summary-table"; +import ItemSearchInput from "../file-manager/item-search-input"; +import {mappingPackageStatesApi as sectionApi} from "src/api/mapping-packages/states"; const useItemsSearch = (items) => { const [state, setState] = useState({ - filters: { - }, + filters: {}, sort: { column: "", direction: "desc" }, search: [], - searchColumns:["test_suite","short_result_path"], + searchColumns: ["test_suite", "short_result_path"], page: sectionApi.DEFAULT_PAGE, rowsPerPage: sectionApi.DEFAULT_ROWS_PER_PAGE }); @@ -28,7 +27,7 @@ const useItemsSearch = (items) => { let returnItem = null; state.searchColumns.forEach(column => { state.search.forEach(search => { - if(item[column]?.toLowerCase()?.includes(search.toLowerCase())) + if (item[column]?.toLowerCase()?.includes(search.toLowerCase())) returnItem = item }) }) @@ -37,11 +36,11 @@ const useItemsSearch = (items) => { const filteredItems = searchItems.filter((item) => { let returnItem = item; - Object.entries(filters).forEach(filter=> { + Object.entries(filters).forEach(filter => { const [key, value] = filter - if(value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) + if (value !== "" && value !== undefined && typeof item[key] === "boolean" && item[key] !== (value == "true")) returnItem = null - if(value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) + if (value !== undefined && typeof item[key] === "string" && !item[key].toLowerCase().includes(value.toLowerCase)) returnItem = null }) return returnItem @@ -49,10 +48,10 @@ const useItemsSearch = (items) => { const sortedItems = () => { const sortColumn = state.sort.column - if(!sortColumn) { + if (!sortColumn) { return filteredItems } else { - return filteredItems.sort((a,b) => { + return filteredItems.sort((a, b) => { if (typeof a[sortColumn] === "string") return state.sort.direction === "asc" ? a[sortColumn]?.localeCompare(b[sortColumn]) : @@ -61,45 +60,39 @@ const useItemsSearch = (items) => { return state.sort.direction === "asc" ? a[sortColumn] - b[sortColumn] : b[sortColumn] - a[sortColumn] - }) + }) } } const pagedItems = sortedItems().filter((item, i) => { const pageSize = state.page * state.rowsPerPage - if((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) + if ((pageSize <= i && pageSize + state.rowsPerPage > i) || state.rowsPerPage < 0) return item }) const handleSearchItems = (filters) => { - setState(prevState => ({...prevState, search: filters })) + setState(prevState => ({...prevState, search: filters})) } const handleFiltersChange = (filters) => { - setState(prevState => ({ - ...prevState, - filters, - page: 0 - })); + setState(prevState => ({...prevState, filters, page: 0})); } const handlePageChange = (event, page) => { - setState(prevState => ({ - ...prevState, - page - })); + setState(prevState => ({...prevState, page})); } const handleSort = (column, desc) => { - setState(prevState=> ({ ...prevState, sort: {column, - direction: prevState.sort.column === column ? prevState.sort.direction === "asc" ? "desc" : "asc" : desc ? "desc" : "asc" }})) + setState(prevState => ({ + ...prevState, sort: { + column, + direction: prevState.sort.column === column ? prevState.sort.direction === "asc" ? "desc" : "asc" : desc ? "desc" : "asc" + } + })) } const handleRowsPerPageChange = (event) => { - setState(prevState => ({ - ...prevState, - rowsPerPage: parseInt(event.target.value, 10) - })); + setState(prevState => ({...prevState, rowsPerPage: parseInt(event.target.value, 10)})); } return { @@ -114,28 +107,29 @@ const useItemsSearch = (items) => { }; }; -const ShaclTestDatasetReport = ({ sid, suiteId }) => { +const ShaclTestDatasetReport = ({sid, suiteId, handleSelectFile}) => { const [validationReport, setValidationReport] = useState([]) - const [dataState, setDataState] = useState({load:true, error:false}) + const [dataState, setDataState] = useState({load: true, error: false}) - useEffect(()=>{ + useEffect(() => { handleValidationReportsGet(sid, suiteId) - },[]) + }, []) const handleValidationReportsGet = async (sid, suiteId) => { - try { - setDataState({load:true, error: false}) - const result = await sectionApi.getShaclReportsSuite(sid, suiteId) - setValidationReport(mapShaclResults(result.summary)) - setDataState(e=>({...e, load: false})) - } catch (err) { - console.error(err); - setDataState({load:false, error: true}) - } + setDataState({load: true, error: false}) + sectionApi.getShaclReportsSuite(sid, suiteId) + .then(res => { + setValidationReport(mapShaclResults(res.summary)) + setDataState(e => ({...e, load: false})) + }) + .catch(err => { + console.error(err); + setDataState({load: false, error: true}) + }) } - const mapShaclResults = (result) => { + const mapShaclResults = (result) => { return result.results.map(e => { const resultArray = {} resultArray["shacl_suite"] = result.shacl_suites?.[0]?.shacl_suite_id @@ -169,15 +163,16 @@ const ShaclTestDatasetReport = ({ sid, suiteId }) => { data={validationReport}> diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_view.js b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_view.js index 413dc643d..95c0f9303 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_view.js +++ b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_view.js @@ -1,83 +1,93 @@ import {useState} from "react"; -import Stack from "@mui/material/Stack"; -import Breadcrumbs from "@mui/material/Breadcrumbs"; -import KeyboardArrowRightIcon from "@mui/icons-material/KeyboardArrowRight"; +import ChevronRightIcon from '@mui/icons-material/ChevronRight'; + import Link from "@mui/material/Link"; +import Stack from "@mui/material/Stack"; import Typography from "@mui/material/Typography"; +import Breadcrumbs from "@mui/material/Breadcrumbs"; import CoverageFiles from "./coverage_files"; -import ShaclPackageStateReport from "./shacl_validation_report_package_state"; -import ShaclTestDatasetReport from "./shacl_validation_report_test_dataset"; import ShaclFileReport from "./shacl_validation_report_file"; +import ShaclTestDatasetReport from "./shacl_validation_report_test_dataset"; +import ShaclPackageStateReport from "./shacl_validation_report_package_state"; -const packageState = "package_state"; -const packageStateLabel = "Package State SHACL Coverage"; -const testDataset = "test_dataset"; -const testDatasetLabel = "Test Dataset SHACL Coverage"; -const fileCoverage = "file_coverage"; -const fileCoverageLabel = "File SHACL Coverage" +const PACKAGE_STATE = "package_state"; +const PACKAGE_STATE_LABEL = "Package State SHACL Coverage"; +const TEST_DATASET = "test_dataset"; +const TEST_DATASET_LABEL = "Test Dataset SHACL Coverage"; +const FILE_COVERAGE = "file_coverage"; +const FILE_COVERAGE_LABEL = "File SHACL Coverage" -const ShaclValidationReportView = ({ sid, reportTree }) => { +const ShaclValidationReportView = ({sid, reportTree}) => { const [selectedPackageState, setSelectedPackageState] = useState(reportTree.test_data_suites[0]) const [selectedTestDataset, setSelectedTestDataset] = useState(selectedPackageState.test_data_states[0]) - const [currentTab, setCurrentTab] = useState(packageState) + const [currentTab, setCurrentTab] = useState(PACKAGE_STATE) const handleSetPackageState = (file) => { setSelectedPackageState(file) - setCurrentTab(testDataset) + setCurrentTab(TEST_DATASET) } const handleSetTestDataset = (file) => { setSelectedTestDataset(file) - setCurrentTab(fileCoverage) + setCurrentTab(FILE_COVERAGE) + } + + const handleSetTestAndPackage = (testData, testDataSuite) => { + const packageState = reportTree.test_data_suites.find(tds => tds.oid === testDataSuite) + setSelectedTestDataset(packageState?.test_data_states.find(ps => ps.oid === testData)); + setSelectedPackageState(packageState); + setCurrentTab(FILE_COVERAGE) } return ( <> - }> + }> setCurrentTab(packageState)} + color={currentTab !== PACKAGE_STATE ? "inherit" : "primary"} + onClick={() => setCurrentTab(PACKAGE_STATE)} > - {packageStateLabel} + {PACKAGE_STATE_LABEL} - {currentTab !== packageState && + {currentTab !== PACKAGE_STATE && setCurrentTab(testDataset)} + color={currentTab !== TEST_DATASET ? "inherit" : "primary"} + onClick={() => setCurrentTab(TEST_DATASET)} > - {testDatasetLabel}: {{selectedPackageState.identifier}} + {TEST_DATASET_LABEL}: {{selectedPackageState.identifier}} } - {currentTab === fileCoverage && + {currentTab === FILE_COVERAGE && - {fileCoverageLabel}: {{selectedTestDataset.identifier}} + {FILE_COVERAGE_LABEL}: {{selectedTestDataset.identifier}} } - {currentTab === packageState && + {currentTab === PACKAGE_STATE && <> } - {currentTab === testDataset && + {currentTab === TEST_DATASET && <> } - {currentTab === fileCoverage && + {currentTab === FILE_COVERAGE && + suiteId={selectedPackageState.oid} + testId={selectedTestDataset.oid}/> } ) diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js index 643ebdfdb..8e09e16ff 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js +++ b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js @@ -1,11 +1,11 @@ import {useState} from "react"; -import KeyboardArrowRightIcon from "@mui/icons-material/KeyboardArrowRight"; +import ChevronRightIcon from '@mui/icons-material/ChevronRight'; -import Stack from "@mui/material/Stack"; -import Breadcrumbs from "@mui/material/Breadcrumbs"; import Link from "@mui/material/Link"; +import Stack from "@mui/material/Stack"; import Typography from "@mui/material/Typography"; +import Breadcrumbs from "@mui/material/Breadcrumbs"; import CoverageFiles from "./coverage_files"; import SparqlFileReport from "./sparql_validation_report_file"; @@ -45,7 +45,7 @@ const SparqlValidationReportView = ({sid, reportTree}) => { return ( <> - }> + }> setCurrentTab(PACKAGE_STATE)} diff --git a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_view.js b/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_view.js index c43942abd..eb70f033a 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_view.js +++ b/mapping_workbench/frontend/src/sections/app/xpath_validation_report/xpath_validation_report_view.js @@ -1,15 +1,16 @@ import {useState} from "react"; +import ChevronRightIcon from '@mui/icons-material/ChevronRight'; + import Link from "@mui/material/Link"; import Stack from "@mui/material/Stack"; import Typography from "@mui/material/Typography"; import Breadcrumbs from "@mui/material/Breadcrumbs"; -import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'; import CoverageFiles from "./coverage_files"; +import XpathValidationReportTest from "./xpath_validation_report_file"; import XpathValidationReport from "./xpath_validation_report_package_state"; import XpathValidationReportSuite from "./xpath_validation_report_test_dataset"; -import XpathValidationReportTest from "./xpath_validation_report_file"; const PACKAGE_STATE = "package_state" const PACKAGE_STATE_LABEL = "Package State XPath Coverage" @@ -43,7 +44,7 @@ const XpathValidationReportView = ({sid, reportTree}) => { return ( <> - }> + }> setCurrentTab(PACKAGE_STATE)} From 24e99309d289255bcd721495dbf29e245b45709e Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Wed, 25 Sep 2024 11:58:56 +0300 Subject: [PATCH 18/35] MWB-806: separate in 2 buttons --- .../app/shacl_validation_report/list-table.js | 18 +++++++++++++----- .../shacl_validation_report_test_dataset.js | 2 +- .../shacl_validation_report_view.js | 12 ++++++++---- .../app/sparql_validation_report/list-table.js | 18 +++++++++++++----- .../sparql_validation_report_test_dataset.js | 1 + .../sparql_validation_report_view.js | 12 ++++++++---- 6 files changed, 44 insertions(+), 19 deletions(-) diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js index 7d3ef81b8..234509736 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js @@ -37,11 +37,19 @@ export const ListTable = (props) => { const mapNotices = (notices) => { return ( notices.map((notice, i) => - ) + <> + + {' / '} + + ) ) } diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_test_dataset.js b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_test_dataset.js index 9f5b8566d..3bffb2486 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_test_dataset.js +++ b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_test_dataset.js @@ -116,7 +116,7 @@ const ShaclTestDatasetReport = ({sid, suiteId, handleSelectFile}) => { handleValidationReportsGet(sid, suiteId) }, []) - const handleValidationReportsGet = async (sid, suiteId) => { + const handleValidationReportsGet = (sid, suiteId) => { setDataState({load: true, error: false}) sectionApi.getShaclReportsSuite(sid, suiteId) .then(res => { diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_view.js b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_view.js index 95c0f9303..efa94503a 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_view.js +++ b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/shacl_validation_report_view.js @@ -35,11 +35,15 @@ const ShaclValidationReportView = ({sid, reportTree}) => { setCurrentTab(FILE_COVERAGE) } - const handleSetTestAndPackage = (testData, testDataSuite) => { + const handleSetTestAndPackage = (testDataSuite, testData) => { const packageState = reportTree.test_data_suites.find(tds => tds.oid === testDataSuite) - setSelectedTestDataset(packageState?.test_data_states.find(ps => ps.oid === testData)); - setSelectedPackageState(packageState); - setCurrentTab(FILE_COVERAGE) + if (testData) { + setSelectedTestDataset(packageState?.test_data_states.find(ps => ps.oid === testData)); + setCurrentTab(FILE_COVERAGE) + } else { + setSelectedPackageState(packageState); + setCurrentTab(TEST_DATASET) + } } return ( diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/list-table.js b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/list-table.js index 5c10d0379..ba0602a42 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/list-table.js @@ -39,11 +39,19 @@ export const ListTable = (props) => { const mapNotices = (notices) => { return ( notices.map((notice, i) => - ) + <> + + {' / '} + + ) ) } diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_test_dataset.js b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_test_dataset.js index 889226bf2..b56efc81f 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_test_dataset.js +++ b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_test_dataset.js @@ -1,4 +1,5 @@ import {useEffect, useState} from "react"; + import Typography from "@mui/material/Typography"; import {ListTable} from "./list-table"; diff --git a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js index 8e09e16ff..e02fb51b4 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js +++ b/mapping_workbench/frontend/src/sections/app/sparql_validation_report/sparql_validation_report_view.js @@ -35,11 +35,15 @@ const SparqlValidationReportView = ({sid, reportTree}) => { setCurrentTab(FILE_COVERAGE) } - const handleSetTestAndPackage = (testData, testDataSuite) => { + const handleSetTestAndPackage = (testDataSuite, testData) => { const packageState = reportTree.test_data_suites.find(tds => tds.oid === testDataSuite) - setSelectedTestDataset(packageState?.test_data_states.find(ps => ps.oid === testData)); - setSelectedPackageState(packageState); - setCurrentTab(FILE_COVERAGE) + if (testData) { + setSelectedTestDataset(packageState?.test_data_states.find(ps => ps.oid === testData)); + setCurrentTab(FILE_COVERAGE) + } else { + setSelectedPackageState(packageState); + setCurrentTab(TEST_DATASET) + } } return ( From 6ec8f3c7340494d018670f08039b17eeb8fd5508 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Thu, 26 Sep 2024 09:42:23 +0300 Subject: [PATCH 19/35] MWB-806: fix merge --- .../pages/app/mapping-packages/[id]/states/[sid]/view.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js b/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js index 1c1105f98..825070782 100644 --- a/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js +++ b/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js @@ -29,13 +29,13 @@ import {mappingPackageStatesApi as sectionApi} from 'src/api/mapping-packages/st const StateDetails = dynamic(() => import("src/sections/app/mapping-package/state/state-details")); const XpathValidationReportView = - dynamic(() => import("src/sections/app/xpath_validation_report/xpath_validation_report_view"), + dynamic(() => import("src/sections/app/xpath-validation-report/xpath_validation_report_view"), {loading: () => }); const SparqlValidationReport = - dynamic(() => import("src/sections/app/sparql_validation_report/sparql_validation_report_view"), + dynamic(() => import("src/sections/app/sparql-validation-report/sparql_validation_report_view"), {loading: () => }); const ShaclValidationReport = - dynamic(() => import("src/sections/app/shacl_validation_report/shacl_validation_report_view"), + dynamic(() => import("src/sections/app/shacl-validation-report/shacl_validation_report_view"), {loading: () => }); const tabs = [ From 8429d5b8aab7f1591201cd8bab060fa824d54352 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Thu, 26 Sep 2024 10:28:07 +0300 Subject: [PATCH 20/35] MWB-806: fix merge --- .../[id]/states/[sid]/view.js | 5 ++- .../mapping-package/state/state-details.js | 9 ++-- .../app/shacl-validation-report/list-table.js | 44 ++++++++++++------- .../shacl_validation_report_file.js | 23 +++++----- .../sparql-validation-report/list-table.js | 15 ++++--- .../sparql_validation_report_file.js | 4 +- .../sparql_validation_report_test_dataset.js | 2 +- .../xpath_validation_report_file.js | 2 +- .../xpath_validation_report_package_state.js | 2 +- .../xpath_validation_report_test_dataset.js | 2 +- 10 files changed, 61 insertions(+), 47 deletions(-) diff --git a/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js b/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js index 825070782..292e74c63 100644 --- a/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js +++ b/mapping_workbench/frontend/src/pages/app/mapping-packages/[id]/states/[sid]/view.js @@ -27,7 +27,8 @@ import {mappingPackagesApi as previousSectionApi} from 'src/api/mapping-packages import {mappingPackageStatesApi as sectionApi} from 'src/api/mapping-packages/states'; const StateDetails = - dynamic(() => import("src/sections/app/mapping-package/state/state-details")); + dynamic(() => import("src/sections/app/mapping-package/state/state-details"), + {loading: () => }); const XpathValidationReportView = dynamic(() => import("src/sections/app/xpath-validation-report/xpath_validation_report_view"), {loading: () => }); @@ -62,7 +63,7 @@ const Page = () => { } }, [sid]); - const handleItemsGet = async (sid) => { + const handleItemsGet = (sid) => { sectionApi.getState(sid) .then(res => setItem(res)) .catch(err => console.error(err)) diff --git a/mapping_workbench/frontend/src/sections/app/mapping-package/state/state-details.js b/mapping_workbench/frontend/src/sections/app/mapping-package/state/state-details.js index c90e42572..c20451aa5 100644 --- a/mapping_workbench/frontend/src/sections/app/mapping-package/state/state-details.js +++ b/mapping_workbench/frontend/src/sections/app/mapping-package/state/state-details.js @@ -1,9 +1,10 @@ -import Grid from "@mui/material/Unstable_Grid2"; import Card from "@mui/material/Card"; -import CardContent from "@mui/material/CardContent"; -import {PropertyList} from "../../../../components/property-list"; -import {PropertyListItem} from "../../../../components/property-list-item"; import Divider from "@mui/material/Divider"; +import Grid from "@mui/material/Unstable_Grid2"; +import CardContent from "@mui/material/CardContent"; + +import {PropertyList} from "src/components/property-list"; +import {PropertyListItem} from "src/components/property-list-item"; const StateDetails = ({item}) => { return( diff --git a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js index 1049a7389..d66e78c0c 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js @@ -1,17 +1,18 @@ import {useState} from "react"; import PropTypes from 'prop-types'; +import {Box} from "@mui/system"; +import Stack from "@mui/material/Stack"; import Table from '@mui/material/Table'; +import Button from "@mui/material/Button"; +import Dialog from '@mui/material/Dialog'; +import TableRow from '@mui/material/TableRow'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableHead from '@mui/material/TableHead'; -import TableRow from '@mui/material/TableRow'; -import Button from "@mui/material/Button"; -import Dialog from '@mui/material/Dialog'; import DialogTitle from "@mui/material/DialogTitle"; import DialogContent from "@mui/material/DialogContent"; import DialogActions from "@mui/material/DialogActions"; -import Stack from "@mui/material/Stack"; import {Scrollbar} from 'src/components/scrollbar'; import {ResultChip, SorterHeader as UtilsSorterHeader} from "./utils"; @@ -30,17 +31,26 @@ export const ListTable = (props) => { rowsPerPage = 0, sort, onSort, - sectionApi + sectionApi, + handleSelectFile } = props; const mapNotices = (notices) => { return ( -
    - {notices.map((notice, i) => -
  • - {`${notice.test_data_suite_id} / ${notice.test_data_id}`} -
  • )} -
+ notices.map((notice, i) => + + + {' / '} + + ) ) } @@ -89,7 +99,7 @@ export const ListTable = (props) => { - @@ -140,7 +150,7 @@ export const ListTable = (props) => { { diff --git a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/shacl_validation_report_file.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/shacl_validation_report_file.js index 4c117e7c2..e8b8667d5 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/shacl_validation_report_file.js +++ b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/shacl_validation_report_file.js @@ -118,17 +118,18 @@ const ShaclFileReport = ({sid, suiteId, testId, files, mappingSuiteIdentifier}) handleValidationReportsGet(sid, suiteId, testId) }, []) - const handleValidationReportsGet = async (sid, suiteId, testId) => { - try { - setDataState({load: true, error: false}) - const result = await sectionApi.getSparqlReportsFile(sid, suiteId, testId) - setValidationReport(mapShaclFileResults(result.results?.[0]?.results?.[0]?.results) ?? []) - setValidationResult(mapShaclFileStates(result.results?.[0]) ?? []); - setDataState(e => ({...e, load: false})) - } catch (err) { - console.error(err); - setDataState({load: false, error: true}) - } + const handleValidationReportsGet = (sid, suiteId, testId) => { + setDataState({load: true, error: false}) + sectionApi.getSparqlReportsFile(sid, suiteId, testId) + .then(res => { + setValidationReport(mapShaclFileResults(res.results?.[0]?.results?.[0]?.results) ?? []) + setValidationResult(mapShaclFileStates(res.results?.[0]) ?? []); + setDataState(e => ({...e, load: false})) + }) + .catch(err => { + console.error(err); + setDataState({load: false, error: true}) + }) } const mapShaclFileStates = (states) => { diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js index ba0602a42..296c91b76 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js @@ -2,6 +2,7 @@ import {useState} from "react"; import PropTypes from 'prop-types'; import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; +import {Box} from "@mui/system"; import Table from '@mui/material/Table'; import Stack from "@mui/material/Stack"; import Button from "@mui/material/Button"; @@ -39,19 +40,19 @@ export const ListTable = (props) => { const mapNotices = (notices) => { return ( notices.map((notice, i) => - <> - {' / '} - - ) + ) ) } @@ -169,7 +170,7 @@ export const ListTable = (props) => { { @@ -123,7 +123,7 @@ const SparqlFileReport = ({sid, suiteId, testId, files, mappingSuiteIdentifier}) handleValidationReportsGet(sid, suiteId, testId) }, []) - const handleValidationReportsGet = async (sid, suiteId, testId) => { + const handleValidationReportsGet = (sid, suiteId, testId) => { setDataState({load: true, error: false}) sectionApi.getSparqlReportsTest(sid, suiteId, testId) .then(res => { diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_test_dataset.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_test_dataset.js index b56efc81f..1e1ebeb5a 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_test_dataset.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_test_dataset.js @@ -123,7 +123,7 @@ const SparqlTestDatasetReport = ({sid, suiteId, handleSelectFile}) => { handleValidationReportsGet(sid, suiteId) }, []) - const handleValidationReportsGet = async (sid, suiteId) => { + const handleValidationReportsGet = (sid, suiteId) => { setDataState({load: true, error: false}) sectionApi.getSparqlReportsSuite(sid, suiteId) .then(res => { diff --git a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_file.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_file.js index 7b6c0eee3..eab715e51 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_file.js +++ b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_file.js @@ -122,7 +122,7 @@ const XpathValidationReportTest = ({sid, suiteId, testId, mappingSuiteIdentifier handleValidationReportsTestGet(sid, suiteId, testId) }, [testId]) - const handleValidationReportsTestGet = async (sid, suiteId, testId) => { + const handleValidationReportsTestGet = (sid, suiteId, testId) => { setDataState({load: true, error: false}) sectionApi.getXpathReportsTest(sid, suiteId, testId) .then(res => { diff --git a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_package_state.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_package_state.js index 708829b48..354147917 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_package_state.js +++ b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_package_state.js @@ -119,7 +119,7 @@ const XpathValidationReport = ({ sid, files, mappingSuiteIdentifier, handleSelec handleValidationReportsGet(sid) },[]) - const handleValidationReportsGet = async (sid) => { + const handleValidationReportsGet = (sid) => { setDataState({load: true, error: false}) sectionApi.getXpathReports(sid) .then(res => { diff --git a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_test_dataset.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_test_dataset.js index ed4d09090..763560e43 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_test_dataset.js +++ b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_test_dataset.js @@ -123,7 +123,7 @@ const XpathValidationReportSuite = ({sid, suiteId, files, mappingSuiteIdentifier handleValidationReportsSuiteGet(sid, suiteId) }, [suiteId]) - const handleValidationReportsSuiteGet = async (sid, suiteId) => { + const handleValidationReportsSuiteGet = (sid, suiteId) => { setDataState({load: true, error: false}) sectionApi.getXpathReportsSuite(sid, suiteId) .then(res => { From 557d2aebf6a028a7499947b51706dcbb9e2dbbb6 Mon Sep 17 00:00:00 2001 From: Kolea PLESCO Date: Thu, 26 Sep 2024 22:27:56 +0300 Subject: [PATCH 21/35] xpath condition updates: model, form --- .../adapters/standard/importer.py | 1 + .../models/imported_mapping_suite.py | 4 +- mapping_workbench/frontend/package.json | 2 +- .../src/components/app/form/code-text-area.js | 10 +- .../components/app/form/codeMirrorDefault.js | 2 +- .../app/conceptual-mapping-rule/cm-card.js | 26 ++- .../develop/add-edit-drawer.js | 3 +- .../develop/list-table.js | 158 +++++++++++------- .../app/conceptual-mapping-rule/edit-form.js | 20 ++- .../generic-triple-map-fragment/edit-form.js | 3 +- 10 files changed, 150 insertions(+), 79 deletions(-) diff --git a/mapping_workbench/backend/package_importer/adapters/standard/importer.py b/mapping_workbench/backend/package_importer/adapters/standard/importer.py index cff91dd95..41717bfdd 100644 --- a/mapping_workbench/backend/package_importer/adapters/standard/importer.py +++ b/mapping_workbench/backend/package_importer/adapters/standard/importer.py @@ -79,6 +79,7 @@ async def add_mapping_rules_from_mono(self, mono_package: ImportedMappingSuite): if self.package.id not in rule.refers_to_mapping_package_ids: rule.refers_to_mapping_package_ids.append(self.package.id) + rule.xpath_condition = mono_rule.xpath_condition rule.target_class_path = mono_rule.class_path rule.target_property_path = mono_rule.property_path rule.sort_order = sort_order diff --git a/mapping_workbench/backend/package_importer/models/imported_mapping_suite.py b/mapping_workbench/backend/package_importer/models/imported_mapping_suite.py index 13bcf197c..7db9deb2c 100644 --- a/mapping_workbench/backend/package_importer/models/imported_mapping_suite.py +++ b/mapping_workbench/backend/package_importer/models/imported_mapping_suite.py @@ -35,7 +35,7 @@ class EFormsMappingConceptualRule(BaseModel): bt_id: Optional[str] = Field(None, alias="BT ID") mapping_group_id: Optional[str] = Field(None, alias="Mapping Group ID") absolute_xpath: str = Field(..., alias="Absolute XPath") - xpath_condition: Optional[str] = Field(..., alias="XPath Condition") + xpath_condition: Optional[str] = Field(None, alias="XPath Condition") class_path: Optional[str] = Field(None, alias="Class Path") property_path: Optional[str] = Field(None, alias="Property Path") status: Optional[str] = Field(None, alias="Status") @@ -55,7 +55,7 @@ class StandardMappingConceptualRule(BaseModel): bt_name: Optional[str] = Field(None, alias="eForm BT Name (Provisional/Indicative) (O)") absolute_xpath: Optional[str] = Field(..., alias="Field XPath (M)") relative_xpath: Optional[str] = Field(..., alias="Field XPath (M)") - xpath_condition: Optional[str] = Field(..., alias="Field XPath condition (M)") + xpath_condition: Optional[str] = Field(None, alias="Field XPath condition (M)") class_path: Optional[str] = Field(None, alias="Class path (M)") property_path: Optional[str] = Field(None, alias="Property path (M)") reference_to_integration_tests: Optional[str] = Field(None, alias="Reference to Integration Tests (O)") diff --git a/mapping_workbench/frontend/package.json b/mapping_workbench/frontend/package.json index 73dff4770..0ca40d59c 100644 --- a/mapping_workbench/frontend/package.json +++ b/mapping_workbench/frontend/package.json @@ -95,7 +95,7 @@ "react-markdown": "8.0.7", "react-quill": "2.0.0", "react-redux": "8.0.5", - "react-simple-code-editor": "^0.13.1", + "react-simple-code-editor": "^0.14.1", "react-slick": "0.29.0", "react-syntax-highlighter": "15.5.0", "redux": "4.2.1", diff --git a/mapping_workbench/frontend/src/components/app/form/code-text-area.js b/mapping_workbench/frontend/src/components/app/form/code-text-area.js index 1450585af..845b0489a 100644 --- a/mapping_workbench/frontend/src/components/app/form/code-text-area.js +++ b/mapping_workbench/frontend/src/components/app/form/code-text-area.js @@ -25,7 +25,10 @@ export const FormCodeTextArea = (props) => { const { formik, name, label, required = false, + language_grammar = null, grammar = null, language = null, + height = eval(variables['codeTextareaHeight']), + innerHeight = null, disabled, ...other } = props; @@ -43,7 +46,7 @@ export const FormCodeTextArea = (props) => { formik.values[name] = content; }, [formik]); - const codeGrammar = grammar ? languages[grammar] : DEFAULT_GRAMMAR; + const codeGrammar = language_grammar || (grammar ? languages[grammar] : DEFAULT_GRAMMAR); const codeLanguage = language || DEFAULT_LANGUAGE; return ( @@ -60,7 +63,7 @@ export const FormCodeTextArea = (props) => { { outline: 'none', border: 0, boxShadow: 'none', - opacity: disabled ? .7 : 1 + opacity: disabled ? .7 : 1, + height: innerHeight }} textareaClassName={styles['code-textarea']} preClassName={styles['code-textarea-pre']} diff --git a/mapping_workbench/frontend/src/components/app/form/codeMirrorDefault.js b/mapping_workbench/frontend/src/components/app/form/codeMirrorDefault.js index 755908b73..eb2dfe3be 100644 --- a/mapping_workbench/frontend/src/components/app/form/codeMirrorDefault.js +++ b/mapping_workbench/frontend/src/components/app/form/codeMirrorDefault.js @@ -5,7 +5,7 @@ import {xml} from '@codemirror/lang-xml' import {json} from '@codemirror/lang-json' // import rdf from '@rdfjs-elements/rdf-editor' import {turtle} from 'codemirror-lang-turtle'; -import { sparql } from 'codemirror-lang-sparql'; +import {sparql} from 'codemirror-lang-sparql'; import {useTheme} from "@mui/material/styles"; diff --git a/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/cm-card.js b/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/cm-card.js index 19ee1b783..81fb8688f 100644 --- a/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/cm-card.js +++ b/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/cm-card.js @@ -18,6 +18,8 @@ import Dialog from "@mui/material/Dialog"; import {useDialog} from "../../../hooks/use-dialog"; import CMNotes from "./cm-notes"; import {toastError, toastLoad, toastSuccess} from "../../../components/app-toast"; +import Divider from "@mui/material/Divider"; +import {Prism as SyntaxHighlighter} from "react-syntax-highlighter"; const CMCard = (props) => { const {cm_rule, structural_element, cm_statuses, ...other} = props; @@ -146,13 +148,26 @@ const CMCard = (props) => { }} /> + {cm_rule.xpath_condition && + {cm_rule.xpath_condition} + } + sx={{ + whiteSpace: "pre-wrap", + py: 1.5 + }} + />} { }} /> -
- - {cm_rule.sparql_assertions && cm_rule.sparql_assertions.map(cm_query => +
+ {cm_rule.sparql_assertions.map(cm_query => )} -
+ }
+ { @@ -23,77 +28,108 @@ export const ListTableRow = (props) => { onDelete } = props; + const xpathConditionDialog = useDialog() + const [confirmOpen, setConfirmOpen] = useState(false); + const openXPathConditionDialog = () => { + xpathConditionDialog.handleOpen({}) + } + return ( - - - - {item.source_structural_element_sdk_element_id} - - - - {item.source_structural_element_absolute_xpath} - - - - {item.min_sdk_version} - - - {item.max_sdk_version} - - - {item.target_class_path} - - - {item.target_property_path} - - - - - onDelete(item)} - > - Are you sure you want to delete it? - - - + {item.source_structural_element_absolute_xpath} + + + {item.xpath_condition && + } + + + {item.min_sdk_version} + + + {item.max_sdk_version} + + + {item.target_class_path} + + + {item.target_property_path} + + + + + onDelete(item)} + > + Are you sure you want to delete it? + + + + + + XPath Condition + + + + {item.xpath_condition} + + + + ); } export const ListTable = (props) => { const { count = 0, items = [], - onPageChange = () => {}, - onSort = () => {}, + onPageChange = () => { + }, + onSort = () => { + }, sort, onRowsPerPageChange, page = 0, @@ -108,10 +144,10 @@ export const ListTable = (props) => { const SorterHeader = (props) => { const direction = props.fieldName === sort.column && sort.direction === 'desc' ? 'asc' : 'desc'; - return( + return ( ) } diff --git a/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/edit-form.js b/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/edit-form.js index 64529299e..c860f98c0 100644 --- a/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/edit-form.js +++ b/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/edit-form.js @@ -38,6 +38,9 @@ import {ListSelectorSelect as ResourceListSelector} from "src/components/app/lis import {MappingPackageCheckboxList} from "src/sections/app/mapping-package/components/mapping-package-checkbox-list"; import {TermValidityInfo} from "./term-validity"; +import {FormCodeTextArea} from "../../../components/app/form/code-text-area"; +import 'prismjs/components/prism-xquery'; + const RuleComment = ({formik, fieldName, idx, handleDelete, ...other}) => { @@ -197,6 +200,7 @@ export const EditForm = (props) => { const initialValues = { source_structural_element: item.source_structural_element?.id ?? '', + xpath_condition: item.xpath_condition ?? '', min_sdk_version: item.min_sdk_version ?? '', max_sdk_version: item.max_sdk_version ?? '', // mapping_group_id: item.mapping_group_id ?? '', @@ -327,7 +331,6 @@ export const EditForm = (props) => { if (isProjectDataReady >= 3) return ; - return (
@@ -473,6 +476,18 @@ export const EditForm = (props) => { + + + + @@ -903,7 +918,8 @@ export const EditForm = (props) => {
- ); + ) + ; } ; diff --git a/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/edit-form.js b/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/edit-form.js index 817da7f57..05ffa873f 100644 --- a/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/edit-form.js +++ b/mapping_workbench/frontend/src/sections/app/generic-triple-map-fragment/edit-form.js @@ -3,10 +3,8 @@ import {useCallback, useEffect, useState} from "react"; import PropTypes from 'prop-types'; import {useFormik} from 'formik'; import * as Yup from 'yup'; -import CodeMirror from '@uiw/react-codemirror'; import {turtle} from 'codemirror-lang-turtle'; import {yaml} from '@codemirror/lang-yaml'; -import {githubDark, githubLight} from '@uiw/codemirror-themes-all'; import {Box} from "@mui/system"; import Card from '@mui/material/Card'; @@ -250,6 +248,7 @@ export const EditForm = (props) => { // theme={theme.palette.mode === 'dark' ? githubDark : githubLight} style={{resize: 'vertical', overflow: 'auto', height: 600}} value={formik.values.triple_map_content} + lang={formik.values.format} // extensions={[lng[formik.values.format].extension()]} onChange={(value) => formik.setFieldValue('triple_map_content', value)} // options={{ From 84f793c732a943362596f77b627b33dd10660990 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Fri, 27 Sep 2024 09:00:31 +0300 Subject: [PATCH 22/35] MWB-797: clean up tests --- mapping_workbench/frontend/cypress.config.js | 2 +- .../frontend/cypress/e2e/cleanUp.feature | 13 +++++++----- .../frontend/cypress/e2e/cleanUp/cleanUp.js | 20 +++++++++---------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/mapping_workbench/frontend/cypress.config.js b/mapping_workbench/frontend/cypress.config.js index 10ef01502..a4eee7900 100644 --- a/mapping_workbench/frontend/cypress.config.js +++ b/mapping_workbench/frontend/cypress.config.js @@ -60,7 +60,7 @@ module.exports = defineConfig({ // "cypress/e2e/termValidator.feature", // "cypress/e2e/sparqlQueries.feature", // "cypress/e2e/genericTripleMaps.feature", - // "cypress/e2e/cleanUp.feature", + "cypress/e2e/cleanUp.feature", ], video: false, // reporter: 'junit', diff --git a/mapping_workbench/frontend/cypress/e2e/cleanUp.feature b/mapping_workbench/frontend/cypress/e2e/cleanUp.feature index c5dc42581..dd0eb846d 100644 --- a/mapping_workbench/frontend/cypress/e2e/cleanUp.feature +++ b/mapping_workbench/frontend/cypress/e2e/cleanUp.feature @@ -1,13 +1,16 @@ -Feature: Entry Packages +Feature: CleanUp after test - As a valid use i want to see package - Scenario: Delete Packages + As a valid user i want cleanup data after tests + + Background: Given Session Login Then Go Home Then Check home title - Then I click on account button - Then I select project setup + Scenario: Delete Packages + Then Visit Projects + Then I get redirected to projects list page + Then I type project name When I click on delete button Then I click yes button diff --git a/mapping_workbench/frontend/cypress/e2e/cleanUp/cleanUp.js b/mapping_workbench/frontend/cypress/e2e/cleanUp/cleanUp.js index 0e06f4a07..5038e17df 100644 --- a/mapping_workbench/frontend/cypress/e2e/cleanUp/cleanUp.js +++ b/mapping_workbench/frontend/cypress/e2e/cleanUp/cleanUp.js @@ -1,10 +1,10 @@ import {Given, Then, When} from 'cypress-cucumber-preprocessor/steps' -const {username, password, homeURL, projectName, appURLPrefix , homePageLabel} = Cypress.env() +const {username, password, homeURL, projectName, appURLPrefix, homePageLabel} = Cypress.env() Given('Session Login', () => { // Caching session when logging in via page visit - cy.session([username,password], () => { + cy.session([username, password], () => { cy.visit(homeURL) cy.get('[name=username]').clear().type(username) cy.get('[name=password]').clear().type(password) @@ -14,23 +14,21 @@ Given('Session Login', () => { }) Then('Check home title', () => { - cy.title().should('eq',homePageLabel) + cy.title().should('eq', homePageLabel) }) -Then('I click on account button', () => { - cy.get('#account_button').click() +Then('Visit Projects', () => { + cy.visit(homeURL + '/app/projects') }) -Then('I select project setup', () => { - cy.get('#project_setup_button').click() +Then('I get redirected to projects list page', () => { + cy.title().should('eq', 'App: Projects List | Mapping Workbench') }) -Then('I search for project', () => { - // cy.intercept('GET', appURLPrefix + '/projects*',).as('get') +Then('I type project name', () => { cy.get('input[type=text]').clear().type(projectName + '{enter}') }) - When('I click on delete button', () => { cy.get('#delete_button').click() }) @@ -41,6 +39,6 @@ Then('I click yes button', () => { }) Then('I get success delete', () => { - cy.wait('@delete').its('response.statusCode').should('eq',200) + cy.wait('@delete').its('response.statusCode').should('eq', 200) }) From e216f83f6abd5e22a888f1681ad5e0b7405f30c3 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Fri, 27 Sep 2024 10:10:12 +0300 Subject: [PATCH 23/35] MWB-797: update table data --- .../app/shacl-validation-report/list-table.js | 15 ++- .../list-table-file.js | 110 +++++++----------- .../sparql-validation-report/list-table.js | 17 +-- 3 files changed, 57 insertions(+), 85 deletions(-) diff --git a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js index d66e78c0c..ad4ec9500 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js @@ -59,9 +59,7 @@ export const ListTable = (props) => { setDescriptionDialog({open: true, title, description}); } - const handleClose = () => { - setDescriptionDialog(e => ({...e, open: false})); - }; + const handleClose = () => setDescriptionDialog(e => ({...e, open: false})); const SorterHeader = (props) => { alignItems="center" justifyContent="start" height={100}> - {result.count} - {!!result.count && } + {result.count + ? + : {result.count}}
} diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js index e0a0a007b..bad1169ae 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js @@ -1,29 +1,23 @@ import {useState} from "react"; +import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; +import PropTypes from 'prop-types'; +import {Box} from "@mui/system"; +import Chip from "@mui/material/Chip"; import Table from '@mui/material/Table'; +import TableRow from '@mui/material/TableRow'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; -import TableSortLabel from '@mui/material/TableSortLabel'; import TableHead from '@mui/material/TableHead'; -import TableRow from '@mui/material/TableRow'; import Typography from '@mui/material/Typography'; -import Tooltip from "@mui/material/Tooltip"; -import Button from "@mui/material/Button"; -import Dialog from '@mui/material/Dialog'; -import DialogTitle from "@mui/material/DialogTitle"; -import DialogContent from "@mui/material/DialogContent"; -import DialogActions from "@mui/material/DialogActions"; -import DialogContentText from "@mui/material/DialogContentText"; -import Chip from "@mui/material/Chip"; -import {Scrollbar} from 'src/components/scrollbar'; -import PropTypes from 'prop-types'; import {resultColor} from "./utils"; -import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; -import TablePagination from "../../components/table-pagination"; +import {Scrollbar} from 'src/components/scrollbar'; +import TablePagination from "src/sections/components/table-pagination"; +import TableSorterHeader from "src/sections/components/table-sorter-header"; export const ListTableFile = (props) => { - const [descriptionDialog, setDescriptionDialog] = useState({open:false, title:"", text:""}) + const [descriptionDialog, setDescriptionDialog] = useState({open: false, title: "", text: ""}) const { count = 0, @@ -37,30 +31,14 @@ export const ListTableFile = (props) => { sectionApi } = props; - const handleOpenDescription = ({title, description}) => { - setDescriptionDialog({open: true, title, description}); - }; - - const handleOpenDetails = ({title, fields_covered, query_result}) => { - const description = <>
  • {`Query result: ${query_result}`}
  • {`Fields covered: ${fields_covered}`}
  • - setDescriptionDialog({open: true, title, description}); - } - - const handleClose = () => { - setDescriptionDialog(e=>({...e, open: false})); - }; - - const SorterHeader = ({fieldName, title}) => { - return - onSort(fieldName)}> - {title ?? fieldName} - - + const SorterHeader = (props) => { + const direction = props.fieldName === sort.column && sort.direction === 'desc' ? 'asc' : 'desc'; + return ( + + ) } return ( @@ -88,8 +66,8 @@ export const ListTableFile = (props) => { Description - + {
    - + + + + {item.description} + + + {/*{item.description}*/} + {/**/} + wrapLines + lineProps={{ + style: { + overflowWrap: 'break-word', + whiteSpace: 'pre-wrap' + } + }}> {item.query} @@ -128,10 +118,10 @@ export const ListTableFile = (props) => { color={resultColor(item.result)}/> - + + {`Query result: ${item.query_result}`} + {`Fields covered: ${item.fields_covered}`} + @@ -141,24 +131,6 @@ export const ListTableFile = (props) => { - - - {descriptionDialog.title} - - - - {descriptionDialog.description} - - - - - - ); }; diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js index 296c91b76..9ef01de9e 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js @@ -80,11 +80,12 @@ export const ListTable = (props) => { alignItems="center" justifyContent="start" height={100}> - {result.count} - {!!result.count && } + {result.count + ? + : {result.count}} } @@ -110,8 +111,8 @@ export const ListTable = (props) => { title="Field"/> - + {
    - {item.test_suite} + {item.xpath_condition} Date: Fri, 27 Sep 2024 10:27:54 +0300 Subject: [PATCH 24/35] MWB-797: remove unused code --- .../app/sparql-validation-report/list-table-file.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js index bad1169ae..f2e46e779 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js @@ -1,4 +1,3 @@ -import {useState} from "react"; import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; import PropTypes from 'prop-types'; @@ -17,7 +16,6 @@ import TablePagination from "src/sections/components/table-pagination"; import TableSorterHeader from "src/sections/components/table-sorter-header"; export const ListTableFile = (props) => { - const [descriptionDialog, setDescriptionDialog] = useState({open: false, title: "", text: ""}) const { count = 0, @@ -63,7 +61,8 @@ export const ListTableFile = (props) => { title="Field"/> - Description + { {item.description} - {/*{item.description}*/} - {/**/} Date: Fri, 27 Sep 2024 14:56:33 +0300 Subject: [PATCH 25/35] MWB-797: notice selection for xpath --- .../app/xpath-validation-report/list-table.js | 56 ++++++++++++++++++- .../xpath_validation_report_view.js | 12 ++-- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js index 7698a0b24..c75e5f694 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js @@ -17,6 +17,11 @@ import Typography from '@mui/material/Typography'; import {Scrollbar} from 'src/components/scrollbar'; import TablePagination from "src/sections/components/table-pagination"; import TableSorterHeader from "src/sections/components/table-sorter-header"; +import Dialog from "@mui/material/Dialog"; +import DialogTitle from "@mui/material/DialogTitle"; +import DialogContent from "@mui/material/DialogContent"; +import DialogActions from "@mui/material/DialogActions"; +import {Box} from "@mui/system"; export const ListTable = (props) => { @@ -33,12 +38,43 @@ export const ListTable = (props) => { sort } = props; + const [descriptionDialog, setDescriptionDialog] = useState({open: false, title: "", description: ""}) + const [popover, setPopover] = useState({}) const setPopoverOpen = (item, anchor) => { setPopover({data: item, anchor}) } + const handleClose = () => { + setDescriptionDialog(e => ({...e, open: false})); + }; + + const mapNotices = (notices) => { + return ( + notices.map((notice, i) => + + + {' / '} + + ) + ) + } + + + const handleOpenDetails = (title, notices) => { + const description = mapNotices(notices) + setDescriptionDialog({open: true, title, description}); + } + const SorterHeader = (props) => { const direction = props.fieldName === sort.column && sort.direction === 'desc' ? 'asc' : 'desc'; return ( @@ -111,7 +147,9 @@ export const ListTable = (props) => { @@ -148,6 +186,22 @@ export const ListTable = (props) => { {e.test_data_id} )} + + + {descriptionDialog.title} + + + {descriptionDialog.description} + + + + + ); }; diff --git a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_view.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_view.js index eb70f033a..f7fd9da5f 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_view.js +++ b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/xpath_validation_report_view.js @@ -34,11 +34,15 @@ const XpathValidationReportView = ({sid, reportTree}) => { setCurrentTab(FILE_COVERAGE) } - const handleSetTestAndPackage = (testData, testDataSuite) => { + const handleSetTestAndPackage = (testDataSuite, testData) => { const packageState = reportTree.test_data_suites.find(tds => tds.oid === testDataSuite) - setSelectedTestDataset(packageState?.test_data_states.find(ps => ps.oid === testData)); - setSelectedPackageState(packageState); - setCurrentTab(FILE_COVERAGE) + if (testData) { + setSelectedTestDataset(packageState?.test_data_states.find(ps => ps.oid === testData)); + setCurrentTab(FILE_COVERAGE) + } else { + setSelectedPackageState(packageState); + setCurrentTab(TEST_DATASET) + } } return ( From bd3c4dcddb3bf136e2662076b187895a972b1cec Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Fri, 27 Sep 2024 15:10:54 +0300 Subject: [PATCH 26/35] MWB-797: clean code --- .../app/shacl-validation-report/list-table.js | 42 ++-- .../app/shacl_validation_report/list-table.js | 221 ------------------ .../sparql-validation-report/list-table.js | 10 +- .../app/xpath-validation-report/list-table.js | 56 +---- 4 files changed, 30 insertions(+), 299 deletions(-) delete mode 100644 mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js diff --git a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js index ad4ec9500..963732e96 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js @@ -14,10 +14,11 @@ import DialogTitle from "@mui/material/DialogTitle"; import DialogContent from "@mui/material/DialogContent"; import DialogActions from "@mui/material/DialogActions"; +import {ResultChip} from "./utils"; import {Scrollbar} from 'src/components/scrollbar'; -import {ResultChip, SorterHeader as UtilsSorterHeader} from "./utils"; import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; -import TablePagination from "../../components/table-pagination"; +import TablePagination from "src/sections/components/table-pagination"; +import TableSorterHeader from "src/sections/components/table-sorter-header"; export const ListTable = (props) => { const [descriptionDialog, setDescriptionDialog] = useState({open: false, title: "", text: ""}) @@ -35,33 +36,28 @@ export const ListTable = (props) => { handleSelectFile } = props; - const mapNotices = (notices) => { - return ( - notices.map((notice, i) => - - - {' / '} - - ) - ) - } - const handleOpenDetails = ({title, notices}) => { - const description = mapNotices(notices) + const description = notices.map((notice, i) => + + + {' / '} + + ) + setDescriptionDialog({open: true, title, description}); } const handleClose = () => setDescriptionDialog(e => ({...e, open: false})); - const SorterHeader = (props) => diff --git a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js b/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js deleted file mode 100644 index 234509736..000000000 --- a/mapping_workbench/frontend/src/sections/app/shacl_validation_report/list-table.js +++ /dev/null @@ -1,221 +0,0 @@ -import {useState} from "react"; -import PropTypes from 'prop-types'; -import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; - -import Table from '@mui/material/Table'; -import Stack from "@mui/material/Stack"; -import Button from "@mui/material/Button"; -import Dialog from '@mui/material/Dialog'; -import TableRow from '@mui/material/TableRow'; -import TableBody from '@mui/material/TableBody'; -import TableCell from '@mui/material/TableCell'; -import TableHead from '@mui/material/TableHead'; -import DialogTitle from "@mui/material/DialogTitle"; -import DialogContent from "@mui/material/DialogContent"; -import DialogActions from "@mui/material/DialogActions"; - -import {Scrollbar} from 'src/components/scrollbar'; -import {ResultChip, SorterHeader as UtilsSorterHeader} from "./utils"; -import TablePagination from "src/sections/components/table-pagination"; - -export const ListTable = (props) => { - const [descriptionDialog, setDescriptionDialog] = useState({open: false, title: "", text: ""}) - - const { - count = 0, - items = [], - onPageChange, - onRowsPerPageChange, - page = 0, - rowsPerPage = 0, - sort, - onSort, - sectionApi, - handleSelectFile - } = props; - - const mapNotices = (notices) => { - return ( - notices.map((notice, i) => - <> - - {' / '} - - ) - ) - } - - const handleOpenDetails = ({title, notices}) => { - const description = mapNotices(notices) - setDescriptionDialog({open: true, title, description}); - } - - const handleClose = () => { - setDescriptionDialog(e => ({...e, open: false})); - }; - - const SorterHeader = (props) => - - const ResultCell = ({title, result, onClick}) => { - return - {result.count} - {!!result.count && } - - } - - return ( - <> - - - - - - - - - - - - - - - - - } - desc/> - - - } - desc/> - - - } - desc/> - - - } - desc/> - - - - - {items?.map((item, key) => { - return ( - - - {item.shacl_suite} - - - {0} - - - - {item.short_result_path} - - - - - - - - - - - - - - - - - ); - })} - -
    -
    -
    - - - {descriptionDialog.title} - - - {descriptionDialog.description} - - - - - - - ); -}; - -ListTable.propTypes = { - count: PropTypes.number, - items: PropTypes.array, - onPageChange: PropTypes.func, - onRowsPerPageChange: PropTypes.func, - page: PropTypes.number, - rowsPerPage: PropTypes.number -}; diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js index 9ef01de9e..c2f7c3688 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js @@ -37,9 +37,8 @@ export const ListTable = (props) => { handleSelectFile } = props; - const mapNotices = (notices) => { - return ( - notices.map((notice, i) => + const handleOpenDetails = ({title, notices}) => { + const description = notices.map((notice, i) => ) - ) - } - - const handleOpenDetails = ({title, notices}) => { - const description = mapNotices(notices) setDescriptionDialog({open: true, title, description}); } diff --git a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js index c75e5f694..cdeb32344 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js @@ -1,27 +1,26 @@ import {useState} from "react"; import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; - import PropTypes from 'prop-types'; + import CheckIcon from '@mui/icons-material/Check'; import CloseIcon from '@mui/icons-material/Close'; +import {Box} from "@mui/system"; import Table from '@mui/material/Table'; +import Dialog from "@mui/material/Dialog"; import Button from "@mui/material/Button"; -import Popover from "@mui/material/Popover"; import TableRow from '@mui/material/TableRow'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableHead from '@mui/material/TableHead'; import Typography from '@mui/material/Typography'; +import DialogTitle from "@mui/material/DialogTitle"; +import DialogContent from "@mui/material/DialogContent"; +import DialogActions from "@mui/material/DialogActions"; import {Scrollbar} from 'src/components/scrollbar'; import TablePagination from "src/sections/components/table-pagination"; import TableSorterHeader from "src/sections/components/table-sorter-header"; -import Dialog from "@mui/material/Dialog"; -import DialogTitle from "@mui/material/DialogTitle"; -import DialogContent from "@mui/material/DialogContent"; -import DialogActions from "@mui/material/DialogActions"; -import {Box} from "@mui/system"; export const ListTable = (props) => { @@ -40,19 +39,10 @@ export const ListTable = (props) => { const [descriptionDialog, setDescriptionDialog] = useState({open: false, title: "", description: ""}) - const [popover, setPopover] = useState({}) + const handleClose = () => setDescriptionDialog(e => ({...e, open: false})); - const setPopoverOpen = (item, anchor) => { - setPopover({data: item, anchor}) - } - - const handleClose = () => { - setDescriptionDialog(e => ({...e, open: false})); - }; - - const mapNotices = (notices) => { - return ( - notices.map((notice, i) => + const handleOpenDetails = (title, notices) => { + const description = notices.map((notice, i) => ) - ) - } - - const handleOpenDetails = (title, notices) => { - const description = mapNotices(notices) setDescriptionDialog({open: true, title, description}); } @@ -147,8 +132,6 @@ export const ListTable = (props) => { @@ -165,27 +148,6 @@ export const ListTable = (props) => { - setPopover({})} - anchorOrigin={{ - vertical: 'bottom', - horizontal: 'left', - }} - transformOrigin={{ - vertical: 'top', - horizontal: 'center', - }} - > - {popover.data?.test_data_xpaths?.map((e, i) => - )} - Date: Fri, 27 Sep 2024 23:30:14 +0300 Subject: [PATCH 27/35] xpath condition validation --- .../adapters/sparql_validator.py | 31 +++-- .../adapters/xpath_validator.py | 41 +++++-- .../models/sparql_validation.py | 1 + .../models/xpath_validation.py | 2 + .../services/mapping_package_validator.py | 2 +- .../services/xpath_coverage_validator.py | 109 ++++++++++-------- .../list-table-file.js | 83 +++++++++---- 7 files changed, 177 insertions(+), 92 deletions(-) diff --git a/mapping_workbench/backend/package_validator/adapters/sparql_validator.py b/mapping_workbench/backend/package_validator/adapters/sparql_validator.py index e4de890bc..3fa5445e9 100644 --- a/mapping_workbench/backend/package_validator/adapters/sparql_validator.py +++ b/mapping_workbench/backend/package_validator/adapters/sparql_validator.py @@ -79,24 +79,33 @@ def process_sparql_result(self, sparql_query_result: SPARQLQueryResult): for xpath_assertion in xpath_validation_results: if xpath_assertion.is_covered: validation_xpaths.add(xpath_assertion.sdk_element_xpath.strip()) + sparql_query_result.meets_xpath_condition = xpath_assertion.meets_xpath_condition sparql_query_result.fields_covered = (not sparql_query_xpath or ( sparql_query_xpath in validation_xpaths )) # Refined result - result = self.refined_result(ask_answer, sparql_query_result, result) + result = self.refined_result(ask_answer, sparql_query_result) sparql_query_result.result = result @classmethod - def refined_result(cls, ask_answer, sparql_query_result, result: SPARQLQueryRefinedResultType) \ + def refined_result(cls, ask_answer, sparql_query_result: SPARQLQueryResult) \ -> SPARQLQueryRefinedResultType: - if ask_answer and sparql_query_result.fields_covered: - result = SPARQLQueryRefinedResultType.VALID.value - elif not ask_answer and not sparql_query_result.fields_covered: - result = SPARQLQueryRefinedResultType.UNVERIFIABLE.value - elif ask_answer and not sparql_query_result.fields_covered: - result = SPARQLQueryRefinedResultType.WARNING.value - elif not ask_answer and sparql_query_result.fields_covered: - result = SPARQLQueryRefinedResultType.INVALID.value - return result + + if sparql_query_result.fields_covered: + if ask_answer: + if sparql_query_result.meets_xpath_condition: + return SPARQLQueryRefinedResultType.VALID.value + else: + return SPARQLQueryRefinedResultType.WARNING.value + else: + if sparql_query_result.meets_xpath_condition: + return SPARQLQueryRefinedResultType.INVALID.value + else: + return SPARQLQueryRefinedResultType.VALID.value + else: + if ask_answer: + return SPARQLQueryRefinedResultType.WARNING.value + else: + return SPARQLQueryRefinedResultType.UNVERIFIABLE.value diff --git a/mapping_workbench/backend/package_validator/adapters/xpath_validator.py b/mapping_workbench/backend/package_validator/adapters/xpath_validator.py index d47798eb7..78999708d 100644 --- a/mapping_workbench/backend/package_validator/adapters/xpath_validator.py +++ b/mapping_workbench/backend/package_validator/adapters/xpath_validator.py @@ -4,7 +4,8 @@ from xml.etree import ElementTree from pydantic import validate_call -from saxonche import PySaxonProcessor, PySaxonApiError, PyXPathProcessor, PyXdmNode, PyXdmValue, XdmNodeKind +from saxonche import PySaxonProcessor, PySaxonApiError, PyXPathProcessor, PyXdmNode, PyXdmValue, XdmNodeKind, \ + PyXQueryProcessor from mapping_workbench.backend.logger.services import mwb_logger from mapping_workbench.backend.package_validator.adapters.data_validator import TestDataValidator @@ -15,7 +16,9 @@ class XPATHValidator(TestDataValidator): """ """ - xp: Any = None + xp: Any = None # saxon_processor + xpp: Any = None # xpath_processor + xqp: Any = None # xquery_processor namespaces: Any = None prefixes: Any = None DEFAULT_XML_NS_PREFIX: str = '' @@ -25,11 +28,24 @@ def __init__(self, xml_content, **data: Any): super().__init__(**data) self.namespaces = self.extract_namespaces(xml_content) self.prefixes = {v: k for k, v in self.namespaces.items()} - self.xp = self.init_xp_processor(xml_content) + self.xp = PySaxonProcessor(license=False) + self.init_xp_processors(xml_content) def validate(self, xpath_expression) -> List[XPathAssertionEntry]: return self.get_unique_xpaths(xpath_expression) + def check_xpath_condition(self, xquery_expression) -> bool: + if not xquery_expression: + return True + + try: + self.xqp.set_query_content(xquery_expression) + result: PyXdmValue = self.xqp.run_query_to_value() + return str(result) == 'true' + except PySaxonApiError as e: + mwb_logger.log_all_error(str(e), str(e)) + return False + def get_ns_tag(self, node: PyXdmNode) -> Union[str, None]: if node is None or node.name is None: return None @@ -78,19 +94,22 @@ def extract_namespaces(self, xml_content): namespaces[ns] = url return namespaces - def init_xp_processor(self, xml_content: str) -> PyXPathProcessor: - proc = PySaxonProcessor(license=False) - xp = proc.new_xpath_processor() + def init_xp_processors(self, xml_content: str): + + self.xpp: PyXPathProcessor = self.xp.new_xpath_processor() + self.xqp: PyXQueryProcessor = self.xp.new_xquery_processor() + for prefix, ns_uri in self.namespaces.items(): - xp.declare_namespace(prefix, ns_uri) - document = proc.parse_xml(xml_text=xml_content) - xp.set_context(xdm_item=document) + self.xpp.declare_namespace(prefix, ns_uri) + self.xqp.declare_namespace(prefix, ns_uri) - return xp + document = self.xp.parse_xml(xml_text=xml_content) + self.xpp.set_context(xdm_item=document) + self.xqp.set_context(xdm_item=document) def check_xpath_expression(self, xpath_expression: str) -> Union[PyXdmValue, None]: try: - return self.xp.evaluate(xpath_expression) + return self.xpp.evaluate(xpath_expression) except PySaxonApiError | Exception as e: mwb_logger.log_all_error(str(e), str(e)) return None diff --git a/mapping_workbench/backend/package_validator/models/sparql_validation.py b/mapping_workbench/backend/package_validator/models/sparql_validation.py index b75951c8a..af18721bd 100644 --- a/mapping_workbench/backend/package_validator/models/sparql_validation.py +++ b/mapping_workbench/backend/package_validator/models/sparql_validation.py @@ -37,6 +37,7 @@ class SPARQLQueryResult(ValidationSPARQLQuery, BaseModel): result: Optional[SPARQLQueryRefinedResultType] = None query_result: Optional[bool] = None fields_covered: Optional[bool] = True + meets_xpath_condition: Optional[bool] = True missing_fields: Optional[List[CMRuleSDKElement]] = [] error: Optional[str] = None message: Optional[str] = None diff --git a/mapping_workbench/backend/package_validator/models/xpath_validation.py b/mapping_workbench/backend/package_validator/models/xpath_validation.py index f9d684282..008031fc4 100644 --- a/mapping_workbench/backend/package_validator/models/xpath_validation.py +++ b/mapping_workbench/backend/package_validator/models/xpath_validation.py @@ -18,6 +18,8 @@ class XPathAssertionTestDataEntry(ValidationTestDataEntry): class XPathAssertion(CMRuleSDKElement): test_data_xpaths: Optional[List[XPathAssertionTestDataEntry]] = None is_covered: Optional[bool] = False + xpath_condition: Optional[str] = None + meets_xpath_condition: Optional[bool] = True message: Optional[str] = None class Settings: diff --git a/mapping_workbench/backend/package_validator/services/mapping_package_validator.py b/mapping_workbench/backend/package_validator/services/mapping_package_validator.py index 708750efd..e160df061 100644 --- a/mapping_workbench/backend/package_validator/services/mapping_package_validator.py +++ b/mapping_workbench/backend/package_validator/services/mapping_package_validator.py @@ -43,7 +43,7 @@ async def validate_mapping_package(mapping_package_state: MappingPackageState, t if tasks_to_run is None or TaskToRun.VALIDATE_PACKAGE_SPARQL.value in tasks_to_run: mwb_logger.log_all_info("Validating Package State ... SPARQL") - validate_mapping_package_state_with_sparql(mapping_package_state) + #validate_mapping_package_state_with_sparql(mapping_package_state) mwb_logger.log_all_info("Validating Package State ... SPARQL DONE") diff --git a/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py b/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py index 9f88cc014..d93185ea4 100644 --- a/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py +++ b/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py @@ -1,5 +1,6 @@ from typing import List +from mapping_workbench.backend.logger.services import mwb_logger from mapping_workbench.backend.mapping_package.models.entity import MappingPackageState from mapping_workbench.backend.package_validator.adapters.xpath_validator import XPATHValidator from mapping_workbench.backend.package_validator.models.xpath_validation import XPathAssertion, \ @@ -16,7 +17,9 @@ def update_xpath_assertion( test_data_suite: TestDataSuiteState, test_data_state: TestDataState, xpaths: List[XPathAssertionEntry], - validation_message=None + validation_message=None, + xpath_condition=None, + meets_xpath_condition=True ): if not state.validation.xpath: state.validation.xpath = XPATHTestDataValidationResult() @@ -36,8 +39,10 @@ def update_xpath_assertion( sdk_element_xpath=xpath, sdk_element_title=element_title, is_covered=False, + xpath_condition=xpath_condition, + meets_xpath_condition=meets_xpath_condition, test_data_xpaths=[], - message=validation_message + message=validation_message, ) ) idx = len(state.validation.xpath.results) - 1 @@ -46,7 +51,8 @@ def update_xpath_assertion( state.validation.xpath.results[idx], test_data_suite, test_data_state, - xpaths + xpaths, + meets_xpath_condition ) @@ -54,7 +60,8 @@ def update_xpath_assertion_test_data_entry( test_data_xpath_assertion: XPathAssertion, test_data_suite: TestDataSuiteState, test_data_state: TestDataState, - xpaths: List[XPathAssertionEntry] + xpaths: List[XPathAssertionEntry], + meets_xpath_condition=True ): if not test_data_xpath_assertion.test_data_xpaths: test_data_xpath_assertion.test_data_xpaths = [] @@ -81,6 +88,7 @@ def update_xpath_assertion_test_data_entry( update_xpath_assertion_test_data_entry_xpaths(test_data_xpath_assertion.test_data_xpaths[idx], xpaths) test_data_xpath_assertion.is_covered = (len(test_data_xpath_assertion.test_data_xpaths) > 0) + test_data_xpath_assertion.meets_xpath_condition &= meets_xpath_condition def update_xpath_assertion_test_data_entry_xpaths( @@ -106,46 +114,57 @@ def compute_xpath_assertions_for_mapping_package(mapping_package_state: MappingP for test_data_state in test_data_states: xml_content = test_data_state.xml_manifestation.content xpath_validator: XPATHValidator = XPATHValidator(xml_content) - + mwb_logger.log_all_info(f"Test Data '{test_data_state.title}'") for conceptual_mapping_rule_state in conceptual_mapping_rule_states: structural_element = conceptual_mapping_rule_state.source_structural_element - if structural_element: - cm_xpath = structural_element.absolute_xpath - cm_sdk_id = structural_element.sdk_element_id - cm_sdk_title = structural_element.name - - validation_message = None - xpaths: List[XPathAssertionEntry] = [] - try: - xpaths = xpath_validator.validate(cm_xpath) - except Exception as e: - validation_message = str(e) - - update_xpath_assertion( - state=mapping_package_state, - element_id=cm_sdk_id, - xpath=cm_xpath, - element_title=cm_sdk_title, - test_data_suite=test_data_suite, - test_data_state=test_data_state, - xpaths=xpaths - ) - update_xpath_assertion( - state=test_data_suite, - element_id=cm_sdk_id, - xpath=cm_xpath, - element_title=cm_sdk_title, - test_data_suite=test_data_suite, - test_data_state=test_data_state, - xpaths=xpaths - ) - update_xpath_assertion( - state=test_data_state, - element_id=cm_sdk_id, - xpath=cm_xpath, - element_title=cm_sdk_title, - test_data_suite=test_data_suite, - test_data_state=test_data_state, - xpaths=xpaths, - validation_message=validation_message - ) + if not structural_element: + continue + + cm_xpath = structural_element.absolute_xpath + cm_sdk_id = structural_element.sdk_element_id + cm_sdk_title = structural_element.name + + validation_message = None + xpaths: List[XPathAssertionEntry] = [] + try: + xpaths = xpath_validator.validate(cm_xpath) + except Exception as e: + validation_message = str(e) + + meets_xpath_condition: bool = True + cm_xpath_condition = conceptual_mapping_rule_state.xpath_condition + if cm_xpath_condition: + mwb_logger.log_all_info(cm_xpath_condition) + meets_xpath_condition = xpath_validator.check_xpath_condition(cm_xpath_condition) + mwb_logger.log_all_info(str(meets_xpath_condition)) + + update_xpath_assertion( + state=mapping_package_state, + element_id=cm_sdk_id, + xpath=cm_xpath, + element_title=cm_sdk_title, + test_data_suite=test_data_suite, + test_data_state=test_data_state, + xpaths=xpaths + ) + update_xpath_assertion( + state=test_data_suite, + element_id=cm_sdk_id, + xpath=cm_xpath, + element_title=cm_sdk_title, + test_data_suite=test_data_suite, + test_data_state=test_data_state, + xpaths=xpaths + ) + update_xpath_assertion( + state=test_data_state, + element_id=cm_sdk_id, + xpath=cm_xpath, + element_title=cm_sdk_title, + test_data_suite=test_data_suite, + test_data_state=test_data_state, + xpaths=xpaths, + xpath_condition=cm_xpath_condition, + meets_xpath_condition=meets_xpath_condition, + validation_message=validation_message + ) diff --git a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js index fd96afd44..9c18a5344 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js +++ b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js @@ -19,11 +19,12 @@ import CloseIcon from '@mui/icons-material/Close'; import {Scrollbar} from 'src/components/scrollbar'; import PropTypes from 'prop-types'; -import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; +import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; import TablePagination from "../../components/table-pagination"; +import Stack from "@mui/material/Stack"; export const ListTable = (props) => { - const [descriptionDialog, setDescriptionDialog] = useState({open:false, title:"", text:""}) + const [descriptionDialog, setDescriptionDialog] = useState({open: false, title: "", text: ""}) const { count = 0, @@ -38,21 +39,21 @@ export const ListTable = (props) => { } = props; const handleClose = () => { - setDescriptionDialog(e=>({...e, open: false})); + setDescriptionDialog(e => ({...e, open: false})); }; const SorterHeader = ({fieldName, title}) => { - return - onSort(fieldName)}> - {title ?? fieldName} - - + return + onSort(fieldName)}> + {title ?? fieldName} + + } return ( @@ -80,15 +81,19 @@ export const ListTable = (props) => { - + + + + + title="Found"/> {items?.map((item, key) => { - const notices = item.test_data_xpaths.map(e=> `"${e.test_data_id}":${e.xpaths.length}`) + const notices = item.test_data_xpaths.map(e => `"${e.test_data_id}":${e.xpaths.length}`) return ( @@ -101,13 +106,43 @@ export const ListTable = (props) => { + lineProps={{ + style: { + wordBreak: 'break-all', + whiteSpace: 'pre-wrap' + } + }}> {item.sdk_element_xpath} } - - {item.is_covered ? : } + + { + item.xpath_condition && + + {item.xpath_condition} + + {item.meets_xpath_condition ? : + } + + } + + + {item.is_covered ? : + } @@ -124,15 +159,15 @@ export const ListTable = (props) => { aria-describedby="alert-dialog-description" > - {descriptionDialog.title} + {descriptionDialog.title} - - {descriptionDialog.description} - + + {descriptionDialog.description} + - + From 083458ac77bf964e4927be1a2731466eb13c432a Mon Sep 17 00:00:00 2001 From: Kolea PLESCO Date: Sat, 28 Sep 2024 01:15:13 +0300 Subject: [PATCH 28/35] xpath condition validation --- .../adapters/sparql_validator.py | 13 ++++- .../models/xpath_validation.py | 7 ++- .../services/mapping_package_validator.py | 2 +- .../services/sparql_cm_assertions.py | 12 +++-- .../services/xpath_coverage_validator.py | 42 ++++++++++----- .../sparql_test_suite/models/entity.py | 8 ++- .../list-table-file.js | 40 +++++++++++++- .../sparql_validation_report_file.js | 1 + .../list-table-file.js | 54 +++++++++++-------- .../app/xpath-validation-report/list-table.js | 43 ++++++++++++++- 10 files changed, 172 insertions(+), 50 deletions(-) diff --git a/mapping_workbench/backend/package_validator/adapters/sparql_validator.py b/mapping_workbench/backend/package_validator/adapters/sparql_validator.py index 3fa5445e9..546c15ae2 100644 --- a/mapping_workbench/backend/package_validator/adapters/sparql_validator.py +++ b/mapping_workbench/backend/package_validator/adapters/sparql_validator.py @@ -75,14 +75,25 @@ def process_sparql_result(self, sparql_query_result: SPARQLQueryResult): xpath_validation_results = xpath_validation.results sparql_query_xpath = sparql_query_result.query.cm_rule.sdk_element_xpath.strip() \ if sparql_query_result.query.cm_rule else None + sparql_xpath_condition = sparql_query_result.query.cm_rule.xpath_condition.xpath_condition.strip() \ + if sparql_query_result.query.cm_rule else None validation_xpaths = set() + validation_xpath_conditions = set() for xpath_assertion in xpath_validation_results: if xpath_assertion.is_covered: validation_xpaths.add(xpath_assertion.sdk_element_xpath.strip()) - sparql_query_result.meets_xpath_condition = xpath_assertion.meets_xpath_condition + if xpath_assertion.xpath_conditions: + validation_xpath_conditions |= set([ + (xpath_condition.xpath_condition or '').strip() + for xpath_condition in xpath_assertion.xpath_conditions + if xpath_condition.meets_xpath_condition + ]) sparql_query_result.fields_covered = (not sparql_query_xpath or ( sparql_query_xpath in validation_xpaths )) + sparql_query_result.meets_xpath_condition = (not sparql_xpath_condition or ( + sparql_xpath_condition in validation_xpath_conditions + )) # Refined result result = self.refined_result(ask_answer, sparql_query_result) diff --git a/mapping_workbench/backend/package_validator/models/xpath_validation.py b/mapping_workbench/backend/package_validator/models/xpath_validation.py index 008031fc4..48f1db6e7 100644 --- a/mapping_workbench/backend/package_validator/models/xpath_validation.py +++ b/mapping_workbench/backend/package_validator/models/xpath_validation.py @@ -15,11 +15,14 @@ class XPathAssertionTestDataEntry(ValidationTestDataEntry): xpaths: Optional[List[XPathAssertionEntry]] = None +class XPathAssertionCondition(BaseModel): + xpath_condition: Optional[str] = None + meets_xpath_condition: Optional[bool] = True + class XPathAssertion(CMRuleSDKElement): test_data_xpaths: Optional[List[XPathAssertionTestDataEntry]] = None is_covered: Optional[bool] = False - xpath_condition: Optional[str] = None - meets_xpath_condition: Optional[bool] = True + xpath_conditions: Optional[List[XPathAssertionCondition]] = None message: Optional[str] = None class Settings: diff --git a/mapping_workbench/backend/package_validator/services/mapping_package_validator.py b/mapping_workbench/backend/package_validator/services/mapping_package_validator.py index e160df061..708750efd 100644 --- a/mapping_workbench/backend/package_validator/services/mapping_package_validator.py +++ b/mapping_workbench/backend/package_validator/services/mapping_package_validator.py @@ -43,7 +43,7 @@ async def validate_mapping_package(mapping_package_state: MappingPackageState, t if tasks_to_run is None or TaskToRun.VALIDATE_PACKAGE_SPARQL.value in tasks_to_run: mwb_logger.log_all_info("Validating Package State ... SPARQL") - #validate_mapping_package_state_with_sparql(mapping_package_state) + validate_mapping_package_state_with_sparql(mapping_package_state) mwb_logger.log_all_info("Validating Package State ... SPARQL DONE") diff --git a/mapping_workbench/backend/package_validator/services/sparql_cm_assertions.py b/mapping_workbench/backend/package_validator/services/sparql_cm_assertions.py index 6b9e2c195..f3300b248 100644 --- a/mapping_workbench/backend/package_validator/services/sparql_cm_assertions.py +++ b/mapping_workbench/backend/package_validator/services/sparql_cm_assertions.py @@ -8,10 +8,10 @@ from mapping_workbench.backend.fields_registry.models.field_registry import StructuralElement from mapping_workbench.backend.file_resource.models.file_resource import FileResourceFormat from mapping_workbench.backend.ontology.services.namespaces import get_prefixes_definitions -from mapping_workbench.backend.package_validator.models.test_data_validation import CMRuleSDKElement +from mapping_workbench.backend.package_validator.models.xpath_validation import XPathAssertionCondition from mapping_workbench.backend.project.models.entity import Project from mapping_workbench.backend.sparql_test_suite.models.entity import SPARQLTestFileResource, SPARQLTestSuite, \ - SPARQLQueryValidationType + SPARQLQueryValidationType, SPARQLCMRule from mapping_workbench.backend.sparql_test_suite.services.api import get_sparql_test_suite_by_project_and_title from mapping_workbench.backend.sparql_test_suite.services.data import SPARQL_CM_ASSERTIONS_SUITE_TITLE from mapping_workbench.backend.user.models.user import User @@ -139,10 +139,14 @@ async def generate_and_save_cm_assertions_queries( SPARQLTestFileResource.identifier == sparql_identifier ) - cm_rule_sdk_element = CMRuleSDKElement( + cm_rule_sdk_element = SPARQLCMRule( sdk_element_id=structural_element.sdk_element_id, sdk_element_title=structural_element.name, - sdk_element_xpath=structural_element.absolute_xpath + sdk_element_xpath=structural_element.absolute_xpath, + xpath_condition=XPathAssertionCondition( + xpath_condition=(cm_rule.xpath_condition or ''), + meets_xpath_condition=None + ) ) if not sparql_test_file_resource: diff --git a/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py b/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py index d93185ea4..db33dd7ea 100644 --- a/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py +++ b/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py @@ -4,7 +4,7 @@ from mapping_workbench.backend.mapping_package.models.entity import MappingPackageState from mapping_workbench.backend.package_validator.adapters.xpath_validator import XPATHValidator from mapping_workbench.backend.package_validator.models.xpath_validation import XPathAssertion, \ - XPATHTestDataValidationResult, XPathAssertionTestDataEntry, XPathAssertionEntry + XPATHTestDataValidationResult, XPathAssertionTestDataEntry, XPathAssertionEntry, XPathAssertionCondition from mapping_workbench.backend.test_data_suite.models.entity import TestDataSuiteState, TestDataValidation, \ TestDataState @@ -18,8 +18,7 @@ def update_xpath_assertion( test_data_state: TestDataState, xpaths: List[XPathAssertionEntry], validation_message=None, - xpath_condition=None, - meets_xpath_condition=True + xpath_condition: XPathAssertionCondition = None ): if not state.validation.xpath: state.validation.xpath = XPATHTestDataValidationResult() @@ -39,8 +38,7 @@ def update_xpath_assertion( sdk_element_xpath=xpath, sdk_element_title=element_title, is_covered=False, - xpath_condition=xpath_condition, - meets_xpath_condition=meets_xpath_condition, + xpath_conditions=[], test_data_xpaths=[], message=validation_message, ) @@ -52,7 +50,7 @@ def update_xpath_assertion( test_data_suite, test_data_state, xpaths, - meets_xpath_condition + xpath_condition ) @@ -61,7 +59,7 @@ def update_xpath_assertion_test_data_entry( test_data_suite: TestDataSuiteState, test_data_state: TestDataState, xpaths: List[XPathAssertionEntry], - meets_xpath_condition=True + xpath_condition: XPathAssertionCondition = None, ): if not test_data_xpath_assertion.test_data_xpaths: test_data_xpath_assertion.test_data_xpaths = [] @@ -87,8 +85,20 @@ def update_xpath_assertion_test_data_entry( update_xpath_assertion_test_data_entry_xpaths(test_data_xpath_assertion.test_data_xpaths[idx], xpaths) + if xpath_condition: + idx = next( + ( + idx for idx, entry in enumerate(test_data_xpath_assertion.xpath_conditions) + if entry.xpath_condition == xpath_condition.xpath_condition + ), -1 + ) + if idx < 0: + test_data_xpath_assertion.xpath_conditions.append(xpath_condition) + else: + test_data_xpath_assertion.xpath_conditions[idx].meets_xpath_condition &= xpath_condition.meets_xpath_condition + test_data_xpath_assertion.is_covered = (len(test_data_xpath_assertion.test_data_xpaths) > 0) - test_data_xpath_assertion.meets_xpath_condition &= meets_xpath_condition + def update_xpath_assertion_test_data_entry_xpaths( @@ -134,9 +144,12 @@ def compute_xpath_assertions_for_mapping_package(mapping_package_state: MappingP meets_xpath_condition: bool = True cm_xpath_condition = conceptual_mapping_rule_state.xpath_condition if cm_xpath_condition: - mwb_logger.log_all_info(cm_xpath_condition) meets_xpath_condition = xpath_validator.check_xpath_condition(cm_xpath_condition) - mwb_logger.log_all_info(str(meets_xpath_condition)) + + xpath_condition = XPathAssertionCondition( + xpath_condition=cm_xpath_condition or '', + meets_xpath_condition=meets_xpath_condition + ) update_xpath_assertion( state=mapping_package_state, @@ -145,7 +158,8 @@ def compute_xpath_assertions_for_mapping_package(mapping_package_state: MappingP element_title=cm_sdk_title, test_data_suite=test_data_suite, test_data_state=test_data_state, - xpaths=xpaths + xpaths=xpaths, + xpath_condition=xpath_condition ) update_xpath_assertion( state=test_data_suite, @@ -154,7 +168,8 @@ def compute_xpath_assertions_for_mapping_package(mapping_package_state: MappingP element_title=cm_sdk_title, test_data_suite=test_data_suite, test_data_state=test_data_state, - xpaths=xpaths + xpaths=xpaths, + xpath_condition=xpath_condition ) update_xpath_assertion( state=test_data_state, @@ -164,7 +179,6 @@ def compute_xpath_assertions_for_mapping_package(mapping_package_state: MappingP test_data_suite=test_data_suite, test_data_state=test_data_state, xpaths=xpaths, - xpath_condition=cm_xpath_condition, - meets_xpath_condition=meets_xpath_condition, + xpath_condition=xpath_condition, validation_message=validation_message ) diff --git a/mapping_workbench/backend/sparql_test_suite/models/entity.py b/mapping_workbench/backend/sparql_test_suite/models/entity.py index 2448953d5..ba291e80d 100644 --- a/mapping_workbench/backend/sparql_test_suite/models/entity.py +++ b/mapping_workbench/backend/sparql_test_suite/models/entity.py @@ -12,6 +12,7 @@ from mapping_workbench.backend.file_resource.models.file_resource import FileResource, FileResourceCollection, \ FileResourceIn from mapping_workbench.backend.package_validator.models.test_data_validation import CMRuleSDKElement +from mapping_workbench.backend.package_validator.models.xpath_validation import XPathAssertionCondition from mapping_workbench.backend.state_manager.models.state_object import ObjectState, StatefulObjectABC @@ -35,6 +36,9 @@ def __str__(self): return str(self.value) +class SPARQLCMRule(CMRuleSDKElement): + xpath_condition: Optional[XPathAssertionCondition] = None + class SPARQLTestState(ObjectState): oid: Optional[PydanticObjectId] = None format: Optional[SPARQLTestFileResourceFormat] = None @@ -42,7 +46,7 @@ class SPARQLTestState(ObjectState): title: Optional[str] = None filename: Optional[str] = None content: Optional[str] = None - cm_rule: Optional[CMRuleSDKElement] = None + cm_rule: Optional[SPARQLCMRule] = None model_config = ConfigDict(use_enum_values=True) @@ -112,7 +116,7 @@ class SPARQLTestFileResource(FileResource, StatefulObjectABC): format: Optional[SPARQLTestFileResourceFormat] = None type: Optional[SPARQLQueryValidationType] = None sparql_test_suite: Optional[Link[SPARQLTestSuite]] = None - cm_rule: Optional[CMRuleSDKElement] = None + cm_rule: Optional[SPARQLCMRule] = None async def get_state(self) -> SPARQLTestState: return SPARQLTestState( diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js index f2e46e779..da9ddc3b0 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js @@ -14,6 +14,9 @@ import {resultColor} from "./utils"; import {Scrollbar} from 'src/components/scrollbar'; import TablePagination from "src/sections/components/table-pagination"; import TableSorterHeader from "src/sections/components/table-sorter-header"; +import Stack from "@mui/material/Stack"; +import CheckIcon from "@mui/icons-material/Check"; +import CloseIcon from "@mui/icons-material/Close"; export const ListTableFile = (props) => { @@ -38,6 +41,7 @@ export const ListTableFile = (props) => { /> ) } + console.log(items); return ( <> @@ -56,10 +60,14 @@ export const ListTableFile = (props) => { - + + + + @@ -81,11 +89,39 @@ export const ListTableFile = (props) => { {items?.map((item, key) => { return ( - + {item.title} + + + + + {item?.xpath_condition?.xpath_condition || '-'} + + {item?.xpath_condition?.meets_xpath_condition ? + : + } + + + diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_file.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_file.js index db0b600fc..f2baee1cd 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_file.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_file.js @@ -149,6 +149,7 @@ const SparqlFileReport = ({sid, suiteId, testId, files, mappingSuiteIdentifier}) resultArray["query_result"] = e.query_result resultArray["fields_covered"] = e.fields_covered resultArray["result"] = e.result + resultArray["xpath_condition"] = e.query?.cm_rule?.xpath_condition return resultArray; }) diff --git a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js index 9c18a5344..c79af1a1d 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js +++ b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js @@ -81,7 +81,7 @@ export const ListTable = (props) => { - + @@ -116,28 +116,38 @@ export const ListTable = (props) => { } - + { - item.xpath_condition && - - {item.xpath_condition} - - {item.meets_xpath_condition ? : - } - + item.xpath_conditions?.map((xpath_condition, key) => { + return ( + + + + {xpath_condition.xpath_condition || '-'} + + {xpath_condition.meets_xpath_condition ? + : + } + + + ); + }) } diff --git a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js index cdeb32344..2d351c2eb 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js @@ -21,6 +21,7 @@ import DialogActions from "@mui/material/DialogActions"; import {Scrollbar} from 'src/components/scrollbar'; import TablePagination from "src/sections/components/table-pagination"; import TableSorterHeader from "src/sections/components/table-sorter-header"; +import Stack from "@mui/material/Stack"; export const ListTable = (props) => { @@ -95,11 +96,15 @@ export const ListTable = (props) => { + + + - + @@ -129,6 +134,40 @@ export const ListTable = (props) => { } + + { + item.xpath_conditions?.map((xpath_condition, key) => { + return ( + + + + {xpath_condition.xpath_condition || '-'} + + {xpath_condition.meets_xpath_condition ? + : + } + + + ); + }) + } + - + {item.is_covered ? : } From bb552b2b0cbf972c4ced77f4319aaf93fdc06e91 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Mon, 30 Sep 2024 10:27:32 +0300 Subject: [PATCH 29/35] MWB-797: some code arrangement and remove console warnings --- .../app/vertical-layout/side-nav-item.js | 1 - .../list-table-file.js | 7 +- .../app/shacl-validation-report/list-table.js | 24 ++-- .../list-table-file.js | 13 ++- .../sparql-validation-report/list-table.js | 30 ++--- .../query-result-table.js | 4 +- .../list-table-file.js | 105 ++++++++---------- 7 files changed, 86 insertions(+), 98 deletions(-) diff --git a/mapping_workbench/frontend/src/layouts/app/vertical-layout/side-nav-item.js b/mapping_workbench/frontend/src/layouts/app/vertical-layout/side-nav-item.js index 0beeba88e..de906b56a 100644 --- a/mapping_workbench/frontend/src/layouts/app/vertical-layout/side-nav-item.js +++ b/mapping_workbench/frontend/src/layouts/app/vertical-layout/side-nav-item.js @@ -81,7 +81,6 @@ export const SideNavItem = (props) => { id={['nav', ...title.toLowerCase().split(' ')].join('_')} disabled={disabled} onClick={handleToggle} - someProp={'prop'} sx={{ alignItems: 'center', borderRadius: 1, diff --git a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table-file.js index 9469a92af..4e4e97200 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table-file.js +++ b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table-file.js @@ -1,4 +1,3 @@ - import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import PropTypes from 'prop-types'; @@ -8,9 +7,9 @@ import TableCell from '@mui/material/TableCell'; import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; -import {SorterHeader as UtilsSorterHeader} from "./utils"; import {Scrollbar} from 'src/components/scrollbar'; -import TablePagination from '../../components/table-pagination'; +import TablePagination from 'src/sections/components/table-pagination'; +import TableSorterHeader from "src/sections/components/table-sorter-header"; export const ListTableFile = (props) => { @@ -26,7 +25,7 @@ export const ListTableFile = (props) => { sectionApi } = props; - const SorterHeader = (props) => diff --git a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js index 963732e96..3aac753b1 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js @@ -63,17 +63,19 @@ export const ListTable = (props) => { /> const ResultCell = ({title, result, onClick}) => { - return - {result.count - ? - : {result.count}} - + return ( + + {result.count + ? + : {result.count}} + + ) } return ( diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js index da9ddc3b0..83b704822 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js @@ -4,19 +4,20 @@ import PropTypes from 'prop-types'; import {Box} from "@mui/system"; import Chip from "@mui/material/Chip"; import Table from '@mui/material/Table'; +import Stack from "@mui/material/Stack"; import TableRow from '@mui/material/TableRow'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableHead from '@mui/material/TableHead'; +import CheckIcon from "@mui/icons-material/Check"; +import CloseIcon from "@mui/icons-material/Close"; import Typography from '@mui/material/Typography'; import {resultColor} from "./utils"; import {Scrollbar} from 'src/components/scrollbar'; import TablePagination from "src/sections/components/table-pagination"; import TableSorterHeader from "src/sections/components/table-sorter-header"; -import Stack from "@mui/material/Stack"; -import CheckIcon from "@mui/icons-material/Check"; -import CloseIcon from "@mui/icons-material/Close"; + export const ListTableFile = (props) => { @@ -41,7 +42,6 @@ export const ListTableFile = (props) => { /> ) } - console.log(items); return ( <> @@ -64,7 +64,8 @@ export const ListTableFile = (props) => { - + @@ -107,7 +108,7 @@ export const ListTableFile = (props) => { > { } = props; const handleOpenDetails = ({title, notices}) => { - const description = notices.map((notice, i) => - - - {' / '} - - ) + const description = notices.map((notice, i) => + + + {' / '} + + ) setDescriptionDialog({open: true, title, description}); } @@ -79,7 +79,7 @@ export const ListTable = (props) => { onClick={() => onClick({title, notices: result.test_datas})}> {result.count} - : {result.count}} + : {result.count}} } diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/query-result-table.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/query-result-table.js index 41b11444a..1de8e6021 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/query-result-table.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/query-result-table.js @@ -1,11 +1,11 @@ import {useState} from "react"; +import Chip from "@mui/material/Chip"; import Table from '@mui/material/Table'; +import TableRow from '@mui/material/TableRow'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableHead from '@mui/material/TableHead'; -import TableRow from '@mui/material/TableRow'; -import Chip from "@mui/material/Chip"; import {Scrollbar} from 'src/components/scrollbar'; import {resultColor, SorterHeader, sortItems} from "./utils"; diff --git a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js index c79af1a1d..b1ff7aed7 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js +++ b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js @@ -1,27 +1,26 @@ import {useState} from "react"; +import PropTypes from 'prop-types'; +import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; +import Stack from "@mui/material/Stack"; import Table from '@mui/material/Table'; +import Button from "@mui/material/Button"; +import Dialog from '@mui/material/Dialog'; +import TableRow from '@mui/material/TableRow'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; -import TableSortLabel from '@mui/material/TableSortLabel'; import TableHead from '@mui/material/TableHead'; -import TableRow from '@mui/material/TableRow'; +import CloseIcon from '@mui/icons-material/Close'; +import CheckIcon from '@mui/icons-material/Check'; import Typography from '@mui/material/Typography'; -import Tooltip from "@mui/material/Tooltip"; -import Button from "@mui/material/Button"; -import Dialog from '@mui/material/Dialog'; import DialogTitle from "@mui/material/DialogTitle"; import DialogContent from "@mui/material/DialogContent"; import DialogActions from "@mui/material/DialogActions"; import DialogContentText from "@mui/material/DialogContentText"; -import CheckIcon from '@mui/icons-material/Check'; -import CloseIcon from '@mui/icons-material/Close'; import {Scrollbar} from 'src/components/scrollbar'; -import PropTypes from 'prop-types'; -import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; -import TablePagination from "../../components/table-pagination"; -import Stack from "@mui/material/Stack"; +import TablePagination from "src/sections/components/table-pagination"; +import TableSorterHeader from "src/sections/components/table-sorter-header"; export const ListTable = (props) => { const [descriptionDialog, setDescriptionDialog] = useState({open: false, title: "", text: ""}) @@ -38,23 +37,12 @@ export const ListTable = (props) => { sort } = props; - const handleClose = () => { - setDescriptionDialog(e => ({...e, open: false})); - }; - + const handleClose = () => setDescriptionDialog(e => ({...e, open: false})); - const SorterHeader = ({fieldName, title}) => { - return - onSort(fieldName)}> - {title ?? fieldName} - - - } + const SorterHeader = (props) => return ( <> @@ -93,7 +81,6 @@ export const ListTable = (props) => { {items?.map((item, key) => { - const notices = item.test_data_xpaths.map(e => `"${e.test_data_id}":${e.xpaths.length}`) return ( @@ -117,42 +104,42 @@ export const ListTable = (props) => { } - { - item.xpath_conditions?.map((xpath_condition, key) => { - return ( + {item.xpath_conditions?.map((xpath_condition, key) => { + return ( + - - - {xpath_condition.xpath_condition || '-'} - - {xpath_condition.meets_xpath_condition ? - : - } - + + {xpath_condition.xpath_condition || '-'} + + {xpath_condition.meets_xpath_condition ? + : + } - ); - }) - } + + ); + })} - {item.is_covered ? : - } + {item.is_covered + ? + : } From 0488061ca98a98ea25d9022a58a9afb729b54414 Mon Sep 17 00:00:00 2001 From: Kolea PLESCO Date: Mon, 30 Sep 2024 15:13:04 +0300 Subject: [PATCH 30/35] xpath condition validation --- .../services/sparql_validator.py | 16 ++- .../services/xpath_coverage_validator.py | 2 +- .../list-table-file.js | 126 +++++++++--------- .../sparql-validation-report/list-table.js | 29 +++- .../sparql_validation_report_file.js | 1 + .../sparql_validation_report_test_dataset.js | 2 + 6 files changed, 104 insertions(+), 72 deletions(-) diff --git a/mapping_workbench/backend/package_validator/services/sparql_validator.py b/mapping_workbench/backend/package_validator/services/sparql_validator.py index c96f0595c..c97178aac 100644 --- a/mapping_workbench/backend/package_validator/services/sparql_validator.py +++ b/mapping_workbench/backend/package_validator/services/sparql_validator.py @@ -26,11 +26,12 @@ def validate_tests_data_with_sparql_tests( sparql_runner = SPARQLValidator(test_data=test_data, test_data_suite=test_data_suite) tests_data[idx].validation.sparql = sparql_runner.validate(sparql_queries=sparql_tests) - tests_data[idx].validation.sparql.summary = aggregate_sparql_tests_summary( - tests_data[idx].validation.sparql.results, - [SPARQLTestState(oid=None)], - False - ) + if tests_data[idx].validation.sparql and tests_data[idx].validation.sparql.results: + tests_data[idx].validation.sparql.summary = aggregate_sparql_tests_summary( + tests_data[idx].validation.sparql.results, + [SPARQLTestState(oid=None)], + False + ) except Exception as e: mwb_logger.log_all_error(message="ERROR :: SPARQL Validation :: Stack trace: ", stack_trace=str(e)) pass @@ -53,9 +54,11 @@ def aggregate_sparql_tests_summary( ) ) idx = len(summary) - 1 + for result in results: if result.query.oid != summary[idx].query.oid: continue + if result.result == SPARQLQueryRefinedResultType.VALID.value: if add_summary_result_test_data(summary[idx].result.valid.test_datas, result.test_data) or not use_grouping: @@ -81,6 +84,7 @@ def aggregate_sparql_tests_summary( result.test_data) or not use_grouping: summary[idx].result.unknown.count += 1 + summary[idx].query.cm_rule.xpath_condition.meets_xpath_condition |= result.meets_xpath_condition return summary @@ -105,7 +109,7 @@ def validate_mapping_package_state_with_sparql(mapping_package_state: MappingPac test_data_suite_results = [] for test_data_state in mapping_package_state.test_data_suites[idx].test_data_states: - test_data_state_results = test_data_state.validation.sparql.results or [] + test_data_state_results = (test_data_state.validation.sparql and test_data_state.validation.sparql.results) or [] test_data_suite_results.extend(test_data_state_results) state_results.extend(test_data_state_results) diff --git a/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py b/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py index db33dd7ea..9a5b277c9 100644 --- a/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py +++ b/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py @@ -95,7 +95,7 @@ def update_xpath_assertion_test_data_entry( if idx < 0: test_data_xpath_assertion.xpath_conditions.append(xpath_condition) else: - test_data_xpath_assertion.xpath_conditions[idx].meets_xpath_condition &= xpath_condition.meets_xpath_condition + test_data_xpath_assertion.xpath_conditions[idx].meets_xpath_condition |= xpath_condition.meets_xpath_condition test_data_xpath_assertion.is_covered = (len(test_data_xpath_assertion.test_data_xpaths) > 0) diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js index da9ddc3b0..928e9c818 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js @@ -17,6 +17,7 @@ import TableSorterHeader from "src/sections/components/table-sorter-header"; import Stack from "@mui/material/Stack"; import CheckIcon from "@mui/icons-material/Check"; import CloseIcon from "@mui/icons-material/Close"; +import Divider from "@mui/material/Divider"; export const ListTableFile = (props) => { @@ -64,13 +65,9 @@ export const ListTableFile = (props) => { - - - - + + title=""/> { - - - - {item?.xpath_condition?.xpath_condition || '-'} - - {item?.xpath_condition?.meets_xpath_condition ? - : - } + + + {item?.xpath_condition?.xpath_condition} + + {item?.meets_xpath_condition ? + : + } + - - - - - - - {item.description} - - - - - - {item.query} - - - - - - - - {`Query result: ${item.query_result}`} - {`Fields covered: ${item.fields_covered}`} - - - + + } + + + {item.description} + + + + + + {item.query} + + + + + + + + {`Query result: ${item.query_result}`} + {`Fields covered: ${item.fields_covered}`} + + + - ); + ) + ; })}
    diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js index c2f7c3688..7d79ad290 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js @@ -20,6 +20,8 @@ import {ResultChip} from "./utils"; import {Scrollbar} from 'src/components/scrollbar'; import TablePagination from "src/sections/components/table-pagination"; import TableSorterHeader from "src/sections/components/table-sorter-header"; +import CheckIcon from "@mui/icons-material/Check"; +import CloseIcon from "@mui/icons-material/Close"; export const ListTable = (props) => { const [descriptionDialog, setDescriptionDialog] = useState({open: false, title: "", description: ""}) @@ -160,7 +162,32 @@ export const ListTable = (props) => {
    - {item.xpath_condition} + + + + {item?.xpath_condition?.xpath_condition || '-'} + + {item?.meets_xpath_condition ? + : + } + + { const [key, value] = entrie resultArray[`${key}Count`] = value.count }) + resultArray["meets_xpath_condition"] = e.meets_xpath_condition + resultArray["xpath_condition"] = e.query?.cm_rule?.xpath_condition return resultArray; }) From 63a56b904fd29392e5896cdc747558dc697a69c7 Mon Sep 17 00:00:00 2001 From: Victor Frunze Date: Mon, 30 Sep 2024 15:20:29 +0300 Subject: [PATCH 31/35] MWB-797: update xpath dark theme --- .../list-table-file.js | 36 +++++++----- .../app/shacl-validation-report/list-table.js | 2 + .../list-table-file.js | 2 + .../sparql-validation-report/list-table.js | 2 + .../list-table-file.js | 24 ++++---- .../app/xpath-validation-report/list-table.js | 56 +++++++++---------- 6 files changed, 64 insertions(+), 58 deletions(-) diff --git a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table-file.js index 4e4e97200..8e8e6bb56 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table-file.js +++ b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table-file.js @@ -1,4 +1,4 @@ -import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; +import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; import PropTypes from 'prop-types'; import Table from '@mui/material/Table'; @@ -7,6 +7,7 @@ import TableCell from '@mui/material/TableCell'; import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; +import {codeStyle} from "src/utils/code-style"; import {Scrollbar} from 'src/components/scrollbar'; import TablePagination from 'src/sections/components/table-pagination'; import TableSorterHeader from "src/sections/components/table-sorter-header"; @@ -28,7 +29,7 @@ export const ListTableFile = (props) => { const SorterHeader = (props) => + /> return ( { title="Message"/> - + - + @@ -73,40 +74,45 @@ export const ListTableFile = (props) => { + wrapLines + style={codeStyle} + lineProps={{style: {overflowWrap: 'break-word', whiteSpace: 'pre-wrap'}}}> {item.short_focus_node} + wrapLines + style={codeStyle} + lineProps={{style: {overflowWrap: 'break-word', whiteSpace: 'pre-wrap'}}}> {item.message} + wrapLines + style={codeStyle} + lineProps={{style: {overflowWrap: 'break-word', whiteSpace: 'pre-wrap'}}}> {item.short_result_path} + wrapLines + style={codeStyle} + lineProps={{style: {overflowWrap: 'break-word', whiteSpace: 'pre-wrap'}}}> {item.short_result_severity} + wrapLines + style={codeStyle} + lineProps={{style: {overflowWrap: 'break-word', whiteSpace: 'pre-wrap'}}}> {item.short_source_constraint_component} diff --git a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js index 3aac753b1..bae65f0b8 100644 --- a/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/shacl-validation-report/list-table.js @@ -15,6 +15,7 @@ import DialogContent from "@mui/material/DialogContent"; import DialogActions from "@mui/material/DialogActions"; import {ResultChip} from "./utils"; +import {codeStyle} from "src/utils/code-style"; import {Scrollbar} from 'src/components/scrollbar'; import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'; import TablePagination from "src/sections/components/table-pagination"; @@ -148,6 +149,7 @@ export const ListTable = (props) => { { { { - + @@ -89,19 +91,13 @@ export const ListTable = (props) => { - { - - {item.sdk_element_xpath} - - } + + {item.sdk_element_xpath} + {item.xpath_conditions?.map((xpath_condition, key) => { diff --git a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js index 2d351c2eb..b871f2a4e 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table.js @@ -6,6 +6,7 @@ import CheckIcon from '@mui/icons-material/Check'; import CloseIcon from '@mui/icons-material/Close'; import {Box} from "@mui/system"; +import Stack from "@mui/material/Stack"; import Table from '@mui/material/Table'; import Dialog from "@mui/material/Dialog"; import Button from "@mui/material/Button"; @@ -18,10 +19,10 @@ import DialogTitle from "@mui/material/DialogTitle"; import DialogContent from "@mui/material/DialogContent"; import DialogActions from "@mui/material/DialogActions"; +import {codeStyle} from "src/utils/code-style"; import {Scrollbar} from 'src/components/scrollbar'; import TablePagination from "src/sections/components/table-pagination"; import TableSorterHeader from "src/sections/components/table-sorter-header"; -import Stack from "@mui/material/Stack"; export const ListTable = (props) => { @@ -44,19 +45,19 @@ export const ListTable = (props) => { const handleOpenDetails = (title, notices) => { const description = notices.map((notice, i) => - - - {' / '} - - ) + + + {' / '} + + ) setDescriptionDialog({open: true, title, description}); } @@ -104,7 +105,8 @@ export const ListTable = (props) => { - + @@ -120,25 +122,20 @@ export const ListTable = (props) => { - { - - {item.sdk_element_xpath} - - } + + {item.sdk_element_xpath} + { item.xpath_conditions?.map((xpath_condition, key) => { return ( @@ -150,7 +147,8 @@ export const ListTable = (props) => { > Date: Mon, 30 Sep 2024 17:02:14 +0300 Subject: [PATCH 32/35] xpath condition validation --- .../services/sparql_cm_assertions.py | 5 +- .../services/xpath_coverage_validator.py | 2 +- .../app/conceptual-mapping-rule/cm-card.js | 10 ++- .../develop/list-table.js | 10 ++- .../list-table-file.js | 1 + .../sparql-validation-report/list-table.js | 78 +++++++++++++------ .../sparql_validation_report_package_state.js | 2 + .../list-table-file.js | 1 + 8 files changed, 79 insertions(+), 30 deletions(-) diff --git a/mapping_workbench/backend/package_validator/services/sparql_cm_assertions.py b/mapping_workbench/backend/package_validator/services/sparql_cm_assertions.py index f3300b248..46a023864 100644 --- a/mapping_workbench/backend/package_validator/services/sparql_cm_assertions.py +++ b/mapping_workbench/backend/package_validator/services/sparql_cm_assertions.py @@ -122,7 +122,8 @@ async def generate_and_save_cm_assertions_queries( subject_type_display = ('\n\t' + subject_type) if subject_type else '' file_name = f"{rq_name}{sparql_idx}.rq" file_content = f"#title: {sparql_title}\n" \ - f"#description: “{sparql_description}” " \ + f"#description: " \ + f"{f'“{sparql_description}” ' if sparql_description else ''}" \ f"The corresponding XML element is " \ f"{sparql_xpath}. " \ f"The expected ontology instances are epo: {cm_rule.target_class_path} .\n" \ @@ -145,7 +146,7 @@ async def generate_and_save_cm_assertions_queries( sdk_element_xpath=structural_element.absolute_xpath, xpath_condition=XPathAssertionCondition( xpath_condition=(cm_rule.xpath_condition or ''), - meets_xpath_condition=None + meets_xpath_condition=(False if cm_rule.xpath_condition else True) ) ) diff --git a/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py b/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py index db33dd7ea..66d9126e3 100644 --- a/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py +++ b/mapping_workbench/backend/package_validator/services/xpath_coverage_validator.py @@ -141,8 +141,8 @@ def compute_xpath_assertions_for_mapping_package(mapping_package_state: MappingP except Exception as e: validation_message = str(e) - meets_xpath_condition: bool = True cm_xpath_condition = conceptual_mapping_rule_state.xpath_condition + meets_xpath_condition: bool = True if cm_xpath_condition: meets_xpath_condition = xpath_validator.check_xpath_condition(cm_xpath_condition) diff --git a/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/cm-card.js b/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/cm-card.js index 81fb8688f..fe4163368 100644 --- a/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/cm-card.js +++ b/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/cm-card.js @@ -20,6 +20,7 @@ import CMNotes from "./cm-notes"; import {toastError, toastLoad, toastSuccess} from "../../../components/app-toast"; import Divider from "@mui/material/Divider"; import {Prism as SyntaxHighlighter} from "react-syntax-highlighter"; +import {codeStyle} from "../../../utils/code-style"; const CMCard = (props) => { const {cm_rule, structural_element, cm_statuses, ...other} = props; @@ -149,7 +150,13 @@ const CMCard = (props) => { /> + {structuralElement?.absolute_xpath} + } sx={{ whiteSpace: "pre-wrap", py: 1.5 @@ -160,6 +167,7 @@ const CMCard = (props) => { value={ {cm_rule.xpath_condition} } diff --git a/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/develop/list-table.js b/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/develop/list-table.js index 20381e11e..99ecb0cb4 100644 --- a/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/develop/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/develop/list-table.js @@ -19,6 +19,7 @@ import DialogContent from "@mui/material/DialogContent"; import Dialog from "@mui/material/Dialog"; import {useDialog} from "../../../../hooks/use-dialog"; import {Prism as SyntaxHighlighter} from "react-syntax-highlighter"; +import {codeStyle} from "../../../../utils/code-style"; export const ListTableRow = (props) => { @@ -51,7 +52,13 @@ export const ListTableRow = (props) => { wordBreak: "break-all" }} > - {item.source_structural_element_absolute_xpath} + + {item.source_structural_element_absolute_xpath} + {item.xpath_condition && @@ -114,6 +121,7 @@ export const ListTableRow = (props) => { {item.xpath_condition} diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js index cea6c115d..59a80a5c2 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table-file.js @@ -155,6 +155,7 @@ export const ListTableFile = (props) => { {`Query result: ${item.query_result}`} + {`Fields covered: ${item.fields_covered}`} diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js index 82f79baea..b2ecd07de 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/list-table.js @@ -23,6 +23,9 @@ import TablePagination from "src/sections/components/table-pagination"; import TableSorterHeader from "src/sections/components/table-sorter-header"; import CheckIcon from "@mui/icons-material/Check"; import CloseIcon from "@mui/icons-material/Close"; +import {useDialog} from "../../../hooks/use-dialog"; +import Divider from "@mui/material/Divider"; +import Slack from "next-auth/providers/slack"; export const ListTable = (props) => { const [descriptionDialog, setDescriptionDialog] = useState({open: false, title: "", description: ""}) @@ -86,6 +89,12 @@ export const ListTable = (props) => { } + const xpathConditionDialog = useDialog() + + const openXPathConditionDialog = (data) => { + xpathConditionDialog.handleOpen(data) + } + return ( <> { - + @@ -163,32 +172,25 @@ export const ListTable = (props) => { - + {item?.xpath_condition?.xpath_condition && - - {item?.xpath_condition?.xpath_condition || '-'} - - {item?.meets_xpath_condition ? - : - } - - + + + {item?.xpath_condition?.meets_xpath_condition ? + : + } + + } { + + + XPath Condition for "{xpathConditionDialog.data?.title}" + + + + {xpathConditionDialog.data?.xpath_condition?.xpath_condition} + + + + {xpathConditionDialog.data?.xpath_condition?.meets_xpath_condition ? + <> - At least one Test Data meets this XPath Condition : + <> - No Test Data meets this XPath Condition} + + + + ); }; diff --git a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_package_state.js b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_package_state.js index b280ae2c4..0658af15d 100644 --- a/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_package_state.js +++ b/mapping_workbench/frontend/src/sections/app/sparql-validation-report/sparql_validation_report_package_state.js @@ -161,6 +161,8 @@ const SparqlValidationReport = ({sid, handleSelectFile}) => { const [key, value] = entrie resultArray[`${key}Count`] = value.count }) + resultArray["meets_xpath_condition"] = e.meets_xpath_condition + resultArray["xpath_condition"] = e.query?.cm_rule?.xpath_condition return resultArray; }) diff --git a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js index 3d2e5cac1..3ca135b93 100644 --- a/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js +++ b/mapping_workbench/frontend/src/sections/app/xpath-validation-report/list-table-file.js @@ -116,6 +116,7 @@ export const ListTable = (props) => { Date: Mon, 30 Sep 2024 17:09:54 +0300 Subject: [PATCH 33/35] updated tests for xpath condition validation --- .../backend/package_importer/adapters/importer_abc.py | 5 ++--- tests/unit/backend/package_validator/conftest.py | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/mapping_workbench/backend/package_importer/adapters/importer_abc.py b/mapping_workbench/backend/package_importer/adapters/importer_abc.py index d4a19365a..0ddfd23b4 100644 --- a/mapping_workbench/backend/package_importer/adapters/importer_abc.py +++ b/mapping_workbench/backend/package_importer/adapters/importer_abc.py @@ -6,7 +6,6 @@ from mapping_workbench.backend.mapping_package.models.entity import MappingPackage from mapping_workbench.backend.mapping_rule_registry.models.entity import MappingGroup from mapping_workbench.backend.package_importer.models.imported_mapping_suite import ImportedMappingSuite -from mapping_workbench.backend.package_validator.models.test_data_validation import CMRuleSDKElement from mapping_workbench.backend.project.models.entity import Project from mapping_workbench.backend.resource_collection.models.entity import ResourceFile, ResourceCollection, \ ResourceFileFormat @@ -15,7 +14,7 @@ from mapping_workbench.backend.shacl_test_suite.models.entity import SHACLTestFileResourceFormat, SHACLTestSuite, \ SHACLTestFileResource from mapping_workbench.backend.sparql_test_suite.models.entity import SPARQLTestFileResourceFormat, SPARQLTestSuite, \ - SPARQLTestFileResource, SPARQLQueryValidationType + SPARQLTestFileResource, SPARQLQueryValidationType, SPARQLCMRule from mapping_workbench.backend.sparql_test_suite.services.data import SPARQL_CM_ASSERTIONS_SUITE_TITLE, \ SPARQL_INTEGRATION_TESTS_SUITE_TITLE from mapping_workbench.backend.test_data_suite.models.entity import TestDataSuite, TestDataFileResource, \ @@ -186,7 +185,7 @@ async def add_sparql_test_suites_from_mono(self, mono_package: ImportedMappingSu ) metadata = self.extract_metadata_from_sparql_query(resource_content) - cm_rule_sdk_element = CMRuleSDKElement( + cm_rule_sdk_element = SPARQLCMRule( sdk_element_id=None, sdk_element_title=metadata['title'] if 'title' in metadata else None, sdk_element_xpath=metadata['xpath'] if 'xpath' in metadata else None diff --git a/tests/unit/backend/package_validator/conftest.py b/tests/unit/backend/package_validator/conftest.py index 43e4f3170..486c58f71 100644 --- a/tests/unit/backend/package_validator/conftest.py +++ b/tests/unit/backend/package_validator/conftest.py @@ -6,11 +6,11 @@ from mapping_workbench.backend.fields_registry.models.field_registry import StructuralElement from mapping_workbench.backend.mapping_package.models.entity import MappingPackage, MappingPackageState from mapping_workbench.backend.package_importer.adapters.eforms.importer import PackageImporter -from mapping_workbench.backend.package_validator.models.test_data_validation import CMRuleSDKElement from mapping_workbench.backend.project.models.entity import Project from mapping_workbench.backend.shacl_test_suite.models.entity import SHACLTestFileResourceFormat, SHACLTestSuiteState, \ SHACLTestState -from mapping_workbench.backend.sparql_test_suite.models.entity import SPARQLTestFileResourceFormat, SPARQLTestState +from mapping_workbench.backend.sparql_test_suite.models.entity import SPARQLTestFileResourceFormat, SPARQLTestState, \ + SPARQLCMRule from mapping_workbench.backend.test_data_suite.models.entity import TestDataFileResource, \ TestDataFileResourceFormat from mapping_workbench.backend.user.models.user import User @@ -67,7 +67,7 @@ def dummy_sparql_test_suite(sparql_test_resources_file_path: pathlib.Path, metadata = dummy_package_importer.extract_metadata_from_sparql_query( sparql_test_resources_file_path.read_text(encoding="utf-8") ) - cm_rule_sdk_element = CMRuleSDKElement( + cm_rule_sdk_element = SPARQLCMRule( eforms_sdk_element_id=None, eforms_sdk_element_title=metadata['title'] ) From aa21241afdc29ae85ffae5597f73f8c0526d6354 Mon Sep 17 00:00:00 2001 From: Kolea PLESCO Date: Mon, 30 Sep 2024 20:39:16 +0300 Subject: [PATCH 34/35] updated importer to display warnings + fix cm rules import algo --- .../backend/fields_registry/services/data.py | 4 +- .../backend/logger/adapters/console_logger.py | 2 + .../backend/logger/adapters/sys_logger.py | 2 + .../backend/logger/models/logger_record.py | 1 + .../backend/logger/services/logger_factory.py | 8 + .../adapters/eforms/importer.py | 9 +- .../package_importer/adapters/importer_abc.py | 4 +- .../adapters/standard/importer.py | 5 +- .../entrypoints/api/routes.py | 9 +- .../models/imported_mapping_suite.py | 6 + .../services/import_mapping_suite.py | 20 +- .../package_importer/services/tasks.py | 10 +- .../backend/task_manager/adapters/task.py | 13 +- .../task_manager/adapters/task_manager.py | 1 + .../backend/tasks/models/task_response.py | 5 + .../develop/list-search.js | 2 +- .../conceptual-mapping-rule/list-search.js | 184 ++++++------------ .../src/sections/app/tasks/list-table.js | 41 ++-- .../backend/first_scenario/_test_scenario.py | 3 +- .../package_exporter/test_package_exporter.py | 4 +- .../test_import_mapping_package.py | 8 +- 21 files changed, 173 insertions(+), 168 deletions(-) create mode 100644 mapping_workbench/backend/tasks/models/task_response.py diff --git a/mapping_workbench/backend/fields_registry/services/data.py b/mapping_workbench/backend/fields_registry/services/data.py index b0039941a..7fe9d943f 100644 --- a/mapping_workbench/backend/fields_registry/services/data.py +++ b/mapping_workbench/backend/fields_registry/services/data.py @@ -7,13 +7,13 @@ async def get_structural_element_by_unique_fields( - sdk_element_id, name, bt_id, absolute_xpath, project_id: PydanticObjectId + sdk_element_id, bt_id, absolute_xpath, project_id: PydanticObjectId, name: str = None ) -> StructuralElement: project_link = Project.link_from_id(project_id) return await StructuralElement.find_one( StructuralElement.project == project_link, StructuralElement.sdk_element_id == sdk_element_id, - StructuralElement.name == name, + #StructuralElement.name == name, StructuralElement.bt_id == bt_id, StructuralElement.absolute_xpath == absolute_xpath ) diff --git a/mapping_workbench/backend/logger/adapters/console_logger.py b/mapping_workbench/backend/logger/adapters/console_logger.py index 76396f574..89f9fd285 100644 --- a/mapping_workbench/backend/logger/adapters/console_logger.py +++ b/mapping_workbench/backend/logger/adapters/console_logger.py @@ -8,5 +8,7 @@ class LoggerConsole(LoggerABC): def log(self, log_record: LogRecord): if log_record.log_severity == LogSeverity.ERROR: print(str(log_record), file=sys.stderr) + elif log_record.log_severity == LogSeverity.WARNING: + print(str(log_record)) else: print(str(log_record)) diff --git a/mapping_workbench/backend/logger/adapters/sys_logger.py b/mapping_workbench/backend/logger/adapters/sys_logger.py index 85a837171..1657a281c 100644 --- a/mapping_workbench/backend/logger/adapters/sys_logger.py +++ b/mapping_workbench/backend/logger/adapters/sys_logger.py @@ -17,5 +17,7 @@ class LoggerSys(LoggerABC): def log(self, log_record: LogRecord): if log_record.log_severity == LogSeverity.ERROR: logger.error(str(log_record)) + elif log_record.log_severity == LogSeverity.WARNING: + logger.warning(str(log_record)) else: logger.info(str(log_record)) diff --git a/mapping_workbench/backend/logger/models/logger_record.py b/mapping_workbench/backend/logger/models/logger_record.py index 13d50df90..7a8284f2b 100644 --- a/mapping_workbench/backend/logger/models/logger_record.py +++ b/mapping_workbench/backend/logger/models/logger_record.py @@ -11,6 +11,7 @@ class LogSeverity(Enum): INFO = "INFO" + WARNING = "WARNING" ERROR = "ERROR" diff --git a/mapping_workbench/backend/logger/services/logger_factory.py b/mapping_workbench/backend/logger/services/logger_factory.py index b94808653..502014463 100644 --- a/mapping_workbench/backend/logger/services/logger_factory.py +++ b/mapping_workbench/backend/logger/services/logger_factory.py @@ -45,3 +45,11 @@ def log_all_info(self, message: str): ) for logger in self.loggers.values(): logger.log(log_record) + + def log_all_warning(self, message: str): + log_record = LogRecord( + log_severity=LogSeverity.WARNING, + message=message + ) + for logger in self.loggers.values(): + logger.log(log_record) diff --git a/mapping_workbench/backend/package_importer/adapters/eforms/importer.py b/mapping_workbench/backend/package_importer/adapters/eforms/importer.py index 361e9f358..e44982a47 100644 --- a/mapping_workbench/backend/package_importer/adapters/eforms/importer.py +++ b/mapping_workbench/backend/package_importer/adapters/eforms/importer.py @@ -58,15 +58,20 @@ async def add_mapping_rules_from_mono(self, mono_package: ImportedMappingSuite): for mono_rule in mono_package.conceptual_rules: source_structural_element: StructuralElement = await get_structural_element_by_unique_fields( sdk_element_id=mono_rule.eforms_sdk_id, - name=mono_rule.field_name, bt_id=mono_rule.bt_id, absolute_xpath=mono_rule.absolute_xpath, - project_id=self.project.id + project_id=self.project.id, + #name=mono_rule.field_name ) if not source_structural_element: continue + if source_structural_element.name != mono_rule.field_name: + m = f"Field[{source_structural_element.sdk_element_id}] has Imported Name ({mono_rule.field_name}) <> Current Name ({source_structural_element.name})" + mwb_logger.log_all_warning(m) + self.warnings.append(m) + # A conceptual mapping rule may have same structural element but different Ontology Fragment rule: ConceptualMappingRule = await ConceptualMappingRule.find_one( ConceptualMappingRule.source_structural_element == StructuralElement.link_from_id(source_structural_element.id), diff --git a/mapping_workbench/backend/package_importer/adapters/importer_abc.py b/mapping_workbench/backend/package_importer/adapters/importer_abc.py index 0ddfd23b4..322657253 100644 --- a/mapping_workbench/backend/package_importer/adapters/importer_abc.py +++ b/mapping_workbench/backend/package_importer/adapters/importer_abc.py @@ -1,6 +1,6 @@ from abc import ABC, abstractmethod from pathlib import Path -from typing import Dict, Tuple +from typing import Dict, Tuple, List from mapping_workbench.backend.conceptual_mapping_rule.models.entity import ConceptualMappingRule from mapping_workbench.backend.mapping_package.models.entity import MappingPackage @@ -26,6 +26,7 @@ class PackageImporterABC(ABC): package: MappingPackage + warnings: List[str] = [] def __init__(self, project: Project, user: User): self.project = project @@ -33,6 +34,7 @@ def __init__(self, project: Project, user: User): self.user = user self.package = None + @abstractmethod async def import_from_mono_mapping_suite(self, mono_package: ImportedMappingSuite): """ diff --git a/mapping_workbench/backend/package_importer/adapters/standard/importer.py b/mapping_workbench/backend/package_importer/adapters/standard/importer.py index 41717bfdd..d925ad68a 100644 --- a/mapping_workbench/backend/package_importer/adapters/standard/importer.py +++ b/mapping_workbench/backend/package_importer/adapters/standard/importer.py @@ -5,6 +5,7 @@ from mapping_workbench.backend.conceptual_mapping_rule.services.data import get_conceptual_mapping_rule_by_key from mapping_workbench.backend.fields_registry.models.field_registry import StructuralElement from mapping_workbench.backend.fields_registry.services.data import get_structural_element_by_unique_fields +from mapping_workbench.backend.logger.services import mwb_logger from mapping_workbench.backend.mapping_package.models.entity import MappingPackage from mapping_workbench.backend.package_importer.adapters.importer_abc import PackageImporterABC from mapping_workbench.backend.package_importer.models.imported_mapping_suite import ImportedMappingSuite @@ -41,10 +42,10 @@ async def add_mapping_rules_from_mono(self, mono_package: ImportedMappingSuite): for mono_rule in mono_package.conceptual_rules: source_structural_element: StructuralElement = await get_structural_element_by_unique_fields( sdk_element_id=mono_rule.field_name, - name=mono_rule.field_name, bt_id=mono_rule.bt_id, absolute_xpath=mono_rule.absolute_xpath, - project_id=self.project.id + project_id=self.project.id, + #name=mono_rule.field_name ) if not source_structural_element: diff --git a/mapping_workbench/backend/package_importer/entrypoints/api/routes.py b/mapping_workbench/backend/package_importer/entrypoints/api/routes.py index f7431f1f9..225d9b40a 100644 --- a/mapping_workbench/backend/package_importer/entrypoints/api/routes.py +++ b/mapping_workbench/backend/package_importer/entrypoints/api/routes.py @@ -2,7 +2,7 @@ from fastapi import APIRouter, status, Form, UploadFile, Depends from mapping_workbench.backend.mapping_package import PackageType -from mapping_workbench.backend.mapping_package.models.entity import MappingPackage +from mapping_workbench.backend.package_importer.models.imported_mapping_suite import APIImportedMappingSuiteResponse from mapping_workbench.backend.package_importer.services import tasks from mapping_workbench.backend.package_importer.services.import_mapping_suite import \ import_mapping_package_from_archive, clear_project_data @@ -36,7 +36,8 @@ async def route_clear_project_data( "/import/archive", description=f"Import {NAME_FOR_ONE} Archive", name=f"{NAME_FOR_ONE}:import_archive", - status_code=status.HTTP_201_CREATED + status_code=status.HTTP_201_CREATED, + response_model=APIImportedMappingSuiteResponse ) async def route_import_package_archive( project: PydanticObjectId = Form(...), @@ -46,11 +47,11 @@ async def route_import_package_archive( ): if not package_type: package_type = PackageType.EFORMS - mapping_package: MappingPackage = await import_mapping_package_from_archive( + imported_mapping_package: APIImportedMappingSuiteResponse = await import_mapping_package_from_archive( file.file.read(), await get_project(project), package_type, user ) - return mapping_package.model_dump() + return imported_mapping_package @router.post( diff --git a/mapping_workbench/backend/package_importer/models/imported_mapping_suite.py b/mapping_workbench/backend/package_importer/models/imported_mapping_suite.py index 7db9deb2c..39a53feb5 100644 --- a/mapping_workbench/backend/package_importer/models/imported_mapping_suite.py +++ b/mapping_workbench/backend/package_importer/models/imported_mapping_suite.py @@ -1,6 +1,8 @@ from typing import List, Optional from pydantic import BaseModel, Field, ConfigDict +from mapping_workbench.backend.mapping_package.models.entity import MappingPackage + class MappingMetadata(BaseModel): identifier: str = Field(None, alias="Identifier") @@ -108,3 +110,7 @@ class ImportedStandardMappingSuite(ImportedMappingSuite): metadata: StandardMappingMetadata conceptual_rules: List[StandardMappingConceptualRule] = [] + +class APIImportedMappingSuiteResponse(BaseModel): + mapping_package: MappingPackage + warnings: List[str] = [] \ No newline at end of file diff --git a/mapping_workbench/backend/package_importer/services/import_mapping_suite.py b/mapping_workbench/backend/package_importer/services/import_mapping_suite.py index 7e71586dd..6465f4b95 100644 --- a/mapping_workbench/backend/package_importer/services/import_mapping_suite.py +++ b/mapping_workbench/backend/package_importer/services/import_mapping_suite.py @@ -2,6 +2,7 @@ import pathlib import tempfile import zipfile +from typing import Any from mapping_workbench.backend.core.services.exceptions import InvalidResourceException, InvalidPackageTypeException from mapping_workbench.backend.mapping_package import PackageType @@ -10,18 +11,20 @@ from mapping_workbench.backend.package_importer.adapters.importer_abc import PackageImporterABC from mapping_workbench.backend.package_importer.adapters.importer_factory import PackageImporterFactory from mapping_workbench.backend.package_importer.adapters.standard.importer import StandardPackageImporter +from mapping_workbench.backend.package_importer.models.imported_mapping_suite import APIImportedMappingSuiteResponse from mapping_workbench.backend.package_importer.services.import_mono_eforms_mapping_suite import \ import_eforms_mapping_suite_from_file_system from mapping_workbench.backend.package_importer.services.import_mono_standard_mapping_suite import \ import_standard_mapping_suite_from_file_system from mapping_workbench.backend.project.models.entity import Project +from mapping_workbench.backend.tasks.models.task_response import TaskResponse from mapping_workbench.backend.user.models.user import User async def import_mapping_package( mapping_package_dir_path: pathlib.Path, project: Project, package_type: PackageType, user: User = None -) -> MappingPackage: +) -> APIImportedMappingSuiteResponse: if package_type == PackageType.STANDARD: monolith_mapping_suite = import_standard_mapping_suite_from_file_system(mapping_package_dir_path) else: # package_type == PackageType.EFORMS: @@ -31,12 +34,16 @@ async def import_mapping_package( package_type=package_type, project=project, user=user ) package: MappingPackage = await importer.import_from_mono_mapping_suite(monolith_mapping_suite) - return package + + return APIImportedMappingSuiteResponse( + mapping_package=package, + warnings=importer.warnings + ) async def import_mapping_package_from_archive( - file_content: bytes, project: Project, package_type: PackageType, user: User = None -) -> MappingPackage: + file_content: bytes, project: Project, package_type: PackageType, user: User = None, task_response: TaskResponse = None +) -> APIImportedMappingSuiteResponse: zf = zipfile.ZipFile(io.BytesIO(file_content)) tempdir = tempfile.TemporaryDirectory() tempdir_name = tempdir.name @@ -48,7 +55,10 @@ async def import_mapping_package_from_archive( except AssertionError as error: raise InvalidResourceException(str(error)) - return await import_mapping_package(dir_contents[0], project, package_type, user) + result = await import_mapping_package(dir_contents[0], project, package_type, user) + if task_response: + task_response.data = result + return result async def clear_project_data(project: Project, package_type: PackageType = None): diff --git a/mapping_workbench/backend/package_importer/services/tasks.py b/mapping_workbench/backend/package_importer/services/tasks.py index b61ebc7b4..f42c2066c 100644 --- a/mapping_workbench/backend/package_importer/services/tasks.py +++ b/mapping_workbench/backend/package_importer/services/tasks.py @@ -1,8 +1,9 @@ +from mapping_workbench.backend.mapping_package import PackageType from mapping_workbench.backend.package_importer.services.import_mapping_suite import \ import_mapping_package_from_archive -from mapping_workbench.backend.mapping_package import PackageType from mapping_workbench.backend.project.models.entity import Project from mapping_workbench.backend.task_manager.services.task_wrapper import run_task +from mapping_workbench.backend.tasks.models.task_response import TaskResponse from mapping_workbench.backend.user.models.user import User @@ -11,8 +12,11 @@ def task_import_mapping_package( project: Project, package_type: PackageType, user: User = None -): +) -> TaskResponse: + task_response: TaskResponse = TaskResponse() + run_task( import_mapping_package_from_archive, - file_content, project, package_type, user + file_content, project, package_type, user, task_response ) + return task_response diff --git a/mapping_workbench/backend/task_manager/adapters/task.py b/mapping_workbench/backend/task_manager/adapters/task.py index c590a31ed..a4bca470b 100644 --- a/mapping_workbench/backend/task_manager/adapters/task.py +++ b/mapping_workbench/backend/task_manager/adapters/task.py @@ -9,6 +9,7 @@ from pydantic import BaseModel from mapping_workbench.backend.config import settings +from mapping_workbench.backend.tasks.models.task_response import TaskResponse class TaskStatus(str, Enum): @@ -30,6 +31,7 @@ class TaskResult: started_at: datetime = None finished_at: datetime = None exception_message: str = None + warnings: List[str] = [] task_status: TaskStatus = TaskStatus.FINISHED @@ -45,6 +47,7 @@ class TaskMetadata(BaseModel): started_at: datetime = None finished_at: datetime = None exception_message: str = None + warnings: List[str] = [] created_by: Optional[str] = None @@ -68,7 +71,10 @@ def __call__(self, *args, **kwargs) -> TaskResult: task_result = TaskResult() task_result.started_at = datetime.now(tzlocal()) try: - self.task_function(*args, **kwargs) + response = self.task_function(*args, **kwargs) + if isinstance(response, TaskResponse): + if hasattr(response.data, 'warnings'): + task_result.warnings = response.data.warnings task_result.task_status = TaskStatus.FINISHED except Exception as e: task_result.exception_message = str(e) @@ -201,6 +207,11 @@ def update_exception_message(self, exception_message: str): """ self.task_metadata.exception_message = exception_message + def update_warnings(self, warnings: List[str]): + """ + """ + self.task_metadata.warnings = warnings + def get_task_status(self) -> TaskStatus: """ Gets task status. diff --git a/mapping_workbench/backend/task_manager/adapters/task_manager.py b/mapping_workbench/backend/task_manager/adapters/task_manager.py index 887c23e7d..97ea67030 100644 --- a/mapping_workbench/backend/task_manager/adapters/task_manager.py +++ b/mapping_workbench/backend/task_manager/adapters/task_manager.py @@ -20,6 +20,7 @@ def on_task_done_callback(future): task.update_task_status(task_result.task_status) task.update_started_at(task_result.started_at) task.update_finished_at(task_result.finished_at) + task.update_warnings(task_result.warnings) task.update_exception_message(task_result.exception_message) except CancelledError: task.update_task_status(TaskStatus.CANCELED) diff --git a/mapping_workbench/backend/tasks/models/task_response.py b/mapping_workbench/backend/tasks/models/task_response.py new file mode 100644 index 000000000..582559b2b --- /dev/null +++ b/mapping_workbench/backend/tasks/models/task_response.py @@ -0,0 +1,5 @@ +from typing import Any + + +class TaskResponse: + data: Any = None \ No newline at end of file diff --git a/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/develop/list-search.js b/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/develop/list-search.js index ace08c273..1b3e25980 100644 --- a/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/develop/list-search.js +++ b/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/develop/list-search.js @@ -164,7 +164,7 @@ export const ListSearch = (props) => { disableUnderline fullWidth inputProps={{ref: queryRef}} - placeholder="Search by project title" + placeholder="Search" sx={{flexGrow: 1}} /> diff --git a/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/list-search.js b/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/list-search.js index 444f89a87..24c9288c7 100644 --- a/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/list-search.js +++ b/mapping_workbench/frontend/src/sections/app/conceptual-mapping-rule/list-search.js @@ -8,8 +8,6 @@ import Input from '@mui/material/Input'; import Stack from '@mui/material/Stack'; import SvgIcon from '@mui/material/SvgIcon'; import Typography from '@mui/material/Typography'; - -import {MultiSelect} from 'src/components/multi-select'; import Switch from "@mui/material/Switch"; import RadioGroup from "@mui/material/RadioGroup"; import FormControlLabel from "@mui/material/FormControlLabel"; @@ -17,25 +15,14 @@ import Radio from "@mui/material/Radio"; import Paper from "@mui/material/Paper"; -const statusOptions = [ - { - label: 'Published', - value: 'published' - }, - { - label: 'Draft', - value: 'draft' - } -]; - export const ListSearch = (props) => { - const {onFiltersChange, onDetailedViewChange, detailedView, placeholder="Search", showChips, ...other} = props; + const {onFiltersChange, onDetailedViewChange, detailedView, placeholder = "Search", ...other} = props; const queryRef = useRef(null); const firstUpdate = useRef(true) const [chips, setChips] = useState([]); useEffect(() => { - if(firstUpdate.current) + if (firstUpdate.current) firstUpdate.current = false else handleChipsUpdate(); @@ -95,15 +82,13 @@ export const ListSearch = (props) => { return prevChips.map((chip) => chip.field === 'q' ? {...chip, value} : chip); else return prevChips.filter((chip) => chip.field !== 'q'); - } - else - if (value) { - const chip = { - label: 'Q', - field: 'q', - value - }; - return [...prevChips, chip]; + } else if (value) { + const chip = { + label: 'Q', + field: 'q', + value + }; + return [...prevChips, chip]; } return prevChips; }); @@ -150,51 +135,6 @@ export const ListSearch = (props) => { }); } - const handleStatusChange = values => { - setChips((prevChips) => { - const valuesFound = []; - - // First cleanup the previous chips - const newChips = prevChips.filter((chip) => { - if (chip.field !== 'status') { - return true; - } - - const found = values.includes(chip.value); - - if (found) { - valuesFound.push(chip.value); - } - - return found; - }); - - // Nothing changed - if (values.length === valuesFound.length) { - return newChips; - } - - values.forEach((value) => { - if (!valuesFound.includes(value)) { - const option = statusOptions.find((option) => option.value === value); - - newChips.push({ - label: 'Status', - field: 'status', - value, - displayValue: option.label - }); - } - }); - - return newChips; - }); - } - - - // We memoize this part to prevent re-render issues - const statusValues = chips?.filter(chip => chip.field === 'status').map(chip => chip.value) - const termsValidityValue = useMemo(() => (chips .find((chip) => chip.field === 'terms_validity') || {'value': ''}).value, [chips]); @@ -223,57 +163,57 @@ export const ListSearch = (props) => { {chips?.length ? - - {chips.map((chip, index) => ( - - <> - {chip.label} - {` :${chip.displayValue ?? chip.value}`}: - - - )} - onDelete={() => handleChipDelete(chip)} - variant="outlined" - /> - ))} - + + {chips.map((chip, index) => ( + + <> + {chip.label} + {` :${chip.displayValue ?? chip.value}`}: + + + )} + onDelete={() => handleChipDelete(chip)} + variant="outlined" + /> + ))} + : - - - No filters applied - - - } + + + No filters applied + + + } onDetailedViewChange(e, e.target.checked)} - /> - } + onDetailedViewChange(e, e.target.checked)} + /> + } label="Detailed view"/> { - {showChips > 0 && - - } ); }; diff --git a/mapping_workbench/frontend/src/sections/app/tasks/list-table.js b/mapping_workbench/frontend/src/sections/app/tasks/list-table.js index 8c5fa0018..3ed945ea9 100644 --- a/mapping_workbench/frontend/src/sections/app/tasks/list-table.js +++ b/mapping_workbench/frontend/src/sections/app/tasks/list-table.js @@ -24,13 +24,17 @@ import {useGlobalState} from "../../../hooks/use-global-state"; import TableSorterHeader from "../../components/table-sorter-header"; import moment from "moment"; import nl2br from "../../../utils/nl2br"; +import ListItem from "@mui/material/ListItem"; +import List from "@mui/material/List"; export const ListTable = (props) => { const { count = 0, items = [], - onPageChange = () => {}, - onSort = () => {}, + onPageChange = () => { + }, + onSort = () => { + }, sort, onRowsPerPageChange, page = 0, @@ -72,10 +76,10 @@ export const ListTable = (props) => { const SorterHeader = (props) => { const direction = props.fieldName === sort.column && sort.direction === 'desc' ? 'asc' : 'desc'; - return( + return ( ) } @@ -130,6 +134,7 @@ export const ListTable = (props) => { {items.map((item) => { + console.log(item); const item_id = item.task_id; const isCurrent = item_id === currentItem; @@ -237,13 +242,25 @@ export const ListTable = (props) => { gap={3} > {item.exception_message && <> - - Message - - - - {nl2br(item.exception_message)} - + + Message + + + + {nl2br(item.exception_message)} + + } + {item.warnings && item.warnings.length > 0 && <> + + Warning + + + + {item.warnings.map((warning) => + {warning} + )} + }
    diff --git a/tests/unit/backend/first_scenario/_test_scenario.py b/tests/unit/backend/first_scenario/_test_scenario.py index 9030c2611..588adac11 100644 --- a/tests/unit/backend/first_scenario/_test_scenario.py +++ b/tests/unit/backend/first_scenario/_test_scenario.py @@ -2,6 +2,7 @@ import rdflib +from mapping_workbench.backend.mapping_package import PackageType from mapping_workbench.backend.ontology.models.namespace import Namespace ssl._create_default_https_context = ssl._create_unverified_context @@ -44,7 +45,7 @@ async def test_mapping_package_pipeline_scenario(eforms_sdk_repo_v_1_9_1_dir_pat print("Imported eForms fields") project = Project(id=ObjectId(), title="Test project") await project.save() - mapping_package = await import_mapping_package(PACKAGE_EFORMS_16_DIR_PATH, project) + mapping_package = (await import_mapping_package(PACKAGE_EFORMS_16_DIR_PATH, project, PackageType.EFORMS)).mapping_package print("Mapping package id: ", mapping_package.id) assert mapping_package.id await generate_and_save_cm_assertions_queries(project_id=project.id) diff --git a/tests/unit/backend/package_exporter/test_package_exporter.py b/tests/unit/backend/package_exporter/test_package_exporter.py index 51466c2f3..91b298dd1 100644 --- a/tests/unit/backend/package_exporter/test_package_exporter.py +++ b/tests/unit/backend/package_exporter/test_package_exporter.py @@ -1,4 +1,6 @@ import ssl + +from mapping_workbench.backend.mapping_package import PackageType from mapping_workbench.backend.ontology.models.namespace import Namespace ssl._create_default_https_context = ssl._create_unverified_context @@ -42,7 +44,7 @@ async def _test_package_exporter(eforms_sdk_repo_v_1_9_1_dir_path): print("Imported eForms fields") project = Project(id=ObjectId(), title="Test project") await project.save() - mapping_package = await import_mapping_package(PACKAGE_EFORMS_16_DIR_PATH, project) + mapping_package = (await import_mapping_package(PACKAGE_EFORMS_16_DIR_PATH, project, PackageType.EFORMS)).mapping_package print("Mapping package id: ", mapping_package.id) assert mapping_package.id await generate_and_save_cm_assertions_queries(project_id=project.id) diff --git a/tests/unit/backend/package_importer/test_import_mapping_package.py b/tests/unit/backend/package_importer/test_import_mapping_package.py index cb4a33208..0b24c9feb 100644 --- a/tests/unit/backend/package_importer/test_import_mapping_package.py +++ b/tests/unit/backend/package_importer/test_import_mapping_package.py @@ -85,9 +85,9 @@ async def check_cleared_imported_data(project): async def test_import_eforms_mapping_package(dummy_project, dummy_structural_element): await dummy_structural_element.create() - eforms_package = await import_mapping_package_from_archive( + eforms_package = (await import_mapping_package_from_archive( read_archive(EFORMS_PACKAGE_PATH), dummy_project, PackageType.EFORMS - ) + )).mapping_package await check_imported_data(dummy_project, eforms_package, 'package_eforms_16_v1.2') @@ -106,9 +106,9 @@ async def test_import_eforms_mapping_package(dummy_project, dummy_structural_ele @pytest.mark.asyncio async def test_import_standard_mapping_package(dummy_project, dummy_structural_element): - standard_package = await import_mapping_package_from_archive( + standard_package = (await import_mapping_package_from_archive( read_archive(STANDARD_PACKAGE_PATH), dummy_project, PackageType.STANDARD - ) + )).mapping_package await check_imported_data(dummy_project, standard_package, 'package_F03') From b7a4d1c68a906425afc858e579e23e1f1f76311d Mon Sep 17 00:00:00 2001 From: Kolea PLESCO Date: Mon, 30 Sep 2024 20:44:34 +0300 Subject: [PATCH 35/35] updated importer to display warnings + fix cm rules import algo --- .../package_importer/entrypoints/api/routes.py | 6 +++--- .../models/imported_mapping_suite.py | 2 +- .../services/import_mapping_suite.py | 14 +++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/mapping_workbench/backend/package_importer/entrypoints/api/routes.py b/mapping_workbench/backend/package_importer/entrypoints/api/routes.py index 225d9b40a..8fb2d25fc 100644 --- a/mapping_workbench/backend/package_importer/entrypoints/api/routes.py +++ b/mapping_workbench/backend/package_importer/entrypoints/api/routes.py @@ -2,7 +2,7 @@ from fastapi import APIRouter, status, Form, UploadFile, Depends from mapping_workbench.backend.mapping_package import PackageType -from mapping_workbench.backend.package_importer.models.imported_mapping_suite import APIImportedMappingSuiteResponse +from mapping_workbench.backend.package_importer.models.imported_mapping_suite import ImportedMappingSuiteResponse from mapping_workbench.backend.package_importer.services import tasks from mapping_workbench.backend.package_importer.services.import_mapping_suite import \ import_mapping_package_from_archive, clear_project_data @@ -37,7 +37,7 @@ async def route_clear_project_data( description=f"Import {NAME_FOR_ONE} Archive", name=f"{NAME_FOR_ONE}:import_archive", status_code=status.HTTP_201_CREATED, - response_model=APIImportedMappingSuiteResponse + response_model=ImportedMappingSuiteResponse ) async def route_import_package_archive( project: PydanticObjectId = Form(...), @@ -47,7 +47,7 @@ async def route_import_package_archive( ): if not package_type: package_type = PackageType.EFORMS - imported_mapping_package: APIImportedMappingSuiteResponse = await import_mapping_package_from_archive( + imported_mapping_package: ImportedMappingSuiteResponse = await import_mapping_package_from_archive( file.file.read(), await get_project(project), package_type, user ) diff --git a/mapping_workbench/backend/package_importer/models/imported_mapping_suite.py b/mapping_workbench/backend/package_importer/models/imported_mapping_suite.py index 39a53feb5..2143738fe 100644 --- a/mapping_workbench/backend/package_importer/models/imported_mapping_suite.py +++ b/mapping_workbench/backend/package_importer/models/imported_mapping_suite.py @@ -111,6 +111,6 @@ class ImportedStandardMappingSuite(ImportedMappingSuite): conceptual_rules: List[StandardMappingConceptualRule] = [] -class APIImportedMappingSuiteResponse(BaseModel): +class ImportedMappingSuiteResponse(BaseModel): mapping_package: MappingPackage warnings: List[str] = [] \ No newline at end of file diff --git a/mapping_workbench/backend/package_importer/services/import_mapping_suite.py b/mapping_workbench/backend/package_importer/services/import_mapping_suite.py index 6465f4b95..71909edb6 100644 --- a/mapping_workbench/backend/package_importer/services/import_mapping_suite.py +++ b/mapping_workbench/backend/package_importer/services/import_mapping_suite.py @@ -2,16 +2,15 @@ import pathlib import tempfile import zipfile -from typing import Any -from mapping_workbench.backend.core.services.exceptions import InvalidResourceException, InvalidPackageTypeException +from mapping_workbench.backend.core.services.exceptions import InvalidResourceException from mapping_workbench.backend.mapping_package import PackageType from mapping_workbench.backend.mapping_package.models.entity import MappingPackage from mapping_workbench.backend.package_importer.adapters.eforms.importer import EFormsPackageImporter from mapping_workbench.backend.package_importer.adapters.importer_abc import PackageImporterABC from mapping_workbench.backend.package_importer.adapters.importer_factory import PackageImporterFactory from mapping_workbench.backend.package_importer.adapters.standard.importer import StandardPackageImporter -from mapping_workbench.backend.package_importer.models.imported_mapping_suite import APIImportedMappingSuiteResponse +from mapping_workbench.backend.package_importer.models.imported_mapping_suite import ImportedMappingSuiteResponse from mapping_workbench.backend.package_importer.services.import_mono_eforms_mapping_suite import \ import_eforms_mapping_suite_from_file_system from mapping_workbench.backend.package_importer.services.import_mono_standard_mapping_suite import \ @@ -24,7 +23,7 @@ async def import_mapping_package( mapping_package_dir_path: pathlib.Path, project: Project, package_type: PackageType, user: User = None -) -> APIImportedMappingSuiteResponse: +) -> ImportedMappingSuiteResponse: if package_type == PackageType.STANDARD: monolith_mapping_suite = import_standard_mapping_suite_from_file_system(mapping_package_dir_path) else: # package_type == PackageType.EFORMS: @@ -35,15 +34,16 @@ async def import_mapping_package( ) package: MappingPackage = await importer.import_from_mono_mapping_suite(monolith_mapping_suite) - return APIImportedMappingSuiteResponse( + return ImportedMappingSuiteResponse( mapping_package=package, warnings=importer.warnings ) async def import_mapping_package_from_archive( - file_content: bytes, project: Project, package_type: PackageType, user: User = None, task_response: TaskResponse = None -) -> APIImportedMappingSuiteResponse: + file_content: bytes, project: Project, package_type: PackageType, user: User = None, + task_response: TaskResponse = None +) -> ImportedMappingSuiteResponse: zf = zipfile.ZipFile(io.BytesIO(file_content)) tempdir = tempfile.TemporaryDirectory() tempdir_name = tempdir.name