chore: minor ui improvements

This commit is contained in:
Daniel Hougaard
2025-03-05 22:47:40 +04:00
parent 16c1516979
commit b607429b99
2 changed files with 47 additions and 7 deletions
@@ -1,13 +1,21 @@
import { useState } from "react"; /* eslint-disable no-nested-ternary */
import { faChevronRight, faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons"; import { useEffect, useState } from "react";
import {
faChevronRight,
faExclamationTriangle,
faEye,
faEyeSlash
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import * as Collapsible from "@radix-ui/react-collapsible"; import * as Collapsible from "@radix-ui/react-collapsible";
import { AxiosError } from "axios";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { createNotification } from "@app/components/notifications";
import { FormControl, FormLabel, SecretInput, Spinner, Tooltip } from "@app/components/v2"; import { FormControl, FormLabel, SecretInput, Spinner, Tooltip } from "@app/components/v2";
import { useWorkspace } from "@app/context"; import { useWorkspace } from "@app/context";
import { useGetSecretReferenceTree } from "@app/hooks/api"; import { useGetSecretReferenceTree } from "@app/hooks/api";
import { TSecretReferenceTraceNode } from "@app/hooks/api/types"; import { ApiErrorTypes, TApiErrors, TSecretReferenceTraceNode } from "@app/hooks/api/types";
import style from "./SecretReferenceDetails.module.css"; import style from "./SecretReferenceDetails.module.css";
@@ -84,7 +92,7 @@ export const SecretReferenceTree = ({ secretPath, environment, secretKey }: Prop
const { currentWorkspace } = useWorkspace(); const { currentWorkspace } = useWorkspace();
const projectId = currentWorkspace?.id || ""; const projectId = currentWorkspace?.id || "";
const { data, isPending } = useGetSecretReferenceTree({ const { data, isPending, isError, error } = useGetSecretReferenceTree({
secretPath, secretPath,
environmentSlug: environment, environmentSlug: environment,
projectId, projectId,
@@ -94,6 +102,26 @@ export const SecretReferenceTree = ({ secretPath, environment, secretKey }: Prop
const tree = data?.tree; const tree = data?.tree;
const secretValue = data?.value; const secretValue = data?.value;
useEffect(() => {
if (error instanceof AxiosError) {
const err = error?.response?.data as TApiErrors;
if (err?.error === ApiErrorTypes.CustomForbiddenError) {
createNotification({
title: "You don't have permission to view reference tree",
text: "You don't have permission to view one or more of the referenced secrets.",
type: "error"
});
return;
}
createNotification({
title: "Error fetching secret reference tree",
text: "Please try again later.",
type: "error"
});
}
}, [error]);
if (isPending) { if (isPending) {
return ( return (
<div className="flex items-center justify-center py-4"> <div className="flex items-center justify-center py-4">
@@ -114,11 +142,16 @@ export const SecretReferenceTree = ({ secretPath, environment, secretKey }: Prop
</FormControl> </FormControl>
<FormLabel className="mb-2" label="Reference Tree" /> <FormLabel className="mb-2" label="Reference Tree" />
<div className="thin-scrollbar relative max-h-96 overflow-auto rounded-md border border-mineshaft-600 bg-bunker-700 py-6 text-sm text-mineshaft-200"> <div className="thin-scrollbar relative max-h-96 overflow-auto rounded-md border border-mineshaft-600 bg-bunker-700 py-6 text-sm text-mineshaft-200">
{tree && ( {isError ? (
<div className="flex items-center justify-center py-4">
<FontAwesomeIcon icon={faExclamationTriangle} className="mr-2 text-red-500" />
<p className="text-red-500">Error fetching secret reference tree</p>
</div>
) : tree ? (
<ul className={style.tree}> <ul className={style.tree}>
<SecretReferenceNode node={tree} isRoot secretKey={secretKey} /> <SecretReferenceNode node={tree} isRoot secretKey={secretKey} />
</ul> </ul>
)} ) : null}
</div> </div>
<div className="mt-2 text-sm text-mineshaft-400"> <div className="mt-2 text-sm text-mineshaft-400">
Click a secret key to view its sub-references. Click a secret key to view its sub-references.
+8 -1
View File
@@ -46,7 +46,8 @@ export enum ApiErrorTypes {
ValidationError = "ValidationFailure", ValidationError = "ValidationFailure",
BadRequestError = "BadRequest", BadRequestError = "BadRequest",
UnauthorizedError = "UnauthorizedError", UnauthorizedError = "UnauthorizedError",
ForbiddenError = "PermissionDenied" ForbiddenError = "PermissionDenied",
CustomForbiddenError = "ForbiddenError"
} }
export type TApiErrors = export type TApiErrors =
@@ -69,6 +70,12 @@ export type TApiErrors =
details: PureAbility["rules"]; details: PureAbility["rules"];
statusCode: 403; statusCode: 403;
} }
| {
reqId: string;
error: ApiErrorTypes.CustomForbiddenError;
message: string;
statusCode: 403;
}
| { | {
reqId: string; reqId: string;
statusCode: 400; statusCode: 400;