From 109d45987b5e9d819b61e9f9c62d78f276668814 Mon Sep 17 00:00:00 2001 From: Ethan Finlay Date: Mon, 19 Dec 2022 12:20:33 -0500 Subject: [PATCH] fixing issue unresolve bug and adding concept of scanIssue/decreased amount of intial data on issue load --- assets/js/Components/UfixitModal.js | 268 ++++++++++++++++++---------- assets/js/Services/Api.js | 16 ++ src/Controller/IssuesController.php | 16 ++ src/Entity/Issue.php | 3 - 4 files changed, 203 insertions(+), 100 deletions(-) diff --git a/assets/js/Components/UfixitModal.js b/assets/js/Components/UfixitModal.js index cfa1e03f9..5a51b0432 100644 --- a/assets/js/Components/UfixitModal.js +++ b/assets/js/Components/UfixitModal.js @@ -32,6 +32,7 @@ class UfixitModal extends React.Component { this.state = { windowContents: 'preview', expandExample: false, + issueDetailsPending: true } this.modalMessages = [] @@ -46,6 +47,22 @@ class UfixitModal extends React.Component { this.handleManualScan = this.handleManualScan.bind(this) } + componentDidMount() { + this.syncIssue(this.props.activeIssue) + } + + componentDidUpdate(prevProps, prevState) { + if (prevProps.activeIssue.id != this.props.activeIssue.id) { + this.setState({ + windowContents: 'preview', + expandExample: false, + issueDetailsPending: true + }) + + this.syncIssue(this.props.activeIssue) + } + } + findActiveIndex() { if (this.props.filteredRows && this.props.activeIssue) { for (const i in this.props.filteredRows) { @@ -69,6 +86,7 @@ class UfixitModal extends React.Component { newIndex = 0 } this.clearMessages() + this.setState({ issueDetailsPending: true }) this.props.handleActiveIssue(this.props.filteredRows[newIndex].issue, newIndex) } @@ -87,14 +105,18 @@ class UfixitModal extends React.Component { const pending = (this.props.activeIssue && (this.props.activeIssue.pending == '1')) let activeIndex = this.findActiveIndex(); - const UfixitForm = returnIssueForm(activeIssue) + let code = '' + let UfixitForm let showExample = false if (!this.props.t(`rule.example.${activeIssue.scanRuleId}`).includes('rule.example')) { showExample = true } - let code = this.prepareCode(activeIssue) + if (!this.state.issueDetailsPending) { + UfixitForm = ufixitService.returnIssueForm(activeIssue) + code = this.prepareCode(activeIssue) + } return ( @@ -120,96 +142,103 @@ class UfixitModal extends React.Component { - - - - {ReactHtmlParser(this.props.t(`rule.desc.${activeIssue.scanRuleId}`), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, this.props.settings) })} - - - {showExample && - - - {ReactHtmlParser(this.props.t(`rule.example.${activeIssue.scanRuleId}`), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, this.props.settings) })} - - - } - - - - - + {this.state.issueDetailsPending && + + - {('module' !== activeContentItem.contentType) && - - {this.props.t('label.manual_resolution')} - {this.props.t('label.resolved_description')} - - {('2' == activeIssue.pending) ? - - : - - } + } + {!this.state.issueDetailsPending && + + + + {ReactHtmlParser(this.props.t(`rule.desc.${activeIssue.scanRuleId}`), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, this.props.settings) })} + + + {showExample && + + + {ReactHtmlParser(this.props.t(`rule.example.${activeIssue.scanRuleId}`), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, this.props.settings) })} - + } - - - - - - {('preview' === this.state.windowContents) ? - {this.props.t('label.preview')} - : - this.handleWindowToggle('preview')}> - {this.props.t('label.preview')} + + + + + + + {('module' !== activeContentItem.contentType) && + + {this.props.t('label.manual_resolution')} + {this.props.t('label.resolved_description')} + + {('2' == activeIssue.pending) ? + + : + + } + + + } + + + + + + {('preview' === this.state.windowContents) ? + {this.props.t('label.preview')} + : + this.handleWindowToggle('preview')}> + {this.props.t('label.preview')} + } + + + {('html' === this.state.windowContents) ? + {this.props.t('label.view_source')} + : + this.handleWindowToggle('html')}> + {this.props.t('label.view_source')} + } + + + + {('preview' === this.state.windowContents) && + + } - - - {('html' === this.state.windowContents) ? - {this.props.t('label.view_source')} - : - this.handleWindowToggle('html')}> - {this.props.t('label.view_source')} + {('html' === this.state.windowContents) && + } - - - - {('preview' === this.state.windowContents) && - - - } - {('html' === this.state.windowContents) && - + + + + {/* {this.props.t('label.source')} */} + {activeContentItem && + + {activeContentItem.contentType} + } iconPlacement="end"> + {activeContentItem.title} + + } - - - {/* {this.props.t('label.source')} */} - {activeContentItem && - - {activeContentItem.contentType} - } iconPlacement="end"> - {activeContentItem.title} - - - } - - - + + + } @@ -280,7 +309,12 @@ class UfixitModal extends React.Component { if (activeIssue.status) { activeIssue.status = false - activeIssue.newHtml = Html.toString(Html.removeClass(activeIssue.sourceHtml, 'phpally-ignore')) + activeIssue.newHtml = Html.toString( + Html.removeClass(activeIssue.sourceHtml, 'phpally-ignore') + ) + activeIssue.newHtml = Html.toString( + Html.addClass(activeIssue.newHtml, `udoit-${activeIssue.id}`) + ) } else { activeIssue.status = 2 @@ -296,7 +330,6 @@ class UfixitModal extends React.Component { if (response.data.issue) { const newIssue = { ...activeIssue, ...response.data.issue } - const newReport = response.data.report // update activeIssue newIssue.pending = false @@ -304,16 +337,39 @@ class UfixitModal extends React.Component { newIssue.sourceHtml = newIssue.newHtml newIssue.newHtml = '' // Get updated report - api.scanContent(newIssue.contentItemId) - .then((responseStr) => responseStr.json()) - .then((res) => { - // update activeIssue - this.props.handleActiveIssue(newIssue) - - this.props.handleIssueSave(newIssue, res.data) - }) - } - else { + api + .scanContent(newIssue.contentItemId) + .then((responseStr) => responseStr.json()) + .then((scanResponse) => { + // If we just unresolved the issue + if (!newIssue.status) { + // Loop through report + for (var issue of scanResponse.data.issues) { + if (issue.scanRuleId === newIssue.scanRuleId) { + // Get issue details + api.syncIssue(issue) + .then((responseStr) => responseStr.json()) + .then((res) => { + let issueDetails = res.data + + if (issueDetails.sourceHtml === newIssue.sourceHtml) { + newIssue.id = issueDetails.id + newIssue.sourceHtml = Html.toString( + Html.removeClass(newIssue.sourceHtml, `udoit-${activeIssue.id}`) + ) + newIssue.newHtml = '' + newIssue.previewHtml = issueDetails.previewHtml + } + }) + } + } + } + + this.props.handleActiveIssue(newIssue) + this.props.handleIssueSave(newIssue, scanResponse.data) + + }) + } else { activeIssue.pending = false this.props.handleActiveIssue(activeIssue) } @@ -432,6 +488,24 @@ class UfixitModal extends React.Component { clearMessages() { this.modalMessages = []; } + + syncIssue(issue) { + let api = new Api(this.props.settings) + + api.syncIssue(issue) + .then((response) => response.json()) + .then((response) => { + const newIssue = { ...issue, ...response.data } + + // set messages + response.messages.forEach((msg) => this.addMessage(msg)) + + if (newIssue.id === this.props.activeIssue.id) { + this.props.handleActiveIssue(newIssue) + this.setState({ issueDetailsPending: false }); + } + }) + } } export default UfixitModal; diff --git a/assets/js/Services/Api.js b/assets/js/Services/Api.js index 3ace069d9..a1943c630 100644 --- a/assets/js/Services/Api.js +++ b/assets/js/Services/Api.js @@ -6,6 +6,7 @@ export default class Api { getReport: '/api/courses/{course}/reports/{report}', getReportHistory: '/api/courses/{course}/reports', saveIssue: '/api/issues/{issue}/save', + syncIssue: '/api/issues/{issue}', resolveIssue: '/api/issues/{issue}/resolve', reviewFile: '/api/files/{file}/review', postFile: '/api/files/{file}/post', @@ -90,6 +91,21 @@ export default class Api { }) } + syncIssue(issue) { + const authToken = this.getAuthToken(); + + let url = `${this.apiUrl}${this.endpoints.syncIssue}`; + url = url.replace('{issue}', issue.id); + + return fetch(url, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'X-AUTH-TOKEN': authToken, + }, + }); + } + resolveIssue(issue) { const authToken = this.getAuthToken() diff --git a/src/Controller/IssuesController.php b/src/Controller/IssuesController.php index c003334ab..ce5f13cfc 100644 --- a/src/Controller/IssuesController.php +++ b/src/Controller/IssuesController.php @@ -21,6 +21,22 @@ public function __construct(ManagerRegistry $doctrine) $this->doctrine = $doctrine; } + #[Route(path: '/api/issues/{issue}', name: 'get_issue')] + public function getIssue(Issue $issue) + { + $apiResponse = new ApiResponse(); + + $apiResponse->setData([ + 'id' => $issue->getId(), + 'sourceHtml' => $issue->getHtml(), + 'previewHtml' => $issue->getPreviewHtml(), + 'metadata' => $issue->getMetadata(), + 'status' => $issue->getStatus(), + ]); + + return new JsonResponse($apiResponse); + } + // Save change to issue HTML to LMS #[Route('/api/issues/{issue}/save', name: 'save_issue')] public function saveIssue( diff --git a/src/Entity/Issue.php b/src/Entity/Issue.php index b8f5af2d9..1b1ed2c86 100644 --- a/src/Entity/Issue.php +++ b/src/Entity/Issue.php @@ -92,9 +92,6 @@ public function jsonSerialize(): array "contentItemId" => $this->contentItem->getId(), "scanRuleId" => $this->scanRuleId, "type" => $this->type, - "sourceHtml" => $this->html, - "previewHtml" => $this->previewHtml, - "metadata" => $this->metadata, ]; }