chore: publish from main

This commit is contained in:
github-actions[bot]
2026-07-16 05:17:31 +00:00
parent 0fc2e10146
commit f7645b8fc4
9 changed files with 322 additions and 2185 deletions
File diff suppressed because it is too large Load Diff
+31 -13
View File
@@ -40,6 +40,19 @@ export interface CookbookRecipeMatch {
highlightedName?: string;
}
function buildCookbookRecipeUrl(
cookbookId: string,
languageId: string,
recipeId: string,
filePath?: string | null
): string {
const basePath = `/learning-hub/cookbook/${encodeURIComponent(
cookbookId
)}/${encodeURIComponent(languageId)}/${encodeURIComponent(recipeId)}/`;
if (!filePath) return basePath;
return `${basePath}#file=${encodeURIComponent(filePath)}`;
}
export function getRecipeResultsCountText(
filteredCount: number,
totalCount: number
@@ -211,27 +224,32 @@ function renderRecipeCard(
${
variant
? `
<button class="btn btn-secondary btn-small view-recipe-btn" data-doc="${escapeHtml(
variant.doc
<a class="btn btn-secondary btn-small" href="${buildCookbookRecipeUrl(
cookbook.id,
displayLanguage,
recipe.id
)}">
<svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor" aria-hidden="true">
<path d="M1 2.75A.75.75 0 0 1 1.75 2h12.5a.75.75 0 0 1 0 1.5H1.75A.75.75 0 0 1 1 2.75zm0 5A.75.75 0 0 1 1.75 7h12.5a.75.75 0 0 1 0 1.5H1.75A.75.75 0 0 1 1 7.75zM1.75 12h12.5a.75.75 0 0 1 0 1.5H1.75a.75.75 0 0 1 0-1.5z"/>
<path d="M1 2.75A.75.75 0 0 1 1.75 2h12.5a.75.75 0 0 1 0 1.5H1.75A.75.75 0 0 1 1 2.75zm0 5A.75.75 0 0 1 1.75 7h12.5a.75.75 0 0 1 0 1.5H1.75A.75.75 0 0 1 1 7.75zM1.75 12h12.5a.75.75 0 0 1 0 1.5H1.75a.75.75 0 0 1 0-1.5z"/>
</svg>
View Recipe
</button>
</a>
${
variant.example
? `
<button class="btn btn-secondary btn-small view-example-btn" data-example="${escapeHtml(
variant.example
? `
<a class="btn btn-secondary btn-small" href="${buildCookbookRecipeUrl(
cookbook.id,
displayLanguage,
recipe.id,
variant.example
)}">
<svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor" aria-hidden="true">
<path d="M4.72 3.22a.75.75 0 0 1 1.06 0l3.5 3.5a.75.75 0 0 1 0 1.06l-3.5 3.5a.75.75 0 0 1-1.06-1.06L7.69 7.5 4.72 4.28a.75.75 0 0 1 0-1.06zm6.25 1.06L10.22 5l.75.75-2.25 2.25 2.25 2.25-.75.75-.75-.72L11.97 7.5z"/>
</svg>
View Example
</button>
<svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor" aria-hidden="true">
<path d="M4.72 3.22a.75.75 0 0 1 1.06 0l3.5 3.5a.75.75 0 0 1 0 1.06l-3.5 3.5a.75.75 0 0 1-1.06-1.06L7.69 7.5 4.72 4.28a.75.75 0 0 1 0-1.06zm6.25 1.06L10.22 5l.75.75-2.25 2.25 2.25 2.25-.75.75-.75-.72L11.97 7.5z"/>
</svg>
View Example
</a>
`
: ""
: ""
}
<a href="https://github.com/github/awesome-copilot/blob/main/${escapeHtml(
variant.doc
+59 -37
View File
@@ -5,7 +5,6 @@
import { FuzzySearch, type SearchableItem } from "../search";
import { fetchData, debounce } from "../utils";
import { createChoices, getChoicesValues, type Choices } from "../choices";
import { setupModal } from "../modal";
import {
getRecipeResultsCountText,
renderCookbookSectionsHtml,
@@ -62,10 +61,10 @@ export async function initSamplesPage(): Promise<void> {
search = new FuzzySearch(allRecipes);
// Setup UI
setupModal();
handleLegacyCookbookHashLink();
setupFilters();
setupSearch();
setupRecipeListeners();
setupInteractionListeners();
updateResultsCount();
} catch (error) {
console.error("Failed to initialize samples page:", error);
@@ -259,38 +258,16 @@ function renderCookbooks(): void {
});
// Setup event listeners
setupRecipeListeners();
setupInteractionListeners();
}
/**
* Setup event listeners for recipe interactions
* Setup event listeners for cookbook interactions
*/
function setupRecipeListeners(): void {
// View recipe buttons
document.querySelectorAll(".view-recipe-btn").forEach((btn) => {
btn.addEventListener("click", async (e) => {
e.stopPropagation();
const docPath = (btn as HTMLElement).dataset.doc;
if (docPath) {
await showRecipeContent(docPath, "recipe");
}
});
});
// View example buttons
document.querySelectorAll(".view-example-btn").forEach((btn) => {
btn.addEventListener("click", async (e) => {
e.stopPropagation();
const examplePath = (btn as HTMLElement).dataset.example;
if (examplePath) {
await showRecipeContent(examplePath, "example");
}
});
});
function setupInteractionListeners(): void {
// Language tab clicks
document.querySelectorAll(".lang-tab").forEach((tab) => {
tab.addEventListener("click", (e) => {
tab.addEventListener("click", () => {
const langId = (tab as HTMLElement).dataset.lang;
if (langId) {
selectedLanguage = langId;
@@ -307,15 +284,60 @@ function setupRecipeListeners(): void {
}
/**
* Show recipe/example content in modal
* Redirect legacy cookbook #file=<path> links to canonical cookbook routes.
*/
async function showRecipeContent(
filePath: string,
type: "recipe" | "example"
): Promise<void> {
// Use existing modal infrastructure
const { openFileModal } = await import("../modal");
await openFileModal(filePath, type);
function handleLegacyCookbookHashLink(): void {
const hashMatch = window.location.hash.match(/^#file=(.+)$/);
if (!hashMatch) return;
let filePath: string;
try {
filePath = decodeURIComponent(hashMatch[1]);
} catch {
return;
}
const parsed = parseCookbookPath(filePath);
if (!parsed) return;
const nextUrl = `/learning-hub/cookbook/${encodeURIComponent(
parsed.cookbook
)}/${encodeURIComponent(parsed.language)}/${encodeURIComponent(
parsed.recipe
)}/${parsed.example ? `#file=${encodeURIComponent(filePath)}` : ""}`;
window.location.replace(nextUrl);
}
function parseCookbookPath(filePath: string): {
cookbook: string;
language: string;
recipe: string;
example: boolean;
} | null {
const docMatch = filePath.match(/^cookbook\/([^/]+)\/([^/]+)\/([^/]+)\.md$/);
if (docMatch) {
return {
cookbook: docMatch[1],
language: docMatch[2],
recipe: docMatch[3],
example: false,
};
}
const exampleMatch = filePath.match(
/^cookbook\/([^/]+)\/([^/]+)\/recipe\/([^/.]+)\.[^/.]+$/
);
if (exampleMatch) {
return {
cookbook: exampleMatch[1],
language: exampleMatch[2],
recipe: exampleMatch[3],
example: true,
};
}
return null;
}
/**