Skip to content

Commit

Permalink
fix(web): show link for deployed_version.url
Browse files Browse the repository at this point in the history
  • Loading branch information
JosephKav committed Apr 15, 2024
1 parent b182af4 commit bcbd835
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 77 deletions.
6 changes: 3 additions & 3 deletions web/ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions web/ui/react-app/src/components/generic/form-validate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,23 @@ export const regexTest = (value: string, use?: boolean) => {
return true;
};

/**
* Returns an error message if the value is not a valid Git repository
*
* @param value - The value to test
* @param use - Whether to use this test
* @returns - An error message if the value is not a valid Git repository
*/
export const repoTest = (value: string, use?: boolean) => {
if (!value || !use) return true;

if (/^[\w.-]+\/[\w.-]+$/g.test(value)) {
return true;
}

return "Must be in the format OWNER/REPO";
};

/**
* Returns an error message if the value is required
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useFormContext, useWatch } from "react-hook-form";

import { BooleanWithDefault } from "components/generic";
import { DeployedVersionLookupEditType } from "types/service-edit";
import VersionWithLink from "./version-with-link";
import VersionWithRefresh from "./version-with-refresh";

interface Props {
Expand Down Expand Up @@ -60,13 +61,11 @@ const EditServiceDeployedVersion: FC<Props> = ({
<Accordion>
<Accordion.Header>Deployed Version:</Accordion.Header>
<Accordion.Body>
<FormItem
key="url"
<VersionWithLink
name="deployed_version.url"
type="url"
col_sm={12}
label="URL"
tooltip="URL to query for the version that's running"
isURL
/>
<BooleanWithDefault
name="deployed_version.allow_invalid_certs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,18 @@ const EditServiceLatestVersion: FC<Props> = ({
/>
<VersionWithLink
name="latest_version.url"
type={latestVersionType}
required
col_sm={8}
col_xs={8}
type={latestVersionType}
tooltip={
latestVersionType === "github" ? (
<>
{"https://github.com/"}
<span className="bold-underline">OWNER/REPO</span>
</>
) : undefined
}
position="right"
/>
{latestVersionType === "github" ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ const TestNotify: FC<Props> = ({ path, original, extras }) => {
const currentTime = Date.now();
if (currentTime - lastFetched < 2000) return;

// double trugger to ensure all fields are validated
await trigger(path);
const result = await trigger(path);
const result = await trigger(path, { shouldFocus: true });
if (result) {
testRefetch();
setLastFetched(currentTime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import {
FormGroup,
InputGroup,
} from "react-bootstrap";
import { FC, useEffect, useState } from "react";
import { FC, useState } from "react";
import {
repoTest,
requiredTest,
urlTest,
} from "components/generic/form-validate";
import { useFormContext, useWatch } from "react-hook-form";

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
Expand All @@ -19,8 +24,9 @@ interface Props {
name: string;
type: "github" | "url";
required?: boolean;
col_sm: number;
col_xs: number;
col_sm?: number;
col_xs?: number;
tooltip?: string | JSX.Element;
position?: Position;
}

Expand All @@ -32,6 +38,7 @@ interface Props {
* @param required - Whether the field is required
* @param col_xs - The number of columns the item takes up on XS+ screens
* @param col_sm - The number of columns the item takes up on SM+ screens
* @param tooltip - The tooltip for the field
* @param position - The position of the field
* @returns The form fields for the `latest_version`
*/
Expand All @@ -41,88 +48,43 @@ const VersionWithLink: FC<Props> = ({
required,
col_xs = 12,
col_sm = 6,
tooltip,
position,
}) => {
const { setValue, setError, clearErrors } = useFormContext();
const { register, setError, clearErrors } = useFormContext();
const value: string = useWatch({ name: name });

const [isUnfocused, setIsUnfocused] = useState(true);
const handleFocus = () => {
setIsUnfocused(false);
};
const handleBlur = () => {
setIsUnfocused(true);
};
const handleFocus = () => setIsUnfocused(false);
const handleBlur = () => setIsUnfocused(true);
const link = (type: "github" | "url") =>
type === "github" ? `https://github.com/${value}` : value;

const error = useError(name, required ? true : false);
const error = useError(name, true);

const padding = formPadding({ col_xs, col_sm, position });

useEffect(() => {
if (!isUnfocused) return;

if (required && !value) {
setError(name, { type: "required", message: "Required" });
return;
}

if (type === "url") {
try {
const parsedURL = new URL(value);
if (!["http:", "https:"].includes(parsedURL.protocol))
throw new Error("Invalid protocol");
} catch (error) {
if (/^https?:\/\//.test(value as string)) {
setError(name, {
type: "url",
message: "Invalid URL",
});
return;
}
setError(name, {
type: "url",
message: "Invalid URL - http(s):// prefix required",
});
return;
}
}
// GitHub - OWNER/REPO
else {
if (!/^[\w-]+\/[\w-]+$/g.test(value)) {
setError(name, {
type: "github",
message: "Must be in the format 'OWNER/REPO'",
});
return;
}
}

clearErrors(name);
}, [value, isUnfocused]);

return (
<Col xs={col_xs} sm={col_sm} className={`${padding} pt-1 pb-1 col-form`}>
<FormGroup>
<FormLabel
text={type === "github" ? "Repository" : "URL"}
tooltip={
type === "github" ? (
<>
{"https://github.com/"}
<span className="bold-underline">OWNER/REPO</span>
</>
) : undefined
}
tooltip={tooltip}
required={required !== false}
/>
<InputGroup className="me-3">
<FormControl
defaultValue={value}
onFocus={handleFocus}
onBlur={handleBlur}
onChange={(e) => setValue(name, e.target.value)}
{...register(name, {
validate: {
required: (value) =>
requiredTest(value, name, setError, clearErrors, required),
isType: (value) =>
type === "url" ? urlTest(value, true) : repoTest(value, true),
},
onBlur: handleBlur,
})}
isInvalid={!!error}
/>
{isUnfocused && value && !error && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const VersionWithRefresh: FC<Props> = ({ vType, serviceName, original }) => {
if (currentTime - lastFetched < 1000) return;

// Ensure valid form
const result = await trigger(dataTarget);
const result = await trigger(dataTarget, { shouldFocus: true });
if (!result) return;

refetchSemanticVersioning();
Expand Down
4 changes: 2 additions & 2 deletions web/ui/react-app/src/utils/query-params.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ export const deepDiff = (
// diff arrays
if (Array.isArray(oldObj[key]) || Array.isArray(newObj[key])) {
// if array lengths differ, include all elements in diff
if ((oldObj[key] ?? []).length !== newObj[key].length) {
if ((oldObj[key] ?? []).length !== (newObj[key] ?? []).length) {
diff[key] = newObj[key];
// else, recurse on each element
} else {
const subDiff = (oldObj[key] || []).map(
const subDiff = (oldObj[key] ?? []).map(
(elem: DiffObject, i: string | number) =>
deepDiff(newObj[key][i], elem)
);
Expand Down

0 comments on commit bcbd835

Please sign in to comment.