json-object-editor 0.10.657 → 0.10.660
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 +5 -1
- package/docs/React_Form_Integration_Strategy.md +398 -0
- package/form-qs.json +1007 -0
- package/js/joe-ai.js +231 -31
- package/package.json +1 -1
- package/react-form-spa-ex.js +570 -0
- package/readme.md +5 -1
- package/server/fields/core.js +4 -1
- package/server/plugins/chatgpt.js +135 -3
- package/server/schemas/ai_assistant.js +15 -1
- package/server/schemas/ai_widget_conversation.js +31 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
## 0.10.
|
|
1
|
+
## 0.10.660
|
|
2
2
|
|
|
3
3
|
- MCP as an optional layer on all AI surfaces
|
|
4
4
|
- `ai_prompt`: added MCP config block (`mcp_enabled`, `mcp_toolset`, `mcp_selected_tools`, `mcp_instructions_mode`) so prompts can opt into MCP tools with named toolsets (`read-only`, `minimal`, `all`, `custom`) and auto‑generated tool instructions.
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
- `runWithTools` now applies `attachFilesToResponsesPayload` to both the initial tool‑planning call and the final Responses call (including the token‑limit retry), so MCP runs consistently see file attachments.
|
|
11
11
|
- Storage / history robustness
|
|
12
12
|
- Hardened `JOE.Storage.save` history diffing by sanitizing cached vs current documents before `$c.changes(...)` to avoid a `craydent-object.equals` edge case where comparing `null`/`undefined` could throw on `.toString()`. This only affects `_history.changes`, not saved documents.
|
|
13
|
+
- Object chat unification
|
|
14
|
+
- The legacy assistants-based `objectChat` flow has been replaced with a floating `<joe-ai-widget>` shell (with `<joe-ai-assistant-picker>`), so object chat uses the same widget + MCP stack as AIHub.
|
|
15
|
+
- `ai_widget_conversation` now supports scoped chats via `scope_itemtype`/`scope_id` and tracks attached OpenAI Files via `attached_openai_file_ids` and `attached_files_meta`.
|
|
16
|
+
- On the first turn of an object-scoped chat, the server preloads a slimmed `understandObject` snapshot for the scoped object and merges object files + assistant files into the `openai_file_ids` passed to `runWithTools`, so assistants immediately understand which record they’re talking about and can reason over its files.
|
|
13
17
|
|
|
14
18
|
## 0.10.654
|
|
15
19
|
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
# React Form Integration Strategy for JOE
|
|
2
|
+
|
|
3
|
+
## Executive Summary
|
|
4
|
+
|
|
5
|
+
This document outlines strategy options for integrating:
|
|
6
|
+
1. **JSON-based form definitions** (from `form-qs.json` format)
|
|
7
|
+
2. **React Single Page Application** as a page type in JOE
|
|
8
|
+
3. **Form submission storage** into JOE's submission system
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Current State Analysis
|
|
13
|
+
|
|
14
|
+
### JOE Form System (Current)
|
|
15
|
+
- **Schema**: `form` schema with `sections` (objectList), `questions` (references to question schema)
|
|
16
|
+
- **Rendering**: `formBuilder` plugin renders HTML forms server-side
|
|
17
|
+
- **Submission**: POST to `/API/plugin/formBuilder/submission` with `{formid, submission: {...}}`
|
|
18
|
+
- **Storage**: Creates `submission` items with `data`, `form_name`, `form` (reference), `visitor`, `submission_date`
|
|
19
|
+
|
|
20
|
+
### JOE Page System (Current)
|
|
21
|
+
- **Content Types**: `wysiwyg`, `code`, `plugin`, `module`
|
|
22
|
+
- **Module Type**: Server-side JS function that returns HTML string
|
|
23
|
+
- **Includes**: Can load JS/CSS files via `include` schema (served at `/_include/{id}`)
|
|
24
|
+
- **Layouts**: Templates with `${this.PAGE.content}` placeholder
|
|
25
|
+
|
|
26
|
+
### Target Requirements
|
|
27
|
+
1. Use JSON file (`form-qs.json`) for form structure and rules
|
|
28
|
+
2. Embed React SPA as a page in JOE
|
|
29
|
+
3. Submit to JOE submission storage on form completion
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Strategy Options
|
|
34
|
+
|
|
35
|
+
### **Option 1: React SPA as Code Page with API Bridge** ⭐ **RECOMMENDED**
|
|
36
|
+
|
|
37
|
+
#### Architecture
|
|
38
|
+
- **Page Type**: `content_type: 'code'`
|
|
39
|
+
- **React App**: Compiled/bundled React app loaded via includes or inline
|
|
40
|
+
- **JSON Loading**: React app fetches form definition JSON via API endpoint
|
|
41
|
+
- **Submission**: React app posts to JOE submission API endpoint
|
|
42
|
+
|
|
43
|
+
#### Implementation Details
|
|
44
|
+
|
|
45
|
+
**1. Create Form Definition API Endpoint**
|
|
46
|
+
```javascript
|
|
47
|
+
// server/plugins/formDefinition.js
|
|
48
|
+
this.get = function(req, res) {
|
|
49
|
+
var formId = req.query.formid || req.params.formid;
|
|
50
|
+
// Load form-qs.json format, return as JSON
|
|
51
|
+
// Could be stored as include or in a new form_definition schema
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**2. Create Submission API Endpoint** (extend existing or new)
|
|
56
|
+
```javascript
|
|
57
|
+
// Extend server/plugins/formBuilder.js or create formSubmission.js
|
|
58
|
+
this.submit = function(data, req) {
|
|
59
|
+
// Accept JSON form submission, map to JOE submission format
|
|
60
|
+
// Create submission record with form reference
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**3. React App Integration**
|
|
65
|
+
- React app bundled (webpack/vite) and stored as an `include` (JS file)
|
|
66
|
+
- Page content: `<div id="react-form-root"></div><script src="/_include/{react-bundle-id}"></script>`
|
|
67
|
+
- React app:
|
|
68
|
+
- Fetches form definition from `/API/plugin/formDefinition/get?formid={id}`
|
|
69
|
+
- Renders form using `react-form-spa-ex.js` logic
|
|
70
|
+
- Submits to `/API/plugin/formBuilder/submission` (or new endpoint)
|
|
71
|
+
|
|
72
|
+
#### Pros
|
|
73
|
+
- ✅ Leverages existing JOE infrastructure
|
|
74
|
+
- ✅ React app is independent and can be versioned/updated separately
|
|
75
|
+
- ✅ Works with existing submission storage
|
|
76
|
+
- ✅ Minimal changes to JOE core
|
|
77
|
+
- ✅ Can reuse existing form validation/storage logic
|
|
78
|
+
|
|
79
|
+
#### Cons
|
|
80
|
+
- ⚠️ Requires bundling React app separately
|
|
81
|
+
- ⚠️ Two API endpoints to maintain (form definition + submission)
|
|
82
|
+
- ⚠️ React app needs to know JOE API structure
|
|
83
|
+
|
|
84
|
+
#### Estimated Effort
|
|
85
|
+
- **Low-Medium**: ~2-3 days
|
|
86
|
+
- API endpoint for form definitions: 4-6 hours
|
|
87
|
+
- Submission endpoint extension: 2-4 hours
|
|
88
|
+
- React app integration/hooking: 4-6 hours
|
|
89
|
+
- Testing: 4-6 hours
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
### **Option 2: New "spa" Content Type with Form Plugin**
|
|
94
|
+
|
|
95
|
+
#### Architecture
|
|
96
|
+
- **Page Type**: New `content_type: 'spa'` option
|
|
97
|
+
- **Form Plugin**: New `reactForm` plugin that handles React app bootstrapping
|
|
98
|
+
- **Configuration**: Page stores React component path and form definition reference
|
|
99
|
+
|
|
100
|
+
#### Implementation Details
|
|
101
|
+
|
|
102
|
+
**1. Extend Page Schema**
|
|
103
|
+
```javascript
|
|
104
|
+
// server/schemas/page.js
|
|
105
|
+
{ name:'content_type', type:'string', enumValues:['wysiwyg','code','plugin','module','spa'] }
|
|
106
|
+
// Add fields: spa_component, form_definition_id
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**2. Create React Form Plugin**
|
|
110
|
+
```javascript
|
|
111
|
+
// server/plugins/reactForm.js
|
|
112
|
+
this.render = function(data, req) {
|
|
113
|
+
var page = data.page;
|
|
114
|
+
var formDef = loadFormDefinition(page.form_definition_id);
|
|
115
|
+
// Return HTML with:
|
|
116
|
+
// - React libraries (CDN or includes)
|
|
117
|
+
// - Form definition as JSON in <script> tag
|
|
118
|
+
// - React component mount point
|
|
119
|
+
// - Submission handler that calls JOE API
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**3. Submission Handling**
|
|
124
|
+
- Plugin generates submission handler that posts to existing formBuilder endpoint
|
|
125
|
+
- Maps JSON form format to JOE submission format
|
|
126
|
+
|
|
127
|
+
#### Pros
|
|
128
|
+
- ✅ Native JOE integration
|
|
129
|
+
- ✅ Form definitions can be stored as JOE items
|
|
130
|
+
- ✅ Consistent with other page content types
|
|
131
|
+
- ✅ Can be configured through JOE UI
|
|
132
|
+
|
|
133
|
+
#### Cons
|
|
134
|
+
- ⚠️ Requires schema changes to page
|
|
135
|
+
- ⚠️ More complex implementation
|
|
136
|
+
- ⚠️ Need to handle React bundling/delivery
|
|
137
|
+
|
|
138
|
+
#### Estimated Effort
|
|
139
|
+
- **Medium**: ~4-5 days
|
|
140
|
+
- Schema extensions: 2-4 hours
|
|
141
|
+
- React form plugin: 1-2 days
|
|
142
|
+
- React bundling strategy: 4-8 hours
|
|
143
|
+
- UI for configuring SPA pages: 4-6 hours
|
|
144
|
+
- Testing: 1 day
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
### **Option 3: Module Type with Server-Side React Rendering**
|
|
149
|
+
|
|
150
|
+
#### Architecture
|
|
151
|
+
- **Page Type**: `content_type: 'module'`
|
|
152
|
+
- **SSR**: Use React server-side rendering (via `react-dom/server`)
|
|
153
|
+
- **Hydration**: Client-side React app for interactivity
|
|
154
|
+
|
|
155
|
+
#### Implementation Details
|
|
156
|
+
|
|
157
|
+
**1. Module Function**
|
|
158
|
+
```javascript
|
|
159
|
+
// Page content (module type)
|
|
160
|
+
module.exports = async function(content) {
|
|
161
|
+
var React = require('react');
|
|
162
|
+
var ReactDOMServer = require('react-dom/server');
|
|
163
|
+
var FormApp = require('./path/to/react-form-spa-ex.js');
|
|
164
|
+
var formDef = loadFormDefinition(content.PAGE.meta.form_definition_id);
|
|
165
|
+
|
|
166
|
+
var html = ReactDOMServer.renderToString(
|
|
167
|
+
React.createElement(FormApp, { formDefinition: formDef })
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
return `<div id="root">${html}</div>
|
|
171
|
+
<script>window.__FORM_DEF__ = ${JSON.stringify(formDef)};</script>
|
|
172
|
+
<script src="/_include/{react-bundle-id}"></script>`;
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**2. Client Hydration**
|
|
177
|
+
- React app mounts and hydrates the server-rendered HTML
|
|
178
|
+
- Handles form submission to JOE API
|
|
179
|
+
|
|
180
|
+
#### Pros
|
|
181
|
+
- ✅ SEO-friendly (server-rendered)
|
|
182
|
+
- ✅ Faster initial render
|
|
183
|
+
- ✅ Uses existing module type
|
|
184
|
+
|
|
185
|
+
#### Cons
|
|
186
|
+
- ⚠️ Requires React SSR dependencies on server
|
|
187
|
+
- ⚠️ More complex build/deployment
|
|
188
|
+
- ⚠️ Node.js React dependencies add overhead
|
|
189
|
+
- ⚠️ Hydration complexity
|
|
190
|
+
|
|
191
|
+
#### Estimated Effort
|
|
192
|
+
- **Medium-High**: ~5-7 days
|
|
193
|
+
- SSR setup: 1-2 days
|
|
194
|
+
- Hydration logic: 1 day
|
|
195
|
+
- Build configuration: 1 day
|
|
196
|
+
- Testing/debugging: 2-3 days
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
### **Option 4: Hybrid - Form Definition Schema + React Include**
|
|
201
|
+
|
|
202
|
+
#### Architecture
|
|
203
|
+
- **New Schema**: `form_definition` schema to store JSON form definitions
|
|
204
|
+
- **Form Mapping**: Bridge between JSON form format and JOE form/question schemas
|
|
205
|
+
- **Page**: Code or module type that loads React app and form definition
|
|
206
|
+
|
|
207
|
+
#### Implementation Details
|
|
208
|
+
|
|
209
|
+
**1. Create Form Definition Schema**
|
|
210
|
+
```javascript
|
|
211
|
+
// server/schemas/form_definition.js
|
|
212
|
+
{
|
|
213
|
+
name: 'form_definition',
|
|
214
|
+
fields: [
|
|
215
|
+
{ name: 'form_id', type: 'string' }, // matches form-qs.json formId
|
|
216
|
+
{ name: 'definition', type: 'object' }, // full form-qs.json structure
|
|
217
|
+
{ name: 'form', type: 'string', isReference: true } // link to JOE form
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**2. Form Bridge Service**
|
|
223
|
+
```javascript
|
|
224
|
+
// server/plugins/formBridge.js
|
|
225
|
+
// Convert form-qs.json format to JOE form/questions
|
|
226
|
+
// Or: Store JSON format, map on-the-fly for submissions
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**3. React App**
|
|
230
|
+
- Loads form definition from API
|
|
231
|
+
- Renders form
|
|
232
|
+
- Submits in format compatible with JOE submissions
|
|
233
|
+
|
|
234
|
+
#### Pros
|
|
235
|
+
- ✅ JSON form definitions stored as first-class JOE items
|
|
236
|
+
- ✅ Can sync/import from external JSON files
|
|
237
|
+
- ✅ Separation of concerns (definition vs. rendering)
|
|
238
|
+
- ✅ Can potentially auto-generate JOE forms from JSON
|
|
239
|
+
|
|
240
|
+
#### Cons
|
|
241
|
+
- ⚠️ Additional schema to maintain
|
|
242
|
+
- ⚠️ Need mapping/bridge logic
|
|
243
|
+
- ⚠️ More moving parts
|
|
244
|
+
|
|
245
|
+
#### Estimated Effort
|
|
246
|
+
- **Medium**: ~4-5 days
|
|
247
|
+
- Form definition schema: 4-6 hours
|
|
248
|
+
- Bridge/mapping logic: 1-2 days
|
|
249
|
+
- React integration: 1 day
|
|
250
|
+
- Testing: 1 day
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Recommended Approach: **Option 1 with Option 4 Enhancements**
|
|
255
|
+
|
|
256
|
+
### Phase 1: Quick Win (Option 1)
|
|
257
|
+
1. Create API endpoint to serve form definitions (store JSON in includes or files)
|
|
258
|
+
2. Extend formBuilder submission endpoint to accept JSON format submissions
|
|
259
|
+
3. Create React app that:
|
|
260
|
+
- Loads form definition from API
|
|
261
|
+
- Renders form (based on react-form-spa-ex.js)
|
|
262
|
+
- Submits to JOE endpoint
|
|
263
|
+
4. Embed React app in a JOE page via includes
|
|
264
|
+
|
|
265
|
+
### Phase 2: Enhanced (Option 4 additions)
|
|
266
|
+
1. Create `form_definition` schema to store JSON form definitions in JOE
|
|
267
|
+
2. Add UI to import/manage form definitions
|
|
268
|
+
3. Optionally: Auto-create JOE forms from JSON definitions for reporting/admin
|
|
269
|
+
|
|
270
|
+
### Why This Approach?
|
|
271
|
+
- ✅ **Fastest to implement**: Leverages existing infrastructure
|
|
272
|
+
- ✅ **Low risk**: Minimal changes to core JOE systems
|
|
273
|
+
- ✅ **Flexible**: Can evolve to Option 4 later without breaking changes
|
|
274
|
+
- ✅ **Testable**: Can test React app independently
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Technical Implementation Details
|
|
279
|
+
|
|
280
|
+
### JSON Form Format Mapping
|
|
281
|
+
|
|
282
|
+
The `form-qs.json` format has:
|
|
283
|
+
- `formId`, `formName`, `version`
|
|
284
|
+
- `sections[]` with `fields[]`
|
|
285
|
+
- `visibility` rules with `whenAll`/`whenAny` conditions
|
|
286
|
+
- `dataExport` settings
|
|
287
|
+
|
|
288
|
+
**Mapping to JOE Submissions:**
|
|
289
|
+
```javascript
|
|
290
|
+
{
|
|
291
|
+
itemtype: 'submission',
|
|
292
|
+
form: {joe_form_id}, // reference to JOE form
|
|
293
|
+
form_name: formDef.formName,
|
|
294
|
+
data: {
|
|
295
|
+
// Flattened field values
|
|
296
|
+
first_name: "...",
|
|
297
|
+
last_name: "...",
|
|
298
|
+
// ... all field values
|
|
299
|
+
},
|
|
300
|
+
submission_date: new Date().toISOString(),
|
|
301
|
+
visitor: visitor_id, // from form if configured
|
|
302
|
+
source: req.headers.referer
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### React App Submission Handler
|
|
307
|
+
|
|
308
|
+
```javascript
|
|
309
|
+
async function submitForm(formData, formId) {
|
|
310
|
+
const response = await fetch('/API/plugin/formBuilder/submission', {
|
|
311
|
+
method: 'POST',
|
|
312
|
+
headers: { 'Content-Type': 'application/json' },
|
|
313
|
+
body: JSON.stringify({
|
|
314
|
+
formid: formId, // JOE form ID
|
|
315
|
+
submission: formData // { first_name: "...", ... }
|
|
316
|
+
})
|
|
317
|
+
});
|
|
318
|
+
return response.json();
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Form Definition API
|
|
323
|
+
|
|
324
|
+
```javascript
|
|
325
|
+
// GET /API/plugin/formDefinition/get?formid={id}
|
|
326
|
+
// Returns: form-qs.json format
|
|
327
|
+
{
|
|
328
|
+
formId: "...",
|
|
329
|
+
formName: "...",
|
|
330
|
+
sections: [...],
|
|
331
|
+
settings: {...}
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Migration Path
|
|
338
|
+
|
|
339
|
+
1. **Week 1**: Implement Option 1 (API endpoints + React integration)
|
|
340
|
+
2. **Week 2**: Test with example form, refine submission mapping
|
|
341
|
+
3. **Week 3** (Optional): Implement Option 4 enhancements (form_definition schema)
|
|
342
|
+
4. **Week 4**: Documentation and production deployment
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Open Questions
|
|
347
|
+
|
|
348
|
+
1. **Form Definition Storage**: Store JSON in includes, files, or new schema?
|
|
349
|
+
- **Recommendation**: Start with includes/files, move to schema in Phase 2
|
|
350
|
+
|
|
351
|
+
2. **React Bundling**: Use CDN, bundle via build process, or serve from includes?
|
|
352
|
+
- **Recommendation**: Bundle React app, store as include for versioning
|
|
353
|
+
|
|
354
|
+
3. **Form ID Mapping**: How to map `form-qs.json` `formId` to JOE `form._id`?
|
|
355
|
+
- **Recommendation**: Add `form_json_id` field to form schema, or store mapping in form_definition
|
|
356
|
+
|
|
357
|
+
4. **Visitor Tracking**: How to identify visitors in React SPA context?
|
|
358
|
+
- **Recommendation**: Use existing visitor_id_field mechanism, pass via form definition
|
|
359
|
+
|
|
360
|
+
5. **Validation**: Use React-side validation only, or also JOE-side?
|
|
361
|
+
- **Recommendation**: Client-side for UX, server-side for security (both)
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## Next Steps
|
|
366
|
+
|
|
367
|
+
1. **Decision**: Review options and select approach
|
|
368
|
+
2. **Prototype**: Build minimal POC of selected option
|
|
369
|
+
3. **Refine**: Iterate based on prototype feedback
|
|
370
|
+
4. **Implement**: Full implementation
|
|
371
|
+
5. **Test**: Comprehensive testing with example forms
|
|
372
|
+
6. **Deploy**: Production deployment
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## Appendix: File Structure
|
|
377
|
+
|
|
378
|
+
```
|
|
379
|
+
server/
|
|
380
|
+
plugins/
|
|
381
|
+
formDefinition.js (new - serves JSON form definitions)
|
|
382
|
+
formBuilder.js (extend - handle JSON submissions)
|
|
383
|
+
|
|
384
|
+
schemas/
|
|
385
|
+
form_definition.js (optional - Phase 2)
|
|
386
|
+
|
|
387
|
+
includes/
|
|
388
|
+
react-form-bundle.js (bundled React app)
|
|
389
|
+
|
|
390
|
+
pages/
|
|
391
|
+
react-form-example (page with React form)
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
**Document Version**: 1.0
|
|
397
|
+
**Date**: 2026-01-04
|
|
398
|
+
**Author**: AI Assistant + User Collaboration
|