@saltcorn/builder 1.6.0-alpha.0 → 1.6.0-alpha.10

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.
Files changed (40) hide show
  1. package/dist/builder_bundle.js +4126 -2
  2. package/dist/builder_bundle.js.LICENSE.txt +18 -51
  3. package/package.json +31 -27
  4. package/src/components/Builder.js +334 -122
  5. package/src/components/Library.js +25 -13
  6. package/src/components/RenderNode.js +19 -8
  7. package/src/components/Toolbox.js +333 -269
  8. package/src/components/elements/Action.js +144 -29
  9. package/src/components/elements/Aggregation.js +20 -23
  10. package/src/components/elements/ArrayManager.js +7 -5
  11. package/src/components/elements/BoxModelEditor.js +19 -17
  12. package/src/components/elements/Card.js +47 -34
  13. package/src/components/elements/Clone.js +74 -2
  14. package/src/components/elements/Column.js +1 -1
  15. package/src/components/elements/Columns.js +27 -25
  16. package/src/components/elements/Container.js +170 -90
  17. package/src/components/elements/DropDownFilter.js +10 -8
  18. package/src/components/elements/DropMenu.js +18 -9
  19. package/src/components/elements/Field.js +9 -7
  20. package/src/components/elements/HTMLCode.js +3 -1
  21. package/src/components/elements/Image.js +20 -15
  22. package/src/components/elements/JoinField.js +15 -11
  23. package/src/components/elements/Link.js +18 -16
  24. package/src/components/elements/ListColumn.js +7 -3
  25. package/src/components/elements/ListColumns.js +4 -1
  26. package/src/components/elements/MonacoEditor.js +4 -2
  27. package/src/components/elements/Page.js +7 -4
  28. package/src/components/elements/RelationBadges.js +16 -11
  29. package/src/components/elements/RelationOnDemandPicker.js +18 -12
  30. package/src/components/elements/SearchBar.js +37 -10
  31. package/src/components/elements/Table.js +72 -65
  32. package/src/components/elements/Tabs.js +18 -15
  33. package/src/components/elements/Text.js +19 -14
  34. package/src/components/elements/ToggleFilter.js +28 -25
  35. package/src/components/elements/View.js +36 -18
  36. package/src/components/elements/ViewLink.js +15 -11
  37. package/src/components/elements/utils.js +224 -55
  38. package/src/components/storage.js +27 -129
  39. package/src/hooks/useTranslation.js +11 -0
  40. package/src/index.js +6 -3
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import React, { useEffect, useContext, Fragment } from "react";
8
+ import useTranslation from "../hooks/useTranslation";
8
9
  import { Element, useEditor } from "@craftjs/core";
9
10
  import { Text } from "./elements/Text";
10
11
  import { HTMLCode } from "./elements/HTMLCode";
@@ -105,18 +106,21 @@ const WrapElem = ({
105
106
  * @subcategory components / Toolbox
106
107
  * @namespace
107
108
  */
108
- const TextElem = ({ connectors }) => (
109
- <WrapElem
110
- connectors={connectors}
111
- icon={<TextareaT className="mb-2" />}
112
- fontSize="22px"
113
- title="Text"
114
- bold
115
- label="Text"
116
- >
117
- <Text text="Hello world" block={false} textStyle={""} />
118
- </WrapElem>
119
- );
109
+ const TextElem = ({ connectors }) => {
110
+ const { t } = useTranslation();
111
+ return (
112
+ <WrapElem
113
+ connectors={connectors}
114
+ icon={<TextareaT className="mb-2" />}
115
+ fontSize="22px"
116
+ title={t("Text")}
117
+ bold
118
+ label={t("Text")}
119
+ >
120
+ <Text text="Hello world" block={false} textStyle={""} />
121
+ </WrapElem>
122
+ );
123
+ };
120
124
  /**
121
125
  * @param {object} props
122
126
  * @param {object} props.connectors
@@ -125,17 +129,20 @@ const TextElem = ({ connectors }) => (
125
129
  * @subcategory components / Toolbox
126
130
  * @namespace
127
131
  */
128
- const ColumnsElem = ({ connectors }) => (
129
- <WrapElem
130
- connectors={connectors}
131
- innerClass="mt-m1px"
132
- icon="fas fa-columns"
133
- title="Split into columns"
134
- label="Columns"
135
- >
136
- <Columns contents={[]} setting_col_n={1} />
137
- </WrapElem>
138
- );
132
+ const ColumnsElem = ({ connectors }) => {
133
+ const { t } = useTranslation();
134
+ return (
135
+ <WrapElem
136
+ connectors={connectors}
137
+ innerClass="mt-m1px"
138
+ icon="fas fa-columns"
139
+ title={t("Split into columns")}
140
+ label={t("Columns")}
141
+ >
142
+ <Columns contents={[]} setting_col_n={1} />
143
+ </WrapElem>
144
+ );
145
+ };
139
146
  /**
140
147
  * @param {object} props
141
148
  * @param {object} props.connectors
@@ -144,16 +151,19 @@ const ColumnsElem = ({ connectors }) => (
144
151
  * @subcategory components / Toolbox
145
152
  * @namespace
146
153
  */
147
- const TabsElem = ({ connectors }) => (
148
- <WrapElem
149
- connectors={connectors}
150
- icon={<SegmentedNav className="mb-2 h4" />}
151
- title="Tabbed content"
152
- label="Tabs"
153
- >
154
- <Tabs contents={[]} />
155
- </WrapElem>
156
- );
154
+ const TabsElem = ({ connectors }) => {
155
+ const { t } = useTranslation();
156
+ return (
157
+ <WrapElem
158
+ connectors={connectors}
159
+ icon={<SegmentedNav className="mb-2 h4" />}
160
+ title={t("Tabbed content")}
161
+ label={t("Tabs")}
162
+ >
163
+ <Tabs contents={[]} />
164
+ </WrapElem>
165
+ );
166
+ };
157
167
  /**
158
168
  * @param {object} props
159
169
  * @param {object} props.connectors
@@ -162,17 +172,20 @@ const TabsElem = ({ connectors }) => (
162
172
  * @subcategory components / Toolbox
163
173
  * @namespace
164
174
  */
165
- const LineBreakElem = ({ connectors }) => (
166
- <WrapElem
167
- connectors={connectors}
168
- text="↵"
169
- fontSize="26px"
170
- title="Line break"
171
- label="Break"
172
- >
173
- <LineBreak />
174
- </WrapElem>
175
- );
175
+ const LineBreakElem = ({ connectors }) => {
176
+ const { t } = useTranslation();
177
+ return (
178
+ <WrapElem
179
+ connectors={connectors}
180
+ text=""
181
+ fontSize="26px"
182
+ title={t("Line break")}
183
+ label={t("Break")}
184
+ >
185
+ <LineBreak />
186
+ </WrapElem>
187
+ );
188
+ };
176
189
  /**
177
190
  * @param {object} props
178
191
  * @param {object} props.connectors
@@ -181,16 +194,19 @@ const LineBreakElem = ({ connectors }) => (
181
194
  * @subcategory components / Toolbox
182
195
  * @namespace
183
196
  */
184
- const HTMLElem = ({ connectors }) => (
185
- <WrapElem
186
- connectors={connectors}
187
- icon="fas fa-code"
188
- title="HTML code"
189
- label="Code"
190
- >
191
- <HTMLCode text={""} />
192
- </WrapElem>
193
- );
197
+ const HTMLElem = ({ connectors }) => {
198
+ const { t } = useTranslation();
199
+ return (
200
+ <WrapElem
201
+ connectors={connectors}
202
+ icon="fas fa-code"
203
+ title={t("HTML code")}
204
+ label={t("Code")}
205
+ >
206
+ <HTMLCode text={""} />
207
+ </WrapElem>
208
+ );
209
+ };
194
210
  /**
195
211
  * @param {object} props
196
212
  * @param {object} props.connectors
@@ -199,16 +215,19 @@ const HTMLElem = ({ connectors }) => (
199
215
  * @subcategory components / Toolbox
200
216
  * @namespace
201
217
  */
202
- const CardElem = ({ connectors }) => (
203
- <WrapElem
204
- connectors={connectors}
205
- title="Card"
206
- icon="far fa-square"
207
- label="Card"
208
- >
209
- <Element canvas is={Card} isFormula={{}} url=""></Element>
210
- </WrapElem>
211
- );
218
+ const CardElem = ({ connectors }) => {
219
+ const { t } = useTranslation();
220
+ return (
221
+ <WrapElem
222
+ connectors={connectors}
223
+ title={t("Card")}
224
+ icon="far fa-square"
225
+ label={t("Card")}
226
+ >
227
+ <Element canvas is={Card} isFormula={{}} url=""></Element>
228
+ </WrapElem>
229
+ );
230
+ };
212
231
  /**
213
232
  * @param {object} props
214
233
  * @param {object} props.connectors
@@ -217,16 +236,19 @@ const CardElem = ({ connectors }) => (
217
236
  * @subcategory components / Toolbox
218
237
  * @namespace
219
238
  */
220
- const ImageElem = ({ connectors, images }) => (
221
- <WrapElem
222
- connectors={connectors}
223
- icon="fas fa-image"
224
- title="Image"
225
- label="Image"
226
- >
227
- <Image fileid={images.length > 0 ? images[0].id : 0} />
228
- </WrapElem>
229
- );
239
+ const ImageElem = ({ connectors, images }) => {
240
+ const { t } = useTranslation();
241
+ return (
242
+ <WrapElem
243
+ connectors={connectors}
244
+ icon="fas fa-image"
245
+ title={t("Image")}
246
+ label={t("Image")}
247
+ >
248
+ <Image fileid={images.length > 0 ? images[0].id : 0} />
249
+ </WrapElem>
250
+ );
251
+ };
230
252
  /**
231
253
  * @param {object} props
232
254
  * @param {object} props.connectors
@@ -235,16 +257,19 @@ const ImageElem = ({ connectors, images }) => (
235
257
  * @subcategory components / Toolbox
236
258
  * @namespace
237
259
  */
238
- const LinkElem = ({ connectors }) => (
239
- <WrapElem
240
- connectors={connectors}
241
- icon="fas fa-link"
242
- title="Link"
243
- label="Link"
244
- >
245
- <Link />
246
- </WrapElem>
247
- );
260
+ const LinkElem = ({ connectors }) => {
261
+ const { t } = useTranslation();
262
+ return (
263
+ <WrapElem
264
+ connectors={connectors}
265
+ icon="fas fa-link"
266
+ title={t("Link")}
267
+ label={t("Link")}
268
+ >
269
+ <Link />
270
+ </WrapElem>
271
+ );
272
+ };
248
273
  /**
249
274
  * @param {object} props
250
275
  * @param {object} props.connectors
@@ -253,21 +278,24 @@ const LinkElem = ({ connectors }) => (
253
278
  * @subcategory components / Toolbox
254
279
  * @namespace
255
280
  */
256
- const ViewElem = ({ connectors, views, isPageEdit }) => (
257
- <WrapElem
258
- connectors={connectors}
259
- icon="fas fa-eye"
260
- title="Embed a view"
261
- label="View"
262
- disable={!views || views.length < (!isPageEdit ? 2 : 1)}
263
- >
264
- <View
265
- name={"not_assigned"}
266
- state={"shared"}
267
- view={views?.length > 0 ? views[0].name : ""}
268
- />
269
- </WrapElem>
270
- );
281
+ const ViewElem = ({ connectors, views, isPageEdit }) => {
282
+ const { t } = useTranslation();
283
+ return (
284
+ <WrapElem
285
+ connectors={connectors}
286
+ icon="fas fa-eye"
287
+ title={t("Embed a view")}
288
+ label={t("View")}
289
+ disable={!views || views.length < (!isPageEdit ? 2 : 1)}
290
+ >
291
+ <View
292
+ name={"not_assigned"}
293
+ state={"shared"}
294
+ view={views?.length > 0 ? views[0].name : ""}
295
+ />
296
+ </WrapElem>
297
+ );
298
+ };
271
299
  /**
272
300
  * @param {object} props
273
301
  * @param {object} props.connectors
@@ -276,16 +304,19 @@ const ViewElem = ({ connectors, views, isPageEdit }) => (
276
304
  * @subcategory components / Toolbox
277
305
  * @namespace
278
306
  */
279
- const SearchElem = ({ connectors }) => (
280
- <WrapElem
281
- connectors={connectors}
282
- icon="fas fa-search"
283
- title="Search bar"
284
- label="Search"
285
- >
286
- <Element canvas is={SearchBar}></Element>
287
- </WrapElem>
288
- );
307
+ const SearchElem = ({ connectors }) => {
308
+ const { t } = useTranslation();
309
+ return (
310
+ <WrapElem
311
+ connectors={connectors}
312
+ icon="fas fa-search"
313
+ title={t("Search bar")}
314
+ label={t("Search")}
315
+ >
316
+ <Element canvas is={SearchBar}></Element>
317
+ </WrapElem>
318
+ );
319
+ };
289
320
  /**
290
321
  * @param {object} props
291
322
  * @param {object} props.connectors
@@ -294,16 +325,19 @@ const SearchElem = ({ connectors }) => (
294
325
  * @subcategory components / Toolbox
295
326
  * @namespace
296
327
  */
297
- const ContainerElem = ({ connectors }) => (
298
- <WrapElem
299
- connectors={connectors}
300
- icon={<BoundingBox className="mb-2 h5" />}
301
- title="Container"
302
- label="Contain"
303
- >
304
- <Element canvas is={Container}></Element>
305
- </WrapElem>
306
- );
328
+ const ContainerElem = ({ connectors }) => {
329
+ const { t } = useTranslation();
330
+ return (
331
+ <WrapElem
332
+ connectors={connectors}
333
+ icon={<BoundingBox className="mb-2 h5" />}
334
+ title={t("Container")}
335
+ label={t("Contain")}
336
+ >
337
+ <Element canvas is={Container}></Element>
338
+ </WrapElem>
339
+ );
340
+ };
307
341
  /**
308
342
  * @param {object} props
309
343
  * @param {object} props.connectors
@@ -312,22 +346,25 @@ const ContainerElem = ({ connectors }) => (
312
346
  * @subcategory components / Toolbox
313
347
  * @namespace
314
348
  */
315
- const FieldElem = ({ connectors, fields, field_view_options }) => (
316
- <WrapElem
317
- connectors={connectors}
318
- icon="fas fa-asterisk"
319
- title="Field"
320
- label="Field"
321
- >
322
- <Field
323
- name={fields[0].name}
324
- block={false}
325
- textStyle={""}
326
- configuration={{}}
327
- fieldview={fields[0].is_fkey ? "" : field_view_options[fields[0].name][0]}
328
- />
329
- </WrapElem>
330
- );
349
+ const FieldElem = ({ connectors, fields, field_view_options }) => {
350
+ const { t } = useTranslation();
351
+ return (
352
+ <WrapElem
353
+ connectors={connectors}
354
+ icon="fas fa-asterisk"
355
+ title={t("Field")}
356
+ label={t("Field")}
357
+ >
358
+ <Field
359
+ name={fields[0].name}
360
+ block={false}
361
+ textStyle={""}
362
+ configuration={{}}
363
+ fieldview={fields[0].is_fkey ? "" : field_view_options[fields[0].name][0]}
364
+ />
365
+ </WrapElem>
366
+ );
367
+ };
331
368
  /**
332
369
  * @param {object} props
333
370
  * @param {object} props.connectors
@@ -336,44 +373,53 @@ const FieldElem = ({ connectors, fields, field_view_options }) => (
336
373
  * @subcategory components / Toolbox
337
374
  * @namespace
338
375
  */
339
- const DropDownFilterElem = ({ connectors, fields }) => (
340
- <WrapElem
341
- connectors={connectors}
342
- icon="far fa-caret-square-down"
343
- title="Dropdown filter"
344
- label="Select"
345
- >
346
- <DropDownFilter
347
- name={fields[0].name}
348
- block={false}
349
- neutral_label={""}
350
- full_width={false}
351
- />
352
- </WrapElem>
353
- );
376
+ const DropDownFilterElem = ({ connectors, fields }) => {
377
+ const { t } = useTranslation();
378
+ return (
379
+ <WrapElem
380
+ connectors={connectors}
381
+ icon="far fa-caret-square-down"
382
+ title={t("Dropdown filter")}
383
+ label={t("Select")}
384
+ >
385
+ <DropDownFilter
386
+ name={fields[0].name}
387
+ block={false}
388
+ neutral_label={""}
389
+ full_width={false}
390
+ />
391
+ </WrapElem>
392
+ );
393
+ };
354
394
 
355
- const DropMenuElem = ({ connectors }) => (
356
- <WrapElem
357
- connectors={connectors}
358
- icon="far fa-caret-square-down"
359
- title="Dropdown menu"
360
- label="DropMenu"
361
- >
362
- <Element canvas is={DropMenu}></Element>
363
- </WrapElem>
364
- );
395
+ const DropMenuElem = ({ connectors }) => {
396
+ const { t } = useTranslation();
397
+ return (
398
+ <WrapElem
399
+ connectors={connectors}
400
+ icon="far fa-caret-square-down"
401
+ title={t("Dropdown menu")}
402
+ label={t("DropMenu")}
403
+ >
404
+ <Element canvas is={DropMenu}></Element>
405
+ </WrapElem>
406
+ );
407
+ };
365
408
 
366
- const PageElem = ({ connectors, pages }) => (
367
- <WrapElem
368
- connectors={connectors}
369
- icon="fa-fw far fa-file"
370
- title="Embed a page"
371
- label="Page"
372
- disable={pages.length <= 1}
373
- >
374
- <Page page={pages.length > 0 ? pages[0].name : "page"} />
375
- </WrapElem>
376
- );
409
+ const PageElem = ({ connectors, pages }) => {
410
+ const { t } = useTranslation();
411
+ return (
412
+ <WrapElem
413
+ connectors={connectors}
414
+ icon="fa-fw far fa-file"
415
+ title={t("Embed a page")}
416
+ label={t("Page")}
417
+ disable={pages.length <= 1}
418
+ >
419
+ <Page page={pages.length > 0 ? pages[0].name : "page"} />
420
+ </WrapElem>
421
+ );
422
+ };
377
423
 
378
424
  /**
379
425
  * @param {object} props
@@ -383,16 +429,19 @@ const PageElem = ({ connectors, pages }) => (
383
429
  * @subcategory components / Toolbox
384
430
  * @namespace
385
431
  */
386
- const ToggleFilterElem = ({ connectors, fields }) => (
387
- <WrapElem
388
- connectors={connectors}
389
- icon="fas fa-toggle-on"
390
- title="Toggle filter"
391
- label="Toggle"
392
- >
393
- <ToggleFilter name={fields[0].name} value={""} label={""} block={false} />
394
- </WrapElem>
395
- );
432
+ const ToggleFilterElem = ({ connectors, fields }) => {
433
+ const { t } = useTranslation();
434
+ return (
435
+ <WrapElem
436
+ connectors={connectors}
437
+ icon="fas fa-toggle-on"
438
+ title={t("Toggle filter")}
439
+ label={t("Toggle")}
440
+ >
441
+ <ToggleFilter name={fields[0].name} value={""} label={""} block={false} />
442
+ </WrapElem>
443
+ );
444
+ };
396
445
  /**
397
446
  * @param {object} props
398
447
  * @param {object} props.connectors
@@ -401,22 +450,25 @@ const ToggleFilterElem = ({ connectors, fields }) => (
401
450
  * @subcategory components / Toolbox
402
451
  * @namespace
403
452
  */
404
- const JoinFieldElem = ({ connectors, options }) => (
405
- <WrapElem
406
- connectors={connectors}
407
- icon={<Diagram3Fill className="mb-2 h5" />}
408
- title="Join field"
409
- label="Join"
410
- disable={options.parent_field_list.length === 0}
411
- >
412
- <JoinField
413
- name={options.parent_field_list[0]}
414
- configuration={{}}
415
- textStyle={""}
416
- block={false}
417
- />
418
- </WrapElem>
419
- );
453
+ const JoinFieldElem = ({ connectors, options }) => {
454
+ const { t } = useTranslation();
455
+ return (
456
+ <WrapElem
457
+ connectors={connectors}
458
+ icon={<Diagram3Fill className="mb-2 h5" />}
459
+ title={t("Join field")}
460
+ label={t("Join")}
461
+ disable={options.parent_field_list.length === 0}
462
+ >
463
+ <JoinField
464
+ name={options.parent_field_list[0]}
465
+ configuration={{}}
466
+ textStyle={""}
467
+ block={false}
468
+ />
469
+ </WrapElem>
470
+ );
471
+ };
420
472
  /**
421
473
  * @param {object} props
422
474
  * @param {object} props.connectors
@@ -425,22 +477,25 @@ const JoinFieldElem = ({ connectors, options }) => (
425
477
  * @subcategory components / Toolbox
426
478
  * @namespace
427
479
  */
428
- const ViewLinkElem = ({ connectors, options }) => (
429
- <WrapElem
430
- connectors={connectors}
431
- icons={["fas fa-eye", "fas fa-link"]}
432
- title="Link to a view"
433
- label="ViewLink"
434
- disable={!options.views || options.views.length < 2}
435
- >
436
- <ViewLink
437
- name={options.views?.length > 0 ? options.views[0].name : ""}
438
- block={false}
439
- minRole={100}
440
- label={""}
441
- />
442
- </WrapElem>
443
- );
480
+ const ViewLinkElem = ({ connectors, options }) => {
481
+ const { t } = useTranslation();
482
+ return (
483
+ <WrapElem
484
+ connectors={connectors}
485
+ icons={["fas fa-eye", "fas fa-link"]}
486
+ title={t("Link to a view")}
487
+ label={t("ViewLink")}
488
+ disable={!options.views || options.views.length < 2}
489
+ >
490
+ <ViewLink
491
+ name={options.views?.length > 0 ? options.views[0].name : ""}
492
+ block={false}
493
+ minRole={100}
494
+ label={""}
495
+ />
496
+ </WrapElem>
497
+ );
498
+ };
444
499
 
445
500
  /**
446
501
  * @param {object} props
@@ -450,31 +505,34 @@ const ViewLinkElem = ({ connectors, options }) => (
450
505
  * @subcategory components / Toolbox
451
506
  * @namespace
452
507
  */
453
- const ActionElem = ({ connectors, options }) => (
454
- <WrapElem
455
- connectors={connectors}
456
- label="Action"
457
- icon="fas fa-running"
458
- title="Action button"
459
- >
460
- <Action
461
- name={
462
- options.actions[0].optgroup
463
- ? options.actions[0].options[0]
464
- : options.actions[0]
465
- }
466
- action_row_variable={""}
467
- block={false}
468
- minRole={100}
469
- confirm={false}
470
- spinner={true}
471
- action_label={""}
472
- isFormula={{}}
473
- rndid={rand_ident()}
474
- configuration={{}}
475
- />
476
- </WrapElem>
477
- );
508
+ const ActionElem = ({ connectors, options }) => {
509
+ const { t } = useTranslation();
510
+ return (
511
+ <WrapElem
512
+ connectors={connectors}
513
+ label={t("Action")}
514
+ icon="fas fa-running"
515
+ title={t("Action button")}
516
+ >
517
+ <Action
518
+ name={
519
+ options.actions[0].optgroup
520
+ ? options.actions[0].options[0]
521
+ : options.actions[0]
522
+ }
523
+ action_row_variable={""}
524
+ block={false}
525
+ minRole={100}
526
+ confirm={false}
527
+ spinner={true}
528
+ action_label={""}
529
+ isFormula={{}}
530
+ rndid={rand_ident()}
531
+ configuration={{}}
532
+ />
533
+ </WrapElem>
534
+ );
535
+ };
478
536
 
479
537
  /**
480
538
  * @param {object} props
@@ -484,38 +542,44 @@ const ActionElem = ({ connectors, options }) => (
484
542
  * @subcategory components / Toolbox
485
543
  * @namespace
486
544
  */
487
- const AggregationElem = ({ connectors, child_field_list, agg_field_opts }) => (
488
- <WrapElem
489
- connectors={connectors}
490
- text="∑"
491
- title="Aggregation"
492
- label="Aggreg8"
493
- bold
494
- fontSize="16px"
495
- disable={child_field_list.length === 0}
496
- >
497
- <Aggregation
498
- agg_relation={child_field_list[0]}
499
- agg_field={headOr(agg_field_opts[child_field_list[0]], "")?.name}
500
- stat={"Count"}
501
- textStyle={""}
502
- aggwhere={""}
503
- block={false}
504
- />
505
- </WrapElem>
506
- );
545
+ const AggregationElem = ({ connectors, child_field_list, agg_field_opts }) => {
546
+ const { t } = useTranslation();
547
+ return (
548
+ <WrapElem
549
+ connectors={connectors}
550
+ text=""
551
+ title={t("Aggregation")}
552
+ label={t("Aggreg8")}
553
+ bold
554
+ fontSize="16px"
555
+ disable={child_field_list.length === 0}
556
+ >
557
+ <Aggregation
558
+ agg_relation={child_field_list[0]}
559
+ agg_field={headOr(agg_field_opts[child_field_list[0]], "")?.name}
560
+ stat={"Count"}
561
+ textStyle={""}
562
+ aggwhere={""}
563
+ block={false}
564
+ />
565
+ </WrapElem>
566
+ );
567
+ };
507
568
 
508
- const TableElem = ({ connectors }) => (
509
- <WrapElem
510
- connectors={connectors}
511
- innerClass="mt-m1px"
512
- icon="fas fa-table"
513
- title="Table"
514
- label="Table"
515
- >
516
- <Table contents={[[], []]} rows={2} columns={2} />
517
- </WrapElem>
518
- );
569
+ const TableElem = ({ connectors }) => {
570
+ const { t } = useTranslation();
571
+ return (
572
+ <WrapElem
573
+ connectors={connectors}
574
+ innerClass="mt-m1px"
575
+ icon="fas fa-table"
576
+ title={t("Table")}
577
+ label={t("Table")}
578
+ >
579
+ <Table contents={[[], []]} rows={2} columns={2} />
580
+ </WrapElem>
581
+ );
582
+ };
519
583
 
520
584
  const chunkToolBox = (elems, expanded) => {
521
585
  const chunks = chunk(elems, expanded ? 3 : 2);