Address PR comments

This commit is contained in:
Carlos Monastyrski
2025-11-07 02:09:26 -03:00
parent bb6b1940d1
commit b37a9f4168
19 changed files with 327 additions and 264 deletions
@@ -10,8 +10,11 @@ export const useCreatePkiAlertV2 = () => {
return useMutation<TPkiAlertV2, unknown, TCreatePkiAlertV2>({
mutationFn: async (data) => {
const { data: response } = await apiRequest.post<TPkiAlertV2>("/api/v2/pki/alerts", data);
return response;
const { data: response } = await apiRequest.post<{ alert: TPkiAlertV2 }>(
"/api/v2/pki/alerts",
data
);
return response.alert;
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({
@@ -26,11 +29,11 @@ export const useUpdatePkiAlertV2 = () => {
return useMutation<TPkiAlertV2, unknown, TUpdatePkiAlertV2>({
mutationFn: async ({ alertId, ...data }) => {
const { data: response } = await apiRequest.patch<TPkiAlertV2>(
const { data: response } = await apiRequest.patch<{ alert: TPkiAlertV2 }>(
`/api/v2/pki/alerts/${alertId}`,
data
);
return response;
return response.alert;
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({
@@ -48,8 +51,10 @@ export const useDeletePkiAlertV2 = () => {
return useMutation<TPkiAlertV2, unknown, TDeletePkiAlertV2>({
mutationFn: async ({ alertId }) => {
const { data } = await apiRequest.delete<TPkiAlertV2>(`/api/v2/pki/alerts/${alertId}`);
return data;
const { data } = await apiRequest.delete<{ alert: TPkiAlertV2 }>(
`/api/v2/pki/alerts/${alertId}`
);
return data.alert;
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({
@@ -31,8 +31,8 @@ const fetchPkiAlertsV2 = async (params: TGetPkiAlertsV2): Promise<TGetPkiAlertsV
};
const fetchPkiAlertV2ById = async ({ alertId }: TGetPkiAlertV2ById): Promise<TPkiAlertV2> => {
const { data } = await apiRequest.get<TPkiAlertV2>(`/api/v2/pki/alerts/${alertId}`);
return data;
const { data } = await apiRequest.get<{ alert: TPkiAlertV2 }>(`/api/v2/pki/alerts/${alertId}`);
return data.alert;
};
const fetchPkiAlertV2MatchingCertificates = async (
+5 -5
View File
@@ -51,7 +51,7 @@ export interface TPkiAlertChannelV2 {
export interface TPkiAlertV2 {
id: string;
projectId: string;
slug: string;
name: string;
description?: string;
eventType: PkiAlertEventTypeV2;
alertBefore?: string;
@@ -94,7 +94,7 @@ export interface TGetPkiAlertV2ById {
export interface TCreatePkiAlertV2 {
projectId: string;
slug: string;
name: string;
description?: string;
eventType: PkiAlertEventTypeV2;
alertBefore?: string;
@@ -105,7 +105,7 @@ export interface TCreatePkiAlertV2 {
export interface TUpdatePkiAlertV2 {
alertId: string;
slug?: string;
name?: string;
description?: string;
eventType?: PkiAlertEventTypeV2;
alertBefore?: string;
@@ -172,11 +172,11 @@ export const pkiAlertChannelV2Schema = z.object({
export const createPkiAlertV2Schema = z.object({
projectId: z.string().uuid(),
slug: z
name: z
.string()
.min(1)
.max(255)
.regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Must be a valid slug (lowercase, numbers, hyphens only)"),
.regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Must be a valid name (lowercase, numbers, hyphens only)"),
description: z.string().max(1000).optional(),
eventType: z.nativeEnum(PkiAlertEventTypeV2),
alertBefore: z
@@ -45,7 +45,7 @@ export const PkiAlertsV2Page = ({ hideContainer = false }: Props) => {
const [deleteModal, setDeleteModal] = useState<{
isOpen: boolean;
alertId?: string;
slug?: string;
name?: string;
}>({
isOpen: false
});
@@ -113,7 +113,7 @@ export const PkiAlertsV2Page = ({ hideContainer = false }: Props) => {
setDeleteModal({
isOpen: true,
alertId: alert.id,
slug: alert.slug
name: alert.name
})
}
/>
@@ -199,8 +199,8 @@ export const PkiAlertsV2Page = ({ hideContainer = false }: Props) => {
<DeleteActionModal
isOpen={deleteModal.isOpen}
deleteKey="delete"
title={`Delete PKI Alert "${deleteModal.slug}"`}
onChange={(isOpen) => setDeleteModal({ isOpen, alertId: undefined, slug: undefined })}
title={`Delete PKI Alert "${deleteModal.name}"`}
onChange={(isOpen) => setDeleteModal({ isOpen, alertId: undefined, name: undefined })}
onDeleteApproved={handleDeleteAlert}
/>
</div>
@@ -162,7 +162,7 @@ export const CreatePkiAlertV2FormSteps = () => {
render={({ field, fieldState: { error } }) => (
<FormControl label="Alert Type" isError={Boolean(error)} errorText={error?.message}>
<Select
defaultValue={field.value}
value={field.value}
onValueChange={(value) => field.onChange(value)}
className="w-full"
>
@@ -185,9 +185,9 @@ export const CreatePkiAlertV2FormSteps = () => {
<Controller
control={control}
name="slug"
name="name"
render={({ field, fieldState: { error } }) => (
<FormControl label="Alert Slug" isError={Boolean(error)} errorText={error?.message}>
<FormControl label="Alert Name" isError={Boolean(error)} errorText={error?.message}>
<Input {...field} placeholder="e.g., prod-cert-expiring-soon" />
</FormControl>
)}
@@ -490,12 +490,12 @@ export const CreatePkiAlertV2FormSteps = () => {
<div className="space-y-4">
<FormControl label="Email Recipients">
<TextArea
defaultValue={
value={
Array.isArray((watchedChannels?.[0]?.config as any)?.recipients)
? (watchedChannels[0].config as any).recipients.join(", ")
: ""
}
onBlur={(e) => {
onChange={(e) => {
const emailList = e.target.value
.split(",")
.map((email) => email.trim())
@@ -522,7 +522,7 @@ export const CreatePkiAlertV2FormSteps = () => {
<span className="text-sm text-mineshaft-300">Basic Information</span>
</div>
<div className="flex flex-wrap gap-x-8 gap-y-2">
<GenericFieldLabel label="Slug">{watch("slug") || "Not specified"}</GenericFieldLabel>
<GenericFieldLabel label="Name">{watch("name") || "Not specified"}</GenericFieldLabel>
<GenericFieldLabel label="Event Type">
{formatEventType(watchedEventType)}
</GenericFieldLabel>
@@ -37,7 +37,7 @@ const FORM_TABS: { name: string; key: string; fields: (keyof TFormData)[] }[] =
{
name: "Details",
key: "basicInfo",
fields: ["slug", "description", "alertBefore"]
fields: ["name", "description", "alertBefore"]
},
{ name: "Filters", key: "filterRules", fields: ["filters"] },
{ name: "Preview", key: "preview", fields: [] },
@@ -61,7 +61,7 @@ export const CreatePkiAlertV2Modal = ({ isOpen, onOpenChange, alertToEdit, alert
resolver: zodResolver(isEditing ? updatePkiAlertV2Schema : createPkiAlertV2Schema),
defaultValues: {
projectId: currentProject?.id || "",
slug: "",
name: "",
description: "",
eventType: PkiAlertEventTypeV2.EXPIRATION,
alertBefore: "30d",
@@ -93,7 +93,7 @@ export const CreatePkiAlertV2Modal = ({ isOpen, onOpenChange, alertToEdit, alert
if (editingAlert && isEditing) {
reset({
projectId: currentProject?.id || "",
slug: editingAlert.slug,
name: editingAlert.name,
description: editingAlert.description || "",
eventType: editingAlert.eventType,
alertBefore: editingAlert.alertBefore || "30d",
@@ -121,7 +121,7 @@ export const CreatePkiAlertV2Modal = ({ isOpen, onOpenChange, alertToEdit, alert
} else if (!isEditing) {
reset({
projectId: currentProject?.id || "",
slug: "",
name: "",
description: "",
eventType: PkiAlertEventTypeV2.EXPIRATION,
alertBefore: "30d",
@@ -87,7 +87,7 @@ export const PkiAlertV2Row = ({ alert, onView, onEdit, onDelete }: Props) => {
<Tr>
<Td>
<div className="flex items-center gap-2">
<div className="font-medium text-gray-200">{alert.slug}</div>
<div className="font-medium text-gray-200">{alert.name}</div>
{alert.description && (
<Tooltip content={alert.description}>
<FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-400" />
@@ -60,7 +60,7 @@ export const UpdatePkiAlertV2Modal = ({ isOpen, onOpenChange, alertId }: Props)
useEffect(() => {
if (alert) {
reset({
slug: alert.slug,
name: alert.name,
description: alert.description || "",
eventType: alert.eventType,
alertBefore: alert.alertBefore || "",
@@ -190,7 +190,7 @@ export const UpdatePkiAlertV2Modal = ({ isOpen, onOpenChange, alertId }: Props)
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
<Controller
control={control}
name="slug"
name="name"
render={({ field, fieldState: { error } }) => (
<FormControl label="Alert Name" isError={Boolean(error)} errorText={error?.message}>
<Input {...field} placeholder="certificate-expiration-alert" />
@@ -136,7 +136,7 @@ export const ViewPkiAlertV2Modal = ({ isOpen, onOpenChange, alertId }: Props) =>
<ModalContent title="Certificate Alert Details" className="max-w-6xl">
<div className="space-y-6">
<div className="flex items-center justify-between">
<h2 className="text-xl font-semibold text-gray-200">{alert.slug}</h2>
<h2 className="text-xl font-semibold text-gray-200">{alert.name}</h2>
<Badge variant={alert.enabled ? "success" : "neutral"}>
{alert.enabled ? "Enabled" : "Disabled"}
</Badge>
@@ -176,11 +176,11 @@ export const ViewPkiAlertV2Modal = ({ isOpen, onOpenChange, alertId }: Props) =>
<div className="space-y-3">
<h3 className="text-lg font-medium text-gray-200">Filter Rules</h3>
{alert.filters.length === 0 ? (
{(alert.filters || []).length === 0 ? (
<p className="text-gray-400">No filter rules configured</p>
) : (
<div className="space-y-2">
{alert.filters.map((filter) => {
{(alert.filters || []).map((filter) => {
const formatFilterText = () => {
const field = filter.field.replace(/_/g, " ");
const operator = filter.operator.replace(/_/g, " ");
@@ -207,14 +207,14 @@ export const ViewPkiAlertV2Modal = ({ isOpen, onOpenChange, alertId }: Props) =>
<div className="space-y-3">
<h3 className="text-lg font-medium text-gray-200">Notification Recipients</h3>
{alert.channels.some(
{(alert.channels || []).some(
(channel) =>
channel.channelType === "email" && (channel.config as any)?.recipients
) ? (
<div className="space-y-3">
<div>
<div className="flex flex-wrap gap-1">
{alert.channels
{(alert.channels || [])
.filter(
(channel) =>
channel.channelType === "email" &&