Skip to content

Commit 27079d9

Browse files
component sorting and z-index based on sorting position
1 parent 875bdfd commit 27079d9

File tree

8 files changed

+92
-11
lines changed

8 files changed

+92
-11
lines changed

client/packages/lowcoder/src/comps/comps/containerComp/containerView.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,14 +230,27 @@ const onDrop = (
230230
};
231231
const key = genRandomKey();
232232
const layoutItem = Object.values(items)[0];
233+
// calculate postion of newly added comp
234+
// should have last position in the comps list
235+
let itemPos = 0;
236+
if (!Object.keys(layout).length) {
237+
itemPos = 0;
238+
} else {
239+
itemPos = Math.max(...Object.values(layout).map(l => l.pos || 0)) + 1;
240+
}
233241
// log.debug("layout: onDrop. widgetValue: ", widgetValue, " layoutItem: ", layoutItem);
234242
dispatch(
235243
wrapActionExtraInfo(
236244
multiChangeAction({
237245
layout: changeValueAction(
238246
{
239247
...layout,
240-
[key]: { ...layoutItem, i: key, placeholder: undefined },
248+
[key]: {
249+
...layoutItem,
250+
i: key,
251+
placeholder: undefined,
252+
pos: itemPos,
253+
},
241254
},
242255
true
243256
),
@@ -463,6 +476,7 @@ export function InnerGrid(props: ViewPropsWithSelect) {
463476
layout={props.layout}
464477
extraLayout={extraLayout}
465478
onDropDragOver={(e) => {
479+
466480
const compType = draggingUtils.getData<UICompType>("compType");
467481
const compLayout = draggingUtils.getData<UICompLayoutInfo>("compLayout");
468482
if (compType) {

client/packages/lowcoder/src/comps/comps/textComp.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const getStyle = (style: TextStyleType) => {
3737
margin: ${style.margin} !important;
3838
padding: ${style.padding};
3939
width: ${widthCalculator(style.margin)};
40-
height: ${heightCalculator(style.margin)};
40+
// height: ${heightCalculator(style.margin)};
4141
h1 {
4242
line-height: 1.5;
4343
}

client/packages/lowcoder/src/constants/Layers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export const Layers = {
3030
// comp selection wrapper
3131
dragSelectBox: 399,
3232
//
33-
compHover: 300,
33+
compHover: 100,
3434
//
3535
compSelected: 200,
3636
//

client/packages/lowcoder/src/layout/gridItem.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type GridItemCallback<Data extends GridDragEvent | GridResizeEvent> = (
3434
arg3: Data
3535
) => void;
3636
export type GridItemProps = {
37+
zIndex: number;
3738
children: ReactElement;
3839
cols: number;
3940
containerWidth: number;
@@ -81,7 +82,8 @@ export type GridItemProps = {
8182

8283
export const IsDroppable = React.createContext(true);
8384

84-
const ResizableStyled = styled(Resizable)`
85+
const ResizableStyled = styled(Resizable)<{ $zIndex: number }>`
86+
z-index: ${props => props.$zIndex};
8587
&:hover {
8688
z-index: 1;
8789
}
@@ -151,7 +153,8 @@ export function GridItem(props: GridItemProps) {
151153
const mixinResizable = (
152154
child: ReactElement,
153155
position: Position,
154-
isResizable: boolean
156+
isResizable: boolean,
157+
zIndex: number,
155158
): ReactElement => {
156159
const { cols, x, minW, minH, maxW, maxH, resizeHandles } = props;
157160
// This is the max possible width - doesn't go to infinity because of the width of the window
@@ -179,6 +182,7 @@ export function GridItem(props: GridItemProps) {
179182
onResizeStop={onResizeStop}
180183
resizeHandles={resizeHandles}
181184
handle={Handle}
185+
$zIndex={zIndex}
182186
>
183187
{child}
184188
</ResizableStyled>
@@ -397,7 +401,7 @@ export function GridItem(props: GridItemProps) {
397401
return { width, height, top, left };
398402
}, [dragging, position.height, position.left, position.top, position.width, resizing]);
399403

400-
const { isDraggable, isResizable, layoutHide, children, isSelected, clickItem } = props;
404+
const { isDraggable, isResizable, layoutHide, children, isSelected, clickItem, zIndex } = props;
401405
const pos = calcPosition();
402406
const render = () => {
403407
let child = React.Children.only(children);
@@ -433,7 +437,7 @@ export function GridItem(props: GridItemProps) {
433437
},
434438
});
435439
// Resizable support. This is usually on but the user can toggle it off.
436-
newChild = mixinResizable(newChild, pos, isResizable);
440+
newChild = mixinResizable(newChild, pos, isResizable, zIndex);
437441
// Draggable support. This is always on, except for with placeholders.
438442
newChild = mixinDraggable(newChild, isDraggable);
439443
return newChild;

client/packages/lowcoder/src/layout/gridLayout.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
393393
};
394394

395395
processGridItem(
396+
zIndex: number,
396397
item: LayoutItem,
397398
childrenMap: _.Dictionary<React.ReactElement>
398399
): React.ReactElement | undefined {
@@ -464,6 +465,7 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
464465
top: showName?.top ?? 0,
465466
bottom: (showName?.bottom ?? 0) + (this.ref.current?.scrollHeight ?? 0),
466467
}}
468+
zIndex={zIndex}
467469
>
468470
{child}
469471
</GridItem>
@@ -863,7 +865,6 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
863865
// move the logic to onDragEnd function when dragging from the canvas
864866
return;
865867
}
866-
867868
let layout = this.getUILayout();
868869
const ops = layoutOpUtils.push(this.state.ops, deleteItemOp(droppingKey));
869870
const items = _.pick(layout, droppingKey);
@@ -1001,6 +1002,7 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
10011002
this.ref = this.props.innerRef ?? this.innerRef;
10021003

10031004
// log.debug("GridLayout render. layout: ", layout, " oriLayout: ", this.state.layout, " extraLayout: ", this.props.extraLayout);
1005+
const layouts = Object.values(layout);
10041006
return (
10051007
<LayoutContainer
10061008
ref={this.ref}
@@ -1026,7 +1028,13 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
10261028
<div style={contentStyle}>
10271029
{showGridLines && this.gridLines()}
10281030
{mounted &&
1029-
Object.values(layout).map((item) => this.processGridItem(item, childrenMap))}
1031+
layouts.map((item) => {
1032+
const zIndex = item.pos !== undefined
1033+
? layouts.length - item.pos
1034+
: 1;
1035+
return this.processGridItem(zIndex, item, childrenMap)
1036+
})
1037+
}
10301038
{this.hintPlaceholder()}
10311039
</div>
10321040
</ReactResizeDetector>

client/packages/lowcoder/src/layout/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export type LayoutItem = {
1414
x: number;
1515
y: number;
1616
i: string;
17+
pos?: number;
1718
minW?: number;
1819
minH?: number;
1920
maxW?: number;

client/packages/lowcoder/src/pages/editor/LeftContent.tsx

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ import { CollapseWrapper, DirectoryTreeStyle, Node } from "./styledComponents";
3333
import { DataNode, EventDataNode } from "antd/lib/tree";
3434
import { isAggregationApp } from "util/appUtils";
3535
import cloneDeep from 'lodash/cloneDeep';
36+
import { useDispatch } from "react-redux";
37+
import { useApplicationId } from "util/hooks";
38+
import { updateApplication } from "redux/reduxActions/applicationActions";
3639

3740
const CollapseTitleWrapper = styled.div`
3841
display: flex;
@@ -209,6 +212,8 @@ type NodeItem = {
209212
title: string;
210213
type?: UICompType;
211214
children: NodeItem[];
215+
pos?: number;
216+
disabled?: boolean;
212217
};
213218

214219
type NodeInfo = {
@@ -243,25 +248,28 @@ export const LeftContent = (props: LeftContentProps) => {
243248
const editorState = useContext(EditorContext);
244249
const [expandedKeys, setExpandedKeys] = useState<Array<React.Key>>([]);
245250
const [showData, setShowData] = useState<NodeInfo[]>([]);
251+
const dispatch = useDispatch();
252+
const applicationId = useApplicationId();
246253

247254
const getTree = (tree: CompTree, result: NodeItem[], key?: string) => {
248255
const { items, children } = tree;
249256
if (Object.keys(items).length) {
250257
for (const i in items) {
251-
const info = {
258+
const info: NodeItem = {
252259
title: items[i].children.name.getView(),
253260
type: items[i].children.compType.getView() as UICompType,
254261
key: i,
255262
children: [],
256263
};
257264
if (key) {
258265
const parent = getTreeNodeByKey(result, key);
266+
info.disabled = true;
259267
parent?.children.push(info);
260268
} else {
261269
result.push(info);
262270
}
263271
}
264-
result = _.sortBy(result, [(x) => x.title]);
272+
// result = _.sortBy(result, [(x) => x.title]);
265273
}
266274
if (Object.keys(children).length) {
267275
for (const i in children) {
@@ -428,6 +436,20 @@ export const LeftContent = (props: LeftContentProps) => {
428436
? editorState.getUIComp().getTree()
429437
: editorState.getHooksComp().getUITree();
430438
const explorerData: NodeItem[] = getTree(tree, []);
439+
// TODO: handle sorting inside modals/drawers
440+
if(type === TreeUIKey.Modals) return explorerData;
441+
442+
const dsl = editorState.rootComp.toJsonValue();
443+
explorerData.forEach(data => {
444+
data['pos'] = dsl.ui.layout[data.key].pos;
445+
})
446+
explorerData.sort((a, b) => {
447+
const aPos = a?.pos || 0;
448+
const bPos = b?.pos || 0;
449+
if (aPos < bPos) return -1;
450+
if (aPos > bPos) return 1;
451+
return 0;
452+
});
431453
return explorerData;
432454
}
433455

@@ -468,7 +490,34 @@ export const LeftContent = (props: LeftContentProps) => {
468490
parentNode.children.splice(dropIndex > dragIndex ? dropIndex - 1 : dropIndex, 0, draggedNode);
469491
}
470492
}
493+
494+
const dsl = editorState.rootComp.toJsonValue();
495+
let layout: any = {};
496+
parentNode.children.forEach((data, index) => {
497+
layout[data.key] = {
498+
...dsl.ui.layout[data.key],
499+
pos: index,
500+
};
501+
})
471502

503+
if ( type === TreeUIKey.Modals) return newTreeData;
504+
505+
dispatch(
506+
updateApplication({
507+
applicationId: applicationId,
508+
editingApplicationDSL: {
509+
...dsl,
510+
ui: {
511+
...dsl.ui,
512+
layout,
513+
}
514+
} as object,
515+
})
516+
);
517+
editorState.rootComp.children.ui.dispatchChangeValueAction({
518+
...dsl.ui,
519+
layout,
520+
})
472521
return newTreeData;
473522
});
474523
}

client/packages/lowcoder/src/pages/editor/styledComponents.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ export const DirectoryTreeStyle = styled(DirectoryTree)`
5858
.ant-tree-node-content-wrapper.ant-tree-node-selected {
5959
color: #333;
6060
}
61+
.ant-tree-treenode-disabled {
62+
.ant-tree-node-content-wrapper {
63+
color: inherit;
64+
}
65+
}
6166
}
6267
`;
6368

0 commit comments

Comments
 (0)