Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/components/GlossaryCard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from "react";
import ArrowUpRight from "../../static/img/ArrowUpRight.svg";

const GlossaryCard = ({name, description, link}) => {
return (
<a
href={link}
className="group flex h-full flex-col rounded-xl border border-transparent bg-[var(--ifm-card-background-color)] p-6 shadow-[0_4px_12px_var(--ifm-card-shadow-color)] transition-all duration-300 hover:border-[var(--ifm-color-primary)] hover:shadow-[0_8px_20px_var(--ifm-card-shadow-color)] focus:outline-none focus:ring-2 focus:ring-[var(--ifm-color-primary)] focus:ring-offset-2
"
>
<div className="mb-3 flex items-start justify-between">
<h3 className="pr-4 text-xl font-bold text-[var(--ifm-color-primary)]">
{name}
</h3>
<ArrowUpRight
className=" flex-shrink-0 text-[var(--ifm-color-emphasis-500)] transition-all duration-300 ease-in-out group-hover:rotate-45 group-hover:text-[var(--ifm-color-primary)]"
size={22}
/>
</div>
<p className="text-sm leading-relaxed text-[var(--ifm-color-emphasis-700)]">
{description}
</p>
</a>
);
};

export default GlossaryCard;
305 changes: 114 additions & 191 deletions src/pages/concepts/reference/glossary.js
Original file line number Diff line number Diff line change
@@ -1,208 +1,131 @@
import React, {useState} from "react";
import React, {useState, useMemo} from "react";
import Layout from "@theme/Layout";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";

import {glossaryEntries} from "../../../../static/data/glossaryEntries";
import GlossaryCard from "../../../components/GlossaryCard";

function Glossary() {
const [state, setState] = useState(() => {
const alphabet = "ABCEFGIMRSTUW";
const initialState = {};
for (let i = 0; i < alphabet.length; i++) {
initialState[alphabet[i]] = true;
}
return initialState;
});
const entries = {
A: [
{
name: "Acceptance Testing",
link: "/docs/concepts/reference/glossary/acceptance-testing",
},
{
name: "Agile Unit Testing",
link: "/docs/concepts/reference/glossary/agile-unit-testing",
},
{
name: "AI Test Completion",
link: "/docs/concepts/reference/glossary/ai-test-completion",
},
],
B: [
{
name: "BDD",
link: "/docs/concepts/reference/glossary/behaviour-driven-development",
},
{
name: "Beta Testing",
link: "/docs/concepts/reference/glossary/beta-testing",
},
{
name: "Black Box Testing",
link: "/docs/concepts/reference/glossary/black-box-testing",
},
],
C: [
{
name: "Code Coverage",
link: "/docs/concepts/reference/glossary/code-coverage",
},
{
name: "Cucumber Testing",
link: "/docs/concepts/reference/glossary/cucumber-testing",
},
],
E: [
{
name: "End To End Testing",
link: "/docs/concepts/reference/glossary/end-to-end-testing",
},
{
name: "Error Guessing",
link: "/docs/concepts/reference/glossary/error-guessing",
},
],
F: [
{
name: "Functional Testing",
link: "/docs/concepts/reference/glossary/functional-testing",
},
],
G: [
{
name: "Gray Box Testing",
link: "/docs/concepts/reference/glossary/gray-box-testing",
},
],
I: [
{
name: "Integration Testing",
link: "/docs/concepts/reference/glossary/integration-testing",
},
{
name: "Idempotency",
link: "/docs/concepts/reference/glossary/idempotency",
},
],
M: [
{
name: "Manual Testing",
link: "/docs/concepts/reference/glossary/manual-testing",
},
{
name: "Mocks",
link: "/docs/concepts/reference/glossary/mocks",
},
{
name: "Microservice Testing",
link: "/docs/concepts/reference/glossary/microservice-testing",
},
],
R: [
{
name: "Regression Testing",
link: "/docs/concepts/reference/glossary/regression-testing",
},
],
S: [
{
name: "Stubs",
ink: "/docs/concepts/reference/glossary/stubs",
},
{
name: "Software Testing Life Cycle",
link: "/docs/concepts/reference/glossary/software-testing-life-cycle",
},
],
T: [
{
name: "Test Driven TDD",
link: "/docs/concepts/reference/glossary/test-driven-development",
},
{
name: "Test Data Generation",
link: "/docs/concepts/reference/glossary/test-data-generation",
},
],
U: [
{
name: "Unit Test Automation",
link: "/docs/concepts/reference/glossary/unit-test-automation",
},
{
name: "Unit Testing",
link: "/docs/concepts/reference/glossary/unit-testing",
},
],
W: [
{
name: "White Box Testing",
link: "/docs/concepts/reference/glossary/white-box-testing",
},
],
const [selectedletter, setselectedletter] = useState([]);

const allLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
const availableLetters = Object.keys(glossaryEntries);

const handleLetterClick = (letter) => {
setselectedletter((prev) =>
prev.includes(letter)
? prev.filter((l) => l !== letter)
: [...prev, letter]
);
};
const {siteConfig, siteMetadata} = useDocusaurusContext;
const handleClick = (index) => {
setState((state) => {
var obj = {
...state,
[index]: !state[index],
};
return obj;
});

// Reset filter
const handleResetFilter = () => {
setselectedletter([]);
};

// Memoize the filtered entries to avoid re calculating on every render
const filteredEntrie = useMemo(() => {
if (selectedletter.length === 0) {
return Object.values(glossaryEntries).flat();
}
return selectedletter
.map((letter) => glossaryEntries[letter] || [])
.flat()
.sort((a, b) => a.name.localeCompare(b.name));
}, [selectedletter]);

return (
<Layout
title="About the docs"
title="Glossary"
permalink="/reference/glossary"
description="User General Information about Keploy's Documentation"
description="A glossary of terms related to software testing and development."
>
<main className="margin-vert--lg container flex flex-col justify-evenly">
<div className="pb-5 text-center text-4xl font-bold">Glossary</div>
<div className="flex flex-row justify-evenly">
{new Array(26).fill(0).map((x, i) => (
<main className="container mx-auto my-12 px-4 sm:px-6 lg:px-8">
<div className="mb-12 text-center">
<h1 className="text-4xl font-extrabold tracking-tight sm:text-5xl">
Glossary
</h1>
<p className="mt-4 text-lg text-[var(--ifm-color-emphasis-700)]">
Your guide to modern software testing and development terminology.
</p>
</div>

<div
className="mb-8 flex flex-wrap justify-center gap-2"
role="navigation"
aria-label="Alphabetical Glossary Navigation"
>
{allLetters.map((letter) => {
const isAvailable = availableLetters.includes(letter);
const isSelected = selectedletter.includes(letter);

return (
<button
key={letter}
onClick={() => handleLetterClick(letter)}
disabled={!isAvailable}
className={`flex h-10 w-10 items-center justify-center rounded-full text-lg font-bold transition-all duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-[var(--ifm-color-primary)] focus:ring-offset-2 sm:h-12 sm:w-12
${
isAvailable
? isSelected
? "scale-110 bg-[var(--ifm-color-primary)] text-white shadow-lg"
: "bg-[var(--ifm-card-background-color)] text-[var(--ifm-color-primary)] shadow-md hover:bg-[var(--ifm-color-primary-lightest)] hover:text-[var(--ifm-color-primary-darker)]"
: "cursor-not-allowed bg-transparent text-[var(--ifm-color-emphasis-300)]"
}
`}
aria-pressed={isSelected}
>
{letter}
</button>
);
})}
</div>

{selectedletter.length > 0 && (
<div className="mb-10 text-center">
<button
className={`col-span-1 gap-2 rounded-sm p-3
${
state[String.fromCharCode(65 + i)]
? "text-black-200 rounded-3xl bg-orange-200 font-bold shadow-md hover:text-orange-950 dark:text-orange-900"
: entries[String.fromCharCode(65 + i)] === undefined
? "bg-transparent text-gray-400" // Modified color class
: "bg-grey-200 rounded-3xl shadow-md"
} `}
key={i}
disabled={
entries[String.fromCharCode(65 + i)] === undefined
? true
: false
}
onClick={() => handleClick(String.fromCharCode(65 + i))}
onClick={handleResetFilter}
className="rounded-full border-2 border-[var(--ifm-color-primary)] bg-transparent px-6 py-2 font-semibold text-[var(--ifm-color-primary)] transition-colors hover:bg-[var(--ifm-color-primary)] hover:text-white"
>
{String.fromCharCode(65 + i)}
Reset Filter
</button>
))}
</div>
<div className="-mb-3 mt-10 flex flex-wrap justify-center gap-4 text-xl font-semibold">
{Object.entries(state).map(([key, value]) => {
return (
<div key={key} className="mb-4 w-1/4">
<div key={key}>{value ? key : ""}</div>
{value ? (
<div className="ml-4 flex flex-col justify-around text-xl">
{entries[key]?.map(({name, link}, i) => (
<a
className="text-orange-600 hover:text-orange-800 hover:underline"
key={i}
href={link}
>
{name}
</a>
</div>
)}

<div className="mt-12">
{selectedletter.length > 0 ? (
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
{filteredEntrie.map((entry, index) => (
<GlossaryCard key={`${entry.name}-${index}`} {...entry} />
))}
</div>
) : (
<div className="space-y-16">
{Object.entries(glossaryEntries).map(([letter, entries]) => (
<section key={letter} id={`letter-${letter}`}>
<h2 className="mb-6 border-b-2 border-[var(--ifm-color-emphasis-300)] pb-3 text-4xl font-bold text-[var(--ifm-color-primary)]">
{letter}
</h2>
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
{entries.map((entry, index) => (
<GlossaryCard key={`${entry.name}-${index}`} {...entry} />
))}
</div>
) : (
""
)}
</div>
);
})}
</section>
))}
</div>
)}

{filteredEntrie.length === 0 && selectedletter.length > 0 && (
<div className="py-16 text-center">
<p className="text-2xl font-semibold text-[var(--ifm-color-emphasis-800)]">
No terms found.
</p>
<p className="mt-2 text-[var(--ifm-color-emphasis-600)]">
Try selecting a different letter or resetting the filter.
</p>
</div>
)}
</div>
</main>
</Layout>
Expand Down
Loading