@saltcorn/builder 1.5.0-beta.12 → 1.5.0-beta.14

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.
@@ -0,0 +1,182 @@
1
+ import React, { Fragment, useState, useEffect, useRef } from "react";
2
+ import optionsCtx from "../context";
3
+
4
+ import Editor, { useMonaco } from "@monaco-editor/react";
5
+
6
+ const setMonacoLanguage = async (monaco, options, isStatements) => {
7
+ monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
8
+ noLib: true,
9
+ allowNonTsExtensions: true,
10
+ });
11
+ if (options.setMonaco) return;
12
+
13
+ options.setMonaco = true;
14
+ const tsres = await fetch(
15
+ `/admin/ts-declares?${options.tableName ? `table=${options.tableName}` : ""}&user=yes`
16
+ );
17
+ const tsds = await tsres.text();
18
+
19
+ monaco.languages.typescript.typescriptDefaults.addExtraLib(tsds);
20
+ // for code ending in return: https://github.com/microsoft/monaco-editor/issues/1661
21
+ // codes for await ignore are shown by hover card
22
+ if (isStatements)
23
+ monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
24
+ //noSemanticValidation: false,
25
+ //noSyntaxValidation: false,
26
+ diagnosticCodesToIgnore: [1108, 1378, 1375, 7044, 2580, 80005],
27
+ });
28
+ };
29
+
30
+ export const SingleLineEditor = ({
31
+ setProp,
32
+ value,
33
+ propKey,
34
+ onChange,
35
+ className,
36
+ }) => {
37
+ const options = React.useContext(optionsCtx);
38
+
39
+ const handleEditorWillMount = (monaco) => {
40
+ setMonacoLanguage(monaco, options, false);
41
+ };
42
+ return (
43
+ <div className="form-control p-0 pt-1">
44
+ <Editor
45
+ className={className || ""}
46
+ height="22px"
47
+ value={value}
48
+ onChange={(value) => {
49
+ onChange && onChange(value);
50
+ setProp && propKey && setProp((prop) => (prop[propKey] = value));
51
+ }}
52
+ defaultLanguage="typescript"
53
+ //onMount={handleEditorDidMount}
54
+ //beforeMount={handleEditorWillMount}
55
+ options={singleLineEditorOptions}
56
+ //theme="myCoolTheme"
57
+ beforeMount={handleEditorWillMount}
58
+ />
59
+ </div>
60
+ );
61
+ };
62
+
63
+ export const MultiLineCodeEditor = ({ setProp, value, onChange }) => {
64
+ const options = React.useContext(optionsCtx);
65
+
66
+ const handleEditorWillMount = (monaco) => {
67
+ setMonacoLanguage(monaco, options, true);
68
+ };
69
+ return (
70
+ <div className="form-control p-0 pt-2">
71
+ <Editor
72
+ height="150px"
73
+ value={value}
74
+ onChange={onChange}
75
+ defaultLanguage="typescript"
76
+ //onMount={handleEditorDidMount}
77
+ //beforeMount={handleEditorWillMount}
78
+ options={multiLineEditorOptions}
79
+ //theme="myCoolTheme"
80
+ beforeMount={handleEditorWillMount}
81
+ />
82
+ </div>
83
+ );
84
+ };
85
+
86
+ const multiLineEditorOptions = {
87
+ fontSize: "14px",
88
+ fontWeight: "normal",
89
+ wordWrap: "off",
90
+ lineNumbers: "off",
91
+ lineNumbersMinChars: 0,
92
+ overviewRulerLanes: 0,
93
+ overviewRulerBorder: false,
94
+ hideCursorInOverviewRuler: true,
95
+ lineDecorationsWidth: 10,
96
+ glyphMargin: false,
97
+ folding: false,
98
+ // disable `Find`
99
+ find: {
100
+ addExtraSpaceOnTop: false,
101
+ autoFindInSelection: "never",
102
+ seedSearchStringFromSelection: false,
103
+ },
104
+ minimap: { enabled: false },
105
+ // see: https://github.com/microsoft/monaco-editor/issues/1746
106
+ wordBasedSuggestions: false,
107
+ // avoid links underline
108
+ links: false,
109
+ // avoid highlight hover word
110
+ occurrencesHighlight: false,
111
+ cursorStyle: "line-thin",
112
+ // hide current row highlight grey border
113
+ // see: https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.ieditoroptions.html#renderlinehighlight
114
+ renderLineHighlight: "none",
115
+ contextmenu: false,
116
+ // default selection is rounded
117
+ roundedSelection: false,
118
+ hover: {
119
+ // unit: ms
120
+ // default: 300
121
+ delay: 100,
122
+ },
123
+ acceptSuggestionOnEnter: "on",
124
+ // auto adjust width and height to parent
125
+ // see: https://github.com/Microsoft/monaco-editor/issues/543#issuecomment-321767059
126
+ automaticLayout: true,
127
+ // if monaco is inside a table, hover tips or completion may casue table body scroll
128
+ fixedOverflowWidgets: true,
129
+ };
130
+
131
+ //https://codesandbox.io/p/sandbox/react-monaco-single-line-forked-nsmhp6?file=%2Fsrc%2FApp.js%3A28%2C31
132
+ const singleLineEditorOptions = {
133
+ fontSize: "14px",
134
+ fontWeight: "normal",
135
+ wordWrap: "off",
136
+ lineNumbers: "off",
137
+ lineNumbersMinChars: 0,
138
+ overviewRulerLanes: 0,
139
+ overviewRulerBorder: false,
140
+ hideCursorInOverviewRuler: true,
141
+ lineDecorationsWidth: 10,
142
+ glyphMargin: false,
143
+ folding: false,
144
+ scrollBeyondLastColumn: 0,
145
+ scrollbar: {
146
+ horizontal: "hidden",
147
+ vertical: "hidden",
148
+ // avoid can not scroll page when hover monaco
149
+ alwaysConsumeMouseWheel: false,
150
+ },
151
+ // disable `Find`
152
+ find: {
153
+ addExtraSpaceOnTop: false,
154
+ autoFindInSelection: "never",
155
+ seedSearchStringFromSelection: false,
156
+ },
157
+ minimap: { enabled: false },
158
+ // see: https://github.com/microsoft/monaco-editor/issues/1746
159
+ wordBasedSuggestions: false,
160
+ // avoid links underline
161
+ links: false,
162
+ // avoid highlight hover word
163
+ occurrencesHighlight: false,
164
+ cursorStyle: "line-thin",
165
+ // hide current row highlight grey border
166
+ // see: https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.ieditoroptions.html#renderlinehighlight
167
+ renderLineHighlight: "none",
168
+ contextmenu: false,
169
+ // default selection is rounded
170
+ roundedSelection: false,
171
+ hover: {
172
+ // unit: ms
173
+ // default: 300
174
+ delay: 100,
175
+ },
176
+ acceptSuggestionOnEnter: "on",
177
+ // auto adjust width and height to parent
178
+ // see: https://github.com/Microsoft/monaco-editor/issues/543#issuecomment-321767059
179
+ automaticLayout: true,
180
+ // if monaco is inside a table, hover tips or completion may casue table body scroll
181
+ fixedOverflowWidgets: true,
182
+ };
@@ -26,6 +26,7 @@ import FontIconPicker from "@fonticonpicker/react-fonticonpicker";
26
26
  import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
27
27
  import fas from "@fortawesome/free-solid-svg-icons";
28
28
  import far from "@fortawesome/free-regular-svg-icons";
29
+ import { SingleLineEditor } from "./MonacoEditor";
29
30
  const ckConfig = {
30
31
  toolbarGroups: [
31
32
  { name: "document", groups: ["mode", "document", "doctools"] },
@@ -202,13 +203,7 @@ const TextSettings = () => {
202
203
  )}
203
204
  <label>Text to display</label>
204
205
  {allowFormula && isFormula.text ? (
205
- <input
206
- type="text"
207
- className="text-to-display form-control"
208
- value={text}
209
- onChange={setAProp("text")}
210
- spellCheck={false}
211
- />
206
+ <SingleLineEditor setProp={setProp} value={text} propKey="text" />
212
207
  ) : (
213
208
  <ErrorBoundary>
214
209
  <div className="border">
@@ -31,6 +31,16 @@ import {
31
31
  Relation,
32
32
  buildTableCaches,
33
33
  } from "@saltcorn/common-code";
34
+ import { SingleLineEditor } from "./MonacoEditor";
35
+
36
+ /*
37
+ <SingleLineEditor
38
+ setProp={setProp}
39
+ value={extra_state_fml}
40
+ propKey="extra_state_fml"
41
+ />
42
+
43
+ */
34
44
 
35
45
  export /**
36
46
  * @param {object} props
@@ -28,6 +28,7 @@ import FontIconPicker from "@fonticonpicker/react-fonticonpicker";
28
28
  import Tippy from "@tippyjs/react";
29
29
  import { RelationType } from "@saltcorn/common-code";
30
30
  import Select from "react-select";
31
+ import { MultiLineCodeEditor, SingleLineEditor } from "./MonacoEditor";
31
32
 
32
33
  export const DynamicFontAwesomeIcon = ({ icon, className }) => {
33
34
  if (!icon) return null;
@@ -204,17 +205,12 @@ const OrFormula = ({ setProp, isFormula, node, nodekey, children }) => {
204
205
  <Fragment>
205
206
  <div className="input-group input-group-sm w-100">
206
207
  {isFormula[nodekey] ? (
207
- <input
208
- type="text"
209
- className="form-control text-to-display"
208
+ <SingleLineEditor
210
209
  value={node[nodekey] || ""}
211
- spellCheck={false}
212
- onChange={(e) => {
213
- if (e.target) {
214
- const target_value = e.target.value;
215
- setProp((prop) => (prop[nodekey] = target_value));
216
- }
210
+ onChange={(target_value) => {
211
+ setProp((prop) => (prop[nodekey] = target_value));
217
212
  }}
213
+ className="text-to-display"
218
214
  />
219
215
  ) : (
220
216
  children
@@ -487,8 +483,12 @@ export /**
487
483
  * @subcategory components / elements / utils
488
484
  * @namespace
489
485
  */
490
- const Accordion = ({ titles, children }) => {
491
- const [currentTab, setCurrentTab] = useState(0);
486
+ const Accordion = ({ titles, children, value, onChange }) => {
487
+ const [currentTab, setCurrentTab] = useState(value || 0);
488
+ const setTab = (ix) => {
489
+ setCurrentTab(ix);
490
+ onChange && onChange(ix);
491
+ };
492
492
  return (
493
493
  <Fragment>
494
494
  {children.map((child, ix) => {
@@ -499,7 +499,7 @@ const Accordion = ({ titles, children }) => {
499
499
  className={`bg-${
500
500
  isCurrent ? "primary" : "secondary"
501
501
  } ps-1 text-white w-100 mt-1`}
502
- onClick={() => setCurrentTab(ix)}
502
+ onClick={() => setTab(ix)}
503
503
  >
504
504
  <span className="w-1em">
505
505
  {isCurrent ? (
@@ -1067,17 +1067,25 @@ const ConfigField = ({
1067
1067
  onChange={(e) => e.target && myOnChange(e.target.value)}
1068
1068
  />
1069
1069
  ),
1070
- code: () => (
1071
- <textarea
1072
- rows="6"
1073
- type="text"
1074
- className={`field-${field?.name} form-control`}
1075
- value={value}
1076
- name={field?.name}
1077
- onChange={(e) => e.target && myOnChange(e.target.value)}
1078
- spellCheck={false}
1079
- />
1080
- ),
1070
+ code: () =>
1071
+ field?.attributes?.expression_type === "row" ||
1072
+ field?.attributes?.expression_type === "query" ? (
1073
+ <textarea
1074
+ rows="6"
1075
+ type="text"
1076
+ className={`field-${field?.name} form-control`}
1077
+ value={value}
1078
+ name={field?.name}
1079
+ onChange={(e) => e.target && myOnChange(e.target.value)}
1080
+ spellCheck={false}
1081
+ />
1082
+ ) : (
1083
+ <MultiLineCodeEditor
1084
+ setProp={setProp}
1085
+ value={value}
1086
+ onChange={myOnChange}
1087
+ />
1088
+ ),
1081
1089
  select: () => {
1082
1090
  if (field.class?.includes?.("selectizable")) {
1083
1091
  const seloptions = field.options.map((o, ix) =>