add grey out feature, update tag and hero text (#386)

* update tag and hover page

* remove tags

* add filter tag

* add clear all


* changes for checkbox as array

* update Azure AI Search

* fix bug

---------

Co-authored-by: Victor Vazquez <vhvb1989@gmail.com>
This commit is contained in:
hemarina 2024-05-17 18:07:05 -07:00 коммит произвёл GitHub
Родитель 7bb7b89cef
Коммит 9df16bb6ef
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
12 изменённых файлов: 480 добавлений и 144 удалений

Просмотреть файл

@ -17,13 +17,28 @@ import { Tags, type TagType } from "../../../data/tags";
import { TagList } from "../../../data/users";
import styles from "./styles.module.css";
import { useColorMode } from "@docusaurus/theme-common";
import { useHistory } from "@docusaurus/router";
import { prepareUserState } from "@site/src/pages/index";
import { UserState } from "../ShowcaseTemplateSearch";
function ShowcaseFilterViewAll({
tags,
number,
activeTags,
selectedCheckbox,
setSelectedCheckbox,
location,
readSearchTags,
replaceSearchTags,
}: {
tags: TagType[];
number: string;
activeTags: TagType[];
selectedCheckbox: TagType[];
setSelectedCheckbox: React.Dispatch<React.SetStateAction<TagType[]>>;
location;
readSearchTags: (search: string) => TagType[];
replaceSearchTags: (search: string, newTags: TagType[]) => string;
}) {
const [openItems, setOpenItems] = React.useState(["0"]);
const handleToggle: AccordionToggleEventHandler<string> = (event, data) => {
@ -62,11 +77,31 @@ function ShowcaseFilterViewAll({
className={styles.checkboxListItem}
style={{ marginBottom: "7px" }}
>
<ShowcaseTagSelect id={id} tag={tag} label={tagObject.label} />
<ShowcaseTagSelect
id={id}
tag={tag}
label={tagObject.label}
activeTags={activeTags}
selectedCheckbox={selectedCheckbox}
setSelectedCheckbox={setSelectedCheckbox}
location={location}
readSearchTags={readSearchTags}
replaceSearchTags={replaceSearchTags}
/>
</div>
) : (
<div key={key} className={styles.checkboxListItem}>
<ShowcaseTagSelect id={id} tag={tag} label={tagObject.label} />
<ShowcaseTagSelect
id={id}
tag={tag}
label={tagObject.label}
activeTags={activeTags}
selectedCheckbox={selectedCheckbox}
setSelectedCheckbox={setSelectedCheckbox}
location={location}
readSearchTags={readSearchTags}
replaceSearchTags={replaceSearchTags}
/>
</div>
);
})}
@ -90,6 +125,12 @@ function ShowcaseFilterViewAll({
id={id}
tag={tag}
label={tagObject.label}
activeTags={activeTags}
selectedCheckbox={selectedCheckbox}
setSelectedCheckbox={setSelectedCheckbox}
location={location}
readSearchTags={readSearchTags}
replaceSearchTags={replaceSearchTags}
/>
</div>
);
@ -118,7 +159,25 @@ function ShowcaseFilterViewAll({
);
}
export default function ShowcaseLeftFilters() {
export default function ShowcaseLeftFilters({
activeTags,
selectedCheckbox,
setSelectedCheckbox,
location,
selectedTags,
setSelectedTags,
readSearchTags,
replaceSearchTags,
}: {
activeTags: TagType[];
selectedCheckbox: TagType[];
setSelectedCheckbox: React.Dispatch<React.SetStateAction<TagType[]>>;
location;
selectedTags: TagType[];
setSelectedTags: React.Dispatch<React.SetStateAction<TagType[]>>;
readSearchTags: (search: string) => TagType[];
replaceSearchTags: (search: string, newTags: TagType[]) => string;
}) {
const sortTagList = TagList.sort();
const uncategoryTag = TagList.filter((tag) => {
const tagObject = Tags[tag];
@ -152,18 +211,22 @@ export default function ShowcaseLeftFilters() {
const tagObject = Tags[tag];
return tagObject.type === "Topic";
});
const [openItems, setOpenItems] = React.useState([
"1",
"2",
"3",
"4",
"5",
"6",
"7",
]);
const [openItems, setOpenItems] = React.useState([]);
const handleToggle: AccordionToggleEventHandler<string> = (event, data) => {
setOpenItems(data.openItems);
};
const history = useHistory();
const searchParams = new URLSearchParams(location.search);
const clearAll = () => {
setSelectedCheckbox([]);
setSelectedTags([]);
searchParams.delete("tags");
history.push({
...location,
search: searchParams.toString(),
state: prepareUserState(),
});
};
return (
<Accordion
openItems={openItems}
@ -172,14 +235,13 @@ export default function ShowcaseLeftFilters() {
collapsible
>
<div style={{ paddingBottom: "7px" }}>
<div
style={{
fontSize: "20px",
fontWeight: "500",
padding: "0 0 15px 12px",
}}
>
Filter by
<div className={styles.filterTop}>
<div className={styles.filterBy}>Filter by</div>
{selectedTags.length > 0 ? (
<div className={styles.clearAll} onClick={clearAll}>
Clear all
</div>
) : null}
</div>
{uncategoryTag.map((tag) => {
const tagObject = Tags[tag];
@ -192,7 +254,17 @@ export default function ShowcaseLeftFilters() {
className={styles.checkboxListItem}
style={{ paddingLeft: "12px" }}
>
<ShowcaseTagSelect id={id} tag={tag} label={tagObject.label} />
<ShowcaseTagSelect
id={id}
tag={tag}
label={tagObject.label}
activeTags={activeTags}
selectedCheckbox={selectedCheckbox}
setSelectedCheckbox={setSelectedCheckbox}
location={location}
readSearchTags={readSearchTags}
replaceSearchTags={replaceSearchTags}
/>
</div>
);
})}
@ -208,7 +280,16 @@ export default function ShowcaseLeftFilters() {
<div style={{ fontSize: "16px", fontWeight: "500" }}>Language</div>
</AccordionHeader>
<AccordionPanel>
<ShowcaseFilterViewAll tags={languageTag} number={"1"} />
<ShowcaseFilterViewAll
tags={languageTag}
number={"1"}
activeTags={activeTags}
selectedCheckbox={selectedCheckbox}
setSelectedCheckbox={setSelectedCheckbox}
location={location}
readSearchTags={readSearchTags}
replaceSearchTags={replaceSearchTags}
/>
</AccordionPanel>
</AccordionItem>
@ -223,7 +304,16 @@ export default function ShowcaseLeftFilters() {
<div style={{ fontSize: "16px", fontWeight: "500" }}>Framework</div>
</AccordionHeader>
<AccordionPanel>
<ShowcaseFilterViewAll tags={frameworkTag} number={"2"} />
<ShowcaseFilterViewAll
tags={frameworkTag}
number={"2"}
activeTags={activeTags}
selectedCheckbox={selectedCheckbox}
setSelectedCheckbox={setSelectedCheckbox}
location={location}
readSearchTags={readSearchTags}
replaceSearchTags={replaceSearchTags}
/>
</AccordionPanel>
</AccordionItem>
@ -238,7 +328,16 @@ export default function ShowcaseLeftFilters() {
<div style={{ fontSize: "16px", fontWeight: "500" }}>Services</div>
</AccordionHeader>
<AccordionPanel>
<ShowcaseFilterViewAll tags={servicesTag} number={"3"} />
<ShowcaseFilterViewAll
tags={servicesTag}
number={"3"}
activeTags={activeTags}
selectedCheckbox={selectedCheckbox}
setSelectedCheckbox={setSelectedCheckbox}
location={location}
readSearchTags={readSearchTags}
replaceSearchTags={replaceSearchTags}
/>
</AccordionPanel>
</AccordionItem>
@ -253,7 +352,16 @@ export default function ShowcaseLeftFilters() {
<div style={{ fontSize: "16px", fontWeight: "500" }}>Database</div>
</AccordionHeader>
<AccordionPanel>
<ShowcaseFilterViewAll tags={databaseTag} number={"4"} />
<ShowcaseFilterViewAll
tags={databaseTag}
number={"4"}
activeTags={activeTags}
selectedCheckbox={selectedCheckbox}
setSelectedCheckbox={setSelectedCheckbox}
location={location}
readSearchTags={readSearchTags}
replaceSearchTags={replaceSearchTags}
/>
</AccordionPanel>
</AccordionItem>
@ -270,7 +378,16 @@ export default function ShowcaseLeftFilters() {
</div>
</AccordionHeader>
<AccordionPanel>
<ShowcaseFilterViewAll tags={infrastructureAsCodeTag} number={"5"} />
<ShowcaseFilterViewAll
tags={infrastructureAsCodeTag}
number={"5"}
activeTags={activeTags}
selectedCheckbox={selectedCheckbox}
setSelectedCheckbox={setSelectedCheckbox}
location={location}
readSearchTags={readSearchTags}
replaceSearchTags={replaceSearchTags}
/>
</AccordionPanel>
</AccordionItem>
@ -285,7 +402,16 @@ export default function ShowcaseLeftFilters() {
<div style={{ fontSize: "16px", fontWeight: "500" }}>Tools</div>
</AccordionHeader>
<AccordionPanel>
<ShowcaseFilterViewAll tags={otherTag} number={"6"} />
<ShowcaseFilterViewAll
tags={otherTag}
number={"6"}
activeTags={activeTags}
selectedCheckbox={selectedCheckbox}
setSelectedCheckbox={setSelectedCheckbox}
location={location}
readSearchTags={readSearchTags}
replaceSearchTags={replaceSearchTags}
/>
</AccordionPanel>
</AccordionItem>
@ -300,7 +426,16 @@ export default function ShowcaseLeftFilters() {
<div style={{ fontSize: "16px", fontWeight: "500" }}>Topic</div>
</AccordionHeader>
<AccordionPanel>
<ShowcaseFilterViewAll tags={topicTag} number={"7"} />
<ShowcaseFilterViewAll
tags={topicTag}
number={"7"}
activeTags={activeTags}
selectedCheckbox={selectedCheckbox}
setSelectedCheckbox={setSelectedCheckbox}
location={location}
readSearchTags={readSearchTags}
replaceSearchTags={replaceSearchTags}
/>
</AccordionPanel>
</AccordionItem>
</Accordion>

Просмотреть файл

@ -15,3 +15,25 @@
.color {
color: var(--ifm-color-purple);
}
.filterTop {
display: flex;
align-items: center;
gap: 10px;
padding: 0 0 15px 12px;
}
.clearAll {
font-size: 14px;
font-weight: 400;
line-height: 20px;
text-decoration-line: underline;
cursor: pointer;
color: var(--ifm-color-purple);
}
.filterBy {
font-size: 20px;
font-weight: 600;
line-height: 28px;
}

Просмотреть файл

@ -3,47 +3,37 @@
* Licensed under the MIT License.
*/
import React, { useCallback, useState, useEffect } from "react";
import { useHistory, useLocation } from "@docusaurus/router";
import React, { useCallback, useEffect } from "react";
import { useHistory } from "@docusaurus/router";
import { toggleListItem } from "@site/src/utils/jsUtils";
import { prepareUserState } from "@site/src/pages/index";
import { type TagType } from "@site/src/data/tags";
import { Checkbox } from "@fluentui/react-components";
const TagQueryStringKey = "tags";
export function readSearchTags(search: string): TagType[] {
return new URLSearchParams(search).getAll(TagQueryStringKey) as TagType[];
}
function replaceSearchTags(search: string, newTags: TagType[]) {
const searchParams = new URLSearchParams(search);
searchParams.delete(TagQueryStringKey);
newTags.forEach((tag) => searchParams.append(TagQueryStringKey, tag));
return searchParams.toString();
}
export default function ShowcaseTagSelect(
// id: string,
{
label,
tag,
id,
}: {
label: string;
tag: TagType;
id: string;
}
): JSX.Element {
const location = useLocation();
export default function ShowcaseTagSelect({
label,
tag,
id,
activeTags,
selectedCheckbox,
setSelectedCheckbox,
location,
readSearchTags,
replaceSearchTags,
}: {
label: string;
tag: TagType;
id: string;
activeTags: TagType[];
selectedCheckbox: TagType[];
setSelectedCheckbox: React.Dispatch<React.SetStateAction<TagType[]>>;
location;
readSearchTags: (search: string) => TagType[];
replaceSearchTags: (search: string, newTags: TagType[]) => string;
}): JSX.Element {
const history = useHistory();
const [selected, setSelected] = useState(false);
useEffect(() => {
const tags = readSearchTags(location.search);
setSelected(tags.includes(tag));
}, [tag, location]);
const toggleTag = useCallback(() => {
// updates only the url query
const toggleTag = () => {
const tags = readSearchTags(location.search);
const newTags = toggleListItem(tags, tag);
const newSearch = replaceSearchTags(location.search, newTags);
@ -52,9 +42,19 @@ export default function ShowcaseTagSelect(
search: newSearch,
state: prepareUserState(),
});
}, [tag, location, history]);
const template = id.replace("showcase_checkbox_id_", "")
const contentForAdobeAnalytics = `{\"id\":\"${template}\",\"cN\":\"Tags\"}`
};
const template = id.replace("showcase_checkbox_id_", "");
const contentForAdobeAnalytics = `{\"id\":\"${template}\",\"cN\":\"Tags\"}`;
const toggleCheck = (tag: TagType) => {
if (selectedCheckbox.includes(tag)) {
setSelectedCheckbox(selectedCheckbox.filter((item) => item !== tag));
} else {
setSelectedCheckbox([...selectedCheckbox, tag]);
}
};
return (
<>
<Checkbox
@ -64,10 +64,15 @@ export default function ShowcaseTagSelect(
if (e.key === "Enter") {
toggleTag();
}
toggleCheck(tag);
}}
onChange={toggleTag}
checked={selected}
onChange={() => {
toggleTag();
toggleCheck(tag);
}}
checked={selectedCheckbox.includes(tag)}
label={label}
disabled={!activeTags?.includes(tag)}
/>
</>
);

Просмотреть файл

@ -14,7 +14,7 @@ import { useColorMode } from "@docusaurus/theme-common";
const TITLE = "Template Library";
const DESCRIPTION =
"A community-contributed template gallery built to work with the Azure Developer CLI.";
"An open-source template gallery to get started with Azure.";
const ADD_URL = "https://aka.ms/azd";
export var InputValue: string | null = null;
@ -159,17 +159,28 @@ export default function ShowcaseTemplateSearch() {
size={300}
style={{
color: "#242424",
padding: "20px 0",
paddingTop: "20px",
}}
>
Not familiar with the Azure Developer CLI (azd)?
Each template is a fully working, cloud-ready application deployable
with the Azure Developer CLI (azd).{" "}
</Text>
<Text
align="center"
size={300}
style={{
color: "#242424",
paddingBottom: "20px",
}}
>
New to azd? Welcome!
<FluentUILink
href={ADD_URL}
target="_blank"
style={{ paddingLeft: "3px" }}
className={styles.learnMoreColor}
>
Learn more
Learn more in our docs.
</FluentUILink>
</Text>
</div>

Просмотреть файл

@ -47,7 +47,6 @@ export type TagType =
| "keyvault"
| "aca"
| "mongodb"
| "signalR"
| "functions"
| "blobstorage"
| "azuredb-postgreSQL"
@ -59,11 +58,9 @@ export type TagType =
| "servicebus"
| "vnets"
| "fastapi"
| "fhir"
| "ahds"
| "appinsights"
| "loganalytics"
| "cognitivesearch"
| "aisearch"
| "openai"
| "azureai"
| "flask"
@ -75,7 +72,6 @@ export type TagType =
| "sapcloudsdk"
| "nestjs"
| "dataverse"
| "chatgpt"
| "aks"
| "azurecdn"
| "frontdoor"
@ -212,11 +208,6 @@ export const Tags: { [type in TagType]: Tag } = {
description: "Template architecture uses Thymeleaf template engine",
type: "Tools",
},
chatgpt: {
label: "ChatGPT",
description: "Template architecture uses ChatGPT application",
type: "Tools",
},
"dall-e": {
label: "Dall-E",
description: "Template architecture uses Dall-E",
@ -345,12 +336,6 @@ export const Tags: { [type in TagType]: Tag } = {
},
// ---- Service
fhir: {
label: "FHIR Service",
description:
"Template architecture uses Fast Healthcare Interoperability Resources (FHIR) service",
type: "Service",
},
dataverse: {
label: "Dataverse",
description: "Template architecture uses Microsoft Dataverse",
@ -368,14 +353,6 @@ export const Tags: { [type in TagType]: Tag } = {
},
// ---- Azure Services
ahds: {
label: "Azure Health Data Service",
description:
"Template architecture uses Azure Health Data Services workspace",
azureIcon: "./img/Azure-Health-Data-Service.svg",
url: "https://azure.microsoft.com/products/health-data-services/",
type: "Service",
},
appinsights: {
label: "Azure Application Insights",
description: "Template architecture uses Azure Application Insights",
@ -425,13 +402,6 @@ export const Tags: { [type in TagType]: Tag } = {
url: "https://azure.microsoft.com/products/cosmos-db/",
type: "Service",
},
signalR: {
label: "Azure SignalR",
description: "Template architecture uses Azure SignalR",
azureIcon: "./img/Azure-SignalR.svg",
url: "https://azure.microsoft.com/products/signalr-service",
type: "Service",
},
functions: {
label: "Azure Functions",
description: "Template architecture uses Azure Functions",
@ -488,11 +458,11 @@ export const Tags: { [type in TagType]: Tag } = {
url: "https://azure.microsoft.com/products/virtual-network",
type: "Service",
},
cognitivesearch: {
label: "Azure Cognitive Search",
description: "Template architecture uses Azure Cognitive Search",
azureIcon: "./img/Azure-Cognitive-Search.svg",
url: "https://azure.microsoft.com/products/ai-services/cognitive-search",
aisearch: {
label: "Azure AI Search",
description: "Template architecture uses Azure AI Search",
azureIcon: "./img/Azure-AI-Search.svg",
url: "https://azure.microsoft.com/products/ai-services/ai-search",
type: "Service",
},
openai: {

Просмотреть файл

@ -3,17 +3,55 @@
* Licensed under the MIT License.
*/
import React, { useState, useMemo, useEffect } from "react";
import { readSearchTags } from "../components/gallery/ShowcaseTagSelect";
import { useLocation } from "@docusaurus/router";
import React, { useState, useMemo, useEffect, useCallback } from "react";
import {
UserState,
InputValue,
} from "../components/gallery/ShowcaseTemplateSearch";
import { type User, type TagType } from "../data/tags";
import { Tags, type User, type TagType } from "../data/tags";
import { sortedUsers, unsortedUsers } from "../data/users";
import { Text, Combobox, Option, Spinner } from "@fluentui/react-components";
import {
Text,
Combobox,
Option,
Spinner,
Badge,
} from "@fluentui/react-components";
import ShowcaseCards from "./ShowcaseCards";
import useBaseUrl from "@docusaurus/useBaseUrl";
import styles from "./styles.module.css";
import { useColorMode } from "@docusaurus/theme-common";
import { useHistory } from "@docusaurus/router";
import { toggleListItem } from "@site/src/utils/jsUtils";
import { prepareUserState } from "./index";
const TagQueryStringKey2 = "tags";
const readSearchTags2 = (search: string): TagType[] => {
return new URLSearchParams(search).getAll(TagQueryStringKey2) as TagType[];
}
function replaceSearchTags(search: string, newTags: TagType[]) {
const searchParams = new URLSearchParams(search);
searchParams.delete(TagQueryStringKey2);
newTags.forEach((tag) => searchParams.append(TagQueryStringKey2, tag));
return searchParams.toString();
}
// updates only the url query
const toggleTag = (tag: TagType, location: Location) => {
const history = useHistory();
return useCallback(() => {
const tags = readSearchTags2(location.search);
const newTags = toggleListItem(tags, tag);
const newSearch = replaceSearchTags(location.search, newTags);
history.push({
...location,
search: newSearch,
state: prepareUserState(),
});
}, [tag, location, history]);
}
function restoreUserState(userState: UserState | null) {
const { scrollTopPosition, focusedElementId } = userState ?? {
@ -64,7 +102,7 @@ function filterUsers(
user.title.toLowerCase().includes(searchName.toLowerCase())
);
}
if (!selectedTags && selectedTags.length === 0) {
if (!selectedTags || selectedTags.length === 0) {
return users;
}
return users.filter((user) => {
@ -75,21 +113,103 @@ function filterUsers(
});
}
export default function ShowcaseCardPage() {
function FilterAppliedBar({
clearAll,
selectedTags,
}: {
clearAll;
selectedTags: TagType[];
}) {
const { colorMode } = useColorMode();
return selectedTags.length > 0 ? (
<div
style={{
paddingTop: "32px",
display: "flex",
gap: "12px",
alignItems: "center",
}}
>
<div
style={{
fontSize: "14px",
fontWeight: "400",
lineHeight: "20px",
}}
>
Filters applied:
</div>
{selectedTags.map((tag, index) => {
const tagObject = Tags[tag];
const key = `showcase_checkbox_key_${tag}`;
const id = `showcase_checkbox_id_${tag}`;
return (
<Badge
appearance="tint"
size="extra-large"
color="brand"
shape="rounded"
icon={
colorMode != "dark" ? (
<img
src={useBaseUrl("/img/lightModePurpleClose.svg")}
height={20}
alt="Close"
/>
) : (
<img
src={useBaseUrl("/img/darkModePurpleClose.svg")}
height={20}
alt="Close"
/>
)
}
iconPosition="after"
className={styles.filterBadge}
onClick={() => {
toggleTag(tag, location);
}}
>
{tagObject.label}
</Badge>
);
})}
<div className={styles.clearAll} onClick={clearAll}>
Clear all
</div>
</div>
) : null;
}
export default function ShowcaseCardPage({
setActiveTags,
selectedTags,
location,
setSelectedTags,
readSearchTags,
replaceSearchTags,
}: {
setActiveTags: React.Dispatch<React.SetStateAction<TagType[]>>;
selectedTags: TagType[];
location;
setSelectedTags: React.Dispatch<React.SetStateAction<TagType[]>>;
readSearchTags: (search: string) => TagType[];
replaceSearchTags: (search: string, newTags: TagType[]) => string;
}) {
const [selectedOptions, setSelectedOptions] = useState<string[]>([]);
const [loading, setLoading] = useState(true);
const [selectedTags, setSelectedTags] = useState<TagType[]>([]);
const [searchName, setSearchName] = useState<string | null>(null);
const [selectedUsers, setSelectedUsers] = useState<User[]>([]);
const location = useLocation<UserState>();
const clearAll = () => {
setSelectedTags([]);
};
useEffect(() => {
setSelectedTags(readSearchTags(location.search));
setSelectedUsers(readSortChoice(selectedOptions[0]));
setSearchName(readSearchName(location.search));
restoreUserState(location.state);
setLoading(false);
}, [location, selectedOptions]);
@ -98,6 +218,12 @@ export default function ShowcaseCardPage() {
[selectedUsers, selectedTags, searchName]
);
useEffect(() => {
const unionTags = new Set<TagType>();
cards.forEach((user) => user.tags.forEach((tag) => unionTags.add(tag)));
setActiveTags(Array.from(unionTags));
}, [cards]);
const sortByOnSelect = (event, data) => {
setLoading(true);
setSelectedOptions(data.selectedOptions);
@ -158,6 +284,7 @@ export default function ShowcaseCardPage() {
</Combobox>
</div>
</div>
{/* <FilterAppliedBar clearAll={clearAll} selectedTags={selectedTags} /> */}
{loading ? (
<Spinner labelPosition="below" label="Loading..." />
) : (

Просмотреть файл

@ -16,10 +16,12 @@ import {
} from "@fluentui/react-components";
import { initializeIcons } from "@fluentui/react/lib/Icons";
import ExecutionEnvironment from "@docusaurus/ExecutionEnvironment";
import { type TagType } from "@site/src/data/tags";
import { TagList } from "@site/src/data/users";
import styles from "./styles.module.css";
import { useColorMode } from "@docusaurus/theme-common";
import ShowcaseCardPage from "./ShowcaseCardPage";
import { useLocation } from "@docusaurus/router";
initializeIcons();
@ -34,15 +36,32 @@ export function prepareUserState(): UserState | undefined {
return undefined;
}
const TagQueryStringKey = "tags";
const readSearchTags = (search: string): TagType[] => {
return new URLSearchParams(search).getAll(TagQueryStringKey) as TagType[];
};
const replaceSearchTags = (search: string, newTags: TagType[]) => {
const searchParams = new URLSearchParams(search);
searchParams.delete(TagQueryStringKey);
newTags.forEach((tag) => searchParams.append(TagQueryStringKey, tag));
return searchParams.toString();
};
const App = () => {
const { colorMode } = useColorMode();
const [loading, setLoading] = useState(true);
const [activeTags, setActiveTags] = useState<TagType[]>(TagList);
const [selectedCheckbox, setSelectedCheckbox] = useState<TagType[]>([]);
const location = useLocation<UserState>();
const [selectedTags, setSelectedTags] = useState<TagType[]>([]);
useEffect(() => {
setSelectedTags(readSearchTags(location.search));
setSelectedCheckbox(readSearchTags(location.search));
setTimeout(() => {
setLoading(false);
}, 500);
}, []);
}, [location]);
return !loading ? (
<FluentProvider
@ -51,10 +70,26 @@ const App = () => {
<ShowcaseTemplateSearch />
<div className={styles.filterAndCard}>
<div className={styles.filter}>
<ShowcaseLeftFilters />
<ShowcaseLeftFilters
activeTags={activeTags}
selectedCheckbox={selectedCheckbox}
setSelectedCheckbox={setSelectedCheckbox}
location={location}
setSelectedTags={setSelectedTags}
selectedTags={selectedTags}
readSearchTags={readSearchTags}
replaceSearchTags={replaceSearchTags}
/>
</div>
<div className={styles.card}>
<ShowcaseCardPage />
<ShowcaseCardPage
setActiveTags={setActiveTags}
selectedTags={selectedTags}
location={location}
setSelectedTags={setSelectedTags}
readSearchTags={readSearchTags}
replaceSearchTags={replaceSearchTags}
/>
</div>
</div>
</FluentProvider>

Просмотреть файл

@ -124,6 +124,27 @@
width: 100%;
}
.clearAll {
font-size: 14px;
font-weight: 400;
line-height: 20px;
text-decoration-line: underline;
cursor: pointer;
color: var(--ifm-color-purple);
}
.filterBadge {
color: var(--ifm-color-purple);
cursor: pointer;
border: 1px solid #d2ccf8;
background: #f9f8fe;
}
[data-theme="dark"] .filterBadge {
border: 1px solid #221d46;
background: #3f3682;
}
@media screen and (max-width: 996px) {
.filterAndCard {
flex-direction: column;

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 1.2 KiB

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Просмотреть файл

@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Dismiss">
<path id="Shape" d="M4.08859 4.21569L4.14645 4.14645C4.32001 3.97288 4.58944 3.9536 4.78431 4.08859L4.85355 4.14645L10 9.293L15.1464 4.14645C15.32 3.97288 15.5894 3.9536 15.7843 4.08859L15.8536 4.14645C16.0271 4.32001 16.0464 4.58944 15.9114 4.78431L15.8536 4.85355L10.707 10L15.8536 15.1464C16.0271 15.32 16.0464 15.5894 15.9114 15.7843L15.8536 15.8536C15.68 16.0271 15.4106 16.0464 15.2157 15.9114L15.1464 15.8536L10 10.707L4.85355 15.8536C4.67999 16.0271 4.41056 16.0464 4.21569 15.9114L4.14645 15.8536C3.97288 15.68 3.9536 15.4106 4.08859 15.2157L4.14645 15.1464L9.293 10L4.14645 4.85355C3.97288 4.67999 3.9536 4.41056 4.08859 4.21569L4.14645 4.14645L4.08859 4.21569Z" fill="#A79CF1"/>
</g>
</svg>

После

Ширина:  |  Высота:  |  Размер: 815 B

Просмотреть файл

@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Dismiss">
<path id="Shape" d="M4.08859 4.21569L4.14645 4.14645C4.32001 3.97288 4.58944 3.9536 4.78431 4.08859L4.85355 4.14645L10 9.293L15.1464 4.14645C15.32 3.97288 15.5894 3.9536 15.7843 4.08859L15.8536 4.14645C16.0271 4.32001 16.0464 4.58944 15.9114 4.78431L15.8536 4.85355L10.707 10L15.8536 15.1464C16.0271 15.32 16.0464 15.5894 15.9114 15.7843L15.8536 15.8536C15.68 16.0271 15.4106 16.0464 15.2157 15.9114L15.1464 15.8536L10 10.707L4.85355 15.8536C4.67999 16.0271 4.41056 16.0464 4.21569 15.9114L4.14645 15.8536C3.97288 15.68 3.9536 15.4106 4.08859 15.2157L4.14645 15.1464L9.293 10L4.14645 4.85355C3.97288 4.67999 3.9536 4.41056 4.08859 4.21569L4.14645 4.14645L4.08859 4.21569Z" fill="#6656D1"/>
</g>
</svg>

После

Ширина:  |  Высота:  |  Размер: 815 B

Просмотреть файл

@ -414,9 +414,9 @@
"aks",
"kubernetes",
"aca",
"cognitivesearch",
"aisearch",
"openai",
"chatgpt",
"gpt",
"rediscache",
"ai",
"msft"
@ -433,7 +433,7 @@
"bicep",
"python",
"openai",
"chatgpt",
"gpt",
"ai",
"flask",
"aca",
@ -451,7 +451,7 @@
"bicep",
"java",
"openai",
"chatgpt",
"gpt",
"ai",
"blobstorage",
"azurespringapps",
@ -630,8 +630,8 @@
"source": "https://github.com/Azure-Samples/azure-search-openai-demo",
"tags": [
"openai",
"chatgpt",
"cognitivesearch",
"gpt",
"aisearch",
"python",
"typescript",
"bicep",
@ -745,7 +745,7 @@
"source": "https://github.com/Azure-Samples/function-csharp-ai-textsummarize",
"tags": [
"functions",
"cognitivesearch",
"aisearch",
"dotnetCsharp",
"azureai",
"ai",
@ -759,7 +759,7 @@
"website": "https://github.com/Azure-Samples",
"author": "Paul Yuknewicz",
"source": "https://github.com/Azure-Samples/function-python-ai-textsummarize",
"tags": ["functions", "cognitivesearch", "python", "azureai", "ai", "msft"]
"tags": ["functions", "aisearch", "python", "azureai", "ai", "msft"]
},
{
"title": "Flask Container with CDN",
@ -922,7 +922,7 @@
"tags": [
"bicep",
"openai",
"chatgpt",
"gpt",
"ai",
"apim",
"reactjs",
@ -1049,7 +1049,7 @@
"monitor",
"keyvault",
"appinsights",
"chatgpt",
"gpt",
"community"
]
},
@ -1108,7 +1108,7 @@
"openai",
"ai",
"appservice",
"cognitivesearch",
"aisearch",
"semantickernel",
"reactjs",
"bicep",
@ -1143,8 +1143,8 @@
"tags": [
"ai",
"bicep",
"chatgpt",
"cognitivesearch",
"gpt",
"aisearch",
"javascript",
"nodejs",
"openai",
@ -1233,7 +1233,7 @@
"website": "https://github.com/Azure-Samples",
"author": "Paul Yuknewicz",
"source": "https://github.com/Azure-Samples/function-javascript-ai-openai-chatgpt",
"tags": ["functions", "openai", "javascript", "ai", "chatgpt", "msft"]
"tags": ["functions", "openai", "javascript", "ai", "gpt", "msft"]
},
{
"title": "Azure Functions - Chat using ChatGPT (Python v2 Function)",
@ -1242,7 +1242,7 @@
"website": "https://github.com/Azure-Samples",
"author": "Paul Yuknewicz",
"source": "https://github.com/Azure-Samples/function-python-ai-openai-chatgpt",
"tags": ["functions", "openai", "python", "ai", "chatgpt", "msft"]
"tags": ["functions", "openai", "python", "ai", "gpt", "msft"]
},
{
"title": "Azure Functions - LangChain with Azure OpenAI and ChatGPT (Python v2 Function)",
@ -1262,8 +1262,8 @@
"source": "https://github.com/Azure/GPT-RAG",
"tags": [
"openai",
"chatgpt",
"cognitivesearch",
"gpt",
"aisearch",
"python",
"typescript",
"bicep",
@ -1590,9 +1590,9 @@
"python",
"typescript",
"flask",
"cognitivesearch",
"aisearch",
"openai",
"chatgpt",
"gpt",
"ai",
"msft",
"new"
@ -1625,7 +1625,7 @@
"source": "https://github.com/john0isaac/rag-semantic-kernel-mongodb-vcore",
"tags": [
"openai",
"chatgpt",
"gpt",
"cosmosdb",
"mongodb",
"python",
@ -1645,7 +1645,7 @@
"tags": [
"ai",
"bicep",
"chatgpt",
"gpt",
"serverlessapi",
"javascript",
"nodejs",