Merge pull request #8340 from ToolJet/platform/v10.x
* [docs]:update quickstart guide v2 (#8058) * revamp quickstart guide and add topics to ToolJet concepts * add new guides using floik * add new items to tooljet concepts * update writing custom code concept * make UI enhancements and update the getting started guide * update tooljet concepts and add new topics * merge with dev and misc enhancements * create render * enhance formatting in access values concept * updates to quickstart guide and concepts * fix proofreading errords and update docs * revert versions and doc settings * add platform overview page and fix issues with floik demo sizing * add padding to badges and update workflows screenshot * add latest docs to the previous version * remove versions to preview on render * remove old getting started guide from next and 2.25 * add homepage slug * [docs] git sync - docs v2.24 (#8078) * [docs] gitsync * [docs]git sync * updates after review * added flow diagram and use cases * changes after review * Update docs/docs/gitsync.md * note for workspace constants * Added docs v2.24.0 * bump version * [Imp] Auto-removing query params from redirect urls (While login to the application) (#8128) * add: added query params to logout urls * add: added support for sso login * fix: page handle not updated after rename * [fix] Rendering all apps inside a folder after the app rename. (#8133) * fix: rendering all apps inside a folder after app rename * fix: Breadcrumbs path not contains query params * [fix] Sometimes the workspace modal CTA is in disabled state even if the values are correct (#8299) * fix: sometimes the workspace modal CTA is in disabled state even if the values are accepted * fix: erorr message * Fix MariaDB connection issues (#8235) * Add default connection limit for mariadb test connection in backend * map connectionLimit to connection_limit * remove log * remove comments * fix: mariadbPool causes server crash in case of unknown db * fix: prev details getting replicated in next selected ds * Save button on Datasource changes not enabled (#8171) * fixes: disabled state of ds changes on header values * add check for editor headers * fix: constants resolution on saved datasources (#8223) * Fixed websocket unavailable issue when the user tries to release the version before the connection is established (#8305) * Revamp Global Data sources (#8274) * changes: listing of data sources * add: plugins to ds list * review fixes * fixes * fix: placeholder values for encrypted fields * fixes * review changes * added missing line (#8349) * Fix for handling 'go to app' event for previously added unreleased apps and new apps (#8169) * fix go to app event for unreleased apps * updates * fix: added 401 check (#8351) * [chore] Node-module vulnerabilities (#8226) * started working on node upgrade to 18.18.2 * testing ci * updated ci node version * updated action code * deleted all package-lock.json files * deleted and ovverrided some packages * deleted and fixed server & frontend vulnerabilities * updated firestore version * fix: ws type issue * fix: upgraded lerna version * regenerated package-lock.json files again * regenerated marketplace lock file * updated node version in other ci and docker files * update: lock file plugin side * updated the npm version in docker & ci files * removed unused imports from events file * removed dependency-review action * updated some packages * tried to go with current node-module of jest. had to upgrade * fix: deprecated function usage - ts-jest * fix: server directory lint issues * fixed login page issue after router-dom upgrade * updated import/no-unresolved rule to ignore import errors of react-loading-skeleton, react-spring packages * fix: cypress node version & package-lock issue * regenerated cli package-lock.json * fix: new webpack version might cause runtime issues (had issues with enterprise). lets use old version only * fix: form-data docker issue * removed comment * Modify failing test cases (#8372) * package-lock for marketplace (#8391) * Fixes UI and test connection issues (#8377) * fixes: testconnection bugs * fixes * revert: package-lock * add: new line * url redirect fix * Added test user on seeding (#8393) * Added test user on seeding * fix * fix * fix * Updated the cypress spec with node upgrade changes (#8405) * update cypress specs * update the data source count values --------- Co-authored-by: Karan Rathod <karan.altcampus@gmail.com> Co-authored-by: Shubhendra Singh Chauhan <withshubh@gmail.com> Co-authored-by: Kavin Venkatachalam <50441969+kavinvenkatachalam@users.noreply.github.com> Co-authored-by: Muhsin Shah C P <muhsinshah21@gmail.com> Co-authored-by: Anantshree Chandola <anantshreechandola23@gmail.com> Co-authored-by: vjaris42 <vjy239@gmail.com> Co-authored-by: Ajith KV <ajith.jaban@gmail.com> Co-authored-by: Mekhla Asopa <59684099+Mekhla-Asopa@users.noreply.github.com>
12
.github/workflows/ci.yml
vendored
|
|
@ -38,10 +38,10 @@ jobs:
|
|||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js 18.3.0
|
||||
- name: Use Node.js 18.18.2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
node-version: 18.18.2
|
||||
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v3
|
||||
|
|
@ -68,10 +68,10 @@ jobs:
|
|||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js 18.3.0
|
||||
- name: Use Node.js 18.18.2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
node-version: 18.18.2
|
||||
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v3
|
||||
|
|
@ -93,7 +93,7 @@ jobs:
|
|||
unit-test:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
container: node:18.3.0-buster
|
||||
container: node:18.18.2-buster
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
|
|
@ -131,7 +131,7 @@ jobs:
|
|||
e2e-test:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
container: node:18.3.0-buster
|
||||
container: node:18.18.2-buster
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
|
|
|
|||
2
.github/workflows/cypress-appbuilder.yml
vendored
|
|
@ -20,7 +20,7 @@ jobs:
|
|||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
node-version: 18.18.2
|
||||
|
||||
- name: Set up Docker
|
||||
uses: docker-practice/actions-setup-docker@master
|
||||
|
|
|
|||
2
.github/workflows/cypress-platform.yml
vendored
|
|
@ -20,7 +20,7 @@ jobs:
|
|||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
node-version: 18.18.2
|
||||
|
||||
- name: Set up Docker
|
||||
uses: docker-practice/actions-setup-docker@master
|
||||
|
|
|
|||
2
.nvmrc
|
|
@ -1 +1 @@
|
|||
v18.3.0
|
||||
v18.18.2
|
||||
2
.version
|
|
@ -1 +1 @@
|
|||
2.26.2
|
||||
2.27.0
|
||||
|
|
|
|||
12470
cli/package-lock.json
generated
|
|
@ -70,7 +70,7 @@ Cypress.Commands.add("apiCreateApp", (appName = "testApp") => {
|
|||
url: "http://localhost:3000/api/apps",
|
||||
headers: {
|
||||
"Tj-Workspace-Id": Cypress.env("workspaceId"),
|
||||
Cookie: `tj_auth_token=${cookie.value}`,
|
||||
Cookie: `tj_auth_token = ${cookie.value}`,
|
||||
},
|
||||
body: {
|
||||
created_at: "",
|
||||
|
|
@ -212,3 +212,27 @@ Cypress.Commands.add("userInviteApi", (userName, userEmail) => {
|
|||
});
|
||||
});
|
||||
});
|
||||
Cypress.Commands.add("addQueryApi", (queryName, query, dataQueryId) => {
|
||||
cy.getCookie("tj_auth_token").then((cookie) => {
|
||||
const headers = {
|
||||
"Tj-Workspace-Id": Cypress.env("workspaceId"),
|
||||
Cookie: `tj_auth_token=${cookie.value}`,
|
||||
};
|
||||
cy.request({
|
||||
method: "PATCH",
|
||||
url: `http://localhost:3000/api/data_queries/${dataQueryId}`,
|
||||
headers: headers,
|
||||
body: {
|
||||
name: queryName,
|
||||
options: {
|
||||
mode: "sql",
|
||||
transformationLanguage: "javascript",
|
||||
enableTransformation: false,
|
||||
query: query,
|
||||
},
|
||||
},
|
||||
}).then((patchResponse) => {
|
||||
expect(patchResponse.status).to.equal(200);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export const s3Text = {
|
|||
alertRegionIsMissing: "Region is missing",
|
||||
cypressAwsS3: "cypress-aws-s3",
|
||||
placeholderEnterAccessKey: "Enter access key",
|
||||
placeholderEnterSecretKey: "Enter secret key",
|
||||
placeholderEnterSecretKey: "**************",
|
||||
labelRegion: "Region",
|
||||
region: "N. california",
|
||||
alertInvalidUrl: "Invalid URL",
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@ export const bigqueryText = {
|
|||
cypressBigQuery: "cypress-bigquery",
|
||||
errorInvalidEmailId:
|
||||
"The incoming JSON object does not contain a client_email field",
|
||||
placehlderPrivateKey: "Enter JSON private key for service account",
|
||||
placehlderPrivateKey: "**************",
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ export const dataSourceText = {
|
|||
allDataSources: "All data sources (41)",
|
||||
allDatabase: "Databases (17)",
|
||||
allApis: "APIs (20)",
|
||||
allCloudStorage: "Cloud Storage (4)",
|
||||
allCloudStorage: "Cloud Storages (4)",
|
||||
pluginsLabelAndCount: "Plugins (0)",
|
||||
|
||||
postgreSQL: "PostgreSQL",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ export const dynamoDbText = {
|
|||
accessKey: "Access key",
|
||||
placeHolderAccessKey: "Enter access key",
|
||||
secretKey: "Secret key",
|
||||
placeholderSecretKey: "Enter secret key",
|
||||
placeholderSecretKey: "**************",
|
||||
|
||||
errorMissingRegion: "Missing region in config",
|
||||
errorInvalidToken: "The security token included in the request is invalid.",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ export const firestoreText = {
|
|||
cypressFirestore: "cypress-firestore",
|
||||
labelPrivateKey: "Private key",
|
||||
privateKey: "Private key",
|
||||
placeholderPrivateKey: "Enter private key",
|
||||
placeholderPrivateKey: "**************",
|
||||
|
||||
errorGcpKeyCouldNotBeParsed:
|
||||
"GCP key could not be parsed as a valid JSON object",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ export const postgreSqlText = {
|
|||
allDataSources: "All data sources (43)",
|
||||
allDatabase: "Databases (19)",
|
||||
allApis: "APIs (20)",
|
||||
allCloudStorage: "Cloud Storage (4)",
|
||||
allCloudStorage: "Cloud Storages (4)",
|
||||
|
||||
postgreSQL: "PostgreSQL",
|
||||
labelHost: "Host",
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@ export const redisText = {
|
|||
|
||||
errorMaxRetries:
|
||||
'Reached the max retries per request limit (which is 1). Refer to "maxRetriesPerRequest" option for details.',
|
||||
errorPort: "Port should be >= 0 and < 65536. Received 108299.",
|
||||
errorPort: "Port should be >= 0 and < 65536. Received type number (108299).",
|
||||
errorInvalidUserOrPassword: "WRONGPASS invalid username-password pair",
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import {
|
|||
closeDSModal,
|
||||
deleteDatasource,
|
||||
addQuery,
|
||||
addQueryN,
|
||||
verifyValueOnInspector,
|
||||
} from "Support/utils/dataSource";
|
||||
import { dataSourceSelector } from "Selectors/dataSource";
|
||||
|
|
@ -38,12 +37,8 @@ describe("Global Datasource Manager", () => {
|
|||
cy.viewport(1200, 1300);
|
||||
});
|
||||
before(() => {
|
||||
cy.apiLogin();
|
||||
cy.apiCreateApp();
|
||||
cy.openApp();
|
||||
cy.renameApp(data.appName);
|
||||
cy.dragAndDropWidget("Table", 250, 250);
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.apiCreateApp(data.appName);
|
||||
addNewUserMW(data.firstName, data.email);
|
||||
logout();
|
||||
});
|
||||
|
|
@ -72,7 +67,7 @@ describe("Global Datasource Manager", () => {
|
|||
);
|
||||
cy.get(dataSourceSelector.querySearchBar)
|
||||
.invoke("attr", "placeholder")
|
||||
.should("eq", "Search Databases");
|
||||
.should("eq", "Search data sources");
|
||||
|
||||
cy.get(dataSourceSelector.apiLabelAndCount)
|
||||
.verifyVisibleElement("have.text", dataSourceText.allApis)
|
||||
|
|
@ -81,20 +76,14 @@ describe("Global Datasource Manager", () => {
|
|||
"have.text",
|
||||
" APIs"
|
||||
);
|
||||
cy.get(dataSourceSelector.querySearchBar)
|
||||
.invoke("attr", "placeholder")
|
||||
.should("eq", "Search APIs");
|
||||
|
||||
cy.get(dataSourceSelector.cloudStorageLabelAndCount)
|
||||
.verifyVisibleElement("have.text", dataSourceText.allCloudStorage)
|
||||
.click();
|
||||
cy.get(commonSelectors.breadcrumbPageTitle).verifyVisibleElement(
|
||||
"have.text",
|
||||
" Cloud Storage"
|
||||
" Cloud Storages"
|
||||
);
|
||||
cy.get(dataSourceSelector.querySearchBar)
|
||||
.invoke("attr", "placeholder")
|
||||
.should("eq", "Search Cloud Storage");
|
||||
|
||||
cy.get(dataSourceSelector.pluginsLabelAndCount)
|
||||
.verifyVisibleElement("have.text", dataSourceText.pluginsLabelAndCount)
|
||||
|
|
@ -103,9 +92,6 @@ describe("Global Datasource Manager", () => {
|
|||
"have.text",
|
||||
" Plugins"
|
||||
);
|
||||
cy.get(dataSourceSelector.querySearchBar)
|
||||
.invoke("attr", "placeholder")
|
||||
.should("eq", "Search Plugins");
|
||||
|
||||
cy.get('[data-cy="added-ds-label"]').should(($el) => {
|
||||
expect($el.contents().first().text().trim()).to.eq("Data sources added");
|
||||
|
|
@ -178,6 +164,7 @@ describe("Global Datasource Manager", () => {
|
|||
|
||||
deleteDatasource(`cypress-${data.dsName1}-postgresql1`);
|
||||
});
|
||||
|
||||
it("Should verify the Datasource connection and query creation using global data source", () => {
|
||||
selectAndAddDataSource(
|
||||
"databases",
|
||||
|
|
@ -198,10 +185,7 @@ describe("Global Datasource Manager", () => {
|
|||
);
|
||||
cy.wait("@datasource");
|
||||
|
||||
cy.get(commonSelectors.globalDataSourceIcon).click();
|
||||
cy.get(commonSelectors.dashboardIcon).click();
|
||||
navigateToAppEditor(data.appName);
|
||||
|
||||
cy.openApp();
|
||||
pinInspector();
|
||||
|
||||
addQuery(
|
||||
|
|
@ -223,24 +207,22 @@ describe("Global Datasource Manager", () => {
|
|||
.should("be.visible")
|
||||
.and("have.text", "+ Add new Data source");
|
||||
cy.get(".p-2 > .tj-base-btn").click();
|
||||
cy.get('[data-cy="databases-datasource-button"]').should("be.visible");
|
||||
|
||||
selectAndAddDataSource(
|
||||
"databases",
|
||||
dataSourceText.postgreSQL,
|
||||
data.dsName2
|
||||
cy.apiCreateGDS(
|
||||
"http://localhost:3000/api/v2/data_sources",
|
||||
`cypress-${data.dsName2}-postgresql`,
|
||||
"postgresql",
|
||||
[
|
||||
{ key: "host", value: Cypress.env("pg_host") },
|
||||
{ key: "port", value: 5432 },
|
||||
{ key: "database", value: Cypress.env("pg_user") },
|
||||
{ key: "username", value: Cypress.env("pg_user") },
|
||||
{ key: "password", value: Cypress.env("pg_password"), encrypted: true },
|
||||
{ key: "ssl_enabled", value: false, encrypted: false },
|
||||
{ key: "ssl_certificate", value: "none", encrypted: false },
|
||||
]
|
||||
);
|
||||
cy.intercept("GET", "api/v2/data_sources").as("datasource");
|
||||
fillConnectionForm(
|
||||
{
|
||||
Host: Cypress.env("pg_host"),
|
||||
Port: "5432",
|
||||
"Database Name": Cypress.env("pg_user"),
|
||||
Username: Cypress.env("pg_user"),
|
||||
Password: Cypress.env("pg_password"),
|
||||
},
|
||||
".form-switch"
|
||||
);
|
||||
cy.wait("@datasource");
|
||||
|
||||
navigateToManageGroups();
|
||||
cy.get(groupsSelector.appSearchBox).click();
|
||||
|
|
@ -265,7 +247,7 @@ describe("Global Datasource Manager", () => {
|
|||
it("Should validate the user's global data source permissions on apps created by admin", () => {
|
||||
logout();
|
||||
cy.apiLogin(data.email, "password");
|
||||
cy.visit('/my-workspace')
|
||||
cy.visit("/my-workspace");
|
||||
|
||||
cy.get(commonSelectors.globalDataSourceIcon).should("not.exist");
|
||||
|
||||
|
|
@ -281,8 +263,7 @@ describe("Global Datasource Manager", () => {
|
|||
cy.get(dataSourceSelector.queryCreateAndRunButton).click();
|
||||
verifyValueOnInspector("table_preview", "7 items ");
|
||||
|
||||
cy.get('[data-cy="show-ds-popover-button"]').click();
|
||||
addQueryN(
|
||||
addQuery(
|
||||
"student_data",
|
||||
`SELECT * FROM student_data;`,
|
||||
`cypress-${data.dsName2}-postgresql`
|
||||
|
|
@ -293,16 +274,14 @@ describe("Global Datasource Manager", () => {
|
|||
"student_data "
|
||||
);
|
||||
cy.get(dataSourceSelector.queryCreateAndRunButton).click();
|
||||
verifyValueOnInspector("student_data", "8 items ");
|
||||
verifyValueOnInspector("student_data", "4 items ");
|
||||
});
|
||||
it("Should verify the query creation and scope changing functionality.", () => {
|
||||
data.appName = `${fake.companyName}-App`;
|
||||
logout();
|
||||
cy.apiLogin(data.email, "password");
|
||||
cy.visit('/my-workspace')
|
||||
cy.apiCreateApp(data.appName);
|
||||
cy.openApp();
|
||||
cy.dragAndDropWidget("Table", 250, 250);
|
||||
|
||||
addQuery(
|
||||
"table_preview",
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ describe("Data sources", () => {
|
|||
);
|
||||
fillDataSourceTextField(
|
||||
"Key",
|
||||
"Enter your key",
|
||||
"**************",
|
||||
Cypress.env("cosmosdb_key")
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ describe("Data source Elasticsearch", () => {
|
|||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPassword,
|
||||
"Enter password",
|
||||
"**************",
|
||||
Cypress.env("elasticsearch_password")
|
||||
);
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ describe("Data source Elasticsearch", () => {
|
|||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPassword,
|
||||
"Enter password",
|
||||
"**************",
|
||||
"elasticsearch_password"
|
||||
);
|
||||
|
||||
|
|
@ -173,7 +173,7 @@ describe("Data source Elasticsearch", () => {
|
|||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPassword,
|
||||
"Enter password",
|
||||
"**************",
|
||||
Cypress.env("elasticsearch_password")
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ describe("Data sources", () => {
|
|||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPassword,
|
||||
"Enter password",
|
||||
"**************",
|
||||
Cypress.env("mariadb_password")
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ describe("Data sources MySql", () => {
|
|||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPassword,
|
||||
"Enter password",
|
||||
"**************",
|
||||
Cypress.env("mysql_password")
|
||||
);
|
||||
|
||||
|
|
@ -169,7 +169,7 @@ describe("Data sources MySql", () => {
|
|||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPassword,
|
||||
"Enter password",
|
||||
"**************",
|
||||
Cypress.env("mysql_password")
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ describe("Data sources", () => {
|
|||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPassword,
|
||||
"Enter password",
|
||||
"**************",
|
||||
Cypress.env("pg_password")
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ describe("Data source Redis", () => {
|
|||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPassword,
|
||||
"Enter password",
|
||||
"**************",
|
||||
Cypress.env("redis_password")
|
||||
);
|
||||
|
||||
|
|
@ -156,7 +156,7 @@ describe("Data source Redis", () => {
|
|||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPassword,
|
||||
"Enter password",
|
||||
"**************",
|
||||
"redis_password"
|
||||
);
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ describe("Data source Redis", () => {
|
|||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPassword,
|
||||
"Enter password",
|
||||
"**************",
|
||||
Cypress.env("redis_password")
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ describe("Data source SMTP", () => {
|
|||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPassword,
|
||||
"Enter password",
|
||||
"**************",
|
||||
Cypress.env("smtp_password")
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ describe("Data sources", () => {
|
|||
);
|
||||
cy.get('[data-cy="connection-alert-text"]').should(
|
||||
"have.text",
|
||||
"Network error. Could not reach Snowflake."
|
||||
"Invalid account. The specified value must be a valid subdomain string."
|
||||
);
|
||||
deleteDatasource(`cypress-${data.lastName}-snowflake`);
|
||||
});
|
||||
|
|
@ -124,7 +124,7 @@ describe("Data sources", () => {
|
|||
);
|
||||
fillDataSourceTextField(
|
||||
"Password",
|
||||
"Enter password",
|
||||
"**************",
|
||||
Cypress.env("snowflake_password")
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ describe("Data sources", () => {
|
|||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPassword,
|
||||
"Enter password",
|
||||
"**************",
|
||||
Cypress.env("sqlserver_password")
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -100,17 +100,20 @@ describe("Redirection error pages", () => {
|
|||
cy.visit(`http://localhost:8082/applications/${data.slug}`);
|
||||
cy.get(commonSelectors.modalHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"URL unavailable"
|
||||
"App URL Unavailable"
|
||||
);
|
||||
cy.get(commonSelectors.modalDescription).verifyVisibleElement(
|
||||
"have.text",
|
||||
"This URL is not accessible because it has not been released yet. Please either release it or contact admin for access."
|
||||
'The app URL is currently unavailable because the app has not been released. Please either release it or contact admin for access.'
|
||||
);
|
||||
cy.get('[data-cy="open-app-button"]').verifyVisibleElement("have.text", "Open app")
|
||||
|
||||
cy.get(commonSelectors.backToHomeButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Back to home page"
|
||||
);
|
||||
cy.url().should("eq", "http://localhost:8082/error/url-unavailable");
|
||||
|
||||
cy.url().should("eq", `http://localhost:8082/error/url-unavailable?appSlug=${data.slug}`);
|
||||
cy.get(commonSelectors.backToHomeButton).click();
|
||||
cy.get(commonSelectors.pageSectionHeader).should("be.visible");
|
||||
|
||||
|
|
@ -127,6 +130,8 @@ describe("Redirection error pages", () => {
|
|||
"have.text",
|
||||
"You don’t have access to this app. Kindly contact admin to know more."
|
||||
);
|
||||
// cy.get('[data-cy="open-app-button"]').verifyVisibleElement("have.text", "Open app")
|
||||
|
||||
cy.get(commonSelectors.backToHomeButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Back to home page"
|
||||
|
|
@ -157,17 +162,17 @@ describe("Redirection error pages", () => {
|
|||
cy.visit(`http://localhost:8082/applications/${data.slug}`);
|
||||
cy.get(commonSelectors.modalHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"URL unavailable"
|
||||
"App URL Unavailable"
|
||||
);
|
||||
cy.get(commonSelectors.modalDescription).verifyVisibleElement(
|
||||
"have.text",
|
||||
"This URL is not accessible because it has not been released yet. Please either release it or contact admin for access."
|
||||
'The app URL is currently unavailable because the app has not been released. Please either release it or contact admin for access.'
|
||||
);
|
||||
cy.get(commonSelectors.backToHomeButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Back to home page"
|
||||
);
|
||||
cy.url().should("eq", "http://localhost:8082/error/url-unavailable");
|
||||
cy.url().should("eq", `http://localhost:8082/error/url-unavailable?appSlug=${data.slug}`);
|
||||
cy.get(commonSelectors.backToHomeButton).click();
|
||||
cy.get(commonSelectors.pageSectionHeader).should("be.visible");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export const deleteComponentAndVerify = (widgetName) => {
|
|||
});
|
||||
cy.verifyToastMessage(
|
||||
`[class=go3958317564]`,
|
||||
"Component deleted! (⌘ + Z to undo)"
|
||||
"Component deleted! (ctrl + Z to undo)"
|
||||
);
|
||||
cy.notVisible(commonWidgetSelector.draggableWidget(widgetName));
|
||||
};
|
||||
|
|
|
|||
|
|
@ -72,33 +72,44 @@ export const closeDSModal = () => {
|
|||
});
|
||||
};
|
||||
|
||||
export const addQuery = (queryName, query, dbName) => {
|
||||
export const addQueryN = (queryName, query, dbName) => {
|
||||
cy.get("body").then(($body) => {
|
||||
if ($body.find('[data-cy="gds-querymanager-search-bar"]').length > 0) {
|
||||
cy.clearAndType('[data-cy="gds-querymanager-search-bar"]', `${dbName}`);
|
||||
}
|
||||
});
|
||||
cy.intercept("POST", "http://localhost:3000/api/data_queries").as(
|
||||
"createQuery"
|
||||
);
|
||||
|
||||
cy.get(`[data-cy="${dbName}-add-query-card"] > .text-truncate`).click();
|
||||
cy.get('[data-cy="query-rename-input"]').clear().type(queryName);
|
||||
cy.forceClickOnCanvas();
|
||||
|
||||
cy.get(dataSourceSelector.queryInputField)
|
||||
.realMouseDown({ position: "center" })
|
||||
.realType(" ");
|
||||
cy.get(dataSourceSelector.queryInputField).clearAndTypeOnCodeMirror(query);
|
||||
cy.get(dataSourceSelector.queryCreateAndRunButton).click();
|
||||
cy.wait("@createQuery").then((interception) => {
|
||||
const dataQueryId = interception.response.body.id;
|
||||
cy.visit("/my-workspace");
|
||||
cy.addQueryApi(queryName, query, dataQueryId);
|
||||
cy.openApp();
|
||||
});
|
||||
};
|
||||
|
||||
export const addQueryN = (queryName, query, dbName) => {
|
||||
export const addQuery = (queryName, query, dbName) => {
|
||||
cy.get('[data-cy="show-ds-popover-button"]').click();
|
||||
cy.get(".css-1rrkggf-Input").type(`${dbName}`);
|
||||
cy.intercept("POST", "http://localhost:3000/api/data_queries").as(
|
||||
"createQuery"
|
||||
);
|
||||
cy.contains(`[id*="react-select-"]`, dbName).click();
|
||||
|
||||
cy.get('[data-cy="query-rename-input"]').clear().type(queryName);
|
||||
|
||||
cy.get(dataSourceSelector.queryInputField)
|
||||
.realMouseDown({ position: "center" })
|
||||
.realType(" ");
|
||||
cy.get(dataSourceSelector.queryInputField).clearAndTypeOnCodeMirror(query);
|
||||
cy.get(dataSourceSelector.queryCreateAndRunButton).click();
|
||||
cy.wait("@createQuery").then((interception) => {
|
||||
const dataQueryId = interception.response.body.id;
|
||||
cy.visit("/my-workspace");
|
||||
cy.addQueryApi(queryName, query, dataQueryId);
|
||||
cy.openApp();
|
||||
});
|
||||
};
|
||||
|
||||
export const verifyValueOnInspector = (queryName, value) => {
|
||||
|
|
@ -119,4 +130,4 @@ export const verifyValueOnInspector = (queryName, value) => {
|
|||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
|
|||
6779
cypress-tests/package-lock.json
generated
|
|
@ -7,7 +7,7 @@ sudo apt-get -y install --no-install-recommends wget gnupg ca-certificates apt-u
|
|||
curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
nvm install 18.3.0
|
||||
nvm install 18.18.2
|
||||
sudo ln -s "$(which node)" /usr/bin/node
|
||||
sudo ln -s "$(which npm)" /usr/bin/npm
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ mv /tmp/.env ~/app/.env
|
|||
mv /tmp/setup_app ~/app/setup_app
|
||||
sudo chmod +x ~/app/setup_app
|
||||
|
||||
npm install -g npm@8.11.0
|
||||
npm install -g npm@9.8.1
|
||||
|
||||
# Building ToolJet app
|
||||
npm install -g @nestjs/cli
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# pull official base image
|
||||
FROM node:18.3.0-buster
|
||||
FROM node:18.18.2-buster
|
||||
|
||||
ENV NODE_ENV=development
|
||||
|
||||
RUN npm i -g npm@8.11.0
|
||||
RUN npm i -g npm@9.8.1
|
||||
|
||||
# set working directory
|
||||
WORKDIR /app
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# pull official base image
|
||||
FROM node:18.3.0-buster
|
||||
FROM node:18.18.2-buster
|
||||
|
||||
RUN npm i -g npm@8.11.0
|
||||
RUN npm i -g npm@9.8.1
|
||||
|
||||
# set working directory
|
||||
WORKDIR /app
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM node:18.3.0-buster AS builder
|
||||
FROM node:18.18.2-buster AS builder
|
||||
# Fix for JS heap limit allocation issue
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ COPY ./server/ ./server/
|
|||
RUN npm install -g @nestjs/cli
|
||||
RUN npm --prefix server run build
|
||||
|
||||
FROM node:18.3.0-buster
|
||||
FROM node:18.18.2-buster
|
||||
# copy postgrest executable
|
||||
COPY --from=postgrest/postgrest:v10.1.1.20221215 /bin/postgrest /bin
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
FROM node:18.3.0-buster AS builder
|
||||
FROM node:18.18.2-buster AS builder
|
||||
|
||||
# Fix for JS heap limit allocation issue
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
RUN npm i -g npm@8.11.0
|
||||
RUN npm i -g npm@9.8.1
|
||||
RUN mkdir -p /app
|
||||
|
||||
WORKDIR /app
|
||||
|
|
@ -42,12 +42,12 @@ RUN apt-get update -yq \
|
|||
&& apt-get clean -y
|
||||
|
||||
|
||||
RUN curl -O https://nodejs.org/dist/v18.3.0/node-v18.3.0-linux-x64.tar.xz \
|
||||
&& tar -xf node-v18.3.0-linux-x64.tar.xz \
|
||||
&& mv node-v18.3.0-linux-x64 /usr/local/lib/nodejs \
|
||||
RUN curl -O https://nodejs.org/dist/v18.18.2/node-v18.18.2-linux-x64.tar.xz \
|
||||
&& tar -xf node-v18.18.2-linux-x64.tar.xz \
|
||||
&& mv node-v18.18.2-linux-x64 /usr/local/lib/nodejs \
|
||||
&& echo 'export PATH="/usr/local/lib/nodejs/bin:$PATH"' >> /etc/profile.d/nodejs.sh \
|
||||
&& /bin/bash -c "source /etc/profile.d/nodejs.sh" \
|
||||
&& rm node-v18.3.0-linux-x64.tar.xz
|
||||
&& rm node-v18.18.2-linux-x64.tar.xz
|
||||
ENV PATH=/usr/local/lib/nodejs/bin:$PATH
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
FROM node:18.3.0-buster as builder
|
||||
FROM node:18.18.2-buster as builder
|
||||
|
||||
# Fix for JS heap limit allocation issue
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
RUN npm i -g npm@8.11.0
|
||||
RUN npm i -g npm@9.8.1
|
||||
RUN npm install -g @nestjs/cli
|
||||
|
||||
RUN mkdir -p /app
|
||||
|
|
@ -32,12 +32,12 @@ RUN apt-get update -yq \
|
|||
&& apt-get install -yq build-essential \
|
||||
&& apt-get clean -y
|
||||
|
||||
RUN curl -O https://nodejs.org/dist/v18.3.0/node-v18.3.0-linux-x64.tar.xz \
|
||||
&& tar -xf node-v18.3.0-linux-x64.tar.xz \
|
||||
&& mv node-v18.3.0-linux-x64 /usr/local/lib/nodejs \
|
||||
RUN curl -O https://nodejs.org/dist/v18.18.2/node-v18.18.2-linux-x64.tar.xz \
|
||||
&& tar -xf node-v18.18.2-linux-x64.tar.xz \
|
||||
&& mv node-v18.18.2-linux-x64 /usr/local/lib/nodejs \
|
||||
&& echo 'export PATH="/usr/local/lib/nodejs/bin:$PATH"' >> /etc/profile.d/nodejs.sh \
|
||||
&& /bin/bash -c "source /etc/profile.d/nodejs.sh" \
|
||||
&& rm node-v18.3.0-linux-x64.tar.xz
|
||||
&& rm node-v18.18.2-linux-x64.tar.xz
|
||||
ENV PATH=/usr/local/lib/nodejs/bin:$PATH
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# pull official base image
|
||||
FROM node:18.3.0-buster
|
||||
FROM node:18.18.2-buster
|
||||
RUN apt-get update && apt-get install -y postgresql-client freetds-dev libaio1 wget
|
||||
|
||||
# Install Instantclient Basic Light Oracle and Dependencies
|
||||
|
|
@ -19,7 +19,7 @@ WORKDIR /
|
|||
ENV NODE_ENV=development
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
RUN npm i -g npm@8.11.0
|
||||
RUN npm i -g npm@9.8.1
|
||||
RUN mkdir -p /app
|
||||
WORKDIR /app
|
||||
|
||||
|
|
|
|||
136
docs/docs/getting-started/platform-overview.md
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
---
|
||||
id: platform-overview
|
||||
title: Platform Overview
|
||||
slug: /
|
||||
---
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
<!-- ## What is ToolJet?
|
||||
|
||||
ToolJet is a fast, secure, and user-friendly development platform to build custom internal tools. ToolJet streamlines the development process with seamless integrations, robust security, and a comprehensive suite of app-building tools. -->
|
||||
|
||||
## What is ToolJet?
|
||||
|
||||
ToolJet is a low-code platform that enables developers to rapidly build and deploy custom internal tools. It has a drag-and-drop app builder with 45 pre-built components, so developers can create complex applications in minutes. ToolJet also connects to most popular data sources and APIs out of the box, and it has a group-based permission system for easy user access management. ToolJet also comes with a lot of other features, but for now, let’s build a basic ToolJet app.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
## How ToolJet Works:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{ border:'0', marginBottom:'15px', borderRadius:'5px', boxShadow: '0px 1px 3px rgba(0, 0, 0, 0.2)' }} className="screenshot-full" src="/img/platform-overview/platform-overview-v2.jpg" alt="Platform Overview" />
|
||||
</div>
|
||||
|
||||
**With ToolJet, you can streamline app development with 4 core steps:** <br/>
|
||||
|
||||
**Connect Data Sources**: Leverage ToolJet's robust integration features to connect with any data source. The platform supports seamless data integration across over 50 different applications, databases, and APIs.
|
||||
|
||||
**Design Stunning Interfaces**: Drag and drop UI components like Tables, Charts, Forms, and more build custom applications in minutes. Integrate these components with data sources and incorporate business logic through JavaScript or Python.
|
||||
|
||||
**Automate Complex Workflows**: Develop multi-step workflows in ToolJet to automate business processes. In addition to building and automating workflows, ToolJet allows for easy integration of these workflows within your applications.
|
||||
|
||||
**Secure and Manage**: Secure your internal tools with detailed permissions settings and audit logs. Maintain quality and consistency with version control, and keep track of performance with comprehensive observability tools.
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingBottom:'24px'}}>
|
||||
|
||||
Below is a detailed overview of ToolJet's key functionalities, demonstrating how ToolJet helps teams to build more with less effort and greater efficiency.
|
||||
|
||||
### Visual App Builder
|
||||
Enables the creation of visually appealing front-ends with a drag-and-drop interface and pre-built components.
|
||||
<!-- It simplifies the app-development process, making it accessible even for non-technical users. -->
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{ border:'0'}} className="screenshot-full" src="/img/platform-overview/app-builder.png" alt="App-Builder" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
### Integrations
|
||||
Offers seamless integration with a wide range of data sources, including over 50 applications, databases, and APIs.
|
||||
<!-- This feature facilitates easy data connectivity and aggregation from various systems. -->
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{ border:'0'}} className="screenshot-full" src="/img/platform-overview/integrations.png" alt="Integrations" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
### ToolJet Database
|
||||
A robust, scalable database solution built atop PostgreSQL. It allows for no-code database management, enabling users to build, manage, and scale databases effortlessly.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{ border:'0'}} className="screenshot-full" src="/img/platform-overview/tooljet-db.png" alt="ToolJet Database" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
### Workflow Automation
|
||||
Simplifies the automation of complex manual business processes, reducing the engineering effort required.
|
||||
<!-- This feature is particularly useful for streamlining enterprise workflows and improving operational efficiency. -->
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{ border:'0'}} className="screenshot-full" src="/img/platform-overview/workflows.png" alt="Workflows" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
### Enterprise-Grade Security
|
||||
Designed with advanced security features and a scalable infrastructure to meet the needs of enterprise teams.
|
||||
<!-- This ensures the protection of sensitive data and the reliability of the platform in handling large-scale applications. -->
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{ border:'0', borderRadius:'5px'}} className="screenshot-full" src="/img/platform-overview/security.png" alt="Security" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
### SSO Support
|
||||
|
||||
Single Sign-On (SSO) capabilities, supporting a variety of providers including Okta, Google, Azure AD, and OpenID Connect.
|
||||
<!-- This enhances user authentication and bolsters overall security. -->
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{ border:'0', borderRadius:'5px'}} className="screenshot-full" src="/img/platform-overview/sso.png" alt="SSO Support" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
### Multiple Environments
|
||||
Creation and management of multiple environments for efficient application lifecycle management, allowing different stages like development, testing, and production to be handled seamlessly.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{ border:'0', borderRadius:'5px'}} className="screenshot-full" src="/img/platform-overview/multi-environment.png" alt="SSO Support" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
### Multiplayer Editing
|
||||
|
||||
Multiple users can collaboratively work on app development in real-time. Simultaneous edits and contributions from different team members streamlines the development process and fosters a more dynamic and interactive workspace
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{ border:'0', marginBottom: '15px' }} className="screenshot-full" src="/img/platform-overview/multiplayer.png" alt="Multiplayer Editing" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
Whether you're a seasoned developer or a business professional, ToolJet stands out as a comprehensive solution to fast-track your internal tool development process.
|
||||
236
docs/docs/getting-started/quickstart-guide.md
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
---
|
||||
id: quickstart-guide
|
||||
title: Quickstart Guide
|
||||
---
|
||||
|
||||
<!-- <div style={{paddingTop:'24px', paddingBottom:'24px'}}> -->
|
||||
|
||||
|
||||
This Quickstart Guide will show you how to create an employee directory application in minutes using ToolJet. This app will let you track and update employee information with a beautiful user interface. Here are the step-by-step instructions:
|
||||
|
||||
**[1. Create Your First Application](#1-create-your-first-application)** <br/>
|
||||
**[2. Create Employee Database](#2-create-employee-database)** <br/>
|
||||
**[3. Integrate Data](#3-integrate-data)** <br/>
|
||||
**[4. List Employees](#4-list-employees)** <br/>
|
||||
**[5. Add New Employee](#5-add-new-employee)** <br/>
|
||||
**[6. Preview, Release And Share](#6-preview-release-and-share)** <br/>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
<!-- </div> -->
|
||||
|
||||
### 1. Create Your First Application
|
||||
|
||||
Once you have created an account with ToolJet, go to the dashboard and click on the Create new app button. Name your application as "Employee Directory". You are ready to design your application now.
|
||||
|
||||
<div style={{marginBottom:'15px', height:'397px', }}>
|
||||
<iframe
|
||||
className="screenshot-full"
|
||||
src="https://www.floik.com/embed/e4f537b5-7b36-4760-9a52-caefc659a90b/b4059c71-812d-407b-9d4a-fc598eac6260-flo.html"
|
||||
style={{width: '100%', height: '100%', border: '0'}}
|
||||
frameborder='0'
|
||||
allowfullscreen="allowfullscreen"
|
||||
webkitallowfullscreen
|
||||
mozallowfullscreen
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
Click and drag a **[Table](/docs/widgets/table)** component to the canvas.
|
||||
|
||||
<div style={{marginBottom:'15px', height:'397px', }}>
|
||||
<iframe
|
||||
className="screenshot-full"
|
||||
src="https://www.floik.com/embed/e4f537b5-7b36-4760-9a52-caefc659a90b/ee10d678-63fb-4fd5-a217-835ddd0898e9-flo.html"
|
||||
style={{width: '100%', height: '100%', border: '0'}}
|
||||
frameborder="0"
|
||||
allowfullscreen="allowfullscreen"
|
||||
webkitallowfullscreen
|
||||
mozallowfullscreen
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
Optionally, you can style the Table by **[adjusting its styling properties](/docs/tooljet-concepts/what-are-components#customizing-components)** and create a header by placing **[Text](/docs/widgets/text)** components over a **[Container](/docs/widgets/container)** component and styling them.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{marginBottom:'15px', borderRadius: '6px' }} className="screenshot-full" src="/img/quickstart-guide/header-design-v2.png" alt="Database Preview" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
### 2. Create Employee Database
|
||||
|
||||
Now, create a new table in **[ToolJet’s Database](/docs/tooljet-database/)** to store employee records. Name the table employees and add the following columns: `firstname`, `lastname`, `email`, `phone`, `department`, `position`, `joining`, and `status`. Also, add a few employee records in the table.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{marginBottom:'15px'}} className="screenshot-full" src="/img/quickstart-guide/create-database-v2.png" alt="Database Preview" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
|
||||
### 3. Integrate Data
|
||||
|
||||
To display employees in the application, we first need to fetch data from the database using a query:
|
||||
- Click on the Add button in the **[Query Panel](/docs/app-builder/query-panel/)**, select ToolJet Database
|
||||
- Rename the query to `getEmployees`
|
||||
- Choose `employees` as Table name, List rows as Operations
|
||||
- Toggle Run this query on application load? to automatically run the query when the app starts
|
||||
- Click on Run to fetch data
|
||||
|
||||
<div style={{marginBottom:'15px', height:'397px', }}>
|
||||
<iframe
|
||||
className="screenshot-full"
|
||||
src="https://www.floik.com/embed/e4f537b5-7b36-4760-9a52-caefc659a90b/de162474-7861-4275-bc8a-da275517908c-flo.html"
|
||||
style={{width: '100%', height: '100%', border: '0'}}
|
||||
frameborder="0"
|
||||
allowfullscreen="allowfullscreen"
|
||||
webkitallowfullscreen
|
||||
mozallowfullscreen
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
Click on the Preview button to see a preview of the fetched data.
|
||||
|
||||
<div style={{marginBottom:'15px', height:'397px', }}>
|
||||
<iframe
|
||||
className="screenshot-full"
|
||||
src="https://www.floik.com/embed/e4f537b5-7b36-4760-9a52-caefc659a90b/b01e837b-b1b0-468e-a4e3-4b8064ba2e56-flo.html"
|
||||
style={{width: '100%', height: '100%', border: '0'}}
|
||||
frameborder="0"
|
||||
allowfullscreen="allowfullscreen"
|
||||
webkitallowfullscreen
|
||||
mozallowfullscreen
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
### 4. List Employees
|
||||
|
||||
Now, we need to bind the data returned by the `getEmployees` query above with the Table created in Step 1. Click on the Table component to open its configuration panel on the right. Under the `Data` property, paste the below code:
|
||||
|
||||
```js
|
||||
{{queries.getEmployees.data}}
|
||||
```
|
||||
<div style={{marginBottom:'15px', height:'397px', }}>
|
||||
<iframe
|
||||
className="screenshot-full"
|
||||
src="https://www.floik.com/embed/e4f537b5-7b36-4760-9a52-caefc659a90b/f780f25f-0832-4a06-86f2-46864b891db1-flo.html"
|
||||
style={{width: '100%', height: '100%', border: '0'}}
|
||||
frameborder="0"
|
||||
allowfullscreen="allowfullscreen"
|
||||
webkitallowfullscreen
|
||||
mozallowfullscreen
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
Now the Table component is filled with the data returned by the `getEmployees` query.
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
### 5. Add New Employee
|
||||
|
||||
Next step is to create a way to add data for new employees.
|
||||
|
||||
- Click on Add in the query panel, select ToolJet Database
|
||||
- Select `employees` as Table name, Create row as Operations
|
||||
- Rename the query to `addEmployee`
|
||||
- Click Add Column to add required columns
|
||||
- Enter code below for **email** and **firstname** column keys:
|
||||
|
||||
```js
|
||||
{{components.table1.newRows[0].email}}
|
||||
{{components.table1.newRows[0].firstname}}
|
||||
...
|
||||
```
|
||||
|
||||
Frame all the remaining keys in the same format.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px', marginBottom:'15px', borderRadius: '6px' }} className="screenshot-full" src="/img/quickstart-guide/add-employee-query-v2.png" alt="Add Employee Query" />
|
||||
</div>
|
||||
|
||||
Let's continue working on this query. The data needs to reload once this query runs since we want the Table component to be populated with the updated data. Follow the below steps to run the `getEmployees` query after the `addEmployee` query is completed.
|
||||
|
||||
- Scroll down and click on New event handler
|
||||
- Select Query Success as Event and Run Query as Action
|
||||
- Select `getEmployees` as Query
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px', marginBottom:'15px', borderRadius: '6px'}} className="screenshot-full" src="/img/quickstart-guide/reload-data-v2.png" alt="Reload Table Data" />
|
||||
</div>
|
||||
|
||||
We are now ready with a query that will allow us to add new employee data. Let's link this query to a button.
|
||||
|
||||
In the bottom-right corner of the Table component, there is a `+`/Add new row button. Follow the below steps to run the `addEmployee` query on click of the `+`/Add new row button:
|
||||
- Click on the Table component, go to Events in configuration panel and add a New event handler
|
||||
- Choose Add new rows as Event, Run Query as Action
|
||||
- Select `addEmployee` as the Query
|
||||
|
||||
<div style={{marginBottom:'15px', height:'397px', }}>
|
||||
<iframe
|
||||
className="screenshot-full"
|
||||
src="https://www.floik.com/embed/e4f537b5-7b36-4760-9a52-caefc659a90b/e53c2517-41f1-4ee0-a5c0-59f5c3622c4a-flo.html"
|
||||
style={{width: '100%', height: '100%', border: '0'}}
|
||||
frameborder="0"
|
||||
allowfullscreen="allowfullscreen"
|
||||
webkitallowfullscreen
|
||||
mozallowfullscreen
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
Now if you click on the `+`/Add new row button, enter the employee data and click on Save. The `addEmployee` query will run and the data will be written to the `employees` table in the ToolJet Database.
|
||||
|
||||
<div style={{marginBottom:'15px', height:'397px', }}>
|
||||
<iframe
|
||||
className="screenshot-full"
|
||||
src="https://www.floik.com/embed/e4f537b5-7b36-4760-9a52-caefc659a90b/a33b3f9d-a33d-49c3-a031-db09b0202cfd-flo.html"
|
||||
style={{width: '100%', height: '100%', border: '0'}}
|
||||
frameborder="0"
|
||||
allowfullscreen="allowfullscreen"
|
||||
webkitallowfullscreen
|
||||
mozallowfullscreen
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
### 6. Preview, Release And Share
|
||||
|
||||
The preview, release and share buttons are on the top-right of the App-Builder.
|
||||
|
||||
- Click on the Preview on the top-right of app builder to review how your application is coming along while development.
|
||||
- Once the development is done and you are ready to use the application, click on Release button to deploy the app.
|
||||
- Finally, share your application with your end users using Share button
|
||||
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{marginBottom:'15px'}} className="screenshot-full" src="/img/quickstart-guide/preview-share-v2.png" alt="Preview And Share" />
|
||||
</div>
|
||||
|
||||
Congratulations! You've successfully built an employee directory application and, in the process, covered the fundamentals of ToolJet.
|
||||
|
||||
To learn more about how ToolJet works, explore the subjects covered in **[ToolJet Concepts](/docs/tooljet-concepts/what-are-components)**.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
252
docs/docs/gitsync.md
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
---
|
||||
id: gitsync
|
||||
title: GitSync
|
||||
---
|
||||
|
||||
GitSync feature allows users to synchronize the applications on their workspace with a git repository. GitSync feature simplifies the process of managing and version controlling your applications on ToolJet.
|
||||
|
||||
## Overview
|
||||
|
||||
ToolJet applications can be synchronized with a Git repository, offering the flexibility to tailor your application development and deployment processes across various environments while aligning with best practices for the application development lifecycle.
|
||||
|
||||
### Key Use-Cases:
|
||||
|
||||
#### Backup of Apps
|
||||
|
||||
GitSync provides a straightforward solution for creating backups of your applications. By pushing changes to a Git repository, users can ensure a secure and versioned history of their application. This serves as a reliable backup mechanism, safeguarding against accidental application/version deletion or corruption.
|
||||
|
||||
#### Environment Migration
|
||||
|
||||
Facilitating the movement of applications across different ToolJet deployments (e.g., from development to staging to production), GitSync acts as a pivotal tool for environment migration. Users can effortlessly transfer their applications across environments by pushing changes to a Git repository.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/envmigration.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
|
||||
## Setting up GitSyncing with GitHub
|
||||
|
||||
:::caution
|
||||
- ToolJet support git repo managers like GitHub, GitLab, Bitbucket, AWS CodeCommit, and Azure Repos.
|
||||
- Only Admins have the permission to configure the GitSync feature on workspace level.
|
||||
:::
|
||||
|
||||
### Step 1: Create a new repository on GitHub
|
||||
|
||||
Create a new repository on GitHub. The repository can be public or private. You can also use an existing repository. Make sure that the repository is empty.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/github1.png" alt="GitHub" />
|
||||
|
||||
</div>
|
||||
|
||||
### Step 2: Obtain the repository URL
|
||||
|
||||
Obtain the **SSH URL** of the repository. When a repository is created, GitHub shows a screen with the repository URL. If the repository is already created, you can obtain the URL by clicking on the **Clone or download** button.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/github2.png" alt="GitHub" />
|
||||
|
||||
</div>
|
||||
|
||||
### Step 3: Configure the GitSync feature on ToolJet
|
||||
|
||||
Go to the **Workspace settings**, and click on the **Configure git** tab.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/gitsync.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
Enter the **SSH URL** of the repository (obtained in Step 2) in the **Git repository URL** field. Click on the **Generate SSH key** button, and copy the SSH key that is generated. The SSH key is used to authenticate ToolJet with the repository.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/git2.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
|
||||
### Step 4: Deploy the SSH key to GitHub repository
|
||||
|
||||
Go to the **Settings** tab of the GitHub repository that you created in Step 1, and click on the **Deploy keys** tab. Click on the **Add deploy key** button.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/github3.png" alt="GitHub" />
|
||||
|
||||
</div>
|
||||
|
||||
Enter a title for the SSH key in the **Title** field. Paste the SSH key that you copied in Step 3 in the **Key** field. Make sure that the **Allow write access** checkbox is checked, especially when configuring the GitSync feature to [push changes to Git](#pushing-changes-to-git-repo). However, it is not mandatory to check this option when setting up the GitSync feature for [pulling changes from Git](#pulling-changes-from-git-repo). Finally, click on the **Add key** button.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/github4.png" alt="GitHub" />
|
||||
|
||||
</div>
|
||||
|
||||
### Step 5: Finish the GitSync configuration on ToolJet
|
||||
|
||||
Go back to the **Configure git** tab on ToolJet, and click on the **Finalize setup** button. If the SSH key is configured correctly, you will see a success message.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/git5.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
|
||||
## Enable/Disable GitSync
|
||||
|
||||
To enable or disable the GitSync feature, go to the **Configure git** tab on the **Workspace settings** page, and toggle on/off the **Connect** switch. This is only available if the GitSync feature is configured.
|
||||
|
||||
**When enabled**
|
||||
|
||||
On clicking the GitSync button, the users will be able to commit changes to the git repository.
|
||||
|
||||
**When disabled**
|
||||
1. For non-admin users: The users will not be able to commit changes to the git repository. They will see a dialogue box that the GitSync feature is not configured and they need to contact the admin to configure it.
|
||||
2. For admin users: The users will see a dialogue box with a link to configure the GitSync feature.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/connect.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
|
||||
## Delete GitSync configuration
|
||||
|
||||
To delete the GitSync configuration, go to the **Configure git** tab on the **Workspace settings** page, and click on the **Delete configuration** button. This will delete the SSH key from the ToolJet configuration and the GitSync feature will be disabled.
|
||||
|
||||
**Note:**
|
||||
- Deleting the GitSync configuration will not delete the apps from the git repository. The apps will still be available in the git repository in the same state as they were before the GitSync configuration was deleted.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/deleteconfig.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
|
||||
## Git repo
|
||||
|
||||
Once the initial commit is made, you can see the app files in the git repository. The repository will have the individual app folders and a **.meta** folder. The app folders will be named as the app name and will have the respective **JSON** file of the application. The **.meta** folder will have the `meta.json` file that contains the meta information of each application synced to git repo.
|
||||
|
||||
The **meta.json** file holds information about apps such as the **App name**, **last commit message**, **last commit user**, **last commit date**, **version name**, and **version id**.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/gitcommit.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
|
||||
## Pushing changes to git repo
|
||||
|
||||
Once the GitSync feature is configured, you can start pushing changes to the git repository.
|
||||
|
||||
### App creation
|
||||
|
||||
When you create a new app, you will see an option to select the `Commit changes`. If you select the `commit changes` option, the changes will be committed to the git repository.
|
||||
|
||||
:::info
|
||||
If the app name is same as the name of the existing app in the git repo, it will overwrite the existing app in the git repo.
|
||||
:::
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/commitchanges.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
Selecting the `Commit changes` option will create a new commit in the git repository. The commit message will be `App creation` and the author will be the user who created the app.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/firstcommit.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
|
||||
### App rename
|
||||
|
||||
Whenever an app is renamed, the changes will be automatically committed to the git repository. The commit message will be `App is renamed` and the author will be the user who renamed the app.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/rename.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
|
||||
### App updates
|
||||
|
||||
Whenever a user makes a change in an app, they can make a commit to the git repository by clicking on the **GitSync** button on the topbar. On clicking the **GitSync** button, a modal will open with the option to enter the commit message. The user can enter the commit message and click on the **Commit changes** button to commit the changes to the git repository. Along with the commit message, the user can also see the connnected **Git repo URL** and the **last commit details**.
|
||||
|
||||
**Last commit details** helps the user to know the last commit message, author, date, and time. This helps the user to know the last commit details and make the commit message accordingly.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/modalgit.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
Once the changes are committed, the user can see the commit message, author, and date in the git repository.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/commitgitsync.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
|
||||
### App deletion
|
||||
|
||||
Whenever a user deleted an app from the workspace, the app will not be deleted from the git repository. The app will be available in the git repository in the same state as it was before the app was deleted.
|
||||
|
||||
### App version update
|
||||
|
||||
Whenever a user creates a new app version and creates a commit to git repository, the **JSON** file in the app folder will be replaced with the new version of the app that was created. The **meta.json** file in the **.meta** folder will also be updated with the new version id and version name.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/replace.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
|
||||
## Pulling changes from git repo
|
||||
|
||||
You can configure the GitSync feature on another workspace to pull the changes from the git repository. To configure the GitSync feature on another workspace, follow the steps mentioned in the [Setting up GitSyncing with GitHub](#setting-up-git-syncing-with-github) section.
|
||||
|
||||
Once the GitSync feature is configured, go to the ToolJet dashboard and click on the three dots on the right side of the **Create new app** button. Click on the **Import from git repository** option.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/importgit.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
On clicking the **Import from git repository** option, a modal will open with the dropdown to select the app to be imported from the git repository. Once the app is selected, the app name and the last commit will be displayed. Click on the **Import app** button to import the app from the git repository.
|
||||
|
||||
:::caution
|
||||
- The app imported from the git repository cannot be edited.
|
||||
- The app imported from the Git repository should have a unique name. If the app's name is the same as that of an existing app in the workspace, the user will need to either rename the existing app or delete it to successfully import another app with the same name.
|
||||
- Workspace constants are not synced with the git repository. After pulling the app, if the app throws an error, the user will need to manually add the workspace constants.
|
||||
:::
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/importmodal.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
|
||||
### Checking for updates
|
||||
|
||||
You can check for updates in the git repository by clicking on the **GitSync** button on the topbar. On clicking the **GitSync** button, a modal will open with the option to **Check for updates**. Click on the **Check for updates** button to check for updates in the git repository. If there are any updates, you will see the details of the updates such as commit message, author, and the date in the modal. Click on the **Pull changes** button to pull the changes from the git repository.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/gitsync/updatecheck.png" alt="GitSync" />
|
||||
|
||||
</div>
|
||||
36
docs/docs/tooljet-concepts/how-to-access-values.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
id: how-to-access-values
|
||||
title: How to Access Values?
|
||||
---
|
||||
|
||||
|
||||
In ToolJet, double curly braces `{{}}` can be used to retrieve data returned by queries, access values related to components and pass custom code. You can see the list of all accessible values in the **[Inspector](/docs/how-to/use-inspector/)** tab in the left sidebar.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px'}} className="screenshot-full" src="/img/tooljet-concepts/writing-custom-code/inspector.png" alt="Check Available Values Using Inspector" />
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
### Accessing Values
|
||||
|
||||
The **queries** keyword can be used to access data returned by queries. For example:`{{queries.getSalesData.data}}`
|
||||
|
||||
Similarly, the **components** keyword can be used to access data in the components and other component-related variables. For example: `{{components.table1.selectedRow.id}}`.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
### Writing Custom Code
|
||||
|
||||
You can write custom JavaScript code to set colors, enable or disable toggles and more by passing in JavaScript code inside double curly braces. To change Background Color of a button based on the light or dark theme using **fx** (next to properties in configuration panel), you can use a code that returns a string value of hex code. <br/>
|
||||
|
||||
For example, `{{globals.theme.name == "light" ? "#375FCF" : "#FFFFFF"}}`
|
||||
|
||||
Similary, to enable or disable a button based on user input using **fx**, you can write a JavaScript code that returns true or false. <br/>
|
||||
|
||||
For example, `{{components.form1.data.textinput1 == "" ? true : false}}`.
|
||||
|
||||
</div>
|
||||
25
docs/docs/tooljet-concepts/integrating-data.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
id: integrating-data
|
||||
title: Integrating Data
|
||||
---
|
||||
|
||||
Queries allows you to interact with various data sources, such as databases, APIs, and third-party services. They act as the bridge between your application's components and the data you wish to display, manipulate, or store.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px', marginBottom:'15px'}} className="screenshot-full" src="/img/tooljet-concepts/integrating-data/query-example.png" alt="Styles Tab" />
|
||||
</div>
|
||||
|
||||
These queries are constructed in the Query Panel in the App-Builder, a dedicated section within the ToolJet App-Builder, where you can write low-code or custom SQL statements, API requests, or other data retrieval methods.
|
||||
|
||||
## Configuring Queries
|
||||
You can configure queries to run automatically when an application loads, or trigger them based on specific events or user actions. For example, you could set up a query to run when a user clicks a button, fills out a form, or selects an item from a dropdown menu. This enables you to create dynamic, interactive applications.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px', marginBottom:'15px'}} className="screenshot-full" src="/img/tooljet-concepts/integrating-data/trigger-query.png" alt="Trigger Query" />
|
||||
</div>
|
||||
|
||||
|
||||
## Integration of Queries and Components
|
||||
Queries are deeply integrated with ToolJet's components. Once a query fetches data, you can easily bind that data to various components in your application using ToolJet's templating syntax. Similarly, you can use queries to create, write or update data and trigger them on button clicks and other events.
|
||||
|
||||
|
||||
39
docs/docs/tooljet-concepts/permissions.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
id: permissions
|
||||
title: Securing Applications Through Permissions
|
||||
---
|
||||
|
||||
ToolJet employs a Role-Based Access Control (RBAC) system to manage security and access to its resources, which include apps, folders, and workspace variables.
|
||||
|
||||
In this system, Admins have the authority to invite Users to their workspaces and assign them to specific Groups. Each Group is associated with a set of Permissions that dictate what level of access its members have to various resources.
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
## Groups
|
||||
By default, there are two groups: **All Users**, which contains all workspace members, and **Admins**, which grants full access to all ToolJet resources. Custom groups like Support or Engineering can also be created to fine-tune access controls.
|
||||
|
||||
<div style={{marginBottom:'15px', height:'397px'}}>
|
||||
<iframe
|
||||
className="screenshot-full"
|
||||
src="https://www.floik.com/embed/e4f537b5-7b36-4760-9a52-caefc659a90b/a2f9229b-255a-44d5-a25a-35ad72de7125-flo.html"
|
||||
style={{width: '100%', height: '100%', border: '0'}}
|
||||
frameborder="0"
|
||||
allowfullscreen="allowfullscreen"
|
||||
webkitallowfullscreen
|
||||
mozallowfullscreen
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
## Setting Permissions Based on Groups and Permissions
|
||||
To secure your applications in ToolJet, you can leverage Groups and Permissions. For instance, you could create a custom group named Finance Team and assign it permissions to only access financial apps and variables within the workspace. When you invite new users, you can directly assign them to this group, ensuring they only have access to the resources they need to perform their tasks. You can also make the app public and make it accessible to users without the need to log in.
|
||||
|
||||
By thoughtfully configuring these settings, you can create a secure environment tailored to your organization's needs.
|
||||
|
||||
</div>
|
||||
|
||||
30
docs/docs/tooljet-concepts/styling-components.md
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
id: styling-components
|
||||
title: Styling Components
|
||||
---
|
||||
|
||||
<div style={{marginLeft: "40px", marginRight: "40px"}}>
|
||||
|
||||
|
||||
Styling components in ToolJet is a straightforward yet powerful way to enhance the visual appeal and usability of your application. Once you've dragged and dropped a component onto the canvas in the App-Builder, you can access its styling options through the configuration panel on the right side.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px', marginBottom:'15px'}} className="screenshot-full" src="/img/tooljet-concepts/styling-components/styles-tab.png" alt="Styles Tab" />
|
||||
</div>
|
||||
|
||||
The Styles tab on this panel allows you to modify various visual properties such as colors, fonts, borders, and dimensions. You can also apply conditional styling based on data or user interactions, enabling you to create a more dynamic and responsive user interface.
|
||||
|
||||
## Intuitive Styling Options
|
||||
The styling options in ToolJet are designed to be intuitive, eliminating the need for extensive CSS or design experience. You can easily change the background color of a button, adjust the font size of a text field, or add padding and margins to layout components. These styling changes are immediately reflected on the canvas, providing real-time feedback as you build your application.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px', marginBottom:'15px'}} className="screenshot-full" src="/img/tooljet-concepts/styling-components/styling-options.gif" alt="Styling Options" />
|
||||
</div>
|
||||
|
||||
## Custom CSS
|
||||
Beyond basic styling, ToolJet also offers advanced customization capabilities. For users who are comfortable with CSS, there's the option to add custom classes. This opens up endless possibilities for fine-tuning the appearance and behavior of your application. Whether you're aiming for a specific brand aesthetic or need to meet particular accessibility standards, ToolJet's styling options give you the flexibility to create an application that not only functions well but also looks great.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
42
docs/docs/tooljet-concepts/using-fx.md
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
id: using-fx
|
||||
title: Using the FX Functionality
|
||||
---
|
||||
|
||||
Clicking on the **fx** symbol in ToolJet opens up a code editor that allows you to write custom JavaScript expressions. You can find **fx** in the configuration panel on the right, next to various properties and settings of a component.
|
||||
|
||||
With **fx**, you can perform calculations or set conditional logic to dynamically configure the components without leaving the ToolJet interface. It's an invaluable tool for adding complexity and interactivity to your applications.
|
||||
|
||||
## Toggle Button
|
||||
|
||||
When using **fx** buttons associated with toggle buttons, the expected output of the code you enter should be a boolean value - `true` or `false`. For example, the below code will check whether the entered age entered in the number input field of the form is above 18, the button component will be enabled or disabled based on it.
|
||||
|
||||
```js
|
||||
{{components.form1.data.numberinput1.value>18? false : true}}
|
||||
```
|
||||
|
||||
<div style={{marginBottom:'15px', height:'492px'}}>
|
||||
<iframe
|
||||
className="screenshot-full"
|
||||
src="https://www.floik.com/embed/e4f537b5-7b36-4760-9a52-caefc659a90b/4931d426-a33c-47c4-a30f-b34283b482ec-flo.html"
|
||||
style={{width: '100%', height: '100%'}}
|
||||
frameborder="0"
|
||||
allowfullscreen="allowfullscreen"
|
||||
webkitallowfullscreen
|
||||
mozallowfullscreen
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
For other cases, the expected value is a string. For example, If you are setting `Text color`, `Background Color`, `Loader Color`, etc. You need to pass in a JavaScript code that returns a hex code as a string.
|
||||
|
||||
## Access all Variables, Queries, and Components
|
||||
|
||||
The expressions you write in the code editor available after clicking on **fx** lets you access all the variables, queries, and components within your application. This allows you to create intricate relationships between different parts of your app, making it more responsive and user-friendly.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
44
docs/docs/tooljet-concepts/what-are-components.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
id: what-are-components
|
||||
title: What Are Components?
|
||||
---
|
||||
|
||||
|
||||
Components in ToolJet serve as the building blocks for creating applications. They are pre-designed elements that you can drag and drop onto the canvas in the App-Builder. ToolJet comes with 45+ built-in components.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px', marginBottom:'15px'}} className="screenshot-full" src="/img/tooljet-concepts/what-are-components/drag-drop-components.gif" alt="Drag And Drop Components" />
|
||||
</div>
|
||||
|
||||
These components range from basic UI elements like buttons, text fields, and tables, to more complex elements like kanban, charts, and maps. By using components, you can quickly assemble a functional and visually appealing application without having to write code from scratch.
|
||||
|
||||
### Customizing Components
|
||||
|
||||
Components are highly customizable and interactive. Once you place a component on the canvas, you can easily modify its properties, styles, and behaviors through the configuration panel on the right side of the App-Builder. This allows you to make your application dynamic and responsive.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px', marginBottom:'15px'}} className="screenshot-full" src="/img/tooljet-concepts/what-are-components/component-config.gif" alt="Component Configuration" />
|
||||
</div>
|
||||
|
||||
### Using Components With Data
|
||||
|
||||
In ToolJet, components can be easily connected to various data sources like databases, APIs, and third-party services through **[queries](what-are-queries)**. Once the data is fetched, you can bind it to components like tables, charts, and more.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px', marginBottom:'15px'}} className="screenshot-full" src="/img/tooljet-concepts/what-are-components/adding-data-to-component.png" alt="Adding Data To Component" />
|
||||
</div>
|
||||
|
||||
## Custom Components
|
||||
|
||||
ToolJet allows for the creation of custom components using React. This feature is invaluable for developers who require functionalities beyond the 45+ built-in components that ToolJet offers. To create a custom component, you can drag and drop a **[Custom Component](/docs/widgets/custom-component/)** on the canvas and configure its data and code.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px', marginBottom:'15px'}} className="screenshot-full" src="/img/tooljet-concepts/what-are-components/custom-components.png" alt="Custom Components" />
|
||||
</div>
|
||||
|
||||
By incorporating custom React components, you can significantly extend the capabilities of your ToolJet applications, allowing for a more tailored and unique user experience.
|
||||
|
||||
To explore the full list of components in ToolJet, go through the **[Component Library](/docs/widgets/bounded-box)**.
|
||||
|
||||
|
||||
|
||||
37
docs/docs/tooljet-concepts/what-are-datasources.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
id: what-are-datasources
|
||||
title: What Are Data Sources?
|
||||
---
|
||||
|
||||
|
||||
Data sources are pivotal as they enable us to fetch and send data to and from different sources including databases, external APIs, or services. Once a data source is configured, it can be shared across all apps within a workspace.
|
||||
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
## Types and Management of Data Sources
|
||||
|
||||
Apart from its built-in database, ToolJet supports a range of external data sources which can be broadly categorized into databases, external APIs, and services. To manage these data sources, ToolJet provides a data source manager that can be opened by clicking on the **Data Sources** button located on the left-sidebar of the App-Builder.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px'}} className="screenshot-full" src="/img/tooljet-concepts/what-are-datasources/data-source-manager.png" alt="Data Source Manager" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
## Adding A Data Source
|
||||
|
||||
Adding a new data source is as easy as filling out a form; users can click on the Data Sources button in the left-sidebar, navigate to the required data source, click on the corresponding **Add** button and enter the credentials.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px'}} className="screenshot-full" src="/img/tooljet-concepts/what-are-datasources/configure-data-source.gif" alt="Configuring Data Source" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
To see a full list of compatible data sources and their set up details, checkout the **[Datasource Catalog](/docs/data-sources/overview)**.
|
||||
|
||||
|
||||
|
||||
32
docs/docs/tooljet-concepts/what-are-events.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
id: what-are-events
|
||||
title: What Are Events?
|
||||
---
|
||||
|
||||
Events are used to run queries, show alerts and other functionalities based on triggers such as button clicks or query completion. Events can be chained together to run a series of logical operations. For example, the completion of one query could trigger another event that runs a second query, and so on. This way, a single user interaction, like clicking a button, could set off a chain of events.
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
## Triggering Events
|
||||
Suppose you have a query that refreshes data when a user clicks on a button, and you also want to display a pop-up alert upon successful data refresh. In ToolJet, you can configure an event to trigger a query upon clicking the button, followed by another event to display a pop-up alert confirming the successful data refresh after the query execution is completed.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px'}} className="screenshot-full" src="/img/tooljet-concepts/what-are-events/events-configuration.png" alt="Event Configuration" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
## Setting Up Event Handlers
|
||||
|
||||
Setting up event handlers to manage such triggers and responses is a straightforward process in ToolJet. For instance, to set up an event that triggers on the click of a button, you simply navigate to the button component's configuration, click on **New Event Handler**, and define the Event and the Action to be taken. The actions could range from running a query, showing an alert, or even switching to a different page.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
42
docs/docs/tooljet-concepts/what-are-queries.md
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
id: what-are-queries
|
||||
title: What Are Queries?
|
||||
---
|
||||
|
||||
**Queries** act as a bridge between the application and data sources. Queries help interact with data sources like databases or APIs. They fetch or update data based on events like button clicks, making apps dynamic.
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
## Creation and Management
|
||||
|
||||
**Query Panel** is the hub for creating and managing queries to interact with connected data sources. Located at the bottom of the app-builder, it allows users to perform API requests, database queries, and data manipulations using JavaScript and Python. The Query Panel is divided into two main sections: on the left, the **Query Manager** allows for the listing and management of queries; on the right, the **Query Editor** provides the functionality to construct queries either through a low-code interface or by manually entering the query text.
|
||||
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px'}} className="screenshot-full" src="/img/tooljet-concepts/what-are-queries/query-panel.png" alt="Query Panel" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{paddingTop:'24px', paddingBottom:'24px'}}>
|
||||
|
||||
## Execution and Interaction
|
||||
|
||||
Queries run when triggered by app events, such as clicking a button. They can fetch new data or change existing data, and the results can be displayed in the app using tables or charts. This makes data interaction in your app straightforward and effective.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img style={{padding: '10px'}} className="screenshot-full" src="/img/tooljet-concepts/what-are-queries/trigger-query.png" alt="Trigger Query Config" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
Learn more about queries in this **[detailed guide](/docs/app-builder/query-panel/)** for Query Panel.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -10,7 +10,26 @@
|
|||
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
|
||||
const sidebars = {
|
||||
docs: [
|
||||
'getting-started',
|
||||
{
|
||||
'type': 'category',
|
||||
'label': 'Getting Started',
|
||||
'items': [
|
||||
'getting-started/platform-overview',
|
||||
'getting-started/quickstart-guide',
|
||||
],
|
||||
},
|
||||
{
|
||||
'type': 'category',
|
||||
'label': 'ToolJet Concepts',
|
||||
'items': [
|
||||
'tooljet-concepts/what-are-components',
|
||||
'tooljet-concepts/what-are-datasources',
|
||||
'tooljet-concepts/what-are-queries',
|
||||
'tooljet-concepts/what-are-events',
|
||||
'tooljet-concepts/how-to-access-values',
|
||||
'tooljet-concepts/permissions',
|
||||
],
|
||||
},
|
||||
{
|
||||
'type': 'category',
|
||||
'label': 'Setup',
|
||||
|
|
@ -212,6 +231,7 @@ const sidebars = {
|
|||
'tutorial/keyboard-shortcuts',
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
'type': 'category',
|
||||
'label': 'Workflows',
|
||||
|
|
@ -302,6 +322,7 @@ const sidebars = {
|
|||
'tutorial/versioning-and-release',
|
||||
],
|
||||
},
|
||||
'gitsync',
|
||||
{
|
||||
'type': 'category',
|
||||
'label': 'Marketplace',
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
--ifm-color-primary-lighter: rgb(102, 212, 189);
|
||||
--ifm-color-primary-lightest: rgb(146, 224, 208);
|
||||
--ifm-code-font-size: 95%;
|
||||
--ifm-menu-color-active: #4d72fa;
|
||||
--ifm-menu-color-active: #3E63DD;
|
||||
--ifm-font-family-base: 'IBM Plex Sans';
|
||||
--tblr-blue: #206bc4;
|
||||
--tblr-azure: #4299e1;
|
||||
|
|
@ -43,6 +43,40 @@
|
|||
--tblr-font-sans-serif: "Inter", -apple-system, BlinkMacSystemFont, San Francisco, Segoe UI, Roboto, Helvetica Neue, sans-serif;
|
||||
--tblr-font-monospace: null, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
|
||||
--tblr-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||
--doc-sidebar-width: 250px !important;
|
||||
--ifm-link-color: #3e63dd;
|
||||
--ifm-menu-color-background-active: #f0f4ff;
|
||||
--ifm-link-menu-color-background-hover: #f0f4ff;
|
||||
}
|
||||
|
||||
/* .markdown h1 {
|
||||
margin-left: 10%;
|
||||
margin-right: 10%;
|
||||
} */
|
||||
|
||||
.menu__link--sublist-caret:after {
|
||||
background: var(--ifm-menu-link-sublist-icon) 50% / 1rem 1rem;
|
||||
}
|
||||
|
||||
.menu__caret:before {
|
||||
background: var(--ifm-menu-link-sublist-icon) 50% / 1rem 1rem !important;
|
||||
}
|
||||
|
||||
.badge--primary {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
article {
|
||||
padding-left: 7%;
|
||||
padding-right: 7%;
|
||||
}
|
||||
|
||||
.menu__caret {
|
||||
size: small;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 180%;
|
||||
}
|
||||
|
||||
.admonition {
|
||||
|
|
|
|||
BIN
docs/static/img/gitsync/commitchanges.png
vendored
Normal file
|
After Width: | Height: | Size: 396 KiB |
BIN
docs/static/img/gitsync/commitgitsync.png
vendored
Normal file
|
After Width: | Height: | Size: 380 KiB |
BIN
docs/static/img/gitsync/connect.png
vendored
Normal file
|
After Width: | Height: | Size: 366 KiB |
BIN
docs/static/img/gitsync/deleteconfig.png
vendored
Normal file
|
After Width: | Height: | Size: 365 KiB |
BIN
docs/static/img/gitsync/envmigration.png
vendored
Normal file
|
After Width: | Height: | Size: 176 KiB |
BIN
docs/static/img/gitsync/firstcommit.png
vendored
Normal file
|
After Width: | Height: | Size: 353 KiB |
BIN
docs/static/img/gitsync/git2.png
vendored
Normal file
|
After Width: | Height: | Size: 373 KiB |
BIN
docs/static/img/gitsync/git5.png
vendored
Normal file
|
After Width: | Height: | Size: 364 KiB |
BIN
docs/static/img/gitsync/gitcommit.png
vendored
Normal file
|
After Width: | Height: | Size: 496 KiB |
BIN
docs/static/img/gitsync/github1.png
vendored
Normal file
|
After Width: | Height: | Size: 431 KiB |
BIN
docs/static/img/gitsync/github2.png
vendored
Normal file
|
After Width: | Height: | Size: 477 KiB |
BIN
docs/static/img/gitsync/github3.png
vendored
Normal file
|
After Width: | Height: | Size: 320 KiB |
BIN
docs/static/img/gitsync/github4.png
vendored
Normal file
|
After Width: | Height: | Size: 390 KiB |
BIN
docs/static/img/gitsync/gitsync.png
vendored
Normal file
|
After Width: | Height: | Size: 269 KiB |
BIN
docs/static/img/gitsync/importgit.png
vendored
Normal file
|
After Width: | Height: | Size: 384 KiB |
BIN
docs/static/img/gitsync/importmodal.png
vendored
Normal file
|
After Width: | Height: | Size: 402 KiB |
BIN
docs/static/img/gitsync/modalgit.png
vendored
Normal file
|
After Width: | Height: | Size: 441 KiB |
BIN
docs/static/img/gitsync/rename.png
vendored
Normal file
|
After Width: | Height: | Size: 368 KiB |
BIN
docs/static/img/gitsync/replace.png
vendored
Normal file
|
After Width: | Height: | Size: 552 KiB |
BIN
docs/static/img/gitsync/updatecheck.png
vendored
Normal file
|
After Width: | Height: | Size: 410 KiB |
BIN
docs/static/img/platform-overview/app-builder.png
vendored
Normal file
|
After Width: | Height: | Size: 699 KiB |
BIN
docs/static/img/platform-overview/integrations.png
vendored
Normal file
|
After Width: | Height: | Size: 298 KiB |
BIN
docs/static/img/platform-overview/multi-environment.png
vendored
Normal file
|
After Width: | Height: | Size: 361 KiB |
BIN
docs/static/img/platform-overview/multiplayer.png
vendored
Normal file
|
After Width: | Height: | Size: 454 KiB |
BIN
docs/static/img/platform-overview/platform-overview-v2.jpg
vendored
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/static/img/platform-overview/platform-overview.png
vendored
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/static/img/platform-overview/security.png
vendored
Normal file
|
After Width: | Height: | Size: 352 KiB |
BIN
docs/static/img/platform-overview/sso.png
vendored
Normal file
|
After Width: | Height: | Size: 312 KiB |
BIN
docs/static/img/platform-overview/tooljet-db.png
vendored
Normal file
|
After Width: | Height: | Size: 321 KiB |
BIN
docs/static/img/platform-overview/workflows.png
vendored
Normal file
|
After Width: | Height: | Size: 744 KiB |
BIN
docs/static/img/quickstart-guide/add-a-table-v2.png
vendored
Normal file
|
After Width: | Height: | Size: 382 KiB |
BIN
docs/static/img/quickstart-guide/add-a-table.png
vendored
Normal file
|
After Width: | Height: | Size: 341 KiB |
BIN
docs/static/img/quickstart-guide/add-action-button-v2.png
vendored
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
docs/static/img/quickstart-guide/add-action-dialog-v2.png
vendored
Normal file
|
After Width: | Height: | Size: 167 KiB |
BIN
docs/static/img/quickstart-guide/add-employee-query-v2.png
vendored
Normal file
|
After Width: | Height: | Size: 200 KiB |
BIN
docs/static/img/quickstart-guide/app-builder-overview-v2.png
vendored
Normal file
|
After Width: | Height: | Size: 328 KiB |
BIN
docs/static/img/quickstart-guide/create-database-v2.png
vendored
Normal file
|
After Width: | Height: | Size: 181 KiB |
BIN
docs/static/img/quickstart-guide/first-query-v2.png
vendored
Normal file
|
After Width: | Height: | Size: 105 KiB |
BIN
docs/static/img/quickstart-guide/header-design-v2.png
vendored
Normal file
|
After Width: | Height: | Size: 287 KiB |
BIN
docs/static/img/quickstart-guide/preview-share-v2.png
vendored
Normal file
|
After Width: | Height: | Size: 335 KiB |
BIN
docs/static/img/quickstart-guide/query-preview-v2.png
vendored
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
docs/static/img/quickstart-guide/reload-data-v2.png
vendored
Normal file
|
After Width: | Height: | Size: 187 KiB |
BIN
docs/static/img/quickstart-guide/table-with-data-v2.png
vendored
Normal file
|
After Width: | Height: | Size: 253 KiB |
BIN
docs/static/img/tooljet-concepts/integrating-data/query-example.png
vendored
Normal file
|
After Width: | Height: | Size: 129 KiB |
BIN
docs/static/img/tooljet-concepts/integrating-data/trigger-query.png
vendored
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
docs/static/img/tooljet-concepts/styling-components/styles-tab.png
vendored
Normal file
|
After Width: | Height: | Size: 436 KiB |
BIN
docs/static/img/tooljet-concepts/styling-components/styling-options.gif
vendored
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/static/img/tooljet-concepts/what-are-components/adding-data-to-component.png
vendored
Normal file
|
After Width: | Height: | Size: 362 KiB |
BIN
docs/static/img/tooljet-concepts/what-are-components/component-config.gif
vendored
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
docs/static/img/tooljet-concepts/what-are-components/custom-components.png
vendored
Normal file
|
After Width: | Height: | Size: 193 KiB |
BIN
docs/static/img/tooljet-concepts/what-are-components/drag-drop-components.gif
vendored
Normal file
|
After Width: | Height: | Size: 789 KiB |