diff --git a/dmnverifierfrontend/src/main/resources/META-INF/resources/css/dmnEditorTabs.css b/dmnverifierfrontend/src/main/resources/META-INF/resources/css/dmnEditorTabs.css index 46662bc29899ee6234506aba7668b2048f090cb6..d55dd433eb4141314ee2a9bae2728549d0f21a6d 100644 --- a/dmnverifierfrontend/src/main/resources/META-INF/resources/css/dmnEditorTabs.css +++ b/dmnverifierfrontend/src/main/resources/META-INF/resources/css/dmnEditorTabs.css @@ -34,8 +34,9 @@ } .highlight { - background-color: darkred; - color: white; + background-color: darkred !important; + fill: darkred !important; + color: white !important; } .dmn-js-parent { diff --git a/dmnverifierfrontend/src/main/resources/META-INF/resources/index.html b/dmnverifierfrontend/src/main/resources/META-INF/resources/index.html index b70bff040ca9bd3fb42b44b1ea893cbca578524c..d6edbf53815805cf5a71f464f213717f13451289 100644 --- a/dmnverifierfrontend/src/main/resources/META-INF/resources/index.html +++ b/dmnverifierfrontend/src/main/resources/META-INF/resources/index.html @@ -75,6 +75,7 @@ <script src="js/dmnUpDownload.js" type="text/javascript"></script> <script src="js/dmnViewer.js" type="text/javascript"></script> <script src="js/dmnVerifier.js" type="text/javascript"></script> +<script src="js/dmnVerifierActions.js" type="text/javascript"></script> <script src="js/dmnCamundaApi.js" type="text/javascript"></script> </body> </html> diff --git a/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerificationResultSet..js b/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerificationResultSet..js index 999e64ea7eec9d898389d7904dc33eb28af335d5..83469d1ed6ef8ed050cb81a8daf34f7c36ce3150 100644 --- a/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerificationResultSet..js +++ b/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerificationResultSet..js @@ -23,26 +23,26 @@ * @property {number} size * @property {string} message * @property {string} verificationClassification - * @property {Array.<VerificationEntryElements>} elements - * @property {Array.<VerificationFixes>} verificationFixes + * @property {Array.<VerificationEntryElement>} elements + * @property {Array.<VerificationFix>} verificationFixes */ /** - * @typedef VerificationEntryElements + * @typedef VerificationEntryElement * @type {object} * @property {number} id * @property {Object.<string, number>} identifier */ /** - * @typedef VerificationFixes + * @typedef VerificationFix * @type {object} * @property {string} fixName - * @property {Array.<Actions>} actions + * @property {Array.<Action>} actions */ /** - * @typedef Actions + * @typedef Action * @type {object} * @property {number} id * @property {string} actionScope diff --git a/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerifier.js b/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerifier.js index bc7c9ac8b764276d3e0cb56f4ed4f954393869fd..da9cc8e433158bc2df8a09d72ccd3eb94729a57a 100644 --- a/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerifier.js +++ b/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerifier.js @@ -89,6 +89,11 @@ function cleanDmnVerifierRoot() { Reconnect verification backend</button> `)); } else { + $header.append($(` + <button class="clickable dmn-verifier-header-item" id="dmn-button-clean" + title="Request verifications" onClick="cleanHighlightFunction()"> + Clean</button> + `)); $header.append($verifierTypes); $verifierTypes.select2({ containerCssClass: "dmn-verifier-header-item dmn-verifier-select clickable", @@ -98,7 +103,7 @@ function cleanDmnVerifierRoot() { }, allowClear: true }); - // Add Button + // Add Button Verifications $header.append($(` <button class="clickable dmn-verifier-header-item" id="dmn-button-verify" title="Request verifications" onClick="checkVerifications()"> @@ -153,7 +158,6 @@ function getVerifications() { }, success: function (data) { console.log('successful dmn verification request:'); - console.log(data); verifierResults = data; // sort the list 1. classification, 2. size of entries verifierResults.verifier.sort(function ( @@ -210,6 +214,7 @@ function renderTypeOptions() { } function renderDmnVerifierOptions() { + cleanHighlightFunction(); $select.append($(`<option>Select a verifier</option>`)); let currentOpt = ''; let $curGroup; @@ -253,8 +258,7 @@ function renderDmnVerifierOptions() { /** * - * @param verifierSelect - * @Type option + * @param {Option} verifierSelect */ function renderVerifierResult(verifierSelect) { let verifier = findVerifierByName(verifierSelect.value); @@ -268,17 +272,17 @@ function renderVerifierResult(verifierSelect) { /** * - * @param verifier - * @Type VerifierResult + * @param {VerifierResult} verifier */ function renderVerifier(verifier) { + cleanHighlightFunction(); let $verifierContent = $('#dmn-verifier-content'); $verifierContent.empty(); $verifierContent.css('display', 'none'); let $verifierType = $(`<div class="verifier-type"></div>`); let $verifierEntries = $(`<div class="verifier-entries"></div>`); - // Add name and description of verifier + // name and description of verifier $verifierType.append($(` <div class="verifier-type-name"><h2>${verifier.type.niceName}</h2></div> `)); @@ -299,8 +303,7 @@ function renderVerifier(verifier) { /** * - * @param verificationEntry - * @Type VerificationEntry + * @param {VerificationEntry} verificationEntry */ function renderVerificationEntry(verificationEntry) { let $entryContainer = $(`<div class="verification-container"></div>`); @@ -310,20 +313,30 @@ function renderVerificationEntry(verificationEntry) { $entryContainer.append($(` <div class="verification-message">${verificationEntry.message}</div> `)); - // "dmn-${verificationEntry.verificationClassification}" let $fixButtons = $(`<div class="verification-container-fix-buttons"></div>`); - - /* - $fixButtons.append( - $(`<button class="verification-fix-button clickable">Show</button>`)); - $fixButtons.append( - $(`<button class="verification-fix-button clickable">Fix</button>`)); - $fixButtons.append( - $(`<button class="verification-fix-button clickable">Fix</button>`)); */ - $entryContainer.append($fixButtons); // TODO: render buttons + renderFixButtons($fixButtons, verificationEntry); + $entryContainer.append($fixButtons); return $entryContainer; } +/** + * + * @param $fixButtons + * @param {VerificationEntry} verificationEntry + */ +function renderFixButtons($fixButtons, verificationEntry) { + for (let i = 0; i < verificationEntry.verificationFixes.length; i++) { + let fix = verificationEntry.verificationFixes[i]; + let $fixButton = $(` + <button class="verification-fix-button clickable">${fix.fixName}</button> + `); + $fixButton.on('click', function () { + performVerificationFix(verificationEntry, fix); + }); + $fixButtons.append($fixButton); + } +} + /** * * @param verifierName diff --git a/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerifierActions.js b/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerifierActions.js new file mode 100644 index 0000000000000000000000000000000000000000..491e274e73841d7970b88fa19a277836606f1449 --- /dev/null +++ b/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerifierActions.js @@ -0,0 +1,134 @@ +/** + * + * @param {VerificationEntry} verificationEntry + * @param {VerificationFix} fix + */ +function performVerificationFix(verificationEntry, fix) { + console.log("FIX", fix); + cleanHighlightFunction(); + for (let i = 0; i < fix.actions.length; i++) { + switch (fix.actions[i].actionType) { + case 'SHOW': + performVerificationFixSHOW(verificationEntry, fix.actions[i]); + break; + case 'UPDATE': + // break; + case 'INSERT': + // break; + case 'DELETE': + // break; + default: + alert("Action not defined!"); + } + performHighlightFunction(); + } +} + +/** + * + * @param {VerificationEntry} verificationEntry + * @param {Action} fixAction + */ +function performVerificationFixSHOW(verificationEntry, fixAction) { + switch (fixAction.actionScope) { + case 'RULE': + fixSHOW_RULE(verificationEntry, fixAction); + break; + case 'INPUT_ENTRY': + fixSHOW_INPUT_ENTRY(verificationEntry, fixAction); + break; + case 'OUTPUT_ENTRY': + fixSHOW_OUTPUT_ENTRY(verificationEntry, fixAction); + break; + case 'INPUT_DATA': + fixSHOW_INPUT_DATA(verificationEntry, fixAction); + break; + case 'INPUT_COLUMN': + fixSHOW_INPUT_COLUMN(verificationEntry, fixAction); + break; + case 'OUTPUT_COLUMN': + fixSHOW_OUTPUT_COLUMN(verificationEntry, fixAction); + break; + case 'DECISION_TABLE': + fixSHOW_DECISION_TABLE(verificationEntry, fixAction); + break; + case 'DECISION': + fixSHOW_DECISION(verificationEntry, fixAction); + break; + default: + alert("ACTION: " + fix.actions[i].actionType + ' -> ' + + fix.actions[i].actionScope); // TODO + } +} + +/** + * + * @param {VerificationEntry} verificationEntry + * @param {Action} fixAction + */ +function fixSHOW_RULE(verificationEntry, fixAction) { + highlightRules(verificationEntry.elements); +} + +/** + * + * @param {VerificationEntry} verificationEntry + * @param {Action} fixAction + */ +function fixSHOW_INPUT_ENTRY(verificationEntry, fixAction) { + highlightDataEntries(verificationEntry.elements, 'inputEntryId'); +} + +/** + * + * @param {VerificationEntry} verificationEntry + * @param {Action} fixAction + */ +function fixSHOW_INPUT_DATA(verificationEntry, fixAction) { + highlightInputData(verificationEntry.elements); +} + +/** + * + * @param {VerificationEntry} verificationEntry + * @param {Action} fixAction + */ +function fixSHOW_OUTPUT_ENTRY(verificationEntry, fixAction) { + highlightDataEntries(verificationEntry.elements, 'outputEntryId'); +} + +/** + * + * @param {VerificationEntry} verificationEntry + * @param {Action} fixAction + */ +function fixSHOW_INPUT_COLUMN(verificationEntry, fixAction) { + highlightColumns(verificationEntry.elements, 'inputId'); +} + +/** + * + * @param {VerificationEntry} verificationEntry + * @param {Action} fixAction + */ +function fixSHOW_OUTPUT_COLUMN(verificationEntry, fixAction) { + highlightColumns(verificationEntry.elements, 'outputId'); +} + +/** + * + * @param {VerificationEntry} verificationEntry + * @param {Action} fixAction + */ +function fixSHOW_DECISION_TABLE(verificationEntry, fixAction) { + highlightDecision(verificationEntry.elements); +} + +/** + * + * @param {VerificationEntry} verificationEntry + * @param {Action} fixAction + */ +function fixSHOW_DECISION(verificationEntry, fixAction) { + highlightDecision(verificationEntry.elements); +} diff --git a/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnViewer.js b/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnViewer.js index f81817efa86b00cd04d8c94e4c35a551e7aec6fd..8df73002838c14827fe12929a7c0fc4730158e0a 100644 --- a/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnViewer.js +++ b/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnViewer.js @@ -19,12 +19,12 @@ $(document).ready(function () { var activeEditor = dmnModeler.getActiveViewer(); // access active editor components var canvas = activeEditor.get('canvas'); - // zoom to fit full viewport - canvas.zoom('fit-viewport'); } else { let dmnModelerHeight = $(window).height() / 2.5; $(".dmn-js-parent").css('height', dmnModelerHeight + 'px'); } + // zoom to fit full viewport + canvas.zoom('fit-viewport'); }); }); @@ -65,6 +65,8 @@ dmnModeler.on('views.changed', function (event) { `); $tabs.append(tab); }); + // render new highlighting elements + performHighlightFunction(); }); /** @@ -109,14 +111,147 @@ function openDiagram(dmnXML) { }); } -function addHighlightCss(ruleC) { - $('#tab-dec-' + ruleC.rules[0].decisionKey).click(); - ruleC.rules.forEach(function (rule) { - $('[data-row-id=' + rule.ruleId + ']').toggleClass('highlight'); +let renderHighlightFunction = []; + +function performHighlightFunction() { + for (let i = 0; i < renderHighlightFunction.length; i++) { + renderHighlightFunction[i].highlight(); + } +} + +function cleanHighlightFunction() { + for (let i = 0; i < renderHighlightFunction.length; i++) { + renderHighlightFunction[i].clean(); + } + renderHighlightFunction = []; +} + +function highlightSingleDecision(decisionId) { + // node + let $decisionNode = $( + '[data-element-id=' + decisionId + '] > g > rect'); + $decisionNode.css('fill', 'darkred'); + // tab + $('#tab-dec-' + decisionId).addClass('highlight'); +} + +function cleanSingleDecision(decisionId) { + // node + let $decisionNode = $( + '[data-element-id=' + decisionId + '] > g > rect'); + $decisionNode.css('fill', 'white'); + // tab + $('#tab-dec-' + decisionId).removeClass('highlight'); +} + +/** + * + * @param {Array<VerificationEntryElement>}elements + */ +function highlightRules(elements) { + renderHighlightFunction.push({ + highlight: function () { + highlightSingleDecision(elements[0].identifier['decisionId']); + elements.forEach(function (el) { + $('[data-row-id=' + el.identifier['ruleId'] + ']').addClass( + 'highlight'); + }); + }, + clean: function () { + cleanSingleDecision(elements[0].identifier['decisionId']); + elements.forEach(function (el) { + $('[data-row-id=' + el.identifier['ruleId'] + ']').removeClass( + 'highlight'); + }); + } }); } -function addHighlightCssSingleRule(id, decisionKey) { - $('#tab-dec-' + decisionKey).click(); - $('[data-row-id=' + id + ']').toggleClass('highlight'); +/** + * + * @param {Array<VerificationEntryElement>}elements + * @param {string} identifier + */ +function highlightColumns(elements, identifier) { + renderHighlightFunction.push({ + highlight: function () { + highlightSingleDecision(elements[0].identifier['decisionId']); + elements.forEach(function (el) { + $('[data-col-id=' + el.identifier[identifier] + ']').addClass( + 'highlight'); + }); + }, + clean: function () { + cleanSingleDecision(elements[0].identifier['decisionId']); + elements.forEach(function (el) { + $('[data-col-id=' + el.identifier[identifier] + ']').removeClass( + 'highlight'); + }); + } + }); +} + +/** + * + * @param {Array<VerificationEntryElement>}elements + * @param {string} identifier + */ +function highlightDataEntries(elements, identifier) { + renderHighlightFunction.push({ + highlight: function () { + highlightSingleDecision(elements[0].identifier['decisionId']); + elements.forEach(function (el) { + $('[data-element-id=' + el.identifier[identifier] + ']').addClass( + 'highlight'); + }); + }, + clean: function () { + cleanSingleDecision(elements[0].identifier['decisionId']); + elements.forEach(function (el) { + $('[data-element-id=' + el.identifier[identifier] + ']').removeClass( + 'highlight'); + }); + } + }); +} + +/** + * + * @param {Array<VerificationEntryElement>}elements + */ +function highlightInputData(elements) { + renderHighlightFunction.push({ + highlight: function () { + elements.forEach(function (el) { + $('[data-element-id=' + el.identifier['inputDataId'] + '] > g > rect') + .css('fill', 'darkred'); + }); + }, + clean: function () { + elements.forEach(function (el) { + $('[data-element-id=' + el.identifier['inputDataId'] + '] > g > rect') + .css('fill', 'white'); + }); + } + }); +} + +/** + * + * @param {Array<VerificationEntryElement>}elements + */ +function highlightDecision(elements) { + console.log(elements); + renderHighlightFunction.push({ + highlight: function () { + elements.forEach(function (el) { + highlightSingleDecision(el.identifier['decisionId']); + }); + }, + clean: function () { + elements.forEach(function (el) { + cleanSingleDecision(el.identifier['decisionId']); + }); + } + }); }