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
55 changes: 55 additions & 0 deletions frontend/src/components/modal/AddRepositoryModal.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { mount } from "cypress/react";
import { BrowserRouter } from "react-router";

import { AppContextProvider } from "../../context/AppContext";

import AddRepositoryModal from "./AddRepositoryModal";

function renderModal() {
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
},
});

mount(
<AppContextProvider>
<BrowserRouter>
<QueryClientProvider client={queryClient}>
<AddRepositoryModal isOpen={true} onClose={() => {}} />
</QueryClientProvider>
</BrowserRouter>
</AppContextProvider>
);
}

describe("AddRepositoryModal preset suggestions", () => {
beforeEach(() => {
if (!document.getElementById("portal")) {
const portal = document.createElement("div");
portal.id = "portal";
document.body.appendChild(portal);
}
});

it("renders popular repository suggestions and auto-fills fields when clicked", () => {
renderModal();

cy.get("[data-cy='preset-repo-jetstack']").should("exist");
cy.get("[data-cy='preset-repo-traefik']").should("exist");

cy.get("[data-cy='add-chart-name']").should("have.value", "");
cy.get("[data-cy='add-chart-url']").should("have.value", "");

cy.get("[data-cy='preset-repo-jetstack']").click();

cy.get("[data-cy='add-chart-name']").should("have.value", "jetstack");
cy.get("[data-cy='add-chart-url']").should(
"have.value",
"https://charts.jetstack.io"
);
});
});
32 changes: 32 additions & 0 deletions frontend/src/components/modal/AddRepositoryModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { useState } from "react";

import apiService from "../../API/apiService";
import { useAppContext } from "../../context/AppContext";
import {
POPULAR_REPOSITORIES,
type SuggestedRepository,
} from "../../data/popularRepositories";
import useAlertError from "../../hooks/useAlertError";
import useCustomSearchParams from "../../hooks/useCustomSearchParams";
import useNavigateWithSearchParams from "../../hooks/useNavigateWithSearchParams";
Expand Down Expand Up @@ -32,12 +36,21 @@ function AddRepositoryModal({ isOpen, onClose }: AddRepositoryModalProps) {
username: "",
password: "",
});

const [isLoading, setIsLoading] = useState(false);
const alertError = useAlertError();
const { setSelectedRepo } = useAppContext();
const navigate = useNavigateWithSearchParams();
const queryClient = useQueryClient();

const handleSelectPreset = (repo: SuggestedRepository) => {
setFormData((prev) => ({
...prev,
name: repo.name,
url: repo.url,
}));
};

const addRepository = async () => {
const body = new FormData();
body.append("name", formData.name ?? "");
Expand Down Expand Up @@ -105,6 +118,25 @@ function AddRepositoryModal({ isOpen, onClose }: AddRepositoryModalProps) {
</div>
}
>
<div className="mb-5">
<div className="mb-2 text-xs font-semibold tracking-wider text-gray-500 uppercase">
Popular Repositories (click to auto-fill)
</div>
<div className="flex flex-wrap gap-2">
{POPULAR_REPOSITORIES.map((repo) => (
<button
key={repo.name}
type="button"
data-cy={`preset-repo-${repo.name}`}
onClick={() => handleSelectPreset(repo)}
className="inline-flex cursor-pointer items-center rounded-full border border-gray-200 bg-gray-50 px-3 py-1 text-xs font-medium text-gray-700 transition-colors hover:border-sky-500 hover:bg-sky-50 hover:text-sky-700"
title={`${repo.name}: ${repo.description}`}
>
+ {repo.name}
</button>
))}
</div>
</div>
<div className="flex gap-x-3">
<label className="flex-1" htmlFor="name">
<div className="require mb-2 text-sm">Name</div>
Expand Down
43 changes: 43 additions & 0 deletions frontend/src/data/popularRepositories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { Repository } from "./types";

export interface SuggestedRepository extends Repository {
description: string;
}

export const POPULAR_REPOSITORIES: SuggestedRepository[] = [
{
name: "jetstack",
url: "https://charts.jetstack.io",
description: "cert-manager and PKI management tools",
},
{
name: "prometheus-community",
url: "https://prometheus-community.github.io/helm-charts",
description: "Prometheus, Alertmanager, and monitoring stack",
},
{
name: "traefik",
url: "https://traefik.github.io/charts",
description: "Traefik Ingress controller and reverse proxy",
},
{
name: "grafana",
url: "https://grafana.github.io/helm-charts",
description: "Grafana, Loki, Tempo, and observability tooling",
},
{
name: "cilium",
url: "https://helm.cilium.io/",
description: "eBPF-based networking, security, and observability",
},
{
name: "argo",
url: "https://argoproj.github.io/argo-helm",
description: "Argo Workflows, Argo CD, Argo Events, and Rollouts",
},
{
name: "komodorio",
url: "https://helm-charts.komodor.io",
description: "Komodor platform agent and tools",
},
];
Loading