1
0
mirror of https://github.com/Stirling-Tools/Stirling-PDF.git synced 2024-11-10 18:00:11 +01:00

Pipeline fixes for json lists + delete func (#1425)

* init

* revert

* pipelines fixes for lists

* pipeline fixes to allow json lists

* formatting

* pipeline changes

* langs

---------

Co-authored-by: a <a>
This commit is contained in:
Anthony Stirling 2024-06-09 13:56:55 +01:00 committed by GitHub
parent 56fdf1f3a1
commit 63bdc0d59e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
41 changed files with 184 additions and 41 deletions

View File

@ -103,6 +103,7 @@ body:
- Chrome - Chrome
- Safari - Safari
- Microsoft Edge - Microsoft Edge
- Other
- type: checkboxes - type: checkboxes
id: terms id: terms
@ -111,5 +112,5 @@ body:
description: | description: |
Please confirm that you have searched for similar issues and none of them match your problem. Please confirm that you have searched for similar issues and none of them match your problem.
options: options:
- label: I have verified that there are no issues related to my problem. - label: I have verified that there are no existing issues raised related to my problem.
required: true required: true

View File

@ -0,0 +1,43 @@
{
"name": "OCR images",
"pipeline": [
{
"operation": "/api/v1/convert/img/pdf",
"parameters": {
"fitOption": "fillPage",
"colorType": "color",
"autoRotate": true,
"fileInput": "automated"
}
},
{
"operation": "/api/v1/general/merge-pdfs",
"parameters": {
"sortType": "orderProvided",
"fileInput": "automated"
}
},
{
"operation": "/api/v1/misc/ocr-pdf",
"parameters": {
"languages": [
"eng"
],
"sidecar": false,
"deskew": false,
"clean": false,
"cleanFinal": false,
"ocrType": "skip-text",
"ocrRenderType": "hocr",
"removeImagesAfter": false,
"fileInput": "automated"
}
}
],
"_examples": {
"outputDir": "{outputFolder}/{folderName}",
"outputFileName": "{filename}-{pipelineName}-{date}-{time}"
},
"outputDir": "{outputFolder}",
"outputFileName": "{filename}"
}

View File

@ -105,8 +105,15 @@ public class PipelineProcessor {
body.add("fileInput", file); body.add("fileInput", file);
for (Entry<String, Object> entry : parameters.entrySet()) { for (Entry<String, Object> entry : parameters.entrySet()) {
if (entry.getValue() instanceof List) {
List<?> list = (List<?>) entry.getValue();
for (Object item : list) {
body.add(entry.getKey(), item);
}
} else {
body.add(entry.getKey(), entry.getValue()); body.add(entry.getKey(), entry.getValue());
} }
}
ResponseEntity<byte[]> response = sendWebRequest(url, body); ResponseEntity<byte[]> response = sendWebRequest(url, body);
@ -167,8 +174,15 @@ public class PipelineProcessor {
} }
for (Entry<String, Object> entry : parameters.entrySet()) { for (Entry<String, Object> entry : parameters.entrySet()) {
if (entry.getValue() instanceof List) {
List<?> list = (List<?>) entry.getValue();
for (Object item : list) {
body.add(entry.getKey(), item);
}
} else {
body.add(entry.getKey(), entry.getValue()); body.add(entry.getKey(), entry.getValue());
} }
}
ResponseEntity<byte[]> response = sendWebRequest(url, body); ResponseEntity<byte[]> response = sendWebRequest(url, body);

View File

@ -4,8 +4,7 @@ import jakarta.servlet.http.HttpServletRequest;
public class UrlUtils { public class UrlUtils {
private UrlUtils() { private UrlUtils() {}
}
public static String getOrigin(HttpServletRequest request) { public static String getOrigin(HttpServletRequest request) {
String scheme = request.getScheme(); // http or https String scheme = request.getScheme(); // http or https

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Custom
pipeline.submitButton=Submit pipeline.submitButton=Submit
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Персонализиран
pipeline.submitButton=Подайте pipeline.submitButton=Подайте
pipeline.help=Pipeline Помощ pipeline.help=Pipeline Помощ
pipeline.scanHelp=Помощ за сканиране на папки pipeline.scanHelp=Помощ за сканиране на папки
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Custom
pipeline.submitButton=Submit pipeline.submitButton=Submit
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Vlastní
pipeline.submitButton=Odeslat pipeline.submitButton=Odeslat
pipeline.help=Pomoc s pipeline pipeline.help=Pomoc s pipeline
pipeline.scanHelp=Pomoc se skenováním adresáře pipeline.scanHelp=Pomoc se skenováním adresáře
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Benutzerdefiniert
pipeline.submitButton=Speichern pipeline.submitButton=Speichern
pipeline.help=Hilfe für Pipeline pipeline.help=Hilfe für Pipeline
pipeline.scanHelp=Hilfe zum Ordnerscan pipeline.scanHelp=Hilfe zum Ordnerscan
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Custom
pipeline.submitButton=Υποβολή pipeline.submitButton=Υποβολή
pipeline.help=Βοήθεια για το Pipeline pipeline.help=Βοήθεια για το Pipeline
pipeline.scanHelp=Βοήθεια για Σάρωση Φακέλων pipeline.scanHelp=Βοήθεια για Σάρωση Φακέλων
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Custom
pipeline.submitButton=Submit pipeline.submitButton=Submit
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Custom
pipeline.submitButton=Submit pipeline.submitButton=Submit
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Personalizar
pipeline.submitButton=Enviar pipeline.submitButton=Enviar
pipeline.help=Ayuda de Canalización pipeline.help=Ayuda de Canalización
pipeline.scanHelp=Ayuda de escaneado de carpetas pipeline.scanHelp=Ayuda de escaneado de carpetas
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Custom
pipeline.submitButton=Submit pipeline.submitButton=Submit
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Personnaliser
pipeline.submitButton=Soumettre pipeline.submitButton=Soumettre
pipeline.help=Aide Pipeline pipeline.help=Aide Pipeline
pipeline.scanHelp=Aide analyse de dossier pipeline.scanHelp=Aide analyse de dossier
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Custom
pipeline.submitButton=Submit pipeline.submitButton=Submit
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Prilagođeno
pipeline.submitButton=Pošalji pipeline.submitButton=Pošalji
pipeline.help=Pipeline Pomoć pipeline.help=Pipeline Pomoć
pipeline.scanHelp=Pomoć za skeniranje mapa pipeline.scanHelp=Pomoć za skeniranje mapa
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Custom
pipeline.submitButton=Submit pipeline.submitButton=Submit
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Custom
pipeline.submitButton=Submit pipeline.submitButton=Submit
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Personalizzato
pipeline.submitButton=Invia pipeline.submitButton=Invia
pipeline.help=Aiuto sulla pipeline pipeline.help=Aiuto sulla pipeline
pipeline.scanHelp=Aiuto per la scansione delle cartelle pipeline.scanHelp=Aiuto per la scansione delle cartelle
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=カスタム
pipeline.submitButton=送信 pipeline.submitButton=送信
pipeline.help=パイプラインのヘルプ pipeline.help=パイプラインのヘルプ
pipeline.scanHelp=フォルダ スキャンのヘルプ pipeline.scanHelp=フォルダ スキャンのヘルプ
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=관습
pipeline.submitButton=전송 pipeline.submitButton=전송
pipeline.help=파이프라인 도움말 pipeline.help=파이프라인 도움말
pipeline.scanHelp=폴더 스캔 도움말 pipeline.scanHelp=폴더 스캔 도움말
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Aangepast
pipeline.submitButton=Opslaan pipeline.submitButton=Opslaan
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Tilpasset
pipeline.submitButton=Send inn pipeline.submitButton=Send inn
pipeline.help=Pipeline hjelp pipeline.help=Pipeline hjelp
pipeline.scanHelp=Mappe skanning hjelp pipeline.scanHelp=Mappe skanning hjelp
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Custom
pipeline.submitButton=Submit pipeline.submitButton=Submit
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Custom
pipeline.submitButton=Submit pipeline.submitButton=Submit
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Personalizar
pipeline.submitButton=Submeter pipeline.submitButton=Submeter
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Custom
pipeline.submitButton=Submit pipeline.submitButton=Submit
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Пользовательский
pipeline.submitButton=Отправить pipeline.submitButton=Отправить
pipeline.help=Справка по конвейерной обработке pipeline.help=Справка по конвейерной обработке
pipeline.scanHelp=Справка по сканированию папок pipeline.scanHelp=Справка по сканированию папок
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Vlastné
pipeline.submitButton=Odoslať pipeline.submitButton=Odoslať
pipeline.help=Pomoc s pipeline pipeline.help=Pomoc s pipeline
pipeline.scanHelp=Pomoc so skenovaním priečinka pipeline.scanHelp=Pomoc so skenovaním priečinka
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Prilagođeno
pipeline.submitButton=Pošalji pipeline.submitButton=Pošalji
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Custom
pipeline.submitButton=Submit pipeline.submitButton=Submit
pipeline.help=Pipeline Help pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Folder Scanning Help
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Özel
pipeline.submitButton=Gönder pipeline.submitButton=Gönder
pipeline.help=Çoklu İşlemler Yardım pipeline.help=Çoklu İşlemler Yardım
pipeline.scanHelp=Klasör Tarama Yardımı pipeline.scanHelp=Klasör Tarama Yardımı
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=Користувацький
pipeline.submitButton=Надіслати pipeline.submitButton=Надіслати
pipeline.help=Довідка з конвеєрної обробки pipeline.help=Довідка з конвеєрної обробки
pipeline.scanHelp=Довідка зі сканування папок pipeline.scanHelp=Довідка зі сканування папок
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=自定义
pipeline.submitButton=提交 pipeline.submitButton=提交
pipeline.help=工作流帮助 pipeline.help=工作流帮助
pipeline.scanHelp=文件夹扫描帮助 pipeline.scanHelp=文件夹扫描帮助
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

View File

@ -86,6 +86,7 @@ pipeline.defaultOption=自訂
pipeline.submitButton=送出 pipeline.submitButton=送出
pipeline.help=管道説明 pipeline.help=管道説明
pipeline.scanHelp=資料夾掃描説明 pipeline.scanHelp=資料夾掃描説明
pipeline.deletePrompt=Are you sure you want to delete pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #

File diff suppressed because one or more lines are too long

View File

@ -96,7 +96,6 @@ document.getElementById("submitConfigBtn").addEventListener("click", function ()
for (let i = 0; i < pipelineList.length; i++) { for (let i = 0; i < pipelineList.length; i++) {
let operationName = pipelineList[i].querySelector(".operationName").textContent; let operationName = pipelineList[i].querySelector(".operationName").textContent;
let parameters = operationSettings[operationName] || {}; let parameters = operationSettings[operationName] || {};
pipelineConfig.pipeline.push({ pipelineConfig.pipeline.push({
operation: operationName, operation: operationName,
parameters: parameters, parameters: parameters,
@ -104,7 +103,6 @@ document.getElementById("submitConfigBtn").addEventListener("click", function ()
} }
let pipelineConfigJson = JSON.stringify(pipelineConfig, null, 2); let pipelineConfigJson = JSON.stringify(pipelineConfig, null, 2);
let formData = new FormData(); let formData = new FormData();
let fileInput = document.getElementById("fileInput-input"); let fileInput = document.getElementById("fileInput-input");
@ -218,6 +216,41 @@ fetch("v1/api-docs")
}); });
}); });
document.getElementById('deletePipelineBtn').addEventListener('click', function(event) {
event.preventDefault();
let pipelineName = document.getElementById('pipelineName').value;
if (confirm(deletePipelineText + pipelineName)) {
removePipelineFromUI(pipelineName);
let key = "#Pipeline-" + pipelineName;
if (localStorage.getItem(key)) {
localStorage.removeItem(key);
}
let pipelineSelect = document.getElementById("pipelineSelect");
let modal = document.getElementById('pipelineSettingsModal');
if (modal.style.display !== 'none') {
$('#pipelineSettingsModal').modal('hide');
}
if (pipelineSelect.options.length > 0) {
pipelineSelect.selectedIndex = 0;
pipelineSelect.dispatchEvent(new Event('change'));
}
}
});
function removePipelineFromUI(pipelineName) {
let pipelineSelect = document.getElementById("pipelineSelect");
for (let i = 0; i < pipelineSelect.options.length; i++) {
console.log(pipelineSelect.options[i])
console.log("list " + pipelineSelect.options[i].innerText + " vs " + pipelineName)
if (pipelineSelect.options[i].innerText === pipelineName) {
pipelineSelect.remove(i);
break;
}
}
}
document.getElementById("addOperationBtn").addEventListener("click", function () { document.getElementById("addOperationBtn").addEventListener("click", function () {
let selectedOperation = document.getElementById("operationsDropdown").value; let selectedOperation = document.getElementById("operationsDropdown").value;
let pipelineList = document.getElementById("pipelineList"); let pipelineList = document.getElementById("pipelineList");
@ -379,10 +412,14 @@ document.getElementById("addOperationBtn").addEventListener("click", function ()
if (defaultValue === true) parameterInput.checked = true; if (defaultValue === true) parameterInput.checked = true;
break; break;
case "array": case "array":
case "object": // If parameter.schema.format === 'binary' is to be checked, it should be checked here
//TODO compare to doc and check if fileInput array? parameter.schema.format === 'binary'
parameterInput = document.createElement("textarea"); parameterInput = document.createElement("textarea");
parameterInput.placeholder = `Enter a JSON formatted ${parameter.schema.type}, If this is a fileInput, it is not currently supported`; parameterInput.placeholder = 'Enter a JSON formatted array, e.g., ["item1", "item2", "item3"]';
parameterInput.className = "form-control";
break;
case "object":
parameterInput = document.createElement("textarea");
parameterInput.placeholder = 'Enter a JSON formatted object, e.g., {"key": "value"} If this is a fileInput, it is not currently supported';
parameterInput.className = "form-control"; parameterInput.className = "form-control";
break; break;
default: default:
@ -445,9 +482,14 @@ document.getElementById("addOperationBtn").addEventListener("click", function ()
settings[parameter.name] = ""; settings[parameter.name] = "";
} else { } else {
try { try {
settings[parameter.name] = JSON.parse(value); const parsedValue = JSON.parse(value);
} catch (err) { if (Array.isArray(parsedValue)) {
console.error(`Invalid JSON format for ${parameter.name}`); settings[parameter.name] = parsedValue;
} else {
settings[parameter.name] = value;
}
} catch (e) {
settings[parameter.name] = value;
} }
} }
break; break;
@ -558,7 +600,6 @@ function configToJson() {
parameters: parameters, parameters: parameters,
}); });
} }
return JSON.stringify(pipelineConfig, null, 2); return JSON.stringify(pipelineConfig, null, 2);
} }
@ -642,7 +683,13 @@ async function processPipelineConfig(configString) {
case "text": case "text":
case "textarea": case "textarea":
default: default:
input.value = JSON.stringify(operationConfig.parameters[parameterName]); var value = operationConfig.parameters[parameterName]
if (typeof value !== 'string') {
input.value = JSON.stringify(value) ;
} else {
input.value = value;
}
} }
} }
}); });

View File

@ -16,6 +16,7 @@
/> />
<script th:inline="javascript"> <script th:inline="javascript">
const saveSettings = /*[[#{pipelineOptions.saveSettings}]]*/ ""; const saveSettings = /*[[#{pipelineOptions.saveSettings}]]*/ "";
const deletePipelineText = /*[[#{pipeline.pipeline.deletePrompt}]]*/ "Are you sure you want to delete pipeline";
</script> </script>
</head> </head>
@ -92,7 +93,7 @@
<!-- The Modal --> <!-- The Modal -->
<div class="modal" id="pipelineSettingsModal"> <div class="modal" id="pipelineSettingsModal">
<div class="modal-dialog"> <div class="modal-dialog modal-lg">
<div class="modal-content dark-card"> <div class="modal-content dark-card">
<!-- Modal Header --> <!-- Modal Header -->
<div class="modal-header"> <div class="modal-header">
@ -158,6 +159,12 @@
<!-- Modal footer --> <!-- Modal footer -->
<div class="modal-footer"> <div class="modal-footer">
<button
id="deletePipelineBtn"
class="btn btn-danger"
th:text="#{delete}"
></button>
<button <button
id="saveBrowserPipelineBtn" id="saveBrowserPipelineBtn"
class="btn btn-success" class="btn btn-success"