1
1
import { CompInfo , EditorContext } from "comps/editorState" ;
2
2
import {
3
3
BaseSection ,
4
- Collapse ,
5
4
CollapseLabel as Label ,
6
5
CollapseTitle as Title ,
7
6
FoldedIcon ,
8
7
LeftCommon ,
9
8
ScrollBar ,
10
- Tooltip ,
11
9
UnfoldIcon ,
12
- LeftLayersIcon ,
13
- GridIcon ,
14
10
LeftShow ,
15
- LeftHide ,
16
- LeftLock ,
17
- LeftUnlock ,
18
11
} from "lowcoder-design" ;
19
- import React , { ReactNode , useCallback , useContext , useMemo , useState , useEffect } from "react" ;
12
+ import React , { useCallback , useContext , useMemo , useState , useEffect , useRef } from "react" ;
20
13
import _ , { get } from "lodash" ;
21
14
import styled from "styled-components" ;
22
15
import { leftCompListClassName } from "pages/tutorials/tutorialsConstant" ;
23
16
import UIComp from "comps/comps/uiComp" ;
24
- import { getParentNodeKeysByKey , getTreeNodeByKey , safeJSONStringify } from "util/objectUtils" ;
25
- import { BackgroundColor , TopHeaderHeight } from "constants/style" ;
17
+ import { getTreeNodeByKey } from "util/objectUtils" ;
18
+ import { TopHeaderHeight } from "constants/style" ;
26
19
import { trans } from "i18n" ;
27
20
import { CompTree } from "comps/comps/containerBase" ;
28
21
import { CompStateIcon } from "./editorConstants" ;
@@ -32,7 +25,6 @@ import { isAggregationApp } from "util/appUtils";
32
25
import cloneDeep from 'lodash/cloneDeep' ;
33
26
import { useDispatch } from "react-redux" ;
34
27
import { useApplicationId } from "util/hooks" ;
35
- import { updateApplication } from "redux/reduxActions/applicationActions" ;
36
28
import { Button , Divider , Dropdown , Flex , Input , Menu , MenuProps , Space } from "antd" ;
37
29
import { Switch } from "antd" ;
38
30
import {
@@ -42,6 +34,7 @@ import {
42
34
import { check , withViewFn } from "@lowcoder-ee/index.sdk" ;
43
35
import { DownOutlined } from "@ant-design/icons" ;
44
36
import { ItemType } from "antd/es/menu/hooks/useItems" ;
37
+ import ColorPicker , { configChangeParams } from "components/ColorPicker" ;
45
38
46
39
47
40
export type DisabledCollisionStatus = "true" | "false" ; // "true" means collision is not enabled - Layering works, "false" means collision is enabled - Layering does not work
@@ -246,10 +239,47 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
246
239
247
240
const [ checkedKeys , setCheckedKeys ] = useState < string [ ] > ( [ ] ) ;
248
241
const [ actionValue , setActionValue ] = useState < string > ( "" ) ;
242
+ const [ selectedActionKey , setSelectedActionKey ] = useState < string | null > ( null ) ;
243
+ const [ placeholderText , setPlaceholderText ] = useState < string > ( "" ) ;
244
+ const [ color , setColor ] = useState < string > ( "" ) ;
249
245
250
- const handleActionValueChange = ( e : any ) => {
246
+ const handleColorChange = ( color : string | undefined , actionType : string ) => {
247
+ const newColor = color || '#ffffff' ;
248
+
249
+ for ( let key of getCheckedKeys ( ) ) {
250
+ const node = getTreeNodeByKey ( componentTreeData , key ) ;
251
+ const comp = editorState . getUICompByName ( node . title ) ;
252
+ if ( comp ) {
253
+ const { children } = comp . children . comp ;
254
+ const compType = comp . children . compType . getView ( ) ;
255
+ const types = actionType . split ( '.' ) ;
256
+ if ( types . length === 1 ) { // e.g hidden, disabled
257
+ children [ types [ 0 ] ] ?. dispatchChangeValueAction ( color ) ;
258
+ }
259
+ else if ( types . length === 2 ) { // nested object e.g. style.background
260
+ console . log ( children [ types [ 0 ] ] ) ;
261
+ if ( ! children [ types [ 0 ] ] ) {
262
+ if ( children [ compType ] . children [ types [ 0 ] ] ?. children [ types [ 1 ] ] ) {
263
+ children [ compType ] . children [ types [ 0 ] ] . children [ types [ 1 ] ] ?. dispatchChangeValueAction ( color ) ;
264
+ }
265
+ }
266
+ else {
267
+ if ( children [ types [ 0 ] ] . children [ types [ 1 ] ] ) {
268
+ children [ types [ 0 ] ] . children [ types [ 1 ] ] ?. dispatchChangeValueAction ( color ) ;
269
+ }
270
+ else {
271
+ children [ types [ 0 ] ] [ types [ 1 ] ] ?. dispatchChangeValueAction ( color ) ;
272
+ }
273
+ }
274
+ }
275
+ }
276
+ }
277
+ } ;
278
+
279
+
280
+ /* const handleActionValueChange = (e: any) => {
251
281
setActionValue(e.target.value);
252
- }
282
+ } */
253
283
254
284
// sync selected components with checked keys
255
285
useEffect ( ( ) => {
@@ -267,6 +297,12 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
267
297
setCheckedKeys ( selectedComponentsOnCanvas ) ;
268
298
} , [ editorState ] ) ;
269
299
300
+ // make sure to handle the selectedActionKey for the changed input fields
301
+ useEffect ( ( ) => {
302
+ setActionValue ( '' ) ;
303
+ setColor ( '#ffffff' ) ;
304
+ } , [ selectedActionKey , placeholderText ] ) ;
305
+
270
306
const onCheck = ( checkedKeys : any , e : any ) => {
271
307
setCheckedKeys ( checkedKeys ) ;
272
308
const checkedComponents = new Set < string > ( ) ;
@@ -290,29 +326,36 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
290
326
const node = getTreeNodeByKey ( componentTreeData , key ) ;
291
327
const comp = editorState . getUICompByName ( node . title ) ;
292
328
if ( comp ) {
293
- const { children } = comp . children . comp
329
+ const { children } = comp . children . comp ;
330
+ const compType = comp . children . compType . getView ( ) ;
294
331
const types = actionType . split ( '.' ) ;
295
-
296
332
if ( types . length === 1 ) { // e.g hidden, disabled
297
333
children [ types [ 0 ] ] ?. dispatchChangeValueAction ( value ) ;
298
334
}
299
335
else if ( types . length === 2 ) { // nested object e.g. style.background
300
- children [ types [ 0 ] ] [ types [ 1 ] ] ?. dispatchChangeValueAction ( value ) ;
336
+ console . log ( children [ types [ 0 ] ] ) ;
337
+ if ( ! children [ types [ 0 ] ] ) {
338
+ if ( children [ compType ] . children [ types [ 0 ] ] ?. children [ types [ 1 ] ] ) {
339
+ children [ compType ] . children [ types [ 0 ] ] . children [ types [ 1 ] ] ?. dispatchChangeValueAction ( value ) ;
340
+ }
341
+ }
342
+ else {
343
+ if ( children [ types [ 0 ] ] . children [ types [ 1 ] ] ) {
344
+ children [ types [ 0 ] ] . children [ types [ 1 ] ] ?. dispatchChangeValueAction ( value ) ;
345
+ }
346
+ else {
347
+ children [ types [ 0 ] ] [ types [ 1 ] ] ?. dispatchChangeValueAction ( value ) ;
348
+ }
349
+ }
301
350
}
302
351
}
303
352
}
304
353
} , [ getActionValue , getCheckedKeys ] ) ;
305
354
306
- /*
307
-
308
- dispatch(
309
- multiChangeAction({
310
- width: changeValueAction(width, true),
311
- autoWidth: changeValueAction("fixed", true),
312
- })
313
- );
314
-
315
- */
355
+ const handleActionSelection = useCallback ( ( key : string ) => {
356
+ setSelectedActionKey ( key ) ;
357
+ setPlaceholderText ( getPlaceholderText ( key ) ) ;
358
+ } , [ handleComponentsActions ] ) ;
316
359
317
360
const layerActions : ItemType [ ] = [
318
361
{
@@ -324,15 +367,63 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
324
367
key : 'disable' ,
325
368
} ,
326
369
{
327
- label : 'Component Background' ,
328
- key : 'style.background' ,
370
+ label : 'Margin' ,
371
+ key : 'style.margin' ,
372
+ } ,
373
+ {
374
+ label : 'Padding' ,
375
+ key : 'style.padding' ,
376
+ } ,
377
+ {
378
+ label : 'Border Radius' ,
379
+ key : 'style.radius' ,
329
380
} ,
330
381
{
331
- label : 'Unlock ' ,
332
- key : '4 ' ,
382
+ label : 'Border Width ' ,
383
+ key : 'style.borderWidth ' ,
333
384
} ,
385
+ {
386
+ label : 'Font Size' ,
387
+ key : 'style.textSize' ,
388
+ } ,
389
+ {
390
+ label : 'Font Weight' ,
391
+ key : 'style.textWeight' ,
392
+ } ,
393
+ {
394
+ label : 'Font Family' ,
395
+ key : 'style.fontFamily' ,
396
+ }
334
397
] ;
335
398
399
+
400
+ const getPlaceholderText = ( key : string ) => {
401
+ switch ( key ) {
402
+ case 'hidden' :
403
+ case 'disable' :
404
+ return 'true | false' ;
405
+ case 'style.background' :
406
+ case 'style.text' :
407
+ case 'style.border' :
408
+ return 'e.g., #ffffff' ; // Indicate example format
409
+ case 'style.radius' :
410
+ return 'e.g., 4px' ; // Indicate example format
411
+ case 'style.borderWidth' :
412
+ return 'e.g., 2px' ; // Indicate example format
413
+ case 'style.textSize' :
414
+ return 'e.g., 16px' ; // Indicate example format
415
+ case 'style.textWeight' :
416
+ return 'bold | 900' ;
417
+ case 'style.fontFamily' :
418
+ return 'Arial, sans-serif' ;
419
+ case 'style.margin' :
420
+ case 'style.padding' :
421
+ return 'e.g., 4px 8px 16px 32px' ; // Indicate example format
422
+ default :
423
+ return 'Action Value' ;
424
+ }
425
+ } ;
426
+
336
427
const getTreeUI = ( ) => {
337
428
// here the components get sorted by name
338
429
// TODO: sort by category
@@ -367,7 +458,7 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
367
458
onDrop = { ( info ) => handleDrop ( info ) }
368
459
treeData = { componentTreeData }
369
460
icon = { ( props : any ) => props . type && (
370
- < div style = { { margin : '3px 0 0 -3px ' } } > { /* Adjust the margin as needed */ }
461
+ < div style = { { margin : '3px 4px 0 -4px ' } } > { /* Adjust the margin as needed */ }
371
462
{ CompStateIcon [ props . type as UICompType ] || < LeftCommon /> }
372
463
</ div >
373
464
) }
@@ -379,14 +470,11 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
379
470
380
471
< div style = { { margin :"10px 0px" } } >
381
472
< Flex gap = "small" vertical >
382
- { trans ( "leftPanel.selectedComponents" ) } < br />
383
- { trans ( "leftPanel.displayComponents" ) }
384
- < Input placeholder = "Action Value" onChange = { handleActionValueChange } />
385
473
< CustomDropdown
386
474
dropdownRender = { ( ) => (
387
475
< Menu
388
476
items = { layerActions }
389
- onClick = { ( { key} ) => handleComponentsActions ( key ) }
477
+ onClick = { ( { key} ) => handleActionSelection ( key ) }
390
478
/>
391
479
) }
392
480
>
@@ -397,6 +485,37 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
397
485
</ Space >
398
486
</ Button >
399
487
</ CustomDropdown >
488
+ < Input
489
+ value = { actionValue } // Use actionValue for the default case as well
490
+ onChange = { ( e ) => setActionValue ( e . target . value ) } // Handle changes to update actionValue
491
+ placeholder = { placeholderText }
492
+ />
493
+ < Button
494
+ type = "primary"
495
+ disabled = { ! selectedActionKey }
496
+ onClick = { ( ) => selectedActionKey && handleComponentsActions ( selectedActionKey ) }
497
+ >
498
+ Apply Action
499
+ </ Button >
500
+ < br />
501
+ < ColorPicker
502
+ colorKey = { "background" }
503
+ name = { trans ( "componentDoc.styleBackgroundColor" ) }
504
+ color = { "#ffffff" }
505
+ configChange = { ( params ) => handleColorChange ( params . color , "style.background" ) }
506
+ />
507
+ < ColorPicker
508
+ colorKey = { "border" }
509
+ name = { trans ( "componentDoc.styleBorderColor" ) }
510
+ color = { "#ffffff" }
511
+ configChange = { ( params ) => handleColorChange ( params . color , "style.border" ) }
512
+ />
513
+ < ColorPicker
514
+ colorKey = { "text" }
515
+ name = { trans ( "style.textColor" ) }
516
+ color = { "#ffffff" }
517
+ configChange = { ( params ) => handleColorChange ( params . color , "style.text" ) }
518
+ />
400
519
</ Flex >
401
520
</ div >
402
521
</ div >
0 commit comments