From 5919277935c49790e51a4f1756d762aa216f8ba6 Mon Sep 17 00:00:00 2001
From: mou <10402885@qq.com>
Date: Fri, 4 Aug 2023 16:29:41 +0800
Subject: [PATCH 01/97] =?UTF-8?q?=E5=9B=BE=E6=A0=87=E9=80=89=E6=8B=A9?=
 =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=B7=BB=E5=8A=A0antD=E5=9B=BE=E6=A0=87=20ic?=
 =?UTF-8?q?onControl=20add=20antd=20icon?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../src/components/iconSelect/index.tsx       | 101 +++++++++++++-----
 .../src/comps/controls/controlParams.tsx      |   1 +
 .../src/comps/controls/dropdownControl.tsx    |   1 +
 .../src/comps/controls/iconControl.tsx        |   5 +-
 4 files changed, 80 insertions(+), 28 deletions(-)

diff --git a/client/packages/lowcoder-design/src/components/iconSelect/index.tsx b/client/packages/lowcoder-design/src/components/iconSelect/index.tsx
index 41f0bcf61e..425b19185d 100644
--- a/client/packages/lowcoder-design/src/components/iconSelect/index.tsx
+++ b/client/packages/lowcoder-design/src/components/iconSelect/index.tsx
@@ -1,16 +1,24 @@
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import type { IconDefinition } from "@fortawesome/free-regular-svg-icons";
 import { Popover } from "antd";
-import { ActionType } from '@rc-component/trigger/lib/interface';
+import { ActionType } from "@rc-component/trigger/lib/interface";
 import { TacoInput } from "components/tacoInput";
 import { Tooltip } from "components/toolTip";
 import { trans } from "i18n/design";
 import _ from "lodash";
-import { ReactNode, useEffect, useCallback, useMemo, useRef, useState } from "react";
+import {
+  ReactNode,
+  useEffect,
+  useCallback,
+  useMemo,
+  useRef,
+  useState,
+} from "react";
 import Draggable from "react-draggable";
 import { List, ListRowProps } from "react-virtualized";
 import styled from "styled-components";
 import { CloseIcon, SearchIcon } from "icons";
+import { ANTDICON } from "../../../../lowcoder/src/comps/comps/timelineComp/antIcon";
 
 const PopupContainer = styled.div`
   width: 408px;
@@ -110,11 +118,23 @@ const IconItemContainer = styled.div`
 
 class Icon {
   readonly title: string;
-  constructor(readonly def: IconDefinition, readonly names: string[]) {
-    this.title = def.iconName.split("-").map(_.upperFirst).join(" ");
+  constructor(readonly def: IconDefinition | any, readonly names: string[]) {
+    if (def?.iconName) {
+      this.title = def.iconName.split("-").map(_.upperFirst).join(" ");
+    } else {
+      this.title = names[0].slice(5);
+      this.def = def;
+    }
   }
   getView() {
-    return <FontAwesomeIcon icon={this.def} style={{ width: "1em", height: "1em" }} />;
+    if (this.names[0].startsWith("antd/")) return this.def;
+    else
+      return (
+        <FontAwesomeIcon
+          icon={this.def}
+          style={{ width: "1em", height: "1em" }}
+        />
+      );
   }
 }
 
@@ -144,6 +164,13 @@ async function getAllIcons() {
       }
     }
   }
+  //append ant icon
+  for (let key of Object.keys(ANTDICON)) {
+    ret["antd/" + key] = new Icon(
+      ANTDICON[key.toLowerCase() as keyof typeof ANTDICON],
+      ["antd/" + key]
+    );
+  }
   allIcons = ret;
   return ret;
 }
@@ -151,7 +178,11 @@ async function getAllIcons() {
 export const iconPrefix = "/icon:";
 
 export function removeQuote(value?: string) {
-  return value ? (value.startsWith('"') && value.endsWith('"') ? value.slice(1, -1) : value) : "";
+  return value
+    ? value.startsWith('"') && value.endsWith('"')
+      ? value.slice(1, -1)
+      : value
+    : "";
 }
 
 function getIconKey(value?: string) {
@@ -171,7 +202,8 @@ export function useIcon(value?: string) {
 function search(
   allIcons: Record<string, Icon>,
   searchText: string,
-  searchKeywords?: Record<string, string>
+  searchKeywords?: Record<string, string>,
+  IconType?: "OnlyAntd" | "All" | "default" | undefined
 ) {
   const tokens = searchText
     .toLowerCase()
@@ -182,6 +214,8 @@ function search(
       if (icon.names.length === 0) {
         return false;
       }
+      if (IconType === "OnlyAntd" && !key.startsWith("antd/")) return false;
+      if (IconType === "default" && key.startsWith("antd/")) return false;
       let text = icon.names
         .flatMap((name) => [name, searchKeywords?.[name]])
         .filter((t) => t)
@@ -198,16 +232,20 @@ const IconPopup = (props: {
   label?: ReactNode;
   onClose: () => void;
   searchKeywords?: Record<string, string>;
+  IconType?: "OnlyAntd" | "All" | "default" | undefined;
 }) => {
   const [searchText, setSearchText] = useState("");
   const [allIcons, setAllIcons] = useState<Record<string, Icon>>({});
   const searchResults = useMemo(
-    () => search(allIcons, searchText, props.searchKeywords),
+    () => search(allIcons, searchText, props.searchKeywords, props.IconType),
     [searchText, allIcons]
   );
   const onChangeRef = useRef(props.onChange);
   onChangeRef.current = props.onChange;
-  const onChangeIcon = useCallback((key: string) => onChangeRef.current(iconPrefix + key), []);
+  const onChangeIcon = useCallback(
+    (key: string) => onChangeRef.current(iconPrefix + key),
+    []
+  );
   const columnNum = 8;
 
   useEffect(() => {
@@ -217,24 +255,26 @@ const IconPopup = (props: {
   const rowRenderer = useCallback(
     (p: ListRowProps) => (
       <IconRow key={p.key} style={p.style}>
-        {searchResults.slice(p.index * columnNum, (p.index + 1) * columnNum).map(([key, icon]) => (
-          <Tooltip
-            key={key}
-            title={icon.title}
-            placement="bottom"
-            align={{ offset: [0, -7, 0, 0] }}
-            destroyTooltipOnHide
-          >
-            <IconItemContainer
-              tabIndex={0}
-              onClick={() => {
-                onChangeIcon(key);
-              }}
+        {searchResults
+          .slice(p.index * columnNum, (p.index + 1) * columnNum)
+          .map(([key, icon]) => (
+            <Tooltip
+              key={key}
+              title={icon.title}
+              placement="bottom"
+              align={{ offset: [0, -7, 0, 0] }}
+              destroyTooltipOnHide
             >
-              {icon.getView()}
-            </IconItemContainer>
-          </Tooltip>
-        ))}
+              <IconItemContainer
+                tabIndex={0}
+                onClick={() => {
+                  onChangeIcon(key);
+                }}
+              >
+                {icon.getView()}
+              </IconItemContainer>
+            </Tooltip>
+          ))}
       </IconRow>
     ),
     [searchResults, allIcons, onChangeIcon]
@@ -279,6 +319,7 @@ export const IconSelectBase = (props: {
   leftOffset?: number;
   parent?: HTMLElement | null;
   searchKeywords?: Record<string, string>;
+  IconType?: "OnlyAntd" | "All" | "default" | undefined;
 }) => {
   const { setVisible, parent } = props;
   return (
@@ -290,7 +331,11 @@ export const IconSelectBase = (props: {
       onOpenChange={setVisible}
       getPopupContainer={parent ? () => parent : undefined}
       // hide the original background when dragging the popover is allowed
-      overlayInnerStyle={{ border: "none", boxShadow: "none", background: "transparent" }}
+      overlayInnerStyle={{
+        border: "none",
+        boxShadow: "none",
+        background: "transparent",
+      }}
       // when dragging is allowed, always re-location to avoid the popover exceeds the screen
       destroyTooltipOnHide
       content={
@@ -299,6 +344,7 @@ export const IconSelectBase = (props: {
           label={props.label}
           onClose={() => setVisible?.(false)}
           searchKeywords={props.searchKeywords}
+          IconType={props.IconType}
         />
       }
     >
@@ -312,6 +358,7 @@ export const IconSelect = (props: {
   label?: ReactNode;
   children?: ReactNode;
   searchKeywords?: Record<string, string>;
+  IconType?: "OnlyAntd" | "All" | "default" | undefined;
 }) => {
   const [visible, setVisible] = useState(false);
   return (
diff --git a/client/packages/lowcoder/src/comps/controls/controlParams.tsx b/client/packages/lowcoder/src/comps/controls/controlParams.tsx
index 0ee9de8e6c..7b84c439de 100644
--- a/client/packages/lowcoder/src/comps/controls/controlParams.tsx
+++ b/client/packages/lowcoder/src/comps/controls/controlParams.tsx
@@ -18,6 +18,7 @@ export interface ControlParams extends CodeEditorControlParams {
   preInputNode?: ReactNode;
   childrenWrapperStyle?: CSSProperties;
   extraChildren?: ReactNode;
+  IconType?: "OnlyAntd" | "All" | "default" | undefined;
 }
 
 export interface ControlType {
diff --git a/client/packages/lowcoder/src/comps/controls/dropdownControl.tsx b/client/packages/lowcoder/src/comps/controls/dropdownControl.tsx
index 211dd09101..838b98a340 100644
--- a/client/packages/lowcoder/src/comps/controls/dropdownControl.tsx
+++ b/client/packages/lowcoder/src/comps/controls/dropdownControl.tsx
@@ -28,6 +28,7 @@ interface DropdownControlParams<T extends OptionsType> extends ControlParams {
   showSearch?: boolean;
   dropdownStyle?: React.CSSProperties;
   labelStyle?: React.CSSProperties;
+  IconType?: "OnlyAntd" | "All" | "default" | undefined;
 }
 
 interface DropdownPropertyViewProps<T extends OptionsType>
diff --git a/client/packages/lowcoder/src/comps/controls/iconControl.tsx b/client/packages/lowcoder/src/comps/controls/iconControl.tsx
index 26a768b4e6..ca954b47db 100644
--- a/client/packages/lowcoder/src/comps/controls/iconControl.tsx
+++ b/client/packages/lowcoder/src/comps/controls/iconControl.tsx
@@ -75,6 +75,7 @@ const IconPicker = (props: {
   value: string;
   onChange: (value: string) => void;
   label?: ReactNode;
+  IconType?: "OnlyAntd" | "All" | "default" | undefined;
 }) => {
   const icon = useIcon(props.value);
   return (
@@ -82,6 +83,7 @@ const IconPicker = (props: {
       onChange={props.onChange}
       label={props.label}
       searchKeywords={i18nObjs.iconSearchKeywords}
+      IconType={props.IconType}
     >
       <TacoButton style={{ width: "100%" }}>
         {icon ? (
@@ -251,7 +253,7 @@ export class IconControl extends AbstractComp<ReactNode, string, Node<ValueAndMs
         { filterText: params.label },
         <Wrapper>
           <SwitchWrapper label={params.label} tooltip={params.tooltip} lastNode={jsContent} />
-          {this.useCodeEditor && <IconCodeEditor codeControl={this.codeControl} params={params} />}
+          {this.useCodeEditor && <IconCodeEditor codeControl={this.codeControl} params={params}/>}
         </Wrapper>
       );
     }
@@ -262,6 +264,7 @@ export class IconControl extends AbstractComp<ReactNode, string, Node<ValueAndMs
             value={this.codeControl.getView()}
             onChange={(x) => this.dispatchChangeValueAction(x)}
             label={params.label}
+            IconType={params.IconType}
           />
         )}
       </ControlPropertyViewWrapper>

From f3cb6746830fb915b42e184bf7ed30922875f8c5 Mon Sep 17 00:00:00 2001
From: mou <10402885@qq.com>
Date: Wed, 9 Aug 2023 09:55:58 +0800
Subject: [PATCH 02/97] add_icon_component

---
 .../src/icons/IconCompIcon.svg                |   1 +
 .../lowcoder-design/src/icons/index.ts        |   2 +
 .../lowcoder/src/comps/comps/iconComp.tsx     | 142 ++++++++++++++++++
 .../comps/controls/styleControlConstants.tsx  |   5 +
 client/packages/lowcoder/src/comps/index.tsx  |  16 ++
 .../lowcoder/src/comps/uiCompRegistry.ts      |   1 +
 .../packages/lowcoder/src/i18n/locales/en.ts  |   8 +
 .../packages/lowcoder/src/i18n/locales/zh.ts  |  33 ++++
 .../src/pages/editor/editorConstants.tsx      |   2 +
 9 files changed, 210 insertions(+)
 create mode 100644 client/packages/lowcoder-design/src/icons/IconCompIcon.svg
 create mode 100644 client/packages/lowcoder/src/comps/comps/iconComp.tsx

diff --git a/client/packages/lowcoder-design/src/icons/IconCompIcon.svg b/client/packages/lowcoder-design/src/icons/IconCompIcon.svg
new file mode 100644
index 0000000000..ce549b56c6
--- /dev/null
+++ b/client/packages/lowcoder-design/src/icons/IconCompIcon.svg
@@ -0,0 +1 @@
+<svg t="1691242418775" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15052" width="200" height="200"><path d="M497.6 263.9l-4.5-41.9-2.5-21-1.9-12.1c-0.7-4-1.9-7.9-2.9-11.7-9-30.9-28.6-56.9-53-74.1C408.3 86 379.2 77.4 350.6 78c-27.9 0.6-55.8 0.7-83.8 0.1l-41.9-1.4-20.9-1.1h-11c-3.7 0-7.3 0.6-11 0.9-29.3 3.4-58.1 17.4-79.1 40-10.4 11.3-19.1 24.5-25 39-5.9 14.5-9.2 30.1-10 45.9l-2.7 83.8-1.3 41.8-0.7 21 0.3 12.3c0.2 4.1 0.9 8.2 1.3 12.2 5 32.6 21.8 63.5 47 85.4 25.1 22 58.4 35 92.3 35.8 27.9 0.8 55.8 1.6 83.8 2.8l41.9 1.7 21 0.8 13.2-0.2c4.4-0.1 8.8-0.9 13.2-1.4 35-5.2 68.3-23.5 91.2-50.9 11.3-13.8 20.5-29.4 26.3-46.3 5.8-16.9 8.5-34.7 8.3-52.4-1-28-2.8-55.9-5.4-83.9z m-45.9-71.6l-0.8 8.9-2.5 20.9-4.5 41.9c-2.6 27.9-4.4 55.8-5.4 83.8-1 20.5-8.7 40-21.5 55.5-12.9 15.6-30.9 26.7-50.8 31.2-2.5 0.4-5 1.2-7.6 1.5l-7.7 0.8-20.9 0.9-41.9 1.7c-27.9 1.1-55.8 2-83.8 2.8-22 0.6-44.2-6.5-61.9-20.4-17.8-13.8-30.4-34.3-35.1-56.6-0.5-2.8-1.2-5.6-1.5-8.5l-0.8-8.6-0.7-20.9-1.3-41.9-2.7-83.8c-0.9-24.2 6.4-48.9 21.2-69.3 14.8-20.4 37.3-35.8 62.9-42.2 3.2-0.6 6.4-1.5 9.7-1.9L204 87l20.9-1.1 41.9-1.4c27.9-0.6 55.8-0.5 83.8 0.1 27.2 0.8 53.6 12.2 72 30.9 18.6 18.6 28.4 43.9 29.2 67.9-0.1 3 0.2 5.9-0.1 8.9zM497.6 709.6l-4.5-41.9-2.5-21-1.9-12.1c-0.7-4-1.9-7.9-2.9-11.7-9-30.9-28.6-56.9-53-74.1-24.5-17.2-53.6-25.8-82.2-25.2-27.9 0.6-55.8 0.7-83.8 0.1l-41.9-1.4-20.9-1.1h-11c-3.7 0-7.3 0.6-11 0.9-29.3 3.4-58.1 17.4-79.1 40-10.4 11.3-19.1 24.5-25 39-5.9 14.5-9.2 30.1-10 45.9l-2.7 83.8-1.3 41.9-0.7 21 0.3 12.3c0.2 4.1 0.9 8.2 1.3 12.2 5 32.6 21.8 63.5 47 85.4 25.1 22 58.4 35 92.3 35.8 27.9 0.8 55.8 1.6 83.8 2.8l41.9 1.7 21 0.8 13.2-0.2c4.4-0.1 8.8-0.9 13.2-1.4 35-5.2 68.3-23.5 91.2-50.9 11.3-13.8 20.5-29.4 26.3-46.3 5.8-16.9 8.5-34.7 8.3-52.4-1-28-2.8-55.9-5.4-83.9zM451.7 638l-0.8 8.9-2.5 20.9-4.5 41.9c-2.6 27.9-4.4 55.8-5.4 83.8-1 20.5-8.7 40-21.5 55.5-12.9 15.6-30.9 26.7-50.8 31.2-2.5 0.4-5 1.2-7.6 1.5l-7.7 0.8-20.9 0.9-42 1.6c-27.9 1.1-55.8 2-83.8 2.8-22 0.6-44.2-6.5-61.9-20.4-17.8-13.8-30.4-34.3-35.1-56.6-0.5-2.8-1.2-5.6-1.5-8.5l-0.8-8.6-0.7-20.9-1.3-41.9-2.7-83.8c-0.9-24.2 6.4-48.9 21.2-69.3 14.8-20.4 37.3-35.8 62.9-42.2 3.2-0.6 6.4-1.5 9.7-1.9l9.9-1.1 20.9-1.1 41.9-1.4c27.9-0.6 55.8-0.5 83.8 0.1 27.2 0.8 53.6 12.2 72 30.9 18.6 18.6 28.4 43.9 29.2 67.9 0 3 0.3 6 0 9zM521.3 372.5c5 32.6 21.8 63.5 47 85.4 25.1 22 58.4 35 92.3 35.8 27.9 0.8 55.8 1.6 83.8 2.8l41.9 1.7 21 0.8 13.2-0.2c4.4-0.1 8.8-0.9 13.2-1.4 35-5.2 68.3-23.5 91.2-50.9 11.3-13.8 20.5-29.4 26.3-46.3 5.8-16.9 8.5-34.7 8.3-52.4-1-27.9-2.8-55.8-5.4-83.8l-4.5-41.9-2.5-21L945 189c-0.7-4-1.9-7.9-2.9-11.7-9-30.9-28.6-56.9-53-74.1C864.7 86 835.6 77.4 806.9 78c-27.9 0.6-55.8 0.7-83.8 0.1l-41.9-1.4-20.9-1.1h-11c-3.7 0-7.3 0.6-11 0.9-29.3 3.4-58.1 17.4-79.1 40-10.4 11.3-19.1 24.5-25 39-5.9 14.5-9.2 30.1-10 45.9l-2.7 83.8-1.3 41.9-0.7 21 0.3 12.3c0.3 3.9 1 8 1.5 12.1zM577.8 132c14.8-20.4 37.3-35.8 62.9-42.2 3.2-0.6 6.4-1.5 9.7-1.9l9.9-1.1 20.9-1.1 41.9-1.4c27.9-0.6 55.8-0.5 83.8 0.1 27.2 0.8 53.6 12.2 72 30.9 18.6 18.6 28.4 43.9 29.2 67.9-0.1 3 0.2 6-0.1 9l-0.8 8.9-2.5 20.9-4.5 41.9c-2.6 27.9-4.4 55.8-5.4 83.8-1 20.5-8.7 40-21.5 55.5-12.9 15.6-30.9 26.7-50.8 31.2-2.5 0.4-5 1.2-7.6 1.5l-7.7 0.8-20.9 0.9-41.9 1.7c-27.9 1.1-55.8 2-83.8 2.8-22 0.6-44.2-6.5-61.9-20.4-17.8-13.8-30.4-34.3-35.1-56.6-0.5-2.8-1.2-5.6-1.5-8.5l-0.8-8.6-0.7-20.9-1.3-41.9-2.7-83.8c-1-24.3 6.4-49 21.2-69.4zM954 709.6l-4.5-41.9-2.5-21-1.9-12.1c-0.7-4-1.9-7.9-2.9-11.7-9-30.9-28.6-56.9-53-74.1-24.5-17.2-53.6-25.8-82.2-25.2-27.9 0.6-55.8 0.7-83.8 0.1l-41.9-1.4-20.9-1.1h-11c-3.7 0-7.3 0.6-11 0.9-29.3 3.4-58.1 17.4-79.1 40-10.4 11.3-19.1 24.5-25 39-5.9 14.5-9.2 30.1-10 45.9l-2.7 83.8-1.3 41.9-0.7 21 0.3 12.3c0.1 4.1 0.9 8.2 1.3 12.2 5 32.6 21.8 63.5 47 85.4 25.1 22 58.4 35 92.3 35.8 27.9 0.8 55.8 1.6 83.8 2.8l41.9 1.7 21 0.8 13.2-0.2c4.4-0.1 8.8-0.9 13.2-1.4 35-5.2 68.3-23.5 91.2-50.9 11.3-13.8 20.5-29.4 26.3-46.3 5.8-16.9 8.5-34.7 8.3-52.4-1-28-2.8-55.9-5.4-83.9zM908.1 638l-0.8 8.9-2.5 20.9-4.5 41.9c-2.6 27.9-4.4 55.8-5.4 83.8-1 20.5-8.7 40-21.5 55.5-12.9 15.6-30.9 26.7-50.8 31.2-2.5 0.4-5 1.2-7.6 1.5l-7.7 0.8-20.9 0.9-41.9 1.7c-27.9 1.1-55.8 2-83.8 2.8-22 0.6-44.2-6.5-61.9-20.4-17.8-13.8-30.4-34.3-35.1-56.6-0.5-2.8-1.2-5.6-1.5-8.5l-0.8-8.6-0.7-20.9-1.3-41.9-2.7-83.8c-0.9-24.2 6.4-48.9 21.2-69.3 14.8-20.4 37.3-35.8 62.9-42.2 3.2-0.6 6.4-1.5 9.7-1.9l9.9-1.1 20.9-1.1 41.9-1.4c27.9-0.6 55.8-0.5 83.8 0.1 27.2 0.8 53.6 12.2 72 30.9 18.6 18.6 28.4 43.9 29.2 67.9-0.1 2.9 0.1 5.9-0.1 8.9z" fill="#d7d9e0" p-id="15053"></path></svg>
\ No newline at end of file
diff --git a/client/packages/lowcoder-design/src/icons/index.ts b/client/packages/lowcoder-design/src/icons/index.ts
index 4ac1b051ed..6d620cf46e 100644
--- a/client/packages/lowcoder-design/src/icons/index.ts
+++ b/client/packages/lowcoder-design/src/icons/index.ts
@@ -291,3 +291,5 @@ export { ReactComponent as TimeLineIcon } from "icons/icon-timeline-comp.svg"
 export { ReactComponent as LottieIcon } from "icons/icon-lottie.svg";
 export { ReactComponent as MentionIcon } from "icons/icon-mention-comp.svg";
 export { ReactComponent as AutoCompleteCompIcon } from "icons/icon-autocomplete-comp.svg";
+
+export { ReactComponent as IconCompIcon } from "icons/IconCompIcon.svg";
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/comps/iconComp.tsx b/client/packages/lowcoder/src/comps/comps/iconComp.tsx
new file mode 100644
index 0000000000..41b73da718
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/iconComp.tsx
@@ -0,0 +1,142 @@
+import { useEffect, useRef, useState } from "react";
+import styled, { css } from "styled-components";
+import { RecordConstructorToView } from "lowcoder-core";
+import { styleControl } from "comps/controls/styleControl";
+import _ from "lodash";
+import {
+  IconStyle,
+  IconStyleType,
+  heightCalculator,
+  widthCalculator,
+} from "comps/controls/styleControlConstants";
+import { UICompBuilder } from "comps/generators/uiCompBuilder";
+import { withDefault } from "../generators";
+import {
+  NameConfigHidden,
+  withExposingConfigs,
+} from "comps/generators/withExposing";
+import { Section, sectionNames } from "lowcoder-design";
+import { hiddenPropertyView } from "comps/utils/propertyUtils";
+import { trans } from "i18n";
+import { NumberControl } from "comps/controls/codeControl";
+import { IconControl } from "comps/controls/iconControl";
+import ReactResizeDetector from "react-resize-detector";
+import { AutoHeightControl } from "../controls/autoHeightControl";
+import {
+  clickEvent,
+  eventHandlerControl,
+} from "../controls/eventHandlerControl";
+
+const Container = styled.div<{ $style: IconStyleType | undefined }>`
+  height: 100%;
+  width: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  svg {
+    object-fit: contain;
+    pointer-events: auto;
+  }
+  ${(props) => props.$style && getStyle(props.$style)}
+`;
+
+const getStyle = (style: IconStyleType) => {
+  return css`
+    svg {
+      color: ${style.fill};
+    }
+    padding: ${style.padding};
+    border: 1px solid ${style.border};
+    border-radius: ${style.radius};
+    margin: ${style.margin};
+    max-width: ${widthCalculator(style.margin)};
+    max-height: ${heightCalculator(style.margin)};
+  `;
+};
+
+const EventOptions = [clickEvent] as const;
+
+const childrenMap = {
+  style: styleControl(IconStyle),
+  icon: withDefault(IconControl, "/icon:antd/homefilled"),
+  autoHeight: withDefault(AutoHeightControl, "auto"),
+  iconSize: withDefault(NumberControl, 20),
+  onEvent: eventHandlerControl(EventOptions),
+};
+
+const IconView = (props: RecordConstructorToView<typeof childrenMap>) => {
+  const conRef = useRef<HTMLDivElement>(null);
+  const [width, setWidth] = useState(0);
+  const [height, setHeight] = useState(0);
+
+  useEffect(() => {
+    if (height && width) {
+      onResize();
+    }
+  }, [height, width]);
+
+  const onResize = () => {
+    const container = conRef.current;
+    setWidth(container?.clientWidth ?? 0);
+    setHeight(container?.clientHeight ?? 0);
+  };
+
+  return (
+    <ReactResizeDetector onResize={onResize}>
+      <Container
+        ref={conRef}
+        $style={props.style}
+        style={{
+          fontSize: props.autoHeight
+            ? `${height < width ? height : width}px`
+            : props.iconSize,
+          background: props.style.background,
+        }}
+        onClick={() => props.onEvent("click")}
+      >
+        {props.icon}
+      </Container>
+    </ReactResizeDetector>
+  );
+};
+
+let IconBasicComp = (function () {
+  return new UICompBuilder(childrenMap, (props) => <IconView {...props} />)
+    .setPropertyViewFn((children) => (
+      <>
+        <Section name={sectionNames.basic}>
+          {children.icon.propertyView({
+            label: trans("iconComp.icon"),
+            IconType: "All",
+          })}
+          {children.autoHeight.propertyView({
+            label: trans("iconComp.autoSize"),
+          })}
+          {!children.autoHeight.getView() &&
+            children.iconSize.propertyView({
+              label: trans("iconComp.iconSize"),
+            })}
+        </Section>
+        <Section name={sectionNames.interaction}>
+          {children.onEvent.getPropertyView()}
+        </Section>
+        <Section name={sectionNames.layout}>
+          {hiddenPropertyView(children)}
+        </Section>
+        <Section name={sectionNames.style}>
+          {children.style.getPropertyView()}
+        </Section>
+      </>
+    ))
+    .build();
+})();
+
+IconBasicComp = class extends IconBasicComp {
+  override autoHeight(): boolean {
+    return false;
+  }
+};
+
+export const IconComp = withExposingConfigs(IconBasicComp, [
+  NameConfigHidden,
+]);
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index 5d650faea4..ca58c28362 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -775,6 +775,10 @@ export const NavigationStyle = [
 
 export const ImageStyle = [getStaticBorder("#00000000"), RADIUS, MARGIN, PADDING] as const;
 
+export const IconStyle = [getStaticBackground("#00000000"),
+  getStaticBorder("#00000000"), FILL, RADIUS, MARGIN, PADDING] as const;
+
+
 export const ListViewStyle = BG_STATIC_BORDER_RADIUS;
 
 export const JsonSchemaFormStyle = BG_STATIC_BORDER_RADIUS;
@@ -934,6 +938,7 @@ export type DividerStyleType = StyleConfigType<typeof DividerStyle>;
 export type ProgressStyleType = StyleConfigType<typeof ProgressStyle>;
 export type NavigationStyleType = StyleConfigType<typeof NavigationStyle>;
 export type ImageStyleType = StyleConfigType<typeof ImageStyle>;
+export type IconStyleType = StyleConfigType<typeof IconStyle>;
 export type ListViewStyleType = StyleConfigType<typeof ListViewStyle>;
 export type JsonSchemaFormStyleType = StyleConfigType<typeof JsonSchemaFormStyle>;
 export type TreeSelectStyleType = StyleConfigType<typeof TreeSelectStyle>;
diff --git a/client/packages/lowcoder/src/comps/index.tsx b/client/packages/lowcoder/src/comps/index.tsx
index 5dc0f29236..b70906d200 100644
--- a/client/packages/lowcoder/src/comps/index.tsx
+++ b/client/packages/lowcoder/src/comps/index.tsx
@@ -96,6 +96,7 @@ import {
   LottieIcon,
   MentionIcon,
   AutoCompleteCompIcon,
+  IconCompIcon,
 } from "lowcoder-design";
 
 import { defaultFormData, FormComp } from "./comps/formComp/formComp";
@@ -124,6 +125,8 @@ import { SignatureComp } from "./comps/signatureComp";
 import { TimeLineComp } from "./comps/timelineComp/timelineComp";
 import { MentionComp } from "./comps/textInputComp/mentionComp";
 import { AutoCompleteComp } from "./comps/autoCompleteComp/autoCompleteComp"
+import { IconComp } from "./comps/iconComp";
+
 //Added by Aqib Mirza
 import { JsonLottieComp } from "./comps/jsonComp/jsonLottieComp";
 
@@ -881,6 +884,19 @@ const uiCompMap: Registry = {
       h: 5,
     },
   },
+  icon: {
+    name: trans("uiComp.iconCompName"),
+    enName: "icon",
+    description: trans("uiComp.iconCompDesc"),
+    categories: ["dataDisplay"],
+    icon: IconCompIcon,
+    keywords: trans("uiComp.iconCompKeywords"),
+    comp: IconComp,
+    layoutInfo: {
+      w: 2,
+      h: 10,
+    },
+  },
 };
 
 export function loadComps() {
diff --git a/client/packages/lowcoder/src/comps/uiCompRegistry.ts b/client/packages/lowcoder/src/comps/uiCompRegistry.ts
index 6cd63e9208..9ba13b9305 100644
--- a/client/packages/lowcoder/src/comps/uiCompRegistry.ts
+++ b/client/packages/lowcoder/src/comps/uiCompRegistry.ts
@@ -114,6 +114,7 @@ export type UICompType =
   | "timeline"
   | "mention"
   | "autocomplete"
+  | "icon"
 
 export const uiCompRegistry = {} as Record<UICompType | string, UICompManifest>;
 
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index 941a777673..304651c629 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -853,6 +853,9 @@ export const en = {
     autoCompleteCompName: "autoComplete",
     autoCompleteCompDesc: "autoComplete",
     autoCompleteCompKeywords: "",
+    iconCompName: "icon",
+    iconCompDesc: "icon",
+    iconCompKeywords: "",
   },
   comp: {
     menuViewDocs: "View documentation",
@@ -2505,4 +2508,9 @@ export const en = {
     helpLabel: "label",
     helpValue: "value",
   },
+  iconComp: {
+    icon: "icon",
+    autoSize: "icon AutoSize",
+    iconSize: "icon size",
+  }
 };
diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts
index 7fb2416d54..0539f15cac 100644
--- a/client/packages/lowcoder/src/i18n/locales/zh.ts
+++ b/client/packages/lowcoder/src/i18n/locales/zh.ts
@@ -836,6 +836,9 @@ uiComp: {
     autoCompleteCompName: "自动完成",
     autoCompleteCompDesc: "自动完成",
     autoCompleteCompKeywords: "zdwc",
+    iconCompName: "图标",
+    iconCompDesc: "图标",
+    iconCompKeywords: "tb",
 },
 comp: {
     menuViewDocs: "查看文档",
@@ -2495,5 +2498,35 @@ timeLine: {
         helpLabel: "标签",
         helpValue: "值",
     },
+      comment: {
+        value: "评论列表数据",
+        showSendButton: "允许评论",
+        title: "标题",
+        titledDefaultValue: "共有%d条评论",
+        placeholder: "shift + enter 快捷发送评论;输入@或#可快速输入",
+        placeholderDec: "占位符",
+        buttonTextDec: "按钮文本",
+        buttonText: "发表",
+        mentionList: "提及列表数据",
+        mentionListDec: "key-提及关键字;value-提及列表",
+        userInfo: "用户信息",
+        dateErr: "日期错误",
+        commentList: "评论列表数据",
+        deletedItem: "已删除的数据",
+        submitedItem: "已提交的数据",
+        deleteAble: "显示删除按钮",
+        Introduction: "属性介绍",
+        helpUser: "用户信息(必填)",
+        helpname: "用户名(必填)",
+        helpavatar: "头像地址(高优先)",
+        helpdisplayName: "头像文字(低优先)",
+        helpvalue: "评论内容",
+        helpcreatedAt: "创建时间",
+      },
+    iconComp: {
+        icon: "图标",
+        autoSize: "图标自动大小",
+        iconSize: "图标大小",
+      }
 };
 
diff --git a/client/packages/lowcoder/src/pages/editor/editorConstants.tsx b/client/packages/lowcoder/src/pages/editor/editorConstants.tsx
index a09a9a56ee..cd3c81c3a7 100644
--- a/client/packages/lowcoder/src/pages/editor/editorConstants.tsx
+++ b/client/packages/lowcoder/src/pages/editor/editorConstants.tsx
@@ -39,6 +39,7 @@ import {
   TimeLineIcon,
   MentionIcon,
   AutoCompleteCompIcon,
+  IconCompIcon,
 } from "lowcoder-design";
 
 export const CompStateIcon: {
@@ -107,4 +108,5 @@ export const CompStateIcon: {
   timeline: <TimeLineIcon />,
   mention: <MentionIcon/>,
   autocomplete: <AutoCompleteCompIcon />,
+  icon: <IconCompIcon />,
 };

From fd9c3ccfe95ff3de8f2d4f46f43fb86fbdb0e6b6 Mon Sep 17 00:00:00 2001
From: mou <10402885@qq.com>
Date: Wed, 9 Aug 2023 10:26:48 +0800
Subject: [PATCH 03/97] fix_toggle_button_icon_bug

---
 .../lowcoder-design/src/components/iconSelect/index.tsx         | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/client/packages/lowcoder-design/src/components/iconSelect/index.tsx b/client/packages/lowcoder-design/src/components/iconSelect/index.tsx
index 425b19185d..da47c2dab9 100644
--- a/client/packages/lowcoder-design/src/components/iconSelect/index.tsx
+++ b/client/packages/lowcoder-design/src/components/iconSelect/index.tsx
@@ -127,7 +127,7 @@ class Icon {
     }
   }
   getView() {
-    if (this.names[0].startsWith("antd/")) return this.def;
+    if (this.names[0]?.startsWith("antd/")) return this.def;
     else
       return (
         <FontAwesomeIcon

From a5d099bb14ee151fa4e02c12e49fb6bdfff837e7 Mon Sep 17 00:00:00 2001
From: freddysundowner <githumbi3fred@gmail.com>
Date: Fri, 29 Dec 2023 11:06:35 +0300
Subject: [PATCH 04/97] initial

---
 .../lowcoder/src/comps/editorState.tsx        |  81 ++++++++--
 .../lowcoder/src/pages/common/header.tsx      | 153 ++++++++++++++----
 .../src/pages/editor/editorSkeletonView.tsx   |  18 ++-
 .../lowcoder/src/pages/editor/editorView.tsx  | 100 +++++++++---
 .../src/pages/tutorials/tutorialsConstant.tsx |   5 +
 .../lowcoder/src/util/localStorageUtil.ts     |  21 ++-
 6 files changed, 305 insertions(+), 73 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/editorState.tsx b/client/packages/lowcoder/src/comps/editorState.tsx
index 35732c075a..5e87d3b57c 100644
--- a/client/packages/lowcoder/src/comps/editorState.tsx
+++ b/client/packages/lowcoder/src/comps/editorState.tsx
@@ -2,8 +2,12 @@ import { isContainer } from "comps/comps/containerBase";
 import { RootComp as RootCompTmp } from "comps/comps/rootComp";
 import { PositionParams } from "layout";
 import _ from "lodash";
-import React, { ReactNode } from "react";
-import { BottomResComp, BottomResListComp, BottomResTypeEnum } from "types/bottomRes";
+import React, { ReactNode, useContext } from "react";
+import {
+  BottomResComp,
+  BottomResListComp,
+  BottomResTypeEnum,
+} from "types/bottomRes";
 import { setFields } from "util/objectUtils";
 import { OptionalComp, renameAction } from "lowcoder-core";
 import { GridItemComp } from "./comps/gridItemComp";
@@ -13,7 +17,7 @@ import { NameAndExposingInfo } from "./utils/exposingTypes";
 import { checkName } from "./utils/rename";
 import { trans } from "i18n";
 import { UiLayoutType } from "./comps/uiComp";
-import { getEditorModeStatus } from "util/localStorageUtil";
+import { getCollissionStatus, getEditorModeStatus } from "util/localStorageUtil";
 
 type RootComp = InstanceType<typeof RootCompTmp>;
 
@@ -43,6 +47,7 @@ export class EditorState {
   readonly showPropertyPane: boolean = false;
   readonly selectedCompNames: Set<string> = new Set();
   readonly editorModeStatus: string = "";
+  readonly collissionStatus: string = "";
   readonly isDragging: boolean = false;
   readonly draggingCompType: string = "button";
   readonly forceShowGrid: boolean = false; // show grid lines
@@ -52,16 +57,20 @@ export class EditorState {
   readonly showResultCompName: string = "";
   readonly selectSource?: SelectSourceType; // the source of select type
 
-  private readonly setEditorState: (fn: (editorState: EditorState) => EditorState) => void;
+  private readonly setEditorState: (
+    fn: (editorState: EditorState) => EditorState
+  ) => void;
 
   constructor(
     rootComp: RootComp,
     setEditorState: (fn: (editorState: EditorState) => EditorState) => void,
-    initialEditorModeStatus: string = getEditorModeStatus()
+    initialEditorModeStatus: string = getEditorModeStatus(),
+    initialCollissionStatus: string = getCollissionStatus()
   ) {
     this.rootComp = rootComp;
     this.setEditorState = setEditorState;
     this.editorModeStatus = initialEditorModeStatus;
+    this.collissionStatus = initialCollissionStatus;
   }
 
   /**
@@ -79,7 +88,10 @@ export class EditorState {
   }
 
   getAllCompMap() {
-    return { ...this.getAllHooksCompMap(), ...this.getUIComp().getAllCompItems() };
+    return {
+      ...this.getAllHooksCompMap(),
+      ...this.getUIComp().getAllCompItems(),
+    };
   }
 
   getAllUICompMap() {
@@ -104,7 +116,9 @@ export class EditorState {
    */
   getUICompByName(name: string) {
     const compMap = this.getAllUICompMap();
-    return Object.values(compMap).find((item) => item.children.name.getView() === name);
+    return Object.values(compMap).find(
+      (item) => item.children.name.getView() === name
+    );
   }
 
   getNameGenerator() {
@@ -130,7 +144,11 @@ export class EditorState {
     });
   }
 
-  getCompInfo(nameAndExposingInfo: NameAndExposingInfo, name: string, type: string): CompInfo {
+  getCompInfo(
+    nameAndExposingInfo: NameAndExposingInfo,
+    name: string,
+    type: string
+  ): CompInfo {
     return {
       name,
       type,
@@ -157,7 +175,11 @@ export class EditorState {
     const exposingInfo = listComp.nameAndExposingInfo();
     return listComp.getView().map((item) => {
       const name = item.children.name.getView();
-      return this.getCompInfo(exposingInfo, name, BottomResTypeEnum.DateResponder);
+      return this.getCompInfo(
+        exposingInfo,
+        name,
+        BottomResTypeEnum.DateResponder
+      );
     });
   }
 
@@ -175,7 +197,11 @@ export class EditorState {
     const exposingInfo = listComp.nameAndExposingInfo();
     return listComp.getView().map((item) => {
       const name = item.children.name.getView();
-      return this.getCompInfo(exposingInfo, name, BottomResTypeEnum.Transformer);
+      return this.getCompInfo(
+        exposingInfo,
+        name,
+        BottomResTypeEnum.Transformer
+      );
     });
   }
 
@@ -222,7 +248,10 @@ export class EditorState {
   }
 
   selectedQueryComp() {
-    if (this.selectedBottomResType !== BottomResTypeEnum.Query || !this.selectedBottomResName) {
+    if (
+      this.selectedBottomResType !== BottomResTypeEnum.Query ||
+      !this.selectedBottomResName
+    ) {
       return undefined;
     }
     return this.getQueriesComp()
@@ -233,7 +262,9 @@ export class EditorState {
   }
 
   showResultComp(): BottomResComp | undefined {
-    const bottomResComps = Object.values(BottomResTypeEnum).reduce<BottomResComp[]>((a, b) => {
+    const bottomResComps = Object.values(BottomResTypeEnum).reduce<
+      BottomResComp[]
+    >((a, b) => {
       const items = this.getBottomResListComp(b).items();
       return a.concat(items);
     }, []);
@@ -279,7 +310,10 @@ export class EditorState {
       return this.getUIComp().getComp();
     }
     const [key, comp] = _.toPairs(selectedComps)[0];
-    if (_.size(selectedComps) === 1 && isContainer((comp as GridItemComp)?.children?.comp)) {
+    if (
+      _.size(selectedComps) === 1 &&
+      isContainer((comp as GridItemComp)?.children?.comp)
+    ) {
       return comp.children.comp;
     }
 
@@ -307,7 +341,9 @@ export class EditorState {
   isCompSelected(compName: string): OptionalComp {
     const compMap = this.getAllCompMap();
     return Object.values(compMap).find(
-      (item) => item.children.name.getView() === compName && this.selectedCompNames.has(compName)
+      (item) =>
+        item.children.name.getView() === compName &&
+        this.selectedCompNames.has(compName)
     );
   }
 
@@ -319,6 +355,10 @@ export class EditorState {
     this.changeState({ editorModeStatus: newEditorModeStatus });
   }
 
+  setCollissionStatus(newCollissionStatus: string) {
+    this.changeState({ collissionStatus: newCollissionStatus });
+  }
+
   setDragging(dragging: boolean) {
     if (this.isDragging === dragging) {
       return;
@@ -356,7 +396,10 @@ export class EditorState {
     });
   }
 
-  setSelectedCompNames(selectedCompNames: Set<string>, selectSource?: SelectSourceType) {
+  setSelectedCompNames(
+    selectedCompNames: Set<string>,
+    selectSource?: SelectSourceType
+  ) {
     if (selectedCompNames.size === 0 && this.selectedCompNames.size === 0) {
       return;
     }
@@ -406,7 +449,9 @@ export class EditorState {
   }
 
   getBottomResComp(name: string): BottomResComp | undefined {
-    const bottomResComps = Object.values(BottomResTypeEnum).reduce<BottomResComp[]>((a, b) => {
+    const bottomResComps = Object.values(BottomResTypeEnum).reduce<
+      BottomResComp[]
+    >((a, b) => {
       const items = this.getBottomResListComp(b).items();
       return a.concat(items);
     }, []);
@@ -467,8 +512,10 @@ export class EditorState {
   getAppType(): UiLayoutType {
     return this.getUIComp().children.compType.getView();
   }
+  getCollissionStatus(): string {
+    return this.collissionStatus;
+  }
 }
-
 export const EditorContext = React.createContext<EditorState>(undefined as any);
 
 // current comp name
diff --git a/client/packages/lowcoder/src/pages/common/header.tsx b/client/packages/lowcoder/src/pages/common/header.tsx
index 0b80f0b73b..108076d3e9 100644
--- a/client/packages/lowcoder/src/pages/common/header.tsx
+++ b/client/packages/lowcoder/src/pages/common/header.tsx
@@ -2,8 +2,13 @@ import { Dropdown, Skeleton, Radio, RadioChangeEvent } from "antd";
 import LayoutHeader from "components/layout/Header";
 import { SHARE_TITLE } from "constants/apiConstants";
 import { AppTypeEnum } from "constants/applicationConstants";
-import { ALL_APPLICATIONS_URL, AUTH_LOGIN_URL, preview } from "constants/routesURL";
+import {
+  ALL_APPLICATIONS_URL,
+  AUTH_LOGIN_URL,
+  preview,
+} from "constants/routesURL";
 import { User } from "constants/userConstants";
+import { Switch } from "antd";
 import {
   CommonTextLabel,
   CustomModal,
@@ -21,8 +26,14 @@ import { trans } from "i18n";
 import dayjs from "dayjs";
 import { useContext, useState } from "react";
 import { useDispatch, useSelector } from "react-redux";
-import { publishApplication, updateAppMetaAction } from "redux/reduxActions/applicationActions";
-import { recoverSnapshotAction, setShowAppSnapshot } from "redux/reduxActions/appSnapshotActions";
+import {
+  publishApplication,
+  updateAppMetaAction,
+} from "redux/reduxActions/applicationActions";
+import {
+  recoverSnapshotAction,
+  setShowAppSnapshot,
+} from "redux/reduxActions/appSnapshotActions";
 import { currentApplication } from "redux/selectors/applicationSelector";
 import {
   getSelectedAppSnapshot,
@@ -40,8 +51,8 @@ import { HeaderStartDropdown } from "./headerStartDropdown";
 import { AppPermissionDialog } from "../../components/PermissionDialog/AppPermissionDialog";
 import { getBrandingConfig } from "../../redux/selectors/configSelectors";
 import { messageInstance } from "lowcoder-design";
-import { EditorContext } from  "../../comps/editorState";
-
+import { EditorContext } from "../../comps/editorState";
+import { SwitchChangeEventHandler } from "antd/es/switch";
 
 const StyledLink = styled.a`
   display: flex;
@@ -157,13 +168,13 @@ const GrayBtn = styled(TacoButton)`
     margin-right: 8px;
     cursor: pointer;
     --antd-wave-shadow-color: #8b8fa34c;
-  
+
     &:hover {
       background: #666666;
       color: #ffffff;
       border: none;
     }
-  
+
     &:focus {
       background: #666666;
       color: #ffffff;
@@ -259,7 +270,10 @@ function HeaderProfile(props: { user: User }) {
   return (
     <div>
       {user.isAnonymous ? (
-        <LoginBtn buttonType="primary" onClick={() => history.push(AUTH_LOGIN_URL)}>
+        <LoginBtn
+          buttonType="primary"
+          onClick={() => history.push(AUTH_LOGIN_URL)}
+        >
           {trans("userAuth.login")}
         </LoginBtn>
       ) : (
@@ -271,21 +285,29 @@ function HeaderProfile(props: { user: User }) {
 
 export type PanelStatus = { left: boolean; bottom: boolean; right: boolean };
 export type TogglePanel = (panel?: keyof PanelStatus) => void;
+export type EnabledCollissionStatus = "true" | "false";
 export type EditorModeStatus = "layout" | "logic" | "both";
-export type ToggleEditorModeStatus = (editorModeStatus?: EditorModeStatus) => void;
+export type ToggleEditorModeStatus = (
+  editorModeStatus?: EditorModeStatus
+) => void;
+export type ToggleCollissionStatus = (
+  collissionStatus?: EnabledCollissionStatus
+) => void;
 
 type HeaderProps = {
   panelStatus: PanelStatus;
   togglePanel: TogglePanel;
   editorModeStatus: EditorModeStatus;
   toggleEditorModeStatus: ToggleEditorModeStatus;
+  collissionStatus: EnabledCollissionStatus;
+  toggleCollissionStatus: ToggleCollissionStatus;
 };
 
 // header in editor page
 export default function Header(props: HeaderProps) {
   const editorState = useContext(EditorContext);
   const { togglePanel } = props;
-  const { toggleEditorModeStatus } = props;
+  const { toggleEditorModeStatus, toggleCollissionStatus } = props;
   const { left, bottom, right } = props.panelStatus;
   const user = useSelector(getUser);
   const application = useSelector(currentApplication);
@@ -301,16 +323,49 @@ export default function Header(props: HeaderProps) {
   const isModule = appType === AppTypeEnum.Module;
 
   const editorModeOptions = [
-    { label: trans("header.editorMode_layout"), key: "editorModeSelector_layout", value: "layout" },
-    { label: trans("header.editorMode_logic"), key: "editorModeSelector_logic", value: "logic" },
-    { label: trans("header.editorMode_both"), key: "editorModeSelector_both", value: "both" },
+    {
+      label: trans("header.editorMode_layout"),
+      key: "editorModeSelector_layout",
+      value: "layout",
+    },
+    {
+      label: trans("header.editorMode_logic"),
+      key: "editorModeSelector_logic",
+      value: "logic",
+    },
+    {
+      label: trans("header.editorMode_both"),
+      key: "editorModeSelector_both",
+      value: "both",
+    },
   ];
-  
-  const onEditorStateValueChange = ({ target: { value } }: RadioChangeEvent) => {
+
+  // const collissionOptions = [
+  //   {
+  //     label: trans("header.editorMode_layout"),
+  //     key: "editorModeSelector_layout",
+  //     value: "tru",
+  //   },
+  //   {
+  //     label: trans("header.editorMode_logic"),
+  //     key: "editorModeSelector_logic",
+  //     value: "logic", 
+  //   },
+  //   {
+  //     label: trans("header.editorMode_both"),
+  //     key: "editorModeSelector_both",
+  //     value: "both",
+  //   },
+  // ];
+
+  const onEditorStateValueChange = ({
+    target: { value },
+  }: RadioChangeEvent) => {
     toggleEditorModeStatus(value);
     editorState.setEditorModeStatus(value);
   };
-  
+
+
   const headerStart = (
     <>
       <StyledLink onClick={() => history.push(ALL_APPLICATIONS_URL)}>
@@ -330,7 +385,12 @@ export default function Header(props: HeaderProps) {
                 messageInstance.warning(trans("header.nameCheckMessage"));
                 return;
               }
-              dispatch(updateAppMetaAction({ applicationId: applicationId, name: value }));
+              dispatch(
+                updateAppMetaAction({
+                  applicationId: applicationId,
+                  name: value,
+                })
+              );
               setEditName(false);
             }}
           />
@@ -343,15 +403,34 @@ export default function Header(props: HeaderProps) {
           }}
         />
       )}
-      {showAppSnapshot && <ViewOnlyLabel>{trans("header.viewOnly")}</ViewOnlyLabel>}
+      {showAppSnapshot && (
+        <ViewOnlyLabel>{trans("header.viewOnly")}</ViewOnlyLabel>
+      )}
     </>
   );
 
-  // key={option.key}
-
   const headerMiddle = (
-    <> 
-      <Radio.Group onChange={onEditorStateValueChange} value={props.editorModeStatus} optionType="button" buttonStyle="solid" size="small">
+    <>
+      <>
+        <p style={{ color: "#ffffff", marginTop: "10px" }}>
+          Layers 
+        </p>
+        <Switch
+          checked={props.collissionStatus == "true"}
+          disabled={false}
+          onChange={(value: any) => {
+            toggleCollissionStatus(value == true ? "true" : "false");
+            editorState.setCollissionStatus(value == true ? "true" : "false");
+          }}
+        />
+      </>
+      <Radio.Group
+        onChange={onEditorStateValueChange}
+        value={props.editorModeStatus}
+        optionType="button"
+        buttonStyle="solid"
+        size="small"
+      >
         {editorModeOptions.map((option) => (
           <Radio.Button key={option.key} value={option.value}>
             {option.label}
@@ -377,7 +456,9 @@ export default function Header(props: HeaderProps) {
               CustomModal.confirm({
                 title: trans("header.recoverAppSnapshotTitle"),
                 content: trans("header.recoverAppSnapshotContent", {
-                  time: dayjs(selectedSnapshot.createTime).format("YYYY-MM-DD HH:mm"),
+                  time: dayjs(selectedSnapshot.createTime).format(
+                    "YYYY-MM-DD HH:mm"
+                  ),
                 }),
                 onConfirm: () => {
                   dispatch(
@@ -409,11 +490,15 @@ export default function Header(props: HeaderProps) {
         <AppPermissionDialog
           applicationId={applicationId}
           visible={permissionDialogVisible}
-          onVisibleChange={(visible) => !visible && setPermissionDialogVisible(false)}
+          onVisibleChange={(visible) =>
+            !visible && setPermissionDialogVisible(false)
+          }
         />
       )}
       {canManageApp(user, application) && (
-        <GrayBtn onClick={() => setPermissionDialogVisible(true)}>{SHARE_TITLE}</GrayBtn>
+        <GrayBtn onClick={() => setPermissionDialogVisible(true)}>
+          {SHARE_TITLE}
+        </GrayBtn>
       )}
       <PreviewBtn buttonType="primary" onClick={() => preview(applicationId)}>
         {trans("header.preview")}
@@ -436,11 +521,15 @@ export default function Header(props: HeaderProps) {
             items={[
               {
                 key: "deploy",
-                label: <CommonTextLabel>{trans("header.deploy")}</CommonTextLabel>,
+                label: (
+                  <CommonTextLabel>{trans("header.deploy")}</CommonTextLabel>
+                ),
               },
               {
                 key: "snapshot",
-                label: <CommonTextLabel>{trans("header.snapshot")}</CommonTextLabel>,
+                label: (
+                  <CommonTextLabel>{trans("header.snapshot")}</CommonTextLabel>
+                ),
               },
             ]}
           />
@@ -456,7 +545,11 @@ export default function Header(props: HeaderProps) {
   );
 
   return (
-    <LayoutHeader headerStart={headerStart} headerMiddle={headerMiddle} headerEnd={headerEnd} />
+    <LayoutHeader
+      headerStart={headerStart}
+      headerMiddle={headerMiddle}
+      headerEnd={headerEnd}
+    />
   );
 }
 
@@ -475,7 +568,9 @@ export function AppHeader() {
     <LayoutHeader
       headerStart={headerStart}
       headerEnd={headerEnd}
-      style={user.orgDev ? {} : { backgroundColor: brandingConfig?.headerColor }}
+      style={
+        user.orgDev ? {} : { backgroundColor: brandingConfig?.headerColor }
+      }
     />
   );
 }
diff --git a/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx b/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx
index e1a1766ad3..aa036d57c1 100644
--- a/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx
+++ b/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx
@@ -7,7 +7,7 @@ import {
   LeftPanel,
   MiddlePanel,
 } from "pages/common/styledComponent";
-import { getPanelStatus, getEditorModeStatus, getPanelStyle } from "util/localStorageUtil";
+import { getPanelStatus, getEditorModeStatus, getPanelStyle, getCollissionStatus } from "util/localStorageUtil";
 import { BottomSkeleton } from "pages/editor/bottom/BottomContent";
 import RightPanel from "pages/editor/right/RightPanel";
 import _ from "lodash";
@@ -47,6 +47,7 @@ export const EditorLoadingSpin = (props: { height?: string | number }) => {
 export default function EditorSkeletonView() {
   const panelStatus = getPanelStatus();
   const editorModeStatus = getEditorModeStatus();
+  const collissionStatus = getCollissionStatus();
   const panelStyle = getPanelStyle();
   const isUserViewMode = useUserViewMode();
   const isTemplate = useTemplateViewMode();
@@ -58,7 +59,14 @@ export default function EditorSkeletonView() {
   return (
     <>
       <Height100Div>
-        <Header panelStatus={panelStatus} togglePanel={_.noop} editorModeStatus={editorModeStatus} toggleEditorModeStatus={_.noop} />
+        <Header
+          panelStatus={panelStatus}
+          togglePanel={_.noop}
+          collissionStatus={collissionStatus}
+          toggleCollissionStatus={_.noop}
+          editorModeStatus={editorModeStatus}
+          toggleEditorModeStatus={_.noop}
+        />
         <Body>
           <SiderStyled />
           {panelStatus.left && (
@@ -77,7 +85,11 @@ export default function EditorSkeletonView() {
             )}
           </MiddlePanel>
           {panelStatus.right && (
-            <RightPanel showPropertyPane={false} onCompDrag={_.noop} onTabChange={_.noop} />
+            <RightPanel
+              showPropertyPane={false}
+              onCompDrag={_.noop}
+              onTabChange={_.noop}
+            />
           )}
         </Body>
       </Height100Div>
diff --git a/client/packages/lowcoder/src/pages/editor/editorView.tsx b/client/packages/lowcoder/src/pages/editor/editorView.tsx
index a63c2ad2fa..d82a0b6181 100644
--- a/client/packages/lowcoder/src/pages/editor/editorView.tsx
+++ b/client/packages/lowcoder/src/pages/editor/editorView.tsx
@@ -8,9 +8,21 @@ import { Layers } from "constants/Layers";
 import { TopHeaderHeight } from "constants/style";
 import { trans } from "i18n";
 import { draggingUtils } from "layout";
-import { LeftPreloadIcon, LeftSettingIcon, LeftStateIcon, ScrollBar } from "lowcoder-design";
+import {
+  LeftPreloadIcon,
+  LeftSettingIcon,
+  LeftStateIcon,
+  ScrollBar,
+} from "lowcoder-design";
 import { useTemplateViewMode } from "util/hooks";
-import Header, { PanelStatus, TogglePanel, EditorModeStatus, ToggleEditorModeStatus } from "pages/common/header";
+import Header, {
+  PanelStatus,
+  TogglePanel,
+  EditorModeStatus,
+  ToggleEditorModeStatus,
+  EnabledCollissionStatus,
+  ToggleCollissionStatus,
+} from "pages/common/header";
 import { HelpDropdown } from "pages/common/help";
 import { PreviewHeader } from "pages/common/previewHeader";
 import {
@@ -28,8 +40,19 @@ import {
 } from "pages/editor/editorHotKeys";
 import RightPanel from "pages/editor/right/RightPanel";
 import EditorTutorials from "pages/tutorials/editorTutorials";
-import { editorContentClassName, UserGuideLocationState } from "pages/tutorials/tutorialsConstant";
-import React, { useCallback, useContext, useEffect, useLayoutEffect, useMemo, useState } from "react";
+import {
+  CollisionState,
+  editorContentClassName,
+  UserGuideLocationState,
+} from "pages/tutorials/tutorialsConstant";
+import React, {
+  useCallback,
+  useContext,
+  useEffect,
+  useLayoutEffect,
+  useMemo,
+  useState,
+} from "react";
 import { Helmet } from "react-helmet";
 import { useDispatch, useSelector } from "react-redux";
 import { useLocation } from "react-router-dom";
@@ -38,7 +61,17 @@ import { currentApplication } from "redux/selectors/applicationSelector";
 import { showAppSnapshotSelector } from "redux/selectors/appSnapshotSelector";
 import styled from "styled-components";
 import { ExternalEditorContext } from "util/context/ExternalEditorContext";
-import { DefaultPanelStatus, getPanelStatus, savePanelStatus, DefaultEditorModeStatus, getEditorModeStatus, saveEditorModeStatus } from "util/localStorageUtil";
+import {
+  DefaultPanelStatus,
+  getPanelStatus,
+  savePanelStatus,
+  DefaultEditorModeStatus,
+  getEditorModeStatus,
+  saveEditorModeStatus,
+  saveEnableCollissionStatus,
+  getCollissionStatus,
+  DefaultCollissionStatus,
+} from "util/localStorageUtil";
 import Bottom from "./bottom/BottomPanel";
 import { LeftContent } from "./LeftContent";
 import { isAggregationApp } from "util/appUtils";
@@ -179,14 +212,15 @@ const items = [
   },
 ];
 
-
 function EditorView(props: EditorViewProps) {
   const { uiComp } = props;
   const editorState = useContext(EditorContext);
   const { readOnly, hideHeader } = useContext(ExternalEditorContext);
   const application = useSelector(currentApplication);
   const locationState = useLocation<UserGuideLocationState>().state;
+  const collisionState = useLocation<CollisionState>().state;
   const showNewUserGuide = locationState?.showNewUserGuide;
+  const showCollission = collisionState?.collission;
   const showAppSnapshot = useSelector(showAppSnapshotSelector);
   const [showShortcutList, setShowShortcutList] = useState(false);
   const toggleShortcutList = useCallback(
@@ -201,8 +235,9 @@ function EditorView(props: EditorViewProps) {
     return showNewUserGuide ? DefaultPanelStatus : getPanelStatus();
   });
 
-  const [prePanelStatus, setPrePanelStatus] = useState<PanelStatus>(DefaultPanelStatus);
-  
+  const [prePanelStatus, setPrePanelStatus] =
+    useState<PanelStatus>(DefaultPanelStatus);
+
   const togglePanel: TogglePanel = useCallback(
     (key) => {
       let newPanelStatus;
@@ -223,23 +258,32 @@ function EditorView(props: EditorViewProps) {
     [panelStatus, prePanelStatus]
   );
 
+  // added by Fred  to set comp collision state
+  const [collisionStatus, setCollisionStatus] = useState(() => {
+    return showCollission ? DefaultCollissionStatus : getCollissionStatus();
+  });
+
+  const toggleCollissionStatus: ToggleCollissionStatus = useCallback(
+    (value) => {
+      setCollisionStatus(value ? value : "false");
+      saveEnableCollissionStatus(value ? value : "false");
+    },
+    [collisionStatus]
+  );
 
   // added by Falk Wolsky to support a Layout and Logic Mode in Lowcoder
   const [editorModeStatus, setEditorModeStatus] = useState(() => {
     return showNewUserGuide ? DefaultEditorModeStatus : getEditorModeStatus();
   });
-  
-  const toggleEditorModeStatus: ToggleEditorModeStatus = useCallback( (value) => {
 
-      setEditorModeStatus(value ? value : "both" as EditorModeStatus);
-      saveEditorModeStatus(value ? value : "both" as EditorModeStatus);
-        
+  const toggleEditorModeStatus: ToggleEditorModeStatus = useCallback(
+    (value) => {
+      setEditorModeStatus(value ? value : ("both" as EditorModeStatus));
+      saveEditorModeStatus(value ? value : ("both" as EditorModeStatus));
     },
     [editorModeStatus]
   );
 
-
-  
   const onCompDrag = useCallback(
     (dragCompKey: string) => {
       editorState.setDraggingCompType(dragCompKey);
@@ -267,7 +311,8 @@ function EditorView(props: EditorViewProps) {
       setHeight(window.innerHeight);
     }
 
-    const eventType = "orientationchange" in window ? "orientationchange" : "resize";
+    const eventType =
+      "orientationchange" in window ? "orientationchange" : "resize";
     window.addEventListener(eventType, updateSize);
     updateSize();
     return () => window.removeEventListener(eventType, updateSize);
@@ -293,7 +338,9 @@ function EditorView(props: EditorViewProps) {
           <ViewBody hideBodyHeader={hideBodyHeader} height={height}>
             {uiComp.getView()}
           </ViewBody>
-          <div style={{ zIndex: Layers.hooksCompContainer }}>{hookCompViews}</div>
+          <div style={{ zIndex: Layers.hooksCompContainer }}>
+            {hookCompViews}
+          </div>
         </EditorContainerWithViewMode>
       </CustomShortcutWrapper>
     );
@@ -329,7 +376,14 @@ function EditorView(props: EditorViewProps) {
         draggingUtils.clearData();
       }}
     >
-      <Header togglePanel={togglePanel} panelStatus={panelStatus} toggleEditorModeStatus={toggleEditorModeStatus} editorModeStatus={editorModeStatus}  />
+      <Header
+        togglePanel={togglePanel}
+        panelStatus={panelStatus}
+        toggleEditorModeStatus={toggleEditorModeStatus}
+        toggleCollissionStatus={toggleCollissionStatus}
+        editorModeStatus={editorModeStatus}
+        collissionStatus={collisionStatus}
+      />
       <Helmet>{application && <title>{application.name}</title>}</Helmet>
       {showNewUserGuide && <EditorTutorials />}
       <EditorGlobalHotKeys
@@ -369,7 +423,9 @@ function EditorView(props: EditorViewProps) {
                 <SettingsDiv>
                   <ScrollBar>
                     {application &&
-                      !isAggregationApp(AppUILayoutType[application.applicationType]) && (
+                      !isAggregationApp(
+                        AppUILayoutType[application.applicationType]
+                      ) && (
                         <>
                           {appSettingsComp.getPropertyView()}
                           <Divider />
@@ -379,7 +435,11 @@ function EditorView(props: EditorViewProps) {
                     {props.preloadComp.getPropertyView()}
                     <PreloadDiv
                       onClick={() =>
-                        dispatch(setEditorExternalStateAction({ showScriptsAndStyleModal: true }))
+                        dispatch(
+                          setEditorExternalStateAction({
+                            showScriptsAndStyleModal: true,
+                          })
+                        )
                       }
                     >
                       <LeftPreloadIcon />
diff --git a/client/packages/lowcoder/src/pages/tutorials/tutorialsConstant.tsx b/client/packages/lowcoder/src/pages/tutorials/tutorialsConstant.tsx
index 147327178c..550f072141 100644
--- a/client/packages/lowcoder/src/pages/tutorials/tutorialsConstant.tsx
+++ b/client/packages/lowcoder/src/pages/tutorials/tutorialsConstant.tsx
@@ -31,3 +31,8 @@ export const defaultJoyrideFloaterProps: FloaterType = {
 export type UserGuideLocationState = {
   showNewUserGuide?: boolean;
 };
+
+export type CollisionState = {
+  showNewUserGuide?: boolean;
+  collission?: boolean;
+};
diff --git a/client/packages/lowcoder/src/util/localStorageUtil.ts b/client/packages/lowcoder/src/util/localStorageUtil.ts
index 2d06ddd200..c6ee587ad2 100644
--- a/client/packages/lowcoder/src/util/localStorageUtil.ts
+++ b/client/packages/lowcoder/src/util/localStorageUtil.ts
@@ -1,4 +1,4 @@
-import { PanelStatus } from "pages/common/header";
+import { EnabledCollissionStatus, PanelStatus } from "pages/common/header";
 import { EditorModeStatus } from "pages/common/header";
 import log from "loglevel";
 import { JSONValue } from "util/jsonTypes";
@@ -19,7 +19,6 @@ export const DefaultPanelStatus: PanelStatus = {
   right: true,
 };
 
-
 const DefaultPanelStyle: PanelStyle = {
   bottom: {
     h: 285,
@@ -42,12 +41,26 @@ export function getPanelStatus(): PanelStatus {
   return { ...DefaultPanelStatus, ...JSON.parse(str) };
 }
 
-
 export function saveEditorModeStatus(editorModeStatus: EditorModeStatus) {
   localStorage.setItem("editor_mode_status", editorModeStatus);
 }
+//ADDED BY FRED TO SAVE enabledCollission
+export function saveEnableCollissionStatus(
+  collisionStatus: EnabledCollissionStatus
+) {
+  localStorage.setItem("enable_collission", collisionStatus);
+}
+
+export const DefaultCollissionStatus: EnabledCollissionStatus = "true";
+export function getCollissionStatus(): EnabledCollissionStatus {
+  const str = localStorage.getItem("enable_collission");
+  if (!str) {
+    return DefaultCollissionStatus;
+  }
+  return str as EnabledCollissionStatus;
+}
 
-export const DefaultEditorModeStatus: EditorModeStatus = "both"; 
+export const DefaultEditorModeStatus: EditorModeStatus = "both";
 export function getEditorModeStatus(): EditorModeStatus {
   const str = localStorage.getItem("editor_mode_status");
   if (!str) {

From 3856adcf50558149ccea748d44dcbcfafaece866 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Wed, 17 Jan 2024 14:46:54 +0500
Subject: [PATCH 05/97] fix table docs

---
 client/packages/lowcoder/src/i18n/locales/en.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index f898766946..f572227cd5 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -2573,7 +2573,7 @@ export const en = {
     "selectBackground": "Selected Background"
   },
   "componentDocExtra": {
-    "table": "Additional Documentation for Table Component"
+    table,
   },
   "idSource": {
     "title": "OAuth Providers",

From 788b3ada46d2f0cf9a6e501385482e7e56af77fa Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Wed, 17 Jan 2024 19:19:21 +0500
Subject: [PATCH 06/97] fix custom component

---
 .../lowcoder/src/comps/comps/customComp/customComp.tsx        | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/customComp/customComp.tsx b/client/packages/lowcoder/src/comps/comps/customComp/customComp.tsx
index 990f5b0729..fafb3f7f5d 100644
--- a/client/packages/lowcoder/src/comps/comps/customComp/customComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/customComp/customComp.tsx
@@ -12,7 +12,6 @@ import { EventData, EventTypeEnum } from "./types";
 import { hiddenPropertyView } from "comps/utils/propertyUtils";
 import { trans } from "i18n";
 import { EditorContext } from "comps/editorState";
-import * as ReactDOMClient from 'react-dom/client';
 
 // TODO: eventually to embedd in container so we have styling?
 // TODO: support different starter templates for different frameworks (react, ANT, Flutter, Angular, etc)
@@ -60,8 +59,7 @@ const defaultCode = `
   );
   
   const ConnectedComponent = ${trans("customComp.sdkGlobalVarName")}.connect(MyCustomComponent);
-  const container = document.getElementById('root');
-  const root = ReactDOMClient.createRoot(container);
+  const root = ReactDOM.createRoot(document.getElementById("root"));
   root.render(<ConnectedComponent />);
   
   </script>

From d19c210ef6de3a4cc36e33bb9b168c2d1aca5067 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Fri, 19 Jan 2024 15:58:53 +0500
Subject: [PATCH 07/97] fix rerendering apps in sdk

---
 client/packages/lowcoder-sdk/index.tsx                   | 5 ++++-
 client/packages/lowcoder-sdk/package.json                | 2 +-
 client/packages/lowcoder/src/appView/AppViewInstance.tsx | 7 +++----
 client/packages/lowcoder/src/appView/bootstrapAt.tsx     | 3 ++-
 4 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/client/packages/lowcoder-sdk/index.tsx b/client/packages/lowcoder-sdk/index.tsx
index 4ff48c510e..54fc1bb97f 100644
--- a/client/packages/lowcoder-sdk/index.tsx
+++ b/client/packages/lowcoder-sdk/index.tsx
@@ -1,5 +1,6 @@
 import { useRef } from "react";
 import ReactDOM, { flushSync } from "react-dom";
+import { createRoot } from "react-dom/client";
 import { AppViewInstance, bootstrapAppAt, LowcoderAppView } from "./src/index";
 
 const url = new URL(location.href);
@@ -70,7 +71,9 @@ async function bootstrap() {
   });
 
   // React
-  ReactDOM.render(<ReactDemoApp />, document.querySelector("#app2"));
+  const container = document.querySelector("#app2");
+  const root = createRoot(container!);
+  root.render(<ReactDemoApp />);
 }
 
 bootstrap();
diff --git a/client/packages/lowcoder-sdk/package.json b/client/packages/lowcoder-sdk/package.json
index 88b06a6489..36583cdcf7 100644
--- a/client/packages/lowcoder-sdk/package.json
+++ b/client/packages/lowcoder-sdk/package.json
@@ -1,6 +1,6 @@
 {
   "name": "lowcoder-sdk",
-  "version": "2.3.0",
+  "version": "2.3.1",
   "type": "module",
   "files": [
     "src",
diff --git a/client/packages/lowcoder/src/appView/AppViewInstance.tsx b/client/packages/lowcoder/src/appView/AppViewInstance.tsx
index b9e8457bed..4163ddfff3 100644
--- a/client/packages/lowcoder/src/appView/AppViewInstance.tsx
+++ b/client/packages/lowcoder/src/appView/AppViewInstance.tsx
@@ -4,7 +4,7 @@ import { RootComp } from "comps/comps/rootComp";
 import { setGlobalSettings } from "comps/utils/globalSettings";
 import { sdkConfig } from "constants/sdkConfig";
 import _ from "lodash";
-import { createRoot } from "react-dom/client";
+import { Root } from "react-dom/client";
 import { StyleSheetManager } from "styled-components";
 import { ModuleDSL, ModuleDSLIoInput } from "types/dsl";
 import { AppView } from "./AppView";
@@ -40,7 +40,7 @@ export class AppViewInstance<I = any, O = any> {
     webUrl: "https://app.lowcoder.cloud",
   };
 
-  constructor(private appId: string, private node: Element, options: AppViewInstanceOptions = {}) {
+  constructor(private appId: string, private node: Element, private root: Root, options: AppViewInstanceOptions = {}) {
     Object.assign(this.options, options);
     if (this.options.baseUrl) {
       sdkConfig.baseURL = this.options.baseUrl;
@@ -137,8 +137,7 @@ export class AppViewInstance<I = any, O = any> {
 
   private async render() {
     const data = await this.dataPromise;
-    const root = createRoot(this.node);
-    root.render(
+    this.root.render(
       <StyleSheetManager target={this.node as HTMLElement}>
         <AppView
           appId={this.appId}
diff --git a/client/packages/lowcoder/src/appView/bootstrapAt.tsx b/client/packages/lowcoder/src/appView/bootstrapAt.tsx
index b4fccbd545..b7dba8e9d8 100644
--- a/client/packages/lowcoder/src/appView/bootstrapAt.tsx
+++ b/client/packages/lowcoder/src/appView/bootstrapAt.tsx
@@ -1,5 +1,6 @@
 import { loadComps } from "comps";
 import { AppViewInstance, AppViewInstanceOptions } from "./AppViewInstance";
+import { createRoot } from "react-dom/client";
 
 loadComps();
 
@@ -12,5 +13,5 @@ export async function bootstrapAppAt<I>(
     console.error("node must be not null.");
     return;
   }
-  return new AppViewInstance(appId, node, options);
+  return new AppViewInstance(appId, node, createRoot(node), options);
 }

From 951b904c9b9452a6b6d51a4bf4519edd8e3e6912 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Fri, 19 Jan 2024 18:15:08 +0500
Subject: [PATCH 08/97] fix repositoryUrl check in workflows

---
 .github/workflows/publish-lowcoder-cli.yml   | 2 +-
 .github/workflows/publish-lowcoder-comps.yml | 2 +-
 .github/workflows/publish-lowcoder-core.yml  | 2 +-
 .github/workflows/publish-lowcoder-sdk.yml   | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/publish-lowcoder-cli.yml b/.github/workflows/publish-lowcoder-cli.yml
index 2aadbe4889..f7b325e6f4 100644
--- a/.github/workflows/publish-lowcoder-cli.yml
+++ b/.github/workflows/publish-lowcoder-cli.yml
@@ -9,7 +9,7 @@ on:
 
 jobs:
   publish-package:
-    if: ${{ github.repositoryUrl == 'git://github.com/lowcoder/lowcoder.git'}}
+    if: ${{ github.repositoryUrl == 'git://github.com/lowcoder-org/lowcoder.git'}}
     runs-on: ubuntu-latest
     steps:
       - name: Checkout repository
diff --git a/.github/workflows/publish-lowcoder-comps.yml b/.github/workflows/publish-lowcoder-comps.yml
index 27ffb60f9e..a83425cf5e 100644
--- a/.github/workflows/publish-lowcoder-comps.yml
+++ b/.github/workflows/publish-lowcoder-comps.yml
@@ -9,7 +9,7 @@ on:
 
 jobs:
   publish-package:
-    if: ${{ github.repositoryUrl == 'git://github.com/lowcoder/lowcoder.git'}}
+    if: ${{ github.repositoryUrl == 'git://github.com/lowcoder-org/lowcoder.git'}}
     runs-on: ubuntu-latest
     steps:
       - name: Checkout repository
diff --git a/.github/workflows/publish-lowcoder-core.yml b/.github/workflows/publish-lowcoder-core.yml
index 34222ad56e..7fb0b1cd78 100644
--- a/.github/workflows/publish-lowcoder-core.yml
+++ b/.github/workflows/publish-lowcoder-core.yml
@@ -9,7 +9,7 @@ on:
 
 jobs:
   publish-package:
-    if: ${{ github.repositoryUrl == 'git://github.com/lowcoder/lowcoder.git'}}
+    if: ${{ github.repositoryUrl == 'git://github.com/lowcoder-org/lowcoder.git'}}
     runs-on: ubuntu-latest
     steps:
       - name: Checkout repository
diff --git a/.github/workflows/publish-lowcoder-sdk.yml b/.github/workflows/publish-lowcoder-sdk.yml
index d9385b7d98..a597071bac 100644
--- a/.github/workflows/publish-lowcoder-sdk.yml
+++ b/.github/workflows/publish-lowcoder-sdk.yml
@@ -9,7 +9,7 @@ on:
 
 jobs:
   publish-package:
-    if: ${{ github.repositoryUrl == 'git://github.com/lowcoder/lowcoder.git'}}
+    if: ${{ github.repositoryUrl == 'git://github.com/lowcoder-org/lowcoder.git'}}
     runs-on: ubuntu-latest
     steps:
       - name: Checkout repository

From 54cf4db6803cf6d3bf989f42afb99524df8b0ab5 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Fri, 19 Jan 2024 18:15:22 +0500
Subject: [PATCH 09/97] fix styles for sortable column header

---
 .../comps/comps/tableComp/column/tableColumnComp.tsx  |  4 ++--
 .../src/comps/comps/tableComp/tableCompView.tsx       | 11 +++++++----
 .../lowcoder/src/comps/controls/styleControl.tsx      |  2 +-
 3 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
index ac113e8493..39a392ad4c 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
@@ -106,7 +106,7 @@ export const columnChildrenMap = {
   borderWidth: withDefault(RadiusControl, ""),
   radius: withDefault(RadiusControl, ""),
   textSize: withDefault(RadiusControl, ""),
-  textWeight: withDefault(StringControl, "regular"),
+  textWeight: withDefault(StringControl, "normal"),
   fontFamily: withDefault(StringControl, "sans-serif"),
   cellColor: CellColorComp,
   textOverflow: withDefault(TextOverflowControl, "ellipsis"),
@@ -276,7 +276,7 @@ export class ColumnComp extends ColumnInitComp {
         {this.children.textWeight.propertyView({
           label: trans('style.textWeight'),
           preInputNode: <StyledTextWeightIcon as={TextWeigthIcon} title="" />,	
-          placeholder: 'regular',
+          placeholder: 'normal',
         })}
         {this.children.fontFamily.propertyView({
           label: trans('style.fontFamily'),
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
index a398f0060e..729e8f6b9c 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
@@ -212,9 +212,6 @@ const TableWrapper = styled.div<{
             border-color: ${(props) => props.$headerStyle.border};
             border-width: ${(props) => props.$headerStyle.borderWidth};
             color: ${(props) => props.$headerStyle.headerText};
-            font-size: ${(props) => props.$headerStyle.textSize};
-            font-weight: ${(props) => props.$headerStyle.textWeight};
-            font-family: ${(props) => props.$headerStyle.fontFamily};
             border-inline-end: ${(props) => `${props.$headerStyle.borderWidth} solid ${props.$headerStyle.border}`} !important;
             ${(props) => 
               props.$fixedHeader && `
@@ -227,6 +224,12 @@ const TableWrapper = styled.div<{
 
             > div {
               margin: ${(props) => props.$headerStyle.margin};
+
+              &, .ant-table-column-title > div {
+                font-size: ${(props) => props.$headerStyle.textSize};
+                font-weight: ${(props) => props.$headerStyle.textWeight};
+                font-family: ${(props) => props.$headerStyle.fontFamily};
+              }
             }
 
             &:last-child {
@@ -516,7 +519,7 @@ function TableCellView(props: {
     const cellColor = cellColorFn({
       currentCell: record[title.toLowerCase()],
     });
-  
+    
     const style = {
       background: cellColor || rowColor || columnStyle.background || columnsStyle.background,
       margin: columnStyle.margin || columnsStyle.margin,
diff --git a/client/packages/lowcoder/src/comps/controls/styleControl.tsx b/client/packages/lowcoder/src/comps/controls/styleControl.tsx
index 6a13911713..669c450e3e 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControl.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControl.tsx
@@ -393,7 +393,7 @@ function calcColors<ColorMap extends Record<string, string>>(
     }
     if (isTextWeightConfig(config)) {
       // TODO: remove default textWeight after added in theme in backend.
-      res[name] = themeWithDefault[config.textWeight] || 'regular';
+      res[name] = themeWithDefault[config.textWeight] || 'normal';
     }
     if (isFontFamilyConfig(config)) {
       res[name] = themeWithDefault[config.fontFamily] || 'sans-serif';

From f341397ffdec712c26c7578ac6dbe6e94cba5bbf Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Fri, 19 Jan 2024 19:51:39 +0500
Subject: [PATCH 10/97] adding background styles in container

---
 .../comps/controls/styleControlConstants.tsx  | 113 +++++-------------
 1 file changed, 33 insertions(+), 80 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index 2ebd7a28a8..5dea81d301 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -510,6 +510,38 @@ export const ContainerStyle = [
   BORDER_WIDTH,
   MARGIN,	
   PADDING,
+  {
+    name: "background",
+    label: trans("style.background"),
+    depName: "background",
+    depType: DEP_TYPE.SELF,
+    transformer: toSelf,
+  },
+  {
+    name: "backgroundImage",
+    label: trans("style.backgroundImage"),
+    backgroundImage: "backgroundImage",
+  },
+  {
+    name: "backgroundImageRepeat",
+    label: trans("style.backgroundImageRepeat"),
+    backgroundImageRepeat: "backgroundImageRepeat",
+  },
+  {
+    name: "backgroundImageSize",
+    label: trans("style.backgroundImageSize"),
+    backgroundImageSize: "backgroundImageSize",
+  },
+  {
+    name: "backgroundImagePosition",
+    label: trans("style.backgroundImagePosition"),
+    backgroundImagePosition: "backgroundImagePosition",
+  },
+  {
+    name: "backgroundImageOrigin",
+    label: trans("style.backgroundImageOrigin"),
+    backgroundImageOrigin: "backgroundImageOrigin",
+  },
 ] as const;
 
 export const ContainerHeaderStyle = [
@@ -732,9 +764,6 @@ export const MultiSelectStyle = [
 ] as const;
 
 export const TabContainerStyle = [
-  ...BG_STATIC_BORDER_RADIUS,
-  BORDER_WIDTH,
-  HEADER_BACKGROUND,
   {
     name: "tabText",
     label: trans("style.tabText"),
@@ -749,83 +778,7 @@ export const TabContainerStyle = [
     depType: DEP_TYPE.SELF,
     transformer: toSelf,
   },
-  MARGIN,	
-  PADDING,
-  {
-    name: "headerBackgroundImage",
-    label: trans("style.headerBackgroundImage"),
-    headerBackgroundImage: "headerBackgroundImage",
-  },
-  {
-    name: "headerBackgroundImageRepeat",
-    label: trans("style.headerBackgroundImageRepeat"),
-    headerBackgroundImageRepeat: "headerBackgroundImageRepeat",
-  },
-  {
-    name: "headerBackgroundImageSize",
-    label: trans("style.headerBackgroundImageSize"),
-    headerBackgroundImageSize: "headerBackgroundImageSize",
-  },
-  {
-    name: "headerBackgroundImagePosition",
-    label: trans("style.headerBackgroundImagePosition"),
-    headerBackgroundImagePosition: "headerBackgroundImagePosition",
-  }
-  ,{
-    name: "headerBackgroundImageOrigin",
-    label: trans("style.headerBackgroundImageOrigin"),
-    headerBackgroundImageOrigin: "headerBackgroundImageOrigin",
-  },
-  {
-    name: "backgroundImage",
-    label: trans("style.backgroundImage"),
-    backgroundImage: "backgroundImage",
-  },
-  {
-    name: "backgroundImageRepeat",
-    label: trans("style.backgroundImageRepeat"),
-    backgroundImageRepeat: "backgroundImageRepeat",
-  },
-  {
-    name: "backgroundImageSize",
-    label: trans("style.backgroundImageSize"),
-    backgroundImageSize: "backgroundImageSize",
-  },
-  {
-    name: "backgroundImagePosition",
-    label: trans("style.backgroundImagePosition"),
-    backgroundImagePosition: "backgroundImagePosition",
-  },
-  {
-    name: "backgroundImageOrigin",
-    label: trans("style.backgroundImageOrigin"),
-    backgroundImageOrigin: "backgroundImageOrigin",
-  },
-  {
-    name: "footerBackgroundImage",
-    label: trans("style.footerBackgroundImage"),
-    footerBackgroundImage: "footerBackgroundImage",
-  },
-  {
-    name: "footerBackgroundImageRepeat",
-    label: trans("style.footerBackgroundImageRepeat"),
-    footerBackgroundImageRepeat: "footerBackgroundImageRepeat",
-  },
-  {
-    name: "footerBackgroundImageSize",
-    label: trans("style.footerBackgroundImageSize"),
-    footerBackgroundImageSize: "footerBackgroundImageSize",
-  },
-  {
-    name: "footerBackgroundImagePosition",
-    label: trans("style.footerBackgroundImagePosition"),
-    footerBackgroundImagePosition: "footerBackgroundImagePosition",
-  }
-  ,{
-    name: "footerBackgroundImageOrigin",
-    label: trans("style.footerBackgroundImageOrigin"),
-    footerBackgroundImageOrigin: "footerBackgroundImageOrigin",
-  }
+  ...ContainerStyle,
 ] as const;
 
 export const ModalStyle = [

From e818a274e02a7692e21233e52dce597792fbea26 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Fri, 19 Jan 2024 19:52:25 +0500
Subject: [PATCH 11/97] adding background styles in container

---
 .../comps/comps/triContainerComp/triContainer.tsx    | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx
index 613baf94e8..eea06d5695 100644
--- a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx
+++ b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx
@@ -18,6 +18,12 @@ const getStyle = (style: ContainerStyleType) => {
     padding: ${style.padding};	
     // width: ${widthCalculator(style.margin)};	
     // height: ${heightCalculator(style.margin)};
+    ${style.background && `background-color: ${style.background};`}
+    ${style.backgroundImage && `background-image: ${style.backgroundImage};`}
+    ${style.backgroundImageRepeat && `background-repeat: ${style.backgroundImageRepeat};`}
+    ${style.backgroundImageSize && `background-size: ${style.backgroundImageSize};`}
+    ${style.backgroundImagePosition && `background-position: ${style.backgroundImagePosition};`}
+    ${style.backgroundImageOrigin && `background-origin: ${style.backgroundImageOrigin};`}
   `;
 };
 
@@ -130,7 +136,7 @@ export function TriContainer(props: TriContainerProps) {
             minHeight="46px"
             containerPadding={[paddingWidth, 3]}
             showName={{ bottom: showBody || showFooter ? 20 : 0 }}
-            $backgroundColor={headerStyle?.headerBackground}
+            $backgroundColor={headerStyle?.headerBackground || 'transparent'}
             $headerBackgroundImage={headerStyle?.headerBackgroundImage}
             $headerBackgroundImageRepeat={headerStyle?.headerBackgroundImageRepeat}
             $headerBackgroundImageSize={headerStyle?.headerBackgroundImageSize}
@@ -154,7 +160,7 @@ export function TriContainer(props: TriContainerProps) {
               (showHeader && showFooter) || showHeader ? [paddingWidth, 11.5] : [paddingWidth, 11]
             }
             hintPlaceholder={props.hintPlaceholder ?? HintPlaceHolder}
-            $backgroundColor={bodyStyle?.background}
+            $backgroundColor={bodyStyle?.background || 'transparent'}
             $borderColor={style?.border}
             $borderWidth={style?.borderWidth}
             $backgroundImage={bodyStyle?.backgroundImage}
@@ -177,7 +183,7 @@ export function TriContainer(props: TriContainerProps) {
             minHeight={showBody ? "47px" : "46px"}
             containerPadding={showBody || showHeader ? [paddingWidth, 3.5] : [paddingWidth, 3]}
             showName={{ top: showHeader || showBody ? 20 : 0 }}
-            $backgroundColor={footerStyle?.footerBackground}
+            $backgroundColor={footerStyle?.footerBackground || 'transparent'}
             $footerBackgroundImage={footerStyle?.footerBackgroundImage}
             $footerBackgroundImageRepeat={footerStyle?.footerBackgroundImageRepeat}
             $footerBackgroundImageSize={footerStyle?.footerBackgroundImageSize}

From c063b69d0a6d85ff2160f97f681261a60fd9cead Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Fri, 19 Jan 2024 19:53:35 +0500
Subject: [PATCH 12/97] updated tabs container styles

---
 .../comps/comps/tabs/tabbedContainerComp.tsx  | 86 +++++++++++++------
 1 file changed, 60 insertions(+), 26 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/tabs/tabbedContainerComp.tsx b/client/packages/lowcoder/src/comps/comps/tabs/tabbedContainerComp.tsx
index afd010959d..06a5ad9559 100644
--- a/client/packages/lowcoder/src/comps/comps/tabs/tabbedContainerComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tabs/tabbedContainerComp.tsx
@@ -7,7 +7,7 @@ import { BooleanStateControl, booleanExposingStateControl, stringExposingStateCo
 import { eventHandlerControl } from "comps/controls/eventHandlerControl";
 import { TabsOptionControl } from "comps/controls/optionsControl";
 import { styleControl } from "comps/controls/styleControl";
-import { TabContainerStyle, TabContainerStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
+import { ContainerBodyStyle, ContainerBodyStyleType, ContainerHeaderStyle, ContainerHeaderStyleType, TabContainerStyle, TabContainerStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
 import { sameTypeMap, UICompBuilder, withDefault } from "comps/generators";
 import { addMapChildAction } from "comps/generators/sameTypeMap";
 import { NameConfig, NameConfigHidden, withExposingConfigs } from "comps/generators/withExposing";
@@ -33,9 +33,6 @@ import { DisabledContext } from "comps/generators/uiCompBuilder";
 import { EditorContext } from "comps/editorState";
 import { checkIsMobile } from "util/commonUtils";
 import { messageInstance } from "lowcoder-design";
-import { show } from "antd-mobile/es/components/dialog/show";
-import { BoolControl } from "@lowcoder-ee/index.sdk";
-import { Switch } from "antd";
 
 const EVENT_OPTIONS = [
   {
@@ -57,38 +54,52 @@ const childrenMap = {
   disabled: BoolCodeControl,
   showHeader: withDefault(BooleanStateControl, "true"),
   style: styleControl(TabContainerStyle),
+  headerStyle: styleControl(ContainerHeaderStyle),
+  bodyStyle: styleControl(ContainerBodyStyle),
 };
 
 type ViewProps = RecordConstructorToView<typeof childrenMap>;
 type TabbedContainerProps = ViewProps & { dispatch: DispatchType };
  
-const getStyle = (style: TabContainerStyleType) => {
+const getStyle = (
+  style: TabContainerStyleType,
+  headerStyle: ContainerHeaderStyleType,
+  bodyStyle: ContainerBodyStyleType,
+) => {
   return css`
     &.ant-tabs {
+      overflow: hidden;
       border: ${style.borderWidth} solid ${style.border};
       border-radius: ${style.radius};
-      overflow: hidden;
       padding: ${style.padding};
+      background-color: ${style.background};
+      background-image: ${style.backgroundImage};
+      background-repeat: ${style.backgroundImageRepeat};
+      background-size: ${style.backgroundImageSize};
+      background-position: ${style.backgroundImagePosition};
+      background-origin: ${style.backgroundImageOrigin};
+
+      > .ant-tabs-content-holder > .ant-tabs-content > .ant-tabs-tabpane {
+        height: 100%;
+        .react-grid-layout {
+          border-radius: 0;
+          background-color: ${bodyStyle.background || 'transparent'};
+          background-image: ${bodyStyle.backgroundImage};
+          background-repeat: ${bodyStyle.backgroundImageRepeat};
+          background-size: ${bodyStyle.backgroundImageSize};
+          background-position: ${bodyStyle.backgroundImagePosition};
+          background-origin: ${bodyStyle.backgroundImageOrigin};
 
-      > .ant-tabs-content-holder > .ant-tabs-content > div > .react-grid-layout {
-        background-color: ${style.background};
-        border-radius: 0;
-        
-        background-image: ${style.backgroundImage};
-        background-repeat: ${style.backgroundImageRepeat};
-        background-size: ${style.backgroundImageSize};
-        background-position: ${style.backgroundImagePosition};
-        background-origin: ${style.backgroundImageOrigin};
-        
+        }
       }
 
       > .ant-tabs-nav {
-        background-color: ${style.headerBackground};
-        background-image: ${style.headerBackgroundImage};
-        background-repeat: ${style.headerBackgroundImageRepeat};
-        background-size: ${style.headerBackgroundImageSize};
-        background-position: ${style.headerBackgroundImagePosition};
-        background-origin: ${style.headerBackgroundImageOrigin};
+        background-color: ${headerStyle.headerBackground || 'transparent'};
+        background-image: ${headerStyle.headerBackgroundImage};
+        background-repeat: ${headerStyle.headerBackgroundImageRepeat};
+        background-size: ${headerStyle.headerBackgroundImageSize};
+        background-position: ${headerStyle.headerBackgroundImagePosition};
+        background-origin: ${headerStyle.headerBackgroundImageOrigin};
 
         .ant-tabs-tab {
           div {
@@ -113,7 +124,9 @@ const getStyle = (style: TabContainerStyleType) => {
 };
 
 const StyledTabs = styled(Tabs)<{ 
-  $style: TabContainerStyleType; 
+  $style: TabContainerStyleType;
+  $headerStyle: ContainerHeaderStyleType;
+  $bodyStyle: ContainerBodyStyleType;
   $isMobile?: boolean; 
   $showHeader?: boolean;
 }>`
@@ -145,7 +158,11 @@ const StyledTabs = styled(Tabs)<{
     margin-right: -24px;
   }
 
-  ${(props) => props.$style && getStyle(props.$style)}
+  ${(props) => props.$style && getStyle(
+    props.$style,
+    props.$headerStyle,
+    props.$bodyStyle,
+  )}
 `;
 
 const ContainerInTab = (props: ContainerBaseProps) => {
@@ -155,7 +172,14 @@ const ContainerInTab = (props: ContainerBaseProps) => {
 };
 
 const TabbedContainer = (props: TabbedContainerProps) => {
-  let { tabs, containers, dispatch, style } = props;
+  let {
+    tabs,
+    containers,
+    dispatch,
+    style,
+    headerStyle,
+    bodyStyle,
+  } = props;
 
   const visibleTabs = tabs.filter((tab) => !tab.hidden);
   const selectedTab = visibleTabs.find((tab) => tab.key === props.selectedTabKey.value);
@@ -203,7 +227,7 @@ const TabbedContainer = (props: TabbedContainerProps) => {
       key: tab.key,
       forceRender: true,
       children: (
-        <BackgroundColorContext.Provider value={props.style.background}>
+        <BackgroundColorContext.Provider value={bodyStyle.background}>
           <ContainerInTab
             layout={containerProps.layout.getView()}
             items={gridItemCompToGridItems(containerProps.items.getView())}
@@ -222,6 +246,8 @@ const TabbedContainer = (props: TabbedContainerProps) => {
     <StyledTabs
       activeKey={activeKey}
       $style={style}
+      $headerStyle={headerStyle}
+      $bodyStyle={bodyStyle}
       $showHeader={showHeader}
       onChange={(key) => {
         if (key !== props.selectedTabKey.value) {
@@ -277,6 +303,14 @@ export const TabbedContainerBaseComp = (function () {
               <Section name={sectionNames.style}>
                 {children.style.getPropertyView()}
               </Section>
+              {children.showHeader.getView() && (
+                <Section name={"Header Style"}>
+                  { children.headerStyle.getPropertyView() }
+                </Section>
+              )}
+              <Section name={"Body Style"}>
+                { children.bodyStyle.getPropertyView() }
+              </Section>
             </>
           )}
         </>

From a0199e4d62aedccb6896da6a4ede57f22a56960b Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Fri, 19 Jan 2024 19:55:37 +0500
Subject: [PATCH 13/97] handle form height based for fixed height setting

---
 .../src/comps/comps/formComp/formComp.tsx     | 29 +++++++++++++++----
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/formComp/formComp.tsx b/client/packages/lowcoder/src/comps/comps/formComp/formComp.tsx
index a1fb8182d8..16166e3f22 100644
--- a/client/packages/lowcoder/src/comps/comps/formComp/formComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/formComp/formComp.tsx
@@ -57,6 +57,17 @@ import log from "loglevel";
 import { DisabledContext } from "comps/generators/uiCompBuilder";
 import { LoadingOutlined } from "@ant-design/icons";
 import { messageInstance } from "lowcoder-design";
+import { styled } from "styled-components";
+
+const FormWrapper = styled.div`
+  height: 100%;
+  .ant-spin-nested-loading {
+    height: 100%;
+    .ant-spin-container {
+      height: 100%;
+    }
+  }
+`;
 
 const eventOptions = [submitEvent] as const;
 
@@ -172,12 +183,18 @@ const FormBaseComp = (function () {
   return new ContainerCompBuilder(childrenMap, (props, dispatch) => {
     return (
       <DisabledContext.Provider value={props.disabled}>
-        <Spin indicator={loadingIcon} spinning={props.loading}>
-          <TriContainer
-            {...props}
-            hintPlaceholder={<BodyPlaceholder {...props} dispatch={dispatch} />}
-          />
-        </Spin>
+        <FormWrapper>
+          <Spin
+            indicator={loadingIcon}
+            spinning={props.loading}
+            style={{height: '100%'}}
+          >
+            <TriContainer
+              {...props}
+              hintPlaceholder={<BodyPlaceholder {...props} dispatch={dispatch} />}
+            />
+          </Spin>
+        </FormWrapper>
       </DisabledContext.Provider>
     );
   })

From 44359dc8723a0e7f57e8c6317ff44eb25403f112 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 19 Jan 2024 22:36:14 +0000
Subject: [PATCH 14/97] Bump vite from 4.5.1 to 4.5.2 in /client

Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.5.1 to 4.5.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v4.5.2/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.5.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
---
 .../package.json                              |   2 +-
 client/packages/lowcoder-cli/package.json     |   2 +-
 client/packages/lowcoder-comps/package.json   |   2 +-
 .../lowcoder-plugin-demo/package.json         |   2 +-
 client/packages/lowcoder-sdk/package.json     |   2 +-
 client/packages/lowcoder/package.json         |   2 +-
 client/yarn.lock                              | 454 +-----------------
 7 files changed, 20 insertions(+), 446 deletions(-)

diff --git a/client/packages/lowcoder-cli-template-typescript/package.json b/client/packages/lowcoder-cli-template-typescript/package.json
index 4b85ecf87d..a6b2b83b00 100644
--- a/client/packages/lowcoder-cli-template-typescript/package.json
+++ b/client/packages/lowcoder-cli-template-typescript/package.json
@@ -32,7 +32,7 @@
     "react-dom": "^18.2.0",
     "react-resize-detector": "^7.0.0",
     "typescript": "5.3.3",
-    "vite": "^5.0.10"
+    "vite": "^4.5.2"
   },
   "keywords": [
     "Lowcoder, Component, Template, Plugin, Demonstrator"
diff --git a/client/packages/lowcoder-cli/package.json b/client/packages/lowcoder-cli/package.json
index 5e87b44833..7fa45ad87d 100644
--- a/client/packages/lowcoder-cli/package.json
+++ b/client/packages/lowcoder-cli/package.json
@@ -33,7 +33,7 @@
     "react-dom": "^18.2.0",
     "react-json-view": "^1.21.3",
     "rollup-plugin-external-globals": "^0.7.1",
-    "vite": "^4.3.9",
+    "vite": "^4.5.2",
     "vite-plugin-css-injected-by-js": "^2.1.1",
     "vite-plugin-svgr": "^2.2.2"
   },
diff --git a/client/packages/lowcoder-comps/package.json b/client/packages/lowcoder-comps/package.json
index f0d610f5cd..1bf1dae929 100644
--- a/client/packages/lowcoder-comps/package.json
+++ b/client/packages/lowcoder-comps/package.json
@@ -69,7 +69,7 @@
   },
   "devDependencies": {
     "jest": "29.3.0",
-    "vite": "^4.3.9",
+    "vite": "^4.5.2",
     "vite-tsconfig-paths": "^3.6.0"
   }
 }
diff --git a/client/packages/lowcoder-plugin-demo/package.json b/client/packages/lowcoder-plugin-demo/package.json
index 357c4dee8e..5b434b6b80 100644
--- a/client/packages/lowcoder-plugin-demo/package.json
+++ b/client/packages/lowcoder-plugin-demo/package.json
@@ -35,6 +35,6 @@
     "lowcoder-cli": "workspace:^",
     "lowcoder-sdk": "workspace:^",
     "typescript": "4.8.4",
-    "vite": "^4.3.9"
+    "vite": "^4.5.2"
   }
 }
diff --git a/client/packages/lowcoder-sdk/package.json b/client/packages/lowcoder-sdk/package.json
index 36583cdcf7..e595878f56 100644
--- a/client/packages/lowcoder-sdk/package.json
+++ b/client/packages/lowcoder-sdk/package.json
@@ -43,7 +43,7 @@
     "rollup-plugin-terser": "^7.0.2",
     "rollup-plugin-typescript": "^1.0.1",
     "typescript": "^4.8.4",
-    "vite": "^4.3.9",
+    "vite": "^4.5.2",
     "vite-plugin-svgr": "^2.2.2",
     "vite-tsconfig-paths": "^3.6.0"
   },
diff --git a/client/packages/lowcoder/package.json b/client/packages/lowcoder/package.json
index f575d828d7..9fb4735ad6 100644
--- a/client/packages/lowcoder/package.json
+++ b/client/packages/lowcoder/package.json
@@ -124,7 +124,7 @@
     "http-proxy-middleware": "^2.0.6",
     "rollup-plugin-visualizer": "^5.9.2",
     "typescript": "^4.8.4",
-    "vite": "^4.5.1",
+    "vite": "^4.5.2",
     "vite-plugin-checker": "^0.5.1",
     "vite-plugin-html": "^3.2.0",
     "vite-plugin-svgr": "^2.2.2",
diff --git a/client/yarn.lock b/client/yarn.lock
index 9dead2fc88..e528246312 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -2049,13 +2049,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/aix-ppc64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/aix-ppc64@npm:0.19.11"
-  conditions: os=aix & cpu=ppc64
-  languageName: node
-  linkType: hard
-
 "@esbuild/android-arm64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/android-arm64@npm:0.18.20"
@@ -2063,13 +2056,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/android-arm64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/android-arm64@npm:0.19.11"
-  conditions: os=android & cpu=arm64
-  languageName: node
-  linkType: hard
-
 "@esbuild/android-arm@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/android-arm@npm:0.18.20"
@@ -2077,13 +2063,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/android-arm@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/android-arm@npm:0.19.11"
-  conditions: os=android & cpu=arm
-  languageName: node
-  linkType: hard
-
 "@esbuild/android-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/android-x64@npm:0.18.20"
@@ -2091,13 +2070,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/android-x64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/android-x64@npm:0.19.11"
-  conditions: os=android & cpu=x64
-  languageName: node
-  linkType: hard
-
 "@esbuild/darwin-arm64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/darwin-arm64@npm:0.18.20"
@@ -2105,13 +2077,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/darwin-arm64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/darwin-arm64@npm:0.19.11"
-  conditions: os=darwin & cpu=arm64
-  languageName: node
-  linkType: hard
-
 "@esbuild/darwin-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/darwin-x64@npm:0.18.20"
@@ -2119,13 +2084,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/darwin-x64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/darwin-x64@npm:0.19.11"
-  conditions: os=darwin & cpu=x64
-  languageName: node
-  linkType: hard
-
 "@esbuild/freebsd-arm64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/freebsd-arm64@npm:0.18.20"
@@ -2133,13 +2091,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/freebsd-arm64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/freebsd-arm64@npm:0.19.11"
-  conditions: os=freebsd & cpu=arm64
-  languageName: node
-  linkType: hard
-
 "@esbuild/freebsd-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/freebsd-x64@npm:0.18.20"
@@ -2147,13 +2098,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/freebsd-x64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/freebsd-x64@npm:0.19.11"
-  conditions: os=freebsd & cpu=x64
-  languageName: node
-  linkType: hard
-
 "@esbuild/linux-arm64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-arm64@npm:0.18.20"
@@ -2161,13 +2105,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/linux-arm64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/linux-arm64@npm:0.19.11"
-  conditions: os=linux & cpu=arm64
-  languageName: node
-  linkType: hard
-
 "@esbuild/linux-arm@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-arm@npm:0.18.20"
@@ -2175,13 +2112,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/linux-arm@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/linux-arm@npm:0.19.11"
-  conditions: os=linux & cpu=arm
-  languageName: node
-  linkType: hard
-
 "@esbuild/linux-ia32@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-ia32@npm:0.18.20"
@@ -2189,13 +2119,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/linux-ia32@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/linux-ia32@npm:0.19.11"
-  conditions: os=linux & cpu=ia32
-  languageName: node
-  linkType: hard
-
 "@esbuild/linux-loong64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-loong64@npm:0.18.20"
@@ -2203,13 +2126,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/linux-loong64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/linux-loong64@npm:0.19.11"
-  conditions: os=linux & cpu=loong64
-  languageName: node
-  linkType: hard
-
 "@esbuild/linux-mips64el@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-mips64el@npm:0.18.20"
@@ -2217,13 +2133,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/linux-mips64el@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/linux-mips64el@npm:0.19.11"
-  conditions: os=linux & cpu=mips64el
-  languageName: node
-  linkType: hard
-
 "@esbuild/linux-ppc64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-ppc64@npm:0.18.20"
@@ -2231,13 +2140,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/linux-ppc64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/linux-ppc64@npm:0.19.11"
-  conditions: os=linux & cpu=ppc64
-  languageName: node
-  linkType: hard
-
 "@esbuild/linux-riscv64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-riscv64@npm:0.18.20"
@@ -2245,13 +2147,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/linux-riscv64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/linux-riscv64@npm:0.19.11"
-  conditions: os=linux & cpu=riscv64
-  languageName: node
-  linkType: hard
-
 "@esbuild/linux-s390x@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-s390x@npm:0.18.20"
@@ -2259,13 +2154,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/linux-s390x@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/linux-s390x@npm:0.19.11"
-  conditions: os=linux & cpu=s390x
-  languageName: node
-  linkType: hard
-
 "@esbuild/linux-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-x64@npm:0.18.20"
@@ -2273,13 +2161,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/linux-x64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/linux-x64@npm:0.19.11"
-  conditions: os=linux & cpu=x64
-  languageName: node
-  linkType: hard
-
 "@esbuild/netbsd-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/netbsd-x64@npm:0.18.20"
@@ -2287,13 +2168,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/netbsd-x64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/netbsd-x64@npm:0.19.11"
-  conditions: os=netbsd & cpu=x64
-  languageName: node
-  linkType: hard
-
 "@esbuild/openbsd-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/openbsd-x64@npm:0.18.20"
@@ -2301,13 +2175,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/openbsd-x64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/openbsd-x64@npm:0.19.11"
-  conditions: os=openbsd & cpu=x64
-  languageName: node
-  linkType: hard
-
 "@esbuild/sunos-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/sunos-x64@npm:0.18.20"
@@ -2315,13 +2182,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/sunos-x64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/sunos-x64@npm:0.19.11"
-  conditions: os=sunos & cpu=x64
-  languageName: node
-  linkType: hard
-
 "@esbuild/win32-arm64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/win32-arm64@npm:0.18.20"
@@ -2329,13 +2189,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/win32-arm64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/win32-arm64@npm:0.19.11"
-  conditions: os=win32 & cpu=arm64
-  languageName: node
-  linkType: hard
-
 "@esbuild/win32-ia32@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/win32-ia32@npm:0.18.20"
@@ -2343,13 +2196,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/win32-ia32@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/win32-ia32@npm:0.19.11"
-  conditions: os=win32 & cpu=ia32
-  languageName: node
-  linkType: hard
-
 "@esbuild/win32-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/win32-x64@npm:0.18.20"
@@ -2357,13 +2203,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/win32-x64@npm:0.19.11":
-  version: 0.19.11
-  resolution: "@esbuild/win32-x64@npm:0.19.11"
-  conditions: os=win32 & cpu=x64
-  languageName: node
-  linkType: hard
-
 "@eslint-community/eslint-utils@npm:^4.2.0":
   version: 4.4.0
   resolution: "@eslint-community/eslint-utils@npm:4.4.0"
@@ -3675,97 +3514,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@rollup/rollup-android-arm-eabi@npm:4.9.5":
-  version: 4.9.5
-  resolution: "@rollup/rollup-android-arm-eabi@npm:4.9.5"
-  conditions: os=android & cpu=arm
-  languageName: node
-  linkType: hard
-
-"@rollup/rollup-android-arm64@npm:4.9.5":
-  version: 4.9.5
-  resolution: "@rollup/rollup-android-arm64@npm:4.9.5"
-  conditions: os=android & cpu=arm64
-  languageName: node
-  linkType: hard
-
-"@rollup/rollup-darwin-arm64@npm:4.9.5":
-  version: 4.9.5
-  resolution: "@rollup/rollup-darwin-arm64@npm:4.9.5"
-  conditions: os=darwin & cpu=arm64
-  languageName: node
-  linkType: hard
-
-"@rollup/rollup-darwin-x64@npm:4.9.5":
-  version: 4.9.5
-  resolution: "@rollup/rollup-darwin-x64@npm:4.9.5"
-  conditions: os=darwin & cpu=x64
-  languageName: node
-  linkType: hard
-
-"@rollup/rollup-linux-arm-gnueabihf@npm:4.9.5":
-  version: 4.9.5
-  resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.9.5"
-  conditions: os=linux & cpu=arm
-  languageName: node
-  linkType: hard
-
-"@rollup/rollup-linux-arm64-gnu@npm:4.9.5":
-  version: 4.9.5
-  resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.9.5"
-  conditions: os=linux & cpu=arm64 & libc=glibc
-  languageName: node
-  linkType: hard
-
-"@rollup/rollup-linux-arm64-musl@npm:4.9.5":
-  version: 4.9.5
-  resolution: "@rollup/rollup-linux-arm64-musl@npm:4.9.5"
-  conditions: os=linux & cpu=arm64 & libc=musl
-  languageName: node
-  linkType: hard
-
-"@rollup/rollup-linux-riscv64-gnu@npm:4.9.5":
-  version: 4.9.5
-  resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.9.5"
-  conditions: os=linux & cpu=riscv64 & libc=glibc
-  languageName: node
-  linkType: hard
-
-"@rollup/rollup-linux-x64-gnu@npm:4.9.5":
-  version: 4.9.5
-  resolution: "@rollup/rollup-linux-x64-gnu@npm:4.9.5"
-  conditions: os=linux & cpu=x64 & libc=glibc
-  languageName: node
-  linkType: hard
-
-"@rollup/rollup-linux-x64-musl@npm:4.9.5":
-  version: 4.9.5
-  resolution: "@rollup/rollup-linux-x64-musl@npm:4.9.5"
-  conditions: os=linux & cpu=x64 & libc=musl
-  languageName: node
-  linkType: hard
-
-"@rollup/rollup-win32-arm64-msvc@npm:4.9.5":
-  version: 4.9.5
-  resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.9.5"
-  conditions: os=win32 & cpu=arm64
-  languageName: node
-  linkType: hard
-
-"@rollup/rollup-win32-ia32-msvc@npm:4.9.5":
-  version: 4.9.5
-  resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.9.5"
-  conditions: os=win32 & cpu=ia32
-  languageName: node
-  linkType: hard
-
-"@rollup/rollup-win32-x64-msvc@npm:4.9.5":
-  version: 4.9.5
-  resolution: "@rollup/rollup-win32-x64-msvc@npm:4.9.5"
-  conditions: os=win32 & cpu=x64
-  languageName: node
-  linkType: hard
-
 "@rushstack/eslint-patch@npm:^1.1.0":
   version: 1.6.1
   resolution: "@rushstack/eslint-patch@npm:1.6.1"
@@ -4121,7 +3869,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@types/estree@npm:*, @types/estree@npm:1.0.5, @types/estree@npm:^1.0.0":
+"@types/estree@npm:*, @types/estree@npm:^1.0.0":
   version: 1.0.5
   resolution: "@types/estree@npm:1.0.5"
   checksum: dd8b5bed28e6213b7acd0fb665a84e693554d850b0df423ac8076cc3ad5823a6bc26b0251d080bdc545af83179ede51dd3f6fa78cad2c46ed1f29624ddf3e41a
@@ -8108,86 +7856,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"esbuild@npm:^0.19.3":
-  version: 0.19.11
-  resolution: "esbuild@npm:0.19.11"
-  dependencies:
-    "@esbuild/aix-ppc64": 0.19.11
-    "@esbuild/android-arm": 0.19.11
-    "@esbuild/android-arm64": 0.19.11
-    "@esbuild/android-x64": 0.19.11
-    "@esbuild/darwin-arm64": 0.19.11
-    "@esbuild/darwin-x64": 0.19.11
-    "@esbuild/freebsd-arm64": 0.19.11
-    "@esbuild/freebsd-x64": 0.19.11
-    "@esbuild/linux-arm": 0.19.11
-    "@esbuild/linux-arm64": 0.19.11
-    "@esbuild/linux-ia32": 0.19.11
-    "@esbuild/linux-loong64": 0.19.11
-    "@esbuild/linux-mips64el": 0.19.11
-    "@esbuild/linux-ppc64": 0.19.11
-    "@esbuild/linux-riscv64": 0.19.11
-    "@esbuild/linux-s390x": 0.19.11
-    "@esbuild/linux-x64": 0.19.11
-    "@esbuild/netbsd-x64": 0.19.11
-    "@esbuild/openbsd-x64": 0.19.11
-    "@esbuild/sunos-x64": 0.19.11
-    "@esbuild/win32-arm64": 0.19.11
-    "@esbuild/win32-ia32": 0.19.11
-    "@esbuild/win32-x64": 0.19.11
-  dependenciesMeta:
-    "@esbuild/aix-ppc64":
-      optional: true
-    "@esbuild/android-arm":
-      optional: true
-    "@esbuild/android-arm64":
-      optional: true
-    "@esbuild/android-x64":
-      optional: true
-    "@esbuild/darwin-arm64":
-      optional: true
-    "@esbuild/darwin-x64":
-      optional: true
-    "@esbuild/freebsd-arm64":
-      optional: true
-    "@esbuild/freebsd-x64":
-      optional: true
-    "@esbuild/linux-arm":
-      optional: true
-    "@esbuild/linux-arm64":
-      optional: true
-    "@esbuild/linux-ia32":
-      optional: true
-    "@esbuild/linux-loong64":
-      optional: true
-    "@esbuild/linux-mips64el":
-      optional: true
-    "@esbuild/linux-ppc64":
-      optional: true
-    "@esbuild/linux-riscv64":
-      optional: true
-    "@esbuild/linux-s390x":
-      optional: true
-    "@esbuild/linux-x64":
-      optional: true
-    "@esbuild/netbsd-x64":
-      optional: true
-    "@esbuild/openbsd-x64":
-      optional: true
-    "@esbuild/sunos-x64":
-      optional: true
-    "@esbuild/win32-arm64":
-      optional: true
-    "@esbuild/win32-ia32":
-      optional: true
-    "@esbuild/win32-x64":
-      optional: true
-  bin:
-    esbuild: bin/esbuild
-  checksum: ae949a796d1d06b55275ae7491ce137857468f69a93d8cc9c0943d2a701ac54e14dbb250a2ba56f2ad98283669578f1ec3bd85a4681910a5ff29a2470c3bd62c
-  languageName: node
-  linkType: hard
-
 "escalade@npm:^3.1.1":
   version: 3.1.1
   resolution: "escalade@npm:3.1.1"
@@ -9117,7 +8785,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2, fsevents@npm:~2.3.3":
+"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2":
   version: 2.3.3
   resolution: "fsevents@npm:2.3.3"
   dependencies:
@@ -9127,7 +8795,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"fsevents@patch:fsevents@^2.3.2#~builtin<compat/fsevents>, fsevents@patch:fsevents@~2.3.2#~builtin<compat/fsevents>, fsevents@patch:fsevents@~2.3.3#~builtin<compat/fsevents>":
+"fsevents@patch:fsevents@^2.3.2#~builtin<compat/fsevents>, fsevents@patch:fsevents@~2.3.2#~builtin<compat/fsevents>":
   version: 2.3.3
   resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin<compat/fsevents>::version=2.3.3&hash=df0bf1"
   dependencies:
@@ -11775,7 +11443,7 @@ __metadata:
     react-dom: ^18.2.0
     react-resize-detector: ^7.0.0
     typescript: 5.3.3
-    vite: ^5.0.10
+    vite: ^4.5.2
   languageName: unknown
   linkType: soft
 
@@ -11795,7 +11463,7 @@ __metadata:
     react-json-view: ^1.21.3
     rollup-plugin-external-globals: ^0.7.1
     typescript: ^4.8.4
-    vite: ^4.3.9
+    vite: ^4.5.2
     vite-plugin-css-injected-by-js: ^2.1.1
     vite-plugin-svgr: ^2.2.2
   peerDependencies:
@@ -11828,7 +11496,7 @@ __metadata:
     react: ^18.2.0
     react-dom: ^18.2.0
     typescript: 4.8.4
-    vite: ^4.3.9
+    vite: ^4.5.2
     vite-tsconfig-paths: ^3.6.0
   languageName: unknown
   linkType: soft
@@ -11901,7 +11569,7 @@ __metadata:
     react: ^18.2.0
     react-dom: ^18.2.0
     typescript: 4.8.4
-    vite: ^4.3.9
+    vite: ^4.5.2
   languageName: unknown
   linkType: soft
 
@@ -11975,7 +11643,7 @@ __metadata:
     rollup-plugin-terser: ^7.0.2
     rollup-plugin-typescript: ^1.0.1
     typescript: ^4.8.4
-    vite: ^4.3.9
+    vite: ^4.5.2
     vite-plugin-svgr: ^2.2.2
     vite-tsconfig-paths: ^3.6.0
   peerDependencies:
@@ -12095,7 +11763,7 @@ __metadata:
     typescript-collections: ^1.3.3
     ua-parser-js: ^1.0.33
     uuid: ^9.0.0
-    vite: ^4.5.1
+    vite: ^4.5.2
     vite-plugin-checker: ^0.5.1
     vite-plugin-html: ^3.2.0
     vite-plugin-svgr: ^2.2.2
@@ -13875,7 +13543,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"postcss@npm:^8.4.27, postcss@npm:^8.4.32":
+"postcss@npm:^8.4.27":
   version: 8.4.33
   resolution: "postcss@npm:8.4.33"
   dependencies:
@@ -15973,60 +15641,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"rollup@npm:^4.2.0":
-  version: 4.9.5
-  resolution: "rollup@npm:4.9.5"
-  dependencies:
-    "@rollup/rollup-android-arm-eabi": 4.9.5
-    "@rollup/rollup-android-arm64": 4.9.5
-    "@rollup/rollup-darwin-arm64": 4.9.5
-    "@rollup/rollup-darwin-x64": 4.9.5
-    "@rollup/rollup-linux-arm-gnueabihf": 4.9.5
-    "@rollup/rollup-linux-arm64-gnu": 4.9.5
-    "@rollup/rollup-linux-arm64-musl": 4.9.5
-    "@rollup/rollup-linux-riscv64-gnu": 4.9.5
-    "@rollup/rollup-linux-x64-gnu": 4.9.5
-    "@rollup/rollup-linux-x64-musl": 4.9.5
-    "@rollup/rollup-win32-arm64-msvc": 4.9.5
-    "@rollup/rollup-win32-ia32-msvc": 4.9.5
-    "@rollup/rollup-win32-x64-msvc": 4.9.5
-    "@types/estree": 1.0.5
-    fsevents: ~2.3.2
-  dependenciesMeta:
-    "@rollup/rollup-android-arm-eabi":
-      optional: true
-    "@rollup/rollup-android-arm64":
-      optional: true
-    "@rollup/rollup-darwin-arm64":
-      optional: true
-    "@rollup/rollup-darwin-x64":
-      optional: true
-    "@rollup/rollup-linux-arm-gnueabihf":
-      optional: true
-    "@rollup/rollup-linux-arm64-gnu":
-      optional: true
-    "@rollup/rollup-linux-arm64-musl":
-      optional: true
-    "@rollup/rollup-linux-riscv64-gnu":
-      optional: true
-    "@rollup/rollup-linux-x64-gnu":
-      optional: true
-    "@rollup/rollup-linux-x64-musl":
-      optional: true
-    "@rollup/rollup-win32-arm64-msvc":
-      optional: true
-    "@rollup/rollup-win32-ia32-msvc":
-      optional: true
-    "@rollup/rollup-win32-x64-msvc":
-      optional: true
-    fsevents:
-      optional: true
-  bin:
-    rollup: dist/bin/rollup
-  checksum: a6bb721f2251a2299e99be2eb58b0949571545809b75571c42baa50e749437aa9ef40f0660644d992e2387ba7f0775271ab9388fe4fbb02c6c3fc5db6a8b9711
-  languageName: node
-  linkType: hard
-
 "rtl-css-js@npm:^1.16.1":
   version: 1.16.1
   resolution: "rtl-css-js@npm:1.16.1"
@@ -18036,9 +17650,9 @@ __metadata:
   languageName: node
   linkType: hard
 
-"vite@npm:^4.3.9, vite@npm:^4.5.1":
-  version: 4.5.1
-  resolution: "vite@npm:4.5.1"
+"vite@npm:^4.5.2":
+  version: 4.5.2
+  resolution: "vite@npm:4.5.2"
   dependencies:
     esbuild: ^0.18.10
     fsevents: ~2.3.2
@@ -18072,47 +17686,7 @@ __metadata:
       optional: true
   bin:
     vite: bin/vite.js
-  checksum: 72b3584b3d3b8d14e8a37f0248e47fb8b4d02ab35de5b5a8e5ca8ae55c3be2aab73760dc36edac4fa722de182f78cc492eb44888fcb4a9a0712c4605dad644f9
-  languageName: node
-  linkType: hard
-
-"vite@npm:^5.0.10":
-  version: 5.0.11
-  resolution: "vite@npm:5.0.11"
-  dependencies:
-    esbuild: ^0.19.3
-    fsevents: ~2.3.3
-    postcss: ^8.4.32
-    rollup: ^4.2.0
-  peerDependencies:
-    "@types/node": ^18.0.0 || >=20.0.0
-    less: "*"
-    lightningcss: ^1.21.0
-    sass: "*"
-    stylus: "*"
-    sugarss: "*"
-    terser: ^5.4.0
-  dependenciesMeta:
-    fsevents:
-      optional: true
-  peerDependenciesMeta:
-    "@types/node":
-      optional: true
-    less:
-      optional: true
-    lightningcss:
-      optional: true
-    sass:
-      optional: true
-    stylus:
-      optional: true
-    sugarss:
-      optional: true
-    terser:
-      optional: true
-  bin:
-    vite: bin/vite.js
-  checksum: 262e41f25ce0cc5fc3c2065b1796f64ec115d3ac2d9625dbfb36d6628ba10e63684ef5515bb2ff1aa8e34c6f89e9c10e8211cb88f6c7f0da6869362851345437
+  checksum: 9d1f84f703c2660aced34deee7f309278ed368880f66e9570ac115c793d91f7fffb80ab19c602b3c8bc1341fe23437d86a3fcca2a9ef82f7ef0cdac5a40d0c86
   languageName: node
   linkType: hard
 

From 5c225ccb2829fae464b66f8b964d9c82ec6bce0f Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Thu, 18 Jan 2024 12:42:52 +0500
Subject: [PATCH 15/97] column data mapping

---
 .../comps/tableComp/column/columnTypeComp.tsx | 36 ++++++++++++++++-
 .../tableComp/column/tableColumnComp.tsx      | 39 +++++++++++++++++++
 .../src/comps/comps/tableComp/tableUtils.tsx  |  1 +
 .../src/comps/controls/dropdownControl.tsx    |  3 +-
 4 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComp.tsx
index 678bcabb0e..7e90615044 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComp.tsx
@@ -1,7 +1,7 @@
 import { CellProps } from "components/table/EditableCell";
 import { DateTimeComp } from "comps/comps/tableComp/column/columnTypeComps/columnDateTimeComp";
 import { ButtonComp } from "comps/comps/tableComp/column/simpleColumnTypeComps";
-import { withType } from "comps/generators";
+import { MultiCompBuilder, withDefault, withType } from "comps/generators";
 import { trans } from "i18n";
 import { Dropdown } from "lowcoder-design";
 import { BooleanComp } from "./columnTypeComps/columnBooleanComp";
@@ -17,6 +17,31 @@ import { ColumnTagsComp } from "./columnTypeComps/columnTagsComp";
 import { ColumnSelectComp } from "./columnTypeComps/columnSelectComp";
 import { SimpleTextComp } from "./columnTypeComps/simpleTextComp";
 import { ColumnNumberComp } from "./columnTypeComps/ColumnNumberComp";
+import { useState } from "react";
+import { dropdownControl } from "@lowcoder-ee/index.sdk";
+
+const columnValueOptions = [
+  {
+    label: "ID",
+    value: "{{currentRow.id}}",
+  },
+  {
+    label: "Name",
+    value: "{{currentRow.name}}",
+  },
+  {
+    label: "Department",
+    value: "{{currentRow.department}}",
+  },
+  {
+    label: "Date",
+    value: "{{currentRow.date}}",
+  },
+  {
+    label: "Other",
+    value: "",
+  },
+] as const;
 
 const actionOptions = [
   {
@@ -104,6 +129,15 @@ export type ColumnTypeKeys = keyof ColumnTypeMapType;
 
 const TypedColumnTypeComp = withType(ColumnTypeCompMap, "text");
 
+const childrenMap = {
+  comp: TypedColumnTypeComp,
+  valueMap: dropdownControl(columnValueOptions, "")
+};
+
+const TmpColumnTypeComp = new MultiCompBuilder(childrenMap, (props) => {
+  return props;
+}).build();
+
 export class ColumnTypeComp extends TypedColumnTypeComp {
   override getView() {
     const childView = this.children.comp.getView();
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
index 39a392ad4c..6932a49835 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
@@ -57,6 +57,29 @@ const columnFixOptions = [
   },
 ] as const;
 
+const columnValueOptions = [
+  {
+    label: "ID",
+    value: "{{currentRow.id}}",
+  },
+  {
+    label: "Name",
+    value: "{{currentRow.name}}",
+  },
+  {
+    label: "Department",
+    value: "{{currentRow.department}}",
+  },
+  {
+    label: "Date",
+    value: "{{currentRow.date}}",
+  },
+  {
+    label: "Other",
+    value: "",
+  },
+] as const;
+
 const cellColorLabel = trans("table.cellColor");
 const CellColorTempComp = withContext(
   new MultiCompBuilder({ color: ColorOrBoolCodeControl }, (props) => props.color)
@@ -94,6 +117,7 @@ export const columnChildrenMap = {
   sortable: BoolControl,
   width: NumberControl,
   autoWidth: dropdownControl(columnWidthOptions, "auto"),
+  columnMapping: dropdownControl(columnValueOptions, ""),
   render: RenderComp,
   align: HorizontalAlignmentControl,
   tempHide: stateComp<boolean>(false),
@@ -195,6 +219,21 @@ export class ColumnComp extends ColumnInitComp {
           label: trans("table.columnTitle"),
           placeholder: this.children.dataIndex.getView(),
         })}
+        {this.children.columnMapping.propertyView({
+          label: "Data Mapping",
+          onChange: (value) => {
+            console.log(value)
+            const comp = this.children.render.getSelectedComp().getComp();
+            // let textRawData = "{{currentCell}}";
+            // if (comp.children.hasOwnProperty("text")) {
+            //   textRawData = (comp.children as any).text.toJsonValue();
+            // }
+            this.children.render.dispatchChangeValueAction({
+              compType: columnType,
+              comp: { text: value },
+            } as any);
+          }
+        })}
         {/* FIXME: cast type currently, return type of withContext should be corrected later */}
         {this.children.render.getPropertyView()}
         {this.children.showTitle.propertyView({
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
index 4532475c8e..a9fb52ea7c 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
@@ -271,6 +271,7 @@ export function columnsToAntdFormat(
   columnsAggrData: ColumnsAggrData,
   onTableEvent: (eventName: any) => void,
 ): Array<CustomColumnType<RecordType>> {
+  console.log(columnsAggrData);
   const sortMap: Map<string | undefined, SortOrder> = new Map(
     sort.map((s) => [s.column, s.desc ? "descend" : "ascend"])
   );
diff --git a/client/packages/lowcoder/src/comps/controls/dropdownControl.tsx b/client/packages/lowcoder/src/comps/controls/dropdownControl.tsx
index 211dd09101..1492a97a45 100644
--- a/client/packages/lowcoder/src/comps/controls/dropdownControl.tsx
+++ b/client/packages/lowcoder/src/comps/controls/dropdownControl.tsx
@@ -92,15 +92,16 @@ export function dropdownAbstractControl<T extends OptionsType>(
       return controlItem(
         { filterText: params.label },
         <DropdownPropertyView<T>
+          {...params}
           value={this.value}
           options={finalOptions}
           onChange={(value) => {
+            console.log(value);
             if (!params.disableDispatchValueChange) {
               this.dispatchChangeValueAction(value);
             }
             params.onChange?.(value);
           }}
-          {...params}
         />
       );
     }

From e47d9e9705580b09701f3d6654ed15f951f50a98 Mon Sep 17 00:00:00 2001
From: mdpung <mdpung@gmail.com>
Date: Mon, 22 Jan 2024 14:44:38 -0700
Subject: [PATCH 16/97] Update javascript-query.md

Typo in the word "parameters", missing the 'r'.
---
 docs/build-apps/write-javascript/javascript-query.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/build-apps/write-javascript/javascript-query.md b/docs/build-apps/write-javascript/javascript-query.md
index 3fda2c7f8c..3cb22b11ef 100644
--- a/docs/build-apps/write-javascript/javascript-query.md
+++ b/docs/build-apps/write-javascript/javascript-query.md
@@ -117,7 +117,7 @@ return queryByName.run().then(
 
 ### Pass in parameters
 
-You can pass parametes in the `run()` method to decouple query implementation from its parameters.
+You can pass parameters in the `run()` method to decouple query implementation from its parameters.
 
 ```javascript
 query.run({

From 155fbaec08737fdb9a300c253683f24a5b78cced Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Tue, 23 Jan 2024 13:33:34 +0500
Subject: [PATCH 17/97] dynamice populate columns for data mapping

---
 .../comps/tableComp/column/columnTypeComp.tsx | 36 +---------
 .../columnTypeComps/columnBooleanComp.tsx     |  6 +-
 .../tableComp/column/tableColumnComp.tsx      | 65 ++++++++-----------
 .../src/comps/comps/tableComp/tableUtils.tsx  | 15 ++++-
 .../packages/lowcoder/src/i18n/locales/de.ts  |  3 +-
 .../packages/lowcoder/src/i18n/locales/en.ts  |  3 +-
 .../i18n/locales/translation_files/en.json    |  1 +
 .../packages/lowcoder/src/i18n/locales/zh.ts  |  3 +-
 8 files changed, 52 insertions(+), 80 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComp.tsx
index 7e90615044..678bcabb0e 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComp.tsx
@@ -1,7 +1,7 @@
 import { CellProps } from "components/table/EditableCell";
 import { DateTimeComp } from "comps/comps/tableComp/column/columnTypeComps/columnDateTimeComp";
 import { ButtonComp } from "comps/comps/tableComp/column/simpleColumnTypeComps";
-import { MultiCompBuilder, withDefault, withType } from "comps/generators";
+import { withType } from "comps/generators";
 import { trans } from "i18n";
 import { Dropdown } from "lowcoder-design";
 import { BooleanComp } from "./columnTypeComps/columnBooleanComp";
@@ -17,31 +17,6 @@ import { ColumnTagsComp } from "./columnTypeComps/columnTagsComp";
 import { ColumnSelectComp } from "./columnTypeComps/columnSelectComp";
 import { SimpleTextComp } from "./columnTypeComps/simpleTextComp";
 import { ColumnNumberComp } from "./columnTypeComps/ColumnNumberComp";
-import { useState } from "react";
-import { dropdownControl } from "@lowcoder-ee/index.sdk";
-
-const columnValueOptions = [
-  {
-    label: "ID",
-    value: "{{currentRow.id}}",
-  },
-  {
-    label: "Name",
-    value: "{{currentRow.name}}",
-  },
-  {
-    label: "Department",
-    value: "{{currentRow.department}}",
-  },
-  {
-    label: "Date",
-    value: "{{currentRow.date}}",
-  },
-  {
-    label: "Other",
-    value: "",
-  },
-] as const;
 
 const actionOptions = [
   {
@@ -129,15 +104,6 @@ export type ColumnTypeKeys = keyof ColumnTypeMapType;
 
 const TypedColumnTypeComp = withType(ColumnTypeCompMap, "text");
 
-const childrenMap = {
-  comp: TypedColumnTypeComp,
-  valueMap: dropdownControl(columnValueOptions, "")
-};
-
-const TmpColumnTypeComp = new MultiCompBuilder(childrenMap, (props) => {
-  return props;
-}).build();
-
 export class ColumnTypeComp extends TypedColumnTypeComp {
   override getView() {
     const childView = this.children.comp.getView();
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnBooleanComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnBooleanComp.tsx
index 3a1e91f8ae..b65c74eb41 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnBooleanComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnBooleanComp.tsx
@@ -19,13 +19,13 @@ const Wrapper = styled.div`
   padding: 0 8px;
 `;
 
-const IconWrapper = styled.div<{ $style: CheckboxStyleType; ifChecked: boolean }>`
+const IconWrapper = styled.div<{ $style: CheckboxStyleType; $ifChecked: boolean }>`
   height: 22px;
   svg {
     width: 14px;
     height: 22px;
     g {
-      stroke: ${(props) => props.ifChecked && props.$style.checkedBackground} !important;
+      stroke: ${(props) => props.$ifChecked && props.$style.checkedBackground} !important;
     }
   }
 `;
@@ -87,7 +87,7 @@ export const BooleanComp = (function () {
       const CheckBoxComp = () => {
         const style = useStyle(CheckboxStyle);
         return (
-          <IconWrapper $style={style} ifChecked={value}>
+          <IconWrapper $style={style} $ifChecked={value}>
             {value ? (
               <TableCheckedIcon />
             ) : props.falseValues === "x" ? (
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
index 6932a49835..0d5e2ac2be 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
@@ -21,7 +21,7 @@ import {
   withFunction,
   wrapChildAction,
 } from "lowcoder-core";
-import { AlignClose, AlignLeft, AlignRight, IconRadius, BorderWidthIcon, TextSizeIcon, FontFamilyIcon, TextWeigthIcon, ImageCompIcon, controlItem } from "lowcoder-design";
+import { AlignClose, AlignLeft, AlignRight, IconRadius, BorderWidthIcon, TextSizeIcon, FontFamilyIcon, TextWeigthIcon, ImageCompIcon, controlItem, Dropdown, OptionType } from "lowcoder-design";
 import { ColumnTypeComp, ColumnTypeCompMap } from "./columnTypeComp";
 import { ColorControl } from "comps/controls/colorControl";
 import { JSONValue } from "util/jsonTypes";
@@ -57,29 +57,6 @@ const columnFixOptions = [
   },
 ] as const;
 
-const columnValueOptions = [
-  {
-    label: "ID",
-    value: "{{currentRow.id}}",
-  },
-  {
-    label: "Name",
-    value: "{{currentRow.name}}",
-  },
-  {
-    label: "Department",
-    value: "{{currentRow.department}}",
-  },
-  {
-    label: "Date",
-    value: "{{currentRow.date}}",
-  },
-  {
-    label: "Other",
-    value: "",
-  },
-] as const;
-
 const cellColorLabel = trans("table.cellColor");
 const CellColorTempComp = withContext(
   new MultiCompBuilder({ color: ColorOrBoolCodeControl }, (props) => props.color)
@@ -113,11 +90,11 @@ export const columnChildrenMap = {
   isCustom: valueComp<boolean>(false),
   // If it is a data column, it must be the name of the column and cannot be duplicated as a react key
   dataIndex: valueComp<string>(""),
+  columnsList: valueComp<Array<JSONValue>>([]),
   hide: BoolControl,
   sortable: BoolControl,
   width: NumberControl,
   autoWidth: dropdownControl(columnWidthOptions, "auto"),
-  columnMapping: dropdownControl(columnValueOptions, ""),
   render: RenderComp,
   align: HorizontalAlignmentControl,
   tempHide: stateComp<boolean>(false),
@@ -213,27 +190,39 @@ export class ColumnComp extends ColumnInitComp {
 
   propertyView(key: string) {
     const columnType = this.children.render.getSelectedComp().getComp().children.compType.getView();
+    const initialColumns = this.children.render.getSelectedComp().getParams()?.initialColumns as OptionType[] || [];
+    const column = this.children.render.getSelectedComp().getComp().toJsonValue();
+    let columnValue = '{{currentCell}}';
+    if (column.comp?.hasOwnProperty('src')) {
+      columnValue = (column.comp as any).src;
+    } else if (column.comp?.hasOwnProperty('text')) {
+      columnValue = (column.comp as any).text;
+    }
+
     return (
       <>
         {this.children.title.propertyView({
           label: trans("table.columnTitle"),
           placeholder: this.children.dataIndex.getView(),
         })}
-        {this.children.columnMapping.propertyView({
-          label: "Data Mapping",
-          onChange: (value) => {
-            console.log(value)
-            const comp = this.children.render.getSelectedComp().getComp();
-            // let textRawData = "{{currentCell}}";
-            // if (comp.children.hasOwnProperty("text")) {
-            //   textRawData = (comp.children as any).text.toJsonValue();
-            // }
+        <Dropdown
+          showSearch={true}
+          value={columnValue}
+          options={initialColumns}
+          label={trans("table.dataMapping")}
+          onChange={(value) => {
+            // Keep the previous text value, some components do not have text, the default value is currentCell
+            const compType = columnType;
+            let comp: Record<string, string> = { text: value};
+            if(columnType === 'image') {
+              comp = { src: value };
+            }
             this.children.render.dispatchChangeValueAction({
-              compType: columnType,
-              comp: { text: value },
+              compType,
+              comp,
             } as any);
-          }
-        })}
+          }}
+        />
         {/* FIXME: cast type currently, return type of withContext should be corrected later */}
         {this.children.render.getPropertyView()}
         {this.children.showTitle.propertyView({
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
index a9fb52ea7c..9508af8cef 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
@@ -250,6 +250,18 @@ function renderTitle(props: { title: string; editable: boolean }) {
   );
 }
 
+function getInitialColumns(columnsAggrData: ColumnsAggrData) {
+  const initialColumns = Object.keys(columnsAggrData).map(column => ({
+    label: <span style={{textTransform: 'capitalize'}}>{column}</span>,
+    value: `{{currentRow.${column}}}`
+  }))
+  initialColumns.push({
+    label: <span>Select with handlebars</span>,
+    value: '{{currentCell}}',
+  })
+  return initialColumns;
+}
+
 export type CustomColumnType<RecordType> = ColumnType<RecordType> & {
   onWidthResize?: (width: number) => void;
   titleText: string;
@@ -271,7 +283,7 @@ export function columnsToAntdFormat(
   columnsAggrData: ColumnsAggrData,
   onTableEvent: (eventName: any) => void,
 ): Array<CustomColumnType<RecordType>> {
-  console.log(columnsAggrData);
+  const initialColumns = getInitialColumns(columnsAggrData);
   const sortMap: Map<string | undefined, SortOrder> = new Map(
     sort.map((s) => [s.column, s.desc ? "descend" : "ascend"])
   );
@@ -345,6 +357,7 @@ export function columnsToAntdFormat(
               currentRow: _.omit(record, OB_ROW_ORI_INDEX),
               currentIndex: index,
               currentOriginalIndex: tryToNumber(record[OB_ROW_ORI_INDEX]),
+              initialColumns,
             },
             String(record[OB_ROW_ORI_INDEX])
           )
diff --git a/client/packages/lowcoder/src/i18n/locales/de.ts b/client/packages/lowcoder/src/i18n/locales/de.ts
index 298e80ef4d..b30fead70c 100644
--- a/client/packages/lowcoder/src/i18n/locales/de.ts
+++ b/client/packages/lowcoder/src/i18n/locales/de.ts
@@ -1135,6 +1135,7 @@ export const de = {
       "auto": "Auto",
       "fixed": "Festgelegt",
       "columnType": "Säule Typ",
+      "dataMapping": "Datenzuordnung",
       "numberStep": "Schritt",
       "numberStepTooltip": "Die Zahl, auf die der aktuelle Wert erhöht oder verringert wird. Es kann eine ganze Zahl oder eine Dezimalzahl sein",
       "precision": "Präzision",
@@ -2375,7 +2376,7 @@ export const de = {
       "selectBackground": "Ausgewählter Hintergrund"
   },
   "componentDocExtra": {
-      "table": "Zusätzliche Dokumentation für die Tabellenkomponente"
+      "table": table,
   },
   "idSource": {
       "title": "OAuth-Anbieter",
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index 9cc91a970f..b5ec23f09e 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -1258,6 +1258,7 @@ export const en = {
     "auto": "Auto",
     "fixed": "Fixed",
     "columnType": "Column Type",
+    "dataMapping": "Data Mapping",
     "numberStep": "Step",
     "numberStepTooltip": "The number to which the current value is increased or decreased. It can be an integer or decimal",
     "precision": "Precision",
@@ -2573,7 +2574,7 @@ export const en = {
     "selectBackground": "Selected Background"
   },
   "componentDocExtra": {
-    table,
+    "table": table,
   },
   "idSource": {
     "title": "OAuth Providers",
diff --git a/client/packages/lowcoder/src/i18n/locales/translation_files/en.json b/client/packages/lowcoder/src/i18n/locales/translation_files/en.json
index ac390b96cc..f53bbcb575 100644
--- a/client/packages/lowcoder/src/i18n/locales/translation_files/en.json
+++ b/client/packages/lowcoder/src/i18n/locales/translation_files/en.json
@@ -1,3 +1,4 @@
+
 {
   "productName": "Lowcoder",
   "productDesc": "Create software applications for your company and customers with minimal coding experience. Lowcoder is an excellent alternative to Retool, Appsmith, and Tooljet.",
diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts
index a91e25bffd..7ff3d68255 100644
--- a/client/packages/lowcoder/src/i18n/locales/zh.ts
+++ b/client/packages/lowcoder/src/i18n/locales/zh.ts
@@ -1221,6 +1221,7 @@ table: {
     imageSrc: "图片链接",
     imageSize: "图片尺寸",
     columnTitle: "标题",
+    dataMapping: "数据映射",
     showTitle: "显示标题",
     showTitleTooltip: "显示/隐藏表标题中的列标题",
     sortable: "可排序",
@@ -2521,7 +2522,7 @@ calendar: {
     selectBackground: "选中背景",
 },
 componentDocExtra: {
-    table,
+    table: table,
 },
 idSource: {
     title: "OAuth 提供商",

From 964fadf310ff8d527439c49623c1aa3364f6a01d Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Tue, 23 Jan 2024 20:24:05 +0500
Subject: [PATCH 18/97] upgrade antd to v5.13.2

---
 client/packages/lowcoder/package.json         |   2 +-
 .../PermissionDialog/Permission.tsx           |   4 +-
 .../PermissionDialog/PermissionList.tsx       |   2 +-
 .../comps/comps/dateComp/dateRangeUIView.tsx  |   2 +-
 .../videoMeetingControllerComp.tsx            |   5 +-
 .../columnTypeComps/ColumnNumberComp.tsx      |   2 +-
 .../column/columnTypeComps/columnDateComp.tsx |   2 +-
 .../column/columnTypeComps/columnImgComp.tsx  |   2 +-
 .../column/columnTypeComps/columnLinkComp.tsx |   2 +-
 .../columnTypeComps/columnMarkdownComp.tsx    |   2 +-
 .../columnTypeComps/columnProgressComp.tsx    |   2 +-
 .../columnTypeComps/columnStatusComp.tsx      |   6 +-
 .../column/columnTypeComps/columnTagsComp.tsx |   6 +-
 .../column/columnTypeComps/simpleTextComp.tsx |   2 +-
 .../lowcoder/src/comps/hooks/drawerComp.tsx   |   5 +-
 .../src/pages/ApplicationV2/HomeLayout.tsx    |   6 +-
 .../pages/editor/bottom/BottomMetaDrawer.tsx  |  10 +-
 client/yarn.lock                              | 149 ++++++++++--------
 18 files changed, 113 insertions(+), 98 deletions(-)

diff --git a/client/packages/lowcoder/package.json b/client/packages/lowcoder/package.json
index f575d828d7..50dbd813fc 100644
--- a/client/packages/lowcoder/package.json
+++ b/client/packages/lowcoder/package.json
@@ -38,7 +38,7 @@
     "agora-access-token": "^2.0.4",
     "agora-rtc-sdk-ng": "^4.19.0",
     "agora-rtm-sdk": "^1.5.1",
-    "antd": "^5.12.5",
+    "antd": "^5.13.2",
     "axios": "^1.6.2",
     "buffer": "^6.0.3",
     "clsx": "^2.0.0",
diff --git a/client/packages/lowcoder/src/components/PermissionDialog/Permission.tsx b/client/packages/lowcoder/src/components/PermissionDialog/Permission.tsx
index 74beb77aa0..dd591145f3 100644
--- a/client/packages/lowcoder/src/components/PermissionDialog/Permission.tsx
+++ b/client/packages/lowcoder/src/components/PermissionDialog/Permission.tsx
@@ -369,10 +369,10 @@ const PermissionSelector = (props: {
             width: "fit-content",
           }}
           $isVisible={roleSelectVisible}
-          bordered={false}
+          variant="borderless"
           defaultValue={props.supportRoles[0]}
           optionLabelProp="label"
-          onChange={(value) => setSelectRole(value)}
+          onChange={(value: string) => setSelectRole(value as ApplicationRoleType)}
         >
           {props.supportRoles.map((role) => (
             <CustomSelect.Option key={role.value} value={role.value} label={role.label}>
diff --git a/client/packages/lowcoder/src/components/PermissionDialog/PermissionList.tsx b/client/packages/lowcoder/src/components/PermissionDialog/PermissionList.tsx
index d834b7cd05..4fd3abb9ef 100644
--- a/client/packages/lowcoder/src/components/PermissionDialog/PermissionList.tsx
+++ b/client/packages/lowcoder/src/components/PermissionDialog/PermissionList.tsx
@@ -119,7 +119,7 @@ function PermissionLiItem(props: {
             width: "100px",
           }}
           defaultValue={permissionItem.role}
-          bordered={false}
+          variant="borderless"
           optionLabelProp="label"
           onSelect={(value: any, option: any) => {
             if (option.key === "delete") {
diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx
index b349ae0615..ff1478fe46 100644
--- a/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx
@@ -13,7 +13,7 @@ import { omit } from "lodash";
 
 const { RangePicker } = DatePicker;
 
-const RangePickerStyled = styled((props: any) => <RangePicker {...props} />)<{ $style: DateTimeStyleType }>`
+const RangePickerStyled = styled(RangePicker)<{ $style: DateTimeStyleType }>`
   width: 100%;
   ${(props) => props.$style && getStyle(props.$style)}
 `;
diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx
index 6a9cd69803..685673735c 100644
--- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx
@@ -509,8 +509,11 @@ let MTComp = (function () {
                   ? { overflow: "auto", pointerEvents: "auto" }
                   : {}
               }
-              contentWrapperStyle={{ maxHeight: "100%", maxWidth: "100%" }}
               styles={{
+                wrapper: {
+                  maxHeight: "100%",
+                  maxWidth: "100%"
+                }, 
                 body: {
                   padding: 0,
                   backgroundColor: props.style.background,
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/ColumnNumberComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/ColumnNumberComp.tsx
index 20622b3b21..e8e7295791 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/ColumnNumberComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/ColumnNumberComp.tsx
@@ -65,7 +65,7 @@ export const ColumnNumberComp = (function () {
           step={step}
           defaultValue={props.value}
           autoFocus
-          bordered={false}
+          variant="borderless"
           onChange={(value) => {
             value = value ?? 0;
             props.onChange(!float ? Math.floor(value) : value);
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnDateComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnDateComp.tsx
index af5070300c..9149af73c5 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnDateComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnDateComp.tsx
@@ -170,7 +170,7 @@ export const DateEdit = (props: DateEditProps) => {
         superNextIcon={<IconSuperNext />}
         superPrevIcon={<SuperPrevIcon />}
         allowClear={false}
-        bordered={false}
+        variant="borderless"
         autoFocus
         defaultValue={value}
         showTime={props.showTime}
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnImgComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnImgComp.tsx
index 25fd9e1d32..566da4aa9e 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnImgComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnImgComp.tsx
@@ -31,7 +31,7 @@ export const ImageComp = (function () {
       <Input
         defaultValue={props.value}
         autoFocus
-        bordered={false}
+        variant="borderless"
         onChange={(e) => {
           const value = e.target.value;
           props.onChange(value);
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnLinkComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnLinkComp.tsx
index 4ed3b40da8..9a28d18300 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnLinkComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnLinkComp.tsx
@@ -59,7 +59,7 @@ export const LinkComp = (function () {
       <Input
         defaultValue={props.value}
         autoFocus
-        bordered={false}
+        variant="borderless"
         onChange={(e) => {
           const value = e.target.value;
           props.onChange(value);
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnMarkdownComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnMarkdownComp.tsx
index 748308f869..aa131c04e4 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnMarkdownComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnMarkdownComp.tsx
@@ -45,7 +45,7 @@ export const ColumnMarkdownComp = (function () {
       <Input
         defaultValue={props.value}
         autoFocus
-        bordered={false}
+        variant="borderless"
         onChange={(e) => {
           const value = e.target.value;
           props.onChange(value);
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnProgressComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnProgressComp.tsx
index 60f302ce52..1c5e02814f 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnProgressComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnProgressComp.tsx
@@ -94,7 +94,7 @@ export const ProgressComp = (function () {
           max={100}
           defaultValue={props.value}
           autoFocus
-          bordered={false}
+          variant="borderless"
           controls={{ upIcon: <TablePlusIcon />, downIcon: <TableMinusIcon /> }}
           onChange={(value) => {
             props.onChange(Number(value));
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnStatusComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnStatusComp.tsx
index 28a2db0836..04678f33b8 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnStatusComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnStatusComp.tsx
@@ -53,14 +53,14 @@ const StatusEdit = (props: StatusEditPropsType) => {
       <CustomSelect
         autoFocus
         defaultOpen
-        bordered={false}
+        variant="borderless"
         optionLabelProp="children"
         open={open}
         defaultValue={props.value.value}
         style={{ width: "100%" }}
         suffixIcon={<PackUpIcon />}
         showSearch
-        onSearch={(value) => {
+        onSearch={(value: string) => {
           if (defaultStatus.findIndex((item) => item.text.includes(value)) < 0) {
             setStatus([
               ...defaultStatus,
@@ -77,7 +77,7 @@ const StatusEdit = (props: StatusEditPropsType) => {
             status: status.find((item) => item.text === value)?.status || "none",
           });
         }}
-        onChange={(value) => {
+        onChange={(value: string) => {
           props.onChange({
             value,
             status: status.find((item) => item.text === value)?.status || "none",
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnTagsComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnTagsComp.tsx
index 4124d67ee6..fd8eaf9015 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnTagsComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnTagsComp.tsx
@@ -170,14 +170,14 @@ const TagEdit = (props: TagEditPropsType) => {
       <CustomSelect
         autoFocus
         defaultOpen
-        bordered={false}
+        variant="borderless"
         optionLabelProp="children"
         showSearch
         defaultValue={props.value}
         style={{ width: "100%" }}
         open={open}
         suffixIcon={<PackUpIcon />}
-        onSearch={(value) => {
+        onSearch={(value: string) => {
           if (defaultTags.findIndex((item) => item.includes(value)) < 0) {
             setTags([...defaultTags, value]);
           } else {
@@ -185,7 +185,7 @@ const TagEdit = (props: TagEditPropsType) => {
           }
           props.onChange(value);
         }}
-        onChange={(value) => {
+        onChange={(value: string | string[]) => {
           props.onChange(value);
         }}
         dropdownRender={(originNode: ReactNode) => (
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/simpleTextComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/simpleTextComp.tsx
index a0da677aee..574972e4e8 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/simpleTextComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/simpleTextComp.tsx
@@ -26,7 +26,7 @@ export const SimpleTextComp = (function () {
       <Input
         defaultValue={props.value}
         autoFocus
-        bordered={false}
+        variant="borderless"
         onChange={(e) => {
           const value = e.target.value;
           props.onChange(value);
diff --git a/client/packages/lowcoder/src/comps/hooks/drawerComp.tsx b/client/packages/lowcoder/src/comps/hooks/drawerComp.tsx
index 1ae4b96734..f885e2436c 100644
--- a/client/packages/lowcoder/src/comps/hooks/drawerComp.tsx
+++ b/client/packages/lowcoder/src/comps/hooks/drawerComp.tsx
@@ -126,8 +126,11 @@ let TmpDrawerComp = (function () {
               resizable={resizable}
               onResizeStop={onResizeStop}
               rootStyle={props.visible.value ? { overflow: "auto", pointerEvents: "auto" } : {}}
-              contentWrapperStyle={{ maxHeight: "100%", maxWidth: "100%" }}
               styles={{
+                wrapper: {
+                  maxHeight: "100%",
+                  maxWidth: "100%",
+                },
                 body: {
                   padding: 0,
                   backgroundColor: props.style.background
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
index 9ecd9aa16d..fde596953d 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
@@ -365,9 +365,9 @@ export function HomeLayout(props: HomeLayoutProps) {
       <OperationWrapper>
         {mode !== "folders" && mode !== "module" && (
           <FilterDropdown
-            bordered={false}
+            variant="borderless"
             value={filterBy}
-            onChange={(value) => setFilterBy(value as HomeResKey)}
+            onChange={(value: any) => setFilterBy(value as HomeResKey)}
             options={[
               getFilterMenuItem(HomeResTypeEnum.All),
               getFilterMenuItem(HomeResTypeEnum.Application),
@@ -375,7 +375,7 @@ export function HomeLayout(props: HomeLayoutProps) {
               getFilterMenuItem(HomeResTypeEnum.Navigation),
               ...(mode !== "trash" ? [getFilterMenuItem(HomeResTypeEnum.Folder)] : []),
             ]}
-            getPopupContainer={(node) => node}
+            getPopupContainer={(node: any) => node}
             suffixIcon={<ArrowSolidIcon />}
           />
         )}
diff --git a/client/packages/lowcoder/src/pages/editor/bottom/BottomMetaDrawer.tsx b/client/packages/lowcoder/src/pages/editor/bottom/BottomMetaDrawer.tsx
index 6dd207ef6c..197389596e 100644
--- a/client/packages/lowcoder/src/pages/editor/bottom/BottomMetaDrawer.tsx
+++ b/client/packages/lowcoder/src/pages/editor/bottom/BottomMetaDrawer.tsx
@@ -280,11 +280,6 @@ export default function BottomMetaDrawer(props: BottomMetaDrawerProps) {
       <Drawer
         $vis={visible}
         mask={false}
-        contentWrapperStyle={{
-          height: "100%",
-          boxShadow: "none",
-          borderRadius: "0",
-        }}
         rootStyle={{
           position: "absolute",
           height: "100%",
@@ -294,6 +289,11 @@ export default function BottomMetaDrawer(props: BottomMetaDrawerProps) {
         title={<DrawerTitleView />}
         styles={{
           header: headerWrapperStyle,
+          wrapper: {
+            height: "100%",
+            boxShadow: "none",
+            borderRadius: "0",
+          },
           body: {
             padding: "0 0 0 8px",
             overflowX: "hidden",
diff --git a/client/yarn.lock b/client/yarn.lock
index 9dead2fc88..876df404e7 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -82,8 +82,8 @@ __metadata:
   linkType: hard
 
 "@ant-design/cssinjs@npm:^1.18.2":
-  version: 1.18.2
-  resolution: "@ant-design/cssinjs@npm:1.18.2"
+  version: 1.18.4
+  resolution: "@ant-design/cssinjs@npm:1.18.4"
   dependencies:
     "@babel/runtime": ^7.11.1
     "@emotion/hash": ^0.8.0
@@ -95,7 +95,7 @@ __metadata:
   peerDependencies:
     react: ">=16.0.0"
     react-dom: ">=16.0.0"
-  checksum: b3430547a625fae25b0b459fc9055422985fb1855f0296bb0208d51586e7c0c1e1dae2dc59b6af28234f4b3de938434a0b737bde59d8c4f52feb7a14e7fa8202
+  checksum: c6028097929a9948d1e9d5441aeab51ff824edacf98976fb06c146397c7cc9b2fc3f88765a0d93345b1fbbf6b766f638260652d5637fcbf6e6bbafe4e79e60bd
   languageName: node
   linkType: hard
 
@@ -1722,7 +1722,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.10.4, @babel/runtime@npm:^7.11.1, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.16.7, @babel/runtime@npm:^7.18.0, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.22.5, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.6, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2":
+"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.11.1, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.18.0, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2":
   version: 7.23.7
   resolution: "@babel/runtime@npm:7.23.7"
   dependencies:
@@ -1731,6 +1731,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@babel/runtime@npm:^7.10.4, @babel/runtime@npm:^7.16.7, @babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.22.5, @babel/runtime@npm:^7.23.6":
+  version: 7.23.8
+  resolution: "@babel/runtime@npm:7.23.8"
+  dependencies:
+    regenerator-runtime: ^0.14.0
+  checksum: 0bd5543c26811153822a9f382fd39886f66825ff2a397a19008011376533747cd05c33a91f6248c0b8b0edf0448d7c167ebfba34786088f1b7eb11c65be7dfc3
+  languageName: node
+  linkType: hard
+
 "@babel/template@npm:^7.22.15, @babel/template@npm:^7.3.3":
   version: 7.22.15
   resolution: "@babel/template@npm:7.22.15"
@@ -3223,9 +3232,9 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@rc-component/tour@npm:~1.11.1":
-  version: 1.11.1
-  resolution: "@rc-component/tour@npm:1.11.1"
+"@rc-component/tour@npm:~1.12.2":
+  version: 1.12.3
+  resolution: "@rc-component/tour@npm:1.12.3"
   dependencies:
     "@babel/runtime": ^7.18.0
     "@rc-component/portal": ^1.0.0-9
@@ -3235,7 +3244,7 @@ __metadata:
   peerDependencies:
     react: ">=16.9.0"
     react-dom: ">=16.9.0"
-  checksum: 4c9c509f775cd3c4bdc2d73efe27f2c1ec19132f5a0011c1e82420bc243fdb2fc66bfeee0bd4c4073a1c2621d9aa0d303a71f233db6be5140a397c3f94979090
+  checksum: 1a137d235e42df80d490023d452d6b571ad1afc07a9b5d3cd9312ae8657b5f2d68209a5c7144d2b5fb9e50712a6d927a1218ea2cab4f5337a7265fa91ca9d023
   languageName: node
   linkType: hard
 
@@ -5203,9 +5212,9 @@ __metadata:
   languageName: node
   linkType: hard
 
-"antd@npm:^5.12.5":
-  version: 5.12.8
-  resolution: "antd@npm:5.12.8"
+"antd@npm:^5.13.2":
+  version: 5.13.2
+  resolution: "antd@npm:5.13.2"
   dependencies:
     "@ant-design/colors": ^7.0.2
     "@ant-design/cssinjs": ^1.18.2
@@ -5214,23 +5223,23 @@ __metadata:
     "@ctrl/tinycolor": ^3.6.1
     "@rc-component/color-picker": ~1.5.1
     "@rc-component/mutate-observer": ^1.1.0
-    "@rc-component/tour": ~1.11.1
+    "@rc-component/tour": ~1.12.2
     "@rc-component/trigger": ^1.18.2
     classnames: ^2.5.1
     copy-to-clipboard: ^3.3.3
     dayjs: ^1.11.10
     qrcode.react: ^3.1.0
-    rc-cascader: ~3.20.0
+    rc-cascader: ~3.21.0
     rc-checkbox: ~3.1.0
     rc-collapse: ~3.7.2
     rc-dialog: ~9.3.4
-    rc-drawer: ~6.5.2
+    rc-drawer: ~7.0.0
     rc-dropdown: ~4.1.0
     rc-field-form: ~1.41.0
     rc-image: ~7.5.1
-    rc-input: ~1.3.11
-    rc-input-number: ~8.4.0
-    rc-mentions: ~2.9.1
+    rc-input: ~1.4.3
+    rc-input-number: ~8.6.1
+    rc-mentions: ~2.10.1
     rc-menu: ~9.12.4
     rc-motion: ^2.9.0
     rc-notification: ~5.3.0
@@ -5240,16 +5249,16 @@ __metadata:
     rc-rate: ~2.12.0
     rc-resize-observer: ^1.4.0
     rc-segmented: ~2.2.2
-    rc-select: ~14.10.0
+    rc-select: ~14.11.0
     rc-slider: ~10.5.0
     rc-steps: ~6.0.1
     rc-switch: ~4.1.0
-    rc-table: ~7.36.1
-    rc-tabs: ~12.14.1
-    rc-textarea: ~1.5.3
+    rc-table: ~7.37.0
+    rc-tabs: ~14.0.0
+    rc-textarea: ~1.6.3
     rc-tooltip: ~6.1.3
     rc-tree: ~5.8.2
-    rc-tree-select: ~5.15.0
+    rc-tree-select: ~5.17.0
     rc-upload: ~4.5.2
     rc-util: ^5.38.1
     scroll-into-view-if-needed: ^3.1.0
@@ -5257,7 +5266,7 @@ __metadata:
   peerDependencies:
     react: ">=16.9.0"
     react-dom: ">=16.9.0"
-  checksum: 827334d691daccfbb59519f998b5718c20cffd8a1c718557ca7f59425a3524515a655129040b6d8b53b9e0a3c0c58c391c752f0573ccc738c41028c3c39c06ac
+  checksum: b58f985678cfe63800f2276aebc64bd91216b1a6fd25f287ddb9883c923b8d32707ced161799f146314c0be4f6eead1dbdb30127bb003240416863ac2dc91974
   languageName: node
   linkType: hard
 
@@ -12026,7 +12035,7 @@ __metadata:
     agora-access-token: ^2.0.4
     agora-rtc-sdk-ng: ^4.19.0
     agora-rtm-sdk: ^1.5.1
-    antd: ^5.12.5
+    antd: ^5.13.2
     axios: ^1.6.2
     buffer: ^6.0.3
     clsx: ^2.0.0
@@ -14168,20 +14177,20 @@ __metadata:
   languageName: node
   linkType: hard
 
-"rc-cascader@npm:~3.20.0":
-  version: 3.20.0
-  resolution: "rc-cascader@npm:3.20.0"
+"rc-cascader@npm:~3.21.0":
+  version: 3.21.2
+  resolution: "rc-cascader@npm:3.21.2"
   dependencies:
     "@babel/runtime": ^7.12.5
     array-tree-filter: ^2.1.0
     classnames: ^2.3.1
-    rc-select: ~14.10.0
+    rc-select: ~14.11.0
     rc-tree: ~5.8.1
     rc-util: ^5.37.0
   peerDependencies:
     react: ">=16.9.0"
     react-dom: ">=16.9.0"
-  checksum: fd85091f90c7a82ff8e240c356de9f1070e6371217a7ab852908b64746488586d8c9b2893ce5895373e1e8d55c36d5cd899808ec6d7938bfe81d19be2ceee94a
+  checksum: 448dd4562edb67d24259e620b026061597c1ccea2823474b4fdeec4d789f7c241bfb5e1e99daab29bb1a9c5f103f741efd4531f2f506ab35058914765be313df
   languageName: node
   linkType: hard
 
@@ -14230,9 +14239,9 @@ __metadata:
   languageName: node
   linkType: hard
 
-"rc-drawer@npm:~6.5.2":
-  version: 6.5.2
-  resolution: "rc-drawer@npm:6.5.2"
+"rc-drawer@npm:~7.0.0":
+  version: 7.0.0
+  resolution: "rc-drawer@npm:7.0.0"
   dependencies:
     "@babel/runtime": ^7.10.1
     "@rc-component/portal": ^1.1.1
@@ -14242,7 +14251,7 @@ __metadata:
   peerDependencies:
     react: ">=16.9.0"
     react-dom: ">=16.9.0"
-  checksum: e96908f641ea0a4b26e7142a932cefe60ee34c03c6c569a6070af770b0be8a883e89521217d8391957254b0ed88b4ac1735129c9e062528db0751bfd0222a0c1
+  checksum: 57c646c1b99be344c995eb67c36e9f78f1af6c1c3fce78d79738fe48dbb682f0143c993888535aaa5a912906ed713cd1df5d43f4a982bd98399467e1b539987f
   languageName: node
   linkType: hard
 
@@ -14306,25 +14315,25 @@ __metadata:
   languageName: node
   linkType: hard
 
-"rc-input-number@npm:~8.4.0":
-  version: 8.4.0
-  resolution: "rc-input-number@npm:8.4.0"
+"rc-input-number@npm:~8.6.1":
+  version: 8.6.1
+  resolution: "rc-input-number@npm:8.6.1"
   dependencies:
     "@babel/runtime": ^7.10.1
     "@rc-component/mini-decimal": ^1.0.1
     classnames: ^2.2.5
-    rc-input: ~1.3.5
+    rc-input: ~1.4.0
     rc-util: ^5.28.0
   peerDependencies:
     react: ">=16.9.0"
     react-dom: ">=16.9.0"
-  checksum: 00bb0b40c0f13747315790d1ec2b8707abee8388c1623dee5ebdf51cc93ae6441f200d19ecda5f85e44dd180d9e93dadf4cb8ce2e02c3a4db81f1e69d9b4dc04
+  checksum: 20b348ba1f134983fd5cc5884bd3ff3a3ff57fc072896f8fb6a97d0e239f72136331a5a728b4b5b5b2f6287d263a262971a8c36a4268d585fb4bbea2b332e28a
   languageName: node
   linkType: hard
 
-"rc-input@npm:~1.3.11, rc-input@npm:~1.3.5":
-  version: 1.3.11
-  resolution: "rc-input@npm:1.3.11"
+"rc-input@npm:~1.4.0, rc-input@npm:~1.4.3":
+  version: 1.4.3
+  resolution: "rc-input@npm:1.4.3"
   dependencies:
     "@babel/runtime": ^7.11.1
     classnames: ^2.2.1
@@ -14332,25 +14341,25 @@ __metadata:
   peerDependencies:
     react: ">=16.0.0"
     react-dom: ">=16.0.0"
-  checksum: e548f5e46c34058cb53baba3891e1d307cd8d6d2f01896cb14bf78dea84c179e7e05fb23829704f89a4610bbaf278e713702ea64ad9e94813c425d821c70502e
+  checksum: 7c4f9cb5e21caf7dd2b6f8c70fe5d493e43e5db0e0fbf8414512b8217f24c198c549bfbd4422461482389904595df8ef794a677aea37d66bbd8030dafa4799b6
   languageName: node
   linkType: hard
 
-"rc-mentions@npm:~2.9.1":
-  version: 2.9.1
-  resolution: "rc-mentions@npm:2.9.1"
+"rc-mentions@npm:~2.10.1":
+  version: 2.10.1
+  resolution: "rc-mentions@npm:2.10.1"
   dependencies:
     "@babel/runtime": ^7.22.5
     "@rc-component/trigger": ^1.5.0
     classnames: ^2.2.6
-    rc-input: ~1.3.5
+    rc-input: ~1.4.0
     rc-menu: ~9.12.0
-    rc-textarea: ~1.5.0
+    rc-textarea: ~1.6.1
     rc-util: ^5.34.1
   peerDependencies:
     react: ">=16.9.0"
     react-dom: ">=16.9.0"
-  checksum: f5b7ad6a3f674e259e243c12450f81ee7f69298a4cce8a4ef9a467622651f7452eebcfdf737e8587239d77a9f109aafafe5e547401ec806e3a2a14a9df20800e
+  checksum: 0b1fc9690cbf76a72acf020a94eb1a33fdd2545c8170622c99e925b630d25874ab52110376861d1ec95ca50fcd8cef417e7c83fb723592073a798d86e9bb24e6
   languageName: node
   linkType: hard
 
@@ -14534,9 +14543,9 @@ __metadata:
   languageName: node
   linkType: hard
 
-"rc-select@npm:~14.10.0":
-  version: 14.10.0
-  resolution: "rc-select@npm:14.10.0"
+"rc-select@npm:~14.11.0, rc-select@npm:~14.11.0-0":
+  version: 14.11.0
+  resolution: "rc-select@npm:14.11.0"
   dependencies:
     "@babel/runtime": ^7.10.1
     "@rc-component/trigger": ^1.5.0
@@ -14548,7 +14557,7 @@ __metadata:
   peerDependencies:
     react: "*"
     react-dom: "*"
-  checksum: 1f922000e64338b7c43ba0e67429e482291f4e8d9e2d1977e0414171ff388050de4802c780baaa4e48c299b025c2334227382d3c47ca1f2888dbef83c73ab43e
+  checksum: e3258545a64c687b2e3c456edf8c426961cf69823d67972580db49f470cd5bd11a7e1a55033c206b542c5c130ee45a2dd2436a9dae00c6528190d170eef6ff31
   languageName: node
   linkType: hard
 
@@ -14594,9 +14603,9 @@ __metadata:
   languageName: node
   linkType: hard
 
-"rc-table@npm:~7.36.1":
-  version: 7.36.1
-  resolution: "rc-table@npm:7.36.1"
+"rc-table@npm:~7.37.0":
+  version: 7.37.0
+  resolution: "rc-table@npm:7.37.0"
   dependencies:
     "@babel/runtime": ^7.10.1
     "@rc-component/context": ^1.4.0
@@ -14607,13 +14616,13 @@ __metadata:
   peerDependencies:
     react: ">=16.9.0"
     react-dom: ">=16.9.0"
-  checksum: b4441944eb0feb011091caeb433d455dbf52c8c16b39b0730a48bce05b28ce8928344053c8b9eb5f3dab60f1590edcfaeca05b5cf6e9c77832cf379e6f1568c7
+  checksum: bf6a2bf791ad06bc66333ec500c37236cf3b6d823607a1ca933331b5ff24498c1e2ae8bc39900ea3e0d2a598f4273c0ce99fc355799d3e182f0285774f88cbd7
   languageName: node
   linkType: hard
 
-"rc-tabs@npm:~12.14.1":
-  version: 12.14.1
-  resolution: "rc-tabs@npm:12.14.1"
+"rc-tabs@npm:~14.0.0":
+  version: 14.0.0
+  resolution: "rc-tabs@npm:14.0.0"
   dependencies:
     "@babel/runtime": ^7.11.2
     classnames: 2.x
@@ -14625,23 +14634,23 @@ __metadata:
   peerDependencies:
     react: ">=16.9.0"
     react-dom: ">=16.9.0"
-  checksum: 6f8c39336670f7f21b970a4fcad73b711f45982c76ea2d83a4c00e7d06f707da21b107211548b16320cd13ba292eb5a4edccdc95179aaa88e6db24eea488e18c
+  checksum: 4847c623b8bb219ad80d4ebd59ae7e389feb2c1a9eacd18127b3f567d0c1db555b87e88cc72bf21201d8a60cac0eed6f930261f368979d720a8a22e39567ef85
   languageName: node
   linkType: hard
 
-"rc-textarea@npm:~1.5.0, rc-textarea@npm:~1.5.3":
-  version: 1.5.3
-  resolution: "rc-textarea@npm:1.5.3"
+"rc-textarea@npm:~1.6.1, rc-textarea@npm:~1.6.3":
+  version: 1.6.3
+  resolution: "rc-textarea@npm:1.6.3"
   dependencies:
     "@babel/runtime": ^7.10.1
     classnames: ^2.2.1
-    rc-input: ~1.3.5
+    rc-input: ~1.4.0
     rc-resize-observer: ^1.0.0
     rc-util: ^5.27.0
   peerDependencies:
     react: ">=16.9.0"
     react-dom: ">=16.9.0"
-  checksum: 44ca7e5b62938c18ef57f80f9ed08dcadc6b741dd420a53b1afcbd3d7c23d72bc5335b28e17fa70782f699cd9d1108f8be56db3e326c6abd364a1cbe8c480b43
+  checksum: a9774cafd228da8900859187db39b3e3ebe0fc53abe727af14a545062ba6b0d6a568f356fed77394f0f1296b328d28eba9c50068c8034d40967de8a6e283b1f5
   languageName: node
   linkType: hard
 
@@ -14659,19 +14668,19 @@ __metadata:
   languageName: node
   linkType: hard
 
-"rc-tree-select@npm:~5.15.0":
-  version: 5.15.0
-  resolution: "rc-tree-select@npm:5.15.0"
+"rc-tree-select@npm:~5.17.0":
+  version: 5.17.0
+  resolution: "rc-tree-select@npm:5.17.0"
   dependencies:
     "@babel/runtime": ^7.10.1
     classnames: 2.x
-    rc-select: ~14.10.0
+    rc-select: ~14.11.0-0
     rc-tree: ~5.8.1
     rc-util: ^5.16.1
   peerDependencies:
     react: "*"
     react-dom: "*"
-  checksum: 34ed86e65a5ab0a3b80f25ccced3c1d4641621638cf4d5953af8420306a513e93194a9e30f5e689e4e4e8b44f1461b82b5443f71d72f6ca72e1f612487e09d87
+  checksum: 245061c480ae5625fdb016a098770d6bfac0a6445856d4870a02b78e236a6510e241a4eaef36bb36236c6dca936a992a967e327a04d0440685ad6d0ba7c18b12
   languageName: node
   linkType: hard
 

From a81e175405f05556e6738fa10b44adf8d7953dd0 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Wed, 24 Jan 2024 23:41:54 +0100
Subject: [PATCH 19/97] Pushing from header to left meno bar

---
 .../lowcoder/src/comps/editorState.tsx        |  2 +-
 .../lowcoder/src/pages/common/header.tsx      | 28 ++++-----
 .../src/pages/editor/editorSkeletonView.tsx   |  7 ++-
 .../lowcoder/src/pages/editor/editorView.tsx  | 57 ++++++++++++++++---
 .../lowcoder/src/util/localStorageUtil.ts     |  3 +-
 5 files changed, 66 insertions(+), 31 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/editorState.tsx b/client/packages/lowcoder/src/comps/editorState.tsx
index 5e87d3b57c..9ec9e54151 100644
--- a/client/packages/lowcoder/src/comps/editorState.tsx
+++ b/client/packages/lowcoder/src/comps/editorState.tsx
@@ -2,7 +2,7 @@ import { isContainer } from "comps/comps/containerBase";
 import { RootComp as RootCompTmp } from "comps/comps/rootComp";
 import { PositionParams } from "layout";
 import _ from "lodash";
-import React, { ReactNode, useContext } from "react";
+import React, { ReactNode } from "react";
 import {
   BottomResComp,
   BottomResListComp,
diff --git a/client/packages/lowcoder/src/pages/common/header.tsx b/client/packages/lowcoder/src/pages/common/header.tsx
index e7dd9d9dd7..3581a3eaf4 100644
--- a/client/packages/lowcoder/src/pages/common/header.tsx
+++ b/client/packages/lowcoder/src/pages/common/header.tsx
@@ -287,29 +287,34 @@ function HeaderProfile(props: { user: User }) {
 
 export type PanelStatus = { left: boolean; bottom: boolean; right: boolean };
 export type TogglePanel = (panel?: keyof PanelStatus) => void;
-export type EnabledCollissionStatus = "true" | "false";
+
 export type EditorModeStatus = "layout" | "logic" | "both";
 export type ToggleEditorModeStatus = (
   editorModeStatus?: EditorModeStatus
 ) => void;
+
+/* 
+// export type EnabledCollissionStatus = "true" | "false";
 export type ToggleCollissionStatus = (
   collissionStatus?: EnabledCollissionStatus
-) => void;
+) => void; 
+*/
 
 type HeaderProps = {
   panelStatus: PanelStatus;
   togglePanel: TogglePanel;
   editorModeStatus: EditorModeStatus;
   toggleEditorModeStatus: ToggleEditorModeStatus;
-  collissionStatus: EnabledCollissionStatus;
-  toggleCollissionStatus: ToggleCollissionStatus;
+  // collissionStatus: EnabledCollissionStatus;
+  // toggleCollissionStatus: ToggleCollissionStatus;
 };
 
 // header in editor page
 export default function Header(props: HeaderProps) {
   const editorState = useContext(EditorContext);
   const { togglePanel } = props;
-  const { toggleEditorModeStatus, toggleCollissionStatus } = props;
+  const { toggleEditorModeStatus } = props;
+  // const { toggleCollissionStatus } = props;
   const { left, bottom, right } = props.panelStatus;
   const user = useSelector(getUser);
   const application = useSelector(currentApplication);
@@ -413,18 +418,7 @@ export default function Header(props: HeaderProps) {
 
   const headerMiddle = (
     <>
-      <>
-        <p style={{ color: "#ffffff", marginTop: "10px" }}>
-          Layers 
-        </p>
-        <Switch
-          checked={props.collissionStatus == "true"}
-          disabled={false}
-          onChange={(value: any) => {
-            toggleCollissionStatus(value == true ? "true" : "false");
-            editorState.setCollissionStatus(value == true ? "true" : "false");
-          }}
-        />
+      <>      
       </>
       <Radio.Group
         onChange={onEditorStateValueChange}
diff --git a/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx b/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx
index fa55546108..58d7ffd5a4 100644
--- a/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx
+++ b/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx
@@ -63,15 +63,16 @@ export default function EditorSkeletonView() {
         <Header
           panelStatus={panelStatus}
           togglePanel={_.noop}
-          collissionStatus={collissionStatus}
-          toggleCollissionStatus={_.noop}
           editorModeStatus={editorModeStatus}
           toggleEditorModeStatus={_.noop}
         />
         <Body>
           <SiderStyled />
           {panelStatus.left && (
-            <LeftPanel>
+            <LeftPanel
+              collissionStatus={collissionStatus}
+              toggleCollissionStatus={_.noop}
+            >
               <StyledSkeleton active paragraph={{ rows: 10 }} />
             </LeftPanel>
           )}
diff --git a/client/packages/lowcoder/src/pages/editor/editorView.tsx b/client/packages/lowcoder/src/pages/editor/editorView.tsx
index 81b7ec0842..e1b966688a 100644
--- a/client/packages/lowcoder/src/pages/editor/editorView.tsx
+++ b/client/packages/lowcoder/src/pages/editor/editorView.tsx
@@ -20,9 +20,7 @@ import Header, {
   PanelStatus,
   TogglePanel,
   EditorModeStatus,
-  ToggleEditorModeStatus,
-  EnabledCollissionStatus,
-  ToggleCollissionStatus,
+  ToggleEditorModeStatus
 } from "pages/common/header";
 import { HelpDropdown } from "pages/common/help";
 import { PreviewHeader } from "pages/common/previewHeader";
@@ -76,6 +74,8 @@ import {
 import Bottom from "./bottom/BottomPanel";
 import { LeftContent } from "./LeftContent";
 import { isAggregationApp } from "util/appUtils";
+import { Switch } from "antd";
+import { SwitchChangeEventHandler } from "antd/es/switch";
 
 const HookCompContainer = styled.div`
   pointer-events: none;
@@ -141,6 +141,16 @@ const HelpDiv = styled.div`
     }
   }
 `;
+
+const LayoutMenuDiv = styled.div`
+  > div {
+    left: 6px;
+    right: auto;
+    height: 28px;
+    top: 15px;
+  }
+`;
+
 const SettingsDiv = styled.div`
   display: flex;
   flex-direction: column;
@@ -200,6 +210,7 @@ interface EditorViewProps {
 enum SiderKey {
   State = "state",
   Setting = "setting",
+  Layout = "layout",
 }
 
 const items = [
@@ -211,8 +222,18 @@ const items = [
     key: SiderKey.Setting,
     icon: <LeftSettingIcon />,
   },
+  {
+    key: SiderKey.Layout,
+    icon: <LeftSettingIcon />,
+  },
 ];
 
+  // added by Fred to set comp collision state
+export type EnabledCollissionStatus = "true" | "false"; // "true" means collission is enabled, "false" means collission is disabled
+export  type ToggleCollissionStatus = (
+    collissionStatus?: EnabledCollissionStatus
+  ) => void;
+
 function EditorView(props: EditorViewProps) {
   const { uiComp } = props;
   const editorState = useContext(EditorContext);
@@ -259,7 +280,7 @@ function EditorView(props: EditorViewProps) {
     [panelStatus, prePanelStatus]
   );
 
-  // added by Fred  to set comp collision state
+
   const [collisionStatus, setCollisionStatus] = useState(() => {
     return showCollission ? DefaultCollissionStatus : getCollissionStatus();
   });
@@ -381,9 +402,7 @@ function EditorView(props: EditorViewProps) {
         togglePanel={togglePanel}
         panelStatus={panelStatus}
         toggleEditorModeStatus={toggleEditorModeStatus}
-        toggleCollissionStatus={toggleCollissionStatus}
-        editorModeStatus={editorModeStatus}
-        collissionStatus={collisionStatus}
+        editorModeStatus={editorModeStatus} 
       />
       <Helmet>{application && <title>{application.name}</title>}</Helmet>
       {showNewUserGuide && <EditorTutorials />}
@@ -395,7 +414,8 @@ function EditorView(props: EditorViewProps) {
       >
         <Body>
           <SiderWrapper>
-            <Sider width={40}>
+            <Sider width={40} >
+              
               <Menu
                 theme="dark"
                 mode="inline"
@@ -404,7 +424,9 @@ function EditorView(props: EditorViewProps) {
                 items={items}
                 disabled={showAppSnapshot}
                 onClick={(params) => clickMenu(params)}
-              />
+              >
+              </Menu>
+              
               {!showAppSnapshot && (
                 <HelpDiv>
                   <HelpDropdown
@@ -451,6 +473,23 @@ function EditorView(props: EditorViewProps) {
                   {props.preloadComp.getJSLibraryPropertyView()}
                 </SettingsDiv>
               )}
+
+              
+
+              {menuKey === SiderKey.Layout && (
+                <SettingsDiv>
+                  <Switch
+                    checked={editorState.collissionStatus == "true"}
+                    disabled={false}
+                    onChange={(value: any) => {
+                      toggleCollissionStatus(value == true ? "true" : "false");
+                      editorState.setCollissionStatus(value == true ? "true" : "false");
+                    }}
+                  />
+                   <Divider />            
+                </SettingsDiv>
+              )}
+
             </LeftPanel>
           )}
           <MiddlePanel>
diff --git a/client/packages/lowcoder/src/util/localStorageUtil.ts b/client/packages/lowcoder/src/util/localStorageUtil.ts
index c6ee587ad2..15e951909c 100644
--- a/client/packages/lowcoder/src/util/localStorageUtil.ts
+++ b/client/packages/lowcoder/src/util/localStorageUtil.ts
@@ -1,4 +1,5 @@
-import { EnabledCollissionStatus, PanelStatus } from "pages/common/header";
+import { PanelStatus } from "pages/common/header";
+import { EnabledCollissionStatus } from "pages/editor/editorView";
 import { EditorModeStatus } from "pages/common/header";
 import log from "loglevel";
 import { JSONValue } from "util/jsonTypes";

From 875bdfdc71bad0fff4706aebfea77a3542f61090 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Thu, 25 Jan 2024 19:17:12 +0100
Subject: [PATCH 20/97] Sortable Display of Components

---
 client/packages/lowcoder-core/lib/index.d.ts  |   2 +-
 .../lowcoder/src/comps/editorState.tsx        |  20 ++--
 client/packages/lowcoder/src/layout/utils.ts  |  11 +-
 .../lowcoder/src/pages/common/header.tsx      |  30 -----
 .../lowcoder/src/pages/editor/LeftContent.tsx | 107 +++++++++++++++---
 .../src/pages/editor/editorSkeletonView.tsx   |   8 +-
 .../lowcoder/src/pages/editor/editorView.tsx  |  34 +++---
 .../src/pages/tutorials/tutorialsConstant.tsx |   5 -
 .../lowcoder/src/util/localStorageUtil.ts     |  20 ++--
 9 files changed, 142 insertions(+), 95 deletions(-)

diff --git a/client/packages/lowcoder-core/lib/index.d.ts b/client/packages/lowcoder-core/lib/index.d.ts
index d0db17798c..b29a693f4f 100644
--- a/client/packages/lowcoder-core/lib/index.d.ts
+++ b/client/packages/lowcoder-core/lib/index.d.ts
@@ -454,7 +454,7 @@ declare enum CompActionTypes {
      * broadcast other actions in comp tree structure.
      * used for encapsulate MultiBaseComp
      */
-    BROADCAST = "BROADCAST"
+    BROADCAST = "BROADCAST",
 }
 type ExtraActionType = "layout" | "delete" | "add" | "modify" | "rename" | "recover" | "upgrade";
 type ActionExtraInfo = {
diff --git a/client/packages/lowcoder/src/comps/editorState.tsx b/client/packages/lowcoder/src/comps/editorState.tsx
index 9ec9e54151..ee9db5475c 100644
--- a/client/packages/lowcoder/src/comps/editorState.tsx
+++ b/client/packages/lowcoder/src/comps/editorState.tsx
@@ -17,7 +17,7 @@ import { NameAndExposingInfo } from "./utils/exposingTypes";
 import { checkName } from "./utils/rename";
 import { trans } from "i18n";
 import { UiLayoutType } from "./comps/uiComp";
-import { getCollissionStatus, getEditorModeStatus } from "util/localStorageUtil";
+import { getCollisionStatus, getEditorModeStatus } from "util/localStorageUtil";
 
 type RootComp = InstanceType<typeof RootCompTmp>;
 
@@ -47,7 +47,7 @@ export class EditorState {
   readonly showPropertyPane: boolean = false;
   readonly selectedCompNames: Set<string> = new Set();
   readonly editorModeStatus: string = "";
-  readonly collissionStatus: string = "";
+  readonly collisionStatus: string = "";
   readonly isDragging: boolean = false;
   readonly draggingCompType: string = "button";
   readonly forceShowGrid: boolean = false; // show grid lines
@@ -65,12 +65,12 @@ export class EditorState {
     rootComp: RootComp,
     setEditorState: (fn: (editorState: EditorState) => EditorState) => void,
     initialEditorModeStatus: string = getEditorModeStatus(),
-    initialCollissionStatus: string = getCollissionStatus()
+    initialCollisionStatus: string = getCollisionStatus()
   ) {
     this.rootComp = rootComp;
     this.setEditorState = setEditorState;
     this.editorModeStatus = initialEditorModeStatus;
-    this.collissionStatus = initialCollissionStatus;
+    this.collisionStatus = initialCollisionStatus;
   }
 
   /**
@@ -134,12 +134,13 @@ export class EditorState {
 
   uiCompInfoList(): Array<CompInfo> {
     const compMap = this.getAllUICompMap();
-    return Object.values(compMap).map((item) => {
+    return Object.entries(compMap).map(([key, item]) => {
       return {
         name: item.children.name.getView(),
         type: item.children.compType.getView(),
         data: item.children.comp.exposingValues,
         dataDesc: item.children.comp.exposingInfo().propertyDesc,
+        key: key,
       };
     });
   }
@@ -355,8 +356,8 @@ export class EditorState {
     this.changeState({ editorModeStatus: newEditorModeStatus });
   }
 
-  setCollissionStatus(newCollissionStatus: string) {
-    this.changeState({ collissionStatus: newCollissionStatus });
+  setCollisionStatus(newCollisionStatus: string) {
+    this.changeState({ collisionStatus: newCollisionStatus });
   }
 
   setDragging(dragging: boolean) {
@@ -512,9 +513,10 @@ export class EditorState {
   getAppType(): UiLayoutType {
     return this.getUIComp().children.compType.getView();
   }
-  getCollissionStatus(): string {
-    return this.collissionStatus;
+  getCollisionStatus(): string {
+    return this.collisionStatus;
   }
+  
 }
 export const EditorContext = React.createContext<EditorState>(undefined as any);
 
diff --git a/client/packages/lowcoder/src/layout/utils.ts b/client/packages/lowcoder/src/layout/utils.ts
index c55c44dc2a..6a9f0494d0 100644
--- a/client/packages/lowcoder/src/layout/utils.ts
+++ b/client/packages/lowcoder/src/layout/utils.ts
@@ -1,11 +1,13 @@
 import { UICompType } from "comps/uiCompRegistry";
 import _ from "lodash";
-import React, { ReactElement, SyntheticEvent } from "react";
+import React, { ReactElement, SyntheticEvent, useContext } from "react";
 import { DraggableEvent } from "react-draggable";
 import { PositionParams } from "./calculateUtils";
 import { draggingUtils } from "./draggingUtils";
 import { GridLayoutProps, ResizeHandleAxis } from "./gridLayoutPropTypes";
 
+import { getCollisionStatus } from "util/localStorageUtil";
+
 export type LayoutItem = {
   w: number;
   h: number;
@@ -169,7 +171,12 @@ export function collides(l1: LayoutItem, l2: LayoutItem): boolean {
   if (l1.y + l1.h <= l2.y) return false; // l1 is above l2
   if (l1.y >= l2.y + l2.h) return false; // l1 is below l2
 
-  return true; // boxes overlap
+  if (getCollisionStatus() === "true") {
+    return false;
+  }
+  else {
+    return true; // boxes overlap
+  }
 }
 
 /**
diff --git a/client/packages/lowcoder/src/pages/common/header.tsx b/client/packages/lowcoder/src/pages/common/header.tsx
index 3581a3eaf4..06a0067ecf 100644
--- a/client/packages/lowcoder/src/pages/common/header.tsx
+++ b/client/packages/lowcoder/src/pages/common/header.tsx
@@ -10,7 +10,6 @@ import {
   preview,
 } from "constants/routesURL";
 import { User } from "constants/userConstants";
-import { Switch } from "antd";
 import {
   CommonTextLabel,
   CustomModal,
@@ -54,7 +53,6 @@ import { AppPermissionDialog } from "../../components/PermissionDialog/AppPermis
 import { getBrandingConfig } from "../../redux/selectors/configSelectors";
 import { messageInstance } from "lowcoder-design";
 import { EditorContext } from "../../comps/editorState";
-import { SwitchChangeEventHandler } from "antd/es/switch";
 
 const StyledLink = styled.a`
   display: flex;
@@ -293,20 +291,11 @@ export type ToggleEditorModeStatus = (
   editorModeStatus?: EditorModeStatus
 ) => void;
 
-/* 
-// export type EnabledCollissionStatus = "true" | "false";
-export type ToggleCollissionStatus = (
-  collissionStatus?: EnabledCollissionStatus
-) => void; 
-*/
-
 type HeaderProps = {
   panelStatus: PanelStatus;
   togglePanel: TogglePanel;
   editorModeStatus: EditorModeStatus;
   toggleEditorModeStatus: ToggleEditorModeStatus;
-  // collissionStatus: EnabledCollissionStatus;
-  // toggleCollissionStatus: ToggleCollissionStatus;
 };
 
 // header in editor page
@@ -314,7 +303,6 @@ export default function Header(props: HeaderProps) {
   const editorState = useContext(EditorContext);
   const { togglePanel } = props;
   const { toggleEditorModeStatus } = props;
-  // const { toggleCollissionStatus } = props;
   const { left, bottom, right } = props.panelStatus;
   const user = useSelector(getUser);
   const application = useSelector(currentApplication);
@@ -347,24 +335,6 @@ export default function Header(props: HeaderProps) {
     },
   ];
 
-  // const collissionOptions = [
-  //   {
-  //     label: trans("header.editorMode_layout"),
-  //     key: "editorModeSelector_layout",
-  //     value: "tru",
-  //   },
-  //   {
-  //     label: trans("header.editorMode_logic"),
-  //     key: "editorModeSelector_logic",
-  //     value: "logic", 
-  //   },
-  //   {
-  //     label: trans("header.editorMode_both"),
-  //     key: "editorModeSelector_both",
-  //     value: "both",
-  //   },
-  // ];
-
   const onEditorStateValueChange = ({
     target: { value },
   }: RadioChangeEvent) => {
diff --git a/client/packages/lowcoder/src/pages/editor/LeftContent.tsx b/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
index 5924d90bfe..01de26f679 100644
--- a/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
+++ b/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
@@ -15,7 +15,7 @@ import {
   UnfoldIcon,
   UnShow,
 } from "lowcoder-design";
-import React, { ReactNode, useCallback, useContext, useMemo, useState } from "react";
+import React, { ReactNode, useCallback, useContext, useMemo, useState, useEffect } from "react";
 import { hookCompCategory } from "comps/hooks/hookCompTypes";
 import _ from "lodash";
 import styled from "styled-components";
@@ -32,6 +32,7 @@ import { UICompType } from "comps/uiCompRegistry";
 import { CollapseWrapper, DirectoryTreeStyle, Node } from "./styledComponents";
 import { DataNode, EventDataNode } from "antd/lib/tree";
 import { isAggregationApp } from "util/appUtils";
+import cloneDeep from 'lodash/cloneDeep';
 
 const CollapseTitleWrapper = styled.div`
   display: flex;
@@ -408,17 +409,94 @@ export const LeftContent = (props: LeftContentProps) => {
     );
   };
 
-  const getTreeUI = (type: TreeUIKey) => {
-    const uiCompInfos = _.sortBy(editorState.uiCompInfoList(), [(x) => x.name]);
+  const [componentTreeData, setComponentTreeData] = useState<NodeItem[]>([]);
+  const [modalsTreeData, setModalsTreeData] = useState<NodeItem[]>([]);
+
+  useEffect(() => {
+    const compData = getTreeUIData(TreeUIKey.Components);
+    setComponentTreeData(compData);
+  }, [editorState]);
+  
+  useEffect(() => {
+    const modalsData = getTreeUIData(TreeUIKey.Modals);
+    setModalsTreeData(modalsData);
+  }, [editorState]);
+
+  const getTreeUIData = (type: TreeUIKey) => {
     const tree =
       type === TreeUIKey.Components
         ? editorState.getUIComp().getTree()
         : editorState.getHooksComp().getUITree();
     const explorerData: NodeItem[] = getTree(tree, []);
+    return explorerData;
+  }
+
+  interface DropInfo {
+    node: { key: string; pos: string };
+    dragNode: { key: string; pos: string };
+  }
+
+  const handleDragEnter = (info: { node?: any; expandedKeys?: any; }) => {
+    // Assuming 'info' has a property 'expandedKeys' which is an array of keys
+    const { expandedKeys } = info;
+    if (!expandedKeys.includes(info.node.key)) {
+      setExpandedKeys(expandedKeys);
+    }
+  };
+
+  const handleDrop = (info: { node: { key: any; pos: string; }; dragNode: { key: any; pos: string; }; }, type: TreeUIKey) => {
+    const dropPos = info.node.pos.split('-');
+    const dragPos = info.dragNode.pos.split('-');
+
+    if (dropPos.length === dragPos.length) {
+      setComponentTreeData(prevData => {
+        let newTreeData = cloneDeep(prevData);
+        const dropIndex = Number(dropPos[dropPos.length - 1]);
+        const dragIndex = Number(dragPos[dragPos.length - 1]);
+        const parentNodePos = dropPos.slice(0, -1).join('-');
+
+        // TODO: handle drag and drop for childen of root (container components for example)
+        // findNodeByPos does not work yet
+        const parentNode = parentNodePos === "0" ? { children: newTreeData } : findNodeByPos(newTreeData, parentNodePos);
+  
+        console.log('parentNode', parentNode);
+  
+        if (parentNode && parentNode.children) {
+          const draggedNodeIndex = parentNode.children.findIndex(node => node.key === info.dragNode.key);
+          if (draggedNodeIndex !== -1) {
+            const [draggedNode] = parentNode.children.splice(draggedNodeIndex, 1);
+            parentNode.children.splice(dropIndex > dragIndex ? dropIndex - 1 : dropIndex, 0, draggedNode);
+          }
+        }
+        
+        return newTreeData;
+      });
+    }
+  };
+  
+  const findNodeByPos = (nodes: NodeItem[], pos: string): { children: NodeItem[] } => {
+    const posArr = pos.split('-').map(p => Number(p));
+    let currentNode = { children: nodes };
+    for (let i = 0; i < posArr.length; i++) {
+      currentNode = currentNode.children[posArr[i]];
+    }
+    return currentNode;
+  };
+
+  const getTreeUI = (type: TreeUIKey) => {
+    // here the components get sorted by name
+    // TODO: sort by category
+    // TODO: sort by Types etc.
+    const uiCompInfos = _.sortBy(editorState.uiCompInfoList(), [(x) => x.name]);
+    /* const tree =
+      type === TreeUIKey.Components
+        ? editorState.getUIComp().getTree()
+        : editorState.getHooksComp().getUITree();
+    const explorerData: NodeItem[] = getTree(tree, []); */
     let selectedKeys = [];
     if (editorState.selectedCompNames.size === 1) {
       const key = Object.keys(editorState.selectedComps())[0];
-      const parentKeys = getParentNodeKeysByKey(explorerData, key);
+      const parentKeys = getParentNodeKeysByKey(type === TreeUIKey.Components ? componentTreeData : modalsTreeData, key);
       if (parentKeys && parentKeys.length) {
         let needSet = false;
         parentKeys.forEach((key) => {
@@ -433,12 +511,11 @@ export const LeftContent = (props: LeftContentProps) => {
 
     return (
       <DirectoryTreeStyle
-        treeData={explorerData}
-        // icon={(props: NodeItem) => props.type && (CompStateIcon[props.type] || <LeftCommon />)}
+        draggable={type === TreeUIKey.Components ? true : false}
+        onDragEnter={handleDragEnter}
+        onDrop={(info) => handleDrop(info, type)}
+        treeData={type === TreeUIKey.Components ? componentTreeData : modalsTreeData}
         icon={(props: any) => props.type && (CompStateIcon[props.type as UICompType] || <LeftCommon />)}
-        // switcherIcon={({ expanded }: { expanded: boolean }) =>
-        //   expanded ? <FoldedIcon /> : <UnfoldIcon />
-        // }
         switcherIcon={(props: any) =>
           props.expanded ? <FoldedIcon /> : <UnfoldIcon />
         }
@@ -455,15 +532,15 @@ export const LeftContent = (props: LeftContentProps) => {
     if (isAggregationApp(editorState.getAppType())) {
       return;
     }
-    return getTreeUI(TreeUIKey.Components);
-  }, [editorState, uiCollapseClick, expandedKeys, showData]);
-
+    return getTreeUI(TreeUIKey.Components); // Pass componentTreeData
+  }, [editorState, uiCollapseClick, expandedKeys, showData, componentTreeData]);
+  
   const modalsCollapse = useMemo(() => {
     if (isAggregationApp(editorState.getAppType())) {
       return;
     }
-    return getTreeUI(TreeUIKey.Modals);
-  }, [editorState, uiCollapseClick, expandedKeys, showData]);
+    return getTreeUI(TreeUIKey.Modals); // Pass modalsTreeData
+  }, [editorState, uiCollapseClick, expandedKeys, showData, modalsTreeData]);
 
   const bottomResCollapse = useMemo(() => {
     return editorState
@@ -549,4 +626,4 @@ export const LeftContent = (props: LeftContentProps) => {
       </LeftContentTabs>
     </LeftContentWrapper>
   );
-};
+};
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx b/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx
index 58d7ffd5a4..01ba97c43d 100644
--- a/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx
+++ b/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx
@@ -7,7 +7,7 @@ import {
   LeftPanel,
   MiddlePanel,
 } from "pages/common/styledComponent";
-import { getPanelStatus, getEditorModeStatus, getPanelStyle, getCollissionStatus } from "util/localStorageUtil";
+import { getPanelStatus, getEditorModeStatus, getPanelStyle, getCollisionStatus } from "util/localStorageUtil";
 import { BottomSkeleton } from "pages/editor/bottom/BottomContent";
 import RightPanel from "pages/editor/right/RightPanel";
 import _ from "lodash";
@@ -48,7 +48,7 @@ export const EditorLoadingSpin = (props: { height?: string | number }) => {
 export default function EditorSkeletonView() {
   const panelStatus = getPanelStatus();
   const editorModeStatus = getEditorModeStatus();
-  const collissionStatus = getCollissionStatus();
+  const collisionStatus = getCollisionStatus();
   const panelStyle = getPanelStyle();
   const isUserViewMode = useUserViewMode();
   const isTemplate = useTemplateViewMode();
@@ -70,8 +70,8 @@ export default function EditorSkeletonView() {
           <SiderStyled />
           {panelStatus.left && (
             <LeftPanel
-              collissionStatus={collissionStatus}
-              toggleCollissionStatus={_.noop}
+              collisionStatus={collisionStatus}
+              toggleCollisionStatus={_.noop}
             >
               <StyledSkeleton active paragraph={{ rows: 10 }} />
             </LeftPanel>
diff --git a/client/packages/lowcoder/src/pages/editor/editorView.tsx b/client/packages/lowcoder/src/pages/editor/editorView.tsx
index e1b966688a..8cd7390fef 100644
--- a/client/packages/lowcoder/src/pages/editor/editorView.tsx
+++ b/client/packages/lowcoder/src/pages/editor/editorView.tsx
@@ -40,7 +40,6 @@ import {
 import RightPanel from "pages/editor/right/RightPanel";
 import EditorTutorials from "pages/tutorials/editorTutorials";
 import {
-  CollisionState,
   editorContentClassName,
   UserGuideLocationState,
 } from "pages/tutorials/tutorialsConstant";
@@ -67,15 +66,13 @@ import {
   DefaultEditorModeStatus,
   getEditorModeStatus,
   saveEditorModeStatus,
-  saveEnableCollissionStatus,
-  getCollissionStatus,
-  DefaultCollissionStatus,
+  saveCollisionStatus,
+  getCollisionStatus,
 } from "util/localStorageUtil";
 import Bottom from "./bottom/BottomPanel";
 import { LeftContent } from "./LeftContent";
 import { isAggregationApp } from "util/appUtils";
 import { Switch } from "antd";
-import { SwitchChangeEventHandler } from "antd/es/switch";
 
 const HookCompContainer = styled.div`
   pointer-events: none;
@@ -229,9 +226,9 @@ const items = [
 ];
 
   // added by Fred to set comp collision state
-export type EnabledCollissionStatus = "true" | "false"; // "true" means collission is enabled, "false" means collission is disabled
-export  type ToggleCollissionStatus = (
-    collissionStatus?: EnabledCollissionStatus
+export type DisabledCollisionStatus = "true" | "false"; // "true" means collision is not enabled - Layering works, "false" means collision is enabled - Layering does not work
+export  type ToggleCollisionStatus = (
+    collisionStatus?: DisabledCollisionStatus
   ) => void;
 
 function EditorView(props: EditorViewProps) {
@@ -240,9 +237,7 @@ function EditorView(props: EditorViewProps) {
   const { readOnly, hideHeader } = useContext(ExternalEditorContext);
   const application = useSelector(currentApplication);
   const locationState = useLocation<UserGuideLocationState>().state;
-  const collisionState = useLocation<CollisionState>().state;
   const showNewUserGuide = locationState?.showNewUserGuide;
-  const showCollission = collisionState?.collission;
   const showAppSnapshot = useSelector(showAppSnapshotSelector);
   const [showShortcutList, setShowShortcutList] = useState(false);
   const toggleShortcutList = useCallback(
@@ -280,22 +275,23 @@ function EditorView(props: EditorViewProps) {
     [panelStatus, prePanelStatus]
   );
 
-
+  // added by Falk Wolsky to support a Layers in Lowcoder
   const [collisionStatus, setCollisionStatus] = useState(() => {
-    return showCollission ? DefaultCollissionStatus : getCollissionStatus();
+    return getCollisionStatus();
   });
 
-  const toggleCollissionStatus: ToggleCollissionStatus = useCallback(
+  const toggleCollisionStatus: ToggleCollisionStatus = useCallback(
     (value) => {
-      setCollisionStatus(value ? value : "false");
-      saveEnableCollissionStatus(value ? value : "false");
+      setCollisionStatus(value ? value : ("false" as DisabledCollisionStatus));
+      saveCollisionStatus(value ? value : ("false" as DisabledCollisionStatus));
     },
     [collisionStatus]
   );
 
+
   // added by Falk Wolsky to support a Layout and Logic Mode in Lowcoder
   const [editorModeStatus, setEditorModeStatus] = useState(() => {
-    return showNewUserGuide ? DefaultEditorModeStatus : getEditorModeStatus();
+    return getEditorModeStatus();
   });
 
   const toggleEditorModeStatus: ToggleEditorModeStatus = useCallback(
@@ -479,11 +475,11 @@ function EditorView(props: EditorViewProps) {
               {menuKey === SiderKey.Layout && (
                 <SettingsDiv>
                   <Switch
-                    checked={editorState.collissionStatus == "true"}
+                    checked={editorState.collisionStatus == "true"}
                     disabled={false}
                     onChange={(value: any) => {
-                      toggleCollissionStatus(value == true ? "true" : "false");
-                      editorState.setCollissionStatus(value == true ? "true" : "false");
+                      toggleCollisionStatus(value == true ? "true" : "false");
+                      editorState.setCollisionStatus(value == true ? "true" : "false");
                     }}
                   />
                    <Divider />            
diff --git a/client/packages/lowcoder/src/pages/tutorials/tutorialsConstant.tsx b/client/packages/lowcoder/src/pages/tutorials/tutorialsConstant.tsx
index 550f072141..147327178c 100644
--- a/client/packages/lowcoder/src/pages/tutorials/tutorialsConstant.tsx
+++ b/client/packages/lowcoder/src/pages/tutorials/tutorialsConstant.tsx
@@ -31,8 +31,3 @@ export const defaultJoyrideFloaterProps: FloaterType = {
 export type UserGuideLocationState = {
   showNewUserGuide?: boolean;
 };
-
-export type CollisionState = {
-  showNewUserGuide?: boolean;
-  collission?: boolean;
-};
diff --git a/client/packages/lowcoder/src/util/localStorageUtil.ts b/client/packages/lowcoder/src/util/localStorageUtil.ts
index 15e951909c..2f102a6967 100644
--- a/client/packages/lowcoder/src/util/localStorageUtil.ts
+++ b/client/packages/lowcoder/src/util/localStorageUtil.ts
@@ -1,5 +1,5 @@
 import { PanelStatus } from "pages/common/header";
-import { EnabledCollissionStatus } from "pages/editor/editorView";
+import { DisabledCollisionStatus as DisabledCollisionStatus } from "pages/editor/editorView";
 import { EditorModeStatus } from "pages/common/header";
 import log from "loglevel";
 import { JSONValue } from "util/jsonTypes";
@@ -45,20 +45,20 @@ export function getPanelStatus(): PanelStatus {
 export function saveEditorModeStatus(editorModeStatus: EditorModeStatus) {
   localStorage.setItem("editor_mode_status", editorModeStatus);
 }
-//ADDED BY FRED TO SAVE enabledCollission
-export function saveEnableCollissionStatus(
-  collisionStatus: EnabledCollissionStatus
+//ADDED BY FRED TO SAVE enabledCollision
+export function saveCollisionStatus(
+  collisionStatus: DisabledCollisionStatus
 ) {
-  localStorage.setItem("enable_collission", collisionStatus);
+  localStorage.setItem("disable_collision", collisionStatus);
 }
 
-export const DefaultCollissionStatus: EnabledCollissionStatus = "true";
-export function getCollissionStatus(): EnabledCollissionStatus {
-  const str = localStorage.getItem("enable_collission");
+export const DefaultCollisionStatus: DisabledCollisionStatus = "true";
+export function getCollisionStatus(): DisabledCollisionStatus {
+  const str = localStorage.getItem("disable_collision");
   if (!str) {
-    return DefaultCollissionStatus;
+    return DefaultCollisionStatus;
   }
-  return str as EnabledCollissionStatus;
+  return str as DisabledCollisionStatus;
 }
 
 export const DefaultEditorModeStatus: EditorModeStatus = "both";

From d33f51a710939a541bc96122cad86a011bd685a8 Mon Sep 17 00:00:00 2001
From: Abdul Qadir <abdul.qadir@ikhwatech.com>
Date: Thu, 1 Feb 2024 21:06:06 +0500
Subject: [PATCH 21/97] feat: add marketplace applications handling

---
 .../domain/application/model/Application.java |  8 +++
 .../repository/ApplicationRepository.java     |  2 +
 .../service/ApplicationService.java           | 11 ++++
 .../permission/model/ResourceAction.java      |  1 +
 .../application/ApplicationApiService.java    | 10 +++-
 .../application/ApplicationController.java    | 16 ++++++
 .../api/application/ApplicationEndpoints.java | 31 +++++++++-
 .../application/view/ApplicationInfoView.java |  2 +
 .../view/ApplicationPermissionView.java       |  5 ++
 .../view/MarketplaceApplicationInfoView.java  | 30 ++++++++++
 .../lowcoder/api/home/UserHomeApiService.java |  3 +
 .../api/home/UserHomeApiServiceImpl.java      | 57 ++++++++++++++++++-
 12 files changed, 172 insertions(+), 4 deletions(-)
 create mode 100644 server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/MarketplaceApplicationInfoView.java

diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/model/Application.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/model/Application.java
index 1c5863f9b6..8144b45e2a 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/model/Application.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/model/Application.java
@@ -39,6 +39,8 @@ public class Application extends HasIdAndAuditing {
     private final Map<String, Object> publishedApplicationDSL;
 
     private final Boolean publicToAll;
+    private final Boolean publicToMarketplace;
+
     private Map<String, Object> editingApplicationDSL;
 
     @Transient
@@ -75,6 +77,7 @@ public Application(@JsonProperty("orgId") String organizationId,
             @JsonProperty("applicationStatus") ApplicationStatus applicationStatus,
             @JsonProperty("publishedApplicationDSL") Map<String, Object> publishedApplicationDSL,
             @JsonProperty("publicToAll") Boolean publicToAll,
+            @JsonProperty("publicToMarketplace") Boolean publicToMarketplace,
             @JsonProperty("editingApplicationDSL") Map<String, Object> editingApplicationDSL) {
         this.organizationId = organizationId;
         this.name = name;
@@ -82,6 +85,7 @@ public Application(@JsonProperty("orgId") String organizationId,
         this.applicationStatus = applicationStatus;
         this.publishedApplicationDSL = publishedApplicationDSL;
         this.publicToAll = publicToAll;
+        this.publicToMarketplace = publicToMarketplace;
         this.editingApplicationDSL = editingApplicationDSL;
     }
 
@@ -105,6 +109,10 @@ public boolean isPublicToAll() {
         return BooleanUtils.toBooleanDefaultIfNull(publicToAll, false);
     }
 
+    public boolean isPublicToMarketplace() {
+        return BooleanUtils.toBooleanDefaultIfNull(publicToMarketplace, false);
+    }
+
     public ApplicationQuery getQueryByViewModeAndQueryId(boolean isViewMode, String queryId) {
         return (isViewMode ? getLiveQueries() : getEditingQueries())
                 .stream()
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
index f520fe037f..db842dadb7 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
@@ -37,4 +37,6 @@ public interface ApplicationRepository extends ReactiveMongoRepository<Applicati
     @Query(fields = "{_id : 1}")
     Flux<Application> findByPublicToAllIsTrueAndIdIn(Collection<String> ids);
 
+    Flux<Application> findByPublicToAllIsTrueAndPublicToMarketplaceIsTrue();
+
 }
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
index 79acb26190..c0917d2ecc 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
@@ -103,6 +103,10 @@ public Flux<Application> findByOrganizationIdWithoutDsl(String organizationId) {
         return repository.findByOrganizationId(organizationId);
     }
 
+    public Flux<Application> findAllMarketplaceApps() {
+        return repository.findByPublicToAllIsTrueAndPublicToMarketplaceIsTrue();
+    }
+
     public Mono<Long> countByOrganizationId(String orgId, ApplicationStatus applicationStatus) {
         return repository.countByOrganizationIdAndApplicationStatus(orgId, applicationStatus);
     }
@@ -147,6 +151,13 @@ public Mono<Boolean> setApplicationPublicToAll(String applicationId, boolean pub
         return mongoUpsertHelper.updateById(application, applicationId);
     }
 
+    public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, boolean publicToMarketplace) {
+        Application application = Application.builder()
+                .publicToMarketplace(publicToMarketplace)
+                .build();
+        return mongoUpsertHelper.updateById(application, applicationId);
+    }
+
     @NonEmptyMono
     @SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
     public Mono<Set<String>> getPublicApplicationIds(Collection<String> applicationIds) {
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/model/ResourceAction.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/model/ResourceAction.java
index b6b2149906..c11257e414 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/model/ResourceAction.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/model/ResourceAction.java
@@ -24,6 +24,7 @@ public enum ResourceAction {
     EDIT_APPLICATIONS(ResourceRole.EDITOR, ResourceType.APPLICATION),
 
     SET_APPLICATIONS_PUBLIC(ResourceRole.EDITOR, ResourceType.APPLICATION),
+    SET_APPLICATIONS_PUBLIC_TO_MARKETPLACE(ResourceRole.EDITOR, ResourceType.APPLICATION),
 
     // datasource action
     MANAGE_DATASOURCES(ResourceRole.OWNER, ResourceType.DATASOURCE),
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
index f2a538e162..cf3d68d481 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
@@ -141,7 +141,7 @@ public Mono<ApplicationView> create(CreateApplicationRequest createApplicationRe
                 createApplicationRequest.applicationType(),
                 NORMAL,
                 createApplicationRequest.publishedApplicationDSL(),
-                false, createApplicationRequest.editingApplicationDSL());
+                false, false, createApplicationRequest.editingApplicationDSL());
 
         if (StringUtils.isBlank(application.getOrganizationId())) {
             return deferredError(INVALID_PARAMETER, "ORG_ID_EMPTY");
@@ -429,6 +429,7 @@ public Mono<ApplicationPermissionView> getApplicationPermissions(String applicat
                                         .creatorId(creatorId)
                                         .orgName(organization.getName())
                                         .publicToAll(application.isPublicToAll())
+                                        .publicToMarketplace(application.isPublicToMarketplace())
                                         .build();
                             });
                 });
@@ -485,6 +486,7 @@ private ApplicationInfoView buildView(Application application, String role, @Nul
                 .applicationStatus(application.getApplicationStatus())
                 .folderId(folderId)
                 .publicToAll(application.isPublicToAll())
+                .publicToMarketplace(application.isPublicToMarketplace())
                 .build();
     }
 
@@ -498,6 +500,12 @@ public Mono<Boolean> setApplicationPublicToAll(String applicationId, boolean pub
                 .then(applicationService.setApplicationPublicToAll(applicationId, publicToAll));
     }
 
+    public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, boolean publicToMarketplace) {
+        return checkCurrentUserApplicationPermission(applicationId, ResourceAction.SET_APPLICATIONS_PUBLIC_TO_MARKETPLACE)
+                .then(checkApplicationStatus(applicationId, NORMAL))
+                .then(applicationService.setApplicationPublicToMarketplace(applicationId, publicToMarketplace));
+    }
+
     private Map<String, Object> sanitizeDsl(Map<String, Object> applicationDsl) {
         if (applicationDsl.get("queries") instanceof List<?> queries) {
             List<Map<String, Object>> list = queries.stream().map(this::doSanitizeQuery).toList();
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
index b080da7ba5..ff37c60119 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
@@ -15,6 +15,7 @@
 import org.lowcoder.api.application.view.ApplicationInfoView;
 import org.lowcoder.api.application.view.ApplicationPermissionView;
 import org.lowcoder.api.application.view.ApplicationView;
+import org.lowcoder.api.application.view.MarketplaceApplicationInfoView;
 import org.lowcoder.api.framework.view.ResponseView;
 import org.lowcoder.api.home.UserHomeApiService;
 import org.lowcoder.api.home.UserHomepageView;
@@ -127,6 +128,14 @@ public Mono<ResponseView<List<ApplicationInfoView>>> getApplications(@RequestPar
                 .map(ResponseView::success);
     }
 
+    @Override
+    public Mono<ResponseView<List<MarketplaceApplicationInfoView>>> getMarketplaceApplications(@RequestParam(required = false) Integer applicationType) {
+        ApplicationType applicationTypeEnum = applicationType == null ? null : ApplicationType.fromValue(applicationType);
+        return userHomeApiService.getAllMarketplaceApplications(applicationTypeEnum)
+                .collectList()
+                .map(ResponseView::success);
+    }
+
     @Override
     public Mono<ResponseView<Boolean>> updatePermission(@PathVariable String applicationId,
             @PathVariable String permissionId,
@@ -177,4 +186,11 @@ public Mono<ResponseView<Boolean>> setApplicationPublicToAll(@PathVariable Strin
         return applicationApiService.setApplicationPublicToAll(applicationId, request.publicToAll())
                 .map(ResponseView::success);
     }
+
+    @Override
+    public Mono<ResponseView<Boolean>> setApplicationPublicToMarketplace(@PathVariable String applicationId,
+                                                                         @RequestBody ApplicationPublicToMarketplaceRequest request) {
+        return applicationApiService.setApplicationPublicToMarketplace(applicationId, request.publicToMarketplace())
+                .map(ResponseView::success);
+    }
 }
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
index 8417c40d02..da51dfa047 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
@@ -10,6 +10,7 @@
 import org.lowcoder.api.application.view.ApplicationInfoView;
 import org.lowcoder.api.application.view.ApplicationPermissionView;
 import org.lowcoder.api.application.view.ApplicationView;
+import org.lowcoder.api.application.view.MarketplaceApplicationInfoView;
 import org.lowcoder.api.framework.view.ResponseView;
 import org.lowcoder.api.home.UserHomepageView;
 import org.lowcoder.domain.application.model.Application;
@@ -149,6 +150,15 @@ public Mono<ResponseView<List<ApplicationInfoView>>> getApplications(@RequestPar
             @RequestParam(required = false) ApplicationStatus applicationStatus,
             @RequestParam(defaultValue = "true") boolean withContainerSize);
 
+	@Operation(
+			tags = TAG_APPLICATION_MANAGEMENT,
+			operationId = "listMarketplaceApplications",
+			summary = "List marketplace Applications",
+			description = "Retrieve a list of Lowcoder Applications that are published to the marketplace"
+	)
+	@GetMapping("/marketplace-apps")
+	public Mono<ResponseView<List<MarketplaceApplicationInfoView>>> getMarketplaceApplications(@RequestParam(required = false) Integer applicationType);
+
 	@Operation(
 			tags = TAG_APPLICATION_PERMISSIONS,
 		    operationId = "updateApplicationPermissions",
@@ -202,8 +212,18 @@ public Mono<ResponseView<Boolean>> grantPermission(
     public Mono<ResponseView<Boolean>> setApplicationPublicToAll(@PathVariable String applicationId,
             @RequestBody ApplicationPublicToAllRequest request);
 
-    
-    public record BatchAddPermissionRequest(String role, Set<String> userIds, Set<String> groupIds) {
+	@Operation(
+			tags = TAG_APPLICATION_MANAGEMENT,
+			operationId = "setApplicationAsPublicToMarketplace",
+			summary = "Set Application as publicly available on marketplace but to only logged in users",
+			description = "Set a Lowcoder Application identified by its ID as publicly available on marketplace but to only logged in users."
+	)
+	@PutMapping("/{applicationId}/public-to-marketplace")
+	public Mono<ResponseView<Boolean>> setApplicationPublicToMarketplace(@PathVariable String applicationId,
+																  @RequestBody ApplicationPublicToMarketplaceRequest request);
+
+
+	public record BatchAddPermissionRequest(String role, Set<String> userIds, Set<String> groupIds) {
     }
 
     public record ApplicationPublicToAllRequest(Boolean publicToAll) {
@@ -213,6 +233,13 @@ public Boolean publicToAll() {
         }
     }
 
+	public record ApplicationPublicToMarketplaceRequest(Boolean publicToMarketplace) {
+		@Override
+		public Boolean publicToMarketplace() {
+			return BooleanUtils.isTrue(publicToMarketplace);
+		}
+	}
+
     public record UpdatePermissionRequest(String role) {
     }
 
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/ApplicationInfoView.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/ApplicationInfoView.java
index 62cc9258f5..66eda18712 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/ApplicationInfoView.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/ApplicationInfoView.java
@@ -38,6 +38,8 @@ public class ApplicationInfoView {
 
     private final boolean publicToAll;
 
+    private final boolean publicToMarketplace;
+
     public long getLastViewTime() {
         return lastViewTime == null ? 0 : lastViewTime.toEpochMilli();
     }
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/ApplicationPermissionView.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/ApplicationPermissionView.java
index 64d8b1038b..ec17670bf5 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/ApplicationPermissionView.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/ApplicationPermissionView.java
@@ -8,8 +8,13 @@
 public class ApplicationPermissionView extends CommonPermissionView {
 
     private boolean publicToAll;
+    private boolean publicToMarketplace;
 
     public boolean isPublicToAll() {
         return publicToAll;
     }
+
+    public boolean isPublicToMarketplace() {
+        return publicToMarketplace;
+    }
 }
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/MarketplaceApplicationInfoView.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/MarketplaceApplicationInfoView.java
new file mode 100644
index 0000000000..b45ffd499d
--- /dev/null
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/MarketplaceApplicationInfoView.java
@@ -0,0 +1,30 @@
+package org.lowcoder.api.application.view;
+
+import lombok.Builder;
+import lombok.Getter;
+import org.lowcoder.domain.application.model.ApplicationStatus;
+
+@Builder
+@Getter
+public class MarketplaceApplicationInfoView {
+
+    // org details
+    private final String orgId;
+    private final String orgName;
+
+    // creator info
+    private final String creatorEmail;
+
+    // App details
+    private final String applicationId;
+    private final String name;
+    private final long createAt;
+    private final String createBy;
+    /**
+     * @see org.lowcoder.domain.application.model.ApplicationType
+     */
+    private final int applicationType;
+    private final ApplicationStatus applicationStatus;
+
+
+}
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiService.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiService.java
index ddcfff54c7..5f194fcc4f 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiService.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiService.java
@@ -2,6 +2,7 @@
 
 import javax.annotation.Nullable;
 
+import org.lowcoder.api.application.view.MarketplaceApplicationInfoView;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
@@ -22,4 +23,6 @@ public interface UserHomeApiService {
 
     Flux<ApplicationInfoView> getAllAuthorisedApplications4CurrentOrgMember(@Nullable ApplicationType applicationType,
             @Nullable ApplicationStatus applicationStatus, boolean withContainerSize);
+
+    public Flux<MarketplaceApplicationInfoView> getAllMarketplaceApplications(@Nullable ApplicationType applicationType);
 }
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
index f083076473..6d7aff678f 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
@@ -18,6 +18,7 @@
 import org.apache.commons.lang3.StringUtils;
 import org.lowcoder.api.application.view.ApplicationInfoView;
 import org.lowcoder.api.application.view.ApplicationInfoView.ApplicationInfoViewBuilder;
+import org.lowcoder.api.application.view.MarketplaceApplicationInfoView;
 import org.lowcoder.api.usermanagement.OrgDevChecker;
 import org.lowcoder.api.usermanagement.view.OrgAndVisitorRoleView;
 import org.lowcoder.api.usermanagement.view.UserProfileView;
@@ -256,6 +257,59 @@ public Flux<ApplicationInfoView> getAllAuthorisedApplications4CurrentOrgMember(@
                 });
     }
 
+    @Override
+    public Flux<MarketplaceApplicationInfoView> getAllMarketplaceApplications(@Nullable ApplicationType applicationType) {
+
+        return sessionUserService.getVisitorOrgMemberCache()
+                .flatMapMany(orgMember -> {
+                    // application flux
+                    Flux<Application> applicationFlux = Flux.defer(() -> applicationService.findAllMarketplaceApps())
+                            .filter(application -> isNull(applicationType) || application.getApplicationType() == applicationType.getValue())
+                            .cache();
+
+                    // user map
+                    Mono<Map<String, User>> userMapMono = applicationFlux
+                            .flatMap(application -> emptyIfNull(application.getCreatedBy()))
+                            .collectList()
+                            .flatMap(creatorIds -> userService.getByIds(creatorIds))
+                            .cache();
+
+                    // org map
+                    Mono<Map<String, Organization>> orgMapMono = applicationFlux
+                            .flatMap(application -> emptyIfNull(application.getOrganizationId()))
+                            .collectList()
+                            .flatMap(orgIds -> organizationService.getByIds(orgIds)
+                                    .collectList()
+                                    .map(it -> it.stream().collect(Collectors.toMap(Organization::getId, Function.identity())))
+                            )
+                            .cache();
+
+
+                    return applicationFlux
+                            .flatMap(application -> Mono.zip(Mono.just(application), userMapMono, orgMapMono))
+                            .map(tuple -> {
+                                // build view
+                                Application application = tuple.getT1();
+                                Map<String, User> userMap = tuple.getT2();
+                                Map<String, Organization> orgMap = tuple.getT3();
+                                return MarketplaceApplicationInfoView.builder()
+                                        .applicationId(application.getId())
+                                        .name(application.getName())
+                                        .applicationType(application.getApplicationType())
+                                        .applicationStatus(application.getApplicationStatus())
+                                        .orgId(application.getOrganizationId())
+                                        .orgName(orgMap.get(application.getOrganizationId()).getName())
+                                        .creatorEmail(Optional.ofNullable(userMap.get(application.getCreatedBy()))
+                                                .map(User::getName)
+                                                .orElse(""))
+                                        .createAt(application.getCreatedAt().toEpochMilli())
+                                        .createBy(application.getCreatedBy())
+                                        .build();
+                            });
+
+                });
+    }
+
     private ApplicationInfoView buildView(Application application, ResourceRole maxRole, Map<String, User> userMap, @Nullable Instant lastViewTime,
             boolean withContainerSize) {
         ApplicationInfoViewBuilder applicationInfoViewBuilder = ApplicationInfoView.builder()
@@ -271,7 +325,8 @@ private ApplicationInfoView buildView(Application application, ResourceRole maxR
                 .applicationStatus(application.getApplicationStatus())
                 .lastModifyTime(application.getUpdatedAt())
                 .lastViewTime(lastViewTime)
-                .publicToAll(application.isPublicToAll());
+                .publicToAll(application.isPublicToAll())
+                .publicToMarketplace(application.isPublicToMarketplace());
         if (withContainerSize) {
             return applicationInfoViewBuilder
                     .containerSize(application.getLiveContainerSize())

From 27079d9161d2390f641a90756e5ecfbc5ec4e4f6 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Fri, 2 Feb 2024 20:44:25 +0500
Subject: [PATCH 22/97] component sorting and z-index based on sorting position

---
 .../comps/containerComp/containerView.tsx     | 16 +++++-
 .../lowcoder/src/comps/comps/textComp.tsx     |  2 +-
 .../packages/lowcoder/src/constants/Layers.ts |  2 +-
 .../packages/lowcoder/src/layout/gridItem.tsx | 12 +++--
 .../lowcoder/src/layout/gridLayout.tsx        | 12 ++++-
 client/packages/lowcoder/src/layout/utils.ts  |  1 +
 .../lowcoder/src/pages/editor/LeftContent.tsx | 53 ++++++++++++++++++-
 .../src/pages/editor/styledComponents.tsx     |  5 ++
 8 files changed, 92 insertions(+), 11 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/containerComp/containerView.tsx b/client/packages/lowcoder/src/comps/comps/containerComp/containerView.tsx
index 26ac5561e0..45d8f7d26a 100644
--- a/client/packages/lowcoder/src/comps/comps/containerComp/containerView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/containerComp/containerView.tsx
@@ -230,6 +230,14 @@ 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(
@@ -237,7 +245,12 @@ const onDrop = (
           layout: changeValueAction(
             {
               ...layout,
-              [key]: { ...layoutItem, i: key, placeholder: undefined },
+              [key]: {
+                ...layoutItem,
+                i: key,
+                placeholder: undefined,
+                pos: itemPos,
+              },
             },
             true
           ),
@@ -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) {
diff --git a/client/packages/lowcoder/src/comps/comps/textComp.tsx b/client/packages/lowcoder/src/comps/comps/textComp.tsx
index 671e67354f..aec1f8af12 100644
--- a/client/packages/lowcoder/src/comps/comps/textComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/textComp.tsx
@@ -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;
       }
diff --git a/client/packages/lowcoder/src/constants/Layers.ts b/client/packages/lowcoder/src/constants/Layers.ts
index fcd2a361bf..358f52dccc 100644
--- a/client/packages/lowcoder/src/constants/Layers.ts
+++ b/client/packages/lowcoder/src/constants/Layers.ts
@@ -30,7 +30,7 @@ export const Layers = {
   // comp selection wrapper
   dragSelectBox: 399,
   //
-  compHover: 300,
+  compHover: 100,
   //
   compSelected: 200,
   //
diff --git a/client/packages/lowcoder/src/layout/gridItem.tsx b/client/packages/lowcoder/src/layout/gridItem.tsx
index ba80c46f5f..d3fec9367b 100644
--- a/client/packages/lowcoder/src/layout/gridItem.tsx
+++ b/client/packages/lowcoder/src/layout/gridItem.tsx
@@ -34,6 +34,7 @@ type GridItemCallback<Data extends GridDragEvent | GridResizeEvent> = (
   arg3: Data
 ) => void;
 export type GridItemProps = {
+  zIndex: number;
   children: ReactElement;
   cols: number;
   containerWidth: number;
@@ -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;
   }
@@ -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
@@ -179,6 +182,7 @@ export function GridItem(props: GridItemProps) {
         onResizeStop={onResizeStop}
         resizeHandles={resizeHandles}
         handle={Handle}
+        $zIndex={zIndex}
       >
         {child}
       </ResizableStyled>
@@ -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);
@@ -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;
diff --git a/client/packages/lowcoder/src/layout/gridLayout.tsx b/client/packages/lowcoder/src/layout/gridLayout.tsx
index 328ff1ab6b..0058ff71f2 100644
--- a/client/packages/lowcoder/src/layout/gridLayout.tsx
+++ b/client/packages/lowcoder/src/layout/gridLayout.tsx
@@ -393,6 +393,7 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
   };
 
   processGridItem(
+    zIndex: number,
     item: LayoutItem,
     childrenMap: _.Dictionary<React.ReactElement>
   ): React.ReactElement | undefined {
@@ -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>
@@ -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);
@@ -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}
@@ -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>
diff --git a/client/packages/lowcoder/src/layout/utils.ts b/client/packages/lowcoder/src/layout/utils.ts
index 6a9f0494d0..40ee0ed727 100644
--- a/client/packages/lowcoder/src/layout/utils.ts
+++ b/client/packages/lowcoder/src/layout/utils.ts
@@ -14,6 +14,7 @@ export type LayoutItem = {
   x: number;
   y: number;
   i: string;
+  pos?: number;
   minW?: number;
   minH?: number;
   maxW?: number;
diff --git a/client/packages/lowcoder/src/pages/editor/LeftContent.tsx b/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
index 01de26f679..66f32141cf 100644
--- a/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
+++ b/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
@@ -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;
@@ -209,6 +212,8 @@ type NodeItem = {
   title: string;
   type?: UICompType;
   children: NodeItem[];
+  pos?: number;
+  disabled?: boolean;
 };
 
 type NodeInfo = {
@@ -243,12 +248,14 @@ 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,
@@ -256,12 +263,13 @@ export const LeftContent = (props: LeftContentProps) => {
         };
         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) {
@@ -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;
   }
 
@@ -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;
       });
     }
diff --git a/client/packages/lowcoder/src/pages/editor/styledComponents.tsx b/client/packages/lowcoder/src/pages/editor/styledComponents.tsx
index c0d68b2f95..6df7b9d7a7 100644
--- a/client/packages/lowcoder/src/pages/editor/styledComponents.tsx
+++ b/client/packages/lowcoder/src/pages/editor/styledComponents.tsx
@@ -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;
+      }
+    }
   }
 `;
 

From 5323da554b3256a8231bc84d9245611a0cf030ba Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Sat, 3 Feb 2024 14:16:50 +0100
Subject: [PATCH 23/97] [WIP] Own Display for Layers

---
 .../lowcoder-design/src/icons/index.ts        | 312 ++++++++---------
 .../packages/lowcoder/src/layout/gridItem.tsx |  18 +-
 .../lowcoder/src/pages/editor/LeftContent.tsx | 115 ++-----
 .../src/pages/editor/LeftLayersContent.tsx    | 325 ++++++++++++++++++
 .../lowcoder/src/pages/editor/editorView.tsx  |  41 +--
 .../src/pages/editor/styledComponents.tsx     |  12 +-
 .../lowcoder/src/util/localStorageUtil.ts     |   2 +-
 7 files changed, 532 insertions(+), 293 deletions(-)
 create mode 100644 client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx

diff --git a/client/packages/lowcoder-design/src/icons/index.ts b/client/packages/lowcoder-design/src/icons/index.ts
index 2afd2a7394..8b80e30bf1 100644
--- a/client/packages/lowcoder-design/src/icons/index.ts
+++ b/client/packages/lowcoder-design/src/icons/index.ts
@@ -298,104 +298,106 @@ export { ReactComponent as MentionIcon } from "icons/icon-mention-comp.svg";
 export { ReactComponent as AutoCompleteCompIcon } from "icons/icon-autocomplete-comp.svg";
 export { ReactComponent as WidthIcon } from "icons/icon-width.svg";
 export { ReactComponent as ResponsiveLayoutCompIcon } from "icons/icon-responsive-layout-comp.svg";
-export { ReactComponent as TextSizeIcon } from "./remix/font-size-2.svg";
-export { ReactComponent as FontFamilyIcon } from "./remix/font-sans-serif.svg";
-export { ReactComponent as TextWeigthIcon } from "./remix/bold.svg";
-export { ReactComponent as BorderWidthIcon } from "./remix/expand-width-line.svg";
+export { ReactComponent as TextSizeIcon } from "icons/remix/font-size-2.svg";
+export { ReactComponent as FontFamilyIcon } from "icons/remix/font-sans-serif.svg";
+export { ReactComponent as TextWeigthIcon } from "icons/remix/bold.svg";
+export { ReactComponent as BorderWidthIcon } from "icons/remix/expand-width-line.svg";
+export { ReactComponent as LeftInfoLine } from "icons/remix/information-line.svg";
+export { ReactComponent as LeftInfoFill } from "icons/remix/information-fill.svg";
 
 
 // new
-/* export { ReactComponent as AppSnapshotIcon } from "./remix/screenshot-2-line.svg"; // Closest match for app snapshot
+/* export { ReactComponent as AppSnapshotIcon } from "icons/remix/screenshot-2-line.svg"; // Closest match for app snapshot
 export { ReactComponent as HookCompDropIcon } from "./hook-comp-drop.svg";
 export { ReactComponent as HookCompIcon } from "./hook-comp.svg";
-export { ReactComponent as IconsIcon } from "./remix/apps-line.svg"; // Closest match for icons
+export { ReactComponent as IconsIcon } from "icons/remix/apps-line.svg"; // Closest match for icons
 export { ReactComponent as JsGrayIcon } from "./icon-Js-Gray.svg";
 export { ReactComponent as JsColorsIcon } from "./icon-Js-colors.svg";
-export { ReactComponent as AdminIcon } from "./remix/admin-line.svg"; // Exact match
+export { ReactComponent as AdminIcon } from "icons/remix/admin-line.svg"; // Exact match
 export { ReactComponent as AlignVerticalCent } from "./icon-align-vertical-center.svg";
-export { ReactComponent as AppEditIcon } from "./remix/edit-box-line.svg"; // Closest match for app edit
+export { ReactComponent as AppEditIcon } from "icons/remix/edit-box-line.svg"; // Closest match for app edit
 export { ReactComponent as AuditAppIcon } from "./icon-audit-app.svg";
 export { ReactComponent as AuditDbIcon } from "./icon-audit-db.svg";
-export { ReactComponent as TreeFoldIcon } from "./remix/tree-line.svg"; // Closest match for tree fold
+export { ReactComponent as TreeFoldIcon } from "icons/remix/tree-line.svg"; // Closest match for tree fold
 export { ReactComponent as AuditQueryIcon } from "./icon-audit-query.svg";
 export { ReactComponent as AuditUserIcon } from "./icon-audit-user.svg";
-export { ReactComponent as AuditFolderIcon } from "./remix/folder-line.svg"; // Closest match for audit folder
+export { ReactComponent as AuditFolderIcon } from "icons/remix/folder-line.svg"; // Closest match for audit folder
 export { ReactComponent as AutoCompleteIcon } from "./icon-autoComplete.svg";
-export { ReactComponent as CalendarIcon } from "./remix/calendar-2-line.svg"; // Exact match
+export { ReactComponent as CalendarIcon } from "icons/remix/calendar-2-line.svg"; // Exact match
 export { ReactComponent as CaptchaIcon } from "./icon-captcha.svg";
-export { ReactComponent as CheckboxIcon } from "./remix/checkbox-line.svg"; // Exact match
+export { ReactComponent as CheckboxIcon } from "icons/remix/checkbox-line.svg"; // Exact match
 export { ReactComponent as CheckoutIcon } from "./icon-checkout.svg";
 export { ReactComponent as ClickLinkIcon } from "./icon-clickLink.svg";
-export { ReactComponent as CloseEyeIcon } from "./remix/eye-off-line.svg"; // Closest match for close eye
+export { ReactComponent as CloseEyeIcon } from "icons/remix/eye-off-line.svg"; // Closest match for close eye
 export { ReactComponent as CodeEditorCloseIcon } from "./icon-code-editor-close.svg";
 export { ReactComponent as CodeEditorOpenIcon } from "./icon-code-editor-open.svg";
-export { ReactComponent as ColorHexIcon } from "./remix/palette-line.svg"; // Closest match for color hex
+export { ReactComponent as ColorHexIcon } from "icons/remix/palette-line.svg"; // Closest match for color hex
 export { ReactComponent as ContainerDragIcon } from "./icon-container-drag.svg";
-export { ReactComponent as CopyIcon } from "./remix/file-copy-line.svg"; // Closest match for copy
+export { ReactComponent as CopyIcon } from "icons/remix/file-copy-line.svg"; // Closest match for copy
 export { ReactComponent as CreateModuleIcon } from "./icon-create-module.svg";
 export { ReactComponent as PrevIcon } from "./icon-date-prev.svg";
 export { ReactComponent as SuperPrevIcon } from "./icon-date-super-prev.svg";
 export { ReactComponent as DragWhiteIcon } from "./icon-drag-white.svg";
-export { ReactComponent as EmptyDataIcon } from "./remix/emotion-unhappy-line.svg"; // Closest match for empty data
+export { ReactComponent as EmptyDataIcon } from "icons/remix/emotion-unhappy-line.svg"; // Closest match for empty data
 export { ReactComponent as FlokcloseIcon } from "./icon-flokclose.svg";
 export { ReactComponent as FoldedIcon } from "./icon-folded.svg";
-export { ReactComponent as GridIcon } from "./remix/grid-line.svg"; // Exact match
-export { ReactComponent as GroupIcon } from "./remix/group-line.svg"; // Closest match for group
-export { ReactComponent as HelpIcon } from "./remix/question-answer-line.svg"; // Closest match for help
-export { ReactComponent as LayoutIcon } from "./remix/layout-6-line.svg"; // Closest match for layout
-export { ReactComponent as LockIcon } from "./remix/lock-line.svg"; // Exact match
-export { ReactComponent as MembersIcon } from "./remix/group-line.svg"; // Closest match for members
-export { ReactComponent as MoreActionIcon } from "./remix/more-2-line.svg"; // Closest match for more action
-export { ReactComponent as MultiselectTagIcon } from "./remix/price-tag-3-line.svg"; // Closest match for multiselect tag
-export { ReactComponent as MustFillStarIcon } from "./remix/star-line.svg"; // Closest match for must fill star
-export { ReactComponent as NofileIcon } from "./remix/file-unknow-line.svg"; // Closest match for nofile
+export { ReactComponent as GridIcon } from "icons/remix/grid-line.svg"; // Exact match
+export { ReactComponent as GroupIcon } from "icons/remix/group-line.svg"; // Closest match for group
+export { ReactComponent as HelpIcon } from "icons/remix/question-answer-line.svg"; // Closest match for help
+export { ReactComponent as LayoutIcon } from "icons/remix/layout-6-line.svg"; // Closest match for layout
+export { ReactComponent as LockIcon } from "icons/remix/lock-line.svg"; // Exact match
+export { ReactComponent as MembersIcon } from "icons/remix/group-line.svg"; // Closest match for members
+export { ReactComponent as MoreActionIcon } from "icons/remix/more-2-line.svg"; // Closest match for more action
+export { ReactComponent as MultiselectTagIcon } from "icons/remix/price-tag-3-line.svg"; // Closest match for multiselect tag
+export { ReactComponent as MustFillStarIcon } from "icons/remix/star-line.svg"; // Closest match for must fill star
+export { ReactComponent as NofileIcon } from "icons/remix/file-unknow-line.svg"; // Closest match for nofile
 export { ReactComponent as OmitIcon } from "./icon-omit.svg";
-export { ReactComponent as OpenEyeIcon } from "./remix/eye-line.svg"; // Closest match for open eye
-export { ReactComponent as PasswordIcon } from "./remix/lock-password-line.svg"; // Closest match for password
-export { ReactComponent as RadioCheckedIcon } from "./remix/list-radio.svg"; // Closest match for radio checked
-export { ReactComponent as RequiredIcon } from "./remix/alert-line.svg"; // Closest match for required
+export { ReactComponent as OpenEyeIcon } from "icons/remix/eye-line.svg"; // Closest match for open eye
+export { ReactComponent as PasswordIcon } from "icons/remix/lock-password-line.svg"; // Closest match for password
+export { ReactComponent as RadioCheckedIcon } from "icons/remix/list-radio.svg"; // Closest match for radio checked
+export { ReactComponent as RequiredIcon } from "icons/remix/alert-line.svg"; // Closest match for required
 export { ReactComponent as AttributeIcon } from "./icon-right-attribute.svg";
 export { ReactComponent as InsertIcon } from "./icon-right-insert.svg";
 export { ReactComponent as ShowBorderIcon } from "./icon-show-border.svg";
 export { ReactComponent as SpaceIcon } from "./icon-space.svg";
-export { ReactComponent as StarIcon } from "./remix/star-line.svg"; // Exact match
+export { ReactComponent as StarIcon } from "icons/remix/star-line.svg"; // Exact match
 export { ReactComponent as SuperUserIcon } from "./icon-super-user.svg";
-export { ReactComponent as SwitchCheckedIcon } from "./remix/toggle-line.svg"; // Closest match for switch checked
+export { ReactComponent as SwitchCheckedIcon } from "icons/remix/toggle-line.svg"; // Closest match for switch checked
 export { ReactComponent as TextEditIcon } from "./icon-text-edit.svg";
 export { ReactComponent as TextboxIcon } from "./icon-textbox.svg";
-export { ReactComponent as TriangleIcon } from "./remix/arrow-up-line.svg"; // Closest match for triangle
-export { ReactComponent as TypographyIcon } from "./remix/file-text-line.svg"; // Closest match for typography
+export { ReactComponent as TriangleIcon } from "icons/remix/arrow-up-line.svg"; // Closest match for triangle
+export { ReactComponent as TypographyIcon } from "icons/remix/file-text-line.svg"; // Closest match for typography
 export { ReactComponent as UnfoldWhiteIcon } from "./icon-unfold-white.svg";
 export { ReactComponent as UnfoldIcon } from "./icon-unfold.svg";
 export { ReactComponent as WarningWhiteIcon } from "./icon-warning-white.svg";
-export { ReactComponent as WarningIcon } from "./remix/error-warning-line.svg"; // Closest match for warning
+export { ReactComponent as WarningIcon } from "icons/remix/error-warning-line.svg"; // Closest match for warning
 export { ReactComponent as WidthDragIcon } from "./icon-widthDrag.svg";
-export { ReactComponent as ManyCheckboxIcon } from "./remix/checkbox-multiple-line.svg"; // Closest match for many checkbox
-export { ReactComponent as Layout } from "./remix/layout-2-line.svg"; // Closest match for layout
-export { ReactComponent as Left } from "./remix/arrow-left-s-line.svg"; // Closest match for left
-export { ReactComponent as Middle } from "./remix/align-vertically.svg"; // Closest match for middle
-export { ReactComponent as Right } from "./remix/arrow-right-s-line.svg"; // Closest match for right
+export { ReactComponent as ManyCheckboxIcon } from "icons/remix/checkbox-multiple-line.svg"; // Closest match for many checkbox
+export { ReactComponent as Layout } from "icons/remix/layout-2-line.svg"; // Closest match for layout
+export { ReactComponent as Left } from "icons/remix/arrow-left-s-line.svg"; // Closest match for left
+export { ReactComponent as Middle } from "icons/remix/align-vertically.svg"; // Closest match for middle
+export { ReactComponent as Right } from "icons/remix/arrow-right-s-line.svg"; // Closest match for right
 export { ReactComponent as DeployIcon } from "./icon-rocket.svg";
-export { ReactComponent as ExportIcon } from "./remix/share-forward-line.svg"; // Closest match for export
+export { ReactComponent as ExportIcon } from "icons/remix/share-forward-line.svg"; // Closest match for export
 export { ReactComponent as BluePlusIcon } from "./icon-blue-add.svg";
-export { ReactComponent as PencilIcon } from "./remix/pencil-line.svg"; // Closest match for pencil
-export { ReactComponent as DragIcon } from "./remix/drag-move-2-line.svg"; // Closest match for drag
+export { ReactComponent as PencilIcon } from "icons/remix/pencil-line.svg"; // Closest match for pencil
+export { ReactComponent as DragIcon } from "icons/remix/drag-move-2-line.svg"; // Closest match for drag
 export { ReactComponent as PointIcon } from "./icon-three-point.svg";
-export { ReactComponent as AlignJustify } from "./remix/align-justify.svg"; // Exact match
-export { ReactComponent as AlignRight } from "./remix/align-right.svg"; // Exact match
-export { ReactComponent as AlignCenter } from "./remix/align-center.svg"; // Exact match
-export { ReactComponent as AlignLeft } from "./remix/align-left.svg"; // Exact match
+export { ReactComponent as AlignJustify } from "icons/remix/align-justify.svg"; // Exact match
+export { ReactComponent as AlignRight } from "icons/remix/align-right.svg"; // Exact match
+export { ReactComponent as AlignCenter } from "icons/remix/align-center.svg"; // Exact match
+export { ReactComponent as AlignLeft } from "icons/remix/align-left.svg"; // Exact match
 export { ReactComponent as AlignClose } from "./icon-align-close.svg";
 export { ReactComponent as AlignTop } from "./icon-align-top.svg";
 export { ReactComponent as AlignBottom } from "./icon-align-bottom.svg";
-export { ReactComponent as AddIcon } from "./remix/add-line.svg"; // Closest match for add
+export { ReactComponent as AddIcon } from "icons/remix/add-line.svg"; // Closest match for add
 export { ReactComponent as ApplicationDocIcon } from "./icon-application-doc.svg";
-export { ReactComponent as ImportAppIcon } from "./remix/download-cloud-line.svg"; // Closest match for import app
+export { ReactComponent as ImportAppIcon } from "icons/remix/download-cloud-line.svg"; // Closest match for import app
 export { ReactComponent as ModuleDocIcon } from "./icon-module-doc.svg";
-export { ReactComponent as ImportIcon } from "./remix/download-cloud-line.svg"; // Closest match for import
-export { ReactComponent as ImportIconV2 } from "./remix/download-cloud-line.svg"; // Closest match for import v2
+export { ReactComponent as ImportIcon } from "icons/remix/download-cloud-line.svg"; // Closest match for import
+export { ReactComponent as ImportIconV2 } from "icons/remix/download-cloud-line.svg"; // Closest match for import v2
 export { ReactComponent as ModuleMenuIcon } from "./icon-module-menu.svg";
-export { ReactComponent as ModuleIcon } from "./remix/stack-line.svg"; // Closest match for module
+export { ReactComponent as ModuleIcon } from "icons/remix/stack-line.svg"; // Closest match for module
 export { ReactComponent as AllAppIcon } from "./icon-all-app.svg";
 export { ReactComponent as DatasourceIcon } from "./icon-datasource.svg";
 export { ReactComponent as QueryLibraryIcon } from "./icon-query-library.svg";
@@ -403,82 +405,82 @@ export { ReactComponent as TransformerIcon } from "./icon-transformer.svg"; // O
 export { ReactComponent as TempStateIcon } from "./icon-temp-state.svg";
 export { ReactComponent as IconDep } from "./icon-style-dep.svg";
 export { ReactComponent as IconRadius } from "./icon-style-border-radius.svg";
-export { ReactComponent as IconReset } from "./remix/refresh-line.svg";
+export { ReactComponent as IconReset } from "icons/remix/refresh-line.svg";
 export { ReactComponent as NavComIcon } from "./icon-nav.svg";
 export { ReactComponent as ButtonCompIcon } from "./icon-button.svg";
-export { ReactComponent as InputCompIcon } from "./remix/input-method-line.svg"; // Closest match for input component
-export { ReactComponent as TextCompIcon } from "./remix/file-text-line.svg"; // Closest match for text component
-export { ReactComponent as SwitchCompIcon } from "./remix/switch-line.svg"; // Closest match for switch component
-export { ReactComponent as TableCompIcon } from "./remix/table-line.svg"; // Closest match for table component
-export { ReactComponent as SelectCompIcon } from "./remix/dropdown-list.svg"; // Closest match for select component
-export { ReactComponent as CheckboxCompIcon } from "./remix/checkbox-line.svg"; // Closest match for checkbox component
-export { ReactComponent as RadioCompIcon } from "./remix/radio-line.svg"; // Closest match for radio component
-export { ReactComponent as TimeCompIcon } from "./remix/time-line.svg"; // Closest match for time component
+export { ReactComponent as InputCompIcon } from "icons/remix/input-method-line.svg"; // Closest match for input component
+export { ReactComponent as TextCompIcon } from "icons/remix/file-text-line.svg"; // Closest match for text component
+export { ReactComponent as SwitchCompIcon } from "icons/remix/switch-line.svg"; // Closest match for switch component
+export { ReactComponent as TableCompIcon } from "icons/remix/table-line.svg"; // Closest match for table component
+export { ReactComponent as SelectCompIcon } from "icons/remix/dropdown-list.svg"; // Closest match for select component
+export { ReactComponent as CheckboxCompIcon } from "icons/remix/checkbox-line.svg"; // Closest match for checkbox component
+export { ReactComponent as RadioCompIcon } from "icons/remix/radio-line.svg"; // Closest match for radio component
+export { ReactComponent as TimeCompIcon } from "icons/remix/time-line.svg"; // Closest match for time component
 export { ReactComponent as TimeRangeCompIcon } from "./icon-timeRange.svg";
-export { ReactComponent as DateCompIcon } from "./remix/calendar-2-line.svg"; // Closest match for date component
+export { ReactComponent as DateCompIcon } from "icons/remix/calendar-2-line.svg"; // Closest match for date component
 export { ReactComponent as DateRangeCompIcon } from "./icon-dateRange.svg";
-export { ReactComponent as UploadCompIcon } from "./remix/upload-cloud-2-line.svg"; // Closest match for upload component
-export { ReactComponent as ImageCompIcon } from "./remix/image-line.svg"; // Closest match for image component
-export { ReactComponent as RatingCompIcon } from "./remix/star-line.svg"; // Closest match for rating component
-export { ReactComponent as SliderCompIcon } from "./remix/git-commit-line.svg"; // Closest match for slider component
+export { ReactComponent as UploadCompIcon } from "icons/remix/upload-cloud-2-line.svg"; // Closest match for upload component
+export { ReactComponent as ImageCompIcon } from "icons/remix/image-line.svg"; // Closest match for image component
+export { ReactComponent as RatingCompIcon } from "icons/remix/star-line.svg"; // Closest match for rating component
+export { ReactComponent as SliderCompIcon } from "icons/remix/git-commit-line.svg"; // Closest match for slider component
 export { ReactComponent as ProcessCircleCompIcon } from "./icon-sliderCircle.svg";
-export { ReactComponent as ChartCompIcon } from "./remix/pie-chart-2-line.svg"; // Closest match for chart component
+export { ReactComponent as ChartCompIcon } from "icons/remix/pie-chart-2-line.svg"; // Closest match for chart component
 export { ReactComponent as JsonFormCompIcon } from "./icon-jsonForm.svg";
-export { ReactComponent as FormCompIcon } from "./remix/draft-line.svg"; // Closest match for form component
+export { ReactComponent as FormCompIcon } from "icons/remix/draft-line.svg"; // Closest match for form component
 export { ReactComponent as ProgressCompIcon } from "./icon-progress.svg";
 export { ReactComponent as FileViewerCompIcon } from "./icon-fileViewer.svg";
 export { ReactComponent as ContainerCompIcon } from "./icon-container.svg";
-export { ReactComponent as LinkCompIcon } from "./remix/links-line.svg"; // Closest match for link component
-export { ReactComponent as MultiSelectCompIcon } from "./remix/list-check-3.svg"; // Closest match for multiselect component
-export { ReactComponent as PasswordCompIcon } from "./remix/key-2-line.svg"; // Closest match for password component
-export { ReactComponent as RangeSliderCompIcon } from "./remix/switch-line.svg"; // Closest match for range slider component
+export { ReactComponent as LinkCompIcon } from "icons/remix/links-line.svg"; // Closest match for link component
+export { ReactComponent as MultiSelectCompIcon } from "icons/remix/list-check-3.svg"; // Closest match for multiselect component
+export { ReactComponent as PasswordCompIcon } from "icons/remix/key-2-line.svg"; // Closest match for password component
+export { ReactComponent as RangeSliderCompIcon } from "icons/remix/switch-line.svg"; // Closest match for range slider component
 export { ReactComponent as SegmentedCompIcon } from "./icon-insert-segmentedControl.svg";
-export { ReactComponent as TextAreaCompIcon } from "./remix/text-block.svg"; // Closest match for textarea component
+export { ReactComponent as TextAreaCompIcon } from "icons/remix/text-block.svg"; // Closest match for textarea component
 export { ReactComponent as NumberInputCompIcon } from "./icon-insert-numberInput.svg";
-export { ReactComponent as DropdownCompIcon } from "./remix/dropdown-list.svg"; // Closest match for dropdown component
+export { ReactComponent as DropdownCompIcon } from "icons/remix/dropdown-list.svg"; // Closest match for dropdown component
 export { ReactComponent as DividerCompIcon } from "./icon-insert-divider.svg";
 export { ReactComponent as RichTextEditorCompIcon } from "./icon-insert-rich-text-editor.svg";
-export { ReactComponent as ModalCompIcon } from "./remix/window-line.svg"; // Closest match for modal component
-export { ReactComponent as TabbedContainerCompIcon } from "./remix/layout-column-line.svg"; // Closest match for tabbed container
+export { ReactComponent as ModalCompIcon } from "icons/remix/window-line.svg"; // Closest match for modal component
+export { ReactComponent as TabbedContainerCompIcon } from "icons/remix/layout-column-line.svg"; // Closest match for tabbed container
 export { ReactComponent as CascaderCompIcon } from "./icon-cascader.svg";
-export { ReactComponent as TreeIcon } from "./remix/node-tree.svg"; // Closest match for tree icon
+export { ReactComponent as TreeIcon } from "icons/remix/node-tree.svg"; // Closest match for tree icon
 export { ReactComponent as TreeSelectIcon } from "./icon-tree-select.svg";
 export { ReactComponent as CustomCompIcon } from "./icon-custom-component.svg";
-export { ReactComponent as IFrameCompIcon } from "./remix/window-2-line.svg"; // Closest match for iframe component
+export { ReactComponent as IFrameCompIcon } from "icons/remix/window-2-line.svg"; // Closest match for iframe component
 export { ReactComponent as ListViewIcon } from "./icon-insert-listView.svg";
-export { ReactComponent as GridCompIcon } from "./remix/grid-line.svg"; // Closest match for grid component
+export { ReactComponent as GridCompIcon } from "icons/remix/grid-line.svg"; // Closest match for grid component
 export { ReactComponent as PackUpIcon } from "./icon-Pack-up.svg";
-export { ReactComponent as SearchIcon } from "./remix/search-line.svg"; // Closest match for search icon
-export { ReactComponent as SearchOutlinedIcon } from "./remix/search-eye-line.svg"; // Closest match for search outlined icon
-export { ReactComponent as FilterIcon } from "./remix/filter-line.svg"; // Closest match for filter icon
-export { ReactComponent as DownloadIcon } from "./remix/download-line.svg"; // Closest match for download icon
-export { ReactComponent as DownloadBoldIcon } from "./remix/download-2-line.svg"; // Closest match for download bold icon
+export { ReactComponent as SearchIcon } from "icons/remix/search-line.svg"; // Closest match for search icon
+export { ReactComponent as SearchOutlinedIcon } from "icons/remix/search-eye-line.svg"; // Closest match for search outlined icon
+export { ReactComponent as FilterIcon } from "icons/remix/filter-line.svg"; // Closest match for filter icon
+export { ReactComponent as DownloadIcon } from "icons/remix/download-line.svg"; // Closest match for download icon
+export { ReactComponent as DownloadBoldIcon } from "icons/remix/download-2-line.svg"; // Closest match for download bold icon
 export { ReactComponent as DownloadedIcon } from "./icon-downloaded.svg";
-export { ReactComponent as SettingIcon } from "./remix/settings-line.svg"; // Closest match for setting icon
-export { ReactComponent as RefreshIcon } from "./remix/refresh-line.svg"; // Closest match for refresh icon
-export { ReactComponent as DeleteIcon } from "./remix/delete-bin-6-line.svg"; // Closest match for delete icon
+export { ReactComponent as SettingIcon } from "icons/remix/settings-line.svg"; // Closest match for setting icon
+export { ReactComponent as RefreshIcon } from "icons/remix/refresh-line.svg"; // Closest match for refresh icon
+export { ReactComponent as DeleteIcon } from "icons/remix/delete-bin-6-line.svg"; // Closest match for delete icon
 export { ReactComponent as DeleteInputIcon } from "./icon-deleteinput.svg";
 export { ReactComponent as UpgradeIcon } from "./icon-upgrade.svg";
-export { ReactComponent as QuestionIcon } from "./remix/question-line.svg"; // Closest match for question icon
-export { ReactComponent as CloseIcon } from "./remix/close-line.svg"; // Closest match for close icon
-export { ReactComponent as SuccessIcon } from "./remix/check-double-line.svg"; // Closest match for success icon
-export { ReactComponent as ErrorIcon } from "./remix/error-warning-line.svg"; // Closest match for error icon
-export { ReactComponent as DocIcon } from "./remix/file-text-line.svg"; // Closest match for document icon
+export { ReactComponent as QuestionIcon } from "icons/remix/question-line.svg"; // Closest match for question icon
+export { ReactComponent as CloseIcon } from "icons/remix/close-line.svg"; // Closest match for close icon
+export { ReactComponent as SuccessIcon } from "icons/remix/check-double-line.svg"; // Closest match for success icon
+export { ReactComponent as ErrorIcon } from "icons/remix/error-warning-line.svg"; // Closest match for error icon
+export { ReactComponent as DocIcon } from "icons/remix/file-text-line.svg"; // Closest match for document icon
 export { ReactComponent as DocBoldIcon } from "./icon-tutorial-bold.svg";
-export { ReactComponent as QRCodeCompIcon } from "./remix/qr-code-line.svg"; // Closest match for QR code component
+export { ReactComponent as QRCodeCompIcon } from "icons/remix/qr-code-line.svg"; // Closest match for QR code component
 export { ReactComponent as NavDocIcon } from "./icon-nav-doc.svg";
 export { ReactComponent as LabIcon } from "./icon-laboratory.svg";
 export { ReactComponent as JsonExplorerCompIcon } from "./icon-json-explorer.svg";
 export { ReactComponent as JsonEditorCompIcon } from "./icon-json-editor.svg";
-export { ReactComponent as ArrowIcon } from "./remix/arrow-right-s-line.svg"; // Closest generic match for arrow icon
-export { ReactComponent as ArrowSolidIcon } from "./remix/arrow-right-line.svg"; // Closest match for solid arrow icon
-export { ReactComponent as AudioCompIcon } from "./remix/speaker-3-line.svg"; // Closest match for audio component
-export { ReactComponent as VideoCompIcon } from "./remix/video-line.svg"; // Closest match for video component
+export { ReactComponent as ArrowIcon } from "icons/remix/arrow-right-s-line.svg"; // Closest generic match for arrow icon
+export { ReactComponent as ArrowSolidIcon } from "icons/remix/arrow-right-line.svg"; // Closest match for solid arrow icon
+export { ReactComponent as AudioCompIcon } from "icons/remix/speaker-3-line.svg"; // Closest match for audio component
+export { ReactComponent as VideoCompIcon } from "icons/remix/video-line.svg"; // Closest match for video component
 export { ReactComponent as videoPlayTriangle } from "./icon-video-play-triangle.svg";
-export { ReactComponent as DrawerCompIcon } from "./remix/sidebar-unfold-line.svg"; // Closest match for drawer component
-export { ReactComponent as LeftMeetingIcon } from "./remix/team-line.svg"; // Closest match for left meeting icon
-export { ReactComponent as PlusIcon } from "./remix/add-line.svg"; // Closest match for plus icon
-export { ReactComponent as HomeIcon } from "./remix/home-2-line.svg"; // Closest match for home icon
+export { ReactComponent as DrawerCompIcon } from "icons/remix/sidebar-unfold-line.svg"; // Closest match for drawer component
+export { ReactComponent as LeftMeetingIcon } from "icons/remix/team-line.svg"; // Closest match for left meeting icon
+export { ReactComponent as PlusIcon } from "icons/remix/add-line.svg"; // Closest match for plus icon
+export { ReactComponent as HomeIcon } from "icons/remix/home-2-line.svg"; // Closest match for home icon
 export { ReactComponent as HomeModuleIcon } from "./icon-application-module.svg";
 export { ReactComponent as HomeQueryLibraryIcon } from "./icon-application-query-library.svg";
 export { ReactComponent as HomeDataSourceIcon } from "./icon-application-datasource.svg";
@@ -489,8 +491,8 @@ export { ReactComponent as HomeQueryLibraryActiveIcon } from "./icon-application
 export { ReactComponent as HomeDataSourceActiveIcon } from "./icon-application-datasource-active.svg";
 export { ReactComponent as RecyclerActiveIcon } from "./icon-application-recycler-active.svg";
 export { ReactComponent as FavoritesIcon } from "./icon-application-favorites.svg";
-export { ReactComponent as HomeSettingIcon } from "./remix/settings-5-line.svg"; // Closest match for home setting icon
-export { ReactComponent as FolderIcon } from "./remix/folder-4-line.svg"; // Closest match for folder icon
+export { ReactComponent as HomeSettingIcon } from "icons/remix/settings-5-line.svg"; // Closest match for home setting icon
+export { ReactComponent as FolderIcon } from "icons/remix/folder-4-line.svg"; // Closest match for folder icon
 export { ReactComponent as AllTypesIcon } from "./icon-application-all.svg";
 export { ReactComponent as InviteUserIcon } from "./icon-application-invite-user.svg";
 export { ReactComponent as HomeEmptyIcon } from "./icon-application-empty.svg";
@@ -518,15 +520,15 @@ export { ReactComponent as MSSQLIcon } from "./icon-query-mssql.svg";
 export { ReactComponent as SMTPIcon } from "./icon-query-SMTP.svg";
 export { ReactComponent as OracleIcon } from "./icon-query-OracleDB.svg";
 export { ReactComponent as ClickHouseIcon } from "./icon-query-ClickHouse.svg";
-export { ReactComponent as ResetIcon } from "./remix/refresh-line.svg"; // Closest match for reset icon
-export { ReactComponent as EditIcon } from "./remix/edit-2-line.svg"; // Closest match for edit icon
+export { ReactComponent as ResetIcon } from "icons/remix/refresh-line.svg"; // Closest match for reset icon
+export { ReactComponent as EditIcon } from "icons/remix/edit-2-line.svg"; // Closest match for edit icon
 export { ReactComponent as EditableIcon } from "./icon-editable.svg";
 export { ReactComponent as LeftStateIcon } from "./icon-left-state.svg";
 export { ReactComponent as LeftSettingIcon } from "./icon-left-setting.svg";
 export { ReactComponent as LeftHelpIcon } from "./icon-left-help.svg";
 export { ReactComponent as LeftPreloadIcon } from "./icon-left-preload.svg";
 export { ReactComponent as CollapsibleContainerCompIcon } from "./icon-collapsible-container.svg";
-export { ReactComponent as ToggleButtonCompIcon } from "./remix/switch-line.svg"; // Closest match for toggle button component
+export { ReactComponent as ToggleButtonCompIcon } from "icons/remix/switch-line.svg"; // Closest match for toggle button component
 export { ReactComponent as GoogleSheetsIcon } from "./icon-query-GoogleSheets.svg";
 export { ReactComponent as GraphqlIcon } from "./icon-query-Graphql.svg";
 export { ReactComponent as SnowflakeIcon } from "./icon-query-snowflake.svg";
@@ -538,71 +540,71 @@ export { ReactComponent as HomeSettingsActiveIcon } from "./icon-home-settings-a
 export { ReactComponent as HelpGithubIcon } from "./icon-help-github.svg";
 export { ReactComponent as HelpDiscordIcon } from "./icon-help-discord.svg";
 export { ReactComponent as LeftAudio } from "./icon-left-comp-audio.svg";
-export { ReactComponent as LeftButton } from "./remix/rectangle-line.svg"; // Closest match for left button
-export { ReactComponent as LeftChart } from "./remix/bar-chart-2-line.svg"; // Closest match for left chart
-export { ReactComponent as LeftCheckbox } from "./remix/checkbox-line.svg"; // Closest match for left checkbox
+export { ReactComponent as LeftButton } from "icons/remix/rectangle-line.svg"; // Closest match for left button
+export { ReactComponent as LeftChart } from "icons/remix/bar-chart-2-line.svg"; // Closest match for left chart
+export { ReactComponent as LeftCheckbox } from "icons/remix/checkbox-line.svg"; // Closest match for left checkbox
 export { ReactComponent as LeftCommon } from "./icon-left-comp-common.svg";
 export { ReactComponent as LeftContainer } from "./icon-left-comp-container.svg";
-export { ReactComponent as LeftDate } from "./remix/calendar-2-line.svg"; // Closest match for left date
+export { ReactComponent as LeftDate } from "icons/remix/calendar-2-line.svg"; // Closest match for left date
 export { ReactComponent as LeftDivider } from "./icon-left-comp-divider.svg";
-export { ReactComponent as LeftDrawer } from "./remix/sidebar-unfold-line.svg"; // Closest match for drawer component
-export { ReactComponent as LeftMeeting } from "./remix/team-line.svg"; // Closest match for left meeting icon
-export { ReactComponent as LeftFile } from "./remix/file-line.svg"; // Closest match for left file
+export { ReactComponent as LeftDrawer } from "icons/remix/sidebar-unfold-line.svg"; // Closest match for drawer component
+export { ReactComponent as LeftMeeting } from "icons/remix/team-line.svg"; // Closest match for left meeting icon
+export { ReactComponent as LeftFile } from "icons/remix/file-line.svg"; // Closest match for left file
 export { ReactComponent as LeftFileViewer } from "./icon-left-comp-fileViewer.svg";
-export { ReactComponent as LeftForm } from "./remix/draft-line.svg"; // Closest match for left form
-export { ReactComponent as LeftIframe } from "./remix/window-2-line.svg"; // Closest match for left iframe
-export { ReactComponent as LeftImage } from "./remix/image-line.svg"; // Closest match for left image
-export { ReactComponent as LeftInput } from "./remix/input-method-line.svg"; // Closest match for left input
+export { ReactComponent as LeftForm } from "icons/remix/draft-line.svg"; // Closest match for left form
+export { ReactComponent as LeftIframe } from "icons/remix/window-2-line.svg"; // Closest match for left iframe
+export { ReactComponent as LeftImage } from "icons/remix/image-line.svg"; // Closest match for left image
+export { ReactComponent as LeftInput } from "icons/remix/input-method-line.svg"; // Closest match for left input
 export { ReactComponent as LeftJsonEditor } from "./icon-left-comp-jsonEditor.svg";
-export { ReactComponent as LeftLink } from "./remix/links-line.svg"; // Closest match for left link
+export { ReactComponent as LeftLink } from "icons/remix/links-line.svg"; // Closest match for left link
 export { ReactComponent as LeftListView } from "./icon-left-comp-listView.svg";
-export { ReactComponent as LeftModal } from "./remix/shadow-line.svg"; // Closest match for left modal
-export { ReactComponent as LeftNavigation } from "./remix/compass-line.svg"; // Closest match for left navigation
+export { ReactComponent as LeftModal } from "icons/remix/shadow-line.svg"; // Closest match for left modal
+export { ReactComponent as LeftNavigation } from "icons/remix/compass-line.svg"; // Closest match for left navigation
 export { ReactComponent as LeftNumberInput } from "./icon-insert-numberInput.svg";
-export { ReactComponent as LeftPassword } from "./remix/key-2-line.svg"; // Closest match for left password
+export { ReactComponent as LeftPassword } from "icons/remix/key-2-line.svg"; // Closest match for left password
 export { ReactComponent as LeftProgress } from "./icon-progress.svg";
-export { ReactComponent as LeftQrCode } from "./remix/qr-code-line.svg"; // Closest match for left QR code
-export { ReactComponent as LeftRadio } from "./remix/radio-line.svg"; // Closest match for left radio
-export { ReactComponent as LeftRating } from "./remix/star-line.svg"; // Closest match for left rating
+export { ReactComponent as LeftQrCode } from "icons/remix/qr-code-line.svg"; // Closest match for left QR code
+export { ReactComponent as LeftRadio } from "icons/remix/radio-line.svg"; // Closest match for left radio
+export { ReactComponent as LeftRating } from "icons/remix/star-line.svg"; // Closest match for left rating
 export { ReactComponent as LeftSegmentedControl } from "./icon-left-comp-segmentedControl.svg";
-export { ReactComponent as LeftSelect } from "./remix/dropdown-list.svg"; // Closest match for left select
-export { ReactComponent as LeftSlider } from "./remix/git-commit-line.svg"; // Closest match for left slider
-export { ReactComponent as LeftSwitch } from "./remix/switch-line.svg"; // Closest match for left switch
-export { ReactComponent as LeftTable } from "./remix/table-line.svg"; // Closest match for left table
-export { ReactComponent as LeftText } from "./remix/file-text-line.svg"; // Closest match for left text
-export { ReactComponent as LeftTime } from "./remix/time-line.svg"; // Closest match for left time
-export { ReactComponent as LeftTree } from "./remix/node-tree.svg"; // Closest match for left tree
-export { ReactComponent as LeftVideo } from "./remix/video-line.svg"; // Closest match for left video
-export { ReactComponent as LeftOpen } from "./remix/door-open-line.svg"; // Closest match for left open
-export { ReactComponent as LeftClose } from "./remix/door-closed-line.svg"; // Closest match for left close
-export { ReactComponent as ScannerIcon } from "./remix/scan-line.svg"; // Closest match for scanner icon
+export { ReactComponent as LeftSelect } from "icons/remix/dropdown-list.svg"; // Closest match for left select
+export { ReactComponent as LeftSlider } from "icons/remix/git-commit-line.svg"; // Closest match for left slider
+export { ReactComponent as LeftSwitch } from "icons/remix/switch-line.svg"; // Closest match for left switch
+export { ReactComponent as LeftTable } from "icons/remix/table-line.svg"; // Closest match for left table
+export { ReactComponent as LeftText } from "icons/remix/file-text-line.svg"; // Closest match for left text
+export { ReactComponent as LeftTime } from "icons/remix/time-line.svg"; // Closest match for left time
+export { ReactComponent as LeftTree } from "icons/remix/node-tree.svg"; // Closest match for left tree
+export { ReactComponent as LeftVideo } from "icons/remix/video-line.svg"; // Closest match for left video
+export { ReactComponent as LeftOpen } from "icons/remix/door-open-line.svg"; // Closest match for left open
+export { ReactComponent as LeftClose } from "icons/remix/door-closed-line.svg"; // Closest match for left close
+export { ReactComponent as ScannerIcon } from "icons/remix/scan-line.svg"; // Closest match for scanner icon
 export { ReactComponent as MaterialUploadIcon } from "./icon-material-upload.svg";
-export { ReactComponent as CalendarCompIcon } from "./remix/calendar-2-line.svg"; // Closest match for calendar component
+export { ReactComponent as CalendarCompIcon } from "icons/remix/calendar-2-line.svg"; // Closest match for calendar component
 export { ReactComponent as LeftSignature } from "./icon-left-signature.svg";
-export { ReactComponent as UndoIcon } from "./remix/arrow-go-back-line.svg"; // Closest match for undo icon
-export { ReactComponent as SignatureIcon } from "./remix/pen-nib-line.svg"; // Closest match for signature icon
+export { ReactComponent as UndoIcon } from "icons/remix/arrow-go-back-line.svg"; // Closest match for undo icon
+export { ReactComponent as SignatureIcon } from "icons/remix/pen-nib-line.svg"; // Closest match for signature icon
 export { ReactComponent as ManualIcon } from "./icon-manual.svg";
-export { ReactComponent as WarnIcon } from "./remix/alert-line.svg"; // Closest match for warn icon
+export { ReactComponent as WarnIcon } from "icons/remix/alert-line.svg"; // Closest match for warn icon
 export { ReactComponent as SyncManualIcon } from "./icon-sync-manual.svg";
-export { ReactComponent as DangerIcon } from "./remix/error-warning-line.svg"; // Closest match for danger icon
-export { ReactComponent as TableMinusIcon } from "./remix/checkbox-indeterminate-line.svg"; // Closest match for table minus icon
-export { ReactComponent as TablePlusIcon } from "./remix/add-box-line.svg"; // Closest match for table plus icon
-export { ReactComponent as MobileAppIcon } from "./remix/smartphone-line.svg"; // Closest match for mobile app icon
-export { ReactComponent as MobileNavIcon } from "./remix/navigation-line.svg"; // Closest match for mobile navigation icon
-export { ReactComponent as PcNavIcon } from "./remix/computer-line.svg"; // Closest match for PC navigation icon
-export { ReactComponent as UnLockIcon } from "./remix/lock-unlock-line.svg"; // Closest match for unlock icon
-export { ReactComponent as CalendarDeleteIcon } from "./remix/calendar-2-line.svg"; // Closest match for calendar delete icon
-export { ReactComponent as TableCheckedIcon } from "./remix/checkbox-circle-line.svg"; // Closest match for table checked icon
-export { ReactComponent as TableUnCheckedIcon } from "./remix/checkbox-blank-circle-line.svg"; // Closest match for table unchecked icon
-export { ReactComponent as FileFolderIcon } from "./remix/folder-2-line.svg"; // Closest match for file folder icon
-export { ReactComponent as ExpandIcon } from "./remix/menu-unfold-line.svg"; // Closest match for expand icon
-export { ReactComponent as CompressIcon } from "./remix/menu-fold-line.svg"; // Closest match for compress icon
-export { ReactComponent as TableCellsIcon } from "./remix/grid-line.svg"; // Closest match for table cells icon
-export { ReactComponent as TimeLineIcon } from "./remix/time-line.svg"; // Closest match for timeline icon
+export { ReactComponent as DangerIcon } from "icons/remix/error-warning-line.svg"; // Closest match for danger icon
+export { ReactComponent as TableMinusIcon } from "icons/remix/checkbox-indeterminate-line.svg"; // Closest match for table minus icon
+export { ReactComponent as TablePlusIcon } from "icons/remix/add-box-line.svg"; // Closest match for table plus icon
+export { ReactComponent as MobileAppIcon } from "icons/remix/smartphone-line.svg"; // Closest match for mobile app icon
+export { ReactComponent as MobileNavIcon } from "icons/remix/navigation-line.svg"; // Closest match for mobile navigation icon
+export { ReactComponent as PcNavIcon } from "icons/remix/computer-line.svg"; // Closest match for PC navigation icon
+export { ReactComponent as UnLockIcon } from "icons/remix/lock-unlock-line.svg"; // Closest match for unlock icon
+export { ReactComponent as CalendarDeleteIcon } from "icons/remix/calendar-2-line.svg"; // Closest match for calendar delete icon
+export { ReactComponent as TableCheckedIcon } from "icons/remix/checkbox-circle-line.svg"; // Closest match for table checked icon
+export { ReactComponent as TableUnCheckedIcon } from "icons/remix/checkbox-blank-circle-line.svg"; // Closest match for table unchecked icon
+export { ReactComponent as FileFolderIcon } from "icons/remix/folder-2-line.svg"; // Closest match for file folder icon
+export { ReactComponent as ExpandIcon } from "icons/remix/menu-unfold-line.svg"; // Closest match for expand icon
+export { ReactComponent as CompressIcon } from "icons/remix/menu-fold-line.svg"; // Closest match for compress icon
+export { ReactComponent as TableCellsIcon } from "icons/remix/grid-line.svg"; // Closest match for table cells icon
+export { ReactComponent as TimeLineIcon } from "icons/remix/time-line.svg"; // Closest match for timeline icon
 export { ReactComponent as LottieIcon } from "./icon-lottie.svg";
 export { ReactComponent as CommentIcon } from "./icon-comment-comp.svg";
 export { ReactComponent as MentionIcon } from "./icon-mention-comp.svg";
 export { ReactComponent as AutoCompleteCompIcon } from "./icon-autocomplete-comp.svg";
 export { ReactComponent as WidthIcon } from "./icon-width.svg";
-export { ReactComponent as ResponsiveLayoutCompIcon } from "./remix/layout-column-line.svg"; // Closest match for responsive layout component
+export { ReactComponent as ResponsiveLayoutCompIcon } from "icons/remix/layout-column-line.svg"; // Closest match for responsive layout component
 export { ReactComponent as TextSizeIcon } from "./icon-text-size.svg"; */
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/layout/gridItem.tsx b/client/packages/lowcoder/src/layout/gridItem.tsx
index d3fec9367b..ad1f8ae06e 100644
--- a/client/packages/lowcoder/src/layout/gridItem.tsx
+++ b/client/packages/lowcoder/src/layout/gridItem.tsx
@@ -82,11 +82,18 @@ export type GridItemProps = {
 
 export const IsDroppable = React.createContext(true);
 
-const ResizableStyled = styled(Resizable)<{ $zIndex: number }>`
-  z-index: ${props => props.$zIndex};
-  &:hover {
-    z-index: 1;
-  }
+/* const ResizableStyled = styled(Resizable)<{ $zIndex: number, isDroppable : boolean}>`
+  z-index: ${props => props.$zIndex * 10};
+  ${props => props.isDroppable && `
+    &:hover {
+      z-index: 1;
+    }
+  `}
+`; */
+
+// changed to remove &:hover { z-index: 1; as it lead into flickering
+const ResizableStyled = styled(Resizable)<{ $zIndex: number, isDroppable : boolean}>`
+  z-index: ${props => props.$zIndex * 10};
 `;
 
 /**
@@ -183,6 +190,7 @@ export function GridItem(props: GridItemProps) {
         resizeHandles={resizeHandles}
         handle={Handle}
         $zIndex={zIndex}
+        isDroppable={draggingUtils.getData("i") !== props.i}
       >
         {child}
       </ResizableStyled>
diff --git a/client/packages/lowcoder/src/pages/editor/LeftContent.tsx b/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
index 66f32141cf..faee2cea3f 100644
--- a/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
+++ b/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
@@ -6,9 +6,9 @@ import {
   CollapseTitle as Title,
   CopyTextButton,
   FoldedIcon,
-  LeftClose,
   LeftCommon,
-  LeftOpen,
+  LeftInfoFill,
+  LeftInfoLine,
   PadDiv,
   ScrollBar,
   Tooltip,
@@ -36,6 +36,7 @@ import cloneDeep from 'lodash/cloneDeep';
 import { useDispatch } from "react-redux";
 import { useApplicationId } from "util/hooks";
 import { updateApplication } from "redux/reduxActions/applicationActions";
+import { Divider } from "antd";
 
 const CollapseTitleWrapper = styled.div`
   display: flex;
@@ -195,6 +196,8 @@ const CollapseView = React.memo(
 
 interface LeftContentProps {
   uiComp: InstanceType<typeof UIComp>;
+  checkable?: boolean;
+  isDraggable?: boolean;
 }
 
 enum LeftTabKey {
@@ -250,6 +253,8 @@ export const LeftContent = (props: LeftContentProps) => {
   const [showData, setShowData] = useState<NodeInfo[]>([]);
   const dispatch = useDispatch();
   const applicationId = useApplicationId();
+  const checkable = props.checkable || false;
+  const isDraggable = props.isDraggable || false;
 
   const getTree = (tree: CompTree, result: NodeItem[], key?: string) => {
     const { items, children } = tree;
@@ -362,7 +367,7 @@ export const LeftContent = (props: LeftContentProps) => {
                     setShowData(newData);
                   }}
                 >
-                  <LeftOpen />
+                  <LeftInfoLine/>
                 </div>
               </Tooltip>
             ) : (
@@ -395,7 +400,7 @@ export const LeftContent = (props: LeftContentProps) => {
                     setShowData(newData);
                   }}
                 >
-                  <LeftClose />
+                  <LeftInfoFill />
                 </div>
               </Tooltip>
             ))}
@@ -438,7 +443,7 @@ export const LeftContent = (props: LeftContentProps) => {
     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;
@@ -452,85 +457,7 @@ export const LeftContent = (props: LeftContentProps) => {
     });
     return explorerData;
   }
-
-  interface DropInfo {
-    node: { key: string; pos: string };
-    dragNode: { key: string; pos: string };
-  }
-
-  const handleDragEnter = (info: { node?: any; expandedKeys?: any; }) => {
-    // Assuming 'info' has a property 'expandedKeys' which is an array of keys
-    const { expandedKeys } = info;
-    if (!expandedKeys.includes(info.node.key)) {
-      setExpandedKeys(expandedKeys);
-    }
-  };
-
-  const handleDrop = (info: { node: { key: any; pos: string; }; dragNode: { key: any; pos: string; }; }, type: TreeUIKey) => {
-    const dropPos = info.node.pos.split('-');
-    const dragPos = info.dragNode.pos.split('-');
-
-    if (dropPos.length === dragPos.length) {
-      setComponentTreeData(prevData => {
-        let newTreeData = cloneDeep(prevData);
-        const dropIndex = Number(dropPos[dropPos.length - 1]);
-        const dragIndex = Number(dragPos[dragPos.length - 1]);
-        const parentNodePos = dropPos.slice(0, -1).join('-');
-
-        // TODO: handle drag and drop for childen of root (container components for example)
-        // findNodeByPos does not work yet
-        const parentNode = parentNodePos === "0" ? { children: newTreeData } : findNodeByPos(newTreeData, parentNodePos);
-  
-        console.log('parentNode', parentNode);
-  
-        if (parentNode && parentNode.children) {
-          const draggedNodeIndex = parentNode.children.findIndex(node => node.key === info.dragNode.key);
-          if (draggedNodeIndex !== -1) {
-            const [draggedNode] = parentNode.children.splice(draggedNodeIndex, 1);
-            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;
-      });
-    }
-  };
   
-  const findNodeByPos = (nodes: NodeItem[], pos: string): { children: NodeItem[] } => {
-    const posArr = pos.split('-').map(p => Number(p));
-    let currentNode = { children: nodes };
-    for (let i = 0; i < posArr.length; i++) {
-      currentNode = currentNode.children[posArr[i]];
-    }
-    return currentNode;
-  };
 
   const getTreeUI = (type: TreeUIKey) => {
     // here the components get sorted by name
@@ -559,21 +486,22 @@ export const LeftContent = (props: LeftContentProps) => {
     }
 
     return (
-      <DirectoryTreeStyle
-        draggable={type === TreeUIKey.Components ? true : false}
-        onDragEnter={handleDragEnter}
-        onDrop={(info) => handleDrop(info, type)}
+      <><DirectoryTreeStyle
         treeData={type === TreeUIKey.Components ? componentTreeData : modalsTreeData}
-        icon={(props: any) => props.type && (CompStateIcon[props.type as UICompType] || <LeftCommon />)}
-        switcherIcon={(props: any) =>
-          props.expanded ? <FoldedIcon /> : <UnfoldIcon />
-        }
+        icon={(props: any) => props.type && (
+          <div style={{ margin: '3px 0 0 -3px'}}> {/* Adjust the margin as needed */}
+            {CompStateIcon[props.type as UICompType] || <LeftCommon />}
+          </div>
+        )}
+        switcherIcon={(props: any) => props.expanded ? <FoldedIcon /> : <UnfoldIcon />}
         expandedKeys={expandedKeys}
         onExpand={(keys) => setExpandedKeys(keys)}
         onClick={(e, node) => handleNodeClick(e, node, uiCompInfos)}
         selectedKeys={selectedKeys}
-        titleRender={(nodeData) => getTreeNode(nodeData as NodeItem, uiCompInfos)}
-      />
+        titleRender={(nodeData) => getTreeNode(nodeData as NodeItem, uiCompInfos)} />
+        <Divider />
+        <div></div>
+        </>
     );
   };
 
@@ -623,6 +551,7 @@ export const LeftContent = (props: LeftContentProps) => {
   }, [editorState]);
 
   const moduleLayoutComp = uiComp.getModuleLayoutComp();
+
   const stateContent = (
     <ScrollBar>
       <div style={{ paddingBottom: 80 }}>
diff --git a/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx b/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
new file mode 100644
index 0000000000..bba1dfbd3d
--- /dev/null
+++ b/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
@@ -0,0 +1,325 @@
+import { CompInfo, EditorContext } from "comps/editorState";
+import {
+  BaseSection,
+  Collapse,
+  CollapseLabel as Label,
+  CollapseTitle as Title,
+  CopyTextButton,
+  FoldedIcon,
+  LeftCommon,
+  LeftInfoFill,
+  LeftInfoLine,
+  PadDiv,
+  ScrollBar,
+  Tooltip,
+  UnfoldIcon,
+  UnShow,
+} from "lowcoder-design";
+import React, { ReactNode, useCallback, useContext, useMemo, useState, useEffect } from "react";
+import { hookCompCategory } from "comps/hooks/hookCompTypes";
+import _ from "lodash";
+import styled from "styled-components";
+import { leftCompListClassName } from "pages/tutorials/tutorialsConstant";
+import UIComp from "comps/comps/uiComp";
+import { BottomResTypeEnum } from "types/bottomRes";
+import { getParentNodeKeysByKey, getTreeNodeByKey, safeJSONStringify } from "util/objectUtils";
+import { Tabs, TabTitle } from "components/Tabs";
+import { BackgroundColor, TopHeaderHeight } from "constants/style";
+import { trans } from "i18n";
+import { CompTree } from "comps/comps/containerBase";
+import { CompStateIcon } from "./editorConstants";
+import { UICompType } from "comps/uiCompRegistry";
+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";
+import { Divider } from "antd";
+import { Switch } from "antd";
+import {
+  saveCollisionStatus,
+  getCollisionStatus,
+} from "util/localStorageUtil";
+
+
+export type DisabledCollisionStatus = "true" | "false"; // "true" means collision is not enabled - Layering works, "false" means collision is enabled - Layering does not work
+export  type ToggleCollisionStatus = (
+    collisionStatus?: DisabledCollisionStatus
+  ) => void;
+
+interface LeftLayersContentProps {
+  uiComp: InstanceType<typeof UIComp>;
+}
+
+type NodeItem = {
+  key: string;
+  title: string;
+  type?: UICompType;
+  children: NodeItem[];
+  pos?: number;
+  disabled?: boolean;
+  fixed?: boolean;
+};
+
+const LeftLayersContentWrapper = styled.div`
+  height: calc(100vh - ${TopHeaderHeight});
+`;
+
+export const LeftLayersContent = (props: LeftLayersContentProps) => {
+  const { uiComp } = props;
+  const editorState = useContext(EditorContext);
+  const [expandedKeys, setExpandedKeys] = useState<Array<React.Key>>([]);
+  const dispatch = useDispatch();
+  const applicationId = useApplicationId();
+
+  // added by Falk Wolsky to support a Layers in Lowcoder
+  const [collisionStatus, setCollisionStatus] = useState(() => {
+    return getCollisionStatus();
+  });
+
+  const toggleCollisionStatus: ToggleCollisionStatus = useCallback(
+    (value) => {
+      setCollisionStatus(value ? value : ("false" as DisabledCollisionStatus));
+      saveCollisionStatus(value ? value : ("false" as DisabledCollisionStatus));
+    },
+    [collisionStatus]
+  );
+
+  const getTree = (tree: CompTree, result: NodeItem[], key?: string) => {
+    const { items, children } = tree;
+    if (Object.keys(items).length) {
+      for (const i in items) {
+        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]);
+    }
+    if (Object.keys(children).length) {
+      for (const i in children) {
+        getTree(children[i], result, i);
+      }
+    }
+    return result;
+  };
+
+  const uiCollapseClick = useCallback(
+    (compName: string) => {
+      editorState.setSelectedCompNames(new Set([compName]), "leftPanel");
+    },
+    [editorState]
+  );
+
+  const getTreeNode = (node: NodeItem, uiCompInfos: CompInfo[]) => {
+    const data = uiCompInfos.find((item) => item.name === node.title);
+    return (
+      <Node>
+        <span>
+          <span>{node.title}</span>
+        </span>
+        
+      </Node>
+    );
+  };
+
+  const [componentTreeData, setComponentTreeData] = useState<NodeItem[]>([]);
+
+  useEffect(() => {
+    const compData = getTreeUIData();
+    setComponentTreeData(compData);
+  }, [editorState]);
+  
+  const getTreeUIData = () => {
+    const tree = editorState.getUIComp().getTree();
+    const explorerData: NodeItem[] = getTree(tree, []);
+    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;
+  }
+
+  interface DropInfo {
+    node: { key: string; pos: string };
+    dragNode: { key: string; pos: string };
+  }
+
+  const handleDragEnter = (info: { node?: any; expandedKeys?: any; }) => {
+    // Assuming 'info' has a property 'expandedKeys' which is an array of keys
+    const { expandedKeys } = info;
+    if (!expandedKeys.includes(info.node.key)) {
+      setExpandedKeys(expandedKeys);
+    }
+  };
+
+  const handleDrop = (info: { node: { key: any; pos: string; }; dragNode: { key: any; pos: string; }; }) => {
+    const dropPos = info.node.pos.split('-');
+    const dragPos = info.dragNode.pos.split('-');
+
+    if (dropPos.length === dragPos.length) {
+      setComponentTreeData(prevData => {
+        let newTreeData = cloneDeep(prevData);
+        const dropIndex = Number(dropPos[dropPos.length - 1]);
+        const dragIndex = Number(dragPos[dragPos.length - 1]);
+        const parentNodePos = dropPos.slice(0, -1).join('-');
+
+        // TODO: handle drag and drop for childen of root (container components for example)
+        // findNodeByPos does not work yet
+        const parentNode = parentNodePos === "0" ? { children: newTreeData } : findNodeByPos(newTreeData, parentNodePos);
+    
+        if (parentNode && parentNode.children) {
+          const draggedNodeIndex = parentNode.children.findIndex(node => node.key === info.dragNode.key);
+          if (draggedNodeIndex !== -1) {
+            const [draggedNode] = parentNode.children.splice(draggedNodeIndex, 1);
+            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,
+          };
+        })
+        
+        dispatch(
+          updateApplication({
+            applicationId: applicationId,
+            editingApplicationDSL: {
+              ...dsl,
+              ui: {
+                ...dsl.ui,
+                layout,
+              }
+            } as object,
+          })
+        );
+        editorState.rootComp.children.ui.dispatchChangeValueAction({
+          ...dsl.ui,
+          layout,
+        })
+        return newTreeData;
+      });
+    }
+  };
+  
+  const findNodeByPos = (nodes: NodeItem[], pos: string): { children: NodeItem[] } => {
+    const posArr = pos.split('-').map(p => Number(p));
+    let currentNode = { children: nodes };
+    for (let i = 0; i < posArr.length; i++) {
+      currentNode = currentNode.children[posArr[i]];
+    }
+    return currentNode;
+  };
+
+  const [checkedKeys, setCheckedKeys] = useState<string[]>([]);
+
+  const onCheck = (checkedKeys: any, e: any) => {
+    setCheckedKeys(checkedKeys);
+    console.log('onCheck', checkedKeys);
+  }
+
+  const getTreeUI = () => {
+    // here the components get sorted by name
+    // TODO: sort by category
+    // TODO: sort by Types etc.
+    const uiCompInfos = _.sortBy(editorState.uiCompInfoList(), [(x) => x.name]);
+    
+    /* const tree =
+      type === TreeUIKey.Components
+        ? editorState.getUIComp().getTree()
+        : editorState.getHooksComp().getUITree();
+    const explorerData: NodeItem[] = getTree(tree, []); */
+    
+    let selectedKeys = [];
+    if (editorState.selectedCompNames.size === 1) {
+      const key = Object.keys(editorState.selectedComps())[0];
+      const parentKeys = getParentNodeKeysByKey(componentTreeData, key);
+      if (parentKeys && parentKeys.length) {
+        let needSet = false;
+        parentKeys.forEach((key) => {
+          if (!expandedKeys.includes(key)) {
+            needSet = true;
+          }
+        });
+        needSet && setExpandedKeys(_.union(expandedKeys, parentKeys));
+      }
+      selectedKeys.push(key);
+    }
+
+    const isDraggable = editorState.collisionStatus === "true" ? true : false;
+
+    return (
+      <>
+        <Switch
+          checked={editorState.collisionStatus == "true"}
+          disabled={false}
+          onChange={(value: any) => {
+            toggleCollisionStatus(value == true ? "true" : "false");
+            editorState.setCollisionStatus(value == true ? "true" : "false");
+          } } />
+      <DirectoryTreeStyle
+        checkable={true}
+        onCheck={onCheck}
+        draggable={isDraggable}
+        onDragEnter={handleDragEnter}
+        onDrop={(info) => handleDrop(info)}
+        treeData={componentTreeData}
+        icon={(props: any) => props.type && (
+          <div style={{ margin: '3px 0 0 -3px'}}> {/* Adjust the margin as needed */}
+            {CompStateIcon[props.type as UICompType] || <LeftCommon />}
+          </div>
+        )}
+        switcherIcon={(props: any) => props.expanded ? <FoldedIcon /> : <UnfoldIcon />}
+        expandedKeys={expandedKeys}
+        onExpand={(keys) => setExpandedKeys(keys)}
+        // onClick={(e, node) => handleNodeClick(e, node, uiCompInfos)}
+        selectedKeys={selectedKeys}
+        titleRender={(nodeData) => getTreeNode(nodeData as NodeItem, uiCompInfos)} />
+        <Divider />
+        <div></div>
+        </>
+    );
+  };
+
+  const uiCollapse = useMemo(() => {
+    if (isAggregationApp(editorState.getAppType())) {
+      return;
+    }
+    return getTreeUI();
+  }, [editorState, uiCollapseClick, expandedKeys, componentTreeData]);
+  
+  const layerControlContent = (
+    <ScrollBar>
+      <div style={{ paddingBottom: 80 }}>
+        <BaseSection name={trans("leftPanel.components")} width={288} noMargin>
+          <span className={leftCompListClassName}>{uiCollapse}</span>
+        </BaseSection>
+      </div>
+    </ScrollBar>
+  );
+
+  return <LeftLayersContentWrapper className="cypress-left-content">{layerControlContent}</LeftLayersContentWrapper>;
+  
+};
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/pages/editor/editorView.tsx b/client/packages/lowcoder/src/pages/editor/editorView.tsx
index 8cd7390fef..45a5122142 100644
--- a/client/packages/lowcoder/src/pages/editor/editorView.tsx
+++ b/client/packages/lowcoder/src/pages/editor/editorView.tsx
@@ -66,13 +66,12 @@ import {
   DefaultEditorModeStatus,
   getEditorModeStatus,
   saveEditorModeStatus,
-  saveCollisionStatus,
-  getCollisionStatus,
 } from "util/localStorageUtil";
 import Bottom from "./bottom/BottomPanel";
 import { LeftContent } from "./LeftContent";
+import { LeftLayersContent } from "./LeftLayersContent";
 import { isAggregationApp } from "util/appUtils";
-import { Switch } from "antd";
+
 
 const HookCompContainer = styled.div`
   pointer-events: none;
@@ -225,11 +224,6 @@ const items = [
   },
 ];
 
-  // added by Fred to set comp collision state
-export type DisabledCollisionStatus = "true" | "false"; // "true" means collision is not enabled - Layering works, "false" means collision is enabled - Layering does not work
-export  type ToggleCollisionStatus = (
-    collisionStatus?: DisabledCollisionStatus
-  ) => void;
 
 function EditorView(props: EditorViewProps) {
   const { uiComp } = props;
@@ -275,20 +269,6 @@ function EditorView(props: EditorViewProps) {
     [panelStatus, prePanelStatus]
   );
 
-  // added by Falk Wolsky to support a Layers in Lowcoder
-  const [collisionStatus, setCollisionStatus] = useState(() => {
-    return getCollisionStatus();
-  });
-
-  const toggleCollisionStatus: ToggleCollisionStatus = useCallback(
-    (value) => {
-      setCollisionStatus(value ? value : ("false" as DisabledCollisionStatus));
-      saveCollisionStatus(value ? value : ("false" as DisabledCollisionStatus));
-    },
-    [collisionStatus]
-  );
-
-
   // added by Falk Wolsky to support a Layout and Logic Mode in Lowcoder
   const [editorModeStatus, setEditorModeStatus] = useState(() => {
     return getEditorModeStatus();
@@ -386,6 +366,7 @@ function EditorView(props: EditorViewProps) {
     setMenuKey(params.key);
   };
   const appSettingsComp = editorState.getAppSettingsComp();
+
   return (
     <Height100Div
       onDragEnd={(e) => {
@@ -437,7 +418,7 @@ function EditorView(props: EditorViewProps) {
 
           {panelStatus.left && editorModeStatus !== "layout" && (
             <LeftPanel>
-              {menuKey === SiderKey.State && <LeftContent uiComp={uiComp} />}
+              {menuKey === SiderKey.State && <LeftContent uiComp={uiComp}/>}
               {menuKey === SiderKey.Setting && (
                 <SettingsDiv>
                   <ScrollBar>
@@ -470,20 +451,8 @@ function EditorView(props: EditorViewProps) {
                 </SettingsDiv>
               )}
 
-              
-
               {menuKey === SiderKey.Layout && (
-                <SettingsDiv>
-                  <Switch
-                    checked={editorState.collisionStatus == "true"}
-                    disabled={false}
-                    onChange={(value: any) => {
-                      toggleCollisionStatus(value == true ? "true" : "false");
-                      editorState.setCollisionStatus(value == true ? "true" : "false");
-                    }}
-                  />
-                   <Divider />            
-                </SettingsDiv>
+                <LeftLayersContent uiComp={uiComp} />
               )}
 
             </LeftPanel>
diff --git a/client/packages/lowcoder/src/pages/editor/styledComponents.tsx b/client/packages/lowcoder/src/pages/editor/styledComponents.tsx
index 6df7b9d7a7..2188b4ea1d 100644
--- a/client/packages/lowcoder/src/pages/editor/styledComponents.tsx
+++ b/client/packages/lowcoder/src/pages/editor/styledComponents.tsx
@@ -31,6 +31,9 @@ export const DirectoryTreeStyle = styled(DirectoryTree)`
       align-items: center;
     }
   }
+  .ant-tree-checkbox+span {
+    padding-left: 0;
+  }
   .ant-tree-treenode {
     padding: 0;
     max-width: 288px;
@@ -110,14 +113,17 @@ export const Node = styled.span`
   }
 `;
 
+// margin: 4px -16px 4px ${(props) => props.$clientX && `calc(-${props.$clientX}px + 16px)`};
+//  width: 256px;
 export const CollapseWrapper = styled.div<{ $clientX?: number }>`
-  width: 256px;
+  width: 100%; 
   border: 1px solid #E1E3EB;
   border-radius: 4px;
   overflow: hidden;
   background: #fff;
-  padding: 4px 0;
-  margin: 4px -16px 4px ${(props) => props.$clientX && `calc(-${props.$clientX}px + 16px)`};
+  padding: 0px;
+  position: relative;
+  margin: 4px 0px 4px 0};
   .simplebar-content > div {
     > .ant-collapse > .ant-collapse-item {
       > .ant-collapse-header {
diff --git a/client/packages/lowcoder/src/util/localStorageUtil.ts b/client/packages/lowcoder/src/util/localStorageUtil.ts
index 2f102a6967..1c468be88b 100644
--- a/client/packages/lowcoder/src/util/localStorageUtil.ts
+++ b/client/packages/lowcoder/src/util/localStorageUtil.ts
@@ -1,5 +1,5 @@
 import { PanelStatus } from "pages/common/header";
-import { DisabledCollisionStatus as DisabledCollisionStatus } from "pages/editor/editorView";
+import { DisabledCollisionStatus as DisabledCollisionStatus } from "pages/editor/LeftLayersContent";
 import { EditorModeStatus } from "pages/common/header";
 import log from "loglevel";
 import { JSONValue } from "util/jsonTypes";

From 9ac931aec3b0adfabe9f85a54c84057de4d011e9 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Sun, 4 Feb 2024 17:45:08 +0100
Subject: [PATCH 24/97] [WIP] Own Display for Layers

---
 .../lowcoder-design/src/icons/index.ts        | 365 +++++++++---------
 .../packages/lowcoder/src/i18n/locales/en.ts  |   7 +-
 .../packages/lowcoder/src/i18n/locales/zh.ts  |   5 +-
 .../lowcoder/src/pages/editor/LeftContent.tsx | 111 ++----
 .../src/pages/editor/LeftLayersContent.tsx    | 249 ++++++++----
 .../lowcoder/src/pages/editor/editorView.tsx  |  21 +-
 6 files changed, 420 insertions(+), 338 deletions(-)

diff --git a/client/packages/lowcoder-design/src/icons/index.ts b/client/packages/lowcoder-design/src/icons/index.ts
index 8b80e30bf1..938cd1fc40 100644
--- a/client/packages/lowcoder-design/src/icons/index.ts
+++ b/client/packages/lowcoder-design/src/icons/index.ts
@@ -214,8 +214,9 @@ export { ReactComponent as ClickHouseIcon } from "./icon-query-ClickHouse.svg";
 export { ReactComponent as ResetIcon } from "./icon-style-reset.svg";
 export { ReactComponent as EditIcon } from "./icon-edit.svg";
 export { ReactComponent as EditableIcon } from "./icon-editable.svg";
-export { ReactComponent as LeftStateIcon } from "./icon-left-state.svg";
-export { ReactComponent as LeftSettingIcon } from "./icon-left-setting.svg";
+export { ReactComponent as LeftStateIcon } from "./remix/node-tree.svg";
+export { ReactComponent as LeftSettingIcon } from "./remix/tools-fill.svg";
+export { ReactComponent as LeftLayersIcon } from "./remix/stack-line.svg";
 export { ReactComponent as LeftHelpIcon } from "./icon-left-help.svg";
 export { ReactComponent as LeftPreloadIcon } from "./icon-left-preload.svg";
 export { ReactComponent as CollapsibleContainerCompIcon } from "./icon-collapsible-container.svg";
@@ -277,127 +278,131 @@ export { ReactComponent as SignatureIcon } from "./icon-signature.svg";
 export { ReactComponent as ManualIcon } from "./icon-manual.svg";
 export { ReactComponent as WarnIcon } from "./icon-warn.svg";
 export { ReactComponent as SyncManualIcon } from "./icon-sync-manual.svg";
-export { ReactComponent as DangerIcon } from "icons/icon-danger.svg";
-export { ReactComponent as TableMinusIcon } from "icons/icon-table-minus.svg";
-export { ReactComponent as TablePlusIcon } from "icons/icon-table-plus.svg";
-export { ReactComponent as MobileAppIcon } from "icons/icon-mobile-app.svg";
-export { ReactComponent as MobileNavIcon } from "icons/icon-navigation-mobile.svg";
-export { ReactComponent as PcNavIcon } from "icons/icon-navigation-pc.svg";
-export { ReactComponent as UnLockIcon } from "icons/icon-unlock.svg";
-export { ReactComponent as CalendarDeleteIcon } from "icons/icon-calendar-delete.svg";
-export { ReactComponent as TableCheckedIcon } from "icons/icon-table-checked.svg";
-export { ReactComponent as TableUnCheckedIcon } from "icons/icon-table-boolean-false.svg";
-export { ReactComponent as FileFolderIcon } from "icons/icon-editor-folder.svg";
-export { ReactComponent as ExpandIcon } from "icons/icon-expand.svg";
-export { ReactComponent as CompressIcon } from "icons/icon-compress.svg";
-export { ReactComponent as TableCellsIcon } from "icons/icon-table-cells.svg"; // Added By Aqib Mirza
-export { ReactComponent as TimeLineIcon } from "icons/icon-timeline-comp.svg"
-export { ReactComponent as LottieIcon } from "icons/icon-lottie.svg";
-export { ReactComponent as CommentIcon } from "icons/icon-comment-comp.svg";
-export { ReactComponent as MentionIcon } from "icons/icon-mention-comp.svg";
-export { ReactComponent as AutoCompleteCompIcon } from "icons/icon-autocomplete-comp.svg";
-export { ReactComponent as WidthIcon } from "icons/icon-width.svg";
-export { ReactComponent as ResponsiveLayoutCompIcon } from "icons/icon-responsive-layout-comp.svg";
-export { ReactComponent as TextSizeIcon } from "icons/remix/font-size-2.svg";
-export { ReactComponent as FontFamilyIcon } from "icons/remix/font-sans-serif.svg";
-export { ReactComponent as TextWeigthIcon } from "icons/remix/bold.svg";
-export { ReactComponent as BorderWidthIcon } from "icons/remix/expand-width-line.svg";
-export { ReactComponent as LeftInfoLine } from "icons/remix/information-line.svg";
-export { ReactComponent as LeftInfoFill } from "icons/remix/information-fill.svg";
+export { ReactComponent as DangerIcon } from "./icon-danger.svg";
+export { ReactComponent as TableMinusIcon } from "./icon-table-minus.svg";
+export { ReactComponent as TablePlusIcon } from "./icon-table-plus.svg";
+export { ReactComponent as MobileAppIcon } from "./icon-mobile-app.svg";
+export { ReactComponent as MobileNavIcon } from "./icon-navigation-mobile.svg";
+export { ReactComponent as PcNavIcon } from "./icon-navigation-pc.svg";
+export { ReactComponent as UnLockIcon } from "./icon-unlock.svg";
+export { ReactComponent as CalendarDeleteIcon } from "./icon-calendar-delete.svg";
+export { ReactComponent as TableCheckedIcon } from "./icon-table-checked.svg";
+export { ReactComponent as TableUnCheckedIcon } from "./icon-table-boolean-false.svg";
+export { ReactComponent as FileFolderIcon } from "./icon-editor-folder.svg";
+export { ReactComponent as ExpandIcon } from "./icon-expand.svg";
+export { ReactComponent as CompressIcon } from "./icon-compress.svg";
+export { ReactComponent as TableCellsIcon } from "./icon-table-cells.svg"; // Added By Aqib Mirza
+export { ReactComponent as TimeLineIcon } from "./icon-timeline-comp.svg"
+export { ReactComponent as LottieIcon } from "./icon-lottie.svg";
+export { ReactComponent as CommentIcon } from "./icon-comment-comp.svg";
+export { ReactComponent as MentionIcon } from "./icon-mention-comp.svg";
+export { ReactComponent as AutoCompleteCompIcon } from "./icon-autocomplete-comp.svg";
+export { ReactComponent as WidthIcon } from "./icon-width.svg";
+export { ReactComponent as ResponsiveLayoutCompIcon } from "./icon-responsive-layout-comp.svg";
+export { ReactComponent as TextSizeIcon } from "./remix/font-size-2.svg";
+export { ReactComponent as FontFamilyIcon } from "./remix/font-sans-serif.svg";
+export { ReactComponent as TextWeigthIcon } from "./remix/bold.svg";
+export { ReactComponent as BorderWidthIcon } from "./remix/expand-width-line.svg";
+export { ReactComponent as LeftInfoLine } from "./remix/information-line.svg";
+export { ReactComponent as LeftInfoFill } from "./remix/information-fill.svg";
+export { ReactComponent as LeftShow } from "./remix/eye-off-line.svg";
+export { ReactComponent as LeftHide } from "./remix/eye-line.svg";
+export { ReactComponent as LeftLock } from "./remix/lock-line.svg";
+export { ReactComponent as LeftUnlock } from "./remix/lock-unlock-line.svg";
 
 
 // new
-/* export { ReactComponent as AppSnapshotIcon } from "icons/remix/screenshot-2-line.svg"; // Closest match for app snapshot
+/* export { ReactComponent as AppSnapshotIcon } from "./remix/screenshot-2-line.svg"; // Closest match for app snapshot
 export { ReactComponent as HookCompDropIcon } from "./hook-comp-drop.svg";
 export { ReactComponent as HookCompIcon } from "./hook-comp.svg";
-export { ReactComponent as IconsIcon } from "icons/remix/apps-line.svg"; // Closest match for icons
+export { ReactComponent as IconsIcon } from "./remix/apps-line.svg"; // Closest match for icons
 export { ReactComponent as JsGrayIcon } from "./icon-Js-Gray.svg";
 export { ReactComponent as JsColorsIcon } from "./icon-Js-colors.svg";
-export { ReactComponent as AdminIcon } from "icons/remix/admin-line.svg"; // Exact match
+export { ReactComponent as AdminIcon } from "./remix/admin-line.svg"; // Exact match
 export { ReactComponent as AlignVerticalCent } from "./icon-align-vertical-center.svg";
-export { ReactComponent as AppEditIcon } from "icons/remix/edit-box-line.svg"; // Closest match for app edit
+export { ReactComponent as AppEditIcon } from "./remix/edit-box-line.svg"; // Closest match for app edit
 export { ReactComponent as AuditAppIcon } from "./icon-audit-app.svg";
 export { ReactComponent as AuditDbIcon } from "./icon-audit-db.svg";
-export { ReactComponent as TreeFoldIcon } from "icons/remix/tree-line.svg"; // Closest match for tree fold
+export { ReactComponent as TreeFoldIcon } from "./remix/tree-line.svg"; // Closest match for tree fold
 export { ReactComponent as AuditQueryIcon } from "./icon-audit-query.svg";
 export { ReactComponent as AuditUserIcon } from "./icon-audit-user.svg";
-export { ReactComponent as AuditFolderIcon } from "icons/remix/folder-line.svg"; // Closest match for audit folder
+export { ReactComponent as AuditFolderIcon } from "./remix/folder-line.svg"; // Closest match for audit folder
 export { ReactComponent as AutoCompleteIcon } from "./icon-autoComplete.svg";
-export { ReactComponent as CalendarIcon } from "icons/remix/calendar-2-line.svg"; // Exact match
+export { ReactComponent as CalendarIcon } from "./remix/calendar-2-line.svg"; // Exact match
 export { ReactComponent as CaptchaIcon } from "./icon-captcha.svg";
-export { ReactComponent as CheckboxIcon } from "icons/remix/checkbox-line.svg"; // Exact match
+export { ReactComponent as CheckboxIcon } from "./remix/checkbox-line.svg"; // Exact match
 export { ReactComponent as CheckoutIcon } from "./icon-checkout.svg";
 export { ReactComponent as ClickLinkIcon } from "./icon-clickLink.svg";
-export { ReactComponent as CloseEyeIcon } from "icons/remix/eye-off-line.svg"; // Closest match for close eye
+export { ReactComponent as CloseEyeIcon } from "./remix/eye-off-line.svg"; // Closest match for close eye
 export { ReactComponent as CodeEditorCloseIcon } from "./icon-code-editor-close.svg";
 export { ReactComponent as CodeEditorOpenIcon } from "./icon-code-editor-open.svg";
-export { ReactComponent as ColorHexIcon } from "icons/remix/palette-line.svg"; // Closest match for color hex
+export { ReactComponent as ColorHexIcon } from "./remix/palette-line.svg"; // Closest match for color hex
 export { ReactComponent as ContainerDragIcon } from "./icon-container-drag.svg";
-export { ReactComponent as CopyIcon } from "icons/remix/file-copy-line.svg"; // Closest match for copy
+export { ReactComponent as CopyIcon } from "./remix/file-copy-line.svg"; // Closest match for copy
 export { ReactComponent as CreateModuleIcon } from "./icon-create-module.svg";
 export { ReactComponent as PrevIcon } from "./icon-date-prev.svg";
 export { ReactComponent as SuperPrevIcon } from "./icon-date-super-prev.svg";
 export { ReactComponent as DragWhiteIcon } from "./icon-drag-white.svg";
-export { ReactComponent as EmptyDataIcon } from "icons/remix/emotion-unhappy-line.svg"; // Closest match for empty data
+export { ReactComponent as EmptyDataIcon } from "./remix/emotion-unhappy-line.svg"; // Closest match for empty data
 export { ReactComponent as FlokcloseIcon } from "./icon-flokclose.svg";
 export { ReactComponent as FoldedIcon } from "./icon-folded.svg";
-export { ReactComponent as GridIcon } from "icons/remix/grid-line.svg"; // Exact match
-export { ReactComponent as GroupIcon } from "icons/remix/group-line.svg"; // Closest match for group
-export { ReactComponent as HelpIcon } from "icons/remix/question-answer-line.svg"; // Closest match for help
-export { ReactComponent as LayoutIcon } from "icons/remix/layout-6-line.svg"; // Closest match for layout
-export { ReactComponent as LockIcon } from "icons/remix/lock-line.svg"; // Exact match
-export { ReactComponent as MembersIcon } from "icons/remix/group-line.svg"; // Closest match for members
-export { ReactComponent as MoreActionIcon } from "icons/remix/more-2-line.svg"; // Closest match for more action
-export { ReactComponent as MultiselectTagIcon } from "icons/remix/price-tag-3-line.svg"; // Closest match for multiselect tag
-export { ReactComponent as MustFillStarIcon } from "icons/remix/star-line.svg"; // Closest match for must fill star
-export { ReactComponent as NofileIcon } from "icons/remix/file-unknow-line.svg"; // Closest match for nofile
+export { ReactComponent as GridIcon } from "./remix/grid-line.svg"; // Exact match
+export { ReactComponent as GroupIcon } from "./remix/group-line.svg"; // Closest match for group
+export { ReactComponent as HelpIcon } from "./remix/question-answer-line.svg"; // Closest match for help
+export { ReactComponent as LayoutIcon } from "./remix/layout-6-line.svg"; // Closest match for layout
+export { ReactComponent as LockIcon } from "./remix/lock-line.svg"; // Exact match
+export { ReactComponent as MembersIcon } from "./remix/group-line.svg"; // Closest match for members
+export { ReactComponent as MoreActionIcon } from "./remix/more-2-line.svg"; // Closest match for more action
+export { ReactComponent as MultiselectTagIcon } from "./remix/price-tag-3-line.svg"; // Closest match for multiselect tag
+export { ReactComponent as MustFillStarIcon } from "./remix/star-line.svg"; // Closest match for must fill star
+export { ReactComponent as NofileIcon } from "./remix/file-unknow-line.svg"; // Closest match for nofile
 export { ReactComponent as OmitIcon } from "./icon-omit.svg";
-export { ReactComponent as OpenEyeIcon } from "icons/remix/eye-line.svg"; // Closest match for open eye
-export { ReactComponent as PasswordIcon } from "icons/remix/lock-password-line.svg"; // Closest match for password
-export { ReactComponent as RadioCheckedIcon } from "icons/remix/list-radio.svg"; // Closest match for radio checked
-export { ReactComponent as RequiredIcon } from "icons/remix/alert-line.svg"; // Closest match for required
+export { ReactComponent as OpenEyeIcon } from "./remix/eye-line.svg"; // Closest match for open eye
+export { ReactComponent as PasswordIcon } from "./remix/lock-password-line.svg"; // Closest match for password
+export { ReactComponent as RadioCheckedIcon } from "./remix/list-radio.svg"; // Closest match for radio checked
+export { ReactComponent as RequiredIcon } from "./remix/alert-line.svg"; // Closest match for required
 export { ReactComponent as AttributeIcon } from "./icon-right-attribute.svg";
 export { ReactComponent as InsertIcon } from "./icon-right-insert.svg";
 export { ReactComponent as ShowBorderIcon } from "./icon-show-border.svg";
 export { ReactComponent as SpaceIcon } from "./icon-space.svg";
-export { ReactComponent as StarIcon } from "icons/remix/star-line.svg"; // Exact match
+export { ReactComponent as StarIcon } from "./remix/star-line.svg"; // Exact match
 export { ReactComponent as SuperUserIcon } from "./icon-super-user.svg";
-export { ReactComponent as SwitchCheckedIcon } from "icons/remix/toggle-line.svg"; // Closest match for switch checked
+export { ReactComponent as SwitchCheckedIcon } from "./remix/toggle-line.svg"; // Closest match for switch checked
 export { ReactComponent as TextEditIcon } from "./icon-text-edit.svg";
 export { ReactComponent as TextboxIcon } from "./icon-textbox.svg";
-export { ReactComponent as TriangleIcon } from "icons/remix/arrow-up-line.svg"; // Closest match for triangle
-export { ReactComponent as TypographyIcon } from "icons/remix/file-text-line.svg"; // Closest match for typography
+export { ReactComponent as TriangleIcon } from "./remix/arrow-up-line.svg"; // Closest match for triangle
+export { ReactComponent as TypographyIcon } from "./remix/file-text-line.svg"; // Closest match for typography
 export { ReactComponent as UnfoldWhiteIcon } from "./icon-unfold-white.svg";
 export { ReactComponent as UnfoldIcon } from "./icon-unfold.svg";
 export { ReactComponent as WarningWhiteIcon } from "./icon-warning-white.svg";
-export { ReactComponent as WarningIcon } from "icons/remix/error-warning-line.svg"; // Closest match for warning
+export { ReactComponent as WarningIcon } from "./remix/error-warning-line.svg"; // Closest match for warning
 export { ReactComponent as WidthDragIcon } from "./icon-widthDrag.svg";
-export { ReactComponent as ManyCheckboxIcon } from "icons/remix/checkbox-multiple-line.svg"; // Closest match for many checkbox
-export { ReactComponent as Layout } from "icons/remix/layout-2-line.svg"; // Closest match for layout
-export { ReactComponent as Left } from "icons/remix/arrow-left-s-line.svg"; // Closest match for left
-export { ReactComponent as Middle } from "icons/remix/align-vertically.svg"; // Closest match for middle
-export { ReactComponent as Right } from "icons/remix/arrow-right-s-line.svg"; // Closest match for right
+export { ReactComponent as ManyCheckboxIcon } from "./remix/checkbox-multiple-line.svg"; // Closest match for many checkbox
+export { ReactComponent as Layout } from "./remix/layout-2-line.svg"; // Closest match for layout
+export { ReactComponent as Left } from "./remix/arrow-left-s-line.svg"; // Closest match for left
+export { ReactComponent as Middle } from "./remix/align-vertically.svg"; // Closest match for middle
+export { ReactComponent as Right } from "./remix/arrow-right-s-line.svg"; // Closest match for right
 export { ReactComponent as DeployIcon } from "./icon-rocket.svg";
-export { ReactComponent as ExportIcon } from "icons/remix/share-forward-line.svg"; // Closest match for export
+export { ReactComponent as ExportIcon } from "./remix/share-forward-line.svg"; // Closest match for export
 export { ReactComponent as BluePlusIcon } from "./icon-blue-add.svg";
-export { ReactComponent as PencilIcon } from "icons/remix/pencil-line.svg"; // Closest match for pencil
-export { ReactComponent as DragIcon } from "icons/remix/drag-move-2-line.svg"; // Closest match for drag
+export { ReactComponent as PencilIcon } from "./remix/pencil-line.svg"; // Closest match for pencil
+export { ReactComponent as DragIcon } from "./remix/drag-move-2-line.svg"; // Closest match for drag
 export { ReactComponent as PointIcon } from "./icon-three-point.svg";
-export { ReactComponent as AlignJustify } from "icons/remix/align-justify.svg"; // Exact match
-export { ReactComponent as AlignRight } from "icons/remix/align-right.svg"; // Exact match
-export { ReactComponent as AlignCenter } from "icons/remix/align-center.svg"; // Exact match
-export { ReactComponent as AlignLeft } from "icons/remix/align-left.svg"; // Exact match
+export { ReactComponent as AlignJustify } from "./remix/align-justify.svg"; // Exact match
+export { ReactComponent as AlignRight } from "./remix/align-right.svg"; // Exact match
+export { ReactComponent as AlignCenter } from "./remix/align-center.svg"; // Exact match
+export { ReactComponent as AlignLeft } from "./remix/align-left.svg"; // Exact match
 export { ReactComponent as AlignClose } from "./icon-align-close.svg";
 export { ReactComponent as AlignTop } from "./icon-align-top.svg";
 export { ReactComponent as AlignBottom } from "./icon-align-bottom.svg";
-export { ReactComponent as AddIcon } from "icons/remix/add-line.svg"; // Closest match for add
+export { ReactComponent as AddIcon } from "./remix/add-line.svg"; // Closest match for add
 export { ReactComponent as ApplicationDocIcon } from "./icon-application-doc.svg";
-export { ReactComponent as ImportAppIcon } from "icons/remix/download-cloud-line.svg"; // Closest match for import app
+export { ReactComponent as ImportAppIcon } from "./remix/download-cloud-line.svg"; // Closest match for import app
 export { ReactComponent as ModuleDocIcon } from "./icon-module-doc.svg";
-export { ReactComponent as ImportIcon } from "icons/remix/download-cloud-line.svg"; // Closest match for import
-export { ReactComponent as ImportIconV2 } from "icons/remix/download-cloud-line.svg"; // Closest match for import v2
+export { ReactComponent as ImportIcon } from "./remix/download-cloud-line.svg"; // Closest match for import
+export { ReactComponent as ImportIconV2 } from "./remix/download-cloud-line.svg"; // Closest match for import v2
 export { ReactComponent as ModuleMenuIcon } from "./icon-module-menu.svg";
-export { ReactComponent as ModuleIcon } from "icons/remix/stack-line.svg"; // Closest match for module
+export { ReactComponent as ModuleIcon } from "./remix/stack-line.svg"; // Closest match for module
 export { ReactComponent as AllAppIcon } from "./icon-all-app.svg";
 export { ReactComponent as DatasourceIcon } from "./icon-datasource.svg";
 export { ReactComponent as QueryLibraryIcon } from "./icon-query-library.svg";
@@ -405,82 +410,82 @@ export { ReactComponent as TransformerIcon } from "./icon-transformer.svg"; // O
 export { ReactComponent as TempStateIcon } from "./icon-temp-state.svg";
 export { ReactComponent as IconDep } from "./icon-style-dep.svg";
 export { ReactComponent as IconRadius } from "./icon-style-border-radius.svg";
-export { ReactComponent as IconReset } from "icons/remix/refresh-line.svg";
+export { ReactComponent as IconReset } from "./remix/refresh-line.svg";
 export { ReactComponent as NavComIcon } from "./icon-nav.svg";
 export { ReactComponent as ButtonCompIcon } from "./icon-button.svg";
-export { ReactComponent as InputCompIcon } from "icons/remix/input-method-line.svg"; // Closest match for input component
-export { ReactComponent as TextCompIcon } from "icons/remix/file-text-line.svg"; // Closest match for text component
-export { ReactComponent as SwitchCompIcon } from "icons/remix/switch-line.svg"; // Closest match for switch component
-export { ReactComponent as TableCompIcon } from "icons/remix/table-line.svg"; // Closest match for table component
-export { ReactComponent as SelectCompIcon } from "icons/remix/dropdown-list.svg"; // Closest match for select component
-export { ReactComponent as CheckboxCompIcon } from "icons/remix/checkbox-line.svg"; // Closest match for checkbox component
-export { ReactComponent as RadioCompIcon } from "icons/remix/radio-line.svg"; // Closest match for radio component
-export { ReactComponent as TimeCompIcon } from "icons/remix/time-line.svg"; // Closest match for time component
+export { ReactComponent as InputCompIcon } from "./remix/input-method-line.svg"; // Closest match for input component
+export { ReactComponent as TextCompIcon } from "./remix/file-text-line.svg"; // Closest match for text component
+export { ReactComponent as SwitchCompIcon } from "./remix/switch-line.svg"; // Closest match for switch component
+export { ReactComponent as TableCompIcon } from "./remix/table-line.svg"; // Closest match for table component
+export { ReactComponent as SelectCompIcon } from "./remix/dropdown-list.svg"; // Closest match for select component
+export { ReactComponent as CheckboxCompIcon } from "./remix/checkbox-line.svg"; // Closest match for checkbox component
+export { ReactComponent as RadioCompIcon } from "./remix/radio-line.svg"; // Closest match for radio component
+export { ReactComponent as TimeCompIcon } from "./remix/time-line.svg"; // Closest match for time component
 export { ReactComponent as TimeRangeCompIcon } from "./icon-timeRange.svg";
-export { ReactComponent as DateCompIcon } from "icons/remix/calendar-2-line.svg"; // Closest match for date component
+export { ReactComponent as DateCompIcon } from "./remix/calendar-2-line.svg"; // Closest match for date component
 export { ReactComponent as DateRangeCompIcon } from "./icon-dateRange.svg";
-export { ReactComponent as UploadCompIcon } from "icons/remix/upload-cloud-2-line.svg"; // Closest match for upload component
-export { ReactComponent as ImageCompIcon } from "icons/remix/image-line.svg"; // Closest match for image component
-export { ReactComponent as RatingCompIcon } from "icons/remix/star-line.svg"; // Closest match for rating component
-export { ReactComponent as SliderCompIcon } from "icons/remix/git-commit-line.svg"; // Closest match for slider component
+export { ReactComponent as UploadCompIcon } from "./remix/upload-cloud-2-line.svg"; // Closest match for upload component
+export { ReactComponent as ImageCompIcon } from "./remix/image-line.svg"; // Closest match for image component
+export { ReactComponent as RatingCompIcon } from "./remix/star-line.svg"; // Closest match for rating component
+export { ReactComponent as SliderCompIcon } from "./remix/git-commit-line.svg"; // Closest match for slider component
 export { ReactComponent as ProcessCircleCompIcon } from "./icon-sliderCircle.svg";
-export { ReactComponent as ChartCompIcon } from "icons/remix/pie-chart-2-line.svg"; // Closest match for chart component
+export { ReactComponent as ChartCompIcon } from "./remix/pie-chart-2-line.svg"; // Closest match for chart component
 export { ReactComponent as JsonFormCompIcon } from "./icon-jsonForm.svg";
-export { ReactComponent as FormCompIcon } from "icons/remix/draft-line.svg"; // Closest match for form component
+export { ReactComponent as FormCompIcon } from "./remix/draft-line.svg"; // Closest match for form component
 export { ReactComponent as ProgressCompIcon } from "./icon-progress.svg";
 export { ReactComponent as FileViewerCompIcon } from "./icon-fileViewer.svg";
 export { ReactComponent as ContainerCompIcon } from "./icon-container.svg";
-export { ReactComponent as LinkCompIcon } from "icons/remix/links-line.svg"; // Closest match for link component
-export { ReactComponent as MultiSelectCompIcon } from "icons/remix/list-check-3.svg"; // Closest match for multiselect component
-export { ReactComponent as PasswordCompIcon } from "icons/remix/key-2-line.svg"; // Closest match for password component
-export { ReactComponent as RangeSliderCompIcon } from "icons/remix/switch-line.svg"; // Closest match for range slider component
+export { ReactComponent as LinkCompIcon } from "./remix/links-line.svg"; // Closest match for link component
+export { ReactComponent as MultiSelectCompIcon } from "./remix/list-check-3.svg"; // Closest match for multiselect component
+export { ReactComponent as PasswordCompIcon } from "./remix/key-2-line.svg"; // Closest match for password component
+export { ReactComponent as RangeSliderCompIcon } from "./remix/switch-line.svg"; // Closest match for range slider component
 export { ReactComponent as SegmentedCompIcon } from "./icon-insert-segmentedControl.svg";
-export { ReactComponent as TextAreaCompIcon } from "icons/remix/text-block.svg"; // Closest match for textarea component
+export { ReactComponent as TextAreaCompIcon } from "./remix/text-block.svg"; // Closest match for textarea component
 export { ReactComponent as NumberInputCompIcon } from "./icon-insert-numberInput.svg";
-export { ReactComponent as DropdownCompIcon } from "icons/remix/dropdown-list.svg"; // Closest match for dropdown component
+export { ReactComponent as DropdownCompIcon } from "./remix/dropdown-list.svg"; // Closest match for dropdown component
 export { ReactComponent as DividerCompIcon } from "./icon-insert-divider.svg";
 export { ReactComponent as RichTextEditorCompIcon } from "./icon-insert-rich-text-editor.svg";
-export { ReactComponent as ModalCompIcon } from "icons/remix/window-line.svg"; // Closest match for modal component
-export { ReactComponent as TabbedContainerCompIcon } from "icons/remix/layout-column-line.svg"; // Closest match for tabbed container
+export { ReactComponent as ModalCompIcon } from "./remix/window-line.svg"; // Closest match for modal component
+export { ReactComponent as TabbedContainerCompIcon } from "./remix/layout-column-line.svg"; // Closest match for tabbed container
 export { ReactComponent as CascaderCompIcon } from "./icon-cascader.svg";
-export { ReactComponent as TreeIcon } from "icons/remix/node-tree.svg"; // Closest match for tree icon
+export { ReactComponent as TreeIcon } from "./remix/node-tree.svg"; // Closest match for tree icon
 export { ReactComponent as TreeSelectIcon } from "./icon-tree-select.svg";
 export { ReactComponent as CustomCompIcon } from "./icon-custom-component.svg";
-export { ReactComponent as IFrameCompIcon } from "icons/remix/window-2-line.svg"; // Closest match for iframe component
+export { ReactComponent as IFrameCompIcon } from "./remix/window-2-line.svg"; // Closest match for iframe component
 export { ReactComponent as ListViewIcon } from "./icon-insert-listView.svg";
-export { ReactComponent as GridCompIcon } from "icons/remix/grid-line.svg"; // Closest match for grid component
+export { ReactComponent as GridCompIcon } from "./remix/grid-line.svg"; // Closest match for grid component
 export { ReactComponent as PackUpIcon } from "./icon-Pack-up.svg";
-export { ReactComponent as SearchIcon } from "icons/remix/search-line.svg"; // Closest match for search icon
-export { ReactComponent as SearchOutlinedIcon } from "icons/remix/search-eye-line.svg"; // Closest match for search outlined icon
-export { ReactComponent as FilterIcon } from "icons/remix/filter-line.svg"; // Closest match for filter icon
-export { ReactComponent as DownloadIcon } from "icons/remix/download-line.svg"; // Closest match for download icon
-export { ReactComponent as DownloadBoldIcon } from "icons/remix/download-2-line.svg"; // Closest match for download bold icon
+export { ReactComponent as SearchIcon } from "./remix/search-line.svg"; // Closest match for search icon
+export { ReactComponent as SearchOutlinedIcon } from "./remix/search-eye-line.svg"; // Closest match for search outlined icon
+export { ReactComponent as FilterIcon } from "./remix/filter-line.svg"; // Closest match for filter icon
+export { ReactComponent as DownloadIcon } from "./remix/download-line.svg"; // Closest match for download icon
+export { ReactComponent as DownloadBoldIcon } from "./remix/download-2-line.svg"; // Closest match for download bold icon
 export { ReactComponent as DownloadedIcon } from "./icon-downloaded.svg";
-export { ReactComponent as SettingIcon } from "icons/remix/settings-line.svg"; // Closest match for setting icon
-export { ReactComponent as RefreshIcon } from "icons/remix/refresh-line.svg"; // Closest match for refresh icon
-export { ReactComponent as DeleteIcon } from "icons/remix/delete-bin-6-line.svg"; // Closest match for delete icon
+export { ReactComponent as SettingIcon } from "./remix/settings-line.svg"; // Closest match for setting icon
+export { ReactComponent as RefreshIcon } from "./remix/refresh-line.svg"; // Closest match for refresh icon
+export { ReactComponent as DeleteIcon } from "./remix/delete-bin-6-line.svg"; // Closest match for delete icon
 export { ReactComponent as DeleteInputIcon } from "./icon-deleteinput.svg";
 export { ReactComponent as UpgradeIcon } from "./icon-upgrade.svg";
-export { ReactComponent as QuestionIcon } from "icons/remix/question-line.svg"; // Closest match for question icon
-export { ReactComponent as CloseIcon } from "icons/remix/close-line.svg"; // Closest match for close icon
-export { ReactComponent as SuccessIcon } from "icons/remix/check-double-line.svg"; // Closest match for success icon
-export { ReactComponent as ErrorIcon } from "icons/remix/error-warning-line.svg"; // Closest match for error icon
-export { ReactComponent as DocIcon } from "icons/remix/file-text-line.svg"; // Closest match for document icon
+export { ReactComponent as QuestionIcon } from "./remix/question-line.svg"; // Closest match for question icon
+export { ReactComponent as CloseIcon } from "./remix/close-line.svg"; // Closest match for close icon
+export { ReactComponent as SuccessIcon } from "./remix/check-double-line.svg"; // Closest match for success icon
+export { ReactComponent as ErrorIcon } from "./remix/error-warning-line.svg"; // Closest match for error icon
+export { ReactComponent as DocIcon } from "./remix/file-text-line.svg"; // Closest match for document icon
 export { ReactComponent as DocBoldIcon } from "./icon-tutorial-bold.svg";
-export { ReactComponent as QRCodeCompIcon } from "icons/remix/qr-code-line.svg"; // Closest match for QR code component
+export { ReactComponent as QRCodeCompIcon } from "./remix/qr-code-line.svg"; // Closest match for QR code component
 export { ReactComponent as NavDocIcon } from "./icon-nav-doc.svg";
 export { ReactComponent as LabIcon } from "./icon-laboratory.svg";
 export { ReactComponent as JsonExplorerCompIcon } from "./icon-json-explorer.svg";
 export { ReactComponent as JsonEditorCompIcon } from "./icon-json-editor.svg";
-export { ReactComponent as ArrowIcon } from "icons/remix/arrow-right-s-line.svg"; // Closest generic match for arrow icon
-export { ReactComponent as ArrowSolidIcon } from "icons/remix/arrow-right-line.svg"; // Closest match for solid arrow icon
-export { ReactComponent as AudioCompIcon } from "icons/remix/speaker-3-line.svg"; // Closest match for audio component
-export { ReactComponent as VideoCompIcon } from "icons/remix/video-line.svg"; // Closest match for video component
+export { ReactComponent as ArrowIcon } from "./remix/arrow-right-s-line.svg"; // Closest generic match for arrow icon
+export { ReactComponent as ArrowSolidIcon } from "./remix/arrow-right-line.svg"; // Closest match for solid arrow icon
+export { ReactComponent as AudioCompIcon } from "./remix/speaker-3-line.svg"; // Closest match for audio component
+export { ReactComponent as VideoCompIcon } from "./remix/video-line.svg"; // Closest match for video component
 export { ReactComponent as videoPlayTriangle } from "./icon-video-play-triangle.svg";
-export { ReactComponent as DrawerCompIcon } from "icons/remix/sidebar-unfold-line.svg"; // Closest match for drawer component
-export { ReactComponent as LeftMeetingIcon } from "icons/remix/team-line.svg"; // Closest match for left meeting icon
-export { ReactComponent as PlusIcon } from "icons/remix/add-line.svg"; // Closest match for plus icon
-export { ReactComponent as HomeIcon } from "icons/remix/home-2-line.svg"; // Closest match for home icon
+export { ReactComponent as DrawerCompIcon } from "./remix/sidebar-unfold-line.svg"; // Closest match for drawer component
+export { ReactComponent as LeftMeetingIcon } from "./remix/team-line.svg"; // Closest match for left meeting icon
+export { ReactComponent as PlusIcon } from "./remix/add-line.svg"; // Closest match for plus icon
+export { ReactComponent as HomeIcon } from "./remix/home-2-line.svg"; // Closest match for home icon
 export { ReactComponent as HomeModuleIcon } from "./icon-application-module.svg";
 export { ReactComponent as HomeQueryLibraryIcon } from "./icon-application-query-library.svg";
 export { ReactComponent as HomeDataSourceIcon } from "./icon-application-datasource.svg";
@@ -491,8 +496,8 @@ export { ReactComponent as HomeQueryLibraryActiveIcon } from "./icon-application
 export { ReactComponent as HomeDataSourceActiveIcon } from "./icon-application-datasource-active.svg";
 export { ReactComponent as RecyclerActiveIcon } from "./icon-application-recycler-active.svg";
 export { ReactComponent as FavoritesIcon } from "./icon-application-favorites.svg";
-export { ReactComponent as HomeSettingIcon } from "icons/remix/settings-5-line.svg"; // Closest match for home setting icon
-export { ReactComponent as FolderIcon } from "icons/remix/folder-4-line.svg"; // Closest match for folder icon
+export { ReactComponent as HomeSettingIcon } from "./remix/settings-5-line.svg"; // Closest match for home setting icon
+export { ReactComponent as FolderIcon } from "./remix/folder-4-line.svg"; // Closest match for folder icon
 export { ReactComponent as AllTypesIcon } from "./icon-application-all.svg";
 export { ReactComponent as InviteUserIcon } from "./icon-application-invite-user.svg";
 export { ReactComponent as HomeEmptyIcon } from "./icon-application-empty.svg";
@@ -520,15 +525,15 @@ export { ReactComponent as MSSQLIcon } from "./icon-query-mssql.svg";
 export { ReactComponent as SMTPIcon } from "./icon-query-SMTP.svg";
 export { ReactComponent as OracleIcon } from "./icon-query-OracleDB.svg";
 export { ReactComponent as ClickHouseIcon } from "./icon-query-ClickHouse.svg";
-export { ReactComponent as ResetIcon } from "icons/remix/refresh-line.svg"; // Closest match for reset icon
-export { ReactComponent as EditIcon } from "icons/remix/edit-2-line.svg"; // Closest match for edit icon
+export { ReactComponent as ResetIcon } from "./remix/refresh-line.svg"; // Closest match for reset icon
+export { ReactComponent as EditIcon } from "./remix/edit-2-line.svg"; // Closest match for edit icon
 export { ReactComponent as EditableIcon } from "./icon-editable.svg";
 export { ReactComponent as LeftStateIcon } from "./icon-left-state.svg";
 export { ReactComponent as LeftSettingIcon } from "./icon-left-setting.svg";
 export { ReactComponent as LeftHelpIcon } from "./icon-left-help.svg";
 export { ReactComponent as LeftPreloadIcon } from "./icon-left-preload.svg";
 export { ReactComponent as CollapsibleContainerCompIcon } from "./icon-collapsible-container.svg";
-export { ReactComponent as ToggleButtonCompIcon } from "icons/remix/switch-line.svg"; // Closest match for toggle button component
+export { ReactComponent as ToggleButtonCompIcon } from "./remix/switch-line.svg"; // Closest match for toggle button component
 export { ReactComponent as GoogleSheetsIcon } from "./icon-query-GoogleSheets.svg";
 export { ReactComponent as GraphqlIcon } from "./icon-query-Graphql.svg";
 export { ReactComponent as SnowflakeIcon } from "./icon-query-snowflake.svg";
@@ -540,71 +545,71 @@ export { ReactComponent as HomeSettingsActiveIcon } from "./icon-home-settings-a
 export { ReactComponent as HelpGithubIcon } from "./icon-help-github.svg";
 export { ReactComponent as HelpDiscordIcon } from "./icon-help-discord.svg";
 export { ReactComponent as LeftAudio } from "./icon-left-comp-audio.svg";
-export { ReactComponent as LeftButton } from "icons/remix/rectangle-line.svg"; // Closest match for left button
-export { ReactComponent as LeftChart } from "icons/remix/bar-chart-2-line.svg"; // Closest match for left chart
-export { ReactComponent as LeftCheckbox } from "icons/remix/checkbox-line.svg"; // Closest match for left checkbox
+export { ReactComponent as LeftButton } from "./remix/rectangle-line.svg"; // Closest match for left button
+export { ReactComponent as LeftChart } from "./remix/bar-chart-2-line.svg"; // Closest match for left chart
+export { ReactComponent as LeftCheckbox } from "./remix/checkbox-line.svg"; // Closest match for left checkbox
 export { ReactComponent as LeftCommon } from "./icon-left-comp-common.svg";
 export { ReactComponent as LeftContainer } from "./icon-left-comp-container.svg";
-export { ReactComponent as LeftDate } from "icons/remix/calendar-2-line.svg"; // Closest match for left date
+export { ReactComponent as LeftDate } from "./remix/calendar-2-line.svg"; // Closest match for left date
 export { ReactComponent as LeftDivider } from "./icon-left-comp-divider.svg";
-export { ReactComponent as LeftDrawer } from "icons/remix/sidebar-unfold-line.svg"; // Closest match for drawer component
-export { ReactComponent as LeftMeeting } from "icons/remix/team-line.svg"; // Closest match for left meeting icon
-export { ReactComponent as LeftFile } from "icons/remix/file-line.svg"; // Closest match for left file
+export { ReactComponent as LeftDrawer } from "./remix/sidebar-unfold-line.svg"; // Closest match for drawer component
+export { ReactComponent as LeftMeeting } from "./remix/team-line.svg"; // Closest match for left meeting icon
+export { ReactComponent as LeftFile } from "./remix/file-line.svg"; // Closest match for left file
 export { ReactComponent as LeftFileViewer } from "./icon-left-comp-fileViewer.svg";
-export { ReactComponent as LeftForm } from "icons/remix/draft-line.svg"; // Closest match for left form
-export { ReactComponent as LeftIframe } from "icons/remix/window-2-line.svg"; // Closest match for left iframe
-export { ReactComponent as LeftImage } from "icons/remix/image-line.svg"; // Closest match for left image
-export { ReactComponent as LeftInput } from "icons/remix/input-method-line.svg"; // Closest match for left input
+export { ReactComponent as LeftForm } from "./remix/draft-line.svg"; // Closest match for left form
+export { ReactComponent as LeftIframe } from "./remix/window-2-line.svg"; // Closest match for left iframe
+export { ReactComponent as LeftImage } from "./remix/image-line.svg"; // Closest match for left image
+export { ReactComponent as LeftInput } from "./remix/input-method-line.svg"; // Closest match for left input
 export { ReactComponent as LeftJsonEditor } from "./icon-left-comp-jsonEditor.svg";
-export { ReactComponent as LeftLink } from "icons/remix/links-line.svg"; // Closest match for left link
+export { ReactComponent as LeftLink } from "./remix/links-line.svg"; // Closest match for left link
 export { ReactComponent as LeftListView } from "./icon-left-comp-listView.svg";
-export { ReactComponent as LeftModal } from "icons/remix/shadow-line.svg"; // Closest match for left modal
-export { ReactComponent as LeftNavigation } from "icons/remix/compass-line.svg"; // Closest match for left navigation
+export { ReactComponent as LeftModal } from "./remix/shadow-line.svg"; // Closest match for left modal
+export { ReactComponent as LeftNavigation } from "./remix/compass-line.svg"; // Closest match for left navigation
 export { ReactComponent as LeftNumberInput } from "./icon-insert-numberInput.svg";
-export { ReactComponent as LeftPassword } from "icons/remix/key-2-line.svg"; // Closest match for left password
+export { ReactComponent as LeftPassword } from "./remix/key-2-line.svg"; // Closest match for left password
 export { ReactComponent as LeftProgress } from "./icon-progress.svg";
-export { ReactComponent as LeftQrCode } from "icons/remix/qr-code-line.svg"; // Closest match for left QR code
-export { ReactComponent as LeftRadio } from "icons/remix/radio-line.svg"; // Closest match for left radio
-export { ReactComponent as LeftRating } from "icons/remix/star-line.svg"; // Closest match for left rating
+export { ReactComponent as LeftQrCode } from "./remix/qr-code-line.svg"; // Closest match for left QR code
+export { ReactComponent as LeftRadio } from "./remix/radio-line.svg"; // Closest match for left radio
+export { ReactComponent as LeftRating } from "./remix/star-line.svg"; // Closest match for left rating
 export { ReactComponent as LeftSegmentedControl } from "./icon-left-comp-segmentedControl.svg";
-export { ReactComponent as LeftSelect } from "icons/remix/dropdown-list.svg"; // Closest match for left select
-export { ReactComponent as LeftSlider } from "icons/remix/git-commit-line.svg"; // Closest match for left slider
-export { ReactComponent as LeftSwitch } from "icons/remix/switch-line.svg"; // Closest match for left switch
-export { ReactComponent as LeftTable } from "icons/remix/table-line.svg"; // Closest match for left table
-export { ReactComponent as LeftText } from "icons/remix/file-text-line.svg"; // Closest match for left text
-export { ReactComponent as LeftTime } from "icons/remix/time-line.svg"; // Closest match for left time
-export { ReactComponent as LeftTree } from "icons/remix/node-tree.svg"; // Closest match for left tree
-export { ReactComponent as LeftVideo } from "icons/remix/video-line.svg"; // Closest match for left video
-export { ReactComponent as LeftOpen } from "icons/remix/door-open-line.svg"; // Closest match for left open
-export { ReactComponent as LeftClose } from "icons/remix/door-closed-line.svg"; // Closest match for left close
-export { ReactComponent as ScannerIcon } from "icons/remix/scan-line.svg"; // Closest match for scanner icon
+export { ReactComponent as LeftSelect } from "./remix/dropdown-list.svg"; // Closest match for left select
+export { ReactComponent as LeftSlider } from "./remix/git-commit-line.svg"; // Closest match for left slider
+export { ReactComponent as LeftSwitch } from "./remix/switch-line.svg"; // Closest match for left switch
+export { ReactComponent as LeftTable } from "./remix/table-line.svg"; // Closest match for left table
+export { ReactComponent as LeftText } from "./remix/file-text-line.svg"; // Closest match for left text
+export { ReactComponent as LeftTime } from "./remix/time-line.svg"; // Closest match for left time
+export { ReactComponent as LeftTree } from "./remix/node-tree.svg"; // Closest match for left tree
+export { ReactComponent as LeftVideo } from "./remix/video-line.svg"; // Closest match for left video
+export { ReactComponent as LeftOpen } from "./remix/door-open-line.svg"; // Closest match for left open
+export { ReactComponent as LeftClose } from "./remix/door-closed-line.svg"; // Closest match for left close
+export { ReactComponent as ScannerIcon } from "./remix/scan-line.svg"; // Closest match for scanner icon
 export { ReactComponent as MaterialUploadIcon } from "./icon-material-upload.svg";
-export { ReactComponent as CalendarCompIcon } from "icons/remix/calendar-2-line.svg"; // Closest match for calendar component
+export { ReactComponent as CalendarCompIcon } from "./remix/calendar-2-line.svg"; // Closest match for calendar component
 export { ReactComponent as LeftSignature } from "./icon-left-signature.svg";
-export { ReactComponent as UndoIcon } from "icons/remix/arrow-go-back-line.svg"; // Closest match for undo icon
-export { ReactComponent as SignatureIcon } from "icons/remix/pen-nib-line.svg"; // Closest match for signature icon
+export { ReactComponent as UndoIcon } from "./remix/arrow-go-back-line.svg"; // Closest match for undo icon
+export { ReactComponent as SignatureIcon } from "./remix/pen-nib-line.svg"; // Closest match for signature icon
 export { ReactComponent as ManualIcon } from "./icon-manual.svg";
-export { ReactComponent as WarnIcon } from "icons/remix/alert-line.svg"; // Closest match for warn icon
+export { ReactComponent as WarnIcon } from "./remix/alert-line.svg"; // Closest match for warn icon
 export { ReactComponent as SyncManualIcon } from "./icon-sync-manual.svg";
-export { ReactComponent as DangerIcon } from "icons/remix/error-warning-line.svg"; // Closest match for danger icon
-export { ReactComponent as TableMinusIcon } from "icons/remix/checkbox-indeterminate-line.svg"; // Closest match for table minus icon
-export { ReactComponent as TablePlusIcon } from "icons/remix/add-box-line.svg"; // Closest match for table plus icon
-export { ReactComponent as MobileAppIcon } from "icons/remix/smartphone-line.svg"; // Closest match for mobile app icon
-export { ReactComponent as MobileNavIcon } from "icons/remix/navigation-line.svg"; // Closest match for mobile navigation icon
-export { ReactComponent as PcNavIcon } from "icons/remix/computer-line.svg"; // Closest match for PC navigation icon
-export { ReactComponent as UnLockIcon } from "icons/remix/lock-unlock-line.svg"; // Closest match for unlock icon
-export { ReactComponent as CalendarDeleteIcon } from "icons/remix/calendar-2-line.svg"; // Closest match for calendar delete icon
-export { ReactComponent as TableCheckedIcon } from "icons/remix/checkbox-circle-line.svg"; // Closest match for table checked icon
-export { ReactComponent as TableUnCheckedIcon } from "icons/remix/checkbox-blank-circle-line.svg"; // Closest match for table unchecked icon
-export { ReactComponent as FileFolderIcon } from "icons/remix/folder-2-line.svg"; // Closest match for file folder icon
-export { ReactComponent as ExpandIcon } from "icons/remix/menu-unfold-line.svg"; // Closest match for expand icon
-export { ReactComponent as CompressIcon } from "icons/remix/menu-fold-line.svg"; // Closest match for compress icon
-export { ReactComponent as TableCellsIcon } from "icons/remix/grid-line.svg"; // Closest match for table cells icon
-export { ReactComponent as TimeLineIcon } from "icons/remix/time-line.svg"; // Closest match for timeline icon
+export { ReactComponent as DangerIcon } from "./remix/error-warning-line.svg"; // Closest match for danger icon
+export { ReactComponent as TableMinusIcon } from "./remix/checkbox-indeterminate-line.svg"; // Closest match for table minus icon
+export { ReactComponent as TablePlusIcon } from "./remix/add-box-line.svg"; // Closest match for table plus icon
+export { ReactComponent as MobileAppIcon } from "./remix/smartphone-line.svg"; // Closest match for mobile app icon
+export { ReactComponent as MobileNavIcon } from "./remix/navigation-line.svg"; // Closest match for mobile navigation icon
+export { ReactComponent as PcNavIcon } from "./remix/computer-line.svg"; // Closest match for PC navigation icon
+export { ReactComponent as UnLockIcon } from "./remix/lock-unlock-line.svg"; // Closest match for unlock icon
+export { ReactComponent as CalendarDeleteIcon } from "./remix/calendar-2-line.svg"; // Closest match for calendar delete icon
+export { ReactComponent as TableCheckedIcon } from "./remix/checkbox-circle-line.svg"; // Closest match for table checked icon
+export { ReactComponent as TableUnCheckedIcon } from "./remix/checkbox-blank-circle-line.svg"; // Closest match for table unchecked icon
+export { ReactComponent as FileFolderIcon } from "./remix/folder-2-line.svg"; // Closest match for file folder icon
+export { ReactComponent as ExpandIcon } from "./remix/menu-unfold-line.svg"; // Closest match for expand icon
+export { ReactComponent as CompressIcon } from "./remix/menu-fold-line.svg"; // Closest match for compress icon
+export { ReactComponent as TableCellsIcon } from "./remix/grid-line.svg"; // Closest match for table cells icon
+export { ReactComponent as TimeLineIcon } from "./remix/time-line.svg"; // Closest match for timeline icon
 export { ReactComponent as LottieIcon } from "./icon-lottie.svg";
 export { ReactComponent as CommentIcon } from "./icon-comment-comp.svg";
 export { ReactComponent as MentionIcon } from "./icon-mention-comp.svg";
 export { ReactComponent as AutoCompleteCompIcon } from "./icon-autocomplete-comp.svg";
 export { ReactComponent as WidthIcon } from "./icon-width.svg";
-export { ReactComponent as ResponsiveLayoutCompIcon } from "icons/remix/layout-column-line.svg"; // Closest match for responsive layout component
+export { ReactComponent as ResponsiveLayoutCompIcon } from "./remix/layout-column-line.svg"; // Closest match for responsive layout component
 export { ReactComponent as TextSizeIcon } from "./icon-text-size.svg"; */
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index b5ec23f09e..cd57c91657 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -104,7 +104,12 @@ export const en = {
     "components": "Active Components",
     "modals": "in-App Modals",
     "expandTip": "Click to Expand {component}'s Data",
-    "collapseTip": "Click to Collapse {component}'s Data"
+    "collapseTip": "Click to Collapse {component}'s Data",
+    "layers": "Layers",
+    "activatelayers": "Use Layers in this App",
+    "selectedComponents": "Selected Components...",
+    "displayComponents": "control Display",
+    "lockComponents": "control Position",
   },
 
   // second part
diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts
index 7ff3d68255..ac6020fd49 100644
--- a/client/packages/lowcoder/src/i18n/locales/zh.ts
+++ b/client/packages/lowcoder/src/i18n/locales/zh.ts
@@ -106,7 +106,10 @@ leftPanel: {
     components: "组件",
     modals: "对话框",
     expandTip: "点击展开 {component} 的数据",
-    collapseTip: "点击折叠 {component} 的数据"
+    collapseTip: "点击折叠 {component} 的数据",
+    layers: "图层",
+    activatelayers: "激活图层",
+    selectedComponents: "已选组件",
 },
 bottomPanel: {
     title: "查询",
diff --git a/client/packages/lowcoder/src/pages/editor/LeftContent.tsx b/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
index faee2cea3f..5924d90bfe 100644
--- a/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
+++ b/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
@@ -6,16 +6,16 @@ import {
   CollapseTitle as Title,
   CopyTextButton,
   FoldedIcon,
+  LeftClose,
   LeftCommon,
-  LeftInfoFill,
-  LeftInfoLine,
+  LeftOpen,
   PadDiv,
   ScrollBar,
   Tooltip,
   UnfoldIcon,
   UnShow,
 } from "lowcoder-design";
-import React, { ReactNode, useCallback, useContext, useMemo, useState, useEffect } from "react";
+import React, { ReactNode, useCallback, useContext, useMemo, useState } from "react";
 import { hookCompCategory } from "comps/hooks/hookCompTypes";
 import _ from "lodash";
 import styled from "styled-components";
@@ -32,11 +32,6 @@ import { UICompType } from "comps/uiCompRegistry";
 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";
-import { Divider } from "antd";
 
 const CollapseTitleWrapper = styled.div`
   display: flex;
@@ -196,8 +191,6 @@ const CollapseView = React.memo(
 
 interface LeftContentProps {
   uiComp: InstanceType<typeof UIComp>;
-  checkable?: boolean;
-  isDraggable?: boolean;
 }
 
 enum LeftTabKey {
@@ -215,8 +208,6 @@ type NodeItem = {
   title: string;
   type?: UICompType;
   children: NodeItem[];
-  pos?: number;
-  disabled?: boolean;
 };
 
 type NodeInfo = {
@@ -251,16 +242,12 @@ 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 checkable = props.checkable || false;
-  const isDraggable = props.isDraggable || false;
 
   const getTree = (tree: CompTree, result: NodeItem[], key?: string) => {
     const { items, children } = tree;
     if (Object.keys(items).length) {
       for (const i in items) {
-        const info: NodeItem = {
+        const info = {
           title: items[i].children.name.getView(),
           type: items[i].children.compType.getView() as UICompType,
           key: i,
@@ -268,13 +255,12 @@ export const LeftContent = (props: LeftContentProps) => {
         };
         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) {
@@ -367,7 +353,7 @@ export const LeftContent = (props: LeftContentProps) => {
                     setShowData(newData);
                   }}
                 >
-                  <LeftInfoLine/>
+                  <LeftOpen />
                 </div>
               </Tooltip>
             ) : (
@@ -400,7 +386,7 @@ export const LeftContent = (props: LeftContentProps) => {
                     setShowData(newData);
                   }}
                 >
-                  <LeftInfoFill />
+                  <LeftClose />
                 </div>
               </Tooltip>
             ))}
@@ -422,57 +408,17 @@ export const LeftContent = (props: LeftContentProps) => {
     );
   };
 
-  const [componentTreeData, setComponentTreeData] = useState<NodeItem[]>([]);
-  const [modalsTreeData, setModalsTreeData] = useState<NodeItem[]>([]);
-
-  useEffect(() => {
-    const compData = getTreeUIData(TreeUIKey.Components);
-    setComponentTreeData(compData);
-  }, [editorState]);
-  
-  useEffect(() => {
-    const modalsData = getTreeUIData(TreeUIKey.Modals);
-    setModalsTreeData(modalsData);
-  }, [editorState]);
-
-  const getTreeUIData = (type: TreeUIKey) => {
-    const tree =
-      type === TreeUIKey.Components
-        ? 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;
-  }
-  
-
   const getTreeUI = (type: TreeUIKey) => {
-    // here the components get sorted by name
-    // TODO: sort by category
-    // TODO: sort by Types etc.
     const uiCompInfos = _.sortBy(editorState.uiCompInfoList(), [(x) => x.name]);
-    /* const tree =
+    const tree =
       type === TreeUIKey.Components
         ? editorState.getUIComp().getTree()
         : editorState.getHooksComp().getUITree();
-    const explorerData: NodeItem[] = getTree(tree, []); */
+    const explorerData: NodeItem[] = getTree(tree, []);
     let selectedKeys = [];
     if (editorState.selectedCompNames.size === 1) {
       const key = Object.keys(editorState.selectedComps())[0];
-      const parentKeys = getParentNodeKeysByKey(type === TreeUIKey.Components ? componentTreeData : modalsTreeData, key);
+      const parentKeys = getParentNodeKeysByKey(explorerData, key);
       if (parentKeys && parentKeys.length) {
         let needSet = false;
         parentKeys.forEach((key) => {
@@ -486,22 +432,22 @@ export const LeftContent = (props: LeftContentProps) => {
     }
 
     return (
-      <><DirectoryTreeStyle
-        treeData={type === TreeUIKey.Components ? componentTreeData : modalsTreeData}
-        icon={(props: any) => props.type && (
-          <div style={{ margin: '3px 0 0 -3px'}}> {/* Adjust the margin as needed */}
-            {CompStateIcon[props.type as UICompType] || <LeftCommon />}
-          </div>
-        )}
-        switcherIcon={(props: any) => props.expanded ? <FoldedIcon /> : <UnfoldIcon />}
+      <DirectoryTreeStyle
+        treeData={explorerData}
+        // icon={(props: NodeItem) => props.type && (CompStateIcon[props.type] || <LeftCommon />)}
+        icon={(props: any) => props.type && (CompStateIcon[props.type as UICompType] || <LeftCommon />)}
+        // switcherIcon={({ expanded }: { expanded: boolean }) =>
+        //   expanded ? <FoldedIcon /> : <UnfoldIcon />
+        // }
+        switcherIcon={(props: any) =>
+          props.expanded ? <FoldedIcon /> : <UnfoldIcon />
+        }
         expandedKeys={expandedKeys}
         onExpand={(keys) => setExpandedKeys(keys)}
         onClick={(e, node) => handleNodeClick(e, node, uiCompInfos)}
         selectedKeys={selectedKeys}
-        titleRender={(nodeData) => getTreeNode(nodeData as NodeItem, uiCompInfos)} />
-        <Divider />
-        <div></div>
-        </>
+        titleRender={(nodeData) => getTreeNode(nodeData as NodeItem, uiCompInfos)}
+      />
     );
   };
 
@@ -509,15 +455,15 @@ export const LeftContent = (props: LeftContentProps) => {
     if (isAggregationApp(editorState.getAppType())) {
       return;
     }
-    return getTreeUI(TreeUIKey.Components); // Pass componentTreeData
-  }, [editorState, uiCollapseClick, expandedKeys, showData, componentTreeData]);
-  
+    return getTreeUI(TreeUIKey.Components);
+  }, [editorState, uiCollapseClick, expandedKeys, showData]);
+
   const modalsCollapse = useMemo(() => {
     if (isAggregationApp(editorState.getAppType())) {
       return;
     }
-    return getTreeUI(TreeUIKey.Modals); // Pass modalsTreeData
-  }, [editorState, uiCollapseClick, expandedKeys, showData, modalsTreeData]);
+    return getTreeUI(TreeUIKey.Modals);
+  }, [editorState, uiCollapseClick, expandedKeys, showData]);
 
   const bottomResCollapse = useMemo(() => {
     return editorState
@@ -551,7 +497,6 @@ export const LeftContent = (props: LeftContentProps) => {
   }, [editorState]);
 
   const moduleLayoutComp = uiComp.getModuleLayoutComp();
-
   const stateContent = (
     <ScrollBar>
       <div style={{ paddingBottom: 80 }}>
@@ -604,4 +549,4 @@ export const LeftContent = (props: LeftContentProps) => {
       </LeftContentTabs>
     </LeftContentWrapper>
   );
-};
\ No newline at end of file
+};
diff --git a/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx b/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
index bba1dfbd3d..9529758ddc 100644
--- a/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
+++ b/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
@@ -4,55 +4,57 @@ import {
   Collapse,
   CollapseLabel as Label,
   CollapseTitle as Title,
-  CopyTextButton,
   FoldedIcon,
   LeftCommon,
-  LeftInfoFill,
-  LeftInfoLine,
-  PadDiv,
   ScrollBar,
   Tooltip,
   UnfoldIcon,
-  UnShow,
+  LeftLayersIcon,
+  GridIcon,
+  LeftShow,
+  LeftHide,
+  LeftLock,
+  LeftUnlock,
 } from "lowcoder-design";
 import React, { ReactNode, useCallback, useContext, useMemo, useState, useEffect } from "react";
-import { hookCompCategory } from "comps/hooks/hookCompTypes";
-import _ from "lodash";
+import _, { get } from "lodash";
 import styled from "styled-components";
 import { leftCompListClassName } from "pages/tutorials/tutorialsConstant";
 import UIComp from "comps/comps/uiComp";
-import { BottomResTypeEnum } from "types/bottomRes";
 import { getParentNodeKeysByKey, getTreeNodeByKey, safeJSONStringify } from "util/objectUtils";
-import { Tabs, TabTitle } from "components/Tabs";
 import { BackgroundColor, TopHeaderHeight } from "constants/style";
 import { trans } from "i18n";
 import { CompTree } from "comps/comps/containerBase";
 import { CompStateIcon } from "./editorConstants";
 import { UICompType } from "comps/uiCompRegistry";
-import { CollapseWrapper, DirectoryTreeStyle, Node } from "./styledComponents";
-import { DataNode, EventDataNode } from "antd/lib/tree";
+import { DirectoryTreeStyle, Node } from "./styledComponents";
 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";
-import { Divider } from "antd";
+import { Button, Divider, Dropdown, Flex, Input, MenuProps, Space } from "antd";
 import { Switch } from "antd";
 import {
   saveCollisionStatus,
   getCollisionStatus,
 } from "util/localStorageUtil";
+import { check, withViewFn } from "@lowcoder-ee/index.sdk";
+import { DownOutlined } from "@ant-design/icons";
+import { ItemType } from "antd/es/menu/hooks/useItems";
 
 
 export type DisabledCollisionStatus = "true" | "false"; // "true" means collision is not enabled - Layering works, "false" means collision is enabled - Layering does not work
-export  type ToggleCollisionStatus = (
-    collisionStatus?: DisabledCollisionStatus
-  ) => void;
+export type ToggleCollisionStatus = (collisionStatus?: DisabledCollisionStatus) => void;
 
 interface LeftLayersContentProps {
   uiComp: InstanceType<typeof UIComp>;
 }
 
+const DropdownLeftShow = () => (
+  <LeftShow viewBox="0 0 256 256" /> // Setting custom viewBox
+);
+
 type NodeItem = {
   key: string;
   title: string;
@@ -67,6 +69,14 @@ const LeftLayersContentWrapper = styled.div`
   height: calc(100vh - ${TopHeaderHeight});
 `;
 
+const CustomDropdown = styled(Dropdown)`
+  .ant-dropdown-menu-item-icon {
+    width: 14px !important;
+    height: 14px !important; 
+    max-width: 14px !important;
+  }
+`;
+
 export const LeftLayersContent = (props: LeftLayersContentProps) => {
   const { uiComp } = props;
   const editorState = useContext(EditorContext);
@@ -129,25 +139,35 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
         <span>
           <span>{node.title}</span>
         </span>
-        
       </Node>
     );
   };
 
   const [componentTreeData, setComponentTreeData] = useState<NodeItem[]>([]);
 
+  // update component tree data when editor state changes
   useEffect(() => {
     const compData = getTreeUIData();
     setComponentTreeData(compData);
   }, [editorState]);
-  
+
+
   const getTreeUIData = () => {
     const tree = editorState.getUIComp().getTree();
     const explorerData: NodeItem[] = getTree(tree, []);
     const dsl = editorState.rootComp.toJsonValue();
-    explorerData.forEach(data => {
-      data['pos'] = dsl.ui.layout[data.key].pos;
-    })
+
+    if (dsl.ui.compType === "module") {
+      explorerData.forEach(data => {
+        data['pos'] = dsl.ui.comp.container.layout[data.key].pos;
+      })
+    }
+    else {
+      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;
@@ -155,6 +175,7 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
       if (aPos > bPos) return 1;
       return 0;
     });
+
     return explorerData;
   }
 
@@ -233,73 +254,163 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
     return currentNode;
   };
 
+  // here we handle the checked keys of the component tree
+
   const [checkedKeys, setCheckedKeys] = useState<string[]>([]);
+  const [actionValue, setActionValue] = useState<string>("");
+
+  const handleActionValueChange = (e: any) => {
+    setActionValue(e.target.value);
+  }
+
+  // sync selected components with checked keys
+  useEffect(() => {
+    setCheckedKeys([]);
+    const selectedComponentsOnCanvas: string[] = [];
+    const compTree = editorState.getUIComp().getTree();
+    const explorerData: NodeItem[] = getTree(compTree, []);
+    for (let value of editorState.selectedCompNames) {
+      for (let key of explorerData) {
+        if (key.title === value) {
+          selectedComponentsOnCanvas.push(key.key);
+        }
+      }
+    }
+    setCheckedKeys(selectedComponentsOnCanvas);
+  }, [editorState]);
 
   const onCheck = (checkedKeys: any, e: any) => {
     setCheckedKeys(checkedKeys);
-    console.log('onCheck', checkedKeys);
+    const checkedComponents = new Set<string>();
+    for (let key of e.checkedNodes){
+      checkedComponents.add(key.title);
+    }
+    editorState.setSelectedCompNames(checkedComponents, "leftPanel");
+  }
+
+  const getCheckedKeys = () => {
+    return checkedKeys;
+  }
+
+  const getActionValue = () => {
+    return actionValue;
   }
 
+  const handleComponentsActions = (actionType : string) => {
+    for (let key of getCheckedKeys()) {
+      const node = getTreeNodeByKey(componentTreeData, key);
+      const comp = editorState.getUICompByName(node.title);
+      if (comp != undefined) {
+        if (actionType === "hidden") {
+          comp.children.comp.dispatchChangeValueAction({ hidden: getActionValue() });
+        }
+        else if (actionType === "disable") {
+          comp.children.comp.dispatchChangeValueAction({ disabled: getActionValue() });
+        }
+        else if (actionType === "background") {
+          comp.children.comp.dispatchChangeValueAction({ BackgroundColor : getActionValue() });
+        }
+        else {
+          comp.children.comp.dispatchChangeValueAction({ actionType: getActionValue() });
+        }
+      }
+    }
+  }
+
+  /* 
+
+  dispatch(
+        multiChangeAction({
+          width: changeValueAction(width, true),
+          autoWidth: changeValueAction("fixed", true),
+        })
+      );
+
+  */
+
+  const layerActions: ItemType[] = [
+    {
+      label: 'Hide Component',
+      key: 'hide',
+      onClick: () => handleComponentsActions("hidden"),
+    },
+    {
+      label: 'Disable Component',
+      key: 'background',
+      onClick: () => handleComponentsActions("disable"),
+    },
+    {
+      label: 'Component Background',
+      key: '3',
+      onClick: () => handleComponentsActions("background"),
+    },
+    {
+      label: 'Unlock',
+      key: '4',
+    },
+  ];
+
   const getTreeUI = () => {
     // here the components get sorted by name
     // TODO: sort by category
     // TODO: sort by Types etc.
     const uiCompInfos = _.sortBy(editorState.uiCompInfoList(), [(x) => x.name]);
-    
-    /* const tree =
-      type === TreeUIKey.Components
-        ? editorState.getUIComp().getTree()
-        : editorState.getHooksComp().getUITree();
-    const explorerData: NodeItem[] = getTree(tree, []); */
-    
-    let selectedKeys = [];
-    if (editorState.selectedCompNames.size === 1) {
-      const key = Object.keys(editorState.selectedComps())[0];
-      const parentKeys = getParentNodeKeysByKey(componentTreeData, key);
-      if (parentKeys && parentKeys.length) {
-        let needSet = false;
-        parentKeys.forEach((key) => {
-          if (!expandedKeys.includes(key)) {
-            needSet = true;
-          }
-        });
-        needSet && setExpandedKeys(_.union(expandedKeys, parentKeys));
-      }
-      selectedKeys.push(key);
-    }
-
     const isDraggable = editorState.collisionStatus === "true" ? true : false;
 
     return (
       <>
-        <Switch
+      <div style={{margin:"0px 16px"}}>
+        <div style={{marginBottom:"10px"}}>
+          {trans("leftPanel.activatelayers")}
+          <Switch 
+          style={{margin : "0px 10px"}}
+          size="small"
           checked={editorState.collisionStatus == "true"}
           disabled={false}
           onChange={(value: any) => {
             toggleCollisionStatus(value == true ? "true" : "false");
             editorState.setCollisionStatus(value == true ? "true" : "false");
-          } } />
-      <DirectoryTreeStyle
-        checkable={true}
-        onCheck={onCheck}
-        draggable={isDraggable}
-        onDragEnter={handleDragEnter}
-        onDrop={(info) => handleDrop(info)}
-        treeData={componentTreeData}
-        icon={(props: any) => props.type && (
-          <div style={{ margin: '3px 0 0 -3px'}}> {/* Adjust the margin as needed */}
-            {CompStateIcon[props.type as UICompType] || <LeftCommon />}
-          </div>
-        )}
-        switcherIcon={(props: any) => props.expanded ? <FoldedIcon /> : <UnfoldIcon />}
-        expandedKeys={expandedKeys}
-        onExpand={(keys) => setExpandedKeys(keys)}
-        // onClick={(e, node) => handleNodeClick(e, node, uiCompInfos)}
-        selectedKeys={selectedKeys}
-        titleRender={(nodeData) => getTreeNode(nodeData as NodeItem, uiCompInfos)} />
-        <Divider />
-        <div></div>
-        </>
+          } } /></div>
+
+        <DirectoryTreeStyle
+          checkable={true}
+          onCheck={onCheck}
+          selectable={false}
+          checkedKeys={checkedKeys}
+          draggable={isDraggable}
+          onDragEnter={handleDragEnter}
+          onDrop={(info) => handleDrop(info)}
+          treeData={componentTreeData}
+          icon={(props: any) => props.type && (
+            <div style={{ margin: '3px 0 0 -3px'}}> {/* Adjust the margin as needed */}
+              {CompStateIcon[props.type as UICompType] || <LeftCommon />}
+            </div>
+          )}
+          switcherIcon={(props: any) => props.expanded ? <FoldedIcon /> : <UnfoldIcon />}
+          expandedKeys={expandedKeys}
+          onExpand={(keys) => setExpandedKeys(keys)}
+          titleRender={(nodeData) => getTreeNode(nodeData as NodeItem, uiCompInfos)} />
+
+        <div style={{margin:"10px 0px"}}> 
+          <Flex gap="small" vertical>
+            {trans("leftPanel.selectedComponents")}<br/>
+            {trans("leftPanel.displayComponents")}
+            <Input placeholder="Action Value" onChange={handleActionValueChange}/>
+            <CustomDropdown menu={{ items: layerActions }}>
+              <Button size={"small"}>
+                <Space>
+                  Action
+                  <DownOutlined />
+                </Space>
+              </Button>
+            </CustomDropdown>
+          </Flex>
+        </div>
+
+      </div>
+     
+      <Divider />
+      </>
     );
   };
 
@@ -313,8 +424,8 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
   const layerControlContent = (
     <ScrollBar>
       <div style={{ paddingBottom: 80 }}>
-        <BaseSection name={trans("leftPanel.components")} width={288} noMargin>
-          <span className={leftCompListClassName}>{uiCollapse}</span>
+        <BaseSection name={trans("leftPanel.layers")} width={288} noMargin>
+          <div className={leftCompListClassName}>{uiCollapse}</div>
         </BaseSection>
       </div>
     </ScrollBar>
diff --git a/client/packages/lowcoder/src/pages/editor/editorView.tsx b/client/packages/lowcoder/src/pages/editor/editorView.tsx
index 45a5122142..af1981c376 100644
--- a/client/packages/lowcoder/src/pages/editor/editorView.tsx
+++ b/client/packages/lowcoder/src/pages/editor/editorView.tsx
@@ -13,6 +13,7 @@ import {
   LeftPreloadIcon,
   LeftSettingIcon,
   LeftStateIcon,
+  LeftLayersIcon,
   ScrollBar,
 } from "lowcoder-design";
 import { useTemplateViewMode } from "util/hooks";
@@ -209,7 +210,7 @@ enum SiderKey {
   Layout = "layout",
 }
 
-const items = [
+const standardSiderItems = [
   {
     key: SiderKey.State,
     icon: <LeftStateIcon />,
@@ -220,10 +221,20 @@ const items = [
   },
   {
     key: SiderKey.Layout,
-    icon: <LeftSettingIcon />,
+    icon: <LeftLayersIcon />,
   },
 ];
 
+const aggregationSiderItems = [
+  {
+    key: SiderKey.State,
+    icon: <LeftStateIcon />,
+  },
+  {
+    key: SiderKey.Setting,
+    icon: <LeftSettingIcon />,
+  }
+];
 
 function EditorView(props: EditorViewProps) {
   const { uiComp } = props;
@@ -392,13 +403,15 @@ function EditorView(props: EditorViewProps) {
         <Body>
           <SiderWrapper>
             <Sider width={40} >
-              
               <Menu
                 theme="dark"
                 mode="inline"
                 defaultSelectedKeys={[SiderKey.State]}
                 selectedKeys={panelStatus.left ? [menuKey] : [""]}
-                items={items}
+                items={application &&
+                  !isAggregationApp(
+                    AppUILayoutType[application.applicationType]
+                  ) ? standardSiderItems : aggregationSiderItems}
                 disabled={showAppSnapshot}
                 onClick={(params) => clickMenu(params)}
               >

From 02c1ab338a354fe15fe69f39ee656333009dbffc Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Mon, 5 Feb 2024 21:50:03 +0500
Subject: [PATCH 25/97] bulk actions

---
 .../src/pages/editor/LeftLayersContent.tsx    | 62 +++++++++----------
 1 file changed, 28 insertions(+), 34 deletions(-)

diff --git a/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx b/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
index 9529758ddc..05470460f1 100644
--- a/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
+++ b/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
@@ -33,7 +33,7 @@ import cloneDeep from 'lodash/cloneDeep';
 import { useDispatch } from "react-redux";
 import { useApplicationId } from "util/hooks";
 import { updateApplication } from "redux/reduxActions/applicationActions";
-import { Button, Divider, Dropdown, Flex, Input, MenuProps, Space } from "antd";
+import { Button, Divider, Dropdown, Flex, Input, Menu, MenuProps, Space } from "antd";
 import { Switch } from "antd";
 import {
   saveCollisionStatus,
@@ -223,19 +223,7 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
             pos: index,
           };
         })
-        
-        dispatch(
-          updateApplication({
-            applicationId: applicationId,
-            editingApplicationDSL: {
-              ...dsl,
-              ui: {
-                ...dsl.ui,
-                layout,
-              }
-            } as object,
-          })
-        );
+
         editorState.rootComp.children.ui.dispatchChangeValueAction({
           ...dsl.ui,
           layout,
@@ -292,30 +280,32 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
     return checkedKeys;
   }
 
+  useEffect(() => {
+    console.log('onChange', actionValue);
+  }, [actionValue])
+  
   const getActionValue = () => {
     return actionValue;
   }
 
-  const handleComponentsActions = (actionType : string) => {
+  const handleComponentsActions = useCallback((actionType: string) => {
+    const value = getActionValue();
     for (let key of getCheckedKeys()) {
       const node = getTreeNodeByKey(componentTreeData, key);
       const comp = editorState.getUICompByName(node.title);
-      if (comp != undefined) {
-        if (actionType === "hidden") {
-          comp.children.comp.dispatchChangeValueAction({ hidden: getActionValue() });
-        }
-        else if (actionType === "disable") {
-          comp.children.comp.dispatchChangeValueAction({ disabled: getActionValue() });
-        }
-        else if (actionType === "background") {
-          comp.children.comp.dispatchChangeValueAction({ BackgroundColor : getActionValue() });
+      if(comp) {
+        const { children } = comp.children.comp
+        const types = actionType.split('.');
+
+        if(types.length === 1) { // e.g hidden, disabled
+          children[types[0]]?.dispatchChangeValueAction(value);
         }
-        else {
-          comp.children.comp.dispatchChangeValueAction({ actionType: getActionValue() });
+        else if(types.length === 2) { // nested object e.g. style.background
+          children[types[0]][types[1]]?.dispatchChangeValueAction(value);
         }
       }
     }
-  }
+  }, [getActionValue, getCheckedKeys]);
 
   /* 
 
@@ -331,18 +321,15 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
   const layerActions: ItemType[] = [
     {
       label: 'Hide Component',
-      key: 'hide',
-      onClick: () => handleComponentsActions("hidden"),
+      key: 'hidden',
     },
     {
       label: 'Disable Component',
-      key: 'background',
-      onClick: () => handleComponentsActions("disable"),
+      key: 'disable',
     },
     {
       label: 'Component Background',
-      key: '3',
-      onClick: () => handleComponentsActions("background"),
+      key: 'style.background',
     },
     {
       label: 'Unlock',
@@ -396,7 +383,14 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
             {trans("leftPanel.selectedComponents")}<br/>
             {trans("leftPanel.displayComponents")}
             <Input placeholder="Action Value" onChange={handleActionValueChange}/>
-            <CustomDropdown menu={{ items: layerActions }}>
+            <CustomDropdown
+              dropdownRender={() => (
+                <Menu
+                  items={layerActions}
+                  onClick={({key}) => handleComponentsActions(key)}
+                />
+              )}
+            >
               <Button size={"small"}>
                 <Space>
                   Action

From d98d2c5345678a816f10fdfda7b52e284505d937 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Tue, 6 Feb 2024 14:30:03 +0500
Subject: [PATCH 26/97] immediately trigger custom validation on input change

---
 .../comps/textInputComp/textInputConstants.tsx    | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx b/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx
index 291c040771..2deb701e66 100644
--- a/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx
@@ -32,7 +32,7 @@ import {
   requiredPropertyView,
 } from "comps/utils/propertyUtils";
 import { trans } from "i18n";
-import { ChangeEvent, useRef, useState } from "react";
+import { ChangeEvent, useEffect, useRef, useState } from "react";
 import { refMethods } from "comps/generators/withMethodExposing";
 import { InputRef } from "antd/es/input";
 import {
@@ -168,17 +168,22 @@ export const useTextInputProps = (props: RecordConstructorToView<typeof textInpu
   const propsRef = useRef<RecordConstructorToView<typeof textInputChildren>>(props);
   propsRef.current = props;
 
-  const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
-    props.value.onChange(e.target.value);
-    propsRef.current.onEvent("change");
+  const inputValue = props.value.value;
+
+  useEffect(() => {
     setValidateState(
       textInputValidate({
         ...propsRef.current,
         value: {
-          value: e.target.value,
+          value: inputValue,
         },
       })
     );
+  }, [inputValue]);
+
+  const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
+    props.value.onChange(e.target.value);
+    propsRef.current.onEvent("change");
   };
   return [
     {

From 55fbff9c8da4fd9796372cc168eb03a9888ea8d9 Mon Sep 17 00:00:00 2001
From: Abdul Qadir <abdul.qadir@ikhwatech.com>
Date: Tue, 6 Feb 2024 21:37:58 +0500
Subject: [PATCH 27/97] Add handling for PTM apps

---
 .../repository/ApplicationRepository.java     |  2 +-
 .../service/ApplicationService.java           |  5 +++--
 .../service/ApplicationPermissionHandler.java | 17 ++++++++++++++-
 .../service/DatasourcePermissionHandler.java  |  6 +++++-
 .../service/ResourcePermissionHandler.java    | 21 +++++++++++++++++--
 .../service/ResourcePermissionService.java    |  3 ++-
 .../application/ApplicationController.java    |  8 +++++++
 .../api/application/ApplicationEndpoints.java |  9 ++++++++
 8 files changed, 63 insertions(+), 8 deletions(-)

diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
index db842dadb7..cf23dcb501 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
@@ -35,7 +35,7 @@ public interface ApplicationRepository extends ReactiveMongoRepository<Applicati
     Flux<Application> findByIdIn(List<String> ids);
 
     @Query(fields = "{_id : 1}")
-    Flux<Application> findByPublicToAllIsTrueAndIdIn(Collection<String> ids);
+    Flux<Application> findByPublicToAllIsTrueAndPublicToMarketplaceAndIdIn(Collection<String> ids, Boolean publicToMarketplace);
 
     Flux<Application> findByPublicToAllIsTrueAndPublicToMarketplaceIsTrue();
 
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
index c0917d2ecc..abcfb6eabb 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
@@ -160,9 +160,10 @@ public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, boo
 
     @NonEmptyMono
     @SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
-    public Mono<Set<String>> getPublicApplicationIds(Collection<String> applicationIds) {
-        return repository.findByPublicToAllIsTrueAndIdIn(applicationIds)
+    public Mono<Set<String>> getPublicApplicationIds(Collection<String> applicationIds, Boolean isAnonymous) {
+        return repository.findByPublicToAllIsTrueAndPublicToMarketplaceAndIdIn(applicationIds, !isAnonymous)
                 .map(HasIdAndAuditing::getId)
                 .collect(Collectors.toSet());
+
     }
 }
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ApplicationPermissionHandler.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ApplicationPermissionHandler.java
index 8ab5c7c499..d93585bb0d 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ApplicationPermissionHandler.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ApplicationPermissionHandler.java
@@ -46,7 +46,22 @@ protected Mono<Map<String, List<ResourcePermission>>> getAnonymousUserPermission
         }
 
         Set<String> applicationIds = newHashSet(resourceIds);
-        return Mono.zip(applicationService.getPublicApplicationIds(applicationIds),
+        return Mono.zip(applicationService.getPublicApplicationIds(applicationIds, Boolean.TRUE),
+                        templateSolution.getTemplateApplicationIds(applicationIds))
+                .map(tuple -> {
+                    Set<String> publicAppIds = tuple.getT1();
+                    Set<String> templateAppIds = tuple.getT2();
+                    return collectMap(union(publicAppIds, templateAppIds), identity(), this::getAnonymousUserPermission);
+                });
+    }
+
+    // This is for PTM apps that are public but only available to logged-in users
+    @Override
+    protected Mono<Map<String, List<ResourcePermission>>> getNonAnonymousUserPublicResourcePermissions
+            (Collection<String> resourceIds, ResourceAction resourceAction) {
+
+        Set<String> applicationIds = newHashSet(resourceIds);
+        return Mono.zip(applicationService.getPublicApplicationIds(applicationIds, Boolean.FALSE),
                         templateSolution.getTemplateApplicationIds(applicationIds))
                 .map(tuple -> {
                     Set<String> publicAppIds = tuple.getT1();
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/DatasourcePermissionHandler.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/DatasourcePermissionHandler.java
index 59be368c72..130ee80331 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/DatasourcePermissionHandler.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/DatasourcePermissionHandler.java
@@ -1,7 +1,6 @@
 package org.lowcoder.domain.permission.service;
 
 import static org.lowcoder.domain.permission.model.ResourceHolder.USER;
-import static org.lowcoder.sdk.constants.Authentication.ANONYMOUS_USER_ID;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -39,6 +38,11 @@ protected Mono<Map<String, List<ResourcePermission>>> getAnonymousUserPermission
         return Mono.just(Collections.emptyMap());
     }
 
+    @Override
+    protected Mono<Map<String, List<ResourcePermission>>> getNonAnonymousUserPublicResourcePermissions(Collection<String> resourceIds, ResourceAction resourceAction) {
+        return Mono.just(Collections.emptyMap());
+    }
+
     @Override
     protected Mono<String> getOrgId(String resourceId) {
         return datasourceService.getById(resourceId)
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ResourcePermissionHandler.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ResourcePermissionHandler.java
index 6ad1ccdcc4..762e9bcb13 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ResourcePermissionHandler.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ResourcePermissionHandler.java
@@ -94,6 +94,16 @@ public Mono<UserPermissionOnResourceStatus> checkUserPermissionStatusOnResource(
             return publicResourcePermissionMono;
         }
 
+        Mono<UserPermissionOnResourceStatus> nonAnonymousPublicResourcePermissionMono = getNonAnonymousUserPublicResourcePermissions(singletonList(resourceId), resourceAction)
+                .map(it -> it.getOrDefault(resourceId, emptyList()))
+                .map(it -> {
+                    if (!it.isEmpty()) {
+                        return UserPermissionOnResourceStatus.success(it.get(0));
+                    }
+                    return isAnonymousUser(userId) ? UserPermissionOnResourceStatus.anonymousUser() : UserPermissionOnResourceStatus.notInOrg();
+                });
+
+
         Mono<UserPermissionOnResourceStatus> orgUserPermissionMono = getOrgId(resourceId)
                 .flatMap(orgId -> orgMemberService.getOrgMember(orgId, userId))
                 .flatMap(orgMember -> {
@@ -107,13 +117,17 @@ public Mono<UserPermissionOnResourceStatus> checkUserPermissionStatusOnResource(
                 })
                 .defaultIfEmpty(UserPermissionOnResourceStatus.notInOrg());
 
-        return Mono.zip(publicResourcePermissionMono, orgUserPermissionMono)
+        return Mono.zip(publicResourcePermissionMono, nonAnonymousPublicResourcePermissionMono, orgUserPermissionMono)
                 .map(tuple -> {
                     UserPermissionOnResourceStatus publicResourcePermission = tuple.getT1();
-                    UserPermissionOnResourceStatus orgUserPermission = tuple.getT2();
+                    UserPermissionOnResourceStatus nonAnonymousPublicResourcePermission = tuple.getT2();
+                    UserPermissionOnResourceStatus orgUserPermission = tuple.getT3();
                     if (orgUserPermission.hasPermission()) {
                         return orgUserPermission;
                     }
+                    if(nonAnonymousPublicResourcePermission.hasPermission()) {
+                        return nonAnonymousPublicResourcePermission;
+                    }
                     if (publicResourcePermission.hasPermission()) {
                         return publicResourcePermission;
                     }
@@ -132,6 +146,9 @@ private ResourcePermission getMaxPermission(List<ResourcePermission> permissions
     protected abstract Mono<Map<String, List<ResourcePermission>>> getAnonymousUserPermissions(Collection<String> resourceIds,
             ResourceAction resourceAction);
 
+    protected abstract Mono<Map<String, List<ResourcePermission>>> getNonAnonymousUserPublicResourcePermissions
+            (Collection<String> resourceIds, ResourceAction resourceAction);
+
     private Mono<Map<String, List<ResourcePermission>>> getAllMatchingPermissions0(String userId, String orgId, ResourceType resourceType,
             Collection<String> resourceIds,
             ResourceAction resourceAction) {
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ResourcePermissionService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ResourcePermissionService.java
index 8565591103..9cdba0e303 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ResourcePermissionService.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ResourcePermissionService.java
@@ -214,7 +214,8 @@ public Mono<ResourcePermission> checkAndReturnMaxPermission(String userId, Strin
                 });
     }
 
-    public Mono<UserPermissionOnResourceStatus> checkUserPermissionStatusOnResource(String userId, String resourceId, ResourceAction resourceAction) {
+    public Mono<UserPermissionOnResourceStatus> checkUserPermissionStatusOnResource
+            (String userId, String resourceId, ResourceAction resourceAction) {
         ResourceType resourceType = resourceAction.getResourceType();
         var resourcePermissionHandler = getResourcePermissionHandler(resourceType);
         return resourcePermissionHandler.checkUserPermissionStatusOnResource(userId, resourceId, resourceAction);
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
index ff37c60119..a5c29b1329 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
@@ -97,6 +97,14 @@ public Mono<ResponseView<ApplicationView>> getPublishedApplication(@PathVariable
                 .map(ResponseView::success);
     }
 
+    @Override
+    public Mono<ResponseView<ApplicationView>> getPublishedMarketPlaceApplication(@PathVariable String applicationId) {
+        return applicationApiService.getPublishedApplication(applicationId)
+                .delayUntil(applicationView -> applicationApiService.updateUserApplicationLastViewTime(applicationId))
+                .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(applicationView, VIEW))
+                .map(ResponseView::success);
+    }
+
     @Override
     public Mono<ResponseView<ApplicationView>> update(@PathVariable String applicationId,
             @RequestBody Application newApplication) {
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
index da51dfa047..0d03f608fb 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
@@ -111,6 +111,15 @@ public interface ApplicationEndpoints
     @GetMapping("/{applicationId}/view")
     public Mono<ResponseView<ApplicationView>> getPublishedApplication(@PathVariable String applicationId);
 
+	@Operation(
+			tags = TAG_APPLICATION_MANAGEMENT,
+			operationId = "getMarketplaceApplicationDataInViewMode",
+			summary = "Get Marketplace Application data in view mode",
+			description = "Retrieve the DSL data of a Lowcoder Application in view-mode by its ID for the marketplace."
+	)
+	@GetMapping("/{applicationId}/view_marketplace")
+	public Mono<ResponseView<ApplicationView>> getPublishedMarketPlaceApplication(@PathVariable String applicationId);
+
 	@Operation(
 			tags = TAG_APPLICATION_MANAGEMENT,
 		    operationId = "updateApplication",

From a6e34bdbf2c5f0ed710505aef0d1be853b39e6ad Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Wed, 7 Feb 2024 12:04:44 +0500
Subject: [PATCH 28/97] Fixed changing editable column value doesn't show save
 button + dont show custom columns in column value selector

---
 .../tableComp/column/tableColumnComp.tsx      |  3 +--
 .../src/comps/comps/tableComp/tableUtils.tsx  | 23 +++++++++++++------
 .../src/comps/generators/withParams.tsx       |  2 +-
 3 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
index 0d5e2ac2be..cb19414b93 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
@@ -90,7 +90,6 @@ export const columnChildrenMap = {
   isCustom: valueComp<boolean>(false),
   // If it is a data column, it must be the name of the column and cannot be duplicated as a react key
   dataIndex: valueComp<string>(""),
-  columnsList: valueComp<Array<JSONValue>>([]),
   hide: BoolControl,
   sortable: BoolControl,
   width: NumberControl,
@@ -207,7 +206,7 @@ export class ColumnComp extends ColumnInitComp {
         })}
         <Dropdown
           showSearch={true}
-          value={columnValue}
+          defaultValue={columnValue}
           options={initialColumns}
           label={trans("table.dataMapping")}
           onChange={(value) => {
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
index 9508af8cef..967ce1fbf4 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
@@ -250,13 +250,21 @@ function renderTitle(props: { title: string; editable: boolean }) {
   );
 }
 
-function getInitialColumns(columnsAggrData: ColumnsAggrData) {
-  const initialColumns = Object.keys(columnsAggrData).map(column => ({
-    label: <span style={{textTransform: 'capitalize'}}>{column}</span>,
-    value: `{{currentRow.${column}}}`
-  }))
+function getInitialColumns(
+  columnsAggrData: ColumnsAggrData,
+  customColumns: string[],
+) {
+  let initialColumns = [];
+  Object.keys(columnsAggrData).forEach(column => {
+    if(customColumns.includes(column)) return;
+    initialColumns.push({
+      // label: <span style={{textTransform: 'capitalize'}}>{column}</span>,
+      label: column,
+      value: `{{currentRow.${column}}}`
+    });
+  });
   initialColumns.push({
-    label: <span>Select with handlebars</span>,
+    label: 'Select with handlebars',
     value: '{{currentCell}}',
   })
   return initialColumns;
@@ -283,7 +291,8 @@ export function columnsToAntdFormat(
   columnsAggrData: ColumnsAggrData,
   onTableEvent: (eventName: any) => void,
 ): Array<CustomColumnType<RecordType>> {
-  const initialColumns = getInitialColumns(columnsAggrData);
+  const customColumns = columns.filter(col => col.isCustom).map(col => col.dataIndex);
+  const initialColumns = getInitialColumns(columnsAggrData, customColumns);
   const sortMap: Map<string | undefined, SortOrder> = new Map(
     sort.map((s) => [s.column, s.desc ? "descend" : "ascend"])
   );
diff --git a/client/packages/lowcoder/src/comps/generators/withParams.tsx b/client/packages/lowcoder/src/comps/generators/withParams.tsx
index a29f63cb31..4a72c3ae65 100644
--- a/client/packages/lowcoder/src/comps/generators/withParams.tsx
+++ b/client/packages/lowcoder/src/comps/generators/withParams.tsx
@@ -34,7 +34,7 @@ export const paramsEqual = (
   params1: Record<string, unknown> | undefined,
   params2: Record<string, unknown> | undefined
 ) => {
-  return depthEqual(params1, params2, 3);
+  return depthEqual(params1, params2, 4);
 };
 
 export function withParams<TCtor extends MultiCompConstructor>(

From 4ae9f7128a5b740d5cf217ebf5512859bd9af363 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Wed, 7 Feb 2024 12:22:51 +0500
Subject: [PATCH 29/97] two or more select columns in table, all editable
 select columns shows last select column options

---
 .../tableComp/column/columnTypeComps/columnSelectComp.tsx  | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnSelectComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnSelectComp.tsx
index d4305a928d..e9c5ebaa13 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnSelectComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnSelectComp.tsx
@@ -23,13 +23,14 @@ type SelectEditProps = {
   options: any[];
 };
 
-const SelectEdit = (props: SelectEditProps) => {
+const SelectEdit = (
+  props: SelectEditProps,
+) => {
   const [currentValue, setCurrentValue] = useState(props.initialValue);
-
   return (
     <SelectUIView 
       value={currentValue}
-      options={options}
+      options={props.options}
       onChange={(val) => {
         props.onChange(val);
         setCurrentValue(val)

From ff6b08f253e622d27e152c16f8e77bedf6c937ac Mon Sep 17 00:00:00 2001
From: Abdul Qadir <abdul.qadir@ikhwatech.com>
Date: Wed, 7 Feb 2024 20:28:02 +0500
Subject: [PATCH 30/97] Finalize handling for ptm apps

---
 .../domain/application/repository/ApplicationRepository.java    | 2 +-
 .../lowcoder/domain/application/service/ApplicationService.java | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
index cf23dcb501..8c018d71e1 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
@@ -35,7 +35,7 @@ public interface ApplicationRepository extends ReactiveMongoRepository<Applicati
     Flux<Application> findByIdIn(List<String> ids);
 
     @Query(fields = "{_id : 1}")
-    Flux<Application> findByPublicToAllIsTrueAndPublicToMarketplaceAndIdIn(Collection<String> ids, Boolean publicToMarketplace);
+    Flux<Application> findByPublicToAllIsTrueAndPublicToMarketplaceIsAndIdIn(Boolean publicToMarketplace, Collection<String> ids);
 
     Flux<Application> findByPublicToAllIsTrueAndPublicToMarketplaceIsTrue();
 
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
index abcfb6eabb..ec6997e09c 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
@@ -161,7 +161,7 @@ public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, boo
     @NonEmptyMono
     @SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
     public Mono<Set<String>> getPublicApplicationIds(Collection<String> applicationIds, Boolean isAnonymous) {
-        return repository.findByPublicToAllIsTrueAndPublicToMarketplaceAndIdIn(applicationIds, !isAnonymous)
+        return repository.findByPublicToAllIsTrueAndPublicToMarketplaceIsAndIdIn(!isAnonymous, applicationIds)
                 .map(HasIdAndAuditing::getId)
                 .collect(Collectors.toSet());
 

From 11c6dcdab76114fb426099e5c2a3a6fe9bed9781 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Wed, 7 Feb 2024 23:21:56 +0500
Subject: [PATCH 31/97] event Handlers in Dropdown do not read current item
 variable correctly

---
 .../src/comps/comps/buttonComp/dropdownComp.tsx   |  7 +++++--
 .../src/comps/controls/optionsControl.tsx         | 15 ++++++++++++---
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/dropdownComp.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/dropdownComp.tsx
index f58b39bd6b..5b15445dfb 100644
--- a/client/packages/lowcoder/src/comps/comps/buttonComp/dropdownComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/buttonComp/dropdownComp.tsx
@@ -83,13 +83,16 @@ const DropdownTmpComp = (function () {
         key: option.label + " - " + index,
         disabled: option.disabled,
         icon: hasIcon && <span>{option.prefixIcon}</span>,
-        onEvent: option.onEvent,
+        index,
       }));
 
     const menu = (
       <Menu
         items={items}
-        onClick={({ key }) => items.find((o) => o.key === key)?.onEvent("click")}
+        onClick={({ key }) => {
+          const item = items.find((o) => o.key === key);
+          item && props.options[item.index]?.onEvent("click");
+        }}
       />
     );
 
diff --git a/client/packages/lowcoder/src/comps/controls/optionsControl.tsx b/client/packages/lowcoder/src/comps/controls/optionsControl.tsx
index 24dd5f42f8..221459b288 100644
--- a/client/packages/lowcoder/src/comps/controls/optionsControl.tsx
+++ b/client/packages/lowcoder/src/comps/controls/optionsControl.tsx
@@ -33,11 +33,12 @@ import {
 import styled from "styled-components";
 import { lastValueIfEqual } from "util/objectUtils";
 import { getNextEntityName } from "util/stringUtils";
-import { JSONValue } from "util/jsonTypes";
+import { JSONObject, JSONValue } from "util/jsonTypes";
 import { ButtonEventHandlerControl } from "./eventHandlerControl";
 import { ControlItemCompBuilder } from "comps/generators/controlCompBuilder";
 import { ColorControl } from "./colorControl";
 import { StringStateControl } from "./codeStateControl";
+import { reduceInContext } from "../utils/reduceContext";
 
 const OptionTypes = [
   {
@@ -312,8 +313,16 @@ export function mapOptionsControl<T extends OptionsControlType>(
     }
 
     override reduce(action: CompAction) {
-      const comp = super.reduce(action);
+      // TODO: temporary solution condition to fix context issue in dropdown option's events
+      if (
+        action.type === CompActionTypes.CUSTOM
+        && (action.value as JSONObject).type === 'actionTriggered'
+      ) {
+        const comp = reduceInContext({ inEventContext: true }, () => super.reduce(action));
+        return comp;
+      } else
       if (action.type === CompActionTypes.UPDATE_NODES_V2) {
+        const comp = super.reduce(action)
         if (comp.children.data !== this.children.data) {
           const sourceArray = comp.children.data.getView();
           const dataExample = sourceArray ? sourceArray[0] : undefined;
@@ -323,7 +332,7 @@ export function mapOptionsControl<T extends OptionsControlType>(
           }
         }
       }
-      return comp;
+      return super.reduce(action);
     }
 
     updateContext(dataExample: JSONValue) {

From d1c9efaa4b3e7a45d1536574a106f987e67c3d7f Mon Sep 17 00:00:00 2001
From: "S. Seide" <account-github@seide.st>
Date: Tue, 13 Feb 2024 11:48:11 +0100
Subject: [PATCH 32/97] fix helm template encryption env var names

---
 deploy/helm/templates/api-service/secrets.yaml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/deploy/helm/templates/api-service/secrets.yaml b/deploy/helm/templates/api-service/secrets.yaml
index d7c134ca11..d900bd1bf4 100644
--- a/deploy/helm/templates/api-service/secrets.yaml
+++ b/deploy/helm/templates/api-service/secrets.yaml
@@ -20,6 +20,6 @@ stringData:
   {{- else }}
   LOWCODER_MONGODB_URL: {{ .Values.mongodb.externalUrl | quote }}
   {{- end }}
-  ELOWCODER_DB_NCRYPTION_PASSWORD: {{ .Values.global.config.encryption.password | default "lowcoder.org" | quote }}
-  ELOWCODER_DB_NCRYPTION_SALT: {{ .Values.global.config.encryption.salt | default "lowcoder.org" | quote }}
+  LOWCODER_DB_ENCRYPTION_PASSWORD: {{ .Values.global.config.encryption.password | default "lowcoder.org" | quote }}
+  LOWCODER_DB_ENCRYPTION_SALT: {{ .Values.global.config.encryption.salt | default "lowcoder.org" | quote }}
   LOWCODER_API_KEY_SECRET: "{{ .Values.global.config.apiKeySecret }}"

From 570d184417426bc43a47ee045a779d8e73de92e6 Mon Sep 17 00:00:00 2001
From: Abdul Qadir <abdul.qadir@ikhwatech.com>
Date: Wed, 14 Feb 2024 19:00:11 +0500
Subject: [PATCH 33/97] Add feature to set app as agency profile

---
 .../domain/application/model/Application.java |  8 +++
 .../repository/ApplicationRepository.java     |  7 ++-
 .../service/ApplicationService.java           | 13 ++++-
 .../permission/model/ResourceAction.java      |  1 +
 .../application/ApplicationApiService.java    |  8 ++-
 .../application/ApplicationController.java    | 25 +++++++++
 .../api/application/ApplicationEndpoints.java | 35 ++++++++++++
 .../lowcoder/api/home/UserHomeApiService.java |  2 +
 .../api/home/UserHomeApiServiceImpl.java      | 53 +++++++++++++++++++
 9 files changed, 148 insertions(+), 4 deletions(-)

diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/model/Application.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/model/Application.java
index 8144b45e2a..89c76c41b4 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/model/Application.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/model/Application.java
@@ -41,6 +41,8 @@ public class Application extends HasIdAndAuditing {
     private final Boolean publicToAll;
     private final Boolean publicToMarketplace;
 
+    private final Boolean agencyProfile;
+
     private Map<String, Object> editingApplicationDSL;
 
     @Transient
@@ -78,6 +80,7 @@ public Application(@JsonProperty("orgId") String organizationId,
             @JsonProperty("publishedApplicationDSL") Map<String, Object> publishedApplicationDSL,
             @JsonProperty("publicToAll") Boolean publicToAll,
             @JsonProperty("publicToMarketplace") Boolean publicToMarketplace,
+            @JsonProperty("agencyProfile") Boolean agencyProfile,
             @JsonProperty("editingApplicationDSL") Map<String, Object> editingApplicationDSL) {
         this.organizationId = organizationId;
         this.name = name;
@@ -86,6 +89,7 @@ public Application(@JsonProperty("orgId") String organizationId,
         this.publishedApplicationDSL = publishedApplicationDSL;
         this.publicToAll = publicToAll;
         this.publicToMarketplace = publicToMarketplace;
+        this.agencyProfile = agencyProfile;
         this.editingApplicationDSL = editingApplicationDSL;
     }
 
@@ -113,6 +117,10 @@ public boolean isPublicToMarketplace() {
         return BooleanUtils.toBooleanDefaultIfNull(publicToMarketplace, false);
     }
 
+    public boolean agencyProfile() {
+        return BooleanUtils.toBooleanDefaultIfNull(agencyProfile, false);
+    }
+
     public ApplicationQuery getQueryByViewModeAndQueryId(boolean isViewMode, String queryId) {
         return (isViewMode ? getLiveQueries() : getEditingQueries())
                 .stream()
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
index 8c018d71e1..ac37c6e9dd 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
@@ -34,9 +34,12 @@ public interface ApplicationRepository extends ReactiveMongoRepository<Applicati
 
     Flux<Application> findByIdIn(List<String> ids);
 
-    @Query(fields = "{_id : 1}")
-    Flux<Application> findByPublicToAllIsTrueAndPublicToMarketplaceIsAndIdIn(Boolean publicToMarketplace, Collection<String> ids);
+    @Query(value = "{$and:[{'publicToAll':true},{'$or':[{'publicToMarketplace':?0},{'agencyProfile':?1}]}, {'_id': { $in: ?2}}]}", fields = "{_id : 1}")
+    Flux<Application> findByPublicToAllIsTrueAndPublicToMarketplaceIsOrAgencyProfileIsAndIdIn
+            (Boolean publicToMarketplace, Boolean agencyProfile, Collection<String> ids);
 
     Flux<Application> findByPublicToAllIsTrueAndPublicToMarketplaceIsTrue();
 
+    Flux<Application> findByPublicToAllIsTrueAndAgencyProfileIsTrue();
+
 }
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
index ec6997e09c..a97f8ca675 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
@@ -107,6 +107,10 @@ public Flux<Application> findAllMarketplaceApps() {
         return repository.findByPublicToAllIsTrueAndPublicToMarketplaceIsTrue();
     }
 
+    public Flux<Application> findAllAgencyProfileApps() {
+        return repository.findByPublicToAllIsTrueAndAgencyProfileIsTrue();
+    }
+
     public Mono<Long> countByOrganizationId(String orgId, ApplicationStatus applicationStatus) {
         return repository.countByOrganizationIdAndApplicationStatus(orgId, applicationStatus);
     }
@@ -158,10 +162,17 @@ public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, boo
         return mongoUpsertHelper.updateById(application, applicationId);
     }
 
+    public Mono<Boolean> setApplicationAsAgencyProfile(String applicationId, boolean agencyProfile) {
+        Application application = Application.builder()
+                .agencyProfile(agencyProfile)
+                .build();
+        return mongoUpsertHelper.updateById(application, applicationId);
+    }
+
     @NonEmptyMono
     @SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
     public Mono<Set<String>> getPublicApplicationIds(Collection<String> applicationIds, Boolean isAnonymous) {
-        return repository.findByPublicToAllIsTrueAndPublicToMarketplaceIsAndIdIn(!isAnonymous, applicationIds)
+        return repository.findByPublicToAllIsTrueAndPublicToMarketplaceIsOrAgencyProfileIsAndIdIn(!isAnonymous, !isAnonymous, applicationIds)
                 .map(HasIdAndAuditing::getId)
                 .collect(Collectors.toSet());
 
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/model/ResourceAction.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/model/ResourceAction.java
index c11257e414..da442e7e02 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/model/ResourceAction.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/model/ResourceAction.java
@@ -25,6 +25,7 @@ public enum ResourceAction {
 
     SET_APPLICATIONS_PUBLIC(ResourceRole.EDITOR, ResourceType.APPLICATION),
     SET_APPLICATIONS_PUBLIC_TO_MARKETPLACE(ResourceRole.EDITOR, ResourceType.APPLICATION),
+    SET_APPLICATIONS_AS_AGENCY_PROFILE(ResourceRole.EDITOR, ResourceType.APPLICATION),
 
     // datasource action
     MANAGE_DATASOURCES(ResourceRole.OWNER, ResourceType.DATASOURCE),
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
index cf3d68d481..f8b624c2a9 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
@@ -141,7 +141,7 @@ public Mono<ApplicationView> create(CreateApplicationRequest createApplicationRe
                 createApplicationRequest.applicationType(),
                 NORMAL,
                 createApplicationRequest.publishedApplicationDSL(),
-                false, false, createApplicationRequest.editingApplicationDSL());
+                false, false, false, createApplicationRequest.editingApplicationDSL());
 
         if (StringUtils.isBlank(application.getOrganizationId())) {
             return deferredError(INVALID_PARAMETER, "ORG_ID_EMPTY");
@@ -506,6 +506,12 @@ public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, boo
                 .then(applicationService.setApplicationPublicToMarketplace(applicationId, publicToMarketplace));
     }
 
+    public Mono<Boolean> setApplicationAsAgencyProfile(String applicationId, boolean agencyProfile) {
+        return checkCurrentUserApplicationPermission(applicationId, ResourceAction.SET_APPLICATIONS_AS_AGENCY_PROFILE)
+                .then(checkApplicationStatus(applicationId, NORMAL))
+                .then(applicationService.setApplicationAsAgencyProfile(applicationId, agencyProfile));
+    }
+
     private Map<String, Object> sanitizeDsl(Map<String, Object> applicationDsl) {
         if (applicationDsl.get("queries") instanceof List<?> queries) {
             List<Map<String, Object>> list = queries.stream().map(this::doSanitizeQuery).toList();
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
index a5c29b1329..5f02f9783a 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
@@ -105,6 +105,14 @@ public Mono<ResponseView<ApplicationView>> getPublishedMarketPlaceApplication(@P
                 .map(ResponseView::success);
     }
 
+    @Override
+    public Mono<ResponseView<ApplicationView>> getAgencyProfileApplication(@PathVariable String applicationId) {
+        return applicationApiService.getPublishedApplication(applicationId)
+                .delayUntil(applicationView -> applicationApiService.updateUserApplicationLastViewTime(applicationId))
+                .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(applicationView, VIEW))
+                .map(ResponseView::success);
+    }
+
     @Override
     public Mono<ResponseView<ApplicationView>> update(@PathVariable String applicationId,
             @RequestBody Application newApplication) {
@@ -144,6 +152,14 @@ public Mono<ResponseView<List<MarketplaceApplicationInfoView>>> getMarketplaceAp
                 .map(ResponseView::success);
     }
 
+    @Override
+    public Mono<ResponseView<List<MarketplaceApplicationInfoView>>> getAgencyProfileApplications(@RequestParam(required = false) Integer applicationType) {
+        ApplicationType applicationTypeEnum = applicationType == null ? null : ApplicationType.fromValue(applicationType);
+        return userHomeApiService.getAllMarketplaceApplications(applicationTypeEnum)
+                .collectList()
+                .map(ResponseView::success);
+    }
+
     @Override
     public Mono<ResponseView<Boolean>> updatePermission(@PathVariable String applicationId,
             @PathVariable String permissionId,
@@ -201,4 +217,13 @@ public Mono<ResponseView<Boolean>> setApplicationPublicToMarketplace(@PathVariab
         return applicationApiService.setApplicationPublicToMarketplace(applicationId, request.publicToMarketplace())
                 .map(ResponseView::success);
     }
+
+    @Override
+    public Mono<ResponseView<Boolean>> setApplicationAsAgencyProfile(@PathVariable String applicationId,
+                                                                     @RequestBody ApplicationAsAgencyProfileRequest request) {
+        return applicationApiService.setApplicationAsAgencyProfile(applicationId, request.agencyProfile())
+                .map(ResponseView::success);
+    }
+
+
 }
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
index 0d03f608fb..2c97333824 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
@@ -120,6 +120,15 @@ public interface ApplicationEndpoints
 	@GetMapping("/{applicationId}/view_marketplace")
 	public Mono<ResponseView<ApplicationView>> getPublishedMarketPlaceApplication(@PathVariable String applicationId);
 
+	@Operation(
+			tags = TAG_APPLICATION_MANAGEMENT,
+			operationId = "getAgencyProfileApplicationDataInViewMode",
+			summary = "Get Agency profile Application data in view mode",
+			description = "Retrieve the DSL data of a Lowcoder Application in view-mode by its ID marked as agency profile."
+	)
+	@GetMapping("/{applicationId}/view_agency")
+	public Mono<ResponseView<ApplicationView>> getAgencyProfileApplication(@PathVariable String applicationId);
+
 	@Operation(
 			tags = TAG_APPLICATION_MANAGEMENT,
 		    operationId = "updateApplication",
@@ -168,6 +177,15 @@ public Mono<ResponseView<List<ApplicationInfoView>>> getApplications(@RequestPar
 	@GetMapping("/marketplace-apps")
 	public Mono<ResponseView<List<MarketplaceApplicationInfoView>>> getMarketplaceApplications(@RequestParam(required = false) Integer applicationType);
 
+	@Operation(
+			tags = TAG_APPLICATION_MANAGEMENT,
+			operationId = "listAgencyProfileApplications",
+			summary = "List agency profile Applications",
+			description = "Retrieve a list of Lowcoder Applications that are set as agency profiles"
+	)
+	@GetMapping("/agency-profiles")
+	public Mono<ResponseView<List<MarketplaceApplicationInfoView>>> getAgencyProfileApplications(@RequestParam(required = false) Integer applicationType);
+
 	@Operation(
 			tags = TAG_APPLICATION_PERMISSIONS,
 		    operationId = "updateApplicationPermissions",
@@ -231,6 +249,16 @@ public Mono<ResponseView<Boolean>> setApplicationPublicToAll(@PathVariable Strin
 	public Mono<ResponseView<Boolean>> setApplicationPublicToMarketplace(@PathVariable String applicationId,
 																  @RequestBody ApplicationPublicToMarketplaceRequest request);
 
+	@Operation(
+			tags = TAG_APPLICATION_MANAGEMENT,
+			operationId = "setApplicationAsAgencyProfile",
+			summary = "Set Application as agency profile",
+			description = "Set a Lowcoder Application identified by its ID as as agency profile but to only logged in users."
+	)
+	@PutMapping("/{applicationId}/agency-profile")
+	public Mono<ResponseView<Boolean>> setApplicationAsAgencyProfile(@PathVariable String applicationId,
+																	 @RequestBody ApplicationAsAgencyProfileRequest request);
+
 
 	public record BatchAddPermissionRequest(String role, Set<String> userIds, Set<String> groupIds) {
     }
@@ -249,6 +277,13 @@ public Boolean publicToMarketplace() {
 		}
 	}
 
+	public record ApplicationAsAgencyProfileRequest(Boolean agencyProfile) {
+		@Override
+		public Boolean agencyProfile() {
+			return BooleanUtils.isTrue(agencyProfile);
+		}
+	}
+
     public record UpdatePermissionRequest(String role) {
     }
 
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiService.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiService.java
index 5f194fcc4f..454af54d85 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiService.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiService.java
@@ -25,4 +25,6 @@ Flux<ApplicationInfoView> getAllAuthorisedApplications4CurrentOrgMember(@Nullabl
             @Nullable ApplicationStatus applicationStatus, boolean withContainerSize);
 
     public Flux<MarketplaceApplicationInfoView> getAllMarketplaceApplications(@Nullable ApplicationType applicationType);
+
+    public Flux<MarketplaceApplicationInfoView> getAllAgencyProfileApplications(@Nullable ApplicationType applicationType);
 }
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
index 6d7aff678f..e10fe0ea1f 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
@@ -310,6 +310,59 @@ public Flux<MarketplaceApplicationInfoView> getAllMarketplaceApplications(@Nulla
                 });
     }
 
+    @Override
+    public Flux<MarketplaceApplicationInfoView> getAllAgencyProfileApplications(@Nullable ApplicationType applicationType) {
+
+        return sessionUserService.getVisitorOrgMemberCache()
+                .flatMapMany(orgMember -> {
+                    // application flux
+                    Flux<Application> applicationFlux = Flux.defer(() -> applicationService.findAllAgencyProfileApps())
+                            .filter(application -> isNull(applicationType) || application.getApplicationType() == applicationType.getValue())
+                            .cache();
+
+                    // user map
+                    Mono<Map<String, User>> userMapMono = applicationFlux
+                            .flatMap(application -> emptyIfNull(application.getCreatedBy()))
+                            .collectList()
+                            .flatMap(creatorIds -> userService.getByIds(creatorIds))
+                            .cache();
+
+                    // org map
+                    Mono<Map<String, Organization>> orgMapMono = applicationFlux
+                            .flatMap(application -> emptyIfNull(application.getOrganizationId()))
+                            .collectList()
+                            .flatMap(orgIds -> organizationService.getByIds(orgIds)
+                                    .collectList()
+                                    .map(it -> it.stream().collect(Collectors.toMap(Organization::getId, Function.identity())))
+                            )
+                            .cache();
+
+
+                    return applicationFlux
+                            .flatMap(application -> Mono.zip(Mono.just(application), userMapMono, orgMapMono))
+                            .map(tuple -> {
+                                // build view
+                                Application application = tuple.getT1();
+                                Map<String, User> userMap = tuple.getT2();
+                                Map<String, Organization> orgMap = tuple.getT3();
+                                return MarketplaceApplicationInfoView.builder()
+                                        .applicationId(application.getId())
+                                        .name(application.getName())
+                                        .applicationType(application.getApplicationType())
+                                        .applicationStatus(application.getApplicationStatus())
+                                        .orgId(application.getOrganizationId())
+                                        .orgName(orgMap.get(application.getOrganizationId()).getName())
+                                        .creatorEmail(Optional.ofNullable(userMap.get(application.getCreatedBy()))
+                                                .map(User::getName)
+                                                .orElse(""))
+                                        .createAt(application.getCreatedAt().toEpochMilli())
+                                        .createBy(application.getCreatedBy())
+                                        .build();
+                            });
+
+                });
+    }
+
     private ApplicationInfoView buildView(Application application, ResourceRole maxRole, Map<String, User> userMap, @Nullable Instant lastViewTime,
             boolean withContainerSize) {
         ApplicationInfoViewBuilder applicationInfoViewBuilder = ApplicationInfoView.builder()

From acbef3c0e54048b51bac3a1bce624f838afc3c65 Mon Sep 17 00:00:00 2001
From: Abdul Qadir <abdul.qadir@ikhwatech.com>
Date: Wed, 14 Feb 2024 19:30:45 +0500
Subject: [PATCH 34/97] Add validation between ptm and agency apis

---
 .../api/application/ApplicationApiService.java | 18 ++++++++++++++++--
 .../api/application/ApplicationController.java |  6 +++---
 .../api/application/ApplicationEndpoints.java  |  6 ++++++
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
index f8b624c2a9..f1eaad172b 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
@@ -248,6 +248,19 @@ private Mono<Void> checkApplicationStatus(Application application, ApplicationSt
         return Mono.error(new BizException(BizError.UNSUPPORTED_OPERATION, "BAD_REQUEST"));
     }
 
+    private Mono<Void> checkApplicationViewRequest(Application application, ApplicationEndpoints.ApplicationRequestType expected) {
+        if (expected == ApplicationEndpoints.ApplicationRequestType.PUBLIC_TO_ALL && application.isPublicToAll()) {
+            return Mono.empty();
+        }
+        if (expected == ApplicationEndpoints.ApplicationRequestType.PUBLIC_TO_MARKETPLACE && application.isPublicToMarketplace()) {
+            return Mono.empty();
+        }
+        if (expected == ApplicationEndpoints.ApplicationRequestType.AGENCY_PROFILE && application.agencyProfile()) {
+            return Mono.empty();
+        }
+        return Mono.error(new BizException(BizError.UNSUPPORTED_OPERATION, "BAD_REQUEST"));
+    }
+
     private Mono<Boolean> updateApplicationStatus(String applicationId, ApplicationStatus applicationStatus) {
         return checkCurrentUserApplicationPermission(applicationId, MANAGE_APPLICATIONS)
                 .then(Mono.defer(() -> {
@@ -280,10 +293,11 @@ public Mono<ApplicationView> getEditingApplication(String applicationId) {
                 });
     }
 
-    public Mono<ApplicationView> getPublishedApplication(String applicationId) {
+    public Mono<ApplicationView> getPublishedApplication(String applicationId, ApplicationEndpoints.ApplicationRequestType requestType) {
         return checkPermissionWithReadableErrorMsg(applicationId, READ_APPLICATIONS)
                 .zipWhen(permission -> applicationService.findById(applicationId)
-                        .delayUntil(application -> checkApplicationStatus(application, NORMAL)))
+                        .delayUntil(application -> checkApplicationStatus(application, NORMAL))
+                        .delayUntil(application -> checkApplicationViewRequest(application, requestType)))
                 .zipWhen(tuple -> applicationService.getAllDependentModulesFromApplication(tuple.getT2(), true), TupleUtils::merge)
                 .zipWhen(tuple -> organizationService.getOrgCommonSettings(tuple.getT2().getOrganizationId()), TupleUtils::merge)
                 .zipWith(getTemplateIdFromApplicationId(applicationId), TupleUtils::merge)
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
index 5f02f9783a..e75de598d0 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
@@ -91,7 +91,7 @@ public Mono<ResponseView<ApplicationView>> getEditingApplication(@PathVariable S
 
     @Override
     public Mono<ResponseView<ApplicationView>> getPublishedApplication(@PathVariable String applicationId) {
-        return applicationApiService.getPublishedApplication(applicationId)
+        return applicationApiService.getPublishedApplication(applicationId, ApplicationRequestType.PUBLIC_TO_ALL)
                 .delayUntil(applicationView -> applicationApiService.updateUserApplicationLastViewTime(applicationId))
                 .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(applicationView, VIEW))
                 .map(ResponseView::success);
@@ -99,7 +99,7 @@ public Mono<ResponseView<ApplicationView>> getPublishedApplication(@PathVariable
 
     @Override
     public Mono<ResponseView<ApplicationView>> getPublishedMarketPlaceApplication(@PathVariable String applicationId) {
-        return applicationApiService.getPublishedApplication(applicationId)
+        return applicationApiService.getPublishedApplication(applicationId, ApplicationRequestType.PUBLIC_TO_MARKETPLACE)
                 .delayUntil(applicationView -> applicationApiService.updateUserApplicationLastViewTime(applicationId))
                 .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(applicationView, VIEW))
                 .map(ResponseView::success);
@@ -107,7 +107,7 @@ public Mono<ResponseView<ApplicationView>> getPublishedMarketPlaceApplication(@P
 
     @Override
     public Mono<ResponseView<ApplicationView>> getAgencyProfileApplication(@PathVariable String applicationId) {
-        return applicationApiService.getPublishedApplication(applicationId)
+        return applicationApiService.getPublishedApplication(applicationId, ApplicationRequestType.AGENCY_PROFILE)
                 .delayUntil(applicationView -> applicationApiService.updateUserApplicationLastViewTime(applicationId))
                 .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(applicationView, VIEW))
                 .map(ResponseView::success);
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
index 2c97333824..eae901f219 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
@@ -284,6 +284,12 @@ public Boolean agencyProfile() {
 		}
 	}
 
+	public enum ApplicationRequestType {
+		PUBLIC_TO_ALL,
+		PUBLIC_TO_MARKETPLACE,
+		AGENCY_PROFILE,
+	}
+
     public record UpdatePermissionRequest(String role) {
     }
 

From 37a901ab680fcda2c2189db711191c9e0170f55a Mon Sep 17 00:00:00 2001
From: Imtanan Aziz Toor <imtanan.aziz@ikhwatech.com>
Date: Wed, 14 Feb 2024 21:18:20 +0500
Subject: [PATCH 35/97] font style property created and added in textDisplay
 component

---
 client/package.json                           |   1 +
 .../lowcoder/src/comps/comps/textComp.tsx     |   9 +-
 .../src/comps/controls/styleControl.tsx       | 471 +++++++++---------
 .../comps/controls/styleControlConstants.tsx  | 230 ++++-----
 .../packages/lowcoder/src/i18n/locales/en.ts  |   1 +
 5 files changed, 371 insertions(+), 341 deletions(-)

diff --git a/client/package.json b/client/package.json
index 2f49baf8c4..6e1dff2dc4 100644
--- a/client/package.json
+++ b/client/package.json
@@ -11,6 +11,7 @@
   },
   "scripts": {
     "start": "yarn workspace lowcoder start",
+    "start-win":"LOWCODER_API_SERVICE_URL=http://localhost:3000 yarn start",
     "start:ee": "REACT_APP_EDITION=enterprise yarn workspace lowcoder start",
     "start:ee-global": "REACT_APP_EDITION=enterprise-global yarn workspace lowcoder start",
     "build": "yarn node ./scripts/build.js",
diff --git a/client/packages/lowcoder/src/comps/comps/textComp.tsx b/client/packages/lowcoder/src/comps/comps/textComp.tsx
index 671e67354f..4359166dd5 100644
--- a/client/packages/lowcoder/src/comps/comps/textComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/textComp.tsx
@@ -29,6 +29,7 @@ const getStyle = (style: TextStyleType) => {
     font-size: ${style.textSize} !important;
     font-weight: ${style.textWeight} !important;
     font-family: ${style.fontFamily} !important;
+    font-style:${style.fontStyle} !important;
     background-color: ${style.background};
     .markdown-body a {
       color: ${style.links};
@@ -111,7 +112,7 @@ const VerticalAlignmentOptions = [
 ] as const;
 
 
-let TextTmpComp = (function () {  
+let TextTmpComp = (function () {
 
   const childrenMap = {
     text: stringExposingStateControl(
@@ -123,7 +124,7 @@ let TextTmpComp = (function () {
     horizontalAlignment: alignWithJustifyControl(),
     verticalAlignment: dropdownControl(VerticalAlignmentOptions, "center"),
     style: styleControl(TextStyle),
-    margin: MarginControl,	
+    margin: MarginControl,
     padding: PaddingControl,
   };
   return new UICompBuilder(childrenMap, (props) => {
@@ -145,7 +146,7 @@ let TextTmpComp = (function () {
     .setPropertyViewFn((children) => {
       return (
         <>
-        
+
           <Section name={sectionNames.basic}>
             {children.type.propertyView({
               label: trans("value"),
@@ -160,7 +161,7 @@ let TextTmpComp = (function () {
               {hiddenPropertyView(children)}
             </Section>
           )}
-        
+
           {["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && (
             <>
               <Section name={sectionNames.layout}>
diff --git a/client/packages/lowcoder/src/comps/controls/styleControl.tsx b/client/packages/lowcoder/src/comps/controls/styleControl.tsx
index 669c450e3e..7295a97831 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControl.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControl.tsx
@@ -36,6 +36,7 @@ import {
   TextSizeConfig,
   TextWeightConfig,
   FontFamilyConfig,
+  FontStyleConfig,
   BorderWidthConfig,
   BackgroundImageConfig,
   BackgroundImageRepeatConfig,
@@ -136,13 +137,16 @@ function isTextWeightConfig(config: SingleColorConfig): config is TextWeightConf
 function isFontFamilyConfig(config: SingleColorConfig): config is FontFamilyConfig {
   return config.hasOwnProperty("fontFamily");
 }
+function isFontStyleConfig(config: SingleColorConfig): config is FontStyleConfig {
+  return config.hasOwnProperty("fontStyle");
+}
 
-function isMarginConfig(config: SingleColorConfig): config is MarginConfig {	
-  return config.hasOwnProperty("margin");	
-}	
+function isMarginConfig(config: SingleColorConfig): config is MarginConfig {
+  return config.hasOwnProperty("margin");
+}
 
-function isPaddingConfig(config: SingleColorConfig): config is PaddingConfig {	
-  return config.hasOwnProperty("padding");	
+function isPaddingConfig(config: SingleColorConfig): config is PaddingConfig {
+  return config.hasOwnProperty("padding");
 }
 
 // function styleControl(colorConfig: Array<SingleColorConfig>) {
@@ -215,12 +219,15 @@ function isEmptyTextWeight(textWeight: string) {
 function isEmptyFontFamily(fontFamily: string) {
   return _.isEmpty(fontFamily);
 }
+function isEmptyFontStyle(fontStyle: string) {
+  return _.isEmpty(fontStyle);
+}
 
-function isEmptyMargin(margin: string) {	
-  return _.isEmpty(margin);	
-}	
-function isEmptyPadding(padding: string) {	
-  return _.isEmpty(padding);	
+function isEmptyMargin(margin: string) {
+  return _.isEmpty(margin);
+}
+function isEmptyPadding(padding: string) {
+  return _.isEmpty(padding);
 }
 
 /**
@@ -237,93 +244,97 @@ function calcColors<ColorMap extends Record<string, string>>(
   let res: Record<string, string> = {};
   colorConfigs.forEach((config) => {
     const name = config.name;
-    if (!isEmptyRadius(props[name]) && isRadiusConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyBorderWidth(props[name]) && isBorderWidthConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyBackgroundImageConfig(props[name]) && isBackgroundImageConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyBackgroundImageRepeatConfig(props[name]) && isBackgroundImageRepeatConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyBackgroundImageSizeConfig(props[name]) && isBackgroundImageSizeConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyBackgroundImagePositionConfig(props[name]) && isBackgroundImagePositionConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyBackgroundImageOriginConfig(props[name]) && isBackgroundImageOriginConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyHeaderBackgroundImageConfig(props[name]) && isHeaderBackgroundImageConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyHeaderBackgroundImageRepeatConfig(props[name]) && isHeaderBackgroundImageRepeatConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyHeaderBackgroundImageSizeConfig(props[name]) && isHeaderBackgroundImageSizeConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyHeaderBackgroundImagePositionConfig(props[name]) && isHeaderBackgroundImagePositionConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyHeaderBackgroundImageOriginConfig(props[name]) && isHeaderBackgroundImageOriginConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyFooterBackgroundImageConfig(props[name]) && isFooterBackgroundImageConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyFooterBackgroundImageRepeatConfig(props[name]) && isFooterBackgroundImageRepeatConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyFooterBackgroundImageSizeConfig(props[name]) && isFooterBackgroundImageSizeConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyFooterBackgroundImagePositionConfig(props[name]) && isFooterBackgroundImagePositionConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyFooterBackgroundImageOriginConfig(props[name]) && isFooterBackgroundImageOriginConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyTextSize(props[name]) && isTextSizeConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }	
-    if (!isEmptyTextWeight(props[name]) && isTextWeightConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }	
-    if (!isEmptyFontFamily(props[name]) && isFontFamilyConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }
-    if (!isEmptyMargin(props[name]) && isMarginConfig(config)) {	
-      res[name] = props[name];	
-      return;	
-    }	
-    if (!isEmptyPadding(props[name]) && isPaddingConfig(config)) {	
-      res[name] = props[name];	
-      return;	
+    if (!isEmptyRadius(props[name]) && isRadiusConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyBorderWidth(props[name]) && isBorderWidthConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyBackgroundImageConfig(props[name]) && isBackgroundImageConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyBackgroundImageRepeatConfig(props[name]) && isBackgroundImageRepeatConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyBackgroundImageSizeConfig(props[name]) && isBackgroundImageSizeConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyBackgroundImagePositionConfig(props[name]) && isBackgroundImagePositionConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyBackgroundImageOriginConfig(props[name]) && isBackgroundImageOriginConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyHeaderBackgroundImageConfig(props[name]) && isHeaderBackgroundImageConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyHeaderBackgroundImageRepeatConfig(props[name]) && isHeaderBackgroundImageRepeatConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyHeaderBackgroundImageSizeConfig(props[name]) && isHeaderBackgroundImageSizeConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyHeaderBackgroundImagePositionConfig(props[name]) && isHeaderBackgroundImagePositionConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyHeaderBackgroundImageOriginConfig(props[name]) && isHeaderBackgroundImageOriginConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyFooterBackgroundImageConfig(props[name]) && isFooterBackgroundImageConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyFooterBackgroundImageRepeatConfig(props[name]) && isFooterBackgroundImageRepeatConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyFooterBackgroundImageSizeConfig(props[name]) && isFooterBackgroundImageSizeConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyFooterBackgroundImagePositionConfig(props[name]) && isFooterBackgroundImagePositionConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyFooterBackgroundImageOriginConfig(props[name]) && isFooterBackgroundImageOriginConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyTextSize(props[name]) && isTextSizeConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyTextWeight(props[name]) && isTextWeightConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyFontFamily(props[name]) && isFontFamilyConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyFontStyle(props[name]) && isFontStyleConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyMargin(props[name]) && isMarginConfig(config)) {
+      res[name] = props[name];
+      return;
+    }
+    if (!isEmptyPadding(props[name]) && isPaddingConfig(config)) {
+      res[name] = props[name];
+      return;
     }
     if (!isEmptyColor(props[name])) {
       if (isThemeColorKey(props[name])) {
@@ -398,11 +409,14 @@ function calcColors<ColorMap extends Record<string, string>>(
     if (isFontFamilyConfig(config)) {
       res[name] = themeWithDefault[config.fontFamily] || 'sans-serif';
     }
-    if (isMarginConfig(config)) {	
-      res[name] = themeWithDefault[config.margin];	
-    }	
-    if (isPaddingConfig(config)) {	
-      res[name] = themeWithDefault[config.padding];	
+    if (isFontStyleConfig(config)) {
+      res[name] = themeWithDefault[config.fontStyle] || 'normal'
+    }
+    if (isMarginConfig(config)) {
+      res[name] = themeWithDefault[config.margin];
+    }
+    if (isPaddingConfig(config)) {
+      res[name] = themeWithDefault[config.padding];
     }
   });
   // The second pass calculates dep
@@ -509,7 +523,7 @@ const StyleContent = styled.div`
 
 const RadiusIcon = styled(IconRadius)` margin: 0 8px 0 -2px;`;
 const BorderIcon = styled(BorderWidthIcon)` margin: 0 8px 0 -3px; padding: 3px;`;
-const MarginIcon = styled(ExpandIcon)` margin: 0 8px 0 2px;`;	
+const MarginIcon = styled(ExpandIcon)` margin: 0 8px 0 2px;`;
 const PaddingIcon = styled(CompressIcon)`	margin: 0 8px 0 2px;`;
 const StyledTextSizeIcon = styled(TextSizeIcon)` margin: 0 8px 0 -3px; padding: 3px;`;
 const StyledFontFamilyIcon = styled(FontFamilyIcon)` margin: 0 8px 0 -3px; padding: 3px;`;
@@ -527,13 +541,14 @@ export function styleControl<T extends readonly SingleColorConfig[]>(colorConfig
   const childrenMap: any = {};
   colorConfigs.map((config) => {
     const name: Names<T> = config.name;
-    if (	
+    if (
       name === "radius" ||
       name === "borderWidth" ||
       name === "cardRadius" ||
-      name === "textSize" || 
+      name === "textSize" ||
       name === "textWeight" ||
       name === "fontFamily" ||
+      name === "fontStyle" ||
       name === "backgroundImage" ||
       name === "backgroundImageRepeat" ||
       name === "backgroundImageSize" ||
@@ -549,15 +564,15 @@ export function styleControl<T extends readonly SingleColorConfig[]>(colorConfig
       name === "footerBackgroundImageSize" ||
       name === "footerBackgroundImagePosition" ||
       name === "footerBackgroundImageOrigin" ||
-      name === "margin" || 
-      name === "padding" || 
-      name === "containerheaderpadding" || 
-      name === "containerfooterpadding" || 
+      name === "margin" ||
+      name === "padding" ||
+      name === "containerheaderpadding" ||
+      name === "containerfooterpadding" ||
       name === "containerbodypadding"
-    ) {	
-      childrenMap[name] = StringControl;	
-    }  else {	
-      childrenMap[name] = ColorControl;	
+    ) {
+      childrenMap[name] = StringControl;
+    } else {
+      childrenMap[name] = ColorControl;
     }
   });
   // [K in Names<T>]: new (params: CompParams<any>) => ColorControl;
@@ -593,12 +608,12 @@ export function styleControl<T extends readonly SingleColorConfig[]>(colorConfig
                 onClick={() => {
                   colorConfigs.map((item) => {
                     const name: Names<T> = item.name;
-                    if (	
-                      name === "radius" ||	
-                      name === "margin" ||	
+                    if (
+                      name === "radius" ||
+                      name === "margin" ||
                       name === "padding" ||
-                      name === "containerheaderpadding"	||
-                      name === "containerfooterpadding"	||
+                      name === "containerheaderpadding" ||
+                      name === "containerfooterpadding" ||
                       name === "containerbodypadding" ||
                       name === "borderWidth" ||
                       name === "backgroundImage" ||
@@ -653,115 +668,123 @@ export function styleControl<T extends readonly SingleColorConfig[]>(colorConfig
                 }
                 return controlItem(
                   { filterText: config.label },
-                  <div key={index}>	
+                  <div key={index}>
                     {(name === "radius" ||
-                    name === "gap" ||	
-                    name === "cardRadius")
-                      ? (	
-                          children[name] as InstanceType<typeof StringControl>	
-                        ).propertyView({	
-                          label: config.label,	
-                          preInputNode: <RadiusIcon title="Radius" />,	
-                          placeholder: props[name],	
-                        })
-                        : name === "borderWidth"
-                        ? (	
-                            children[name] as InstanceType<typeof StringControl>	
-                          ).propertyView({	
-                            label: config.label,	
-                            preInputNode: <BorderIcon title="Border-Width" />,	
-                            placeholder: props[name],	
-                          })
-                      : name === "margin"	
-                      ? (	
-                          children[name] as InstanceType<typeof StringControl>	
-                        ).propertyView({	
-                          label: config.label,	
-                          preInputNode: <MarginIcon title="Margin" />,	
-                          placeholder: props[name],	
-                        })	
-                      : (name === "padding" ||
-                      name === "containerheaderpadding"	||
-                      name === "containerfooterpadding"	||
-                      name === "containerbodypadding")
-                      ? (	
-                          children[name] as InstanceType<typeof StringControl>	
-                        ).propertyView({	
-                          label: config.label,	
-                          preInputNode: <PaddingIcon title="Padding" />,	
-                          placeholder: props[name],	
-                        })	
-                      : name === "textSize"
-                      ? (	
-                          children[name] as InstanceType<typeof StringControl>	
-                        ).propertyView({	
-                          label: config.label,	
-                          preInputNode: <StyledTextSizeIcon title="Font Size" />,	
-                          placeholder: props[name],	
-                        })
-                      : name === "textWeight"
-                      ? (	
-                          children[name] as InstanceType<typeof StringControl>	
-                        ).propertyView({	
-                          label: config.label,	
-                          preInputNode: <StyledTextWeightIcon title="Font Weight" />,	
-                          placeholder: props[name],	
-                        })
-                      : name === "fontFamily"
-                      ? (	
-                          children[name] as InstanceType<typeof StringControl>	
-                        ).propertyView({	
+                      name === "gap" ||
+                      name === "cardRadius")
+                      ? (
+                        children[name] as InstanceType<typeof StringControl>
+                      ).propertyView({
+                        label: config.label,
+                        preInputNode: <RadiusIcon title="Radius" />,
+                        placeholder: props[name],
+                      })
+                      : name === "borderWidth"
+                        ? (
+                          children[name] as InstanceType<typeof StringControl>
+                        ).propertyView({
                           label: config.label,
-                          preInputNode: <StyledFontFamilyIcon title="Font Family" />,	
-                          placeholder: props[name],	
-                        })
-                      : name === "backgroundImage" || name === "headerBackgroundImage" || name === "footerBackgroundImage"
-                      ? (	
-                          children[name] as InstanceType<typeof StringControl>	
-                        ).propertyView({	
-                          label: config.label,	
-                          preInputNode: <StyledBackgroundImageIcon title="Background Image" />,	
-                          placeholder: props[name],	
-                        })
-                      : name === "backgroundImageRepeat" || name === "headerBackgroundImageRepeat" || name === "footerBackgroundImageRepeat"
-                      ? (	
-                          children[name] as InstanceType<typeof StringControl>	
-                        ).propertyView({	
-                          label: config.label,	
-                          preInputNode: <StyledBackgroundImageIcon title="Background Image Repeat" />,	
-                          placeholder: props[name],	
-                        })
-                      : name === "backgroundImageSize" || name === "headerBackgroundImageSize" || name === "footerBackgroundImageSize"
-                      ? (	
-                          children[name] as InstanceType<typeof StringControl>	
-                        ).propertyView({	
-                          label: config.label,	
-                          preInputNode: <StyledBackgroundImageIcon title="Background Image Size" />,	
-                          placeholder: props[name],	
+                          preInputNode: <BorderIcon title="Border-Width" />,
+                          placeholder: props[name],
                         })
-                      : name === "backgroundImagePosition" || name === "headerBackgroundImagePosition" || name === "footerBackgroundImagePosition"
-                      ? (	
-                          children[name] as InstanceType<typeof StringControl>	
-                        ).propertyView({	
-                          label: config.label,	
-                          preInputNode: <StyledBackgroundImageIcon title="Background Image Position" />,	
-                          placeholder: props[name],	
-                        })
-                      : name === "backgroundImageOrigin" || name === "headerBackgroundImageOrigin" || name === "footerBackgroundImageOrigin"
-                      ? (	
-                          children[name] as InstanceType<typeof StringControl>	
-                        ).propertyView({	
-                          label: config.label,	
-                          preInputNode: <StyledBackgroundImageIcon title="Background Image Origin" />,	
-                          placeholder: props[name],	
-                        })
-                      : children[name].propertyView({	
-                          label: config.label,	
-                          panelDefaultColor: props[name],	
-                          // isDep: isDepColorConfig(config),	
-                          isDep: true,	
-                          depMsg: depMsg,	
-                        })}	
+                        : name === "margin"
+                          ? (
+                            children[name] as InstanceType<typeof StringControl>
+                          ).propertyView({
+                            label: config.label,
+                            preInputNode: <MarginIcon title="Margin" />,
+                            placeholder: props[name],
+                          })
+                          : (name === "padding" ||
+                            name === "containerheaderpadding" ||
+                            name === "containerfooterpadding" ||
+                            name === "containerbodypadding")
+                            ? (
+                              children[name] as InstanceType<typeof StringControl>
+                            ).propertyView({
+                              label: config.label,
+                              preInputNode: <PaddingIcon title="Padding" />,
+                              placeholder: props[name],
+                            })
+                            : name === "textSize"
+                              ? (
+                                children[name] as InstanceType<typeof StringControl>
+                              ).propertyView({
+                                label: config.label,
+                                preInputNode: <StyledTextSizeIcon title="Font Size" />,
+                                placeholder: props[name],
+                              })
+                              : name === "textWeight"
+                                ? (
+                                  children[name] as InstanceType<typeof StringControl>
+                                ).propertyView({
+                                  label: config.label,
+                                  preInputNode: <StyledTextWeightIcon title="Font Weight" />,
+                                  placeholder: props[name],
+                                })
+                                : name === "fontFamily"
+                                  ? (
+                                    children[name] as InstanceType<typeof StringControl>
+                                  ).propertyView({
+                                    label: config.label,
+                                    preInputNode: <StyledFontFamilyIcon title="Font Family" />,
+                                    placeholder: props[name],
+                                  })
+                                  : name === "fontStyle"
+                                    ? (
+                                      children[name] as InstanceType<typeof StringControl>
+                                    ).propertyView({
+                                      label: config.label,
+                                      preInputNode: <StyledFontFamilyIcon title="Font Style" />,
+                                      placeholder: props[name],
+                                    })
+                                    : name === "backgroundImage" || name === "headerBackgroundImage" || name === "footerBackgroundImage"
+                                      ? (
+                                        children[name] as InstanceType<typeof StringControl>
+                                      ).propertyView({
+                                        label: config.label,
+                                        preInputNode: <StyledBackgroundImageIcon title="Background Image" />,
+                                        placeholder: props[name],
+                                      })
+                                      : name === "backgroundImageRepeat" || name === "headerBackgroundImageRepeat" || name === "footerBackgroundImageRepeat"
+                                        ? (
+                                          children[name] as InstanceType<typeof StringControl>
+                                        ).propertyView({
+                                          label: config.label,
+                                          preInputNode: <StyledBackgroundImageIcon title="Background Image Repeat" />,
+                                          placeholder: props[name],
+                                        })
+                                        : name === "backgroundImageSize" || name === "headerBackgroundImageSize" || name === "footerBackgroundImageSize"
+                                          ? (
+                                            children[name] as InstanceType<typeof StringControl>
+                                          ).propertyView({
+                                            label: config.label,
+                                            preInputNode: <StyledBackgroundImageIcon title="Background Image Size" />,
+                                            placeholder: props[name],
+                                          })
+                                          : name === "backgroundImagePosition" || name === "headerBackgroundImagePosition" || name === "footerBackgroundImagePosition"
+                                            ? (
+                                              children[name] as InstanceType<typeof StringControl>
+                                            ).propertyView({
+                                              label: config.label,
+                                              preInputNode: <StyledBackgroundImageIcon title="Background Image Position" />,
+                                              placeholder: props[name],
+                                            })
+                                            : name === "backgroundImageOrigin" || name === "headerBackgroundImageOrigin" || name === "footerBackgroundImageOrigin"
+                                              ? (
+                                                children[name] as InstanceType<typeof StringControl>
+                                              ).propertyView({
+                                                label: config.label,
+                                                preInputNode: <StyledBackgroundImageIcon title="Background Image Origin" />,
+                                                placeholder: props[name],
+                                              })
+                                              : children[name].propertyView({
+                                                label: config.label,
+                                                panelDefaultColor: props[name],
+                                                // isDep: isDepColorConfig(config),	
+                                                isDep: true,
+                                                depMsg: depMsg,
+                                              })}
                   </div>
                 );
               })}
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index 5dea81d301..3df7ba687a 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -1,7 +1,7 @@
 import { ThemeDetail } from "api/commonSettingApi";
 import { darkenColor, isDarkColor, lightenColor, toHex } from "lowcoder-design";
 import { trans } from "i18n";
-import { StyleConfigType } from "./styleControl"; 
+import { StyleConfigType } from "./styleControl";
 
 type SupportPlatform = "pc" | "mobile";
 
@@ -23,21 +23,21 @@ export type BorderWidthConfig = CommonColorConfig & {
 
 export type BackgroundImageConfig = CommonColorConfig & { readonly backgroundImage: string; };
 export type BackgroundImageRepeatConfig = CommonColorConfig & { readonly backgroundImageRepeat: string; };
-export type BackgroundImageSizeConfig = CommonColorConfig & { readonly backgroundImageSize: string;};
+export type BackgroundImageSizeConfig = CommonColorConfig & { readonly backgroundImageSize: string; };
 export type BackgroundImagePositionConfig = CommonColorConfig & { readonly backgroundImagePosition: string; };
-export type BackgroundImageOriginConfig = CommonColorConfig & { readonly backgroundImageOrigin: string;};
+export type BackgroundImageOriginConfig = CommonColorConfig & { readonly backgroundImageOrigin: string; };
 
 export type HeaderBackgroundImageConfig = CommonColorConfig & { readonly headerBackgroundImage: string; };
 export type HeaderBackgroundImageRepeatConfig = CommonColorConfig & { readonly headerBackgroundImageRepeat: string; };
-export type HeaderBackgroundImageSizeConfig = CommonColorConfig & { readonly headerBackgroundImageSize: string;};
+export type HeaderBackgroundImageSizeConfig = CommonColorConfig & { readonly headerBackgroundImageSize: string; };
 export type HeaderBackgroundImagePositionConfig = CommonColorConfig & { readonly headerBackgroundImagePosition: string; };
-export type HeaderBackgroundImageOriginConfig = CommonColorConfig & { readonly headerBackgroundImageOrigin: string;};
+export type HeaderBackgroundImageOriginConfig = CommonColorConfig & { readonly headerBackgroundImageOrigin: string; };
 
 export type FooterBackgroundImageConfig = CommonColorConfig & { readonly footerBackgroundImage: string; };
 export type FooterBackgroundImageRepeatConfig = CommonColorConfig & { readonly footerBackgroundImageRepeat: string; };
-export type FooterBackgroundImageSizeConfig = CommonColorConfig & { readonly footerBackgroundImageSize: string;};
+export type FooterBackgroundImageSizeConfig = CommonColorConfig & { readonly footerBackgroundImageSize: string; };
 export type FooterBackgroundImagePositionConfig = CommonColorConfig & { readonly footerBackgroundImagePosition: string; };
-export type FooterBackgroundImageOriginConfig = CommonColorConfig & { readonly footerBackgroundImageOrigin: string;};
+export type FooterBackgroundImageOriginConfig = CommonColorConfig & { readonly footerBackgroundImageOrigin: string; };
 
 export type TextSizeConfig = CommonColorConfig & {
   readonly textSize: string;
@@ -51,6 +51,10 @@ export type FontFamilyConfig = CommonColorConfig & {
   readonly fontFamily: string;
 };
 
+export type FontStyleConfig = CommonColorConfig & {
+  readonly fontStyle: string;
+}
+
 export type ContainerHeaderPaddigConfig = CommonColorConfig & {
   readonly containerheaderpadding: string;
 };
@@ -63,11 +67,11 @@ export type ContainerFooterPaddigConfig = CommonColorConfig & {
   readonly containerfooterpadding: string;
 };
 
-export type MarginConfig = CommonColorConfig & {	
-  readonly margin: string;	
-};	
-export type PaddingConfig = CommonColorConfig & {	
-  readonly padding: string;	
+export type MarginConfig = CommonColorConfig & {
+  readonly margin: string;
+};
+export type PaddingConfig = CommonColorConfig & {
+  readonly padding: string;
 };
 
 export type DepColorConfig = CommonColorConfig & {
@@ -76,7 +80,7 @@ export type DepColorConfig = CommonColorConfig & {
   readonly depType?: DEP_TYPE;
   transformer: (color: string, ...rest: string[]) => string;
 };
-export type SingleColorConfig = SimpleColorConfig | DepColorConfig | RadiusConfig | BorderWidthConfig | BackgroundImageConfig | BackgroundImageRepeatConfig | BackgroundImageSizeConfig | BackgroundImagePositionConfig | BackgroundImageOriginConfig | TextSizeConfig | TextWeightConfig | FontFamilyConfig | MarginConfig | PaddingConfig | ContainerHeaderPaddigConfig | ContainerFooterPaddigConfig | ContainerBodyPaddigConfig | HeaderBackgroundImageConfig | HeaderBackgroundImageRepeatConfig | HeaderBackgroundImageSizeConfig | HeaderBackgroundImagePositionConfig | HeaderBackgroundImageOriginConfig | FooterBackgroundImageConfig | FooterBackgroundImageRepeatConfig | FooterBackgroundImageSizeConfig | FooterBackgroundImagePositionConfig | FooterBackgroundImageOriginConfig;
+export type SingleColorConfig = SimpleColorConfig | DepColorConfig | RadiusConfig | BorderWidthConfig | BackgroundImageConfig | BackgroundImageRepeatConfig | BackgroundImageSizeConfig | BackgroundImagePositionConfig | BackgroundImageOriginConfig | TextSizeConfig | TextWeightConfig | FontFamilyConfig | FontStyleConfig | MarginConfig | PaddingConfig | ContainerHeaderPaddigConfig | ContainerFooterPaddigConfig | ContainerBodyPaddigConfig | HeaderBackgroundImageConfig | HeaderBackgroundImageRepeatConfig | HeaderBackgroundImageSizeConfig | HeaderBackgroundImagePositionConfig | HeaderBackgroundImageOriginConfig | FooterBackgroundImageConfig | FooterBackgroundImageRepeatConfig | FooterBackgroundImageSizeConfig | FooterBackgroundImagePositionConfig | FooterBackgroundImageOriginConfig;
 
 export const defaultTheme: ThemeDetail = {
   primary: "#3377FF",
@@ -85,7 +89,7 @@ export const defaultTheme: ThemeDetail = {
   canvas: "#F5F5F6",
   primarySurface: "#FFFFFF",
   borderRadius: "4px",
-  margin: "3px",	
+  margin: "3px",
   padding: "3px",
   gridColumns: "24",
   textSize: "14px",
@@ -322,61 +326,67 @@ const BACKGROUND_IMAGE_ORIGIN = {
   backgroundImageOrigin: "backgroundImageOrigin",
 } as const;
 
-const MARGIN = {	
-  name: "margin",	
-  label: trans("style.margin"),	
-  margin: "margin",	
-} as const;	
+const MARGIN = {
+  name: "margin",
+  label: trans("style.margin"),
+  margin: "margin",
+} as const;
 
-const PADDING = {	
-  name: "padding",	
-  label: trans("style.padding"),	
-  padding: "padding",	
+const PADDING = {
+  name: "padding",
+  label: trans("style.padding"),
+  padding: "padding",
 } as const;
 
-const TEXT_SIZE = {	
+const TEXT_SIZE = {
   name: "textSize",
-  label: trans("style.textSize"),	
-  textSize: "textSize",	
+  label: trans("style.textSize"),
+  textSize: "textSize",
 } as const;
 
-const TEXT_WEIGHT = {	
+const TEXT_WEIGHT = {
   name: "textWeight",
-  label: trans("style.textWeight"),	
-  textWeight: "textWeight",	
+  label: trans("style.textWeight"),
+  textWeight: "textWeight",
 } as const;
 
-const FONT_FAMILY = {	
+const FONT_FAMILY = {
   name: "fontFamily",
-  label: trans("style.fontFamily"),	
-  fontFamily: "fontFamily",	
+  label: trans("style.fontFamily"),
+  fontFamily: "fontFamily",
 } as const;
 
-const CONTAINERHEADERPADDING = {	
-  name: "containerheaderpadding",	
-  label: trans("style.containerheaderpadding"),	
-  containerheaderpadding: "padding",	
+const FONT_STYLE = {
+  name: "fontStyle",
+  label: trans("style.fontStyle"),
+  fontStyle: "fontStyle",
+} as const
+
+const CONTAINERHEADERPADDING = {
+  name: "containerheaderpadding",
+  label: trans("style.containerheaderpadding"),
+  containerheaderpadding: "padding",
 } as const;
 
-const CONTAINERFOOTERPADDING = {	
-  name: "containerfooterpadding",	
-  label: trans("style.containerfooterpadding"),	
-  containerfooterpadding: "padding",	
+const CONTAINERFOOTERPADDING = {
+  name: "containerfooterpadding",
+  label: trans("style.containerfooterpadding"),
+  containerfooterpadding: "padding",
 } as const;
 
 
-const CONTAINERBODYPADDING = {	
-  name: "containerbodypadding",	
-  label: trans("style.containerbodypadding"),	
-  containerbodypadding: "padding",	
+const CONTAINERBODYPADDING = {
+  name: "containerbodypadding",
+  label: trans("style.containerbodypadding"),
+  containerbodypadding: "padding",
 } as const;
 
 const getStaticBorder = (color: string = SECOND_SURFACE_COLOR) =>
-  ({
-    name: "border",
-    label: trans("style.border"),
-    color,
-  } as const);
+({
+  name: "border",
+  label: trans("style.border"),
+  color,
+} as const);
 
 const HEADER_BACKGROUND = {
   name: "headerBackground",
@@ -439,13 +449,13 @@ function getStaticBackground(color: string) {
 }
 
 export const ButtonStyle = [
-  ...getBgBorderRadiusByBg("primary"), 
+  ...getBgBorderRadiusByBg("primary"),
   BORDER_WIDTH,
-  TEXT, 
+  TEXT,
   TEXT_SIZE,
   TEXT_WEIGHT,
   FONT_FAMILY,
-  MARGIN, 
+  MARGIN,
   PADDING
 ] as const;
 
@@ -464,7 +474,7 @@ export const ToggleButtonStyle = [
   TEXT_SIZE,
   TEXT_WEIGHT,
   FONT_FAMILY,
-  MARGIN,	
+  MARGIN,
   PADDING,
 ] as const;
 
@@ -480,8 +490,9 @@ export const TextStyle = [
   TEXT_SIZE,
   TEXT_WEIGHT,
   FONT_FAMILY,
+  FONT_STYLE,
   BORDER,
-  MARGIN,	
+  MARGIN,
   PADDING,
   {
     name: "links",
@@ -491,16 +502,16 @@ export const TextStyle = [
     transformer: toSelf,
   },
   RADIUS,
-  BORDER_WIDTH
+  BORDER_WIDTH,
 ] as const;
 
-export const MarginStyle = [	
-  {	
-    name: "margin",	
-    label: trans("style.margin"),	
-    margin: "margin",	
-  },	
-];	
+export const MarginStyle = [
+  {
+    name: "margin",
+    label: trans("style.margin"),
+    margin: "margin",
+  },
+];
 
 
 export const ContainerStyle = [
@@ -508,7 +519,7 @@ export const ContainerStyle = [
   getStaticBorder(),
   RADIUS,
   BORDER_WIDTH,
-  MARGIN,	
+  MARGIN,
   PADDING,
   {
     name: "background",
@@ -567,7 +578,7 @@ export const ContainerHeaderStyle = [
     label: trans("style.backgroundImagePosition"),
     headerBackgroundImagePosition: "headerBackgroundImagePosition",
   }
-  ,{
+  , {
     name: "headerBackgroundImageOrigin",
     label: trans("style.backgroundImageOrigin"),
     headerBackgroundImageOrigin: "headerBackgroundImageOrigin",
@@ -639,7 +650,7 @@ export const ContainerFooterStyle = [
     label: trans("style.backgroundImagePosition"),
     footerBackgroundImagePosition: "footerBackgroundImagePosition",
   }
-  ,{
+  , {
     name: "footerBackgroundImageOrigin",
     label: trans("style.backgroundImageOrigin"),
     footerBackgroundImageOrigin: "footerBackgroundImageOrigin",
@@ -662,7 +673,7 @@ export const SliderStyle = [
     color: SURFACE_COLOR,
   },
   TRACK,
-  MARGIN,	
+  MARGIN,
   PADDING,
 ] as const;
 
@@ -674,7 +685,7 @@ export const InputLikeStyle = [
   TEXT_SIZE,
   TEXT_WEIGHT,
   FONT_FAMILY,
-  MARGIN,	
+  MARGIN,
   PADDING,
   ...ACCENT_VALIDATE,
 ] as const;
@@ -691,7 +702,7 @@ export const RatingStyle = [
     label: trans("style.unchecked"),
     color: SECOND_SURFACE_COLOR,
   },
-  MARGIN,	
+  MARGIN,
   PADDING,
 ] as const;
 
@@ -715,7 +726,7 @@ export const SwitchStyle = [
     depType: DEP_TYPE.SELF,
     transformer: toSelf,
   },
-  MARGIN,	
+  MARGIN,
   PADDING,
 ] as const;
 
@@ -723,7 +734,7 @@ export const SelectStyle = [
   LABEL,
   ...getStaticBgBorderRadiusByBg(SURFACE_COLOR, "pc"),
   TEXT,
-  MARGIN,	
+  MARGIN,
   PADDING,
   ...ACCENT_VALIDATE,
 ] as const;
@@ -732,7 +743,7 @@ const multiSelectCommon = [
   LABEL,
   ...getStaticBgBorderRadiusByBg(SURFACE_COLOR, "pc"),
   TEXT,
-  MARGIN,	
+  MARGIN,
   PADDING,
   {
     name: "tags",
@@ -784,7 +795,7 @@ export const TabContainerStyle = [
 export const ModalStyle = [
   ...getBgBorderRadiusByBg(),
   BORDER_WIDTH,
-  MARGIN,	
+  MARGIN,
   PADDING,
   BACKGROUND_IMAGE,
   BACKGROUND_IMAGE_REPEAT,
@@ -798,7 +809,7 @@ export const CascaderStyle = [
   ...getStaticBgBorderRadiusByBg(SURFACE_COLOR, "pc"),
   TEXT,
   ACCENT,
-  MARGIN,	
+  MARGIN,
   PADDING,
 ] as const;
 
@@ -838,7 +849,7 @@ export const CheckboxStyle = [
   RADIUS,
   STATIC_TEXT,
   VALIDATE,
-  MARGIN,	
+  MARGIN,
   PADDING,
 ] as const;
 
@@ -854,7 +865,7 @@ export const RadioStyle = [
   },
   STATIC_TEXT,
   VALIDATE,
-  MARGIN,	
+  MARGIN,
   PADDING,
 ] as const;
 
@@ -880,7 +891,7 @@ export const SegmentStyle = [
   },
   RADIUS,
   VALIDATE,
-  MARGIN,	
+  MARGIN,
   PADDING,
 ] as const;
 
@@ -1001,7 +1012,7 @@ export const FileViewerStyle = [
   getStaticBackground("#FFFFFF"),
   getStaticBorder("#00000000"),
   RADIUS,
-  MARGIN,	
+  MARGIN,
   PADDING,
   BORDER_WIDTH
 ] as const;
@@ -1012,7 +1023,7 @@ export const DateTimeStyle = [
   LABEL,
   ...getStaticBgBorderRadiusByBg(SURFACE_COLOR),
   TEXT,
-  MARGIN,	
+  MARGIN,
   PADDING,
   ...ACCENT_VALIDATE,
 ] as const;
@@ -1027,7 +1038,7 @@ function handleToHoverLink(color: string) {
 
 export const LinkStyle = [
   ...LinkTextStyle,
-  MARGIN,	
+  MARGIN,
   PADDING,
   TEXT_SIZE
 ] as const;
@@ -1039,7 +1050,7 @@ export const DividerStyle = [
     color: lightenColor(SECOND_SURFACE_COLOR, 0.05),
   },
   BORDER_WIDTH,
-  MARGIN,	
+  MARGIN,
   PADDING,
   {
     name: "text",
@@ -1063,7 +1074,7 @@ export const ProgressStyle = [
   TRACK,
   FILL,
   SUCCESS,
-  MARGIN,	
+  MARGIN,
   PADDING,
 ] as const;
 
@@ -1078,7 +1089,7 @@ export const NavigationStyle = [
   ACCENT,
   getStaticBackground("#FFFFFF00"),
   getStaticBorder("#FFFFFF00"),
-  MARGIN,	
+  MARGIN,
   PADDING,
 ] as const;
 
@@ -1095,7 +1106,7 @@ export const QRCodeStyle = [
     label: trans("color"),
     color: "#000000",
   },
-  MARGIN,	
+  MARGIN,
   PADDING,
   BORDER,
   RADIUS,
@@ -1119,7 +1130,7 @@ export const TimeLineStyle = [
     label: trans("timeLine.subTitleColor"),
     color: "#848484",
   },
-  MARGIN,	
+  MARGIN,
   PADDING,
   RADIUS
 ] as const;
@@ -1199,7 +1210,7 @@ export const SignatureStyle = [
     label: trans("style.footerIcon"),
     color: "#222222",
   },
-  MARGIN,	
+  MARGIN,
   PADDING,
   BORDER_WIDTH
 ] as const;
@@ -1213,7 +1224,7 @@ export const LottieStyle = [
     depType: DEP_TYPE.SELF,
     transformer: toSelf,
   },
-  MARGIN,	
+  MARGIN,
   PADDING,
 ] as const;
 /////////////////////
@@ -1225,19 +1236,19 @@ export const CommentStyle = [
     depType: DEP_TYPE.SELF,
     transformer: toSelf,
   },
-  MARGIN,	
+  MARGIN,
   PADDING,
   RADIUS,
 ] as const
 export const ResponsiveLayoutRowStyle = [
   ...BG_STATIC_BORDER_RADIUS,
-  MARGIN,	
+  MARGIN,
   PADDING,
 ] as const;
 
 export const ResponsiveLayoutColStyle = [
   ...BG_STATIC_BORDER_RADIUS,
-  MARGIN,	
+  MARGIN,
   PADDING,
 ] as const;
 
@@ -1297,9 +1308,9 @@ export const NavLayoutItemActiveStyle = [
 export const CarouselStyle = [getBackground("canvas")] as const;
 
 export const RichTextEditorStyle = [
-  getStaticBorder(), 
-  getBackground("primarySurface"), 
-  RADIUS, 
+  getStaticBorder(),
+  getBackground("primarySurface"),
+  RADIUS,
   BORDER_WIDTH
 ] as const;
 
@@ -1354,43 +1365,36 @@ export type NavLayoutItemHoverStyleType = StyleConfigType<typeof NavLayoutItemHo
 export type NavLayoutItemActiveStyleType = StyleConfigType<typeof NavLayoutItemActiveStyle>;
 
 export function widthCalculator(margin: string) {
-  const marginArr = margin?.trim().replace(/\s+/g,' ').split(" ") || "";
+  const marginArr = margin?.trim().replace(/\s+/g, ' ').split(" ") || "";
   if (marginArr.length === 1) {
-    return `calc(100% - ${
-      parseInt(margin.replace(/[^\d.]/g, "")) * 2 + 
+    return `calc(100% - ${parseInt(margin.replace(/[^\d.]/g, "")) * 2 +
       (margin.replace(/[0-9]/g, "") || "px")
-    })`;
+      })`;
   } else if (marginArr.length === 2 || marginArr.length === 3) {
-    return `calc(100% - ${
-      parseInt(marginArr[1].replace(/[^\d.]/g, "")) * 2 +
+    return `calc(100% - ${parseInt(marginArr[1].replace(/[^\d.]/g, "")) * 2 +
       (marginArr[1].replace(/[0-9]/g, "") || 'px')
-    })`;
+      })`;
   } else {
-    return `calc(100% - ${
-      parseInt(marginArr[1]?.replace(/[^\d.]/g, "") || "0") +
+    return `calc(100% - ${parseInt(marginArr[1]?.replace(/[^\d.]/g, "") || "0") +
       (marginArr[1]?.replace(/[0-9]/g, "") || "px")
-    } - ${
-      parseInt(marginArr[3]?.replace(/[^\d.]/g, "") || "0") +
+      } - ${parseInt(marginArr[3]?.replace(/[^\d.]/g, "") || "0") +
       (marginArr[3]?.replace(/[0-9]/g, "") || "px")
-    })`;
+      })`;
   }
 }
 
 export function heightCalculator(margin: string) {
   const marginArr = margin?.trim().split(" ") || "";
   if (marginArr.length === 1 || marginArr.length === 2) {
-    return `calc(100% - ${
-      parseInt(marginArr[0].replace(/[^\d.]/g, "")) * 2 + 
+    return `calc(100% - ${parseInt(marginArr[0].replace(/[^\d.]/g, "")) * 2 +
       (marginArr[0].replace(/[0-9]/g, "") || 'px')
-    })`;
-  }else if(marginArr.length >2){
-    return `calc(100% - ${
-      parseInt(marginArr[0]?.replace(/[^\d.]/g, "") || "0") +
+      })`;
+  } else if (marginArr.length > 2) {
+    return `calc(100% - ${parseInt(marginArr[0]?.replace(/[^\d.]/g, "") || "0") +
       (marginArr[0]?.replace(/[0-9]/g, "") || "px")
-    } - ${
-      parseInt(marginArr[2]?.replace(/[^\d.]/g, "") || "0") +
+      } - ${parseInt(marginArr[2]?.replace(/[^\d.]/g, "") || "0") +
       (marginArr[2]?.replace(/[0-9]/g, "") || "px")
-    })`;
+      })`;
   }
 }
 
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index 9cc91a970f..fc05496d41 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -361,6 +361,7 @@ export const en = {
     "textSize": "Text Size",
     "textWeight": "Text Weight",
     "fontFamily": "Font Family",
+    "fontStyle":"Font Style",
     "backgroundImage": "BG Image",
     "backgroundImageRepeat": "BG Repeat",
     "backgroundImageSize": "BG Size",

From b0f8e670e92005dfdc9fc8e5beeb52535b47ff61 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Wed, 14 Feb 2024 21:38:10 +0500
Subject: [PATCH 36/97] listView doesn't expose component updates for child
 components

---
 .../src/comps/comps/listViewComp/listView.tsx |  5 ++-
 .../comps/comps/listViewComp/listViewComp.tsx | 14 +++++--
 .../lowcoder/src/comps/comps/ratingComp.tsx   | 22 ++++++++--
 .../comps/selectInputComp/checkboxComp.tsx    | 12 +++---
 .../comps/selectInputComp/multiSelectComp.tsx | 16 +++----
 .../comps/comps/selectInputComp/radioComp.tsx |  9 ++--
 .../selectInputComp/radioCompConstants.tsx    |  6 ++-
 .../selectInputComp/segmentedControl.tsx      | 13 +++---
 .../comps/selectInputComp/selectComp.tsx      | 14 +++----
 .../selectInputComp/selectCompConstants.tsx   |  3 +-
 .../selectInputComp/selectInputConstants.tsx  | 42 +++++++++++++++++--
 .../src/comps/comps/tableComp/tableUtils.tsx  |  1 -
 .../textInputComp/textInputConstants.tsx      | 19 +++++++--
 .../comps/comps/treeComp/treeSelectComp.tsx   | 10 +++--
 .../src/comps/comps/treeComp/treeUtils.tsx    |  6 ++-
 .../src/comps/controls/optionsControl.tsx     |  1 +
 16 files changed, 141 insertions(+), 52 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/listViewComp/listView.tsx b/client/packages/lowcoder/src/comps/comps/listViewComp/listView.tsx
index 97319c64ed..b45bc755bc 100644
--- a/client/packages/lowcoder/src/comps/comps/listViewComp/listView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/listViewComp/listView.tsx
@@ -176,7 +176,10 @@ export function ListView(props: Props) {
               return <div key={itemIdx} style={{ flex: "auto" }}></div>;
             }
             const containerProps = containerFn(
-              { [itemIndexName]: itemIdx, [itemDataName]: getCurrentItemParams(data, itemIdx) },
+              {
+                [itemIndexName]: itemIdx,
+                [itemDataName]: getCurrentItemParams(data, itemIdx)
+              },
               String(itemIdx)
             ).getView();
             const unMountFn = () => {
diff --git a/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx b/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx
index 5df6f33f75..c9a28811da 100644
--- a/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx
@@ -7,7 +7,7 @@ import {
 } from "comps/controls/codeControl";
 import { styleControl } from "comps/controls/styleControl";
 import { ListViewStyle } from "comps/controls/styleControlConstants";
-import { UICompBuilder, withDefault, withPropertyViewFn, withViewFn } from "comps/generators";
+import { UICompBuilder, stateComp, valueComp, withDefault, withPropertyViewFn, withViewFn } from "comps/generators";
 import {
   CompDepsConfig,
   depsConfig,
@@ -80,10 +80,10 @@ export class ListViewImplComp extends ListViewTmpComp implements IContainer {
   }
   override reduce(action: CompAction): this {
     // console.info("listView reduce. action: ", action);
-
     let comp = reduceInContext({ inEventContext: true }, () => super.reduce(action));
+
     if (action.type === CompActionTypes.UPDATE_NODES_V2) {
-      const { itemCount } = getData(comp.children.noOfRows.getView());
+      const { itemCount} = getData(comp.children.noOfRows.getView());
       const pagination = comp.children.pagination.getView();
       const total = pagination.total || itemCount;
       const offset = (pagination.current - 1) * pagination.pageSize;
@@ -171,6 +171,12 @@ export const ListViewComp = withExposingConfigs(ListViewPropertyComp, [
       return data;
     },
   }),
+  // new CompDepsConfig(
+  //   "index",
+  //   (comp) => ({index: comp.children.itemIndexName.node() }),
+  //   (input) => input.index.value,
+  //   "index", // trans("listView.itemsDesc")
+  // ),
   NameConfigHidden,
 ]);
 
@@ -232,7 +238,7 @@ export function defaultListViewData(compName: string, nameGenerator: NameGenerat
           compType: "rating",
           name: nameGenerator.genItemName("rating"),
           comp: {
-            value: "{{currentItem.rate / 2}}",
+            defaultValue: "{{currentItem.rate / 2}}",
             max: "5",
             label: {
               text: "",
diff --git a/client/packages/lowcoder/src/comps/comps/ratingComp.tsx b/client/packages/lowcoder/src/comps/comps/ratingComp.tsx
index 992c45f742..40db580ab0 100644
--- a/client/packages/lowcoder/src/comps/comps/ratingComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/ratingComp.tsx
@@ -15,7 +15,7 @@ import { migrateOldData } from "comps/generators/simpleGenerators";
 import { disabledPropertyView, hiddenPropertyView } from "comps/utils/propertyUtils";
 import { trans } from "i18n";
 
-import { useContext } from "react";
+import { useContext, useEffect, useRef } from "react";
 import { EditorContext } from "comps/editorState";
 
 const EventOptions = [changeEvent] as const;
@@ -36,6 +36,7 @@ function fixOldData(oldData: any) {
 
 const RatingBasicComp = (function () {
   const childrenMap = {
+    defaultValue: numberExposingStateControl("defaultValue"),
     value: numberExposingStateControl("value"),
     max: withDefault(NumberControl, "5"),
     label: LabelControl,
@@ -46,6 +47,21 @@ const RatingBasicComp = (function () {
     ...formDataChildren,
   };
   return new UICompBuilder(childrenMap, (props) => {
+    const defaultValue = { ...props.defaultValue }.value;
+    const value = { ...props.value }.value;
+    const changeRef = useRef(false)
+
+    useEffect(() => {
+      props.value.onChange(defaultValue);
+    }, [defaultValue]);
+
+    useEffect(() => {
+      if (!changeRef.current) return;
+
+      props.onEvent("change");
+      changeRef.current = false;
+    }, [value]);
+
     return props.label({
       style: props.style,
       children: (
@@ -54,7 +70,7 @@ const RatingBasicComp = (function () {
           value={props.value.value}
           onChange={(e) => {
             props.value.onChange(e);
-            props.onEvent("change");
+            changeRef.current = true;
           }}
           allowHalf={props.allowHalf}
           disabled={props.disabled}
@@ -67,7 +83,7 @@ const RatingBasicComp = (function () {
       return (
         <>
           <Section name={sectionNames.basic}>
-            {children.value.propertyView({ label: trans("prop.defaultValue") })}
+            {children.defaultValue.propertyView({ label: trans("prop.defaultValue") })}
             {children.max.propertyView({
               label: trans("rating.max"),
             })}
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx
index 8152980d56..f30b92c459 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx
@@ -102,7 +102,8 @@ const CheckboxGroup = styled(AntdCheckboxGroup)<{
 
 const CheckboxBasicComp = (function () {
   const childrenMap = {
-    value: arrayStringExposingStateControl("value", ["1"]),
+    defaultValue: arrayStringExposingStateControl("defaultValue"),
+    value: arrayStringExposingStateControl("value"),
     label: LabelControl,
     disabled: BoolCodeControl,
     onEvent: ChangeEventHandlerControl,
@@ -115,7 +116,10 @@ const CheckboxBasicComp = (function () {
     ...formDataChildren,
   };
   return new UICompBuilder(childrenMap, (props) => {
-    const [validateState, handleValidate] = useSelectInputValidate(props);
+    const [
+      validateState,
+      handleChange,
+    ] = useSelectInputValidate(props);
     return props.label({
       required: props.required,
       style: props.style,
@@ -134,9 +138,7 @@ const CheckboxBasicComp = (function () {
               disabled: option.disabled,
             }))}
           onChange={(values) => {
-            handleValidate(values as string[]);
-            props.value.onChange(values as string[]);
-            props.onEvent("change");
+            handleChange(values as string[]);
           }}
         />
       ),
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/multiSelectComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/multiSelectComp.tsx
index c052f89fb9..a8c2c0dc11 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/multiSelectComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/multiSelectComp.tsx
@@ -14,18 +14,24 @@ import { SelectInputInvalidConfig, useSelectInputValidate } from "./selectInputC
 
 import { PaddingControl } from "../../controls/paddingControl";	
 import { MarginControl } from "../../controls/marginControl";
+import { useEffect, useRef } from "react";
 
 const MultiSelectBasicComp = (function () {
   const childrenMap = {
     ...SelectChildrenMap,
-    value: arrayStringExposingStateControl("value", ["1", "2"]),
+    defaultValue: arrayStringExposingStateControl("defaultValue", ["1", "2"]),
+    value: arrayStringExposingStateControl("value"),
     style: styleControl(MultiSelectStyle),
     margin: MarginControl,	
     padding: PaddingControl,
   };
   return new UICompBuilder(childrenMap, (props, dispatch) => {
     const valueSet = new Set<any>(props.options.map((o) => o.value)); // Filter illegal default values entered by the user
-    const [validateState, handleValidate] = useSelectInputValidate(props);
+    const [
+      validateState,
+      handleChange,
+    ] = useSelectInputValidate(props);
+    
     return props.label({
       required: props.required,
       style: props.style,
@@ -34,11 +40,7 @@ const MultiSelectBasicComp = (function () {
           {...props}
           mode={"multiple"}
           value={props.value.value.filter?.((v) => valueSet.has(v))}
-          onChange={(value) => {
-            handleValidate(value);
-            props.value.onChange(value);
-            props.onEvent("change");
-          }}
+          onChange={handleChange}
           dispatch={dispatch}
         />
       ),
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx
index e1bc7033ce..494a3b24fe 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx
@@ -83,7 +83,10 @@ const Radio = styled(AntdRadioGroup)<{
 
 const RadioBasicComp = (function () {
   return new UICompBuilder(RadioChildrenMap, (props) => {
-    const [validateState, handleValidate] = useSelectInputValidate(props);
+    const [
+      validateState,
+      handleChange,
+    ] = useSelectInputValidate(props);
     return props.label({
       required: props.required,
       style: props.style,
@@ -95,9 +98,7 @@ const RadioBasicComp = (function () {
           $style={props.style}
           $layout={props.layout}
           onChange={(e) => {
-            handleValidate(e.target.value);
-            props.value.onChange(e.target.value);
-            props.onEvent("change");
+            handleChange(e.target.value);
           }}
           options={props.options
             .filter((option) => option.value !== undefined && !option.hidden)
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioCompConstants.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioCompConstants.tsx
index f84180dd0f..56cf0c8c06 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioCompConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioCompConstants.tsx
@@ -30,6 +30,7 @@ export const RadioLayoutOptions = [
 ] as const;
 
 export const RadioChildrenMap = {
+  defaultValue: stringExposingStateControl("value"),
   value: stringExposingStateControl("value"),
   label: LabelControl,
   disabled: BoolCodeControl,
@@ -46,6 +47,9 @@ export const RadioChildrenMap = {
 export const RadioPropertyView = (
   children: RecordConstructorToComp<
     typeof RadioChildrenMap & { hidden: typeof BoolCodeControl } & {
+      defaultValue:
+        | ReturnType<typeof stringExposingStateControl>
+        | ReturnType<typeof arrayStringExposingStateControl>;
       value:
         | ReturnType<typeof stringExposingStateControl>
         | ReturnType<typeof arrayStringExposingStateControl>;
@@ -55,7 +59,7 @@ export const RadioPropertyView = (
   <>
     <Section name={sectionNames.basic}>
       {children.options.propertyView({})}
-      {children.value.propertyView({ label: trans("prop.defaultValue") })}
+      {children.defaultValue.propertyView({ label: trans("prop.defaultValue") })}
     </Section>
 
     {["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && (
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/segmentedControl.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/segmentedControl.tsx
index bf105982ae..6c82fd62bb 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/segmentedControl.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/segmentedControl.tsx
@@ -62,6 +62,7 @@ const Segmented = styled(AntdSegmented)<{ $style: SegmentStyleType }>`
 `;
 
 const SegmentChildrenMap = {
+  defaultValue: stringExposingStateControl("value"),
   value: stringExposingStateControl("value"),
   label: LabelControl,
   disabled: BoolCodeControl,
@@ -76,7 +77,11 @@ const SegmentChildrenMap = {
 
 const SegmentedControlBasicComp = (function () {
   return new UICompBuilder(SegmentChildrenMap, (props) => {
-    const [validateState, handleValidate] = useSelectInputValidate(props);
+    const [
+      validateState,
+      handleValidate,
+      handleChange,
+    ] = useSelectInputValidate(props);
     return props.label({
       required: props.required,
       style: props.style,
@@ -88,9 +93,7 @@ const SegmentedControlBasicComp = (function () {
           value={props.value.value}
           $style={props.style}
           onChange={(value) => {
-            handleValidate(value.toString());
-            props.value.onChange(value.toString());
-            props.onEvent("change");
+            handleChange(value.toString());
           }}
           options={props.options
             .filter((option) => option.value !== undefined && !option.hidden)
@@ -109,7 +112,7 @@ const SegmentedControlBasicComp = (function () {
       <>
         <Section name={sectionNames.basic}>
           {children.options.propertyView({})}
-          {children.value.propertyView({ label: trans("prop.defaultValue") })}
+          {children.defaultValue.propertyView({ label: trans("prop.defaultValue") })}
         </Section>
 
         {["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && (
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectComp.tsx
index 98c5b8bc84..1a30f25221 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectComp.tsx
@@ -21,16 +21,21 @@ import { RecordConstructorToView } from "lowcoder-core";
 const SelectBasicComp = (function () {
   const childrenMap = {
     ...SelectChildrenMap,
+    defaultValue: stringExposingStateControl("defaultValue"),
     value: stringExposingStateControl("value"),
     style: styleControl(SelectStyle),
   };
   return new UICompBuilder(childrenMap, (props, dispatch) => {
-    const [validateState, handleValidate] = useSelectInputValidate(props);
+    const [
+      validateState,
+      handleChange,
+    ] = useSelectInputValidate(props);
 
     const propsRef = useRef<RecordConstructorToView<typeof childrenMap>>(props);
     propsRef.current = props;
 
     const valueSet = new Set<any>(props.options.map((o) => o.value)); // Filter illegal default values entered by the user
+    
     return props.label({
       required: props.required,
       style: props.style,
@@ -38,12 +43,7 @@ const SelectBasicComp = (function () {
         <SelectUIView
           {...props}
           value={valueSet.has(props.value.value) ? props.value.value : undefined}
-          onChange={(value) => {
-            props.value.onChange(value ?? "").then(() => {
-              propsRef.current.onEvent("change");
-              handleValidate(value ?? "");
-            });
-          }}
+          onChange={handleChange}
           dispatch={dispatch}
         />
       ),
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
index 86493bf765..4f5a0ba18e 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
@@ -265,6 +265,7 @@ export const SelectPropertyView = (
       hidden: typeof BoolCodeControl;
     }
   > & {
+    defaultValue: { propertyView: (params: ControlParams) => ControlNode };
     value: { propertyView: (params: ControlParams) => ControlNode };
     style: { getPropertyView: () => ControlNode };
   }
@@ -272,7 +273,7 @@ export const SelectPropertyView = (
   <>
     <Section name={sectionNames.basic}>
       {children.options.propertyView({})}
-      {children.value.propertyView({ label: trans("prop.defaultValue") })}
+      {children.defaultValue.propertyView({ label: trans("prop.defaultValue") })}
       {placeholderPropertyView(children)}
     </Section>
 
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectInputConstants.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectInputConstants.tsx
index 8476a372cc..7c4fdc1268 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectInputConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectInputConstants.tsx
@@ -11,7 +11,7 @@ import {
 } from "../../controls/codeStateControl";
 import { requiredPropertyView } from "comps/utils/propertyUtils";
 import { trans } from "i18n";
-import { useRef, useState } from "react";
+import { useEffect, useRef, useState } from "react";
 import { SelectInputOptionControl } from "../../controls/optionsControl";
 import { refMethods } from "comps/generators/withMethodExposing";
 import { blurMethod, focusWithOptions } from "comps/utils/methodUtils";
@@ -22,10 +22,18 @@ export const SelectInputValidationChildren = {
 };
 type ValidationComp = RecordConstructorToComp<typeof SelectInputValidationChildren>;
 
+type SelectValue = string | (string | number)[];
 type ValidationParams = {
-  value: { value: string | (string | number)[] };
+  defaultValue?: {
+    value: SelectValue,
+  };
+  value: {
+    value: SelectValue,
+    onChange?: (value: any) => Promise<unknown>,
+  };
   required: boolean;
   customRule: string;
+  onEvent?: (eventName: string) => Promise<unknown[]>,
 };
 
 export const selectInputValidate = (
@@ -45,10 +53,14 @@ export const selectInputValidate = (
 };
 
 export const useSelectInputValidate = (props: ValidationParams) => {
+  const [validateState, setValidateState] = useState({});
+  const changeRef = useRef(false)
   const propsRef = useRef<ValidationParams>(props);
   propsRef.current = props;
 
-  const [validateState, setValidateState] = useState({});
+  const selectValue = props.value.value;
+  const defaultValue = props.defaultValue?.value;
+
   const handleValidate = (value: string | (string | number)[]) => {
     setValidateState(
       selectInputValidate({
@@ -59,7 +71,29 @@ export const useSelectInputValidate = (props: ValidationParams) => {
       })
     );
   };
-  return [validateState, handleValidate] as const;
+
+  useEffect(() => {
+    props.value.onChange?.(defaultValue)
+  }, [defaultValue]);
+  
+  useEffect(() => {
+    if (!changeRef.current) return;
+
+    handleValidate(selectValue);
+    props.onEvent?.("change");
+    changeRef.current = false;
+  }, [selectValue]);
+
+  const handleChange = (value: any) => {
+    props.value.onChange?.(value);
+    changeRef.current = true;
+  };
+
+  return [
+    validateState,
+    handleValidate,
+    handleChange,
+  ] as const;
 };
 
 type ValidationCompWithValue = ValidationComp & {
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
index 967ce1fbf4..f3a74123fa 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
@@ -258,7 +258,6 @@ function getInitialColumns(
   Object.keys(columnsAggrData).forEach(column => {
     if(customColumns.includes(column)) return;
     initialColumns.push({
-      // label: <span style={{textTransform: 'capitalize'}}>{column}</span>,
       label: column,
       value: `{{currentRow.${column}}}`
     });
diff --git a/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx b/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx
index 2deb701e66..66b7e4cdbf 100644
--- a/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx
@@ -134,6 +134,7 @@ const TextInputInvalidConfig = depsConfig<TextInputComp, ChildrenTypeToDepsKeys<
 export const TextInputConfigs = [TextInputInvalidConfig, ...CommonNameConfig];
 
 export const textInputChildren = {
+  defaultValue: stringExposingStateControl("defaultValue"),
   value: stringExposingStateControl("value"),
   disabled: BoolCodeControl,
   label: LabelControl,
@@ -156,6 +157,7 @@ export const textInputProps = (props: RecordConstructorToView<typeof textInputCh
   disabled: props.disabled,
   readOnly: props.readOnly,
   placeholder: props.placeholder,
+  defaultValue: props.defaultValue.value,
   value: props.value.value,
   onFocus: () => props.onEvent("focus"),
   onBlur: () => props.onEvent("blur"),
@@ -164,13 +166,21 @@ export const textInputProps = (props: RecordConstructorToView<typeof textInputCh
 
 export const useTextInputProps = (props: RecordConstructorToView<typeof textInputChildren>) => {
   const [validateState, setValidateState] = useState({});
+  const changeRef = useRef(false)
 
   const propsRef = useRef<RecordConstructorToView<typeof textInputChildren>>(props);
   propsRef.current = props;
 
-  const inputValue = props.value.value;
+  const defaultValue = { ...props.defaultValue }.value;
+  const inputValue = { ...props.value }.value;
 
   useEffect(() => {
+    props.value.onChange(defaultValue)
+  }, [defaultValue]);
+
+  useEffect(() => {
+    if (!changeRef.current) return;
+
     setValidateState(
       textInputValidate({
         ...propsRef.current,
@@ -179,12 +189,15 @@ export const useTextInputProps = (props: RecordConstructorToView<typeof textInpu
         },
       })
     );
+    propsRef.current.onEvent("change");
+    changeRef.current = false;
   }, [inputValue]);
 
   const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
     props.value.onChange(e.target.value);
-    propsRef.current.onEvent("change");
+    changeRef.current = true;
   };
+
   return [
     {
       ...textInputProps(props),
@@ -198,7 +211,7 @@ type TextInputComp = RecordConstructorToComp<typeof textInputChildren>;
 
 export const TextInputBasicSection = (children: TextInputComp) => (
   <Section name={sectionNames.basic}>
-    {children.value.propertyView({ label: trans("prop.defaultValue") })}
+    {children.defaultValue.propertyView({ label: trans("prop.defaultValue") })}
     {placeholderPropertyView(children)}
   </Section>
 );
diff --git a/client/packages/lowcoder/src/comps/comps/treeComp/treeSelectComp.tsx b/client/packages/lowcoder/src/comps/comps/treeComp/treeSelectComp.tsx
index 993113e970..ea31712a3c 100644
--- a/client/packages/lowcoder/src/comps/comps/treeComp/treeSelectComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/treeComp/treeSelectComp.tsx
@@ -85,7 +85,11 @@ const TreeCompView = (
 ) => {
   const { treeData, selectType, value, expanded, style, inputValue } = props;
   const isSingle = selectType === "single";
-  const [validateState, handleValidate] = useSelectInputValidate(props);
+  const [
+    validateState,
+    handleChange,
+  ] = useSelectInputValidate(props);
+
   useEffect(() => {
     if (isSingle && value.value.length > 1) {
       value.onChange(value.value.slice(0, 1));
@@ -119,9 +123,7 @@ const TreeCompView = (
         }}
         onChange={(keys) => {
           const nextValue = Array.isArray(keys) ? keys : keys !== undefined ? [keys] : [];
-          handleValidate(nextValue);
-          value.onChange(nextValue);
-          props.onEvent("change");
+          handleChange(nextValue);
         }}
         showSearch={props.showSearch}
         // search label
diff --git a/client/packages/lowcoder/src/comps/comps/treeComp/treeUtils.tsx b/client/packages/lowcoder/src/comps/comps/treeComp/treeUtils.tsx
index 1ad7ce9090..2e6fb61d62 100644
--- a/client/packages/lowcoder/src/comps/comps/treeComp/treeUtils.tsx
+++ b/client/packages/lowcoder/src/comps/comps/treeComp/treeUtils.tsx
@@ -68,6 +68,7 @@ function expandAll(data: TreeDataNode[]) {
 export const treeCommonChildren = {
   // TODO: support loading mode
   treeData: jsonControl(convertTreeData, defaultTreeData),
+  defaultValue: jsonExposingStateControl("value", checkNodeValues, []),
   value: jsonExposingStateControl("value", checkNodeValues, []),
   expanded: jsonStateControl(checkNodeValues, []),
   defaultExpandAll: BoolControl,
@@ -94,8 +95,9 @@ type TreeCommonComp = NewChildren<RecordConstructorToComp<typeof treeCommonChild
 export const treeDataPropertyView = (children: TreeCommonComp) =>
   children.treeData.propertyView({ label: trans("tree.treeData"), tooltip: treeDataTooltip });
 
-export const valuePropertyView = (children: TreeCommonComp) =>
-  children.value.propertyView({ label: trans("tree.value") });
+export const valuePropertyView = (children: TreeCommonComp) => {
+  return children.defaultValue.propertyView({ label: trans("tree.value") });
+}
 
 export const formSection = (children: TreeCommonComp) => <FormDataPropertyView {...children} />;
 
diff --git a/client/packages/lowcoder/src/comps/controls/optionsControl.tsx b/client/packages/lowcoder/src/comps/controls/optionsControl.tsx
index 221459b288..1230a195e7 100644
--- a/client/packages/lowcoder/src/comps/controls/optionsControl.tsx
+++ b/client/packages/lowcoder/src/comps/controls/optionsControl.tsx
@@ -331,6 +331,7 @@ export function mapOptionsControl<T extends OptionsControlType>(
             return comp.updateContext(dataExample);
           }
         }
+        return comp;
       }
       return super.reduce(action);
     }

From d7daf285e54f92bb92e05c41323ef10ad8911ac3 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Wed, 14 Feb 2024 21:46:34 +0500
Subject: [PATCH 37/97] expose setPage method on ListView and GridView

---
 .../comps/comps/listViewComp/listViewComp.tsx | 21 +++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx b/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx
index c9a28811da..dd1dc85e98 100644
--- a/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx
@@ -37,6 +37,7 @@ import { ContextContainerComp } from "./contextContainerComp";
 import { ListView } from "./listView";
 import { listPropertyView } from "./listViewPropertyView";
 import { getData } from "./listViewUtils";
+import { withMethodExposing } from "comps/generators/withMethodExposing";
 
 const childrenMap = {
   noOfRows: withIsLoadingMethod(NumberOrJSONObjectArrayControl), // FIXME: migrate "noOfRows" to "data"
@@ -151,11 +152,11 @@ export class ListViewImplComp extends ListViewTmpComp implements IContainer {
 
 const ListViewRenderComp = withViewFn(ListViewImplComp, (comp) => <ListView comp={comp} />);
 const ListPropertyView = listPropertyView("listView");
-const ListViewPropertyComp = withPropertyViewFn(ListViewRenderComp, (comp) => {
+let ListViewPropertyComp = withPropertyViewFn(ListViewRenderComp, (comp) => {
   return <ListPropertyView comp={comp} />;
 });
 
-export const ListViewComp = withExposingConfigs(ListViewPropertyComp, [
+ListViewPropertyComp = withExposingConfigs(ListViewPropertyComp, [
   new CompDepsConfig(
     "items",
     (comp) => ({ data: comp.itemsNode() }),
@@ -180,6 +181,22 @@ export const ListViewComp = withExposingConfigs(ListViewPropertyComp, [
   NameConfigHidden,
 ]);
 
+export const ListViewComp = withMethodExposing(ListViewPropertyComp, [
+  {
+    method: {
+      name: "setPage",
+      description: "",
+      params: [{ name: "page", type: "number" }],
+    },
+    execute: (comp, values) => {
+      const page = values[0] as number;
+      if (page && page > 0) {
+        comp.children.pagination.children.pageNo.dispatchChangeValueAction(page);
+      }
+    },
+  },
+])
+
 export function defaultListViewData(compName: string, nameGenerator: NameGenerator) {
   return {
     noOfRows:

From 349986e427dc48ec72de4376491587369f69c206 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Thu, 15 Feb 2024 01:54:29 +0500
Subject: [PATCH 38/97] fix number input 'allow null value' has no effect

---
 .../comps/numberInputComp/numberInputComp.tsx | 20 ++++++++++++++++---
 .../src/comps/controls/dropdownControl.tsx    |  1 -
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx b/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx
index f1c917521b..4baacf4d1b 100644
--- a/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx
@@ -10,7 +10,7 @@ import {
 import { BoolControl } from "comps/controls/boolControl";
 import { dropdownControl } from "comps/controls/dropdownControl";
 import { LabelControl } from "comps/controls/labelControl";
-import { numberExposingStateControl } from "comps/controls/codeStateControl";
+import { numberExposingStateControl, stringExposingStateControl } from "comps/controls/codeStateControl";
 import NP from "number-precision";
 
 import {
@@ -234,6 +234,7 @@ const UndefinedNumberControl = codeControl<number | undefined>((value: any) => {
 });
 
 const childrenMap = {
+  defaultValue: stringExposingStateControl("defaultValue"), // It is more convenient for string to handle various states, save raw input here
   value: numberExposingStateControl("value"), // It is more convenient for string to handle various states, save raw input here
   placeholder: StringControl,
   disabled: BoolCodeControl,
@@ -261,6 +262,17 @@ const childrenMap = {
 
 const CustomInputNumber = (props: RecordConstructorToView<typeof childrenMap>) => {
   const ref = useRef<HTMLInputElement | null>(null);
+  const defaultValue = props.defaultValue.value;
+
+  useEffect(() => {
+    let value = 0;
+    if (defaultValue === 'null' && props.allowNull) {
+      value = NaN;
+    } else if (!isNaN(Number(defaultValue))) {
+      value = Number(defaultValue);
+    }
+    props.value.onChange(value);
+  }, [defaultValue]);
 
   const formatFn = (value: number) =>
     format(value, props.allowNull, props.formatter, props.precision, props.thousandsSeparator);
@@ -271,7 +283,9 @@ const CustomInputNumber = (props: RecordConstructorToView<typeof childrenMap>) =
     const oldValue = props.value.value;
     const newValue = parseNumber(tmpValue, props.allowNull);
     props.value.onChange(newValue);
-    oldValue !== newValue && props.onEvent("change");
+    if((oldValue !== newValue)) {
+      props.onEvent("change");
+    }
   };
 
   useEffect(() => {
@@ -363,7 +377,7 @@ const NumberInputTmpComp = (function () {
     .setPropertyViewFn((children) => (
       <>
         <Section name={sectionNames.basic}>
-          {children.value.propertyView({ label: trans("prop.defaultValue") })}
+          {children.defaultValue.propertyView({ label: trans("prop.defaultValue") })}
           {placeholderPropertyView(children)}
           {children.formatter.propertyView({ label: trans("numberInput.formatter") })}
         </Section>
diff --git a/client/packages/lowcoder/src/comps/controls/dropdownControl.tsx b/client/packages/lowcoder/src/comps/controls/dropdownControl.tsx
index 1492a97a45..01b7b832cd 100644
--- a/client/packages/lowcoder/src/comps/controls/dropdownControl.tsx
+++ b/client/packages/lowcoder/src/comps/controls/dropdownControl.tsx
@@ -96,7 +96,6 @@ export function dropdownAbstractControl<T extends OptionsType>(
           value={this.value}
           options={finalOptions}
           onChange={(value) => {
-            console.log(value);
             if (!params.disableDispatchValueChange) {
               this.dispatchChangeValueAction(value);
             }

From ad0d049ed73dde660f109a296d4887f26e247b2c Mon Sep 17 00:00:00 2001
From: freddysundowner <githumbi3fred@gmail.com>
Date: Thu, 15 Feb 2024 11:40:52 +0300
Subject: [PATCH 39/97] fix:Date Range Component crashes when we remove Suffix
 Icon

---
 client/packages/lowcoder/src/comps/utils/index.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/client/packages/lowcoder/src/comps/utils/index.tsx b/client/packages/lowcoder/src/comps/utils/index.tsx
index d0ff1dcb69..1dda47b1ec 100644
--- a/client/packages/lowcoder/src/comps/utils/index.tsx
+++ b/client/packages/lowcoder/src/comps/utils/index.tsx
@@ -84,4 +84,4 @@ export function arrayMove<T>(data: Array<T>, start: number, end: number) {
   return result;
 }
 
-export const hasIcon = (icon: ReactNode) => (icon as ReactElement).props.value;
+export const hasIcon = (icon: ReactNode) => (icon as ReactElement).props?.value;

From 92196587caf138ab1694f96958222703bdedb57b Mon Sep 17 00:00:00 2001
From: Ludo Mikula <ludovit.mikula@mikori.sk>
Date: Thu, 15 Feb 2024 10:05:54 +0100
Subject: [PATCH 40/97] fix: fixed failing test

---
 .../lowcoder/api/application/ApplicationApiServiceTest.java  | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/server/api-service/lowcoder-server/src/test/java/org/lowcoder/api/application/ApplicationApiServiceTest.java b/server/api-service/lowcoder-server/src/test/java/org/lowcoder/api/application/ApplicationApiServiceTest.java
index 50fc1d85d2..5bf57b4616 100644
--- a/server/api-service/lowcoder-server/src/test/java/org/lowcoder/api/application/ApplicationApiServiceTest.java
+++ b/server/api-service/lowcoder-server/src/test/java/org/lowcoder/api/application/ApplicationApiServiceTest.java
@@ -8,6 +8,7 @@
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.lowcoder.api.application.ApplicationEndpoints.ApplicationRequestType;
 import org.lowcoder.api.application.ApplicationEndpoints.CreateApplicationRequest;
 import org.lowcoder.api.application.view.ApplicationPermissionView;
 import org.lowcoder.api.application.view.ApplicationView;
@@ -133,7 +134,7 @@ public void testPublishApplication() {
                 .verifyComplete();
 
         // published dsl before publish
-        StepVerifier.create(applicationIdMono.flatMap(id -> applicationApiService.getPublishedApplication(id)))
+        StepVerifier.create(applicationIdMono.flatMap(id -> applicationApiService.getPublishedApplication(id, ApplicationRequestType.PUBLIC_TO_ALL)))
                 .assertNext(applicationView -> Assert.assertEquals(Map.of("comp", "table"), applicationView.getApplicationDSL()))
                 .verifyComplete();
 
@@ -147,7 +148,7 @@ public void testPublishApplication() {
                 .verifyComplete();
 
         // published dsl after publish
-        StepVerifier.create(applicationIdMono.flatMap(id -> applicationApiService.getPublishedApplication(id)))
+        StepVerifier.create(applicationIdMono.flatMap(id -> applicationApiService.getPublishedApplication(id, ApplicationRequestType.PUBLIC_TO_ALL)))
                 .assertNext(applicationView -> Assert.assertEquals(Map.of("comp", "list"), applicationView.getApplicationDSL()))
                 .verifyComplete();
     }

From b1743852d6db41177ae20d2bdddf2645ec089ac4 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Thu, 15 Feb 2024 17:04:18 +0500
Subject: [PATCH 41/97] bulk action value

---
 .../src/pages/editor/LeftLayersContent.tsx    | 28 +++++++++----------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx b/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
index 05470460f1..5f2aeb25bd 100644
--- a/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
+++ b/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
@@ -279,10 +279,6 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
   const getCheckedKeys = () => {
     return checkedKeys;
   }
-
-  useEffect(() => {
-    console.log('onChange', actionValue);
-  }, [actionValue])
   
   const getActionValue = () => {
     return actionValue;
@@ -350,14 +346,16 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
         <div style={{marginBottom:"10px"}}>
           {trans("leftPanel.activatelayers")}
           <Switch 
-          style={{margin : "0px 10px"}}
-          size="small"
-          checked={editorState.collisionStatus == "true"}
-          disabled={false}
-          onChange={(value: any) => {
-            toggleCollisionStatus(value == true ? "true" : "false");
-            editorState.setCollisionStatus(value == true ? "true" : "false");
-          } } /></div>
+            style={{margin : "0px 10px"}}
+            size="small"
+            checked={editorState.collisionStatus == "true"}
+            disabled={false}
+            onChange={(value: any) => {
+              toggleCollisionStatus(value == true ? "true" : "false");
+              editorState.setCollisionStatus(value == true ? "true" : "false");
+            }}
+          />
+        </div>
 
         <DirectoryTreeStyle
           checkable={true}
@@ -376,7 +374,8 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
           switcherIcon={(props: any) => props.expanded ? <FoldedIcon /> : <UnfoldIcon />}
           expandedKeys={expandedKeys}
           onExpand={(keys) => setExpandedKeys(keys)}
-          titleRender={(nodeData) => getTreeNode(nodeData as NodeItem, uiCompInfos)} />
+          titleRender={(nodeData) => getTreeNode(nodeData as NodeItem, uiCompInfos)}
+        />
 
         <div style={{margin:"10px 0px"}}> 
           <Flex gap="small" vertical>
@@ -400,7 +399,6 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
             </CustomDropdown>
           </Flex>
         </div>
-
       </div>
      
       <Divider />
@@ -413,7 +411,7 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
       return;
     }
     return getTreeUI();
-  }, [editorState, uiCollapseClick, expandedKeys, componentTreeData]);
+  }, [editorState, uiCollapseClick, expandedKeys, componentTreeData, actionValue]);
   
   const layerControlContent = (
     <ScrollBar>

From a314784bb616482224f67f7b6915d8694259b19b Mon Sep 17 00:00:00 2001
From: freddysundowner <githumbi3fred@gmail.com>
Date: Thu, 15 Feb 2024 15:13:19 +0300
Subject: [PATCH 42/97] fix:when using an external data source

---
 .../src/comps/generators/uiCompBuilder.tsx    | 71 +++++++++++++++----
 1 file changed, 56 insertions(+), 15 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx b/client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx
index 9cc05a1544..bfa0f20cfd 100644
--- a/client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx
+++ b/client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx
@@ -12,18 +12,26 @@ import {
   ToNodeType,
   ViewFnTypeForComp,
 } from "./multi";
-import { ChildrenToComp, ExposingConfig, withExposingConfigs } from "./withExposing";
+import {
+  ChildrenToComp,
+  ExposingConfig,
+  withExposingConfigs,
+} from "./withExposing";
 import {
   ExposeMethodCompConstructor,
   MethodConfigsType,
   withMethodExposing,
 } from "./withMethodExposing";
 
-export type NewChildren<ChildrenCompMap extends Record<string, Comp<unknown>>> = ChildrenCompMap & {
-  hidden: InstanceType<typeof BoolCodeControl>;
-};
+export type NewChildren<ChildrenCompMap extends Record<string, Comp<unknown>>> =
+  ChildrenCompMap & {
+    hidden: InstanceType<typeof BoolCodeControl>;
+  };
 
-export function HidableView(props: { children: JSX.Element | React.ReactNode; hidden: boolean }) {
+export function HidableView(props: {
+  children: JSX.Element | React.ReactNode;
+  hidden: boolean;
+}) {
   const { readOnly } = useContext(ExternalEditorContext);
   if (readOnly) {
     return <>{props.children}</>;
@@ -31,7 +39,9 @@ export function HidableView(props: { children: JSX.Element | React.ReactNode; hi
     return (
       <>
         {props.hidden ? (
-          <div style={{ opacity: "50%", width: "100%", height: "100%" }}>{props.children}</div>
+          <div style={{ opacity: "50%", width: "100%", height: "100%" }}>
+            {props.children}
+          </div>
         ) : (
           <>{props.children}</>
         )}
@@ -40,7 +50,9 @@ export function HidableView(props: { children: JSX.Element | React.ReactNode; hi
   }
 }
 
-export function uiChildren<ChildrenCompMap extends Record<string, Comp<unknown>>>(
+export function uiChildren<
+  ChildrenCompMap extends Record<string, Comp<unknown>>,
+>(
   childrenMap: ToConstructor<ChildrenCompMap>
 ): ToConstructor<NewChildren<ChildrenCompMap>> {
   return { ...childrenMap, hidden: BoolCodeControl } as any;
@@ -51,12 +63,17 @@ type ViewReturn = ReactNode;
 /**
  * UI components can be constructed with this class, providing the hidden interface
  */
-export class UICompBuilder<ChildrenCompMap extends Record<string, Comp<unknown>>> {
+export class UICompBuilder<
+  ChildrenCompMap extends Record<string, Comp<unknown>>,
+> {
   private childrenMap: ToConstructor<ChildrenCompMap>;
   private viewFn: ViewFnTypeForComp<ViewReturn, NewChildren<ChildrenCompMap>>;
-  private propertyViewFn: PropertyViewFnTypeForComp<NewChildren<ChildrenCompMap>> = () => null;
+  private propertyViewFn: PropertyViewFnTypeForComp<
+    NewChildren<ChildrenCompMap>
+  > = () => null;
   private stateConfigs: ExposingConfig<ChildrenToComp<ChildrenCompMap>>[] = [];
-  private methodConfigs: MethodConfigsType<ExposeMethodCompConstructor<any>> = [];
+  private methodConfigs: MethodConfigsType<ExposeMethodCompConstructor<any>> =
+    [];
 
   /**
    * If viewFn is not placed in the constructor, the type of ViewReturn cannot be inferred
@@ -69,18 +86,24 @@ export class UICompBuilder<ChildrenCompMap extends Record<string, Comp<unknown>>
     this.viewFn = viewFn;
   }
 
-  setPropertyViewFn(propertyViewFn: PropertyViewFnTypeForComp<NewChildren<ChildrenCompMap>>) {
+  setPropertyViewFn(
+    propertyViewFn: PropertyViewFnTypeForComp<NewChildren<ChildrenCompMap>>
+  ) {
     this.propertyViewFn = propertyViewFn;
     return this;
   }
 
-  setExposeStateConfigs(configs: ExposingConfig<ChildrenToComp<ChildrenCompMap>>[]) {
+  setExposeStateConfigs(
+    configs: ExposingConfig<ChildrenToComp<ChildrenCompMap>>[]
+  ) {
     this.stateConfigs = configs;
     return this;
   }
 
   setExposeMethodConfigs(
-    configs: MethodConfigsType<ExposeMethodCompConstructor<MultiBaseComp<ChildrenCompMap>>>
+    configs: MethodConfigsType<
+      ExposeMethodCompConstructor<MultiBaseComp<ChildrenCompMap>>
+    >
   ) {
     this.methodConfigs = configs;
     return this;
@@ -113,14 +136,18 @@ export class UICompBuilder<ChildrenCompMap extends Record<string, Comp<unknown>>
       }
 
       override getPropertyView(): ReactNode {
-        return <PropertyView comp={this} propertyViewFn={builder.propertyViewFn} />;
+        return (
+          <PropertyView comp={this} propertyViewFn={builder.propertyViewFn} />
+        );
       }
     }
 
     return withExposingConfigs(
       withMethodExposing(
         MultiTempComp,
-        this.methodConfigs as MethodConfigsType<ExposeMethodCompConstructor<MultiTempComp>>
+        this.methodConfigs as MethodConfigsType<
+          ExposeMethodCompConstructor<MultiTempComp>
+        >
       ) as typeof MultiTempComp,
       this.stateConfigs
     );
@@ -134,12 +161,26 @@ export const DisabledContext = React.createContext<boolean>(false);
  */
 function UIView(props: { comp: any; viewFn: any }) {
   const comp = props.comp;
+  console.log(comp);
+
+  console.log(comp.children);
+
   const childrenProps = childrenToProps(comp.children);
   const parentDisabled = useContext(DisabledContext);
   const disabled = childrenProps["disabled"];
   if (disabled !== undefined && typeof disabled === "boolean") {
     childrenProps["disabled"] = disabled || parentDisabled;
   }
+
+  //ADDED BY FRED
+  if (childrenProps.events) {
+    const events = childrenProps.events as { value?: any[] };
+    if (!events.value || events.value.length === 0) {
+      events.value = [];
+    }
+  }
+  //END ADD BY FRED
+
   return (
     <HidableView hidden={childrenProps.hidden as boolean}>
       {props.viewFn(childrenProps, comp.dispatch)}

From 85926955f5e9cffc1d4baaba51e75f58a5f7f38f Mon Sep 17 00:00:00 2001
From: Imtanan Aziz Toor <imtanan.aziz@ikhwatech.com>
Date: Thu, 15 Feb 2024 19:32:08 +0500
Subject: [PATCH 43/97] text-area font syle added

---
 .../textInputComp/textInputConstants.tsx      |   9 +-
 .../comps/controls/styleControlConstants.tsx  |   1 +
 ....timestamp-1708005283355-9ba212c9a46a4.mjs | 331 ++++++++++++++++++
 3 files changed, 337 insertions(+), 4 deletions(-)
 create mode 100644 client/packages/lowcoder/vite.config.mts.timestamp-1708005283355-9ba212c9a46a4.mjs

diff --git a/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx b/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx
index 291c040771..5a2438245f 100644
--- a/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx
@@ -229,6 +229,7 @@ export function getStyle(style: InputLikeStyleType) {
       font-size: ${style.textSize};
       font-weight: ${style.textWeight};
       font-family: ${style.fontFamily};
+      font-style:${style.fontStyle};
       background-color: ${style.background};
       border-color: ${style.border};
 
@@ -275,10 +276,10 @@ export const inputRefMethods = [
 ];
 
 export function checkMentionListData(data: any) {
-  if(data === "") return {}
-  for(const key in data) {
-    check(data[key], ["array"], key,(node)=>{
-      check(node, ["string"], );
+  if (data === "") return {}
+  for (const key in data) {
+    check(data[key], ["array"], key, (node) => {
+      check(node, ["string"],);
       return node
     })
   }
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index 3df7ba687a..f8fa415a86 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -685,6 +685,7 @@ export const InputLikeStyle = [
   TEXT_SIZE,
   TEXT_WEIGHT,
   FONT_FAMILY,
+  FONT_STYLE,
   MARGIN,
   PADDING,
   ...ACCENT_VALIDATE,
diff --git a/client/packages/lowcoder/vite.config.mts.timestamp-1708005283355-9ba212c9a46a4.mjs b/client/packages/lowcoder/vite.config.mts.timestamp-1708005283355-9ba212c9a46a4.mjs
new file mode 100644
index 0000000000..8600472a2e
--- /dev/null
+++ b/client/packages/lowcoder/vite.config.mts.timestamp-1708005283355-9ba212c9a46a4.mjs
@@ -0,0 +1,331 @@
+// vite.config.mts
+import dotenv from "file:///C:/Projects/lowcoder/client/node_modules/dotenv/lib/main.js";
+import { defineConfig } from "file:///C:/Projects/lowcoder/client/node_modules/vite/dist/node/index.js";
+import react from "file:///C:/Projects/lowcoder/client/node_modules/@vitejs/plugin-react/dist/index.mjs";
+import viteTsconfigPaths from "file:///C:/Projects/lowcoder/client/node_modules/vite-tsconfig-paths/dist/index.mjs";
+import svgrPlugin from "file:///C:/Projects/lowcoder/client/node_modules/vite-plugin-svgr/dist/index.mjs";
+import checker from "file:///C:/Projects/lowcoder/client/node_modules/vite-plugin-checker/dist/esm/main.js";
+import { visualizer } from "file:///C:/Projects/lowcoder/client/node_modules/rollup-plugin-visualizer/dist/plugin/index.js";
+import path from "path";
+import chalk from "file:///C:/Projects/lowcoder/client/node_modules/chalk/source/index.js";
+import { createHtmlPlugin } from "file:///C:/Projects/lowcoder/client/node_modules/vite-plugin-html/dist/index.mjs";
+
+// src/dev-utils/util.js
+function ensureLastSlash(str) {
+  if (!str) {
+    return "/";
+  }
+  if (!str.endsWith("/")) {
+    return `${str}/`;
+  }
+  return str;
+}
+
+// src/dev-utils/buildVars.js
+var buildVars = [
+  {
+    name: "PUBLIC_URL",
+    defaultValue: "/"
+  },
+  {
+    name: "REACT_APP_EDITION",
+    defaultValue: "community"
+  },
+  {
+    name: "REACT_APP_LANGUAGES",
+    defaultValue: ""
+  },
+  {
+    name: "REACT_APP_COMMIT_ID",
+    defaultValue: "00000"
+  },
+  {
+    name: "REACT_APP_API_HOST",
+    defaultValue: ""
+  },
+  {
+    name: "LOWCODER_NODE_SERVICE_URL",
+    defaultValue: ""
+  },
+  {
+    name: "REACT_APP_ENV",
+    defaultValue: "production"
+  },
+  {
+    name: "REACT_APP_BUILD_ID",
+    defaultValue: ""
+  },
+  {
+    name: "REACT_APP_LOG_LEVEL",
+    defaultValue: "error"
+  },
+  {
+    name: "REACT_APP_IMPORT_MAP",
+    defaultValue: "{}"
+  },
+  {
+    name: "REACT_APP_SERVER_IPS",
+    defaultValue: ""
+  },
+  {
+    name: "REACT_APP_BUNDLE_BUILTIN_PLUGIN",
+    defaultValue: ""
+  },
+  {
+    name: "REACT_APP_BUNDLE_TYPE",
+    defaultValue: "app"
+  },
+  {
+    name: "REACT_APP_DISABLE_JS_SANDBOX",
+    defaultValue: ""
+  }
+];
+
+// src/dev-utils/external.js
+var libs = [
+  "axios",
+  "redux",
+  "react-router",
+  "react-router-dom",
+  "react-redux",
+  "react",
+  "react-dom",
+  "lodash",
+  "history",
+  "antd",
+  "@dnd-kit/core",
+  "@dnd-kit/modifiers",
+  "@dnd-kit/sortable",
+  "@dnd-kit/utilities",
+  {
+    name: "moment",
+    extractDefault: true
+  },
+  {
+    name: "dayjs",
+    extractDefault: true
+  },
+  {
+    name: "lowcoder-sdk",
+    from: "./src/index.sdk.ts"
+  },
+  {
+    name: "styled-components",
+    mergeDefaultAndNameExports: true
+  }
+];
+var getLibGlobalVarName = (name) => {
+  return "$" + name.replace(/@/g, "$").replace(/[\/\-]/g, "_");
+};
+var libsImportCode = (exclude = []) => {
+  const importLines = [];
+  const assignLines = [];
+  libs.forEach((i) => {
+    let name = i;
+    let merge = false;
+    let from = name;
+    let extractDefault = false;
+    if (typeof i === "object") {
+      name = i.name;
+      merge = i.mergeDefaultAndNameExports ?? false;
+      from = i.from ?? name;
+      extractDefault = i.extractDefault ?? false;
+    }
+    if (exclude.includes(name)) {
+      return;
+    }
+    const varName = getLibGlobalVarName(name);
+    if (merge) {
+      importLines.push(`import * as ${varName}_named_exports from '${from}';`);
+      importLines.push(`import ${varName} from '${from}';`);
+      assignLines.push(`Object.assign(${varName}, ${varName}_named_exports);`);
+    } else if (extractDefault) {
+      importLines.push(`import ${varName} from '${from}';`);
+    } else {
+      importLines.push(`import * as ${varName} from '${from}';`);
+    }
+    assignLines.push(`window.${varName} = ${varName};`);
+  });
+  return importLines.concat(assignLines).join("\n");
+};
+
+// src/dev-utils/globalDepPlguin.js
+function globalDepPlugin(exclude = []) {
+  const virtualModuleId = "virtual:globals";
+  return {
+    name: "lowcoder-global-plugin",
+    resolveId(id) {
+      if (id === virtualModuleId) {
+        return id;
+      }
+    },
+    load(id) {
+      if (id === virtualModuleId) {
+        return libsImportCode(exclude);
+      }
+    }
+  };
+}
+
+// vite.config.mts
+var __vite_injected_original_dirname = "C:\\Projects\\lowcoder\\client\\packages\\lowcoder";
+dotenv.config();
+var apiProxyTarget = process.env.LOWCODER_API_SERVICE_URL;
+var nodeServiceApiProxyTarget = process.env.NODE_SERVICE_API_PROXY_TARGET;
+var nodeEnv = process.env.NODE_ENV ?? "development";
+var edition = process.env.REACT_APP_EDITION;
+var isEEGlobal = edition === "enterprise-global";
+var isEE = edition === "enterprise" || isEEGlobal;
+var isDev = nodeEnv === "development";
+var isVisualizerEnabled = !!process.env.ENABLE_VISUALIZER;
+var browserCheckFileName = `browser-check.js`;
+var base = ensureLastSlash(process.env.PUBLIC_URL);
+if (!apiProxyTarget && isDev) {
+  console.log();
+  console.log(chalk.red`LOWCODER_API_SERVICE_URL is required.\n`);
+  console.log(chalk.cyan`Start with command: LOWCODER_API_SERVICE_URL=\{backend-api-addr\} yarn start`);
+  console.log();
+  process.exit(1);
+}
+var proxyConfig = {
+  "/api": {
+    target: apiProxyTarget,
+    changeOrigin: false
+  }
+};
+if (nodeServiceApiProxyTarget) {
+  proxyConfig["/node-service"] = {
+    target: nodeServiceApiProxyTarget
+  };
+}
+var define = {};
+buildVars.forEach(({ name, defaultValue }) => {
+  define[name] = JSON.stringify(process.env[name] || defaultValue);
+});
+var viteConfig = {
+  define,
+  assetsInclude: ["**/*.md"],
+  resolve: {
+    extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json"],
+    alias: {
+      "@lowcoder-ee": path.resolve(
+        __vite_injected_original_dirname,
+        isEE ? `../lowcoder/src/${isEEGlobal ? "ee-global" : "ee"}` : "../lowcoder/src"
+      )
+    }
+  },
+  base,
+  build: {
+    manifest: true,
+    target: "es2015",
+    cssTarget: "chrome63",
+    outDir: "build",
+    assetsDir: "static",
+    emptyOutDir: false,
+    rollupOptions: {
+      output: {
+        chunkFileNames: "[hash].js"
+      }
+    },
+    commonjsOptions: {
+      defaultIsModuleExports: (id) => {
+        if (id.indexOf("antd/lib") !== -1) {
+          return false;
+        }
+        return "auto";
+      }
+    }
+  },
+  css: {
+    preprocessorOptions: {
+      less: {
+        modifyVars: {
+          "@primary-color": "#3377FF",
+          "@link-color": "#3377FF",
+          "@border-color-base": "#D7D9E0",
+          "@border-radius-base": "4px"
+        },
+        javascriptEnabled: true
+      }
+    }
+  },
+  server: {
+    open: true,
+    cors: true,
+    port: 8e3,
+    host: "0.0.0.0",
+    proxy: proxyConfig
+  },
+  plugins: [
+    checker({
+      typescript: true,
+      eslint: {
+        lintCommand: 'eslint --quiet "./src/**/*.{ts,tsx}"',
+        dev: {
+          logLevel: ["error"]
+        }
+      }
+    }),
+    react({
+      babel: {
+        parserOpts: {
+          plugins: ["decorators-legacy"]
+        }
+      }
+    }),
+    viteTsconfigPaths({
+      projects: ["../lowcoder/tsconfig.json", "../lowcoder-design/tsconfig.json"]
+    }),
+    svgrPlugin({
+      svgrOptions: {
+        exportType: "named",
+        prettier: false,
+        svgo: false,
+        titleProp: true,
+        ref: true
+      }
+    }),
+    globalDepPlugin(),
+    createHtmlPlugin({
+      minify: true,
+      inject: {
+        data: {
+          browserCheckScript: isDev ? "" : `<script src="${base}${browserCheckFileName}"></script>`
+        }
+      }
+    }),
+    isVisualizerEnabled && visualizer()
+  ].filter(Boolean)
+};
+var browserCheckConfig = {
+  ...viteConfig,
+  define: {
+    ...viteConfig.define,
+    "process.env.NODE_ENV": JSON.stringify("production")
+  },
+  build: {
+    ...viteConfig.build,
+    manifest: false,
+    copyPublicDir: false,
+    emptyOutDir: true,
+    lib: {
+      formats: ["iife"],
+      name: "BrowserCheck",
+      entry: "./src/browser-check.ts",
+      fileName: () => {
+        return browserCheckFileName;
+      }
+    }
+  }
+};
+var buildTargets = {
+  main: viteConfig,
+  browserCheck: browserCheckConfig
+};
+var buildTarget = buildTargets[process.env.BUILD_TARGET || "main"];
+var vite_config_default = defineConfig(buildTarget || viteConfig);
+export {
+  vite_config_default as default,
+  viteConfig
+};
+//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcubXRzIiwgInNyYy9kZXYtdXRpbHMvdXRpbC5qcyIsICJzcmMvZGV2LXV0aWxzL2J1aWxkVmFycy5qcyIsICJzcmMvZGV2LXV0aWxzL2V4dGVybmFsLmpzIiwgInNyYy9kZXYtdXRpbHMvZ2xvYmFsRGVwUGxndWluLmpzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSA9IFwiQzpcXFxcUHJvamVjdHNcXFxcbG93Y29kZXJcXFxcY2xpZW50XFxcXHBhY2thZ2VzXFxcXGxvd2NvZGVyXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCJDOlxcXFxQcm9qZWN0c1xcXFxsb3djb2RlclxcXFxjbGllbnRcXFxccGFja2FnZXNcXFxcbG93Y29kZXJcXFxcdml0ZS5jb25maWcubXRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9DOi9Qcm9qZWN0cy9sb3djb2Rlci9jbGllbnQvcGFja2FnZXMvbG93Y29kZXIvdml0ZS5jb25maWcubXRzXCI7aW1wb3J0IGRvdGVudiBmcm9tIFwiZG90ZW52XCI7XHJcbmltcG9ydCB7IGRlZmluZUNvbmZpZywgU2VydmVyT3B0aW9ucywgVXNlckNvbmZpZyB9IGZyb20gXCJ2aXRlXCI7XHJcbmltcG9ydCByZWFjdCBmcm9tIFwiQHZpdGVqcy9wbHVnaW4tcmVhY3RcIjtcclxuaW1wb3J0IHZpdGVUc2NvbmZpZ1BhdGhzIGZyb20gXCJ2aXRlLXRzY29uZmlnLXBhdGhzXCI7XHJcbmltcG9ydCBzdmdyUGx1Z2luIGZyb20gXCJ2aXRlLXBsdWdpbi1zdmdyXCI7XHJcbmltcG9ydCBjaGVja2VyIGZyb20gXCJ2aXRlLXBsdWdpbi1jaGVja2VyXCI7XHJcbmltcG9ydCB7IHZpc3VhbGl6ZXIgfSBmcm9tIFwicm9sbHVwLXBsdWdpbi12aXN1YWxpemVyXCI7XHJcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XHJcbmltcG9ydCBjaGFsayBmcm9tIFwiY2hhbGtcIjtcclxuaW1wb3J0IHsgY3JlYXRlSHRtbFBsdWdpbiB9IGZyb20gXCJ2aXRlLXBsdWdpbi1odG1sXCI7XHJcbmltcG9ydCB7IGVuc3VyZUxhc3RTbGFzaCB9IGZyb20gXCIuL3NyYy9kZXYtdXRpbHMvdXRpbFwiO1xyXG5pbXBvcnQgeyBidWlsZFZhcnMgfSBmcm9tIFwiLi9zcmMvZGV2LXV0aWxzL2J1aWxkVmFyc1wiO1xyXG5pbXBvcnQgeyBnbG9iYWxEZXBQbHVnaW4gfSBmcm9tIFwiLi9zcmMvZGV2LXV0aWxzL2dsb2JhbERlcFBsZ3VpblwiO1xyXG5cclxuZG90ZW52LmNvbmZpZygpO1xyXG5cclxuY29uc3QgYXBpUHJveHlUYXJnZXQgPSBwcm9jZXNzLmVudi5MT1dDT0RFUl9BUElfU0VSVklDRV9VUkw7XHJcbmNvbnN0IG5vZGVTZXJ2aWNlQXBpUHJveHlUYXJnZXQgPSBwcm9jZXNzLmVudi5OT0RFX1NFUlZJQ0VfQVBJX1BST1hZX1RBUkdFVDtcclxuY29uc3Qgbm9kZUVudiA9IHByb2Nlc3MuZW52Lk5PREVfRU5WID8/IFwiZGV2ZWxvcG1lbnRcIjtcclxuY29uc3QgZWRpdGlvbiA9IHByb2Nlc3MuZW52LlJFQUNUX0FQUF9FRElUSU9OO1xyXG5jb25zdCBpc0VFR2xvYmFsID0gZWRpdGlvbiA9PT0gXCJlbnRlcnByaXNlLWdsb2JhbFwiO1xyXG5jb25zdCBpc0VFID0gZWRpdGlvbiA9PT0gXCJlbnRlcnByaXNlXCIgfHwgaXNFRUdsb2JhbDtcclxuY29uc3QgaXNEZXYgPSBub2RlRW52ID09PSBcImRldmVsb3BtZW50XCI7XHJcbmNvbnN0IGlzVmlzdWFsaXplckVuYWJsZWQgPSAhIXByb2Nlc3MuZW52LkVOQUJMRV9WSVNVQUxJWkVSO1xyXG4vLyB0aGUgZmlsZSB3YXMgbmV2ZXIgY3JlYXRlZFxyXG4vLyBjb25zdCBicm93c2VyQ2hlY2tGaWxlTmFtZSA9IGBicm93c2VyLWNoZWNrLSR7cHJvY2Vzcy5lbnYuUkVBQ1RfQVBQX0NPTU1JVF9JRH0uanNgO1xyXG5jb25zdCBicm93c2VyQ2hlY2tGaWxlTmFtZSA9IGBicm93c2VyLWNoZWNrLmpzYDtcclxuY29uc3QgYmFzZSA9IGVuc3VyZUxhc3RTbGFzaChwcm9jZXNzLmVudi5QVUJMSUNfVVJMKTtcclxuXHJcbmlmICghYXBpUHJveHlUYXJnZXQgJiYgaXNEZXYpIHtcclxuICBjb25zb2xlLmxvZygpO1xyXG4gIGNvbnNvbGUubG9nKGNoYWxrLnJlZGBMT1dDT0RFUl9BUElfU0VSVklDRV9VUkwgaXMgcmVxdWlyZWQuXFxuYCk7XHJcbiAgY29uc29sZS5sb2coY2hhbGsuY3lhbmBTdGFydCB3aXRoIGNvbW1hbmQ6IExPV0NPREVSX0FQSV9TRVJWSUNFX1VSTD1cXHtiYWNrZW5kLWFwaS1hZGRyXFx9IHlhcm4gc3RhcnRgKTtcclxuICBjb25zb2xlLmxvZygpO1xyXG4gIHByb2Nlc3MuZXhpdCgxKTtcclxufVxyXG5cclxuY29uc3QgcHJveHlDb25maWc6IFNlcnZlck9wdGlvbnNbXCJwcm94eVwiXSA9IHtcclxuICBcIi9hcGlcIjoge1xyXG4gICAgdGFyZ2V0OiBhcGlQcm94eVRhcmdldCxcclxuICAgIGNoYW5nZU9yaWdpbjogZmFsc2UsXHJcbiAgfSxcclxufTtcclxuXHJcbmlmIChub2RlU2VydmljZUFwaVByb3h5VGFyZ2V0KSB7XHJcbiAgcHJveHlDb25maWdbXCIvbm9kZS1zZXJ2aWNlXCJdID0ge1xyXG4gICAgdGFyZ2V0OiBub2RlU2VydmljZUFwaVByb3h5VGFyZ2V0LFxyXG4gIH07XHJcbn1cclxuXHJcbmNvbnN0IGRlZmluZSA9IHt9O1xyXG5idWlsZFZhcnMuZm9yRWFjaCgoeyBuYW1lLCBkZWZhdWx0VmFsdWUgfSkgPT4ge1xyXG4gIGRlZmluZVtuYW1lXSA9IEpTT04uc3RyaW5naWZ5KHByb2Nlc3MuZW52W25hbWVdIHx8IGRlZmF1bHRWYWx1ZSk7XHJcbn0pO1xyXG5cclxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cclxuZXhwb3J0IGNvbnN0IHZpdGVDb25maWc6IFVzZXJDb25maWcgPSB7XHJcbiAgZGVmaW5lLFxyXG4gIGFzc2V0c0luY2x1ZGU6IFtcIioqLyoubWRcIl0sXHJcbiAgcmVzb2x2ZToge1xyXG4gICAgZXh0ZW5zaW9uczogW1wiLm1qc1wiLCBcIi5qc1wiLCBcIi50c1wiLCBcIi5qc3hcIiwgXCIudHN4XCIsIFwiLmpzb25cIl0sXHJcbiAgICBhbGlhczoge1xyXG4gICAgICBcIkBsb3djb2Rlci1lZVwiOiBwYXRoLnJlc29sdmUoXHJcbiAgICAgICAgX19kaXJuYW1lLFxyXG4gICAgICAgIGlzRUUgPyBgLi4vbG93Y29kZXIvc3JjLyR7aXNFRUdsb2JhbCA/IFwiZWUtZ2xvYmFsXCIgOiBcImVlXCJ9YCA6IFwiLi4vbG93Y29kZXIvc3JjXCJcclxuICAgICAgKSxcclxuICAgIH0sXHJcbiAgfSxcclxuICBiYXNlLFxyXG4gIGJ1aWxkOiB7XHJcbiAgICBtYW5pZmVzdDogdHJ1ZSxcclxuICAgIHRhcmdldDogXCJlczIwMTVcIixcclxuICAgIGNzc1RhcmdldDogXCJjaHJvbWU2M1wiLFxyXG4gICAgb3V0RGlyOiBcImJ1aWxkXCIsXHJcbiAgICBhc3NldHNEaXI6IFwic3RhdGljXCIsXHJcbiAgICBlbXB0eU91dERpcjogZmFsc2UsXHJcbiAgICByb2xsdXBPcHRpb25zOiB7XHJcbiAgICAgIG91dHB1dDoge1xyXG4gICAgICAgIGNodW5rRmlsZU5hbWVzOiBcIltoYXNoXS5qc1wiLFxyXG4gICAgICB9LFxyXG4gICAgfSxcclxuICAgIGNvbW1vbmpzT3B0aW9uczoge1xyXG4gICAgICBkZWZhdWx0SXNNb2R1bGVFeHBvcnRzOiAoaWQpID0+IHtcclxuICAgICAgICBpZiAoaWQuaW5kZXhPZihcImFudGQvbGliXCIpICE9PSAtMSkge1xyXG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gXCJhdXRvXCI7XHJcbiAgICAgIH0sXHJcbiAgICB9LFxyXG4gIH0sXHJcbiAgY3NzOiB7XHJcbiAgICBwcmVwcm9jZXNzb3JPcHRpb25zOiB7XHJcbiAgICAgIGxlc3M6IHtcclxuICAgICAgICBtb2RpZnlWYXJzOiB7XHJcbiAgICAgICAgICBcIkBwcmltYXJ5LWNvbG9yXCI6IFwiIzMzNzdGRlwiLFxyXG4gICAgICAgICAgXCJAbGluay1jb2xvclwiOiBcIiMzMzc3RkZcIixcclxuICAgICAgICAgIFwiQGJvcmRlci1jb2xvci1iYXNlXCI6IFwiI0Q3RDlFMFwiLFxyXG4gICAgICAgICAgXCJAYm9yZGVyLXJhZGl1cy1iYXNlXCI6IFwiNHB4XCIsXHJcbiAgICAgICAgfSxcclxuICAgICAgICBqYXZhc2NyaXB0RW5hYmxlZDogdHJ1ZSxcclxuICAgICAgfSxcclxuICAgIH0sXHJcbiAgfSxcclxuICBzZXJ2ZXI6IHtcclxuICAgIG9wZW46IHRydWUsXHJcbiAgICBjb3JzOiB0cnVlLFxyXG4gICAgcG9ydDogODAwMCxcclxuICAgIGhvc3Q6IFwiMC4wLjAuMFwiLFxyXG4gICAgcHJveHk6IHByb3h5Q29uZmlnLFxyXG4gIH0sXHJcbiAgcGx1Z2luczogW1xyXG4gICAgY2hlY2tlcih7XHJcbiAgICAgIHR5cGVzY3JpcHQ6IHRydWUsXHJcbiAgICAgIGVzbGludDoge1xyXG4gICAgICAgIGxpbnRDb21tYW5kOiAnZXNsaW50IC0tcXVpZXQgXCIuL3NyYy8qKi8qLnt0cyx0c3h9XCInLFxyXG4gICAgICAgIGRldjoge1xyXG4gICAgICAgICAgbG9nTGV2ZWw6IFtcImVycm9yXCJdLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0sXHJcbiAgICB9KSxcclxuICAgIHJlYWN0KHtcclxuICAgICAgYmFiZWw6IHtcclxuICAgICAgICBwYXJzZXJPcHRzOiB7XHJcbiAgICAgICAgICBwbHVnaW5zOiBbXCJkZWNvcmF0b3JzLWxlZ2FjeVwiXSxcclxuICAgICAgICB9LFxyXG4gICAgICB9LFxyXG4gICAgfSksXHJcbiAgICB2aXRlVHNjb25maWdQYXRocyh7XHJcbiAgICAgIHByb2plY3RzOiBbXCIuLi9sb3djb2Rlci90c2NvbmZpZy5qc29uXCIsIFwiLi4vbG93Y29kZXItZGVzaWduL3RzY29uZmlnLmpzb25cIl0sXHJcbiAgICB9KSxcclxuICAgIHN2Z3JQbHVnaW4oe1xyXG4gICAgICBzdmdyT3B0aW9uczoge1xyXG4gICAgICAgIGV4cG9ydFR5cGU6IFwibmFtZWRcIixcclxuICAgICAgICBwcmV0dGllcjogZmFsc2UsXHJcbiAgICAgICAgc3ZnbzogZmFsc2UsXHJcbiAgICAgICAgdGl0bGVQcm9wOiB0cnVlLFxyXG4gICAgICAgIHJlZjogdHJ1ZSxcclxuICAgICAgfSxcclxuICAgIH0pLFxyXG4gICAgZ2xvYmFsRGVwUGx1Z2luKCksXHJcbiAgICBjcmVhdGVIdG1sUGx1Z2luKHtcclxuICAgICAgbWluaWZ5OiB0cnVlLFxyXG4gICAgICBpbmplY3Q6IHtcclxuICAgICAgICBkYXRhOiB7XHJcbiAgICAgICAgICBicm93c2VyQ2hlY2tTY3JpcHQ6IGlzRGV2ID8gXCJcIiA6IGA8c2NyaXB0IHNyYz1cIiR7YmFzZX0ke2Jyb3dzZXJDaGVja0ZpbGVOYW1lfVwiPjwvc2NyaXB0PmAsXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgIH0pLFxyXG4gICAgaXNWaXN1YWxpemVyRW5hYmxlZCAmJiB2aXN1YWxpemVyKCksXHJcbiAgXS5maWx0ZXIoQm9vbGVhbiksXHJcbn07XHJcblxyXG5jb25zdCBicm93c2VyQ2hlY2tDb25maWc6IFVzZXJDb25maWcgPSB7XHJcbiAgLi4udml0ZUNvbmZpZyxcclxuICBkZWZpbmU6IHtcclxuICAgIC4uLnZpdGVDb25maWcuZGVmaW5lLFxyXG4gICAgXCJwcm9jZXNzLmVudi5OT0RFX0VOVlwiOiBKU09OLnN0cmluZ2lmeShcInByb2R1Y3Rpb25cIiksXHJcbiAgfSxcclxuICBidWlsZDoge1xyXG4gICAgLi4udml0ZUNvbmZpZy5idWlsZCxcclxuICAgIG1hbmlmZXN0OiBmYWxzZSxcclxuICAgIGNvcHlQdWJsaWNEaXI6IGZhbHNlLFxyXG4gICAgZW1wdHlPdXREaXI6IHRydWUsXHJcbiAgICBsaWI6IHtcclxuICAgICAgZm9ybWF0czogW1wiaWlmZVwiXSxcclxuICAgICAgbmFtZTogXCJCcm93c2VyQ2hlY2tcIixcclxuICAgICAgZW50cnk6IFwiLi9zcmMvYnJvd3Nlci1jaGVjay50c1wiLFxyXG4gICAgICBmaWxlTmFtZTogKCkgPT4ge1xyXG4gICAgICAgIHJldHVybiBicm93c2VyQ2hlY2tGaWxlTmFtZTtcclxuICAgICAgfSxcclxuICAgIH0sXHJcbiAgfSxcclxufTtcclxuXHJcbmNvbnN0IGJ1aWxkVGFyZ2V0cyA9IHtcclxuICBtYWluOiB2aXRlQ29uZmlnLFxyXG4gIGJyb3dzZXJDaGVjazogYnJvd3NlckNoZWNrQ29uZmlnLFxyXG59O1xyXG5cclxuY29uc3QgYnVpbGRUYXJnZXQgPSBidWlsZFRhcmdldHNbcHJvY2Vzcy5lbnYuQlVJTERfVEFSR0VUIHx8IFwibWFpblwiXTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyhidWlsZFRhcmdldCB8fCB2aXRlQ29uZmlnKTtcclxuIiwgImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJDOlxcXFxQcm9qZWN0c1xcXFxsb3djb2RlclxcXFxjbGllbnRcXFxccGFja2FnZXNcXFxcbG93Y29kZXJcXFxcc3JjXFxcXGRldi11dGlsc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiQzpcXFxcUHJvamVjdHNcXFxcbG93Y29kZXJcXFxcY2xpZW50XFxcXHBhY2thZ2VzXFxcXGxvd2NvZGVyXFxcXHNyY1xcXFxkZXYtdXRpbHNcXFxcdXRpbC5qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vQzovUHJvamVjdHMvbG93Y29kZXIvY2xpZW50L3BhY2thZ2VzL2xvd2NvZGVyL3NyYy9kZXYtdXRpbHMvdXRpbC5qc1wiO2ltcG9ydCBmcyBmcm9tIFwibm9kZTpmc1wiO1xyXG5pbXBvcnQgeyBkaXJuYW1lIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xyXG5pbXBvcnQgeyBmaWxlVVJMVG9QYXRoIH0gZnJvbSBcIm5vZGU6dXJsXCI7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc3RyaXBMYXN0U2xhc2goc3RyKSB7XHJcbiAgaWYgKHN0ci5lbmRzV2l0aChcIi9cIikpIHtcclxuICAgIHJldHVybiBzdHIuc2xpY2UoMCwgc3RyLmxlbmd0aCAtIDEpO1xyXG4gIH1cclxuICByZXR1cm4gc3RyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZW5zdXJlTGFzdFNsYXNoKHN0cikge1xyXG4gIGlmICghc3RyKSB7XHJcbiAgICByZXR1cm4gXCIvXCI7XHJcbiAgfVxyXG4gIGlmICghc3RyLmVuZHNXaXRoKFwiL1wiKSkge1xyXG4gICAgcmV0dXJuIGAke3N0cn0vYDtcclxuICB9XHJcbiAgcmV0dXJuIHN0cjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHJlYWRKc29uKGZpbGUpIHtcclxuICByZXR1cm4gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMoZmlsZSkudG9TdHJpbmcoKSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjdXJyZW50RGlyTmFtZShpbXBvcnRNZXRhVXJsKSB7XHJcbiAgcmV0dXJuIGRpcm5hbWUoZmlsZVVSTFRvUGF0aChpbXBvcnRNZXRhVXJsKSk7XHJcbn1cclxuIiwgImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJDOlxcXFxQcm9qZWN0c1xcXFxsb3djb2RlclxcXFxjbGllbnRcXFxccGFja2FnZXNcXFxcbG93Y29kZXJcXFxcc3JjXFxcXGRldi11dGlsc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiQzpcXFxcUHJvamVjdHNcXFxcbG93Y29kZXJcXFxcY2xpZW50XFxcXHBhY2thZ2VzXFxcXGxvd2NvZGVyXFxcXHNyY1xcXFxkZXYtdXRpbHNcXFxcYnVpbGRWYXJzLmpzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9DOi9Qcm9qZWN0cy9sb3djb2Rlci9jbGllbnQvcGFja2FnZXMvbG93Y29kZXIvc3JjL2Rldi11dGlscy9idWlsZFZhcnMuanNcIjtleHBvcnQgY29uc3QgYnVpbGRWYXJzID0gW1xyXG4gIHtcclxuICAgIG5hbWU6IFwiUFVCTElDX1VSTFwiLFxyXG4gICAgZGVmYXVsdFZhbHVlOiBcIi9cIixcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6IFwiUkVBQ1RfQVBQX0VESVRJT05cIixcclxuICAgIGRlZmF1bHRWYWx1ZTogXCJjb21tdW5pdHlcIixcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6IFwiUkVBQ1RfQVBQX0xBTkdVQUdFU1wiLFxyXG4gICAgZGVmYXVsdFZhbHVlOiBcIlwiLFxyXG4gIH0sXHJcbiAge1xyXG4gICAgbmFtZTogXCJSRUFDVF9BUFBfQ09NTUlUX0lEXCIsXHJcbiAgICBkZWZhdWx0VmFsdWU6IFwiMDAwMDBcIixcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6IFwiUkVBQ1RfQVBQX0FQSV9IT1NUXCIsXHJcbiAgICBkZWZhdWx0VmFsdWU6IFwiXCIsXHJcbiAgfSxcclxuICB7XHJcbiAgICBuYW1lOiBcIkxPV0NPREVSX05PREVfU0VSVklDRV9VUkxcIixcclxuICAgIGRlZmF1bHRWYWx1ZTogXCJcIixcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6IFwiUkVBQ1RfQVBQX0VOVlwiLFxyXG4gICAgZGVmYXVsdFZhbHVlOiBcInByb2R1Y3Rpb25cIixcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6IFwiUkVBQ1RfQVBQX0JVSUxEX0lEXCIsXHJcbiAgICBkZWZhdWx0VmFsdWU6IFwiXCIsXHJcbiAgfSxcclxuICB7XHJcbiAgICBuYW1lOiBcIlJFQUNUX0FQUF9MT0dfTEVWRUxcIixcclxuICAgIGRlZmF1bHRWYWx1ZTogXCJlcnJvclwiLFxyXG4gIH0sXHJcbiAge1xyXG4gICAgbmFtZTogXCJSRUFDVF9BUFBfSU1QT1JUX01BUFwiLFxyXG4gICAgZGVmYXVsdFZhbHVlOiBcInt9XCIsXHJcbiAgfSxcclxuICB7XHJcbiAgICBuYW1lOiBcIlJFQUNUX0FQUF9TRVJWRVJfSVBTXCIsXHJcbiAgICBkZWZhdWx0VmFsdWU6IFwiXCIsXHJcbiAgfSxcclxuICB7XHJcbiAgICBuYW1lOiBcIlJFQUNUX0FQUF9CVU5ETEVfQlVJTFRJTl9QTFVHSU5cIixcclxuICAgIGRlZmF1bHRWYWx1ZTogXCJcIixcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6IFwiUkVBQ1RfQVBQX0JVTkRMRV9UWVBFXCIsXHJcbiAgICBkZWZhdWx0VmFsdWU6IFwiYXBwXCIsXHJcbiAgfSxcclxuICB7XHJcbiAgICBuYW1lOiBcIlJFQUNUX0FQUF9ESVNBQkxFX0pTX1NBTkRCT1hcIixcclxuICAgIGRlZmF1bHRWYWx1ZTogXCJcIixcclxuICB9LFxyXG5dO1xyXG4iLCAiY29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2Rpcm5hbWUgPSBcIkM6XFxcXFByb2plY3RzXFxcXGxvd2NvZGVyXFxcXGNsaWVudFxcXFxwYWNrYWdlc1xcXFxsb3djb2RlclxcXFxzcmNcXFxcZGV2LXV0aWxzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCJDOlxcXFxQcm9qZWN0c1xcXFxsb3djb2RlclxcXFxjbGllbnRcXFxccGFja2FnZXNcXFxcbG93Y29kZXJcXFxcc3JjXFxcXGRldi11dGlsc1xcXFxleHRlcm5hbC5qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vQzovUHJvamVjdHMvbG93Y29kZXIvY2xpZW50L3BhY2thZ2VzL2xvd2NvZGVyL3NyYy9kZXYtdXRpbHMvZXh0ZXJuYWwuanNcIjsvKipcclxuICogbGlicyB0byBpbXBvcnQgYXMgZ2xvYmFsIHZhclxyXG4gKiBuYW1lOiBtb2R1bGUgbmFtZVxyXG4gKiBtZXJnZURlZmF1bHRBbmROYW1lRXhwb3J0czogd2hldGhlciB0byBtZXJnZSBkZWZhdWx0IGFuZCBuYW1lZCBleHBvcnRzXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgbGlicyA9IFtcclxuICBcImF4aW9zXCIsXHJcbiAgXCJyZWR1eFwiLFxyXG4gIFwicmVhY3Qtcm91dGVyXCIsXHJcbiAgXCJyZWFjdC1yb3V0ZXItZG9tXCIsXHJcbiAgXCJyZWFjdC1yZWR1eFwiLFxyXG4gIFwicmVhY3RcIixcclxuICBcInJlYWN0LWRvbVwiLFxyXG4gIFwibG9kYXNoXCIsXHJcbiAgXCJoaXN0b3J5XCIsXHJcbiAgXCJhbnRkXCIsXHJcbiAgXCJAZG5kLWtpdC9jb3JlXCIsXHJcbiAgXCJAZG5kLWtpdC9tb2RpZmllcnNcIixcclxuICBcIkBkbmQta2l0L3NvcnRhYmxlXCIsXHJcbiAgXCJAZG5kLWtpdC91dGlsaXRpZXNcIixcclxuICB7XHJcbiAgICBuYW1lOiBcIm1vbWVudFwiLFxyXG4gICAgZXh0cmFjdERlZmF1bHQ6IHRydWUsXHJcbiAgfSxcclxuICB7XHJcbiAgICBuYW1lOiBcImRheWpzXCIsXHJcbiAgICBleHRyYWN0RGVmYXVsdDogdHJ1ZSxcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6IFwibG93Y29kZXItc2RrXCIsXHJcbiAgICBmcm9tOiBcIi4vc3JjL2luZGV4LnNkay50c1wiLFxyXG4gIH0sXHJcbiAge1xyXG4gICAgbmFtZTogXCJzdHlsZWQtY29tcG9uZW50c1wiLFxyXG4gICAgbWVyZ2VEZWZhdWx0QW5kTmFtZUV4cG9ydHM6IHRydWUsXHJcbiAgfSxcclxuXTtcclxuXHJcbi8qKlxyXG4gKiBnZXQgZ2xvYmFsIHZhciBuYW1lIGZyb20gbW9kdWxlIG5hbWVcclxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcclxuICogQHJldHVybnNcclxuICovXHJcbmV4cG9ydCBjb25zdCBnZXRMaWJHbG9iYWxWYXJOYW1lID0gKG5hbWUpID0+IHtcclxuICByZXR1cm4gXCIkXCIgKyBuYW1lLnJlcGxhY2UoL0AvZywgXCIkXCIpLnJlcGxhY2UoL1tcXC9cXC1dL2csIFwiX1wiKTtcclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBnZXRMaWJOYW1lcyA9ICgpID0+IHtcclxuICByZXR1cm4gbGlicy5tYXAoKGkpID0+IHtcclxuICAgIGlmICh0eXBlb2YgaSA9PT0gXCJvYmplY3RcIikge1xyXG4gICAgICByZXR1cm4gaS5uYW1lO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGk7XHJcbiAgfSk7XHJcbn07XHJcblxyXG5leHBvcnQgY29uc3QgZ2V0QWxsTGliR2xvYmFsVmFyTmFtZXMgPSAoKSA9PiB7XHJcbiAgY29uc3QgcmV0ID0ge307XHJcbiAgbGlicy5mb3JFYWNoKChsaWIpID0+IHtcclxuICAgIGxldCBuYW1lID0gbGliO1xyXG4gICAgaWYgKHR5cGVvZiBsaWIgPT09IFwib2JqZWN0XCIpIHtcclxuICAgICAgbmFtZSA9IGxpYi5uYW1lO1xyXG4gICAgfVxyXG4gICAgcmV0W25hbWVdID0gZ2V0TGliR2xvYmFsVmFyTmFtZShuYW1lKTtcclxuICB9KTtcclxuICByZXR1cm4gcmV0O1xyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IGxpYnNJbXBvcnRDb2RlID0gKGV4Y2x1ZGUgPSBbXSkgPT4ge1xyXG4gIGNvbnN0IGltcG9ydExpbmVzID0gW107XHJcbiAgY29uc3QgYXNzaWduTGluZXMgPSBbXTtcclxuICBsaWJzLmZvckVhY2goKGkpID0+IHtcclxuICAgIGxldCBuYW1lID0gaTtcclxuICAgIGxldCBtZXJnZSA9IGZhbHNlO1xyXG4gICAgbGV0IGZyb20gPSBuYW1lO1xyXG4gICAgbGV0IGV4dHJhY3REZWZhdWx0ID0gZmFsc2U7XHJcblxyXG4gICAgaWYgKHR5cGVvZiBpID09PSBcIm9iamVjdFwiKSB7XHJcbiAgICAgIG5hbWUgPSBpLm5hbWU7XHJcbiAgICAgIG1lcmdlID0gaS5tZXJnZURlZmF1bHRBbmROYW1lRXhwb3J0cyA/PyBmYWxzZTtcclxuICAgICAgZnJvbSA9IGkuZnJvbSA/PyBuYW1lO1xyXG4gICAgICBleHRyYWN0RGVmYXVsdCA9IGkuZXh0cmFjdERlZmF1bHQgPz8gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGV4Y2x1ZGUuaW5jbHVkZXMobmFtZSkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHZhck5hbWUgPSBnZXRMaWJHbG9iYWxWYXJOYW1lKG5hbWUpO1xyXG4gICAgaWYgKG1lcmdlKSB7XHJcbiAgICAgIGltcG9ydExpbmVzLnB1c2goYGltcG9ydCAqIGFzICR7dmFyTmFtZX1fbmFtZWRfZXhwb3J0cyBmcm9tICcke2Zyb219JztgKTtcclxuICAgICAgaW1wb3J0TGluZXMucHVzaChgaW1wb3J0ICR7dmFyTmFtZX0gZnJvbSAnJHtmcm9tfSc7YCk7XHJcbiAgICAgIGFzc2lnbkxpbmVzLnB1c2goYE9iamVjdC5hc3NpZ24oJHt2YXJOYW1lfSwgJHt2YXJOYW1lfV9uYW1lZF9leHBvcnRzKTtgKTtcclxuICAgIH0gZWxzZSBpZiAoZXh0cmFjdERlZmF1bHQpIHtcclxuICAgICAgaW1wb3J0TGluZXMucHVzaChgaW1wb3J0ICR7dmFyTmFtZX0gZnJvbSAnJHtmcm9tfSc7YCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpbXBvcnRMaW5lcy5wdXNoKGBpbXBvcnQgKiBhcyAke3Zhck5hbWV9IGZyb20gJyR7ZnJvbX0nO2ApO1xyXG4gICAgfVxyXG4gICAgYXNzaWduTGluZXMucHVzaChgd2luZG93LiR7dmFyTmFtZX0gPSAke3Zhck5hbWV9O2ApO1xyXG4gIH0pO1xyXG4gIHJldHVybiBpbXBvcnRMaW5lcy5jb25jYXQoYXNzaWduTGluZXMpLmpvaW4oXCJcXG5cIik7XHJcbn07XHJcbiIsICJjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSA9IFwiQzpcXFxcUHJvamVjdHNcXFxcbG93Y29kZXJcXFxcY2xpZW50XFxcXHBhY2thZ2VzXFxcXGxvd2NvZGVyXFxcXHNyY1xcXFxkZXYtdXRpbHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkM6XFxcXFByb2plY3RzXFxcXGxvd2NvZGVyXFxcXGNsaWVudFxcXFxwYWNrYWdlc1xcXFxsb3djb2RlclxcXFxzcmNcXFxcZGV2LXV0aWxzXFxcXGdsb2JhbERlcFBsZ3Vpbi5qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vQzovUHJvamVjdHMvbG93Y29kZXIvY2xpZW50L3BhY2thZ2VzL2xvd2NvZGVyL3NyYy9kZXYtdXRpbHMvZ2xvYmFsRGVwUGxndWluLmpzXCI7aW1wb3J0IHsgbGlic0ltcG9ydENvZGUgfSBmcm9tIFwiLi9leHRlcm5hbC5qc1wiO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdsb2JhbERlcFBsdWdpbihleGNsdWRlID0gW10pIHtcclxuICBjb25zdCB2aXJ0dWFsTW9kdWxlSWQgPSBcInZpcnR1YWw6Z2xvYmFsc1wiO1xyXG4gIHJldHVybiB7XHJcbiAgICBuYW1lOiBcImxvd2NvZGVyLWdsb2JhbC1wbHVnaW5cIixcclxuICAgIHJlc29sdmVJZChpZCkge1xyXG4gICAgICBpZiAoaWQgPT09IHZpcnR1YWxNb2R1bGVJZCkge1xyXG4gICAgICAgIHJldHVybiBpZDtcclxuICAgICAgfVxyXG4gICAgfSxcclxuICAgIGxvYWQoaWQpIHtcclxuICAgICAgaWYgKGlkID09PSB2aXJ0dWFsTW9kdWxlSWQpIHtcclxuICAgICAgICByZXR1cm4gbGlic0ltcG9ydENvZGUoZXhjbHVkZSk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcbiAgfTtcclxufVxyXG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQXVVLE9BQU8sWUFBWTtBQUMxVixTQUFTLG9CQUErQztBQUN4RCxPQUFPLFdBQVc7QUFDbEIsT0FBTyx1QkFBdUI7QUFDOUIsT0FBTyxnQkFBZ0I7QUFDdkIsT0FBTyxhQUFhO0FBQ3BCLFNBQVMsa0JBQWtCO0FBQzNCLE9BQU8sVUFBVTtBQUNqQixPQUFPLFdBQVc7QUFDbEIsU0FBUyx3QkFBd0I7OztBQ0UxQixTQUFTLGdCQUFnQixLQUFLO0FBQ25DLE1BQUksQ0FBQyxLQUFLO0FBQ1IsV0FBTztBQUFBLEVBQ1Q7QUFDQSxNQUFJLENBQUMsSUFBSSxTQUFTLEdBQUcsR0FBRztBQUN0QixXQUFPLEdBQUcsR0FBRztBQUFBLEVBQ2Y7QUFDQSxTQUFPO0FBQ1Q7OztBQ25Cc1gsSUFBTSxZQUFZO0FBQUEsRUFDdFk7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUNGOzs7QUNwRE8sSUFBTSxPQUFPO0FBQUEsRUFDbEI7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLElBQ0UsTUFBTTtBQUFBLElBQ04sZ0JBQWdCO0FBQUEsRUFDbEI7QUFBQSxFQUNBO0FBQUEsSUFDRSxNQUFNO0FBQUEsSUFDTixnQkFBZ0I7QUFBQSxFQUNsQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxFQUNSO0FBQUEsRUFDQTtBQUFBLElBQ0UsTUFBTTtBQUFBLElBQ04sNEJBQTRCO0FBQUEsRUFDOUI7QUFDRjtBQU9PLElBQU0sc0JBQXNCLENBQUMsU0FBUztBQUMzQyxTQUFPLE1BQU0sS0FBSyxRQUFRLE1BQU0sR0FBRyxFQUFFLFFBQVEsV0FBVyxHQUFHO0FBQzdEO0FBdUJPLElBQU0saUJBQWlCLENBQUMsVUFBVSxDQUFDLE1BQU07QUFDOUMsUUFBTSxjQUFjLENBQUM7QUFDckIsUUFBTSxjQUFjLENBQUM7QUFDckIsT0FBSyxRQUFRLENBQUMsTUFBTTtBQUNsQixRQUFJLE9BQU87QUFDWCxRQUFJLFFBQVE7QUFDWixRQUFJLE9BQU87QUFDWCxRQUFJLGlCQUFpQjtBQUVyQixRQUFJLE9BQU8sTUFBTSxVQUFVO0FBQ3pCLGFBQU8sRUFBRTtBQUNULGNBQVEsRUFBRSw4QkFBOEI7QUFDeEMsYUFBTyxFQUFFLFFBQVE7QUFDakIsdUJBQWlCLEVBQUUsa0JBQWtCO0FBQUEsSUFDdkM7QUFFQSxRQUFJLFFBQVEsU0FBUyxJQUFJLEdBQUc7QUFDMUI7QUFBQSxJQUNGO0FBRUEsVUFBTSxVQUFVLG9CQUFvQixJQUFJO0FBQ3hDLFFBQUksT0FBTztBQUNULGtCQUFZLEtBQUssZUFBZSxPQUFPLHdCQUF3QixJQUFJLElBQUk7QUFDdkUsa0JBQVksS0FBSyxVQUFVLE9BQU8sVUFBVSxJQUFJLElBQUk7QUFDcEQsa0JBQVksS0FBSyxpQkFBaUIsT0FBTyxLQUFLLE9BQU8sa0JBQWtCO0FBQUEsSUFDekUsV0FBVyxnQkFBZ0I7QUFDekIsa0JBQVksS0FBSyxVQUFVLE9BQU8sVUFBVSxJQUFJLElBQUk7QUFBQSxJQUN0RCxPQUFPO0FBQ0wsa0JBQVksS0FBSyxlQUFlLE9BQU8sVUFBVSxJQUFJLElBQUk7QUFBQSxJQUMzRDtBQUNBLGdCQUFZLEtBQUssVUFBVSxPQUFPLE1BQU0sT0FBTyxHQUFHO0FBQUEsRUFDcEQsQ0FBQztBQUNELFNBQU8sWUFBWSxPQUFPLFdBQVcsRUFBRSxLQUFLLElBQUk7QUFDbEQ7OztBQ25HTyxTQUFTLGdCQUFnQixVQUFVLENBQUMsR0FBRztBQUM1QyxRQUFNLGtCQUFrQjtBQUN4QixTQUFPO0FBQUEsSUFDTCxNQUFNO0FBQUEsSUFDTixVQUFVLElBQUk7QUFDWixVQUFJLE9BQU8saUJBQWlCO0FBQzFCLGVBQU87QUFBQSxNQUNUO0FBQUEsSUFDRjtBQUFBLElBQ0EsS0FBSyxJQUFJO0FBQ1AsVUFBSSxPQUFPLGlCQUFpQjtBQUMxQixlQUFPLGVBQWUsT0FBTztBQUFBLE1BQy9CO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFDRjs7O0FKakJBLElBQU0sbUNBQW1DO0FBY3pDLE9BQU8sT0FBTztBQUVkLElBQU0saUJBQWlCLFFBQVEsSUFBSTtBQUNuQyxJQUFNLDRCQUE0QixRQUFRLElBQUk7QUFDOUMsSUFBTSxVQUFVLFFBQVEsSUFBSSxZQUFZO0FBQ3hDLElBQU0sVUFBVSxRQUFRLElBQUk7QUFDNUIsSUFBTSxhQUFhLFlBQVk7QUFDL0IsSUFBTSxPQUFPLFlBQVksZ0JBQWdCO0FBQ3pDLElBQU0sUUFBUSxZQUFZO0FBQzFCLElBQU0sc0JBQXNCLENBQUMsQ0FBQyxRQUFRLElBQUk7QUFHMUMsSUFBTSx1QkFBdUI7QUFDN0IsSUFBTSxPQUFPLGdCQUFnQixRQUFRLElBQUksVUFBVTtBQUVuRCxJQUFJLENBQUMsa0JBQWtCLE9BQU87QUFDNUIsVUFBUSxJQUFJO0FBQ1osVUFBUSxJQUFJLE1BQU0sNENBQTRDO0FBQzlELFVBQVEsSUFBSSxNQUFNLGtGQUFrRjtBQUNwRyxVQUFRLElBQUk7QUFDWixVQUFRLEtBQUssQ0FBQztBQUNoQjtBQUVBLElBQU0sY0FBc0M7QUFBQSxFQUMxQyxRQUFRO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixjQUFjO0FBQUEsRUFDaEI7QUFDRjtBQUVBLElBQUksMkJBQTJCO0FBQzdCLGNBQVksZUFBZSxJQUFJO0FBQUEsSUFDN0IsUUFBUTtBQUFBLEVBQ1Y7QUFDRjtBQUVBLElBQU0sU0FBUyxDQUFDO0FBQ2hCLFVBQVUsUUFBUSxDQUFDLEVBQUUsTUFBTSxhQUFhLE1BQU07QUFDNUMsU0FBTyxJQUFJLElBQUksS0FBSyxVQUFVLFFBQVEsSUFBSSxJQUFJLEtBQUssWUFBWTtBQUNqRSxDQUFDO0FBR00sSUFBTSxhQUF5QjtBQUFBLEVBQ3BDO0FBQUEsRUFDQSxlQUFlLENBQUMsU0FBUztBQUFBLEVBQ3pCLFNBQVM7QUFBQSxJQUNQLFlBQVksQ0FBQyxRQUFRLE9BQU8sT0FBTyxRQUFRLFFBQVEsT0FBTztBQUFBLElBQzFELE9BQU87QUFBQSxNQUNMLGdCQUFnQixLQUFLO0FBQUEsUUFDbkI7QUFBQSxRQUNBLE9BQU8sbUJBQW1CLGFBQWEsY0FBYyxJQUFJLEtBQUs7QUFBQSxNQUNoRTtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQUEsRUFDQTtBQUFBLEVBQ0EsT0FBTztBQUFBLElBQ0wsVUFBVTtBQUFBLElBQ1YsUUFBUTtBQUFBLElBQ1IsV0FBVztBQUFBLElBQ1gsUUFBUTtBQUFBLElBQ1IsV0FBVztBQUFBLElBQ1gsYUFBYTtBQUFBLElBQ2IsZUFBZTtBQUFBLE1BQ2IsUUFBUTtBQUFBLFFBQ04sZ0JBQWdCO0FBQUEsTUFDbEI7QUFBQSxJQUNGO0FBQUEsSUFDQSxpQkFBaUI7QUFBQSxNQUNmLHdCQUF3QixDQUFDLE9BQU87QUFDOUIsWUFBSSxHQUFHLFFBQVEsVUFBVSxNQUFNLElBQUk7QUFDakMsaUJBQU87QUFBQSxRQUNUO0FBQ0EsZUFBTztBQUFBLE1BQ1Q7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUFBLEVBQ0EsS0FBSztBQUFBLElBQ0gscUJBQXFCO0FBQUEsTUFDbkIsTUFBTTtBQUFBLFFBQ0osWUFBWTtBQUFBLFVBQ1Ysa0JBQWtCO0FBQUEsVUFDbEIsZUFBZTtBQUFBLFVBQ2Ysc0JBQXNCO0FBQUEsVUFDdEIsdUJBQXVCO0FBQUEsUUFDekI7QUFBQSxRQUNBLG1CQUFtQjtBQUFBLE1BQ3JCO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFBQSxFQUNBLFFBQVE7QUFBQSxJQUNOLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxJQUNOLE9BQU87QUFBQSxFQUNUO0FBQUEsRUFDQSxTQUFTO0FBQUEsSUFDUCxRQUFRO0FBQUEsTUFDTixZQUFZO0FBQUEsTUFDWixRQUFRO0FBQUEsUUFDTixhQUFhO0FBQUEsUUFDYixLQUFLO0FBQUEsVUFDSCxVQUFVLENBQUMsT0FBTztBQUFBLFFBQ3BCO0FBQUEsTUFDRjtBQUFBLElBQ0YsQ0FBQztBQUFBLElBQ0QsTUFBTTtBQUFBLE1BQ0osT0FBTztBQUFBLFFBQ0wsWUFBWTtBQUFBLFVBQ1YsU0FBUyxDQUFDLG1CQUFtQjtBQUFBLFFBQy9CO0FBQUEsTUFDRjtBQUFBLElBQ0YsQ0FBQztBQUFBLElBQ0Qsa0JBQWtCO0FBQUEsTUFDaEIsVUFBVSxDQUFDLDZCQUE2QixrQ0FBa0M7QUFBQSxJQUM1RSxDQUFDO0FBQUEsSUFDRCxXQUFXO0FBQUEsTUFDVCxhQUFhO0FBQUEsUUFDWCxZQUFZO0FBQUEsUUFDWixVQUFVO0FBQUEsUUFDVixNQUFNO0FBQUEsUUFDTixXQUFXO0FBQUEsUUFDWCxLQUFLO0FBQUEsTUFDUDtBQUFBLElBQ0YsQ0FBQztBQUFBLElBQ0QsZ0JBQWdCO0FBQUEsSUFDaEIsaUJBQWlCO0FBQUEsTUFDZixRQUFRO0FBQUEsTUFDUixRQUFRO0FBQUEsUUFDTixNQUFNO0FBQUEsVUFDSixvQkFBb0IsUUFBUSxLQUFLLGdCQUFnQixJQUFJLEdBQUcsb0JBQW9CO0FBQUEsUUFDOUU7QUFBQSxNQUNGO0FBQUEsSUFDRixDQUFDO0FBQUEsSUFDRCx1QkFBdUIsV0FBVztBQUFBLEVBQ3BDLEVBQUUsT0FBTyxPQUFPO0FBQ2xCO0FBRUEsSUFBTSxxQkFBaUM7QUFBQSxFQUNyQyxHQUFHO0FBQUEsRUFDSCxRQUFRO0FBQUEsSUFDTixHQUFHLFdBQVc7QUFBQSxJQUNkLHdCQUF3QixLQUFLLFVBQVUsWUFBWTtBQUFBLEVBQ3JEO0FBQUEsRUFDQSxPQUFPO0FBQUEsSUFDTCxHQUFHLFdBQVc7QUFBQSxJQUNkLFVBQVU7QUFBQSxJQUNWLGVBQWU7QUFBQSxJQUNmLGFBQWE7QUFBQSxJQUNiLEtBQUs7QUFBQSxNQUNILFNBQVMsQ0FBQyxNQUFNO0FBQUEsTUFDaEIsTUFBTTtBQUFBLE1BQ04sT0FBTztBQUFBLE1BQ1AsVUFBVSxNQUFNO0FBQ2QsZUFBTztBQUFBLE1BQ1Q7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUNGO0FBRUEsSUFBTSxlQUFlO0FBQUEsRUFDbkIsTUFBTTtBQUFBLEVBQ04sY0FBYztBQUNoQjtBQUVBLElBQU0sY0FBYyxhQUFhLFFBQVEsSUFBSSxnQkFBZ0IsTUFBTTtBQUVuRSxJQUFPLHNCQUFRLGFBQWEsZUFBZSxVQUFVOyIsCiAgIm5hbWVzIjogW10KfQo=

From 8fd726c954c6cb4de310639a11c65a781fe72159 Mon Sep 17 00:00:00 2001
From: Imtanan Aziz Toor <imtanan.aziz@ikhwatech.com>
Date: Thu, 15 Feb 2024 21:15:52 +0500
Subject: [PATCH 44/97] Text area font style added

---
 .../tableComp/column/tableColumnComp.tsx      | 28 ++++++----
 .../comps/comps/tableComp/tableCompView.tsx   | 56 +++++++++++--------
 .../src/comps/comps/tableComp/tableTypes.tsx  |  2 +-
 .../src/comps/comps/tableComp/tableUtils.tsx  |  2 +
 .../comps/controls/styleControlConstants.tsx  |  8 ++-
 5 files changed, 59 insertions(+), 37 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
index 39a392ad4c..0de0247954 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx
@@ -108,6 +108,7 @@ export const columnChildrenMap = {
   textSize: withDefault(RadiusControl, ""),
   textWeight: withDefault(StringControl, "normal"),
   fontFamily: withDefault(StringControl, "sans-serif"),
+  fontStyle: withDefault(StringControl, 'normal'),
   cellColor: CellColorComp,
   textOverflow: withDefault(TextOverflowControl, "ellipsis"),
   linkColor: withDefault(ColorControl, "#3377ff"),
@@ -155,10 +156,10 @@ export class ColumnComp extends ColumnInitComp {
         )
       );
     }
-    if(action.type === CompActionTypes.CHANGE_VALUE) {
+    if (action.type === CompActionTypes.CHANGE_VALUE) {
       const title = comp.children.title.unevaledValue;
       const dataIndex = comp.children.dataIndex.getView();
-      if(!Boolean(title)) {
+      if (!Boolean(title)) {
         comp.children.title.dispatchChangeValueAction(dataIndex);
       }
     }
@@ -223,10 +224,10 @@ export class ColumnComp extends ColumnInitComp {
         })}
         {this.children.autoWidth.getView() === "fixed" &&
           this.children.width.propertyView({ label: trans("prop.width") })}
-        
+
         {(columnType === 'link' || columnType === 'links') && (
           <>
-            <Divider style={{margin: '12px 0'}} />
+            <Divider style={{ margin: '12px 0' }} />
             {controlItem({}, (
               <div>
                 <b>{"Link Style"}</b>
@@ -243,10 +244,10 @@ export class ColumnComp extends ColumnInitComp {
             })}
           </>
         )}
-        <Divider style={{margin: '12px 0'}} />
+        <Divider style={{ margin: '12px 0' }} />
         {controlItem({}, (
           <div>
-             <b>{"Column Style"}</b>
+            <b>{"Column Style"}</b>
           </div>
         ))}
         {this.children.background.propertyView({
@@ -260,29 +261,34 @@ export class ColumnComp extends ColumnInitComp {
         })}
         {this.children.borderWidth.propertyView({
           label: trans('style.borderWidth'),
-          preInputNode: <StyledBorderIcon as={BorderWidthIcon} title="" />,	
+          preInputNode: <StyledBorderIcon as={BorderWidthIcon} title="" />,
           placeholder: '1px',
         })}
         {this.children.radius.propertyView({
           label: trans('style.borderRadius'),
-          preInputNode: <StyledBorderRadiusIcon as={IconRadius} title="" />,	
+          preInputNode: <StyledBorderRadiusIcon as={IconRadius} title="" />,
           placeholder: '3px',
         })}
         {this.children.textSize.propertyView({
           label: trans('style.textSize'),
-          preInputNode: <StyledTextSizeIcon as={TextSizeIcon} title="" />,	
+          preInputNode: <StyledTextSizeIcon as={TextSizeIcon} title="" />,
           placeholder: '14px',
         })}
         {this.children.textWeight.propertyView({
           label: trans('style.textWeight'),
-          preInputNode: <StyledTextWeightIcon as={TextWeigthIcon} title="" />,	
+          preInputNode: <StyledTextWeightIcon as={TextWeigthIcon} title="" />,
           placeholder: 'normal',
         })}
         {this.children.fontFamily.propertyView({
           label: trans('style.fontFamily'),
-          preInputNode: <StyledFontFamilyIcon as={FontFamilyIcon} title="" />,	
+          preInputNode: <StyledFontFamilyIcon as={FontFamilyIcon} title="" />,
           placeholder: 'sans-serif',
         })}
+        {this.children.fontStyle.propertyView({
+          label: trans('style.fontStyle'),
+          preInputNode: <StyledFontFamilyIcon as={FontFamilyIcon} title="" />,
+          placeholder: 'normal'
+        })}
         {this.children.textOverflow.getPropertyView()}
         {this.children.cellColor.getPropertyView()}
       </>
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
index 729e8f6b9c..f16db203e3 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
@@ -51,7 +51,7 @@ const getStyle = (
   style: TableStyleType,
   rowStyle: TableRowStyleType,
   headerStyle: TableHeaderStyleType,
-  toolbarStyle: TableToolbarStyleType
+  toolbarStyle: TableToolbarStyleType,
 ) => {
   const background = genLinerGradient(style.background);
   const selectedRowBackground = genLinerGradient(rowStyle.selectedRowBackground);
@@ -140,7 +140,8 @@ const BackgroundWrapper = styled.div<{
   background: ${(props) => props.$style.background} !important;
   border: ${(props) => `${props.$style.borderWidth} solid ${props.$style.border} !important`};
   border-radius: ${(props) => props.$style.radius} !important;
-  padding: unset !important;
+  // padding: unset !important;
+  padding: ${(props) => props.$style.padding} !important
   margin: ${(props) => props.$style.margin} !important;
   overflow: scroll !important;
   ${(props) => props.$style}
@@ -209,18 +210,19 @@ const TableWrapper = styled.div<{
         > .ant-table-thead {
           > tr > th {
             background-color: ${(props) => props.$headerStyle.headerBackground};
+           
             border-color: ${(props) => props.$headerStyle.border};
             border-width: ${(props) => props.$headerStyle.borderWidth};
             color: ${(props) => props.$headerStyle.headerText};
             border-inline-end: ${(props) => `${props.$headerStyle.borderWidth} solid ${props.$headerStyle.border}`} !important;
-            ${(props) => 
-              props.$fixedHeader && `
+            ${(props) =>
+    props.$fixedHeader && `
                 position: sticky;
                 position: -webkit-sticky;
                 top: ${props.$fixedToolbar ? '47px' : '0'};
                 z-index: 99;
               `
-            }
+  }
 
             > div {
               margin: ${(props) => props.$headerStyle.margin};
@@ -229,6 +231,8 @@ const TableWrapper = styled.div<{
                 font-size: ${(props) => props.$headerStyle.textSize};
                 font-weight: ${(props) => props.$headerStyle.textWeight};
                 font-family: ${(props) => props.$headerStyle.fontFamily};
+                font-style: ${(props) => props.$headerStyle.fontStyle};
+                color:${(props) => props.$headerStyle.text}
               }
             }
 
@@ -286,8 +290,8 @@ const TableWrapper = styled.div<{
 
         // hide the bottom border of the last row
         ${(props) =>
-          props.$toolbarPosition !== "below" &&
-          `
+    props.$toolbarPosition !== "below" &&
+    `
             tbody > tr:last-child > td {
               border-bottom: unset;
             }
@@ -300,10 +304,10 @@ const TableWrapper = styled.div<{
     }
   }
   
-  ${(props) => 
+  ${(props) =>
     props.$style && getStyle(props.$style, props.$rowStyle, props.$headerStyle, props.$toolbarStyle)}
 `;
-  
+
 const TableTh = styled.th<{ width?: number }>`
   overflow: hidden;
 
@@ -318,7 +322,7 @@ const TableTh = styled.th<{ width?: number }>`
 
 const TableTd = styled.td<{
   $background: string;
-  $style: TableColumnStyleType & {rowHeight?: string};
+  $style: TableColumnStyleType & { rowHeight?: string };
   $defaultThemeDetail: ThemeDetail;
   $linkStyle?: TableColumnLinkStyleType;
   $isEditing: boolean;
@@ -348,7 +352,8 @@ const TableTd = styled.td<{
     
     ${(props) => props.$tableSize === 'small' && `
       padding: 1px 8px;
-      font-size: ${props.$defaultThemeDetail.textSize == props.$style.textSize ? '14px !important' : props.$style.textSize + ' !important' };
+      font-size: ${props.$defaultThemeDetail.textSize == props.$style.textSize ? '14px !important' : props.$style.textSize + ' !important'};
+    font-style:${props.$style.fontStyle} !important;
       min-height: ${props.$style.rowHeight || '14px'};
       line-height: 20px;
       ${!props.$autoHeight && `
@@ -358,7 +363,8 @@ const TableTd = styled.td<{
     `};
     ${(props) => props.$tableSize === 'middle' && `
       padding: 8px 8px;
-      font-size: ${props.$defaultThemeDetail.textSize == props.$style.textSize ? '16px !important' : props.$style.textSize + ' !important' };
+      font-size: ${props.$defaultThemeDetail.textSize == props.$style.textSize ? '16px !important' : props.$style.textSize + ' !important'};
+      font-style:${props.$style.fontStyle} !important;
       min-height: ${props.$style.rowHeight || '24px'};
       line-height: 24px;
       ${!props.$autoHeight && `
@@ -368,7 +374,8 @@ const TableTd = styled.td<{
     `};
     ${(props) => props.$tableSize === 'large' && `
       padding: 16px 16px;
-      font-size: ${props.$defaultThemeDetail.textSize == props.$style.textSize ? '18px !important' : props.$style.textSize + ' !important' };
+      font-size: ${props.$defaultThemeDetail.textSize == props.$style.textSize ? '18px !important' : props.$style.textSize + ' !important'};
+      font-style:${props.$style.fontStyle} !important;
       min-height: ${props.$style.rowHeight || '48px'};
       ${!props.$autoHeight && `
         overflow-y: auto;
@@ -444,7 +451,7 @@ const ResizeableTitle = (props: any) => {
       draggableOpts={{ enableUserSelectHack: false }}
       handle={(axis: ResizeHandleAxis, ref: ReactRef<HTMLDivElement>) => (
         <TitleResizeHandle
-          ref={ref} 
+          ref={ref}
           onClick={(e) => {
             e.preventDefault();
             e.stopPropagation();
@@ -519,7 +526,7 @@ function TableCellView(props: {
     const cellColor = cellColorFn({
       currentCell: record[title.toLowerCase()],
     });
-    
+
     const style = {
       background: cellColor || rowColor || columnStyle.background || columnsStyle.background,
       margin: columnStyle.margin || columnsStyle.margin,
@@ -530,6 +537,7 @@ function TableCellView(props: {
       textSize: columnStyle.textSize || columnsStyle.textSize,
       textWeight: columnStyle.textWeight || columnsStyle.textWeight,
       fontFamily: columnStyle.fontFamily || columnsStyle.fontFamily,
+      fontStyle: columnStyle.fontStyle || columnsStyle.fontStyle,
       rowHeight: rowHeight,
     }
     let { background } = style;
@@ -554,7 +562,7 @@ function TableCellView(props: {
       </TableTd>
     );
   }
-
+ 
   return (
     <TableCellContext.Provider value={{ isEditing: editing, setIsEditing: setEditing }}>
       {tdView}
@@ -804,7 +812,7 @@ export function TableCompView(props: {
 
   return (
     <BackgroundColorContext.Provider value={style.background} >
-      
+
       <BackgroundWrapper ref={ref} $style={style} $tableAutoHeight={tableAutoHeight}>
         {toolbar.position === "above" && toolbarView}
         <TableWrapper
@@ -826,11 +834,11 @@ export function TableCompView(props: {
                 : "OB_CHILDREN_KEY_PLACEHOLDER",
               fixed: "left",
               onExpand: (expanded) => {
-              if(expanded) {
-                handleChangeEvent('rowExpand')
-              } else {
-                handleChangeEvent('rowShrink')
-              }
+                if (expanded) {
+                  handleChangeEvent('rowExpand')
+                } else {
+                  handleChangeEvent('rowShrink')
+                }
               }
             }}
             rowColorFn={compChildren.rowColor.getView() as any}
@@ -857,14 +865,14 @@ export function TableCompView(props: {
               compChildren.loading.getView()
             }
           />
-          
+
           <SlotConfigContext.Provider value={{ modalWidth: width && Math.max(width, 300) }}>
             {expansion.expandModalView}
           </SlotConfigContext.Provider>
         </TableWrapper>
         {toolbar.position === "below" && toolbarView}
       </BackgroundWrapper>
-      
+
     </BackgroundColorContext.Provider>
   );
 }
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx
index 90f5f0a6c6..41a846c19e 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx
@@ -210,7 +210,7 @@ const tableChildrenMap = {
   toolbarStyle: styleControl(TableToolbarStyle),
   headerStyle: styleControl(TableHeaderStyle),
   searchText: StringControl,
-  columnsStyle: withDefault(styleControl(TableColumnStyle), {borderWidth: '1px', radius: '0px'}),
+  columnsStyle: withDefault(styleControl(TableColumnStyle), {borderWidth: '1px', radius: '0px',fontStyle:'italic'}),
   viewModeResizable: BoolControl,
   visibleResizables: BoolControl,
   // sample data for regenerating columns
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
index 4532475c8e..83bc941d72 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx
@@ -311,6 +311,7 @@ export function columnsToAntdFormat(
       status: StatusType;
     }[];
     const title = renderTitle({ title: column.title, editable: column.editable });
+   
     return {
       title: column.showTitle ? title : '',
       titleText: column.title,
@@ -326,6 +327,7 @@ export function columnsToAntdFormat(
         radius: column.radius,
         textSize: column.textSize,
         textWeight: column.textWeight,
+        fontStyle:column.fontStyle,
         fontFamily: column.fontFamily,
         borderWidth: column.borderWidth,
       },
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index f8fa415a86..c01fc0d0b6 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -920,6 +920,7 @@ const LinkTextStyle = [
 
 export const TableStyle = [
   MARGIN,
+  PADDING,
   ...BG_STATIC_BORDER_RADIUS,
   {
     name: "borderWidth",
@@ -943,6 +944,10 @@ export const TableToolbarStyle = [
 
 export const TableHeaderStyle = [
   MARGIN,
+  PADDING,
+  FONT_FAMILY,
+  FONT_STYLE,
+  TEXT,
   {
     name: "headerBackground",
     label: trans("style.tableHeaderBackground"),
@@ -1000,7 +1005,8 @@ export const TableColumnStyle = [
   TEXT,
   TEXT_SIZE,
   TEXT_WEIGHT,
-  FONT_FAMILY
+  FONT_FAMILY,
+  FONT_STYLE,
 ] as const;
 
 export const TableColumnLinkStyle = [

From a603a57f2dc5791564a55d52611b4910fccc3f2a Mon Sep 17 00:00:00 2001
From: Imtanan Aziz Toor <imtanan.aziz@ikhwatech.com>
Date: Thu, 15 Feb 2024 21:17:50 +0500
Subject: [PATCH 45/97] Table column styles working

---
 .../lowcoder/src/comps/comps/tableComp/tableCompView.tsx    | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
index f16db203e3..fcf99b18a0 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
@@ -535,9 +535,9 @@ function TableCellView(props: {
       radius: columnStyle.radius || columnsStyle.radius,
       borderWidth: columnStyle.borderWidth || columnsStyle.borderWidth,
       textSize: columnStyle.textSize || columnsStyle.textSize,
-      textWeight: columnStyle.textWeight || columnsStyle.textWeight,
-      fontFamily: columnStyle.fontFamily || columnsStyle.fontFamily,
-      fontStyle: columnStyle.fontStyle || columnsStyle.fontStyle,
+      textWeight: columnsStyle.textWeight || columnStyle.textWeight,
+      fontFamily: columnsStyle.fontFamily || columnStyle.fontFamily,
+      fontStyle: columnsStyle.fontStyle || columnStyle.fontStyle,
       rowHeight: rowHeight,
     }
     let { background } = style;

From 0bc7f5b666cfeb14d612b25fcef4039b302d11da Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Thu, 15 Feb 2024 21:50:05 +0100
Subject: [PATCH 46/97] Control of Component Properties

---
 client/package.json                           |   2 +-
 .../src/pages/editor/LeftLayersContent.tsx    | 189 ++++++++++++++----
 .../src/pages/editor/styledComponents.tsx     |  10 +-
 3 files changed, 163 insertions(+), 38 deletions(-)

diff --git a/client/package.json b/client/package.json
index 2f49baf8c4..fccf0fff11 100644
--- a/client/package.json
+++ b/client/package.json
@@ -1,6 +1,6 @@
 {
   "name": "lowcoder-root",
-  "version": "2.2.0",
+  "version": "2.3.0",
   "type": "module",
   "private": true,
   "workspaces": [
diff --git a/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx b/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
index 5f2aeb25bd..9fd7e68045 100644
--- a/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
+++ b/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
@@ -1,28 +1,21 @@
 import { CompInfo, EditorContext } from "comps/editorState";
 import {
   BaseSection,
-  Collapse,
   CollapseLabel as Label,
   CollapseTitle as Title,
   FoldedIcon,
   LeftCommon,
   ScrollBar,
-  Tooltip,
   UnfoldIcon,
-  LeftLayersIcon,
-  GridIcon,
   LeftShow,
-  LeftHide,
-  LeftLock,
-  LeftUnlock,
 } from "lowcoder-design";
-import React, { ReactNode, useCallback, useContext, useMemo, useState, useEffect } from "react";
+import React, { useCallback, useContext, useMemo, useState, useEffect, useRef } from "react";
 import _, { get } from "lodash";
 import styled from "styled-components";
 import { leftCompListClassName } from "pages/tutorials/tutorialsConstant";
 import UIComp from "comps/comps/uiComp";
-import { getParentNodeKeysByKey, getTreeNodeByKey, safeJSONStringify } from "util/objectUtils";
-import { BackgroundColor, TopHeaderHeight } from "constants/style";
+import { getTreeNodeByKey } from "util/objectUtils";
+import { TopHeaderHeight } from "constants/style";
 import { trans } from "i18n";
 import { CompTree } from "comps/comps/containerBase";
 import { CompStateIcon } from "./editorConstants";
@@ -32,7 +25,6 @@ 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";
 import { Button, Divider, Dropdown, Flex, Input, Menu, MenuProps, Space } from "antd";
 import { Switch } from "antd";
 import {
@@ -42,6 +34,7 @@ import {
 import { check, withViewFn } from "@lowcoder-ee/index.sdk";
 import { DownOutlined } from "@ant-design/icons";
 import { ItemType } from "antd/es/menu/hooks/useItems";
+import ColorPicker, { configChangeParams } from "components/ColorPicker";
 
 
 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) => {
 
   const [checkedKeys, setCheckedKeys] = useState<string[]>([]);
   const [actionValue, setActionValue] = useState<string>("");
+  const [selectedActionKey, setSelectedActionKey] = useState<string | null>(null);
+  const [placeholderText, setPlaceholderText] = useState<string>("");
+  const [color, setColor] = useState<string>("");
 
-  const handleActionValueChange = (e: any) => {
+  const handleColorChange = (color: string | undefined, actionType: string) => {
+    const newColor = color || '#ffffff';
+
+    for (let key of getCheckedKeys()) {
+      const node = getTreeNodeByKey(componentTreeData, key);
+      const comp = editorState.getUICompByName(node.title);
+      if(comp) {
+        const { children } = comp.children.comp;
+        const compType = comp.children.compType.getView();
+        const types = actionType.split('.');
+        if(types.length === 1) { // e.g hidden, disabled
+          children[types[0]]?.dispatchChangeValueAction(color);
+        }
+        else if(types.length === 2) { // nested object e.g. style.background
+          console.log(children[types[0]]);
+          if (!children[types[0]]) {
+            if (children[compType].children[types[0]]?.children[types[1]]) {
+              children[compType].children[types[0]].children[types[1]]?.dispatchChangeValueAction(color);
+            }
+          }
+          else {
+            if (children[types[0]].children[types[1]]) {
+              children[types[0]].children[types[1]]?.dispatchChangeValueAction(color);
+            }
+            else {
+              children[types[0]][types[1]]?.dispatchChangeValueAction(color);
+            }
+          }
+        }
+      }
+    }
+  };
+
+
+  /* const handleActionValueChange = (e: any) => {
     setActionValue(e.target.value);
-  }
+  } */
 
   // sync selected components with checked keys
   useEffect(() => {
@@ -267,6 +297,12 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
     setCheckedKeys(selectedComponentsOnCanvas);
   }, [editorState]);
 
+  // make sure to handle the selectedActionKey for the changed input fields
+  useEffect(() => {
+    setActionValue('');
+    setColor('#ffffff');
+  }, [selectedActionKey, placeholderText]);
+
   const onCheck = (checkedKeys: any, e: any) => {
     setCheckedKeys(checkedKeys);
     const checkedComponents = new Set<string>();
@@ -290,29 +326,36 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
       const node = getTreeNodeByKey(componentTreeData, key);
       const comp = editorState.getUICompByName(node.title);
       if(comp) {
-        const { children } = comp.children.comp
+        const { children } = comp.children.comp;
+        const compType = comp.children.compType.getView();
         const types = actionType.split('.');
-
         if(types.length === 1) { // e.g hidden, disabled
           children[types[0]]?.dispatchChangeValueAction(value);
         }
         else if(types.length === 2) { // nested object e.g. style.background
-          children[types[0]][types[1]]?.dispatchChangeValueAction(value);
+          console.log(children[types[0]]);
+          if (!children[types[0]]) {
+            if (children[compType].children[types[0]]?.children[types[1]]) {
+              children[compType].children[types[0]].children[types[1]]?.dispatchChangeValueAction(value);
+            }
+          }
+          else {
+            if (children[types[0]].children[types[1]]) {
+              children[types[0]].children[types[1]]?.dispatchChangeValueAction(value);
+            }
+            else {
+              children[types[0]][types[1]]?.dispatchChangeValueAction(value);
+            }
+          }
         }
       }
     }
   }, [getActionValue, getCheckedKeys]);
 
-  /* 
-
-  dispatch(
-        multiChangeAction({
-          width: changeValueAction(width, true),
-          autoWidth: changeValueAction("fixed", true),
-        })
-      );
-
-  */
+  const handleActionSelection = useCallback((key: string) => {
+    setSelectedActionKey(key);
+    setPlaceholderText(getPlaceholderText(key));
+  }, [handleComponentsActions]);
 
   const layerActions: ItemType[] = [
     {
@@ -324,15 +367,63 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
       key: 'disable',
     },
     {
-      label: 'Component Background',
-      key: 'style.background',
+      label: 'Margin',
+      key: 'style.margin',
+    },
+    {
+      label: 'Padding',
+      key: 'style.padding',
+    },
+    {
+      label: 'Border Radius',
+      key: 'style.radius',
     },
     {
-      label: 'Unlock',
-      key: '4',
+      label: 'Border Width',
+      key: 'style.borderWidth',
     },
+    {
+      label: 'Font Size',
+      key: 'style.textSize',
+    },
+    {
+      label: 'Font Weight',
+      key: 'style.textWeight',
+    },
+    {
+      label: 'Font Family',
+      key: 'style.fontFamily',
+    }
   ];
 
+
+  const getPlaceholderText = (key: string) => {
+    switch (key) {
+      case 'hidden':
+      case 'disable':
+        return 'true | false';
+      case 'style.background':
+      case 'style.text':
+      case 'style.border':
+        return 'e.g., #ffffff'; // Indicate example format
+      case 'style.radius':
+        return 'e.g., 4px'; // Indicate example format
+      case 'style.borderWidth':
+        return 'e.g., 2px'; // Indicate example format
+      case 'style.textSize':
+        return 'e.g., 16px'; // Indicate example format
+      case 'style.textWeight':
+        return 'bold | 900';
+      case 'style.fontFamily':
+        return 'Arial, sans-serif';
+      case 'style.margin':
+      case 'style.padding':
+        return 'e.g., 4px 8px 16px 32px'; // Indicate example format
+      default:
+        return 'Action Value';
+    }
+  };  
+  
   const getTreeUI = () => {
     // here the components get sorted by name
     // TODO: sort by category
@@ -367,7 +458,7 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
           onDrop={(info) => handleDrop(info)}
           treeData={componentTreeData}
           icon={(props: any) => props.type && (
-            <div style={{ margin: '3px 0 0 -3px'}}> {/* Adjust the margin as needed */}
+            <div style={{ margin: '3px 4px 0 -4px'}}> {/* Adjust the margin as needed */}
               {CompStateIcon[props.type as UICompType] || <LeftCommon />}
             </div>
           )}
@@ -379,14 +470,11 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
 
         <div style={{margin:"10px 0px"}}> 
           <Flex gap="small" vertical>
-            {trans("leftPanel.selectedComponents")}<br/>
-            {trans("leftPanel.displayComponents")}
-            <Input placeholder="Action Value" onChange={handleActionValueChange}/>
             <CustomDropdown
               dropdownRender={() => (
                 <Menu
                   items={layerActions}
-                  onClick={({key}) => handleComponentsActions(key)}
+                  onClick={({key}) => handleActionSelection(key)}
                 />
               )}
             >
@@ -397,6 +485,37 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
                 </Space>
               </Button>
             </CustomDropdown>
+            <Input 
+              value={actionValue} // Use actionValue for the default case as well
+              onChange={(e) => setActionValue(e.target.value)} // Handle changes to update actionValue
+              placeholder={placeholderText}
+            />
+            <Button 
+              type="primary"
+              disabled={!selectedActionKey}
+              onClick={() => selectedActionKey && handleComponentsActions(selectedActionKey)}
+            >
+              Apply Action
+            </Button>
+            <br/>
+            <ColorPicker
+                colorKey={"background"}
+                name={trans("componentDoc.styleBackgroundColor")}
+                color={"#ffffff"}
+                configChange={(params) => handleColorChange(params.color, "style.background")}
+            />
+            <ColorPicker
+                colorKey={"border"}
+                name={trans("componentDoc.styleBorderColor")}
+                color={"#ffffff"}
+                configChange={(params) => handleColorChange(params.color, "style.border")}
+            />
+            <ColorPicker
+                colorKey={"text"}
+                name={trans("style.textColor")}
+                color={"#ffffff"}
+                configChange={(params) => handleColorChange(params.color, "style.text")}
+            />
           </Flex>
         </div>
       </div>
diff --git a/client/packages/lowcoder/src/pages/editor/styledComponents.tsx b/client/packages/lowcoder/src/pages/editor/styledComponents.tsx
index 2188b4ea1d..b1125d4c92 100644
--- a/client/packages/lowcoder/src/pages/editor/styledComponents.tsx
+++ b/client/packages/lowcoder/src/pages/editor/styledComponents.tsx
@@ -25,11 +25,17 @@ export const DirectoryTreeStyle = styled(DirectoryTree)`
     position: unset;
     .ant-tree-iconEle {
       width: 16px;
-      height: 26px;
-      margin-right: 4px;
+      height: 16px;
+      margin: 0px 0px 0px 4px;
       display: flex;
       align-items: center;
+      svg {
+        width: 16px;
+        height: 16px;
+        stroke: #000;
+      }
     }
+
   }
   .ant-tree-checkbox+span {
     padding-left: 0;

From 1b0012ab75d2d99fab214d394d1ef6254469907c Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Fri, 16 Feb 2024 16:01:51 +0500
Subject: [PATCH 47/97] expose page no of list/grid view

---
 .../src/comps/comps/listViewComp/listViewComp.tsx    | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx b/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx
index dd1dc85e98..947cbee095 100644
--- a/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx
@@ -172,12 +172,12 @@ ListViewPropertyComp = withExposingConfigs(ListViewPropertyComp, [
       return data;
     },
   }),
-  // new CompDepsConfig(
-  //   "index",
-  //   (comp) => ({index: comp.children.itemIndexName.node() }),
-  //   (input) => input.index.value,
-  //   "index", // trans("listView.itemsDesc")
-  // ),
+  new CompDepsConfig(
+    "pageNo",
+    (comp) => ({index: comp.children.pagination.children.pageNo.exposingNode() }),
+    (input) => input.index,
+    "Page Number", // trans("listView.itemsDesc")
+  ),
   NameConfigHidden,
 ]);
 

From 1c14de683521b2f376b811312a30937b301f24f2 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Fri, 16 Feb 2024 22:19:32 +0100
Subject: [PATCH 48/97] Introduce switchable Scrollbar for Module and List View

---
 .../comps/comps/gridLayoutComp/canvasView.tsx |  6 ++++-
 .../src/comps/comps/listViewComp/listView.tsx | 26 +++++++++++--------
 .../comps/comps/listViewComp/listViewComp.tsx |  1 +
 .../listViewComp/listViewPropertyView.tsx     | 10 +++++++
 .../src/comps/comps/moduleComp/moduleComp.tsx | 17 ++++++++----
 .../moduleContainerComp/moduleLayoutComp.tsx  | 16 ++++++++----
 .../packages/lowcoder/src/i18n/locales/en.ts  |  1 +
 .../packages/lowcoder/src/i18n/locales/zh.ts  |  3 ++-
 8 files changed, 57 insertions(+), 23 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/gridLayoutComp/canvasView.tsx b/client/packages/lowcoder/src/comps/comps/gridLayoutComp/canvasView.tsx
index 9d59591a4a..ec11598f70 100644
--- a/client/packages/lowcoder/src/comps/comps/gridLayoutComp/canvasView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/gridLayoutComp/canvasView.tsx
@@ -19,6 +19,7 @@ import { defaultTheme } from "comps/controls/styleControlConstants";
 import { checkIsMobile } from "util/commonUtils";
 import { CanvasContainerID } from "constants/domLocators";
 import { CNRootContainer } from "constants/styleSelectors";
+import { ScrollBar } from "lowcoder-design";
 
 const UICompContainer = styled.div<{ $maxWidth?: number; readOnly?: boolean; $bgColor: string }>`
   height: 100%;
@@ -112,7 +113,8 @@ export function CanvasView(props: ContainerBaseProps) {
         $bgColor={bgColor}
       >
         <div>
-          <Profiler id="Panel" onRender={profilerCallback}>
+          <ScrollBar style={{ height: "100%", margin: "0px", padding: "0px" }}>
+            <Profiler id="Panel" onRender={profilerCallback}>
             <InnerGrid
               containerPadding={rootContainerPadding}
               overflow={rootContainerOverflow}
@@ -123,6 +125,8 @@ export function CanvasView(props: ContainerBaseProps) {
               radius="0px"
             />
           </Profiler>
+          </ScrollBar>
+          
         </div>
       </UICompContainer>
     );
diff --git a/client/packages/lowcoder/src/comps/comps/listViewComp/listView.tsx b/client/packages/lowcoder/src/comps/comps/listViewComp/listView.tsx
index b45bc755bc..8234e42311 100644
--- a/client/packages/lowcoder/src/comps/comps/listViewComp/listView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/listViewComp/listView.tsx
@@ -3,7 +3,7 @@ import { EditorContext } from "comps/editorState";
 import { BackgroundColorContext } from "comps/utils/backgroundColorContext";
 import _ from "lodash";
 import { ConstructorToView, deferAction } from "lowcoder-core";
-import { HintPlaceHolder, pageItemRender } from "lowcoder-design";
+import { HintPlaceHolder, ScrollBar, pageItemRender } from "lowcoder-design";
 import { RefObject, useContext, useEffect, useMemo, useRef } from "react";
 import ReactResizeDetector from "react-resize-detector";
 import styled from "styled-components";
@@ -80,7 +80,7 @@ function ListItem(props: ListItemProps) {
   // }, []);
 
   return (
-    <ContainerInListView
+      <ContainerInListView
       layout={containerProps.layout}
       items={gridItemCompToGridItems(containerProps.items)}
       positionParams={containerProps.positionParams}
@@ -95,7 +95,7 @@ function ListItem(props: ListItemProps) {
       scrollContainerRef={scrollContainerRef}
       overflow={"hidden"}
       minHeight={minHeight}
-      enableGridLines={true}
+      enableGridLines={true}    
     />
   );
 }
@@ -125,6 +125,7 @@ export function ListView(props: Props) {
     [children.noOfRows]
   );
   const autoHeight = useMemo(() => children.autoHeight.getView(), [children.autoHeight]);
+  const scrollbars = useMemo(() => children.scrollbars.getView(), [children.scrollbars]);
   const noOfColumns = useMemo(
     () => Math.max(1, children.noOfColumns.getView()),
     [children.noOfColumns]
@@ -214,14 +215,17 @@ export function ListView(props: Props) {
     <BackgroundColorContext.Provider value={style.background}>
       <ListViewWrapper $style={style} $paddingWidth={paddingWidth}>
         <BodyWrapper ref={ref} $autoHeight={autoHeight}>
-          <ReactResizeDetector
-            onResize={(width?: number, height?: number) => {
-              if (height) setListHeight(height);
-            }}
-            observerOptions={{ box: "border-box" }}
-          >
-            <div style={{ height: autoHeight ? "auto" : "100%" }}>{renders}</div>
-          </ReactResizeDetector>
+          {scrollbars ? (
+            <ScrollBar style={{ height: autoHeight ? "auto" : "100%", margin: "0px", padding: "0px" }}>
+              <>{<ReactResizeDetector onResize={(width?: number, height?: number) => { if (height) setListHeight(height); }} observerOptions={{ box: "border-box" }} >
+                <div style={{ height: autoHeight ? "auto" : "100%" }}>{renders}</div>
+              </ReactResizeDetector>}</>
+            </ScrollBar>
+          ) : (
+            <>{<ReactResizeDetector onResize={(width?: number, height?: number) => { if (height) setListHeight(height); }} observerOptions={{ box: "border-box" }} >
+              <div style={{ height: autoHeight ? "auto" : "100%" }}>{renders}</div>
+            </ReactResizeDetector>}</>
+          )}
         </BodyWrapper>
         <FooterWrapper>
           <Pagination size="small" itemRender={pageItemRender} {...pageInfo.pagination} />
diff --git a/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx b/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx
index 947cbee095..3687df0c41 100644
--- a/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx
@@ -48,6 +48,7 @@ const childrenMap = {
   heightUnitOfRow: withDefault(NumberControl, 1),
   container: ContextContainerComp,
   autoHeight: AutoHeightControl,
+  scrollbars: withDefault(BoolControl, false),
   showBorder: BoolControl,
   pagination: withDefault(PaginationControl, { pageSize: "6" }),
   style: styleControl(ListViewStyle),
diff --git a/client/packages/lowcoder/src/comps/comps/listViewComp/listViewPropertyView.tsx b/client/packages/lowcoder/src/comps/comps/listViewComp/listViewPropertyView.tsx
index e18ff26ab2..33d731a550 100644
--- a/client/packages/lowcoder/src/comps/comps/listViewComp/listViewPropertyView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/listViewComp/listViewPropertyView.tsx
@@ -4,6 +4,7 @@ import { ListViewImplComp } from "./listViewComp";
 import { ListCompType } from "./listViewUtils";
 import { useContext } from "react";
 import { EditorContext } from "comps/editorState";
+import { disabledPropertyView, hiddenPropertyView } from "comps/utils/propertyUtils";
 
 type Props = {
   comp: InstanceType<typeof ListViewImplComp>;
@@ -52,9 +53,18 @@ export function listPropertyView(compType: ListCompType) {
           </Section>
         )}
 
+        {(useContext(EditorContext).editorModeStatus === "logic" || useContext(EditorContext).editorModeStatus === "both") && (
+          <Section name={sectionNames.interaction}>
+            {hiddenPropertyView(children)}
+          </Section>
+        )}
+
         {(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && (
           <><Section name={sectionNames.layout}>
               {children.autoHeight.getPropertyView()}
+              {children.scrollbars.propertyView({
+              label: trans("prop.scrollbar"),
+            })}
             </Section>
             <Section name={sectionNames.style}>
               {children.style.getPropertyView()}
diff --git a/client/packages/lowcoder/src/comps/comps/moduleComp/moduleComp.tsx b/client/packages/lowcoder/src/comps/comps/moduleComp/moduleComp.tsx
index 5534bd43b6..f48918f309 100644
--- a/client/packages/lowcoder/src/comps/comps/moduleComp/moduleComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/moduleComp/moduleComp.tsx
@@ -13,7 +13,7 @@ import {
 } from "lowcoder-core";
 import { RootComp } from "comps/comps/rootComp";
 import { AutoHeightControl } from "comps/controls/autoHeightControl";
-import { valueComp, withViewFn } from "comps/generators";
+import { valueComp, withDefault, withViewFn } from "comps/generators";
 import { ToDataType, ToInstanceType } from "comps/generators/multi";
 import { HidableView, UICompBuilder } from "comps/generators/uiCompBuilder";
 import { withExposingRaw } from "comps/generators/withExposing";
@@ -22,7 +22,7 @@ import { getReduceContext, PartialReduceContext, reduceInContext } from "comps/u
 import { API_STATUS_CODES } from "constants/apiConstants";
 import { AppTypeEnum } from "constants/applicationConstants";
 import { GreyTextColor } from "constants/style";
-import { Section, sectionNames } from "lowcoder-design";
+import { ScrollBar, Section, sectionNames } from "lowcoder-design";
 import { ReactNode, useEffect, useMemo } from "react";
 import styled from "styled-components";
 import {
@@ -38,6 +38,7 @@ import { hiddenPropertyView } from "comps/utils/propertyUtils";
 import { ModuleLoading } from "components/ModuleLoading";
 import { trans } from "i18n";
 import { ParamsConfig, ParamType } from "comps/controls/actionSelector/executeCompTypes";
+import { BoolControl } from "comps/controls/boolControl";
 
 const Wrapper = styled.div`
   height: 100%;
@@ -83,6 +84,7 @@ const childrenMap = {
   inputs: ModuleInputComp,
   events: eventHandlerControl(),
   autoHeight: AutoHeightControl,
+  scrollbars: withDefault(BoolControl, false),
 };
 
 type DataType = ToDataType<ToInstanceType<typeof childrenMap>>;
@@ -121,6 +123,9 @@ class ModuleTmpComp extends ModuleCompBase {
         )}
         <Section name={sectionNames.layout}>
           {!this.autoScaleCompHeight() && this.children.autoHeight.getPropertyView()}
+          {this.children.scrollbars.propertyView({
+            label: trans("prop.scrollbar"),
+          })}
           {hiddenPropertyView(this.children)}
         </Section>
       </>
@@ -525,9 +530,11 @@ const ModuleCompWithView = withViewFn(ModuleTmpComp, (comp) => {
   if (comp.moduleRootComp && comp.isReady) {
     content = (
       <Wrapper className="module-wrapper">
-        <ExternalEditorContext.Provider value={moduleExternalState}>
-          {comp.moduleRootComp.getView()}
-        </ExternalEditorContext.Provider>
+        <ScrollBar style={{ height: comp.children.scrollbars.getView() ? "100%" : "auto", margin: "0px", padding: "0px" }}>
+          <ExternalEditorContext.Provider value={moduleExternalState}>
+           {comp.moduleRootComp.getView()}
+          </ExternalEditorContext.Provider>
+        </ScrollBar>
       </Wrapper>
     );
   }
diff --git a/client/packages/lowcoder/src/comps/comps/moduleContainerComp/moduleLayoutComp.tsx b/client/packages/lowcoder/src/comps/comps/moduleContainerComp/moduleLayoutComp.tsx
index a1a7db9499..f3a8445ff0 100644
--- a/client/packages/lowcoder/src/comps/comps/moduleContainerComp/moduleLayoutComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/moduleContainerComp/moduleLayoutComp.tsx
@@ -1,5 +1,5 @@
 import { BoolControl } from "comps/controls/boolControl";
-import { stateComp, UICompBuilder, valueComp } from "comps/generators";
+import { stateComp, UICompBuilder, valueComp, withDefault } from "comps/generators";
 import { NameGenerator } from "comps/utils";
 import { NameAndExposingInfo } from "comps/utils/exposingTypes";
 import { trans } from "i18n";
@@ -11,7 +11,7 @@ import { CompAction, CompActionTypes } from "lowcoder-core";
 import { ReactElement, useContext } from "react";
 import { ExternalEditorContext } from "util/context/ExternalEditorContext";
 import { JSONValue } from "util/jsonTypes";
-import { Section, sectionNames } from "lowcoder-design";
+import { ScrollBar, Section, sectionNames } from "lowcoder-design";
 import { getAllCompItems, IContainer } from "../containerBase";
 import { SimpleContainerComp } from "../containerBase/simpleContainerComp";
 import { GridItemsType } from "../containerComp/containerView";
@@ -67,7 +67,9 @@ function ModuleLayoutView(props: IProps) {
 
   if (readOnly) {
     return (
-      <ModulePreviewWrapper className={CNRootContainer}>{props.containerView}</ModulePreviewWrapper>
+      <ScrollBar style={{ height: "100%", margin: "0px", padding: "0px" }}>
+        <ModulePreviewWrapper className={CNRootContainer}>{props.containerView}</ModulePreviewWrapper>
+      </ScrollBar>
     );
   }
 
@@ -94,7 +96,8 @@ function ModuleLayoutView(props: IProps) {
   };
 
   return (
-    <CanvasView
+    <ScrollBar style={{ height: "100%", margin: "0px", padding: "0px" }}>
+      <CanvasView
       layout={layout}
       items={items}
       positionParams={{ ...positionParams, cols: parseInt(defaultGrid) }}
@@ -103,6 +106,7 @@ function ModuleLayoutView(props: IProps) {
       onLayoutChange={onLayoutChange}
       extraHeight="0px"
     />
+    </ScrollBar>
   );
 }
 
@@ -113,7 +117,8 @@ export class ModuleLayoutComp extends ModuleLayoutCompBase implements IContainer
     const isRowCountLocked = this.children.autoScaleCompHeight.getView();
     const rowCount = this.children.containerRowCount.getView();
     return (
-      <ModuleLayoutView
+      <div>
+        <ModuleLayoutView
         positionParams={this.children.positionParams.getView()}
         containerSize={this.children.containerSize.getView()}
         containerView={this.children.container.containerView({
@@ -133,6 +138,7 @@ export class ModuleLayoutComp extends ModuleLayoutCompBase implements IContainer
           });
         }}
       />
+      </div>
     );
   }
   getPropertyView() {
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index cd57c91657..7a8c342109 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -193,6 +193,7 @@ export const en = {
     "maskClosable": "Click Outside to Close",
     "showMask": "Show Mask",
     "textOverflow": "Text Overflow",
+    "scrollbar" : "Show Scrollbars",
   },
   "autoHeightProp": {
     "auto": "Auto",
diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts
index ac6020fd49..28194e00f0 100644
--- a/client/packages/lowcoder/src/i18n/locales/zh.ts
+++ b/client/packages/lowcoder/src/i18n/locales/zh.ts
@@ -185,7 +185,8 @@ prop: {
     showBody: "显示表体",
     showFooter: "显示表尾",
     maskClosable: "点击蒙层关闭",
-    showMask: "显示蒙层"
+    showMask: "显示蒙层",
+    scrollbar: "滚动条",
 },
 autoHeightProp: {
     auto: "自动",

From e3463a087010dc33e8b66b615ad7daa786bc66e7 Mon Sep 17 00:00:00 2001
From: imtananikhwa <156658165+imtananikhwa@users.noreply.github.com>
Date: Sat, 17 Feb 2024 13:51:28 +0500
Subject: [PATCH 49/97] Delete
 client/packages/lowcoder/vite.config.mts.timestamp-1708005283355-9ba212c9a46a4.mjs

junk file removed
---
 ....timestamp-1708005283355-9ba212c9a46a4.mjs | 331 ------------------
 1 file changed, 331 deletions(-)
 delete mode 100644 client/packages/lowcoder/vite.config.mts.timestamp-1708005283355-9ba212c9a46a4.mjs

diff --git a/client/packages/lowcoder/vite.config.mts.timestamp-1708005283355-9ba212c9a46a4.mjs b/client/packages/lowcoder/vite.config.mts.timestamp-1708005283355-9ba212c9a46a4.mjs
deleted file mode 100644
index 8600472a2e..0000000000
--- a/client/packages/lowcoder/vite.config.mts.timestamp-1708005283355-9ba212c9a46a4.mjs
+++ /dev/null
@@ -1,331 +0,0 @@
-// vite.config.mts
-import dotenv from "file:///C:/Projects/lowcoder/client/node_modules/dotenv/lib/main.js";
-import { defineConfig } from "file:///C:/Projects/lowcoder/client/node_modules/vite/dist/node/index.js";
-import react from "file:///C:/Projects/lowcoder/client/node_modules/@vitejs/plugin-react/dist/index.mjs";
-import viteTsconfigPaths from "file:///C:/Projects/lowcoder/client/node_modules/vite-tsconfig-paths/dist/index.mjs";
-import svgrPlugin from "file:///C:/Projects/lowcoder/client/node_modules/vite-plugin-svgr/dist/index.mjs";
-import checker from "file:///C:/Projects/lowcoder/client/node_modules/vite-plugin-checker/dist/esm/main.js";
-import { visualizer } from "file:///C:/Projects/lowcoder/client/node_modules/rollup-plugin-visualizer/dist/plugin/index.js";
-import path from "path";
-import chalk from "file:///C:/Projects/lowcoder/client/node_modules/chalk/source/index.js";
-import { createHtmlPlugin } from "file:///C:/Projects/lowcoder/client/node_modules/vite-plugin-html/dist/index.mjs";
-
-// src/dev-utils/util.js
-function ensureLastSlash(str) {
-  if (!str) {
-    return "/";
-  }
-  if (!str.endsWith("/")) {
-    return `${str}/`;
-  }
-  return str;
-}
-
-// src/dev-utils/buildVars.js
-var buildVars = [
-  {
-    name: "PUBLIC_URL",
-    defaultValue: "/"
-  },
-  {
-    name: "REACT_APP_EDITION",
-    defaultValue: "community"
-  },
-  {
-    name: "REACT_APP_LANGUAGES",
-    defaultValue: ""
-  },
-  {
-    name: "REACT_APP_COMMIT_ID",
-    defaultValue: "00000"
-  },
-  {
-    name: "REACT_APP_API_HOST",
-    defaultValue: ""
-  },
-  {
-    name: "LOWCODER_NODE_SERVICE_URL",
-    defaultValue: ""
-  },
-  {
-    name: "REACT_APP_ENV",
-    defaultValue: "production"
-  },
-  {
-    name: "REACT_APP_BUILD_ID",
-    defaultValue: ""
-  },
-  {
-    name: "REACT_APP_LOG_LEVEL",
-    defaultValue: "error"
-  },
-  {
-    name: "REACT_APP_IMPORT_MAP",
-    defaultValue: "{}"
-  },
-  {
-    name: "REACT_APP_SERVER_IPS",
-    defaultValue: ""
-  },
-  {
-    name: "REACT_APP_BUNDLE_BUILTIN_PLUGIN",
-    defaultValue: ""
-  },
-  {
-    name: "REACT_APP_BUNDLE_TYPE",
-    defaultValue: "app"
-  },
-  {
-    name: "REACT_APP_DISABLE_JS_SANDBOX",
-    defaultValue: ""
-  }
-];
-
-// src/dev-utils/external.js
-var libs = [
-  "axios",
-  "redux",
-  "react-router",
-  "react-router-dom",
-  "react-redux",
-  "react",
-  "react-dom",
-  "lodash",
-  "history",
-  "antd",
-  "@dnd-kit/core",
-  "@dnd-kit/modifiers",
-  "@dnd-kit/sortable",
-  "@dnd-kit/utilities",
-  {
-    name: "moment",
-    extractDefault: true
-  },
-  {
-    name: "dayjs",
-    extractDefault: true
-  },
-  {
-    name: "lowcoder-sdk",
-    from: "./src/index.sdk.ts"
-  },
-  {
-    name: "styled-components",
-    mergeDefaultAndNameExports: true
-  }
-];
-var getLibGlobalVarName = (name) => {
-  return "$" + name.replace(/@/g, "$").replace(/[\/\-]/g, "_");
-};
-var libsImportCode = (exclude = []) => {
-  const importLines = [];
-  const assignLines = [];
-  libs.forEach((i) => {
-    let name = i;
-    let merge = false;
-    let from = name;
-    let extractDefault = false;
-    if (typeof i === "object") {
-      name = i.name;
-      merge = i.mergeDefaultAndNameExports ?? false;
-      from = i.from ?? name;
-      extractDefault = i.extractDefault ?? false;
-    }
-    if (exclude.includes(name)) {
-      return;
-    }
-    const varName = getLibGlobalVarName(name);
-    if (merge) {
-      importLines.push(`import * as ${varName}_named_exports from '${from}';`);
-      importLines.push(`import ${varName} from '${from}';`);
-      assignLines.push(`Object.assign(${varName}, ${varName}_named_exports);`);
-    } else if (extractDefault) {
-      importLines.push(`import ${varName} from '${from}';`);
-    } else {
-      importLines.push(`import * as ${varName} from '${from}';`);
-    }
-    assignLines.push(`window.${varName} = ${varName};`);
-  });
-  return importLines.concat(assignLines).join("\n");
-};
-
-// src/dev-utils/globalDepPlguin.js
-function globalDepPlugin(exclude = []) {
-  const virtualModuleId = "virtual:globals";
-  return {
-    name: "lowcoder-global-plugin",
-    resolveId(id) {
-      if (id === virtualModuleId) {
-        return id;
-      }
-    },
-    load(id) {
-      if (id === virtualModuleId) {
-        return libsImportCode(exclude);
-      }
-    }
-  };
-}
-
-// vite.config.mts
-var __vite_injected_original_dirname = "C:\\Projects\\lowcoder\\client\\packages\\lowcoder";
-dotenv.config();
-var apiProxyTarget = process.env.LOWCODER_API_SERVICE_URL;
-var nodeServiceApiProxyTarget = process.env.NODE_SERVICE_API_PROXY_TARGET;
-var nodeEnv = process.env.NODE_ENV ?? "development";
-var edition = process.env.REACT_APP_EDITION;
-var isEEGlobal = edition === "enterprise-global";
-var isEE = edition === "enterprise" || isEEGlobal;
-var isDev = nodeEnv === "development";
-var isVisualizerEnabled = !!process.env.ENABLE_VISUALIZER;
-var browserCheckFileName = `browser-check.js`;
-var base = ensureLastSlash(process.env.PUBLIC_URL);
-if (!apiProxyTarget && isDev) {
-  console.log();
-  console.log(chalk.red`LOWCODER_API_SERVICE_URL is required.\n`);
-  console.log(chalk.cyan`Start with command: LOWCODER_API_SERVICE_URL=\{backend-api-addr\} yarn start`);
-  console.log();
-  process.exit(1);
-}
-var proxyConfig = {
-  "/api": {
-    target: apiProxyTarget,
-    changeOrigin: false
-  }
-};
-if (nodeServiceApiProxyTarget) {
-  proxyConfig["/node-service"] = {
-    target: nodeServiceApiProxyTarget
-  };
-}
-var define = {};
-buildVars.forEach(({ name, defaultValue }) => {
-  define[name] = JSON.stringify(process.env[name] || defaultValue);
-});
-var viteConfig = {
-  define,
-  assetsInclude: ["**/*.md"],
-  resolve: {
-    extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json"],
-    alias: {
-      "@lowcoder-ee": path.resolve(
-        __vite_injected_original_dirname,
-        isEE ? `../lowcoder/src/${isEEGlobal ? "ee-global" : "ee"}` : "../lowcoder/src"
-      )
-    }
-  },
-  base,
-  build: {
-    manifest: true,
-    target: "es2015",
-    cssTarget: "chrome63",
-    outDir: "build",
-    assetsDir: "static",
-    emptyOutDir: false,
-    rollupOptions: {
-      output: {
-        chunkFileNames: "[hash].js"
-      }
-    },
-    commonjsOptions: {
-      defaultIsModuleExports: (id) => {
-        if (id.indexOf("antd/lib") !== -1) {
-          return false;
-        }
-        return "auto";
-      }
-    }
-  },
-  css: {
-    preprocessorOptions: {
-      less: {
-        modifyVars: {
-          "@primary-color": "#3377FF",
-          "@link-color": "#3377FF",
-          "@border-color-base": "#D7D9E0",
-          "@border-radius-base": "4px"
-        },
-        javascriptEnabled: true
-      }
-    }
-  },
-  server: {
-    open: true,
-    cors: true,
-    port: 8e3,
-    host: "0.0.0.0",
-    proxy: proxyConfig
-  },
-  plugins: [
-    checker({
-      typescript: true,
-      eslint: {
-        lintCommand: 'eslint --quiet "./src/**/*.{ts,tsx}"',
-        dev: {
-          logLevel: ["error"]
-        }
-      }
-    }),
-    react({
-      babel: {
-        parserOpts: {
-          plugins: ["decorators-legacy"]
-        }
-      }
-    }),
-    viteTsconfigPaths({
-      projects: ["../lowcoder/tsconfig.json", "../lowcoder-design/tsconfig.json"]
-    }),
-    svgrPlugin({
-      svgrOptions: {
-        exportType: "named",
-        prettier: false,
-        svgo: false,
-        titleProp: true,
-        ref: true
-      }
-    }),
-    globalDepPlugin(),
-    createHtmlPlugin({
-      minify: true,
-      inject: {
-        data: {
-          browserCheckScript: isDev ? "" : `<script src="${base}${browserCheckFileName}"></script>`
-        }
-      }
-    }),
-    isVisualizerEnabled && visualizer()
-  ].filter(Boolean)
-};
-var browserCheckConfig = {
-  ...viteConfig,
-  define: {
-    ...viteConfig.define,
-    "process.env.NODE_ENV": JSON.stringify("production")
-  },
-  build: {
-    ...viteConfig.build,
-    manifest: false,
-    copyPublicDir: false,
-    emptyOutDir: true,
-    lib: {
-      formats: ["iife"],
-      name: "BrowserCheck",
-      entry: "./src/browser-check.ts",
-      fileName: () => {
-        return browserCheckFileName;
-      }
-    }
-  }
-};
-var buildTargets = {
-  main: viteConfig,
-  browserCheck: browserCheckConfig
-};
-var buildTarget = buildTargets[process.env.BUILD_TARGET || "main"];
-var vite_config_default = defineConfig(buildTarget || viteConfig);
-export {
-  vite_config_default as default,
-  viteConfig
-};
-//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcubXRzIiwgInNyYy9kZXYtdXRpbHMvdXRpbC5qcyIsICJzcmMvZGV2LXV0aWxzL2J1aWxkVmFycy5qcyIsICJzcmMvZGV2LXV0aWxzL2V4dGVybmFsLmpzIiwgInNyYy9kZXYtdXRpbHMvZ2xvYmFsRGVwUGxndWluLmpzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSA9IFwiQzpcXFxcUHJvamVjdHNcXFxcbG93Y29kZXJcXFxcY2xpZW50XFxcXHBhY2thZ2VzXFxcXGxvd2NvZGVyXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCJDOlxcXFxQcm9qZWN0c1xcXFxsb3djb2RlclxcXFxjbGllbnRcXFxccGFja2FnZXNcXFxcbG93Y29kZXJcXFxcdml0ZS5jb25maWcubXRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9DOi9Qcm9qZWN0cy9sb3djb2Rlci9jbGllbnQvcGFja2FnZXMvbG93Y29kZXIvdml0ZS5jb25maWcubXRzXCI7aW1wb3J0IGRvdGVudiBmcm9tIFwiZG90ZW52XCI7XHJcbmltcG9ydCB7IGRlZmluZUNvbmZpZywgU2VydmVyT3B0aW9ucywgVXNlckNvbmZpZyB9IGZyb20gXCJ2aXRlXCI7XHJcbmltcG9ydCByZWFjdCBmcm9tIFwiQHZpdGVqcy9wbHVnaW4tcmVhY3RcIjtcclxuaW1wb3J0IHZpdGVUc2NvbmZpZ1BhdGhzIGZyb20gXCJ2aXRlLXRzY29uZmlnLXBhdGhzXCI7XHJcbmltcG9ydCBzdmdyUGx1Z2luIGZyb20gXCJ2aXRlLXBsdWdpbi1zdmdyXCI7XHJcbmltcG9ydCBjaGVja2VyIGZyb20gXCJ2aXRlLXBsdWdpbi1jaGVja2VyXCI7XHJcbmltcG9ydCB7IHZpc3VhbGl6ZXIgfSBmcm9tIFwicm9sbHVwLXBsdWdpbi12aXN1YWxpemVyXCI7XHJcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XHJcbmltcG9ydCBjaGFsayBmcm9tIFwiY2hhbGtcIjtcclxuaW1wb3J0IHsgY3JlYXRlSHRtbFBsdWdpbiB9IGZyb20gXCJ2aXRlLXBsdWdpbi1odG1sXCI7XHJcbmltcG9ydCB7IGVuc3VyZUxhc3RTbGFzaCB9IGZyb20gXCIuL3NyYy9kZXYtdXRpbHMvdXRpbFwiO1xyXG5pbXBvcnQgeyBidWlsZFZhcnMgfSBmcm9tIFwiLi9zcmMvZGV2LXV0aWxzL2J1aWxkVmFyc1wiO1xyXG5pbXBvcnQgeyBnbG9iYWxEZXBQbHVnaW4gfSBmcm9tIFwiLi9zcmMvZGV2LXV0aWxzL2dsb2JhbERlcFBsZ3VpblwiO1xyXG5cclxuZG90ZW52LmNvbmZpZygpO1xyXG5cclxuY29uc3QgYXBpUHJveHlUYXJnZXQgPSBwcm9jZXNzLmVudi5MT1dDT0RFUl9BUElfU0VSVklDRV9VUkw7XHJcbmNvbnN0IG5vZGVTZXJ2aWNlQXBpUHJveHlUYXJnZXQgPSBwcm9jZXNzLmVudi5OT0RFX1NFUlZJQ0VfQVBJX1BST1hZX1RBUkdFVDtcclxuY29uc3Qgbm9kZUVudiA9IHByb2Nlc3MuZW52Lk5PREVfRU5WID8/IFwiZGV2ZWxvcG1lbnRcIjtcclxuY29uc3QgZWRpdGlvbiA9IHByb2Nlc3MuZW52LlJFQUNUX0FQUF9FRElUSU9OO1xyXG5jb25zdCBpc0VFR2xvYmFsID0gZWRpdGlvbiA9PT0gXCJlbnRlcnByaXNlLWdsb2JhbFwiO1xyXG5jb25zdCBpc0VFID0gZWRpdGlvbiA9PT0gXCJlbnRlcnByaXNlXCIgfHwgaXNFRUdsb2JhbDtcclxuY29uc3QgaXNEZXYgPSBub2RlRW52ID09PSBcImRldmVsb3BtZW50XCI7XHJcbmNvbnN0IGlzVmlzdWFsaXplckVuYWJsZWQgPSAhIXByb2Nlc3MuZW52LkVOQUJMRV9WSVNVQUxJWkVSO1xyXG4vLyB0aGUgZmlsZSB3YXMgbmV2ZXIgY3JlYXRlZFxyXG4vLyBjb25zdCBicm93c2VyQ2hlY2tGaWxlTmFtZSA9IGBicm93c2VyLWNoZWNrLSR7cHJvY2Vzcy5lbnYuUkVBQ1RfQVBQX0NPTU1JVF9JRH0uanNgO1xyXG5jb25zdCBicm93c2VyQ2hlY2tGaWxlTmFtZSA9IGBicm93c2VyLWNoZWNrLmpzYDtcclxuY29uc3QgYmFzZSA9IGVuc3VyZUxhc3RTbGFzaChwcm9jZXNzLmVudi5QVUJMSUNfVVJMKTtcclxuXHJcbmlmICghYXBpUHJveHlUYXJnZXQgJiYgaXNEZXYpIHtcclxuICBjb25zb2xlLmxvZygpO1xyXG4gIGNvbnNvbGUubG9nKGNoYWxrLnJlZGBMT1dDT0RFUl9BUElfU0VSVklDRV9VUkwgaXMgcmVxdWlyZWQuXFxuYCk7XHJcbiAgY29uc29sZS5sb2coY2hhbGsuY3lhbmBTdGFydCB3aXRoIGNvbW1hbmQ6IExPV0NPREVSX0FQSV9TRVJWSUNFX1VSTD1cXHtiYWNrZW5kLWFwaS1hZGRyXFx9IHlhcm4gc3RhcnRgKTtcclxuICBjb25zb2xlLmxvZygpO1xyXG4gIHByb2Nlc3MuZXhpdCgxKTtcclxufVxyXG5cclxuY29uc3QgcHJveHlDb25maWc6IFNlcnZlck9wdGlvbnNbXCJwcm94eVwiXSA9IHtcclxuICBcIi9hcGlcIjoge1xyXG4gICAgdGFyZ2V0OiBhcGlQcm94eVRhcmdldCxcclxuICAgIGNoYW5nZU9yaWdpbjogZmFsc2UsXHJcbiAgfSxcclxufTtcclxuXHJcbmlmIChub2RlU2VydmljZUFwaVByb3h5VGFyZ2V0KSB7XHJcbiAgcHJveHlDb25maWdbXCIvbm9kZS1zZXJ2aWNlXCJdID0ge1xyXG4gICAgdGFyZ2V0OiBub2RlU2VydmljZUFwaVByb3h5VGFyZ2V0LFxyXG4gIH07XHJcbn1cclxuXHJcbmNvbnN0IGRlZmluZSA9IHt9O1xyXG5idWlsZFZhcnMuZm9yRWFjaCgoeyBuYW1lLCBkZWZhdWx0VmFsdWUgfSkgPT4ge1xyXG4gIGRlZmluZVtuYW1lXSA9IEpTT04uc3RyaW5naWZ5KHByb2Nlc3MuZW52W25hbWVdIHx8IGRlZmF1bHRWYWx1ZSk7XHJcbn0pO1xyXG5cclxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cclxuZXhwb3J0IGNvbnN0IHZpdGVDb25maWc6IFVzZXJDb25maWcgPSB7XHJcbiAgZGVmaW5lLFxyXG4gIGFzc2V0c0luY2x1ZGU6IFtcIioqLyoubWRcIl0sXHJcbiAgcmVzb2x2ZToge1xyXG4gICAgZXh0ZW5zaW9uczogW1wiLm1qc1wiLCBcIi5qc1wiLCBcIi50c1wiLCBcIi5qc3hcIiwgXCIudHN4XCIsIFwiLmpzb25cIl0sXHJcbiAgICBhbGlhczoge1xyXG4gICAgICBcIkBsb3djb2Rlci1lZVwiOiBwYXRoLnJlc29sdmUoXHJcbiAgICAgICAgX19kaXJuYW1lLFxyXG4gICAgICAgIGlzRUUgPyBgLi4vbG93Y29kZXIvc3JjLyR7aXNFRUdsb2JhbCA/IFwiZWUtZ2xvYmFsXCIgOiBcImVlXCJ9YCA6IFwiLi4vbG93Y29kZXIvc3JjXCJcclxuICAgICAgKSxcclxuICAgIH0sXHJcbiAgfSxcclxuICBiYXNlLFxyXG4gIGJ1aWxkOiB7XHJcbiAgICBtYW5pZmVzdDogdHJ1ZSxcclxuICAgIHRhcmdldDogXCJlczIwMTVcIixcclxuICAgIGNzc1RhcmdldDogXCJjaHJvbWU2M1wiLFxyXG4gICAgb3V0RGlyOiBcImJ1aWxkXCIsXHJcbiAgICBhc3NldHNEaXI6IFwic3RhdGljXCIsXHJcbiAgICBlbXB0eU91dERpcjogZmFsc2UsXHJcbiAgICByb2xsdXBPcHRpb25zOiB7XHJcbiAgICAgIG91dHB1dDoge1xyXG4gICAgICAgIGNodW5rRmlsZU5hbWVzOiBcIltoYXNoXS5qc1wiLFxyXG4gICAgICB9LFxyXG4gICAgfSxcclxuICAgIGNvbW1vbmpzT3B0aW9uczoge1xyXG4gICAgICBkZWZhdWx0SXNNb2R1bGVFeHBvcnRzOiAoaWQpID0+IHtcclxuICAgICAgICBpZiAoaWQuaW5kZXhPZihcImFudGQvbGliXCIpICE9PSAtMSkge1xyXG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gXCJhdXRvXCI7XHJcbiAgICAgIH0sXHJcbiAgICB9LFxyXG4gIH0sXHJcbiAgY3NzOiB7XHJcbiAgICBwcmVwcm9jZXNzb3JPcHRpb25zOiB7XHJcbiAgICAgIGxlc3M6IHtcclxuICAgICAgICBtb2RpZnlWYXJzOiB7XHJcbiAgICAgICAgICBcIkBwcmltYXJ5LWNvbG9yXCI6IFwiIzMzNzdGRlwiLFxyXG4gICAgICAgICAgXCJAbGluay1jb2xvclwiOiBcIiMzMzc3RkZcIixcclxuICAgICAgICAgIFwiQGJvcmRlci1jb2xvci1iYXNlXCI6IFwiI0Q3RDlFMFwiLFxyXG4gICAgICAgICAgXCJAYm9yZGVyLXJhZGl1cy1iYXNlXCI6IFwiNHB4XCIsXHJcbiAgICAgICAgfSxcclxuICAgICAgICBqYXZhc2NyaXB0RW5hYmxlZDogdHJ1ZSxcclxuICAgICAgfSxcclxuICAgIH0sXHJcbiAgfSxcclxuICBzZXJ2ZXI6IHtcclxuICAgIG9wZW46IHRydWUsXHJcbiAgICBjb3JzOiB0cnVlLFxyXG4gICAgcG9ydDogODAwMCxcclxuICAgIGhvc3Q6IFwiMC4wLjAuMFwiLFxyXG4gICAgcHJveHk6IHByb3h5Q29uZmlnLFxyXG4gIH0sXHJcbiAgcGx1Z2luczogW1xyXG4gICAgY2hlY2tlcih7XHJcbiAgICAgIHR5cGVzY3JpcHQ6IHRydWUsXHJcbiAgICAgIGVzbGludDoge1xyXG4gICAgICAgIGxpbnRDb21tYW5kOiAnZXNsaW50IC0tcXVpZXQgXCIuL3NyYy8qKi8qLnt0cyx0c3h9XCInLFxyXG4gICAgICAgIGRldjoge1xyXG4gICAgICAgICAgbG9nTGV2ZWw6IFtcImVycm9yXCJdLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0sXHJcbiAgICB9KSxcclxuICAgIHJlYWN0KHtcclxuICAgICAgYmFiZWw6IHtcclxuICAgICAgICBwYXJzZXJPcHRzOiB7XHJcbiAgICAgICAgICBwbHVnaW5zOiBbXCJkZWNvcmF0b3JzLWxlZ2FjeVwiXSxcclxuICAgICAgICB9LFxyXG4gICAgICB9LFxyXG4gICAgfSksXHJcbiAgICB2aXRlVHNjb25maWdQYXRocyh7XHJcbiAgICAgIHByb2plY3RzOiBbXCIuLi9sb3djb2Rlci90c2NvbmZpZy5qc29uXCIsIFwiLi4vbG93Y29kZXItZGVzaWduL3RzY29uZmlnLmpzb25cIl0sXHJcbiAgICB9KSxcclxuICAgIHN2Z3JQbHVnaW4oe1xyXG4gICAgICBzdmdyT3B0aW9uczoge1xyXG4gICAgICAgIGV4cG9ydFR5cGU6IFwibmFtZWRcIixcclxuICAgICAgICBwcmV0dGllcjogZmFsc2UsXHJcbiAgICAgICAgc3ZnbzogZmFsc2UsXHJcbiAgICAgICAgdGl0bGVQcm9wOiB0cnVlLFxyXG4gICAgICAgIHJlZjogdHJ1ZSxcclxuICAgICAgfSxcclxuICAgIH0pLFxyXG4gICAgZ2xvYmFsRGVwUGx1Z2luKCksXHJcbiAgICBjcmVhdGVIdG1sUGx1Z2luKHtcclxuICAgICAgbWluaWZ5OiB0cnVlLFxyXG4gICAgICBpbmplY3Q6IHtcclxuICAgICAgICBkYXRhOiB7XHJcbiAgICAgICAgICBicm93c2VyQ2hlY2tTY3JpcHQ6IGlzRGV2ID8gXCJcIiA6IGA8c2NyaXB0IHNyYz1cIiR7YmFzZX0ke2Jyb3dzZXJDaGVja0ZpbGVOYW1lfVwiPjwvc2NyaXB0PmAsXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgIH0pLFxyXG4gICAgaXNWaXN1YWxpemVyRW5hYmxlZCAmJiB2aXN1YWxpemVyKCksXHJcbiAgXS5maWx0ZXIoQm9vbGVhbiksXHJcbn07XHJcblxyXG5jb25zdCBicm93c2VyQ2hlY2tDb25maWc6IFVzZXJDb25maWcgPSB7XHJcbiAgLi4udml0ZUNvbmZpZyxcclxuICBkZWZpbmU6IHtcclxuICAgIC4uLnZpdGVDb25maWcuZGVmaW5lLFxyXG4gICAgXCJwcm9jZXNzLmVudi5OT0RFX0VOVlwiOiBKU09OLnN0cmluZ2lmeShcInByb2R1Y3Rpb25cIiksXHJcbiAgfSxcclxuICBidWlsZDoge1xyXG4gICAgLi4udml0ZUNvbmZpZy5idWlsZCxcclxuICAgIG1hbmlmZXN0OiBmYWxzZSxcclxuICAgIGNvcHlQdWJsaWNEaXI6IGZhbHNlLFxyXG4gICAgZW1wdHlPdXREaXI6IHRydWUsXHJcbiAgICBsaWI6IHtcclxuICAgICAgZm9ybWF0czogW1wiaWlmZVwiXSxcclxuICAgICAgbmFtZTogXCJCcm93c2VyQ2hlY2tcIixcclxuICAgICAgZW50cnk6IFwiLi9zcmMvYnJvd3Nlci1jaGVjay50c1wiLFxyXG4gICAgICBmaWxlTmFtZTogKCkgPT4ge1xyXG4gICAgICAgIHJldHVybiBicm93c2VyQ2hlY2tGaWxlTmFtZTtcclxuICAgICAgfSxcclxuICAgIH0sXHJcbiAgfSxcclxufTtcclxuXHJcbmNvbnN0IGJ1aWxkVGFyZ2V0cyA9IHtcclxuICBtYWluOiB2aXRlQ29uZmlnLFxyXG4gIGJyb3dzZXJDaGVjazogYnJvd3NlckNoZWNrQ29uZmlnLFxyXG59O1xyXG5cclxuY29uc3QgYnVpbGRUYXJnZXQgPSBidWlsZFRhcmdldHNbcHJvY2Vzcy5lbnYuQlVJTERfVEFSR0VUIHx8IFwibWFpblwiXTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyhidWlsZFRhcmdldCB8fCB2aXRlQ29uZmlnKTtcclxuIiwgImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJDOlxcXFxQcm9qZWN0c1xcXFxsb3djb2RlclxcXFxjbGllbnRcXFxccGFja2FnZXNcXFxcbG93Y29kZXJcXFxcc3JjXFxcXGRldi11dGlsc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiQzpcXFxcUHJvamVjdHNcXFxcbG93Y29kZXJcXFxcY2xpZW50XFxcXHBhY2thZ2VzXFxcXGxvd2NvZGVyXFxcXHNyY1xcXFxkZXYtdXRpbHNcXFxcdXRpbC5qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vQzovUHJvamVjdHMvbG93Y29kZXIvY2xpZW50L3BhY2thZ2VzL2xvd2NvZGVyL3NyYy9kZXYtdXRpbHMvdXRpbC5qc1wiO2ltcG9ydCBmcyBmcm9tIFwibm9kZTpmc1wiO1xyXG5pbXBvcnQgeyBkaXJuYW1lIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xyXG5pbXBvcnQgeyBmaWxlVVJMVG9QYXRoIH0gZnJvbSBcIm5vZGU6dXJsXCI7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc3RyaXBMYXN0U2xhc2goc3RyKSB7XHJcbiAgaWYgKHN0ci5lbmRzV2l0aChcIi9cIikpIHtcclxuICAgIHJldHVybiBzdHIuc2xpY2UoMCwgc3RyLmxlbmd0aCAtIDEpO1xyXG4gIH1cclxuICByZXR1cm4gc3RyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZW5zdXJlTGFzdFNsYXNoKHN0cikge1xyXG4gIGlmICghc3RyKSB7XHJcbiAgICByZXR1cm4gXCIvXCI7XHJcbiAgfVxyXG4gIGlmICghc3RyLmVuZHNXaXRoKFwiL1wiKSkge1xyXG4gICAgcmV0dXJuIGAke3N0cn0vYDtcclxuICB9XHJcbiAgcmV0dXJuIHN0cjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHJlYWRKc29uKGZpbGUpIHtcclxuICByZXR1cm4gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMoZmlsZSkudG9TdHJpbmcoKSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjdXJyZW50RGlyTmFtZShpbXBvcnRNZXRhVXJsKSB7XHJcbiAgcmV0dXJuIGRpcm5hbWUoZmlsZVVSTFRvUGF0aChpbXBvcnRNZXRhVXJsKSk7XHJcbn1cclxuIiwgImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJDOlxcXFxQcm9qZWN0c1xcXFxsb3djb2RlclxcXFxjbGllbnRcXFxccGFja2FnZXNcXFxcbG93Y29kZXJcXFxcc3JjXFxcXGRldi11dGlsc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiQzpcXFxcUHJvamVjdHNcXFxcbG93Y29kZXJcXFxcY2xpZW50XFxcXHBhY2thZ2VzXFxcXGxvd2NvZGVyXFxcXHNyY1xcXFxkZXYtdXRpbHNcXFxcYnVpbGRWYXJzLmpzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9DOi9Qcm9qZWN0cy9sb3djb2Rlci9jbGllbnQvcGFja2FnZXMvbG93Y29kZXIvc3JjL2Rldi11dGlscy9idWlsZFZhcnMuanNcIjtleHBvcnQgY29uc3QgYnVpbGRWYXJzID0gW1xyXG4gIHtcclxuICAgIG5hbWU6IFwiUFVCTElDX1VSTFwiLFxyXG4gICAgZGVmYXVsdFZhbHVlOiBcIi9cIixcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6IFwiUkVBQ1RfQVBQX0VESVRJT05cIixcclxuICAgIGRlZmF1bHRWYWx1ZTogXCJjb21tdW5pdHlcIixcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6IFwiUkVBQ1RfQVBQX0xBTkdVQUdFU1wiLFxyXG4gICAgZGVmYXVsdFZhbHVlOiBcIlwiLFxyXG4gIH0sXHJcbiAge1xyXG4gICAgbmFtZTogXCJSRUFDVF9BUFBfQ09NTUlUX0lEXCIsXHJcbiAgICBkZWZhdWx0VmFsdWU6IFwiMDAwMDBcIixcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6IFwiUkVBQ1RfQVBQX0FQSV9IT1NUXCIsXHJcbiAgICBkZWZhdWx0VmFsdWU6IFwiXCIsXHJcbiAgfSxcclxuICB7XHJcbiAgICBuYW1lOiBcIkxPV0NPREVSX05PREVfU0VSVklDRV9VUkxcIixcclxuICAgIGRlZmF1bHRWYWx1ZTogXCJcIixcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6IFwiUkVBQ1RfQVBQX0VOVlwiLFxyXG4gICAgZGVmYXVsdFZhbHVlOiBcInByb2R1Y3Rpb25cIixcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6IFwiUkVBQ1RfQVBQX0JVSUxEX0lEXCIsXHJcbiAgICBkZWZhdWx0VmFsdWU6IFwiXCIsXHJcbiAgfSxcclxuICB7XHJcbiAgICBuYW1lOiBcIlJFQUNUX0FQUF9MT0dfTEVWRUxcIixcclxuICAgIGRlZmF1bHRWYWx1ZTogXCJlcnJvclwiLFxyXG4gIH0sXHJcbiAge1xyXG4gICAgbmFtZTogXCJSRUFDVF9BUFBfSU1QT1JUX01BUFwiLFxyXG4gICAgZGVmYXVsdFZhbHVlOiBcInt9XCIsXHJcbiAgfSxcclxuICB7XHJcbiAgICBuYW1lOiBcIlJFQUNUX0FQUF9TRVJWRVJfSVBTXCIsXHJcbiAgICBkZWZhdWx0VmFsdWU6IFwiXCIsXHJcbiAgfSxcclxuICB7XHJcbiAgICBuYW1lOiBcIlJFQUNUX0FQUF9CVU5ETEVfQlVJTFRJTl9QTFVHSU5cIixcclxuICAgIGRlZmF1bHRWYWx1ZTogXCJcIixcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6IFwiUkVBQ1RfQVBQX0JVTkRMRV9UWVBFXCIsXHJcbiAgICBkZWZhdWx0VmFsdWU6IFwiYXBwXCIsXHJcbiAgfSxcclxuICB7XHJcbiAgICBuYW1lOiBcIlJFQUNUX0FQUF9ESVNBQkxFX0pTX1NBTkRCT1hcIixcclxuICAgIGRlZmF1bHRWYWx1ZTogXCJcIixcclxuICB9LFxyXG5dO1xyXG4iLCAiY29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2Rpcm5hbWUgPSBcIkM6XFxcXFByb2plY3RzXFxcXGxvd2NvZGVyXFxcXGNsaWVudFxcXFxwYWNrYWdlc1xcXFxsb3djb2RlclxcXFxzcmNcXFxcZGV2LXV0aWxzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCJDOlxcXFxQcm9qZWN0c1xcXFxsb3djb2RlclxcXFxjbGllbnRcXFxccGFja2FnZXNcXFxcbG93Y29kZXJcXFxcc3JjXFxcXGRldi11dGlsc1xcXFxleHRlcm5hbC5qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vQzovUHJvamVjdHMvbG93Y29kZXIvY2xpZW50L3BhY2thZ2VzL2xvd2NvZGVyL3NyYy9kZXYtdXRpbHMvZXh0ZXJuYWwuanNcIjsvKipcclxuICogbGlicyB0byBpbXBvcnQgYXMgZ2xvYmFsIHZhclxyXG4gKiBuYW1lOiBtb2R1bGUgbmFtZVxyXG4gKiBtZXJnZURlZmF1bHRBbmROYW1lRXhwb3J0czogd2hldGhlciB0byBtZXJnZSBkZWZhdWx0IGFuZCBuYW1lZCBleHBvcnRzXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgbGlicyA9IFtcclxuICBcImF4aW9zXCIsXHJcbiAgXCJyZWR1eFwiLFxyXG4gIFwicmVhY3Qtcm91dGVyXCIsXHJcbiAgXCJyZWFjdC1yb3V0ZXItZG9tXCIsXHJcbiAgXCJyZWFjdC1yZWR1eFwiLFxyXG4gIFwicmVhY3RcIixcclxuICBcInJlYWN0LWRvbVwiLFxyXG4gIFwibG9kYXNoXCIsXHJcbiAgXCJoaXN0b3J5XCIsXHJcbiAgXCJhbnRkXCIsXHJcbiAgXCJAZG5kLWtpdC9jb3JlXCIsXHJcbiAgXCJAZG5kLWtpdC9tb2RpZmllcnNcIixcclxuICBcIkBkbmQta2l0L3NvcnRhYmxlXCIsXHJcbiAgXCJAZG5kLWtpdC91dGlsaXRpZXNcIixcclxuICB7XHJcbiAgICBuYW1lOiBcIm1vbWVudFwiLFxyXG4gICAgZXh0cmFjdERlZmF1bHQ6IHRydWUsXHJcbiAgfSxcclxuICB7XHJcbiAgICBuYW1lOiBcImRheWpzXCIsXHJcbiAgICBleHRyYWN0RGVmYXVsdDogdHJ1ZSxcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6IFwibG93Y29kZXItc2RrXCIsXHJcbiAgICBmcm9tOiBcIi4vc3JjL2luZGV4LnNkay50c1wiLFxyXG4gIH0sXHJcbiAge1xyXG4gICAgbmFtZTogXCJzdHlsZWQtY29tcG9uZW50c1wiLFxyXG4gICAgbWVyZ2VEZWZhdWx0QW5kTmFtZUV4cG9ydHM6IHRydWUsXHJcbiAgfSxcclxuXTtcclxuXHJcbi8qKlxyXG4gKiBnZXQgZ2xvYmFsIHZhciBuYW1lIGZyb20gbW9kdWxlIG5hbWVcclxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcclxuICogQHJldHVybnNcclxuICovXHJcbmV4cG9ydCBjb25zdCBnZXRMaWJHbG9iYWxWYXJOYW1lID0gKG5hbWUpID0+IHtcclxuICByZXR1cm4gXCIkXCIgKyBuYW1lLnJlcGxhY2UoL0AvZywgXCIkXCIpLnJlcGxhY2UoL1tcXC9cXC1dL2csIFwiX1wiKTtcclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBnZXRMaWJOYW1lcyA9ICgpID0+IHtcclxuICByZXR1cm4gbGlicy5tYXAoKGkpID0+IHtcclxuICAgIGlmICh0eXBlb2YgaSA9PT0gXCJvYmplY3RcIikge1xyXG4gICAgICByZXR1cm4gaS5uYW1lO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGk7XHJcbiAgfSk7XHJcbn07XHJcblxyXG5leHBvcnQgY29uc3QgZ2V0QWxsTGliR2xvYmFsVmFyTmFtZXMgPSAoKSA9PiB7XHJcbiAgY29uc3QgcmV0ID0ge307XHJcbiAgbGlicy5mb3JFYWNoKChsaWIpID0+IHtcclxuICAgIGxldCBuYW1lID0gbGliO1xyXG4gICAgaWYgKHR5cGVvZiBsaWIgPT09IFwib2JqZWN0XCIpIHtcclxuICAgICAgbmFtZSA9IGxpYi5uYW1lO1xyXG4gICAgfVxyXG4gICAgcmV0W25hbWVdID0gZ2V0TGliR2xvYmFsVmFyTmFtZShuYW1lKTtcclxuICB9KTtcclxuICByZXR1cm4gcmV0O1xyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IGxpYnNJbXBvcnRDb2RlID0gKGV4Y2x1ZGUgPSBbXSkgPT4ge1xyXG4gIGNvbnN0IGltcG9ydExpbmVzID0gW107XHJcbiAgY29uc3QgYXNzaWduTGluZXMgPSBbXTtcclxuICBsaWJzLmZvckVhY2goKGkpID0+IHtcclxuICAgIGxldCBuYW1lID0gaTtcclxuICAgIGxldCBtZXJnZSA9IGZhbHNlO1xyXG4gICAgbGV0IGZyb20gPSBuYW1lO1xyXG4gICAgbGV0IGV4dHJhY3REZWZhdWx0ID0gZmFsc2U7XHJcblxyXG4gICAgaWYgKHR5cGVvZiBpID09PSBcIm9iamVjdFwiKSB7XHJcbiAgICAgIG5hbWUgPSBpLm5hbWU7XHJcbiAgICAgIG1lcmdlID0gaS5tZXJnZURlZmF1bHRBbmROYW1lRXhwb3J0cyA/PyBmYWxzZTtcclxuICAgICAgZnJvbSA9IGkuZnJvbSA/PyBuYW1lO1xyXG4gICAgICBleHRyYWN0RGVmYXVsdCA9IGkuZXh0cmFjdERlZmF1bHQgPz8gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGV4Y2x1ZGUuaW5jbHVkZXMobmFtZSkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHZhck5hbWUgPSBnZXRMaWJHbG9iYWxWYXJOYW1lKG5hbWUpO1xyXG4gICAgaWYgKG1lcmdlKSB7XHJcbiAgICAgIGltcG9ydExpbmVzLnB1c2goYGltcG9ydCAqIGFzICR7dmFyTmFtZX1fbmFtZWRfZXhwb3J0cyBmcm9tICcke2Zyb219JztgKTtcclxuICAgICAgaW1wb3J0TGluZXMucHVzaChgaW1wb3J0ICR7dmFyTmFtZX0gZnJvbSAnJHtmcm9tfSc7YCk7XHJcbiAgICAgIGFzc2lnbkxpbmVzLnB1c2goYE9iamVjdC5hc3NpZ24oJHt2YXJOYW1lfSwgJHt2YXJOYW1lfV9uYW1lZF9leHBvcnRzKTtgKTtcclxuICAgIH0gZWxzZSBpZiAoZXh0cmFjdERlZmF1bHQpIHtcclxuICAgICAgaW1wb3J0TGluZXMucHVzaChgaW1wb3J0ICR7dmFyTmFtZX0gZnJvbSAnJHtmcm9tfSc7YCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpbXBvcnRMaW5lcy5wdXNoKGBpbXBvcnQgKiBhcyAke3Zhck5hbWV9IGZyb20gJyR7ZnJvbX0nO2ApO1xyXG4gICAgfVxyXG4gICAgYXNzaWduTGluZXMucHVzaChgd2luZG93LiR7dmFyTmFtZX0gPSAke3Zhck5hbWV9O2ApO1xyXG4gIH0pO1xyXG4gIHJldHVybiBpbXBvcnRMaW5lcy5jb25jYXQoYXNzaWduTGluZXMpLmpvaW4oXCJcXG5cIik7XHJcbn07XHJcbiIsICJjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSA9IFwiQzpcXFxcUHJvamVjdHNcXFxcbG93Y29kZXJcXFxcY2xpZW50XFxcXHBhY2thZ2VzXFxcXGxvd2NvZGVyXFxcXHNyY1xcXFxkZXYtdXRpbHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkM6XFxcXFByb2plY3RzXFxcXGxvd2NvZGVyXFxcXGNsaWVudFxcXFxwYWNrYWdlc1xcXFxsb3djb2RlclxcXFxzcmNcXFxcZGV2LXV0aWxzXFxcXGdsb2JhbERlcFBsZ3Vpbi5qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vQzovUHJvamVjdHMvbG93Y29kZXIvY2xpZW50L3BhY2thZ2VzL2xvd2NvZGVyL3NyYy9kZXYtdXRpbHMvZ2xvYmFsRGVwUGxndWluLmpzXCI7aW1wb3J0IHsgbGlic0ltcG9ydENvZGUgfSBmcm9tIFwiLi9leHRlcm5hbC5qc1wiO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdsb2JhbERlcFBsdWdpbihleGNsdWRlID0gW10pIHtcclxuICBjb25zdCB2aXJ0dWFsTW9kdWxlSWQgPSBcInZpcnR1YWw6Z2xvYmFsc1wiO1xyXG4gIHJldHVybiB7XHJcbiAgICBuYW1lOiBcImxvd2NvZGVyLWdsb2JhbC1wbHVnaW5cIixcclxuICAgIHJlc29sdmVJZChpZCkge1xyXG4gICAgICBpZiAoaWQgPT09IHZpcnR1YWxNb2R1bGVJZCkge1xyXG4gICAgICAgIHJldHVybiBpZDtcclxuICAgICAgfVxyXG4gICAgfSxcclxuICAgIGxvYWQoaWQpIHtcclxuICAgICAgaWYgKGlkID09PSB2aXJ0dWFsTW9kdWxlSWQpIHtcclxuICAgICAgICByZXR1cm4gbGlic0ltcG9ydENvZGUoZXhjbHVkZSk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcbiAgfTtcclxufVxyXG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQXVVLE9BQU8sWUFBWTtBQUMxVixTQUFTLG9CQUErQztBQUN4RCxPQUFPLFdBQVc7QUFDbEIsT0FBTyx1QkFBdUI7QUFDOUIsT0FBTyxnQkFBZ0I7QUFDdkIsT0FBTyxhQUFhO0FBQ3BCLFNBQVMsa0JBQWtCO0FBQzNCLE9BQU8sVUFBVTtBQUNqQixPQUFPLFdBQVc7QUFDbEIsU0FBUyx3QkFBd0I7OztBQ0UxQixTQUFTLGdCQUFnQixLQUFLO0FBQ25DLE1BQUksQ0FBQyxLQUFLO0FBQ1IsV0FBTztBQUFBLEVBQ1Q7QUFDQSxNQUFJLENBQUMsSUFBSSxTQUFTLEdBQUcsR0FBRztBQUN0QixXQUFPLEdBQUcsR0FBRztBQUFBLEVBQ2Y7QUFDQSxTQUFPO0FBQ1Q7OztBQ25Cc1gsSUFBTSxZQUFZO0FBQUEsRUFDdFk7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLGNBQWM7QUFBQSxFQUNoQjtBQUNGOzs7QUNwRE8sSUFBTSxPQUFPO0FBQUEsRUFDbEI7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLElBQ0UsTUFBTTtBQUFBLElBQ04sZ0JBQWdCO0FBQUEsRUFDbEI7QUFBQSxFQUNBO0FBQUEsSUFDRSxNQUFNO0FBQUEsSUFDTixnQkFBZ0I7QUFBQSxFQUNsQjtBQUFBLEVBQ0E7QUFBQSxJQUNFLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxFQUNSO0FBQUEsRUFDQTtBQUFBLElBQ0UsTUFBTTtBQUFBLElBQ04sNEJBQTRCO0FBQUEsRUFDOUI7QUFDRjtBQU9PLElBQU0sc0JBQXNCLENBQUMsU0FBUztBQUMzQyxTQUFPLE1BQU0sS0FBSyxRQUFRLE1BQU0sR0FBRyxFQUFFLFFBQVEsV0FBVyxHQUFHO0FBQzdEO0FBdUJPLElBQU0saUJBQWlCLENBQUMsVUFBVSxDQUFDLE1BQU07QUFDOUMsUUFBTSxjQUFjLENBQUM7QUFDckIsUUFBTSxjQUFjLENBQUM7QUFDckIsT0FBSyxRQUFRLENBQUMsTUFBTTtBQUNsQixRQUFJLE9BQU87QUFDWCxRQUFJLFFBQVE7QUFDWixRQUFJLE9BQU87QUFDWCxRQUFJLGlCQUFpQjtBQUVyQixRQUFJLE9BQU8sTUFBTSxVQUFVO0FBQ3pCLGFBQU8sRUFBRTtBQUNULGNBQVEsRUFBRSw4QkFBOEI7QUFDeEMsYUFBTyxFQUFFLFFBQVE7QUFDakIsdUJBQWlCLEVBQUUsa0JBQWtCO0FBQUEsSUFDdkM7QUFFQSxRQUFJLFFBQVEsU0FBUyxJQUFJLEdBQUc7QUFDMUI7QUFBQSxJQUNGO0FBRUEsVUFBTSxVQUFVLG9CQUFvQixJQUFJO0FBQ3hDLFFBQUksT0FBTztBQUNULGtCQUFZLEtBQUssZUFBZSxPQUFPLHdCQUF3QixJQUFJLElBQUk7QUFDdkUsa0JBQVksS0FBSyxVQUFVLE9BQU8sVUFBVSxJQUFJLElBQUk7QUFDcEQsa0JBQVksS0FBSyxpQkFBaUIsT0FBTyxLQUFLLE9BQU8sa0JBQWtCO0FBQUEsSUFDekUsV0FBVyxnQkFBZ0I7QUFDekIsa0JBQVksS0FBSyxVQUFVLE9BQU8sVUFBVSxJQUFJLElBQUk7QUFBQSxJQUN0RCxPQUFPO0FBQ0wsa0JBQVksS0FBSyxlQUFlLE9BQU8sVUFBVSxJQUFJLElBQUk7QUFBQSxJQUMzRDtBQUNBLGdCQUFZLEtBQUssVUFBVSxPQUFPLE1BQU0sT0FBTyxHQUFHO0FBQUEsRUFDcEQsQ0FBQztBQUNELFNBQU8sWUFBWSxPQUFPLFdBQVcsRUFBRSxLQUFLLElBQUk7QUFDbEQ7OztBQ25HTyxTQUFTLGdCQUFnQixVQUFVLENBQUMsR0FBRztBQUM1QyxRQUFNLGtCQUFrQjtBQUN4QixTQUFPO0FBQUEsSUFDTCxNQUFNO0FBQUEsSUFDTixVQUFVLElBQUk7QUFDWixVQUFJLE9BQU8saUJBQWlCO0FBQzFCLGVBQU87QUFBQSxNQUNUO0FBQUEsSUFDRjtBQUFBLElBQ0EsS0FBSyxJQUFJO0FBQ1AsVUFBSSxPQUFPLGlCQUFpQjtBQUMxQixlQUFPLGVBQWUsT0FBTztBQUFBLE1BQy9CO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFDRjs7O0FKakJBLElBQU0sbUNBQW1DO0FBY3pDLE9BQU8sT0FBTztBQUVkLElBQU0saUJBQWlCLFFBQVEsSUFBSTtBQUNuQyxJQUFNLDRCQUE0QixRQUFRLElBQUk7QUFDOUMsSUFBTSxVQUFVLFFBQVEsSUFBSSxZQUFZO0FBQ3hDLElBQU0sVUFBVSxRQUFRLElBQUk7QUFDNUIsSUFBTSxhQUFhLFlBQVk7QUFDL0IsSUFBTSxPQUFPLFlBQVksZ0JBQWdCO0FBQ3pDLElBQU0sUUFBUSxZQUFZO0FBQzFCLElBQU0sc0JBQXNCLENBQUMsQ0FBQyxRQUFRLElBQUk7QUFHMUMsSUFBTSx1QkFBdUI7QUFDN0IsSUFBTSxPQUFPLGdCQUFnQixRQUFRLElBQUksVUFBVTtBQUVuRCxJQUFJLENBQUMsa0JBQWtCLE9BQU87QUFDNUIsVUFBUSxJQUFJO0FBQ1osVUFBUSxJQUFJLE1BQU0sNENBQTRDO0FBQzlELFVBQVEsSUFBSSxNQUFNLGtGQUFrRjtBQUNwRyxVQUFRLElBQUk7QUFDWixVQUFRLEtBQUssQ0FBQztBQUNoQjtBQUVBLElBQU0sY0FBc0M7QUFBQSxFQUMxQyxRQUFRO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixjQUFjO0FBQUEsRUFDaEI7QUFDRjtBQUVBLElBQUksMkJBQTJCO0FBQzdCLGNBQVksZUFBZSxJQUFJO0FBQUEsSUFDN0IsUUFBUTtBQUFBLEVBQ1Y7QUFDRjtBQUVBLElBQU0sU0FBUyxDQUFDO0FBQ2hCLFVBQVUsUUFBUSxDQUFDLEVBQUUsTUFBTSxhQUFhLE1BQU07QUFDNUMsU0FBTyxJQUFJLElBQUksS0FBSyxVQUFVLFFBQVEsSUFBSSxJQUFJLEtBQUssWUFBWTtBQUNqRSxDQUFDO0FBR00sSUFBTSxhQUF5QjtBQUFBLEVBQ3BDO0FBQUEsRUFDQSxlQUFlLENBQUMsU0FBUztBQUFBLEVBQ3pCLFNBQVM7QUFBQSxJQUNQLFlBQVksQ0FBQyxRQUFRLE9BQU8sT0FBTyxRQUFRLFFBQVEsT0FBTztBQUFBLElBQzFELE9BQU87QUFBQSxNQUNMLGdCQUFnQixLQUFLO0FBQUEsUUFDbkI7QUFBQSxRQUNBLE9BQU8sbUJBQW1CLGFBQWEsY0FBYyxJQUFJLEtBQUs7QUFBQSxNQUNoRTtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQUEsRUFDQTtBQUFBLEVBQ0EsT0FBTztBQUFBLElBQ0wsVUFBVTtBQUFBLElBQ1YsUUFBUTtBQUFBLElBQ1IsV0FBVztBQUFBLElBQ1gsUUFBUTtBQUFBLElBQ1IsV0FBVztBQUFBLElBQ1gsYUFBYTtBQUFBLElBQ2IsZUFBZTtBQUFBLE1BQ2IsUUFBUTtBQUFBLFFBQ04sZ0JBQWdCO0FBQUEsTUFDbEI7QUFBQSxJQUNGO0FBQUEsSUFDQSxpQkFBaUI7QUFBQSxNQUNmLHdCQUF3QixDQUFDLE9BQU87QUFDOUIsWUFBSSxHQUFHLFFBQVEsVUFBVSxNQUFNLElBQUk7QUFDakMsaUJBQU87QUFBQSxRQUNUO0FBQ0EsZUFBTztBQUFBLE1BQ1Q7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUFBLEVBQ0EsS0FBSztBQUFBLElBQ0gscUJBQXFCO0FBQUEsTUFDbkIsTUFBTTtBQUFBLFFBQ0osWUFBWTtBQUFBLFVBQ1Ysa0JBQWtCO0FBQUEsVUFDbEIsZUFBZTtBQUFBLFVBQ2Ysc0JBQXNCO0FBQUEsVUFDdEIsdUJBQXVCO0FBQUEsUUFDekI7QUFBQSxRQUNBLG1CQUFtQjtBQUFBLE1BQ3JCO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFBQSxFQUNBLFFBQVE7QUFBQSxJQUNOLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxJQUNOLE9BQU87QUFBQSxFQUNUO0FBQUEsRUFDQSxTQUFTO0FBQUEsSUFDUCxRQUFRO0FBQUEsTUFDTixZQUFZO0FBQUEsTUFDWixRQUFRO0FBQUEsUUFDTixhQUFhO0FBQUEsUUFDYixLQUFLO0FBQUEsVUFDSCxVQUFVLENBQUMsT0FBTztBQUFBLFFBQ3BCO0FBQUEsTUFDRjtBQUFBLElBQ0YsQ0FBQztBQUFBLElBQ0QsTUFBTTtBQUFBLE1BQ0osT0FBTztBQUFBLFFBQ0wsWUFBWTtBQUFBLFVBQ1YsU0FBUyxDQUFDLG1CQUFtQjtBQUFBLFFBQy9CO0FBQUEsTUFDRjtBQUFBLElBQ0YsQ0FBQztBQUFBLElBQ0Qsa0JBQWtCO0FBQUEsTUFDaEIsVUFBVSxDQUFDLDZCQUE2QixrQ0FBa0M7QUFBQSxJQUM1RSxDQUFDO0FBQUEsSUFDRCxXQUFXO0FBQUEsTUFDVCxhQUFhO0FBQUEsUUFDWCxZQUFZO0FBQUEsUUFDWixVQUFVO0FBQUEsUUFDVixNQUFNO0FBQUEsUUFDTixXQUFXO0FBQUEsUUFDWCxLQUFLO0FBQUEsTUFDUDtBQUFBLElBQ0YsQ0FBQztBQUFBLElBQ0QsZ0JBQWdCO0FBQUEsSUFDaEIsaUJBQWlCO0FBQUEsTUFDZixRQUFRO0FBQUEsTUFDUixRQUFRO0FBQUEsUUFDTixNQUFNO0FBQUEsVUFDSixvQkFBb0IsUUFBUSxLQUFLLGdCQUFnQixJQUFJLEdBQUcsb0JBQW9CO0FBQUEsUUFDOUU7QUFBQSxNQUNGO0FBQUEsSUFDRixDQUFDO0FBQUEsSUFDRCx1QkFBdUIsV0FBVztBQUFBLEVBQ3BDLEVBQUUsT0FBTyxPQUFPO0FBQ2xCO0FBRUEsSUFBTSxxQkFBaUM7QUFBQSxFQUNyQyxHQUFHO0FBQUEsRUFDSCxRQUFRO0FBQUEsSUFDTixHQUFHLFdBQVc7QUFBQSxJQUNkLHdCQUF3QixLQUFLLFVBQVUsWUFBWTtBQUFBLEVBQ3JEO0FBQUEsRUFDQSxPQUFPO0FBQUEsSUFDTCxHQUFHLFdBQVc7QUFBQSxJQUNkLFVBQVU7QUFBQSxJQUNWLGVBQWU7QUFBQSxJQUNmLGFBQWE7QUFBQSxJQUNiLEtBQUs7QUFBQSxNQUNILFNBQVMsQ0FBQyxNQUFNO0FBQUEsTUFDaEIsTUFBTTtBQUFBLE1BQ04sT0FBTztBQUFBLE1BQ1AsVUFBVSxNQUFNO0FBQ2QsZUFBTztBQUFBLE1BQ1Q7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUNGO0FBRUEsSUFBTSxlQUFlO0FBQUEsRUFDbkIsTUFBTTtBQUFBLEVBQ04sY0FBYztBQUNoQjtBQUVBLElBQU0sY0FBYyxhQUFhLFFBQVEsSUFBSSxnQkFBZ0IsTUFBTTtBQUVuRSxJQUFPLHNCQUFRLGFBQWEsZUFBZSxVQUFVOyIsCiAgIm5hbWVzIjogW10KfQo=

From b58ad7d0075fe5f4b1b6aa06dea1addde0254d40 Mon Sep 17 00:00:00 2001
From: freddysundowner <githumbi3fred@gmail.com>
Date: Sat, 17 Feb 2024 14:57:55 +0300
Subject: [PATCH 50/97] autocomplete removed extra tab and cleaned up the codes

---
 .../autoCompleteComp/autoCompleteComp.tsx     | 63 ++----------
 .../selectInputComp/selectCompConstants.tsx   | 99 ++++++++++++-------
 2 files changed, 70 insertions(+), 92 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/autoCompleteComp/autoCompleteComp.tsx b/client/packages/lowcoder/src/comps/comps/autoCompleteComp/autoCompleteComp.tsx
index 5c01bdc62d..1101fc6d28 100644
--- a/client/packages/lowcoder/src/comps/comps/autoCompleteComp/autoCompleteComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/autoCompleteComp/autoCompleteComp.tsx
@@ -34,7 +34,6 @@ import { trans } from "i18n";
 import { IconControl } from "comps/controls/iconControl";
 import { hasIcon } from "comps/utils";
 import { InputRef } from "antd/es/input";
-import { default as  AntInputSearch } from "antd/es/input/Search";
 import { default as ConfigProvider } from "antd/es/config-provider";
 import { default as AutoComplete } from "antd/es/auto-complete";
 import { RefControl } from "comps/controls/refControl";
@@ -54,40 +53,21 @@ import {
   componentSize,
 } from "./autoCompleteConstants";
 
-// const InputStyle = styled(Input)<{ $style: InputLikeStyleType }>`
-//   ${(props) => props.$style && getStyle(props.$style) }
-// `;
+
 
 const InputStyle = styled(Input)<{ $style: InputLikeStyleType }>`
   ${(props) => css`
     ${getStyle(props.$style)}
-    .ant-select-selection-search-input {
-      height: 100%;
-    }
     input {
-      padding: ${props.style?.padding}
+      padding: ${props.style?.padding};
     }
-  `}
-`;
-
-const CustomStyledSearch = styled(AntInputSearch)<{ $style: InputLikeStyleType }>`
-  ${(props) => css`
-    padding: 0;
-    input.ant-input {
-      padding: ${props.$style?.padding};
-    }
-    .ant-btn.ant-input-search-button {
-      height: 100%;
-      padding: ${props.$style?.padding} !important;
-      padding-left: 15px !important;
-      padding-right: 15px !important;
-      .ant-btn-icon {
-        line-height: 28px;
-      }
+    .ant-select-single {
+      width: 100% !important;
     }
   `}
 `;
 
+
 const childrenMap = {
   ...textInputChildren,
   viewRef: RefControl<InputRef>,
@@ -131,6 +111,7 @@ let AutoCompleteCompBase = (function () {
       autocompleteIconColor,
       componentSize,
     } = props;
+    
 
     const getTextInputValidate = () => {
       return {
@@ -189,7 +170,7 @@ let AutoCompleteCompBase = (function () {
                 props.valueInItems.onChange(false);
                 setvalidateState(textInputValidate(getTextInputValidate()));
                 setsearchtext(value);
-                props.value.onChange(value);
+                props.value.onChange(value); 
                 props.onEvent("change")
               }}
               onFocus={() => {
@@ -280,22 +261,7 @@ let AutoCompleteCompBase = (function () {
                 return false;
               }}
             >
-              {autoCompleteType === "AntDesign" ? (
-                <CustomStyledSearch
-                  placeholder={placeholder}
-                  enterButton={autocompleteIconColor === "blue"}
-                  allowClear={props.allowClear}
-                  ref={props.viewRef}
-                  onPressEnter={undefined}
-                  status={getValidate(validateState)}
-                  onSubmit={() => props.onEvent("submit")}
-                  $style={props.style}
-                />
-              ) : (
                 <InputStyle
-                  // style={{
-                  //   height: componentSize === "small" ? "30px" : "38px",
-                  // }}
                   ref={props.viewRef}
                   placeholder={placeholder}
                   allowClear={props.allowClear}
@@ -305,7 +271,6 @@ let AutoCompleteCompBase = (function () {
                   status={getValidate(validateState)}
                   onPressEnter={undefined}
                 />
-              )}
             </AutoComplete>
           </ConfigProvider>
         </>
@@ -317,17 +282,7 @@ let AutoCompleteCompBase = (function () {
     .setPropertyViewFn((children) => {
       return (
         <>
-          <Section name={trans("autoComplete.ComponentType")}>
-            {children.autoCompleteType.propertyView({
-              label: trans("autoComplete.type"),
-              radioButton: true,
-            })}
-            {children.autoCompleteType.getView() === "AntDesign" &&
-              children.autocompleteIconColor.propertyView({
-                label: trans("button.prefixIcon"),
-                radioButton: true,
-              })}
-
+          <Section>
             {children.autoCompleteType.getView() === "normal" &&
               children.prefixIcon.propertyView({
                 label: trans("button.prefixIcon"),
@@ -403,6 +358,6 @@ export const AutoCompleteComp = withExposingConfigs(AutoCompleteCompBase, [
   new NameConfig("value", trans("export.inputValueDesc")),
   new NameConfig("valueInItems", trans("autoComplete.valueInItems")),
   NameConfigPlaceHolder,
-  NameConfigRequired,
+  NameConfigRequired, 
   ...TextInputConfigs,
 ]);
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
index 4f5a0ba18e..ca5a6648b6 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
@@ -7,7 +7,7 @@ import {
 import { BoolControl } from "../../controls/boolControl";
 import { LabelControl } from "../../controls/labelControl";
 import { BoolCodeControl, StringControl } from "../../controls/codeControl";
-import { PaddingControl } from "../../controls/paddingControl";	
+import { PaddingControl } from "../../controls/paddingControl";
 import { MarginControl } from "../../controls/marginControl";
 import {
   ControlNode,
@@ -27,14 +27,17 @@ import {
   SelectInputValidationChildren,
   SelectInputValidationSection,
 } from "./selectInputConstants";
-import { formDataChildren, FormDataPropertyView } from "../formComp/formDataConstants";
+import {
+  formDataChildren,
+  FormDataPropertyView,
+} from "../formComp/formDataConstants";
 import {
   CascaderStyleType,
   MultiSelectStyleType,
   SelectStyleType,
   TreeSelectStyleType,
   widthCalculator,
-  heightCalculator
+  heightCalculator,
 } from "comps/controls/styleControlConstants";
 import { stateComp, withDefault } from "../../generators";
 import {
@@ -55,34 +58,39 @@ import { useContext } from "react";
 import { EditorContext } from "comps/editorState";
 
 export const getStyle = (
-  style: SelectStyleType | MultiSelectStyleType | CascaderStyleType | TreeSelectStyleType
+  style:
+    | SelectStyleType
+    | MultiSelectStyleType
+    | CascaderStyleType
+    | TreeSelectStyleType
 ) => {
   return css`
     &.ant-select .ant-select-selector,
     &.ant-select-multiple .ant-select-selection-item {
       border-radius: ${style.radius};
-      padding: ${style.padding};	
-      height: auto;	
-    }	
-    .ant-select-selection-search {	
-      padding: ${style.padding};	
-    }	
-    .ant-select-selector::after,	
-    .ant-select-selection-placeholder,	
-    .ant-select-selection-item {	
+      padding: ${style.padding};
+      height: auto;
+    }
+    .ant-select-selection-search {
+      padding: ${style.padding};
+    }
+    .ant-select-selector::after,
+    .ant-select-selection-placeholder,
+    .ant-select-selection-item {
       line-height: 1.5715 !important;
     }
 
     &.ant-select:not(.ant-select-disabled) {
       color: ${style.text};
-      .ant-select-selection-placeholder,	
-      .ant-select-selection-item {	
-        line-height: 1.5715 !important;	
+      .ant-select-selection-placeholder,
+      .ant-select-selection-item {
+        line-height: 1.5715 !important;
       }
       .ant-select-selection-placeholder,
       &.ant-select-single.ant-select-open .ant-select-selection-item {
         color: ${style.text};
         opacity: 0.4;
+        width: 100%;
       }
 
       .ant-select-selector {
@@ -103,16 +111,16 @@ export const getStyle = (
         color: ${style.text === "#222222"
           ? "#8B8FA3"
           : isDarkColor(style.text)
-          ? lightenColor(style.text, 0.2)
-          : style.text};
+            ? lightenColor(style.text, 0.2)
+            : style.text};
       }
 
       .ant-select-clear:hover {
         color: ${style.text === "#222222"
           ? "#8B8FA3"
           : isDarkColor(style.text)
-          ? lightenColor(style.text, 0.1)
-          : style.text};
+            ? lightenColor(style.text, 0.1)
+            : style.text};
       }
 
       &.ant-select-multiple .ant-select-selection-item {
@@ -160,7 +168,9 @@ const getDropdownStyle = (style: MultiSelectStyleType) => {
   `;
 };
 
-const Select = styled(AntdSelect)<{ $style: SelectStyleType & MultiSelectStyleType }>`
+const Select = styled(AntdSelect)<{
+  $style: SelectStyleType & MultiSelectStyleType;
+}>`
   width: 100%;
 
   ${(props) => props.$style && getStyle(props.$style)}
@@ -169,7 +179,7 @@ const Select = styled(AntdSelect)<{ $style: SelectStyleType & MultiSelectStyleTy
 const DropdownStyled = styled.div<{ $style: MultiSelectStyleType }>`
   ${(props) => props.$style && getDropdownStyle(props.$style)}
   .ant-select-item-option-content {
-    ${(props) => `padding: ${props.$style.padding}`};	
+    ${(props) => `padding: ${props.$style.padding}`};
   }
   .option-label img {
     min-width: 14px;
@@ -197,7 +207,7 @@ export const SelectChildrenMap = {
   inputValue: stateComp<string>(""), // user's input value when search
   showSearch: BoolControl.DEFAULT_TRUE,
   viewRef: RefControl<BaseSelectRef>,
-  margin: MarginControl,	
+  margin: MarginControl,
   padding: PaddingControl,
   ...SelectInputValidationChildren,
   ...formDataChildren,
@@ -221,9 +231,13 @@ export const SelectUIView = (
     placeholder={props.placeholder}
     value={props.value}
     showSearch={props.showSearch}
-    filterOption={(input, option) => option?.label.toLowerCase().includes(input.toLowerCase())}
+    filterOption={(input, option) =>
+      option?.label.toLowerCase().includes(input.toLowerCase())
+    }
     dropdownRender={(originNode: ReactNode) => (
-      <DropdownStyled $style={props.style as MultiSelectStyleType}>{originNode}</DropdownStyled>
+      <DropdownStyled $style={props.style as MultiSelectStyleType}>
+        {originNode}
+      </DropdownStyled>
     )}
     dropdownStyle={{
       padding: 0,
@@ -250,8 +264,8 @@ export const SelectUIView = (
           key={option.value}
         >
           <Wrapper className="option-label">
-            {props.options.findIndex((option) => hasIcon(option.prefixIcon)) > -1 &&
-              option.prefixIcon}
+            {props.options.findIndex((option) => hasIcon(option.prefixIcon)) >
+              -1 && option.prefixIcon}
             {<span>{option.label}</span>}
           </Wrapper>
         </Select.Option>
@@ -273,24 +287,28 @@ export const SelectPropertyView = (
   <>
     <Section name={sectionNames.basic}>
       {children.options.propertyView({})}
-      {children.defaultValue.propertyView({ label: trans("prop.defaultValue") })}
+      {children.defaultValue.propertyView({
+        label: trans("prop.defaultValue"),
+      })}
       {placeholderPropertyView(children)}
     </Section>
 
     {["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && (
-      <><>
-        <SelectInputValidationSection {...children} />
-        <FormDataPropertyView {...children} />
-      </><Section name={sectionNames.interaction}>
+      <>
+        <>
+          <SelectInputValidationSection {...children} />
+          <FormDataPropertyView {...children} />
+        </>
+        <Section name={sectionNames.interaction}>
           {children.onEvent.getPropertyView()}
           {disabledPropertyView(children)}
           {hiddenPropertyView(children)}
-        </Section></>
+        </Section>
+      </>
     )}
 
-    {["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && (
-      children.label.getPropertyView()
-    )}
+    {["layout", "both"].includes(useContext(EditorContext).editorModeStatus) &&
+      children.label.getPropertyView()}
 
     {["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && (
       <Section name={sectionNames.advanced}>
@@ -299,7 +317,9 @@ export const SelectPropertyView = (
       </Section>
     )}
 
-    {["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && (
+    {["layout", "both"].includes(
+      useContext(EditorContext).editorModeStatus
+    ) && (
       <Section name={sectionNames.style}>
         {children.style.getPropertyView()}
       </Section>
@@ -307,4 +327,7 @@ export const SelectPropertyView = (
   </>
 );
 
-export const baseSelectRefMethods = refMethods<BaseSelectRef>([focusMethod, blurMethod]);
+export const baseSelectRefMethods = refMethods<BaseSelectRef>([
+  focusMethod,
+  blurMethod,
+]);

From 4cdbe2aa51970b009ce65b665c2b7f24bc78a848 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Sat, 17 Feb 2024 13:03:06 +0100
Subject: [PATCH 51/97] Adding scrollbar Support for Containers

---
 .../comps/containerComp/containerComp.tsx     |  6 +-
 .../comps/containerComp/containerView.tsx     |  2 +
 .../comps/comps/gridLayoutComp/canvasView.tsx | 25 +++----
 .../listViewComp/listViewPropertyView.tsx     |  8 +-
 .../comps/triContainerComp/triContainer.tsx   | 73 ++++++++++++-------
 .../triContainerComp/triContainerComp.tsx     |  4 +-
 6 files changed, 74 insertions(+), 44 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/containerComp/containerComp.tsx b/client/packages/lowcoder/src/comps/comps/containerComp/containerComp.tsx
index 5df0cd4be3..e6ba29282f 100644
--- a/client/packages/lowcoder/src/comps/comps/containerComp/containerComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/containerComp/containerComp.tsx
@@ -24,7 +24,7 @@ export const ContainerBaseComp = (function () {
   return new ContainerCompBuilder(childrenMap, (props, dispatch) => {
     return (
       <DisabledContext.Provider value={props.disabled}>
-        <TriContainer {...props} />
+          <TriContainer {...props} />        
       </DisabledContext.Provider>
     );
   })
@@ -78,6 +78,7 @@ function convertOldContainerParams(params: CompParams<any>) {
     // old params
     if (container && (container.hasOwnProperty("layout") || container.hasOwnProperty("items"))) {
       const autoHeight = tempParams.value.autoHeight;
+      const scrollbars = tempParams.value.scrollbars;
       return {
         ...tempParams,
         value: {
@@ -87,6 +88,7 @@ function convertOldContainerParams(params: CompParams<any>) {
             showBody: true,
             showFooter: false,
             autoHeight: autoHeight,
+            scrollbars: scrollbars,
           },
         },
       };
@@ -123,7 +125,7 @@ export function defaultContainerData(
           layoutItem: {
             i: "",
             h: 5,
-            w: 24,
+            w: 12,
             x: 0,
             y: 0,
           },
diff --git a/client/packages/lowcoder/src/comps/comps/containerComp/containerView.tsx b/client/packages/lowcoder/src/comps/comps/containerComp/containerView.tsx
index 45d8f7d26a..d7ee0e4218 100644
--- a/client/packages/lowcoder/src/comps/comps/containerComp/containerView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/containerComp/containerView.tsx
@@ -5,6 +5,7 @@ import { hookCompCategory, HookCompType } from "comps/hooks/hookCompTypes";
 import { UICompLayoutInfo, uiCompRegistry, UICompType } from "comps/uiCompRegistry";
 import { genRandomKey } from "comps/utils/idGenerator";
 import { parseCompType } from "comps/utils/remote";
+import { ScrollBar } from "lowcoder-design";
 import {
   DEFAULT_POSITION_PARAMS,
   draggingUtils,
@@ -102,6 +103,7 @@ type ExtraProps = {
   rowCount?: number;
   isRowCountLocked?: boolean;
   autoHeight?: boolean;
+  scrollbars?: boolean;
   minHeight?: string;
   emptyRows?: number;
   extraHeight?: string;
diff --git a/client/packages/lowcoder/src/comps/comps/gridLayoutComp/canvasView.tsx b/client/packages/lowcoder/src/comps/comps/gridLayoutComp/canvasView.tsx
index ec11598f70..545608daa3 100644
--- a/client/packages/lowcoder/src/comps/comps/gridLayoutComp/canvasView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/gridLayoutComp/canvasView.tsx
@@ -113,20 +113,19 @@ export function CanvasView(props: ContainerBaseProps) {
         $bgColor={bgColor}
       >
         <div>
-          <ScrollBar style={{ height: "100%", margin: "0px", padding: "0px" }}>
+          {/* <ScrollBar style={{ height: "100%", margin: "0px", padding: "0px" }}> */}
             <Profiler id="Panel" onRender={profilerCallback}>
-            <InnerGrid
-              containerPadding={rootContainerPadding}
-              overflow={rootContainerOverflow}
-              {...props}
-              positionParams={positionParams} // Added By Aqib Mirza
-              {...gridLayoutCanvasProps}
-              bgColor={bgColor}
-              radius="0px"
-            />
-          </Profiler>
-          </ScrollBar>
-          
+              <InnerGrid
+                containerPadding={rootContainerPadding}
+                overflow={rootContainerOverflow}
+                {...props}
+                positionParams={positionParams} // Added By Aqib Mirza
+                {...gridLayoutCanvasProps}
+                bgColor={bgColor}
+                radius="0px"
+              />
+            </Profiler>
+          {/*</ScrollBar> */}
         </div>
       </UICompContainer>
     );
diff --git a/client/packages/lowcoder/src/comps/comps/listViewComp/listViewPropertyView.tsx b/client/packages/lowcoder/src/comps/comps/listViewComp/listViewPropertyView.tsx
index 33d731a550..5d2c5dc0a8 100644
--- a/client/packages/lowcoder/src/comps/comps/listViewComp/listViewPropertyView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/listViewComp/listViewPropertyView.tsx
@@ -62,9 +62,11 @@ export function listPropertyView(compType: ListCompType) {
         {(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && (
           <><Section name={sectionNames.layout}>
               {children.autoHeight.getPropertyView()}
-              {children.scrollbars.propertyView({
-              label: trans("prop.scrollbar"),
-            })}
+              {!children.autoHeight.getView() && 
+                children.scrollbars.propertyView({
+                label: trans("prop.scrollbar"),
+               }  
+              )}
             </Section>
             <Section name={sectionNames.style}>
               {children.style.getPropertyView()}
diff --git a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx
index eea06d5695..d1d57401a7 100644
--- a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx
+++ b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx
@@ -1,7 +1,7 @@
 import { ContainerStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
 import { EditorContext } from "comps/editorState";
 import { BackgroundColorContext } from "comps/utils/backgroundColorContext";
-import { HintPlaceHolder } from "lowcoder-design";
+import { HintPlaceHolder, ScrollBar } from "lowcoder-design";
 import { ReactNode, useContext } from "react";
 import styled, { css } from "styled-components";
 import { checkIsMobile } from "util/commonUtils";
@@ -14,10 +14,7 @@ const getStyle = (style: ContainerStyleType) => {
     border-width: ${style.borderWidth};
     border-radius: ${style.radius};
     overflow: hidden;
-    // margin: ${style.margin};	
     padding: ${style.padding};	
-    // width: ${widthCalculator(style.margin)};	
-    // height: ${heightCalculator(style.margin)};
     ${style.background && `background-color: ${style.background};`}
     ${style.backgroundImage && `background-image: ${style.backgroundImage};`}
     ${style.backgroundImageRepeat && `background-repeat: ${style.backgroundImageRepeat};`}
@@ -107,6 +104,7 @@ export function TriContainer(props: TriContainerProps) {
   const { showHeader, showFooter } = container;
   // When the header and footer are not displayed, the body must be displayed
   const showBody = container.showBody || (!showHeader && !showFooter);
+  const scrollbars = container.scrollbars;
 
   const { items: headerItems, ...otherHeaderProps } = container.header;
   const { items: bodyItems, ...otherBodyProps } = container.body["0"].children.view.getView();
@@ -149,27 +147,52 @@ export function TriContainer(props: TriContainerProps) {
       )}
       {showBody && (
         <BackgroundColorContext.Provider value={bodyStyle.background}>
-          <BodyInnerGrid
-            $showBorder={showHeader}
-            {...otherBodyProps}
-            items={gridItemCompToGridItems(bodyItems)}
-            autoHeight={container.autoHeight}
-            emptyRows={14}
-            minHeight={showHeader ? "143px" : "142px"}
-            containerPadding={
-              (showHeader && showFooter) || showHeader ? [paddingWidth, 11.5] : [paddingWidth, 11]
-            }
-            hintPlaceholder={props.hintPlaceholder ?? HintPlaceHolder}
-            $backgroundColor={bodyStyle?.background || 'transparent'}
-            $borderColor={style?.border}
-            $borderWidth={style?.borderWidth}
-            $backgroundImage={bodyStyle?.backgroundImage}
-            $backgroundImageRepeat={bodyStyle?.backgroundImageRepeat}
-            $backgroundImageSize={bodyStyle?.backgroundImageSize}
-            $backgroundImagePosition={bodyStyle?.backgroundImagePosition}
-            $backgroundImageOrigin={bodyStyle?.backgroundImageOrigin}
-            style={{padding: bodyStyle.containerbodypadding}}
-          />
+          {scrollbars ? (
+            <ScrollBar style={{ height: container.autoHeight ? "auto" : "100%", margin: "0px", padding: "0px" }}>
+              <BodyInnerGrid
+                $showBorder={showHeader}
+                {...otherBodyProps}
+                items={gridItemCompToGridItems(bodyItems)}
+                autoHeight={container.autoHeight}
+                emptyRows={14}
+                minHeight={showHeader ? "143px" : "142px"}
+                containerPadding={
+                  (showHeader && showFooter) || showHeader ? [paddingWidth, 11.5] : [paddingWidth, 11]
+                }
+                hintPlaceholder={props.hintPlaceholder ?? HintPlaceHolder}
+                $backgroundColor={bodyStyle?.background || 'transparent'}
+                $borderColor={style?.border}
+                $borderWidth={style?.borderWidth}
+                $backgroundImage={bodyStyle?.backgroundImage}
+                $backgroundImageRepeat={bodyStyle?.backgroundImageRepeat}
+                $backgroundImageSize={bodyStyle?.backgroundImageSize}
+                $backgroundImagePosition={bodyStyle?.backgroundImagePosition}
+                $backgroundImageOrigin={bodyStyle?.backgroundImageOrigin}
+                style={{padding: bodyStyle.containerbodypadding}}
+              />
+            </ScrollBar>
+            ) : (
+            <BodyInnerGrid
+              $showBorder={showHeader}
+              {...otherBodyProps}
+              items={gridItemCompToGridItems(bodyItems)}
+              autoHeight={container.autoHeight}
+              emptyRows={14}
+              minHeight={showHeader ? "143px" : "142px"}
+              containerPadding={
+                (showHeader && showFooter) || showHeader ? [paddingWidth, 11.5] : [paddingWidth, 11]
+              }
+              hintPlaceholder={props.hintPlaceholder ?? HintPlaceHolder}
+              $backgroundColor={bodyStyle?.background || 'transparent'}
+              $borderColor={style?.border}
+              $borderWidth={style?.borderWidth}
+              $backgroundImage={bodyStyle?.backgroundImage}
+              $backgroundImageRepeat={bodyStyle?.backgroundImageRepeat}
+              $backgroundImageSize={bodyStyle?.backgroundImageSize}
+              $backgroundImagePosition={bodyStyle?.backgroundImagePosition}
+              $backgroundImageOrigin={bodyStyle?.backgroundImageOrigin}
+              style={{padding: bodyStyle.containerbodypadding}}/>
+          )}
         </BackgroundColorContext.Provider>
       )}
       {showFooter && (
diff --git a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx
index 87380c628e..26f8dea384 100644
--- a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx
@@ -39,7 +39,7 @@ const childrenMap = {
   showBody: BoolControl.DEFAULT_TRUE,
   showFooter: BoolControl,
   autoHeight: AutoHeightControl,
-
+  scrollbars: withDefault(BoolControl, false),
   style: styleControl(ContainerStyle),
   headerStyle: styleControl(ContainerHeaderStyle),
   bodyStyle: styleControl(ContainerBodyStyle),
@@ -55,6 +55,7 @@ const TriContainerBaseComp = migrateOldData(
 );
 
 export class TriContainerComp extends TriContainerBaseComp implements IContainer {
+  scrollbars: any;
   private allContainers() {
     return [
       this.children.header,
@@ -124,6 +125,7 @@ export class TriContainerComp extends TriContainerBaseComp implements IContainer
       this.children.showHeader.propertyView({ label: trans("prop.showHeader") }),
       this.children.showBody.propertyView({ label: trans("prop.showBody") }),
       this.children.showFooter.propertyView({ label: trans("prop.showFooter") }),
+      this.children.scrollbars.propertyView({ label: trans("prop.scrollbar") }),
     ];
   }
 

From 792c79b792650e8bd53c8bfcab732ba1ed551e40 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Sat, 17 Feb 2024 13:52:10 +0100
Subject: [PATCH 52/97] Fixing Scrollbar Property & Icon position for left menu
 tree

---
 .../src/comps/comps/triContainerComp/triContainerComp.tsx | 2 +-
 .../lowcoder/src/comps/controls/styleControlConstants.tsx | 8 +-------
 client/packages/lowcoder/src/pages/editor/LeftContent.tsx | 6 +++++-
 .../lowcoder/src/pages/editor/LeftLayersContent.tsx       | 2 +-
 4 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx
index 26f8dea384..c32ba3d2ed 100644
--- a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx
@@ -125,7 +125,7 @@ export class TriContainerComp extends TriContainerBaseComp implements IContainer
       this.children.showHeader.propertyView({ label: trans("prop.showHeader") }),
       this.children.showBody.propertyView({ label: trans("prop.showBody") }),
       this.children.showFooter.propertyView({ label: trans("prop.showFooter") }),
-      this.children.scrollbars.propertyView({ label: trans("prop.scrollbar") }),
+      (!this.children.autoHeight.getView()) && this.children.scrollbars.propertyView({ label: trans("prop.scrollbar") }),
     ];
   }
 
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index 5dea81d301..a9749121f2 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -506,17 +506,11 @@ export const MarginStyle = [
 export const ContainerStyle = [
   // ...BG_STATIC_BORDER_RADIUS,
   getStaticBorder(),
+  getBackground(),
   RADIUS,
   BORDER_WIDTH,
   MARGIN,	
   PADDING,
-  {
-    name: "background",
-    label: trans("style.background"),
-    depName: "background",
-    depType: DEP_TYPE.SELF,
-    transformer: toSelf,
-  },
   {
     name: "backgroundImage",
     label: trans("style.backgroundImage"),
diff --git a/client/packages/lowcoder/src/pages/editor/LeftContent.tsx b/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
index 5924d90bfe..8188685d1e 100644
--- a/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
+++ b/client/packages/lowcoder/src/pages/editor/LeftContent.tsx
@@ -435,7 +435,11 @@ export const LeftContent = (props: LeftContentProps) => {
       <DirectoryTreeStyle
         treeData={explorerData}
         // icon={(props: NodeItem) => props.type && (CompStateIcon[props.type] || <LeftCommon />)}
-        icon={(props: any) => props.type && (CompStateIcon[props.type as UICompType] || <LeftCommon />)}
+        icon={(props: any) => props.type && (
+          <div style={{ margin: '16px 4px 0 -4px'}}> 
+            {CompStateIcon[props.type as UICompType] || <LeftCommon />}
+          </div>
+        )}
         // switcherIcon={({ expanded }: { expanded: boolean }) =>
         //   expanded ? <FoldedIcon /> : <UnfoldIcon />
         // }
diff --git a/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx b/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
index 9fd7e68045..93a66fc44c 100644
--- a/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
+++ b/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx
@@ -458,7 +458,7 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => {
           onDrop={(info) => handleDrop(info)}
           treeData={componentTreeData}
           icon={(props: any) => props.type && (
-            <div style={{ margin: '3px 4px 0 -4px'}}> {/* Adjust the margin as needed */}
+            <div style={{ margin: '3px 4px 0 -4px'}}> 
               {CompStateIcon[props.type as UICompType] || <LeftCommon />}
             </div>
           )}

From 0886f58f394e2d7c1bdd5dc8a1bf2058fff5ecfd Mon Sep 17 00:00:00 2001
From: Imtanan Aziz Toor <imtanan.aziz@ikhwatech.com>
Date: Sat, 17 Feb 2024 23:32:19 +0500
Subject: [PATCH 53/97] Controls added to divider, button comp, dropdown, nav
 ,link & mention componente

---
 .../comps/buttonComp/buttonCompConstants.tsx  |  1 +
 .../comps/comps/buttonComp/dropdownComp.tsx   |  5 +++
 .../src/comps/comps/buttonComp/linkComp.tsx   |  4 +++
 .../lowcoder/src/comps/comps/dividerComp.tsx  | 15 ++++-----
 .../src/comps/comps/navComp/navComp.tsx       | 31 ++++++++++++++-----
 .../comps/comps/textInputComp/mentionComp.tsx | 16 +++++-----
 .../comps/controls/styleControlConstants.tsx  | 21 ++++++++++++-
 7 files changed, 70 insertions(+), 23 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/buttonCompConstants.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/buttonCompConstants.tsx
index 7114a019b0..0f60c7a2d2 100644
--- a/client/packages/lowcoder/src/comps/comps/buttonComp/buttonCompConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/buttonComp/buttonCompConstants.tsx
@@ -22,6 +22,7 @@ export function getButtonStyle(buttonStyle: ButtonStyleType) {
         font-size: ${buttonStyle.textSize};
         font-weight: ${buttonStyle.textWeight};
         font-family: ${buttonStyle.fontFamily};
+        font-style: ${buttonStyle.fontStyle};
         background-color: ${buttonStyle.background};
         border-radius: ${buttonStyle.radius};
         margin: ${buttonStyle.margin};	
diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/dropdownComp.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/dropdownComp.tsx
index f58b39bd6b..7c2278d7bd 100644
--- a/client/packages/lowcoder/src/comps/comps/buttonComp/dropdownComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/buttonComp/dropdownComp.tsx
@@ -42,6 +42,11 @@ const LeftButtonWrapper = styled.div<{ $buttonStyle: ButtonStyleType }>`
       margin: 0 !important;
       ${(props) => `border-radius: ${props.$buttonStyle.radius} 0 0 ${props.$buttonStyle.radius};`}
     }
+    ${(props) => `background-color: ${props.$buttonStyle.background};`}
+    ${(props) => `color: ${props.$buttonStyle.text};`}
+    ${(props) => `padding: ${props.$buttonStyle.padding};`}
+    ${(props) => `font-size: ${props.$buttonStyle.textSize};`}
+    ${(props) => `font-style: ${props.$buttonStyle.fontStyle};`}
     width: 100%;
   }
 `;
diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx
index 275b125b31..65b288bacb 100644
--- a/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx
@@ -29,6 +29,10 @@ const Link = styled(Button)<{ $style: LinkStyleType }>`
     margin: ${props.$style.margin};
     padding: ${props.$style.padding};
     font-size: ${props.$style.textSize};
+    font-style:${props.$style.fontStyle};
+    font-family:${props.$style.fontFamily};
+    border: ${props.$style.borderWidth} solid ${props.$style.border};
+    background-color: ${props.$style.background};
     &:hover {
       color: ${props.$style.hoverText} !important;
     }
diff --git a/client/packages/lowcoder/src/comps/comps/dividerComp.tsx b/client/packages/lowcoder/src/comps/comps/dividerComp.tsx
index e830a6f41c..032807de2e 100644
--- a/client/packages/lowcoder/src/comps/comps/dividerComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/dividerComp.tsx
@@ -21,7 +21,7 @@ type IProps = DividerProps & { $style: DividerStyleType; dashed: boolean };
 // TODO: find out how to set border style when text is active
 // TODO: enable type "vertical" https://ant.design/components/divider
 
-const StyledDivider = styled(Divider)<IProps>`
+const StyledDivider = styled(Divider) <IProps>`
   margin-top: 3.5px;
   .ant-divider-inner-text {
     height: 32px;
@@ -30,16 +30,17 @@ const StyledDivider = styled(Divider)<IProps>`
     font-size: ${(props) => props.$style.textSize};
     font-weight: ${(props) => props.$style.textWeight};
     font-family: ${(props) => props.$style.fontFamily};
+    font-style:${(props) => props.$style.fontStyle}
   }
   min-width: 0;	
-  width: ${(props) => {	
-    return widthCalculator(props.$style.margin);	
+  width: ${(props) => {
+    return widthCalculator(props.$style.margin);
   }};	
-  min-height: ${(props) => {	
-    return heightCalculator(props.$style.margin);	
+  min-height: ${(props) => {
+    return heightCalculator(props.$style.margin);
   }};	
-  margin: ${(props) => {	
-    return props.$style.margin;	
+  margin: ${(props) => {
+    return props.$style.margin;
   }};	
   padding: ${(props) => props.$style.padding};
   
diff --git a/client/packages/lowcoder/src/comps/comps/navComp/navComp.tsx b/client/packages/lowcoder/src/comps/comps/navComp/navComp.tsx
index fb6d4609b6..c5eedea6f7 100644
--- a/client/packages/lowcoder/src/comps/comps/navComp/navComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/navComp/navComp.tsx
@@ -23,17 +23,18 @@ type IProps = {
   $justify: boolean;
   $bgColor: string;
   $borderColor: string;
+  $borderWidth: string;
 };
 
-const Wrapper = styled("div")<Pick<IProps, "$bgColor" | "$borderColor">>`
+const Wrapper = styled("div") <Pick<IProps, "$bgColor" | "$borderColor" | "$borderWidth">>`
   height: 100%;
   border-radius: 2px;
   box-sizing: border-box;
-  border: 1px solid ${(props) => props.$borderColor};
+  border: ${(props) => props.$borderWidth ? `${props.$borderWidth}` : '1px'} solid ${(props) => props.$borderColor};
   background-color: ${(props) => props.$bgColor};
 `;
 
-const NavInner = styled("div")<Pick<IProps, "$justify">>`
+const NavInner = styled("div") <Pick<IProps, "$justify">>`
   margin: 0 -16px;
   height: 100%;
   display: flex;
@@ -44,12 +45,20 @@ const Item = styled.div<{
   $active: boolean;
   $activeColor: string;
   $color: string;
+  $fontFamily: string;
+  $fontStyle: string;
+  $textWeight: string;
+  $textSize: string;
 }>`
   height: 30px;
   line-height: 30px;
   padding: 0 16px;
   color: ${(props) => (props.$active ? props.$activeColor : props.$color)};
-  font-weight: 500;
+  font-weight: ${(props) => (props.$textWeight ? props.$textWeight : 500)};
+  font-family:${(props) => (props.$fontFamily ? props.$fontFamily : 'sans-serif')};
+  font-style:${(props) => (props.$fontStyle ? props.$fontStyle : 'normal')};
+  font-size:${(props) => (props.$textSize ? props.$textSize : '14px')}
+
 
   &:hover {
     color: ${(props) => props.$activeColor};
@@ -79,7 +88,7 @@ const ItemList = styled.div<{ $align: string }>`
   justify-content: ${(props) => props.$align};
 `;
 
-const StyledMenu = styled(Menu)<MenuProps>`
+const StyledMenu = styled(Menu) <MenuProps>`
   &.ant-dropdown-menu {
     min-width: 160px;
   }
@@ -144,6 +153,10 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
             $active={active || subMenuSelectedKeys.length > 0}
             $color={props.style.text}
             $activeColor={props.style.accent}
+            $fontFamily={props.style.fontFamily}
+            $fontStyle={props.style.fontStyle}
+            $textWeight={props.style.textWeight}
+            $textSize={props.style.textSize}
             onClick={() => onEvent("click")}
           >
             {label}
@@ -178,7 +191,11 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
   const justify = props.horizontalAlignment === "justify";
 
   return (
-    <Wrapper $borderColor={props.style.border} $bgColor={props.style.background}>
+    <Wrapper
+      $borderColor={props.style.border}
+      $bgColor={props.style.background}
+      $borderWidth={props.style.borderWidth}
+    >
       <NavInner $justify={justify}>
         {props.logoUrl && (
           <LogoWrapper onClick={() => props.logoEvent("click")}>
@@ -220,7 +237,7 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
           </Section>
         )}
 
-        {(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && (  
+        {(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && (
           <Section name={sectionNames.style}>
             {children.style.getPropertyView()}
           </Section>
diff --git a/client/packages/lowcoder/src/comps/comps/textInputComp/mentionComp.tsx b/client/packages/lowcoder/src/comps/comps/textInputComp/mentionComp.tsx
index 630f7e376e..28051a0676 100644
--- a/client/packages/lowcoder/src/comps/comps/textInputComp/mentionComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/textInputComp/mentionComp.tsx
@@ -101,7 +101,7 @@ let MentionTmpComp = (function () {
     const [activationFlag, setActivationFlag] = useState(false);
     const [prefix, setPrefix] = useState<PrefixType>("@");
     type PrefixType = "@" | keyof typeof mentionList;
-    
+
     const onSearch = (_: string, newPrefix: PrefixType) => {
       setPrefix(newPrefix);
     };
@@ -192,7 +192,7 @@ let MentionTmpComp = (function () {
                 label: value,
               }))}
               autoSize={props.autoHeight}
-              style={{ height: "100%", maxHeight: "100%", resize: "none", padding: props.style.padding }}
+              style={{ height: "100%", maxHeight: "100%", resize: "none", padding: props.style.padding, fontStyle: props.style.fontStyle, fontFamily: props.style.fontFamily, borderWidth: props.style.borderWidth, fontWeight: props.style.textWeight }}
               readOnly={props.readOnly}
             />
           </ConfigProvider>
@@ -222,12 +222,12 @@ let MentionTmpComp = (function () {
         )}
 
         {["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && (
-        <><Section name={sectionNames.interaction}>
+          <><Section name={sectionNames.interaction}>
             {children.onEvent.getPropertyView()}
             {disabledPropertyView(children)}
           </Section>
-          <Section name={sectionNames.layout}>{hiddenPropertyView(children)}</Section>
-          <Section name={sectionNames.advanced}>
+            <Section name={sectionNames.layout}>{hiddenPropertyView(children)}</Section>
+            <Section name={sectionNames.advanced}>
               {readOnlyPropertyView(children)}
             </Section><Section name={sectionNames.validation}>
               {requiredPropertyView(children)}
@@ -241,9 +241,9 @@ let MentionTmpComp = (function () {
         )}
 
         {["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && (
-        <><Section name={sectionNames.style}>
-              {children.style.getPropertyView()}
-            </Section></>
+          <><Section name={sectionNames.style}>
+            {children.style.getPropertyView()}
+          </Section></>
         )}
       </>
     ))
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index c01fc0d0b6..86189ba5a3 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -455,6 +455,7 @@ export const ButtonStyle = [
   TEXT_SIZE,
   TEXT_WEIGHT,
   FONT_FAMILY,
+  FONT_STYLE,
   MARGIN,
   PADDING
 ] as const;
@@ -474,6 +475,7 @@ export const ToggleButtonStyle = [
   TEXT_SIZE,
   TEXT_WEIGHT,
   FONT_FAMILY,
+  FONT_STYLE,
   MARGIN,
   PADDING,
 ] as const;
@@ -1045,8 +1047,19 @@ function handleToHoverLink(color: string) {
 
 export const LinkStyle = [
   ...LinkTextStyle,
+  {
+    name: "background",
+    label: trans("style.background"),
+    depTheme: "canvas",
+    depType: DEP_TYPE.SELF,
+    transformer: toSelf,
+  },
   MARGIN,
   PADDING,
+  FONT_FAMILY,
+  FONT_STYLE,
+  BORDER,
+  BORDER_WIDTH,
   TEXT_SIZE
 ] as const;
 
@@ -1067,7 +1080,8 @@ export const DividerStyle = [
   },
   TEXT_SIZE,
   TEXT_WEIGHT,
-  FONT_FAMILY
+  FONT_FAMILY,
+  FONT_STYLE
 ] as const;
 
 export const ProgressStyle = [
@@ -1098,6 +1112,11 @@ export const NavigationStyle = [
   getStaticBorder("#FFFFFF00"),
   MARGIN,
   PADDING,
+  FONT_FAMILY,
+  FONT_STYLE,
+  TEXT_WEIGHT,
+  TEXT_SIZE,
+  BORDER_WIDTH
 ] as const;
 
 export const ImageStyle = [getStaticBorder("#00000000"), RADIUS, BORDER_WIDTH, MARGIN, PADDING] as const;

From effe7d4914a29790311d5b9cda9dd09956f5c801 Mon Sep 17 00:00:00 2001
From: Yofriadi Yahya <yofriadi.yahya@pinhome.id>
Date: Sun, 18 Feb 2024 12:03:53 +0700
Subject: [PATCH 54/97] Remove .DS_Store file and duplicate in .gitignore

---
 .DS_Store  | Bin 8196 -> 0 bytes
 .gitignore |   2 --
 2 files changed, 2 deletions(-)
 delete mode 100644 .DS_Store

diff --git a/.DS_Store b/.DS_Store
deleted file mode 100644
index 096f7b6bab0cc84fb460c538fd2ed1661d4df09f..0000000000000000000000000000000000000000
GIT binary patch
diff --git a/.gitignore b/.gitignore
index 697f85552a..2e1b56cd59 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,5 +9,3 @@ client/node_modules/
 client/packages/lowcoder-plugin-demo/.yarn/install-state.gz
 client/packages/lowcoder-plugin-demo/yarn.lock
 client/packages/lowcoder-plugin-demo/.yarn/cache/@types-node-npm-16.18.68-56f72825c0-094ae9ed80.zip
-.DS_Store
-.DS_Store

From e77d06357b04a8071eac2babee214c9bc4dceb28 Mon Sep 17 00:00:00 2001
From: freddysundowner <githumbi3fred@gmail.com>
Date: Mon, 19 Feb 2024 12:45:20 +0300
Subject: [PATCH 55/97] fixed auto complete resize issue

---
 .../comps/autoCompleteComp/autoCompleteComp.tsx     | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/autoCompleteComp/autoCompleteComp.tsx b/client/packages/lowcoder/src/comps/comps/autoCompleteComp/autoCompleteComp.tsx
index 1101fc6d28..059dd38521 100644
--- a/client/packages/lowcoder/src/comps/comps/autoCompleteComp/autoCompleteComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/autoCompleteComp/autoCompleteComp.tsx
@@ -162,19 +162,20 @@ let AutoCompleteCompBase = (function () {
               },
             }}
           >
-            <AutoComplete
+            <AutoComplete 
               disabled={props.disabled}
               value={searchtext}
-              options={items}
+              options={items} 
+              style={{ width: "100%" }}
               onChange={(value: string, option) => {
                 props.valueInItems.onChange(false);
                 setvalidateState(textInputValidate(getTextInputValidate()));
                 setsearchtext(value);
                 props.value.onChange(value); 
                 props.onEvent("change")
-              }}
+              }} 
               onFocus={() => {
-                setActivationFlag(true)
+                setActivationFlag(true) 
                 props.onEvent("focus")
               }}
               onBlur={() => props.onEvent("blur")}
@@ -275,8 +276,8 @@ let AutoCompleteCompBase = (function () {
           </ConfigProvider>
         </>
       ),
-      style: props.style,
-      ...validateState,
+      // style: props.style,
+      // ...validateState,
     });
   })
     .setPropertyViewFn((children) => {

From 18959b99ccdde7327fbcb4f1be34fb8ef85ebfe0 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Mon, 19 Feb 2024 12:59:05 +0100
Subject: [PATCH 56/97] Change wording for Layers

---
 client/packages/lowcoder/src/i18n/locales/en.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index 7a8c342109..74b2296b9b 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -106,7 +106,7 @@ export const en = {
     "expandTip": "Click to Expand {component}'s Data",
     "collapseTip": "Click to Collapse {component}'s Data",
     "layers": "Layers",
-    "activatelayers": "Use Layers in this App",
+    "activatelayers": "Use dynamic Layers",
     "selectedComponents": "Selected Components...",
     "displayComponents": "control Display",
     "lockComponents": "control Position",

From 91b470f8cf2bf9e93cfc99f426a50b14a071b027 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Mon, 19 Feb 2024 18:58:47 +0500
Subject: [PATCH 57/97] fix layers zIndex issue

---
 client/packages/lowcoder/src/comps/utils/gridCompOperator.ts | 1 +
 client/packages/lowcoder/src/layout/gridLayout.tsx           | 5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/utils/gridCompOperator.ts b/client/packages/lowcoder/src/comps/utils/gridCompOperator.ts
index 4279ed654b..828b8f286f 100644
--- a/client/packages/lowcoder/src/comps/utils/gridCompOperator.ts
+++ b/client/packages/lowcoder/src/comps/utils/gridCompOperator.ts
@@ -173,6 +173,7 @@ export class GridCompOperator {
       this.doDelete(editorState, compRecords) &&
       messageInstance.info(trans("gridCompOperator.deleteCompsSuccess", { undoKey }));
     };
+
     if (compNum > 1) {
       CustomModal.confirm({
         title: trans("gridCompOperator.deleteCompsTitle"),
diff --git a/client/packages/lowcoder/src/layout/gridLayout.tsx b/client/packages/lowcoder/src/layout/gridLayout.tsx
index 0058ff71f2..6b697c0c0c 100644
--- a/client/packages/lowcoder/src/layout/gridLayout.tsx
+++ b/client/packages/lowcoder/src/layout/gridLayout.tsx
@@ -1003,6 +1003,7 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
 
     // log.debug("GridLayout render. layout: ", layout, " oriLayout: ", this.state.layout, " extraLayout: ", this.props.extraLayout);
     const layouts = Object.values(layout);
+    const maxLayoutPos = Math.max(...layouts.map(l => l.pos || 0))
     return (
       <LayoutContainer
         ref={this.ref}
@@ -1027,10 +1028,10 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
         >
           <div style={contentStyle}>
             {showGridLines && this.gridLines()}
-            {mounted &&
+            {mounted && 
               layouts.map((item) => {
                 const zIndex = item.pos !== undefined
-                  ? layouts.length - item.pos
+                  ? (maxLayoutPos - item.pos) + 1
                   : 1;
                 return this.processGridItem(zIndex, item, childrenMap)
               })

From 7cb3164970474b6737452dfc1c21f8676a9c8e2d Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Mon, 19 Feb 2024 21:22:20 +0100
Subject: [PATCH 58/97] Fix Modal Closing Button

---
 client/packages/lowcoder/src/comps/hooks/modalComp.tsx | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/client/packages/lowcoder/src/comps/hooks/modalComp.tsx b/client/packages/lowcoder/src/comps/hooks/modalComp.tsx
index 49139eb393..96f0055ae3 100644
--- a/client/packages/lowcoder/src/comps/hooks/modalComp.tsx
+++ b/client/packages/lowcoder/src/comps/hooks/modalComp.tsx
@@ -46,6 +46,9 @@ const getStyle = (style: ModalStyleType) => {
         background-color: ${style.background};
       }
     }
+    .ant-modal-close {
+      inset-inline-end: 7px !important;
+    }
   `;
 };
 

From 5c1ef4d5d57e610de449a1848d619c08509fe0ab Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Tue, 20 Feb 2024 16:37:17 +0500
Subject: [PATCH 59/97] added api_usage endpoint

---
 client/packages/lowcoder/src/api/orgApi.ts    |  9 +++++++
 .../src/constants/reduxActionConstants.ts     |  2 ++
 .../lowcoder/src/pages/setting/index.tsx      | 10 ++++++++
 .../redux/reducers/uiReducers/orgReducer.ts   | 10 ++++++++
 .../src/redux/reduxActions/orgActions.ts      | 22 ++++++++++++++++
 .../lowcoder/src/redux/sagas/orgSagas.ts      | 25 ++++++++++++++++++-
 .../src/redux/selectors/orgSelectors.ts       |  4 +++
 7 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/client/packages/lowcoder/src/api/orgApi.ts b/client/packages/lowcoder/src/api/orgApi.ts
index 31ed40e583..7c1396a391 100644
--- a/client/packages/lowcoder/src/api/orgApi.ts
+++ b/client/packages/lowcoder/src/api/orgApi.ts
@@ -29,6 +29,10 @@ export interface CreateOrgResponse extends ApiResponse {
   data: { orgId: string };
 }
 
+export interface OrgAPIUsageResponse extends ApiResponse {
+  data: number;
+}
+
 export class OrgApi extends Api {
   static createGroupURL = "/v1/groups";
   static updateGroupURL = (groupId: string) => `/v1/groups/${groupId}/update`;
@@ -47,6 +51,7 @@ export class OrgApi extends Api {
   static createOrgURL = "/v1/organizations";
   static deleteOrgURL = (orgId: string) => `/v1/organizations/${orgId}`;
   static updateOrgURL = (orgId: string) => `/v1/organizations/${orgId}/update`;
+  static fetchUsage = (orgId: string) => `/v1/organizations/${orgId}/api-usage`;
 
   static createGroup(request: { name: string }): AxiosPromise<GenericApiResponse<OrgGroup>> {
     return Api.post(OrgApi.createGroupURL, request);
@@ -127,6 +132,10 @@ export class OrgApi extends Api {
   static updateOrg(request: UpdateOrgPayload): AxiosPromise<ApiResponse> {
     return Api.put(OrgApi.updateOrgURL(request.id), request);
   }
+
+  static fetchAPIUsage(orgId: string, lastMonthOnly?: boolean): AxiosPromise<ApiResponse> {
+    return Api.get(OrgApi.fetchUsage(orgId), lastMonthOnly);
+  }
 }
 
 export default OrgApi;
diff --git a/client/packages/lowcoder/src/constants/reduxActionConstants.ts b/client/packages/lowcoder/src/constants/reduxActionConstants.ts
index 7b2b284428..fdf34040b3 100644
--- a/client/packages/lowcoder/src/constants/reduxActionConstants.ts
+++ b/client/packages/lowcoder/src/constants/reduxActionConstants.ts
@@ -100,6 +100,8 @@ export const ReduxActionTypes = {
   UPDATE_USER_PROFILE_SUCCESS: "UPDATE_USER_PROFILE_SUCCESS",
   UPLOAD_USER_HEAD_SUCCESS: "UPLOAD_USER_HEAD_SUCCESS", // update avatar
   MARK_USER_STATUS: "MARK_USER_STATUS",
+  FETCH_ORG_API_USAGE: "FETCH_ORG_API_USAGE",
+  FETCH_ORG_API_USAGE_SUCCESS: "FETCH_ORG_API_USAGE_SUCCESS",
 
   /* home data */
   FETCH_HOME_DATA: "FETCH_HOME_DATA",
diff --git a/client/packages/lowcoder/src/pages/setting/index.tsx b/client/packages/lowcoder/src/pages/setting/index.tsx
index e77bb14501..9cfa2b235b 100644
--- a/client/packages/lowcoder/src/pages/setting/index.tsx
+++ b/client/packages/lowcoder/src/pages/setting/index.tsx
@@ -8,6 +8,16 @@ import SettingHome from "./settingHome";
 
 export function Setting() {
   const user = useSelector(getUser);
+
+  /* fetch Org's API usage
+
+  const apiUsage = useSelector(getOrgApiUsage);
+  useEffect(() => {
+    dispatch(fetchAPIUsageAction(user.currentOrgId));
+  }, [user.currentOrgId])
+
+  */
+
   if (!currentOrgAdminOrDev(user)) {
     history.push(BASE_URL);
   }
diff --git a/client/packages/lowcoder/src/redux/reducers/uiReducers/orgReducer.ts b/client/packages/lowcoder/src/redux/reducers/uiReducers/orgReducer.ts
index 2d35b7e0c4..f020cf99f1 100644
--- a/client/packages/lowcoder/src/redux/reducers/uiReducers/orgReducer.ts
+++ b/client/packages/lowcoder/src/redux/reducers/uiReducers/orgReducer.ts
@@ -8,6 +8,7 @@ import { User } from "constants/userConstants";
 import {
   DeleteOrgUserPayload,
   GroupUsersPayload,
+  OrgAPIUsagePayload,
   OrgUsersPayload,
   RemoveGroupUserPayload,
 } from "redux/reduxActions/orgActions";
@@ -24,6 +25,7 @@ const initialState: OrgReduxState = {
   groupUsersFetching: true,
   fetchOrgGroupsFinished: false,
   orgCreateStatus: "init",
+  apiUsage: 0,
 };
 
 const orgReducer = createImmerReducer(initialState, {
@@ -104,6 +106,13 @@ const orgReducer = createImmerReducer(initialState, {
     ...state,
     orgCreateStatus: "error",
   }),
+  [ReduxActionTypes.FETCH_ORG_API_USAGE_SUCCESS]: (
+    state: OrgReduxState,
+    action: ReduxAction<OrgAPIUsagePayload>
+  ): OrgReduxState => ({
+    ...state,
+    apiUsage: action.payload.apiUsage,
+  })
 });
 
 export interface OrgReduxState {
@@ -115,6 +124,7 @@ export interface OrgReduxState {
   groupUsersFetching: boolean;
   fetchOrgGroupsFinished: boolean;
   orgCreateStatus: ApiRequestStatus;
+  apiUsage: number;
 }
 
 export default orgReducer;
diff --git a/client/packages/lowcoder/src/redux/reduxActions/orgActions.ts b/client/packages/lowcoder/src/redux/reduxActions/orgActions.ts
index d7326c1d7a..9d2f3eb6ac 100644
--- a/client/packages/lowcoder/src/redux/reduxActions/orgActions.ts
+++ b/client/packages/lowcoder/src/redux/reduxActions/orgActions.ts
@@ -151,3 +151,25 @@ export const updateOrgSuccess = (payload: UpdateOrgPayload) => {
     payload: payload,
   };
 };
+
+export type OrgAPIUsagePayload = {
+  apiUsage: number,
+};
+
+export const fetchAPIUsageAction = (
+  orgId: string,
+  lastMonthOnly?: boolean,
+) => ({
+  type: ReduxActionTypes.FETCH_ORG_API_USAGE,
+  payload: {
+    orgId,
+    lastMonthOnly,
+  },
+});
+
+export const fetchAPIUsageSuccessAction = (apiUsage: number) => ({
+  type: ReduxActionTypes.FETCH_ORG_API_USAGE_SUCCESS,
+  payload: {
+    apiUsage,
+  },
+});
diff --git a/client/packages/lowcoder/src/redux/sagas/orgSagas.ts b/client/packages/lowcoder/src/redux/sagas/orgSagas.ts
index 8835a2f3f4..f1604241de 100644
--- a/client/packages/lowcoder/src/redux/sagas/orgSagas.ts
+++ b/client/packages/lowcoder/src/redux/sagas/orgSagas.ts
@@ -1,7 +1,7 @@
 import { messageInstance } from "lowcoder-design";
 
 import { ApiResponse, GenericApiResponse } from "api/apiResponses";
-import OrgApi, { CreateOrgResponse, GroupUsersResponse, OrgUsersResponse } from "api/orgApi";
+import OrgApi, { CreateOrgResponse, GroupUsersResponse, OrgAPIUsageResponse, OrgUsersResponse } from "api/orgApi";
 import { AxiosResponse } from "axios";
 import { OrgGroup } from "constants/orgConstants";
 import {
@@ -280,6 +280,28 @@ export function* updateOrgSaga(action: ReduxAction<UpdateOrgPayload>) {
   }
 }
 
+export function* fetchAPIUsageSaga(action: ReduxAction<{
+  orgId: string,
+  lastMonthOnly?: boolean,
+}>) {
+  try {
+    const response: AxiosResponse<OrgAPIUsageResponse> = yield call(
+      OrgApi.fetchAPIUsage,
+      action.payload.orgId,
+      action.payload.lastMonthOnly,
+    );
+    const isValidResponse: boolean = validateResponse(response);
+    if (isValidResponse) {
+      yield put({
+        type: ReduxActionTypes.FETCH_ORG_API_USAGE_SUCCESS,
+        payload: response.data.data,
+      });
+    }
+  } catch (error) {
+    log.error(error);
+  }
+}
+
 export default function* orgSagas() {
   yield all([
     takeLatest(ReduxActionTypes.UPDATE_GROUP_INFO, updateGroupSaga),
@@ -297,5 +319,6 @@ export default function* orgSagas() {
     takeLatest(ReduxActionTypes.CREATE_ORG, createOrgSaga),
     takeLatest(ReduxActionTypes.DELETE_ORG, deleteOrgSaga),
     takeLatest(ReduxActionTypes.UPDATE_ORG, updateOrgSaga),
+    takeLatest(ReduxActionTypes.FETCH_ORG_API_USAGE, fetchAPIUsageSaga),
   ]);
 }
diff --git a/client/packages/lowcoder/src/redux/selectors/orgSelectors.ts b/client/packages/lowcoder/src/redux/selectors/orgSelectors.ts
index 281ff138b1..8ea9aa3ec0 100644
--- a/client/packages/lowcoder/src/redux/selectors/orgSelectors.ts
+++ b/client/packages/lowcoder/src/redux/selectors/orgSelectors.ts
@@ -15,3 +15,7 @@ export const getFetchOrgGroupsFinished = (state: AppState) => {
 export const getOrgCreateStatus = (state: AppState) => {
   return state.ui.org.orgCreateStatus;
 };
+
+export const getOrgApiUsage = (state: AppState) => {
+  return state.ui.org.apiUsage;
+}

From 5a4e1c4f22c8312db7ada1ebbfb7fae290510d1a Mon Sep 17 00:00:00 2001
From: Imtanan Aziz Toor <imtanan.aziz@ikhwatech.com>
Date: Tue, 20 Feb 2024 17:50:59 +0500
Subject: [PATCH 60/97] Common style config added, number input component
 updated, link component fixes

---
 .../src/comps/comps/buttonComp/linkComp.tsx   |  17 +--
 .../comps/numberInputComp/numberInputComp.tsx |  25 ++--
 .../comps/controls/styleControlConstants.tsx  | 114 ++++++++----------
 3 files changed, 75 insertions(+), 81 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx
index 65b288bacb..1d41ad3345 100644
--- a/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx
@@ -23,7 +23,7 @@ import { RefControl } from "comps/controls/refControl";
 import { EditorContext } from "comps/editorState";
 import React, { useContext } from "react";
 
-const Link = styled(Button)<{ $style: LinkStyleType }>`
+const Link = styled(Button) <{ $style: LinkStyleType }>`
   ${(props) => `
     color: ${props.$style.text};
     margin: ${props.$style.margin};
@@ -31,6 +31,7 @@ const Link = styled(Button)<{ $style: LinkStyleType }>`
     font-size: ${props.$style.textSize};
     font-style:${props.$style.fontStyle};
     font-family:${props.$style.fontFamily};
+    font-weight:${props.$style.textWeight};
     border: ${props.$style.borderWidth} solid ${props.$style.border};
     background-color: ${props.$style.background};
     &:hover {
@@ -118,15 +119,15 @@ const LinkTmpComp = (function () {
               {hiddenPropertyView(children)}
               {loadingPropertyView(children)}
             </Section>
-            <Section name={sectionNames.advanced}>
-              {children.prefixIcon.propertyView({ label: trans("button.prefixIcon") })}
-              {children.suffixIcon.propertyView({ label: trans("button.suffixIcon") })}
-            </Section></>
+              <Section name={sectionNames.advanced}>
+                {children.prefixIcon.propertyView({ label: trans("button.prefixIcon") })}
+                {children.suffixIcon.propertyView({ label: trans("button.suffixIcon") })}
+              </Section></>
           )}
 
-        {(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && (
-          <><Section name={sectionNames.style}>{children.style.getPropertyView()}</Section></>
-        )}
+          {(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && (
+            <><Section name={sectionNames.style}>{children.style.getPropertyView()}</Section></>
+          )}
         </>
       );
     })
diff --git a/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx b/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx
index f1c917521b..26fb581692 100644
--- a/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx
@@ -56,6 +56,7 @@ import { EditorContext } from "comps/editorState";
 const getStyle = (style: InputLikeStyleType) => {
   return css`
     border-radius: ${style.radius};
+    border-width:${style.borderWidth} !important;
     // still use antd style when disabled
     &:not(.ant-input-number-disabled) {
       color: ${style.text};
@@ -78,11 +79,17 @@ const getStyle = (style: InputLikeStyleType) => {
       }
       .ant-input-number {	
         margin: 0;	
+        
       }	
-      .ant-input-number input {	
+      .ant-input-number-input {	
         margin: 0;	
         padding: ${style.padding};	
         height: ${heightCalculator(style.margin)};	
+        color:${style.text};
+        font-family:${style.fontFamily} !important;
+        font-weight:${style.textWeight} !important;
+        font-size:${style.textSize} !important;
+        font-style:${style.fontStyle} !important;
       }
 
       .ant-input-number-handler-wrap {
@@ -110,7 +117,7 @@ const getStyle = (style: InputLikeStyleType) => {
   `;
 };
 
-const InputNumber = styled(AntdInputNumber)<{
+const InputNumber = styled(AntdInputNumber) <{
   $style: InputLikeStyleType;
 }>`
   width: 100%;
@@ -377,15 +384,15 @@ const NumberInputTmpComp = (function () {
             {children.max.propertyView({ label: trans("prop.maximum") })}
             {children.customRule.propertyView({})}
           </Section>
-          <Section name={sectionNames.interaction}>
-            {children.onEvent.getPropertyView()}
-            {disabledPropertyView(children)}
-            {hiddenPropertyView(children)}
-          </Section>
+            <Section name={sectionNames.interaction}>
+              {children.onEvent.getPropertyView()}
+              {disabledPropertyView(children)}
+              {hiddenPropertyView(children)}
+            </Section>
           </>
         )}
- 
-        {(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && ( 
+
+        {(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && (
           children.label.getPropertyView()
         )}
 
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index 86189ba5a3..347c7ede3d 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -397,6 +397,18 @@ const HEADER_BACKGROUND = {
 } as const;
 
 const BG_STATIC_BORDER_RADIUS = [getBackground(), getStaticBorder(), RADIUS] as const;
+const STYLING_FIELDS_SEQUENCE = [
+  TEXT,
+  TEXT_SIZE,
+  TEXT_WEIGHT,
+  FONT_FAMILY,
+  FONT_STYLE,
+  BORDER,
+  MARGIN,
+  PADDING,
+  RADIUS,
+  BORDER_WIDTH,
+]
 
 const FILL = {
   name: "fill",
@@ -450,34 +462,23 @@ function getStaticBackground(color: string) {
 
 export const ButtonStyle = [
   ...getBgBorderRadiusByBg("primary"),
-  BORDER_WIDTH,
-  TEXT,
-  TEXT_SIZE,
-  TEXT_WEIGHT,
-  FONT_FAMILY,
-  FONT_STYLE,
-  MARGIN,
-  PADDING
+  ...STYLING_FIELDS_SEQUENCE
 ] as const;
 
 export const ToggleButtonStyle = [
   getBackground("canvas"),
-  {
-    name: "border",
-    label: trans("style.border"),
-    depName: "text",
-    depType: DEP_TYPE.SELF,
-    transformer: toSelf,
-  },
-  RADIUS,
-  BORDER_WIDTH,
-  TEXT,
-  TEXT_SIZE,
-  TEXT_WEIGHT,
-  FONT_FAMILY,
-  FONT_STYLE,
-  MARGIN,
-  PADDING,
+  ...STYLING_FIELDS_SEQUENCE.map((style) => {
+    if (style.name === 'border') {
+      return {
+        ...style,
+        depType: DEP_TYPE.SELF,
+        transformer: toSelf
+      }
+    }
+    return {
+      ...style
+    }
+  })
 ] as const;
 
 export const TextStyle = [
@@ -488,14 +489,7 @@ export const TextStyle = [
     depType: DEP_TYPE.SELF,
     transformer: toSelf,
   },
-  TEXT,
-  TEXT_SIZE,
-  TEXT_WEIGHT,
-  FONT_FAMILY,
-  FONT_STYLE,
-  BORDER,
-  MARGIN,
-  PADDING,
+  ...STYLING_FIELDS_SEQUENCE,
   {
     name: "links",
     label: trans("style.links"),
@@ -503,8 +497,6 @@ export const TextStyle = [
     depType: DEP_TYPE.SELF,
     transformer: toSelf,
   },
-  RADIUS,
-  BORDER_WIDTH,
 ] as const;
 
 export const MarginStyle = [
@@ -681,15 +673,16 @@ export const SliderStyle = [
 
 export const InputLikeStyle = [
   LABEL,
-  ...getStaticBgBorderRadiusByBg(SURFACE_COLOR),
-  BORDER_WIDTH,
-  TEXT,
-  TEXT_SIZE,
-  TEXT_WEIGHT,
-  FONT_FAMILY,
-  FONT_STYLE,
-  MARGIN,
-  PADDING,
+  getStaticBackground(SURFACE_COLOR),
+  // TEXT,
+  // TEXT_SIZE,
+  // TEXT_WEIGHT,
+  // FONT_FAMILY,
+  // FONT_STYLE,
+  // MARGIN,
+  // PADDING,
+  // BORDER_WIDTH,
+  ...STYLING_FIELDS_SEQUENCE,
   ...ACCENT_VALIDATE,
 ] as const;
 
@@ -1046,7 +1039,7 @@ function handleToHoverLink(color: string) {
 }
 
 export const LinkStyle = [
-  ...LinkTextStyle,
+
   {
     name: "background",
     label: trans("style.background"),
@@ -1054,13 +1047,8 @@ export const LinkStyle = [
     depType: DEP_TYPE.SELF,
     transformer: toSelf,
   },
-  MARGIN,
-  PADDING,
-  FONT_FAMILY,
-  FONT_STYLE,
-  BORDER,
-  BORDER_WIDTH,
-  TEXT_SIZE
+  ...LinkTextStyle,
+  ...STYLING_FIELDS_SEQUENCE.filter((style) => style.name !== 'text')
 ] as const;
 
 export const DividerStyle = [
@@ -1069,19 +1057,17 @@ export const DividerStyle = [
     label: trans("color"),
     color: lightenColor(SECOND_SURFACE_COLOR, 0.05),
   },
-  BORDER_WIDTH,
-  MARGIN,
-  PADDING,
-  {
-    name: "text",
-    label: trans("text"),
-    depName: "color",
-    transformer: handleToDividerText,
-  },
-  TEXT_SIZE,
-  TEXT_WEIGHT,
-  FONT_FAMILY,
-  FONT_STYLE
+  ...STYLING_FIELDS_SEQUENCE.map((style) => {
+    if (style.name === 'text') {
+      return {
+        name: "text",
+        label: trans("text"),
+        depName: "color",
+        transformer: handleToDividerText,
+      }
+    }
+    return style
+  })
 ] as const;
 
 export const ProgressStyle = [

From 83442f4af98a9828ecb91cfab44955074c50e1a4 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Tue, 20 Feb 2024 21:44:11 +0100
Subject: [PATCH 61/97] Fix Modal padding Bug (whitescreen)

---
 .../lowcoder/src/comps/hooks/modalComp.tsx      | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/hooks/modalComp.tsx b/client/packages/lowcoder/src/comps/hooks/modalComp.tsx
index 96f0055ae3..fe9a6503ae 100644
--- a/client/packages/lowcoder/src/comps/hooks/modalComp.tsx
+++ b/client/packages/lowcoder/src/comps/hooks/modalComp.tsx
@@ -60,12 +60,13 @@ function extractMarginValues(style: ModalStyleType) {
   const regex = /\d+px|\d+em|\d+%|\d+vh|\d+vw/g;
   // Extract the values using the regular expression
   let values = style.padding.match(regex);
+  let valuesarray: number[] = [];
   // If only one value is found, duplicate it to simulate uniform margin
   if (values && values.length === 1) {
-      values = [values[0], values[0]];
+    valuesarray = [parseInt(values[0]), parseInt(values[0])];
   }
   // Return the array of values
-  return values;
+  return valuesarray;
 }
 
 const ModalStyled = styled.div<{ $style: ModalStyleType }>`
@@ -124,7 +125,13 @@ let TmpModalComp = (function () {
         },
         [dispatch]
       );
-      let paddingValues = extractMarginValues(props.style);
+      let paddingValues = [10, 10];
+      if (props.style.padding != undefined) {
+        const extractedValues = extractMarginValues(props.style);
+        if (extractedValues !== null) {
+          paddingValues = extractedValues;
+        } 
+      }
       return (
         <BackgroundColorContext.Provider value={props.style.background}>
           <ModalWrapper>
@@ -153,8 +160,8 @@ let TmpModalComp = (function () {
                 {...otherContainerProps}
                 items={gridItemCompToGridItems(items)}
                 autoHeight={props.autoHeight}
-                minHeight={paddingValues ? DEFAULT_HEIGHT - parseInt(paddingValues[0]) * 2 + "px" : ""}
-                containerPadding={paddingValues ? [parseInt(paddingValues[0]), parseInt(paddingValues[1])] : [24,24]}
+                minHeight={paddingValues ? DEFAULT_HEIGHT - paddingValues[0] * 2 + "px" : ""}
+                containerPadding={paddingValues ? [paddingValues[0], paddingValues[1]] : [24,24]}
                 hintPlaceholder={HintPlaceHolder}
               />
             </Modal>

From 878dfaacbcddfcfe1d0e1dd31d0892e98ccaa73f Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Tue, 20 Feb 2024 22:09:59 +0100
Subject: [PATCH 62/97] Add Icon Comp Texts in Language Files

---
 client/packages/lowcoder/src/i18n/locales/en.ts | 12 ++++++++++--
 client/packages/lowcoder/src/i18n/locales/zh.ts |  8 ++++++++
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index 74b2296b9b..287603466e 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -948,7 +948,11 @@ export const en = {
 
     "responsiveLayoutCompName": "Responsive Layout",
     "responsiveLayoutCompDesc": "A layout component designed to adapt and respond to different screen sizes and devices, ensuring a consistent user experience.",
-    "responsiveLayoutCompKeywords": "responsive, layout, adapt, screen size"
+    "responsiveLayoutCompKeywords": "responsive, layout, adapt, screen size",
+
+    "iconCompName": "Icons",
+    "iconCompDesc": "Use various Icons to enhance the visual appeal and user experience of your application.",
+    "iconCompKeywords": "Icons, pictograms, symbols, shapes",
   },
 
 
@@ -1068,7 +1072,11 @@ export const en = {
 
   // ninth part
 
-
+  "iconComp": {
+    "icon": "Icon",
+    "autoSize": "Icon AutoSize",
+    "iconSize": "Icon Size",
+  },
   "numberInput": {
     "formatter": "Format",
     "precision": "Precision",
diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts
index 28194e00f0..e0634a2349 100644
--- a/client/packages/lowcoder/src/i18n/locales/zh.ts
+++ b/client/packages/lowcoder/src/i18n/locales/zh.ts
@@ -879,6 +879,9 @@ uiComp: {
     responsiveLayoutCompName: "响应式布局",
     responsiveLayoutCompDesc: "响应式布局",
     responsiveLayoutCompKeywords: "",
+    iconCompName: "图标",
+    iconCompDesc: "图标",
+    iconCompKeywords: "tb",
 },
 comp: {
     menuViewDocs: "查看文档",
@@ -2630,6 +2633,11 @@ timeLine: {
         helpvalue: "评论内容",
         helpcreatedAt: "创建时间",
       },
+      iconComp: {
+        icon: "图标",
+        autoSize: "图标自动大小",
+        iconSize: "图标大小",
+      },
     mention:{
         mentionList: "提及列表",
     },

From 50933b8411df81a193e421003c860a5ab92685ef Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 20 Feb 2024 22:37:24 +0000
Subject: [PATCH 63/97] Bump ip from 2.0.0 to 2.0.1 in /client

Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
---
 client/yarn.lock | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/client/yarn.lock b/client/yarn.lock
index 9dead2fc88..9ef4c6de6c 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -9983,9 +9983,9 @@ __metadata:
   linkType: hard
 
 "ip@npm:^2.0.0":
-  version: 2.0.0
-  resolution: "ip@npm:2.0.0"
-  checksum: cfcfac6b873b701996d71ec82a7dd27ba92450afdb421e356f44044ed688df04567344c36cbacea7d01b1c39a4c732dc012570ebe9bebfb06f27314bca625349
+  version: 2.0.1
+  resolution: "ip@npm:2.0.1"
+  checksum: d765c9fd212b8a99023a4cde6a558a054c298d640fec1020567494d257afd78ca77e37126b1a3ef0e053646ced79a816bf50621d38d5e768cdde0431fa3b0d35
   languageName: node
   linkType: hard
 

From 2286a21497813eaccca99ac7154a81f3a46e97d1 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Wed, 21 Feb 2024 12:43:52 +0100
Subject: [PATCH 64/97] Add Icon Comp - Fixes

---
 client/package.json                           |  1 +
 .../src/components/iconSelect/index.tsx       |  2 +
 .../lowcoder-design/src/icons/index.ts        | 21 -----
 client/packages/lowcoder/package.json         |  9 ++-
 client/packages/lowcoder/src/comps/index.tsx  | 67 ++++------------
 client/yarn.lock                              | 77 +++++++++++--------
 6 files changed, 70 insertions(+), 107 deletions(-)

diff --git a/client/package.json b/client/package.json
index fccf0fff11..92d3afa245 100644
--- a/client/package.json
+++ b/client/package.json
@@ -77,6 +77,7 @@
     "chalk": "4",
     "number-precision": "^1.6.0",
     "react-player": "^2.11.0",
+    "remixicon-react": "^1.0.0",
     "tui-image-editor": "^3.15.3"
   }
 }
diff --git a/client/packages/lowcoder-design/src/components/iconSelect/index.tsx b/client/packages/lowcoder-design/src/components/iconSelect/index.tsx
index ac3264aa2a..7ffc8cc72f 100644
--- a/client/packages/lowcoder-design/src/components/iconSelect/index.tsx
+++ b/client/packages/lowcoder-design/src/components/iconSelect/index.tsx
@@ -1,5 +1,6 @@
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import type { IconDefinition } from "@fortawesome/free-regular-svg-icons";
+import type { IconDefinition as IconDefinitionBrands } from "@fortawesome/free-brands-svg-icons";
 import { Popover } from "antd";
 import { ActionType } from "@rc-component/trigger/lib/interface";
 import { TacoInput } from "components/tacoInput";
@@ -147,6 +148,7 @@ async function getAllIcons() {
   const [{ far }, { fas }] = await Promise.all([
     import("@fortawesome/free-regular-svg-icons"),
     import("@fortawesome/free-solid-svg-icons"),
+    // import("@fontawesome/free-brands-svg-icons"),
   ]);
   const ret: Record<string, Icon> = {};
   for (const [type, pack] of Object.entries({ solid: fas, regular: far })) {
diff --git a/client/packages/lowcoder-design/src/icons/index.ts b/client/packages/lowcoder-design/src/icons/index.ts
index 662c4b0edc..1eee6b5e2f 100644
--- a/client/packages/lowcoder-design/src/icons/index.ts
+++ b/client/packages/lowcoder-design/src/icons/index.ts
@@ -278,28 +278,7 @@ export { ReactComponent as SignatureIcon } from "./icon-signature.svg";
 export { ReactComponent as ManualIcon } from "./icon-manual.svg";
 export { ReactComponent as WarnIcon } from "./icon-warn.svg";
 export { ReactComponent as SyncManualIcon } from "./icon-sync-manual.svg";
-
-export { ReactComponent as DangerIcon } from "icons/icon-danger.svg";
-export { ReactComponent as TableMinusIcon } from "icons/icon-table-minus.svg";
-export { ReactComponent as TablePlusIcon } from "icons/icon-table-plus.svg";
-export { ReactComponent as MobileAppIcon } from "icons/icon-mobile-app.svg";
-export { ReactComponent as MobileNavIcon } from "icons/icon-navigation-mobile.svg";
-export { ReactComponent as PcNavIcon } from "icons/icon-navigation-pc.svg";
-export { ReactComponent as UnLockIcon } from "icons/icon-unlock.svg";
-export { ReactComponent as CalendarDeleteIcon } from "icons/icon-calendar-delete.svg";
-export { ReactComponent as TableCheckedIcon } from "icons/icon-table-checked.svg";
-export { ReactComponent as TableUnCheckedIcon } from "icons/icon-table-boolean-false.svg";
-export { ReactComponent as FileFolderIcon } from "icons/icon-editor-folder.svg";
-export { ReactComponent as ExpandIcon } from "icons/icon-expand.svg";
-export { ReactComponent as CompressIcon } from "icons/icon-compress.svg";
-export { ReactComponent as TableCellsIcon } from "icons/icon-table-cells.svg"; // Added By Aqib Mirza
-export { ReactComponent as TimeLineIcon } from "icons/icon-timeline-comp.svg"
-export { ReactComponent as LottieIcon } from "icons/icon-lottie.svg";
-export { ReactComponent as MentionIcon } from "icons/icon-mention-comp.svg";
-export { ReactComponent as AutoCompleteCompIcon } from "icons/icon-autocomplete-comp.svg";
-
 export { ReactComponent as IconCompIcon } from "icons/IconCompIcon.svg";
-
 export { ReactComponent as DangerIcon } from "./icon-danger.svg";
 export { ReactComponent as TableMinusIcon } from "./icon-table-minus.svg";
 export { ReactComponent as TablePlusIcon } from "./icon-table-plus.svg";
diff --git a/client/packages/lowcoder/package.json b/client/packages/lowcoder/package.json
index 1e8e507895..addc573f83 100644
--- a/client/packages/lowcoder/package.json
+++ b/client/packages/lowcoder/package.json
@@ -6,7 +6,7 @@
   "main": "src/index.sdk.ts",
   "types": "src/index.sdk.ts",
   "dependencies": {
-    "@ant-design/icons": "^4.7.0",
+    "@ant-design/icons": "^5.3.0",
     "@codemirror/autocomplete": "^6.11.1",
     "@codemirror/commands": "^6.3.2",
     "@codemirror/lang-css": "^6.2.1",
@@ -19,9 +19,10 @@
     "@dnd-kit/modifiers": "^5.0.0",
     "@dnd-kit/sortable": "^6.0.0",
     "@dnd-kit/utilities": "^3.1.0",
-    "@fortawesome/fontawesome-svg-core": "^6.4.0",
-    "@fortawesome/free-regular-svg-icons": "^6.4.0",
-    "@fortawesome/free-solid-svg-icons": "^6.4.0",
+    "@fortawesome/fontawesome-svg-core": "^6.5.1",
+    "@fortawesome/free-brands-svg-icons": "^6.5.1",
+    "@fortawesome/free-regular-svg-icons": "^6.5.1",
+    "@fortawesome/free-solid-svg-icons": "^6.5.1",
     "@fortawesome/react-fontawesome": "latest",
     "@manaflair/redux-batch": "^1.0.0",
     "@rjsf/antd": "^5.15.1",
diff --git a/client/packages/lowcoder/src/comps/index.tsx b/client/packages/lowcoder/src/comps/index.tsx
index 072eec5e94..aebaae3bf5 100644
--- a/client/packages/lowcoder/src/comps/index.tsx
+++ b/client/packages/lowcoder/src/comps/index.tsx
@@ -67,6 +67,7 @@ import { VideoMeetingStreamComp } from "./comps/meetingComp/videoMeetingStreamCo
 import { ControlButton } from "./comps/meetingComp/controlButton";
 import { VideoMeetingControllerComp } from "./comps/meetingComp/videoMeetingControllerComp";
 import { VideoSharingStreamComp } from "./comps/meetingComp/videoSharingStreamComp";
+import { IconComp } from "./comps/iconComp";
 
 import {
   AudioCompIcon,
@@ -130,43 +131,9 @@ import {
   CommentIcon,
   MentionIcon,
   AutoCompleteCompIcon,
-
-  IconCompIcon,
-} from "lowcoder-design";
-// from Mousheng
-import { defaultFormData, FormComp } from "./comps/formComp/formComp";
-import { IFrameComp } from "./comps/iframeComp";
-import { defaultGridData, defaultListViewData, GridComp, ListViewComp } from "./comps/listViewComp";
-import { ModuleComp } from "./comps/moduleComp/moduleComp";
-import { NavComp } from "./comps/navComp/navComp";
-import { TableComp } from "./comps/tableComp";
-import { registerComp, UICompManifest, UICompType } from "./uiCompRegistry";
-import { QRCodeComp } from "./comps/qrCodeComp";
-import { JsonExplorerComp } from "./comps/jsonComp/jsonExplorerComp";
-import { JsonEditorComp } from "./comps/jsonComp/jsonEditorComp";
-import { TreeComp } from "./comps/treeComp/treeComp";
-import { TreeSelectComp } from "./comps/treeComp/treeSelectComp";
-import { trans } from "i18n";
-import { remoteComp } from "./comps/remoteComp/remoteComp";
-import { AudioComp } from "./comps/mediaComp/audioComp";
-import { VideoComp } from "./comps/mediaComp/videoComp";
-import { DrawerComp } from "./hooks/drawerComp";
-import { CarouselComp } from "./comps/carouselComp";
-import { ToggleButtonComp } from "./comps/buttonComp/toggleButtonComp";
-import { defaultCollapsibleContainerData } from "./comps/containerComp/collapsibleContainerComp";
-import { RemoteCompInfo } from "types/remoteComp";
-import { ScannerComp } from "./comps/buttonComp/scannerComp";
-import { SignatureComp } from "./comps/signatureComp";
-import { TimeLineComp } from "./comps/timelineComp/timelineComp";
-import { MentionComp } from "./comps/textInputComp/mentionComp";
-import { AutoCompleteComp } from "./comps/autoCompleteComp/autoCompleteComp"
-import { IconComp } from "./comps/iconComp";
-// from Mousheng
-
-//Added by Aqib Mirza
-import { JsonLottieComp } from "./comps/jsonComp/jsonLottieComp";
   ResponsiveLayoutCompIcon,
   MermaidIcon,
+  IconCompIcon,
 } from "lowcoder-design";
 
 type Registry = {
@@ -950,6 +917,19 @@ var uiCompMap: Registry = {
       h: 40,
     },
   },
+  icon: {
+    name: trans("uiComp.iconCompName"),
+    enName: "icon",
+    description: trans("uiComp.iconCompDesc"),
+    categories: ["multimedia"],
+    icon: IconCompIcon,
+    keywords: trans("uiComp.iconCompKeywords"),
+    comp: IconComp,
+    layoutInfo: {
+      w: 2,
+      h: 10,
+    },
+  },
   imageEditor: {
     name: trans("uiComp.imageEditorCompName"),
     enName: "Image Editor",
@@ -1058,23 +1038,6 @@ var uiCompMap: Registry = {
     },
   },
 
-// from Mousheng
-  icon: {
-    name: trans("uiComp.iconCompName"),
-    enName: "icon",
-    description: trans("uiComp.iconCompDesc"),
-    categories: ["dataDisplay"],
-    icon: IconCompIcon,
-    keywords: trans("uiComp.iconCompKeywords"),
-    comp: IconComp,
-    layoutInfo: {
-      w: 2,
-      h: 10,
-    },
-  },
-
-// from Mousheng
-
   // Integration
 
   iframe: {
diff --git a/client/yarn.lock b/client/yarn.lock
index 548e5b8740..baff44425c 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -63,15 +63,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@ant-design/colors@npm:^6.0.0":
-  version: 6.0.0
-  resolution: "@ant-design/colors@npm:6.0.0"
-  dependencies:
-    "@ctrl/tinycolor": ^3.4.0
-  checksum: 55110ac8a3353f3ec2d2fdee6ffb841967dd75f3783ef4e68c22731e042606bc5b3c3febb6cd20aed3f14585729ce8eddf75b531c703c06a2e95b8569861bb47
-  languageName: node
-  linkType: hard
-
 "@ant-design/colors@npm:^7.0.0, @ant-design/colors@npm:^7.0.2":
   version: 7.0.2
   resolution: "@ant-design/colors@npm:7.0.2"
@@ -106,36 +97,42 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@ant-design/icons@npm:^4.7.0":
-  version: 4.8.1
-  resolution: "@ant-design/icons@npm:4.8.1"
+"@ant-design/icons-svg@npm:^4.4.0":
+  version: 4.4.2
+  resolution: "@ant-design/icons-svg@npm:4.4.2"
+  checksum: c66cda4533ec2f86162a9adda04be2aba5674d5c758ba886bd9d8de89dc45473ef3124eb755b4cfbd09121d3bdc34e075ee931e47dd0f8a7fdc01be0cb3d6c40
+  languageName: node
+  linkType: hard
+
+"@ant-design/icons@npm:^5.2.6":
+  version: 5.2.6
+  resolution: "@ant-design/icons@npm:5.2.6"
   dependencies:
-    "@ant-design/colors": ^6.0.0
+    "@ant-design/colors": ^7.0.0
     "@ant-design/icons-svg": ^4.3.0
     "@babel/runtime": ^7.11.2
     classnames: ^2.2.6
-    lodash: ^4.17.15
-    rc-util: ^5.9.4
+    rc-util: ^5.31.1
   peerDependencies:
     react: ">=16.0.0"
     react-dom: ">=16.0.0"
-  checksum: abd3603ea951983a8bfa7f4c7e6fcc787ccdc4804faa8bb8641b6904a95cf5fc04753cf636a6c5b5b798f371f4075fddae29684779bb16e2a025b727ab2c8ad3
+  checksum: 2f571699b1903383cd09faa78e4cce34973debb0e7ec6223b9d9a0a6ab2b2f0c876072db62bbd4e6a45e864df5447343315e066abeffaf58aa5b97df3acc89f1
   languageName: node
   linkType: hard
 
-"@ant-design/icons@npm:^5.2.6":
-  version: 5.2.6
-  resolution: "@ant-design/icons@npm:5.2.6"
+"@ant-design/icons@npm:^5.3.0":
+  version: 5.3.0
+  resolution: "@ant-design/icons@npm:5.3.0"
   dependencies:
     "@ant-design/colors": ^7.0.0
-    "@ant-design/icons-svg": ^4.3.0
+    "@ant-design/icons-svg": ^4.4.0
     "@babel/runtime": ^7.11.2
     classnames: ^2.2.6
     rc-util: ^5.31.1
   peerDependencies:
     react: ">=16.0.0"
     react-dom: ">=16.0.0"
-  checksum: 2f571699b1903383cd09faa78e4cce34973debb0e7ec6223b9d9a0a6ab2b2f0c876072db62bbd4e6a45e864df5447343315e066abeffaf58aa5b97df3acc89f1
+  checksum: 6b58bb057f0c92b5d1fc5bd062119e070ac0ef86979c011dbae657b54e51bdfc4efd1d7f52cd3e0e05a8f82c81847f86bb4bb7f797154b5fcfc750f4758b4a45
   languageName: node
   linkType: hard
 
@@ -1946,7 +1943,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@ctrl/tinycolor@npm:^3.4.0, @ctrl/tinycolor@npm:^3.6.1":
+"@ctrl/tinycolor@npm:^3.6.1":
   version: 3.6.1
   resolution: "@ctrl/tinycolor@npm:3.6.1"
   checksum: cefec6fcaaa3eb8ddf193f981e097dccf63b97b93b1e861cb18c645654824c831a568f444996e15ee509f255658ed82fba11c5365494a6e25b9b12ac454099e0
@@ -2336,7 +2333,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@fortawesome/fontawesome-svg-core@npm:^6.4.0":
+"@fortawesome/fontawesome-svg-core@npm:^6.5.1":
   version: 6.5.1
   resolution: "@fortawesome/fontawesome-svg-core@npm:6.5.1"
   dependencies:
@@ -2345,7 +2342,16 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@fortawesome/free-regular-svg-icons@npm:^6.4.0":
+"@fortawesome/free-brands-svg-icons@npm:^6.5.1":
+  version: 6.5.1
+  resolution: "@fortawesome/free-brands-svg-icons@npm:6.5.1"
+  dependencies:
+    "@fortawesome/fontawesome-common-types": 6.5.1
+  checksum: c29f8a9ad9886c0733d3616b5ea05b08b4943c1b5231c73f31a07e7df36c337e5a51cfe7cc610e623cb2b4a0607e3f82a8a3f46107c4347aa653784489672314
+  languageName: node
+  linkType: hard
+
+"@fortawesome/free-regular-svg-icons@npm:^6.5.1":
   version: 6.5.1
   resolution: "@fortawesome/free-regular-svg-icons@npm:6.5.1"
   dependencies:
@@ -2354,7 +2360,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@fortawesome/free-solid-svg-icons@npm:^6.4.0":
+"@fortawesome/free-solid-svg-icons@npm:^6.5.1":
   version: 6.5.1
   resolution: "@fortawesome/free-solid-svg-icons@npm:6.5.1"
   dependencies:
@@ -11622,6 +11628,7 @@ __metadata:
     number-precision: ^1.6.0
     prettier: ^3.1.0
     react-player: ^2.11.0
+    remixicon-react: ^1.0.0
     rimraf: ^3.0.2
     rollup: ^2.79.0
     shelljs: ^0.8.5
@@ -11665,7 +11672,7 @@ __metadata:
   version: 0.0.0-use.local
   resolution: "lowcoder@workspace:packages/lowcoder"
   dependencies:
-    "@ant-design/icons": ^4.7.0
+    "@ant-design/icons": ^5.3.0
     "@codemirror/autocomplete": ^6.11.1
     "@codemirror/commands": ^6.3.2
     "@codemirror/lang-css": ^6.2.1
@@ -11678,9 +11685,10 @@ __metadata:
     "@dnd-kit/modifiers": ^5.0.0
     "@dnd-kit/sortable": ^6.0.0
     "@dnd-kit/utilities": ^3.1.0
-    "@fortawesome/fontawesome-svg-core": ^6.4.0
-    "@fortawesome/free-regular-svg-icons": ^6.4.0
-    "@fortawesome/free-solid-svg-icons": ^6.4.0
+    "@fortawesome/fontawesome-svg-core": ^6.5.1
+    "@fortawesome/free-brands-svg-icons": ^6.5.1
+    "@fortawesome/free-regular-svg-icons": ^6.5.1
+    "@fortawesome/free-solid-svg-icons": ^6.5.1
     "@fortawesome/react-fontawesome": latest
     "@manaflair/redux-batch": ^1.0.0
     "@rjsf/antd": ^5.15.1
@@ -14398,7 +14406,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"rc-util@npm:^5.0.1, rc-util@npm:^5.16.1, rc-util@npm:^5.17.0, rc-util@npm:^5.18.1, rc-util@npm:^5.19.2, rc-util@npm:^5.2.0, rc-util@npm:^5.20.1, rc-util@npm:^5.21.0, rc-util@npm:^5.24.4, rc-util@npm:^5.25.2, rc-util@npm:^5.26.0, rc-util@npm:^5.27.0, rc-util@npm:^5.28.0, rc-util@npm:^5.30.0, rc-util@npm:^5.31.1, rc-util@npm:^5.32.2, rc-util@npm:^5.34.1, rc-util@npm:^5.35.0, rc-util@npm:^5.36.0, rc-util@npm:^5.37.0, rc-util@npm:^5.38.0, rc-util@npm:^5.38.1, rc-util@npm:^5.8.0, rc-util@npm:^5.9.4":
+"rc-util@npm:^5.0.1, rc-util@npm:^5.16.1, rc-util@npm:^5.17.0, rc-util@npm:^5.18.1, rc-util@npm:^5.19.2, rc-util@npm:^5.2.0, rc-util@npm:^5.20.1, rc-util@npm:^5.21.0, rc-util@npm:^5.24.4, rc-util@npm:^5.25.2, rc-util@npm:^5.26.0, rc-util@npm:^5.27.0, rc-util@npm:^5.28.0, rc-util@npm:^5.30.0, rc-util@npm:^5.31.1, rc-util@npm:^5.32.2, rc-util@npm:^5.34.1, rc-util@npm:^5.35.0, rc-util@npm:^5.36.0, rc-util@npm:^5.37.0, rc-util@npm:^5.38.0, rc-util@npm:^5.38.1, rc-util@npm:^5.8.0":
   version: 5.38.1
   resolution: "rc-util@npm:5.38.1"
   dependencies:
@@ -15225,6 +15233,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"remixicon-react@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "remixicon-react@npm:1.0.0"
+  peerDependencies:
+    react: ">=0.14.0"
+  checksum: be7abfb3558c9ed18ccfff5a28bd66dbee4207887682ae7a00c697e6051eadecad0da83f1e83910ed6ddebe7f2ab73e488f0f4c604897605bbb3d8f519f416ed
+  languageName: node
+  linkType: hard
+
 "request-promise-core@npm:1.1.4":
   version: 1.1.4
   resolution: "request-promise-core@npm:1.1.4"

From f808455179381a2b34b1567cba243185f6fb6542 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Wed, 21 Feb 2024 18:37:30 +0500
Subject: [PATCH 65/97] added marketplace endpoints

---
 .../lowcoder/src/api/applicationApi.ts        | 22 ++++++++++++++++++-
 .../src/constants/reduxActionConstants.ts     |  2 ++
 .../reducers/uiReducers/applicationReducer.ts |  9 ++++++++
 .../redux/reduxActions/applicationActions.ts  |  4 ++++
 .../src/redux/sagas/applicationSagas.ts       | 22 +++++++++++++++++++
 .../redux/selectors/applicationSelector.ts    |  2 ++
 6 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/client/packages/lowcoder/src/api/applicationApi.ts b/client/packages/lowcoder/src/api/applicationApi.ts
index 41ee23204f..06659a4414 100644
--- a/client/packages/lowcoder/src/api/applicationApi.ts
+++ b/client/packages/lowcoder/src/api/applicationApi.ts
@@ -78,6 +78,7 @@ class ApplicationApi extends Api {
   static newURLPrefix = "/applications";
   static fetchHomeDataURL = "/v1/applications/home";
   static createApplicationURL = "/v1/applications";
+  static fetchAllMarketplaceAppsURL = "/v1/applications/marketplace-apps";
   static deleteApplicationURL = (applicationId: string) => `/v1/applications/${applicationId}`;
   static getAppPublishInfoURL = (applicationId: string) => `/v1/applications/${applicationId}/view`;
   static getAppEditingInfoURL = (applicationId: string) => `/v1/applications/${applicationId}`;
@@ -92,6 +93,9 @@ class ApplicationApi extends Api {
     `/v1/applications/${applicationId}/permissions/${permissionId}`;
   static createFromTemplateURL = `/v1/applications/createFromTemplate`;
   static publicToAllURL = (applicationId: string) => `/applications/${applicationId}/public-to-all`;
+  static publicToMarketplaceURL = (applicationId: string) => `/v1/applications/${applicationId}/public-to-marketplace`;
+  static getMarketplaceAppURL = (applicationId: string) => `/v1/applications/${applicationId}/view_marketplace`;
+
 
   static fetchHomeData(request: HomeDataPayload): AxiosPromise<HomeDataResponse> {
     return Api.get(ApplicationApi.fetchHomeDataURL, request);
@@ -167,7 +171,9 @@ class ApplicationApi extends Api {
     const url =
       type === "published"
         ? ApplicationApi.getAppPublishInfoURL(applicationId)
-        : ApplicationApi.getAppEditingInfoURL(applicationId);
+        : type === "view_marketplace"
+          ? ApplicationApi.getMarketplaceAppURL(applicationId)
+          : ApplicationApi.getAppEditingInfoURL(applicationId);
     return Api.get(url);
   }
 
@@ -211,6 +217,20 @@ class ApplicationApi extends Api {
       publicToAll: publicToAll,
     });
   }
+
+  static publicToMarketplace(appId: string, publicToMarketplace: boolean) {
+    return Api.put(ApplicationApi.publicToMarketplaceURL(appId), {
+      publicToMarketplace,
+    });
+  }
+
+  static fetchAllMarketplaceApps() {
+    return Api.get(ApplicationApi.fetchAllMarketplaceAppsURL);
+  }
+
+  static getMarketplaceApp(appId: string) {
+    return Api.get(ApplicationApi.getMarketplaceAppURL(appId));
+  }
 }
 
 export default ApplicationApi;
diff --git a/client/packages/lowcoder/src/constants/reduxActionConstants.ts b/client/packages/lowcoder/src/constants/reduxActionConstants.ts
index fdf34040b3..ae7ebf1298 100644
--- a/client/packages/lowcoder/src/constants/reduxActionConstants.ts
+++ b/client/packages/lowcoder/src/constants/reduxActionConstants.ts
@@ -137,6 +137,8 @@ export const ReduxActionTypes = {
   FETCH_ALL_APPLICATIONS_SUCCESS: "FETCH_ALL_APPLICATIONS_SUCCESS",
   FETCH_ALL_MODULES_INIT: "FETCH_ALL_MODULES_INIT",
   FETCH_ALL_MODULES_SUCCESS: "FETCH_ALL_MODULES_SUCCESS",
+  FETCH_ALL_MARKETPLACE_APPS: "FETCH_ALL_MARKETPLACE_APPS",
+  FETCH_ALL_MARKETPLACE_APPS_SUCCESS: "FETCH_ALL_MARKETPLACE_APPS_SUCCESS",
 
   /* user profile */
   SET_USER_PROFILE_SETTING_MODAL_VISIBLE: "SET_USER_PROFILE_SETTING_MODAL_VISIBLE",
diff --git a/client/packages/lowcoder/src/redux/reducers/uiReducers/applicationReducer.ts b/client/packages/lowcoder/src/redux/reducers/uiReducers/applicationReducer.ts
index 7938543a4f..dda424c1f5 100644
--- a/client/packages/lowcoder/src/redux/reducers/uiReducers/applicationReducer.ts
+++ b/client/packages/lowcoder/src/redux/reducers/uiReducers/applicationReducer.ts
@@ -24,6 +24,7 @@ const initialState: ApplicationReduxState = {
   applicationList: [],
   modules: [],
   recycleList: [],
+  marketplace: [],
   loadingStatus: {
     isFetchingHomeData: false,
     fetchHomeDataFinished: false,
@@ -98,6 +99,13 @@ const usersReducer = createReducer(initialState, {
     ...state,
     recycleList: action.payload,
   }),
+  [ReduxActionTypes.FETCH_ALL_MARKETPLACE_APPS_SUCCESS]: (
+    state: ApplicationReduxState,
+    action: ReduxAction<ApplicationMeta[]>
+  ): ApplicationReduxState => ({
+    ...state,
+    marketplace: action.payload,
+  }),
   [ReduxActionTypes.CREATE_APPLICATION_INIT]: (
     state: ApplicationReduxState
   ): ApplicationReduxState => ({
@@ -336,6 +344,7 @@ export interface ApplicationReduxState {
   applicationList: ApplicationMeta[];
   modules: ApplicationMeta[];
   recycleList: ApplicationMeta[];
+  marketplace: ApplicationMeta[];
   appPermissionInfo?: AppPermissionInfo;
   currentApplication?: ApplicationMeta;
   templateId?: string;
diff --git a/client/packages/lowcoder/src/redux/reduxActions/applicationActions.ts b/client/packages/lowcoder/src/redux/reduxActions/applicationActions.ts
index 12697e3522..7619798d69 100644
--- a/client/packages/lowcoder/src/redux/reduxActions/applicationActions.ts
+++ b/client/packages/lowcoder/src/redux/reduxActions/applicationActions.ts
@@ -32,6 +32,10 @@ export const fetchApplicationRecycleList = () => ({
   type: ReduxActionTypes.FETCH_APPLICATION_RECYCLE_LIST_INIT,
 });
 
+export const fetchAllMarketplaceApps = () => ({
+  type: ReduxActionTypes.FETCH_ALL_MARKETPLACE_APPS,
+});
+
 export type CreateApplicationPayload = {
   applicationName: string;
   applicationType: AppTypeEnum;
diff --git a/client/packages/lowcoder/src/redux/sagas/applicationSagas.ts b/client/packages/lowcoder/src/redux/sagas/applicationSagas.ts
index c496441822..6967c3c149 100644
--- a/client/packages/lowcoder/src/redux/sagas/applicationSagas.ts
+++ b/client/packages/lowcoder/src/redux/sagas/applicationSagas.ts
@@ -372,6 +372,24 @@ function* fetchApplicationRecycleListSaga() {
   }
 }
 
+function* fetchAllMarketplaceAppsSaga() {
+  try {
+    const response: AxiosResponse<GenericApiResponse<ApplicationMeta[]>> = yield call(
+      ApplicationApi.fetchAllMarketplaceApps
+    );
+    const isValidResponse: boolean = validateResponse(response);
+    if (isValidResponse) {
+      yield put({
+        type: ReduxActionTypes.FETCH_ALL_MARKETPLACE_APPS_SUCCESS,
+        payload: response.data.data,
+      });
+    }
+  } catch (error: any) {
+    messageInstance.error(error.message);
+    log.debug("fetch marketplace apps error: ", error);
+  }
+}
+
 export default function* applicationSagas() {
   yield all([
     takeLatest(ReduxActionTypes.FETCH_HOME_DATA, fetchHomeDataSaga),
@@ -393,5 +411,9 @@ export default function* applicationSagas() {
       ReduxActionTypes.FETCH_APPLICATION_RECYCLE_LIST_INIT,
       fetchApplicationRecycleListSaga
     ),
+    takeLatest(
+      ReduxActionTypes.FETCH_ALL_MARKETPLACE_APPS,
+      fetchAllMarketplaceAppsSaga,
+    ),
   ]);
 }
diff --git a/client/packages/lowcoder/src/redux/selectors/applicationSelector.ts b/client/packages/lowcoder/src/redux/selectors/applicationSelector.ts
index 3279f65c66..2d888a9c97 100644
--- a/client/packages/lowcoder/src/redux/selectors/applicationSelector.ts
+++ b/client/packages/lowcoder/src/redux/selectors/applicationSelector.ts
@@ -8,6 +8,8 @@ export const modulesSelector = (state: AppState): ApplicationMeta[] => state.ui.
 
 export const recycleListSelector = (state: AppState) => state.ui.application.recycleList;
 
+export const marketplaceSelector = (state: AppState) => state.ui.application.marketplace;
+
 export const getHomeOrg = (state: AppState) => state.ui.application.homeOrg;
 
 export const isFetchingHomeData = (state: AppState) =>

From 5bce8d21259d0aaaadaea3e0f22c6b1cde51d2a2 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Wed, 21 Feb 2024 18:39:52 +0500
Subject: [PATCH 66/97] added switch to make as public to marketplace

---
 .../PermissionDialog/AppPermissionDialog.tsx  | 21 +++++++++++++++++++
 .../src/constants/applicationConstants.ts     |  6 ++++--
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/client/packages/lowcoder/src/components/PermissionDialog/AppPermissionDialog.tsx b/client/packages/lowcoder/src/components/PermissionDialog/AppPermissionDialog.tsx
index b86282d80f..37ec80ab6b 100644
--- a/client/packages/lowcoder/src/components/PermissionDialog/AppPermissionDialog.tsx
+++ b/client/packages/lowcoder/src/components/PermissionDialog/AppPermissionDialog.tsx
@@ -197,12 +197,33 @@ function AppShareView(props: {
 }) {
   const { applicationId, permissionInfo, isModule } = props;
   const [isPublic, setPublic] = useState(permissionInfo.publicToAll);
+  const [isPublicToMarketplace, setPublicToMarketplace] = useState(permissionInfo.publicToMarketplace);
   const dispatch = useDispatch();
   useEffect(() => {
     setPublic(permissionInfo.publicToAll);
   }, [permissionInfo.publicToAll]);
+  useEffect(() => {
+    setPublicToMarketplace(permissionInfo.publicToMarketplace);
+  }, [permissionInfo.publicToMarketplace]);
   return (
     <div style={{ marginBottom: "22px" }}>
+      <PermissionSwitchWrapper>
+        <TacoSwitch
+          checked={isPublicToMarketplace}
+          onChange={(checked) => {
+            setPublicToMarketplace(checked);
+            ApplicationApi.publicToMarketplace(applicationId, checked)
+              .then((resp) => {
+                validateResponse(resp);
+                dispatch(updateAppPermissionInfo({ publicToMarketplace: checked }));
+              })
+              .catch((e) => {
+                messageInstance.error(e.message);
+              });
+          }}
+          label={isModule ? 'Public module to marketplace' : 'Public app to marketplace'}
+        />
+      </PermissionSwitchWrapper>
       <PermissionSwitchWrapper>
         <TacoSwitch
           checked={isPublic}
diff --git a/client/packages/lowcoder/src/constants/applicationConstants.ts b/client/packages/lowcoder/src/constants/applicationConstants.ts
index db0b620dad..40b38ee529 100644
--- a/client/packages/lowcoder/src/constants/applicationConstants.ts
+++ b/client/packages/lowcoder/src/constants/applicationConstants.ts
@@ -20,7 +20,7 @@ export const AppUILayoutType: Record<AppTypeEnum, UiLayoutType> = {
   [AppTypeEnum.MobileTabLayout]: "mobileTabLayout",
 };
 
-export type ApplicationDSLType = "editing" | "published";
+export type ApplicationDSLType = "editing" | "published" | "view_marketplace";
 export type ApplicationRoleType = "viewer" | "editor" | "owner";
 export type ApplicationPermissionType = "USER" | "GROUP" | "ORG_ADMIN";
 
@@ -36,6 +36,7 @@ export interface ApplicationMeta {
   containerSize?: { height: number; width: number };
   createBy: string;
   createAt: number;
+  creatorEmail?: string;
   orgId: string;
   role: ApplicationRoleType;
   extra: ApplicationExtra;
@@ -80,9 +81,10 @@ export interface AppPermissionInfo {
   permissions: PermissionItem[];
   invitationCodes: AppInviteInfo[];
   publicToAll: boolean;
+  publicToMarketplace: boolean;
 }
 
-export type AppViewMode = "edit" | "preview" | "view";
+export type AppViewMode = "edit" | "preview" | "view" | "view_marketplace";
 
 export type AppPathParams = {
   viewMode: AppViewMode;

From 3ff918e5f24ca80367054046aade47906d90daae Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Wed, 21 Feb 2024 18:41:38 +0500
Subject: [PATCH 67/97] added marketplace route

---
 .../src/icons/icon-application-home.svg       |  4 +--
 .../icon-application-marketplace-active.svg   | 12 +++++++
 .../icons/icon-application-marketplace.svg    | 16 +++++++++
 .../lowcoder-design/src/icons/index.ts        |  2 ++
 client/packages/lowcoder/src/app.tsx          |  2 ++
 .../lowcoder/src/constants/routesURL.ts       |  1 +
 .../packages/lowcoder/src/i18n/locales/de.ts  |  1 +
 .../packages/lowcoder/src/i18n/locales/en.ts  |  1 +
 .../packages/lowcoder/src/i18n/locales/zh.ts  |  1 +
 .../pages/ApplicationV2/MarketplaceView.tsx   | 35 +++++++++++++++++++
 .../src/pages/ApplicationV2/index.tsx         | 17 +++++++++
 11 files changed, 90 insertions(+), 2 deletions(-)
 create mode 100644 client/packages/lowcoder-design/src/icons/icon-application-marketplace-active.svg
 create mode 100644 client/packages/lowcoder-design/src/icons/icon-application-marketplace.svg
 create mode 100644 client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx

diff --git a/client/packages/lowcoder-design/src/icons/icon-application-home.svg b/client/packages/lowcoder-design/src/icons/icon-application-home.svg
index 8435068e1c..e56d475c91 100644
--- a/client/packages/lowcoder-design/src/icons/icon-application-home.svg
+++ b/client/packages/lowcoder-design/src/icons/icon-application-home.svg
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg">
   <defs>
-    <linearGradient id="icon-application-home_svg__a" x1="50%" y1="1.89576049%" x2="50%" y2="94.4251638%">
+    <linearGradient id="icon-application-home-active_svg__a" x1="50%" y1="1.89576049%" x2="50%" y2="94.4251638%">
       <stop stop-color="#5C6066" offset="0%"/>
       <stop stop-color="#333740" offset="100%"/>
     </linearGradient>
@@ -11,6 +11,6 @@
     </linearGradient>
   </defs>
   <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-    <path d="M9.29562521,0.732013329 C9.68797628,0.343324403 10.3211343,0.346293158 10.7098232,0.73864423 L10.7098232,0.73864423 L18.9442291,9.05063294 C19.0926385,9.20044065 19.1758975,9.4027861 19.1758975,9.61365979 C19.1758975,10.0554876 18.8177253,10.4136598 18.3758975,10.4136598 L18.3758975,10.4136598 L16.8630892,10.4136598 L16.8630892,17.300355 C16.8633999,17.3004585 16.8633999,17.3005621 16.8633998,17.3006657 L16.8571726,17.423357 C16.7955639,18.0284473 16.2844095,18.5004964 15.6630892,18.5000443 L15.6630892,18.5000443 L4.3377353,18.4971121 C3.67511501,18.4966298 3.13804603,17.9594217 3.1377353,17.2968013 L3.1377353,17.2968013 L3.1377353,10.4136598 L1.62413378,10.4136598 C1.41328052,10.4136598 1.21095296,10.3304169 1.06114882,10.1820329 C0.747245039,9.87110485 0.744832702,9.3645786 1.05576071,9.05067483 L1.05576071,9.05067483 L9.28894244,0.738696591 L9.28894244,0.738696591 Z M11.8596759,13 L8.14055447,13 C7.58826972,13 7.14055447,13.4477153 7.14055447,14 C7.14055447,14.5522847 7.58826972,15 8.14055447,15 L8.14055447,15 L11.8596759,15 C12.4119606,15 12.8596759,14.5522847 12.8596759,14 C12.8596759,13.4477153 12.4119606,13 11.8596759,13 L11.8596759,13 Z" fill="url(#icon-application-home_svg__a)" fill-rule="nonzero"/>
+    <path d="M9.29562521,0.732013329 C9.68797628,0.343324403 10.3211343,0.346293158 10.7098232,0.73864423 L10.7098232,0.73864423 L18.9442291,9.05063294 C19.0926385,9.20044065 19.1758975,9.4027861 19.1758975,9.61365979 C19.1758975,10.0554876 18.8177253,10.4136598 18.3758975,10.4136598 L18.3758975,10.4136598 L16.8630892,10.4136598 L16.8630892,17.300355 C16.8633999,17.3004585 16.8633999,17.3005621 16.8633998,17.3006657 L16.8571726,17.423357 C16.7955639,18.0284473 16.2844095,18.5004964 15.6630892,18.5000443 L15.6630892,18.5000443 L4.3377353,18.4971121 C3.67511501,18.4966298 3.13804603,17.9594217 3.1377353,17.2968013 L3.1377353,17.2968013 L3.1377353,10.4136598 L1.62413378,10.4136598 C1.41328052,10.4136598 1.21095296,10.3304169 1.06114882,10.1820329 C0.747245039,9.87110485 0.744832702,9.3645786 1.05576071,9.05067483 L1.05576071,9.05067483 L9.28894244,0.738696591 L9.28894244,0.738696591 Z M11.8596759,13 L8.14055447,13 C7.58826972,13 7.14055447,13.4477153 7.14055447,14 C7.14055447,14.5522847 7.58826972,15 8.14055447,15 L8.14055447,15 L11.8596759,15 C12.4119606,15 12.8596759,14.5522847 12.8596759,14 C12.8596759,13.4477153 12.4119606,13 11.8596759,13 L11.8596759,13 Z" fill="url(#icon-application-home-active_svg__a)" fill-rule="nonzero"/>
   </g>
 </svg>
diff --git a/client/packages/lowcoder-design/src/icons/icon-application-marketplace-active.svg b/client/packages/lowcoder-design/src/icons/icon-application-marketplace-active.svg
new file mode 100644
index 0000000000..6db0975e52
--- /dev/null
+++ b/client/packages/lowcoder-design/src/icons/icon-application-marketplace-active.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="20px" height="20px" viewBox="0 0 23 23" version="1.1" xmlns="http://www.w3.org/2000/svg">
+  <defs>
+    <linearGradient id="icon-application-marketplace-active_svg__a" x1="50%" y1="1.89576049%" x2="50%" y2="94.4251638%">
+      <stop stop-color="#6D83F2" offset="0%"/>
+      <stop stop-color="#4965F2" offset="100%"/>
+    </linearGradient>
+  </defs>
+  <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+    <path d="M2.7,9.45a4.235,4.235,0,0,0,.3.3V22a1,1,0,0,0,1,1H20a1,1,0,0,0,1-1V9.752a4.235,4.235,0,0,0,.3-.3,4,4,0,0,0,.731-3.456L20.97,1.758A1,1,0,0,0,20,1H4a1,1,0,0,0-.97.758L1.972,5.994A4,4,0,0,0,2.7,9.45ZM13,21H11V16h2Zm6,0H15V15a1,1,0,0,0-1-1H10a1,1,0,0,0-1,1v6H5V10.9A3.989,3.989,0,0,0,8.914,9.61c.026.03.053.059.08.089A4.086,4.086,0,0,0,12.041,11a4.039,4.039,0,0,0,2.965-1.3c.027-.03.054-.059.08-.089A3.989,3.989,0,0,0,19,10.9ZM3.911,6.479,4.781,3H19.219l.87,3.479A2.029,2.029,0,0,1,18.12,9,2.041,2.041,0,0,1,16.1,7.14l-.042-.5a1,1,0,0,0-1.993.166v0a2.006,2.006,0,0,1-.529,1.539A2.059,2.059,0,0,1,11.959,9,2.029,2.029,0,0,1,9.937,6.806v0a1,1,0,0,0-.914-1.079.989.989,0,0,0-1.079.913l-.042.5A2.041,2.041,0,0,1,5.88,9,2.029,2.029,0,0,1,3.911,6.479Z" fill="url(#icon-application-marketplace-active_svg__a)" fill-rule="nonzero" />
+  </g>
+</svg>
\ No newline at end of file
diff --git a/client/packages/lowcoder-design/src/icons/icon-application-marketplace.svg b/client/packages/lowcoder-design/src/icons/icon-application-marketplace.svg
new file mode 100644
index 0000000000..4175130634
--- /dev/null
+++ b/client/packages/lowcoder-design/src/icons/icon-application-marketplace.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="20px" height="20px" viewBox="0 0 23 23" version="1.1" xmlns="http://www.w3.org/2000/svg">
+  <defs>
+    <linearGradient id="icon-application-marketplace_svg__a" x1="50%" y1="1.89576049%" x2="50%" y2="94.4251638%">
+      <stop stop-color="#5C6066" offset="0%"/>
+      <stop stop-color="#333740" offset="100%"/>
+    </linearGradient>
+    <linearGradient x1="50%" y1="1.89576049%" x2="50%" y2="94.4251638%">
+      <stop stop-color="#6D83F2" offset="0%"/>
+      <stop stop-color="#4965F2" offset="100%"/>
+    </linearGradient>
+  </defs>
+  <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+    <path d="M2.7,9.45a4.235,4.235,0,0,0,.3.3V22a1,1,0,0,0,1,1H20a1,1,0,0,0,1-1V9.752a4.235,4.235,0,0,0,.3-.3,4,4,0,0,0,.731-3.456L20.97,1.758A1,1,0,0,0,20,1H4a1,1,0,0,0-.97.758L1.972,5.994A4,4,0,0,0,2.7,9.45ZM13,21H11V16h2Zm6,0H15V15a1,1,0,0,0-1-1H10a1,1,0,0,0-1,1v6H5V10.9A3.989,3.989,0,0,0,8.914,9.61c.026.03.053.059.08.089A4.086,4.086,0,0,0,12.041,11a4.039,4.039,0,0,0,2.965-1.3c.027-.03.054-.059.08-.089A3.989,3.989,0,0,0,19,10.9ZM3.911,6.479,4.781,3H19.219l.87,3.479A2.029,2.029,0,0,1,18.12,9,2.041,2.041,0,0,1,16.1,7.14l-.042-.5a1,1,0,0,0-1.993.166v0a2.006,2.006,0,0,1-.529,1.539A2.059,2.059,0,0,1,11.959,9,2.029,2.029,0,0,1,9.937,6.806v0a1,1,0,0,0-.914-1.079.989.989,0,0,0-1.079.913l-.042.5A2.041,2.041,0,0,1,5.88,9,2.029,2.029,0,0,1,3.911,6.479Z" fill="url(#icon-application-marketplace_svg__a)" fill-rule="nonzero" />
+  </g>
+</svg>
\ No newline at end of file
diff --git a/client/packages/lowcoder-design/src/icons/index.ts b/client/packages/lowcoder-design/src/icons/index.ts
index 938cd1fc40..e9d141765f 100644
--- a/client/packages/lowcoder-design/src/icons/index.ts
+++ b/client/packages/lowcoder-design/src/icons/index.ts
@@ -176,11 +176,13 @@ export { ReactComponent as HomeModuleIcon } from "./icon-application-module.svg"
 export { ReactComponent as HomeQueryLibraryIcon } from "./icon-application-query-library.svg";
 export { ReactComponent as HomeDataSourceIcon } from "./icon-application-datasource.svg";
 export { ReactComponent as RecyclerIcon } from "./icon-application-recycler.svg";
+export { ReactComponent as MarketplaceIcon } from "./icon-application-marketplace.svg";
 export { ReactComponent as HomeActiveIcon } from "./icon-application-home-active.svg";
 export { ReactComponent as HomeModuleActiveIcon } from "./icon-application-module-active.svg";
 export { ReactComponent as HomeQueryLibraryActiveIcon } from "./icon-application-query-library-active.svg";
 export { ReactComponent as HomeDataSourceActiveIcon } from "./icon-application-datasource-active.svg";
 export { ReactComponent as RecyclerActiveIcon } from "./icon-application-recycler-active.svg";
+export { ReactComponent as MarketplaceActiveIcon } from "./icon-application-marketplace-active.svg";
 export { ReactComponent as FavoritesIcon } from "./icon-application-favorites.svg";
 export { ReactComponent as HomeSettingIcon } from "./icon-application-setting.svg";
 export { ReactComponent as FolderIcon } from "./icon-application-folder.svg";
diff --git a/client/packages/lowcoder/src/app.tsx b/client/packages/lowcoder/src/app.tsx
index 0e25e3a52e..8b3a944f7d 100644
--- a/client/packages/lowcoder/src/app.tsx
+++ b/client/packages/lowcoder/src/app.tsx
@@ -14,6 +14,7 @@ import {
   IMPORT_APP_FROM_TEMPLATE_URL,
   INVITE_LANDING_URL,
   isAuthUnRequired,
+  MARKETPLACE_URL,
   ORG_AUTH_LOGIN_URL,
   ORG_AUTH_REGISTER_URL,
   QUERY_LIBRARY_URL,
@@ -138,6 +139,7 @@ class AppIndex extends React.Component<AppIndexProps, any> {
                 FOLDER_URL,
                 TRASH_URL,
                 SETTING,
+                MARKETPLACE_URL,
               ]}
               // component={ApplicationListPage}
               component={ApplicationHome}
diff --git a/client/packages/lowcoder/src/constants/routesURL.ts b/client/packages/lowcoder/src/constants/routesURL.ts
index 8b7abb5ee0..1c21036ab2 100644
--- a/client/packages/lowcoder/src/constants/routesURL.ts
+++ b/client/packages/lowcoder/src/constants/routesURL.ts
@@ -21,6 +21,7 @@ export const ORGANIZATION_SETTING_DETAIL = `${ORGANIZATION_SETTING}/:orgId`;
 
 export const ALL_APPLICATIONS_URL = "/apps";
 export const MODULE_APPLICATIONS_URL = "/apps/module";
+export const MARKETPLACE_URL = `/marketplace`;
 export const DATASOURCE_URL = `/datasource`;
 export const DATASOURCE_CREATE_URL = `${DATASOURCE_URL}/new/:datasourceType`;
 export const DATASOURCE_EDIT_URL = `${DATASOURCE_URL}/:datasourceId`;
diff --git a/client/packages/lowcoder/src/i18n/locales/de.ts b/client/packages/lowcoder/src/i18n/locales/de.ts
index b30fead70c..defca35301 100644
--- a/client/packages/lowcoder/src/i18n/locales/de.ts
+++ b/client/packages/lowcoder/src/i18n/locales/de.ts
@@ -2053,6 +2053,7 @@ export const de = {
       "modules": "Module",
       "module": "Modul",
       "trash": "Papierkorb",
+      "marketplace": "Marktplatz",
       "queryLibrary": "Abfragebibliothek",
       "datasource": "Datenquellen",
       "selectDatasourceType": "Datenquellentyp auswählen",
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index 74b2296b9b..9d59f83dfa 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -2236,6 +2236,7 @@ export const en = {
     "modules": "Modules",
     "module": "Module",
     "trash": "Trash",
+    "marketplace": "Marketplace",
     "queryLibrary": "Query Library",
     "datasource": "Data Sources",
     "selectDatasourceType": "Select Data Source Type",
diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts
index 28194e00f0..b2df346d36 100644
--- a/client/packages/lowcoder/src/i18n/locales/zh.ts
+++ b/client/packages/lowcoder/src/i18n/locales/zh.ts
@@ -2120,6 +2120,7 @@ home: {
     modules: "模块",
     module: "模块",
     trash: "回收站",
+    marketplace: "市场",
     queryLibrary: "查询管理",
     datasource: "数据源",
     selectDatasourceType: "选择数据源类型",
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx
new file mode 100644
index 0000000000..d518250d1c
--- /dev/null
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx
@@ -0,0 +1,35 @@
+import { useEffect, useState } from "react";
+import { useDispatch, useSelector } from "react-redux";
+import { HomeLayout } from "./HomeLayout";
+import { MARKETPLACE_URL } from "constants/routesURL";
+import { marketplaceSelector } from "redux/selectors/applicationSelector";
+import { fetchAllMarketplaceApps } from "redux/reduxActions/applicationActions";
+import { trans } from "../../i18n";
+
+export function MarketplaceView() {
+  const [haveFetchedApps, setHaveFetchApps] = useState<boolean>(false);
+
+  const dispatch = useDispatch();
+  const marketplaceApps = useSelector(marketplaceSelector);
+
+  useEffect(() => {
+    if (!marketplaceApps.length && !haveFetchedApps) {
+      dispatch(fetchAllMarketplaceApps());
+      setHaveFetchApps(true);
+    }
+  }, []);
+
+  useEffect(() => {
+    if (marketplaceApps.length) {
+      setHaveFetchApps(true);
+    }
+  }, [marketplaceApps])
+
+  return (
+    <HomeLayout
+      elements={marketplaceApps}
+      breadcrumb={[{ text: trans("home.marketplace"), path: MARKETPLACE_URL }]}
+      mode={"marketplace"}
+    />
+  );
+};
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
index 7e24d5eee6..a9525298b7 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
@@ -4,6 +4,7 @@ import {
   FOLDER_URL,
   FOLDER_URL_PREFIX,
   FOLDERS_URL,
+  MARKETPLACE_URL,
   MODULE_APPLICATIONS_URL,
   QUERY_LIBRARY_URL,
   SETTING,
@@ -30,6 +31,8 @@ import {
   PointIcon,
   RecyclerActiveIcon,
   RecyclerIcon,
+  MarketplaceIcon,
+  MarketplaceActiveIcon,
 } from "lowcoder-design";
 import React, { useEffect, useState } from "react";
 import { fetchAllApplications, fetchHomeData } from "redux/reduxActions/applicationActions";
@@ -44,6 +47,7 @@ import styled, { css } from "styled-components";
 import history from "../../util/history";
 import { FolderView } from "./FolderView";
 import { TrashView } from "./TrashView";
+import { MarketplaceView } from "./MarketplaceView";
 import { SideBarItemType } from "../../components/layout/SideBarSection";
 import { RootFolderListView } from "./RootFolderListView";
 import InviteDialog from "../common/inviteDialog";
@@ -411,6 +415,19 @@ export default function ApplicationHome() {
                 visible: ({ user }) => user.orgDev,
                 onSelected: (_, currentPath) => currentPath.split("/")[1] === "datasource",
               },
+              {
+                text: <TabLabel>{trans("home.marketplace")}</TabLabel>,
+                routePath: MARKETPLACE_URL,
+                routePathExact: false,
+                routeComp: MarketplaceView,
+                icon: ({ selected, ...otherProps }) =>
+                  selected ? (
+                    <MarketplaceActiveIcon {...otherProps} />
+                  ) : (
+                    <MarketplaceIcon {...otherProps} />
+                  ),
+                visible: ({ user }) => user.orgDev,
+              },
               {
                 text: <TabLabel>{trans("settings.title")}</TabLabel>,
                 routePath: SETTING,

From 606a9d17d797b8be35659decf27ac2cd2d156679 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Wed, 21 Feb 2024 18:42:44 +0500
Subject: [PATCH 68/97] update app editor to view marketplace app

---
 .../src/pages/ApplicationV2/HomeLayout.tsx    | 18 +++---
 .../src/pages/ApplicationV2/HomeResCard.tsx   |  8 +++
 .../src/pages/ApplicationV2/HomeTableView.tsx |  5 ++
 .../src/pages/common/headerStartDropdown.tsx  | 61 +++++++++++--------
 .../src/pages/common/previewHeader.tsx        | 20 +++++-
 .../lowcoder/src/pages/editor/AppEditor.tsx   |  2 +-
 .../lowcoder/src/util/homeResUtils.tsx        |  2 +
 client/packages/lowcoder/src/util/hooks.ts    |  2 +-
 8 files changed, 81 insertions(+), 37 deletions(-)

diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
index fde596953d..b18b944f70 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
@@ -238,11 +238,12 @@ export interface HomeRes {
   isEditable?: boolean;
   isManageable: boolean;
   isDeletable: boolean;
+  isMarketplace?: boolean;
 }
 
 export type HomeBreadcrumbType = { text: string; path: string };
 
-export type HomeLayoutMode = "view" | "trash" | "module" | "folder" | "folders";
+export type HomeLayoutMode = "view" | "trash" | "module" | "folder" | "folders" | "marketplace";
 
 export interface HomeLayoutProps {
   breadcrumb?: HomeBreadcrumbType[];
@@ -306,11 +307,12 @@ export function HomeLayout(props: HomeLayoutProps) {
             id: e.applicationId,
             name: e.name,
             type: HomeResTypeEnum[HomeResTypeEnum[e.applicationType] as HomeResKey],
-            creator: e.createBy,
+            creator: e?.creatorEmail ?? e.createBy,
             lastModifyTime: e.lastModifyTime,
-            isEditable: canEditApp(user, e),
-            isManageable: canManageApp(user, e),
-            isDeletable: canEditApp(user, e),
+            isEditable: mode !== 'marketplace' && canEditApp(user, e),
+            isManageable: mode !== 'marketplace' && canManageApp(user, e),
+            isDeletable: mode !== 'marketplace' && canEditApp(user, e),
+            isMarketplace: mode === 'marketplace',
           }
     );
 
@@ -387,7 +389,7 @@ export function HomeLayout(props: HomeLayoutProps) {
             onChange={(e) => setSearchValue(e.target.value)}
             style={{ width: "192px", height: "32px", margin: "0" }}
           />
-          {mode !== "trash" && user.orgDev && (
+          {mode !== "trash" && mode !== "marketplace" && user.orgDev && (
             <CreateDropdown defaultVisible={showNewUserGuide(user)} mode={mode} />
           )}
         </OperationRightWrapper>
@@ -421,11 +423,13 @@ export function HomeLayout(props: HomeLayoutProps) {
                 <div style={{ marginBottom: "16px" }}>
                   {mode === "trash"
                     ? trans("home.trashEmpty")
+                    : mode === "marketplace"
+                    ? "No apps in marketplace yet"
                     : user.orgDev
                     ? trans("home.projectEmptyCanAdd")
                     : trans("home.projectEmpty")}
                 </div>
-                {mode !== "trash" && user.orgDev && <CreateDropdown mode={mode} />}
+                {mode !== "trash" && mode !== "marketplace" && user.orgDev && <CreateDropdown mode={mode} />}
               </EmptyView>
             )}
           </>
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx
index 26c97eb30d..32e2258ed8 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx
@@ -11,6 +11,7 @@ import {
   handleAppEditClick,
   handleAppViewClick,
   handleFolderViewClick,
+  handleMarketplaceAppViewClick,
   HomeResInfo,
 } from "../../util/homeResUtils";
 import { HomeResOptions } from "./HomeResOptions";
@@ -167,6 +168,7 @@ export function HomeResCard(props: { res: HomeRes; onMove: (res: HomeRes) => voi
         )}
         <CardInfo
           onClick={(e) => {
+            console.log(res.isMarketplace);
             if (appNameEditing) {
               return;
             }
@@ -177,6 +179,10 @@ export function HomeResCard(props: { res: HomeRes; onMove: (res: HomeRes) => voi
                 history.push(APPLICATION_VIEW_URL(res.id, "view"));
                 return;
               }
+              if(res.isMarketplace) {
+                handleMarketplaceAppViewClick(res.id);
+                return;
+              }
               res.isEditable ? handleAppEditClick(e, res.id) : handleAppViewClick(res.id);
             }
           }}
@@ -211,6 +217,8 @@ export function HomeResCard(props: { res: HomeRes; onMove: (res: HomeRes) => voi
             onClick={() =>
               res.type === HomeResTypeEnum.Folder
                 ? handleFolderViewClick(res.id)
+                : res.isMarketplace
+                ? handleMarketplaceAppViewClick(res.id)
                 : handleAppViewClick(res.id)
             }
           >
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx
index 4a76939ee6..aa767250c1 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx
@@ -7,6 +7,7 @@ import {
   handleAppEditClick,
   handleAppViewClick,
   handleFolderViewClick,
+  handleMarketplaceAppViewClick,
   HomeResInfo,
 } from "../../util/homeResUtils";
 import { HomeResTypeEnum } from "../../types/homeRes";
@@ -75,6 +76,8 @@ export const HomeTableView = (props: { resources: HomeRes[] }) => {
             }
             if (item.type === HomeResTypeEnum.Folder) {
               handleFolderViewClick(item.id);
+            } else if(item.isMarketplace) {
+              handleMarketplaceAppViewClick(item.id);
             } else {
               item.isEditable ? handleAppEditClick(e, item.id) : handleAppViewClick(item.id);
             }
@@ -209,6 +212,8 @@ export const HomeTableView = (props: { resources: HomeRes[] }) => {
                       e.stopPropagation();
                       return item.type === HomeResTypeEnum.Folder
                         ? handleFolderViewClick(item.id)
+                        : item.isMarketplace
+                        ? handleMarketplaceAppViewClick(item.id)
                         : handleAppViewClick(item.id);
                     }}
                     style={{ marginRight: "52px" }}
diff --git a/client/packages/lowcoder/src/pages/common/headerStartDropdown.tsx b/client/packages/lowcoder/src/pages/common/headerStartDropdown.tsx
index eefa27800b..1ea2836908 100644
--- a/client/packages/lowcoder/src/pages/common/headerStartDropdown.tsx
+++ b/client/packages/lowcoder/src/pages/common/headerStartDropdown.tsx
@@ -11,7 +11,7 @@ import {
 } from "lowcoder-design";
 import { trans, transToNode } from "i18n";
 import { exportApplicationAsJSONFile } from "pages/ApplicationV2/components/AppImport";
-import { useContext, useState } from "react";
+import { useContext, useMemo, useState } from "react";
 import { useDispatch, useSelector } from "react-redux";
 import { currentApplication } from "redux/selectors/applicationSelector";
 import { showAppSnapshotSelector } from "redux/selectors/appSnapshotSelector";
@@ -23,6 +23,8 @@ import { recycleApplication } from "redux/reduxActions/applicationActions";
 import { CopyModal } from "./copyModal";
 import { ExternalEditorContext } from "util/context/ExternalEditorContext";
 import { messageInstance } from "lowcoder-design";
+import { getUser } from "redux/selectors/usersSelectors";
+import { canEditApp } from "util/permissionUtils";
 
 const PackUpIconStyled = styled(PackUpIcon)`
   transform: rotate(180deg);
@@ -68,6 +70,7 @@ export const TypeName = {
 };
 
 export function HeaderStartDropdown(props: { setEdit: () => void }) {
+  const user = useSelector(getUser);
   const showAppSnapshot = useSelector(showAppSnapshotSelector);
   const applicationId = useApplicationId();
   const application = useSelector(currentApplication);
@@ -76,6 +79,37 @@ export function HeaderStartDropdown(props: { setEdit: () => void }) {
   const { appType } = useContext(ExternalEditorContext);
   const isModule = appType === AppTypeEnum.Module;
 
+  const isEditable = canEditApp(user, application);
+
+  const menuItems = useMemo(() => ([
+    {
+      key: "edit",
+      label: <CommonTextLabel>{trans("header.editName")}</CommonTextLabel>,
+      visible: isEditable,
+    },
+    {
+      key: "export",
+      label: <CommonTextLabel>{trans("header.export")}</CommonTextLabel>,
+      visible: true,
+    },
+    {
+      key: "duplicate",
+      label: (
+        <CommonTextLabel>
+          {trans("header.duplicate", {
+            type: TypeName[application?.applicationType!]?.toLowerCase(),
+          })}
+        </CommonTextLabel>
+      ),
+      visible: true,
+    },
+    {
+      key: "delete",
+      label: <CommonTextLabelDelete>{trans("home.moveToTrash")}</CommonTextLabelDelete>,
+      visible: isEditable,
+    },
+  ]), [isEditable]);
+
   return (
     <>
       <DropdownStyled
@@ -115,30 +149,7 @@ export function HeaderStartDropdown(props: { setEdit: () => void }) {
                 });
               }
             }}
-            items={[
-              {
-                key: "edit",
-                label: <CommonTextLabel>{trans("header.editName")}</CommonTextLabel>,
-              },
-              {
-                key: "export",
-                label: <CommonTextLabel>{trans("header.export")}</CommonTextLabel>,
-              },
-              {
-                key: "duplicate",
-                label: (
-                  <CommonTextLabel>
-                    {trans("header.duplicate", {
-                      type: TypeName[application?.applicationType!]?.toLowerCase(),
-                    })}
-                  </CommonTextLabel>
-                ),
-              },
-              {
-                key: "delete",
-                label: <CommonTextLabelDelete>{trans("home.moveToTrash")}</CommonTextLabelDelete>,
-              },
-            ]}
+            items={menuItems.filter(item => item.visible)}
           />
         )}
       >
diff --git a/client/packages/lowcoder/src/pages/common/previewHeader.tsx b/client/packages/lowcoder/src/pages/common/previewHeader.tsx
index 507330cbf2..85ae198d65 100644
--- a/client/packages/lowcoder/src/pages/common/previewHeader.tsx
+++ b/client/packages/lowcoder/src/pages/common/previewHeader.tsx
@@ -17,6 +17,9 @@ import { Logo } from "@lowcoder-ee/assets/images";
 import { AppPermissionDialog } from "../../components/PermissionDialog/AppPermissionDialog";
 import { useState } from "react";
 import { getBrandingConfig } from "../../redux/selectors/configSelectors";
+import { HeaderStartDropdown } from "./headerStartDropdown";
+import { useParams } from "react-router";
+import { AppPathParams } from "constants/applicationConstants";
 
 const HeaderFont = styled.div<{ $bgColor: string }>`
   font-weight: 500;
@@ -125,21 +128,32 @@ export function HeaderProfile(props: { user: User }) {
 }
 
 export const PreviewHeader = () => {
+  const params = useParams<AppPathParams>();
   const user = useSelector(getUser);
   const application = useSelector(currentApplication);
   const applicationId = useApplicationId();
   const templateId = useSelector(getTemplateId);
   const brandingConfig = useSelector(getBrandingConfig);
   const [permissionDialogVisible, setPermissionDialogVisible] = useState(false);
+  const isViewMarketplaceMode = params.viewMode === 'view_marketplace';
 
   const headerStart = (
     <>
       <StyledLink onClick={() => history.push(ALL_APPLICATIONS_URL)}>
         <LogoIcon branding={true} />
       </StyledLink>
-      <HeaderFont $bgColor={brandingConfig?.headerColor ?? "#2c2c2c"}>
-        {application && application.name}
-      </HeaderFont>
+      {isViewMarketplaceMode && (
+        <HeaderStartDropdown
+          setEdit={() => {
+            
+          }}
+        />
+      )}
+      {!isViewMarketplaceMode && (
+        <HeaderFont $bgColor={brandingConfig?.headerColor ?? "#2c2c2c"}>
+          {application && application.name}
+        </HeaderFont>
+      )}
     </>
   );
 
diff --git a/client/packages/lowcoder/src/pages/editor/AppEditor.tsx b/client/packages/lowcoder/src/pages/editor/AppEditor.tsx
index 05d5c4a088..c1d241a0ae 100644
--- a/client/packages/lowcoder/src/pages/editor/AppEditor.tsx
+++ b/client/packages/lowcoder/src/pages/editor/AppEditor.tsx
@@ -33,7 +33,7 @@ export default function AppEditor() {
   const isUserViewMode = useUserViewMode();
   const params = useParams<AppPathParams>();
   const applicationId = params.applicationId;
-  const viewMode = params.viewMode === "view" ? "published" : "editing";
+  const viewMode = params.viewMode === "view" ? "published" : params.viewMode === "view_marketplace" ? "view_marketplace" : "editing";
   const currentUser = useSelector(getUser);
   const dispatch = useDispatch();
   const fetchOrgGroupsFinished = useSelector(getFetchOrgGroupsFinished);
diff --git a/client/packages/lowcoder/src/util/homeResUtils.tsx b/client/packages/lowcoder/src/util/homeResUtils.tsx
index 2c37817d94..8f7e1dfe8f 100644
--- a/client/packages/lowcoder/src/util/homeResUtils.tsx
+++ b/client/packages/lowcoder/src/util/homeResUtils.tsx
@@ -58,4 +58,6 @@ export const handleAppEditClick = (e: any, id: string): void => {
 
 export const handleAppViewClick = (id: string) => window.open(APPLICATION_VIEW_URL(id, "view"));
 
+export const handleMarketplaceAppViewClick = (id: string) => window.open(APPLICATION_VIEW_URL(id, "view_marketplace"));
+
 export const handleFolderViewClick = (id: string) => history.push(buildFolderUrl(id));
diff --git a/client/packages/lowcoder/src/util/hooks.ts b/client/packages/lowcoder/src/util/hooks.ts
index 67e3971840..ca67a902f1 100644
--- a/client/packages/lowcoder/src/util/hooks.ts
+++ b/client/packages/lowcoder/src/util/hooks.ts
@@ -25,7 +25,7 @@ export function isUserViewMode(params?: AppPathParams) {
     return false;
   }
   const { viewMode } = params;
-  return viewMode === "preview" || viewMode === "view";
+  return viewMode === "preview" || viewMode === "view" || viewMode === "view_marketplace";
 }
 
 /**

From 61c166b0ee1a8aeabddda10566589d0d24317459 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Wed, 21 Feb 2024 18:49:34 +0500
Subject: [PATCH 69/97] checkbox/radio fix

---
 .../src/comps/comps/selectInputComp/segmentedControl.tsx        | 1 -
 .../src/comps/comps/selectInputComp/selectInputConstants.tsx    | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/segmentedControl.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/segmentedControl.tsx
index 6c82fd62bb..156c837990 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/segmentedControl.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/segmentedControl.tsx
@@ -79,7 +79,6 @@ const SegmentedControlBasicComp = (function () {
   return new UICompBuilder(SegmentChildrenMap, (props) => {
     const [
       validateState,
-      handleValidate,
       handleChange,
     ] = useSelectInputValidate(props);
     return props.label({
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectInputConstants.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectInputConstants.tsx
index 7c4fdc1268..c69c356055 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectInputConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectInputConstants.tsx
@@ -91,7 +91,7 @@ export const useSelectInputValidate = (props: ValidationParams) => {
 
   return [
     validateState,
-    handleValidate,
+    // handleValidate,
     handleChange,
   ] as const;
 };

From a05565641865638af180f5ce36571dcdf86e3b43 Mon Sep 17 00:00:00 2001
From: Imtanan Aziz Toor <imtanan.aziz@ikhwatech.com>
Date: Wed, 21 Feb 2024 20:21:33 +0500
Subject: [PATCH 70/97] Creating function that helps to replace style from
 common style array with special array of styles, so individual styles of a
 component also can be handled, progress bar component updated

---
 .../lowcoder/src/comps/comps/progressComp.tsx |  3 ++
 .../comps/controls/styleControlConstants.tsx  | 33 +++++++++++--------
 2 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/progressComp.tsx b/client/packages/lowcoder/src/comps/comps/progressComp.tsx
index 1acf7f2d6a..76c5f4aef8 100644
--- a/client/packages/lowcoder/src/comps/comps/progressComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/progressComp.tsx
@@ -18,6 +18,9 @@ const getStyle = (style: ProgressStyleType) => {
     line-height: 2;
     .ant-progress-text {
       color: ${style.text};
+      font-style:${style.fontStyle};
+        font-family:${style.fontFamily};
+        font-weight:${style.textWeight};
     }
     width: ${widthCalculator(style.margin)};	
     height: ${heightCalculator(style.margin)};	
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index 347c7ede3d..9c45f893ab 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -460,6 +460,21 @@ function getStaticBackground(color: string) {
   } as const;
 }
 
+
+function replaceAndMergeMultipleStyles(originalArray: any[], styleToReplace: string, replacingStyles: any[]): any[] {
+  let temp = []
+  let foundIndex = originalArray.findIndex((element) => element.name === styleToReplace)
+
+  if (foundIndex !== -1) {
+    let elementsBeforeFoundIndex = originalArray.filter((item, index) => index < foundIndex)
+    let elementsAfterFoundIndex = originalArray.filter((item, index) => index > foundIndex)
+    temp = [...elementsBeforeFoundIndex, ...replacingStyles, ...elementsAfterFoundIndex]
+  } else
+    temp = [...originalArray]
+
+  return temp
+}
+
 export const ButtonStyle = [
   ...getBgBorderRadiusByBg("primary"),
   ...STYLING_FIELDS_SEQUENCE
@@ -674,14 +689,6 @@ export const SliderStyle = [
 export const InputLikeStyle = [
   LABEL,
   getStaticBackground(SURFACE_COLOR),
-  // TEXT,
-  // TEXT_SIZE,
-  // TEXT_WEIGHT,
-  // FONT_FAMILY,
-  // FONT_STYLE,
-  // MARGIN,
-  // PADDING,
-  // BORDER_WIDTH,
   ...STYLING_FIELDS_SEQUENCE,
   ...ACCENT_VALIDATE,
 ] as const;
@@ -1047,8 +1054,7 @@ export const LinkStyle = [
     depType: DEP_TYPE.SELF,
     transformer: toSelf,
   },
-  ...LinkTextStyle,
-  ...STYLING_FIELDS_SEQUENCE.filter((style) => style.name !== 'text')
+  ...replaceAndMergeMultipleStyles(STYLING_FIELDS_SEQUENCE, 'text', [...LinkTextStyle])
 ] as const;
 
 export const DividerStyle = [
@@ -1070,19 +1076,18 @@ export const DividerStyle = [
   })
 ] as const;
 
+// Hidden border and borderWidth properties as AntD doesnt allow these properties for progress bar
 export const ProgressStyle = [
-  {
+  ...replaceAndMergeMultipleStyles(STYLING_FIELDS_SEQUENCE, 'text', [{
     name: "text",
     label: trans("text"),
     depTheme: "canvas",
     depType: DEP_TYPE.CONTRAST_TEXT,
     transformer: contrastText,
-  },
+  }]).filter((style)=> ['border','borderWidth'].includes(style.name) === false),
   TRACK,
   FILL,
   SUCCESS,
-  MARGIN,
-  PADDING,
 ] as const;
 
 export const NavigationStyle = [

From 82c3de8565f9febaceff5aafa1d27860928f94dd Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Thu, 22 Feb 2024 09:15:45 +0100
Subject: [PATCH 71/97] Fix Lowcocer Comps Documentation

---
 client/packages/lowcoder-comps/README.md    | 105 ++++++++++++++++++--
 client/packages/lowcoder-comps/package.json |   2 +-
 2 files changed, 100 insertions(+), 7 deletions(-)

diff --git a/client/packages/lowcoder-comps/README.md b/client/packages/lowcoder-comps/README.md
index 7c74d491a9..15f56dc46a 100644
--- a/client/packages/lowcoder-comps/README.md
+++ b/client/packages/lowcoder-comps/README.md
@@ -1,22 +1,100 @@
-# lowcoder comp lib
+# Lowcoder Extra Components
+
+This is the workspace for Lowcoder Extra Components like Calendar, Image Editor, Mermaid Charts and eCharts.
+
+## Local Development preparation
+
+Navigate your terminal or bash to your /root folder (lowcoder repository) to install Lowcoder Extra Components dependencies and the Lowcoder SDK
+
+To develop with the Lowcoder Extra Components after you clone the Lowcoder Repository, first make sure the Lowcoder SDK is local built.
+
+```bash
+cd client/packages/lowcoder-sdk
+yarn build
+```
 
 ## Start
 
-Start dev server to develop your comp lib.
+Now you can start the local dev server for Lowcoder Extra Components to develop and add your Component Plugin
 
 ```bash
+cd client/packages/lowcoder-comps
 yarn start
+```
 
-# or
+The local dev server will build for roughly a minute and open then a Browser Window on http://localhost:9000/ with the Lowcoder Component Builder. 
+
+## Local development
+
+After the local dev server is started, the Lowcoder Component Builder is prepared. A new browser window should open at http://localhost:9000 This is the Components Preview, which allows you to see your new component in action, as it would work in the Lowcoder Editor.
+
+Data, methods and properties are visible and interactive, so you can test your Component during development. The view will get automatically refreshed.
+
+The Lowcoder Component Builder makes the development & publishing of multiple individual components as bundle possible. Find the /src/comps folder in /lowcoder-comps. Here are existing components to find. It is suggested for new components to create a new folder. In the left navigation of the Components Preview you can switch between your components.
+
+to see your component and include it in the processing on the development server, you have to do the folloiwing steps:
+
+### modify /lowcoder-comps/package.json
+
+```JSON
+"yournewcomponent": {
+    "name": "Your new Component name",
+    "icon": "./icons/your-icon.svg",
+    "description": "A Component Plugin to ...",
+    "category": "itemHandling",
+    "layoutInfo": {
+        "w": 6,
+        "h": 30
+    }
+}
+```
 
-npm start
+
+Please choose one category out of:
+
+ - dashboards
+ - layout
+ - forms
+ - collaboration
+ - projectmanagement
+ - scheduling
+ - documents
+ - itemHandling
+ - multimedia
+ - integration
+
+layoutInfo helps you to define the size (in grid-cells) of your Component in the grid for the very first moment, when a user drags your Component out of the components display on the right side in the Lowcoder Editor.
+
+### modify /lowcoder-comps/src/index.ts
+
+```JavaScript
+Add your Component for the exported members of Lowcoder Extra Components 
+
+import { ChartCompWithDefault } from "./comps/chartComp/chartComp";
+import { ImageEditorComp } from "./comps/imageEditorComp/index";
+import { CalendarComp } from "./comps/calendarComp/calendarComp";
+import { MermaidComp } from "comps/mermaidComp";
+
+import { YourComponent } from "comps/yourComponentFolder/yourComponent";
+
+export default {
+  chart: ChartCompWithDefault,
+  imageEditor: ImageEditorComp,
+  calendar: CalendarComp,
+  mermaid: MermaidComp,
+
+  yourcomponent: YourComponent,
+};
 ```
+Now your Plugin should be visibe and displayed in the Lowcoder Component Builder at http://localhost:9000/
 
 ## Build
 
-Build current comp lib into a .tgz file that you can upload it to the Lowcoder Comp Market.
+When you finish development and all tests, you can build the Components to use it in runtime.
 
-Before build you should change the version in package.json file.
+This will build the current Component Plugins into a .tgz file that you can upload.
+
+**Before build you should change the version in package.json file.**
 
 ```bash
 yarn build
@@ -25,3 +103,18 @@ yarn build
 
 npm run build
 ```
+
+## How to publish a Component Plugin
+
+With the following command you can publish the script to the NPM repository:
+
+```bash
+yarn build --publish
+```
+
+This command will publis the whole Lowcoder Extra Components bundle to [NPMjs](https://www.npmjs.com/)
+Make sure, you updated the Version of Lowcoder Comps before in /lowcoder-comps/package.json
+
+## Contribute your Plugin
+
+If you wish to contribute your plugin and persist it as general Lowcoder Extra Component, please raise a PR to our /dev branch in the Lowcoder Community-Edition Repository https://github.com/lowcoder-org/lowcoder
\ No newline at end of file
diff --git a/client/packages/lowcoder-comps/package.json b/client/packages/lowcoder-comps/package.json
index 1bf1dae929..43386ccf9c 100644
--- a/client/packages/lowcoder-comps/package.json
+++ b/client/packages/lowcoder-comps/package.json
@@ -69,7 +69,7 @@
   },
   "devDependencies": {
     "jest": "29.3.0",
-    "vite": "^4.5.2",
+    "vite": "^5.0.12",
     "vite-tsconfig-paths": "^3.6.0"
   }
 }

From f556fa7aa07061d9068eeb624d7ced4c51524f03 Mon Sep 17 00:00:00 2001
From: Imtanan Aziz Toor <imtanan.aziz@ikhwatech.com>
Date: Thu, 22 Feb 2024 13:28:18 +0500
Subject: [PATCH 72/97] nav component issue fixes, component updates in
 progress

---
 .../src/comps/comps/buttonComp/linkComp.tsx   |  4 +-
 .../src/comps/comps/navComp/navComp.tsx       | 20 +++++---
 .../comps/comps/textInputComp/mentionComp.tsx | 12 ++++-
 .../comps/controls/styleControlConstants.tsx  | 50 ++++++++++++-------
 4 files changed, 58 insertions(+), 28 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx
index 1d41ad3345..cbd5b26b21 100644
--- a/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx
@@ -33,6 +33,7 @@ const Link = styled(Button) <{ $style: LinkStyleType }>`
     font-family:${props.$style.fontFamily};
     font-weight:${props.$style.textWeight};
     border: ${props.$style.borderWidth} solid ${props.$style.border};
+    border-radius:${props.$style.radius ? props.$style.radius:'0px'};
     background-color: ${props.$style.background};
     &:hover {
       color: ${props.$style.hoverText} !important;
@@ -41,7 +42,8 @@ const Link = styled(Button) <{ $style: LinkStyleType }>`
       color: ${props.$style.activeText} !important;
     }
   `}
-  &.ant-btn {
+
+  &.ant-btn { 
     display: inline-flex;
     align-items: center;
     > span {
diff --git a/client/packages/lowcoder/src/comps/comps/navComp/navComp.tsx b/client/packages/lowcoder/src/comps/comps/navComp/navComp.tsx
index c5eedea6f7..44b782b476 100644
--- a/client/packages/lowcoder/src/comps/comps/navComp/navComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/navComp/navComp.tsx
@@ -24,18 +24,19 @@ type IProps = {
   $bgColor: string;
   $borderColor: string;
   $borderWidth: string;
+  $borderRadius: string;
 };
 
-const Wrapper = styled("div") <Pick<IProps, "$bgColor" | "$borderColor" | "$borderWidth">>`
+const Wrapper = styled("div") <Pick<IProps, "$bgColor" | "$borderColor" | "$borderWidth" | "$borderRadius">>`
   height: 100%;
-  border-radius: 2px;
+  border-radius: ${(props) => props.$borderRadius ? props.$borderRadius : '2px'};
   box-sizing: border-box;
   border: ${(props) => props.$borderWidth ? `${props.$borderWidth}` : '1px'} solid ${(props) => props.$borderColor};
   background-color: ${(props) => props.$bgColor};
 `;
 
 const NavInner = styled("div") <Pick<IProps, "$justify">>`
-  margin: 0 -16px;
+  // margin: 0 -16px;
   height: 100%;
   display: flex;
   justify-content: ${(props) => (props.$justify ? "space-between" : "left")};
@@ -49,17 +50,19 @@ const Item = styled.div<{
   $fontStyle: string;
   $textWeight: string;
   $textSize: string;
+  $margin: string;
+  $padding: string;
 }>`
   height: 30px;
   line-height: 30px;
-  padding: 0 16px;
+  padding: ${(props) => props.$padding ? props.$padding : '0 16px'};
   color: ${(props) => (props.$active ? props.$activeColor : props.$color)};
   font-weight: ${(props) => (props.$textWeight ? props.$textWeight : 500)};
   font-family:${(props) => (props.$fontFamily ? props.$fontFamily : 'sans-serif')};
   font-style:${(props) => (props.$fontStyle ? props.$fontStyle : 'normal')};
-  font-size:${(props) => (props.$textSize ? props.$textSize : '14px')}
-
-
+  font-size:${(props) => (props.$textSize ? props.$textSize : '14px')};
+  margin:${(props) => props.$margin ? props.$margin : '0px'};
+  
   &:hover {
     color: ${(props) => props.$activeColor};
     cursor: pointer;
@@ -157,6 +160,8 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
             $fontStyle={props.style.fontStyle}
             $textWeight={props.style.textWeight}
             $textSize={props.style.textSize}
+            $padding={props.style.padding}
+            $margin={props.style.margin}
             onClick={() => onEvent("click")}
           >
             {label}
@@ -195,6 +200,7 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
       $borderColor={props.style.border}
       $bgColor={props.style.background}
       $borderWidth={props.style.borderWidth}
+      $borderRadius={props.style.borderRadius}
     >
       <NavInner $justify={justify}>
         {props.logoUrl && (
diff --git a/client/packages/lowcoder/src/comps/comps/textInputComp/mentionComp.tsx b/client/packages/lowcoder/src/comps/comps/textInputComp/mentionComp.tsx
index 28051a0676..c760e054bb 100644
--- a/client/packages/lowcoder/src/comps/comps/textInputComp/mentionComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/textInputComp/mentionComp.tsx
@@ -192,7 +192,17 @@ let MentionTmpComp = (function () {
                 label: value,
               }))}
               autoSize={props.autoHeight}
-              style={{ height: "100%", maxHeight: "100%", resize: "none", padding: props.style.padding, fontStyle: props.style.fontStyle, fontFamily: props.style.fontFamily, borderWidth: props.style.borderWidth, fontWeight: props.style.textWeight }}
+              style={{
+                height: "100%",
+                maxHeight: "100%",
+                resize: "none",
+                padding: props.style.padding,
+                fontStyle: props.style.fontStyle,
+                fontFamily: props.style.fontFamily,
+                borderWidth: props.style.borderWidth,
+                fontWeight: props.style.textWeight,
+                fontSize: props.style.textSize
+              }}
               readOnly={props.readOnly}
             />
           </ConfigProvider>
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index 9c45f893ab..bd895a9610 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -476,7 +476,8 @@ function replaceAndMergeMultipleStyles(originalArray: any[], styleToReplace: str
 }
 
 export const ButtonStyle = [
-  ...getBgBorderRadiusByBg("primary"),
+  // ...getBgBorderRadiusByBg("primary"),
+  getBackground('primary'),
   ...STYLING_FIELDS_SEQUENCE
 ] as const;
 
@@ -1084,30 +1085,41 @@ export const ProgressStyle = [
     depTheme: "canvas",
     depType: DEP_TYPE.CONTRAST_TEXT,
     transformer: contrastText,
-  }]).filter((style)=> ['border','borderWidth'].includes(style.name) === false),
+  }]).filter((style) => ['border', 'borderWidth'].includes(style.name) === false),
   TRACK,
   FILL,
   SUCCESS,
 ] as const;
 
 export const NavigationStyle = [
-  {
-    name: "text",
-    label: trans("text"),
-    depName: "background",
-    depType: DEP_TYPE.CONTRAST_TEXT,
-    transformer: contrastText,
-  },
-  ACCENT,
-  getStaticBackground("#FFFFFF00"),
-  getStaticBorder("#FFFFFF00"),
-  MARGIN,
-  PADDING,
-  FONT_FAMILY,
-  FONT_STYLE,
-  TEXT_WEIGHT,
-  TEXT_SIZE,
-  BORDER_WIDTH
+  ...replaceAndMergeMultipleStyles(STYLING_FIELDS_SEQUENCE, 'text', [
+    {
+      name: "text",
+      label: trans("text"),
+      depName: "background",
+      depType: DEP_TYPE.CONTRAST_TEXT,
+      transformer: contrastText,
+    },
+    ACCENT,
+    getStaticBackground("#FFFFFF00")
+  ])
+  // {
+  //   name: "text",
+  //   label: trans("text"),
+  //   depName: "background",
+  //   depType: DEP_TYPE.CONTRAST_TEXT,
+  //   transformer: contrastText,
+  // },
+  // ACCENT,
+  // getStaticBackground("#FFFFFF00"),
+  // getStaticBorder("#FFFFFF00"),
+  // MARGIN,
+  // PADDING,
+  // FONT_FAMILY,
+  // FONT_STYLE,
+  // TEXT_WEIGHT,
+  // TEXT_SIZE,
+  // BORDER_WIDTH
 ] as const;
 
 export const ImageStyle = [getStaticBorder("#00000000"), RADIUS, BORDER_WIDTH, MARGIN, PADDING] as const;

From 8a630659ce1838e59d52f69f190e5afbd3c8d31f Mon Sep 17 00:00:00 2001
From: Imtanan Aziz Toor <imtanan.aziz@ikhwatech.com>
Date: Thu, 22 Feb 2024 13:34:24 +0500
Subject: [PATCH 73/97] Toggle button border Width fixes

---
 .../lowcoder/src/comps/comps/buttonComp/buttonCompConstants.tsx  | 1 +
 1 file changed, 1 insertion(+)

diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/buttonCompConstants.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/buttonCompConstants.tsx
index 0f60c7a2d2..e770014f71 100644
--- a/client/packages/lowcoder/src/comps/comps/buttonComp/buttonCompConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/buttonComp/buttonCompConstants.tsx
@@ -13,6 +13,7 @@ export function getButtonStyle(buttonStyle: ButtonStyleType) {
   return css`
     &&& {
       border-radius: ${buttonStyle.radius};
+      border-width:${buttonStyle.borderWidth};
       margin: ${buttonStyle.margin};	
       padding: ${buttonStyle.padding};
       &:not(:disabled) {

From 7b6dda61d674697061825301a1f3132394dc1986 Mon Sep 17 00:00:00 2001
From: Imtanan Aziz Toor <imtanan.aziz@ikhwatech.com>
Date: Thu, 22 Feb 2024 15:22:18 +0500
Subject: [PATCH 74/97] FOnt added for testing, circle progress and progress
 updated

---
 client/packages/lowcoder/index.html           |  4 ++++
 .../src/comps/comps/progressCircleComp.tsx    | 22 ++++++++++++-------
 .../lowcoder/src/comps/comps/progressComp.tsx |  1 +
 .../comps/controls/styleControlConstants.tsx  |  3 +++
 4 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/client/packages/lowcoder/index.html b/client/packages/lowcoder/index.html
index c83e225aab..038b31c384 100644
--- a/client/packages/lowcoder/index.html
+++ b/client/packages/lowcoder/index.html
@@ -7,6 +7,10 @@
     <meta name="theme-color" content="#000000" />
     <meta property="iframely:title" content="Lowcoder" />
     <meta property="iframely:description" content="Lowcoder | rapid App & VideoMeeting builder for everyone." />
+    <!-- Added Montserrat google font link to test font family style property for components -->
+    <link rel="preconnect" href="https://fonts.googleapis.com">
+    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+    <link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
     <style>
       html,
       body {
diff --git a/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx b/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx
index d7b29f6336..c39b391001 100644
--- a/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx
@@ -1,6 +1,6 @@
 import { default as Progress } from "antd/es/progress";
 import { styleControl } from "comps/controls/styleControl";
-import { ProgressStyle, ProgressStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
+import { CircleProgressStyle, CircleProgressType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
 import styled, { css } from "styled-components";
 import { Section, sectionNames } from "lowcoder-design";
 import { numberExposingStateControl } from "../controls/codeStateControl";
@@ -14,33 +14,38 @@ import { EditorContext } from "comps/editorState";
 
 // TODO: after Update of ANTd, introduce Size attribute to ProgressCircle
 
-const getStyle = (style: ProgressStyleType) => {
+const getStyle = (style: CircleProgressType) => {
   return css`
     width: ${widthCalculator(style.margin)};	
     height: ${heightCalculator(style.margin)};	
     margin: ${style.margin};	
     padding: ${style.padding};
+    border-radius:${style.radius};
     .ant-progress-text {
-      color: ${style.text};
+      color: ${style.text} !important;
+      font-family:${style.fontFamily};
+      font-style:${style.fontStyle};
+      font-size:${style.textSize} !important;
+      font-weight:${style.textWeight};
     }
     .ant-progress-circle-trail {
       stroke: ${style.track};
     }
     .ant-progress-inner .ant-progress-circle-path {
-      stroke: ${style.fill};
+      stroke: ${style.fill} !important;
     }
     &.ant-progress-status-success {
       .ant-progress-inner .ant-progress-circle-path {
-        stroke: ${style.success};
+        stroke: ${style.success} !important;
       }
       .ant-progress-text {
-        color: ${style.success};
+        color: ${style.success} !important;
       }
     }
   `;
 };
 
-export const StyledProgressCircle = styled(Progress)<{ $style: ProgressStyleType }>`
+export const StyledProgressCircle = styled(Progress) <{ $style: CircleProgressType }>`
   width: 100%;
   height: 100%;
   padding: 2px;
@@ -59,7 +64,8 @@ export const StyledProgressCircle = styled(Progress)<{ $style: ProgressStyleType
 let ProgressCircleTmpComp = (function () {
   const childrenMap = {
     value: numberExposingStateControl("value", 60),
-    style: styleControl(ProgressStyle),
+    // borderRadius property hidden as it's not valid for progress circle
+    style: styleControl(CircleProgressStyle),
   };
   return new UICompBuilder(childrenMap, (props) => {
     return (
diff --git a/client/packages/lowcoder/src/comps/comps/progressComp.tsx b/client/packages/lowcoder/src/comps/comps/progressComp.tsx
index 76c5f4aef8..9090fa2491 100644
--- a/client/packages/lowcoder/src/comps/comps/progressComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/progressComp.tsx
@@ -21,6 +21,7 @@ const getStyle = (style: ProgressStyleType) => {
       font-style:${style.fontStyle};
         font-family:${style.fontFamily};
         font-weight:${style.textWeight};
+        font-size:${style.textSize};
     }
     width: ${widthCalculator(style.margin)};	
     height: ${heightCalculator(style.margin)};	
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index bd895a9610..b8cab410ab 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -1091,6 +1091,8 @@ export const ProgressStyle = [
   SUCCESS,
 ] as const;
 
+export const CircleProgressStyle = [...ProgressStyle.filter((style) => style.name !== 'radius')]
+
 export const NavigationStyle = [
   ...replaceAndMergeMultipleStyles(STYLING_FIELDS_SEQUENCE, 'text', [
     {
@@ -1375,6 +1377,7 @@ export type DateTimeStyleType = StyleConfigType<typeof DateTimeStyle>;
 export type LinkStyleType = StyleConfigType<typeof LinkStyle>;
 export type DividerStyleType = StyleConfigType<typeof DividerStyle>;
 export type ProgressStyleType = StyleConfigType<typeof ProgressStyle>;
+export type CircleProgressType = StyleConfigType<typeof CircleProgressStyle>;
 export type NavigationStyleType = StyleConfigType<typeof NavigationStyle>;
 export type ImageStyleType = StyleConfigType<typeof ImageStyle>;
 export type ListViewStyleType = StyleConfigType<typeof ListViewStyle>;

From 4b94a7f138a1ac4814307b56cedaaa287578a1b9 Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Thu, 22 Feb 2024 15:25:44 +0500
Subject: [PATCH 75/97] Fix for conditional color for table's column

---
 .../lowcoder/src/comps/comps/tableComp/tableCompView.tsx        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
index 729e8f6b9c..d19586c6b5 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
@@ -517,7 +517,7 @@ function TableCellView(props: {
       columnTitle: title,
     });
     const cellColor = cellColorFn({
-      currentCell: record[title.toLowerCase()],
+      currentCell: record[title],
     });
     
     const style = {

From cac08a4e2c2655321d5ced9e9afb8c26b8a3e1be Mon Sep 17 00:00:00 2001
From: Imtanan Aziz Toor <imtanan.aziz@ikhwatech.com>
Date: Thu, 22 Feb 2024 15:42:21 +0500
Subject: [PATCH 76/97] File upload component styling and controls added

---
 .../lowcoder/src/comps/comps/fileComp/fileComp.tsx         | 5 +++++
 .../lowcoder/src/comps/controls/styleControlConstants.tsx  | 7 ++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/client/packages/lowcoder/src/comps/comps/fileComp/fileComp.tsx b/client/packages/lowcoder/src/comps/comps/fileComp/fileComp.tsx
index 52dbe74d07..018855b9c9 100644
--- a/client/packages/lowcoder/src/comps/comps/fileComp/fileComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/fileComp/fileComp.tsx
@@ -141,6 +141,11 @@ const getStyle = (style: FileStyleType) => {
       padding: ${style.padding};	
       width: ${widthCalculator(style.margin)};	
       height: ${heightCalculator(style.margin)};
+      font-family:${style.fontFamily};
+      font-size:${style.textSize};
+      font-weight:${style.textWeight};
+      font-style:${style.fontStyle};
+      border-width:${style.borderWidth};
     }
 
     .ant-btn:not(:disabled) {
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index b8cab410ab..49bbc52ec8 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -1016,7 +1016,12 @@ export const TableColumnLinkStyle = [
   ...LinkTextStyle,
 ] as const;
 
-export const FileStyle = [...getStaticBgBorderRadiusByBg(SURFACE_COLOR), TEXT, ACCENT, MARGIN, PADDING] as const;
+export const FileStyle = [
+  // ...getStaticBgBorderRadiusByBg(SURFACE_COLOR), 
+  getStaticBackground(SURFACE_COLOR),
+  ...replaceAndMergeMultipleStyles(STYLING_FIELDS_SEQUENCE,'border',[getStaticBorder('#00000000')]),
+  // TEXT, ACCENT, MARGIN, PADDING
+] as const;
 
 export const FileViewerStyle = [
   getStaticBackground("#FFFFFF"),

From 8bb42424dc90bd54eed5d99be43e5b776643d700 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Thu, 22 Feb 2024 17:47:09 +0100
Subject: [PATCH 77/97] Small adaptions for Marketplace

---
 .../comps/calendarComp/calendarConstants.tsx  |   8 +-
 .../assets/images/marketplaceHeaderImage.jpg  | Bin 0 -> 80436 bytes
 .../PermissionDialog/AppPermissionDialog.tsx  |  40 +-
 .../packages/lowcoder/src/i18n/locales/de.ts  |   8 +-
 .../packages/lowcoder/src/i18n/locales/en.ts  |   8 +-
 .../packages/lowcoder/src/i18n/locales/zh.ts  |   4 +
 .../src/pages/ApplicationV2/HomeLayout.tsx    |  31 +-
 .../src/pages/ApplicationV2/HomeResCard.tsx   |   1 -
 .../src/pages/ApplicationV2/index.tsx         |  28 +-
 client/yarn.lock                              | 445 +++++++++++++++++-
 10 files changed, 526 insertions(+), 47 deletions(-)
 create mode 100644 client/packages/lowcoder/src/assets/images/marketplaceHeaderImage.jpg

diff --git a/client/packages/lowcoder-comps/src/comps/calendarComp/calendarConstants.tsx b/client/packages/lowcoder-comps/src/comps/calendarComp/calendarConstants.tsx
index 93c07c4628..bbc02cafde 100644
--- a/client/packages/lowcoder-comps/src/comps/calendarComp/calendarConstants.tsx
+++ b/client/packages/lowcoder-comps/src/comps/calendarComp/calendarConstants.tsx
@@ -205,9 +205,9 @@ export const Wrapper = styled.div<{
       flex-direction: inherit;
     }
     .fc-day-today .fc-daygrid-day-number {
-      background-color: ${(props) => props.$theme.primary};
+      background-color: ${(props) => props.$theme?.primary ? props.$theme.primary : props.$style.background};
       color: ${(props) =>
-        contrastText(props.$theme.primary || "", props.$theme.textDark, props.$theme.textLight)};
+        contrastText(props.$theme?.primary || "", props.$theme?.textDark || "#000000", props.$theme?.textLight || "#ffffff")};
     }
     .fc-daygrid-day-events {
       padding: 1px 0 5px 0;
@@ -585,10 +585,10 @@ export const Wrapper = styled.div<{
     }
     .fc-day-today.fc-col-header-cell {
       background-color: ${(props) =>
-        isDarkColor(props.$style.background) ? "#ffffff19" : toHex(props.$theme.primary!) + "19"};
+        isDarkColor(props.$style.background) ? "#ffffff19" : toHex(props.$theme?.primary!) + "19"};
       a {
         color: ${(props) =>
-          !isDarkColor(props.$style.background) && darkenColor(props.$theme.primary!, 0.1)};
+          !isDarkColor(props.$style.background) && darkenColor(props.$theme?.primary!, 0.1)};
       }
     }
     .fc-col-header-cell-cushion {
diff --git a/client/packages/lowcoder/src/assets/images/marketplaceHeaderImage.jpg b/client/packages/lowcoder/src/assets/images/marketplaceHeaderImage.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a4eeb5714ca803778e37f8cf02b7b886f281cf9c
GIT binary patch
diff --git a/client/packages/lowcoder/src/components/PermissionDialog/AppPermissionDialog.tsx b/client/packages/lowcoder/src/components/PermissionDialog/AppPermissionDialog.tsx
index 37ec80ab6b..499ceae379 100644
--- a/client/packages/lowcoder/src/components/PermissionDialog/AppPermissionDialog.tsx
+++ b/client/packages/lowcoder/src/components/PermissionDialog/AppPermissionDialog.tsx
@@ -29,6 +29,7 @@ import { StyledLoading } from "./commonComponents";
 import { PermissionRole } from "./Permission";
 import { SHARE_TITLE } from "../../constants/apiConstants";
 import { messageInstance } from "lowcoder-design";
+import { Divider } from "antd";
 
 export const AppPermissionDialog = (props: {
   applicationId: string;
@@ -207,23 +208,7 @@ function AppShareView(props: {
   }, [permissionInfo.publicToMarketplace]);
   return (
     <div style={{ marginBottom: "22px" }}>
-      <PermissionSwitchWrapper>
-        <TacoSwitch
-          checked={isPublicToMarketplace}
-          onChange={(checked) => {
-            setPublicToMarketplace(checked);
-            ApplicationApi.publicToMarketplace(applicationId, checked)
-              .then((resp) => {
-                validateResponse(resp);
-                dispatch(updateAppPermissionInfo({ publicToMarketplace: checked }));
-              })
-              .catch((e) => {
-                messageInstance.error(e.message);
-              });
-          }}
-          label={isModule ? 'Public module to marketplace' : 'Public app to marketplace'}
-        />
-      </PermissionSwitchWrapper>
+      
       <PermissionSwitchWrapper>
         <TacoSwitch
           checked={isPublic}
@@ -241,6 +226,27 @@ function AppShareView(props: {
           label={isModule ? trans("home.modulePublicMessage") : trans("home.appPublicMessage")}
         />
       </PermissionSwitchWrapper>
+      {isPublic &&
+        <PermissionSwitchWrapper>
+          <TacoSwitch
+            checked={isPublicToMarketplace}
+            onChange={(checked) => {
+              setPublicToMarketplace(checked);
+              ApplicationApi.publicToMarketplace(applicationId, checked)
+                .then((resp) => {
+                  validateResponse(resp);
+                  dispatch(updateAppPermissionInfo({ publicToMarketplace: checked }));
+                })
+                .catch((e) => {
+                  messageInstance.error(e.message);
+                });
+            } }
+            label={isModule ? trans("home.moduleMarketplaceMessage") : trans("home.appMarketplaceMessage")} />
+        </PermissionSwitchWrapper> }
+        { isPublicToMarketplace && <><div style={{ margin: "10px 22px 22px 22px" }}>
+          {trans("home.marketplaceGoodPublishing")}
+        </div><Divider/></>}
+
       {isPublic && <AppInviteView appId={applicationId} />}
     </div>
   );
diff --git a/client/packages/lowcoder/src/i18n/locales/de.ts b/client/packages/lowcoder/src/i18n/locales/de.ts
index defca35301..671abf94cf 100644
--- a/client/packages/lowcoder/src/i18n/locales/de.ts
+++ b/client/packages/lowcoder/src/i18n/locales/de.ts
@@ -2111,8 +2111,12 @@ export const de = {
       "allPermissions": "Besitzer",
       "shareLink": "Link teilen: ",
       "copyLink": "Link kopieren",
-      "appPublicMessage": "Mach die App öffentlich. Jeder kann sie sehen.",
-      "modulePublicMessage": "Mach das Modul öffentlich. Jeder kann es sehen.",
+      "appPublicMessage": "App veröffentlichen. Auf dem Marktplatz für jeden zu sehen.",
+      "modulePublicMessage": "Module veröffentlichen. Auf dem Marktplatz für jeden zu sehen.",
+      "appMarketplaceMessage": "Veröffentlichen Sie Ihre App auf dem Lowcoder-Marktplatz. Jeder kann sie dort sehen und kopieren.",
+      "moduleMarketplaceMessage": "Veröffentlichen Sie Ihr Modul auf dem Lowcoder-Marktplatz. Jeder kann es dort sehen und kopieren.",
+      "marketplaceGoodPublishing": "Bitte stellen Sie sicher, dass Ihre App gut benannt und einfach zu bedienen ist. Entfernen Sie alle sensiblen Informationen vor der Veröffentlichung. Entfernen Sie außerdem lokale Datenquellen und ersetzen Sie sie durch statische, integrierte temporäre Daten.",
+      "noMarketplaceApps": "Noch sind keine Anwendungen auf dem Marktplatz.",
       "memberPermissionList": "Mitgliedschaftsberechtigungen: ",
       "orgName": "{orgName} admins",
       "addMember": "Mitglieder hinzufügen",
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index 3d56617d2f..a40d69d2e6 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -2238,8 +2238,8 @@ export const en = {
     "history": "History"
   },
   "home": {
-    "allApplications": "All Apps",
-    "allModules": "All Modules",
+    "allApplications": "Your Apps",
+    "allModules": "Your Modules",
     "allFolders": "All Folders",
     "modules": "Modules",
     "module": "Module",
@@ -2304,6 +2304,10 @@ export const en = {
     "copyLink": "Copy link",
     "appPublicMessage": "Make the app public. Anyone can view.",
     "modulePublicMessage": "Make the module public. Anyone can view.",
+    "appMarketplaceMessage": "Publish your App on Lowcoder Marketplace. Anyone can view and copy it from there.",
+    "moduleMarketplaceMessage": "Publish your Module on Lowcoder Marketplace. Anyone can view and copy it from there.",
+    "marketplaceGoodPublishing": "Please make sure your app is well-named and easy to use. Remove any sensitive information before publishing. Also, remove local datasources and replace by static built-in temporary data.",
+    "noMarketplaceApps": "No apps yet in the marketplace",
     "memberPermissionList": "Member permissions: ",
     "orgName": "{orgName} admins",
     "addMember": "Add members",
diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts
index b847a6090a..b90d3a8f11 100644
--- a/client/packages/lowcoder/src/i18n/locales/zh.ts
+++ b/client/packages/lowcoder/src/i18n/locales/zh.ts
@@ -2183,6 +2183,10 @@ home: {
     copyLink: "复制链接",
     appPublicMessage: "将应用设为公开,任何人都可以查看.",
     modulePublicMessage: "将模块设为公开,任何人都可以查看.",
+    "appMarketplaceMessage": "发布您的应用程序到Lowcoder市场.任何人都可以在那里查看和复制它.",
+    "moduleMarketplaceMessage": "发布您的模块到Lowcoder市场.任何人都可以在那里查看和复制它.",
+    "marketplaceGoodPublishing": "请确保您的应用程序命名准确、易于使用。发布前请删除任何敏感信息。此外，移除本地数据源，代之以静态内置临时数据",
+    "noMarketplaceApps": "市场上还没有应用程序",
     memberPermissionList: "成员权限:",
     orgName: "{orgName}管理员",
     addMember: "添加成员",
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
index b18b944f70..9ea75b051f 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
@@ -32,6 +32,7 @@ import { CreateDropdown } from "./CreateDropdown";
 import { trans } from "../../i18n";
 import { isFetchingFolderElements } from "../../redux/selectors/folderSelector";
 import { checkIsMobile } from "util/commonUtils";
+import MarketplaceHeaderImage from "assets/images/marketplaceHeaderImage.jpg";
 
 const Wrapper = styled.div`
   display: flex;
@@ -65,6 +66,23 @@ const OperationWrapper = styled.div`
   }
 `;
 
+const MarketplaceHeader = styled.div`
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  width: 100%;
+  height: 200px;
+  padding: 0 36px;
+  margin: 8px 0 20px 0;
+  @media screen and (max-width: 500px) {
+    padding: 0 24px;
+  }
+  > img { 
+    width: 100%;
+    object-fit: cover;
+  }
+`;
+
 const ContentWrapper = styled.div`
   position: relative;
 `;
@@ -364,6 +382,10 @@ export function HomeLayout(props: HomeLayoutProps) {
       {showNewUserGuide(user) && <HomepageTourV2 />}
       {/*<HomepageTourV2 />*/}
 
+      {mode === "marketplace" && (
+       <MarketplaceHeader><img src={MarketplaceHeaderImage} alt="Lowcoder Application Marketplace"/></MarketplaceHeader>
+      )}
+
       <OperationWrapper>
         {mode !== "folders" && mode !== "module" && (
           <FilterDropdown
@@ -374,8 +396,9 @@ export function HomeLayout(props: HomeLayoutProps) {
               getFilterMenuItem(HomeResTypeEnum.All),
               getFilterMenuItem(HomeResTypeEnum.Application),
               getFilterMenuItem(HomeResTypeEnum.Module),
-              getFilterMenuItem(HomeResTypeEnum.Navigation),
-              ...(mode !== "trash" ? [getFilterMenuItem(HomeResTypeEnum.Folder)] : []),
+              ...(mode !== "marketplace" ? [getFilterMenuItem(HomeResTypeEnum.Navigation)] : []),
+              ...(mode !== "trash" && mode !== "marketplace" ? [getFilterMenuItem(HomeResTypeEnum.Folder)] : []),
+  
             ]}
             getPopupContainer={(node: any) => node}
             suffixIcon={<ArrowSolidIcon />}
@@ -396,6 +419,8 @@ export function HomeLayout(props: HomeLayoutProps) {
       </OperationWrapper>
 
       <ContentWrapper>
+
+        
         {isFetching && resList.length === 0 ? (
           <SkeletonStyle active paragraph={{ rows: 8, width: 648 }} title={false} />
         ) : (
@@ -424,7 +449,7 @@ export function HomeLayout(props: HomeLayoutProps) {
                   {mode === "trash"
                     ? trans("home.trashEmpty")
                     : mode === "marketplace"
-                    ? "No apps in marketplace yet"
+                    ? trans("home.noMarketplaceApps")
                     : user.orgDev
                     ? trans("home.projectEmptyCanAdd")
                     : trans("home.projectEmpty")}
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx
index 32e2258ed8..ceef8b54ad 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx
@@ -168,7 +168,6 @@ export function HomeResCard(props: { res: HomeRes; onMove: (res: HomeRes) => voi
         )}
         <CardInfo
           onClick={(e) => {
-            console.log(res.isMarketplace);
             if (appNameEditing) {
               return;
             }
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
index a9525298b7..2baac32592 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
@@ -345,7 +345,7 @@ export default function ApplicationHome() {
                   selected ? <HomeActiveIcon {...otherProps} /> : <HomeIcon {...otherProps} />,
               },
               {
-                text: <TabLabel>{trans("home.modules")}</TabLabel>,
+                text: <TabLabel>{trans("home.allModules")}</TabLabel>,
                 routePath: MODULE_APPLICATIONS_URL,
                 routeComp: ModuleView,
                 icon: ({ selected, ...otherProps }) =>
@@ -356,6 +356,19 @@ export default function ApplicationHome() {
                   ),
                 visible: ({ user }) => user.orgDev,
               },
+              {
+                text: <TabLabel>{trans("home.marketplace")}</TabLabel>,
+                routePath: MARKETPLACE_URL,
+                routePathExact: false,
+                routeComp: MarketplaceView,
+                icon: ({ selected, ...otherProps }) =>
+                  selected ? (
+                    <MarketplaceActiveIcon {...otherProps} />
+                  ) : (
+                    <MarketplaceIcon {...otherProps} />
+                  ),
+                visible: ({ user }) => user.orgDev,
+              },
               {
                 text: <TabLabel>{trans("home.trash")}</TabLabel>,
                 routePath: TRASH_URL,
@@ -415,19 +428,6 @@ export default function ApplicationHome() {
                 visible: ({ user }) => user.orgDev,
                 onSelected: (_, currentPath) => currentPath.split("/")[1] === "datasource",
               },
-              {
-                text: <TabLabel>{trans("home.marketplace")}</TabLabel>,
-                routePath: MARKETPLACE_URL,
-                routePathExact: false,
-                routeComp: MarketplaceView,
-                icon: ({ selected, ...otherProps }) =>
-                  selected ? (
-                    <MarketplaceActiveIcon {...otherProps} />
-                  ) : (
-                    <MarketplaceIcon {...otherProps} />
-                  ),
-                visible: ({ user }) => user.orgDev,
-              },
               {
                 text: <TabLabel>{trans("settings.title")}</TabLabel>,
                 routePath: SETTING,
diff --git a/client/yarn.lock b/client/yarn.lock
index 548e5b8740..706f6c885b 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -2058,6 +2058,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/aix-ppc64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/aix-ppc64@npm:0.19.12"
+  conditions: os=aix & cpu=ppc64
+  languageName: node
+  linkType: hard
+
 "@esbuild/android-arm64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/android-arm64@npm:0.18.20"
@@ -2065,6 +2072,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/android-arm64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/android-arm64@npm:0.19.12"
+  conditions: os=android & cpu=arm64
+  languageName: node
+  linkType: hard
+
 "@esbuild/android-arm@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/android-arm@npm:0.18.20"
@@ -2072,6 +2086,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/android-arm@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/android-arm@npm:0.19.12"
+  conditions: os=android & cpu=arm
+  languageName: node
+  linkType: hard
+
 "@esbuild/android-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/android-x64@npm:0.18.20"
@@ -2079,6 +2100,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/android-x64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/android-x64@npm:0.19.12"
+  conditions: os=android & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@esbuild/darwin-arm64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/darwin-arm64@npm:0.18.20"
@@ -2086,6 +2114,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/darwin-arm64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/darwin-arm64@npm:0.19.12"
+  conditions: os=darwin & cpu=arm64
+  languageName: node
+  linkType: hard
+
 "@esbuild/darwin-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/darwin-x64@npm:0.18.20"
@@ -2093,6 +2128,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/darwin-x64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/darwin-x64@npm:0.19.12"
+  conditions: os=darwin & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@esbuild/freebsd-arm64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/freebsd-arm64@npm:0.18.20"
@@ -2100,6 +2142,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/freebsd-arm64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/freebsd-arm64@npm:0.19.12"
+  conditions: os=freebsd & cpu=arm64
+  languageName: node
+  linkType: hard
+
 "@esbuild/freebsd-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/freebsd-x64@npm:0.18.20"
@@ -2107,6 +2156,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/freebsd-x64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/freebsd-x64@npm:0.19.12"
+  conditions: os=freebsd & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-arm64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-arm64@npm:0.18.20"
@@ -2114,6 +2170,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-arm64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/linux-arm64@npm:0.19.12"
+  conditions: os=linux & cpu=arm64
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-arm@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-arm@npm:0.18.20"
@@ -2121,6 +2184,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-arm@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/linux-arm@npm:0.19.12"
+  conditions: os=linux & cpu=arm
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-ia32@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-ia32@npm:0.18.20"
@@ -2128,6 +2198,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-ia32@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/linux-ia32@npm:0.19.12"
+  conditions: os=linux & cpu=ia32
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-loong64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-loong64@npm:0.18.20"
@@ -2135,6 +2212,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-loong64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/linux-loong64@npm:0.19.12"
+  conditions: os=linux & cpu=loong64
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-mips64el@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-mips64el@npm:0.18.20"
@@ -2142,6 +2226,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-mips64el@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/linux-mips64el@npm:0.19.12"
+  conditions: os=linux & cpu=mips64el
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-ppc64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-ppc64@npm:0.18.20"
@@ -2149,6 +2240,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-ppc64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/linux-ppc64@npm:0.19.12"
+  conditions: os=linux & cpu=ppc64
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-riscv64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-riscv64@npm:0.18.20"
@@ -2156,6 +2254,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-riscv64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/linux-riscv64@npm:0.19.12"
+  conditions: os=linux & cpu=riscv64
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-s390x@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-s390x@npm:0.18.20"
@@ -2163,6 +2268,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-s390x@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/linux-s390x@npm:0.19.12"
+  conditions: os=linux & cpu=s390x
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/linux-x64@npm:0.18.20"
@@ -2170,6 +2282,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-x64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/linux-x64@npm:0.19.12"
+  conditions: os=linux & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@esbuild/netbsd-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/netbsd-x64@npm:0.18.20"
@@ -2177,6 +2296,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/netbsd-x64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/netbsd-x64@npm:0.19.12"
+  conditions: os=netbsd & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@esbuild/openbsd-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/openbsd-x64@npm:0.18.20"
@@ -2184,6 +2310,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/openbsd-x64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/openbsd-x64@npm:0.19.12"
+  conditions: os=openbsd & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@esbuild/sunos-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/sunos-x64@npm:0.18.20"
@@ -2191,6 +2324,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/sunos-x64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/sunos-x64@npm:0.19.12"
+  conditions: os=sunos & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@esbuild/win32-arm64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/win32-arm64@npm:0.18.20"
@@ -2198,6 +2338,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/win32-arm64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/win32-arm64@npm:0.19.12"
+  conditions: os=win32 & cpu=arm64
+  languageName: node
+  linkType: hard
+
 "@esbuild/win32-ia32@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/win32-ia32@npm:0.18.20"
@@ -2205,6 +2352,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/win32-ia32@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/win32-ia32@npm:0.19.12"
+  conditions: os=win32 & cpu=ia32
+  languageName: node
+  linkType: hard
+
 "@esbuild/win32-x64@npm:0.18.20":
   version: 0.18.20
   resolution: "@esbuild/win32-x64@npm:0.18.20"
@@ -2212,6 +2366,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/win32-x64@npm:0.19.12":
+  version: 0.19.12
+  resolution: "@esbuild/win32-x64@npm:0.19.12"
+  conditions: os=win32 & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@eslint-community/eslint-utils@npm:^4.2.0":
   version: 4.4.0
   resolution: "@eslint-community/eslint-utils@npm:4.4.0"
@@ -3523,6 +3684,97 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@rollup/rollup-android-arm-eabi@npm:4.12.0":
+  version: 4.12.0
+  resolution: "@rollup/rollup-android-arm-eabi@npm:4.12.0"
+  conditions: os=android & cpu=arm
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-android-arm64@npm:4.12.0":
+  version: 4.12.0
+  resolution: "@rollup/rollup-android-arm64@npm:4.12.0"
+  conditions: os=android & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-darwin-arm64@npm:4.12.0":
+  version: 4.12.0
+  resolution: "@rollup/rollup-darwin-arm64@npm:4.12.0"
+  conditions: os=darwin & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-darwin-x64@npm:4.12.0":
+  version: 4.12.0
+  resolution: "@rollup/rollup-darwin-x64@npm:4.12.0"
+  conditions: os=darwin & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-arm-gnueabihf@npm:4.12.0":
+  version: 4.12.0
+  resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.12.0"
+  conditions: os=linux & cpu=arm
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-arm64-gnu@npm:4.12.0":
+  version: 4.12.0
+  resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.12.0"
+  conditions: os=linux & cpu=arm64 & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-arm64-musl@npm:4.12.0":
+  version: 4.12.0
+  resolution: "@rollup/rollup-linux-arm64-musl@npm:4.12.0"
+  conditions: os=linux & cpu=arm64 & libc=musl
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-riscv64-gnu@npm:4.12.0":
+  version: 4.12.0
+  resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.12.0"
+  conditions: os=linux & cpu=riscv64 & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-x64-gnu@npm:4.12.0":
+  version: 4.12.0
+  resolution: "@rollup/rollup-linux-x64-gnu@npm:4.12.0"
+  conditions: os=linux & cpu=x64 & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-x64-musl@npm:4.12.0":
+  version: 4.12.0
+  resolution: "@rollup/rollup-linux-x64-musl@npm:4.12.0"
+  conditions: os=linux & cpu=x64 & libc=musl
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-win32-arm64-msvc@npm:4.12.0":
+  version: 4.12.0
+  resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.12.0"
+  conditions: os=win32 & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-win32-ia32-msvc@npm:4.12.0":
+  version: 4.12.0
+  resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.12.0"
+  conditions: os=win32 & cpu=ia32
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-win32-x64-msvc@npm:4.12.0":
+  version: 4.12.0
+  resolution: "@rollup/rollup-win32-x64-msvc@npm:4.12.0"
+  conditions: os=win32 & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@rushstack/eslint-patch@npm:^1.1.0":
   version: 1.6.1
   resolution: "@rushstack/eslint-patch@npm:1.6.1"
@@ -3878,7 +4130,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@types/estree@npm:*, @types/estree@npm:^1.0.0":
+"@types/estree@npm:*, @types/estree@npm:1.0.5, @types/estree@npm:^1.0.0":
   version: 1.0.5
   resolution: "@types/estree@npm:1.0.5"
   checksum: dd8b5bed28e6213b7acd0fb665a84e693554d850b0df423ac8076cc3ad5823a6bc26b0251d080bdc545af83179ede51dd3f6fa78cad2c46ed1f29624ddf3e41a
@@ -7865,6 +8117,86 @@ __metadata:
   languageName: node
   linkType: hard
 
+"esbuild@npm:^0.19.3":
+  version: 0.19.12
+  resolution: "esbuild@npm:0.19.12"
+  dependencies:
+    "@esbuild/aix-ppc64": 0.19.12
+    "@esbuild/android-arm": 0.19.12
+    "@esbuild/android-arm64": 0.19.12
+    "@esbuild/android-x64": 0.19.12
+    "@esbuild/darwin-arm64": 0.19.12
+    "@esbuild/darwin-x64": 0.19.12
+    "@esbuild/freebsd-arm64": 0.19.12
+    "@esbuild/freebsd-x64": 0.19.12
+    "@esbuild/linux-arm": 0.19.12
+    "@esbuild/linux-arm64": 0.19.12
+    "@esbuild/linux-ia32": 0.19.12
+    "@esbuild/linux-loong64": 0.19.12
+    "@esbuild/linux-mips64el": 0.19.12
+    "@esbuild/linux-ppc64": 0.19.12
+    "@esbuild/linux-riscv64": 0.19.12
+    "@esbuild/linux-s390x": 0.19.12
+    "@esbuild/linux-x64": 0.19.12
+    "@esbuild/netbsd-x64": 0.19.12
+    "@esbuild/openbsd-x64": 0.19.12
+    "@esbuild/sunos-x64": 0.19.12
+    "@esbuild/win32-arm64": 0.19.12
+    "@esbuild/win32-ia32": 0.19.12
+    "@esbuild/win32-x64": 0.19.12
+  dependenciesMeta:
+    "@esbuild/aix-ppc64":
+      optional: true
+    "@esbuild/android-arm":
+      optional: true
+    "@esbuild/android-arm64":
+      optional: true
+    "@esbuild/android-x64":
+      optional: true
+    "@esbuild/darwin-arm64":
+      optional: true
+    "@esbuild/darwin-x64":
+      optional: true
+    "@esbuild/freebsd-arm64":
+      optional: true
+    "@esbuild/freebsd-x64":
+      optional: true
+    "@esbuild/linux-arm":
+      optional: true
+    "@esbuild/linux-arm64":
+      optional: true
+    "@esbuild/linux-ia32":
+      optional: true
+    "@esbuild/linux-loong64":
+      optional: true
+    "@esbuild/linux-mips64el":
+      optional: true
+    "@esbuild/linux-ppc64":
+      optional: true
+    "@esbuild/linux-riscv64":
+      optional: true
+    "@esbuild/linux-s390x":
+      optional: true
+    "@esbuild/linux-x64":
+      optional: true
+    "@esbuild/netbsd-x64":
+      optional: true
+    "@esbuild/openbsd-x64":
+      optional: true
+    "@esbuild/sunos-x64":
+      optional: true
+    "@esbuild/win32-arm64":
+      optional: true
+    "@esbuild/win32-ia32":
+      optional: true
+    "@esbuild/win32-x64":
+      optional: true
+  bin:
+    esbuild: bin/esbuild
+  checksum: 2936e29107b43e65a775b78b7bc66ddd7d76febd73840ac7e825fb22b65029422ff51038a08d19b05154f543584bd3afe7d1ef1c63900429475b17fbe61cb61f
+  languageName: node
+  linkType: hard
+
 "escalade@npm:^3.1.1":
   version: 3.1.1
   resolution: "escalade@npm:3.1.1"
@@ -8794,7 +9126,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2":
+"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2, fsevents@npm:~2.3.3":
   version: 2.3.3
   resolution: "fsevents@npm:2.3.3"
   dependencies:
@@ -8804,7 +9136,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"fsevents@patch:fsevents@^2.3.2#~builtin<compat/fsevents>, fsevents@patch:fsevents@~2.3.2#~builtin<compat/fsevents>":
+"fsevents@patch:fsevents@^2.3.2#~builtin<compat/fsevents>, fsevents@patch:fsevents@~2.3.2#~builtin<compat/fsevents>, fsevents@patch:fsevents@~2.3.3#~builtin<compat/fsevents>":
   version: 2.3.3
   resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin<compat/fsevents>::version=2.3.3&hash=df0bf1"
   dependencies:
@@ -11505,7 +11837,7 @@ __metadata:
     react: ^18.2.0
     react-dom: ^18.2.0
     typescript: 4.8.4
-    vite: ^4.5.2
+    vite: ^5.0.12
     vite-tsconfig-paths: ^3.6.0
   languageName: unknown
   linkType: soft
@@ -13563,6 +13895,17 @@ __metadata:
   languageName: node
   linkType: hard
 
+"postcss@npm:^8.4.35":
+  version: 8.4.35
+  resolution: "postcss@npm:8.4.35"
+  dependencies:
+    nanoid: ^3.3.7
+    picocolors: ^1.0.0
+    source-map-js: ^1.0.2
+  checksum: cf3c3124d3912a507603f6d9a49b3783f741075e9aa73eb592a6dd9194f9edab9d20a8875d16d137d4f779fe7b6fbd1f5727e39bfd1c3003724980ee4995e1da
+  languageName: node
+  linkType: hard
+
 "preact@npm:~10.12.1":
   version: 10.12.1
   resolution: "preact@npm:10.12.1"
@@ -15650,6 +15993,60 @@ __metadata:
   languageName: node
   linkType: hard
 
+"rollup@npm:^4.2.0":
+  version: 4.12.0
+  resolution: "rollup@npm:4.12.0"
+  dependencies:
+    "@rollup/rollup-android-arm-eabi": 4.12.0
+    "@rollup/rollup-android-arm64": 4.12.0
+    "@rollup/rollup-darwin-arm64": 4.12.0
+    "@rollup/rollup-darwin-x64": 4.12.0
+    "@rollup/rollup-linux-arm-gnueabihf": 4.12.0
+    "@rollup/rollup-linux-arm64-gnu": 4.12.0
+    "@rollup/rollup-linux-arm64-musl": 4.12.0
+    "@rollup/rollup-linux-riscv64-gnu": 4.12.0
+    "@rollup/rollup-linux-x64-gnu": 4.12.0
+    "@rollup/rollup-linux-x64-musl": 4.12.0
+    "@rollup/rollup-win32-arm64-msvc": 4.12.0
+    "@rollup/rollup-win32-ia32-msvc": 4.12.0
+    "@rollup/rollup-win32-x64-msvc": 4.12.0
+    "@types/estree": 1.0.5
+    fsevents: ~2.3.2
+  dependenciesMeta:
+    "@rollup/rollup-android-arm-eabi":
+      optional: true
+    "@rollup/rollup-android-arm64":
+      optional: true
+    "@rollup/rollup-darwin-arm64":
+      optional: true
+    "@rollup/rollup-darwin-x64":
+      optional: true
+    "@rollup/rollup-linux-arm-gnueabihf":
+      optional: true
+    "@rollup/rollup-linux-arm64-gnu":
+      optional: true
+    "@rollup/rollup-linux-arm64-musl":
+      optional: true
+    "@rollup/rollup-linux-riscv64-gnu":
+      optional: true
+    "@rollup/rollup-linux-x64-gnu":
+      optional: true
+    "@rollup/rollup-linux-x64-musl":
+      optional: true
+    "@rollup/rollup-win32-arm64-msvc":
+      optional: true
+    "@rollup/rollup-win32-ia32-msvc":
+      optional: true
+    "@rollup/rollup-win32-x64-msvc":
+      optional: true
+    fsevents:
+      optional: true
+  bin:
+    rollup: dist/bin/rollup
+  checksum: a7398f072cf50804e9bdaf363792d0b7801800640434e7867c10b4e2e7be421ca2dc614ae0fc7392044eaf77d5c3a66f76a6fa2246bef97a7bc55926a8d60982
+  languageName: node
+  linkType: hard
+
 "rtl-css-js@npm:^1.16.1":
   version: 1.16.1
   resolution: "rtl-css-js@npm:1.16.1"
@@ -17699,6 +18096,46 @@ __metadata:
   languageName: node
   linkType: hard
 
+"vite@npm:^5.0.12":
+  version: 5.1.4
+  resolution: "vite@npm:5.1.4"
+  dependencies:
+    esbuild: ^0.19.3
+    fsevents: ~2.3.3
+    postcss: ^8.4.35
+    rollup: ^4.2.0
+  peerDependencies:
+    "@types/node": ^18.0.0 || >=20.0.0
+    less: "*"
+    lightningcss: ^1.21.0
+    sass: "*"
+    stylus: "*"
+    sugarss: "*"
+    terser: ^5.4.0
+  dependenciesMeta:
+    fsevents:
+      optional: true
+  peerDependenciesMeta:
+    "@types/node":
+      optional: true
+    less:
+      optional: true
+    lightningcss:
+      optional: true
+    sass:
+      optional: true
+    stylus:
+      optional: true
+    sugarss:
+      optional: true
+    terser:
+      optional: true
+  bin:
+    vite: bin/vite.js
+  checksum: fb8b944c69fd738b412ad10471f01db01ed59b5d7fdf182b836b420b221a8bd5ada74d225a87aaa80cf8d2b693cc4a89ab7c291254a8b4e6faefd93843ebb9d3
+  languageName: node
+  linkType: hard
+
 "vlq@npm:^0.2.2":
   version: 0.2.3
   resolution: "vlq@npm:0.2.3"

From f42e8e7c54c08388dae412b8f51a2d9ae8878c3c Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Thu, 22 Feb 2024 20:00:15 +0100
Subject: [PATCH 78/97] Changes for AntIcon, Timeline Component

---
 client/VERSION                                |  2 +-
 client/package.json                           |  1 +
 .../lowcoder-design/src/components/edit.tsx   |  2 +-
 .../src/icons}/antIcon.tsx                    | 21 +++++++
 client/packages/lowcoder-design/src/index.ts  |  2 +
 .../comps/comps/timelineComp/timelineComp.tsx | 59 +++++++++++--------
 .../src/pages/common/headerStartDropdown.tsx  |  2 +-
 client/yarn.lock                              | 10 ++++
 8 files changed, 70 insertions(+), 29 deletions(-)
 rename client/packages/{lowcoder/src/comps/comps/timelineComp => lowcoder-design/src/icons}/antIcon.tsx (98%)

diff --git a/client/VERSION b/client/VERSION
index cc6612c36e..a6254504e4 100644
--- a/client/VERSION
+++ b/client/VERSION
@@ -1 +1 @@
-2.3.0
\ No newline at end of file
+2.3.1
\ No newline at end of file
diff --git a/client/package.json b/client/package.json
index fccf0fff11..f2054b5306 100644
--- a/client/package.json
+++ b/client/package.json
@@ -70,6 +70,7 @@
   },
   "dependencies": {
     "@lottiefiles/react-lottie-player": "^3.5.3",
+    "@remixicon/react": "^4.1.1",
     "@testing-library/react": "^14.1.2",
     "@testing-library/user-event": "^14.5.1",
     "@types/styled-components": "^5.1.34",
diff --git a/client/packages/lowcoder-design/src/components/edit.tsx b/client/packages/lowcoder-design/src/components/edit.tsx
index c093fa6a2d..0a17bfe8ab 100644
--- a/client/packages/lowcoder-design/src/components/edit.tsx
+++ b/client/packages/lowcoder-design/src/components/edit.tsx
@@ -68,7 +68,7 @@ const TextInput = styled(Input)<InputProps & { $hasPrefix?: boolean }>`
   border: none;
   padding: 0 8px 0 4px;
   padding-left: ${(props) => (props.$hasPrefix ? "28px" : "4px")};
-  color: #ffffff;
+  color: #444444;
   line-height: 28px;
   font-size: 14px;
 
diff --git a/client/packages/lowcoder/src/comps/comps/timelineComp/antIcon.tsx b/client/packages/lowcoder-design/src/icons/antIcon.tsx
similarity index 98%
rename from client/packages/lowcoder/src/comps/comps/timelineComp/antIcon.tsx
rename to client/packages/lowcoder-design/src/icons/antIcon.tsx
index 7879ff920f..34cd128f22 100644
--- a/client/packages/lowcoder/src/comps/comps/timelineComp/antIcon.tsx
+++ b/client/packages/lowcoder-design/src/icons/antIcon.tsx
@@ -1581,3 +1581,24 @@ export const ANTDICON = {
   zoominoutlined: <ZoomInOutlined />,
   zoomoutoutlined: <ZoomOutOutlined />,
 };
+
+
+// Function to dynamically import icons
+export const loadAntDIcon = async (iconName: string) => {
+  if (!iconName) return null;
+
+  try {
+    const module = await import(`@ant-design/icons`);
+    const IconComponent = (module as any)[iconName];
+    if (IconComponent) {
+      // Return the icon component if found
+      return <IconComponent />;
+    } else {
+      console.error(`Icon ${iconName} not found in @ant-design/icons`);
+      return null;
+    }
+  } catch (error) {
+    console.error(`Error loading icon ${iconName}:`, error);
+    return null;
+  }
+};
\ No newline at end of file
diff --git a/client/packages/lowcoder-design/src/index.ts b/client/packages/lowcoder-design/src/index.ts
index a2a7ca4954..92a05fb78c 100644
--- a/client/packages/lowcoder-design/src/index.ts
+++ b/client/packages/lowcoder-design/src/index.ts
@@ -49,3 +49,5 @@ export * from "./components/toolTip";
 export * from "./components/video";
 
 export * from "./icons";
+
+export * from "./icons/antIcon";
diff --git a/client/packages/lowcoder/src/comps/comps/timelineComp/timelineComp.tsx b/client/packages/lowcoder/src/comps/comps/timelineComp/timelineComp.tsx
index 78a2787afd..7433cc64d8 100644
--- a/client/packages/lowcoder/src/comps/comps/timelineComp/timelineComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/timelineComp/timelineComp.tsx
@@ -1,26 +1,19 @@
-import React, { useEffect, useState } from "react";
+import React, { useEffect, useState, useContext } from "react";
 import { default as Button } from "antd/es/button";
-// 渲染组件到编辑器
 import {
   changeChildAction,
   DispatchType,
   CompAction,
   RecordConstructorToView,
 } from "lowcoder-core";
-// 文字国际化转换api
 import { trans } from "i18n";
-// 右侧属性栏总框架
 import { UICompBuilder, withDefault } from "../../generators";
-// 右侧属性子框架
 import { Section, sectionNames } from "lowcoder-design";
-// 指示组件是否隐藏的开关
 import { hiddenPropertyView } from "comps/utils/propertyUtils";
-// 右侧属性开关
-
 import { BoolControl } from "comps/controls/boolControl";
-import { stringExposingStateControl } from "comps/controls/codeStateControl"; //文本并暴露值
+import { stringExposingStateControl } from "comps/controls/codeStateControl";
 import { dropdownControl } from "comps/controls/dropdownControl";
-import { styleControl } from "comps/controls/styleControl"; //样式输入框
+import { styleControl } from "comps/controls/styleControl";
 import { alignControl } from "comps/controls/alignControl";
 import { AutoHeightControl } from "comps/controls/autoHeightControl";
 import { jsonValueExposingStateControl } from "comps/controls/codeStateControl";
@@ -34,35 +27,25 @@ import {
   NumberControl,
   StringControl,
 } from "comps/controls/codeControl";
-// 事件控制
 import {
   clickEvent,
   eventHandlerControl,
 } from "comps/controls/eventHandlerControl";
-
-// 引入样式
 import {
   TimeLineStyle,
   heightCalculator,
   widthCalculator,
   marginCalculator,
 } from "comps/controls/styleControlConstants";
-// 初始化暴露值
 import { stateComp, valueComp } from "comps/generators/simpleGenerators";
-// 组件对外暴露属性的api
 import {
   NameConfig,
   NameConfigHidden,
   withExposingConfigs,
 } from "comps/generators/withExposing";
-
 import { timelineDate, timelineNode, TimelineDataTooltip } from "./timelineConstants";
 import { convertTimeLineData } from "./timelineUtils";
 import { default as Timeline } from "antd/es/timeline";
-
-import { ANTDICON } from "./antIcon"; // todo: select icons to not import all icons
-
-import { useContext } from "react";
 import { EditorContext } from "comps/editorState"; 
 
 const EventOptions = [
@@ -86,18 +69,44 @@ const childrenMap = {
   clickedIndex: valueComp<number>(0),
 };
 
+// Utility function to dynamically load Ant Design icons
+const loadIcon = async (iconName: string) => {
+  if (!iconName) return null;
+  try {
+    const module = await import(`@ant-design/icons`);
+    const IconComponent = (module as any)[iconName];
+    return IconComponent ? <IconComponent /> : null;
+  } catch (error) {
+    console.error(`Error loading icon ${iconName}:`, error);
+    return null;
+  }
+};
+
 const TimelineComp = (
   props: RecordConstructorToView<typeof childrenMap> & {
     dispatch: (action: CompAction) => void;
   }
 ) => {
   const { value, dispatch, style, mode, reverse, onEvent } = props;
+  const [icons, setIcons] = useState<React.ReactNode[]>([]);
+
+  useEffect(() => {
+    const loadIcons = async () => {
+      const iconComponents = await Promise.all(
+        value.map((node) =>
+          node.dot ? loadIcon(node.dot) : Promise.resolve(null)
+        )
+      );
+      setIcons(iconComponents);
+    };
+
+    loadIcons();
+  }, [value]);
+
   const timelineItems = value.map((value: timelineNode, index: number) => ({
     key: index,
     color: value?.color,
-    dot: value?.dot && ANTDICON.hasOwnProperty(value?.dot.toLowerCase())
-      ? ANTDICON[value?.dot.toLowerCase() as keyof typeof ANTDICON]
-      : "",
+    dot: icons[index] || "",
     label: (
       <span style={{ color: value?.lableColor || style?.lableColor }}>
         {value?.label}
@@ -125,10 +134,8 @@ const TimelineComp = (
         </p>
       </>
     )
-  }
-  ))
+  }));
 
-  // TODO:parse px string
   return (
     <div
       style={{
diff --git a/client/packages/lowcoder/src/pages/common/headerStartDropdown.tsx b/client/packages/lowcoder/src/pages/common/headerStartDropdown.tsx
index 1ea2836908..6fe44ec93a 100644
--- a/client/packages/lowcoder/src/pages/common/headerStartDropdown.tsx
+++ b/client/packages/lowcoder/src/pages/common/headerStartDropdown.tsx
@@ -154,7 +154,7 @@ export function HeaderStartDropdown(props: { setEdit: () => void }) {
         )}
       >
         <EditTextWrapper
-          style={{ width: "fit-content", maxWidth: "288px", padding: "0 8px" }}
+          style={{ width: "fit-content", maxWidth: "288px", padding: "0 8px"}}
           disabled={showAppSnapshot}
         >
           {isModule && (
diff --git a/client/yarn.lock b/client/yarn.lock
index 706f6c885b..95b2481e60 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -3387,6 +3387,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@remixicon/react@npm:^4.1.1":
+  version: 4.1.1
+  resolution: "@remixicon/react@npm:4.1.1"
+  peerDependencies:
+    react: ">=18.2.0"
+  checksum: 59b05b91ad9335ae531b2927ceb7c5930ec5afcdabb5d96461d3181e1f794ddbdd4a899e85eb66f1a5341f55132898b6f680f51643bd7bd7244a741f44beb0b7
+  languageName: node
+  linkType: hard
+
 "@rjsf/antd@npm:^5.15.1":
   version: 5.15.1
   resolution: "@rjsf/antd@npm:5.15.1"
@@ -11921,6 +11930,7 @@ __metadata:
     "@babel/preset-env": ^7.20.2
     "@babel/preset-typescript": ^7.18.6
     "@lottiefiles/react-lottie-player": ^3.5.3
+    "@remixicon/react": ^4.1.1
     "@rollup/plugin-typescript": ^8.5.0
     "@testing-library/jest-dom": ^5.16.5
     "@testing-library/react": ^14.1.2

From 48b46ccdf00ca8f5250369f95fd0fafb70f18a11 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Thu, 22 Feb 2024 21:58:15 +0100
Subject: [PATCH 79/97] Fixing IconComponent

---
 .../src/components/iconSelect/index.tsx       | 55 +++++++++++----
 .../lowcoder/src/comps/comps/iconComp.tsx     | 68 ++++++++++---------
 .../comps/controls/styleControlConstants.tsx  | 10 ++-
 3 files changed, 84 insertions(+), 49 deletions(-)

diff --git a/client/packages/lowcoder-design/src/components/iconSelect/index.tsx b/client/packages/lowcoder-design/src/components/iconSelect/index.tsx
index 7ffc8cc72f..232f89ca7e 100644
--- a/client/packages/lowcoder-design/src/components/iconSelect/index.tsx
+++ b/client/packages/lowcoder-design/src/components/iconSelect/index.tsx
@@ -1,6 +1,6 @@
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import type { IconDefinition } from "@fortawesome/free-regular-svg-icons";
-import type { IconDefinition as IconDefinitionBrands } from "@fortawesome/free-brands-svg-icons";
+// import type { IconDefinition as IconDefinitionBrands } from "@fortawesome/free-brands-svg-icons";
 import { Popover } from "antd";
 import { ActionType } from "@rc-component/trigger/lib/interface";
 import { TacoInput } from "components/tacoInput";
@@ -19,10 +19,11 @@ import Draggable from "react-draggable";
 import { default as List, ListRowProps } from "react-virtualized/dist/es/List";
 import styled from "styled-components";
 import { CloseIcon, SearchIcon } from "icons";
-import { ANTDICON } from "../../../../lowcoder/src/comps/comps/timelineComp/antIcon";
+import { ANTDICON } from "icons/antIcon";
+import { Divider } from "antd-mobile";
 
 const PopupContainer = styled.div`
-  width: 408px;
+  width: 580px;
   background: #ffffff;
   box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
   border-radius: 8px;
@@ -85,10 +86,11 @@ const IconList = styled(List)`
     background-color: rgba(139, 143, 163, 0.36);
   }
 `;
+
 const IconRow = styled.div`
   padding: 0 6px;
   display: flex;
-  align-items: center;
+  align-items: flex-start; /* Align items to the start to allow different heights */
   justify-content: space-between;
 
   &:last-child {
@@ -96,14 +98,16 @@ const IconRow = styled.div`
     justify-content: flex-start;
   }
 `;
+
 const IconItemContainer = styled.div`
-  width: 40px;
-  height: 40px;
+  width: 60px;
   display: flex;
-  align-items: center;
-  justify-content: center;
+  flex-direction: column;
+  align-items: center; 
+  justify-content: flex-start; 
   cursor: pointer;
-  font-size: 20px;
+  font-size: 28px;
+  margin-bottom: 24px; 
 
   &:hover {
     border: 1px solid #315efb;
@@ -117,6 +121,22 @@ const IconItemContainer = styled.div`
   }
 `;
 
+const IconWrapper = styled.div`
+  height: auto;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+`;
+
+const IconKeyDisplay = styled.div`
+  font-size: 8px;
+  color: #8b8fa3;
+  margin-top: 4px; /* Space between the icon and the text */
+  text-align: center;
+  word-wrap: break-word; /* Ensure text wraps */
+  width: 100%; /* Ensure the container can grow */
+`;
+
 class Icon {
   readonly title: string;
   constructor(readonly def: IconDefinition | any, readonly names: string[]) {
@@ -133,7 +153,7 @@ class Icon {
       return (
         <FontAwesomeIcon
           icon={this.def}
-          style={{ width: "1em", height: "1em" }}
+          style={{ width: "1em", height: "1em"}}
         />
       );
   }
@@ -254,6 +274,10 @@ const IconPopup = (props: {
     getAllIcons().then(setAllIcons);
   }, []);
 
+  const smallTextStyle = {
+    fontSize: '8px'
+  };
+
   const rowRenderer = useCallback(
     (p: ListRowProps) => (
       <IconRow key={p.key} style={p.style}>
@@ -262,7 +286,7 @@ const IconPopup = (props: {
           .map(([key, icon]) => (
             <Tooltip
               key={key}
-              title={icon.title}
+              title={icon.title + ", Key: " + key}
               placement="bottom"
               align={{ offset: [0, -7, 0, 0] }}
               destroyTooltipOnHide
@@ -273,7 +297,8 @@ const IconPopup = (props: {
                   onChangeIcon(key);
                 }}
               >
-                {icon.getView()}
+                <IconWrapper>{icon.getView()}</IconWrapper>
+                <IconKeyDisplay>{key}</IconKeyDisplay>
               </IconItemContainer>
             </Tooltip>
           ))}
@@ -299,9 +324,9 @@ const IconPopup = (props: {
         </SearchDiv>
         <IconListWrapper>
           <IconList
-            width={394}
-            height={312}
-            rowHeight={48}
+            width={550}
+            height={400}
+            rowHeight={80}
             rowCount={Math.ceil(searchResults.length / columnNum)}
             rowRenderer={rowRenderer}
           />
diff --git a/client/packages/lowcoder/src/comps/comps/iconComp.tsx b/client/packages/lowcoder/src/comps/comps/iconComp.tsx
index 41b73da718..d2db615961 100644
--- a/client/packages/lowcoder/src/comps/comps/iconComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/iconComp.tsx
@@ -26,33 +26,31 @@ import {
   clickEvent,
   eventHandlerControl,
 } from "../controls/eventHandlerControl";
+import { useContext } from "react";
+import { EditorContext } from "comps/editorState";
 
 const Container = styled.div<{ $style: IconStyleType | undefined }>`
-  height: 100%;
-  width: 100%;
   display: flex;
   align-items: center;
   justify-content: center;
-  svg {
-    object-fit: contain;
-    pointer-events: auto;
-  }
-  ${(props) => props.$style && getStyle(props.$style)}
-`;
 
-const getStyle = (style: IconStyleType) => {
-  return css`
+  ${(props) => props.$style && css`
+    height: calc(100% - ${props.$style.margin});
+    width: calc(100% - ${props.$style.margin});
+    padding: ${props.$style.padding};
+    margin: ${props.$style.margin};
+    border: ${props.$style.borderWidth} solid ${props.$style.border};
+    border-radius: ${props.$style.radius};
+    background: ${props.$style.background};
     svg {
-      color: ${style.fill};
+      max-width: ${widthCalculator(props.$style.margin)};
+      max-height: ${heightCalculator(props.$style.margin)};
+      color: ${props.$style.fill};
+      object-fit: contain;
+      pointer-events: auto;
     }
-    padding: ${style.padding};
-    border: 1px solid ${style.border};
-    border-radius: ${style.radius};
-    margin: ${style.margin};
-    max-width: ${widthCalculator(style.margin)};
-    max-height: ${heightCalculator(style.margin)};
-  `;
-};
+  `}
+`;
 
 const EventOptions = [clickEvent] as const;
 
@@ -94,7 +92,7 @@ const IconView = (props: RecordConstructorToView<typeof childrenMap>) => {
         }}
         onClick={() => props.onEvent("click")}
       >
-        {props.icon}
+        {props.icon}  
       </Container>
     </ReactResizeDetector>
   );
@@ -109,23 +107,29 @@ let IconBasicComp = (function () {
             label: trans("iconComp.icon"),
             IconType: "All",
           })}
-          {children.autoHeight.propertyView({
+          
+        </Section> 
+
+        {["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && (
+          <Section name={sectionNames.interaction}>
+            {children.onEvent.getPropertyView()}
+            {hiddenPropertyView(children)}
+          </Section>
+        )}
+
+        {["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && (
+          <><Section name={sectionNames.layout}>
+            {children.autoHeight.propertyView({
             label: trans("iconComp.autoSize"),
           })}
-          {!children.autoHeight.getView() &&
+            {!children.autoHeight.getView() &&
             children.iconSize.propertyView({
               label: trans("iconComp.iconSize"),
             })}
-        </Section>
-        <Section name={sectionNames.interaction}>
-          {children.onEvent.getPropertyView()}
-        </Section>
-        <Section name={sectionNames.layout}>
-          {hiddenPropertyView(children)}
-        </Section>
-        <Section name={sectionNames.style}>
-          {children.style.getPropertyView()}
-        </Section>
+          </Section><Section name={sectionNames.style}>
+              {children.style.getPropertyView()}
+            </Section></>
+        )}
       </>
     ))
     .build();
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index 9626e4fbf8..11f4e012d7 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -1078,8 +1078,14 @@ export const NavigationStyle = [
 
 export const ImageStyle = [getStaticBorder("#00000000"), RADIUS, BORDER_WIDTH, MARGIN, PADDING] as const;
 
-export const IconStyle = [getStaticBackground("#00000000"),
-  getStaticBorder("#00000000"), FILL, RADIUS, MARGIN, PADDING] as const;
+export const IconStyle = [
+  getStaticBackground("#00000000"),
+  getStaticBorder("#00000000"), 
+  FILL,
+  RADIUS,
+  BORDER_WIDTH,
+  MARGIN, 
+  PADDING] as const;
 
 
 export const ListViewStyle = BG_STATIC_BORDER_RADIUS;

From af08bea25440514fb425024d8e7cbb96213db6fd Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 22 Feb 2024 21:05:05 +0000
Subject: [PATCH 80/97] Bump @dnd-kit/modifiers from 5.0.0 to 7.0.0 in /client

Bumps [@dnd-kit/modifiers](https://github.com/clauderic/dnd-kit/tree/HEAD/packages/modifiers) from 5.0.0 to 7.0.0.
- [Release notes](https://github.com/clauderic/dnd-kit/releases)
- [Changelog](https://github.com/clauderic/dnd-kit/blob/master/packages/modifiers/CHANGELOG.md)
- [Commits](https://github.com/clauderic/dnd-kit/commits/@dnd-kit/modifiers@7.0.0/packages/modifiers)

---
updated-dependencies:
- dependency-name: "@dnd-kit/modifiers"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
---
 client/packages/lowcoder/package.json |  2 +-
 client/yarn.lock                      | 17 +++++++++--------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/client/packages/lowcoder/package.json b/client/packages/lowcoder/package.json
index addc573f83..f9625024b4 100644
--- a/client/packages/lowcoder/package.json
+++ b/client/packages/lowcoder/package.json
@@ -16,7 +16,7 @@
     "@codemirror/lang-sql": "^6.5.4",
     "@codemirror/search": "^6.5.5",
     "@dnd-kit/core": "^5.0.1",
-    "@dnd-kit/modifiers": "^5.0.0",
+    "@dnd-kit/modifiers": "^7.0.0",
     "@dnd-kit/sortable": "^6.0.0",
     "@dnd-kit/utilities": "^3.1.0",
     "@fortawesome/fontawesome-svg-core": "^6.5.1",
diff --git a/client/yarn.lock b/client/yarn.lock
index 3851091465..6d5e23611a 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -1982,15 +1982,16 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@dnd-kit/modifiers@npm:^5.0.0":
-  version: 5.0.0
-  resolution: "@dnd-kit/modifiers@npm:5.0.0"
+"@dnd-kit/modifiers@npm:^7.0.0":
+  version: 7.0.0
+  resolution: "@dnd-kit/modifiers@npm:7.0.0"
   dependencies:
-    "@dnd-kit/utilities": ^3.1.0
+    "@dnd-kit/utilities": ^3.2.2
     tslib: ^2.0.0
   peerDependencies:
-    "@dnd-kit/core": ^5.0.0
-  checksum: 93889b8cfc3ba787f8bddaddd4428c121065a02752a5f8dfa38774441c3466b7a9f24555144aced93e2c051087deb01bd073d91654ff1eda28e564591bf700aa
+    "@dnd-kit/core": ^6.1.0
+    react: ">=16.8.0"
+  checksum: 176f76a552a2692a205f7fe647c836aa7ded7f0fdc3370407f3633c153139fe838cb85e59cbc3b156377cc8fe3fb7b72af15b97ed3de15cec904eae35f0c36e6
   languageName: node
   linkType: hard
 
@@ -2007,7 +2008,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@dnd-kit/utilities@npm:^3.1.0":
+"@dnd-kit/utilities@npm:^3.1.0, @dnd-kit/utilities@npm:^3.2.2":
   version: 3.2.2
   resolution: "@dnd-kit/utilities@npm:3.2.2"
   dependencies:
@@ -12024,7 +12025,7 @@ __metadata:
     "@codemirror/lang-sql": ^6.5.4
     "@codemirror/search": ^6.5.5
     "@dnd-kit/core": ^5.0.1
-    "@dnd-kit/modifiers": ^5.0.0
+    "@dnd-kit/modifiers": ^7.0.0
     "@dnd-kit/sortable": ^6.0.0
     "@dnd-kit/utilities": ^3.1.0
     "@fortawesome/fontawesome-svg-core": ^6.5.1

From 925dec30b2dc6fb19684409db606e96bf6796988 Mon Sep 17 00:00:00 2001
From: zaini <alimzaini@outlook.com>
Date: Thu, 22 Feb 2024 14:01:25 -0800
Subject: [PATCH 81/97] Add deploy Lowcoder via Stitch badge

---
 README.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/README.md b/README.md
index 807ffabf81..493858073a 100644
--- a/README.md
+++ b/README.md
@@ -88,6 +88,8 @@ And we mean it... Day by day!
 You can access Lowcoder from [cloud-hosted version](https://app.lowcoder.cloud/) at any time, or use the following resources for self-host Lowcoder on different platforms:
 - [Docker](https://docs.lowcoder.cloud/lowcoder-documentation/setup-and-run/self-hosting)
 
+[![Deploy to AWS using Stitch](https://img.shields.io/badge/deploy_with-Stitch-%23E369F7?logo=amazonaws&color=%23E369F7)](https://deploy.stitch.tech/lowcoder/lowcoder)
+
 ## 💪 Contributing
 - Language support: If you have experience with a language that isn't currently supported by our product, send us a pull request.
 - Create and share components or demos: If you've created something that might be useful to others, add the link here.

From 1c4748f4e896de8493f897d5ca1bfbf311d6beab Mon Sep 17 00:00:00 2001
From: zaini <alimzaini@outlook.com>
Date: Thu, 22 Feb 2024 14:05:50 -0800
Subject: [PATCH 82/97] Update README

---
 README.md | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 493858073a..ef329a7277 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
 > **Note**  
 > Lowcoder continues from the abandoned Openblocks project. For more information [read our manifesto](MANIFESTO.md).
 
+[![Deploy to AWS using Stitch](https://img.shields.io/badge/deploy_with-Stitch-%23E369F7?logo=amazonaws&color=%23E369F7)](https://deploy.stitch.tech/lowcoder/lowcoder)
+
 <div align="center">
     <h1 style="border-bottom: none; margin-bottom: 0">Lowcoder</h1>
     <h3 style="margin-top: 0">This is the only Platform, which closes the gap between App Development, Website Development and Slide-Presentations.</h3>
@@ -85,11 +87,11 @@ And we mean it... Day by day!
 🔎 Submit an issue here on [GitHub](https://github.com/lowcoder-org/lowcoder/issues)
 
 ## 💻 Deployment Options
+[![Deploy to AWS using Stitch](https://img.shields.io/badge/deploy_with-Stitch-%23E369F7?logo=amazonaws&color=%23E369F7)](https://deploy.stitch.tech/lowcoder/lowcoder)
+
 You can access Lowcoder from [cloud-hosted version](https://app.lowcoder.cloud/) at any time, or use the following resources for self-host Lowcoder on different platforms:
 - [Docker](https://docs.lowcoder.cloud/lowcoder-documentation/setup-and-run/self-hosting)
 
-[![Deploy to AWS using Stitch](https://img.shields.io/badge/deploy_with-Stitch-%23E369F7?logo=amazonaws&color=%23E369F7)](https://deploy.stitch.tech/lowcoder/lowcoder)
-
 ## 💪 Contributing
 - Language support: If you have experience with a language that isn't currently supported by our product, send us a pull request.
 - Create and share components or demos: If you've created something that might be useful to others, add the link here.

From 8c7c873745716cd1153bed49e733778e0e2d161c Mon Sep 17 00:00:00 2001
From: Imtanan Aziz Toor <imtanan.aziz@ikhwatech.com>
Date: Fri, 23 Feb 2024 12:55:13 +0500
Subject: [PATCH 83/97] Radio component styling added

---
 .../comps/selectInputComp/checkboxComp.tsx    | 12 ++++++++-
 .../comps/comps/selectInputComp/radioComp.tsx |  6 ++++-
 .../comps/controls/styleControlConstants.tsx  | 26 ++++++++++---------
 3 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx
index 8152980d56..5a4a22e17a 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx
@@ -38,6 +38,7 @@ export const getStyle = (style: CheckboxStyleType) => {
         .ant-checkbox-inner {
           background-color: ${style.checkedBackground};
           border-color: ${style.checkedBackground};
+          border-width:${!!style.borderWidth ? style.borderWidth : '2px'};
 
           &::after {
             border-color: ${style.checked};
@@ -46,6 +47,7 @@ export const getStyle = (style: CheckboxStyleType) => {
 
         &::after {
           border-color: ${style.checkedBackground};
+          border-width:${!!style.borderWidth ? style.borderWidth : '2px'};
           border-radius: ${style.radius};
         }
       }
@@ -54,15 +56,23 @@ export const getStyle = (style: CheckboxStyleType) => {
         border-radius: ${style.radius};
         background-color: ${style.uncheckedBackground};
         border-color: ${style.uncheckedBorder};
+        border-width:${!!style.borderWidth ? style.borderWidth : '2px'};
       }
 
       &:hover .ant-checkbox-inner,
       .ant-checkbox:hover .ant-checkbox-inner,
       .ant-checkbox-input:focus + .ant-checkbox-inner {
         border-color: ${style.checkedBackground};
+        border-width:${!!style.borderWidth ? style.borderWidth : '2px'};
       }
     }
 
+    .ant-checkbox-group-item {
+      font-family:${style.fontFamily};
+      font-size:${style.textSize};
+      font-weight:${style.textWeight};
+      font-style:${style.fontStyle};
+    }
     .ant-checkbox-wrapper {
       padding: ${style.padding};
       .ant-checkbox-inner,
@@ -73,7 +83,7 @@ export const getStyle = (style: CheckboxStyleType) => {
   `;
 };
 
-const CheckboxGroup = styled(AntdCheckboxGroup)<{
+const CheckboxGroup = styled(AntdCheckboxGroup) <{
   $style: CheckboxStyleType;
   $layout: ValueFromOption<typeof RadioLayoutOptions>;
 }>`
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx
index e1bc7033ce..af98eee25f 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx
@@ -21,6 +21,10 @@ const getStyle = (style: RadioStyleType) => {
       padding: ${style.padding};
       span:not(.ant-radio) {
         ${EllipsisTextCss};
+        font-family:${style.fontFamily};
+        font-size:${style.textSize};
+        font-weight:${style.textWeight};
+        font-style:${style.fontStyle};
       }
 
       .ant-radio-checked {
@@ -37,7 +41,7 @@ const getStyle = (style: RadioStyleType) => {
       .ant-radio-inner {
         background-color: ${style.uncheckedBackground};
         border-color: ${style.uncheckedBorder};
-
+        border-width:${style.borderWidth};
         &::after {
           background-color: ${style.checked};
         }
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index 49bbc52ec8..f1b4d4add0 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -841,7 +841,8 @@ function checkAndUncheck() {
 }
 
 export const CheckboxStyle = [
-  LABEL,
+  // LABEL,
+  ...replaceAndMergeMultipleStyles(STYLING_FIELDS_SEQUENCE, 'text', [LABEL, STATIC_TEXT, VALIDATE]).filter((style) => style.name !== 'border'),
   ...checkAndUncheck(),
   {
     name: "checked",
@@ -850,15 +851,16 @@ export const CheckboxStyle = [
     depType: DEP_TYPE.CONTRAST_TEXT,
     transformer: contrastText,
   },
-  RADIUS,
-  STATIC_TEXT,
-  VALIDATE,
-  MARGIN,
-  PADDING,
+  // RADIUS,
+  // STATIC_TEXT,
+  // VALIDATE,
+  // MARGIN,
+  // PADDING,
 ] as const;
 
 export const RadioStyle = [
-  LABEL,
+  // LABEL,
+  ...replaceAndMergeMultipleStyles(STYLING_FIELDS_SEQUENCE, 'text', [LABEL, STATIC_TEXT, VALIDATE]).filter((style) => style.name !== 'border' && style.name !== 'radius'),
   ...checkAndUncheck(),
   {
     name: "checked",
@@ -867,10 +869,10 @@ export const RadioStyle = [
     depType: DEP_TYPE.SELF,
     transformer: toSelf,
   },
-  STATIC_TEXT,
-  VALIDATE,
-  MARGIN,
-  PADDING,
+  // STATIC_TEXT,
+  // VALIDATE,
+  // MARGIN,
+  // PADDING,
 ] as const;
 
 export const SegmentStyle = [
@@ -1019,7 +1021,7 @@ export const TableColumnLinkStyle = [
 export const FileStyle = [
   // ...getStaticBgBorderRadiusByBg(SURFACE_COLOR), 
   getStaticBackground(SURFACE_COLOR),
-  ...replaceAndMergeMultipleStyles(STYLING_FIELDS_SEQUENCE,'border',[getStaticBorder('#00000000')]),
+  ...replaceAndMergeMultipleStyles(STYLING_FIELDS_SEQUENCE, 'border', [getStaticBorder('#00000000')]),
   // TEXT, ACCENT, MARGIN, PADDING
 ] as const;
 

From d91a25c218cdeb86e3ac3351cbd8882ed6918755 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Fri, 23 Feb 2024 10:44:39 +0100
Subject: [PATCH 84/97] Preparing Dynamic Icon Loading

---
 client/package.json                           |    3 +-
 .../components/iconSelect/loadDynamicIcon.tsx | 1645 +++++++++++++++++
 .../lowcoder-design/src/icons/antIcon.tsx     |   21 -
 client/yarn.lock                              |   10 -
 4 files changed, 1646 insertions(+), 33 deletions(-)
 create mode 100644 client/packages/lowcoder-design/src/components/iconSelect/loadDynamicIcon.tsx

diff --git a/client/package.json b/client/package.json
index fbed11fa2c..f9a524be54 100644
--- a/client/package.json
+++ b/client/package.json
@@ -1,6 +1,6 @@
 {
   "name": "lowcoder-root",
-  "version": "2.3.0",
+  "version": "2.3.1",
   "type": "module",
   "private": true,
   "workspaces": [
@@ -78,7 +78,6 @@
     "chalk": "4",
     "number-precision": "^1.6.0",
     "react-player": "^2.11.0",
-    "remixicon-react": "^1.0.0",
     "tui-image-editor": "^3.15.3"
   }
 }
diff --git a/client/packages/lowcoder-design/src/components/iconSelect/loadDynamicIcon.tsx b/client/packages/lowcoder-design/src/components/iconSelect/loadDynamicIcon.tsx
new file mode 100644
index 0000000000..eed1f71392
--- /dev/null
+++ b/client/packages/lowcoder-design/src/components/iconSelect/loadDynamicIcon.tsx
@@ -0,0 +1,1645 @@
+import React, { useState, useEffect } from 'react';
+
+
+// Function to dynamically import icons
+/* export const loadAntDIcon = async (iconName: string) => {
+  if (!iconName) return null;
+
+  try {
+    const module = await import(`@ant-design/icons`);
+    const IconComponent = (module as any)[iconName];
+    if (IconComponent) {
+      // Return the icon component if found
+      return <IconComponent />;
+    } else {
+      console.error(`Icon ${iconName} not found in @ant-design/icons`);
+      return null;
+    }
+  } catch (error) {
+    console.error(`Error loading icon ${iconName}:`, error);
+    return null;
+  }
+}; */
+
+interface DynamicIconComponentProps {
+  iconName: string;
+  iconSet?: string;
+}
+
+const loadDynamicIcon: React.FC<DynamicIconComponentProps> = ({ iconName, ...props }) => {
+  const [Icon, setIcon] = useState<React.ElementType>(() => null);
+
+  useEffect(() => {
+    const importIcon = async () => {
+      if (props.iconSet === 'remixicon') {
+        try {
+          const module = await import(`@remixicon/react/${iconName}`);
+          setIcon(() => module.default);
+        } catch (error) {
+          console.error(`Could not load icon ${iconName}:`, error);
+        }
+      }
+      if (props.iconSet === 'ant') {
+        try {
+          const module = await import(`@ant-design/icons`);
+          const IconComponent = (module as any)[iconName];
+          setIcon(() => IconComponent);
+        } catch (error) {
+          console.error(`Could not load icon ${iconName}:`, error);
+        }
+      }
+    };
+
+    importIcon();
+  }, [iconName]);
+
+  return Icon ? <Icon {...props} /> : null;
+};
+
+export default loadDynamicIcon;
+
+/// 
+
+/* import {
+  AccountBookFilled,
+  AccountBookOutlined,
+  AccountBookTwoTone,
+  AimOutlined,
+  AlertFilled,
+  AlertOutlined,
+  AlertTwoTone,
+  AlibabaOutlined,
+  AlignCenterOutlined,
+  AlignLeftOutlined,
+  AlignRightOutlined,
+  AlipayCircleFilled,
+  AlipayCircleOutlined,
+  AlipayOutlined,
+  AlipaySquareFilled,
+  AliwangwangFilled,
+  AliwangwangOutlined,
+  AliyunOutlined,
+  AmazonCircleFilled,
+  AmazonOutlined,
+  AmazonSquareFilled,
+  AndroidFilled,
+  AndroidOutlined,
+  AntCloudOutlined,
+  AntDesignOutlined,
+  ApartmentOutlined,
+  ApiFilled,
+  ApiOutlined,
+  ApiTwoTone,
+  AppleFilled,
+  AppleOutlined,
+  AppstoreAddOutlined,
+  AppstoreFilled,
+  AppstoreOutlined,
+  AppstoreTwoTone,
+  AreaChartOutlined,
+  ArrowDownOutlined,
+  ArrowLeftOutlined,
+  ArrowRightOutlined,
+  ArrowUpOutlined,
+  ArrowsAltOutlined,
+  AudioFilled,
+  AudioMutedOutlined,
+  AudioOutlined,
+  AudioTwoTone,
+  AuditOutlined,
+  BackwardFilled,
+  BackwardOutlined,
+  BankFilled,
+  BankOutlined,
+  BankTwoTone,
+  BarChartOutlined,
+  BarcodeOutlined,
+  BarsOutlined,
+  BehanceCircleFilled,
+  BehanceOutlined,
+  BehanceSquareFilled,
+  BehanceSquareOutlined,
+  BellFilled,
+  BellOutlined,
+  BellTwoTone,
+  BgColorsOutlined,
+  BlockOutlined,
+  BoldOutlined,
+  BookFilled,
+  BookOutlined,
+  BookTwoTone,
+  BorderBottomOutlined,
+  BorderHorizontalOutlined,
+  BorderInnerOutlined,
+  BorderLeftOutlined,
+  BorderOuterOutlined,
+  BorderOutlined,
+  BorderRightOutlined,
+  BorderTopOutlined,
+  BorderVerticleOutlined,
+  BorderlessTableOutlined,
+  BoxPlotFilled,
+  BoxPlotOutlined,
+  BoxPlotTwoTone,
+  BranchesOutlined,
+  BugFilled,
+  BugOutlined,
+  BugTwoTone,
+  BuildFilled,
+  BuildOutlined,
+  BuildTwoTone,
+  BulbFilled,
+  BulbOutlined,
+  BulbTwoTone,
+  CalculatorFilled,
+  CalculatorOutlined,
+  CalculatorTwoTone,
+  CalendarFilled,
+  CalendarOutlined,
+  CalendarTwoTone,
+  CameraFilled,
+  CameraOutlined,
+  CameraTwoTone,
+  CarFilled,
+  CarOutlined,
+  CarTwoTone,
+  CaretDownFilled,
+  CaretDownOutlined,
+  CaretLeftFilled,
+  CaretLeftOutlined,
+  CaretRightFilled,
+  CaretRightOutlined,
+  CaretUpFilled,
+  CaretUpOutlined,
+  CarryOutFilled,
+  CarryOutOutlined,
+  CarryOutTwoTone,
+  CheckCircleFilled,
+  CheckCircleOutlined,
+  CheckCircleTwoTone,
+  CheckOutlined,
+  CheckSquareFilled,
+  CheckSquareOutlined,
+  CheckSquareTwoTone,
+  ChromeFilled,
+  ChromeOutlined,
+  CiCircleFilled,
+  CiCircleOutlined,
+  CiCircleTwoTone,
+  CiOutlined,
+  CiTwoTone,
+  ClearOutlined,
+  ClockCircleFilled,
+  ClockCircleOutlined,
+  ClockCircleTwoTone,
+  CloseCircleFilled,
+  CloseCircleOutlined,
+  CloseCircleTwoTone,
+  CloseOutlined,
+  CloseSquareFilled,
+  CloseSquareOutlined,
+  CloseSquareTwoTone,
+  CloudDownloadOutlined,
+  CloudFilled,
+  CloudOutlined,
+  CloudServerOutlined,
+  CloudSyncOutlined,
+  CloudTwoTone,
+  CloudUploadOutlined,
+  ClusterOutlined,
+  CodeFilled,
+  CodeOutlined,
+  CodeSandboxCircleFilled,
+  CodeSandboxOutlined,
+  CodeSandboxSquareFilled,
+  CodeTwoTone,
+  CodepenCircleFilled,
+  CodepenCircleOutlined,
+  CodepenOutlined,
+  CodepenSquareFilled,
+  CoffeeOutlined,
+  ColumnHeightOutlined,
+  ColumnWidthOutlined,
+  CommentOutlined,
+  CompassFilled,
+  CompassOutlined,
+  CompassTwoTone,
+  CompressOutlined,
+  ConsoleSqlOutlined,
+  ContactsFilled,
+  ContactsOutlined,
+  ContactsTwoTone,
+  ContainerFilled,
+  ContainerOutlined,
+  ContainerTwoTone,
+  ControlFilled,
+  ControlOutlined,
+  ControlTwoTone,
+  CopyFilled,
+  CopyOutlined,
+  CopyTwoTone,
+  CopyrightCircleFilled,
+  CopyrightCircleOutlined,
+  CopyrightCircleTwoTone,
+  CopyrightOutlined,
+  CopyrightTwoTone,
+  CreditCardFilled,
+  CreditCardOutlined,
+  CreditCardTwoTone,
+  CrownFilled,
+  CrownOutlined,
+  CrownTwoTone,
+  CustomerServiceFilled,
+  CustomerServiceOutlined,
+  CustomerServiceTwoTone,
+  DashOutlined,
+  DashboardFilled,
+  DashboardOutlined,
+  DashboardTwoTone,
+  DatabaseFilled,
+  DatabaseOutlined,
+  DatabaseTwoTone,
+  DeleteColumnOutlined,
+  DeleteFilled,
+  DeleteOutlined,
+  DeleteRowOutlined,
+  DeleteTwoTone,
+  DeliveredProcedureOutlined,
+  DeploymentUnitOutlined,
+  DesktopOutlined,
+  DiffFilled,
+  DiffOutlined,
+  DiffTwoTone,
+  DingdingOutlined,
+  DingtalkCircleFilled,
+  DingtalkOutlined,
+  DingtalkSquareFilled,
+  DisconnectOutlined,
+  DislikeFilled,
+  DislikeOutlined,
+  DislikeTwoTone,
+  DollarCircleFilled,
+  DollarCircleOutlined,
+  DollarCircleTwoTone,
+  DollarOutlined,
+  DollarTwoTone,
+  DotChartOutlined,
+  DoubleLeftOutlined,
+  DoubleRightOutlined,
+  DownCircleFilled,
+  DownCircleOutlined,
+  DownCircleTwoTone,
+  DownOutlined,
+  DownSquareFilled,
+  DownSquareOutlined,
+  DownSquareTwoTone,
+  DownloadOutlined,
+  DragOutlined,
+  DribbbleCircleFilled,
+  DribbbleOutlined,
+  DribbbleSquareFilled,
+  DribbbleSquareOutlined,
+  DropboxCircleFilled,
+  DropboxOutlined,
+  DropboxSquareFilled,
+  EditFilled,
+  EditOutlined,
+  EditTwoTone,
+  EllipsisOutlined,
+  EnterOutlined,
+  EnvironmentFilled,
+  EnvironmentOutlined,
+  EnvironmentTwoTone,
+  EuroCircleFilled,
+  EuroCircleOutlined,
+  EuroCircleTwoTone,
+  EuroOutlined,
+  EuroTwoTone,
+  ExceptionOutlined,
+  ExclamationCircleFilled,
+  ExclamationCircleOutlined,
+  ExclamationCircleTwoTone,
+  ExclamationOutlined,
+  ExpandAltOutlined,
+  ExpandOutlined,
+  ExperimentFilled,
+  ExperimentOutlined,
+  ExperimentTwoTone,
+  ExportOutlined,
+  EyeFilled,
+  EyeInvisibleFilled,
+  EyeInvisibleOutlined,
+  EyeInvisibleTwoTone,
+  EyeOutlined,
+  EyeTwoTone,
+  FacebookFilled,
+  FacebookOutlined,
+  FallOutlined,
+  FastBackwardFilled,
+  FastBackwardOutlined,
+  FastForwardFilled,
+  FastForwardOutlined,
+  FieldBinaryOutlined,
+  FieldNumberOutlined,
+  FieldStringOutlined,
+  FieldTimeOutlined,
+  FileAddFilled,
+  FileAddOutlined,
+  FileAddTwoTone,
+  FileDoneOutlined,
+  FileExcelFilled,
+  FileExcelOutlined,
+  FileExcelTwoTone,
+  FileExclamationFilled,
+  FileExclamationOutlined,
+  FileExclamationTwoTone,
+  FileFilled,
+  FileGifOutlined,
+  FileImageFilled,
+  FileImageOutlined,
+  FileImageTwoTone,
+  FileJpgOutlined,
+  FileMarkdownFilled,
+  FileMarkdownOutlined,
+  FileMarkdownTwoTone,
+  FileOutlined,
+  FilePdfFilled,
+  FilePdfOutlined,
+  FilePdfTwoTone,
+  FilePptFilled,
+  FilePptOutlined,
+  FilePptTwoTone,
+  FileProtectOutlined,
+  FileSearchOutlined,
+  FileSyncOutlined,
+  FileTextFilled,
+  FileTextOutlined,
+  FileTextTwoTone,
+  FileTwoTone,
+  FileUnknownFilled,
+  FileUnknownOutlined,
+  FileUnknownTwoTone,
+  FileWordFilled,
+  FileWordOutlined,
+  FileWordTwoTone,
+  FileZipFilled,
+  FileZipOutlined,
+  FileZipTwoTone,
+  FilterFilled,
+  FilterOutlined,
+  FilterTwoTone,
+  FireFilled,
+  FireOutlined,
+  FireTwoTone,
+  FlagFilled,
+  FlagOutlined,
+  FlagTwoTone,
+  FolderAddFilled,
+  FolderAddOutlined,
+  FolderAddTwoTone,
+  FolderFilled,
+  FolderOpenFilled,
+  FolderOpenOutlined,
+  FolderOpenTwoTone,
+  FolderOutlined,
+  FolderTwoTone,
+  FolderViewOutlined,
+  FontColorsOutlined,
+  FontSizeOutlined,
+  ForkOutlined,
+  FormOutlined,
+  FormatPainterFilled,
+  FormatPainterOutlined,
+  ForwardFilled,
+  ForwardOutlined,
+  FrownFilled,
+  FrownOutlined,
+  FrownTwoTone,
+  FullscreenExitOutlined,
+  FullscreenOutlined,
+  FunctionOutlined,
+  FundFilled,
+  FundOutlined,
+  FundProjectionScreenOutlined,
+  FundTwoTone,
+  FundViewOutlined,
+  FunnelPlotFilled,
+  FunnelPlotOutlined,
+  FunnelPlotTwoTone,
+  GatewayOutlined,
+  GifOutlined,
+  GiftFilled,
+  GiftOutlined,
+  GiftTwoTone,
+  GithubFilled,
+  GithubOutlined,
+  GitlabFilled,
+  GitlabOutlined,
+  GlobalOutlined,
+  GoldFilled,
+  GoldOutlined,
+  GoldTwoTone,
+  GoldenFilled,
+  GoogleCircleFilled,
+  GoogleOutlined,
+  GooglePlusCircleFilled,
+  GooglePlusOutlined,
+  GooglePlusSquareFilled,
+  GoogleSquareFilled,
+  GroupOutlined,
+  HddFilled,
+  HddOutlined,
+  HddTwoTone,
+  HeartFilled,
+  HeartOutlined,
+  HeartTwoTone,
+  HeatMapOutlined,
+  HighlightFilled,
+  HighlightOutlined,
+  HighlightTwoTone,
+  HistoryOutlined,
+  HolderOutlined,
+  HomeFilled,
+  HomeOutlined,
+  HomeTwoTone,
+  HourglassFilled,
+  HourglassOutlined,
+  HourglassTwoTone,
+  Html5Filled,
+  Html5Outlined,
+  Html5TwoTone,
+  IdcardFilled,
+  IdcardOutlined,
+  IdcardTwoTone,
+  IeCircleFilled,
+  IeOutlined,
+  IeSquareFilled,
+  ImportOutlined,
+  InboxOutlined,
+  InfoCircleFilled,
+  InfoCircleOutlined,
+  InfoCircleTwoTone,
+  InfoOutlined,
+  InsertRowAboveOutlined,
+  InsertRowBelowOutlined,
+  InsertRowLeftOutlined,
+  InsertRowRightOutlined,
+  InstagramFilled,
+  InstagramOutlined,
+  InsuranceFilled,
+  InsuranceOutlined,
+  InsuranceTwoTone,
+  InteractionFilled,
+  InteractionOutlined,
+  InteractionTwoTone,
+  IssuesCloseOutlined,
+  ItalicOutlined,
+  KeyOutlined,
+  LaptopOutlined,
+  LayoutFilled,
+  LayoutOutlined,
+  LayoutTwoTone,
+  LeftCircleFilled,
+  LeftCircleOutlined,
+  LeftCircleTwoTone,
+  LeftOutlined,
+  LeftSquareFilled,
+  LeftSquareOutlined,
+  LeftSquareTwoTone,
+  LikeFilled,
+  LikeOutlined,
+  LikeTwoTone,
+  LineChartOutlined,
+  LineHeightOutlined,
+  LineOutlined,
+  LinkOutlined,
+  LinkedinFilled,
+  LinkedinOutlined,
+  Loading3QuartersOutlined,
+  LoadingOutlined,
+  LockFilled,
+  LockOutlined,
+  LockTwoTone,
+  LoginOutlined,
+  LogoutOutlined,
+  MacCommandFilled,
+  MacCommandOutlined,
+  MailFilled,
+  MailOutlined,
+  MailTwoTone,
+  ManOutlined,
+  MedicineBoxFilled,
+  MedicineBoxOutlined,
+  MedicineBoxTwoTone,
+  MediumCircleFilled,
+  MediumOutlined,
+  MediumSquareFilled,
+  MediumWorkmarkOutlined,
+  MehFilled,
+  MehOutlined,
+  MehTwoTone,
+  MenuFoldOutlined,
+  MenuOutlined,
+  MenuUnfoldOutlined,
+  MergeCellsOutlined,
+  MessageFilled,
+  MessageOutlined,
+  MessageTwoTone,
+  MinusCircleFilled,
+  MinusCircleOutlined,
+  MinusCircleTwoTone,
+  MinusOutlined,
+  MinusSquareFilled,
+  MinusSquareOutlined,
+  MinusSquareTwoTone,
+  MobileFilled,
+  MobileOutlined,
+  MobileTwoTone,
+  MoneyCollectFilled,
+  MoneyCollectOutlined,
+  MoneyCollectTwoTone,
+  MonitorOutlined,
+  MoreOutlined,
+  NodeCollapseOutlined,
+  NodeExpandOutlined,
+  NodeIndexOutlined,
+  NotificationFilled,
+  NotificationOutlined,
+  NotificationTwoTone,
+  NumberOutlined,
+  OneToOneOutlined,
+  OrderedListOutlined,
+  PaperClipOutlined,
+  PartitionOutlined,
+  PauseCircleFilled,
+  PauseCircleOutlined,
+  PauseCircleTwoTone,
+  PauseOutlined,
+  PayCircleFilled,
+  PayCircleOutlined,
+  PercentageOutlined,
+  PhoneFilled,
+  PhoneOutlined,
+  PhoneTwoTone,
+  PicCenterOutlined,
+  PicLeftOutlined,
+  PicRightOutlined,
+  PictureFilled,
+  PictureOutlined,
+  PictureTwoTone,
+  PieChartFilled,
+  PieChartOutlined,
+  PieChartTwoTone,
+  PlayCircleFilled,
+  PlayCircleOutlined,
+  PlayCircleTwoTone,
+  PlaySquareFilled,
+  PlaySquareOutlined,
+  PlaySquareTwoTone,
+  PlusCircleFilled,
+  PlusCircleOutlined,
+  PlusCircleTwoTone,
+  PlusOutlined,
+  PlusSquareFilled,
+  PlusSquareOutlined,
+  PlusSquareTwoTone,
+  PoundCircleFilled,
+  PoundCircleOutlined,
+  PoundCircleTwoTone,
+  PoundOutlined,
+  PoweroffOutlined,
+  PrinterFilled,
+  PrinterOutlined,
+  PrinterTwoTone,
+  ProfileFilled,
+  ProfileOutlined,
+  ProfileTwoTone,
+  ProjectFilled,
+  ProjectOutlined,
+  ProjectTwoTone,
+  PropertySafetyFilled,
+  PropertySafetyOutlined,
+  PropertySafetyTwoTone,
+  PullRequestOutlined,
+  PushpinFilled,
+  PushpinOutlined,
+  PushpinTwoTone,
+  QqCircleFilled,
+  QqOutlined,
+  QqSquareFilled,
+  QrcodeOutlined,
+  QuestionCircleFilled,
+  QuestionCircleOutlined,
+  QuestionCircleTwoTone,
+  QuestionOutlined,
+  RadarChartOutlined,
+  RadiusBottomleftOutlined,
+  RadiusBottomrightOutlined,
+  RadiusSettingOutlined,
+  RadiusUpleftOutlined,
+  RadiusUprightOutlined,
+  ReadFilled,
+  ReadOutlined,
+  ReconciliationFilled,
+  ReconciliationOutlined,
+  ReconciliationTwoTone,
+  RedEnvelopeFilled,
+  RedEnvelopeOutlined,
+  RedEnvelopeTwoTone,
+  RedditCircleFilled,
+  RedditOutlined,
+  RedditSquareFilled,
+  RedoOutlined,
+  ReloadOutlined,
+  RestFilled,
+  RestOutlined,
+  RestTwoTone,
+  RetweetOutlined,
+  RightCircleFilled,
+  RightCircleOutlined,
+  RightCircleTwoTone,
+  RightOutlined,
+  RightSquareFilled,
+  RightSquareOutlined,
+  RightSquareTwoTone,
+  RiseOutlined,
+  RobotFilled,
+  RobotOutlined,
+  RocketFilled,
+  RocketOutlined,
+  RocketTwoTone,
+  RollbackOutlined,
+  RotateLeftOutlined,
+  RotateRightOutlined,
+  SafetyCertificateFilled,
+  SafetyCertificateOutlined,
+  SafetyCertificateTwoTone,
+  SafetyOutlined,
+  SaveFilled,
+  SaveOutlined,
+  SaveTwoTone,
+  ScanOutlined,
+  ScheduleFilled,
+  ScheduleOutlined,
+  ScheduleTwoTone,
+  ScissorOutlined,
+  SearchOutlined,
+  SecurityScanFilled,
+  SecurityScanOutlined,
+  SecurityScanTwoTone,
+  SelectOutlined,
+  SendOutlined,
+  SettingFilled,
+  SettingOutlined,
+  SettingTwoTone,
+  ShakeOutlined,
+  ShareAltOutlined,
+  ShopFilled,
+  ShopOutlined,
+  ShopTwoTone,
+  ShoppingCartOutlined,
+  ShoppingFilled,
+  ShoppingOutlined,
+  ShoppingTwoTone,
+  ShrinkOutlined,
+  SignalFilled,
+  SisternodeOutlined,
+  SketchCircleFilled,
+  SketchOutlined,
+  SketchSquareFilled,
+  SkinFilled,
+  SkinOutlined,
+  SkinTwoTone,
+  SkypeFilled,
+  SkypeOutlined,
+  SlackCircleFilled,
+  SlackOutlined,
+  SlackSquareFilled,
+  SlackSquareOutlined,
+  SlidersFilled,
+  SlidersOutlined,
+  SlidersTwoTone,
+  SmallDashOutlined,
+  SmileFilled,
+  SmileOutlined,
+  SmileTwoTone,
+  SnippetsFilled,
+  SnippetsOutlined,
+  SnippetsTwoTone,
+  SolutionOutlined,
+  SortAscendingOutlined,
+  SortDescendingOutlined,
+  SoundFilled,
+  SoundOutlined,
+  SoundTwoTone,
+  SplitCellsOutlined,
+  StarFilled,
+  StarOutlined,
+  StarTwoTone,
+  StepBackwardFilled,
+  StepBackwardOutlined,
+  StepForwardFilled,
+  StepForwardOutlined,
+  StockOutlined,
+  StopFilled,
+  StopOutlined,
+  StopTwoTone,
+  StrikethroughOutlined,
+  SubnodeOutlined,
+  SwapLeftOutlined,
+  SwapOutlined,
+  SwapRightOutlined,
+  SwitcherFilled,
+  SwitcherOutlined,
+  SwitcherTwoTone,
+  SyncOutlined,
+  TableOutlined,
+  TabletFilled,
+  TabletOutlined,
+  TabletTwoTone,
+  TagFilled,
+  TagOutlined,
+  TagTwoTone,
+  TagsFilled,
+  TagsOutlined,
+  TagsTwoTone,
+  TaobaoCircleFilled,
+  TaobaoCircleOutlined,
+  TaobaoOutlined,
+  TaobaoSquareFilled,
+  TeamOutlined,
+  ThunderboltFilled,
+  ThunderboltOutlined,
+  ThunderboltTwoTone,
+  ToTopOutlined,
+  ToolFilled,
+  ToolOutlined,
+  ToolTwoTone,
+  TrademarkCircleFilled,
+  TrademarkCircleOutlined,
+  TrademarkCircleTwoTone,
+  TrademarkOutlined,
+  TransactionOutlined,
+  TranslationOutlined,
+  TrophyFilled,
+  TrophyOutlined,
+  TrophyTwoTone,
+  TwitterCircleFilled,
+  TwitterOutlined,
+  TwitterSquareFilled,
+  UnderlineOutlined,
+  UndoOutlined,
+  UngroupOutlined,
+  UnlockFilled,
+  UnlockOutlined,
+  UnlockTwoTone,
+  UnorderedListOutlined,
+  UpCircleFilled,
+  UpCircleOutlined,
+  UpCircleTwoTone,
+  UpOutlined,
+  UpSquareFilled,
+  UpSquareOutlined,
+  UpSquareTwoTone,
+  UploadOutlined,
+  UsbFilled,
+  UsbOutlined,
+  UsbTwoTone,
+  UserAddOutlined,
+  UserDeleteOutlined,
+  UserOutlined,
+  UserSwitchOutlined,
+  UsergroupAddOutlined,
+  UsergroupDeleteOutlined,
+  VerifiedOutlined,
+  VerticalAlignBottomOutlined,
+  VerticalAlignMiddleOutlined,
+  VerticalAlignTopOutlined,
+  VerticalLeftOutlined,
+  VerticalRightOutlined,
+  VideoCameraAddOutlined,
+  VideoCameraFilled,
+  VideoCameraOutlined,
+  VideoCameraTwoTone,
+  WalletFilled,
+  WalletOutlined,
+  WalletTwoTone,
+  WarningFilled,
+  WarningOutlined,
+  WarningTwoTone,
+  WechatFilled,
+  WechatOutlined,
+  WeiboCircleFilled,
+  WeiboCircleOutlined,
+  WeiboOutlined,
+  WeiboSquareFilled,
+  WeiboSquareOutlined,
+  WhatsAppOutlined,
+  WifiOutlined,
+  WindowsFilled,
+  WindowsOutlined,
+  WomanOutlined,
+  YahooFilled,
+  YahooOutlined,
+  YoutubeFilled,
+  YoutubeOutlined,
+  YuqueFilled,
+  YuqueOutlined,
+  ZhihuCircleFilled,
+  ZhihuOutlined,
+  ZhihuSquareFilled,
+  ZoomInOutlined,
+  ZoomOutOutlined,
+} from "@ant-design/icons";
+
+export const ANTDICON = {
+  accountbookfilled: <AccountBookFilled />,
+  accountbookoutlined: <AccountBookOutlined />,
+  accountbooktwotone: <AccountBookTwoTone />,
+  aimoutlined: <AimOutlined />,
+  alertfilled: <AlertFilled />,
+  alertoutlined: <AlertOutlined />,
+  alerttwotone: <AlertTwoTone />,
+  alibabaoutlined: <AlibabaOutlined />,
+  aligncenteroutlined: <AlignCenterOutlined />,
+  alignleftoutlined: <AlignLeftOutlined />,
+  alignrightoutlined: <AlignRightOutlined />,
+  alipaycirclefilled: <AlipayCircleFilled />,
+  alipaycircleoutlined: <AlipayCircleOutlined />,
+  alipayoutlined: <AlipayOutlined />,
+  alipaysquarefilled: <AlipaySquareFilled />,
+  aliwangwangfilled: <AliwangwangFilled />,
+  aliwangwangoutlined: <AliwangwangOutlined />,
+  aliyunoutlined: <AliyunOutlined />,
+  amazoncirclefilled: <AmazonCircleFilled />,
+  amazonoutlined: <AmazonOutlined />,
+  amazonsquarefilled: <AmazonSquareFilled />,
+  androidfilled: <AndroidFilled />,
+  androidoutlined: <AndroidOutlined />,
+  antcloudoutlined: <AntCloudOutlined />,
+  antdesignoutlined: <AntDesignOutlined />,
+  apartmentoutlined: <ApartmentOutlined />,
+  apifilled: <ApiFilled />,
+  apioutlined: <ApiOutlined />,
+  apitwotone: <ApiTwoTone />,
+  applefilled: <AppleFilled />,
+  appleoutlined: <AppleOutlined />,
+  appstoreaddoutlined: <AppstoreAddOutlined />,
+  appstorefilled: <AppstoreFilled />,
+  appstoreoutlined: <AppstoreOutlined />,
+  appstoretwotone: <AppstoreTwoTone />,
+  areachartoutlined: <AreaChartOutlined />,
+  arrowdownoutlined: <ArrowDownOutlined />,
+  arrowleftoutlined: <ArrowLeftOutlined />,
+  arrowrightoutlined: <ArrowRightOutlined />,
+  arrowupoutlined: <ArrowUpOutlined />,
+  arrowsaltoutlined: <ArrowsAltOutlined />,
+  audiofilled: <AudioFilled />,
+  audiomutedoutlined: <AudioMutedOutlined />,
+  audiooutlined: <AudioOutlined />,
+  audiotwotone: <AudioTwoTone />,
+  auditoutlined: <AuditOutlined />,
+  backwardfilled: <BackwardFilled />,
+  backwardoutlined: <BackwardOutlined />,
+  bankfilled: <BankFilled />,
+  bankoutlined: <BankOutlined />,
+  banktwotone: <BankTwoTone />,
+  barchartoutlined: <BarChartOutlined />,
+  barcodeoutlined: <BarcodeOutlined />,
+  barsoutlined: <BarsOutlined />,
+  behancecirclefilled: <BehanceCircleFilled />,
+  behanceoutlined: <BehanceOutlined />,
+  behancesquarefilled: <BehanceSquareFilled />,
+  behancesquareoutlined: <BehanceSquareOutlined />,
+  bellfilled: <BellFilled />,
+  belloutlined: <BellOutlined />,
+  belltwotone: <BellTwoTone />,
+  bgcolorsoutlined: <BgColorsOutlined />,
+  blockoutlined: <BlockOutlined />,
+  boldoutlined: <BoldOutlined />,
+  bookfilled: <BookFilled />,
+  bookoutlined: <BookOutlined />,
+  booktwotone: <BookTwoTone />,
+  borderbottomoutlined: <BorderBottomOutlined />,
+  borderhorizontaloutlined: <BorderHorizontalOutlined />,
+  borderinneroutlined: <BorderInnerOutlined />,
+  borderleftoutlined: <BorderLeftOutlined />,
+  borderouteroutlined: <BorderOuterOutlined />,
+  borderoutlined: <BorderOutlined />,
+  borderrightoutlined: <BorderRightOutlined />,
+  bordertopoutlined: <BorderTopOutlined />,
+  borderverticleoutlined: <BorderVerticleOutlined />,
+  borderlesstableoutlined: <BorderlessTableOutlined />,
+  boxplotfilled: <BoxPlotFilled />,
+  boxplotoutlined: <BoxPlotOutlined />,
+  boxplottwotone: <BoxPlotTwoTone />,
+  branchesoutlined: <BranchesOutlined />,
+  bugfilled: <BugFilled />,
+  bugoutlined: <BugOutlined />,
+  bugtwotone: <BugTwoTone />,
+  buildfilled: <BuildFilled />,
+  buildoutlined: <BuildOutlined />,
+  buildtwotone: <BuildTwoTone />,
+  bulbfilled: <BulbFilled />,
+  bulboutlined: <BulbOutlined />,
+  bulbtwotone: <BulbTwoTone />,
+  calculatorfilled: <CalculatorFilled />,
+  calculatoroutlined: <CalculatorOutlined />,
+  calculatortwotone: <CalculatorTwoTone />,
+  calendarfilled: <CalendarFilled />,
+  calendaroutlined: <CalendarOutlined />,
+  calendartwotone: <CalendarTwoTone />,
+  camerafilled: <CameraFilled />,
+  cameraoutlined: <CameraOutlined />,
+  cameratwotone: <CameraTwoTone />,
+  carfilled: <CarFilled />,
+  caroutlined: <CarOutlined />,
+  cartwotone: <CarTwoTone />,
+  caretdownfilled: <CaretDownFilled />,
+  caretdownoutlined: <CaretDownOutlined />,
+  caretleftfilled: <CaretLeftFilled />,
+  caretleftoutlined: <CaretLeftOutlined />,
+  caretrightfilled: <CaretRightFilled />,
+  caretrightoutlined: <CaretRightOutlined />,
+  caretupfilled: <CaretUpFilled />,
+  caretupoutlined: <CaretUpOutlined />,
+  carryoutfilled: <CarryOutFilled />,
+  carryoutoutlined: <CarryOutOutlined />,
+  carryouttwotone: <CarryOutTwoTone />,
+  checkcirclefilled: <CheckCircleFilled />,
+  checkcircleoutlined: <CheckCircleOutlined />,
+  checkcircletwotone: <CheckCircleTwoTone />,
+  checkoutlined: <CheckOutlined />,
+  checksquarefilled: <CheckSquareFilled />,
+  checksquareoutlined: <CheckSquareOutlined />,
+  checksquaretwotone: <CheckSquareTwoTone />,
+  chromefilled: <ChromeFilled />,
+  chromeoutlined: <ChromeOutlined />,
+  cicirclefilled: <CiCircleFilled />,
+  cicircleoutlined: <CiCircleOutlined />,
+  cicircletwotone: <CiCircleTwoTone />,
+  cioutlined: <CiOutlined />,
+  citwotone: <CiTwoTone />,
+  clearoutlined: <ClearOutlined />,
+  clockcirclefilled: <ClockCircleFilled />,
+  clockcircleoutlined: <ClockCircleOutlined />,
+  clockcircletwotone: <ClockCircleTwoTone />,
+  closecirclefilled: <CloseCircleFilled />,
+  closecircleoutlined: <CloseCircleOutlined />,
+  closecircletwotone: <CloseCircleTwoTone />,
+  closeoutlined: <CloseOutlined />,
+  closesquarefilled: <CloseSquareFilled />,
+  closesquareoutlined: <CloseSquareOutlined />,
+  closesquaretwotone: <CloseSquareTwoTone />,
+  clouddownloadoutlined: <CloudDownloadOutlined />,
+  cloudfilled: <CloudFilled />,
+  cloudoutlined: <CloudOutlined />,
+  cloudserveroutlined: <CloudServerOutlined />,
+  cloudsyncoutlined: <CloudSyncOutlined />,
+  cloudtwotone: <CloudTwoTone />,
+  clouduploadoutlined: <CloudUploadOutlined />,
+  clusteroutlined: <ClusterOutlined />,
+  codefilled: <CodeFilled />,
+  codeoutlined: <CodeOutlined />,
+  codesandboxcirclefilled: <CodeSandboxCircleFilled />,
+  codesandboxoutlined: <CodeSandboxOutlined />,
+  codesandboxsquarefilled: <CodeSandboxSquareFilled />,
+  codetwotone: <CodeTwoTone />,
+  codepencirclefilled: <CodepenCircleFilled />,
+  codepencircleoutlined: <CodepenCircleOutlined />,
+  codepenoutlined: <CodepenOutlined />,
+  codepensquarefilled: <CodepenSquareFilled />,
+  coffeeoutlined: <CoffeeOutlined />,
+  columnheightoutlined: <ColumnHeightOutlined />,
+  columnwidthoutlined: <ColumnWidthOutlined />,
+  commentoutlined: <CommentOutlined />,
+  compassfilled: <CompassFilled />,
+  compassoutlined: <CompassOutlined />,
+  compasstwotone: <CompassTwoTone />,
+  compressoutlined: <CompressOutlined />,
+  consolesqloutlined: <ConsoleSqlOutlined />,
+  contactsfilled: <ContactsFilled />,
+  contactsoutlined: <ContactsOutlined />,
+  contactstwotone: <ContactsTwoTone />,
+  containerfilled: <ContainerFilled />,
+  containeroutlined: <ContainerOutlined />,
+  containertwotone: <ContainerTwoTone />,
+  controlfilled: <ControlFilled />,
+  controloutlined: <ControlOutlined />,
+  controltwotone: <ControlTwoTone />,
+  copyfilled: <CopyFilled />,
+  copyoutlined: <CopyOutlined />,
+  copytwotone: <CopyTwoTone />,
+  copyrightcirclefilled: <CopyrightCircleFilled />,
+  copyrightcircleoutlined: <CopyrightCircleOutlined />,
+  copyrightcircletwotone: <CopyrightCircleTwoTone />,
+  copyrightoutlined: <CopyrightOutlined />,
+  copyrighttwotone: <CopyrightTwoTone />,
+  creditcardfilled: <CreditCardFilled />,
+  creditcardoutlined: <CreditCardOutlined />,
+  creditcardtwotone: <CreditCardTwoTone />,
+  crownfilled: <CrownFilled />,
+  crownoutlined: <CrownOutlined />,
+  crowntwotone: <CrownTwoTone />,
+  customerservicefilled: <CustomerServiceFilled />,
+  customerserviceoutlined: <CustomerServiceOutlined />,
+  customerservicetwotone: <CustomerServiceTwoTone />,
+  dashoutlined: <DashOutlined />,
+  dashboardfilled: <DashboardFilled />,
+  dashboardoutlined: <DashboardOutlined />,
+  dashboardtwotone: <DashboardTwoTone />,
+  databasefilled: <DatabaseFilled />,
+  databaseoutlined: <DatabaseOutlined />,
+  databasetwotone: <DatabaseTwoTone />,
+  deletecolumnoutlined: <DeleteColumnOutlined />,
+  deletefilled: <DeleteFilled />,
+  deleteoutlined: <DeleteOutlined />,
+  deleterowoutlined: <DeleteRowOutlined />,
+  deletetwotone: <DeleteTwoTone />,
+  deliveredprocedureoutlined: <DeliveredProcedureOutlined />,
+  deploymentunitoutlined: <DeploymentUnitOutlined />,
+  desktopoutlined: <DesktopOutlined />,
+  difffilled: <DiffFilled />,
+  diffoutlined: <DiffOutlined />,
+  difftwotone: <DiffTwoTone />,
+  dingdingoutlined: <DingdingOutlined />,
+  dingtalkcirclefilled: <DingtalkCircleFilled />,
+  dingtalkoutlined: <DingtalkOutlined />,
+  dingtalksquarefilled: <DingtalkSquareFilled />,
+  disconnectoutlined: <DisconnectOutlined />,
+  dislikefilled: <DislikeFilled />,
+  dislikeoutlined: <DislikeOutlined />,
+  disliketwotone: <DislikeTwoTone />,
+  dollarcirclefilled: <DollarCircleFilled />,
+  dollarcircleoutlined: <DollarCircleOutlined />,
+  dollarcircletwotone: <DollarCircleTwoTone />,
+  dollaroutlined: <DollarOutlined />,
+  dollartwotone: <DollarTwoTone />,
+  dotchartoutlined: <DotChartOutlined />,
+  doubleleftoutlined: <DoubleLeftOutlined />,
+  doublerightoutlined: <DoubleRightOutlined />,
+  downcirclefilled: <DownCircleFilled />,
+  downcircleoutlined: <DownCircleOutlined />,
+  downcircletwotone: <DownCircleTwoTone />,
+  downoutlined: <DownOutlined />,
+  downsquarefilled: <DownSquareFilled />,
+  downsquareoutlined: <DownSquareOutlined />,
+  downsquaretwotone: <DownSquareTwoTone />,
+  downloadoutlined: <DownloadOutlined />,
+  dragoutlined: <DragOutlined />,
+  dribbblecirclefilled: <DribbbleCircleFilled />,
+  dribbbleoutlined: <DribbbleOutlined />,
+  dribbblesquarefilled: <DribbbleSquareFilled />,
+  dribbblesquareoutlined: <DribbbleSquareOutlined />,
+  dropboxcirclefilled: <DropboxCircleFilled />,
+  dropboxoutlined: <DropboxOutlined />,
+  dropboxsquarefilled: <DropboxSquareFilled />,
+  editfilled: <EditFilled />,
+  editoutlined: <EditOutlined />,
+  edittwotone: <EditTwoTone />,
+  ellipsisoutlined: <EllipsisOutlined />,
+  enteroutlined: <EnterOutlined />,
+  environmentfilled: <EnvironmentFilled />,
+  environmentoutlined: <EnvironmentOutlined />,
+  environmenttwotone: <EnvironmentTwoTone />,
+  eurocirclefilled: <EuroCircleFilled />,
+  eurocircleoutlined: <EuroCircleOutlined />,
+  eurocircletwotone: <EuroCircleTwoTone />,
+  eurooutlined: <EuroOutlined />,
+  eurotwotone: <EuroTwoTone />,
+  exceptionoutlined: <ExceptionOutlined />,
+  exclamationcirclefilled: <ExclamationCircleFilled />,
+  exclamationcircleoutlined: <ExclamationCircleOutlined />,
+  exclamationcircletwotone: <ExclamationCircleTwoTone />,
+  exclamationoutlined: <ExclamationOutlined />,
+  expandaltoutlined: <ExpandAltOutlined />,
+  expandoutlined: <ExpandOutlined />,
+  experimentfilled: <ExperimentFilled />,
+  experimentoutlined: <ExperimentOutlined />,
+  experimenttwotone: <ExperimentTwoTone />,
+  exportoutlined: <ExportOutlined />,
+  eyefilled: <EyeFilled />,
+  eyeinvisiblefilled: <EyeInvisibleFilled />,
+  eyeinvisibleoutlined: <EyeInvisibleOutlined />,
+  eyeinvisibletwotone: <EyeInvisibleTwoTone />,
+  eyeoutlined: <EyeOutlined />,
+  eyetwotone: <EyeTwoTone />,
+  facebookfilled: <FacebookFilled />,
+  facebookoutlined: <FacebookOutlined />,
+  falloutlined: <FallOutlined />,
+  fastbackwardfilled: <FastBackwardFilled />,
+  fastbackwardoutlined: <FastBackwardOutlined />,
+  fastforwardfilled: <FastForwardFilled />,
+  fastforwardoutlined: <FastForwardOutlined />,
+  fieldbinaryoutlined: <FieldBinaryOutlined />,
+  fieldnumberoutlined: <FieldNumberOutlined />,
+  fieldstringoutlined: <FieldStringOutlined />,
+  fieldtimeoutlined: <FieldTimeOutlined />,
+  fileaddfilled: <FileAddFilled />,
+  fileaddoutlined: <FileAddOutlined />,
+  fileaddtwotone: <FileAddTwoTone />,
+  filedoneoutlined: <FileDoneOutlined />,
+  fileexcelfilled: <FileExcelFilled />,
+  fileexceloutlined: <FileExcelOutlined />,
+  fileexceltwotone: <FileExcelTwoTone />,
+  fileexclamationfilled: <FileExclamationFilled />,
+  fileexclamationoutlined: <FileExclamationOutlined />,
+  fileexclamationtwotone: <FileExclamationTwoTone />,
+  filefilled: <FileFilled />,
+  filegifoutlined: <FileGifOutlined />,
+  fileimagefilled: <FileImageFilled />,
+  fileimageoutlined: <FileImageOutlined />,
+  fileimagetwotone: <FileImageTwoTone />,
+  filejpgoutlined: <FileJpgOutlined />,
+  filemarkdownfilled: <FileMarkdownFilled />,
+  filemarkdownoutlined: <FileMarkdownOutlined />,
+  filemarkdowntwotone: <FileMarkdownTwoTone />,
+  fileoutlined: <FileOutlined />,
+  filepdffilled: <FilePdfFilled />,
+  filepdfoutlined: <FilePdfOutlined />,
+  filepdftwotone: <FilePdfTwoTone />,
+  filepptfilled: <FilePptFilled />,
+  filepptoutlined: <FilePptOutlined />,
+  fileppttwotone: <FilePptTwoTone />,
+  fileprotectoutlined: <FileProtectOutlined />,
+  filesearchoutlined: <FileSearchOutlined />,
+  filesyncoutlined: <FileSyncOutlined />,
+  filetextfilled: <FileTextFilled />,
+  filetextoutlined: <FileTextOutlined />,
+  filetexttwotone: <FileTextTwoTone />,
+  filetwotone: <FileTwoTone />,
+  fileunknownfilled: <FileUnknownFilled />,
+  fileunknownoutlined: <FileUnknownOutlined />,
+  fileunknowntwotone: <FileUnknownTwoTone />,
+  filewordfilled: <FileWordFilled />,
+  filewordoutlined: <FileWordOutlined />,
+  filewordtwotone: <FileWordTwoTone />,
+  filezipfilled: <FileZipFilled />,
+  filezipoutlined: <FileZipOutlined />,
+  fileziptwotone: <FileZipTwoTone />,
+  filterfilled: <FilterFilled />,
+  filteroutlined: <FilterOutlined />,
+  filtertwotone: <FilterTwoTone />,
+  firefilled: <FireFilled />,
+  fireoutlined: <FireOutlined />,
+  firetwotone: <FireTwoTone />,
+  flagfilled: <FlagFilled />,
+  flagoutlined: <FlagOutlined />,
+  flagtwotone: <FlagTwoTone />,
+  folderaddfilled: <FolderAddFilled />,
+  folderaddoutlined: <FolderAddOutlined />,
+  folderaddtwotone: <FolderAddTwoTone />,
+  folderfilled: <FolderFilled />,
+  folderopenfilled: <FolderOpenFilled />,
+  folderopenoutlined: <FolderOpenOutlined />,
+  folderopentwotone: <FolderOpenTwoTone />,
+  folderoutlined: <FolderOutlined />,
+  foldertwotone: <FolderTwoTone />,
+  folderviewoutlined: <FolderViewOutlined />,
+  fontcolorsoutlined: <FontColorsOutlined />,
+  fontsizeoutlined: <FontSizeOutlined />,
+  forkoutlined: <ForkOutlined />,
+  formoutlined: <FormOutlined />,
+  formatpainterfilled: <FormatPainterFilled />,
+  formatpainteroutlined: <FormatPainterOutlined />,
+  forwardfilled: <ForwardFilled />,
+  forwardoutlined: <ForwardOutlined />,
+  frownfilled: <FrownFilled />,
+  frownoutlined: <FrownOutlined />,
+  frowntwotone: <FrownTwoTone />,
+  fullscreenexitoutlined: <FullscreenExitOutlined />,
+  fullscreenoutlined: <FullscreenOutlined />,
+  functionoutlined: <FunctionOutlined />,
+  fundfilled: <FundFilled />,
+  fundoutlined: <FundOutlined />,
+  fundprojectionscreenoutlined: <FundProjectionScreenOutlined />,
+  fundtwotone: <FundTwoTone />,
+  fundviewoutlined: <FundViewOutlined />,
+  funnelplotfilled: <FunnelPlotFilled />,
+  funnelplotoutlined: <FunnelPlotOutlined />,
+  funnelplottwotone: <FunnelPlotTwoTone />,
+  gatewayoutlined: <GatewayOutlined />,
+  gifoutlined: <GifOutlined />,
+  giftfilled: <GiftFilled />,
+  giftoutlined: <GiftOutlined />,
+  gifttwotone: <GiftTwoTone />,
+  githubfilled: <GithubFilled />,
+  githuboutlined: <GithubOutlined />,
+  gitlabfilled: <GitlabFilled />,
+  gitlaboutlined: <GitlabOutlined />,
+  globaloutlined: <GlobalOutlined />,
+  goldfilled: <GoldFilled />,
+  goldoutlined: <GoldOutlined />,
+  goldtwotone: <GoldTwoTone />,
+  goldenfilled: <GoldenFilled />,
+  googlecirclefilled: <GoogleCircleFilled />,
+  googleoutlined: <GoogleOutlined />,
+  googlepluscirclefilled: <GooglePlusCircleFilled />,
+  googleplusoutlined: <GooglePlusOutlined />,
+  googleplussquarefilled: <GooglePlusSquareFilled />,
+  googlesquarefilled: <GoogleSquareFilled />,
+  groupoutlined: <GroupOutlined />,
+  hddfilled: <HddFilled />,
+  hddoutlined: <HddOutlined />,
+  hddtwotone: <HddTwoTone />,
+  heartfilled: <HeartFilled />,
+  heartoutlined: <HeartOutlined />,
+  hearttwotone: <HeartTwoTone />,
+  heatmapoutlined: <HeatMapOutlined />,
+  highlightfilled: <HighlightFilled />,
+  highlightoutlined: <HighlightOutlined />,
+  highlighttwotone: <HighlightTwoTone />,
+  historyoutlined: <HistoryOutlined />,
+  holderoutlined: <HolderOutlined />,
+  homefilled: <HomeFilled />,
+  homeoutlined: <HomeOutlined />,
+  hometwotone: <HomeTwoTone />,
+  hourglassfilled: <HourglassFilled />,
+  hourglassoutlined: <HourglassOutlined />,
+  hourglasstwotone: <HourglassTwoTone />,
+  html5filled: <Html5Filled />,
+  html5outlined: <Html5Outlined />,
+  html5twotone: <Html5TwoTone />,
+  idcardfilled: <IdcardFilled />,
+  idcardoutlined: <IdcardOutlined />,
+  idcardtwotone: <IdcardTwoTone />,
+  iecirclefilled: <IeCircleFilled />,
+  ieoutlined: <IeOutlined />,
+  iesquarefilled: <IeSquareFilled />,
+  importoutlined: <ImportOutlined />,
+  inboxoutlined: <InboxOutlined />,
+  infocirclefilled: <InfoCircleFilled />,
+  infocircleoutlined: <InfoCircleOutlined />,
+  infocircletwotone: <InfoCircleTwoTone />,
+  infooutlined: <InfoOutlined />,
+  insertrowaboveoutlined: <InsertRowAboveOutlined />,
+  insertrowbelowoutlined: <InsertRowBelowOutlined />,
+  insertrowleftoutlined: <InsertRowLeftOutlined />,
+  insertrowrightoutlined: <InsertRowRightOutlined />,
+  instagramfilled: <InstagramFilled />,
+  instagramoutlined: <InstagramOutlined />,
+  insurancefilled: <InsuranceFilled />,
+  insuranceoutlined: <InsuranceOutlined />,
+  insurancetwotone: <InsuranceTwoTone />,
+  interactionfilled: <InteractionFilled />,
+  interactionoutlined: <InteractionOutlined />,
+  interactiontwotone: <InteractionTwoTone />,
+  issuescloseoutlined: <IssuesCloseOutlined />,
+  italicoutlined: <ItalicOutlined />,
+  keyoutlined: <KeyOutlined />,
+  laptopoutlined: <LaptopOutlined />,
+  layoutfilled: <LayoutFilled />,
+  layoutoutlined: <LayoutOutlined />,
+  layouttwotone: <LayoutTwoTone />,
+  leftcirclefilled: <LeftCircleFilled />,
+  leftcircleoutlined: <LeftCircleOutlined />,
+  leftcircletwotone: <LeftCircleTwoTone />,
+  leftoutlined: <LeftOutlined />,
+  leftsquarefilled: <LeftSquareFilled />,
+  leftsquareoutlined: <LeftSquareOutlined />,
+  leftsquaretwotone: <LeftSquareTwoTone />,
+  likefilled: <LikeFilled />,
+  likeoutlined: <LikeOutlined />,
+  liketwotone: <LikeTwoTone />,
+  linechartoutlined: <LineChartOutlined />,
+  lineheightoutlined: <LineHeightOutlined />,
+  lineoutlined: <LineOutlined />,
+  linkoutlined: <LinkOutlined />,
+  linkedinfilled: <LinkedinFilled />,
+  linkedinoutlined: <LinkedinOutlined />,
+  loading3quartersoutlined: <Loading3QuartersOutlined />,
+  loadingoutlined: <LoadingOutlined />,
+  lockfilled: <LockFilled />,
+  lockoutlined: <LockOutlined />,
+  locktwotone: <LockTwoTone />,
+  loginoutlined: <LoginOutlined />,
+  logoutoutlined: <LogoutOutlined />,
+  maccommandfilled: <MacCommandFilled />,
+  maccommandoutlined: <MacCommandOutlined />,
+  mailfilled: <MailFilled />,
+  mailoutlined: <MailOutlined />,
+  mailtwotone: <MailTwoTone />,
+  manoutlined: <ManOutlined />,
+  medicineboxfilled: <MedicineBoxFilled />,
+  medicineboxoutlined: <MedicineBoxOutlined />,
+  medicineboxtwotone: <MedicineBoxTwoTone />,
+  mediumcirclefilled: <MediumCircleFilled />,
+  mediumoutlined: <MediumOutlined />,
+  mediumsquarefilled: <MediumSquareFilled />,
+  mediumworkmarkoutlined: <MediumWorkmarkOutlined />,
+  mehfilled: <MehFilled />,
+  mehoutlined: <MehOutlined />,
+  mehtwotone: <MehTwoTone />,
+  menufoldoutlined: <MenuFoldOutlined />,
+  menuoutlined: <MenuOutlined />,
+  menuunfoldoutlined: <MenuUnfoldOutlined />,
+  mergecellsoutlined: <MergeCellsOutlined />,
+  messagefilled: <MessageFilled />,
+  messageoutlined: <MessageOutlined />,
+  messagetwotone: <MessageTwoTone />,
+  minuscirclefilled: <MinusCircleFilled />,
+  minuscircleoutlined: <MinusCircleOutlined />,
+  minuscircletwotone: <MinusCircleTwoTone />,
+  minusoutlined: <MinusOutlined />,
+  minussquarefilled: <MinusSquareFilled />,
+  minussquareoutlined: <MinusSquareOutlined />,
+  minussquaretwotone: <MinusSquareTwoTone />,
+  mobilefilled: <MobileFilled />,
+  mobileoutlined: <MobileOutlined />,
+  mobiletwotone: <MobileTwoTone />,
+  moneycollectfilled: <MoneyCollectFilled />,
+  moneycollectoutlined: <MoneyCollectOutlined />,
+  moneycollecttwotone: <MoneyCollectTwoTone />,
+  monitoroutlined: <MonitorOutlined />,
+  moreoutlined: <MoreOutlined />,
+  nodecollapseoutlined: <NodeCollapseOutlined />,
+  nodeexpandoutlined: <NodeExpandOutlined />,
+  nodeindexoutlined: <NodeIndexOutlined />,
+  notificationfilled: <NotificationFilled />,
+  notificationoutlined: <NotificationOutlined />,
+  notificationtwotone: <NotificationTwoTone />,
+  numberoutlined: <NumberOutlined />,
+  onetooneoutlined: <OneToOneOutlined />,
+  orderedlistoutlined: <OrderedListOutlined />,
+  paperclipoutlined: <PaperClipOutlined />,
+  partitionoutlined: <PartitionOutlined />,
+  pausecirclefilled: <PauseCircleFilled />,
+  pausecircleoutlined: <PauseCircleOutlined />,
+  pausecircletwotone: <PauseCircleTwoTone />,
+  pauseoutlined: <PauseOutlined />,
+  paycirclefilled: <PayCircleFilled />,
+  paycircleoutlined: <PayCircleOutlined />,
+  percentageoutlined: <PercentageOutlined />,
+  phonefilled: <PhoneFilled />,
+  phoneoutlined: <PhoneOutlined />,
+  phonetwotone: <PhoneTwoTone />,
+  piccenteroutlined: <PicCenterOutlined />,
+  picleftoutlined: <PicLeftOutlined />,
+  picrightoutlined: <PicRightOutlined />,
+  picturefilled: <PictureFilled />,
+  pictureoutlined: <PictureOutlined />,
+  picturetwotone: <PictureTwoTone />,
+  piechartfilled: <PieChartFilled />,
+  piechartoutlined: <PieChartOutlined />,
+  piecharttwotone: <PieChartTwoTone />,
+  playcirclefilled: <PlayCircleFilled />,
+  playcircleoutlined: <PlayCircleOutlined />,
+  playcircletwotone: <PlayCircleTwoTone />,
+  playsquarefilled: <PlaySquareFilled />,
+  playsquareoutlined: <PlaySquareOutlined />,
+  playsquaretwotone: <PlaySquareTwoTone />,
+  pluscirclefilled: <PlusCircleFilled />,
+  pluscircleoutlined: <PlusCircleOutlined />,
+  pluscircletwotone: <PlusCircleTwoTone />,
+  plusoutlined: <PlusOutlined />,
+  plussquarefilled: <PlusSquareFilled />,
+  plussquareoutlined: <PlusSquareOutlined />,
+  plussquaretwotone: <PlusSquareTwoTone />,
+  poundcirclefilled: <PoundCircleFilled />,
+  poundcircleoutlined: <PoundCircleOutlined />,
+  poundcircletwotone: <PoundCircleTwoTone />,
+  poundoutlined: <PoundOutlined />,
+  poweroffoutlined: <PoweroffOutlined />,
+  printerfilled: <PrinterFilled />,
+  printeroutlined: <PrinterOutlined />,
+  printertwotone: <PrinterTwoTone />,
+  profilefilled: <ProfileFilled />,
+  profileoutlined: <ProfileOutlined />,
+  profiletwotone: <ProfileTwoTone />,
+  projectfilled: <ProjectFilled />,
+  projectoutlined: <ProjectOutlined />,
+  projecttwotone: <ProjectTwoTone />,
+  propertysafetyfilled: <PropertySafetyFilled />,
+  propertysafetyoutlined: <PropertySafetyOutlined />,
+  propertysafetytwotone: <PropertySafetyTwoTone />,
+  pullrequestoutlined: <PullRequestOutlined />,
+  pushpinfilled: <PushpinFilled />,
+  pushpinoutlined: <PushpinOutlined />,
+  pushpintwotone: <PushpinTwoTone />,
+  qqcirclefilled: <QqCircleFilled />,
+  qqoutlined: <QqOutlined />,
+  qqsquarefilled: <QqSquareFilled />,
+  qrcodeoutlined: <QrcodeOutlined />,
+  questioncirclefilled: <QuestionCircleFilled />,
+  questioncircleoutlined: <QuestionCircleOutlined />,
+  questioncircletwotone: <QuestionCircleTwoTone />,
+  questionoutlined: <QuestionOutlined />,
+  radarchartoutlined: <RadarChartOutlined />,
+  radiusbottomleftoutlined: <RadiusBottomleftOutlined />,
+  radiusbottomrightoutlined: <RadiusBottomrightOutlined />,
+  radiussettingoutlined: <RadiusSettingOutlined />,
+  radiusupleftoutlined: <RadiusUpleftOutlined />,
+  radiusuprightoutlined: <RadiusUprightOutlined />,
+  readfilled: <ReadFilled />,
+  readoutlined: <ReadOutlined />,
+  reconciliationfilled: <ReconciliationFilled />,
+  reconciliationoutlined: <ReconciliationOutlined />,
+  reconciliationtwotone: <ReconciliationTwoTone />,
+  redenvelopefilled: <RedEnvelopeFilled />,
+  redenvelopeoutlined: <RedEnvelopeOutlined />,
+  redenvelopetwotone: <RedEnvelopeTwoTone />,
+  redditcirclefilled: <RedditCircleFilled />,
+  redditoutlined: <RedditOutlined />,
+  redditsquarefilled: <RedditSquareFilled />,
+  redooutlined: <RedoOutlined />,
+  reloadoutlined: <ReloadOutlined />,
+  restfilled: <RestFilled />,
+  restoutlined: <RestOutlined />,
+  resttwotone: <RestTwoTone />,
+  retweetoutlined: <RetweetOutlined />,
+  rightcirclefilled: <RightCircleFilled />,
+  rightcircleoutlined: <RightCircleOutlined />,
+  rightcircletwotone: <RightCircleTwoTone />,
+  rightoutlined: <RightOutlined />,
+  rightsquarefilled: <RightSquareFilled />,
+  rightsquareoutlined: <RightSquareOutlined />,
+  rightsquaretwotone: <RightSquareTwoTone />,
+  riseoutlined: <RiseOutlined />,
+  robotfilled: <RobotFilled />,
+  robotoutlined: <RobotOutlined />,
+  rocketfilled: <RocketFilled />,
+  rocketoutlined: <RocketOutlined />,
+  rockettwotone: <RocketTwoTone />,
+  rollbackoutlined: <RollbackOutlined />,
+  rotateleftoutlined: <RotateLeftOutlined />,
+  rotaterightoutlined: <RotateRightOutlined />,
+  safetycertificatefilled: <SafetyCertificateFilled />,
+  safetycertificateoutlined: <SafetyCertificateOutlined />,
+  safetycertificatetwotone: <SafetyCertificateTwoTone />,
+  safetyoutlined: <SafetyOutlined />,
+  savefilled: <SaveFilled />,
+  saveoutlined: <SaveOutlined />,
+  savetwotone: <SaveTwoTone />,
+  scanoutlined: <ScanOutlined />,
+  schedulefilled: <ScheduleFilled />,
+  scheduleoutlined: <ScheduleOutlined />,
+  scheduletwotone: <ScheduleTwoTone />,
+  scissoroutlined: <ScissorOutlined />,
+  searchoutlined: <SearchOutlined />,
+  securityscanfilled: <SecurityScanFilled />,
+  securityscanoutlined: <SecurityScanOutlined />,
+  securityscantwotone: <SecurityScanTwoTone />,
+  selectoutlined: <SelectOutlined />,
+  sendoutlined: <SendOutlined />,
+  settingfilled: <SettingFilled />,
+  settingoutlined: <SettingOutlined />,
+  settingtwotone: <SettingTwoTone />,
+  shakeoutlined: <ShakeOutlined />,
+  sharealtoutlined: <ShareAltOutlined />,
+  shopfilled: <ShopFilled />,
+  shopoutlined: <ShopOutlined />,
+  shoptwotone: <ShopTwoTone />,
+  shoppingcartoutlined: <ShoppingCartOutlined />,
+  shoppingfilled: <ShoppingFilled />,
+  shoppingoutlined: <ShoppingOutlined />,
+  shoppingtwotone: <ShoppingTwoTone />,
+  shrinkoutlined: <ShrinkOutlined />,
+  signalfilled: <SignalFilled />,
+  sisternodeoutlined: <SisternodeOutlined />,
+  sketchcirclefilled: <SketchCircleFilled />,
+  sketchoutlined: <SketchOutlined />,
+  sketchsquarefilled: <SketchSquareFilled />,
+  skinfilled: <SkinFilled />,
+  skinoutlined: <SkinOutlined />,
+  skintwotone: <SkinTwoTone />,
+  skypefilled: <SkypeFilled />,
+  skypeoutlined: <SkypeOutlined />,
+  slackcirclefilled: <SlackCircleFilled />,
+  slackoutlined: <SlackOutlined />,
+  slacksquarefilled: <SlackSquareFilled />,
+  slacksquareoutlined: <SlackSquareOutlined />,
+  slidersfilled: <SlidersFilled />,
+  slidersoutlined: <SlidersOutlined />,
+  sliderstwotone: <SlidersTwoTone />,
+  smalldashoutlined: <SmallDashOutlined />,
+  smilefilled: <SmileFilled />,
+  smileoutlined: <SmileOutlined />,
+  smiletwotone: <SmileTwoTone />,
+  snippetsfilled: <SnippetsFilled />,
+  snippetsoutlined: <SnippetsOutlined />,
+  snippetstwotone: <SnippetsTwoTone />,
+  solutionoutlined: <SolutionOutlined />,
+  sortascendingoutlined: <SortAscendingOutlined />,
+  sortdescendingoutlined: <SortDescendingOutlined />,
+  soundfilled: <SoundFilled />,
+  soundoutlined: <SoundOutlined />,
+  soundtwotone: <SoundTwoTone />,
+  splitcellsoutlined: <SplitCellsOutlined />,
+  starfilled: <StarFilled />,
+  staroutlined: <StarOutlined />,
+  startwotone: <StarTwoTone />,
+  stepbackwardfilled: <StepBackwardFilled />,
+  stepbackwardoutlined: <StepBackwardOutlined />,
+  stepforwardfilled: <StepForwardFilled />,
+  stepforwardoutlined: <StepForwardOutlined />,
+  stockoutlined: <StockOutlined />,
+  stopfilled: <StopFilled />,
+  stopoutlined: <StopOutlined />,
+  stoptwotone: <StopTwoTone />,
+  strikethroughoutlined: <StrikethroughOutlined />,
+  subnodeoutlined: <SubnodeOutlined />,
+  swapleftoutlined: <SwapLeftOutlined />,
+  swapoutlined: <SwapOutlined />,
+  swaprightoutlined: <SwapRightOutlined />,
+  switcherfilled: <SwitcherFilled />,
+  switcheroutlined: <SwitcherOutlined />,
+  switchertwotone: <SwitcherTwoTone />,
+  syncoutlined: <SyncOutlined />,
+  tableoutlined: <TableOutlined />,
+  tabletfilled: <TabletFilled />,
+  tabletoutlined: <TabletOutlined />,
+  tablettwotone: <TabletTwoTone />,
+  tagfilled: <TagFilled />,
+  tagoutlined: <TagOutlined />,
+  tagtwotone: <TagTwoTone />,
+  tagsfilled: <TagsFilled />,
+  tagsoutlined: <TagsOutlined />,
+  tagstwotone: <TagsTwoTone />,
+  taobaocirclefilled: <TaobaoCircleFilled />,
+  taobaocircleoutlined: <TaobaoCircleOutlined />,
+  taobaooutlined: <TaobaoOutlined />,
+  taobaosquarefilled: <TaobaoSquareFilled />,
+  teamoutlined: <TeamOutlined />,
+  thunderboltfilled: <ThunderboltFilled />,
+  thunderboltoutlined: <ThunderboltOutlined />,
+  thunderbolttwotone: <ThunderboltTwoTone />,
+  totopoutlined: <ToTopOutlined />,
+  toolfilled: <ToolFilled />,
+  tooloutlined: <ToolOutlined />,
+  tooltwotone: <ToolTwoTone />,
+  trademarkcirclefilled: <TrademarkCircleFilled />,
+  trademarkcircleoutlined: <TrademarkCircleOutlined />,
+  trademarkcircletwotone: <TrademarkCircleTwoTone />,
+  trademarkoutlined: <TrademarkOutlined />,
+  transactionoutlined: <TransactionOutlined />,
+  translationoutlined: <TranslationOutlined />,
+  trophyfilled: <TrophyFilled />,
+  trophyoutlined: <TrophyOutlined />,
+  trophytwotone: <TrophyTwoTone />,
+  twittercirclefilled: <TwitterCircleFilled />,
+  twitteroutlined: <TwitterOutlined />,
+  twittersquarefilled: <TwitterSquareFilled />,
+  underlineoutlined: <UnderlineOutlined />,
+  undooutlined: <UndoOutlined />,
+  ungroupoutlined: <UngroupOutlined />,
+  unlockfilled: <UnlockFilled />,
+  unlockoutlined: <UnlockOutlined />,
+  unlocktwotone: <UnlockTwoTone />,
+  unorderedlistoutlined: <UnorderedListOutlined />,
+  upcirclefilled: <UpCircleFilled />,
+  upcircleoutlined: <UpCircleOutlined />,
+  upcircletwotone: <UpCircleTwoTone />,
+  upoutlined: <UpOutlined />,
+  upsquarefilled: <UpSquareFilled />,
+  upsquareoutlined: <UpSquareOutlined />,
+  upsquaretwotone: <UpSquareTwoTone />,
+  uploadoutlined: <UploadOutlined />,
+  usbfilled: <UsbFilled />,
+  usboutlined: <UsbOutlined />,
+  usbtwotone: <UsbTwoTone />,
+  useraddoutlined: <UserAddOutlined />,
+  userdeleteoutlined: <UserDeleteOutlined />,
+  useroutlined: <UserOutlined />,
+  userswitchoutlined: <UserSwitchOutlined />,
+  usergroupaddoutlined: <UsergroupAddOutlined />,
+  usergroupdeleteoutlined: <UsergroupDeleteOutlined />,
+  verifiedoutlined: <VerifiedOutlined />,
+  verticalalignbottomoutlined: <VerticalAlignBottomOutlined />,
+  verticalalignmiddleoutlined: <VerticalAlignMiddleOutlined />,
+  verticalaligntopoutlined: <VerticalAlignTopOutlined />,
+  verticalleftoutlined: <VerticalLeftOutlined />,
+  verticalrightoutlined: <VerticalRightOutlined />,
+  videocameraaddoutlined: <VideoCameraAddOutlined />,
+  videocamerafilled: <VideoCameraFilled />,
+  videocameraoutlined: <VideoCameraOutlined />,
+  videocameratwotone: <VideoCameraTwoTone />,
+  walletfilled: <WalletFilled />,
+  walletoutlined: <WalletOutlined />,
+  wallettwotone: <WalletTwoTone />,
+  warningfilled: <WarningFilled />,
+  warningoutlined: <WarningOutlined />,
+  warningtwotone: <WarningTwoTone />,
+  wechatfilled: <WechatFilled />,
+  wechatoutlined: <WechatOutlined />,
+  weibocirclefilled: <WeiboCircleFilled />,
+  weibocircleoutlined: <WeiboCircleOutlined />,
+  weibooutlined: <WeiboOutlined />,
+  weibosquarefilled: <WeiboSquareFilled />,
+  weibosquareoutlined: <WeiboSquareOutlined />,
+  whatsappoutlined: <WhatsAppOutlined />,
+  wifioutlined: <WifiOutlined />,
+  windowsfilled: <WindowsFilled />,
+  windowsoutlined: <WindowsOutlined />,
+  womanoutlined: <WomanOutlined />,
+  yahoofilled: <YahooFilled />,
+  yahoooutlined: <YahooOutlined />,
+  youtubefilled: <YoutubeFilled />,
+  youtubeoutlined: <YoutubeOutlined />,
+  yuquefilled: <YuqueFilled />,
+  yuqueoutlined: <YuqueOutlined />,
+  zhihucirclefilled: <ZhihuCircleFilled />,
+  zhihuoutlined: <ZhihuOutlined />,
+  zhihusquarefilled: <ZhihuSquareFilled />,
+  zoominoutlined: <ZoomInOutlined />,
+  zoomoutoutlined: <ZoomOutOutlined />,
+}; */
\ No newline at end of file
diff --git a/client/packages/lowcoder-design/src/icons/antIcon.tsx b/client/packages/lowcoder-design/src/icons/antIcon.tsx
index 34cd128f22..e746cdab1a 100644
--- a/client/packages/lowcoder-design/src/icons/antIcon.tsx
+++ b/client/packages/lowcoder-design/src/icons/antIcon.tsx
@@ -1580,25 +1580,4 @@ export const ANTDICON = {
   zhihusquarefilled: <ZhihuSquareFilled />,
   zoominoutlined: <ZoomInOutlined />,
   zoomoutoutlined: <ZoomOutOutlined />,
-};
-
-
-// Function to dynamically import icons
-export const loadAntDIcon = async (iconName: string) => {
-  if (!iconName) return null;
-
-  try {
-    const module = await import(`@ant-design/icons`);
-    const IconComponent = (module as any)[iconName];
-    if (IconComponent) {
-      // Return the icon component if found
-      return <IconComponent />;
-    } else {
-      console.error(`Icon ${iconName} not found in @ant-design/icons`);
-      return null;
-    }
-  } catch (error) {
-    console.error(`Error loading icon ${iconName}:`, error);
-    return null;
-  }
 };
\ No newline at end of file
diff --git a/client/yarn.lock b/client/yarn.lock
index 3851091465..2eea2e9bec 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -11970,7 +11970,6 @@ __metadata:
     number-precision: ^1.6.0
     prettier: ^3.1.0
     react-player: ^2.11.0
-    remixicon-react: ^1.0.0
     rimraf: ^3.0.2
     rollup: ^2.79.0
     shelljs: ^0.8.5
@@ -15586,15 +15585,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"remixicon-react@npm:^1.0.0":
-  version: 1.0.0
-  resolution: "remixicon-react@npm:1.0.0"
-  peerDependencies:
-    react: ">=0.14.0"
-  checksum: be7abfb3558c9ed18ccfff5a28bd66dbee4207887682ae7a00c697e6051eadecad0da83f1e83910ed6ddebe7f2ab73e488f0f4c604897605bbb3d8f519f416ed
-  languageName: node
-  linkType: hard
-
 "request-promise-core@npm:1.1.4":
   version: 1.1.4
   resolution: "request-promise-core@npm:1.1.4"

From 67d578c86b8aabee327a67817bcbc9307de3fe70 Mon Sep 17 00:00:00 2001
From: Imtanan Aziz Toor <imtanan.aziz@ikhwatech.com>
Date: Fri, 23 Feb 2024 17:18:43 +0500
Subject: [PATCH 85/97] Checkbox, radio input styles complete, select styling
 in progress

---
 .../comps/selectInputComp/cascaderComp.tsx    |  1 +
 .../selectInputComp/selectCompConstants.tsx   | 37 ++++++++++++-------
 .../columnTypeComps/columnSelectComp.tsx      | 11 ++++--
 .../comps/controls/styleControlConstants.tsx  | 23 +++++++-----
 4 files changed, 44 insertions(+), 28 deletions(-)

diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/cascaderComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/cascaderComp.tsx
index 4c992874ac..e89c0e49f2 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/cascaderComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/cascaderComp.tsx
@@ -11,6 +11,7 @@ import { refMethods } from "comps/generators/withMethodExposing";
 
 const CascaderStyle = styled(Cascader)<{ $style: CascaderStyleType }>`
   width: 100%;
+  font-family:"Montserrat";
   ${(props) => props.$style && getStyle(props.$style)}
 `;
 
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
index 86493bf765..c4b0d43aed 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
@@ -7,7 +7,7 @@ import {
 import { BoolControl } from "../../controls/boolControl";
 import { LabelControl } from "../../controls/labelControl";
 import { BoolCodeControl, StringControl } from "../../controls/codeControl";
-import { PaddingControl } from "../../controls/paddingControl";	
+import { PaddingControl } from "../../controls/paddingControl";
 import { MarginControl } from "../../controls/marginControl";
 import {
   ControlNode,
@@ -65,8 +65,15 @@ export const getStyle = (
       height: auto;	
     }	
     .ant-select-selection-search {	
-      padding: ${style.padding};	
+      padding: ${style.padding};
     }	
+    .ant-select-selection-search-input {
+      font-family:${(style as SelectStyleType).fontFamily} !important;
+      font-size:${(style as SelectStyleType).textSize} !important;
+      font-weight:${(style as SelectStyleType).textWeight};
+      color:${(style as SelectStyleType).text} !important;
+      font-style:${(style as SelectStyleType).fontStyle};
+    }
     .ant-select-selector::after,	
     .ant-select-selection-placeholder,	
     .ant-select-selection-item {	
@@ -88,6 +95,7 @@ export const getStyle = (
       .ant-select-selector {
         background-color: ${style.background};
         border-color: ${style.border};
+        border-width:${(style as SelectStyleType).borderWidth};
       }
 
       &.ant-select-focused,
@@ -101,18 +109,18 @@ export const getStyle = (
       .ant-select-clear {
         background-color: ${style.background};
         color: ${style.text === "#222222"
-          ? "#8B8FA3"
-          : isDarkColor(style.text)
-          ? lightenColor(style.text, 0.2)
-          : style.text};
+      ? "#8B8FA3"
+      : isDarkColor(style.text)
+        ? lightenColor(style.text, 0.2)
+        : style.text};
       }
 
       .ant-select-clear:hover {
         color: ${style.text === "#222222"
-          ? "#8B8FA3"
-          : isDarkColor(style.text)
-          ? lightenColor(style.text, 0.1)
-          : style.text};
+      ? "#8B8FA3"
+      : isDarkColor(style.text)
+        ? lightenColor(style.text, 0.1)
+        : style.text};
       }
 
       &.ant-select-multiple .ant-select-selection-item {
@@ -160,7 +168,7 @@ const getDropdownStyle = (style: MultiSelectStyleType) => {
   `;
 };
 
-const Select = styled(AntdSelect)<{ $style: SelectStyleType & MultiSelectStyleType }>`
+const Select = styled(AntdSelect) <{ $style: SelectStyleType & MultiSelectStyleType }>`
   width: 100%;
 
   ${(props) => props.$style && getStyle(props.$style)}
@@ -197,7 +205,7 @@ export const SelectChildrenMap = {
   inputValue: stateComp<string>(""), // user's input value when search
   showSearch: BoolControl.DEFAULT_TRUE,
   viewRef: RefControl<BaseSelectRef>,
-  margin: MarginControl,	
+  margin: MarginControl,
   padding: PaddingControl,
   ...SelectInputValidationChildren,
   ...formDataChildren,
@@ -235,8 +243,8 @@ export const SelectUIView = (
     onSearch={
       props.showSearch
         ? (value) => {
-            props.dispatch(changeChildAction("inputValue", value, false));
-          }
+          props.dispatch(changeChildAction("inputValue", value, false));
+        }
         : undefined
     }
   >
@@ -248,6 +256,7 @@ export const SelectUIView = (
           label={option.label}
           disabled={option.disabled}
           key={option.value}
+          style={{fontFamily:"Montserrat"}}
         >
           <Wrapper className="option-label">
             {props.options.findIndex((option) => hasIcon(option.prefixIcon)) > -1 &&
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnSelectComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnSelectComp.tsx
index d4305a928d..8f4ef326b5 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnSelectComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnSelectComp.tsx
@@ -23,19 +23,21 @@ type SelectEditProps = {
   options: any[];
 };
 
+const defaultProps: any = {}
 const SelectEdit = (props: SelectEditProps) => {
   const [currentValue, setCurrentValue] = useState(props.initialValue);
 
   return (
-    <SelectUIView 
+    <SelectUIView
+      {...defaultProps}
       value={currentValue}
       options={options}
       onChange={(val) => {
         props.onChange(val);
         setCurrentValue(val)
       }}
-      onEvent={async (eventName)=>{
-        if(eventName==="blur"){
+      onEvent={async (eventName) => {
+        if (eventName === "blur") {
           props.onChangeEnd()
         }
         return []
@@ -66,7 +68,8 @@ export const ColumnSelectComp = (function () {
           onChange={props.onChange}
           onChangeEnd={props.onChangeEnd}
         />
-    )})
+      )
+    })
     .setPropertyViewFn((children) => {
       return (
         <>
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index f1b4d4add0..30513a9af5 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -735,20 +735,23 @@ export const SwitchStyle = [
 ] as const;
 
 export const SelectStyle = [
-  LABEL,
-  ...getStaticBgBorderRadiusByBg(SURFACE_COLOR, "pc"),
-  TEXT,
-  MARGIN,
-  PADDING,
+  // LABEL,
+  ...replaceAndMergeMultipleStyles(STYLING_FIELDS_SEQUENCE, 'border', [...getStaticBgBorderRadiusByBg(SURFACE_COLOR, "pc")]),
+
+  // ...getStaticBgBorderRadiusByBg(SURFACE_COLOR, "pc"),
+  // TEXT,
+  // MARGIN,
+  // PADDING,
   ...ACCENT_VALIDATE,
 ] as const;
 
 const multiSelectCommon = [
-  LABEL,
-  ...getStaticBgBorderRadiusByBg(SURFACE_COLOR, "pc"),
-  TEXT,
-  MARGIN,
-  PADDING,
+  ...replaceAndMergeMultipleStyles(STYLING_FIELDS_SEQUENCE, 'border', [...getStaticBgBorderRadiusByBg(SURFACE_COLOR, "pc")]),
+  // LABEL,
+  // ...getStaticBgBorderRadiusByBg(SURFACE_COLOR, "pc"),
+  // TEXT,
+  // MARGIN,
+  // PADDING,
   {
     name: "tags",
     label: trans("style.tags"),

From e5f2d297dc58d6f877fe72adbfe85258f54de7f0 Mon Sep 17 00:00:00 2001
From: Abdul Qadir <abdul.qadir@ikhwatech.com>
Date: Fri, 23 Feb 2024 17:54:52 +0500
Subject: [PATCH 86/97] Move ptm apps data to application dsl

---
 .../service/ApplicationService.java           | 45 +++++++++++++++----
 .../application/ApplicationApiService.java    |  4 +-
 .../application/ApplicationController.java    |  2 +-
 .../api/application/ApplicationEndpoints.java | 18 +++++++-
 4 files changed, 56 insertions(+), 13 deletions(-)

diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
index a97f8ca675..cfbbe0a378 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
@@ -3,10 +3,7 @@
 
 import static org.lowcoder.domain.application.ApplicationUtil.getDependentModulesFromDsl;
 
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 
 import org.lowcoder.domain.application.model.Application;
@@ -155,11 +152,41 @@ public Mono<Boolean> setApplicationPublicToAll(String applicationId, boolean pub
         return mongoUpsertHelper.updateById(application, applicationId);
     }
 
-    public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, boolean publicToMarketplace) {
-        Application application = Application.builder()
-                .publicToMarketplace(publicToMarketplace)
-                .build();
-        return mongoUpsertHelper.updateById(application, applicationId);
+    public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, Boolean publicToMarketplace, String title, String category, String description) {
+
+        return findById(applicationId)
+                .map(application -> {
+                    Map<String, Object> applicationDsl = application.getEditingApplicationDSL();
+                    if (applicationDsl.containsKey("ui")) {
+                        Map<String, Object> dataObject = (Map<String, Object>) applicationDsl.get("ui");
+
+                        if(publicToMarketplace) {
+                            Map<String, Object> marketplaceMeta = new HashMap<>();
+                            marketplaceMeta.put("title", title);
+                            marketplaceMeta.put("description", description);
+                            marketplaceMeta.put("category", category);
+                            if (dataObject.containsKey("marketplaceMeta")) {
+                                dataObject.replace("marketplaceMeta", marketplaceMeta);
+                            } else {
+                                dataObject.put("marketplaceMeta", marketplaceMeta);
+                            }
+                        } else {
+                            dataObject.remove("marketplaceMeta");
+                        }
+
+                        applicationDsl.replace("ui", dataObject);
+
+                    }
+
+                    return Application.builder()
+                            .publicToMarketplace(publicToMarketplace)
+                            .editingApplicationDSL(applicationDsl)
+                            .build();
+
+                })
+                .flatMap(application -> mongoUpsertHelper.updateById(application, applicationId));
+
+
     }
 
     public Mono<Boolean> setApplicationAsAgencyProfile(String applicationId, boolean agencyProfile) {
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
index f1eaad172b..29dc3b8a91 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
@@ -514,10 +514,10 @@ public Mono<Boolean> setApplicationPublicToAll(String applicationId, boolean pub
                 .then(applicationService.setApplicationPublicToAll(applicationId, publicToAll));
     }
 
-    public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, boolean publicToMarketplace) {
+    public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, ApplicationEndpoints.ApplicationPublicToMarketplaceRequest request) {
         return checkCurrentUserApplicationPermission(applicationId, ResourceAction.SET_APPLICATIONS_PUBLIC_TO_MARKETPLACE)
                 .then(checkApplicationStatus(applicationId, NORMAL))
-                .then(applicationService.setApplicationPublicToMarketplace(applicationId, publicToMarketplace));
+                .then(applicationService.setApplicationPublicToMarketplace(applicationId, request.publicToMarketplace(), request.title(), request.category(), request.description()));
     }
 
     public Mono<Boolean> setApplicationAsAgencyProfile(String applicationId, boolean agencyProfile) {
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
index e75de598d0..1b6bf34a5b 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
@@ -214,7 +214,7 @@ public Mono<ResponseView<Boolean>> setApplicationPublicToAll(@PathVariable Strin
     @Override
     public Mono<ResponseView<Boolean>> setApplicationPublicToMarketplace(@PathVariable String applicationId,
                                                                          @RequestBody ApplicationPublicToMarketplaceRequest request) {
-        return applicationApiService.setApplicationPublicToMarketplace(applicationId, request.publicToMarketplace())
+        return applicationApiService.setApplicationPublicToMarketplace(applicationId, request)
                 .map(ResponseView::success);
     }
 
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
index eae901f219..5da9cf827f 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
@@ -270,11 +270,27 @@ public Boolean publicToAll() {
         }
     }
 
-	public record ApplicationPublicToMarketplaceRequest(Boolean publicToMarketplace) {
+	public record ApplicationPublicToMarketplaceRequest(Boolean publicToMarketplace, String title, String description, String category) {
 		@Override
 		public Boolean publicToMarketplace() {
 			return BooleanUtils.isTrue(publicToMarketplace);
 		}
+
+		@Override
+		public String title() {
+			return title;
+		}
+
+		@Override
+		public String description() {
+			return description;
+		}
+
+		@Override
+		public String category() {
+			return category;
+		}
+
 	}
 
 	public record ApplicationAsAgencyProfileRequest(Boolean agencyProfile) {

From e8d875c77e6bd94f422bd4e763dfa2731464c4b5 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Fri, 23 Feb 2024 15:09:14 +0100
Subject: [PATCH 87/97] Fixing MSSQL ConnectionString Parameter databaseName

---
 .../src/main/java/org/lowcoder/plugin/mssql/MssqlConnector.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/server/api-service/lowcoder-plugins/mssqlPlugin/src/main/java/org/lowcoder/plugin/mssql/MssqlConnector.java b/server/api-service/lowcoder-plugins/mssqlPlugin/src/main/java/org/lowcoder/plugin/mssql/MssqlConnector.java
index ee770f0981..7aa6f0223e 100644
--- a/server/api-service/lowcoder-plugins/mssqlPlugin/src/main/java/org/lowcoder/plugin/mssql/MssqlConnector.java
+++ b/server/api-service/lowcoder-plugins/mssqlPlugin/src/main/java/org/lowcoder/plugin/mssql/MssqlConnector.java
@@ -55,7 +55,7 @@ protected void setUpConfigs(MssqlDatasourceConfig datasourceConfig, HikariConfig
 
 
         if (isNotBlank(database)) {
-            urlBuilder.append("database=")
+            urlBuilder.append("databaseName=")
                     .append(database)
                     .append(";");
         }

From a087797d7037c48c31dcf4389298dfdca102be9d Mon Sep 17 00:00:00 2001
From: RAHEEL <mraheeliftikhar1994@gmail.com>
Date: Fri, 23 Feb 2024 20:13:09 +0500
Subject: [PATCH 88/97] separate marketplace apps in self hosting env

---
 .../icon-lowcoder-marketplace-active.svg      | 12 ++++
 .../src/icons/icon-lowcoder-marketplace.svg   | 16 +++++
 .../lowcoder-design/src/icons/index.ts        |  2 +
 client/packages/lowcoder/src/app.tsx          |  1 +
 .../src/constants/applicationConstants.ts     |  2 +
 .../lowcoder/src/constants/routesURL.ts       |  6 +-
 .../pages/ApplicationV2/MarketplaceView.tsx   | 66 ++++++++++++++-----
 .../src/pages/ApplicationV2/index.tsx         | 29 +++++++-
 8 files changed, 114 insertions(+), 20 deletions(-)
 create mode 100644 client/packages/lowcoder-design/src/icons/icon-lowcoder-marketplace-active.svg
 create mode 100644 client/packages/lowcoder-design/src/icons/icon-lowcoder-marketplace.svg

diff --git a/client/packages/lowcoder-design/src/icons/icon-lowcoder-marketplace-active.svg b/client/packages/lowcoder-design/src/icons/icon-lowcoder-marketplace-active.svg
new file mode 100644
index 0000000000..6550e65dc7
--- /dev/null
+++ b/client/packages/lowcoder-design/src/icons/icon-lowcoder-marketplace-active.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="20px" height="20px" viewBox="0 0 23 23" version="1.1" xmlns="http://www.w3.org/2000/svg">
+  <defs>
+    <linearGradient id="icon-lowcoder-marketplace-active_svg__a" x1="50%" y1="1.89576049%" x2="50%" y2="94.4251638%">
+      <stop stop-color="#6D83F2" offset="0%"/>
+      <stop stop-color="#4965F2" offset="100%"/>
+    </linearGradient>
+  </defs>
+  <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+    <path d="M10.2721 2.524h3.7795v13.2283h-3.7795zm-7.559 18.8977v-3.7795h7.5591v3.7795zm11.3386-.0001v-3.7795h7.5591v3.7795z" fill="url(#icon-lowcoder-marketplace-active_svg__a)" fill-rule="nonzero"/>
+  </g>
+</svg>
\ No newline at end of file
diff --git a/client/packages/lowcoder-design/src/icons/icon-lowcoder-marketplace.svg b/client/packages/lowcoder-design/src/icons/icon-lowcoder-marketplace.svg
new file mode 100644
index 0000000000..903bcc0f1d
--- /dev/null
+++ b/client/packages/lowcoder-design/src/icons/icon-lowcoder-marketplace.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="20px" height="20px" viewBox="0 0 23 23" version="1.1" xmlns="http://www.w3.org/2000/svg">
+  <defs>
+    <linearGradient id="icon-lowcoder-marketplace_svg__a" x1="50%" y1="1.89576049%" x2="50%" y2="94.4251638%">
+      <stop stop-color="#5C6066" offset="0%"/>
+      <stop stop-color="#333740" offset="100%"/>
+    </linearGradient>
+    <linearGradient x1="50%" y1="1.89576049%" x2="50%" y2="94.4251638%">
+      <stop stop-color="#6D83F2" offset="0%"/>
+      <stop stop-color="#4965F2" offset="100%"/>
+    </linearGradient>
+  </defs>
+  <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+    <path d="M10.2721 2.524h3.7795v13.2283h-3.7795zm-7.559 18.8977v-3.7795h7.5591v3.7795zm11.3386-.0001v-3.7795h7.5591v3.7795z" fill="url(#icon-lowcoder-marketplace_svg__a)" fill-rule="nonzero"/>
+  </g>
+</svg>
\ No newline at end of file
diff --git a/client/packages/lowcoder-design/src/icons/index.ts b/client/packages/lowcoder-design/src/icons/index.ts
index 1862d85aee..6fdc18332e 100644
--- a/client/packages/lowcoder-design/src/icons/index.ts
+++ b/client/packages/lowcoder-design/src/icons/index.ts
@@ -177,12 +177,14 @@ export { ReactComponent as HomeQueryLibraryIcon } from "./icon-application-query
 export { ReactComponent as HomeDataSourceIcon } from "./icon-application-datasource.svg";
 export { ReactComponent as RecyclerIcon } from "./icon-application-recycler.svg";
 export { ReactComponent as MarketplaceIcon } from "./icon-application-marketplace.svg";
+export { ReactComponent as LowcoderMarketplaceIcon } from "./icon-lowcoder-marketplace.svg";
 export { ReactComponent as HomeActiveIcon } from "./icon-application-home-active.svg";
 export { ReactComponent as HomeModuleActiveIcon } from "./icon-application-module-active.svg";
 export { ReactComponent as HomeQueryLibraryActiveIcon } from "./icon-application-query-library-active.svg";
 export { ReactComponent as HomeDataSourceActiveIcon } from "./icon-application-datasource-active.svg";
 export { ReactComponent as RecyclerActiveIcon } from "./icon-application-recycler-active.svg";
 export { ReactComponent as MarketplaceActiveIcon } from "./icon-application-marketplace-active.svg";
+export { ReactComponent as  LowcoderMarketplaceActiveIcon } from "./icon-lowcoder-marketplace-active.svg";
 export { ReactComponent as FavoritesIcon } from "./icon-application-favorites.svg";
 export { ReactComponent as HomeSettingIcon } from "./icon-application-setting.svg";
 export { ReactComponent as FolderIcon } from "./icon-application-folder.svg";
diff --git a/client/packages/lowcoder/src/app.tsx b/client/packages/lowcoder/src/app.tsx
index 8b3a944f7d..ec2aaa0086 100644
--- a/client/packages/lowcoder/src/app.tsx
+++ b/client/packages/lowcoder/src/app.tsx
@@ -14,6 +14,7 @@ import {
   IMPORT_APP_FROM_TEMPLATE_URL,
   INVITE_LANDING_URL,
   isAuthUnRequired,
+  MARKETPLACE_TYPE_URL,
   MARKETPLACE_URL,
   ORG_AUTH_LOGIN_URL,
   ORG_AUTH_REGISTER_URL,
diff --git a/client/packages/lowcoder/src/constants/applicationConstants.ts b/client/packages/lowcoder/src/constants/applicationConstants.ts
index 40b38ee529..90130e18b4 100644
--- a/client/packages/lowcoder/src/constants/applicationConstants.ts
+++ b/client/packages/lowcoder/src/constants/applicationConstants.ts
@@ -115,3 +115,5 @@ export type AppSnapshotList = {
   count: number; // total count
   list: AppSnapshot[];
 };
+
+export type MarketplaceType = "local" | "lowcoder";
diff --git a/client/packages/lowcoder/src/constants/routesURL.ts b/client/packages/lowcoder/src/constants/routesURL.ts
index 1c21036ab2..f2f2e7664c 100644
--- a/client/packages/lowcoder/src/constants/routesURL.ts
+++ b/client/packages/lowcoder/src/constants/routesURL.ts
@@ -1,4 +1,4 @@
-import { AppViewMode } from "constants/applicationConstants";
+import { AppViewMode, MarketplaceType } from "constants/applicationConstants";
 import { LocationDescriptor } from "history";
 import { UserGuideLocationState } from "pages/tutorials/tutorialsConstant";
 import { DatasourceType } from "@lowcoder-ee/constants/queryConstants";
@@ -43,10 +43,14 @@ export const LDAP_AUTH_LOGIN_URL = `${USER_AUTH_URL}/ldap/login`;
 export const INVITE_LANDING_URL = "/invite/:invitationId";
 export const ORG_AUTH_LOGIN_URL = `/org/:orgId/auth/login`;
 export const ORG_AUTH_REGISTER_URL = `/org/:orgId/auth/register`;
+export const MARKETPLACE_TYPE_URL = `${MARKETPLACE_URL}/:marketplaceType`;
 
 export const APPLICATION_VIEW_URL = (appId: string, viewMode: AppViewMode) =>
   `${ALL_APPLICATIONS_URL}/${appId}/${viewMode}`;
 
+export const MARKETPLACE_URL_BY_TYPE = (type: MarketplaceType) =>
+  `${MARKETPLACE_URL}/${type}`;
+
 export const isAuthUnRequired = (pathname: string): boolean => {
   return (
     pathname.startsWith("/invite/") ||
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx
index d518250d1c..f8091174b3 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx
@@ -1,34 +1,66 @@
 import { useEffect, useState } from "react";
-import { useDispatch, useSelector } from "react-redux";
 import { HomeLayout } from "./HomeLayout";
-import { MARKETPLACE_URL } from "constants/routesURL";
-import { marketplaceSelector } from "redux/selectors/applicationSelector";
-import { fetchAllMarketplaceApps } from "redux/reduxActions/applicationActions";
+import { MARKETPLACE_TYPE_URL, MARKETPLACE_URL } from "constants/routesURL";
 import { trans } from "../../i18n";
+import axios, { AxiosResponse } from "axios";
+import ApplicationApi from "@lowcoder-ee/api/applicationApi";
+import { ApplicationMeta, MarketplaceType } from "@lowcoder-ee/constants/applicationConstants";
+import { GenericApiResponse } from "@lowcoder-ee/api/apiResponses";
+import { validateResponse } from "@lowcoder-ee/api/apiUtils";
+import { messageInstance } from "lowcoder-design";
+import { matchPath } from "react-router";
+import log from "loglevel";
 
 export function MarketplaceView() {
-  const [haveFetchedApps, setHaveFetchApps] = useState<boolean>(false);
+  const [ marketplaceApps, setMarketplaceApps ] = useState<Array<ApplicationMeta>>([]);
+  const marketplaceType = matchPath<{marketplaceType?: MarketplaceType}>(window.location.pathname, MARKETPLACE_TYPE_URL)?.params
+    .marketplaceType;
+  const isLowcoderMarketplace = marketplaceType === 'lowcoder';
+  const marketplaceBreadcrumbText = !marketplaceType?.length
+    ? trans("home.marketplace")
+    : marketplaceType === 'lowcoder'
+    ? `${trans("home.marketplace")} (Lowcoder)`
+    : `${trans("home.marketplace")} (Local)`;
 
-  const dispatch = useDispatch();
-  const marketplaceApps = useSelector(marketplaceSelector);
+  const fetchLowcoderMarketplaceApps = () => {
+    const http = axios.create({
+      baseURL: 'https://api-service.lowcoder.cloud',
+      withCredentials: false,
+    });
+    return http.get(`/api/v1/applications/marketplace-apps`);
+  };
 
-  useEffect(() => {
-    if (!marketplaceApps.length && !haveFetchedApps) {
-      dispatch(fetchAllMarketplaceApps());
-      setHaveFetchApps(true);
+  const fetchLocalMarketplaceApps = () => {
+    return ApplicationApi.fetchAllMarketplaceApps()
+  }
+
+  const fetchMarketplaceApps = async () => {
+    try {
+      let response: AxiosResponse<GenericApiResponse<ApplicationMeta[]>>;
+      if(isLowcoderMarketplace) {
+        response = await fetchLowcoderMarketplaceApps();
+      } else {
+        response = await fetchLocalMarketplaceApps();
+      }
+
+      const isValidResponse: boolean = validateResponse(response);
+      if (isValidResponse) {
+        setMarketplaceApps(response.data.data);
+      }
+    } catch (error: any) {
+      messageInstance.error(error.message);
+      log.debug("fetch marketplace apps error: ", error);
     }
-  }, []);
+  }
 
   useEffect(() => {
-    if (marketplaceApps.length) {
-      setHaveFetchApps(true);
-    }
-  }, [marketplaceApps])
+    fetchMarketplaceApps();
+  }, [marketplaceType]);
 
   return (
     <HomeLayout
       elements={marketplaceApps}
-      breadcrumb={[{ text: trans("home.marketplace"), path: MARKETPLACE_URL }]}
+      breadcrumb={[{ text: marketplaceBreadcrumbText, path: MARKETPLACE_URL }]}
       mode={"marketplace"}
     />
   );
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
index 2baac32592..c2d3c435e4 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
@@ -5,6 +5,7 @@ import {
   FOLDER_URL_PREFIX,
   FOLDERS_URL,
   MARKETPLACE_URL,
+  MARKETPLACE_URL_BY_TYPE,
   MODULE_APPLICATIONS_URL,
   QUERY_LIBRARY_URL,
   SETTING,
@@ -33,6 +34,8 @@ import {
   RecyclerIcon,
   MarketplaceIcon,
   MarketplaceActiveIcon,
+  LowcoderMarketplaceActiveIcon,
+  LowcoderMarketplaceIcon,
 } from "lowcoder-design";
 import React, { useEffect, useState } from "react";
 import { fetchAllApplications, fetchHomeData } from "redux/reduxActions/applicationActions";
@@ -245,6 +248,7 @@ export default function ApplicationHome() {
   const allAppCount = allApplications.length;
   const allFoldersCount = allFolders.length;
   const orgHomeId = "root";
+  const isSelfHost = window.location.host !== 'app.lowcoder.cloud';
 
   const handleFolderCreate = useCreateFolder();
 
@@ -357,8 +361,16 @@ export default function ApplicationHome() {
                 visible: ({ user }) => user.orgDev,
               },
               {
-                text: <TabLabel>{trans("home.marketplace")}</TabLabel>,
-                routePath: MARKETPLACE_URL,
+                text: (
+                  <TabLabel>
+                    {
+                      isSelfHost
+                        ? `${trans("home.marketplace")} (Local)`
+                        : trans("home.marketplace")
+                    }
+                  </TabLabel>
+                ),
+                routePath: isSelfHost ? MARKETPLACE_URL_BY_TYPE('local') : MARKETPLACE_URL,
                 routePathExact: false,
                 routeComp: MarketplaceView,
                 icon: ({ selected, ...otherProps }) =>
@@ -369,6 +381,19 @@ export default function ApplicationHome() {
                   ),
                 visible: ({ user }) => user.orgDev,
               },
+              {
+                text: <TabLabel>{`${trans("home.marketplace")} (Lowcoder)`}</TabLabel>,
+                routePath: MARKETPLACE_URL_BY_TYPE('lowcoder'),
+                routePathExact: false,
+                routeComp: MarketplaceView,
+                icon: ({ selected, ...otherProps }) =>
+                  selected ? (
+                    <LowcoderMarketplaceActiveIcon {...otherProps} />
+                  ) : (
+                    <LowcoderMarketplaceIcon {...otherProps} />
+                  ),
+                visible: ({ user }) => user.orgDev && isSelfHost,
+              },
               {
                 text: <TabLabel>{trans("home.trash")}</TabLabel>,
                 routePath: TRASH_URL,

From 1ba1207aa89c35285dba66f08bd5d9e0575c743d Mon Sep 17 00:00:00 2001
From: zaini <alimzaini@outlook.com>
Date: Fri, 23 Feb 2024 10:22:27 -0800
Subject: [PATCH 89/97] Remove from top section

---
 README.md | 2 --
 1 file changed, 2 deletions(-)

diff --git a/README.md b/README.md
index ef329a7277..6ef8e9423b 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,6 @@
 > **Note**  
 > Lowcoder continues from the abandoned Openblocks project. For more information [read our manifesto](MANIFESTO.md).
 
-[![Deploy to AWS using Stitch](https://img.shields.io/badge/deploy_with-Stitch-%23E369F7?logo=amazonaws&color=%23E369F7)](https://deploy.stitch.tech/lowcoder/lowcoder)
-
 <div align="center">
     <h1 style="border-bottom: none; margin-bottom: 0">Lowcoder</h1>
     <h3 style="margin-top: 0">This is the only Platform, which closes the gap between App Development, Website Development and Slide-Presentations.</h3>

From 060851e16f84a949b3be6a5a52713bc11384976c Mon Sep 17 00:00:00 2001
From: Abdul Qadir <abdul.qadir@ikhwatech.com>
Date: Sat, 24 Feb 2024 00:33:42 +0500
Subject: [PATCH 90/97] PTM apps enhancements

---
 .../repository/ApplicationRepository.java     |  2 ++
 .../service/ApplicationService.java           | 22 +++++++++++++++----
 .../service/ApplicationPermissionHandler.java |  4 ++--
 .../service/ResourcePermissionHandler.java    |  4 ++++
 .../org/lowcoder/sdk/config/CommonConfig.java |  7 ++++++
 .../application/ApplicationController.java    |  2 +-
 .../view/MarketplaceApplicationInfoView.java  |  7 ++++++
 .../framework/security/SecurityConfig.java    |  4 ++++
 .../api/home/UserHomeApiServiceImpl.java      | 12 +++++++++-
 .../main/resources/application-lowcoder.yml   |  2 ++
 .../resources/selfhost/ce/application.yml     |  2 ++
 11 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
index ac37c6e9dd..7c42ccc736 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java
@@ -38,6 +38,8 @@ public interface ApplicationRepository extends ReactiveMongoRepository<Applicati
     Flux<Application> findByPublicToAllIsTrueAndPublicToMarketplaceIsOrAgencyProfileIsAndIdIn
             (Boolean publicToMarketplace, Boolean agencyProfile, Collection<String> ids);
 
+    Flux<Application> findByPublicToAllIsTrueAndPublicToMarketplaceIsAndAgencyProfileIsAndIdIn(Boolean publicToMarketplace, Boolean agencyProfile, Collection<String> ids);
+
     Flux<Application> findByPublicToAllIsTrueAndPublicToMarketplaceIsTrue();
 
     Flux<Application> findByPublicToAllIsTrueAndAgencyProfileIsTrue();
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
index cfbbe0a378..e19895c7c3 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
@@ -198,10 +198,24 @@ public Mono<Boolean> setApplicationAsAgencyProfile(String applicationId, boolean
 
     @NonEmptyMono
     @SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
-    public Mono<Set<String>> getPublicApplicationIds(Collection<String> applicationIds, Boolean isAnonymous) {
-        return repository.findByPublicToAllIsTrueAndPublicToMarketplaceIsOrAgencyProfileIsAndIdIn(!isAnonymous, !isAnonymous, applicationIds)
-                .map(HasIdAndAuditing::getId)
-                .collect(Collectors.toSet());
+    public Mono<Set<String>> getPublicApplicationIds(Collection<String> applicationIds, Boolean isAnonymous, Boolean isPrivateMarketplace) {
+
+        if(isAnonymous) {
+            if(isPrivateMarketplace) {
+                return repository.findByPublicToAllIsTrueAndPublicToMarketplaceIsAndAgencyProfileIsAndIdIn(false, false, applicationIds)
+                        .map(HasIdAndAuditing::getId)
+                        .collect(Collectors.toSet());
+            } else {
+                return repository.findByPublicToAllIsTrueAndPublicToMarketplaceIsAndAgencyProfileIsAndIdIn(true, false, applicationIds)
+                        .map(HasIdAndAuditing::getId)
+                        .collect(Collectors.toSet());
+            }
+        } else {
+                return repository.findByPublicToAllIsTrueAndPublicToMarketplaceIsOrAgencyProfileIsAndIdIn(true, true, applicationIds)
+                        .map(HasIdAndAuditing::getId)
+                        .collect(Collectors.toSet());
+        }
+
 
     }
 }
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ApplicationPermissionHandler.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ApplicationPermissionHandler.java
index d93585bb0d..5d6448d139 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ApplicationPermissionHandler.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ApplicationPermissionHandler.java
@@ -46,7 +46,7 @@ protected Mono<Map<String, List<ResourcePermission>>> getAnonymousUserPermission
         }
 
         Set<String> applicationIds = newHashSet(resourceIds);
-        return Mono.zip(applicationService.getPublicApplicationIds(applicationIds, Boolean.TRUE),
+        return Mono.zip(applicationService.getPublicApplicationIds(applicationIds, Boolean.TRUE, config.getMarketplace().isPrivateMode()),
                         templateSolution.getTemplateApplicationIds(applicationIds))
                 .map(tuple -> {
                     Set<String> publicAppIds = tuple.getT1();
@@ -61,7 +61,7 @@ protected Mono<Map<String, List<ResourcePermission>>> getAnonymousUserPermission
             (Collection<String> resourceIds, ResourceAction resourceAction) {
 
         Set<String> applicationIds = newHashSet(resourceIds);
-        return Mono.zip(applicationService.getPublicApplicationIds(applicationIds, Boolean.FALSE),
+        return Mono.zip(applicationService.getPublicApplicationIds(applicationIds, Boolean.FALSE, config.getMarketplace().isPrivateMode()),
                         templateSolution.getTemplateApplicationIds(applicationIds))
                 .map(tuple -> {
                     Set<String> publicAppIds = tuple.getT1();
diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ResourcePermissionHandler.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ResourcePermissionHandler.java
index 762e9bcb13..09efd31f25 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ResourcePermissionHandler.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ResourcePermissionHandler.java
@@ -26,6 +26,7 @@
 import org.lowcoder.domain.permission.model.ResourceRole;
 import org.lowcoder.domain.permission.model.ResourceType;
 import org.lowcoder.domain.permission.model.UserPermissionOnResourceStatus;
+import org.lowcoder.sdk.config.CommonConfig;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import com.google.common.collect.Maps;
@@ -44,6 +45,9 @@ abstract class ResourcePermissionHandler {
     @Autowired
     private OrgMemberService orgMemberService;
 
+    @Autowired
+    protected CommonConfig config;
+
     public Mono<Map<String, List<ResourcePermission>>> getAllMatchingPermissions(String userId,
             Collection<String> resourceIds,
             ResourceAction resourceAction) {
diff --git a/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java b/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java
index 7d32ed0d83..d1fcf3ea81 100644
--- a/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java
+++ b/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java
@@ -44,6 +44,7 @@ public class CommonConfig {
     private Cookie cookie = new Cookie();
     private JsExecutor jsExecutor = new JsExecutor();
     private Set<String> disallowedHosts = new HashSet<>();
+    private Marketplace marketplace = new Marketplace();
 
     public boolean isSelfHost() {
         return !isCloud();
@@ -145,6 +146,12 @@ public static class JsExecutor {
         private String host;
     }
 
+    @Data
+    public static class Marketplace {
+
+        private boolean privateMode = Boolean.TRUE;
+    }
+
 
     @Getter
     @Setter
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
index 1b6bf34a5b..f412bed4d3 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
@@ -155,7 +155,7 @@ public Mono<ResponseView<List<MarketplaceApplicationInfoView>>> getMarketplaceAp
     @Override
     public Mono<ResponseView<List<MarketplaceApplicationInfoView>>> getAgencyProfileApplications(@RequestParam(required = false) Integer applicationType) {
         ApplicationType applicationTypeEnum = applicationType == null ? null : ApplicationType.fromValue(applicationType);
-        return userHomeApiService.getAllMarketplaceApplications(applicationTypeEnum)
+        return userHomeApiService.getAllAgencyProfileApplications(applicationTypeEnum)
                 .collectList()
                 .map(ResponseView::success);
     }
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/MarketplaceApplicationInfoView.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/MarketplaceApplicationInfoView.java
index b45ffd499d..973c4caacf 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/MarketplaceApplicationInfoView.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/MarketplaceApplicationInfoView.java
@@ -2,12 +2,19 @@
 
 import lombok.Builder;
 import lombok.Getter;
+import lombok.Setter;
 import org.lowcoder.domain.application.model.ApplicationStatus;
 
 @Builder
 @Getter
+@Setter
 public class MarketplaceApplicationInfoView {
 
+    // marketplace specific details
+    private String title;
+    private String description;
+    private String category;
+
     // org details
     private final String orgId;
     private final String orgName;
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java
index 376fc3c4b1..b4010257be 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java
@@ -108,6 +108,7 @@ SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, CONFIG_URL), // system config
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, CONFIG_URL + "/deploymentId"), // system config
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, APPLICATION_URL + "/*/view"), // application view
+                        ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, APPLICATION_URL + "/*/view_marketplace"), // application view
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, USER_URL + "/me"),
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, USER_URL + "/currentUser"),
 
@@ -132,6 +133,7 @@ SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.CONFIG_URL + "/deploymentId"),
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.HEAD, NewUrl.STATE_URL + "/healthCheck"),
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.APPLICATION_URL + "/*/view"),
+                        ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.APPLICATION_URL + "/*/view_marketplace"),
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.USER_URL + "/me"),
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.USER_URL + "/currentUser"),
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.GROUP_URL + "/list"),
@@ -177,6 +179,7 @@ private CorsConfigurationSource buildCorsConfigurationSource() {
         source.registerCorsConfiguration(GROUP_URL + "/list", skipCheckCorsForAll);
         source.registerCorsConfiguration(QUERY_URL + "/execute", skipCheckCorsForAll);
         source.registerCorsConfiguration(APPLICATION_URL + "/*/view", skipCheckCorsForAll);
+        source.registerCorsConfiguration(APPLICATION_URL + "/*/view_marketplace", skipCheckCorsForAll);
         source.registerCorsConfiguration(GITHUB_STAR, skipCheckCorsForAll);
         source.registerCorsConfiguration(ORGANIZATION_URL + "/*/datasourceTypes", skipCheckCorsForAll);
         source.registerCorsConfiguration(DATASOURCE_URL + "/jsDatasourcePlugins", skipCheckCorsForAll);
@@ -186,6 +189,7 @@ private CorsConfigurationSource buildCorsConfigurationSource() {
         source.registerCorsConfiguration(NewUrl.GROUP_URL + "/list", skipCheckCorsForAll);
         source.registerCorsConfiguration(NewUrl.QUERY_URL + "/execute", skipCheckCorsForAll);
         source.registerCorsConfiguration(NewUrl.APPLICATION_URL + "/*/view", skipCheckCorsForAll);
+        source.registerCorsConfiguration(NewUrl.APPLICATION_URL + "/*/view_marketplace", skipCheckCorsForAll);
         source.registerCorsConfiguration(NewUrl.ORGANIZATION_URL + "/*/datasourceTypes", skipCheckCorsForAll);
         source.registerCorsConfiguration(NewUrl.DATASOURCE_URL + "/jsDatasourcePlugins", skipCheckCorsForAll);
 
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
index e10fe0ea1f..64ece33d65 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
@@ -292,7 +292,7 @@ public Flux<MarketplaceApplicationInfoView> getAllMarketplaceApplications(@Nulla
                                 Application application = tuple.getT1();
                                 Map<String, User> userMap = tuple.getT2();
                                 Map<String, Organization> orgMap = tuple.getT3();
-                                return MarketplaceApplicationInfoView.builder()
+                                MarketplaceApplicationInfoView marketplaceApplicationInfoView = MarketplaceApplicationInfoView.builder()
                                         .applicationId(application.getId())
                                         .name(application.getName())
                                         .applicationType(application.getApplicationType())
@@ -305,6 +305,16 @@ public Flux<MarketplaceApplicationInfoView> getAllMarketplaceApplications(@Nulla
                                         .createAt(application.getCreatedAt().toEpochMilli())
                                         .createBy(application.getCreatedBy())
                                         .build();
+
+                                // marketplace specific fields
+                                Map<String, Object> marketplaceMeta = (Map<String, Object>)
+                                        ((Map<String, Object>)application.getEditingApplicationDSL().get("ui")).get("marketplaceMeta");
+                                marketplaceApplicationInfoView.setTitle((String)marketplaceMeta.get("title"));
+                                marketplaceApplicationInfoView.setCategory((String)marketplaceMeta.get("category"));
+                                marketplaceApplicationInfoView.setDescription((String)marketplaceMeta.get("description"));
+
+                                return marketplaceApplicationInfoView;
+
                             });
 
                 });
diff --git a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml
index 75ae0dba94..66d022e68a 100644
--- a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml
+++ b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml
@@ -44,6 +44,8 @@ common:
   block-hound-enable: false
   js-executor:
     host: http://127.0.0.1:6060
+  marketplace:
+    private-mode: false
 
 material:
   mongodb-grid-fs:
diff --git a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml
index df83019823..11c0511c27 100644
--- a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml
+++ b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml
@@ -53,6 +53,8 @@ common:
   max-query-timeout: ${LOWCODER_MAX_QUERY_TIMEOUT:120}
   workspace:
     mode: ${LOWCODER_WORKSPACE_MODE:SAAS}
+  marketplace:
+    private-mode: ${MARKETPLACE_PRIVATE_MODE:true}
 
 material:
   mongodb-grid-fs:

From d4ea385aaa4f9d35afde2e24ddb5d92a3c5fcfac Mon Sep 17 00:00:00 2001
From: Abdul Qadir <abdul.qadir@ikhwatech.com>
Date: Sat, 24 Feb 2024 17:41:07 +0500
Subject: [PATCH 91/97] Handle marketplace-apps api handling for public
 marketplace

---
 .../application/ApplicationController.java    |  2 ++
 .../framework/security/SecurityConfig.java    |  5 +++++
 .../api/home/UserHomeApiServiceImpl.java      | 21 +++++++++++++------
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
index f412bed4d3..86be1e576a 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java
@@ -17,6 +17,7 @@
 import org.lowcoder.api.application.view.ApplicationView;
 import org.lowcoder.api.application.view.MarketplaceApplicationInfoView;
 import org.lowcoder.api.framework.view.ResponseView;
+import org.lowcoder.api.home.SessionUserService;
 import org.lowcoder.api.home.UserHomeApiService;
 import org.lowcoder.api.home.UserHomepageView;
 import org.lowcoder.api.util.BusinessEventPublisher;
@@ -39,6 +40,7 @@ public class ApplicationController implements ApplicationEndpoints {
     private final UserHomeApiService userHomeApiService;
     private final ApplicationApiService applicationApiService;
     private final BusinessEventPublisher businessEventPublisher;
+    private final SessionUserService sessionUserService;
 
     @Override
     public Mono<ResponseView<ApplicationView>> create(@RequestBody CreateApplicationRequest createApplicationRequest) {
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java
index b4010257be..b933a63e1f 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java
@@ -109,6 +109,8 @@ SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, CONFIG_URL + "/deploymentId"), // system config
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, APPLICATION_URL + "/*/view"), // application view
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, APPLICATION_URL + "/*/view_marketplace"), // application view
+                        ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, APPLICATION_URL + "/marketplace-apps"), // marketplace apps
+
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, USER_URL + "/me"),
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, USER_URL + "/currentUser"),
 
@@ -134,6 +136,7 @@ SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.HEAD, NewUrl.STATE_URL + "/healthCheck"),
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.APPLICATION_URL + "/*/view"),
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.APPLICATION_URL + "/*/view_marketplace"),
+                        ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.APPLICATION_URL + "/marketplace-apps"), // marketplace apps
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.USER_URL + "/me"),
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.USER_URL + "/currentUser"),
                         ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.GROUP_URL + "/list"),
@@ -180,6 +183,7 @@ private CorsConfigurationSource buildCorsConfigurationSource() {
         source.registerCorsConfiguration(QUERY_URL + "/execute", skipCheckCorsForAll);
         source.registerCorsConfiguration(APPLICATION_URL + "/*/view", skipCheckCorsForAll);
         source.registerCorsConfiguration(APPLICATION_URL + "/*/view_marketplace", skipCheckCorsForAll);
+        source.registerCorsConfiguration(APPLICATION_URL + "/marketplace-apps", skipCheckCorsForAll);
         source.registerCorsConfiguration(GITHUB_STAR, skipCheckCorsForAll);
         source.registerCorsConfiguration(ORGANIZATION_URL + "/*/datasourceTypes", skipCheckCorsForAll);
         source.registerCorsConfiguration(DATASOURCE_URL + "/jsDatasourcePlugins", skipCheckCorsForAll);
@@ -190,6 +194,7 @@ private CorsConfigurationSource buildCorsConfigurationSource() {
         source.registerCorsConfiguration(NewUrl.QUERY_URL + "/execute", skipCheckCorsForAll);
         source.registerCorsConfiguration(NewUrl.APPLICATION_URL + "/*/view", skipCheckCorsForAll);
         source.registerCorsConfiguration(NewUrl.APPLICATION_URL + "/*/view_marketplace", skipCheckCorsForAll);
+        source.registerCorsConfiguration(NewUrl.APPLICATION_URL + "/marketplace-apps", skipCheckCorsForAll);
         source.registerCorsConfiguration(NewUrl.ORGANIZATION_URL + "/*/datasourceTypes", skipCheckCorsForAll);
         source.registerCorsConfiguration(NewUrl.DATASOURCE_URL + "/jsDatasourcePlugins", skipCheckCorsForAll);
 
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
index 64ece33d65..079e831eeb 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
@@ -40,6 +40,7 @@
 import org.lowcoder.domain.user.service.UserService;
 import org.lowcoder.domain.user.service.UserStatusService;
 import org.lowcoder.infra.util.NetworkUtils;
+import org.lowcoder.sdk.config.CommonConfig;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.web.server.ServerWebExchange;
@@ -80,6 +81,9 @@ public class UserHomeApiServiceImpl implements UserHomeApiService {
     @Autowired
     private UserApplicationInteractionService userApplicationInteractionService;
 
+    @Autowired
+    private CommonConfig config;
+
     @Override
     public Mono<UserProfileView> buildUserProfileView(User user, ServerWebExchange exchange) {
 
@@ -260,8 +264,13 @@ public Flux<ApplicationInfoView> getAllAuthorisedApplications4CurrentOrgMember(@
     @Override
     public Flux<MarketplaceApplicationInfoView> getAllMarketplaceApplications(@Nullable ApplicationType applicationType) {
 
-        return sessionUserService.getVisitorOrgMemberCache()
-                .flatMapMany(orgMember -> {
+        return sessionUserService.isAnonymousUser()
+                .flatMapMany(isAnonymousUser -> {
+
+                    if(config.getMarketplace().isPrivateMode() && isAnonymousUser) {
+                        return Mono.empty();
+                    }
+
                     // application flux
                     Flux<Application> applicationFlux = Flux.defer(() -> applicationService.findAllMarketplaceApps())
                             .filter(application -> isNull(applicationType) || application.getApplicationType() == applicationType.getValue())
@@ -287,11 +296,11 @@ public Flux<MarketplaceApplicationInfoView> getAllMarketplaceApplications(@Nulla
 
                     return applicationFlux
                             .flatMap(application -> Mono.zip(Mono.just(application), userMapMono, orgMapMono))
-                            .map(tuple -> {
+                            .map(tuple2 -> {
                                 // build view
-                                Application application = tuple.getT1();
-                                Map<String, User> userMap = tuple.getT2();
-                                Map<String, Organization> orgMap = tuple.getT3();
+                                Application application = tuple2.getT1();
+                                Map<String, User> userMap = tuple2.getT2();
+                                Map<String, Organization> orgMap = tuple2.getT3();
                                 MarketplaceApplicationInfoView marketplaceApplicationInfoView = MarketplaceApplicationInfoView.builder()
                                         .applicationId(application.getId())
                                         .name(application.getName())

From 7aa74fbe0b530ba9a9ed94062ba516dbd678347e Mon Sep 17 00:00:00 2001
From: Abdul Qadir <abdul.qadir@ikhwatech.com>
Date: Sat, 24 Feb 2024 18:16:31 +0500
Subject: [PATCH 92/97] Add image field to ptm apps meta

---
 .../domain/application/service/ApplicationService.java    | 4 +++-
 .../lowcoder/api/application/ApplicationApiService.java   | 3 ++-
 .../lowcoder/api/application/ApplicationEndpoints.java    | 8 +++++++-
 .../application/view/MarketplaceApplicationInfoView.java  | 1 +
 .../org/lowcoder/api/home/UserHomeApiServiceImpl.java     | 1 +
 5 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
index e19895c7c3..917d0762e0 100644
--- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
+++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java
@@ -152,7 +152,8 @@ public Mono<Boolean> setApplicationPublicToAll(String applicationId, boolean pub
         return mongoUpsertHelper.updateById(application, applicationId);
     }
 
-    public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, Boolean publicToMarketplace, String title, String category, String description) {
+    public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, Boolean publicToMarketplace,
+                                                           String title, String category, String description, String image) {
 
         return findById(applicationId)
                 .map(application -> {
@@ -165,6 +166,7 @@ public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, Boo
                             marketplaceMeta.put("title", title);
                             marketplaceMeta.put("description", description);
                             marketplaceMeta.put("category", category);
+                            marketplaceMeta.put("image", image);
                             if (dataObject.containsKey("marketplaceMeta")) {
                                 dataObject.replace("marketplaceMeta", marketplaceMeta);
                             } else {
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
index 29dc3b8a91..fb05dcf879 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiService.java
@@ -517,7 +517,8 @@ public Mono<Boolean> setApplicationPublicToAll(String applicationId, boolean pub
     public Mono<Boolean> setApplicationPublicToMarketplace(String applicationId, ApplicationEndpoints.ApplicationPublicToMarketplaceRequest request) {
         return checkCurrentUserApplicationPermission(applicationId, ResourceAction.SET_APPLICATIONS_PUBLIC_TO_MARKETPLACE)
                 .then(checkApplicationStatus(applicationId, NORMAL))
-                .then(applicationService.setApplicationPublicToMarketplace(applicationId, request.publicToMarketplace(), request.title(), request.category(), request.description()));
+                .then(applicationService.setApplicationPublicToMarketplace
+                        (applicationId, request.publicToMarketplace(), request.title(), request.category(), request.description(), request.image()));
     }
 
     public Mono<Boolean> setApplicationAsAgencyProfile(String applicationId, boolean agencyProfile) {
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
index 5da9cf827f..2ac3232894 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java
@@ -270,7 +270,8 @@ public Boolean publicToAll() {
         }
     }
 
-	public record ApplicationPublicToMarketplaceRequest(Boolean publicToMarketplace, String title, String description, String category) {
+	public record ApplicationPublicToMarketplaceRequest(Boolean publicToMarketplace, String title,
+														String description, String category, String image) {
 		@Override
 		public Boolean publicToMarketplace() {
 			return BooleanUtils.isTrue(publicToMarketplace);
@@ -291,6 +292,11 @@ public String category() {
 			return category;
 		}
 
+		@Override
+		public String image() {
+			return image;
+		}
+
 	}
 
 	public record ApplicationAsAgencyProfileRequest(Boolean agencyProfile) {
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/MarketplaceApplicationInfoView.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/MarketplaceApplicationInfoView.java
index 973c4caacf..0de5a6aaf3 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/MarketplaceApplicationInfoView.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/view/MarketplaceApplicationInfoView.java
@@ -14,6 +14,7 @@ public class MarketplaceApplicationInfoView {
     private String title;
     private String description;
     private String category;
+    private String image;
 
     // org details
     private final String orgId;
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
index 079e831eeb..2662900dd8 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/UserHomeApiServiceImpl.java
@@ -321,6 +321,7 @@ public Flux<MarketplaceApplicationInfoView> getAllMarketplaceApplications(@Nulla
                                 marketplaceApplicationInfoView.setTitle((String)marketplaceMeta.get("title"));
                                 marketplaceApplicationInfoView.setCategory((String)marketplaceMeta.get("category"));
                                 marketplaceApplicationInfoView.setDescription((String)marketplaceMeta.get("description"));
+                                marketplaceApplicationInfoView.setImage((String)marketplaceMeta.get("image"));
 
                                 return marketplaceApplicationInfoView;
 

From 5cfac16940958f1586ae58e6b00e34bf29b929a2 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Sat, 24 Feb 2024 14:36:10 +0100
Subject: [PATCH 93/97] Adapting Marketplace

---
 .../src/constants/applicationConstants.ts     | 40 +++++++++++
 .../packages/lowcoder/src/i18n/locales/en.ts  |  4 ++
 .../packages/lowcoder/src/i18n/locales/zh.ts  |  4 ++
 .../src/pages/ApplicationV2/HomeLayout.tsx    | 56 +++++++++++++--
 .../pages/ApplicationV2/MarketplaceView.tsx   | 55 +++++++-------
 .../src/pages/ApplicationV2/index.tsx         | 21 +-----
 .../src/pages/common/headerStartDropdown.tsx  | 72 +++++++++++--------
 .../src/pages/common/previewHeader.tsx        |  5 +-
 8 files changed, 169 insertions(+), 88 deletions(-)

diff --git a/client/packages/lowcoder/src/constants/applicationConstants.ts b/client/packages/lowcoder/src/constants/applicationConstants.ts
index 90130e18b4..339548ab09 100644
--- a/client/packages/lowcoder/src/constants/applicationConstants.ts
+++ b/client/packages/lowcoder/src/constants/applicationConstants.ts
@@ -13,6 +13,40 @@ export enum AppTypeEnum {
   MobileTabLayout = 6,
 }
 
+export enum ApplicationCategoriesEnum {
+  BUSINESS = "Business",
+  DASHBOARD = "Dashboards & Reporting",
+  SLIDES = "Slides & Presentations",
+  WEBSITE = "Website",
+  SHOPPING = "Shopping & Ecommerce",
+  TOOLS = "Tools & Internal Apps",
+  COMMUNICATION = "Communication",
+  PRODUCTIVITY = "Productivity",
+  EDUCATION = "Education",
+  SOCIAL_MEDIA = "Social Media",
+  ENTERTAINMENT = "Entertainment",
+  FINANCE = "Finance",
+  HEALTH_FITNESS = "Health & Fitness",
+  LIFESTYLE = "Lifestyle",
+  NEWS_MAGAZINES = "News & Magazines",
+  PERSONALIZATION = "Personalization",
+  PHOTOGRAPHY = "Photography",
+  SPORTS = "Sports",
+  TRAVEL_LOCAL = "Travel & Local",
+  WEATHER = "Weather",
+  MEDICAL = "Medical",
+  MUSIC_AUDIO = "Music & Audio",
+  AUTO_VEHICLES = "Auto & Vehicles",
+  ART_DESIGN = "Art & Design",
+  BEAUTY = "Beauty",
+  DATING = "Dating",
+  EVENTS = "Events",
+  FOOD_DRINK = "Food & Drink",
+  HOUSE_HOME = "House & Home",
+  PARENTING = "Parenting",
+  MAPS_NAVIGATION = "Maps & Navigation",
+};
+
 export const AppUILayoutType: Record<AppTypeEnum, UiLayoutType> = {
   [AppTypeEnum.Application]: "normal",
   [AppTypeEnum.Module]: "module",
@@ -37,6 +71,11 @@ export interface ApplicationMeta {
   createBy: string;
   createAt: number;
   creatorEmail?: string;
+  title?: string;
+  description?: string;
+  icon?: string;
+  category?: ApplicationCategoriesEnum;
+  showheader?: boolean;
   orgId: string;
   role: ApplicationRoleType;
   extra: ApplicationExtra;
@@ -44,6 +83,7 @@ export interface ApplicationMeta {
   lastViewTime: number;
   folderId: string;
   folder: false;
+  isLocalMarketplace?: boolean;
   applicationStatus: "NORMAL" | "RECYCLED" | "DELETED";
 }
 
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index a40d69d2e6..bbe46953f9 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -2304,10 +2304,14 @@ export const en = {
     "copyLink": "Copy link",
     "appPublicMessage": "Make the app public. Anyone can view.",
     "modulePublicMessage": "Make the module public. Anyone can view.",
+    "marketplaceURL": "https://api-service.lowcoder.cloud",
     "appMarketplaceMessage": "Publish your App on Lowcoder Marketplace. Anyone can view and copy it from there.",
     "moduleMarketplaceMessage": "Publish your Module on Lowcoder Marketplace. Anyone can view and copy it from there.",
     "marketplaceGoodPublishing": "Please make sure your app is well-named and easy to use. Remove any sensitive information before publishing. Also, remove local datasources and replace by static built-in temporary data.",
     "noMarketplaceApps": "No apps yet in the marketplace",
+    "errorMarketplaceApps": "Error while loading Marketplace Apps",
+    "localMarketplaceTitle": "Local Marketplace",
+    "globalMarketplaceTitle": "Lowcoder Marketplace",
     "memberPermissionList": "Member permissions: ",
     "orgName": "{orgName} admins",
     "addMember": "Add members",
diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts
index b90d3a8f11..f39827bcb3 100644
--- a/client/packages/lowcoder/src/i18n/locales/zh.ts
+++ b/client/packages/lowcoder/src/i18n/locales/zh.ts
@@ -2183,10 +2183,14 @@ home: {
     copyLink: "复制链接",
     appPublicMessage: "将应用设为公开,任何人都可以查看.",
     modulePublicMessage: "将模块设为公开,任何人都可以查看.",
+    "marketplaceURL": "https://api-service.lowcoder.cloud",
     "appMarketplaceMessage": "发布您的应用程序到Lowcoder市场.任何人都可以在那里查看和复制它.",
     "moduleMarketplaceMessage": "发布您的模块到Lowcoder市场.任何人都可以在那里查看和复制它.",
     "marketplaceGoodPublishing": "请确保您的应用程序命名准确、易于使用。发布前请删除任何敏感信息。此外，移除本地数据源，代之以静态内置临时数据",
     "noMarketplaceApps": "市场上还没有应用程序",
+    "errorMarketplaceApps": "获取市场应用程序错误",
+    "localMarketplaceTitle": "本地市场",
+    "globalMarketplaceTitle": "Lowcoder 市场",
     memberPermissionList: "成员权限:",
     orgName: "{orgName}管理员",
     addMember: "添加成员",
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
index 9ea75b051f..ff6b6cf27e 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
@@ -33,6 +33,8 @@ import { trans } from "../../i18n";
 import { isFetchingFolderElements } from "../../redux/selectors/folderSelector";
 import { checkIsMobile } from "util/commonUtils";
 import MarketplaceHeaderImage from "assets/images/marketplaceHeaderImage.jpg";
+import { Divider } from "antd";
+import { Margin } from "../setting/theme/styledComponents";
 
 const Wrapper = styled.div`
   display: flex;
@@ -257,6 +259,7 @@ export interface HomeRes {
   isManageable: boolean;
   isDeletable: boolean;
   isMarketplace?: boolean;
+  isLocalMarketplace?: boolean;
 }
 
 export type HomeBreadcrumbType = { text: string; path: string };
@@ -266,11 +269,13 @@ export type HomeLayoutMode = "view" | "trash" | "module" | "folder" | "folders"
 export interface HomeLayoutProps {
   breadcrumb?: HomeBreadcrumbType[];
   elements: Array<ApplicationMeta | FolderMeta>;
+  localMarketplaceApps?: Array<ApplicationMeta>;
+  globalMarketplaceApps?: Array<ApplicationMeta>;
   mode: HomeLayoutMode;
 }
 
 export function HomeLayout(props: HomeLayoutProps) {
-  const { breadcrumb = [], elements = [], mode } = props;
+  const { breadcrumb = [], elements = [], localMarketplaceApps = [], globalMarketplaceApps = [],mode } = props;
   const user = useSelector(getUser);
   const isFetching = useSelector(isFetchingFolderElements);
 
@@ -288,7 +293,17 @@ export function HomeLayout(props: HomeLayoutProps) {
     return null;
   }
 
-  const resList: HomeRes[] = elements
+  var displayElements = elements;
+  if (mode === "marketplace") {
+    const markedLocalApps = localMarketplaceApps.map(app => ({ ...app, isLocalMarketplace: true }));
+    const markedGlobalApps = globalMarketplaceApps.map(app => ({ ...app, isLocalMarketplace: false }));
+    // Merge local and global apps into the elements array
+    displayElements = [...markedLocalApps, ...markedGlobalApps];
+  }
+
+  console.log("HomeLayout: displayElements", displayElements);
+
+  const resList: HomeRes[] = displayElements
     .filter((e) =>
       searchValue
         ? e.name.toLocaleLowerCase().includes(searchValue) ||
@@ -331,6 +346,7 @@ export function HomeLayout(props: HomeLayoutProps) {
             isManageable: mode !== 'marketplace' && canManageApp(user, e),
             isDeletable: mode !== 'marketplace' && canEditApp(user, e),
             isMarketplace: mode === 'marketplace',
+            isLocalMarketplace: e.isLocalMarketplace,
           }
     );
 
@@ -420,7 +436,6 @@ export function HomeLayout(props: HomeLayoutProps) {
 
       <ContentWrapper>
 
-        
         {isFetching && resList.length === 0 ? (
           <SkeletonStyle active paragraph={{ rows: 8, width: 648 }} title={false} />
         ) : (
@@ -434,11 +449,38 @@ export function HomeLayout(props: HomeLayoutProps) {
                     <LayoutSwitcher onClick={() => setLayout(layout === "list" ? "card" : "list")}>
                       {layout === "list" ? <HomeCardIcon /> : <HomeListIcon />}
                     </LayoutSwitcher>
-                    {layout === "list" ? (
-                      <HomeTableView resources={resList} />
-                    ) : (
-                      <HomeCardView resources={resList} />
+                  
+                    {mode === "marketplace" && (
+                      <>
+                        {layout === "list" ? (
+                          <>
+                            <h2 style={{padding: "0 36px"}}>{trans("home.localMarketplaceTitle")}</h2>
+                            <HomeTableView resources={resList.filter(app => app.isLocalMarketplace)} />
+                            <Divider style={{padding: "0 36px", margin: "0 36px", width: "calc(100% - 72px) !important"}}/>
+                            <h2 style={{padding: "0 36px"}}>{trans("home.globalMarketplaceTitle")}</h2>
+                            <HomeTableView resources={resList.filter(app => !app.isLocalMarketplace)} />
+                          </>
+                        ) : (
+                          <>
+                            <h2 style={{padding: "0 36px"}}>{trans("home.localMarketplaceTitle")}</h2>
+                            <HomeCardView resources={resList.filter(app => app.isLocalMarketplace)} />
+                            <Divider style={{padding: "0 36px", margin: "12px 36px", width: "calc(100% - 72px) !important"}}/>
+                            <h2 style={{padding: "0 36px"}}>{trans("home.globalMarketplaceTitle")}</h2>
+                            <HomeCardView resources={resList.filter(app => !app.isLocalMarketplace)} />
+                          </>
+                        )}
+                      </>
                     )}
+                    {mode !== "marketplace" && (
+                      <>
+                        {layout === "list" ? (
+                          <HomeTableView resources={resList} />
+                        ) : (
+                          <HomeCardView resources={resList} />
+                        )}
+                      </>
+                    )}
+
                   </>
                 )}
               </>
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx
index f8091174b3..55df189c37 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx
@@ -13,54 +13,49 @@ import log from "loglevel";
 
 export function MarketplaceView() {
   const [ marketplaceApps, setMarketplaceApps ] = useState<Array<ApplicationMeta>>([]);
-  const marketplaceType = matchPath<{marketplaceType?: MarketplaceType}>(window.location.pathname, MARKETPLACE_TYPE_URL)?.params
-    .marketplaceType;
-  const isLowcoderMarketplace = marketplaceType === 'lowcoder';
-  const marketplaceBreadcrumbText = !marketplaceType?.length
-    ? trans("home.marketplace")
-    : marketplaceType === 'lowcoder'
-    ? `${trans("home.marketplace")} (Lowcoder)`
-    : `${trans("home.marketplace")} (Local)`;
-
-  const fetchLowcoderMarketplaceApps = () => {
-    const http = axios.create({
-      baseURL: 'https://api-service.lowcoder.cloud',
-      withCredentials: false,
-    });
-    return http.get(`/api/v1/applications/marketplace-apps`);
-  };
-
-  const fetchLocalMarketplaceApps = () => {
-    return ApplicationApi.fetchAllMarketplaceApps()
-  }
+  const [ localMarketplaceApps, setLocalMarketplaceApps ] = useState<Array<ApplicationMeta>>([]);
 
   const fetchMarketplaceApps = async () => {
     try {
       let response: AxiosResponse<GenericApiResponse<ApplicationMeta[]>>;
-      if(isLowcoderMarketplace) {
-        response = await fetchLowcoderMarketplaceApps();
-      } else {
-        response = await fetchLocalMarketplaceApps();
+      const http = axios.create({
+        baseURL: trans("home.marketplaceURL"),
+        withCredentials: false,
+      });
+      response = await http.get(`/api/v1/applications/marketplace-apps`);
+      const isValidResponse: boolean = validateResponse(response);
+      if (isValidResponse) {
+        setMarketplaceApps(response.data.data);
       }
+    } catch (error: any) {
+      messageInstance.error(trans("home.errorMarketplaceApps"));
+    }
+  }
 
+  const fetchLocalMarketplaceApps = async () => {
+    try {
+      let response: AxiosResponse<GenericApiResponse<ApplicationMeta[]>>;
+      response = await ApplicationApi.fetchAllMarketplaceApps();
       const isValidResponse: boolean = validateResponse(response);
       if (isValidResponse) {
-        setMarketplaceApps(response.data.data);
+        setLocalMarketplaceApps(response.data.data);
       }
     } catch (error: any) {
-      messageInstance.error(error.message);
-      log.debug("fetch marketplace apps error: ", error);
+      messageInstance.error(trans("home.errorMarketplaceApps"));
     }
   }
 
   useEffect(() => {
     fetchMarketplaceApps();
-  }, [marketplaceType]);
+    fetchLocalMarketplaceApps();
+  }, []);
 
   return (
     <HomeLayout
-      elements={marketplaceApps}
-      breadcrumb={[{ text: marketplaceBreadcrumbText, path: MARKETPLACE_URL }]}
+      elements={[]}
+      localMarketplaceApps={localMarketplaceApps}
+      globalMarketplaceApps={marketplaceApps}
+      breadcrumb={[{ text: trans("home.marketplace"), path: MARKETPLACE_URL }]}
       mode={"marketplace"}
     />
   );
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
index c2d3c435e4..76ccf765de 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
@@ -363,14 +363,10 @@ export default function ApplicationHome() {
               {
                 text: (
                   <TabLabel>
-                    {
-                      isSelfHost
-                        ? `${trans("home.marketplace")} (Local)`
-                        : trans("home.marketplace")
-                    }
+                    {trans("home.marketplace")}
                   </TabLabel>
                 ),
-                routePath: isSelfHost ? MARKETPLACE_URL_BY_TYPE('local') : MARKETPLACE_URL,
+                routePath: MARKETPLACE_URL,
                 routePathExact: false,
                 routeComp: MarketplaceView,
                 icon: ({ selected, ...otherProps }) =>
@@ -381,19 +377,6 @@ export default function ApplicationHome() {
                   ),
                 visible: ({ user }) => user.orgDev,
               },
-              {
-                text: <TabLabel>{`${trans("home.marketplace")} (Lowcoder)`}</TabLabel>,
-                routePath: MARKETPLACE_URL_BY_TYPE('lowcoder'),
-                routePathExact: false,
-                routeComp: MarketplaceView,
-                icon: ({ selected, ...otherProps }) =>
-                  selected ? (
-                    <LowcoderMarketplaceActiveIcon {...otherProps} />
-                  ) : (
-                    <LowcoderMarketplaceIcon {...otherProps} />
-                  ),
-                visible: ({ user }) => user.orgDev && isSelfHost,
-              },
               {
                 text: <TabLabel>{trans("home.trash")}</TabLabel>,
                 routePath: TRASH_URL,
diff --git a/client/packages/lowcoder/src/pages/common/headerStartDropdown.tsx b/client/packages/lowcoder/src/pages/common/headerStartDropdown.tsx
index 6fe44ec93a..be16727fe6 100644
--- a/client/packages/lowcoder/src/pages/common/headerStartDropdown.tsx
+++ b/client/packages/lowcoder/src/pages/common/headerStartDropdown.tsx
@@ -69,7 +69,7 @@ export const TypeName = {
   [AppTypeEnum.MobileTabLayout]: trans("home.mobileTabLayout"),
 };
 
-export function HeaderStartDropdown(props: { setEdit: () => void }) {
+export function HeaderStartDropdown(props: { setEdit: () => void, isViewMarketplaceMode?: boolean}) {
   const user = useSelector(getUser);
   const showAppSnapshot = useSelector(showAppSnapshotSelector);
   const applicationId = useApplicationId();
@@ -80,35 +80,49 @@ export function HeaderStartDropdown(props: { setEdit: () => void }) {
   const isModule = appType === AppTypeEnum.Module;
 
   const isEditable = canEditApp(user, application);
+  const isMarketplace = props.isViewMarketplaceMode;
+
+  const menuItems = useMemo(() => {
+    // Define a base array with items that are always visible
+    const items = [
+      {
+        key: "export",
+        label: <CommonTextLabel>{trans("header.export")}</CommonTextLabel>,
+        visible: true,
+      },
+      {
+        key: "duplicate",
+        label: (
+          <CommonTextLabel>
+            {trans("header.duplicate", {
+              type: TypeName[application?.applicationType!]?.toLowerCase(),
+            })}
+          </CommonTextLabel>
+        ),
+        visible: true,
+      },
+    ];
+  
+    // Conditionally add items based on isEditable and isMarketplace flags
+    if (!isMarketplace) {
+      items.unshift(
+        {
+          key: "edit",
+          label: <CommonTextLabel>{trans("header.editName")}</CommonTextLabel>,
+          visible: isEditable,
+        },
+        {
+          key: "delete",
+          label: <CommonTextLabelDelete>{trans("home.moveToTrash")}</CommonTextLabelDelete>,
+          visible: isEditable,
+        }
+      );
+    }
+  
+    return items;
+  }, [isEditable, isMarketplace]);
+
 
-  const menuItems = useMemo(() => ([
-    {
-      key: "edit",
-      label: <CommonTextLabel>{trans("header.editName")}</CommonTextLabel>,
-      visible: isEditable,
-    },
-    {
-      key: "export",
-      label: <CommonTextLabel>{trans("header.export")}</CommonTextLabel>,
-      visible: true,
-    },
-    {
-      key: "duplicate",
-      label: (
-        <CommonTextLabel>
-          {trans("header.duplicate", {
-            type: TypeName[application?.applicationType!]?.toLowerCase(),
-          })}
-        </CommonTextLabel>
-      ),
-      visible: true,
-    },
-    {
-      key: "delete",
-      label: <CommonTextLabelDelete>{trans("home.moveToTrash")}</CommonTextLabelDelete>,
-      visible: isEditable,
-    },
-  ]), [isEditable]);
 
   return (
     <>
diff --git a/client/packages/lowcoder/src/pages/common/previewHeader.tsx b/client/packages/lowcoder/src/pages/common/previewHeader.tsx
index 85ae198d65..faaa28f53a 100644
--- a/client/packages/lowcoder/src/pages/common/previewHeader.tsx
+++ b/client/packages/lowcoder/src/pages/common/previewHeader.tsx
@@ -144,9 +144,8 @@ export const PreviewHeader = () => {
       </StyledLink>
       {isViewMarketplaceMode && (
         <HeaderStartDropdown
-          setEdit={() => {
-            
-          }}
+          setEdit={() => { }}
+          isViewMarketplaceMode={isViewMarketplaceMode}
         />
       )}
       {!isViewMarketplaceMode && (

From c42d0575b36b9bb6ef7f227dc581d7058794ec53 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Sat, 24 Feb 2024 17:35:03 +0100
Subject: [PATCH 94/97] Change of Version and Documentation URLs

---
 client/package.json                             | 2 +-
 client/packages/lowcoder/package.json           | 2 +-
 client/packages/lowcoder/src/i18n/locales/en.ts | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/client/package.json b/client/package.json
index 25b47c3d7f..af52e0a314 100644
--- a/client/package.json
+++ b/client/package.json
@@ -11,7 +11,7 @@
   },
   "scripts": {
     "start": "yarn workspace lowcoder start",
-    "start-win":"LOWCODER_API_SERVICE_URL=http://localhost:3000 yarn start",
+    "start-win": "LOWCODER_API_SERVICE_URL=http://localhost:3000 yarn start",
     "start:ee": "REACT_APP_EDITION=enterprise yarn workspace lowcoder start",
     "start:ee-global": "REACT_APP_EDITION=enterprise-global yarn workspace lowcoder start",
     "build": "yarn node ./scripts/build.js",
diff --git a/client/packages/lowcoder/package.json b/client/packages/lowcoder/package.json
index f9625024b4..6b26ce7ff2 100644
--- a/client/packages/lowcoder/package.json
+++ b/client/packages/lowcoder/package.json
@@ -1,6 +1,6 @@
 {
   "name": "lowcoder",
-  "version": "2.2.0",
+  "version": "2.3.1",
   "private": true,
   "type": "module",
   "main": "src/index.sdk.ts",
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index 22cdf522be..0ad9f76c95 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -2775,7 +2775,7 @@ export const en = {
     aboutUs: "https://lowcoder.cloud/about",
     changeLog: "https://github.com/lowcoder-org/lowcoder/releases",
     introVideo: "",
-    devNpmPlugin: "https://docs.lowcoder.cloud/lowcoder-extension/develop-data-source-plugins",
+    devNpmPlugin: "https://github.com/lowcoder-org/lowcoder-create-component-plugin",
     devNpmPluginText: "How to develop npm plugin",
     useHost: "https://docs.lowcoder.cloud/setup-and-run/self-hosting/access-local-database-or-api",
     eventHandlerSlowdown: "https://docs.lowcoder.cloud/build-applications/app-interaction/event-handlers",

From 0f6c3bcc7062d28317cfc8a3ac6c9830d4146a31 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Sun, 25 Feb 2024 12:49:53 +0100
Subject: [PATCH 95/97] Display Workplace API Usage in Settings

---
 client/packages/lowcoder/src/api/orgApi.ts    |  9 ++++--
 .../src/constants/reduxActionConstants.ts     |  2 ++
 .../packages/lowcoder/src/i18n/locales/en.ts  |  6 +++-
 .../packages/lowcoder/src/i18n/locales/zh.ts  |  4 +++
 .../setting/advanced/AdvancedSetting.tsx      | 21 ++++++++++++-
 .../lowcoder/src/pages/setting/index.tsx      |  9 ------
 .../redux/reducers/uiReducers/orgReducer.ts   | 14 ++++++++-
 .../src/redux/reduxActions/orgActions.ts      | 31 +++++++++++++++----
 .../lowcoder/src/redux/sagas/orgSagas.ts      | 29 +++++++++++++----
 .../src/redux/selectors/orgSelectors.ts       |  4 +++
 10 files changed, 103 insertions(+), 26 deletions(-)

diff --git a/client/packages/lowcoder/src/api/orgApi.ts b/client/packages/lowcoder/src/api/orgApi.ts
index 7c1396a391..b2164d202d 100644
--- a/client/packages/lowcoder/src/api/orgApi.ts
+++ b/client/packages/lowcoder/src/api/orgApi.ts
@@ -133,9 +133,14 @@ export class OrgApi extends Api {
     return Api.put(OrgApi.updateOrgURL(request.id), request);
   }
 
-  static fetchAPIUsage(orgId: string, lastMonthOnly?: boolean): AxiosPromise<ApiResponse> {
-    return Api.get(OrgApi.fetchUsage(orgId), lastMonthOnly);
+  static fetchAPIUsage(orgId: string): AxiosPromise<ApiResponse> {
+    return Api.get(OrgApi.fetchUsage(orgId));
   }
+
+  static fetchLastMonthAPIUsage(orgId: string): AxiosPromise<ApiResponse> {
+    return Api.get(OrgApi.fetchUsage(orgId), { lastMonthOnly: true });
+  }
+
 }
 
 export default OrgApi;
diff --git a/client/packages/lowcoder/src/constants/reduxActionConstants.ts b/client/packages/lowcoder/src/constants/reduxActionConstants.ts
index ae7ebf1298..90102d79bc 100644
--- a/client/packages/lowcoder/src/constants/reduxActionConstants.ts
+++ b/client/packages/lowcoder/src/constants/reduxActionConstants.ts
@@ -102,6 +102,8 @@ export const ReduxActionTypes = {
   MARK_USER_STATUS: "MARK_USER_STATUS",
   FETCH_ORG_API_USAGE: "FETCH_ORG_API_USAGE",
   FETCH_ORG_API_USAGE_SUCCESS: "FETCH_ORG_API_USAGE_SUCCESS",
+  FETCH_ORG_LAST_MONTH_API_USAGE: "FETCH_ORG_LAST_MONTH_API_USAGE",
+  FETCH_ORG_LAST_MONTH_API_USAGE_SUCCESS: "FETCH_ORG_LAST_MONTH_API_USAGE_SUCCESS",
 
   /* home data */
   FETCH_HOME_DATA: "FETCH_HOME_DATA",
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index 0ad9f76c95..146aa4330a 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -1908,7 +1908,11 @@ export const en = {
     "preloadLibsAddBtn": "Add a Library",
     "saveSuccess": "Saved Successfully",
     "AuthOrgTitle": "Workspace Welcome Screen",
-    "AuthOrgDescrition": "The URL for Your Users to Sign In to the Current Workspace."
+    "AuthOrgDescrition": "The URL for Your Users to Sign In to the Current Workspace.",
+    "APIConsumption": "API Consumption",
+    "APIConsumptionDescription": "Here you can see the API Consumption for All Apps in the Current Workspace.",
+    "overallAPIConsumption": "Overall API Consumption in this Workspace till now",
+    "lastMonthAPIConsumption": "Last Month API Consumption, in this Workspace"
   },
 
 
diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts
index f39827bcb3..a6057f1767 100644
--- a/client/packages/lowcoder/src/i18n/locales/zh.ts
+++ b/client/packages/lowcoder/src/i18n/locales/zh.ts
@@ -1809,6 +1809,10 @@ advanced: {
     preloadLibsEmpty: "尚未添加 JavaScript 库",
     preloadLibsAddBtn: "添加库",
     saveSuccess: "保存成功",
+    "APIConsumption": "API 消耗",
+    "APIConsumptionDescription": "API 消耗是指当前工作空间中所有应用程序的 API 消耗情况,包括调用次数和调用时间.",
+    "overallAPIConsumption": "总体 API 消耗",
+    "apiCalls" : "API 调用次数",
 },
 branding: {
     title: "品牌",
diff --git a/client/packages/lowcoder/src/pages/setting/advanced/AdvancedSetting.tsx b/client/packages/lowcoder/src/pages/setting/advanced/AdvancedSetting.tsx
index 85b8aac0b5..cf13c06f56 100644
--- a/client/packages/lowcoder/src/pages/setting/advanced/AdvancedSetting.tsx
+++ b/client/packages/lowcoder/src/pages/setting/advanced/AdvancedSetting.tsx
@@ -7,7 +7,9 @@ import React, { useEffect, useState } from "react";
 import { useDispatch, useSelector } from "react-redux";
 import { fetchCommonSettings, setCommonSettings } from "redux/reduxActions/commonSettingsActions";
 import { getCommonSettings } from "redux/selectors/commonSettingSelectors";
+import { fetchAPIUsageAction, fetchLastMonthAPIUsageAction } from "redux/reduxActions/orgActions";
 import { getUser } from "redux/selectors/usersSelectors";
+import { getOrgApiUsage, getOrgLastMonthApiUsage } from "redux/selectors/orgSelectors";
 import styled from "styled-components";
 import { useShallowEqualSelector } from "util/hooks";
 import { Level1SettingPageContent, Level1SettingPageTitle } from "../styled";
@@ -24,6 +26,7 @@ import { getGlobalSettings } from "comps/utils/globalSettings";
 import { fetchJSLibrary } from "util/jsLibraryUtils";
 import { evalFunc } from "lowcoder-core";
 import { messageInstance } from "lowcoder-design";
+import Api from "@lowcoder-ee/api/api";
 
 const AdvancedSettingContent = styled.div`
   max-width: 840px;
@@ -76,6 +79,16 @@ export function AdvancedSetting() {
     label: app.name,
   }));
 
+  const apiUsage = useSelector(getOrgApiUsage);
+  useEffect(() => {
+    dispatch(fetchAPIUsageAction(currentUser.currentOrgId));
+  }, [currentUser.currentOrgId])
+
+  const lastMonthApiUsage = useSelector(getOrgLastMonthApiUsage);
+  useEffect(() => {
+    dispatch(fetchLastMonthAPIUsageAction(currentUser.currentOrgId));
+  }, [currentUser.currentOrgId])
+
   useEffect(() => {
     dispatch(fetchCommonSettings({ orgId: currentUser.currentOrgId }));
     dispatch(fetchAllApplications({}));
@@ -118,8 +131,8 @@ export function AdvancedSetting() {
 
   const isNotChange = JSON.stringify(commonSettings) === JSON.stringify(settings);
   const extraAdvanceSettings = useExtraAdvanceSettings();
-
   const runJSInHost = getGlobalSettings().orgCommonSettings?.runJavaScriptInHost ?? false;
+
   return (
     <Level1SettingPageContent>
       <Prompt
@@ -262,6 +275,12 @@ export function AdvancedSetting() {
           )}
         </div>
         {extraAdvanceSettings}
+        <div className="section-title">{trans("advanced.APIConsumption")}</div>
+        <HelpText style={{ marginBottom: 12 }}>{trans("advanced.APIConsumptionDescription")}</HelpText>
+        <div className="section-content">
+          {trans("advanced.overallAPIConsumption")} : {apiUsage ? Intl.NumberFormat('en-GB', { maximumFractionDigits: 2 }).format(apiUsage) + " API Calls.": 'Loading API usage data...'}<br/>
+          {trans("advanced.lastMonthAPIConsumption")} : {lastMonthApiUsage ? Intl.NumberFormat('en-GB', { maximumFractionDigits: 2 }).format(lastMonthApiUsage) + " API Calls." : 'Loading API usage data...'}
+        </div>
       </AdvancedSettingContent>
     </Level1SettingPageContent>
   );
diff --git a/client/packages/lowcoder/src/pages/setting/index.tsx b/client/packages/lowcoder/src/pages/setting/index.tsx
index 9cfa2b235b..aa321ef330 100644
--- a/client/packages/lowcoder/src/pages/setting/index.tsx
+++ b/client/packages/lowcoder/src/pages/setting/index.tsx
@@ -9,15 +9,6 @@ import SettingHome from "./settingHome";
 export function Setting() {
   const user = useSelector(getUser);
 
-  /* fetch Org's API usage
-
-  const apiUsage = useSelector(getOrgApiUsage);
-  useEffect(() => {
-    dispatch(fetchAPIUsageAction(user.currentOrgId));
-  }, [user.currentOrgId])
-
-  */
-
   if (!currentOrgAdminOrDev(user)) {
     history.push(BASE_URL);
   }
diff --git a/client/packages/lowcoder/src/redux/reducers/uiReducers/orgReducer.ts b/client/packages/lowcoder/src/redux/reducers/uiReducers/orgReducer.ts
index f020cf99f1..47ad062201 100644
--- a/client/packages/lowcoder/src/redux/reducers/uiReducers/orgReducer.ts
+++ b/client/packages/lowcoder/src/redux/reducers/uiReducers/orgReducer.ts
@@ -9,6 +9,7 @@ import {
   DeleteOrgUserPayload,
   GroupUsersPayload,
   OrgAPIUsagePayload,
+  OrgLastMonthAPIUsagePayload,
   OrgUsersPayload,
   RemoveGroupUserPayload,
 } from "redux/reduxActions/orgActions";
@@ -26,6 +27,7 @@ const initialState: OrgReduxState = {
   fetchOrgGroupsFinished: false,
   orgCreateStatus: "init",
   apiUsage: 0,
+  lastMonthApiUsage: 0,
 };
 
 const orgReducer = createImmerReducer(initialState, {
@@ -106,13 +108,22 @@ const orgReducer = createImmerReducer(initialState, {
     ...state,
     orgCreateStatus: "error",
   }),
+  
   [ReduxActionTypes.FETCH_ORG_API_USAGE_SUCCESS]: (
     state: OrgReduxState,
     action: ReduxAction<OrgAPIUsagePayload>
   ): OrgReduxState => ({
     ...state,
     apiUsage: action.payload.apiUsage,
-  })
+  }),
+
+  [ReduxActionTypes.FETCH_ORG_LAST_MONTH_API_USAGE_SUCCESS]: (
+    state: OrgReduxState,
+    action: ReduxAction<OrgLastMonthAPIUsagePayload>
+  ): OrgReduxState => ({
+    ...state,
+    lastMonthApiUsage: action.payload.lastMonthApiUsage,
+  }),
 });
 
 export interface OrgReduxState {
@@ -125,6 +136,7 @@ export interface OrgReduxState {
   fetchOrgGroupsFinished: boolean;
   orgCreateStatus: ApiRequestStatus;
   apiUsage: number;
+  lastMonthApiUsage: number;
 }
 
 export default orgReducer;
diff --git a/client/packages/lowcoder/src/redux/reduxActions/orgActions.ts b/client/packages/lowcoder/src/redux/reduxActions/orgActions.ts
index 9d2f3eb6ac..196d7c1554 100644
--- a/client/packages/lowcoder/src/redux/reduxActions/orgActions.ts
+++ b/client/packages/lowcoder/src/redux/reduxActions/orgActions.ts
@@ -152,24 +152,43 @@ export const updateOrgSuccess = (payload: UpdateOrgPayload) => {
   };
 };
 
+
+// till now
 export type OrgAPIUsagePayload = {
   apiUsage: number,
 };
-
 export const fetchAPIUsageAction = (
   orgId: string,
-  lastMonthOnly?: boolean,
 ) => ({
   type: ReduxActionTypes.FETCH_ORG_API_USAGE,
   payload: {
     orgId,
-    lastMonthOnly,
   },
 });
 
-export const fetchAPIUsageSuccessAction = (apiUsage: number) => ({
-  type: ReduxActionTypes.FETCH_ORG_API_USAGE_SUCCESS,
+export const fetchAPIUsageActionSuccess = (payload: OrgAPIUsagePayload) => {
+  return {
+    type: ReduxActionTypes.FETCH_ORG_API_USAGE_SUCCESS,
+    payload: payload,
+  };
+};
+
+// last month
+export type OrgLastMonthAPIUsagePayload = {
+  lastMonthApiUsage: number,
+};
+export const fetchLastMonthAPIUsageAction = (
+  orgId: string,
+) => ({
+  type: ReduxActionTypes.FETCH_ORG_LAST_MONTH_API_USAGE,
   payload: {
-    apiUsage,
+    orgId,
   },
 });
+
+export const fetchLastMonthAPIUsageActionSuccess = (payload: OrgLastMonthAPIUsagePayload) => {
+  return {
+    type: ReduxActionTypes.FETCH_ORG_LAST_MONTH_API_USAGE_SUCCESS,
+    payload: payload,
+  };
+};
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/redux/sagas/orgSagas.ts b/client/packages/lowcoder/src/redux/sagas/orgSagas.ts
index f1604241de..125d13c009 100644
--- a/client/packages/lowcoder/src/redux/sagas/orgSagas.ts
+++ b/client/packages/lowcoder/src/redux/sagas/orgSagas.ts
@@ -21,6 +21,8 @@ import {
   UpdateGroupActionPayload,
   UpdateOrgPayload,
   updateOrgSuccess,
+  fetchAPIUsageActionSuccess,
+  fetchLastMonthAPIUsageActionSuccess,
   UpdateUserGroupRolePayload,
   UpdateUserOrgRolePayload,
 } from "redux/reduxActions/orgActions";
@@ -282,20 +284,34 @@ export function* updateOrgSaga(action: ReduxAction<UpdateOrgPayload>) {
 
 export function* fetchAPIUsageSaga(action: ReduxAction<{
   orgId: string,
-  lastMonthOnly?: boolean,
 }>) {
   try {
     const response: AxiosResponse<OrgAPIUsageResponse> = yield call(
       OrgApi.fetchAPIUsage,
       action.payload.orgId,
-      action.payload.lastMonthOnly,
     );
     const isValidResponse: boolean = validateResponse(response);
     if (isValidResponse) {
-      yield put({
-        type: ReduxActionTypes.FETCH_ORG_API_USAGE_SUCCESS,
-        payload: response.data.data,
-      });
+      yield put(fetchAPIUsageActionSuccess({apiUsage: response.data.data})
+      );
+    }
+  } catch (error) {
+    log.error(error);
+  }
+}
+
+export function* fetchLastMonthAPIUsageSaga(action: ReduxAction<{
+  orgId: string,
+}>) {
+  try {
+    const response: AxiosResponse<OrgAPIUsageResponse> = yield call(
+      OrgApi.fetchLastMonthAPIUsage,
+      action.payload.orgId,
+    );
+    const isValidResponse: boolean = validateResponse(response);
+    if (isValidResponse) {
+      yield put(fetchLastMonthAPIUsageActionSuccess({lastMonthApiUsage: response.data.data})
+      );
     }
   } catch (error) {
     log.error(error);
@@ -320,5 +336,6 @@ export default function* orgSagas() {
     takeLatest(ReduxActionTypes.DELETE_ORG, deleteOrgSaga),
     takeLatest(ReduxActionTypes.UPDATE_ORG, updateOrgSaga),
     takeLatest(ReduxActionTypes.FETCH_ORG_API_USAGE, fetchAPIUsageSaga),
+    takeLatest(ReduxActionTypes.FETCH_ORG_LAST_MONTH_API_USAGE, fetchLastMonthAPIUsageSaga),
   ]);
 }
diff --git a/client/packages/lowcoder/src/redux/selectors/orgSelectors.ts b/client/packages/lowcoder/src/redux/selectors/orgSelectors.ts
index 8ea9aa3ec0..2e69cb7be1 100644
--- a/client/packages/lowcoder/src/redux/selectors/orgSelectors.ts
+++ b/client/packages/lowcoder/src/redux/selectors/orgSelectors.ts
@@ -19,3 +19,7 @@ export const getOrgCreateStatus = (state: AppState) => {
 export const getOrgApiUsage = (state: AppState) => {
   return state.ui.org.apiUsage;
 }
+
+export const getOrgLastMonthApiUsage = (state: AppState) => {
+  return state.ui.org.lastMonthApiUsage;
+}

From 4ac41029adfd596fd6b9f7c106fb986c1b4fa541 Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Sun, 25 Feb 2024 12:58:51 +0100
Subject: [PATCH 96/97] Updated Readme for Sponsors

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 6ef8e9423b..07a5693a53 100644
--- a/README.md
+++ b/README.md
@@ -99,4 +99,4 @@ You can access Lowcoder from [cloud-hosted version](https://app.lowcoder.cloud/)
 Accelerate the growth of Lowcoder and unleash its potential with your Sponsorship – together, we're shaping the future of Lowcode for everyone!
 [Be a Sponsor](https://github.com/sponsors/lowcoder-org)
 
-Like ... @CHSchuepfer & @spacegoats-io. Thank you very much!!
\ No newline at end of file
+Like ...  [@spacegoats-io](https://github.com/spacegoats-io), [@Jomedya](https://github.com/Jomedya), [@CHSchuepfer](https://github.com/CHSchuepfer), Thank you very much!!
\ No newline at end of file

From 97a091c8f6ad88b449d0ce573bf6c035f4295d6f Mon Sep 17 00:00:00 2001
From: FalkWolsky <fw@falkwolsky.com>
Date: Sun, 25 Feb 2024 14:56:49 +0100
Subject: [PATCH 97/97] Display Fix for Marketplaces

---
 .../src/pages/ApplicationV2/HomeLayout.tsx    | 53 +++++++++++++------
 1 file changed, 37 insertions(+), 16 deletions(-)

diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
index ff6b6cf27e..eccd53b21f 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
@@ -34,7 +34,7 @@ import { isFetchingFolderElements } from "../../redux/selectors/folderSelector";
 import { checkIsMobile } from "util/commonUtils";
 import MarketplaceHeaderImage from "assets/images/marketplaceHeaderImage.jpg";
 import { Divider } from "antd";
-import { Margin } from "../setting/theme/styledComponents";
+import { Margin } from "../setting/theme/styledComponents"; 
 
 const Wrapper = styled.div`
   display: flex;
@@ -239,6 +239,7 @@ const LayoutSwitcher = styled.div`
   }
 `;
 
+
 function showNewUserGuide(user: User) {
   return (
     user.orgDev &&
@@ -278,7 +279,7 @@ export function HomeLayout(props: HomeLayoutProps) {
   const { breadcrumb = [], elements = [], localMarketplaceApps = [], globalMarketplaceApps = [],mode } = props;
   const user = useSelector(getUser);
   const isFetching = useSelector(isFetchingFolderElements);
-
+  const isSelfHost = window.location.host !== 'app.lowcoder.cloud';
   const [filterBy, setFilterBy] = useState<HomeResKey>("All");
   const [searchValue, setSearchValue] = useState("");
   const [layout, setLayout] = useState<HomeLayoutType>(
@@ -294,14 +295,16 @@ export function HomeLayout(props: HomeLayoutProps) {
   }
 
   var displayElements = elements;
-  if (mode === "marketplace") {
+  if (mode === "marketplace" && isSelfHost) {
     const markedLocalApps = localMarketplaceApps.map(app => ({ ...app, isLocalMarketplace: true }));
     const markedGlobalApps = globalMarketplaceApps.map(app => ({ ...app, isLocalMarketplace: false }));
     // Merge local and global apps into the elements array
     displayElements = [...markedLocalApps, ...markedGlobalApps];
   }
-
-  console.log("HomeLayout: displayElements", displayElements);
+  else if (mode === "marketplace") {
+    const markedLocalApps = localMarketplaceApps.map(app => ({ ...app, isLocalMarketplace: true }));
+    displayElements = [...markedLocalApps];
+  }
 
   const resList: HomeRes[] = displayElements
     .filter((e) =>
@@ -454,19 +457,37 @@ export function HomeLayout(props: HomeLayoutProps) {
                       <>
                         {layout === "list" ? (
                           <>
-                            <h2 style={{padding: "0 36px"}}>{trans("home.localMarketplaceTitle")}</h2>
-                            <HomeTableView resources={resList.filter(app => app.isLocalMarketplace)} />
-                            <Divider style={{padding: "0 36px", margin: "0 36px", width: "calc(100% - 72px) !important"}}/>
-                            <h2 style={{padding: "0 36px"}}>{trans("home.globalMarketplaceTitle")}</h2>
-                            <HomeTableView resources={resList.filter(app => !app.isLocalMarketplace)} />
+                            {isSelfHost ? (
+                              <>
+                                <h2 style={{ padding: "0 36px" }}>{trans("home.localMarketplaceTitle")}</h2>
+                                <HomeTableView resources={resList.filter(app => app.isLocalMarketplace)} />
+                                <Divider style={{ padding: "0 36px", margin: "0 36px", width: "calc(100% - 72px) !important" }} />
+                                <h2 style={{ padding: "0 36px" }}>{trans("home.globalMarketplaceTitle")}</h2>
+                                <HomeTableView resources={resList.filter(app => !app.isLocalMarketplace)} />
+                              </>
+                            ) : (
+                              <>
+                                <h2 style={{padding: "0 36px"}}>{trans("home.globalMarketplaceTitle")}</h2>
+                                <HomeTableView resources={resList.filter(app => app.isLocalMarketplace)} />
+                              </> 
+                            )}
                           </>
                         ) : (
-                          <>
-                            <h2 style={{padding: "0 36px"}}>{trans("home.localMarketplaceTitle")}</h2>
-                            <HomeCardView resources={resList.filter(app => app.isLocalMarketplace)} />
-                            <Divider style={{padding: "0 36px", margin: "12px 36px", width: "calc(100% - 72px) !important"}}/>
-                            <h2 style={{padding: "0 36px"}}>{trans("home.globalMarketplaceTitle")}</h2>
-                            <HomeCardView resources={resList.filter(app => !app.isLocalMarketplace)} />
+                            <>
+                            {isSelfHost ? (
+                              <>
+                                <h2 style={{padding: "0 36px"}}>{trans("home.localMarketplaceTitle")}</h2>
+                                <HomeCardView resources={resList.filter(app => app.isLocalMarketplace)} />
+                                <Divider style={{padding: "0 36px", margin: "12px 36px", width: "calc(100% - 72px) !important"}}/>
+                                <h2 style={{padding: "0 36px"}}>{trans("home.globalMarketplaceTitle")}</h2>
+                                <HomeCardView resources={resList.filter(app => !app.isLocalMarketplace)} />
+                              </>
+                            ) : (
+                              <>
+                                <h2 style={{padding: "0 36px"}}>{trans("home.globalMarketplaceTitle")}</h2>
+                                <HomeCardView resources={resList.filter(app => app.isLocalMarketplace)} />
+                              </>
+                            )}
                           </>
                         )}
                       </>
