diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index f331676ab6..93e8d275fb 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -11,7 +11,7 @@ body: Please search open/closed issues before submitting. Someone might have asked the same thing before 😉! - If you want to discuss sth, please go to the [Discussion](https://github.com/illa-family/discussions) + If you want to discuss sth, please go to the [Discussion](https://github.com/illacloud/discussions) - type: "input" id: "description" diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 1d6d3c9f95..ef0ac0b956 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,8 @@ blank_issues_enabled: false contact_links: - name: Ask a question - url: https://github.com/orgs/illa-family/discussions + url: https://github.com/orgs/illacloud/discussions about: Ask questions and discuss topics with other community members - name: Chat with other community members - url: https://discord.gg/2tGBuJkgd6 - about: The official illa Family Discord community + url: https://discord.gg/illacloud + about: The official illa Cloud Discord community diff --git a/.gitmodules b/.gitmodules index 530e10c2b0..143ba76877 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "illa-design"] path = illa-design - url = https://github.com/illa-family/illa-design.git + url = https://github.com/illacloud/illa-design.git branch = develop diff --git a/apps/builder/package.json b/apps/builder/package.json index d89c80757c..674adcc65f 100644 --- a/apps/builder/package.json +++ b/apps/builder/package.json @@ -1,11 +1,11 @@ { "name": "illa-builder", "description": "Help every Developer as fast as to build Business Tools", - "repository": "git@github.com:illa-family/illa-builder.git", + "repository": "git@github.com:illacloud/illa-builder.git", "private": true, - "author": "illa Family", + "author": "illa Cloud", "license": "Apache-2.0", - "version": "1.1.2", + "version": "1.3.2", "scripts": { "dev": "vite --mode cloud", "build-cloud": "vite build --mode cloud", diff --git a/apps/builder/src/components/CodeEditor/index.tsx b/apps/builder/src/components/CodeEditor/index.tsx index 376a3215f9..59969aed8d 100644 --- a/apps/builder/src/components/CodeEditor/index.tsx +++ b/apps/builder/src/components/CodeEditor/index.tsx @@ -1,7 +1,13 @@ -/* eslint-disable */ -import { forwardRef, useContext, useEffect, useRef, useState } from "react" +import { + forwardRef, + useContext, + useEffect, + useRef, + useState, + useCallback, +} from "react" import { Global } from "@emotion/react" -import { debounce, get } from "lodash" +import { cloneDeep, debounce, get } from "lodash" import CodeMirror, { Editor } from "codemirror" import "codemirror/lib/codemirror.css" import "codemirror/lib/codemirror" @@ -12,7 +18,7 @@ import "codemirror/addon/display/placeholder" import "codemirror/addon/display/autorefresh" import "./modes" import "./hinter" -import "./lintHelper" +import { clearMarks, lineMarker } from "@/components/CodeEditor/lintHelper" import { BaseTern, TernServer } from "./TernSever" import { Trigger } from "@illa-design/trigger" import { evaluateDynamicString } from "@/utils/evaluateDynamicString" @@ -20,15 +26,14 @@ import { CodePreview } from "./CodePreview" import { CodeEditorProps, EditorModes, ResultPreview } from "./interface" import { applyCodeEditorStyle, codemirrorStyle } from "./style" import { isCloseKey, isExpectType } from "./utils" -import { GLOBAL_DATA_CONTEXT } from "@/page/App/context/globalDataProvider" import { useSelector } from "react-redux" import { getLanguageValue } from "@/redux/builderInfo/builderInfoSelector" import { getExecutionError, getExecutionResult, } from "@/redux/currentApp/executionTree/executionSelector" -import { clearMarks, lineMarker } from "@/components/CodeEditor/lintHelper" import { VALIDATION_TYPES } from "@/utils/validationFactory" +import { isDynamicString } from "@/utils/evaluateDynamicString/utils" export const CodeEditor = forwardRef( (props, ref) => { @@ -51,29 +56,24 @@ export const CodeEditor = forwardRef( onChange, ...otherProps } = props - const { globalData } = useContext(GLOBAL_DATA_CONTEXT) const languageValue = useSelector(getLanguageValue) const executionError = useSelector(getExecutionError) const executionResult = useSelector(getExecutionResult) + const executionResultRef = useRef>(executionResult) const codeTargetRef = useRef(null) const sever = useRef() - const [editor, setEditor] = useState() + const ILLAEditor = useRef(null) const [preview, setPreview] = useState({ state: "default", type: expectedType, }) const [previewVisible, setPreviewVisible] = useState() const [focus, setFocus] = useState() - const [error, setError] = useState() + const [error, setError] = useState(false) // Solve the closure problem const latestProps = useRef(props) latestProps.current = props - const globalDataRef = useRef(globalData) - useEffect(() => { - globalDataRef.current = globalData - }, [globalData]) - const handleFocus = () => { setFocus(true) } @@ -84,38 +84,48 @@ export const CodeEditor = forwardRef( setPreviewVisible(false) } - const valueChanged = (currentValue: string) => { - let calcResult: any = null - let previewType = expectedType - setError(false) - try { - calcResult = evaluateDynamicString( - "", - currentValue, - globalDataRef.current, - ) - // [TODO]: v1 evaluate - // if (!currentValue?.includes("{{")) { - // calcResult = getEvalValue(previewType, calcResult) - // } - isExpectType(previewType, calcResult) - setPreview({ - state: "default", - type: previewType, - content: calcResult, - }) - } catch (e) { - setError(true) - if (e instanceof Error) { + const valueChanged = useCallback( + (currentValue: string) => { + let calcResult: any = null + let previewType = expectedType + setError(false) + try { + const isDynamic = isDynamicString(currentValue) + if (isDynamic) { + calcResult = evaluateDynamicString( + "", + currentValue, + executionResultRef.current || {}, + ) + } else { + calcResult = currentValue + } + + // [TODO]: v1 evaluate + // if (!currentValue?.includes("{{")) { + // calcResult = getEvalValue(previewType, calcResult) + // } + calcResult && isExpectType(previewType, calcResult) + setPreview({ - state: "error", - content: e.toString(), + state: "default", + type: previewType, + content: calcResult, }) + } catch (e) { + setError(true) + if (e instanceof Error) { + setPreview({ + state: "error", + content: e.toString(), + }) + } + } finally { + latestProps.current.onChange?.(currentValue, calcResult) } - } finally { - latestProps.current.onChange?.(currentValue, calcResult) - } - } + }, + [expectedType], + ) useEffect(() => { if (path) { @@ -135,8 +145,8 @@ export const CodeEditor = forwardRef( content: evalError.errorMessage, }) } - if (lintError?.errorLine && editor) { - lineMarker(editor, lintError.errorLine - 1) + if (lintError?.errorLine && ILLAEditor.current) { + lineMarker(ILLAEditor.current, lintError.errorLine - 1) } } else { setError(false) @@ -147,7 +157,13 @@ export const CodeEditor = forwardRef( }) } } - }, [executionError, executionResult, path]) + }, [executionError, executionResult, expectedType, path]) + + useEffect(() => { + if (!path && previewVisible) { + valueChanged(value || "") + } + }, [valueChanged, value, path, previewVisible]) const handleChange = (editor: Editor) => { const currentValue = editor?.getValue() @@ -161,37 +177,40 @@ export const CodeEditor = forwardRef( const debounceHandleChange = debounce(handleChange, 300) - const handleKeyUp = (editor: Editor, event: KeyboardEvent) => { - const key = event.key - const code = `${event.ctrlKey ? "Ctrl+" : ""}${event.code}` - if (isCloseKey(code) || isCloseKey(key)) { - editor.closeHint() - return - } - const cursor = editor.getCursor() - const line = editor.getLine(cursor.line) - let showAutocomplete = false - if (mode === "XML_JS" || mode === "HTML_JS") { - showAutocomplete = true - } - if (key === "/") { - showAutocomplete = true - } else if (event.code === "Backspace") { - const prevChar = line[cursor.ch - 1] - showAutocomplete = !!prevChar && /[a-zA-Z_0-9.]/.test(prevChar) - } else if (key === "{") { - const prevChar = line[cursor.ch - 2] - showAutocomplete = prevChar === "{" - } else if (key.length == 1) { - showAutocomplete = /[a-zA-Z_0-9.]/.test(key) - } - showAutocomplete && handleAutocomplete(editor, line) - } + const handleKeyUp = useCallback( + (editor: Editor, event: KeyboardEvent) => { + const key = event.key + const code = `${event.ctrlKey ? "Ctrl+" : ""}${event.code}` + if (isCloseKey(code) || isCloseKey(key)) { + editor.closeHint() + return + } + const cursor = editor.getCursor() + const line = editor.getLine(cursor.line) + let showAutocomplete = false + if (mode === "XML_JS" || mode === "HTML_JS") { + showAutocomplete = true + } + if (key === "/") { + showAutocomplete = true + } else if (event.code === "Backspace") { + const prevChar = line[cursor.ch - 1] + showAutocomplete = !!prevChar && /[a-zA-Z_0-9.]/.test(prevChar) + } else if (key === "{") { + const prevChar = line[cursor.ch - 2] + showAutocomplete = prevChar === "{" + } else if (key.length == 1) { + showAutocomplete = /[a-zA-Z_0-9.]/.test(key) + } + showAutocomplete && handleAutocomplete(editor, line) + }, + [mode], + ) useEffect(() => { - const currentValue = editor?.getValue() + const currentValue = ILLAEditor.current?.getValue() if (value !== currentValue) { - editor?.setValue(value ?? "") + ILLAEditor.current?.setValue(value ?? "") } }, [value]) @@ -219,17 +238,21 @@ export const CodeEditor = forwardRef( } } + useEffect(() => { + executionResultRef.current = executionResult + }, [executionResult]) + useEffect(() => { sever.current = TernServer(languageValue, { ...executionResult }) }, [executionResult, languageValue]) useEffect(() => { - editor?.setOption("mode", EditorModes[mode]) + ILLAEditor.current?.setOption("mode", EditorModes[mode]) }, [mode]) useEffect(() => { - if (!editor) { - const editor = CodeMirror(codeTargetRef.current!, { + if (!ILLAEditor.current) { + ILLAEditor.current = CodeMirror(codeTargetRef.current!, { mode: EditorModes[mode], placeholder, lineNumbers, @@ -247,23 +270,34 @@ export const CodeEditor = forwardRef( }, }) if (noTab) { - editor?.setOption("extraKeys", { Tab: false }) + ILLAEditor.current?.setOption("extraKeys", { Tab: false }) } if (lineNumbers) { - editor?.setOption("gutters", ["CodeMirror-lint-markers"]) + ILLAEditor.current?.setOption("gutters", ["CodeMirror-lint-markers"]) } - editor.on("change", debounceHandleChange) - editor.on("keyup", handleKeyUp) - editor.on("focus", handleFocus) - editor.on("blur", handleBlur) - setEditor(editor) + ILLAEditor.current.on("change", debounceHandleChange) + ILLAEditor.current.on("keyup", handleKeyUp) + ILLAEditor.current.on("focus", handleFocus) + ILLAEditor.current.on("blur", handleBlur) } + }, [ + debounceHandleChange, + handleKeyUp, + lineNumbers, + mode, + noTab, + placeholder, + readOnly, + value, + ]) + useEffect(() => { return () => { - editor?.off("change", debounceHandleChange) - editor?.off("keyup", handleKeyUp) - editor?.off("focus", handleFocus) - editor?.off("blur", handleBlur) + ILLAEditor.current?.off("change", debounceHandleChange) + ILLAEditor.current?.off("keyup", handleKeyUp) + ILLAEditor.current?.off("focus", handleFocus) + ILLAEditor.current?.off("blur", handleBlur) + ILLAEditor.current = null } }, []) diff --git a/apps/builder/src/components/CodeEditor/style.ts b/apps/builder/src/components/CodeEditor/style.ts index 8caf6fc383..fe91bca099 100644 --- a/apps/builder/src/components/CodeEditor/style.ts +++ b/apps/builder/src/components/CodeEditor/style.ts @@ -132,7 +132,6 @@ export function applyCodeEditorStyle( &:hover { border-color: ${globalColor(`--${illaPrefix}-techPurple-06`)}; - z-index: 1; } ` } diff --git a/apps/builder/src/hooks/useInitApp.tsx b/apps/builder/src/hooks/useInitApp.tsx index fe3871218f..68d510955f 100644 --- a/apps/builder/src/hooks/useInitApp.tsx +++ b/apps/builder/src/hooks/useInitApp.tsx @@ -12,6 +12,7 @@ import { useDispatch } from "react-redux" import { IllaMode } from "@/redux/config/configState" import { executionActions } from "@/redux/currentApp/executionTree/executionSlice" import { DisplayNameGenerator } from "@/utils/generators/generateDisplayName" +import { runAction } from "@/page/App/components/Actions/ActionPanel/utils/runAction" export const useInitBuilderApp = (model: IllaMode) => { // editor default version id == 0 @@ -22,49 +23,65 @@ export const useInitBuilderApp = (model: IllaMode) => { useEffect(() => { const controller = new AbortController() - Api.request( - { - url: `/apps/${appId}/versions/${versionId}`, - method: "GET", - signal: controller.signal, - }, - (response) => { - if (model === "edit") { - dispatch(configActions.resetConfig()) - } - dispatch(configActions.updateIllaMode(model)) - dispatch(appInfoActions.updateAppInfoReducer(response.data.appInfo)) - dispatch( - componentsActions.updateComponentReducer(response.data.components), - ) - dispatch(actionActions.updateActionListReducer(response.data.actions)) + new Promise((resolve, reject) => { + Api.request( + { + url: `/apps/${appId}/versions/${versionId}`, + method: "GET", + signal: controller.signal, + }, + (response) => { + if (model === "edit") { + dispatch(configActions.resetConfig()) + } + dispatch(configActions.updateIllaMode(model)) + dispatch(appInfoActions.updateAppInfoReducer(response.data.appInfo)) + dispatch( + componentsActions.updateComponentReducer(response.data.components), + ) + dispatch(actionActions.updateActionListReducer(response.data.actions)) - dispatch( - dragShadowActions.updateDragShadowReducer( - response.data.dragShadowState, - ), - ) - dispatch( - dottedLineSquareActions.updateDottedLineSquareReducer( - response.data.dottedLineSquareState, - ), - ) - DisplayNameGenerator.initApp(appId ?? "") - DisplayNameGenerator.updateDisplayNameList( - response.data.components, - response.data.actions, - ) - dispatch(executionActions.startExecutionReducer()) - if (model === "edit" && response.data.actions.length > 0) { - dispatch(configActions.changeSelectedAction(response.data.actions[0])) - } - }, - (e) => {}, - (e) => {}, - (loading) => { - setLoadingState(loading) - }, - ) + dispatch( + dragShadowActions.updateDragShadowReducer( + response.data.dragShadowState, + ), + ) + dispatch( + dottedLineSquareActions.updateDottedLineSquareReducer( + response.data.dottedLineSquareState, + ), + ) + DisplayNameGenerator.initApp(appId ?? "") + DisplayNameGenerator.updateDisplayNameList( + response.data.components, + response.data.actions, + ) + dispatch(executionActions.startExecutionReducer()) + if (model === "edit" && response.data.actions.length > 0) { + dispatch( + configActions.changeSelectedAction(response.data.actions[0]), + ) + } + resolve(response.data) + }, + (e) => { + reject("failure") + }, + (e) => { + reject("crash") + }, + (loading) => { + setLoadingState(loading) + }, + ) + }).then((value) => { + const autoRunAction = value.actions.filter((action) => { + return action.triggerMode === "automate" + }) + autoRunAction.forEach((action) => { + runAction(action) + }) + }) return () => { controller.abort() } diff --git a/apps/builder/src/page/App/components/Actions/ActionGenerator/config.ts b/apps/builder/src/page/App/components/Actions/ActionGenerator/config.ts index a60aea3b77..0be6df3d47 100644 --- a/apps/builder/src/page/App/components/Actions/ActionGenerator/config.ts +++ b/apps/builder/src/page/App/components/Actions/ActionGenerator/config.ts @@ -35,10 +35,6 @@ export const Databases: ActionDataItem[] = [ actionType: "elastic", isDraft: true, }, - { - actionType: "snowflake", - isDraft: true, - }, ] export const Apis: ActionDataItem[] = [ @@ -54,14 +50,6 @@ export const Apis: ActionDataItem[] = [ actionType: "s3", isDraft: true, }, - { - actionType: "zapier", - isDraft: true, - }, - { - actionType: "datadog", - isDraft: true, - }, { actionType: "smtp", isDraft: true, diff --git a/apps/builder/src/page/App/components/Actions/getIcon.tsx b/apps/builder/src/page/App/components/Actions/getIcon.tsx index e08bbaa723..7fc7ebf5eb 100644 --- a/apps/builder/src/page/App/components/Actions/getIcon.tsx +++ b/apps/builder/src/page/App/components/Actions/getIcon.tsx @@ -30,14 +30,8 @@ export function getIconFromResourceType( return case "mariadb": return - case "snowflake": - return case "tidb": return - case "datadog": - return - case "zapier": - return case "s3": return case "mysql": @@ -69,14 +63,8 @@ export function getIconFromActionType( return case "mariadb": return - case "snowflake": - return case "tidb": return - case "datadog": - return - case "zapier": - return case "s3": return case "mysql": diff --git a/apps/builder/src/page/App/components/ComponentManager/index.tsx b/apps/builder/src/page/App/components/ComponentManager/index.tsx index 991619ea1f..38d7cd6988 100644 --- a/apps/builder/src/page/App/components/ComponentManager/index.tsx +++ b/apps/builder/src/page/App/components/ComponentManager/index.tsx @@ -8,6 +8,7 @@ import { FocusManager } from "@/utils/focusManager" import { ConfigPanel } from "@/page/App/components/ConfigPanel" import { ComponentPanel } from "@/page/App/components/ComponentPanel" import { PagePanel } from "@/page/App/components/PagePanel" +import { getCurrentPageDisplayName } from "@/redux/currentApp/executionTree/executionSelector" export const ComponentsManager: FC> = ( props, @@ -17,6 +18,8 @@ export const ComponentsManager: FC> = ( const [activeKey, setActiveKey] = useState("Insert") const selectedDisplayNames = useSelector(getSelectedComponents) + const currentPageDisplayName = useSelector(getCurrentPageDisplayName) + const prevPageDisplayName = useRef(currentPageDisplayName) const isClickChange = useRef(false) useEffect(() => { @@ -32,8 +35,12 @@ export const ComponentsManager: FC> = ( } } } + if (prevPageDisplayName.current !== currentPageDisplayName) { + setActiveKey("Page") + prevPageDisplayName.current = currentPageDisplayName + } isClickChange.current = false - }, [activeKey, selectedDisplayNames]) + }, [activeKey, currentPageDisplayName, selectedDisplayNames]) return (
= (props) => { const { componentNode, @@ -63,6 +65,8 @@ export const RenderComponentCanvas: FC<{ canResizeY = true, safeRowNumber, blockColumns = BASIC_BLOCK_COLUMNS, + addedRowNumber, + canAutoScroll = false, } = props const isShowCanvasDot = useSelector(isShowDot) @@ -82,6 +86,7 @@ export const RenderComponentCanvas: FC<{ const currentCanvasRef = useRef( null, ) as MutableRefObject + const autoScrollTimeoutID = useRef() const unitWidth = useMemo(() => { return bounds.width / blockColumns @@ -89,14 +94,6 @@ export const RenderComponentCanvas: FC<{ const componentTree = useMemo(() => { const childrenNode = componentNode.childrenNode - if ( - componentNode.type === "CANVAS" && - (!Array.isArray(componentNode.childrenNode) || - componentNode.childrenNode.length === 0) && - !isShowCanvasDot - ) { - return - } return childrenNode?.map((item) => { const h = item.h * UNIT_HEIGHT const w = item.w * unitWidth @@ -116,6 +113,7 @@ export const RenderComponentCanvas: FC<{ canResizeY={canResizeY} minHeight={minHeight} safeRowNumber={safeRowNumber} + addedRowNumber={addedRowNumber} /> ) case "EDITOR_SCALE_SQUARE": @@ -143,15 +141,14 @@ export const RenderComponentCanvas: FC<{ } }) }, [ + addedRowNumber, blockColumns, canResizeY, collisionEffect, componentNode.childrenNode, componentNode.displayName, componentNode.h, - componentNode.type, containerPadding, - isShowCanvasDot, minHeight, rowNumber, safeRowNumber, @@ -443,34 +440,76 @@ export const RenderComponentCanvas: FC<{ [bounds, unitWidth, UNIT_HEIGHT, canDrop, isFreezeCanvas, componentNode], ) + const maxY = useMemo(() => { + let maxY = 0 + componentNode.childrenNode?.forEach((node) => { + maxY = Math.max(maxY, node.y + node.h) + }) + return maxY + }, [componentNode.childrenNode]) + + const finalRowNumber = useMemo(() => { + return Math.max( + maxY, + Math.floor((minHeight || document.body.clientHeight) / UNIT_HEIGHT), + ) + }, [maxY, minHeight]) + useEffect(() => { if (!isActive && canResizeY) { - const childrenNodes = componentNode.childrenNode - let maxY = 0 - childrenNodes?.forEach((node) => { - maxY = Math.max(maxY, node.y + node.h) - }) if (illaMode === "edit") { - setRowNumber( - Math.max( - maxY + safeRowNumber, - Math.floor((minHeight || document.body.clientHeight) / UNIT_HEIGHT), - ), - ) + if ( + finalRowNumber === maxY && + finalRowNumber + addedRowNumber >= rowNumber + ) { + setRowNumber(finalRowNumber + addedRowNumber) + if ( + canAutoScroll && + rowNumber !== 0 && + finalRowNumber + addedRowNumber !== rowNumber + ) { + clearTimeout(autoScrollTimeoutID.current) + autoScrollTimeoutID.current = setTimeout(() => { + containerRef.current?.scrollBy({ + top: (addedRowNumber * UNIT_HEIGHT) / 4, + behavior: "smooth", + }) + }, 60) + } + } else { + setRowNumber(finalRowNumber) + } } else { setRowNumber(maxY) } } }, [ - bounds.height, + addedRowNumber, + canAutoScroll, canResizeY, - componentNode.childrenNode, + containerRef, + finalRowNumber, illaMode, isActive, - minHeight, - safeRowNumber, + maxY, + rowNumber, ]) + useEffect(() => { + return () => { + clearTimeout(autoScrollTimeoutID.current) + } + }, []) + + if ( + componentNode.type === "CANVAS" && + (!Array.isArray(componentNode.childrenNode) || + componentNode.childrenNode.length === 0) && + !isShowCanvasDot + ) { + return + } + return (
{ diff --git a/apps/builder/src/page/App/components/DotPanel/renderSection.tsx b/apps/builder/src/page/App/components/DotPanel/renderSection.tsx index ef4be23f94..5bedaf77e4 100644 --- a/apps/builder/src/page/App/components/DotPanel/renderSection.tsx +++ b/apps/builder/src/page/App/components/DotPanel/renderSection.tsx @@ -121,6 +121,8 @@ export const RenderSection = forwardRef( canResizeY minHeight={containerBound.height - 16} safeRowNumber={0} + addedRowNumber={40} + canAutoScroll /> )}
@@ -369,6 +371,7 @@ export const RenderHeaderSection = forwardRef< canResizeY minHeight={containerBound.height - 16} safeRowNumber={0} + addedRowNumber={5} /> )}
@@ -633,6 +636,7 @@ export const RenderFooterSection = forwardRef< canResizeY minHeight={containerBound.height - 16} safeRowNumber={0} + addedRowNumber={5} /> )} @@ -889,6 +893,8 @@ export const RenderLeftSection = forwardRef< } safeRowNumber={0} blockColumns={16} + addedRowNumber={40} + canAutoScroll /> )} {showFoldIcon && ( @@ -1186,6 +1192,8 @@ export const RenderRightSection = forwardRef< } safeRowNumber={0} blockColumns={16} + addedRowNumber={40} + canAutoScroll /> )} {showFoldIcon && ( diff --git a/apps/builder/src/page/App/components/PanelSetters/InputSetter/editableInputSetterWithMeasure.tsx b/apps/builder/src/page/App/components/PanelSetters/InputSetter/editableInputSetterWithMeasure.tsx new file mode 100644 index 0000000000..b9f2e79f61 --- /dev/null +++ b/apps/builder/src/page/App/components/PanelSetters/InputSetter/editableInputSetterWithMeasure.tsx @@ -0,0 +1,44 @@ +import { FC, useCallback, FocusEvent } from "react" +import { Input } from "@illa-design/input" +import { + editableInputIconStyle, + editableInputSetterStyle, +} from "@/page/App/components/PanelSetters/InputSetter/style" +import { EditableInputSetterProps } from "@/page/App/components/PanelSetters/InputSetter/interface" + +const valueWithMeasureRegex = /^\d+(\.\d+)?(px|vh|vw|%|em|rem|cm|mm|in|pt|pc)$/ + +export const EditableInputWithMeasureSetter: FC = ( + props, +) => { + const { value, handleUpdateDsl, attrName, icon } = props + + const fixInputValueWhenBlur = useCallback( + (e: FocusEvent) => { + let currentValue = e.target.value.toLocaleLowerCase().replace(/\s*/g, "") + if (currentValue && !valueWithMeasureRegex.test(currentValue)) { + const decimalArr = currentValue.match(/\d+(\.\d+)?/g) + if (decimalArr) currentValue = decimalArr.join("") + "px" + } + handleUpdateDsl(attrName, currentValue) + }, + [attrName, handleUpdateDsl], + ) + + return ( +
+ {icon ?
{icon}
: null} +
+ { + handleUpdateDsl(attrName, value) + }} + onBlur={fixInputValueWhenBlur} + /> +
+
+ ) +} diff --git a/apps/builder/src/page/App/components/PanelSetters/TableSetter/interface.ts b/apps/builder/src/page/App/components/PanelSetters/TableSetter/interface.ts index 96adb4ae1c..96f6f45fa9 100644 --- a/apps/builder/src/page/App/components/PanelSetters/TableSetter/interface.ts +++ b/apps/builder/src/page/App/components/PanelSetters/TableSetter/interface.ts @@ -14,4 +14,10 @@ export type SelectOptions = ( export interface ColumnsSelectSetterProps extends BaseSetter, PanelLabelProps { allowClear?: boolean } +export interface TableDataSourceSetterProps + extends BaseSetter, + PanelLabelProps { + allowClear?: boolean +} + export interface TableDataInputSetterProps extends BaseInputSetterProps {} diff --git a/apps/builder/src/page/App/components/PanelSetters/TableSetter/tableDataInputSetter.tsx b/apps/builder/src/page/App/components/PanelSetters/TableSetter/tableDataInputSetter.tsx index fdc4c7d44e..f2aedcc1ca 100644 --- a/apps/builder/src/page/App/components/PanelSetters/TableSetter/tableDataInputSetter.tsx +++ b/apps/builder/src/page/App/components/PanelSetters/TableSetter/tableDataInputSetter.tsx @@ -38,13 +38,15 @@ export const TableDataInputSetter: FC = (props) => { (attrName: string, newValue: any) => { try { const data = evaluateDynamicString("", newValue, BUILDER_CALC_CONTEXT) - let newColumns = tansTableDataToColumns(data) - if (!isEqual(newColumns, columns)) { - handleUpdateMultiAttrDSL?.({ - columns: newColumns, - [attrName]: newValue, - }) - return + if (Array.isArray(data)) { + let newColumns = tansTableDataToColumns(data) + if (!isEqual(newColumns, columns)) { + handleUpdateMultiAttrDSL?.({ + columns: newColumns, + [attrName]: newValue, + }) + return + } } } catch {} handleUpdateMultiAttrDSL?.({ diff --git a/apps/builder/src/page/App/components/PanelSetters/TableSetter/tableDataSourceSelectSetter.tsx b/apps/builder/src/page/App/components/PanelSetters/TableSetter/tableDataSourceSelectSetter.tsx new file mode 100644 index 0000000000..47c707a6d4 --- /dev/null +++ b/apps/builder/src/page/App/components/PanelSetters/TableSetter/tableDataSourceSelectSetter.tsx @@ -0,0 +1,155 @@ +import { FC, useCallback, useMemo } from "react" +import { TableDataSourceSetterProps } from "@/page/App/components/PanelSetters/TableSetter/interface" +import { debounce, get } from "lodash" +import { useSelector } from "react-redux" +import { RootState } from "@/store" +import { + getActionExecutionResult, + getExecutionError, +} from "@/redux/currentApp/executionTree/executionSelector" +import { getActionList } from "@/redux/currentApp/action/actionSelector" +import { searchDSLByDisplayName } from "@/redux/currentApp/editor/components/componentsSelector" +import { publicPaddingStyle } from "@/page/App/components/InspectPanel/style" +import { BaseDynamicSelect } from "@/page/App/components/PanelSetters/SelectSetter/baseDynamicSelect" +import { VALIDATION_TYPES } from "@/utils/validationFactory" +import { tansTableDataToColumns } from "@/widgetLibrary/TableWidget/utils" +import { evaluateDynamicString } from "@/utils/evaluateDynamicString" + +export const TableDataSourceSelectSetter: FC = ( + props, +) => { + const { + widgetDisplayName, + labelName, + labelDesc, + handleUpdateDsl, + handleUpdateMultiAttrDSL, + } = props + + const actions = useSelector(getActionList) + const actionExecutionResult = useSelector(getActionExecutionResult) + const isError = useSelector((state) => { + const errors = getExecutionError(state) + const thisError = get(errors, `${widgetDisplayName}.dataSource`) + return thisError?.length > 0 + }) + const targetComponentProps = useSelector>( + (rootState) => { + return searchDSLByDisplayName(widgetDisplayName, rootState)?.props || {} + }, + ) + + const customColumns = useMemo(() => { + const columns = get(targetComponentProps, "columns", []) + return columns.filter((item: any) => item.custom) + }, [targetComponentProps]) + + const isDynamic = useMemo(() => { + const dataSourceMode = get(targetComponentProps, "dataSourceMode", "select") + return dataSourceMode === "dynamic" + }, [targetComponentProps]) + + const finalValue = useMemo(() => { + if (isDynamic) { + return get(targetComponentProps, "dataSourceJS") + } else { + return get(targetComponentProps, "dataSource") + } + }, [isDynamic, targetComponentProps]) + + const selectedOptions = useMemo(() => { + return actions.map((action) => ({ + label: action.displayName, + value: `{{${action.displayName}.data}}`, + })) + }, [actions]) + + const handleClickFxButton = useCallback(() => { + const isInOption = selectedOptions.some( + (option) => option.value === finalValue, + ) + if (isDynamic) { + handleUpdateDsl("dataSourceMode", "select") + if (!isInOption) { + handleUpdateDsl("dataSource", "") + } else { + handleUpdateDsl("dataSource", finalValue) + } + } else { + handleUpdateDsl("dataSourceMode", "dynamic") + if (isInOption) { + handleUpdateDsl("dataSourceJS", finalValue) + } + } + }, [handleUpdateDsl, isDynamic, selectedOptions, finalValue]) + + const handleChangeInput = useCallback( + (value: string) => { + const data = evaluateDynamicString("", value, actionExecutionResult) + if (Array.isArray(data)) { + let newColumns = tansTableDataToColumns(data) + if (newColumns?.length) { + handleUpdateMultiAttrDSL?.({ + columns: newColumns.concat(customColumns), + dataSourceJS: value, + }) + return + } + } + handleUpdateDsl("dataSourceJS", value) + }, + [ + actionExecutionResult, + customColumns, + handleUpdateDsl, + handleUpdateMultiAttrDSL, + ], + ) + + const debounceHandleChangeInput = debounce(handleChangeInput, 300) + + const handleChangeSelect = useCallback( + (value: any) => { + const data = evaluateDynamicString("", value, actionExecutionResult) + if (Array.isArray(data)) { + let newColumns = tansTableDataToColumns(data) + if (newColumns?.length) { + handleUpdateMultiAttrDSL?.({ + columns: newColumns.concat(customColumns), + dataSource: value, + }) + return + } + } + handleUpdateDsl("dataSource", value) + }, + [ + actionExecutionResult, + customColumns, + handleUpdateDsl, + handleUpdateMultiAttrDSL, + ], + ) + + return ( +
+ +
+ ) +} + +TableDataSourceSelectSetter.displayName = "TableDataSourceSelectSetter" diff --git a/apps/builder/src/page/App/components/PanelSetters/index.tsx b/apps/builder/src/page/App/components/PanelSetters/index.tsx index debbee1264..6329ae5a64 100644 --- a/apps/builder/src/page/App/components/PanelSetters/index.tsx +++ b/apps/builder/src/page/App/components/PanelSetters/index.tsx @@ -33,6 +33,8 @@ import { TabsDefaultKeySetter } from "@/page/App/components/PanelSetters/TabsSet import { MenuOptionSetter } from "@/page/App/components/PanelSetters/MenuSetter/MenuOptionSetter" import { EventTargetPageSelect } from "./SelectSetter/pageSelect" import { EventTargetViewSelect } from "./SelectSetter/eventBodyViewSelect" +import { EditableInputWithMeasureSetter } from "./InputSetter/editableInputSetterWithMeasure" +import { TableDataSourceSelectSetter } from "@/page/App/components/PanelSetters/TableSetter/tableDataSourceSelectSetter" const SetterTypeMapSetter = { INPUT_SETTER: BaseInput, @@ -51,6 +53,7 @@ const SetterTypeMapSetter = { TABS_DEFAULT_KEY_SETTER: TabsDefaultKeySetter, TABS_CONTAINER_SELECT_SETTER: TabsContainerSelectSetter, TABLE_DATA_INPUT_SETTER: TableDataInputSetter, + TABLE_DATASOURCE_SELECT_SETTER: TableDataSourceSelectSetter, OPTION_MAPPED_SETTER: MappedOptionSetter, EVENT_HANDLER_SETTER: EventHandlerSetter, EVENT_TARGET_SELECT_SETTER: EventTargetWidgetSelect, @@ -61,6 +64,7 @@ const SetterTypeMapSetter = { EVENT_WIDGET_METHOD_SELECT_SETTER: EventWidgetMethodSelect, EVENT_ACTION_SELECT_SETTER: EventActionTypeSelect, EDITABLE_INPUT_SETTER: EditableInputSetter, + EDITABLE_INPUT_WITH_MEASURE_SETTER: EditableInputWithMeasureSetter, BASE_DYNAMIC_SELECT_SETTER: BaseDynamicSelect, CHART_DATASOURCE_SELECT_SETTER: ChartDataSourceSetter, CHART_KEYS_SELECT_SETTER: ChartKeysSelectSetter, diff --git a/apps/builder/src/page/Dashboard/components/ResourceGenerator/config.ts b/apps/builder/src/page/Dashboard/components/ResourceGenerator/config.ts index f4d5899deb..1493a9738e 100644 --- a/apps/builder/src/page/Dashboard/components/ResourceGenerator/config.ts +++ b/apps/builder/src/page/Dashboard/components/ResourceGenerator/config.ts @@ -35,10 +35,6 @@ export const Databases: ResourceDataItem[] = [ resourceType: "elastic", isDraft: true, }, - { - resourceType: "snowflake", - isDraft: true, - }, ] export const Apis: ResourceDataItem[] = [ @@ -54,14 +50,6 @@ export const Apis: ResourceDataItem[] = [ resourceType: "s3", isDraft: true, }, - { - resourceType: "zapier", - isDraft: true, - }, - { - resourceType: "datadog", - isDraft: true, - }, { resourceType: "smtp", isDraft: true, diff --git a/apps/builder/src/page/Deploy/style.ts b/apps/builder/src/page/Deploy/style.ts index 540bbef524..b2b3e704b0 100644 --- a/apps/builder/src/page/Deploy/style.ts +++ b/apps/builder/src/page/Deploy/style.ts @@ -20,6 +20,7 @@ export const deployLogoStyle = css` align-items: center; font-weight: 500; cursor: pointer; + background-color: ${globalColor(`--${illaPrefix}-white-01`)}; ` export const logoStyle = css` width: 25px; diff --git a/apps/builder/src/redux/currentApp/action/actionState.ts b/apps/builder/src/redux/currentApp/action/actionState.ts index 67494bae95..996b09384b 100644 --- a/apps/builder/src/redux/currentApp/action/actionState.ts +++ b/apps/builder/src/redux/currentApp/action/actionState.ts @@ -37,11 +37,8 @@ export type ActionType = | "elastic" | "postgresql" | "mariadb" - | "snowflake" | "tidb" - | "datadog" | "smtp" - | "zapier" | "s3" | "transformer" diff --git a/apps/builder/src/redux/currentApp/executionTree/executionSelector.ts b/apps/builder/src/redux/currentApp/executionTree/executionSelector.ts index 570966ecfd..1631961b48 100644 --- a/apps/builder/src/redux/currentApp/executionTree/executionSelector.ts +++ b/apps/builder/src/redux/currentApp/executionTree/executionSelector.ts @@ -149,3 +149,11 @@ export const getActionExecutionResultArray = createSelector( return actionExecutionResultArray }, ) + +export const getCurrentPageDisplayName = createSelector( + [getRootNodeExecutionResult], + (rootNode) => { + const { pageSortedKey, currentPageIndex } = rootNode + return pageSortedKey[currentPageIndex] + }, +) diff --git a/apps/builder/src/redux/resource/resourceState.ts b/apps/builder/src/redux/resource/resourceState.ts index 97b1bac2b6..7f488857d8 100644 --- a/apps/builder/src/redux/resource/resourceState.ts +++ b/apps/builder/src/redux/resource/resourceState.ts @@ -12,11 +12,8 @@ export type ResourceType = | "elastic" | "postgresql" | "mariadb" - | "snowflake" | "tidb" - | "datadog" | "smtp" - | "zapier" | "s3" export type ResourceContent = diff --git a/apps/builder/src/utils/actionResourceTransformer.ts b/apps/builder/src/utils/actionResourceTransformer.ts index 29fdcd820d..4fe46e9e50 100644 --- a/apps/builder/src/utils/actionResourceTransformer.ts +++ b/apps/builder/src/utils/actionResourceTransformer.ts @@ -1,5 +1,4 @@ import { ActionType } from "@/redux/currentApp/action/actionState" -import i18n from "@/i18n/config" import { ResourceType } from "@/redux/resource/resourceState" export function getActionTypeFromResourceType( @@ -27,16 +26,10 @@ export function getActionNameFromActionType(actionType: ActionType): string { return "PostgreSQL" case "mariadb": return "MariaDB" - case "snowflake": - return "Snowflake" case "tidb": return "TiDB" - case "datadog": - return "DataDog" case "smtp": return "SMTP" - case "zapier": - return "Zapier" case "s3": return "Amazon S3" case "transformer": @@ -70,16 +63,10 @@ export function getResourceNameFromResourceType( return "PostgreSQL" case "mariadb": return "MariaDB" - case "snowflake": - return "Snowflake" case "tidb": return "TiDB" - case "datadog": - return "DataDog" case "smtp": return "SMTP" - case "zapier": - return "Zapier" case "s3": return "Amazon S3" default: diff --git a/apps/builder/src/utils/evaluateDynamicString/codeSandbox.ts b/apps/builder/src/utils/evaluateDynamicString/codeSandbox.ts index ec024960bd..d8675c09aa 100644 --- a/apps/builder/src/utils/evaluateDynamicString/codeSandbox.ts +++ b/apps/builder/src/utils/evaluateDynamicString/codeSandbox.ts @@ -1,6 +1,13 @@ import { getScriptToEval } from "./scriptTemplate" import { createGlobalData } from "./utils" +const access_white_list: string[] = [] + +function runUsersCode(code: string) { + code = "with(shadow) {" + code + "}" + return new Function("shadow", code) +} + export function evalScript( script: string, dataTree: Record, @@ -16,10 +23,25 @@ export function evalScript( self[entity] = GlobalData[entity] } + const ctxProxy = new Proxy(GlobalData, { + has: (target, prop) => { + if (typeof prop === "symbol") { + return false + } + if (access_white_list.includes(prop)) { + return target.hasOwnProperty(prop) + } + if (!target.hasOwnProperty(prop)) { + throw new Error(`${prop} is not defined`) + } + return true + }, + }) + const userScript = getScriptToEval(script, isTriggerBased) try { - result = eval(userScript) + result = runUsersCode(userScript).call(ctxProxy, ctxProxy) } catch (error) { throw error } finally { diff --git a/apps/builder/src/widgetLibrary/BarProgressWidget/panelConfig.tsx b/apps/builder/src/widgetLibrary/BarProgressWidget/panelConfig.tsx index 72754366a1..d853e7a5ba 100644 --- a/apps/builder/src/widgetLibrary/BarProgressWidget/panelConfig.tsx +++ b/apps/builder/src/widgetLibrary/BarProgressWidget/panelConfig.tsx @@ -160,7 +160,7 @@ export const BAR_PROGRESS_PANEL_CONFIG: PanelConfig[] = [ { id: `${baseWidgetName}-strokeWidth`, labelName: i18n.t("editor.inspect.setter_label.stroke_width"), - setterType: "EDITABLE_INPUT_SETTER", + setterType: "EDITABLE_INPUT_WITH_MEASURE_SETTER", icon: , attrName: "strokeWidth", defaultValue: "4px", diff --git a/apps/builder/src/widgetLibrary/BasicContainer/BasicContainer.tsx b/apps/builder/src/widgetLibrary/BasicContainer/BasicContainer.tsx index 7904efddc0..876cede228 100644 --- a/apps/builder/src/widgetLibrary/BasicContainer/BasicContainer.tsx +++ b/apps/builder/src/widgetLibrary/BasicContainer/BasicContainer.tsx @@ -11,6 +11,7 @@ export const BasicContainer: FC = (props) => { minHeight, padding, safeRowNumber = 8, + addedRowNumber = 8, } = props const containerRef: MutableRefObject = useRef(null) @@ -29,6 +30,7 @@ export const BasicContainer: FC = (props) => { canResizeY={canResizeY} minHeight={minHeight} safeRowNumber={safeRowNumber} + addedRowNumber={addedRowNumber} /> ) diff --git a/apps/builder/src/widgetLibrary/BasicContainer/interface.ts b/apps/builder/src/widgetLibrary/BasicContainer/interface.ts index 8accb45caf..3432130f43 100644 --- a/apps/builder/src/widgetLibrary/BasicContainer/interface.ts +++ b/apps/builder/src/widgetLibrary/BasicContainer/interface.ts @@ -7,4 +7,5 @@ export interface BasicContainerProps { canResizeY?: boolean padding?: number safeRowNumber?: number + addedRowNumber: number } diff --git a/apps/builder/src/widgetLibrary/CircleProgressWidget/panelConfig.tsx b/apps/builder/src/widgetLibrary/CircleProgressWidget/panelConfig.tsx index ec4565a5b1..333f3c4650 100644 --- a/apps/builder/src/widgetLibrary/CircleProgressWidget/panelConfig.tsx +++ b/apps/builder/src/widgetLibrary/CircleProgressWidget/panelConfig.tsx @@ -118,7 +118,7 @@ export const CIRCLE_PROGRESS_PANEL_CONFIG: PanelConfig[] = [ { id: `${baseWidgetName}-strokeWidth`, labelName: i18n.t("editor.inspect.setter_label.stroke_width"), - setterType: "EDITABLE_INPUT_SETTER", + setterType: "EDITABLE_INPUT_WITH_MEASURE_SETTER", icon: , attrName: "strokeWidth", defaultValue: "4px", diff --git a/apps/builder/src/widgetLibrary/ContainerWidget/container.tsx b/apps/builder/src/widgetLibrary/ContainerWidget/container.tsx index 7a2e69468d..7470c3a1b7 100644 --- a/apps/builder/src/widgetLibrary/ContainerWidget/container.tsx +++ b/apps/builder/src/widgetLibrary/ContainerWidget/container.tsx @@ -3,6 +3,8 @@ import { ContainerProps } from "@/widgetLibrary/ContainerWidget/interface" import { TooltipWrapper } from "@/widgetLibrary/PublicSector/TooltipWrapper" import { BasicContainer } from "@/widgetLibrary/BasicContainer/BasicContainer" import { ContainerEmptyState } from "./emptyState" +import { containerWrapperStyle } from "./style" +import useMeasure from "react-use-measure" export const ContainerWidget: FC = (props) => { const { @@ -16,10 +18,9 @@ export const ContainerWidget: FC = (props) => { viewList, tooltipText, childrenNode, - h, - unitH, } = props const preCurrentViewIndex = useRef(currentIndex) + const [containerRef, containerBounds] = useMeasure() useEffect(() => { if (typeof preCurrentViewIndex.current !== "number") { @@ -37,13 +38,15 @@ export const ContainerWidget: FC = (props) => { return ( ) } return - }, [childrenNode, currentIndex, h, unitH]) + }, [childrenNode, containerBounds.height, currentIndex]) useEffect(() => { handleUpdateGlobalData?.(displayName, { @@ -148,7 +151,9 @@ export const ContainerWidget: FC = (props) => { return ( - {renderComponent} +
+ {renderComponent} +
) } diff --git a/apps/builder/src/widgetLibrary/ContainerWidget/panelConfig.tsx b/apps/builder/src/widgetLibrary/ContainerWidget/panelConfig.tsx index e78d0f5c8a..b9ab4996b3 100644 --- a/apps/builder/src/widgetLibrary/ContainerWidget/panelConfig.tsx +++ b/apps/builder/src/widgetLibrary/ContainerWidget/panelConfig.tsx @@ -122,7 +122,7 @@ export const CONTAINER_PANEL_CONFIG: PanelConfig[] = [ id: `${baseWidgetName}-style-radius`, labelName: i18n.t("editor.inspect.setter_label.radius"), attrName: "radius", - setterType: "EDITABLE_INPUT_SETTER", + setterType: "EDITABLE_INPUT_WITH_MEASURE_SETTER", icon: , defaultValue: "4px", }, @@ -131,8 +131,8 @@ export const CONTAINER_PANEL_CONFIG: PanelConfig[] = [ labelName: i18n.t("editor.inspect.setter_label.width"), attrName: "borderWidth", icon: , - setterType: "EDITABLE_INPUT_SETTER", - defaultValue: "4px", + setterType: "EDITABLE_INPUT_WITH_MEASURE_SETTER", + defaultValue: "1px", }, ], }, diff --git a/apps/builder/src/widgetLibrary/ContainerWidget/style.ts b/apps/builder/src/widgetLibrary/ContainerWidget/style.ts index 51ef8c9c19..24b83ca43a 100644 --- a/apps/builder/src/widgetLibrary/ContainerWidget/style.ts +++ b/apps/builder/src/widgetLibrary/ContainerWidget/style.ts @@ -21,3 +21,8 @@ export const emptyStateWrapperStyle = css` align-items: center; justify-content: center; ` + +export const containerWrapperStyle = css` + width: 100%; + height: 100%; +` diff --git a/apps/builder/src/widgetLibrary/DividerWidget/panelConfig.tsx b/apps/builder/src/widgetLibrary/DividerWidget/panelConfig.tsx index e12d667665..6b6059f52b 100644 --- a/apps/builder/src/widgetLibrary/DividerWidget/panelConfig.tsx +++ b/apps/builder/src/widgetLibrary/DividerWidget/panelConfig.tsx @@ -73,7 +73,7 @@ export const DIVIDER_PANEL_CONFIG: PanelConfig[] = [ { id: `${baseWidgetName}-style-text-size`, labelName: i18n.t("editor.inspect.setter_label.text_size"), - setterType: "EDITABLE_INPUT_SETTER", + setterType: "EDITABLE_INPUT_WITH_MEASURE_SETTER", attrName: "fs", icon: , defaultValue: "14px", diff --git a/apps/builder/src/widgetLibrary/FormWidget/form.tsx b/apps/builder/src/widgetLibrary/FormWidget/form.tsx index 991c750d25..2e84c572c8 100644 --- a/apps/builder/src/widgetLibrary/FormWidget/form.tsx +++ b/apps/builder/src/widgetLibrary/FormWidget/form.tsx @@ -380,6 +380,7 @@ export const FormWidget: FC = (props) => { canResizeY={false} minHeight={headerBounds.height - 16} padding={8} + addedRowNumber={0} /> ) }, [childrenNode, headerBounds.height]) @@ -392,6 +393,7 @@ export const FormWidget: FC = (props) => { minHeight={bodyBounds.height - 2 * 8} padding={8} safeRowNumber={1} + addedRowNumber={20} /> ) }, [bodyBounds.height, childrenNode]) @@ -404,6 +406,7 @@ export const FormWidget: FC = (props) => { canResizeY={false} minHeight={footerBounds.height - 2 * 8} padding={8} + addedRowNumber={0} /> ) }, [childrenNode, footerBounds.height]) diff --git a/apps/builder/src/widgetLibrary/FormWidget/panelConfig.tsx b/apps/builder/src/widgetLibrary/FormWidget/panelConfig.tsx index 6a9d28984e..b1ab399123 100644 --- a/apps/builder/src/widgetLibrary/FormWidget/panelConfig.tsx +++ b/apps/builder/src/widgetLibrary/FormWidget/panelConfig.tsx @@ -124,7 +124,7 @@ export const FORM_PANEL_CONFIG: PanelConfig[] = [ id: `${baseWidgetName}-style-radius`, labelName: i18n.t("editor.inspect.setter_label.radius"), attrName: "radius", - setterType: "EDITABLE_INPUT_SETTER", + setterType: "EDITABLE_INPUT_WITH_MEASURE_SETTER", icon: , defaultValue: "4px", }, @@ -133,7 +133,7 @@ export const FORM_PANEL_CONFIG: PanelConfig[] = [ labelName: i18n.t("editor.inspect.setter_label.width"), attrName: "borderWidth", icon: , - setterType: "EDITABLE_INPUT_SETTER", + setterType: "EDITABLE_INPUT_WITH_MEASURE_SETTER", defaultValue: "4px", }, ], diff --git a/apps/builder/src/widgetLibrary/ImageWidget/panelConfig.tsx b/apps/builder/src/widgetLibrary/ImageWidget/panelConfig.tsx index 20d0945aa7..6673603aa9 100644 --- a/apps/builder/src/widgetLibrary/ImageWidget/panelConfig.tsx +++ b/apps/builder/src/widgetLibrary/ImageWidget/panelConfig.tsx @@ -93,7 +93,7 @@ export const IMAGE_PANEL_CONFIG: PanelConfig[] = [ { id: `${baseWidgetName}-style-radius`, labelName: i18n.t("editor.inspect.setter_label.radius"), - setterType: "EDITABLE_INPUT_SETTER", + setterType: "EDITABLE_INPUT_WITH_MEASURE_SETTER", attrName: "radius", icon: , defaultValue: "0px", diff --git a/apps/builder/src/widgetLibrary/MenuWidget/widgetConfig.tsx b/apps/builder/src/widgetLibrary/MenuWidget/widgetConfig.tsx index 8e4087c3b1..5acf97cf22 100644 --- a/apps/builder/src/widgetLibrary/MenuWidget/widgetConfig.tsx +++ b/apps/builder/src/widgetLibrary/MenuWidget/widgetConfig.tsx @@ -1,5 +1,5 @@ import { ReactComponent as MenuWidgetIcon } from "@/assets/widgetCover/menu.svg" -import { WidgetConfig } from "@/widgetLibrary/interface" +import { RESIZE_DIRECTION, WidgetConfig } from "@/widgetLibrary/interface" import i18n from "@/i18n/config" const menuList = [ @@ -46,6 +46,7 @@ export const MENU_WIDGET_CONFIG: WidgetConfig = { icon: , keywords: ["Menu", "菜单"], sessionType: "PRESENTATION", + resizeDirection: RESIZE_DIRECTION.HORIZONTAL, defaults: { menuList, selectedKeys: ["1"], diff --git a/apps/builder/src/widgetLibrary/PublicSector/TransformWidgetWrapper/index.tsx b/apps/builder/src/widgetLibrary/PublicSector/TransformWidgetWrapper/index.tsx index 4c002c670e..7e47414269 100644 --- a/apps/builder/src/widgetLibrary/PublicSector/TransformWidgetWrapper/index.tsx +++ b/apps/builder/src/widgetLibrary/PublicSector/TransformWidgetWrapper/index.tsx @@ -293,12 +293,17 @@ export const TransformWidgetWrapper: FC = memo( shadow, } = realProps + const _radius = !isNaN(Number(radius)) ? radius + "px" : radius?.toString() + const _borderWidth = !isNaN(Number(borderWidth)) + ? borderWidth + "px" + : borderWidth?.toString() + return hidden ? null : (
void } -export interface TableWidgetProps extends WrappedTableProps, BaseWidgetProps {} +export interface TableWidgetProps extends WrappedTableProps, BaseWidgetProps { + dataSource: any[] + dataSourceJS: any[] + dataSourceMode: "select" | "dynamic" +} diff --git a/apps/builder/src/widgetLibrary/TableWidget/panelConfig.tsx b/apps/builder/src/widgetLibrary/TableWidget/panelConfig.tsx index ced281182b..c3b31ebf38 100644 --- a/apps/builder/src/widgetLibrary/TableWidget/panelConfig.tsx +++ b/apps/builder/src/widgetLibrary/TableWidget/panelConfig.tsx @@ -13,12 +13,11 @@ export const TABLE_PANEL_CONFIG: PanelConfig[] = [ groupName: i18n.t("editor.inspect.setter_group.data"), children: [ { - id: `${baseWidgetName}-basic-data`, - labelName: i18n.t("editor.inspect.setter_label.data"), - attrName: "data", - isSetterSingleRow: true, - setterType: "TABLE_DATA_INPUT_SETTER", - expectedType: VALIDATION_TYPES.ARRAY, + id: `${baseWidgetName}-data-source`, + labelName: i18n.t("editor.inspect.setter_label.data_source"), + useCustomLayout: true, + attrName: "dataSource", + setterType: "TABLE_DATASOURCE_SELECT_SETTER", }, { id: `${baseWidgetName}-basic-emptyState`, diff --git a/apps/builder/src/widgetLibrary/TableWidget/table.tsx b/apps/builder/src/widgetLibrary/TableWidget/table.tsx index e26b4046cd..d3dd0b76cb 100644 --- a/apps/builder/src/widgetLibrary/TableWidget/table.tsx +++ b/apps/builder/src/widgetLibrary/TableWidget/table.tsx @@ -27,6 +27,13 @@ export const WrappedTable = forwardRef( handleOnColumnFiltersChange, } = props + const formatData = useMemo(() => { + if (Array.isArray(data)) { + return data + } + return [] + }, [data]) + return ( ( pinedHeader w="100%" h="100%" - data={data} + data={formatData} columns={columns} filter={filter} loading={loading} @@ -64,6 +71,9 @@ export const TableWidget: FC = (props) => { download, overFlow, pageSize, + dataSource, + dataSourceJS, + dataSourceMode, displayName, defaultSortKey, defaultSortOrder, @@ -104,10 +114,16 @@ export const TableWidget: FC = (props) => { return res }, [columns]) + const realDataSourceArray = useMemo(() => { + if (dataSourceMode === "dynamic") { + return dataSourceJS ? dataSourceJS : [] + } + return dataSource ? dataSource : [] + }, [dataSource, dataSourceJS, dataSourceMode]) + useEffect(() => { handleUpdateGlobalData(displayName, { defaultSort, - data, columns, }) return () => { @@ -116,7 +132,6 @@ export const TableWidget: FC = (props) => { }, [ displayName, defaultSort, - data, columns, handleUpdateGlobalData, handleUpdateDsl, @@ -125,7 +140,7 @@ export const TableWidget: FC = (props) => { return ( , defaultValue: "14px", diff --git a/apps/builder/src/widgetLibrary/TextWidget/tests/text.test.tsx b/apps/builder/src/widgetLibrary/TextWidget/tests/text.test.tsx index 03f3fd4dc0..db6152e7da 100644 --- a/apps/builder/src/widgetLibrary/TextWidget/tests/text.test.tsx +++ b/apps/builder/src/widgetLibrary/TextWidget/tests/text.test.tsx @@ -17,7 +17,7 @@ test("Text renders with textColor", () => { test("Text renders with markdown", () => { render( , @@ -26,7 +26,7 @@ test("Text renders with markdown", () => { "font-weight": "bold", }) expect( - screen.getByText("https://github.com/illa-family/illa-builder"), + screen.getByText("https://github.com/illacloud/illa-builder"), ).toHaveStyle({ color: "#833fdf", }) diff --git a/illa-design b/illa-design index ce9c4940a5..08a5dc722c 160000 --- a/illa-design +++ b/illa-design @@ -1 +1 @@ -Subproject commit ce9c4940a572325d63712df4940bc51be2797c07 +Subproject commit 08a5dc722c8027c70626807745754f966c7f8260 diff --git a/package.json b/package.json index 69f09f0a5f..40ae8d8b6f 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "illa", "description": "Help developers build business tools more efficiently.", - "repository": "git@github.com:illa-family", + "repository": "git@github.com:illacloud", "private": true, - "author": "illa Family", + "author": "illa Cloud", "license": "Apache-2.0", "version": "0.0.0", "scripts": {