Merge branch 'fix/minor_ui_adjustments' of https://github.com/langflow-ai/langflow into fix/minor_ui_adjustments

This commit is contained in:
cristhianzl 2024-06-10 20:06:41 -03:00
commit 3cda01b9c6
17 changed files with 132 additions and 51 deletions

View file

@ -0,0 +1,38 @@
from typing import Optional
from langflow.custom import CustomComponent
from langflow.schema.message import Message
class MessageComponent(CustomComponent):
display_name = "Message"
description = "Creates a Message object given a Session ID."
def build_config(self):
return {
"sender": {
"options": ["Machine", "User"],
"display_name": "Sender Type",
},
"sender_name": {"display_name": "Sender Name"},
"text": {"display_name": "Text"},
"session_id": {
"display_name": "Session ID",
"info": "Session ID of the chat history.",
"input_types": ["Text"],
},
}
def build(
self,
sender: str = "User",
sender_name: Optional[str] = None,
session_id: Optional[str] = None,
text: str = "",
) -> Message:
message = Message(
text=text, sender=sender, sender_name=sender_name, flow_id=self.graph.flow_id, session_id=session_id
)
self.status = message
return message

View file

@ -1,5 +1,3 @@
from typing import List, Optional
from langflow.custom import CustomComponent from langflow.custom import CustomComponent
from langflow.memory import get_messages, store_message from langflow.memory import get_messages, store_message
from langflow.schema.message import Message from langflow.schema.message import Message
@ -7,36 +5,18 @@ from langflow.schema.message import Message
class StoreMessageComponent(CustomComponent): class StoreMessageComponent(CustomComponent):
display_name = "Store Message" display_name = "Store Message"
description = "Stores a chat message given a Session ID." description = "Stores a chat message."
beta: bool = True
def build_config(self): def build_config(self):
return { return {
"sender": {
"options": ["Machine", "User"],
"display_name": "Sender Type",
},
"sender_name": {"display_name": "Sender Name"},
"message": {"display_name": "Message"}, "message": {"display_name": "Message"},
"session_id": {
"display_name": "Session ID",
"info": "Session ID of the chat history.",
"input_types": ["Text"],
},
} }
def build( def build(
self, self,
sender: str = "User", message: Message,
sender_name: Optional[str] = None, ) -> Message:
session_id: Optional[str] = None, store_message(message, flow_id=self.graph.flow_id)
message: str = "", self.status = get_messages()
) -> List[Message]:
store_message(
message=Message(
text=message, sender=sender, sender_name=sender_name, flow_id=self.graph.flow_id, session_id=session_id
)
)
self.status = get_messages(session_id=session_id) return message
return get_messages(session_id=session_id)

View file

@ -46,7 +46,13 @@ def get_messages(
# so we need to reverse the order # so we need to reverse the order
messages_df = messages_df[::-1] if order == "DESC" else messages_df messages_df = messages_df[::-1] if order == "DESC" else messages_df
for row in messages_df.itertuples(): for row in messages_df.itertuples():
msg = Message(text=row.text, sender=row.sender, sender_name=row.sender_name, timestamp=row.timestamp) msg = Message(
text=row.text,
sender=row.sender,
session_id=row.session_id,
sender_name=row.sender_name,
timestamp=row.timestamp,
)
messages.append(msg) messages.append(msg)

View file

@ -156,3 +156,8 @@ body {
.react-flow__edge .react-flow__edge-path { .react-flow__edge .react-flow__edge-path {
stroke: var(--connection) !important; stroke: var(--connection) !important;
} }
.ag-react-container {
width: 100%;
height: 100%;
}

View file

@ -14,7 +14,13 @@ import sortByName from "./utils/sort-by-name";
//TODO IMPLEMENT FORM LOGIC //TODO IMPLEMENT FORM LOGIC
export default function AddNewVariableButton({ children }): JSX.Element { export default function AddNewVariableButton({
children,
asChild,
}: {
children: JSX.Element;
asChild?: boolean;
}): JSX.Element {
const [key, setKey] = useState(""); const [key, setKey] = useState("");
const [value, setValue] = useState(""); const [value, setValue] = useState("");
const [type, setType] = useState("Generic"); const [type, setType] = useState("Generic");
@ -87,7 +93,7 @@ export default function AddNewVariableButton({ children }): JSX.Element {
aria-hidden="true" aria-hidden="true"
/> />
</BaseModal.Header> </BaseModal.Header>
<BaseModal.Trigger asChild>{children}</BaseModal.Trigger> <BaseModal.Trigger asChild={asChild}>{children}</BaseModal.Trigger>
<BaseModal.Content> <BaseModal.Content>
<div className="flex h-full w-full flex-col gap-4 align-middle"> <div className="flex h-full w-full flex-col gap-4 align-middle">
<Label>Variable Name</Label> <Label>Variable Name</Label>

View file

@ -0,0 +1,9 @@
import Loading from "../../../ui/loading";
export default function LoadingOverlay() {
return (
<div className=" flex h-full w-full items-center justify-center bg-background align-middle">
<Loading />
</div>
);
}

View file

@ -28,7 +28,7 @@ export default function TableNodeCellRender({
value, value,
nodeClass, nodeClass,
handleOnNewValue: handleOnNewValueNode, handleOnNewValue: handleOnNewValueNode,
handleOnChangeDb, handleOnChangeDb: handleOnChangeDbNode,
}, },
}: CustomCellRendererProps) { }: CustomCellRendererProps) {
const handleOnNewValue = (newValue: any, name: string) => { const handleOnNewValue = (newValue: any, name: string) => {
@ -41,6 +41,15 @@ export default function TableNodeCellRender({
setTemplateValue(newValue); setTemplateValue(newValue);
}; };
const handleOnChangeDb = (newValue: boolean, name: string) => {
handleOnChangeDbNode(newValue, name);
setTemplateData((old) => {
let newData = cloneDeep(old);
newData.load_from_db = newValue;
return newData;
});
};
const [templateValue, setTemplateValue] = useState(value); const [templateValue, setTemplateValue] = useState(value);
const [templateData, setTemplateData] = useState(data); const [templateData, setTemplateData] = useState(data);

View file

@ -13,6 +13,7 @@ import ForwardedIconComponent from "../genericIconComponent";
import { Alert, AlertDescription, AlertTitle } from "../ui/alert"; import { Alert, AlertDescription, AlertTitle } from "../ui/alert";
import TableOptions from "./components/TableOptions"; import TableOptions from "./components/TableOptions";
import resetGrid from "./utils/reset-grid-columns"; import resetGrid from "./utils/reset-grid-columns";
import Loading from "../ui/loading";
interface TableComponentProps extends AgGridReactProps { interface TableComponentProps extends AgGridReactProps {
columnDefs: NonNullable<AgGridReactProps["columnDefs"]>; columnDefs: NonNullable<AgGridReactProps["columnDefs"]>;
@ -76,7 +77,7 @@ const TableComponent = forwardRef<
const dark = useDarkStore((state) => state.dark); const dark = useDarkStore((state) => state.dark);
const initialColumnDefs = useRef(colDef); const initialColumnDefs = useRef(colDef);
const [columnStateChange, setColumnStateChange] = useState(false); const [columnStateChange, setColumnStateChange] = useState(false);
const storeReference = props.columnDefs.map((e) => e.headerName).join("_");
const makeLastColumnNonResizable = (columnDefs) => { const makeLastColumnNonResizable = (columnDefs) => {
columnDefs.forEach((colDef, index) => { columnDefs.forEach((colDef, index) => {
colDef.resizable = index !== columnDefs.length - 1; colDef.resizable = index !== columnDefs.length - 1;
@ -89,13 +90,26 @@ const TableComponent = forwardRef<
realRef.current = params; realRef.current = params;
const updatedColumnDefs = makeLastColumnNonResizable([...colDef]); const updatedColumnDefs = makeLastColumnNonResizable([...colDef]);
params.api.setGridOption("columnDefs", updatedColumnDefs); params.api.setGridOption("columnDefs", updatedColumnDefs);
const customInit = localStorage.getItem(storeReference);
initialColumnDefs.current = params.api.getColumnDefs(); initialColumnDefs.current = params.api.getColumnDefs();
if (props.onGridReady) props.onGridReady(params); if (customInit && realRef.current) {
realRef.current.api.applyColumnState({
state: JSON.parse(customInit),
applyOrder: true,
});
}
setTimeout(() => { setTimeout(() => {
setColumnStateChange(false); if (customInit && realRef.current) {
}, 200); setColumnStateChange(true);
} else {
setColumnStateChange(false);
}
}, 50);
setTimeout(() => {
realRef.current.api.hideOverlay();
}, 1000);
if (props.onGridReady) props.onGridReady(params);
}; };
const onColumnMoved = (params) => { const onColumnMoved = (params) => {
const updatedColumnDefs = makeLastColumnNonResizable( const updatedColumnDefs = makeLastColumnNonResizable(
params.columnApi.getAllGridColumns().map((col) => col.getColDef()), params.columnApi.getAllGridColumns().map((col) => col.getColDef()),
@ -103,7 +117,6 @@ const TableComponent = forwardRef<
params.api.setGridOption("columnDefs", updatedColumnDefs); params.api.setGridOption("columnDefs", updatedColumnDefs);
if (props.onColumnMoved) props.onColumnMoved(params); if (props.onColumnMoved) props.onColumnMoved(params);
}; };
if (props.rowData.length === 0) { if (props.rowData.length === 0) {
return ( return (
<div className="flex h-full w-full items-center justify-center rounded-md border"> <div className="flex h-full w-full items-center justify-center rounded-md border">
@ -138,6 +151,10 @@ const TableComponent = forwardRef<
onColumnMoved={onColumnMoved} onColumnMoved={onColumnMoved}
onStateUpdated={(e) => { onStateUpdated={(e) => {
if (e.sources.some((source) => source.includes("column"))) { if (e.sources.some((source) => source.includes("column"))) {
localStorage.setItem(
storeReference,
JSON.stringify(realRef.current?.api?.getColumnState()),
);
setColumnStateChange(true); setColumnStateChange(true);
} }
}} }}
@ -152,6 +169,7 @@ const TableComponent = forwardRef<
resetGrid(realRef, initialColumnDefs); resetGrid(realRef, initialColumnDefs);
setTimeout(() => { setTimeout(() => {
setColumnStateChange(false); setColumnStateChange(false);
localStorage.removeItem(storeReference);
}, 100); }, 100);
}} }}
/> />

View file

@ -65,10 +65,15 @@ export default function ChatView({
.filter((output) => output.data.message) .filter((output) => output.data.message)
.map((output, index) => { .map((output, index) => {
try { try {
const { sender, message, sender_name, stream_url, files } = output console.log("output:", output);
.data.message as ChatOutputType; const { sender, message, sender_name, stream_url, files } =
output.data.message.message !== "" ||
(output.data.message.files ?? []).length > 0
? output.data.message
: output.data.artifacts;
const is_ai = sender === "Machine" || sender === null; const is_ai =
sender === "Machine" || sender === null || sender === undefined;
return { return {
isSend: !is_ai, isSend: !is_ai,
message: message, message: message,

View file

@ -371,7 +371,9 @@ export default function IOModal({
size="md" size="md"
className="block truncate" className="block truncate"
> >
{session} {session === currentFlow?.id
? "Default Session"
: session}
</Badge> </Badge>
</div> </div>
</ShadTooltip> </ShadTooltip>

View file

@ -6,6 +6,7 @@ import TableToggleCellRender from "../../../components/tableComponent/components
const useColumnDefs = ( const useColumnDefs = (
myData: any, myData: any,
handleOnNewValue: (newValue: any, name: string) => void, handleOnNewValue: (newValue: any, name: string) => void,
handleOnChangeDb: (value: boolean, key: string) => void,
changeAdvanced: (n: string) => void, changeAdvanced: (n: string) => void,
open: boolean, open: boolean,
) => { ) => {
@ -47,9 +48,7 @@ const useColumnDefs = (
value: params.data.value, value: params.data.value,
nodeClass: myData.node, nodeClass: myData.node,
handleOnNewValue: handleOnNewValue, handleOnNewValue: handleOnNewValue,
handleOnChangeDb: (value, key) => { handleOnChangeDb: handleOnChangeDb,
myData.node!.template[key].load_from_db = value;
},
}; };
}, },
minWidth: 340, minWidth: 340,

View file

@ -39,9 +39,12 @@ const EditNodeModal = forwardRef(
!myData.current.node!.template[n]?.advanced; !myData.current.node!.template[n]?.advanced;
} }
const handleOnNewValue = (newValue: any, name) => { const handleOnNewValue = (newValue: any, key: string) => {
console.log(newValue); myData.current.node!.template[key].value = newValue;
myData.current.node!.template[name].value = newValue; };
const handleOnChangeDb = (newValue: boolean, key: string) => {
myData.current.node!.template[key].load_from_db = newValue;
}; };
const rowData = useRowData(data, open); const rowData = useRowData(data, open);
@ -49,6 +52,7 @@ const EditNodeModal = forwardRef(
const columnDefs: ColDef[] = useColumnDefs( const columnDefs: ColDef[] = useColumnDefs(
data, data,
handleOnNewValue, handleOnNewValue,
handleOnChangeDb,
changeAdvanced, changeAdvanced,
open, open,
); );

View file

@ -36,7 +36,7 @@ export default function SettingsPage(): JSX.Element {
), ),
}, },
{ {
title: "API Keys", title: "Langflow API",
href: "/settings/api-keys", href: "/settings/api-keys",
icon: ( icon: (
<ForwardedIconComponent <ForwardedIconComponent

View file

@ -18,7 +18,7 @@ const ApiKeyHeaderComponent = ({
<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="flex items-center text-lg font-semibold tracking-tight"> <h2 className="flex items-center text-lg font-semibold tracking-tight">
API Keys Langflow API
<ForwardedIconComponent <ForwardedIconComponent
name="Key" name="Key"
className="ml-2 h-5 w-5 text-primary" className="ml-2 h-5 w-5 text-primary"

View file

@ -143,7 +143,7 @@ export default function GlobalVariablesPage() {
</p> </p>
</div> </div>
<div className="flex flex-shrink-0 items-center gap-2"> <div className="flex flex-shrink-0 items-center gap-2">
<AddNewVariableButton> <AddNewVariableButton asChild>
<Button data-testid="api-key-button-store" variant="primary"> <Button data-testid="api-key-button-store" variant="primary">
<IconComponent name="Plus" className="w-4" /> <IconComponent name="Plus" className="w-4" />
Add New Add New

View file

@ -291,7 +291,7 @@
} }
.main-page-nav-button { .main-page-nav-button {
@apply mr-2 w-4; @apply w-4;
} }
.main-page-description-text { .main-page-description-text {

View file

@ -170,7 +170,7 @@ export type VertexDataTypeAPI = {
inactive?: boolean; inactive?: boolean;
timedelta?: number; timedelta?: number;
duration?: string; duration?: string;
artifacts?: any; artifacts?: any | ChatOutputType | ChatInputType;
message: ChatOutputType | ChatInputType; message: ChatOutputType | ChatInputType;
}; };