@@ -12,12 +12,17 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@radix-ui/react-avatar": "^1.1.3",
|
"@radix-ui/react-avatar": "^1.1.3",
|
||||||
|
"@radix-ui/react-checkbox": "^1.0.4",
|
||||||
"@radix-ui/react-collapsible": "^1.1.3",
|
"@radix-ui/react-collapsible": "^1.1.3",
|
||||||
"@radix-ui/react-dialog": "^1.1.6",
|
"@radix-ui/react-dialog": "^1.1.6",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
||||||
|
"@radix-ui/react-label": "^2.0.2",
|
||||||
"@radix-ui/react-progress": "^1.1.2",
|
"@radix-ui/react-progress": "^1.1.2",
|
||||||
|
"@radix-ui/react-radio-group": "^1.1.3",
|
||||||
|
"@radix-ui/react-select": "^2.0.0",
|
||||||
"@radix-ui/react-separator": "^1.1.2",
|
"@radix-ui/react-separator": "^1.1.2",
|
||||||
"@radix-ui/react-slot": "^1.1.2",
|
"@radix-ui/react-slot": "^1.1.2",
|
||||||
|
"@radix-ui/react-toast": "^1.2.6",
|
||||||
"@radix-ui/react-tooltip": "^1.1.8",
|
"@radix-ui/react-tooltip": "^1.1.8",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
@@ -31,11 +36,7 @@
|
|||||||
"react-router": "^7.1.5",
|
"react-router": "^7.1.5",
|
||||||
"relay-runtime": "^18.2.0",
|
"relay-runtime": "^18.2.0",
|
||||||
"tailwind-merge": "^3.0.1",
|
"tailwind-merge": "^3.0.1",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7"
|
||||||
"@radix-ui/react-checkbox": "^1.0.4",
|
|
||||||
"@radix-ui/react-label": "^2.0.2",
|
|
||||||
"@radix-ui/react-radio-group": "^1.1.3",
|
|
||||||
"@radix-ui/react-select": "^2.0.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.26.7",
|
"@babel/core": "^7.26.7",
|
||||||
|
|||||||
127
apps/console/src/components/ui/toast.tsx
Normal file
127
apps/console/src/components/ui/toast.tsx
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import * as ToastPrimitives from "@radix-ui/react-toast"
|
||||||
|
import { cva, type VariantProps } from "class-variance-authority"
|
||||||
|
import { X } from "lucide-react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const ToastProvider = ToastPrimitives.Provider
|
||||||
|
|
||||||
|
const ToastViewport = React.forwardRef<
|
||||||
|
React.ElementRef<typeof ToastPrimitives.Viewport>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<ToastPrimitives.Viewport
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
ToastViewport.displayName = ToastPrimitives.Viewport.displayName
|
||||||
|
|
||||||
|
const toastVariants = cva(
|
||||||
|
"group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
|
||||||
|
{
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
default: "border bg-background text-foreground",
|
||||||
|
destructive:
|
||||||
|
"destructive group border-destructive bg-destructive text-destructive-foreground",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: "default",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const Toast = React.forwardRef<
|
||||||
|
React.ElementRef<typeof ToastPrimitives.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> &
|
||||||
|
VariantProps<typeof toastVariants>
|
||||||
|
>(({ className, variant, ...props }, ref) => {
|
||||||
|
return (
|
||||||
|
<ToastPrimitives.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn(toastVariants({ variant }), className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
Toast.displayName = ToastPrimitives.Root.displayName
|
||||||
|
|
||||||
|
const ToastAction = React.forwardRef<
|
||||||
|
React.ElementRef<typeof ToastPrimitives.Action>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<ToastPrimitives.Action
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
ToastAction.displayName = ToastPrimitives.Action.displayName
|
||||||
|
|
||||||
|
const ToastClose = React.forwardRef<
|
||||||
|
React.ElementRef<typeof ToastPrimitives.Close>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<ToastPrimitives.Close
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
toast-close=""
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<X className="h-4 w-4" />
|
||||||
|
</ToastPrimitives.Close>
|
||||||
|
))
|
||||||
|
ToastClose.displayName = ToastPrimitives.Close.displayName
|
||||||
|
|
||||||
|
const ToastTitle = React.forwardRef<
|
||||||
|
React.ElementRef<typeof ToastPrimitives.Title>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<ToastPrimitives.Title
|
||||||
|
ref={ref}
|
||||||
|
className={cn("text-sm font-semibold [&+div]:text-xs", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
ToastTitle.displayName = ToastPrimitives.Title.displayName
|
||||||
|
|
||||||
|
const ToastDescription = React.forwardRef<
|
||||||
|
React.ElementRef<typeof ToastPrimitives.Description>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<ToastPrimitives.Description
|
||||||
|
ref={ref}
|
||||||
|
className={cn("text-sm opacity-90", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
ToastDescription.displayName = ToastPrimitives.Description.displayName
|
||||||
|
|
||||||
|
type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>
|
||||||
|
|
||||||
|
type ToastActionElement = React.ReactElement<typeof ToastAction>
|
||||||
|
|
||||||
|
export {
|
||||||
|
type ToastProps,
|
||||||
|
type ToastActionElement,
|
||||||
|
ToastProvider,
|
||||||
|
ToastViewport,
|
||||||
|
Toast,
|
||||||
|
ToastTitle,
|
||||||
|
ToastDescription,
|
||||||
|
ToastClose,
|
||||||
|
ToastAction,
|
||||||
|
}
|
||||||
33
apps/console/src/components/ui/toaster.tsx
Normal file
33
apps/console/src/components/ui/toaster.tsx
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { useToast } from "@/hooks/use-toast"
|
||||||
|
import {
|
||||||
|
Toast,
|
||||||
|
ToastClose,
|
||||||
|
ToastDescription,
|
||||||
|
ToastProvider,
|
||||||
|
ToastTitle,
|
||||||
|
ToastViewport,
|
||||||
|
} from "@/components/ui/toast"
|
||||||
|
|
||||||
|
export function Toaster() {
|
||||||
|
const { toasts } = useToast()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ToastProvider>
|
||||||
|
{toasts.map(function ({ id, title, description, action, ...props }) {
|
||||||
|
return (
|
||||||
|
<Toast key={id} {...props}>
|
||||||
|
<div className="grid gap-1">
|
||||||
|
{title && <ToastTitle>{title}</ToastTitle>}
|
||||||
|
{description && (
|
||||||
|
<ToastDescription>{description}</ToastDescription>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{action}
|
||||||
|
<ToastClose />
|
||||||
|
</Toast>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
<ToastViewport />
|
||||||
|
</ToastProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
194
apps/console/src/hooks/use-toast.ts
Normal file
194
apps/console/src/hooks/use-toast.ts
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
// Inspired by react-hot-toast library
|
||||||
|
import * as React from "react"
|
||||||
|
|
||||||
|
import type {
|
||||||
|
ToastActionElement,
|
||||||
|
ToastProps,
|
||||||
|
} from "@/components/ui/toast"
|
||||||
|
|
||||||
|
const TOAST_LIMIT = 1
|
||||||
|
const TOAST_REMOVE_DELAY = 1000000
|
||||||
|
|
||||||
|
type ToasterToast = ToastProps & {
|
||||||
|
id: string
|
||||||
|
title?: React.ReactNode
|
||||||
|
description?: React.ReactNode
|
||||||
|
action?: ToastActionElement
|
||||||
|
}
|
||||||
|
|
||||||
|
const actionTypes = {
|
||||||
|
ADD_TOAST: "ADD_TOAST",
|
||||||
|
UPDATE_TOAST: "UPDATE_TOAST",
|
||||||
|
DISMISS_TOAST: "DISMISS_TOAST",
|
||||||
|
REMOVE_TOAST: "REMOVE_TOAST",
|
||||||
|
} as const
|
||||||
|
|
||||||
|
let count = 0
|
||||||
|
|
||||||
|
function genId() {
|
||||||
|
count = (count + 1) % Number.MAX_SAFE_INTEGER
|
||||||
|
return count.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActionType = typeof actionTypes
|
||||||
|
|
||||||
|
type Action =
|
||||||
|
| {
|
||||||
|
type: ActionType["ADD_TOAST"]
|
||||||
|
toast: ToasterToast
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: ActionType["UPDATE_TOAST"]
|
||||||
|
toast: Partial<ToasterToast>
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: ActionType["DISMISS_TOAST"]
|
||||||
|
toastId?: ToasterToast["id"]
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: ActionType["REMOVE_TOAST"]
|
||||||
|
toastId?: ToasterToast["id"]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
toasts: ToasterToast[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()
|
||||||
|
|
||||||
|
const addToRemoveQueue = (toastId: string) => {
|
||||||
|
if (toastTimeouts.has(toastId)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
toastTimeouts.delete(toastId)
|
||||||
|
dispatch({
|
||||||
|
type: "REMOVE_TOAST",
|
||||||
|
toastId: toastId,
|
||||||
|
})
|
||||||
|
}, TOAST_REMOVE_DELAY)
|
||||||
|
|
||||||
|
toastTimeouts.set(toastId, timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const reducer = (state: State, action: Action): State => {
|
||||||
|
switch (action.type) {
|
||||||
|
case "ADD_TOAST":
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
|
||||||
|
}
|
||||||
|
|
||||||
|
case "UPDATE_TOAST":
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
toasts: state.toasts.map((t) =>
|
||||||
|
t.id === action.toast.id ? { ...t, ...action.toast } : t
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
case "DISMISS_TOAST": {
|
||||||
|
const { toastId } = action
|
||||||
|
|
||||||
|
// ! Side effects ! - This could be extracted into a dismissToast() action,
|
||||||
|
// but I'll keep it here for simplicity
|
||||||
|
if (toastId) {
|
||||||
|
addToRemoveQueue(toastId)
|
||||||
|
} else {
|
||||||
|
state.toasts.forEach((toast) => {
|
||||||
|
addToRemoveQueue(toast.id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
toasts: state.toasts.map((t) =>
|
||||||
|
t.id === toastId || toastId === undefined
|
||||||
|
? {
|
||||||
|
...t,
|
||||||
|
open: false,
|
||||||
|
}
|
||||||
|
: t
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "REMOVE_TOAST":
|
||||||
|
if (action.toastId === undefined) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
toasts: [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
toasts: state.toasts.filter((t) => t.id !== action.toastId),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const listeners: Array<(state: State) => void> = []
|
||||||
|
|
||||||
|
let memoryState: State = { toasts: [] }
|
||||||
|
|
||||||
|
function dispatch(action: Action) {
|
||||||
|
memoryState = reducer(memoryState, action)
|
||||||
|
listeners.forEach((listener) => {
|
||||||
|
listener(memoryState)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type Toast = Omit<ToasterToast, "id">
|
||||||
|
|
||||||
|
function toast({ ...props }: Toast) {
|
||||||
|
const id = genId()
|
||||||
|
|
||||||
|
const update = (props: ToasterToast) =>
|
||||||
|
dispatch({
|
||||||
|
type: "UPDATE_TOAST",
|
||||||
|
toast: { ...props, id },
|
||||||
|
})
|
||||||
|
const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id })
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: "ADD_TOAST",
|
||||||
|
toast: {
|
||||||
|
...props,
|
||||||
|
id,
|
||||||
|
open: true,
|
||||||
|
onOpenChange: (open) => {
|
||||||
|
if (!open) dismiss()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: id,
|
||||||
|
dismiss,
|
||||||
|
update,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function useToast() {
|
||||||
|
const [state, setState] = React.useState<State>(memoryState)
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
listeners.push(setState)
|
||||||
|
return () => {
|
||||||
|
const index = listeners.indexOf(setState)
|
||||||
|
if (index > -1) {
|
||||||
|
listeners.splice(index, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [state])
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
toast,
|
||||||
|
dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { useToast, toast }
|
||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
BreadcrumbProvider,
|
BreadcrumbProvider,
|
||||||
useBreadcrumb,
|
useBreadcrumb,
|
||||||
} from "@/contexts/BreadcrumbContext";
|
} from "@/contexts/BreadcrumbContext";
|
||||||
|
import { Toaster } from "@/components/ui/toaster";
|
||||||
|
|
||||||
function BreadcrumbNavigation() {
|
function BreadcrumbNavigation() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@@ -90,6 +91,7 @@ export default function ConsoleLayout() {
|
|||||||
</header>
|
</header>
|
||||||
<div className="flex flex-1 flex-col gap-4 p-4 pt-0">
|
<div className="flex flex-1 flex-col gap-4 p-4 pt-0">
|
||||||
<Outlet />
|
<Outlet />
|
||||||
|
<Toaster />
|
||||||
</div>
|
</div>
|
||||||
</SidebarInset>
|
</SidebarInset>
|
||||||
</SidebarProvider>
|
</SidebarProvider>
|
||||||
|
|||||||
@@ -2,19 +2,24 @@
|
|||||||
|
|
||||||
import { Card } from "@/components/ui/card";
|
import { Card } from "@/components/ui/card";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { HelpCircle, ArrowUpRight } from "lucide-react";
|
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 {
|
import {
|
||||||
graphql,
|
graphql,
|
||||||
PreloadedQuery,
|
PreloadedQuery,
|
||||||
usePreloadedQuery,
|
usePreloadedQuery,
|
||||||
useQueryLoader,
|
useQueryLoader,
|
||||||
|
useMutation,
|
||||||
} from "react-relay";
|
} from "react-relay";
|
||||||
import { Suspense, useEffect, useState } from "react";
|
import { Suspense, useEffect, useState, useCallback, useMemo } from "react";
|
||||||
import type { VendorOverviewPageQuery as VendorOverviewPageQueryType } from "./__generated__/VendorOverviewPageQuery.graphql";
|
import type { VendorOverviewPageQuery as VendorOverviewPageQueryType } from "./__generated__/VendorOverviewPageQuery.graphql";
|
||||||
import { useParams } from "react-router";
|
import { useParams } from "react-router";
|
||||||
import { Helmet } from "react-helmet-async";
|
import { Helmet } from "react-helmet-async";
|
||||||
import { useBreadcrumb } from "@/contexts/BreadcrumbContext";
|
import { useBreadcrumb } from "@/contexts/BreadcrumbContext";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
import type { UpdateVendorInput } from "./__generated__/VendorOverviewPageUpdateVendorMutation.graphql";
|
||||||
|
|
||||||
const vendorOverviewPageQuery = graphql`
|
const vendorOverviewPageQuery = graphql`
|
||||||
query VendorOverviewPageQuery($vendorId: ID!) {
|
query VendorOverviewPageQuery($vendorId: ID!) {
|
||||||
@@ -32,11 +37,75 @@ const vendorOverviewPageQuery = graphql`
|
|||||||
privacyPolicyUrl
|
privacyPolicyUrl
|
||||||
createdAt
|
createdAt
|
||||||
updatedAt
|
updatedAt
|
||||||
|
version
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const updateVendorMutation = graphql`
|
||||||
|
mutation VendorOverviewPageUpdateVendorMutation($input: UpdateVendorInput!) {
|
||||||
|
updateVendor(input: $input) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
serviceStartAt
|
||||||
|
serviceTerminationAt
|
||||||
|
serviceCriticality
|
||||||
|
riskTier
|
||||||
|
statusPageUrl
|
||||||
|
termsOfServiceUrl
|
||||||
|
privacyPolicyUrl
|
||||||
|
updatedAt
|
||||||
|
version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
function EditableField({
|
||||||
|
label,
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
type = "text",
|
||||||
|
helpText,
|
||||||
|
}: {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
type?: string;
|
||||||
|
helpText?: string;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<HelpCircle className="h-4 w-4 text-gray-400" />
|
||||||
|
<Label className="text-sm">{label}</Label>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Input
|
||||||
|
type={type}
|
||||||
|
value={value}
|
||||||
|
onChange={(e) => onChange(e.target.value)}
|
||||||
|
/>
|
||||||
|
{helpText && <p className="text-sm text-gray-500">{helpText}</p>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format date for input field (YYYY-MM-DDTHH:mm)
|
||||||
|
function formatDateForInput(date: string | null | undefined): string {
|
||||||
|
if (!date) return '';
|
||||||
|
return new Date(date).toISOString().slice(0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format date for API (2006-01-02T15:04:05.999999999Z07:00)
|
||||||
|
function formatDateForAPI(dateStr: string): string {
|
||||||
|
if (!dateStr) return '';
|
||||||
|
const date = new Date(dateStr);
|
||||||
|
return date.toISOString();
|
||||||
|
}
|
||||||
|
|
||||||
function VendorOverviewPageContent({
|
function VendorOverviewPageContent({
|
||||||
queryRef,
|
queryRef,
|
||||||
}: {
|
}: {
|
||||||
@@ -44,8 +113,94 @@ function VendorOverviewPageContent({
|
|||||||
}) {
|
}) {
|
||||||
const data = usePreloadedQuery(vendorOverviewPageQuery, queryRef);
|
const data = usePreloadedQuery(vendorOverviewPageQuery, queryRef);
|
||||||
const { setBreadcrumbSegment } = useBreadcrumb();
|
const { setBreadcrumbSegment } = useBreadcrumb();
|
||||||
const [selectedCriticality, setSelectedCriticality] = useState(data.node.serviceCriticality);
|
const [editedFields, setEditedFields] = useState<Set<string>>(new Set());
|
||||||
const [selectedRiskTier, setSelectedRiskTier] = useState(data.node.riskTier);
|
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,
|
||||||
|
riskTier: data.node.riskTier,
|
||||||
|
statusPageUrl: data.node.statusPageUrl || '',
|
||||||
|
termsOfServiceUrl: data.node.termsOfServiceUrl || '',
|
||||||
|
privacyPolicyUrl: data.node.privacyPolicyUrl || '',
|
||||||
|
});
|
||||||
|
const [commit] = useMutation(updateVendorMutation);
|
||||||
|
const [_, loadQuery] = useQueryLoader<VendorOverviewPageQueryType>(vendorOverviewPageQuery);
|
||||||
|
const { toast } = useToast();
|
||||||
|
|
||||||
|
const hasChanges = editedFields.size > 0;
|
||||||
|
|
||||||
|
const handleSave = useCallback(() => {
|
||||||
|
const formattedData = {
|
||||||
|
...formData,
|
||||||
|
serviceStartAt: formatDateForAPI(formData.serviceStartAt),
|
||||||
|
serviceTerminationAt: formData.serviceTerminationAt ? formatDateForAPI(formData.serviceTerminationAt) : null,
|
||||||
|
};
|
||||||
|
|
||||||
|
commit({
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
id: data.node.id,
|
||||||
|
expectedVersion: data.node.version,
|
||||||
|
...formattedData,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onCompleted: () => {
|
||||||
|
toast({
|
||||||
|
title: "Success",
|
||||||
|
description: "Changes saved successfully",
|
||||||
|
variant: "default",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
if (error.message?.includes('concurrent modification')) {
|
||||||
|
toast({
|
||||||
|
title: "Error",
|
||||||
|
description: "Someone else modified this vendor. Reloading latest data.",
|
||||||
|
variant: "destructive",
|
||||||
|
});
|
||||||
|
|
||||||
|
loadQuery({ vendorId: data.node.id! });
|
||||||
|
|
||||||
|
} else {
|
||||||
|
toast({
|
||||||
|
title: "Error",
|
||||||
|
description: error.message || "Failed to save changes",
|
||||||
|
variant: "destructive",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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) => {
|
||||||
|
setFormData(prev => ({
|
||||||
|
...prev,
|
||||||
|
[field]: value,
|
||||||
|
}));
|
||||||
|
setEditedFields(prev => new Set(prev).add(field));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update the cancel handler to also format dates
|
||||||
|
const handleCancel = () => {
|
||||||
|
setFormData({
|
||||||
|
name: data.node.name || '',
|
||||||
|
description: data.node.description || '',
|
||||||
|
serviceStartAt: formatDateForInput(data.node.serviceStartAt),
|
||||||
|
serviceTerminationAt: formatDateForInput(data.node.serviceTerminationAt),
|
||||||
|
serviceCriticality: data.node.serviceCriticality,
|
||||||
|
riskTier: data.node.riskTier,
|
||||||
|
statusPageUrl: data.node.statusPageUrl || '',
|
||||||
|
termsOfServiceUrl: data.node.termsOfServiceUrl || '',
|
||||||
|
privacyPolicyUrl: data.node.privacyPolicyUrl || '',
|
||||||
|
});
|
||||||
|
setEditedFields(new Set());
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data.node?.name) {
|
if (data.node?.name) {
|
||||||
@@ -54,205 +209,185 @@ function VendorOverviewPageContent({
|
|||||||
}, [data.node?.name, setBreadcrumbSegment]);
|
}, [data.node?.name, setBreadcrumbSegment]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6 p-4 md:p-6 lg:p-8">
|
<>
|
||||||
<div className="mx-auto max-w-4xl space-y-6">
|
<div className="space-y-6 p-4 md:p-6 lg:p-8">
|
||||||
<div className="space-y-2">
|
<div className="mx-auto max-w-4xl space-y-6">
|
||||||
<h1 className="text-xl font-semibold text-gray-900">
|
<EditableField
|
||||||
{data.node.name}
|
label="Name"
|
||||||
</h1>
|
value={formData.name}
|
||||||
<p className="text-gray-600">{data.node.description}</p>
|
onChange={(value) => handleFieldChange('name', value)}
|
||||||
</div>
|
/>
|
||||||
|
|
||||||
<Card className="p-6">
|
<EditableField
|
||||||
<div className="space-y-4">
|
label="Description"
|
||||||
<div className="space-y-2">
|
value={formData.description}
|
||||||
<h2 className="text-lg font-medium">Service Information</h2>
|
onChange={(value) => handleFieldChange('description', value)}
|
||||||
<p className="text-sm text-gray-500">
|
/>
|
||||||
Basic information about the vendor service
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<Card className="p-6">
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="flex items-center gap-2">
|
<h2 className="text-lg font-medium">Service Information</h2>
|
||||||
<HelpCircle className="h-4 w-4 text-gray-400" />
|
<p className="text-sm text-gray-500">
|
||||||
<Label className="text-sm">Service Start Date</Label>
|
Basic information about the vendor service
|
||||||
</div>
|
|
||||||
<p className="text-sm text-gray-600">
|
|
||||||
{new Date(data.node.serviceStartAt).toLocaleDateString()}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{data.node?.serviceTerminationAt && (
|
<div className="space-y-4">
|
||||||
|
<EditableField
|
||||||
|
label="Service Start At"
|
||||||
|
value={formData.serviceStartAt}
|
||||||
|
type="datetime-local"
|
||||||
|
onChange={(value) => handleFieldChange('serviceStartAt', value)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditableField
|
||||||
|
label="Service Termination At"
|
||||||
|
value={formData.serviceTerminationAt}
|
||||||
|
type="datetime-local"
|
||||||
|
onChange={(value) => handleFieldChange('serviceTerminationAt', value)}
|
||||||
|
/>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<HelpCircle className="h-4 w-4 text-gray-400" />
|
<HelpCircle className="h-4 w-4 text-gray-400" />
|
||||||
<Label className="text-sm">Service Termination At</Label>
|
<Label className="text-sm">Service Criticality</Label>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-gray-600">
|
<div className="flex gap-2">
|
||||||
{new Date(data.node.serviceTerminationAt).toLocaleDateString()}
|
<button
|
||||||
|
onClick={() => handleFieldChange('serviceCriticality', 'LOW')}
|
||||||
|
className={cn(
|
||||||
|
"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"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
Low
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => handleFieldChange('serviceCriticality', 'MEDIUM')}
|
||||||
|
className={cn(
|
||||||
|
"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"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
Medium
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => handleFieldChange('serviceCriticality', 'HIGH')}
|
||||||
|
className={cn(
|
||||||
|
"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"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
High
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm text-gray-500">
|
||||||
|
{formData.serviceCriticality === 'HIGH' &&
|
||||||
|
"Critical service - downtime severely impacts end-users"}
|
||||||
|
{formData.serviceCriticality === 'MEDIUM' &&
|
||||||
|
"Important service - downtime moderately affects end-users"}
|
||||||
|
{formData.serviceCriticality === 'LOW' &&
|
||||||
|
"Non-critical service - minimal end-user impact if down"}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<HelpCircle className="h-4 w-4 text-gray-400" />
|
<HelpCircle className="h-4 w-4 text-gray-400" />
|
||||||
<Label className="text-sm">Service Criticality</Label>
|
<Label className="text-sm">Risk Tier</Label>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<button
|
||||||
|
onClick={() => handleFieldChange('riskTier', 'CRITICAL')}
|
||||||
|
className={cn(
|
||||||
|
"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"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
Critical
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => handleFieldChange('riskTier', 'SIGNIFICANT')}
|
||||||
|
className={cn(
|
||||||
|
"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"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
Significant
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => handleFieldChange('riskTier', 'GENERAL')}
|
||||||
|
className={cn(
|
||||||
|
"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"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
General
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm text-gray-500">
|
||||||
|
{formData.riskTier === 'CRITICAL' &&
|
||||||
|
"Handles sensitive data, critical for platform operation"}
|
||||||
|
{formData.riskTier === 'SIGNIFICANT' &&
|
||||||
|
"No user data access, but important for platform management"}
|
||||||
|
{formData.riskTier === 'GENERAL' &&
|
||||||
|
"General vendor with minimal risk"}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-2">
|
|
||||||
<button
|
<EditableField
|
||||||
onClick={() => setSelectedCriticality('LOW')}
|
label="Status Page URL"
|
||||||
className={cn(
|
value={formData.statusPageUrl || ""}
|
||||||
"rounded-full px-4 py-1 text-sm transition-colors",
|
onChange={(value) => handleFieldChange('statusPageUrl', value)}
|
||||||
selectedCriticality === '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"
|
<EditableField
|
||||||
)}
|
label="Terms of Service URL"
|
||||||
>
|
value={formData.termsOfServiceUrl || ""}
|
||||||
Low
|
onChange={(value) => handleFieldChange('termsOfServiceUrl', value)}
|
||||||
</button>
|
/>
|
||||||
<button
|
|
||||||
onClick={() => setSelectedCriticality('MEDIUM')}
|
<EditableField
|
||||||
className={cn(
|
label="Privacy Policy URL"
|
||||||
"rounded-full px-4 py-1 text-sm transition-colors",
|
value={formData.privacyPolicyUrl || ""}
|
||||||
selectedCriticality === 'MEDIUM'
|
onChange={(value) => handleFieldChange('privacyPolicyUrl', value)}
|
||||||
? "bg-yellow-100 text-yellow-900 ring-2 ring-yellow-600 ring-offset-2"
|
/>
|
||||||
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
Medium
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => setSelectedCriticality('HIGH')}
|
|
||||||
className={cn(
|
|
||||||
"rounded-full px-4 py-1 text-sm transition-colors",
|
|
||||||
selectedCriticality === '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"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
High
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<p className="text-sm text-gray-500">
|
|
||||||
{selectedCriticality === 'HIGH' &&
|
|
||||||
"Critical service - downtime severely impacts end-users"}
|
|
||||||
{selectedCriticality === 'MEDIUM' &&
|
|
||||||
"Important service - downtime moderately affects end-users"}
|
|
||||||
{selectedCriticality === 'LOW' &&
|
|
||||||
"Non-critical service - minimal end-user impact if down"}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<HelpCircle className="h-4 w-4 text-gray-400" />
|
|
||||||
<Label className="text-sm">Risk Tier</Label>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<button
|
|
||||||
onClick={() => setSelectedRiskTier('CRITICAL')}
|
|
||||||
className={cn(
|
|
||||||
"rounded-full px-4 py-1 text-sm transition-colors",
|
|
||||||
selectedRiskTier === '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"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
Critical
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => setSelectedRiskTier('SIGNIFICANT')}
|
|
||||||
className={cn(
|
|
||||||
"rounded-full px-4 py-1 text-sm transition-colors",
|
|
||||||
selectedRiskTier === '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"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
Significant
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => setSelectedRiskTier('GENERAL')}
|
|
||||||
className={cn(
|
|
||||||
"rounded-full px-4 py-1 text-sm transition-colors",
|
|
||||||
selectedRiskTier === '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"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
General
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<p className="text-sm text-gray-500">
|
|
||||||
{selectedRiskTier === 'CRITICAL' &&
|
|
||||||
"Handles sensitive data, critical for platform operation"}
|
|
||||||
{selectedRiskTier === 'SIGNIFICANT' &&
|
|
||||||
"No user data access, but important for platform management"}
|
|
||||||
{selectedRiskTier === 'GENERAL' &&
|
|
||||||
"General vendor with minimal risk"}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{data.node?.statusPageUrl && (
|
|
||||||
<div className="space-y-2">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<HelpCircle className="h-4 w-4 text-gray-400" />
|
|
||||||
<Label className="text-sm">Status Page</Label>
|
|
||||||
</div>
|
|
||||||
<a
|
|
||||||
href={data.node.statusPageUrl}
|
|
||||||
className="text-primary hover:underline inline-flex items-center gap-1"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
View Status Page
|
|
||||||
<ArrowUpRight className="h-4 w-4" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{data.node.termsOfServiceUrl && (
|
|
||||||
<div className="space-y-2">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<HelpCircle className="h-4 w-4 text-gray-400" />
|
|
||||||
<Label className="text-sm">Terms of Service</Label>
|
|
||||||
</div>
|
|
||||||
<a
|
|
||||||
href={data.node.termsOfServiceUrl}
|
|
||||||
className="text-primary hover:underline inline-flex items-center gap-1"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
View Terms of Service
|
|
||||||
<ArrowUpRight className="h-4 w-4" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{data.node.privacyPolicyUrl && (
|
|
||||||
<div className="space-y-2">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<HelpCircle className="h-4 w-4 text-gray-400" />
|
|
||||||
<Label className="text-sm">Privacy Policy</Label>
|
|
||||||
</div>
|
|
||||||
<a
|
|
||||||
href={data.node.privacyPolicyUrl}
|
|
||||||
className="text-primary hover:underline inline-flex items-center gap-1"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
View Privacy Policy
|
|
||||||
<ArrowUpRight className="h-4 w-4" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Card>
|
||||||
</Card>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
{hasChanges && (
|
||||||
|
<div className="fixed bottom-6 right-6 flex gap-2">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
onClick={handleCancel}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={handleSave}
|
||||||
|
className="bg-primary text-primary-foreground hover:bg-primary/90"
|
||||||
|
>
|
||||||
|
Save Changes
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<180daebbc0ea7b69991d7bad2005ea13>>
|
* @generated SignedSource<<2d865a3f5deae54eed7c54b08df7bf0a>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -28,6 +28,7 @@ export type VendorOverviewPageQuery$data = {
|
|||||||
readonly statusPageUrl?: string | null | undefined;
|
readonly statusPageUrl?: string | null | undefined;
|
||||||
readonly termsOfServiceUrl?: string | null | undefined;
|
readonly termsOfServiceUrl?: string | null | undefined;
|
||||||
readonly updatedAt?: any;
|
readonly updatedAt?: any;
|
||||||
|
readonly version?: number;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
export type VendorOverviewPageQuery = {
|
export type VendorOverviewPageQuery = {
|
||||||
@@ -133,6 +134,13 @@ v13 = {
|
|||||||
"kind": "ScalarField",
|
"kind": "ScalarField",
|
||||||
"name": "updatedAt",
|
"name": "updatedAt",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
|
},
|
||||||
|
v14 = {
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "version",
|
||||||
|
"storageKey": null
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
"fragment": {
|
"fragment": {
|
||||||
@@ -163,7 +171,8 @@ return {
|
|||||||
(v10/*: any*/),
|
(v10/*: any*/),
|
||||||
(v11/*: any*/),
|
(v11/*: any*/),
|
||||||
(v12/*: any*/),
|
(v12/*: any*/),
|
||||||
(v13/*: any*/)
|
(v13/*: any*/),
|
||||||
|
(v14/*: any*/)
|
||||||
],
|
],
|
||||||
"type": "Vendor",
|
"type": "Vendor",
|
||||||
"abstractKey": null
|
"abstractKey": null
|
||||||
@@ -210,7 +219,8 @@ return {
|
|||||||
(v10/*: any*/),
|
(v10/*: any*/),
|
||||||
(v11/*: any*/),
|
(v11/*: any*/),
|
||||||
(v12/*: any*/),
|
(v12/*: any*/),
|
||||||
(v13/*: any*/)
|
(v13/*: any*/),
|
||||||
|
(v14/*: any*/)
|
||||||
],
|
],
|
||||||
"type": "Vendor",
|
"type": "Vendor",
|
||||||
"abstractKey": null
|
"abstractKey": null
|
||||||
@@ -221,16 +231,16 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "d732d532dc450d86b3e790500c59e0ee",
|
"cacheID": "9163462a149138110e8573e0b28350f9",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "VendorOverviewPageQuery",
|
"name": "VendorOverviewPageQuery",
|
||||||
"operationKind": "query",
|
"operationKind": "query",
|
||||||
"text": "query VendorOverviewPageQuery(\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 VendorOverviewPageQuery(\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 version\n }\n id\n }\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "0b7427451e68a951e2eecbc3f5c59456";
|
(node as any).hash = "56567f61e1016e70d6993ac132ca8382";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
192
apps/console/src/pages/__generated__/VendorOverviewPageUpdateVendorMutation.graphql.ts
generated
Normal file
192
apps/console/src/pages/__generated__/VendorOverviewPageUpdateVendorMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<0c1d84470c9beda41d05161fad1608f2>>
|
||||||
|
* @lightSyntaxTransform
|
||||||
|
* @nogrep
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
|
export type RiskTier = "CRITICAL" | "GENERAL" | "SIGNIFICANT";
|
||||||
|
export type ServiceCriticality = "HIGH" | "LOW" | "MEDIUM";
|
||||||
|
export type UpdateVendorInput = {
|
||||||
|
description?: string | null | undefined;
|
||||||
|
expectedVersion: number;
|
||||||
|
id: string;
|
||||||
|
name?: string | null | undefined;
|
||||||
|
privacyPolicyUrl?: string | null | undefined;
|
||||||
|
riskTier?: RiskTier | null | undefined;
|
||||||
|
serviceCriticality?: ServiceCriticality | null | undefined;
|
||||||
|
serviceStartAt?: any | null | undefined;
|
||||||
|
serviceTerminationAt?: any | null | undefined;
|
||||||
|
statusPageUrl?: string | null | undefined;
|
||||||
|
termsOfServiceUrl?: string | null | undefined;
|
||||||
|
};
|
||||||
|
export type VendorOverviewPageUpdateVendorMutation$variables = {
|
||||||
|
input: UpdateVendorInput;
|
||||||
|
};
|
||||||
|
export type VendorOverviewPageUpdateVendorMutation$data = {
|
||||||
|
readonly updateVendor: {
|
||||||
|
readonly description: string;
|
||||||
|
readonly id: string;
|
||||||
|
readonly name: string;
|
||||||
|
readonly privacyPolicyUrl: string | null | undefined;
|
||||||
|
readonly riskTier: RiskTier;
|
||||||
|
readonly serviceCriticality: ServiceCriticality;
|
||||||
|
readonly serviceStartAt: any;
|
||||||
|
readonly serviceTerminationAt: any | null | undefined;
|
||||||
|
readonly statusPageUrl: string | null | undefined;
|
||||||
|
readonly termsOfServiceUrl: string | null | undefined;
|
||||||
|
readonly updatedAt: any;
|
||||||
|
readonly version: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export type VendorOverviewPageUpdateVendorMutation = {
|
||||||
|
response: VendorOverviewPageUpdateVendorMutation$data;
|
||||||
|
variables: VendorOverviewPageUpdateVendorMutation$variables;
|
||||||
|
};
|
||||||
|
|
||||||
|
const node: ConcreteRequest = (function(){
|
||||||
|
var v0 = [
|
||||||
|
{
|
||||||
|
"defaultValue": null,
|
||||||
|
"kind": "LocalArgument",
|
||||||
|
"name": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
v1 = [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": [
|
||||||
|
{
|
||||||
|
"kind": "Variable",
|
||||||
|
"name": "input",
|
||||||
|
"variableName": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"concreteType": "Vendor",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "updateVendor",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "id",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "name",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "description",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "serviceStartAt",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "serviceTerminationAt",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "serviceCriticality",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "riskTier",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "statusPageUrl",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "termsOfServiceUrl",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "privacyPolicyUrl",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "updatedAt",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "version",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
"fragment": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Fragment",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "VendorOverviewPageUpdateVendorMutation",
|
||||||
|
"selections": (v1/*: any*/),
|
||||||
|
"type": "Mutation",
|
||||||
|
"abstractKey": null
|
||||||
|
},
|
||||||
|
"kind": "Request",
|
||||||
|
"operation": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Operation",
|
||||||
|
"name": "VendorOverviewPageUpdateVendorMutation",
|
||||||
|
"selections": (v1/*: any*/)
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"cacheID": "d0dd4f7b7219b20cc57a57e25b2b1197",
|
||||||
|
"id": null,
|
||||||
|
"metadata": {},
|
||||||
|
"name": "VendorOverviewPageUpdateVendorMutation",
|
||||||
|
"operationKind": "mutation",
|
||||||
|
"text": "mutation VendorOverviewPageUpdateVendorMutation(\n $input: UpdateVendorInput!\n) {\n updateVendor(input: $input) {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n updatedAt\n version\n }\n}\n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
(node as any).hash = "be093542424cdd4a329ec389312d0f83";
|
||||||
|
|
||||||
|
export default node;
|
||||||
35
package-lock.json
generated
35
package-lock.json
generated
@@ -29,6 +29,7 @@
|
|||||||
"@radix-ui/react-select": "^2.0.0",
|
"@radix-ui/react-select": "^2.0.0",
|
||||||
"@radix-ui/react-separator": "^1.1.2",
|
"@radix-ui/react-separator": "^1.1.2",
|
||||||
"@radix-ui/react-slot": "^1.1.2",
|
"@radix-ui/react-slot": "^1.1.2",
|
||||||
|
"@radix-ui/react-toast": "^1.2.6",
|
||||||
"@radix-ui/react-tooltip": "^1.1.8",
|
"@radix-ui/react-tooltip": "^1.1.8",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
@@ -2935,6 +2936,40 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@radix-ui/react-toast": {
|
||||||
|
"version": "1.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-gN4dpuIVKEgpLn1z5FhzT9mYRUitbfZq9XqN/7kkBMUgFTzTG8x/KszWJugJXHcwxckY8xcKDZPz7kG3o6DsUA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/primitive": "1.1.1",
|
||||||
|
"@radix-ui/react-collection": "1.1.2",
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.1",
|
||||||
|
"@radix-ui/react-context": "1.1.1",
|
||||||
|
"@radix-ui/react-dismissable-layer": "1.1.5",
|
||||||
|
"@radix-ui/react-portal": "1.1.4",
|
||||||
|
"@radix-ui/react-presence": "1.1.2",
|
||||||
|
"@radix-ui/react-primitive": "2.0.2",
|
||||||
|
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||||
|
"@radix-ui/react-use-controllable-state": "1.1.0",
|
||||||
|
"@radix-ui/react-use-layout-effect": "1.1.0",
|
||||||
|
"@radix-ui/react-visually-hidden": "1.1.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@radix-ui/react-tooltip": {
|
"node_modules/@radix-ui/react-tooltip": {
|
||||||
"version": "1.1.8",
|
"version": "1.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.8.tgz",
|
||||||
|
|||||||
@@ -116,8 +116,6 @@ type Vendor implements Node {
|
|||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
description: String!
|
description: String!
|
||||||
createdAt: Datetime!
|
|
||||||
updatedAt: Datetime!
|
|
||||||
serviceStartAt: Datetime!
|
serviceStartAt: Datetime!
|
||||||
serviceTerminationAt: Datetime
|
serviceTerminationAt: Datetime
|
||||||
serviceCriticality: ServiceCriticality!
|
serviceCriticality: ServiceCriticality!
|
||||||
@@ -125,6 +123,9 @@ type Vendor implements Node {
|
|||||||
statusPageUrl: String
|
statusPageUrl: String
|
||||||
termsOfServiceUrl: String
|
termsOfServiceUrl: String
|
||||||
privacyPolicyUrl: String
|
privacyPolicyUrl: String
|
||||||
|
createdAt: Datetime!
|
||||||
|
updatedAt: Datetime!
|
||||||
|
version: Int!
|
||||||
}
|
}
|
||||||
|
|
||||||
type FrameworkConnection {
|
type FrameworkConnection {
|
||||||
@@ -313,6 +314,7 @@ type Query {
|
|||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
createVendor(input: CreateVendorInput!): Vendor!
|
createVendor(input: CreateVendorInput!): Vendor!
|
||||||
|
updateVendor(input: UpdateVendorInput!): Vendor!
|
||||||
deleteVendor(input: DeleteVendorInput!): Void!
|
deleteVendor(input: DeleteVendorInput!): Void!
|
||||||
deletePeople(input: DeletePeopleInput!): Void!
|
deletePeople(input: DeletePeopleInput!): Void!
|
||||||
createPeople(input: CreatePeopleInput!): People!
|
createPeople(input: CreatePeopleInput!): People!
|
||||||
@@ -353,6 +355,7 @@ enum RiskTier @goModel(model: "github.com/getprobo/probo/pkg/probo/coredata.Risk
|
|||||||
|
|
||||||
input UpdateVendorInput {
|
input UpdateVendorInput {
|
||||||
id: ID!
|
id: ID!
|
||||||
|
expectedVersion: Int!
|
||||||
name: String
|
name: String
|
||||||
description: String
|
description: String
|
||||||
serviceStartAt: Datetime
|
serviceStartAt: Datetime
|
||||||
@@ -362,4 +365,4 @@ input UpdateVendorInput {
|
|||||||
statusPageUrl: String
|
statusPageUrl: String
|
||||||
termsOfServiceUrl: String
|
termsOfServiceUrl: String
|
||||||
privacyPolicyUrl: String
|
privacyPolicyUrl: String
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ type ComplexityRoot struct {
|
|||||||
CreateVendor func(childComplexity int, input types.CreateVendorInput) int
|
CreateVendor func(childComplexity int, input types.CreateVendorInput) int
|
||||||
DeletePeople func(childComplexity int, input types.DeletePeopleInput) int
|
DeletePeople func(childComplexity int, input types.DeletePeopleInput) int
|
||||||
DeleteVendor func(childComplexity int, input types.DeleteVendorInput) int
|
DeleteVendor func(childComplexity int, input types.DeleteVendorInput) int
|
||||||
|
UpdateVendor func(childComplexity int, input types.UpdateVendorInput) int
|
||||||
}
|
}
|
||||||
|
|
||||||
Organization struct {
|
Organization struct {
|
||||||
@@ -257,6 +258,7 @@ type ComplexityRoot struct {
|
|||||||
StatusPageURL func(childComplexity int) int
|
StatusPageURL func(childComplexity int) int
|
||||||
TermsOfServiceURL func(childComplexity int) int
|
TermsOfServiceURL func(childComplexity int) int
|
||||||
UpdatedAt func(childComplexity int) int
|
UpdatedAt func(childComplexity int) int
|
||||||
|
Version func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
VendorConnection struct {
|
VendorConnection struct {
|
||||||
@@ -282,6 +284,7 @@ type FrameworkResolver interface {
|
|||||||
}
|
}
|
||||||
type MutationResolver interface {
|
type MutationResolver interface {
|
||||||
CreateVendor(ctx context.Context, input types.CreateVendorInput) (*types.Vendor, error)
|
CreateVendor(ctx context.Context, input types.CreateVendorInput) (*types.Vendor, error)
|
||||||
|
UpdateVendor(ctx context.Context, input types.UpdateVendorInput) (*types.Vendor, error)
|
||||||
DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (string, error)
|
DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (string, error)
|
||||||
DeletePeople(ctx context.Context, input types.DeletePeopleInput) (string, error)
|
DeletePeople(ctx context.Context, input types.DeletePeopleInput) (string, error)
|
||||||
CreatePeople(ctx context.Context, input types.CreatePeopleInput) (*types.People, error)
|
CreatePeople(ctx context.Context, input types.CreatePeopleInput) (*types.People, error)
|
||||||
@@ -771,6 +774,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||||||
|
|
||||||
return e.complexity.Mutation.DeleteVendor(childComplexity, args["input"].(types.DeleteVendorInput)), true
|
return e.complexity.Mutation.DeleteVendor(childComplexity, args["input"].(types.DeleteVendorInput)), true
|
||||||
|
|
||||||
|
case "Mutation.updateVendor":
|
||||||
|
if e.complexity.Mutation.UpdateVendor == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
args, err := ec.field_Mutation_updateVendor_args(context.TODO(), rawArgs)
|
||||||
|
if err != nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Mutation.UpdateVendor(childComplexity, args["input"].(types.UpdateVendorInput)), true
|
||||||
|
|
||||||
case "Organization.createdAt":
|
case "Organization.createdAt":
|
||||||
if e.complexity.Organization.CreatedAt == nil {
|
if e.complexity.Organization.CreatedAt == nil {
|
||||||
break
|
break
|
||||||
@@ -1207,6 +1222,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||||||
|
|
||||||
return e.complexity.Vendor.UpdatedAt(childComplexity), true
|
return e.complexity.Vendor.UpdatedAt(childComplexity), true
|
||||||
|
|
||||||
|
case "Vendor.version":
|
||||||
|
if e.complexity.Vendor.Version == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Vendor.Version(childComplexity), true
|
||||||
|
|
||||||
case "VendorConnection.edges":
|
case "VendorConnection.edges":
|
||||||
if e.complexity.VendorConnection.Edges == nil {
|
if e.complexity.VendorConnection.Edges == nil {
|
||||||
break
|
break
|
||||||
@@ -1463,8 +1485,6 @@ type Vendor implements Node {
|
|||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
description: String!
|
description: String!
|
||||||
createdAt: Datetime!
|
|
||||||
updatedAt: Datetime!
|
|
||||||
serviceStartAt: Datetime!
|
serviceStartAt: Datetime!
|
||||||
serviceTerminationAt: Datetime
|
serviceTerminationAt: Datetime
|
||||||
serviceCriticality: ServiceCriticality!
|
serviceCriticality: ServiceCriticality!
|
||||||
@@ -1472,6 +1492,9 @@ type Vendor implements Node {
|
|||||||
statusPageUrl: String
|
statusPageUrl: String
|
||||||
termsOfServiceUrl: String
|
termsOfServiceUrl: String
|
||||||
privacyPolicyUrl: String
|
privacyPolicyUrl: String
|
||||||
|
createdAt: Datetime!
|
||||||
|
updatedAt: Datetime!
|
||||||
|
version: Int!
|
||||||
}
|
}
|
||||||
|
|
||||||
type FrameworkConnection {
|
type FrameworkConnection {
|
||||||
@@ -1660,6 +1683,7 @@ type Query {
|
|||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
createVendor(input: CreateVendorInput!): Vendor!
|
createVendor(input: CreateVendorInput!): Vendor!
|
||||||
|
updateVendor(input: UpdateVendorInput!): Vendor!
|
||||||
deleteVendor(input: DeleteVendorInput!): Void!
|
deleteVendor(input: DeleteVendorInput!): Void!
|
||||||
deletePeople(input: DeletePeopleInput!): Void!
|
deletePeople(input: DeletePeopleInput!): Void!
|
||||||
createPeople(input: CreatePeopleInput!): People!
|
createPeople(input: CreatePeopleInput!): People!
|
||||||
@@ -1700,6 +1724,7 @@ enum RiskTier @goModel(model: "github.com/getprobo/probo/pkg/probo/coredata.Risk
|
|||||||
|
|
||||||
input UpdateVendorInput {
|
input UpdateVendorInput {
|
||||||
id: ID!
|
id: ID!
|
||||||
|
expectedVersion: Int!
|
||||||
name: String
|
name: String
|
||||||
description: String
|
description: String
|
||||||
serviceStartAt: Datetime
|
serviceStartAt: Datetime
|
||||||
@@ -1709,7 +1734,8 @@ input UpdateVendorInput {
|
|||||||
statusPageUrl: String
|
statusPageUrl: String
|
||||||
termsOfServiceUrl: String
|
termsOfServiceUrl: String
|
||||||
privacyPolicyUrl: String
|
privacyPolicyUrl: String
|
||||||
}`, BuiltIn: false},
|
}
|
||||||
|
`, BuiltIn: false},
|
||||||
}
|
}
|
||||||
var parsedSchema = gqlparser.MustLoadSchema(sources...)
|
var parsedSchema = gqlparser.MustLoadSchema(sources...)
|
||||||
|
|
||||||
@@ -2117,6 +2143,29 @@ func (ec *executionContext) field_Mutation_deleteVendor_argsInput(
|
|||||||
return zeroVal, nil
|
return zeroVal, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) field_Mutation_updateVendor_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
||||||
|
var err error
|
||||||
|
args := map[string]any{}
|
||||||
|
arg0, err := ec.field_Mutation_updateVendor_argsInput(ctx, rawArgs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
args["input"] = arg0
|
||||||
|
return args, nil
|
||||||
|
}
|
||||||
|
func (ec *executionContext) field_Mutation_updateVendor_argsInput(
|
||||||
|
ctx context.Context,
|
||||||
|
rawArgs map[string]any,
|
||||||
|
) (types.UpdateVendorInput, error) {
|
||||||
|
ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input"))
|
||||||
|
if tmp, ok := rawArgs["input"]; ok {
|
||||||
|
return ec.unmarshalNUpdateVendorInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateVendorInput(ctx, tmp)
|
||||||
|
}
|
||||||
|
|
||||||
|
var zeroVal types.UpdateVendorInput
|
||||||
|
return zeroVal, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) field_Organization_frameworks_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
func (ec *executionContext) field_Organization_frameworks_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
||||||
var err error
|
var err error
|
||||||
args := map[string]any{}
|
args := map[string]any{}
|
||||||
@@ -4923,10 +4972,6 @@ func (ec *executionContext) fieldContext_Mutation_createVendor(ctx context.Conte
|
|||||||
return ec.fieldContext_Vendor_name(ctx, field)
|
return ec.fieldContext_Vendor_name(ctx, field)
|
||||||
case "description":
|
case "description":
|
||||||
return ec.fieldContext_Vendor_description(ctx, field)
|
return ec.fieldContext_Vendor_description(ctx, field)
|
||||||
case "createdAt":
|
|
||||||
return ec.fieldContext_Vendor_createdAt(ctx, field)
|
|
||||||
case "updatedAt":
|
|
||||||
return ec.fieldContext_Vendor_updatedAt(ctx, field)
|
|
||||||
case "serviceStartAt":
|
case "serviceStartAt":
|
||||||
return ec.fieldContext_Vendor_serviceStartAt(ctx, field)
|
return ec.fieldContext_Vendor_serviceStartAt(ctx, field)
|
||||||
case "serviceTerminationAt":
|
case "serviceTerminationAt":
|
||||||
@@ -4941,6 +4986,12 @@ func (ec *executionContext) fieldContext_Mutation_createVendor(ctx context.Conte
|
|||||||
return ec.fieldContext_Vendor_termsOfServiceUrl(ctx, field)
|
return ec.fieldContext_Vendor_termsOfServiceUrl(ctx, field)
|
||||||
case "privacyPolicyUrl":
|
case "privacyPolicyUrl":
|
||||||
return ec.fieldContext_Vendor_privacyPolicyUrl(ctx, field)
|
return ec.fieldContext_Vendor_privacyPolicyUrl(ctx, field)
|
||||||
|
case "createdAt":
|
||||||
|
return ec.fieldContext_Vendor_createdAt(ctx, field)
|
||||||
|
case "updatedAt":
|
||||||
|
return ec.fieldContext_Vendor_updatedAt(ctx, field)
|
||||||
|
case "version":
|
||||||
|
return ec.fieldContext_Vendor_version(ctx, field)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("no field named %q was found under type Vendor", field.Name)
|
return nil, fmt.Errorf("no field named %q was found under type Vendor", field.Name)
|
||||||
},
|
},
|
||||||
@@ -4953,6 +5004,77 @@ func (ec *executionContext) fieldContext_Mutation_createVendor(ctx context.Conte
|
|||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Mutation_updateVendor(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Mutation_updateVendor(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return ec.resolvers.Mutation().UpdateVendor(rctx, fc.Args["input"].(types.UpdateVendorInput))
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !graphql.HasFieldError(ctx, fc) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*types.Vendor)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNVendor2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐVendor(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Mutation_updateVendor(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Mutation",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: true,
|
||||||
|
IsResolver: true,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
switch field.Name {
|
||||||
|
case "id":
|
||||||
|
return ec.fieldContext_Vendor_id(ctx, field)
|
||||||
|
case "name":
|
||||||
|
return ec.fieldContext_Vendor_name(ctx, field)
|
||||||
|
case "description":
|
||||||
|
return ec.fieldContext_Vendor_description(ctx, field)
|
||||||
|
case "serviceStartAt":
|
||||||
|
return ec.fieldContext_Vendor_serviceStartAt(ctx, field)
|
||||||
|
case "serviceTerminationAt":
|
||||||
|
return ec.fieldContext_Vendor_serviceTerminationAt(ctx, field)
|
||||||
|
case "serviceCriticality":
|
||||||
|
return ec.fieldContext_Vendor_serviceCriticality(ctx, field)
|
||||||
|
case "riskTier":
|
||||||
|
return ec.fieldContext_Vendor_riskTier(ctx, field)
|
||||||
|
case "statusPageUrl":
|
||||||
|
return ec.fieldContext_Vendor_statusPageUrl(ctx, field)
|
||||||
|
case "termsOfServiceUrl":
|
||||||
|
return ec.fieldContext_Vendor_termsOfServiceUrl(ctx, field)
|
||||||
|
case "privacyPolicyUrl":
|
||||||
|
return ec.fieldContext_Vendor_privacyPolicyUrl(ctx, field)
|
||||||
|
case "createdAt":
|
||||||
|
return ec.fieldContext_Vendor_createdAt(ctx, field)
|
||||||
|
case "updatedAt":
|
||||||
|
return ec.fieldContext_Vendor_updatedAt(ctx, field)
|
||||||
|
case "version":
|
||||||
|
return ec.fieldContext_Vendor_version(ctx, field)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("no field named %q was found under type Vendor", field.Name)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
if fc.Args, err = ec.field_Mutation_updateVendor_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return fc, err
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Mutation_deleteVendor(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Mutation_deleteVendor(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||||
fc, err := ec.fieldContext_Mutation_deleteVendor(ctx, field)
|
fc, err := ec.fieldContext_Mutation_deleteVendor(ctx, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -7215,82 +7337,6 @@ func (ec *executionContext) fieldContext_Vendor_description(_ context.Context, f
|
|||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Vendor_createdAt(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) {
|
|
||||||
fc, err := ec.fieldContext_Vendor_createdAt(ctx, field)
|
|
||||||
if err != nil {
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
ctx = graphql.WithFieldContext(ctx, fc)
|
|
||||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
|
||||||
ctx = rctx // use context from middleware stack in children
|
|
||||||
return obj.CreatedAt, nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
ec.Error(ctx, err)
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
if resTmp == nil {
|
|
||||||
if !graphql.HasFieldError(ctx, fc) {
|
|
||||||
ec.Errorf(ctx, "must not be null")
|
|
||||||
}
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
res := resTmp.(time.Time)
|
|
||||||
fc.Result = res
|
|
||||||
return ec.marshalNDatetime2timeᚐTime(ctx, field.Selections, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) fieldContext_Vendor_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
|
||||||
fc = &graphql.FieldContext{
|
|
||||||
Object: "Vendor",
|
|
||||||
Field: field,
|
|
||||||
IsMethod: false,
|
|
||||||
IsResolver: false,
|
|
||||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
|
||||||
return nil, errors.New("field of type Datetime does not have child fields")
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return fc, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) _Vendor_updatedAt(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) {
|
|
||||||
fc, err := ec.fieldContext_Vendor_updatedAt(ctx, field)
|
|
||||||
if err != nil {
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
ctx = graphql.WithFieldContext(ctx, fc)
|
|
||||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
|
||||||
ctx = rctx // use context from middleware stack in children
|
|
||||||
return obj.UpdatedAt, nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
ec.Error(ctx, err)
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
if resTmp == nil {
|
|
||||||
if !graphql.HasFieldError(ctx, fc) {
|
|
||||||
ec.Errorf(ctx, "must not be null")
|
|
||||||
}
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
res := resTmp.(time.Time)
|
|
||||||
fc.Result = res
|
|
||||||
return ec.marshalNDatetime2timeᚐTime(ctx, field.Selections, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) fieldContext_Vendor_updatedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
|
||||||
fc = &graphql.FieldContext{
|
|
||||||
Object: "Vendor",
|
|
||||||
Field: field,
|
|
||||||
IsMethod: false,
|
|
||||||
IsResolver: false,
|
|
||||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
|
||||||
return nil, errors.New("field of type Datetime does not have child fields")
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return fc, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) _Vendor_serviceStartAt(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Vendor_serviceStartAt(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) {
|
||||||
fc, err := ec.fieldContext_Vendor_serviceStartAt(ctx, field)
|
fc, err := ec.fieldContext_Vendor_serviceStartAt(ctx, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -7545,6 +7591,120 @@ func (ec *executionContext) fieldContext_Vendor_privacyPolicyUrl(_ context.Conte
|
|||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Vendor_createdAt(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Vendor_createdAt(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.CreatedAt, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !graphql.HasFieldError(ctx, fc) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(time.Time)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNDatetime2timeᚐTime(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Vendor_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Vendor",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type Datetime does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Vendor_updatedAt(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Vendor_updatedAt(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.UpdatedAt, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !graphql.HasFieldError(ctx, fc) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(time.Time)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNDatetime2timeᚐTime(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Vendor_updatedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Vendor",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type Datetime does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Vendor_version(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Vendor_version(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Version, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !graphql.HasFieldError(ctx, fc) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(int)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNInt2int(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Vendor_version(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Vendor",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type Int does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _VendorConnection_edges(ctx context.Context, field graphql.CollectedField, obj *types.VendorConnection) (ret graphql.Marshaler) {
|
func (ec *executionContext) _VendorConnection_edges(ctx context.Context, field graphql.CollectedField, obj *types.VendorConnection) (ret graphql.Marshaler) {
|
||||||
fc, err := ec.fieldContext_VendorConnection_edges(ctx, field)
|
fc, err := ec.fieldContext_VendorConnection_edges(ctx, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -7714,10 +7874,6 @@ func (ec *executionContext) fieldContext_VendorEdge_node(_ context.Context, fiel
|
|||||||
return ec.fieldContext_Vendor_name(ctx, field)
|
return ec.fieldContext_Vendor_name(ctx, field)
|
||||||
case "description":
|
case "description":
|
||||||
return ec.fieldContext_Vendor_description(ctx, field)
|
return ec.fieldContext_Vendor_description(ctx, field)
|
||||||
case "createdAt":
|
|
||||||
return ec.fieldContext_Vendor_createdAt(ctx, field)
|
|
||||||
case "updatedAt":
|
|
||||||
return ec.fieldContext_Vendor_updatedAt(ctx, field)
|
|
||||||
case "serviceStartAt":
|
case "serviceStartAt":
|
||||||
return ec.fieldContext_Vendor_serviceStartAt(ctx, field)
|
return ec.fieldContext_Vendor_serviceStartAt(ctx, field)
|
||||||
case "serviceTerminationAt":
|
case "serviceTerminationAt":
|
||||||
@@ -7732,6 +7888,12 @@ func (ec *executionContext) fieldContext_VendorEdge_node(_ context.Context, fiel
|
|||||||
return ec.fieldContext_Vendor_termsOfServiceUrl(ctx, field)
|
return ec.fieldContext_Vendor_termsOfServiceUrl(ctx, field)
|
||||||
case "privacyPolicyUrl":
|
case "privacyPolicyUrl":
|
||||||
return ec.fieldContext_Vendor_privacyPolicyUrl(ctx, field)
|
return ec.fieldContext_Vendor_privacyPolicyUrl(ctx, field)
|
||||||
|
case "createdAt":
|
||||||
|
return ec.fieldContext_Vendor_createdAt(ctx, field)
|
||||||
|
case "updatedAt":
|
||||||
|
return ec.fieldContext_Vendor_updatedAt(ctx, field)
|
||||||
|
case "version":
|
||||||
|
return ec.fieldContext_Vendor_version(ctx, field)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("no field named %q was found under type Vendor", field.Name)
|
return nil, fmt.Errorf("no field named %q was found under type Vendor", field.Name)
|
||||||
},
|
},
|
||||||
@@ -9440,7 +9602,7 @@ func (ec *executionContext) unmarshalInputUpdateVendorInput(ctx context.Context,
|
|||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"id", "name", "description", "serviceStartAt", "serviceTerminationAt", "serviceCriticality", "riskTier", "statusPageUrl", "termsOfServiceUrl", "privacyPolicyUrl"}
|
fieldsInOrder := [...]string{"id", "expectedVersion", "name", "description", "serviceStartAt", "serviceTerminationAt", "serviceCriticality", "riskTier", "statusPageUrl", "termsOfServiceUrl", "privacyPolicyUrl"}
|
||||||
for _, k := range fieldsInOrder {
|
for _, k := range fieldsInOrder {
|
||||||
v, ok := asMap[k]
|
v, ok := asMap[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -9454,6 +9616,13 @@ func (ec *executionContext) unmarshalInputUpdateVendorInput(ctx context.Context,
|
|||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
it.ID = data
|
it.ID = data
|
||||||
|
case "expectedVersion":
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("expectedVersion"))
|
||||||
|
data, err := ec.unmarshalNInt2int(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
it.ExpectedVersion = data
|
||||||
case "name":
|
case "name":
|
||||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name"))
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name"))
|
||||||
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
|
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
@@ -10492,6 +10661,13 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
|
|||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
out.Invalids++
|
||||||
}
|
}
|
||||||
|
case "updateVendor":
|
||||||
|
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
|
return ec._Mutation_updateVendor(ctx, field)
|
||||||
|
})
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
out.Invalids++
|
||||||
|
}
|
||||||
case "deleteVendor":
|
case "deleteVendor":
|
||||||
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
return ec._Mutation_deleteVendor(ctx, field)
|
return ec._Mutation_deleteVendor(ctx, field)
|
||||||
@@ -11346,16 +11522,6 @@ func (ec *executionContext) _Vendor(ctx context.Context, sel ast.SelectionSet, o
|
|||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
out.Invalids++
|
||||||
}
|
}
|
||||||
case "createdAt":
|
|
||||||
out.Values[i] = ec._Vendor_createdAt(ctx, field, obj)
|
|
||||||
if out.Values[i] == graphql.Null {
|
|
||||||
out.Invalids++
|
|
||||||
}
|
|
||||||
case "updatedAt":
|
|
||||||
out.Values[i] = ec._Vendor_updatedAt(ctx, field, obj)
|
|
||||||
if out.Values[i] == graphql.Null {
|
|
||||||
out.Invalids++
|
|
||||||
}
|
|
||||||
case "serviceStartAt":
|
case "serviceStartAt":
|
||||||
out.Values[i] = ec._Vendor_serviceStartAt(ctx, field, obj)
|
out.Values[i] = ec._Vendor_serviceStartAt(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
@@ -11379,6 +11545,21 @@ func (ec *executionContext) _Vendor(ctx context.Context, sel ast.SelectionSet, o
|
|||||||
out.Values[i] = ec._Vendor_termsOfServiceUrl(ctx, field, obj)
|
out.Values[i] = ec._Vendor_termsOfServiceUrl(ctx, field, obj)
|
||||||
case "privacyPolicyUrl":
|
case "privacyPolicyUrl":
|
||||||
out.Values[i] = ec._Vendor_privacyPolicyUrl(ctx, field, obj)
|
out.Values[i] = ec._Vendor_privacyPolicyUrl(ctx, field, obj)
|
||||||
|
case "createdAt":
|
||||||
|
out.Values[i] = ec._Vendor_createdAt(ctx, field, obj)
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
out.Invalids++
|
||||||
|
}
|
||||||
|
case "updatedAt":
|
||||||
|
out.Values[i] = ec._Vendor_updatedAt(ctx, field, obj)
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
out.Invalids++
|
||||||
|
}
|
||||||
|
case "version":
|
||||||
|
out.Values[i] = ec._Vendor_version(ctx, field, obj)
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
out.Invalids++
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
panic("unknown field " + strconv.Quote(field.Name))
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
}
|
}
|
||||||
@@ -12730,6 +12911,11 @@ func (ec *executionContext) marshalNTaskStateTransitionEdge2ᚖgithubᚗcomᚋge
|
|||||||
return ec._TaskStateTransitionEdge(ctx, sel, v)
|
return ec._TaskStateTransitionEdge(ctx, sel, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) unmarshalNUpdateVendorInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateVendorInput(ctx context.Context, v any) (types.UpdateVendorInput, error) {
|
||||||
|
res, err := ec.unmarshalInputUpdateVendorInput(ctx, v)
|
||||||
|
return res, graphql.ErrorOnPath(ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalNVendor2githubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐVendor(ctx context.Context, sel ast.SelectionSet, v types.Vendor) graphql.Marshaler {
|
func (ec *executionContext) marshalNVendor2githubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐVendor(ctx context.Context, sel ast.SelectionSet, v types.Vendor) graphql.Marshaler {
|
||||||
return ec._Vendor(ctx, sel, &v)
|
return ec._Vendor(ctx, sel, &v)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ type TaskStateTransitionEdge struct {
|
|||||||
|
|
||||||
type UpdateVendorInput struct {
|
type UpdateVendorInput struct {
|
||||||
ID gid.GID `json:"id"`
|
ID gid.GID `json:"id"`
|
||||||
|
ExpectedVersion int `json:"expectedVersion"`
|
||||||
Name *string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
Description *string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
ServiceStartAt *time.Time `json:"serviceStartAt,omitempty"`
|
ServiceStartAt *time.Time `json:"serviceStartAt,omitempty"`
|
||||||
@@ -255,8 +256,6 @@ type Vendor struct {
|
|||||||
ID gid.GID `json:"id"`
|
ID gid.GID `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
|
||||||
UpdatedAt time.Time `json:"updatedAt"`
|
|
||||||
ServiceStartAt time.Time `json:"serviceStartAt"`
|
ServiceStartAt time.Time `json:"serviceStartAt"`
|
||||||
ServiceTerminationAt *time.Time `json:"serviceTerminationAt,omitempty"`
|
ServiceTerminationAt *time.Time `json:"serviceTerminationAt,omitempty"`
|
||||||
ServiceCriticality coredata.ServiceCriticality `json:"serviceCriticality"`
|
ServiceCriticality coredata.ServiceCriticality `json:"serviceCriticality"`
|
||||||
@@ -264,6 +263,9 @@ type Vendor struct {
|
|||||||
StatusPageURL *string `json:"statusPageUrl,omitempty"`
|
StatusPageURL *string `json:"statusPageUrl,omitempty"`
|
||||||
TermsOfServiceURL *string `json:"termsOfServiceUrl,omitempty"`
|
TermsOfServiceURL *string `json:"termsOfServiceUrl,omitempty"`
|
||||||
PrivacyPolicyURL *string `json:"privacyPolicyUrl,omitempty"`
|
PrivacyPolicyURL *string `json:"privacyPolicyUrl,omitempty"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
|
Version int `json:"version"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Vendor) IsNode() {}
|
func (Vendor) IsNode() {}
|
||||||
|
|||||||
@@ -53,5 +53,6 @@ func NewVendor(v *coredata.Vendor) *Vendor {
|
|||||||
StatusPageURL: v.StatusPageURL,
|
StatusPageURL: v.StatusPageURL,
|
||||||
TermsOfServiceURL: v.TermsOfServiceURL,
|
TermsOfServiceURL: v.TermsOfServiceURL,
|
||||||
PrivacyPolicyURL: v.PrivacyPolicyURL,
|
PrivacyPolicyURL: v.PrivacyPolicyURL,
|
||||||
|
Version: v.Version,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,28 @@ func (r *mutationResolver) CreateVendor(ctx context.Context, input types.CreateV
|
|||||||
return types.NewVendor(vendor), nil
|
return types.NewVendor(vendor), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateVendor is the resolver for the updateVendor field.
|
||||||
|
func (r *mutationResolver) UpdateVendor(ctx context.Context, input types.UpdateVendorInput) (*types.Vendor, error) {
|
||||||
|
vendor, err := r.svc.UpdateVendor(ctx, probo.UpdateVendorRequest{
|
||||||
|
ID: input.ID,
|
||||||
|
ExpectedVersion: input.ExpectedVersion,
|
||||||
|
Name: input.Name,
|
||||||
|
Description: input.Description,
|
||||||
|
ServiceStartAt: input.ServiceStartAt,
|
||||||
|
ServiceTerminationAt: input.ServiceTerminationAt,
|
||||||
|
ServiceCriticality: input.ServiceCriticality,
|
||||||
|
RiskTier: input.RiskTier,
|
||||||
|
StatusPageURL: input.StatusPageURL,
|
||||||
|
TermsOfServiceURL: input.TermsOfServiceURL,
|
||||||
|
PrivacyPolicyURL: input.PrivacyPolicyURL,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot update vendor: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return types.NewVendor(vendor), nil
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteVendor is the resolver for the deleteVendor field.
|
// DeleteVendor is the resolver for the deleteVendor field.
|
||||||
func (r *mutationResolver) DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (string, error) {
|
func (r *mutationResolver) DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (string, error) {
|
||||||
err := r.svc.DeleteVendor(ctx, input.VendorID)
|
err := r.svc.DeleteVendor(ctx, input.VendorID)
|
||||||
|
|||||||
1
pkg/probo/coredata/migrations/20250218T121700Z.sql
Normal file
1
pkg/probo/coredata/migrations/20250218T121700Z.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE vendors ADD COLUMN version INTEGER NOT NULL DEFAULT 1;
|
||||||
@@ -16,6 +16,7 @@ package coredata
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"maps"
|
"maps"
|
||||||
"time"
|
"time"
|
||||||
@@ -26,6 +27,8 @@ import (
|
|||||||
"go.gearno.de/kit/pg"
|
"go.gearno.de/kit/pg"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrConcurrentModification = errors.New("concurrent modification")
|
||||||
|
|
||||||
type (
|
type (
|
||||||
Vendor struct {
|
Vendor struct {
|
||||||
ID gid.GID
|
ID gid.GID
|
||||||
@@ -41,9 +44,23 @@ type (
|
|||||||
PrivacyPolicyURL *string
|
PrivacyPolicyURL *string
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
|
Version int
|
||||||
}
|
}
|
||||||
|
|
||||||
Vendors []*Vendor
|
Vendors []*Vendor
|
||||||
|
|
||||||
|
UpdateVendorParams struct {
|
||||||
|
ExpectedVersion int
|
||||||
|
Name *string
|
||||||
|
Description *string
|
||||||
|
ServiceStartAt *time.Time
|
||||||
|
ServiceTerminationAt *time.Time
|
||||||
|
ServiceCriticality *ServiceCriticality
|
||||||
|
RiskTier *RiskTier
|
||||||
|
StatusPageURL *string
|
||||||
|
TermsOfServiceURL *string
|
||||||
|
PrivacyPolicyURL *string
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (v Vendor) CursorKey() page.CursorKey {
|
func (v Vendor) CursorKey() page.CursorKey {
|
||||||
@@ -65,6 +82,7 @@ func (v *Vendor) scan(r pgx.Row) error {
|
|||||||
&v.PrivacyPolicyURL,
|
&v.PrivacyPolicyURL,
|
||||||
&v.CreatedAt,
|
&v.CreatedAt,
|
||||||
&v.UpdatedAt,
|
&v.UpdatedAt,
|
||||||
|
&v.Version,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +106,8 @@ SELECT
|
|||||||
terms_of_service_url,
|
terms_of_service_url,
|
||||||
privacy_policy_url,
|
privacy_policy_url,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at,
|
||||||
|
version
|
||||||
FROM
|
FROM
|
||||||
vendors
|
vendors
|
||||||
WHERE
|
WHERE
|
||||||
@@ -133,7 +152,8 @@ INSERT INTO
|
|||||||
terms_of_service_url,
|
terms_of_service_url,
|
||||||
privacy_policy_url,
|
privacy_policy_url,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at,
|
||||||
|
version
|
||||||
)
|
)
|
||||||
VALUES (
|
VALUES (
|
||||||
@vendor_id,
|
@vendor_id,
|
||||||
@@ -148,7 +168,8 @@ VALUES (
|
|||||||
@terms_of_service_url,
|
@terms_of_service_url,
|
||||||
@privacy_policy_url,
|
@privacy_policy_url,
|
||||||
@created_at,
|
@created_at,
|
||||||
@updated_at
|
@updated_at,
|
||||||
|
1
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
@@ -210,7 +231,8 @@ SELECT
|
|||||||
terms_of_service_url,
|
terms_of_service_url,
|
||||||
privacy_policy_url,
|
privacy_policy_url,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at,
|
||||||
|
version
|
||||||
FROM
|
FROM
|
||||||
vendors
|
vendors
|
||||||
WHERE
|
WHERE
|
||||||
@@ -249,3 +271,93 @@ WHERE
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *Vendor) Update(
|
||||||
|
ctx context.Context,
|
||||||
|
conn pg.Conn,
|
||||||
|
scope *Scope,
|
||||||
|
params UpdateVendorParams,
|
||||||
|
) error {
|
||||||
|
q := `
|
||||||
|
UPDATE vendors SET
|
||||||
|
name = COALESCE(@name, name),
|
||||||
|
description = COALESCE(@description, description),
|
||||||
|
service_start_at = COALESCE(@service_start_at, service_start_at),
|
||||||
|
service_termination_at = COALESCE(@service_termination_at, service_termination_at),
|
||||||
|
service_criticality = COALESCE(@service_criticality, service_criticality),
|
||||||
|
risk_tier = COALESCE(@risk_tier, risk_tier),
|
||||||
|
status_page_url = COALESCE(@status_page_url, status_page_url),
|
||||||
|
terms_of_service_url = COALESCE(@terms_of_service_url, terms_of_service_url),
|
||||||
|
privacy_policy_url = COALESCE(@privacy_policy_url, privacy_policy_url),
|
||||||
|
updated_at = @updated_at,
|
||||||
|
version = version + 1
|
||||||
|
WHERE %s
|
||||||
|
AND id = @vendor_id
|
||||||
|
AND version = @expected_version
|
||||||
|
RETURNING
|
||||||
|
id,
|
||||||
|
organization_id,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
service_start_at,
|
||||||
|
service_termination_at,
|
||||||
|
service_criticality,
|
||||||
|
risk_tier,
|
||||||
|
status_page_url,
|
||||||
|
terms_of_service_url,
|
||||||
|
privacy_policy_url,
|
||||||
|
created_at,
|
||||||
|
updated_at,
|
||||||
|
version
|
||||||
|
`
|
||||||
|
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||||
|
|
||||||
|
args := pgx.NamedArgs{
|
||||||
|
"vendor_id": v.ID,
|
||||||
|
"expected_version": params.ExpectedVersion,
|
||||||
|
"updated_at": time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Name != nil {
|
||||||
|
args["name"] = *params.Name
|
||||||
|
}
|
||||||
|
if params.Description != nil {
|
||||||
|
args["description"] = *params.Description
|
||||||
|
}
|
||||||
|
if params.ServiceStartAt != nil {
|
||||||
|
args["service_start_at"] = *params.ServiceStartAt
|
||||||
|
}
|
||||||
|
if params.ServiceTerminationAt != nil {
|
||||||
|
args["service_termination_at"] = *params.ServiceTerminationAt
|
||||||
|
}
|
||||||
|
if params.ServiceCriticality != nil {
|
||||||
|
args["service_criticality"] = *params.ServiceCriticality
|
||||||
|
}
|
||||||
|
if params.RiskTier != nil {
|
||||||
|
args["risk_tier"] = *params.RiskTier
|
||||||
|
}
|
||||||
|
if params.StatusPageURL != nil {
|
||||||
|
args["status_page_url"] = *params.StatusPageURL
|
||||||
|
}
|
||||||
|
if params.TermsOfServiceURL != nil {
|
||||||
|
args["terms_of_service_url"] = *params.TermsOfServiceURL
|
||||||
|
}
|
||||||
|
if params.PrivacyPolicyURL != nil {
|
||||||
|
args["privacy_policy_url"] = *params.PrivacyPolicyURL
|
||||||
|
}
|
||||||
|
|
||||||
|
maps.Copy(args, scope.SQLArguments())
|
||||||
|
|
||||||
|
r := conn.QueryRow(ctx, q, args)
|
||||||
|
|
||||||
|
v2 := Vendor{}
|
||||||
|
if err := v2.scan(r); err != nil {
|
||||||
|
if errors.Is(err, pgx.ErrNoRows) {
|
||||||
|
return ErrConcurrentModification
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*v = v2
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
55
pkg/probo/update_vendor.go
Normal file
55
pkg/probo/update_vendor.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package probo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/getprobo/probo/pkg/gid"
|
||||||
|
"github.com/getprobo/probo/pkg/probo/coredata"
|
||||||
|
"go.gearno.de/kit/pg"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdateVendorRequest struct {
|
||||||
|
ID gid.GID
|
||||||
|
ExpectedVersion int
|
||||||
|
Name *string
|
||||||
|
Description *string
|
||||||
|
ServiceStartAt *time.Time
|
||||||
|
ServiceTerminationAt *time.Time
|
||||||
|
ServiceCriticality *coredata.ServiceCriticality
|
||||||
|
RiskTier *coredata.RiskTier
|
||||||
|
StatusPageURL *string
|
||||||
|
TermsOfServiceURL *string
|
||||||
|
PrivacyPolicyURL *string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Service) UpdateVendor(
|
||||||
|
ctx context.Context,
|
||||||
|
req UpdateVendorRequest,
|
||||||
|
) (*coredata.Vendor, error) {
|
||||||
|
params := coredata.UpdateVendorParams{
|
||||||
|
ExpectedVersion: req.ExpectedVersion,
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
ServiceStartAt: req.ServiceStartAt,
|
||||||
|
ServiceTerminationAt: req.ServiceTerminationAt,
|
||||||
|
ServiceCriticality: req.ServiceCriticality,
|
||||||
|
RiskTier: req.RiskTier,
|
||||||
|
StatusPageURL: req.StatusPageURL,
|
||||||
|
TermsOfServiceURL: req.TermsOfServiceURL,
|
||||||
|
PrivacyPolicyURL: req.PrivacyPolicyURL,
|
||||||
|
}
|
||||||
|
|
||||||
|
vendor := &coredata.Vendor{ID: req.ID}
|
||||||
|
|
||||||
|
err := s.pg.WithTx(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return vendor.Update(ctx, conn, s.scope, params)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return vendor, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user