Skip to content

Improving Height Calculations #1535

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,32 @@
<p>
Create software applications (internal and customer-facing!) and Meeting/Collaboration tools for your Company and your Customers with minimal coding experience.
</p>
<h3 style="margin-top: 0">Lowcoder is the best Retool, Appsmith or Tooljet Alternative.</h3>
<h3 style="margin-top: 0">We think, Lowcoder is simply better than Retool, Appsmith Tooljet, Outsystems or Mendix.</h3>
</div>
---

<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"/>

## 🎥 Lowcoder Intro Video
<div align="center">
<a href="https://www.youtube.com/watch?v=AQo0iFWUWiU" target="_blank">
<img src="https://img.youtube.com/vi/AQo0iFWUWiU/maxresdefault.jpg" alt="Lowcoder Intro Video" width="100%">
</a>
<p><i>Click the image above to watch the video on YouTube</i> 📺</p>
</div>

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

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

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.

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.
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".

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

## 🪄 Features
- **Visual UI builder** with 100+ built-in components. Save 90% of time to build apps.
- **Visual UI builder** with 120+ built-in components. Save 90% of time to build apps.
- **Modules** for reusable (!) embedable component sets in the UI builder.
- **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)
- **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)
- **Video Meeting Components** to create your own individual Web-Meeting tool.
- **Query Library** for reusable data queries of your data sources.
- **Custom components** to develop own components and use them in the UI builder.
Expand Down Expand Up @@ -107,7 +114,3 @@ Accelerate the growth of Lowcoder and unleash its potential with your Sponsorshi
[Be a Sponsor](https://github.com/sponsors/lowcoder-org)

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!!

## Intro Video

[![Watch the video](https://i.ytimg.com/vi/s4ltAqS0hzM/maxresdefault.jpg?sqp=-oaymwEmCIAKENAF8quKqQMa8AEB-AH-CYAC0AWKAgwIABABGD0gSShyMA8=&rs=AOn4CLAlPOIFdtauythoBKNPXhi6XGwlDQ)](https://youtu.be/s4ltAqS0hzM?feature=shared)
16 changes: 16 additions & 0 deletions client/packages/lowcoder/src/api/subscriptionApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,22 @@ export const createCustomer = async (subscriptionCustomer: LowcoderNewCustomer)
}
};

export const cleanupCustomer = async (subscriptionCustomer: LowcoderSearchCustomer) => {
const apiBody = {
path: "webhook/secure/cleanup-customer",
data: subscriptionCustomer,
method: "post",
headers: lcHeaders
};
try {
const result = await SubscriptionApi.secureRequest(apiBody, 15000);
return result?.data as any;
} catch (error) {
console.error("Error creating customer:", error);
throw error;
}
};

export const getProduct = async (productId : string) => {
const apiBody = {
path: "webhook/secure/get-product",
Expand Down
23 changes: 4 additions & 19 deletions client/packages/lowcoder/src/comps/queries/queryComp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ QueryCompTmp = class extends QueryCompTmp {
}
if (action.type === CompActionTypes.EXECUTE_QUERY) {
if (getReduceContext().disableUpdateState) return this;
if(!action.args) action.args = this.children.variables.children.variables.toJsonValue().reduce((acc, curr) => Object.assign(acc, {[curr.key as string]:curr.value}), {});
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}), {});
action.args.$queryName = this.children.name.getView();

return this.executeQuery(action);
Expand Down Expand Up @@ -664,23 +664,6 @@ export const QueryComp = withExposingConfigs(QueryCompTmp, [
new NameConfig("isFetching", trans("query.isFetchingExportDesc")),
new NameConfig("runTime", trans("query.runTimeExportDesc")),
new NameConfig("latestEndTime", trans("query.latestEndTimeExportDesc")),
new DepsConfig(
"variables",
(children: any) => {
return {data: children.variables.children.variables.node()};
},
(input) => {
if (!input.data) {
return undefined;
}
const newNode = Object.values(input.data)
.filter((kvNode: any) => kvNode.key)
.map((kvNode: any) => ({[kvNode.key]: kvNode.value}))
.reduce((prev, obj) => ({...prev, ...obj}), {});
return newNode;
},
trans("query.variables")
),
new NameConfig("triggerType", trans("query.triggerTypeExportDesc")),
]);

Expand Down Expand Up @@ -777,13 +760,15 @@ class QueryListComp extends QueryListTmpComp implements BottomResListComp {

const jsonData = originQuery.toJsonValue();
//Regenerate variable header
const newKeys:string[] = [];
jsonData.variables?.variables?.forEach(kv => {
const [prefix, _] = (kv.key as string).split(/(?=\d+$)/);
let i=1, newName = "";
do {
newName = prefix + (i++);
} while(editorState.checkRename("", newName));
} while(editorState.checkRename("", newName) || newKeys.includes(newName));
kv.key = newName;
newKeys.push(newName);
})

const newQueryName = this.genNewName(editorState);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ export function toQueryView(params: FunctionProperty[]) {
variables?: any;
timeout: InstanceType<ParamsControlType>;
}): Promise<QueryResult> => {
console.log("toQueryView props", props, params);
const { applicationId, isViewMode } = getGlobalSettings();

const mappedVariables = Object.keys(props.variables).map(key => ({key: `${props.args?.$queryName}.variables.${key}`, value: props.variables[key]}));
const mappedVariables = Object.keys(props.variables).filter(k => k !== "$queryName").map(key => ({key: `${props.args?.$queryName}.variables.${key}`, value: props.variables[key] || ""}));
let request: QueryExecuteRequest = {
path: props.applicationPath,
params: [
Expand Down
15 changes: 15 additions & 0 deletions client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
TRASH_URL,
NEWS_URL,
ORG_HOME_URL,
SUBSCRIPTION_SETTING,
} from "constants/routesURL";
import { getUser, isFetchingUser } from "redux/selectors/usersSelectors";
import { useDispatch, useSelector } from "react-redux";
Expand Down Expand Up @@ -57,6 +58,7 @@ import { trans } from "../../i18n";
import { foldersSelector } from "../../redux/selectors/folderSelector";
import Setting from "pages/setting";
import { Support } from "pages/support";
import { Subscription } from "pages/setting/subscriptions"
// import { TypographyText } from "../../components/TypographyText";
// import { messageInstance } from "lowcoder-design/src/components/GlobalInstances";
import { isEE } from "util/envUtils";
Expand Down Expand Up @@ -248,6 +250,19 @@ export default function ApplicationHome() {
],
} : { items: [] },

!supportSubscription && user.orgDev ? {
items: [
{
text: <TabLabel>{trans("home.support")}</TabLabel>,
routePath: SUBSCRIPTION_SETTING,
routeComp: Subscription,
routePathExact: false,
icon: ({ selected, ...otherProps }) => selected ? <SupportIcon {...otherProps} width={"24px"}/> : <SupportIcon {...otherProps} width={"24px"}/>,
mobileVisible: true,
},
],
} : { items: [] },

supportSubscription && user.orgDev ? {
items: [
{
Expand Down
2 changes: 0 additions & 2 deletions client/packages/lowcoder/src/redux/sagas/subscriptionSagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ import { Subscription, LowcoderSearchCustomer } from '@lowcoder-ee/constants/sub
function* fetchSubscriptionsSaga(action: ReturnType<typeof fetchSubscriptionsAction>) {
try {
const user: User = yield select(getUser);
const currentUser: CurrentUser = yield select(getCurrentUser);
const orgID = user.currentOrgId;
const domain = `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}`;
const deploymentId: string = yield select(getDeploymentId);

const subscriptionSearchCustomer: LowcoderSearchCustomer = {
Expand Down
36 changes: 4 additions & 32 deletions client/packages/lowcoder/src/util/context/SubscriptionContext.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createCheckoutLink, createCustomer, getProducts, searchCustomer } from "@lowcoder-ee/api/subscriptionApi";
import { createCheckoutLink, cleanupCustomer } from "@lowcoder-ee/api/subscriptionApi";
import { StripeCustomer, SubscriptionProduct, InitSubscriptionProducts, LowcoderSearchCustomer, LowcoderNewCustomer, Subscription } from "@lowcoder-ee/constants/subscriptionConstants";
import { getDeploymentId } from "@lowcoder-ee/redux/selectors/configSelectors";
import { getFetchSubscriptionsFinished, getSubscriptions, getSubscriptionsError } from "@lowcoder-ee/redux/selectors/subscriptionSelectors";
Expand Down Expand Up @@ -78,17 +78,6 @@ export const SubscriptionContextProvider = (props: {
userId: user.id,
};

const subscriptionNewCustomer: LowcoderNewCustomer = {
hostname: domain,
hostId: deploymentId,
email: currentUser.email,
orgId: orgID,
userId: user.id,
userName: user.username,
type: admin,
companyName: currentOrg?.name || "Unknown",
};

useEffect(() => {
// If products are already loaded in the outer context, reuse them
if (productsLoaded) {
Expand All @@ -104,28 +93,11 @@ export const SubscriptionContextProvider = (props: {
const initializeCustomer = async () => {
if (existingCustomer) {
setCustomer(existingCustomer);

cleanupCustomer(subscriptionSearchCustomer);

return;
}

/* try {
setIsCreatingCustomer(true);
const subscriptionSearchCustomer: LowcoderSearchCustomer = {
hostId: deploymentId,
orgId: orgID,
userId: user.id,
};
const existingCustomer = await searchCustomer(subscriptionSearchCustomer);
if (existingCustomer) {
setCustomer(existingCustomer);
} else {
const newCustomer = await createCustomer(subscriptionNewCustomer);
setCustomer(newCustomer);
}
} catch (error) {
setCustomerDataError(true);
} finally {
setIsCreatingCustomer(false);
} */
};

if (!customer && isCustomerInitializationComplete) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Develop Data Source Plugins

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.
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.

## Basics

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

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).
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).

## Overall definition of a plugin

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

## Testing

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:
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:

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

## What's next

Congrats! After testing the data source plugin, you can submit a [Pull Request](https://github.com/Lowcoder-dev/Lowcoder/pulls) now.
Congrats! After testing the data source plugin, you can submit a [Pull Request](https://github.com/lowcoder-org/lowcoder/pulls) now.
2 changes: 1 addition & 1 deletion docs/setup-and-run/self-hosting/heroku.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Deploy

1. [Sign up](https://signup.heroku.com/) for a new Heroku account, or [log in](https://id.heroku.com/login) to get started.
2. Click to start Heroku [one-click deployment](https://heroku.com/deploy?template=https://github.com/Lowcoder-dev/Lowcoder).
2. Click to start Heroku [one-click deployment](https://heroku.com/deploy?template=https://github.com/lowcoder-org/lowcoder).
3. Set the **App name** which will be part of the app URL later, and choose a region.
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.
5. Click the **Deploy app** button.
Expand Down
4 changes: 2 additions & 2 deletions server/api-service/lowcoder-plugins/oraclePlugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
<!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc6 -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.4</version>
<artifactId>ojdbc11</artifactId>
<version>23.7.0.25.01</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
Expand Down
Loading