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
|
||||
|
||||
- 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
|
||||
- People may be linked to user
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@ import {
|
||||
usePaginationFragment,
|
||||
} from "react-relay";
|
||||
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 { Store, ChevronRight, Trash2 } from "lucide-react";
|
||||
import { Store, Plus, MoreHorizontal } from "lucide-react";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Link } from "react-router";
|
||||
@@ -83,6 +83,7 @@ const vendorListFragment = graphql`
|
||||
id
|
||||
name
|
||||
description
|
||||
websiteUrl
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
@@ -108,6 +109,7 @@ const createVendorMutation = graphql`
|
||||
id
|
||||
name
|
||||
description
|
||||
websiteUrl
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
@@ -141,7 +143,7 @@ function LoadAboveButton({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex justify-center">
|
||||
<div className="flex justify-center mt-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={onLoadMore}
|
||||
@@ -168,7 +170,7 @@ function LoadBelowButton({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex justify-center">
|
||||
<div className="flex justify-center mt-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={onLoadMore}
|
||||
@@ -194,6 +196,7 @@ function ListVendorContent({
|
||||
const [, setSearchParams] = useSearchParams();
|
||||
const [, startTransition] = useTransition();
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [showAddVendorDropdown, setShowAddVendorDropdown] = useState(false);
|
||||
const [filteredVendors, setFilteredVendors] = useState<VendorData[]>([]);
|
||||
const [vendorsData, setVendorsData] = useState<VendorData[]>([]);
|
||||
const [isLoadingVendors, setIsLoadingVendors] = useState(false);
|
||||
@@ -250,14 +253,77 @@ function ListVendorContent({
|
||||
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 (
|
||||
<PageTemplate
|
||||
title="Vendors"
|
||||
description="Vendors are third-party services that your company uses. Add them to
|
||||
keep track of their risk and compliance status."
|
||||
description="Vendors are third-party services that your company uses. Add them to 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">
|
||||
<div className="rounded-xl border bg-level-1 p-4">
|
||||
{showAddVendorDropdown && (
|
||||
<div className="mb-6 p-4 border rounded-xl bg-white relative">
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<Store className="h-5 w-5" />
|
||||
<h3 className="font-medium">Add a vendor</h3>
|
||||
@@ -268,18 +334,7 @@ function ListVendorContent({
|
||||
placeholder="Type vendor's name"
|
||||
value={searchTerm}
|
||||
style={{ borderRadius: "0.3rem" }}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
setSearchTerm(value);
|
||||
if (value.trim() === "") {
|
||||
setFilteredVendors([]);
|
||||
} else {
|
||||
const results = fuse
|
||||
.search(value)
|
||||
.map((result) => result.item);
|
||||
setFilteredVendors(results);
|
||||
}
|
||||
}}
|
||||
onChange={handleSearchChange}
|
||||
disabled={isLoadingVendors}
|
||||
/>
|
||||
{isLoadingVendors && (
|
||||
@@ -291,12 +346,12 @@ function ListVendorContent({
|
||||
{searchTerm.trim() !== "" && (
|
||||
<div
|
||||
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) => (
|
||||
<button
|
||||
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={() => {
|
||||
createVendor({
|
||||
variables: {
|
||||
@@ -325,6 +380,7 @@ function ListVendorContent({
|
||||
onCompleted() {
|
||||
setSearchTerm("");
|
||||
setFilteredVendors([]);
|
||||
setShowAddVendorDropdown(false);
|
||||
toast({
|
||||
title: "Vendor added",
|
||||
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
|
||||
className="w-full px-3 py-2 text-left hover:bg-h-subtle-bg flex items-center gap-2 border-t"
|
||||
onClick={() => {
|
||||
className="w-full px-3 py-2 text-left hover:bg-gray-50 flex items-center gap-2 border-t"
|
||||
onClick={(e) => {
|
||||
createVendor({
|
||||
variables: {
|
||||
connections: [vendorsConnection.vendors.__id],
|
||||
@@ -348,13 +416,12 @@ function ListVendorContent({
|
||||
name: searchTerm.trim(),
|
||||
description: "",
|
||||
serviceStartAt: new Date().toISOString(),
|
||||
serviceCriticality: "LOW",
|
||||
riskTier: "GENERAL",
|
||||
},
|
||||
},
|
||||
onCompleted() {
|
||||
setSearchTerm("");
|
||||
setFilteredVendors([]);
|
||||
setShowAddVendorDropdown(false);
|
||||
toast({
|
||||
title: "Vendor created",
|
||||
description:
|
||||
@@ -364,80 +431,180 @@ function ListVendorContent({
|
||||
});
|
||||
}}
|
||||
>
|
||||
<span className="font-medium">Create new vendor:</span>{" "}
|
||||
{searchTerm}
|
||||
<div className="flex items-center gap-2">
|
||||
<Plus className="h-4 w-4" />
|
||||
<span className="font-medium">Create new vendor:</span> {searchTerm}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="space-y-2">
|
||||
{vendors.map((vendor) => (
|
||||
<Link
|
||||
key={vendor?.id}
|
||||
to={`/organizations/${organizationId}/vendors/${vendor?.id}`}
|
||||
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="rounded-xl border overflow-hidden">
|
||||
<table className="w-full bg-white">
|
||||
<thead className="bg-white border-b border-gray-100">
|
||||
<tr>
|
||||
<th className="py-3 px-4 text-left text-xs font-semibold text-gray-500">
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge
|
||||
variant="secondary"
|
||||
className={
|
||||
vendor.riskTier === "CRITICAL"
|
||||
? "bg-danger-bg text-danger rounded-full px-3 py-0.5 text-xs font-medium"
|
||||
: vendor?.riskTier === "SIGNIFICANT"
|
||||
? "bg-warning-bg text-warning rounded-full px-3 py-0.5 text-xs font-medium"
|
||||
: "bg-success-bg text-success rounded-full px-3 py-0.5 text-xs font-medium"
|
||||
}
|
||||
Vendor
|
||||
<svg
|
||||
width="8"
|
||||
height="8"
|
||||
viewBox="0 0 8 8"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="text-gray-400"
|
||||
>
|
||||
{vendor.riskTier}
|
||||
</Badge>
|
||||
<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" />
|
||||
<path d="M4 6L7 3H1L4 6Z" fill="currentColor" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</th>
|
||||
<th className="py-3 px-4 text-left text-xs font-semibold text-gray-500">
|
||||
<div className="flex items-center gap-2">
|
||||
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>
|
||||
|
||||
<LoadAboveButton
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<ccdef4cce3d167b401f6d89dea1dde33>>
|
||||
* @generated SignedSource<<55ac3df9e65daff882c0d44f7b4904c2>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -43,6 +43,7 @@ export type ListVendorViewCreateVendorMutation$data = {
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly updatedAt: string;
|
||||
readonly websiteUrl: string | null | undefined;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -107,6 +108,13 @@ v3 = {
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "websiteUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -193,16 +201,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "03c1d61a3a252ca74bd8da1821f1e0b9",
|
||||
"cacheID": "4ff1631133af0ca4a0d3109dbd1bda4f",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "ListVendorViewCreateVendorMutation",
|
||||
"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;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<a59c7eee4b53c2b74df89a2fa693d9cd>>
|
||||
* @generated SignedSource<<2d5b613cbbbd051c4c1f1561f55bf644>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -210,6 +210,13 @@ return {
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "websiteUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -313,16 +320,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "b4165eeba6363c964b11f14f678d5338",
|
||||
"cacheID": "b1055c67d0940ecd9189ec80410a8add",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "ListVendorViewPaginationQuery",
|
||||
"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;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<bdea7e121ea26a5af6985b4399be4bcc>>
|
||||
* @generated SignedSource<<4d1328e7df631fabe3c8b7dccdf5ffb0>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -212,6 +212,13 @@ return {
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "websiteUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -315,12 +322,12 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "d93a40f389769d5895b502cb8e7a2c16",
|
||||
"cacheID": "f4269cea33bcb3665cfc49bc350cf426",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "ListVendorViewQuery",
|
||||
"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
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -21,6 +21,7 @@ export type ListVendorView_vendors$data = {
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly updatedAt: string;
|
||||
readonly websiteUrl: string | null | undefined;
|
||||
};
|
||||
}>;
|
||||
readonly pageInfo: {
|
||||
@@ -153,6 +154,13 @@ return {
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "websiteUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -248,6 +256,6 @@ return {
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "477e430705f0f3cbadb8dfac89e24629";
|
||||
(node as any).hash = "3908e5fd1af7e0cb367a480fc9fc437e";
|
||||
|
||||
export default node;
|
||||
|
||||
Reference in New Issue
Block a user