@saltcorn/builder 0.8.2-beta.0 → 0.8.3-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saltcorn/builder",
3
- "version": "0.8.2-beta.0",
3
+ "version": "0.8.3-alpha.0",
4
4
  "description": "Drag and drop view builder for Saltcorn, open-source no-code platform",
5
5
  "main": "index.js",
6
6
  "homepage": "https://saltcorn.com",
@@ -3,6 +3,7 @@
3
3
  * @module components/elements/JoinField
4
4
  * @subcategory components / elements
5
5
  */
6
+ /* eslint-env jquery */
6
7
 
7
8
  import React, { useContext, useEffect, Fragment } from "react";
8
9
  import { useNode } from "@craftjs/core";
@@ -65,6 +66,302 @@ const JoinField = ({ name, block, fieldview, textStyle }) => {
65
66
  );
66
67
  };
67
68
 
69
+ const buildFieldsMenu = (options, setProp, refetchPreview) => {
70
+ const { join_field_options } = options.join_field_picker_data;
71
+ return (
72
+ <div className="dropdown">
73
+ <button
74
+ id="f-top-dropdown"
75
+ type="button"
76
+ onClick={() => {
77
+ $(
78
+ "#f-top-dropdown,.dropdown-submenu.show,#r-top-dropdown.show"
79
+ ).dropdown("toggle");
80
+ }}
81
+ className="btn btn-outline-primary dropdown-toggle"
82
+ aria-expanded="false"
83
+ >
84
+ Fields
85
+ </button>
86
+ <div className="dropdown-menu">
87
+ <ul className="ps-0 mb-0">
88
+ {join_field_options
89
+ .filter(
90
+ (field) =>
91
+ field.subFields &&
92
+ field.subFields.find(
93
+ ({ fieldPath }) =>
94
+ options.parent_field_list.indexOf(fieldPath) >= 0
95
+ )
96
+ )
97
+ .map((field) => {
98
+ return (
99
+ <li
100
+ key={`_li_${field.fieldPath}`}
101
+ className="dropdown-item dropstart"
102
+ >
103
+ <div
104
+ id={`_field_${field.fieldPath}`}
105
+ className="dropdown-toggle dropdown-submenu"
106
+ onClick={toggleSubmenu}
107
+ role="button"
108
+ aria-expanded="false"
109
+ >
110
+ {field.name}
111
+ </div>
112
+ <div className="dropdown-menu">
113
+ <h5 className="join-table-header">{field.table}</h5>
114
+ <ul className="ps-0">
115
+ {field.subFields
116
+ .filter(
117
+ (f) =>
118
+ options.parent_field_list.indexOf(f.fieldPath) >= 0
119
+ )
120
+ .map((subOne) => {
121
+ return subOne.subFields &&
122
+ subOne.subFields.length > 0 ? (
123
+ <li
124
+ key={`_li_${subOne.fieldPath}`}
125
+ className="dropdown-item dropstart"
126
+ >
127
+ <div
128
+ id={`_field_${subOne.fieldPath}`}
129
+ className="dropdown-toggle dropdown-submenu"
130
+ onClick={toggleSubmenu}
131
+ role="button"
132
+ aria-expanded="false"
133
+ >
134
+ {subOne.name}
135
+ </div>
136
+ <div className="dropdown-menu">
137
+ <h5 className="join-table-header">
138
+ {subOne.table}
139
+ </h5>
140
+ <ul className="ps-0">
141
+ {subOne.subFields
142
+ .filter(
143
+ (f) =>
144
+ options.parent_field_list.indexOf(
145
+ f.fieldPath
146
+ ) >= 0
147
+ )
148
+ .map((subTwo) => {
149
+ return subTwo.subFields &&
150
+ subTwo.subFields.length > 0 ? (
151
+ <li
152
+ key={`_li_${subTwo.fieldPath}`}
153
+ className="dropdown-item dropstart"
154
+ >
155
+ <div
156
+ id={`_field_${subTwo.fieldPath}`}
157
+ className="dropdown-toggle dropdown-submenu"
158
+ onClick={toggleSubmenu}
159
+ role="button"
160
+ aria-expanded="false"
161
+ >
162
+ {subTwo.name}
163
+ </div>
164
+ <div className="dropdown-menu">
165
+ <h5 className="join-table-header">
166
+ {subTwo.table}
167
+ </h5>
168
+ <ul className="ps-0">
169
+ {subTwo.subFields
170
+ .filter(
171
+ (f) =>
172
+ options.parent_field_list.indexOf(
173
+ f.fieldPath
174
+ ) >= 0
175
+ )
176
+ .map((subThree) => {
177
+ return (
178
+ <li
179
+ key={`_li_${subThree.fieldPath}`}
180
+ className="dropdown-item field-val-item"
181
+ onClick={(e) =>
182
+ joinFieldClicked(
183
+ subThree.fieldPath,
184
+ setProp,
185
+ options,
186
+ refetchPreview
187
+ )
188
+ }
189
+ role="button"
190
+ >
191
+ {subThree.name}
192
+ </li>
193
+ );
194
+ })}
195
+ </ul>
196
+ </div>
197
+ </li>
198
+ ) : (
199
+ <li
200
+ key={`_li_${subTwo.fieldPath}`}
201
+ className="dropdown-item field-val-item"
202
+ onClick={(e) =>
203
+ joinFieldClicked(
204
+ subTwo.fieldPath,
205
+ setProp,
206
+ options,
207
+ refetchPreview
208
+ )
209
+ }
210
+ role="button"
211
+ >
212
+ {subTwo.name}
213
+ </li>
214
+ );
215
+ })}
216
+ </ul>
217
+ </div>
218
+ </li>
219
+ ) : (
220
+ <li
221
+ key={`_li_${subOne.fieldPath}`}
222
+ className="dropdown-item field-val-item"
223
+ onClick={(e) =>
224
+ joinFieldClicked(
225
+ subOne.fieldPath,
226
+ setProp,
227
+ options,
228
+ refetchPreview
229
+ )
230
+ }
231
+ role="button"
232
+ >
233
+ {subOne.name}
234
+ </li>
235
+ );
236
+ })}
237
+ </ul>
238
+ </div>
239
+ </li>
240
+ );
241
+ })}
242
+ </ul>
243
+ </div>
244
+ </div>
245
+ );
246
+ };
247
+
248
+ const buildRelationsMenu = (
249
+ options,
250
+ setProp,
251
+ refetchPreview,
252
+ hasFieldsPicker
253
+ ) => {
254
+ const { relation_options } = options.join_field_picker_data;
255
+ return (
256
+ <div className={`dropdown ${hasFieldsPicker ? "ps-2" : ""}`}>
257
+ <button
258
+ id="r-top-dropdown"
259
+ type="button"
260
+ onClick={() => {
261
+ $(
262
+ "#r-top-dropdown,.dropdown-submenu.show,#f-top-dropdown.show"
263
+ ).dropdown("toggle");
264
+ }}
265
+ className="btn btn-outline-primary dropdown-toggle"
266
+ aria-expanded="false"
267
+ >
268
+ Relations
269
+ </button>
270
+ <div className="dropdown-menu">
271
+ <ul className="ps-0 mb-0">
272
+ {relation_options
273
+ .filter(
274
+ (join) =>
275
+ options.parent_field_list.find((f) =>
276
+ f.startsWith(join.relationPath)
277
+ ) !== undefined
278
+ )
279
+ .map((join) => {
280
+ return (
281
+ <li
282
+ key={`_li_${join.relationPath}`}
283
+ className="dropdown-item dropstart"
284
+ >
285
+ <div
286
+ id={`_relation_${join.relationPath}`}
287
+ className="dropdown-toggle dropdown-submenu"
288
+ onClick={toggleRelationsSubmenu}
289
+ role="button"
290
+ aria-expanded="false"
291
+ >
292
+ {join.relationPath}
293
+ </div>
294
+ <div className="dropdown-menu">
295
+ <ul className="ps-0 mb-0">
296
+ {join.relationFields
297
+ .filter(
298
+ (fName) =>
299
+ options.parent_field_list.indexOf(
300
+ `${join.relationPath}->${fName}`
301
+ ) >= 0
302
+ )
303
+ .map((fName) => {
304
+ const fullPath = `${join.relationPath}->${fName}`;
305
+ return (
306
+ <li
307
+ key={`_li_${fullPath}`}
308
+ className="dropdown-item field-val-item"
309
+ onClick={(e) => {
310
+ joinFieldClicked(
311
+ fullPath,
312
+ setProp,
313
+ options,
314
+ refetchPreview
315
+ );
316
+ }}
317
+ role="button"
318
+ >
319
+ {fName}
320
+ </li>
321
+ );
322
+ })}
323
+ </ul>
324
+ </div>
325
+ </li>
326
+ );
327
+ })}
328
+ </ul>
329
+ </div>
330
+ </div>
331
+ );
332
+ };
333
+
334
+ function toggleRelationsSubmenu(e) {
335
+ $(".dropdown-submenu.show").dropdown("toggle");
336
+ $(document.getElementById(`${e.target.id}`)).dropdown("toggle");
337
+ }
338
+
339
+ function toggleSubmenu(e) {
340
+ $(document.getElementById(`${e.target.id}`)).dropdown("toggle");
341
+ const clickedField = e.target.id.replace("_field_", "");
342
+ $(".dropdown-submenu.show").each(function (index) {
343
+ const openField = this.id.replace("_field_", "");
344
+ if (clickedField.indexOf(openField) < 0) {
345
+ $(this).dropdown("toggle");
346
+ }
347
+ });
348
+ }
349
+
350
+ function joinFieldClicked(fieldPath, setProp, options, refetchPreview) {
351
+ setProp((prop) => (prop.name = fieldPath));
352
+ const newfvs = options.field_view_options[fieldPath];
353
+ if (newfvs && newfvs.length > 0) {
354
+ setProp((prop) => (prop.fieldview = newfvs[0]));
355
+ refetchPreview({
356
+ name: fieldPath,
357
+ fieldview: newfvs[0],
358
+ });
359
+ } else refetchPreview({ name: fieldPath });
360
+ $(
361
+ ".dropdown-submenu.show,#f-top-dropdown.show,#r-top-dropdown.show"
362
+ ).dropdown("toggle");
363
+ }
364
+
68
365
  export /**
69
366
  * @returns {Fragment}
70
367
  * @namespace
@@ -104,6 +401,10 @@ const JoinFieldSettings = () => {
104
401
  setPreviews,
105
402
  node_id,
106
403
  });
404
+ const showFieldsPicker =
405
+ options.join_field_picker_data?.join_field_options.length > 0;
406
+ const showRelationsPicker =
407
+ options.join_field_picker_data?.relation_options.length > 0;
107
408
  return (
108
409
  <Fragment>
109
410
  <i>
@@ -118,29 +419,31 @@ const JoinFieldSettings = () => {
118
419
  <label>Join field</label>
119
420
  </td>
120
421
  <td>
121
- <select
422
+ <input
423
+ id="inputjoin_field"
424
+ type="text"
425
+ className="form-control bg-white item-menu"
426
+ name="join_field"
427
+ data-fieldname="join_field"
428
+ readOnly="readonly"
122
429
  value={name}
123
- className="form-control form-select"
124
- onChange={(e) => {
125
- if (!e.target) return;
126
- const value = e.target.value;
127
- setProp((prop) => (prop.name = value));
128
- const newfvs = options.field_view_options[value];
129
- if (newfvs && newfvs.length > 0) {
130
- setProp((prop) => (prop.fieldview = newfvs[0]));
131
- refetchPreview({
132
- name: value,
133
- fieldview: newfvs[0],
134
- });
135
- } else refetchPreview({ name: value });
136
- }}
137
- >
138
- {options.parent_field_list.map((f, ix) => (
139
- <option key={ix} value={f}>
140
- {f}
141
- </option>
142
- ))}
143
- </select>
430
+ />
431
+ </td>
432
+ </tr>
433
+
434
+ <tr>
435
+ <td colSpan="2">
436
+ <div className="d-flex">
437
+ {showFieldsPicker &&
438
+ buildFieldsMenu(options, setProp, refetchPreview)}
439
+ {showRelationsPicker &&
440
+ buildRelationsMenu(
441
+ options,
442
+ setProp,
443
+ refetchPreview,
444
+ showFieldsPicker
445
+ )}
446
+ </div>
144
447
  </td>
145
448
  </tr>
146
449
  {fvs && (