mirror of
https://github.com/langflow-ai/langflow.git
synced 2026-07-24 07:34:10 +08:00
fix(ui): Show welcome page for new users when AUTO_LOGIN is false (#12626)
* fix page displayed on AUTO LOGIN false * fix: translate Portuguese test comments to English --------- Co-authored-by: ogabrielluiz <gabriel@langflow.org>
This commit is contained in:
committed by
GitHub
parent
976bb699ce
commit
3fba536f03
@ -0,0 +1,97 @@
|
||||
import type { FlowType } from "@/types/flow";
|
||||
import type { FolderType } from "../../entities";
|
||||
import { shouldShowMainContent } from "../main-page-utils";
|
||||
|
||||
const makeFlow = (id: string): FlowType =>
|
||||
({ id, name: `flow-${id}`, is_component: false }) as FlowType;
|
||||
|
||||
const makeFolder = (id: string, name = "default"): FolderType => ({
|
||||
id,
|
||||
name,
|
||||
description: "",
|
||||
parent_id: "",
|
||||
flows: [],
|
||||
components: [],
|
||||
});
|
||||
|
||||
describe("shouldShowMainContent", () => {
|
||||
it("should_show_welcome_page_when_new_user_has_no_flows_and_examples_are_global_with_auto_login_off", () => {
|
||||
// Arrange — reproduces the exact bug scenario:
|
||||
// AUTO_LOGIN=false, new user on first login.
|
||||
// /flows/ returns [] (user_id == current_user.id doesn't match starters).
|
||||
// /basic_examples/ returns global STARTER_FOLDER flows (user_id=None).
|
||||
// User only has the default folder from get_or_create_default_folder.
|
||||
const flows: FlowType[] = [];
|
||||
const examples: FlowType[] = [
|
||||
makeFlow("starter-1"),
|
||||
makeFlow("starter-2"),
|
||||
makeFlow("starter-3"),
|
||||
];
|
||||
const folders: FolderType[] = [makeFolder("default-folder-id")];
|
||||
|
||||
// Act
|
||||
const result = shouldShowMainContent(flows, examples, folders);
|
||||
|
||||
// Assert — must be false so the Welcome page is shown
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it("should_show_welcome_page_when_user_flows_are_all_starter_examples_with_auto_login_on", () => {
|
||||
// AUTO_LOGIN=true: /flows/ returns starters via OR (user_id is None).
|
||||
// So flows and examples share the same ids.
|
||||
const sharedFlows = [
|
||||
makeFlow("starter-1"),
|
||||
makeFlow("starter-2"),
|
||||
makeFlow("starter-3"),
|
||||
];
|
||||
const folders: FolderType[] = [makeFolder("default-folder-id")];
|
||||
|
||||
const result = shouldShowMainContent(sharedFlows, sharedFlows, folders);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it("should_show_main_content_when_user_has_at_least_one_custom_flow_besides_examples", () => {
|
||||
const examples = [makeFlow("starter-1"), makeFlow("starter-2")];
|
||||
const flows = [...examples, makeFlow("user-custom-1")];
|
||||
const folders = [makeFolder("default-folder-id")];
|
||||
|
||||
const result = shouldShowMainContent(flows, examples, folders);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should_show_main_content_when_user_has_more_than_one_folder", () => {
|
||||
const flows: FlowType[] = [];
|
||||
const examples = [makeFlow("starter-1")];
|
||||
const folders = [
|
||||
makeFolder("default-folder-id"),
|
||||
makeFolder("extra-folder-id", "Extra"),
|
||||
];
|
||||
|
||||
const result = shouldShowMainContent(flows, examples, folders);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should_show_welcome_page_when_user_has_no_flows_and_no_examples_and_single_folder", () => {
|
||||
const result = shouldShowMainContent([], [], [makeFolder("default")]);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it("should_show_main_content_when_auto_login_off_user_creates_only_a_single_custom_flow", () => {
|
||||
// AUTO_LOGIN=false user creating their first custom flow.
|
||||
const flows = [makeFlow("my-first-flow")];
|
||||
const examples = [
|
||||
makeFlow("starter-1"),
|
||||
makeFlow("starter-2"),
|
||||
makeFlow("starter-3"),
|
||||
];
|
||||
const folders = [makeFolder("default-folder-id")];
|
||||
|
||||
const result = shouldShowMainContent(flows, examples, folders);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
13
src/frontend/src/pages/MainPage/pages/main-page-utils.ts
Normal file
13
src/frontend/src/pages/MainPage/pages/main-page-utils.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import type { FlowType } from "@/types/flow";
|
||||
import type { FolderType } from "../entities";
|
||||
|
||||
export function shouldShowMainContent(
|
||||
flows: FlowType[] | undefined,
|
||||
examples: FlowType[] | undefined,
|
||||
folders: FolderType[] | undefined,
|
||||
): boolean {
|
||||
if (!flows || !examples || !folders) return false;
|
||||
const exampleIds = new Set(examples.map((example) => example.id));
|
||||
const userOwnedFlows = flows.filter((flow) => !exampleIds.has(flow.id));
|
||||
return userOwnedFlows.length > 0 || folders.length > 1;
|
||||
}
|
||||
@ -11,7 +11,7 @@ import useAlertStore from "@/stores/alertStore";
|
||||
import useFlowsManagerStore from "@/stores/flowsManagerStore";
|
||||
import { useFolderStore } from "@/stores/foldersStore";
|
||||
import ModalsComponent from "../components/modalsComponent";
|
||||
import EmptyPageCommunity from "./empty-page";
|
||||
import { shouldShowMainContent } from "./main-page-utils";
|
||||
|
||||
export default function CollectionPage(): JSX.Element {
|
||||
const [openModal, setOpenModal] = useState(false);
|
||||
@ -54,33 +54,30 @@ export default function CollectionPage(): JSX.Element {
|
||||
);
|
||||
};
|
||||
|
||||
const showMainContent = shouldShowMainContent(flows, examples, folders);
|
||||
|
||||
return (
|
||||
<SidebarProvider width="280px">
|
||||
{flows &&
|
||||
examples &&
|
||||
folders &&
|
||||
((flows?.length !== examples?.length && folders?.length > 0) ||
|
||||
folders?.length > 1) && (
|
||||
<SideBarFoldersButtonsComponent
|
||||
handleChangeFolder={(id: string) => {
|
||||
navigate(`all/folder/${id}`);
|
||||
}}
|
||||
handleDeleteFolder={(item) => {
|
||||
setFolderToEdit(item);
|
||||
setOpenDeleteFolderModal(true);
|
||||
}}
|
||||
handleFilesClick={() => {
|
||||
navigate("assets");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{flows && examples && folders && showMainContent && (
|
||||
<SideBarFoldersButtonsComponent
|
||||
handleChangeFolder={(id: string) => {
|
||||
navigate(`all/folder/${id}`);
|
||||
}}
|
||||
handleDeleteFolder={(item) => {
|
||||
setFolderToEdit(item);
|
||||
setOpenDeleteFolderModal(true);
|
||||
}}
|
||||
handleFilesClick={() => {
|
||||
navigate("assets");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<main className="flex h-full w-full overflow-hidden">
|
||||
{flows && examples && folders ? (
|
||||
<div
|
||||
className={`relative mx-auto flex h-full w-full flex-col overflow-hidden`}
|
||||
>
|
||||
{(flows?.length !== examples?.length && folders?.length > 0) ||
|
||||
folders?.length > 1 ? (
|
||||
{showMainContent ? (
|
||||
<Outlet />
|
||||
) : (
|
||||
<CustomEmptyPageCommunity setOpenModal={setOpenModal} />
|
||||
|
||||
Reference in New Issue
Block a user