diff --git a/assets/js/analytics-events.tsx b/assets/js/analytics-events.tsx
index 73def257..1bbf4f9a 100644
--- a/assets/js/analytics-events.tsx
+++ b/assets/js/analytics-events.tsx
@@ -7,6 +7,7 @@ import { Alert } from "./components/alert";
import { urlify } from "./components/anchor-link";
import { Sidenav } from "./components/sidenav";
import { Heading } from "./components/heading";
+import { permalink, searchURL } from "./github-urls";
interface AnalyticsEventAttribute {
name: string;
@@ -15,10 +16,29 @@ interface AnalyticsEventAttribute {
}
interface AnalyticsEvent {
+ /**
+ * String name for the event (the one that gets logged to events.log)
+ */
event_name: string;
previous_event_names?: string[];
description: string;
attributes: AnalyticsEventAttribute[];
+ /**
+ * Ruby analytics method name
+ */
+ method_name?: string;
+ /**
+ * Source file that this documentation comes from
+ */
+ source_file?: string;
+ /**
+ * Line in source file where documentation comes from
+ */
+ source_line?: number;
+ /**
+ * SHA that documentation was generated from
+ */
+ source_sha?: string;
}
function Example({
@@ -101,11 +121,45 @@ function Event({ event }: { event: AnalyticsEvent }) {
previous_event_names: previousEventNames,
description,
attributes = [],
+ method_name: methodName,
+ source_file: sourceFile,
+ source_line: sourceLine,
+ source_sha: sourceSHA,
} = event;
return (
-
{eventName}
+
+ {eventName}
+
+ {methodName && sourceFile && sourceLine && (
+
+
+ Source definition
+
+ ,{" "}
+
+ source usages
+
+
+ )}
{description}
{previousEventNames?.length ? (
<>
diff --git a/assets/js/components/heading.tsx b/assets/js/components/heading.tsx
index d33a2de6..50c4437c 100644
--- a/assets/js/components/heading.tsx
+++ b/assets/js/components/heading.tsx
@@ -7,6 +7,7 @@ interface HeadingProps {
level: HeadingLevel;
id?: string;
+ className?: string;
children: string;
}
@@ -15,11 +16,12 @@ export function Heading({
level,
children,
id = urlify(children),
+ className,
}: HeadingProps) {
const TagName = level;
return (
-
+
{children}
diff --git a/assets/js/github.tsx b/assets/js/github-api.tsx
similarity index 100%
rename from assets/js/github.tsx
rename to assets/js/github-api.tsx
diff --git a/assets/js/github-urls.tsx b/assets/js/github-urls.tsx
new file mode 100644
index 00000000..0e653b05
--- /dev/null
+++ b/assets/js/github-urls.tsx
@@ -0,0 +1,61 @@
+export function permalink({
+ repo,
+ ref = "main",
+ file,
+ line,
+}: {
+ repo: string;
+ file: string;
+ ref?: string;
+ line?: number | string;
+}) {
+ return `https://github.com/${repo}/blob/${ref}/${file}${
+ line ? `#L${line}` : ""
+ }`;
+}
+
+export function searchURL({
+ needle,
+ repo,
+ extension,
+ path,
+ type,
+}: {
+ needle?: string;
+ path?: string;
+ repo?: string;
+ /**
+ * @example "rb"
+ */
+ extension?: string;
+ type?:
+ | "repositories"
+ | "code"
+ | "commits"
+ | "issues"
+ | "discussions"
+ | "registrypackages"
+ | "wikis"
+ | "users";
+}) {
+ const url = new URL("https://github.com/search");
+
+ const q = [
+ needle,
+ repo && `repo:${repo}`,
+ extension && `extension:${extension}`,
+ path && `path:${path}`,
+ ]
+ .filter(Boolean)
+ .join(" ");
+
+ if (q) {
+ url.searchParams.set("q", q);
+ }
+
+ if (type) {
+ url.searchParams.set("type", type);
+ }
+
+ return url.toString();
+}
diff --git a/assets/js/private-articles.tsx b/assets/js/private-articles.tsx
index 8d20b97b..7a7cdcfe 100644
--- a/assets/js/private-articles.tsx
+++ b/assets/js/private-articles.tsx
@@ -7,7 +7,7 @@ import { createPortal } from "preact/compat";
import { useQuery } from "preact-fetching";
import { useCurrentUser, PrivateLoginLink } from "./private";
import { Alert } from "./components/alert";
-import { fetchGitHubFile, isGithubDirectory, isGithubFile } from "./github";
+import { fetchGitHubFile, isGithubDirectory, isGithubFile } from "./github-api";
import { Navigation, SidenavWithWrapper } from "./components/sidenav";
import { Heading } from "./components/heading";
import type { HeadingLevel } from "./components/heading";