Skip to content

Commit

Permalink
fix: emui enable exact package name searching (#2052)
Browse files Browse the repository at this point in the history
## Description:
This PR implements exact package name searching in the EMUI. This allows
indexing errors to be surfaced in the UI, for example:


[exact-match.webm](https://github.com/kurtosis-tech/kurtosis/assets/4419574/8cf29524-59de-44fc-834b-c07852406a12)

This PR also fixes #2051 by treating arguments with no argtype (as is
the case for the `args` argument) as a `JSON` argument. This behaviour
for Form->kurtosis format is now consistent with the existing kurtosis
format->Form transformer.

## Is this change user facing?
YES

## References (if applicable):
- Fixes #2051
  • Loading branch information
Dartoxian committed Jan 16, 2024
1 parent a61d37b commit 69c57ec
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 7 deletions.
2 changes: 1 addition & 1 deletion enclave-manager/web/cypress/e2e/enclaveList.cy.ts
Expand Up @@ -26,7 +26,7 @@ describe("Enclave List", () => {
cy.contains("Script completed", { timeout: 10 * 1000 });
});

it.only("Shows a new enclave in the list", () => {
it("Shows a new enclave in the list", () => {
cy.goToEnclaveList();
cy.contains("tr", enclaveName).should("not.exist");

Expand Down
9 changes: 9 additions & 0 deletions enclave-manager/web/cypress/e2e/enclaves/packageSearch.cy.ts
@@ -0,0 +1,9 @@
describe("New Enclave package search", () => {
it("Can find an enclave by exact name", () => {
cy.goToEnclaveList();
cy.contains("New Enclave").click();
cy.contains("Package Template Repo").should("not.exist");
cy.focused().type("github.com/kurtosis-tech/package-template-repo");
cy.contains("Package Template Repo");
});
});
@@ -1,5 +1,6 @@
import { Flex, Heading, Spinner } from "@chakra-ui/react";
import { GetPackagesResponse, KurtosisPackage } from "kurtosis-cloud-indexer-sdk";
import { ReadPackageResponse } from "kurtosis-cloud-indexer-sdk/build/kurtosis_package_indexer_pb";
import { isDefined, SavedPackagesProvider } from "kurtosis-ui-components";
import { createContext, PropsWithChildren, useCallback, useContext, useEffect, useState } from "react";
import { Result } from "true-myth";
Expand All @@ -8,6 +9,7 @@ import { loadSavedPackageNames, storeSavedPackages } from "./storage";

export type CatalogState = {
catalog: Result<GetPackagesResponse, string>;
getSinglePackage: (packageName: string) => Promise<Result<ReadPackageResponse, string>>;
refreshCatalog: () => Promise<Result<GetPackagesResponse, string>>;
};

Expand Down Expand Up @@ -42,6 +44,13 @@ export const CatalogContextProvider = ({ children }: PropsWithChildren) => {
});
}, []);

const getSinglePackage = useCallback(
async (packageName: string) => {
return await packageIndexerClient.readPackage(packageName);
},
[packageIndexerClient],
);

useEffect(() => {
refreshCatalog();
}, [refreshCatalog]);
Expand All @@ -58,7 +67,7 @@ export const CatalogContextProvider = ({ children }: PropsWithChildren) => {
}

return (
<CatalogContext.Provider value={{ catalog, refreshCatalog }}>
<CatalogContext.Provider value={{ catalog, refreshCatalog, getSinglePackage }}>
<SavedPackagesProvider savedPackages={savedPackages} togglePackageSaved={togglePackageSaved}>
{children}
</SavedPackagesProvider>
Expand Down
Expand Up @@ -10,16 +10,30 @@ import {
InputGroup,
InputLeftElement,
InputRightElement,
Spinner,
Text,
} from "@chakra-ui/react";
import { KurtosisPackage } from "kurtosis-cloud-indexer-sdk";
import { FindCommand, KurtosisAlert, KurtosisPackageCardHorizontal, useSavedPackages } from "kurtosis-ui-components";
import { ChangeEvent, useMemo, useRef, useState } from "react";
import {
FindCommand,
isDefined,
KurtosisAlert,
KurtosisPackageCardHorizontal,
parsePackageUrl,
useSavedPackages,
} from "kurtosis-ui-components";
import { debounce } from "lodash";
import { ChangeEvent, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { FiSearch } from "react-icons/fi";
import { useCatalogContext } from "../../../../../catalog/CatalogContext";
import { DrawerExpandCollapseButton } from "../DrawerExpandCollapseButton";
import { DrawerSizes } from "../types";

type ExactMatchState =
| { type: "loading"; url: string }
| { type: "loaded"; package: KurtosisPackage }
| { type: "error"; error: string };

type PackageSelectBodyProps = {
onPackageSelected: (kurtosisPackage: KurtosisPackage) => void;
onClose: () => void;
Expand All @@ -35,7 +49,46 @@ export const PackageSelectBody = ({
const searchRef = useRef<HTMLInputElement>(null);
const [searchTerm, setSearchTerm] = useState("");

const { catalog } = useCatalogContext();
const [exactMatch, setExactMatch] = useState<ExactMatchState>();
const { catalog, getSinglePackage } = useCatalogContext();

const checkSinglePackageDebounced = useMemo(
() =>
debounce(
async (packageName: string) => {
const singlePackageResult = await getSinglePackage(packageName);
if (singlePackageResult.isErr) {
setExactMatch({ type: "error", error: singlePackageResult.error });
return;
}
if (isDefined(singlePackageResult.value.package)) {
setExactMatch({ type: "loaded", package: singlePackageResult.value.package });
}
},
1000,
{ trailing: true, leading: false },
),
[getSinglePackage],
);

const startCheckSinglePackage = useCallback(
async (packageName: string) => {
let isKurtosisPackageName = false;
try {
parsePackageUrl(packageName);
isKurtosisPackageName = true;
} catch (error: any) {
// This packageName isn't a kurtosis package url
}
if (isKurtosisPackageName) {
setExactMatch({ type: "loading", url: packageName });
checkSinglePackageDebounced(packageName);
} else {
setExactMatch(undefined);
}
},
[checkSinglePackageDebounced],
);

const searchResults = useMemo(
() =>
Expand All @@ -53,6 +106,10 @@ export const PackageSelectBody = ({
setSearchTerm(e.target.value);
};

useEffect(() => {
startCheckSinglePackage(searchTerm);
}, [startCheckSinglePackage, searchTerm]);

if (searchResults.isErr) {
return (
<DrawerBody>
Expand Down Expand Up @@ -92,6 +149,28 @@ export const PackageSelectBody = ({
)}
</InputRightElement>
</InputGroup>
{isDefined(exactMatch) && (
<Flex flexDirection={"column"} gap={"10px"}>
<Text fontWeight={"semibold"} pt={"16px"} pb={"6px"}>
Exact Match
</Text>
{exactMatch.type === "loading" && (
<Flex flexDirection={"column"} alignItems={"center"}>
<Spinner />
<Text>Looking for a Kurtosis Package at {exactMatch.url}</Text>
</Flex>
)}
{exactMatch.type === "loaded" && (
<KurtosisPackageCardHorizontal
kurtosisPackage={exactMatch.package}
onClick={() => onPackageSelected(exactMatch.package)}
/>
)}
{exactMatch.type === "error" && (
<KurtosisAlert message={"Error looking up package"} details={exactMatch.error} />
)}
</Flex>
)}
{(searchTerm.length > 0 || savedPackages.length === 0) && (
<Flex flexDirection={"column"} gap={"10px"}>
<Text fontWeight={"semibold"} pt={"16px"} pb={"6px"}>
Expand Down
Expand Up @@ -63,9 +63,12 @@ export function transformFormArgsToKurtosisArgs(data: Record<string, any>, kurto
case ArgumentValueType.STRING:
return value;
case ArgumentValueType.JSON:
return YAML.parse(value);
default:
return value;
try {
return YAML.parse(value);
} catch (error: any) {
return value;
}
}
};

Expand Down

0 comments on commit 69c57ec

Please sign in to comment.