DataSetLarge.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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 {
  4. Col,
  5. Container,
  6. Button,
  7. ButtonDropdown,
  8. ButtonGroup,
  9. Card,
  10. CardBody,
  11. CardText,
  12. CardTitle,
  13. CardSubtitle,
  14. DropdownItem,
  15. DropdownMenu,
  16. DropdownToggle,
  17. Media
  18. } from 'reactstrap';
  19. import { withRouter, Link } from 'react-router-dom';
  20. import CircularProgressbar from 'react-circular-progressbar';
  21. import 'react-circular-progressbar/dist/styles.css';
  22. import { getRecentAssessmentQuality } from '../../../services/tripleStoreAPIs/sparql/getRecentAssessmentQuality';
  23. import { read } from '../../../services/tripleStoreAPIs/readFromTripleStore';
  24. import { triggerAssessment } from '../../../services/luzzuFrameWorkAPIs/triggerAssessment';
  25. import { cancelAssessment } from '../../../services/luzzuFrameWorkAPIs/cancelAssessment';
  26. import LoadingSpinner from '../loading';
  27. import LoadingFailed from '../loadingFailed';
  28. import { updateDataset, getStatus } from '../../../services/datasetConfigDetails/datasetConfigDetails';
  29. import { getStatusUpdate } from '../../../services/luzzuFrameWorkAPIs/getStatusUpdate';
  30. const noteReadyToPublish = "rgba(255,0,0,0.6)";
  31. const readyToPublish = "rgba(34,139,34,0.8)";
  32. class DataSetLarge extends Component {
  33. state = {
  34. dropdownOpen: false,
  35. dataSetLastAssessed: "Not Assessed Yet",
  36. canAssess: true,
  37. lastAssessmentQuality: 0.0,
  38. isloading: false,
  39. loadFailed: false,
  40. lastAssessmentMetrics: [],
  41. datasetID:this.props.dataSetDetails.datasetID
  42. };
  43. recall = 0;
  44. toggle = () => {
  45. this.setState({
  46. dropdownOpen: !this.state.dropdownOpen,
  47. });
  48. }
  49. componentDidMount() {
  50. if (this.props.dataSetDetails.lastAssessmentRequestID !== "") {
  51. getStatusUpdate(this.props.dataSetDetails.lastAssessmentRequestID).then((response) => {
  52. if (typeof response !== 'undefined') {
  53. if (response.Status === "INPROGRESS") {
  54. this.setState(
  55. {
  56. canAssess: false
  57. }, () => { this.statusUpdate(); }
  58. );
  59. }
  60. }
  61. });
  62. }
  63. this.getLatestAssessmentQuality();
  64. }
  65. componentWillUnmount() {
  66. //console.log("Component Will Unmount");
  67. //console.log(this.recall);
  68. clearInterval(this.recall);
  69. //console.log(this.recall);
  70. }
  71. checkWrapperServiceIsReachable =()=>
  72. {
  73. let isReachable = false;
  74. return new Promise((resolve)=>
  75. {
  76. this.setState({isloading:true},()=>{
  77. getStatus().then((response)=>{
  78. this.setState({isloading:false},()=>{
  79. if(response.status===200)
  80. {
  81. if(response.data.status==="OK")
  82. {
  83. isReachable=true;
  84. resolve(isReachable);
  85. }
  86. else
  87. {
  88. isReachable=false;
  89. resolve(isReachable);
  90. }
  91. }
  92. else
  93. {
  94. isReachable=false;
  95. resolve(isReachable);
  96. }
  97. });
  98. });
  99. });
  100. }
  101. );
  102. }
  103. handleAssessClick = async () => {
  104. let wrapperServiceIsReachable=false;
  105. wrapperServiceIsReachable = await this.checkWrapperServiceIsReachable();
  106. if(wrapperServiceIsReachable)
  107. {
  108. this.setState({ isloading: true }, () => {
  109. triggerAssessment(this.props.dataSetDetails).then((response) => {
  110. console.log(this.props.dataSetDetails)
  111. console.log(response)
  112. if (response.status === 200) {
  113. this.setState(prevState => ({
  114. isloading: false,
  115. loadFailed: false,
  116. canAssess: false
  117. }), () => {
  118. let knowledgeBaseCache = JSON.parse(sessionStorage.getItem(this.props.dataSetDetails.knowledgeBaseID));
  119. if(knowledgeBaseCache!==null)
  120. {
  121. sessionStorage.removeItem(this.props.dataSetDetails.knowledgeBaseI);
  122. }
  123. this.statusUpdate();
  124. this.setState({ isloading: true }, () => {
  125. updateDataset({"lastAssessmentRequestID":response.data['Request-ID'], "knowledgeBaseID":""}, this.props.dataSetDetails.datasetID).then((response) => {
  126. console.log(response)
  127. if (response.status === 200) {
  128. this.setState({
  129. isloading: false,
  130. //loadFailed: false
  131. });
  132. }
  133. else {
  134. this.setState({
  135. isloading: false,
  136. //loadFailed: true
  137. });
  138. }
  139. });
  140. });
  141. });
  142. this.props.whenUpdated({...this.props.dataSetDetails, lastAssessmentRequestID:response.data['Request-ID'],knowledgeBaseID:"" });
  143. }
  144. else {
  145. this.setState({
  146. isloading: false,
  147. loadFailed: true
  148. });
  149. }
  150. })
  151. }
  152. );
  153. }
  154. else
  155. {
  156. this.setState({
  157. loadFailed: true
  158. });
  159. }
  160. }
  161. getLatestAssessmentQuality = () => {
  162. read(getRecentAssessmentQuality(this.props.dataSetDetails.datasetPLD)).then((response) => {
  163. let assessmentValues = [];
  164. let assessmentDate = "Not Assessed Yet";
  165. let calculateValue = [];
  166. let actualValue = 0.0;
  167. if (response) {
  168. if (response.results.bindings.length > 0) {
  169. calculateValue = response.results.bindings.map((metricDetails) => {
  170. let metricValueType = (metricDetails.Value.datatype).split("#")[1]
  171. let metricValue = 0.0;
  172. assessmentDate = metricDetails.TimePeriod.value;
  173. if (metricValueType === "boolean") {
  174. let metricValueTemp = metricDetails.Value.value
  175. if (metricValueTemp === "true") {
  176. metricValue = 1.0;
  177. }
  178. }
  179. else {
  180. metricValue = Number.parseFloat(metricDetails.Value.value).toFixed(2)
  181. }
  182. assessmentValues.push(
  183. metricDetails
  184. );
  185. return (this.props.dataSetDetails.assessmentMetrics.filter((metric) => { if (metric.assess === true & metric.metric === metricDetails.Metric.value) { return true; } return false }).map((metric) => {if (metricValueType === "boolean") { if(metricValue===metric.target){return parseFloat(1.0, 10);}else{return parseFloat(0.0, 10);}}else{return parseFloat(metricValue, 10);}}));
  186. });
  187. }
  188. }
  189. let filteredArray = calculateValue.flat();
  190. if (filteredArray.length >0) {
  191. actualValue = filteredArray.reduce((previous, current) => current += previous) / filteredArray.length;
  192. }
  193. this.setState(
  194. {
  195. dataSetLastAssessed: (assessmentDate).split(".")[0],
  196. lastAssessmentQuality: Number(parseFloat(actualValue).toFixed(4)),
  197. lastAssessmentMetrics: [...assessmentValues]
  198. }, ()=> { //console.log(this.state.lastAssessmentQuality);
  199. this.props.whenUpdated({...this.props.dataSetDetails, dataSetLastAssessed:assessmentDate, lastAssessmentQuality:this.state.lastAssessmentQuality,lastAssessmentMetrics:[...this.state.lastAssessmentMetrics] });}
  200. );
  201. });
  202. }
  203. statusUpdate = async () => {
  204. this.recall = setInterval(async () => {
  205. //console.log("Status Update");
  206. await getStatusUpdate(this.props.dataSetDetails.lastAssessmentRequestID).then((response) => {
  207. if (typeof response === 'undefined') {
  208. this.setState(
  209. {
  210. canAssess: true
  211. });
  212. clearInterval(this.recall);
  213. }
  214. else {
  215. if (response.Status !== "INPROGRESS") {
  216. this.setState(
  217. {
  218. canAssess: true
  219. }
  220. );
  221. clearInterval(this.recall);
  222. this.getLatestAssessmentQuality();
  223. }
  224. }
  225. });
  226. }, 5000);
  227. }
  228. toggleAlertModel = () => {
  229. this.setState({
  230. loadFailed: false
  231. });
  232. }
  233. cancelAssessment =()=>
  234. {
  235. this.setState({ isloading: true }, () => {
  236. cancelAssessment(this.props.dataSetDetails.lastAssessmentRequestID).then((response)=>{
  237. //console.log(response);
  238. if (response.status === 200 ) {
  239. if(response.data.Status==="CANCELLED")
  240. {
  241. this.setState({
  242. isloading: false,
  243. loadFailed: false,
  244. canAssess: true}, ()=>{
  245. clearInterval(this.recall);
  246. });
  247. }
  248. else {
  249. this.setState({
  250. isloading: false,
  251. loadFailed: true});
  252. }
  253. }
  254. else {
  255. this.setState({
  256. isloading: false,
  257. loadFailed: true});
  258. }
  259. });
  260. });
  261. }
  262. openConfig = () => {
  263. this.props.onConfigClick(this.props.dataSetDetails);
  264. }
  265. render() {
  266. let camelize = (str) => {
  267. return str.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
  268. return index === 0 ? word.toLowerCase() : word.toUpperCase();
  269. }).replace(/\s+/g, '');
  270. }
  271. let percentageValue = 0;
  272. percentageValue = Number.parseFloat(this.state.lastAssessmentQuality * 100).toFixed(2);
  273. //console.log(percentageValue);
  274. let canPublish = "Not Ready to Publish";
  275. let displayColour = noteReadyToPublish;
  276. let canPublishClass = "text-left font-weight-bold";
  277. if (this.state.lastAssessmentQuality >= this.props.dataSetDetails.expectedProgress) {
  278. canPublish = "Ready to Publish";
  279. displayColour = readyToPublish;
  280. canPublishClass = "text-left font-weight-bold";
  281. }
  282. return (
  283. <Col xs="12" sm="6" lg="4">
  284. <Container style={{ margin: 'auto' }} className=" w-100 h-90 dataSetTiles" >
  285. <Card className="text-white bg-info text-center w-100 h-90 " >
  286. <CardBody className="pb-0">
  287. <ButtonGroup className="float-right">
  288. <ButtonDropdown id='card1' isOpen={this.state.dropdownOpen} toggle={this.toggle}>
  289. <DropdownToggle caret className="p-0" color="transparent">
  290. <Media className="icon-settings"></Media>
  291. </DropdownToggle>
  292. <DropdownMenu right>
  293. <DropdownItem onClick={this.props.onRemoveClick}>Remove</DropdownItem>
  294. <DropdownItem onClick={this.openConfig}>Config</DropdownItem>
  295. {!this.state.canAssess?<DropdownItem onClick={this.cancelAssessment}>Cancel Assessment</DropdownItem>:null}
  296. </DropdownMenu>
  297. </ButtonDropdown>
  298. </ButtonGroup>
  299. <Link to={{ pathname: this.props.location.pathname + "/" + (this.props.dataSetDetails.datasetID) }}>
  300. <CardTitle className="text-value font-weight-bold text-dark text-left text-truncate">{this.props.dataSetDetails.datasetName}</CardTitle>
  301. <CardSubtitle className={canPublishClass} style={{ color: displayColour }}>{canPublish}</CardSubtitle>
  302. <div style={{ width: '150px', margin: 'auto' }}>
  303. <CircularProgressbar percentage={percentageValue} text={`${percentageValue}%`} background backgroundPadding={6} styles={{ background: { fill: '#3e98c7' }, text: { fill: displayColour }, path: { stroke: displayColour }, trail: { stroke: 'transparent' } }} />
  304. </div>
  305. <br />
  306. </Link>
  307. {this.state.canAssess ? <Button block color="secondary" aria-pressed="true" onClick={this.handleAssessClick} >Run Assessment</Button> : <Button disabled block color="secondary" aria-pressed="true" onClick={this.handleAssessClick} >Run Assessment</Button>}
  308. <CardText className="text-dark">Last Assessed : {this.state.dataSetLastAssessed}</CardText>
  309. </CardBody>
  310. </Card>
  311. </Container>
  312. {this.state.isloading ? <LoadingSpinner /> : null}
  313. {this.state.loadFailed ? <LoadingFailed clickHandler={this.toggleAlertModel} /> : null}
  314. </Col>
  315. );
  316. }
  317. }
  318. export default withRouter(DataSetLarge);