Move remaining library dialogs to new style

This commit is contained in:
Nick O'Leary 2019-04-24 11:50:24 +01:00
parent 6f37d5ca5c
commit 5e43a02cd3
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
11 changed files with 335 additions and 253 deletions

View File

@ -55,9 +55,6 @@
"export" : "Exportieren", "export" : "Exportieren",
"search" : "Flows durchsuchen", "search" : "Flows durchsuchen",
"searchInput" : "durchsuchen Sie Ihre Flows", "searchInput" : "durchsuchen Sie Ihre Flows",
"clipboard" : "Zwischenablage",
"library" : "Bibliothek",
"examples" : "Beispiele",
"subflows" : "Subflow", "subflows" : "Subflow",
"createSubflow" : "Subflow erstellen", "createSubflow" : "Subflow erstellen",
"selectionToSubflow" : "Auswahl für Subflow", "selectionToSubflow" : "Auswahl für Subflow",
@ -136,8 +133,8 @@
} }
}, },
"clipboard" : { "clipboard" : {
"clipboard" : "Zwischenablage",
"nodes" : "Knoten", "nodes" : "Knoten",
"selectNodes" : "Wählen Sie den Text oben aus, und kopieren Sie die Datei in die Zwischenablage.",
"pasteNodes" : "Knoten hier einfügen", "pasteNodes" : "Knoten hier einfügen",
"importNodes" : "Knoten importieren", "importNodes" : "Knoten importieren",
"exportNodes" : "Knoten in Zwischenablage exportieren", "exportNodes" : "Knoten in Zwischenablage exportieren",
@ -297,22 +294,19 @@
"managePalette" : "Palette verwalten" "managePalette" : "Palette verwalten"
}, },
"library" : { "library" : {
"library" : "Bibliothek",
"openLibrary" : "Bibliothek öffnen ...", "openLibrary" : "Bibliothek öffnen ...",
"saveToLibrary" : "In Bibliothek speichern ...", "saveToLibrary" : "In Bibliothek speichern ...",
"typeLibrary" : "__type__, Bibliothek", "typeLibrary" : "__type__, Bibliothek",
"unnamedType" : "Unbenannt __type__", "unnamedType" : "Unbenannt __type__",
"exportToLibrary" : "Knoten in Bibliothek exportieren",
"dialogSaveOverwrite" : "Ein __libraryType__ mit dem Namen __libraryName__ ist bereits vorhanden. Überschreiben?", "dialogSaveOverwrite" : "Ein __libraryType__ mit dem Namen __libraryName__ ist bereits vorhanden. Überschreiben?",
"invalidFilename" : "Ungültiger Dateiname", "invalidFilename" : "Ungültiger Dateiname",
"savedNodes" : "Gespeicherte Knoten", "savedNodes" : "Gespeicherte Knoten",
"savedType" : "Gespeichert __type__", "savedType" : "Gespeichert __type__",
"saveFailed" : "Speichern fehlgeschlagen: __message__", "saveFailed" : "Speichern fehlgeschlagen: __message__",
"filename" : "Name der Datei", "types": {
"folder" : "Ordner", "examples" : "Beispiele"
"filenamePlaceholder" : "Datei", }
"fullFilenamePlaceholder" : "a/b/Datei",
"folderPlaceholder" : "a/b",
"breadcrumb" : "Bibliothek"
}, },
"palette" : { "palette" : {
"noInfo" : "Keine Informationen verfügbar", "noInfo" : "Keine Informationen verfügbar",
@ -826,4 +820,4 @@
"code" : "code" "code" : "code"
} }
} }
} }

View File

@ -59,9 +59,6 @@
"export": "Export", "export": "Export",
"search": "Search flows", "search": "Search flows",
"searchInput": "search your flows", "searchInput": "search your flows",
"clipboard": "Clipboard",
"library": "Library",
"examples": "Examples",
"subflows": "Subflows", "subflows": "Subflows",
"createSubflow": "Create Subflow", "createSubflow": "Create Subflow",
"selectionToSubflow": "Selection to Subflow", "selectionToSubflow": "Selection to Subflow",
@ -154,6 +151,7 @@
} }
}, },
"clipboard": { "clipboard": {
"clipboard": "Clipboard",
"nodes": "Nodes", "nodes": "Nodes",
"node": "__count__ node", "node": "__count__ node",
"node_plural": "__count__ nodes", "node_plural": "__count__ nodes",
@ -163,7 +161,6 @@
"flow_plural": "__count__ flows", "flow_plural": "__count__ flows",
"subflow": "__count__ subflow", "subflow": "__count__ subflow",
"subflow_plural": "__count__ subflows", "subflow_plural": "__count__ subflows",
"selectNodes": "Select the text above and copy to the clipboard.",
"pasteNodes": "Paste flow json or", "pasteNodes": "Paste flow json or",
"selectFile": "select a file to import", "selectFile": "select a file to import",
"importNodes": "Import nodes", "importNodes": "Import nodes",
@ -353,23 +350,21 @@
"managePalette": "Manage palette" "managePalette": "Manage palette"
}, },
"library": { "library": {
"library": "Library",
"openLibrary": "Open Library...", "openLibrary": "Open Library...",
"saveToLibrary": "Save to Library...", "saveToLibrary": "Save to Library...",
"typeLibrary": "__type__ library", "typeLibrary": "__type__ library",
"unnamedType": "Unnamed __type__", "unnamedType": "Unnamed __type__",
"exportToLibrary": "Export nodes to library",
"exportedToLibrary": "Nodes exported to library", "exportedToLibrary": "Nodes exported to library",
"dialogSaveOverwrite": "A __libraryType__ called __libraryName__ already exists. Overwrite?", "dialogSaveOverwrite": "A __libraryType__ called __libraryName__ already exists. Overwrite?",
"invalidFilename": "Invalid filename", "invalidFilename": "Invalid filename",
"savedNodes": "Saved nodes", "savedNodes": "Saved nodes",
"savedType": "Saved __type__", "savedType": "Saved __type__",
"saveFailed": "Save failed: __message__", "saveFailed": "Save failed: __message__",
"filename": "Filename", "types": {
"folder": "Folder", "local": "Local",
"filenamePlaceholder": "file", "examples": "Examples"
"fullFilenamePlaceholder": "a/b/file", }
"folderPlaceholder": "a/b",
"breadcrumb": "Library"
}, },
"palette": { "palette": {
"noInfo": "no information available", "noInfo": "no information available",

View File

@ -59,9 +59,6 @@
"export": "書き出し", "export": "書き出し",
"search": "ノードを検索", "search": "ノードを検索",
"searchInput": "ノードを検索", "searchInput": "ノードを検索",
"clipboard": "クリップボード",
"library": "ライブラリ",
"examples": "サンプル",
"subflows": "サブフロー", "subflows": "サブフロー",
"createSubflow": "サブフローを作成", "createSubflow": "サブフローを作成",
"selectionToSubflow": "選択部分をサブフロー化", "selectionToSubflow": "選択部分をサブフロー化",
@ -154,6 +151,7 @@
} }
}, },
"clipboard": { "clipboard": {
"clipboard": "クリップボード",
"nodes": "ノード", "nodes": "ノード",
"node": "__count__ 個のノード", "node": "__count__ 個のノード",
"node_plural": "__count__ 個のノード", "node_plural": "__count__ 個のノード",
@ -163,7 +161,6 @@
"flow_plural": "__count__ 個のフロー", "flow_plural": "__count__ 個のフロー",
"subflow": "__count__ 個のサブフロー", "subflow": "__count__ 個のサブフロー",
"subflow_plural": "__count__ 個のサブフロー", "subflow_plural": "__count__ 個のサブフロー",
"selectNodes": "上のテキストを選択し、クリップボードへコピーしてください",
"pasteNodes": "JSON形式のフローデータを貼り付けてください", "pasteNodes": "JSON形式のフローデータを貼り付けてください",
"selectFile": "読み込むファイルを選択してください", "selectFile": "読み込むファイルを選択してください",
"importNodes": "フローをクリップボートから読み込み", "importNodes": "フローをクリップボートから読み込み",
@ -349,22 +346,19 @@
"managePalette": "パレットの管理" "managePalette": "パレットの管理"
}, },
"library": { "library": {
"library": "ライブラリ",
"openLibrary": "ライブラリを開く", "openLibrary": "ライブラリを開く",
"saveToLibrary": "ライブラリへ保存", "saveToLibrary": "ライブラリへ保存",
"typeLibrary": "__type__ ライブラリ", "typeLibrary": "__type__ ライブラリ",
"unnamedType": "名前なし __type__", "unnamedType": "名前なし __type__",
"exportToLibrary": "ライブラリへフローを書き出す",
"dialogSaveOverwrite": "__libraryName__ という __libraryType__ は既に存在しています 上書きしますか?", "dialogSaveOverwrite": "__libraryName__ という __libraryType__ は既に存在しています 上書きしますか?",
"invalidFilename": "不正なファイル名", "invalidFilename": "不正なファイル名",
"savedNodes": "フローを保存しました", "savedNodes": "フローを保存しました",
"savedType": "__type__ を保存しました", "savedType": "__type__ を保存しました",
"saveFailed": "保存に失敗しました: __message__", "saveFailed": "保存に失敗しました: __message__",
"filename": "ファイル名", "types": {
"folder": "フォルダ", "examples": "サンプル"
"filenamePlaceholder": "ファイル", }
"fullFilenamePlaceholder": "a/b/file",
"folderPlaceholder": "a/b",
"breadcrumb": "ライブラリ"
}, },
"palette": { "palette": {
"noInfo": "情報がありません", "noInfo": "情報がありません",

View File

@ -58,9 +58,6 @@
"export": "내보내기", "export": "내보내기",
"search": "플로우 겅색", "search": "플로우 겅색",
"searchInput": "플로우 검색", "searchInput": "플로우 검색",
"clipboard": "클립보드",
"library": "라이브러리",
"examples": "예시",
"subflows": "보조 플로우", "subflows": "보조 플로우",
"createSubflow": "보조 플로우 생성", "createSubflow": "보조 플로우 생성",
"selectionToSubflow": "보조 플로우 선택", "selectionToSubflow": "보조 플로우 선택",
@ -148,6 +145,7 @@
} }
}, },
"clipboard": { "clipboard": {
"clipboard": "클립보드",
"nodes": "노드", "nodes": "노드",
"node": "__count__ 개의 노드", "node": "__count__ 개의 노드",
"node_plural": "__count__ 개의 노드", "node_plural": "__count__ 개의 노드",
@ -157,7 +155,6 @@
"flow_plural": "__count__ 개의 플로우", "flow_plural": "__count__ 개의 플로우",
"subflow": "__count__ 개의 서브 플로우", "subflow": "__count__ 개의 서브 플로우",
"subflow_plural": "__count__ 개의 서브 플로우", "subflow_plural": "__count__ 개의 서브 플로우",
"selectNodes": "텍스트를 선택하고 클립보드에 복사하세요",
"pasteNodes": "여기에 노드를 붙여넣기 하세요", "pasteNodes": "여기에 노드를 붙여넣기 하세요",
"selectFile": "불러올 파일을 선택하세요", "selectFile": "불러올 파일을 선택하세요",
"importNodes": "노드 불러오기", "importNodes": "노드 불러오기",
@ -338,22 +335,19 @@
"managePalette": "팔렛트 관리" "managePalette": "팔렛트 관리"
}, },
"library": { "library": {
"library": "라이브러리",
"openLibrary": "라이브러리 열기...", "openLibrary": "라이브러리 열기...",
"saveToLibrary": "라이브러리로 저장...", "saveToLibrary": "라이브러리로 저장...",
"typeLibrary": "__type__ 라이브러리", "typeLibrary": "__type__ 라이브러리",
"unnamedType": "이름없는 __type__", "unnamedType": "이름없는 __type__",
"exportToLibrary": "라이브러리로 노드 내보내기",
"dialogSaveOverwrite": "__libraryType__이 __libraryName__으로 이미 등록되어있습니다. 덮어쓸까요?", "dialogSaveOverwrite": "__libraryType__이 __libraryName__으로 이미 등록되어있습니다. 덮어쓸까요?",
"invalidFilename": "파일명이 올바르지 않습니다", "invalidFilename": "파일명이 올바르지 않습니다",
"savedNodes": "저장된 노드", "savedNodes": "저장된 노드",
"savedType": "저장된 __type__", "savedType": "저장된 __type__",
"saveFailed": "저장 실패 : __message__", "saveFailed": "저장 실패 : __message__",
"filename": "파일명", "types": {
"folder": "폴더명", "examples": "예시"
"filenamePlaceholder": "파일", }
"fullFilenamePlaceholder": "a/b/file",
"folderPlaceholder": "a/b",
"breadcrumb": "라이브러리"
}, },
"palette": { "palette": {
"noInfo": "정보 없음", "noInfo": "정보 없음",
@ -904,4 +898,4 @@
"description": "상세 내역", "description": "상세 내역",
"appearance": "모양" "appearance": "모양"
} }
} }

View File

@ -50,9 +50,6 @@
"export": "导出", "export": "导出",
"search": "查找流程", "search": "查找流程",
"searchInput": "查找流程", "searchInput": "查找流程",
"clipboard": "剪贴板",
"library": "库",
"examples": "例子",
"subflows": "子流程", "subflows": "子流程",
"createSubflow": "新建子流程", "createSubflow": "新建子流程",
"selectionToSubflow": "将选择部分更改为子流程", "selectionToSubflow": "将选择部分更改为子流程",
@ -100,8 +97,8 @@
} }
}, },
"clipboard": { "clipboard": {
"clipboard": "剪贴板",
"nodes": "节点", "nodes": "节点",
"selectNodes": "选择上面的文本并复制到剪贴板",
"pasteNodes": "在这里粘贴节点", "pasteNodes": "在这里粘贴节点",
"importNodes": "导入节点", "importNodes": "导入节点",
"exportNodes": "导出节点至剪贴板", "exportNodes": "导出节点至剪贴板",
@ -237,6 +234,7 @@
"managePalette": "管理面板" "managePalette": "管理面板"
}, },
"library": { "library": {
"library": "库",
"openLibrary": "打开库...", "openLibrary": "打开库...",
"saveToLibrary": "保存到库...", "saveToLibrary": "保存到库...",
"typeLibrary": "__type__类型库", "typeLibrary": "__type__类型库",
@ -247,12 +245,9 @@
"savedNodes": "保存的节点", "savedNodes": "保存的节点",
"savedType": "已保存__type__", "savedType": "已保存__type__",
"saveFailed": "保存失败: __message__", "saveFailed": "保存失败: __message__",
"filename": "文件名", "types": {
"folder": "文件夹", "examples": "例子"
"filenamePlaceholder": "文件", }
"fullFilenamePlaceholder": "a/b/文件",
"folderPlaceholder": "a/b",
"breadcrumb": "库"
}, },
"palette": { "palette": {
"noInfo": "无可用信息", "noInfo": "无可用信息",

View File

@ -462,14 +462,8 @@ var RED = (function() {
null null
]}); ]});
menuOptions.push(null); menuOptions.push(null);
menuOptions.push({id:"menu-item-import",label:RED._("menu.label.import"),options:[ menuOptions.push({id:"menu-item-import",label:RED._("menu.label.import"),onselect:"core:show-import-dialog"});
{id:"menu-item-import-clipboard",label:RED._("menu.label.clipboard"),onselect:"core:show-import-dialog"}, menuOptions.push({id:"menu-item-export",label:RED._("menu.label.export"),onselect:"core:show-export-dialog"});
{id:"menu-item-import-library",label:RED._("menu.label.library"),onselect:"core:library-import"}
]});
menuOptions.push({id:"menu-item-export",label:RED._("menu.label.export"),options:[
{id:"menu-item-export-clipboard",label:RED._("menu.label.clipboard"),onselect:"core:show-export-dialog"},
{id:"menu-item-export-library",label:RED._("menu.label.library"),onselect:"core:library-export"}
]});
menuOptions.push(null); menuOptions.push(null);
menuOptions.push({id:"menu-item-search",label:RED._("menu.label.search"),onselect:"core:search"}); menuOptions.push({id:"menu-item-search",label:RED._("menu.label.search"),onselect:"core:search"});
menuOptions.push(null); menuOptions.push(null);

View File

@ -24,7 +24,7 @@ RED.clipboard = (function() {
var disabled = false; var disabled = false;
var popover; var popover;
var currentPopoverError; var currentPopoverError;
var activeExportTab; var activeTab;
var libraryBrowser; var libraryBrowser;
function setupDialogs() { function setupDialogs() {
@ -33,7 +33,7 @@ RED.clipboard = (function() {
.dialog({ .dialog({
modal: true, modal: true,
autoOpen: false, autoOpen: false,
width: 800, width: 700,
resizable: false, resizable: false,
buttons: [ buttons: [
{ {
@ -63,7 +63,7 @@ RED.clipboard = (function() {
class: "primary", class: "primary",
text: RED._("clipboard.export.copy"), text: RED._("clipboard.export.copy"),
click: function() { click: function() {
if (activeExportTab === "clipboard-dialog-export-tab-clipboard") { if (activeTab === "clipboard-dialog-export-tab-clipboard") {
$("#clipboard-export").select(); $("#clipboard-export").select();
document.execCommand("copy"); document.execCommand("copy");
document.getSelection().removeAllRanges(); document.getSelection().removeAllRanges();
@ -93,9 +93,9 @@ RED.clipboard = (function() {
} }
}); });
} }
if (selectedPath.files) { if (selectedPath.children) {
var exists = false; var exists = false;
selectedPath.files.forEach(function(f) { selectedPath.children.forEach(function(f) {
if (f.label === filename) { if (f.label === filename) {
exists = true; exists = true;
} }
@ -133,7 +133,17 @@ RED.clipboard = (function() {
class: "primary", class: "primary",
text: RED._("common.label.import"), text: RED._("common.label.import"),
click: function() { click: function() {
RED.view.importNodes($("#clipboard-import").val(),$("#import-tab > a.selected").attr('id') === 'import-tab-new'); var addNewFlow = ($("#import-tab > a.selected").attr('id') === 'import-tab-new');
if (activeTab === "clipboard-dialog-import-tab-clipboard") {
RED.view.importNodes($("#clipboard-import").val(),addNewFlow);
} else {
var selectedPath = libraryBrowser.getSelected();
if (selectedPath.path) {
$.get('library/flows/'+selectedPath.path, function(data) {
RED.view.importNodes(data,addNewFlow);
});
}
}
$( this ).dialog( "close" ); $( this ).dialog( "close" );
} }
} }
@ -160,12 +170,12 @@ RED.clipboard = (function() {
'<a id="export-range-full" class="editor-button toggle" href="#" data-i18n="clipboard.export.all"></a>'+ '<a id="export-range-full" class="editor-button toggle" href="#" data-i18n="clipboard.export.all"></a>'+
'</span>'+ '</span>'+
'</div>'+ '</div>'+
'<div style="height: 500px; position:relative; border:1px solid #999;">'+ '<div style="height: 400px; position:relative; border:1px solid #999;">'+
'<div style="position: absolute; top:0;left:0;bottom:0;width:120px;background: #f3f3f3;">'+ '<div style="position: absolute; top:0;left:0;bottom:0;width:120px;background: #f3f3f3;">'+
'<ul id="clipboard-dialog-export-tabs"></ul>'+ '<ul id="clipboard-dialog-export-tabs"></ul>'+
'</div>'+ '</div>'+
'<div id="clipboard-dialog-export-tabs-content">'+ '<div id="clipboard-dialog-export-tabs-content" class="clipboard-dialog-tabs-content">'+
'<div id="clipboard-dialog-export-tab-clipboard">'+ '<div id="clipboard-dialog-export-tab-clipboard" class="clipboard-dialog-tab-clipboard">'+
'<div class="form-row">'+ '<div class="form-row">'+
'<textarea readonly id="clipboard-export"></textarea>'+ '<textarea readonly id="clipboard-export"></textarea>'+
'</div>'+ '</div>'+
@ -176,7 +186,7 @@ RED.clipboard = (function() {
'</span>'+ '</span>'+
'</div>'+ '</div>'+
'</div>'+ '</div>'+
'<div id="clipboard-dialog-export-tab-library">'+ '<div id="clipboard-dialog-export-tab-library" class="clipboard-dialog-tab-library">'+
'<div id="clipboard-dialog-export-tab-library-browser"></div>'+ '<div id="clipboard-dialog-export-tab-library-browser"></div>'+
'<div class="form-row">'+ '<div class="form-row">'+
'<label data-i18n="clipboard.export.exportAs"></label><input id="clipboard-dialog-tab-library-name" type="text">'+ '<label data-i18n="clipboard.export.exportAs"></label><input id="clipboard-dialog-tab-library-name" type="text">'+
@ -188,20 +198,33 @@ RED.clipboard = (function() {
importNodesDialog = importNodesDialog =
'<div class="form-row"><span data-i18n="clipboard.pasteNodes"></span>'+ '<div style="height: 400px; position:relative; border:1px solid #999; margin-bottom: 12px">'+
' <a class="editor-button" id="import-file-upload-btn"><i class="fa fa-upload"></i> <span data-i18n="clipboard.selectFile"></span></a>'+ '<div style="position: absolute; top:0;left:0;bottom:0;width:120px;background: #f3f3f3;">'+
'<input type="file" id="import-file-upload" accept=".json" style="display:none">'+ '<ul id="clipboard-dialog-import-tabs"></ul>'+
'</div>'+
'<div id="clipboard-dialog-import-tabs-content" class="clipboard-dialog-tabs-content">'+
'<div id="clipboard-dialog-import-tab-clipboard" class="clipboard-dialog-tab-clipboard">'+
'<div class="form-row"><span data-i18n="clipboard.pasteNodes"></span>'+
' <a class="editor-button" id="import-file-upload-btn"><i class="fa fa-upload"></i> <span data-i18n="clipboard.selectFile"></span></a>'+
'<input type="file" id="import-file-upload" accept=".json" style="display:none">'+
'</div>'+
'<div class="form-row">'+
'<textarea id="clipboard-import"></textarea>'+
'</div>'+
'</div>'+
'<div id="clipboard-dialog-import-tab-library" class="clipboard-dialog-tab-library">'+
'<div id="clipboard-dialog-import-tab-library-browser"></div>'+
'</div>'+
'</div>'+
'</div>'+ '</div>'+
'<div class="form-row">'+ '<div class="form-row">'+
'<textarea style="resize: none; width: 100%; border-radius: 0px;font-family: monospace; font-size: 12px; background:#eee; padding-left: 0.5em; box-sizing:border-box;" id="clipboard-import" rows="5"></textarea>'+ '<label style="width:auto;margin-right: 10px;" data-i18n="clipboard.import.import"></label>'+
'</div>'+ '<span id="import-tab" class="button-group">'+
'<div class="form-row">'+ '<a id="import-tab-current" class="editor-button toggle selected" href="#" data-i18n="clipboard.export.current"></a>'+
'<label style="width:auto;margin-right: 10px;" data-i18n="clipboard.import.import"></label>'+ '<a id="import-tab-new" class="editor-button toggle" href="#" data-i18n="clipboard.import.newFlow"></a>'+
'<span id="import-tab" class="button-group">'+ '</span>'+
'<a id="import-tab-current" class="editor-button toggle selected" href="#" data-i18n="clipboard.export.current"></a>'+
'<a id="import-tab-new" class="editor-button toggle" href="#" data-i18n="clipboard.import.newFlow"></a>'+
'</span>'+
'</div>'; '</div>';
} }
var validateExportFilenameTimeout var validateExportFilenameTimeout
@ -223,107 +246,167 @@ RED.clipboard = (function() {
},100); },100);
} }
var validateImportTimeout; var validateImportTimeout;
function validateImport() { function validateImport() {
if (validateImportTimeout) { if (activeTab === "clipboard-dialog-import-tab-clipboard") {
clearTimeout(validateImportTimeout); if (validateImportTimeout) {
} clearTimeout(validateImportTimeout);
validateImportTimeout = setTimeout(function() {
var importInput = $("#clipboard-import");
var v = importInput.val().trim();
if (v === "") {
popover.close(true);
currentPopoverError = null;
importInput.removeClass("input-error");
$("#clipboard-dialog-ok").button("disable");
return;
} }
try { validateImportTimeout = setTimeout(function() {
if (!/^\[[\s\S]*\]$/m.test(v)) { var importInput = $("#clipboard-import");
throw new Error(RED._("clipboard.import.errors.notArray")); var v = importInput.val().trim();
} if (v === "") {
var res = JSON.parse(v); popover.close(true);
for (var i=0;i<res.length;i++) {
if (typeof res[i] !== "object") {
throw new Error(RED._("clipboard.import.errors.itemNotObject",{index:i}));
}
if (!res[i].hasOwnProperty('id')) {
throw new Error(RED._("clipboard.import.errors.missingId",{index:i}));
}
if (!res[i].hasOwnProperty('type')) {
throw new Error(RED._("clipboard.import.errors.missingType",{index:i}));
}
}
currentPopoverError = null;
popover.close(true);
importInput.removeClass("input-error");
importInput.val(v);
$("#clipboard-dialog-ok").button("enable");
} catch(err) {
if (v !== "") {
importInput.addClass("input-error");
var errString = err.toString();
if (errString !== currentPopoverError) {
// Display the error as-is.
// Error messages are only in English. Each browser has its
// own set of messages with very little consistency.
// To provide translated messages this code will either need to:
// - reduce everything down to 'unexpected token at position x'
// which is the least useful, but most consistent message
// - use a custom/library parser that gives consistent messages
// which can be translated.
var message = $('<div class="clipboard-import-error"></div>').text(errString);
var errorPos;
// Chrome error messages
var m = /at position (\d+)/i.exec(errString);
if (m) {
errorPos = parseInt(m[1]);
} else {
// Firefox error messages
m = /at line (\d+) column (\d+)/i.exec(errString);
if (m) {
var line = parseInt(m[1])-1;
var col = parseInt(m[2])-1;
var lines = v.split("\n");
errorPos = 0;
for (var i=0;i<line;i++) {
errorPos += lines[i].length+1;
}
errorPos += col;
} else {
// Safari doesn't provide any position information
// IE: tbd
}
}
if (errorPos !== undefined) {
v = v.replace(/\n/g,"↵");
var index = parseInt(m[1]);
var parseError = $('<div>').appendTo(message);
var code = $('<pre>').appendTo(parseError);
$('<span>').text(v.substring(errorPos-12,errorPos)).appendTo(code)
$('<span class="error">').text(v.charAt(errorPos)).appendTo(code);
$('<span>').text(v.substring(errorPos+1,errorPos+12)).appendTo(code);
}
popover.close(true).setContent(message).open();
currentPopoverError = errString;
}
} else {
currentPopoverError = null; currentPopoverError = null;
importInput.removeClass("input-error");
$("#clipboard-dialog-ok").button("disable");
return;
} }
try {
if (!/^\[[\s\S]*\]$/m.test(v)) {
throw new Error(RED._("clipboard.import.errors.notArray"));
}
var res = JSON.parse(v);
for (var i=0;i<res.length;i++) {
if (typeof res[i] !== "object") {
throw new Error(RED._("clipboard.import.errors.itemNotObject",{index:i}));
}
if (!res[i].hasOwnProperty('id')) {
throw new Error(RED._("clipboard.import.errors.missingId",{index:i}));
}
if (!res[i].hasOwnProperty('type')) {
throw new Error(RED._("clipboard.import.errors.missingType",{index:i}));
}
}
currentPopoverError = null;
popover.close(true);
importInput.removeClass("input-error");
importInput.val(v);
$("#clipboard-dialog-ok").button("enable");
} catch(err) {
if (v !== "") {
importInput.addClass("input-error");
var errString = err.toString();
if (errString !== currentPopoverError) {
// Display the error as-is.
// Error messages are only in English. Each browser has its
// own set of messages with very little consistency.
// To provide translated messages this code will either need to:
// - reduce everything down to 'unexpected token at position x'
// which is the least useful, but most consistent message
// - use a custom/library parser that gives consistent messages
// which can be translated.
var message = $('<div class="clipboard-import-error"></div>').text(errString);
var errorPos;
// Chrome error messages
var m = /at position (\d+)/i.exec(errString);
if (m) {
errorPos = parseInt(m[1]);
} else {
// Firefox error messages
m = /at line (\d+) column (\d+)/i.exec(errString);
if (m) {
var line = parseInt(m[1])-1;
var col = parseInt(m[2])-1;
var lines = v.split("\n");
errorPos = 0;
for (var i=0;i<line;i++) {
errorPos += lines[i].length+1;
}
errorPos += col;
} else {
// Safari doesn't provide any position information
// IE: tbd
}
}
if (errorPos !== undefined) {
v = v.replace(/\n/g,"↵");
var index = parseInt(m[1]);
var parseError = $('<div>').appendTo(message);
var code = $('<pre>').appendTo(parseError);
$('<span>').text(v.substring(errorPos-12,errorPos)).appendTo(code)
$('<span class="error">').text(v.charAt(errorPos)).appendTo(code);
$('<span>').text(v.substring(errorPos+1,errorPos+12)).appendTo(code);
}
popover.close(true).setContent(message).open();
currentPopoverError = errString;
}
} else {
currentPopoverError = null;
}
$("#clipboard-dialog-ok").button("disable");
}
},100);
} else {
var file = libraryBrowser.getSelected();
if (file && file.label && !file.children) {
$("#clipboard-dialog-ok").button("enable");
} else {
$("#clipboard-dialog-ok").button("disable"); $("#clipboard-dialog-ok").button("disable");
} }
},100); }
} }
function importNodes() { function importNodes(mode) {
if (disabled) { if (disabled) {
return; return;
} }
mode = mode || "clipboard";
dialogContainer.empty(); dialogContainer.empty();
dialogContainer.append($(importNodesDialog)); dialogContainer.append($(importNodesDialog));
var tabs = RED.tabs.create({
id: "clipboard-dialog-import-tabs",
vertical: true,
onchange: function(tab) {
$("#clipboard-dialog-import-tabs-content").children().hide();
$("#" + tab.id).show();
activeTab = tab.id;
if (popover) {
popover.close(true);
currentPopoverError = null;
}
if (tab.id === "clipboard-dialog-import-tab-clipboard") {
$("#clipboard-import").focus();
}
validateImport();
}
});
tabs.addTab({
id: "clipboard-dialog-import-tab-clipboard",
label: RED._("clipboard.clipboard")
});
tabs.addTab({
id: "clipboard-dialog-import-tab-library",
label: RED._("library.library")
});
tabs.activateTab("clipboard-dialog-import-tab-"+mode);
if (mode === 'clipboard') {
setTimeout(function() {
$("#clipboard-import").focus();
},100)
}
$("#clipboard-dialog-tab-library-name").keyup(validateExportFilename);
$("#clipboard-dialog-tab-library-name").on('paste',function() { setTimeout(validateExportFilename,10)});
$("#clipboard-dialog-export").button("enable");
libraryBrowser = RED.library.createBrowser({
container: $("#clipboard-dialog-import-tab-library-browser"),
onselect: function(file) {
if (file && file.label && !file.children) {
$("#clipboard-dialog-ok").button("enable");
} else {
$("#clipboard-dialog-ok").button("disable");
}
}
})
loadFlowLibrary(libraryBrowser,true);
dialogContainer.i18n(); dialogContainer.i18n();
$("#clipboard-dialog-ok").show(); $("#clipboard-dialog-ok").show();
@ -381,7 +464,7 @@ RED.clipboard = (function() {
onchange: function(tab) { onchange: function(tab) {
$("#clipboard-dialog-export-tabs-content").children().hide(); $("#clipboard-dialog-export-tabs-content").children().hide();
$("#" + tab.id).show(); $("#" + tab.id).show();
activeExportTab = tab.id; activeTab = tab.id;
if (tab.id === "clipboard-dialog-export-tab-clipboard") { if (tab.id === "clipboard-dialog-export-tab-clipboard") {
$("#clipboard-dialog-export").button("option","label", RED._("clipboard.export.copy")) $("#clipboard-dialog-export").button("option","label", RED._("clipboard.export.copy"))
$("#clipboard-dialog-download").show(); $("#clipboard-dialog-download").show();
@ -394,11 +477,11 @@ RED.clipboard = (function() {
}); });
tabs.addTab({ tabs.addTab({
id: "clipboard-dialog-export-tab-clipboard", id: "clipboard-dialog-export-tab-clipboard",
label: "Clipboard" label: RED._("clipboard.clipboard")
}); });
tabs.addTab({ tabs.addTab({
id: "clipboard-dialog-export-tab-library", id: "clipboard-dialog-export-tab-library",
label: "Library" label: RED._("library.library")
}); });
tabs.activateTab("clipboard-dialog-export-tab-"+mode); tabs.activateTab("clipboard-dialog-export-tab-"+mode);
@ -416,53 +499,10 @@ RED.clipboard = (function() {
} }
} }
}) })
loadFlowLibrary(libraryBrowser,false);
function xformList(list,label,root) {
var result = {
icon: root===""?"fa fa-archive":'fa fa-folder',
label: label,
path: root
};
result.children = [];
if (list.f) {
list.f.forEach(function(f) {
result.children.push({
icon: 'fa fa-file-o',
label: f,
path: root+f
});
});
}
if (list.d) {
for (var l in list.d) {
if (list.d.hasOwnProperty(l)) {
if (root+l !== "_examples_") {
result.children.push(xformList(list.d[l], l,root+l+"/"))
}
}
}
}
result.children.sort(function(A,B){
if (A.children && !B.children) {
return -1;
} else if (!A.children && B.children) {
return 1;
} else {
return A.label.localeCompare(B.label);
}
});
return result;
}
$.getJSON("library/flows", function(data) {
var listing = [xformList(data,"Local","")];
listing[0].expanded = true;
libraryBrowser.data(listing);
});
$("#clipboard-dialog-tab-library-name").val("flows.json").select(); $("#clipboard-dialog-tab-library-name").val("flows.json").select();
dialogContainer.i18n(); dialogContainer.i18n();
var format = RED.settings.flowFilePretty ? "export-format-full" : "export-format-mini"; var format = RED.settings.flowFilePretty ? "export-format-full" : "export-format-mini";
@ -569,6 +609,60 @@ RED.clipboard = (function() {
$("#clipboard-dialog-download").show(); $("#clipboard-dialog-download").show();
} }
function transformFlowList(list,label,root,includeExamples) {
var result = {
icon: root===""?"fa fa-archive":'fa fa-folder',
label: label,
path: root
};
result.children = [];
if (list.f) {
list.f.forEach(function(f) {
result.children.push({
icon: 'fa fa-file-o',
label: f,
path: root+f
});
});
}
if (list.d) {
for (var l in list.d) {
if (list.d.hasOwnProperty(l)) {
if (root+l !== "_examples_") {
result.children.push(transformFlowList(list.d[l], l,root+l+"/",includeExamples))
} else if (includeExamples) {
result._examples = transformFlowList(list.d[l], l,root+l+"/",includeExamples)
}
}
}
}
result.children.sort(function(A,B){
if (A.children && !B.children) {
return -1;
} else if (!A.children && B.children) {
return 1;
} else {
return A.label.localeCompare(B.label);
}
});
return result;
}
function loadFlowLibrary(browser,includeExamples) {
$.getJSON("library/flows", function(data) {
var listing = [transformFlowList(data,RED._("library.types.local"),"",includeExamples)];
listing[0].expanded = true;
if (includeExamples && listing[0]._examples) {
var examples = listing[0]._examples;
delete listing[0]._examples;
examples.label = RED._("library.types.examples");
examples.icon = "fa fa-archive";
listing.unshift(examples)
}
browser.data(listing);
});
}
function hideDropTarget() { function hideDropTarget() {
$("#dropTarget").hide(); $("#dropTarget").hide();

View File

@ -121,24 +121,41 @@
container.addClass('built'); container.addClass('built');
var childrenAdded = false; var childrenAdded = false;
var spinner; var spinner;
var startTime = 0;
item.children(item,function(children) { item.children(item,function(children) {
childrenAdded = true; childrenAdded = true;
item.treeList.childList = that._addChildren(container,parent,children,depth); item.treeList.childList = that._addChildren(container,item,children,depth).hide();
if (spinner) { var delta = Date.now() - startTime;
spinner.remove(); if (delta < 400) {
setTimeout(function() {
item.treeList.childList.slideDown('fast');
if (spinner) {
spinner.remove();
}
},400-delta);
} else {
item.treeList.childList.slideDown('fast');
if (spinner) {
spinner.remove();
}
} }
that._trigger("childrenloaded",null,item) that._trigger("childrenloaded",null,item)
}); });
if (!childrenAdded) { if (!childrenAdded) {
startTime = Date.now();
spinner = $('<div class="red-ui-treeList-spinner">').css({ spinner = $('<div class="red-ui-treeList-spinner">').css({
"background-position": (35+depth*15)+'px 50%' "background-position": (35+depth*15)+'px 50%'
}).appendTo(container); }).appendTo(container);
} }
} else {
item.treeList.childList.slideDown('fast');
} }
container.addClass("expanded"); container.addClass("expanded");
} }
item.treeList.collapse = function() { item.treeList.collapse = function() {
item.treeList.childList.slideUp('fast');
container.removeClass("expanded"); container.removeClass("expanded");
} }
@ -181,7 +198,7 @@
} }
if (item.children) { if (item.children) {
if (Array.isArray(item.children)) { if (Array.isArray(item.children)) {
item.treeList.childList = that._addChildren(container,item,item.children,depth); item.treeList.childList = that._addChildren(container,item,item.children,depth).hide();
} }
if (item.expanded) { if (item.expanded) {
item.treeList.expand(); item.treeList.expand();

View File

@ -15,16 +15,14 @@
**/ **/
RED.library = (function() { RED.library = (function() {
var exportToLibraryDialog;
var loadLibraryBrowser; var loadLibraryBrowser;
var saveLibraryBrowser; var saveLibraryBrowser;
var libraryEditor; var libraryEditor;
var activeLibrary; var activeLibrary;
var _libraryLookup = '<div id="node-dialog-library-load" class="hide">'+ var _libraryLookup = '<div id="node-dialog-library-load" class="hide">'+
'<form class="form-horizontal">'+ '<form class="form-horizontal">'+
'<div style="height: 500px; position:relative; ">'+ '<div style="height: 400px; position:relative; ">'+
'<div id="node-dialog-library-load-panes">'+ '<div id="node-dialog-library-load-panes">'+
'<div class="red-ui-panel" id="node-dialog-library-load-browser"></div>'+ '<div class="red-ui-panel" id="node-dialog-library-load-browser"></div>'+
'<div class="red-ui-panel">'+ '<div class="red-ui-panel">'+
@ -60,6 +58,7 @@ RED.library = (function() {
} }
var filename = $("#node-dialog-library-save-filename").val().trim() var filename = $("#node-dialog-library-save-filename").val().trim()
var selectedPath = saveLibraryBrowser.getSelected(); var selectedPath = saveLibraryBrowser.getSelected();
console.log(selectedPath);
if (!selectedPath.children) { if (!selectedPath.children) {
selectedPath = selectedPath.parent; selectedPath = selectedPath.parent;
} }
@ -90,9 +89,11 @@ RED.library = (function() {
} }
}); });
} }
if (selectedPath.files) { console.log(filename);
console.log(selectedPath);
if (selectedPath.children) {
var exists = false; var exists = false;
selectedPath.files.forEach(function(f) { selectedPath.children.forEach(function(f) {
if (f.label === filename) { if (f.label === filename) {
exists = true; exists = true;
} }
@ -211,7 +212,7 @@ RED.library = (function() {
loadLibraryFolder(options.url, "", function(items) { loadLibraryFolder(options.url, "", function(items) {
var listing = [{ var listing = [{
icon: 'fa fa-archive', icon: 'fa fa-archive',
label: "Local", label: RED._("library.types.local"),
path: "", path: "",
expanded: true, expanded: true,
writable: false, writable: false,
@ -257,7 +258,7 @@ RED.library = (function() {
loadLibraryFolder(options.url, "", function(items) { loadLibraryFolder(options.url, "", function(items) {
var listing = [{ var listing = [{
icon: 'fa fa-archive', icon: 'fa fa-archive',
label: "Local", label: RED._("library.types.local"),
path: "", path: "",
expanded: true, expanded: true,
writable: false, writable: false,
@ -285,13 +286,6 @@ RED.library = (function() {
function createBrowser(options) { function createBrowser(options) {
var panes = $('<div class="red-ui-library-browser"></div>').appendTo(options.container); var panes = $('<div class="red-ui-library-browser"></div>').appendTo(options.container);
// var dirsPane = $('<div class="red-ui-panel"></div>').appendTo(panes);
// var filesPane = $('<div class="red-ui-panel"></div>').appendTo(panes);
//
// RED.panels.create({
// container:panes,
// dir: "horizontal"
// });
var dirList = $("<div>").css({width: "100%", height: "100%"}).appendTo(panes) var dirList = $("<div>").css({width: "100%", height: "100%"}).appendTo(panes)
.treeList({}).on('treelistselect', function(event, item) { .treeList({}).on('treelistselect', function(event, item) {
if (addButton) { if (addButton) {
@ -307,7 +301,7 @@ RED.library = (function() {
}); });
var addButton; var addButton;
if (options.addFolderButton) { if (options.addFolderButton) {
var tools = $("<div>").css({position: "absolute",bottom:"3px",left:"3px"}).appendTo(panes) var tools = $("<div>").css({position: "absolute",bottom:"3px",right:"25px"}).appendTo(panes)
addButton= $('<button type="button" class="editor-button editor-button-small"><i class="fa fa-plus"> <i class="fa fa-folder-o"></button>').appendTo(tools).click(function(e) { addButton= $('<button type="button" class="editor-button editor-button-small"><i class="fa fa-plus"> <i class="fa fa-folder-o"></button>').appendTo(tools).click(function(e) {
var defaultFolderName = "new-folder"; var defaultFolderName = "new-folder";
var defaultFolderNameMatches = {}; var defaultFolderNameMatches = {};

View File

@ -48,7 +48,7 @@
} }
} }
} }
#clipboard-dialog-export-tab-clipboard { .clipboard-dialog-tab-clipboard {
padding: 10px; padding: 10px;
textarea { textarea {
resize: none; resize: none;
@ -56,7 +56,7 @@
border-radius: 4px; border-radius: 4px;
font-family: monospace !important; font-family: monospace !important;
font-size: 13px !important; font-size: 13px !important;
height: 430px; height: 300px;
line-height: 1.3em; line-height: 1.3em;
padding: 6px 10px; padding: 6px 10px;
background: #F3E7E7; background: #F3E7E7;
@ -64,7 +64,7 @@
} }
} }
#clipboard-dialog-export-tabs-content { .clipboard-dialog-tabs-content {
position: absolute; position: absolute;
top: 0; top: 0;
left: 120px; left: 120px;
@ -72,19 +72,25 @@
bottom: 0; bottom: 0;
padding: 0; padding: 0;
background: white; background: white;
&>div { &>div {
height: calc(100% - 20px) height: calc(100% - 20px)
} }
} }
#clipboard-dialog-export-tab-library { .clipboard-dialog-tab-library {
.form-row { .form-row {
margin-left: 10px; margin-left: 10px;
} }
} }
#clipboard-dialog {
form {
margin-bottom: 0;
}
.form-row:last-child {
margin-bottom: 0;
}
}
#clipboard-dialog-tab-library-name { #clipboard-dialog-tab-library-name {
width: calc(100% - 120px); width: calc(100% - 120px);
} }
@ -94,7 +100,13 @@
border-bottom: 1px solid $primary-border-color; border-bottom: 1px solid $primary-border-color;
box-sizing: border-box; box-sizing: border-box;
} }
#clipboard-dialog-import-tab-library {
height: 100%;
}
#clipboard-dialog-import-tab-library-browser {
height: 100%;
box-sizing: border-box;
}
.red-ui-library-browser { .red-ui-library-browser {

View File

@ -49,18 +49,18 @@
transition: transform 0.1s ease-in-out; transition: transform 0.1s ease-in-out;
} }
.red-ui-editableList { .red-ui-editableList {
display: none; // display: none;
} }
&.expanded { &.expanded {
& > .red-ui-treeList-label .fa-angle-right { & > .red-ui-treeList-label .fa-angle-right {
transform: rotate(90deg) transform: rotate(90deg)
} }
& > .red-ui-editableList { // & > .red-ui-editableList {
display: block // display: block
} // }
& > .red-ui-treeList-spinner { // & > .red-ui-treeList-spinner {
display: block; // display: block;
} // }
} }
} }
} }
@ -108,7 +108,6 @@ label.red-ui-treeList-label {
text-align: center; text-align: center;
} }
.red-ui-treeList-spinner { .red-ui-treeList-spinner {
display: none;
height: 32px; height: 32px;
background: url(images/spin.svg) 50% 50% no-repeat; background: url(images/spin.svg) 50% 50% no-repeat;
background-size: auto 20px; background-size: auto 20px;