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/86] =?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 41f0bcf61..425b19185 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 ; + if (this.names[0].startsWith("antd/")) return this.def; + else + return ( + + ); } } @@ -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, searchText: string, - searchKeywords?: Record + searchKeywords?: Record, + 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; + IconType?: "OnlyAntd" | "All" | "default" | undefined; }) => { const [searchText, setSearchText] = useState(""); const [allIcons, setAllIcons] = useState>({}); 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) => ( - {searchResults.slice(p.index * columnNum, (p.index + 1) * columnNum).map(([key, icon]) => ( - - { - onChangeIcon(key); - }} + {searchResults + .slice(p.index * columnNum, (p.index + 1) * columnNum) + .map(([key, icon]) => ( + - {icon.getView()} - - - ))} + { + onChangeIcon(key); + }} + > + {icon.getView()} + + + ))} ), [searchResults, allIcons, onChangeIcon] @@ -279,6 +319,7 @@ export const IconSelectBase = (props: { leftOffset?: number; parent?: HTMLElement | null; searchKeywords?: Record; + 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; + 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 0ee9de8e6..7b84c439d 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 211dd0910..838b98a34 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 extends ControlParams { showSearch?: boolean; dropdownStyle?: React.CSSProperties; labelStyle?: React.CSSProperties; + IconType?: "OnlyAntd" | "All" | "default" | undefined; } interface DropdownPropertyViewProps diff --git a/client/packages/lowcoder/src/comps/controls/iconControl.tsx b/client/packages/lowcoder/src/comps/controls/iconControl.tsx index 26a768b4e..ca954b47d 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} > {icon ? ( @@ -251,7 +253,7 @@ export class IconControl extends AbstractComp - {this.useCodeEditor && } + {this.useCodeEditor && } ); } @@ -262,6 +264,7 @@ export class IconControl extends AbstractComp this.dispatchChangeValueAction(x)} label={params.label} + IconType={params.IconType} /> )} 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/86] 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 000000000..ce549b56c --- /dev/null +++ b/client/packages/lowcoder-design/src/icons/IconCompIcon.svg @@ -0,0 +1 @@ + \ 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 4ac1b051e..6d620cf46 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 000000000..41b73da71 --- /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) => { + const conRef = useRef(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 ( + + props.onEvent("click")} + > + {props.icon} + + + ); +}; + +let IconBasicComp = (function () { + return new UICompBuilder(childrenMap, (props) => ) + .setPropertyViewFn((children) => ( + <> +
+ {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"), + })} +
+
+ {children.onEvent.getPropertyView()} +
+
+ {hiddenPropertyView(children)} +
+
+ {children.style.getPropertyView()} +
+ + )) + .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 5d650faea..ca58c2836 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; export type ProgressStyleType = StyleConfigType; export type NavigationStyleType = StyleConfigType; export type ImageStyleType = StyleConfigType; +export type IconStyleType = StyleConfigType; export type ListViewStyleType = StyleConfigType; export type JsonSchemaFormStyleType = StyleConfigType; export type TreeSelectStyleType = StyleConfigType; diff --git a/client/packages/lowcoder/src/comps/index.tsx b/client/packages/lowcoder/src/comps/index.tsx index 5dc0f2923..b70906d20 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 6cd63e920..9ba13b930 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; diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 941a77767..304651c62 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 7fb2416d5..0539f15ca 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 a09a9a56e..cd3c81c3a 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: , mention: , autocomplete: , + icon: , }; 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/86] 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 425b19185..da47c2dab 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 ( Date: Fri, 29 Dec 2023 11:06:35 +0300 Subject: [PATCH 04/86] 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 35732c075..5e87d3b57 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; @@ -43,6 +47,7 @@ export class EditorState { readonly showPropertyPane: boolean = false; readonly selectedCompNames: Set = 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((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, selectSource?: SelectSourceType) { + setSelectedCompNames( + selectedCompNames: Set, + 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((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(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 0b80f0b73..108076d3e 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 (
{user.isAnonymous ? ( - history.push(AUTH_LOGIN_URL)}> + history.push(AUTH_LOGIN_URL)} + > {trans("userAuth.login")} ) : ( @@ -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 = ( <> 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 && {trans("header.viewOnly")}} + {showAppSnapshot && ( + {trans("header.viewOnly")} + )} ); - // key={option.key} - const headerMiddle = ( - <> - + <> + <> +

+ Layers +

+ { + toggleCollissionStatus(value == true ? "true" : "false"); + editorState.setCollissionStatus(value == true ? "true" : "false"); + }} + /> + + {editorModeOptions.map((option) => ( {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) { !visible && setPermissionDialogVisible(false)} + onVisibleChange={(visible) => + !visible && setPermissionDialogVisible(false) + } /> )} {canManageApp(user, application) && ( - setPermissionDialogVisible(true)}>{SHARE_TITLE} + setPermissionDialogVisible(true)}> + {SHARE_TITLE} + )} preview(applicationId)}> {trans("header.preview")} @@ -436,11 +521,15 @@ export default function Header(props: HeaderProps) { items={[ { key: "deploy", - label: {trans("header.deploy")}, + label: ( + {trans("header.deploy")} + ), }, { key: "snapshot", - label: {trans("header.snapshot")}, + label: ( + {trans("header.snapshot")} + ), }, ]} /> @@ -456,7 +545,11 @@ export default function Header(props: HeaderProps) { ); return ( - + ); } @@ -475,7 +568,9 @@ export function AppHeader() { ); } diff --git a/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx b/client/packages/lowcoder/src/pages/editor/editorSkeletonView.tsx index e1a1766ad..aa036d57c 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 ( <> -
+
{panelStatus.left && ( @@ -77,7 +85,11 @@ export default function EditorSkeletonView() { )} {panelStatus.right && ( - + )} diff --git a/client/packages/lowcoder/src/pages/editor/editorView.tsx b/client/packages/lowcoder/src/pages/editor/editorView.tsx index a63c2ad2f..d82a0b618 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().state; + const collisionState = useLocation().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(DefaultPanelStatus); - + const [prePanelStatus, setPrePanelStatus] = + useState(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) { {uiComp.getView()} -
{hookCompViews}
+
+ {hookCompViews} +
); @@ -329,7 +376,14 @@ function EditorView(props: EditorViewProps) { draggingUtils.clearData(); }} > -
+
{application && {application.name}} {showNewUserGuide && } {application && - !isAggregationApp(AppUILayoutType[application.applicationType]) && ( + !isAggregationApp( + AppUILayoutType[application.applicationType] + ) && ( <> {appSettingsComp.getPropertyView()} @@ -379,7 +435,11 @@ function EditorView(props: EditorViewProps) { {props.preloadComp.getPropertyView()} - dispatch(setEditorExternalStateAction({ showScriptsAndStyleModal: true })) + dispatch( + setEditorExternalStateAction({ + showScriptsAndStyleModal: true, + }) + ) } > diff --git a/client/packages/lowcoder/src/pages/tutorials/tutorialsConstant.tsx b/client/packages/lowcoder/src/pages/tutorials/tutorialsConstant.tsx index 147327178..550f07214 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 2d06ddd20..c6ee587ad 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 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 05/86] 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] --- .../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 4b85ecf87..a6b2b83b0 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 5e87b4483..7fa45ad87 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 f0d610f5c..1bf1dae92 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 357c4dee8..5b434b6b8 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 36583cdcf..e595878f5 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 f575d828d..9fb4735ad 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 9dead2fc8..e52824631 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, fsevents@patch:fsevents@~2.3.2#~builtin, fsevents@patch:fsevents@~2.3.3#~builtin": +"fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::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 Date: Thu, 18 Jan 2024 12:42:52 +0500 Subject: [PATCH 06/86] 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 678bcabb0..7e9061504 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 39a392ad4..6932a4983 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(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 4532475c8..a9fb52ea7 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> { + console.log(columnsAggrData); const sortMap: Map = 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 211dd0910..1492a97a4 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( return controlItem( { filterText: params.label }, + {...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 Date: Mon, 22 Jan 2024 14:44:38 -0700 Subject: [PATCH 07/86] 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 3fda2c7f8..3cb22b11e 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 Date: Tue, 23 Jan 2024 13:33:34 +0500 Subject: [PATCH 08/86] 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 7e9061504..678bcabb0 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 3a1e91f8a..b65c74eb4 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 ( - + {value ? ( ) : 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 6932a4983..0d5e2ac2b 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(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(""), + columnsList: valueComp>([]), hide: BoolControl, sortable: BoolControl, width: NumberControl, autoWidth: dropdownControl(columnWidthOptions, "auto"), - columnMapping: dropdownControl(columnValueOptions, ""), render: RenderComp, align: HorizontalAlignmentControl, tempHide: stateComp(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(); - // } + { + // Keep the previous text value, some components do not have text, the default value is currentCell + const compType = columnType; + let comp: Record = { 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 a9fb52ea7..9508af8ce 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: {column}, + value: `{{currentRow.${column}}}` + })) + initialColumns.push({ + label: Select with handlebars, + value: '{{currentCell}}', + }) + return initialColumns; +} + export type CustomColumnType = ColumnType & { onWidthResize?: (width: number) => void; titleText: string; @@ -271,7 +283,7 @@ export function columnsToAntdFormat( columnsAggrData: ColumnsAggrData, onTableEvent: (eventName: any) => void, ): Array> { - console.log(columnsAggrData); + const initialColumns = getInitialColumns(columnsAggrData); const sortMap: Map = 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 298e80ef4..b30fead70 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 9cc91a970..b5ec23f09 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 ac390b96c..f53bbcb57 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 a91e25bff..7ff3d6825 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 Date: Tue, 23 Jan 2024 20:24:05 +0500 Subject: [PATCH 09/86] 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 f575d828d..50dbd813f 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 74beb77aa..dd591145f 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) => ( diff --git a/client/packages/lowcoder/src/components/PermissionDialog/PermissionList.tsx b/client/packages/lowcoder/src/components/PermissionDialog/PermissionList.tsx index d834b7cd0..4fd3abb9e 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 b349ae061..ff1478fe4 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) => )<{ $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 6a9cd6980..685673735 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 20622b3b2..e8e729579 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 af5070300..9149af73c 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={} 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 25fd9e1d3..566da4aa9 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 () { { 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 4ed3b40da..9a28d1830 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 () { { 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 748308f86..aa131c04e 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 () { { 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 60f302ce5..1c5e02814 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: , downIcon: }} 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 28a2db083..04678f33b 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) => { } 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 4124d67ee..fd8eaf901 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) => { } - 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 a0da677ae..574972e4e 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 () { { 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 1ae4b9673..f885e2436 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 9ecd9aa16..fde596953 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) { {mode !== "folders" && mode !== "module" && ( 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={} /> )} diff --git a/client/packages/lowcoder/src/pages/editor/bottom/BottomMetaDrawer.tsx b/client/packages/lowcoder/src/pages/editor/bottom/BottomMetaDrawer.tsx index 6dd207ef6..197389596 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) { } 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 9dead2fc8..876df404e 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 Date: Wed, 24 Jan 2024 23:41:54 +0100 Subject: [PATCH 10/86] 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 5e87d3b57..9ec9e5415 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 e7dd9d9dd..3581a3eaf 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 = ( <> - <> -

- Layers -

- { - toggleCollissionStatus(value == true ? "true" : "false"); - editorState.setCollissionStatus(value == true ? "true" : "false"); - }} - /> + <> {panelStatus.left && ( - + )} diff --git a/client/packages/lowcoder/src/pages/editor/editorView.tsx b/client/packages/lowcoder/src/pages/editor/editorView.tsx index 81b7ec084..e1b966688 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: , }, + { + key: SiderKey.Layout, + icon: , + }, ]; + // 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} /> {application && {application.name}} {showNewUserGuide && } @@ -395,7 +414,8 @@ function EditorView(props: EditorViewProps) { > - + + clickMenu(params)} - /> + > + + {!showAppSnapshot && ( )} + + + + {menuKey === SiderKey.Layout && ( + + { + toggleCollissionStatus(value == true ? "true" : "false"); + editorState.setCollissionStatus(value == true ? "true" : "false"); + }} + /> + + + )} + )} diff --git a/client/packages/lowcoder/src/util/localStorageUtil.ts b/client/packages/lowcoder/src/util/localStorageUtil.ts index c6ee587ad..15e951909 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 Date: Thu, 25 Jan 2024 19:17:12 +0100 Subject: [PATCH 11/86] 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 d0db17798..b29a693f4 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 9ec9e5415..ee9db5475 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; @@ -47,7 +47,7 @@ export class EditorState { readonly showPropertyPane: boolean = false; readonly selectedCompNames: Set = 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 { 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(undefined as any); diff --git a/client/packages/lowcoder/src/layout/utils.ts b/client/packages/lowcoder/src/layout/utils.ts index c55c44dc2..6a9f0494d 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 3581a3eaf..06a0067ec 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 5924d90bf..01de26f67 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([]); + const [modalsTreeData, setModalsTreeData] = useState([]); + + 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 ( props.type && (CompStateIcon[props.type] || )} + 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] || )} - // switcherIcon={({ expanded }: { expanded: boolean }) => - // expanded ? : - // } switcherIcon={(props: any) => props.expanded ? : } @@ -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) => { ); -}; +}; \ 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 58d7ffd5a..01ba97c43 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() { {panelStatus.left && ( diff --git a/client/packages/lowcoder/src/pages/editor/editorView.tsx b/client/packages/lowcoder/src/pages/editor/editorView.tsx index e1b966688..8cd7390fe 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().state; - const collisionState = useLocation().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 && ( { - toggleCollissionStatus(value == true ? "true" : "false"); - editorState.setCollissionStatus(value == true ? "true" : "false"); + toggleCollisionStatus(value == true ? "true" : "false"); + editorState.setCollisionStatus(value == true ? "true" : "false"); }} /> diff --git a/client/packages/lowcoder/src/pages/tutorials/tutorialsConstant.tsx b/client/packages/lowcoder/src/pages/tutorials/tutorialsConstant.tsx index 550f07214..147327178 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 15e951909..2f102a696 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 Date: Thu, 1 Feb 2024 21:06:06 +0500 Subject: [PATCH 12/86] 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 1c5863f9b..8144b45e2 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 publishedApplicationDSL; private final Boolean publicToAll; + private final Boolean publicToMarketplace; + private Map editingApplicationDSL; @Transient @@ -75,6 +77,7 @@ public Application(@JsonProperty("orgId") String organizationId, @JsonProperty("applicationStatus") ApplicationStatus applicationStatus, @JsonProperty("publishedApplicationDSL") Map publishedApplicationDSL, @JsonProperty("publicToAll") Boolean publicToAll, + @JsonProperty("publicToMarketplace") Boolean publicToMarketplace, @JsonProperty("editingApplicationDSL") Map 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 f520fe037..db842dadb 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 findByPublicToAllIsTrueAndIdIn(Collection ids); + Flux 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 79acb2619..c0917d2ec 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 findByOrganizationIdWithoutDsl(String organizationId) { return repository.findByOrganizationId(organizationId); } + public Flux findAllMarketplaceApps() { + return repository.findByPublicToAllIsTrueAndPublicToMarketplaceIsTrue(); + } + public Mono countByOrganizationId(String orgId, ApplicationStatus applicationStatus) { return repository.countByOrganizationIdAndApplicationStatus(orgId, applicationStatus); } @@ -147,6 +151,13 @@ public Mono setApplicationPublicToAll(String applicationId, boolean pub return mongoUpsertHelper.updateById(application, applicationId); } + public Mono setApplicationPublicToMarketplace(String applicationId, boolean publicToMarketplace) { + Application application = Application.builder() + .publicToMarketplace(publicToMarketplace) + .build(); + return mongoUpsertHelper.updateById(application, applicationId); + } + @NonEmptyMono @SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform") public Mono> getPublicApplicationIds(Collection 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 b6b214990..c11257e41 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 f2a538e16..cf3d68d48 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 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 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 setApplicationPublicToAll(String applicationId, boolean pub .then(applicationService.setApplicationPublicToAll(applicationId, publicToAll)); } + public Mono 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 sanitizeDsl(Map applicationDsl) { if (applicationDsl.get("queries") instanceof List queries) { List> 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 b080da7ba..ff37c6011 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>> getApplications(@RequestPar .map(ResponseView::success); } + @Override + public Mono>> 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> updatePermission(@PathVariable String applicationId, @PathVariable String permissionId, @@ -177,4 +186,11 @@ public Mono> setApplicationPublicToAll(@PathVariable Strin return applicationApiService.setApplicationPublicToAll(applicationId, request.publicToAll()) .map(ResponseView::success); } + + @Override + public Mono> 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 8417c40d0..da51dfa04 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>> 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>> getMarketplaceApplications(@RequestParam(required = false) Integer applicationType); + @Operation( tags = TAG_APPLICATION_PERMISSIONS, operationId = "updateApplicationPermissions", @@ -202,8 +212,18 @@ public Mono> grantPermission( public Mono> setApplicationPublicToAll(@PathVariable String applicationId, @RequestBody ApplicationPublicToAllRequest request); - - public record BatchAddPermissionRequest(String role, Set userIds, Set 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> setApplicationPublicToMarketplace(@PathVariable String applicationId, + @RequestBody ApplicationPublicToMarketplaceRequest request); + + + public record BatchAddPermissionRequest(String role, Set userIds, Set 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 62cc9258f..66eda1871 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 64d8b1038..ec17670bf 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 000000000..b45ffd499 --- /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 ddcfff54c..5f194fcc4 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 getAllAuthorisedApplications4CurrentOrgMember(@Nullable ApplicationType applicationType, @Nullable ApplicationStatus applicationStatus, boolean withContainerSize); + + public Flux 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 f08307647..6d7aff678 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 getAllAuthorisedApplications4CurrentOrgMember(@ }); } + @Override + public Flux getAllMarketplaceApplications(@Nullable ApplicationType applicationType) { + + return sessionUserService.getVisitorOrgMemberCache() + .flatMapMany(orgMember -> { + // application flux + Flux applicationFlux = Flux.defer(() -> applicationService.findAllMarketplaceApps()) + .filter(application -> isNull(applicationType) || application.getApplicationType() == applicationType.getValue()) + .cache(); + + // user map + Mono> userMapMono = applicationFlux + .flatMap(application -> emptyIfNull(application.getCreatedBy())) + .collectList() + .flatMap(creatorIds -> userService.getByIds(creatorIds)) + .cache(); + + // org map + Mono> 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 userMap = tuple.getT2(); + Map 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 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 Date: Fri, 2 Feb 2024 20:44:25 +0500 Subject: [PATCH 13/86] 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 26ac5561e..45d8f7d26 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("compType"); const compLayout = draggingUtils.getData("compLayout"); if (compType) { diff --git a/client/packages/lowcoder/src/comps/comps/textComp.tsx b/client/packages/lowcoder/src/comps/comps/textComp.tsx index 671e67354..aec1f8af1 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 fcd2a361b..358f52dcc 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 ba80c46f5..d3fec9367 100644 --- a/client/packages/lowcoder/src/layout/gridItem.tsx +++ b/client/packages/lowcoder/src/layout/gridItem.tsx @@ -34,6 +34,7 @@ type GridItemCallback = ( 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} @@ -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 328ff1ab6..0058ff71f 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 { }; processGridItem( + zIndex: number, item: LayoutItem, childrenMap: _.Dictionary ): React.ReactElement | undefined { @@ -464,6 +465,7 @@ class GridLayout extends React.Component { top: showName?.top ?? 0, bottom: (showName?.bottom ?? 0) + (this.ref.current?.scrollHeight ?? 0), }} + zIndex={zIndex} > {child} @@ -863,7 +865,6 @@ class GridLayout extends React.Component { // 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 { 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 ( {
{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()}
diff --git a/client/packages/lowcoder/src/layout/utils.ts b/client/packages/lowcoder/src/layout/utils.ts index 6a9f0494d..40ee0ed72 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 01de26f67..66f32141c 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>([]); const [showData, setShowData] = useState([]); + 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 c0d68b2f9..6df7b9d7a 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 Date: Sat, 3 Feb 2024 14:16:50 +0100 Subject: [PATCH 14/86] [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 2afd2a739..8b80e30bf 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 d3fec9367..ad1f8ae06 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} diff --git a/client/packages/lowcoder/src/pages/editor/LeftContent.tsx b/client/packages/lowcoder/src/pages/editor/LeftContent.tsx index 66f32141c..faee2cea3 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; + checkable?: boolean; + isDraggable?: boolean; } enum LeftTabKey { @@ -250,6 +253,8 @@ export const LeftContent = (props: LeftContentProps) => { const [showData, setShowData] = useState([]); 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); }} > - +
) : ( @@ -395,7 +400,7 @@ export const LeftContent = (props: LeftContentProps) => { setShowData(newData); }} > - + ))} @@ -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 ( - handleDrop(info, type)} + <> props.type && (CompStateIcon[props.type as UICompType] || )} - switcherIcon={(props: any) => - props.expanded ? : - } + icon={(props: any) => props.type && ( +
{/* Adjust the margin as needed */} + {CompStateIcon[props.type as UICompType] || } +
+ )} + switcherIcon={(props: any) => props.expanded ? : } 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)} /> + +
+ ); }; @@ -623,6 +551,7 @@ export const LeftContent = (props: LeftContentProps) => { }, [editorState]); const moduleLayoutComp = uiComp.getModuleLayoutComp(); + const stateContent = (
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 000000000..bba1dfbd3 --- /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; +} + +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>([]); + 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.title} + + + + ); + }; + + const [componentTreeData, setComponentTreeData] = useState([]); + + 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([]); + + 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 ( + <> + { + toggleCollisionStatus(value == true ? "true" : "false"); + editorState.setCollisionStatus(value == true ? "true" : "false"); + } } /> + handleDrop(info)} + treeData={componentTreeData} + icon={(props: any) => props.type && ( +
{/* Adjust the margin as needed */} + {CompStateIcon[props.type as UICompType] || } +
+ )} + switcherIcon={(props: any) => props.expanded ? : } + expandedKeys={expandedKeys} + onExpand={(keys) => setExpandedKeys(keys)} + // onClick={(e, node) => handleNodeClick(e, node, uiCompInfos)} + selectedKeys={selectedKeys} + titleRender={(nodeData) => getTreeNode(nodeData as NodeItem, uiCompInfos)} /> + +
+ + ); + }; + + const uiCollapse = useMemo(() => { + if (isAggregationApp(editorState.getAppType())) { + return; + } + return getTreeUI(); + }, [editorState, uiCollapseClick, expandedKeys, componentTreeData]); + + const layerControlContent = ( + +
+ + {uiCollapse} + +
+
+ ); + + return {layerControlContent}; + +}; \ 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 8cd7390fe..45a512214 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 ( { @@ -437,7 +418,7 @@ function EditorView(props: EditorViewProps) { {panelStatus.left && editorModeStatus !== "layout" && ( - {menuKey === SiderKey.State && } + {menuKey === SiderKey.State && } {menuKey === SiderKey.Setting && ( @@ -470,20 +451,8 @@ function EditorView(props: EditorViewProps) { )} - - {menuKey === SiderKey.Layout && ( - - { - toggleCollisionStatus(value == true ? "true" : "false"); - editorState.setCollisionStatus(value == true ? "true" : "false"); - }} - /> - - + )} diff --git a/client/packages/lowcoder/src/pages/editor/styledComponents.tsx b/client/packages/lowcoder/src/pages/editor/styledComponents.tsx index 6df7b9d7a..2188b4ea1 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 2f102a696..1c468be88 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 Date: Sun, 4 Feb 2024 17:45:08 +0100 Subject: [PATCH 15/86] [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 8b80e30bf..938cd1fc4 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 b5ec23f09..cd57c9165 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 7ff3d6825..ac6020fd4 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 faee2cea3..5924d90bf 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; - 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>([]); const [showData, setShowData] = useState([]); - 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); }} > - +
) : ( @@ -400,7 +386,7 @@ export const LeftContent = (props: LeftContentProps) => { setShowData(newData); }} > - + ))} @@ -422,57 +408,17 @@ export const LeftContent = (props: LeftContentProps) => { ); }; - const [componentTreeData, setComponentTreeData] = useState([]); - const [modalsTreeData, setModalsTreeData] = useState([]); - - 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 ( - <> props.type && ( -
{/* Adjust the margin as needed */} - {CompStateIcon[props.type as UICompType] || } -
- )} - switcherIcon={(props: any) => props.expanded ? : } + props.type && (CompStateIcon[props.type] || )} + icon={(props: any) => props.type && (CompStateIcon[props.type as UICompType] || )} + // switcherIcon={({ expanded }: { expanded: boolean }) => + // expanded ? : + // } + switcherIcon={(props: any) => + props.expanded ? : + } 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)} + /> ); }; @@ -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 = (
@@ -604,4 +549,4 @@ export const LeftContent = (props: LeftContentProps) => { ); -}; \ 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 bba1dfbd3..9529758dd 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; } +const DropdownLeftShow = () => ( + // 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) => { {node.title} - ); }; const [componentTreeData, setComponentTreeData] = useState([]); + // 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([]); + const [actionValue, setActionValue] = useState(""); + + 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(); + 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 ( <> - +
+ {trans("leftPanel.activatelayers")} + { toggleCollisionStatus(value == true ? "true" : "false"); editorState.setCollisionStatus(value == true ? "true" : "false"); - } } /> - handleDrop(info)} - treeData={componentTreeData} - icon={(props: any) => props.type && ( -
{/* Adjust the margin as needed */} - {CompStateIcon[props.type as UICompType] || } -
- )} - switcherIcon={(props: any) => props.expanded ? : } - expandedKeys={expandedKeys} - onExpand={(keys) => setExpandedKeys(keys)} - // onClick={(e, node) => handleNodeClick(e, node, uiCompInfos)} - selectedKeys={selectedKeys} - titleRender={(nodeData) => getTreeNode(nodeData as NodeItem, uiCompInfos)} /> - -
- + } } />
+ + handleDrop(info)} + treeData={componentTreeData} + icon={(props: any) => props.type && ( +
{/* Adjust the margin as needed */} + {CompStateIcon[props.type as UICompType] || } +
+ )} + switcherIcon={(props: any) => props.expanded ? : } + expandedKeys={expandedKeys} + onExpand={(keys) => setExpandedKeys(keys)} + titleRender={(nodeData) => getTreeNode(nodeData as NodeItem, uiCompInfos)} /> + +
+ + {trans("leftPanel.selectedComponents")}
+ {trans("leftPanel.displayComponents")} + + + + +
+
+ +
+ + + ); }; @@ -313,8 +424,8 @@ export const LeftLayersContent = (props: LeftLayersContentProps) => { const layerControlContent = (
- - {uiCollapse} + +
{uiCollapse}
diff --git a/client/packages/lowcoder/src/pages/editor/editorView.tsx b/client/packages/lowcoder/src/pages/editor/editorView.tsx index 45a512214..af1981c37 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: , @@ -220,10 +221,20 @@ const items = [ }, { key: SiderKey.Layout, - icon: , + icon: , }, ]; +const aggregationSiderItems = [ + { + key: SiderKey.State, + icon: , + }, + { + key: SiderKey.Setting, + icon: , + } +]; function EditorView(props: EditorViewProps) { const { uiComp } = props; @@ -392,13 +403,15 @@ function EditorView(props: EditorViewProps) { - clickMenu(params)} > From 02c1ab338a354fe15fe69f39ee656333009dbffc Mon Sep 17 00:00:00 2001 From: RAHEEL Date: Mon, 5 Feb 2024 21:50:03 +0500 Subject: [PATCH 16/86] 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 9529758dd..05470460f 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")}
{trans("leftPanel.displayComponents")} - + ( + handleComponentsActions(key)} + /> + )} + > + setActionValue(e.target.value)} // Handle changes to update actionValue + placeholder={placeholderText} + /> + +
+ handleColorChange(params.color, "style.background")} + /> + handleColorChange(params.color, "style.border")} + /> + handleColorChange(params.color, "style.text")} + /> diff --git a/client/packages/lowcoder/src/pages/editor/styledComponents.tsx b/client/packages/lowcoder/src/pages/editor/styledComponents.tsx index 2188b4ea1..b1125d4c9 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 Date: Fri, 16 Feb 2024 16:01:51 +0500 Subject: [PATCH 38/86] 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 dd1dc85e9..947cbee09 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 Date: Fri, 16 Feb 2024 22:19:32 +0100 Subject: [PATCH 39/86] 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 9d59591a4..ec11598f7 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} >
- + + + +
); diff --git a/client/packages/lowcoder/src/comps/comps/listViewComp/listView.tsx b/client/packages/lowcoder/src/comps/comps/listViewComp/listView.tsx index b45bc755b..8234e4231 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 ( - ); } @@ -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) { - { - if (height) setListHeight(height); - }} - observerOptions={{ box: "border-box" }} - > -
{renders}
-
+ {scrollbars ? ( + + <>{ { if (height) setListHeight(height); }} observerOptions={{ box: "border-box" }} > +
{renders}
+
} +
+ ) : ( + <>{ { if (height) setListHeight(height); }} observerOptions={{ box: "border-box" }} > +
{renders}
+
} + )}
diff --git a/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx b/client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx index 947cbee09..3687df0c4 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 e18ff26ab..33d731a55 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; @@ -52,9 +53,18 @@ export function listPropertyView(compType: ListCompType) { )} + {(useContext(EditorContext).editorModeStatus === "logic" || useContext(EditorContext).editorModeStatus === "both") && ( +
+ {hiddenPropertyView(children)} +
+ )} + {(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && ( <>
{children.autoHeight.getPropertyView()} + {children.scrollbars.propertyView({ + label: trans("prop.scrollbar"), + })}
{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 5534bd43b..f48918f30 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>; @@ -121,6 +123,9 @@ class ModuleTmpComp extends ModuleCompBase { )}
{!this.autoScaleCompHeight() && this.children.autoHeight.getPropertyView()} + {this.children.scrollbars.propertyView({ + label: trans("prop.scrollbar"), + })} {hiddenPropertyView(this.children)}
@@ -525,9 +530,11 @@ const ModuleCompWithView = withViewFn(ModuleTmpComp, (comp) => { if (comp.moduleRootComp && comp.isReady) { content = ( - - {comp.moduleRootComp.getView()} - + + + {comp.moduleRootComp.getView()} + + ); } diff --git a/client/packages/lowcoder/src/comps/comps/moduleContainerComp/moduleLayoutComp.tsx b/client/packages/lowcoder/src/comps/comps/moduleContainerComp/moduleLayoutComp.tsx index a1a7db949..f3a8445ff 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 ( - {props.containerView} + + {props.containerView} + ); } @@ -94,7 +96,8 @@ function ModuleLayoutView(props: IProps) { }; return ( - + + ); } @@ -113,7 +117,8 @@ export class ModuleLayoutComp extends ModuleLayoutCompBase implements IContainer const isRowCountLocked = this.children.autoScaleCompHeight.getView(); const rowCount = this.children.containerRowCount.getView(); return ( - + + ); } getPropertyView() { diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index cd57c9165..7a8c34210 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 ac6020fd4..28194e00f 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 40/86] 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 8600472a2..000000000 --- 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 ? "" : `` - } - } - }), - 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 Date: Sat, 17 Feb 2024 14:57:55 +0300 Subject: [PATCH 41/86] 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 5c01bdc62..1101fc6d2 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, @@ -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" ? ( - props.onEvent("submit")} - $style={props.style} - /> - ) : ( - )} @@ -317,17 +282,7 @@ let AutoCompleteCompBase = (function () { .setPropertyViewFn((children) => { return ( <> -
- {children.autoCompleteType.propertyView({ - label: trans("autoComplete.type"), - radioButton: true, - })} - {children.autoCompleteType.getView() === "AntDesign" && - children.autocompleteIconColor.propertyView({ - label: trans("button.prefixIcon"), - radioButton: true, - })} - +
{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 4f5a0ba18..ca5a6648b 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(""), // user's input value when search showSearch: BoolControl.DEFAULT_TRUE, viewRef: RefControl, - 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) => ( - {originNode} + + {originNode} + )} dropdownStyle={{ padding: 0, @@ -250,8 +264,8 @@ export const SelectUIView = ( key={option.value} > - {props.options.findIndex((option) => hasIcon(option.prefixIcon)) > -1 && - option.prefixIcon} + {props.options.findIndex((option) => hasIcon(option.prefixIcon)) > + -1 && option.prefixIcon} {{option.label}} @@ -273,24 +287,28 @@ export const SelectPropertyView = ( <>
{children.options.propertyView({})} - {children.defaultValue.propertyView({ label: trans("prop.defaultValue") })} + {children.defaultValue.propertyView({ + label: trans("prop.defaultValue"), + })} {placeholderPropertyView(children)}
{["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && ( - <><> - - -
+ <> + <> + + + +
{children.onEvent.getPropertyView()} {disabledPropertyView(children)} {hiddenPropertyView(children)} -
+
+ )} - {["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && ( - children.label.getPropertyView() - )} + {["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && + children.label.getPropertyView()} {["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && (
@@ -299,7 +317,9 @@ export const SelectPropertyView = (
)} - {["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && ( + {["layout", "both"].includes( + useContext(EditorContext).editorModeStatus + ) && (
{children.style.getPropertyView()}
@@ -307,4 +327,7 @@ export const SelectPropertyView = ( ); -export const baseSelectRefMethods = refMethods([focusMethod, blurMethod]); +export const baseSelectRefMethods = refMethods([ + focusMethod, + blurMethod, +]); From 4cdbe2aa51970b009ce65b665c2b7f24bc78a848 Mon Sep 17 00:00:00 2001 From: FalkWolsky Date: Sat, 17 Feb 2024 13:03:06 +0100 Subject: [PATCH 42/86] 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 5df0cd4be..e6ba29282 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 ( - + ); }) @@ -78,6 +78,7 @@ function convertOldContainerParams(params: CompParams) { // 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) { 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 45d8f7d26..d7ee0e421 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 ec11598f7..545608daa 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} >
- + {/* */} - - - - + + + {/* */}
); diff --git a/client/packages/lowcoder/src/comps/comps/listViewComp/listViewPropertyView.tsx b/client/packages/lowcoder/src/comps/comps/listViewComp/listViewPropertyView.tsx index 33d731a55..5d2c5dc0a 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") && ( <>
{children.autoHeight.getPropertyView()} - {children.scrollbars.propertyView({ - label: trans("prop.scrollbar"), - })} + {!children.autoHeight.getView() && + children.scrollbars.propertyView({ + label: trans("prop.scrollbar"), + } + )}
{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 eea06d569..d1d57401a 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 && ( - + {scrollbars ? ( + + + + ) : ( + + )} )} {showFooter && ( diff --git a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx index 87380c628..26f8dea38 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 Date: Sat, 17 Feb 2024 13:52:10 +0100 Subject: [PATCH 43/86] 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 26f8dea38..c32ba3d2e 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 5dea81d30..a9749121f 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 5924d90bf..8188685d1 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) => { props.type && (CompStateIcon[props.type] || )} - icon={(props: any) => props.type && (CompStateIcon[props.type as UICompType] || )} + icon={(props: any) => props.type && ( +
+ {CompStateIcon[props.type as UICompType] || } +
+ )} // switcherIcon={({ expanded }: { expanded: boolean }) => // expanded ? : // } diff --git a/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx b/client/packages/lowcoder/src/pages/editor/LeftLayersContent.tsx index 9fd7e6804..93a66fc44 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 && ( -
{/* Adjust the margin as needed */} +
{CompStateIcon[props.type as UICompType] || }
)} From 0886f58f394e2d7c1bdd5dc8a1bf2058fff5ecfd Mon Sep 17 00:00:00 2001 From: Imtanan Aziz Toor Date: Sat, 17 Feb 2024 23:32:19 +0500 Subject: [PATCH 44/86] 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 7114a019b..0f60c7a2d 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 f58b39bd6..7c2278d7b 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 275b125b3..65b288bac 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 e830a6f41..032807de2 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)` +const StyledDivider = styled(Divider) ` margin-top: 3.5px; .ant-divider-inner-text { height: 32px; @@ -30,16 +30,17 @@ const StyledDivider = styled(Divider)` 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 fb6d4609b..c5eedea6f 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")>` +const Wrapper = styled("div") >` 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")>` +const NavInner = styled("div") >` 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)` +const StyledMenu = styled(Menu) ` &.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 ( - + {props.logoUrl && ( props.logoEvent("click")}> @@ -220,7 +237,7 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
)} - {(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && ( + {(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && (
{children.style.getPropertyView()}
diff --git a/client/packages/lowcoder/src/comps/comps/textInputComp/mentionComp.tsx b/client/packages/lowcoder/src/comps/comps/textInputComp/mentionComp.tsx index 630f7e376..28051a067 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("@"); 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} /> @@ -222,12 +222,12 @@ let MentionTmpComp = (function () { )} {["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && ( - <>
+ <>
{children.onEvent.getPropertyView()} {disabledPropertyView(children)}
-
{hiddenPropertyView(children)}
-
+
{hiddenPropertyView(children)}
+
{readOnlyPropertyView(children)}
{requiredPropertyView(children)} @@ -241,9 +241,9 @@ let MentionTmpComp = (function () { )} {["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && ( - <>
- {children.style.getPropertyView()} -
+ <>
+ {children.style.getPropertyView()} +
)} )) diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx index c01fc0d0b..86189ba5a 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 Date: Sun, 18 Feb 2024 12:03:53 +0700 Subject: [PATCH 45/86] 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 literal 0 HcmV?d00001 literal 8196 zcmeHMPfrs;6n|4{yA@4{(S(C08$9R%E1(Iemr`025`lz8IHPg@HX*;`ZJrP5~OtbT5=l$NBH^07_?Q8*nWE;*T zz$gG1criILj8&h)^z7;>G1)VQlAt}f8 zL>@7SFvosV;xbaUgcRmLH^5I#EkH#r6$sSx zd+IR#M%7hmE@!*c#y%tU{?q=K&Cj!8z4K3ft=xS#kowA8L$W{0{Gz~Pi1?|}ZX|hTa?Wg9Ve?J@;f28=0Yz|; zw-R^|M6e(Jg|(Z0P5M2wYi`94CMLd<*iigbB55RzVdIfircEm-1Pwo1s6SwLE0nr+ zyIrtXE2ZZ8$oVAGj2}L z?2VhdlM^?l#?4zdr}y?!#)Zq*?<}uxxmAz8Y=!3U_(j*o7@0vx z@dPz}728(bbE&t12ExceCTqwjg`F^)s!D&6=^LckQf6KnT;# znL(IP#>5YB7+g6HMq30w5-(#%jkkkSV@*CQR8=2pocBvtD>Az~wrXDY)2s0%_dl}u zPUFfdK^6R)+F46d6~B3j%<3kz0Y z3CF2|6S4aiu}i@+;%6a;_W6Dme6_s|tu~*}Wt-Ju@4!~uK&;9+`T6=eViUN&886(I z%KOEqx7)l&Fx~tZgi-mAo%@Bu;A>UBkKn#ihijPI?3>uck&6)EoW*^OM-uRTB$`Jo z@6~xRpSoxUj)s9D;bxSb|MP?2{~yg@+KXmDGjJ>!An}})%VKElAA8X#*;(7f>oH!e sFkDMWZh{qquzr3VN7?zq5Zk8IWu$Bgi5e{b{Y8L&{&U`Sb+Q@w3n?6 Date: Mon, 19 Feb 2024 12:45:20 +0300 Subject: [PATCH 46/86] 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 1101fc6d2..059dd3852 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 () { }, }} > - { 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 () { ), - style: props.style, - ...validateState, + // style: props.style, + // ...validateState, }); }) .setPropertyViewFn((children) => { From 18959b99ccdde7327fbcb4f1be34fb8ef85ebfe0 Mon Sep 17 00:00:00 2001 From: FalkWolsky Date: Mon, 19 Feb 2024 12:59:05 +0100 Subject: [PATCH 47/86] 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 7a8c34210..74b2296b9 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 Date: Mon, 19 Feb 2024 18:58:47 +0500 Subject: [PATCH 48/86] 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 4279ed654..828b8f286 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 0058ff71f..6b697c0c0 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 { // 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 ( { >
{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 Date: Mon, 19 Feb 2024 21:22:20 +0100 Subject: [PATCH 49/86] 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 49139eb39..96f0055ae 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 Date: Tue, 20 Feb 2024 16:37:17 +0500 Subject: [PATCH 50/86] 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 31ed40e58..7c1396a39 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> { return Api.post(OrgApi.createGroupURL, request); @@ -127,6 +132,10 @@ export class OrgApi extends Api { static updateOrg(request: UpdateOrgPayload): AxiosPromise { return Api.put(OrgApi.updateOrgURL(request.id), request); } + + static fetchAPIUsage(orgId: string, lastMonthOnly?: boolean): AxiosPromise { + 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 7b2b28442..fdf34040b 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 e77bb1450..9cfa2b235 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 2d35b7e0c..f020cf99f 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 + ): 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 d7326c1d7..9d2f3eb6a 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 8835a2f3f..f1604241d 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) { } } +export function* fetchAPIUsageSaga(action: ReduxAction<{ + orgId: string, + lastMonthOnly?: boolean, +}>) { + try { + const response: AxiosResponse = 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 281ff138b..8ea9aa3ec 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 Date: Tue, 20 Feb 2024 17:50:59 +0500 Subject: [PATCH 51/86] 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 65b288bac..1d41ad334 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)}
-
- {children.prefixIcon.propertyView({ label: trans("button.prefixIcon") })} - {children.suffixIcon.propertyView({ label: trans("button.suffixIcon") })} -
+
+ {children.prefixIcon.propertyView({ label: trans("button.prefixIcon") })} + {children.suffixIcon.propertyView({ label: trans("button.suffixIcon") })} +
)} - {(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && ( - <>
{children.style.getPropertyView()}
- )} + {(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && ( + <>
{children.style.getPropertyView()}
+ )} ); }) diff --git a/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx b/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx index f1c917521..26fb58169 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({})}
-
- {children.onEvent.getPropertyView()} - {disabledPropertyView(children)} - {hiddenPropertyView(children)} -
+
+ {children.onEvent.getPropertyView()} + {disabledPropertyView(children)} + {hiddenPropertyView(children)} +
)} - - {(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 86189ba5a..347c7ede3 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 Date: Tue, 20 Feb 2024 21:44:11 +0100 Subject: [PATCH 52/86] 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 96f0055ae..fe9a6503a 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 ( @@ -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} /> From 878dfaacbcddfcfe1d0e1dd31d0892e98ccaa73f Mon Sep 17 00:00:00 2001 From: FalkWolsky Date: Tue, 20 Feb 2024 22:09:59 +0100 Subject: [PATCH 53/86] 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 74b2296b9..287603466 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 28194e00f..e0634a234 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 2286a21497813eaccca99ac7154a81f3a46e97d1 Mon Sep 17 00:00:00 2001 From: FalkWolsky Date: Wed, 21 Feb 2024 12:43:52 +0100 Subject: [PATCH 54/86] 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 fccf0fff1..92d3afa24 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 ac3264aa2..7ffc8cc72 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 = {}; 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 662c4b0ed..1eee6b5e2 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 1e8e50789..addc573f8 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 072eec5e9..aebaae3bf 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 548e5b874..baff44425 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 Date: Wed, 21 Feb 2024 18:37:30 +0500 Subject: [PATCH 55/86] 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 41ee23204..06659a441 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 { 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 fdf34040b..ae7ebf129 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 7938543a4..dda424c1f 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 + ): 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 12697e352..7619798d6 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 c49644182..6967c3c14 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> = 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 3279f65c6..2d888a9c9 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 Date: Wed, 21 Feb 2024 18:39:52 +0500 Subject: [PATCH 56/86] 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 b86282d80..37ec80ab6 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 (
+ + { + 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'} + /> + = { [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 Date: Wed, 21 Feb 2024 18:41:38 +0500 Subject: [PATCH 57/86] 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 8435068e1..e56d475c9 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 @@ - + @@ -11,6 +11,6 @@ - + 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 000000000..6db0975e5 --- /dev/null +++ b/client/packages/lowcoder-design/src/icons/icon-application-marketplace-active.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ 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 000000000..417513063 --- /dev/null +++ b/client/packages/lowcoder-design/src/icons/icon-application-marketplace.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ 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 938cd1fc4..e9d141765 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 0e25e3a52..8b3a944f7 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 { 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 8b7abb5ee..1c21036ab 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 b30fead70..defca3530 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 74b2296b9..9d59f83df 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 28194e00f..b2df346d3 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 000000000..d518250d1 --- /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(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 ( + + ); +}; \ 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 7e24d5eee..a9525298b 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: {trans("home.marketplace")}, + routePath: MARKETPLACE_URL, + routePathExact: false, + routeComp: MarketplaceView, + icon: ({ selected, ...otherProps }) => + selected ? ( + + ) : ( + + ), + visible: ({ user }) => user.orgDev, + }, { text: {trans("settings.title")}, routePath: SETTING, From 606a9d17d797b8be35659decf27ac2cd2d156679 Mon Sep 17 00:00:00 2001 From: RAHEEL Date: Wed, 21 Feb 2024 18:42:44 +0500 Subject: [PATCH 58/86] 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 fde596953..b18b944f7 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 && ( )} @@ -421,11 +423,13 @@ export function HomeLayout(props: HomeLayoutProps) {
{mode === "trash" ? trans("home.trashEmpty") + : mode === "marketplace" + ? "No apps in marketplace yet" : user.orgDev ? trans("home.projectEmptyCanAdd") : trans("home.projectEmpty")}
- {mode !== "trash" && user.orgDev && } + {mode !== "trash" && mode !== "marketplace" && user.orgDev && } )} diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx index 26c97eb30..32e2258ed 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 )} { + 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 4a76939ee..aa767250c 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 eefa27800..1ea283690 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: {trans("header.editName")}, + visible: isEditable, + }, + { + key: "export", + label: {trans("header.export")}, + visible: true, + }, + { + key: "duplicate", + label: ( + + {trans("header.duplicate", { + type: TypeName[application?.applicationType!]?.toLowerCase(), + })} + + ), + visible: true, + }, + { + key: "delete", + label: {trans("home.moveToTrash")}, + visible: isEditable, + }, + ]), [isEditable]); + return ( <> void }) { }); } }} - items={[ - { - key: "edit", - label: {trans("header.editName")}, - }, - { - key: "export", - label: {trans("header.export")}, - }, - { - key: "duplicate", - label: ( - - {trans("header.duplicate", { - type: TypeName[application?.applicationType!]?.toLowerCase(), - })} - - ), - }, - { - key: "delete", - label: {trans("home.moveToTrash")}, - }, - ]} + 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 507330cbf..85ae198d6 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(); 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 = ( <> history.push(ALL_APPLICATIONS_URL)}> - - {application && application.name} - + {isViewMarketplaceMode && ( + { + + }} + /> + )} + {!isViewMarketplaceMode && ( + + {application && application.name} + + )} ); diff --git a/client/packages/lowcoder/src/pages/editor/AppEditor.tsx b/client/packages/lowcoder/src/pages/editor/AppEditor.tsx index 05d5c4a08..c1d241a0a 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(); 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 2c37817d9..8f7e1dfe8 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 67e397184..ca67a902f 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 Date: Wed, 21 Feb 2024 18:49:34 +0500 Subject: [PATCH 59/86] 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 6c82fd62b..156c83799 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 7c4fdc126..c69c35605 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 Date: Wed, 21 Feb 2024 20:21:33 +0500 Subject: [PATCH 60/86] 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 1acf7f2d6..76c5f4aef 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 347c7ede3..9c45f893a 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 Date: Thu, 22 Feb 2024 09:15:45 +0100 Subject: [PATCH 61/86] 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 7c74d491a..15f56dc46 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 1bf1dae92..43386ccf9 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 Date: Thu, 22 Feb 2024 13:28:18 +0500 Subject: [PATCH 62/86] 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 1d41ad334..cbd5b26b2 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 c5eedea6f..44b782b47 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") >` +const Wrapper = styled("div") >` 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") >` - 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} > {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 28051a067..c760e054b 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} /> diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx index 9c45f893a..bd895a961 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 Date: Thu, 22 Feb 2024 13:34:24 +0500 Subject: [PATCH 63/86] 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 0f60c7a2d..e770014f7 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 Date: Thu, 22 Feb 2024 15:22:18 +0500 Subject: [PATCH 64/86] 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 c83e225aa..038b31c38 100644 --- a/client/packages/lowcoder/index.html +++ b/client/packages/lowcoder/index.html @@ -7,6 +7,10 @@ + + + +