Skip to content

Commit ac12f11

Browse files
authored
Merge branch 'dev' into ptm-apps-enhancements
2 parents 7aa74fb + 5cfac16 commit ac12f11

File tree

8 files changed

+169
-88
lines changed

8 files changed

+169
-88
lines changed

client/packages/lowcoder/src/constants/applicationConstants.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,40 @@ export enum AppTypeEnum {
1313
MobileTabLayout = 6,
1414
}
1515

16+
export enum ApplicationCategoriesEnum {
17+
BUSINESS = "Business",
18+
DASHBOARD = "Dashboards & Reporting",
19+
SLIDES = "Slides & Presentations",
20+
WEBSITE = "Website",
21+
SHOPPING = "Shopping & Ecommerce",
22+
TOOLS = "Tools & Internal Apps",
23+
COMMUNICATION = "Communication",
24+
PRODUCTIVITY = "Productivity",
25+
EDUCATION = "Education",
26+
SOCIAL_MEDIA = "Social Media",
27+
ENTERTAINMENT = "Entertainment",
28+
FINANCE = "Finance",
29+
HEALTH_FITNESS = "Health & Fitness",
30+
LIFESTYLE = "Lifestyle",
31+
NEWS_MAGAZINES = "News & Magazines",
32+
PERSONALIZATION = "Personalization",
33+
PHOTOGRAPHY = "Photography",
34+
SPORTS = "Sports",
35+
TRAVEL_LOCAL = "Travel & Local",
36+
WEATHER = "Weather",
37+
MEDICAL = "Medical",
38+
MUSIC_AUDIO = "Music & Audio",
39+
AUTO_VEHICLES = "Auto & Vehicles",
40+
ART_DESIGN = "Art & Design",
41+
BEAUTY = "Beauty",
42+
DATING = "Dating",
43+
EVENTS = "Events",
44+
FOOD_DRINK = "Food & Drink",
45+
HOUSE_HOME = "House & Home",
46+
PARENTING = "Parenting",
47+
MAPS_NAVIGATION = "Maps & Navigation",
48+
};
49+
1650
export const AppUILayoutType: Record<AppTypeEnum, UiLayoutType> = {
1751
[AppTypeEnum.Application]: "normal",
1852
[AppTypeEnum.Module]: "module",
@@ -37,13 +71,19 @@ export interface ApplicationMeta {
3771
createBy: string;
3872
createAt: number;
3973
creatorEmail?: string;
74+
title?: string;
75+
description?: string;
76+
icon?: string;
77+
category?: ApplicationCategoriesEnum;
78+
showheader?: boolean;
4079
orgId: string;
4180
role: ApplicationRoleType;
4281
extra: ApplicationExtra;
4382
lastModifyTime: number; // may be 0
4483
lastViewTime: number;
4584
folderId: string;
4685
folder: false;
86+
isLocalMarketplace?: boolean;
4787
applicationStatus: "NORMAL" | "RECYCLED" | "DELETED";
4888
}
4989

client/packages/lowcoder/src/i18n/locales/en.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,10 +2304,14 @@ export const en = {
23042304
"copyLink": "Copy link",
23052305
"appPublicMessage": "Make the app public. Anyone can view.",
23062306
"modulePublicMessage": "Make the module public. Anyone can view.",
2307+
"marketplaceURL": "https://api-service.lowcoder.cloud",
23072308
"appMarketplaceMessage": "Publish your App on Lowcoder Marketplace. Anyone can view and copy it from there.",
23082309
"moduleMarketplaceMessage": "Publish your Module on Lowcoder Marketplace. Anyone can view and copy it from there.",
23092310
"marketplaceGoodPublishing": "Please make sure your app is well-named and easy to use. Remove any sensitive information before publishing. Also, remove local datasources and replace by static built-in temporary data.",
23102311
"noMarketplaceApps": "No apps yet in the marketplace",
2312+
"errorMarketplaceApps": "Error while loading Marketplace Apps",
2313+
"localMarketplaceTitle": "Local Marketplace",
2314+
"globalMarketplaceTitle": "Lowcoder Marketplace",
23112315
"memberPermissionList": "Member permissions: ",
23122316
"orgName": "{orgName} admins",
23132317
"addMember": "Add members",

client/packages/lowcoder/src/i18n/locales/zh.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2183,10 +2183,14 @@ home: {
21832183
copyLink: "复制链接",
21842184
appPublicMessage: "将应用设为公开,任何人都可以查看.",
21852185
modulePublicMessage: "将模块设为公开,任何人都可以查看.",
2186+
"marketplaceURL": "https://api-service.lowcoder.cloud",
21862187
"appMarketplaceMessage": "发布您的应用程序到Lowcoder市场.任何人都可以在那里查看和复制它.",
21872188
"moduleMarketplaceMessage": "发布您的模块到Lowcoder市场.任何人都可以在那里查看和复制它.",
21882189
"marketplaceGoodPublishing": "请确保您的应用程序命名准确、易于使用。发布前请删除任何敏感信息。此外,移除本地数据源,代之以静态内置临时数据",
21892190
"noMarketplaceApps": "市场上还没有应用程序",
2191+
"errorMarketplaceApps": "获取市场应用程序错误",
2192+
"localMarketplaceTitle": "本地市场",
2193+
"globalMarketplaceTitle": "Lowcoder 市场",
21902194
memberPermissionList: "成员权限:",
21912195
orgName: "{orgName}管理员",
21922196
addMember: "添加成员",

client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import { trans } from "../../i18n";
3333
import { isFetchingFolderElements } from "../../redux/selectors/folderSelector";
3434
import { checkIsMobile } from "util/commonUtils";
3535
import MarketplaceHeaderImage from "assets/images/marketplaceHeaderImage.jpg";
36+
import { Divider } from "antd";
37+
import { Margin } from "../setting/theme/styledComponents";
3638

3739
const Wrapper = styled.div`
3840
display: flex;
@@ -257,6 +259,7 @@ export interface HomeRes {
257259
isManageable: boolean;
258260
isDeletable: boolean;
259261
isMarketplace?: boolean;
262+
isLocalMarketplace?: boolean;
260263
}
261264

262265
export type HomeBreadcrumbType = { text: string; path: string };
@@ -266,11 +269,13 @@ export type HomeLayoutMode = "view" | "trash" | "module" | "folder" | "folders"
266269
export interface HomeLayoutProps {
267270
breadcrumb?: HomeBreadcrumbType[];
268271
elements: Array<ApplicationMeta | FolderMeta>;
272+
localMarketplaceApps?: Array<ApplicationMeta>;
273+
globalMarketplaceApps?: Array<ApplicationMeta>;
269274
mode: HomeLayoutMode;
270275
}
271276

272277
export function HomeLayout(props: HomeLayoutProps) {
273-
const { breadcrumb = [], elements = [], mode } = props;
278+
const { breadcrumb = [], elements = [], localMarketplaceApps = [], globalMarketplaceApps = [],mode } = props;
274279
const user = useSelector(getUser);
275280
const isFetching = useSelector(isFetchingFolderElements);
276281

@@ -288,7 +293,17 @@ export function HomeLayout(props: HomeLayoutProps) {
288293
return null;
289294
}
290295

291-
const resList: HomeRes[] = elements
296+
var displayElements = elements;
297+
if (mode === "marketplace") {
298+
const markedLocalApps = localMarketplaceApps.map(app => ({ ...app, isLocalMarketplace: true }));
299+
const markedGlobalApps = globalMarketplaceApps.map(app => ({ ...app, isLocalMarketplace: false }));
300+
// Merge local and global apps into the elements array
301+
displayElements = [...markedLocalApps, ...markedGlobalApps];
302+
}
303+
304+
console.log("HomeLayout: displayElements", displayElements);
305+
306+
const resList: HomeRes[] = displayElements
292307
.filter((e) =>
293308
searchValue
294309
? e.name.toLocaleLowerCase().includes(searchValue) ||
@@ -331,6 +346,7 @@ export function HomeLayout(props: HomeLayoutProps) {
331346
isManageable: mode !== 'marketplace' && canManageApp(user, e),
332347
isDeletable: mode !== 'marketplace' && canEditApp(user, e),
333348
isMarketplace: mode === 'marketplace',
349+
isLocalMarketplace: e.isLocalMarketplace,
334350
}
335351
);
336352

@@ -420,7 +436,6 @@ export function HomeLayout(props: HomeLayoutProps) {
420436

421437
<ContentWrapper>
422438

423-
424439
{isFetching && resList.length === 0 ? (
425440
<SkeletonStyle active paragraph={{ rows: 8, width: 648 }} title={false} />
426441
) : (
@@ -434,11 +449,38 @@ export function HomeLayout(props: HomeLayoutProps) {
434449
<LayoutSwitcher onClick={() => setLayout(layout === "list" ? "card" : "list")}>
435450
{layout === "list" ? <HomeCardIcon /> : <HomeListIcon />}
436451
</LayoutSwitcher>
437-
{layout === "list" ? (
438-
<HomeTableView resources={resList} />
439-
) : (
440-
<HomeCardView resources={resList} />
452+
453+
{mode === "marketplace" && (
454+
<>
455+
{layout === "list" ? (
456+
<>
457+
<h2 style={{padding: "0 36px"}}>{trans("home.localMarketplaceTitle")}</h2>
458+
<HomeTableView resources={resList.filter(app => app.isLocalMarketplace)} />
459+
<Divider style={{padding: "0 36px", margin: "0 36px", width: "calc(100% - 72px) !important"}}/>
460+
<h2 style={{padding: "0 36px"}}>{trans("home.globalMarketplaceTitle")}</h2>
461+
<HomeTableView resources={resList.filter(app => !app.isLocalMarketplace)} />
462+
</>
463+
) : (
464+
<>
465+
<h2 style={{padding: "0 36px"}}>{trans("home.localMarketplaceTitle")}</h2>
466+
<HomeCardView resources={resList.filter(app => app.isLocalMarketplace)} />
467+
<Divider style={{padding: "0 36px", margin: "12px 36px", width: "calc(100% - 72px) !important"}}/>
468+
<h2 style={{padding: "0 36px"}}>{trans("home.globalMarketplaceTitle")}</h2>
469+
<HomeCardView resources={resList.filter(app => !app.isLocalMarketplace)} />
470+
</>
471+
)}
472+
</>
441473
)}
474+
{mode !== "marketplace" && (
475+
<>
476+
{layout === "list" ? (
477+
<HomeTableView resources={resList} />
478+
) : (
479+
<HomeCardView resources={resList} />
480+
)}
481+
</>
482+
)}
483+
442484
</>
443485
)}
444486
</>

client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,54 +13,49 @@ import log from "loglevel";
1313

1414
export function MarketplaceView() {
1515
const [ marketplaceApps, setMarketplaceApps ] = useState<Array<ApplicationMeta>>([]);
16-
const marketplaceType = matchPath<{marketplaceType?: MarketplaceType}>(window.location.pathname, MARKETPLACE_TYPE_URL)?.params
17-
.marketplaceType;
18-
const isLowcoderMarketplace = marketplaceType === 'lowcoder';
19-
const marketplaceBreadcrumbText = !marketplaceType?.length
20-
? trans("home.marketplace")
21-
: marketplaceType === 'lowcoder'
22-
? `${trans("home.marketplace")} (Lowcoder)`
23-
: `${trans("home.marketplace")} (Local)`;
24-
25-
const fetchLowcoderMarketplaceApps = () => {
26-
const http = axios.create({
27-
baseURL: 'https://api-service.lowcoder.cloud',
28-
withCredentials: false,
29-
});
30-
return http.get(`/api/v1/applications/marketplace-apps`);
31-
};
32-
33-
const fetchLocalMarketplaceApps = () => {
34-
return ApplicationApi.fetchAllMarketplaceApps()
35-
}
16+
const [ localMarketplaceApps, setLocalMarketplaceApps ] = useState<Array<ApplicationMeta>>([]);
3617

3718
const fetchMarketplaceApps = async () => {
3819
try {
3920
let response: AxiosResponse<GenericApiResponse<ApplicationMeta[]>>;
40-
if(isLowcoderMarketplace) {
41-
response = await fetchLowcoderMarketplaceApps();
42-
} else {
43-
response = await fetchLocalMarketplaceApps();
21+
const http = axios.create({
22+
baseURL: trans("home.marketplaceURL"),
23+
withCredentials: false,
24+
});
25+
response = await http.get(`/api/v1/applications/marketplace-apps`);
26+
const isValidResponse: boolean = validateResponse(response);
27+
if (isValidResponse) {
28+
setMarketplaceApps(response.data.data);
4429
}
30+
} catch (error: any) {
31+
messageInstance.error(trans("home.errorMarketplaceApps"));
32+
}
33+
}
4534

35+
const fetchLocalMarketplaceApps = async () => {
36+
try {
37+
let response: AxiosResponse<GenericApiResponse<ApplicationMeta[]>>;
38+
response = await ApplicationApi.fetchAllMarketplaceApps();
4639
const isValidResponse: boolean = validateResponse(response);
4740
if (isValidResponse) {
48-
setMarketplaceApps(response.data.data);
41+
setLocalMarketplaceApps(response.data.data);
4942
}
5043
} catch (error: any) {
51-
messageInstance.error(error.message);
52-
log.debug("fetch marketplace apps error: ", error);
44+
messageInstance.error(trans("home.errorMarketplaceApps"));
5345
}
5446
}
5547

5648
useEffect(() => {
5749
fetchMarketplaceApps();
58-
}, [marketplaceType]);
50+
fetchLocalMarketplaceApps();
51+
}, []);
5952

6053
return (
6154
<HomeLayout
62-
elements={marketplaceApps}
63-
breadcrumb={[{ text: marketplaceBreadcrumbText, path: MARKETPLACE_URL }]}
55+
elements={[]}
56+
localMarketplaceApps={localMarketplaceApps}
57+
globalMarketplaceApps={marketplaceApps}
58+
breadcrumb={[{ text: trans("home.marketplace"), path: MARKETPLACE_URL }]}
6459
mode={"marketplace"}
6560
/>
6661
);

client/packages/lowcoder/src/pages/ApplicationV2/index.tsx

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -363,14 +363,10 @@ export default function ApplicationHome() {
363363
{
364364
text: (
365365
<TabLabel>
366-
{
367-
isSelfHost
368-
? `${trans("home.marketplace")} (Local)`
369-
: trans("home.marketplace")
370-
}
366+
{trans("home.marketplace")}
371367
</TabLabel>
372368
),
373-
routePath: isSelfHost ? MARKETPLACE_URL_BY_TYPE('local') : MARKETPLACE_URL,
369+
routePath: MARKETPLACE_URL,
374370
routePathExact: false,
375371
routeComp: MarketplaceView,
376372
icon: ({ selected, ...otherProps }) =>
@@ -381,19 +377,6 @@ export default function ApplicationHome() {
381377
),
382378
visible: ({ user }) => user.orgDev,
383379
},
384-
{
385-
text: <TabLabel>{`${trans("home.marketplace")} (Lowcoder)`}</TabLabel>,
386-
routePath: MARKETPLACE_URL_BY_TYPE('lowcoder'),
387-
routePathExact: false,
388-
routeComp: MarketplaceView,
389-
icon: ({ selected, ...otherProps }) =>
390-
selected ? (
391-
<LowcoderMarketplaceActiveIcon {...otherProps} />
392-
) : (
393-
<LowcoderMarketplaceIcon {...otherProps} />
394-
),
395-
visible: ({ user }) => user.orgDev && isSelfHost,
396-
},
397380
{
398381
text: <TabLabel>{trans("home.trash")}</TabLabel>,
399382
routePath: TRASH_URL,

0 commit comments

Comments
 (0)