Skip to content

Commit 7115dee

Browse files
authored
Merge branch 'dev' into height-calculation-improvements
2 parents 1091688 + 9ea5e96 commit 7115dee

File tree

10 files changed

+62
-74
lines changed

10 files changed

+62
-74
lines changed

README.md

+15-12
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,32 @@
77
<p>
88
Create software applications (internal and customer-facing!) and Meeting/Collaboration tools for your Company and your Customers with minimal coding experience.
99
</p>
10-
<h3 style="margin-top: 0">Lowcoder is the best Retool, Appsmith or Tooljet Alternative.</h3>
10+
<h3 style="margin-top: 0">We think, Lowcoder is simply better than Retool, Appsmith Tooljet, Outsystems or Mendix.</h3>
1111
</div>
12+
---
1213

13-
<img src="https://1167272343-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjNgeI0mUzgw6Re92iTOw%2Fuploads%2FnwXJC1XBqP2MvTQitPyo%2FApp%20Editor%20%7C%20Main%20Screeen%20clean.png?alt=media&token=e5fba81b-82a7-4c0e-a15d-baa781d5b13a"/>
14-
14+
## 🎥 Lowcoder Intro Video
15+
<div align="center">
16+
<a href="https://www.youtube.com/watch?v=AQo0iFWUWiU" target="_blank">
17+
<img src="https://img.youtube.com/vi/AQo0iFWUWiU/maxresdefault.jpg" alt="Lowcoder Intro Video" width="100%">
18+
</a>
19+
<p><i>Click the image above to watch the video on YouTube</i> 📺</p>
20+
</div>
1521

22+
---
1623
## 📢 Use Lowcoder in 3 steps
1724
1. Connect to any data sources or APIs.
18-
2. Build flexible and responsive UI with 100+ components and free layout / design possibilities.
25+
2. Build flexible and responsive UI with 120+ components and free layout / design possibilities.
1926
3. Share with colleagues and customers.
2027

2128
## 💡 Why Lowcoder
2229
One platform for everything instead so many different softwares. (like Website Builders, CMS, CRM, POS, ERP, Dashboards & Data Story Visualization, Collaboration Tools).
2330

2431
It's cumbersome to create a single app. You had to design user interfaces, write code in multiple languages and frameworks, and understand how all of that code works together.
2532

26-
NewGen Lowcode Platforms like Retool and others are great for their simplicity and flexibility - like Lowcoder too, but they can also be limited in different ways, especially when it comes to "external" applications for everyone.
33+
NewGen Lowcode Platforms like Retool and others are great for their simplicity and flexibility - like Lowcoder too, but they can also be limited in different ways, especially when it comes to "external" applications for everyone - because their pricing focusses to internal apps and "pay per User".
2734

28-
Lowcoder wants to take a step forward. More specifically, Lowcoder is:
35+
With Lowcoder we did a step forward. More specifically, Lowcoder is:
2936
- An all-in-one IDE to create internal or customer-facing (external) apps.
3037
- A place to create, build and share building blocks of web applications and whole websites.
3138
- The tool and community to support your business, and lower the cost and time to develop interactive applications.
@@ -34,9 +41,9 @@ Lowcoder wants to take a step forward. More specifically, Lowcoder is:
3441
- The only platform which has extensibility plugin architecture [Check Community Contributions](https://www.npmjs.com/search?q=lowcoder-comp)
3542

3643
## 🪄 Features
37-
- **Visual UI builder** with 100+ built-in components. Save 90% of time to build apps.
44+
- **Visual UI builder** with 120+ built-in components. Save 90% of time to build apps.
3845
- **Modules** for reusable (!) embedable component sets in the UI builder.
39-
- **Embed Lowcoder Apps as native parts of any Website** instead of iFrame (!). [Demo](https://lowcoder.cloud/about), [Docu](https://docs.lowcoder.cloud/lowcoder-documentation/lowcoder-extension/native-embed-sdk)
46+
- **Embed Lowcoder Apps as native parts of any Website** instead of iFrame (!). [Demo](http://demo-lowcoder.42web.io/ecommerce/), [Docu](https://docs.lowcoder.cloud/lowcoder-documentation/lowcoder-extension/native-embed-sdk)
4047
- **Video Meeting Components** to create your own individual Web-Meeting tool.
4148
- **Query Library** for reusable data queries of your data sources.
4249
- **Custom components** to develop own components and use them in the UI builder.
@@ -107,7 +114,3 @@ Accelerate the growth of Lowcoder and unleash its potential with your Sponsorshi
107114
[Be a Sponsor](https://github.com/sponsors/lowcoder-org)
108115

109116
Like ... [@Darkjamin](https://github.com/Darkjamin), [@spacegoats-io](https://github.com/spacegoats-io), [@Jomedya](https://github.com/Jomedya), [@CHSchuepfer](https://github.com/CHSchuepfer), Thank you very much!!
110-
111-
## Intro Video
112-
113-
[![Watch the video](https://i.ytimg.com/vi/s4ltAqS0hzM/maxresdefault.jpg?sqp=-oaymwEmCIAKENAF8quKqQMa8AEB-AH-CYAC0AWKAgwIABABGD0gSShyMA8=&rs=AOn4CLAlPOIFdtauythoBKNPXhi6XGwlDQ)](https://youtu.be/s4ltAqS0hzM?feature=shared)

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

+16
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,22 @@ export const createCustomer = async (subscriptionCustomer: LowcoderNewCustomer)
182182
}
183183
};
184184

185+
export const cleanupCustomer = async (subscriptionCustomer: LowcoderSearchCustomer) => {
186+
const apiBody = {
187+
path: "webhook/secure/cleanup-customer",
188+
data: subscriptionCustomer,
189+
method: "post",
190+
headers: lcHeaders
191+
};
192+
try {
193+
const result = await SubscriptionApi.secureRequest(apiBody, 15000);
194+
return result?.data as any;
195+
} catch (error) {
196+
console.error("Error creating customer:", error);
197+
throw error;
198+
}
199+
};
200+
185201
export const getProduct = async (productId : string) => {
186202
const apiBody = {
187203
path: "webhook/secure/get-product",

client/packages/lowcoder/src/comps/queries/queryComp.tsx

+4-19
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ QueryCompTmp = class extends QueryCompTmp {
363363
}
364364
if (action.type === CompActionTypes.EXECUTE_QUERY) {
365365
if (getReduceContext().disableUpdateState) return this;
366-
if(!action.args) action.args = this.children.variables.children.variables.toJsonValue().reduce((acc, curr) => Object.assign(acc, {[curr.key as string]:curr.value}), {});
366+
if(!action.args) action.args = this.children.variables.children.variables.toJsonValue().filter(kv => kv.key).reduce((acc, curr) => Object.assign(acc, {[curr.key as string]:curr.value}), {});
367367
action.args.$queryName = this.children.name.getView();
368368

369369
return this.executeQuery(action);
@@ -664,23 +664,6 @@ export const QueryComp = withExposingConfigs(QueryCompTmp, [
664664
new NameConfig("isFetching", trans("query.isFetchingExportDesc")),
665665
new NameConfig("runTime", trans("query.runTimeExportDesc")),
666666
new NameConfig("latestEndTime", trans("query.latestEndTimeExportDesc")),
667-
new DepsConfig(
668-
"variables",
669-
(children: any) => {
670-
return {data: children.variables.children.variables.node()};
671-
},
672-
(input) => {
673-
if (!input.data) {
674-
return undefined;
675-
}
676-
const newNode = Object.values(input.data)
677-
.filter((kvNode: any) => kvNode.key)
678-
.map((kvNode: any) => ({[kvNode.key]: kvNode.value}))
679-
.reduce((prev, obj) => ({...prev, ...obj}), {});
680-
return newNode;
681-
},
682-
trans("query.variables")
683-
),
684667
new NameConfig("triggerType", trans("query.triggerTypeExportDesc")),
685668
]);
686669

@@ -777,13 +760,15 @@ class QueryListComp extends QueryListTmpComp implements BottomResListComp {
777760

778761
const jsonData = originQuery.toJsonValue();
779762
//Regenerate variable header
763+
const newKeys:string[] = [];
780764
jsonData.variables?.variables?.forEach(kv => {
781765
const [prefix, _] = (kv.key as string).split(/(?=\d+$)/);
782766
let i=1, newName = "";
783767
do {
784768
newName = prefix + (i++);
785-
} while(editorState.checkRename("", newName));
769+
} while(editorState.checkRename("", newName) || newKeys.includes(newName));
786770
kv.key = newName;
771+
newKeys.push(newName);
787772
})
788773

789774
const newQueryName = this.genNewName(editorState);

client/packages/lowcoder/src/comps/queries/queryCompUtils.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@ export function toQueryView(params: FunctionProperty[]) {
2828
variables?: any;
2929
timeout: InstanceType<ParamsControlType>;
3030
}): Promise<QueryResult> => {
31-
console.log("toQueryView props", props, params);
3231
const { applicationId, isViewMode } = getGlobalSettings();
3332

34-
const mappedVariables = Object.keys(props.variables).map(key => ({key: `${props.args?.$queryName}.variables.${key}`, value: props.variables[key]}));
33+
const mappedVariables = Object.keys(props.variables).filter(k => k !== "$queryName").map(key => ({key: `${props.args?.$queryName}.variables.${key}`, value: props.variables[key] || ""}));
3534
let request: QueryExecuteRequest = {
3635
path: props.applicationPath,
3736
params: [

client/packages/lowcoder/src/pages/ApplicationV2/index.tsx

+15
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
TRASH_URL,
1111
NEWS_URL,
1212
ORG_HOME_URL,
13+
SUBSCRIPTION_SETTING,
1314
} from "constants/routesURL";
1415
import { getUser, isFetchingUser } from "redux/selectors/usersSelectors";
1516
import { useDispatch, useSelector } from "react-redux";
@@ -57,6 +58,7 @@ import { trans } from "../../i18n";
5758
import { foldersSelector } from "../../redux/selectors/folderSelector";
5859
import Setting from "pages/setting";
5960
import { Support } from "pages/support";
61+
import { Subscription } from "pages/setting/subscriptions"
6062
// import { TypographyText } from "../../components/TypographyText";
6163
// import { messageInstance } from "lowcoder-design/src/components/GlobalInstances";
6264
import { isEE } from "util/envUtils";
@@ -248,6 +250,19 @@ export default function ApplicationHome() {
248250
],
249251
} : { items: [] },
250252

253+
!supportSubscription && user.orgDev ? {
254+
items: [
255+
{
256+
text: <TabLabel>{trans("home.support")}</TabLabel>,
257+
routePath: SUBSCRIPTION_SETTING,
258+
routeComp: Subscription,
259+
routePathExact: false,
260+
icon: ({ selected, ...otherProps }) => selected ? <SupportIcon {...otherProps} width={"24px"}/> : <SupportIcon {...otherProps} width={"24px"}/>,
261+
mobileVisible: true,
262+
},
263+
],
264+
} : { items: [] },
265+
251266
supportSubscription && user.orgDev ? {
252267
items: [
253268
{

client/packages/lowcoder/src/redux/sagas/subscriptionSagas.ts

-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ import { Subscription, LowcoderSearchCustomer } from '@lowcoder-ee/constants/sub
1111
function* fetchSubscriptionsSaga(action: ReturnType<typeof fetchSubscriptionsAction>) {
1212
try {
1313
const user: User = yield select(getUser);
14-
const currentUser: CurrentUser = yield select(getCurrentUser);
1514
const orgID = user.currentOrgId;
16-
const domain = `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}`;
1715
const deploymentId: string = yield select(getDeploymentId);
1816

1917
const subscriptionSearchCustomer: LowcoderSearchCustomer = {

client/packages/lowcoder/src/util/context/SubscriptionContext.tsx

+4-32
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createCheckoutLink, createCustomer, getProducts, searchCustomer } from "@lowcoder-ee/api/subscriptionApi";
1+
import { createCheckoutLink, cleanupCustomer } from "@lowcoder-ee/api/subscriptionApi";
22
import { StripeCustomer, SubscriptionProduct, InitSubscriptionProducts, LowcoderSearchCustomer, LowcoderNewCustomer, Subscription } from "@lowcoder-ee/constants/subscriptionConstants";
33
import { getDeploymentId } from "@lowcoder-ee/redux/selectors/configSelectors";
44
import { getFetchSubscriptionsFinished, getSubscriptions, getSubscriptionsError } from "@lowcoder-ee/redux/selectors/subscriptionSelectors";
@@ -78,17 +78,6 @@ export const SubscriptionContextProvider = (props: {
7878
userId: user.id,
7979
};
8080

81-
const subscriptionNewCustomer: LowcoderNewCustomer = {
82-
hostname: domain,
83-
hostId: deploymentId,
84-
email: currentUser.email,
85-
orgId: orgID,
86-
userId: user.id,
87-
userName: user.username,
88-
type: admin,
89-
companyName: currentOrg?.name || "Unknown",
90-
};
91-
9281
useEffect(() => {
9382
// If products are already loaded in the outer context, reuse them
9483
if (productsLoaded) {
@@ -104,28 +93,11 @@ export const SubscriptionContextProvider = (props: {
10493
const initializeCustomer = async () => {
10594
if (existingCustomer) {
10695
setCustomer(existingCustomer);
96+
97+
cleanupCustomer(subscriptionSearchCustomer);
98+
10799
return;
108100
}
109-
110-
/* try {
111-
setIsCreatingCustomer(true);
112-
const subscriptionSearchCustomer: LowcoderSearchCustomer = {
113-
hostId: deploymentId,
114-
orgId: orgID,
115-
userId: user.id,
116-
};
117-
const existingCustomer = await searchCustomer(subscriptionSearchCustomer);
118-
if (existingCustomer) {
119-
setCustomer(existingCustomer);
120-
} else {
121-
const newCustomer = await createCustomer(subscriptionNewCustomer);
122-
setCustomer(newCustomer);
123-
}
124-
} catch (error) {
125-
setCustomerDataError(true);
126-
} finally {
127-
setIsCreatingCustomer(false);
128-
} */
129101
};
130102

131103
if (!customer && isCustomerInitializationComplete) {

docs/lowcoder-extension/opensource-contribution/develop-data-source-plugins.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Develop Data Source Plugins
22

3-
This document provides basic information and guides for developing data source plugins. Developers are highly welcomed to make contributions to [Lowcoder](https://github.com/Lowcoder-dev/Lowcoder)--the open source project.
3+
This document provides basic information and guides for developing data source plugins. Developers are highly welcomed to make contributions to [Lowcoder](https://github.com/lowcoder-org/lowcoder)--the open source project.
44

55
## Basics
66

@@ -12,7 +12,7 @@ A data source plugin is described by a **JavaScript Object** which mainly consis
1212
* Definition of the **Action list** for data source queries and the configuration form for each Action.
1313
* Definition of the **execution logic** for Actions.
1414

15-
Currently, all data source plugins are maintained in the `src/plugins` directory of the `node-service` project. Click to view [the project](https://github.com/Lowcoder-dev/Lowcoder/tree/develop/server/node-service), and you might take a quick look at the [S3 plugin](https://github.com/Lowcoder-dev/Lowcoder/tree/develop/server/node-service/src/plugins/s3).
15+
Currently, all data source plugins are maintained in the `src/plugins` directory of the `node-service` project. Click to view [the project](https://github.com/lowcoder-org/lowcoder/tree/main/server/node-service), and you might take a quick look at the [S3 plugin](https://github.com/lowcoder-org/lowcoder/tree/main/server/node-service/src/plugins/s3).
1616

1717
## Overall definition of a plugin
1818

@@ -268,7 +268,7 @@ Due to various reasons, the generated plugin code needs to be correctly validate
268268

269269
## Testing
270270

271-
Necessary testing should be done before publishing the plugin. Testing a data source plugin requires a backend environment. You can start a local environment by following the documentation [Start a local backend server](https://github.com/Lowcoder-dev/Lowcoder/tree/develop/client#readme) and test the data source plugin in following aspects:
271+
Necessary testing should be done before publishing the plugin. Testing a data source plugin requires a backend environment. You can start a local environment by following the documentation [Start a local backend server](https://github.com/lowcoder-org/lowcoder/tree/main/server/api-service#readme) and test the data source plugin in following aspects:
272272

273273
1. Make sure the data source plugin has been added to the plugin list in the file `src/plugins/index.ts`.
274274
2. Start the node-service server in the `node-service` directory by executing `yarn dev`.
@@ -292,4 +292,4 @@ You can then use the data source plugin just developed in this environment.
292292

293293
## What's next
294294

295-
Congrats! After testing the data source plugin, you can submit a [Pull Request](https://github.com/Lowcoder-dev/Lowcoder/pulls) now.
295+
Congrats! After testing the data source plugin, you can submit a [Pull Request](https://github.com/lowcoder-org/lowcoder/pulls) now.

docs/setup-and-run/self-hosting/heroku.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## Deploy
44

55
1. [Sign up](https://signup.heroku.com/) for a new Heroku account, or [log in](https://id.heroku.com/login) to get started.
6-
2. Click to start Heroku [one-click deployment](https://heroku.com/deploy?template=https://github.com/Lowcoder-dev/Lowcoder).
6+
2. Click to start Heroku [one-click deployment](https://heroku.com/deploy?template=https://github.com/lowcoder-org/lowcoder).
77
3. Set the **App name** which will be part of the app URL later, and choose a region.
88
4. (Not required) Fill in the **Config Vars** according to the descriptions. These are all optional variables used for environment-specific configuration. You can skip this step and manage environment variables later.
99
5. Click the **Deploy app** button.

server/api-service/lowcoder-plugins/oraclePlugin/pom.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
<!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc6 -->
3232
<dependency>
3333
<groupId>com.oracle.database.jdbc</groupId>
34-
<artifactId>ojdbc6</artifactId>
35-
<version>11.2.0.4</version>
34+
<artifactId>ojdbc11</artifactId>
35+
<version>23.7.0.25.01</version>
3636
</dependency>
3737
<dependency>
3838
<groupId>org.testcontainers</groupId>

0 commit comments

Comments
 (0)