diff --git a/ui/.eslintrc.cjs b/ui/.eslintrc.cjs
index 6f1426da12..8c32ae0804 100644
--- a/ui/.eslintrc.cjs
+++ b/ui/.eslintrc.cjs
@@ -12,6 +12,7 @@ module.exports = {
"plugin:jsx-a11y/recommended",
"eslint-config-prettier",
"prettier",
+ "next/core-web-vitals",
],
parserOptions: {
ecmaVersion: "latest",
@@ -37,7 +38,14 @@ module.exports = {
"eol-last": ["error", "always"],
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
- "jsx-a11y/anchor-is-valid": "error",
+ "jsx-a11y/anchor-is-valid": [
+ "error",
+ {
+ components: ["Link"],
+ specialLink: ["hrefLeft", "hrefRight"],
+ aspects: ["invalidHref", "preferButton"],
+ },
+ ],
"jsx-a11y/alt-text": "error",
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
},
diff --git a/ui/actions/providers/providers.ts b/ui/actions/providers/providers.ts
index cd9e021696..3b2ea126d3 100644
--- a/ui/actions/providers/providers.ts
+++ b/ui/actions/providers/providers.ts
@@ -42,6 +42,7 @@ export const getProviders = async ({
revalidatePath("/providers");
return parsedData;
} catch (error) {
+ // eslint-disable-next-line no-console
console.error("Error fetching providers:", error);
return undefined;
}
diff --git a/ui/actions/services/services.ts b/ui/actions/services/services.ts
index c4ab342f01..cfd295e1cb 100644
--- a/ui/actions/services/services.ts
+++ b/ui/actions/services/services.ts
@@ -1,13 +1,10 @@
"use server";
import { revalidatePath } from "next/cache";
-import { redirect } from "next/navigation";
-import { parse } from "path";
import { auth } from "@/auth.config";
-import { getErrorMessage, parseStringify } from "@/lib";
-export const getServices = async ({}) => {
+export const getServices = async () => {
const session = await auth();
const keyServer = process.env.API_BASE_URL;
@@ -90,6 +87,7 @@ export const getServices = async ({}) => {
fail_findings: failFindings,
});
} catch (error) {
+ // eslint-disable-next-line no-console
console.error(`Error fetching data for service ${service.id}:`, error);
}
}
diff --git a/ui/actions/users/users.ts b/ui/actions/users/users.ts
index 3d06ccc801..ce80221da3 100644
--- a/ui/actions/users/users.ts
+++ b/ui/actions/users/users.ts
@@ -42,6 +42,7 @@ export const getUsers = async ({
revalidatePath("/users");
return parsedData;
} catch (error) {
+ // eslint-disable-next-line no-console
console.error("Error fetching users:", error);
return undefined;
}
@@ -200,6 +201,7 @@ export const getProfileInfo = async () => {
revalidatePath("/profile");
return parsedData;
} catch (error) {
+ // eslint-disable-next-line no-console
console.error("Error fetching profile:", error);
return undefined;
}
diff --git a/ui/app/(prowler)/compliance/page.tsx b/ui/app/(prowler)/compliance/page.tsx
index 108433a7c7..ce5fe18e5d 100644
--- a/ui/app/(prowler)/compliance/page.tsx
+++ b/ui/app/(prowler)/compliance/page.tsx
@@ -1,3 +1,5 @@
+export const dynamic = "force-dynamic";
+
import { Spacer } from "@nextui-org/react";
import { Suspense } from "react";
diff --git a/ui/app/(prowler)/error.tsx b/ui/app/(prowler)/error.tsx
index 980e681220..d5083d9d33 100644
--- a/ui/app/(prowler)/error.tsx
+++ b/ui/app/(prowler)/error.tsx
@@ -24,11 +24,10 @@ export default function Error({
An unexpected error occurred
- We're sorry for the inconvenience. Please try again or contact support
- if the problem persists.
+ We're sorry for the inconvenience. Please try again or contact
+ support if the problem persists.
-
- {" "}
+
Go to the homepage
diff --git a/ui/app/(prowler)/providers/page.tsx b/ui/app/(prowler)/providers/page.tsx
index b41c049202..3851c75f0d 100644
--- a/ui/app/(prowler)/providers/page.tsx
+++ b/ui/app/(prowler)/providers/page.tsx
@@ -72,15 +72,15 @@ const SSRDataTable = async ({
return acc;
}, {}) || {};
- const enrichedProviders = providersData?.data.map(
- (provider: ProviderProps) => {
- const groupNames = provider.relationships.provider_groups.data.map(
- (group: { id: string }) =>
- providerGroupDict[group.id] || "Unknown Group",
- );
+ const enrichedProviders =
+ providersData?.data?.map((provider: ProviderProps) => {
+ const groupNames =
+ provider.relationships?.provider_groups?.data?.map(
+ (group: { id: string }) =>
+ providerGroupDict[group.id] || "Unknown Group",
+ ) || [];
return { ...provider, groupNames };
- },
- );
+ }) || [];
return (
}>
-
+
>
);
}
-const SSRServiceGrid = async ({
- searchParams,
-}: {
- searchParams: SearchParamsProps;
-}) => {
- const servicesData = await getServices(searchParams);
- const [services] = await Promise.all([servicesData]);
+const SSRServiceGrid = async () => {
+ const services = await getServices();
return (
diff --git a/ui/components/compliance/data-compliance/select-scan-compliance-data.tsx b/ui/components/compliance/data-compliance/select-scan-compliance-data.tsx
index 5ebc36515d..6bbfd3d4e0 100644
--- a/ui/components/compliance/data-compliance/select-scan-compliance-data.tsx
+++ b/ui/components/compliance/data-compliance/select-scan-compliance-data.tsx
@@ -15,6 +15,9 @@ export const SelectScanComplianceData = ({
+ return (
+
+ ) : (
+ (item.startContent ?? null)
+ )
+ }
+ title={isCompact || isNestType ? null : item.title}
+ >
+ {isCompact ? (
+
+
+ {item.icon ? (
+
) : (
(item.startContent ?? null)
- )
- }
- >
- {item.items && item.items?.length > 0 ? (
-
- {item.items.map(renderItem)}
-
- ) : (
- renderItem(item)
- )}
-
-
- ) : null}
-
- );
- },
- [isCompact, hideEndContent, iconClassName, items],
- );
+ )}
+
+
+ ) : null}
+ {!isCompact && isNestType ? (
+
+
+
+
+ {item.title}
+
+
+ ) : (
+ (item.startContent ?? null)
+ )
+ }
+ >
+ {item.items && item.items?.length > 0 ? (
+
+ {item.items.map(renderItem)}
+
+ ) : (
+ renderItem(item)
+ )}
+
+
+ ) : null}
+
+ );
+ },
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ [isCompact, hideEndContent, iconClassName],
+ );
- const renderItem = React.useCallback(
- (item: SidebarItem) => {
+ const renderItem: (item: SidebarItem) => JSX.Element = React.useCallback(
+ (item) => {
const isNestType =
item.items &&
item.items?.length > 0 &&
@@ -261,7 +263,7 @@ const Sidebar = React.forwardRef(
);
},
- [isCompact, hideEndContent, iconClassName, itemClasses?.base],
+ [isCompact, hideEndContent, iconClassName, renderNestItem],
);
return (
diff --git a/ui/components/ui/table/data-table-pagination.tsx b/ui/components/ui/table/data-table-pagination.tsx
index dfcec441a3..c81e272100 100644
--- a/ui/components/ui/table/data-table-pagination.tsx
+++ b/ui/components/ui/table/data-table-pagination.tsx
@@ -18,10 +18,11 @@ interface DataTablePaginationProps {
}
export function DataTablePagination({ metadata }: DataTablePaginationProps) {
- if (!metadata) return null;
const pathname = usePathname();
const searchParams = useSearchParams();
+ if (!metadata) return null;
+
const { currentPage, totalPages, totalEntries } = getPaginationInfo(metadata);
const createPageUrl = (pageNumber: number | string) => {
diff --git a/ui/components/users/forms/edit-form.tsx b/ui/components/users/forms/edit-form.tsx
index 6c5a8c2d77..5911044b0f 100644
--- a/ui/components/users/forms/edit-form.tsx
+++ b/ui/components/users/forms/edit-form.tsx
@@ -178,6 +178,9 @@ export const EditForm = ({
label="Role"
labelPlacement="outside"
placeholder="Select a role"
+ classNames={{
+ selectorIcon: "right-2",
+ }}
variant="bordered"
selectedKeys={[field.value || ""]}
onSelectionChange={(selected) => {
diff --git a/ui/hooks/useLocalStorage.ts b/ui/hooks/useLocalStorage.ts
index 0d5e70a957..8e86347b87 100644
--- a/ui/hooks/useLocalStorage.ts
+++ b/ui/hooks/useLocalStorage.ts
@@ -21,6 +21,7 @@ export const useLocalStorage = (
setState(JSON.parse(value));
}
} catch (error) {
+ // eslint-disable-next-line no-console
console.error(error);
}
}, [key]);
@@ -38,6 +39,7 @@ export const useLocalStorage = (
window.localStorage.setItem(key, JSON.stringify(valueToStore));
setState(valueToStore);
} catch (error) {
+ // eslint-disable-next-line no-console
console.error(error);
}
};
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 3643260973..7568d27969 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -44,6 +44,7 @@
"recharts": "^2.13.0-alpha.4",
"server-only": "^0.0.1",
"shadcn-ui": "^0.2.3",
+ "sharp": "^0.33.5",
"tailwind-merge": "^2.5.3",
"tailwindcss-animate": "^1.0.7",
"uuid": "^10.0.0",
@@ -61,7 +62,7 @@
"@typescript-eslint/parser": "^7.10.0",
"autoprefixer": "10.4.19",
"eslint": "^8.56.0",
- "eslint-config-next": "14.2.1",
+ "eslint-config-next": "^14.2.23",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.9.0",
@@ -247,6 +248,16 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@emnapi/runtime": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz",
+ "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -489,6 +500,367 @@
"integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==",
"dev": true
},
+ "node_modules/@img/sharp-darwin-arm64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz",
+ "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-arm64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-darwin-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz",
+ "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz",
+ "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz",
+ "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz",
+ "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz",
+ "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz",
+ "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz",
+ "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz",
+ "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz",
+ "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz",
+ "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.0.5"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz",
+ "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-s390x": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz",
+ "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz",
+ "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz",
+ "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz",
+ "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-wasm32": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz",
+ "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.2.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-ia32": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz",
+ "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz",
+ "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
"node_modules/@internationalized/date": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.6.0.tgz",
@@ -615,6 +987,16 @@
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.22.tgz",
"integrity": "sha512-EQ6y1QeNQglNmNIXvwP/Bb+lf7n9WtgcWvtoFsHquVLCJUuxRs+6SfZ5EK0/EqkkLex4RrDySvKgKNN7PXip7Q=="
},
+ "node_modules/@next/eslint-plugin-next": {
+ "version": "14.2.23",
+ "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.23.tgz",
+ "integrity": "sha512-efRC7m39GoiU1fXZRgGySqYbQi6ZyLkuGlvGst7IwkTTczehQTJA/7PoMg4MMjUZvZEGpiSEu+oJBAjPawiC3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "glob": "10.3.10"
+ }
+ },
"node_modules/@next/swc-darwin-arm64": {
"version": "14.2.22",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.22.tgz",
@@ -7242,9 +7624,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001640",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz",
- "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==",
+ "version": "1.0.30001692",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz",
+ "integrity": "sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==",
"funding": [
{
"type": "opencollective",
@@ -7258,7 +7640,8 @@
"type": "github",
"url": "https://github.com/sponsors/ai"
}
- ]
+ ],
+ "license": "CC-BY-4.0"
},
"node_modules/chalk": {
"version": "4.1.2",
@@ -8252,6 +8635,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/detect-libc": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
+ "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/detect-node-es": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
@@ -8605,14 +8997,16 @@
}
},
"node_modules/eslint-config-next": {
- "version": "14.2.1",
- "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.2.1.tgz",
- "integrity": "sha512-BgD0kPCWMlqoItRf3xe9fG0MqwObKfVch+f2ccwDpZiCJA8ghkz2wrASH+bI6nLZzGcOJOpMm1v1Q1euhfpt4Q==",
+ "version": "14.2.23",
+ "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.2.23.tgz",
+ "integrity": "sha512-qtWJzOsDZxnLtXLNtnVjbutHmnEp6QTTSZBTlTCge/Wy0AsUaq8nwR91dBcZZvFg3eY3zKFPBhUkLMHu3Qpauw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@next/eslint-plugin-next": "14.2.1",
+ "@next/eslint-plugin-next": "14.2.23",
"@rushstack/eslint-patch": "^1.3.3",
- "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0",
+ "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0",
+ "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0",
"eslint-import-resolver-node": "^0.3.6",
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-import": "^2.28.1",
@@ -8630,133 +9024,6 @@
}
}
},
- "node_modules/eslint-config-next/node_modules/@next/eslint-plugin-next": {
- "version": "14.2.1",
- "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.1.tgz",
- "integrity": "sha512-Fp+mthEBjkn8r9qd6o4JgxKp0IDEzW0VYHD8ZC05xS5/lFNwHKuOdr2kVhWG7BQCO9L6eeepshM1Wbs2T+LgSg==",
- "dev": true,
- "dependencies": {
- "glob": "10.3.10"
- }
- },
- "node_modules/eslint-config-next/node_modules/@typescript-eslint/parser": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz",
- "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/scope-manager": "7.2.0",
- "@typescript-eslint/types": "7.2.0",
- "@typescript-eslint/typescript-estree": "7.2.0",
- "@typescript-eslint/visitor-keys": "7.2.0",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.56.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/eslint-config-next/node_modules/@typescript-eslint/scope-manager": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz",
- "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/types": "7.2.0",
- "@typescript-eslint/visitor-keys": "7.2.0"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/eslint-config-next/node_modules/@typescript-eslint/types": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz",
- "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==",
- "dev": true,
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/eslint-config-next/node_modules/@typescript-eslint/typescript-estree": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz",
- "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/types": "7.2.0",
- "@typescript-eslint/visitor-keys": "7.2.0",
- "debug": "^4.3.4",
- "globby": "^11.1.0",
- "is-glob": "^4.0.3",
- "minimatch": "9.0.3",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/eslint-config-next/node_modules/@typescript-eslint/visitor-keys": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz",
- "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/types": "7.2.0",
- "eslint-visitor-keys": "^3.4.1"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/eslint-config-next/node_modules/minimatch": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
- "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/eslint-config-prettier": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
@@ -12737,10 +13004,10 @@
}
},
"node_modules/semver": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
- "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
- "dev": true,
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -12898,6 +13165,45 @@
"node": ">=6"
}
},
+ "node_modules/sharp": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz",
+ "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "color": "^4.2.3",
+ "detect-libc": "^2.0.3",
+ "semver": "^7.6.3"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "0.33.5",
+ "@img/sharp-darwin-x64": "0.33.5",
+ "@img/sharp-libvips-darwin-arm64": "1.0.4",
+ "@img/sharp-libvips-darwin-x64": "1.0.4",
+ "@img/sharp-libvips-linux-arm": "1.0.5",
+ "@img/sharp-libvips-linux-arm64": "1.0.4",
+ "@img/sharp-libvips-linux-s390x": "1.0.4",
+ "@img/sharp-libvips-linux-x64": "1.0.4",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.0.4",
+ "@img/sharp-libvips-linuxmusl-x64": "1.0.4",
+ "@img/sharp-linux-arm": "0.33.5",
+ "@img/sharp-linux-arm64": "0.33.5",
+ "@img/sharp-linux-s390x": "0.33.5",
+ "@img/sharp-linux-x64": "0.33.5",
+ "@img/sharp-linuxmusl-arm64": "0.33.5",
+ "@img/sharp-linuxmusl-x64": "0.33.5",
+ "@img/sharp-wasm32": "0.33.5",
+ "@img/sharp-win32-ia32": "0.33.5",
+ "@img/sharp-win32-x64": "0.33.5"
+ }
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
diff --git a/ui/package.json b/ui/package.json
index fecdcafd80..f32492f4ef 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -36,6 +36,7 @@
"recharts": "^2.13.0-alpha.4",
"server-only": "^0.0.1",
"shadcn-ui": "^0.2.3",
+ "sharp": "^0.33.5",
"tailwind-merge": "^2.5.3",
"tailwindcss-animate": "^1.0.7",
"uuid": "^10.0.0",
@@ -53,7 +54,7 @@
"@typescript-eslint/parser": "^7.10.0",
"autoprefixer": "10.4.19",
"eslint": "^8.56.0",
- "eslint-config-next": "14.2.1",
+ "eslint-config-next": "^14.2.23",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.9.0",
diff --git a/ui/styles/globals.css b/ui/styles/globals.css
index ea9b8d5b5b..3d8d40186d 100644
--- a/ui/styles/globals.css
+++ b/ui/styles/globals.css
@@ -36,4 +36,8 @@
.no-scrollbar {
scrollbar-width: none;
}
+
+ .checkbox-update {
+ @apply mr-2 bg-background;
+ }
}