Rename frontend directory (#472)

* Rename directory

* Cleanup

* Recover lost images

* remove lint
This commit is contained in:
Andrey Pokhilko
2023-09-26 10:04:44 +01:00
committed by GitHub
parent 133eef6745
commit dd7aca70ff
146 changed files with 595 additions and 309 deletions

View File

@@ -0,0 +1,9 @@
import SwaggerUI from "swagger-ui-react";
import "swagger-ui-react/swagger-ui.css";
import openapi from "../../public/openapi.json";
const DocsPage = () => {
return <SwaggerUI spec={openapi} />;
};
export default DocsPage;

View File

@@ -0,0 +1,101 @@
import InstalledPackagesHeader from "../components/InstalledPackages/InstalledPackagesHeader";
import InstalledPackagesList from "../components/InstalledPackages/InstalledPackagesList";
import ClustersList from "../components/ClustersList";
import { useGetInstalledReleases } from "../API/releases";
import { useMemo, useState } from "react";
import Spinner from "../components/Spinner";
import useAlertError from "../hooks/useAlertError";
import { useParams, useNavigate } from "react-router-dom";
import useCustomSearchParams from "../hooks/useCustomSearchParams";
import { Release } from "../data/types";
function Installed() {
const { searchParamsObject } = useCustomSearchParams();
const { context } = useParams();
const { filteredNamespace } = searchParamsObject;
const selectedNamespaces = useMemo(
() => filteredNamespace?.split("+"),
[filteredNamespace]
);
const navigate = useNavigate();
const handleClusterChange = (clusterName: string) => {
navigate({
pathname: `/${clusterName}/installed`,
});
};
const [filterKey, setFilterKey] = useState<string>("");
const alertError = useAlertError();
const { data, isLoading, isRefetching } = useGetInstalledReleases(
context ?? "",
{
retry: false,
onError: (e) => {
alertError.setShowErrorModal({
title: "Failed to get list of charts",
msg: (e as Error).message,
});
},
}
);
const filteredReleases = useMemo(() => {
return (
data?.filter((installedPackage: Release) => {
if (filterKey) {
const {
namespace: releaseNamespace,
name: releaseName,
chartName,
} = installedPackage;
const shownByNS =
!selectedNamespaces ||
!selectedNamespaces.length ||
selectedNamespaces.includes(releaseNamespace);
const shownByStr =
releaseName.includes(filterKey) || chartName.includes(filterKey);
if (shownByNS && shownByStr) {
return true;
} else {
return false;
}
} else {
return selectedNamespaces
? selectedNamespaces.includes(installedPackage.namespace)
: true;
}
}) ?? []
);
}, [data, filterKey, selectedNamespaces]);
return (
<div className="flex flex-row w-full">
<ClustersList
selectedCluster={context ?? ""}
filteredNamespaces={selectedNamespaces}
onClusterChange={handleClusterChange}
installedReleases={data}
/>
<div className="p-5 w-[calc(100%-17rem)]">
<InstalledPackagesHeader
isLoading={isLoading || isRefetching}
filteredReleases={filteredReleases}
setFilterKey={setFilterKey}
/>
{isLoading || isRefetching ? (
<div className="py-2">
<Spinner />
</div>
) : (
<InstalledPackagesList filteredReleases={filteredReleases} />
)}
</div>
</div>
);
}
export default Installed;

View File

@@ -0,0 +1,14 @@
function NotFound() {
return (
<div
style={{
display: "flex",
flex: 1,
}}
>
404 page not found
</div>
);
}
export default NotFound;

View File

@@ -0,0 +1,67 @@
import { useMemo, useEffect } from "react";
import RepositoriesList from "../components/repository/RepositoriesList";
import RepositoryViewer from "../components/repository/RepositoryViewer";
import { Repository } from "../data/types";
import { useGetRepositories } from "../API/repositories";
import { HelmRepositories } from "../API/interfaces";
import { useParams } from "react-router-dom";
import { useAppContext } from "../context/AppContext";
import useNavigateWithSearchParams from "../hooks/useNavigateWithSearchParams";
function RepositoryPage() {
const { selectedRepo: repoFromParams, context } = useParams();
const navigate = useNavigateWithSearchParams();
const { setSelectedRepo, selectedRepo } = useAppContext();
const handleRepositoryChanged = (selectedRepository: Repository) => {
navigate(`/${context}/repository/${selectedRepository.name}`, {
replace: true,
});
};
useEffect(() => {
if (repoFromParams) {
setSelectedRepo(repoFromParams);
}
}, [setSelectedRepo, repoFromParams]);
useEffect(() => {
if (selectedRepo && !repoFromParams) {
navigate(`/${context}/repository/${selectedRepo}`, {
replace: true,
});
}
}, [selectedRepo, repoFromParams, context, navigate]);
const { data: repositories = [] } = useGetRepositories({
onSuccess: (data: HelmRepositories) => {
const sortedData = data?.sort((a, b) => a.name.localeCompare(b.name));
if (sortedData && sortedData.length > 0 && !repoFromParams) {
handleRepositoryChanged(sortedData[0]);
}
},
});
const selectedRepository = useMemo(() => {
if (repoFromParams) {
return repositories?.find((repo) => repo.name === repoFromParams);
}
}, [repositories, repoFromParams]);
return (
<div className="flex flex-row p-5 gap-4">
<RepositoriesList
repositories={repositories}
onRepositoryChanged={handleRepositoryChanged}
selectedRepository={selectedRepository}
/>
<div className="w-[calc(100%-21rem)]">
<RepositoryViewer repository={selectedRepository} />
</div>
</div>
);
}
export default RepositoryPage;

View File

@@ -0,0 +1,101 @@
import { useMemo } from "react";
import { useParams } from "react-router-dom";
import RevisionDetails from "../components/revision/RevisionDetails";
import RevisionsList from "../components/revision/RevisionsList";
import { ReleaseRevision } from "../data/types";
import { useQuery } from "@tanstack/react-query";
import apiService from "../API/apiService";
import Spinner from "../components/Spinner";
const descendingSort = (r1: ReleaseRevision, r2: ReleaseRevision) =>
r1.revision - r2.revision < 0 ? 1 : -1;
function Revision() {
const { revision = "", ...restParams } = useParams();
const selectedRevision = revision ? parseInt(revision, 10) : 0;
const { data: releaseRevisions, isLoading: isLoadingHistory } = useQuery<
ReleaseRevision[]
>({
//eslint-ignore
//@ts-ignore
queryKey: ["releasesHistory", restParams],
queryFn: apiService.getReleasesHistory,
});
const latestRevision = useMemo(
() =>
Array.isArray(releaseRevisions) &&
releaseRevisions.reduce((max, revisionData) => {
return Math.max(max, revisionData.revision);
}, Number.MIN_SAFE_INTEGER),
[releaseRevisions]
);
const sortedReleases = useMemo(
() => (releaseRevisions as ReleaseRevision[])?.sort(descendingSort),
[releaseRevisions]
);
const selectedRelease = useMemo(() => {
if (selectedRevision && releaseRevisions) {
return (releaseRevisions as ReleaseRevision[]).find(
(r: ReleaseRevision) => r.revision === selectedRevision
);
}
return null;
}, [releaseRevisions, selectedRevision]);
return (
<div className="flex">
<div className="flex flex-col gap-2 w-1/6 min-h-screen bg-[#E8EDF2] pb-4">
<label className="mt-5 mx-5 text-sm text-dark font-semibold">
Revisions
</label>
{isLoadingHistory ? (
<RevisionSidebarSkeleton />
) : (
<RevisionsList
releaseRevisions={sortedReleases}
selectedRevision={selectedRevision}
/>
)}
</div>
<div className="w-5/6 min-h-screen bg-body-background pb-4">
{isLoadingHistory ? (
<div className=" p-4">
<Spinner />
</div>
) : selectedRelease ? (
<RevisionDetails
//@ts-ignore
release={selectedRelease}
installedRevision={
//@ts-ignore
releaseRevisions?.[0] as ReleaseRevision
}
isLatest={selectedRelease.revision === latestRevision}
latestRevision={latestRevision.revision}
/>
) : null}
</div>
</div>
);
}
const RevisionSidebarSkeleton = () => {
return (
<>
<div className="border rounded-md mx-5 p-2 gap-4 animate-pulse h-[74px] w-[88%] bg-gray-100" />
<div className="border rounded-md mx-5 p-2 gap-4 animate-pulse h-[74px] w-[88%] bg-gray-100" />
<div className="border rounded-md mx-5 p-2 gap-4 animate-pulse h-[74px] w-[88%] bg-gray-100" />
<div className="border rounded-md mx-5 p-2 gap-4 animate-pulse h-[74px] w-[88%] bg-gray-100" />
<div className="border rounded-md mx-5 p-2 gap-4 animate-pulse h-[74px] w-[88%] bg-gray-100" />
<div className="border rounded-md mx-5 p-2 gap-4 animate-pulse h-[74px] w-[88%] bg-gray-100" />
</>
);
};
export default Revision;