@saltcorn/builder 0.6.4 → 0.7.0-beta.2

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.6.4",
3
+ "version": "0.7.0-beta.2",
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",
@@ -26,6 +26,7 @@ import { Image } from "./elements/Image";
26
26
  import { Tabs } from "./elements/Tabs";
27
27
  import { Empty } from "./elements/Empty";
28
28
  import { DropDownFilter } from "./elements/DropDownFilter";
29
+ import { DropMenu } from "./elements/DropMenu";
29
30
  import { ToggleFilter } from "./elements/ToggleFilter";
30
31
  import optionsCtx from "./context";
31
32
  import PreviewCtx from "./preview_context";
@@ -211,7 +212,7 @@ const SettingsPanel = () => {
211
212
  <Fragment>
212
213
  {selected.isDeletable && (
213
214
  <button className="btn btn-sm btn-danger" onClick={deleteThis}>
214
- <FontAwesomeIcon icon={faTrashAlt} className="mr-1" />
215
+ <FontAwesomeIcon icon={faTrashAlt} className="me-1" />
215
216
  Delete
216
217
  </button>
217
218
  )}
@@ -220,16 +221,16 @@ const SettingsPanel = () => {
220
221
  className="btn btn-sm btn-danger"
221
222
  onClick={deleteChildren}
222
223
  >
223
- <FontAwesomeIcon icon={faTrashAlt} className="mr-1" />
224
+ <FontAwesomeIcon icon={faTrashAlt} className="me-1" />
224
225
  Delete contents
225
226
  </button>
226
227
  ) : (
227
228
  <button
228
229
  title="Duplicate element with its children"
229
- className="btn btn-sm btn-secondary ml-2"
230
+ className="btn btn-sm btn-secondary ms-2"
230
231
  onClick={duplicate}
231
232
  >
232
- <FontAwesomeIcon icon={faCopy} className="mr-1" />
233
+ <FontAwesomeIcon icon={faCopy} className="me-1" />
233
234
  Clone
234
235
  </button>
235
236
  )}
@@ -271,7 +272,7 @@ const SaveButton = () => {
271
272
  };
272
273
  return options.page_id || options.view_id ? (
273
274
  <button
274
- className="btn btn-sm btn-outline-secondary mr-2 builder-save-ajax"
275
+ className="btn btn-sm btn-outline-secondary me-2 builder-save-ajax"
275
276
  onClick={onClick}
276
277
  >
277
278
  Save
@@ -315,7 +316,7 @@ const HistoryPanel = () => {
315
316
  <Fragment>
316
317
  {canUndo && (
317
318
  <button
318
- className="btn btn-sm btn-secondary ml-2 mr-2"
319
+ className="btn btn-sm btn-secondary ms-2 me-2"
319
320
  title="Undo"
320
321
  onClick={() => actions.history.undo()}
321
322
  >
@@ -412,7 +413,7 @@ const Builder = ({ options, layout, mode }) => {
412
413
  </div>
413
414
  </Accordion>
414
415
  </div>
415
- <div className="card toolbox-card pr-0">
416
+ <div className="card toolbox-card pe-0">
416
417
  <div className="card-header">Layers</div>
417
418
  {showLayers && (
418
419
  <div className="card-body p-0 builder-layers">
@@ -446,6 +447,7 @@ const Builder = ({ options, layout, mode }) => {
446
447
  Container,
447
448
  Column,
448
449
  DropDownFilter,
450
+ DropMenu,
449
451
  Tabs,
450
452
  ToggleFilter,
451
453
  }}
@@ -168,7 +168,7 @@ const Library = () => {
168
168
  disabled={!selected}
169
169
  onClick={() => setAdding(!adding)}
170
170
  >
171
- <FontAwesomeIcon icon={faPlus} className="mr-1" />
171
+ <FontAwesomeIcon icon={faPlus} className="me-1" />
172
172
  Add
173
173
  </button>
174
174
  <div
@@ -192,11 +192,11 @@ const Library = () => {
192
192
  isMulti={false}
193
193
  />
194
194
  <button className={`btn btn-primary mt-3`} onClick={addSelected}>
195
- <FontAwesomeIcon icon={faPlus} className="mr-1" />
195
+ <FontAwesomeIcon icon={faPlus} className="me-1" />
196
196
  Add
197
197
  </button>
198
198
  <button
199
- className={`btn btn-outline-secondary ml-2 mt-3`}
199
+ className={`btn btn-outline-secondary ms-2 mt-3`}
200
200
  onClick={() => setAdding(false)}
201
201
  >
202
202
  <FontAwesomeIcon icon={faTimes} />
@@ -127,19 +127,19 @@ const RenderNode = ({ render }) => {
127
127
  zIndex: 9999,
128
128
  }}
129
129
  >
130
- <div className="dispname mr-3">{name}</div>{" "}
130
+ <div className="dispname me-3">{name}</div>{" "}
131
131
  {moveable && isActive && (
132
132
  <button
133
133
  className="btn btn-link btn-builder-move p-0"
134
134
  ref={drag}
135
135
  >
136
- <FontAwesomeIcon icon={faArrowsAlt} className="mr-2" />
136
+ <FontAwesomeIcon icon={faArrowsAlt} className="me-2" />
137
137
  </button>
138
138
  )}
139
139
  {isActive && parent && parent !== "ROOT" ? (
140
140
  <FontAwesomeIcon
141
141
  icon={faArrowUp}
142
- className="mr-2"
142
+ className="me-2"
143
143
  onClick={() => {
144
144
  actions.selectNode(parent);
145
145
  }}
@@ -151,12 +151,12 @@ const RenderNode = ({ render }) => {
151
151
  key={1}
152
152
  icon={faCopy}
153
153
  onClick={duplicate}
154
- className="mr-2"
154
+ className="me-2"
155
155
  />,
156
156
  <FontAwesomeIcon
157
157
  key={2}
158
158
  icon={faTrashAlt}
159
- className="mr-2"
159
+ className="me-2"
160
160
  onMouseDown={(e) => {
161
161
  e.stopPropagation();
162
162
  actions.delete(id);
@@ -175,13 +175,13 @@ const RenderNode = ({ render }) => {
175
175
  };
176
176
  /*
177
177
  {moveable ? (
178
- <Btn className="mr-2 cursor-move" ref={drag}>
178
+ <Btn className="me-2 cursor-move" ref={drag}>
179
179
  <Move />
180
180
  </Btn>
181
181
  ) : null}
182
182
  {id !== ROOT_NODE && (
183
183
  <Btn
184
- className="mr-2 cursor-pointer"
184
+ className="me-2 cursor-pointer"
185
185
  onClick={() => {
186
186
  actions.selectNode(parent);
187
187
  }}
@@ -16,6 +16,7 @@ import { ViewLink } from "./elements/ViewLink";
16
16
  import { Columns } from "./elements/Columns";
17
17
  import { Action } from "./elements/Action";
18
18
  import { DropDownFilter } from "./elements/DropDownFilter";
19
+ import { DropMenu } from "./elements/DropMenu";
19
20
  import { ToggleFilter } from "./elements/ToggleFilter";
20
21
  import { Empty } from "./elements/Empty";
21
22
  import { Card } from "./elements/Card";
@@ -336,7 +337,7 @@ const DropDownFilterElem = ({ connectors, fields }) => (
336
337
  connectors={connectors}
337
338
  icon="far fa-caret-square-down"
338
339
  title="Dropdown filter"
339
- label="Dropdown"
340
+ label="Select"
340
341
  >
341
342
  <DropDownFilter
342
343
  name={fields[0].name}
@@ -346,6 +347,18 @@ const DropDownFilterElem = ({ connectors, fields }) => (
346
347
  />
347
348
  </WrapElem>
348
349
  );
350
+
351
+ const DropMenuElem = ({ connectors }) => (
352
+ <WrapElem
353
+ connectors={connectors}
354
+ icon="far fa-caret-square-down"
355
+ title="Dropdown menu"
356
+ label="DropMenu"
357
+ >
358
+ <DropMenu />
359
+ </WrapElem>
360
+ );
361
+
349
362
  /**
350
363
  * @param {object} props
351
364
  * @param {object} props.connectors
@@ -456,7 +469,7 @@ const AggregationElem = ({ connectors, child_field_list, agg_field_opts }) => (
456
469
  connectors={connectors}
457
470
  text="∑"
458
471
  title="Aggregation"
459
- label="Calc"
472
+ label="Aggreg8"
460
473
  bold
461
474
  fontSize="16px"
462
475
  disable={child_field_list.length === 0}
@@ -529,6 +542,7 @@ const ToolboxShow = () => {
529
542
  </div>
530
543
  <div className="toolbar-row">
531
544
  <HTMLElem connectors={connectors} />
545
+ <DropMenuElem connectors={connectors} />
532
546
  </div>
533
547
  </Fragment>
534
548
  );
@@ -19,8 +19,8 @@ import {
19
19
  } from "./utils";
20
20
 
21
21
  export /**
22
- *
23
- * @param {object} props
22
+ *
23
+ * @param {object} props
24
24
  * @param {string} props.name
25
25
  * @param {string} props.block
26
26
  * @param {string} props.action_label
@@ -35,8 +35,7 @@ export /**
35
35
  * @subcategory components
36
36
  * @namespace
37
37
  */
38
- const Action =
39
- ({
38
+ const Action = ({
40
39
  name,
41
40
  block,
42
41
  action_label,
@@ -51,14 +50,14 @@ const Action =
51
50
  selected,
52
51
  connectors: { connect, drag },
53
52
  } = useNode((node) => ({ selected: node.events.selected }));
54
-
55
53
  /**
56
54
  * @type {object}
57
55
  */
58
- const btn = (
56
+ return (
59
57
  <button
60
- className={`btn ${action_style || "btn-primary"} ${action_size || ""}`}
61
- {...blockProps(block)}
58
+ className={`btn ${action_style || "btn-primary"} ${action_size || ""} ${
59
+ selected ? "selected-node" : ""
60
+ } ${block ? "d-block" : ""}`}
62
61
  ref={(dom) => connect(drag(dom))}
63
62
  style={
64
63
  action_style === "btn-custom-color"
@@ -70,20 +69,19 @@ const Action =
70
69
  : {}
71
70
  }
72
71
  >
73
- <DynamicFontAwesomeIcon icon={action_icon} className="mr-1" />
72
+ <DynamicFontAwesomeIcon icon={action_icon} className="me-1" />
74
73
  {action_label || name}
75
74
  </button>
76
75
  );
77
- return selected ? <span className={"selected-node"}>{btn}</span> : btn;
78
76
  };
79
77
 
80
- export /**
78
+ export /**
81
79
  * @category saltcorn-builder
82
80
  * @subcategory components
83
81
  * @namespace
84
82
  * @returns {div}
85
83
  */
86
- const ActionSettings = () => {
84
+ const ActionSettings = () => {
87
85
  const node = useNode((node) => ({
88
86
  name: node.data.props.name,
89
87
  block: node.data.props.block,
@@ -123,7 +121,7 @@ export /**
123
121
  <td>
124
122
  <select
125
123
  value={name}
126
- className="form-control"
124
+ className="form-control form-select"
127
125
  onChange={(e) => {
128
126
  setProp((prop) => (prop.name = e.target.value));
129
127
  setInitialConfig(
@@ -195,8 +193,8 @@ export /**
195
193
  );
196
194
  };
197
195
 
198
- /**
199
- * @type {object}
196
+ /**
197
+ * @type {object}
200
198
  */
201
199
  Action.craft = {
202
200
  displayName: "Action",
@@ -10,7 +10,7 @@ import optionsCtx from "../context";
10
10
  import { blockProps, BlockSetting, TextStyleRow } from "./utils";
11
11
 
12
12
  export /**
13
- * @param {object} props
13
+ * @param {object} props
14
14
  * @param {string} props.agg_relation
15
15
  * @param {string} props.agg_field
16
16
  * @param {string} props.stat
@@ -21,13 +21,7 @@ export /**
21
21
  * @subcategory components
22
22
  * @namespace
23
23
  */
24
- const Aggregation = ({
25
- agg_relation,
26
- agg_field,
27
- stat,
28
- block,
29
- textStyle,
30
- }) => {
24
+ const Aggregation = ({ agg_relation, agg_field, stat, block, textStyle }) => {
31
25
  const {
32
26
  selected,
33
27
  connectors: { connect, drag },
@@ -76,7 +70,7 @@ const AggregationSettings = () => {
76
70
  </td>
77
71
  <td>
78
72
  <select
79
- className="form-control"
73
+ className="form-control form-select"
80
74
  value={agg_relation}
81
75
  onChange={(e) =>
82
76
  setProp((prop) => {
@@ -100,7 +94,7 @@ const AggregationSettings = () => {
100
94
  </td>
101
95
  <td>
102
96
  <select
103
- className="form-control"
97
+ className="form-control form-select"
104
98
  value={agg_field}
105
99
  onChange={(e) =>
106
100
  setProp((prop) => (prop.agg_field = e.target.value))
@@ -121,7 +115,7 @@ const AggregationSettings = () => {
121
115
  <td>
122
116
  <select
123
117
  value={stat}
124
- className="form-control"
118
+ className="form-control form-select"
125
119
  onChange={(e) => setProp((prop) => (prop.stat = e.target.value))}
126
120
  >
127
121
  <option value={"Count"}>Count</option>
@@ -129,6 +123,7 @@ const AggregationSettings = () => {
129
123
  <option value={"Sum"}>Sum</option>
130
124
  <option value={"Max"}>Max</option>
131
125
  <option value={"Min"}>Min</option>
126
+ <option value={"Array_Agg"}>Array_Agg</option>
132
127
  {options.fields
133
128
  .filter((f) => f.type.name === "Date")
134
129
  .map((f) => (
@@ -163,8 +158,8 @@ const AggregationSettings = () => {
163
158
  );
164
159
  };
165
160
 
166
- /**
167
- * @type {object}
161
+ /**
162
+ * @type {object}
168
163
  */
169
164
  Aggregation.craft = {
170
165
  displayName: "Aggregation",
@@ -42,7 +42,7 @@ const Card = ({ children, isFormula, title, shadow, noPadding, style }) => {
42
42
  {title && title.length > 0 && (
43
43
  <div className="card-header">
44
44
  {isFormula.title ? (
45
- <span className="text-monospace">={title}</span>
45
+ <span className="font-monospace">={title}</span>
46
46
  ) : (
47
47
  title
48
48
  )}
@@ -159,7 +159,7 @@ const ColumnsSettings = () => {
159
159
  <td>/12</td>
160
160
  <td>
161
161
  <select
162
- className="form-control"
162
+ className="form-control form-select"
163
163
  value={breakpoints[ix]}
164
164
  onChange={(e) =>
165
165
  setProp((prop) => (prop.breakpoints[ix] = e.target.value))
@@ -395,7 +395,6 @@ const ContainerSettings = () => {
395
395
  { value: "left", title: "Left", label: <AlignStart /> },
396
396
  { value: "center", title: "Center", label: <AlignCenter /> },
397
397
  { value: "right", title: "Right", label: <AlignEnd /> },
398
- { value: "justify", title: "Justify", label: <Justify /> },
399
398
  ],
400
399
  }}
401
400
  node={node}
@@ -488,7 +487,7 @@ const ContainerSettings = () => {
488
487
  <td>
489
488
  <select
490
489
  value={bgFileId}
491
- className="form-control-sm w-100"
490
+ className="form-control-sm w-100 form-select"
492
491
  onChange={setAProp("bgFileId")}
493
492
  >
494
493
  {options.images.map((f, ix) => (
@@ -512,7 +511,7 @@ const ContainerSettings = () => {
512
511
  <td>
513
512
  <select
514
513
  value={imageSize}
515
- className="form-control-sm"
514
+ className="form-control-sm form-select"
516
515
  onChange={setAProp("imageSize")}
517
516
  >
518
517
  <option>contain</option>
@@ -543,7 +542,7 @@ const ContainerSettings = () => {
543
542
  field={{
544
543
  name: "font-family",
545
544
  label: "Font family",
546
- type: "String",
545
+ type: "Font",
547
546
  }}
548
547
  node={node}
549
548
  setProp={setProp}
@@ -742,7 +741,7 @@ const ContainerSettings = () => {
742
741
  onChange={setAProp("showIfFormula")}
743
742
  />
744
743
  <div style={{ marginTop: "-5px" }}>
745
- <small className="text-muted text-monospace">FORMULA</small>
744
+ <small className="text-muted font-monospace">FORMULA</small>
746
745
  </div>
747
746
  </td>
748
747
  </tr>
@@ -803,7 +802,7 @@ const ContainerSettings = () => {
803
802
  <td>
804
803
  <select
805
804
  value={minScreenWidth}
806
- className="form-control"
805
+ className="form-control form-select"
807
806
  onChange={setAProp("minScreenWidth")}
808
807
  >
809
808
  <option value="">all</option>
@@ -821,7 +820,7 @@ const ContainerSettings = () => {
821
820
  <td>
822
821
  <select
823
822
  value={maxScreenWidth}
824
- className="form-control"
823
+ className="form-control form-select"
825
824
  onChange={setAProp("maxScreenWidth")}
826
825
  >
827
826
  <option value="">all</option>
@@ -847,7 +846,7 @@ const ContainerSettings = () => {
847
846
  <label>Hover color</label>
848
847
  <select
849
848
  value={hoverColor}
850
- className="form-control"
849
+ className="form-control form-select"
851
850
  onChange={setAProp("hoverColor")}
852
851
  >
853
852
  <option value="">None</option>
@@ -69,7 +69,7 @@ const DropDownFilterSettings = () => {
69
69
  <td>
70
70
  <select
71
71
  value={name}
72
- className="form-control"
72
+ className="form-control form-select"
73
73
  onChange={(e) => setProp((prop) => (prop.name = e.target.value))}
74
74
  >
75
75
  {options.fields.map((f, ix) => (
@@ -0,0 +1,156 @@
1
+ /**
2
+ * @category saltcorn-builder
3
+ * @module components/elements/DropMenu
4
+ * @subcategory components / elements
5
+ */
6
+
7
+ import React, { Fragment, useState } from "react";
8
+ import { Element, useNode } from "@craftjs/core";
9
+ import { Column } from "./Column";
10
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
11
+ import { faCaretDown } from "@fortawesome/free-solid-svg-icons";
12
+ import {
13
+ SettingsRow,
14
+ BlockSetting,
15
+ ButtonOrLinkSettingsRows,
16
+ DynamicFontAwesomeIcon,
17
+ } from "./utils";
18
+
19
+ export /**
20
+ * @param {object} props
21
+ * @param {boolean} props.has_dropdown
22
+ * @param {string} props.children
23
+ * @param {boolean} props.show_badges
24
+ * @returns {div}
25
+ * @namespace
26
+ * @category saltcorn-builder
27
+ * @subcategory components
28
+ */
29
+ const DropMenu = ({
30
+ children,
31
+ action_style,
32
+ action_size,
33
+ action_icon,
34
+ action_bgcol,
35
+ action_bordercol,
36
+ action_textcol,
37
+ block,
38
+ label,
39
+ }) => {
40
+ const {
41
+ selected,
42
+ connectors: { connect, drag },
43
+ } = useNode((node) => ({ selected: node.events.selected }));
44
+ const [showDropdown, setDropdown] = useState(false);
45
+ //const [dropWidth, setDropWidth] = useState(200);
46
+ return (
47
+ <div
48
+ className={`${selected ? "selected-node" : ""} ${block ? "d-block" : ""}`}
49
+ ref={(dom) => connect(drag(dom))}
50
+ >
51
+ <button
52
+ className={`btn ${action_style || "btn-primary"} ${action_size || ""} `}
53
+ style={
54
+ action_style === "btn-custom-color"
55
+ ? {
56
+ backgroundColor: action_bgcol || "#000000",
57
+ borderColor: action_bordercol || "#000000",
58
+ color: action_textcol || "#000000",
59
+ }
60
+ : {}
61
+ }
62
+ >
63
+ <DynamicFontAwesomeIcon icon={action_icon} className="me-1" />
64
+
65
+ {label}
66
+ <FontAwesomeIcon
67
+ icon={faCaretDown}
68
+ className="ms-1"
69
+ onClick={() => setDropdown(!showDropdown)}
70
+ />
71
+ </button>
72
+ <div
73
+ className={`dropdown-menu dropmenu-dropdown ${
74
+ showDropdown ? "show" : ""
75
+ }`}
76
+ >
77
+ <div className="canvas d-flex flex-column">{children}</div>
78
+ </div>
79
+ </div>
80
+ );
81
+ };
82
+
83
+ export /**
84
+ * @returns {div}
85
+ * @namespace
86
+ * @category saltcorn-builder
87
+ * @subcategory components
88
+ */
89
+ const DropMenuSettings = () => {
90
+ const node = useNode((node) => ({
91
+ label: node.data.props.label,
92
+ block: node.data.props.block,
93
+ action_style: node.data.props.action_style,
94
+ action_size: node.data.props.action_size,
95
+ action_icon: node.data.props.action_icon,
96
+ action_bgcol: node.data.props.action_bgcol,
97
+ action_bordercol: node.data.props.action_bordercol,
98
+ action_textcol: node.data.props.action_textcol,
99
+ }));
100
+ const {
101
+ actions: { setProp },
102
+ label,
103
+ block,
104
+ } = node;
105
+ return (
106
+ <table className="w-100">
107
+ <tbody>
108
+ <SettingsRow
109
+ field={{
110
+ label: "Label",
111
+ name: "label",
112
+ type: "String",
113
+ }}
114
+ node={node}
115
+ setProp={setProp}
116
+ />
117
+ <ButtonOrLinkSettingsRows
118
+ setProp={setProp}
119
+ keyPrefix="action_"
120
+ values={node}
121
+ />
122
+ <tr>
123
+ <td colSpan="2">
124
+ <BlockSetting block={block} setProp={setProp} />
125
+ </td>
126
+ </tr>
127
+ </tbody>
128
+ </table>
129
+ );
130
+ };
131
+
132
+ /**
133
+ * @type {object}
134
+ */
135
+ DropMenu.craft = {
136
+ displayName: "DropMenu",
137
+ props: {
138
+ label: "",
139
+ show_badges: false,
140
+ },
141
+ related: {
142
+ settings: DropMenuSettings,
143
+ segment_type: "dropdown_menu",
144
+ hasContents: true,
145
+ fields: [
146
+ "label",
147
+ "block",
148
+ "action_style",
149
+ "action_size",
150
+ "action_icon",
151
+ "action_bgcol",
152
+ "action_bordercol",
153
+ "action_textcol",
154
+ ],
155
+ },
156
+ };
@@ -134,7 +134,7 @@ const FieldSettings = () => {
134
134
  <td>
135
135
  <select
136
136
  value={name}
137
- className="form-control"
137
+ className="form-control form-select"
138
138
  onChange={(e) => {
139
139
  setProp((prop) => (prop.name = e.target.value));
140
140
  const newfvs = options.field_view_options[e.target.value];
@@ -164,7 +164,7 @@ const FieldSettings = () => {
164
164
  <td>
165
165
  <select
166
166
  value={fieldview}
167
- className="form-control"
167
+ className="form-control form-select"
168
168
  onChange={(e) => {
169
169
  setProp((prop) => (prop.fieldview = e.target.value));
170
170
  setInitialConfig(
@@ -142,7 +142,7 @@ const ImageSettings = () => {
142
142
  <td>
143
143
  <select
144
144
  value={srctype}
145
- className="form-control"
145
+ className="form-control form-select"
146
146
  onChange={setAProp("srctype")}
147
147
  >
148
148
  <option>File</option>
@@ -160,7 +160,7 @@ const ImageSettings = () => {
160
160
  <td>
161
161
  <select
162
162
  value={fileid}
163
- className="form-control"
163
+ className="form-control form-select"
164
164
  onChange={setAProp("fileid")}
165
165
  >
166
166
  {options.images.map((f, ix) => (
@@ -217,7 +217,7 @@ const ImageSettings = () => {
217
217
  <td>
218
218
  <select
219
219
  value={field}
220
- className="form-control"
220
+ className="form-control form-select"
221
221
  onChange={setAProp("field")}
222
222
  >
223
223
  {options.fields
@@ -120,7 +120,7 @@ const JoinFieldSettings = () => {
120
120
  <td>
121
121
  <select
122
122
  value={name}
123
- className="form-control"
123
+ className="form-control form-select"
124
124
  onChange={(e) => {
125
125
  setProp((prop) => (prop.name = e.target.value));
126
126
  const newfvs = options.field_view_options[e.target.value];
@@ -150,7 +150,7 @@ const JoinFieldSettings = () => {
150
150
  <td>
151
151
  <select
152
152
  value={fieldview}
153
- className="form-control"
153
+ className="form-control form-select"
154
154
  onChange={(e) => {
155
155
  setProp((prop) => (prop.fieldview = e.target.value));
156
156
  refetchPreview({ fieldview: e.target.value });