ProblematicThingViewDetails.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. //© 2019 Dublin City University, Trinity College Dublin. All rights reserved. This material may not be reproduced, displayed, modified or distributed without the express prior written permission of the copyright holder.
  2. import React, { Component } from 'react';
  3. import { Nav, NavItem, NavLink, TabContent, UncontrolledTooltip, Table, TabPane, Modal, Col, Row, ModalBody, ModalHeader, ModalFooter, Button } from 'reactstrap';
  4. import classnames from 'classnames';
  5. import exceptionInfoIconDetails from '../../../../config/exceptionInfoIconDetails';
  6. import { connect } from 'react-redux';
  7. import LoadingSpinner from '../../loading';
  8. import LoadingFailed from '../../loadingFailed';
  9. import { read } from '../../../../services/tripleStoreAPIs/readFromTripleStore';
  10. import { fetchListOfSimilarTriples } from '../../../../services/tripleStoreAPIs/sparql/fetchListOfSimilarTriples';
  11. import properties from '../../../../config/dashboardProperties';
  12. class ProblematicThingViewDetails extends Component {
  13. constructor(props) {
  14. //console.log("ProblematicThingViewDetails constructor");
  15. super(props);
  16. this.state = {
  17. problematicThing: "",
  18. activeTab: "",
  19. navigationTabs: [],
  20. triples: [],
  21. isloading: false,
  22. dataGraph: "",
  23. graphType: ""
  24. }
  25. //console.log(this.props);
  26. }
  27. toggleTab = (tabID) => {
  28. //console.log(typeof tabID);
  29. if (this.state.activeTab !== tabID) {
  30. this.setState({
  31. activeTab: tabID
  32. });
  33. }
  34. }
  35. componentDidMount() {
  36. //console.log("componentDidMount");
  37. this.setState({
  38. isloading: true
  39. }, () => {
  40. this.initialize().then((results) => {
  41. this.setState({
  42. problematicThing: results[0],
  43. activeTab: results[1],
  44. navigationTabs: results[2],
  45. dataGraph: results[3],
  46. graphType: results[4],
  47. triples: results[5],
  48. isloading: false
  49. });
  50. }
  51. );
  52. });
  53. }
  54. initialize = async () => {
  55. //console.log("initialize");
  56. let problematicThing = Object.keys(this.props.problematicThingDetails)[0];
  57. let activeTab = "Default";
  58. let navigationTabs = [];
  59. navigationTabs.push("Default");
  60. /*
  61. if (this.props.problematicThingDetails[problematicThing].effectedResources.length > 0) {
  62. navigationTabs.push("Impacted Resources");
  63. }*/
  64. if (this.props.problematicThingDetails[problematicThing].linkedProblematicThings.length > 0) {
  65. navigationTabs.push("Linked Problematic Things");
  66. }
  67. navigationTabs.sort();
  68. let dataGraph = "";
  69. let graphType = "";
  70. if (this.props.datasetDetailsCache[0].isSparqlEndPoint) {
  71. dataGraph = this.props.datasetDetailsCache[0].sparqlEndPoint;
  72. graphType = "SERVICE";
  73. }
  74. else {
  75. let dataGraphName = this.props.datasetDetailsCache[0].fileName.replace(/^.*[\\/]/, '').split('.').slice(0, -1).join('.');
  76. dataGraph = "http://" + properties.tripleStore.host + ":" + properties.tripleStore.port + "/" + properties.tripleStore.datastore + "/data/" + dataGraphName;
  77. graphType = "GRAPH";
  78. }
  79. let query = await this.prepareQuery(problematicThing);
  80. //console.log(query);
  81. let triples = await this.fetchListOfTriples(dataGraph, graphType, query, problematicThing);
  82. //console.log(triples);
  83. return [problematicThing, activeTab, navigationTabs, dataGraph, graphType, triples];
  84. }
  85. fetchListOfTriples_NEW = (dataGraph, graphType, query, problematicThing) => {
  86. let triples = [];
  87. let problem = problematicThing.split("-> ")[1];
  88. let problematicPart = problematicThing.split("-> ")[0];
  89. return new Promise((resolve) => {
  90. //let knowledgeBaseCache = JSON.parse(sessionStorage.getItem(this.props.knowledgeBaseID));
  91. //let knowledgeBaseCache = this.props.knowledgeBaseCache;
  92. for (const knowledgeBase of this.props.knowledgeBaseCache) {
  93. if ((this.props.currentMetrics.indexOf(knowledgeBase.FailedMertic)>=0) & knowledgeBase[problematicPart]===problem) {
  94. triples.push({
  95. Subject: knowledgeBase.Subject,
  96. Predicate: knowledgeBase.Predicate,
  97. Object: knowledgeBase.Object,
  98. Exception: []
  99. });
  100. }
  101. }
  102. for (const triple of triples) {
  103. //console.log("Inside Triple Array : "+tripleArray);
  104. for (const knowledgeBase of this.props.knowledgeBaseCache) {
  105. if (knowledgeBase.Subject === triple.Subject & knowledgeBase.Predicate === triple.Predicate & knowledgeBase.Object === triple.Object) {
  106. triple.Exception.push(knowledgeBase.Exception);
  107. }
  108. }
  109. }
  110. resolve(triples);
  111. });
  112. }
  113. fetchListOfTriples = (dataGraph, graphType, query, problematicThing) => {
  114. let triples = [];
  115. let problem = problematicThing.split("-> ")[1];
  116. return new Promise((resolve) => {
  117. read(fetchListOfSimilarTriples(graphType, dataGraph, query)).then((response) => {
  118. //console.log(response);
  119. if (response) {
  120. if (response.results.bindings.length > 0) {
  121. for (const result of response.results.bindings) {
  122. let subject = "";
  123. let predicate = "";
  124. let object = "";
  125. if (result.Subject === undefined) {
  126. subject = problem;
  127. }
  128. else {
  129. subject = "<" + result.Subject.value + ">";
  130. }
  131. if (result.Predicate === undefined) {
  132. predicate = problem;
  133. }
  134. else {
  135. predicate = "<" + result.Predicate.value + ">";
  136. }
  137. if (result.Object === undefined) {
  138. object = problem;
  139. }
  140. else {
  141. if (result.Object.type === "uri") {
  142. object += "<" + result.Object.value + ">";
  143. }
  144. else {
  145. if (result.Object["xml:lang"] !== undefined) {
  146. object += "\"\"\"" + result.Object.value + "\"\"\"@" + result.Object["xml:lang"];
  147. }
  148. else if (result.Object["datatype"] !== undefined) {
  149. let value = result.Object.value.replace(/("|')/g, '\\$1');
  150. object += "\"\"\"" + value + "\"\"\"" + "^^<" + result.Object["datatype"] + ">";
  151. }
  152. else {
  153. object += "\"\"\"" + result.Object.value + "\"\"\"";
  154. }
  155. }
  156. }
  157. triples.push({
  158. Subject: subject,
  159. Predicate: predicate,
  160. Object: object,
  161. Exception: []
  162. });
  163. }
  164. //let knowledgeBaseCache = JSON.parse(sessionStorage.getItem(this.props.knowledgeBaseID));
  165. //let knowledgeBaseCache = this.props.knowledgeBaseCache;
  166. let tripleArray = 0;
  167. for (const triple of triples) {
  168. //console.log("Inside Triple Array : "+tripleArray);
  169. for (const knowledgeBase of this.props.knowledgeBaseCache) {
  170. if (knowledgeBase.Subject === triple.Subject & knowledgeBase.Predicate === triple.Predicate & knowledgeBase.Object === triple.Object) {
  171. triple.Exception.push(knowledgeBase.Exception);
  172. }
  173. }
  174. tripleArray += 1;
  175. }
  176. //console.log("Returning Similar Resources");
  177. //console.log(similarResourcesFound);
  178. resolve(triples);
  179. }
  180. else {
  181. resolve(triples);
  182. }
  183. }
  184. else {
  185. resolve(triples);
  186. }
  187. });
  188. });
  189. }
  190. prepareQuery = (problematicThing) => {
  191. //console.log("prepareQuery");
  192. let problematicPart = problematicThing.split("-> ")[0];
  193. let problem = problematicThing.split("-> ")[1];
  194. let query = "";
  195. return new Promise((resolve) => {
  196. if (problematicPart === "Subject") {
  197. query = problem + " ?Predicate ?Object";
  198. }
  199. else if (problematicPart === "Predicate") {
  200. query = "?Subject " + problem + " ?Object";
  201. }
  202. else if (problematicPart === "Object") {
  203. query = "?Subject ?Predicate " + problem;
  204. }
  205. resolve(query);
  206. });
  207. }
  208. renderDetails = (tabID) => {
  209. switch (tabID) {
  210. case "Default":
  211. return (<React.Fragment>
  212. <div className="text-center">
  213. <h6 className="mb-1">{this.state.problematicThing}</h6>
  214. <p style={{ fontSize: "14px" }}>Exception(s) Related to this Problematic Thing : {this.props.problematicThingDetails[this.state.problematicThing].exception.map((exception, indexException) => { return <React.Fragment key={indexException}><i>{exception} </i><i className="fa fa-info-circle" id={exception + "_toolTipIcon"}> </i><UncontrolledTooltip placement="right" target={exception + "_toolTipIcon"}>{exceptionInfoIconDetails.infoIcon[exception]}</UncontrolledTooltip>&nbsp;</React.Fragment> })}</p>
  215. </div>
  216. <font size="2" >
  217. <Table hover bordered><thead><tr><th>Subject</th><th>Predicate</th><th>Object</th><th>Exception(s)</th></tr></thead><tbody>
  218. {this.state.triples.map((triple, indexInside) => {
  219. if (triple.Exception.length > 0) {
  220. return <tr key={indexInside} style={{ 'backgroundColor': 'rgba(255,255,102,0.5)' }} ><td>{triple.Subject}</td><td>{triple.Predicate}</td><td>{triple.Object}</td><td>{triple.Exception.join(', ')}</td></tr>
  221. }
  222. return <tr key={indexInside}><td>{triple.Subject}</td><td>{triple.Predicate}</td><td>{triple.Object}</td><td></td></tr>
  223. })}
  224. </tbody></Table></font>
  225. </React.Fragment>);
  226. case "Impacted Resources":
  227. return (<React.Fragment><Table hover bordered striped><thead><tr><th>Resource</th></tr></thead><tbody>
  228. {this.props.problematicThingDetails[this.state.problematicThing].effectedResources.map((resource, indexInside) => {
  229. return <tr key={indexInside}><td>{resource}</td></tr>
  230. })}
  231. </tbody></Table>
  232. </React.Fragment>);
  233. case "Linked Problematic Things":
  234. return (<React.Fragment><Table hover bordered striped><thead><tr><th>Problematic Thing <small>(Click on the link to navigate)</small></th></tr></thead><tbody>
  235. {this.props.problematicThingDetails[this.state.problematicThing].linkedProblematicThings.map((link, indexInside) => {
  236. return <tr key={indexInside}><td onClick={() => this.props.linkNavigation(link)}>{link}</td></tr>
  237. })}
  238. </tbody></Table>
  239. </React.Fragment>);
  240. }
  241. }
  242. render() {
  243. //console.log(this.state);
  244. let navigationTabs = null;
  245. let displayPane = null;
  246. navigationTabs = (this.state.navigationTabs.map((tabID, index) => {
  247. return <NavItem key={index}><NavLink className={classnames({ active: this.state.activeTab === tabID })} onClick={() => { this.toggleTab(tabID); }}>{tabID}</NavLink></NavItem>
  248. }));
  249. displayPane = (this.state.navigationTabs.map((tabID, index) => {
  250. return <TabPane key={index} tabId={tabID} style={{ overflow: 'scroll', height: '30rem' }}><Row><Col>
  251. {
  252. this.renderDetails(tabID)
  253. }
  254. </Col></Row></TabPane>
  255. }));
  256. return (
  257. <React.Fragment>
  258. <Modal isOpen={true} className="modal-dialog-centered mw-100 w-100" >
  259. <ModalHeader style={{ margin: 'auto' }}>Problematic Thing Details</ModalHeader>
  260. <ModalBody>
  261. <Nav tabs>
  262. {navigationTabs}
  263. </Nav>
  264. <TabContent activeTab={this.state.activeTab}>
  265. {displayPane}
  266. </TabContent>
  267. </ModalBody>
  268. <ModalFooter>
  269. <Button color="secondary" onClick={this.props.closeModel}>Ok</Button>
  270. </ModalFooter>
  271. {this.state.isloading ? <LoadingSpinner /> : null}
  272. </Modal>
  273. </React.Fragment>
  274. );
  275. }
  276. }
  277. const mapStateToProps = (state, ownProps) => {
  278. let datasetID = Number(ownProps.datasetID);
  279. let datasetDetails = state.datasetDetailsCache.filter((dataset) => { if (dataset.datasetID === datasetID) { return dataset; } return null; });
  280. return (
  281. {
  282. datasetDetailsCache: datasetDetails
  283. }
  284. );
  285. }
  286. export default connect(mapStateToProps)(ProblematicThingViewDetails);