Skip to content

Commit 982f98b

Browse files
added dropdown in app settings to change lowcoder-comps version
1 parent 0e2b3cc commit 982f98b

File tree

2 files changed

+62
-9
lines changed

2 files changed

+62
-9
lines changed

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

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { dropdownInputSimpleControl } from "comps/controls/dropdownInputSimpleCo
44
import { MultiCompBuilder, valueComp, withDefault } from "comps/generators";
55
import { AddIcon, Dropdown } from "lowcoder-design";
66
import { EllipsisSpan } from "pages/setting/theme/styledComponents";
7-
import { useEffect } from "react";
7+
import { useEffect, useState } from "react";
88
import { useSelector } from "react-redux";
99
import { getDefaultTheme, getThemeList } from "redux/selectors/commonSettingSelectors";
1010
import styled, { css } from "styled-components";
@@ -19,6 +19,8 @@ import { IconControl } from "comps/controls/iconControl";
1919
import { dropdownControl } from "comps/controls/dropdownControl";
2020
import { ApplicationCategoriesEnum } from "constants/applicationConstants";
2121
import { BoolControl } from "../controls/boolControl";
22+
import { getNpmPackageMeta } from "../utils/remote";
23+
import { getPromiseAfterDispatch } from "@lowcoder-ee/util/promiseUtils";
2224

2325
const TITLE = trans("appSetting.title");
2426
const USER_DEFINE = "__USER_DEFINE";
@@ -189,13 +191,15 @@ const childrenMap = {
189191
preventAppStylesOverwriting: withDefault(BoolControl, true),
190192
customShortcuts: CustomShortcutsComp,
191193
disableCollision: valueComp<boolean>(false),
194+
lowcoderCompVersion: withDefault(StringControl, 'latest'),
192195
};
193196
type ChildrenInstance = RecordConstructorToComp<typeof childrenMap> & {
194197
themeList: ThemeType[];
195198
defaultTheme: string;
196199
};
197200

198201
function AppSettingsModal(props: ChildrenInstance) {
202+
const [lowcoderCompVersions, setLowcoderCompVersions] = useState(['latest']);
199203
const {
200204
themeList,
201205
defaultTheme,
@@ -207,11 +211,14 @@ function AppSettingsModal(props: ChildrenInstance) {
207211
category,
208212
showHeaderInPublic,
209213
preventAppStylesOverwriting,
214+
lowcoderCompVersion,
210215
} = props;
216+
211217
const THEME_OPTIONS = themeList?.map((theme) => ({
212218
label: theme.name,
213219
value: theme.id + "",
214220
}));
221+
215222
const themeWithDefault = (
216223
themeId.getView() === DEFAULT_THEMEID ||
217224
(!!themeId.getView() &&
@@ -225,6 +232,17 @@ function AppSettingsModal(props: ChildrenInstance) {
225232
themeId.dispatchChangeValueAction(themeWithDefault);
226233
}
227234
}, [themeWithDefault]);
235+
236+
useEffect(() => {
237+
const fetchCompsPackageMeta = async () => {
238+
const packageMeta = await getNpmPackageMeta('lowcoder-comps');
239+
if (packageMeta?.versions) {
240+
setLowcoderCompVersions(Object.keys(packageMeta.versions).reverse())
241+
}
242+
}
243+
fetchCompsPackageMeta();
244+
}, [])
245+
228246

229247
const DropdownItem = (params: { value: string }) => {
230248
const themeItem = themeList.find((theme) => theme.id === params.value);
@@ -308,6 +326,31 @@ function AppSettingsModal(props: ChildrenInstance) {
308326
})}
309327
</div>
310328
</DivStyled>
329+
<DividerStyled />
330+
<DivStyled>
331+
<Dropdown
332+
defaultValue={lowcoderCompVersion.getView()}
333+
placeholder={'Select version'}
334+
options={
335+
lowcoderCompVersions.map(version => ({label: version, value: version}))
336+
}
337+
label={'Lowcoder Comps Version'}
338+
placement="bottom"
339+
allowClear
340+
onChange={async (value) => {
341+
await getPromiseAfterDispatch(
342+
lowcoderCompVersion.dispatch,
343+
lowcoderCompVersion.changeValueAction(value), {
344+
autoHandleAfterReduce: true,
345+
}
346+
)
347+
setTimeout(() => {
348+
window.location.reload();
349+
}, 1000);
350+
}}
351+
/>
352+
</DivStyled>
353+
<DividerStyled />
311354
{props.customShortcuts.getPropertyView()}
312355
</SettingsStyled>
313356
);

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

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ import { GreyTextColor } from "constants/style";
55
import log from "loglevel";
66
import { Comp, CompAction, CompParams, customAction, isCustomAction } from "lowcoder-core";
77
import { WhiteLoading } from "lowcoder-design";
8-
import { useState } from "react";
8+
import { useContext, useState } from "react";
99
import { useMount } from "react-use";
1010
import styled from "styled-components";
1111
import { RemoteCompInfo, RemoteCompLoader } from "types/remoteComp";
1212
import { loaders } from "./loaders";
1313
import { withErrorBoundary } from "comps/generators/withErrorBoundary";
14+
import { EditorContext } from "@lowcoder-ee/comps/editorState";
1415

1516
const ViewError = styled.div`
1617
display: flex;
@@ -45,18 +46,22 @@ interface RemoteCompReadyAction {
4546
}
4647

4748
interface RemoteCompViewProps {
48-
loadComp: () => Promise<void>;
49+
isLowcoderComp?: boolean;
50+
loadComp: (packageVersion?: string) => Promise<void>;
4951
loadingElement?: () => React.ReactNode;
5052
errorElement?: (error: any) => React.ReactNode;
5153
}
5254

5355
function RemoteCompView(props: React.PropsWithChildren<RemoteCompViewProps>) {
54-
const { loadComp, loadingElement, errorElement } = props;
56+
const { loadComp, loadingElement, errorElement, isLowcoderComp } = props;
5557
const [error, setError] = useState<any>("");
56-
58+
const editorState = useContext(EditorContext);
59+
const lowcoderCompPackageVersion = editorState?.getAppSettings().lowcoderCompVersion || 'latest';
60+
const packageVersion = isLowcoderComp ? lowcoderCompPackageVersion : 'latest';
61+
5762
useMount(() => {
5863
setError("");
59-
loadComp().catch((e) => {
64+
loadComp(packageVersion).catch((e) => {
6065
setError(String(e));
6166
});
6267
});
@@ -96,7 +101,7 @@ export function remoteComp<T extends RemoteCompInfo = RemoteCompInfo>(
96101
this.compValue = params.value;
97102
}
98103

99-
private async load() {
104+
private async load(packageVersion = 'latest') {
100105
if (!remoteInfo) {
101106
return;
102107
}
@@ -108,7 +113,7 @@ export function remoteComp<T extends RemoteCompInfo = RemoteCompInfo>(
108113
log.error("loader not found, remote info:", remoteInfo);
109114
return;
110115
}
111-
const RemoteExportedComp = await finalLoader(remoteInfo);
116+
const RemoteExportedComp = await finalLoader({...remoteInfo, packageVersion});
112117
if (!RemoteExportedComp) {
113118
return;
114119
}
@@ -135,7 +140,12 @@ export function remoteComp<T extends RemoteCompInfo = RemoteCompInfo>(
135140
getView() {
136141
const key = `${remoteInfo?.packageName}-${remoteInfo?.packageVersion}-${remoteInfo?.compName}`;
137142
return (
138-
<RemoteCompView key={key} loadComp={() => this.load()} loadingElement={loadingElement} />
143+
<RemoteCompView
144+
key={key}
145+
isLowcoderComp={remoteInfo?.packageName === 'lowcoder-comps'}
146+
loadComp={(packageVersion?: string) => this.load(packageVersion)}
147+
loadingElement={loadingElement}
148+
/>
139149
);
140150
}
141151

0 commit comments

Comments
 (0)