Skip to content

Commit 4025287

Browse files
Frontend: Soft limits- add warnings for large audits to prevent resource issues
1 parent cf62bbc commit 4025287

4 files changed

Lines changed: 74 additions & 3 deletions

File tree

apps/frontend/src/components/AuditPagesInput.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import { StyledButton } from "./StyledButton";
44
import { AuditPagesInputTable } from "./AuditPagesInputTable";
55
import { StyledLabeledInput } from "./StyledLabeledInput";
66
import { Card } from "./Card";
7+
import { TbAlertTriangle } from "react-icons/tb";
78
import style from "./AuditPagesInput.module.scss";
89

10+
const URL_SOFT_LIMIT = 10_000;
11+
912
interface Page {
1013
url: string;
1114
type: "html" | "pdf";
@@ -129,6 +132,18 @@ export const AuditPagesInput: React.FC<ChildProps> = ({
129132
}));
130133
}
131134

135+
// Soft limit warning for large URL counts
136+
const totalAfterAdd = pages.length + newPages.length;
137+
if (newPages.length > 0 && totalAfterAdd >= URL_SOFT_LIMIT) {
138+
const proceed = window.confirm(
139+
`Adding these URLs will bring your total to ${totalAfterAdd.toLocaleString()} URLs. Large audits take significantly longer to scan. Continue?`
140+
);
141+
if (!proceed) {
142+
e.target.value = "";
143+
return;
144+
}
145+
}
146+
132147
// Add all valid URLs to the pages
133148
if (newPages.length > 0) {
134149
setPages(prev => [...prev, ...newPages]);
@@ -390,6 +405,14 @@ export const AuditPagesInput: React.FC<ChildProps> = ({
390405
isShared={isShared}
391406
updatePageType={updatePageType}
392407
/>
408+
{pages.length >= URL_SOFT_LIMIT && (
409+
<Card variant="short-error">
410+
<TbAlertTriangle className="icon-small" />
411+
<div className="font-small">
412+
<b>Large audit:</b> This audit has {pages.length.toLocaleString()} URLs. Large audits take significantly longer to scan.
413+
</div>
414+
</Card>
415+
)}
393416
{!isShared && (
394417
<Card variant="inset-light">
395418
<h3>Add URLs to Scan</h3>

apps/frontend/src/components/AuditRemoteCsvInput.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ import { useDebouncedCallback } from "use-debounce";
77

88
import * as API from "aws-amplify/api";
99
import { MdCheckCircle, MdError } from "react-icons/md";
10+
import { TbAlertTriangle } from "react-icons/tb";
1011
import { AuditPagesInputTable } from "./AuditPagesInputTable";
1112

13+
const URL_SOFT_LIMIT = 10_000;
14+
1215
interface Page {
1316
url: string;
1417
type: "html" | "pdf";
@@ -162,6 +165,14 @@ export const AuditRemoteCsvInput: React.FC<ChildProps> = ({ csvUrl, setCsvUrl, v
162165
{validCsv &&
163166
<Card variant="short-success"><MdCheckCircle className="icon-small" /><div className="font-small"><b>CSV Found!</b></div></Card>
164167
}
168+
{validCsv && pages.length >= URL_SOFT_LIMIT && (
169+
<Card variant="short-error">
170+
<TbAlertTriangle className="icon-small" />
171+
<div className="font-small">
172+
<b>Large audit:</b> This CSV contains {pages.length.toLocaleString()} URLs. Large audits take significantly longer to scan.
173+
</div>
174+
</Card>
175+
)}
165176
{pages.length > 0 &&
166177
<AuditPagesInputTable
167178
pages={pages}

apps/frontend/src/routes/Audit.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,15 @@ export const Audit = () => {
299299
}
300300
};
301301

302+
const URL_SOFT_LIMIT = 10_000;
303+
302304
const updateAuditInterval = async (newValue: string) => {
305+
if (newValue === "Daily" && pages.length >= URL_SOFT_LIMIT) {
306+
const proceed = window.confirm(
307+
`Setting daily scans for an audit with ${pages.length.toLocaleString()} URLs will use significant resources. Continue?`
308+
);
309+
if (!proceed) return;
310+
}
303311
console.log("Updating audit interval:", newValue);
304312
const updatedInterval = await apiClient.graphql({
305313
query: `mutation ($audit_id:uuid, $interval: String) {

apps/frontend/src/routes/BuildAudit.tsx

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { useState, FormEvent } from "react";
22
import { Link, useNavigate } from "react-router-dom";
3+
import { useQuery } from "@tanstack/react-query";
34
import { useUser } from "../queries";
45
import * as API from "aws-amplify/api";
56
import {
@@ -13,7 +14,7 @@ import { createLog } from "#src/utils/createLog.ts";
1314
import { StyledLabeledInput } from "#src/components/StyledLabeledInput.tsx";
1415
import { Card } from "#src/components/Card.tsx";
1516
import { CgOptions } from "react-icons/cg";
16-
import { TbList, TbMail } from "react-icons/tb";
17+
import { TbAlertTriangle, TbMail } from "react-icons/tb";
1718
import { StyledButton } from "#src/components/StyledButton.tsx";
1819
import { LuClipboardCheck, LuClipboardPaste, LuImport } from "react-icons/lu";
1920
import styles from "./BuildAudit.module.scss";
@@ -27,6 +28,10 @@ interface Page {
2728
type: "html" | "pdf";
2829
}
2930

31+
const apiClient = API.generateClient();
32+
const URL_SOFT_LIMIT = 10_000;
33+
const AUDIT_SOFT_LIMIT = 10_000;
34+
3035
export const BuildAudit = () => {
3136
const navigate = useNavigate();
3237
const { setAnnounceMessage } = useGlobalStore();
@@ -38,9 +43,20 @@ export const BuildAudit = () => {
3843
const [auditNameValid, setAuditNameValid] = useState(false);
3944
const [isSaving, setIsSaving] = useState(false);
4045
const [isSavingAndRunning, setIsSavingAndRunning] = useState(false);
46+
const [scanFrequency, setScanFrequency] = useState("Manually");
4147

4248
const [validRemoteCsv, setValidRemoteCsv] = useState(false);
4349

50+
const { data: auditCount } = useQuery({
51+
queryKey: ["auditCount"],
52+
queryFn: async () => {
53+
const result = (await apiClient.graphql({
54+
query: `{ audits_aggregate(where: {interval: {_neq: "Quick Scan"}}) { aggregate { count } } }`,
55+
})) as any;
56+
return result?.data?.audits_aggregate?.aggregate?.count ?? 0;
57+
},
58+
});
59+
4460
const defaultEmailList = {
4561
emails: [
4662
/* {
@@ -152,6 +168,14 @@ export const BuildAudit = () => {
152168
{/* <Link to="..">← Go Back</Link>
153169
*/}
154170
<h1 className="initial-focus-element">Audit Builder</h1>
171+
{auditCount >= AUDIT_SOFT_LIMIT && (
172+
<Card variant="short-error">
173+
<TbAlertTriangle className="icon-small" />
174+
<div className="font-small">
175+
<b>Large number of audits:</b> Your account has {auditCount.toLocaleString()} audits. Having a large number of audits may affect system performance.
176+
</div>
177+
</Card>
178+
)}
155179
<form onSubmit={saveAndRunAudit}>
156180
<div className="cards-38-62">
157181
<Card variant="light">
@@ -178,15 +202,20 @@ export const BuildAudit = () => {
178202
id="scanFrequency"
179203
name="scanFrequency"
180204
className={styles["input-element"]}
205+
value={scanFrequency}
206+
onChange={(e) => setScanFrequency(e.target.value)}
181207
>
182208
<option>Manually</option>
183209
<option>Daily</option>
184210
<option>Weekly</option>
185211
<option>Monthly</option>
186-
{/*
187-
<option>On Monitor Update</option> */}
188212
</select>
189213
</StyledLabeledInput>
214+
{scanFrequency === "Daily" && pages.length >= URL_SOFT_LIMIT && (
215+
<p className="font-small" style={{ color: "#b45309", display: "flex", alignItems: "center", gap: "4px" }}>
216+
<TbAlertTriangle /> Daily scans for audits with {pages.length.toLocaleString()} URLs will use significant resources.
217+
</p>
218+
)}
190219
</Card>
191220
<Card variant="light">
192221
<h2>

0 commit comments

Comments
 (0)