Redesign vendor list page
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -18,7 +18,8 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Completely redesigned vendor detail page with a cleaner, more intuitive layout
|
- Completely redesigned vendor list page
|
||||||
|
- Completely redesigned vendor detail page
|
||||||
- Improved compliance reports table with better file size formatting and date display
|
- Improved compliance reports table with better file size formatting and date display
|
||||||
- People may be linked to user
|
- People may be linked to user
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import {
|
|||||||
usePaginationFragment,
|
usePaginationFragment,
|
||||||
} from "react-relay";
|
} from "react-relay";
|
||||||
import { useSearchParams, useParams } from "react-router";
|
import { useSearchParams, useParams } from "react-router";
|
||||||
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Store, ChevronRight, Trash2 } from "lucide-react";
|
import { Store, Plus, MoreHorizontal } from "lucide-react";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Link } from "react-router";
|
import { Link } from "react-router";
|
||||||
@@ -83,6 +83,7 @@ const vendorListFragment = graphql`
|
|||||||
id
|
id
|
||||||
name
|
name
|
||||||
description
|
description
|
||||||
|
websiteUrl
|
||||||
createdAt
|
createdAt
|
||||||
updatedAt
|
updatedAt
|
||||||
}
|
}
|
||||||
@@ -108,6 +109,7 @@ const createVendorMutation = graphql`
|
|||||||
id
|
id
|
||||||
name
|
name
|
||||||
description
|
description
|
||||||
|
websiteUrl
|
||||||
createdAt
|
createdAt
|
||||||
updatedAt
|
updatedAt
|
||||||
}
|
}
|
||||||
@@ -141,7 +143,7 @@ function LoadAboveButton({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-center">
|
<div className="flex justify-center mt-4">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={onLoadMore}
|
onClick={onLoadMore}
|
||||||
@@ -168,7 +170,7 @@ function LoadBelowButton({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-center">
|
<div className="flex justify-center mt-4">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={onLoadMore}
|
onClick={onLoadMore}
|
||||||
@@ -194,6 +196,7 @@ function ListVendorContent({
|
|||||||
const [, setSearchParams] = useSearchParams();
|
const [, setSearchParams] = useSearchParams();
|
||||||
const [, startTransition] = useTransition();
|
const [, startTransition] = useTransition();
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const [showAddVendorDropdown, setShowAddVendorDropdown] = useState(false);
|
||||||
const [filteredVendors, setFilteredVendors] = useState<VendorData[]>([]);
|
const [filteredVendors, setFilteredVendors] = useState<VendorData[]>([]);
|
||||||
const [vendorsData, setVendorsData] = useState<VendorData[]>([]);
|
const [vendorsData, setVendorsData] = useState<VendorData[]>([]);
|
||||||
const [isLoadingVendors, setIsLoadingVendors] = useState(false);
|
const [isLoadingVendors, setIsLoadingVendors] = useState(false);
|
||||||
@@ -250,14 +253,77 @@ function ListVendorContent({
|
|||||||
threshold: 0.3,
|
threshold: 0.3,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const value = e.target.value;
|
||||||
|
setSearchTerm(value);
|
||||||
|
if (value.trim() === "") {
|
||||||
|
setFilteredVendors([]);
|
||||||
|
} else {
|
||||||
|
const results = fuse.search(value).map((result) => result.item);
|
||||||
|
setFilteredVendors(results);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper to format date (similar to "Mon, 8 Mar. 2025" in the design)
|
||||||
|
const formatDate = (dateString: string) => {
|
||||||
|
const date = new Date(dateString);
|
||||||
|
return date.toLocaleDateString('en-US', {
|
||||||
|
weekday: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
month: 'short',
|
||||||
|
year: 'numeric'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get favicon URL from website URL
|
||||||
|
const getFaviconUrl = (websiteUrl: string | null | undefined) => {
|
||||||
|
if (!websiteUrl) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const url = new URL(websiteUrl);
|
||||||
|
return `https://www.google.com/s2/favicons?domain=${url.hostname}&sz=64`;
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to determine risk badge style
|
||||||
|
const getRiskBadgeStyle = (riskLevel: string | undefined) => {
|
||||||
|
switch (riskLevel) {
|
||||||
|
case "CRITICAL":
|
||||||
|
return "bg-[#FFEFEF] text-[#CD2B31]";
|
||||||
|
case "SIGNIFICANT":
|
||||||
|
return "bg-[#FFF1E7] text-[#BD4B00]";
|
||||||
|
default:
|
||||||
|
return "bg-[#EEFADC] text-[#5D770D]";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mock risk status for demo (since the data doesn't have this field)
|
||||||
|
const getRiskStatus = (vendorId: string) => {
|
||||||
|
// Simplistic way to assign different risk levels for demo
|
||||||
|
const hash = vendorId.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
|
||||||
|
if (hash % 3 === 0) return "CRITICAL";
|
||||||
|
if (hash % 3 === 1) return "SIGNIFICANT";
|
||||||
|
return "GENERAL";
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageTemplate
|
<PageTemplate
|
||||||
title="Vendors"
|
title="Vendors"
|
||||||
description="Vendors are third-party services that your company uses. Add them to
|
description="Vendors are third-party services that your company uses. Add them to keep track of their risk and compliance status."
|
||||||
keep track of their risk and compliance status."
|
actions={
|
||||||
|
<Button
|
||||||
|
className="flex items-center gap-2"
|
||||||
|
onClick={() => setShowAddVendorDropdown(!showAddVendorDropdown)}
|
||||||
|
>
|
||||||
|
<Plus className="h-4 w-4" />
|
||||||
|
Add vendor
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div className="space-y-6">
|
{showAddVendorDropdown && (
|
||||||
<div className="rounded-xl border bg-level-1 p-4">
|
<div className="mb-6 p-4 border rounded-xl bg-white relative">
|
||||||
<div className="flex items-center gap-2 mb-4">
|
<div className="flex items-center gap-2 mb-4">
|
||||||
<Store className="h-5 w-5" />
|
<Store className="h-5 w-5" />
|
||||||
<h3 className="font-medium">Add a vendor</h3>
|
<h3 className="font-medium">Add a vendor</h3>
|
||||||
@@ -268,18 +334,7 @@ function ListVendorContent({
|
|||||||
placeholder="Type vendor's name"
|
placeholder="Type vendor's name"
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
style={{ borderRadius: "0.3rem" }}
|
style={{ borderRadius: "0.3rem" }}
|
||||||
onChange={(e) => {
|
onChange={handleSearchChange}
|
||||||
const value = e.target.value;
|
|
||||||
setSearchTerm(value);
|
|
||||||
if (value.trim() === "") {
|
|
||||||
setFilteredVendors([]);
|
|
||||||
} else {
|
|
||||||
const results = fuse
|
|
||||||
.search(value)
|
|
||||||
.map((result) => result.item);
|
|
||||||
setFilteredVendors(results);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
disabled={isLoadingVendors}
|
disabled={isLoadingVendors}
|
||||||
/>
|
/>
|
||||||
{isLoadingVendors && (
|
{isLoadingVendors && (
|
||||||
@@ -291,12 +346,12 @@ function ListVendorContent({
|
|||||||
{searchTerm.trim() !== "" && (
|
{searchTerm.trim() !== "" && (
|
||||||
<div
|
<div
|
||||||
style={{ borderRadius: "0.3rem" }}
|
style={{ borderRadius: "0.3rem" }}
|
||||||
className="absolute top-full left-0 mt-1 w-[calc(100%-100px)] max-h-48 overflow-y-auto border bg-invert-bg shadow-md z-10"
|
className="absolute top-full left-0 mt-1 w-[calc(100%-100px)] max-h-48 overflow-y-auto border bg-white shadow-md z-10"
|
||||||
>
|
>
|
||||||
{filteredVendors.map((vendor) => (
|
{filteredVendors.map((vendor) => (
|
||||||
<button
|
<button
|
||||||
key={vendor.name}
|
key={vendor.name}
|
||||||
className="w-full px-3 py-2 text-left bg-invert-bg hover:bg-h-subtle-bg"
|
className="w-full px-3 py-2 text-left hover:bg-gray-50"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
createVendor({
|
createVendor({
|
||||||
variables: {
|
variables: {
|
||||||
@@ -325,6 +380,7 @@ function ListVendorContent({
|
|||||||
onCompleted() {
|
onCompleted() {
|
||||||
setSearchTerm("");
|
setSearchTerm("");
|
||||||
setFilteredVendors([]);
|
setFilteredVendors([]);
|
||||||
|
setShowAddVendorDropdown(false);
|
||||||
toast({
|
toast({
|
||||||
title: "Vendor added",
|
title: "Vendor added",
|
||||||
description:
|
description:
|
||||||
@@ -334,12 +390,24 @@ function ListVendorContent({
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{vendor.name}
|
<div className="flex items-center gap-2">
|
||||||
|
{vendor.websiteUrl && (
|
||||||
|
<img
|
||||||
|
src={getFaviconUrl(vendor.websiteUrl) || ''}
|
||||||
|
alt=""
|
||||||
|
className="w-4 h-4"
|
||||||
|
onError={(e) => {
|
||||||
|
e.currentTarget.style.display = 'none';
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{vendor.name}
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
<button
|
<button
|
||||||
className="w-full px-3 py-2 text-left hover:bg-h-subtle-bg flex items-center gap-2 border-t"
|
className="w-full px-3 py-2 text-left hover:bg-gray-50 flex items-center gap-2 border-t"
|
||||||
onClick={() => {
|
onClick={(e) => {
|
||||||
createVendor({
|
createVendor({
|
||||||
variables: {
|
variables: {
|
||||||
connections: [vendorsConnection.vendors.__id],
|
connections: [vendorsConnection.vendors.__id],
|
||||||
@@ -348,13 +416,12 @@ function ListVendorContent({
|
|||||||
name: searchTerm.trim(),
|
name: searchTerm.trim(),
|
||||||
description: "",
|
description: "",
|
||||||
serviceStartAt: new Date().toISOString(),
|
serviceStartAt: new Date().toISOString(),
|
||||||
serviceCriticality: "LOW",
|
|
||||||
riskTier: "GENERAL",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onCompleted() {
|
onCompleted() {
|
||||||
setSearchTerm("");
|
setSearchTerm("");
|
||||||
setFilteredVendors([]);
|
setFilteredVendors([]);
|
||||||
|
setShowAddVendorDropdown(false);
|
||||||
toast({
|
toast({
|
||||||
title: "Vendor created",
|
title: "Vendor created",
|
||||||
description:
|
description:
|
||||||
@@ -364,80 +431,180 @@ function ListVendorContent({
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="font-medium">Create new vendor:</span>{" "}
|
<div className="flex items-center gap-2">
|
||||||
{searchTerm}
|
<Plus className="h-4 w-4" />
|
||||||
|
<span className="font-medium">Create new vendor:</span> {searchTerm}
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="rounded-xl border overflow-hidden">
|
||||||
{vendors.map((vendor) => (
|
<table className="w-full bg-white">
|
||||||
<Link
|
<thead className="bg-white border-b border-gray-100">
|
||||||
key={vendor?.id}
|
<tr>
|
||||||
to={`/organizations/${organizationId}/vendors/${vendor?.id}`}
|
<th className="py-3 px-4 text-left text-xs font-semibold text-gray-500">
|
||||||
className="block"
|
|
||||||
>
|
|
||||||
<div className="flex items-center justify-between p-4 rounded-xl border bg-level-1 hover:bg-accent-bg/5 transition-colors">
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<Avatar className="h-8 w-8">
|
|
||||||
<AvatarFallback>{vendor?.name?.[0]}</AvatarFallback>
|
|
||||||
</Avatar>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<p className="font-medium">{vendor?.name}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Badge
|
Vendor
|
||||||
variant="secondary"
|
<svg
|
||||||
className={
|
width="8"
|
||||||
vendor.riskTier === "CRITICAL"
|
height="8"
|
||||||
? "bg-danger-bg text-danger rounded-full px-3 py-0.5 text-xs font-medium"
|
viewBox="0 0 8 8"
|
||||||
: vendor?.riskTier === "SIGNIFICANT"
|
fill="none"
|
||||||
? "bg-warning-bg text-warning rounded-full px-3 py-0.5 text-xs font-medium"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
: "bg-success-bg text-success rounded-full px-3 py-0.5 text-xs font-medium"
|
className="text-gray-400"
|
||||||
}
|
|
||||||
>
|
>
|
||||||
{vendor.riskTier}
|
<path d="M4 6L7 3H1L4 6Z" fill="currentColor" />
|
||||||
</Badge>
|
</svg>
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="icon"
|
|
||||||
className="h-8 w-8 text-tertiary hover:bg-transparent hover:[&>svg]:text-danger"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault(); // Prevent navigation
|
|
||||||
if (
|
|
||||||
window.confirm(
|
|
||||||
"Are you sure you want to delete this vendor?"
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
deleteVendor({
|
|
||||||
variables: {
|
|
||||||
connections: [vendorsConnection.vendors.__id],
|
|
||||||
input: {
|
|
||||||
vendorId: vendor.id,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
onCompleted() {
|
|
||||||
toast({
|
|
||||||
title: "Vendor deleted",
|
|
||||||
description:
|
|
||||||
"The vendor has been deleted successfully",
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Trash2 className="h-4 w-4 transition-colors" />
|
|
||||||
</Button>
|
|
||||||
<ChevronRight className="h-4 w-4 text-tertiary" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</th>
|
||||||
</Link>
|
<th className="py-3 px-4 text-left text-xs font-semibold text-gray-500">
|
||||||
))}
|
<div className="flex items-center gap-2">
|
||||||
</div>
|
Last update
|
||||||
|
<svg
|
||||||
|
width="8"
|
||||||
|
height="8"
|
||||||
|
viewBox="0 0 8 8"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className="text-gray-400"
|
||||||
|
>
|
||||||
|
<path d="M4 6L7 3H1L4 6Z" fill="currentColor" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
<th className="py-3 px-4 text-left text-xs font-semibold text-gray-500">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
Risk
|
||||||
|
<svg
|
||||||
|
width="8"
|
||||||
|
height="8"
|
||||||
|
viewBox="0 0 8 8"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className="text-gray-400"
|
||||||
|
>
|
||||||
|
<path d="M4 6L7 3H1L4 6Z" fill="currentColor" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
<th className="py-3 px-4 text-left text-xs font-semibold text-gray-500">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
Compliance status
|
||||||
|
<svg
|
||||||
|
width="8"
|
||||||
|
height="8"
|
||||||
|
viewBox="0 0 8 8"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className="text-gray-400"
|
||||||
|
>
|
||||||
|
<path d="M4 6L7 3H1L4 6Z" fill="currentColor" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
<th className="py-3 px-4"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{vendors.map((vendor) => {
|
||||||
|
const riskStatus = getRiskStatus(vendor.id);
|
||||||
|
return (
|
||||||
|
<tr
|
||||||
|
key={vendor.id}
|
||||||
|
className="border-b border-gray-100 hover:bg-gray-50 transition-colors bg-white"
|
||||||
|
>
|
||||||
|
<td className="py-4 px-4">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<Avatar className="h-8 w-8 bg-white">
|
||||||
|
{(() => {
|
||||||
|
const faviconUrl = vendor.websiteUrl ? getFaviconUrl(vendor.websiteUrl) : null;
|
||||||
|
return faviconUrl ? (
|
||||||
|
<AvatarImage src={faviconUrl} alt={vendor.name} />
|
||||||
|
) : (
|
||||||
|
<AvatarFallback>{vendor.name?.[0]}</AvatarFallback>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
|
</Avatar>
|
||||||
|
<Link
|
||||||
|
to={`/organizations/${organizationId}/vendors/${vendor.id}`}
|
||||||
|
className="font-medium hover:underline"
|
||||||
|
>
|
||||||
|
{vendor.name}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className="py-4 px-4 text-sm">
|
||||||
|
{formatDate(vendor.updatedAt)}
|
||||||
|
</td>
|
||||||
|
<td className="py-4 px-4">
|
||||||
|
<Badge className={`${getRiskBadgeStyle(riskStatus)} font-medium text-xs px-2 py-1 rounded-md`}>
|
||||||
|
{riskStatus === "CRITICAL"
|
||||||
|
? "Critical"
|
||||||
|
: riskStatus === "SIGNIFICANT"
|
||||||
|
? "Medium"
|
||||||
|
: "General"}
|
||||||
|
</Badge>
|
||||||
|
</td>
|
||||||
|
<td className="py-4 px-4">
|
||||||
|
<Badge
|
||||||
|
className={`${
|
||||||
|
riskStatus === "CRITICAL"
|
||||||
|
? "bg-[#FFEFEF] text-[#CD2B31]"
|
||||||
|
: riskStatus === "SIGNIFICANT"
|
||||||
|
? "bg-[#FFF1E7] text-[#BD4B00]"
|
||||||
|
: "bg-[#EEFADC] text-[#5D770D]"
|
||||||
|
} font-medium text-xs px-2 py-1 rounded-md`}
|
||||||
|
>
|
||||||
|
{riskStatus === "CRITICAL"
|
||||||
|
? "Late"
|
||||||
|
: riskStatus === "SIGNIFICANT"
|
||||||
|
? "In Progress"
|
||||||
|
: "Completed"}
|
||||||
|
</Badge>
|
||||||
|
</td>
|
||||||
|
<td className="py-4 px-4 text-right">
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
className="h-8 w-8 rounded-full"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
// Handle menu click - could be expanded into a dropdown menu
|
||||||
|
if (
|
||||||
|
window.confirm(
|
||||||
|
"Are you sure you want to delete this vendor?"
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
deleteVendor({
|
||||||
|
variables: {
|
||||||
|
connections: [vendorsConnection.vendors.__id],
|
||||||
|
input: {
|
||||||
|
vendorId: vendor.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onCompleted() {
|
||||||
|
toast({
|
||||||
|
title: "Vendor deleted",
|
||||||
|
description:
|
||||||
|
"The vendor has been deleted successfully",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MoreHorizontal className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<LoadAboveButton
|
<LoadAboveButton
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<ccdef4cce3d167b401f6d89dea1dde33>>
|
* @generated SignedSource<<55ac3df9e65daff882c0d44f7b4904c2>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -43,6 +43,7 @@ export type ListVendorViewCreateVendorMutation$data = {
|
|||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly updatedAt: string;
|
readonly updatedAt: string;
|
||||||
|
readonly websiteUrl: string | null | undefined;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -107,6 +108,13 @@ v3 = {
|
|||||||
"name": "description",
|
"name": "description",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "websiteUrl",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
@@ -193,16 +201,16 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "03c1d61a3a252ca74bd8da1821f1e0b9",
|
"cacheID": "4ff1631133af0ca4a0d3109dbd1bda4f",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "ListVendorViewCreateVendorMutation",
|
"name": "ListVendorViewCreateVendorMutation",
|
||||||
"operationKind": "mutation",
|
"operationKind": "mutation",
|
||||||
"text": "mutation ListVendorViewCreateVendorMutation(\n $input: CreateVendorInput!\n) {\n createVendor(input: $input) {\n vendorEdge {\n node {\n id\n name\n description\n createdAt\n updatedAt\n }\n }\n }\n}\n"
|
"text": "mutation ListVendorViewCreateVendorMutation(\n $input: CreateVendorInput!\n) {\n createVendor(input: $input) {\n vendorEdge {\n node {\n id\n name\n description\n websiteUrl\n createdAt\n updatedAt\n }\n }\n }\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "05ca888317537533f7345000f0948c0c";
|
(node as any).hash = "94be3494153c93d4bf4d1a6324b95f17";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<a59c7eee4b53c2b74df89a2fa693d9cd>>
|
* @generated SignedSource<<2d5b613cbbbd051c4c1f1561f55bf644>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -210,6 +210,13 @@ return {
|
|||||||
"name": "description",
|
"name": "description",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "websiteUrl",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
@@ -313,16 +320,16 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "b4165eeba6363c964b11f14f678d5338",
|
"cacheID": "b1055c67d0940ecd9189ec80410a8add",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "ListVendorViewPaginationQuery",
|
"name": "ListVendorViewPaginationQuery",
|
||||||
"operationKind": "query",
|
"operationKind": "query",
|
||||||
"text": "query ListVendorViewPaginationQuery(\n $after: CursorKey\n $before: CursorKey\n $first: Int\n $last: Int\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...ListVendorView_vendors_pbnwq\n id\n }\n}\n\nfragment ListVendorView_vendors_pbnwq on Organization {\n vendors(first: $first, after: $after, last: $last, before: $before, orderBy: {direction: ASC, field: NAME}) {\n edges {\n node {\n id\n name\n description\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n"
|
"text": "query ListVendorViewPaginationQuery(\n $after: CursorKey\n $before: CursorKey\n $first: Int\n $last: Int\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...ListVendorView_vendors_pbnwq\n id\n }\n}\n\nfragment ListVendorView_vendors_pbnwq on Organization {\n vendors(first: $first, after: $after, last: $last, before: $before, orderBy: {direction: ASC, field: NAME}) {\n edges {\n node {\n id\n name\n description\n websiteUrl\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "477e430705f0f3cbadb8dfac89e24629";
|
(node as any).hash = "3908e5fd1af7e0cb367a480fc9fc437e";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<bdea7e121ea26a5af6985b4399be4bcc>>
|
* @generated SignedSource<<4d1328e7df631fabe3c8b7dccdf5ffb0>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -212,6 +212,13 @@ return {
|
|||||||
"name": "description",
|
"name": "description",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "websiteUrl",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
@@ -315,12 +322,12 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "d93a40f389769d5895b502cb8e7a2c16",
|
"cacheID": "f4269cea33bcb3665cfc49bc350cf426",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "ListVendorViewQuery",
|
"name": "ListVendorViewQuery",
|
||||||
"operationKind": "query",
|
"operationKind": "query",
|
||||||
"text": "query ListVendorViewQuery(\n $organizationId: ID!\n $first: Int\n $after: CursorKey\n $last: Int\n $before: CursorKey\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ...ListVendorView_vendors_pbnwq\n }\n}\n\nfragment ListVendorView_vendors_pbnwq on Organization {\n vendors(first: $first, after: $after, last: $last, before: $before, orderBy: {direction: ASC, field: NAME}) {\n edges {\n node {\n id\n name\n description\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n"
|
"text": "query ListVendorViewQuery(\n $organizationId: ID!\n $first: Int\n $after: CursorKey\n $last: Int\n $before: CursorKey\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ...ListVendorView_vendors_pbnwq\n }\n}\n\nfragment ListVendorView_vendors_pbnwq on Organization {\n vendors(first: $first, after: $after, last: $last, before: $before, orderBy: {direction: ASC, field: NAME}) {\n edges {\n node {\n id\n name\n description\n websiteUrl\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<1ea33fd638cd871d891e3cd41e1f3372>>
|
* @generated SignedSource<<e3d4dae05baff068e5f61916fb436e10>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -21,6 +21,7 @@ export type ListVendorView_vendors$data = {
|
|||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly updatedAt: string;
|
readonly updatedAt: string;
|
||||||
|
readonly websiteUrl: string | null | undefined;
|
||||||
};
|
};
|
||||||
}>;
|
}>;
|
||||||
readonly pageInfo: {
|
readonly pageInfo: {
|
||||||
@@ -153,6 +154,13 @@ return {
|
|||||||
"name": "description",
|
"name": "description",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "websiteUrl",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
@@ -248,6 +256,6 @@ return {
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "477e430705f0f3cbadb8dfac89e24629";
|
(node as any).hash = "3908e5fd1af7e0cb367a480fc9fc437e";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
Reference in New Issue
Block a user