Skip to content

Commit

Permalink
fix: small Emui QoL improvements (#1944)
Browse files Browse the repository at this point in the history
## Description:
This PR makes some small quality of life improvements identified whilst
debugging the polka issue:
* Strip `https://` from the start of github package urls
* Handle bad arg types more gracefully (screenshot below)
* Use unique keys in the DataTable component to stop react complaining.

![Screenshot from 2023-12-13
16-46-27](https://github.com/kurtosis-tech/kurtosis/assets/4419574/375328a5-49a9-4b6e-ae01-314e002d8ecc)

## Is this change user facing?
YES

## References (if applicable):
*
https://sageroomworkspace.slack.com/archives/C060Z6HDYR3/p1702477312080589
  • Loading branch information
Dartoxian committed Dec 14, 2023
1 parent cc44ade commit 21b5ffd
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 85 deletions.
1 change: 1 addition & 0 deletions enclave-manager/web/package.json
Expand Up @@ -21,6 +21,7 @@
"luxon": "^3.4.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-error-boundary": "^4.0.11",
"react-hook-form": "^7.47.0",
"react-icons": "^4.11.0",
"react-markdown": "^9.0.0",
Expand Down
Expand Up @@ -22,7 +22,7 @@ export class KurtosisPackageIndexerClient {
};

parsePackageUrl(packageUrl: string) {
const components = packageUrl.split("/");
const components = packageUrl.replace(/https?:\/\//, "").split("/");
if (components.length < 3) {
throw Error(`Illegal url, invalid number of components: ${packageUrl}`);
}
Expand Down
7 changes: 6 additions & 1 deletion enclave-manager/web/src/components/KurtosisAlert.tsx
Expand Up @@ -12,7 +12,8 @@ import {
Box,
Flex,
} from "@chakra-ui/react";
import { isDefined } from "../utils";
import { FallbackProps } from "react-error-boundary";
import { isDefined, stringifyError } from "../utils";

type KurtosisAlertProps = AlertProps & {
message: string;
Expand Down Expand Up @@ -51,3 +52,7 @@ export const KurtosisAlert = ({ message, details, ...alertProps }: KurtosisAlert
</Alert>
);
};

export const KurtosisAlertError = ({ error }: FallbackProps) => {
return <KurtosisAlert message={"An error ocurred, details below"} details={stringifyError(error)} />;
};
Expand Up @@ -54,11 +54,20 @@ export const KurtosisArgumentTypeInput = ({
case ArgumentValueType.INTEGER:
return <IntegerArgumentInput {...childProps} />;
case ArgumentValueType.DICT:
assertDefined(subType1, `innerType1 was not defined on DICT argument ${name}`);
assertDefined(subType2, `innerType2 was not defined on DICT argument ${name}`);
assertDefined(
subType1,
`innerType1 was not defined on DICT argument ${name}, check the format used matches https://docs.kurtosis.com/api-reference/starlark-reference/docstring-syntax#types`,
);
assertDefined(
subType2,
`innerType2 was not defined on DICT argument ${name}, check the format used matches https://docs.kurtosis.com/api-reference/starlark-reference/docstring-syntax#types`,
);
return <DictArgumentInput keyType={subType1} valueType={subType2} {...childProps} />;
case ArgumentValueType.LIST:
assertDefined(subType1, `innerType1 was not defined on DICT argument ${name}`);
assertDefined(
subType1,
`innerType1 was not defined on DICT argument ${name}, check the format used matches https://docs.kurtosis.com/api-reference/starlark-reference/docstring-syntax#types`,
);
return <ListArgumentInput valueType={subType1} {...childProps} />;
case ArgumentValueType.BOOL:
return <BooleanArgumentInput {...childProps} />;
Expand Down
Expand Up @@ -15,6 +15,7 @@ import {
} from "@chakra-ui/react";
import { EnclaveMode } from "enclave-manager-sdk/build/engine_service_pb";
import { useMemo, useRef, useState } from "react";
import { ErrorBoundary } from "react-error-boundary";
import { SubmitHandler } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import { useKurtosisClient } from "../../../client/enclaveManager/KurtosisClientContext";
Expand All @@ -24,7 +25,7 @@ import { EnclaveFullInfo } from "../../../emui/enclaves/types";
import { assertDefined, isDefined, stringifyError } from "../../../utils";
import { KURTOSIS_PACKAGE_ID_URL_ARG, KURTOSIS_PACKAGE_PARAMS_URL_ARG } from "../../constants";
import { CopyButton } from "../../CopyButton";
import { KurtosisAlert } from "../../KurtosisAlert";
import { KurtosisAlert, KurtosisAlertError } from "../../KurtosisAlert";
import { PackageSourceButton } from "../../PackageSourceButton";
import {
EnclaveConfigurationForm,
Expand Down Expand Up @@ -123,7 +124,13 @@ export const ConfigureEnclaveModal = ({
if (!isDefined(preloadArgs)) {
return undefined;
}
const parsedForm = JSON.parse(atob(preloadArgs)) as ConfigureEnclaveForm;
let parsedForm: ConfigureEnclaveForm;
try {
parsedForm = JSON.parse(atob(preloadArgs)) as ConfigureEnclaveForm;
} catch (err: any) {
setError(`Unable to parse the url - was it copied correctly? Got Error: ${stringifyError(err)}`);
return undefined;
}
kurtosisPackage.args
.filter((arg) => !isDefined(arg.typeV2?.topLevelType) || arg.typeV2?.topLevelType === ArgumentValueType.JSON)
.forEach((arg) => {
Expand Down Expand Up @@ -239,77 +246,81 @@ export const ConfigureEnclaveModal = ({
{!isDefined(existingEnclave) && "New "}Enclave Configuration
</ModalHeader>
<ModalCloseButton />
<EnclaveConfigurationForm
ref={formRef}
initialValues={initialValues}
onSubmit={handleLoadSubmit}
kurtosisPackage={kurtosisPackage}
style={{
display: "flex",
flexDirection: "column",
flex: "0 1 auto",
minHeight: 0,
}}
>
<ModalBody flex="0 1 auto" p={"0px"} display={"flex"} flexDirection={"column"}>
<Flex flex={"0"} fontSize={"sm"} justifyContent={"center"} alignItems={"center"} gap={"12px"} pb={"12px"}>
<Text>Configuring</Text>
<PackageSourceButton source={kurtosisPackage.name} size={"sm"} variant={"outline"} color={"gray.100"} />
</Flex>
{isDefined(error) && (
<KurtosisAlert flex={"1 0 auto"} message={"Could not execute configuration"} details={error} />
)}
<Flex
flex={"0 1 auto"}
overflowY={"scroll"}
minHeight={0}
flexDirection={"column"}
gap={"24px"}
p={"12px 24px"}
bg={"gray.900"}
>
<Flex justifyContent={"space-between"} alignItems={"center"}>
<Tooltip
shouldWrapChildren
label={"When enabled, Kurtosis will automatically restart any services that crash inside the enclave"}
>
<FormControl display={"flex"} alignItems={"center"} gap={"16px"}>
<BooleanArgumentInput inputType={"switch"} name={"restartServices"} />
<Text fontSize={"xs"}>Restart services</Text>
</FormControl>
</Tooltip>
<Tooltip shouldWrapChildren label={"Create a link that can be used to share this configuration."}>
<CopyButton contentName={"url"} valueToCopy={getLinkToCurrentConfig} text={"Copy link"} />
</Tooltip>
<ErrorBoundary fallbackRender={KurtosisAlertError}>
<EnclaveConfigurationForm
ref={formRef}
initialValues={initialValues}
onSubmit={handleLoadSubmit}
kurtosisPackage={kurtosisPackage}
style={{
display: "flex",
flexDirection: "column",
flex: "0 1 auto",
minHeight: 0,
}}
>
<ModalBody flex="0 1 auto" p={"0px"} display={"flex"} flexDirection={"column"}>
<Flex flex={"0"} fontSize={"sm"} justifyContent={"center"} alignItems={"center"} gap={"12px"} pb={"12px"}>
<Text>Configuring</Text>
<PackageSourceButton source={kurtosisPackage.name} size={"sm"} variant={"outline"} color={"gray.100"} />
</Flex>
<KurtosisArgumentFormControl name={"enclaveName"} label={"Enclave name"} type={"text"}>
<StringArgumentInput
name={"enclaveName"}
disabled={isDefined(existingEnclave)}
validate={(value) => {
if (value.length > 0 && !isEnclaveNameAllowed(value)) {
return `The enclave name must match ${allowedEnclaveNamePattern}`;
{isDefined(error) && (
<KurtosisAlert flex={"1 0 auto"} message={"Could not execute configuration"} details={error} />
)}
<Flex
flex={"0 1 auto"}
overflowY={"scroll"}
minHeight={0}
flexDirection={"column"}
gap={"24px"}
p={"12px 24px"}
bg={"gray.900"}
>
<Flex justifyContent={"space-between"} alignItems={"center"}>
<Tooltip
shouldWrapChildren
label={
"When enabled, Kurtosis will automatically restart any services that crash inside the enclave"
}
}}
tabIndex={1}
/>
</KurtosisArgumentFormControl>
{kurtosisPackage.args.map((arg, i) => (
<KurtosisPackageArgumentInput key={i} argument={arg} />
))}
</Flex>
</ModalBody>
<ModalFooter flex={"0"}>
<Flex justifyContent={"flex-end"} gap={"12px"}>
<Button color={"gray.100"} onClick={handleClose} isDisabled={isLoading}>
Cancel
</Button>
<Button type={"submit"} isLoading={isLoading} colorScheme={"kurtosisGreen"}>
{existingEnclave ? "Update" : "Run"}
</Button>
</Flex>
</ModalFooter>
</EnclaveConfigurationForm>
>
<FormControl display={"flex"} alignItems={"center"} gap={"16px"}>
<BooleanArgumentInput inputType={"switch"} name={"restartServices"} />
<Text fontSize={"xs"}>Restart services</Text>
</FormControl>
</Tooltip>
<Tooltip shouldWrapChildren label={"Create a link that can be used to share this configuration."}>
<CopyButton contentName={"url"} valueToCopy={getLinkToCurrentConfig} text={"Copy link"} />
</Tooltip>
</Flex>
<KurtosisArgumentFormControl name={"enclaveName"} label={"Enclave name"} type={"text"}>
<StringArgumentInput
name={"enclaveName"}
disabled={isDefined(existingEnclave)}
validate={(value) => {
if (value.length > 0 && !isEnclaveNameAllowed(value)) {
return `The enclave name must match ${allowedEnclaveNamePattern}`;
}
}}
tabIndex={1}
/>
</KurtosisArgumentFormControl>
{kurtosisPackage.args.map((arg, i) => (
<KurtosisPackageArgumentInput key={i} argument={arg} />
))}
</Flex>
</ModalBody>
<ModalFooter flex={"0"}>
<Flex justifyContent={"flex-end"} gap={"12px"}>
<Button color={"gray.100"} onClick={handleClose} isDisabled={isLoading}>
Cancel
</Button>
<Button type={"submit"} isLoading={isLoading} colorScheme={"kurtosisGreen"}>
{existingEnclave ? "Update" : "Run"}
</Button>
</Flex>
</ModalFooter>
</EnclaveConfigurationForm>
</ErrorBoundary>
</ModalContent>
</Modal>
);
Expand Down
Expand Up @@ -78,6 +78,7 @@ export const PortsTable = ({
const columns = useMemo<ColumnDef<PortsTableRow, any>[]>(
() => [
columnHelper.accessor("port", {
id: "port_name",
header: "Name",
cell: ({ row, getValue }) => (
<Flex flexDirection={"column"} gap={"10px"}>
Expand All @@ -95,6 +96,7 @@ export const PortsTable = ({
),
}),
columnHelper.accessor("port", {
id: "private_public_ports",
header: "Private / Public Ports",
cell: ({ row, getValue }) => (
<Flex flexDirection={"column"} gap={"10px"}>
Expand All @@ -105,6 +107,7 @@ export const PortsTable = ({
),
}),
columnHelper.accessor("port", {
id: "port_protocol",
header: "Application Protocol",
cell: ({ row, getValue }) => (
<Flex flexDirection={"column"} gap={"10px"}>
Expand All @@ -113,6 +116,7 @@ export const PortsTable = ({
),
}),
columnHelper.accessor("port", {
id: "port_transport",
header: "Transport Protocol",
cell: ({ row, getValue }) => (
<Flex flexDirection={"column"} gap={"10px"}>
Expand All @@ -128,7 +132,7 @@ export const PortsTable = ({
<DataTable
columns={columns}
data={getPortTableRows(instanceUUID, enclaveUUID, serviceUUID, privatePorts, publicPorts, publicIp)}
defaultSorting={[{ id: "port", desc: true }]}
defaultSorting={[{ id: "port_name", desc: true }]}
/>
);
};
7 changes: 7 additions & 0 deletions enclave-manager/web/yarn.lock
Expand Up @@ -9231,6 +9231,13 @@ react-dom@^18.2.0:
loose-envify "^1.1.0"
scheduler "^0.23.0"

react-error-boundary@^4.0.11:
version "4.0.11"
resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-4.0.11.tgz#36bf44de7746714725a814630282fee83a7c9a1c"
integrity sha512-U13ul67aP5DOSPNSCWQ/eO0AQEYzEFkVljULQIjMV0KlffTAhxuDoBKdO0pb/JZ8mDhMKFZ9NZi0BmLGUiNphw==
dependencies:
"@babel/runtime" "^7.12.5"

react-error-overlay@^6.0.11:
version "6.0.11"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb"
Expand Down
6 changes: 3 additions & 3 deletions engine/server/webapp/asset-manifest.json
@@ -1,10 +1,10 @@
{
"files": {
"main.js": "./static/js/main.de76da51.js",
"main.js": "./static/js/main.69addaf3.js",
"index.html": "./index.html",
"main.de76da51.js.map": "./static/js/main.de76da51.js.map"
"main.69addaf3.js.map": "./static/js/main.69addaf3.js.map"
},
"entrypoints": [
"static/js/main.de76da51.js"
"static/js/main.69addaf3.js"
]
}
2 changes: 1 addition & 1 deletion engine/server/webapp/index.html
@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Kurtosis Enclave Manager"/><title>Kurtosis Enclave Manager</title><script defer="defer" src="./static/js/main.de76da51.js"></script></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Kurtosis Enclave Manager"/><title>Kurtosis Enclave Manager</title><script defer="defer" src="./static/js/main.69addaf3.js"></script></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

Large diffs are not rendered by default.

Large diffs are not rendered by default.

0 comments on commit 21b5ffd

Please sign in to comment.