merge feature/ui_table into feature/ui_table

This commit is contained in:
igorrCarvalho 2024-04-29 19:01:27 -03:00
commit 7e95ca9689
10 changed files with 129 additions and 28 deletions

View file

@ -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 ###

View file

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

View file

@ -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")

View file

@ -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>
); );
} }

View file

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

View file

@ -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) => {

View file

@ -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) => {

View 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;
}

View file

@ -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;
}; };

View file

@ -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,