fix: adds table dropdown cell editor using options defined in TableInput column (#6825)

* Added options parameter to table

* Removed shadow from no-border on ag cell

* Added Table Dropdown Cell Editor

* Added options to column field type

* Rendered dropdown instead of text if column has options

* Changed structured output to use new options

* Updated starter projects

* Refactor: Simplify TableOptions field definitions

---------

Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
This commit is contained in:
Lucas Oliveira 2025-02-26 18:37:09 -03:00 • committed by GitHub
commit 45536d55e5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 73 additions and 11 deletions

View file

@ -5,7 +5,14 @@ from pydantic import BaseModel, Field, create_model
from langflow.base.models.chat_result import get_chat_result from langflow.base.models.chat_result import get_chat_result
from langflow.custom import Component from langflow.custom import Component
from langflow.helpers.base_model import build_model_from_schema from langflow.helpers.base_model import build_model_from_schema
from langflow.io import BoolInput, HandleInput, MessageTextInput, MultilineInput, Output, TableInput from langflow.io import (
BoolInput,
HandleInput,
MessageTextInput,
MultilineInput,
Output,
TableInput,
)
from langflow.schema.data import Data from langflow.schema.data import Data
from langflow.schema.dataframe import DataFrame from langflow.schema.dataframe import DataFrame
from langflow.schema.table import EditMode from langflow.schema.table import EditMode
@ -92,7 +99,8 @@ class StructuredOutputComponent(Component):
"description": ( "description": (
"Indicate the data type of the output field (e.g., str, int, float, bool, list, dict)." "Indicate the data type of the output field (e.g., str, int, float, bool, list, dict)."
), ),
"default": "text", "options": ["str", "int", "float", "bool", "list", "dict"],
"default": "str",
}, },
{ {
"name": "multiple", "name": "multiple",
@ -103,7 +111,14 @@ class StructuredOutputComponent(Component):
"edit_mode": EditMode.INLINE, "edit_mode": EditMode.INLINE,
}, },
], ],
value=[{"name": "field", "description": "description of field", "type": "text", "multiple": "False"}], value=[
{
"name": "field",
"description": "description of field",
"type": "str",
"multiple": "False",
}
],
), ),
BoolInput( BoolInput(
name="multiple", name="multiple",
@ -115,8 +130,16 @@ class StructuredOutputComponent(Component):
] ]
outputs = [ outputs = [
Output(name="structured_output", display_name="Structured Output", method="build_structured_output"), Output(
Output(name="structured_output_dataframe", display_name="DataFrame", method="as_dataframe"), name="structured_output",
display_name="Structured Output",
method="build_structured_output",
),
Output(
name="structured_output_dataframe",
display_name="DataFrame",
method="as_dataframe",
),
] ]
def build_structured_output_base(self) -> Data: def build_structured_output_base(self) -> Data:

File diff suppressed because one or more lines are too long

View file

@ -34,6 +34,7 @@ class Column(BaseModel):
model_config = ConfigDict(populate_by_name=True) model_config = ConfigDict(populate_by_name=True)
name: str name: str
display_name: str = Field(default="") display_name: str = Field(default="")
options: list[str] | None = Field(default=None)
sortable: bool = Field(default=True) sortable: bool = Field(default=True)
filterable: bool = Field(default=True) filterable: bool = Field(default=True)
formatter: FormatterType | str | None = Field(default=None) formatter: FormatterType | str | None = Field(default=None)

View file

@ -124,11 +124,12 @@ body {
/* This CSS is to not apply the border for the column having 'no-border' class */ /* This CSS is to not apply the border for the column having 'no-border' class */
.no-border.ag-cell:focus { .no-border.ag-cell:focus {
border: none !important; border: none !important;
outline: none; outline: none !important;
box-shadow: none !important;
} }
.no-border.ag-cell { .no-border.ag-cell {
border: none !important; border: none !important;
outline: none; outline: none !important;
} }
.react-flow__edge.selected .react-flow__edge-path { .react-flow__edge.selected .react-flow__edge-path {

View file

@ -0,0 +1,22 @@
import { CustomCellEditorProps } from "ag-grid-react";
import InputComponent from "../../../inputComponent";
export default function TableDropdownCellEditor({
value,
values,
onValueChange,
colDef,
}: CustomCellEditorProps & { values: string[] }) {
return (
<div className="flex h-full items-center px-2">
<InputComponent
setSelectedOption={(value) => onValueChange(value)}
value={value}
options={values}
password={false}
placeholder={"Select an option"}
id="apply-to-fields"
/>
</div>
);
}

View file

@ -28,4 +28,5 @@ export interface ColumnField {
default?: any; default?: any;
edit_mode?: "modal" | "inline" | "popover"; edit_mode?: "modal" | "inline" | "popover";
hidden?: boolean; hidden?: boolean;
options?: string[];
} }

View file

@ -1,4 +1,5 @@
import TableAutoCellRender from "@/components/core/parameterRenderComponent/components/tableComponent/components/tableAutoCellRender"; import TableAutoCellRender from "@/components/core/parameterRenderComponent/components/tableComponent/components/tableAutoCellRender";
import TableDropdownCellEditor from "@/components/core/parameterRenderComponent/components/tableComponent/components/tableDropdownCellEditor";
import TableToggleCellEditor from "@/components/core/parameterRenderComponent/components/tableComponent/components/tableToggleCellEditor"; import TableToggleCellEditor from "@/components/core/parameterRenderComponent/components/tableComponent/components/tableToggleCellEditor";
import useAlertStore from "@/stores/alertStore"; import useAlertStore from "@/stores/alertStore";
import { ColumnField, FormatterType } from "@/types/utils/functions"; import { ColumnField, FormatterType } from "@/types/utils/functions";
@ -566,8 +567,21 @@ export function FormatColumns(columns: ColumnField[]): ColDef<any>[] {
newCol.cellRendererParams = { newCol.cellRendererParams = {
formatter: col.formatter, formatter: col.formatter,
}; };
if (col.formatter !== FormatterType.text || col.edit_mode !== "inline") {
if ( if (
col.formatter !== FormatterType.text ||
col.edit_mode !== "inline" ||
col.options
) {
if (col.options && col.formatter === FormatterType.text) {
newCol.cellEditor = TableDropdownCellEditor;
newCol.cellEditorPopup = false;
newCol.cellEditorParams = {
values: col.options,
};
newCol.autoHeight = false;
newCol.cellClass = "no-border !py-2";
} else if (
col.edit_mode === "popover" && col.edit_mode === "popover" &&
col.formatter === FormatterType.text col.formatter === FormatterType.text
) { ) {