merge feature/ui_table into feature/ui_table
This commit is contained in:
commit
7e95ca9689
10 changed files with 129 additions and 28 deletions
|
|
@ -0,0 +1,45 @@
|
||||||
|
"""Add default_fields column
|
||||||
|
|
||||||
|
Revision ID: 1f4d6df60295
|
||||||
|
Revises: 58b28437a398
|
||||||
|
Create Date: 2024-04-29 09:49:46.864145
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from alembic import op
|
||||||
|
from sqlalchemy.engine.reflection import Inspector
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = "1f4d6df60295"
|
||||||
|
down_revision: Union[str, None] = "58b28437a398"
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
conn = op.get_bind()
|
||||||
|
inspector = Inspector.from_engine(conn) # type: ignore
|
||||||
|
table_names = inspector.get_table_names()
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
column_names = [column["name"] for column in inspector.get_columns("variable")]
|
||||||
|
with op.batch_alter_table("variable", schema=None) as batch_op:
|
||||||
|
if "default_fields" not in column_names:
|
||||||
|
batch_op.add_column(sa.Column("default_fields", sa.JSON(), nullable=True))
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
conn = op.get_bind()
|
||||||
|
inspector = Inspector.from_engine(conn) # type: ignore
|
||||||
|
table_names = inspector.get_table_names()
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
column_names = [column["name"] for column in inspector.get_columns("variable")]
|
||||||
|
with op.batch_alter_table("variable", schema=None) as batch_op:
|
||||||
|
if "default_fields" in column_names:
|
||||||
|
batch_op.drop_column("default_fields")
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from datetime import datetime
|
from datetime import datetime, timezone
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
|
|
@ -85,7 +85,7 @@ def update_variable(
|
||||||
variable_data = variable.model_dump(exclude_unset=True)
|
variable_data = variable.model_dump(exclude_unset=True)
|
||||||
for key, value in variable_data.items():
|
for key, value in variable_data.items():
|
||||||
setattr(db_variable, key, value)
|
setattr(db_variable, key, value)
|
||||||
db_variable.updated_at = datetime.utcnow()
|
db_variable.updated_at = datetime.now(timezone.utc)
|
||||||
session.commit()
|
session.commit()
|
||||||
session.refresh(db_variable)
|
session.refresh(db_variable)
|
||||||
return db_variable
|
return db_variable
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import TYPE_CHECKING, Optional
|
from typing import TYPE_CHECKING, List, Optional
|
||||||
from uuid import UUID, uuid4
|
from uuid import UUID, uuid4
|
||||||
|
|
||||||
from sqlmodel import Column, DateTime, Field, Relationship, SQLModel, func
|
from sqlmodel import JSON, Column, DateTime, Field, Relationship, SQLModel, func
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from langflow.services.database.models.user.model import User
|
from langflow.services.database.models.user.model import User
|
||||||
|
|
@ -15,6 +15,7 @@ def utc_now():
|
||||||
class VariableBase(SQLModel):
|
class VariableBase(SQLModel):
|
||||||
name: Optional[str] = Field(None, description="Name of the variable")
|
name: Optional[str] = Field(None, description="Name of the variable")
|
||||||
value: Optional[str] = Field(None, description="Encrypted value of the variable")
|
value: Optional[str] = Field(None, description="Encrypted value of the variable")
|
||||||
|
default_fields: Optional[List[str]] = Field(sa_column=Column(JSON))
|
||||||
type: Optional[str] = Field(None, description="Type of the variable")
|
type: Optional[str] = Field(None, description="Type of the variable")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -35,6 +36,7 @@ class Variable(VariableBase, table=True):
|
||||||
sa_column=Column(DateTime(timezone=True), nullable=True),
|
sa_column=Column(DateTime(timezone=True), nullable=True),
|
||||||
description="Last update time of the variable",
|
description="Last update time of the variable",
|
||||||
)
|
)
|
||||||
|
default_fields: Optional[List[str]] = Field(sa_column=Column(JSON))
|
||||||
# foreign key to user table
|
# foreign key to user table
|
||||||
user_id: UUID = Field(description="User ID associated with this variable", foreign_key="user.id")
|
user_id: UUID = Field(description="User ID associated with this variable", foreign_key="user.id")
|
||||||
user: "User" = Relationship(back_populates="variables")
|
user: "User" = Relationship(back_populates="variables")
|
||||||
|
|
@ -56,3 +58,4 @@ class VariableUpdate(SQLModel):
|
||||||
id: UUID # Include the ID for updating
|
id: UUID # Include the ID for updating
|
||||||
name: Optional[str] = Field(None, description="Name of the variable")
|
name: Optional[str] = Field(None, description="Name of the variable")
|
||||||
value: Optional[str] = Field(None, description="Encrypted value of the variable")
|
value: Optional[str] = Field(None, description="Encrypted value of the variable")
|
||||||
|
default_fields: Optional[List[str]] = Field(None, description="Default fields for the variable")
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
|
import { ColDef, ColGroupDef } from "ag-grid-community";
|
||||||
import "ag-grid-community/styles/ag-grid.css"; // Mandatory CSS required by the grid
|
import "ag-grid-community/styles/ag-grid.css"; // Mandatory CSS required by the grid
|
||||||
import "ag-grid-community/styles/ag-theme-quartz.css"; // Optional Theme applied to the grid
|
import "ag-grid-community/styles/ag-theme-quartz.css"; // Optional Theme applied to the grid
|
||||||
import { AgGridReact } from "ag-grid-react";
|
import { AgGridReact } from "ag-grid-react";
|
||||||
import { ColDef,ColGroupDef } from 'ag-grid-community';
|
import { ColDef,ColGroupDef } from 'ag-grid-community';
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Card, CardContent, CardFooter } from "../ui/card";
|
import { useDarkStore } from "../../stores/darkStore";
|
||||||
|
import "../../style/ag-theme-shadcn.css"; // Custom CSS applied to the grid
|
||||||
|
import { cn } from "../../utils/utils";
|
||||||
|
import { Button } from "../ui/button";
|
||||||
|
|
||||||
export default function TableComponent() {
|
export default function TableComponent() {
|
||||||
// Column Definitions: Defines the columns to be displayed.
|
// Column Definitions: Defines the columns to be displayed.
|
||||||
const [colDefs, setColDefs] = useState<(ColDef<any> | ColGroupDef<any>)[]>([
|
const [colDefs, setColDefs] = useState<(ColDef<any> | ColGroupDef<any>)[]>([
|
||||||
{ headerName: "Variable Name",
|
{ headerName: "Variable Name", field: "name", flex: 1 }, //This column will be twice as wide as the others
|
||||||
field: "name",
|
|
||||||
flex: 1,
|
|
||||||
editable: true
|
|
||||||
}, //This column will be twice as wide as the others
|
|
||||||
{
|
{
|
||||||
|
|
||||||
field: "type",
|
field: "type",
|
||||||
|
|
@ -32,7 +32,7 @@ export default function TableComponent() {
|
||||||
editable: true,
|
editable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
headerName: "Default Fields",
|
headerName: "Apply To Fields",
|
||||||
field: "defaultFields",
|
field: "defaultFields",
|
||||||
flex: 1,
|
flex: 1,
|
||||||
editable: true,
|
editable: true,
|
||||||
|
|
@ -72,20 +72,18 @@ export default function TableComponent() {
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const dark = useDarkStore((state) => state.dark);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="mb-12 h-full">
|
<div className="flex h-full flex-col">
|
||||||
<CardContent className="flex h-full flex-col pt-4">
|
|
||||||
<div
|
<div
|
||||||
className="ag-theme-quartz h-full" // applying the grid theme
|
className={cn(
|
||||||
|
dark ? "ag-theme-quartz-dark" : "ag-theme-quartz",
|
||||||
|
"ag-theme-shadcn flex h-full flex-col pb-8"
|
||||||
|
)} // applying the grid theme
|
||||||
>
|
>
|
||||||
<AgGridReact columnDefs={colDefs} rowData={rowData} />
|
<AgGridReact pagination={true} columnDefs={colDefs} rowData={rowData} />
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</div>
|
||||||
<CardFooter>
|
|
||||||
<div className="text-xs text-muted-foreground">
|
|
||||||
Showing <strong>1-3</strong> of <strong>3</strong> products
|
|
||||||
</div>
|
|
||||||
</CardFooter>
|
|
||||||
</Card>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import IconComponent from "../../components/genericIconComponent";
|
import IconComponent from "../../components/genericIconComponent";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
|
|
||||||
|
import AddNewVariableButton from "../../components/addNewVariableButtonComponent/addNewVariableButton";
|
||||||
|
import ForwardedIconComponent from "../../components/genericIconComponent";
|
||||||
import TableComponent from "../../components/tableComponent";
|
import TableComponent from "../../components/tableComponent";
|
||||||
|
|
||||||
export default function GlobalVariablesPage() {
|
export default function GlobalVariablesPage() {
|
||||||
|
|
@ -8,17 +10,25 @@ export default function GlobalVariablesPage() {
|
||||||
<div className="flex h-full w-full flex-col justify-between gap-6">
|
<div className="flex h-full w-full flex-col justify-between gap-6">
|
||||||
<div className="flex w-full items-center justify-between gap-4 space-y-0.5">
|
<div className="flex w-full items-center justify-between gap-4 space-y-0.5">
|
||||||
<div className="flex w-full flex-col">
|
<div className="flex w-full flex-col">
|
||||||
<h2 className="text-xl font-bold tracking-tight">Global Variables</h2>
|
<h2 className="flex items-center text-lg font-semibold tracking-tight">
|
||||||
<p className="text-muted-foreground">
|
Global Variables
|
||||||
|
<ForwardedIconComponent
|
||||||
|
name="Globe"
|
||||||
|
className="ml-2 h-5 w-5 text-primary"
|
||||||
|
/>
|
||||||
|
</h2>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
Manage and assign global variables to default fields. You can add
|
Manage and assign global variables to default fields. You can add
|
||||||
new global variables by clicking the button.
|
new global variables by clicking the button.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-shrink-0">
|
<div className="flex-shrink-0">
|
||||||
<Button data-testid="api-key-button-store" variant="primary">
|
<AddNewVariableButton>
|
||||||
<IconComponent name="Plus" className="mr-2 w-4" />
|
<Button data-testid="api-key-button-store" variant="primary">
|
||||||
Add Global Variables
|
<IconComponent name="Plus" className="mr-2 w-4" />
|
||||||
</Button>
|
Add New
|
||||||
|
</Button>
|
||||||
|
</AddNewVariableButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,13 @@ import { GlobalVariablesStore } from "../types/zustand/globalVariables";
|
||||||
|
|
||||||
export const useGlobalVariablesStore = create<GlobalVariablesStore>(
|
export const useGlobalVariablesStore = create<GlobalVariablesStore>(
|
||||||
(set, get) => ({
|
(set, get) => ({
|
||||||
|
avaliableFields: [],
|
||||||
|
setAvaliableFields: (fields) => {
|
||||||
|
set({ avaliableFields: fields });
|
||||||
|
},
|
||||||
|
addAvaliableField: (field) => {
|
||||||
|
set({ avaliableFields: [...get().avaliableFields, field] });
|
||||||
|
},
|
||||||
globalVariablesEntries: [],
|
globalVariablesEntries: [],
|
||||||
globalVariables: {},
|
globalVariables: {},
|
||||||
setGlobalVariables: (variables) => {
|
setGlobalVariables: (variables) => {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ export const useTypesStore = create<TypesStoreType>((set, get) => ({
|
||||||
templates: templatesGenerator(data),
|
templates: templatesGenerator(data),
|
||||||
}));
|
}));
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
console.log(templatesGenerator(data))
|
||||||
resolve();
|
resolve();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
|
|
||||||
21
src/frontend/src/style/ag-theme-shadcn.css
Normal file
21
src/frontend/src/style/ag-theme-shadcn.css
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* set the background color of many elements across the grid */
|
||||||
|
.ag-theme-shadcn {
|
||||||
|
--ag-foreground-color: hsl(var(--foreground));
|
||||||
|
--ag-background-color: hsl(var(--background));
|
||||||
|
--ag-secondary-foreground-color: hsl(var(--secondary-foreground));
|
||||||
|
--ag-data-color: hsl(var(--foreground));
|
||||||
|
--ag-header-foreground-color: hsl(var(--muted-foreground));
|
||||||
|
--ag-header-background-color: hsl(var(--background));
|
||||||
|
--ag-tooltip-background-color: hsl(var(--muted));
|
||||||
|
--ag-disabled-foreground-color: hsl(var(--muted-foreground));
|
||||||
|
--ag-border-color: hsl(var(--border));
|
||||||
|
--ag-selected-row-background-color: hsl(var(--accent));
|
||||||
|
--ag-menu-background-color: hsl(var(--accent));
|
||||||
|
--ag-panel-background-color: hsl(var(--accent));
|
||||||
|
--ag-row-hover-color: hsl(var(--accent));
|
||||||
|
--ag-header-height: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ag-theme-shadcn .ag-paging-panel {
|
||||||
|
height: 3rem;
|
||||||
|
}
|
||||||
|
|
@ -7,4 +7,7 @@ export type GlobalVariablesStore = {
|
||||||
addGlobalVariable: (name: string, id: string, type?: string) => void;
|
addGlobalVariable: (name: string, id: string, type?: string) => void;
|
||||||
removeGlobalVariable: (name: string) => void;
|
removeGlobalVariable: (name: string) => void;
|
||||||
getVariableId: (name: string) => string | undefined;
|
getVariableId: (name: string) => string | undefined;
|
||||||
|
avaliableFields: Array<string>;
|
||||||
|
setAvaliableFields: (fields: Array<string>) => void;
|
||||||
|
addAvaliableField: (field: string) => void;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1234,6 +1234,19 @@ export function templatesGenerator(data: APIObjectType) {
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function extractFieldsFromComponenents(data:APIObjectType ) {
|
||||||
|
const fields = new Set();
|
||||||
|
Object.keys(data).forEach((key) => {
|
||||||
|
Object.keys(data[key]).forEach((kind) => {
|
||||||
|
Object.keys(data[key][kind].template).forEach((field) => {
|
||||||
|
if(data[key][kind].template[field].display_name && data[key][kind].template[field].show)
|
||||||
|
fields.add(data[key][kind].template[field].display_name);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return Array.from(fields);
|
||||||
|
}
|
||||||
|
|
||||||
export function downloadFlow(
|
export function downloadFlow(
|
||||||
flow: FlowType,
|
flow: FlowType,
|
||||||
flowName: string,
|
flowName: string,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue