@qarakash/blockwriteai 1.0.9 → 1.0.11
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/README.md +176 -601
- package/dist/blockwriteai.min.css +1 -0
- package/dist/blockwriteai.min.js +1 -0
- package/dist/plugins/blockwriteai-advanced-blocks.min.js +1 -0
- package/dist/plugins/blockwriteai-ai.min.js +1 -0
- package/dist/plugins/blockwriteai-code-assist.min.js +1 -0
- package/dist/plugins/blockwriteai-drawing.min.js +1 -0
- package/dist/plugins/blockwriteai-history.min.js +1 -0
- package/dist/plugins/blockwriteai-mermaid.min.js +1 -0
- package/dist/plugins/blockwriteai-signature-flow.min.js +1 -0
- package/dist/plugins/blockwriteai-signature.min.js +1 -0
- package/package.json +26 -18
- package/types/index.d.ts +7 -1
- package/dist/blockwriteai.css +0 -3762
- package/dist/blockwriteai.js +0 -6771
- package/dist/plugins/blockwriteai-advanced-blocks.js +0 -2282
- package/dist/plugins/blockwriteai-ai.js +0 -671
- package/dist/plugins/blockwriteai-code-assist.js +0 -609
- package/dist/plugins/blockwriteai-drawing.js +0 -178
- package/dist/plugins/blockwriteai-history.js +0 -23
- package/dist/plugins/blockwriteai-mermaid.js +0 -1986
- package/dist/plugins/blockwriteai-signature-flow.js +0 -493
- package/dist/plugins/blockwriteai-signature.js +0 -463
|
@@ -1,493 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* BlockWriteAI Signature Flow Plugin
|
|
3
|
-
* Adds optional sequential multi-signer signature flows.
|
|
4
|
-
*/
|
|
5
|
-
(function (global) {
|
|
6
|
-
"use strict";
|
|
7
|
-
|
|
8
|
-
var BlockWriteAI = global.BlockWriteAI;
|
|
9
|
-
if (!BlockWriteAI || BlockWriteAI.__signatureFlowPluginInstalled) return;
|
|
10
|
-
BlockWriteAI.__signatureFlowPluginInstalled = true;
|
|
11
|
-
|
|
12
|
-
var H = BlockWriteAI.helpers || {};
|
|
13
|
-
var el = H.el;
|
|
14
|
-
var esc = H.escapeHTML || function (value) {
|
|
15
|
-
return String(value == null ? "" : value).replace(/[&<>"]/g, function (ch) {
|
|
16
|
-
return { "&": "&", "<": "<", ">": ">", '"': """ }[ch];
|
|
17
|
-
});
|
|
18
|
-
};
|
|
19
|
-
var faIcon = H.faIcon || function (name, label) {
|
|
20
|
-
return '<i class="fa-solid fa-' + esc(name) + '" aria-hidden="true"></i><span class="rbe-sr-only">' + esc(label || name) + "</span>";
|
|
21
|
-
};
|
|
22
|
-
var uid = H.uid || function (prefix) {
|
|
23
|
-
return (prefix || "signature-flow") + "-" + Math.random().toString(36).slice(2, 9);
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
function pluginAsset(path) {
|
|
27
|
-
try {
|
|
28
|
-
var base = (document.currentScript && document.currentScript.src) || document.baseURI;
|
|
29
|
-
return new URL(path, base).href;
|
|
30
|
-
} catch (error) {
|
|
31
|
-
return path;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
var LOGO_URL = pluginAsset("../blockwriteai-logo.svg");
|
|
36
|
-
var STORAGE_PREFIX = "blockwriteai-signature-flow:";
|
|
37
|
-
|
|
38
|
-
function injectStyles() {
|
|
39
|
-
if (document.querySelector("style[data-blockwriteai-signature-flow-plugin]")) return;
|
|
40
|
-
var style = document.createElement("style");
|
|
41
|
-
style.dataset.blockwriteaiSignatureFlowPlugin = "true";
|
|
42
|
-
style.textContent =
|
|
43
|
-
".rbe-signature-flow-editor{border:1px solid #d7dee8;border-radius:8px;background:#fff;padding:14px;display:grid;gap:12px;}" +
|
|
44
|
-
".rbe-signature-flow-top{display:flex;justify-content:space-between;align-items:center;gap:10px;}" +
|
|
45
|
-
".rbe-signature-flow-top strong{font:800 14px/1.3 Arial,sans-serif;color:#344054;}" +
|
|
46
|
-
".rbe-signature-flow-steps{display:grid;gap:8px;}" +
|
|
47
|
-
".rbe-signature-flow-step{display:grid;grid-template-columns:auto minmax(160px,1fr) auto;gap:8px;align-items:center;border:1px solid #e2e8f0;border-radius:8px;background:#fbfdff;padding:8px;}" +
|
|
48
|
-
".rbe-signature-flow-index{width:28px;height:28px;border-radius:999px;background:#eaf1ff;color:#1d4ed8;display:grid;place-items:center;font:800 12px/1 Arial,sans-serif;}" +
|
|
49
|
-
".rbe-signature-flow-step input{width:100%;border:1px solid #d7dee8;border-radius:8px;background:#fff;color:#172033;font:14px/1.4 Arial,sans-serif;padding:9px 10px;}" +
|
|
50
|
-
".rbe-signature-flow-add,.rbe-signature-flow-remove{border:1px solid #d7dee8;border-radius:8px;background:#fff;color:#344054;min-width:34px;height:34px;display:inline-grid;place-items:center;cursor:pointer;}" +
|
|
51
|
-
".rbe-signature-flow-add:hover{border-color:#16a34a;background:#ecfdf3;color:#07845f;}" +
|
|
52
|
-
".rbe-signature-flow-remove:hover{border-color:#dc2626;background:#fef2f2;color:#b42318;}" +
|
|
53
|
-
".rbe-output-signature-flow{display:grid;gap:12px;margin:0 0 15px;}" +
|
|
54
|
-
".rbe-output-signature-flow-title{font:800 15px/1.35 Arial,sans-serif;color:#172033;}" +
|
|
55
|
-
".rbe-flow-signature-track{display:flex;flex-wrap:wrap;align-items:stretch;justify-content:center;gap:10px 8px;}" +
|
|
56
|
-
".rbe-flow-signature-card{position:relative;overflow:visible;container-type:inline-size;border:1px solid #d7dee8;border-radius:8px;background:#fff;padding:10px;display:grid;gap:8px;flex:1 1 170px;min-width:150px;max-width:230px;min-height:126px;box-sizing:border-box;}" +
|
|
57
|
-
".rbe-flow-signature-card.is-locked{opacity:.68;}" +
|
|
58
|
-
".rbe-flow-signature-watermark{position:absolute;left:50%;top:52%;width:min(140px,76%);max-height:82px;object-fit:contain;opacity:.14;transform:translate(-50%,-50%);pointer-events:none;user-select:none;}" +
|
|
59
|
-
".rbe-flow-signature-seal{position:absolute;right:10px;top:8px;z-index:4;width:34px;height:34px;background:#d40000;color:#fff;display:none;place-items:center;padding:0;border-radius:4px;box-shadow:0 8px 14px rgba(160,0,0,.2);pointer-events:none;}" +
|
|
60
|
-
".rbe-flow-signature-card[data-signed='true'] .rbe-flow-signature-seal{display:grid;}" +
|
|
61
|
-
".rbe-flow-signature-seal-logo{display:block;width:25px;height:25px;}" +
|
|
62
|
-
".rbe-flow-signature-head{position:relative;z-index:1;display:grid;gap:6px;font:800 13px/1.3 Arial,sans-serif;color:#344054;}" +
|
|
63
|
-
".rbe-flow-signature-label{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}" +
|
|
64
|
-
".rbe-flow-signature-status{justify-self:start;border-radius:999px;background:#fffbeb;color:#b45309;padding:4px 7px;font-size:10px;line-height:1;font-weight:800;white-space:nowrap;}" +
|
|
65
|
-
".rbe-flow-signature-card.is-signed{border-color:#86efac;background:#f0fdf4;}" +
|
|
66
|
-
".rbe-flow-signature-card.is-signed .rbe-flow-signature-status{background:#dcfce7;color:#07845f;}" +
|
|
67
|
-
".rbe-flow-signature-card.is-locked .rbe-flow-signature-status{background:#fef3c7;color:#92400e;}" +
|
|
68
|
-
".rbe-flow-signature-connector{align-self:center;display:inline-flex;align-items:center;justify-content:center;flex:0 0 30px;min-height:34px;color:#b45309;font:900 18px/1 Arial,sans-serif;}" +
|
|
69
|
-
".rbe-flow-signature-connector::before{content:'\\2192';}" +
|
|
70
|
-
".rbe-flow-signature-connector.is-complete{color:#16a34a;}" +
|
|
71
|
-
".rbe-flow-signature-connector.is-pending{color:#d97706;}" +
|
|
72
|
-
".rbe-flow-signature-unsigned{position:relative;z-index:1;display:grid;grid-template-columns:1fr;gap:7px;align-items:center;width:100%;margin:0;}" +
|
|
73
|
-
".rbe-flow-signature-input{width:100%;min-width:0;min-height:38px;border:1px solid #cbd5e1;border-radius:8px;background:#fff;color:#111827;font:15px/1.2 'Brush Script MT','Segoe Script','Lucida Handwriting',cursive;padding:7px 9px;text-align:center;box-sizing:border-box;}" +
|
|
74
|
-
".rbe-flow-signature-input::placeholder{color:#98a2b3;font:13px/1.35 Arial,sans-serif;}" +
|
|
75
|
-
".rbe-flow-signature-apply{border:1px solid #1d4ed8;border-radius:8px;background:#2563eb;color:#fff;font:800 13px/1 Arial,sans-serif;padding:9px 10px;cursor:pointer;}" +
|
|
76
|
-
".rbe-flow-signature-apply:disabled,.rbe-flow-signature-input:disabled{cursor:not-allowed;opacity:.7;}" +
|
|
77
|
-
".rbe-flow-signature-card.has-error .rbe-flow-signature-input{border-color:#dc2626;box-shadow:0 0 0 3px rgba(220,38,38,.12);}" +
|
|
78
|
-
".rbe-flow-signature-signed{position:relative;z-index:1;display:grid;gap:5px;align-items:center;}" +
|
|
79
|
-
".rbe-flow-signature-signed[hidden],.rbe-flow-signature-unsigned[hidden]{display:none!important;}" +
|
|
80
|
-
".rbe-flow-signature-name{min-width:0;font-family:'Brush Script MT','Segoe Script','Lucida Handwriting',cursive;font-size:15px;line-height:1.1;color:#050505;overflow-wrap:anywhere;}" +
|
|
81
|
-
".rbe-flow-signature-meta{min-width:0;font-family:Arial,sans-serif;font-size:12px;line-height:1.2;color:#050505;display:grid;gap:2px;overflow-wrap:anywhere;}" +
|
|
82
|
-
".rbe-flow-signature-meta strong{font-weight:500;}" +
|
|
83
|
-
".rbe-flow-signature-meta strong,.rbe-flow-signature-meta span,.rbe-flow-signature-meta time{min-width:0;overflow-wrap:anywhere;}" +
|
|
84
|
-
".rbe-flow-signature-card.is-compact{padding:8px;gap:6px;}" +
|
|
85
|
-
".rbe-flow-signature-card.is-compact .rbe-flow-signature-name{font-size:15px;}" +
|
|
86
|
-
".rbe-flow-signature-card.is-compact .rbe-flow-signature-meta{font-size:11px;line-height:1.22;}" +
|
|
87
|
-
".rbe-flow-signature-card.is-compact .rbe-flow-signature-seal{right:7px;top:7px;width:30px;height:30px;}" +
|
|
88
|
-
".rbe-flow-signature-card.is-compact .rbe-flow-signature-seal-logo{width:22px;height:22px;}" +
|
|
89
|
-
"@container (max-width:180px){.rbe-flow-signature-meta{font-size:11px;}.rbe-flow-signature-name{font-size:14px;}}" +
|
|
90
|
-
"@media (max-width:720px){.rbe-signature-flow-step{grid-template-columns:1fr;}.rbe-signature-flow-index{width:100%;border-radius:8px;}.rbe-flow-signature-card{flex-basis:150px;}.rbe-flow-signature-connector{flex-basis:24px;}}";
|
|
91
|
-
document.head.appendChild(style);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function cleanText(value) {
|
|
95
|
-
return String(value == null ? "" : value).trim();
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function sealHTML(className) {
|
|
99
|
-
return (
|
|
100
|
-
'<span class="' +
|
|
101
|
-
esc(className) +
|
|
102
|
-
'" aria-hidden="true"><svg class="' +
|
|
103
|
-
esc(className + "-logo") +
|
|
104
|
-
'" viewBox="0 0 32 32" role="img" focusable="false"><path d="M7 4h12l6 6v15a3 3 0 0 1-3 3H10a3 3 0 0 1-3-3z" fill="#fff"/><path d="M19 4v6h6" fill="#ffe5e5"/><path d="M10 23c2-4 3-4 4 0 1-2 2-2 3 0 1-1 2-1 4 0" fill="none" stroke="#d40000" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/><path d="M22.5 17.5l4.6-4.6 2 2-4.6 4.6-3 .9z" fill="#fff"/><path d="M26.3 13.7l2 2" fill="none" stroke="#d40000" stroke-width="1.1" stroke-linecap="round"/></svg></span>'
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function formatSignatureDate(date) {
|
|
109
|
-
var pad = function (value) { return String(value).padStart(2, "0"); };
|
|
110
|
-
var offset = -date.getTimezoneOffset();
|
|
111
|
-
var sign = offset >= 0 ? "+" : "-";
|
|
112
|
-
var abs = Math.abs(offset);
|
|
113
|
-
return date.getFullYear() + "." + pad(date.getMonth() + 1) + "." + pad(date.getDate()) + " " + pad(date.getHours()) + ":" + pad(date.getMinutes()) + ":" + pad(date.getSeconds()) + " " + sign + pad(Math.floor(abs / 60)) + "'" + pad(abs % 60) + "'";
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function storageKey(flowId, stepId) {
|
|
117
|
-
return STORAGE_PREFIX + flowId + ":" + stepId;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function readStored(flowId, stepId) {
|
|
121
|
-
try {
|
|
122
|
-
return JSON.parse(localStorage.getItem(storageKey(flowId, stepId)) || "null");
|
|
123
|
-
} catch (error) {
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function saveStored(flowId, stepId, record) {
|
|
129
|
-
try {
|
|
130
|
-
localStorage.setItem(storageKey(flowId, stepId), JSON.stringify(record));
|
|
131
|
-
} catch (error) {
|
|
132
|
-
// Best-effort local preview storage.
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function normalizeSteps(steps) {
|
|
137
|
-
var list = Array.isArray(steps) ? steps : [];
|
|
138
|
-
if (!list.length) {
|
|
139
|
-
list = [
|
|
140
|
-
{ id: uid("signer"), label: "Signer 1" },
|
|
141
|
-
{ id: uid("signer"), label: "Signer 2" },
|
|
142
|
-
{ id: uid("signer"), label: "Signer 3" }
|
|
143
|
-
];
|
|
144
|
-
}
|
|
145
|
-
return list.map(function (step, index) {
|
|
146
|
-
step = step || {};
|
|
147
|
-
return {
|
|
148
|
-
id: step.id || uid("signer"),
|
|
149
|
-
label: cleanText(step.label) || "Signer " + (index + 1)
|
|
150
|
-
};
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function createEditorStep(editor, step, index) {
|
|
155
|
-
var row = el("div", "rbe-signature-flow-step", { dataset: { stepId: step.id || uid("signer") } });
|
|
156
|
-
row.appendChild(el("span", "rbe-signature-flow-index", { text: index + 1 }));
|
|
157
|
-
row.appendChild(
|
|
158
|
-
el("input", "rbe-signature-flow-label", {
|
|
159
|
-
type: "text",
|
|
160
|
-
value: step.label || "Signer " + (index + 1),
|
|
161
|
-
placeholder: "Signer name or role",
|
|
162
|
-
disabled: editor.readOnly
|
|
163
|
-
})
|
|
164
|
-
);
|
|
165
|
-
row.appendChild(
|
|
166
|
-
el("button", "rbe-signature-flow-remove", {
|
|
167
|
-
type: "button",
|
|
168
|
-
title: "Remove signer",
|
|
169
|
-
"aria-label": "Remove signer",
|
|
170
|
-
html: faIcon("trash-can", "Remove signer"),
|
|
171
|
-
disabled: editor.readOnly
|
|
172
|
-
})
|
|
173
|
-
);
|
|
174
|
-
return row;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
function refreshEditorStepNumbers(wrap) {
|
|
178
|
-
Array.prototype.slice.call(wrap.querySelectorAll(".rbe-signature-flow-step")).forEach(function (row, index) {
|
|
179
|
-
var badge = row.querySelector(".rbe-signature-flow-index");
|
|
180
|
-
if (badge) badge.textContent = index + 1;
|
|
181
|
-
var input = row.querySelector(".rbe-signature-flow-label");
|
|
182
|
-
if (input && !cleanText(input.value)) input.placeholder = "Signer " + (index + 1);
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function createFlowConnector() {
|
|
187
|
-
var connector = document.createElement("span");
|
|
188
|
-
connector.className = "rbe-flow-signature-connector is-pending";
|
|
189
|
-
connector.setAttribute("aria-hidden", "true");
|
|
190
|
-
return connector;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function refreshFlowConnectors(track) {
|
|
194
|
-
if (!track) return [];
|
|
195
|
-
Array.prototype.slice.call(track.querySelectorAll(".rbe-flow-signature-connector")).forEach(function (connector) {
|
|
196
|
-
connector.remove();
|
|
197
|
-
});
|
|
198
|
-
var cards = Array.prototype.slice.call(track.children).filter(function (child) {
|
|
199
|
-
return child.classList && child.classList.contains("rbe-flow-signature-card");
|
|
200
|
-
});
|
|
201
|
-
cards.forEach(function (card, index) {
|
|
202
|
-
if (index < cards.length - 1) {
|
|
203
|
-
track.insertBefore(createFlowConnector(), card.nextSibling);
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
return cards;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
function ensureFlowTrack(flow) {
|
|
210
|
-
var track = null;
|
|
211
|
-
Array.prototype.slice.call(flow.children).some(function (child) {
|
|
212
|
-
if (child.classList && child.classList.contains("rbe-flow-signature-track")) {
|
|
213
|
-
track = child;
|
|
214
|
-
return true;
|
|
215
|
-
}
|
|
216
|
-
return false;
|
|
217
|
-
});
|
|
218
|
-
if (!track) {
|
|
219
|
-
track = document.createElement("div");
|
|
220
|
-
track.className = "rbe-flow-signature-track";
|
|
221
|
-
var title = flow.querySelector(".rbe-output-signature-flow-title");
|
|
222
|
-
if (title && title.parentNode === flow) {
|
|
223
|
-
flow.insertBefore(track, title.nextSibling);
|
|
224
|
-
} else {
|
|
225
|
-
flow.appendChild(track);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
Array.prototype.slice.call(flow.children).forEach(function (child) {
|
|
229
|
-
if (child !== track && child.classList && child.classList.contains("rbe-flow-signature-card")) {
|
|
230
|
-
track.appendChild(child);
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
refreshFlowConnectors(track);
|
|
234
|
-
return track;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
function applySignedStep(card, record) {
|
|
238
|
-
if (!card || !record || !record.name) return;
|
|
239
|
-
card.classList.add("is-signed");
|
|
240
|
-
card.classList.remove("is-locked", "has-error");
|
|
241
|
-
card.dataset.signed = "true";
|
|
242
|
-
var unsigned = card.querySelector(".rbe-flow-signature-unsigned");
|
|
243
|
-
var signed = card.querySelector(".rbe-flow-signature-signed");
|
|
244
|
-
var status = card.querySelector(".rbe-flow-signature-status");
|
|
245
|
-
var name = card.querySelector(".rbe-flow-signature-name");
|
|
246
|
-
var by = card.querySelector(".rbe-flow-signature-by-name");
|
|
247
|
-
var time = card.querySelector(".rbe-flow-signature-date");
|
|
248
|
-
var input = card.querySelector(".rbe-flow-signature-input");
|
|
249
|
-
if (input) {
|
|
250
|
-
input.value = record.name;
|
|
251
|
-
input.readOnly = true;
|
|
252
|
-
}
|
|
253
|
-
if (unsigned) unsigned.hidden = true;
|
|
254
|
-
if (signed) signed.hidden = false;
|
|
255
|
-
if (status) status.textContent = "Signed";
|
|
256
|
-
if (name) name.textContent = record.name;
|
|
257
|
-
if (by) by.textContent = record.name;
|
|
258
|
-
if (time) {
|
|
259
|
-
time.textContent = record.dateLabel || formatSignatureDate(new Date(record.date || Date.now()));
|
|
260
|
-
if (record.date) time.setAttribute("datetime", record.date);
|
|
261
|
-
}
|
|
262
|
-
syncFlowCardSize(card);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
function syncFlowCardSize(card) {
|
|
266
|
-
if (!card || !card.getBoundingClientRect) return;
|
|
267
|
-
var width = card.getBoundingClientRect().width;
|
|
268
|
-
card.classList.toggle("is-compact", width > 0 && width < 190);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
function observeFlowCard(card) {
|
|
272
|
-
if (!card || card.dataset.flowCardResizeObserved === "true") return;
|
|
273
|
-
card.dataset.flowCardResizeObserved = "true";
|
|
274
|
-
syncFlowCardSize(card);
|
|
275
|
-
if (typeof ResizeObserver === "undefined") {
|
|
276
|
-
window.addEventListener("resize", function () {
|
|
277
|
-
syncFlowCardSize(card);
|
|
278
|
-
});
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
var observer = new ResizeObserver(function () {
|
|
282
|
-
syncFlowCardSize(card);
|
|
283
|
-
});
|
|
284
|
-
observer.observe(card);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
function updateFlowLocks(flow) {
|
|
288
|
-
var track = ensureFlowTrack(flow);
|
|
289
|
-
var cards = Array.prototype.slice.call(track.querySelectorAll(".rbe-flow-signature-card"));
|
|
290
|
-
var connectors = Array.prototype.slice.call(track.querySelectorAll(".rbe-flow-signature-connector"));
|
|
291
|
-
var previousSigned = true;
|
|
292
|
-
cards.forEach(function (card, index) {
|
|
293
|
-
var isSigned = card.dataset.signed === "true";
|
|
294
|
-
var unlocked = previousSigned || isSigned;
|
|
295
|
-
card.classList.toggle("is-locked", !unlocked);
|
|
296
|
-
card.classList.toggle("is-active", unlocked && !isSigned);
|
|
297
|
-
card.classList.toggle("is-pending", !isSigned);
|
|
298
|
-
var input = card.querySelector(".rbe-flow-signature-input");
|
|
299
|
-
var button = card.querySelector(".rbe-flow-signature-apply");
|
|
300
|
-
var status = card.querySelector(".rbe-flow-signature-status");
|
|
301
|
-
if (!isSigned) {
|
|
302
|
-
if (input) input.disabled = !unlocked;
|
|
303
|
-
if (button) button.disabled = !unlocked;
|
|
304
|
-
if (status) status.textContent = unlocked ? "Ready to sign" : "Pending";
|
|
305
|
-
}
|
|
306
|
-
if (connectors[index]) {
|
|
307
|
-
connectors[index].classList.toggle("is-complete", isSigned);
|
|
308
|
-
connectors[index].classList.toggle("is-pending", !isSigned);
|
|
309
|
-
}
|
|
310
|
-
previousSigned = isSigned;
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
function signFlowStep(card) {
|
|
315
|
-
if (!card || card.classList.contains("is-locked")) return;
|
|
316
|
-
var input = card.querySelector(".rbe-flow-signature-input");
|
|
317
|
-
var name = cleanText(input && input.value);
|
|
318
|
-
if (!name) {
|
|
319
|
-
card.classList.add("has-error");
|
|
320
|
-
if (input) input.focus();
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
var now = new Date();
|
|
324
|
-
var record = {
|
|
325
|
-
name: name,
|
|
326
|
-
date: now.toISOString(),
|
|
327
|
-
dateLabel: formatSignatureDate(now)
|
|
328
|
-
};
|
|
329
|
-
var flow = card.closest(".rbe-output-signature-flow");
|
|
330
|
-
saveStored(flow.dataset.flowId || "", card.dataset.stepId || "", record);
|
|
331
|
-
applySignedStep(card, record);
|
|
332
|
-
updateFlowLocks(flow);
|
|
333
|
-
card.dispatchEvent(new CustomEvent("blockwriteai:signature-flow-signed", { bubbles: true, detail: record }));
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
function initFlowOutputs(root) {
|
|
337
|
-
injectStyles();
|
|
338
|
-
Array.prototype.slice.call((root || document).querySelectorAll(".rbe-output-signature-flow")).forEach(function (flow) {
|
|
339
|
-
if (flow.dataset.flowReady === "true") return;
|
|
340
|
-
flow.dataset.flowReady = "true";
|
|
341
|
-
var flowId = flow.dataset.flowId || uid("signature-flow");
|
|
342
|
-
flow.dataset.flowId = flowId;
|
|
343
|
-
ensureFlowTrack(flow);
|
|
344
|
-
Array.prototype.slice.call(flow.querySelectorAll(".rbe-flow-signature-card")).forEach(function (card) {
|
|
345
|
-
observeFlowCard(card);
|
|
346
|
-
var stepId = card.dataset.stepId || uid("signer");
|
|
347
|
-
card.dataset.stepId = stepId;
|
|
348
|
-
var stored = readStored(flowId, stepId);
|
|
349
|
-
if (stored && stored.name) applySignedStep(card, stored);
|
|
350
|
-
var input = card.querySelector(".rbe-flow-signature-input");
|
|
351
|
-
var button = card.querySelector(".rbe-flow-signature-apply");
|
|
352
|
-
if (button) {
|
|
353
|
-
button.addEventListener("click", function () {
|
|
354
|
-
signFlowStep(card);
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
if (input) {
|
|
358
|
-
input.addEventListener("input", function () {
|
|
359
|
-
card.classList.remove("has-error");
|
|
360
|
-
});
|
|
361
|
-
input.addEventListener("keydown", function (event) {
|
|
362
|
-
if (event.key === "Enter") {
|
|
363
|
-
event.preventDefault();
|
|
364
|
-
signFlowStep(card);
|
|
365
|
-
}
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
});
|
|
369
|
-
updateFlowLocks(flow);
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
injectStyles();
|
|
374
|
-
|
|
375
|
-
BlockWriteAI.registerTool("signatureFlow", {
|
|
376
|
-
label: "Signature Flow",
|
|
377
|
-
hint: "Sequential signer approvals",
|
|
378
|
-
icon: "people-arrows",
|
|
379
|
-
premiumFeature: "signature_flow",
|
|
380
|
-
defaultData: function () {
|
|
381
|
-
return {
|
|
382
|
-
flowId: uid("signature-flow"),
|
|
383
|
-
title: "Signature Flow",
|
|
384
|
-
steps: normalizeSteps()
|
|
385
|
-
};
|
|
386
|
-
},
|
|
387
|
-
render: function (body, data) {
|
|
388
|
-
injectStyles();
|
|
389
|
-
data = data || {};
|
|
390
|
-
var wrap = el("div", "rbe-signature-flow-editor", { dataset: { flowId: data.flowId || uid("signature-flow") } });
|
|
391
|
-
var top = el("div", "rbe-signature-flow-top");
|
|
392
|
-
top.appendChild(el("strong", "", { text: "Signature Flow" }));
|
|
393
|
-
top.appendChild(
|
|
394
|
-
el("button", "rbe-signature-flow-add", {
|
|
395
|
-
type: "button",
|
|
396
|
-
title: "Add signer",
|
|
397
|
-
"aria-label": "Add signer",
|
|
398
|
-
html: faIcon("circle-plus", "Add signer"),
|
|
399
|
-
disabled: this.readOnly
|
|
400
|
-
})
|
|
401
|
-
);
|
|
402
|
-
wrap.appendChild(top);
|
|
403
|
-
var stepsWrap = el("div", "rbe-signature-flow-steps");
|
|
404
|
-
normalizeSteps(data.steps).forEach(function (step, index) {
|
|
405
|
-
stepsWrap.appendChild(createEditorStep(this, step, index));
|
|
406
|
-
}, this);
|
|
407
|
-
wrap.appendChild(stepsWrap);
|
|
408
|
-
body.appendChild(wrap);
|
|
409
|
-
|
|
410
|
-
var editor = this;
|
|
411
|
-
var addButton = wrap.querySelector(".rbe-signature-flow-add");
|
|
412
|
-
if (addButton) {
|
|
413
|
-
addButton.addEventListener("click", function () {
|
|
414
|
-
var index = stepsWrap.querySelectorAll(".rbe-signature-flow-step").length;
|
|
415
|
-
stepsWrap.appendChild(createEditorStep(editor, { id: uid("signer"), label: "Signer " + (index + 1) }, index));
|
|
416
|
-
refreshEditorStepNumbers(wrap);
|
|
417
|
-
if (editor && typeof editor.changed === "function") editor.changed(true);
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
stepsWrap.addEventListener("click", function (event) {
|
|
421
|
-
var remove = event.target.closest(".rbe-signature-flow-remove");
|
|
422
|
-
if (!remove || editor.readOnly) return;
|
|
423
|
-
var rows = stepsWrap.querySelectorAll(".rbe-signature-flow-step");
|
|
424
|
-
if (rows.length <= 1) return;
|
|
425
|
-
remove.closest(".rbe-signature-flow-step").remove();
|
|
426
|
-
refreshEditorStepNumbers(wrap);
|
|
427
|
-
if (editor && typeof editor.changed === "function") editor.changed(true);
|
|
428
|
-
});
|
|
429
|
-
},
|
|
430
|
-
serialize: function (block) {
|
|
431
|
-
var wrap = block.querySelector(".rbe-signature-flow-editor");
|
|
432
|
-
return {
|
|
433
|
-
flowId: (wrap && wrap.dataset.flowId) || uid("signature-flow"),
|
|
434
|
-
title: "Signature Flow",
|
|
435
|
-
steps: Array.prototype.slice.call(block.querySelectorAll(".rbe-signature-flow-step")).map(function (row, index) {
|
|
436
|
-
return {
|
|
437
|
-
id: row.dataset.stepId || uid("signer"),
|
|
438
|
-
label: cleanText((row.querySelector(".rbe-signature-flow-label") || {}).value) || "Signer " + (index + 1)
|
|
439
|
-
};
|
|
440
|
-
})
|
|
441
|
-
};
|
|
442
|
-
},
|
|
443
|
-
toHTML: function (data) {
|
|
444
|
-
injectStyles();
|
|
445
|
-
data = data || {};
|
|
446
|
-
var flowId = data.flowId || uid("signature-flow");
|
|
447
|
-
var steps = normalizeSteps(data.steps);
|
|
448
|
-
return (
|
|
449
|
-
'<section class="rbe-output-signature-flow" data-flow-id="' +
|
|
450
|
-
esc(flowId) +
|
|
451
|
-
'"><div class="rbe-output-signature-flow-title">Signature Flow</div><div class="rbe-flow-signature-track">' +
|
|
452
|
-
steps.map(function (step, index) {
|
|
453
|
-
return (
|
|
454
|
-
'<section class="rbe-flow-signature-card" data-step-id="' +
|
|
455
|
-
esc(step.id) +
|
|
456
|
-
'" data-signed="false">' +
|
|
457
|
-
sealHTML("rbe-flow-signature-seal") +
|
|
458
|
-
'<img class="rbe-flow-signature-watermark" src="' +
|
|
459
|
-
esc(LOGO_URL) +
|
|
460
|
-
'" alt="" aria-hidden="true"><div class="rbe-flow-signature-head"><span class="rbe-flow-signature-label">' +
|
|
461
|
-
esc(index + 1 + ". " + step.label) +
|
|
462
|
-
'</span><span class="rbe-flow-signature-status">Waiting</span></div><div class="rbe-flow-signature-unsigned"><input class="rbe-flow-signature-input" type="text" autocomplete="name" placeholder="Enter your name here..."><button type="button" class="rbe-flow-signature-apply">' +
|
|
463
|
-
faIcon("file-signature", "Sign") +
|
|
464
|
-
'<span>Sign</span></button></div><div class="rbe-flow-signature-signed" hidden><div class="rbe-flow-signature-name"></div><div class="rbe-flow-signature-meta"><strong>Digitally signed by <span class="rbe-flow-signature-by-name"></span></strong><span>Date: <time class="rbe-flow-signature-date"></time></span></div></div></section>' +
|
|
465
|
-
(index < steps.length - 1 ? '<span class="rbe-flow-signature-connector is-pending" aria-hidden="true"></span>' : "")
|
|
466
|
-
);
|
|
467
|
-
}).join("") +
|
|
468
|
-
"</div></section>"
|
|
469
|
-
);
|
|
470
|
-
},
|
|
471
|
-
toMarkdown: function (data) {
|
|
472
|
-
return "Signature Flow\n" + normalizeSteps(data && data.steps).map(function (step, index) {
|
|
473
|
-
return index + 1 + ". " + step.label;
|
|
474
|
-
}).join("\n");
|
|
475
|
-
}
|
|
476
|
-
});
|
|
477
|
-
|
|
478
|
-
global.BlockWriteAISignatureFlow = {
|
|
479
|
-
init: initFlowOutputs,
|
|
480
|
-
sign: signFlowStep,
|
|
481
|
-
update: updateFlowLocks
|
|
482
|
-
};
|
|
483
|
-
|
|
484
|
-
if (document.readyState === "loading") {
|
|
485
|
-
document.addEventListener("DOMContentLoaded", function () {
|
|
486
|
-
initFlowOutputs(document);
|
|
487
|
-
});
|
|
488
|
-
} else {
|
|
489
|
-
setTimeout(function () {
|
|
490
|
-
initFlowOutputs(document);
|
|
491
|
-
}, 0);
|
|
492
|
-
}
|
|
493
|
-
})(typeof window !== "undefined" ? window : this);
|