@@ -12,12 +12,21 @@ import { default as Space } from "antd/es/space";
1212import { default as Flex } from "antd/es/flex" ;
1313import type { InputRef } from 'antd' ;
1414import { default as DownOutlined } from "@ant-design/icons/DownOutlined" ;
15- import { BaseSection } from "lowcoder-design" ;
15+ import { BaseSection , Dropdown } from "lowcoder-design" ;
1616import { EditorContext } from "comps/editorState" ;
1717import { message } from "antd" ;
1818import { CustomDropdown } from "./styled" ;
19- import { generateComponentActionItems , getComponentCategories } from "./utils" ;
19+ import {
20+ generateComponentActionItems ,
21+ getComponentCategories ,
22+ getEditorComponentInfo ,
23+ getLayoutItemsOrder
24+ } from "./utils" ;
2025import { actionRegistry , getAllActionItems } from "./actionConfigs" ;
26+ import { getThemeList } from "@lowcoder-ee/redux/selectors/commonSettingSelectors" ;
27+ import { useSelector } from "react-redux" ;
28+ import { ActionOptions } from "comps/controls/actionSelector/actionSelectorControl" ;
29+ import { eventToShortcut , readableShortcut } from "util/keyUtils" ;
2130
2231export function ActionInputSection ( ) {
2332 const [ actionValue , setActionValue ] = useState < string > ( "" ) ;
@@ -31,8 +40,22 @@ export function ActionInputSection() {
3140 const [ showStylingInput , setShowStylingInput ] = useState < boolean > ( false ) ;
3241 const [ selectedEditorComponent , setSelectedEditorComponent ] = useState < string | null > ( null ) ;
3342 const [ validationError , setValidationError ] = useState < string | null > ( null ) ;
43+ const [ showDynamicLayoutDropdown , setShowDynamicLayoutDropdown ] = useState < boolean > ( false ) ;
44+ const [ selectedDynamicLayoutIndex , setSelectedDynamicLayoutIndex ] = useState < string | null > ( null ) ;
45+ const [ showThemeDropdown , setShowThemeDropdown ] = useState < boolean > ( false ) ;
46+ const [ selectedTheme , setSelectedTheme ] = useState < string | null > ( null ) ;
47+ const [ showCustomShortcutsActionDropdown , setShowCustomShortcutsActionDropdown ] = useState < boolean > ( false ) ;
48+ const [ selectedCustomShortcutAction , setSelectedCustomShortcutAction ] = useState < string | null > ( null ) ;
3449 const inputRef = useRef < InputRef > ( null ) ;
3550 const editorState = useContext ( EditorContext ) ;
51+ const themeList = useSelector ( getThemeList ) || [ ] ;
52+
53+ const THEME_OPTIONS = useMemo ( ( ) => {
54+ return themeList . map ( ( theme ) => ( {
55+ label : theme . name ,
56+ value : theme . id + "" ,
57+ } ) ) ;
58+ } , [ themeList ] ) ;
3659
3760 const categories = useMemo ( ( ) => {
3861 return getComponentCategories ( ) ;
@@ -56,6 +79,25 @@ export function ActionInputSection() {
5679 } ) ) ;
5780 } , [ editorState ] ) ;
5881
82+ const simpleLayoutItems = useMemo ( ( ) => {
83+ if ( ! editorComponents ) return [ ] ;
84+
85+ const editorComponentInfo = getEditorComponentInfo ( editorState ) ;
86+ if ( ! editorComponentInfo ) return [ ] ;
87+
88+ const currentLayout = editorComponentInfo . currentLayout ;
89+ const items = editorComponentInfo . items ;
90+
91+ return Object . keys ( currentLayout ) . map ( ( key ) => {
92+ const item = items ? items [ key ] : null ;
93+ const componentName = item ? ( item as any ) . children . name . getView ( ) : key ;
94+ return {
95+ label : componentName ,
96+ key : componentName
97+ } ;
98+ } ) ;
99+ } , [ editorState ] ) ;
100+
59101 const currentAction = useMemo ( ( ) => {
60102 return selectedActionKey ? actionRegistry . get ( selectedActionKey ) : null ;
61103 } , [ selectedActionKey ] ) ;
@@ -81,8 +123,14 @@ export function ActionInputSection() {
81123 setSelectedEditorComponent ( null ) ;
82124 setIsNestedComponent ( false ) ;
83125 setSelectedNestComponent ( null ) ;
126+ setShowDynamicLayoutDropdown ( false ) ;
84127 setActionValue ( "" ) ;
85-
128+ setSelectedDynamicLayoutIndex ( null ) ;
129+ setShowThemeDropdown ( false ) ;
130+ setSelectedTheme ( null ) ;
131+ setShowCustomShortcutsActionDropdown ( false ) ;
132+ setSelectedCustomShortcutAction ( null ) ;
133+
86134 if ( action . requiresComponentSelection ) {
87135 setShowComponentDropdown ( true ) ;
88136 setPlaceholderText ( "Select a component to add" ) ;
@@ -103,6 +151,15 @@ export function ActionInputSection() {
103151 if ( action . isNested ) {
104152 setIsNestedComponent ( true ) ;
105153 }
154+ if ( action . dynamicLayout ) {
155+ setShowDynamicLayoutDropdown ( true ) ;
156+ }
157+ if ( action . isTheme ) {
158+ setShowThemeDropdown ( true ) ;
159+ }
160+ if ( action . isCustomShortcuts ) {
161+ setShowCustomShortcutsActionDropdown ( true ) ;
162+ }
106163 } , [ ] ) ;
107164
108165 const handleComponentSelection = useCallback ( ( key : string ) => {
@@ -168,13 +225,26 @@ export function ActionInputSection() {
168225 return ;
169226 }
170227
228+ if ( currentAction . isTheme && ! selectedTheme ) {
229+ message . error ( 'Please select a theme' ) ;
230+ return ;
231+ }
232+
233+ if ( currentAction . isCustomShortcuts && ! selectedCustomShortcutAction ) {
234+ message . error ( 'Please select a custom shortcut action' ) ;
235+ return ;
236+ }
237+
171238 try {
172239 await currentAction . execute ( {
173240 actionKey : selectedActionKey ,
174241 actionValue,
175242 selectedComponent,
176243 selectedEditorComponent,
177244 selectedNestComponent,
245+ selectedDynamicLayoutIndex,
246+ selectedTheme,
247+ selectedCustomShortcutAction,
178248 editorState
179249 } ) ;
180250
@@ -189,7 +259,12 @@ export function ActionInputSection() {
189259 setValidationError ( null ) ;
190260 setIsNestedComponent ( false ) ;
191261 setSelectedNestComponent ( null ) ;
192-
262+ setShowDynamicLayoutDropdown ( false ) ;
263+ setSelectedDynamicLayoutIndex ( null ) ;
264+ setShowThemeDropdown ( false ) ;
265+ setSelectedTheme ( null ) ;
266+ setShowCustomShortcutsActionDropdown ( false ) ;
267+ setSelectedCustomShortcutAction ( null ) ;
193268 } catch ( error ) {
194269 console . error ( 'Error executing action:' , error ) ;
195270 message . error ( 'Failed to execute action. Please try again.' ) ;
@@ -200,6 +275,9 @@ export function ActionInputSection() {
200275 selectedComponent ,
201276 selectedEditorComponent ,
202277 selectedNestComponent ,
278+ selectedDynamicLayoutIndex ,
279+ selectedTheme ,
280+ selectedCustomShortcutAction ,
203281 editorState ,
204282 currentAction ,
205283 validateInput
@@ -213,7 +291,16 @@ export function ActionInputSection() {
213291 if ( currentAction . requiresInput && ! actionValue . trim ( ) ) return true ;
214292
215293 return false ;
216- } , [ selectedActionKey , currentAction , selectedComponent , selectedEditorComponent , actionValue ] ) ;
294+ } , [
295+ selectedActionKey ,
296+ currentAction ,
297+ selectedComponent ,
298+ selectedEditorComponent ,
299+ actionValue ,
300+ selectedCustomShortcutAction ,
301+ selectedTheme ,
302+ selectedNestComponent
303+ ] ) ;
217304
218305 const shouldShowInput = useMemo ( ( ) => {
219306 if ( ! currentAction ) return false ;
@@ -299,7 +386,7 @@ export function ActionInputSection() {
299386 popupRender = { ( ) => (
300387 < Menu
301388 items = { editorComponents }
302- onClick = { ( { key } ) => {
389+ onClick = { ( { key} ) => {
303390 handleEditorComponentSelection ( key ) ;
304391 } }
305392 />
@@ -314,24 +401,111 @@ export function ActionInputSection() {
314401 </ CustomDropdown >
315402 ) }
316403
317- { shouldShowInput && (
318- showStylingInput ? (
319- < Input . TextArea
320- ref = { inputRef }
321- value = { actionValue }
322- onChange = { handleInputChange }
323- placeholder = { placeholderText }
324- status = { validationError ? 'error' : undefined }
325- autoSize = { { minRows : 1 } }
404+ { showDynamicLayoutDropdown && (
405+ < CustomDropdown
406+ overlayStyle = { {
407+ maxHeight : '400px' ,
408+ overflow : 'auto' ,
409+ zIndex : 9999
410+ } }
411+ popupRender = { ( ) => (
412+ < Menu
413+ items = { simpleLayoutItems }
414+ onClick = { ( { key} ) => {
415+ handleEditorComponentSelection ( key ) ;
416+ } }
326417 />
327- ) : (
418+ ) }
419+ >
420+ < Button size = { "small" } >
421+ < Space >
422+ { selectedEditorComponent ? selectedEditorComponent : 'Layout' }
423+ < DownOutlined />
424+ </ Space >
425+ </ Button >
426+ </ CustomDropdown >
427+ ) }
428+
429+ { showDynamicLayoutDropdown && (
430+ < Dropdown
431+ options = { getLayoutItemsOrder ( simpleLayoutItems ) }
432+ onChange = { ( value ) => {
433+ setSelectedDynamicLayoutIndex ( value ) ;
434+ } }
435+ >
436+ < Button size = { "small" } >
437+ < Space >
438+ { selectedEditorComponent ? selectedEditorComponent : 'Layout' }
439+ < DownOutlined />
440+ </ Space >
441+ </ Button >
442+ </ Dropdown >
443+ ) }
444+
445+ { showThemeDropdown && (
446+ < Dropdown
447+ options = { THEME_OPTIONS }
448+ onChange = { ( value ) => {
449+ setSelectedTheme ( value ) ;
450+ } }
451+ >
452+ < Button size = { "small" } >
453+ < Space >
454+ { selectedTheme ? selectedTheme : 'Select Theme' }
455+ </ Space >
456+ </ Button >
457+ </ Dropdown >
458+ ) }
459+
460+ { showCustomShortcutsActionDropdown && (
461+ < Dropdown
462+ options = { ActionOptions }
463+ onChange = { ( value ) => {
464+ setSelectedCustomShortcutAction ( value ) ;
465+ } }
466+ >
467+ < Button size = { "small" } >
468+ < Space >
469+ { selectedCustomShortcutAction ? selectedCustomShortcutAction : 'Select Action' }
470+ </ Space >
471+ </ Button >
472+ </ Dropdown >
473+ ) }
474+
475+ { shouldShowInput && (
476+ currentAction ?. isCustomShortcuts ? (
328477 < Input
329478 ref = { inputRef }
330- value = { actionValue }
331- onChange = { handleInputChange }
479+ value = { readableShortcut ( actionValue ) }
332480 placeholder = { placeholderText }
333481 status = { validationError ? 'error' : undefined }
482+ onKeyDownCapture = { ( e ) => {
483+ setActionValue ( eventToShortcut ( e ) ) ;
484+ e . preventDefault ( ) ;
485+ e . stopPropagation ( ) ;
486+ } }
487+ onChange = { ( ) => { } }
488+ readOnly
334489 />
490+ ) : (
491+ showStylingInput ? (
492+ < Input . TextArea
493+ ref = { inputRef }
494+ value = { actionValue }
495+ onChange = { handleInputChange }
496+ placeholder = { placeholderText }
497+ status = { validationError ? 'error' : undefined }
498+ autoSize = { { minRows : 1 } }
499+ />
500+ ) : (
501+ < Input
502+ ref = { inputRef }
503+ value = { actionValue }
504+ onChange = { handleInputChange }
505+ placeholder = { placeholderText }
506+ status = { validationError ? 'error' : undefined }
507+ />
508+ )
335509 )
336510 ) }
337511
0 commit comments