Skip to content

Commit d6b0ef0

Browse files
committed
update folder structure and adds component actions to js console
1 parent 6722132 commit d6b0ef0

File tree

13 files changed

+1776
-375
lines changed

13 files changed

+1776
-375
lines changed
Lines changed: 1 addition & 375 deletions
Original file line numberDiff line numberDiff line change
@@ -1,375 +1 @@
1-
import { EmptyContent } from "components/EmptyContent";
2-
import { HelpText } from "components/HelpText";
3-
import { Tabs } from "components/Tabs";
4-
import {
5-
clearMockWindow,
6-
clearStyleEval,
7-
ConstructorToComp,
8-
evalFunc,
9-
evalStyle,
10-
RecordConstructorToComp,
11-
} from "lowcoder-core";
12-
import { CodeTextControl } from "comps/controls/codeTextControl";
13-
import SimpleStringControl from "comps/controls/simpleStringControl";
14-
import { MultiCompBuilder, withPropertyViewFn } from "comps/generators";
15-
import { list } from "comps/generators/list";
16-
import { BaseSection, CustomModal, PlusIcon, ScrollBar } from "lowcoder-design";
17-
import React, { useContext, useEffect, useState } from "react";
18-
import styled from "styled-components";
19-
import { ExternalEditorContext } from "util/context/ExternalEditorContext";
20-
import { runScriptInHost } from "util/commonUtils";
21-
import { getGlobalSettings } from "comps/utils/globalSettings";
22-
import { trans } from "i18n";
23-
import log from "loglevel";
24-
import { JSLibraryModal } from "components/JSLibraryModal";
25-
import { JSLibraryTree } from "components/JSLibraryTree";
26-
import { fetchJSLibrary } from "util/jsLibraryUtils";
27-
28-
export interface ExternalPreload {
29-
css?: string;
30-
libs?: string[];
31-
script?: string;
32-
runJavaScriptInHost?: boolean;
33-
}
34-
35-
interface RunAndClearable<T> {
36-
run(id: string, externalPreload?: T): Promise<any>;
37-
38-
clear(): Promise<any>;
39-
}
40-
41-
class LibsCompBase extends list(SimpleStringControl) implements RunAndClearable<string[]> {
42-
success: Record<string, boolean> = {};
43-
globalVars: Record<string, string[]> = {};
44-
externalLibs: string[] = [];
45-
runInHost: boolean = false;
46-
47-
getAllLibs() {
48-
return this.externalLibs.concat(this.getView().map((i) => i.getView()));
49-
}
50-
51-
async loadScript(url: string) {
52-
if (this.success[url]) {
53-
return;
54-
}
55-
return fetchJSLibrary(url).then((code) => {
56-
evalFunc(
57-
code,
58-
{},
59-
{},
60-
{
61-
scope: "function",
62-
disableLimit: this.runInHost,
63-
onSetGlobalVars: (v: string) => {
64-
this.globalVars[url] = this.globalVars[url] || [];
65-
if (!this.globalVars[url].includes(v)) {
66-
this.globalVars[url].push(v);
67-
}
68-
},
69-
}
70-
);
71-
this.success[url] = true;
72-
});
73-
}
74-
75-
async loadAllLibs() {
76-
const scriptRunners = this.getAllLibs().map((url) =>
77-
this.loadScript(url).catch((e) => {
78-
log.warn(e);
79-
})
80-
);
81-
82-
try {
83-
await Promise.all(scriptRunners);
84-
} catch (e) {
85-
log.warn("load preload libs error:", e);
86-
}
87-
}
88-
89-
async run(id: string, externalLibs: string[] = [], runInHost: boolean = false) {
90-
this.externalLibs = externalLibs;
91-
this.runInHost = runInHost;
92-
return this.loadAllLibs();
93-
}
94-
95-
async clear(): Promise<any> {
96-
clearMockWindow();
97-
}
98-
}
99-
100-
const LibsComp = withPropertyViewFn(LibsCompBase, (comp) => {
101-
useEffect(() => {
102-
comp.loadAllLibs();
103-
}, [comp.getView().length]);
104-
return (
105-
<ScrollBar style={{ height: "295px" }}>
106-
{comp.getAllLibs().length === 0 && (
107-
<EmptyContent text={trans("preLoad.jsLibraryEmptyContent")} style={{ margin: "0 16px" }} />
108-
)}
109-
<JSLibraryTree
110-
mode={"column"}
111-
libs={comp
112-
.getView()
113-
.map((i) => ({
114-
url: i.getView(),
115-
deletable: true,
116-
exportedAs: comp.globalVars[i.getView()]?.[0],
117-
}))
118-
.concat(
119-
comp.externalLibs.map((l) => ({
120-
url: l,
121-
deletable: false,
122-
exportedAs: comp.globalVars[l]?.[0],
123-
}))
124-
)}
125-
onDelete={(idx) => {
126-
comp.dispatch(comp.deleteAction(idx));
127-
}}
128-
/>
129-
</ScrollBar>
130-
);
131-
});
132-
133-
function runScript(code: string, inHost?: boolean) {
134-
if (inHost) {
135-
runScriptInHost(code);
136-
return;
137-
}
138-
try {
139-
evalFunc(code, {}, {});
140-
} catch (e) {
141-
log.error(e);
142-
}
143-
}
144-
145-
class ScriptComp extends CodeTextControl implements RunAndClearable<string> {
146-
runInHost: boolean = false;
147-
148-
runPreloadScript() {
149-
const code = this.getView();
150-
if (!code) {
151-
return;
152-
}
153-
runScript(code, this.runInHost);
154-
}
155-
156-
async run(id: string, externalScript: string = "", runInHost: boolean = false) {
157-
this.runInHost = runInHost;
158-
if (externalScript) {
159-
runScript(externalScript, runInHost);
160-
}
161-
this.runPreloadScript();
162-
}
163-
164-
async clear(): Promise<any> {
165-
clearMockWindow();
166-
}
167-
}
168-
169-
class CSSComp extends CodeTextControl implements RunAndClearable<string> {
170-
id = "";
171-
externalCSS: string = "";
172-
173-
async applyAllCSS() {
174-
const css = this.getView();
175-
evalStyle(this.id, [this.externalCSS, css]);
176-
}
177-
178-
async run(id: string, externalCSS: string = "") {
179-
this.id = id;
180-
this.externalCSS = externalCSS;
181-
return this.applyAllCSS();
182-
}
183-
184-
async clear() {
185-
clearStyleEval(this.id);
186-
}
187-
}
188-
189-
class GlobalCSSComp extends CodeTextControl implements RunAndClearable<string> {
190-
id = "";
191-
externalCSS: string = "";
192-
193-
async applyAllCSS() {
194-
const css = this.getView();
195-
evalStyle(this.id, [this.externalCSS, css], true);
196-
}
197-
198-
async run(id: string, externalCSS: string = "") {
199-
this.id = id;
200-
this.externalCSS = externalCSS;
201-
return this.applyAllCSS();
202-
}
203-
204-
async clear() {
205-
clearStyleEval(this.id);
206-
}
207-
}
208-
209-
const childrenMap = {
210-
libs: LibsComp,
211-
script: ScriptComp,
212-
css: CSSComp,
213-
globalCSS: GlobalCSSComp,
214-
};
215-
216-
type ChildrenInstance = RecordConstructorToComp<typeof childrenMap>;
217-
218-
function JavaScriptTabPane(props: { comp: ConstructorToComp<typeof ScriptComp> }) {
219-
useEffect(() => {
220-
props.comp.runPreloadScript();
221-
}, [props.comp]);
222-
223-
const codePlaceholder = `window.name = 'Tom';\nwindow.greet = () => "hello world";`;
224-
225-
return (
226-
<>
227-
<HelpText style={{ marginBottom: 20 }}>{trans("preLoad.jsHelpText")}</HelpText>
228-
{props.comp.propertyView({
229-
expandable: false,
230-
styleName: "window",
231-
codeType: "Function",
232-
language: "javascript",
233-
placeholder: codePlaceholder,
234-
})}
235-
</>
236-
);
237-
}
238-
239-
function CSSTabPane(props: { comp: CSSComp, isGlobal?: boolean }) {
240-
useEffect(() => {
241-
props.comp.applyAllCSS();
242-
}, [props.comp]);
243-
244-
const codePlaceholder = `.top-header {\n background-color: red; \n}`;
245-
246-
return (
247-
<>
248-
<HelpText style={{ marginBottom: 20 }}>{trans("preLoad.cssHelpText")}</HelpText>
249-
{props.comp.propertyView({
250-
expandable: false,
251-
placeholder: codePlaceholder,
252-
styleName: "window",
253-
language: "css",
254-
})}
255-
</>
256-
);
257-
}
258-
259-
enum TabKey {
260-
JavaScript = "js",
261-
CSS = "css",
262-
GLOBAL_CSS = "global_css",
263-
}
264-
265-
function PreloadConfigModal(props: ChildrenInstance) {
266-
const [activeKey, setActiveKey] = useState(TabKey.JavaScript);
267-
const { showScriptsAndStyleModal, changeExternalState } = useContext(ExternalEditorContext);
268-
269-
const tabItems = [
270-
{
271-
key: TabKey.JavaScript,
272-
label: 'JavaScript',
273-
children: <JavaScriptTabPane comp={props.script} />
274-
},
275-
{
276-
key: TabKey.CSS,
277-
label: 'CSS',
278-
children: <CSSTabPane comp={props.css} />
279-
},
280-
{
281-
key: TabKey.GLOBAL_CSS,
282-
label: 'Global CSS',
283-
children: <CSSTabPane comp={props.globalCSS} isGlobal />
284-
},
285-
]
286-
return (
287-
<CustomModal
288-
draggable
289-
mask={activeKey !== TabKey.CSS}
290-
open={showScriptsAndStyleModal}
291-
title={trans("preLoad.scriptsAndStyles")}
292-
destroyOnHidden
293-
onCancel={() => changeExternalState?.({ showScriptsAndStyleModal: false })}
294-
showOkButton={false}
295-
showCancelButton={false}
296-
width="600px"
297-
>
298-
<Tabs
299-
onChange={(k) => setActiveKey(k as TabKey)}
300-
style={{ marginBottom: 8, marginTop: 4 }}
301-
activeKey={activeKey}
302-
items={ tabItems }
303-
>
304-
</Tabs>
305-
</CustomModal>
306-
);
307-
}
308-
309-
const PreloadCompBase = new MultiCompBuilder(childrenMap, () => {})
310-
.setPropertyViewFn((children) => <PreloadConfigModal {...children} />)
311-
.build();
312-
313-
const AddJSLibraryButton = styled.div`
314-
cursor: pointer;
315-
margin-right: 16px;
316-
317-
g g {
318-
stroke: #8b8fa3;
319-
}
320-
321-
&:hover {
322-
g g {
323-
stroke: #222222;
324-
}
325-
}
326-
`;
327-
328-
const JSLibraryWrapper = styled.div`
329-
position: relative;
330-
`;
331-
332-
export class PreloadComp extends PreloadCompBase {
333-
async clear() {
334-
return Promise.allSettled(Object.values(this.children).map((i) => i.clear()));
335-
}
336-
337-
async run(id: string) {
338-
const { orgCommonSettings = {} } = getGlobalSettings();
339-
const { preloadCSS,preloadGlobalCSS, preloadJavaScript, preloadLibs, runJavaScriptInHost } = orgCommonSettings;
340-
await this.children.css.run(id, preloadCSS || "");
341-
await this.children.globalCSS.run('body', preloadGlobalCSS || "");
342-
await this.children.libs.run(id, preloadLibs || [], !!runJavaScriptInHost);
343-
await this.children.script.run(id, preloadJavaScript || "", !!runJavaScriptInHost);
344-
}
345-
346-
getJSLibraryPropertyView() {
347-
const libs = this.children.libs;
348-
return (
349-
<JSLibraryWrapper>
350-
<BaseSection
351-
name={trans("preLoad.jsLibrary")}
352-
width={288}
353-
noMargin
354-
style={{
355-
borderTop: "1px solid #e1e3eb",
356-
backgroundColor: "#fff",
357-
}}
358-
additionalButton={
359-
<AddJSLibraryButton>
360-
<JSLibraryModal
361-
runInHost={libs.runInHost}
362-
trigger={<PlusIcon height={"46px"} />}
363-
onCheck={(url) => !libs.getAllLibs().includes(url)}
364-
onLoad={(url) => libs.loadScript(url)}
365-
onSuccess={(url) => libs.dispatch(libs.pushAction(url))}
366-
/>
367-
</AddJSLibraryButton>
368-
}
369-
>
370-
{this.children.libs.getPropertyView()}
371-
</BaseSection>
372-
</JSLibraryWrapper>
373-
);
374-
}
375-
}
1+
export { PreloadComp } from "./preLoadComp/preLoadComp";

0 commit comments

Comments
 (0)