Skip to content

Commit

Permalink
Adapting Marketplace
Browse files Browse the repository at this point in the history
  • Loading branch information
FalkWolsky committed Feb 24, 2024
1 parent c2b90de commit 5cfac16
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 88 deletions.
40 changes: 40 additions & 0 deletions client/packages/lowcoder/src/constants/applicationConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,40 @@ export enum AppTypeEnum {
MobileTabLayout = 6,
}

export enum ApplicationCategoriesEnum {
BUSINESS = "Business",
DASHBOARD = "Dashboards & Reporting",
SLIDES = "Slides & Presentations",
WEBSITE = "Website",
SHOPPING = "Shopping & Ecommerce",
TOOLS = "Tools & Internal Apps",
COMMUNICATION = "Communication",
PRODUCTIVITY = "Productivity",
EDUCATION = "Education",
SOCIAL_MEDIA = "Social Media",
ENTERTAINMENT = "Entertainment",
FINANCE = "Finance",
HEALTH_FITNESS = "Health & Fitness",
LIFESTYLE = "Lifestyle",
NEWS_MAGAZINES = "News & Magazines",
PERSONALIZATION = "Personalization",
PHOTOGRAPHY = "Photography",
SPORTS = "Sports",
TRAVEL_LOCAL = "Travel & Local",
WEATHER = "Weather",
MEDICAL = "Medical",
MUSIC_AUDIO = "Music & Audio",
AUTO_VEHICLES = "Auto & Vehicles",
ART_DESIGN = "Art & Design",
BEAUTY = "Beauty",
DATING = "Dating",
EVENTS = "Events",
FOOD_DRINK = "Food & Drink",
HOUSE_HOME = "House & Home",
PARENTING = "Parenting",
MAPS_NAVIGATION = "Maps & Navigation",
};

export const AppUILayoutType: Record<AppTypeEnum, UiLayoutType> = {
[AppTypeEnum.Application]: "normal",
[AppTypeEnum.Module]: "module",
Expand All @@ -37,13 +71,19 @@ export interface ApplicationMeta {
createBy: string;
createAt: number;
creatorEmail?: string;
title?: string;
description?: string;
icon?: string;
category?: ApplicationCategoriesEnum;
showheader?: boolean;
orgId: string;
role: ApplicationRoleType;
extra: ApplicationExtra;
lastModifyTime: number; // may be 0
lastViewTime: number;
folderId: string;
folder: false;
isLocalMarketplace?: boolean;
applicationStatus: "NORMAL" | "RECYCLED" | "DELETED";
}

Expand Down
4 changes: 4 additions & 0 deletions client/packages/lowcoder/src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2304,10 +2304,14 @@ export const en = {
"copyLink": "Copy link",
"appPublicMessage": "Make the app public. Anyone can view.",
"modulePublicMessage": "Make the module public. Anyone can view.",
"marketplaceURL": "https://api-service.lowcoder.cloud",
"appMarketplaceMessage": "Publish your App on Lowcoder Marketplace. Anyone can view and copy it from there.",
"moduleMarketplaceMessage": "Publish your Module on Lowcoder Marketplace. Anyone can view and copy it from there.",
"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.",
"noMarketplaceApps": "No apps yet in the marketplace",
"errorMarketplaceApps": "Error while loading Marketplace Apps",
"localMarketplaceTitle": "Local Marketplace",
"globalMarketplaceTitle": "Lowcoder Marketplace",
"memberPermissionList": "Member permissions: ",
"orgName": "{orgName} admins",
"addMember": "Add members",
Expand Down
4 changes: 4 additions & 0 deletions client/packages/lowcoder/src/i18n/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2183,10 +2183,14 @@ home: {
copyLink: "复制链接",
appPublicMessage: "将应用设为公开,任何人都可以查看.",
modulePublicMessage: "将模块设为公开,任何人都可以查看.",
"marketplaceURL": "https://api-service.lowcoder.cloud",
"appMarketplaceMessage": "发布您的应用程序到Lowcoder市场.任何人都可以在那里查看和复制它.",
"moduleMarketplaceMessage": "发布您的模块到Lowcoder市场.任何人都可以在那里查看和复制它.",
"marketplaceGoodPublishing": "请确保您的应用程序命名准确、易于使用。发布前请删除任何敏感信息。此外,移除本地数据源,代之以静态内置临时数据",
"noMarketplaceApps": "市场上还没有应用程序",
"errorMarketplaceApps": "获取市场应用程序错误",
"localMarketplaceTitle": "本地市场",
"globalMarketplaceTitle": "Lowcoder 市场",
memberPermissionList: "成员权限:",
orgName: "{orgName}管理员",
addMember: "添加成员",
Expand Down
56 changes: 49 additions & 7 deletions client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import { trans } from "../../i18n";
import { isFetchingFolderElements } from "../../redux/selectors/folderSelector";
import { checkIsMobile } from "util/commonUtils";
import MarketplaceHeaderImage from "assets/images/marketplaceHeaderImage.jpg";
import { Divider } from "antd";
import { Margin } from "../setting/theme/styledComponents";

const Wrapper = styled.div`
display: flex;
Expand Down Expand Up @@ -257,6 +259,7 @@ export interface HomeRes {
isManageable: boolean;
isDeletable: boolean;
isMarketplace?: boolean;
isLocalMarketplace?: boolean;
}

export type HomeBreadcrumbType = { text: string; path: string };
Expand All @@ -266,11 +269,13 @@ export type HomeLayoutMode = "view" | "trash" | "module" | "folder" | "folders"
export interface HomeLayoutProps {
breadcrumb?: HomeBreadcrumbType[];
elements: Array<ApplicationMeta | FolderMeta>;
localMarketplaceApps?: Array<ApplicationMeta>;
globalMarketplaceApps?: Array<ApplicationMeta>;
mode: HomeLayoutMode;
}

export function HomeLayout(props: HomeLayoutProps) {
const { breadcrumb = [], elements = [], mode } = props;
const { breadcrumb = [], elements = [], localMarketplaceApps = [], globalMarketplaceApps = [],mode } = props;
const user = useSelector(getUser);
const isFetching = useSelector(isFetchingFolderElements);

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

const resList: HomeRes[] = elements
var displayElements = elements;
if (mode === "marketplace") {
const markedLocalApps = localMarketplaceApps.map(app => ({ ...app, isLocalMarketplace: true }));
const markedGlobalApps = globalMarketplaceApps.map(app => ({ ...app, isLocalMarketplace: false }));
// Merge local and global apps into the elements array
displayElements = [...markedLocalApps, ...markedGlobalApps];
}

console.log("HomeLayout: displayElements", displayElements);

const resList: HomeRes[] = displayElements
.filter((e) =>
searchValue
? e.name.toLocaleLowerCase().includes(searchValue) ||
Expand Down Expand Up @@ -331,6 +346,7 @@ export function HomeLayout(props: HomeLayoutProps) {
isManageable: mode !== 'marketplace' && canManageApp(user, e),
isDeletable: mode !== 'marketplace' && canEditApp(user, e),
isMarketplace: mode === 'marketplace',
isLocalMarketplace: e.isLocalMarketplace,
}
);

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

<ContentWrapper>


{isFetching && resList.length === 0 ? (
<SkeletonStyle active paragraph={{ rows: 8, width: 648 }} title={false} />
) : (
Expand All @@ -434,11 +449,38 @@ export function HomeLayout(props: HomeLayoutProps) {
<LayoutSwitcher onClick={() => setLayout(layout === "list" ? "card" : "list")}>
{layout === "list" ? <HomeCardIcon /> : <HomeListIcon />}
</LayoutSwitcher>
{layout === "list" ? (
<HomeTableView resources={resList} />
) : (
<HomeCardView resources={resList} />

{mode === "marketplace" && (
<>
{layout === "list" ? (
<>
<h2 style={{padding: "0 36px"}}>{trans("home.localMarketplaceTitle")}</h2>
<HomeTableView resources={resList.filter(app => app.isLocalMarketplace)} />
<Divider style={{padding: "0 36px", margin: "0 36px", width: "calc(100% - 72px) !important"}}/>
<h2 style={{padding: "0 36px"}}>{trans("home.globalMarketplaceTitle")}</h2>
<HomeTableView resources={resList.filter(app => !app.isLocalMarketplace)} />
</>
) : (
<>
<h2 style={{padding: "0 36px"}}>{trans("home.localMarketplaceTitle")}</h2>
<HomeCardView resources={resList.filter(app => app.isLocalMarketplace)} />
<Divider style={{padding: "0 36px", margin: "12px 36px", width: "calc(100% - 72px) !important"}}/>
<h2 style={{padding: "0 36px"}}>{trans("home.globalMarketplaceTitle")}</h2>
<HomeCardView resources={resList.filter(app => !app.isLocalMarketplace)} />
</>
)}
</>
)}
{mode !== "marketplace" && (
<>
{layout === "list" ? (
<HomeTableView resources={resList} />
) : (
<HomeCardView resources={resList} />
)}
</>
)}

</>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,54 +13,49 @@ import log from "loglevel";

export function MarketplaceView() {
const [ marketplaceApps, setMarketplaceApps ] = useState<Array<ApplicationMeta>>([]);
const marketplaceType = matchPath<{marketplaceType?: MarketplaceType}>(window.location.pathname, MARKETPLACE_TYPE_URL)?.params
.marketplaceType;
const isLowcoderMarketplace = marketplaceType === 'lowcoder';
const marketplaceBreadcrumbText = !marketplaceType?.length
? trans("home.marketplace")
: marketplaceType === 'lowcoder'
? `${trans("home.marketplace")} (Lowcoder)`
: `${trans("home.marketplace")} (Local)`;

const fetchLowcoderMarketplaceApps = () => {
const http = axios.create({
baseURL: 'https://api-service.lowcoder.cloud',
withCredentials: false,
});
return http.get(`/api/v1/applications/marketplace-apps`);
};

const fetchLocalMarketplaceApps = () => {
return ApplicationApi.fetchAllMarketplaceApps()
}
const [ localMarketplaceApps, setLocalMarketplaceApps ] = useState<Array<ApplicationMeta>>([]);

const fetchMarketplaceApps = async () => {
try {
let response: AxiosResponse<GenericApiResponse<ApplicationMeta[]>>;
if(isLowcoderMarketplace) {
response = await fetchLowcoderMarketplaceApps();
} else {
response = await fetchLocalMarketplaceApps();
const http = axios.create({
baseURL: trans("home.marketplaceURL"),
withCredentials: false,
});
response = await http.get(`/api/v1/applications/marketplace-apps`);
const isValidResponse: boolean = validateResponse(response);
if (isValidResponse) {
setMarketplaceApps(response.data.data);
}
} catch (error: any) {
messageInstance.error(trans("home.errorMarketplaceApps"));
}
}

const fetchLocalMarketplaceApps = async () => {
try {
let response: AxiosResponse<GenericApiResponse<ApplicationMeta[]>>;
response = await ApplicationApi.fetchAllMarketplaceApps();
const isValidResponse: boolean = validateResponse(response);
if (isValidResponse) {
setMarketplaceApps(response.data.data);
setLocalMarketplaceApps(response.data.data);
}
} catch (error: any) {
messageInstance.error(error.message);
log.debug("fetch marketplace apps error: ", error);
messageInstance.error(trans("home.errorMarketplaceApps"));
}
}

useEffect(() => {
fetchMarketplaceApps();
}, [marketplaceType]);
fetchLocalMarketplaceApps();
}, []);

return (
<HomeLayout
elements={marketplaceApps}
breadcrumb={[{ text: marketplaceBreadcrumbText, path: MARKETPLACE_URL }]}
elements={[]}
localMarketplaceApps={localMarketplaceApps}
globalMarketplaceApps={marketplaceApps}
breadcrumb={[{ text: trans("home.marketplace"), path: MARKETPLACE_URL }]}
mode={"marketplace"}
/>
);
Expand Down
21 changes: 2 additions & 19 deletions client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -363,14 +363,10 @@ export default function ApplicationHome() {
{
text: (
<TabLabel>
{
isSelfHost
? `${trans("home.marketplace")} (Local)`
: trans("home.marketplace")
}
{trans("home.marketplace")}
</TabLabel>
),
routePath: isSelfHost ? MARKETPLACE_URL_BY_TYPE('local') : MARKETPLACE_URL,
routePath: MARKETPLACE_URL,
routePathExact: false,
routeComp: MarketplaceView,
icon: ({ selected, ...otherProps }) =>
Expand All @@ -381,19 +377,6 @@ export default function ApplicationHome() {
),
visible: ({ user }) => user.orgDev,
},
{
text: <TabLabel>{`${trans("home.marketplace")} (Lowcoder)`}</TabLabel>,
routePath: MARKETPLACE_URL_BY_TYPE('lowcoder'),
routePathExact: false,
routeComp: MarketplaceView,
icon: ({ selected, ...otherProps }) =>
selected ? (
<LowcoderMarketplaceActiveIcon {...otherProps} />
) : (
<LowcoderMarketplaceIcon {...otherProps} />
),
visible: ({ user }) => user.orgDev && isSelfHost,
},
{
text: <TabLabel>{trans("home.trash")}</TabLabel>,
routePath: TRASH_URL,
Expand Down
Loading

0 comments on commit 5cfac16

Please sign in to comment.