diff --git a/frontend/src/base/components/project-list/ProjectListCard.css b/frontend/src/base/components/project-list/ProjectListCard.css
index a912020..53577fd 100644
--- a/frontend/src/base/components/project-list/ProjectListCard.css
+++ b/frontend/src/base/components/project-list/ProjectListCard.css
@@ -9,6 +9,7 @@
background-color: var(--project-detail-bg);
position: relative;
overflow: hidden;
+ cursor: pointer;
}
.project-list-card-wrapper:hover {
@@ -170,10 +171,6 @@
}
/* ---------- body ---------- */
-.project-list-card-clickable-content {
- cursor: pointer;
-}
-
.project-list-card-detail-section {
padding: 12px 14px;
}
diff --git a/frontend/src/base/components/project-list/ProjectListCard.jsx b/frontend/src/base/components/project-list/ProjectListCard.jsx
index 131755d..f180428 100644
--- a/frontend/src/base/components/project-list/ProjectListCard.jsx
+++ b/frontend/src/base/components/project-list/ProjectListCard.jsx
@@ -89,6 +89,10 @@ function ProjectListCard({
} ${isDeleting ? "project-list-card--deleting" : ""} ${
selectionMode || isSelected ? "project-list-card--selection-mode" : ""
}`}
+ role="button"
+ tabIndex={0}
+ onClick={handleCardClick}
+ onKeyDown={(e) => e.key === "Enter" && handleCardClick()}
>
{/* deleting overlay */}
{isDeleting && (
@@ -141,6 +145,7 @@ function ProjectListCard({
if (ShareProjectModal) setIsShareModalOpen(true);
}}
onKeyDown={(e) => {
+ e.stopPropagation();
if (e.key === "Enter" && ShareProjectModal)
setIsShareModalOpen(true);
}}
@@ -167,14 +172,8 @@ function ProjectListCard({
)}
- {/* ---------- body (clickable) ---------- */}
-
e.key === "Enter" && handleCardClick()}
- >
+ {/* ---------- body ---------- */}
+
{/* description */}
state.sessionDetails?.is_cloud);
const currentSchema = useProjectStore((state) => state.currentSchema);
+ const setCurrentSchema = useProjectStore((state) => state.setCurrentSchema);
+ const schemaList = useProjectStore((state) => state.schemaList);
+ const projectId = useProjectStore((state) => state.projectId);
+ const expService = explorerService();
+ const { notify } = useNotificationService();
+
+ const schemaOptions = useMemo(
+ () => schemaList.map((s) => ({ label: s, value: s })),
+ [schemaList]
+ );
+
+ const handleSchemaChange = useCallback(
+ (value) => {
+ expService
+ .setProjectSchema(projectId, value)
+ .then(() => {
+ setCurrentSchema(value);
+ notify({ type: "success", message: "Schema updated successfully" });
+ })
+ .catch((error) => {
+ console.error(error);
+ notify({ error });
+ });
+ },
+ [expService, projectId, setCurrentSchema, notify]
+ );
const llmOptions = useMemo(
() =>
@@ -169,12 +197,28 @@ const PromptActions = memo(function PromptActions({
)}
- {/* Schema indicator */}
- {currentSchema && (
+ {/* Schema selector */}
+ {schemaList.length > 0 ? (
+
+
+
+
+ ) : (
}
- text={currentSchema}
- tooltipTitle="All new models generated will be created inside this schema. To modify it, click the settings icon from the left explorer."
+ text="No schema"
+ tooltipTitle="No schemas available. Please configure a database connection and select a schema from the explorer."
+ className="chat-ai-info-chip-error"
/>
)}
diff --git a/frontend/src/ide/editor/no-code-configuration/configure-source-destination.jsx b/frontend/src/ide/editor/no-code-configuration/configure-source-destination.jsx
index 5a0bc4c..99f860d 100644
--- a/frontend/src/ide/editor/no-code-configuration/configure-source-destination.jsx
+++ b/frontend/src/ide/editor/no-code-configuration/configure-source-destination.jsx
@@ -204,178 +204,143 @@ function ConfigureSourceDestination({
}, [reference]);
return (
<>
-
-
+
+
+
+ Hierarchy
+
+
+ {
+ const newModelType = e.target.value;
+ if (newModelType === "root") {
+ setPrevReference(reference.length ? reference : []);
+ setReference([]);
+ } else {
+ setReference(prevReference.length ? prevReference : reference);
+ }
+ setModelType(newModelType);
+ }}
+ className="mb-10"
>
-
-
-
-
- Hierarchy
-
-
- {
- const newModelType = e.target.value;
- if (newModelType === "root") {
- setPrevReference(reference.length ? reference : []);
- setReference([]);
- } else {
- setReference(
- prevReference.length ? prevReference : reference
- );
+ Root model
+
+ Child of
+
+
+ {modelType === "child" && (
+
+ handleChange("reference", value, setReference, false)
+ }
+ options={referenceList}
+ showSearch
+ popupMatchSelectWidth={false}
+ />
+ )}
+
+
+ {/* ---------- Configure Source & Destination ---------- */}
+
+
+
+
+ Configure Source
+
+
+
+ {isSchemaExists && (
+
+
+ handleChange("schema_name", value, setSource)
}
- setModelType(newModelType);
- }}
+ options={allSchemas.map((value) => ({ value }))}
+ showSearch
+ popupMatchSelectWidth={false}
+ loading={isLoadingSchemas}
+ notFoundContent={
+ isLoadingSchemas ? "Loading schemas..." : "No schemas found"
+ }
+ />
+
+ )}
+
+
- Root model
-
- Child of
-
-
- {modelType === "child" && (
- <>
-
- handleChange("reference", value, setReference, false)
- }
- options={referenceList}
- showSearch
- />
- >
- )}
+ placeholder="Select the table"
+ value={source.table_name}
+ onChange={(value) => handleChange("table_name", value, setSource)}
+ options={allTables[
+ isSchemaExists ? source.schema_name : "default"
+ ]?.map((value) => ({
+ value,
+ }))}
+ showSearch
+ popupMatchSelectWidth={false}
+ disabled={isSchemaExists && !source.schema_name}
+ loading={
+ isLoadingTables[isSchemaExists ? source.schema_name : "default"]
+ }
+ notFoundContent={
+ isLoadingTables[isSchemaExists ? source.schema_name : "default"]
+ ? "Loading tables..."
+ : "No tables found"
+ }
+ />
-
-
-
-
-
- Configure Source
-
-
-
- {isSchemaExists && (
-
-
- handleChange("schema_name", value, setSource)
- }
- options={allSchemas.map((value) => ({ value }))}
- showSearch
- loading={isLoadingSchemas}
- notFoundContent={
- isLoadingSchemas
- ? "Loading schemas..."
- : "No schemas found"
- }
- />
-
- )}
-
-
- handleChange("table_name", value, setSource)
- }
- options={allTables[
- isSchemaExists ? source.schema_name : "default"
- ]?.map((value) => ({
- value,
- }))}
- showSearch
- disabled={isSchemaExists && !source.schema_name}
- loading={
- isLoadingTables[
- isSchemaExists ? source.schema_name : "default"
- ]
- }
- notFoundContent={
- isLoadingTables[
- isSchemaExists ? source.schema_name : "default"
- ]
- ? "Loading tables..."
- : "No tables found"
- }
- />
-
-
-
-
-
-
- Configure Destination
-
-
-
- {isSchemaExists && (
-
-
- handleChange("schema_name", value, setModel, false)
- }
- options={allSchemas.map((value) => ({ value }))}
- showSearch
- loading={isLoadingSchemas}
- notFoundContent={
- isLoadingSchemas
- ? "Loading schemas..."
- : "No schemas found"
- }
- />
-
- )}
-
- {
- // Block spaces by replacing them with an empty string
- const noSpacesValue = value.replace(/\s/g, "");
- handleChange(
- "table_name",
- noSpacesValue,
- setModel,
- false
- );
- }}
- disabled={isSchemaExists && !model.schema_name}
- />
-
-
-
+
+
+
+
+
+ Configure Destination
+
+
+
+ {isSchemaExists && (
+
+
+ handleChange("schema_name", value, setModel, false)
+ }
+ options={allSchemas.map((value) => ({ value }))}
+ showSearch
+ popupMatchSelectWidth={false}
+ loading={isLoadingSchemas}
+ notFoundContent={
+ isLoadingSchemas ? "Loading schemas..." : "No schemas found"
+ }
+ />
+
+ )}
+
+ {
+ const noSpacesValue = value.replace(/\s/g, "");
+ handleChange("table_name", noSpacesValue, setModel, false);
+ }}
+ disabled={isSchemaExists && !model.schema_name}
+ />
diff --git a/frontend/src/ide/editor/no-code-model/no-code-model.css b/frontend/src/ide/editor/no-code-model/no-code-model.css
index 677d255..0c710ea 100644
--- a/frontend/src/ide/editor/no-code-model/no-code-model.css
+++ b/frontend/src/ide/editor/no-code-model/no-code-model.css
@@ -121,10 +121,19 @@
.configure-tables .ant-space,
.configure-tables .ant-select,
+.configure-tables .ant-select-auto-complete,
.width-100-percent {
width: 100% !important;
}
+.configure-section-card {
+ margin-bottom: 12px;
+}
+
+.configure-section-card h4:first-child {
+ margin-top: 0;
+}
+
.search-icon {
margin-left: -3px;
margin-right: 12px;
@@ -681,7 +690,8 @@
justify-content: space-between;
align-items: center;
padding-block: 8px;
- overflow-x: auto;
+ flex-wrap: wrap;
+ gap: 8px;
}
.custom-pagination-container .custom-pagination .ant-pagination-options {
diff --git a/frontend/src/ide/editor/no-code-toolbar/no-code-toolbar.css b/frontend/src/ide/editor/no-code-toolbar/no-code-toolbar.css
index 90f0f05..d401063 100644
--- a/frontend/src/ide/editor/no-code-toolbar/no-code-toolbar.css
+++ b/frontend/src/ide/editor/no-code-toolbar/no-code-toolbar.css
@@ -9,9 +9,16 @@
flex: 1;
overflow: hidden;
scroll-behavior: smooth;
- padding: 12px 0px 8px;
+ padding: 6px 12px;
+ margin-bottom: 6px;
display: flex;
align-items: center;
+ background-color: var(--menu-items-bg);
+ border-radius: 6px;
+}
+
+.no-code-toolbar-content > .ant-space {
+ padding-top: 11px;
}
/* Hidden toolbar items (overflow) */
diff --git a/frontend/src/ide/explorer/explorer-component.jsx b/frontend/src/ide/explorer/explorer-component.jsx
index 83ef24a..a578fdc 100644
--- a/frontend/src/ide/explorer/explorer-component.jsx
+++ b/frontend/src/ide/explorer/explorer-component.jsx
@@ -82,6 +82,7 @@ const IdeExplorer = ({
} = useProjectStore();
const currentSchema = useProjectStore((state) => state.currentSchema);
const setCurrentSchema = useProjectStore((state) => state.setCurrentSchema);
+ const setSchemaList = useProjectStore((state) => state.setSchemaList);
// Reset currentSchema on unmount to prevent stale data
useEffect(() => {
@@ -308,6 +309,9 @@ const IdeExplorer = ({
setCurrentSchema("");
}
+ // Store plain schema list in shared store
+ setSchemaList(allSchemas);
+
const items = allSchemas.map((el) => ({
label: el,
key: el,
diff --git a/frontend/src/store/project-store.js b/frontend/src/store/project-store.js
index e99f8d6..67be3b8 100644
--- a/frontend/src/store/project-store.js
+++ b/frontend/src/store/project-store.js
@@ -9,6 +9,7 @@ const STORE_VARIABLES = {
projectId: "",
renamedModel: {},
currentSchema: "",
+ schemaList: [],
};
const useProjectStore = create(
@@ -71,6 +72,11 @@ const useProjectStore = create(
return { currentSchema: schema };
});
},
+ setSchemaList: (list) => {
+ setState(() => {
+ return { schemaList: list };
+ });
+ },
}),
{
name: "project-tab-storage",