Movatterモバイル変換


[0]ホーム

URL:


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

Commitc96bb7e

Browse files
author
FalkWolsky
committed
Rounding Up Marketplace and Multi-Icon Component
1 parent1c44f3a commitc96bb7e

File tree

13 files changed

+368
-24
lines changed

13 files changed

+368
-24
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ const AppCategories = Object.keys(ApplicationCategoriesEnum).map(
172172
constvalue=ApplicationCategoriesEnum[catasAppCategoriesEnumKey];
173173
return{
174174
label:value,
175-
value,
175+
value:cat
176176
}
177177
}
178178
)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,4 @@ IconBasicComp = class extends IconBasicComp {
144144
exportconstIconComp=withExposingConfigs(IconBasicComp,[
145145
NameConfigHidden,
146146
]);
147+
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
2+
import{FontAwesomeIcon}from'@fortawesome/react-fontawesome';
3+
import{findIconDefinition,library}from'@fortawesome/fontawesome-svg-core';
4+
import{fas}from'@fortawesome/free-solid-svg-icons';
5+
import{far}from'@fortawesome/free-regular-svg-icons';
6+
import*asAntdIconsfrom'@ant-design/icons';
7+
8+
library.add(far,fas);
9+
10+
functionparseIconIdentifier(identifier:string){
11+
if(identifier.startsWith('/icon:antd/')){
12+
letname=identifier.split('/')[2];
13+
return{type:'antd', name};
14+
}
15+
elseif(identifier.startsWith('/icon:solid/')||identifier.startsWith('/icon:regular/')){
16+
const[style,name]=identifier.substring(6).split('/');
17+
return{type:'fontAwesome', style, name};
18+
}
19+
elseif(identifier.startsWith('data:image')){
20+
return{type:'base64',data:identifier,name:""};
21+
}
22+
elseif(identifier.startsWith('http')){
23+
return{type:'url',url:identifier,name:""};
24+
}
25+
else{
26+
return{type:'unknown',name:""};
27+
}
28+
}
29+
30+
interfaceIconProps{
31+
identifier:string;
32+
width?:string;
33+
height?:string;
34+
style?:React.CSSProperties;
35+
}
36+
37+
constconvertToCamelCase=(name:string)=>{
38+
returnname.replace(/(-\w)/g,(match)=>match[1].toUpperCase());
39+
}
40+
41+
constappendStyleSuffix=(name:string)=>{
42+
if(name.endsWith('outlined')){
43+
returnname.replace('outlined','Outlined');
44+
}elseif(name.endsWith('filled')){
45+
returnname.replace('filled','Filled');
46+
}elseif(name.endsWith('twotone')){
47+
returnname.replace('twotone','TwoTone');
48+
}
49+
returnname;
50+
}
51+
52+
// Multi icon Display Component
53+
54+
constbaseMultiIconDisplay:React.FC<IconProps>=({ identifier, width='24px', height='24px', style})=>{
55+
56+
consticonData=parseIconIdentifier(identifier);
57+
58+
if(iconData.type==='fontAwesome'){
59+
constprefix=iconData.style==='solid' ?'fas' :'far';// 'fas' for solid, 'far' for regular
60+
// Find the icon definition using prefix and iconName
61+
consticonLookup=findIconDefinition({prefix:prefixasany,iconName:iconData.nameasany});
62+
63+
if(!iconLookup){
64+
console.error(`Icon${iconData.name} with prefix${prefix} not found`);
65+
returnnull;
66+
}
67+
return<FontAwesomeIconicon={iconLookup}style={{ width, height, ...style}}/>;
68+
}
69+
elseif(iconData.type==='antd'){
70+
leticonName=convertToCamelCase(iconData.name);
71+
iconName=appendStyleSuffix(iconName);
72+
iconName=iconName.charAt(0).toUpperCase()+iconName.slice(1);
73+
constAntdIcon=(AntdIconsasany)[iconName];
74+
if(!AntdIcon){
75+
console.error(`ANTd Icon${iconData.name} not found`);
76+
returnnull;
77+
}
78+
return<AntdIconstyle={{fontSize:width, ...style}}/>;
79+
}
80+
elseif(iconData.type==='url'||iconData.type==='base64'){
81+
return<imgsrc={iconData.type==='url' ?iconData.url :iconData.data}alt="icon"style={{ width, height, ...style}}/>;
82+
}
83+
else{
84+
returnnull;// Unknown type
85+
}
86+
};
87+
88+
exportconstMultiIconDisplay=baseMultiIconDisplay;

‎client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ function ColumnPropertyView<T extends MultiBaseComp<TableChildrenType>>(props: {
272272
<ToolTipLabeltitle={trans("table.refreshButtonTooltip")}>
273273
<StyledRefreshIcon
274274
onClick={()=>{
275-
console.log("comp",comp);
275+
//console.log("comp", comp);
276276
comp.dispatch(
277277
wrapChildAction(
278278
"columns",

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export interface ApplicationMeta {
7979
creatorEmail?:string;
8080
title?:string;
8181
description?:string;
82-
icon?:string;
82+
image?:string;
8383
category?:ApplicationCategoriesEnum;
8484
showheader?:boolean;
8585
orgId:string;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,6 +2266,7 @@ export const en = {
22662266
"module":"Module",
22672267
"trash":"Trash",
22682268
"marketplace":"Marketplace",
2269+
"allCategories":"All Categories",
22692270
"queryLibrary":"Query Library",
22702271
"datasource":"Data Sources",
22712272
"selectDatasourceType":"Select Data Source Type",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2210,6 +2210,7 @@ home: {
22102210
"errorMarketplaceApps":"获取市场应用程序错误",
22112211
"localMarketplaceTitle":"本地市场",
22122212
"globalMarketplaceTitle":"Lowcoder 市场",
2213+
"allCategories":"所有类别",
22132214
memberPermissionList:"成员权限:",
22142215
orgName:"{orgName}管理员",
22152216
addMember:"添加成员",

‎client/packages/lowcoder/src/pages/ApplicationV2/HomeCardView.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
importstyledfrom"styled-components";
22
import{HomeRes}from"./HomeLayout";
33
import{HomeResCard}from"./HomeResCard";
4+
import{MarketplaceResCard}from"./MarketplaceResCard";
45
importReact,{useState}from"react";
56
import{MoveToFolderModal}from"./MoveToFolderModal";
67

78
constApplicationCardsWrapper=styled.div`
89
display: grid;
910
grid-template-columns: repeat(auto-fill, minmax(408px, 1fr));
10-
grid-template-rows: repeat(auto-fill, min(68px, 100%));
11+
grid-template-rows: repeat(auto-fill, min(auto, 100%));
1112
grid-column-gap: 112px;
13+
grid-row-gap: 20px;
1214
margin: 48px 26px 80px;
1315
overflow: hidden;
1416
@media screen and (max-width: 500px) {
@@ -23,6 +25,8 @@ export function HomeCardView(props: { resources: HomeRes[] }) {
2325
return(
2426
<ApplicationCardsWrapper>
2527
{props.resources.map((res)=>(
28+
res.isMarketplace ?
29+
<MarketplaceResCardkey={res.id}res={res}/> :
2630
<HomeResCardkey={res.id}res={res}onMove={setNeedMoveRes}/>
2731
))}
2832
<MoveToFolderModalsource={needMoveRes}onClose={()=>setNeedMoveRes(undefined)}/>

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

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { checkIsMobile } from "util/commonUtils";
3535
importMarketplaceHeaderImagefrom"assets/images/marketplaceHeaderImage.jpg";
3636
import{Divider}from"antd";
3737
import{Margin}from"../setting/theme/styledComponents";
38+
import{ApplicationCategoriesEnum}from"constants/applicationConstants";
3839

3940
constWrapper=styled.div`
4041
display: flex;
@@ -171,7 +172,7 @@ const FilterDropdown = styled(Select)`
171172

172173
constFilterMenuItem=styled.div`
173174
display: flex;
174-
align-items:center;
175+
align-items:left;
175176
height: 29px;
176177
width: 100%;
177178
`;
@@ -253,6 +254,10 @@ export interface HomeRes {
253254
key:string;
254255
id:string;
255256
name:string;
257+
title?:string;
258+
description?:string;
259+
category?:string;
260+
icon?:string;
256261
type:HomeResTypeEnum;
257262
creator:string;
258263
lastModifyTime:number;
@@ -276,20 +281,37 @@ export interface HomeLayoutProps {
276281
}
277282

278283
exportfunctionHomeLayout(props:HomeLayoutProps){
284+
285+
279286
const{ breadcrumb=[], elements=[], localMarketplaceApps=[], globalMarketplaceApps=[],mode}=props;
287+
288+
constcategoryOptions=[
289+
{label:<FilterMenuItem>{trans("home.allCategories")}</FilterMenuItem>,value:'All'},
290+
...Object.entries(ApplicationCategoriesEnum).map(([key,value])=>({
291+
label:(
292+
<FilterMenuItem>
293+
{value}
294+
</FilterMenuItem>
295+
),
296+
value:key,
297+
})),
298+
];
299+
280300
constuser=useSelector(getUser);
281301
constisFetching=useSelector(isFetchingFolderElements);
282302
constisSelfHost=window.location.host!=='app.lowcoder.cloud';
283-
const[filterBy,setFilterBy]=useState<HomeResKey>("All");
303+
const[typeFilter,setTypeFilter]=useState<HomeResKey>("All");
304+
const[categoryFilter,setCategoryFilter]=useState<ApplicationCategoriesEnum|"All">("All");
284305
const[searchValue,setSearchValue]=useState("");
285306
const[layout,setLayout]=useState<HomeLayoutType>(
286307
checkIsMobile(window.innerWidth) ?"card" :getHomeLayout()
287308
);
288309

310+
289311
useEffect(()=>saveHomeLayout(layout),[layout]);
290312

291313
useEffect(()=>{
292-
// remove collision status from localstorage
314+
// remove collision status from localstorage, as the next selected app may have another collision status
293315
removeCollisionStatus();
294316
},[]);
295317

@@ -300,6 +322,7 @@ export function HomeLayout(props: HomeLayoutProps) {
300322
}
301323

302324
vardisplayElements=elements;
325+
303326
if(mode==="marketplace"&&isSelfHost){
304327
constmarkedLocalApps=localMarketplaceApps.map(app=>({ ...app,isLocalMarketplace:true}));
305328
constmarkedGlobalApps=globalMarketplaceApps.map(app=>({ ...app,isLocalMarketplace:false}));
@@ -319,18 +342,27 @@ export function HomeLayout(props: HomeLayoutProps) {
319342
:true
320343
)
321344
.filter((e)=>{
322-
if(HomeResTypeEnum[filterBy].valueOf()===HomeResTypeEnum.All){
345+
if(HomeResTypeEnum[typeFilter].valueOf()===HomeResTypeEnum.All){
323346
returntrue;
324347
}
325348
if(e.folder){
326-
returnHomeResTypeEnum[filterBy]===HomeResTypeEnum.Folder;
349+
returnHomeResTypeEnum[typeFilter]===HomeResTypeEnum.Folder;
327350
}else{
328-
if(filterBy==="Navigation"){
351+
if(typeFilter==="Navigation"){
329352
returnNavigationTypes.map((t)=>t.valueOf()).includes(e.applicationType);
330353
}
331-
returnHomeResTypeEnum[filterBy].valueOf()===e.applicationType;
354+
returnHomeResTypeEnum[typeFilter].valueOf()===e.applicationType;
355+
}
356+
})
357+
.filter((e)=>{
358+
// If "All" is selected, do not filter out any elements based on category
359+
if(categoryFilter==='All'||!categoryFilter){
360+
returntrue;
332361
}
362+
// Otherwise, filter elements based on the selected category
363+
return!e.folder&&e.category===categoryFilter.toString();
333364
})
365+
334366
.map((e)=>
335367
e.folder
336368
?{
@@ -347,6 +379,10 @@ export function HomeLayout(props: HomeLayoutProps) {
347379
key:e.applicationId,
348380
id:e.applicationId,
349381
name:e.name,
382+
title:e.title,
383+
description:e.description,
384+
category:e.category,
385+
icon:e.image,
350386
type:HomeResTypeEnum[HomeResTypeEnum[e.applicationType]asHomeResKey],
351387
creator:e?.creatorEmail??e.createBy,
352388
lastModifyTime:e.lastModifyTime,
@@ -385,6 +421,14 @@ export function HomeLayout(props: HomeLayoutProps) {
385421
}))
386422
]
387423

424+
consttestOptions=[
425+
getFilterMenuItem(HomeResTypeEnum.All),
426+
getFilterMenuItem(HomeResTypeEnum.Application),
427+
getFilterMenuItem(HomeResTypeEnum.Module),
428+
...(mode!=="marketplace" ?[getFilterMenuItem(HomeResTypeEnum.Navigation)] :[]),
429+
...(mode!=="trash"&&mode!=="marketplace" ?[getFilterMenuItem(HomeResTypeEnum.Folder)] :[]),
430+
];
431+
388432
return(
389433
<Wrapper>
390434
<HeaderWrapper>
@@ -414,19 +458,27 @@ export function HomeLayout(props: HomeLayoutProps) {
414458
{mode!=="folders"&&mode!=="module"&&(
415459
<FilterDropdown
416460
variant="borderless"
417-
value={filterBy}
418-
onChange={(value:any)=>setFilterBy(valueasHomeResKey)}
461+
value={typeFilter}
462+
onChange={(value:any)=>setTypeFilter(valueasHomeResKey)}
419463
options={[
420464
getFilterMenuItem(HomeResTypeEnum.All),
421465
getFilterMenuItem(HomeResTypeEnum.Application),
422466
getFilterMenuItem(HomeResTypeEnum.Module),
423467
...(mode!=="marketplace" ?[getFilterMenuItem(HomeResTypeEnum.Navigation)] :[]),
424468
...(mode!=="trash"&&mode!=="marketplace" ?[getFilterMenuItem(HomeResTypeEnum.Folder)] :[]),
425-
426469
]}
427470
getPopupContainer={(node:any)=>node}
428-
suffixIcon={<ArrowSolidIcon/>}
429-
/>
471+
suffixIcon={<ArrowSolidIcon/>}/>
472+
)}
473+
{mode==="marketplace"&&(
474+
<FilterDropdown
475+
style={{minWidth:"220px"}}
476+
variant="borderless"
477+
value={categoryFilter}
478+
onChange={(value:any)=>setCategoryFilter(valueasApplicationCategoriesEnum)}
479+
options={categoryOptions}
480+
// getPopupContainer={(node) => node}
481+
suffixIcon={<ArrowSolidIcon/>}/>
430482
)}
431483

432484
<OperationRightWrapper>

‎client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ const Card = styled.div`
7373
align-items: center;
7474
height: 100%;
7575
width: 100%;
76-
border-bottom: 1px solid #f5f5f6;
76+
7777
padding: 0 10px;
7878
7979
button {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp