34
apps/console/eslint.config.js
Normal file
34
apps/console/eslint.config.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import globals from "globals";
|
||||
import pluginJs from "@eslint/js";
|
||||
import tseslint from "typescript-eslint";
|
||||
import pluginReact from "eslint-plugin-react";
|
||||
|
||||
|
||||
/** @type {import('eslint').Linter.Config[]} */
|
||||
export default [
|
||||
{files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"]},
|
||||
{languageOptions: {
|
||||
globals: globals.browser,
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true
|
||||
}
|
||||
}
|
||||
}},
|
||||
pluginJs.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
pluginReact.configs.flat.recommended,
|
||||
{
|
||||
settings: {
|
||||
react: {
|
||||
version: "detect"
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
"react/react-in-jsx-scope": "off",
|
||||
"react/prop-types": "off",
|
||||
"@typescript-eslint/no-explicit-any": "warn",
|
||||
"react/no-unescaped-entities": "off"
|
||||
}
|
||||
}
|
||||
];
|
||||
@@ -43,6 +43,7 @@
|
||||
"@babel/preset-env": "^7.26.7",
|
||||
"@babel/preset-typescript": "^7.26.0",
|
||||
"@deanc/esbuild-plugin-postcss": "^1.0.2",
|
||||
"@eslint/js": "^9.21.0",
|
||||
"@probo/tsconfig": "^0.0.1",
|
||||
"@types/babel-core": "^6.25.10",
|
||||
"@types/node": "^22.13.0",
|
||||
@@ -54,9 +55,12 @@
|
||||
"babel-plugin-relay": "^18.2.0",
|
||||
"esbuild": "^0.25.0",
|
||||
"eslint": "^9.21.0",
|
||||
"eslint-plugin-react": "^7.37.4",
|
||||
"globals": "^16.0.0",
|
||||
"relay-compiler": "^18.2.0",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.7.3"
|
||||
"typescript": "^5.7.3",
|
||||
"typescript-eslint": "^8.25.0"
|
||||
},
|
||||
"relay": {
|
||||
"src": "src",
|
||||
|
||||
@@ -4,13 +4,7 @@ import { lazy, StrictMode, Suspense } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { HelmetProvider } from "react-helmet-async";
|
||||
import { RelayEnvironmentProvider } from "react-relay";
|
||||
import {
|
||||
BrowserRouter,
|
||||
Route,
|
||||
Routes,
|
||||
useLocation,
|
||||
Navigate,
|
||||
} from "react-router";
|
||||
import { BrowserRouter, Route, Routes, useLocation } from "react-router";
|
||||
import "App.css";
|
||||
import ErrorBoundary from "./components/ErrorBoundary";
|
||||
import ConsoleLayout from "./layouts/ConsoleLayout";
|
||||
@@ -122,11 +116,22 @@ function App() {
|
||||
element={
|
||||
<Suspense>
|
||||
<ErrorBoundaryWithLocation>
|
||||
<CreateOrganizationPage />
|
||||
<ConsoleLayout />
|
||||
</ErrorBoundaryWithLocation>
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
>
|
||||
<Route
|
||||
index
|
||||
element={
|
||||
<Suspense>
|
||||
<ErrorBoundaryWithLocation>
|
||||
<CreateOrganizationPage />
|
||||
</ErrorBoundaryWithLocation>
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
</Route>
|
||||
|
||||
{/* Organization-specific Routes */}
|
||||
<Route
|
||||
@@ -147,6 +152,16 @@ function App() {
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="create"
|
||||
element={
|
||||
<Suspense>
|
||||
<ErrorBoundaryWithLocation>
|
||||
<CreateOrganizationPage />
|
||||
</ErrorBoundaryWithLocation>
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="peoples"
|
||||
element={
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
BookOpen,
|
||||
Users,
|
||||
ToyBrick,
|
||||
Command,
|
||||
LifeBuoy,
|
||||
Send,
|
||||
Settings,
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
import { graphql, useFragment } from "react-relay";
|
||||
import { useNavigate } from "react-router";
|
||||
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -28,10 +28,7 @@ import {
|
||||
useSidebar,
|
||||
} from "@/components/ui/sidebar";
|
||||
import { useAuth } from "@/contexts/AuthContext";
|
||||
import {
|
||||
NavUser_viewer$key,
|
||||
NavUser_viewer$data,
|
||||
} from "./__generated__/NavUser_viewer.graphql";
|
||||
import { NavUser_viewer$key } from "./__generated__/NavUser_viewer.graphql";
|
||||
|
||||
export const navUserFragment = graphql`
|
||||
fragment NavUser_viewer on User {
|
||||
|
||||
@@ -38,7 +38,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
response.ok && !response.headers.get("WWW-Authenticate");
|
||||
setIsAuthenticated(authenticated);
|
||||
return authenticated;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
setIsAuthenticated(false);
|
||||
return false;
|
||||
} finally {
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
import {
|
||||
Link,
|
||||
Outlet,
|
||||
Route,
|
||||
Routes,
|
||||
useLocation,
|
||||
useParams,
|
||||
} from "react-router";
|
||||
import { Link, Outlet, Route, Routes, useParams } from "react-router";
|
||||
import { AppSidebar } from "@/components/AppSidebar";
|
||||
import React from "react";
|
||||
import {
|
||||
@@ -33,6 +26,26 @@ import { ConsoleLayoutOrganizationQuery } from "./__generated__/ConsoleLayoutOrg
|
||||
|
||||
function BreadcrumbHome({ children }: { children: React.ReactNode }) {
|
||||
const { organizationId } = useParams();
|
||||
|
||||
// If there's no organizationId, we're on the create organization page
|
||||
if (!organizationId) {
|
||||
return (
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink asChild>
|
||||
<Link to="/">Home</Link>
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Create Organization</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
);
|
||||
}
|
||||
|
||||
const data = useLazyLoadQuery<ConsoleLayoutOrganizationQuery>(
|
||||
graphql`
|
||||
query ConsoleLayoutOrganizationQuery($organizationId: ID!) {
|
||||
@@ -223,17 +236,6 @@ function BreadcrumbPeopleOverview() {
|
||||
);
|
||||
}
|
||||
|
||||
function BreadcrumbCreateOrganization() {
|
||||
return (
|
||||
<>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Create Organization</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function BreadcrumbControlOverview() {
|
||||
const { organizationId, frameworkId, controlId } = useParams();
|
||||
const data = useLazyLoadQuery<ConsoleLayoutBreadcrumbControlOverviewQuery>(
|
||||
@@ -289,6 +291,7 @@ function BreadcrumbControlOverview() {
|
||||
|
||||
export default function ConsoleLayout() {
|
||||
const { organizationId } = useParams();
|
||||
const showBreadcrumb = !!organizationId;
|
||||
|
||||
return (
|
||||
<SidebarProvider>
|
||||
@@ -299,31 +302,36 @@ export default function ConsoleLayout() {
|
||||
<SidebarTrigger className="-ml-1" />
|
||||
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||
<BreadcrumbHome>
|
||||
<Routes>
|
||||
<Route path="frameworks" element={<BreadcrumbFrameworkList />}>
|
||||
{showBreadcrumb && (
|
||||
<Routes>
|
||||
<Route
|
||||
path=":frameworkId"
|
||||
element={<BreadcrumbFrameworkOverview />}
|
||||
/>
|
||||
<Route
|
||||
path=":frameworkId/controls/:controlId"
|
||||
element={<BreadcrumbControlOverview />}
|
||||
/>
|
||||
</Route>
|
||||
<Route path="peoples" element={<BreadcrumbPeopleList />}>
|
||||
<Route
|
||||
path=":peopleId"
|
||||
element={<BreadcrumbPeopleOverview />}
|
||||
/>
|
||||
<Route path="create" element={<BreadcrumbCreatePeople />} />
|
||||
</Route>
|
||||
<Route path="vendors" element={<BreadcrumbVendorList />}>
|
||||
<Route
|
||||
path=":vendorId"
|
||||
element={<BreadcrumbVendorOverview />}
|
||||
/>
|
||||
</Route>
|
||||
</Routes>
|
||||
path="frameworks"
|
||||
element={<BreadcrumbFrameworkList />}
|
||||
>
|
||||
<Route
|
||||
path=":frameworkId"
|
||||
element={<BreadcrumbFrameworkOverview />}
|
||||
/>
|
||||
<Route
|
||||
path=":frameworkId/controls/:controlId"
|
||||
element={<BreadcrumbControlOverview />}
|
||||
/>
|
||||
</Route>
|
||||
<Route path="peoples" element={<BreadcrumbPeopleList />}>
|
||||
<Route
|
||||
path=":peopleId"
|
||||
element={<BreadcrumbPeopleOverview />}
|
||||
/>
|
||||
<Route path="create" element={<BreadcrumbCreatePeople />} />
|
||||
</Route>
|
||||
<Route path="vendors" element={<BreadcrumbVendorList />}>
|
||||
<Route
|
||||
path=":vendorId"
|
||||
element={<BreadcrumbVendorOverview />}
|
||||
/>
|
||||
</Route>
|
||||
</Routes>
|
||||
)}
|
||||
</BreadcrumbHome>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -143,12 +143,12 @@ export default function CreateOrganizationPage() {
|
||||
<title>Create Organization - Probo</title>
|
||||
</Helmet>
|
||||
|
||||
<div className="container mx-auto p-6 space-y-6">
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h1 className="text-4xl font-medium tracking-tight">
|
||||
<h1 className="text-2xl font-semibold tracking-tight">
|
||||
Create Organization
|
||||
</h1>
|
||||
<p className="text-lg text-muted-foreground">
|
||||
<p className="text-muted-foreground">
|
||||
Create a new organization to manage your compliance and security
|
||||
needs.
|
||||
</p>
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
import { Suspense, useEffect, useState } from "react";
|
||||
import { Suspense, useState } from "react";
|
||||
import { useNavigate, useParams } from "react-router";
|
||||
import {
|
||||
graphql,
|
||||
PreloadedQuery,
|
||||
usePreloadedQuery,
|
||||
useQueryLoader,
|
||||
useMutation,
|
||||
useRelayEnvironment,
|
||||
ConnectionHandler,
|
||||
} from "react-relay";
|
||||
import { graphql, useMutation, ConnectionHandler } from "react-relay";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card } from "@/components/ui/card";
|
||||
@@ -86,7 +78,7 @@ function CreatePeoplePageContent() {
|
||||
kind: "EMPLOYEE" as "EMPLOYEE" | "CONTRACTOR",
|
||||
});
|
||||
|
||||
const handleFieldChange = (field: keyof typeof formData, value: any) => {
|
||||
const handleFieldChange = (field: keyof typeof formData, value: unknown) => {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
|
||||
@@ -6,10 +6,9 @@ import {
|
||||
usePreloadedQuery,
|
||||
useQueryLoader,
|
||||
} from "react-relay";
|
||||
import { Shield, FileText, Clock, MoveUpRight } from "lucide-react";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Progress } from "@/components/ui/progress";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { Shield, MoveUpRight, Clock } from "lucide-react";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
|
||||
import type { FrameworkOverviewPageQuery as FrameworkOverviewPageQueryType } from "./__generated__/FrameworkOverviewPageQuery.graphql";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { createPortal } from "react-dom";
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useState } from "react";
|
||||
import { Link, useLocation, useNavigate } from "react-router";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { Link, useNavigate } from "react-router";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
@@ -14,12 +13,8 @@ export default function LoginPage() {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const { toast } = useToast();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const { checkAuth } = useAuth();
|
||||
|
||||
// Get the redirect path from location state or default to home
|
||||
const from = location.state?.from?.pathname || "/";
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setIsLoading(true);
|
||||
@@ -50,10 +45,10 @@ export default function LoginPage() {
|
||||
} else {
|
||||
throw new Error("Authentication failed");
|
||||
}
|
||||
} catch (error: any) {
|
||||
} catch (error: unknown) {
|
||||
toast({
|
||||
title: "Error",
|
||||
description: error.message || "Failed to login",
|
||||
description: error instanceof Error ? error.message : "Failed to login",
|
||||
variant: "destructive",
|
||||
});
|
||||
} finally {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { useNavigate } from "react-router";
|
||||
import { graphql, useLazyLoadQuery } from "react-relay";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
usePaginationFragment,
|
||||
} from "react-relay";
|
||||
import { useSearchParams, useParams } from "react-router";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { UserPlus, Trash2, ChevronRight } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -136,8 +136,8 @@ function PeopleListContent({
|
||||
peopleListPageQuery,
|
||||
queryRef
|
||||
);
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const [, setSearchParams] = useSearchParams();
|
||||
const [, startTransition] = useTransition();
|
||||
const [deletePeople] =
|
||||
useMutation<PeopleListPageDeletePeopleMutation>(deletePeopleMutation);
|
||||
const { organizationId } = useParams();
|
||||
|
||||
@@ -95,8 +95,8 @@ function PeopleOverviewPageContent({
|
||||
kind: data.node.kind,
|
||||
});
|
||||
const [commit] = useMutation(updatePeopleMutation);
|
||||
const [_, loadQuery] = useQueryLoader<PeopleOverviewPageQueryType>(
|
||||
peopleOverviewPageQuery,
|
||||
const [, loadQuery] = useQueryLoader<PeopleOverviewPageQueryType>(
|
||||
peopleOverviewPageQuery
|
||||
);
|
||||
const { toast } = useToast();
|
||||
|
||||
@@ -139,7 +139,7 @@ function PeopleOverviewPageContent({
|
||||
});
|
||||
}, [commit, data.node.id, data.node.version, formData, loadQuery, toast]);
|
||||
|
||||
const handleFieldChange = (field: keyof typeof formData, value: any) => {
|
||||
const handleFieldChange = (field: keyof typeof formData, value: unknown) => {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
@@ -198,7 +198,7 @@ function PeopleOverviewPageContent({
|
||||
onClick={() => {
|
||||
const newEmails =
|
||||
formData.additionalEmailAddresses.filter(
|
||||
(_, i) => i !== index,
|
||||
(_, i) => i !== index
|
||||
);
|
||||
handleFieldChange("additionalEmailAddresses", newEmails);
|
||||
}}
|
||||
@@ -243,7 +243,7 @@ function PeopleOverviewPageContent({
|
||||
"rounded-full px-4 py-1 text-sm transition-colors",
|
||||
formData.kind === "EMPLOYEE"
|
||||
? "bg-blue-100 text-blue-900 ring-2 ring-blue-600 ring-offset-2"
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200",
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
|
||||
)}
|
||||
>
|
||||
Employee
|
||||
@@ -254,7 +254,7 @@ function PeopleOverviewPageContent({
|
||||
"rounded-full px-4 py-1 text-sm transition-colors",
|
||||
formData.kind === "CONTRACTOR"
|
||||
? "bg-purple-100 text-purple-900 ring-2 ring-purple-600 ring-offset-2"
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200",
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
|
||||
)}
|
||||
>
|
||||
Contractor
|
||||
@@ -303,7 +303,7 @@ function PeopleOverviewPageFallback() {
|
||||
export default function PeopleOverviewPage() {
|
||||
const { peopleId } = useParams();
|
||||
const [queryRef, loadQuery] = useQueryLoader<PeopleOverviewPageQueryType>(
|
||||
peopleOverviewPageQuery,
|
||||
peopleOverviewPageQuery
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
CardTitle,
|
||||
CardDescription,
|
||||
} from "@/components/ui/card";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
usePaginationFragment,
|
||||
} from "react-relay";
|
||||
import { useSearchParams, useParams } from "react-router";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Store, ChevronRight, Trash2 } from "lucide-react";
|
||||
import { Input } from "@/components/ui/input";
|
||||
@@ -190,8 +190,8 @@ function VendorListContent({
|
||||
vendorListPageQuery,
|
||||
queryRef
|
||||
);
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const [, setSearchParams] = useSearchParams();
|
||||
const [, startTransition] = useTransition();
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [filteredVendors, setFilteredVendors] = useState<VendorItem[]>([]);
|
||||
const [createVendor] =
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Label } from "@/components/ui/label";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { HelpCircle, ArrowUpRight, Pencil, Check, X } from "lucide-react";
|
||||
import { HelpCircle } from "lucide-react";
|
||||
import {
|
||||
graphql,
|
||||
PreloadedQuery,
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
useQueryLoader,
|
||||
useMutation,
|
||||
} from "react-relay";
|
||||
import { Suspense, useEffect, useState, useCallback, useMemo } from "react";
|
||||
import { Suspense, useEffect, useState, useCallback } from "react";
|
||||
import type { VendorOverviewPageQuery as VendorOverviewPageQueryType } from "./__generated__/VendorOverviewPageQuery.graphql";
|
||||
import { useParams } from "react-router";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
@@ -124,8 +124,8 @@ function VendorOverviewPageContent({
|
||||
privacyPolicyUrl: data.node.privacyPolicyUrl || "",
|
||||
});
|
||||
const [commit] = useMutation(updateVendorMutation);
|
||||
const [_, loadQuery] = useQueryLoader<VendorOverviewPageQueryType>(
|
||||
vendorOverviewPageQuery,
|
||||
const [, loadQuery] = useQueryLoader<VendorOverviewPageQueryType>(
|
||||
vendorOverviewPageQuery
|
||||
);
|
||||
const { toast } = useToast();
|
||||
|
||||
@@ -174,13 +174,10 @@ function VendorOverviewPageContent({
|
||||
});
|
||||
}
|
||||
},
|
||||
updater: (store) => {
|
||||
// Clear any error states if needed
|
||||
},
|
||||
});
|
||||
}, [commit, data.node.id, data.node.version, formData, loadQuery, toast]);
|
||||
|
||||
const handleFieldChange = (field: keyof typeof formData, value: any) => {
|
||||
const handleFieldChange = (field: keyof typeof formData, value: unknown) => {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
@@ -262,7 +259,7 @@ function VendorOverviewPageContent({
|
||||
"rounded-full px-4 py-1 text-sm transition-colors",
|
||||
formData.serviceCriticality === "LOW"
|
||||
? "bg-green-100 text-green-900 ring-2 ring-green-600 ring-offset-2"
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200",
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
|
||||
)}
|
||||
>
|
||||
Low
|
||||
@@ -275,7 +272,7 @@ function VendorOverviewPageContent({
|
||||
"rounded-full px-4 py-1 text-sm transition-colors",
|
||||
formData.serviceCriticality === "MEDIUM"
|
||||
? "bg-yellow-100 text-yellow-900 ring-2 ring-yellow-600 ring-offset-2"
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200",
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
|
||||
)}
|
||||
>
|
||||
Medium
|
||||
@@ -288,7 +285,7 @@ function VendorOverviewPageContent({
|
||||
"rounded-full px-4 py-1 text-sm transition-colors",
|
||||
formData.serviceCriticality === "HIGH"
|
||||
? "bg-red-100 text-red-900 ring-2 ring-red-600 ring-offset-2"
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200",
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
|
||||
)}
|
||||
>
|
||||
High
|
||||
@@ -316,7 +313,7 @@ function VendorOverviewPageContent({
|
||||
"rounded-full px-4 py-1 text-sm transition-colors",
|
||||
formData.riskTier === "CRITICAL"
|
||||
? "bg-red-100 text-red-900 ring-2 ring-red-600 ring-offset-2"
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200",
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
|
||||
)}
|
||||
>
|
||||
Critical
|
||||
@@ -329,7 +326,7 @@ function VendorOverviewPageContent({
|
||||
"rounded-full px-4 py-1 text-sm transition-colors",
|
||||
formData.riskTier === "SIGNIFICANT"
|
||||
? "bg-yellow-100 text-yellow-900 ring-2 ring-yellow-600 ring-offset-2"
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200",
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
|
||||
)}
|
||||
>
|
||||
Significant
|
||||
@@ -340,7 +337,7 @@ function VendorOverviewPageContent({
|
||||
"rounded-full px-4 py-1 text-sm transition-colors",
|
||||
formData.riskTier === "GENERAL"
|
||||
? "bg-green-100 text-green-900 ring-2 ring-green-600 ring-offset-2"
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200",
|
||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
|
||||
)}
|
||||
>
|
||||
General
|
||||
@@ -421,7 +418,7 @@ function VendorOverviewPageFallback() {
|
||||
export default function VendorOverviewPage() {
|
||||
const { vendorId } = useParams();
|
||||
const [queryRef, loadQuery] = useQueryLoader<VendorOverviewPageQueryType>(
|
||||
vendorOverviewPageQuery,
|
||||
vendorOverviewPageQuery
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user