mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-20 11:12:31 +02:00
Show a warning if the logs are disabled to reduce confusion
This commit is contained in:
@@ -3547,6 +3547,9 @@
|
|||||||
"sidebarLogsAction": "Admin Action Logs",
|
"sidebarLogsAction": "Admin Action Logs",
|
||||||
"logRetention": "Log Retention",
|
"logRetention": "Log Retention",
|
||||||
"logRetentionDescription": "Manage how long different types of logs are retained for this organization or disable them",
|
"logRetentionDescription": "Manage how long different types of logs are retained for this organization or disable them",
|
||||||
|
"logRetentionDisabledWarningTitle": "Log Retention Disabled",
|
||||||
|
"logRetentionDisabledWarningDescription": "{logType} are not being retained for this organization, so new activity will not appear here. Enable retention in security settings to start collecting these logs.",
|
||||||
|
"logRetentionDisabledWarningButton": "Go to Security Settings",
|
||||||
"requestLogsDescription": "View detailed request logs for HTTPS resources in this organization",
|
"requestLogsDescription": "View detailed request logs for HTTPS resources in this organization",
|
||||||
"aiSessionLogs": "AI Gateway Session Logs",
|
"aiSessionLogs": "AI Gateway Session Logs",
|
||||||
"aiSessionLogsDescription": "View prompt and response transcripts for AI gateway requests in this organization",
|
"aiSessionLogsDescription": "View prompt and response transcripts for AI gateway requests in this organization",
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ export const orgs = pgTable("orgs", {
|
|||||||
"settingsLogRetentionDaysAISessions"
|
"settingsLogRetentionDaysAISessions"
|
||||||
) // where 0 = dont keep logs and -1 = keep forever and 9001 = end of the following year
|
) // where 0 = dont keep logs and -1 = keep forever and 9001 = end of the following year
|
||||||
.notNull()
|
.notNull()
|
||||||
.default(7),
|
.default(0),
|
||||||
sshCaPrivateKey: text("sshCaPrivateKey"), // Encrypted SSH CA private key (PEM format)
|
sshCaPrivateKey: text("sshCaPrivateKey"), // Encrypted SSH CA private key (PEM format)
|
||||||
sshCaPublicKey: text("sshCaPublicKey"), // SSH CA public key (OpenSSH format)
|
sshCaPublicKey: text("sshCaPublicKey"), // SSH CA public key (OpenSSH format)
|
||||||
isBillingOrg: boolean("isBillingOrg"),
|
isBillingOrg: boolean("isBillingOrg"),
|
||||||
|
|||||||
@@ -443,7 +443,11 @@ export const configSchema = z
|
|||||||
disable_config_managed_domains: z.boolean().optional(),
|
disable_config_managed_domains: z.boolean().optional(),
|
||||||
disable_product_help_banners: z.boolean().optional(),
|
disable_product_help_banners: z.boolean().optional(),
|
||||||
disable_enterprise_features: z.boolean().optional(),
|
disable_enterprise_features: z.boolean().optional(),
|
||||||
enable_acme_cert_sync: z.boolean().optional().default(true)
|
enable_acme_cert_sync: z.boolean().optional().default(true),
|
||||||
|
disable_private_http_placeholder: z
|
||||||
|
.boolean()
|
||||||
|
.optional()
|
||||||
|
.default(false)
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
acme: z
|
acme: z
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export class PrivateConfig {
|
|||||||
|
|
||||||
this.rawPrivateConfig = parsedPrivateConfig;
|
this.rawPrivateConfig = parsedPrivateConfig;
|
||||||
|
|
||||||
this.migrateDeprecatedAcmeConfig(privateEnvironment);
|
this.migrateDeprecatedConfig(privateEnvironment);
|
||||||
|
|
||||||
process.env.BRANDING_HIDE_AUTH_LAYOUT_FOOTER =
|
process.env.BRANDING_HIDE_AUTH_LAYOUT_FOOTER =
|
||||||
this.rawPrivateConfig.branding?.hide_auth_layout_footer === true
|
this.rawPrivateConfig.branding?.hide_auth_layout_footer === true
|
||||||
@@ -152,12 +152,12 @@ export class PrivateConfig {
|
|||||||
return this.rawPrivateConfig;
|
return this.rawPrivateConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
// `flags.enable_acme_cert_sync` and `acme` used to live in the private
|
// `flags.enable_acme_cert_sync`, `flags.disable_private_http_placeholder`,
|
||||||
// config file. They now live in the public config file. If an operator
|
// and `acme` used to live in the private config file. They now live in
|
||||||
// still has them set in the private config and hasn't moved them over to
|
// the public config file. If an operator still has them set in the
|
||||||
// the public config, pull them forward so behavior doesn't silently
|
// private config and hasn't moved them over to the public config, pull
|
||||||
// change out from under them.
|
// them forward so behavior doesn't silently change out from under them.
|
||||||
private migrateDeprecatedAcmeConfig(privateEnvironment: any) {
|
private migrateDeprecatedConfig(privateEnvironment: any) {
|
||||||
const publicEnvironment: any = readPublicConfigFile();
|
const publicEnvironment: any = readPublicConfigFile();
|
||||||
const rawConfig: any = config.getRawConfig();
|
const rawConfig: any = config.getRawConfig();
|
||||||
|
|
||||||
@@ -182,6 +182,20 @@ export class PrivateConfig {
|
|||||||
);
|
);
|
||||||
rawConfig.acme = this.rawPrivateConfig.acme;
|
rawConfig.acme = this.rawPrivateConfig.acme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
privateEnvironment?.flags?.disable_private_http_placeholder !==
|
||||||
|
undefined &&
|
||||||
|
publicEnvironment?.flags?.disable_private_http_placeholder ===
|
||||||
|
undefined
|
||||||
|
) {
|
||||||
|
logger.warn(
|
||||||
|
"`flags.disable_private_http_placeholder` is deprecated in the private config file and has moved to the public config file. Using the value from the private config file for now, but please move it to the public config."
|
||||||
|
);
|
||||||
|
rawConfig.flags = rawConfig.flags ?? {};
|
||||||
|
rawConfig.flags.disable_private_http_placeholder =
|
||||||
|
this.rawPrivateConfig.flags.disable_private_http_placeholder;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -115,10 +115,13 @@ export const privateConfigSchema = z
|
|||||||
// any value set here is migrated into the public config at
|
// any value set here is migrated into the public config at
|
||||||
// startup by PrivateConfig (server/private/lib/config.ts).
|
// startup by PrivateConfig (server/private/lib/config.ts).
|
||||||
enable_acme_cert_sync: z.boolean().optional(),
|
enable_acme_cert_sync: z.boolean().optional(),
|
||||||
disable_private_http_placeholder: z
|
// @deprecated Moved to the public config file as
|
||||||
.boolean()
|
// `flags.disable_private_http_placeholder`
|
||||||
.optional()
|
// (server/lib/readConfigFile.ts). Kept here only so existing
|
||||||
.default(false)
|
// private config files keep parsing; any value set here is
|
||||||
|
// migrated into the public config at startup by PrivateConfig
|
||||||
|
// (server/private/lib/config.ts).
|
||||||
|
disable_private_http_placeholder: z.boolean().optional()
|
||||||
})
|
})
|
||||||
.optional()
|
.optional()
|
||||||
.prefault({}),
|
.prefault({}),
|
||||||
|
|||||||
@@ -329,8 +329,7 @@ export async function getTraefikConfig(
|
|||||||
}[] = [];
|
}[] = [];
|
||||||
if (
|
if (
|
||||||
build == "enterprise" &&
|
build == "enterprise" &&
|
||||||
!privateConfig.getRawPrivateConfig().flags
|
!config.getRawConfig().flags?.disable_private_http_placeholder
|
||||||
.disable_private_http_placeholder
|
|
||||||
) {
|
) {
|
||||||
// we dont want to do this on the cloud
|
// we dont want to do this on the cloud
|
||||||
// Query siteResources in HTTP mode with SSL enabled and aliases - cert generation / HTTPS edge
|
// Query siteResources in HTTP mode with SSL enabled and aliases - cert generation / HTTPS edge
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ import { getPrivateResourceSettingsHref } from "@app/lib/launcherResourceAdminHr
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { useStoredPageSize } from "@app/hooks/useStoredPageSize";
|
import { useStoredPageSize } from "@app/hooks/useStoredPageSize";
|
||||||
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
|
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
|
||||||
|
import LogRetentionWarning from "@app/components/LogRetentionWarning";
|
||||||
|
import { useOrgContext } from "@app/hooks/useOrgContext";
|
||||||
import { usePaidStatus } from "@app/hooks/usePaidStatus";
|
import { usePaidStatus } from "@app/hooks/usePaidStatus";
|
||||||
import { tierMatrix } from "@server/lib/billing/tierMatrix";
|
import { tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||||
import { logQueries } from "@app/lib/queries";
|
import { logQueries } from "@app/lib/queries";
|
||||||
@@ -32,6 +34,7 @@ export default function GeneralPage() {
|
|||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
const { orgId } = useParams();
|
const { orgId } = useParams();
|
||||||
|
|
||||||
|
const { org } = useOrgContext();
|
||||||
const { isPaidUser } = usePaidStatus();
|
const { isPaidUser } = usePaidStatus();
|
||||||
|
|
||||||
const [isExporting, startTransition] = useTransition();
|
const [isExporting, startTransition] = useTransition();
|
||||||
@@ -529,6 +532,13 @@ export default function GeneralPage() {
|
|||||||
|
|
||||||
<PaidFeaturesAlert tiers={tierMatrix.accessLogs} />
|
<PaidFeaturesAlert tiers={tierMatrix.accessLogs} />
|
||||||
|
|
||||||
|
{org.org.settingsLogRetentionDaysAccess === 0 && (
|
||||||
|
<LogRetentionWarning
|
||||||
|
orgId={orgId as string}
|
||||||
|
logTypeLabel={t("accessLogs")}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<LogDataTable
|
<LogDataTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={rows}
|
data={rows}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ import { ColumnFilterButton } from "@app/components/ColumnFilterButton";
|
|||||||
import { DateTimeValue } from "@app/components/DateTimePicker";
|
import { DateTimeValue } from "@app/components/DateTimePicker";
|
||||||
import { LogDataTable } from "@app/components/LogDataTable";
|
import { LogDataTable } from "@app/components/LogDataTable";
|
||||||
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
|
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
|
||||||
|
import LogRetentionWarning from "@app/components/LogRetentionWarning";
|
||||||
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
||||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||||
|
import { useOrgContext } from "@app/hooks/useOrgContext";
|
||||||
import { usePaidStatus } from "@app/hooks/usePaidStatus";
|
import { usePaidStatus } from "@app/hooks/usePaidStatus";
|
||||||
import { useStoredPageSize } from "@app/hooks/useStoredPageSize";
|
import { useStoredPageSize } from "@app/hooks/useStoredPageSize";
|
||||||
import { toast } from "@app/hooks/useToast";
|
import { toast } from "@app/hooks/useToast";
|
||||||
@@ -29,6 +31,7 @@ export default function GeneralPage() {
|
|||||||
const { orgId } = useParams();
|
const { orgId } = useParams();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
|
|
||||||
|
const { org } = useOrgContext();
|
||||||
const { isPaidUser } = usePaidStatus();
|
const { isPaidUser } = usePaidStatus();
|
||||||
|
|
||||||
const [isExporting, startTransition] = useTransition();
|
const [isExporting, startTransition] = useTransition();
|
||||||
@@ -359,6 +362,13 @@ export default function GeneralPage() {
|
|||||||
|
|
||||||
<PaidFeaturesAlert tiers={tierMatrix.actionLogs} />
|
<PaidFeaturesAlert tiers={tierMatrix.actionLogs} />
|
||||||
|
|
||||||
|
{org.org.settingsLogRetentionDaysAction === 0 && (
|
||||||
|
<LogRetentionWarning
|
||||||
|
orgId={orgId as string}
|
||||||
|
logTypeLabel={t("actionLogs")}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<LogDataTable
|
<LogDataTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={rows}
|
data={rows}
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ import { ColumnFilterButton } from "@app/components/ColumnFilterButton";
|
|||||||
import { DateTimeValue } from "@app/components/DateTimePicker";
|
import { DateTimeValue } from "@app/components/DateTimePicker";
|
||||||
import { LogDataTable } from "@app/components/LogDataTable";
|
import { LogDataTable } from "@app/components/LogDataTable";
|
||||||
import { AiSessionChatView } from "@app/components/AiSessionChatView";
|
import { AiSessionChatView } from "@app/components/AiSessionChatView";
|
||||||
|
import LogRetentionWarning from "@app/components/LogRetentionWarning";
|
||||||
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
||||||
import { Button } from "@app/components/ui/button";
|
import { Button } from "@app/components/ui/button";
|
||||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||||
|
import { useOrgContext } from "@app/hooks/useOrgContext";
|
||||||
import { toast } from "@app/hooks/useToast";
|
import { toast } from "@app/hooks/useToast";
|
||||||
import { createApiClient } from "@app/lib/api";
|
import { createApiClient } from "@app/lib/api";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
@@ -41,6 +43,8 @@ export default function AiSessionLogsPage() {
|
|||||||
const { orgId } = useParams();
|
const { orgId } = useParams();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
|
|
||||||
|
const { org } = useOrgContext();
|
||||||
|
|
||||||
const [isExporting, startTransition] = useTransition();
|
const [isExporting, startTransition] = useTransition();
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState<number>(0);
|
const [currentPage, setCurrentPage] = useState<number>(0);
|
||||||
@@ -641,6 +645,13 @@ export default function AiSessionLogsPage() {
|
|||||||
description={t("aiSessionLogsDescription")}
|
description={t("aiSessionLogsDescription")}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{org.org.settingsLogRetentionDaysAISessions === 0 && (
|
||||||
|
<LogRetentionWarning
|
||||||
|
orgId={orgId as string}
|
||||||
|
logTypeLabel={t("aiSessionLogs")}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<LogDataTable
|
<LogDataTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={rows}
|
data={rows}
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ import { ColumnFilterButton } from "@app/components/ColumnFilterButton";
|
|||||||
import { DateTimeValue } from "@app/components/DateTimePicker";
|
import { DateTimeValue } from "@app/components/DateTimePicker";
|
||||||
import { LogDataTable } from "@app/components/LogDataTable";
|
import { LogDataTable } from "@app/components/LogDataTable";
|
||||||
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
|
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
|
||||||
|
import LogRetentionWarning from "@app/components/LogRetentionWarning";
|
||||||
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
||||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||||
|
import { useOrgContext } from "@app/hooks/useOrgContext";
|
||||||
import { usePaidStatus } from "@app/hooks/usePaidStatus";
|
import { usePaidStatus } from "@app/hooks/usePaidStatus";
|
||||||
import { useStoredPageSize } from "@app/hooks/useStoredPageSize";
|
import { useStoredPageSize } from "@app/hooks/useStoredPageSize";
|
||||||
import { toast } from "@app/hooks/useToast";
|
import { toast } from "@app/hooks/useToast";
|
||||||
@@ -47,6 +49,7 @@ export default function ConnectionLogsPage() {
|
|||||||
const { orgId } = useParams();
|
const { orgId } = useParams();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
|
|
||||||
|
const { org } = useOrgContext();
|
||||||
const { isPaidUser } = usePaidStatus();
|
const { isPaidUser } = usePaidStatus();
|
||||||
|
|
||||||
const [isExporting, startTransition] = useTransition();
|
const [isExporting, startTransition] = useTransition();
|
||||||
@@ -582,6 +585,13 @@ export default function ConnectionLogsPage() {
|
|||||||
|
|
||||||
<PaidFeaturesAlert tiers={tierMatrix.connectionLogs} />
|
<PaidFeaturesAlert tiers={tierMatrix.connectionLogs} />
|
||||||
|
|
||||||
|
{org.org.settingsLogRetentionDaysConnection === 0 && (
|
||||||
|
<LogRetentionWarning
|
||||||
|
orgId={orgId as string}
|
||||||
|
logTypeLabel={t("connectionLogs")}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<LogDataTable
|
<LogDataTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={rows}
|
data={rows}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { verifySession } from "@app/lib/auth/verifySession";
|
import { verifySession } from "@app/lib/auth/verifySession";
|
||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
import { cache } from "react";
|
import { cache } from "react";
|
||||||
|
import OrgProvider from "@app/providers/OrgProvider";
|
||||||
|
import { getCachedOrg } from "@app/lib/api/getCachedOrg";
|
||||||
|
|
||||||
type GeneralSettingsProps = {
|
type GeneralSettingsProps = {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
@@ -11,6 +13,8 @@ export default async function GeneralSettingsPage({
|
|||||||
children,
|
children,
|
||||||
params
|
params
|
||||||
}: GeneralSettingsProps) {
|
}: GeneralSettingsProps) {
|
||||||
|
const { orgId } = await params;
|
||||||
|
|
||||||
const getUser = cache(verifySession);
|
const getUser = cache(verifySession);
|
||||||
const user = await getUser();
|
const user = await getUser();
|
||||||
|
|
||||||
@@ -18,5 +22,13 @@ export default async function GeneralSettingsPage({
|
|||||||
redirect(`/`);
|
redirect(`/`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return children;
|
let org = null;
|
||||||
|
try {
|
||||||
|
const res = await getCachedOrg(orgId);
|
||||||
|
org = res.data.data;
|
||||||
|
} catch {
|
||||||
|
redirect(`/${orgId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <OrgProvider org={org}>{children}</OrgProvider>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
import { ColumnFilter } from "@app/components/ColumnFilter";
|
import { ColumnFilter } from "@app/components/ColumnFilter";
|
||||||
import { DateTimeValue } from "@app/components/DateTimePicker";
|
import { DateTimeValue } from "@app/components/DateTimePicker";
|
||||||
import { LogDataTable } from "@app/components/LogDataTable";
|
import { LogDataTable } from "@app/components/LogDataTable";
|
||||||
|
import LogRetentionWarning from "@app/components/LogRetentionWarning";
|
||||||
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
||||||
import { Button } from "@app/components/ui/button";
|
import { Button } from "@app/components/ui/button";
|
||||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||||
|
import { useOrgContext } from "@app/hooks/useOrgContext";
|
||||||
import { toast } from "@app/hooks/useToast";
|
import { toast } from "@app/hooks/useToast";
|
||||||
import { createApiClient } from "@app/lib/api";
|
import { createApiClient } from "@app/lib/api";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
@@ -29,6 +31,8 @@ export default function GeneralPage() {
|
|||||||
const { orgId } = useParams();
|
const { orgId } = useParams();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
|
|
||||||
|
const { org } = useOrgContext();
|
||||||
|
|
||||||
const [isExporting, startTransition] = useTransition();
|
const [isExporting, startTransition] = useTransition();
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState<number>(0);
|
const [currentPage, setCurrentPage] = useState<number>(0);
|
||||||
@@ -714,6 +718,13 @@ export default function GeneralPage() {
|
|||||||
description={t("requestLogsDescription")}
|
description={t("requestLogsDescription")}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{org.org.settingsLogRetentionDaysRequest === 0 && (
|
||||||
|
<LogRetentionWarning
|
||||||
|
orgId={orgId as string}
|
||||||
|
logTypeLabel={t("requestLogs")}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<LogDataTable
|
<LogDataTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={rows}
|
data={rows}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import ActionBanner from "@app/components/ActionBanner";
|
||||||
|
import { Button } from "@app/components/ui/button";
|
||||||
|
import { ArrowRight, ShieldAlert } from "lucide-react";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
type LogRetentionWarningProps = {
|
||||||
|
orgId: string;
|
||||||
|
logTypeLabel: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function LogRetentionWarning({
|
||||||
|
orgId,
|
||||||
|
logTypeLabel
|
||||||
|
}: LogRetentionWarningProps) {
|
||||||
|
const t = useTranslations();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ActionBanner
|
||||||
|
variant="warning"
|
||||||
|
title={t("logRetentionDisabledWarningTitle")}
|
||||||
|
titleIcon={<ShieldAlert className="w-5 h-5" />}
|
||||||
|
description={t("logRetentionDisabledWarningDescription", {
|
||||||
|
logType: logTypeLabel
|
||||||
|
})}
|
||||||
|
actions={
|
||||||
|
<Link href={`/${orgId}/settings/general/security`}>
|
||||||
|
<Button variant="outline" className="gap-2">
|
||||||
|
{t("logRetentionDisabledWarningButton")}
|
||||||
|
<ArrowRight className="size-4" />
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LogRetentionWarning;
|
||||||
Reference in New Issue
Block a user