mirror of
https://github.com/fosrl/pangolin.git
synced 2026-05-17 06:24:32 +00:00
dont filter admin role in role selector for alerts
This commit is contained in:
@@ -97,10 +97,7 @@ export default function UptimeAlertSection({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const allRoles = useMemo(
|
const allRoles = useMemo(
|
||||||
() =>
|
() => orgRoles.map((r) => ({ id: String(r.roleId), text: r.name })),
|
||||||
orgRoles
|
|
||||||
.map((r) => ({ id: String(r.roleId), text: r.name }))
|
|
||||||
.filter((r) => r.text !== "Admin"),
|
|
||||||
[orgRoles]
|
[orgRoles]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -30,10 +30,7 @@ import {
|
|||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
SelectValue
|
SelectValue
|
||||||
} from "@app/components/ui/select";
|
} from "@app/components/ui/select";
|
||||||
import {
|
import { RadioGroup, RadioGroupItem } from "@app/components/ui/radio-group";
|
||||||
RadioGroup,
|
|
||||||
RadioGroupItem
|
|
||||||
} from "@app/components/ui/radio-group";
|
|
||||||
import { Label } from "@app/components/ui/label";
|
import { Label } from "@app/components/ui/label";
|
||||||
import { StrategySelect } from "@app/components/StrategySelect";
|
import { StrategySelect } from "@app/components/StrategySelect";
|
||||||
import { TagInput, type Tag } from "@app/components/tags/tag-input";
|
import { TagInput, type Tag } from "@app/components/tags/tag-input";
|
||||||
@@ -59,7 +56,6 @@ export function AddActionPanel({
|
|||||||
}) {
|
}) {
|
||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
|
|
||||||
|
|
||||||
const EXTERNAL_INTEGRATIONS = [
|
const EXTERNAL_INTEGRATIONS = [
|
||||||
{
|
{
|
||||||
id: "pagerduty",
|
id: "pagerduty",
|
||||||
@@ -247,9 +243,7 @@ function HealthCheckMultiSelect({
|
|||||||
const shown = useMemo(() => {
|
const shown = useMemo(() => {
|
||||||
const query = debounced.trim().toLowerCase();
|
const query = debounced.trim().toLowerCase();
|
||||||
const base = query
|
const base = query
|
||||||
? healthChecks.filter((hc) =>
|
? healthChecks.filter((hc) => hc.name.toLowerCase().includes(query))
|
||||||
hc.name.toLowerCase().includes(query)
|
|
||||||
)
|
|
||||||
: healthChecks;
|
: healthChecks;
|
||||||
// Always keep already-selected items visible even if they fall outside the search
|
// Always keep already-selected items visible even if they fall outside the search
|
||||||
if (query && value.length > 0) {
|
if (query && value.length > 0) {
|
||||||
@@ -323,9 +317,7 @@ function HealthCheckMultiSelect({
|
|||||||
aria-hidden
|
aria-hidden
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
/>
|
/>
|
||||||
<span className="truncate">
|
<span className="truncate">{hc.name}</span>
|
||||||
{hc.name}
|
|
||||||
</span>
|
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
))}
|
))}
|
||||||
</CommandGroup>
|
</CommandGroup>
|
||||||
@@ -510,8 +502,12 @@ function NotifyActionFields({
|
|||||||
number | null
|
number | null
|
||||||
>(null);
|
>(null);
|
||||||
|
|
||||||
const { data: orgUsers = [], isLoading: isLoadingUsers } = useQuery(orgQueries.users({ orgId }));
|
const { data: orgUsers = [], isLoading: isLoadingUsers } = useQuery(
|
||||||
const { data: orgRoles = [], isLoading: isLoadingRoles } = useQuery(orgQueries.roles({ orgId }));
|
orgQueries.users({ orgId })
|
||||||
|
);
|
||||||
|
const { data: orgRoles = [], isLoading: isLoadingRoles } = useQuery(
|
||||||
|
orgQueries.roles({ orgId })
|
||||||
|
);
|
||||||
|
|
||||||
const allUsers = useMemo(
|
const allUsers = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@@ -527,10 +523,7 @@ function NotifyActionFields({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const allRoles = useMemo(
|
const allRoles = useMemo(
|
||||||
() =>
|
() => orgRoles.map((r) => ({ id: String(r.roleId), text: r.name })),
|
||||||
orgRoles
|
|
||||||
.map((r) => ({ id: String(r.roleId), text: r.name }))
|
|
||||||
.filter((r) => r.text !== "Admin"),
|
|
||||||
[orgRoles]
|
[orgRoles]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -578,9 +571,18 @@ function NotifyActionFields({
|
|||||||
hasResolvedTagsRef.current = true;
|
hasResolvedTagsRef.current = true;
|
||||||
}, [isLoadingUsers, isLoadingRoles, allUsers, allRoles]);
|
}, [isLoadingUsers, isLoadingRoles, allUsers, allRoles]);
|
||||||
|
|
||||||
const userTags = (useWatch({ control, name: `actions.${index}.userTags` }) ?? []) as Tag[];
|
const userTags = (useWatch({
|
||||||
const roleTags = (useWatch({ control, name: `actions.${index}.roleTags` }) ?? []) as Tag[];
|
control,
|
||||||
const emailTags = (useWatch({ control, name: `actions.${index}.emailTags` }) ?? []) as Tag[];
|
name: `actions.${index}.userTags`
|
||||||
|
}) ?? []) as Tag[];
|
||||||
|
const roleTags = (useWatch({
|
||||||
|
control,
|
||||||
|
name: `actions.${index}.roleTags`
|
||||||
|
}) ?? []) as Tag[];
|
||||||
|
const emailTags = (useWatch({
|
||||||
|
control,
|
||||||
|
name: `actions.${index}.emailTags`
|
||||||
|
}) ?? []) as Tag[];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-3 pt-1">
|
<div className="space-y-3 pt-1">
|
||||||
@@ -788,7 +790,9 @@ function WebhookActionFields({
|
|||||||
{t("httpDestAuthNoneTitle")}
|
{t("httpDestAuthNoneTitle")}
|
||||||
</Label>
|
</Label>
|
||||||
<p className="text-xs text-muted-foreground mt-0.5">
|
<p className="text-xs text-muted-foreground mt-0.5">
|
||||||
{t("httpDestAuthNoneDescription")}
|
{t(
|
||||||
|
"httpDestAuthNoneDescription"
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -806,10 +810,14 @@ function WebhookActionFields({
|
|||||||
htmlFor={`auth-bearer-${index}`}
|
htmlFor={`auth-bearer-${index}`}
|
||||||
className="cursor-pointer font-medium"
|
className="cursor-pointer font-medium"
|
||||||
>
|
>
|
||||||
{t("httpDestAuthBearerTitle")}
|
{t(
|
||||||
|
"httpDestAuthBearerTitle"
|
||||||
|
)}
|
||||||
</Label>
|
</Label>
|
||||||
<p className="text-xs text-muted-foreground mt-0.5">
|
<p className="text-xs text-muted-foreground mt-0.5">
|
||||||
{t("httpDestAuthBearerDescription")}
|
{t(
|
||||||
|
"httpDestAuthBearerDescription"
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{field.value === "bearer" && (
|
{field.value === "bearer" && (
|
||||||
@@ -821,7 +829,9 @@ function WebhookActionFields({
|
|||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input
|
||||||
{...f}
|
{...f}
|
||||||
placeholder={t("httpDestAuthBearerPlaceholder")}
|
placeholder={t(
|
||||||
|
"httpDestAuthBearerPlaceholder"
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
@@ -845,10 +855,14 @@ function WebhookActionFields({
|
|||||||
htmlFor={`auth-basic-${index}`}
|
htmlFor={`auth-basic-${index}`}
|
||||||
className="cursor-pointer font-medium"
|
className="cursor-pointer font-medium"
|
||||||
>
|
>
|
||||||
{t("httpDestAuthBasicTitle")}
|
{t(
|
||||||
|
"httpDestAuthBasicTitle"
|
||||||
|
)}
|
||||||
</Label>
|
</Label>
|
||||||
<p className="text-xs text-muted-foreground mt-0.5">
|
<p className="text-xs text-muted-foreground mt-0.5">
|
||||||
{t("httpDestAuthBasicDescription")}
|
{t(
|
||||||
|
"httpDestAuthBasicDescription"
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{field.value === "basic" && (
|
{field.value === "basic" && (
|
||||||
@@ -860,7 +874,9 @@ function WebhookActionFields({
|
|||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input
|
||||||
{...f}
|
{...f}
|
||||||
placeholder={t("httpDestAuthBasicPlaceholder")}
|
placeholder={t(
|
||||||
|
"httpDestAuthBasicPlaceholder"
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
@@ -884,10 +900,14 @@ function WebhookActionFields({
|
|||||||
htmlFor={`auth-custom-${index}`}
|
htmlFor={`auth-custom-${index}`}
|
||||||
className="cursor-pointer font-medium"
|
className="cursor-pointer font-medium"
|
||||||
>
|
>
|
||||||
{t("httpDestAuthCustomTitle")}
|
{t(
|
||||||
|
"httpDestAuthCustomTitle"
|
||||||
|
)}
|
||||||
</Label>
|
</Label>
|
||||||
<p className="text-xs text-muted-foreground mt-0.5">
|
<p className="text-xs text-muted-foreground mt-0.5">
|
||||||
{t("httpDestAuthCustomDescription")}
|
{t(
|
||||||
|
"httpDestAuthCustomDescription"
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{field.value === "custom" && (
|
{field.value === "custom" && (
|
||||||
@@ -895,12 +915,16 @@ function WebhookActionFields({
|
|||||||
<FormField
|
<FormField
|
||||||
control={control}
|
control={control}
|
||||||
name={`actions.${index}.customHeaderName`}
|
name={`actions.${index}.customHeaderName`}
|
||||||
render={({ field: f }) => (
|
render={({
|
||||||
|
field: f
|
||||||
|
}) => (
|
||||||
<FormItem className="flex-1">
|
<FormItem className="flex-1">
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input
|
||||||
{...f}
|
{...f}
|
||||||
placeholder={t("httpDestAuthCustomHeaderNamePlaceholder")}
|
placeholder={t(
|
||||||
|
"httpDestAuthCustomHeaderNamePlaceholder"
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
@@ -910,12 +934,16 @@ function WebhookActionFields({
|
|||||||
<FormField
|
<FormField
|
||||||
control={control}
|
control={control}
|
||||||
name={`actions.${index}.customHeaderValue`}
|
name={`actions.${index}.customHeaderValue`}
|
||||||
render={({ field: f }) => (
|
render={({
|
||||||
|
field: f
|
||||||
|
}) => (
|
||||||
<FormItem className="flex-1">
|
<FormItem className="flex-1">
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input
|
||||||
{...f}
|
{...f}
|
||||||
placeholder={t("httpDestAuthCustomHeaderValuePlaceholder")}
|
placeholder={t(
|
||||||
|
"httpDestAuthCustomHeaderValuePlaceholder"
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
@@ -949,7 +977,7 @@ function WebhookHeadersField({
|
|||||||
}) {
|
}) {
|
||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
const headers =
|
const headers =
|
||||||
(useWatch({ control, name: `actions.${index}.headers` as const }) ?? []);
|
useWatch({ control, name: `actions.${index}.headers` as const }) ?? [];
|
||||||
return (
|
return (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<FormLabel>{t("alertingWebhookHeaders")}</FormLabel>
|
<FormLabel>{t("alertingWebhookHeaders")}</FormLabel>
|
||||||
@@ -961,7 +989,12 @@ function WebhookHeadersField({
|
|||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="flex-1">
|
<FormItem className="flex-1">
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input {...field} placeholder={t("webhookHeaderKeyPlaceholder")} />
|
<Input
|
||||||
|
{...field}
|
||||||
|
placeholder={t(
|
||||||
|
"webhookHeaderKeyPlaceholder"
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
@@ -972,7 +1005,12 @@ function WebhookHeadersField({
|
|||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="flex-1">
|
<FormItem className="flex-1">
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input {...field} placeholder={t("webhookHeaderValuePlaceholder")} />
|
<Input
|
||||||
|
{...field}
|
||||||
|
placeholder={t(
|
||||||
|
"webhookHeaderValuePlaceholder"
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
@@ -984,9 +1022,8 @@ function WebhookHeadersField({
|
|||||||
className="shrink-0"
|
className="shrink-0"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const cur =
|
const cur =
|
||||||
form.getValues(
|
form.getValues(`actions.${index}.headers`) ??
|
||||||
`actions.${index}.headers`
|
[];
|
||||||
) ?? [];
|
|
||||||
form.setValue(
|
form.setValue(
|
||||||
`actions.${index}.headers`,
|
`actions.${index}.headers`,
|
||||||
cur.filter((__, i) => i !== hi),
|
cur.filter((__, i) => i !== hi),
|
||||||
@@ -1005,10 +1042,11 @@ function WebhookHeadersField({
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
const cur =
|
const cur =
|
||||||
form.getValues(`actions.${index}.headers`) ?? [];
|
form.getValues(`actions.${index}.headers`) ?? [];
|
||||||
form.setValue(`actions.${index}.headers`, [
|
form.setValue(
|
||||||
...cur,
|
`actions.${index}.headers`,
|
||||||
{ key: "", value: "" }
|
[...cur, { key: "", value: "" }],
|
||||||
], { shouldDirty: true });
|
{ shouldDirty: true }
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Plus className="h-4 w-4 mr-1" />
|
<Plus className="h-4 w-4 mr-1" />
|
||||||
@@ -1111,22 +1149,18 @@ export function AlertRuleSourceFields({
|
|||||||
curTrigger !== "resource_unhealthy" &&
|
curTrigger !== "resource_unhealthy" &&
|
||||||
curTrigger !== "resource_toggle"
|
curTrigger !== "resource_toggle"
|
||||||
) {
|
) {
|
||||||
setValue(
|
setValue("trigger", "resource_toggle", {
|
||||||
"trigger",
|
shouldValidate: true
|
||||||
"resource_toggle",
|
});
|
||||||
{ shouldValidate: true }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
curTrigger !== "health_check_healthy" &&
|
curTrigger !== "health_check_healthy" &&
|
||||||
curTrigger !== "health_check_unhealthy" &&
|
curTrigger !== "health_check_unhealthy" &&
|
||||||
curTrigger !== "health_check_toggle"
|
curTrigger !== "health_check_toggle"
|
||||||
) {
|
) {
|
||||||
setValue(
|
setValue("trigger", "health_check_toggle", {
|
||||||
"trigger",
|
shouldValidate: true
|
||||||
"health_check_toggle",
|
});
|
||||||
{ shouldValidate: true }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user