From 982f98be195087252d43175a7cf2006a209f57f7 Mon Sep 17 00:00:00 2001 From: RAHEEL Date: Tue, 16 Jul 2024 18:34:45 +0500 Subject: [PATCH 1/3] added dropdown in app settings to change lowcoder-comps version --- .../src/comps/comps/appSettingsComp.tsx | 45 ++++++++++++++++++- .../src/comps/comps/remoteComp/remoteComp.tsx | 26 +++++++---- 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/appSettingsComp.tsx b/client/packages/lowcoder/src/comps/comps/appSettingsComp.tsx index d4de3b59f..1f8016ced 100644 --- a/client/packages/lowcoder/src/comps/comps/appSettingsComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/appSettingsComp.tsx @@ -4,7 +4,7 @@ import { dropdownInputSimpleControl } from "comps/controls/dropdownInputSimpleCo import { MultiCompBuilder, valueComp, withDefault } from "comps/generators"; import { AddIcon, Dropdown } from "lowcoder-design"; import { EllipsisSpan } from "pages/setting/theme/styledComponents"; -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import { useSelector } from "react-redux"; import { getDefaultTheme, getThemeList } from "redux/selectors/commonSettingSelectors"; import styled, { css } from "styled-components"; @@ -19,6 +19,8 @@ import { IconControl } from "comps/controls/iconControl"; import { dropdownControl } from "comps/controls/dropdownControl"; import { ApplicationCategoriesEnum } from "constants/applicationConstants"; import { BoolControl } from "../controls/boolControl"; +import { getNpmPackageMeta } from "../utils/remote"; +import { getPromiseAfterDispatch } from "@lowcoder-ee/util/promiseUtils"; const TITLE = trans("appSetting.title"); const USER_DEFINE = "__USER_DEFINE"; @@ -189,6 +191,7 @@ const childrenMap = { preventAppStylesOverwriting: withDefault(BoolControl, true), customShortcuts: CustomShortcutsComp, disableCollision: valueComp(false), + lowcoderCompVersion: withDefault(StringControl, 'latest'), }; type ChildrenInstance = RecordConstructorToComp & { themeList: ThemeType[]; @@ -196,6 +199,7 @@ type ChildrenInstance = RecordConstructorToComp & { }; function AppSettingsModal(props: ChildrenInstance) { + const [lowcoderCompVersions, setLowcoderCompVersions] = useState(['latest']); const { themeList, defaultTheme, @@ -207,11 +211,14 @@ function AppSettingsModal(props: ChildrenInstance) { category, showHeaderInPublic, preventAppStylesOverwriting, + lowcoderCompVersion, } = props; + const THEME_OPTIONS = themeList?.map((theme) => ({ label: theme.name, value: theme.id + "", })); + const themeWithDefault = ( themeId.getView() === DEFAULT_THEMEID || (!!themeId.getView() && @@ -225,6 +232,17 @@ function AppSettingsModal(props: ChildrenInstance) { themeId.dispatchChangeValueAction(themeWithDefault); } }, [themeWithDefault]); + + useEffect(() => { + const fetchCompsPackageMeta = async () => { + const packageMeta = await getNpmPackageMeta('lowcoder-comps'); + if (packageMeta?.versions) { + setLowcoderCompVersions(Object.keys(packageMeta.versions).reverse()) + } + } + fetchCompsPackageMeta(); + }, []) + const DropdownItem = (params: { value: string }) => { const themeItem = themeList.find((theme) => theme.id === params.value); @@ -308,6 +326,31 @@ function AppSettingsModal(props: ChildrenInstance) { })} + + + ({label: version, value: version})) + } + label={'Lowcoder Comps Version'} + placement="bottom" + allowClear + onChange={async (value) => { + await getPromiseAfterDispatch( + lowcoderCompVersion.dispatch, + lowcoderCompVersion.changeValueAction(value), { + autoHandleAfterReduce: true, + } + ) + setTimeout(() => { + window.location.reload(); + }, 1000); + }} + /> + + {props.customShortcuts.getPropertyView()} ); diff --git a/client/packages/lowcoder/src/comps/comps/remoteComp/remoteComp.tsx b/client/packages/lowcoder/src/comps/comps/remoteComp/remoteComp.tsx index be0f9aae2..64f018582 100644 --- a/client/packages/lowcoder/src/comps/comps/remoteComp/remoteComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/remoteComp/remoteComp.tsx @@ -5,12 +5,13 @@ import { GreyTextColor } from "constants/style"; import log from "loglevel"; import { Comp, CompAction, CompParams, customAction, isCustomAction } from "lowcoder-core"; import { WhiteLoading } from "lowcoder-design"; -import { useState } from "react"; +import { useContext, useState } from "react"; import { useMount } from "react-use"; import styled from "styled-components"; import { RemoteCompInfo, RemoteCompLoader } from "types/remoteComp"; import { loaders } from "./loaders"; import { withErrorBoundary } from "comps/generators/withErrorBoundary"; +import { EditorContext } from "@lowcoder-ee/comps/editorState"; const ViewError = styled.div` display: flex; @@ -45,18 +46,22 @@ interface RemoteCompReadyAction { } interface RemoteCompViewProps { - loadComp: () => Promise; + isLowcoderComp?: boolean; + loadComp: (packageVersion?: string) => Promise; loadingElement?: () => React.ReactNode; errorElement?: (error: any) => React.ReactNode; } function RemoteCompView(props: React.PropsWithChildren) { - const { loadComp, loadingElement, errorElement } = props; + const { loadComp, loadingElement, errorElement, isLowcoderComp } = props; const [error, setError] = useState(""); - + const editorState = useContext(EditorContext); + const lowcoderCompPackageVersion = editorState?.getAppSettings().lowcoderCompVersion || 'latest'; + const packageVersion = isLowcoderComp ? lowcoderCompPackageVersion : 'latest'; + useMount(() => { setError(""); - loadComp().catch((e) => { + loadComp(packageVersion).catch((e) => { setError(String(e)); }); }); @@ -96,7 +101,7 @@ export function remoteComp( this.compValue = params.value; } - private async load() { + private async load(packageVersion = 'latest') { if (!remoteInfo) { return; } @@ -108,7 +113,7 @@ export function remoteComp( log.error("loader not found, remote info:", remoteInfo); return; } - const RemoteExportedComp = await finalLoader(remoteInfo); + const RemoteExportedComp = await finalLoader({...remoteInfo, packageVersion}); if (!RemoteExportedComp) { return; } @@ -135,7 +140,12 @@ export function remoteComp( getView() { const key = `${remoteInfo?.packageName}-${remoteInfo?.packageVersion}-${remoteInfo?.compName}`; return ( - this.load()} loadingElement={loadingElement} /> + this.load(packageVersion)} + loadingElement={loadingElement} + /> ); } From 868faf540a258766ecf5b8fd01e1c74b1da2de29 Mon Sep 17 00:00:00 2001 From: RAHEEL Date: Wed, 17 Jul 2024 23:57:40 +0500 Subject: [PATCH 2/3] add version change dropdown for comp plugins --- .../lowcoder/src/components/CompName.tsx | 10 ++-- .../src/comps/comps/appSettingsComp.tsx | 1 - .../src/comps/comps/remoteComp/remoteComp.tsx | 15 ++++- .../src/comps/generators/uiCompBuilder.tsx | 59 ++++++++++++++++++- client/packages/lowcoder/src/comps/index.tsx | 6 ++ .../src/constants/compPluginConstants.ts | 8 +++ 6 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 client/packages/lowcoder/src/constants/compPluginConstants.ts diff --git a/client/packages/lowcoder/src/components/CompName.tsx b/client/packages/lowcoder/src/components/CompName.tsx index b350cf746..0e11d10e2 100644 --- a/client/packages/lowcoder/src/components/CompName.tsx +++ b/client/packages/lowcoder/src/components/CompName.tsx @@ -121,12 +121,12 @@ export const CompName = (props: Iprops) => { onClick: () => { }, }); - items.push({ - text: trans("history.currentVersion") + ": " + compInfo.packageVersion, - onClick: () => { + // items.push({ + // text: trans("history.currentVersion") + ": " + compInfo.packageVersion, + // onClick: () => { - }, - }); + // }, + // }); items.push({ text: trans("comp.menuUpgradeToLatest"), diff --git a/client/packages/lowcoder/src/comps/comps/appSettingsComp.tsx b/client/packages/lowcoder/src/comps/comps/appSettingsComp.tsx index 1f8016ced..667c2b9ae 100644 --- a/client/packages/lowcoder/src/comps/comps/appSettingsComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/appSettingsComp.tsx @@ -336,7 +336,6 @@ function AppSettingsModal(props: ChildrenInstance) { } label={'Lowcoder Comps Version'} placement="bottom" - allowClear onChange={async (value) => { await getPromiseAfterDispatch( lowcoderCompVersion.dispatch, diff --git a/client/packages/lowcoder/src/comps/comps/remoteComp/remoteComp.tsx b/client/packages/lowcoder/src/comps/comps/remoteComp/remoteComp.tsx index 64f018582..ce3611793 100644 --- a/client/packages/lowcoder/src/comps/comps/remoteComp/remoteComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/remoteComp/remoteComp.tsx @@ -12,6 +12,7 @@ import { RemoteCompInfo, RemoteCompLoader } from "types/remoteComp"; import { loaders } from "./loaders"; import { withErrorBoundary } from "comps/generators/withErrorBoundary"; import { EditorContext } from "@lowcoder-ee/comps/editorState"; +import { CompContext } from "@lowcoder-ee/comps/utils/compContext"; const ViewError = styled.div` display: flex; @@ -56,9 +57,19 @@ function RemoteCompView(props: React.PropsWithChildren) { const { loadComp, loadingElement, errorElement, isLowcoderComp } = props; const [error, setError] = useState(""); const editorState = useContext(EditorContext); + const compState = useContext(CompContext); const lowcoderCompPackageVersion = editorState?.getAppSettings().lowcoderCompVersion || 'latest'; - const packageVersion = isLowcoderComp ? lowcoderCompPackageVersion : 'latest'; - + + let packageVersion = 'latest'; + // lowcoder-comps's package version + if (isLowcoderComp) { + packageVersion = lowcoderCompPackageVersion; + } + // component plugin's package version + else if (compState.comp?.comp.version) { + packageVersion = compState.comp?.comp.version; + } + useMount(() => { setError(""); loadComp(packageVersion).catch((e) => { diff --git a/client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx b/client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx index 559f93945..cbfea61ef 100644 --- a/client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx +++ b/client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx @@ -1,5 +1,5 @@ import { BoolCodeControl, StringControl } from "comps/controls/codeControl"; -import React, { ReactNode, useContext, useRef } from "react"; +import React, { ReactNode, useContext, useEffect, useRef, useState } from "react"; import { ExternalEditorContext } from "util/context/ExternalEditorContext"; import { Comp, CompParams, MultiBaseComp } from "lowcoder-core"; import { @@ -22,10 +22,17 @@ import { MethodConfigsType, withMethodExposing, } from "./withMethodExposing"; -import { Section } from "lowcoder-design"; +import {Section, controlItem } from "lowcoder-design"; import { trans } from "i18n"; import { BoolControl } from "../controls/boolControl"; import { valueComp, withDefault } from "./simpleGenerators"; +import { getPromiseAfterDispatch } from "@lowcoder-ee/util/promiseUtils"; +import { EditorContext } from "../editorState"; +import { values } from "lodash"; +import { UICompType, uiCompRegistry } from "../uiCompRegistry"; +import { getNpmPackageMeta } from "../utils/remote"; +import { compPluginsList } from "constants/compPluginConstants"; +import Select from "antd/es/select"; export type NewChildren>> = ChildrenCompMap & { @@ -33,6 +40,7 @@ export type NewChildren>> = className: InstanceType; dataTestId: InstanceType; preventStyleOverwriting: InstanceType; + version: InstanceType; }; export function HidableView(props: { @@ -64,6 +72,28 @@ export function ExtendedPropertyView< childrenMap: NewChildren } ) { + const [compVersions, setCompVersions] = useState(['latest']); + const [compName, setCompName] = useState(''); + const editorState = useContext(EditorContext); + const selectedComp = values(editorState.selectedComps())[0]; + const compType = selectedComp.children.compType.getView() as UICompType; + + useEffect(() => { + setCompName(uiCompRegistry[compType].compName || ''); + }, [compType]); + + useEffect(() => { + const fetchCompsPackageMeta = async () => { + const packageMeta = await getNpmPackageMeta(compName); + if (packageMeta?.versions) { + setCompVersions(Object.keys(packageMeta.versions).reverse()) + } + } + if (Boolean(compName) && compPluginsList.includes(compName)) { + fetchCompsPackageMeta(); + } + }, [compName]); + return ( <> {props.children} @@ -72,6 +102,30 @@ export function ExtendedPropertyView< {props.childrenMap.dataTestId?.propertyView({ label: trans("prop.dataTestId") })} {props.childrenMap.preventStyleOverwriting?.propertyView({ label: trans("prop.preventOverwriting") })} + {compPluginsList.includes(compName) && ( +
+ {controlItem({}, ( +