json-object-editor 0.10.636 → 0.10.639

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.
@@ -1,229 +1,229 @@
1
- var schema = {
2
- title: "AI Widget Conversation | ${name||_id}",
3
- display: "AI Convo (new)",
4
- info: "Lightweight conversation log for external AI widgets.",
5
- summary:{
6
- description:'Lightweight, persistent conversation record for embeddable AI widgets.',
7
- purpose:'Use ai_widget_conversation to track widget chats, including model choice, linked ai_assistant, effective system instructions, and a compact messages array. External sites and test pages create/update these records via the chatgpt widgetStart/widgetMessage/widgetHistory endpoints.',
8
- wip:false,
9
- labelField:'name',
10
- defaultSort:{ field:'last_message_at', dir:'desc' },
11
- searchableFields:['name','info','model','assistant_id','source','user_name','_id'],
12
- allowedSorts:['last_message_at','created','joeUpdated','name'],
13
- relationships:{
14
- outbound:[
15
- { field:'assistant', targetSchema:'ai_assistant', cardinality:'one' },
16
- { field:'user', targetSchema:'user', cardinality:'one' },
17
- { field:'tags', targetSchema:'tag', cardinality:'many' }
18
- ],
19
- inbound:{ graphRef:'server/relationships.graph.json' }
20
- },
21
- joeManagedFields:['created','joeUpdated'],
22
- fields:[
23
- { name:'_id', type:'string', required:true },
24
- { name:'itemtype', type:'string', required:true, const:'ai_widget_conversation' },
25
- { name:'name', type:'string' },
26
- { name:'info', type:'string' },
27
- { name:'model', type:'string' },
28
- { name:'assistant', type:'string', isReference:true, targetSchema:'ai_assistant' },
29
- { name:'assistant_id', type:'string' },
30
- { name:'system', type:'string' },
31
- { name:'messages', type:'objectList' },
32
- { name:'last_message_at', type:'string', format:'date-time' },
33
- { name:'source', type:'string' },
34
- { name:'user', type:'string', isReference:true, targetSchema:'user' },
35
- { name:'user_name', type:'string' },
36
- { name:'user_color', type:'string' },
37
- { name:'assistant_color', type:'string' },
38
- { name:'tags', type:'string', isArray:true, isReference:true, targetSchema:'tag' },
39
- { name:'joeUpdated', type:'string', format:'date-time' },
40
- { name:'created', type:'string', format:'date-time' }
41
- ]
42
- },
43
- listView: {
44
- title: function (convo) {
45
- try{
46
- var ts = convo.last_message_at || convo.joeUpdated || convo.created || '';
47
- var prettyTs = (_joe && _joe.Utils && typeof _joe.Utils.prettyPrintDTS === 'function')
48
- ? _joe.Utils.prettyPrintDTS(ts)
49
- : ts;
50
- var title = convo.name || prettyTs || convo._id;
51
-
52
- function textColorForBg(hex){
53
- if (!hex || typeof hex !== 'string' || !/^#?[0-9a-fA-F]{6}$/.test(hex)) return '#000';
54
- var h = (hex[0] === '#') ? hex.slice(1) : hex;
55
- var n = parseInt(h, 16);
56
- var r = (n >> 16) & 0xff;
57
- var g = (n >> 8) & 0xff;
58
- var b = n & 0xff;
59
- var luminance = r * 0.299 + g * 0.587 + b * 0.114;
60
- return luminance > 186 ? '#000' : '#fff';
61
- }
62
-
63
- function chip(label,bg){
64
- if(!label){ return ''; }
65
- var fg = textColorForBg(bg);
66
- return '<span style="display:inline-block;padding:1px 6px;border-radius:999px;font-size:10px;margin-right:4px;background:'+bg+';color:'+fg+';">'
67
- + label + '</span>';
68
- }
69
-
70
- // User chip
71
- var userName = '';
72
- var userColor = convo.user_color || '';
73
- if (convo.user){
74
- var u = $J.get(convo.user,'user') || $J.get(convo.user);
75
- if (u){
76
- userName = u.fullname || u.name || convo.user_name || '';
77
- userColor = u.color || userColor;
78
- }
79
- } else if (convo.user_name){
80
- userName = convo.user_name;
81
- }
82
- var userChip = userName ? chip(userName, userColor || '#4b5563') : '';
83
-
84
- // Assistant chip
85
- var asstName = '';
86
- var asstColor = convo.assistant_color || '';
87
- if (convo.assistant && _joe && _joe.Data && _joe.Data.ai_assistant){
88
- var a = $J.get(convo.assistant,'ai_assistant') ||
89
- _joe.Data.ai_assistant.where({_id:convo.assistant})[0];
90
- if (a){
91
- asstName = a.name || a.title || a.assistant_id || a._id;
92
- asstColor = a.assistant_color || a.color || asstColor;
93
- }
94
- }
95
- if (!asstName && convo.assistant_id && _joe && _joe.Data && _joe.Data.ai_assistant){
96
- var a2 = _joe.Data.ai_assistant.where({assistant_id:convo.assistant_id})[0];
97
- if (a2){
98
- asstName = a2.name || a2.title || a2.assistant_id || a2._id;
99
- asstColor = a2.assistant_color || a2.color || asstColor;
100
- }else{
101
- asstName = convo.assistant_id;
102
- }
103
- }
104
- var asstChip = asstName ? chip(asstName, asstColor || '#2563eb') : '';
105
-
106
- return ''
107
- + '<joe-title>'+title+'</joe-title>'
108
- + '<joe-subtitle>'+userChip+asstChip+'</joe-subtitle>'
109
- + (prettyTs ? '<joe-subtext>'+prettyTs+'</joe-subtext>' : '');
110
- }catch(e){
111
- return '<joe-title>'+(convo.name||convo._id)+'</joe-title>';
112
- }
113
- },
114
- listWindowTitle: "AI Widget Conversations"
115
- },
116
- fields: function () {
117
- return [
118
- "name",
119
- "info",
120
- {section_start:"participants"},
121
- {
122
- name: "user",
123
- type: "select",
124
- values: "user",
125
- display: "User (JOE)",
126
- comment: "User of this conversation.",
127
- width: "50%",
128
- blank:true
129
- },
130
- {
131
- name: "assistant",
132
- type: "select",
133
- values: "ai_assistant",
134
- display: "Assistant (JOE)",
135
- comment: "Optional link to an ai_assistant config used by this widget.",
136
- width: "50%",
137
- blank:true
138
- },
139
- {section_end:"participants"},
140
- { section_start: "conversation", display: "Conversation", collapsed: false },
141
- {
142
- name: "model",
143
- type: "select",
144
- values: "ai_model",
145
- display: "Model",
146
- comment: "Default OpenAI model used for this conversation.",
147
- width: "50%"
148
- },
149
- {
150
- name: "assistant_id",
151
- type: "text",
152
- display: "OpenAI Assistant ID",
153
- comment: "Optional OpenAI assistant used for this conversation."
154
- },
155
- {
156
- name: "system",
157
- type: "code",
158
- display: "System Instructions",
159
- height: "160px",
160
- comment: "Effective system prompt used for this conversation."
161
- },
162
- {
163
- name: "messages",
164
- type: "code",
165
- display: "Messages (JSON)",
166
- height: "260px",
167
- comment: "Array of {role, content, created_at}. Managed by the widget API."
168
- },
169
- {
170
- name: "last_message_at",
171
- type: "date",
172
- display: "Last Message At",
173
- locked: true
174
- },
175
- { section_end: "conversation" },
176
-
177
- { section_start: "meta", collapsed: true },
178
- "source",
179
- "tags",
180
- { section_end: "meta" },
181
-
182
- { section_start: "system", collapsed: true },
183
- "_id",
184
- "created",
185
- "joeUpdated",
186
- "itemtype",
187
- { section_end: "system" }
188
- ];
189
- },
190
-
191
- // Subsets: grouped quick-filters in the list submenu
192
- subsets:function(){
193
- var sets = [];
194
- // Group by source (e.g., aihub_card, widget, etc.)
195
- sets = sets.concat(
196
- _joe.Filter.Options.getDatasetPropertyValues('ai_widget_conversation','source',{
197
- group:'source'
198
- })
199
- );
200
- return sets;
201
- },
202
-
203
- // Filters: sidebar filters
204
- filters:function(){
205
- var filters = [];
206
-
207
- // Distinct users referenced by ai_widget_conversation.user
208
- filters = filters.concat(
209
- _joe.Filter.Options.datasetProperty('user','user',{
210
- group:'user',
211
- collapsed:true
212
- }),
213
- // Distinct assistants (JOE ai_assistant) referenced by this conversation
214
- _joe.Filter.Options.datasetProperty('ai_assistant','assistant',{
215
- group:'assistant',
216
- collapsed:true
217
- })
218
- );
219
-
220
- return filters;
221
- },
222
-
223
- idprop: "_id",
224
- sorter: ["!last_message_at", "!created"]
225
- };
226
-
227
- module.exports = schema;
228
-
229
-
1
+ var schema = {
2
+ title: "AI Widget Conversation | ${name||_id}",
3
+ display: "AI Convo (new)",
4
+ info: "Lightweight conversation log for external AI widgets.",
5
+ summary:{
6
+ description:'Lightweight, persistent conversation record for embeddable AI widgets.',
7
+ purpose:'Use ai_widget_conversation to track widget chats, including model choice, linked ai_assistant, effective system instructions, and a compact messages array. External sites and test pages create/update these records via the chatgpt widgetStart/widgetMessage/widgetHistory endpoints.',
8
+ wip:false,
9
+ labelField:'name',
10
+ defaultSort:{ field:'last_message_at', dir:'desc' },
11
+ searchableFields:['name','info','model','assistant_id','source','user_name','_id'],
12
+ allowedSorts:['last_message_at','created','joeUpdated','name'],
13
+ relationships:{
14
+ outbound:[
15
+ { field:'assistant', targetSchema:'ai_assistant', cardinality:'one' },
16
+ { field:'user', targetSchema:'user', cardinality:'one' },
17
+ { field:'tags', targetSchema:'tag', cardinality:'many' }
18
+ ],
19
+ inbound:{ graphRef:'server/relationships.graph.json' }
20
+ },
21
+ joeManagedFields:['created','joeUpdated'],
22
+ fields:[
23
+ { name:'_id', type:'string', required:true },
24
+ { name:'itemtype', type:'string', required:true, const:'ai_widget_conversation' },
25
+ { name:'name', type:'string' },
26
+ { name:'info', type:'string' },
27
+ { name:'model', type:'string' },
28
+ { name:'assistant', type:'string', isReference:true, targetSchema:'ai_assistant' },
29
+ { name:'assistant_id', type:'string' },
30
+ { name:'system', type:'string' },
31
+ { name:'messages', type:'objectList' },
32
+ { name:'last_message_at', type:'string', format:'date-time' },
33
+ { name:'source', type:'string' },
34
+ { name:'user', type:'string', isReference:true, targetSchema:'user' },
35
+ { name:'user_name', type:'string' },
36
+ { name:'user_color', type:'string' },
37
+ { name:'assistant_color', type:'string' },
38
+ { name:'tags', type:'string', isArray:true, isReference:true, targetSchema:'tag' },
39
+ { name:'joeUpdated', type:'string', format:'date-time' },
40
+ { name:'created', type:'string', format:'date-time' }
41
+ ]
42
+ },
43
+ listView: {
44
+ title: function (convo) {
45
+ try{
46
+ var ts = convo.last_message_at || convo.joeUpdated || convo.created || '';
47
+ var prettyTs = (_joe && _joe.Utils && typeof _joe.Utils.prettyPrintDTS === 'function')
48
+ ? _joe.Utils.prettyPrintDTS(ts)
49
+ : ts;
50
+ var title = convo.name || prettyTs || convo._id;
51
+
52
+ function textColorForBg(hex){
53
+ if (!hex || typeof hex !== 'string' || !/^#?[0-9a-fA-F]{6}$/.test(hex)) return '#000';
54
+ var h = (hex[0] === '#') ? hex.slice(1) : hex;
55
+ var n = parseInt(h, 16);
56
+ var r = (n >> 16) & 0xff;
57
+ var g = (n >> 8) & 0xff;
58
+ var b = n & 0xff;
59
+ var luminance = r * 0.299 + g * 0.587 + b * 0.114;
60
+ return luminance > 186 ? '#000' : '#fff';
61
+ }
62
+
63
+ function chip(label,bg){
64
+ if(!label){ return ''; }
65
+ var fg = textColorForBg(bg);
66
+ return '<span style="display:inline-block;padding:1px 6px;border-radius:999px;font-size:10px;margin-right:4px;background:'+bg+';color:'+fg+';">'
67
+ + label + '</span>';
68
+ }
69
+
70
+ // User chip
71
+ var userName = '';
72
+ var userColor = convo.user_color || '';
73
+ if (convo.user){
74
+ var u = $J.get(convo.user,'user') || $J.get(convo.user);
75
+ if (u){
76
+ userName = u.fullname || u.name || convo.user_name || '';
77
+ userColor = u.color || userColor;
78
+ }
79
+ } else if (convo.user_name){
80
+ userName = convo.user_name;
81
+ }
82
+ var userChip = userName ? chip(userName, userColor || '#4b5563') : '';
83
+
84
+ // Assistant chip
85
+ var asstName = '';
86
+ var asstColor = convo.assistant_color || '';
87
+ if (convo.assistant && _joe && _joe.Data && _joe.Data.ai_assistant){
88
+ var a = $J.get(convo.assistant,'ai_assistant') ||
89
+ _joe.Data.ai_assistant.where({_id:convo.assistant})[0];
90
+ if (a){
91
+ asstName = a.name || a.title || a.assistant_id || a._id;
92
+ asstColor = a.assistant_color || a.color || asstColor;
93
+ }
94
+ }
95
+ if (!asstName && convo.assistant_id && _joe && _joe.Data && _joe.Data.ai_assistant){
96
+ var a2 = _joe.Data.ai_assistant.where({assistant_id:convo.assistant_id})[0];
97
+ if (a2){
98
+ asstName = a2.name || a2.title || a2.assistant_id || a2._id;
99
+ asstColor = a2.assistant_color || a2.color || asstColor;
100
+ }else{
101
+ asstName = convo.assistant_id;
102
+ }
103
+ }
104
+ var asstChip = asstName ? chip(asstName, asstColor || '#2563eb') : '';
105
+
106
+ return ''
107
+ + '<joe-title>'+title+'</joe-title>'
108
+ + '<joe-subtitle>'+userChip+asstChip+'</joe-subtitle>'
109
+ + (prettyTs ? '<joe-subtext>'+prettyTs+'</joe-subtext>' : '');
110
+ }catch(e){
111
+ return '<joe-title>'+(convo.name||convo._id)+'</joe-title>';
112
+ }
113
+ },
114
+ listWindowTitle: "AI Widget Conversations"
115
+ },
116
+ fields: function () {
117
+ return [
118
+ "name",
119
+ "info",
120
+ {section_start:"participants"},
121
+ {
122
+ name: "user",
123
+ type: "select",
124
+ values: "user",
125
+ display: "User (JOE)",
126
+ comment: "User of this conversation.",
127
+ width: "50%",
128
+ blank:true
129
+ },
130
+ {
131
+ name: "assistant",
132
+ type: "select",
133
+ values: "ai_assistant",
134
+ display: "Assistant (JOE)",
135
+ comment: "Optional link to an ai_assistant config used by this widget.",
136
+ width: "50%",
137
+ blank:true
138
+ },
139
+ {section_end:"participants"},
140
+ { section_start: "conversation", display: "Conversation", collapsed: false },
141
+ {
142
+ name: "model",
143
+ type: "select",
144
+ values: "ai_model",
145
+ display: "Model",
146
+ comment: "Default OpenAI model used for this conversation.",
147
+ width: "50%"
148
+ },
149
+ {
150
+ name: "assistant_id",
151
+ type: "text",
152
+ display: "OpenAI Assistant ID",
153
+ comment: "Optional OpenAI assistant used for this conversation."
154
+ },
155
+ {
156
+ name: "system",
157
+ type: "code",
158
+ display: "System Instructions",
159
+ height: "160px",
160
+ comment: "Effective system prompt used for this conversation."
161
+ },
162
+ {
163
+ name: "messages",
164
+ type: "code",
165
+ display: "Messages (JSON)",
166
+ height: "260px",
167
+ comment: "Array of {role, content, created_at}. Managed by the widget API."
168
+ },
169
+ {
170
+ name: "last_message_at",
171
+ type: "date",
172
+ display: "Last Message At",
173
+ locked: true
174
+ },
175
+ { section_end: "conversation" },
176
+
177
+ { section_start: "meta", collapsed: true },
178
+ "source",
179
+ "tags",
180
+ { section_end: "meta" },
181
+
182
+ { section_start: "system", collapsed: true },
183
+ "_id",
184
+ "created",
185
+ "joeUpdated",
186
+ "itemtype",
187
+ { section_end: "system" }
188
+ ];
189
+ },
190
+
191
+ // Subsets: grouped quick-filters in the list submenu
192
+ subsets:function(){
193
+ var sets = [];
194
+ // Group by source (e.g., aihub_card, widget, etc.)
195
+ sets = sets.concat(
196
+ _joe.Filter.Options.getDatasetPropertyValues('ai_widget_conversation','source',{
197
+ group:'source'
198
+ })
199
+ );
200
+ return sets;
201
+ },
202
+
203
+ // Filters: sidebar filters
204
+ filters:function(){
205
+ var filters = [];
206
+
207
+ // Distinct users referenced by ai_widget_conversation.user
208
+ filters = filters.concat(
209
+ _joe.Filter.Options.datasetProperty('user','user',{
210
+ group:'user',
211
+ collapsed:true
212
+ }),
213
+ // Distinct assistants (JOE ai_assistant) referenced by this conversation
214
+ _joe.Filter.Options.datasetProperty('ai_assistant','assistant',{
215
+ group:'assistant',
216
+ collapsed:true
217
+ })
218
+ );
219
+
220
+ return filters;
221
+ },
222
+
223
+ idprop: "_id",
224
+ sorter: ["!last_message_at", "!created"]
225
+ };
226
+
227
+ module.exports = schema;
228
+
229
+
@@ -2,6 +2,47 @@ var form ={
2
2
  title: '${name}',
3
3
  info:"Build a form to collect information from your audience. Add questions from the question panel.",
4
4
  menuicon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="-8 -8 48 48"><path d="M16 2C14.7 2 13.8 2.9 13.4 4L11 4 6 4 5 4 5 5 5 28 5 29 6 29 26 29 27 29 27 28 27 5 27 4 26 4 21 4 18.6 4C18.2 2.9 17.3 2 16 2zM16 4C16.6 4 17 4.4 17 5L17 6 18 6 20 6 20 8 12 8 12 6 14 6 15 6 15 5C15 4.4 15.4 4 16 4zM7 6L10 6 10 9 10 10 11 10 21 10 22 10 22 9 22 6 25 6 25 27 7 27 7 6zM9 12L9 13 9 16 9 17 10 17 13 17 14 17 14 16 14 13 14 12 13 12 10 12 9 12zM16 13L16 15 23 15 23 13 16 13zM11 14L12 14 12 15 11 15 11 14zM9 19L9 24 14 24 14 19 9 19zM16 20L16 22 23 22 23 20 16 20z"/></svg>',
5
+ // Curated summary for agents
6
+ summary:{
7
+ description:'Form builder for collecting structured data from visitors with sections and questions.',
8
+ purpose:'Forms collect data from visitors through questions organized into sections. A form references questions for visitor ID and submission date tracking, can include code assets (includes), and supports custom validation and server actions. Forms are used in the Questionnaire and Church apps.',
9
+ labelField:'name',
10
+ defaultSort:{ field:'joeUpdated', dir:'desc' },
11
+ searchableFields:['name','info','_id'],
12
+ allowedSorts:['joeUpdated','created','name'],
13
+ relationships:{
14
+ outbound:[
15
+ { field:'visitor_id_field', targetSchema:'question', cardinality:'one' },
16
+ { field:'submission_date_field', targetSchema:'question', cardinality:'one' },
17
+ { field:'questions', targetSchema:'question', cardinality:'many' },
18
+ { field:'includes', targetSchema:'include', cardinality:'many' },
19
+ { field:'tags', targetSchema:'tag', cardinality:'many' }
20
+ ],
21
+ inbound:{ graphRef:'server/relationships.graph.json' }
22
+ },
23
+ joeManagedFields:['created','joeUpdated'],
24
+ fields:[
25
+ { name:'_id', type:'string', required:true },
26
+ { name:'itemtype', type:'string', required:true, const:'form' },
27
+ { name:'name', type:'string', required:true },
28
+ { name:'info', type:'string' },
29
+ { name:'visitor_id_field', type:'string', isReference:true, targetSchema:'question' },
30
+ { name:'submission_date_field', type:'string', isReference:true, targetSchema:'question' },
31
+ { name:'sections', type:'objectList' },
32
+ { name:'questions', type:'string', isArray:true, isReference:true, targetSchema:'question' },
33
+ { name:'validate', type:'code' },
34
+ { name:'callback', type:'code' },
35
+ { name:'server_action', type:'code' },
36
+ { name:'form_button_label', type:'string' },
37
+ { name:'hostname', type:'string' },
38
+ { name:'save_submission', type:'boolean' },
39
+ { name:'upsert_submission', type:'boolean' },
40
+ { name:'includes', type:'string', isArray:true, isReference:true, targetSchema:'include' },
41
+ { name:'tags', type:'string', isArray:true, isReference:true, targetSchema:'tag' },
42
+ { name:'joeUpdated', type:'string', format:'date-time', required:true },
43
+ { name:'created', type:'string', format:'date-time', required:true }
44
+ ]
45
+ },
5
46
  fields:[
6
47
  'name',
7
48
  { name:'visitor_id_field',
@@ -3,6 +3,30 @@ var schema = {
3
3
  title : '${name}',
4
4
  //menuicon:'<svg xmlns="https://www.w3.org/TR/SVG/" viewBox="-10 -10 120 120"><path d="M33.91,51.07a19.75,19.75,0,0,1-1.5-2.59l-.17-.29-.1-.28a19.5,19.5,0,1,1,35.71,0l-.21.49,0,.05A19.74,19.74,0,0,1,66.11,51L50,78.95ZM50,24.89a13,13,0,1,0,13,13A13,13,0,0,0,50,24.89Z"/><path d="M50,21.05A19,19,0,0,1,67.4,47.7l-.2.46,0,0,0,0,0,0a19,19,0,0,1-1.44,2.49l0,0,0,0L50,77.95,34.34,50.82l0,0,0,0a19.06,19.06,0,0,1-1.44-2.49l0,0,0,0,0,0-.2-.46A19,19,0,0,1,50,21.05m0,30.33a13.5,13.5,0,1,0-13.5-13.5A13.52,13.52,0,0,0,50,51.39m0-31.33A20,20,0,0,0,31.69,48.11h-.07l.34.59a20,20,0,0,0,1.52,2.63L50,79.95,66.53,51.32A20,20,0,0,0,68,48.7l.34-.59h-.07A20,20,0,0,0,50,20.05Zm0,30.33a12.5,12.5,0,1,1,12.5-12.5A12.5,12.5,0,0,1,50,50.39Z"/></svg>',
5
5
  menuicon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="-9 -9 44 44" ><path d="M13 0C9.7 0 7 2.7 7 6 7 9.3 12.2 17.5 12.2 22L13.8 22C13.8 17.6 19 9 19 6 19 2.7 16.3 0 13 0zM13 3C14.7 3 16 4.3 16 6 16 7.7 14.7 9 13 9 11.3 9 10 7.7 10 6 10 4.3 11.3 3 13 3zM6.8 17.3A1 1 0 0 0 6.8 17.3C4.9 17.6 3.4 18.1 2.2 18.7 1.6 19 1.1 19.3 0.7 19.8 0.3 20.2 0 20.8 0 21.4 0 22.4 0.6 23.1 1.4 23.6 2.1 24.2 3.1 24.6 4.2 24.9 6.5 25.6 9.6 26 13 26 16.4 26 19.5 25.6 21.8 24.9 22.9 24.6 23.9 24.2 24.6 23.6 25.4 23.1 26 22.4 26 21.4 26 20.8 25.7 20.2 25.3 19.8 24.9 19.3 24.4 19 23.8 18.7 22.6 18.1 21 17.6 19.2 17.3A1 1 0 1 0 18.8 19.3C20.6 19.6 22 20 22.9 20.5 23.4 20.7 23.7 20.9 23.8 21.1 24 21.3 24 21.4 24 21.4 24 21.5 23.9 21.7 23.5 22 23 22.3 22.2 22.7 21.2 23 19.1 23.6 16.2 24 13 24 9.8 24 6.9 23.6 4.8 23 3.8 22.7 3 22.3 2.5 22 2.1 21.7 2 21.5 2 21.4 2 21.4 2 21.3 2.2 21.1 2.3 20.9 2.6 20.7 3.1 20.5 4 20 5.4 19.6 7.1 19.3A1 1 0 1 0 6.8 17.3z"/></svg>',
6
+ // Curated summary for agents
7
+ summary:{
8
+ description:'Physical location with geographic coordinates for mapping and visitor tracking.',
9
+ purpose:'Locations represent places that can be associated with events, visitors, or other entities. They store coordinates (coords) for mapping and are used in the VEM (Visitor Experience Manager) app to track visitor locations.',
10
+ labelField:'name',
11
+ defaultSort:{ field:'joeUpdated', dir:'desc' },
12
+ searchableFields:['name','info','description','_id'],
13
+ allowedSorts:['joeUpdated','created','name'],
14
+ relationships:{
15
+ outbound:[],
16
+ inbound:{ graphRef:'server/relationships.graph.json' }
17
+ },
18
+ joeManagedFields:['created','joeUpdated'],
19
+ fields:[
20
+ { name:'_id', type:'string', required:true },
21
+ { name:'itemtype', type:'string', required:true, const:'location' },
22
+ { name:'name', type:'string', required:true },
23
+ { name:'info', type:'string' },
24
+ { name:'coords', type:'string' },
25
+ { name:'description', type:'string' },
26
+ { name:'joeUpdated', type:'string', format:'date-time', required:true },
27
+ { name:'created', type:'string', format:'date-time', required:true }
28
+ ]
29
+ },
6
30
  listView:{
7
31
  title:
8
32
  '<joe-title>${name}</joe-title>' +
@@ -2,6 +2,41 @@ var schema = {
2
2
  title : '${name}',
3
3
  info:"A member is a site visitor who has created an account to access private site content.",
4
4
  menuicon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="-6 -6 36 36"><path d="M20 5H4C2.9 5 2 5.9 2 7v10c0 1.1 0.9 2 2 2h16c1.1 0 2-0.9 2-2V7C22 5.9 21.1 5 20 5zM8.5 7C9.9 7 11 8.1 11 9.5c0 1.4-1.1 2.5-2.5 2.5S6 10.9 6 9.5C6 8.1 7.1 7 8.5 7zM13 17H4v-1c0-1.7 1.7-2.9 3-3h3c1.2 0.1 3 1.3 3 3V17zM20 15h-5v-2h5V15zM20 11h-5V9h5V11z"/></svg>',
5
+ // Curated summary for agents
6
+ summary:{
7
+ description:'Site visitor account with authentication credentials for accessing private content.',
8
+ purpose:'Members are authenticated site visitors who have created accounts. They can access private content, participate in member-only features, and are managed through the Members app. Members extend the visitor concept with account credentials and profile information.',
9
+ labelField:'name',
10
+ defaultSort:{ field:'joeUpdated', dir:'desc' },
11
+ searchableFields:['name','email','first_name','last_name','info','_id'],
12
+ allowedSorts:['joeUpdated','created','name','email'],
13
+ relationships:{
14
+ outbound:[],
15
+ inbound:{ graphRef:'server/relationships.graph.json' }
16
+ },
17
+ joeManagedFields:['created','joeUpdated'],
18
+ fields:[
19
+ { name:'_id', type:'string', required:true },
20
+ { name:'itemtype', type:'string', required:true, const:'member' },
21
+ { name:'name', type:'string', required:true, comment:'username' },
22
+ { name:'password', type:'string' },
23
+ { name:'info', type:'string' },
24
+ { name:'first_name', type:'string' },
25
+ { name:'last_name', type:'string' },
26
+ { name:'email', type:'string' },
27
+ { name:'phone', type:'string' },
28
+ { name:'address', type:'string' },
29
+ { name:'postal_code', type:'string' },
30
+ { name:'country', type:'string' },
31
+ { name:'image', type:'string' },
32
+ { name:'private', type:'boolean' },
33
+ { name:'description', type:'string', comment:'member bio' },
34
+ { name:'member_info', type:'object' },
35
+ { name:'token', type:'string' },
36
+ { name:'joeUpdated', type:'string', format:'date-time', required:true },
37
+ { name:'created', type:'string', format:'date-time', required:true }
38
+ ]
39
+ },
5
40
  listView:{
6
41
  title: '<joe-title>${name}</joe-title>'
7
42
  +'<joe-subtitle>${first_name} ${last_name}</joe-subtitle><joe-subtext>${email}</joe-subtext>',
@@ -1,6 +1,42 @@
1
1
  var question ={
2
2
  title: 'Q | ${name}',
3
3
  info:"The question panel is where you can manage the questions used to build a form.",
4
+ // Curated summary for agents
5
+ summary:{
6
+ description:'Reusable question definition used to build forms with various input types.',
7
+ purpose:'Questions define form field types (text, select, boolean, etc.) and can be organized into forms. Questions can reference datasets for select/multiple types, can be marked as usable for visitor ID or submission date tracking, and are categorized with tags. Questions are used in the Questionnaire and Church apps.',
8
+ labelField:'name',
9
+ defaultSort:{ field:'joeUpdated', dir:'desc' },
10
+ searchableFields:['name','info','title','fieldname','_id'],
11
+ allowedSorts:['joeUpdated','created','name','question_type'],
12
+ relationships:{
13
+ outbound:[
14
+ { field:'tags', targetSchema:'tag', cardinality:'many' }
15
+ ],
16
+ inbound:{ graphRef:'server/relationships.graph.json' }
17
+ },
18
+ joeManagedFields:['created','joeUpdated'],
19
+ fields:[
20
+ { name:'_id', type:'string', required:true },
21
+ { name:'itemtype', type:'string', required:true, const:'question' },
22
+ { name:'name', type:'string', required:true },
23
+ { name:'info', type:'string' },
24
+ { name:'title', type:'string' },
25
+ { name:'fieldname', type:'string' },
26
+ { name:'question_type', type:'string', enumValues:['oneline','textarea','select','boolean','multiple','content','password','number'] },
27
+ { name:'question_dataset', type:'string' },
28
+ { name:'option_template', type:'string' },
29
+ { name:'value_template', type:'string' },
30
+ { name:'options', type:'objectList' },
31
+ { name:'content', type:'code' },
32
+ { name:'required', type:'boolean' },
33
+ { name:'canBeId', type:'boolean' },
34
+ { name:'canBeDate', type:'boolean' },
35
+ { name:'tags', type:'string', isArray:true, isReference:true, targetSchema:'tag' },
36
+ { name:'joeUpdated', type:'string', format:'date-time', required:true },
37
+ { name:'created', type:'string', format:'date-time', required:true }
38
+ ]
39
+ },
4
40
  subsets:function(){
5
41
  return [{name:'Required',filter:{required:true},stripeColor:'#ff9999'}
6
42