Skip to content

[Feat] Layer Feature & Bulk Property Settings #681

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Feb 15, 2024
Prev Previous commit
Next Next commit
component sorting and z-index based on sorting position
  • Loading branch information
raheeliftikhar5 committed Feb 2, 2024
commit 27079d9161d2390f641a90756e5ecfbc5ec4e4f6
Original file line number Diff line number Diff line change
Expand Up @@ -230,14 +230,27 @@ const onDrop = (
};
const key = genRandomKey();
const layoutItem = Object.values(items)[0];
// calculate postion of newly added comp
// should have last position in the comps list
let itemPos = 0;
if (!Object.keys(layout).length) {
itemPos = 0;
} else {
itemPos = Math.max(...Object.values(layout).map(l => l.pos || 0)) + 1;
}
// log.debug("layout: onDrop. widgetValue: ", widgetValue, " layoutItem: ", layoutItem);
dispatch(
wrapActionExtraInfo(
multiChangeAction({
layout: changeValueAction(
{
...layout,
[key]: { ...layoutItem, i: key, placeholder: undefined },
[key]: {
...layoutItem,
i: key,
placeholder: undefined,
pos: itemPos,
},
},
true
),
Expand Down Expand Up @@ -463,6 +476,7 @@ export function InnerGrid(props: ViewPropsWithSelect) {
layout={props.layout}
extraLayout={extraLayout}
onDropDragOver={(e) => {

const compType = draggingUtils.getData<UICompType>("compType");
const compLayout = draggingUtils.getData<UICompLayoutInfo>("compLayout");
if (compType) {
Expand Down
2 changes: 1 addition & 1 deletion client/packages/lowcoder/src/comps/comps/textComp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const getStyle = (style: TextStyleType) => {
margin: ${style.margin} !important;
padding: ${style.padding};
width: ${widthCalculator(style.margin)};
height: ${heightCalculator(style.margin)};
// height: ${heightCalculator(style.margin)};
h1 {
line-height: 1.5;
}
Expand Down
2 changes: 1 addition & 1 deletion client/packages/lowcoder/src/constants/Layers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const Layers = {
// comp selection wrapper
dragSelectBox: 399,
//
compHover: 300,
compHover: 100,
//
compSelected: 200,
//
Expand Down
12 changes: 8 additions & 4 deletions client/packages/lowcoder/src/layout/gridItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type GridItemCallback<Data extends GridDragEvent | GridResizeEvent> = (
arg3: Data
) => void;
export type GridItemProps = {
zIndex: number;
children: ReactElement;
cols: number;
containerWidth: number;
Expand Down Expand Up @@ -81,7 +82,8 @@ export type GridItemProps = {

export const IsDroppable = React.createContext(true);

const ResizableStyled = styled(Resizable)`
const ResizableStyled = styled(Resizable)<{ $zIndex: number }>`
z-index: ${props => props.$zIndex};
&:hover {
z-index: 1;
}
Expand Down Expand Up @@ -151,7 +153,8 @@ export function GridItem(props: GridItemProps) {
const mixinResizable = (
child: ReactElement,
position: Position,
isResizable: boolean
isResizable: boolean,
zIndex: number,
): ReactElement => {
const { cols, x, minW, minH, maxW, maxH, resizeHandles } = props;
// This is the max possible width - doesn't go to infinity because of the width of the window
Expand Down Expand Up @@ -179,6 +182,7 @@ export function GridItem(props: GridItemProps) {
onResizeStop={onResizeStop}
resizeHandles={resizeHandles}
handle={Handle}
$zIndex={zIndex}
>
{child}
</ResizableStyled>
Expand Down Expand Up @@ -397,7 +401,7 @@ export function GridItem(props: GridItemProps) {
return { width, height, top, left };
}, [dragging, position.height, position.left, position.top, position.width, resizing]);

const { isDraggable, isResizable, layoutHide, children, isSelected, clickItem } = props;
const { isDraggable, isResizable, layoutHide, children, isSelected, clickItem, zIndex } = props;
const pos = calcPosition();
const render = () => {
let child = React.Children.only(children);
Expand Down Expand Up @@ -433,7 +437,7 @@ export function GridItem(props: GridItemProps) {
},
});
// Resizable support. This is usually on but the user can toggle it off.
newChild = mixinResizable(newChild, pos, isResizable);
newChild = mixinResizable(newChild, pos, isResizable, zIndex);
// Draggable support. This is always on, except for with placeholders.
newChild = mixinDraggable(newChild, isDraggable);
return newChild;
Expand Down
12 changes: 10 additions & 2 deletions client/packages/lowcoder/src/layout/gridLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
};

processGridItem(
zIndex: number,
item: LayoutItem,
childrenMap: _.Dictionary<React.ReactElement>
): React.ReactElement | undefined {
Expand Down Expand Up @@ -464,6 +465,7 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
top: showName?.top ?? 0,
bottom: (showName?.bottom ?? 0) + (this.ref.current?.scrollHeight ?? 0),
}}
zIndex={zIndex}
>
{child}
</GridItem>
Expand Down Expand Up @@ -863,7 +865,6 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
// move the logic to onDragEnd function when dragging from the canvas
return;
}

let layout = this.getUILayout();
const ops = layoutOpUtils.push(this.state.ops, deleteItemOp(droppingKey));
const items = _.pick(layout, droppingKey);
Expand Down Expand Up @@ -1001,6 +1002,7 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
this.ref = this.props.innerRef ?? this.innerRef;

// log.debug("GridLayout render. layout: ", layout, " oriLayout: ", this.state.layout, " extraLayout: ", this.props.extraLayout);
const layouts = Object.values(layout);
return (
<LayoutContainer
ref={this.ref}
Expand All @@ -1026,7 +1028,13 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
<div style={contentStyle}>
{showGridLines && this.gridLines()}
{mounted &&
Object.values(layout).map((item) => this.processGridItem(item, childrenMap))}
layouts.map((item) => {
const zIndex = item.pos !== undefined
? layouts.length - item.pos
: 1;
return this.processGridItem(zIndex, item, childrenMap)
})
}
{this.hintPlaceholder()}
</div>
</ReactResizeDetector>
Expand Down
1 change: 1 addition & 0 deletions client/packages/lowcoder/src/layout/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type LayoutItem = {
x: number;
y: number;
i: string;
pos?: number;
minW?: number;
minH?: number;
maxW?: number;
Expand Down
53 changes: 51 additions & 2 deletions client/packages/lowcoder/src/pages/editor/LeftContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ import { CollapseWrapper, DirectoryTreeStyle, Node } from "./styledComponents";
import { DataNode, EventDataNode } from "antd/lib/tree";
import { isAggregationApp } from "util/appUtils";
import cloneDeep from 'lodash/cloneDeep';
import { useDispatch } from "react-redux";
import { useApplicationId } from "util/hooks";
import { updateApplication } from "redux/reduxActions/applicationActions";

const CollapseTitleWrapper = styled.div`
display: flex;
Expand Down Expand Up @@ -209,6 +212,8 @@ type NodeItem = {
title: string;
type?: UICompType;
children: NodeItem[];
pos?: number;
disabled?: boolean;
};

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

const getTree = (tree: CompTree, result: NodeItem[], key?: string) => {
const { items, children } = tree;
if (Object.keys(items).length) {
for (const i in items) {
const info = {
const info: NodeItem = {
title: items[i].children.name.getView(),
type: items[i].children.compType.getView() as UICompType,
key: i,
children: [],
};
if (key) {
const parent = getTreeNodeByKey(result, key);
info.disabled = true;
parent?.children.push(info);
} else {
result.push(info);
}
}
result = _.sortBy(result, [(x) => x.title]);
// result = _.sortBy(result, [(x) => x.title]);
}
if (Object.keys(children).length) {
for (const i in children) {
Expand Down Expand Up @@ -428,6 +436,20 @@ export const LeftContent = (props: LeftContentProps) => {
? editorState.getUIComp().getTree()
: editorState.getHooksComp().getUITree();
const explorerData: NodeItem[] = getTree(tree, []);
// TODO: handle sorting inside modals/drawers
if(type === TreeUIKey.Modals) return explorerData;

const dsl = editorState.rootComp.toJsonValue();
explorerData.forEach(data => {
data['pos'] = dsl.ui.layout[data.key].pos;
})
explorerData.sort((a, b) => {
const aPos = a?.pos || 0;
const bPos = b?.pos || 0;
if (aPos < bPos) return -1;
if (aPos > bPos) return 1;
return 0;
});
return explorerData;
}

Expand Down Expand Up @@ -468,7 +490,34 @@ export const LeftContent = (props: LeftContentProps) => {
parentNode.children.splice(dropIndex > dragIndex ? dropIndex - 1 : dropIndex, 0, draggedNode);
}
}

const dsl = editorState.rootComp.toJsonValue();
let layout: any = {};
parentNode.children.forEach((data, index) => {
layout[data.key] = {
...dsl.ui.layout[data.key],
pos: index,
};
})

if ( type === TreeUIKey.Modals) return newTreeData;

dispatch(
updateApplication({
applicationId: applicationId,
editingApplicationDSL: {
...dsl,
ui: {
...dsl.ui,
layout,
}
} as object,
})
);
editorState.rootComp.children.ui.dispatchChangeValueAction({
...dsl.ui,
layout,
})
return newTreeData;
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ export const DirectoryTreeStyle = styled(DirectoryTree)`
.ant-tree-node-content-wrapper.ant-tree-node-selected {
color: #333;
}
.ant-tree-treenode-disabled {
.ant-tree-node-content-wrapper {
color: inherit;
}
}
}
`;

Expand Down