Skip to content

Commit 2397012

Browse files
authored
Merge branch 'dev' into ee-setup
2 parents b8c7625 + 50db580 commit 2397012

File tree

66 files changed

+1967
-421
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+1967
-421
lines changed

.github/workflows/sonarcloud.yml

+1
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ jobs:
3030
env:
3131
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
3232
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
33+
SONAR_SCANNER_OPTS: "-Dsonar.javascript.node.maxspace=8192 -Xmx8192m"

client/VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.6.4
1+
2.6.5

client/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "lowcoder-frontend",
3-
"version": "2.6.4",
3+
"version": "2.6.5",
44
"type": "module",
55
"private": true,
66
"workspaces": [

client/packages/lowcoder-comps/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "lowcoder-comps",
3-
"version": "2.6.5",
3+
"version": "2.6.6",
44
"type": "module",
55
"license": "MIT",
66
"dependencies": {

client/packages/lowcoder-comps/src/comps/calendarComp/calendarComp.tsx

+83-94
Large diffs are not rendered by default.

client/packages/lowcoder-comps/src/comps/calendarComp/calendarConstants.tsx

+37-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import {
1515
lightenColor,
1616
toHex,
1717
UnderlineCss,
18-
EventModalStyleType
18+
EventModalStyleType,
19+
DateParser,
20+
isValidColor,
21+
Theme,
1922
} from "lowcoder-sdk";
2023
import styled from "styled-components";
2124
import dayjs from "dayjs";
@@ -27,6 +30,10 @@ import {
2730
} from "@fullcalendar/core";
2831
import { default as Form } from "antd/es/form";
2932

33+
type Theme = typeof Theme;
34+
type EventModalStyleType = typeof EventModalStyleType;
35+
type CalendarStyleType = typeof CalendarStyleType;
36+
3037
export const Wrapper = styled.div<{
3138
$editable?: boolean;
3239
$style?: CalendarStyleType;
@@ -1135,3 +1142,32 @@ export const viewClassNames = (info: ViewContentArg) => {
11351142
return className;
11361143
};
11371144

1145+
export const formattedEvents = (events: EventType[], theme?: Theme) => {
1146+
return events.map((item: EventType) => {
1147+
return {
1148+
title: item.label,
1149+
label: item.label,
1150+
id: item.id,
1151+
start: dayjs(item.start, DateParser).format(),
1152+
end: dayjs(item.end, DateParser).format(),
1153+
allDay: item.allDay,
1154+
...(item.resourceId ? { resourceId: item.resourceId } : {}),
1155+
...(item.groupId ? { groupId: item.groupId } : {}),
1156+
backgroundColor: item.backgroundColor,
1157+
extendedProps: { // Ensure color is in extendedProps
1158+
color: isValidColor(item.color || "") ? item.color : theme?.theme?.primary,
1159+
detail: item.detail,
1160+
titleColor: item.titleColor,
1161+
detailColor: item.detailColor,
1162+
titleFontWeight: item.titleFontWeight,
1163+
titleFontStyle: item.titleFontStyle,
1164+
detailFontWeight: item.detailFontWeight,
1165+
detailFontStyle: item.detailFontStyle,
1166+
animation: item?.animation,
1167+
animationDelay: item?.animationDelay,
1168+
animationDuration: item?.animationDuration,
1169+
animationIterationCount: item?.animationIterationCount
1170+
}
1171+
}
1172+
})
1173+
}

client/packages/lowcoder-design/src/components/keyValueList.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export const KeyValueList = (props: {
9696
onDelete: (item: ReactNode, index: number) => void;
9797
isStatic?: boolean;
9898
indicatorForAll?: boolean;
99+
allowDeletingAll?: boolean;
99100
}) => {
100101
return (
101102
<>
@@ -105,8 +106,8 @@ export const KeyValueList = (props: {
105106
{item}
106107
{!props.isStatic &&
107108
<DelIcon
108-
onClick={() => props.list.length > 1 && props.onDelete(item, index)}
109-
$forbidden={props.list.length === 1}
109+
onClick={() => (props.allowDeletingAll || (!props.allowDeletingAll && props.list.length > 1)) && props.onDelete(item, index)}
110+
$forbidden={!props.allowDeletingAll && props.list.length === 1}
110111
/>
111112
}
112113
</KeyValueListItem>

client/packages/lowcoder-sdk/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "lowcoder-sdk",
3-
"version": "2.6.6",
3+
"version": "2.6.7",
44
"type": "module",
55
"files": [
66
"src",

client/packages/lowcoder/index.html

-4
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@
5454
<script>
5555
window.global = window;
5656
</script>
57-
<script
58-
src="https://tag.clearbitscripts.com/v1/pk_dfbc0aeefb28dc63475b67134facf127/tags.js"
59-
referrerPolicy="no-referrer"
60-
></script>
6157
<script async defer src="//js-eu1.hs-scripts.com/144574215.js" type="text/javascript" id="hs-script-loader"></script>
6258
</head>
6359
<body>

client/packages/lowcoder/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "lowcoder",
3-
"version": "2.6.4",
3+
"version": "2.6.5",
44
"private": true,
55
"type": "module",
66
"main": "src/index.sdk.ts",
@@ -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",

client/packages/lowcoder/src/api/apiUtils.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,14 @@ export const apiFailureResponseInterceptor = (error: any) => {
122122
if (!notAuthRequiredPath(error.config?.url)) {
123123
if (error.response.status === API_STATUS_CODES.REQUEST_NOT_AUTHORISED) {
124124
// get x-org-id from failed request
125-
const organizationId = error.response.headers['x-org-id'] || undefined;
125+
let organizationId;
126+
if (error.response.headers['x-org-id']) {
127+
organizationId = error.response.headers['x-org-id'];
128+
}
129+
if (localStorage.getItem('lowcoder_login_orgId')) {
130+
organizationId = localStorage.getItem('lowcoder_login_orgId');
131+
localStorage.removeItem('lowcoder_login_orgId');
132+
}
126133
// Redirect to login and set a redirect url.
127134
StoreRegistry.getStore().dispatch(
128135
logoutAction({
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import Api from "api/api";
2+
import axios, { AxiosInstance, AxiosPromise, AxiosRequestConfig } from "axios";
3+
import { calculateFlowCode } from "./apiUtils";
4+
5+
export interface SearchParams {
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+
export type ResponseType = {
16+
response: any;
17+
};
18+
19+
const lcHeaders = {
20+
"Lowcoder-Token": calculateFlowCode(),
21+
"Content-Type": "application/json"
22+
};
23+
24+
let axiosIns: AxiosInstance | null = null;
25+
26+
const getAxiosInstance = (clientSecret?: string) => {
27+
if (axiosIns && !clientSecret) {
28+
return axiosIns;
29+
}
30+
31+
const headers: Record<string, string> = {
32+
"Content-Type": "application/json",
33+
};
34+
35+
const apiRequestConfig: AxiosRequestConfig = {
36+
baseURL: "https://api-service.lowcoder.cloud/api/flow",
37+
headers,
38+
};
39+
40+
axiosIns = axios.create(apiRequestConfig);
41+
return axiosIns;
42+
}
43+
44+
class IconFlowApi extends Api {
45+
46+
static async secureRequest(body: any, timeout: number = 6000): Promise<any> {
47+
let response;
48+
const axiosInstance = getAxiosInstance();
49+
50+
// Create a cancel token and set timeout for cancellation
51+
const source = axios.CancelToken.source();
52+
const timeoutId = setTimeout(() => {
53+
source.cancel("Request timed out.");
54+
}, timeout);
55+
56+
// Request configuration with cancel token
57+
const requestConfig: AxiosRequestConfig = {
58+
method: "POST",
59+
withCredentials: true,
60+
data: body,
61+
cancelToken: source.token, // Add cancel token
62+
};
63+
64+
try {
65+
response = await axiosInstance.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+
const retrySource = axios.CancelToken.source();
72+
const retryTimeoutId = setTimeout(() => {
73+
retrySource.cancel("Retry request timed out.");
74+
}, 20000);
75+
76+
response = await axiosInstance.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+
throw retryError;
85+
}
86+
} else {
87+
console.warn("Error at Secure Flow Request:", error);
88+
throw error;
89+
}
90+
} finally {
91+
clearTimeout(timeoutId); // Clear the initial timeout
92+
}
93+
94+
return response;
95+
}
96+
97+
}
98+
99+
export const searchAssets = async (searchParameters : SearchParams) => {
100+
const apiBody = {
101+
path: "webhook/scout/search-asset",
102+
data: searchParameters,
103+
method: "post",
104+
headers: lcHeaders
105+
};
106+
try {
107+
const result = await IconFlowApi.secureRequest(apiBody);
108+
return result?.data?.response?.items?.total > 0 ? result.data.response.items as any : null;
109+
} catch (error) {
110+
console.error("Error searching Design Assets:", error);
111+
throw error;
112+
}
113+
};
114+
115+
export const getAssetLinks = async (uuid: string, params: Record<string, string>) => {
116+
const apiBody = {
117+
path: "webhook/scout/get-asset-links",
118+
data: {"uuid" : uuid, "params" : params},
119+
method: "post",
120+
headers: lcHeaders
121+
};
122+
try {
123+
const result = await IconFlowApi.secureRequest(apiBody);
124+
125+
return result?.data?.response?.download?.url.length > 0 ? result.data.response.download as any : null;
126+
} catch (error) {
127+
console.error("Error searching Design Assets:", error);
128+
throw error;
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+
export default IconFlowApi;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Api from "api/api";
2+
import axios from "axios";
3+
4+
export type ResponseType = {
5+
response: any;
6+
};
7+
8+
class IconScoutApi extends Api {
9+
static async downloadAsset(url: string): Promise<any> {
10+
const response = await axios.get(url, {responseType: 'blob'})
11+
return response?.data;
12+
}
13+
}
14+
15+
export default IconScoutApi;

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

-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import Api from "api/api";
22
import axios, { 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
import type {
105
LowcoderNewCustomer,
116
LowcoderSearchCustomer,

0 commit comments

Comments
 (0)