@inteli.city/node-red-plugin-project-files 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +64 -0
- package/LICENSE +201 -0
- package/README.md +300 -0
- package/editor/project-files.html +7 -0
- package/package.json +40 -0
- package/resources/project-files/admin-ajax.js +12 -0
- package/resources/project-files/dialogs.js +107 -0
- package/resources/project-files/plugin.js +1675 -0
- package/resources/project-files/prefs.js +11 -0
- package/resources/project-files/rules.js +47 -0
- package/resources/project-files/style.js +492 -0
- package/runtime/admin.js +469 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// dialogs.js — Reusable modal dialog system for the Project Files plugin.
|
|
2
|
+
// Loaded before plugin.js; dsffModal / dsffPrompt / dsffConfirm are plain globals.
|
|
3
|
+
// Feature-level decisions (e.g. "unsaved changes before navigating") stay in plugin.js.
|
|
4
|
+
|
|
5
|
+
var dsffModalSeq = 0;
|
|
6
|
+
|
|
7
|
+
// Low-level modal builder.
|
|
8
|
+
// opts.title – bold heading (optional)
|
|
9
|
+
// opts.body – HTML string (optional)
|
|
10
|
+
// opts.input – { placeholder?, value? } adds a text input
|
|
11
|
+
// opts.buttons – [{ label, cls?, key?: "Enter"|"Escape", action?(val) }]
|
|
12
|
+
function dsffModal(opts) {
|
|
13
|
+
var ns = "dsff-modal-" + (++dsffModalSeq);
|
|
14
|
+
var $overlay = $('<div class="dsff-modal-overlay">').appendTo(document.body);
|
|
15
|
+
var $dlg = $('<div class="dsff-modal">').appendTo($overlay);
|
|
16
|
+
|
|
17
|
+
if (opts.title) $('<div class="dsff-modal-title">').text(opts.title).appendTo($dlg);
|
|
18
|
+
if (opts.body) $('<div class="dsff-modal-body">').html(opts.body).appendTo($dlg);
|
|
19
|
+
|
|
20
|
+
var $input = null;
|
|
21
|
+
if (opts.input) {
|
|
22
|
+
$input = $('<input type="text" class="dsff-modal-input">')
|
|
23
|
+
.attr("placeholder", opts.input.placeholder || "")
|
|
24
|
+
.val(opts.input.value || "");
|
|
25
|
+
$dlg.append($input);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var $btns = $('<div class="dsff-modal-btns">').appendTo($dlg);
|
|
29
|
+
var bmap = {};
|
|
30
|
+
|
|
31
|
+
(opts.buttons || []).forEach(function (b) {
|
|
32
|
+
var $b = $('<button class="red-ui-button">').text(b.label);
|
|
33
|
+
if (b.cls) $b.addClass(b.cls);
|
|
34
|
+
$b.on("click", function () {
|
|
35
|
+
close();
|
|
36
|
+
if (typeof b.action === "function") b.action($input ? $input.val() : undefined);
|
|
37
|
+
});
|
|
38
|
+
$btns.append($b);
|
|
39
|
+
if (b.key) bmap[b.key] = $b;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
function close() {
|
|
43
|
+
$overlay.remove();
|
|
44
|
+
$(document).off("keydown." + ns);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
$overlay.on("click", function (e) {
|
|
48
|
+
if (e.target === $overlay[0]) {
|
|
49
|
+
if (bmap.Escape) bmap.Escape.trigger("click"); else close();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
$(document).on("keydown." + ns, function (e) {
|
|
54
|
+
if (e.key === "Escape") {
|
|
55
|
+
if (bmap.Escape) bmap.Escape.trigger("click"); else close();
|
|
56
|
+
} else if (e.key === "Enter" && (!$input || document.activeElement === $input[0])) {
|
|
57
|
+
e.preventDefault();
|
|
58
|
+
if (bmap.Enter) bmap.Enter.trigger("click");
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
setTimeout(function () {
|
|
63
|
+
if ($input) { $input.focus(); $input[0].select(); }
|
|
64
|
+
else if (bmap.Enter) bmap.Enter.focus();
|
|
65
|
+
}, 0);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Text-input prompt.
|
|
69
|
+
// opts: { title, body?, placeholder?, value?, confirmLabel?, onConfirm }
|
|
70
|
+
function dsffPrompt(opts) {
|
|
71
|
+
dsffModal({
|
|
72
|
+
title: opts.title,
|
|
73
|
+
body: opts.body || null,
|
|
74
|
+
input: { placeholder: opts.placeholder || "", value: opts.value || "" },
|
|
75
|
+
buttons: [
|
|
76
|
+
{ label: "Cancel", key: "Escape" },
|
|
77
|
+
{ label: opts.confirmLabel || "OK",
|
|
78
|
+
cls: "dsff-modal-btn-primary",
|
|
79
|
+
key: "Enter",
|
|
80
|
+
action: function (val) {
|
|
81
|
+
var v = (val || "").trim();
|
|
82
|
+
if (v) opts.onConfirm(v);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Confirmation dialog.
|
|
90
|
+
// opts: { title, body, confirmLabel?, cancelLabel?, danger?, onConfirm, onCancel? }
|
|
91
|
+
function dsffConfirm(opts) {
|
|
92
|
+
dsffModal({
|
|
93
|
+
title: opts.title,
|
|
94
|
+
body: opts.body,
|
|
95
|
+
buttons: [
|
|
96
|
+
{ label: opts.cancelLabel || "Cancel",
|
|
97
|
+
key: "Escape",
|
|
98
|
+
action: opts.onCancel
|
|
99
|
+
},
|
|
100
|
+
{ label: opts.confirmLabel || "Confirm",
|
|
101
|
+
cls: opts.danger ? "dsff-modal-btn-danger" : "dsff-modal-btn-primary",
|
|
102
|
+
key: "Enter",
|
|
103
|
+
action: opts.onConfirm
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
});
|
|
107
|
+
}
|