@kaspernj/api-maker 1.0.326 → 1.0.327
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/collection-loader.jsx +27 -5
- package/src/event-updated.jsx +18 -67
- package/src/use-collection.mjs +36 -39
- package/src/use-created-event.mjs +1 -1
- package/src/use-updated-event.mjs +58 -0
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
]
|
|
17
17
|
},
|
|
18
18
|
"name": "@kaspernj/api-maker",
|
|
19
|
-
"version": "1.0.
|
|
19
|
+
"version": "1.0.327",
|
|
20
20
|
"type": "module",
|
|
21
21
|
"description": "",
|
|
22
22
|
"main": "index.js",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"js-money": ">= 0.6.3",
|
|
50
50
|
"numberable": ">= 1.0.0",
|
|
51
51
|
"object-to-formdata": ">= 4.1.0",
|
|
52
|
-
"on-location-changed": ">= 1.0.
|
|
52
|
+
"on-location-changed": ">= 1.0.9",
|
|
53
53
|
"qs": ">= 6.9.3",
|
|
54
54
|
"replaceall": ">= 0.1.6",
|
|
55
55
|
"set-state-compare": ">= 1.0.28",
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import Collection from "./collection.mjs"
|
|
1
2
|
import {digg} from "diggerize"
|
|
2
3
|
import {memo, useEffect} from "react"
|
|
4
|
+
import PropTypes from "prop-types"
|
|
5
|
+
import PropTypesExact from "prop-types-exact"
|
|
3
6
|
import useCollection from "./use-collection"
|
|
4
7
|
import useShape from "set-state-compare/src/use-shape.js"
|
|
5
8
|
|
|
6
|
-
const CollectionLoader = (
|
|
7
|
-
const s = useShape(
|
|
8
|
-
const useCollectionResult = useCollection(
|
|
9
|
+
const CollectionLoader = ({component, ...restProps}) => {
|
|
10
|
+
const s = useShape(restProps)
|
|
11
|
+
const useCollectionResult = useCollection(restProps)
|
|
9
12
|
const cachePartsKeys = [
|
|
10
13
|
"modelIdsCacheString",
|
|
11
14
|
"overallCount",
|
|
@@ -25,10 +28,10 @@ const CollectionLoader = (props) => {
|
|
|
25
28
|
cacheParts.push(digg(useCollectionResult, cachePartsKey))
|
|
26
29
|
}
|
|
27
30
|
|
|
28
|
-
s.updateMeta({useCollectionResult})
|
|
31
|
+
s.updateMeta({component, useCollectionResult})
|
|
29
32
|
|
|
30
33
|
useEffect(() => {
|
|
31
|
-
const componentShape = digg(s.
|
|
34
|
+
const componentShape = digg(s.m.component, "shape")
|
|
32
35
|
|
|
33
36
|
componentShape.set(s.m.useCollectionResult)
|
|
34
37
|
}, cacheParts)
|
|
@@ -36,4 +39,23 @@ const CollectionLoader = (props) => {
|
|
|
36
39
|
return null
|
|
37
40
|
}
|
|
38
41
|
|
|
42
|
+
CollectionLoader.propTypes = PropTypesExact({
|
|
43
|
+
abilities: PropTypes.object,
|
|
44
|
+
collection: PropTypes.instanceOf(Collection),
|
|
45
|
+
component: PropTypes.object.isRequired,
|
|
46
|
+
defaultParams: PropTypes.object,
|
|
47
|
+
groupBy: PropTypes.array,
|
|
48
|
+
modelClass: PropTypes.func.isRequired,
|
|
49
|
+
noRecordsAvailableContent: PropTypes.func,
|
|
50
|
+
noRecordsFoundContent: PropTypes.func,
|
|
51
|
+
onModelsLoaded: PropTypes.func,
|
|
52
|
+
pagination: PropTypes.bool.isRequired,
|
|
53
|
+
preloads: PropTypes.array.isRequired,
|
|
54
|
+
queryMethod: PropTypes.func,
|
|
55
|
+
queryName: PropTypes.string,
|
|
56
|
+
ransack: PropTypes.object,
|
|
57
|
+
select: PropTypes.object,
|
|
58
|
+
selectColumns: PropTypes.object
|
|
59
|
+
})
|
|
60
|
+
|
|
39
61
|
export default memo(CollectionLoader)
|
package/src/event-updated.jsx
CHANGED
|
@@ -1,72 +1,23 @@
|
|
|
1
|
-
import debounce from "debounce"
|
|
2
|
-
import ModelEvents from "./model-events.mjs"
|
|
3
1
|
import PropTypes from "prop-types"
|
|
4
2
|
import propTypesExact from "prop-types-exact"
|
|
5
|
-
import
|
|
3
|
+
import {memo} from "react"
|
|
4
|
+
import useUpdatedEvent from "./use-updated-event.mjs"
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
active: true
|
|
10
|
-
}
|
|
6
|
+
const ApiMakerEventUpdated = ({model, onUpdated, ...restProps}) => {
|
|
7
|
+
useUpdatedEvent(model, onUpdated, restProps)
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
active: PropTypes.bool.isRequired,
|
|
14
|
-
debounce: PropTypes.oneOfType([
|
|
15
|
-
PropTypes.bool,
|
|
16
|
-
PropTypes.number
|
|
17
|
-
]),
|
|
18
|
-
model: PropTypes.object.isRequired,
|
|
19
|
-
onConnected: PropTypes.func,
|
|
20
|
-
onUpdated: PropTypes.func.isRequired
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
componentDidMount () {
|
|
24
|
-
this.connect()
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
componentWillUnmount () {
|
|
28
|
-
if (this.connectUpdated) {
|
|
29
|
-
this.connectUpdated.unsubscribe()
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (this.onConnectedListener) {
|
|
33
|
-
this.connectUpdated.events.removeListener("connected", this.props.onConnected)
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
connect () {
|
|
38
|
-
const {model, onConnected} = this.props
|
|
39
|
-
|
|
40
|
-
this.connectUpdated = ModelEvents.connectUpdated(model, this.onUpdated)
|
|
41
|
-
|
|
42
|
-
if (onConnected) {
|
|
43
|
-
this.onConnectedListener = this.connectUpdated.events.addListener("connected", this.props.onConnected)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
debounce () {
|
|
48
|
-
if (!this.debounceInstance) {
|
|
49
|
-
if (typeof this.props.debounce == "number") {
|
|
50
|
-
this.debounceInstance = debounce(this.props.onUpdated, this.props.debounce)
|
|
51
|
-
} else {
|
|
52
|
-
this.debounceInstance = debounce(this.props.onUpdated)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return this.debounceInstance
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
onUpdated = (...args) => {
|
|
60
|
-
if (!this.props.active) {
|
|
61
|
-
return
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (this.props.debounce) {
|
|
65
|
-
this.debounce()(...args)
|
|
66
|
-
} else {
|
|
67
|
-
this.props.onUpdated(...args)
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
render = () => null
|
|
9
|
+
return null
|
|
72
10
|
}
|
|
11
|
+
|
|
12
|
+
ApiMakerEventUpdated.propTypes = propTypesExact({
|
|
13
|
+
active: PropTypes.bool,
|
|
14
|
+
debounce: PropTypes.oneOfType([
|
|
15
|
+
PropTypes.bool,
|
|
16
|
+
PropTypes.number
|
|
17
|
+
]),
|
|
18
|
+
model: PropTypes.object.isRequired,
|
|
19
|
+
onConnected: PropTypes.func,
|
|
20
|
+
onUpdated: PropTypes.func.isRequired
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
export default memo(ApiMakerEventUpdated)
|
package/src/use-collection.mjs
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import Collection from "./collection.mjs"
|
|
2
1
|
import debounce from "debounce"
|
|
3
2
|
import {digg} from "diggerize"
|
|
4
3
|
import * as inflection from "inflection"
|
|
5
4
|
import ModelEvents from "./model-events.mjs"
|
|
6
|
-
import PropTypes from "prop-types"
|
|
7
|
-
import PropTypesExact from "prop-types-exact"
|
|
8
5
|
import {useCallback, useEffect} from "react"
|
|
9
6
|
import useShape from "set-state-compare/src/use-shape.js"
|
|
10
7
|
import useQueryParams from "on-location-changed/src/use-query-params.js"
|
|
@@ -15,6 +12,7 @@ const useCollection = (
|
|
|
15
12
|
collection,
|
|
16
13
|
defaultParams,
|
|
17
14
|
groupBy = ["id"],
|
|
15
|
+
limit,
|
|
18
16
|
modelClass,
|
|
19
17
|
noRecordsAvailableContent = undefined,
|
|
20
18
|
noRecordsFoundContent = undefined,
|
|
@@ -23,16 +21,23 @@ const useCollection = (
|
|
|
23
21
|
preloads = [],
|
|
24
22
|
queryMethod,
|
|
25
23
|
queryName,
|
|
24
|
+
ransack,
|
|
26
25
|
select = {},
|
|
27
|
-
selectColumns
|
|
26
|
+
selectColumns,
|
|
27
|
+
...restProps
|
|
28
28
|
},
|
|
29
29
|
cacheKeys = []
|
|
30
30
|
) => {
|
|
31
|
+
if (Object.keys(restProps).length > 0) {
|
|
32
|
+
throw new Error(`Unknown props given to useCollection: ${Object.keys(restProps).join(", ")}`)
|
|
33
|
+
}
|
|
34
|
+
|
|
31
35
|
const s = useShape({
|
|
32
36
|
abilities,
|
|
33
37
|
collection,
|
|
34
38
|
defaultParams,
|
|
35
39
|
groupBy,
|
|
40
|
+
limit,
|
|
36
41
|
modelClass,
|
|
37
42
|
noRecordsAvailableContent,
|
|
38
43
|
noRecordsFoundContent,
|
|
@@ -40,12 +45,27 @@ const useCollection = (
|
|
|
40
45
|
pagination,
|
|
41
46
|
preloads,
|
|
42
47
|
queryMethod,
|
|
48
|
+
ransack,
|
|
43
49
|
select,
|
|
44
50
|
selectColumns
|
|
45
51
|
})
|
|
46
52
|
|
|
53
|
+
s.meta.queryParams = useQueryParams()
|
|
54
|
+
|
|
47
55
|
if (!queryName) queryName = digg(modelClass.modelClassData(), "collectionKey")
|
|
48
56
|
|
|
57
|
+
const hasQParams = useCallback(() => {
|
|
58
|
+
if (s.s.queryQName in s.m.queryParams) return true
|
|
59
|
+
|
|
60
|
+
return false
|
|
61
|
+
}, [])
|
|
62
|
+
|
|
63
|
+
const qParams = useCallback(() => {
|
|
64
|
+
if (hasQParams()) return JSON.parse(digg(s.m.queryParams, s.s.queryQName))
|
|
65
|
+
|
|
66
|
+
return {}
|
|
67
|
+
}, [])
|
|
68
|
+
|
|
49
69
|
s.useStates({
|
|
50
70
|
models: undefined,
|
|
51
71
|
overallCount: undefined,
|
|
@@ -55,14 +75,14 @@ const useCollection = (
|
|
|
55
75
|
queryQName: `${queryName}_q`,
|
|
56
76
|
querySName: `${queryName}_s`,
|
|
57
77
|
queryPageName: `${queryName}_page`,
|
|
58
|
-
qParams: undefined,
|
|
59
78
|
result: undefined,
|
|
60
79
|
searchParams: undefined,
|
|
61
80
|
showNoRecordsAvailableContent: false,
|
|
62
81
|
showNoRecordsFoundContent: false
|
|
63
82
|
})
|
|
64
|
-
|
|
65
|
-
|
|
83
|
+
s.useStates({
|
|
84
|
+
qParams: qParams()
|
|
85
|
+
})
|
|
66
86
|
|
|
67
87
|
let modelIdsCacheString
|
|
68
88
|
|
|
@@ -74,8 +94,6 @@ const useCollection = (
|
|
|
74
94
|
modelIdsCacheString = s.s.models.map((model) => model.cacheKey())?.join("---")
|
|
75
95
|
}
|
|
76
96
|
|
|
77
|
-
s.updateMeta({queryParams})
|
|
78
|
-
|
|
79
97
|
const loadOverallCount = useCallback(async () => {
|
|
80
98
|
const baseQuery = s.p.collection || s.p.modelClass.all()
|
|
81
99
|
const overallCount = await baseQuery.count()
|
|
@@ -87,18 +105,6 @@ const useCollection = (
|
|
|
87
105
|
})
|
|
88
106
|
}, [])
|
|
89
107
|
|
|
90
|
-
const hasQParams = useCallback(() => {
|
|
91
|
-
if (s.s.queryQName in s.m.queryParams) return true
|
|
92
|
-
|
|
93
|
-
return false
|
|
94
|
-
}, [])
|
|
95
|
-
|
|
96
|
-
const qParams = useCallback(() => {
|
|
97
|
-
if (hasQParams()) return JSON.parse(digg(s.m.queryParams, s.s.queryQName))
|
|
98
|
-
|
|
99
|
-
return {}
|
|
100
|
-
}, [])
|
|
101
|
-
|
|
102
108
|
const loadQParams = useCallback(() => {
|
|
103
109
|
const qParamsToSet = hasQParams() ? qParams() : Object.assign({}, s.p.defaultParams)
|
|
104
110
|
const searchParams = []
|
|
@@ -137,6 +143,7 @@ const useCollection = (
|
|
|
137
143
|
|
|
138
144
|
query = query
|
|
139
145
|
.ransack(s.s.qParams)
|
|
146
|
+
.ransack(s.props.ransack)
|
|
140
147
|
.search(s.s.searchParams)
|
|
141
148
|
.searchKey(s.s.queryQName)
|
|
142
149
|
.pageKey(s.s.queryPageName)
|
|
@@ -145,6 +152,7 @@ const useCollection = (
|
|
|
145
152
|
.select(s.p.select)
|
|
146
153
|
|
|
147
154
|
if (s.p.abilities) query = query.abilities(s.p.abilities)
|
|
155
|
+
if (s.p.limit !== undefined) query = query.limit(s.p.limit)
|
|
148
156
|
if (s.p.selectColumns) query = query.selectColumns(s.p.selectColumns)
|
|
149
157
|
|
|
150
158
|
let result
|
|
@@ -235,7 +243,13 @@ const useCollection = (
|
|
|
235
243
|
loadQParams()
|
|
236
244
|
loadModels()
|
|
237
245
|
},
|
|
238
|
-
[
|
|
246
|
+
[
|
|
247
|
+
s.m.queryParams[s.s.queryQName],
|
|
248
|
+
s.m.queryParams[s.s.queryPageName],
|
|
249
|
+
s.m.queryParams[s.s.queryPerKey],
|
|
250
|
+
s.m.queryParams[s.s.querySName],
|
|
251
|
+
collection
|
|
252
|
+
].concat(cacheKeys)
|
|
239
253
|
)
|
|
240
254
|
|
|
241
255
|
useEffect(() => {
|
|
@@ -276,21 +290,4 @@ const useCollection = (
|
|
|
276
290
|
return result
|
|
277
291
|
}
|
|
278
292
|
|
|
279
|
-
useCollection.propTypes = PropTypesExact({
|
|
280
|
-
abilities: PropTypes.object,
|
|
281
|
-
collection: PropTypes.instanceOf(Collection),
|
|
282
|
-
defaultParams: PropTypes.object,
|
|
283
|
-
groupBy: PropTypes.array,
|
|
284
|
-
modelClass: PropTypes.func.isRequired,
|
|
285
|
-
noRecordsAvailableContent: PropTypes.func,
|
|
286
|
-
noRecordsFoundContent: PropTypes.func,
|
|
287
|
-
onModelsLoaded: PropTypes.func,
|
|
288
|
-
pagination: PropTypes.bool.isRequired,
|
|
289
|
-
preloads: PropTypes.array.isRequired,
|
|
290
|
-
queryMethod: PropTypes.func,
|
|
291
|
-
queryName: PropTypes.string,
|
|
292
|
-
select: PropTypes.object,
|
|
293
|
-
selectColumns: PropTypes.object
|
|
294
|
-
})
|
|
295
|
-
|
|
296
293
|
export default useCollection
|
|
@@ -2,7 +2,7 @@ import debounceFunction from "debounce"
|
|
|
2
2
|
import ModelEvents from "./model-events.mjs"
|
|
3
3
|
import PropTypes from "prop-types"
|
|
4
4
|
import propTypesExact from "prop-types-exact"
|
|
5
|
-
import {useCallback, useEffect
|
|
5
|
+
import {useCallback, useEffect} from "react"
|
|
6
6
|
import useShape from "set-state-compare/src/use-shape.js"
|
|
7
7
|
|
|
8
8
|
const ApiMakerUseCreatedEvent = (modelClass, onCreated, args = {}) => {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {useCallback, useEffect, useMemo} from "react"
|
|
2
|
+
import debounceFunction from "debounce"
|
|
3
|
+
import ModelEvents from "./model-events.mjs"
|
|
4
|
+
import useShape from "set-state-compare/src/use-shape.js"
|
|
5
|
+
|
|
6
|
+
const ApiMakerUseUpdatedEvent = (model, onUpdated, {active = true, debounce, onConnected, ...restProps}) => {
|
|
7
|
+
if (Object.keys(restProps).length > 0) {
|
|
8
|
+
throw new Error(`Unknown props given to useUpdatedEvent: ${Object.keys(restProps).join(", ")}`)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const s = useShape({active, debounce, model, onUpdated})
|
|
12
|
+
|
|
13
|
+
const debounceCallback = useMemo(() => {
|
|
14
|
+
if (typeof debounce == "number") {
|
|
15
|
+
return debounceFunction(s.p.onUpdated, debounce)
|
|
16
|
+
} else {
|
|
17
|
+
return debounceFunction(s.p.onUpdated)
|
|
18
|
+
}
|
|
19
|
+
}, [debounce])
|
|
20
|
+
|
|
21
|
+
s.updateMeta({debounceCallback})
|
|
22
|
+
|
|
23
|
+
const onUpdatedCallback = useCallback((...args) => {
|
|
24
|
+
if (!s.p.active) {
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (s.p.debounce) {
|
|
29
|
+
s.m.debounceCallback(...args)
|
|
30
|
+
} else {
|
|
31
|
+
s.p.onUpdated(...args)
|
|
32
|
+
}
|
|
33
|
+
}, [])
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
let connectUpdated, onConnectedListener
|
|
37
|
+
|
|
38
|
+
if (model) {
|
|
39
|
+
connectUpdated = ModelEvents.connectUpdated(model, onUpdatedCallback)
|
|
40
|
+
|
|
41
|
+
if (onConnected) {
|
|
42
|
+
onConnectedListener = connectUpdated.events.addListener("connected", onConnected)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return () => {
|
|
47
|
+
if (onConnectedListener) {
|
|
48
|
+
connectUpdated.events.removeListener("connected", onConnected)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (connectUpdated) {
|
|
52
|
+
connectUpdated.unsubscribe()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}, [model?.id()])
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export default ApiMakerUseUpdatedEvent
|