Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Added Pagination & Updated sidebar with counts #271

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
301bea9
feat: updated nextjs docs to include app router
jagadeeshgade008 Feb 28, 2024
e69af9b
Refactor app router usage in nextjs.md
jagadeeshgade008 Feb 29, 2024
c29f71d
Paggination
jagadeeshgade008 Mar 1, 2024
a08943f
Remove Pagination component and update
jagadeeshgade008 Mar 4, 2024
ff7e3f9
Add pagination functionality to ListAttributes,
jagadeeshgade008 Mar 4, 2024
f0af817
Fix styling issues in Alert, App, Header, and
jagadeeshgade008 Mar 4, 2024
3b802b2
Fix header styling and remove commented code
jagadeeshgade008 Mar 4, 2024
ce87ffb
Refactor load more button in ListAttributes,
jagadeeshgade008 Mar 5, 2024
954c235
Merge branch 'featurevisor:main' into pagination
jagadeeshgade008 Mar 6, 2024
5d14aba
fix: formats fixed
jagadeeshgade008 Mar 6, 2024
6735eb1
Add end flag to navigation links
jagadeeshgade008 Mar 7, 2024
2a68d54
Merge branch 'main' into pagination
jagadeeshgade008 Mar 18, 2024
25e263d
Merge branch 'main' into pagination
jagadeeshgade008 Apr 16, 2024
c8aeeb8
Merge branch 'main' into pagination
jagadeeshgade008 Apr 17, 2024
baa1c4a
Add revision to search index and display revision
jagadeeshgade008 Apr 22, 2024
726a29e
Remove console.log statements
jagadeeshgade008 Apr 22, 2024
8a0c0a6
Fix header entity count display
jagadeeshgade008 Apr 22, 2024
72631e3
Fix revision display in Header component
jagadeeshgade008 Apr 23, 2024
d8dc366
Fix indentation in Header component
jagadeeshgade008 Apr 23, 2024
17fa02b
Merge branch 'main' into pagination
jagadeeshgade008 Apr 24, 2024
a17e39a
Merge branch 'main' into pagination
jagadeeshgade008 Apr 29, 2024
f447ccb
Merge branch 'main' into pagination
jagadeeshgade008 May 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions packages/core/src/site/generateSiteSearchIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export async function generateSiteSearchIndex(
const { rootDirectoryPath, projectConfig, datasource } = deps;

const result: SearchIndex = {
revision: "",
links: undefined,
entities: {
attributes: [],
Expand All @@ -30,6 +31,14 @@ export async function generateSiteSearchIndex(
},
};

/**
* Revision
*/
const revision = await datasource.readRevision();
if (revision) {
result.revision = revision.trim();
}

/**
* Links
*/
Expand Down
1 change: 1 addition & 0 deletions packages/site/mock/search-index.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"revision": "v0.1.0",
"links": {
"attribute": "https://github.com/featurevisor/featurevisor/blob/main/examples/example-1/attributes/{{key}}.yml",
"segment": "https://github.com/featurevisor/featurevisor/blob/main/examples/example-1/segments/{{key}}.yml",
Expand Down
4 changes: 2 additions & 2 deletions packages/site/src/components/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ interface AlertProps {
export function Alert(props: AlertProps) {
if (props.type === "success") {
return (
<p className="mx-6 block rounded border-2 border-green-300 bg-green-200 p-3 text-sm text-gray-600">
<p className="my-6 mx-6 block rounded border-2 border-green-300 bg-green-200 p-3 text-sm text-gray-600">
{props.children}
</p>
);
}

return (
<p className="mx-6 block rounded border-2 border-orange-300 bg-orange-200 p-3 text-sm text-gray-600">
<p className="my-6 mx-6 block rounded border-2 border-orange-300 bg-orange-200 p-3 text-sm text-gray-600">
{props.children}
</p>
);
Expand Down
112 changes: 66 additions & 46 deletions packages/site/src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,27 @@ import { SearchIndex } from "@featurevisor/types";

export function App() {
const [fetchedSearchIndex, setSearchIndex] = React.useState(undefined);
const [revision, setRevision] = React.useState("");
const [entitiesCount, setEntitiesCount] = React.useState({
features: 0,
segments: 0,
attributes: 0,
});

React.useEffect(() => {
fetch("/search-index.json")
.then((response) => response.json())
.then((data) => {
setRevision(data.revision);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


setEntitiesCount({
features: data.entities.features.length,
segments: data.entities.segments.length,
attributes: data.entities.attributes.length,
});
// below line is for pagination testing
// data.entities.segments = [...data.entities.segments,...data.entities.segments]
// data.entities.attributes = [...data.entities.attributes,...data.entities.attributes]
setSearchIndex(data);
});
}, []);
Expand All @@ -54,62 +70,66 @@ export function App() {
: [];

return (
<div>
<Header />

<main>
{!fetchedSearchIndex && <Alert type="warning">Loading...</Alert>}

{fetchedSearchIndex && (
<SearchIndexContext.Provider value={{ isLoaded: true, data: fetchedSearchIndex }}>
<Routes>
<Route path="features">
<Route index element={<ListFeatures />} />

<Route path=":featureKey" element={<ShowFeature />}>
<Route index element={<DisplayFeatureOverview />} />
<Route path="variations" element={<DisplayFeatureVariations />} />
<Route path="variables" element={<DisplayFeatureVariablesSchema />} />
<Route path="rules" element={<DisplayFeatureRules />}>
<Route path=":environmentKey" element={<DisplayFeatureRulesTable />} />
<Route index element={<Navigate to={environmentKeys[0]} replace />} />
<div className="grid lg:grid-cols-12">
<div className="lg:col-span-2">
<Header entitiesCount={entitiesCount} revision={revision} />
</div>

<div className="lg:col-span-10">
<main>
{!fetchedSearchIndex && <Alert type="warning">Loading...</Alert>}

{fetchedSearchIndex && (
<SearchIndexContext.Provider value={{ isLoaded: true, data: fetchedSearchIndex }}>
<Routes>
<Route path="features">
<Route index element={<ListFeatures />} />

<Route path=":featureKey" element={<ShowFeature />}>
<Route index element={<DisplayFeatureOverview />} />
<Route path="variations" element={<DisplayFeatureVariations />} />
<Route path="variables" element={<DisplayFeatureVariablesSchema />} />
<Route path="rules" element={<DisplayFeatureRules />}>
<Route path=":environmentKey" element={<DisplayFeatureRulesTable />} />
<Route index element={<Navigate to={environmentKeys[0]} replace />} />
</Route>
<Route path="force" element={<DisplayFeatureForce />}>
<Route path=":environmentKey" element={<DisplayFeatureForceTable />} />
<Route index element={<Navigate to={environmentKeys[0]} replace />} />
</Route>
<Route path="history" element={<DisplayFeatureHistory />} />
</Route>
<Route path="force" element={<DisplayFeatureForce />}>
<Route path=":environmentKey" element={<DisplayFeatureForceTable />} />
<Route index element={<Navigate to={environmentKeys[0]} replace />} />
</Route>
<Route path="history" element={<DisplayFeatureHistory />} />
</Route>
</Route>

<Route path="segments">
<Route index element={<ListSegments />} />
<Route path="segments">
<Route index element={<ListSegments />} />

<Route path=":segmentKey" element={<ShowSegment />}>
<Route index element={<DisplaySegmentOverview />} />
<Route path="usage" element={<DisplaySegmentUsage />} />
<Route path="history" element={<DisplaySegmentHistory />} />
<Route path=":segmentKey" element={<ShowSegment />}>
<Route index element={<DisplaySegmentOverview />} />
<Route path="usage" element={<DisplaySegmentUsage />} />
<Route path="history" element={<DisplaySegmentHistory />} />
</Route>
</Route>
</Route>

<Route path="attributes">
<Route index element={<ListAttributes />} />
<Route path="attributes">
<Route index element={<ListAttributes />} />

<Route path=":attributeKey" element={<ShowAttribute />}>
<Route index element={<DisplayAttributeOverview />} />
<Route path="usage" element={<DisplayAttributeUsage />} />
<Route path="history" element={<DisplayAttributeHistory />} />
<Route path=":attributeKey" element={<ShowAttribute />}>
<Route index element={<DisplayAttributeOverview />} />
<Route path="usage" element={<DisplayAttributeUsage />} />
<Route path="history" element={<DisplayAttributeHistory />} />
</Route>
</Route>
</Route>

<Route path="history" element={<ListHistory />} />
<Route index element={<Navigate to="features" replace />} />
</Routes>
</SearchIndexContext.Provider>
)}
</main>
<Route path="history" element={<ListHistory />} />
<Route index element={<Navigate to="features" replace />} />
</Routes>
</SearchIndexContext.Provider>
)}

<Footer />
<Footer />
</main>
</div>
</div>
);
}
173 changes: 138 additions & 35 deletions packages/site/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import * as React from "react";
import { Link, NavLink } from "react-router-dom";

export function Header() {
export function Header(props) {
const { entitiesCount, revision } = props;
const [isOpen, setIsOpen] = React.useState(false);

const navItems = [
{
title: "Features",
Expand All @@ -23,40 +26,140 @@ export function Header() {
];

return (
<div className="bg-gray-800">
<nav className="mx-auto flex max-w-4xl items-center justify-between px-8 pb-4 pt-3">
<Link to="/" className="text-gray-50">
<img
alt="Featurevisor"
src="/favicon-128.png"
className="absolute top-4 -ml-2 w-[36px]"
/>
</Link>

<div className="relative flex gap-x-4">
{navItems.map((item) => (
<NavLink
key={item.title}
to={item.to}
className={({ isActive }) => {
return [
"relative",
"rounded-lg",
isActive ? "bg-gray-700" : "",
"px-3",
"py-2",
"text-sm",
"font-semibold",
"leading-6",
"text-gray-50",
].join(" ");
}}
<>
<div className="bg-gray-800 lg:h-screen fixed w-[18%] overflow-auto lg:block hidden">
<nav className="mx-auto flex flex-col items-start justify-start px-8 pt-3 h-100">
<Link to="/" className="text-gray-50 mb-8 flex align-middle justify-center w-full">
<img alt="Featurevisor" src="/favicon-128.png" className="w-[63px]" />
</Link>

<div className="relative flex flex-col gap-y-4 w-full">
{navItems.map((item) => (
<NavLink
key={item.title}
to={item.to}
className={({ isActive }) => {
return [
"relative",
"rounded-lg",
isActive ? "bg-gray-700" : "",
"px-3",
"py-2",
"text-sm",
"font-semibold",
"leading-6",
"text-gray-50",
"flex",
"justify-between",
"items-center",
"w-full",
"hover:bg-gray-600",
].join(" ");
}}
>
{item.title}
{item.title != "History" && (
<span className="inline-flex items-center justify-center w-3 h-3 p-3 ms-3 text-sm font-medium text-blue-800 bg-blue-100 rounded-full dark:bg-blue-900 dark:text-blue-300">
{entitiesCount[item.title.toLowerCase()] || 0}
</span>
)}
</NavLink>
))}
</div>

<div className="fixed flex flex-col gap-y-4 w-full px-3 text-gray-50 bottom-0">
Revision: {revision}
</div>
</nav>
</div>

<div className="lg:hidden block bg-gray-800 w-full h-[60px] ">
<nav className="mx-auto flex items-center justify-between px-8 h-full">
<Link to="/" className="text-gray-50">
<img alt="Featurevisor" src="/favicon-128.png" className="w-[36px]" />
</Link>

<button className="text-gray-50" onClick={() => setIsOpen(!isOpen)}>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth="1.5"
stroke="currentColor"
className="w-6 h-6"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M3.75 5.25h16.5m-16.5 4.5h16.5m-16.5 4.5h16.5m-16.5 4.5h16.5"
/>
</svg>
</button>

<main
className={
" fixed overflow-hidden z-10 bg-gray-900 bg-opacity-25 inset-0 transform ease-in-out " +
(isOpen
? " transition-opacity opacity-100 duration-500 translate-x-0 "
: " transition-all delay-500 opacity-0 translate-x-full ")
}
>
<section
className={
" w-screen max-w-lg right-0 absolute bg-gray-800 h-full shadow-xl delay-400 duration-500 ease-in-out transition-all transform " +
(isOpen ? " translate-x-0 " : " translate-x-full ")
}
>
{item.title}
</NavLink>
))}
</div>
</nav>
</div>
<article className="relative w-screen max-w-lg pb-10 flex flex-col space-y-6 overflow-y-scroll h-full px-3">
{/* <header className="p-4 font-bold text-lg">Header</header> */}
<div className="relative flex flex-col gap-y-4 w-full pt-9">
{navItems.map((item) => (
<NavLink
key={item.title}
to={item.to}
className={({ isActive }) => {
return [
"relative",
"rounded-lg",
isActive ? "bg-gray-700" : "",
"px-3",
"py-2",
"text-sm",
"font-semibold",
"leading-6",
"text-gray-50",
"flex",
"justify-between",
"items-center",
"w-full",
"hover:bg-gray-600",
].join(" ");
}}
>
{item.title}
{item.title != "History" && (
<span className="inline-flex items-center justify-center w-3 h-3 p-3 ms-3 text-sm font-medium text-blue-800 bg-blue-100 rounded-full dark:bg-blue-900 dark:text-blue-300">
{entitiesCount[item.title.toLowerCase()] || 0}
</span>
)}
</NavLink>
))}
</div>

<div className="fixed flex flex-col gap-y-4 w-full px-3 text-gray-50 bottom-0">
Revision: {revision}
</div>
</article>
</section>
<section
className=" w-screen h-full cursor-pointer "
onClick={() => {
setIsOpen(false);
}}
></section>
</main>
</nav>
</div>
</>
);
}