-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgeneric-repo.ts
68 lines (59 loc) · 2.63 KB
/
generic-repo.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import { Repository } from 'pinia-orm'
import { api } from 'src/boot/axios'
import iRecord from './i-record'
import { useAuthenticationStore } from '../authentication/pinia-authentication'
interface SimpleApiBackedRepo {
// requiring this because UI tries to update before async function is even done.
// TODO: there might be a way to properly await onDialogOK in particular (perhaps by making the q.dialog async)
loaded: boolean
// TODO: access T.entity somehow. In the meantime just have a string property.
apidir: string
}
// iCreateT is basically the model's mandatory fields minus id since a new object won't be assigned an ID yet.
// T can implement iCreateT but what really matters is iCreateT should be what that API expects
// todo: support optional UUID client-side id generation
export default class CustomRepo<iCreateT, T extends iRecord> extends Repository<T> implements SimpleApiBackedRepo {
loaded = false
apidir = ''
// todo: use DI perhaps, to specify the shape of a headers provider
// todo: handle null/undefined commonHeader in case of none required
// todo: place common header in all calls
commonHeader = () => {
const auth = useAuthenticationStore()
return { headers: auth.bearerToken }
}
highestID = () => {
// todo: it would be nice if id wasn't always nullable. Perhaps Model could make id not-null
return this.all().reduce((max, x) => (x.id ?? 0) > (max.id ?? 0) ? x : max)
}
fetch = async () => {
this.loaded = false
const response = await api.get(`/${this.apidir}`)
console.log(response.data as T[])
this.fresh(response.data as T[])
this.loaded = true
return response
}
add = async (newItem: iCreateT) => {
console.debug('add item: ', { newItem })
const response = await api.post(`/${this.apidir}`, newItem)
console.debug('response: ', response)
this.save(response.data)
}
delete = async (id: number) => {
// todo: debug, info, and error handling
return await api.delete(`/${this.apidir}/${id}`)
}
update = async (newItemValue: T) => {
// todo: debug, info, and error handling
return await api.patch(`/${this.apidir}/${newItemValue.id}`)
}
// includeEntity: name of entity to include. * invokes withAll. ** invokes withAllRecursive.
// todo: test if this sorts the store in-place
sorted = (sort: (a: T, b: T) => number, includeEntity?: string) => {
if (typeof includeEntity === 'undefined') return this.all().sort(sort)
if (includeEntity === '**') return this.withAllRecursive().get().sort(sort)
if (includeEntity === '*') return this.withAll().get().sort(sort)
return this.with(includeEntity).get().sort(sort)
}
}