pipeline enhance for MI
This commit is contained in:
parent
eda91cc556
commit
f535387ac4
3 changed files with 521 additions and 482 deletions
|
@ -138,7 +138,7 @@ public class PipelineProcessor {
|
||||||
hasErrors = true;
|
hasErrors = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
outputFiles = newOutputFiles;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -177,11 +177,13 @@ public class PipelineProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logPrintStream.close();
|
logPrintStream.close();
|
||||||
|
outputFiles = newOutputFiles;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (hasErrors) {
|
if (hasErrors) {
|
||||||
logger.error("Errors occurred during processing. Log: {}", logStream.toString());
|
logger.error("Errors occurred during processing. Log: {}", logStream.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return outputFiles;
|
return outputFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,475 +1,496 @@
|
||||||
document.getElementById('validateButton').addEventListener('click', function(event) {
|
document.getElementById('validateButton').addEventListener('click', function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
validatePipeline();
|
validatePipeline();
|
||||||
});
|
|
||||||
function validatePipeline() {
|
|
||||||
let pipelineListItems = document.getElementById('pipelineList').children;
|
|
||||||
let isValid = true;
|
|
||||||
let containsAddPassword = false;
|
|
||||||
for (let i = 0; i < pipelineListItems.length - 1; i++) {
|
|
||||||
let currentOperation = pipelineListItems[i].querySelector('.operationName').textContent;
|
|
||||||
let nextOperation = pipelineListItems[i + 1].querySelector('.operationName').textContent;
|
|
||||||
if (currentOperation === '/add-password') {
|
|
||||||
containsAddPassword = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let currentOperationDescription = apiDocs[currentOperation]?.post?.description || "";
|
|
||||||
let nextOperationDescription = apiDocs[nextOperation]?.post?.description || "";
|
|
||||||
|
|
||||||
// Strip off 'ZIP-' prefix
|
|
||||||
currentOperationDescription = currentOperationDescription.replace("ZIP-", '');
|
|
||||||
nextOperationDescription = nextOperationDescription.replace("ZIP-", '');
|
|
||||||
|
|
||||||
let currentOperationOutput = currentOperationDescription.match(/Output:([A-Z\/]*)/)?.[1] || "";
|
|
||||||
let nextOperationInput = nextOperationDescription.match(/Input:([A-Z\/]*)/)?.[1] || "";
|
|
||||||
|
|
||||||
// Splitting in case of multiple possible output/input
|
|
||||||
let currentOperationOutputArr = currentOperationOutput.split('/');
|
|
||||||
let nextOperationInputArr = nextOperationInput.split('/');
|
|
||||||
|
|
||||||
if (currentOperationOutput !== 'ANY' && nextOperationInput !== 'ANY') {
|
|
||||||
let intersection = currentOperationOutputArr.filter(value => nextOperationInputArr.includes(value));
|
|
||||||
console.log(`Intersection: ${intersection}`);
|
|
||||||
|
|
||||||
if (intersection.length === 0) {
|
|
||||||
updateValidateButton(false);
|
|
||||||
isValid = false;
|
|
||||||
console.log(`Incompatible operations: The output of operation '${currentOperation}' (${currentOperationOutput}) is not compatible with the input of the following operation '${nextOperation}' (${nextOperationInput}).`);
|
|
||||||
alert(`Incompatible operations: The output of operation '${currentOperation}' (${currentOperationOutput}) is not compatible with the input of the following operation '${nextOperation}' (${nextOperationInput}).`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (containsAddPassword && pipelineListItems[pipelineListItems.length - 1].querySelector('.operationName').textContent !== '/add-password') {
|
|
||||||
updateValidateButton(false);
|
|
||||||
alert('The "add-password" operation should be at the end of the operations sequence. Please adjust the operations order.');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (isValid) {
|
|
||||||
console.log('Pipeline is valid');
|
|
||||||
// Continue with the pipeline operation
|
|
||||||
} else {
|
|
||||||
console.error('Pipeline is not valid');
|
|
||||||
// Stop operation, maybe display an error to the user
|
|
||||||
}
|
|
||||||
updateValidateButton(isValid);
|
|
||||||
return isValid;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateValidateButton(isValid) {
|
|
||||||
var validateButton = document.getElementById('validateButton');
|
|
||||||
if (isValid) {
|
|
||||||
validateButton.classList.remove('btn-danger');
|
|
||||||
validateButton.classList.add('btn-success');
|
|
||||||
} else {
|
|
||||||
validateButton.classList.remove('btn-success');
|
|
||||||
validateButton.classList.add('btn-danger');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
document.getElementById('submitConfigBtn').addEventListener('click', function() {
|
|
||||||
|
|
||||||
if (validatePipeline() === false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let selectedOperation = document.getElementById('operationsDropdown').value;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var pipelineName = document.getElementById('pipelineName').value;
|
|
||||||
let pipelineList = document.getElementById('pipelineList').children;
|
|
||||||
let pipelineConfig = {
|
|
||||||
"name": pipelineName,
|
|
||||||
"pipeline": [],
|
|
||||||
"_examples": {
|
|
||||||
"outputDir": "{outputFolder}/{folderName}",
|
|
||||||
"outputFileName": "{filename}-{pipelineName}-{date}-{time}"
|
|
||||||
},
|
|
||||||
"outputDir": "httpWebRequest",
|
|
||||||
"outputFileName": "{filename}"
|
|
||||||
};
|
|
||||||
|
|
||||||
for (let i = 0; i < pipelineList.length; i++) {
|
|
||||||
let operationName = pipelineList[i].querySelector('.operationName').textContent;
|
|
||||||
let parameters = operationSettings[operationName] || {};
|
|
||||||
|
|
||||||
pipelineConfig.pipeline.push({
|
|
||||||
"operation": operationName,
|
|
||||||
"parameters": parameters
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let pipelineConfigJson = JSON.stringify(pipelineConfig, null, 2);
|
|
||||||
|
|
||||||
let formData = new FormData();
|
|
||||||
|
|
||||||
let fileInput = document.getElementById('fileInput-input');
|
|
||||||
let files = fileInput.files;
|
|
||||||
|
|
||||||
for (let i = 0; i < files.length; i++) {
|
|
||||||
console.log("files[i]", files[i].name);
|
|
||||||
formData.append('fileInput', files[i], files[i].name);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("pipelineConfigJson", pipelineConfigJson);
|
|
||||||
formData.append('json', pipelineConfigJson);
|
|
||||||
console.log("formData", formData);
|
|
||||||
|
|
||||||
fetch('api/v1/pipeline/handleData', {
|
|
||||||
method: 'POST',
|
|
||||||
body: formData
|
|
||||||
})
|
|
||||||
.then(response => {
|
|
||||||
// Save the response to use it later
|
|
||||||
const responseToUseLater = response;
|
|
||||||
|
|
||||||
return response.blob().then(blob => {
|
|
||||||
let url = window.URL.createObjectURL(blob);
|
|
||||||
let a = document.createElement('a');
|
|
||||||
a.href = url;
|
|
||||||
|
|
||||||
// Use responseToUseLater instead of response
|
|
||||||
const contentDisposition = responseToUseLater.headers.get('Content-Disposition');
|
|
||||||
let filename = 'download';
|
|
||||||
if (contentDisposition && contentDisposition.indexOf('attachment') !== -1) {
|
|
||||||
filename = decodeURIComponent(contentDisposition.split('filename=')[1].replace(/"/g, '')).trim();
|
|
||||||
}
|
|
||||||
a.download = filename;
|
|
||||||
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
a.remove();
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error('Error:', error);
|
|
||||||
});
|
});
|
||||||
|
function validatePipeline() {
|
||||||
});
|
let pipelineListItems = document.getElementById('pipelineList').children;
|
||||||
|
let isValid = true;
|
||||||
let apiDocs = {};
|
let containsAddPassword = false;
|
||||||
let apiSchemas = {};
|
for (let i = 0; i < pipelineListItems.length - 1; i++) {
|
||||||
let operationSettings = {};
|
let currentOperation = pipelineListItems[i].querySelector('.operationName').textContent;
|
||||||
|
let nextOperation = pipelineListItems[i + 1].querySelector('.operationName').textContent;
|
||||||
fetch('v1/api-docs')
|
if (currentOperation === '/add-password') {
|
||||||
.then(response => response.json())
|
containsAddPassword = true;
|
||||||
.then(data => {
|
|
||||||
|
|
||||||
apiDocs = data.paths;
|
|
||||||
apiSchemas = data.components.schemas;
|
|
||||||
let operationsDropdown = document.getElementById('operationsDropdown');
|
|
||||||
const ignoreOperations = ["/api/v1/pipeline/handleData", "/api/v1/pipeline/operationToIgnore"]; // Add the operations you want to ignore here
|
|
||||||
|
|
||||||
operationsDropdown.innerHTML = '';
|
|
||||||
|
|
||||||
let operationsByTag = {};
|
|
||||||
|
|
||||||
// Group operations by tags
|
|
||||||
Object.keys(data.paths).forEach(operationPath => {
|
|
||||||
let operation = data.paths[operationPath].post;
|
|
||||||
if(!operation || !operation.description) {
|
|
||||||
console.log(operationPath);
|
|
||||||
}
|
}
|
||||||
if (operation && !ignoreOperations.includes(operationPath) && !operation.description.includes("Type:MISO")) {
|
|
||||||
let operationTag = operation.tags[0]; // This assumes each operation has exactly one tag
|
let currentOperationDescription = apiDocs[currentOperation]?.post?.description || "";
|
||||||
if (!operationsByTag[operationTag]) {
|
let nextOperationDescription = apiDocs[nextOperation]?.post?.description || "";
|
||||||
operationsByTag[operationTag] = [];
|
|
||||||
|
// Strip off 'ZIP-' prefix
|
||||||
|
currentOperationDescription = currentOperationDescription.replace("ZIP-", '');
|
||||||
|
nextOperationDescription = nextOperationDescription.replace("ZIP-", '');
|
||||||
|
|
||||||
|
let currentOperationOutput = currentOperationDescription.match(/Output:([A-Z\/]*)/)?.[1] || "";
|
||||||
|
let nextOperationInput = nextOperationDescription.match(/Input:([A-Z\/]*)/)?.[1] || "";
|
||||||
|
|
||||||
|
// Splitting in case of multiple possible output/input
|
||||||
|
let currentOperationOutputArr = currentOperationOutput.split('/');
|
||||||
|
let nextOperationInputArr = nextOperationInput.split('/');
|
||||||
|
|
||||||
|
if (currentOperationOutput !== 'ANY' && nextOperationInput !== 'ANY') {
|
||||||
|
let intersection = currentOperationOutputArr.filter(value => nextOperationInputArr.includes(value));
|
||||||
|
console.log(`Intersection: ${intersection}`);
|
||||||
|
|
||||||
|
if (intersection.length === 0) {
|
||||||
|
updateValidateButton(false);
|
||||||
|
isValid = false;
|
||||||
|
console.log(`Incompatible operations: The output of operation '${currentOperation}' (${currentOperationOutput}) is not compatible with the input of the following operation '${nextOperation}' (${nextOperationInput}).`);
|
||||||
|
alert(`Incompatible operations: The output of operation '${currentOperation}' (${currentOperationOutput}) is not compatible with the input of the following operation '${nextOperation}' (${nextOperationInput}).`);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
operationsByTag[operationTag].push(operationPath);
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
// Specify the order of tags
|
if (containsAddPassword && pipelineListItems[pipelineListItems.length - 1].querySelector('.operationName').textContent !== '/add-password') {
|
||||||
let tagOrder = ["General", "Security", "Convert", "Misc", "Filter"];
|
updateValidateButton(false);
|
||||||
|
alert('The "add-password" operation should be at the end of the operations sequence. Please adjust the operations order.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (isValid) {
|
||||||
|
console.log('Pipeline is valid');
|
||||||
|
// Continue with the pipeline operation
|
||||||
|
} else {
|
||||||
|
console.error('Pipeline is not valid');
|
||||||
|
// Stop operation, maybe display an error to the user
|
||||||
|
}
|
||||||
|
updateValidateButton(isValid);
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
|
||||||
// Create dropdown options
|
function updateValidateButton(isValid) {
|
||||||
tagOrder.forEach(tag => {
|
var validateButton = document.getElementById('validateButton');
|
||||||
if (operationsByTag[tag]) {
|
if (isValid) {
|
||||||
let group = document.createElement('optgroup');
|
validateButton.classList.remove('btn-danger');
|
||||||
group.label = tag;
|
validateButton.classList.add('btn-success');
|
||||||
|
} else {
|
||||||
operationsByTag[tag].forEach(operationPath => {
|
validateButton.classList.remove('btn-success');
|
||||||
let option = document.createElement('option');
|
validateButton.classList.add('btn-danger');
|
||||||
|
}
|
||||||
let operationPathDisplay = operationPath
|
|
||||||
operationPathDisplay = operationPath.replace(new RegExp("api/v1/" + tag.toLowerCase() + "/", 'i'), "");
|
|
||||||
|
|
||||||
|
|
||||||
if(operationPath.includes("/convert")){
|
|
||||||
operationPathDisplay = operationPathDisplay.replace(/^\//, '').replaceAll("/", " to ");
|
|
||||||
} else {
|
|
||||||
operationPathDisplay = operationPathDisplay.replace(/\//g, ''); // Remove slashes
|
|
||||||
}
|
|
||||||
operationPathDisplay = operationPathDisplay.replaceAll(" ","-");
|
|
||||||
option.textContent = operationPathDisplay;
|
|
||||||
option.value = operationPath; // Keep the value with slashes for querying
|
|
||||||
group.appendChild(option);
|
|
||||||
});
|
|
||||||
|
|
||||||
operationsDropdown.appendChild(group);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
document.getElementById('addOperationBtn').addEventListener('click', function() {
|
|
||||||
let selectedOperation = document.getElementById('operationsDropdown').value;
|
|
||||||
let pipelineList = document.getElementById('pipelineList');
|
|
||||||
|
|
||||||
let listItem = document.createElement('li');
|
|
||||||
listItem.className = "list-group-item";
|
|
||||||
let hasSettings = false;
|
|
||||||
if (apiDocs[selectedOperation] && apiDocs[selectedOperation].post) {
|
|
||||||
const postMethod = apiDocs[selectedOperation].post;
|
|
||||||
|
|
||||||
// Check if parameters exist
|
|
||||||
if (postMethod.parameters && postMethod.parameters.length > 0) {
|
|
||||||
hasSettings = true;
|
|
||||||
} else if (postMethod.requestBody && postMethod.requestBody.content['multipart/form-data']) {
|
|
||||||
// Extract the reference key
|
|
||||||
const refKey = postMethod.requestBody.content['multipart/form-data'].schema['$ref'].split('/').pop();
|
|
||||||
// Check if the referenced schema exists and has properties
|
|
||||||
if (apiSchemas[refKey] && Object.keys(apiSchemas[refKey].properties).length > 0) {
|
|
||||||
hasSettings = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
listItem.innerHTML = `
|
document.getElementById('submitConfigBtn').addEventListener('click', function() {
|
||||||
<div class="d-flex justify-content-between align-items-center w-100">
|
|
||||||
<div class="operationName">${selectedOperation}</div>
|
|
||||||
<div class="arrows d-flex">
|
|
||||||
<button class="btn btn-secondary move-up ms-1"><span>↑</span></button>
|
|
||||||
<button class="btn btn-secondary move-down ms-1"><span>↓</span></button>
|
|
||||||
<button class="btn ${hasSettings ? 'btn-warning' : 'btn-secondary'} pipelineSettings ms-1" ${hasSettings ? "" : "disabled"}>
|
|
||||||
<span style="color: ${hasSettings ? "white" : "grey"};">⚙️</span>
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-danger remove ms-1"><span>X</span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
|
if (validatePipeline() === false) {
|
||||||
pipelineList.appendChild(listItem);
|
return;
|
||||||
|
|
||||||
listItem.querySelector('.move-up').addEventListener('click', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
if (listItem.previousElementSibling) {
|
|
||||||
pipelineList.insertBefore(listItem, listItem.previousElementSibling);
|
|
||||||
}
|
}
|
||||||
});
|
let selectedOperation = document.getElementById('operationsDropdown').value;
|
||||||
|
|
||||||
listItem.querySelector('.move-down').addEventListener('click', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
if (listItem.nextElementSibling) {
|
var pipelineName = document.getElementById('pipelineName').value;
|
||||||
pipelineList.insertBefore(listItem.nextElementSibling, listItem);
|
let pipelineList = document.getElementById('pipelineList').children;
|
||||||
|
let pipelineConfig = {
|
||||||
|
"name": pipelineName,
|
||||||
|
"pipeline": [],
|
||||||
|
"_examples": {
|
||||||
|
"outputDir": "{outputFolder}/{folderName}",
|
||||||
|
"outputFileName": "{filename}-{pipelineName}-{date}-{time}"
|
||||||
|
},
|
||||||
|
"outputDir": "httpWebRequest",
|
||||||
|
"outputFileName": "{filename}"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let i = 0; i < pipelineList.length; i++) {
|
||||||
|
let operationName = pipelineList[i].querySelector('.operationName').textContent;
|
||||||
|
let parameters = operationSettings[operationName] || {};
|
||||||
|
|
||||||
|
pipelineConfig.pipeline.push({
|
||||||
|
"operation": operationName,
|
||||||
|
"parameters": parameters
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
listItem.querySelector('.remove').addEventListener('click', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
pipelineList.removeChild(listItem);
|
|
||||||
hideOrShowPipelineHeader();
|
|
||||||
});
|
|
||||||
|
|
||||||
listItem.querySelector('.pipelineSettings').addEventListener('click', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
showpipelineSettingsModal(selectedOperation);
|
|
||||||
hideOrShowPipelineHeader();
|
|
||||||
});
|
|
||||||
|
|
||||||
function showpipelineSettingsModal(operation) {
|
|
||||||
let pipelineSettingsModal = document.getElementById('pipelineSettingsModal');
|
|
||||||
let pipelineSettingsContent = document.getElementById('pipelineSettingsContent');
|
|
||||||
let operationData = apiDocs[operation].post.parameters || [];
|
|
||||||
|
|
||||||
// Resolve the $ref reference to get actual schema properties
|
|
||||||
let refKey = apiDocs[operation].post.requestBody.content['multipart/form-data'].schema['$ref'].split('/').pop();
|
|
||||||
let requestBodyData = apiSchemas[refKey].properties || {};
|
|
||||||
|
|
||||||
// Combine operationData and requestBodyData into a single array
|
|
||||||
operationData = operationData.concat(Object.keys(requestBodyData).map(key => ({
|
|
||||||
name: key,
|
|
||||||
schema: requestBodyData[key]
|
|
||||||
})));
|
|
||||||
|
|
||||||
pipelineSettingsContent.innerHTML = '';
|
|
||||||
|
|
||||||
operationData.forEach(parameter => {
|
|
||||||
// If the parameter name is 'fileInput', return early to skip the rest of this iteration
|
|
||||||
if (parameter.name === 'fileInput') return;
|
|
||||||
|
|
||||||
let parameterDiv = document.createElement('div');
|
|
||||||
parameterDiv.className = "mb-3";
|
|
||||||
|
|
||||||
let parameterLabel = document.createElement('label');
|
|
||||||
parameterLabel.textContent = `${parameter.name} (${parameter.schema.type}): `;
|
|
||||||
parameterLabel.title = parameter.schema.description;
|
|
||||||
parameterLabel.setAttribute('for', parameter.name);
|
|
||||||
parameterDiv.appendChild(parameterLabel);
|
|
||||||
|
|
||||||
let defaultValue = parameter.schema.example;
|
|
||||||
if (defaultValue === undefined) defaultValue = parameter.schema.default;
|
|
||||||
|
|
||||||
let parameterInput;
|
|
||||||
|
|
||||||
// check if enum exists in schema
|
|
||||||
if (parameter.schema.enum) {
|
|
||||||
// if enum exists, create a select element
|
|
||||||
parameterInput = document.createElement('select');
|
|
||||||
parameterInput.className = "form-control";
|
|
||||||
|
|
||||||
// iterate over each enum value and create an option for it
|
let pipelineConfigJson = JSON.stringify(pipelineConfig, null, 2);
|
||||||
parameter.schema.enum.forEach(value => {
|
|
||||||
let option = document.createElement('option');
|
let formData = new FormData();
|
||||||
option.value = value;
|
|
||||||
option.text = value;
|
let fileInput = document.getElementById('fileInput-input');
|
||||||
parameterInput.appendChild(option);
|
let files = fileInput.files;
|
||||||
|
|
||||||
|
for (let i = 0; i < files.length; i++) {
|
||||||
|
console.log("files[i]", files[i].name);
|
||||||
|
formData.append('fileInput', files[i], files[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("pipelineConfigJson", pipelineConfigJson);
|
||||||
|
formData.append('json', pipelineConfigJson);
|
||||||
|
console.log("formData", formData);
|
||||||
|
|
||||||
|
fetch('api/v1/pipeline/handleData', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
// Save the response to use it later
|
||||||
|
const responseToUseLater = response;
|
||||||
|
|
||||||
|
return response.blob().then(blob => {
|
||||||
|
let url = window.URL.createObjectURL(blob);
|
||||||
|
let a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
|
||||||
|
// Use responseToUseLater instead of response
|
||||||
|
const contentDisposition = responseToUseLater.headers.get('Content-Disposition');
|
||||||
|
let filename = 'download';
|
||||||
|
if (contentDisposition && contentDisposition.indexOf('attachment') !== -1) {
|
||||||
|
filename = decodeURIComponent(contentDisposition.split('filename=')[1].replace(/"/g, '')).trim();
|
||||||
|
}
|
||||||
|
a.download = filename;
|
||||||
|
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
a.remove();
|
||||||
});
|
});
|
||||||
} else {
|
})
|
||||||
// switch-case statement for handling non-enum types
|
.catch((error) => {
|
||||||
switch (parameter.schema.type) {
|
console.error('Error:', error);
|
||||||
case 'string':
|
});
|
||||||
if (parameter.schema.format === 'binary') {
|
|
||||||
// This is a file input
|
|
||||||
|
|
||||||
//parameterInput = document.createElement('input');
|
});
|
||||||
//parameterInput.type = 'file';
|
|
||||||
//parameterInput.className = "form-control";
|
|
||||||
|
|
||||||
parameterInput = document.createElement('input');
|
let apiDocs = {};
|
||||||
parameterInput.type = 'text';
|
let apiSchemas = {};
|
||||||
parameterInput.className = "form-control";
|
let operationSettings = {};
|
||||||
parameterInput.value = "FileInputPathToBeInputtedManuallyOffline";
|
|
||||||
|
fetch('v1/api-docs')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
|
||||||
|
apiDocs = data.paths;
|
||||||
|
apiSchemas = data.components.schemas;
|
||||||
|
let operationsDropdown = document.getElementById('operationsDropdown');
|
||||||
|
const ignoreOperations = ["/api/v1/pipeline/handleData", "/api/v1/pipeline/operationToIgnore"]; // Add the operations you want to ignore here
|
||||||
|
|
||||||
|
operationsDropdown.innerHTML = '';
|
||||||
|
|
||||||
|
let operationsByTag = {};
|
||||||
|
|
||||||
|
// Group operations by tags
|
||||||
|
Object.keys(data.paths).forEach(operationPath => {
|
||||||
|
let operation = data.paths[operationPath].post;
|
||||||
|
if (!operation || !operation.description) {
|
||||||
|
console.log(operationPath);
|
||||||
|
}
|
||||||
|
//!operation.description.includes("Type:MISO")
|
||||||
|
if (operation && !ignoreOperations.includes(operationPath)) {
|
||||||
|
let operationTag = operation.tags[0]; // This assumes each operation has exactly one tag
|
||||||
|
if (!operationsByTag[operationTag]) {
|
||||||
|
operationsByTag[operationTag] = [];
|
||||||
|
}
|
||||||
|
operationsByTag[operationTag].push(operationPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Specify the order of tags
|
||||||
|
let tagOrder = ["General", "Security", "Convert", "Misc", "Filter"];
|
||||||
|
|
||||||
|
// Create dropdown options
|
||||||
|
tagOrder.forEach(tag => {
|
||||||
|
if (operationsByTag[tag]) {
|
||||||
|
let group = document.createElement('optgroup');
|
||||||
|
group.label = tag;
|
||||||
|
|
||||||
|
operationsByTag[tag].forEach(operationPath => {
|
||||||
|
let option = document.createElement('option');
|
||||||
|
|
||||||
|
let operationPathDisplay = operationPath
|
||||||
|
operationPathDisplay = operationPath.replace(new RegExp("api/v1/" + tag.toLowerCase() + "/", 'i'), "");
|
||||||
|
|
||||||
|
|
||||||
|
if (operationPath.includes("/convert")) {
|
||||||
|
operationPathDisplay = operationPathDisplay.replace(/^\//, '').replaceAll("/", " to ");
|
||||||
} else {
|
} else {
|
||||||
|
operationPathDisplay = operationPathDisplay.replace(/\//g, ''); // Remove slashes
|
||||||
|
}
|
||||||
|
operationPathDisplay = operationPathDisplay.replaceAll(" ", "-");
|
||||||
|
option.textContent = operationPathDisplay;
|
||||||
|
option.value = operationPath; // Keep the value with slashes for querying
|
||||||
|
group.appendChild(option);
|
||||||
|
});
|
||||||
|
|
||||||
|
operationsDropdown.appendChild(group);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
document.getElementById('addOperationBtn').addEventListener('click', function() {
|
||||||
|
let selectedOperation = document.getElementById('operationsDropdown').value;
|
||||||
|
let pipelineList = document.getElementById('pipelineList');
|
||||||
|
|
||||||
|
let listItem = document.createElement('li');
|
||||||
|
listItem.className = "list-group-item";
|
||||||
|
let hasSettings = false;
|
||||||
|
if (apiDocs[selectedOperation] && apiDocs[selectedOperation].post) {
|
||||||
|
const postMethod = apiDocs[selectedOperation].post;
|
||||||
|
|
||||||
|
// Check if parameters exist
|
||||||
|
if (postMethod.parameters && postMethod.parameters.length > 0) {
|
||||||
|
hasSettings = true;
|
||||||
|
} else if (postMethod.requestBody && postMethod.requestBody.content['multipart/form-data']) {
|
||||||
|
// Extract the reference key
|
||||||
|
const refKey = postMethod.requestBody.content['multipart/form-data'].schema['$ref'].split('/').pop();
|
||||||
|
// Check if the referenced schema exists and has properties
|
||||||
|
if (apiSchemas[refKey] && Object.keys(apiSchemas[refKey].properties).length > 0) {
|
||||||
|
hasSettings = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
listItem.innerHTML = `
|
||||||
|
<div class="d-flex justify-content-between align-items-center w-100">
|
||||||
|
<div class="operationName">${selectedOperation}</div>
|
||||||
|
<div class="arrows d-flex">
|
||||||
|
<button class="btn btn-secondary move-up ms-1"><span>↑</span></button>
|
||||||
|
<button class="btn btn-secondary move-down ms-1"><span>↓</span></button>
|
||||||
|
<button class="btn ${hasSettings ? 'btn-warning' : 'btn-secondary'} pipelineSettings ms-1" ${hasSettings ? "" : "disabled"}>
|
||||||
|
<span style="color: ${hasSettings ? "white" : "grey"};">⚙️</span>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-danger remove ms-1"><span>X</span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
|
||||||
|
pipelineList.appendChild(listItem);
|
||||||
|
|
||||||
|
listItem.querySelector('.move-up').addEventListener('click', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
if (listItem.previousElementSibling) {
|
||||||
|
pipelineList.insertBefore(listItem, listItem.previousElementSibling);
|
||||||
|
updateConfigInDropdown();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
listItem.querySelector('.move-down').addEventListener('click', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
if (listItem.nextElementSibling) {
|
||||||
|
pipelineList.insertBefore(listItem.nextElementSibling, listItem);
|
||||||
|
updateConfigInDropdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
listItem.querySelector('.remove').addEventListener('click', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
pipelineList.removeChild(listItem);
|
||||||
|
hideOrShowPipelineHeader();
|
||||||
|
updateConfigInDropdown();
|
||||||
|
});
|
||||||
|
|
||||||
|
listItem.querySelector('.pipelineSettings').addEventListener('click', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
showpipelineSettingsModal(selectedOperation);
|
||||||
|
hideOrShowPipelineHeader();
|
||||||
|
});
|
||||||
|
|
||||||
|
function showpipelineSettingsModal(operation) {
|
||||||
|
let pipelineSettingsModal = document.getElementById('pipelineSettingsModal');
|
||||||
|
let pipelineSettingsContent = document.getElementById('pipelineSettingsContent');
|
||||||
|
let operationData = apiDocs[operation].post.parameters || [];
|
||||||
|
|
||||||
|
// Resolve the $ref reference to get actual schema properties
|
||||||
|
let refKey = apiDocs[operation].post.requestBody.content['multipart/form-data'].schema['$ref'].split('/').pop();
|
||||||
|
let requestBodyData = apiSchemas[refKey].properties || {};
|
||||||
|
|
||||||
|
// Combine operationData and requestBodyData into a single array
|
||||||
|
operationData = operationData.concat(Object.keys(requestBodyData).map(key => ({
|
||||||
|
name: key,
|
||||||
|
schema: requestBodyData[key]
|
||||||
|
})));
|
||||||
|
|
||||||
|
pipelineSettingsContent.innerHTML = '';
|
||||||
|
|
||||||
|
operationData.forEach(parameter => {
|
||||||
|
// If the parameter name is 'fileInput', return early to skip the rest of this iteration
|
||||||
|
if (parameter.name === 'fileInput') return;
|
||||||
|
|
||||||
|
let parameterDiv = document.createElement('div');
|
||||||
|
parameterDiv.className = "mb-3";
|
||||||
|
|
||||||
|
let parameterLabel = document.createElement('label');
|
||||||
|
parameterLabel.textContent = `${parameter.name} (${parameter.schema.type}): `;
|
||||||
|
parameterLabel.title = parameter.schema.description;
|
||||||
|
parameterLabel.setAttribute('for', parameter.name);
|
||||||
|
parameterDiv.appendChild(parameterLabel);
|
||||||
|
|
||||||
|
let defaultValue = parameter.schema.example;
|
||||||
|
if (defaultValue === undefined) defaultValue = parameter.schema.default;
|
||||||
|
|
||||||
|
let parameterInput;
|
||||||
|
|
||||||
|
// check if enum exists in schema
|
||||||
|
if (parameter.schema.enum) {
|
||||||
|
// if enum exists, create a select element
|
||||||
|
parameterInput = document.createElement('select');
|
||||||
|
parameterInput.className = "form-control";
|
||||||
|
|
||||||
|
// iterate over each enum value and create an option for it
|
||||||
|
parameter.schema.enum.forEach(value => {
|
||||||
|
let option = document.createElement('option');
|
||||||
|
option.value = value;
|
||||||
|
option.text = value;
|
||||||
|
parameterInput.appendChild(option);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// switch-case statement for handling non-enum types
|
||||||
|
switch (parameter.schema.type) {
|
||||||
|
case 'string':
|
||||||
|
if (parameter.schema.format === 'binary') {
|
||||||
|
// This is a file input
|
||||||
|
|
||||||
|
//parameterInput = document.createElement('input');
|
||||||
|
//parameterInput.type = 'file';
|
||||||
|
//parameterInput.className = "form-control";
|
||||||
|
|
||||||
|
parameterInput = document.createElement('input');
|
||||||
|
parameterInput.type = 'text';
|
||||||
|
parameterInput.className = "form-control";
|
||||||
|
parameterInput.value = "FileInputPathToBeInputtedManuallyOffline";
|
||||||
|
} else {
|
||||||
|
parameterInput = document.createElement('input');
|
||||||
|
parameterInput.type = 'text';
|
||||||
|
parameterInput.className = "form-control";
|
||||||
|
if (defaultValue !== undefined) parameterInput.value = defaultValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'number':
|
||||||
|
case 'integer':
|
||||||
|
parameterInput = document.createElement('input');
|
||||||
|
parameterInput.type = 'number';
|
||||||
|
parameterInput.className = "form-control";
|
||||||
|
if (defaultValue !== undefined) parameterInput.value = defaultValue;
|
||||||
|
break;
|
||||||
|
case 'boolean':
|
||||||
|
parameterInput = document.createElement('input');
|
||||||
|
parameterInput.type = 'checkbox';
|
||||||
|
if (defaultValue === true) parameterInput.checked = true;
|
||||||
|
break;
|
||||||
|
case 'array':
|
||||||
|
case 'object':
|
||||||
|
parameterInput = document.createElement('textarea');
|
||||||
|
parameterInput.placeholder = `Enter a JSON formatted ${parameter.schema.type}`;
|
||||||
|
parameterInput.className = "form-control";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
parameterInput = document.createElement('input');
|
parameterInput = document.createElement('input');
|
||||||
parameterInput.type = 'text';
|
parameterInput.type = 'text';
|
||||||
parameterInput.className = "form-control";
|
parameterInput.className = "form-control";
|
||||||
if (defaultValue !== undefined) parameterInput.value = defaultValue;
|
if (defaultValue !== undefined) parameterInput.value = defaultValue;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case 'number':
|
|
||||||
case 'integer':
|
|
||||||
parameterInput = document.createElement('input');
|
|
||||||
parameterInput.type = 'number';
|
|
||||||
parameterInput.className = "form-control";
|
|
||||||
if (defaultValue !== undefined) parameterInput.value = defaultValue;
|
|
||||||
break;
|
|
||||||
case 'boolean':
|
|
||||||
parameterInput = document.createElement('input');
|
|
||||||
parameterInput.type = 'checkbox';
|
|
||||||
if (defaultValue === true) parameterInput.checked = true;
|
|
||||||
break;
|
|
||||||
case 'array':
|
|
||||||
case 'object':
|
|
||||||
parameterInput = document.createElement('textarea');
|
|
||||||
parameterInput.placeholder = `Enter a JSON formatted ${parameter.schema.type}`;
|
|
||||||
parameterInput.className = "form-control";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
parameterInput = document.createElement('input');
|
|
||||||
parameterInput.type = 'text';
|
|
||||||
parameterInput.className = "form-control";
|
|
||||||
if (defaultValue !== undefined) parameterInput.value = defaultValue;
|
|
||||||
}
|
}
|
||||||
}
|
parameterInput.id = parameter.name;
|
||||||
parameterInput.id = parameter.name;
|
|
||||||
|
|
||||||
console.log("defaultValue", defaultValue);
|
console.log("defaultValue", defaultValue);
|
||||||
console.log("parameterInput", parameterInput);
|
console.log("parameterInput", parameterInput);
|
||||||
if (operationSettings[operation] && operationSettings[operation][parameter.name] !== undefined) {
|
if (operationSettings[operation] && operationSettings[operation][parameter.name] !== undefined) {
|
||||||
let savedValue = operationSettings[operation][parameter.name];
|
let savedValue = operationSettings[operation][parameter.name];
|
||||||
|
|
||||||
switch (parameter.schema.type) {
|
|
||||||
case 'number':
|
|
||||||
case 'integer':
|
|
||||||
parameterInput.value = savedValue.toString();
|
|
||||||
break;
|
|
||||||
case 'boolean':
|
|
||||||
parameterInput.checked = savedValue;
|
|
||||||
break;
|
|
||||||
case 'array':
|
|
||||||
case 'object':
|
|
||||||
parameterInput.value = JSON.stringify(savedValue);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
parameterInput.value = savedValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log("parameterInput2", parameterInput);
|
|
||||||
parameterDiv.appendChild(parameterInput);
|
|
||||||
|
|
||||||
pipelineSettingsContent.appendChild(parameterDiv);
|
|
||||||
});
|
|
||||||
|
|
||||||
let saveButton = document.createElement('button');
|
|
||||||
saveButton.textContent = "Save Settings";
|
|
||||||
saveButton.className = "btn btn-primary";
|
|
||||||
saveButton.addEventListener('click', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
let settings = {};
|
|
||||||
operationData.forEach(parameter => {
|
|
||||||
if(parameter.name !== "fileInput"){
|
|
||||||
let value = document.getElementById(parameter.name).value;
|
|
||||||
switch (parameter.schema.type) {
|
switch (parameter.schema.type) {
|
||||||
case 'number':
|
case 'number':
|
||||||
case 'integer':
|
case 'integer':
|
||||||
settings[parameter.name] = Number(value);
|
parameterInput.value = savedValue.toString();
|
||||||
break;
|
break;
|
||||||
case 'boolean':
|
case 'boolean':
|
||||||
settings[parameter.name] = document.getElementById(parameter.name).checked;
|
parameterInput.checked = savedValue;
|
||||||
break;
|
break;
|
||||||
case 'array':
|
case 'array':
|
||||||
case 'object':
|
case 'object':
|
||||||
try {
|
parameterInput.value = JSON.stringify(savedValue);
|
||||||
settings[parameter.name] = JSON.parse(value);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Invalid JSON format for ${parameter.name}`);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
settings[parameter.name] = value;
|
parameterInput.value = savedValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
console.log("parameterInput2", parameterInput);
|
||||||
|
parameterDiv.appendChild(parameterInput);
|
||||||
|
|
||||||
|
pipelineSettingsContent.appendChild(parameterDiv);
|
||||||
});
|
});
|
||||||
operationSettings[operation] = settings;
|
|
||||||
//pipelineSettingsModal.style.display = "none";
|
|
||||||
});
|
|
||||||
pipelineSettingsContent.appendChild(saveButton);
|
|
||||||
|
|
||||||
//pipelineSettingsModal.style.display = "block";
|
let saveButton = document.createElement('button');
|
||||||
|
saveButton.textContent = "Save Settings";
|
||||||
|
saveButton.className = "btn btn-primary";
|
||||||
|
saveButton.addEventListener('click', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
let settings = {};
|
||||||
|
operationData.forEach(parameter => {
|
||||||
|
if (parameter.name !== "fileInput") {
|
||||||
|
let value = document.getElementById(parameter.name).value;
|
||||||
|
switch (parameter.schema.type) {
|
||||||
|
case 'number':
|
||||||
|
case 'integer':
|
||||||
|
settings[parameter.name] = Number(value);
|
||||||
|
break;
|
||||||
|
case 'boolean':
|
||||||
|
settings[parameter.name] = document.getElementById(parameter.name).checked;
|
||||||
|
break;
|
||||||
|
case 'array':
|
||||||
|
case 'object':
|
||||||
|
try {
|
||||||
|
settings[parameter.name] = JSON.parse(value);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Invalid JSON format for ${parameter.name}`);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
settings[parameter.name] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
operationSettings[operation] = settings;
|
||||||
|
//pipelineSettingsModal.style.display = "none";
|
||||||
|
});
|
||||||
|
pipelineSettingsContent.appendChild(saveButton);
|
||||||
|
|
||||||
//pipelineSettingsModal.getElementsByClassName("close")[0].onclick = function() {
|
//pipelineSettingsModal.style.display = "block";
|
||||||
// pipelineSettingsModal.style.display = "none";
|
|
||||||
//}
|
//pipelineSettingsModal.getElementsByClassName("close")[0].onclick = function() {
|
||||||
|
// pipelineSettingsModal.style.display = "none";
|
||||||
|
//}
|
||||||
|
|
||||||
|
//window.onclick = function(event) {
|
||||||
|
// if (event.target == pipelineSettingsModal) {
|
||||||
|
// pipelineSettingsModal.style.display = "none";
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
updateConfigInDropdown();
|
||||||
|
hideOrShowPipelineHeader();
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateConfigInDropdown() {
|
||||||
|
let pipelineSelect = document.getElementById('pipelineSelect');
|
||||||
|
let selectedOption = pipelineSelect.options[pipelineSelect.selectedIndex];
|
||||||
|
|
||||||
|
// Get the current configuration as JSON
|
||||||
|
let pipelineConfigJson = configToJson();
|
||||||
|
console.log("pipelineConfigJson", pipelineConfigJson);
|
||||||
|
if (!pipelineConfigJson) {
|
||||||
|
console.error("Failed to update configuration: Invalid configuration");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the value of the selected option with the new configuration
|
||||||
|
selectedOption.value = pipelineConfigJson;
|
||||||
|
|
||||||
//window.onclick = function(event) {
|
|
||||||
// if (event.target == pipelineSettingsModal) {
|
|
||||||
// pipelineSettingsModal.style.display = "none";
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
hideOrShowPipelineHeader();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var saveBtn = document.getElementById('savePipelineBtn');
|
var saveBtn = document.getElementById('savePipelineBtn');
|
||||||
|
|
||||||
|
@ -479,10 +500,10 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
||||||
// Add the event listener
|
// Add the event listener
|
||||||
saveBtn.addEventListener('click', savePipeline);
|
saveBtn.addEventListener('click', savePipeline);
|
||||||
console.log("saveBtn", saveBtn)
|
console.log("saveBtn", saveBtn)
|
||||||
function savePipeline() {
|
|
||||||
|
|
||||||
if (validatePipeline() === false) {
|
function configToJson() {
|
||||||
return;
|
if (!validatePipeline()) {
|
||||||
|
return null; // Return null if validation fails
|
||||||
}
|
}
|
||||||
|
|
||||||
var pipelineName = document.getElementById('pipelineName').value;
|
var pipelineName = document.getElementById('pipelineName').value;
|
||||||
|
@ -509,11 +530,23 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
||||||
"parameters": parameters
|
"parameters": parameters
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
console.log("Downloading..");
|
|
||||||
|
return JSON.stringify(pipelineConfig, null, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function savePipeline() {
|
||||||
|
let pipelineConfigJson = configToJson();
|
||||||
|
if (!pipelineConfigJson) {
|
||||||
|
console.error("Failed to save pipeline: Invalid configuration");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pipelineName = document.getElementById('pipelineName').value;
|
||||||
|
console.log("Downloading...");
|
||||||
let a = document.createElement('a');
|
let a = document.createElement('a');
|
||||||
a.href = URL.createObjectURL(new Blob([JSON.stringify(pipelineConfig, null, 2)], {
|
a.href = URL.createObjectURL(new Blob([pipelineConfigJson], { type: 'application/json' }));
|
||||||
type: 'application/json'
|
|
||||||
}));
|
|
||||||
a.download = pipelineName + '.json';
|
a.download = pipelineName + '.json';
|
||||||
a.style.display = 'none';
|
a.style.display = 'none';
|
||||||
|
|
||||||
|
@ -522,7 +555,9 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
||||||
document.body.removeChild(a);
|
document.body.removeChild(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function processPipelineConfig(configString) {
|
async function processPipelineConfig(configString) {
|
||||||
|
console.log("configString",configString);
|
||||||
let pipelineConfig = JSON.parse(configString);
|
let pipelineConfig = JSON.parse(configString);
|
||||||
let pipelineList = document.getElementById('pipelineList');
|
let pipelineList = document.getElementById('pipelineList');
|
||||||
|
|
||||||
|
@ -596,14 +631,14 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
||||||
|
|
||||||
|
|
||||||
function hideOrShowPipelineHeader() {
|
function hideOrShowPipelineHeader() {
|
||||||
var pipelineHeader = document.getElementById('pipelineHeader');
|
var pipelineHeader = document.getElementById('pipelineHeader');
|
||||||
var pipelineList = document.getElementById('pipelineList');
|
var pipelineList = document.getElementById('pipelineList');
|
||||||
|
|
||||||
if (pipelineList.children.length === 0) {
|
if (pipelineList.children.length === 0) {
|
||||||
// Hide the pipeline header if there are no items in the pipeline list
|
// Hide the pipeline header if there are no items in the pipeline list
|
||||||
pipelineHeader.style.display = 'none';
|
pipelineHeader.style.display = 'none';
|
||||||
} else {
|
} else {
|
||||||
// Show the pipeline header if there are items in the pipeline list
|
// Show the pipeline header if there are items in the pipeline list
|
||||||
pipelineHeader.style.display = 'block';
|
pipelineHeader.style.display = 'block';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,8 @@
|
||||||
<div class="center-element">
|
<div class="center-element">
|
||||||
<div class="element-margin">
|
<div class="element-margin">
|
||||||
<select id="pipelineSelect" class="custom-select">
|
<select id="pipelineSelect" class="custom-select">
|
||||||
|
<option value="{"name":"Custom","pipeline":[],"_examples":{"outputDir":"{outputFolder}/{folderName}","outputFileName":"{filename}-{pipelineName}-{date}-{time}"},"outputDir":"{outputFolder}","outputFileName":"{filename}"}" th:text="Custom"></option>
|
||||||
|
|
||||||
<th:block th:each="config : ${pipelineConfigsWithNames}">
|
<th:block th:each="config : ${pipelineConfigsWithNames}">
|
||||||
<option th:value="${config.json}" th:text="${config.name}"></option>
|
<option th:value="${config.json}" th:text="${config.name}"></option>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|
Loading…
Reference in a new issue