From 015067cd096db8bd9a81b9face0ec6c367b87b17 Mon Sep 17 00:00:00 2001 From: Victor Vazquez Date: Fri, 3 May 2024 15:22:45 -0700 Subject: [PATCH 1/2] adding support for template refs: As part of the list of templates, this PR is adding support to have an entry like: { "ref": "https://url/templates.json", "tags": ["aiApps"] } When this entry is found, awesome-azd will expand that entry into all the entries referenced on that url. Then, the tags are appended to the tags from the original entries. This feature allow a seemly experience to batch a group of templates which are already maintained as part of another source and avoid duplicity. --- .../components/gallery/ShowcaseCard/index.tsx | 4 +-- .../gallery/ShowcaseCardPanel/index.tsx | 4 +-- .../gallery/ShowcaseMultipleAuthors/index.tsx | 4 +-- .../components/gallery/ShowcaseTag/index.tsx | 2 +- website/src/data/tags.tsx | 10 ++++-- website/src/data/users.tsx | 30 +++++++++++++++--- website/src/pages/ShowcaseCardPage.tsx | 31 ++++++++++--------- website/src/pages/ShowcaseCards.tsx | 4 +-- website/static/templates.json | 4 +++ 9 files changed, 63 insertions(+), 30 deletions(-) diff --git a/website/src/components/gallery/ShowcaseCard/index.tsx b/website/src/components/gallery/ShowcaseCard/index.tsx index cb2c13b9..a6503526 100644 --- a/website/src/components/gallery/ShowcaseCard/index.tsx +++ b/website/src/components/gallery/ShowcaseCard/index.tsx @@ -5,7 +5,7 @@ import React from "react"; import styleCSS from "./styles.module.css"; -import { type User } from "../../../data/tags"; +import { type Template } from "../../../data/tags"; import useBaseUrl from "@docusaurus/useBaseUrl"; import { Card, @@ -60,7 +60,7 @@ const darkTheme: PartialTheme = { }, }; -function ShowcaseCard({ user }: { user: User }): JSX.Element { +function ShowcaseCard({ user }: { user: Template }): JSX.Element { const styles = useStyles(); const title = user.title; const tags = user.tags; diff --git a/website/src/components/gallery/ShowcaseCardPanel/index.tsx b/website/src/components/gallery/ShowcaseCardPanel/index.tsx index 94006163..fcfe0c3c 100644 --- a/website/src/components/gallery/ShowcaseCardPanel/index.tsx +++ b/website/src/components/gallery/ShowcaseCardPanel/index.tsx @@ -5,7 +5,7 @@ import React from "react"; import styles from "./styles.module.css"; -import { Tags, type User, type TagType } from "../../../data/tags"; +import { Tags, type Template, type TagType } from "../../../data/tags"; import { TagList } from "../../../data/users"; import { sortBy } from "@site/src/utils/jsUtils"; import useBaseUrl from "@docusaurus/useBaseUrl"; @@ -87,7 +87,7 @@ function CopyButton({ url, colorMode }: { url: string; colorMode: string }) { ); } -export default function ShowcaseCardPanel({ user }: { user: User }) { +export default function ShowcaseCardPanel({ user }: { user: Template }) { const [ isPopupVisibleTemplateDetails, { toggle: toggleIsPopupVisibleTemplateDetails }, diff --git a/website/src/components/gallery/ShowcaseMultipleAuthors/index.tsx b/website/src/components/gallery/ShowcaseMultipleAuthors/index.tsx index 3b146575..aacfaec7 100644 --- a/website/src/components/gallery/ShowcaseMultipleAuthors/index.tsx +++ b/website/src/components/gallery/ShowcaseMultipleAuthors/index.tsx @@ -5,7 +5,7 @@ import React from "react"; import styles from "./styles.module.css"; -import { type User } from "../../../data/tags"; +import { type Template } from "../../../data/tags"; import { makeStyles, Link as FluentUILink, @@ -115,7 +115,7 @@ export default function ShowcaseMultipleAuthors({ user, cardPanel, }: { - user: User; + user: Template; cardPanel: boolean; }) { const { colorMode } = useColorMode(); diff --git a/website/src/components/gallery/ShowcaseTag/index.tsx b/website/src/components/gallery/ShowcaseTag/index.tsx index 14faceac..9ab35d59 100644 --- a/website/src/components/gallery/ShowcaseTag/index.tsx +++ b/website/src/components/gallery/ShowcaseTag/index.tsx @@ -5,7 +5,7 @@ import React from "react"; import styles from "./styles.module.css"; -import { Tag, Tags, type User, type TagType } from "../../../data/tags"; +import { Tag, Tags, type Template, type TagType } from "../../../data/tags"; import { TagList } from "../../../data/users"; import { sortBy } from "@site/src/utils/jsUtils"; import { Badge, Tooltip, makeStyles } from "@fluentui/react-components"; diff --git a/website/src/data/tags.tsx b/website/src/data/tags.tsx index 54836741..009bb361 100644 --- a/website/src/data/tags.tsx +++ b/website/src/data/tags.tsx @@ -12,7 +12,7 @@ export type Tag = { type?: string; }; -export type User = { +export type Template = { title: string; description: string; preview: string; @@ -20,6 +20,7 @@ export type User = { author: string; source: string | null; tags: TagType[]; + ref: string; }; // NN: Updated TagType to suit Static Web Apps @@ -105,7 +106,8 @@ export type TagType = | "ruby" | "rubyonrails" | "serverlessapi" - | "langchain"; + | "langchain" + | "aiApps"; // LIST OF AVAILABLE TAGS // Each tag in lit about must have a defined object here @@ -137,6 +139,10 @@ export const Tags: { [type in TagType]: Tag } = { label: "Popular", description: "This tag is used for popular templates.", }, + aiApps: { + label: "AI Apps", + description: "This tag is used for AI Apps.", + }, //============ FOR REGULAR USE diff --git a/website/src/data/users.tsx b/website/src/data/users.tsx index dfaf182e..b3115561 100644 --- a/website/src/data/users.tsx +++ b/website/src/data/users.tsx @@ -6,7 +6,7 @@ /* eslint-disable global-require */ import { sortBy } from '../utils/jsUtils'; -import { TagType, User, Tags } from './tags'; +import { TagType, Template, Tags } from './tags'; import templates from '../../static/templates.json' // *** ADDING DATA TO AZD GALLERY ****/ @@ -16,12 +16,34 @@ import templates from '../../static/templates.json' // *************** CARD DATA STARTS HERE *********************** // Add your site to this list // prettier-ignore +const expandedTemplates: Template[] = []; + +const expand = async (source:Template[]):Promise => { + await Promise.all(source.map(async (template) => { + if (template.ref) { + const resp = await fetch(template.ref); + const data = await resp.json() as Template[]; + data.forEach((d) => { + expandedTemplates.push({...d, tags: [...d.tags, ...(template.tags || [])]}); + }); + } else { + expandedTemplates.push(template) + } + })); + + return expandedTemplates; +} -export const unsortedUsers: User[] = templates as User[] +export const unsortedUsers = (async ():Promise => { + if (expandedTemplates.length !== 0) { + return expandedTemplates; + } + return expand(templates as Template[]); +})(); export const TagList = Object.keys(Tags) as TagType[]; -function sortUsers() { - let result = unsortedUsers; +async function sortUsers() { + let result = await unsortedUsers; // Sort by site name result = sortBy(result, (user) => user.title.toLowerCase()); return result; diff --git a/website/src/pages/ShowcaseCardPage.tsx b/website/src/pages/ShowcaseCardPage.tsx index 3586c95c..9e970831 100644 --- a/website/src/pages/ShowcaseCardPage.tsx +++ b/website/src/pages/ShowcaseCardPage.tsx @@ -10,7 +10,7 @@ import { UserState, InputValue, } from "../components/gallery/ShowcaseTemplateSearch"; -import { type User, type TagType } from "../data/tags"; +import { type Template, type TagType } from "../data/tags"; import { sortedUsers, unsortedUsers } from "../data/users"; import { Text, Combobox, Option, Spinner } from "@fluentui/react-components"; import ShowcaseCards from "./ShowcaseCards"; @@ -32,19 +32,19 @@ const SORT_BY_OPTIONS = [ "Alphabetical (Z - A)", ]; -function readSortChoice(rule: string): User[] { +async function readSortChoice(rule: string): Promise { if (rule == SORT_BY_OPTIONS[0]) { - const copyUnsortedUser = unsortedUsers.slice(); + const copyUnsortedUser = (await unsortedUsers).slice(); return copyUnsortedUser.reverse(); } else if (rule == SORT_BY_OPTIONS[1]) { - return unsortedUsers; + return await unsortedUsers; } else if (rule == SORT_BY_OPTIONS[2]) { - return sortedUsers; + return await sortedUsers; } else if (rule == SORT_BY_OPTIONS[3]) { - const copySortedUser = sortedUsers.slice(); + const copySortedUser = (await sortedUsers).slice(); return copySortedUser.reverse(); } - return sortedUsers; + return await sortedUsers; } const SearchNameQueryKey = "name"; @@ -54,7 +54,7 @@ function readSearchName(search: string) { } function filterUsers( - users: User[], + users: Template[], selectedTags: TagType[], searchName: string | null ) { @@ -81,16 +81,17 @@ export default function ShowcaseCardPage() { const [selectedTags, setSelectedTags] = useState([]); const [searchName, setSearchName] = useState(null); - const [selectedUsers, setSelectedUsers] = useState([]); + const [selectedUsers, setSelectedUsers] = useState([]); const location = useLocation(); useEffect(() => { - setSelectedTags(readSearchTags(location.search)); - setSelectedUsers(readSortChoice(selectedOptions[0])); - setSearchName(readSearchName(location.search)); - restoreUserState(location.state); - - setLoading(false); + readSortChoice(selectedOptions[0]).then(templates =>{ + setSelectedTags(readSearchTags(location.search)); + setSelectedUsers(templates); + setSearchName(readSearchName(location.search)); + restoreUserState(location.state); + setLoading(false); + }) }, [location, selectedOptions]); var cards = useMemo( diff --git a/website/src/pages/ShowcaseCards.tsx b/website/src/pages/ShowcaseCards.tsx index 96298de8..1c743e3f 100644 --- a/website/src/pages/ShowcaseCards.tsx +++ b/website/src/pages/ShowcaseCards.tsx @@ -5,7 +5,7 @@ import React from "react"; import ShowcaseEmptyResult from "../components/gallery/ShowcaseEmptyResult"; -import { type User, type TagType } from "../data/tags"; +import { type Template, type TagType } from "../data/tags"; import styles from "./styles.module.css"; import ShowcaseCard from "../components/gallery/ShowcaseCard"; import ShowcaseContributionCard from "../components/gallery/ShowcaseContributionCard"; @@ -13,7 +13,7 @@ import ShowcaseContributionCard from "../components/gallery/ShowcaseContribution export default function ShowcaseCards({ filteredUsers, }: { - filteredUsers: User[]; + filteredUsers: Template[]; }) { const len = filteredUsers ? filteredUsers.length : 0; if (len === 0) { diff --git a/website/static/templates.json b/website/static/templates.json index e24c6341..9a05570b 100644 --- a/website/static/templates.json +++ b/website/static/templates.json @@ -1677,5 +1677,9 @@ "appinsights", "blobstorage" ] + }, + { + "ref": "https://cacheddkci2rpqggas.blob.core.windows.net/ai-templates/templates.json", + "tags": ["aiApps"] } ] From e07c43faad4956513479cb647f760722a908a9ca Mon Sep 17 00:00:00 2001 From: hemarina <104857065+hemarina@users.noreply.github.com> Date: Thu, 9 May 2024 10:03:30 -0700 Subject: [PATCH 2/2] Update website/src/data/tags.tsx --- website/src/data/tags.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/data/tags.tsx b/website/src/data/tags.tsx index 009bb361..9c232d18 100644 --- a/website/src/data/tags.tsx +++ b/website/src/data/tags.tsx @@ -141,7 +141,7 @@ export const Tags: { [type in TagType]: Tag } = { }, aiApps: { label: "AI Apps", - description: "This tag is used for AI Apps.", + description: "This tag is used for AI Apps templates gallery.", }, //============ FOR REGULAR USE