Add vendor compliance reports UI
Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
@@ -6,6 +6,10 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
## [0.4.2] - 2025-04-09
|
||||
|
||||
### Added
|
||||
|
||||
- Add vendor compliance reports UI
|
||||
|
||||
### Changed
|
||||
|
||||
- Simplified policy data model by removing version field and optimistic concurrency
|
||||
|
||||
@@ -12,9 +12,12 @@ import {
|
||||
usePreloadedQuery,
|
||||
useQueryLoader,
|
||||
useMutation,
|
||||
ConnectionHandler,
|
||||
} from "react-relay";
|
||||
import { Suspense, useEffect, useState, useCallback } from "react";
|
||||
import { Suspense, useEffect, useState, useCallback, useRef } from "react";
|
||||
import type { VendorViewQuery as VendorViewQueryType } from "./__generated__/VendorViewQuery.graphql";
|
||||
import type { VendorViewDeleteComplianceReportMutation as DeleteComplianceReportMutationType } from "./__generated__/VendorViewDeleteComplianceReportMutation.graphql";
|
||||
import type { VendorViewUploadComplianceReportMutation as UploadComplianceReportMutationType } from "./__generated__/VendorViewUploadComplianceReportMutation.graphql";
|
||||
import { useParams } from "react-router";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { PageTemplate } from "@/components/PageTemplate";
|
||||
@@ -36,6 +39,20 @@ const vendorViewQuery = graphql`
|
||||
privacyPolicyUrl
|
||||
createdAt
|
||||
updatedAt
|
||||
complianceReports(first: 100)
|
||||
@connection(key: "VendorView_complianceReports") {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
reportName
|
||||
reportDate
|
||||
validUntil
|
||||
fileUrl
|
||||
fileSize
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,6 +78,38 @@ const updateVendorMutation = graphql`
|
||||
}
|
||||
`;
|
||||
|
||||
const deleteComplianceReportMutation = graphql`
|
||||
mutation VendorViewDeleteComplianceReportMutation(
|
||||
$input: DeleteVendorComplianceReportInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
deleteVendorComplianceReport(input: $input) {
|
||||
deletedVendorComplianceReportId @deleteEdge(connections: $connections)
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const uploadComplianceReportMutation = graphql`
|
||||
mutation VendorViewUploadComplianceReportMutation(
|
||||
$input: UploadVendorComplianceReportInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
uploadVendorComplianceReport(input: $input) {
|
||||
vendorComplianceReportEdge @appendEdge(connections: $connections) {
|
||||
node {
|
||||
id
|
||||
reportName
|
||||
reportDate
|
||||
validUntil
|
||||
fileUrl
|
||||
fileSize
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
function EditableField({
|
||||
label,
|
||||
value,
|
||||
@@ -105,6 +154,129 @@ function formatDateForAPI(dateStr: string): string {
|
||||
return date.toISOString();
|
||||
}
|
||||
|
||||
interface ComplianceReport {
|
||||
id: string;
|
||||
reportName: string;
|
||||
reportDate: string;
|
||||
validUntil: string | null | undefined;
|
||||
fileUrl: string;
|
||||
fileSize: number;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
function ComplianceReportsTable({
|
||||
reports,
|
||||
onDelete,
|
||||
onUpload,
|
||||
}: {
|
||||
reports: ComplianceReport[];
|
||||
onDelete: (id: string) => void;
|
||||
onUpload: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
}) {
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
// Truncate filename to a reasonable length if needed
|
||||
const truncateFilename = (filename: string, maxLength = 40) => {
|
||||
if (filename.length <= maxLength) return filename;
|
||||
const extension = filename.split(".").pop();
|
||||
const name = filename.substring(0, maxLength - extension!.length - 3);
|
||||
return `${name}...${extension}`;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<h2 className="text-lg font-medium">Compliance Reports</h2>
|
||||
<p className="text-sm text-secondary">
|
||||
Upload and manage compliance reports for this vendor
|
||||
</p>
|
||||
</div>
|
||||
<div className="rounded-md border">
|
||||
<div className="overflow-hidden">
|
||||
<table className="w-full table-fixed">
|
||||
<thead>
|
||||
<tr className="border-b">
|
||||
<th className="w-2/5 px-4 py-2 text-left text-sm font-medium">
|
||||
Report Name
|
||||
</th>
|
||||
<th className="w-1/5 px-4 py-2 text-left text-sm font-medium">
|
||||
Report Date
|
||||
</th>
|
||||
<th className="w-1/5 px-4 py-2 text-left text-sm font-medium">
|
||||
Valid Until
|
||||
</th>
|
||||
<th className="w-1/5 px-4 py-2 text-left text-sm font-medium">
|
||||
File Size
|
||||
</th>
|
||||
<th className="w-1/5 px-4 py-2 text-left text-sm font-medium">
|
||||
Actions
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{reports.map((report) => (
|
||||
<tr key={report.id} className="border-b">
|
||||
<td className="px-4 py-2">
|
||||
<a
|
||||
href={report.fileUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block text-primary hover:underline"
|
||||
title={report.reportName}
|
||||
>
|
||||
<div className="overflow-hidden text-ellipsis whitespace-nowrap">
|
||||
{truncateFilename(report.reportName)}
|
||||
</div>
|
||||
</a>
|
||||
</td>
|
||||
<td className="px-4 py-2 text-sm">
|
||||
{new Date(report.reportDate).toLocaleDateString()}
|
||||
</td>
|
||||
<td className="px-4 py-2 text-sm">
|
||||
{report.validUntil
|
||||
? new Date(report.validUntil).toLocaleDateString()
|
||||
: "N/A"}
|
||||
</td>
|
||||
<td className="px-4 py-2 text-sm">
|
||||
{(report.fileSize / 1024 / 1024).toFixed(2)} MB
|
||||
</td>
|
||||
<td className="px-4 py-2">
|
||||
<Button
|
||||
variant="destructive"
|
||||
size="sm"
|
||||
onClick={() => onDelete(report.id)}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<input
|
||||
type="file"
|
||||
ref={fileInputRef}
|
||||
className="hidden"
|
||||
onChange={onUpload}
|
||||
accept=".pdf"
|
||||
/>
|
||||
<Button
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
className="bg-primary text-invert hover:bg-primary/90"
|
||||
>
|
||||
Upload New Report
|
||||
</Button>
|
||||
<p className="mt-2 text-sm text-secondary">
|
||||
Only PDF files up to 10MB are allowed
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function VendorViewContent({
|
||||
queryRef,
|
||||
}: {
|
||||
@@ -115,7 +287,6 @@ function VendorViewContent({
|
||||
const [formData, setFormData] = useState({
|
||||
name: data.node.name || "",
|
||||
description: data.node.description || "",
|
||||
// Format dates properly for datetime-local input
|
||||
serviceStartAt: formatDateForInput(data.node.serviceStartAt),
|
||||
serviceTerminationAt: formatDateForInput(data.node.serviceTerminationAt),
|
||||
serviceCriticality: data.node.serviceCriticality,
|
||||
@@ -124,7 +295,15 @@ function VendorViewContent({
|
||||
termsOfServiceUrl: data.node.termsOfServiceUrl || "",
|
||||
privacyPolicyUrl: data.node.privacyPolicyUrl || "",
|
||||
});
|
||||
const [commit] = useMutation(updateVendorMutation);
|
||||
const [updateVendor] = useMutation(updateVendorMutation);
|
||||
const [deleteVendorComplianceReport] =
|
||||
useMutation<DeleteComplianceReportMutationType>(
|
||||
deleteComplianceReportMutation
|
||||
);
|
||||
const [uploadVendorComplianceReport] =
|
||||
useMutation<UploadComplianceReportMutationType>(
|
||||
uploadComplianceReportMutation
|
||||
);
|
||||
const [, loadQuery] = useQueryLoader<VendorViewQueryType>(vendorViewQuery);
|
||||
const { toast } = useToast();
|
||||
|
||||
@@ -139,7 +318,7 @@ function VendorViewContent({
|
||||
: null,
|
||||
};
|
||||
|
||||
commit({
|
||||
updateVendor({
|
||||
variables: {
|
||||
input: {
|
||||
id: data.node.id,
|
||||
@@ -173,7 +352,7 @@ function VendorViewContent({
|
||||
}
|
||||
},
|
||||
});
|
||||
}, [commit, data.node.id, formData, loadQuery, toast]);
|
||||
}, [updateVendor, data.node.id, formData, loadQuery, toast]);
|
||||
|
||||
const handleFieldChange = (field: keyof typeof formData, value: unknown) => {
|
||||
setFormData((prev) => ({
|
||||
@@ -199,6 +378,110 @@ function VendorViewContent({
|
||||
setEditedFields(new Set());
|
||||
};
|
||||
|
||||
const handleDeleteReport = useCallback(
|
||||
(reportId: string) => {
|
||||
deleteVendorComplianceReport({
|
||||
variables: {
|
||||
connections: [
|
||||
ConnectionHandler.getConnectionID(
|
||||
data.node.id!,
|
||||
"VendorView_complianceReports"
|
||||
),
|
||||
],
|
||||
input: {
|
||||
reportId,
|
||||
},
|
||||
},
|
||||
onCompleted: () => {
|
||||
toast({
|
||||
title: "Success",
|
||||
description: "Compliance report deleted successfully",
|
||||
variant: "default",
|
||||
});
|
||||
loadQuery({ vendorId: data.node.id! });
|
||||
},
|
||||
onError: (error) => {
|
||||
toast({
|
||||
title: "Error",
|
||||
description: error.message || "Failed to delete compliance report",
|
||||
variant: "destructive",
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
[deleteVendorComplianceReport, data.node.id, loadQuery, toast]
|
||||
);
|
||||
|
||||
const handleUploadReport = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = event.target.files?.[0];
|
||||
if (!file) return;
|
||||
|
||||
// Validate file type
|
||||
if (file.type !== "application/pdf") {
|
||||
toast({
|
||||
title: "Error",
|
||||
description: "Only PDF files are allowed",
|
||||
variant: "destructive",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate file size (max 10MB)
|
||||
if (file.size > 10 * 1024 * 1024) {
|
||||
toast({
|
||||
title: "Error",
|
||||
description: "File size must be less than 10MB",
|
||||
variant: "destructive",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
const reportDate = new Date().toISOString();
|
||||
|
||||
uploadVendorComplianceReport({
|
||||
variables: {
|
||||
connections: [
|
||||
ConnectionHandler.getConnectionID(
|
||||
data.node.id!,
|
||||
"VendorView_complianceReports"
|
||||
),
|
||||
],
|
||||
input: {
|
||||
vendorId: data.node.id!,
|
||||
reportDate,
|
||||
reportName: file.name,
|
||||
file: null,
|
||||
},
|
||||
},
|
||||
uploadables: {
|
||||
"input.file": file,
|
||||
},
|
||||
onCompleted: () => {
|
||||
toast({
|
||||
title: "Success",
|
||||
description: "Compliance report uploaded successfully",
|
||||
variant: "default",
|
||||
});
|
||||
loadQuery({ vendorId: data.node.id! });
|
||||
},
|
||||
onError: (error) => {
|
||||
toast({
|
||||
title: "Error",
|
||||
description:
|
||||
error.message || "Failed to upload compliance report",
|
||||
variant: "destructive",
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
},
|
||||
[uploadVendorComplianceReport, data.node.id, loadQuery, toast]
|
||||
);
|
||||
|
||||
return (
|
||||
<PageTemplate title={formData.name}>
|
||||
<div className="max-w-2xl space-y-6">
|
||||
@@ -370,6 +653,17 @@ function VendorViewContent({
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card className="p-6">
|
||||
<ComplianceReportsTable
|
||||
reports={
|
||||
data.node.complianceReports?.edges.map((edge) => edge.node) ?? []
|
||||
}
|
||||
onDelete={handleDeleteReport}
|
||||
onUpload={handleUploadReport}
|
||||
/>
|
||||
</Card>
|
||||
|
||||
<div className="mt-6 flex justify-end gap-2">
|
||||
<Button variant="outline" onClick={handleCancel}>
|
||||
Cancel
|
||||
|
||||
132
apps/console/src/pages/organizations/vendors/__generated__/VendorViewDeleteComplianceReportMutation.graphql.ts
generated
vendored
Normal file
132
apps/console/src/pages/organizations/vendors/__generated__/VendorViewDeleteComplianceReportMutation.graphql.ts
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* @generated SignedSource<<a95a2943aea5d692a8f116bef3f91a6f>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type DeleteVendorComplianceReportInput = {
|
||||
reportId: string;
|
||||
};
|
||||
export type VendorViewDeleteComplianceReportMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: DeleteVendorComplianceReportInput;
|
||||
};
|
||||
export type VendorViewDeleteComplianceReportMutation$data = {
|
||||
readonly deleteVendorComplianceReport: {
|
||||
readonly deletedVendorComplianceReportId: string;
|
||||
};
|
||||
};
|
||||
export type VendorViewDeleteComplianceReportMutation = {
|
||||
response: VendorViewDeleteComplianceReportMutation$data;
|
||||
variables: VendorViewDeleteComplianceReportMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deletedVendorComplianceReportId",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "VendorViewDeleteComplianceReportMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "DeleteVendorComplianceReportPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deleteVendorComplianceReport",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "VendorViewDeleteComplianceReportMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "DeleteVendorComplianceReportPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deleteVendorComplianceReport",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "deleteEdge",
|
||||
"key": "",
|
||||
"kind": "ScalarHandle",
|
||||
"name": "deletedVendorComplianceReportId",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "1e41cb2debc83547d78f3dd77236230a",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "VendorViewDeleteComplianceReportMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation VendorViewDeleteComplianceReportMutation(\n $input: DeleteVendorComplianceReportInput!\n) {\n deleteVendorComplianceReport(input: $input) {\n deletedVendorComplianceReportId\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "78d3becac99c6b6d1b65ebb116b0a172";
|
||||
|
||||
export default node;
|
||||
186
apps/console/src/pages/organizations/vendors/__generated__/VendorViewQuery.graphql.ts
generated
vendored
186
apps/console/src/pages/organizations/vendors/__generated__/VendorViewQuery.graphql.ts
generated
vendored
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<61507551e23b8cc70b401cab8ae4e575>>
|
||||
* @generated SignedSource<<e84da0f625c9ae5495a0cb0c99c88c81>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -16,6 +16,19 @@ export type VendorViewQuery$variables = {
|
||||
};
|
||||
export type VendorViewQuery$data = {
|
||||
readonly node: {
|
||||
readonly complianceReports?: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly createdAt: string;
|
||||
readonly fileSize: number;
|
||||
readonly fileUrl: string;
|
||||
readonly id: string;
|
||||
readonly reportDate: string;
|
||||
readonly reportName: string;
|
||||
readonly validUntil: string | null | undefined;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly createdAt?: string;
|
||||
readonly description?: string;
|
||||
readonly id?: string;
|
||||
@@ -133,7 +146,115 @@ v13 = {
|
||||
"kind": "ScalarField",
|
||||
"name": "updatedAt",
|
||||
"storageKey": null
|
||||
};
|
||||
},
|
||||
v14 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v15 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "VendorComplianceReportEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "VendorComplianceReport",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "reportName",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "reportDate",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "validUntil",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fileUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fileSize",
|
||||
"storageKey": null
|
||||
},
|
||||
(v12/*: any*/),
|
||||
(v14/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
v16 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
@@ -163,7 +284,17 @@ return {
|
||||
(v10/*: any*/),
|
||||
(v11/*: any*/),
|
||||
(v12/*: any*/),
|
||||
(v13/*: any*/)
|
||||
(v13/*: any*/),
|
||||
{
|
||||
"alias": "complianceReports",
|
||||
"args": null,
|
||||
"concreteType": "VendorComplianceReportConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__VendorView_complianceReports_connection",
|
||||
"plural": false,
|
||||
"selections": (v15/*: any*/),
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Vendor",
|
||||
"abstractKey": null
|
||||
@@ -189,13 +320,7 @@ return {
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
(v14/*: any*/),
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
@@ -210,7 +335,26 @@ return {
|
||||
(v10/*: any*/),
|
||||
(v11/*: any*/),
|
||||
(v12/*: any*/),
|
||||
(v13/*: any*/)
|
||||
(v13/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v16/*: any*/),
|
||||
"concreteType": "VendorComplianceReportConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "complianceReports",
|
||||
"plural": false,
|
||||
"selections": (v15/*: any*/),
|
||||
"storageKey": "complianceReports(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v16/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "VendorView_complianceReports",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "complianceReports"
|
||||
}
|
||||
],
|
||||
"type": "Vendor",
|
||||
"abstractKey": null
|
||||
@@ -221,16 +365,28 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "40428ff15eb094ffe4cb5ffb5d135cc1",
|
||||
"cacheID": "9d2e53dfbc545614d651819697eda6e6",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"metadata": {
|
||||
"connection": [
|
||||
{
|
||||
"count": null,
|
||||
"cursor": null,
|
||||
"direction": "forward",
|
||||
"path": [
|
||||
"node",
|
||||
"complianceReports"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "VendorViewQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query VendorViewQuery(\n $vendorId: ID!\n) {\n node(id: $vendorId) {\n __typename\n ... on Vendor {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n createdAt\n updatedAt\n }\n id\n }\n}\n"
|
||||
"text": "query VendorViewQuery(\n $vendorId: ID!\n) {\n node(id: $vendorId) {\n __typename\n ... on Vendor {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n createdAt\n updatedAt\n complianceReports(first: 100) {\n edges {\n node {\n id\n reportName\n reportDate\n validUntil\n fileUrl\n fileSize\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "dbef9acdc02dd7e8cd546c0bb8793b9a";
|
||||
(node as any).hash = "110583f1567e472ba6b4a6064be056e9";
|
||||
|
||||
export default node;
|
||||
|
||||
210
apps/console/src/pages/organizations/vendors/__generated__/VendorViewUploadComplianceReportMutation.graphql.ts
generated
vendored
Normal file
210
apps/console/src/pages/organizations/vendors/__generated__/VendorViewUploadComplianceReportMutation.graphql.ts
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
/**
|
||||
* @generated SignedSource<<2bcb17bf1104688db87ac4927bc4c0c7>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type UploadVendorComplianceReportInput = {
|
||||
file: any;
|
||||
reportDate: string;
|
||||
reportName: string;
|
||||
validUntil?: string | null | undefined;
|
||||
vendorId: string;
|
||||
};
|
||||
export type VendorViewUploadComplianceReportMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: UploadVendorComplianceReportInput;
|
||||
};
|
||||
export type VendorViewUploadComplianceReportMutation$data = {
|
||||
readonly uploadVendorComplianceReport: {
|
||||
readonly vendorComplianceReportEdge: {
|
||||
readonly node: {
|
||||
readonly createdAt: string;
|
||||
readonly fileSize: number;
|
||||
readonly fileUrl: string;
|
||||
readonly id: string;
|
||||
readonly reportDate: string;
|
||||
readonly reportName: string;
|
||||
readonly validUntil: string | null | undefined;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
export type VendorViewUploadComplianceReportMutation = {
|
||||
response: VendorViewUploadComplianceReportMutation$data;
|
||||
variables: VendorViewUploadComplianceReportMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "VendorComplianceReportEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "vendorComplianceReportEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "VendorComplianceReport",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "reportName",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "reportDate",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "validUntil",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fileUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fileSize",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "VendorViewUploadComplianceReportMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "UploadVendorComplianceReportPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "uploadVendorComplianceReport",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "VendorViewUploadComplianceReportMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "UploadVendorComplianceReportPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "uploadVendorComplianceReport",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "appendEdge",
|
||||
"key": "",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "vendorComplianceReportEdge",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "6700bbabd4e074cc11d5dc7fa5485ea9",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "VendorViewUploadComplianceReportMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation VendorViewUploadComplianceReportMutation(\n $input: UploadVendorComplianceReportInput!\n) {\n uploadVendorComplianceReport(input: $input) {\n vendorComplianceReportEdge {\n node {\n id\n reportName\n reportDate\n validUntil\n fileUrl\n fileSize\n createdAt\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "1952e347045e900536855a11b826b106";
|
||||
|
||||
export default node;
|
||||
@@ -63,6 +63,7 @@ func (vcs *VendorComplianceReports) LoadForVendorID(
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
vendor_id,
|
||||
report_date,
|
||||
valid_until,
|
||||
report_name,
|
||||
@@ -199,7 +200,8 @@ func (vcr *VendorComplianceReport) Delete(
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
DELETE FROM
|
||||
DELETE
|
||||
FROM
|
||||
vendor_compliance_reports
|
||||
WHERE
|
||||
%s
|
||||
@@ -208,7 +210,8 @@ WHERE
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.NamedArgs{"id": vcr.ID}
|
||||
args := pgx.StrictNamedArgs{"id": vcr.ID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
|
||||
@@ -186,10 +186,16 @@ func (s VendorComplianceReportService) Delete(
|
||||
) error {
|
||||
vendorComplianceReport := &coredata.VendorComplianceReport{ID: vendorComplianceReportID}
|
||||
|
||||
return s.svc.pg.WithConn(
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return vendorComplianceReport.Delete(ctx, conn, s.svc.scope)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot delete vendor compliance report: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user