feat: disallow auditors from editing <NotificationsPage /> settings (#22382)

Auditors are still able to access and read this page but they won't be
aren't able to update any of the content, we should show that to them.
Should also be noted that this page isn't shown to the user in the
sidebar when they are an Auditor.
This commit is contained in:
Jake Howell
2026-04-06 22:32:51 +10:00
committed by GitHub
parent b36619b905
commit baba9e6ede
3 changed files with 23 additions and 3 deletions
@@ -36,6 +36,7 @@ type NotificationEventsProps = {
availableMethods: NotificationMethod[];
templatesByGroup: ReturnType<typeof selectTemplatesByGroup>;
deploymentConfig: DeploymentValues;
canEdit?: boolean;
};
export const NotificationEvents: FC<NotificationEventsProps> = ({
@@ -43,6 +44,7 @@ export const NotificationEvents: FC<NotificationEventsProps> = ({
availableMethods,
templatesByGroup,
deploymentConfig,
canEdit = true,
}) => {
// Webhook
const hasWebhookNotifications = Object.values(templatesByGroup)
@@ -128,6 +130,7 @@ export const NotificationEvents: FC<NotificationEventsProps> = ({
templateId={tpl.id}
options={availableMethods}
value={value}
canEdit={canEdit}
/>
</ListItem>
{!isLastItem && <Divider />}
@@ -152,12 +155,14 @@ type MethodToggleGroupProps = {
templateId: string;
options: NotificationMethod[];
value: NotificationMethod;
canEdit: boolean;
};
const MethodToggleGroup: FC<MethodToggleGroupProps> = ({
value,
options,
templateId,
canEdit,
}) => {
const queryClient = useQueryClient();
const updateMethodMutation = useMutation(
@@ -169,9 +174,13 @@ const MethodToggleGroup: FC<MethodToggleGroupProps> = ({
exclusive
value={value}
size="small"
disabled={!canEdit}
aria-label="Notification method"
css={styles.toggleGroup}
onChange={async (_, method) => {
if (!method) {
return;
}
try {
await updateMethodMutation.mutateAsync({
method,
@@ -196,6 +205,7 @@ const MethodToggleGroup: FC<MethodToggleGroupProps> = ({
<ToggleButton
value={method}
css={styles.toggleButton}
disabled={!canEdit}
onClick={(e) => {
// Retain the value if the user clicks the same button, ensuring
// at least one value remains selected.
@@ -19,6 +19,7 @@ import {
TabsList,
TabsTrigger,
} from "#/components/Tabs/Tabs";
import { useAuthenticated } from "#/hooks/useAuthenticated";
import { useSearchParamsKey } from "#/hooks/useSearchParamsKey";
import { useDeploymentConfig } from "#/modules/management/DeploymentConfigProvider";
import { castNotificationMethod } from "#/modules/notifications/utils";
@@ -38,7 +39,9 @@ function isNotificationTab(
}
const NotificationsPage: FC = () => {
const { permissions } = useAuthenticated();
const { deploymentConfig } = useDeploymentConfig();
const canEditDeploymentConfig = permissions.editDeploymentConfig;
const [systemTemplatesByGroup, customTemplatesByGroup, dispatchMethods] =
useQueries({
queries: [
@@ -102,6 +105,7 @@ const NotificationsPage: FC = () => {
<NotificationEvents
templatesByGroup={allTemplatesByGroup}
deploymentConfig={deploymentConfig.config}
canEdit={canEditDeploymentConfig}
defaultMethod={castNotificationMethod(
dispatchMethods.data.default,
)}
@@ -118,7 +122,7 @@ const NotificationsPage: FC = () => {
/>
</TabsContent>
<TabsContent value="troubleshooting" className="py-6">
<Troubleshooting />
<Troubleshooting canEdit={canEditDeploymentConfig} />
</TabsContent>
</Tabs>
)}
@@ -7,7 +7,13 @@ import { getErrorDetail } from "#/api/errors";
import { Button } from "#/components/Button/Button";
import { Spinner } from "#/components/Spinner/Spinner";
export const Troubleshooting: FC = () => {
type TroubleshootingProps = {
canEdit?: boolean;
};
export const Troubleshooting: FC<TroubleshootingProps> = ({
canEdit = true,
}) => {
const { mutate: sendTestNotificationApi, isPending } = useMutation({
mutationFn: API.postTestNotification,
onSuccess: () => toast.success("Test notification sent."),
@@ -35,7 +41,7 @@ export const Troubleshooting: FC = () => {
<Button
variant="outline"
size="sm"
disabled={isPending}
disabled={isPending || !canEdit}
onClick={() => {
sendTestNotificationApi();
}}