Skip to content

Commit 6f64c77

Browse files
author
lizhi.lzp
committed
chore: simple-bind-var
1 parent 91e7e32 commit 6f64c77

File tree

5 files changed

+375
-17
lines changed

5 files changed

+375
-17
lines changed

src/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import VariableSetter from './setter/variable-setter';
2626
import TitleSetter from './setter/title-setter';
2727
import EventBindDialog from './plugin/plugin-event-bind-dialog';
2828
import VariableBindDialog from './plugin/plugin-variable-bind-dialog';
29+
import SimpleVariableBindPopup from './plugin/plugin-simple-bind-popup'
2930
import './index.less';
3031
import packagesInfo from '../package.json';
3132
// suggest: 做成 StringSetter 的一个参数,
@@ -227,6 +228,7 @@ const engineExt = {
227228
pluginMap: {
228229
EventBindDialog,
229230
VariableBindDialog,
231+
SimpleVariableBindPopup,
230232
},
231233
};
232234
engineExt.version = packagesInfo.version;
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
.simple-dialog-body {
2+
background-color: white;
3+
padding: 12px;
4+
box-shadow: 0 2px 5px rgba(0,0,0,.05);
5+
border-radius: 4px;
6+
7+
.dialog-small-title {
8+
font-weight: 700;
9+
margin-bottom: 8px;
10+
color: var(--color-title, rgb(0, 0, 0));
11+
display: flex;
12+
justify-content: space-between;
13+
.error-message{
14+
color:var(--color-function-error, rgba(255,97,96));
15+
font-weight: 400;
16+
}
17+
}
18+
19+
.dialog-right-container {
20+
width: 400px;
21+
position: relative;
22+
23+
.event-input-container {
24+
margin-bottom: 20px;
25+
}
26+
textarea {
27+
height: 100%;
28+
}
29+
30+
.editor-type-tag {
31+
width: 18px;
32+
height: 18px;
33+
background-color: var(--color-layer-mask-background, rgba(17, 105, 247, 0.18));
34+
border-radius: 2px;
35+
display: flex;
36+
justify-content: center;
37+
align-items: center;
38+
position: absolute;
39+
top: 35px;
40+
z-index: 100;
41+
left: 6px;
42+
}
43+
44+
.editor-context{
45+
border: 1px solid var(--color-field-border, rgba(31, 56, 88, 0.3));
46+
padding: 5px 5px 0px 15px;
47+
border-top-right-radius: 3px;
48+
border-top-left-radius: 3px;
49+
}
50+
51+
.editor-context-error{
52+
border-color:var(--color-function-error, rgba(255,97,96,0.7));
53+
}
54+
}
55+
}
56+
57+
.simple-bind-dialog-bottom {
58+
margin-top: 12px;
59+
.bottom-left-container {
60+
float: left;
61+
}
62+
.bottom-right-container {
63+
float: right;
64+
}
65+
}
66+
67+
.vs-variable-minimize {
68+
width: 120px;
69+
display: flex;
70+
justify-content: space-between;
71+
align-items: center;
72+
position: absolute;
73+
bottom: 10px;
74+
right: 286px;
75+
z-index: 100;
76+
background: var(--color-block-background-normal, #fff);
77+
padding: 8px 12px;
78+
border-radius: 3px;
79+
border: 1px solid var(--color-field-border, #ddd);
80+
box-shadow: 0 0 8px #aaa;
81+
font-size: 14px;
82+
font-weight: 700;
83+
cursor: pointer;
84+
img {
85+
width: 12px;
86+
}
87+
}
88+
89+
.lc-code-control:hover {
90+
border-color: transparent;
91+
}
92+
93+
.lc-code-control.ve-focused {
94+
border-color: transparent;
95+
}
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
import React, { Component } from 'react';
2+
import { Button, Overlay } from '@alifd/next';
3+
import { PluginProps } from '@alilc/lowcode-types';
4+
import { event } from '@alilc/lowcode-engine';
5+
import MonacoEditor from '@alilc/lowcode-plugin-base-monaco-editor';
6+
import './index.less';
7+
8+
9+
const defaultEditorProps = {
10+
width: '100%',
11+
height: '200px',
12+
};
13+
14+
const defaultEditorOption = {
15+
options:{
16+
readOnly: false,
17+
automaticLayout: true,
18+
folding: false, // 默认开启折叠代码功能
19+
lineNumbers: 'off',
20+
wordWrap: 'on',
21+
formatOnPaste: true,
22+
fontSize: 12,
23+
tabSize: 2,
24+
scrollBeyondLastLine: false,
25+
fixedOverflowWidgets: false,
26+
snippetSuggestions: 'top',
27+
minimap: {
28+
enabled: false,
29+
},
30+
scrollbar: {
31+
vertical: 'auto',
32+
horizontal: 'auto',
33+
verticalScrollbarSize:0
34+
},
35+
}
36+
};
37+
38+
export default class SimpleVariableBindPopup extends Component<PluginProps> {
39+
state = {
40+
visiable: false,
41+
isOverFlowMaxSize:false,
42+
jsCode: '',
43+
field: {}, // 编辑器全局变量
44+
treeList: [],
45+
minimize: false, // 是否最小化
46+
autoExpandParent: true,
47+
maxTextSize:0, // 绑定变量最大字符数
48+
node: null as any as HTMLElement, // 触发的节点
49+
};
50+
51+
private editorJsRef = React.createRef();
52+
53+
componentDidMount() {
54+
event.on('common:variableBindDialog.openDialog', ({ field, node }) => {
55+
this.setState({ field, node }, () => {
56+
this.initCode();
57+
this.openDialog();
58+
});
59+
});
60+
}
61+
62+
initCode = () => {
63+
const { field } = this.state;
64+
const fieldValue = field.getValue();
65+
const jsCode = fieldValue?.value;
66+
67+
const {maxTextSize} = this.props.config?.props || {}
68+
69+
this.setState({
70+
jsCode,
71+
// fullScreenStatus: false,
72+
minimize: false, // 是否最小化
73+
isOverFlowMaxSize:false,
74+
// 配置的最大文本长度,默认为0,不控制
75+
maxTextSize:maxTextSize?maxTextSize:0
76+
});
77+
};
78+
79+
openDialog = () => {
80+
this.setState({ visiable: true });
81+
};
82+
83+
closeDialog = () => {
84+
this.setState({
85+
visiable: false,
86+
minimize: false,
87+
});
88+
};
89+
90+
updateCode = (newCode) => {
91+
let isOverFlowMaxSize = false;
92+
if (this.state.maxTextSize){
93+
isOverFlowMaxSize = newCode?.length>this.state.maxTextSize
94+
}
95+
96+
this.setState(
97+
{
98+
jsCode: newCode,
99+
isOverFlowMaxSize
100+
},
101+
this.autoSave,
102+
);
103+
console.log('size====',newCode?.length);
104+
};
105+
106+
autoSave = () => {
107+
const { autoSave } = this.props;
108+
if (autoSave) {
109+
this.onOk(true);
110+
}
111+
};
112+
113+
editorDidMount = () => {
114+
setTimeout(() => {
115+
this.editorNode = this.editorJsRef.current; // 记录当前dom节点;
116+
}, 0);
117+
};
118+
119+
onOk = (autoSave) => {
120+
const { field, jsCode } = this.state;
121+
if(jsCode === undefined || jsCode?.length == 0) {
122+
return this.removeTheBinding()
123+
}
124+
125+
const fieldValue = field.getValue();
126+
field.setValue({
127+
type: 'JSExpression',
128+
value: jsCode,
129+
mock:
130+
Object.prototype.toString.call(fieldValue) === '[object Object]'
131+
? fieldValue.mock
132+
: fieldValue,
133+
});
134+
if (autoSave !== true) {
135+
this.closeDialog();
136+
}
137+
};
138+
139+
removeTheBinding = () => {
140+
const { field } = this.state;
141+
const fieldValue = field.getValue();
142+
const value =
143+
Object.prototype.toString.call(fieldValue) === '[object Object]'
144+
? fieldValue.mock
145+
: fieldValue;
146+
console.debug('value', value, 'fieldValue', fieldValue, field)
147+
field.setValue(value);
148+
this.closeDialog();
149+
};
150+
151+
renderBottom = () => {
152+
const { jsCode } = this.state;
153+
return (
154+
<div className="simple-bind-dialog-bottom">
155+
<div className="bottom-left-container">
156+
{jsCode && jsCode.length > 0 && (
157+
<Button type="normal" warning onClick={this.removeTheBinding}>
158+
移除绑定
159+
</Button>
160+
)}
161+
</div>
162+
163+
<div className="bottom-right-container">
164+
<Button type="primary" onClick={this.onOk} disabled={this.isBtnDisable()}>
165+
确定
166+
</Button>
167+
&nbsp;&nbsp;
168+
<Button type="normal" onClick={this.closeDialog}>
169+
取消
170+
</Button>
171+
</div>
172+
</div>
173+
);
174+
};
175+
176+
minimizeClick = (state) => {
177+
this.setState({
178+
minimize: state,
179+
visiable: !state,
180+
});
181+
};
182+
183+
renderErrorMessage = () => {
184+
const {isOverFlowMaxSize,maxTextSize} = this.state;
185+
return (
186+
isOverFlowMaxSize ? <span className='error-message'>表达式文本不能超过{maxTextSize}个字符,请换成函数调用</span> :null
187+
)
188+
}
189+
190+
isBtnDisable = () => {
191+
const { isOverFlowMaxSize } = this.state;
192+
return isOverFlowMaxSize;
193+
}
194+
195+
196+
render() {
197+
const {
198+
visiable,
199+
jsCode,
200+
minimize,
201+
isOverFlowMaxSize,
202+
} = this.state;
203+
204+
return (
205+
<div>
206+
{minimize ? (
207+
<div className="vs-variable-minimize">
208+
<img
209+
onClick={() => this.minimizeClick(false)}
210+
src="https://img.alicdn.com/imgextra/i2/O1CN01HzeCND1vl948xPEWm_!!6000000006212-55-tps-200-200.svg"
211+
/>
212+
<span onClick={() => this.minimizeClick(false)} className="vs-variable-minimize-title">
213+
变量绑定
214+
</span>
215+
<img
216+
onClick={this.closeDialog}
217+
src="https://img.alicdn.com/imgextra/i2/O1CN017cO64O1DzwlxwDSKW_!!6000000000288-55-tps-200-200.svg"
218+
/>
219+
</div>
220+
) : (
221+
''
222+
)}
223+
{this.state.node &&
224+
<Overlay
225+
v2
226+
key={this.state.field?.id}
227+
visible={!minimize && visiable}
228+
onRequestClose={this.closeDialog}
229+
safeNode={[document.querySelector('.lc-left-area'), document.querySelector('.lc-left-fixed-pane')]}
230+
target={() => this.state.node}
231+
offset={[-380, 10]}
232+
>
233+
<div className="simple-dialog-body">
234+
<div className="dialog-right-container">
235+
<div className="dialog-small-title">绑定 {this.renderErrorMessage()}</div>
236+
<div id="jsEditorDom" className={isOverFlowMaxSize?"editor-context editor-context-error":"editor-context"} ref={this.editorJsRef}>
237+
<div className="editor-type-tag">=</div>
238+
<MonacoEditor
239+
value={jsCode}
240+
{...defaultEditorProps}
241+
{...defaultEditorOption}
242+
{...{ language: 'javascript' }}
243+
onChange={(newCode) => this.updateCode(newCode)}
244+
editorDidMount={(useMonaco, editor) => {
245+
this.editorDidMount.call(this, editor, useMonaco);
246+
}}
247+
/>
248+
</div>
249+
</div>
250+
{this.renderBottom()}
251+
</div>
252+
</Overlay>
253+
}
254+
</div>
255+
);
256+
}
257+
}

0 commit comments

Comments
 (0)