瀏覽代碼

update function started.

Tomi Cvetic 5 年之前
父節點
當前提交
159f17fb08

+ 5 - 1
backend/schema.graphql

@@ -72,11 +72,15 @@ type Mutation {
     title: String!
     type: TrainingTypeCreateOneInput!
     trainingDate: DateTime!
-    location: String
+    location: String!
     attendance: Int
     published: Boolean!
     blocks: BlockInstanceCreateManyWithoutParentTrainingInput
   ): Training!
+  updateTraining(
+    where: TrainingWhereUniqueInput!
+    data: TrainingUpdateInput!
+  ): Training!
   createTrainingType(name: String!, description: String!): TrainingType!
   # createBlock(
   #   title: String!

+ 5 - 1
backend/src/training/resolvers.ts

@@ -33,13 +33,17 @@ export const resolvers: IResolvers = {
   Mutation: {
     createTraining: async (parent, args, context, info) => {
       checkPermission(context, ['INSTRUCTOR', 'ADMIN'])
-      console.log(inspect(args, false, null, true))
       const training = await context.db.mutation.createTraining(
         { data: args },
         info
       )
       return training
     },
+    updateTraining: async (parent, args, context, info) => {
+      checkPermission(context, ['INSTRUCTOR', 'ADMIN'])
+      const training = await context.db.mutation.updateTraining(args, info)
+      return training
+    },
     createTrainingType: async (parent, args, context, info) => {
       checkPermission(context, ['INSTRUCTOR', 'ADMIN'])
       const trainingType = await context.db.mutation.createTrainingType(

文件差異過大導致無法顯示
+ 899 - 4
frontend/src/gql/index.tsx


+ 88 - 0
frontend/src/lib/arrays.ts

@@ -0,0 +1,88 @@
+import { transform, isEqual, isObject, get } from 'lodash'
+
+type Dict = {
+  [key: string]: boolean | Dict
+}
+
+export function diff(newObject: any = {}, oldObject: any = {}, ignore?: Dict) {
+  const currentIgnoreList = ignore
+    ? Object.entries(ignore).reduce(
+        (accumulator, [key, value]) =>
+          typeof value === 'boolean' ? [...accumulator, key] : accumulator,
+        [] as string[]
+      )
+    : []
+  const transformResult = transform(newObject, (result: any, value: any, key: string) => {
+    if (!currentIgnoreList.includes(key) && !isEqual(value, oldObject[key])) {
+      const child = ignore && ignore[key]
+      let childIgnoreList
+      if (result instanceof Array) {
+        childIgnoreList = ignore
+      } else if (typeof child !== 'boolean') {
+        childIgnoreList = child
+      } else {
+        childIgnoreList = undefined
+      }
+      const newValue =
+        isObject(value) && isObject(oldObject[key])
+          ? diff(value, oldObject[key], childIgnoreList)
+          : value
+      if (typeof newValue === 'boolean' || !!newValue) result[key] = newValue
+    }
+  })
+  return Object.keys(transformResult).length > 0 ? transformResult : undefined
+}
+
+export function deepDiff(newObject: any = {}, oldObject: any = {}, ignore?: Dict) {
+  return {
+    added: diff(newObject, oldObject, ignore),
+    removed: diff(oldObject, newObject, ignore),
+  }
+}
+
+interface IcompareOptions<T> {
+  compareKeys: (keyof T)[]
+  diffIgnore?: Dict
+  keyNames?: {
+    inA: string
+    inB: string
+  }
+}
+
+export function compare<T>(objectsA: T[], objectsB: T[], compareOptions: IcompareOptions<T>) {
+  const { keyNames, diffIgnore, compareKeys } = compareOptions
+  const { inA, inB } = keyNames || { inA: 'inFile', inB: 'inDb' }
+  let copyB = [...objectsB]
+  let copyA: T[] = []
+  for (let objectA of objectsA) {
+    const idxObjectB = copyB.findIndex(objectB =>
+      compareKeys.reduce((accumulator, value) => {
+        console.log(get)
+        return accumulator && get(objectA, value, 1) === get(objectB, value, 2)
+      }, true as boolean)
+    )
+    const objectB = copyB[idxObjectB]
+    copyB = [...copyB.slice(0, idxObjectB), ...copyB.slice(idxObjectB + 1)]
+    copyA = [
+      ...copyA,
+      {
+        ...objectA,
+        changes: deepDiff(objectA, objectB, diffIgnore),
+        [inA]: true,
+        [inB]: !!objectB,
+      },
+    ]
+  }
+  for (let objectB of copyB) {
+    copyA = [
+      ...copyA,
+      {
+        ...objectB,
+        changes: deepDiff(undefined, objectB, diffIgnore),
+        [inA]: false,
+        [inB]: true,
+      },
+    ]
+  }
+  return copyA
+}

+ 18 - 7
frontend/src/training/components/EditTraining.tsx

@@ -1,28 +1,39 @@
-import { useCreateTrainingMutation, Training } from '../../gql'
+import { useCreateTrainingMutation, useUpdateTrainingMutation } from '../../gql'
 import { useForm, TextInput, DateTimeInput, Checkbox } from '../../form'
 import { emptyTraining, emptyBlockInstance, transformArrayToDB } from '../utils'
 import TrainingTypeSelector from './TrainingTypeSelector'
 import BlockInstanceInputs from './BlockInstanceInputs'
 import { TTraining } from '../types'
-import { transform, isArray } from 'lodash'
+import { transform } from 'lodash'
+import { diff } from '../../lib/arrays'
 
 const EditTraining = ({ training }: { training?: TTraining }) => {
   const { values, touched, onChange, loadData } = useForm(
     training || emptyTraining()
   )
   const [createTraining, createData] = useCreateTrainingMutation()
-  //const [updateTraining, updateDate] = useUpdateTrainingMutation()
+  const [updateTraining, updateDate] = useUpdateTrainingMutation()
 
   return (
     <form
       onSubmit={ev => {
         ev.preventDefault()
-        const newValues = transform(values, transformArrayToDB)
-        console.log(newValues)
-        if (!values.id.startsWith('++')) {
+        if (values.id.startsWith('++')) {
+          const newValues = transform(values, transformArrayToDB)
+          console.log(newValues)
           createTraining({ variables: newValues })
         } else {
-          //updateTraining({variables: newValues})
+          const changes = diff(values, training || emptyTraining())
+          const newValues = transform(changes, transformArrayToDB)
+          console.log(newValues)
+          if (Object.keys(newValues).length > 0) {
+            console.log('saving changes', newValues)
+            updateTraining({
+              variables: { where: { id: values.id }, data: newValues }
+            })
+          } else {
+            console.log('no changes.')
+          }
         }
       }}
     >

+ 9 - 0
frontend/src/training/training.graphql

@@ -160,6 +160,15 @@ mutation createTraining(
   }
 }
 
+mutation updateTraining(
+  $where: TrainingWhereUniqueInput!
+  $data: TrainingUpdateInput!
+) {
+  updateTraining(where: $where, data: $data) {
+    id
+  }
+}
+
 mutation createTrainingType($name: String!, $description: String!) {
   createTrainingType(name: $name, description: $description) {
     id

部分文件因文件數量過多而無法顯示