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

Commit21510f4

Browse files
author
Connell, Joseph
committed
Merge branch 'feature-otel' ofhttps://github.com/placidic/lowcoder into feature-otel
2 parents7e0e5ca +154d214 commit21510f4

File tree

9 files changed

+440
-44
lines changed

9 files changed

+440
-44
lines changed

‎client/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
"flag-icons":"^7.2.1",
8484
"number-precision":"^1.6.0",
8585
"react-countup":"^6.5.3",
86+
"react-github-btn":"^1.4.0",
8687
"react-player":"^2.11.0",
8788
"resize-observer-polyfill":"^1.5.1",
8889
"rollup":"^4.22.5",

‎client/packages/lowcoder-design/src/icons/index.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,6 @@ export { ReactComponent as BorderWidthIcon } from "./remix/space.svg";
221221
export{ReactComponentasBorderStyleIcon}from"./remix/separator.svg";
222222
export{ReactComponentasRotationIcon}from"./remix/clockwise-line.svg";
223223
export{ReactComponentasBorderRadiusIcon}from"./remix/rounded-corner.svg";
224-
225-
// Falk: TODO
226224
export{ReactComponentasShadowIcon}from"./remix/shadow-line.svg";
227225
export{ReactComponentasOpacityIcon}from"./remix/contrast-drop-2-line.svg";
228226
export{ReactComponentasAnimationIcon}from"./remix/loader-line.svg";
@@ -257,6 +255,13 @@ export { ReactComponent as EnterpriseIcon } from "./remix/earth-line.svg";
257255
export{ReactComponentasVerticalIcon}from"./remix/vertical.svg";
258256
export{ReactComponentasHorizontalIcon}from"./remix/horizontal.svg";
259257

258+
// Social Sharing
259+
export{ReactComponentasTwitterIcon}from"./remix/twitter-x-line.svg";
260+
export{ReactComponentasLinkedInIcon}from"./remix/linkedin-box-fill.svg";
261+
export{ReactComponentasFacebookIcon}from"./remix/facebook-circle-fill.svg";
262+
export{ReactComponentasMediumIcon}from"./remix/medium-fill.svg";
263+
export{ReactComponentasRedditIcon}from"./remix/reddit-line.svg";
264+
260265

261266
// components
262267

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
importApifrom"api/api";
2+
importaxios,{AxiosInstance,AxiosRequestConfig,CancelToken}from"axios";
3+
import{calculateFlowCode}from"./apiUtils";
4+
5+
exporttypeResponseType={
6+
response:any;
7+
};
8+
9+
// Axios Configuration
10+
constlcHeaders={
11+
"Lowcoder-Token":calculateFlowCode(),
12+
"Content-Type":"application/json"
13+
};
14+
15+
letaxiosIns:AxiosInstance|null=null;
16+
17+
constgetAxiosInstance=(clientSecret?:string)=>{
18+
if(axiosIns&&!clientSecret){
19+
returnaxiosIns;
20+
}
21+
22+
constheaders:Record<string,string>={
23+
"Content-Type":"application/json",
24+
};
25+
26+
constapiRequestConfig:AxiosRequestConfig={
27+
baseURL:"https://api-service.lowcoder.cloud/api/flow",
28+
headers,
29+
};
30+
31+
axiosIns=axios.create(apiRequestConfig);
32+
returnaxiosIns;
33+
};
34+
35+
classNewsApiextendsApi{
36+
37+
staticasyncsecureRequest(body:any,timeout:number=6000):Promise<any>{
38+
letresponse;
39+
constaxiosInstance=getAxiosInstance();
40+
41+
// Create a cancel token and set timeout for cancellation
42+
constsource=axios.CancelToken.source();
43+
consttimeoutId=setTimeout(()=>{
44+
source.cancel("Request timed out.");
45+
},timeout);
46+
47+
// Request configuration with cancel token
48+
constrequestConfig:AxiosRequestConfig={
49+
method:"POST",
50+
withCredentials:true,
51+
data:body,
52+
cancelToken:source.token,// Add cancel token
53+
};
54+
55+
try{
56+
response=awaitaxiosInstance.request(requestConfig);
57+
}catch(error){
58+
if(axios.isCancel(error)){
59+
// Retry once after timeout cancellation
60+
try{
61+
// Reset the cancel token and retry
62+
constretrySource=axios.CancelToken.source();
63+
constretryTimeoutId=setTimeout(()=>{
64+
retrySource.cancel("Retry request timed out.");
65+
},10000);
66+
67+
response=awaitaxiosInstance.request({
68+
...requestConfig,
69+
cancelToken:retrySource.token,
70+
});
71+
72+
clearTimeout(retryTimeoutId);
73+
}catch(retryError){
74+
console.warn("Error at Secure Flow Request. Retry failed:",retryError);
75+
throwretryError;
76+
}
77+
}else{
78+
console.warn("Error at Secure Flow Request:",error);
79+
throwerror;
80+
}
81+
}finally{
82+
clearTimeout(timeoutId);// Clear the initial timeout
83+
}
84+
85+
returnresponse;
86+
}
87+
}
88+
89+
// API Functions
90+
91+
// secure/get-youtube-videos
92+
// secure/get-github-releases
93+
94+
exportconstgetReleases=async()=>{
95+
constapiBody={
96+
path:"webhook/secure/get-github-releases",
97+
data:{},
98+
method:"post",
99+
headers:lcHeaders
100+
};
101+
try{
102+
constresult=awaitNewsApi.secureRequest(apiBody);
103+
returnresult?.data[0]?.github?.length>0 ?result.data[0].githubasany[] :[];
104+
}catch(error){
105+
console.error("Error getting news:",error);
106+
throwerror;
107+
}
108+
};
109+
110+
exportconstgetYoutubeVideos=async()=>{
111+
constapiBody={
112+
path:"webhook/secure/get-youtube-videos",
113+
data:{},
114+
method:"post",
115+
headers:lcHeaders
116+
};
117+
try{
118+
constresult=awaitNewsApi.secureRequest(apiBody);
119+
returnresult?.data[0]?.youtube?.length>0 ?result.data[0].youtubeasany[] :[];
120+
}catch(error){
121+
console.error("Error getting news:",error);
122+
throwerror;
123+
}
124+
};
125+
126+
exportconstgetHubspotContent=async()=>{
127+
constapiBody={
128+
path:"webhook/secure/get-hubspot-content",
129+
data:{},
130+
method:"post",
131+
headers:lcHeaders
132+
};
133+
try{
134+
constresult=awaitNewsApi.secureRequest(apiBody);
135+
returnresult?.data[0]?.hubspot?.length>0 ?result.data[0].hubspotasany[] :[];
136+
}catch(error){
137+
console.error("Error getting news:",error);
138+
throwerror;
139+
}
140+
};
141+
142+
exportdefaultNewsApi;

‎client/packages/lowcoder/src/components/PermissionDialog/AppPermissionDialog.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ import { TacoButton } from "components/button";
2727
importcopyfrom"copy-to-clipboard";
2828
import{StyledLoading}from"./commonComponents";
2929
import{PermissionRole}from"./Permission";
30-
import{SHARE_TITLE}from"../../constants/apiConstants";
3130
import{messageInstance}from"lowcoder-design/src/components/GlobalInstances";
3231
import{defaultasDivider}from"antd/es/divider";
32+
import{SocialShareButtons}from"components/SocialShareButtons";
3333

3434
exportconstAppPermissionDialog=React.memo((props:{
3535
applicationId:string;
@@ -83,7 +83,7 @@ export const AppPermissionDialog = React.memo((props: {
8383
return(
8484
<PermissionDialog
8585
{...props}
86-
title={SHARE_TITLE}
86+
title={trans("home.appSharingDialogueTitle")}
8787
ownerLabel={trans("home.allPermissions")}
8888
viewBodyRender={(list)=>{
8989
if(!appPermissionInfo){
@@ -96,6 +96,7 @@ export const AppPermissionDialog = React.memo((props: {
9696
applicationId={applicationId}
9797
permissionInfo={appPermissionInfo!}
9898
/>
99+
<Divider/>
99100
{list}
100101
</>
101102
);
@@ -206,6 +207,8 @@ function AppShareView(props: {
206207
useEffect(()=>{
207208
setPublicToMarketplace(permissionInfo.publicToMarketplace);
208209
},[permissionInfo.publicToMarketplace]);
210+
constinviteLink=window.location.origin+APPLICATION_VIEW_URL(props.applicationId,"view");
211+
209212
return(
210213
<divstyle={{marginBottom:"22px"}}>
211214

@@ -247,7 +250,19 @@ function AppShareView(props: {
247250
{trans("home.marketplaceGoodPublishing")}
248251
</div><Divider/></>}
249252

250-
{isPublic&&<AppInviteViewappId={applicationId}/>}
253+
{isPublic&&<AppInviteViewappId={applicationId}/>}
254+
255+
{isPublic&&
256+
<>
257+
<Divider/>
258+
<SocialShareButtons
259+
url={inviteLink}
260+
text={trans("home.appSocialSharingMessage")}
261+
/>
262+
</>
263+
}
264+
265+
251266
</div>
252267
);
253268
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
importReactfrom"react";
2+
importstyledfrom"styled-components";
3+
import{trans}from"../i18n";
4+
import{
5+
TwitterIcon,
6+
LinkedInIcon,
7+
FacebookIcon,
8+
MediumIcon,
9+
RedditIcon,
10+
}from"lowcoder-design";
11+
12+
constShareWrapper=styled.div`
13+
margin-top: 0px;
14+
padding: 0px;
15+
`;
16+
17+
constButtonGroup=styled.div`
18+
display: flex;
19+
gap: 12px;
20+
margin-top: 8px;
21+
22+
a {
23+
display: inline-flex;
24+
align-items: center;
25+
justify-content: center;
26+
width: 44px;
27+
height: 44px;
28+
border-radius: 4px;
29+
background-color: #f5f5f5;
30+
text-decoration: none;
31+
color: #333;
32+
33+
&:hover {
34+
background-color: #e6e6e6;
35+
}
36+
37+
svg {
38+
width: 20px;
39+
height: 20px;
40+
}
41+
}
42+
`;
43+
44+
exportconstSocialShareButtons:React.FC<{url:string;text:string}>=({
45+
url,
46+
text,
47+
})=>{
48+
constencodedUrl=encodeURIComponent(url);
49+
constencodedText=encodeURIComponent(text);
50+
51+
return(
52+
<ShareWrapper>
53+
<divstyle={{fontWeight:500,marginBottom:4}}>
54+
{trans("home.appSocialSharing")}
55+
</div>
56+
<ButtonGroup>
57+
{/* Twitter supports inline text and URL */}
58+
<a
59+
href={`https://twitter.com/intent/tweet?text=${encodedText}&url=${encodedUrl}`}
60+
target="_blank"
61+
title={trans("home.socialShare")+" Twitter"}
62+
rel="noopener noreferrer"
63+
>
64+
<TwitterIcon/>
65+
</a>
66+
67+
{/* Facebook ONLY accepts the URL and reads OG metadata from it */}
68+
<a
69+
href={`https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`}
70+
target="_blank"
71+
title={trans("home.socialShare")+" Facebook"}
72+
rel="noopener noreferrer"
73+
>
74+
<FacebookIcon/>
75+
</a>
76+
77+
{/* LinkedIn also only uses the URL; title/summary are ignored unless OG tags exist */}
78+
<a
79+
href={`https://www.linkedin.com/sharing/share-offsite/?url=${encodedUrl}`}
80+
target="_blank"
81+
title={trans("home.socialShare")+" LinkedIn"}
82+
rel="noopener noreferrer"
83+
>
84+
<LinkedInIcon/>
85+
</a>
86+
87+
{/* Reddit sharing */}
88+
<a
89+
href={`https://www.reddit.com/submit?url=${encodedUrl}&title=${encodedText}`}
90+
target="_blank"
91+
title={trans("home.socialShare")+" Reddit"}
92+
rel="noopener noreferrer"
93+
>
94+
<RedditIcon/>
95+
</a>
96+
97+
{/* Medium sharing - sharing the Medium article URL directly */}
98+
<a
99+
href={"https://medium.com/new-story"}
100+
target="_blank"
101+
title={trans("home.socialShare")+" Medium"}
102+
rel="noopener noreferrer"
103+
>
104+
<MediumIcon/>
105+
</a>
106+
</ButtonGroup>
107+
</ShareWrapper>
108+
);
109+
};

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3383,6 +3383,10 @@ export const en = {
33833383
"fileFormatError":"File format error",
33843384
"groupWithSquareBrackets":"[Group] ",
33853385
"allPermissions":"Owner",
3386+
"appSharingDialogueTitle" :"App Sharing and Permissions",
3387+
"appSocialSharing" :"Share Your App and Experience on:",
3388+
"appSocialSharingMessage" :"I made this App with Lowcoder, check it out!",
3389+
"socialShare" :"Share on",
33863390
"shareLink":"Share link: ",
33873391
"copyLink":"Copy link",
33883392
"appPublicMessage":"Make the app public. Anyone can view.",

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp