diff --git a/.version b/.version
index b56e89db41..fe96cad5cf 100644
--- a/.version
+++ b/.version
@@ -1 +1 @@
-3.0.0-ce-beta.1
+3.0.0-ce
diff --git a/frontend/.version b/frontend/.version
index b56e89db41..fe96cad5cf 100644
--- a/frontend/.version
+++ b/frontend/.version
@@ -1 +1 @@
-3.0.0-ce-beta.1
+3.0.0-ce
diff --git a/frontend/src/AppBuilder/_hooks/useAppData.js b/frontend/src/AppBuilder/_hooks/useAppData.js
index bb745f2568..21c95a0144 100644
--- a/frontend/src/AppBuilder/_hooks/useAppData.js
+++ b/frontend/src/AppBuilder/_hooks/useAppData.js
@@ -156,7 +156,15 @@ const useAppData = (appId, moduleId, mode = 'edit', { environmentId, versionId }
let editorEnvironment = result.editorEnvironment;
const editorEnvironmentId = result.editing_version?.current_environment_id;
if (isPreviewForVersion) {
+ const rawDataQueries = appData?.data_queries;
+ const rawEditingVersionDataQueries = appData?.editing_version?.data_queries;
appData = convertAllKeysToSnakeCase(appData);
+
+ appData.data_queries = rawDataQueries;
+ if (appData.editing_version && rawEditingVersionDataQueries) {
+ appData.editing_version.data_queries = rawEditingVersionDataQueries;
+ }
+
editorEnvironment = {
id: environmentId,
name: queryParams.env,
diff --git a/frontend/src/Editor/Components/Multiselect.jsx b/frontend/src/Editor/Components/Multiselect.jsx
index 65ebf2767b..591d97f9ea 100644
--- a/frontend/src/Editor/Components/Multiselect.jsx
+++ b/frontend/src/Editor/Components/Multiselect.jsx
@@ -164,7 +164,7 @@ export const Multiselect = function Multiselect({
diff --git a/frontend/src/_components/OrganizationManager/List.jsx b/frontend/src/_components/OrganizationManager/List.jsx
index 8ac54710bb..9229d4079b 100644
--- a/frontend/src/_components/OrganizationManager/List.jsx
+++ b/frontend/src/_components/OrganizationManager/List.jsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useState, useRef } from 'react';
import { authenticationService } from '@/_services';
import { CustomSelect } from './CustomSelect';
import { getAvatar, decodeEntities } from '@/_helpers/utils';
@@ -29,14 +29,21 @@ export const OrganizationList = function () {
fetchOrganizations();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
-
- const switchOrganization = (id) => {
+ const newTabRef = useRef(false);
+ const switchOrganization = (id, newTab = false) => {
+ newTabRef.current = newTab;
const organization = organizationList.find((org) => org.id === id);
if (![id, organization.slug].includes(getWorkspaceIdOrSlugFromURL())) {
const newPath = appendWorkspaceId(organization.slug || id, location.pathname, true);
- window.open(newPath, '_blank');
+ newTab ? window.open(newPath, '_blank') : (window.location = newPath);
}
};
+ const handleOnChange = (id) => {
+ if (!newTabRef.current) {
+ switchOrganization(id, false);
+ }
+ newTabRef.current = false;
+ };
const options = organizationList
.map((org) => ({
@@ -81,7 +88,7 @@ export const OrganizationList = function () {
switchOrganization(org.id)}
+ onClick={() => switchOrganization(org.id, true)}
>
@@ -103,7 +110,7 @@ export const OrganizationList = function () {
isLoading={isGettingOrganizations}
options={options}
value={current_organization_id}
- onChange={(id) => switchOrganization(id)}
+ onChange={handleOnChange}
className={`tj-org-select ${darkMode && 'dark-theme'}`}
/>
diff --git a/frontend/src/_styles/global-datasources.scss b/frontend/src/_styles/global-datasources.scss
index 1cbaed557b..fb482533bc 100644
--- a/frontend/src/_styles/global-datasources.scss
+++ b/frontend/src/_styles/global-datasources.scss
@@ -179,6 +179,7 @@
.datasource-list-container {
overflow-y: auto;
max-height: calc(100vh - 64px);
+ padding-left: 20px;
.datasource-list {
width: 976px;
diff --git a/frontend/src/_styles/theme.scss b/frontend/src/_styles/theme.scss
index 50fb8d60f6..a5987eee1d 100644
--- a/frontend/src/_styles/theme.scss
+++ b/frontend/src/_styles/theme.scss
@@ -3656,6 +3656,9 @@ input:focus-visible {
}
.main-wrapper.theme-dark {
+ position: relative;
+ min-height: 100%;
+ min-width: 100%;
background-color: #2b394b;
}
@@ -7796,7 +7799,11 @@ tbody {
.audit-log-nav-item {
bottom: 40px;
}
-
+.workspace-content-wrapper{
+ overflow-x: auto;
+ overflow-y: auto;
+ padding-left: 20px;
+}
.workspace-content-wrapper,
.database-page-content-wrap {
background-color: var(--page-default);
@@ -10560,6 +10567,7 @@ tbody {
.manage-groups-body {
padding: 12px 12px 10px 12px;
font-size: 12px;
+ overflow-y: auto;
// overflow-y: auto;
height: calc(100vh - 300px);
diff --git a/frontend/webpack.config.js b/frontend/webpack.config.js
index 8d3f1968d6..4eb6c357f8 100644
--- a/frontend/webpack.config.js
+++ b/frontend/webpack.config.js
@@ -196,7 +196,6 @@ module.exports = {
COMMENT_FEATURE_ENABLE: process.env.COMMENT_FEATURE_ENABLE ?? true,
ENABLE_MULTIPLAYER_EDITING: true,
ENABLE_MARKETPLACE_DEV_MODE: process.env.ENABLE_MARKETPLACE_DEV_MODE,
- TJDB_SQL_MODE_DISABLE: process.env.TJDB_SQL_MODE_DISABLE ?? false,
TOOLJET_MARKETPLACE_URL:
process.env.TOOLJET_MARKETPLACE_URL || 'https://tooljet-plugins-production.s3.us-east-2.amazonaws.com',
}),
diff --git a/marketplace/plugins/pinecone/lib/operations.json b/marketplace/plugins/pinecone/lib/operations.json
index b5d3a4e3c9..cd798370bc 100644
--- a/marketplace/plugins/pinecone/lib/operations.json
+++ b/marketplace/plugins/pinecone/lib/operations.json
@@ -5,14 +5,6 @@
"type": "database",
"defaults": {},
"properties": {
- "index": {
- "label": "Index",
- "key": "index",
- "type": "text",
- "description": "Enter the index name (e.g., example-index)",
- "placeholder": "example-index",
- "height": "36px"
- },
"operation": {
"label": "Operation",
"key": "operation",
diff --git a/plugins/packages/common/lib/utils.helper.ts b/plugins/packages/common/lib/utils.helper.ts
index c85909d926..aaab6c436e 100644
--- a/plugins/packages/common/lib/utils.helper.ts
+++ b/plugins/packages/common/lib/utils.helper.ts
@@ -82,8 +82,7 @@ export const sanitizeHeaders = (
queryOptions: any,
hasDataSource = true
): { [k: string]: string } => {
- const cleanHeaders = (headers) =>
- headers.filter(([_, v]) => !isEmpty(v)).map(([k, v]) => [k.trim().toLowerCase(), v]);
+ const cleanHeaders = (headers) => headers.filter(([k, _]) => k !== '').map(([k, v]) => [k.trim(), v]);
const _queryHeaders = cleanHeaders(queryOptions.headers || []);
const queryHeaders = Object.fromEntries(_queryHeaders);
diff --git a/server/.version b/server/.version
index b56e89db41..fe96cad5cf 100644
--- a/server/.version
+++ b/server/.version
@@ -1 +1 @@
-3.0.0-ce-beta.1
+3.0.0-ce
diff --git a/server/data-migrations/1731283187529-PopulateManualConnectionTypeForOldPostgresDs.ts b/server/data-migrations/1731283187529-PopulateManualConnectionTypeForOldPostgresDs.ts
new file mode 100644
index 0000000000..567f1fb3bd
--- /dev/null
+++ b/server/data-migrations/1731283187529-PopulateManualConnectionTypeForOldPostgresDs.ts
@@ -0,0 +1,26 @@
+import { MigrationInterface, QueryRunner } from 'typeorm';
+
+export class PopulateManualConnectionTypeForOldPostgresDs1731283187529 implements MigrationInterface {
+ public async up(queryRunner: QueryRunner): Promise {
+ await queryRunner.query(`
+ UPDATE data_source_options
+ SET options = jsonb_set(
+ COALESCE(options::jsonb, '{}'),
+ '{connection_type}',
+ '{"value": "manual", "encrypted": false}'::jsonb
+ )
+ WHERE data_source_id IN (
+ SELECT ds.id
+ FROM data_sources ds
+ WHERE ds.kind = 'postgresql'
+ )
+ AND NOT EXISTS (
+ SELECT 1
+ FROM jsonb_object_keys(COALESCE(options::jsonb, '{}')) AS keys
+ WHERE keys = 'connection_type'
+ );
+ `);
+ }
+
+ public async down(queryRunner: QueryRunner): Promise {}
+}
diff --git a/server/src/services/data_queries.service.ts b/server/src/services/data_queries.service.ts
index 81509bc95d..cd4531f2e1 100644
--- a/server/src/services/data_queries.service.ts
+++ b/server/src/services/data_queries.service.ts
@@ -573,7 +573,6 @@ export class DataQueriesService {
finalResult += str.slice(lastIndex);
return finalResult;
}
-
async parseQueryOptions(
object: any,
options: object,
@@ -581,10 +580,8 @@ export class DataQueriesService {
environmentId?: string
): Promise