Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 81665b4

Browse files
Merge pull request #1047 from lowcoder-org/lowcoder-comps-version-switch
Added version switch dropdown for Lowcoder comps and comp plugins
2 parents d67b991 + f905f49 commit 81665b4

File tree

6 files changed

+147
-15
lines changed

6 files changed

+147
-15
lines changed

‎client/packages/lowcoder/src/components/CompName.tsx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,12 @@ export const CompName = (props: Iprops) => {
121121
onClick: () => {
122122
},
123123
});
124-
items.push({
125-
text: trans("history.currentVersion") + ": " + compInfo.packageVersion,
126-
onClick: () => {
124+
// items.push({
125+
// text: trans("history.currentVersion") + ": " + compInfo.packageVersion,
126+
// onClick: () => {
127127

128-
},
129-
});
128+
// },
129+
// });
130130

131131
items.push({
132132
text: trans("comp.menuUpgradeToLatest"),

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

Lines changed: 43 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,30 @@ 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+
onChange={async (value) => {
340+
await getPromiseAfterDispatch(
341+
lowcoderCompVersion.dispatch,
342+
lowcoderCompVersion.changeValueAction(value), {
343+
autoHandleAfterReduce: true,
344+
}
345+
)
346+
setTimeout(() => {
347+
window.location.reload();
348+
}, 1000);
349+
}}
350+
/>
351+
</DivStyled>
352+
<DividerStyled />
311353
{props.customShortcuts.getPropertyView()}
312354
</SettingsStyled>
313355
);

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

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ 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";
15+
import { CompContext } from "@lowcoder-ee/comps/utils/compContext";
1416

1517
const ViewError = styled.div`
1618
display: flex;
@@ -45,18 +47,32 @@ interface RemoteCompReadyAction {
4547
}
4648

4749
interface RemoteCompViewProps {
48-
loadComp: () => Promise<void>;
50+
isLowcoderComp?: boolean;
51+
loadComp: (packageVersion?: string) => Promise<void>;
4952
loadingElement?: () => React.ReactNode;
5053
errorElement?: (error: any) => React.ReactNode;
5154
}
5255

5356
function RemoteCompView(props: React.PropsWithChildren<RemoteCompViewProps>) {
54-
const { loadComp, loadingElement, errorElement } = props;
57+
const { loadComp, loadingElement, errorElement, isLowcoderComp } = props;
5558
const [error, setError] = useState<any>("");
59+
const editorState = useContext(EditorContext);
60+
const compState = useContext(CompContext);
61+
const lowcoderCompPackageVersion = editorState?.getAppSettings().lowcoderCompVersion || 'latest';
62+
63+
let packageVersion = 'latest';
64+
// lowcoder-comps's package version
65+
if (isLowcoderComp) {
66+
packageVersion = lowcoderCompPackageVersion;
67+
}
68+
// component plugin's package version
69+
else if (compState.comp?.comp?.version) {
70+
packageVersion = compState.comp?.comp.version;
71+
}
5672

5773
useMount(() => {
5874
setError("");
59-
loadComp().catch((e) => {
75+
loadComp(packageVersion).catch((e) => {
6076
setError(String(e));
6177
});
6278
});
@@ -96,7 +112,7 @@ export function remoteComp<T extends RemoteCompInfo = RemoteCompInfo>(
96112
this.compValue = params.value;
97113
}
98114

99-
private async load() {
115+
private async load(packageVersion='latest') {
100116
if (!remoteInfo) {
101117
return;
102118
}
@@ -108,7 +124,7 @@ export function remoteComp<T extends RemoteCompInfo = RemoteCompInfo>(
108124
log.error("loader not found, remote info:", remoteInfo);
109125
return;
110126
}
111-
const RemoteExportedComp = await finalLoader(remoteInfo);
127+
const RemoteExportedComp = await finalLoader({...remoteInfo, packageVersion});
112128
if (!RemoteExportedComp) {
113129
return;
114130
}
@@ -135,7 +151,12 @@ export function remoteComp<T extends RemoteCompInfo = RemoteCompInfo>(
135151
getView() {
136152
const key = `${remoteInfo?.packageName}-${remoteInfo?.packageVersion}-${remoteInfo?.compName}`;
137153
return (
138-
<RemoteCompView key={key} loadComp={() => this.load()} loadingElement={loadingElement} />
154+
<RemoteCompView
155+
key={key}
156+
isLowcoderComp={remoteInfo?.packageName === 'lowcoder-comps'}
157+
loadComp={(packageVersion?: string) => this.load(packageVersion)}
158+
loadingElement={loadingElement}
159+
/>
139160
);
140161
}
141162

‎client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx‎

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { BoolCodeControl, StringControl } from "comps/controls/codeControl";
2-
import React, { ReactNode, useContext, useRef } from "react";
2+
import React, { ReactNode, useContext, useEffect,useRef,useState } from "react";
33
import { ExternalEditorContext } from "util/context/ExternalEditorContext";
44
import { Comp, CompParams, MultiBaseComp } from "lowcoder-core";
55
import {
@@ -22,17 +22,25 @@ import {
2222
MethodConfigsType,
2323
withMethodExposing,
2424
} from "./withMethodExposing";
25-
import {Section } from "lowcoder-design";
25+
import {Section,controlItem } from "lowcoder-design";
2626
import { trans } from "i18n";
2727
import { BoolControl } from "../controls/boolControl";
2828
import { valueComp, withDefault } from "./simpleGenerators";
29+
import { getPromiseAfterDispatch } from "@lowcoder-ee/util/promiseUtils";
30+
import { EditorContext } from "../editorState";
31+
import { values } from "lodash";
32+
import { UICompType, uiCompRegistry } from "../uiCompRegistry";
33+
import { getNpmPackageMeta } from "../utils/remote";
34+
import { compPluginsList } from "constants/compPluginConstants";
35+
import Select from "antd/es/select";
2936

3037
export type NewChildren<ChildrenCompMap extends Record<string, Comp<unknown>>> =
3138
ChildrenCompMap & {
3239
hidden: InstanceType<typeof BoolCodeControl>;
3340
className: InstanceType<typeof StringControl>;
3441
dataTestId: InstanceType<typeof StringControl>;
3542
preventStyleOverwriting: InstanceType<typeof BoolControl>;
43+
version: InstanceType<typeof StringControl>;
3644
};
3745

3846
export function HidableView(props: {
@@ -64,6 +72,28 @@ export function ExtendedPropertyView<
6472
childrenMap: NewChildren<ChildrenCompMap>
6573
}
6674
) {
75+
const [compVersions, setCompVersions] = useState(['latest']);
76+
const [compName, setCompName] = useState('');
77+
const editorState = useContext(EditorContext);
78+
const selectedComp = values(editorState.selectedComps())[0];
79+
const compType = selectedComp.children.compType.getView() as UICompType;
80+
81+
useEffect(() => {
82+
setCompName(uiCompRegistry[compType].compName || '');
83+
}, [compType]);
84+
85+
useEffect(() => {
86+
const fetchCompsPackageMeta = async () => {
87+
const packageMeta = await getNpmPackageMeta(compName);
88+
if (packageMeta?.versions) {
89+
setCompVersions(Object.keys(packageMeta.versions).reverse())
90+
}
91+
}
92+
if (Boolean(compName) && compPluginsList.includes(compName)) {
93+
fetchCompsPackageMeta();
94+
}
95+
}, [compName]);
96+
6797
return (
6898
<>
6999
{props.children}
@@ -72,6 +102,30 @@ export function ExtendedPropertyView<
72102
{props.childrenMap.dataTestId?.propertyView({ label: trans("prop.dataTestId") })}
73103
{props.childrenMap.preventStyleOverwriting?.propertyView({ label: trans("prop.preventOverwriting") })}
74104
</Section>
105+
{compPluginsList.includes(compName) && (
106+
<Section name={'Component Version'}>
107+
{controlItem({}, (
108+
<Select
109+
defaultValue={props.childrenMap.version.getView()}
110+
placeholder={'Select version'}
111+
options={
112+
compVersions.map(version => ({label: version, value: version}))
113+
}
114+
onChange={async (value) => {
115+
await getPromiseAfterDispatch(
116+
props.childrenMap.version.dispatch,
117+
props.childrenMap.version.changeValueAction(value), {
118+
autoHandleAfterReduce: true,
119+
}
120+
)
121+
setTimeout(() => {
122+
window.location.reload();
123+
}, 1000);
124+
}}
125+
/>
126+
))}
127+
</Section>
128+
)}
75129
</>
76130
);
77131
}
@@ -88,6 +142,7 @@ export function uiChildren<
88142
dataTestId: StringControl,
89143
preventStyleOverwriting: withDefault(BoolControl, false),
90144
appliedThemeId: valueComp<string>(''),
145+
version: withDefault(StringControl, 'latest'),
91146
} as any;
92147
}
93148

‎client/packages/lowcoder/src/comps/index.tsx‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ export var uiCompMap: Registry = {
314314
source: "npm",
315315
isRemote: true,
316316
}),
317+
compName: "lowcoder-comp-geo",
317318
layoutInfo: {
318319
w: 12,
319320
h: 50,
@@ -365,6 +366,7 @@ export var uiCompMap: Registry = {
365366
source: "npm",
366367
isRemote: true,
367368
}),
369+
compName: "lowcoder-comp-reactpivottable",
368370
layoutInfo: {
369371
w: 12,
370372
h: 50,
@@ -1239,6 +1241,7 @@ export var uiCompMap: Registry = {
12391241
source: "npm",
12401242
isRemote: true,
12411243
}),
1244+
compName: "lowcoder-comp-gantt-chart",
12421245
layoutInfo: {
12431246
w: 20,
12441247
h: 60,
@@ -1258,6 +1261,7 @@ export var uiCompMap: Registry = {
12581261
source: "npm",
12591262
isRemote: true,
12601263
}),
1264+
compName: "lowcoder-comp-hillcharts",
12611265
layoutInfo: {
12621266
w: 12,
12631267
h: 50,
@@ -1276,6 +1280,7 @@ export var uiCompMap: Registry = {
12761280
source: "npm",
12771281
isRemote: true,
12781282
}),
1283+
compName: "lowcoder-comp-bpmn-io",
12791284
layoutInfo: {
12801285
w: 19,
12811286
h: 60,
@@ -1632,6 +1637,7 @@ export var uiCompMap: Registry = {
16321637
source: "npm",
16331638
isRemote: true,
16341639
}),
1640+
compName: "lowcoder-comp-cf-turnstile",
16351641
layoutInfo: {
16361642
w: 8,
16371643
h: 20,
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export const compPluginsList = [
2+
"lowcoder-comp-geo",
3+
"lowcoder-comp-reactpivottable",
4+
"lowcoder-comp-gantt-chart",
5+
"lowcoder-comp-hillcharts",
6+
"lowcoder-comp-bpmn-io",
7+
"lowcoder-comp-cf-turnstile",
8+
]

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /