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

Commit50db580

Browse files
authored
Merge pull request#1547 from lowcoder-org/feature-iconscout-intergration
Feature - iconscout intergration
2 parents7fbe869 +9aaa4be commit50db580

File tree

13 files changed

+1185
-224
lines changed

13 files changed

+1185
-224
lines changed

‎client/packages/lowcoder/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"@fortawesome/free-regular-svg-icons":"^6.5.1",
2525
"@fortawesome/free-solid-svg-icons":"^6.5.1",
2626
"@fortawesome/react-fontawesome":"latest",
27+
"@lottiefiles/dotlottie-react":"^0.13.0",
2728
"@manaflair/redux-batch":"^1.0.0",
2829
"@rjsf/antd":"^5.21.2",
2930
"@rjsf/core":"^5.21.2",
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
importApifrom"api/api";
2+
importaxios,{AxiosInstance,AxiosPromise,AxiosRequestConfig}from"axios";
3+
import{calculateFlowCode}from"./apiUtils";
4+
5+
exportinterfaceSearchParams{
6+
query:string;
7+
asset:string;
8+
per_page:number;
9+
page:1;
10+
sort:string;
11+
formats?:string;
12+
price?:string;
13+
}
14+
15+
exporttypeResponseType={
16+
response:any;
17+
};
18+
19+
constlcHeaders={
20+
"Lowcoder-Token":calculateFlowCode(),
21+
"Content-Type":"application/json"
22+
};
23+
24+
letaxiosIns:AxiosInstance|null=null;
25+
26+
constgetAxiosInstance=(clientSecret?:string)=>{
27+
if(axiosIns&&!clientSecret){
28+
returnaxiosIns;
29+
}
30+
31+
constheaders:Record<string,string>={
32+
"Content-Type":"application/json",
33+
};
34+
35+
constapiRequestConfig:AxiosRequestConfig={
36+
baseURL:"https://api-service.lowcoder.cloud/api/flow",
37+
headers,
38+
};
39+
40+
axiosIns=axios.create(apiRequestConfig);
41+
returnaxiosIns;
42+
}
43+
44+
classIconFlowApiextendsApi{
45+
46+
staticasyncsecureRequest(body:any,timeout:number=6000):Promise<any>{
47+
letresponse;
48+
constaxiosInstance=getAxiosInstance();
49+
50+
// Create a cancel token and set timeout for cancellation
51+
constsource=axios.CancelToken.source();
52+
consttimeoutId=setTimeout(()=>{
53+
source.cancel("Request timed out.");
54+
},timeout);
55+
56+
// Request configuration with cancel token
57+
constrequestConfig:AxiosRequestConfig={
58+
method:"POST",
59+
withCredentials:true,
60+
data:body,
61+
cancelToken:source.token,// Add cancel token
62+
};
63+
64+
try{
65+
response=awaitaxiosInstance.request(requestConfig);
66+
}catch(error){
67+
if(axios.isCancel(error)){
68+
// Retry once after timeout cancellation
69+
try{
70+
// Reset the cancel token and retry
71+
constretrySource=axios.CancelToken.source();
72+
constretryTimeoutId=setTimeout(()=>{
73+
retrySource.cancel("Retry request timed out.");
74+
},20000);
75+
76+
response=awaitaxiosInstance.request({
77+
...requestConfig,
78+
cancelToken:retrySource.token,
79+
});
80+
81+
clearTimeout(retryTimeoutId);
82+
}catch(retryError){
83+
console.warn("Error at Secure Flow Request. Retry failed:",retryError);
84+
throwretryError;
85+
}
86+
}else{
87+
console.warn("Error at Secure Flow Request:",error);
88+
throwerror;
89+
}
90+
}finally{
91+
clearTimeout(timeoutId);// Clear the initial timeout
92+
}
93+
94+
returnresponse;
95+
}
96+
97+
}
98+
99+
exportconstsearchAssets=async(searchParameters :SearchParams)=>{
100+
constapiBody={
101+
path:"webhook/scout/search-asset",
102+
data:searchParameters,
103+
method:"post",
104+
headers:lcHeaders
105+
};
106+
try{
107+
constresult=awaitIconFlowApi.secureRequest(apiBody);
108+
returnresult?.data?.response?.items?.total>0 ?result.data.response.itemsasany :null;
109+
}catch(error){
110+
console.error("Error searching Design Assets:",error);
111+
throwerror;
112+
}
113+
};
114+
115+
exportconstgetAssetLinks=async(uuid:string,params:Record<string,string>)=>{
116+
constapiBody={
117+
path:"webhook/scout/get-asset-links",
118+
data:{"uuid" :uuid,"params" :params},
119+
method:"post",
120+
headers:lcHeaders
121+
};
122+
try{
123+
constresult=awaitIconFlowApi.secureRequest(apiBody);
124+
125+
returnresult?.data?.response?.download?.url.length>0 ?result.data.response.downloadasany :null;
126+
}catch(error){
127+
console.error("Error searching Design Assets:",error);
128+
throwerror;
129+
}
130+
};
131+
132+
133+
/*
134+
135+
static async search(params: SearchParams): Promise<any> {
136+
let response;
137+
try {
138+
response = await getAxiosInstance().request({
139+
url: '/v3/search',
140+
method: "GET",
141+
withCredentials: false,
142+
params: {
143+
...params,
144+
},
145+
});
146+
} catch (error) {
147+
console.error(error);
148+
}
149+
return response?.data.response.items;
150+
}
151+
152+
static async download(uuid: string, params: Record<string, string>): Promise<any> {
153+
const response = await getAxiosInstance(clientSecret).request({
154+
url: `/v3/items/${uuid}/api-download?format=${params.format}`,
155+
method: "POST",
156+
withCredentials: false,
157+
});
158+
return response?.data.response.download;
159+
}
160+
161+
*/
162+
163+
exportdefaultIconFlowApi;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
importApifrom"api/api";
2+
importaxiosfrom"axios";
3+
4+
exporttypeResponseType={
5+
response:any;
6+
};
7+
8+
classIconScoutApiextendsApi{
9+
staticasyncdownloadAsset(url:string):Promise<any>{
10+
constresponse=awaitaxios.get(url,{responseType:'blob'})
11+
returnresponse?.data;
12+
}
13+
}
14+
15+
exportdefaultIconScoutApi;

‎client/packages/lowcoder/src/api/subscriptionApi.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
importApifrom"api/api";
22
importaxios,{AxiosInstance,AxiosRequestConfig,CancelToken}from"axios";
3-
import{useDispatch,useSelector}from"react-redux";
4-
import{useEffect,useState}from"react";
53
import{calculateFlowCode}from"./apiUtils";
6-
import{fetchGroupsAction,fetchOrgUsersAction}from"redux/reduxActions/orgActions";
7-
import{getOrgUsers}from"redux/selectors/orgSelectors";
8-
import{AppState}from"@lowcoder-ee/redux/reducers";
94
importtype{
105
LowcoderNewCustomer,
116
LowcoderSearchCustomer,

‎client/packages/lowcoder/src/app.tsx

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import GlobalInstances from 'components/GlobalInstances';
6060
import{fetchHomeData,fetchServerSettingsAction}from"./redux/reduxActions/applicationActions";
6161
import{getNpmPackageMeta}from"./comps/utils/remote";
6262
import{packageMetaReadyAction,setLowcoderCompsLoading}from"./redux/reduxActions/npmPluginActions";
63+
import{SimpleSubscriptionContextProvider}from"./util/context/SimpleSubscriptionContext";
6364

6465
constLazyUserAuthComp=React.lazy(()=>import("pages/userAuth"));
6566
constLazyInviteLanding=React.lazy(()=>import("pages/common/inviteLanding"));
@@ -310,33 +311,35 @@ class AppIndex extends React.Component<AppIndexProps, any> {
310311
component={LazyPublicAppEditor}
311312
/>
312313

313-
<LazyRoute
314-
fallback="layout"
315-
path={APP_EDITOR_URL}
316-
component={LazyAppEditor}
317-
/>
318-
<LazyRoute
319-
fallback="layout"
320-
path={[
321-
USER_PROFILE_URL,
322-
NEWS_URL,
323-
ORG_HOME_URL,
324-
ALL_APPLICATIONS_URL,
325-
DATASOURCE_CREATE_URL,
326-
DATASOURCE_EDIT_URL,
327-
DATASOURCE_URL,
328-
SUPPORT_URL,
329-
QUERY_LIBRARY_URL,
330-
FOLDERS_URL,
331-
FOLDER_URL,
332-
TRASH_URL,
333-
SETTING_URL,
334-
MARKETPLACE_URL,
335-
ADMIN_APP_URL
336-
]}
337-
// component={ApplicationListPage}
338-
component={LazyApplicationHome}
339-
/>
314+
<SimpleSubscriptionContextProvider>
315+
<LazyRoute
316+
fallback="layout"
317+
path={APP_EDITOR_URL}
318+
component={LazyAppEditor}
319+
/>
320+
<LazyRoute
321+
fallback="layout"
322+
path={[
323+
USER_PROFILE_URL,
324+
NEWS_URL,
325+
ORG_HOME_URL,
326+
ALL_APPLICATIONS_URL,
327+
DATASOURCE_CREATE_URL,
328+
DATASOURCE_EDIT_URL,
329+
DATASOURCE_URL,
330+
SUPPORT_URL,
331+
QUERY_LIBRARY_URL,
332+
FOLDERS_URL,
333+
FOLDER_URL,
334+
TRASH_URL,
335+
SETTING_URL,
336+
MARKETPLACE_URL,
337+
ADMIN_APP_URL
338+
]}
339+
// component={ApplicationListPage}
340+
component={LazyApplicationHome}
341+
/>
342+
</SimpleSubscriptionContextProvider>
340343
<LazyRouteexactpath={ADMIN_AUTH_URL}component={LazyUserAuthComp}/>
341344
<LazyRoutepath={USER_AUTH_URL}component={LazyUserAuthComp}/>
342345
<LazyRoute

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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import {
3030
}from"../controls/eventHandlerControl";
3131
import{useContext}from"react";
3232
import{EditorContext}from"comps/editorState";
33+
import{AssetType,IconscoutControl}from"@lowcoder-ee/comps/controls/iconscoutControl";
34+
import{dropdownControl}from"../controls/dropdownControl";
3335

3436
constContainer=styled.div<{
3537
$style:IconStyleType|undefined;
@@ -61,10 +63,17 @@ const Container = styled.div<{
6163

6264
constEventOptions=[clickEvent]asconst;
6365

66+
constModeOptions=[
67+
{label:"Standard",value:"standard"},
68+
{label:"Asset Library",value:"asset-library"},
69+
]asconst;
70+
6471
constchildrenMap={
6572
style:styleControl(IconStyle,'style'),
6673
animationStyle:styleControl(AnimationStyle,'animationStyle'),
74+
sourceMode:dropdownControl(ModeOptions,"standard"),
6775
icon:withDefault(IconControl,"/icon:antd/homefilled"),
76+
iconScoutAsset:IconscoutControl(AssetType.ICON),
6877
autoHeight:withDefault(AutoHeightControl,"auto"),
6978
iconSize:withDefault(NumberControl,20),
7079
onEvent:eventHandlerControl(EventOptions),
@@ -103,7 +112,10 @@ const IconView = (props: RecordConstructorToView<typeof childrenMap>) => {
103112
}}
104113
onClick={()=>props.onEvent("click")}
105114
>
106-
{props.icon}
115+
{props.sourceMode==='standard'
116+
?props.icon
117+
:<imgsrc={props.iconScoutAsset.value}/>
118+
}
107119
</Container>
108120
)}
109121
>
@@ -117,11 +129,17 @@ let IconBasicComp = (function () {
117129
.setPropertyViewFn((children)=>(
118130
<>
119131
<Sectionname={sectionNames.basic}>
120-
{children.icon.propertyView({
132+
{children.sourceMode.propertyView({
133+
label:"",
134+
radioButton:true
135+
})}
136+
{children.sourceMode.getView()==='standard'&&children.icon.propertyView({
121137
label:trans("iconComp.icon"),
122138
IconType:"All",
123139
})}
124-
140+
{children.sourceMode.getView()==='asset-library'&&children.iconScoutAsset.propertyView({
141+
label:trans("button.icon"),
142+
})}
125143
</Section>
126144

127145
{["logic","both"].includes(useContext(EditorContext).editorModeStatus)&&(

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
withExposingConfigs,
1313
}from"../generators/withExposing";
1414
import{RecordConstructorToView}from"lowcoder-core";
15-
import{useEffect,useRef,useState}from"react";
15+
import{ReactElement,useEffect,useRef,useState}from"react";
1616
import_from"lodash";
1717
importReactResizeDetectorfrom"react-resize-detector";
1818
import{styleControl}from"comps/controls/styleControl";
@@ -35,6 +35,8 @@ import { useContext } from "react";
3535
import{EditorContext}from"comps/editorState";
3636
import{StringControl}from"../controls/codeControl";
3737
import{PositionControl}from"comps/controls/dropdownControl";
38+
import{dropdownControl}from"../controls/dropdownControl";
39+
import{AssetType,IconscoutControl}from"../controls/iconscoutControl";
3840

3941
constContainer=styled.div<{
4042
$style:ImageStyleType|undefined,
@@ -111,6 +113,10 @@ const getStyle = (style: ImageStyleType) => {
111113
};
112114

113115
constEventOptions=[clickEvent]asconst;
116+
constModeOptions=[
117+
{label:"URL",value:"standard"},
118+
{label:"Asset Library",value:"asset-library"},
119+
]asconst;
114120

115121
constContainerImg=(props:RecordConstructorToView<typeofchildrenMap>)=>{
116122
constimgRef=useRef<HTMLDivElement>(null);
@@ -194,7 +200,11 @@ const ContainerImg = (props: RecordConstructorToView<typeof childrenMap>) => {
194200
}
195201
>
196202
<AntImage
197-
src={props.src.value}
203+
src={
204+
props.sourceMode==='asset-library'
205+
?props.iconScoutAsset?.value
206+
:props.src.value
207+
}
198208
referrerPolicy="same-origin"
199209
draggable={false}
200210
preview={props.supportPreview ?{src:props.previewSrc||props.src.value} :false}
@@ -210,7 +220,9 @@ const ContainerImg = (props: RecordConstructorToView<typeof childrenMap>) => {
210220
};
211221

212222
constchildrenMap={
223+
sourceMode:dropdownControl(ModeOptions,"standard"),
213224
src:withDefault(StringStateControl,"https://temp.im/350x400"),
225+
iconScoutAsset:IconscoutControl(AssetType.ILLUSTRATION),
214226
onEvent:eventHandlerControl(EventOptions),
215227
style:styleControl(ImageStyle,'style'),
216228
animationStyle:styleControl(AnimationStyle,'animationStyle'),
@@ -234,7 +246,14 @@ let ImageBasicComp = new UICompBuilder(childrenMap, (props) => {
234246
return(
235247
<>
236248
<Sectionname={sectionNames.basic}>
237-
{children.src.propertyView({
249+
{children.sourceMode.propertyView({
250+
label:"",
251+
radioButton:true
252+
})}
253+
{children.sourceMode.getView()==='standard'&&children.src.propertyView({
254+
label:trans("image.src"),
255+
})}
256+
{children.sourceMode.getView()==='asset-library'&&children.iconScoutAsset.propertyView({
238257
label:trans("image.src"),
239258
})}
240259
</Section>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp