+
+
+
+ Need more help?
+
+
+ {"Tangle is open source. Reach out, share an idea, or report a bug."}
+
+
+
+ Ask the community
+
+
+ Report a bug
+
+
+
+
+ );
+}
diff --git a/src/components/Learn/LearnSearchBar.tsx b/src/components/Learn/LearnSearchBar.tsx
index 7ccbb19ea..7312ba3dd 100644
--- a/src/components/Learn/LearnSearchBar.tsx
+++ b/src/components/Learn/LearnSearchBar.tsx
@@ -2,6 +2,7 @@ import { useState } from "react";
import { Icon } from "@/components/ui/icon";
import { Input, InputGroup } from "@/components/ui/input";
+import { Text } from "@/components/ui/typography";
import { TANGLE_WEBSITE_URL } from "@/utils/constants";
import { tracking } from "@/utils/tracking";
@@ -17,24 +18,32 @@ export function LearnSearchBar() {
return (
}
+ suffixElement={
+
+
+ tangleml.com
+
+
+
+ }
>
setValue(e.target.value)}
onEnter={handleSubmit}
- aria-label="Search the Learning Hub"
- className="h-11 text-sm w-80"
+ aria-label="Search the Tangle docs (opens in a new tab)"
+ className="h-11 text-sm"
{...tracking("learning_hub.search.submit")}
/>
diff --git a/src/components/Learn/faq.json b/src/components/Learn/faq.json
new file mode 100644
index 000000000..437ff2e96
--- /dev/null
+++ b/src/components/Learn/faq.json
@@ -0,0 +1,52 @@
+[
+ {
+ "id": "create-pipeline",
+ "question": "How do I create my first pipeline?",
+ "answer": "Head to My Pipelines and click 'New pipeline', or import one of the example pipelines from the Learning Hub to get going in seconds."
+ },
+ {
+ "id": "components",
+ "question": "What's the difference between a component and a task?",
+ "answer": "Components are reusable building blocks defined in YAML. Tasks are individual instances of a component placed on the canvas as part of a pipeline."
+ },
+ {
+ "id": "share-pipeline",
+ "question": "Can I share a pipeline with someone else?",
+ "answer": "Yes. Export the pipeline as YAML from the editor and share the file. The recipient can import it from the home dashboard or open the import URL directly."
+ },
+ {
+ "id": "secrets",
+ "question": "How do I use secrets in my pipeline?",
+ "answer": "Go to Settings, then Secrets, and click Add Secret with a name and value. In the pipeline editor, click the dynamic data dropdown (database icon) on any task argument field, select Secret, and choose it by name. The value is injected at runtime and never stored in the pipeline YAML."
+ },
+ {
+ "id": "viewing-logs",
+ "question": "How do I view and debug logs for my pipeline components?",
+ "answer": "Select a task in the Pipeline Run view and click the Logs tab in the right panel to see error traces. If the Logs tab is empty, the container likely never started, so check the Details tab for error info. For subgraph nodes, double-click to navigate inside. Logs live on the inner tasks, not the parent."
+ },
+ {
+ "id": "caching",
+ "question": "How does caching work, and how do I control it?",
+ "answer": "Tangle automatically caches task results based on the container spec and a hash of all inputs. If the same task with the same inputs has run before, the cached result is reused instantly. To disable caching for a task, select it, open the Configuration tab, and toggle caching off."
+ },
+ {
+ "id": "runs",
+ "question": "How do I share, search, and navigate pipeline runs?",
+ "answer": "Select any task in a run and click the Copy node link button in the Arguments tab to get a shareable deep link to that specific node. Use the All Runs view in the Dashboard to search by pipeline name, creator, date range, or custom annotations."
+ },
+ {
+ "id": "complex-pipelines",
+ "question": "How do I structure complex pipelines with subgraphs, branching, and conditional execution?",
+ "answer": "Pipelines are graph components, so you can nest one pipeline inside another as a subgraph. Export it as YAML and import it as a component. Tasks with no data dependency run in parallel automatically; tasks with dependencies run sequentially. Conditional if/else branching is not yet supported. If a task fails, only its downstream dependents are affected; other branches continue."
+ },
+ {
+ "id": "manage-components",
+ "question": "How do I manage components: publishing, versioning, and reuse?",
+ "answer": "Components live in three places: User Components (browser-local, only you), Standard Library (built-in), and Published Components (shared workspace-wide). To publish, open the component info dialog from User Components, go to the Publish tab, and click Publish. Published components can't be deleted. Publish a new version instead."
+ },
+ {
+ "id": "cancel-pipeline",
+ "question": "How do I cancel a pipeline?",
+ "answer": "In the Pipeline Run view, click the Cancel button. Only the run creator can cancel. Completed tasks keep their results; only pending and running tasks are terminated."
+ }
+]
diff --git a/src/routes/Dashboard/Learn/LearnHomeView.test.tsx b/src/routes/Dashboard/Learn/LearnHomeView.test.tsx
index 74df084cd..4bf7014d0 100644
--- a/src/routes/Dashboard/Learn/LearnHomeView.test.tsx
+++ b/src/routes/Dashboard/Learn/LearnHomeView.test.tsx
@@ -34,7 +34,7 @@ describe("", () => {
test("renders the search bar", () => {
render();
expect(
- screen.getByRole("textbox", { name: /search the learning hub/i }),
+ screen.getByRole("textbox", { name: /search the tangle docs/i }),
).toBeInTheDocument();
});
@@ -48,7 +48,14 @@ describe("", () => {
).toBeInTheDocument();
});
- test("renders the tip of the day, tours, examples and documentation sections", () => {
+ test("renders the docs quicklinks and full-docs link at the top", () => {
+ render();
+ expect(screen.getByText("Getting started")).toBeInTheDocument();
+ expect(screen.getByText("Schema reference")).toBeInTheDocument();
+ expect(screen.getByText("Full docs")).toBeInTheDocument();
+ });
+
+ test("renders the tip, tours, examples and FAQ sections", () => {
render();
expect(
screen.getByRole("heading", { level: 3, name: /tip of the day/i }),
@@ -60,7 +67,7 @@ describe("", () => {
screen.getByRole("heading", { level: 2, name: /example pipelines/i }),
).toBeInTheDocument();
expect(
- screen.getByRole("heading", { level: 2, name: /documentation/i }),
+ screen.getByRole("heading", { level: 2, name: /frequently asked/i }),
).toBeInTheDocument();
});
});
diff --git a/src/routes/Dashboard/Learn/LearnHomeView.tsx b/src/routes/Dashboard/Learn/LearnHomeView.tsx
index 2b13c4bcd..ab8f741fa 100644
--- a/src/routes/Dashboard/Learn/LearnHomeView.tsx
+++ b/src/routes/Dashboard/Learn/LearnHomeView.tsx
@@ -1,6 +1,8 @@
-import { DocumentationPanel } from "@/components/Learn/DocumentationPanel";
+import { DocsQuickLinks } from "@/components/Learn/DocsQuickLinks";
+import { FaqPanel } from "@/components/Learn/FaqPanel";
import { FeaturedExamples } from "@/components/Learn/FeaturedExamples";
import { FeaturedTours } from "@/components/Learn/FeaturedTours";
+import { HelpCard } from "@/components/Learn/HelpCard";
import { LearnPageHeader } from "@/components/Learn/LearnPageHeader";
import { LearnSearchBar } from "@/components/Learn/LearnSearchBar";
import { OnboardingHero } from "@/components/Learn/OnboardingHero";
@@ -16,7 +18,10 @@ export function LearnHomeView() {
description="Everything you need to get the most out of Tangle, all in one place."
icon="GraduationCap"
/>
-
+
+
+
+
@@ -28,7 +33,14 @@ export function LearnHomeView() {
-
+