@fayz-ai/plugin-forms 0.8.0 → 0.8.1
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/dist/{FormBuilder-KDANEL6Z.js → FormBuilder-7SWZQKFN.js} +130 -23
- package/dist/FormBuilder-7SWZQKFN.js.map +1 -0
- package/dist/{FormBuilder-4VKYVZAC.cjs → FormBuilder-YB75LEEH.cjs} +129 -22
- package/dist/FormBuilder-YB75LEEH.cjs.map +1 -0
- package/dist/agent-tools.d.ts +4 -0
- package/dist/agent-tools.d.ts.map +1 -0
- package/dist/chunk-QM2AF3DZ.cjs +446 -0
- package/dist/chunk-QM2AF3DZ.cjs.map +1 -0
- package/dist/chunk-W2ZNJGQC.js +438 -0
- package/dist/chunk-W2ZNJGQC.js.map +1 -0
- package/dist/components/DocumentFormDialog.d.ts +3 -1
- package/dist/components/DocumentFormDialog.d.ts.map +1 -1
- package/dist/components/DocumentList.d.ts.map +1 -1
- package/dist/components/FieldConfigDialog.d.ts.map +1 -1
- package/dist/components/FormBuilder.d.ts.map +1 -1
- package/dist/components/FormViewer.d.ts.map +1 -1
- package/dist/components/PersonDocumentsWidget.d.ts.map +1 -1
- package/dist/data/supabase.d.ts.map +1 -1
- package/dist/index.cjs +142 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +142 -54
- package/dist/index.js.map +1 -1
- package/dist/lib/person-fields.d.ts +16 -0
- package/dist/lib/person-fields.d.ts.map +1 -0
- package/dist/lib/print.d.ts +17 -0
- package/dist/lib/print.d.ts.map +1 -0
- package/dist/lib/tenant.d.ts.map +1 -1
- package/dist/locales/en.d.ts.map +1 -1
- package/dist/locales/pt-BR.d.ts.map +1 -1
- package/dist/migrations/index.d.ts +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/views/CustomFormsSettingsTab.d.ts.map +1 -1
- package/dist/views/TemplateListView.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/agent-tools.ts +73 -0
- package/src/components/DocumentFormDialog.tsx +37 -16
- package/src/components/DocumentList.tsx +12 -8
- package/src/components/FieldConfigDialog.tsx +40 -0
- package/src/components/FormBuilder.tsx +104 -22
- package/src/components/FormViewer.tsx +11 -1
- package/src/components/PersonDocumentsWidget.tsx +10 -1
- package/src/data/supabase.ts +2 -0
- package/src/index.ts +21 -0
- package/src/lib/person-fields.ts +67 -0
- package/src/lib/print.ts +207 -0
- package/src/lib/tenant.ts +6 -2
- package/src/locales/en.ts +20 -0
- package/src/locales/pt-BR.ts +20 -0
- package/src/migrations/003_agent_rpcs.sql +174 -0
- package/src/migrations/index.ts +178 -1
- package/src/types.ts +14 -0
- package/src/views/CustomFormsSettingsTab.tsx +23 -16
- package/src/views/TemplateListView.tsx +29 -18
- package/dist/FormBuilder-4VKYVZAC.cjs.map +0 -1
- package/dist/FormBuilder-KDANEL6Z.js.map +0 -1
- package/dist/chunk-32I43T37.js +0 -198
- package/dist/chunk-32I43T37.js.map +0 -1
- package/dist/chunk-XLUULIVL.cjs +0 -200
- package/dist/chunk-XLUULIVL.cjs.map +0 -1
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { Badge, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Input } from '@fayz-ai/ui';
|
|
3
|
+
import { useTranslation } from '@fayz-ai/core';
|
|
4
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/components/FormRenderer.tsx
|
|
7
|
+
function FieldRenderer({
|
|
8
|
+
field,
|
|
9
|
+
value,
|
|
10
|
+
onChange,
|
|
11
|
+
readOnly
|
|
12
|
+
}) {
|
|
13
|
+
useTranslation();
|
|
14
|
+
switch (field.type) {
|
|
15
|
+
case "title":
|
|
16
|
+
return /* @__PURE__ */ jsx("h3", { className: "text-base font-semibold pt-2 pb-1 border-b", children: field.label });
|
|
17
|
+
case "text":
|
|
18
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
19
|
+
/* @__PURE__ */ jsxs("label", { className: "text-xs font-medium block", children: [
|
|
20
|
+
field.label,
|
|
21
|
+
field.required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-0.5", children: "*" })
|
|
22
|
+
] }),
|
|
23
|
+
/* @__PURE__ */ jsx(
|
|
24
|
+
Input,
|
|
25
|
+
{
|
|
26
|
+
value: value ?? "",
|
|
27
|
+
onChange: (e) => onChange(e.target.value),
|
|
28
|
+
placeholder: field.placeholder,
|
|
29
|
+
className: "h-9 text-sm",
|
|
30
|
+
readOnly
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
] });
|
|
34
|
+
case "memo":
|
|
35
|
+
case "richtext":
|
|
36
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
37
|
+
/* @__PURE__ */ jsxs("label", { className: "text-xs font-medium block", children: [
|
|
38
|
+
field.label,
|
|
39
|
+
field.required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-0.5", children: "*" })
|
|
40
|
+
] }),
|
|
41
|
+
/* @__PURE__ */ jsx(
|
|
42
|
+
"textarea",
|
|
43
|
+
{
|
|
44
|
+
value: value ?? "",
|
|
45
|
+
onChange: (e) => onChange(e.target.value),
|
|
46
|
+
placeholder: field.placeholder,
|
|
47
|
+
className: "flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 min-h-[100px]",
|
|
48
|
+
readOnly
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
] });
|
|
52
|
+
case "date":
|
|
53
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
54
|
+
/* @__PURE__ */ jsxs("label", { className: "text-xs font-medium block", children: [
|
|
55
|
+
field.label,
|
|
56
|
+
field.required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-0.5", children: "*" })
|
|
57
|
+
] }),
|
|
58
|
+
/* @__PURE__ */ jsx(
|
|
59
|
+
Input,
|
|
60
|
+
{
|
|
61
|
+
type: "date",
|
|
62
|
+
value: value ?? "",
|
|
63
|
+
onChange: (e) => onChange(e.target.value),
|
|
64
|
+
className: "h-9 text-sm",
|
|
65
|
+
readOnly
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
] });
|
|
69
|
+
case "select":
|
|
70
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
71
|
+
/* @__PURE__ */ jsxs("label", { className: "text-xs font-medium block", children: [
|
|
72
|
+
field.label,
|
|
73
|
+
field.required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-0.5", children: "*" })
|
|
74
|
+
] }),
|
|
75
|
+
readOnly ? /* @__PURE__ */ jsx("p", { className: "text-sm py-1", children: value ?? "-" }) : /* @__PURE__ */ jsxs(Select, { value: value ?? "", onValueChange: onChange, children: [
|
|
76
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-9 text-sm", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: field.placeholder ?? "..." }) }),
|
|
77
|
+
/* @__PURE__ */ jsx(SelectContent, { children: (field.options ?? []).map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
|
|
78
|
+
] })
|
|
79
|
+
] });
|
|
80
|
+
case "radio":
|
|
81
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
82
|
+
/* @__PURE__ */ jsxs("label", { className: "text-xs font-medium block", children: [
|
|
83
|
+
field.label,
|
|
84
|
+
field.required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-0.5", children: "*" })
|
|
85
|
+
] }),
|
|
86
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-1", children: (field.options ?? []).map((opt) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [
|
|
87
|
+
/* @__PURE__ */ jsx(
|
|
88
|
+
"input",
|
|
89
|
+
{
|
|
90
|
+
type: "radio",
|
|
91
|
+
name: field.id,
|
|
92
|
+
value: opt.value,
|
|
93
|
+
checked: value === opt.value,
|
|
94
|
+
onChange: () => onChange(opt.value),
|
|
95
|
+
disabled: readOnly,
|
|
96
|
+
className: "text-primary"
|
|
97
|
+
}
|
|
98
|
+
),
|
|
99
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm", children: opt.label })
|
|
100
|
+
] }, opt.value)) })
|
|
101
|
+
] });
|
|
102
|
+
case "tags": {
|
|
103
|
+
const selectedTags = Array.isArray(value) ? value : [];
|
|
104
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
105
|
+
/* @__PURE__ */ jsxs("label", { className: "text-xs font-medium block", children: [
|
|
106
|
+
field.label,
|
|
107
|
+
field.required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-0.5", children: "*" })
|
|
108
|
+
] }),
|
|
109
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: (field.options ?? []).map((opt) => {
|
|
110
|
+
const active = selectedTags.includes(opt.value);
|
|
111
|
+
return /* @__PURE__ */ jsx(
|
|
112
|
+
Badge,
|
|
113
|
+
{
|
|
114
|
+
variant: active ? "default" : "outline",
|
|
115
|
+
className: `cursor-pointer text-xs ${readOnly ? "pointer-events-none" : ""}`,
|
|
116
|
+
onClick: () => {
|
|
117
|
+
if (readOnly) return;
|
|
118
|
+
onChange(
|
|
119
|
+
active ? selectedTags.filter((t2) => t2 !== opt.value) : [...selectedTags, opt.value]
|
|
120
|
+
);
|
|
121
|
+
},
|
|
122
|
+
children: opt.label
|
|
123
|
+
},
|
|
124
|
+
opt.value
|
|
125
|
+
);
|
|
126
|
+
}) })
|
|
127
|
+
] });
|
|
128
|
+
}
|
|
129
|
+
case "checkbox":
|
|
130
|
+
return /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 cursor-pointer py-1", children: [
|
|
131
|
+
/* @__PURE__ */ jsx(
|
|
132
|
+
"input",
|
|
133
|
+
{
|
|
134
|
+
type: "checkbox",
|
|
135
|
+
checked: !!value,
|
|
136
|
+
onChange: (e) => onChange(e.target.checked),
|
|
137
|
+
disabled: readOnly,
|
|
138
|
+
className: "rounded border-input"
|
|
139
|
+
}
|
|
140
|
+
),
|
|
141
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm font-medium", children: [
|
|
142
|
+
field.label,
|
|
143
|
+
field.required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-0.5", children: "*" })
|
|
144
|
+
] })
|
|
145
|
+
] });
|
|
146
|
+
case "image":
|
|
147
|
+
case "gallery":
|
|
148
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
149
|
+
/* @__PURE__ */ jsxs("label", { className: "text-xs font-medium block", children: [
|
|
150
|
+
field.label,
|
|
151
|
+
field.required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-0.5", children: "*" })
|
|
152
|
+
] }),
|
|
153
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center rounded-lg border-2 border-dashed py-8 text-sm text-muted-foreground", children: [
|
|
154
|
+
field.type === "gallery" ? "Gallery upload" : "Image upload",
|
|
155
|
+
" \u2014 v2"
|
|
156
|
+
] })
|
|
157
|
+
] });
|
|
158
|
+
case "budget":
|
|
159
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
160
|
+
/* @__PURE__ */ jsxs("label", { className: "text-xs font-medium block", children: [
|
|
161
|
+
field.label,
|
|
162
|
+
field.required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-0.5", children: "*" })
|
|
163
|
+
] }),
|
|
164
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center rounded-lg border-2 border-dashed py-8 text-sm text-muted-foreground", children: "Budget / line items \u2014 v2" })
|
|
165
|
+
] });
|
|
166
|
+
default:
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function FormRenderer({ schema, data, onChange, readOnly }) {
|
|
171
|
+
const sortedFields = [...schema.fields].sort((a, b) => a.row - b.row || a.col - b.col);
|
|
172
|
+
const handleFieldChange = useCallback(
|
|
173
|
+
(fieldId, value) => {
|
|
174
|
+
onChange({ ...data, [fieldId]: value });
|
|
175
|
+
},
|
|
176
|
+
[data, onChange]
|
|
177
|
+
);
|
|
178
|
+
return /* @__PURE__ */ jsx(
|
|
179
|
+
"div",
|
|
180
|
+
{
|
|
181
|
+
className: "grid gap-x-4 gap-y-3",
|
|
182
|
+
style: { gridTemplateColumns: "repeat(12, 1fr)" },
|
|
183
|
+
children: sortedFields.map((field) => /* @__PURE__ */ jsx("div", { style: { gridColumn: `span ${field.colSpan}` }, children: /* @__PURE__ */ jsx(
|
|
184
|
+
FieldRenderer,
|
|
185
|
+
{
|
|
186
|
+
field,
|
|
187
|
+
value: data[field.id],
|
|
188
|
+
onChange: (v) => handleFieldChange(field.id, v),
|
|
189
|
+
readOnly
|
|
190
|
+
}
|
|
191
|
+
) }, field.id))
|
|
192
|
+
}
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// src/lib/print.ts
|
|
197
|
+
function esc(value) {
|
|
198
|
+
return String(value ?? "").replace(
|
|
199
|
+
/[&<>"']/g,
|
|
200
|
+
(c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
function nl2br(value) {
|
|
204
|
+
return esc(value).replace(/\r?\n/g, "<br/>");
|
|
205
|
+
}
|
|
206
|
+
function formatDate(value) {
|
|
207
|
+
const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(value);
|
|
208
|
+
if (!m) return esc(value);
|
|
209
|
+
return `${m[3]}/${m[2]}/${m[1]}`;
|
|
210
|
+
}
|
|
211
|
+
function optionLabel(field, value) {
|
|
212
|
+
const opt = (field.options ?? []).find((o) => o.value === value);
|
|
213
|
+
return esc(opt ? opt.label : value);
|
|
214
|
+
}
|
|
215
|
+
function renderValue(field, value) {
|
|
216
|
+
const empty = '<span class="empty">\u2014</span>';
|
|
217
|
+
switch (field.type) {
|
|
218
|
+
case "memo":
|
|
219
|
+
case "richtext":
|
|
220
|
+
return value ? `<div class="long">${nl2br(String(value))}</div>` : empty;
|
|
221
|
+
case "date":
|
|
222
|
+
return value ? formatDate(String(value)) : empty;
|
|
223
|
+
case "select":
|
|
224
|
+
case "radio":
|
|
225
|
+
return value ? optionLabel(field, value) : empty;
|
|
226
|
+
case "tags": {
|
|
227
|
+
const arr = Array.isArray(value) ? value : [];
|
|
228
|
+
return arr.length ? arr.map((v) => optionLabel(field, v)).join(", ") : empty;
|
|
229
|
+
}
|
|
230
|
+
case "checkbox":
|
|
231
|
+
return value ? "Sim" : "N\xE3o";
|
|
232
|
+
case "image":
|
|
233
|
+
case "gallery":
|
|
234
|
+
case "budget":
|
|
235
|
+
return "";
|
|
236
|
+
// not meaningful on a printed contract
|
|
237
|
+
default:
|
|
238
|
+
return value ? esc(value) : empty;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function buildPrintHtml(template, doc, opts = {}) {
|
|
242
|
+
const heading = opts.heading ?? doc.title ?? template.name;
|
|
243
|
+
const subParts = [opts.subheading ?? doc.personName, new Date(doc.createdAt).toLocaleDateString()].filter(Boolean).map((s) => esc(s)).join(" · ");
|
|
244
|
+
const fields = [...template.schema.fields].sort((a, b) => a.row - b.row || a.col - b.col);
|
|
245
|
+
const clampSpan = (n) => Math.max(1, Math.min(12, Number(n) || 12));
|
|
246
|
+
const body = fields.map((field) => {
|
|
247
|
+
if (field.type === "title") {
|
|
248
|
+
return `<h2 class="section" style="grid-column: 1 / -1">${esc(field.label)}</h2>`;
|
|
249
|
+
}
|
|
250
|
+
const rendered = renderValue(field, doc.data[field.id]);
|
|
251
|
+
if (rendered === "") return "";
|
|
252
|
+
const isLong = field.type === "memo" || field.type === "richtext";
|
|
253
|
+
return `<div class="field${isLong ? " field--long" : ""}" style="grid-column: span ${clampSpan(field.colSpan)}">
|
|
254
|
+
<div class="label">${esc(field.label)}</div>
|
|
255
|
+
<div class="value">${rendered}</div>
|
|
256
|
+
</div>`;
|
|
257
|
+
}).join("\n");
|
|
258
|
+
return `<!doctype html>
|
|
259
|
+
<html lang="pt-BR">
|
|
260
|
+
<head>
|
|
261
|
+
<meta charset="utf-8"/>
|
|
262
|
+
<title>${esc(heading)}</title>
|
|
263
|
+
<style>
|
|
264
|
+
@page { size: A4; margin: 20mm; }
|
|
265
|
+
* { box-sizing: border-box; }
|
|
266
|
+
html, body { margin: 0; padding: 0; }
|
|
267
|
+
body {
|
|
268
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
|
269
|
+
color: #111; font-size: 12pt; line-height: 1.5;
|
|
270
|
+
-webkit-print-color-adjust: exact; print-color-adjust: exact;
|
|
271
|
+
}
|
|
272
|
+
.page { max-width: 170mm; margin: 0 auto; padding: 12mm 0; }
|
|
273
|
+
header { border-bottom: 2px solid #111; padding-bottom: 8px; margin-bottom: 20px; }
|
|
274
|
+
header h1 { font-size: 18pt; margin: 0 0 2px; }
|
|
275
|
+
header .sub { font-size: 10pt; color: #555; }
|
|
276
|
+
/* 12-column grid \u2014 mirrors the builder Preview (FormRenderer) so the print
|
|
277
|
+
keeps the authored column layout. */
|
|
278
|
+
.grid { display: grid; grid-template-columns: repeat(12, 1fr); column-gap: 16px; row-gap: 12px; align-items: start; }
|
|
279
|
+
h2.section { font-size: 13pt; margin: 22px 0 4px; padding-bottom: 3px; border-bottom: 1px solid #ccc; }
|
|
280
|
+
.grid > h2.section:first-child { margin-top: 4px; }
|
|
281
|
+
.field { margin: 0; min-width: 0; }
|
|
282
|
+
.field .label { font-size: 9pt; text-transform: uppercase; letter-spacing: .04em; color: #666; margin-bottom: 2px; }
|
|
283
|
+
.field .value { font-size: 12pt; }
|
|
284
|
+
.field--long .value .long { white-space: normal; text-align: justify; }
|
|
285
|
+
.empty { color: #bbb; }
|
|
286
|
+
footer { margin-top: 40px; font-size: 9pt; color: #888; text-align: center; }
|
|
287
|
+
@media screen { body { background: #f3f3f3; } .page { background: #fff; max-width: 210mm; min-height: 297mm; padding: 20mm; box-shadow: 0 1px 8px rgba(0,0,0,.15); } }
|
|
288
|
+
</style>
|
|
289
|
+
</head>
|
|
290
|
+
<body>
|
|
291
|
+
<div class="page">
|
|
292
|
+
<header>
|
|
293
|
+
<h1>${esc(heading)}</h1>
|
|
294
|
+
${subParts ? `<div class="sub">${subParts}</div>` : ""}
|
|
295
|
+
</header>
|
|
296
|
+
<div class="grid">
|
|
297
|
+
${body}
|
|
298
|
+
</div>
|
|
299
|
+
</div>
|
|
300
|
+
</body>
|
|
301
|
+
</html>`;
|
|
302
|
+
}
|
|
303
|
+
function printHtml(html) {
|
|
304
|
+
if (typeof document === "undefined") return;
|
|
305
|
+
const iframe = document.createElement("iframe");
|
|
306
|
+
iframe.setAttribute("aria-hidden", "true");
|
|
307
|
+
iframe.style.position = "fixed";
|
|
308
|
+
iframe.style.right = "0";
|
|
309
|
+
iframe.style.bottom = "0";
|
|
310
|
+
iframe.style.width = "0";
|
|
311
|
+
iframe.style.height = "0";
|
|
312
|
+
iframe.style.border = "0";
|
|
313
|
+
document.body.appendChild(iframe);
|
|
314
|
+
const cleanup = () => {
|
|
315
|
+
setTimeout(() => {
|
|
316
|
+
if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
|
|
317
|
+
}, 1e3);
|
|
318
|
+
};
|
|
319
|
+
const win = iframe.contentWindow;
|
|
320
|
+
const idoc = iframe.contentDocument || win?.document;
|
|
321
|
+
if (!win || !idoc) {
|
|
322
|
+
cleanup();
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
idoc.open();
|
|
326
|
+
idoc.write(html);
|
|
327
|
+
idoc.close();
|
|
328
|
+
const doPrint = () => {
|
|
329
|
+
try {
|
|
330
|
+
win.focus();
|
|
331
|
+
win.print();
|
|
332
|
+
} finally {
|
|
333
|
+
cleanup();
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
if (idoc.readyState === "complete") {
|
|
337
|
+
setTimeout(doPrint, 50);
|
|
338
|
+
} else {
|
|
339
|
+
iframe.addEventListener("load", () => setTimeout(doPrint, 50), { once: true });
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
function printDocument(template, doc, opts) {
|
|
343
|
+
printHtml(buildPrintHtml(template, doc, opts));
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// src/agent-tools.ts
|
|
347
|
+
var CATEGORY_ENUM = ["anamnesis", "evolution", "report", "contract", "general"];
|
|
348
|
+
var FIELD_SHAPE = "A field object: { type, label, required?, placeholder?, options?[] }. type \u2208 title|text|memo|richtext|date|select|radio|tags|checkbox|image|gallery|budget (title = section heading, no input). options are plain strings, only for select/radio/tags.";
|
|
349
|
+
var createOrUpdateFormTool = {
|
|
350
|
+
id: "custom_forms.createOrUpdateForm",
|
|
351
|
+
name: "createOrUpdateForm",
|
|
352
|
+
description: "Creates or edits a form template (anamnese, contrato, ficha\u2026). Persisted server-side, so it works from ANY page \u2014 the user does NOT need the form builder open. Omit templateId to CREATE (name required); pass templateId to EDIT an existing form. Send the FULL desired field list in `fields` (replaces all fields), or `append_fields` to add to what already exists. Layout is automatic \u2014 never send positions. Understand the intent and propose a sensible field set in one call rather than asking field by field. The user confirms before it is saved.",
|
|
353
|
+
icon: "FileText",
|
|
354
|
+
mode: "persist",
|
|
355
|
+
limitKey: "form_templates",
|
|
356
|
+
permission: { feature: "custom_forms", action: "create" },
|
|
357
|
+
execution: { plane: "server", kind: "rpc", rpc: "agent_forms_upsert_template" },
|
|
358
|
+
category: "Forms",
|
|
359
|
+
suggestions: [
|
|
360
|
+
{ label: "Monte um formul\xE1rio de anamnese" },
|
|
361
|
+
{ label: "Adicione um campo de alergias neste formul\xE1rio" }
|
|
362
|
+
],
|
|
363
|
+
parameters: {
|
|
364
|
+
type: "object",
|
|
365
|
+
properties: {
|
|
366
|
+
templateId: {
|
|
367
|
+
type: "string",
|
|
368
|
+
description: "Existing form id to EDIT (from context or listFormTemplates). Omit to create a new form."
|
|
369
|
+
},
|
|
370
|
+
name: { type: "string", description: "Form name \u2014 required when creating." },
|
|
371
|
+
category: {
|
|
372
|
+
type: "string",
|
|
373
|
+
enum: [...CATEGORY_ENUM],
|
|
374
|
+
description: "anamnesis | evolution | report | contract | general"
|
|
375
|
+
},
|
|
376
|
+
description: { type: "string", description: "Optional short description of the form." },
|
|
377
|
+
fields: {
|
|
378
|
+
type: "array",
|
|
379
|
+
description: `The FULL desired field list \u2014 REPLACES every existing field. Each item: ${FIELD_SHAPE}`,
|
|
380
|
+
items: { type: "object", description: FIELD_SHAPE }
|
|
381
|
+
},
|
|
382
|
+
append_fields: {
|
|
383
|
+
type: "array",
|
|
384
|
+
description: `Fields to ADD to the existing form, keeping current ones. Use this for incremental edits instead of \`fields\`. Each item: ${FIELD_SHAPE}`,
|
|
385
|
+
items: { type: "object", description: FIELD_SHAPE }
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
var FORM_BUILDER_INSTRUCTIONS = [
|
|
391
|
+
"Voc\xEA est\xE1 na tela do CONSTRUTOR DE FORMUL\xC1RIOS. Para montar ou editar formul\xE1rios use a tool createOrUpdateForm (ela persiste no backend e funciona mesmo fora desta tela).",
|
|
392
|
+
"O formul\xE1rio aberto agora \u2014 id, nome, categoria e campos com seus ids \u2014 est\xE1 no JSON da tela em contexto.",
|
|
393
|
+
"Para EDITAR este formul\xE1rio, passe o templateId do contexto. Para adicionar campos mantendo os atuais, use append_fields; para redefinir tudo, use fields com a lista completa.",
|
|
394
|
+
"Ao criar do zero: entenda a inten\xE7\xE3o e proponha um conjunto de campos enxuto numa \xFAnica chamada (n\xE3o pergunte campo a campo). Depois confirme em uma frase o que foi montado.",
|
|
395
|
+
"Tipos de campo: title (cabe\xE7alho de se\xE7\xE3o, sem input), text, memo (multilinha), richtext, date, select, radio, tags, checkbox, image, gallery, budget. Layout \xE9 autom\xE1tico."
|
|
396
|
+
].join(" ");
|
|
397
|
+
|
|
398
|
+
// src/lib/person-fields.ts
|
|
399
|
+
var PERSON_FIELD_OPTIONS = [
|
|
400
|
+
{ value: "name", labelKey: "customForms.personField.name" },
|
|
401
|
+
{ value: "documentNumber", labelKey: "customForms.personField.documentNumber" },
|
|
402
|
+
{ value: "email", labelKey: "customForms.personField.email" },
|
|
403
|
+
{ value: "phone", labelKey: "customForms.personField.phone" },
|
|
404
|
+
{ value: "dateOfBirth", labelKey: "customForms.personField.dateOfBirth" },
|
|
405
|
+
{ value: "guardianName", labelKey: "customForms.personField.guardianName" },
|
|
406
|
+
{ value: "address", labelKey: "customForms.personField.address" },
|
|
407
|
+
{ value: "city", labelKey: "customForms.personField.city" },
|
|
408
|
+
{ value: "state", labelKey: "customForms.personField.state" }
|
|
409
|
+
];
|
|
410
|
+
var toSnake = (k) => k.replace(/[A-Z]/g, (m) => "_" + m.toLowerCase());
|
|
411
|
+
var toCamel = (k) => k.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
412
|
+
function resolvePersonValue(person, mapKey) {
|
|
413
|
+
if (!person || !mapKey) return void 0;
|
|
414
|
+
for (const key of [mapKey, toSnake(mapKey), toCamel(mapKey)]) {
|
|
415
|
+
const v = person[key];
|
|
416
|
+
if (v != null && v !== "") return v;
|
|
417
|
+
}
|
|
418
|
+
return void 0;
|
|
419
|
+
}
|
|
420
|
+
function prefillFromPerson(schema, person, existing = {}) {
|
|
421
|
+
const data = { ...existing };
|
|
422
|
+
if (!schema) return data;
|
|
423
|
+
for (const field of schema.fields) {
|
|
424
|
+
const current = data[field.id];
|
|
425
|
+
if (current != null && current !== "") continue;
|
|
426
|
+
const mapped = field.map ? resolvePersonValue(person, field.map) : void 0;
|
|
427
|
+
if (mapped != null) {
|
|
428
|
+
data[field.id] = mapped;
|
|
429
|
+
} else if (field.defaultValue != null) {
|
|
430
|
+
data[field.id] = field.defaultValue;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return data;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
export { FORM_BUILDER_INSTRUCTIONS, FormRenderer, PERSON_FIELD_OPTIONS, buildPrintHtml, createOrUpdateFormTool, prefillFromPerson, printDocument };
|
|
437
|
+
//# sourceMappingURL=chunk-W2ZNJGQC.js.map
|
|
438
|
+
//# sourceMappingURL=chunk-W2ZNJGQC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/FormRenderer.tsx","../src/lib/print.ts","../src/agent-tools.ts","../src/lib/person-fields.ts"],"names":["t"],"mappings":"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","file":"chunk-W2ZNJGQC.js","sourcesContent":["import React, { useCallback } from 'react'\nimport { Input } from '@fayz-ai/ui'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@fayz-ai/ui'\nimport { Badge } from '@fayz-ai/ui'\nimport { useTranslation } from '@fayz-ai/core'\nimport type { FormFieldDef, FormSchema } from '../types'\n\ninterface FormRendererProps {\n schema: FormSchema\n data: Record<string, unknown>\n onChange: (data: Record<string, unknown>) => void\n readOnly?: boolean\n}\n\nfunction FieldRenderer({\n field,\n value,\n onChange,\n readOnly,\n}: {\n field: FormFieldDef\n value: unknown\n onChange: (value: unknown) => void\n readOnly?: boolean\n}) {\n const t = useTranslation()\n\n switch (field.type) {\n case 'title':\n return (\n <h3 className=\"text-base font-semibold pt-2 pb-1 border-b\">\n {field.label}\n </h3>\n )\n\n case 'text':\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n <Input\n value={(value as string) ?? ''}\n onChange={(e) => onChange(e.target.value)}\n placeholder={field.placeholder}\n className=\"h-9 text-sm\"\n readOnly={readOnly}\n />\n </div>\n )\n\n case 'memo':\n case 'richtext':\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n <textarea\n value={(value as string) ?? ''}\n onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => onChange(e.target.value)}\n placeholder={field.placeholder}\n className=\"flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 min-h-[100px]\"\n readOnly={readOnly}\n />\n </div>\n )\n\n case 'date':\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n <Input\n type=\"date\"\n value={(value as string) ?? ''}\n onChange={(e) => onChange(e.target.value)}\n className=\"h-9 text-sm\"\n readOnly={readOnly}\n />\n </div>\n )\n\n case 'select':\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n {readOnly ? (\n <p className=\"text-sm py-1\">{(value as string) ?? '-'}</p>\n ) : (\n <Select value={(value as string) ?? ''} onValueChange={onChange}>\n <SelectTrigger className=\"h-9 text-sm\">\n <SelectValue placeholder={field.placeholder ?? '...'} />\n </SelectTrigger>\n <SelectContent>\n {(field.options ?? []).map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n </div>\n )\n\n case 'radio':\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n <div className=\"space-y-1\">\n {(field.options ?? []).map((opt) => (\n <label key={opt.value} className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"radio\"\n name={field.id}\n value={opt.value}\n checked={value === opt.value}\n onChange={() => onChange(opt.value)}\n disabled={readOnly}\n className=\"text-primary\"\n />\n <span className=\"text-sm\">{opt.label}</span>\n </label>\n ))}\n </div>\n </div>\n )\n\n case 'tags': {\n const selectedTags = Array.isArray(value) ? (value as string[]) : []\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n <div className=\"flex flex-wrap gap-1.5\">\n {(field.options ?? []).map((opt) => {\n const active = selectedTags.includes(opt.value)\n return (\n <Badge\n key={opt.value}\n variant={active ? 'default' : 'outline'}\n className={`cursor-pointer text-xs ${readOnly ? 'pointer-events-none' : ''}`}\n onClick={() => {\n if (readOnly) return\n onChange(\n active\n ? selectedTags.filter((t) => t !== opt.value)\n : [...selectedTags, opt.value],\n )\n }}\n >\n {opt.label}\n </Badge>\n )\n })}\n </div>\n </div>\n )\n }\n\n case 'checkbox':\n return (\n <label className=\"flex items-center gap-2 cursor-pointer py-1\">\n <input\n type=\"checkbox\"\n checked={!!value}\n onChange={(e) => onChange(e.target.checked)}\n disabled={readOnly}\n className=\"rounded border-input\"\n />\n <span className=\"text-sm font-medium\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </span>\n </label>\n )\n\n case 'image':\n case 'gallery':\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n <div className=\"flex items-center justify-center rounded-lg border-2 border-dashed py-8 text-sm text-muted-foreground\">\n {field.type === 'gallery' ? 'Gallery upload' : 'Image upload'} — v2\n </div>\n </div>\n )\n\n case 'budget':\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n <div className=\"flex items-center justify-center rounded-lg border-2 border-dashed py-8 text-sm text-muted-foreground\">\n Budget / line items — v2\n </div>\n </div>\n )\n\n default:\n return null\n }\n}\n\nexport function FormRenderer({ schema, data, onChange, readOnly }: FormRendererProps) {\n const sortedFields = [...schema.fields].sort((a, b) => a.row - b.row || a.col - b.col)\n\n const handleFieldChange = useCallback(\n (fieldId: string, value: unknown) => {\n onChange({ ...data, [fieldId]: value })\n },\n [data, onChange],\n )\n\n return (\n <div\n className=\"grid gap-x-4 gap-y-3\"\n style={{ gridTemplateColumns: 'repeat(12, 1fr)' }}\n >\n {sortedFields.map((field) => (\n <div key={field.id} style={{ gridColumn: `span ${field.colSpan}` }}>\n <FieldRenderer\n field={field}\n value={data[field.id]}\n onChange={(v) => handleFieldChange(field.id, v)}\n readOnly={readOnly}\n />\n </div>\n ))}\n </div>\n )\n}\n","// ============================================================\n// PRINT / PDF — render a filled document to a printable A4 page\n// ============================================================\n//\n// Browser print-to-PDF: we build a clean, self-contained A4 HTML document from\n// the template schema + saved data, drop it into a hidden iframe, and call\n// print() on it. The browser's print dialog covers both physical printing and\n// \"Save as PDF\". No external deps.\n\nimport type { FormDocument, FormFieldDef, FormTemplate } from '../types'\n\nfunction esc(value: unknown): string {\n return String(value ?? '').replace(/[&<>\"']/g, (c) =>\n ({ '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''' }[c] as string),\n )\n}\n\nfunction nl2br(value: string): string {\n return esc(value).replace(/\\r?\\n/g, '<br/>')\n}\n\nfunction formatDate(value: string): string {\n // ISO date (YYYY-MM-DD) → locale date; anything else passes through.\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(value)\n if (!m) return esc(value)\n return `${m[3]}/${m[2]}/${m[1]}`\n}\n\nfunction optionLabel(field: FormFieldDef, value: unknown): string {\n const opt = (field.options ?? []).find((o) => o.value === value)\n return esc(opt ? opt.label : value)\n}\n\n/** Render one field's value as an HTML fragment for the printed page. */\nfunction renderValue(field: FormFieldDef, value: unknown): string {\n const empty = '<span class=\"empty\">—</span>'\n switch (field.type) {\n case 'memo':\n case 'richtext':\n return value ? `<div class=\"long\">${nl2br(String(value))}</div>` : empty\n case 'date':\n return value ? formatDate(String(value)) : empty\n case 'select':\n case 'radio':\n return value ? optionLabel(field, value) : empty\n case 'tags': {\n const arr = Array.isArray(value) ? value : []\n return arr.length\n ? arr.map((v) => optionLabel(field, v)).join(', ')\n : empty\n }\n case 'checkbox':\n return value ? 'Sim' : 'Não'\n case 'image':\n case 'gallery':\n case 'budget':\n return '' // not meaningful on a printed contract\n default:\n return value ? esc(value) : empty\n }\n}\n\nexport interface BuildPrintOptions {\n /** Heading shown at the top of the page (defaults to the document title). */\n heading?: string\n /** Small line under the heading (e.g. person name). */\n subheading?: string\n}\n\n/** Build a full, self-contained printable HTML document. */\nexport function buildPrintHtml(\n template: FormTemplate,\n doc: FormDocument,\n opts: BuildPrintOptions = {},\n): string {\n const heading = opts.heading ?? doc.title ?? template.name\n const subParts = [opts.subheading ?? doc.personName, new Date(doc.createdAt).toLocaleDateString()]\n .filter(Boolean)\n .map((s) => esc(s))\n .join(' · ')\n\n const fields = [...template.schema.fields].sort((a, b) => a.row - b.row || a.col - b.col)\n\n const clampSpan = (n: unknown) => Math.max(1, Math.min(12, Number(n) || 12))\n\n // Mirror the builder's 12-column grid so the print keeps the authored layout\n // (side-by-side fields stay side by side). Titles span the full row.\n const body = fields\n .map((field) => {\n if (field.type === 'title') {\n return `<h2 class=\"section\" style=\"grid-column: 1 / -1\">${esc(field.label)}</h2>`\n }\n const rendered = renderValue(field, doc.data[field.id])\n if (rendered === '') return ''\n const isLong = field.type === 'memo' || field.type === 'richtext'\n return `<div class=\"field${isLong ? ' field--long' : ''}\" style=\"grid-column: span ${clampSpan(field.colSpan)}\">\n <div class=\"label\">${esc(field.label)}</div>\n <div class=\"value\">${rendered}</div>\n </div>`\n })\n .join('\\n')\n\n return `<!doctype html>\n<html lang=\"pt-BR\">\n<head>\n<meta charset=\"utf-8\"/>\n<title>${esc(heading)}</title>\n<style>\n @page { size: A4; margin: 20mm; }\n * { box-sizing: border-box; }\n html, body { margin: 0; padding: 0; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;\n color: #111; font-size: 12pt; line-height: 1.5;\n -webkit-print-color-adjust: exact; print-color-adjust: exact;\n }\n .page { max-width: 170mm; margin: 0 auto; padding: 12mm 0; }\n header { border-bottom: 2px solid #111; padding-bottom: 8px; margin-bottom: 20px; }\n header h1 { font-size: 18pt; margin: 0 0 2px; }\n header .sub { font-size: 10pt; color: #555; }\n /* 12-column grid — mirrors the builder Preview (FormRenderer) so the print\n keeps the authored column layout. */\n .grid { display: grid; grid-template-columns: repeat(12, 1fr); column-gap: 16px; row-gap: 12px; align-items: start; }\n h2.section { font-size: 13pt; margin: 22px 0 4px; padding-bottom: 3px; border-bottom: 1px solid #ccc; }\n .grid > h2.section:first-child { margin-top: 4px; }\n .field { margin: 0; min-width: 0; }\n .field .label { font-size: 9pt; text-transform: uppercase; letter-spacing: .04em; color: #666; margin-bottom: 2px; }\n .field .value { font-size: 12pt; }\n .field--long .value .long { white-space: normal; text-align: justify; }\n .empty { color: #bbb; }\n footer { margin-top: 40px; font-size: 9pt; color: #888; text-align: center; }\n @media screen { body { background: #f3f3f3; } .page { background: #fff; max-width: 210mm; min-height: 297mm; padding: 20mm; box-shadow: 0 1px 8px rgba(0,0,0,.15); } }\n</style>\n</head>\n<body>\n <div class=\"page\">\n <header>\n <h1>${esc(heading)}</h1>\n ${subParts ? `<div class=\"sub\">${subParts}</div>` : ''}\n </header>\n <div class=\"grid\">\n ${body}\n </div>\n </div>\n</body>\n</html>`\n}\n\n/**\n * Print a prebuilt HTML document via a hidden iframe (popup-blocker safe).\n * The browser print dialog handles both printing and \"Save as PDF\".\n */\nexport function printHtml(html: string): void {\n if (typeof document === 'undefined') return\n const iframe = document.createElement('iframe')\n iframe.setAttribute('aria-hidden', 'true')\n iframe.style.position = 'fixed'\n iframe.style.right = '0'\n iframe.style.bottom = '0'\n iframe.style.width = '0'\n iframe.style.height = '0'\n iframe.style.border = '0'\n document.body.appendChild(iframe)\n\n const cleanup = () => {\n // Give the print dialog a beat before tearing the frame down.\n setTimeout(() => {\n if (iframe.parentNode) iframe.parentNode.removeChild(iframe)\n }, 1000)\n }\n\n const win = iframe.contentWindow\n const idoc = iframe.contentDocument || win?.document\n if (!win || !idoc) {\n cleanup()\n return\n }\n\n idoc.open()\n idoc.write(html)\n idoc.close()\n\n const doPrint = () => {\n try {\n win.focus()\n win.print()\n } finally {\n cleanup()\n }\n }\n\n // Wait for the frame document to be ready before printing.\n if (idoc.readyState === 'complete') {\n setTimeout(doPrint, 50)\n } else {\n iframe.addEventListener('load', () => setTimeout(doPrint, 50), { once: true })\n }\n}\n\n/** Convenience: build + print a document in one call. */\nexport function printDocument(\n template: FormTemplate,\n doc: FormDocument,\n opts?: BuildPrintOptions,\n): void {\n printHtml(buildPrintHtml(template, doc, opts))\n}\n","import type { PluginAITool } from '@fayz-ai/core'\n\n/**\n * The assistant's form-building tool. It is a SERVER-PLANE write (a pool RPC),\n * not a client-side surface mutation — so it works from any page and any\n * channel (in-app FAB, WhatsApp, MCP), and persists straight to the tenant's\n * form templates. This is the same pattern agenda/financial/marketing use.\n *\n * The builder surface (see FormBuilder) still publishes CONTEXT — which form is\n * open and its current fields with ids — so \"add an allergies field to THIS\n * form\" resolves to the right template. But the action itself is this tool.\n */\n\nconst CATEGORY_ENUM = ['anamnesis', 'evolution', 'report', 'contract', 'general'] as const\n\nconst FIELD_SHAPE =\n 'A field object: { type, label, required?, placeholder?, options?[] }. ' +\n 'type ∈ title|text|memo|richtext|date|select|radio|tags|checkbox|image|gallery|budget ' +\n '(title = section heading, no input). options are plain strings, only for select/radio/tags.'\n\nexport const createOrUpdateFormTool: PluginAITool = {\n id: 'custom_forms.createOrUpdateForm',\n name: 'createOrUpdateForm',\n description:\n 'Creates or edits a form template (anamnese, contrato, ficha…). Persisted server-side, so it works from ANY page — the user does NOT need the form builder open. ' +\n 'Omit templateId to CREATE (name required); pass templateId to EDIT an existing form. ' +\n 'Send the FULL desired field list in `fields` (replaces all fields), or `append_fields` to add to what already exists. ' +\n 'Layout is automatic — never send positions. Understand the intent and propose a sensible field set in one call rather than asking field by field. The user confirms before it is saved.',\n icon: 'FileText',\n mode: 'persist',\n limitKey: 'form_templates',\n permission: { feature: 'custom_forms', action: 'create' },\n execution: { plane: 'server', kind: 'rpc', rpc: 'agent_forms_upsert_template' },\n category: 'Forms',\n suggestions: [\n { label: 'Monte um formulário de anamnese' },\n { label: 'Adicione um campo de alergias neste formulário' },\n ],\n parameters: {\n type: 'object',\n properties: {\n templateId: {\n type: 'string',\n description: 'Existing form id to EDIT (from context or listFormTemplates). Omit to create a new form.',\n },\n name: { type: 'string', description: 'Form name — required when creating.' },\n category: {\n type: 'string',\n enum: [...CATEGORY_ENUM],\n description: 'anamnesis | evolution | report | contract | general',\n },\n description: { type: 'string', description: 'Optional short description of the form.' },\n fields: {\n type: 'array',\n description: `The FULL desired field list — REPLACES every existing field. Each item: ${FIELD_SHAPE}`,\n items: { type: 'object', description: FIELD_SHAPE },\n },\n append_fields: {\n type: 'array',\n description: `Fields to ADD to the existing form, keeping current ones. Use this for incremental edits instead of \\`fields\\`. Each item: ${FIELD_SHAPE}`,\n items: { type: 'object', description: FIELD_SHAPE },\n },\n },\n },\n}\n\nexport const FORM_BUILDER_INSTRUCTIONS = [\n 'Você está na tela do CONSTRUTOR DE FORMULÁRIOS. Para montar ou editar formulários use a tool createOrUpdateForm (ela persiste no backend e funciona mesmo fora desta tela).',\n 'O formulário aberto agora — id, nome, categoria e campos com seus ids — está no JSON da tela em contexto.',\n 'Para EDITAR este formulário, passe o templateId do contexto. Para adicionar campos mantendo os atuais, use append_fields; para redefinir tudo, use fields com a lista completa.',\n 'Ao criar do zero: entenda a intenção e proponha um conjunto de campos enxuto numa única chamada (não pergunte campo a campo). Depois confirme em uma frase o que foi montado.',\n 'Tipos de campo: title (cabeçalho de seção, sem input), text, memo (multilinha), richtext, date, select, radio, tags, checkbox, image, gallery, budget. Layout é automático.',\n].join(' ')\n","// ============================================================\n// PERSON FIELD MAPPING — prefill a document from a person record\n// ============================================================\n//\n// A template field can declare `map: '<personKey>'` (see FormFieldDef.map).\n// When a document is created from a person's profile, fields with a mapping are\n// pre-filled from that person's record. The person record reaching the widget\n// is the host app's CRUD detail `item`, keyed by the entity's field keys\n// (camelCase, e.g. `documentNumber`). We resolve tolerantly so the same mapping\n// works whether the host exposes camelCase or snake_case keys.\n\nimport type { FormSchema } from '../types'\n\n/** Curated, vertical-agnostic person keys offered in the field builder. */\nexport const PERSON_FIELD_OPTIONS: Array<{ value: string; labelKey: string }> = [\n { value: 'name', labelKey: 'customForms.personField.name' },\n { value: 'documentNumber', labelKey: 'customForms.personField.documentNumber' },\n { value: 'email', labelKey: 'customForms.personField.email' },\n { value: 'phone', labelKey: 'customForms.personField.phone' },\n { value: 'dateOfBirth', labelKey: 'customForms.personField.dateOfBirth' },\n { value: 'guardianName', labelKey: 'customForms.personField.guardianName' },\n { value: 'address', labelKey: 'customForms.personField.address' },\n { value: 'city', labelKey: 'customForms.personField.city' },\n { value: 'state', labelKey: 'customForms.personField.state' },\n]\n\nconst toSnake = (k: string) => k.replace(/[A-Z]/g, (m) => '_' + m.toLowerCase())\nconst toCamel = (k: string) => k.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())\n\n/** Read a person field value, tolerating camelCase/snake_case key variants. */\nexport function resolvePersonValue(\n person: Record<string, unknown> | undefined | null,\n mapKey: string | undefined,\n): unknown {\n if (!person || !mapKey) return undefined\n for (const key of [mapKey, toSnake(mapKey), toCamel(mapKey)]) {\n const v = person[key]\n if (v != null && v !== '') return v\n }\n return undefined\n}\n\n/**\n * Build the initial document data for a template. For each field, applies (in\n * priority order) an existing value, then the mapped person value, then the\n * field's static `defaultValue`. Never overwrites a value already present in\n * `existing`.\n */\nexport function prefillFromPerson(\n schema: FormSchema | undefined,\n person: Record<string, unknown> | undefined | null,\n existing: Record<string, unknown> = {},\n): Record<string, unknown> {\n const data: Record<string, unknown> = { ...existing }\n if (!schema) return data\n for (const field of schema.fields) {\n const current = data[field.id]\n if (current != null && current !== '') continue\n const mapped = field.map ? resolvePersonValue(person, field.map) : undefined\n if (mapped != null) {\n data[field.id] = mapped\n } else if (field.defaultValue != null) {\n data[field.id] = field.defaultValue\n }\n }\n return data\n}\n"]}
|
|
@@ -7,11 +7,13 @@ interface DocumentFormDialogProps {
|
|
|
7
7
|
existingDocument?: FormDocument;
|
|
8
8
|
personId: string;
|
|
9
9
|
personName?: string;
|
|
10
|
+
/** Full person record — mapped fields are pre-filled from it on new documents. */
|
|
11
|
+
person?: Record<string, unknown>;
|
|
10
12
|
provider: CustomFormsDataProvider;
|
|
11
13
|
store: CustomFormsStore;
|
|
12
14
|
onSaved: () => void;
|
|
13
15
|
onBack: () => void;
|
|
14
16
|
}
|
|
15
|
-
export declare function DocumentFormDialog({ template: initialTemplate, existingDocument, personId, personName, provider, store, onSaved, onBack, }: DocumentFormDialogProps): React.JSX.Element;
|
|
17
|
+
export declare function DocumentFormDialog({ template: initialTemplate, existingDocument, personId, personName, person, provider, store, onSaved, onBack, }: DocumentFormDialogProps): React.JSX.Element;
|
|
16
18
|
export {};
|
|
17
19
|
//# sourceMappingURL=DocumentFormDialog.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentFormDialog.d.ts","sourceRoot":"","sources":["../../src/components/DocumentFormDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"DocumentFormDialog.d.ts","sourceRoot":"","sources":["../../src/components/DocumentFormDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAA;AAK/D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAW1D,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;IAC7B,gBAAgB,CAAC,EAAE,YAAY,CAAA;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,QAAQ,EAAE,uBAAuB,CAAA;IACjC,KAAK,EAAE,gBAAgB,CAAA;IACvB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EAAE,eAAe,EACzB,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,MAAM,EACN,QAAQ,EACR,KAAK,EACL,OAAO,EACP,MAAM,GACP,EAAE,uBAAuB,qBAiHzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentList.d.ts","sourceRoot":"","sources":["../../src/components/DocumentList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAA;AAIvE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,UAAU,CAAA;AAE5D,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,uBAAuB,CAAA;IACjC,KAAK,EAAE,gBAAgB,CAAA;IACvB,MAAM,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAA;IACnC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAA;CACrC;AA8CD,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"DocumentList.d.ts","sourceRoot":"","sources":["../../src/components/DocumentList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAA;AAIvE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,UAAU,CAAA;AAE5D,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,uBAAuB,CAAA;IACjC,KAAK,EAAE,gBAAgB,CAAA;IACvB,MAAM,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAA;IACnC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAA;CACrC;AA8CD,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,iBAAiB,qBAiMhG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FieldConfigDialog.d.ts","sourceRoot":"","sources":["../../src/components/FieldConfigDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"FieldConfigDialog.d.ts","sourceRoot":"","sources":["../../src/components/FieldConfigDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAA;AAoBlD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAiB5C,UAAU,sBAAsB;IAC9B,KAAK,EAAE,YAAY,GAAG,IAAI,CAAA;IAC1B,MAAM,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAA;IACvC,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAA;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,sBAAsB,4BAqM7F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormBuilder.d.ts","sourceRoot":"","sources":["../../src/components/FormBuilder.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"FormBuilder.d.ts","sourceRoot":"","sources":["../../src/components/FormBuilder.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAA;AA2B/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAYlD,UAAU,gBAAgB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,gBAAgB,CAAA;IACvB,QAAQ,EAAE,uBAAuB,CAAA;IACjC,MAAM,EAAE,iBAAiB,CAAA;IACzB,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB;AAED,wBAAgB,WAAW,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,gBAAgB,qBAyX5F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormViewer.d.ts","sourceRoot":"","sources":["../../src/components/FormViewer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAA;AAKlD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"FormViewer.d.ts","sourceRoot":"","sources":["../../src/components/FormViewer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAA;AAKlD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,UAAU,CAAA;AAI1D,UAAU,eAAe;IACvB,QAAQ,EAAE,YAAY,CAAA;IACtB,QAAQ,EAAE,uBAAuB,CAAA;IACjC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAA;CACrC;AASD,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,eAAe,qBAqEtF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PersonDocumentsWidget.d.ts","sourceRoot":"","sources":["../../src/components/PersonDocumentsWidget.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwC,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"PersonDocumentsWidget.d.ts","sourceRoot":"","sources":["../../src/components/PersonDocumentsWidget.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwC,MAAM,OAAO,CAAA;AAK5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAQhD,UAAU,0BAA0B;IAClC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAA;IACvD,MAAM,EAAE,iBAAiB,CAAA;IACzB,QAAQ,EAAE,uBAAuB,CAAA;IACjC,KAAK,EAAE,gBAAgB,CAAA;CACxB;AAQD,wBAAgB,qBAAqB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,0BAA0B,qBA2JlG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/data/supabase.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAiGtD,wBAAgB,2BAA2B,IAAI,uBAAuB,
|
|
1
|
+
{"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/data/supabase.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAiGtD,wBAAgB,2BAA2B,IAAI,uBAAuB,CAqTrE"}
|